mirror of
https://gitee.com/zoujingli/ThinkAdmin.git
synced 2026-06-07 12:38:11 +08:00
fix: Add .php-cs-fixer.php and update many files
Add PHP CS Fixer configuration (.php-cs-fixer.php) to enforce coding style and apply corresponding updates across the codebase. Numerous plugins (think-library and many think-plugs-*) and core config files (cache, database, phinx, worker) were updated along with controllers, services, models, storage adapters, helpers and tests to conform to style fixes and minor compatibility/refactors.
This commit is contained in:
parent
6b3e985747
commit
987ad41765
120
.php-cs-fixer.php
Normal file
120
.php-cs-fixer.php
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
/**
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
* | Payment Plugin for ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
* | 官方网站: https://thinkadmin.top
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
* | 开源协议 ( https://mit-license.org )
|
||||||
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
use PhpCsFixer\Config;
|
||||||
|
use PhpCsFixer\Finder;
|
||||||
|
use PhpCsFixer\Runner\Parallel\ParallelConfig;
|
||||||
|
|
||||||
|
$header = <<<'EOF'
|
||||||
|
+----------------------------------------------------------------------
|
||||||
|
| Payment Plugin for ThinkAdmin
|
||||||
|
+----------------------------------------------------------------------
|
||||||
|
| 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
|
+----------------------------------------------------------------------
|
||||||
|
| 官方网站: https://thinkadmin.top
|
||||||
|
+----------------------------------------------------------------------
|
||||||
|
| 开源协议 ( https://mit-license.org )
|
||||||
|
| 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
|
| 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
|
+----------------------------------------------------------------------
|
||||||
|
| gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
|
| github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
+----------------------------------------------------------------------
|
||||||
|
EOF;
|
||||||
|
|
||||||
|
$config = new Config();
|
||||||
|
$config->setRiskyAllowed(true)->setParallelConfig(new ParallelConfig(8, 24));
|
||||||
|
$finder = Finder::create()->in(__DIR__)->exclude(['vendor', 'public', 'runtime']);
|
||||||
|
return $config->setFinder($finder)->setUsingCache(false)->setRules([
|
||||||
|
'@PSR2' => true,
|
||||||
|
'@Symfony' => true,
|
||||||
|
'@DoctrineAnnotation' => true,
|
||||||
|
'@PhpCsFixer' => true,
|
||||||
|
'header_comment' => [
|
||||||
|
'comment_type' => 'PHPDoc',
|
||||||
|
'header' => $header,
|
||||||
|
'separate' => 'none',
|
||||||
|
'location' => 'after_declare_strict',
|
||||||
|
],
|
||||||
|
'array_syntax' => [
|
||||||
|
'syntax' => 'short',
|
||||||
|
],
|
||||||
|
'list_syntax' => [
|
||||||
|
'syntax' => 'short',
|
||||||
|
],
|
||||||
|
'blank_line_before_statement' => [
|
||||||
|
'statements' => [
|
||||||
|
'declare',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'general_phpdoc_annotation_remove' => [
|
||||||
|
'annotations' => [
|
||||||
|
'author',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'ordered_imports' => [
|
||||||
|
'imports_order' => [
|
||||||
|
'class', 'function', 'const',
|
||||||
|
],
|
||||||
|
'sort_algorithm' => 'alpha',
|
||||||
|
],
|
||||||
|
'single_line_comment_style' => [
|
||||||
|
'comment_types' => [
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'yoda_style' => [
|
||||||
|
'always_move_variable' => false,
|
||||||
|
'equal' => false,
|
||||||
|
'identical' => false,
|
||||||
|
],
|
||||||
|
'phpdoc_align' => [
|
||||||
|
'align' => 'left',
|
||||||
|
],
|
||||||
|
'multiline_whitespace_before_semicolons' => [
|
||||||
|
'strategy' => 'no_multi_line',
|
||||||
|
],
|
||||||
|
'constant_case' => [
|
||||||
|
'case' => 'lower',
|
||||||
|
],
|
||||||
|
'encoding' => true, // PHP代码必须只使用没有BOM的UTF-8
|
||||||
|
'line_ending' => true, // 所有的PHP文件编码必须一致
|
||||||
|
'single_quote' => true, // 简单字符串应该使用单引号代替双引号
|
||||||
|
'no_empty_statement' => true, // 不应该存在空的结构体
|
||||||
|
'standardize_not_equals' => true, // 使用 <> 代替 !=
|
||||||
|
'blank_line_after_namespace' => true, // 命名空间之后空一行
|
||||||
|
'no_empty_phpdoc' => true, // 不应该存在空的 phpdoc
|
||||||
|
'no_empty_comment' => true, // 不应该存在空注释
|
||||||
|
'no_singleline_whitespace_before_semicolons' => true, // 禁止在关闭分号前使用单行空格
|
||||||
|
'concat_space' => ['spacing' => 'one'], // 连接字符是否需要空格,可选配置项 none:不需要 one:一个空格
|
||||||
|
'no_leading_import_slash' => true, // use 语句中取消前置斜杠
|
||||||
|
'cast_spaces' => ['space' => 'none'],
|
||||||
|
'class_attributes_separation' => true,
|
||||||
|
'combine_consecutive_unsets' => true,
|
||||||
|
'declare_strict_types' => true,
|
||||||
|
'lowercase_static_reference' => true,
|
||||||
|
'linebreak_after_opening_tag' => true,
|
||||||
|
'multiline_comment_opening_closing' => true,
|
||||||
|
'no_useless_else' => true,
|
||||||
|
'no_unused_imports' => true,
|
||||||
|
'not_operator_with_successor_space' => false,
|
||||||
|
'not_operator_with_space' => false,
|
||||||
|
'ordered_class_elements' => true,
|
||||||
|
'php_unit_strict' => false,
|
||||||
|
'phpdoc_separation' => false,
|
||||||
|
]);
|
||||||
@ -1,18 +1,22 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// +----------------------------------------------------------------------
|
declare(strict_types=1);
|
||||||
// | Static Plugin for ThinkAdmin
|
/**
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 版权所有 2014~2024 ThinkAdmin [ thinkadmin.top ]
|
* | Payment Plugin for ThinkAdmin
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 官方网站: https://thinkadmin.top
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 开源协议 ( https://mit-license.org )
|
* | 官方网站: https://thinkadmin.top
|
||||||
// | 免责声明 ( https://thinkadmin.top/disclaimer )
|
* +----------------------------------------------------------------------
|
||||||
// +----------------------------------------------------------------------
|
* | 开源协议 ( https://mit-license.org )
|
||||||
// | gitee 代码仓库:https://gitee.com/zoujingli/think-plugs-static
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
// | github 代码仓库:https://github.com/zoujingli/think-plugs-static
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
namespace app\index\controller;
|
namespace app\index\controller;
|
||||||
|
|
||||||
|
|||||||
@ -36,9 +36,13 @@
|
|||||||
"zoujingli/think-plugs-wuma": "*"
|
"zoujingli/think-plugs-wuma": "*"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
|
"friendsofphp/php-cs-fixer": "^3.0",
|
||||||
"zoujingli/think-plugs-helper": "*"
|
"zoujingli/think-plugs-helper": "*"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
"sync": [
|
||||||
|
"php-cs-fixer fix"
|
||||||
|
],
|
||||||
"test": [
|
"test": [
|
||||||
"php -m"
|
"php -m"
|
||||||
]
|
]
|
||||||
@ -100,4 +104,4 @@
|
|||||||
"zoujingli/think-install": true
|
"zoujingli/think-install": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,59 +1,62 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// +----------------------------------------------------------------------
|
declare(strict_types=1);
|
||||||
// | Static Plugin for ThinkAdmin
|
/**
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 版权所有 2014~2024 ThinkAdmin [ thinkadmin.top ]
|
* | Payment Plugin for ThinkAdmin
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 官方网站: https://thinkadmin.top
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 开源协议 ( https://mit-license.org )
|
* | 官方网站: https://thinkadmin.top
|
||||||
// | 免责声明 ( https://thinkadmin.top/disclaimer )
|
* +----------------------------------------------------------------------
|
||||||
// +----------------------------------------------------------------------
|
* | 开源协议 ( https://mit-license.org )
|
||||||
// | gitee 代码仓库:https://gitee.com/zoujingli/think-plugs-static
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
// | github 代码仓库:https://github.com/zoujingli/think-plugs-static
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
return [
|
return [
|
||||||
// 默认缓存驱动
|
// 默认缓存驱动
|
||||||
'default' => env('CACHE_TYPE', 'file'),
|
'default' => env('CACHE_TYPE', 'file'),
|
||||||
// 缓存连接配置
|
// 缓存连接配置
|
||||||
'stores' => [
|
'stores' => [
|
||||||
'file' => [
|
'file' => [
|
||||||
// 驱动方式
|
// 驱动方式
|
||||||
'type' => 'File',
|
'type' => 'File',
|
||||||
// 缓存保存目录
|
// 缓存保存目录
|
||||||
'path' => '',
|
'path' => '',
|
||||||
// 缓存名称前缀
|
// 缓存名称前缀
|
||||||
'prefix' => '',
|
'prefix' => '',
|
||||||
// 缓存有效期 0 表示永久缓存
|
// 缓存有效期 0 表示永久缓存
|
||||||
'expire' => 0,
|
'expire' => 0,
|
||||||
// 缓存标签前缀
|
// 缓存标签前缀
|
||||||
'tag_prefix' => 'tag:',
|
'tag_prefix' => 'tag:',
|
||||||
// 序列化机制
|
// 序列化机制
|
||||||
'serialize' => [],
|
'serialize' => [],
|
||||||
],
|
],
|
||||||
'safe' => [
|
'safe' => [
|
||||||
// 驱动方式
|
// 驱动方式
|
||||||
'type' => 'File',
|
'type' => 'File',
|
||||||
// 缓存保存目录
|
// 缓存保存目录
|
||||||
'path' => syspath('safefile/cache/'),
|
'path' => syspath('safefile/cache/'),
|
||||||
// 缓存名称前缀
|
// 缓存名称前缀
|
||||||
'prefix' => '',
|
'prefix' => '',
|
||||||
// 缓存有效期 0 表示永久缓存
|
// 缓存有效期 0 表示永久缓存
|
||||||
'expire' => 0,
|
'expire' => 0,
|
||||||
// 缓存标签前缀
|
// 缓存标签前缀
|
||||||
'tag_prefix' => 'tag:',
|
'tag_prefix' => 'tag:',
|
||||||
// 序列化机制
|
// 序列化机制
|
||||||
'serialize' => [],
|
'serialize' => [],
|
||||||
],
|
],
|
||||||
'redis' => [
|
'redis' => [
|
||||||
// 驱动方式
|
// 驱动方式
|
||||||
'type' => 'redis',
|
'type' => 'redis',
|
||||||
'host' => env('CACHE_REDIS_HOST', '127.0.0.1'),
|
'host' => env('CACHE_REDIS_HOST', '127.0.0.1'),
|
||||||
'port' => env('CACHE_REDIS_PORT', 6379),
|
'port' => env('CACHE_REDIS_PORT', 6379),
|
||||||
'select' => env('CACHE_REDIS_SELECT', 0),
|
'select' => env('CACHE_REDIS_SELECT', 0),
|
||||||
'password' => env('CACHE_REDIS_PASSWORD', ''),
|
'password' => env('CACHE_REDIS_PASSWORD', ''),
|
||||||
]
|
],
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
|
|||||||
@ -1,83 +1,86 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// +----------------------------------------------------------------------
|
declare(strict_types=1);
|
||||||
// | Static Plugin for ThinkAdmin
|
/**
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 版权所有 2014~2024 ThinkAdmin [ thinkadmin.top ]
|
* | Payment Plugin for ThinkAdmin
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 官方网站: https://thinkadmin.top
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 开源协议 ( https://mit-license.org )
|
* | 官方网站: https://thinkadmin.top
|
||||||
// | 免责声明 ( https://thinkadmin.top/disclaimer )
|
* +----------------------------------------------------------------------
|
||||||
// +----------------------------------------------------------------------
|
* | 开源协议 ( https://mit-license.org )
|
||||||
// | gitee 代码仓库:https://gitee.com/zoujingli/think-plugs-static
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
// | github 代码仓库:https://github.com/zoujingli/think-plugs-static
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
return [
|
return [
|
||||||
// 默认使用的数据库连接配置
|
// 默认使用的数据库连接配置
|
||||||
'default' => env('DB_TYPE', 'sqlite'),
|
'default' => env('DB_TYPE', 'sqlite'),
|
||||||
// 自定义时间查询规则
|
// 自定义时间查询规则
|
||||||
'time_query_rule' => [],
|
'time_query_rule' => [],
|
||||||
// 自动写入时间戳字段
|
// 自动写入时间戳字段
|
||||||
'auto_timestamp' => true,
|
'auto_timestamp' => true,
|
||||||
// 时间字段取出后的默认时间格式
|
// 时间字段取出后的默认时间格式
|
||||||
'datetime_format' => 'Y-m-d H:i:s',
|
'datetime_format' => 'Y-m-d H:i:s',
|
||||||
// 数据库连接配置信息
|
// 数据库连接配置信息
|
||||||
'connections' => [
|
'connections' => [
|
||||||
'mysql' => [
|
'mysql' => [
|
||||||
// 数据库类型
|
// 数据库类型
|
||||||
'type' => 'mysql',
|
'type' => 'mysql',
|
||||||
// 服务器地址
|
// 服务器地址
|
||||||
'hostname' => env('DB_MYSQL_HOST', '127.0.0.1'),
|
'hostname' => env('DB_MYSQL_HOST', '127.0.0.1'),
|
||||||
// 服务器端口
|
// 服务器端口
|
||||||
'hostport' => env('DB_MYSQL_PORT', '3306'),
|
'hostport' => env('DB_MYSQL_PORT', '3306'),
|
||||||
// 数据库名
|
// 数据库名
|
||||||
'database' => env('DB_MYSQL_DATABASE', 'thinkadmin'),
|
'database' => env('DB_MYSQL_DATABASE', 'thinkadmin'),
|
||||||
// 用户名
|
// 用户名
|
||||||
'username' => env('DB_MYSQL_USERNAME', 'root'),
|
'username' => env('DB_MYSQL_USERNAME', 'root'),
|
||||||
// 密码
|
// 密码
|
||||||
'password' => env('DB_MYSQL_PASSWORD', ''),
|
'password' => env('DB_MYSQL_PASSWORD', ''),
|
||||||
// 数据库连接参数
|
// 数据库连接参数
|
||||||
'params' => [],
|
'params' => [],
|
||||||
// 数据库表前缀
|
// 数据库表前缀
|
||||||
'prefix' => env('DB_MYSQL_PREFIX', ''),
|
'prefix' => env('DB_MYSQL_PREFIX', ''),
|
||||||
// 数据库编码默认采用 utf8mb4
|
// 数据库编码默认采用 utf8mb4
|
||||||
'charset' => env('DB_MYSQL_CHARSET', 'utf8mb4'),
|
'charset' => env('DB_MYSQL_CHARSET', 'utf8mb4'),
|
||||||
// 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器)
|
// 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器)
|
||||||
'deploy' => 0,
|
'deploy' => 0,
|
||||||
// 数据库读写是否分离 主从式有效
|
// 数据库读写是否分离 主从式有效
|
||||||
'rw_separate' => false,
|
'rw_separate' => false,
|
||||||
// 读写分离后 主服务器数量
|
// 读写分离后 主服务器数量
|
||||||
'master_num' => 1,
|
'master_num' => 1,
|
||||||
// 指定从服务器序号
|
// 指定从服务器序号
|
||||||
'slave_no' => '',
|
'slave_no' => '',
|
||||||
// 检查字段是否存在
|
// 检查字段是否存在
|
||||||
'fields_strict' => true,
|
'fields_strict' => true,
|
||||||
// 是否需要断线重连
|
// 是否需要断线重连
|
||||||
'break_reconnect' => false,
|
'break_reconnect' => false,
|
||||||
// 监听SQL执行日志
|
// 监听SQL执行日志
|
||||||
'trigger_sql' => true,
|
'trigger_sql' => true,
|
||||||
// 开启字段类型缓存
|
// 开启字段类型缓存
|
||||||
'fields_cache' => isOnline(),
|
'fields_cache' => isOnline(),
|
||||||
],
|
],
|
||||||
'sqlite' => [
|
'sqlite' => [
|
||||||
// 数据库类型
|
// 数据库类型
|
||||||
'type' => 'sqlite',
|
'type' => 'sqlite',
|
||||||
// 数据库文件
|
// 数据库文件
|
||||||
'database' => syspath('database/sqlite.db'),
|
'database' => syspath('database/sqlite.db'),
|
||||||
// 数据库编码默认采用 utf8
|
// 数据库编码默认采用 utf8
|
||||||
'charset' => 'utf8',
|
'charset' => 'utf8',
|
||||||
// 监听执行日志
|
// 监听执行日志
|
||||||
'trigger_sql' => true,
|
'trigger_sql' => true,
|
||||||
// 其他参数字段
|
// 其他参数字段
|
||||||
'deploy' => 0,
|
'deploy' => 0,
|
||||||
'suffix' => '',
|
'suffix' => '',
|
||||||
'prefix' => '',
|
'prefix' => '',
|
||||||
'hostname' => '',
|
'hostname' => '',
|
||||||
'hostport' => '',
|
'hostport' => '',
|
||||||
'username' => '',
|
'username' => '',
|
||||||
'password' => '',
|
'password' => '',
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
|
|||||||
@ -1,19 +1,22 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// +----------------------------------------------------------------------
|
declare(strict_types=1);
|
||||||
// | Static Plugin for ThinkAdmin
|
/**
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 版权所有 2014~2024 ThinkAdmin [ thinkadmin.top ]
|
* | Payment Plugin for ThinkAdmin
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 官方网站: https://thinkadmin.top
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 开源协议 ( https://mit-license.org )
|
* | 官方网站: https://thinkadmin.top
|
||||||
// | 免责声明 ( https://thinkadmin.top/disclaimer )
|
* +----------------------------------------------------------------------
|
||||||
// +----------------------------------------------------------------------
|
* | 开源协议 ( https://mit-license.org )
|
||||||
// | gitee 代码仓库:https://gitee.com/zoujingli/think-plugs-static
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
// | github 代码仓库:https://github.com/zoujingli/think-plugs-static
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
return [
|
return [
|
||||||
// 忽略数据表,填写表名
|
// 忽略数据表,填写表名
|
||||||
'ignore' => [],
|
'ignore' => [],
|
||||||
@ -21,4 +24,4 @@ return [
|
|||||||
'tables' => [],
|
'tables' => [],
|
||||||
// 备份数据表,填写表名
|
// 备份数据表,填写表名
|
||||||
'backup' => [],
|
'backup' => [],
|
||||||
];
|
];
|
||||||
|
|||||||
@ -1,52 +1,52 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// +----------------------------------------------------------------------
|
declare(strict_types=1);
|
||||||
// | Worker Plugin for ThinkAdmin
|
/**
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 版权所有 2014~2024 ThinkAdmin [ thinkadmin.top ]
|
* | Payment Plugin for ThinkAdmin
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 官方网站: https://thinkadmin.top
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 免责声明 ( https://thinkadmin.top/disclaimer )
|
* | 官方网站: https://thinkadmin.top
|
||||||
// | 开源协议 ( http://www.apache.org/licenses/LICENSE-2.0 )
|
* +----------------------------------------------------------------------
|
||||||
// | 配置参考 ( https://www.workerman.net/doc/workerman/worker/properties.html )
|
* | 开源协议 ( https://mit-license.org )
|
||||||
// +----------------------------------------------------------------------
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
// | gitee 代码仓库:https://gitee.com/zoujingli/think-plugs-worker
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
// | github 代码仓库:https://github.com/zoujingli/think-plugs-worker
|
* +----------------------------------------------------------------------
|
||||||
// +----------------------------------------------------------------------
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
// | 配置参数参数:https://www.workerman.net/doc/workerman/worker/properties.html
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
return [
|
return [
|
||||||
// 服务监听地址
|
// 服务监听地址
|
||||||
'host' => '127.0.0.1',
|
'host' => '127.0.0.1',
|
||||||
// 服务监听端口
|
// 服务监听端口
|
||||||
'port' => 2346,
|
'port' => 2346,
|
||||||
// 套接字上下文选项
|
// 套接字上下文选项
|
||||||
'context' => [],
|
'context' => [],
|
||||||
// 高级自定义服务类
|
// 高级自定义服务类
|
||||||
'classes' => '',
|
'classes' => '',
|
||||||
// 消息请求回调处理
|
// 消息请求回调处理
|
||||||
'callable' => null,
|
'callable' => null,
|
||||||
// 服务进程参数配置
|
// 服务进程参数配置
|
||||||
'worker' => [
|
'worker' => [
|
||||||
'name' => 'ThinkAdmin',
|
'name' => 'ThinkAdmin',
|
||||||
'count' => 4,
|
'count' => 4,
|
||||||
],
|
],
|
||||||
// 监控文件变更重载,仅 Debug 模式有效
|
// 监控文件变更重载,仅 Debug 模式有效
|
||||||
'files' => [
|
'files' => [
|
||||||
// 监控检测间隔(单位秒,零不监控)
|
// 监控检测间隔(单位秒,零不监控)
|
||||||
'time' => 3,
|
'time' => 3,
|
||||||
// 文件监控目录(默认监控 app+config 目录)
|
// 文件监控目录(默认监控 app+config 目录)
|
||||||
'path' => [],
|
'path' => [],
|
||||||
// 文件监控后缀(默认监控 所有 文件)
|
// 文件监控后缀(默认监控 所有 文件)
|
||||||
'exts' => ['*']
|
'exts' => ['*'],
|
||||||
],
|
],
|
||||||
// 监控内存超限重载,仅 Debug 模式有效
|
// 监控内存超限重载,仅 Debug 模式有效
|
||||||
'memory' => [
|
'memory' => [
|
||||||
// 监控检测间隔(单位秒,零不监控)
|
// 监控检测间隔(单位秒,零不监控)
|
||||||
'time' => 60,
|
'time' => 60,
|
||||||
// 限制内存大小(可选单位有 G M K )
|
// 限制内存大小(可选单位有 G M K )
|
||||||
'limit' => '1G'
|
'limit' => '1G',
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
|
|||||||
@ -1,20 +1,22 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// +----------------------------------------------------------------------
|
declare(strict_types=1);
|
||||||
// | Library for ThinkAdmin
|
/**
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 版权所有 2014~2025 ThinkAdmin [ thinkadmin.top ]
|
* | Payment Plugin for ThinkAdmin
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 官方网站: https://thinkadmin.top
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 开源协议 ( https://mit-license.org )
|
* | 官方网站: https://thinkadmin.top
|
||||||
// | 免费声明 ( https://thinkadmin.top/disclaimer )
|
* +----------------------------------------------------------------------
|
||||||
// +----------------------------------------------------------------------
|
* | 开源协议 ( https://mit-license.org )
|
||||||
// | gitee 仓库地址 :https://gitee.com/zoujingli/ThinkLibrary
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
// | github 仓库地址 :https://github.com/zoujingli/ThinkLibrary
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
declare (strict_types=1);
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
namespace think\admin;
|
namespace think\admin;
|
||||||
|
|
||||||
@ -22,28 +24,27 @@ use think\exception\HttpResponseException;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 表单模板构建器
|
* 表单模板构建器
|
||||||
* 后面会在兼容的基础上慢慢完善
|
* 后面会在兼容的基础上慢慢完善.
|
||||||
* @class Builder
|
* @class Builder
|
||||||
* @deprecated 试验中建议不使用
|
* @deprecated 试验中建议不使用
|
||||||
* @package think\admin
|
|
||||||
*/
|
*/
|
||||||
class Builder
|
class Builder
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* 生成类型
|
* 生成类型.
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
private $type;
|
private $type;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 显示方式
|
* 显示方式.
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
private $mode;
|
private $mode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 当前控制器
|
* 当前控制器.
|
||||||
* @var \think\admin\Controller
|
* @var Controller
|
||||||
*/
|
*/
|
||||||
private $class;
|
private $class;
|
||||||
|
|
||||||
@ -54,23 +55,23 @@ class Builder
|
|||||||
private $action;
|
private $action;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 表单变量
|
* 表单变量.
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
private $variable = '$vo';
|
private $variable = '$vo';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 表单项目
|
* 表单项目.
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
private $fields = [];
|
private $fields = [];
|
||||||
|
|
||||||
private $buttons = [];
|
private $buttons = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructer
|
* Constructer.
|
||||||
* @param string $type 页面类型
|
* @param string $type 页面类型
|
||||||
* @param string $mode 页面模式
|
* @param string $mode 页面模式
|
||||||
* @param \think\admin\Controller $class
|
|
||||||
*/
|
*/
|
||||||
public function __construct(string $type, string $mode, Controller $class)
|
public function __construct(string $type, string $mode, Controller $class)
|
||||||
{
|
{
|
||||||
@ -80,10 +81,9 @@ class Builder
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建表单生成器
|
* 创建表单生成器.
|
||||||
* @param string $type 页面类型
|
* @param string $type 页面类型
|
||||||
* @param string $mode 页面模式
|
* @param string $mode 页面模式
|
||||||
* @return \think\admin\Builder
|
|
||||||
*/
|
*/
|
||||||
public static function mk(string $type = 'form', string $mode = 'modal'): Builder
|
public static function mk(string $type = 'form', string $mode = 'modal'): Builder
|
||||||
{
|
{
|
||||||
@ -92,7 +92,6 @@ class Builder
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置表单地址
|
* 设置表单地址
|
||||||
* @param string $url
|
|
||||||
* @return $this
|
* @return $this
|
||||||
*/
|
*/
|
||||||
public function setAction(string $url): Builder
|
public function setAction(string $url): Builder
|
||||||
@ -102,8 +101,7 @@ class Builder
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置变量名称
|
* 设置变量名称.
|
||||||
* @param string $name
|
|
||||||
* @return $this
|
* @return $this
|
||||||
*/
|
*/
|
||||||
public function setVariable(string $name): Builder
|
public function setVariable(string $name): Builder
|
||||||
@ -113,7 +111,218 @@ class Builder
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 增加输入表单元素
|
* 创建文本输入框架.
|
||||||
|
* @param string $name 字段名称
|
||||||
|
* @param string $title 字段标题
|
||||||
|
* @param string $substr 字段子标题
|
||||||
|
* @param array $attrs 附加属性
|
||||||
|
* @param mixed $remark
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function addTextArea(string $name, string $title, string $substr = '', bool $required = false, $remark = '', array $attrs = []): Builder
|
||||||
|
{
|
||||||
|
if ($required) {
|
||||||
|
$attrs['required'] = 'required';
|
||||||
|
}
|
||||||
|
$html = "\n\t\t" . '<label class="layui-form-item block relative">';
|
||||||
|
$html .= "\n\t\t\t" . sprintf('<span class="help-label %s"><b>%s</b>%s</span>', empty($attrs['required']) ? '' : 'label-required-prev', $title, $substr);
|
||||||
|
$html .= "\n\t\t\t" . sprintf('<textarea name="%s" %s placeholder="请输入%s" class="layui-textarea">{%s.%s|default=\'\'}</textarea>', $name, $this->_attrs($attrs), $title, $this->variable, $name);
|
||||||
|
if ($remark) {
|
||||||
|
$html .= "\n\t\t\t" . sprintf('<span class="help-block">%s</span>', $remark);
|
||||||
|
}
|
||||||
|
$this->fields[] = "{$html}\n\t\t</lable>";
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建 Text 输入.
|
||||||
|
* @param string $name 字段名称
|
||||||
|
* @param string $title 字段标题
|
||||||
|
* @param string $substr 字段子标题
|
||||||
|
* @param string $remark 字段备注
|
||||||
|
* @param bool $required 是否必填
|
||||||
|
* @param ?string $pattern 验证规则
|
||||||
|
* @param array $attrs 附加属性
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function addTextInput(string $name, string $title, string $substr = '', bool $required = false, string $remark = '', ?string $pattern = null, array $attrs = []): Builder
|
||||||
|
{
|
||||||
|
$attrs['vali-name'] = $title;
|
||||||
|
if ($required) {
|
||||||
|
$attrs['required'] = 'required';
|
||||||
|
}
|
||||||
|
if (is_string($pattern)) {
|
||||||
|
$attrs['pattern'] = $pattern;
|
||||||
|
}
|
||||||
|
return $this->addInput($name, $title, $substr, $remark, $attrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建密钥输入框.
|
||||||
|
* @param string $name 字段名称
|
||||||
|
* @param string $title 字段标题
|
||||||
|
* @param string $substr 字段子标题
|
||||||
|
* @param string $remark 字段备注
|
||||||
|
* @param bool $required 是否必填
|
||||||
|
* @param ?string $pattern 验证规则
|
||||||
|
* @param array $attrs 附加属性
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function addPassInput(string $name, string $title, string $substr = '', bool $required = false, string $remark = '', ?string $pattern = null, array $attrs = []): Builder
|
||||||
|
{
|
||||||
|
$attrs['type'] = 'password';
|
||||||
|
return $this->addTextInput($name, $title, $substr, $required, $remark, $pattern, $attrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加取消按钮.
|
||||||
|
* @param string $name 按钮名称
|
||||||
|
* @param string $confirm 确认提示
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function addCancelButton(string $name = '取消编辑', string $confirm = '确定要取消编辑吗?'): Builder
|
||||||
|
{
|
||||||
|
return $this->addButton($name, $confirm, 'button', 'layui-btn-danger', ['data-close' => null]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加提交按钮.
|
||||||
|
* @param string $name 按钮名称
|
||||||
|
* @param string $confirm 确认提示
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function addSubmitButton(string $name = '保存数据', string $confirm = ''): Builder
|
||||||
|
{
|
||||||
|
return $this->addButton($name, $confirm, 'submit');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加上传单图字段.
|
||||||
|
* @param string $name 字段名称
|
||||||
|
* @param string $title 字段标题
|
||||||
|
* @param string $substr 字段子标题
|
||||||
|
* @param bool $required 必填字段
|
||||||
|
* @param array $attrs 附加属性
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function addUploadOneImage(string $name, string $title, string $substr = '', bool $required = false, array $attrs = []): Builder
|
||||||
|
{
|
||||||
|
if ($required) {
|
||||||
|
$attrs['required'] = 'required';
|
||||||
|
}
|
||||||
|
return $this->_addUploadOneView($name, $title, $substr, $attrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加上传视频字段.
|
||||||
|
* @param string $name 字段名称
|
||||||
|
* @param string $title 字段标题
|
||||||
|
* @param string $substr 字段子标题
|
||||||
|
* @param bool $required 必填字段
|
||||||
|
* @param array $attrs 附加属性
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function addUploadOneVideo(string $name, string $title, string $substr = '', bool $required = false, array $attrs = []): Builder
|
||||||
|
{
|
||||||
|
if ($required) {
|
||||||
|
$attrs['required'] = 'required';
|
||||||
|
}
|
||||||
|
return $this->_addUploadOneView($name, $title, $substr, $attrs, 'video');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建上传多图字段.
|
||||||
|
* @param string $name 字段名称
|
||||||
|
* @param string $title 字段标题
|
||||||
|
* @param string $substr 字段子标题
|
||||||
|
* @param bool $required 必填字段
|
||||||
|
* @param array $attrs 附加属性
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function addUploadMulImage(string $name, string $title, string $substr = '', bool $required = false, array $attrs = []): Builder
|
||||||
|
{
|
||||||
|
if ($required) {
|
||||||
|
$attrs['required'] = 'required';
|
||||||
|
}
|
||||||
|
$attrs = array_merge($attrs, ['type' => 'hidden', 'placeholder' => "请上传{$title} ( 多图 )"]);
|
||||||
|
$html = "\n\t\t" . '<div class="layui-form-item">';
|
||||||
|
$html .= "\n\t\t\t" . sprintf('<span class="help-label %s"><b>%s</b>%s</span>', empty($attrs['required']) ? '' : 'label-required-prev ', $title, $substr);
|
||||||
|
$html .= "\n\t\t\t" . '<div class="layui-textarea help-images layui-bg-gray">';
|
||||||
|
$html .= "\n\t\t\t\t" . sprintf('<input name="%s" %s value="{%s.%s|default=\'\'}">', $name, $this->_attrs($attrs), $this->variable, $name);
|
||||||
|
$html .= "\n\t\t\t" . '</div>' . "\n\t\t" . '</div>';
|
||||||
|
$html .= "\n\t\t" . sprintf('<script>$("input[name=%s]").uploadMultipleImage()</script>', $name);
|
||||||
|
$this->fields[] = $html;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建复选框字段.
|
||||||
|
* @param string $name 字段名称
|
||||||
|
* @param string $title 字段标题
|
||||||
|
* @param string $substr 字段子标题
|
||||||
|
* @param string $vname 变量名称
|
||||||
|
* @param bool $required 是否必选
|
||||||
|
* @param array $attrs 附加属性
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function addCheckInput(string $name, string $title, string $substr, string $vname, bool $required = false, array $attrs = [], string $type = 'checkbox'): Builder
|
||||||
|
{
|
||||||
|
if ($required) {
|
||||||
|
$attrs['required'] = 'required';
|
||||||
|
}
|
||||||
|
$attrs = array_merge($attrs, ['type' => $type, 'lay-ignore' => null, 'name' => $name . ($type === 'checkbox' ? '[]' : '')]);
|
||||||
|
$html = "\n\t\t" . '<div class="layui-form-item">';
|
||||||
|
$html .= "\n\t\t\t" . sprintf('<span class="help-label %s"><b>%s</b>%s</span>', empty($attrs['required']) ? '' : ' label-required-prev', $title, $substr);
|
||||||
|
$html .= "\n\t\t\t" . '<div class="layui-textarea help-checks layui-bg-gray">';
|
||||||
|
$html .= "\n\t\t\t\t" . sprintf('<!--{foreach $%s as $k=>$v}item-->', $vname);
|
||||||
|
$html .= "\n\t\t\t\t" . sprintf('<label class="think-%s label-required-null">', $type);
|
||||||
|
$html .= "\n\t\t\t\t\t" . sprintf('<!--if{if isset(%s.types) and is_array(%s.types) and in_array($k,%s.types)}-->', $this->variable, $this->variable, $this->variable);
|
||||||
|
$html .= "\n\t\t\t\t\t" . sprintf('<input value="{$k|default=\'\'}" %s checked> {$v|default=\'\'}', $this->_attrs($attrs));
|
||||||
|
$html .= "\n\t\t\t\t\t" . '<!--{else}else-->';
|
||||||
|
$html .= "\n\t\t\t\t\t" . sprintf('<input value="{$k|default=\'\'}" %s> {$v|default=\'\'}', $this->_attrs($attrs)) . "\n";
|
||||||
|
$html .= "\n\t\t\t\t\t" . '<!--{/if}if-->';
|
||||||
|
$html .= "\n\t\t\t\t" . '</label>';
|
||||||
|
$html .= "\n\t\t\t\t" . '<!--{/foreach}end-->';
|
||||||
|
$this->fields[] = $html . "\n\t\t\t</div>\n\t\t</div>";
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加单选框架字段.
|
||||||
|
* @param string $name 字段名称
|
||||||
|
* @param string $title 字段标题
|
||||||
|
* @param string $substr 字段子标题
|
||||||
|
* @param string $vname 变量名称
|
||||||
|
* @param bool $required 是否必选
|
||||||
|
* @param array $attrs 附加属性
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function addRadioInput(string $name, string $title, string $substr, string $vname, bool $required = false, array $attrs = []): Builder
|
||||||
|
{
|
||||||
|
return $this->addCheckInput($name, $title, $substr, $vname, $required, $attrs, 'radio');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 显示模板内容.
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function fetch(array $vars = [])
|
||||||
|
{
|
||||||
|
$html = '';
|
||||||
|
$type = "{$this->type}.{$this->mode}";
|
||||||
|
if ($type === 'form.page') {
|
||||||
|
$html = $this->_buildFormPage();
|
||||||
|
} elseif ($type === 'form.modal') {
|
||||||
|
$html = $this->_buildFormModal();
|
||||||
|
}
|
||||||
|
foreach ($this->class as $k => $v) {
|
||||||
|
$vars[$k] = $v;
|
||||||
|
}
|
||||||
|
throw new HttpResponseException(display($html, $vars));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 增加输入表单元素.
|
||||||
* @param string $name 字段名称
|
* @param string $name 字段名称
|
||||||
* @param string $title 字段标题
|
* @param string $title 字段标题
|
||||||
* @param string $subtitle 字段子标题
|
* @param string $subtitle 字段子标题
|
||||||
@ -126,80 +335,26 @@ class Builder
|
|||||||
$html = "\n\t\t" . '<label class="layui-form-item block relative">';
|
$html = "\n\t\t" . '<label class="layui-form-item block relative">';
|
||||||
$html .= "\n\t\t\t" . sprintf('<span class="help-label %s"><b>%s</b>%s</span>', empty($attrs['required']) ? '' : 'label-required-prev', $title, $subtitle);
|
$html .= "\n\t\t\t" . sprintf('<span class="help-label %s"><b>%s</b>%s</span>', empty($attrs['required']) ? '' : 'label-required-prev', $title, $subtitle);
|
||||||
$html .= "\n\t\t\t" . sprintf('<input name="%s" %s placeholder="请输入%s" value="{%s.%s|default=\'\'}" class="layui-input">', $name, $this->_attrs($attrs), $title, $this->variable, $name);
|
$html .= "\n\t\t\t" . sprintf('<input name="%s" %s placeholder="请输入%s" value="{%s.%s|default=\'\'}" class="layui-input">', $name, $this->_attrs($attrs), $title, $this->variable, $name);
|
||||||
if ($remark) $html .= "\n\t\t\t" . sprintf('<span class="help-block">%s</span>', $remark);
|
if ($remark) {
|
||||||
|
$html .= "\n\t\t\t" . sprintf('<span class="help-block">%s</span>', $remark);
|
||||||
|
}
|
||||||
$this->fields[] = "{$html}\n\t\t</label>";
|
$this->fields[] = "{$html}\n\t\t</label>";
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建文本输入框架
|
* 字段属性转换.
|
||||||
* @param string $name 字段名称
|
|
||||||
* @param string $title 字段标题
|
|
||||||
* @param string $substr 字段子标题
|
|
||||||
* @param array $attrs 附加属性
|
|
||||||
* @return $this
|
|
||||||
*/
|
|
||||||
public function addTextArea(string $name, string $title, string $substr = '', bool $required = false, $remark = '', array $attrs = []): Builder
|
|
||||||
{
|
|
||||||
if ($required) $attrs['required'] = 'required';
|
|
||||||
$html = "\n\t\t" . '<label class="layui-form-item block relative">';
|
|
||||||
$html .= "\n\t\t\t" . sprintf('<span class="help-label %s"><b>%s</b>%s</span>', empty($attrs['required']) ? '' : 'label-required-prev', $title, $substr);
|
|
||||||
$html .= "\n\t\t\t" . sprintf('<textarea name="%s" %s placeholder="请输入%s" class="layui-textarea">{%s.%s|default=\'\'}</textarea>', $name, $this->_attrs($attrs), $title, $this->variable, $name);
|
|
||||||
if ($remark) $html .= "\n\t\t\t" . sprintf('<span class="help-block">%s</span>', $remark);
|
|
||||||
$this->fields[] = "{$html}\n\t\t</lable>";
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 字段属性转换
|
|
||||||
* @param array $attrs
|
|
||||||
* @param string $html
|
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
protected function _attrs(array $attrs, string $html = ''): string
|
protected function _attrs(array $attrs, string $html = ''): string
|
||||||
{
|
{
|
||||||
foreach ($attrs as $k => $v) $html .= is_null($v) ? sprintf(' %s', $k) : sprintf(' %s="%s"', $k, $v);
|
foreach ($attrs as $k => $v) {
|
||||||
|
$html .= is_null($v) ? sprintf(' %s', $k) : sprintf(' %s="%s"', $k, $v);
|
||||||
|
}
|
||||||
return $html;
|
return $html;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建 Text 输入
|
* 添加表单按钮.
|
||||||
* @param string $name 字段名称
|
|
||||||
* @param string $title 字段标题
|
|
||||||
* @param string $substr 字段子标题
|
|
||||||
* @param string $remark 字段备注
|
|
||||||
* @param boolean $required 是否必填
|
|
||||||
* @param ?string $pattern 验证规则
|
|
||||||
* @param array $attrs 附加属性
|
|
||||||
* @return $this
|
|
||||||
*/
|
|
||||||
public function addTextInput(string $name, string $title, string $substr = '', bool $required = false, string $remark = '', ?string $pattern = null, array $attrs = []): Builder
|
|
||||||
{
|
|
||||||
$attrs['vali-name'] = $title;
|
|
||||||
if ($required) $attrs['required'] = 'required';
|
|
||||||
if (is_string($pattern)) $attrs['pattern'] = $pattern;
|
|
||||||
return $this->addInput($name, $title, $substr, $remark, $attrs);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建密钥输入框
|
|
||||||
* @param string $name 字段名称
|
|
||||||
* @param string $title 字段标题
|
|
||||||
* @param string $substr 字段子标题
|
|
||||||
* @param string $remark 字段备注
|
|
||||||
* @param boolean $required 是否必填
|
|
||||||
* @param ?string $pattern 验证规则
|
|
||||||
* @param array $attrs 附加属性
|
|
||||||
* @return $this
|
|
||||||
*/
|
|
||||||
public function addPassInput(string $name, string $title, string $substr = '', bool $required = false, string $remark = '', ?string $pattern = null, array $attrs = []): Builder
|
|
||||||
{
|
|
||||||
$attrs['type'] = 'password';
|
|
||||||
return $this->addTextInput($name, $title, $substr, $required, $remark, $pattern, $attrs);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 添加表单按钮
|
|
||||||
* @param string $name 按钮名称
|
* @param string $name 按钮名称
|
||||||
* @param string $confirm 确认提示
|
* @param string $confirm 确认提示
|
||||||
* @param string $type 按钮类型
|
* @param string $type 按钮类型
|
||||||
@ -210,35 +365,15 @@ class Builder
|
|||||||
protected function addButton(string $name, string $confirm, string $type, string $class = '', array $attrs = []): Builder
|
protected function addButton(string $name, string $confirm, string $type, string $class = '', array $attrs = []): Builder
|
||||||
{
|
{
|
||||||
$attrs['type'] = $type;
|
$attrs['type'] = $type;
|
||||||
if ($confirm) $attrs['data-confirm'] = $confirm;
|
if ($confirm) {
|
||||||
|
$attrs['data-confirm'] = $confirm;
|
||||||
|
}
|
||||||
$this->buttons[] = sprintf('<button class="layui-btn %s" %s>%s</button>', $class, $this->_attrs($attrs), $name);
|
$this->buttons[] = sprintf('<button class="layui-btn %s" %s>%s</button>', $class, $this->_attrs($attrs), $name);
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 添加取消按钮
|
* 添加上传单个文件.
|
||||||
* @param string $name 按钮名称
|
|
||||||
* @param string $confirm 确认提示
|
|
||||||
* @return $this
|
|
||||||
*/
|
|
||||||
public function addCancelButton(string $name = '取消编辑', string $confirm = '确定要取消编辑吗?'): Builder
|
|
||||||
{
|
|
||||||
return $this->addButton($name, $confirm, 'button', 'layui-btn-danger', ['data-close' => null]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 添加提交按钮
|
|
||||||
* @param string $name 按钮名称
|
|
||||||
* @param string $confirm 确认提示
|
|
||||||
* @return $this
|
|
||||||
*/
|
|
||||||
public function addSubmitButton(string $name = '保存数据', string $confirm = ''): Builder
|
|
||||||
{
|
|
||||||
return $this->addButton($name, $confirm, 'submit');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 添加上传单个文件
|
|
||||||
* @param string $name 字段名称
|
* @param string $name 字段名称
|
||||||
* @param string $title 字段标题
|
* @param string $title 字段标题
|
||||||
* @param string $substr 字段子标题
|
* @param string $substr 字段子标题
|
||||||
@ -268,124 +403,8 @@ class Builder
|
|||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 添加上传单图字段
|
|
||||||
* @param string $name 字段名称
|
|
||||||
* @param string $title 字段标题
|
|
||||||
* @param string $substr 字段子标题
|
|
||||||
* @param bool $required 必填字段
|
|
||||||
* @param array $attrs 附加属性
|
|
||||||
* @return $this
|
|
||||||
*/
|
|
||||||
public function addUploadOneImage(string $name, string $title, string $substr = '', bool $required = false, array $attrs = []): Builder
|
|
||||||
{
|
|
||||||
if ($required) $attrs['required'] = 'required';
|
|
||||||
return $this->_addUploadOneView($name, $title, $substr, $attrs);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 添加上传视频字段
|
|
||||||
* @param string $name 字段名称
|
|
||||||
* @param string $title 字段标题
|
|
||||||
* @param string $substr 字段子标题
|
|
||||||
* @param bool $required 必填字段
|
|
||||||
* @param array $attrs 附加属性
|
|
||||||
* @return $this
|
|
||||||
*/
|
|
||||||
public function addUploadOneVideo(string $name, string $title, string $substr = '', bool $required = false, array $attrs = []): Builder
|
|
||||||
{
|
|
||||||
if ($required) $attrs['required'] = 'required';
|
|
||||||
return $this->_addUploadOneView($name, $title, $substr, $attrs, 'video');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建上传多图字段
|
|
||||||
* @param string $name 字段名称
|
|
||||||
* @param string $title 字段标题
|
|
||||||
* @param string $substr 字段子标题
|
|
||||||
* @param bool $required 必填字段
|
|
||||||
* @param array $attrs 附加属性
|
|
||||||
* @return $this
|
|
||||||
*/
|
|
||||||
public function addUploadMulImage(string $name, string $title, string $substr = '', bool $required = false, array $attrs = []): Builder
|
|
||||||
{
|
|
||||||
if ($required) $attrs['required'] = 'required';
|
|
||||||
$attrs = array_merge($attrs, ['type' => 'hidden', 'placeholder' => "请上传{$title} ( 多图 )"]);
|
|
||||||
$html = "\n\t\t" . '<div class="layui-form-item">';
|
|
||||||
$html .= "\n\t\t\t" . sprintf('<span class="help-label %s"><b>%s</b>%s</span>', empty($attrs['required']) ? '' : 'label-required-prev ', $title, $substr);
|
|
||||||
$html .= "\n\t\t\t" . '<div class="layui-textarea help-images layui-bg-gray">';
|
|
||||||
$html .= "\n\t\t\t\t" . sprintf('<input name="%s" %s value="{%s.%s|default=\'\'}">', $name, $this->_attrs($attrs), $this->variable, $name);
|
|
||||||
$html .= "\n\t\t\t" . '</div>' . "\n\t\t" . '</div>';
|
|
||||||
$html .= "\n\t\t" . sprintf('<script>$("input[name=%s]").uploadMultipleImage()</script>', $name);
|
|
||||||
$this->fields[] = $html;
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建复选框字段
|
|
||||||
* @param string $name 字段名称
|
|
||||||
* @param string $title 字段标题
|
|
||||||
* @param string $substr 字段子标题
|
|
||||||
* @param string $vname 变量名称
|
|
||||||
* @param bool $required 是否必选
|
|
||||||
* @param array $attrs 附加属性
|
|
||||||
* @return $this
|
|
||||||
*/
|
|
||||||
public function addCheckInput(string $name, string $title, string $substr, string $vname, bool $required = false, array $attrs = [], string $type = 'checkbox'): Builder
|
|
||||||
{
|
|
||||||
if ($required) $attrs['required'] = 'required';
|
|
||||||
$attrs = array_merge($attrs, ['type' => $type, 'lay-ignore' => null, 'name' => $name . ($type === 'checkbox' ? '[]' : '')]);
|
|
||||||
$html = "\n\t\t" . '<div class="layui-form-item">';
|
|
||||||
$html .= "\n\t\t\t" . sprintf('<span class="help-label %s"><b>%s</b>%s</span>', empty($attrs['required']) ? '' : ' label-required-prev', $title, $substr);
|
|
||||||
$html .= "\n\t\t\t" . '<div class="layui-textarea help-checks layui-bg-gray">';
|
|
||||||
$html .= "\n\t\t\t\t" . sprintf('<!--{foreach $%s as $k=>$v}item-->', $vname);
|
|
||||||
$html .= "\n\t\t\t\t" . sprintf('<label class="think-%s label-required-null">', $type);
|
|
||||||
$html .= "\n\t\t\t\t\t" . sprintf('<!--if{if isset(%s.types) and is_array(%s.types) and in_array($k,%s.types)}-->', $this->variable, $this->variable, $this->variable);
|
|
||||||
$html .= "\n\t\t\t\t\t" . sprintf('<input value="{$k|default=\'\'}" %s checked> {$v|default=\'\'}', $this->_attrs($attrs));
|
|
||||||
$html .= "\n\t\t\t\t\t" . '<!--{else}else-->';
|
|
||||||
$html .= "\n\t\t\t\t\t" . sprintf('<input value="{$k|default=\'\'}" %s> {$v|default=\'\'}', $this->_attrs($attrs)) . "\n";
|
|
||||||
$html .= "\n\t\t\t\t\t" . '<!--{/if}if-->';
|
|
||||||
$html .= "\n\t\t\t\t" . '</label>';
|
|
||||||
$html .= "\n\t\t\t\t" . '<!--{/foreach}end-->';
|
|
||||||
$this->fields[] = $html . "\n\t\t\t</div>\n\t\t</div>";
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 添加单选框架字段
|
|
||||||
* @param string $name 字段名称
|
|
||||||
* @param string $title 字段标题
|
|
||||||
* @param string $substr 字段子标题
|
|
||||||
* @param string $vname 变量名称
|
|
||||||
* @param bool $required 是否必选
|
|
||||||
* @param array $attrs 附加属性
|
|
||||||
* @return $this
|
|
||||||
*/
|
|
||||||
public function addRadioInput(string $name, string $title, string $substr, string $vname, bool $required = false, array $attrs = []): Builder
|
|
||||||
{
|
|
||||||
return $this->addCheckInput($name, $title, $substr, $vname, $required, $attrs, 'radio');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 显示模板内容
|
|
||||||
* @return mixed
|
|
||||||
*/
|
|
||||||
public function fetch(array $vars = [])
|
|
||||||
{
|
|
||||||
$html = '';
|
|
||||||
$type = "{$this->type}.{$this->mode}";
|
|
||||||
if ($type === 'form.page') {
|
|
||||||
$html = $this->_buildFormPage();
|
|
||||||
} elseif ($type === 'form.modal') {
|
|
||||||
$html = $this->_buildFormModal();
|
|
||||||
}
|
|
||||||
foreach ($this->class as $k => $v) $vars[$k] = $v;
|
|
||||||
throw new HttpResponseException(display($html, $vars));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 生成弹层表单模板
|
* 生成弹层表单模板
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
private function _buildFormModal(): string
|
private function _buildFormModal(): string
|
||||||
{
|
{
|
||||||
@ -402,10 +421,9 @@ class Builder
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 生成页面表单模板
|
* 生成页面表单模板
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
private function _buildFormPage(): string
|
private function _buildFormPage(): string
|
||||||
{
|
{
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,20 +1,22 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// +----------------------------------------------------------------------
|
declare(strict_types=1);
|
||||||
// | Library for ThinkAdmin
|
/**
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 版权所有 2014~2025 ThinkAdmin [ thinkadmin.top ]
|
* | Payment Plugin for ThinkAdmin
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 官方网站: https://thinkadmin.top
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 开源协议 ( https://mit-license.org )
|
* | 官方网站: https://thinkadmin.top
|
||||||
// | 免费声明 ( https://thinkadmin.top/disclaimer )
|
* +----------------------------------------------------------------------
|
||||||
// +----------------------------------------------------------------------
|
* | 开源协议 ( https://mit-license.org )
|
||||||
// | gitee 仓库地址 :https://gitee.com/zoujingli/ThinkLibrary
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
// | github 仓库地址 :https://github.com/zoujingli/ThinkLibrary
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
declare (strict_types=1);
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
namespace think\admin;
|
namespace think\admin;
|
||||||
|
|
||||||
@ -24,9 +26,8 @@ use think\console\Input;
|
|||||||
use think\console\Output;
|
use think\console\Output;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 自定义指令基类
|
* 自定义指令基类.
|
||||||
* @class Command
|
* @class Command
|
||||||
* @package think\admin
|
|
||||||
*/
|
*/
|
||||||
abstract class Command extends \think\console\Command
|
abstract class Command extends \think\console\Command
|
||||||
{
|
{
|
||||||
@ -43,11 +44,24 @@ abstract class Command extends \think\console\Command
|
|||||||
protected $process;
|
protected $process;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 初始化指令变量
|
* 更新任务进度.
|
||||||
* @param \think\console\Input $input
|
* @param int $total 记录总和
|
||||||
* @param \think\console\Output $output
|
* @param int $count 当前记录
|
||||||
|
* @param string $message 文字描述
|
||||||
|
* @param int $backline 回退行数
|
||||||
|
* @return static
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public function setQueueMessage(int $total, int $count, string $message = '', int $backline = 0): Command
|
||||||
|
{
|
||||||
|
$this->queue->message($total, $count, $message, $backline);
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化指令变量.
|
||||||
* @return $this
|
* @return $this
|
||||||
* @throws \think\admin\Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
protected function initialize(Input $input, Output $output): Command
|
protected function initialize(Input $input, Output $output): Command
|
||||||
{
|
{
|
||||||
@ -60,9 +74,9 @@ abstract class Command extends \think\console\Command
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置失败消息并结束进程
|
* 设置失败消息并结束进程.
|
||||||
* @param string $message 消息内容
|
* @param string $message 消息内容
|
||||||
* @throws \think\admin\Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
protected function setQueueError(string $message)
|
protected function setQueueError(string $message)
|
||||||
{
|
{
|
||||||
@ -75,9 +89,9 @@ abstract class Command extends \think\console\Command
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置成功消息并结束进程
|
* 设置成功消息并结束进程.
|
||||||
* @param string $message 消息内容
|
* @param string $message 消息内容
|
||||||
* @throws \think\admin\Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
protected function setQueueSuccess(string $message)
|
protected function setQueueSuccess(string $message)
|
||||||
{
|
{
|
||||||
@ -90,12 +104,12 @@ abstract class Command extends \think\console\Command
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置进度消息并继续执行
|
* 设置进度消息并继续执行.
|
||||||
* @param null|string $message 进度消息
|
* @param null|string $message 进度消息
|
||||||
* @param null|string $progress 进度数值
|
* @param null|string $progress 进度数值
|
||||||
* @param integer $backline 回退行数
|
* @param int $backline 回退行数
|
||||||
* @return static
|
* @return static
|
||||||
* @throws \think\admin\Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
protected function setQueueProgress(?string $message = null, ?string $progress = null, int $backline = 0): Command
|
protected function setQueueProgress(?string $message = null, ?string $progress = null, int $backline = 0): Command
|
||||||
{
|
{
|
||||||
@ -106,19 +120,4 @@ abstract class Command extends \think\console\Command
|
|||||||
}
|
}
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
/**
|
|
||||||
* 更新任务进度
|
|
||||||
* @param integer $total 记录总和
|
|
||||||
* @param integer $count 当前记录
|
|
||||||
* @param string $message 文字描述
|
|
||||||
* @param integer $backline 回退行数
|
|
||||||
* @return static
|
|
||||||
* @throws \think\admin\Exception
|
|
||||||
*/
|
|
||||||
public function setQueueMessage(int $total, int $count, string $message = '', int $backline = 0): Command
|
|
||||||
{
|
|
||||||
$this->queue->message($total, $count, $message, $backline);
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@ -1,24 +1,25 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// +----------------------------------------------------------------------
|
declare(strict_types=1);
|
||||||
// | Library for ThinkAdmin
|
/**
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 版权所有 2014~2025 ThinkAdmin [ thinkadmin.top ]
|
* | Payment Plugin for ThinkAdmin
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 官方网站: https://thinkadmin.top
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 开源协议 ( https://mit-license.org )
|
* | 官方网站: https://thinkadmin.top
|
||||||
// | 免费声明 ( https://thinkadmin.top/disclaimer )
|
* +----------------------------------------------------------------------
|
||||||
// +----------------------------------------------------------------------
|
* | 开源协议 ( https://mit-license.org )
|
||||||
// | gitee 仓库地址 :https://gitee.com/zoujingli/ThinkLibrary
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
// | github 仓库地址 :https://github.com/zoujingli/ThinkLibrary
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
declare (strict_types=1);
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
namespace think\admin;
|
namespace think\admin;
|
||||||
|
|
||||||
use stdClass;
|
|
||||||
use think\admin\extend\JwtExtend;
|
use think\admin\extend\JwtExtend;
|
||||||
use think\admin\helper\DeleteHelper;
|
use think\admin\helper\DeleteHelper;
|
||||||
use think\admin\helper\FormHelper;
|
use think\admin\helper\FormHelper;
|
||||||
@ -31,32 +32,33 @@ use think\admin\service\NodeService;
|
|||||||
use think\admin\service\QueueService;
|
use think\admin\service\QueueService;
|
||||||
use think\App;
|
use think\App;
|
||||||
use think\db\BaseQuery;
|
use think\db\BaseQuery;
|
||||||
|
use think\db\exception\DataNotFoundException;
|
||||||
|
use think\db\exception\DbException;
|
||||||
|
use think\db\exception\ModelNotFoundException;
|
||||||
use think\exception\HttpResponseException;
|
use think\exception\HttpResponseException;
|
||||||
use think\Model;
|
use think\Model;
|
||||||
use think\Request;
|
use think\Request;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 标准控制器基类
|
* 标准控制器基类.
|
||||||
* @class Controller
|
* @class Controller
|
||||||
* @package think\admin
|
|
||||||
*/
|
*/
|
||||||
class Controller extends stdClass
|
class Controller extends \stdClass
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 应用容器
|
* 应用容器.
|
||||||
* @var App
|
* @var App
|
||||||
*/
|
*/
|
||||||
public $app;
|
public $app;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 请求GET参数
|
* 请求GET参数.
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
public $get = [];
|
public $get = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 当前功能节点
|
* 当前功能节点.
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
public $node;
|
public $node;
|
||||||
@ -69,19 +71,18 @@ class Controller extends stdClass
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 表单CSRF验证状态
|
* 表单CSRF验证状态
|
||||||
* @var boolean
|
* @var bool
|
||||||
*/
|
*/
|
||||||
public $csrf_state = false;
|
public $csrf_state = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 表单CSRF验证消息
|
* 表单CSRF验证消息.
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
public $csrf_message;
|
public $csrf_message;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
* @param App $app
|
|
||||||
*/
|
*/
|
||||||
public function __construct(App $app)
|
public function __construct(App $app)
|
||||||
{
|
{
|
||||||
@ -96,14 +97,7 @@ class Controller extends stdClass
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 控制器初始化
|
* 返回失败的内容.
|
||||||
*/
|
|
||||||
protected function initialize()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 返回失败的内容
|
|
||||||
* @param mixed $info 消息内容
|
* @param mixed $info 消息内容
|
||||||
* @param mixed $data 返回数据
|
* @param mixed $data 返回数据
|
||||||
* @param mixed $code 返回代码
|
* @param mixed $code 返回代码
|
||||||
@ -114,23 +108,27 @@ class Controller extends stdClass
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 返回成功的内容
|
* 返回成功的内容.
|
||||||
* @param mixed $info 消息内容
|
* @param mixed $info 消息内容
|
||||||
* @param mixed $data 返回数据
|
* @param mixed $data 返回数据
|
||||||
* @param mixed $code 返回代码
|
* @param mixed $code 返回代码
|
||||||
*/
|
*/
|
||||||
public function success($info, $data = '{-null-}', $code = 1): void
|
public function success($info, $data = '{-null-}', $code = 1): void
|
||||||
{
|
{
|
||||||
if ($data === '{-null-}') $data = new stdClass();
|
if ($data === '{-null-}') {
|
||||||
|
$data = new \stdClass();
|
||||||
|
}
|
||||||
$result = ['code' => $code, 'info' => is_string($info) ? lang($info) : $info, 'data' => $data];
|
$result = ['code' => $code, 'info' => is_string($info) ? lang($info) : $info, 'data' => $data];
|
||||||
if (JwtExtend::isRejwt()) $result['token'] = JwtExtend::token();
|
if (JwtExtend::isRejwt()) {
|
||||||
|
$result['token'] = JwtExtend::token();
|
||||||
|
}
|
||||||
throw new HttpResponseException(json($result));
|
throw new HttpResponseException(json($result));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* URL重定向
|
* URL重定向.
|
||||||
* @param string $url 跳转链接
|
* @param string $url 跳转链接
|
||||||
* @param integer $code 跳转代码
|
* @param int $code 跳转代码
|
||||||
*/
|
*/
|
||||||
public function redirect(string $url, int $code = 302): void
|
public function redirect(string $url, int $code = 302): void
|
||||||
{
|
{
|
||||||
@ -138,7 +136,7 @@ class Controller extends stdClass
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 返回视图内容
|
* 返回视图内容.
|
||||||
* @param string $tpl 模板名称
|
* @param string $tpl 模板名称
|
||||||
* @param array $vars 模板变量
|
* @param array $vars 模板变量
|
||||||
* @param null|string $node 授权节点
|
* @param null|string $node 授权节点
|
||||||
@ -168,28 +166,31 @@ class Controller extends stdClass
|
|||||||
public function assign($name, $value = ''): Controller
|
public function assign($name, $value = ''): Controller
|
||||||
{
|
{
|
||||||
if (is_string($name)) {
|
if (is_string($name)) {
|
||||||
$this->$name = $value;
|
$this->{$name} = $value;
|
||||||
} elseif (is_array($name)) {
|
} elseif (is_array($name)) {
|
||||||
foreach ($name as $k => $v) {
|
foreach ($name as $k => $v) {
|
||||||
if (is_string($k)) $this->$k = $v;
|
if (is_string($k)) {
|
||||||
|
$this->{$k} = $v;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 数据回调处理机制
|
* 数据回调处理机制.
|
||||||
* @param string $name 回调方法名称
|
* @param string $name 回调方法名称
|
||||||
* @param mixed $one 回调引用参数1
|
* @param mixed $one 回调引用参数1
|
||||||
* @param mixed $two 回调引用参数2
|
* @param mixed $two 回调引用参数2
|
||||||
* @param mixed $thr 回调引用参数3
|
* @param mixed $thr 回调引用参数3
|
||||||
* @return boolean
|
|
||||||
*/
|
*/
|
||||||
public function callback(string $name, &$one = [], &$two = [], &$thr = []): bool
|
public function callback(string $name, &$one = [], &$two = [], &$thr = []): bool
|
||||||
{
|
{
|
||||||
if (is_callable($name)) return call_user_func($name, $this, $one, $two, $thr);
|
if (is_callable($name)) {
|
||||||
|
return call_user_func($name, $this, $one, $two, $thr);
|
||||||
|
}
|
||||||
foreach (["_{$this->app->request->action()}{$name}", $name] as $method) {
|
foreach (["_{$this->app->request->action()}{$name}", $name] as $method) {
|
||||||
if (method_exists($this, $method) && false === $this->$method($one, $two, $thr)) {
|
if (method_exists($this, $method) && $this->{$method}($one, $two, $thr) === false) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -197,11 +198,15 @@ class Controller extends stdClass
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 快捷查询逻辑器
|
* 控制器初始化.
|
||||||
|
*/
|
||||||
|
protected function initialize() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 快捷查询逻辑器.
|
||||||
* @param BaseQuery|Model|string $dbQuery
|
* @param BaseQuery|Model|string $dbQuery
|
||||||
* @param array|string|null $input
|
* @param null|array|string $input
|
||||||
* @return QueryHelper
|
* @throws DbException
|
||||||
* @throws \think\db\exception\DbException
|
|
||||||
*/
|
*/
|
||||||
protected function _query($dbQuery, $input = null): QueryHelper
|
protected function _query($dbQuery, $input = null): QueryHelper
|
||||||
{
|
{
|
||||||
@ -209,17 +214,16 @@ class Controller extends stdClass
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 快捷分页逻辑器
|
* 快捷分页逻辑器.
|
||||||
* @param BaseQuery|Model|string $dbQuery
|
* @param BaseQuery|Model|string $dbQuery
|
||||||
* @param boolean|integer $page 是否分页或指定分页
|
* @param bool|int $page 是否分页或指定分页
|
||||||
* @param boolean $display 是否渲染模板
|
* @param bool $display 是否渲染模板
|
||||||
* @param boolean|integer $total 集合分页记录数
|
* @param bool|int $total 集合分页记录数
|
||||||
* @param integer $limit 集合每页记录数
|
* @param int $limit 集合每页记录数
|
||||||
* @param string $template 模板文件名称
|
* @param string $template 模板文件名称
|
||||||
* @return array
|
* @throws DataNotFoundException
|
||||||
* @throws \think\db\exception\DataNotFoundException
|
* @throws DbException
|
||||||
* @throws \think\db\exception\DbException
|
* @throws ModelNotFoundException
|
||||||
* @throws \think\db\exception\ModelNotFoundException
|
|
||||||
*/
|
*/
|
||||||
protected function _page($dbQuery, $page = true, bool $display = true, $total = false, int $limit = 0, string $template = ''): array
|
protected function _page($dbQuery, $page = true, bool $display = true, $total = false, int $limit = 0, string $template = ''): array
|
||||||
{
|
{
|
||||||
@ -227,17 +231,17 @@ class Controller extends stdClass
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 快捷表单逻辑器
|
* 快捷表单逻辑器.
|
||||||
* @param BaseQuery|Model|string $dbQuery
|
* @param BaseQuery|Model|string $dbQuery
|
||||||
* @param string $template 模板名称
|
* @param string $template 模板名称
|
||||||
* @param string $field 指定数据主键
|
* @param string $field 指定数据主键
|
||||||
* @param mixed $where 额外更新条件
|
* @param mixed $where 额外更新条件
|
||||||
* @param array $data 表单扩展数据
|
* @param array $data 表单扩展数据
|
||||||
* @return array|boolean
|
* @return array|bool
|
||||||
* @throws \think\admin\Exception
|
* @throws Exception
|
||||||
* @throws \think\db\exception\DataNotFoundException
|
* @throws DataNotFoundException
|
||||||
* @throws \think\db\exception\DbException
|
* @throws DbException
|
||||||
* @throws \think\db\exception\ModelNotFoundException
|
* @throws ModelNotFoundException
|
||||||
*/
|
*/
|
||||||
protected function _form($dbQuery, string $template = '', string $field = '', $where = [], array $data = [])
|
protected function _form($dbQuery, string $template = '', string $field = '', $where = [], array $data = [])
|
||||||
{
|
{
|
||||||
@ -245,11 +249,10 @@ class Controller extends stdClass
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 快捷输入并验证( 支持 规则 # 别名 )
|
* 快捷输入并验证( 支持 规则 # 别名 ).
|
||||||
* @param array $rules 验证规则( 验证信息数组 )
|
* @param array $rules 验证规则( 验证信息数组 )
|
||||||
* @param string|array $type 输入方式 ( post. 或 get. )
|
* @param array|string $type 输入方式 ( post. 或 get. )
|
||||||
* @param callable|null $callable 异常处理操作
|
* @param null|callable $callable 异常处理操作
|
||||||
* @return array
|
|
||||||
*/
|
*/
|
||||||
protected function _vali(array $rules, $type = '', ?callable $callable = null): array
|
protected function _vali(array $rules, $type = '', ?callable $callable = null): array
|
||||||
{
|
{
|
||||||
@ -257,13 +260,12 @@ class Controller extends stdClass
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 快捷更新逻辑器
|
* 快捷更新逻辑器.
|
||||||
* @param BaseQuery|Model|string $dbQuery
|
* @param BaseQuery|Model|string $dbQuery
|
||||||
* @param array $data 表单扩展数据
|
* @param array $data 表单扩展数据
|
||||||
* @param string $field 数据对象主键
|
* @param string $field 数据对象主键
|
||||||
* @param mixed $where 额外更新条件
|
* @param mixed $where 额外更新条件
|
||||||
* @return boolean
|
* @throws DbException
|
||||||
* @throws \think\db\exception\DbException
|
|
||||||
*/
|
*/
|
||||||
protected function _save($dbQuery, array $data = [], string $field = '', $where = []): bool
|
protected function _save($dbQuery, array $data = [], string $field = '', $where = []): bool
|
||||||
{
|
{
|
||||||
@ -271,12 +273,11 @@ class Controller extends stdClass
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 快捷删除逻辑器
|
* 快捷删除逻辑器.
|
||||||
* @param BaseQuery|Model|string $dbQuery
|
* @param BaseQuery|Model|string $dbQuery
|
||||||
* @param string $field 数据对象主键
|
* @param string $field 数据对象主键
|
||||||
* @param mixed $where 额外更新条件
|
* @param mixed $where 额外更新条件
|
||||||
* @return boolean
|
* @throws DbException
|
||||||
* @throws \think\db\exception\DbException
|
|
||||||
*/
|
*/
|
||||||
protected function _delete($dbQuery, string $field = '', $where = []): bool
|
protected function _delete($dbQuery, string $field = '', $where = []): bool
|
||||||
{
|
{
|
||||||
@ -285,8 +286,7 @@ class Controller extends stdClass
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 检查表单令牌验证
|
* 检查表单令牌验证
|
||||||
* @param boolean $return 是否返回结果
|
* @param bool $return 是否返回结果
|
||||||
* @return boolean
|
|
||||||
*/
|
*/
|
||||||
protected function _applyFormToken(bool $return = false): bool
|
protected function _applyFormToken(bool $return = false): bool
|
||||||
{
|
{
|
||||||
@ -294,13 +294,13 @@ class Controller extends stdClass
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建异步任务并返回任务编号
|
* 创建异步任务并返回任务编号.
|
||||||
* @param string $title 任务名称
|
* @param string $title 任务名称
|
||||||
* @param string $command 执行内容
|
* @param string $command 执行内容
|
||||||
* @param integer $later 延时执行时间
|
* @param int $later 延时执行时间
|
||||||
* @param array $data 任务附加数据
|
* @param array $data 任务附加数据
|
||||||
* @param integer $rscript 任务类型(0单例,1多例)
|
* @param int $rscript 任务类型(0单例,1多例)
|
||||||
* @param integer $loops 循环等待时间
|
* @param int $loops 循环等待时间
|
||||||
*/
|
*/
|
||||||
protected function _queue(string $title, string $command, int $later = 0, array $data = [], int $rscript = 0, int $loops = 0)
|
protected function _queue(string $title, string $command, int $later = 0, array $data = [], int $rscript = 0, int $loops = 0)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -1,27 +1,28 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// +----------------------------------------------------------------------
|
declare(strict_types=1);
|
||||||
// | Library for ThinkAdmin
|
/**
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 版权所有 2014~2025 ThinkAdmin [ thinkadmin.top ]
|
* | Payment Plugin for ThinkAdmin
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 官方网站: https://thinkadmin.top
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 开源协议 ( https://mit-license.org )
|
* | 官方网站: https://thinkadmin.top
|
||||||
// | 免费声明 ( https://thinkadmin.top/disclaimer )
|
* +----------------------------------------------------------------------
|
||||||
// +----------------------------------------------------------------------
|
* | 开源协议 ( https://mit-license.org )
|
||||||
// | gitee 仓库地址 :https://gitee.com/zoujingli/ThinkLibrary
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
// | github 仓库地址 :https://github.com/zoujingli/ThinkLibrary
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
declare (strict_types=1);
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
namespace think\admin;
|
namespace think\admin;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 自定义数据异常
|
* 自定义数据异常.
|
||||||
* @class Exception
|
* @class Exception
|
||||||
* @package think\admin
|
|
||||||
*/
|
*/
|
||||||
class Exception extends \Exception
|
class Exception extends \Exception
|
||||||
{
|
{
|
||||||
@ -34,10 +35,10 @@ class Exception extends \Exception
|
|||||||
/**
|
/**
|
||||||
* Exception constructor.
|
* Exception constructor.
|
||||||
* @param string $message
|
* @param string $message
|
||||||
* @param integer $code
|
* @param int $code
|
||||||
* @param mixed $data
|
* @param mixed $data
|
||||||
*/
|
*/
|
||||||
public function __construct($message = "", $code = 0, $data = [])
|
public function __construct($message = '', $code = 0, $data = [])
|
||||||
{
|
{
|
||||||
parent::__construct($message);
|
parent::__construct($message);
|
||||||
$this->code = $code;
|
$this->code = $code;
|
||||||
@ -46,7 +47,7 @@ class Exception extends \Exception
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取异常停止数据
|
* 获取异常停止数据.
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public function getData()
|
public function getData()
|
||||||
@ -55,11 +56,11 @@ class Exception extends \Exception
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置异常停止数据
|
* 设置异常停止数据.
|
||||||
* @param mixed $data
|
* @param mixed $data
|
||||||
*/
|
*/
|
||||||
public function setData($data)
|
public function setData($data)
|
||||||
{
|
{
|
||||||
$this->data = $data;
|
$this->data = $data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,20 +1,22 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// +----------------------------------------------------------------------
|
declare(strict_types=1);
|
||||||
// | Library for ThinkAdmin
|
/**
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 版权所有 2014~2025 ThinkAdmin [ thinkadmin.top ]
|
* | Payment Plugin for ThinkAdmin
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 官方网站: https://thinkadmin.top
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 开源协议 ( https://mit-license.org )
|
* | 官方网站: https://thinkadmin.top
|
||||||
// | 免费声明 ( https://thinkadmin.top/disclaimer )
|
* +----------------------------------------------------------------------
|
||||||
// +----------------------------------------------------------------------
|
* | 开源协议 ( https://mit-license.org )
|
||||||
// | gitee 仓库地址 :https://gitee.com/zoujingli/ThinkLibrary
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
// | github 仓库地址 :https://github.com/zoujingli/ThinkLibrary
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
declare (strict_types=1);
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
namespace think\admin;
|
namespace think\admin;
|
||||||
|
|
||||||
@ -27,40 +29,37 @@ use think\db\Query;
|
|||||||
use think\Model;
|
use think\Model;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 控制器助手
|
* 控制器助手.
|
||||||
* @class Helper
|
* @class Helper
|
||||||
* @package think\admin
|
|
||||||
*/
|
*/
|
||||||
abstract class Helper
|
abstract class Helper
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* 应用容器
|
* 应用容器.
|
||||||
* @var App
|
* @var App
|
||||||
*/
|
*/
|
||||||
public $app;
|
public $app;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 控制器实例
|
* 控制器实例.
|
||||||
* @var Controller
|
* @var Controller
|
||||||
*/
|
*/
|
||||||
public $class;
|
public $class;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 当前请求方式
|
* 当前请求方式.
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
public $method;
|
public $method;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 自定输出格式
|
* 自定输出格式.
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
public $output;
|
public $output;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper constructor.
|
* Helper constructor.
|
||||||
* @param App $app
|
|
||||||
* @param Controller $class
|
|
||||||
*/
|
*/
|
||||||
public function __construct(App $app, Controller $class)
|
public function __construct(App $app, Controller $class)
|
||||||
{
|
{
|
||||||
@ -73,7 +72,7 @@ abstract class Helper
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 实例对象反射
|
* 实例对象反射.
|
||||||
* @param array $args
|
* @param array $args
|
||||||
* @return static
|
* @return static
|
||||||
*/
|
*/
|
||||||
@ -85,7 +84,7 @@ abstract class Helper
|
|||||||
/**
|
/**
|
||||||
* 获取数据库查询对象
|
* 获取数据库查询对象
|
||||||
* @param BaseQuery|Model|string $query
|
* @param BaseQuery|Model|string $query
|
||||||
* @return Query|Mongo|BaseQuery
|
* @return BaseQuery|Mongo|Query
|
||||||
*/
|
*/
|
||||||
public static function buildQuery($query)
|
public static function buildQuery($query)
|
||||||
{
|
{
|
||||||
@ -96,7 +95,9 @@ abstract class Helper
|
|||||||
return self::triggerBeforeEvent(static::buildModel($query)->db());
|
return self::triggerBeforeEvent(static::buildModel($query)->db());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ($query instanceof Model) return self::triggerBeforeEvent($query->db());
|
if ($query instanceof Model) {
|
||||||
|
return self::triggerBeforeEvent($query->db());
|
||||||
|
}
|
||||||
if ($query instanceof BaseQuery && !$query->getModel()) {
|
if ($query instanceof BaseQuery && !$query->getModel()) {
|
||||||
// 如果是子查询,不需要挂载模型对象
|
// 如果是子查询,不需要挂载模型对象
|
||||||
if (!self::isSubquery($query->getTable())) {
|
if (!self::isSubquery($query->getTable())) {
|
||||||
@ -111,9 +112,29 @@ abstract class Helper
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 触发查询对象执行前事件
|
* 动态创建模型对象
|
||||||
* @param BaseQuery|Model|mixed $query
|
* @param mixed $name 模型名称
|
||||||
* @return BaseQuery|Model|mixed
|
* @param array $data 初始数据
|
||||||
|
* @param mixed $conn 指定连接
|
||||||
|
*/
|
||||||
|
public static function buildModel(string $name, array $data = [], string $conn = ''): Model
|
||||||
|
{
|
||||||
|
if (strpos($name, '\\') !== false) {
|
||||||
|
if (class_exists($name)) {
|
||||||
|
$model = new $name($data);
|
||||||
|
if ($model instanceof Model) {
|
||||||
|
return $model;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$name = basename(str_replace('\\', '/', $name));
|
||||||
|
}
|
||||||
|
return VirtualModel::mk($name, $data, $conn);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 触发查询对象执行前事件.
|
||||||
|
* @param BaseQuery|mixed|Model $query
|
||||||
|
* @return BaseQuery|mixed|Model
|
||||||
*/
|
*/
|
||||||
private static function triggerBeforeEvent($query)
|
private static function triggerBeforeEvent($query)
|
||||||
{
|
{
|
||||||
@ -122,31 +143,10 @@ abstract class Helper
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 动态创建模型对象
|
* 判断是否为子查询.
|
||||||
* @param mixed $name 模型名称
|
|
||||||
* @param array $data 初始数据
|
|
||||||
* @param mixed $conn 指定连接
|
|
||||||
* @return Model
|
|
||||||
*/
|
|
||||||
public static function buildModel(string $name, array $data = [], string $conn = ''): Model
|
|
||||||
{
|
|
||||||
if (strpos($name, '\\') !== false) {
|
|
||||||
if (class_exists($name)) {
|
|
||||||
$model = new $name($data);
|
|
||||||
if ($model instanceof Model) return $model;
|
|
||||||
}
|
|
||||||
$name = basename(str_replace('\\', '/', $name));
|
|
||||||
}
|
|
||||||
return VirtualModel::mk($name, $data, $conn);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 判断是否为子查询
|
|
||||||
* @param string $sql
|
|
||||||
* @return bool
|
|
||||||
*/
|
*/
|
||||||
private static function isSubquery(string $sql): bool
|
private static function isSubquery(string $sql): bool
|
||||||
{
|
{
|
||||||
return preg_match('/^\(?\s*select\s+/i', $sql) > 0;
|
return preg_match('/^\(?\s*select\s+/i', $sql) > 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,24 +1,25 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// +----------------------------------------------------------------------
|
declare(strict_types=1);
|
||||||
// | Library for ThinkAdmin
|
/**
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 版权所有 2014~2025 ThinkAdmin [ thinkadmin.top ]
|
* | Payment Plugin for ThinkAdmin
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 官方网站: https://thinkadmin.top
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 开源协议 ( https://mit-license.org )
|
* | 官方网站: https://thinkadmin.top
|
||||||
// | 免费声明 ( https://thinkadmin.top/disclaimer )
|
* +----------------------------------------------------------------------
|
||||||
// +----------------------------------------------------------------------
|
* | 开源协议 ( https://mit-license.org )
|
||||||
// | gitee 仓库地址 :https://gitee.com/zoujingli/ThinkLibrary
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
// | github 仓库地址 :https://github.com/zoujingli/ThinkLibrary
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
declare (strict_types=1);
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
namespace think\admin;
|
namespace think\admin;
|
||||||
|
|
||||||
use SplFileInfo;
|
|
||||||
use think\admin\extend\ToolsExtend;
|
use think\admin\extend\ToolsExtend;
|
||||||
use think\admin\service\RuntimeService;
|
use think\admin\service\RuntimeService;
|
||||||
use think\admin\support\command\Database;
|
use think\admin\support\command\Database;
|
||||||
@ -30,6 +31,7 @@ use think\admin\support\command\Sysmenu;
|
|||||||
use think\admin\support\middleware\JwtSession;
|
use think\admin\support\middleware\JwtSession;
|
||||||
use think\admin\support\middleware\MultAccess;
|
use think\admin\support\middleware\MultAccess;
|
||||||
use think\admin\support\middleware\RbacAccess;
|
use think\admin\support\middleware\RbacAccess;
|
||||||
|
use think\App;
|
||||||
use think\exception\HttpException;
|
use think\exception\HttpException;
|
||||||
use think\exception\HttpResponseException;
|
use think\exception\HttpResponseException;
|
||||||
use think\middleware\LoadLangPack;
|
use think\middleware\LoadLangPack;
|
||||||
@ -40,16 +42,14 @@ use think\Service;
|
|||||||
/**
|
/**
|
||||||
* 模块注册服务
|
* 模块注册服务
|
||||||
* @class Library
|
* @class Library
|
||||||
* @package think\admin
|
|
||||||
*/
|
*/
|
||||||
class Library extends Service
|
class Library extends Service
|
||||||
{
|
{
|
||||||
/** @var \think\App */
|
/** @var App */
|
||||||
public static $sapp;
|
public static $sapp;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 启动服务
|
* 启动服务
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public function boot()
|
public function boot()
|
||||||
{
|
{
|
||||||
@ -71,7 +71,6 @@ class Library extends Service
|
|||||||
|
|
||||||
// 请求初始化处理
|
// 请求初始化处理
|
||||||
$this->app->event->listen('HttpRun', function (Request $request) {
|
$this->app->event->listen('HttpRun', function (Request $request) {
|
||||||
|
|
||||||
// 运行环境配置同步
|
// 运行环境配置同步
|
||||||
RuntimeService::sync();
|
RuntimeService::sync();
|
||||||
|
|
||||||
@ -102,15 +101,14 @@ class Library extends Service
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 动态加载文件
|
* 动态加载文件.
|
||||||
* @param string $file
|
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public static function load(string $file)
|
public static function load(string $file)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
return include $file;
|
return include $file;
|
||||||
} catch (\Throwable|\Error $error) {
|
} catch (\Error|\Throwable $error) {
|
||||||
trace_file($error);
|
trace_file($error);
|
||||||
throw new HttpException(500, $error->getMessage());
|
throw new HttpException(500, $error->getMessage());
|
||||||
}
|
}
|
||||||
@ -118,19 +116,26 @@ class Library extends Service
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 初始化服务
|
* 初始化服务
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public function register()
|
public function register()
|
||||||
{
|
{
|
||||||
// 动态加载全局配置
|
// 动态加载全局配置
|
||||||
[$dir, $ext] = [$this->app->getBasePath(), $this->app->getConfigExt()];
|
[$dir, $ext] = [$this->app->getBasePath(), $this->app->getConfigExt()];
|
||||||
ToolsExtend::find($dir, 2, function (SplFileInfo $info) use ($ext) {
|
ToolsExtend::find($dir, 2, function (\SplFileInfo $info) use ($ext) {
|
||||||
$info->isFile() && $info->getBasename() === "sys{$ext}" && Library::load($info->getPathname());
|
$info->isFile() && $info->getBasename() === "sys{$ext}" && Library::load($info->getPathname());
|
||||||
});
|
});
|
||||||
if (is_file($file = "{$dir}common{$ext}")) Library::load($file);
|
if (is_file($file = "{$dir}common{$ext}")) {
|
||||||
if (is_file($file = "{$dir}provider{$ext}")) $this->app->bind(include $file);
|
Library::load($file);
|
||||||
if (is_file($file = "{$dir}event{$ext}")) $this->app->loadEvent(include $file);
|
}
|
||||||
if (is_file($file = "{$dir}middleware{$ext}")) $this->app->middleware->import(include $file, 'app');
|
if (is_file($file = "{$dir}provider{$ext}")) {
|
||||||
|
$this->app->bind(include $file);
|
||||||
|
}
|
||||||
|
if (is_file($file = "{$dir}event{$ext}")) {
|
||||||
|
$this->app->loadEvent(include $file);
|
||||||
|
}
|
||||||
|
if (is_file($file = "{$dir}middleware{$ext}")) {
|
||||||
|
$this->app->middleware->import(include $file, 'app');
|
||||||
|
}
|
||||||
|
|
||||||
// 终端 HTTP 访问时特殊处理
|
// 终端 HTTP 访问时特殊处理
|
||||||
if (!$this->app->runningInConsole()) {
|
if (!$this->app->runningInConsole()) {
|
||||||
@ -139,7 +144,9 @@ class Library extends Service
|
|||||||
$header = ['X-Frame-Options' => $this->app->config->get('app.cors_frame') ?: 'sameorigin'];
|
$header = ['X-Frame-Options' => $this->app->config->get('app.cors_frame') ?: 'sameorigin'];
|
||||||
// HTTP.CORS 跨域规则配置
|
// HTTP.CORS 跨域规则配置
|
||||||
if ($this->app->config->get('app.cors_on', true) && ($origin = $request->header('origin', '-')) !== '-') {
|
if ($this->app->config->get('app.cors_on', true) && ($origin = $request->header('origin', '-')) !== '-') {
|
||||||
if (is_string($hosts = $this->app->config->get('app.cors_host', []))) $hosts = str2arr($hosts);
|
if (is_string($hosts = $this->app->config->get('app.cors_host', []))) {
|
||||||
|
$hosts = str2arr($hosts);
|
||||||
|
}
|
||||||
if (empty($hosts) || in_array(parse_url(strtolower($origin), PHP_URL_HOST), $hosts)) {
|
if (empty($hosts) || in_array(parse_url(strtolower($origin), PHP_URL_HOST), $hosts)) {
|
||||||
$headers = $this->app->config->get('app.cors_headers', 'Api-Name,Api-Type,Api-Token,Jwt-Token,User-Form-Token,User-Token,Token');
|
$headers = $this->app->config->get('app.cors_headers', 'Api-Name,Api-Type,Api-Token,Jwt-Token,User-Form-Token,User-Token,Token');
|
||||||
$header['Access-Control-Allow-Origin'] = $origin;
|
$header['Access-Control-Allow-Origin'] = $origin;
|
||||||
@ -152,9 +159,8 @@ class Library extends Service
|
|||||||
// 跨域预请求状态处理
|
// 跨域预请求状态处理
|
||||||
if ($request->isOptions()) {
|
if ($request->isOptions()) {
|
||||||
throw new HttpResponseException(response()->code(204)->header($header));
|
throw new HttpResponseException(response()->code(204)->header($header));
|
||||||
} else {
|
|
||||||
return $next($request)->header($header);
|
|
||||||
}
|
}
|
||||||
|
return $next($request)->header($header);
|
||||||
});
|
});
|
||||||
|
|
||||||
// 初始化会话和语言包
|
// 初始化会话和语言包
|
||||||
@ -172,4 +178,4 @@ class Library extends Service
|
|||||||
$this->app->middleware->add(RbacAccess::class, 'route');
|
$this->app->middleware->add(RbacAccess::class, 'route');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,32 +1,33 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// +----------------------------------------------------------------------
|
declare(strict_types=1);
|
||||||
// | Library for ThinkAdmin
|
/**
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 版权所有 2014~2025 ThinkAdmin [ thinkadmin.top ]
|
* | Payment Plugin for ThinkAdmin
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 官方网站: https://thinkadmin.top
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 开源协议 ( https://mit-license.org )
|
* | 官方网站: https://thinkadmin.top
|
||||||
// | 免费声明 ( https://thinkadmin.top/disclaimer )
|
* +----------------------------------------------------------------------
|
||||||
// +----------------------------------------------------------------------
|
* | 开源协议 ( https://mit-license.org )
|
||||||
// | gitee 仓库地址 :https://gitee.com/zoujingli/ThinkLibrary
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
// | github 仓库地址 :https://github.com/zoujingli/ThinkLibrary
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
declare (strict_types=1);
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
namespace think\admin;
|
namespace think\admin;
|
||||||
|
|
||||||
use think\admin\helper\QueryHelper;
|
use think\admin\helper\QueryHelper;
|
||||||
|
use think\db\Mongo;
|
||||||
|
use think\db\Query;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 基础模型类
|
* 基础模型类.
|
||||||
* @class Model
|
* @class Model
|
||||||
* @mixin \think\db\Query
|
* @mixin \think\db\Query
|
||||||
* @package think\admin
|
|
||||||
*
|
|
||||||
* --- 静态助手调用
|
|
||||||
* @method static bool mSave(array $data = [], string $field = '', mixed $where = []) 快捷更新
|
* @method static bool mSave(array $data = [], string $field = '', mixed $where = []) 快捷更新
|
||||||
* @method static bool mDelete(string $field = '', mixed $where = []) 快捷删除
|
* @method static bool mDelete(string $field = '', mixed $where = []) 快捷删除
|
||||||
* @method static bool|array mForm(string $template = '', string $field = '', mixed $where = [], array $data = []) 快捷表单
|
* @method static bool|array mForm(string $template = '', string $field = '', mixed $where = [], array $data = []) 快捷表单
|
||||||
@ -36,46 +37,25 @@ use think\admin\helper\QueryHelper;
|
|||||||
abstract class Model extends \think\Model
|
abstract class Model extends \think\Model
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* 日志类型
|
* 日志过滤.
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
protected $oplogType;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 日志名称
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
protected $oplogName;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 日志过滤
|
|
||||||
* @var callable
|
* @var callable
|
||||||
*/
|
*/
|
||||||
public static $oplogCall;
|
public static $oplogCall;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建模型实例
|
* 日志类型.
|
||||||
* @template t of static
|
* @var string
|
||||||
* @param mixed $data
|
|
||||||
* @return t|static
|
|
||||||
*/
|
*/
|
||||||
public static function mk($data = [])
|
protected $oplogType;
|
||||||
{
|
|
||||||
return new static($data);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建查询实例
|
* 日志名称.
|
||||||
* @param array $data
|
* @var string
|
||||||
* @return \think\db\Query|\think\db\Mongo
|
|
||||||
*/
|
*/
|
||||||
public static function mq(array $data = [])
|
protected $oplogName;
|
||||||
{
|
|
||||||
return Helper::buildQuery(static::mk($data)->newQuery());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 调用魔术方法
|
* 调用魔术方法.
|
||||||
* @param string $method 方法名称
|
* @param string $method 方法名称
|
||||||
* @param array $args 调用参数
|
* @param array $args 调用参数
|
||||||
* @return $this|false|mixed
|
* @return $this|false|mixed
|
||||||
@ -83,10 +63,10 @@ abstract class Model extends \think\Model
|
|||||||
public function __call($method, $args)
|
public function __call($method, $args)
|
||||||
{
|
{
|
||||||
$oplogs = [
|
$oplogs = [
|
||||||
'onAdminSave' => "修改%s[%s]状态",
|
'onAdminSave' => '修改%s[%s]状态',
|
||||||
'onAdminUpdate' => "更新%s[%s]记录",
|
'onAdminUpdate' => '更新%s[%s]记录',
|
||||||
'onAdminInsert' => "增加%s[%s]成功",
|
'onAdminInsert' => '增加%s[%s]成功',
|
||||||
"onAdminDelete" => "删除%s[%s]成功",
|
'onAdminDelete' => '删除%s[%s]成功',
|
||||||
];
|
];
|
||||||
if (isset($oplogs[$method])) {
|
if (isset($oplogs[$method])) {
|
||||||
if ($this->oplogType && $this->oplogName) {
|
if ($this->oplogType && $this->oplogName) {
|
||||||
@ -97,16 +77,15 @@ abstract class Model extends \think\Model
|
|||||||
sysoplog($this->oplogType, lang($oplogs[$method], [lang($this->oplogName), $changeIds]));
|
sysoplog($this->oplogType, lang($oplogs[$method], [lang($this->oplogName), $changeIds]));
|
||||||
}
|
}
|
||||||
return $this;
|
return $this;
|
||||||
} else {
|
|
||||||
return parent::__call($method, $args);
|
|
||||||
}
|
}
|
||||||
|
return parent::__call($method, $args);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 静态魔术方法
|
* 静态魔术方法.
|
||||||
* @param string $method 方法名称
|
* @param string $method 方法名称
|
||||||
* @param array $args 调用参数
|
* @param array $args 调用参数
|
||||||
* @return mixed|false|integer|QueryHelper
|
* @return false|int|mixed|QueryHelper
|
||||||
*/
|
*/
|
||||||
public static function __callStatic($method, $args)
|
public static function __callStatic($method, $args)
|
||||||
{
|
{
|
||||||
@ -114,4 +93,24 @@ abstract class Model extends \think\Model
|
|||||||
return parent::__callStatic($method, $args);
|
return parent::__callStatic($method, $args);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建模型实例.
|
||||||
|
* @template t of static
|
||||||
|
* @param mixed $data
|
||||||
|
* @return static|t
|
||||||
|
*/
|
||||||
|
public static function mk($data = [])
|
||||||
|
{
|
||||||
|
return new static($data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建查询实例.
|
||||||
|
* @return Mongo|Query
|
||||||
|
*/
|
||||||
|
public static function mq(array $data = [])
|
||||||
|
{
|
||||||
|
return Helper::buildQuery(static::mk($data)->newQuery());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,20 +1,22 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// +----------------------------------------------------------------------
|
declare(strict_types=1);
|
||||||
// | Library for ThinkAdmin
|
/**
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 版权所有 2014~2025 ThinkAdmin [ thinkadmin.top ]
|
* | Payment Plugin for ThinkAdmin
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 官方网站: https://thinkadmin.top
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 开源协议 ( https://mit-license.org )
|
* | 官方网站: https://thinkadmin.top
|
||||||
// | 免费声明 ( https://thinkadmin.top/disclaimer )
|
* +----------------------------------------------------------------------
|
||||||
// +----------------------------------------------------------------------
|
* | 开源协议 ( https://mit-license.org )
|
||||||
// | gitee 仓库地址 :https://gitee.com/zoujingli/ThinkLibrary
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
// | github 仓库地址 :https://github.com/zoujingli/ThinkLibrary
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
declare (strict_types=1);
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
namespace think\admin;
|
namespace think\admin;
|
||||||
|
|
||||||
@ -27,7 +29,6 @@ use think\Service;
|
|||||||
* 插件注册服务
|
* 插件注册服务
|
||||||
*
|
*
|
||||||
* @class Plugin
|
* @class Plugin
|
||||||
* @package think\admin\service
|
|
||||||
*
|
*
|
||||||
* @method string getAppCode() static 获取插件编号
|
* @method string getAppCode() static 获取插件编号
|
||||||
* @method string getAppName() static 获取插件名称
|
* @method string getAppName() static 获取插件名称
|
||||||
@ -38,7 +39,7 @@ use think\Service;
|
|||||||
abstract class Plugin extends Service
|
abstract class Plugin extends Service
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* 必填,插件包名
|
* 必填,插件包名.
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
protected $package = '';
|
protected $package = '';
|
||||||
@ -50,25 +51,25 @@ abstract class Plugin extends Service
|
|||||||
protected $appCode = '';
|
protected $appCode = '';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 必填,插件名称
|
* 必填,插件名称.
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
protected $appName = '';
|
protected $appName = '';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 可选,插件目录
|
* 可选,插件目录.
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
protected $appPath = '';
|
protected $appPath = '';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 可选,插件别名
|
* 可选,插件别名.
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
protected $appAlias = '';
|
protected $appAlias = '';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 可选,命名空间
|
* 可选,命名空间.
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
protected $appSpace = '';
|
protected $appSpace = '';
|
||||||
@ -80,14 +81,13 @@ abstract class Plugin extends Service
|
|||||||
protected $appService = '';
|
protected $appService = '';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 插件配置
|
* 插件配置.
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
private static $addons = [];
|
private static $addons = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 自动注册插件
|
* 自动注册插件.
|
||||||
* @param \think\App $app
|
|
||||||
*/
|
*/
|
||||||
public function __construct(App $app)
|
public function __construct(App $app)
|
||||||
{
|
{
|
||||||
@ -113,7 +113,7 @@ abstract class Plugin extends Service
|
|||||||
|
|
||||||
// 应用插件包名计算
|
// 应用插件包名计算
|
||||||
if (empty($this->package) && ($path = $ref->getFileName())) {
|
if (empty($this->package) && ($path = $ref->getFileName())) {
|
||||||
for ($level = 1; $level <= 3; $level++) {
|
for ($level = 1; $level <= 3; ++$level) {
|
||||||
if (is_file($file = dirname($path, $level) . '/composer.json')) {
|
if (is_file($file = dirname($path, $level) . '/composer.json')) {
|
||||||
$this->package = json_decode(file_get_contents($file), true)['name'] ?? '';
|
$this->package = json_decode(file_get_contents($file), true)['name'] ?? '';
|
||||||
break;
|
break;
|
||||||
@ -123,26 +123,30 @@ abstract class Plugin extends Service
|
|||||||
|
|
||||||
// 应用插件计算名称及别名
|
// 应用插件计算名称及别名
|
||||||
$attr = explode('\\', $ref->getNamespaceName());
|
$attr = explode('\\', $ref->getNamespaceName());
|
||||||
if ($attr[0] === NodeService::space()) array_shift($attr);
|
if ($attr[0] === NodeService::space()) {
|
||||||
|
array_shift($attr);
|
||||||
|
}
|
||||||
|
|
||||||
$this->appCode = $this->appCode ?: join('-', $attr);
|
$this->appCode = $this->appCode ?: join('-', $attr);
|
||||||
if ($this->appCode === $this->appAlias) $this->appAlias = '';
|
if ($this->appCode === $this->appAlias) {
|
||||||
|
$this->appAlias = '';
|
||||||
|
}
|
||||||
|
|
||||||
if (is_dir($this->appPath)) {
|
if (is_dir($this->appPath)) {
|
||||||
// 写入插件参数信息
|
// 写入插件参数信息
|
||||||
self::$addons[$this->appCode] = [
|
self::$addons[$this->appCode] = [
|
||||||
'name' => $this->appName,
|
'name' => $this->appName,
|
||||||
'path' => realpath($this->appPath) . DIRECTORY_SEPARATOR,
|
'path' => realpath($this->appPath) . DIRECTORY_SEPARATOR,
|
||||||
'alias' => $this->appAlias,
|
'alias' => $this->appAlias,
|
||||||
'space' => $this->appSpace ?: NodeService::space($this->appCode),
|
'space' => $this->appSpace ?: NodeService::space($this->appCode),
|
||||||
'package' => $this->package,
|
'package' => $this->package,
|
||||||
'service' => $this->appService
|
'service' => $this->appService,
|
||||||
];
|
];
|
||||||
// 插件别名动态设置
|
// 插件别名动态设置
|
||||||
if (!empty($this->appAlias) && $this->appCode !== $this->appAlias) {
|
if (!empty($this->appAlias) && $this->appCode !== $this->appAlias) {
|
||||||
Library::$sapp->config->set([
|
Library::$sapp->config->set([
|
||||||
'app_map' => array_merge(Library::$sapp->config->get('app.app_map', []), [
|
'app_map' => array_merge(Library::$sapp->config->get('app.app_map', []), [
|
||||||
$this->appAlias => $this->appCode
|
$this->appAlias => $this->appCode,
|
||||||
]),
|
]),
|
||||||
], 'app');
|
], 'app');
|
||||||
}
|
}
|
||||||
@ -150,49 +154,17 @@ abstract class Plugin extends Service
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 注册应用启动
|
* 获取对象内部属性.
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function boot(): void
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取插件及安装信息
|
|
||||||
* @param ?string $code 指定插件编号
|
|
||||||
* @param boolean $append 关联安装数据
|
|
||||||
* @return ?array
|
|
||||||
*/
|
|
||||||
public static function get(?string $code = null, bool $append = false): ?array
|
|
||||||
{
|
|
||||||
// 读取插件原始信息
|
|
||||||
$data = empty($code) ? self::$addons : (self::$addons[$code] ?? null);
|
|
||||||
if (empty($data) || empty($append)) return $data;
|
|
||||||
// 关联插件安装信息
|
|
||||||
$versions = ModuleService::getLibrarys();
|
|
||||||
return empty($code) ? array_map(static function ($item) use ($versions) {
|
|
||||||
$item['install'] = $versions[$item['package']] ?? [];
|
|
||||||
if (empty($item['name'])) $item['name'] = $item['install']['name'] ?? '';
|
|
||||||
return $item;
|
|
||||||
}, $data) : $data + ['install' => $versions[$data['package']] ?? []];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取对象内部属性
|
|
||||||
* @param string $name
|
|
||||||
* @return null
|
|
||||||
*/
|
*/
|
||||||
public function __get(string $name)
|
public function __get(string $name)
|
||||||
{
|
{
|
||||||
return $this->$name ?? '';
|
return $this->{$name} ?? '';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 静态调用方法兼容
|
* 静态调用方法兼容.
|
||||||
* @param string $method
|
* @return null|array|string
|
||||||
* @param array $arguments
|
* @throws Exception
|
||||||
* @return array|string|null
|
|
||||||
* @throws \think\admin\Exception
|
|
||||||
*/
|
*/
|
||||||
public static function __callStatic(string $method, array $arguments)
|
public static function __callStatic(string $method, array $arguments)
|
||||||
{
|
{
|
||||||
@ -216,11 +188,9 @@ abstract class Plugin extends Service
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 魔术方法调用兼容处理
|
* 魔术方法调用兼容处理.
|
||||||
* @param string $method
|
* @return null|array
|
||||||
* @param array $arguments
|
* @throws Exception
|
||||||
* @return array|null
|
|
||||||
* @throws \think\admin\Exception
|
|
||||||
*/
|
*/
|
||||||
public function __call(string $method, array $arguments)
|
public function __call(string $method, array $arguments)
|
||||||
{
|
{
|
||||||
@ -228,8 +198,36 @@ abstract class Plugin extends Service
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 定义插件菜单
|
* 注册应用启动.
|
||||||
|
*/
|
||||||
|
public function boot(): void {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取插件及安装信息.
|
||||||
|
* @param ?string $code 指定插件编号
|
||||||
|
* @param bool $append 关联安装数据
|
||||||
|
*/
|
||||||
|
public static function get(?string $code = null, bool $append = false): ?array
|
||||||
|
{
|
||||||
|
// 读取插件原始信息
|
||||||
|
$data = empty($code) ? self::$addons : (self::$addons[$code] ?? null);
|
||||||
|
if (empty($data) || empty($append)) {
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
// 关联插件安装信息
|
||||||
|
$versions = ModuleService::getLibrarys();
|
||||||
|
return empty($code) ? array_map(static function ($item) use ($versions) {
|
||||||
|
$item['install'] = $versions[$item['package']] ?? [];
|
||||||
|
if (empty($item['name'])) {
|
||||||
|
$item['name'] = $item['install']['name'] ?? '';
|
||||||
|
}
|
||||||
|
return $item;
|
||||||
|
}, $data) : $data + ['install' => $versions[$data['package']] ?? []];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 定义插件菜单.
|
||||||
* @return array 一级或二级菜单
|
* @return array 一级或二级菜单
|
||||||
*/
|
*/
|
||||||
abstract public static function menu(): array;
|
abstract public static function menu(): array;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,20 +1,22 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// +----------------------------------------------------------------------
|
declare(strict_types=1);
|
||||||
// | Library for ThinkAdmin
|
/**
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 版权所有 2014~2025 ThinkAdmin [ thinkadmin.top ]
|
* | Payment Plugin for ThinkAdmin
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 官方网站: https://thinkadmin.top
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 开源协议 ( https://mit-license.org )
|
* | 官方网站: https://thinkadmin.top
|
||||||
// | 免费声明 ( https://thinkadmin.top/disclaimer )
|
* +----------------------------------------------------------------------
|
||||||
// +----------------------------------------------------------------------
|
* | 开源协议 ( https://mit-license.org )
|
||||||
// | gitee 仓库地址 :https://gitee.com/zoujingli/ThinkLibrary
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
// | github 仓库地址 :https://github.com/zoujingli/ThinkLibrary
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
declare (strict_types=1);
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
namespace think\admin;
|
namespace think\admin;
|
||||||
|
|
||||||
@ -23,14 +25,13 @@ use think\admin\service\QueueService;
|
|||||||
use think\App;
|
use think\App;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 任务基础类
|
* 任务基础类.
|
||||||
* @class Queue
|
* @class Queue
|
||||||
* @package think\admin
|
|
||||||
*/
|
*/
|
||||||
abstract class Queue
|
abstract class Queue
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* 应用实例
|
* 应用实例.
|
||||||
* @var App
|
* @var App
|
||||||
*/
|
*/
|
||||||
protected $app;
|
protected $app;
|
||||||
@ -49,8 +50,6 @@ abstract class Queue
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
* @param App $app
|
|
||||||
* @param ProcessService $process
|
|
||||||
*/
|
*/
|
||||||
public function __construct(App $app, ProcessService $process)
|
public function __construct(App $app, ProcessService $process)
|
||||||
{
|
{
|
||||||
@ -59,8 +58,7 @@ abstract class Queue
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 初始化任务数据
|
* 初始化任务数据.
|
||||||
* @param QueueService $queue
|
|
||||||
* @return $this
|
* @return $this
|
||||||
*/
|
*/
|
||||||
public function initialize(QueueService $queue): Queue
|
public function initialize(QueueService $queue): Queue
|
||||||
@ -70,14 +68,13 @@ abstract class Queue
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 执行任务处理内容
|
* 执行任务处理内容.
|
||||||
* @param array $data
|
* @return string|void
|
||||||
* @return void|string
|
|
||||||
*/
|
*/
|
||||||
abstract public function execute(array $data = []);
|
abstract public function execute(array $data = []);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置失败的消息
|
* 设置失败的消息.
|
||||||
* @param string $message 消息内容
|
* @param string $message 消息内容
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
@ -87,7 +84,7 @@ abstract class Queue
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置成功的消息
|
* 设置成功的消息.
|
||||||
* @param string $message 消息内容
|
* @param string $message 消息内容
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
@ -97,13 +94,13 @@ abstract class Queue
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 更新任务进度
|
* 更新任务进度.
|
||||||
* @param integer $total 记录总和
|
* @param int $total 记录总和
|
||||||
* @param integer $count 当前记录
|
* @param int $count 当前记录
|
||||||
* @param string $message 文字描述
|
* @param string $message 文字描述
|
||||||
* @param integer $backline 回退行数
|
* @param int $backline 回退行数
|
||||||
* @return static
|
* @return static
|
||||||
* @throws \think\admin\Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
protected function setQueueMessage(int $total, int $count, string $message = '', int $backline = 0): Queue
|
protected function setQueueMessage(int $total, int $count, string $message = '', int $backline = 0): Queue
|
||||||
{
|
{
|
||||||
@ -112,16 +109,15 @@ abstract class Queue
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置任务的进度
|
* 设置任务的进度.
|
||||||
* @param ?string $message 进度消息
|
* @param ?string $message 进度消息
|
||||||
* @param ?string $progress 进度数值
|
* @param ?string $progress 进度数值
|
||||||
* @param integer $backline 回退行数
|
* @param int $backline 回退行数
|
||||||
* @return Queue
|
* @throws Exception
|
||||||
* @throws \think\admin\Exception
|
|
||||||
*/
|
*/
|
||||||
protected function setQueueProgress(?string $message = null, ?string $progress = null, int $backline = 0): Queue
|
protected function setQueueProgress(?string $message = null, ?string $progress = null, int $backline = 0): Queue
|
||||||
{
|
{
|
||||||
$this->queue->progress(2, $message, $progress, $backline);
|
$this->queue->progress(2, $message, $progress, $backline);
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,20 +1,22 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// +----------------------------------------------------------------------
|
declare(strict_types=1);
|
||||||
// | Library for ThinkAdmin
|
/**
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 版权所有 2014~2025 ThinkAdmin [ thinkadmin.top ]
|
* | Payment Plugin for ThinkAdmin
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 官方网站: https://thinkadmin.top
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 开源协议 ( https://mit-license.org )
|
* | 官方网站: https://thinkadmin.top
|
||||||
// | 免费声明 ( https://thinkadmin.top/disclaimer )
|
* +----------------------------------------------------------------------
|
||||||
// +----------------------------------------------------------------------
|
* | 开源协议 ( https://mit-license.org )
|
||||||
// | gitee 仓库地址 :https://gitee.com/zoujingli/ThinkLibrary
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
// | github 仓库地址 :https://github.com/zoujingli/ThinkLibrary
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
declare (strict_types=1);
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
namespace think\admin;
|
namespace think\admin;
|
||||||
|
|
||||||
@ -22,21 +24,19 @@ use think\App;
|
|||||||
use think\Container;
|
use think\Container;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 自定义服务基类
|
* 自定义服务基类.
|
||||||
* @class Service
|
* @class Service
|
||||||
* @package think\admin
|
|
||||||
*/
|
*/
|
||||||
abstract class Service
|
abstract class Service
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* 应用实例
|
* 应用实例.
|
||||||
* @var App
|
* @var App
|
||||||
*/
|
*/
|
||||||
protected $app;
|
protected $app;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
* @param App $app
|
|
||||||
*/
|
*/
|
||||||
public function __construct(App $app)
|
public function __construct(App $app)
|
||||||
{
|
{
|
||||||
@ -44,21 +44,19 @@ abstract class Service
|
|||||||
$this->initialize();
|
$this->initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 初始化服务
|
|
||||||
*/
|
|
||||||
protected function initialize()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 静态实例对象
|
* 静态实例对象
|
||||||
* @param array $var 实例参数
|
* @param array $var 实例参数
|
||||||
* @param boolean $new 创建新实例
|
* @param bool $new 创建新实例
|
||||||
* @return static|mixed
|
* @return mixed|static
|
||||||
*/
|
*/
|
||||||
public static function instance(array $var = [], bool $new = false)
|
public static function instance(array $var = [], bool $new = false)
|
||||||
{
|
{
|
||||||
return Container::getInstance()->make(static::class, $var, $new);
|
return Container::getInstance()->make(static::class, $var, $new);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
/**
|
||||||
|
* 初始化服务
|
||||||
|
*/
|
||||||
|
protected function initialize() {}
|
||||||
|
}
|
||||||
|
|||||||
@ -1,20 +1,22 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// +----------------------------------------------------------------------
|
declare(strict_types=1);
|
||||||
// | Library for ThinkAdmin
|
/**
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 版权所有 2014~2025 ThinkAdmin [ thinkadmin.top ]
|
* | Payment Plugin for ThinkAdmin
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 官方网站: https://thinkadmin.top
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 开源协议 ( https://mit-license.org )
|
* | 官方网站: https://thinkadmin.top
|
||||||
// | 免费声明 ( https://thinkadmin.top/disclaimer )
|
* +----------------------------------------------------------------------
|
||||||
// +----------------------------------------------------------------------
|
* | 开源协议 ( https://mit-license.org )
|
||||||
// | gitee 仓库地址 :https://gitee.com/zoujingli/ThinkLibrary
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
// | github 仓库地址 :https://github.com/zoujingli/ThinkLibrary
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
declare (strict_types=1);
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
namespace think\admin;
|
namespace think\admin;
|
||||||
|
|
||||||
@ -23,9 +25,8 @@ use think\admin\storage\LocalStorage;
|
|||||||
use think\Container;
|
use think\Container;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 文件存储引擎管理
|
* 文件存储引擎管理.
|
||||||
* @class Storage
|
* @class Storage
|
||||||
* @package think\admin
|
|
||||||
* @method static array info($name, $safe = false, $attname = null) 文件存储信息
|
* @method static array info($name, $safe = false, $attname = null) 文件存储信息
|
||||||
* @method static array set($name, $file, $safe = false, $attname = null) 储存文件
|
* @method static array set($name, $file, $safe = false, $attname = null) 储存文件
|
||||||
* @method static string url($name, $safe = false, $attname = null) 获取文件链接
|
* @method static string url($name, $safe = false, $attname = null) 获取文件链接
|
||||||
@ -37,13 +38,26 @@ use think\Container;
|
|||||||
*/
|
*/
|
||||||
abstract class Storage
|
abstract class Storage
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* 静态访问启用.
|
||||||
|
* @param string $method 方法名称
|
||||||
|
* @param array $arguments 调用参数
|
||||||
|
* @return mixed
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public static function __callStatic(string $method, array $arguments)
|
||||||
|
{
|
||||||
|
if (method_exists($storage = static::instance(), $method)) {
|
||||||
|
return call_user_func_array([$storage, $method], $arguments);
|
||||||
|
}
|
||||||
|
throw new Exception('method not exists: ' . get_class($storage) . "->{$method}()");
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 实例化存储操作对象
|
* 实例化存储操作对象
|
||||||
* @param ?string $name 驱动名称
|
* @param ?string $name 驱动名称
|
||||||
* @param ?string $class 驱动类名
|
* @param ?string $class 驱动类名
|
||||||
* @return \think\admin\contract\StorageInterface
|
* @throws Exception
|
||||||
* @throws \think\admin\Exception
|
|
||||||
*/
|
*/
|
||||||
public static function instance(?string $name = null, ?string $class = null): StorageInterface
|
public static function instance(?string $name = null, ?string $class = null): StorageInterface
|
||||||
{
|
{
|
||||||
@ -52,7 +66,9 @@ abstract class Storage
|
|||||||
$type = ucfirst(strtolower($name ?: sysconf('storage.type|raw')));
|
$type = ucfirst(strtolower($name ?: sysconf('storage.type|raw')));
|
||||||
$class = "think\\admin\\storage\\{$type}Storage";
|
$class = "think\\admin\\storage\\{$type}Storage";
|
||||||
}
|
}
|
||||||
if (class_exists($class)) return Container::getInstance()->make($class);
|
if (class_exists($class)) {
|
||||||
|
return Container::getInstance()->make($class);
|
||||||
|
}
|
||||||
throw new Exception("Storage driver [{$class}] does not exist.");
|
throw new Exception("Storage driver [{$class}] does not exist.");
|
||||||
} catch (Exception $exception) {
|
} catch (Exception $exception) {
|
||||||
throw $exception;
|
throw $exception;
|
||||||
@ -62,26 +78,24 @@ abstract class Storage
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取文件相对名称
|
* 获取文件相对名称.
|
||||||
* @param string $url 文件访问链接
|
* @param string $url 文件访问链接
|
||||||
* @param string $ext 文件后缀名称
|
* @param string $ext 文件后缀名称
|
||||||
* @param string $pre 文件存储前缀
|
* @param string $pre 文件存储前缀
|
||||||
* @param string $fun 名称规则方法
|
* @param string $fun 名称规则方法
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public static function name(string $url, string $ext = '', string $pre = '', string $fun = 'md5'): string
|
public static function name(string $url, string $ext = '', string $pre = '', string $fun = 'md5'): string
|
||||||
{
|
{
|
||||||
[$hah, $ext] = [$fun($url), trim($ext ?: pathinfo($url, 4), '.\\/')];
|
[$hah, $ext] = [$fun($url), trim($ext ?: pathinfo($url, 4), '.\/')];
|
||||||
$attr = [trim($pre, '.\\/'), substr($hah, 0, 2), substr($hah, 2, 30)];
|
$attr = [trim($pre, '.\/'), substr($hah, 0, 2), substr($hah, 2, 30)];
|
||||||
return trim(join('/', $attr), '/') . '.' . strtolower($ext ?: 'tmp');
|
return trim(join('/', $attr), '/') . '.' . strtolower($ext ?: 'tmp');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 下载文件到本地
|
* 下载文件到本地.
|
||||||
* @param string $url 文件URL地址
|
* @param string $url 文件URL地址
|
||||||
* @param boolean $force 是否强制下载
|
* @param bool $force 是否强制下载
|
||||||
* @param integer $expire 文件保留时间
|
* @param int $expire 文件保留时间
|
||||||
* @return array
|
|
||||||
*/
|
*/
|
||||||
public static function down(string $url, bool $force = false, int $expire = 0): array
|
public static function down(string $url, bool $force = false, int $expire = 0): array
|
||||||
{
|
{
|
||||||
@ -100,10 +114,9 @@ abstract class Storage
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取后缀类型
|
* 获取后缀类型.
|
||||||
* @param array|string $exts 文件后缀
|
* @param array|string $exts 文件后缀
|
||||||
* @param array $mime 文件信息
|
* @param array $mime 文件信息
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public static function mime($exts, array $mime = []): string
|
public static function mime($exts, array $mime = []): string
|
||||||
{
|
{
|
||||||
@ -115,36 +128,35 @@ abstract class Storage
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取所有类型
|
* 获取所有类型.
|
||||||
* @return array
|
|
||||||
*/
|
*/
|
||||||
public static function mimes(): array
|
public static function mimes(): array
|
||||||
{
|
{
|
||||||
static $mimes = [];
|
static $mimes = [];
|
||||||
if (count($mimes) > 0) return $mimes;
|
if (count($mimes) > 0) {
|
||||||
|
return $mimes;
|
||||||
|
}
|
||||||
return $mimes = include __DIR__ . '/storage/bin/mimes.php';
|
return $mimes = include __DIR__ . '/storage/bin/mimes.php';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取存储类型
|
* 获取存储类型.
|
||||||
* @return array
|
|
||||||
*/
|
*/
|
||||||
public static function types(): array
|
public static function types(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'local' => lang('本地服务器存储'),
|
'local' => lang('本地服务器存储'),
|
||||||
'alist' => lang('自建Alist存储'),
|
'alist' => lang('自建Alist存储'),
|
||||||
'qiniu' => lang('七牛云对象存储'),
|
'qiniu' => lang('七牛云对象存储'),
|
||||||
'upyun' => lang('又拍云USS存储'),
|
'upyun' => lang('又拍云USS存储'),
|
||||||
'txcos' => lang('腾讯云COS存储'),
|
'txcos' => lang('腾讯云COS存储'),
|
||||||
'alioss' => lang('阿里云OSS存储'),
|
'alioss' => lang('阿里云OSS存储'),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 使用CURL读取网络资源
|
* 使用CURL读取网络资源.
|
||||||
* @param string $url 资源地址
|
* @param string $url 资源地址
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public static function curlGet(string $url): string
|
public static function curlGet(string $url): string
|
||||||
{
|
{
|
||||||
@ -161,28 +173,12 @@ abstract class Storage
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 静态访问启用
|
* 图片数据存储.
|
||||||
* @param string $method 方法名称
|
|
||||||
* @param array $arguments 调用参数
|
|
||||||
* @return mixed
|
|
||||||
* @throws \think\admin\Exception
|
|
||||||
*/
|
|
||||||
public static function __callStatic(string $method, array $arguments)
|
|
||||||
{
|
|
||||||
if (method_exists($storage = static::instance(), $method)) {
|
|
||||||
return call_user_func_array([$storage, $method], $arguments);
|
|
||||||
} else {
|
|
||||||
throw new Exception("method not exists: " . get_class($storage) . "->{$method}()");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 图片数据存储
|
|
||||||
* @param string $base64 图片内容
|
* @param string $base64 图片内容
|
||||||
* @param string $prefix 保存前缀
|
* @param string $prefix 保存前缀
|
||||||
* @param boolean $safemode 安全模式
|
* @param bool $safemode 安全模式
|
||||||
* @return array [ url => URL ]
|
* @return array [ url => URL ]
|
||||||
* @throws \think\admin\Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public static function saveImage(string $base64, string $prefix = 'image', bool $safemode = false): array
|
public static function saveImage(string $base64, string $prefix = 'image', bool $safemode = false): array
|
||||||
{
|
{
|
||||||
@ -191,13 +187,12 @@ abstract class Storage
|
|||||||
$name = static::name($img, $ext, $prefix);
|
$name = static::name($img, $ext, $prefix);
|
||||||
if (empty($ext) || !in_array(strtolower($ext), ['gif', 'png', 'jpg', 'jpeg'])) {
|
if (empty($ext) || !in_array(strtolower($ext), ['gif', 'png', 'jpg', 'jpeg'])) {
|
||||||
throw new Exception('内容格式异常!');
|
throw new Exception('内容格式异常!');
|
||||||
} elseif ($safemode) {
|
|
||||||
return LocalStorage::instance()->set($name, base64_decode($img), true);
|
|
||||||
} else {
|
|
||||||
return static::instance()->set($name, base64_decode($img));
|
|
||||||
}
|
}
|
||||||
} else {
|
if ($safemode) {
|
||||||
return ['url' => $base64];
|
return LocalStorage::instance()->set($name, base64_decode($img), true);
|
||||||
|
}
|
||||||
|
return static::instance()->set($name, base64_decode($img));
|
||||||
}
|
}
|
||||||
|
return ['url' => $base64];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,21 +1,22 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// +----------------------------------------------------------------------
|
declare(strict_types=1);
|
||||||
// | Library for ThinkAdmin
|
/**
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 版权所有 2014~2025 ThinkAdmin [ thinkadmin.top ]
|
* | Payment Plugin for ThinkAdmin
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 官方网站: https://thinkadmin.top
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 开源协议 ( https://mit-license.org )
|
* | 官方网站: https://thinkadmin.top
|
||||||
// | 免费声明 ( https://thinkadmin.top/disclaimer )
|
* +----------------------------------------------------------------------
|
||||||
// +----------------------------------------------------------------------
|
* | 开源协议 ( https://mit-license.org )
|
||||||
// | gitee 仓库地址 :https://gitee.com/zoujingli/ThinkLibrary
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
// | github 仓库地址 :https://github.com/zoujingli/ThinkLibrary
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
declare (strict_types=1);
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
use think\admin\extend\CodeExtend;
|
use think\admin\extend\CodeExtend;
|
||||||
use think\admin\extend\HttpExtend;
|
use think\admin\extend\HttpExtend;
|
||||||
use think\admin\Helper;
|
use think\admin\Helper;
|
||||||
@ -35,9 +36,9 @@ use think\Model;
|
|||||||
|
|
||||||
if (!function_exists('p')) {
|
if (!function_exists('p')) {
|
||||||
/**
|
/**
|
||||||
* 打印输出数据到文件
|
* 打印输出数据到文件.
|
||||||
* @param mixed $data 输出的数据
|
* @param mixed $data 输出的数据
|
||||||
* @param boolean $new 强制替换文件
|
* @param bool $new 强制替换文件
|
||||||
* @param ?string $file 保存文件名称
|
* @param ?string $file 保存文件名称
|
||||||
* @return false|int
|
* @return false|int
|
||||||
*/
|
*/
|
||||||
@ -52,7 +53,6 @@ if (!function_exists('m')) {
|
|||||||
* @param string $name 模型名称
|
* @param string $name 模型名称
|
||||||
* @param array $data 初始数据
|
* @param array $data 初始数据
|
||||||
* @param string $conn 指定连接
|
* @param string $conn 指定连接
|
||||||
* @return Model
|
|
||||||
*/
|
*/
|
||||||
function m(string $name, array $data = [], string $conn = ''): Model
|
function m(string $name, array $data = [], string $conn = ''): Model
|
||||||
{
|
{
|
||||||
@ -62,9 +62,7 @@ if (!function_exists('m')) {
|
|||||||
|
|
||||||
if (!function_exists('auth')) {
|
if (!function_exists('auth')) {
|
||||||
/**
|
/**
|
||||||
* 访问权限检查
|
* 访问权限检查.
|
||||||
* @param ?string $node
|
|
||||||
* @return boolean
|
|
||||||
*/
|
*/
|
||||||
function auth(?string $node): bool
|
function auth(?string $node): bool
|
||||||
{
|
{
|
||||||
@ -76,9 +74,8 @@ if (!function_exists('admuri')) {
|
|||||||
* 生成后台 URL 地址
|
* 生成后台 URL 地址
|
||||||
* @param string $url 路由地址
|
* @param string $url 路由地址
|
||||||
* @param array $vars PATH 变量
|
* @param array $vars PATH 变量
|
||||||
* @param boolean|string $suffix 后缀
|
* @param bool|string $suffix 后缀
|
||||||
* @param boolean|string $domain 域名
|
* @param bool|string $domain 域名
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
function admuri(string $url = '', array $vars = [], $suffix = true, $domain = false): string
|
function admuri(string $url = '', array $vars = [], $suffix = true, $domain = false): string
|
||||||
{
|
{
|
||||||
@ -87,11 +84,10 @@ if (!function_exists('admuri')) {
|
|||||||
}
|
}
|
||||||
if (!function_exists('_vali')) {
|
if (!function_exists('_vali')) {
|
||||||
/**
|
/**
|
||||||
* 快捷输入并验证( 支持 规则 # 别名 )
|
* 快捷输入并验证( 支持 规则 # 别名 ).
|
||||||
* @param array $rules 验证规则( 验证信息数组 )
|
* @param array $rules 验证规则( 验证信息数组 )
|
||||||
* @param string|array $type 输入方式 ( post. 或 get. )
|
* @param array|string $type 输入方式 ( post. 或 get. )
|
||||||
* @param callable|null $callable 异常处理操作
|
* @param null|callable $callable 异常处理操作
|
||||||
* @return array
|
|
||||||
*/
|
*/
|
||||||
function _vali(array $rules, $type = '', ?callable $callable = null): array
|
function _vali(array $rules, $type = '', ?callable $callable = null): array
|
||||||
{
|
{
|
||||||
@ -100,10 +96,9 @@ if (!function_exists('_vali')) {
|
|||||||
}
|
}
|
||||||
if (!function_exists('_query')) {
|
if (!function_exists('_query')) {
|
||||||
/**
|
/**
|
||||||
* 快捷查询逻辑器
|
* 快捷查询逻辑器.
|
||||||
* @param BaseQuery|Model|string $dbQuery
|
* @param BaseQuery|Model|string $dbQuery
|
||||||
* @param array|string|null $input
|
* @param null|array|string $input
|
||||||
* @return QueryHelper
|
|
||||||
*/
|
*/
|
||||||
function _query($dbQuery, $input = null): QueryHelper
|
function _query($dbQuery, $input = null): QueryHelper
|
||||||
{
|
{
|
||||||
@ -112,7 +107,7 @@ if (!function_exists('_query')) {
|
|||||||
}
|
}
|
||||||
if (!function_exists('sysvar')) {
|
if (!function_exists('sysvar')) {
|
||||||
/**
|
/**
|
||||||
* 读写单次请求的内存缓存
|
* 读写单次请求的内存缓存.
|
||||||
* @param null|string $name 数据名称
|
* @param null|string $name 数据名称
|
||||||
* @param null|mixed $value 数据内容
|
* @param null|mixed $value 数据内容
|
||||||
* @return null|array|mixed 返回内容
|
* @return null|array|mixed 返回内容
|
||||||
@ -122,11 +117,11 @@ if (!function_exists('sysvar')) {
|
|||||||
static $swap = [];
|
static $swap = [];
|
||||||
if ($name === '' && $value === '') {
|
if ($name === '' && $value === '') {
|
||||||
return $swap = [];
|
return $swap = [];
|
||||||
} elseif (is_null($value)) {
|
|
||||||
return is_null($name) ? $swap : ($swap[$name] ?? null);
|
|
||||||
} else {
|
|
||||||
return $swap[$name] = $value;
|
|
||||||
}
|
}
|
||||||
|
if (is_null($value)) {
|
||||||
|
return is_null($name) ? $swap : ($swap[$name] ?? null);
|
||||||
|
}
|
||||||
|
return $swap[$name] = $value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!function_exists('sysuri')) {
|
if (!function_exists('sysuri')) {
|
||||||
@ -134,26 +129,33 @@ if (!function_exists('sysuri')) {
|
|||||||
* 生成最短 URL 地址
|
* 生成最短 URL 地址
|
||||||
* @param string $url 路由地址
|
* @param string $url 路由地址
|
||||||
* @param array $vars PATH 变量
|
* @param array $vars PATH 变量
|
||||||
* @param boolean|string $suffix 后缀
|
* @param bool|string $suffix 后缀
|
||||||
* @param boolean|string $domain 域名
|
* @param bool|string $domain 域名
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
function sysuri(string $url = '', array $vars = [], $suffix = true, $domain = false): string
|
function sysuri(string $url = '', array $vars = [], $suffix = true, $domain = false): string
|
||||||
{
|
{
|
||||||
if (preg_match('#^(https?://|\\|/|@)#', $url)) {
|
if (preg_match('#^(https?://|\|/|@)#', $url)) {
|
||||||
return Library::$sapp->route->buildUrl($url, $vars)->suffix($suffix)->domain($domain)->build();
|
return Library::$sapp->route->buildUrl($url, $vars)->suffix($suffix)->domain($domain)->build();
|
||||||
}
|
}
|
||||||
if (count($attr = $url === '' ? [] : explode('/', rtrim($url, '/'))) < 3) {
|
if (count($attr = $url === '' ? [] : explode('/', rtrim($url, '/'))) < 3) {
|
||||||
$map = [Library::$sapp->http->getName(), Library::$sapp->request->controller(), Library::$sapp->request->action(true)];
|
$map = [Library::$sapp->http->getName(), Library::$sapp->request->controller(), Library::$sapp->request->action(true)];
|
||||||
while (count($attr) < 3) array_unshift($attr, $map[2 - count($attr)] ?? 'index');
|
while (count($attr) < 3) {
|
||||||
|
array_unshift($attr, $map[2 - count($attr)] ?? 'index');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
$attr[1] = Str::snake($attr[1]);
|
$attr[1] = Str::snake($attr[1]);
|
||||||
[$rcf, $tmp] = [Library::$sapp->config->get('route', []), uniqid('think_admin_replace_temp_vars_')];
|
[$rcf, $tmp] = [Library::$sapp->config->get('route', []), uniqid('think_admin_replace_temp_vars_')];
|
||||||
$map = [Str::lower($rcf['default_app'] ?? ''), Str::snake($rcf['default_controller'] ?? ''), Str::lower($rcf['default_action'] ?? '')];
|
$map = [Str::lower($rcf['default_app'] ?? ''), Str::snake($rcf['default_controller'] ?? ''), Str::lower($rcf['default_action'] ?? '')];
|
||||||
for ($idx = count($attr) - 1; $idx >= 0; $idx--) if ($attr[$idx] == ($map[$idx] ?: 'index')) $attr[$idx] = $tmp; else break;
|
for ($idx = count($attr) - 1; $idx >= 0; --$idx) {
|
||||||
|
if ($attr[$idx] == ($map[$idx] ?: 'index')) {
|
||||||
|
$attr[$idx] = $tmp;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
$url = Library::$sapp->route->buildUrl(join('/', $attr), $vars)->suffix($suffix)->domain($domain)->build();
|
$url = Library::$sapp->route->buildUrl(join('/', $attr), $vars)->suffix($suffix)->domain($domain)->build();
|
||||||
$ext = is_string($suffix) ? $suffix : ($rcf['url_html_suffix'] ?? 'html');
|
$ext = is_string($suffix) ? $suffix : ($rcf['url_html_suffix'] ?? 'html');
|
||||||
$new = preg_replace("#/{$tmp}(\.{$ext})?#", '', $old = parse_url($url, PHP_URL_PATH) ?: '', -1, $count);
|
$new = preg_replace("#/{$tmp}(\\.{$ext})?#", '', $old = parse_url($url, PHP_URL_PATH) ?: '', -1, $count);
|
||||||
$count > 0 && $suffix && $new && $ext !== '' && $new !== Library::$sapp->request->baseUrl() && $new .= ".{$ext}";
|
$count > 0 && $suffix && $new && $ext !== '' && $new !== Library::$sapp->request->baseUrl() && $new .= ".{$ext}";
|
||||||
return str_replace($old, $new ?: '/', $url);
|
return str_replace($old, $new ?: '/', $url);
|
||||||
}
|
}
|
||||||
@ -161,23 +163,21 @@ if (!function_exists('sysuri')) {
|
|||||||
|
|
||||||
if (!function_exists('encode')) {
|
if (!function_exists('encode')) {
|
||||||
/**
|
/**
|
||||||
* 加密 UTF8 字符串
|
* 加密 UTF8 字符串.
|
||||||
* @param string $content
|
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
function encode(string $content): string
|
function encode(string $content): string
|
||||||
{
|
{
|
||||||
[$chars, $length] = ['', strlen($string = CodeExtend::text2utf8($content))];
|
[$chars, $length] = ['', strlen($string = CodeExtend::text2utf8($content))];
|
||||||
for ($i = 0; $i < $length; $i++) $chars .= str_pad(base_convert(strval(ord($string[$i])), 10, 36), 2, '0', 0);
|
for ($i = 0; $i < $length; ++$i) {
|
||||||
|
$chars .= str_pad(base_convert(strval(ord($string[$i])), 10, 36), 2, '0', 0);
|
||||||
|
}
|
||||||
return $chars;
|
return $chars;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!function_exists('decode')) {
|
if (!function_exists('decode')) {
|
||||||
/**
|
/**
|
||||||
* 解密 UTF8 字符串
|
* 解密 UTF8 字符串.
|
||||||
* @param string $content
|
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
function decode(string $content): string
|
function decode(string $content): string
|
||||||
{
|
{
|
||||||
@ -191,11 +191,10 @@ if (!function_exists('decode')) {
|
|||||||
|
|
||||||
if (!function_exists('str2arr')) {
|
if (!function_exists('str2arr')) {
|
||||||
/**
|
/**
|
||||||
* 字符串转数组
|
* 字符串转数组.
|
||||||
* @param string $text 待转内容
|
* @param string $text 待转内容
|
||||||
* @param string $separ 分隔字符
|
* @param string $separ 分隔字符
|
||||||
* @param ?array $allow 限定规则
|
* @param ?array $allow 限定规则
|
||||||
* @return array
|
|
||||||
*/
|
*/
|
||||||
function str2arr(string $text, string $separ = ',', ?array $allow = null): array
|
function str2arr(string $text, string $separ = ',', ?array $allow = null): array
|
||||||
{
|
{
|
||||||
@ -210,11 +209,10 @@ if (!function_exists('str2arr')) {
|
|||||||
}
|
}
|
||||||
if (!function_exists('arr2str')) {
|
if (!function_exists('arr2str')) {
|
||||||
/**
|
/**
|
||||||
* 数组转字符串
|
* 数组转字符串.
|
||||||
* @param array $data 待转数组
|
* @param array $data 待转数组
|
||||||
* @param string $separ 分隔字符
|
* @param string $separ 分隔字符
|
||||||
* @param ?array $allow 限定规则
|
* @param ?array $allow 限定规则
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
function arr2str(array $data, string $separ = ',', ?array $allow = null): string
|
function arr2str(array $data, string $separ = ',', ?array $allow = null): string
|
||||||
{
|
{
|
||||||
@ -229,8 +227,7 @@ if (!function_exists('arr2str')) {
|
|||||||
|
|
||||||
if (!function_exists('isDebug')) {
|
if (!function_exists('isDebug')) {
|
||||||
/**
|
/**
|
||||||
* 调试模式运行
|
* 调试模式运行.
|
||||||
* @return boolean
|
|
||||||
*/
|
*/
|
||||||
function isDebug(): bool
|
function isDebug(): bool
|
||||||
{
|
{
|
||||||
@ -239,8 +236,7 @@ if (!function_exists('isDebug')) {
|
|||||||
}
|
}
|
||||||
if (!function_exists('isOnline')) {
|
if (!function_exists('isOnline')) {
|
||||||
/**
|
/**
|
||||||
* 产品模式运行
|
* 产品模式运行.
|
||||||
* @return boolean
|
|
||||||
*/
|
*/
|
||||||
function isOnline(): bool
|
function isOnline(): bool
|
||||||
{
|
{
|
||||||
@ -250,58 +246,56 @@ if (!function_exists('isOnline')) {
|
|||||||
|
|
||||||
if (!function_exists('sysconf')) {
|
if (!function_exists('sysconf')) {
|
||||||
/**
|
/**
|
||||||
* 获取或配置系统参数
|
* 获取或配置系统参数.
|
||||||
* @param string $name 参数名称
|
* @param string $name 参数名称
|
||||||
* @param mixed $value 参数内容
|
* @param mixed $value 参数内容
|
||||||
* @return mixed
|
* @return mixed
|
||||||
* @throws \think\admin\Exception
|
* @throws think\admin\Exception
|
||||||
*/
|
*/
|
||||||
function sysconf(string $name = '', $value = null)
|
function sysconf(string $name = '', $value = null)
|
||||||
{
|
{
|
||||||
if (is_null($value) && is_string($name)) {
|
if (is_null($value) && is_string($name)) {
|
||||||
return SystemService::get($name);
|
return SystemService::get($name);
|
||||||
} else {
|
|
||||||
return SystemService::set($name, $value);
|
|
||||||
}
|
}
|
||||||
|
return SystemService::set($name, $value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!function_exists('sysdata')) {
|
if (!function_exists('sysdata')) {
|
||||||
/**
|
/**
|
||||||
* JSON 数据读取与存储
|
* JSON 数据读取与存储.
|
||||||
* @param string $name 数据名称
|
* @param string $name 数据名称
|
||||||
* @param mixed $value 数据内容
|
* @param mixed $value 数据内容
|
||||||
* @return mixed
|
* @return mixed
|
||||||
* @throws \think\admin\Exception
|
* @throws think\admin\Exception
|
||||||
*/
|
*/
|
||||||
function sysdata(string $name, $value = null)
|
function sysdata(string $name, $value = null)
|
||||||
{
|
{
|
||||||
if (is_null($value)) {
|
if (is_null($value)) {
|
||||||
return SystemService::getData($name);
|
return SystemService::getData($name);
|
||||||
} else {
|
|
||||||
return SystemService::setData($name, $value);
|
|
||||||
}
|
}
|
||||||
|
return SystemService::setData($name, $value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!function_exists('syspath')) {
|
if (!function_exists('syspath')) {
|
||||||
/**
|
/**
|
||||||
* 获取文件绝对路径
|
* 获取文件绝对路径.
|
||||||
* @param string $name 文件路径
|
* @param string $name 文件路径
|
||||||
* @param ?string $root 程序根路径
|
* @param ?string $root 程序根路径
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
function syspath(string $name = '', ?string $root = null): string
|
function syspath(string $name = '', ?string $root = null): string
|
||||||
{
|
{
|
||||||
if (is_null($root)) $root = Library::$sapp->getRootPath();
|
if (is_null($root)) {
|
||||||
|
$root = Library::$sapp->getRootPath();
|
||||||
|
}
|
||||||
$attr = ['/' => DIRECTORY_SEPARATOR, '\\' => DIRECTORY_SEPARATOR];
|
$attr = ['/' => DIRECTORY_SEPARATOR, '\\' => DIRECTORY_SEPARATOR];
|
||||||
return rtrim($root, '\\/') . DIRECTORY_SEPARATOR . ltrim(strtr($name, $attr), '\\/');
|
return rtrim($root, '\/') . DIRECTORY_SEPARATOR . ltrim(strtr($name, $attr), '\/');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!function_exists('sysoplog')) {
|
if (!function_exists('sysoplog')) {
|
||||||
/**
|
/**
|
||||||
* 写入系统日志
|
* 写入系统日志.
|
||||||
* @param string $action 日志行为
|
* @param string $action 日志行为
|
||||||
* @param string $content 日志内容
|
* @param string $content 日志内容
|
||||||
* @return boolean
|
|
||||||
*/
|
*/
|
||||||
function sysoplog(string $action, string $content): bool
|
function sysoplog(string $action, string $content): bool
|
||||||
{
|
{
|
||||||
@ -310,8 +304,7 @@ if (!function_exists('sysoplog')) {
|
|||||||
}
|
}
|
||||||
if (!function_exists('systoken')) {
|
if (!function_exists('systoken')) {
|
||||||
/**
|
/**
|
||||||
* 生成 CSRF-TOKEN 参数
|
* 生成 CSRF-TOKEN 参数.
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
function systoken(): string
|
function systoken(): string
|
||||||
{
|
{
|
||||||
@ -323,12 +316,11 @@ if (!function_exists('sysqueue')) {
|
|||||||
* 注册异步处理任务
|
* 注册异步处理任务
|
||||||
* @param string $title 任务名称
|
* @param string $title 任务名称
|
||||||
* @param string $command 执行内容
|
* @param string $command 执行内容
|
||||||
* @param integer $later 延时执行时间
|
* @param int $later 延时执行时间
|
||||||
* @param array $data 任务附加数据
|
* @param array $data 任务附加数据
|
||||||
* @param integer $rscript 任务类型(0单例,1多例)
|
* @param int $rscript 任务类型(0单例,1多例)
|
||||||
* @param integer $loops 循环等待时间
|
* @param int $loops 循环等待时间
|
||||||
* @return string
|
* @throws think\admin\Exception
|
||||||
* @throws \think\admin\Exception
|
|
||||||
*/
|
*/
|
||||||
function sysqueue(string $title, string $command, int $later = 0, array $data = [], int $rscript = 1, int $loops = 0): string
|
function sysqueue(string $title, string $command, int $later = 0, array $data = [], int $rscript = 1, int $loops = 0): string
|
||||||
{
|
{
|
||||||
@ -339,8 +331,6 @@ if (!function_exists('sysqueue')) {
|
|||||||
if (!function_exists('enbase64url')) {
|
if (!function_exists('enbase64url')) {
|
||||||
/**
|
/**
|
||||||
* Base64安全URL编码
|
* Base64安全URL编码
|
||||||
* @param string $string
|
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
function enbase64url(string $string): string
|
function enbase64url(string $string): string
|
||||||
{
|
{
|
||||||
@ -350,8 +340,6 @@ if (!function_exists('enbase64url')) {
|
|||||||
if (!function_exists('debase64url')) {
|
if (!function_exists('debase64url')) {
|
||||||
/**
|
/**
|
||||||
* Base64安全URL解码
|
* Base64安全URL解码
|
||||||
* @param string $string
|
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
function debase64url(string $string): string
|
function debase64url(string $string): string
|
||||||
{
|
{
|
||||||
@ -361,9 +349,7 @@ if (!function_exists('debase64url')) {
|
|||||||
|
|
||||||
if (!function_exists('xss_safe')) {
|
if (!function_exists('xss_safe')) {
|
||||||
/**
|
/**
|
||||||
* 文本内容XSS过滤
|
* 文本内容XSS过滤.
|
||||||
* @param string $text
|
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
function xss_safe(string $text): string
|
function xss_safe(string $text): string
|
||||||
{
|
{
|
||||||
@ -378,7 +364,7 @@ if (!function_exists('http_get')) {
|
|||||||
* @param string $url HTTP请求URL地址
|
* @param string $url HTTP请求URL地址
|
||||||
* @param array|string $query GET请求参数
|
* @param array|string $query GET请求参数
|
||||||
* @param array $options CURL参数
|
* @param array $options CURL参数
|
||||||
* @return boolean|string
|
* @return bool|string
|
||||||
*/
|
*/
|
||||||
function http_get(string $url, $query = [], array $options = [])
|
function http_get(string $url, $query = [], array $options = [])
|
||||||
{
|
{
|
||||||
@ -391,7 +377,7 @@ if (!function_exists('http_post')) {
|
|||||||
* @param string $url HTTP请求URL地址
|
* @param string $url HTTP请求URL地址
|
||||||
* @param array|string $data POST请求数据
|
* @param array|string $data POST请求数据
|
||||||
* @param array $options CURL参数
|
* @param array $options CURL参数
|
||||||
* @return boolean|string
|
* @return bool|string
|
||||||
*/
|
*/
|
||||||
function http_post(string $url, $data, array $options = [])
|
function http_post(string $url, $data, array $options = [])
|
||||||
{
|
{
|
||||||
@ -400,13 +386,13 @@ if (!function_exists('http_post')) {
|
|||||||
}
|
}
|
||||||
if (!function_exists('data_save')) {
|
if (!function_exists('data_save')) {
|
||||||
/**
|
/**
|
||||||
* 数据增量保存
|
* 数据增量保存.
|
||||||
* @param Model|Query|string $dbQuery
|
* @param Model|Query|string $dbQuery
|
||||||
* @param array $data 需要保存或更新的数据
|
* @param array $data 需要保存或更新的数据
|
||||||
* @param string $key 条件主键限制
|
* @param string $key 条件主键限制
|
||||||
* @param mixed $where 其它的where条件
|
* @param mixed $where 其它的where条件
|
||||||
* @return boolean|integer
|
* @return bool|int
|
||||||
* @throws \think\admin\Exception
|
* @throws think\admin\Exception
|
||||||
*/
|
*/
|
||||||
function data_save($dbQuery, array $data, string $key = 'id', $where = [])
|
function data_save($dbQuery, array $data, string $key = 'id', $where = [])
|
||||||
{
|
{
|
||||||
@ -415,11 +401,10 @@ if (!function_exists('data_save')) {
|
|||||||
}
|
}
|
||||||
if (!function_exists('down_file')) {
|
if (!function_exists('down_file')) {
|
||||||
/**
|
/**
|
||||||
* 下载远程文件到本地
|
* 下载远程文件到本地.
|
||||||
* @param string $source 远程文件地址
|
* @param string $source 远程文件地址
|
||||||
* @param boolean $force 是否强制重新下载
|
* @param bool $force 是否强制重新下载
|
||||||
* @param integer $expire 强制本地存储时间
|
* @param int $expire 强制本地存储时间
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
function down_file(string $source, bool $force = false, int $expire = 0): string
|
function down_file(string $source, bool $force = false, int $expire = 0): string
|
||||||
{
|
{
|
||||||
@ -429,62 +414,63 @@ if (!function_exists('down_file')) {
|
|||||||
|
|
||||||
if (!function_exists('trace_file')) {
|
if (!function_exists('trace_file')) {
|
||||||
/**
|
/**
|
||||||
* 输出异常数据到文件
|
* 输出异常数据到文件.
|
||||||
* @param \Exception $exception
|
|
||||||
* @return boolean
|
|
||||||
*/
|
*/
|
||||||
function trace_file(Exception $exception): bool
|
function trace_file(Exception $exception): bool
|
||||||
{
|
{
|
||||||
$path = Library::$sapp->getRuntimePath() . 'trace';
|
$path = Library::$sapp->getRuntimePath() . 'trace';
|
||||||
if (!is_dir($path)) mkdir($path, 0777, true);
|
if (!is_dir($path)) {
|
||||||
|
mkdir($path, 0777, true);
|
||||||
|
}
|
||||||
$name = substr($exception->getFile(), strlen(syspath()));
|
$name = substr($exception->getFile(), strlen(syspath()));
|
||||||
$file = $path . DIRECTORY_SEPARATOR . date('Ymd_His_') . strtr($name, ['/' => '.', '\\' => '.']);
|
$file = $path . DIRECTORY_SEPARATOR . date('Ymd_His_') . strtr($name, ['/' => '.', '\\' => '.']);
|
||||||
$json = json_encode($exception instanceof \think\admin\Exception ? $exception->getData() : [], 64 | 128 | 256);
|
$json = json_encode($exception instanceof think\admin\Exception ? $exception->getData() : [], 64 | 128 | 256);
|
||||||
$class = get_class($exception);
|
$class = get_class($exception);
|
||||||
return false !== file_put_contents($file,
|
return file_put_contents(
|
||||||
"[CODE] {$exception->getCode()}" . PHP_EOL .
|
$file,
|
||||||
"[INFO] {$exception->getMessage()}" . PHP_EOL .
|
"[CODE] {$exception->getCode()}" . PHP_EOL
|
||||||
($exception instanceof \think\admin\Exception ? "[DATA] {$json}" . PHP_EOL : '') .
|
. "[INFO] {$exception->getMessage()}" . PHP_EOL
|
||||||
"[FILE] {$class} in {$name} line {$exception->getLine()}" . PHP_EOL .
|
. ($exception instanceof think\admin\Exception ? "[DATA] {$json}" . PHP_EOL : '')
|
||||||
"[TIME] " . date('Y-m-d H:i:s') . PHP_EOL . PHP_EOL .
|
. "[FILE] {$class} in {$name} line {$exception->getLine()}" . PHP_EOL
|
||||||
'[TRACE]' . PHP_EOL . $exception->getTraceAsString()
|
. '[TIME] ' . date('Y-m-d H:i:s') . PHP_EOL . PHP_EOL
|
||||||
);
|
. '[TRACE]' . PHP_EOL . $exception->getTraceAsString()
|
||||||
|
) !== false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!function_exists('format_bytes')) {
|
if (!function_exists('format_bytes')) {
|
||||||
/**
|
/**
|
||||||
* 文件字节单位转换
|
* 文件字节单位转换.
|
||||||
* @param string|integer $size
|
* @param int|string $size
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
function format_bytes($size): string
|
function format_bytes($size): string
|
||||||
{
|
{
|
||||||
if (is_numeric($size)) {
|
if (is_numeric($size)) {
|
||||||
$units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
|
$units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
|
||||||
for ($i = 0; $size >= 1024 && $i < 4; $i++) $size /= 1024;
|
for ($i = 0; $size >= 1024 && $i < 4; ++$i) {
|
||||||
|
$size /= 1024;
|
||||||
|
}
|
||||||
return round($size, 2) . ' ' . $units[$i];
|
return round($size, 2) . ' ' . $units[$i];
|
||||||
} else {
|
|
||||||
return $size;
|
|
||||||
}
|
}
|
||||||
|
return $size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!function_exists('format_datetime')) {
|
if (!function_exists('format_datetime')) {
|
||||||
/**
|
/**
|
||||||
* 日期格式标准输出
|
* 日期格式标准输出.
|
||||||
* @param int|string $datetime 输入日期
|
* @param int|string $datetime 输入日期
|
||||||
* @param string $format 输出格式
|
* @param string $format 输出格式
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
function format_datetime($datetime, string $format = 'Y年m月d日 H:i:s'): string
|
function format_datetime($datetime, string $format = 'Y年m月d日 H:i:s'): string
|
||||||
{
|
{
|
||||||
if (empty($datetime)) {
|
if (empty($datetime)) {
|
||||||
return '-';
|
return '-';
|
||||||
} elseif (is_numeric($datetime)) {
|
|
||||||
return date(lang($format), intval($datetime));
|
|
||||||
} elseif ($timestamp = strtotime((string)$datetime)) {
|
|
||||||
return date(lang($format), $timestamp);
|
|
||||||
} else {
|
|
||||||
return (string)$datetime;
|
|
||||||
}
|
}
|
||||||
|
if (is_numeric($datetime)) {
|
||||||
|
return date(lang($format), intval($datetime));
|
||||||
|
}
|
||||||
|
if ($timestamp = strtotime((string)$datetime)) {
|
||||||
|
return date(lang($format), $timestamp);
|
||||||
|
}
|
||||||
|
return (string)$datetime;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,99 +1,91 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// +----------------------------------------------------------------------
|
declare(strict_types=1);
|
||||||
// | Library for ThinkAdmin
|
/**
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 版权所有 2014~2025 ThinkAdmin [ thinkadmin.top ]
|
* | Payment Plugin for ThinkAdmin
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 官方网站: https://thinkadmin.top
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 开源协议 ( https://mit-license.org )
|
* | 官方网站: https://thinkadmin.top
|
||||||
// | 免费声明 ( https://thinkadmin.top/disclaimer )
|
* +----------------------------------------------------------------------
|
||||||
// +----------------------------------------------------------------------
|
* | 开源协议 ( https://mit-license.org )
|
||||||
// | gitee 仓库地址 :https://gitee.com/zoujingli/ThinkLibrary
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
// | github 仓库地址 :https://github.com/zoujingli/ThinkLibrary
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
declare (strict_types=1);
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
namespace think\admin\contract;
|
namespace think\admin\contract;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 文件存储标准接口
|
* 文件存储标准接口.
|
||||||
* @class StorageInterface
|
* @class StorageInterface
|
||||||
* @package think\admin\contract
|
|
||||||
*/
|
*/
|
||||||
interface StorageInterface
|
interface StorageInterface
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* 上传文件内容
|
* 上传文件内容.
|
||||||
* @param string $name 文件名称
|
* @param string $name 文件名称
|
||||||
* @param string $file 文件内容
|
* @param string $file 文件内容
|
||||||
* @param boolean $safe 安全模式
|
* @param bool $safe 安全模式
|
||||||
* @param ?string $attname 下载名称
|
* @param ?string $attname 下载名称
|
||||||
* @return array
|
|
||||||
*/
|
*/
|
||||||
public function set(string $name, string $file, bool $safe = false, ?string $attname = null): array;
|
public function set(string $name, string $file, bool $safe = false, ?string $attname = null): array;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 读取文件内容
|
* 读取文件内容.
|
||||||
* @param string $name 文件名称
|
* @param string $name 文件名称
|
||||||
* @param boolean $safe 安全模式
|
* @param bool $safe 安全模式
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public function get(string $name, bool $safe = false): string;
|
public function get(string $name, bool $safe = false): string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 删除存储文件
|
* 删除存储文件.
|
||||||
* @param string $name 文件名称
|
* @param string $name 文件名称
|
||||||
* @param boolean $safe 安全模式
|
* @param bool $safe 安全模式
|
||||||
* @return boolean
|
|
||||||
*/
|
*/
|
||||||
public function del(string $name, bool $safe = false): bool;
|
public function del(string $name, bool $safe = false): bool;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 判断是否存在
|
* 判断是否存在.
|
||||||
* @param string $name 文件名称
|
* @param string $name 文件名称
|
||||||
* @param boolean $safe 安全模式
|
* @param bool $safe 安全模式
|
||||||
* @return boolean
|
|
||||||
*/
|
*/
|
||||||
public function has(string $name, bool $safe = false): bool;
|
public function has(string $name, bool $safe = false): bool;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取访问地址
|
* 获取访问地址
|
||||||
* @param string $name 文件名称
|
* @param string $name 文件名称
|
||||||
* @param boolean $safe 安全模式
|
* @param bool $safe 安全模式
|
||||||
* @param ?string $attname 下载名称
|
* @param ?string $attname 下载名称
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public function url(string $name, bool $safe = false, ?string $attname = null): string;
|
public function url(string $name, bool $safe = false, ?string $attname = null): string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取存储路径
|
* 获取存储路径.
|
||||||
* @param string $name 文件名称
|
* @param string $name 文件名称
|
||||||
* @param boolean $safe 安全模式
|
* @param bool $safe 安全模式
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public function path(string $name, bool $safe = false): string;
|
public function path(string $name, bool $safe = false): string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取文件信息
|
* 获取文件信息.
|
||||||
* @param string $name 文件名称
|
* @param string $name 文件名称
|
||||||
* @param boolean $safe 安全模式
|
* @param bool $safe 安全模式
|
||||||
* @param ?string $attname 下载名称
|
* @param ?string $attname 下载名称
|
||||||
* @return array
|
|
||||||
*/
|
*/
|
||||||
public function info(string $name, bool $safe = false, ?string $attname = null): array;
|
public function info(string $name, bool $safe = false, ?string $attname = null): array;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取上传地址
|
* 获取上传地址
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public function upload(): string;
|
public function upload(): string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取存储区域
|
* 获取存储区域
|
||||||
* @return array
|
|
||||||
*/
|
*/
|
||||||
public static function region(): array;
|
public static function region(): array;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,7 +14,23 @@
|
|||||||
// | github 仓库地址 :https://github.com/zoujingli/ThinkLibrary
|
// | github 仓库地址 :https://github.com/zoujingli/ThinkLibrary
|
||||||
// +----------------------------------------------------------------------
|
// +----------------------------------------------------------------------
|
||||||
|
|
||||||
declare (strict_types=1);
|
declare(strict_types=1);
|
||||||
|
/**
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
* | Payment Plugin for ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
* | 官方网站: https://thinkadmin.top
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
* | 开源协议 ( https://mit-license.org )
|
||||||
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
namespace think\admin\contract;
|
namespace think\admin\contract;
|
||||||
|
|
||||||
@ -23,19 +39,18 @@ use think\App;
|
|||||||
use think\Container;
|
use think\Container;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 文件存储公共属性
|
* 文件存储公共属性.
|
||||||
* @class StorageUsageTrait
|
* @class StorageUsageTrait
|
||||||
* @package think\admin\contract
|
|
||||||
*/
|
*/
|
||||||
trait StorageUsageTrait
|
trait StorageUsageTrait
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @var \think\App $app
|
* @var App
|
||||||
*/
|
*/
|
||||||
protected $app;
|
protected $app;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 链接类型
|
* 链接类型.
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
protected $link;
|
protected $link;
|
||||||
@ -47,9 +62,8 @@ trait StorageUsageTrait
|
|||||||
protected $domain;
|
protected $domain;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 存储器构造方法
|
* 存储器构造方法.
|
||||||
* @param \think\App $app
|
* @throws Exception
|
||||||
* @throws \think\admin\Exception
|
|
||||||
*/
|
*/
|
||||||
public function __construct(App $app)
|
public function __construct(App $app)
|
||||||
{
|
{
|
||||||
@ -59,38 +73,51 @@ trait StorageUsageTrait
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 自定义初始化方法
|
* 重构后兼容处理.
|
||||||
* @return void
|
* @return array|string
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
protected function init()
|
public function __call(string $method, array $arguments)
|
||||||
{
|
{
|
||||||
|
if (strtolower($method) === 'builduploadtoken') {
|
||||||
|
if (method_exists($this, 'token')) {
|
||||||
|
return $this->token(...$arguments);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 调用方法异常处理
|
||||||
|
$class = class_basename(static::class);
|
||||||
|
throw new Exception("method not exists: {$class}->{$method}()");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取对象实例
|
* 获取对象实例.
|
||||||
* @return static
|
* @return static
|
||||||
*/
|
*/
|
||||||
public static function instance()
|
public static function instance()
|
||||||
{
|
{
|
||||||
/** @var \think\admin\contract\StorageInterface */
|
/* @var \think\admin\contract\StorageInterface */
|
||||||
return Container::getInstance()->make(static::class);
|
return Container::getInstance()->make(static::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 自定义初始化方法.
|
||||||
|
*/
|
||||||
|
protected function init() {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取下载链接后缀
|
* 获取下载链接后缀
|
||||||
* @param null|string $attname 下载名称
|
* @param null|string $attname 下载名称
|
||||||
* @param null|string $filename 文件名称
|
* @param null|string $filename 文件名称
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
protected function getSuffix(?string $attname = null, ?string $filename = null): string
|
protected function getSuffix(?string $attname = null, ?string $filename = null): string
|
||||||
{
|
{
|
||||||
[$class, $suffix] = [class_basename(get_class($this)), ''];
|
[$class, $suffix] = [class_basename(get_class($this)), ''];
|
||||||
if (is_string($filename) && stripos($this->link, 'compress') !== false) {
|
if (is_string($filename) && stripos($this->link, 'compress') !== false) {
|
||||||
$compress = [
|
$compress = [
|
||||||
'LocalStorage' => '',
|
'LocalStorage' => '',
|
||||||
'QiniuStorage' => '?imageslim',
|
'QiniuStorage' => '?imageslim',
|
||||||
'UpyunStorage' => '!/format/webp',
|
'UpyunStorage' => '!/format/webp',
|
||||||
'TxcosStorage' => '?imageMogr2/format/webp',
|
'TxcosStorage' => '?imageMogr2/format/webp',
|
||||||
'AliossStorage' => '?x-oss-process=image/format,webp',
|
'AliossStorage' => '?x-oss-process=image/format,webp',
|
||||||
];
|
];
|
||||||
$extens = strtolower(pathinfo($this->delSuffix($filename), PATHINFO_EXTENSION));
|
$extens = strtolower(pathinfo($this->delSuffix($filename), PATHINFO_EXTENSION));
|
||||||
@ -107,9 +134,8 @@ trait StorageUsageTrait
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取文件基础名称
|
* 获取文件基础名称.
|
||||||
* @param string $name 文件名称
|
* @param string $name 文件名称
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
protected function delSuffix(string $name): string
|
protected function delSuffix(string $name): string
|
||||||
{
|
{
|
||||||
@ -121,23 +147,4 @@ trait StorageUsageTrait
|
|||||||
}
|
}
|
||||||
return $name;
|
return $name;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
/**
|
|
||||||
* 重构后兼容处理
|
|
||||||
* @param string $method
|
|
||||||
* @param array $arguments
|
|
||||||
* @return array|string
|
|
||||||
* @throws \think\admin\Exception
|
|
||||||
*/
|
|
||||||
public function __call(string $method, array $arguments)
|
|
||||||
{
|
|
||||||
if (strtolower($method) === 'builduploadtoken') {
|
|
||||||
if (method_exists($this, 'token')) {
|
|
||||||
return $this->token(...$arguments);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 调用方法异常处理
|
|
||||||
$class = class_basename(static::class);
|
|
||||||
throw new Exception("method not exists: {$class}->{$method}()");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@ -1,27 +1,28 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// +----------------------------------------------------------------------
|
declare(strict_types=1);
|
||||||
// | Library for ThinkAdmin
|
/**
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 版权所有 2014~2025 ThinkAdmin [ thinkadmin.top ]
|
* | Payment Plugin for ThinkAdmin
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 官方网站: https://thinkadmin.top
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 开源协议 ( https://mit-license.org )
|
* | 官方网站: https://thinkadmin.top
|
||||||
// | 免费声明 ( https://thinkadmin.top/disclaimer )
|
* +----------------------------------------------------------------------
|
||||||
// +----------------------------------------------------------------------
|
* | 开源协议 ( https://mit-license.org )
|
||||||
// | gitee 仓库地址 :https://gitee.com/zoujingli/ThinkLibrary
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
// | github 仓库地址 :https://github.com/zoujingli/ThinkLibrary
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
declare (strict_types=1);
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
namespace think\admin\contract;
|
namespace think\admin\contract;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 流协议接口
|
* 流协议接口.
|
||||||
* @class StreamInterface
|
* @class StreamInterface
|
||||||
* @package think\admin\contract
|
|
||||||
*/
|
*/
|
||||||
interface StreamInterface
|
interface StreamInterface
|
||||||
{
|
{
|
||||||
@ -54,8 +55,7 @@ interface StreamInterface
|
|||||||
public function stream_open(string $path, string $mode, int $options, ?string &$opened_path): bool;
|
public function stream_open(string $path, string $mode, int $options, ?string &$opened_path): bool;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param int $count
|
* @return false|string
|
||||||
* @return string|false
|
|
||||||
*/
|
*/
|
||||||
public function stream_read(int $count);
|
public function stream_read(int $count);
|
||||||
|
|
||||||
@ -77,9 +77,7 @@ interface StreamInterface
|
|||||||
public function unlink(string $path): bool;
|
public function unlink(string $path): bool;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $path
|
|
||||||
* @param integer $flags
|
|
||||||
* @return array|false
|
* @return array|false
|
||||||
*/
|
*/
|
||||||
public function url_stat(string $path, int $flags);
|
public function url_stat(string $path, int $flags);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,34 +1,33 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// +----------------------------------------------------------------------
|
declare(strict_types=1);
|
||||||
// | Library for ThinkAdmin
|
/**
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 版权所有 2014~2025 ThinkAdmin [ thinkadmin.top ]
|
* | Payment Plugin for ThinkAdmin
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 官方网站: https://thinkadmin.top
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 开源协议 ( https://mit-license.org )
|
* | 官方网站: https://thinkadmin.top
|
||||||
// | 免费声明 ( https://thinkadmin.top/disclaimer )
|
* +----------------------------------------------------------------------
|
||||||
// +----------------------------------------------------------------------
|
* | 开源协议 ( https://mit-license.org )
|
||||||
// | gitee 仓库地址 :https://gitee.com/zoujingli/ThinkLibrary
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
// | github 仓库地址 :https://github.com/zoujingli/ThinkLibrary
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
declare (strict_types=1);
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
namespace think\admin\extend;
|
namespace think\admin\extend;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 随机数码管理扩展
|
* 随机数码管理扩展.
|
||||||
* @class CodeExtend
|
* @class CodeExtend
|
||||||
* @package think\admin\extend
|
|
||||||
*/
|
*/
|
||||||
class CodeExtend
|
class CodeExtend
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 生成 UUID 编码
|
* 生成 UUID 编码
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public static function uuid(): string
|
public static function uuid(): string
|
||||||
{
|
{
|
||||||
@ -40,48 +39,59 @@ class CodeExtend
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 生成随机编码
|
* 生成随机编码
|
||||||
* @param integer $size 编码长度
|
* @param int $size 编码长度
|
||||||
* @param integer $type 编码类型(1纯数字,2纯字母,3数字字母)
|
* @param int $type 编码类型(1纯数字,2纯字母,3数字字母)
|
||||||
* @param string $prefix 编码前缀
|
* @param string $prefix 编码前缀
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public static function random(int $size = 10, int $type = 1, string $prefix = ''): string
|
public static function random(int $size = 10, int $type = 1, string $prefix = ''): string
|
||||||
{
|
{
|
||||||
$numbs = '0123456789';
|
$numbs = '0123456789';
|
||||||
$chars = 'abcdefghijklmnopqrstuvwxyz';
|
$chars = 'abcdefghijklmnopqrstuvwxyz';
|
||||||
if ($type === 1) $chars = $numbs;
|
if ($type === 1) {
|
||||||
if ($type === 3) $chars = "{$numbs}{$chars}";
|
$chars = $numbs;
|
||||||
|
}
|
||||||
|
if ($type === 3) {
|
||||||
|
$chars = "{$numbs}{$chars}";
|
||||||
|
}
|
||||||
$code = $prefix . $chars[rand(1, strlen($chars) - 1)];
|
$code = $prefix . $chars[rand(1, strlen($chars) - 1)];
|
||||||
while (strlen($code) < $size) $code .= $chars[rand(0, strlen($chars) - 1)];
|
while (strlen($code) < $size) {
|
||||||
|
$code .= $chars[rand(0, strlen($chars) - 1)];
|
||||||
|
}
|
||||||
return $code;
|
return $code;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 生成日期编码
|
* 生成日期编码
|
||||||
* @param integer $size 编码长度
|
* @param int $size 编码长度
|
||||||
* @param string $prefix 编码前缀
|
* @param string $prefix 编码前缀
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public static function uniqidDate(int $size = 16, string $prefix = ''): string
|
public static function uniqidDate(int $size = 16, string $prefix = ''): string
|
||||||
{
|
{
|
||||||
if ($size < 14) $size = 14;
|
if ($size < 14) {
|
||||||
|
$size = 14;
|
||||||
|
}
|
||||||
$code = $prefix . date('Ymd') . (date('H') + date('i')) . date('s');
|
$code = $prefix . date('Ymd') . (date('H') + date('i')) . date('s');
|
||||||
while (strlen($code) < $size) $code .= rand(0, 9);
|
while (strlen($code) < $size) {
|
||||||
|
$code .= rand(0, 9);
|
||||||
|
}
|
||||||
return $code;
|
return $code;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 生成数字编码
|
* 生成数字编码
|
||||||
* @param integer $size 编码长度
|
* @param int $size 编码长度
|
||||||
* @param string $prefix 编码前缀
|
* @param string $prefix 编码前缀
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public static function uniqidNumber(int $size = 12, string $prefix = ''): string
|
public static function uniqidNumber(int $size = 12, string $prefix = ''): string
|
||||||
{
|
{
|
||||||
$time = strval(time());
|
$time = strval(time());
|
||||||
if ($size < 10) $size = 10;
|
if ($size < 10) {
|
||||||
|
$size = 10;
|
||||||
|
}
|
||||||
$code = $prefix . (intval($time[0]) + intval($time[1])) . substr($time, 2) . rand(0, 9);
|
$code = $prefix . (intval($time[0]) + intval($time[1])) . substr($time, 2) . rand(0, 9);
|
||||||
while (strlen($code) < $size) $code .= rand(0, 9);
|
while (strlen($code) < $size) {
|
||||||
|
$code .= rand(0, 9);
|
||||||
|
}
|
||||||
return $code;
|
return $code;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,23 +99,26 @@ class CodeExtend
|
|||||||
* 文本转码
|
* 文本转码
|
||||||
* @param string $text 文本内容
|
* @param string $text 文本内容
|
||||||
* @param string $target 目标编码
|
* @param string $target 目标编码
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public static function text2utf8(string $text, string $target = 'UTF-8'): string
|
public static function text2utf8(string $text, string $target = 'UTF-8'): string
|
||||||
{
|
{
|
||||||
[$first2, $first4] = [substr($text, 0, 2), substr($text, 0, 4)];
|
[$first2, $first4] = [substr($text, 0, 2), substr($text, 0, 4)];
|
||||||
if ($first4 === chr(0x00) . chr(0x00) . chr(0xFE) . chr(0xFF)) $ft = 'UTF-32BE';
|
if ($first4 === chr(0x00) . chr(0x00) . chr(0xFE) . chr(0xFF)) {
|
||||||
elseif ($first4 === chr(0xFF) . chr(0xFE) . chr(0x00) . chr(0x00)) $ft = 'UTF-32LE';
|
$ft = 'UTF-32BE';
|
||||||
elseif ($first2 === chr(0xFE) . chr(0xFF)) $ft = 'UTF-16BE';
|
} elseif ($first4 === chr(0xFF) . chr(0xFE) . chr(0x00) . chr(0x00)) {
|
||||||
elseif ($first2 === chr(0xFF) . chr(0xFE)) $ft = 'UTF-16LE';
|
$ft = 'UTF-32LE';
|
||||||
|
} elseif ($first2 === chr(0xFE) . chr(0xFF)) {
|
||||||
|
$ft = 'UTF-16BE';
|
||||||
|
} elseif ($first2 === chr(0xFF) . chr(0xFE)) {
|
||||||
|
$ft = 'UTF-16LE';
|
||||||
|
}
|
||||||
return mb_convert_encoding($text, $target, $ft ?? mb_detect_encoding($text));
|
return mb_convert_encoding($text, $target, $ft ?? mb_detect_encoding($text));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 数据加密处理
|
* 数据加密处理.
|
||||||
* @param mixed $data 加密数据
|
* @param mixed $data 加密数据
|
||||||
* @param string $skey 安全密钥
|
* @param string $skey 安全密钥
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public static function encrypt($data, string $skey): string
|
public static function encrypt($data, string $skey): string
|
||||||
{
|
{
|
||||||
@ -115,7 +128,7 @@ class CodeExtend
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 数据解密处理
|
* 数据解密处理.
|
||||||
* @param string $data 解密数据
|
* @param string $data 解密数据
|
||||||
* @param string $skey 安全密钥
|
* @param string $skey 安全密钥
|
||||||
* @return mixed
|
* @return mixed
|
||||||
@ -129,7 +142,6 @@ class CodeExtend
|
|||||||
/**
|
/**
|
||||||
* Base64Url 安全编码
|
* Base64Url 安全编码
|
||||||
* @param string $text 待加密文本
|
* @param string $text 待加密文本
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public static function enSafe64(string $text): string
|
public static function enSafe64(string $text): string
|
||||||
{
|
{
|
||||||
@ -139,17 +151,15 @@ class CodeExtend
|
|||||||
/**
|
/**
|
||||||
* Base64Url 安全解码
|
* Base64Url 安全解码
|
||||||
* @param string $text 待解密文本
|
* @param string $text 待解密文本
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public static function deSafe64(string $text): string
|
public static function deSafe64(string $text): string
|
||||||
{
|
{
|
||||||
return base64_decode(str_pad(strtr($text, '-_', '+/'), (int) (ceil(strlen($text) / 4) * 4), '='));
|
return base64_decode(str_pad(strtr($text, '-_', '+/'), (int)(ceil(strlen($text) / 4) * 4), '='));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 压缩数据对象
|
* 压缩数据对象
|
||||||
* @param mixed $data
|
* @param mixed $data
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public static function enzip($data): string
|
public static function enzip($data): string
|
||||||
{
|
{
|
||||||
@ -158,11 +168,10 @@ class CodeExtend
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 解压数据对象
|
* 解压数据对象
|
||||||
* @param string $string
|
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public static function dezip(string $string)
|
public static function dezip(string $string)
|
||||||
{
|
{
|
||||||
return unserialize(gzuncompress(static::deSafe64($string)));
|
return unserialize(gzuncompress(static::deSafe64($string)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,56 +1,57 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// +----------------------------------------------------------------------
|
declare(strict_types=1);
|
||||||
// | Library for ThinkAdmin
|
/**
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 版权所有 2014~2025 ThinkAdmin [ thinkadmin.top ]
|
* | Payment Plugin for ThinkAdmin
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 官方网站: https://thinkadmin.top
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 开源协议 ( https://mit-license.org )
|
* | 官方网站: https://thinkadmin.top
|
||||||
// | 免费声明 ( https://thinkadmin.top/disclaimer )
|
* +----------------------------------------------------------------------
|
||||||
// +----------------------------------------------------------------------
|
* | 开源协议 ( https://mit-license.org )
|
||||||
// | gitee 仓库地址 :https://gitee.com/zoujingli/ThinkLibrary
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
// | github 仓库地址 :https://github.com/zoujingli/ThinkLibrary
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
declare (strict_types=1);
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
namespace think\admin\extend;
|
namespace think\admin\extend;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 数据处理扩展
|
* 数据处理扩展.
|
||||||
* @class DataExtend
|
* @class DataExtend
|
||||||
* @package think\admin\extend
|
|
||||||
*/
|
*/
|
||||||
class DataExtend
|
class DataExtend
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* 二维数组转多维数据树
|
* 二维数组转多维数据树.
|
||||||
* @param array $list 待处理数据
|
* @param array $list 待处理数据
|
||||||
* @param string $ckey 自己的主键
|
* @param string $ckey 自己的主键
|
||||||
* @param string $pkey 上级的主键
|
* @param string $pkey 上级的主键
|
||||||
* @param string $chil 子数组名称
|
* @param string $chil 子数组名称
|
||||||
* @return array
|
|
||||||
*/
|
*/
|
||||||
public static function arr2tree(array $list, string $ckey = 'id', string $pkey = 'pid', string $chil = 'sub'): array
|
public static function arr2tree(array $list, string $ckey = 'id', string $pkey = 'pid', string $chil = 'sub'): array
|
||||||
{
|
{
|
||||||
[$tree, $list] = [[], array_column($list, null, $ckey)];
|
[$tree, $list] = [[], array_column($list, null, $ckey)];
|
||||||
foreach ($list as $it) isset($list[$it[$pkey]]) ? $list[$it[$pkey]][$chil][] = &$list[$it[$ckey]] : $tree[] = &$list[$it[$ckey]];
|
foreach ($list as $it) {
|
||||||
|
isset($list[$it[$pkey]]) ? $list[$it[$pkey]][$chil][] = &$list[$it[$ckey]] : $tree[] = &$list[$it[$ckey]];
|
||||||
|
}
|
||||||
return $tree;
|
return $tree;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 二维数组转数据树表
|
* 二维数组转数据树表.
|
||||||
* @param array $list 待处理数据
|
* @param array $list 待处理数据
|
||||||
* @param string $ckey 自己的主键
|
* @param string $ckey 自己的主键
|
||||||
* @param string $pkey 上级的主键
|
* @param string $pkey 上级的主键
|
||||||
* @param string $path 当前 PATH
|
* @param string $path 当前 PATH
|
||||||
* @return array
|
|
||||||
*/
|
*/
|
||||||
public static function arr2table(array $list, string $ckey = 'id', string $pkey = 'pid', string $path = 'path'): array
|
public static function arr2table(array $list, string $ckey = 'id', string $pkey = 'pid', string $path = 'path'): array
|
||||||
{
|
{
|
||||||
$build = static function (array $nodes, callable $build, array &$data = [], string $parent = '') use ($ckey, $pkey, $path) {
|
$build = static function (array $nodes, callable $build, array &$data = [], string $parent = '') use ($ckey, $path) {
|
||||||
foreach ($nodes as $node) {
|
foreach ($nodes as $node) {
|
||||||
$subs = $node['sub'] ?? [];
|
$subs = $node['sub'] ?? [];
|
||||||
unset($node['sub']);
|
unset($node['sub']);
|
||||||
@ -60,11 +61,15 @@ class DataExtend
|
|||||||
$node['spl'] = str_repeat('ㅤ├ㅤ', $node['spt']);
|
$node['spl'] = str_repeat('ㅤ├ㅤ', $node['spt']);
|
||||||
$node['sps'] = ",{$node[$ckey]},";
|
$node['sps'] = ",{$node[$ckey]},";
|
||||||
array_walk_recursive($subs, static function ($val, $key) use ($ckey, &$node) {
|
array_walk_recursive($subs, static function ($val, $key) use ($ckey, &$node) {
|
||||||
if ($key === $ckey) $node['sps'] .= "{$val},";
|
if ($key === $ckey) {
|
||||||
|
$node['sps'] .= "{$val},";
|
||||||
|
}
|
||||||
});
|
});
|
||||||
$node['spp'] = arr2str(str2arr(strtr($parent . $node['sps'], '-', ',')));
|
$node['spp'] = arr2str(str2arr(strtr($parent . $node['sps'], '-', ',')));
|
||||||
$data[] = $node;
|
$data[] = $node;
|
||||||
if (empty($subs)) continue;
|
if (empty($subs)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
$build($subs, $build, $data, $node[$path]);
|
$build($subs, $build, $data, $node[$path]);
|
||||||
}
|
}
|
||||||
return $data;
|
return $data;
|
||||||
@ -73,19 +78,20 @@ class DataExtend
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取数据树子ID集合
|
* 获取数据树子ID集合.
|
||||||
* @param array $list 数据列表
|
* @param array $list 数据列表
|
||||||
* @param mixed $value 起始有效ID值
|
* @param mixed $value 起始有效ID值
|
||||||
* @param string $ckey 当前主键ID名称
|
* @param string $ckey 当前主键ID名称
|
||||||
* @param string $pkey 上级主键ID名称
|
* @param string $pkey 上级主键ID名称
|
||||||
* @return array
|
|
||||||
*/
|
*/
|
||||||
public static function getArrSubIds(array $list, $value = 0, string $ckey = 'id', string $pkey = 'pid'): array
|
public static function getArrSubIds(array $list, $value = 0, string $ckey = 'id', string $pkey = 'pid'): array
|
||||||
{
|
{
|
||||||
$ids = [intval($value)];
|
$ids = [intval($value)];
|
||||||
foreach ($list as $vo) if (intval($vo[$pkey]) > 0 && intval($vo[$pkey]) === intval($value)) {
|
foreach ($list as $vo) {
|
||||||
$ids = array_merge($ids, static::getArrSubIds($list, intval($vo[$ckey]), $ckey, $pkey));
|
if (intval($vo[$pkey]) > 0 && intval($vo[$pkey]) === intval($value)) {
|
||||||
|
$ids = array_merge($ids, static::getArrSubIds($list, intval($vo[$ckey]), $ckey, $pkey));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return $ids;
|
return $ids;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,44 +1,44 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// +----------------------------------------------------------------------
|
declare(strict_types=1);
|
||||||
// | Library for ThinkAdmin
|
/**
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 版权所有 2014~2025 ThinkAdmin [ thinkadmin.top ]
|
* | Payment Plugin for ThinkAdmin
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 官方网站: https://thinkadmin.top
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 开源协议 ( https://mit-license.org )
|
* | 官方网站: https://thinkadmin.top
|
||||||
// | 免费声明 ( https://thinkadmin.top/disclaimer )
|
* +----------------------------------------------------------------------
|
||||||
// +----------------------------------------------------------------------
|
* | 开源协议 ( https://mit-license.org )
|
||||||
// | gitee 仓库地址 :https://gitee.com/zoujingli/ThinkLibrary
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
// | github 仓库地址 :https://github.com/zoujingli/ThinkLibrary
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
declare (strict_types=1);
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
namespace think\admin\extend;
|
namespace think\admin\extend;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 导出 CSV 文件扩展
|
* 导出 CSV 文件扩展.
|
||||||
* @class ExcelExtend
|
* @class ExcelExtend
|
||||||
* @deprecated 改用 JavaScript
|
* @deprecated 改用 JavaScript
|
||||||
* @package think\admin\extend
|
|
||||||
*/
|
*/
|
||||||
class ExcelExtend
|
class ExcelExtend
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置写入 CSV 文件头部
|
* 设置写入 CSV 文件头部.
|
||||||
* @param string $name 导出文件名称
|
* @param string $name 导出文件名称
|
||||||
* @param array $headers 表格头部(一维数组)
|
* @param array $headers 表格头部(一维数组)
|
||||||
*/
|
*/
|
||||||
public static function header(string $name, array $headers): void
|
public static function header(string $name, array $headers): void
|
||||||
{
|
{
|
||||||
header('Content-Type: application/octet-stream');
|
header('Content-Type: application/octet-stream');
|
||||||
header("Content-Disposition: attachment; filename=" . iconv('utf-8', 'gbk//TRANSLIT', $name));
|
header('Content-Disposition: attachment; filename=' . iconv('utf-8', 'gbk//TRANSLIT', $name));
|
||||||
$handle = fopen('php://output', 'w');
|
$handle = fopen('php://output', 'w');
|
||||||
foreach ($headers as $key => $value) {
|
foreach ($headers as $key => $value) {
|
||||||
$headers[$key] = iconv("utf-8", "gbk//TRANSLIT", $value);
|
$headers[$key] = iconv('utf-8', 'gbk//TRANSLIT', $value);
|
||||||
}
|
}
|
||||||
fputcsv($handle, $headers);
|
fputcsv($handle, $headers);
|
||||||
if (is_resource($handle)) {
|
if (is_resource($handle)) {
|
||||||
@ -47,7 +47,7 @@ class ExcelExtend
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置写入CSV文件内容
|
* 设置写入CSV文件内容.
|
||||||
* @param array $list 数据列表(二维数组)
|
* @param array $list 数据列表(二维数组)
|
||||||
* @param array $rules 数据规则(一维数组)
|
* @param array $rules 数据规则(一维数组)
|
||||||
*/
|
*/
|
||||||
@ -67,15 +67,16 @@ class ExcelExtend
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据数组key查询(可带点规则)
|
* 根据数组key查询(可带点规则).
|
||||||
* @param array $data 数据
|
* @param array $data 数据
|
||||||
* @param string $rule 规则,如: order.order_no
|
* @param string $rule 规则,如: order.order_no
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public static function parseKeyDotValue(array $data, string $rule): string
|
public static function parseKeyDotValue(array $data, string $rule): string
|
||||||
{
|
{
|
||||||
[$temp, $attr] = [$data, explode('.', trim($rule, '.'))];
|
[$temp, $attr] = [$data, explode('.', trim($rule, '.'))];
|
||||||
while ($key = array_shift($attr)) $temp = $temp[$key] ?? $temp;
|
while ($key = array_shift($attr)) {
|
||||||
|
$temp = $temp[$key] ?? $temp;
|
||||||
|
}
|
||||||
return (is_string($temp) || is_numeric($temp)) ? @iconv('utf-8', 'gbk//TRANSLIT', "{$temp}") : '';
|
return (is_string($temp) || is_numeric($temp)) ? @iconv('utf-8', 'gbk//TRANSLIT', "{$temp}") : '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,45 +1,46 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// +----------------------------------------------------------------------
|
declare(strict_types=1);
|
||||||
// | Library for ThinkAdmin
|
/**
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 版权所有 2014~2025 ThinkAdmin [ thinkadmin.top ]
|
* | Payment Plugin for ThinkAdmin
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 官方网站: https://thinkadmin.top
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 开源协议 ( https://mit-license.org )
|
* | 官方网站: https://thinkadmin.top
|
||||||
// | 免费声明 ( https://thinkadmin.top/disclaimer )
|
* +----------------------------------------------------------------------
|
||||||
// +----------------------------------------------------------------------
|
* | 开源协议 ( https://mit-license.org )
|
||||||
// | gitee 仓库地址 :https://gitee.com/zoujingli/ThinkLibrary
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
// | github 仓库地址 :https://github.com/zoujingli/ThinkLibrary
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
declare (strict_types=1);
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
namespace think\admin\extend;
|
namespace think\admin\extend;
|
||||||
|
|
||||||
use think\admin\Exception;
|
use think\admin\Exception;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 网站 ICO 文件生成工具
|
* 网站 ICO 文件生成工具.
|
||||||
* @class FaviconExtend
|
* @class FaviconExtend
|
||||||
* @package think\admin\extend
|
|
||||||
*/
|
*/
|
||||||
class FaviconExtend
|
class FaviconExtend
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* 转换后的 BMP 图像
|
* 转换后的 BMP 图像.
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
private $images = [];
|
private $images = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor - 创建一个新的 ICO 生成器
|
* Constructor - 创建一个新的 ICO 生成器.
|
||||||
* @param ?string $file 源图像文件的路径
|
* @param ?string $file 源图像文件的路径
|
||||||
* @param array $size 图片文件尺寸 [W1,H1]
|
* @param array $size 图片文件尺寸 [W1,H1]
|
||||||
* @throws \think\admin\Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
function __construct(?string $file = null, array $size = [])
|
public function __construct(?string $file = null, array $size = [])
|
||||||
{
|
{
|
||||||
$functions = [
|
$functions = [
|
||||||
'imagesx',
|
'imagesx',
|
||||||
@ -54,8 +55,10 @@ class FaviconExtend
|
|||||||
'imagealphablending',
|
'imagealphablending',
|
||||||
];
|
];
|
||||||
|
|
||||||
foreach ($functions as $function) if (!function_exists($function)) {
|
foreach ($functions as $function) {
|
||||||
throw new Exception(lang('Required %s function not found.', [$function]));
|
if (!function_exists($function)) {
|
||||||
|
throw new Exception(lang('Required %s function not found.', [$function]));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_string($file)) {
|
if (is_string($file)) {
|
||||||
@ -64,11 +67,11 @@ class FaviconExtend
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 添加图像到生成器中
|
* 添加图像到生成器中.
|
||||||
*
|
*
|
||||||
* @param string $file 图像文件路径
|
* @param string $file 图像文件路径
|
||||||
* @param array $size 图像文件尺寸
|
* @param array $size 图像文件尺寸
|
||||||
* @throws \think\admin\Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public function addImage(string $file, array $size = []): FaviconExtend
|
public function addImage(string $file, array $size = []): FaviconExtend
|
||||||
{
|
{
|
||||||
@ -86,7 +89,7 @@ class FaviconExtend
|
|||||||
imagesavealpha($image, true);
|
imagesavealpha($image, true);
|
||||||
|
|
||||||
[$sourceWidth, $sourceHeight] = [imagesx($im), imagesy($im)];
|
[$sourceWidth, $sourceHeight] = [imagesx($im), imagesy($im)];
|
||||||
if (false === imagecopyresampled($image, $im, 0, 0, 0, 0, $width, $height, $sourceWidth, $sourceHeight)) {
|
if (imagecopyresampled($image, $im, 0, 0, 0, 0, $width, $height, $sourceWidth, $sourceHeight) === false) {
|
||||||
throw new Exception(lang('Parse and process picture Failed.'));
|
throw new Exception(lang('Parse and process picture Failed.'));
|
||||||
}
|
}
|
||||||
$this->addImageData($image);
|
$this->addImageData($image);
|
||||||
@ -94,10 +97,9 @@ class FaviconExtend
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 将 ICO 内容写入到文件
|
* 将 ICO 内容写入到文件.
|
||||||
*
|
*
|
||||||
* @param string $file 写入文件路径
|
* @param string $file 写入文件路径
|
||||||
* @return boolean
|
|
||||||
*/
|
*/
|
||||||
public function saveIco(string $file): bool
|
public function saveIco(string $file): bool
|
||||||
{
|
{
|
||||||
@ -107,7 +109,7 @@ class FaviconExtend
|
|||||||
if (false === ($fh = fopen($file, 'w'))) {
|
if (false === ($fh = fopen($file, 'w'))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (false === (fwrite($fh, $data))) {
|
if (fwrite($fh, $data) === false) {
|
||||||
fclose($fh);
|
fclose($fh);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -116,7 +118,7 @@ class FaviconExtend
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 生成并获取 ICO 图像数据
|
* 生成并获取 ICO 图像数据.
|
||||||
*/
|
*/
|
||||||
private function getIcoData()
|
private function getIcoData()
|
||||||
{
|
{
|
||||||
@ -137,14 +139,15 @@ class FaviconExtend
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 将 GD 图像转为 BMP 格式
|
* 将 GD 图像转为 BMP 格式.
|
||||||
|
* @param mixed $im
|
||||||
*/
|
*/
|
||||||
private function addImageData($im)
|
private function addImageData($im)
|
||||||
{
|
{
|
||||||
[$width, $height] = [imagesx($im), imagesy($im)];
|
[$width, $height] = [imagesx($im), imagesy($im)];
|
||||||
[$pixelData, $opacityData, $opacityValue] = [[], [], 0];
|
[$pixelData, $opacityData, $opacityValue] = [[], [], 0];
|
||||||
for ($y = $height - 1; $y >= 0; $y--) {
|
for ($y = $height - 1; $y >= 0; --$y) {
|
||||||
for ($x = 0; $x < $width; $x++) {
|
for ($x = 0; $x < $width; ++$x) {
|
||||||
$color = imagecolorat($im, $x, $y);
|
$color = imagecolorat($im, $x, $y);
|
||||||
$alpha = ($color & 0x7F000000) >> 24;
|
$alpha = ($color & 0x7F000000) >> 24;
|
||||||
$alpha = (1 - ($alpha / 127)) * 255;
|
$alpha = (1 - ($alpha / 127)) * 255;
|
||||||
@ -170,26 +173,30 @@ class FaviconExtend
|
|||||||
$imageHeaderSize = 40;
|
$imageHeaderSize = 40;
|
||||||
$colorMaskSize = $width * $height * 4;
|
$colorMaskSize = $width * $height * 4;
|
||||||
$opacityMaskSize = (ceil($width / 32) * 4) * $height;
|
$opacityMaskSize = (ceil($width / 32) * 4) * $height;
|
||||||
$data = pack('VVVvvVVVVVV', 40, $width, ($height * 2), 1, 32, 0, 0, 0, 0, 0, 0);
|
$data = pack('VVVvvVVVVVV', 40, $width, $height * 2, 1, 32, 0, 0, 0, 0, 0, 0);
|
||||||
foreach ($pixelData as $color) $data .= pack('V', $color);
|
foreach ($pixelData as $color) {
|
||||||
foreach ($opacityData as $opacity) $data .= pack('N', $opacity);
|
$data .= pack('V', $color);
|
||||||
|
}
|
||||||
|
foreach ($opacityData as $opacity) {
|
||||||
|
$data .= pack('N', $opacity);
|
||||||
|
}
|
||||||
|
|
||||||
$this->images[] = [
|
$this->images[] = [
|
||||||
'data' => $data,
|
'data' => $data,
|
||||||
'size' => $imageHeaderSize + $colorMaskSize + $opacityMaskSize,
|
'size' => $imageHeaderSize + $colorMaskSize + $opacityMaskSize,
|
||||||
'width' => $width, 'height' => $height,
|
'width' => $width, 'height' => $height,
|
||||||
'pixel' => 32, 'colors' => 0,
|
'pixel' => 32, 'colors' => 0,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 读取图片资源
|
* 读取图片资源.
|
||||||
* @param string $file 文件路径
|
* @param string $file 文件路径
|
||||||
* @return false|resource|\GdImage
|
* @return false|\GdImage|resource
|
||||||
*/
|
*/
|
||||||
private function loadImageFile(string $file)
|
private function loadImageFile(string $file)
|
||||||
{
|
{
|
||||||
if (false === getimagesize($file)) {
|
if (getimagesize($file) === false) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (false === ($data = file_get_contents($file))) {
|
if (false === ($data = file_get_contents($file))) {
|
||||||
@ -201,4 +208,4 @@ class FaviconExtend
|
|||||||
unset($data);
|
unset($data);
|
||||||
return $image;
|
return $image;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,27 +1,28 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// +----------------------------------------------------------------------
|
declare(strict_types=1);
|
||||||
// | Library for ThinkAdmin
|
/**
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 版权所有 2014~2025 ThinkAdmin [ thinkadmin.top ]
|
* | Payment Plugin for ThinkAdmin
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 官方网站: https://thinkadmin.top
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 开源协议 ( https://mit-license.org )
|
* | 官方网站: https://thinkadmin.top
|
||||||
// | 免费声明 ( https://thinkadmin.top/disclaimer )
|
* +----------------------------------------------------------------------
|
||||||
// +----------------------------------------------------------------------
|
* | 开源协议 ( https://mit-license.org )
|
||||||
// | gitee 仓库地址 :https://gitee.com/zoujingli/ThinkLibrary
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
// | github 仓库地址 :https://github.com/zoujingli/ThinkLibrary
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
declare (strict_types=1);
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
namespace think\admin\extend;
|
namespace think\admin\extend;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* CURL模拟请求扩展
|
* CURL模拟请求扩展.
|
||||||
* @class HttpExtend
|
* @class HttpExtend
|
||||||
* @package think\admin\extend
|
|
||||||
*/
|
*/
|
||||||
class HttpExtend
|
class HttpExtend
|
||||||
{
|
{
|
||||||
@ -30,7 +31,7 @@ class HttpExtend
|
|||||||
* @param string $location HTTP请求地址
|
* @param string $location HTTP请求地址
|
||||||
* @param array|string $data GET请求参数
|
* @param array|string $data GET请求参数
|
||||||
* @param array $options CURL请求参数
|
* @param array $options CURL请求参数
|
||||||
* @return boolean|string
|
* @return bool|string
|
||||||
*/
|
*/
|
||||||
public static function get(string $location, $data = [], array $options = [])
|
public static function get(string $location, $data = [], array $options = [])
|
||||||
{
|
{
|
||||||
@ -43,7 +44,7 @@ class HttpExtend
|
|||||||
* @param string $location HTTP请求地址
|
* @param string $location HTTP请求地址
|
||||||
* @param array|string $data POST请求数据
|
* @param array|string $data POST请求数据
|
||||||
* @param array $options CURL请求参数
|
* @param array $options CURL请求参数
|
||||||
* @return boolean|string
|
* @return bool|string
|
||||||
*/
|
*/
|
||||||
public static function post(string $location, $data = [], array $options = [])
|
public static function post(string $location, $data = [], array $options = [])
|
||||||
{
|
{
|
||||||
@ -58,8 +59,8 @@ class HttpExtend
|
|||||||
* @param array $file 提交文件 [field,name,type,content]
|
* @param array $file 提交文件 [field,name,type,content]
|
||||||
* @param array $header 请求头部信息,默认带 Content-type
|
* @param array $header 请求头部信息,默认带 Content-type
|
||||||
* @param string $method 模拟请求的方式 [GET,POST,PUT]
|
* @param string $method 模拟请求的方式 [GET,POST,PUT]
|
||||||
* @param boolean $returnHeader 是否返回头部信息
|
* @param bool $returnHeader 是否返回头部信息
|
||||||
* @return boolean|string
|
* @return bool|string
|
||||||
*/
|
*/
|
||||||
public static function submit(string $url, array $data = [], array $file = [], array $header = [], string $method = 'POST', bool $returnHeader = true)
|
public static function submit(string $url, array $data = [], array $file = [], array $header = [], string $method = 'POST', bool $returnHeader = true)
|
||||||
{
|
{
|
||||||
@ -67,14 +68,16 @@ class HttpExtend
|
|||||||
foreach ($data as $key => $value) {
|
foreach ($data as $key => $value) {
|
||||||
$line[] = "--{$boundary}";
|
$line[] = "--{$boundary}";
|
||||||
$line[] = "Content-Disposition: form-data; name=\"{$key}\"";
|
$line[] = "Content-Disposition: form-data; name=\"{$key}\"";
|
||||||
$line[] = "";
|
$line[] = '';
|
||||||
$line[] = $value;
|
$line[] = $value;
|
||||||
}
|
}
|
||||||
if (is_array($file) && isset($file['field']) && isset($file['name'])) {
|
if (is_array($file) && isset($file['field'], $file['name'])) {
|
||||||
$line[] = "--{$boundary}";
|
$line[] = "--{$boundary}";
|
||||||
$line[] = "Content-Disposition: form-data; name=\"{$file['field']}\"; filename=\"{$file['name']}\"";
|
$line[] = "Content-Disposition: form-data; name=\"{$file['field']}\"; filename=\"{$file['name']}\"";
|
||||||
if (isset($file['type'])) $line[] = "Content-Type: \"{$file['type']}\"";
|
if (isset($file['type'])) {
|
||||||
$line[] = "";
|
$line[] = "Content-Type: \"{$file['type']}\"";
|
||||||
|
}
|
||||||
|
$line[] = '';
|
||||||
$line[] = $file['content'];
|
$line[] = $file['content'];
|
||||||
}
|
}
|
||||||
$line[] = "--{$boundary}--";
|
$line[] = "--{$boundary}--";
|
||||||
@ -87,7 +90,7 @@ class HttpExtend
|
|||||||
* @param string $method 模拟请求方式
|
* @param string $method 模拟请求方式
|
||||||
* @param string $location 模拟请求地址
|
* @param string $location 模拟请求地址
|
||||||
* @param array $options 请求参数[headers,query,data,cookie,cookie_file,timeout,returnHeader]
|
* @param array $options 请求参数[headers,query,data,cookie,cookie_file,timeout,returnHeader]
|
||||||
* @return boolean|string
|
* @return bool|string
|
||||||
*/
|
*/
|
||||||
public static function request(string $method, string $location, array $options = [])
|
public static function request(string $method, string $location, array $options = [])
|
||||||
{
|
{
|
||||||
@ -139,8 +142,10 @@ class HttpExtend
|
|||||||
// 自定义扩展参数配置,二维数组内每个单元为一个设置语句,格式如下:
|
// 自定义扩展参数配置,二维数组内每个单元为一个设置语句,格式如下:
|
||||||
// $setopt = [ [CURLOPT_URL, $location], [CURLOPT_AUTOREFERER, true], ...];
|
// $setopt = [ [CURLOPT_URL, $location], [CURLOPT_AUTOREFERER, true], ...];
|
||||||
if (isset($options['setopt']) && is_array($options['setopt'])) {
|
if (isset($options['setopt']) && is_array($options['setopt'])) {
|
||||||
foreach ($options['setopt'] as $value) if (is_array($value)) {
|
foreach ($options['setopt'] as $value) {
|
||||||
curl_setopt($curl, ...$value);
|
if (is_array($value)) {
|
||||||
|
curl_setopt($curl, ...$value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
curl_setopt($curl, CURLOPT_URL, $location);
|
curl_setopt($curl, CURLOPT_URL, $location);
|
||||||
@ -155,22 +160,21 @@ class HttpExtend
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取浏览器代理信息
|
* 获取浏览器代理信息.
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
private static function getUserAgent(): string
|
private static function getUserAgent(): string
|
||||||
{
|
{
|
||||||
$agents = [
|
$agents = [
|
||||||
"Mozilla/5.0 (Windows NT 6.1; rv:2.0.1) Gecko/20100101 Firefox/4.0.1",
|
'Mozilla/5.0 (Windows NT 6.1; rv:2.0.1) Gecko/20100101 Firefox/4.0.1',
|
||||||
"Mozilla/5.0 (Windows NT 6.1) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.57 Safari/536.11",
|
'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.57 Safari/536.11',
|
||||||
"Mozilla/5.0 (Windows NT 10.0; WOW64; rv:38.0) Gecko/20100101 Firefox/38.0",
|
'Mozilla/5.0 (Windows NT 10.0; WOW64; rv:38.0) Gecko/20100101 Firefox/38.0',
|
||||||
"Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; .NET4.0C; .NET4.0E; .NET CLR 2.0.50727; .NET CLR 3.0.30729; .NET CLR 3.5.30729; InfoPath.3; rv:11.0) like Gecko",
|
'Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; .NET4.0C; .NET4.0E; .NET CLR 2.0.50727; .NET CLR 3.0.30729; .NET CLR 3.5.30729; InfoPath.3; rv:11.0) like Gecko',
|
||||||
"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50",
|
'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50',
|
||||||
"Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0)",
|
'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0)',
|
||||||
"Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)",
|
'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)',
|
||||||
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:2.0.1) Gecko/20100101 Firefox/4.0.1",
|
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:2.0.1) Gecko/20100101 Firefox/4.0.1',
|
||||||
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_0) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11",
|
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_0) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11',
|
||||||
];
|
];
|
||||||
return $agents[array_rand($agents)];
|
return $agents[array_rand($agents)];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,20 +1,22 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// +----------------------------------------------------------------------
|
declare(strict_types=1);
|
||||||
// | Library for ThinkAdmin
|
/**
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 版权所有 2014~2025 ThinkAdmin [ thinkadmin.top ]
|
* | Payment Plugin for ThinkAdmin
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 官方网站: https://thinkadmin.top
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 开源协议 ( https://mit-license.org )
|
* | 官方网站: https://thinkadmin.top
|
||||||
// | 免费声明 ( https://thinkadmin.top/disclaimer )
|
* +----------------------------------------------------------------------
|
||||||
// +----------------------------------------------------------------------
|
* | 开源协议 ( https://mit-license.org )
|
||||||
// | gitee 仓库地址 :https://gitee.com/zoujingli/ThinkLibrary
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
// | github 仓库地址 :https://github.com/zoujingli/ThinkLibrary
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
declare (strict_types=1);
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
namespace think\admin\extend;
|
namespace think\admin\extend;
|
||||||
|
|
||||||
@ -23,9 +25,8 @@ use think\admin\Storage;
|
|||||||
use think\admin\storage\LocalStorage;
|
use think\admin\storage\LocalStorage;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 拼图拖拽验证器
|
* 拼图拖拽验证器.
|
||||||
* @class ImageVerify
|
* @class ImageVerify
|
||||||
* @package think\admin\extend
|
|
||||||
*/
|
*/
|
||||||
class ImageVerify
|
class ImageVerify
|
||||||
{
|
{
|
||||||
@ -37,14 +38,16 @@ class ImageVerify
|
|||||||
|
|
||||||
// 浮层图宽高
|
// 浮层图宽高
|
||||||
private $picWidth = 100;
|
private $picWidth = 100;
|
||||||
|
|
||||||
private $picHeight = 100;
|
private $picHeight = 100;
|
||||||
|
|
||||||
// 目标图宽高
|
// 目标图宽高
|
||||||
private $dstWidth = 600;
|
private $dstWidth = 600;
|
||||||
|
|
||||||
private $dstHeight = 300;
|
private $dstHeight = 300;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 验证器构造方法
|
* 验证器构造方法.
|
||||||
* @param string $image 原始图片
|
* @param string $image 原始图片
|
||||||
* @param array $options 配置参数
|
* @param array $options 配置参数
|
||||||
*/
|
*/
|
||||||
@ -52,18 +55,20 @@ class ImageVerify
|
|||||||
{
|
{
|
||||||
if (!empty($options)) {
|
if (!empty($options)) {
|
||||||
foreach ($options as $k => $v) {
|
foreach ($options as $k => $v) {
|
||||||
if (isset($this->$k)) $this->$k = $v;
|
if (isset($this->{$k})) {
|
||||||
|
$this->{$k} = $v;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$this->srcImage = $image;
|
$this->srcImage = $image;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 生成图片拼图
|
* 生成图片拼图.
|
||||||
* @param string $image 原始图片
|
* @param string $image 原始图片
|
||||||
* @param integer $time 缓存时间
|
* @param int $time 缓存时间
|
||||||
* @param integer $diff 容错数值
|
* @param int $diff 容错数值
|
||||||
* @param integer $retry 容错次数
|
* @param int $retry 容错次数
|
||||||
* @return array [code, bgimg, water]
|
* @return array [code, bgimg, water]
|
||||||
*/
|
*/
|
||||||
public static function render(string $image, int $time = 1800, int $diff = 10, int $retry = 3): array
|
public static function render(string $image, int $time = 1800, int $diff = 10, int $retry = 3): array
|
||||||
@ -76,16 +81,18 @@ class ImageVerify
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 在线验证是否通过
|
* 在线验证是否通过.
|
||||||
* @param string $code 验证码编码
|
* @param string $code 验证码编码
|
||||||
* @param string $value 待验证数值
|
* @param string $value 待验证数值
|
||||||
* @param boolean $clear 验证成功清理
|
* @param bool $clear 验证成功清理
|
||||||
* @return integer [ -1:需要刷新, 0:验证失败, 1:验证成功 ]
|
* @return int [ -1:需要刷新, 0:验证失败, 1:验证成功 ]
|
||||||
*/
|
*/
|
||||||
public static function verify(string $code, string $value, bool $clear = false): int
|
public static function verify(string $code, string $value, bool $clear = false): int
|
||||||
{
|
{
|
||||||
$cache = Library::$sapp->cache->get($code);
|
$cache = Library::$sapp->cache->get($code);
|
||||||
if (empty($cache['range']) || empty($cache['retry'])) return -1;
|
if (empty($cache['range']) || empty($cache['retry'])) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
if ($cache['range'][0] <= $value && $value <= $cache['range'][1]) {
|
if ($cache['range'][0] <= $value && $value <= $cache['range'][1]) {
|
||||||
$clear && Library::$sapp->cache->delete($code);
|
$clear && Library::$sapp->cache->delete($code);
|
||||||
return 1;
|
return 1;
|
||||||
@ -103,10 +110,10 @@ class ImageVerify
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 剧中裁剪图片
|
* 剧中裁剪图片.
|
||||||
* @param string $image 图片资源
|
* @param string $image 图片资源
|
||||||
* @param integer $width 目标宽度
|
* @param int $width 目标宽度
|
||||||
* @param integer $height 目标高度
|
* @param int $height 目标高度
|
||||||
* @return \GdImage|resource
|
* @return \GdImage|resource
|
||||||
*/
|
*/
|
||||||
public static function cover(string $image, int $width, int $height)
|
public static function cover(string $image, int $width, int $height)
|
||||||
@ -114,7 +121,9 @@ class ImageVerify
|
|||||||
// 读取缓存返回图片资源
|
// 读取缓存返回图片资源
|
||||||
$local = LocalStorage::instance();
|
$local = LocalStorage::instance();
|
||||||
$name = Storage::name(join('#', func_get_args()), 'png', 'cache');
|
$name = Storage::name(join('#', func_get_args()), 'png', 'cache');
|
||||||
if ($local->has($name, true)) return imageCreateFromString($local->get($name, true));
|
if ($local->has($name, true)) {
|
||||||
|
return imagecreatefromstring($local->get($name, true));
|
||||||
|
}
|
||||||
// 计算图片尺寸裁剪坐标
|
// 计算图片尺寸裁剪坐标
|
||||||
[$w, $h] = getimagesize($image);
|
[$w, $h] = getimagesize($image);
|
||||||
if ($w > $h) {
|
if ($w > $h) {
|
||||||
@ -124,8 +133,8 @@ class ImageVerify
|
|||||||
} else {
|
} else {
|
||||||
[$_sw, $_sh, $_sx, $_sy] = [$w, $h, 0, 0];
|
[$_sw, $_sh, $_sx, $_sy] = [$w, $h, 0, 0];
|
||||||
}
|
}
|
||||||
$newim = imageCreateTrueColor($width, $height);
|
$newim = imagecreatetruecolor($width, $height);
|
||||||
$srcim = imageCreateFromString(file_get_contents($image));
|
$srcim = imagecreatefromstring(file_get_contents($image));
|
||||||
imagecopyresampled($newim, $srcim, 0, 0, $_sx, $_sy, $width, $height, $_sw, $_sh);
|
imagecopyresampled($newim, $srcim, 0, 0, $_sx, $_sy, $width, $height, $_sw, $_sh);
|
||||||
imagedestroy($srcim);
|
imagedestroy($srcim);
|
||||||
// 缓存图片内容
|
// 缓存图片内容
|
||||||
@ -137,7 +146,7 @@ class ImageVerify
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建背景图和浮层图、浮层图X坐标
|
* 创建背景图和浮层图、浮层图X坐标.
|
||||||
* @return array [point, bgimg, water]
|
* @return array [point, bgimg, water]
|
||||||
*/
|
*/
|
||||||
public function create(): array
|
public function create(): array
|
||||||
@ -146,9 +155,9 @@ class ImageVerify
|
|||||||
$dstim = $this->cover($this->srcImage, $this->dstWidth, $this->dstHeight);
|
$dstim = $this->cover($this->srcImage, $this->dstWidth, $this->dstHeight);
|
||||||
|
|
||||||
// 生成透明底浮层图画布
|
// 生成透明底浮层图画布
|
||||||
$watim = imageCreateTrueColor($this->picWidth, $this->dstHeight);
|
$watim = imagecreatetruecolor($this->picWidth, $this->dstHeight);
|
||||||
imageSaveAlpha($watim, true) && imageAlphaBlending($watim, false);
|
imagesavealpha($watim, true) && imagealphablending($watim, false);
|
||||||
imageFill($watim, 0, 0, imageColorAllocateAlpha($watim, 255, 255, 255, 127));
|
imagefill($watim, 0, 0, imagecolorallocatealpha($watim, 255, 255, 255, 127));
|
||||||
|
|
||||||
// 随机位置
|
// 随机位置
|
||||||
$srcX1 = mt_rand(150, $this->dstWidth - $this->picWidth); // 水印位于大图X坐标
|
$srcX1 = mt_rand(150, $this->dstWidth - $this->picWidth); // 水印位于大图X坐标
|
||||||
@ -162,48 +171,48 @@ class ImageVerify
|
|||||||
|
|
||||||
// 水印边框颜色
|
// 水印边框颜色
|
||||||
$broders = [
|
$broders = [
|
||||||
imageColorAllocateAlpha($dstim, 250, 100, 0, 50),
|
imagecolorallocatealpha($dstim, 250, 100, 0, 50),
|
||||||
imageColorAllocateAlpha($dstim, 250, 0, 100, 50),
|
imagecolorallocatealpha($dstim, 250, 0, 100, 50),
|
||||||
imageColorAllocateAlpha($dstim, 100, 0, 250, 50),
|
imagecolorallocatealpha($dstim, 100, 0, 250, 50),
|
||||||
imageColorAllocateAlpha($dstim, 100, 250, 0, 50),
|
imagecolorallocatealpha($dstim, 100, 250, 0, 50),
|
||||||
imageColorAllocateAlpha($dstim, 0, 250, 100, 50),
|
imagecolorallocatealpha($dstim, 0, 250, 100, 50),
|
||||||
];
|
];
|
||||||
shuffle($broders);
|
shuffle($broders);
|
||||||
$c1 = array_pop($broders);
|
$c1 = array_pop($broders);
|
||||||
$c2 = array_pop($broders);
|
$c2 = array_pop($broders);
|
||||||
$gray = imageColorAllocateAlpha($dstim, 0, 0, 0, 80);
|
$gray = imagecolorallocatealpha($dstim, 0, 0, 0, 80);
|
||||||
$blue = imageColorAllocateAlpha($watim, 0, 100, 250, 50);
|
$blue = imagecolorallocatealpha($watim, 0, 100, 250, 50);
|
||||||
|
|
||||||
// 取原图像素颜色,生成浮层图
|
// 取原图像素颜色,生成浮层图
|
||||||
$waters = $this->withWaterPoint();
|
$waters = $this->withWaterPoint();
|
||||||
for ($i = 0; $i < $this->picHeight; $i++) {
|
for ($i = 0; $i < $this->picHeight; ++$i) {
|
||||||
for ($j = 0; $j < $this->picWidth; $j++) {
|
for ($j = 0; $j < $this->picWidth; ++$j) {
|
||||||
if ($waters[$i][$j] === 1) {
|
if ($waters[$i][$j] === 1) {
|
||||||
if (
|
if (
|
||||||
empty($waters[$i - 1][$j - 1]) || empty($waters[$i - 2][$j - 2]) ||
|
empty($waters[$i - 1][$j - 1]) || empty($waters[$i - 2][$j - 2])
|
||||||
empty($waters[$i + 1][$j + 1]) || empty($waters[$i + 2][$j + 2])
|
|| empty($waters[$i + 1][$j + 1]) || empty($waters[$i + 2][$j + 2])
|
||||||
) {
|
) {
|
||||||
imagesetpixel($watim, $j, $srcY1 + $i, $blue);
|
imagesetpixel($watim, $j, $srcY1 + $i, $blue);
|
||||||
} else {
|
} else {
|
||||||
imagesetpixel($watim, $j, $srcY1 + $i, ImageColorAt($dstim, $srcX1 + $j, $srcY1 + $i));
|
imagesetpixel($watim, $j, $srcY1 + $i, imagecolorat($dstim, $srcX1 + $j, $srcY1 + $i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 在原图挖坑,打上灰色水印
|
// 在原图挖坑,打上灰色水印
|
||||||
for ($i = 0; $i < $this->picHeight; $i++) {
|
for ($i = 0; $i < $this->picHeight; ++$i) {
|
||||||
for ($j = 0; $j < $this->picWidth; $j++) {
|
for ($j = 0; $j < $this->picWidth; ++$j) {
|
||||||
if ($waters[$i][$j] === 1) {
|
if ($waters[$i][$j] === 1) {
|
||||||
if (
|
if (
|
||||||
empty($waters[$i - 1][$j - 1]) ||
|
empty($waters[$i - 1][$j - 1])
|
||||||
empty($waters[$i - 2][$j - 2]) ||
|
|| empty($waters[$i - 2][$j - 2])
|
||||||
empty($waters[$i + 1][$j + 1]) ||
|
|| empty($waters[$i + 1][$j + 1])
|
||||||
empty($waters[$i + 2][$j + 2])
|
|| empty($waters[$i + 2][$j + 2])
|
||||||
) {
|
) {
|
||||||
imagesetpixel($dstim, $srcX1 + $j, $srcY1 + $i, $c1);
|
imagesetpixel($dstim, $srcX1 + $j, $srcY1 + $i, $c1);
|
||||||
// 去除第二个干扰水印
|
// 去除第二个干扰水印
|
||||||
// imagesetpixel($dstim, $srcX2 + $j, $srcY2 + $i, $c2);
|
// imagesetpixel($dstim, $srcX2 + $j, $srcY2 + $i, $c2);
|
||||||
} else {
|
} else {
|
||||||
imagesetpixel($dstim, $srcX1 + $j, $srcY1 + $i, $gray);
|
imagesetpixel($dstim, $srcX1 + $j, $srcY1 + $i, $gray);
|
||||||
// 去除第二个干扰水印
|
// 去除第二个干扰水印
|
||||||
@ -220,13 +229,12 @@ class ImageVerify
|
|||||||
return [
|
return [
|
||||||
'point' => $srcX1,
|
'point' => $srcX1,
|
||||||
'bgimg' => 'data:image/png;base64,' . base64_encode($bgimg),
|
'bgimg' => 'data:image/png;base64,' . base64_encode($bgimg),
|
||||||
'water' => 'data:image/png;base64,' . base64_encode($water)
|
'water' => 'data:image/png;base64,' . base64_encode($water),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 计算水印矩阵坐标
|
* 计算水印矩阵坐标.
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
private function withWaterPoint(): array
|
private function withWaterPoint(): array
|
||||||
{
|
{
|
||||||
@ -241,10 +249,10 @@ class ImageVerify
|
|||||||
|
|
||||||
// 第二个圆中心点
|
// 第二个圆中心点
|
||||||
$c_2_x = $this->picHeight - $this->r;
|
$c_2_x = $this->picHeight - $this->r;
|
||||||
$c_2_y = $lw + ($this->picHeight - ($lw) * 2) / 2;
|
$c_2_y = $lw + ($this->picHeight - $lw * 2) / 2;
|
||||||
|
|
||||||
for ($i = 0; $i < $this->picHeight; $i++) {
|
for ($i = 0; $i < $this->picHeight; ++$i) {
|
||||||
for ($j = 0; $j < $this->picWidth; $j++) {
|
for ($j = 0; $j < $this->picWidth; ++$j) {
|
||||||
// 根据公式(x-a)² + (y-b)² = r² 算出像素是否在圆内
|
// 根据公式(x-a)² + (y-b)² = r² 算出像素是否在圆内
|
||||||
$d1 = pow($j - $c_1_x, 2) + pow($i - $c_1_y, 2);
|
$d1 = pow($j - $c_1_x, 2) + pow($i - $c_1_y, 2);
|
||||||
$d2 = pow($j - $c_2_x, 2) + pow($i - $c_2_y, 2);
|
$d2 = pow($j - $c_2_x, 2) + pow($i - $c_2_y, 2);
|
||||||
@ -258,4 +266,4 @@ class ImageVerify
|
|||||||
|
|
||||||
return $waters;
|
return $waters;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,35 +1,36 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// +----------------------------------------------------------------------
|
declare(strict_types=1);
|
||||||
// | Library for ThinkAdmin
|
/**
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 版权所有 2014~2025 ThinkAdmin [ thinkadmin.top ]
|
* | Payment Plugin for ThinkAdmin
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 官方网站: https://thinkadmin.top
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 开源协议 ( https://mit-license.org )
|
* | 官方网站: https://thinkadmin.top
|
||||||
// | 免费声明 ( https://thinkadmin.top/disclaimer )
|
* +----------------------------------------------------------------------
|
||||||
// +----------------------------------------------------------------------
|
* | 开源协议 ( https://mit-license.org )
|
||||||
// | gitee 仓库地址 :https://gitee.com/zoujingli/ThinkLibrary
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
// | github 仓库地址 :https://github.com/zoujingli/ThinkLibrary
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
declare (strict_types=1);
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
namespace think\admin\extend;
|
namespace think\admin\extend;
|
||||||
|
|
||||||
use think\admin\Exception;
|
use think\admin\Exception;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* JsonRpc 客户端
|
* JsonRpc 客户端.
|
||||||
* @class JsonRpcClient
|
* @class JsonRpcClient
|
||||||
* @package think\admin\extend
|
|
||||||
*/
|
*/
|
||||||
class JsonRpcClient
|
class JsonRpcClient
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* 请求ID
|
* 请求ID.
|
||||||
* @var integer
|
* @var int
|
||||||
*/
|
*/
|
||||||
private $id;
|
private $id;
|
||||||
|
|
||||||
@ -40,15 +41,13 @@ class JsonRpcClient
|
|||||||
private $proxy;
|
private $proxy;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 请求头部参数
|
* 请求头部参数.
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
private $header;
|
private $header;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* JsonRpcClient constructor.
|
* JsonRpcClient constructor.
|
||||||
* @param string $proxy
|
|
||||||
* @param array $header
|
|
||||||
*/
|
*/
|
||||||
public function __construct(string $proxy, array $header = [])
|
public function __construct(string $proxy, array $header = [])
|
||||||
{
|
{
|
||||||
@ -59,21 +58,19 @@ class JsonRpcClient
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 执行 JsonRpc 请求
|
* 执行 JsonRpc 请求
|
||||||
* @param string $method
|
|
||||||
* @param array $params
|
|
||||||
* @return mixed
|
* @return mixed
|
||||||
* @throws \think\admin\Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public function __call(string $method, array $params = [])
|
public function __call(string $method, array $params = [])
|
||||||
{
|
{
|
||||||
$options = [
|
$options = [
|
||||||
'ssl' => [
|
'ssl' => [
|
||||||
'verify_peer' => false,
|
'verify_peer' => false,
|
||||||
'verify_peer_name' => false,
|
'verify_peer_name' => false,
|
||||||
],
|
],
|
||||||
'http' => [
|
'http' => [
|
||||||
'method' => 'POST', "timeout" => 60,
|
'method' => 'POST', 'timeout' => 60,
|
||||||
'header' => join("\r\n", array_merge(['Content-Type:application/json'], $this->header, ['User-Agent:think-admin-jsonrpc', ''])),
|
'header' => join("\r\n", array_merge(['Content-Type:application/json'], $this->header, ['User-Agent:think-admin-jsonrpc', ''])),
|
||||||
'content' => json_encode(['jsonrpc' => '2.0', 'method' => $method, 'params' => $params, 'id' => $this->id], JSON_UNESCAPED_UNICODE),
|
'content' => json_encode(['jsonrpc' => '2.0', 'method' => $method, 'params' => $params, 'id' => $this->id], JSON_UNESCAPED_UNICODE),
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
@ -81,10 +78,12 @@ class JsonRpcClient
|
|||||||
// Performs the HTTP POST
|
// Performs the HTTP POST
|
||||||
if ($fp = fopen($this->proxy, 'r', false, stream_context_create($options))) {
|
if ($fp = fopen($this->proxy, 'r', false, stream_context_create($options))) {
|
||||||
$response = '';
|
$response = '';
|
||||||
while ($line = fgets($fp)) $response .= trim($line) . "\n";
|
while ($line = fgets($fp)) {
|
||||||
|
$response .= trim($line) . "\n";
|
||||||
|
}
|
||||||
[, $response] = [fclose($fp), json_decode($response, true)];
|
[, $response] = [fclose($fp), json_decode($response, true)];
|
||||||
} else {
|
} else {
|
||||||
throw new Exception(lang("Unable connect: %s", [$this->proxy]));
|
throw new Exception(lang('Unable connect: %s', [$this->proxy]));
|
||||||
}
|
}
|
||||||
} catch (Exception $exception) {
|
} catch (Exception $exception) {
|
||||||
throw $exception;
|
throw $exception;
|
||||||
@ -92,14 +91,16 @@ class JsonRpcClient
|
|||||||
throw new Exception($exception->getMessage());
|
throw new Exception($exception->getMessage());
|
||||||
}
|
}
|
||||||
// Compatible with normal
|
// Compatible with normal
|
||||||
if (isset($response['code']) && isset($response['info'])) {
|
if (isset($response['code'], $response['info'])) {
|
||||||
throw new Exception($response['info'], intval($response['code']), $response['data'] ?? []);
|
throw new Exception($response['info'], intval($response['code']), $response['data'] ?? []);
|
||||||
}
|
}
|
||||||
// Final checks and return
|
// Final checks and return
|
||||||
if (empty($response['id']) || $response['id'] != $this->id) {
|
if (empty($response['id']) || $response['id'] != $this->id) {
|
||||||
throw new Exception(lang("Error flag ( Request tag: %s, Response tag: %s )", [$this->id, $response['id'] ?? '-']), 0, $response);
|
throw new Exception(lang('Error flag ( Request tag: %s, Response tag: %s )', [$this->id, $response['id'] ?? '-']), 0, $response);
|
||||||
|
}
|
||||||
|
if (is_null($response['error'])) {
|
||||||
|
return $response['result'];
|
||||||
}
|
}
|
||||||
if (is_null($response['error'])) return $response['result'];
|
|
||||||
throw new Exception($response['error']['message'], intval($response['error']['code']), $response['result'] ?? []);
|
throw new Exception($response['error']['message'], intval($response['error']['code']), $response['result'] ?? []);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,20 +1,22 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// +----------------------------------------------------------------------
|
declare(strict_types=1);
|
||||||
// | Library for ThinkAdmin
|
/**
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 版权所有 2014~2025 ThinkAdmin [ thinkadmin.top ]
|
* | Payment Plugin for ThinkAdmin
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 官方网站: https://thinkadmin.top
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 开源协议 ( https://mit-license.org )
|
* | 官方网站: https://thinkadmin.top
|
||||||
// | 免费声明 ( https://thinkadmin.top/disclaimer )
|
* +----------------------------------------------------------------------
|
||||||
// +----------------------------------------------------------------------
|
* | 开源协议 ( https://mit-license.org )
|
||||||
// | gitee 仓库地址 :https://gitee.com/zoujingli/ThinkLibrary
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
// | github 仓库地址 :https://github.com/zoujingli/ThinkLibrary
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
declare (strict_types=1);
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
namespace think\admin\extend;
|
namespace think\admin\extend;
|
||||||
|
|
||||||
@ -23,9 +25,8 @@ use think\Container;
|
|||||||
use think\exception\HttpResponseException;
|
use think\exception\HttpResponseException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* JsonRpc 服务端
|
* JsonRpc 服务端.
|
||||||
* @class JsonRpcServer
|
* @class JsonRpcServer
|
||||||
* @package think\admin\extend
|
|
||||||
*/
|
*/
|
||||||
class JsonRpcServer
|
class JsonRpcServer
|
||||||
{
|
{
|
||||||
@ -37,7 +38,6 @@ class JsonRpcServer
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* JsonRpcServer constructor.
|
* JsonRpcServer constructor.
|
||||||
* @param App $app
|
|
||||||
*/
|
*/
|
||||||
public function __construct(App $app)
|
public function __construct(App $app)
|
||||||
{
|
{
|
||||||
@ -72,25 +72,28 @@ class JsonRpcServer
|
|||||||
} elseif (!isset($request['id']) || !isset($request['method']) || !isset($request['params'])) {
|
} elseif (!isset($request['id']) || !isset($request['method']) || !isset($request['params'])) {
|
||||||
$error = ['code' => '-32600', 'message' => lang('Invalid request.'), 'meaning' => lang('Invalid JSON parameter.')];
|
$error = ['code' => '-32600', 'message' => lang('Invalid request.'), 'meaning' => lang('Invalid JSON parameter.')];
|
||||||
$response = ['jsonrpc' => '2.0', 'id' => $request['id'] ?? '0', 'result' => null, 'error' => $error];
|
$response = ['jsonrpc' => '2.0', 'id' => $request['id'] ?? '0', 'result' => null, 'error' => $error];
|
||||||
} else try {
|
} else {
|
||||||
if ($object instanceof \Exception) {
|
try {
|
||||||
throw $object;
|
if ($object instanceof \Exception) {
|
||||||
} elseif (strtolower($request['method']) === '_get_class_name_') {
|
throw $object;
|
||||||
$response = ['jsonrpc' => '2.0', 'id' => $request['id'], 'result' => get_class($object), 'error' => null];
|
}
|
||||||
} elseif (method_exists($object, $request['method'])) {
|
if (strtolower($request['method']) === '_get_class_name_') {
|
||||||
$result = call_user_func_array([$object, $request['method']], $request['params']);
|
$response = ['jsonrpc' => '2.0', 'id' => $request['id'], 'result' => get_class($object), 'error' => null];
|
||||||
$response = ['jsonrpc' => '2.0', 'id' => $request['id'], 'result' => $result, 'error' => null];
|
} elseif (method_exists($object, $request['method'])) {
|
||||||
} else {
|
$result = call_user_func_array([$object, $request['method']], $request['params']);
|
||||||
$info = lang('method not exists: %s::%s', [class_basename($object), $request['method']]);
|
$response = ['jsonrpc' => '2.0', 'id' => $request['id'], 'result' => $result, 'error' => null];
|
||||||
$error = ['code' => '-32601', 'message' => $info, 'meaning' => lang('The method does not exist or is invalid.')];
|
} else {
|
||||||
|
$info = lang('method not exists: %s::%s', [class_basename($object), $request['method']]);
|
||||||
|
$error = ['code' => '-32601', 'message' => $info, 'meaning' => lang('The method does not exist or is invalid.')];
|
||||||
|
$response = ['jsonrpc' => '2.0', 'id' => $request['id'], 'result' => null, 'error' => $error];
|
||||||
|
}
|
||||||
|
} catch (\think\admin\Exception $exception) {
|
||||||
|
$error = ['code' => $exception->getCode(), 'message' => lang($exception->getMessage()), 'meaning' => lang('Business Exception.')];
|
||||||
|
$response = ['jsonrpc' => '2.0', 'id' => $request['id'], 'result' => $exception->getData(), 'error' => $error];
|
||||||
|
} catch (\Exception $exception) {
|
||||||
|
$error = ['code' => $exception->getCode(), 'message' => lang($exception->getMessage()), 'meaning' => lang('System Exception.')];
|
||||||
$response = ['jsonrpc' => '2.0', 'id' => $request['id'], 'result' => null, 'error' => $error];
|
$response = ['jsonrpc' => '2.0', 'id' => $request['id'], 'result' => null, 'error' => $error];
|
||||||
}
|
}
|
||||||
} catch (\think\admin\Exception $exception) {
|
|
||||||
$error = ['code' => $exception->getCode(), 'message' => lang($exception->getMessage()), 'meaning' => lang('Business Exception.')];
|
|
||||||
$response = ['jsonrpc' => '2.0', 'id' => $request['id'], 'result' => $exception->getData(), 'error' => $error];
|
|
||||||
} catch (\Exception $exception) {
|
|
||||||
$error = ['code' => $exception->getCode(), 'message' => lang($exception->getMessage()), 'meaning' => lang('System Exception.')];
|
|
||||||
$response = ['jsonrpc' => '2.0', 'id' => $request['id'], 'result' => null, 'error' => $error];
|
|
||||||
}
|
}
|
||||||
// Output the response
|
// Output the response
|
||||||
throw new HttpResponseException(json($response));
|
throw new HttpResponseException(json($response));
|
||||||
@ -98,7 +101,7 @@ class JsonRpcServer
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 打印输出对象方法
|
* 打印输出对象方法.
|
||||||
* @param mixed $object
|
* @param mixed $object
|
||||||
*/
|
*/
|
||||||
protected function printMethod($object)
|
protected function printMethod($object)
|
||||||
@ -107,11 +110,15 @@ class JsonRpcServer
|
|||||||
$object = new \ReflectionClass($object);
|
$object = new \ReflectionClass($object);
|
||||||
echo "<h2>{$object->getName()}</h2><hr>";
|
echo "<h2>{$object->getName()}</h2><hr>";
|
||||||
foreach ($object->getMethods(\ReflectionMethod::IS_PUBLIC) as $method) {
|
foreach ($object->getMethods(\ReflectionMethod::IS_PUBLIC) as $method) {
|
||||||
if (stripos($method->getName(), '_') === 0) continue;
|
if (stripos($method->getName(), '_') === 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
$params = [];
|
$params = [];
|
||||||
foreach ($method->getParameters() as $parameter) {
|
foreach ($method->getParameters() as $parameter) {
|
||||||
$type = $parameter->getType();
|
$type = $parameter->getType();
|
||||||
if ($type instanceof \ReflectionType) $type = $type->getName();
|
if ($type instanceof \ReflectionType) {
|
||||||
|
$type = $type->getName();
|
||||||
|
}
|
||||||
$params[] = ($type ? "{$type} $" : '$') . $parameter->getName();
|
$params[] = ($type ? "{$type} $" : '$') . $parameter->getName();
|
||||||
}
|
}
|
||||||
$params = count($params) > 0 ? join(', ', $params) : '';
|
$params = count($params) > 0 ? join(', ', $params) : '';
|
||||||
@ -122,4 +129,4 @@ class JsonRpcServer
|
|||||||
echo "<h3>[{$exception->getCode()}] {$exception->getMessage()}</h3>";
|
echo "<h3>[{$exception->getCode()}] {$exception->getMessage()}</h3>";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,20 +1,22 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// +----------------------------------------------------------------------
|
declare(strict_types=1);
|
||||||
// | Library for ThinkAdmin
|
/**
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 版权所有 2014~2025 ThinkAdmin [ thinkadmin.top ]
|
* | Payment Plugin for ThinkAdmin
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 官方网站: https://thinkadmin.top
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 开源协议 ( https://mit-license.org )
|
* | 官方网站: https://thinkadmin.top
|
||||||
// | 免费声明 ( https://thinkadmin.top/disclaimer )
|
* +----------------------------------------------------------------------
|
||||||
// +----------------------------------------------------------------------
|
* | 开源协议 ( https://mit-license.org )
|
||||||
// | gitee 仓库地址 :https://gitee.com/zoujingli/ThinkLibrary
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
// | github 仓库地址 :https://github.com/zoujingli/ThinkLibrary
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
declare (strict_types=1);
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
namespace think\admin\extend;
|
namespace think\admin\extend;
|
||||||
|
|
||||||
@ -23,9 +25,8 @@ use think\admin\Exception;
|
|||||||
use think\admin\Library;
|
use think\admin\Library;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 接口 JWT 接口扩展
|
* 接口 JWT 接口扩展.
|
||||||
* @class JwtExtend
|
* @class JwtExtend
|
||||||
* @package think\admin\extend
|
|
||||||
* @method static bool isRejwt() 是否输出令牌
|
* @method static bool isRejwt() 是否输出令牌
|
||||||
* @method static array getInData() 获取输入数据
|
* @method static array getInData() 获取输入数据
|
||||||
*/
|
*/
|
||||||
@ -38,58 +39,84 @@ class JwtExtend
|
|||||||
private const signTypes = [
|
private const signTypes = [
|
||||||
'HS256' => 'sha256',
|
'HS256' => 'sha256',
|
||||||
'HS384' => 'sha384',
|
'HS384' => 'sha384',
|
||||||
'HS512' => 'sha512'
|
'HS512' => 'sha512',
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 是否返回令牌
|
* 获取原会话标签.
|
||||||
* @var boolean
|
|
||||||
*/
|
|
||||||
private static $rejwt = false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 当前请求数据
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
private static $input = [];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取原会话标签
|
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
public static $sessionId = '';
|
public static $sessionId = '';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 生成 jwt token
|
* 是否返回令牌.
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
private static $rejwt = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 当前请求数据.
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
private static $input = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 兼容历史方法.
|
||||||
|
* @return array|string
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public static function __callStatic(string $method, array $arguments)
|
||||||
|
{
|
||||||
|
switch ($method) {
|
||||||
|
case 'isRejwt': // 是否返回令牌
|
||||||
|
return self::$rejwt;
|
||||||
|
case 'getInData': // 获取请求数据
|
||||||
|
return self::$input;
|
||||||
|
case 'getToken': // 生成接口令牌
|
||||||
|
return self::token(...$arguments);
|
||||||
|
case 'verifyToken': // 验证接口令牌
|
||||||
|
return self::verify(...$arguments);
|
||||||
|
default:
|
||||||
|
throw new Exception("method not exists: JwtExtend::{$method}()");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成 jwt token.
|
||||||
* @param array $data jwt 载荷 格式如下非必须
|
* @param array $data jwt 载荷 格式如下非必须
|
||||||
* {
|
* {
|
||||||
* "iss": "http://example.org", // 签发者(Issuer),JWT的签发者
|
* "iss": "http://example.org", // 签发者(Issuer),JWT的签发者
|
||||||
* "sub": "1234567890", // 主题(Subject),JWT所面向的用户
|
* "sub": "1234567890", // 主题(Subject),JWT所面向的用户
|
||||||
* "aud": "http://example.com", // 受众(Audience),接收JWT的一方
|
* "aud": "http://example.com", // 受众(Audience),接收JWT的一方
|
||||||
* "exp": 1625174400, // 过期时间(Expiration time),JWT的过期时间戳
|
* "exp": 1625174400, // 过期时间(Expiration time),JWT的过期时间戳
|
||||||
* "iat": 1625138400, // 签发时间(Issued at),JWT的签发时间戳
|
* "iat": 1625138400, // 签发时间(Issued at),JWT的签发时间戳
|
||||||
* "nbf": 1625138400, // 生效时间(Not Before),JWT的生效时间戳
|
* "nbf": 1625138400, // 生效时间(Not Before),JWT的生效时间戳
|
||||||
* "...": ... // 其他扩展内容
|
* "...": ... // 其他扩展内容
|
||||||
* }
|
* }
|
||||||
* @param ?string $jwtkey 签名密钥
|
* @param ?string $jwtkey 签名密钥
|
||||||
* @param ?boolean $rejwt 输出令牌
|
* @param ?bool $rejwt 输出令牌
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public static function token(array $data = [], ?string $jwtkey = null, ?bool $rejwt = null): string
|
public static function token(array $data = [], ?string $jwtkey = null, ?bool $rejwt = null): string
|
||||||
{
|
{
|
||||||
$jwtkey = self::jwtkey($jwtkey);
|
$jwtkey = self::jwtkey($jwtkey);
|
||||||
if (is_bool($rejwt)) self::$rejwt = $rejwt;
|
if (is_bool($rejwt)) {
|
||||||
|
self::$rejwt = $rejwt;
|
||||||
|
}
|
||||||
|
|
||||||
// JWT 载荷数据组装
|
// JWT 载荷数据组装
|
||||||
[$fields, $payload] = [['iss', 'sub', 'aud', 'exp', 'iat', 'nbf'], ['iat' => time()]];
|
[$fields, $payload] = [['iss', 'sub', 'aud', 'exp', 'iat', 'nbf'], ['iat' => time()]];
|
||||||
foreach ($data as $k => $v) if (in_array($k, $fields)) {
|
foreach ($data as $k => $v) {
|
||||||
$payload[$k] = $v;
|
if (in_array($k, $fields)) {
|
||||||
unset($data[$k]);
|
$payload[$k] = $v;
|
||||||
|
unset($data[$k]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 自定义需要的数据
|
// 自定义需要的数据
|
||||||
$data['.ssid'] = self::withSess();
|
$data['.ssid'] = self::withSess();
|
||||||
if (empty($data['.ssid'])) unset($data['.ssid']);
|
if (empty($data['.ssid'])) {
|
||||||
|
unset($data['.ssid']);
|
||||||
|
}
|
||||||
$payload['enc'] = CodeExtend::encrypt(json_encode($data, JSON_UNESCAPED_UNICODE), $jwtkey);
|
$payload['enc'] = CodeExtend::encrypt(json_encode($data, JSON_UNESCAPED_UNICODE), $jwtkey);
|
||||||
|
|
||||||
// 组装 JWT 内容格式
|
// 组装 JWT 内容格式
|
||||||
@ -99,22 +126,25 @@ class JwtExtend
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 验证 token 是否有效, 默认验证 exp,nbf,iat 时间
|
* 验证 token 是否有效, 默认验证 exp,nbf,iat 时间.
|
||||||
* @param string $token 加密数据
|
* @param string $token 加密数据
|
||||||
* @param ?string $jwtkey 签名密钥
|
* @param ?string $jwtkey 签名密钥
|
||||||
* @return array
|
* @throws Exception
|
||||||
* @throws \think\admin\Exception
|
|
||||||
*/
|
*/
|
||||||
public static function verify(string $token, ?string $jwtkey = null): array
|
public static function verify(string $token, ?string $jwtkey = null): array
|
||||||
{
|
{
|
||||||
$tokens = explode('.', $token);
|
$tokens = explode('.', $token);
|
||||||
if (count($tokens) != 3) throw new Exception('数据解密失败!', 0, []);
|
if (count($tokens) != 3) {
|
||||||
|
throw new Exception('数据解密失败!', 0, []);
|
||||||
|
}
|
||||||
|
|
||||||
[$base64header, $base64payload, $signature] = $tokens;
|
[$base64header, $base64payload, $signature] = $tokens;
|
||||||
|
|
||||||
// 加密算法
|
// 加密算法
|
||||||
$header = json_decode(CodeExtend::deSafe64($base64header), true);
|
$header = json_decode(CodeExtend::deSafe64($base64header), true);
|
||||||
if (empty($header['alg'])) throw new Exception('数据解密失败!', 0, []);
|
if (empty($header['alg'])) {
|
||||||
|
throw new Exception('数据解密失败!', 0, []);
|
||||||
|
}
|
||||||
|
|
||||||
// 签名验证
|
// 签名验证
|
||||||
$jwtkey = self::jwtkey($jwtkey);
|
$jwtkey = self::jwtkey($jwtkey);
|
||||||
@ -143,7 +173,9 @@ class JwtExtend
|
|||||||
// 返回自定义数据字段
|
// 返回自定义数据字段
|
||||||
if (isset($payload['enc'])) {
|
if (isset($payload['enc'])) {
|
||||||
$extra = json_decode(CodeExtend::decrypt($payload['enc'], $jwtkey), true);
|
$extra = json_decode(CodeExtend::decrypt($payload['enc'], $jwtkey), true);
|
||||||
if (!empty($extra['.ssid'])) self::$sessionId = $extra['.ssid'];
|
if (!empty($extra['.ssid'])) {
|
||||||
|
self::$sessionId = $extra['.ssid'];
|
||||||
|
}
|
||||||
unset($payload['enc'], $extra['.ssid']);
|
unset($payload['enc'], $extra['.ssid']);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -151,28 +183,31 @@ class JwtExtend
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取 JWT 密钥
|
* 获取 JWT 密钥.
|
||||||
* @param ?string $jwtkey
|
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public static function jwtkey(?string $jwtkey = null): string
|
public static function jwtkey(?string $jwtkey = null): string
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
if (!empty($jwtkey)) return $jwtkey;
|
if (!empty($jwtkey)) {
|
||||||
|
return $jwtkey;
|
||||||
|
}
|
||||||
|
|
||||||
// 优先读取配置文件
|
// 优先读取配置文件
|
||||||
$jwtkey = config('app.jwtkey');
|
$jwtkey = config('app.jwtkey');
|
||||||
if (!empty($jwtkey)) return $jwtkey;
|
if (!empty($jwtkey)) {
|
||||||
|
return $jwtkey;
|
||||||
|
}
|
||||||
|
|
||||||
// 再次读取数据配置
|
// 再次读取数据配置
|
||||||
$jwtkey = sysconf('data.jwtkey|raw');
|
$jwtkey = sysconf('data.jwtkey|raw');
|
||||||
if (!empty($jwtkey)) return $jwtkey;
|
if (!empty($jwtkey)) {
|
||||||
|
return $jwtkey;
|
||||||
|
}
|
||||||
|
|
||||||
// 自动生成新的密钥
|
// 自动生成新的密钥
|
||||||
$jwtkey = md5(uniqid(strval(rand(1000, 9999)), true));
|
$jwtkey = md5(uniqid(strval(rand(1000, 9999)), true));
|
||||||
sysconf('data.jwtkey', $jwtkey);
|
sysconf('data.jwtkey', $jwtkey);
|
||||||
return $jwtkey;
|
return $jwtkey;
|
||||||
|
|
||||||
} catch (\Exception $exception) {
|
} catch (\Exception $exception) {
|
||||||
trace_file($exception);
|
trace_file($exception);
|
||||||
return 'thinkadmin';
|
return 'thinkadmin';
|
||||||
@ -180,65 +215,40 @@ class JwtExtend
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 输出模板变量
|
* 输出模板变量.
|
||||||
* @param \think\admin\Controller $class
|
|
||||||
* @param array $vars
|
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public static function fetch(Controller $class, array $vars = [])
|
public static function fetch(Controller $class, array $vars = [])
|
||||||
{
|
{
|
||||||
$ignore = array_keys(get_class_vars(Controller::class));
|
$ignore = array_keys(get_class_vars(Controller::class));
|
||||||
foreach ($class as $name => $value) if (!in_array($name, $ignore)) {
|
foreach ($class as $name => $value) {
|
||||||
if (is_array($value) || is_numeric($value) || is_string($value) || is_bool($value) || is_null($value)) {
|
if (!in_array($name, $ignore)) {
|
||||||
$vars[$name] = $value;
|
if (is_array($value) || is_numeric($value) || is_string($value) || is_bool($value) || is_null($value)) {
|
||||||
|
$vars[$name] = $value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$class->success('获取变量成功!', $vars);
|
$class->success('获取变量成功!', $vars);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取原会话标识
|
* 获取原会话标识.
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
private static function withSess(): string
|
private static function withSess(): string
|
||||||
{
|
{
|
||||||
if (!isset(Library::$sapp->session)) return self::$sessionId = '';
|
if (!isset(Library::$sapp->session)) {
|
||||||
|
return self::$sessionId = '';
|
||||||
|
}
|
||||||
return self::$sessionId = Library::$sapp->session->getId();
|
return self::$sessionId = Library::$sapp->session->getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 生成数据签名
|
* 生成数据签名.
|
||||||
* @param string $input 为 base64UrlEncode(header).".".base64UrlEncode(payload)
|
* @param string $input 为 base64UrlEncode(header).".".base64UrlEncode(payload)
|
||||||
* @param string $alg 算法方式
|
* @param string $alg 算法方式
|
||||||
* @param ?string $key 签名密钥
|
* @param ?string $key 签名密钥
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
private static function withSign(string $input, string $alg = 'HS256', ?string $key = null): string
|
private static function withSign(string $input, string $alg = 'HS256', ?string $key = null): string
|
||||||
{
|
{
|
||||||
return CodeExtend::enSafe64(hash_hmac(self::signTypes[$alg], $input, self::jwtkey($key), true));
|
return CodeExtend::enSafe64(hash_hmac(self::signTypes[$alg], $input, self::jwtkey($key), true));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
/**
|
|
||||||
* 兼容历史方法
|
|
||||||
* @param string $method
|
|
||||||
* @param array $arguments
|
|
||||||
* @return array|string
|
|
||||||
* @throws \think\admin\Exception
|
|
||||||
*/
|
|
||||||
public static function __callStatic(string $method, array $arguments)
|
|
||||||
{
|
|
||||||
switch ($method) {
|
|
||||||
case 'isRejwt': // 是否返回令牌
|
|
||||||
return self::$rejwt;
|
|
||||||
case 'getInData': // 获取请求数据
|
|
||||||
return self::$input;
|
|
||||||
case 'getToken': // 生成接口令牌
|
|
||||||
return self::token(...$arguments);
|
|
||||||
case 'verifyToken': // 验证接口令牌
|
|
||||||
return self::verify(...$arguments);
|
|
||||||
default:
|
|
||||||
throw new Exception("method not exists: JwtExtend::{$method}()");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@ -1,45 +1,43 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// +----------------------------------------------------------------------
|
declare(strict_types=1);
|
||||||
// | Library for ThinkAdmin
|
/**
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 版权所有 2014~2025 ThinkAdmin [ thinkadmin.top ]
|
* | Payment Plugin for ThinkAdmin
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 官方网站: https://thinkadmin.top
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 开源协议 ( https://mit-license.org )
|
* | 官方网站: https://thinkadmin.top
|
||||||
// | 免费声明 ( https://thinkadmin.top/disclaimer )
|
* +----------------------------------------------------------------------
|
||||||
// +----------------------------------------------------------------------
|
* | 开源协议 ( https://mit-license.org )
|
||||||
// | gitee 仓库地址 :https://gitee.com/zoujingli/ThinkLibrary
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
// | github 仓库地址 :https://github.com/zoujingli/ThinkLibrary
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
declare (strict_types=1);
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
namespace think\admin\extend;
|
namespace think\admin\extend;
|
||||||
|
|
||||||
use Exception;
|
|
||||||
use Phinx\Db\Adapter\AdapterInterface;
|
use Phinx\Db\Adapter\AdapterInterface;
|
||||||
use Phinx\Db\Adapter\MysqlAdapter;
|
use Phinx\Db\Adapter\MysqlAdapter;
|
||||||
use Phinx\Db\Table;
|
use Phinx\Db\Table;
|
||||||
use SplFileInfo;
|
|
||||||
use think\admin\Library;
|
use think\admin\Library;
|
||||||
use think\admin\model\SystemMenu;
|
use think\admin\model\SystemMenu;
|
||||||
use think\admin\service\ProcessService;
|
use think\admin\service\ProcessService;
|
||||||
use think\helper\Str;
|
use think\helper\Str;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 数据库迁移扩展
|
* 数据库迁移扩展.
|
||||||
* @class PhinxExtend
|
* @class PhinxExtend
|
||||||
* @package think\admin\extend
|
|
||||||
*/
|
*/
|
||||||
class PhinxExtend
|
class PhinxExtend
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* 批量写入菜单
|
* 批量写入菜单.
|
||||||
* @param array $zdata 菜单数据
|
* @param array $zdata 菜单数据
|
||||||
* @param mixed $exists 检测条件
|
* @param mixed $exists 检测条件
|
||||||
* @return boolean
|
|
||||||
*/
|
*/
|
||||||
public static function write2menu(array $zdata, $exists = []): bool
|
public static function write2menu(array $zdata, $exists = []): bool
|
||||||
{
|
{
|
||||||
@ -48,16 +46,20 @@ class PhinxExtend
|
|||||||
if (!empty($exists) && SystemMenu::mk()->where($exists)->findOrEmpty()->isExists()) {
|
if (!empty($exists) && SystemMenu::mk()->where($exists)->findOrEmpty()->isExists()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} catch (Exception $exception) {
|
} catch (\Exception $exception) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// 循环写入系统菜单数据
|
// 循环写入系统菜单数据
|
||||||
foreach ($zdata as $one) {
|
foreach ($zdata as $one) {
|
||||||
$pid1 = static::write1menu($one);
|
$pid1 = static::write1menu($one);
|
||||||
if (!empty($one['subs'])) foreach ($one['subs'] as $two) {
|
if (!empty($one['subs'])) {
|
||||||
$pid2 = static::write1menu($two, $pid1);
|
foreach ($one['subs'] as $two) {
|
||||||
if (!empty($two['subs'])) foreach ($two['subs'] as $thr) {
|
$pid2 = static::write1menu($two, $pid1);
|
||||||
static::write1menu($thr, $pid2);
|
if (!empty($two['subs'])) {
|
||||||
|
foreach ($two['subs'] as $thr) {
|
||||||
|
static::write1menu($thr, $pid2);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -65,39 +67,19 @@ class PhinxExtend
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 单个写入菜单
|
* 升级更新数据表.
|
||||||
* @param array $menu 菜单数据
|
|
||||||
* @param integer $ppid 上级菜单
|
|
||||||
* @return integer
|
|
||||||
*/
|
|
||||||
private static function write1menu(array $menu, int $ppid = 0): int
|
|
||||||
{
|
|
||||||
return (int)SystemMenu::mk()->insertGetId([
|
|
||||||
'pid' => $ppid,
|
|
||||||
'url' => empty($menu['url']) ? (empty($menu['node']) ? '#' : $menu['node']) : $menu['url'],
|
|
||||||
'sort' => $menu['sort'] ?? 0,
|
|
||||||
'icon' => $menu['icon'] ?? '',
|
|
||||||
'node' => empty($menu['node']) ? (empty($menu['url']) ? '' : $menu['url']) : $menu['node'],
|
|
||||||
'title' => $menu['name'] ?? ($menu['title'] ?? ''),
|
|
||||||
'params' => $menu['params'] ?? '',
|
|
||||||
'target' => $menu['target'] ?? '_self',
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 升级更新数据表
|
|
||||||
* @param \Phinx\Db\Table $table
|
|
||||||
* @param array $fields 字段配置
|
* @param array $fields 字段配置
|
||||||
* @param array $indexs 索引配置
|
* @param array $indexs 索引配置
|
||||||
* @param boolean $force 强制更新
|
* @param bool $force 强制更新
|
||||||
* @return \Phinx\Db\Table
|
|
||||||
*/
|
*/
|
||||||
public static function upgrade(Table $table, array $fields, array $indexs = [], bool $force = false): Table
|
public static function upgrade(Table $table, array $fields, array $indexs = [], bool $force = false): Table
|
||||||
{
|
{
|
||||||
[$_exists, $_fields] = [[], array_column($fields, 0)];
|
[$_exists, $_fields] = [[], array_column($fields, 0)];
|
||||||
if ($isExists = $table->exists()) {
|
if ($isExists = $table->exists()) {
|
||||||
// 数据表存在且不强制时退出操作
|
// 数据表存在且不强制时退出操作
|
||||||
if (empty($force)) return $table;
|
if (empty($force)) {
|
||||||
|
return $table;
|
||||||
|
}
|
||||||
foreach ($table->getColumns() as $column) {
|
foreach ($table->getColumns() as $column) {
|
||||||
$_exists[] = $name = $column->getName();
|
$_exists[] = $name = $column->getName();
|
||||||
if (!in_array($name, $_fields)) {
|
if (!in_array($name, $_fields)) {
|
||||||
@ -127,6 +109,106 @@ class PhinxExtend
|
|||||||
return $table;
|
return $table;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建数据库安装脚本.
|
||||||
|
* @return string[]
|
||||||
|
* @throws \Exception
|
||||||
|
*/
|
||||||
|
public static function create2table(array $tables = [], string $class = 'InstallTable', bool $force = false): array
|
||||||
|
{
|
||||||
|
if (Library::$sapp->db->connect()->getConfig('type') !== 'mysql') {
|
||||||
|
throw new \Exception(' ** Notify: 只支持 MySql 数据库生成数据库脚本');
|
||||||
|
}
|
||||||
|
$br = "\r\n";
|
||||||
|
$content = static::_build2table($tables, true, $force);
|
||||||
|
$content = substr($content, strpos($content, "\n") + 1);
|
||||||
|
$content = '<?php' . "{$br}{$br}use think\\admin\\extend\\PhinxExtend;{$br}use think\\migration\\Migrator;{$br}{$br}@set_time_limit(0);{$br}@ini_set('memory_limit', -1);{$br}{$br}class {$class} extends Migrator{$br}{{$br}{$content}}{$br}";
|
||||||
|
return ['file' => static::nextFile($class), 'text' => $content];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建数据库备份脚本.
|
||||||
|
* @throws \Exception
|
||||||
|
*/
|
||||||
|
public static function create2backup(array $tables = [], string $class = 'InstallPackage', bool $progress = true): array
|
||||||
|
{
|
||||||
|
if (Library::$sapp->db->connect()->getConfig('type') !== 'mysql') {
|
||||||
|
throw new \Exception(' ** Notify: 只支持 MySql 数据库生成数据库脚本');
|
||||||
|
}
|
||||||
|
// 处理菜单数据
|
||||||
|
[$menuData, $menuList] = [[], SystemMenu::mk()->where(['status' => 1])->order('sort desc,id asc')->select()->toArray()];
|
||||||
|
foreach (DataExtend::arr2tree($menuList) as $sub1) {
|
||||||
|
$one = ['name' => $sub1['title'], 'icon' => $sub1['icon'], 'url' => $sub1['url'], 'node' => $sub1['node'], 'params' => $sub1['params'], 'subs' => []];
|
||||||
|
if (!empty($sub1['sub'])) {
|
||||||
|
foreach ($sub1['sub'] as $sub2) {
|
||||||
|
$two = ['name' => $sub2['title'], 'icon' => $sub2['icon'], 'url' => $sub2['url'], 'node' => $sub2['node'], 'params' => $sub2['params'], 'subs' => []];
|
||||||
|
if (!empty($sub2['sub'])) {
|
||||||
|
foreach ($sub2['sub'] as $sub3) {
|
||||||
|
$two['subs'][] = ['name' => $sub3['title'], 'url' => $sub3['url'], 'node' => $sub3['node'], 'icon' => $sub3['icon'], 'params' => $sub3['params']];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (empty($two['subs'])) {
|
||||||
|
unset($two['subs']);
|
||||||
|
}
|
||||||
|
$one['subs'][] = $two;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (empty($one['subs'])) {
|
||||||
|
unset($one['subs']);
|
||||||
|
}
|
||||||
|
$menuData[] = $one;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 备份数据表
|
||||||
|
[$extra, $version] = [[], strstr($filename = static::nextFile($class), '_', true)];
|
||||||
|
if (count($tables) > 0) {
|
||||||
|
foreach ($tables as $table) {
|
||||||
|
if (($count = ($db = Library::$sapp->db->table($table))->count()) > 0) {
|
||||||
|
$dataFileName = "{$version}/{$table}.data";
|
||||||
|
$dataFilePath = syspath("database/migrations/{$dataFileName}");
|
||||||
|
is_dir($dataDirectory = dirname($dataFilePath)) || mkdir($dataDirectory, 0777, true);
|
||||||
|
$progress && ProcessService::message(" -- Starting write {$table}.data ..." . PHP_EOL);
|
||||||
|
[$used, $fp] = [0, fopen($dataFilePath, 'w+')];
|
||||||
|
foreach ($db->cursor() as $item) {
|
||||||
|
fwrite($fp, json_encode($item, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) . "\r\n");
|
||||||
|
if ($progress && ($number = sprintf('%.4f', (++$used / $count) * 100) . '%')) {
|
||||||
|
ProcessService::message(" -- -- write {$table}.data: {$used}/{$count} {$number}", 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fclose($fp);
|
||||||
|
$extra[$table] = $dataFileName;
|
||||||
|
$progress && ProcessService::message(" -- Finished write {$table}.data, Total {$used} rows.", 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 生成迁移脚本
|
||||||
|
$template = file_get_contents(dirname(__DIR__) . '/service/bin/package.stub');
|
||||||
|
$dataJson = json_encode($extra, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
|
||||||
|
$menuJson = json_encode($menuData, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
|
||||||
|
$replaces = ['__CLASS__' => $class, '__MENU_JSON__' => $menuJson, '__DATA_JSON__' => $dataJson];
|
||||||
|
return ['file' => $filename, 'text' => str_replace(array_keys($replaces), array_values($replaces), $template)];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 单个写入菜单.
|
||||||
|
* @param array $menu 菜单数据
|
||||||
|
* @param int $ppid 上级菜单
|
||||||
|
*/
|
||||||
|
private static function write1menu(array $menu, int $ppid = 0): int
|
||||||
|
{
|
||||||
|
return (int)SystemMenu::mk()->insertGetId([
|
||||||
|
'pid' => $ppid,
|
||||||
|
'url' => empty($menu['url']) ? (empty($menu['node']) ? '#' : $menu['node']) : $menu['url'],
|
||||||
|
'sort' => $menu['sort'] ?? 0,
|
||||||
|
'icon' => $menu['icon'] ?? '',
|
||||||
|
'node' => empty($menu['node']) ? (empty($menu['url']) ? '' : $menu['url']) : $menu['node'],
|
||||||
|
'title' => $menu['name'] ?? ($menu['title'] ?? ''),
|
||||||
|
'params' => $menu['params'] ?? '',
|
||||||
|
'target' => $menu['target'] ?? '_self',
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 生成索引名称.
|
* 生成索引名称.
|
||||||
*
|
*
|
||||||
@ -147,101 +229,19 @@ class PhinxExtend
|
|||||||
return sprintf('idx_%s_%s_%s', substr(md5($table), -4), $getInitials($table), $name);
|
return sprintf('idx_%s_%s_%s', substr(md5($table), -4), $getInitials($table), $name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建数据库安装脚本
|
|
||||||
* @param array $tables
|
|
||||||
* @param string $class
|
|
||||||
* @param boolean $force
|
|
||||||
* @return string[]
|
|
||||||
* @throws \Exception
|
|
||||||
*/
|
|
||||||
public static function create2table(array $tables = [], string $class = 'InstallTable', bool $force = false): array
|
|
||||||
{
|
|
||||||
if (Library::$sapp->db->connect()->getConfig('type') !== 'mysql') {
|
|
||||||
throw new Exception(' ** Notify: 只支持 MySql 数据库生成数据库脚本');
|
|
||||||
}
|
|
||||||
$br = "\r\n";
|
|
||||||
$content = static::_build2table($tables, true, $force);
|
|
||||||
$content = substr($content, strpos($content, "\n") + 1);
|
|
||||||
$content = '<?php' . "{$br}{$br}use think\\admin\\extend\\PhinxExtend;{$br}use think\migration\Migrator;{$br}{$br}@set_time_limit(0);{$br}@ini_set('memory_limit', -1);{$br}{$br}class {$class} extends Migrator{$br}{{$br}{$content}}{$br}";
|
|
||||||
return ['file' => static::nextFile($class), 'text' => $content];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建数据库备份脚本
|
|
||||||
* @param array $tables
|
|
||||||
* @param string $class
|
|
||||||
* @param boolean $progress
|
|
||||||
* @return array
|
|
||||||
* @throws \Exception
|
|
||||||
*/
|
|
||||||
public static function create2backup(array $tables = [], string $class = 'InstallPackage', bool $progress = true): array
|
|
||||||
{
|
|
||||||
if (Library::$sapp->db->connect()->getConfig('type') !== 'mysql') {
|
|
||||||
throw new Exception(' ** Notify: 只支持 MySql 数据库生成数据库脚本');
|
|
||||||
}
|
|
||||||
// 处理菜单数据
|
|
||||||
[$menuData, $menuList] = [[], SystemMenu::mk()->where(['status' => 1])->order('sort desc,id asc')->select()->toArray()];
|
|
||||||
foreach (DataExtend::arr2tree($menuList) as $sub1) {
|
|
||||||
$one = ['name' => $sub1['title'], 'icon' => $sub1['icon'], 'url' => $sub1['url'], 'node' => $sub1['node'], 'params' => $sub1['params'], 'subs' => []];
|
|
||||||
if (!empty($sub1['sub'])) foreach ($sub1['sub'] as $sub2) {
|
|
||||||
$two = ['name' => $sub2['title'], 'icon' => $sub2['icon'], 'url' => $sub2['url'], 'node' => $sub2['node'], 'params' => $sub2['params'], 'subs' => []];
|
|
||||||
if (!empty($sub2['sub'])) foreach ($sub2['sub'] as $sub3) {
|
|
||||||
$two['subs'][] = ['name' => $sub3['title'], 'url' => $sub3['url'], 'node' => $sub3['node'], 'icon' => $sub3['icon'], 'params' => $sub3['params']];
|
|
||||||
}
|
|
||||||
if (empty($two['subs'])) unset($two['subs']);
|
|
||||||
$one['subs'][] = $two;
|
|
||||||
}
|
|
||||||
if (empty($one['subs'])) unset($one['subs']);
|
|
||||||
$menuData[] = $one;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 备份数据表
|
|
||||||
[$extra, $version] = [[], strstr($filename = static::nextFile($class), '_', true)];
|
|
||||||
if (count($tables) > 0) foreach ($tables as $table) {
|
|
||||||
if (($count = ($db = Library::$sapp->db->table($table))->count()) > 0) {
|
|
||||||
$dataFileName = "{$version}/{$table}.data";
|
|
||||||
$dataFilePath = syspath("database/migrations/{$dataFileName}");
|
|
||||||
is_dir($dataDirectory = dirname($dataFilePath)) || mkdir($dataDirectory, 0777, true);
|
|
||||||
$progress && ProcessService::message(" -- Starting write {$table}.data ..." . PHP_EOL);
|
|
||||||
[$used, $fp] = [0, fopen($dataFilePath, 'w+')];
|
|
||||||
foreach ($db->cursor() as $item) {
|
|
||||||
fwrite($fp, json_encode($item, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) . "\r\n");
|
|
||||||
if ($progress && ($number = sprintf("%.4f", (++$used / $count) * 100) . '%')) {
|
|
||||||
ProcessService::message(" -- -- write {$table}.data: {$used}/{$count} {$number}", 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fclose($fp);
|
|
||||||
$extra[$table] = $dataFileName;
|
|
||||||
$progress && ProcessService::message(" -- Finished write {$table}.data, Total {$used} rows.", 2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 生成迁移脚本
|
|
||||||
$template = file_get_contents(dirname(__DIR__) . '/service/bin/package.stub');
|
|
||||||
$dataJson = json_encode($extra, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
|
|
||||||
$menuJson = json_encode($menuData, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
|
|
||||||
$replaces = ['__CLASS__' => $class, '__MENU_JSON__' => $menuJson, '__DATA_JSON__' => $dataJson];
|
|
||||||
return ['file' => $filename, 'text' => str_replace(array_keys($replaces), array_values($replaces), $template)];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 数组转代码
|
* 数组转代码
|
||||||
* @param array $data
|
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
private static function _arr2str(array $data): string
|
private static function _arr2str(array $data): string
|
||||||
{
|
{
|
||||||
return preg_replace(['#\s+#', '#, \)$#', '#^array \( #'], [' ', ']', '[',], var_export($data, true));
|
return preg_replace(['#\s+#', '#, \)$#', '#^array \( #'], [' ', ']', '['], var_export($data, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 生成数据库表格创建模板
|
* 生成数据库表格创建模板
|
||||||
* @param array $tables 指定数据表
|
* @param array $tables 指定数据表
|
||||||
* @param boolean $rehtml 是否返回内容
|
* @param bool $rehtml 是否返回内容
|
||||||
* @param boolean $force 强制更新结构
|
* @param bool $force 强制更新结构
|
||||||
* @return string
|
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
private static function _build2table(array $tables = [], bool $rehtml = false, bool $force = false): string
|
private static function _build2table(array $tables = [], bool $rehtml = false, bool $force = false): string
|
||||||
@ -249,11 +249,13 @@ class PhinxExtend
|
|||||||
$br = "\r\n";
|
$br = "\r\n";
|
||||||
$connect = Library::$sapp->db->connect();
|
$connect = Library::$sapp->db->connect();
|
||||||
if ($connect->getConfig('type') !== 'mysql') {
|
if ($connect->getConfig('type') !== 'mysql') {
|
||||||
throw new Exception(' ** Notify: 只支持 MySql 数据库生成数据库脚本');
|
throw new \Exception(' ** Notify: 只支持 MySql 数据库生成数据库脚本');
|
||||||
}
|
}
|
||||||
$schema = $connect->getConfig('database');
|
$schema = $connect->getConfig('database');
|
||||||
$content = '<?php' . "{$br}{$br}\t/**{$br}\t * 创建数据库{$br}\t */{$br}\tpublic function change()\n\t{";
|
$content = '<?php' . "{$br}{$br}\t/**{$br}\t * 创建数据库{$br}\t */{$br}\tpublic function change()\n\t{";
|
||||||
foreach ($tables as $table) $content .= "{$br}\t\t\$this->_create_{$table}();";
|
foreach ($tables as $table) {
|
||||||
|
$content .= "{$br}\t\t\$this->_create_{$table}();";
|
||||||
|
}
|
||||||
$content .= "{$br}\t}{$br}{$br}";
|
$content .= "{$br}\t}{$br}{$br}";
|
||||||
|
|
||||||
// 字段默认长度
|
// 字段默认长度
|
||||||
@ -262,27 +264,26 @@ class PhinxExtend
|
|||||||
// 字段类型转换 ( 仅需定义与MySQL不同的配置 )
|
// 字段类型转换 ( 仅需定义与MySQL不同的配置 )
|
||||||
$types = [
|
$types = [
|
||||||
// 整形数字
|
// 整形数字
|
||||||
'tinyint' => AdapterInterface::PHINX_TYPE_TINY_INTEGER,
|
'tinyint' => AdapterInterface::PHINX_TYPE_TINY_INTEGER,
|
||||||
'smallint' => AdapterInterface::PHINX_TYPE_SMALL_INTEGER,
|
'smallint' => AdapterInterface::PHINX_TYPE_SMALL_INTEGER,
|
||||||
'int' => AdapterInterface::PHINX_TYPE_INTEGER,
|
'int' => AdapterInterface::PHINX_TYPE_INTEGER,
|
||||||
'bigint' => AdapterInterface::PHINX_TYPE_BIG_INTEGER,
|
'bigint' => AdapterInterface::PHINX_TYPE_BIG_INTEGER,
|
||||||
// 字符类型
|
// 字符类型
|
||||||
'varchar' => AdapterInterface::PHINX_TYPE_STRING,
|
'varchar' => AdapterInterface::PHINX_TYPE_STRING,
|
||||||
'tinytext' => AdapterInterface::PHINX_TYPE_TEXT,
|
'tinytext' => AdapterInterface::PHINX_TYPE_TEXT,
|
||||||
'mediumtext' => AdapterInterface::PHINX_TYPE_TEXT,
|
'mediumtext' => AdapterInterface::PHINX_TYPE_TEXT,
|
||||||
'longtext' => AdapterInterface::PHINX_TYPE_TEXT,
|
'longtext' => AdapterInterface::PHINX_TYPE_TEXT,
|
||||||
// 仅 mysql 有的字段需要单独处理
|
// 仅 mysql 有的字段需要单独处理
|
||||||
'set' => AdapterInterface::PHINX_TYPE_STRING,
|
'set' => AdapterInterface::PHINX_TYPE_STRING,
|
||||||
'enum' => AdapterInterface::PHINX_TYPE_STRING,
|
'enum' => AdapterInterface::PHINX_TYPE_STRING,
|
||||||
'year' => AdapterInterface::PHINX_TYPE_INTEGER,
|
'year' => AdapterInterface::PHINX_TYPE_INTEGER,
|
||||||
'mediumint' => AdapterInterface::PHINX_TYPE_INTEGER,
|
'mediumint' => AdapterInterface::PHINX_TYPE_INTEGER,
|
||||||
'tinyblob' => AdapterInterface::PHINX_TYPE_BLOB,
|
'tinyblob' => AdapterInterface::PHINX_TYPE_BLOB,
|
||||||
'longblob' => AdapterInterface::PHINX_TYPE_BLOB,
|
'longblob' => AdapterInterface::PHINX_TYPE_BLOB,
|
||||||
'mediumblob' => AdapterInterface::PHINX_TYPE_BLOB,
|
'mediumblob' => AdapterInterface::PHINX_TYPE_BLOB,
|
||||||
];
|
];
|
||||||
|
|
||||||
foreach ($tables as $table) {
|
foreach ($tables as $table) {
|
||||||
|
|
||||||
// 读取数据表 - 备注参数
|
// 读取数据表 - 备注参数
|
||||||
$comment = Library::$sapp->db->table('information_schema.TABLES')->where([
|
$comment = Library::$sapp->db->table('information_schema.TABLES')->where([
|
||||||
'TABLE_SCHEMA' => $schema, 'TABLE_NAME' => $table,
|
'TABLE_SCHEMA' => $schema, 'TABLE_NAME' => $table,
|
||||||
@ -310,7 +311,9 @@ CODE;
|
|||||||
// 生成字段内容
|
// 生成字段内容
|
||||||
$_fieldString = '[' . PHP_EOL;
|
$_fieldString = '[' . PHP_EOL;
|
||||||
foreach (Library::$sapp->db->getFields($table) as $field) {
|
foreach (Library::$sapp->db->getFields($table) as $field) {
|
||||||
if ($field['name'] === 'id') continue;
|
if ($field['name'] === 'id') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
$type = $types[$field['type']] ?? $field['type'];
|
$type = $types[$field['type']] ?? $field['type'];
|
||||||
$data = ['default' => $field['default'], 'null' => empty($field['notnull']), 'comment' => $field['comment'] ?? ''];
|
$data = ['default' => $field['default'], 'null' => empty($field['notnull']), 'comment' => $field['comment'] ?? ''];
|
||||||
if ($field['type'] === 'longtext') {
|
if ($field['type'] === 'longtext') {
|
||||||
@ -334,7 +337,7 @@ CODE;
|
|||||||
$type = $types[$attr[1]] ?? 'decimal';
|
$type = $types[$attr[1]] ?? 'decimal';
|
||||||
$data = array_merge(['precision' => intval($attr[2]), 'scale' => intval($attr[3])], $data);
|
$data = array_merge(['precision' => intval($attr[2]), 'scale' => intval($attr[3])], $data);
|
||||||
}
|
}
|
||||||
$_fieldString .= "\t\t\t['{$field['name']}', '{$type}', " . self::_arr2str($data) . "]," . PHP_EOL;
|
$_fieldString .= "\t\t\t['{$field['name']}', '{$type}', " . self::_arr2str($data) . '],' . PHP_EOL;
|
||||||
}
|
}
|
||||||
$_fieldString .= "\t\t]";
|
$_fieldString .= "\t\t]";
|
||||||
// 生成索引内容
|
// 生成索引内容
|
||||||
@ -356,14 +359,13 @@ CODE;
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 生成下一个脚本名称
|
* 生成下一个脚本名称.
|
||||||
* @param string $class 脚本类名
|
* @param string $class 脚本类名
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
private static function nextFile(string $class): string
|
private static function nextFile(string $class): string
|
||||||
{
|
{
|
||||||
[$snake, $items] = [Str::snake($class), [20010000000000]];
|
[$snake, $items] = [Str::snake($class), [20010000000000]];
|
||||||
ToolsExtend::find(syspath('database/migrations'), 1, function (SplFileInfo $info) use ($snake, &$items) {
|
ToolsExtend::find(syspath('database/migrations'), 1, function (\SplFileInfo $info) use ($snake, &$items) {
|
||||||
if ($info->isFile()) {
|
if ($info->isFile()) {
|
||||||
$bname = pathinfo($info->getBasename(), PATHINFO_FILENAME);
|
$bname = pathinfo($info->getBasename(), PATHINFO_FILENAME);
|
||||||
$items[] = $version = intval(substr($bname, 0, 14));
|
$items[] = $version = intval(substr($bname, 0, 14));
|
||||||
@ -378,4 +380,4 @@ CODE;
|
|||||||
// 计算下一个版本号
|
// 计算下一个版本号
|
||||||
return sprintf("%s_{$snake}.php", min($items) - 1);
|
return sprintf("%s_{$snake}.php", min($items) - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,90 +1,106 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// +----------------------------------------------------------------------
|
declare(strict_types=1);
|
||||||
// | Library for ThinkAdmin
|
/**
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 版权所有 2014~2025 ThinkAdmin [ thinkadmin.top ]
|
* | Payment Plugin for ThinkAdmin
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 官方网站: https://thinkadmin.top
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 开源协议 ( https://mit-license.org )
|
* | 官方网站: https://thinkadmin.top
|
||||||
// | 免费声明 ( https://thinkadmin.top/disclaimer )
|
* +----------------------------------------------------------------------
|
||||||
// +----------------------------------------------------------------------
|
* | 开源协议 ( https://mit-license.org )
|
||||||
// | gitee 仓库地址 :https://gitee.com/zoujingli/ThinkLibrary
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
// | github 仓库地址 :https://github.com/zoujingli/ThinkLibrary
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
declare (strict_types=1);
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
namespace think\admin\extend;
|
namespace think\admin\extend;
|
||||||
|
|
||||||
use Closure;
|
|
||||||
use FilesystemIterator;
|
|
||||||
use Generator;
|
|
||||||
use SplFileInfo;
|
use SplFileInfo;
|
||||||
use think\admin\Exception;
|
use think\admin\Exception;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 通用工具扩展
|
* 通用工具扩展.
|
||||||
* @class ToolsExtend
|
* @class ToolsExtend
|
||||||
* @package think\admin\extend
|
|
||||||
*/
|
*/
|
||||||
class ToolsExtend
|
class ToolsExtend
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* 兼容旧方式调用.
|
||||||
|
* @return array|bool
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public static function __callStatic(string $method, array $arguments)
|
||||||
|
{
|
||||||
|
$methods = [
|
||||||
|
'copyfile' => 'copy',
|
||||||
|
'scandirectory' => 'scan',
|
||||||
|
'findfilesarray' => 'find',
|
||||||
|
'removeemptydirectory' => 'remove',
|
||||||
|
];
|
||||||
|
if ($real = $methods[strtolower($method)] ?? null) {
|
||||||
|
return self::{$real}(...$arguments);
|
||||||
|
}
|
||||||
|
throw new Exception("method not exists: ToolsExtend::{$method}()");
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 扫描目录下的文件列表
|
* 扫描目录下的文件列表.
|
||||||
* @param string $path 扫描目录
|
* @param string $path 扫描目录
|
||||||
* @param ?integer $depth 扫描深度
|
* @param ?int $depth 扫描深度
|
||||||
* @param string $ext 筛选后缀
|
* @param string $ext 筛选后缀
|
||||||
* @param boolean $short 相对路径
|
* @param bool $short 相对路径
|
||||||
* @return array
|
|
||||||
*/
|
*/
|
||||||
public static function scan(string $path, ?int $depth = null, string $ext = '', bool $short = true): array
|
public static function scan(string $path, ?int $depth = null, string $ext = '', bool $short = true): array
|
||||||
{
|
{
|
||||||
return static::find($path, $depth, function (SplFileInfo $info) use ($ext) {
|
return static::find($path, $depth, function (\SplFileInfo $info) use ($ext) {
|
||||||
return $info->isDir() || $ext === '' || strtolower($info->getExtension()) === strtolower($ext);
|
return $info->isDir() || $ext === '' || strtolower($info->getExtension()) === strtolower($ext);
|
||||||
}, $short);
|
}, $short);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 扫描目录并返回文件路径数组
|
* 扫描目录并返回文件路径数组.
|
||||||
* @param string $path 扫描目录
|
* @param string $path 扫描目录
|
||||||
* @param ?integer $depth 扫描深度
|
* @param ?int $depth 扫描深度
|
||||||
* @param ?Closure $filter 文件过滤,返回 false 表示放弃
|
* @param ?\Closure $filter 文件过滤,返回 false 表示放弃
|
||||||
* @param boolean $short 是否返回相对于给定路径的短路径
|
* @param bool $short 是否返回相对于给定路径的短路径
|
||||||
* @return array 包含文件路径的数组
|
* @return array 包含文件路径的数组
|
||||||
*/
|
*/
|
||||||
public static function find(string $path, ?int $depth = null, ?Closure $filter = null, bool $short = true): array
|
public static function find(string $path, ?int $depth = null, ?\Closure $filter = null, bool $short = true): array
|
||||||
{
|
{
|
||||||
[$info, $files] = [new SplFileInfo($path), []];
|
[$info, $files] = [new \SplFileInfo($path), []];
|
||||||
if ($info->isDir() || $info->isFile()) {
|
if ($info->isDir() || $info->isFile()) {
|
||||||
if ($info->isFile() && ($filter === null || $filter($info) !== false)) {
|
if ($info->isFile() && ($filter === null || $filter($info) !== false)) {
|
||||||
$files[] = $short ? $info->getBasename() : $info->getPathname();
|
$files[] = $short ? $info->getBasename() : $info->getPathname();
|
||||||
}
|
}
|
||||||
if ($info->isDir()) foreach (static::findFilesYield($info->getPathname(), $depth, $filter) as $file) {
|
if ($info->isDir()) {
|
||||||
$files[] = $short ? substr($file->getPathname(), strlen($info->getPathname()) + 1) : $file->getPathname();
|
foreach (static::findFilesYield($info->getPathname(), $depth, $filter) as $file) {
|
||||||
|
$files[] = $short ? substr($file->getPathname(), strlen($info->getPathname()) + 1) : $file->getPathname();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return $files;
|
return $files;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 深度拷贝到指定目录
|
* 深度拷贝到指定目录.
|
||||||
* @param string $frdir 来源目录
|
* @param string $frdir 来源目录
|
||||||
* @param string $todir 目标目录
|
* @param string $todir 目标目录
|
||||||
* @param array $files 指定文件
|
* @param array $files 指定文件
|
||||||
* @param boolean $force 强制替换
|
* @param bool $force 强制替换
|
||||||
* @param boolean $remove 删除文件
|
* @param bool $remove 删除文件
|
||||||
* @return boolean
|
|
||||||
*/
|
*/
|
||||||
public static function copy(string $frdir, string $todir, array $files = [], bool $force = true, bool $remove = true): bool
|
public static function copy(string $frdir, string $todir, array $files = [], bool $force = true, bool $remove = true): bool
|
||||||
{
|
{
|
||||||
$frdir = rtrim($frdir, '\\/') . DIRECTORY_SEPARATOR;
|
$frdir = rtrim($frdir, '\/') . DIRECTORY_SEPARATOR;
|
||||||
$todir = rtrim($todir, '\\/') . DIRECTORY_SEPARATOR;
|
$todir = rtrim($todir, '\/') . DIRECTORY_SEPARATOR;
|
||||||
// 扫描目录文件
|
// 扫描目录文件
|
||||||
if (empty($files) && is_dir($frdir)) {
|
if (empty($files) && is_dir($frdir)) {
|
||||||
$files = static::find($frdir, null, function (SplFileInfo $info) {
|
$files = static::find($frdir, null, function (\SplFileInfo $info) {
|
||||||
return $info->getBasename()[0] !== '.';
|
return $info->getBasename()[0] !== '.';
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -104,61 +120,45 @@ class ToolsExtend
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 移除清空目录
|
* 移除清空目录.
|
||||||
* @param string $path
|
|
||||||
* @return boolean
|
|
||||||
*/
|
*/
|
||||||
public static function remove(string $path): bool
|
public static function remove(string $path): bool
|
||||||
{
|
{
|
||||||
if (!file_exists($path)) return true;
|
if (!file_exists($path)) {
|
||||||
if (is_file($path)) return unlink($path);
|
return true;
|
||||||
|
}
|
||||||
|
if (is_file($path)) {
|
||||||
|
return unlink($path);
|
||||||
|
}
|
||||||
$dirs = [$path];
|
$dirs = [$path];
|
||||||
iterator_to_array(self::findFilesYield($path, null, function (SplFileInfo $file) use (&$dirs) {
|
iterator_to_array(self::findFilesYield($path, null, function (\SplFileInfo $file) use (&$dirs) {
|
||||||
$file->isDir() ? $dirs[] = $file->getPathname() : unlink($file->getPathname());
|
$file->isDir() ? $dirs[] = $file->getPathname() : unlink($file->getPathname());
|
||||||
}));
|
}));
|
||||||
usort($dirs, function ($a, $b) {
|
usort($dirs, function ($a, $b) {
|
||||||
return strlen($b) <=> strlen($a);
|
return strlen($b) <=> strlen($a);
|
||||||
});
|
});
|
||||||
foreach ($dirs as $dir) file_exists($dir) && is_dir($dir) && rmdir($dir);
|
foreach ($dirs as $dir) {
|
||||||
|
file_exists($dir) && is_dir($dir) && rmdir($dir);
|
||||||
|
}
|
||||||
return !file_exists($path);
|
return !file_exists($path);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 兼容旧方式调用
|
|
||||||
* @param string $method
|
|
||||||
* @param array $arguments
|
|
||||||
* @return array|bool
|
|
||||||
* @throws \think\admin\Exception
|
|
||||||
*/
|
|
||||||
public static function __callStatic(string $method, array $arguments)
|
|
||||||
{
|
|
||||||
$methods = [
|
|
||||||
'copyfile' => 'copy',
|
|
||||||
'scandirectory' => 'scan',
|
|
||||||
'findfilesarray' => 'find',
|
|
||||||
'removeemptydirectory' => 'remove',
|
|
||||||
];
|
|
||||||
if ($real = $methods[strtolower($method)] ?? null) {
|
|
||||||
return self::{$real}(...$arguments);
|
|
||||||
} else {
|
|
||||||
throw new Exception("method not exists: ToolsExtend::{$method}()");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 递归扫描指定目录,返回文件或目录的 SplFileInfo 对象。
|
* 递归扫描指定目录,返回文件或目录的 SplFileInfo 对象。
|
||||||
* @param string $path 目录路径。
|
* @param string $path 目录路径
|
||||||
* @param ?integer $depth 扫描深度
|
* @param ?int $depth 扫描深度
|
||||||
* @param \Closure|null $filter 文件过滤,返回 false 表示放弃
|
* @param null|\Closure $filter 文件过滤,返回 false 表示放弃
|
||||||
* @param boolean $appendPath 是否包含目录本身在结果中。
|
* @param bool $appendPath 是否包含目录本身在结果中
|
||||||
* @param integer $currDepth 当前深度,临时变量递归时使用。
|
* @param int $currDepth 当前深度,临时变量递归时使用
|
||||||
* @return \Generator 返回 SplFileInfo 对象的生成器。
|
* @return \Generator 返回 SplFileInfo 对象的生成器
|
||||||
*/
|
*/
|
||||||
public static function findFilesYield(string $path, ?int $depth = null, ?Closure $filter = null, bool $appendPath = false, int $currDepth = 1): Generator
|
public static function findFilesYield(string $path, ?int $depth = null, ?\Closure $filter = null, bool $appendPath = false, int $currDepth = 1): \Generator
|
||||||
{
|
{
|
||||||
if (file_exists($path) && is_dir($path) && (is_null($depth) || $currDepth <= $depth)) {
|
if (file_exists($path) && is_dir($path) && (is_null($depth) || $currDepth <= $depth)) {
|
||||||
foreach (new FilesystemIterator($path, FilesystemIterator::SKIP_DOTS) as $item) {
|
foreach (new \FilesystemIterator($path, \FilesystemIterator::SKIP_DOTS) as $item) {
|
||||||
if ($filter !== null && $filter($item) === false) continue;
|
if ($filter !== null && $filter($item) === false) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if ($item->isDir() && !$item->isLink()) {
|
if ($item->isDir() && !$item->isLink()) {
|
||||||
$appendPath && yield $item;
|
$appendPath && yield $item;
|
||||||
yield from static::findFilesYield($item->getPathname(), $depth, $filter, $appendPath, $currDepth + 1);
|
yield from static::findFilesYield($item->getPathname(), $depth, $filter, $appendPath, $currDepth + 1);
|
||||||
@ -168,4 +168,4 @@ class ToolsExtend
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,20 +1,22 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// +----------------------------------------------------------------------
|
declare(strict_types=1);
|
||||||
// | Library for ThinkAdmin
|
/**
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 版权所有 2014~2025 ThinkAdmin [ thinkadmin.top ]
|
* | Payment Plugin for ThinkAdmin
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 官方网站: https://thinkadmin.top
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 开源协议 ( https://mit-license.org )
|
* | 官方网站: https://thinkadmin.top
|
||||||
// | 免费声明 ( https://thinkadmin.top/disclaimer )
|
* +----------------------------------------------------------------------
|
||||||
// +----------------------------------------------------------------------
|
* | 开源协议 ( https://mit-license.org )
|
||||||
// | gitee 仓库地址 :https://gitee.com/zoujingli/ThinkLibrary
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
// | github 仓库地址 :https://github.com/zoujingli/ThinkLibrary
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
declare (strict_types=1);
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
namespace think\admin\extend;
|
namespace think\admin\extend;
|
||||||
|
|
||||||
@ -22,9 +24,8 @@ use think\admin\contract\StreamInterface;
|
|||||||
use think\Model;
|
use think\Model;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 虚拟模型构建协议
|
* 虚拟模型构建协议.
|
||||||
* @class VirtualModel
|
* @class VirtualModel
|
||||||
* @package think\admin\extend
|
|
||||||
*/
|
*/
|
||||||
class VirtualModel extends \stdClass implements StreamInterface
|
class VirtualModel extends \stdClass implements StreamInterface
|
||||||
{
|
{
|
||||||
@ -35,8 +36,8 @@ class VirtualModel extends \stdClass implements StreamInterface
|
|||||||
private $template;
|
private $template;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 读取进度标量
|
* 读取进度标量.
|
||||||
* @var integer
|
* @var int
|
||||||
*/
|
*/
|
||||||
private $position;
|
private $position;
|
||||||
|
|
||||||
@ -44,7 +45,9 @@ class VirtualModel extends \stdClass implements StreamInterface
|
|||||||
{
|
{
|
||||||
// 解析链接参数
|
// 解析链接参数
|
||||||
$attr = parse_url($path);
|
$attr = parse_url($path);
|
||||||
if (empty($attr['fragment'])) $attr['fragment'] = '';
|
if (empty($attr['fragment'])) {
|
||||||
|
$attr['fragment'] = '';
|
||||||
|
}
|
||||||
$type = strtolower($attr['fragment'] ?: 'default');
|
$type = strtolower($attr['fragment'] ?: 'default');
|
||||||
|
|
||||||
// 生成模型代码
|
// 生成模型代码
|
||||||
@ -71,13 +74,9 @@ class VirtualModel extends \stdClass implements StreamInterface
|
|||||||
return $this->position >= strlen($this->template);
|
return $this->position >= strlen($this->template);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function stream_cast(int $cast_as)
|
public function stream_cast(int $cast_as) {}
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public function stream_close(): void
|
public function stream_close(): void {}
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public function stream_flush(): bool
|
public function stream_flush(): bool
|
||||||
{
|
{
|
||||||
@ -170,11 +169,10 @@ class VirtualModel extends \stdClass implements StreamInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建虚拟模型
|
* 创建虚拟模型.
|
||||||
* @param mixed $name 模型名称
|
* @param mixed $name 模型名称
|
||||||
* @param array $data 模型数据
|
* @param array $data 模型数据
|
||||||
* @param mixed $conn 默认链接
|
* @param mixed $conn 默认链接
|
||||||
* @return \think\Model
|
|
||||||
*/
|
*/
|
||||||
public static function mk(string $name, array $data = [], string $conn = ''): Model
|
public static function mk(string $name, array $data = [], string $conn = ''): Model
|
||||||
{
|
{
|
||||||
@ -187,4 +185,4 @@ class VirtualModel extends \stdClass implements StreamInterface
|
|||||||
}
|
}
|
||||||
return new $class($data);
|
return new $class($data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,41 +1,43 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// +----------------------------------------------------------------------
|
declare(strict_types=1);
|
||||||
// | Library for ThinkAdmin
|
/**
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 版权所有 2014~2025 ThinkAdmin [ thinkadmin.top ]
|
* | Payment Plugin for ThinkAdmin
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 官方网站: https://thinkadmin.top
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 开源协议 ( https://mit-license.org )
|
* | 官方网站: https://thinkadmin.top
|
||||||
// | 免费声明 ( https://thinkadmin.top/disclaimer )
|
* +----------------------------------------------------------------------
|
||||||
// +----------------------------------------------------------------------
|
* | 开源协议 ( https://mit-license.org )
|
||||||
// | gitee 仓库地址 :https://gitee.com/zoujingli/ThinkLibrary
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
// | github 仓库地址 :https://github.com/zoujingli/ThinkLibrary
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
declare (strict_types=1);
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
namespace think\admin\helper;
|
namespace think\admin\helper;
|
||||||
|
|
||||||
use think\admin\Helper;
|
use think\admin\Helper;
|
||||||
use think\db\BaseQuery;
|
use think\db\BaseQuery;
|
||||||
|
use think\db\exception\DbException;
|
||||||
use think\Model;
|
use think\Model;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 通用删除管理器
|
* 通用删除管理器.
|
||||||
* @class DeleteHelper
|
* @class DeleteHelper
|
||||||
* @package think\admin\helper
|
|
||||||
*/
|
*/
|
||||||
class DeleteHelper extends Helper
|
class DeleteHelper extends Helper
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* 逻辑器初始化
|
* 逻辑器初始化.
|
||||||
* @param BaseQuery|Model|string $dbQuery
|
* @param BaseQuery|Model|string $dbQuery
|
||||||
* @param string $field 操作数据主键
|
* @param string $field 操作数据主键
|
||||||
* @param mixed $where 额外更新条件
|
* @param mixed $where 额外更新条件
|
||||||
* @return boolean|void
|
* @return bool|void
|
||||||
* @throws \think\db\exception\DbException
|
* @throws DbException
|
||||||
*/
|
*/
|
||||||
public function init($dbQuery, string $field = '', $where = [])
|
public function init($dbQuery, string $field = '', $where = [])
|
||||||
{
|
{
|
||||||
@ -44,13 +46,15 @@ class DeleteHelper extends Helper
|
|||||||
$value = $this->app->request->post($field);
|
$value = $this->app->request->post($field);
|
||||||
|
|
||||||
// 查询限制处理
|
// 查询限制处理
|
||||||
if (!empty($where)) $query->where($where);
|
if (!empty($where)) {
|
||||||
|
$query->where($where);
|
||||||
|
}
|
||||||
if (!isset($where[$field]) && is_string($value)) {
|
if (!isset($where[$field]) && is_string($value)) {
|
||||||
$query->whereIn($field, str2arr($value));
|
$query->whereIn($field, str2arr($value));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 前置回调处理
|
// 前置回调处理
|
||||||
if (false === $this->class->callback('_delete_filter', $query, $where)) {
|
if ($this->class->callback('_delete_filter', $query, $where) === false) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,11 +67,19 @@ class DeleteHelper extends Helper
|
|||||||
$data = [];
|
$data = [];
|
||||||
if (method_exists($query, 'getTableFields')) {
|
if (method_exists($query, 'getTableFields')) {
|
||||||
$fields = $query->getTableFields();
|
$fields = $query->getTableFields();
|
||||||
if (in_array('deleted', $fields)) $data['deleted'] = 1;
|
if (in_array('deleted', $fields)) {
|
||||||
if (in_array('is_deleted', $fields)) $data['is_deleted'] = 1;
|
$data['deleted'] = 1;
|
||||||
|
}
|
||||||
|
if (in_array('is_deleted', $fields)) {
|
||||||
|
$data['is_deleted'] = 1;
|
||||||
|
}
|
||||||
if (isset($data['deleted']) || isset($data['is_deleted'])) {
|
if (isset($data['deleted']) || isset($data['is_deleted'])) {
|
||||||
if (in_array('deleted_at', $fields)) $data['deleted_at'] = date('Y-m-d H:i:s');
|
if (in_array('deleted_at', $fields)) {
|
||||||
if (in_array('deleted_time', $fields)) $data['deleted_time'] = time();
|
$data['deleted_at'] = date('Y-m-d H:i:s');
|
||||||
|
}
|
||||||
|
if (in_array('deleted_time', $fields)) {
|
||||||
|
$data['deleted_time'] = time();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,7 +93,7 @@ class DeleteHelper extends Helper
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 结果回调处理
|
// 结果回调处理
|
||||||
if (false === $this->class->callback('_delete_result', $result)) {
|
if ($this->class->callback('_delete_result', $result) === false) {
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,48 +1,52 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// +----------------------------------------------------------------------
|
declare(strict_types=1);
|
||||||
// | Library for ThinkAdmin
|
/**
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 版权所有 2014~2025 ThinkAdmin [ thinkadmin.top ]
|
* | Payment Plugin for ThinkAdmin
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 官方网站: https://thinkadmin.top
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 开源协议 ( https://mit-license.org )
|
* | 官方网站: https://thinkadmin.top
|
||||||
// | 免费声明 ( https://thinkadmin.top/disclaimer )
|
* +----------------------------------------------------------------------
|
||||||
// +----------------------------------------------------------------------
|
* | 开源协议 ( https://mit-license.org )
|
||||||
// | gitee 仓库地址 :https://gitee.com/zoujingli/ThinkLibrary
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
// | github 仓库地址 :https://github.com/zoujingli/ThinkLibrary
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
declare (strict_types=1);
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
namespace think\admin\helper;
|
namespace think\admin\helper;
|
||||||
|
|
||||||
|
use think\admin\Exception;
|
||||||
use think\admin\Helper;
|
use think\admin\Helper;
|
||||||
use think\admin\service\SystemService;
|
use think\admin\service\SystemService;
|
||||||
use think\db\BaseQuery;
|
use think\db\BaseQuery;
|
||||||
|
use think\db\exception\DataNotFoundException;
|
||||||
|
use think\db\exception\DbException;
|
||||||
|
use think\db\exception\ModelNotFoundException;
|
||||||
use think\Model;
|
use think\Model;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 表单视图管理器
|
* 表单视图管理器.
|
||||||
* @class FormHelper
|
* @class FormHelper
|
||||||
* @package think\admin\helper
|
|
||||||
*/
|
*/
|
||||||
class FormHelper extends Helper
|
class FormHelper extends Helper
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 逻辑器初始化
|
* 逻辑器初始化.
|
||||||
* @param BaseQuery|Model|string $dbQuery
|
* @param BaseQuery|Model|string $dbQuery
|
||||||
* @param string $template 视图模板名称
|
* @param string $template 视图模板名称
|
||||||
* @param string $field 指定数据主键
|
* @param string $field 指定数据主键
|
||||||
* @param mixed $where 限定更新条件
|
* @param mixed $where 限定更新条件
|
||||||
* @param array $edata 表单扩展数据
|
* @param array $edata 表单扩展数据
|
||||||
* @return void|array|boolean
|
* @return array|bool|void
|
||||||
* @throws \think\admin\Exception
|
* @throws Exception
|
||||||
* @throws \think\db\exception\DataNotFoundException
|
* @throws DataNotFoundException
|
||||||
* @throws \think\db\exception\DbException
|
* @throws DbException
|
||||||
* @throws \think\db\exception\ModelNotFoundException
|
* @throws ModelNotFoundException
|
||||||
*/
|
*/
|
||||||
public function init($dbQuery, string $template = '', string $field = '', $where = [], array $edata = [])
|
public function init($dbQuery, string $template = '', string $field = '', $where = [], array $edata = [])
|
||||||
{
|
{
|
||||||
@ -52,10 +56,12 @@ class FormHelper extends Helper
|
|||||||
if ($this->app->request->isGet()) {
|
if ($this->app->request->isGet()) {
|
||||||
if ($value !== null) {
|
if ($value !== null) {
|
||||||
$exist = $query->where([$field => $value])->where($where)->find();
|
$exist = $query->where([$field => $value])->where($where)->find();
|
||||||
if ($exist instanceof Model) $exist = $exist->toArray();
|
if ($exist instanceof Model) {
|
||||||
|
$exist = $exist->toArray();
|
||||||
|
}
|
||||||
$edata = array_merge($edata, $exist ?: []);
|
$edata = array_merge($edata, $exist ?: []);
|
||||||
}
|
}
|
||||||
if (false !== $this->class->callback('_form_filter', $edata)) {
|
if ($this->class->callback('_form_filter', $edata) !== false) {
|
||||||
$this->class->fetch($template, ['vo' => $edata]);
|
$this->class->fetch($template, ['vo' => $edata]);
|
||||||
} else {
|
} else {
|
||||||
return $edata;
|
return $edata;
|
||||||
@ -63,9 +69,9 @@ class FormHelper extends Helper
|
|||||||
}
|
}
|
||||||
if ($this->app->request->isPost()) {
|
if ($this->app->request->isPost()) {
|
||||||
$edata = array_merge($this->app->request->post(), $edata);
|
$edata = array_merge($this->app->request->post(), $edata);
|
||||||
if (false !== $this->class->callback('_form_filter', $edata, $where)) {
|
if ($this->class->callback('_form_filter', $edata, $where) !== false) {
|
||||||
$result = SystemService::save($query, $edata, $field, $where) !== false;
|
$result = SystemService::save($query, $edata, $field, $where) !== false;
|
||||||
if (false !== $this->class->callback('_form_result', $result, $edata)) {
|
if ($this->class->callback('_form_result', $result, $edata) !== false) {
|
||||||
if ($result !== false) {
|
if ($result !== false) {
|
||||||
$this->class->success('数据保存成功!');
|
$this->class->success('数据保存成功!');
|
||||||
} else {
|
} else {
|
||||||
@ -76,4 +82,4 @@ class FormHelper extends Helper
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,20 +1,22 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// +----------------------------------------------------------------------
|
declare(strict_types=1);
|
||||||
// | Library for ThinkAdmin
|
/**
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 版权所有 2014~2025 ThinkAdmin [ thinkadmin.top ]
|
* | Payment Plugin for ThinkAdmin
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 官方网站: https://thinkadmin.top
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 开源协议 ( https://mit-license.org )
|
* | 官方网站: https://thinkadmin.top
|
||||||
// | 免费声明 ( https://thinkadmin.top/disclaimer )
|
* +----------------------------------------------------------------------
|
||||||
// +----------------------------------------------------------------------
|
* | 开源协议 ( https://mit-license.org )
|
||||||
// | gitee 仓库地址 :https://gitee.com/zoujingli/ThinkLibrary
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
// | github 仓库地址 :https://github.com/zoujingli/ThinkLibrary
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
declare (strict_types=1);
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
namespace think\admin\helper;
|
namespace think\admin\helper;
|
||||||
|
|
||||||
@ -22,29 +24,30 @@ use think\admin\Helper;
|
|||||||
use think\admin\Library;
|
use think\admin\Library;
|
||||||
use think\admin\service\AdminService;
|
use think\admin\service\AdminService;
|
||||||
use think\db\BaseQuery;
|
use think\db\BaseQuery;
|
||||||
|
use think\db\exception\DataNotFoundException;
|
||||||
|
use think\db\exception\DbException;
|
||||||
|
use think\db\exception\ModelNotFoundException;
|
||||||
use think\db\Query;
|
use think\db\Query;
|
||||||
use think\exception\HttpResponseException;
|
use think\exception\HttpResponseException;
|
||||||
use think\Model;
|
use think\Model;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 列表处理管理器
|
* 列表处理管理器.
|
||||||
* @class PageHelper
|
* @class PageHelper
|
||||||
* @package think\admin\helper
|
|
||||||
*/
|
*/
|
||||||
class PageHelper extends Helper
|
class PageHelper extends Helper
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* 逻辑器初始化
|
* 逻辑器初始化.
|
||||||
* @param BaseQuery|Model|string $dbQuery
|
* @param BaseQuery|Model|string $dbQuery
|
||||||
* @param boolean|integer $page 是否分页或指定分页
|
* @param bool|int $page 是否分页或指定分页
|
||||||
* @param boolean $display 是否渲染模板
|
* @param bool $display 是否渲染模板
|
||||||
* @param boolean|integer $total 集合分页记录数
|
* @param bool|int $total 集合分页记录数
|
||||||
* @param integer $limit 集合每页记录数
|
* @param int $limit 集合每页记录数
|
||||||
* @param string $template 模板文件名称
|
* @param string $template 模板文件名称
|
||||||
* @return array
|
* @throws DataNotFoundException
|
||||||
* @throws \think\db\exception\DataNotFoundException
|
* @throws DbException
|
||||||
* @throws \think\db\exception\DbException
|
* @throws ModelNotFoundException
|
||||||
* @throws \think\db\exception\ModelNotFoundException
|
|
||||||
*/
|
*/
|
||||||
public function init($dbQuery, $page = true, bool $display = true, $total = false, int $limit = 0, string $template = ''): array
|
public function init($dbQuery, $page = true, bool $display = true, $total = false, int $limit = 0, string $template = ''): array
|
||||||
{
|
{
|
||||||
@ -62,15 +65,19 @@ class PageHelper extends Helper
|
|||||||
$prefix = $inner ? (sysuri('admin/index/index') . '#') : '';
|
$prefix = $inner ? (sysuri('admin/index/index') . '#') : '';
|
||||||
// 生成分页数据
|
// 生成分页数据
|
||||||
$config = ['list_rows' => $limit, 'query' => $get];
|
$config = ['list_rows' => $limit, 'query' => $get];
|
||||||
if (is_numeric($page)) $config['page'] = $page;
|
if (is_numeric($page)) {
|
||||||
|
$config['page'] = $page;
|
||||||
|
}
|
||||||
$data = ($paginate = $query->paginate($config, $this->getCount($query, $total)))->toArray();
|
$data = ($paginate = $query->paginate($config, $this->getCount($query, $total)))->toArray();
|
||||||
$result = ['page' => ['limit' => $data['per_page'], 'total' => $data['total'], 'pages' => $data['last_page'], 'current' => $data['current_page']], 'list' => $data['data']];
|
$result = ['page' => ['limit' => $data['per_page'], 'total' => $data['total'], 'pages' => $data['last_page'], 'current' => $data['current_page']], 'list' => $data['data']];
|
||||||
// 分页跳转参数
|
// 分页跳转参数
|
||||||
$select = "<select onchange='location.href=this.options[this.selectedIndex].value'>";
|
$select = "<select onchange='location.href=this.options[this.selectedIndex].value'>";
|
||||||
if (in_array($limit, $limits)) foreach ($limits as $num) {
|
if (in_array($limit, $limits)) {
|
||||||
$get = array_merge($get, ['limit' => $num, 'page' => 1]);
|
foreach ($limits as $num) {
|
||||||
$url = $this->app->request->baseUrl() . '?' . http_build_query($get, '', '&', PHP_QUERY_RFC3986);
|
$get = array_merge($get, ['limit' => $num, 'page' => 1]);
|
||||||
$select .= sprintf('<option data-num="%d" value="%s" %s>%d</option>', $num, $prefix . $url, $limit === $num ? 'selected' : '', $num);
|
$url = $this->app->request->baseUrl() . '?' . http_build_query($get, '', '&', PHP_QUERY_RFC3986);
|
||||||
|
$select .= sprintf('<option data-num="%d" value="%s" %s>%d</option>', $num, $prefix . $url, $limit === $num ? 'selected' : '', $num);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
$select .= "<option selected>{$limit}</option>";
|
$select .= "<option selected>{$limit}</option>";
|
||||||
}
|
}
|
||||||
@ -80,7 +87,7 @@ class PageHelper extends Helper
|
|||||||
} else {
|
} else {
|
||||||
$result = ['list' => $query->select()->toArray()];
|
$result = ['list' => $query->select()->toArray()];
|
||||||
}
|
}
|
||||||
if (false !== $this->class->callback('_page_filter', $result['list'], $result) && $display) {
|
if ($this->class->callback('_page_filter', $result['list'], $result) !== false && $display) {
|
||||||
if ($this->output === 'get.json') {
|
if ($this->output === 'get.json') {
|
||||||
$this->class->success('JSON-DATA', $result);
|
$this->class->success('JSON-DATA', $result);
|
||||||
} else {
|
} else {
|
||||||
@ -91,13 +98,11 @@ class PageHelper extends Helper
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 组件 Layui.Table 处理
|
* 组件 Layui.Table 处理.
|
||||||
* @param BaseQuery|Model|string $dbQuery
|
* @param BaseQuery|Model|string $dbQuery
|
||||||
* @param string $template
|
* @throws DataNotFoundException
|
||||||
* @return array
|
* @throws DbException
|
||||||
* @throws \think\db\exception\DataNotFoundException
|
* @throws ModelNotFoundException
|
||||||
* @throws \think\db\exception\DbException
|
|
||||||
* @throws \think\db\exception\ModelNotFoundException
|
|
||||||
*/
|
*/
|
||||||
public function layTable($dbQuery, string $template = ''): array
|
public function layTable($dbQuery, string $template = ''): array
|
||||||
{
|
{
|
||||||
@ -105,7 +110,7 @@ class PageHelper extends Helper
|
|||||||
$get = $this->app->request->get();
|
$get = $this->app->request->get();
|
||||||
$query = static::buildQuery($dbQuery);
|
$query = static::buildQuery($dbQuery);
|
||||||
// 根据参数排序
|
// 根据参数排序
|
||||||
if (isset($get['_field_']) && isset($get['_order_'])) {
|
if (isset($get['_field_'], $get['_order_'])) {
|
||||||
$dbQuery->order("{$get['_field_']} {$get['_order_']}");
|
$dbQuery->order("{$get['_field_']} {$get['_order_']}");
|
||||||
}
|
}
|
||||||
return PageHelper::instance()->init($query);
|
return PageHelper::instance()->init($query);
|
||||||
@ -114,7 +119,7 @@ class PageHelper extends Helper
|
|||||||
$get = $this->app->request->get();
|
$get = $this->app->request->get();
|
||||||
$query = $this->autoSortQuery($dbQuery);
|
$query = $this->autoSortQuery($dbQuery);
|
||||||
// 根据参数排序
|
// 根据参数排序
|
||||||
if (isset($get['_field_']) && isset($get['_order_'])) {
|
if (isset($get['_field_'], $get['_order_'])) {
|
||||||
$query->order("{$get['_field_']} {$get['_order_']}");
|
$query->order("{$get['_field_']} {$get['_order_']}");
|
||||||
}
|
}
|
||||||
// 数据分页处理
|
// 数据分页处理
|
||||||
@ -126,54 +131,20 @@ class PageHelper extends Helper
|
|||||||
$data = $query->paginate($cfg, static::getCount($query))->toArray();
|
$data = $query->paginate($cfg, static::getCount($query))->toArray();
|
||||||
$result = ['msg' => '', 'code' => 0, 'count' => $data['total'], 'data' => $data['data']];
|
$result = ['msg' => '', 'code' => 0, 'count' => $data['total'], 'data' => $data['data']];
|
||||||
}
|
}
|
||||||
if (false !== $this->class->callback('_page_filter', $result['data'], $result)) {
|
if ($this->class->callback('_page_filter', $result['data'], $result) !== false) {
|
||||||
static::xssFilter($result['data']);
|
static::xssFilter($result['data']);
|
||||||
throw new HttpResponseException(json($result));
|
throw new HttpResponseException(json($result));
|
||||||
} else {
|
|
||||||
return $result;
|
|
||||||
}
|
}
|
||||||
} else {
|
return $result;
|
||||||
$this->class->fetch($template);
|
|
||||||
return [];
|
|
||||||
}
|
}
|
||||||
}
|
$this->class->fetch($template);
|
||||||
|
return [];
|
||||||
/**
|
|
||||||
* 输出 XSS 过滤处理
|
|
||||||
* @param array $items
|
|
||||||
*/
|
|
||||||
private static function xssFilter(array &$items)
|
|
||||||
{
|
|
||||||
foreach ($items as &$item) if (is_array($item)) {
|
|
||||||
static::xssFilter($item);
|
|
||||||
} elseif (is_string($item)) {
|
|
||||||
$item = htmlspecialchars($item, ENT_QUOTES);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询对象数量统计
|
|
||||||
* @param BaseQuery|Query $query
|
|
||||||
* @param boolean|integer $total
|
|
||||||
* @return integer|boolean|string
|
|
||||||
* @throws \think\db\exception\DbException
|
|
||||||
*/
|
|
||||||
private static function getCount($query, $total = false)
|
|
||||||
{
|
|
||||||
if ($total === true || is_numeric($total)) return $total;
|
|
||||||
[$query, $options] = [clone $query, $query->getOptions()];
|
|
||||||
if (isset($options['order'])) $query->removeOption('order');
|
|
||||||
Library::$sapp->db->trigger('think_before_page_count', $query);
|
|
||||||
if (empty($options['union'])) return $query->count();
|
|
||||||
$table = [$query->buildSql() => '_union_count_'];
|
|
||||||
return $query->newQuery()->table($table)->count();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 绑定排序并返回操作对象
|
* 绑定排序并返回操作对象
|
||||||
* @param BaseQuery|Model|string $dbQuery
|
* @param BaseQuery|Model|string $dbQuery
|
||||||
* @param string $field 指定排序字段
|
* @param string $field 指定排序字段
|
||||||
* @return \think\db\Query
|
|
||||||
*/
|
*/
|
||||||
public function autoSortQuery($dbQuery, string $field = 'sort'): Query
|
public function autoSortQuery($dbQuery, string $field = 'sort'): Query
|
||||||
{
|
{
|
||||||
@ -196,4 +167,42 @@ class PageHelper extends Helper
|
|||||||
}
|
}
|
||||||
return $query;
|
return $query;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
/**
|
||||||
|
* 输出 XSS 过滤处理.
|
||||||
|
*/
|
||||||
|
private static function xssFilter(array &$items)
|
||||||
|
{
|
||||||
|
foreach ($items as &$item) {
|
||||||
|
if (is_array($item)) {
|
||||||
|
static::xssFilter($item);
|
||||||
|
} elseif (is_string($item)) {
|
||||||
|
$item = htmlspecialchars($item, ENT_QUOTES);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询对象数量统计
|
||||||
|
* @param BaseQuery|Query $query
|
||||||
|
* @param bool|int $total
|
||||||
|
* @return bool|int|string
|
||||||
|
* @throws DbException
|
||||||
|
*/
|
||||||
|
private static function getCount($query, $total = false)
|
||||||
|
{
|
||||||
|
if ($total === true || is_numeric($total)) {
|
||||||
|
return $total;
|
||||||
|
}
|
||||||
|
[$query, $options] = [clone $query, $query->getOptions()];
|
||||||
|
if (isset($options['order'])) {
|
||||||
|
$query->removeOption('order');
|
||||||
|
}
|
||||||
|
Library::$sapp->db->trigger('think_before_page_count', $query);
|
||||||
|
if (empty($options['union'])) {
|
||||||
|
return $query->count();
|
||||||
|
}
|
||||||
|
$table = [$query->buildSql() => '_union_count_'];
|
||||||
|
return $query->newQuery()->table($table)->count();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -1,20 +1,22 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// +----------------------------------------------------------------------
|
declare(strict_types=1);
|
||||||
// | Library for ThinkAdmin
|
/**
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 版权所有 2014~2025 ThinkAdmin [ thinkadmin.top ]
|
* | Payment Plugin for ThinkAdmin
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 官方网站: https://thinkadmin.top
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 开源协议 ( https://mit-license.org )
|
* | 官方网站: https://thinkadmin.top
|
||||||
// | 免费声明 ( https://thinkadmin.top/disclaimer )
|
* +----------------------------------------------------------------------
|
||||||
// +----------------------------------------------------------------------
|
* | 开源协议 ( https://mit-license.org )
|
||||||
// | gitee 仓库地址 :https://gitee.com/zoujingli/ThinkLibrary
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
// | github 仓库地址 :https://github.com/zoujingli/ThinkLibrary
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
declare (strict_types=1);
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
namespace think\admin\helper;
|
namespace think\admin\helper;
|
||||||
|
|
||||||
@ -22,45 +24,73 @@ use think\admin\Helper;
|
|||||||
use think\admin\service\SystemService;
|
use think\admin\service\SystemService;
|
||||||
use think\Container;
|
use think\Container;
|
||||||
use think\db\BaseQuery;
|
use think\db\BaseQuery;
|
||||||
|
use think\db\exception\DataNotFoundException;
|
||||||
|
use think\db\exception\DbException;
|
||||||
|
use think\db\exception\ModelNotFoundException;
|
||||||
use think\db\Query;
|
use think\db\Query;
|
||||||
use think\Model;
|
use think\Model;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 搜索条件处理器
|
* 搜索条件处理器.
|
||||||
* @see \think\db\Query
|
* @see Query
|
||||||
* @mixin \think\db\Query
|
* @mixin \think\db\Query
|
||||||
* @class QueryHelper
|
* @class QueryHelper
|
||||||
* @package think\admin\helper
|
|
||||||
*
|
|
||||||
* --- 动态方法调用声明
|
|
||||||
* @method bool mSave(array $data = [], string $field = '', mixed $where = []) 快捷更新
|
* @method bool mSave(array $data = [], string $field = '', mixed $where = []) 快捷更新
|
||||||
* @method bool mDelete(string $field = '', mixed $where = []) 快捷删除
|
* @method bool mDelete(string $field = '', mixed $where = []) 快捷删除
|
||||||
* @method bool|array mForm(string $tpl = '', string $field = '', mixed $where = [], array $data = []) 快捷表单
|
* @method array|bool mForm(string $tpl = '', string $field = '', mixed $where = [], array $data = []) 快捷表单
|
||||||
* @method bool|integer mUpdate(array $data = [], string $field = '', mixed $where = []) 快捷保存
|
* @method bool|int mUpdate(array $data = [], string $field = '', mixed $where = []) 快捷保存
|
||||||
*/
|
*/
|
||||||
class QueryHelper extends Helper
|
class QueryHelper extends Helper
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* 分页助手工具
|
* 分页助手工具.
|
||||||
* @var PageHelper
|
* @var PageHelper
|
||||||
*/
|
*/
|
||||||
protected $page;
|
protected $page;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 当前数据操作
|
* 当前数据操作.
|
||||||
* @var Query
|
* @var Query
|
||||||
*/
|
*/
|
||||||
protected $query;
|
protected $query;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 初始化默认数据
|
* 初始化默认数据.
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $input;
|
protected $input;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 克隆属性复制.
|
||||||
|
*/
|
||||||
|
public function __clone()
|
||||||
|
{
|
||||||
|
$this->page = clone $this->page;
|
||||||
|
$this->query = clone $this->query;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* QueryHelper call.
|
||||||
|
* @param string $name 调用方法名称
|
||||||
|
* @param array $args 调用参数内容
|
||||||
|
* @return $this|mixed
|
||||||
|
*/
|
||||||
|
public function __call(string $name, array $args)
|
||||||
|
{
|
||||||
|
return static::make($this->query, $name, $args, function ($name, $args) {
|
||||||
|
if (is_callable($callable = [$this->query, $name])) {
|
||||||
|
$value = call_user_func_array($callable, $args);
|
||||||
|
if ($name[0] === '_' || $value instanceof $this->query) {
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
return $this;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取当前Db操作对象
|
* 获取当前Db操作对象
|
||||||
* @return Query
|
|
||||||
*/
|
*/
|
||||||
public function db(): Query
|
public function db(): Query
|
||||||
{
|
{
|
||||||
@ -68,10 +98,10 @@ class QueryHelper extends Helper
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 逻辑器初始化
|
* 逻辑器初始化.
|
||||||
* @param BaseQuery|Model|string $dbQuery
|
* @param BaseQuery|Model|string $dbQuery
|
||||||
* @param string|array|null $input 输入数据
|
* @param null|array|string $input 输入数据
|
||||||
* @param callable|null $callable 初始回调
|
* @param null|callable $callable 初始回调
|
||||||
* @return $this
|
* @return $this
|
||||||
*/
|
*/
|
||||||
public function init($dbQuery, $input = null, ?callable $callable = null): QueryHelper
|
public function init($dbQuery, $input = null, ?callable $callable = null): QueryHelper
|
||||||
@ -84,10 +114,10 @@ class QueryHelper extends Helper
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置 Like 查询条件
|
* 设置 Like 查询条件.
|
||||||
* @param string|array $fields 查询字段
|
* @param array|string $fields 查询字段
|
||||||
* @param string $split 前后分割符
|
* @param string $split 前后分割符
|
||||||
* @param string|array|null $input 输入数据
|
* @param null|array|string $input 输入数据
|
||||||
* @param string $alias 别名分割符
|
* @param string $alias 别名分割符
|
||||||
* @return $this
|
* @return $this
|
||||||
*/
|
*/
|
||||||
@ -107,9 +137,9 @@ class QueryHelper extends Helper
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置 Equal 查询条件
|
* 设置 Equal 查询条件.
|
||||||
* @param string|array $fields 查询字段
|
* @param array|string $fields 查询字段
|
||||||
* @param string|array|null $input 输入类型
|
* @param null|array|string $input 输入类型
|
||||||
* @param string $alias 别名分割符
|
* @param string $alias 别名分割符
|
||||||
* @return $this
|
* @return $this
|
||||||
*/
|
*/
|
||||||
@ -129,10 +159,10 @@ class QueryHelper extends Helper
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置 IN 区间查询
|
* 设置 IN 区间查询.
|
||||||
* @param string|array $fields 查询字段
|
* @param array|string $fields 查询字段
|
||||||
* @param string $split 输入分隔符
|
* @param string $split 输入分隔符
|
||||||
* @param string|array|null $input 输入数据
|
* @param null|array|string $input 输入数据
|
||||||
* @param string $alias 别名分割符
|
* @param string $alias 别名分割符
|
||||||
* @return $this
|
* @return $this
|
||||||
*/
|
*/
|
||||||
@ -152,10 +182,10 @@ class QueryHelper extends Helper
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 两字段范围查询
|
* 两字段范围查询.
|
||||||
* @example field1:field2#field,field11:field22#field00
|
* @example field1:field2#field,field11:field22#field00
|
||||||
* @param string|array $fields 查询字段
|
* @param array|string $fields 查询字段
|
||||||
* @param string|array|null $input 输入数据
|
* @param null|array|string $input 输入数据
|
||||||
* @param string $alias 别名分割符
|
* @param string $alias 别名分割符
|
||||||
* @return $this
|
* @return $this
|
||||||
*/
|
*/
|
||||||
@ -179,10 +209,10 @@ class QueryHelper extends Helper
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置内容区间查询
|
* 设置内容区间查询.
|
||||||
* @param string|array $fields 查询字段
|
* @param array|string $fields 查询字段
|
||||||
* @param string $split 输入分隔符
|
* @param string $split 输入分隔符
|
||||||
* @param string|array|null $input 输入数据
|
* @param null|array|string $input 输入数据
|
||||||
* @param string $alias 别名分割符
|
* @param string $alias 别名分割符
|
||||||
* @return $this
|
* @return $this
|
||||||
*/
|
*/
|
||||||
@ -192,48 +222,51 @@ class QueryHelper extends Helper
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置日期时间区间查询
|
* 设置日期时间区间查询.
|
||||||
* @param string|array $fields 查询字段
|
* @param array|string $fields 查询字段
|
||||||
* @param string $split 输入分隔符
|
* @param string $split 输入分隔符
|
||||||
* @param string|array|null $input 输入数据
|
* @param null|array|string $input 输入数据
|
||||||
* @param string $alias 别名分割符
|
* @param string $alias 别名分割符
|
||||||
* @return $this
|
* @return $this
|
||||||
*/
|
*/
|
||||||
public function dateBetween($fields, string $split = ' - ', $input = null, string $alias = '#'): QueryHelper
|
public function dateBetween($fields, string $split = ' - ', $input = null, string $alias = '#'): QueryHelper
|
||||||
{
|
{
|
||||||
return $this->setBetweenWhere($fields, $split, $input, $alias, static function ($value, $type) {
|
return $this->setBetweenWhere($fields, $split, $input, $alias, static function ($value, $type) {
|
||||||
if (preg_match('#^\d{4}(-\d\d){2}\s+\d\d(:\d\d){2}$#', $value)) return $value;
|
if (preg_match('#^\d{4}(-\d\d){2}\s+\d\d(:\d\d){2}$#', $value)) {
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
return $type === 'after' ? "{$value} 23:59:59" : "{$value} 00:00:00";
|
return $type === 'after' ? "{$value} 23:59:59" : "{$value} 00:00:00";
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置时间戳区间查询
|
* 设置时间戳区间查询.
|
||||||
* @param string|array $fields 查询字段
|
* @param array|string $fields 查询字段
|
||||||
* @param string $split 输入分隔符
|
* @param string $split 输入分隔符
|
||||||
* @param string|array|null $input 输入数据
|
* @param null|array|string $input 输入数据
|
||||||
* @param string $alias 别名分割符
|
* @param string $alias 别名分割符
|
||||||
* @return $this
|
* @return $this
|
||||||
*/
|
*/
|
||||||
public function timeBetween($fields, string $split = ' - ', $input = null, string $alias = '#'): QueryHelper
|
public function timeBetween($fields, string $split = ' - ', $input = null, string $alias = '#'): QueryHelper
|
||||||
{
|
{
|
||||||
return $this->setBetweenWhere($fields, $split, $input, $alias, static function ($value, $type) {
|
return $this->setBetweenWhere($fields, $split, $input, $alias, static function ($value, $type) {
|
||||||
if (preg_match('#^\d{4}(-\d\d){2}\s+\d\d(:\d\d){2}$#', $value)) return strtotime($value);
|
if (preg_match('#^\d{4}(-\d\d){2}\s+\d\d(:\d\d){2}$#', $value)) {
|
||||||
|
return strtotime($value);
|
||||||
|
}
|
||||||
return $type === 'after' ? strtotime("{$value} 23:59:59") : strtotime("{$value} 00:00:00");
|
return $type === 'after' ? strtotime("{$value} 23:59:59") : strtotime("{$value} 00:00:00");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 实例化分页管理器
|
* 实例化分页管理器.
|
||||||
* @param boolean|integer $page 是否启用分页
|
* @param bool|int $page 是否启用分页
|
||||||
* @param boolean $display 是否渲染模板
|
* @param bool $display 是否渲染模板
|
||||||
* @param boolean|integer $total 集合分页记录数
|
* @param bool|int $total 集合分页记录数
|
||||||
* @param integer $limit 集合每页记录数
|
* @param int $limit 集合每页记录数
|
||||||
* @param string $template 模板文件名称
|
* @param string $template 模板文件名称
|
||||||
* @return array
|
* @throws DataNotFoundException
|
||||||
* @throws \think\db\exception\DataNotFoundException
|
* @throws DbException
|
||||||
* @throws \think\db\exception\DbException
|
* @throws ModelNotFoundException
|
||||||
* @throws \think\db\exception\ModelNotFoundException
|
|
||||||
*/
|
*/
|
||||||
public function page($page = true, bool $display = true, $total = false, int $limit = 0, string $template = ''): array
|
public function page($page = true, bool $display = true, $total = false, int $limit = 0, string $template = ''): array
|
||||||
{
|
{
|
||||||
@ -241,7 +274,7 @@ class QueryHelper extends Helper
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 清空数据并保留表结构
|
* 清空数据并保留表结构.
|
||||||
* @return $this
|
* @return $this
|
||||||
*/
|
*/
|
||||||
public function empty(): QueryHelper
|
public function empty(): QueryHelper
|
||||||
@ -252,17 +285,18 @@ class QueryHelper extends Helper
|
|||||||
$this->query->getConnection()->execute("truncate table `{$table}`");
|
$this->query->getConnection()->execute("truncate table `{$table}`");
|
||||||
} elseif (in_array($ctype, ['sqlsrv', 'oracle', 'pgsql'])) {
|
} elseif (in_array($ctype, ['sqlsrv', 'oracle', 'pgsql'])) {
|
||||||
$this->query->getConnection()->execute("truncate table {$table}");
|
$this->query->getConnection()->execute("truncate table {$table}");
|
||||||
} else try {
|
} else {
|
||||||
$this->query->newQuery()->whereRaw('1=1')->delete();
|
try {
|
||||||
} catch (\Throwable $exception) {
|
$this->query->newQuery()->whereRaw('1=1')->delete();
|
||||||
trace_file($exception);
|
} catch (\Throwable $exception) {
|
||||||
|
trace_file($exception);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 中间回调处理
|
* 中间回调处理.
|
||||||
* @param callable $after
|
|
||||||
* @return $this
|
* @return $this
|
||||||
*/
|
*/
|
||||||
public function filter(callable $after): QueryHelper
|
public function filter(callable $after): QueryHelper
|
||||||
@ -272,13 +306,13 @@ class QueryHelper extends Helper
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Layui.Table 组件数据
|
* Layui.Table 组件数据.
|
||||||
* @param ?callable $befor 表单前置操作
|
* @param ?callable $befor 表单前置操作
|
||||||
* @param ?callable $after 表单后置操作
|
* @param ?callable $after 表单后置操作
|
||||||
* @param string $template 视图模板文件
|
* @param string $template 视图模板文件
|
||||||
* @throws \think\db\exception\DataNotFoundException
|
* @throws DataNotFoundException
|
||||||
* @throws \think\db\exception\DbException
|
* @throws DbException
|
||||||
* @throws \think\db\exception\ModelNotFoundException
|
* @throws ModelNotFoundException
|
||||||
*/
|
*/
|
||||||
public function layTable(?callable $befor = null, ?callable $after = null, string $template = '')
|
public function layTable(?callable $befor = null, ?callable $after = null, string $template = '')
|
||||||
{
|
{
|
||||||
@ -296,12 +330,33 @@ class QueryHelper extends Helper
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置区域查询条件
|
* 快捷助手调用勾子.
|
||||||
* @param string|array $fields 查询字段
|
* @param Model|Query|string $model
|
||||||
|
* @return false|int|mixed|QueryHelper
|
||||||
|
*/
|
||||||
|
public static function make($model, string $method = 'init', array $args = [], ?callable $nohook = null)
|
||||||
|
{
|
||||||
|
$hooks = [
|
||||||
|
'mForm' => [FormHelper::class, 'init'],
|
||||||
|
'mSave' => [SaveHelper::class, 'init'],
|
||||||
|
'mQuery' => [QueryHelper::class, 'init'],
|
||||||
|
'mDelete' => [DeleteHelper::class, 'init'],
|
||||||
|
'mUpdate' => [SystemService::class, 'update'],
|
||||||
|
];
|
||||||
|
if (isset($hooks[$method])) {
|
||||||
|
[$class, $method] = $hooks[$method];
|
||||||
|
return Container::getInstance()->invokeClass($class)->{$method}($model, ...$args);
|
||||||
|
}
|
||||||
|
return is_callable($nohook) ? $nohook($method, $args) : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置区域查询条件.
|
||||||
|
* @param array|string $fields 查询字段
|
||||||
* @param string $split 输入分隔符
|
* @param string $split 输入分隔符
|
||||||
* @param string|array|null $input 输入数据
|
* @param null|array|string $input 输入数据
|
||||||
* @param string $alias 别名分割符
|
* @param string $alias 别名分割符
|
||||||
* @param callable|null $callback 回调函数
|
* @param null|callable $callback 回调函数
|
||||||
* @return $this
|
* @return $this
|
||||||
*/
|
*/
|
||||||
private function setBetweenWhere($fields, string $split = ' ', $input = null, string $alias = '#', ?callable $callback = null): QueryHelper
|
private function setBetweenWhere($fields, string $split = ' ', $input = null, string $alias = '#', ?callable $callback = null): QueryHelper
|
||||||
@ -325,74 +380,15 @@ class QueryHelper extends Helper
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取输入数据
|
* 获取输入数据.
|
||||||
* @param string|array|null $input
|
* @param null|array|string $input
|
||||||
* @return array
|
|
||||||
*/
|
*/
|
||||||
private function getInputData($input): array
|
private function getInputData($input): array
|
||||||
{
|
{
|
||||||
if (is_array($input)) {
|
if (is_array($input)) {
|
||||||
return $input;
|
return $input;
|
||||||
} else {
|
|
||||||
$input = $input ?: 'request';
|
|
||||||
return $this->app->request->$input();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 克隆属性复制
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function __clone()
|
|
||||||
{
|
|
||||||
$this->page = clone $this->page;
|
|
||||||
$this->query = clone $this->query;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* QueryHelper call.
|
|
||||||
* @param string $name 调用方法名称
|
|
||||||
* @param array $args 调用参数内容
|
|
||||||
* @return $this|mixed
|
|
||||||
*/
|
|
||||||
public function __call(string $name, array $args)
|
|
||||||
{
|
|
||||||
return static::make($this->query, $name, $args, function ($name, $args) {
|
|
||||||
if (is_callable($callable = [$this->query, $name])) {
|
|
||||||
$value = call_user_func_array($callable, $args);
|
|
||||||
if ($name[0] === '_' || $value instanceof $this->query) {
|
|
||||||
return $this;
|
|
||||||
} else {
|
|
||||||
return $value;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 快捷助手调用勾子
|
|
||||||
* @param string|Model|Query $model
|
|
||||||
* @param string $method
|
|
||||||
* @param array $args
|
|
||||||
* @param callable|null $nohook
|
|
||||||
* @return mixed|false|integer|QueryHelper
|
|
||||||
*/
|
|
||||||
public static function make($model, string $method = 'init', array $args = [], ?callable $nohook = null)
|
|
||||||
{
|
|
||||||
$hooks = [
|
|
||||||
'mForm' => [FormHelper::class, 'init'],
|
|
||||||
'mSave' => [SaveHelper::class, 'init'],
|
|
||||||
'mQuery' => [QueryHelper::class, 'init'],
|
|
||||||
'mDelete' => [DeleteHelper::class, 'init'],
|
|
||||||
'mUpdate' => [SystemService::class, 'update'],
|
|
||||||
];
|
|
||||||
if (isset($hooks[$method])) {
|
|
||||||
[$class, $method] = $hooks[$method];
|
|
||||||
return Container::getInstance()->invokeClass($class)->$method($model, ...$args);
|
|
||||||
} else {
|
|
||||||
return is_callable($nohook) ? $nohook($method, $args) : false;
|
|
||||||
}
|
}
|
||||||
|
$input = $input ?: 'request';
|
||||||
|
return $this->app->request->{$input}();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,43 +1,44 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// +----------------------------------------------------------------------
|
declare(strict_types=1);
|
||||||
// | Library for ThinkAdmin
|
/**
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 版权所有 2014~2025 ThinkAdmin [ thinkadmin.top ]
|
* | Payment Plugin for ThinkAdmin
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 官方网站: https://thinkadmin.top
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 开源协议 ( https://mit-license.org )
|
* | 官方网站: https://thinkadmin.top
|
||||||
// | 免费声明 ( https://thinkadmin.top/disclaimer )
|
* +----------------------------------------------------------------------
|
||||||
// +----------------------------------------------------------------------
|
* | 开源协议 ( https://mit-license.org )
|
||||||
// | gitee 仓库地址 :https://gitee.com/zoujingli/ThinkLibrary
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
// | github 仓库地址 :https://github.com/zoujingli/ThinkLibrary
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
declare (strict_types=1);
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
namespace think\admin\helper;
|
namespace think\admin\helper;
|
||||||
|
|
||||||
use think\admin\Helper;
|
use think\admin\Helper;
|
||||||
use think\db\BaseQuery;
|
use think\db\BaseQuery;
|
||||||
|
use think\db\exception\DbException;
|
||||||
use think\Model;
|
use think\Model;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 数据更新管理器
|
* 数据更新管理器.
|
||||||
* @class SaveHelper
|
* @class SaveHelper
|
||||||
* @package think\admin\helper
|
|
||||||
*/
|
*/
|
||||||
class SaveHelper extends Helper
|
class SaveHelper extends Helper
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 逻辑器初始化
|
* 逻辑器初始化.
|
||||||
* @param BaseQuery|Model|string $dbQuery
|
* @param BaseQuery|Model|string $dbQuery
|
||||||
* @param array $edata 表单扩展数据
|
* @param array $edata 表单扩展数据
|
||||||
* @param string $field 数据对象主键
|
* @param string $field 数据对象主键
|
||||||
* @param mixed $where 额外更新条件
|
* @param mixed $where 额外更新条件
|
||||||
* @return boolean|void
|
* @return bool|void
|
||||||
* @throws \think\db\exception\DbException
|
* @throws DbException
|
||||||
*/
|
*/
|
||||||
public function init($dbQuery, array $edata = [], string $field = '', $where = [])
|
public function init($dbQuery, array $edata = [], string $field = '', $where = [])
|
||||||
{
|
{
|
||||||
@ -49,11 +50,13 @@ class SaveHelper extends Helper
|
|||||||
// 主键限制处理
|
// 主键限制处理
|
||||||
if (!isset($where[$field]) && !is_null($value)) {
|
if (!isset($where[$field]) && !is_null($value)) {
|
||||||
$query->whereIn($field, str2arr(strval($value)));
|
$query->whereIn($field, str2arr(strval($value)));
|
||||||
if (isset($edata)) unset($edata[$field]);
|
if (isset($edata)) {
|
||||||
|
unset($edata[$field]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 前置回调处理
|
// 前置回调处理
|
||||||
if (false === $this->class->callback('_save_filter', $query, $edata)) {
|
if ($this->class->callback('_save_filter', $query, $edata) === false) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,7 +71,7 @@ class SaveHelper extends Helper
|
|||||||
|
|
||||||
// 结果回调处理
|
// 结果回调处理
|
||||||
$result = true;
|
$result = true;
|
||||||
if (false === $this->class->callback('_save_result', $result, $model)) {
|
if ($this->class->callback('_save_result', $result, $model) === false) {
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,20 +1,22 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// +----------------------------------------------------------------------
|
declare(strict_types=1);
|
||||||
// | Library for ThinkAdmin
|
/**
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 版权所有 2014~2025 ThinkAdmin [ thinkadmin.top ]
|
* | Payment Plugin for ThinkAdmin
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 官方网站: https://thinkadmin.top
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 开源协议 ( https://mit-license.org )
|
* | 官方网站: https://thinkadmin.top
|
||||||
// | 免费声明 ( https://thinkadmin.top/disclaimer )
|
* +----------------------------------------------------------------------
|
||||||
// +----------------------------------------------------------------------
|
* | 开源协议 ( https://mit-license.org )
|
||||||
// | gitee 仓库地址 :https://gitee.com/zoujingli/ThinkLibrary
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
// | github 仓库地址 :https://github.com/zoujingli/ThinkLibrary
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
declare (strict_types=1);
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
namespace think\admin\helper;
|
namespace think\admin\helper;
|
||||||
|
|
||||||
@ -23,37 +25,42 @@ use think\admin\Library;
|
|||||||
use think\exception\HttpResponseException;
|
use think\exception\HttpResponseException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 表单令牌验证器
|
* 表单令牌验证器.
|
||||||
* @class TokenHelper
|
* @class TokenHelper
|
||||||
* @package think\admin\helper
|
|
||||||
*/
|
*/
|
||||||
class TokenHelper extends Helper
|
class TokenHelper extends Helper
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* 初始化验证码器
|
* 初始化验证码器.
|
||||||
* @param boolean $return
|
* @return bool|void
|
||||||
* @return boolean|void
|
|
||||||
*/
|
*/
|
||||||
public function init(bool $return = false)
|
public function init(bool $return = false)
|
||||||
{
|
{
|
||||||
$this->class->csrf_state = true;
|
$this->class->csrf_state = true;
|
||||||
if (!$this->app->request->isPost()) return true;
|
if (!$this->app->request->isPost()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
$token = $this->app->request->post('_token_');
|
$token = $this->app->request->post('_token_');
|
||||||
$extra = ['_token_' => $token ?: $this->app->request->header('User-Form-Token')];
|
$extra = ['_token_' => $token ?: $this->app->request->header('User-Form-Token')];
|
||||||
if ($this->app->request->checkToken('_token_', $extra)) return true; elseif ($return) return false;
|
if ($this->app->request->checkToken('_token_', $extra)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if ($return) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
$this->class->error($this->class->csrf_message ?: '表单令牌验证失败!');
|
$this->class->error($this->class->csrf_message ?: '表单令牌验证失败!');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 返回视图内容
|
* 返回视图内容.
|
||||||
* @param string $tpl 模板名称
|
* @param string $tpl 模板名称
|
||||||
* @param array $vars 模板变量
|
* @param array $vars 模板变量
|
||||||
* @param string|null $node 授权节点
|
* @param null|string $node 授权节点
|
||||||
*/
|
*/
|
||||||
public static function fetch(string $tpl = '', array $vars = [], ?string $node = null)
|
public static function fetch(string $tpl = '', array $vars = [], ?string $node = null)
|
||||||
{
|
{
|
||||||
throw new HttpResponseException(view($tpl, $vars, 200, static function ($html) use ($node) {
|
throw new HttpResponseException(view($tpl, $vars, 200, static function ($html) {
|
||||||
return preg_replace_callback('/<\/form>/i', static function () use ($node) {
|
return preg_replace_callback('/<\/form>/i', static function () {
|
||||||
return sprintf("<input type='hidden' name='_token_' value='%s'></form>", static::token());
|
return sprintf("<input type='hidden' name='_token_' value='%s'></form>", static::token());
|
||||||
}, $html);
|
}, $html);
|
||||||
}));
|
}));
|
||||||
@ -61,11 +68,10 @@ class TokenHelper extends Helper
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 返回表单令牌数据
|
* 返回表单令牌数据
|
||||||
* 为了兼容JWT模式使用表单令牌
|
* 为了兼容JWT模式使用表单令牌.
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public static function token(): string
|
public static function token(): string
|
||||||
{
|
{
|
||||||
return Library::$sapp->request->buildToken('_token_');
|
return Library::$sapp->request->buildToken('_token_');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,20 +1,22 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// +----------------------------------------------------------------------
|
declare(strict_types=1);
|
||||||
// | Library for ThinkAdmin
|
/**
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 版权所有 2014~2025 ThinkAdmin [ thinkadmin.top ]
|
* | Payment Plugin for ThinkAdmin
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 官方网站: https://thinkadmin.top
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 开源协议 ( https://mit-license.org )
|
* | 官方网站: https://thinkadmin.top
|
||||||
// | 免费声明 ( https://thinkadmin.top/disclaimer )
|
* +----------------------------------------------------------------------
|
||||||
// +----------------------------------------------------------------------
|
* | 开源协议 ( https://mit-license.org )
|
||||||
// | gitee 仓库地址 :https://gitee.com/zoujingli/ThinkLibrary
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
// | github 仓库地址 :https://github.com/zoujingli/ThinkLibrary
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
declare (strict_types=1);
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
namespace think\admin\helper;
|
namespace think\admin\helper;
|
||||||
|
|
||||||
@ -22,17 +24,16 @@ use think\admin\Helper;
|
|||||||
use think\Validate;
|
use think\Validate;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 快捷输入验证器
|
* 快捷输入验证器.
|
||||||
* @class ValidateHelper
|
* @class ValidateHelper
|
||||||
* @package think\admin\helper
|
|
||||||
*/
|
*/
|
||||||
class ValidateHelper extends Helper
|
class ValidateHelper extends Helper
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* 快捷输入并验证( 支持 规则 # 别名 )
|
* 快捷输入并验证( 支持 规则 # 别名 ).
|
||||||
* @param array $rules 验证规则( 验证信息数组 )
|
* @param array $rules 验证规则( 验证信息数组 )
|
||||||
* @param string|array $input 输入内容 ( post. 或 get. )
|
* @param array|string $input 输入内容 ( post. 或 get. )
|
||||||
* @param callable|null $callable 异常处理操作
|
* @param null|callable $callable 异常处理操作
|
||||||
* @return array|void
|
* @return array|void
|
||||||
*
|
*
|
||||||
* age.require => message // 最大值限定
|
* age.require => message // 最大值限定
|
||||||
@ -47,7 +48,7 @@ class ValidateHelper extends Helper
|
|||||||
{
|
{
|
||||||
if (is_string($input)) {
|
if (is_string($input)) {
|
||||||
$type = trim($input, '.') ?: 'param';
|
$type = trim($input, '.') ?: 'param';
|
||||||
$input = $this->app->request->$type();
|
$input = $this->app->request->{$type}();
|
||||||
}
|
}
|
||||||
[$data, $rule, $info] = [[], [], []];
|
[$data, $rule, $info] = [[], [], []];
|
||||||
foreach ($rules as $key => $value) {
|
foreach ($rules as $key => $value) {
|
||||||
@ -59,8 +60,12 @@ class ValidateHelper extends Helper
|
|||||||
} elseif (preg_match('|^(.*?)\.(.*?)#(.*?)#?$|', "{$key}#", $matches)) {
|
} elseif (preg_match('|^(.*?)\.(.*?)#(.*?)#?$|', "{$key}#", $matches)) {
|
||||||
[, $_key, $_rule, $alias] = $matches;
|
[, $_key, $_rule, $alias] = $matches;
|
||||||
if (in_array($_rule, ['value', 'default'])) {
|
if (in_array($_rule, ['value', 'default'])) {
|
||||||
if ($_rule === 'value') $data[$_key] = $value;
|
if ($_rule === 'value') {
|
||||||
if ($_rule === 'default') $data[$_key] = $input[$alias ?: $_key] ?? $value;
|
$data[$_key] = $value;
|
||||||
|
}
|
||||||
|
if ($_rule === 'default') {
|
||||||
|
$data[$_key] = $input[$alias ?: $_key] ?? $value;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
$info[explode(':', "{$_key}.{$_rule}")[0]] = $value;
|
$info[explode(':', "{$_key}.{$_rule}")[0]] = $value;
|
||||||
$data[$_key] = $data[$_key] ?? ($input[$alias ?: $_key] ?? null);
|
$data[$_key] = $data[$_key] ?? ($input[$alias ?: $_key] ?? null);
|
||||||
@ -71,10 +76,10 @@ class ValidateHelper extends Helper
|
|||||||
$validate = new Validate();
|
$validate = new Validate();
|
||||||
if ($validate->rule($rule)->message($info)->check($data)) {
|
if ($validate->rule($rule)->message($info)->check($data)) {
|
||||||
return $data;
|
return $data;
|
||||||
} elseif (is_callable($callable)) {
|
|
||||||
return call_user_func($callable, lang($validate->getError()), $data);
|
|
||||||
} else {
|
|
||||||
$this->class->error(lang($validate->getError()));
|
|
||||||
}
|
}
|
||||||
|
if (is_callable($callable)) {
|
||||||
|
return call_user_func($callable, lang($validate->getError()), $data);
|
||||||
|
}
|
||||||
|
$this->class->error(lang($validate->getError()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,27 +1,28 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// +----------------------------------------------------------------------
|
|
||||||
// | Library for ThinkAdmin
|
|
||||||
// +----------------------------------------------------------------------
|
|
||||||
// | 版权所有 2014~2025 ThinkAdmin [ thinkadmin.top ]
|
|
||||||
// +----------------------------------------------------------------------
|
|
||||||
// | 官方网站: https://thinkadmin.top
|
|
||||||
// +----------------------------------------------------------------------
|
|
||||||
// | 开源协议 ( https://mit-license.org )
|
|
||||||
// | 免费声明 ( https://thinkadmin.top/disclaimer )
|
|
||||||
// +----------------------------------------------------------------------
|
|
||||||
// | gitee 仓库地址 :https://gitee.com/zoujingli/ThinkLibrary
|
|
||||||
// | github 仓库地址 :https://github.com/zoujingli/ThinkLibrary
|
|
||||||
// +----------------------------------------------------------------------
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
/**
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
* | Payment Plugin for ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
* | 官方网站: https://thinkadmin.top
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
* | 开源协议 ( https://mit-license.org )
|
||||||
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
use think\admin\Library;
|
use think\admin\Library;
|
||||||
use think\admin\model\SystemBase;
|
use think\admin\model\SystemBase;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 动态加载英文数据字典
|
* 动态加载英文数据字典
|
||||||
* 从系统数据字典中读取英文翻译,并缓存以提高性能
|
* 从系统数据字典中读取英文翻译,并缓存以提高性能.
|
||||||
*/
|
*/
|
||||||
$cacheKey = 'lang-en-us';
|
$cacheKey = 'lang-en-us';
|
||||||
$langs = Library::$sapp->cache->get($cacheKey, []);
|
$langs = Library::$sapp->cache->get($cacheKey, []);
|
||||||
@ -29,13 +30,13 @@ $langs = Library::$sapp->cache->get($cacheKey, []);
|
|||||||
if (empty($langs)) {
|
if (empty($langs)) {
|
||||||
// 从数据字典读取英文翻译
|
// 从数据字典读取英文翻译
|
||||||
$langs = array_column(SystemBase::items('英文字典'), 'name', 'code');
|
$langs = array_column(SystemBase::items('英文字典'), 'name', 'code');
|
||||||
|
|
||||||
// 读取英文菜单并合并到语言包中(使用 menus_ 前缀)
|
// 读取英文菜单并合并到语言包中(使用 menus_ 前缀)
|
||||||
$menuItems = array_column(SystemBase::items('英文菜单'), 'name', 'code');
|
$menuItems = array_column(SystemBase::items('英文菜单'), 'name', 'code');
|
||||||
foreach ($menuItems as $key => $name) {
|
foreach ($menuItems as $key => $name) {
|
||||||
$langs["menus_{$key}"] = $name;
|
$langs["menus_{$key}"] = $name;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 缓存语言包数据,有效期 360 秒
|
// 缓存语言包数据,有效期 360 秒
|
||||||
Library::$sapp->cache->set($cacheKey, $langs, 360);
|
Library::$sapp->cache->set($cacheKey, $langs, 360);
|
||||||
}
|
}
|
||||||
@ -43,43 +44,43 @@ if (empty($langs)) {
|
|||||||
/**
|
/**
|
||||||
* 静态菜单语言包定义
|
* 静态菜单语言包定义
|
||||||
* 使用固定前缀 `menus_` 开头,便于后续扩展和维护
|
* 使用固定前缀 `menus_` 开头,便于后续扩展和维护
|
||||||
* 注意:该文件仅在英文模式下才会加载,系统默认使用中文模式
|
* 注意:该文件仅在英文模式下才会加载,系统默认使用中文模式.
|
||||||
*/
|
*/
|
||||||
$menus = [
|
$menus = [
|
||||||
// 系统管理菜单
|
// 系统管理菜单
|
||||||
'menus_系统管理' => 'System',
|
'menus_系统管理' => 'System',
|
||||||
'menus_系统配置' => 'Config',
|
'menus_系统配置' => 'Config',
|
||||||
'menus_系统参数配置' => 'Params',
|
'menus_系统参数配置' => 'Params',
|
||||||
'menus_系统任务管理' => 'Tasks',
|
'menus_系统任务管理' => 'Tasks',
|
||||||
'menus_系统日志管理' => 'Logs',
|
'menus_系统日志管理' => 'Logs',
|
||||||
'menus_数据字典管理' => 'Dict',
|
'menus_数据字典管理' => 'Dict',
|
||||||
'menus_系统文件管理' => 'Files',
|
'menus_系统文件管理' => 'Files',
|
||||||
'menus_系统菜单管理' => 'Menus',
|
'menus_系统菜单管理' => 'Menus',
|
||||||
'menus_权限管理' => 'Perms',
|
'menus_权限管理' => 'Perms',
|
||||||
'menus_访问权限管理' => 'Roles',
|
'menus_访问权限管理' => 'Roles',
|
||||||
'menus_系统用户管理' => 'Users',
|
'menus_系统用户管理' => 'Users',
|
||||||
|
|
||||||
// 微信管理菜单
|
// 微信管理菜单
|
||||||
'menus_微信管理' => 'WeChat',
|
'menus_微信管理' => 'WeChat',
|
||||||
'menus_微信接口配置' => 'Config',
|
'menus_微信接口配置' => 'Config',
|
||||||
'menus_微信支付配置' => 'Pay Config',
|
'menus_微信支付配置' => 'Pay Config',
|
||||||
'menus_微信粉丝管理' => 'Fans',
|
'menus_微信粉丝管理' => 'Fans',
|
||||||
'menus_微信定制' => 'Custom',
|
'menus_微信定制' => 'Custom',
|
||||||
'menus_微信图文管理' => 'News',
|
'menus_微信图文管理' => 'News',
|
||||||
'menus_微信菜单配置' => 'Menus',
|
'menus_微信菜单配置' => 'Menus',
|
||||||
'menus_回复规则管理' => 'Rules',
|
'menus_回复规则管理' => 'Rules',
|
||||||
'menus_关注自动回复' => 'Auto Reply',
|
'menus_关注自动回复' => 'Auto Reply',
|
||||||
'menus_微信支付' => 'Payment',
|
'menus_微信支付' => 'Payment',
|
||||||
'menus_支付行为管理' => 'Actions',
|
'menus_支付行为管理' => 'Actions',
|
||||||
'menus_支付退款管理' => 'Refunds',
|
'menus_支付退款管理' => 'Refunds',
|
||||||
|
|
||||||
// 插件中心菜单
|
// 插件中心菜单
|
||||||
'menus_插件中心' => 'Plugins',
|
'menus_插件中心' => 'Plugins',
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 额外语言包配置
|
* 额外语言包配置
|
||||||
* 包含日期格式、登录提示、分页信息等特殊翻译
|
* 包含日期格式、登录提示、分页信息等特殊翻译.
|
||||||
*/
|
*/
|
||||||
$extra = [
|
$extra = [
|
||||||
'Y年m月d日 H:i:s' => 'Y/m/d H:i:s',
|
'Y年m月d日 H:i:s' => 'Y/m/d H:i:s',
|
||||||
@ -89,63 +90,63 @@ $extra = [
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 基础语言包定义
|
* 基础语言包定义
|
||||||
* 包含接口提示、存储引擎、日志记录、模块管理等翻译
|
* 包含接口提示、存储引擎、日志记录、模块管理等翻译.
|
||||||
*/
|
*/
|
||||||
$base = [
|
$base = [
|
||||||
// 接口提示内容
|
// 接口提示内容
|
||||||
'数据删除成功!' => 'Deleted successfully.',
|
'数据删除成功!' => 'Deleted successfully.',
|
||||||
'数据删除失败!' => 'Delete failed.',
|
'数据删除失败!' => 'Delete failed.',
|
||||||
'数据保存成功!' => 'Saved successfully.',
|
'数据保存成功!' => 'Saved successfully.',
|
||||||
'数据保存失败!' => 'Save failed.',
|
'数据保存失败!' => 'Save failed.',
|
||||||
'数据排序成功!' => 'Sorted successfully.',
|
'数据排序成功!' => 'Sorted successfully.',
|
||||||
'列表排序失败!' => 'Sort failed.',
|
'列表排序失败!' => 'Sort failed.',
|
||||||
'请求响应异常!' => 'Request exception.',
|
'请求响应异常!' => 'Request exception.',
|
||||||
'请求响应成功!' => 'Request successful.',
|
'请求响应成功!' => 'Request successful.',
|
||||||
'未授权禁止访问!' => 'Unauthorized access.',
|
'未授权禁止访问!' => 'Unauthorized access.',
|
||||||
'会话无效或已失效!' => 'Session invalid or expired.',
|
'会话无效或已失效!' => 'Session invalid or expired.',
|
||||||
'表单令牌验证失败!' => 'Form token validation failed.',
|
'表单令牌验证失败!' => 'Form token validation failed.',
|
||||||
'接口账号验证失败!' => 'Account verification failed.',
|
'接口账号验证失败!' => 'Account verification failed.',
|
||||||
'接口请求时差过大!' => 'Request time difference too large.',
|
'接口请求时差过大!' => 'Request time difference too large.',
|
||||||
'接口签名验证失败!' => 'Signature verification failed.',
|
'接口签名验证失败!' => 'Signature verification failed.',
|
||||||
'非JWT访问!' => 'JWT access required.',
|
'非JWT访问!' => 'JWT access required.',
|
||||||
'请求参数 %s 不能为空!' => 'Parameter %s cannot be empty.',
|
'请求参数 %s 不能为空!' => 'Parameter %s cannot be empty.',
|
||||||
'接口请求响应格式异常!' => 'Invalid response format.',
|
'接口请求响应格式异常!' => 'Invalid response format.',
|
||||||
'耗时 %.4f 秒' => 'Time: %.4f s',
|
'耗时 %.4f 秒' => 'Time: %.4f s',
|
||||||
'创建任务失败,%s' => 'Failed to create task: %s',
|
'创建任务失败,%s' => 'Failed to create task: %s',
|
||||||
'已创建请等待处理完成!' => 'Task created, please wait.',
|
'已创建请等待处理完成!' => 'Task created, please wait.',
|
||||||
'删除%s[%s]及授权配置' => 'Delete %s[%s] and authorization',
|
'删除%s[%s]及授权配置' => 'Delete %s[%s] and authorization',
|
||||||
'暂无轨迹信息~' => 'No trajectory info.',
|
'暂无轨迹信息~' => 'No trajectory info.',
|
||||||
|
|
||||||
// 存储引擎翻译
|
// 存储引擎翻译
|
||||||
'本地服务器存储' => 'Local Storage',
|
'本地服务器存储' => 'Local Storage',
|
||||||
'自建Alist存储' => 'Alist Storage',
|
'自建Alist存储' => 'Alist Storage',
|
||||||
'又拍云USS存储' => 'Upyun USS',
|
'又拍云USS存储' => 'Upyun USS',
|
||||||
'阿里云OSS存储' => 'Aliyun OSS',
|
'阿里云OSS存储' => 'Aliyun OSS',
|
||||||
'腾讯云COS存储' => 'Tencent COS',
|
'腾讯云COS存储' => 'Tencent COS',
|
||||||
'七牛云对象存储' => 'Qiniu OSS',
|
'七牛云对象存储' => 'Qiniu OSS',
|
||||||
'未配置又拍云域名' => 'Upyun domain not configured',
|
'未配置又拍云域名' => 'Upyun domain not configured',
|
||||||
'未配置阿里云域名' => 'Aliyun domain not configured',
|
'未配置阿里云域名' => 'Aliyun domain not configured',
|
||||||
'未配置七牛云域名' => 'Qiniu domain not configured',
|
'未配置七牛云域名' => 'Qiniu domain not configured',
|
||||||
'未配置腾讯云域名' => 'Tencent domain not configured',
|
'未配置腾讯云域名' => 'Tencent domain not configured',
|
||||||
'未配置Alist域名' => 'Alist domain not configured',
|
'未配置Alist域名' => 'Alist domain not configured',
|
||||||
|
|
||||||
// 默认日志翻译
|
// 默认日志翻译
|
||||||
'增加%s[%s]成功' => 'Added: %s[%s]',
|
'增加%s[%s]成功' => 'Added: %s[%s]',
|
||||||
'修改%s[%s]状态' => 'Modified: %s[%s]',
|
'修改%s[%s]状态' => 'Modified: %s[%s]',
|
||||||
'更新%s[%s]记录' => 'Updated: %s[%s]',
|
'更新%s[%s]记录' => 'Updated: %s[%s]',
|
||||||
'删除%s[%s]成功' => 'Deleted: %s[%s]',
|
'删除%s[%s]成功' => 'Deleted: %s[%s]',
|
||||||
|
|
||||||
// 模块管理翻译
|
// 模块管理翻译
|
||||||
'系统任务管理' => 'Task Management',
|
'系统任务管理' => 'Task Management',
|
||||||
'系统菜单管理' => 'Menu Management',
|
'系统菜单管理' => 'Menu Management',
|
||||||
'系统文件管理' => 'File Management',
|
'系统文件管理' => 'File Management',
|
||||||
'系统用户管理' => 'User Management',
|
'系统用户管理' => 'User Management',
|
||||||
'系统日志管理' => 'Logs Management',
|
'系统日志管理' => 'Logs Management',
|
||||||
'系统参数配置' => 'Parameter Management',
|
'系统参数配置' => 'Parameter Management',
|
||||||
'访问权限管理' => 'Permission Management',
|
'访问权限管理' => 'Permission Management',
|
||||||
'数据字典管理' => 'Dictionary Management',
|
'数据字典管理' => 'Dictionary Management',
|
||||||
'系统运维管理' => 'Maintenance Management',
|
'系统运维管理' => 'Maintenance Management',
|
||||||
];
|
];
|
||||||
|
|
||||||
// 合并所有语言包:基础翻译 -> 额外配置 -> 静态菜单 -> 动态字典
|
// 合并所有语言包:基础翻译 -> 额外配置 -> 静态菜单 -> 动态字典
|
||||||
return array_merge($base, $extra, $menus, $langs);
|
return array_merge($base, $extra, $menus, $langs);
|
||||||
|
|||||||
@ -1,27 +1,28 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// +----------------------------------------------------------------------
|
|
||||||
// | Library for ThinkAdmin
|
|
||||||
// +----------------------------------------------------------------------
|
|
||||||
// | 版权所有 2014~2025 ThinkAdmin [ thinkadmin.top ]
|
|
||||||
// +----------------------------------------------------------------------
|
|
||||||
// | 官方网站: https://thinkadmin.top
|
|
||||||
// +----------------------------------------------------------------------
|
|
||||||
// | 开源协议 ( https://mit-license.org )
|
|
||||||
// | 免费声明 ( https://thinkadmin.top/disclaimer )
|
|
||||||
// +----------------------------------------------------------------------
|
|
||||||
// | gitee 仓库地址 :https://gitee.com/zoujingli/ThinkLibrary
|
|
||||||
// | github 仓库地址 :https://github.com/zoujingli/ThinkLibrary
|
|
||||||
// +----------------------------------------------------------------------
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
/**
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
* | Payment Plugin for ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
* | 官方网站: https://thinkadmin.top
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
* | 开源协议 ( https://mit-license.org )
|
||||||
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
use think\admin\Library;
|
use think\admin\Library;
|
||||||
use think\admin\model\SystemBase;
|
use think\admin\model\SystemBase;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 動態加載繁體中文數據字典
|
* 動態加載繁體中文數據字典
|
||||||
* 從系統數據字典中讀取繁體中文翻譯,並緩存以提高性能
|
* 從系統數據字典中讀取繁體中文翻譯,並緩存以提高性能.
|
||||||
*/
|
*/
|
||||||
$cacheKey = 'lang-zh-tw';
|
$cacheKey = 'lang-zh-tw';
|
||||||
$langs = Library::$sapp->cache->get($cacheKey, []);
|
$langs = Library::$sapp->cache->get($cacheKey, []);
|
||||||
@ -29,20 +30,20 @@ $langs = Library::$sapp->cache->get($cacheKey, []);
|
|||||||
if (empty($langs)) {
|
if (empty($langs)) {
|
||||||
// 從數據字典讀取繁體中文翻譯
|
// 從數據字典讀取繁體中文翻譯
|
||||||
$langs = array_column(SystemBase::items('繁体中文'), 'name', 'code');
|
$langs = array_column(SystemBase::items('繁体中文'), 'name', 'code');
|
||||||
|
|
||||||
// 讀取繁體菜單並合併到語言包中(使用 menus_ 前綴)
|
// 讀取繁體菜單並合併到語言包中(使用 menus_ 前綴)
|
||||||
$menuItems = array_column(SystemBase::items('繁体菜单'), 'name', 'code');
|
$menuItems = array_column(SystemBase::items('繁体菜单'), 'name', 'code');
|
||||||
foreach ($menuItems as $key => $name) {
|
foreach ($menuItems as $key => $name) {
|
||||||
$langs["menus_{$key}"] = $name;
|
$langs["menus_{$key}"] = $name;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 緩存語言包數據,有效期 360 秒
|
// 緩存語言包數據,有效期 360 秒
|
||||||
Library::$sapp->cache->set($cacheKey, $langs, 360);
|
Library::$sapp->cache->set($cacheKey, $langs, 360);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 額外語言包配置
|
* 額外語言包配置
|
||||||
* 包含日期格式、登錄提示、分頁信息等特殊翻譯
|
* 包含日期格式、登錄提示、分頁信息等特殊翻譯.
|
||||||
*/
|
*/
|
||||||
$extra = [
|
$extra = [
|
||||||
'Y年m月d日 H:i:s' => 'Y年m月d日 H:i:s',
|
'Y年m月d日 H:i:s' => 'Y年m月d日 H:i:s',
|
||||||
@ -52,63 +53,63 @@ $extra = [
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 基礎語言包定義
|
* 基礎語言包定義
|
||||||
* 包含接口提示、存儲引擎、日誌記錄、模塊管理等翻譯
|
* 包含接口提示、存儲引擎、日誌記錄、模塊管理等翻譯.
|
||||||
*/
|
*/
|
||||||
$base = [
|
$base = [
|
||||||
// 接口提示內容
|
// 接口提示內容
|
||||||
'数据删除成功!' => '數據刪除成功!',
|
'数据删除成功!' => '數據刪除成功!',
|
||||||
'数据删除失败!' => '數據刪除失敗!',
|
'数据删除失败!' => '數據刪除失敗!',
|
||||||
'数据保存成功!' => '數據保存成功!',
|
'数据保存成功!' => '數據保存成功!',
|
||||||
'数据保存失败!' => '數據保存失敗!',
|
'数据保存失败!' => '數據保存失敗!',
|
||||||
'数据排序成功!' => '數據排序成功!',
|
'数据排序成功!' => '數據排序成功!',
|
||||||
'列表排序失败!' => '列表排序失敗!',
|
'列表排序失败!' => '列表排序失敗!',
|
||||||
'请求响应异常!' => '請求響應異常!',
|
'请求响应异常!' => '請求響應異常!',
|
||||||
'请求响应成功!' => '請求響應成功!',
|
'请求响应成功!' => '請求響應成功!',
|
||||||
'未授权禁止访问!' => '未授權禁止訪問!',
|
'未授权禁止访问!' => '未授權禁止訪問!',
|
||||||
'会话无效或已失效!' => '會話無效或已失效!',
|
'会话无效或已失效!' => '會話無效或已失效!',
|
||||||
'表单令牌验证失败!' => '表單令牌驗證失敗!',
|
'表单令牌验证失败!' => '表單令牌驗證失敗!',
|
||||||
'接口账号验证失败!' => '接口賬號驗證失敗!',
|
'接口账号验证失败!' => '接口賬號驗證失敗!',
|
||||||
'接口请求时差过大!' => '接口請求時差過大!',
|
'接口请求时差过大!' => '接口請求時差過大!',
|
||||||
'接口签名验证失败!' => '接口簽名驗證失敗!',
|
'接口签名验证失败!' => '接口簽名驗證失敗!',
|
||||||
'非JWT访问!' => '請使用 JWT 方式訪問!',
|
'非JWT访问!' => '請使用 JWT 方式訪問!',
|
||||||
'请求参数 %s 不能为空!' => '請求參數 %s 不能爲空!',
|
'请求参数 %s 不能为空!' => '請求參數 %s 不能爲空!',
|
||||||
'接口请求响应格式异常!' => '接口請求響應格式異常!',
|
'接口请求响应格式异常!' => '接口請求響應格式異常!',
|
||||||
'耗时 %.4f 秒' => '耗時 %.4f 秒',
|
'耗时 %.4f 秒' => '耗時 %.4f 秒',
|
||||||
'创建任务失败,%s' => '創建任務失敗,%s',
|
'创建任务失败,%s' => '創建任務失敗,%s',
|
||||||
'已创建请等待处理完成!' => '已創建請等待處理完成!',
|
'已创建请等待处理完成!' => '已創建請等待處理完成!',
|
||||||
'删除%s[%s]及授权配置' => '刪除%s[%s]及授權配置',
|
'删除%s[%s]及授权配置' => '刪除%s[%s]及授權配置',
|
||||||
'暂无轨迹信息~' => '暫無軌迹信息~',
|
'暂无轨迹信息~' => '暫無軌迹信息~',
|
||||||
|
|
||||||
// 存儲引擎翻譯
|
// 存儲引擎翻譯
|
||||||
'本地服务器存储' => '本地服務器存儲',
|
'本地服务器存储' => '本地服務器存儲',
|
||||||
'自建Alist存储' => '自建Alist存儲',
|
'自建Alist存储' => '自建Alist存儲',
|
||||||
'又拍云USS存储' => '又拍雲USS存儲',
|
'又拍云USS存储' => '又拍雲USS存儲',
|
||||||
'阿里云OSS存储' => '阿裏雲OSS存儲',
|
'阿里云OSS存储' => '阿裏雲OSS存儲',
|
||||||
'腾讯云COS存储' => '騰訊雲COS存儲',
|
'腾讯云COS存储' => '騰訊雲COS存儲',
|
||||||
'七牛云对象存储' => '七牛雲對象存儲',
|
'七牛云对象存储' => '七牛雲對象存儲',
|
||||||
'未配置又拍云域名' => '未配置又拍雲域名',
|
'未配置又拍云域名' => '未配置又拍雲域名',
|
||||||
'未配置阿里云域名' => '未配置阿裏雲域名',
|
'未配置阿里云域名' => '未配置阿裏雲域名',
|
||||||
'未配置七牛云域名' => '未配置七牛雲域名',
|
'未配置七牛云域名' => '未配置七牛雲域名',
|
||||||
'未配置腾讯云域名' => '未配置騰訊雲域名',
|
'未配置腾讯云域名' => '未配置騰訊雲域名',
|
||||||
'未配置Alist域名' => '未配置Alist域名',
|
'未配置Alist域名' => '未配置Alist域名',
|
||||||
|
|
||||||
// 默認日誌翻譯
|
// 默認日誌翻譯
|
||||||
'增加%s[%s]成功' => '增加%s[%s]成功',
|
'增加%s[%s]成功' => '增加%s[%s]成功',
|
||||||
'修改%s[%s]状态' => '修改%s[%s]狀態',
|
'修改%s[%s]状态' => '修改%s[%s]狀態',
|
||||||
'更新%s[%s]记录' => '更新%s[%s]記錄',
|
'更新%s[%s]记录' => '更新%s[%s]記錄',
|
||||||
'删除%s[%s]成功' => '刪除%s[%s]成功',
|
'删除%s[%s]成功' => '刪除%s[%s]成功',
|
||||||
|
|
||||||
// 模塊管理翻譯
|
// 模塊管理翻譯
|
||||||
'系统任务管理' => '系統任務管理',
|
'系统任务管理' => '系統任務管理',
|
||||||
'系统菜单管理' => '系統菜單管理',
|
'系统菜单管理' => '系統菜單管理',
|
||||||
'系统文件管理' => '系統文件管理',
|
'系统文件管理' => '系統文件管理',
|
||||||
'系统用户管理' => '系統用戶管理',
|
'系统用户管理' => '系統用戶管理',
|
||||||
'系统日志管理' => '系統日誌管理',
|
'系统日志管理' => '系統日誌管理',
|
||||||
'系统参数配置' => '系統參數配置',
|
'系统参数配置' => '系統參數配置',
|
||||||
'访问权限管理' => '訪問權限管理',
|
'访问权限管理' => '訪問權限管理',
|
||||||
'数据字典管理' => '數據字典管理',
|
'数据字典管理' => '數據字典管理',
|
||||||
'系统运维管理' => '系統運維管理',
|
'系统运维管理' => '系統運維管理',
|
||||||
];
|
];
|
||||||
|
|
||||||
// 合併所有語言包:基礎翻譯 -> 額外配置 -> 動態字典
|
// 合併所有語言包:基礎翻譯 -> 額外配置 -> 動態字典
|
||||||
return array_merge($base, $extra, $langs);
|
return array_merge($base, $extra, $langs);
|
||||||
|
|||||||
@ -1,27 +1,32 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// +----------------------------------------------------------------------
|
declare(strict_types=1);
|
||||||
// | Library for ThinkAdmin
|
/**
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 版权所有 2014~2025 ThinkAdmin [ thinkadmin.top ]
|
* | Payment Plugin for ThinkAdmin
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 官方网站: https://thinkadmin.top
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 开源协议 ( https://mit-license.org )
|
* | 官方网站: https://thinkadmin.top
|
||||||
// | 免费声明 ( https://thinkadmin.top/disclaimer )
|
* +----------------------------------------------------------------------
|
||||||
// +----------------------------------------------------------------------
|
* | 开源协议 ( https://mit-license.org )
|
||||||
// | gitee 仓库地址 :https://gitee.com/zoujingli/ThinkLibrary
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
// | github 仓库地址 :https://github.com/zoujingli/ThinkLibrary
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
declare (strict_types=1);
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
namespace think\admin\model;
|
namespace think\admin\model;
|
||||||
|
|
||||||
use think\admin\Model;
|
use think\admin\Model;
|
||||||
|
use think\db\exception\DataNotFoundException;
|
||||||
|
use think\db\exception\DbException;
|
||||||
|
use think\db\exception\ModelNotFoundException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用户权限模型
|
* 用户权限模型.
|
||||||
*
|
*
|
||||||
* @property int $id
|
* @property int $id
|
||||||
* @property int $sort 排序权重
|
* @property int $sort 排序权重
|
||||||
@ -31,31 +36,30 @@ use think\admin\Model;
|
|||||||
* @property string $title 权限名称
|
* @property string $title 权限名称
|
||||||
* @property string $utype 身份权限
|
* @property string $utype 身份权限
|
||||||
* @class SystemAuth
|
* @class SystemAuth
|
||||||
* @package think\admin\model
|
|
||||||
*/
|
*/
|
||||||
class SystemAuth extends Model
|
class SystemAuth extends Model
|
||||||
{
|
{
|
||||||
protected $createTime = 'create_at';
|
protected $createTime = 'create_at';
|
||||||
|
|
||||||
protected $updateTime = false;
|
protected $updateTime = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 日志名称
|
* 日志名称.
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
protected $oplogName = '系统权限';
|
protected $oplogName = '系统权限';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 日志类型
|
* 日志类型.
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
protected $oplogType = '系统权限管理';
|
protected $oplogType = '系统权限管理';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取权限数据
|
* 获取权限数据.
|
||||||
* @return array
|
* @throws DataNotFoundException
|
||||||
* @throws \think\db\exception\DataNotFoundException
|
* @throws DbException
|
||||||
* @throws \think\db\exception\DbException
|
* @throws ModelNotFoundException
|
||||||
* @throws \think\db\exception\ModelNotFoundException
|
|
||||||
*/
|
*/
|
||||||
public static function items(): array
|
public static function items(): array
|
||||||
{
|
{
|
||||||
@ -63,22 +67,22 @@ class SystemAuth extends Model
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 删除权限事件
|
* 删除权限事件.
|
||||||
* @param string $ids
|
|
||||||
*/
|
*/
|
||||||
public function onAdminDelete(string $ids)
|
public function onAdminDelete(string $ids)
|
||||||
{
|
{
|
||||||
if (count($aids = str2arr($ids)) > 0) SystemNode::mk()->whereIn('auth', $aids)->delete();
|
if (count($aids = str2arr($ids)) > 0) {
|
||||||
sysoplog($this->oplogType, lang("删除%s[%s]及授权配置", [lang($this->oplogName), $ids]));
|
SystemNode::mk()->whereIn('auth', $aids)->delete();
|
||||||
|
}
|
||||||
|
sysoplog($this->oplogType, lang('删除%s[%s]及授权配置', [lang($this->oplogName), $ids]));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 格式化创建时间
|
* 格式化创建时间.
|
||||||
* @param mixed $value
|
* @param mixed $value
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public function getCreateAtAttr($value): string
|
public function getCreateAtAttr($value): string
|
||||||
{
|
{
|
||||||
return format_datetime($value);
|
return format_datetime($value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,27 +1,29 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// +----------------------------------------------------------------------
|
declare(strict_types=1);
|
||||||
// | Library for ThinkAdmin
|
/**
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 版权所有 2014~2025 ThinkAdmin [ thinkadmin.top ]
|
* | Payment Plugin for ThinkAdmin
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 官方网站: https://thinkadmin.top
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 开源协议 ( https://mit-license.org )
|
* | 官方网站: https://thinkadmin.top
|
||||||
// | 免费声明 ( https://thinkadmin.top/disclaimer )
|
* +----------------------------------------------------------------------
|
||||||
// +----------------------------------------------------------------------
|
* | 开源协议 ( https://mit-license.org )
|
||||||
// | gitee 仓库地址 :https://gitee.com/zoujingli/ThinkLibrary
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
// | github 仓库地址 :https://github.com/zoujingli/ThinkLibrary
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
declare (strict_types=1);
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
namespace think\admin\model;
|
namespace think\admin\model;
|
||||||
|
|
||||||
use think\admin\Model;
|
use think\admin\Model;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 数据字典模型
|
* 数据字典模型.
|
||||||
*
|
*
|
||||||
* @property int $deleted 删除状态(0正常,1已删)
|
* @property int $deleted 删除状态(0正常,1已删)
|
||||||
* @property int $deleted_by 删除用户
|
* @property int $deleted_by 删除用户
|
||||||
@ -35,60 +37,63 @@ use think\admin\Model;
|
|||||||
* @property string $name 数据名称
|
* @property string $name 数据名称
|
||||||
* @property string $type 数据类型
|
* @property string $type 数据类型
|
||||||
* @class SystemBase
|
* @class SystemBase
|
||||||
* @package think\admin\model
|
|
||||||
*/
|
*/
|
||||||
class SystemBase extends Model
|
class SystemBase extends Model
|
||||||
{
|
{
|
||||||
protected $createTime = 'create_at';
|
protected $createTime = 'create_at';
|
||||||
|
|
||||||
protected $updateTime = false;
|
protected $updateTime = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 日志名称
|
* 日志名称.
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
protected $oplogName = '数据字典';
|
protected $oplogName = '数据字典';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 日志类型
|
* 日志类型.
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
protected $oplogType = '数据字典管理';
|
protected $oplogType = '数据字典管理';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取指定数据列表
|
* 获取指定数据列表.
|
||||||
* @param string $type 数据类型
|
* @param string $type 数据类型
|
||||||
* @param array $data 外围数据
|
* @param array $data 外围数据
|
||||||
* @param string $field 外链字段
|
* @param string $field 外链字段
|
||||||
* @param string $bind 绑定字段
|
* @param string $bind 绑定字段
|
||||||
* @return array
|
|
||||||
*/
|
*/
|
||||||
public static function items(string $type, array &$data = [], string $field = 'base_code', string $bind = 'base_info'): array
|
public static function items(string $type, array &$data = [], string $field = 'base_code', string $bind = 'base_info'): array
|
||||||
{
|
{
|
||||||
$map = ['type' => $type, 'status' => 1, 'deleted' => 0];
|
$map = ['type' => $type, 'status' => 1, 'deleted' => 0];
|
||||||
$bases = static::mk()->where($map)->order('sort desc,id asc')->column('code,name,content', 'code');
|
$bases = static::mk()->where($map)->order('sort desc,id asc')->column('code,name,content', 'code');
|
||||||
if (count($data) > 0) foreach ($data as &$vo) $vo[$bind] = $bases[$vo[$field]] ?? [];
|
if (count($data) > 0) {
|
||||||
|
foreach ($data as &$vo) {
|
||||||
|
$vo[$bind] = $bases[$vo[$field]] ?? [];
|
||||||
|
}
|
||||||
|
}
|
||||||
return $bases;
|
return $bases;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取所有数据类型
|
* 获取所有数据类型.
|
||||||
* @param boolean $simple 加载默认值
|
* @param bool $simple 加载默认值
|
||||||
* @return array
|
|
||||||
*/
|
*/
|
||||||
public static function types(bool $simple = false): array
|
public static function types(bool $simple = false): array
|
||||||
{
|
{
|
||||||
$types = static::mk()->where(['deleted' => 0])->distinct()->column('type');
|
$types = static::mk()->where(['deleted' => 0])->distinct()->column('type');
|
||||||
if (empty($types) && empty($simple)) $types = ['身份权限'];
|
if (empty($types) && empty($simple)) {
|
||||||
|
$types = ['身份权限'];
|
||||||
|
}
|
||||||
return $types;
|
return $types;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 格式化创建时间
|
* 格式化创建时间.
|
||||||
* @param mixed $value
|
* @param mixed $value
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public function getCreateAtAttr($value): string
|
public function getCreateAtAttr($value): string
|
||||||
{
|
{
|
||||||
return format_datetime($value);
|
return format_datetime($value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,37 +1,39 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// +----------------------------------------------------------------------
|
declare(strict_types=1);
|
||||||
// | Library for ThinkAdmin
|
/**
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 版权所有 2014~2025 ThinkAdmin [ thinkadmin.top ]
|
* | Payment Plugin for ThinkAdmin
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 官方网站: https://thinkadmin.top
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 开源协议 ( https://mit-license.org )
|
* | 官方网站: https://thinkadmin.top
|
||||||
// | 免费声明 ( https://thinkadmin.top/disclaimer )
|
* +----------------------------------------------------------------------
|
||||||
// +----------------------------------------------------------------------
|
* | 开源协议 ( https://mit-license.org )
|
||||||
// | gitee 仓库地址 :https://gitee.com/zoujingli/ThinkLibrary
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
// | github 仓库地址 :https://github.com/zoujingli/ThinkLibrary
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
declare (strict_types=1);
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
namespace think\admin\model;
|
namespace think\admin\model;
|
||||||
|
|
||||||
use think\admin\Model;
|
use think\admin\Model;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 系统配置模型
|
* 系统配置模型.
|
||||||
*
|
*
|
||||||
* @property int $id
|
* @property int $id
|
||||||
* @property string $name 配置名称
|
* @property string $name 配置名称
|
||||||
* @property string $type 配置分类
|
* @property string $type 配置分类
|
||||||
* @property string $value 配置内容
|
* @property string $value 配置内容
|
||||||
* @class SystemConfig
|
* @class SystemConfig
|
||||||
* @package think\admin\model
|
|
||||||
*/
|
*/
|
||||||
class SystemConfig extends Model
|
class SystemConfig extends Model
|
||||||
{
|
{
|
||||||
protected $updateTime = false;
|
protected $updateTime = false;
|
||||||
|
|
||||||
protected $createTime = false;
|
protected $createTime = false;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,27 +1,29 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// +----------------------------------------------------------------------
|
declare(strict_types=1);
|
||||||
// | Library for ThinkAdmin
|
/**
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 版权所有 2014~2025 ThinkAdmin [ thinkadmin.top ]
|
* | Payment Plugin for ThinkAdmin
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 官方网站: https://thinkadmin.top
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 开源协议 ( https://mit-license.org )
|
* | 官方网站: https://thinkadmin.top
|
||||||
// | 免费声明 ( https://thinkadmin.top/disclaimer )
|
* +----------------------------------------------------------------------
|
||||||
// +----------------------------------------------------------------------
|
* | 开源协议 ( https://mit-license.org )
|
||||||
// | gitee 仓库地址 :https://gitee.com/zoujingli/ThinkLibrary
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
// | github 仓库地址 :https://github.com/zoujingli/ThinkLibrary
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
declare (strict_types=1);
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
namespace think\admin\model;
|
namespace think\admin\model;
|
||||||
|
|
||||||
use think\admin\Model;
|
use think\admin\Model;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 系统数据模型
|
* 系统数据模型.
|
||||||
*
|
*
|
||||||
* @property int $id
|
* @property int $id
|
||||||
* @property string $create_time 创建时间
|
* @property string $create_time 创建时间
|
||||||
@ -29,8 +31,5 @@ use think\admin\Model;
|
|||||||
* @property string $update_time 更新时间
|
* @property string $update_time 更新时间
|
||||||
* @property string $value 配置值
|
* @property string $value 配置值
|
||||||
* @class SystemData
|
* @class SystemData
|
||||||
* @package think\admin\model
|
|
||||||
*/
|
*/
|
||||||
class SystemData extends Model
|
class SystemData extends Model {}
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|||||||
@ -1,20 +1,22 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// +----------------------------------------------------------------------
|
declare(strict_types=1);
|
||||||
// | Library for ThinkAdmin
|
/**
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 版权所有 2014~2025 ThinkAdmin [ thinkadmin.top ]
|
* | Payment Plugin for ThinkAdmin
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 官方网站: https://thinkadmin.top
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 开源协议 ( https://mit-license.org )
|
* | 官方网站: https://thinkadmin.top
|
||||||
// | 免费声明 ( https://thinkadmin.top/disclaimer )
|
* +----------------------------------------------------------------------
|
||||||
// +----------------------------------------------------------------------
|
* | 开源协议 ( https://mit-license.org )
|
||||||
// | gitee 仓库地址 :https://gitee.com/zoujingli/ThinkLibrary
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
// | github 仓库地址 :https://github.com/zoujingli/ThinkLibrary
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
declare (strict_types=1);
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
namespace think\admin\model;
|
namespace think\admin\model;
|
||||||
|
|
||||||
@ -41,27 +43,25 @@ use think\model\relation\HasOne;
|
|||||||
* @property string $xext 文件后缀
|
* @property string $xext 文件后缀
|
||||||
* @property string $xkey 文件路径
|
* @property string $xkey 文件路径
|
||||||
* @property string $xurl 访问链接
|
* @property string $xurl 访问链接
|
||||||
* @property-read \think\admin\model\SystemUser $user
|
* @property SystemUser $user
|
||||||
* @class SystemFile
|
* @class SystemFile
|
||||||
* @package think\admin\model
|
|
||||||
*/
|
*/
|
||||||
class SystemFile extends Model
|
class SystemFile extends Model
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* 创建字段
|
* 创建字段.
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
protected $createTime = 'create_at';
|
protected $createTime = 'create_at';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 更新字段
|
* 更新字段.
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
protected $updateTime = 'update_at';
|
protected $updateTime = 'update_at';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 关联用户数据
|
* 关联用户数据.
|
||||||
* @return \think\model\relation\HasOne
|
|
||||||
*/
|
*/
|
||||||
public function user(): HasOne
|
public function user(): HasOne
|
||||||
{
|
{
|
||||||
@ -69,9 +69,8 @@ class SystemFile extends Model
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 格式化创建时间
|
* 格式化创建时间.
|
||||||
* @param mixed $value
|
* @param mixed $value
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public function getCreateAtAttr($value): string
|
public function getCreateAtAttr($value): string
|
||||||
{
|
{
|
||||||
@ -79,12 +78,11 @@ class SystemFile extends Model
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 格式化更新时间
|
* 格式化更新时间.
|
||||||
* @param mixed $value
|
* @param mixed $value
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public function getUpdateAtAttr($value): string
|
public function getUpdateAtAttr($value): string
|
||||||
{
|
{
|
||||||
return format_datetime($value);
|
return format_datetime($value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,27 +1,29 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// +----------------------------------------------------------------------
|
declare(strict_types=1);
|
||||||
// | Library for ThinkAdmin
|
/**
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 版权所有 2014~2025 ThinkAdmin [ thinkadmin.top ]
|
* | Payment Plugin for ThinkAdmin
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 官方网站: https://thinkadmin.top
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 开源协议 ( https://mit-license.org )
|
* | 官方网站: https://thinkadmin.top
|
||||||
// | 免费声明 ( https://thinkadmin.top/disclaimer )
|
* +----------------------------------------------------------------------
|
||||||
// +----------------------------------------------------------------------
|
* | 开源协议 ( https://mit-license.org )
|
||||||
// | gitee 仓库地址 :https://gitee.com/zoujingli/ThinkLibrary
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
// | github 仓库地址 :https://github.com/zoujingli/ThinkLibrary
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
declare (strict_types=1);
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
namespace think\admin\model;
|
namespace think\admin\model;
|
||||||
|
|
||||||
use think\admin\Model;
|
use think\admin\Model;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 系统菜单模型
|
* 系统菜单模型.
|
||||||
*
|
*
|
||||||
* @property int $id
|
* @property int $id
|
||||||
* @property int $pid 上级ID
|
* @property int $pid 上级ID
|
||||||
@ -35,32 +37,31 @@ use think\admin\Model;
|
|||||||
* @property string $title 菜单名称
|
* @property string $title 菜单名称
|
||||||
* @property string $url 链接节点
|
* @property string $url 链接节点
|
||||||
* @class SystemMenu
|
* @class SystemMenu
|
||||||
* @package think\admin\model
|
|
||||||
*/
|
*/
|
||||||
class SystemMenu extends Model
|
class SystemMenu extends Model
|
||||||
{
|
{
|
||||||
protected $createTime = 'create_at';
|
protected $createTime = 'create_at';
|
||||||
|
|
||||||
protected $updateTime = false;
|
protected $updateTime = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 日志名称
|
* 日志名称.
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
protected $oplogName = '系统菜单';
|
protected $oplogName = '系统菜单';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 日志类型
|
* 日志类型.
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
protected $oplogType = '系统菜单管理';
|
protected $oplogType = '系统菜单管理';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 格式化创建时间
|
* 格式化创建时间.
|
||||||
* @param mixed $value
|
* @param mixed $value
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public function getCreateAtAttr($value): string
|
public function getCreateAtAttr($value): string
|
||||||
{
|
{
|
||||||
return format_datetime($value);
|
return format_datetime($value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,43 +1,45 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// +----------------------------------------------------------------------
|
declare(strict_types=1);
|
||||||
// | Library for ThinkAdmin
|
/**
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 版权所有 2014~2025 ThinkAdmin [ thinkadmin.top ]
|
* | Payment Plugin for ThinkAdmin
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 官方网站: https://thinkadmin.top
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 开源协议 ( https://mit-license.org )
|
* | 官方网站: https://thinkadmin.top
|
||||||
// | 免费声明 ( https://thinkadmin.top/disclaimer )
|
* +----------------------------------------------------------------------
|
||||||
// +----------------------------------------------------------------------
|
* | 开源协议 ( https://mit-license.org )
|
||||||
// | gitee 仓库地址 :https://gitee.com/zoujingli/ThinkLibrary
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
// | github 仓库地址 :https://github.com/zoujingli/ThinkLibrary
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
declare (strict_types=1);
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
namespace think\admin\model;
|
namespace think\admin\model;
|
||||||
|
|
||||||
use think\admin\Model;
|
use think\admin\Model;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 授权节点模型
|
* 授权节点模型.
|
||||||
*
|
*
|
||||||
* @property int $auth 角色
|
* @property int $auth 角色
|
||||||
* @property int $id
|
* @property int $id
|
||||||
* @property string $node 节点
|
* @property string $node 节点
|
||||||
* @class SystemNode
|
* @class SystemNode
|
||||||
* @mixin \think\db\Query
|
* @mixin \think\db\Query
|
||||||
* @package think\admin\model
|
|
||||||
*/
|
*/
|
||||||
class SystemNode extends Model
|
class SystemNode extends Model
|
||||||
{
|
{
|
||||||
protected $updateTime = false;
|
protected $updateTime = false;
|
||||||
|
|
||||||
protected $createTime = false;
|
protected $createTime = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 绑定模型名称
|
* 绑定模型名称.
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
protected $name = 'SystemAuthNode';
|
protected $name = 'SystemAuthNode';
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,27 +1,29 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// +----------------------------------------------------------------------
|
declare(strict_types=1);
|
||||||
// | Library for ThinkAdmin
|
/**
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 版权所有 2014~2025 ThinkAdmin [ thinkadmin.top ]
|
* | Payment Plugin for ThinkAdmin
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 官方网站: https://thinkadmin.top
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 开源协议 ( https://mit-license.org )
|
* | 官方网站: https://thinkadmin.top
|
||||||
// | 免费声明 ( https://thinkadmin.top/disclaimer )
|
* +----------------------------------------------------------------------
|
||||||
// +----------------------------------------------------------------------
|
* | 开源协议 ( https://mit-license.org )
|
||||||
// | gitee 仓库地址 :https://gitee.com/zoujingli/ThinkLibrary
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
// | github 仓库地址 :https://github.com/zoujingli/ThinkLibrary
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
declare (strict_types=1);
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
namespace think\admin\model;
|
namespace think\admin\model;
|
||||||
|
|
||||||
use think\admin\Model;
|
use think\admin\Model;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 系统日志模型
|
* 系统日志模型.
|
||||||
*
|
*
|
||||||
* @property int $id
|
* @property int $id
|
||||||
* @property string $action 操作行为名称
|
* @property string $action 操作行为名称
|
||||||
@ -31,20 +33,19 @@ use think\admin\Model;
|
|||||||
* @property string $node 当前操作节点
|
* @property string $node 当前操作节点
|
||||||
* @property string $username 操作人用户名
|
* @property string $username 操作人用户名
|
||||||
* @class SystemOplog
|
* @class SystemOplog
|
||||||
* @package think\admin\model
|
|
||||||
*/
|
*/
|
||||||
class SystemOplog extends Model
|
class SystemOplog extends Model
|
||||||
{
|
{
|
||||||
protected $createTime = 'create_at';
|
protected $createTime = 'create_at';
|
||||||
|
|
||||||
protected $updateTime = false;
|
protected $updateTime = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 格式化创建时间
|
* 格式化创建时间.
|
||||||
* @param mixed $value
|
* @param mixed $value
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public function getCreateAtAttr($value): string
|
public function getCreateAtAttr($value): string
|
||||||
{
|
{
|
||||||
return format_datetime($value);
|
return format_datetime($value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,27 +1,29 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// +----------------------------------------------------------------------
|
declare(strict_types=1);
|
||||||
// | Library for ThinkAdmin
|
/**
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 版权所有 2014~2025 ThinkAdmin [ thinkadmin.top ]
|
* | Payment Plugin for ThinkAdmin
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 官方网站: https://thinkadmin.top
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 开源协议 ( https://mit-license.org )
|
* | 官方网站: https://thinkadmin.top
|
||||||
// | 免费声明 ( https://thinkadmin.top/disclaimer )
|
* +----------------------------------------------------------------------
|
||||||
// +----------------------------------------------------------------------
|
* | 开源协议 ( https://mit-license.org )
|
||||||
// | gitee 仓库地址 :https://gitee.com/zoujingli/ThinkLibrary
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
// | github 仓库地址 :https://github.com/zoujingli/ThinkLibrary
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
declare (strict_types=1);
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
namespace think\admin\model;
|
namespace think\admin\model;
|
||||||
|
|
||||||
use think\admin\Model;
|
use think\admin\Model;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 系统任务模型
|
* 系统任务模型.
|
||||||
*
|
*
|
||||||
* @property int $attempts 执行次数
|
* @property int $attempts 执行次数
|
||||||
* @property int $exec_pid 执行进程
|
* @property int $exec_pid 执行进程
|
||||||
@ -40,17 +42,16 @@ use think\admin\Model;
|
|||||||
* @property string $outer_time 结束时间
|
* @property string $outer_time 结束时间
|
||||||
* @property string $title 任务名称
|
* @property string $title 任务名称
|
||||||
* @class SystemQueue
|
* @class SystemQueue
|
||||||
* @package think\admin\model
|
|
||||||
*/
|
*/
|
||||||
class SystemQueue extends Model
|
class SystemQueue extends Model
|
||||||
{
|
{
|
||||||
protected $createTime = 'create_at';
|
protected $createTime = 'create_at';
|
||||||
|
|
||||||
protected $updateTime = false;
|
protected $updateTime = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 格式化计划时间
|
* 格式化计划时间.
|
||||||
* @param mixed $value
|
* @param mixed $value
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public function getExecTimeAttr($value): string
|
public function getExecTimeAttr($value): string
|
||||||
{
|
{
|
||||||
@ -58,9 +59,8 @@ class SystemQueue extends Model
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 执行开始时间处理
|
* 执行开始时间处理.
|
||||||
* @param mixed $value
|
* @param mixed $value
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public function getEnterTimeAttr($value): string
|
public function getEnterTimeAttr($value): string
|
||||||
{
|
{
|
||||||
@ -68,27 +68,23 @@ class SystemQueue extends Model
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 执行结束时间处理
|
* 执行结束时间处理.
|
||||||
* @param mixed $value
|
* @param mixed $value
|
||||||
* @param array $data
|
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public function getOuterTimeAttr($value, array $data): string
|
public function getOuterTimeAttr($value, array $data): string
|
||||||
{
|
{
|
||||||
if ($value > 0 && $value > $data['enter_time']) {
|
if ($value > 0 && $value > $data['enter_time']) {
|
||||||
return lang("耗时 %.4f 秒", [$data['outer_time'] - $data['enter_time']]);
|
return lang('耗时 %.4f 秒', [$data['outer_time'] - $data['enter_time']]);
|
||||||
} else {
|
|
||||||
return ' - ';
|
|
||||||
}
|
}
|
||||||
|
return ' - ';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 格式化创建时间
|
* 格式化创建时间.
|
||||||
* @param mixed $value
|
* @param mixed $value
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public function getCreateAtAttr($value): string
|
public function getCreateAtAttr($value): string
|
||||||
{
|
{
|
||||||
return format_datetime($value);
|
return format_datetime($value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,20 +1,22 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// +----------------------------------------------------------------------
|
declare(strict_types=1);
|
||||||
// | Library for ThinkAdmin
|
/**
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 版权所有 2014~2025 ThinkAdmin [ thinkadmin.top ]
|
* | Payment Plugin for ThinkAdmin
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 官方网站: https://thinkadmin.top
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 开源协议 ( https://mit-license.org )
|
* | 官方网站: https://thinkadmin.top
|
||||||
// | 免费声明 ( https://thinkadmin.top/disclaimer )
|
* +----------------------------------------------------------------------
|
||||||
// +----------------------------------------------------------------------
|
* | 开源协议 ( https://mit-license.org )
|
||||||
// | gitee 仓库地址 :https://gitee.com/zoujingli/ThinkLibrary
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
// | github 仓库地址 :https://github.com/zoujingli/ThinkLibrary
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
declare (strict_types=1);
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
namespace think\admin\model;
|
namespace think\admin\model;
|
||||||
|
|
||||||
@ -22,7 +24,7 @@ use think\admin\Model;
|
|||||||
use think\model\relation\HasOne;
|
use think\model\relation\HasOne;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 系统用户模型
|
* 系统用户模型.
|
||||||
*
|
*
|
||||||
* @property int $id
|
* @property int $id
|
||||||
* @property int $is_deleted 删除(1删除,0未删)
|
* @property int $is_deleted 删除(1删除,0未删)
|
||||||
@ -42,51 +44,50 @@ use think\model\relation\HasOne;
|
|||||||
* @property string $password 用户密码
|
* @property string $password 用户密码
|
||||||
* @property string $username 用户账号
|
* @property string $username 用户账号
|
||||||
* @property string $usertype 用户类型
|
* @property string $usertype 用户类型
|
||||||
* @property-read \think\admin\model\SystemBase $userinfo
|
* @property SystemBase $userinfo
|
||||||
* @class SystemUser
|
* @class SystemUser
|
||||||
* @package think\admin\model
|
|
||||||
*/
|
*/
|
||||||
class SystemUser extends Model
|
class SystemUser extends Model
|
||||||
{
|
{
|
||||||
protected $createTime = 'create_at';
|
protected $createTime = 'create_at';
|
||||||
|
|
||||||
protected $updateTime = false;
|
protected $updateTime = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 日志名称
|
* 日志名称.
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
protected $oplogName = '系统用户';
|
protected $oplogName = '系统用户';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 日志类型
|
* 日志类型.
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
protected $oplogType = '系统用户管理';
|
protected $oplogType = '系统用户管理';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取用户数据
|
* 获取用户数据.
|
||||||
* @param mixed $map 数据查询规则
|
* @param mixed $map 数据查询规则
|
||||||
* @param array $data 用户数据集合
|
* @param array $data 用户数据集合
|
||||||
* @param string $field 原外连字段
|
* @param string $field 原外连字段
|
||||||
* @param string $target 关联目标字段
|
* @param string $target 关联目标字段
|
||||||
* @param string $fields 关联数据字段
|
* @param string $fields 关联数据字段
|
||||||
* @return array
|
|
||||||
*/
|
*/
|
||||||
public static function items($map, array &$data = [], string $field = 'uuid', string $target = 'user_info', string $fields = 'username,nickname,headimg,status,is_deleted'): array
|
public static function items($map, array &$data = [], string $field = 'uuid', string $target = 'user_info', string $fields = 'username,nickname,headimg,status,is_deleted'): array
|
||||||
{
|
{
|
||||||
$query = static::mk()->where($map)->order('sort desc,id desc');
|
$query = static::mk()->where($map)->order('sort desc,id desc');
|
||||||
if (count($data) > 0) {
|
if (count($data) > 0) {
|
||||||
$users = $query->whereIn('id', array_unique(array_column($data, $field)))->column($fields, 'id');
|
$users = $query->whereIn('id', array_unique(array_column($data, $field)))->column($fields, 'id');
|
||||||
foreach ($data as &$vo) $vo[$target] = $users[$vo[$field]] ?? [];
|
foreach ($data as &$vo) {
|
||||||
|
$vo[$target] = $users[$vo[$field]] ?? [];
|
||||||
|
}
|
||||||
return $users;
|
return $users;
|
||||||
} else {
|
|
||||||
return $query->column($fields, 'id');
|
|
||||||
}
|
}
|
||||||
|
return $query->column($fields, 'id');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 关联身份权限
|
* 关联身份权限.
|
||||||
* @return HasOne
|
|
||||||
*/
|
*/
|
||||||
public function userinfo(): HasOne
|
public function userinfo(): HasOne
|
||||||
{
|
{
|
||||||
@ -96,26 +97,25 @@ class SystemUser extends Model
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 默认头像处理
|
* 默认头像处理.
|
||||||
* @param mixed $value
|
* @param mixed $value
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public function getHeadimgAttr($value): string
|
public function getHeadimgAttr($value): string
|
||||||
{
|
{
|
||||||
if (empty($value)) try {
|
if (empty($value)) {
|
||||||
$host = sysconf('base.site_host|raw') ?: 'https://v6.thinkadmin.top';
|
try {
|
||||||
return "{$host}/static/theme/img/headimg.png";
|
$host = sysconf('base.site_host|raw') ?: 'https://v6.thinkadmin.top';
|
||||||
} catch (\Exception $exception) {
|
return "{$host}/static/theme/img/headimg.png";
|
||||||
return "https://v6.thinkadmin.top/static/theme/img/headimg.png";
|
} catch (\Exception $exception) {
|
||||||
|
return 'https://v6.thinkadmin.top/static/theme/img/headimg.png';
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return $value;
|
return $value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 格式化登录时间
|
* 格式化登录时间.
|
||||||
* @param string $value
|
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public function getLoginAtAttr(string $value): string
|
public function getLoginAtAttr(string $value): string
|
||||||
{
|
{
|
||||||
@ -123,12 +123,11 @@ class SystemUser extends Model
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 格式化创建时间
|
* 格式化创建时间.
|
||||||
* @param mixed $value
|
* @param mixed $value
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public function getCreateAtAttr($value): string
|
public function getCreateAtAttr($value): string
|
||||||
{
|
{
|
||||||
return format_datetime($value);
|
return format_datetime($value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,20 +1,22 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// +----------------------------------------------------------------------
|
declare(strict_types=1);
|
||||||
// | Library for ThinkAdmin
|
/**
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 版权所有 2014~2025 ThinkAdmin [ thinkadmin.top ]
|
* | Payment Plugin for ThinkAdmin
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 官方网站: https://thinkadmin.top
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 开源协议 ( https://mit-license.org )
|
* | 官方网站: https://thinkadmin.top
|
||||||
// | 免费声明 ( https://thinkadmin.top/disclaimer )
|
* +----------------------------------------------------------------------
|
||||||
// +----------------------------------------------------------------------
|
* | 开源协议 ( https://mit-license.org )
|
||||||
// | gitee 仓库地址 :https://gitee.com/zoujingli/ThinkLibrary
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
// | github 仓库地址 :https://github.com/zoujingli/ThinkLibrary
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
declare (strict_types=1);
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
namespace think\admin\service;
|
namespace think\admin\service;
|
||||||
|
|
||||||
@ -32,19 +34,40 @@ use think\Session;
|
|||||||
/**
|
/**
|
||||||
* 系统权限管理服务
|
* 系统权限管理服务
|
||||||
* @class AdminService
|
* @class AdminService
|
||||||
* @package think\admin\service
|
|
||||||
*/
|
*/
|
||||||
class AdminService extends Service
|
class AdminService extends Service
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* 自定义回调处理
|
* 自定义回调处理.
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
private static $checkCallables = [];
|
private static $checkCallables = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 是否已经登录
|
* 静态方法兼容(临时).
|
||||||
* @return boolean
|
* @return bool
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public static function __callStatic(string $method, array $arguments)
|
||||||
|
{
|
||||||
|
if (strtolower($method) === 'clearcache') {
|
||||||
|
return static::clear();
|
||||||
|
}
|
||||||
|
throw new Exception("method not exists: AdminService::{$method}()");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对象方法兼容(临时).
|
||||||
|
* @return bool
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public function __call(string $method, array $arguments)
|
||||||
|
{
|
||||||
|
return static::__callStatic($method, $arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否已经登录.
|
||||||
*/
|
*/
|
||||||
public static function isLogin(): bool
|
public static function isLogin(): bool
|
||||||
{
|
{
|
||||||
@ -52,8 +75,7 @@ class AdminService extends Service
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 是否为超级用户
|
* 是否为超级用户.
|
||||||
* @return boolean
|
|
||||||
*/
|
*/
|
||||||
public static function isSuper(): bool
|
public static function isSuper(): bool
|
||||||
{
|
{
|
||||||
@ -61,8 +83,7 @@ class AdminService extends Service
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取超级用户账号
|
* 获取超级用户账号.
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public static function getSuperName(): string
|
public static function getSuperName(): string
|
||||||
{
|
{
|
||||||
@ -70,8 +91,7 @@ class AdminService extends Service
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取后台用户ID
|
* 获取后台用户ID.
|
||||||
* @return integer
|
|
||||||
*/
|
*/
|
||||||
public static function getUserId(): int
|
public static function getUserId(): int
|
||||||
{
|
{
|
||||||
@ -79,8 +99,7 @@ class AdminService extends Service
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取后台用户名称
|
* 获取后台用户名称.
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public static function getUserName(): string
|
public static function getUserName(): string
|
||||||
{
|
{
|
||||||
@ -88,8 +107,7 @@ class AdminService extends Service
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取用户扩展数据
|
* 获取用户扩展数据.
|
||||||
* @param null|string $field
|
|
||||||
* @param null|mixed $default
|
* @param null|mixed $default
|
||||||
* @return array|mixed
|
* @return array|mixed
|
||||||
*/
|
*/
|
||||||
@ -100,11 +118,8 @@ class AdminService extends Service
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置用户扩展数据
|
* 设置用户扩展数据.
|
||||||
* @param array $data
|
* @throws Exception
|
||||||
* @param boolean $replace
|
|
||||||
* @return boolean
|
|
||||||
* @throws \think\admin\Exception
|
|
||||||
*/
|
*/
|
||||||
public static function setUserData(array $data, bool $replace = false): bool
|
public static function setUserData(array $data, bool $replace = false): bool
|
||||||
{
|
{
|
||||||
@ -113,9 +128,8 @@ class AdminService extends Service
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取用户主题名称
|
* 获取用户主题名称.
|
||||||
* @return string
|
* @throws Exception
|
||||||
* @throws \think\admin\Exception
|
|
||||||
*/
|
*/
|
||||||
public static function getUserTheme(): string
|
public static function getUserTheme(): string
|
||||||
{
|
{
|
||||||
@ -124,10 +138,9 @@ class AdminService extends Service
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置用户主题名称
|
* 设置用户主题名称.
|
||||||
* @param string $theme 主题名称
|
* @param string $theme 主题名称
|
||||||
* @return boolean
|
* @throws Exception
|
||||||
* @throws \think\admin\Exception
|
|
||||||
*/
|
*/
|
||||||
public static function setUserTheme(string $theme): bool
|
public static function setUserTheme(string $theme): bool
|
||||||
{
|
{
|
||||||
@ -135,9 +148,7 @@ class AdminService extends Service
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 注册权限检查函数
|
* 注册权限检查函数.
|
||||||
* @param callable $callable
|
|
||||||
* @return integer
|
|
||||||
*/
|
*/
|
||||||
public static function registerCheckCallable(callable $callable): int
|
public static function registerCheckCallable(callable $callable): int
|
||||||
{
|
{
|
||||||
@ -146,28 +157,24 @@ class AdminService extends Service
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 移除权限检查函数
|
* 移除权限检查函数.
|
||||||
* @param ?integer $index
|
|
||||||
* @return boolean
|
|
||||||
*/
|
*/
|
||||||
public static function removeCheckCallable(?int $index): bool
|
public static function removeCheckCallable(?int $index): bool
|
||||||
{
|
{
|
||||||
if (is_null($index)) {
|
if (is_null($index)) {
|
||||||
self::$checkCallables = [];
|
self::$checkCallables = [];
|
||||||
return true;
|
return true;
|
||||||
} elseif (isset(self::$checkCallables[$index])) {
|
}
|
||||||
|
if (isset(self::$checkCallables[$index])) {
|
||||||
unset(self::$checkCallables[$index]);
|
unset(self::$checkCallables[$index]);
|
||||||
return true;
|
return true;
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 检查指定节点授权
|
* 检查指定节点授权
|
||||||
* --- 需要读取缓存或扫描所有节点
|
* --- 需要读取缓存或扫描所有节点.
|
||||||
* @param null|string $node
|
|
||||||
* @return boolean
|
|
||||||
*/
|
*/
|
||||||
public static function check(?string $node = ''): bool
|
public static function check(?string $node = ''): bool
|
||||||
{
|
{
|
||||||
@ -189,23 +196,24 @@ class AdminService extends Service
|
|||||||
return call_user_func('admin_check_filter', $current, $methods, $userNodes);
|
return call_user_func('admin_check_filter', $current, $methods, $userNodes);
|
||||||
}
|
}
|
||||||
// 超级用户不需要检查权限
|
// 超级用户不需要检查权限
|
||||||
if (static::isSuper()) return true;
|
if (static::isSuper()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
// 节点权限检查,需要兼容 windows 控制器不区分大小写,统一去除节点下划线再检查权限
|
// 节点权限检查,需要兼容 windows 控制器不区分大小写,统一去除节点下划线再检查权限
|
||||||
if (empty($simples = sysvar($skey2 = 'think.admin.fulls') ?: [])) {
|
if (empty($simples = sysvar($skey2 = 'think.admin.fulls') ?: [])) {
|
||||||
foreach ($methods as $k => $v) $simples[strtr($k, ['_' => ''])] = $v;
|
foreach ($methods as $k => $v) {
|
||||||
|
$simples[strtr($k, ['_' => ''])] = $v;
|
||||||
|
}
|
||||||
sysvar($skey2, $simples);
|
sysvar($skey2, $simples);
|
||||||
}
|
}
|
||||||
if (empty($simples[$simple = strtr($current, ['_' => ''])]['isauth'])) {
|
if (empty($simples[$simple = strtr($current, ['_' => ''])]['isauth'])) {
|
||||||
return !(!empty($simples[$simple]['islogin']) && !static::isLogin());
|
return !(!empty($simples[$simple]['islogin']) && !static::isLogin());
|
||||||
} else {
|
|
||||||
return in_array($current, $userNodes);
|
|
||||||
}
|
}
|
||||||
|
return in_array($current, $userNodes);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取授权节点列表
|
* 获取授权节点列表.
|
||||||
* @param array $checkeds
|
|
||||||
* @return array
|
|
||||||
*/
|
*/
|
||||||
public static function getTree(array $checkeds = []): array
|
public static function getTree(array $checkeds = []): array
|
||||||
{
|
{
|
||||||
@ -219,27 +227,36 @@ class AdminService extends Service
|
|||||||
$nodes[$node] = ['node' => $node, 'title' => lang($method['title']), 'pnode' => $pnode, 'checked' => in_array($node, $checkeds)];
|
$nodes[$node] = ['node' => $node, 'title' => lang($method['title']), 'pnode' => $pnode, 'checked' => in_array($node, $checkeds)];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
foreach (array_keys($nodes) as $key) foreach ($methods as $node => $method) if (stripos($key, $node . '/') !== false) {
|
foreach (array_keys($nodes) as $key) {
|
||||||
$pnode = substr($node, 0, strripos($node, '/'));
|
foreach ($methods as $node => $method) {
|
||||||
$nodes[$node] = ['node' => $node, 'title' => lang($method['title']), 'pnode' => $pnode, 'checked' => in_array($node, $checkeds)];
|
if (stripos($key, $node . '/') !== false) {
|
||||||
$nodes[$pnode] = ['node' => $pnode, 'title' => Str::studly($pnode), 'pnode' => '', 'checked' => in_array($pnode, $checkeds)];
|
$pnode = substr($node, 0, strripos($node, '/'));
|
||||||
|
$nodes[$node] = ['node' => $node, 'title' => lang($method['title']), 'pnode' => $pnode, 'checked' => in_array($node, $checkeds)];
|
||||||
|
$nodes[$pnode] = ['node' => $pnode, 'title' => Str::studly($pnode), 'pnode' => '', 'checked' => in_array($pnode, $checkeds)];
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return DataExtend::arr2tree(array_reverse($nodes), 'node', 'pnode', '_sub_');
|
return DataExtend::arr2tree(array_reverse($nodes), 'node', 'pnode', '_sub_');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 初始化用户权限
|
* 初始化用户权限.
|
||||||
* @param boolean $force 强刷权限
|
* @param bool $force 强刷权限
|
||||||
* @return array
|
|
||||||
*/
|
*/
|
||||||
public static function apply(bool $force = false): array
|
public static function apply(bool $force = false): array
|
||||||
{
|
{
|
||||||
if ($force) static::clear();
|
if ($force) {
|
||||||
if (($uuid = static::getUserId()) <= 0) return [];
|
static::clear();
|
||||||
|
}
|
||||||
|
if (($uuid = static::getUserId()) <= 0) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
$user = SystemUser::mk()->where(['id' => $uuid])->findOrEmpty()->toArray();
|
$user = SystemUser::mk()->where(['id' => $uuid])->findOrEmpty()->toArray();
|
||||||
if (!static::isSuper() && count($aids = str2arr($user['authorize'])) > 0) {
|
if (!static::isSuper() && count($aids = str2arr($user['authorize'])) > 0) {
|
||||||
$aids = SystemAuth::mk()->where(['status' => 1])->whereIn('id', $aids)->column('id');
|
$aids = SystemAuth::mk()->where(['status' => 1])->whereIn('id', $aids)->column('id');
|
||||||
if (!empty($aids)) $nodes = SystemNode::mk()->distinct()->whereIn('auth', $aids)->column('node');
|
if (!empty($aids)) {
|
||||||
|
$nodes = SystemNode::mk()->distinct()->whereIn('auth', $aids)->column('node');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
$user['nodes'] = $nodes ?? [];
|
$user['nodes'] = $nodes ?? [];
|
||||||
Library::$sapp->session->set('user', $user);
|
Library::$sapp->session->set('user', $user);
|
||||||
@ -247,8 +264,7 @@ class AdminService extends Service
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 清理节点缓存
|
* 清理节点缓存.
|
||||||
* @return bool
|
|
||||||
*/
|
*/
|
||||||
public static function clear(): bool
|
public static function clear(): bool
|
||||||
{
|
{
|
||||||
@ -257,18 +273,21 @@ class AdminService extends Service
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取会员上传配置
|
* 获取会员上传配置.
|
||||||
* @param ?string $uptoken
|
|
||||||
* @return array [unid,exts]
|
* @return array [unid,exts]
|
||||||
*/
|
*/
|
||||||
public static function withUploadUnid(?string $uptoken = null): array
|
public static function withUploadUnid(?string $uptoken = null): array
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
if ($uptoken === '') return [0, []];
|
if ($uptoken === '') {
|
||||||
|
return [0, []];
|
||||||
|
}
|
||||||
$session = Library::$sapp->session;
|
$session = Library::$sapp->session;
|
||||||
if (is_null($uptoken)) {
|
if (is_null($uptoken)) {
|
||||||
$sesskey = $session->get('UploadSessionKey');
|
$sesskey = $session->get('UploadSessionKey');
|
||||||
if (empty($sesskey)) return [0, []];
|
if (empty($sesskey)) {
|
||||||
|
return [0, []];
|
||||||
|
}
|
||||||
if ($session->getId() !== $sesskey) {
|
if ($session->getId() !== $sesskey) {
|
||||||
$session = Library::$sapp->invokeClass(Session::class);
|
$session = Library::$sapp->invokeClass(Session::class);
|
||||||
$session->setId($sesskey);
|
$session->setId($sesskey);
|
||||||
@ -277,7 +296,9 @@ class AdminService extends Service
|
|||||||
$unid = intval($session->get('AdminUploadUnid', 0));
|
$unid = intval($session->get('AdminUploadUnid', 0));
|
||||||
} else {
|
} else {
|
||||||
$sesskey = CodeExtend::decrypt($uptoken, sysconf('data.jwtkey'));
|
$sesskey = CodeExtend::decrypt($uptoken, sysconf('data.jwtkey'));
|
||||||
if (empty($sesskey)) return [0, []];
|
if (empty($sesskey)) {
|
||||||
|
return [0, []];
|
||||||
|
}
|
||||||
if ($session->getId() !== $sesskey) {
|
if ($session->getId() !== $sesskey) {
|
||||||
$session = Library::$sapp->invokeClass(Session::class);
|
$session = Library::$sapp->invokeClass(Session::class);
|
||||||
$session->setId($sesskey);
|
$session->setId($sesskey);
|
||||||
@ -294,11 +315,10 @@ class AdminService extends Service
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 生成上传入口令牌
|
* 生成上传入口令牌.
|
||||||
* @param integer $unid 会员编号
|
* @param int $unid 会员编号
|
||||||
* @param string $exts 允许后缀(多个以英文逗号隔开)
|
* @param string $exts 允许后缀(多个以英文逗号隔开)
|
||||||
* @return string
|
* @throws Exception
|
||||||
* @throws \think\admin\Exception
|
|
||||||
*/
|
*/
|
||||||
public static function withUploadToken(int $unid, string $exts = ''): string
|
public static function withUploadToken(int $unid, string $exts = ''): string
|
||||||
{
|
{
|
||||||
@ -306,29 +326,4 @@ class AdminService extends Service
|
|||||||
Library::$sapp->session->set('AdminUploadExts', str2arr(strtolower($exts)));
|
Library::$sapp->session->set('AdminUploadExts', str2arr(strtolower($exts)));
|
||||||
return CodeExtend::encrypt(Library::$sapp->session->getId(), sysconf('data.jwtkey'));
|
return CodeExtend::encrypt(Library::$sapp->session->getId(), sysconf('data.jwtkey'));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
/**
|
|
||||||
* 静态方法兼容(临时)
|
|
||||||
* @param string $method
|
|
||||||
* @param array $arguments
|
|
||||||
* @return bool
|
|
||||||
* @throws \think\admin\Exception
|
|
||||||
*/
|
|
||||||
public static function __callStatic(string $method, array $arguments)
|
|
||||||
{
|
|
||||||
if (strtolower($method) === 'clearcache') return static::clear();
|
|
||||||
throw new Exception("method not exists: AdminService::{$method}()");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 对象方法兼容(临时)
|
|
||||||
* @param string $method
|
|
||||||
* @param array $arguments
|
|
||||||
* @return bool
|
|
||||||
* @throws \think\admin\Exception
|
|
||||||
*/
|
|
||||||
public function __call(string $method, array $arguments)
|
|
||||||
{
|
|
||||||
return static::__callStatic($method, $arguments);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@ -1,20 +1,22 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// +----------------------------------------------------------------------
|
|
||||||
// | Library for ThinkAdmin
|
|
||||||
// +----------------------------------------------------------------------
|
|
||||||
// | 版权所有 2014~2025 ThinkAdmin [ thinkadmin.top ]
|
|
||||||
// +----------------------------------------------------------------------
|
|
||||||
// | 官方网站: https://thinkadmin.top
|
|
||||||
// +----------------------------------------------------------------------
|
|
||||||
// | 开源协议 ( https://mit-license.org )
|
|
||||||
// | 免费声明 ( https://thinkadmin.top/disclaimer )
|
|
||||||
// +----------------------------------------------------------------------
|
|
||||||
// | gitee 仓库地址 :https://gitee.com/zoujingli/ThinkLibrary
|
|
||||||
// | github 仓库地址 :https://github.com/zoujingli/ThinkLibrary
|
|
||||||
// +----------------------------------------------------------------------
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
/**
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
* | Payment Plugin for ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
* | 官方网站: https://thinkadmin.top
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
* | 开源协议 ( https://mit-license.org )
|
||||||
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
namespace think\admin\service;
|
namespace think\admin\service;
|
||||||
|
|
||||||
@ -24,90 +26,23 @@ use think\admin\Service;
|
|||||||
/**
|
/**
|
||||||
* 图形验证码服务
|
* 图形验证码服务
|
||||||
* @class CaptchaService
|
* @class CaptchaService
|
||||||
* @package think\admin\service
|
|
||||||
*/
|
*/
|
||||||
class CaptchaService extends Service
|
class CaptchaService extends Service
|
||||||
{
|
{
|
||||||
private $code; // 验证码
|
private $code; // 验证码
|
||||||
|
|
||||||
private $uniqid; // 唯一序号
|
private $uniqid; // 唯一序号
|
||||||
|
|
||||||
private $charset = 'ABCDEFGHKMNPRSTUVWXYZ23456789'; // 随机因子
|
private $charset = 'ABCDEFGHKMNPRSTUVWXYZ23456789'; // 随机因子
|
||||||
|
|
||||||
private $width = 130; // 图片宽度
|
private $width = 130; // 图片宽度
|
||||||
|
|
||||||
private $height = 50; // 图片高度
|
private $height = 50; // 图片高度
|
||||||
|
|
||||||
private $length = 4; // 验证码长度
|
private $length = 4; // 验证码长度
|
||||||
|
|
||||||
private $fontsize = 20; // 指定字体大小
|
private $fontsize = 20; // 指定字体大小
|
||||||
|
|
||||||
/**
|
|
||||||
* 验证码服务初始化
|
|
||||||
* @param array $config
|
|
||||||
* @return static
|
|
||||||
*/
|
|
||||||
public function initialize(array $config = []): CaptchaService
|
|
||||||
{
|
|
||||||
// 动态配置属性
|
|
||||||
foreach ($config as $k => $v) if (isset($this->$k)) $this->$k = $v;
|
|
||||||
// 生成验证码序号
|
|
||||||
$this->uniqid = uniqid('captcha') . mt_rand(1000, 9999);
|
|
||||||
// 生成验证码字符串
|
|
||||||
[$this->code, $length] = ['', strlen($this->charset) - 1];
|
|
||||||
for ($i = 0; $i < $this->length; $i++) {
|
|
||||||
$this->code .= $this->charset[mt_rand(0, $length)];
|
|
||||||
}
|
|
||||||
// 缓存验证码字符串
|
|
||||||
$this->app->cache->set($this->uniqid, $this->code, 360);
|
|
||||||
// 返回当前对象
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 动态切换配置
|
|
||||||
* @param array $config
|
|
||||||
* @return $this
|
|
||||||
*/
|
|
||||||
public function config(array $config = []): CaptchaService
|
|
||||||
{
|
|
||||||
return $this->initialize($config);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取验证码值
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function getCode(): string
|
|
||||||
{
|
|
||||||
return $this->code;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取图片的内容
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function getData(): string
|
|
||||||
{
|
|
||||||
return "data:image/png;base64,{$this->_image()}";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取验证码编号
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function getUniqid(): string
|
|
||||||
{
|
|
||||||
return $this->uniqid;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取验证码数据
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function getAttrs(): array
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
'code' => $this->getCode(),
|
|
||||||
'data' => $this->getData(),
|
|
||||||
'uniqid' => $this->getUniqid(),
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 输出图形验证码
|
* 输出图形验证码
|
||||||
* @return string
|
* @return string
|
||||||
@ -118,8 +53,101 @@ class CaptchaService extends Service
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建验证码图片
|
* 验证码服务初始化.
|
||||||
* @return string
|
* @return static
|
||||||
|
*/
|
||||||
|
public function initialize(array $config = []): CaptchaService
|
||||||
|
{
|
||||||
|
// 动态配置属性
|
||||||
|
foreach ($config as $k => $v) {
|
||||||
|
if (isset($this->{$k})) {
|
||||||
|
$this->{$k} = $v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 生成验证码序号
|
||||||
|
$this->uniqid = uniqid('captcha') . mt_rand(1000, 9999);
|
||||||
|
// 生成验证码字符串
|
||||||
|
[$this->code, $length] = ['', strlen($this->charset) - 1];
|
||||||
|
for ($i = 0; $i < $this->length; ++$i) {
|
||||||
|
$this->code .= $this->charset[mt_rand(0, $length)];
|
||||||
|
}
|
||||||
|
// 缓存验证码字符串
|
||||||
|
$this->app->cache->set($this->uniqid, $this->code, 360);
|
||||||
|
// 返回当前对象
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 动态切换配置.
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function config(array $config = []): CaptchaService
|
||||||
|
{
|
||||||
|
return $this->initialize($config);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取验证码值
|
||||||
|
*/
|
||||||
|
public function getCode(): string
|
||||||
|
{
|
||||||
|
return $this->code;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取图片的内容.
|
||||||
|
*/
|
||||||
|
public function getData(): string
|
||||||
|
{
|
||||||
|
return "data:image/png;base64,{$this->_image()}";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取验证码编号.
|
||||||
|
*/
|
||||||
|
public function getUniqid(): string
|
||||||
|
{
|
||||||
|
return $this->uniqid;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取验证码数据.
|
||||||
|
*/
|
||||||
|
public function getAttrs(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'code' => $this->getCode(),
|
||||||
|
'data' => $this->getData(),
|
||||||
|
'uniqid' => $this->getUniqid(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取字体文件.
|
||||||
|
*/
|
||||||
|
public static function font(): string
|
||||||
|
{
|
||||||
|
return __DIR__ . '/bin/captcha.ttf';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查验证码是否正确.
|
||||||
|
* @param string $code 需要验证的值
|
||||||
|
* @param null|string $uniqid 验证码编号
|
||||||
|
*/
|
||||||
|
public static function check(string $code, ?string $uniqid = null): bool
|
||||||
|
{
|
||||||
|
$_uni = is_string($uniqid) ? $uniqid : input('uniqid', '-');
|
||||||
|
$_val = Library::$sapp->cache->get($_uni, '');
|
||||||
|
if (is_string($_val) && strtolower($_val) === strtolower($code)) {
|
||||||
|
Library::$sapp->cache->delete($_uni);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建验证码图片.
|
||||||
*/
|
*/
|
||||||
private function _image(): string
|
private function _image(): string
|
||||||
{
|
{
|
||||||
@ -128,19 +156,19 @@ class CaptchaService extends Service
|
|||||||
$color = imagecolorallocate($img, mt_rand(220, 255), mt_rand(220, 255), mt_rand(220, 255));
|
$color = imagecolorallocate($img, mt_rand(220, 255), mt_rand(220, 255), mt_rand(220, 255));
|
||||||
imagefilledrectangle($img, 0, $this->height, $this->width, 0, $color);
|
imagefilledrectangle($img, 0, $this->height, $this->width, 0, $color);
|
||||||
// 生成线条
|
// 生成线条
|
||||||
for ($i = 0; $i < 6; $i++) {
|
for ($i = 0; $i < 6; ++$i) {
|
||||||
$color = imagecolorallocate($img, mt_rand(0, 50), mt_rand(0, 50), mt_rand(0, 50));
|
$color = imagecolorallocate($img, mt_rand(0, 50), mt_rand(0, 50), mt_rand(0, 50));
|
||||||
imageline($img, mt_rand(0, $this->width), mt_rand(0, $this->height), mt_rand(0, $this->width), mt_rand(0, $this->height), $color);
|
imageline($img, mt_rand(0, $this->width), mt_rand(0, $this->height), mt_rand(0, $this->width), mt_rand(0, $this->height), $color);
|
||||||
}
|
}
|
||||||
// 生成雪花
|
// 生成雪花
|
||||||
for ($i = 0; $i < 100; $i++) {
|
for ($i = 0; $i < 100; ++$i) {
|
||||||
$color = imagecolorallocate($img, mt_rand(200, 255), mt_rand(200, 255), mt_rand(200, 255));
|
$color = imagecolorallocate($img, mt_rand(200, 255), mt_rand(200, 255), mt_rand(200, 255));
|
||||||
imagestring($img, mt_rand(1, 5), mt_rand(0, $this->width), mt_rand(0, $this->height), '*', $color);
|
imagestring($img, mt_rand(1, 5), mt_rand(0, $this->width), mt_rand(0, $this->height), '*', $color);
|
||||||
}
|
}
|
||||||
// 生成文字
|
// 生成文字
|
||||||
$_x = $this->width / $this->length;
|
$_x = $this->width / $this->length;
|
||||||
$fontfile = self::font();
|
$fontfile = self::font();
|
||||||
for ($i = 0; $i < $this->length; $i++) {
|
for ($i = 0; $i < $this->length; ++$i) {
|
||||||
$fontcolor = imagecolorallocate($img, mt_rand(0, 156), mt_rand(0, 156), mt_rand(0, 156));
|
$fontcolor = imagecolorallocate($img, mt_rand(0, 156), mt_rand(0, 156), mt_rand(0, 156));
|
||||||
if (function_exists('imagettftext')) {
|
if (function_exists('imagettftext')) {
|
||||||
imagettftext($img, $this->fontsize, mt_rand(-30, 30), intval($_x * $i + mt_rand(1, 5)), intval($this->height / 1.4), $fontcolor, $fontfile, $this->code[$i]);
|
imagettftext($img, $this->fontsize, mt_rand(-30, 30), intval($_x * $i + mt_rand(1, 5)), intval($this->height / 1.4), $fontcolor, $fontfile, $this->code[$i]);
|
||||||
@ -157,31 +185,4 @@ class CaptchaService extends Service
|
|||||||
}
|
}
|
||||||
return base64_encode($data);
|
return base64_encode($data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取字体文件
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public static function font(): string
|
|
||||||
{
|
|
||||||
return __DIR__ . '/bin/captcha.ttf';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 检查验证码是否正确
|
|
||||||
* @param string $code 需要验证的值
|
|
||||||
* @param null|string $uniqid 验证码编号
|
|
||||||
* @return boolean
|
|
||||||
*/
|
|
||||||
public static function check(string $code, ?string $uniqid = null): bool
|
|
||||||
{
|
|
||||||
$_uni = is_string($uniqid) ? $uniqid : input('uniqid', '-');
|
|
||||||
$_val = Library::$sapp->cache->get($_uni, '');
|
|
||||||
if (is_string($_val) && strtolower($_val) === strtolower($code)) {
|
|
||||||
Library::$sapp->cache->delete($_uni);
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,20 +1,22 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// +----------------------------------------------------------------------
|
declare(strict_types=1);
|
||||||
// | Library for ThinkAdmin
|
/**
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 版权所有 2014~2025 ThinkAdmin [ thinkadmin.top ]
|
* | Payment Plugin for ThinkAdmin
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 官方网站: https://thinkadmin.top
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 开源协议 ( https://mit-license.org )
|
* | 官方网站: https://thinkadmin.top
|
||||||
// | 免费声明 ( https://thinkadmin.top/disclaimer )
|
* +----------------------------------------------------------------------
|
||||||
// +----------------------------------------------------------------------
|
* | 开源协议 ( https://mit-license.org )
|
||||||
// | gitee 仓库地址 :https://gitee.com/zoujingli/ThinkLibrary
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
// | github 仓库地址 :https://github.com/zoujingli/ThinkLibrary
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
declare (strict_types=1);
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
namespace think\admin\service;
|
namespace think\admin\service;
|
||||||
|
|
||||||
@ -23,40 +25,79 @@ use think\admin\extend\HttpExtend;
|
|||||||
use think\admin\Service;
|
use think\admin\Service;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 百度快递100物流查询
|
* 百度快递100物流查询.
|
||||||
* @class ExpressService
|
* @class ExpressService
|
||||||
* @deprecated 独立封装为插件
|
* @deprecated 独立封装为插件
|
||||||
* @package think\admin\service
|
|
||||||
*/
|
*/
|
||||||
class ExpressService extends Service
|
class ExpressService extends Service
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 网络请求参数
|
* 网络请求参数.
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $options = [];
|
protected $options = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 公司编码别名
|
* 公司编码别名.
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $codes = [
|
protected $codes = [
|
||||||
'YD' => 'yunda',
|
'YD' => 'yunda',
|
||||||
'SF' => 'shunfeng',
|
'SF' => 'shunfeng',
|
||||||
'UC' => 'youshuwuliu',
|
'UC' => 'youshuwuliu',
|
||||||
'YTO' => 'yuantong',
|
'YTO' => 'yuantong',
|
||||||
'STO' => 'shentong',
|
'STO' => 'shentong',
|
||||||
'ZTO' => 'zhongtong',
|
'ZTO' => 'zhongtong',
|
||||||
'ZJS' => 'zhaijisong',
|
'ZJS' => 'zhaijisong',
|
||||||
'DBL' => 'debangwuliu',
|
'DBL' => 'debangwuliu',
|
||||||
'HHTT' => 'tiantian',
|
'HHTT' => 'tiantian',
|
||||||
'HTKY' => 'huitongkuaidi',
|
'HTKY' => 'huitongkuaidi',
|
||||||
'YZPY' => 'youzhengguonei',
|
'YZPY' => 'youzhengguonei',
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 快递服务初始化
|
* 通过百度快递100应用查询物流信息.
|
||||||
|
* @param string $code 快递公司编辑
|
||||||
|
* @param string $number 快递物流编号
|
||||||
|
* @param array $list 快递路径列表
|
||||||
|
*/
|
||||||
|
public function express(string $code, string $number, array $list = []): array
|
||||||
|
{
|
||||||
|
// 新状态:1-新订单,2-在途中,3-签收,4-问题件
|
||||||
|
// 原状态:0-在途,1-揽收,2-疑难,3-签收,4-退签,5-派件,6-退回,7-转投,8-清关,14-拒签
|
||||||
|
$ckey = md5("{$code}{$number}");
|
||||||
|
$cache = $this->app->cache->get($ckey, []);
|
||||||
|
$message = [1 => '新订单', 2 => '在途中', 3 => '签收', 4 => '问题件'];
|
||||||
|
if (!empty($cache)) {
|
||||||
|
return $cache;
|
||||||
|
}
|
||||||
|
for ($i = 0; $i < 6; ++$i) {
|
||||||
|
if (is_array($result = $this->doExpress($code, $number))) {
|
||||||
|
if (isset($result['data']['info']['context'], $result['data']['info']['state'])) {
|
||||||
|
$state = intval($result['data']['info']['state']);
|
||||||
|
$status = in_array($state, [0, 1, 5, 7, 8]) ? 2 : ($state === 3 ? 3 : 4);
|
||||||
|
foreach ($result['data']['info']['context'] as $vo) {
|
||||||
|
$list[] = ['time' => date('Y-m-d H:i:s', intval($vo['time'])), 'context' => $vo['desc']];
|
||||||
|
}
|
||||||
|
$result = ['message' => lang($message[$status] ?? $result['msg']), 'status' => $status, 'express' => $code, 'number' => $number, 'data' => $list];
|
||||||
|
$this->app->cache->set($ckey, $result, 30);
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ['message' => lang('暂无轨迹信息~'), 'status' => 1, 'express' => $code, 'number' => $number, 'data' => $list];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取快递公司列表.
|
||||||
|
*/
|
||||||
|
public function getExpressList(): array
|
||||||
|
{
|
||||||
|
return $this->getQueryData(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 快递服务初始化.
|
||||||
* @return $this
|
* @return $this
|
||||||
*/
|
*/
|
||||||
protected function initialize(): ExpressService
|
protected function initialize(): ExpressService
|
||||||
@ -72,43 +113,6 @@ class ExpressService extends Service
|
|||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 通过百度快递100应用查询物流信息
|
|
||||||
* @param string $code 快递公司编辑
|
|
||||||
* @param string $number 快递物流编号
|
|
||||||
* @param array $list 快递路径列表
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function express(string $code, string $number, array $list = []): array
|
|
||||||
{
|
|
||||||
// 新状态:1-新订单,2-在途中,3-签收,4-问题件
|
|
||||||
// 原状态:0-在途,1-揽收,2-疑难,3-签收,4-退签,5-派件,6-退回,7-转投,8-清关,14-拒签
|
|
||||||
$ckey = md5("{$code}{$number}");
|
|
||||||
$cache = $this->app->cache->get($ckey, []);
|
|
||||||
$message = [1 => '新订单', 2 => '在途中', 3 => '签收', 4 => '问题件'];
|
|
||||||
if (!empty($cache)) return $cache;
|
|
||||||
for ($i = 0; $i < 6; $i++) if (is_array($result = $this->doExpress($code, $number))) {
|
|
||||||
if (isset($result['data']['info']['context']) && isset($result['data']['info']['state'])) {
|
|
||||||
$state = intval($result['data']['info']['state']);
|
|
||||||
$status = in_array($state, [0, 1, 5, 7, 8]) ? 2 : ($state === 3 ? 3 : 4);
|
|
||||||
foreach ($result['data']['info']['context'] as $vo) $list[] = ['time' => date('Y-m-d H:i:s', intval($vo['time'])), 'context' => $vo['desc']];
|
|
||||||
$result = ['message' => lang($message[$status] ?? $result['msg']), 'status' => $status, 'express' => $code, 'number' => $number, 'data' => $list];
|
|
||||||
$this->app->cache->set($ckey, $result, 30);
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ['message' => lang('暂无轨迹信息~'), 'status' => 1, 'express' => $code, 'number' => $number, 'data' => $list];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取快递公司列表
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function getExpressList(): array
|
|
||||||
{
|
|
||||||
return $this->getQueryData(2);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 执行百度快递100应用查询请求
|
* 执行百度快递100应用查询请求
|
||||||
* @param string $code 快递公司编号
|
* @param string $code 快递公司编号
|
||||||
@ -129,17 +133,21 @@ class ExpressService extends Service
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取快递查询接口
|
* 获取快递查询接口.
|
||||||
* @param integer $type 类型数据
|
* @param int $type 类型数据
|
||||||
* @return string|array
|
* @return array|string
|
||||||
*/
|
*/
|
||||||
private function getQueryData(int $type)
|
private function getQueryData(int $type)
|
||||||
{
|
{
|
||||||
$times = 0;
|
$times = 0;
|
||||||
$expressUri = $this->app->cache->get('express_kuaidi_uri', '');
|
$expressUri = $this->app->cache->get('express_kuaidi_uri', '');
|
||||||
if ($type == 1 && !empty($expressUri)) return $expressUri;
|
if ($type == 1 && !empty($expressUri)) {
|
||||||
|
return $expressUri;
|
||||||
|
}
|
||||||
$expressCom = $this->app->cache->get('express_kuaidi_com', []);
|
$expressCom = $this->app->cache->get('express_kuaidi_com', []);
|
||||||
if ($type === 2 && !empty($expressCom)) return $expressCom;
|
if ($type === 2 && !empty($expressCom)) {
|
||||||
|
return $expressCom;
|
||||||
|
}
|
||||||
while (true) {
|
while (true) {
|
||||||
if ($times++ >= 10) {
|
if ($times++ >= 10) {
|
||||||
$times = 0;
|
$times = 0;
|
||||||
@ -153,10 +161,16 @@ class ExpressService extends Service
|
|||||||
$attr = json_decode($items[1], true);
|
$attr = json_decode($items[1], true);
|
||||||
$expressCom = array_combine(array_column($attr, 'value'), array_column($attr, 'text'));
|
$expressCom = array_combine(array_column($attr, 'value'), array_column($attr, 'text'));
|
||||||
$this->app->cache->set('express_kuaidi_com', $expressCom, 3600);
|
$this->app->cache->set('express_kuaidi_com', $expressCom, 3600);
|
||||||
if ($type === 2) return $expressCom;
|
if ($type === 2) {
|
||||||
|
return $expressCom;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if ($type === 1) return $expressUri;
|
if ($type === 1) {
|
||||||
} else usleep(100000);
|
return $expressUri;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
usleep(100000);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,24 +1,25 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// +----------------------------------------------------------------------
|
declare(strict_types=1);
|
||||||
// | Library for ThinkAdmin
|
/**
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 版权所有 2014~2025 ThinkAdmin [ thinkadmin.top ]
|
* | Payment Plugin for ThinkAdmin
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 官方网站: https://thinkadmin.top
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 开源协议 ( https://mit-license.org )
|
* | 官方网站: https://thinkadmin.top
|
||||||
// | 免费声明 ( https://thinkadmin.top/disclaimer )
|
* +----------------------------------------------------------------------
|
||||||
// +----------------------------------------------------------------------
|
* | 开源协议 ( https://mit-license.org )
|
||||||
// | gitee 仓库地址 :https://gitee.com/zoujingli/ThinkLibrary
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
// | github 仓库地址 :https://github.com/zoujingli/ThinkLibrary
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
declare (strict_types=1);
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
namespace think\admin\service;
|
namespace think\admin\service;
|
||||||
|
|
||||||
use stdClass;
|
|
||||||
use think\admin\Exception;
|
use think\admin\Exception;
|
||||||
use think\admin\extend\HttpExtend;
|
use think\admin\extend\HttpExtend;
|
||||||
use think\admin\helper\ValidateHelper;
|
use think\admin\helper\ValidateHelper;
|
||||||
@ -29,24 +30,23 @@ use think\exception\HttpResponseException;
|
|||||||
/**
|
/**
|
||||||
* 通用接口基础服务
|
* 通用接口基础服务
|
||||||
* @class InterfaceService
|
* @class InterfaceService
|
||||||
* @package think\admin\service
|
|
||||||
*/
|
*/
|
||||||
class InterfaceService extends Service
|
class InterfaceService extends Service
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* 输出格式
|
* 输出格式.
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
private $type = 'json';
|
private $type = 'json';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 接口认证账号
|
* 接口认证账号.
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
private $appid;
|
private $appid;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 接口认证密钥
|
* 接口认证密钥.
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
private $appkey;
|
private $appkey;
|
||||||
@ -60,8 +60,7 @@ class InterfaceService extends Service
|
|||||||
/**
|
/**
|
||||||
* 接口服务初始化
|
* 接口服务初始化
|
||||||
* InterfaceService constructor.
|
* InterfaceService constructor.
|
||||||
* @param App $app
|
* @throws Exception
|
||||||
* @throws \think\admin\Exception
|
|
||||||
*/
|
*/
|
||||||
public function __construct(App $app)
|
public function __construct(App $app)
|
||||||
{
|
{
|
||||||
@ -72,7 +71,7 @@ class InterfaceService extends Service
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置接口网关
|
* 设置接口网关.
|
||||||
* @param string $getway 接口网关
|
* @param string $getway 接口网关
|
||||||
* @return $this
|
* @return $this
|
||||||
*/
|
*/
|
||||||
@ -83,7 +82,7 @@ class InterfaceService extends Service
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置授权账号
|
* 设置授权账号.
|
||||||
* @param string $appid 接口账号
|
* @param string $appid 接口账号
|
||||||
* @param string $appkey 接口密钥
|
* @param string $appkey 接口密钥
|
||||||
* @return $this
|
* @return $this
|
||||||
@ -96,7 +95,7 @@ class InterfaceService extends Service
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置输出类型为 JSON
|
* 设置输出类型为 JSON.
|
||||||
* @return $this
|
* @return $this
|
||||||
*/
|
*/
|
||||||
public function setOutTypeJson(): InterfaceService
|
public function setOutTypeJson(): InterfaceService
|
||||||
@ -106,7 +105,7 @@ class InterfaceService extends Service
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置输出类型为 Array
|
* 设置输出类型为 Array.
|
||||||
* @return $this
|
* @return $this
|
||||||
*/
|
*/
|
||||||
public function setOutTypeArray(): InterfaceService
|
public function setOutTypeArray(): InterfaceService
|
||||||
@ -116,8 +115,7 @@ class InterfaceService extends Service
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取当前APPID
|
* 获取当前APPID.
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public function getAppid(): string
|
public function getAppid(): string
|
||||||
{
|
{
|
||||||
@ -125,16 +123,15 @@ class InterfaceService extends Service
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取请求参数
|
* 获取请求参数.
|
||||||
* @return array
|
|
||||||
*/
|
*/
|
||||||
public function getData(): array
|
public function getData(): array
|
||||||
{
|
{
|
||||||
// 基础参数获取
|
// 基础参数获取
|
||||||
$input = ValidateHelper::instance()->init([
|
$input = ValidateHelper::instance()->init([
|
||||||
'time.require' => lang('请求参数 %s 不能为空!', ['time']),
|
'time.require' => lang('请求参数 %s 不能为空!', ['time']),
|
||||||
'sign.require' => lang('请求参数 %s 不能为空!', ['sign']),
|
'sign.require' => lang('请求参数 %s 不能为空!', ['sign']),
|
||||||
'data.require' => lang('请求参数 %s 不能为空!', ['data']),
|
'data.require' => lang('请求参数 %s 不能为空!', ['data']),
|
||||||
'appid.require' => lang('请求参数 %s 不能为空!', ['appid']),
|
'appid.require' => lang('请求参数 %s 不能为空!', ['appid']),
|
||||||
'nostr.require' => lang('请求参数 %s 不能为空!', ['nostr']),
|
'nostr.require' => lang('请求参数 %s 不能为空!', ['nostr']),
|
||||||
], 'post', [$this, 'baseError']);
|
], 'post', [$this, 'baseError']);
|
||||||
@ -155,35 +152,39 @@ class InterfaceService extends Service
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 回复业务处理失败的消息
|
* 回复业务处理失败的消息.
|
||||||
* @param mixed $info 消息内容
|
* @param mixed $info 消息内容
|
||||||
* @param mixed $data 返回数据
|
* @param mixed $data 返回数据
|
||||||
* @param mixed $code 返回状态码
|
* @param mixed $code 返回状态码
|
||||||
*/
|
*/
|
||||||
public function error($info, $data = '{-null-}', $code = 0): void
|
public function error($info, $data = '{-null-}', $code = 0): void
|
||||||
{
|
{
|
||||||
if ($data === '{-null-}') $data = new stdClass();
|
if ($data === '{-null-}') {
|
||||||
|
$data = new \stdClass();
|
||||||
|
}
|
||||||
$this->baseResponse(lang('请求响应异常!'), [
|
$this->baseResponse(lang('请求响应异常!'), [
|
||||||
'code' => $code, 'info' => $info, 'data' => $data,
|
'code' => $code, 'info' => $info, 'data' => $data,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 回复业务处理成功的消息
|
* 回复业务处理成功的消息.
|
||||||
* @param mixed $info 消息内容
|
* @param mixed $info 消息内容
|
||||||
* @param mixed $data 返回数据
|
* @param mixed $data 返回数据
|
||||||
* @param mixed $code 返回状态码
|
* @param mixed $code 返回状态码
|
||||||
*/
|
*/
|
||||||
public function success($info, $data = '{-null-}', $code = 1): void
|
public function success($info, $data = '{-null-}', $code = 1): void
|
||||||
{
|
{
|
||||||
if ($data === '{-null-}') $data = new stdClass();
|
if ($data === '{-null-}') {
|
||||||
|
$data = new \stdClass();
|
||||||
|
}
|
||||||
$this->baseResponse(lang('请求响应成功!'), [
|
$this->baseResponse(lang('请求响应成功!'), [
|
||||||
'code' => $code, 'info' => is_string($info) ? lang($info) : $info, 'data' => $data,
|
'code' => $code, 'info' => is_string($info) ? lang($info) : $info, 'data' => $data,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 回复根失败消息
|
* 回复根失败消息.
|
||||||
* @param mixed $info 消息内容
|
* @param mixed $info 消息内容
|
||||||
* @param mixed $data 返回数据
|
* @param mixed $data 返回数据
|
||||||
* @param mixed $code 根状态码
|
* @param mixed $code 根状态码
|
||||||
@ -194,7 +195,7 @@ class InterfaceService extends Service
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 回复根成功消息
|
* 回复根成功消息.
|
||||||
* @param mixed $info 消息内容
|
* @param mixed $info 消息内容
|
||||||
* @param mixed $data 返回数据
|
* @param mixed $data 返回数据
|
||||||
* @param mixed $code 根状态码
|
* @param mixed $code 根状态码
|
||||||
@ -205,7 +206,7 @@ class InterfaceService extends Service
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 回复根签名消息
|
* 回复根签名消息.
|
||||||
* @param mixed $info 消息内容
|
* @param mixed $info 消息内容
|
||||||
* @param mixed $data 返回数据
|
* @param mixed $data 返回数据
|
||||||
* @param mixed $code 根状态码
|
* @param mixed $code 根状态码
|
||||||
@ -224,8 +225,7 @@ class InterfaceService extends Service
|
|||||||
* 接口数据模拟请求
|
* 接口数据模拟请求
|
||||||
* @param string $uri 接口地址
|
* @param string $uri 接口地址
|
||||||
* @param array $data 请求数据
|
* @param array $data 请求数据
|
||||||
* @param boolean $check 验证结果
|
* @param bool $check 验证结果
|
||||||
* @return array
|
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public function doRequest(string $uri, array $data = [], bool $check = true): array
|
public function doRequest(string $uri, array $data = [], bool $check = true): array
|
||||||
@ -237,21 +237,26 @@ class InterfaceService extends Service
|
|||||||
throw new Exception(lang('接口请求响应格式异常!'));
|
throw new Exception(lang('接口请求响应格式异常!'));
|
||||||
}
|
}
|
||||||
// 返回业务异常结果
|
// 返回业务异常结果
|
||||||
if (empty($result['code'])) throw new Exception($result['info']);
|
if (empty($result['code'])) {
|
||||||
|
throw new Exception($result['info']);
|
||||||
|
}
|
||||||
$array = is_array($result['data']) ? $result['data'] : json_decode($result['data'], true);
|
$array = is_array($result['data']) ? $result['data'] : json_decode($result['data'], true);
|
||||||
// 无需验证直接返回
|
// 无需验证直接返回
|
||||||
if (empty($check)) return $array;
|
if (empty($check)) {
|
||||||
|
return $array;
|
||||||
|
}
|
||||||
// 返回结果签名验证
|
// 返回结果签名验证
|
||||||
$json = is_string($result['data']) ? $result['data'] : json_encode($result['data'], JSON_UNESCAPED_UNICODE);
|
$json = is_string($result['data']) ? $result['data'] : json_encode($result['data'], JSON_UNESCAPED_UNICODE);
|
||||||
$build = $this->signString($json, $result['time'], $result['nostr']);
|
$build = $this->signString($json, $result['time'], $result['nostr']);
|
||||||
if ($build['sign'] === $result['sign']) return $array ?: [];
|
if ($build['sign'] === $result['sign']) {
|
||||||
|
return $array ?: [];
|
||||||
|
}
|
||||||
throw new Exception(lang('返回结果签名验证失败!'));
|
throw new Exception(lang('返回结果签名验证失败!'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 接口响应数据签名
|
* 接口响应数据签名.
|
||||||
* @param array $data ['appid','nostr','time','sign','data']
|
* @param array $data ['appid','nostr','time','sign','data']
|
||||||
* @return array
|
|
||||||
*/
|
*/
|
||||||
private function signData(array $data): array
|
private function signData(array $data): array
|
||||||
{
|
{
|
||||||
@ -259,11 +264,10 @@ class InterfaceService extends Service
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 数据字符串数据签名
|
* 数据字符串数据签名.
|
||||||
* @param string $json 待签名的数据
|
* @param string $json 待签名的数据
|
||||||
* @param mixed $time 签名的时间戳
|
* @param mixed $time 签名的时间戳
|
||||||
* @param mixed $rand 签名随机字符
|
* @param mixed $rand 签名随机字符
|
||||||
* @return array
|
|
||||||
*/
|
*/
|
||||||
private function signString(string $json, $time = null, $rand = null): array
|
private function signString(string $json, $time = null, $rand = null): array
|
||||||
{
|
{
|
||||||
@ -272,4 +276,4 @@ class InterfaceService extends Service
|
|||||||
$sign = md5("{$this->appid}#{$json}#{$time}#{$this->appkey}#{$rand}");
|
$sign = md5("{$this->appid}#{$json}#{$time}#{$this->appkey}#{$rand}");
|
||||||
return ['appid' => $this->appid, 'nostr' => $rand, 'time' => $time, 'sign' => $sign, 'data' => $json];
|
return ['appid' => $this->appid, 'nostr' => $rand, 'time' => $time, 'sign' => $sign, 'data' => $json];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,84 +1,89 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// +----------------------------------------------------------------------
|
declare(strict_types=1);
|
||||||
// | Library for ThinkAdmin
|
/**
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 版权所有 2014~2025 ThinkAdmin [ thinkadmin.top ]
|
* | Payment Plugin for ThinkAdmin
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 官方网站: https://thinkadmin.top
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 开源协议 ( https://mit-license.org )
|
* | 官方网站: https://thinkadmin.top
|
||||||
// | 免费声明 ( https://thinkadmin.top/disclaimer )
|
* +----------------------------------------------------------------------
|
||||||
// +----------------------------------------------------------------------
|
* | 开源协议 ( https://mit-license.org )
|
||||||
// | gitee 仓库地址 :https://gitee.com/zoujingli/ThinkLibrary
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
// | github 仓库地址 :https://github.com/zoujingli/ThinkLibrary
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
declare (strict_types=1);
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
namespace think\admin\service;
|
namespace think\admin\service;
|
||||||
|
|
||||||
use think\admin\extend\DataExtend;
|
use think\admin\extend\DataExtend;
|
||||||
use think\admin\model\SystemMenu;
|
use think\admin\model\SystemMenu;
|
||||||
use think\admin\Service;
|
use think\admin\Service;
|
||||||
|
use think\db\exception\DataNotFoundException;
|
||||||
|
use think\db\exception\DbException;
|
||||||
|
use think\db\exception\ModelNotFoundException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 系统菜单管理服务
|
* 系统菜单管理服务
|
||||||
* @class MenuService
|
* @class MenuService
|
||||||
* @package app\admin\service
|
|
||||||
*/
|
*/
|
||||||
class MenuService extends Service
|
class MenuService extends Service
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* 获取可选菜单节点.
|
||||||
|
* @param bool $force 强制刷新
|
||||||
|
*/
|
||||||
|
public static function getList(bool $force = false): array
|
||||||
|
{
|
||||||
|
$nodes = sysvar($keys = 'think.admin.menus') ?: [];
|
||||||
|
if (empty($force) && count($nodes) > 0) {
|
||||||
|
return $nodes;
|
||||||
|
} $nodes = [];
|
||||||
|
foreach (NodeService::getMethods($force) as $node => $method) {
|
||||||
|
if ($method['ismenu']) {
|
||||||
|
$nodes[] = ['node' => $node, 'title' => self::lang($method['title'])];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sysvar($keys, $nodes);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 菜单分组语言包
|
* 获取系统菜单树数据.
|
||||||
* @param string $name
|
* @throws DataNotFoundException
|
||||||
* @return string
|
* @throws DbException
|
||||||
|
* @throws ModelNotFoundException
|
||||||
|
*/
|
||||||
|
public static function getTree(): array
|
||||||
|
{
|
||||||
|
$menus = SystemMenu::mk()->where(['status' => 1])->order('sort desc,id asc')->select()->toArray();
|
||||||
|
if (function_exists('admin_menu_filter')) {
|
||||||
|
$menus = call_user_func('admin_menu_filter', $menus);
|
||||||
|
}
|
||||||
|
foreach ($menus as &$menu) {
|
||||||
|
$menu['title'] = self::lang($menu['title']);
|
||||||
|
}
|
||||||
|
return static::filter(DataExtend::arr2tree($menus));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 菜单分组语言包.
|
||||||
*/
|
*/
|
||||||
private static function lang(string $name): string
|
private static function lang(string $name): string
|
||||||
{
|
{
|
||||||
$lang = lang("menus_{$name}");
|
$lang = lang("menus_{$name}");
|
||||||
if (stripos($lang, 'menus_') === 0) {
|
if (stripos($lang, 'menus_') === 0) {
|
||||||
return lang(substr($lang, 6));
|
return lang(substr($lang, 6));
|
||||||
} else {
|
|
||||||
return $lang;
|
|
||||||
}
|
}
|
||||||
|
return $lang;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取可选菜单节点
|
* 后台主菜单权限过滤.
|
||||||
* @param boolean $force 强制刷新
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public static function getList(bool $force = false): array
|
|
||||||
{
|
|
||||||
$nodes = sysvar($keys = 'think.admin.menus') ?: [];
|
|
||||||
if (empty($force) && count($nodes) > 0) return $nodes; else $nodes = [];
|
|
||||||
foreach (NodeService::getMethods($force) as $node => $method) {
|
|
||||||
if ($method['ismenu']) $nodes[] = ['node' => $node, 'title' => self::lang($method['title'])];
|
|
||||||
}
|
|
||||||
return sysvar($keys, $nodes);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取系统菜单树数据
|
|
||||||
* @return array
|
|
||||||
* @throws \think\db\exception\DataNotFoundException
|
|
||||||
* @throws \think\db\exception\DbException
|
|
||||||
* @throws \think\db\exception\ModelNotFoundException
|
|
||||||
*/
|
|
||||||
public static function getTree(): array
|
|
||||||
{
|
|
||||||
$menus = SystemMenu::mk()->where(['status' => 1])->order('sort desc,id asc')->select()->toArray();
|
|
||||||
if (function_exists('admin_menu_filter')) $menus = call_user_func('admin_menu_filter', $menus);
|
|
||||||
foreach ($menus as &$menu) $menu['title'] = self::lang($menu['title']);
|
|
||||||
return static::filter(DataExtend::arr2tree($menus));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 后台主菜单权限过滤
|
|
||||||
* @param array $menus 当前菜单列表
|
* @param array $menus 当前菜单列表
|
||||||
* @return array
|
|
||||||
*/
|
*/
|
||||||
private static function filter(array $menus): array
|
private static function filter(array $menus): array
|
||||||
{
|
{
|
||||||
@ -91,13 +96,17 @@ class MenuService extends Service
|
|||||||
} elseif (empty($menu['url']) || $menu['url'] === '#' || !(empty($menu['node']) || AdminService::check($menu['node']))) {
|
} elseif (empty($menu['url']) || $menu['url'] === '#' || !(empty($menu['node']) || AdminService::check($menu['node']))) {
|
||||||
unset($menus[$key]);
|
unset($menus[$key]);
|
||||||
} elseif (preg_match('#^(https?:)?//\w+#i', $menu['url'])) {
|
} elseif (preg_match('#^(https?:)?//\w+#i', $menu['url'])) {
|
||||||
if ($menu['params']) $menu['url'] .= (strpos($menu['url'], '?') === false ? '?' : '&') . $menu['params'];
|
if ($menu['params']) {
|
||||||
|
$menu['url'] .= (strpos($menu['url'], '?') === false ? '?' : '&') . $menu['params'];
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
$node = join('/', array_slice(str2arr($menu['url'], '/'), 0, 3));
|
$node = join('/', array_slice(str2arr($menu['url'], '/'), 0, 3));
|
||||||
$menu['url'] = admuri($menu['url']) . ($menu['params'] ? '?' . $menu['params'] : '');
|
$menu['url'] = admuri($menu['url']) . ($menu['params'] ? '?' . $menu['params'] : '');
|
||||||
if (!AdminService::check($node)) unset($menus[$key]);
|
if (!AdminService::check($node)) {
|
||||||
|
unset($menus[$key]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return $menus;
|
return $menus;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,30 +1,32 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// +----------------------------------------------------------------------
|
declare(strict_types=1);
|
||||||
// | Library for ThinkAdmin
|
/**
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 版权所有 2014~2025 ThinkAdmin [ thinkadmin.top ]
|
* | Payment Plugin for ThinkAdmin
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 官方网站: https://thinkadmin.top
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 开源协议 ( https://mit-license.org )
|
* | 官方网站: https://thinkadmin.top
|
||||||
// | 免费声明 ( https://thinkadmin.top/disclaimer )
|
* +----------------------------------------------------------------------
|
||||||
// +----------------------------------------------------------------------
|
* | 开源协议 ( https://mit-license.org )
|
||||||
// | gitee 仓库地址 :https://gitee.com/zoujingli/ThinkLibrary
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
// | github 仓库地址 :https://github.com/zoujingli/ThinkLibrary
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
declare (strict_types=1);
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
namespace think\admin\service;
|
namespace think\admin\service;
|
||||||
|
|
||||||
|
use think\admin\Exception;
|
||||||
use think\admin\extend\HttpExtend;
|
use think\admin\extend\HttpExtend;
|
||||||
use think\admin\Service;
|
use think\admin\Service;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 旧助通短信接口服务
|
* 旧助通短信接口服务
|
||||||
* @class MessageService
|
* @class MessageService
|
||||||
* @package app\store\service
|
|
||||||
* @deprecated 建议使用云平台服务
|
* @deprecated 建议使用云平台服务
|
||||||
* =================================
|
* =================================
|
||||||
*
|
*
|
||||||
@ -55,28 +57,31 @@ use think\admin\Service;
|
|||||||
*/
|
*/
|
||||||
class MessageService extends Service
|
class MessageService extends Service
|
||||||
{
|
{
|
||||||
|
|
||||||
private $table;
|
private $table;
|
||||||
|
|
||||||
private $chinaUsername;
|
private $chinaUsername;
|
||||||
|
|
||||||
private $chinaPassword;
|
private $chinaPassword;
|
||||||
|
|
||||||
private $globeUsername;
|
private $globeUsername;
|
||||||
|
|
||||||
private $globePassword;
|
private $globePassword;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return $this
|
* 错误消息处理.
|
||||||
* @throws \think\admin\Exception
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected function initialize(): MessageService
|
private $globeMessageMap = [
|
||||||
{
|
2 => '用户账号为空',
|
||||||
$this->table = 'SystemMessageHistory';
|
3 => '用户账号错误',
|
||||||
$this->chinaUsername = sysconf('sms_zt.china_username|raw');
|
4 => '授权密码为空',
|
||||||
$this->chinaPassword = sysconf('sms_zt.china_password|raw');
|
5 => '授权密码错误',
|
||||||
$this->globeUsername = sysconf('sms_zt.globe_username|raw');
|
6 => '当前时间为空',
|
||||||
$this->globePassword = sysconf('sms_zt.globe_password|raw');
|
7 => '当前时间错误',
|
||||||
return $this;
|
8 => '用户类型错误',
|
||||||
}
|
9 => '用户鉴权错误',
|
||||||
|
10 => '请求IP已被列入黑名单',
|
||||||
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 配置内陆短信认证
|
* 配置内陆短信认证
|
||||||
@ -105,8 +110,7 @@ class MessageService extends Service
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置存储数据表
|
* 设置存储数据表.
|
||||||
* @param string $table
|
|
||||||
* @return $this
|
* @return $this
|
||||||
*/
|
*/
|
||||||
public function setSaveTable(string $table): MessageService
|
public function setSaveTable(string $table): MessageService
|
||||||
@ -116,10 +120,7 @@ class MessageService extends Service
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 生成短信内容
|
* 生成短信内容.
|
||||||
* @param string $content
|
|
||||||
* @param array $params
|
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public function buildContent(string $content, array $params = []): string
|
public function buildContent(string $content, array $params = []): string
|
||||||
{
|
{
|
||||||
@ -131,25 +132,24 @@ class MessageService extends Service
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 发送国内短信验证码
|
* 发送国内短信验证码
|
||||||
* @param integer|string $phone 手机号
|
* @param int|string $phone 手机号
|
||||||
* @param integer|string $content 短信内容
|
* @param int|string $content 短信内容
|
||||||
* @param integer|string $productid 短信通道
|
* @param int|string $productid 短信通道
|
||||||
* @return boolean
|
|
||||||
*/
|
*/
|
||||||
public function sendChinaSms($phone, $content, $productid = '676767'): bool
|
public function sendChinaSms($phone, $content, $productid = '676767'): bool
|
||||||
{
|
{
|
||||||
$tkey = date("YmdHis");
|
$tkey = date('YmdHis');
|
||||||
$result = HttpExtend::get('http' . '://www.ztsms.cn/sendNSms.do', [
|
$result = HttpExtend::get('http://www.ztsms.cn/sendNSms.do', [
|
||||||
'tkey' => $tkey,
|
'tkey' => $tkey,
|
||||||
'mobile' => $phone,
|
'mobile' => $phone,
|
||||||
'content' => $content,
|
'content' => $content,
|
||||||
'username' => $this->chinaUsername,
|
'username' => $this->chinaUsername,
|
||||||
'productid' => $productid,
|
'productid' => $productid,
|
||||||
'password' => md5(md5($this->chinaPassword) . $tkey),
|
'password' => md5(md5($this->chinaPassword) . $tkey),
|
||||||
]);
|
]);
|
||||||
[$code] = explode(',', $result . ',');
|
[$code] = explode(',', $result . ',');
|
||||||
$this->app->db->name($this->table)->insert([
|
$this->app->db->name($this->table)->insert([
|
||||||
'phone' => $phone, 'region' => '860',
|
'phone' => $phone, 'region' => '860',
|
||||||
'content' => $content, 'result' => $result,
|
'content' => $content, 'result' => $result,
|
||||||
]);
|
]);
|
||||||
return intval($code) === 1;
|
return intval($code) === 1;
|
||||||
@ -157,11 +157,10 @@ class MessageService extends Service
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 发送国内短信验证码
|
* 发送国内短信验证码
|
||||||
* @param integer|string $phone 目标手机
|
* @param int|string $phone 目标手机
|
||||||
* @param integer $wait 等待时间
|
* @param int $wait 等待时间
|
||||||
* @param string $type 短信模板
|
* @param string $type 短信模板
|
||||||
* @return array
|
* @throws Exception
|
||||||
* @throws \think\admin\Exception
|
|
||||||
*/
|
*/
|
||||||
public function sendChinaSmsByCode($phone, int $wait = 120, string $type = 'sms_reg_template'): array
|
public function sendChinaSmsByCode($phone, int $wait = 120, string $type = 'sms_reg_template'): array
|
||||||
{
|
{
|
||||||
@ -178,17 +177,15 @@ class MessageService extends Service
|
|||||||
if ($this->sendChinaSms($phone, str_replace('{code}', $code, $content))) {
|
if ($this->sendChinaSms($phone, str_replace('{code}', $code, $content))) {
|
||||||
$dtime = ($cache['time'] + $wait < time()) ? 0 : ($wait - time() + $cache['time']);
|
$dtime = ($cache['time'] + $wait < time()) ? 0 : ($wait - time() + $cache['time']);
|
||||||
return [1, lang('短信验证码发送成功!'), ['time' => $dtime]];
|
return [1, lang('短信验证码发送成功!'), ['time' => $dtime]];
|
||||||
} else {
|
|
||||||
return [0, lang('短信发送失败,请稍候再试!'), []];
|
|
||||||
}
|
}
|
||||||
|
return [0, lang('短信发送失败,请稍候再试!'), []];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 验证手机短信验证码
|
* 验证手机短信验证码
|
||||||
* @param integer|string $phone 目标手机
|
* @param int|string $phone 目标手机
|
||||||
* @param integer|string $code 短信验证码
|
* @param int|string $code 短信验证码
|
||||||
* @param string $type 短信模板
|
* @param string $type 短信模板
|
||||||
* @return boolean
|
|
||||||
*/
|
*/
|
||||||
public function check($phone, $code, string $type = 'sms_reg_template'): bool
|
public function check($phone, $code, string $type = 'sms_reg_template'): bool
|
||||||
{
|
{
|
||||||
@ -197,59 +194,43 @@ class MessageService extends Service
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询国内短信余额
|
* 查询国内短信余额.
|
||||||
* @return array
|
|
||||||
*/
|
*/
|
||||||
public function queryChinaSmsBalance(): array
|
public function queryChinaSmsBalance(): array
|
||||||
{
|
{
|
||||||
$tkey = date("YmdHis");
|
$tkey = date('YmdHis');
|
||||||
$result = HttpExtend::get('http' . '://www.ztsms.cn/balanceN.do', [
|
$result = HttpExtend::get('http://www.ztsms.cn/balanceN.do', [
|
||||||
'username' => $this->chinaUsername, 'tkey' => $tkey,
|
'username' => $this->chinaUsername, 'tkey' => $tkey,
|
||||||
'password' => md5(md5($this->chinaPassword) . $tkey),
|
'password' => md5(md5($this->chinaPassword) . $tkey),
|
||||||
]);
|
]);
|
||||||
if ($result > -1) {
|
if ($result > -1) {
|
||||||
return ['code' => 1, 'num' => $result, 'msg' => lang('获取短信剩余条数成功!')];
|
return ['code' => 1, 'num' => $result, 'msg' => lang('获取短信剩余条数成功!')];
|
||||||
} elseif ($result > -2) {
|
|
||||||
return ['code' => 0, 'num' => '0', 'msg' => lang('用户名或者密码不正确!')];
|
|
||||||
} elseif ($result > -3) {
|
|
||||||
return ['code' => 0, 'num' => '0', 'msg' => lang('tkey不正确!')];
|
|
||||||
} elseif ($result > -4) {
|
|
||||||
return ['code' => 0, 'num' => '0', 'msg' => lang('用户不存在或用户停用!')];
|
|
||||||
} else {
|
|
||||||
return ['code' => 0, 'num' => '0', 'msg' => lang('未知错误原因!')];
|
|
||||||
}
|
}
|
||||||
|
if ($result > -2) {
|
||||||
|
return ['code' => 0, 'num' => '0', 'msg' => lang('用户名或者密码不正确!')];
|
||||||
|
}
|
||||||
|
if ($result > -3) {
|
||||||
|
return ['code' => 0, 'num' => '0', 'msg' => lang('tkey不正确!')];
|
||||||
|
}
|
||||||
|
if ($result > -4) {
|
||||||
|
return ['code' => 0, 'num' => '0', 'msg' => lang('用户不存在或用户停用!')];
|
||||||
|
}
|
||||||
|
return ['code' => 0, 'num' => '0', 'msg' => lang('未知错误原因!')];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 错误消息处理
|
* 发送国际短信内容.
|
||||||
* @var array
|
* @param int|string $code 国家代码
|
||||||
*/
|
* @param int|string $mobile 手机号码
|
||||||
private $globeMessageMap = [
|
|
||||||
2 => '用户账号为空',
|
|
||||||
3 => '用户账号错误',
|
|
||||||
4 => '授权密码为空',
|
|
||||||
5 => '授权密码错误',
|
|
||||||
6 => '当前时间为空',
|
|
||||||
7 => '当前时间错误',
|
|
||||||
8 => '用户类型错误',
|
|
||||||
9 => '用户鉴权错误',
|
|
||||||
10 => '请求IP已被列入黑名单',
|
|
||||||
];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 发送国际短信内容
|
|
||||||
* @param integer|string $code 国家代码
|
|
||||||
* @param integer|string $mobile 手机号码
|
|
||||||
* @param string $content 发送内容
|
* @param string $content 发送内容
|
||||||
* @return boolean
|
* @throws Exception
|
||||||
* @throws \think\admin\Exception
|
|
||||||
*/
|
*/
|
||||||
public function sendGlobeSms($code, $mobile, string $content): bool
|
public function sendGlobeSms($code, $mobile, string $content): bool
|
||||||
{
|
{
|
||||||
$tkey = date("YmdHis");
|
$tkey = date('YmdHis');
|
||||||
$result = HttpExtend::get('http' . '://intl.zthysms.com/intSendSms.do', [
|
$result = HttpExtend::get('http://intl.zthysms.com/intSendSms.do', [
|
||||||
'tkey' => $tkey, 'code' => $code, 'mobile' => $mobile,
|
'tkey' => $tkey, 'code' => $code, 'mobile' => $mobile,
|
||||||
'content' => $content, 'username' => sysconf('sms_zt_username2|raw'),
|
'content' => $content, 'username' => sysconf('sms_zt_username2|raw'),
|
||||||
'password' => md5(md5(sysconf('sms_zt_password2|raw')) . $tkey),
|
'password' => md5(md5(sysconf('sms_zt_password2|raw')) . $tkey),
|
||||||
]);
|
]);
|
||||||
$this->app->db->name($this->table)->insert([
|
$this->app->db->name($this->table)->insert([
|
||||||
@ -259,25 +240,22 @@ class MessageService extends Service
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询国际短信余额
|
* 查询国际短信余额.
|
||||||
* @return array
|
|
||||||
*/
|
*/
|
||||||
public function queryGlobeSmsBalance(): array
|
public function queryGlobeSmsBalance(): array
|
||||||
{
|
{
|
||||||
$tkey = date("YmdHis");
|
$tkey = date('YmdHis');
|
||||||
$result = HttpExtend::get('http' . '://intl.zthysms.com/intBalance.do', [
|
$result = HttpExtend::get('http://intl.zthysms.com/intBalance.do', [
|
||||||
'username' => $this->globeUsername, 'tkey' => $tkey, 'password' => md5(md5($this->globePassword) . $tkey),
|
'username' => $this->globeUsername, 'tkey' => $tkey, 'password' => md5(md5($this->globePassword) . $tkey),
|
||||||
]);
|
]);
|
||||||
if (!is_numeric($result) && ($state = intval($result)) && isset($this->globeMessageMap[$state])) {
|
if (!is_numeric($result) && ($state = intval($result)) && isset($this->globeMessageMap[$state])) {
|
||||||
return ['code' => 0, 'num' => 0, 'msg' => lang($this->globeMessageMap[$state])];
|
return ['code' => 0, 'num' => 0, 'msg' => lang($this->globeMessageMap[$state])];
|
||||||
} else {
|
|
||||||
return ['code' => 1, 'num' => $result, 'msg' => lang('查询成功')];
|
|
||||||
}
|
}
|
||||||
|
return ['code' => 1, 'num' => $result, 'msg' => lang('查询成功')];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取国际地域编号
|
* 获取国际地域编号.
|
||||||
* @return array
|
|
||||||
*/
|
*/
|
||||||
public function getGlobeRegionMap(): array
|
public function getGlobeRegionMap(): array
|
||||||
{
|
{
|
||||||
@ -502,4 +480,18 @@ class MessageService extends Service
|
|||||||
['title' => '黑山共和国', 'english' => 'The Republic of Montenegro', 'code' => 382],
|
['title' => '黑山共和国', 'english' => 'The Republic of Montenegro', 'code' => 382],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return $this
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
protected function initialize(): MessageService
|
||||||
|
{
|
||||||
|
$this->table = 'SystemMessageHistory';
|
||||||
|
$this->chinaUsername = sysconf('sms_zt.china_username|raw');
|
||||||
|
$this->chinaPassword = sysconf('sms_zt.china_password|raw');
|
||||||
|
$this->globeUsername = sysconf('sms_zt.globe_username|raw');
|
||||||
|
$this->globePassword = sysconf('sms_zt.globe_password|raw');
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,20 +1,22 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// +----------------------------------------------------------------------
|
declare(strict_types=1);
|
||||||
// | Library for ThinkAdmin
|
/**
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 版权所有 2014~2025 ThinkAdmin [ thinkadmin.top ]
|
* | Payment Plugin for ThinkAdmin
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 官方网站: https://thinkadmin.top
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 开源协议 ( https://mit-license.org )
|
* | 官方网站: https://thinkadmin.top
|
||||||
// | 免费声明 ( https://thinkadmin.top/disclaimer )
|
* +----------------------------------------------------------------------
|
||||||
// +----------------------------------------------------------------------
|
* | 开源协议 ( https://mit-license.org )
|
||||||
// | gitee 仓库地址 :https://gitee.com/zoujingli/ThinkLibrary
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
// | github 仓库地址 :https://github.com/zoujingli/ThinkLibrary
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
declare (strict_types=1);
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
namespace think\admin\service;
|
namespace think\admin\service;
|
||||||
|
|
||||||
@ -22,15 +24,13 @@ use think\admin\Library;
|
|||||||
use think\admin\Service;
|
use think\admin\Service;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 系统模块管理
|
* 系统模块管理.
|
||||||
* @class ModuleService
|
* @class ModuleService
|
||||||
* @package think\admin\service
|
|
||||||
*/
|
*/
|
||||||
class ModuleService extends Service
|
class ModuleService extends Service
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* 获取版本号信息
|
* 获取版本号信息.
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public static function getVersion(): string
|
public static function getVersion(): string
|
||||||
{
|
{
|
||||||
@ -39,55 +39,55 @@ class ModuleService extends Service
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取运行参数变量
|
* 获取运行参数变量.
|
||||||
* @param string $field 指定字段
|
* @param string $field 指定字段
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public static function getRunVar(string $field): string
|
public static function getRunVar(string $field): string
|
||||||
{
|
{
|
||||||
$file = syspath('vendor/binarys.php');
|
$file = syspath('vendor/binarys.php');
|
||||||
if (is_file($file) && is_array($binarys = include $file)) {
|
if (is_file($file) && is_array($binarys = include $file)) {
|
||||||
return $binarys[$field] ?? '';
|
return $binarys[$field] ?? '';
|
||||||
} else {
|
|
||||||
return '';
|
|
||||||
}
|
}
|
||||||
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取 PHP 执行路径
|
* 获取 PHP 执行路径.
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public static function getPhpExec(): string
|
public static function getPhpExec(): string
|
||||||
{
|
{
|
||||||
if ($phpExec = sysvar($keys = 'phpBinary')) return $phpExec;
|
if ($phpExec = sysvar($keys = 'phpBinary')) {
|
||||||
|
return $phpExec;
|
||||||
|
}
|
||||||
if (ProcessService::isFile($phpExec = self::getRunVar('php'))) {
|
if (ProcessService::isFile($phpExec = self::getRunVar('php'))) {
|
||||||
return sysvar($keys, $phpExec);
|
return sysvar($keys, $phpExec);
|
||||||
} else {
|
|
||||||
$phpExec = str_replace('/sbin/php-fpm', '/bin/php', PHP_BINARY);
|
|
||||||
$phpExec = preg_replace('#-(cgi|fpm)(\.exe)?$#', '$2', $phpExec);
|
|
||||||
return sysvar($keys, ProcessService::isFile($phpExec) ? $phpExec : 'php');
|
|
||||||
}
|
}
|
||||||
|
$phpExec = str_replace('/sbin/php-fpm', '/bin/php', PHP_BINARY);
|
||||||
|
$phpExec = preg_replace('#-(cgi|fpm)(\.exe)?$#', '$2', $phpExec);
|
||||||
|
return sysvar($keys, ProcessService::isFile($phpExec) ? $phpExec : 'php');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取应用模块
|
* 获取应用模块.
|
||||||
* @param array $data
|
|
||||||
* @return array
|
|
||||||
*/
|
*/
|
||||||
public static function getModules(array $data = []): array
|
public static function getModules(array $data = []): array
|
||||||
{
|
{
|
||||||
$path = Library::$sapp->getBasePath();
|
$path = Library::$sapp->getBasePath();
|
||||||
foreach (scandir($path) as $item) if ($item[0] !== '.') {
|
foreach (scandir($path) as $item) {
|
||||||
if (is_dir($path . $item)) $data[] = $item;
|
if ($item[0] !== '.') {
|
||||||
|
if (is_dir($path . $item)) {
|
||||||
|
$data[] = $item;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return $data;
|
return $data;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取本地组件
|
* 获取本地组件.
|
||||||
* @param ?string $package 指定包名
|
* @param ?string $package 指定包名
|
||||||
* @param boolean $force 强制刷新
|
* @param bool $force 强制刷新
|
||||||
* @return array|string|null
|
* @return null|array|string
|
||||||
*/
|
*/
|
||||||
public static function getLibrarys(?string $package = null, bool $force = false)
|
public static function getLibrarys(?string $package = null, bool $force = false)
|
||||||
{
|
{
|
||||||
@ -97,4 +97,4 @@ class ModuleService extends Service
|
|||||||
}
|
}
|
||||||
return empty($package) ? $plugs : ($plugs[$package] ?? null);
|
return empty($package) ? $plugs : ($plugs[$package] ?? null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,25 +1,25 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// +----------------------------------------------------------------------
|
declare(strict_types=1);
|
||||||
// | Library for ThinkAdmin
|
/**
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 版权所有 2014~2025 ThinkAdmin [ thinkadmin.top ]
|
* | Payment Plugin for ThinkAdmin
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 官方网站: https://thinkadmin.top
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 开源协议 ( https://mit-license.org )
|
* | 官方网站: https://thinkadmin.top
|
||||||
// | 免费声明 ( https://thinkadmin.top/disclaimer )
|
* +----------------------------------------------------------------------
|
||||||
// +----------------------------------------------------------------------
|
* | 开源协议 ( https://mit-license.org )
|
||||||
// | gitee 仓库地址 :https://gitee.com/zoujingli/ThinkLibrary
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
// | github 仓库地址 :https://github.com/zoujingli/ThinkLibrary
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
declare (strict_types=1);
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
namespace think\admin\service;
|
namespace think\admin\service;
|
||||||
|
|
||||||
use ReflectionClass;
|
|
||||||
use ReflectionMethod;
|
|
||||||
use think\admin\Exception;
|
use think\admin\Exception;
|
||||||
use think\admin\extend\ToolsExtend;
|
use think\admin\extend\ToolsExtend;
|
||||||
use think\admin\Library;
|
use think\admin\Library;
|
||||||
@ -27,54 +27,78 @@ use think\admin\Plugin;
|
|||||||
use think\admin\Service;
|
use think\admin\Service;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 应用节点服务管理
|
* 应用节点服务管理.
|
||||||
* @class NodeService
|
* @class NodeService
|
||||||
* @method static array getModules() 获取应用列表
|
* @method static array getModules() 获取应用列表
|
||||||
* @method static array scanDirectory() 扫描目录列表
|
* @method static array scanDirectory() 扫描目录列表
|
||||||
* @package think\admin\service
|
|
||||||
*/
|
*/
|
||||||
class NodeService extends Service
|
class NodeService extends Service
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* 重构兼容处理.
|
||||||
|
* @return array
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public function __call(string $name, array $arguments)
|
||||||
|
{
|
||||||
|
return static::__callStatic($name, $arguments);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取默认应用空间名
|
* 重构兼容处理.
|
||||||
|
* @return array
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public static function __callStatic(string $name, array $arguments)
|
||||||
|
{
|
||||||
|
if ($name === 'scanDirectory') {
|
||||||
|
return ToolsExtend::scan(...$arguments);
|
||||||
|
}
|
||||||
|
if ($name === 'getModules') {
|
||||||
|
return ModuleService::getModules(...$arguments);
|
||||||
|
}
|
||||||
|
throw new Exception("method not exists: NodeService::{$name}()");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取默认应用空间名.
|
||||||
* @param string $suffix 后缀路径
|
* @param string $suffix 后缀路径
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public static function space(string $suffix = ''): string
|
public static function space(string $suffix = ''): string
|
||||||
{
|
{
|
||||||
$default = Library::$sapp->config->get('app.app_namespace') ?: 'app';
|
$default = Library::$sapp->config->get('app.app_namespace') ?: 'app';
|
||||||
return empty($suffix) ? $default : trim($default . '\\' . trim($suffix, '\\/'), '\\');
|
return empty($suffix) ? $default : trim($default . '\\' . trim($suffix, '\/'), '\\');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 驼峰转下划线规则
|
* 驼峰转下划线规则.
|
||||||
* @param string $name
|
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public static function nameTolower(string $name): string
|
public static function nameTolower(string $name): string
|
||||||
{
|
{
|
||||||
$dots = [];
|
$dots = [];
|
||||||
foreach (explode('.', strtr($name, '/', '.')) as $dot) {
|
foreach (explode('.', strtr($name, '/', '.')) as $dot) {
|
||||||
$dots[] = trim(preg_replace("/[A-Z]/", "_\\0", $dot), '_');
|
$dots[] = trim(preg_replace('/[A-Z]/', '_\0', $dot), '_');
|
||||||
}
|
}
|
||||||
return strtolower(join('.', $dots));
|
return strtolower(join('.', $dots));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取当前节点内容
|
* 获取当前节点内容.
|
||||||
* @param string $type app|module|controller|action
|
* @param string $type app|module|controller|action
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public static function getCurrent(string $type = ''): string
|
public static function getCurrent(string $type = ''): string
|
||||||
{
|
{
|
||||||
// 获取应用节点
|
// 获取应用节点
|
||||||
$appname = strtolower(Library::$sapp->http->getName());
|
$appname = strtolower(Library::$sapp->http->getName());
|
||||||
if (in_array($type, ['app', 'module'])) return $appname;
|
if (in_array($type, ['app', 'module'])) {
|
||||||
|
return $appname;
|
||||||
|
}
|
||||||
|
|
||||||
// 获取控制器节点
|
// 获取控制器节点
|
||||||
$controller = static::nameTolower(Library::$sapp->request->controller());
|
$controller = static::nameTolower(Library::$sapp->request->controller());
|
||||||
if ($type === 'controller') return "{$appname}/{$controller}";
|
if ($type === 'controller') {
|
||||||
|
return "{$appname}/{$controller}";
|
||||||
|
}
|
||||||
|
|
||||||
// 获取方法权限节点
|
// 获取方法权限节点
|
||||||
$method = strtolower(Library::$sapp->request->action());
|
$method = strtolower(Library::$sapp->request->action());
|
||||||
@ -82,13 +106,13 @@ class NodeService extends Service
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 检查并完整节点内容
|
* 检查并完整节点内容.
|
||||||
* @param ?string $node
|
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public static function fullNode(?string $node = ''): string
|
public static function fullNode(?string $node = ''): string
|
||||||
{
|
{
|
||||||
if (empty($node)) return static::getCurrent();
|
if (empty($node)) {
|
||||||
|
return static::getCurrent();
|
||||||
|
}
|
||||||
switch (count($attrs = explode('/', $node))) {
|
switch (count($attrs = explode('/', $node))) {
|
||||||
case 1: # 方法名
|
case 1: # 方法名
|
||||||
return static::getCurrent('controller') . '/' . strtolower($node);
|
return static::getCurrent('controller') . '/' . strtolower($node);
|
||||||
@ -102,16 +126,17 @@ class NodeService extends Service
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取所有控制器入口
|
* 获取所有控制器入口.
|
||||||
* @param boolean $force 强制更新
|
* @param bool $force 强制更新
|
||||||
* @return array
|
|
||||||
*/
|
*/
|
||||||
public static function getMethods(bool $force = false): array
|
public static function getMethods(bool $force = false): array
|
||||||
{
|
{
|
||||||
$skey = 'think.admin.methods';
|
$skey = 'think.admin.methods';
|
||||||
if (empty($force)) {
|
if (empty($force)) {
|
||||||
$data = sysvar($skey) ?: Library::$sapp->cache->get('SystemAuthNode', []);
|
$data = sysvar($skey) ?: Library::$sapp->cache->get('SystemAuthNode', []);
|
||||||
if (count($data) > 0) return sysvar($skey, $data);
|
if (count($data) > 0) {
|
||||||
|
return sysvar($skey, $data);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
$data = [];
|
$data = [];
|
||||||
}
|
}
|
||||||
@ -120,18 +145,22 @@ class NodeService extends Service
|
|||||||
$ignoreAppNames = Library::$sapp->config->get('app.rbac_ignore', []);
|
$ignoreAppNames = Library::$sapp->config->get('app.rbac_ignore', []);
|
||||||
// 扫描所有代码控制器节点,更新节点缓存
|
// 扫描所有代码控制器节点,更新节点缓存
|
||||||
foreach (ToolsExtend::scan(Library::$sapp->getBasePath(), null, 'php') as $name) {
|
foreach (ToolsExtend::scan(Library::$sapp->getBasePath(), null, 'php') as $name) {
|
||||||
if (preg_match("|^(\w+)/controller/(.+)\.php$|i", strtr($name, '\\', '/'), $matches)) {
|
if (preg_match('|^(\w+)/controller/(.+)\.php$|i', strtr($name, '\\', '/'), $matches)) {
|
||||||
[, $appName, $className] = $matches;
|
[, $appName, $className] = $matches;
|
||||||
if (in_array($appName, $ignoreAppNames)) continue;
|
if (in_array($appName, $ignoreAppNames)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
static::_parseClass($appName, self::space($appName), $className, $ignoreMethods, $data);
|
static::_parseClass($appName, self::space($appName), $className, $ignoreMethods, $data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 扫描所有插件代码
|
// 扫描所有插件代码
|
||||||
foreach (Plugin::get() as $appName => $plugin) {
|
foreach (Plugin::get() as $appName => $plugin) {
|
||||||
if (in_array($appName, $ignoreAppNames)) continue;
|
if (in_array($appName, $ignoreAppNames)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
[$appPath, $appSpace] = [$plugin['path'], $plugin['space']];
|
[$appPath, $appSpace] = [$plugin['path'], $plugin['space']];
|
||||||
foreach (ToolsExtend::scan($appPath, null, 'php') as $name) {
|
foreach (ToolsExtend::scan($appPath, null, 'php') as $name) {
|
||||||
if (preg_match("|^.*?controller/(.+)\.php$|i", strtr($name, '\\', '/'), $matches)) {
|
if (preg_match('|^.*?controller/(.+)\.php$|i', strtr($name, '\\', '/'), $matches)) {
|
||||||
static::_parseClass($appName, $appSpace, $matches[1], $ignoreMethods, $data);
|
static::_parseClass($appName, $appSpace, $matches[1], $ignoreMethods, $data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -146,73 +175,45 @@ class NodeService extends Service
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 解析节点数据
|
* 解析节点数据.
|
||||||
* @param string $appName 应用名称
|
* @param string $appName 应用名称
|
||||||
* @param string $appSpace 应用空间
|
* @param string $appSpace 应用空间
|
||||||
* @param string $className 应用类型
|
* @param string $className 应用类型
|
||||||
* @param array $ignoreNode 忽略节点
|
* @param array $ignoreNode 忽略节点
|
||||||
* @param array $data 绑定节点的数据
|
* @param array $data 绑定节点的数据
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
private static function _parseClass(string $appName, string $appSpace, string $className, array $ignoreNode, array &$data)
|
private static function _parseClass(string $appName, string $appSpace, string $className, array $ignoreNode, array &$data)
|
||||||
{
|
{
|
||||||
$classfull = strtr("{$appSpace}/controller/{$className}", '/', '\\');
|
$classfull = strtr("{$appSpace}/controller/{$className}", '/', '\\');
|
||||||
if (class_exists($classfull) && ($class = new ReflectionClass($classfull))) {
|
if (class_exists($classfull) && ($class = new \ReflectionClass($classfull))) {
|
||||||
$prefix = strtolower(strtr("{$appName}/" . static::nameTolower($className), '\\', '/'));
|
$prefix = strtolower(strtr("{$appName}/" . static::nameTolower($className), '\\', '/'));
|
||||||
$data[$prefix] = static::_parseComment($class->getDocComment() ?: '', $className);
|
$data[$prefix] = static::_parseComment($class->getDocComment() ?: '', $className);
|
||||||
foreach ($class->getMethods(ReflectionMethod::IS_PUBLIC) as $method) {
|
foreach ($class->getMethods(\ReflectionMethod::IS_PUBLIC) as $method) {
|
||||||
if (in_array($metname = $method->getName(), $ignoreNode)) continue;
|
if (in_array($metname = $method->getName(), $ignoreNode)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
$data[strtolower("{$prefix}/{$metname}")] = static::_parseComment($method->getDocComment() ?: '', $metname);
|
$data[strtolower("{$prefix}/{$metname}")] = static::_parseComment($method->getDocComment() ?: '', $metname);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 解析硬节点属性
|
* 解析硬节点属性.
|
||||||
* @param string $comment 备注内容
|
* @param string $comment 备注内容
|
||||||
* @param string $default 默认标题
|
* @param string $default 默认标题
|
||||||
* @return array
|
|
||||||
*/
|
*/
|
||||||
private static function _parseComment(string $comment, string $default = ''): array
|
private static function _parseComment(string $comment, string $default = ''): array
|
||||||
{
|
{
|
||||||
$text = strtr($comment, "\n", ' ');
|
$text = strtr($comment, "\n", ' ');
|
||||||
$title = preg_replace('/^\/\*\s*\*\s*\*\s*(.*?)\s*\*.*?$/', '$1', $text);
|
$title = preg_replace('/^\/\*\s*\*\s*\*\s*(.*?)\s*\*.*?$/', '$1', $text);
|
||||||
if (in_array(substr($title, 0, 5), ['@auth', '@menu', '@logi'])) $title = $default;
|
if (in_array(substr($title, 0, 5), ['@auth', '@menu', '@logi'])) {
|
||||||
|
$title = $default;
|
||||||
|
}
|
||||||
return [
|
return [
|
||||||
'title' => $title ?: $default,
|
'title' => $title ?: $default,
|
||||||
'isauth' => intval(preg_match('/@auth\s*true/i', $text)),
|
'isauth' => intval(preg_match('/@auth\s*true/i', $text)),
|
||||||
'ismenu' => intval(preg_match('/@menu\s*true/i', $text)),
|
'ismenu' => intval(preg_match('/@menu\s*true/i', $text)),
|
||||||
'islogin' => intval(preg_match('/@login\s*true/i', $text)),
|
'islogin' => intval(preg_match('/@login\s*true/i', $text)),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
/**
|
|
||||||
* 重构兼容处理
|
|
||||||
* @param string $name
|
|
||||||
* @param array $arguments
|
|
||||||
* @return array
|
|
||||||
* @throws \think\admin\Exception
|
|
||||||
*/
|
|
||||||
public function __call(string $name, array $arguments)
|
|
||||||
{
|
|
||||||
return static::__callStatic($name, $arguments);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 重构兼容处理
|
|
||||||
* @param string $name
|
|
||||||
* @param array $arguments
|
|
||||||
* @return array
|
|
||||||
* @throws \think\admin\Exception
|
|
||||||
*/
|
|
||||||
public static function __callStatic(string $name, array $arguments)
|
|
||||||
{
|
|
||||||
if ($name === 'scanDirectory') {
|
|
||||||
return ToolsExtend::scan(...$arguments);
|
|
||||||
} elseif ($name === 'getModules') {
|
|
||||||
return ModuleService::getModules(...$arguments);
|
|
||||||
} else {
|
|
||||||
throw new Exception("method not exists: NodeService::{$name}()");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@ -1,20 +1,22 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// +----------------------------------------------------------------------
|
declare(strict_types=1);
|
||||||
// | Library for ThinkAdmin
|
/**
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 版权所有 2014~2025 ThinkAdmin [ thinkadmin.top ]
|
* | Payment Plugin for ThinkAdmin
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 官方网站: https://thinkadmin.top
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 开源协议 ( https://mit-license.org )
|
* | 官方网站: https://thinkadmin.top
|
||||||
// | 免费声明 ( https://thinkadmin.top/disclaimer )
|
* +----------------------------------------------------------------------
|
||||||
// +----------------------------------------------------------------------
|
* | 开源协议 ( https://mit-license.org )
|
||||||
// | gitee 仓库地址 :https://gitee.com/zoujingli/ThinkLibrary
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
// | github 仓库地址 :https://github.com/zoujingli/ThinkLibrary
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
declare (strict_types=1);
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
namespace think\admin\service;
|
namespace think\admin\service;
|
||||||
|
|
||||||
@ -27,15 +29,24 @@ use think\admin\Service;
|
|||||||
/**
|
/**
|
||||||
* 系统进程管理服务
|
* 系统进程管理服务
|
||||||
* @class ProcessService
|
* @class ProcessService
|
||||||
* @package think\admin\service
|
|
||||||
*/
|
*/
|
||||||
class ProcessService extends Service
|
class ProcessService extends Service
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* 静态兼容处理.
|
||||||
|
* @return array
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public static function __callStatic(string $method, array $arguments)
|
||||||
|
{
|
||||||
|
if ($method === 'thinkCreate') {
|
||||||
|
return self::thinkExec(...$arguments);
|
||||||
|
}
|
||||||
|
throw new Exception("method not exists: ProcessService::{$method}()");
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 生成 PHP 指令
|
* 生成 PHP 指令.
|
||||||
* @param string $args
|
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public static function php(string $args = ''): string
|
public static function php(string $args = ''): string
|
||||||
{
|
{
|
||||||
@ -43,10 +54,9 @@ class ProcessService extends Service
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 生成 Think 指令
|
* 生成 Think 指令.
|
||||||
* @param string $args 指令参数
|
* @param string $args 指令参数
|
||||||
* @param boolean $simple 仅返回内容
|
* @param bool $simple 仅返回内容
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public static function think(string $args = '', bool $simple = false): string
|
public static function think(string $args = '', bool $simple = false): string
|
||||||
{
|
{
|
||||||
@ -55,9 +65,8 @@ class ProcessService extends Service
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 生成 Composer 指令
|
* 生成 Composer 指令.
|
||||||
* @param string $args 参数
|
* @param string $args 参数
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public static function composer(string $args = ''): string
|
public static function composer(string $args = ''): string
|
||||||
{
|
{
|
||||||
@ -71,11 +80,10 @@ class ProcessService extends Service
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建 Think 进程
|
* 创建 Think 进程.
|
||||||
* @param string $args 执行参数
|
* @param string $args 执行参数
|
||||||
* @param integer $usleep 延时等待
|
* @param int $usleep 延时等待
|
||||||
* @param boolean $doQuery 查询进程
|
* @param bool $doQuery 查询进程
|
||||||
* @return array
|
|
||||||
*/
|
*/
|
||||||
public static function thinkExec(string $args, int $usleep = 0, bool $doQuery = false): array
|
public static function thinkExec(string $args, int $usleep = 0, bool $doQuery = false): array
|
||||||
{
|
{
|
||||||
@ -84,9 +92,8 @@ class ProcessService extends Service
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 检查 Think 进程
|
* 检查 Think 进程.
|
||||||
* @param string $args 执行参数
|
* @param string $args 执行参数
|
||||||
* @return array
|
|
||||||
*/
|
*/
|
||||||
public static function thinkQuery(string $args): array
|
public static function thinkQuery(string $args): array
|
||||||
{
|
{
|
||||||
@ -94,9 +101,9 @@ class ProcessService extends Service
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建异步进程
|
* 创建异步进程.
|
||||||
* @param string $command 任务指令
|
* @param string $command 任务指令
|
||||||
* @param integer $usleep 延时毫米
|
* @param int $usleep 延时毫米
|
||||||
*/
|
*/
|
||||||
public static function create(string $command, int $usleep = 0)
|
public static function create(string $command, int $usleep = 0)
|
||||||
{
|
{
|
||||||
@ -109,35 +116,37 @@ class ProcessService extends Service
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询进程列表
|
* 查询进程列表.
|
||||||
* @param string $cmd 任务指令
|
* @param string $cmd 任务指令
|
||||||
* @param string $name 进程名称
|
* @param string $name 进程名称
|
||||||
* @return array
|
|
||||||
*/
|
*/
|
||||||
public static function query(string $cmd, string $name = 'php.exe'): array
|
public static function query(string $cmd, string $name = 'php.exe'): array
|
||||||
{
|
{
|
||||||
$list = [];
|
$list = [];
|
||||||
if (static::isWin()) {
|
if (static::isWin()) {
|
||||||
$lines = static::exec("wmic process where name=\"{$name}\" get processid,CommandLine", true);
|
$lines = static::exec("wmic process where name=\"{$name}\" get processid,CommandLine", true);
|
||||||
foreach ($lines as $line) if (is_numeric(stripos($line, $cmd))) {
|
foreach ($lines as $line) {
|
||||||
$attr = explode(' ', trim(preg_replace('#\s+#', ' ', $line)));
|
if (is_numeric(stripos($line, $cmd))) {
|
||||||
$list[] = ['pid' => array_pop($attr), 'cmd' => join(' ', $attr)];
|
$attr = explode(' ', trim(preg_replace('#\s+#', ' ', $line)));
|
||||||
|
$list[] = ['pid' => array_pop($attr), 'cmd' => join(' ', $attr)];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$lines = static::exec("ps ax|grep -v grep|grep \"{$cmd}\"", true);
|
$lines = static::exec("ps ax|grep -v grep|grep \"{$cmd}\"", true);
|
||||||
foreach ($lines as $line) if (is_numeric(stripos($line, $cmd))) {
|
foreach ($lines as $line) {
|
||||||
$attr = explode(' ', trim(preg_replace('#\s+#', ' ', $line)));
|
if (is_numeric(stripos($line, $cmd))) {
|
||||||
[$pid] = [array_shift($attr), array_shift($attr), array_shift($attr), array_shift($attr)];
|
$attr = explode(' ', trim(preg_replace('#\s+#', ' ', $line)));
|
||||||
$list[] = ['pid' => $pid, 'cmd' => join(' ', $attr)];
|
[$pid] = [array_shift($attr), array_shift($attr), array_shift($attr), array_shift($attr)];
|
||||||
|
$list[] = ['pid' => $pid, 'cmd' => join(' ', $attr)];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return $list;
|
return $list;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 关闭指定进程
|
* 关闭指定进程.
|
||||||
* @param integer $pid 进程号
|
* @param int $pid 进程号
|
||||||
* @return boolean
|
|
||||||
*/
|
*/
|
||||||
public static function close(int $pid): bool
|
public static function close(int $pid): bool
|
||||||
{
|
{
|
||||||
@ -150,11 +159,11 @@ class ProcessService extends Service
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 立即执行指令
|
* 立即执行指令.
|
||||||
* @param string $command 执行指令
|
* @param string $command 执行指令
|
||||||
* @param boolean $outarr 返回数组
|
* @param bool $outarr 返回数组
|
||||||
* @param ?callable $callable 逐行处理
|
* @param ?callable $callable 逐行处理
|
||||||
* @return string|array
|
* @return array|string
|
||||||
*/
|
*/
|
||||||
public static function exec(string $command, bool $outarr = false, ?callable $callable = null)
|
public static function exec(string $command, bool $outarr = false, ?callable $callable = null)
|
||||||
{
|
{
|
||||||
@ -167,20 +176,20 @@ class ProcessService extends Service
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 输出命令行消息
|
* 输出命令行消息.
|
||||||
* @param string $message 输出内容
|
* @param string $message 输出内容
|
||||||
* @param integer $backline 回退行数
|
* @param int $backline 回退行数
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public static function message(string $message, int $backline = 0)
|
public static function message(string $message, int $backline = 0)
|
||||||
{
|
{
|
||||||
while ($backline-- > 0) $message = "\033[1A\r\033[K{$message}";
|
while ($backline-- > 0) {
|
||||||
|
$message = "\033[1A\r\033[K{$message}";
|
||||||
|
}
|
||||||
print_r($message . PHP_EOL);
|
print_r($message . PHP_EOL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 判断系统类型 WINDOWS
|
* 判断系统类型 WINDOWS.
|
||||||
* @return boolean
|
|
||||||
*/
|
*/
|
||||||
public static function isWin(): bool
|
public static function isWin(): bool
|
||||||
{
|
{
|
||||||
@ -188,8 +197,7 @@ class ProcessService extends Service
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 判断系统类型 UNIX
|
* 判断系统类型 UNIX.
|
||||||
* @return bool
|
|
||||||
*/
|
*/
|
||||||
public static function isUnix(): bool
|
public static function isUnix(): bool
|
||||||
{
|
{
|
||||||
@ -197,9 +205,8 @@ class ProcessService extends Service
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 检查文件是否存在
|
* 检查文件是否存在.
|
||||||
* @param string $file 文件路径
|
* @param string $file 文件路径
|
||||||
* @return boolean
|
|
||||||
*/
|
*/
|
||||||
public static function isFile(string $file): bool
|
public static function isFile(string $file): bool
|
||||||
{
|
{
|
||||||
@ -209,28 +216,11 @@ class ProcessService extends Service
|
|||||||
try {
|
try {
|
||||||
if (self::isWin()) {
|
if (self::isWin()) {
|
||||||
return self::exec("if exist \"{$file}\" echo 1") === '1';
|
return self::exec("if exist \"{$file}\" echo 1") === '1';
|
||||||
} else {
|
|
||||||
return self::exec("if [ -f \"{$file}\" ];then echo 1;fi") === '1';
|
|
||||||
}
|
}
|
||||||
|
return self::exec("if [ -f \"{$file}\" ];then echo 1;fi") === '1';
|
||||||
} catch (\Error|\Exception $exception) {
|
} catch (\Error|\Exception $exception) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
/**
|
|
||||||
* 静态兼容处理
|
|
||||||
* @param string $method
|
|
||||||
* @param array $arguments
|
|
||||||
* @return array
|
|
||||||
* @throws \think\admin\Exception
|
|
||||||
*/
|
|
||||||
public static function __callStatic(string $method, array $arguments)
|
|
||||||
{
|
|
||||||
if ($method === 'thinkCreate') {
|
|
||||||
return self::thinkExec(...$arguments);
|
|
||||||
} else {
|
|
||||||
throw new Exception("method not exists: ProcessService::{$method}()");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@ -1,20 +1,22 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// +----------------------------------------------------------------------
|
declare(strict_types=1);
|
||||||
// | Library for ThinkAdmin
|
/**
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 版权所有 2014~2025 ThinkAdmin [ thinkadmin.top ]
|
* | Payment Plugin for ThinkAdmin
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 官方网站: https://thinkadmin.top
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 开源协议 ( https://mit-license.org )
|
* | 官方网站: https://thinkadmin.top
|
||||||
// | 免费声明 ( https://thinkadmin.top/disclaimer )
|
* +----------------------------------------------------------------------
|
||||||
// +----------------------------------------------------------------------
|
* | 开源协议 ( https://mit-license.org )
|
||||||
// | gitee 仓库地址 :https://gitee.com/zoujingli/ThinkLibrary
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
// | github 仓库地址 :https://github.com/zoujingli/ThinkLibrary
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
declare (strict_types=1);
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
namespace think\admin\service;
|
namespace think\admin\service;
|
||||||
|
|
||||||
@ -26,58 +28,55 @@ use think\admin\Service;
|
|||||||
/**
|
/**
|
||||||
* 任务基础服务
|
* 任务基础服务
|
||||||
* @class QueueService
|
* @class QueueService
|
||||||
* @package think\admin\service
|
|
||||||
*/
|
*/
|
||||||
class QueueService extends Service
|
class QueueService extends Service
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 当前任务编号
|
* 当前任务编号.
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
public $code = '';
|
public $code = '';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 当前任务标题
|
* 当前任务标题.
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
public $title = '';
|
public $title = '';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 当前任务参数
|
* 当前任务参数.
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
public $data = [];
|
public $data = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 当前任务数据
|
* 当前任务数据.
|
||||||
* @var SystemQueue
|
* @var SystemQueue
|
||||||
*/
|
*/
|
||||||
public $record;
|
public $record;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 运行消息记录
|
* 运行消息记录.
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
private $msgs = [];
|
private $msgs = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 运行消息写库
|
* 运行消息写库.
|
||||||
* @var boolean
|
* @var bool
|
||||||
*/
|
*/
|
||||||
private $msgsWriteDb = false;
|
private $msgsWriteDb = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 异常尝试次数
|
* 异常尝试次数.
|
||||||
* @var integer
|
* @var int
|
||||||
*/
|
*/
|
||||||
private $tryTimes = 0;
|
private $tryTimes = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 数据初始化
|
* 数据初始化.
|
||||||
* @param string $code
|
|
||||||
* @return static
|
* @return static
|
||||||
* @throws \think\admin\Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public function initialize(string $code = ''): QueueService
|
public function initialize(string $code = ''): QueueService
|
||||||
{
|
{
|
||||||
@ -90,7 +89,7 @@ class QueueService extends Service
|
|||||||
if (!empty($code)) {
|
if (!empty($code)) {
|
||||||
$this->record = SystemQueue::mk()->master()->where(['code' => $code])->findOrEmpty();
|
$this->record = SystemQueue::mk()->master()->where(['code' => $code])->findOrEmpty();
|
||||||
if ($this->record->isEmpty()) {
|
if ($this->record->isEmpty()) {
|
||||||
$message = sprintf("Qeueu initialize failed, Queue %s not found.", $code);
|
$message = sprintf('Qeueu initialize failed, Queue %s not found.', $code);
|
||||||
$this->app->log->error($message);
|
$this->app->log->error($message);
|
||||||
throw new Exception($message);
|
throw new Exception($message);
|
||||||
}
|
}
|
||||||
@ -105,9 +104,9 @@ class QueueService extends Service
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 重发异步任务
|
* 重发异步任务
|
||||||
* @param integer $wait 等待时间
|
* @param int $wait 等待时间
|
||||||
* @return $this
|
* @return $this
|
||||||
* @throws \think\admin\Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public function reset(int $wait = 0): QueueService
|
public function reset(int $wait = 0): QueueService
|
||||||
{
|
{
|
||||||
@ -122,25 +121,25 @@ class QueueService extends Service
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 添加定时清理任务
|
* 添加定时清理任务
|
||||||
* @param integer $loops 循环时间
|
* @param int $loops 循环时间
|
||||||
* @return $this
|
* @return $this
|
||||||
* @throws \think\admin\Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public static function addCleanQueue(int $loops = 3600): QueueService
|
public static function addCleanQueue(int $loops = 3600): QueueService
|
||||||
{
|
{
|
||||||
return static::register('定时清理系统任务数据', "xadmin:service clean", 0, [], 0, $loops);
|
return static::register('定时清理系统任务数据', 'xadmin:service clean', 0, [], 0, $loops);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 注册异步处理任务
|
* 注册异步处理任务
|
||||||
* @param string $title 任务名称
|
* @param string $title 任务名称
|
||||||
* @param string $command 执行脚本
|
* @param string $command 执行脚本
|
||||||
* @param integer $later 延时时间
|
* @param int $later 延时时间
|
||||||
* @param array $data 任务附加数据
|
* @param array $data 任务附加数据
|
||||||
* @param integer $rscript 任务类型(0单例,1多例)
|
* @param int $rscript 任务类型(0单例,1多例)
|
||||||
* @param integer $loops 循环等待时间
|
* @param int $loops 循环等待时间
|
||||||
* @return $this
|
* @return $this
|
||||||
* @throws \think\admin\Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public static function register(string $title, string $command, int $later = 0, array $data = [], int $rscript = 0, int $loops = 0): QueueService
|
public static function register(string $title, string $command, int $later = 0, array $data = [], int $rscript = 0, int $loops = 0): QueueService
|
||||||
{
|
{
|
||||||
@ -150,21 +149,22 @@ class QueueService extends Service
|
|||||||
throw new Exception(lang('已创建请等待处理完成!'), 0, $queue['code']);
|
throw new Exception(lang('已创建请等待处理完成!'), 0, $queue['code']);
|
||||||
}
|
}
|
||||||
// 生成唯一编号
|
// 生成唯一编号
|
||||||
do $map = ['code' => $code = CodeExtend::uniqidDate(16, 'Q')];
|
do {
|
||||||
while (($queue = SystemQueue::mk()->master()->where($map)->findOrEmpty())->isExists());
|
$map = ['code' => $code = CodeExtend::uniqidDate(16, 'Q')];
|
||||||
|
} while (($queue = SystemQueue::mk()->master()->where($map)->findOrEmpty())->isExists());
|
||||||
// 写入任务数据
|
// 写入任务数据
|
||||||
$queue->save([
|
$queue->save([
|
||||||
'code' => $code,
|
'code' => $code,
|
||||||
'title' => $title,
|
'title' => $title,
|
||||||
'command' => $command,
|
'command' => $command,
|
||||||
'attempts' => 0,
|
'attempts' => 0,
|
||||||
'rscript' => intval(boolval($rscript)),
|
'rscript' => intval(boolval($rscript)),
|
||||||
'exec_data' => json_encode($data, JSON_UNESCAPED_UNICODE),
|
'exec_data' => json_encode($data, JSON_UNESCAPED_UNICODE),
|
||||||
'exec_time' => $later > 0 ? time() + $later : time(),
|
'exec_time' => $later > 0 ? time() + $later : time(),
|
||||||
'enter_time' => 0,
|
'enter_time' => 0,
|
||||||
'outer_time' => 0,
|
'outer_time' => 0,
|
||||||
'loops_time' => $loops,
|
'loops_time' => $loops,
|
||||||
'create_at' => date('Y-m-d H:i:s'),
|
'create_at' => date('Y-m-d H:i:s'),
|
||||||
]);
|
]);
|
||||||
$that = static::instance([], true)->initialize($code);
|
$that = static::instance([], true)->initialize($code);
|
||||||
$that->progress(1, '>>> 任务创建成功 <<<', '0.00');
|
$that->progress(1, '>>> 任务创建成功 <<<', '0.00');
|
||||||
@ -177,36 +177,53 @@ class QueueService extends Service
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置任务进度信息
|
* 设置任务进度信息.
|
||||||
* @param ?integer $status 任务状态
|
* @param ?int $status 任务状态
|
||||||
* @param ?string $message 进度消息
|
* @param ?string $message 进度消息
|
||||||
* @param ?string $progress 进度数值
|
* @param ?string $progress 进度数值
|
||||||
* @param integer $backline 回退信息行
|
* @param int $backline 回退信息行
|
||||||
* @return array
|
* @throws Exception
|
||||||
* @throws \think\admin\Exception
|
|
||||||
*/
|
*/
|
||||||
public function progress(?int $status = null, ?string $message = null, ?string $progress = null, int $backline = 0): array
|
public function progress(?int $status = null, ?string $message = null, ?string $progress = null, int $backline = 0): array
|
||||||
{
|
{
|
||||||
if (is_numeric($status) && intval($status) === 3) {
|
if (is_numeric($status) && intval($status) === 3) {
|
||||||
if (!is_numeric($progress)) $progress = '100.00';
|
if (!is_numeric($progress)) {
|
||||||
if (is_null($message)) $message = '>>> 任务已经完成 <<<';
|
$progress = '100.00';
|
||||||
|
}
|
||||||
|
if (is_null($message)) {
|
||||||
|
$message = '>>> 任务已经完成 <<<';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (is_numeric($status) && intval($status) === 4) {
|
if (is_numeric($status) && intval($status) === 4) {
|
||||||
if (!is_numeric($progress)) $progress = '0.00';
|
if (!is_numeric($progress)) {
|
||||||
if (is_null($message)) $message = '>>> 任务执行失败 <<<';
|
$progress = '0.00';
|
||||||
|
}
|
||||||
|
if (is_null($message)) {
|
||||||
|
$message = '>>> 任务执行失败 <<<';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
if (empty($this->msgs)) $this->msgs = $this->app->cache->get("queue_{$this->code}_progress", [
|
if (empty($this->msgs)) {
|
||||||
'code' => $this->code, 'status' => $status, 'sctime' => 0, 'message' => $message, 'progress' => $progress, 'history' => []
|
$this->msgs = $this->app->cache->get("queue_{$this->code}_progress", [
|
||||||
]);
|
'code' => $this->code, 'status' => $status, 'sctime' => 0, 'message' => $message, 'progress' => $progress, 'history' => [],
|
||||||
|
]);
|
||||||
|
}
|
||||||
$this->tryTimes = 0;
|
$this->tryTimes = 0;
|
||||||
} catch (\Exception|\Error $exception) {
|
} catch (\Error|\Exception $exception) {
|
||||||
if ($this->tryTimes++ > 10) throw new Exception('读取进程缓存异常!');
|
if ($this->tryTimes++ > 10) {
|
||||||
|
throw new Exception('读取进程缓存异常!');
|
||||||
|
}
|
||||||
return $this->progress($status, $message, $progress, $backline);
|
return $this->progress($status, $message, $progress, $backline);
|
||||||
}
|
}
|
||||||
while (--$backline > -1 && count($this->msgs['history']) > 0) array_pop($this->msgs['history']);
|
while (--$backline > -1 && count($this->msgs['history']) > 0) {
|
||||||
if (is_numeric($status)) $this->msgs['status'] = intval($status);
|
array_pop($this->msgs['history']);
|
||||||
if (is_numeric($progress)) $progress = str_pad(sprintf('%.2f', $progress), 6, '0', STR_PAD_LEFT);
|
}
|
||||||
|
if (is_numeric($status)) {
|
||||||
|
$this->msgs['status'] = intval($status);
|
||||||
|
}
|
||||||
|
if (is_numeric($progress)) {
|
||||||
|
$progress = str_pad(sprintf('%.2f', $progress), 6, '0', STR_PAD_LEFT);
|
||||||
|
}
|
||||||
if (is_string($message) && is_null($progress)) {
|
if (is_string($message) && is_null($progress)) {
|
||||||
$this->msgs['swrite'] = 0;
|
$this->msgs['swrite'] = 0;
|
||||||
$this->msgs['message'] = $message;
|
$this->msgs['message'] = $message;
|
||||||
@ -221,48 +238,28 @@ class QueueService extends Service
|
|||||||
$this->msgs['progress'] = $progress;
|
$this->msgs['progress'] = $progress;
|
||||||
$this->msgs['history'][] = ['message' => $message, 'progress' => $progress, 'datetime' => date('Y-m-d H:i:s')];
|
$this->msgs['history'][] = ['message' => $message, 'progress' => $progress, 'datetime' => date('Y-m-d H:i:s')];
|
||||||
}
|
}
|
||||||
if (is_string($message) || is_numeric($progress)) if (count($this->msgs['history']) > 10) {
|
if (is_string($message) || is_numeric($progress)) {
|
||||||
$this->msgs['history'] = array_slice($this->msgs['history'], -10);
|
if (count($this->msgs['history']) > 10) {
|
||||||
|
$this->msgs['history'] = array_slice($this->msgs['history'], -10);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// 延时写入并返回内容
|
// 延时写入并返回内容
|
||||||
return $this->_lazyWrite();
|
return $this->_lazyWrite();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 延时写入记录
|
* 更新任务进度.
|
||||||
* @param boolean $force 强制更新
|
* @param int $total 记录总和
|
||||||
* @return array
|
* @param int $count 当前记录
|
||||||
*/
|
|
||||||
private function _lazyWrite(bool $force = false): array
|
|
||||||
{
|
|
||||||
// 无消息状态
|
|
||||||
if (!isset($this->msgs['status'])) return $this->msgs;
|
|
||||||
// 消息延时写数据库
|
|
||||||
if ($force || empty($this->msgs['sctime']) || in_array($this->msgs['status'], [3, 4]) || microtime(true) - $this->msgs['sctime'] > 1) {
|
|
||||||
if (empty($this->msgs['swrite']) && $this->record->isExists()) {
|
|
||||||
[$this->msgs['swrite'], $this->msgs['sctime']] = [1, microtime(true)];
|
|
||||||
$this->app->cache->set("queue_{$this->code}_progress", $this->msgs, 864000);
|
|
||||||
if ($this->msgsWriteDb) {
|
|
||||||
$this->record->save(['message' => json_encode($this->msgs, JSON_UNESCAPED_UNICODE)]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $this->msgs;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 更新任务进度
|
|
||||||
* @param integer $total 记录总和
|
|
||||||
* @param integer $count 当前记录
|
|
||||||
* @param string $message 文字描述
|
* @param string $message 文字描述
|
||||||
* @param integer $backline 回退行数
|
* @param int $backline 回退行数
|
||||||
* @throws \think\admin\Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public function message(int $total, int $count, string $message = '', int $backline = 0): void
|
public function message(int $total, int $count, string $message = '', int $backline = 0): void
|
||||||
{
|
{
|
||||||
$prefix = str_pad("{$count}", strlen(strval($total)), '0', STR_PAD_LEFT);
|
$prefix = str_pad("{$count}", strlen(strval($total)), '0', STR_PAD_LEFT);
|
||||||
if (defined('WorkQueueCode')) {
|
if (defined('WorkQueueCode')) {
|
||||||
$this->progress(2, "[{$prefix}/{$total}] {$message}", sprintf("%.2f", $count / max($total, 1) * 100), $backline);
|
$this->progress(2, "[{$prefix}/{$total}] {$message}", sprintf('%.2f', $count / max($total, 1) * 100), $backline);
|
||||||
} else {
|
} else {
|
||||||
ProcessService::message("[{$prefix}/{$total}] {$message}", $backline);
|
ProcessService::message("[{$prefix}/{$total}] {$message}", $backline);
|
||||||
}
|
}
|
||||||
@ -279,7 +276,7 @@ class QueueService extends Service
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 任务执行失败
|
* 任务执行失败.
|
||||||
* @param string $message 消息内容
|
* @param string $message 消息内容
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
@ -289,11 +286,31 @@ class QueueService extends Service
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 执行任务处理
|
* 执行任务处理.
|
||||||
* @param array $data 任务参数
|
* @param array $data 任务参数
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public function execute(array $data = [])
|
public function execute(array $data = []) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 延时写入记录.
|
||||||
|
* @param bool $force 强制更新
|
||||||
|
*/
|
||||||
|
private function _lazyWrite(bool $force = false): array
|
||||||
{
|
{
|
||||||
|
// 无消息状态
|
||||||
|
if (!isset($this->msgs['status'])) {
|
||||||
|
return $this->msgs;
|
||||||
|
}
|
||||||
|
// 消息延时写数据库
|
||||||
|
if ($force || empty($this->msgs['sctime']) || in_array($this->msgs['status'], [3, 4]) || microtime(true) - $this->msgs['sctime'] > 1) {
|
||||||
|
if (empty($this->msgs['swrite']) && $this->record->isExists()) {
|
||||||
|
[$this->msgs['swrite'], $this->msgs['sctime']] = [1, microtime(true)];
|
||||||
|
$this->app->cache->set("queue_{$this->code}_progress", $this->msgs, 864000);
|
||||||
|
if ($this->msgsWriteDb) {
|
||||||
|
$this->record->save(['message' => json_encode($this->msgs, JSON_UNESCAPED_UNICODE)]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $this->msgs;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,20 +1,22 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// +----------------------------------------------------------------------
|
declare(strict_types=1);
|
||||||
// | Library for ThinkAdmin
|
/**
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 版权所有 2014~2025 ThinkAdmin [ thinkadmin.top ]
|
* | Payment Plugin for ThinkAdmin
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 官方网站: https://thinkadmin.top
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 开源协议 ( https://mit-license.org )
|
* | 官方网站: https://thinkadmin.top
|
||||||
// | 免费声明 ( https://thinkadmin.top/disclaimer )
|
* +----------------------------------------------------------------------
|
||||||
// +----------------------------------------------------------------------
|
* | 开源协议 ( https://mit-license.org )
|
||||||
// | gitee 仓库地址 :https://gitee.com/zoujingli/ThinkLibrary
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
// | github 仓库地址 :https://github.com/zoujingli/ThinkLibrary
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
declare (strict_types=1);
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
namespace think\admin\service;
|
namespace think\admin\service;
|
||||||
|
|
||||||
@ -29,31 +31,29 @@ use think\Response;
|
|||||||
/**
|
/**
|
||||||
* 系统运行服务
|
* 系统运行服务
|
||||||
* @class RuntimeService
|
* @class RuntimeService
|
||||||
* @package think\admin\service
|
|
||||||
*/
|
*/
|
||||||
class RuntimeService
|
class RuntimeService
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 开发运行模式
|
* 开发运行模式.
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
public const MODE_DEVE = 'dev';
|
public const MODE_DEVE = 'dev';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 演示运行模式
|
* 演示运行模式.
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
public const MODE_DEMO = 'demo';
|
public const MODE_DEMO = 'demo';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 本地运行模式
|
* 本地运行模式.
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
public const MODE_LOCAL = 'local';
|
public const MODE_LOCAL = 'local';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 环境配置文件位置
|
* 环境配置文件位置.
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
private static $envFile = './runtime/.env';
|
private static $envFile = './runtime/.env';
|
||||||
@ -65,9 +65,7 @@ class RuntimeService
|
|||||||
private static $evnHash = '';
|
private static $evnHash = '';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 系统服务初始化
|
* 系统服务初始化.
|
||||||
* @param ?\think\App $app
|
|
||||||
* @return App
|
|
||||||
*/
|
*/
|
||||||
public static function init(?App $app = null): App
|
public static function init(?App $app = null): App
|
||||||
{
|
{
|
||||||
@ -81,7 +79,7 @@ class RuntimeService
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取动态配置
|
* 获取动态配置.
|
||||||
* @param null|string $name 配置名称
|
* @param null|string $name 配置名称
|
||||||
* @param array $default 配置内容
|
* @param array $default 配置内容
|
||||||
* @return array|string
|
* @return array|string
|
||||||
@ -103,11 +101,11 @@ class RuntimeService
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置动态配置
|
* 设置动态配置.
|
||||||
* @param null|mixed $mode 支持模式
|
* @param null|mixed $mode 支持模式
|
||||||
* @param null|array $appmap 应用映射
|
* @param null|array $appmap 应用映射
|
||||||
* @param null|array $domain 域名映射
|
* @param null|array $domain 域名映射
|
||||||
* @return boolean 是否调试模式
|
* @return bool 是否调试模式
|
||||||
*/
|
*/
|
||||||
public static function set(?string $mode = null, ?array $appmap = [], ?array $domain = []): bool
|
public static function set(?string $mode = null, ?array $appmap = [], ?array $domain = []): bool
|
||||||
{
|
{
|
||||||
@ -118,8 +116,12 @@ class RuntimeService
|
|||||||
|
|
||||||
// 组装配置文件格式
|
// 组装配置文件格式
|
||||||
$rows[] = "mode = {$envs['mode']}";
|
$rows[] = "mode = {$envs['mode']}";
|
||||||
foreach ($envs['appmap'] as $key => $item) $rows[] = "appmap[{$key}] = {$item}";
|
foreach ($envs['appmap'] as $key => $item) {
|
||||||
foreach ($envs['domain'] as $key => $item) $rows[] = "domain[{$key}] = {$item}";
|
$rows[] = "appmap[{$key}] = {$item}";
|
||||||
|
}
|
||||||
|
foreach ($envs['domain'] as $key => $item) {
|
||||||
|
$rows[] = "domain[{$key}] = {$item}";
|
||||||
|
}
|
||||||
|
|
||||||
// 写入并刷新文件希值
|
// 写入并刷新文件希值
|
||||||
@file_put_contents(self::$envFile, "[RUNTIME]\n" . join("\n", $rows));
|
@file_put_contents(self::$envFile, "[RUNTIME]\n" . join("\n", $rows));
|
||||||
@ -132,8 +134,7 @@ class RuntimeService
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 同步运行配置
|
* 同步运行配置.
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public static function sync()
|
public static function sync()
|
||||||
{
|
{
|
||||||
@ -142,9 +143,9 @@ class RuntimeService
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 绑定动态配置
|
* 绑定动态配置.
|
||||||
* @param array $data 配置数据
|
* @param array $data 配置数据
|
||||||
* @return boolean 是否调试模式
|
* @return bool 是否调试模式
|
||||||
*/
|
*/
|
||||||
public static function apply(array $data = []): bool
|
public static function apply(array $data = []): bool
|
||||||
{
|
{
|
||||||
@ -162,8 +163,7 @@ class RuntimeService
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 压缩发布项目
|
* 压缩发布项目.
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public static function push(): string
|
public static function push(): string
|
||||||
{
|
{
|
||||||
@ -174,25 +174,29 @@ class RuntimeService
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 判断运行环境
|
* 判断运行环境.
|
||||||
* @param string $type 运行模式(dev|demo|local)
|
* @param string $type 运行模式(dev|demo|local)
|
||||||
* @return boolean
|
|
||||||
*/
|
*/
|
||||||
public static function check(string $type = 'dev'): bool
|
public static function check(string $type = 'dev'): bool
|
||||||
{
|
{
|
||||||
$domain = Library::$sapp->request->host(true);
|
$domain = Library::$sapp->request->host(true);
|
||||||
$isDemo = boolval(preg_match('|v\d+\.thinkadmin\.top|', $domain));
|
$isDemo = boolval(preg_match('|v\d+\.thinkadmin\.top|', $domain));
|
||||||
$isLocal = $domain === '127.0.0.1' || is_numeric(stripos($domain, 'local'));
|
$isLocal = $domain === '127.0.0.1' || is_numeric(stripos($domain, 'local'));
|
||||||
if ($type === static::MODE_DEVE) return $isLocal || $isDemo;
|
if ($type === static::MODE_DEVE) {
|
||||||
if ($type === static::MODE_DEMO) return $isDemo;
|
return $isLocal || $isDemo;
|
||||||
if ($type === static::MODE_LOCAL) return $isLocal;
|
}
|
||||||
|
if ($type === static::MODE_DEMO) {
|
||||||
|
return $isDemo;
|
||||||
|
}
|
||||||
|
if ($type === static::MODE_LOCAL) {
|
||||||
|
return $isLocal;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 清理运行缓存
|
* 清理运行缓存.
|
||||||
* @param boolean $force 清理目录
|
* @param bool $force 清理目录
|
||||||
* @return boolean
|
|
||||||
*/
|
*/
|
||||||
public static function clear(bool $force = true): bool
|
public static function clear(bool $force = true): bool
|
||||||
{
|
{
|
||||||
@ -203,8 +207,7 @@ class RuntimeService
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 开发模式运行
|
* 开发模式运行.
|
||||||
* @return boolean
|
|
||||||
*/
|
*/
|
||||||
public static function isDebug(): bool
|
public static function isDebug(): bool
|
||||||
{
|
{
|
||||||
@ -212,8 +215,7 @@ class RuntimeService
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 生产模式运行
|
* 生产模式运行.
|
||||||
* @return boolean
|
|
||||||
*/
|
*/
|
||||||
public static function isOnline(): bool
|
public static function isOnline(): bool
|
||||||
{
|
{
|
||||||
@ -221,10 +223,7 @@ class RuntimeService
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 初始化主程序
|
* 初始化主程序.
|
||||||
* @param ?\think\App $app
|
|
||||||
* @param ?\think\Request $request
|
|
||||||
* @return \think\Response
|
|
||||||
*/
|
*/
|
||||||
public static function doWebsiteInit(?App $app = null, ?Request $request = null): Response
|
public static function doWebsiteInit(?App $app = null, ?Request $request = null): Response
|
||||||
{
|
{
|
||||||
@ -237,9 +236,7 @@ class RuntimeService
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 初始化命令行
|
* 初始化命令行.
|
||||||
* @param ?\think\App $app
|
|
||||||
* @return integer
|
|
||||||
*/
|
*/
|
||||||
public static function doConsoleInit(?App $app = null): int
|
public static function doConsoleInit(?App $app = null): int
|
||||||
{
|
{
|
||||||
@ -252,12 +249,11 @@ class RuntimeService
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 生成唯一数组
|
* 生成唯一数组.
|
||||||
* @param array ...$args
|
* @param array ...$args
|
||||||
* @return array
|
|
||||||
*/
|
*/
|
||||||
private static function uniqueMergeArray(...$args): array
|
private static function uniqueMergeArray(...$args): array
|
||||||
{
|
{
|
||||||
return array_unique(array_reverse(array_merge(...$args)));
|
return array_unique(array_reverse(array_merge(...$args)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,20 +1,22 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// +----------------------------------------------------------------------
|
declare(strict_types=1);
|
||||||
// | Library for ThinkAdmin
|
/**
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 版权所有 2014~2025 ThinkAdmin [ thinkadmin.top ]
|
* | Payment Plugin for ThinkAdmin
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 官方网站: https://thinkadmin.top
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 开源协议 ( https://mit-license.org )
|
* | 官方网站: https://thinkadmin.top
|
||||||
// | 免费声明 ( https://thinkadmin.top/disclaimer )
|
* +----------------------------------------------------------------------
|
||||||
// +----------------------------------------------------------------------
|
* | 开源协议 ( https://mit-license.org )
|
||||||
// | gitee 仓库地址 :https://gitee.com/zoujingli/ThinkLibrary
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
// | github 仓库地址 :https://github.com/zoujingli/ThinkLibrary
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
declare (strict_types=1);
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
namespace think\admin\service;
|
namespace think\admin\service;
|
||||||
|
|
||||||
@ -35,7 +37,6 @@ use think\Model;
|
|||||||
/**
|
/**
|
||||||
* 系统参数管理服务
|
* 系统参数管理服务
|
||||||
* @class SystemService
|
* @class SystemService
|
||||||
* @package think\admin\service
|
|
||||||
*
|
*
|
||||||
* @method static bool isDebug() 调式模式运行
|
* @method static bool isDebug() 调式模式运行
|
||||||
* @method static bool isOnline() 产品模式运行
|
* @method static bool isOnline() 产品模式运行
|
||||||
@ -57,29 +58,75 @@ use think\Model;
|
|||||||
class SystemService extends Service
|
class SystemService extends Service
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* 生成静态路径链接
|
* 魔术方法调用(临时).
|
||||||
|
* @param string $method 方法名称
|
||||||
|
* @param array $arguments 调用参数
|
||||||
|
* @return mixed
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public function __call(string $method, array $arguments)
|
||||||
|
{
|
||||||
|
return static::__callStatic($method, $arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 静态方法兼容(临时).
|
||||||
|
* @param string $method 方法名称
|
||||||
|
* @param array $arguments 调用参数
|
||||||
|
* @return mixed
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public static function __callStatic(string $method, array $arguments)
|
||||||
|
{
|
||||||
|
$map = [
|
||||||
|
'setRuntime' => 'set',
|
||||||
|
'getRuntime' => 'get',
|
||||||
|
'bindRuntime' => 'apply',
|
||||||
|
'isDebug' => 'isDebug',
|
||||||
|
'isOnline' => 'isOnline',
|
||||||
|
'doInit' => 'doWebsiteInit',
|
||||||
|
'doConsoleInit' => 'doConsoleInit',
|
||||||
|
'pushRuntime' => 'push',
|
||||||
|
'clearRuntime' => 'clear',
|
||||||
|
'checkRunMode' => 'check',
|
||||||
|
];
|
||||||
|
switch (strtolower($method)) {
|
||||||
|
case 'setconfig':
|
||||||
|
return self::setData(...$arguments);
|
||||||
|
case 'getconfig':
|
||||||
|
return self::getData(...$arguments);
|
||||||
|
}
|
||||||
|
if (isset($map[$method])) {
|
||||||
|
return RuntimeService::{$map[$method]}(...$arguments);
|
||||||
|
}
|
||||||
|
throw new Exception("method not exists: RuntimeService::{$method}()");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成静态路径链接.
|
||||||
* @param string $path 后缀路径
|
* @param string $path 后缀路径
|
||||||
* @param ?string $type 路径类型
|
* @param ?string $type 路径类型
|
||||||
* @param mixed $default 默认数据
|
* @param mixed $default 默认数据
|
||||||
* @return string|array
|
* @return array|string
|
||||||
*/
|
*/
|
||||||
public static function uri(string $path = '', ?string $type = '__ROOT__', $default = '')
|
public static function uri(string $path = '', ?string $type = '__ROOT__', $default = '')
|
||||||
{
|
{
|
||||||
$plugin = Library::$sapp->http->getName();
|
$plugin = Library::$sapp->http->getName();
|
||||||
if (strlen($path)) $path = '/' . ltrim($path, '/');
|
if (strlen($path)) {
|
||||||
$prefix = rtrim(dirname(Library::$sapp->request->basefile()), '\\/');
|
$path = '/' . ltrim($path, '/');
|
||||||
|
}
|
||||||
|
$prefix = rtrim(dirname(Library::$sapp->request->basefile()), '\/');
|
||||||
$data = [
|
$data = [
|
||||||
'__APP__' => rtrim(url('@')->build(), '\\/') . $path,
|
'__APP__' => rtrim(url('@')->build(), '\/') . $path,
|
||||||
'__ROOT__' => $prefix . $path,
|
'__ROOT__' => $prefix . $path,
|
||||||
'__PLUG__' => "{$prefix}/static/extra/{$plugin}{$path}",
|
'__PLUG__' => "{$prefix}/static/extra/{$plugin}{$path}",
|
||||||
'__FULL__' => Library::$sapp->request->domain() . $prefix . $path
|
'__FULL__' => Library::$sapp->request->domain() . $prefix . $path,
|
||||||
];
|
];
|
||||||
return is_null($type) ? $data : ($data[$type] ?? $default);
|
return is_null($type) ? $data : ($data[$type] ?? $default);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 生成全部静态路径
|
* 生成全部静态路径.
|
||||||
* @param string $path
|
|
||||||
* @return string[]
|
* @return string[]
|
||||||
*/
|
*/
|
||||||
public static function uris(string $path = ''): array
|
public static function uris(string $path = ''): array
|
||||||
@ -88,11 +135,11 @@ class SystemService extends Service
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置配置数据
|
* 设置配置数据.
|
||||||
* @param string $name 配置名称
|
* @param string $name 配置名称
|
||||||
* @param mixed $value 配置内容
|
* @param mixed $value 配置内容
|
||||||
* @return integer|string
|
* @return int|string
|
||||||
* @throws \think\admin\Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public static function set(string $name, $value = '')
|
public static function set(string $name, $value = '')
|
||||||
{
|
{
|
||||||
@ -103,7 +150,7 @@ class SystemService extends Service
|
|||||||
$count += static::set("{$field}.{$kk}", $vv);
|
$count += static::set("{$field}.{$kk}", $vv);
|
||||||
}
|
}
|
||||||
return $count;
|
return $count;
|
||||||
} else try {
|
} try {
|
||||||
$map = ['type' => $type, 'name' => $field];
|
$map = ['type' => $type, 'name' => $field];
|
||||||
SystemConfig::mk()->master()->where($map)->findOrEmpty()->save(array_merge($map, ['value' => $value]));
|
SystemConfig::mk()->master()->where($map)->findOrEmpty()->save(array_merge($map, ['value' => $value]));
|
||||||
sysvar('think.admin.config', []);
|
sysvar('think.admin.config', []);
|
||||||
@ -115,11 +162,9 @@ class SystemService extends Service
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 读取配置数据
|
* 读取配置数据.
|
||||||
* @param string $name
|
|
||||||
* @param string $default
|
|
||||||
* @return array|mixed|string
|
* @return array|mixed|string
|
||||||
* @throws \think\admin\Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public static function get(string $name = '', string $default = '')
|
public static function get(string $name = '', string $default = '')
|
||||||
{
|
{
|
||||||
@ -133,42 +178,48 @@ class SystemService extends Service
|
|||||||
[$type, $field, $outer] = static::_parse($name);
|
[$type, $field, $outer] = static::_parse($name);
|
||||||
if (empty($name)) {
|
if (empty($name)) {
|
||||||
return $config;
|
return $config;
|
||||||
} elseif (isset($config[$type])) {
|
}
|
||||||
|
if (isset($config[$type])) {
|
||||||
$group = $config[$type];
|
$group = $config[$type];
|
||||||
if ($outer !== 'raw') foreach ($group as $kk => $vo) {
|
if ($outer !== 'raw') {
|
||||||
$group[$kk] = htmlspecialchars(strval($vo));
|
foreach ($group as $kk => $vo) {
|
||||||
|
$group[$kk] = htmlspecialchars(strval($vo));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return $field ? ($group[$field] ?? $default) : $group;
|
return $field ? ($group[$field] ?? $default) : $group;
|
||||||
} else {
|
|
||||||
return $default;
|
|
||||||
}
|
}
|
||||||
|
return $default;
|
||||||
} catch (\Exception $exception) {
|
} catch (\Exception $exception) {
|
||||||
throw new Exception($exception->getMessage(), $exception->getCode());
|
throw new Exception($exception->getMessage(), $exception->getCode());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 数据增量保存
|
* 数据增量保存.
|
||||||
* @param Model|Query|string $query 数据查询对象
|
* @param Model|Query|string $query 数据查询对象
|
||||||
* @param array $data 需要保存的数据,成功返回对应模型
|
* @param array $data 需要保存的数据,成功返回对应模型
|
||||||
* @param string $key 更新条件查询主键
|
* @param string $key 更新条件查询主键
|
||||||
* @param mixed $map 额外更新查询条件
|
* @param mixed $map 额外更新查询条件
|
||||||
* @return boolean|integer 失败返回 false, 成功返回主键值或 true
|
* @return bool|int 失败返回 false, 成功返回主键值或 true
|
||||||
* @throws \think\admin\Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public static function save($query, array &$data, string $key = 'id', $map = [])
|
public static function save($query, array &$data, string $key = 'id', $map = [])
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$query = Helper::buildQuery($query)->master()->strict(false);
|
$query = Helper::buildQuery($query)->master()->strict(false);
|
||||||
if (empty($map[$key])) $query->where([$key => $data[$key] ?? null]);
|
if (empty($map[$key])) {
|
||||||
|
$query->where([$key => $data[$key] ?? null]);
|
||||||
|
}
|
||||||
$model = $query->where($map)->findOrEmpty();
|
$model = $query->where($map)->findOrEmpty();
|
||||||
// 当前操作方法描述
|
// 当前操作方法描述
|
||||||
$action = $model->isExists() ? 'onAdminUpdate' : 'onAdminInsert';
|
$action = $model->isExists() ? 'onAdminUpdate' : 'onAdminInsert';
|
||||||
// 写入或更新模型数据
|
// 写入或更新模型数据
|
||||||
if ($model->save($data) === false) return false;
|
if ($model->save($data) === false) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
// 模型自定义事件回调
|
// 模型自定义事件回调
|
||||||
if ($model instanceof \think\admin\Model) {
|
if ($model instanceof \think\admin\Model) {
|
||||||
$model->$action(strval($model->getAttr($key)));
|
$model->{$action}(strval($model->getAttr($key)));
|
||||||
}
|
}
|
||||||
$data = $model->toArray();
|
$data = $model->toArray();
|
||||||
return $model[$key] ?? true;
|
return $model[$key] ?? true;
|
||||||
@ -178,19 +229,21 @@ class SystemService extends Service
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 批量更新保存数据
|
* 批量更新保存数据.
|
||||||
* @param Model|Query|string $query 数据查询对象
|
* @param Model|Query|string $query 数据查询对象
|
||||||
* @param array $data 需要保存的数据,成功返回对应模型
|
* @param array $data 需要保存的数据,成功返回对应模型
|
||||||
* @param string $key 更新条件查询主键
|
* @param string $key 更新条件查询主键
|
||||||
* @param mixed $map 额外更新查询条件
|
* @param mixed $map 额外更新查询条件
|
||||||
* @return boolean|integer 失败返回 false, 成功返回主键值或 true
|
* @return bool|int 失败返回 false, 成功返回主键值或 true
|
||||||
* @throws \think\admin\Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public static function update($query, array $data, string $key = 'id', $map = [])
|
public static function update($query, array $data, string $key = 'id', $map = [])
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$query = Helper::buildQuery($query)->master()->where($map);
|
$query = Helper::buildQuery($query)->master()->where($map);
|
||||||
if (empty($map[$key])) $query->where([$key => $data[$key] ?? null]);
|
if (empty($map[$key])) {
|
||||||
|
$query->where([$key => $data[$key] ?? null]);
|
||||||
|
}
|
||||||
return (clone $query)->count() > 1 ? $query->strict(false)->update($data) : $query->findOrEmpty()->save($data);
|
return (clone $query)->count() > 1 ? $query->strict(false)->update($data) : $query->findOrEmpty()->save($data);
|
||||||
} catch (\Exception|\Throwable $exception) {
|
} catch (\Exception|\Throwable $exception) {
|
||||||
throw new Exception($exception->getMessage(), $exception->getCode());
|
throw new Exception($exception->getMessage(), $exception->getCode());
|
||||||
@ -198,22 +251,7 @@ class SystemService extends Service
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 解析缓存名称
|
* 获取数据库所有数据表.
|
||||||
* @param string $rule 配置名称
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
private static function _parse(string $rule): array
|
|
||||||
{
|
|
||||||
$type = 'base';
|
|
||||||
if (stripos($rule, '.') !== false) {
|
|
||||||
[$type, $rule] = explode('.', $rule, 2);
|
|
||||||
}
|
|
||||||
[$field, $outer] = explode('|', "{$rule}|");
|
|
||||||
return [$type, $field, strtolower($outer)];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取数据库所有数据表
|
|
||||||
* @return array [table, total, count]
|
* @return array [table, total, count]
|
||||||
*/
|
*/
|
||||||
public static function getTables(): array
|
public static function getTables(): array
|
||||||
@ -223,18 +261,20 @@ class SystemService extends Service
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 复制并创建表结构
|
* 复制并创建表结构.
|
||||||
* @param string $from 来源表名
|
* @param string $from 来源表名
|
||||||
* @param string $create 创建表名
|
* @param string $create 创建表名
|
||||||
* @param array $tables 现有表集合
|
* @param array $tables 现有表集合
|
||||||
* @param boolean $copy 是否复制
|
* @param bool $copy 是否复制
|
||||||
* @param mixed $where 复制条件
|
* @param mixed $where 复制条件
|
||||||
* @throws \think\admin\Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public static function copyTableStruct(string $from, string $create, array $tables = [], bool $copy = false, $where = [])
|
public static function copyTableStruct(string $from, string $create, array $tables = [], bool $copy = false, $where = [])
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
if (empty($tables)) [$tables] = static::getTables();
|
if (empty($tables)) {
|
||||||
|
[$tables] = static::getTables();
|
||||||
|
}
|
||||||
if (!in_array($from, $tables)) {
|
if (!in_array($from, $tables)) {
|
||||||
throw new Exception("待复制的数据表 {$from} 不存在!");
|
throw new Exception("待复制的数据表 {$from} 不存在!");
|
||||||
}
|
}
|
||||||
@ -251,11 +291,10 @@ class SystemService extends Service
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 保存数据内容
|
* 保存数据内容.
|
||||||
* @param string $name 数据名称
|
* @param string $name 数据名称
|
||||||
* @param mixed $value 数据内容
|
* @param mixed $value 数据内容
|
||||||
* @return boolean
|
* @throws Exception
|
||||||
* @throws \think\admin\Exception
|
|
||||||
*/
|
*/
|
||||||
public static function setData(string $name, $value): bool
|
public static function setData(string $name, $value): bool
|
||||||
{
|
{
|
||||||
@ -268,7 +307,7 @@ class SystemService extends Service
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 读取数据内容
|
* 读取数据内容.
|
||||||
* @param string $name 数据名称
|
* @param string $name 数据名称
|
||||||
* @param mixed $default 默认内容
|
* @param mixed $default 默认内容
|
||||||
* @return mixed
|
* @return mixed
|
||||||
@ -278,7 +317,9 @@ class SystemService extends Service
|
|||||||
try {
|
try {
|
||||||
// 读取原始序列化或JSON数据
|
// 读取原始序列化或JSON数据
|
||||||
$value = SystemData::mk()->where(['name' => $name])->value('value');
|
$value = SystemData::mk()->where(['name' => $name])->value('value');
|
||||||
if (is_null($value)) return $default;
|
if (is_null($value)) {
|
||||||
|
return $default;
|
||||||
|
}
|
||||||
if (is_string($value) && strpos($value, '[') === 0) {
|
if (is_string($value) && strpos($value, '[') === 0) {
|
||||||
return json_decode($value, true)[0];
|
return json_decode($value, true)[0];
|
||||||
}
|
}
|
||||||
@ -306,10 +347,7 @@ class SystemService extends Service
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 写入系统日志内容
|
* 写入系统日志内容.
|
||||||
* @param string $action
|
|
||||||
* @param string $content
|
|
||||||
* @return boolean
|
|
||||||
*/
|
*/
|
||||||
public static function setOplog(string $action, string $content): bool
|
public static function setOplog(string $action, string $content): bool
|
||||||
{
|
{
|
||||||
@ -317,27 +355,24 @@ class SystemService extends Service
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取系统日志内容
|
* 获取系统日志内容.
|
||||||
* @param string $action
|
|
||||||
* @param string $content
|
|
||||||
* @return array
|
|
||||||
*/
|
*/
|
||||||
public static function getOplog(string $action, string $content): array
|
public static function getOplog(string $action, string $content): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'node' => NodeService::getCurrent(),
|
'node' => NodeService::getCurrent(),
|
||||||
'action' => lang($action), 'content' => lang($content),
|
'action' => lang($action), 'content' => lang($content),
|
||||||
'geoip' => Library::$sapp->request->ip() ?: '127.0.0.1',
|
'geoip' => Library::$sapp->request->ip() ?: '127.0.0.1',
|
||||||
'username' => AdminService::getUserName() ?: '-',
|
'username' => AdminService::getUserName() ?: '-',
|
||||||
'create_at' => date('Y-m-d H:i:s'),
|
'create_at' => date('Y-m-d H:i:s'),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 打印输出数据到文件
|
* 打印输出数据到文件.
|
||||||
* @param mixed $data 输出的数据
|
* @param mixed $data 输出的数据
|
||||||
* @param boolean $new 强制替换文件
|
* @param bool $new 强制替换文件
|
||||||
* @param string|null $file 文件名称
|
* @param null|string $file 文件名称
|
||||||
* @return false|int
|
* @return false|int
|
||||||
*/
|
*/
|
||||||
public static function putDebug($data, bool $new = false, ?string $file = null)
|
public static function putDebug($data, bool $new = false, ?string $file = null)
|
||||||
@ -345,17 +380,19 @@ class SystemService extends Service
|
|||||||
ob_start();
|
ob_start();
|
||||||
var_dump($data);
|
var_dump($data);
|
||||||
$output = preg_replace('/]=>\n(\s+)/m', '] => ', ob_get_clean());
|
$output = preg_replace('/]=>\n(\s+)/m', '] => ', ob_get_clean());
|
||||||
if (is_null($file)) $file = syspath('runtime/' . date('Ymd') . '.log');
|
if (is_null($file)) {
|
||||||
else if (!preg_match('#[/\\\\]+#', $file)) $file = syspath("runtime/{$file}.log");
|
$file = syspath('runtime/' . date('Ymd') . '.log');
|
||||||
|
} elseif (!preg_match('#[/\\\]+#', $file)) {
|
||||||
|
$file = syspath("runtime/{$file}.log");
|
||||||
|
}
|
||||||
is_dir($dir = dirname($file)) or mkdir($dir, 0777, true);
|
is_dir($dir = dirname($file)) or mkdir($dir, 0777, true);
|
||||||
return $new ? file_put_contents($file, $output) : file_put_contents($file, $output, FILE_APPEND);
|
return $new ? file_put_contents($file, $output) : file_put_contents($file, $output, FILE_APPEND);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置网页标签图标
|
* 设置网页标签图标.
|
||||||
* @param ?string $icon 网页标签图标
|
* @param ?string $icon 网页标签图标
|
||||||
* @return boolean
|
* @throws Exception
|
||||||
* @throws \think\admin\Exception
|
|
||||||
*/
|
*/
|
||||||
public static function setFavicon(?string $icon = null): bool
|
public static function setFavicon(?string $icon = null): bool
|
||||||
{
|
{
|
||||||
@ -371,7 +408,9 @@ class SystemService extends Service
|
|||||||
$name = Storage::name($icon, 'tmp', 'icon');
|
$name = Storage::name($icon, 'tmp', 'icon');
|
||||||
$info = LocalStorage::instance()->set($name, Storage::curlGet($icon), true);
|
$info = LocalStorage::instance()->set($name, Storage::curlGet($icon), true);
|
||||||
}
|
}
|
||||||
if (empty($info) || empty($info['file'])) return false;
|
if (empty($info) || empty($info['file'])) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
$favicon = new FaviconExtend($info['file'], [48, 48]);
|
$favicon = new FaviconExtend($info['file'], [48, 48]);
|
||||||
return $favicon->saveIco(syspath('public/favicon.ico'));
|
return $favicon->saveIco(syspath('public/favicon.ico'));
|
||||||
} catch (Exception $exception) {
|
} catch (Exception $exception) {
|
||||||
@ -383,49 +422,16 @@ class SystemService extends Service
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 魔术方法调用(临时)
|
* 解析缓存名称.
|
||||||
* @param string $method 方法名称
|
* @param string $rule 配置名称
|
||||||
* @param array $arguments 调用参数
|
|
||||||
* @return mixed
|
|
||||||
* @throws \think\admin\Exception
|
|
||||||
*/
|
*/
|
||||||
public function __call(string $method, array $arguments)
|
private static function _parse(string $rule): array
|
||||||
{
|
{
|
||||||
return static::__callStatic($method, $arguments);
|
$type = 'base';
|
||||||
}
|
if (stripos($rule, '.') !== false) {
|
||||||
|
[$type, $rule] = explode('.', $rule, 2);
|
||||||
/**
|
|
||||||
* 静态方法兼容(临时)
|
|
||||||
* @param string $method 方法名称
|
|
||||||
* @param array $arguments 调用参数
|
|
||||||
* @return mixed
|
|
||||||
* @throws \think\admin\Exception
|
|
||||||
*/
|
|
||||||
public static function __callStatic(string $method, array $arguments)
|
|
||||||
{
|
|
||||||
$map = [
|
|
||||||
'setRuntime' => 'set',
|
|
||||||
'getRuntime' => 'get',
|
|
||||||
'bindRuntime' => 'apply',
|
|
||||||
'isDebug' => 'isDebug',
|
|
||||||
'isOnline' => 'isOnline',
|
|
||||||
'doInit' => 'doWebsiteInit',
|
|
||||||
'doConsoleInit' => 'doConsoleInit',
|
|
||||||
'pushRuntime' => 'push',
|
|
||||||
'clearRuntime' => 'clear',
|
|
||||||
'checkRunMode' => 'check',
|
|
||||||
];
|
|
||||||
switch (strtolower($method)) {
|
|
||||||
case 'setconfig':
|
|
||||||
return self::setData(...$arguments);
|
|
||||||
case 'getconfig':
|
|
||||||
return self::getData(...$arguments);
|
|
||||||
}
|
|
||||||
if (isset($map[$method])) {
|
|
||||||
return RuntimeService::{$map[$method]}(...$arguments);
|
|
||||||
} else {
|
|
||||||
throw new Exception("method not exists: RuntimeService::{$method}()");
|
|
||||||
}
|
}
|
||||||
|
[$field, $outer] = explode('|', "{$rule}|");
|
||||||
|
return [$type, $field, strtolower($outer)];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,23 +1,26 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// +----------------------------------------------------------------------
|
declare(strict_types=1);
|
||||||
// | Library for ThinkAdmin
|
/**
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 版权所有 2014~2025 ThinkAdmin [ thinkadmin.top ]
|
* | Payment Plugin for ThinkAdmin
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 官方网站: https://thinkadmin.top
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 开源协议 ( https://mit-license.org )
|
* | 官方网站: https://thinkadmin.top
|
||||||
// | 免费声明 ( https://thinkadmin.top/disclaimer )
|
* +----------------------------------------------------------------------
|
||||||
// +----------------------------------------------------------------------
|
* | 开源协议 ( https://mit-license.org )
|
||||||
// | gitee 仓库地址 :https://gitee.com/zoujingli/ThinkLibrary
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
// | github 仓库地址 :https://github.com/zoujingli/ThinkLibrary
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
declare (strict_types=1);
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
namespace think\admin\service;
|
namespace think\admin\service;
|
||||||
|
|
||||||
|
use think\admin\Exception;
|
||||||
use think\admin\extend\HttpExtend;
|
use think\admin\extend\HttpExtend;
|
||||||
use think\admin\Service;
|
use think\admin\Service;
|
||||||
|
|
||||||
@ -25,18 +28,11 @@ use think\admin\Service;
|
|||||||
* 新助通短信接口服务
|
* 新助通短信接口服务
|
||||||
* @class ZtSmsService
|
* @class ZtSmsService
|
||||||
* @deprecated 独立封装为插件
|
* @deprecated 独立封装为插件
|
||||||
* @package think\admin\service
|
|
||||||
*/
|
*/
|
||||||
class ZtSmsService extends Service
|
class ZtSmsService extends Service
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* 接口地址
|
* 子账号名称.
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
private $api = 'https://api.mix2.zthysms.com';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 子账号名称
|
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
protected $username;
|
protected $username;
|
||||||
@ -48,17 +44,13 @@ class ZtSmsService extends Service
|
|||||||
protected $password;
|
protected $password;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 短信服务初始化
|
* 接口地址
|
||||||
* @throws \think\admin\Exception
|
* @var string
|
||||||
*/
|
*/
|
||||||
protected function initialize()
|
private $api = 'https://api.mix2.zthysms.com';
|
||||||
{
|
|
||||||
$this->username = sysconf('ztsms.username|raw') ?: '';
|
|
||||||
$this->password = sysconf('ztsms.password|raw') ?: '';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 短信服务初始化
|
* 短信服务初始化.
|
||||||
* @param string $username 账号名称
|
* @param string $username 账号名称
|
||||||
* @param string $password 账号密码
|
* @param string $password 账号密码
|
||||||
* @return static
|
* @return static
|
||||||
@ -75,7 +67,6 @@ class ZtSmsService extends Service
|
|||||||
* @param string $code 验证码
|
* @param string $code 验证码
|
||||||
* @param string $phone 手机号验证
|
* @param string $phone 手机号验证
|
||||||
* @param string $template 模板编码
|
* @param string $template 模板编码
|
||||||
* @return boolean
|
|
||||||
*/
|
*/
|
||||||
public function checkVerifyCode(string $code, string $phone, string $template = 'ztsms.register_verify'): bool
|
public function checkVerifyCode(string $code, string $phone, string $template = 'ztsms.register_verify'): bool
|
||||||
{
|
{
|
||||||
@ -83,18 +74,16 @@ class ZtSmsService extends Service
|
|||||||
if (is_array($cache) && isset($cache['code']) && $cache['code'] == $code) {
|
if (is_array($cache) && isset($cache['code']) && $cache['code'] == $code) {
|
||||||
$this->app->cache->delete($ckey);
|
$this->app->cache->delete($ckey);
|
||||||
return true;
|
return true;
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 验证手机短信验证码
|
* 验证手机短信验证码
|
||||||
* @param string $phone 手机号码
|
* @param string $phone 手机号码
|
||||||
* @param integer $wait 等待时间
|
* @param int $wait 等待时间
|
||||||
* @param string $template 模板编码
|
* @param string $template 模板编码
|
||||||
* @return array
|
* @throws Exception
|
||||||
* @throws \think\admin\Exception
|
|
||||||
*/
|
*/
|
||||||
public function sendVerifyCode(string $phone, int $wait = 120, string $template = 'ztsms.register_verify'): array
|
public function sendVerifyCode(string $phone, int $wait = 120, string $template = 'ztsms.register_verify'): array
|
||||||
{
|
{
|
||||||
@ -113,28 +102,27 @@ class ZtSmsService extends Service
|
|||||||
[$state] = $this->timeSend($phone, str_replace('{code}', $code, $content));
|
[$state] = $this->timeSend($phone, str_replace('{code}', $code, $content));
|
||||||
if ($state) {
|
if ($state) {
|
||||||
return [1, lang('短信验证码发送成功!'), ['time' => $wait]];
|
return [1, lang('短信验证码发送成功!'), ['time' => $wait]];
|
||||||
} else {
|
|
||||||
$this->app->cache->delete($ckey);
|
|
||||||
return [0, lang('短信发送失败,请稍候再试!'), ['time' => 0]];
|
|
||||||
}
|
}
|
||||||
|
$this->app->cache->delete($ckey);
|
||||||
|
return [0, lang('短信发送失败,请稍候再试!'), ['time' => 0]];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建短信签名
|
* 创建短信签名.
|
||||||
* @param array $signs 签名列表
|
* @param array $signs 签名列表
|
||||||
* @param string $remark 签名备注
|
* @param string $remark 签名备注
|
||||||
* @return array
|
|
||||||
*/
|
*/
|
||||||
public function signAdd(array $signs = [], string $remark = ''): array
|
public function signAdd(array $signs = [], string $remark = ''): array
|
||||||
{
|
{
|
||||||
foreach ($signs as $key => $name) $signs[$key] = $this->_singName($name);
|
foreach ($signs as $key => $name) {
|
||||||
|
$signs[$key] = $this->_singName($name);
|
||||||
|
}
|
||||||
return $this->doRequest('/sms/v1/sign', ['sign' => $signs, 'remark' => $remark]);
|
return $this->doRequest('/sms/v1/sign', ['sign' => $signs, 'remark' => $remark]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询短信签名
|
* 查询短信签名.
|
||||||
* @param string $name 短信签名
|
* @param string $name 短信签名
|
||||||
* @return array
|
|
||||||
*/
|
*/
|
||||||
public function signGet(string $name): array
|
public function signGet(string $name): array
|
||||||
{
|
{
|
||||||
@ -146,11 +134,10 @@ class ZtSmsService extends Service
|
|||||||
/**
|
/**
|
||||||
* 报备短信模板
|
* 报备短信模板
|
||||||
* @param string $name 模板名称
|
* @param string $name 模板名称
|
||||||
* @param integer $type 模板类型(1验证码, 2行业通知, 3营销推广)
|
* @param int $type 模板类型(1验证码, 2行业通知, 3营销推广)
|
||||||
* @param string $content 模板内容
|
* @param string $content 模板内容
|
||||||
* @param array $params 模板变量
|
* @param array $params 模板变量
|
||||||
* @param string $remark 模板备注
|
* @param string $remark 模板备注
|
||||||
* @return array
|
|
||||||
*/
|
*/
|
||||||
public function tplAdd(string $name, int $type, string $content, array $params = [], string $remark = ''): array
|
public function tplAdd(string $name, int $type, string $content, array $params = [], string $remark = ''): array
|
||||||
{
|
{
|
||||||
@ -162,7 +149,6 @@ class ZtSmsService extends Service
|
|||||||
/**
|
/**
|
||||||
* 查询模板状态
|
* 查询模板状态
|
||||||
* @param string $temId 短信模板
|
* @param string $temId 短信模板
|
||||||
* @return array
|
|
||||||
*/
|
*/
|
||||||
public function tplGet(string $temId): array
|
public function tplGet(string $temId): array
|
||||||
{
|
{
|
||||||
@ -174,7 +160,6 @@ class ZtSmsService extends Service
|
|||||||
* @param string $tpId 短信模板
|
* @param string $tpId 短信模板
|
||||||
* @param string $sign 短信签名
|
* @param string $sign 短信签名
|
||||||
* @param array $records 发送记录
|
* @param array $records 发送记录
|
||||||
* @return array
|
|
||||||
*/
|
*/
|
||||||
public function tplSend(string $tpId, string $sign, array $records): array
|
public function tplSend(string $tpId, string $sign, array $records): array
|
||||||
{
|
{
|
||||||
@ -187,20 +172,19 @@ class ZtSmsService extends Service
|
|||||||
* 发送定时短信
|
* 发送定时短信
|
||||||
* @param string $mobile 发送手机号码
|
* @param string $mobile 发送手机号码
|
||||||
* @param string $content 发送短信内容
|
* @param string $content 发送短信内容
|
||||||
* @param integer $time 定时发送时间(为 0 立即发送)
|
* @param int $time 定时发送时间(为 0 立即发送)
|
||||||
* @return array
|
|
||||||
*/
|
*/
|
||||||
public function timeSend(string $mobile, string $content, int $time = 0): array
|
public function timeSend(string $mobile, string $content, int $time = 0): array
|
||||||
{
|
{
|
||||||
$data = ['mobile' => $mobile, 'content' => $content];
|
$data = ['mobile' => $mobile, 'content' => $content];
|
||||||
if ($time > 0) $data['time'] = $time;
|
if ($time > 0) {
|
||||||
|
$data['time'] = $time;
|
||||||
|
}
|
||||||
return $this->doRequest('/v2/sendSms', $data);
|
return $this->doRequest('/v2/sendSms', $data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 批量发送短信
|
* 批量发送短信
|
||||||
* @param array $records
|
|
||||||
* @return array
|
|
||||||
*/
|
*/
|
||||||
public function batchSend(array $records): array
|
public function batchSend(array $records): array
|
||||||
{
|
{
|
||||||
@ -208,7 +192,7 @@ class ZtSmsService extends Service
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 短信条数查询
|
* 短信条数查询.
|
||||||
*/
|
*/
|
||||||
public function balance(): array
|
public function balance(): array
|
||||||
{
|
{
|
||||||
@ -217,14 +201,26 @@ class ZtSmsService extends Service
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 短信签名内容处理
|
* 短信服务初始化.
|
||||||
* @param string $name
|
* @throws Exception
|
||||||
* @return string
|
*/
|
||||||
|
protected function initialize()
|
||||||
|
{
|
||||||
|
$this->username = sysconf('ztsms.username|raw') ?: '';
|
||||||
|
$this->password = sysconf('ztsms.password|raw') ?: '';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 短信签名内容处理.
|
||||||
*/
|
*/
|
||||||
private function _singName(string $name): string
|
private function _singName(string $name): string
|
||||||
{
|
{
|
||||||
if (strpos($name, '】') === false) $name = $name . '】';
|
if (strpos($name, '】') === false) {
|
||||||
if (strpos($name, '【') === false) $name = '【' . $name;
|
$name = $name . '】';
|
||||||
|
}
|
||||||
|
if (strpos($name, '【') === false) {
|
||||||
|
$name = '【' . $name;
|
||||||
|
}
|
||||||
return $name;
|
return $name;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -232,7 +228,6 @@ class ZtSmsService extends Service
|
|||||||
* 执行网络请求
|
* 执行网络请求
|
||||||
* @param string $uri 接口请求地址
|
* @param string $uri 接口请求地址
|
||||||
* @param array $data 接口请求参数
|
* @param array $data 接口请求参数
|
||||||
* @return array
|
|
||||||
*/
|
*/
|
||||||
private function doRequest(string $uri, array $data): array
|
private function doRequest(string $uri, array $data): array
|
||||||
{
|
{
|
||||||
@ -242,22 +237,21 @@ class ZtSmsService extends Service
|
|||||||
$result = json_decode(HttpExtend::post($this->api . $uri, json_encode(array_merge($data, $extends)), $options), true);
|
$result = json_decode(HttpExtend::post($this->api . $uri, json_encode(array_merge($data, $extends)), $options), true);
|
||||||
if (empty($result['code'])) {
|
if (empty($result['code'])) {
|
||||||
return [0, [], lang('接口请求网络异常')];
|
return [0, [], lang('接口请求网络异常')];
|
||||||
} elseif (intval($result['code']) === 200) {
|
|
||||||
return [1, $result, lang($this->error($result['code']))];
|
|
||||||
} else {
|
|
||||||
return [0, $result, lang($this->error($result['code']))];
|
|
||||||
}
|
}
|
||||||
|
if (intval($result['code']) === 200) {
|
||||||
|
return [1, $result, lang($this->error($result['code']))];
|
||||||
|
}
|
||||||
|
return [0, $result, lang($this->error($result['code']))];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取状态描述
|
* 获取状态描述.
|
||||||
* @param integer $code 异常编号
|
* @param int $code 异常编号
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
private function error(int $code): string
|
private function error(int $code): string
|
||||||
{
|
{
|
||||||
$arrs = [
|
$arrs = [
|
||||||
200 => '提交成功',
|
200 => '提交成功',
|
||||||
4001 => '用户名错误',
|
4001 => '用户名错误',
|
||||||
4002 => '密码不能为空',
|
4002 => '密码不能为空',
|
||||||
4003 => '短信内容不能为空',
|
4003 => '短信内容不能为空',
|
||||||
@ -293,4 +287,4 @@ class ZtSmsService extends Service
|
|||||||
];
|
];
|
||||||
return $arrs[$code] ?? "{$code}";
|
return $arrs[$code] ?? "{$code}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,20 +1,22 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// +----------------------------------------------------------------------
|
declare(strict_types=1);
|
||||||
// | Library for ThinkAdmin
|
/**
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 版权所有 2014~2025 ThinkAdmin [ thinkadmin.top ]
|
* | Payment Plugin for ThinkAdmin
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 官方网站: https://thinkadmin.top
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 开源协议 ( https://mit-license.org )
|
* | 官方网站: https://thinkadmin.top
|
||||||
// | 免费声明 ( https://thinkadmin.top/disclaimer )
|
* +----------------------------------------------------------------------
|
||||||
// +----------------------------------------------------------------------
|
* | 开源协议 ( https://mit-license.org )
|
||||||
// | gitee 仓库地址 :https://gitee.com/zoujingli/ThinkLibrary
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
// | github 仓库地址 :https://github.com/zoujingli/ThinkLibrary
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
declare (strict_types=1);
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
namespace think\admin\storage;
|
namespace think\admin\storage;
|
||||||
|
|
||||||
@ -27,39 +29,203 @@ use think\admin\Storage;
|
|||||||
/**
|
/**
|
||||||
* 阿里云OSS存储支持
|
* 阿里云OSS存储支持
|
||||||
* @class AliossStorage
|
* @class AliossStorage
|
||||||
* @package think\admin\storage
|
|
||||||
*/
|
*/
|
||||||
class AliossStorage implements StorageInterface
|
class AliossStorage implements StorageInterface
|
||||||
{
|
{
|
||||||
use StorageUsageTrait;
|
use StorageUsageTrait;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 数据中心
|
* 数据中心.
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
private $point;
|
private $point;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 存储空间名称
|
* 存储空间名称.
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
private $bucket;
|
private $bucket;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AccessId
|
* AccessId.
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
private $accessKey;
|
private $accessKey;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AccessSecret
|
* AccessSecret.
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
private $secretKey;
|
private $secretKey;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 初始化入口
|
* 上传文件内容.
|
||||||
* @throws \think\admin\Exception
|
* @param string $name 文件名称
|
||||||
|
* @param string $file 文件内容
|
||||||
|
* @param bool $safe 安全模式
|
||||||
|
* @param ?string $attname 下载名称
|
||||||
|
*/
|
||||||
|
public function set(string $name, string $file, bool $safe = false, ?string $attname = null): array
|
||||||
|
{
|
||||||
|
$token = $this->token($name);
|
||||||
|
$data = ['key' => $name];
|
||||||
|
$data['policy'] = $token['policy'];
|
||||||
|
$data['Signature'] = $token['signature'];
|
||||||
|
$data['OSSAccessKeyId'] = $this->accessKey;
|
||||||
|
$data['success_action_status'] = '200';
|
||||||
|
if (is_string($attname) && strlen($attname) > 0) {
|
||||||
|
$data['Content-Disposition'] = 'inline;filename=' . urlencode($attname);
|
||||||
|
}
|
||||||
|
$file = ['field' => 'file', 'name' => $name, 'content' => $file];
|
||||||
|
if (is_numeric(stripos(HttpExtend::submit($this->upload(), $data, $file), '200 OK'))) {
|
||||||
|
return ['file' => $this->path($name, $safe), 'url' => $this->url($name, $safe, $attname), 'key' => $name];
|
||||||
|
}
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 读取文件内容.
|
||||||
|
* @param string $name 文件名称
|
||||||
|
* @param bool $safe 安全模式
|
||||||
|
*/
|
||||||
|
public function get(string $name, bool $safe = false): string
|
||||||
|
{
|
||||||
|
return Storage::curlGet($this->url($name, $safe));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除存储文件.
|
||||||
|
* @param string $name 文件名称
|
||||||
|
* @param bool $safe 安全模式
|
||||||
|
*/
|
||||||
|
public function del(string $name, bool $safe = false): bool
|
||||||
|
{
|
||||||
|
[$file] = explode('?', $name);
|
||||||
|
$result = HttpExtend::request('DELETE', "https://{$this->bucket}.{$this->point}/{$file}", [
|
||||||
|
'returnHeader' => true, 'headers' => $this->_sign('DELETE', $file),
|
||||||
|
]);
|
||||||
|
return is_numeric(stripos($result, '204 No Content'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断是否存在.
|
||||||
|
* @param string $name 文件名称
|
||||||
|
* @param bool $safe 安全模式
|
||||||
|
*/
|
||||||
|
public function has(string $name, bool $safe = false): bool
|
||||||
|
{
|
||||||
|
$file = $this->delSuffix($name);
|
||||||
|
$result = HttpExtend::request('HEAD', "https://{$this->bucket}.{$this->point}/{$file}", [
|
||||||
|
'returnHeader' => true, 'headers' => $this->_sign('HEAD', $file),
|
||||||
|
]);
|
||||||
|
return is_numeric(stripos($result, 'HTTP/1.1 200 OK'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取访问地址
|
||||||
|
* @param string $name 文件名称
|
||||||
|
* @param bool $safe 安全模式
|
||||||
|
* @param ?string $attname 下载名称
|
||||||
|
*/
|
||||||
|
public function url(string $name, bool $safe = false, ?string $attname = null): string
|
||||||
|
{
|
||||||
|
return "{$this->domain}/{$this->delSuffix($name)}{$this->getSuffix($attname, $name)}";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取存储路径.
|
||||||
|
* @param string $name 文件名称
|
||||||
|
* @param bool $safe 安全模式
|
||||||
|
*/
|
||||||
|
public function path(string $name, bool $safe = false): string
|
||||||
|
{
|
||||||
|
return $this->url($name, $safe);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取文件信息.
|
||||||
|
* @param string $name 文件名称
|
||||||
|
* @param bool $safe 安全模式
|
||||||
|
* @param ?string $attname 下载名称
|
||||||
|
*/
|
||||||
|
public function info(string $name, bool $safe = false, ?string $attname = null): array
|
||||||
|
{
|
||||||
|
return $this->has($name, $safe) ? [
|
||||||
|
'url' => $this->url($name, $safe, $attname),
|
||||||
|
'key' => $name, 'file' => $this->path($name, $safe),
|
||||||
|
] : [];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取上传地址
|
||||||
|
*/
|
||||||
|
public function upload(): string
|
||||||
|
{
|
||||||
|
$proc = $this->app->request->isSsl() ? 'https' : 'http';
|
||||||
|
return "{$proc}://{$this->bucket}.{$this->point}";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取上传令牌.
|
||||||
|
* @param string $name 文件名称
|
||||||
|
* @param int $expires 有效时间
|
||||||
|
* @param ?string $attname 下载名称
|
||||||
|
*/
|
||||||
|
public function token(string $name, int $expires = 3600, ?string $attname = null): array
|
||||||
|
{
|
||||||
|
$data = [
|
||||||
|
'policy' => base64_encode(json_encode([
|
||||||
|
'conditions' => [['content-length-range', 0, 1048576000]],
|
||||||
|
'expiration' => date('Y-m-d\TH:i:s.000\Z', time() + $expires),
|
||||||
|
])),
|
||||||
|
'keyid' => $this->accessKey,
|
||||||
|
'siteurl' => $this->url($name, false, $attname),
|
||||||
|
];
|
||||||
|
$data['signature'] = base64_encode(hash_hmac('sha1', $data['policy'], $this->secretKey, true));
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取存储区域
|
||||||
|
*/
|
||||||
|
public static function region(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'oss-cn-hangzhou.aliyuncs.com' => lang('华东 1(杭州)'),
|
||||||
|
'oss-cn-shanghai.aliyuncs.com' => lang('华东 2(上海)'),
|
||||||
|
'oss-cn-nanjing.aliyuncs.com' => lang('华东 5(南京本地地域)'),
|
||||||
|
'oss-cn-fuzhou.aliyuncs.com' => lang('华东 6(福州本地地域)'),
|
||||||
|
'oss-cn-qingdao.aliyuncs.com' => lang('华北 1(青岛)'),
|
||||||
|
'oss-cn-beijing.aliyuncs.com' => lang('华北 2(北京)'),
|
||||||
|
'oss-cn-zhangjiakou.aliyuncs.com' => lang('华北 3(张家口)'),
|
||||||
|
'oss-cn-huhehaote.aliyuncs.com' => lang('华北 5(呼和浩特)'),
|
||||||
|
'oss-cn-wulanchabu.aliyuncs.com' => lang('华北 6(乌兰察布)'),
|
||||||
|
'oss-cn-shenzhen.aliyuncs.com' => lang('华南 1(深圳)'),
|
||||||
|
'oss-cn-heyuan.aliyuncs.com' => lang('华南 2(河源)'),
|
||||||
|
'oss-cn-guangzhou.aliyuncs.com' => lang('华南 3(广州)'),
|
||||||
|
'oss-cn-chengdu.aliyuncs.com' => lang('西南 1(成都)'),
|
||||||
|
'oss-cn-hongkong.aliyuncs.com' => lang('中国(香港)'),
|
||||||
|
'oss-us-west-1.aliyuncs.com' => lang('美国(硅谷)'),
|
||||||
|
'oss-us-east-1.aliyuncs.com' => lang('美国(弗吉尼亚)'),
|
||||||
|
'oss-ap-northeast-1.aliyuncs.com' => lang('日本(东京)'),
|
||||||
|
'oss-ap-northeast-2.aliyuncs.com' => lang('韩国(首尔)'),
|
||||||
|
'oss-ap-southeast-1.aliyuncs.com' => lang('新加坡'),
|
||||||
|
'oss-ap-southeast-2.aliyuncs.com' => lang('澳大利亚(悉尼)'),
|
||||||
|
'oss-ap-southeast-3.aliyuncs.com' => lang('马来西亚(吉隆坡)'),
|
||||||
|
'oss-ap-southeast-5.aliyuncs.com' => lang('印度尼西亚(雅加达)'),
|
||||||
|
'oss-ap-southeast-6.aliyuncs.com' => lang('菲律宾(马尼拉)'),
|
||||||
|
'oss-ap-southeast-7.aliyuncs.com' => lang('泰国(曼谷)'),
|
||||||
|
'oss-ap-south-1.aliyuncs.com' => lang('印度(孟买)'),
|
||||||
|
'oss-eu-central-1.aliyuncs.com' => lang('德国(法兰克福)'),
|
||||||
|
'oss-eu-west-1.aliyuncs.com' => lang('英国(伦敦)'),
|
||||||
|
'oss-me-east-1.aliyuncs.com' => lang('阿联酋(迪拜)'),
|
||||||
|
'oss-rg-china-mainland.aliyuncs.com' => lang('无地域属性(中国内地)'),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化入口.
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
protected function init()
|
protected function init()
|
||||||
{
|
{
|
||||||
@ -81,147 +247,9 @@ class AliossStorage implements StorageInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 上传文件内容
|
* 请求数据签名.
|
||||||
* @param string $name 文件名称
|
|
||||||
* @param string $file 文件内容
|
|
||||||
* @param boolean $safe 安全模式
|
|
||||||
* @param ?string $attname 下载名称
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function set(string $name, string $file, bool $safe = false, ?string $attname = null): array
|
|
||||||
{
|
|
||||||
$token = $this->token($name);
|
|
||||||
$data = ['key' => $name];
|
|
||||||
$data['policy'] = $token['policy'];
|
|
||||||
$data['Signature'] = $token['signature'];
|
|
||||||
$data['OSSAccessKeyId'] = $this->accessKey;
|
|
||||||
$data['success_action_status'] = '200';
|
|
||||||
if (is_string($attname) && strlen($attname) > 0) {
|
|
||||||
$data['Content-Disposition'] = 'inline;filename=' . urlencode($attname);
|
|
||||||
}
|
|
||||||
$file = ['field' => 'file', 'name' => $name, 'content' => $file];
|
|
||||||
if (is_numeric(stripos(HttpExtend::submit($this->upload(), $data, $file), '200 OK'))) {
|
|
||||||
return ['file' => $this->path($name, $safe), 'url' => $this->url($name, $safe, $attname), 'key' => $name];
|
|
||||||
} else {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 读取文件内容
|
|
||||||
* @param string $name 文件名称
|
|
||||||
* @param boolean $safe 安全模式
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function get(string $name, bool $safe = false): string
|
|
||||||
{
|
|
||||||
return Storage::curlGet($this->url($name, $safe));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 删除存储文件
|
|
||||||
* @param string $name 文件名称
|
|
||||||
* @param boolean $safe 安全模式
|
|
||||||
* @return boolean
|
|
||||||
*/
|
|
||||||
public function del(string $name, bool $safe = false): bool
|
|
||||||
{
|
|
||||||
[$file] = explode('?', $name);
|
|
||||||
$result = HttpExtend::request('DELETE', "https://{$this->bucket}.{$this->point}/{$file}", [
|
|
||||||
'returnHeader' => true, 'headers' => $this->_sign('DELETE', $file),
|
|
||||||
]);
|
|
||||||
return is_numeric(stripos($result, '204 No Content'));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 判断是否存在
|
|
||||||
* @param string $name 文件名称
|
|
||||||
* @param boolean $safe 安全模式
|
|
||||||
* @return boolean
|
|
||||||
*/
|
|
||||||
public function has(string $name, bool $safe = false): bool
|
|
||||||
{
|
|
||||||
$file = $this->delSuffix($name);
|
|
||||||
$result = HttpExtend::request('HEAD', "https://{$this->bucket}.{$this->point}/{$file}", [
|
|
||||||
'returnHeader' => true, 'headers' => $this->_sign('HEAD', $file),
|
|
||||||
]);
|
|
||||||
return is_numeric(stripos($result, 'HTTP/1.1 200 OK'));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取访问地址
|
|
||||||
* @param string $name 文件名称
|
|
||||||
* @param boolean $safe 安全模式
|
|
||||||
* @param ?string $attname 下载名称
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function url(string $name, bool $safe = false, ?string $attname = null): string
|
|
||||||
{
|
|
||||||
return "{$this->domain}/{$this->delSuffix($name)}{$this->getSuffix($attname,$name)}";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取存储路径
|
|
||||||
* @param string $name 文件名称
|
|
||||||
* @param boolean $safe 安全模式
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function path(string $name, bool $safe = false): string
|
|
||||||
{
|
|
||||||
return $this->url($name, $safe);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取文件信息
|
|
||||||
* @param string $name 文件名称
|
|
||||||
* @param boolean $safe 安全模式
|
|
||||||
* @param ?string $attname 下载名称
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function info(string $name, bool $safe = false, ?string $attname = null): array
|
|
||||||
{
|
|
||||||
return $this->has($name, $safe) ? [
|
|
||||||
'url' => $this->url($name, $safe, $attname),
|
|
||||||
'key' => $name, 'file' => $this->path($name, $safe),
|
|
||||||
] : [];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取上传地址
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function upload(): string
|
|
||||||
{
|
|
||||||
$proc = $this->app->request->isSsl() ? 'https' : 'http';
|
|
||||||
return "{$proc}://{$this->bucket}.{$this->point}";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取上传令牌
|
|
||||||
* @param string $name 文件名称
|
|
||||||
* @param integer $expires 有效时间
|
|
||||||
* @param ?string $attname 下载名称
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function token(string $name, int $expires = 3600, ?string $attname = null): array
|
|
||||||
{
|
|
||||||
$data = [
|
|
||||||
'policy' => base64_encode(json_encode([
|
|
||||||
'conditions' => [['content-length-range', 0, 1048576000]],
|
|
||||||
'expiration' => date('Y-m-d\TH:i:s.000\Z', time() + $expires),
|
|
||||||
])),
|
|
||||||
'keyid' => $this->accessKey,
|
|
||||||
'siteurl' => $this->url($name, false, $attname),
|
|
||||||
];
|
|
||||||
$data['signature'] = base64_encode(hash_hmac('sha1', $data['policy'], $this->secretKey, true));
|
|
||||||
return $data;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 请求数据签名
|
|
||||||
* @param string $method 请求方式
|
* @param string $method 请求方式
|
||||||
* @param string $soruce 资源名称
|
* @param string $soruce 资源名称
|
||||||
* @return array
|
|
||||||
*/
|
*/
|
||||||
private function _sign(string $method, string $soruce): array
|
private function _sign(string $method, string $soruce): array
|
||||||
{
|
{
|
||||||
@ -241,46 +269,9 @@ class AliossStorage implements StorageInterface
|
|||||||
$content = rawurldecode($content) . "/{$this->bucket}/{$soruce}";
|
$content = rawurldecode($content) . "/{$this->bucket}/{$soruce}";
|
||||||
$signature = base64_encode(hash_hmac('sha1', $content, $this->secretKey, true));
|
$signature = base64_encode(hash_hmac('sha1', $content, $this->secretKey, true));
|
||||||
$header['Authorization'] = "OSS {$this->accessKey}:{$signature}";
|
$header['Authorization'] = "OSS {$this->accessKey}:{$signature}";
|
||||||
foreach ($header as $key => $value) $header[$key] = "{$key}: {$value}";
|
foreach ($header as $key => $value) {
|
||||||
|
$header[$key] = "{$key}: {$value}";
|
||||||
|
}
|
||||||
return array_values($header);
|
return array_values($header);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
/**
|
|
||||||
* 获取存储区域
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public static function region(): array
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
'oss-cn-hangzhou.aliyuncs.com' => lang('华东 1(杭州)'),
|
|
||||||
'oss-cn-shanghai.aliyuncs.com' => lang('华东 2(上海)'),
|
|
||||||
'oss-cn-nanjing.aliyuncs.com' => lang('华东 5(南京本地地域)'),
|
|
||||||
'oss-cn-fuzhou.aliyuncs.com' => lang('华东 6(福州本地地域)'),
|
|
||||||
'oss-cn-qingdao.aliyuncs.com' => lang('华北 1(青岛)'),
|
|
||||||
'oss-cn-beijing.aliyuncs.com' => lang('华北 2(北京)'),
|
|
||||||
'oss-cn-zhangjiakou.aliyuncs.com' => lang('华北 3(张家口)'),
|
|
||||||
'oss-cn-huhehaote.aliyuncs.com' => lang('华北 5(呼和浩特)'),
|
|
||||||
'oss-cn-wulanchabu.aliyuncs.com' => lang('华北 6(乌兰察布)'),
|
|
||||||
'oss-cn-shenzhen.aliyuncs.com' => lang('华南 1(深圳)'),
|
|
||||||
'oss-cn-heyuan.aliyuncs.com' => lang('华南 2(河源)'),
|
|
||||||
'oss-cn-guangzhou.aliyuncs.com' => lang('华南 3(广州)'),
|
|
||||||
'oss-cn-chengdu.aliyuncs.com' => lang('西南 1(成都)'),
|
|
||||||
'oss-cn-hongkong.aliyuncs.com' => lang('中国(香港)'),
|
|
||||||
'oss-us-west-1.aliyuncs.com' => lang('美国(硅谷)'),
|
|
||||||
'oss-us-east-1.aliyuncs.com' => lang('美国(弗吉尼亚)'),
|
|
||||||
'oss-ap-northeast-1.aliyuncs.com' => lang('日本(东京)'),
|
|
||||||
'oss-ap-northeast-2.aliyuncs.com' => lang('韩国(首尔)'),
|
|
||||||
'oss-ap-southeast-1.aliyuncs.com' => lang('新加坡'),
|
|
||||||
'oss-ap-southeast-2.aliyuncs.com' => lang('澳大利亚(悉尼)'),
|
|
||||||
'oss-ap-southeast-3.aliyuncs.com' => lang('马来西亚(吉隆坡)'),
|
|
||||||
'oss-ap-southeast-5.aliyuncs.com' => lang('印度尼西亚(雅加达)'),
|
|
||||||
'oss-ap-southeast-6.aliyuncs.com' => lang('菲律宾(马尼拉)'),
|
|
||||||
'oss-ap-southeast-7.aliyuncs.com' => lang('泰国(曼谷)'),
|
|
||||||
'oss-ap-south-1.aliyuncs.com' => lang('印度(孟买)'),
|
|
||||||
'oss-eu-central-1.aliyuncs.com' => lang('德国(法兰克福)'),
|
|
||||||
'oss-eu-west-1.aliyuncs.com' => lang('英国(伦敦)'),
|
|
||||||
'oss-me-east-1.aliyuncs.com' => lang('阿联酋(迪拜)'),
|
|
||||||
'oss-rg-china-mainland.aliyuncs.com' => lang('无地域属性(中国内地)')
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@ -1,20 +1,22 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// +----------------------------------------------------------------------
|
declare(strict_types=1);
|
||||||
// | Library for ThinkAdmin
|
/**
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 版权所有 2014~2025 ThinkAdmin [ thinkadmin.top ]
|
* | Payment Plugin for ThinkAdmin
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 官方网站: https://thinkadmin.top
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 开源协议 ( https://mit-license.org )
|
* | 官方网站: https://thinkadmin.top
|
||||||
// | 免费声明 ( https://thinkadmin.top/disclaimer )
|
* +----------------------------------------------------------------------
|
||||||
// +----------------------------------------------------------------------
|
* | 开源协议 ( https://mit-license.org )
|
||||||
// | gitee 仓库地址 :https://gitee.com/zoujingli/ThinkLibrary
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
// | github 仓库地址 :https://github.com/zoujingli/ThinkLibrary
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
declare (strict_types=1);
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
namespace think\admin\storage;
|
namespace think\admin\storage;
|
||||||
|
|
||||||
@ -27,14 +29,13 @@ use think\admin\Storage;
|
|||||||
/**
|
/**
|
||||||
* Alist 自建存储支持
|
* Alist 自建存储支持
|
||||||
* @class AlistStorage
|
* @class AlistStorage
|
||||||
* @package think\admin\storage
|
|
||||||
*/
|
*/
|
||||||
class AlistStorage implements StorageInterface
|
class AlistStorage implements StorageInterface
|
||||||
{
|
{
|
||||||
use StorageUsageTrait;
|
use StorageUsageTrait;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用户账号
|
* 用户账号.
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
protected $username;
|
protected $username;
|
||||||
@ -46,7 +47,7 @@ class AlistStorage implements StorageInterface
|
|||||||
protected $password;
|
protected $password;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 保存路径
|
* 保存路径.
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
protected $savepath;
|
protected $savepath;
|
||||||
@ -58,57 +59,31 @@ class AlistStorage implements StorageInterface
|
|||||||
protected $cachekey;
|
protected $cachekey;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 存储引擎初始化
|
* 上传文件内容.
|
||||||
* @return void
|
|
||||||
* @throws \think\admin\Exception
|
|
||||||
*/
|
|
||||||
protected function init()
|
|
||||||
{
|
|
||||||
$host = strtolower(sysconf('storage.alist_http_domain|raw'));
|
|
||||||
$type = strtolower(sysconf('storage.alist_http_protocol|raw'));
|
|
||||||
if (!empty($host) && $type === 'auto') {
|
|
||||||
$this->domain = "//{$host}";
|
|
||||||
} elseif (!empty($host) && in_array($type, ['http', 'https'])) {
|
|
||||||
$this->domain = "{$type}://{$host}";
|
|
||||||
} else {
|
|
||||||
throw new Exception(lang('未配置Alist域名'));
|
|
||||||
}
|
|
||||||
$this->username = sysconf('storage.alist_username|raw') ?: '';
|
|
||||||
$this->password = sysconf('storage.alist_password|raw') ?: '';
|
|
||||||
$this->savepath = trim(sysconf('storage.alist_savepath|raw') ?: '', '\\/');
|
|
||||||
$this->savepath = $this->savepath ? "{$this->savepath}/" : '';
|
|
||||||
$this->cachekey = md5($this->domain . $this->username . $this->password);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 上传文件内容
|
|
||||||
* @param string $name 文件名称
|
* @param string $name 文件名称
|
||||||
* @param string $file 文件内容
|
* @param string $file 文件内容
|
||||||
* @param boolean $safe 安全模式
|
* @param bool $safe 安全模式
|
||||||
* @param ?string $attname 下载名称
|
* @param ?string $attname 下载名称
|
||||||
* @return array
|
* @throws Exception
|
||||||
* @throws \think\admin\Exception
|
|
||||||
*/
|
*/
|
||||||
public function set(string $name, string $file, bool $safe = false, ?string $attname = null): array
|
public function set(string $name, string $file, bool $safe = false, ?string $attname = null): array
|
||||||
{
|
{
|
||||||
$file = ['field' => 'file', 'name' => $name, 'content' => $file];
|
$file = ['field' => 'file', 'name' => $name, 'content' => $file];
|
||||||
$header = ["Authorization: {$this->token()}", "file-path:" . urlencode($this->real($name))];
|
$header = ["Authorization: {$this->token()}", 'file-path:' . urlencode($this->real($name))];
|
||||||
$result = HttpExtend::submit("{$this->domain}/api/fs/form", [], $file, $header, 'PUT', false);
|
$result = HttpExtend::submit("{$this->domain}/api/fs/form", [], $file, $header, 'PUT', false);
|
||||||
if (is_array($data = json_decode($result, true))) {
|
if (is_array($data = json_decode($result, true))) {
|
||||||
if ($data['code'] === 200 && $data['message'] === 'success') {
|
if ($data['code'] === 200 && $data['message'] === 'success') {
|
||||||
return $this->info($name, $safe);
|
return $this->info($name, $safe);
|
||||||
} else {
|
|
||||||
throw new Exception($data['message'] ?? '接口请求失败!', intval($data['code'] ?? 0));
|
|
||||||
}
|
}
|
||||||
|
throw new Exception($data['message'] ?? '接口请求失败!', intval($data['code'] ?? 0));
|
||||||
}
|
}
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 读取文件内容
|
* 读取文件内容.
|
||||||
* @param string $name 文件名称
|
* @param string $name 文件名称
|
||||||
* @param boolean $safe 安全模式
|
* @param bool $safe 安全模式
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public function get(string $name, bool $safe = false): string
|
public function get(string $name, bool $safe = false): string
|
||||||
{
|
{
|
||||||
@ -116,10 +91,9 @@ class AlistStorage implements StorageInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 删除存储文件
|
* 删除存储文件.
|
||||||
* @param string $name 文件名称
|
* @param string $name 文件名称
|
||||||
* @param boolean $safe 安全模式
|
* @param bool $safe 安全模式
|
||||||
* @return boolean
|
|
||||||
*/
|
*/
|
||||||
public function del(string $name, bool $safe = false): bool
|
public function del(string $name, bool $safe = false): bool
|
||||||
{
|
{
|
||||||
@ -134,16 +108,15 @@ class AlistStorage implements StorageInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 判断是否存在
|
* 判断是否存在.
|
||||||
* @param string $name 文件名称
|
* @param string $name 文件名称
|
||||||
* @param boolean $safe 安全模式
|
* @param bool $safe 安全模式
|
||||||
* @return boolean
|
|
||||||
*/
|
*/
|
||||||
public function has(string $name, bool $safe = false): bool
|
public function has(string $name, bool $safe = false): bool
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$this->httpPost('/api/fs/get', [
|
$this->httpPost('/api/fs/get', [
|
||||||
'path' => $this->real($name)
|
'path' => $this->real($name),
|
||||||
]);
|
]);
|
||||||
return true;
|
return true;
|
||||||
} catch (\Exception $exception) {
|
} catch (\Exception $exception) {
|
||||||
@ -152,23 +125,18 @@ class AlistStorage implements StorageInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取文件下载链接
|
* 获取文件下载链接.
|
||||||
* @param string $name
|
|
||||||
* @param bool $safe
|
|
||||||
* @param string|null $attname
|
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public function url(string $name, bool $safe = false, ?string $attname = null): string
|
public function url(string $name, bool $safe = false, ?string $attname = null): string
|
||||||
{
|
{
|
||||||
$path = rtrim($this->userPath(), '\\/') . $this->real($name);
|
$path = rtrim($this->userPath(), '\/') . $this->real($name);
|
||||||
return "{$this->domain}/d{$this->delSuffix($path)}{$this->getSuffix($attname,$path)}";
|
return "{$this->domain}/d{$this->delSuffix($path)}{$this->getSuffix($attname, $path)}";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取存储路径
|
* 获取存储路径.
|
||||||
* @param string $name 文件名称
|
* @param string $name 文件名称
|
||||||
* @param boolean $safe 安全模式
|
* @param bool $safe 安全模式
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public function path(string $name, bool $safe = false): string
|
public function path(string $name, bool $safe = false): string
|
||||||
{
|
{
|
||||||
@ -176,24 +144,22 @@ class AlistStorage implements StorageInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取文件信息
|
* 获取文件信息.
|
||||||
* @param string $name 文件名称
|
* @param string $name 文件名称
|
||||||
* @param boolean $safe 安全模式
|
* @param bool $safe 安全模式
|
||||||
* @param ?string $attname 下载名称
|
* @param ?string $attname 下载名称
|
||||||
* @return array
|
|
||||||
*/
|
*/
|
||||||
public function info(string $name, bool $safe = false, ?string $attname = null): array
|
public function info(string $name, bool $safe = false, ?string $attname = null): array
|
||||||
{
|
{
|
||||||
return $this->has($name, $safe) ? [
|
return $this->has($name, $safe) ? [
|
||||||
'key' => $name,
|
'key' => $name,
|
||||||
'url' => $this->url($name, $safe, $attname),
|
'url' => $this->url($name, $safe, $attname),
|
||||||
'file' => $this->path($name, $safe),
|
'file' => $this->path($name, $safe),
|
||||||
] : [];
|
] : [];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取上传地址
|
* 获取上传地址
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public function upload(): string
|
public function upload(): string
|
||||||
{
|
{
|
||||||
@ -202,7 +168,6 @@ class AlistStorage implements StorageInterface
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取存储区域
|
* 获取存储区域
|
||||||
* @return array
|
|
||||||
*/
|
*/
|
||||||
public static function region(): array
|
public static function region(): array
|
||||||
{
|
{
|
||||||
@ -210,15 +175,66 @@ class AlistStorage implements StorageInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建目录
|
* 转换为绝对路径.
|
||||||
* @param string $path
|
*/
|
||||||
* @return boolean
|
public function real(string $path): string
|
||||||
|
{
|
||||||
|
return "/{$this->savepath}" . trim($path, '\/');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取用户 Token 信息.
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public function token(bool $force = false): string
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$skey = "{$this->cachekey}.token";
|
||||||
|
if (empty($force) && ($token = $this->app->cache->get($skey))) {
|
||||||
|
return $token;
|
||||||
|
}
|
||||||
|
$data = ['Password' => $this->password, 'Username' => $this->username];
|
||||||
|
$body = $this->httpPost('/api/auth/login', $data, false);
|
||||||
|
if (!empty($body['data']['token'])) {
|
||||||
|
$this->app->cache->set($skey, $body['data']['token'], 60);
|
||||||
|
return $body['data']['token'];
|
||||||
|
}
|
||||||
|
throw new Exception('获取用户 Token 失败!');
|
||||||
|
} catch (\Exception $exception) {
|
||||||
|
throw new Exception($exception->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 存储引擎初始化.
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
protected function init()
|
||||||
|
{
|
||||||
|
$host = strtolower(sysconf('storage.alist_http_domain|raw'));
|
||||||
|
$type = strtolower(sysconf('storage.alist_http_protocol|raw'));
|
||||||
|
if (!empty($host) && $type === 'auto') {
|
||||||
|
$this->domain = "//{$host}";
|
||||||
|
} elseif (!empty($host) && in_array($type, ['http', 'https'])) {
|
||||||
|
$this->domain = "{$type}://{$host}";
|
||||||
|
} else {
|
||||||
|
throw new Exception(lang('未配置Alist域名'));
|
||||||
|
}
|
||||||
|
$this->username = sysconf('storage.alist_username|raw') ?: '';
|
||||||
|
$this->password = sysconf('storage.alist_password|raw') ?: '';
|
||||||
|
$this->savepath = trim(sysconf('storage.alist_savepath|raw') ?: '', '\/');
|
||||||
|
$this->savepath = $this->savepath ? "{$this->savepath}/" : '';
|
||||||
|
$this->cachekey = md5($this->domain . $this->username . $this->password);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建目录.
|
||||||
*/
|
*/
|
||||||
protected function mkdir(string $path): bool
|
protected function mkdir(string $path): bool
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$this->httpPost('/api/fs/mkdir', [
|
$this->httpPost('/api/fs/mkdir', [
|
||||||
'path' => $this->real($path)
|
'path' => $this->real($path),
|
||||||
]);
|
]);
|
||||||
return true;
|
return true;
|
||||||
} catch (\Exception $exception) {
|
} catch (\Exception $exception) {
|
||||||
@ -227,51 +243,20 @@ class AlistStorage implements StorageInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 转换为绝对路径
|
* 获取基础路径.
|
||||||
* @param string $path
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function real(string $path): string
|
|
||||||
{
|
|
||||||
return "/{$this->savepath}" . trim($path, '\\/');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取用户 Token 信息
|
|
||||||
* @param boolean $force
|
|
||||||
* @return string
|
|
||||||
* @throws \think\admin\Exception
|
|
||||||
*/
|
|
||||||
public function token(bool $force = false): string
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
$skey = "{$this->cachekey}.token";
|
|
||||||
if (empty($force) && ($token = $this->app->cache->get($skey))) return $token;
|
|
||||||
$data = ['Password' => $this->password, 'Username' => $this->username];
|
|
||||||
$body = $this->httpPost("/api/auth/login", $data, false);
|
|
||||||
if (!empty($body['data']['token'])) {
|
|
||||||
$this->app->cache->set($skey, $body['data']['token'], 60);
|
|
||||||
return $body['data']['token'];
|
|
||||||
} else {
|
|
||||||
throw new Exception('获取用户 Token 失败!');
|
|
||||||
}
|
|
||||||
} catch (\Exception $exception) {
|
|
||||||
throw new Exception($exception->getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取基础路径
|
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
private function userPath(): string
|
private function userPath(): string
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$skey = "{$this->cachekey}.path";
|
$skey = "{$this->cachekey}.path";
|
||||||
if ($path = $this->app->cache->get($skey)) return $path;
|
if ($path = $this->app->cache->get($skey)) {
|
||||||
|
return $path;
|
||||||
|
}
|
||||||
$data = $this->httGet('/api/me');
|
$data = $this->httGet('/api/me');
|
||||||
if (empty($data['data']['base_path'])) return '/';
|
if (empty($data['data']['base_path'])) {
|
||||||
$path = trim($data['data']['base_path'], '\\/');
|
return '/';
|
||||||
|
}
|
||||||
|
$path = trim($data['data']['base_path'], '\/');
|
||||||
$this->app->cache->set($skey, $path = $path ? "/{$path}/" : '/', 60);
|
$this->app->cache->set($skey, $path = $path ? "/{$path}/" : '/', 60);
|
||||||
return $path;
|
return $path;
|
||||||
} catch (\Exception $exception) {
|
} catch (\Exception $exception) {
|
||||||
@ -280,43 +265,39 @@ class AlistStorage implements StorageInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get 提交数据
|
* Get 提交数据.
|
||||||
* @param string $uri
|
* @throws Exception
|
||||||
* @return array
|
|
||||||
* @throws \think\admin\Exception
|
|
||||||
*/
|
*/
|
||||||
private function httGet(string $uri): array
|
private function httGet(string $uri): array
|
||||||
{
|
{
|
||||||
$header = ["Authorization: {$this->token()}"];
|
$header = ["Authorization: {$this->token()}"];
|
||||||
$header[] = "Content-Type: application/json;charset=UTF-8";
|
$header[] = 'Content-Type: application/json;charset=UTF-8';
|
||||||
$result = HttpExtend::get($this->domain . $uri, [], ['headers' => $header]);
|
$result = HttpExtend::get($this->domain . $uri, [], ['headers' => $header]);
|
||||||
if (is_array($data = json_decode($result, true))) {
|
if (is_array($data = json_decode($result, true))) {
|
||||||
if ($data['code'] === 200 && $data['message'] === 'success') return $data;
|
if ($data['code'] === 200 && $data['message'] === 'success') {
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
throw new Exception($data['message'] ?? '接口请求失败!', intval($data['code'] ?? 0));
|
throw new Exception($data['message'] ?? '接口请求失败!', intval($data['code'] ?? 0));
|
||||||
} else {
|
|
||||||
throw new Exception('接口请求失败!');
|
|
||||||
}
|
}
|
||||||
|
throw new Exception('接口请求失败!');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* POST 提交数据
|
* POST 提交数据.
|
||||||
* @param string $uri
|
* @throws Exception
|
||||||
* @param array $body
|
|
||||||
* @param boolean $auth
|
|
||||||
* @return array
|
|
||||||
* @throws \think\admin\Exception
|
|
||||||
*/
|
*/
|
||||||
private function httpPost(string $uri, array $body = [], bool $auth = true): array
|
private function httpPost(string $uri, array $body = [], bool $auth = true): array
|
||||||
{
|
{
|
||||||
$body = json_encode($body, JSON_UNESCAPED_UNICODE);
|
$body = json_encode($body, JSON_UNESCAPED_UNICODE);
|
||||||
$header = $auth ? ["Authorization: {$this->token()}"] : [];
|
$header = $auth ? ["Authorization: {$this->token()}"] : [];
|
||||||
$header[] = "Content-Type: application/json;charset=UTF-8";
|
$header[] = 'Content-Type: application/json;charset=UTF-8';
|
||||||
$result = HttpExtend::post($this->domain . $uri, $body, ['headers' => $header]);
|
$result = HttpExtend::post($this->domain . $uri, $body, ['headers' => $header]);
|
||||||
if (is_array($data = json_decode($result, true))) {
|
if (is_array($data = json_decode($result, true))) {
|
||||||
if ($data['code'] === 200 && $data['message'] === 'success') return $data;
|
if ($data['code'] === 200 && $data['message'] === 'success') {
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
throw new Exception($data['message'] ?? '接口请求失败!', intval($data['code'] ?? 0));
|
throw new Exception($data['message'] ?? '接口请求失败!', intval($data['code'] ?? 0));
|
||||||
} else {
|
|
||||||
throw new Exception('接口请求失败!');
|
|
||||||
}
|
}
|
||||||
|
throw new Exception('接口请求失败!');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,20 +1,22 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// +----------------------------------------------------------------------
|
declare(strict_types=1);
|
||||||
// | Library for ThinkAdmin
|
/**
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 版权所有 2014~2025 ThinkAdmin [ thinkadmin.top ]
|
* | Payment Plugin for ThinkAdmin
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 官方网站: https://thinkadmin.top
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 开源协议 ( https://mit-license.org )
|
* | 官方网站: https://thinkadmin.top
|
||||||
// | 免费声明 ( https://thinkadmin.top/disclaimer )
|
* +----------------------------------------------------------------------
|
||||||
// +----------------------------------------------------------------------
|
* | 开源协议 ( https://mit-license.org )
|
||||||
// | gitee 仓库地址 :https://gitee.com/zoujingli/ThinkLibrary
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
// | github 仓库地址 :https://github.com/zoujingli/ThinkLibrary
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
declare (strict_types=1);
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
namespace think\admin\storage;
|
namespace think\admin\storage;
|
||||||
|
|
||||||
@ -24,38 +26,17 @@ use think\admin\contract\StorageUsageTrait;
|
|||||||
/**
|
/**
|
||||||
* 本地存储支持
|
* 本地存储支持
|
||||||
* @class LocalStorage
|
* @class LocalStorage
|
||||||
* @package think\admin\storage
|
|
||||||
*/
|
*/
|
||||||
class LocalStorage implements StorageInterface
|
class LocalStorage implements StorageInterface
|
||||||
{
|
{
|
||||||
use StorageUsageTrait;
|
use StorageUsageTrait;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 初始化入口
|
* 上传文件内容.
|
||||||
* @throws \think\admin\Exception
|
|
||||||
*/
|
|
||||||
protected function init()
|
|
||||||
{
|
|
||||||
$type = sysconf('storage.local_http_protocol|raw') ?: 'follow';
|
|
||||||
if ($type === 'follow') $type = $this->app->request->scheme();
|
|
||||||
$this->domain = trim(dirname($this->app->request->baseFile()), '\\/');
|
|
||||||
if ($type !== 'path') {
|
|
||||||
$domain = sysconf('storage.local_http_domain|raw') ?: $this->app->request->host();
|
|
||||||
if ($type === 'auto') {
|
|
||||||
$this->domain = "//{$domain}";
|
|
||||||
} elseif (in_array($type, ['http', 'https'])) {
|
|
||||||
$this->domain = "{$type}://{$domain}";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 上传文件内容
|
|
||||||
* @param string $name 文件名称
|
* @param string $name 文件名称
|
||||||
* @param string $file 文件内容
|
* @param string $file 文件内容
|
||||||
* @param boolean $safe 安全模式
|
* @param bool $safe 安全模式
|
||||||
* @param ?string $attname 下载名称
|
* @param ?string $attname 下载名称
|
||||||
* @return array
|
|
||||||
*/
|
*/
|
||||||
public function set(string $name, string $file, bool $safe = false, ?string $attname = null): array
|
public function set(string $name, string $file, bool $safe = false, ?string $attname = null): array
|
||||||
{
|
{
|
||||||
@ -71,37 +52,35 @@ class LocalStorage implements StorageInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 读取文件内容
|
* 读取文件内容.
|
||||||
* @param string $name 文件名称
|
* @param string $name 文件名称
|
||||||
* @param boolean $safe 安全模式
|
* @param bool $safe 安全模式
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public function get(string $name, bool $safe = false): string
|
public function get(string $name, bool $safe = false): string
|
||||||
{
|
{
|
||||||
if (!$this->has($name, $safe)) return '';
|
if (!$this->has($name, $safe)) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
return file_get_contents($this->path($name, $safe));
|
return file_get_contents($this->path($name, $safe));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 删除存储文件
|
* 删除存储文件.
|
||||||
* @param string $name 文件名称
|
* @param string $name 文件名称
|
||||||
* @param boolean $safe 安全模式
|
* @param bool $safe 安全模式
|
||||||
* @return boolean
|
|
||||||
*/
|
*/
|
||||||
public function del(string $name, bool $safe = false): bool
|
public function del(string $name, bool $safe = false): bool
|
||||||
{
|
{
|
||||||
if ($this->has($name, $safe)) {
|
if ($this->has($name, $safe)) {
|
||||||
return @unlink($this->path($name, $safe));
|
return @unlink($this->path($name, $safe));
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 判断是否存在
|
* 判断是否存在.
|
||||||
* @param string $name 文件名称
|
* @param string $name 文件名称
|
||||||
* @param boolean $safe 安全模式
|
* @param bool $safe 安全模式
|
||||||
* @return boolean
|
|
||||||
*/
|
*/
|
||||||
public function has(string $name, bool $safe = false): bool
|
public function has(string $name, bool $safe = false): bool
|
||||||
{
|
{
|
||||||
@ -111,20 +90,18 @@ class LocalStorage implements StorageInterface
|
|||||||
/**
|
/**
|
||||||
* 获取访问地址
|
* 获取访问地址
|
||||||
* @param string $name 文件名称
|
* @param string $name 文件名称
|
||||||
* @param boolean $safe 安全模式
|
* @param bool $safe 安全模式
|
||||||
* @param ?string $attname 下载名称
|
* @param ?string $attname 下载名称
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public function url(string $name, bool $safe = false, ?string $attname = null): string
|
public function url(string $name, bool $safe = false, ?string $attname = null): string
|
||||||
{
|
{
|
||||||
return $safe ? $name : "{$this->domain}/upload/{$this->delSuffix($name)}{$this->getSuffix($attname,$name)}";
|
return $safe ? $name : "{$this->domain}/upload/{$this->delSuffix($name)}{$this->getSuffix($attname, $name)}";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取存储路径
|
* 获取存储路径.
|
||||||
* @param string $name 文件名称
|
* @param string $name 文件名称
|
||||||
* @param boolean $safe 安全模式
|
* @param bool $safe 安全模式
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public function path(string $name, bool $safe = false): string
|
public function path(string $name, bool $safe = false): string
|
||||||
{
|
{
|
||||||
@ -133,11 +110,10 @@ class LocalStorage implements StorageInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取文件信息
|
* 获取文件信息.
|
||||||
* @param string $name 文件名称
|
* @param string $name 文件名称
|
||||||
* @param boolean $safe 安全模式
|
* @param bool $safe 安全模式
|
||||||
* @param ?string $attname 下载名称
|
* @param ?string $attname 下载名称
|
||||||
* @return array
|
|
||||||
*/
|
*/
|
||||||
public function info(string $name, bool $safe = false, ?string $attname = null): array
|
public function info(string $name, bool $safe = false, ?string $attname = null): array
|
||||||
{
|
{
|
||||||
@ -149,7 +125,6 @@ class LocalStorage implements StorageInterface
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取上传地址
|
* 获取上传地址
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public function upload(): string
|
public function upload(): string
|
||||||
{
|
{
|
||||||
@ -158,10 +133,30 @@ class LocalStorage implements StorageInterface
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取存储区域
|
* 获取存储区域
|
||||||
* @return array
|
|
||||||
*/
|
*/
|
||||||
public static function region(): array
|
public static function region(): array
|
||||||
{
|
{
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
/**
|
||||||
|
* 初始化入口.
|
||||||
|
* @throws \think\admin\Exception
|
||||||
|
*/
|
||||||
|
protected function init()
|
||||||
|
{
|
||||||
|
$type = sysconf('storage.local_http_protocol|raw') ?: 'follow';
|
||||||
|
if ($type === 'follow') {
|
||||||
|
$type = $this->app->request->scheme();
|
||||||
|
}
|
||||||
|
$this->domain = trim(dirname($this->app->request->baseFile()), '\/');
|
||||||
|
if ($type !== 'path') {
|
||||||
|
$domain = sysconf('storage.local_http_domain|raw') ?: $this->app->request->host();
|
||||||
|
if ($type === 'auto') {
|
||||||
|
$this->domain = "//{$domain}";
|
||||||
|
} elseif (in_array($type, ['http', 'https'])) {
|
||||||
|
$this->domain = "{$type}://{$domain}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -1,20 +1,22 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// +----------------------------------------------------------------------
|
declare(strict_types=1);
|
||||||
// | Library for ThinkAdmin
|
/**
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 版权所有 2014~2025 ThinkAdmin [ thinkadmin.top ]
|
* | Payment Plugin for ThinkAdmin
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 官方网站: https://thinkadmin.top
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 开源协议 ( https://mit-license.org )
|
* | 官方网站: https://thinkadmin.top
|
||||||
// | 免费声明 ( https://thinkadmin.top/disclaimer )
|
* +----------------------------------------------------------------------
|
||||||
// +----------------------------------------------------------------------
|
* | 开源协议 ( https://mit-license.org )
|
||||||
// | gitee 仓库地址 :https://gitee.com/zoujingli/ThinkLibrary
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
// | github 仓库地址 :https://github.com/zoujingli/ThinkLibrary
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
declare (strict_types=1);
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
namespace think\admin\storage;
|
namespace think\admin\storage;
|
||||||
|
|
||||||
@ -27,74 +29,50 @@ use think\admin\Storage;
|
|||||||
/**
|
/**
|
||||||
* 七牛云存储支持
|
* 七牛云存储支持
|
||||||
* @class QiniuStorage
|
* @class QiniuStorage
|
||||||
* @package think\admin\storage
|
|
||||||
*/
|
*/
|
||||||
class QiniuStorage implements StorageInterface
|
class QiniuStorage implements StorageInterface
|
||||||
{
|
{
|
||||||
use StorageUsageTrait;
|
use StorageUsageTrait;
|
||||||
|
|
||||||
private $bucket;
|
private $bucket;
|
||||||
|
|
||||||
private $accessKey;
|
private $accessKey;
|
||||||
|
|
||||||
private $secretKey;
|
private $secretKey;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 初始化入口
|
* 上传文件内容.
|
||||||
* @throws \think\admin\Exception
|
|
||||||
*/
|
|
||||||
protected function init()
|
|
||||||
{
|
|
||||||
// 读取配置文件
|
|
||||||
$this->bucket = sysconf('storage.qiniu_bucket|raw');
|
|
||||||
$this->accessKey = sysconf('storage.qiniu_access_key|raw');
|
|
||||||
$this->secretKey = sysconf('storage.qiniu_secret_key|raw');
|
|
||||||
// 计算链接前缀
|
|
||||||
$host = strtolower(sysconf('storage.qiniu_http_domain|raw'));
|
|
||||||
$type = strtolower(sysconf('storage.qiniu_http_protocol|raw'));
|
|
||||||
if ($type === 'auto') {
|
|
||||||
$this->domain = "//{$host}";
|
|
||||||
} elseif (in_array($type, ['http', 'https'])) {
|
|
||||||
$this->domain = "{$type}://{$host}";
|
|
||||||
} else {
|
|
||||||
throw new Exception(lang('未配置七牛云域名'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 上传文件内容
|
|
||||||
* @param string $name 文件名称
|
* @param string $name 文件名称
|
||||||
* @param string $file 文件内容
|
* @param string $file 文件内容
|
||||||
* @param boolean $safe 安全模式
|
* @param bool $safe 安全模式
|
||||||
* @param ?string $attname 下载名称
|
* @param ?string $attname 下载名称
|
||||||
* @return array
|
* @throws Exception
|
||||||
* @throws \think\admin\Exception
|
|
||||||
*/
|
*/
|
||||||
public function set(string $name, string $file, bool $safe = false, ?string $attname = null): array
|
public function set(string $name, string $file, bool $safe = false, ?string $attname = null): array
|
||||||
{
|
{
|
||||||
$token = $this->token($name, 3600, $attname);
|
$token = $this->token($name, 3600, $attname);
|
||||||
$data = ['key' => $name, 'token' => $token, 'fileName' => $name];
|
$data = ['key' => $name, 'token' => $token, 'fileName' => $name];
|
||||||
$file = ['field' => "file", 'name' => $name, 'content' => $file];
|
$file = ['field' => 'file', 'name' => $name, 'content' => $file];
|
||||||
$result = HttpExtend::submit($this->upload(), $data, $file, [], 'POST', false);
|
$result = HttpExtend::submit($this->upload(), $data, $file, [], 'POST', false);
|
||||||
return json_decode($result, true);
|
return json_decode($result, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 读取文件内容
|
* 读取文件内容.
|
||||||
* @param string $name 文件名称
|
* @param string $name 文件名称
|
||||||
* @param boolean $safe 安全模式
|
* @param bool $safe 安全模式
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public function get(string $name, bool $safe = false): string
|
public function get(string $name, bool $safe = false): string
|
||||||
{
|
{
|
||||||
$url = $this->url($name, $safe) . "?e=" . time();
|
$url = $this->url($name, $safe) . '?e=' . time();
|
||||||
$token = "{$this->accessKey}:{$this->safeBase64(hash_hmac('sha1', $url, $this->secretKey, true))}";
|
$token = "{$this->accessKey}:{$this->safeBase64(hash_hmac('sha1', $url, $this->secretKey, true))}";
|
||||||
return Storage::curlGet("{$url}&token={$token}");
|
return Storage::curlGet("{$url}&token={$token}");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 删除存储文件
|
* 删除存储文件.
|
||||||
* @param string $name 文件名称
|
* @param string $name 文件名称
|
||||||
* @param boolean $safe 安全模式
|
* @param bool $safe 安全模式
|
||||||
* @return boolean
|
|
||||||
*/
|
*/
|
||||||
public function del(string $name, bool $safe = false): bool
|
public function del(string $name, bool $safe = false): bool
|
||||||
{
|
{
|
||||||
@ -106,10 +84,9 @@ class QiniuStorage implements StorageInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 判断是否存在
|
* 判断是否存在.
|
||||||
* @param string $name 文件名称
|
* @param string $name 文件名称
|
||||||
* @param boolean $safe 安全模式
|
* @param bool $safe 安全模式
|
||||||
* @return boolean
|
|
||||||
*/
|
*/
|
||||||
public function has(string $name, bool $safe = false): bool
|
public function has(string $name, bool $safe = false): bool
|
||||||
{
|
{
|
||||||
@ -119,20 +96,18 @@ class QiniuStorage implements StorageInterface
|
|||||||
/**
|
/**
|
||||||
* 获取访问地址
|
* 获取访问地址
|
||||||
* @param string $name 文件名称
|
* @param string $name 文件名称
|
||||||
* @param boolean $safe 安全模式
|
* @param bool $safe 安全模式
|
||||||
* @param ?string $attname 下载名称
|
* @param ?string $attname 下载名称
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public function url(string $name, bool $safe = false, ?string $attname = null): string
|
public function url(string $name, bool $safe = false, ?string $attname = null): string
|
||||||
{
|
{
|
||||||
return "{$this->domain}/{$this->delSuffix($name)}{$this->getSuffix($attname,$name)}";
|
return "{$this->domain}/{$this->delSuffix($name)}{$this->getSuffix($attname, $name)}";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取存储路径
|
* 获取存储路径.
|
||||||
* @param string $name 文件名称
|
* @param string $name 文件名称
|
||||||
* @param boolean $safe 安全模式
|
* @param bool $safe 安全模式
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public function path(string $name, bool $safe = false): string
|
public function path(string $name, bool $safe = false): string
|
||||||
{
|
{
|
||||||
@ -140,11 +115,10 @@ class QiniuStorage implements StorageInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取文件信息
|
* 获取文件信息.
|
||||||
* @param string $name 文件名称
|
* @param string $name 文件名称
|
||||||
* @param boolean $safe 安全模式
|
* @param bool $safe 安全模式
|
||||||
* @param ?string $attname 下载名称
|
* @param ?string $attname 下载名称
|
||||||
* @return array
|
|
||||||
*/
|
*/
|
||||||
public function info(string $name, bool $safe = false, ?string $attname = null): array
|
public function info(string $name, bool $safe = false, ?string $attname = null): array
|
||||||
{
|
{
|
||||||
@ -155,8 +129,7 @@ class QiniuStorage implements StorageInterface
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取上传地址
|
* 获取上传地址
|
||||||
* @return string
|
* @throws Exception
|
||||||
* @throws \think\admin\Exception
|
|
||||||
*/
|
*/
|
||||||
public function upload(): string
|
public function upload(): string
|
||||||
{
|
{
|
||||||
@ -193,27 +166,62 @@ class QiniuStorage implements StorageInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 生成上传令牌
|
* 生成上传令牌.
|
||||||
* @param ?string $name 文件名称
|
* @param ?string $name 文件名称
|
||||||
* @param integer $expires 有效时间
|
* @param int $expires 有效时间
|
||||||
* @param ?string $attname 下载名称
|
* @param ?string $attname 下载名称
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public function token(?string $name = null, int $expires = 3600, ?string $attname = null): string
|
public function token(?string $name = null, int $expires = 3600, ?string $attname = null): string
|
||||||
{
|
{
|
||||||
$key = is_null($name) ? '$(key)' : $name;
|
$key = is_null($name) ? '$(key)' : $name;
|
||||||
$url = "{$this->domain}/$(key){$this->getSuffix($attname,$name)}";
|
$url = "{$this->domain}/$(key){$this->getSuffix($attname, $name)}";
|
||||||
$policy = $this->safeBase64(json_encode([
|
$policy = $this->safeBase64(json_encode([
|
||||||
"deadline" => time() + $expires, "scope" => is_null($name) ? $this->bucket : "{$this->bucket}:{$name}",
|
'deadline' => time() + $expires, 'scope' => is_null($name) ? $this->bucket : "{$this->bucket}:{$name}",
|
||||||
'returnBody' => json_encode(['uploaded' => true, 'filename' => '$(key)', 'url' => $url, 'key' => $key, 'file' => $key], JSON_UNESCAPED_UNICODE),
|
'returnBody' => json_encode(['uploaded' => true, 'filename' => '$(key)', 'url' => $url, 'key' => $key, 'file' => $key], JSON_UNESCAPED_UNICODE),
|
||||||
]));
|
]));
|
||||||
return "{$this->accessKey}:{$this->safeBase64(hash_hmac('sha1', $policy, $this->secretKey, true))}:{$policy}";
|
return "{$this->accessKey}:{$this->safeBase64(hash_hmac('sha1', $policy, $this->secretKey, true))}:{$policy}";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取存储区域
|
||||||
|
*/
|
||||||
|
public static function region(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'up.qiniup.com' => lang('华东-浙江'),
|
||||||
|
'up-cn-east-2.qiniup.com' => lang('华东-浙江2'),
|
||||||
|
'up-z1.qiniup.com' => lang('华北-河北'),
|
||||||
|
'up-z2.qiniup.com' => lang('华南-广东'),
|
||||||
|
'up-na0.qiniup.com' => lang('北美-洛杉矶'),
|
||||||
|
'up-as0.qiniup.com' => lang('亚太-新加坡'),
|
||||||
|
'up-ap-northeast-1.qiniup.com' => lang('亚太-首尔'),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化入口.
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
protected function init()
|
||||||
|
{
|
||||||
|
// 读取配置文件
|
||||||
|
$this->bucket = sysconf('storage.qiniu_bucket|raw');
|
||||||
|
$this->accessKey = sysconf('storage.qiniu_access_key|raw');
|
||||||
|
$this->secretKey = sysconf('storage.qiniu_secret_key|raw');
|
||||||
|
// 计算链接前缀
|
||||||
|
$host = strtolower(sysconf('storage.qiniu_http_domain|raw'));
|
||||||
|
$type = strtolower(sysconf('storage.qiniu_http_protocol|raw'));
|
||||||
|
if ($type === 'auto') {
|
||||||
|
$this->domain = "//{$host}";
|
||||||
|
} elseif (in_array($type, ['http', 'https'])) {
|
||||||
|
$this->domain = "{$type}://{$host}";
|
||||||
|
} else {
|
||||||
|
throw new Exception(lang('未配置七牛云域名'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 安全BASE64编码
|
* 安全BASE64编码
|
||||||
* @param string $content
|
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
private function safeBase64(string $content): string
|
private function safeBase64(string $content): string
|
||||||
{
|
{
|
||||||
@ -224,7 +232,6 @@ class QiniuStorage implements StorageInterface
|
|||||||
* 生成管理凭证
|
* 生成管理凭证
|
||||||
* @param string $name 文件名称
|
* @param string $name 文件名称
|
||||||
* @param string $type 操作类型
|
* @param string $type 操作类型
|
||||||
* @return array
|
|
||||||
*/
|
*/
|
||||||
private function getAccessToken(string $name, string $type = 'stat'): array
|
private function getAccessToken(string $name, string $type = 'stat'): array
|
||||||
{
|
{
|
||||||
@ -232,21 +239,4 @@ class QiniuStorage implements StorageInterface
|
|||||||
$sign = hash_hmac('sha1', "/{$type}/{$entry}\n", $this->secretKey, true);
|
$sign = hash_hmac('sha1', "/{$type}/{$entry}\n", $this->secretKey, true);
|
||||||
return [$entry, "{$this->accessKey}:{$this->safeBase64($sign)}"];
|
return [$entry, "{$this->accessKey}:{$this->safeBase64($sign)}"];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
/**
|
|
||||||
* 获取存储区域
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public static function region(): array
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
'up.qiniup.com' => lang('华东-浙江'),
|
|
||||||
'up-cn-east-2.qiniup.com' => lang('华东-浙江2'),
|
|
||||||
'up-z1.qiniup.com' => lang('华北-河北'),
|
|
||||||
'up-z2.qiniup.com' => lang('华南-广东'),
|
|
||||||
'up-na0.qiniup.com' => lang('北美-洛杉矶'),
|
|
||||||
'up-as0.qiniup.com' => lang('亚太-新加坡'),
|
|
||||||
'up-ap-northeast-1.qiniup.com' => lang('亚太-首尔'),
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@ -1,20 +1,22 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// +----------------------------------------------------------------------
|
declare(strict_types=1);
|
||||||
// | Library for ThinkAdmin
|
/**
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 版权所有 2014~2025 ThinkAdmin [ thinkadmin.top ]
|
* | Payment Plugin for ThinkAdmin
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 官方网站: https://thinkadmin.top
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 开源协议 ( https://mit-license.org )
|
* | 官方网站: https://thinkadmin.top
|
||||||
// | 免费声明 ( https://thinkadmin.top/disclaimer )
|
* +----------------------------------------------------------------------
|
||||||
// +----------------------------------------------------------------------
|
* | 开源协议 ( https://mit-license.org )
|
||||||
// | gitee 仓库地址 :https://gitee.com/zoujingli/ThinkLibrary
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
// | github 仓库地址 :https://github.com/zoujingli/ThinkLibrary
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
declare (strict_types=1);
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
namespace think\admin\storage;
|
namespace think\admin\storage;
|
||||||
|
|
||||||
@ -27,40 +29,196 @@ use think\admin\Storage;
|
|||||||
/**
|
/**
|
||||||
* 腾讯云COS存储支持
|
* 腾讯云COS存储支持
|
||||||
* @class TxcosStorage
|
* @class TxcosStorage
|
||||||
* @package think\admin\storage
|
|
||||||
*/
|
*/
|
||||||
class TxcosStorage implements StorageInterface
|
class TxcosStorage implements StorageInterface
|
||||||
{
|
{
|
||||||
|
|
||||||
use StorageUsageTrait;
|
use StorageUsageTrait;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 数据中心
|
* 数据中心.
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
private $point;
|
private $point;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 存储空间名称
|
* 存储空间名称.
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
private $bucket;
|
private $bucket;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* $secretId
|
* $secretId.
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
private $secretId;
|
private $secretId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* secretKey
|
* secretKey.
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
private $secretKey;
|
private $secretKey;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 初始化入口
|
* 上传文件内容.
|
||||||
* @throws \think\admin\Exception
|
* @param string $name 文件名称
|
||||||
|
* @param string $file 文件内容
|
||||||
|
* @param bool $safe 安全模式
|
||||||
|
* @param ?string $attname 下载名称
|
||||||
|
*/
|
||||||
|
public function set(string $name, string $file, bool $safe = false, ?string $attname = null): array
|
||||||
|
{
|
||||||
|
$data = $this->token($name) + ['key' => $name];
|
||||||
|
if (is_string($attname) && strlen($attname) > 0) {
|
||||||
|
$data['Content-Disposition'] = urlencode($attname);
|
||||||
|
}
|
||||||
|
$data['success_action_status'] = '200';
|
||||||
|
$file = ['field' => 'file', 'name' => $name, 'content' => $file];
|
||||||
|
if (is_numeric(stripos(HttpExtend::submit($this->upload(), $data, $file), '200 OK'))) {
|
||||||
|
return ['file' => $this->path($name, $safe), 'url' => $this->url($name, $safe, $attname), 'key' => $name];
|
||||||
|
}
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 读取文件内容.
|
||||||
|
* @param string $name 文件名称
|
||||||
|
* @param bool $safe 安全模式
|
||||||
|
*/
|
||||||
|
public function get(string $name, bool $safe = false): string
|
||||||
|
{
|
||||||
|
return Storage::curlGet($this->url($name, $safe));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除存储文件.
|
||||||
|
* @param string $name 文件名称
|
||||||
|
* @param bool $safe 安全模式
|
||||||
|
*/
|
||||||
|
public function del(string $name, bool $safe = false): bool
|
||||||
|
{
|
||||||
|
[$file] = explode('?', $name);
|
||||||
|
$result = HttpExtend::request('DELETE', "https://{$this->bucket}.{$this->point}/{$file}", [
|
||||||
|
'returnHeader' => true, 'headers' => $this->_sign('DELETE', $file),
|
||||||
|
]);
|
||||||
|
return is_numeric(stripos($result, '204 No Content'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断是否存在.
|
||||||
|
* @param string $name 文件名称
|
||||||
|
* @param bool $safe 安全模式
|
||||||
|
*/
|
||||||
|
public function has(string $name, bool $safe = false): bool
|
||||||
|
{
|
||||||
|
$file = $this->delSuffix($name);
|
||||||
|
$result = HttpExtend::request('HEAD', "https://{$this->bucket}.{$this->point}/{$file}", [
|
||||||
|
'returnHeader' => true, 'headers' => $this->_sign('HEAD', $name),
|
||||||
|
]);
|
||||||
|
return is_numeric(stripos($result, 'HTTP/1.1 200 OK'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取访问地址
|
||||||
|
* @param string $name 文件名称
|
||||||
|
* @param bool $safe 安全模式
|
||||||
|
* @param ?string $attname 下载名称
|
||||||
|
*/
|
||||||
|
public function url(string $name, bool $safe = false, ?string $attname = null): string
|
||||||
|
{
|
||||||
|
return "{$this->domain}/{$this->delSuffix($name)}{$this->getSuffix($attname, $name)}";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取存储路径.
|
||||||
|
* @param string $name 文件名称
|
||||||
|
* @param bool $safe 安全模式
|
||||||
|
*/
|
||||||
|
public function path(string $name, bool $safe = false): string
|
||||||
|
{
|
||||||
|
return $this->url($name, $safe);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取文件信息.
|
||||||
|
* @param string $name 文件名称
|
||||||
|
* @param bool $safe 安全模式
|
||||||
|
* @param ?string $attname 下载名称
|
||||||
|
*/
|
||||||
|
public function info(string $name, bool $safe = false, ?string $attname = null): array
|
||||||
|
{
|
||||||
|
return $this->has($name, $safe) ? [
|
||||||
|
'url' => $this->url($name, $safe, $attname),
|
||||||
|
'key' => $name, 'file' => $this->path($name, $safe),
|
||||||
|
] : [];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取上传地址
|
||||||
|
*/
|
||||||
|
public function upload(): string
|
||||||
|
{
|
||||||
|
$proc = $this->app->request->isSsl() ? 'https' : 'http';
|
||||||
|
return "{$proc}://{$this->bucket}.{$this->point}";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成上传令牌.
|
||||||
|
* @param string $name 文件名称
|
||||||
|
* @param int $expires 有效时间
|
||||||
|
* @param ?string $attname 下载名称
|
||||||
|
*/
|
||||||
|
public function token(string $name, int $expires = 3600, ?string $attname = null): array
|
||||||
|
{
|
||||||
|
$startTimestamp = time();
|
||||||
|
$endTimestamp = $startTimestamp + $expires;
|
||||||
|
$keyTime = "{$startTimestamp};{$endTimestamp}";
|
||||||
|
$siteurl = $this->url($name, false, $attname);
|
||||||
|
$policy = json_encode([
|
||||||
|
'expiration' => date('Y-m-d\TH:i:s.000\Z', $endTimestamp),
|
||||||
|
'conditions' => [['q-ak' => $this->secretId], ['q-sign-time' => $keyTime], ['q-sign-algorithm' => 'sha1']],
|
||||||
|
]);
|
||||||
|
return [
|
||||||
|
'policy' => base64_encode($policy), 'q-ak' => $this->secretId,
|
||||||
|
'siteurl' => $siteurl, 'q-key-time' => $keyTime, 'q-sign-algorithm' => 'sha1',
|
||||||
|
'q-signature' => hash_hmac('sha1', sha1($policy), hash_hmac('sha1', $keyTime, $this->secretKey)),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取存储区域
|
||||||
|
*/
|
||||||
|
public static function region(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'cos.ap-beijing-1.myqcloud.com' => lang('中国大陆 公有云地域 北京一区'),
|
||||||
|
'cos.ap-beijing.myqcloud.com' => lang('中国大陆 公有云地域 北京'),
|
||||||
|
'cos.ap-nanjing.myqcloud.com' => lang('中国大陆 公有云地域 南京'),
|
||||||
|
'cos.ap-shanghai.myqcloud.com' => lang('中国大陆 公有云地域 上海'),
|
||||||
|
'cos.ap-guangzhou.myqcloud.com' => lang('中国大陆 公有云地域 广州'),
|
||||||
|
'cos.ap-chengdu.myqcloud.com' => lang('中国大陆 公有云地域 成都'),
|
||||||
|
'cos.ap-chongqing.myqcloud.com' => lang('中国大陆 公有云地域 重庆'),
|
||||||
|
'cos.ap-shenzhen-fsi.myqcloud.com' => lang('中国大陆 金融云地域 深圳金融'),
|
||||||
|
'cos.ap-shanghai-fsi.myqcloud.com' => lang('中国大陆 金融云地域 上海金融'),
|
||||||
|
'cos.ap-beijing-fsi.myqcloud.com' => lang('中国大陆 金融云地域 北京金融'),
|
||||||
|
'cos.ap-hongkong.myqcloud.com' => lang('亚太地区 公有云地域 中国香港'),
|
||||||
|
'cos.ap-singapore.myqcloud.com' => lang('亚太地区 公有云地域 新加坡'),
|
||||||
|
'cos.ap-mumbai.myqcloud.com' => lang('亚太地区 公有云地域 孟买'),
|
||||||
|
'cos.ap-jakarta.myqcloud.com' => lang('亚太地区 公有云地域 雅加达'),
|
||||||
|
'cos.ap-seoul.myqcloud.com' => lang('亚太地区 公有云地域 首尔'),
|
||||||
|
'cos.ap-bangkok.myqcloud.com' => lang('亚太地区 公有云地域 曼谷'),
|
||||||
|
'cos.ap-tokyo.myqcloud.com' => lang('亚太地区 公有云地域 东京'),
|
||||||
|
'cos.na-siliconvalley.myqcloud.com' => lang('北美地区 公有云地域 硅谷'),
|
||||||
|
'cos.na-ashburn.myqcloud.com' => lang('北美地区 公有云地域 弗吉尼亚'),
|
||||||
|
'cos.na-toronto.myqcloud.com' => lang('北美地区 公有云地域 多伦多'),
|
||||||
|
'cos.sa-saopaulo.myqcloud.com' => lang('北美地区 公有云地域 圣保罗'),
|
||||||
|
'cos.eu-frankfurt.myqcloud.com' => lang('欧洲地区 公有云地域 法兰克福'),
|
||||||
|
'cos.eu-moscow.myqcloud.com' => lang('欧洲地区 公有云地域 莫斯科'),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化入口.
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
protected function init()
|
protected function init()
|
||||||
{
|
{
|
||||||
@ -82,146 +240,9 @@ class TxcosStorage implements StorageInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 上传文件内容
|
* 生成请求签名.
|
||||||
* @param string $name 文件名称
|
|
||||||
* @param string $file 文件内容
|
|
||||||
* @param boolean $safe 安全模式
|
|
||||||
* @param ?string $attname 下载名称
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function set(string $name, string $file, bool $safe = false, ?string $attname = null): array
|
|
||||||
{
|
|
||||||
$data = $this->token($name) + ['key' => $name];
|
|
||||||
if (is_string($attname) && strlen($attname) > 0) {
|
|
||||||
$data['Content-Disposition'] = urlencode($attname);
|
|
||||||
}
|
|
||||||
$data['success_action_status'] = '200';
|
|
||||||
$file = ['field' => 'file', 'name' => $name, 'content' => $file];
|
|
||||||
if (is_numeric(stripos(HttpExtend::submit($this->upload(), $data, $file), '200 OK'))) {
|
|
||||||
return ['file' => $this->path($name, $safe), 'url' => $this->url($name, $safe, $attname), 'key' => $name];
|
|
||||||
} else {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 读取文件内容
|
|
||||||
* @param string $name 文件名称
|
|
||||||
* @param boolean $safe 安全模式
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function get(string $name, bool $safe = false): string
|
|
||||||
{
|
|
||||||
return Storage::curlGet($this->url($name, $safe));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 删除存储文件
|
|
||||||
* @param string $name 文件名称
|
|
||||||
* @param boolean $safe 安全模式
|
|
||||||
* @return boolean
|
|
||||||
*/
|
|
||||||
public function del(string $name, bool $safe = false): bool
|
|
||||||
{
|
|
||||||
[$file] = explode('?', $name);
|
|
||||||
$result = HttpExtend::request('DELETE', "https://{$this->bucket}.{$this->point}/{$file}", [
|
|
||||||
'returnHeader' => true, 'headers' => $this->_sign('DELETE', $file),
|
|
||||||
]);
|
|
||||||
return is_numeric(stripos($result, '204 No Content'));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 判断是否存在
|
|
||||||
* @param string $name 文件名称
|
|
||||||
* @param boolean $safe 安全模式
|
|
||||||
* @return boolean
|
|
||||||
*/
|
|
||||||
public function has(string $name, bool $safe = false): bool
|
|
||||||
{
|
|
||||||
$file = $this->delSuffix($name);
|
|
||||||
$result = HttpExtend::request('HEAD', "https://{$this->bucket}.{$this->point}/{$file}", [
|
|
||||||
'returnHeader' => true, 'headers' => $this->_sign('HEAD', $name),
|
|
||||||
]);
|
|
||||||
return is_numeric(stripos($result, 'HTTP/1.1 200 OK'));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取访问地址
|
|
||||||
* @param string $name 文件名称
|
|
||||||
* @param boolean $safe 安全模式
|
|
||||||
* @param ?string $attname 下载名称
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function url(string $name, bool $safe = false, ?string $attname = null): string
|
|
||||||
{
|
|
||||||
return "{$this->domain}/{$this->delSuffix($name)}{$this->getSuffix($attname,$name)}";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取存储路径
|
|
||||||
* @param string $name 文件名称
|
|
||||||
* @param boolean $safe 安全模式
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function path(string $name, bool $safe = false): string
|
|
||||||
{
|
|
||||||
return $this->url($name, $safe);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取文件信息
|
|
||||||
* @param string $name 文件名称
|
|
||||||
* @param boolean $safe 安全模式
|
|
||||||
* @param ?string $attname 下载名称
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function info(string $name, bool $safe = false, ?string $attname = null): array
|
|
||||||
{
|
|
||||||
return $this->has($name, $safe) ? [
|
|
||||||
'url' => $this->url($name, $safe, $attname),
|
|
||||||
'key' => $name, 'file' => $this->path($name, $safe),
|
|
||||||
] : [];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取上传地址
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function upload(): string
|
|
||||||
{
|
|
||||||
$proc = $this->app->request->isSsl() ? 'https' : 'http';
|
|
||||||
return "{$proc}://{$this->bucket}.{$this->point}";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 生成上传令牌
|
|
||||||
* @param string $name 文件名称
|
|
||||||
* @param integer $expires 有效时间
|
|
||||||
* @param ?string $attname 下载名称
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function token(string $name, int $expires = 3600, ?string $attname = null): array
|
|
||||||
{
|
|
||||||
$startTimestamp = time();
|
|
||||||
$endTimestamp = $startTimestamp + $expires;
|
|
||||||
$keyTime = "{$startTimestamp};{$endTimestamp}";
|
|
||||||
$siteurl = $this->url($name, false, $attname);
|
|
||||||
$policy = json_encode([
|
|
||||||
'expiration' => date('Y-m-d\TH:i:s.000\Z', $endTimestamp),
|
|
||||||
'conditions' => [['q-ak' => $this->secretId], ['q-sign-time' => $keyTime], ['q-sign-algorithm' => 'sha1']],
|
|
||||||
]);
|
|
||||||
return [
|
|
||||||
'policy' => base64_encode($policy), 'q-ak' => $this->secretId,
|
|
||||||
'siteurl' => $siteurl, 'q-key-time' => $keyTime, 'q-sign-algorithm' => 'sha1',
|
|
||||||
'q-signature' => hash_hmac('sha1', sha1($policy), hash_hmac('sha1', $keyTime, $this->secretKey)),
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 生成请求签名
|
|
||||||
* @param string $method 请求方式
|
* @param string $method 请求方式
|
||||||
* @param string $soruce 资源名称
|
* @param string $soruce 资源名称
|
||||||
* @return array
|
|
||||||
*/
|
*/
|
||||||
private function _sign(string $method, string $soruce): array
|
private function _sign(string $method, string $soruce): array
|
||||||
{
|
{
|
||||||
@ -257,48 +278,17 @@ class TxcosStorage implements StorageInterface
|
|||||||
// 8.生成签名
|
// 8.生成签名
|
||||||
$signArray = [
|
$signArray = [
|
||||||
'q-sign-algorithm' => 'sha1',
|
'q-sign-algorithm' => 'sha1',
|
||||||
'q-ak' => $this->secretId,
|
'q-ak' => $this->secretId,
|
||||||
'q-sign-time' => $keyTime,
|
'q-sign-time' => $keyTime,
|
||||||
'q-key-time' => $keyTime,
|
'q-key-time' => $keyTime,
|
||||||
'q-header-list' => $headerList,
|
'q-header-list' => $headerList,
|
||||||
'q-url-param-list' => $urlParamList,
|
'q-url-param-list' => $urlParamList,
|
||||||
'q-signature' => $signature,
|
'q-signature' => $signature,
|
||||||
];
|
];
|
||||||
$header['Authorization'] = urldecode(http_build_query($signArray));
|
$header['Authorization'] = urldecode(http_build_query($signArray));
|
||||||
foreach ($header as $key => $value) $header[$key] = ucfirst($key) . ": {$value}";
|
foreach ($header as $key => $value) {
|
||||||
|
$header[$key] = ucfirst($key) . ": {$value}";
|
||||||
|
}
|
||||||
return array_values($header);
|
return array_values($header);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
/**
|
|
||||||
* 获取存储区域
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public static function region(): array
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
'cos.ap-beijing-1.myqcloud.com' => lang('中国大陆 公有云地域 北京一区'),
|
|
||||||
'cos.ap-beijing.myqcloud.com' => lang('中国大陆 公有云地域 北京'),
|
|
||||||
'cos.ap-nanjing.myqcloud.com' => lang('中国大陆 公有云地域 南京'),
|
|
||||||
'cos.ap-shanghai.myqcloud.com' => lang('中国大陆 公有云地域 上海'),
|
|
||||||
'cos.ap-guangzhou.myqcloud.com' => lang('中国大陆 公有云地域 广州'),
|
|
||||||
'cos.ap-chengdu.myqcloud.com' => lang('中国大陆 公有云地域 成都'),
|
|
||||||
'cos.ap-chongqing.myqcloud.com' => lang('中国大陆 公有云地域 重庆'),
|
|
||||||
'cos.ap-shenzhen-fsi.myqcloud.com' => lang('中国大陆 金融云地域 深圳金融'),
|
|
||||||
'cos.ap-shanghai-fsi.myqcloud.com' => lang('中国大陆 金融云地域 上海金融'),
|
|
||||||
'cos.ap-beijing-fsi.myqcloud.com' => lang('中国大陆 金融云地域 北京金融'),
|
|
||||||
'cos.ap-hongkong.myqcloud.com' => lang('亚太地区 公有云地域 中国香港'),
|
|
||||||
'cos.ap-singapore.myqcloud.com' => lang('亚太地区 公有云地域 新加坡'),
|
|
||||||
'cos.ap-mumbai.myqcloud.com' => lang('亚太地区 公有云地域 孟买'),
|
|
||||||
'cos.ap-jakarta.myqcloud.com' => lang('亚太地区 公有云地域 雅加达'),
|
|
||||||
'cos.ap-seoul.myqcloud.com' => lang('亚太地区 公有云地域 首尔'),
|
|
||||||
'cos.ap-bangkok.myqcloud.com' => lang('亚太地区 公有云地域 曼谷'),
|
|
||||||
'cos.ap-tokyo.myqcloud.com' => lang('亚太地区 公有云地域 东京'),
|
|
||||||
'cos.na-siliconvalley.myqcloud.com' => lang('北美地区 公有云地域 硅谷'),
|
|
||||||
'cos.na-ashburn.myqcloud.com' => lang('北美地区 公有云地域 弗吉尼亚'),
|
|
||||||
'cos.na-toronto.myqcloud.com' => lang('北美地区 公有云地域 多伦多'),
|
|
||||||
'cos.sa-saopaulo.myqcloud.com' => lang('北美地区 公有云地域 圣保罗'),
|
|
||||||
'cos.eu-frankfurt.myqcloud.com' => lang('欧洲地区 公有云地域 法兰克福'),
|
|
||||||
'cos.eu-moscow.myqcloud.com' => lang('欧洲地区 公有云地域 莫斯科'),
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@ -1,20 +1,22 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// +----------------------------------------------------------------------
|
declare(strict_types=1);
|
||||||
// | Library for ThinkAdmin
|
/**
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 版权所有 2014~2025 ThinkAdmin [ thinkadmin.top ]
|
* | Payment Plugin for ThinkAdmin
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 官方网站: https://thinkadmin.top
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 开源协议 ( https://mit-license.org )
|
* | 官方网站: https://thinkadmin.top
|
||||||
// | 免费声明 ( https://thinkadmin.top/disclaimer )
|
* +----------------------------------------------------------------------
|
||||||
// +----------------------------------------------------------------------
|
* | 开源协议 ( https://mit-license.org )
|
||||||
// | gitee 仓库地址 :https://gitee.com/zoujingli/ThinkLibrary
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
// | github 仓库地址 :https://github.com/zoujingli/ThinkLibrary
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
declare (strict_types=1);
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
namespace think\admin\storage;
|
namespace think\admin\storage;
|
||||||
|
|
||||||
@ -27,33 +29,169 @@ use think\admin\Storage;
|
|||||||
/**
|
/**
|
||||||
* 又拍云存储支持
|
* 又拍云存储支持
|
||||||
* @class UpyunStorage
|
* @class UpyunStorage
|
||||||
* @package think\admin\storage
|
|
||||||
*/
|
*/
|
||||||
class UpyunStorage implements StorageInterface
|
class UpyunStorage implements StorageInterface
|
||||||
{
|
{
|
||||||
use StorageUsageTrait;
|
use StorageUsageTrait;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 存储空间名称
|
* 存储空间名称.
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
private $bucket;
|
private $bucket;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AccessId
|
* AccessId.
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
private $accessKey;
|
private $accessKey;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AccessSecret
|
* AccessSecret.
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
private $secretKey;
|
private $secretKey;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 初始化入口
|
* 上传文件内容.
|
||||||
* @throws \think\admin\Exception
|
* @param string $name 文件名称
|
||||||
|
* @param string $file 文件内容
|
||||||
|
* @param bool $safe 安全模式
|
||||||
|
* @param ?string $attname 下载名称
|
||||||
|
*/
|
||||||
|
public function set(string $name, string $file, bool $safe = false, ?string $attname = null): array
|
||||||
|
{
|
||||||
|
$data = [];
|
||||||
|
$token = $this->token($name, 3600, $attname, md5($file));
|
||||||
|
$data['policy'] = $token['policy'];
|
||||||
|
$data['authorization'] = $token['authorization'];
|
||||||
|
$file = ['field' => 'file', 'name' => $name, 'content' => $file];
|
||||||
|
if (is_numeric(stripos(HttpExtend::submit($this->upload(), $data, $file), '200 OK'))) {
|
||||||
|
return ['file' => $this->path($name, $safe), 'url' => $this->url($name, $safe, $attname), 'key' => $name];
|
||||||
|
}
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 读取文件内容.
|
||||||
|
* @param string $name 文件名称
|
||||||
|
* @param bool $safe 安全模式
|
||||||
|
*/
|
||||||
|
public function get(string $name, bool $safe = false): string
|
||||||
|
{
|
||||||
|
return Storage::curlGet($this->url($name, $safe));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除存储文件.
|
||||||
|
* @param string $name 文件名称
|
||||||
|
* @param bool $safe 安全模式
|
||||||
|
*/
|
||||||
|
public function del(string $name, bool $safe = false): bool
|
||||||
|
{
|
||||||
|
[$file] = explode('?', $name);
|
||||||
|
$result = HttpExtend::request('DELETE', "{$this->upload()}/{$file}", [
|
||||||
|
'returnHeader' => true, 'headers' => $this->_sign('DELETE', $file),
|
||||||
|
]);
|
||||||
|
return is_numeric(stripos($result, 'HTTP/1.1 200 OK'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断是否存在.
|
||||||
|
* @param string $name 文件名称
|
||||||
|
* @param bool $safe 安全模式
|
||||||
|
*/
|
||||||
|
public function has(string $name, bool $safe = false): bool
|
||||||
|
{
|
||||||
|
$file = $this->delSuffix($name);
|
||||||
|
$result = HttpExtend::request('HEAD', "{$this->upload()}/{$file}", [
|
||||||
|
'returnHeader' => true, 'headers' => $this->_sign('HEAD', $file),
|
||||||
|
]);
|
||||||
|
return is_numeric(stripos($result, 'HTTP/1.1 200 OK'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取访问地址
|
||||||
|
* @param string $name 文件名称
|
||||||
|
* @param bool $safe 安全模式
|
||||||
|
* @param ?string $attname 下载名称
|
||||||
|
*/
|
||||||
|
public function url(string $name, bool $safe = false, ?string $attname = null): string
|
||||||
|
{
|
||||||
|
return "{$this->domain}/{$this->delSuffix($name)}{$this->getSuffix($attname, $name)}";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取存储路径.
|
||||||
|
* @param string $name 文件名称
|
||||||
|
* @param bool $safe 安全模式
|
||||||
|
*/
|
||||||
|
public function path(string $name, bool $safe = false): string
|
||||||
|
{
|
||||||
|
return $this->url($name, $safe);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取文件信息.
|
||||||
|
* @param string $name 文件名称
|
||||||
|
* @param bool $safe 安全模式
|
||||||
|
* @param ?string $attname 下载名称
|
||||||
|
*/
|
||||||
|
public function info(string $name, bool $safe = false, ?string $attname = null): array
|
||||||
|
{
|
||||||
|
return $this->has($name, $safe) ? [
|
||||||
|
'url' => $this->url($name, $safe, $attname),
|
||||||
|
'key' => $name, 'file' => $this->path($name, $safe),
|
||||||
|
] : [];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取上传地址
|
||||||
|
*/
|
||||||
|
public function upload(): string
|
||||||
|
{
|
||||||
|
$protocol = $this->app->request->isSsl() ? 'https' : 'http';
|
||||||
|
return "{$protocol}://v0.api.upyun.com/{$this->bucket}";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成上传令牌.
|
||||||
|
* @param string $name 文件名称
|
||||||
|
* @param int $expires 有效时间
|
||||||
|
* @param ?string $attname 下载名称
|
||||||
|
* @param ?string $fileHash 文件哈希
|
||||||
|
*/
|
||||||
|
public function token(string $name, int $expires = 3600, ?string $attname = null, ?string $fileHash = ''): array
|
||||||
|
{
|
||||||
|
$policy = ['save-key' => $name];
|
||||||
|
$policy['date'] = gmdate('D, d M Y H:i:s \G\M\T');
|
||||||
|
$policy['bucket'] = $this->bucket;
|
||||||
|
$policy['expiration'] = time() + $expires;
|
||||||
|
if ($fileHash) {
|
||||||
|
$policy['content-md5'] = $fileHash;
|
||||||
|
}
|
||||||
|
$data = ['keyid' => $this->accessKey, 'siteurl' => $this->url($name, false, $attname)];
|
||||||
|
$data['policy'] = base64_encode(json_encode($policy, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
|
||||||
|
$content = "POST&/{$this->bucket}&{$policy['date']}&{$data['policy']}";
|
||||||
|
if ($fileHash) {
|
||||||
|
$content .= "&{$fileHash}";
|
||||||
|
}
|
||||||
|
$data['signature'] = base64_encode(hash_hmac('sha1', $content, md5($this->secretKey), true));
|
||||||
|
$data['authorization'] = "UPYUN {$this->accessKey}:{$data['signature']}";
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取存储区域
|
||||||
|
*/
|
||||||
|
public static function region(): array
|
||||||
|
{
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化入口.
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
protected function init()
|
protected function init()
|
||||||
{
|
{
|
||||||
@ -74,145 +212,9 @@ class UpyunStorage implements StorageInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 上传文件内容
|
* 生成请求签名.
|
||||||
* @param string $name 文件名称
|
|
||||||
* @param string $file 文件内容
|
|
||||||
* @param boolean $safe 安全模式
|
|
||||||
* @param ?string $attname 下载名称
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function set(string $name, string $file, bool $safe = false, ?string $attname = null): array
|
|
||||||
{
|
|
||||||
$data = [];
|
|
||||||
$token = $this->token($name, 3600, $attname, md5($file));
|
|
||||||
$data['policy'] = $token['policy'];
|
|
||||||
$data['authorization'] = $token['authorization'];
|
|
||||||
$file = ['field' => 'file', 'name' => $name, 'content' => $file];
|
|
||||||
if (is_numeric(stripos(HttpExtend::submit($this->upload(), $data, $file), '200 OK'))) {
|
|
||||||
return ['file' => $this->path($name, $safe), 'url' => $this->url($name, $safe, $attname), 'key' => $name];
|
|
||||||
} else {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 读取文件内容
|
|
||||||
* @param string $name 文件名称
|
|
||||||
* @param boolean $safe 安全模式
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function get(string $name, bool $safe = false): string
|
|
||||||
{
|
|
||||||
return Storage::curlGet($this->url($name, $safe));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 删除存储文件
|
|
||||||
* @param string $name 文件名称
|
|
||||||
* @param boolean $safe 安全模式
|
|
||||||
* @return boolean
|
|
||||||
*/
|
|
||||||
public function del(string $name, bool $safe = false): bool
|
|
||||||
{
|
|
||||||
[$file] = explode('?', $name);
|
|
||||||
$result = HttpExtend::request('DELETE', "{$this->upload()}/{$file}", [
|
|
||||||
'returnHeader' => true, 'headers' => $this->_sign('DELETE', $file),
|
|
||||||
]);
|
|
||||||
return is_numeric(stripos($result, 'HTTP/1.1 200 OK'));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 判断是否存在
|
|
||||||
* @param string $name 文件名称
|
|
||||||
* @param boolean $safe 安全模式
|
|
||||||
* @return boolean
|
|
||||||
*/
|
|
||||||
public function has(string $name, bool $safe = false): bool
|
|
||||||
{
|
|
||||||
$file = $this->delSuffix($name);
|
|
||||||
$result = HttpExtend::request('HEAD', "{$this->upload()}/{$file}", [
|
|
||||||
'returnHeader' => true, 'headers' => $this->_sign('HEAD', $file),
|
|
||||||
]);
|
|
||||||
return is_numeric(stripos($result, 'HTTP/1.1 200 OK'));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取访问地址
|
|
||||||
* @param string $name 文件名称
|
|
||||||
* @param boolean $safe 安全模式
|
|
||||||
* @param ?string $attname 下载名称
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function url(string $name, bool $safe = false, ?string $attname = null): string
|
|
||||||
{
|
|
||||||
return "{$this->domain}/{$this->delSuffix($name)}{$this->getSuffix($attname,$name)}";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取存储路径
|
|
||||||
* @param string $name 文件名称
|
|
||||||
* @param boolean $safe 安全模式
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function path(string $name, bool $safe = false): string
|
|
||||||
{
|
|
||||||
return $this->url($name, $safe);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取文件信息
|
|
||||||
* @param string $name 文件名称
|
|
||||||
* @param boolean $safe 安全模式
|
|
||||||
* @param ?string $attname 下载名称
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function info(string $name, bool $safe = false, ?string $attname = null): array
|
|
||||||
{
|
|
||||||
return $this->has($name, $safe) ? [
|
|
||||||
'url' => $this->url($name, $safe, $attname),
|
|
||||||
'key' => $name, 'file' => $this->path($name, $safe),
|
|
||||||
] : [];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取上传地址
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function upload(): string
|
|
||||||
{
|
|
||||||
$protocol = $this->app->request->isSsl() ? 'https' : 'http';
|
|
||||||
return "{$protocol}://v0.api.upyun.com/{$this->bucket}";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 生成上传令牌
|
|
||||||
* @param string $name 文件名称
|
|
||||||
* @param integer $expires 有效时间
|
|
||||||
* @param ?string $attname 下载名称
|
|
||||||
* @param ?string $fileHash 文件哈希
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function token(string $name, int $expires = 3600, ?string $attname = null, ?string $fileHash = ''): array
|
|
||||||
{
|
|
||||||
$policy = ['save-key' => $name];
|
|
||||||
$policy['date'] = gmdate('D, d M Y H:i:s \G\M\T');
|
|
||||||
$policy['bucket'] = $this->bucket;
|
|
||||||
$policy['expiration'] = time() + $expires;
|
|
||||||
if ($fileHash) $policy['content-md5'] = $fileHash;
|
|
||||||
$data = ['keyid' => $this->accessKey, 'siteurl' => $this->url($name, false, $attname)];
|
|
||||||
$data['policy'] = base64_encode(json_encode($policy, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
|
|
||||||
$content = "POST&/{$this->bucket}&{$policy['date']}&{$data['policy']}";
|
|
||||||
if ($fileHash) $content .= "&{$fileHash}";
|
|
||||||
$data['signature'] = base64_encode(hash_hmac('sha1', $content, md5($this->secretKey), true));
|
|
||||||
$data['authorization'] = "UPYUN {$this->accessKey}:{$data['signature']}";
|
|
||||||
return $data;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 生成请求签名
|
|
||||||
* @param string $method 请求方式
|
* @param string $method 请求方式
|
||||||
* @param string $name 资源名称
|
* @param string $name 资源名称
|
||||||
* @return array
|
|
||||||
*/
|
*/
|
||||||
private function _sign(string $method, string $name): array
|
private function _sign(string $method, string $name): array
|
||||||
{
|
{
|
||||||
@ -220,13 +222,4 @@ class UpyunStorage implements StorageInterface
|
|||||||
$signature = base64_encode(hash_hmac('sha1', join('&', $data), md5($this->secretKey), true));
|
$signature = base64_encode(hash_hmac('sha1', join('&', $data), md5($this->secretKey), true));
|
||||||
return ["Authorization:UPYUN {$this->accessKey}:{$signature}", "Date:{$date}"];
|
return ["Authorization:UPYUN {$this->accessKey}:{$signature}", "Date:{$date}"];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
/**
|
|
||||||
* 获取存储区域
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public static function region(): array
|
|
||||||
{
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -1,20 +1,22 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// +----------------------------------------------------------------------
|
declare(strict_types=1);
|
||||||
// | Library for ThinkAdmin
|
/**
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 版权所有 2014~2025 ThinkAdmin [ thinkadmin.top ]
|
* | Payment Plugin for ThinkAdmin
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 官方网站: https://thinkadmin.top
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 开源协议 ( https://mit-license.org )
|
* | 官方网站: https://thinkadmin.top
|
||||||
// | 免费声明 ( https://thinkadmin.top/disclaimer )
|
* +----------------------------------------------------------------------
|
||||||
// +----------------------------------------------------------------------
|
* | 开源协议 ( https://mit-license.org )
|
||||||
// | gitee 仓库地址 :https://gitee.com/zoujingli/ThinkLibrary
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
// | github 仓库地址 :https://github.com/zoujingli/ThinkLibrary
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
declare (strict_types=1);
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
namespace think\admin\support;
|
namespace think\admin\support;
|
||||||
|
|
||||||
@ -23,12 +25,11 @@ use think\Route as ThinkRoute;
|
|||||||
/**
|
/**
|
||||||
* 自定义路由对象
|
* 自定义路由对象
|
||||||
* @class Route
|
* @class Route
|
||||||
* @package think\admin\support
|
|
||||||
*/
|
*/
|
||||||
class Route extends ThinkRoute
|
class Route extends ThinkRoute
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* 重载路由配置
|
* 重载路由配置.
|
||||||
* @return $this
|
* @return $this
|
||||||
*/
|
*/
|
||||||
public function reload(): Route
|
public function reload(): Route
|
||||||
@ -36,4 +37,4 @@ class Route extends ThinkRoute
|
|||||||
$this->config = array_merge($this->config, $this->app->config->get('route'));
|
$this->config = array_merge($this->config, $this->app->config->get('route'));
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -24,59 +24,37 @@
|
|||||||
// 以下代码来自 topthink/think-multi-app,有部分修改以兼容 ThinkAdmin 的需求
|
// 以下代码来自 topthink/think-multi-app,有部分修改以兼容 ThinkAdmin 的需求
|
||||||
// +----------------------------------------------------------------------
|
// +----------------------------------------------------------------------
|
||||||
|
|
||||||
declare (strict_types=1);
|
declare(strict_types=1);
|
||||||
|
/**
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
* | Payment Plugin for ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
* | 官方网站: https://thinkadmin.top
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
* | 开源协议 ( https://mit-license.org )
|
||||||
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
namespace think\admin\support;
|
namespace think\admin\support;
|
||||||
|
|
||||||
use InvalidArgumentException;
|
|
||||||
use think\admin\service\NodeService;
|
use think\admin\service\NodeService;
|
||||||
use think\route\Url as ThinkUrl;
|
use think\route\Url as ThinkUrl;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 多应用 URL 生成与解析
|
* 多应用 URL 生成与解析.
|
||||||
* @class Url
|
* @class Url
|
||||||
* @package think\admin\support
|
|
||||||
*/
|
*/
|
||||||
class Url extends ThinkUrl
|
class Url extends ThinkUrl
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* 直接解析 URL 地址
|
* Build URL.
|
||||||
* @param string $url URL
|
|
||||||
* @param string|boolean $domain Domain
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
protected function parseUrl(string $url, &$domain): string
|
|
||||||
{
|
|
||||||
$request = $this->app->request;
|
|
||||||
if (0 === strpos($url, '/')) {
|
|
||||||
$url = substr($url, 1);
|
|
||||||
} elseif (false !== strpos($url, '\\')) {
|
|
||||||
$url = ltrim(str_replace('\\', '/', $url), '/');
|
|
||||||
} elseif (0 === strpos($url, '@')) {
|
|
||||||
$url = substr($url, 1);
|
|
||||||
} else {
|
|
||||||
$attrs = str2arr($url, '/');
|
|
||||||
$action = empty($attrs) ? $request->action() : array_pop($attrs);
|
|
||||||
$contrl = empty($attrs) ? $request->controller() : array_pop($attrs);
|
|
||||||
$module = empty($attrs) ? $this->app->http->getName() : array_pop($attrs);
|
|
||||||
// 拼装新的链接地址
|
|
||||||
$url = NodeService::nameTolower($contrl) . '/' . $action;
|
|
||||||
$bind = $this->app->config->get('app.domain_bind', []);
|
|
||||||
if ($key = array_search($module, $bind)) {
|
|
||||||
if (isset($bind[$_SERVER['SERVER_NAME']])) $domain = $_SERVER['SERVER_NAME'];
|
|
||||||
$domain = is_bool($domain) ? $key : $domain;
|
|
||||||
} elseif ($key = array_search($module, $this->app->config->get('app.app_map', []))) {
|
|
||||||
$url = $key . '/' . $url;
|
|
||||||
} else {
|
|
||||||
$url = $module . '/' . $url;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $url;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Build URL
|
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public function build(): string
|
public function build(): string
|
||||||
{
|
{
|
||||||
@ -85,26 +63,26 @@ class Url extends ThinkUrl
|
|||||||
$domain = $this->domain;
|
$domain = $this->domain;
|
||||||
$suffix = $this->suffix;
|
$suffix = $this->suffix;
|
||||||
$request = $this->app->request;
|
$request = $this->app->request;
|
||||||
if (0 === strpos($url, '[') && $pos = strpos($url, ']')) {
|
if (strpos($url, '[') === 0 && $pos = strpos($url, ']')) {
|
||||||
// [name] 表示使用路由命名标识生成URL
|
// [name] 表示使用路由命名标识生成URL
|
||||||
$name = substr($url, 1, $pos - 1);
|
$name = substr($url, 1, $pos - 1);
|
||||||
$url = 'name' . substr($url, $pos + 1);
|
$url = 'name' . substr($url, $pos + 1);
|
||||||
}
|
}
|
||||||
if (false === strpos($url, '://') && 0 !== strpos($url, '/')) {
|
if (strpos($url, '://') === false && strpos($url, '/') !== 0) {
|
||||||
$info = parse_url($url);
|
$info = parse_url($url);
|
||||||
$url = !empty($info['path']) ? $info['path'] : '';
|
$url = !empty($info['path']) ? $info['path'] : '';
|
||||||
if (isset($info['fragment'])) {
|
if (isset($info['fragment'])) {
|
||||||
// 解析锚点
|
// 解析锚点
|
||||||
$anchor = $info['fragment'];
|
$anchor = $info['fragment'];
|
||||||
if (false !== strpos($anchor, '?')) {
|
if (strpos($anchor, '?') !== false) {
|
||||||
// 解析参数
|
// 解析参数
|
||||||
[$anchor, $info['query']] = explode('?', $anchor, 2);
|
[$anchor, $info['query']] = explode('?', $anchor, 2);
|
||||||
}
|
}
|
||||||
if (false !== strpos($anchor, '@')) {
|
if (strpos($anchor, '@') !== false) {
|
||||||
// 解析域名
|
// 解析域名
|
||||||
[$anchor, $domain] = explode('@', $anchor, 2);
|
[$anchor, $domain] = explode('@', $anchor, 2);
|
||||||
}
|
}
|
||||||
} elseif (strpos($url, '@') && false === strpos($url, '\\')) {
|
} elseif (strpos($url, '@') && strpos($url, '\\') === false) {
|
||||||
// 解析域名
|
// 解析域名
|
||||||
[$url, $domain] = explode('@', $url, 2);
|
[$url, $domain] = explode('@', $url, 2);
|
||||||
}
|
}
|
||||||
@ -122,17 +100,21 @@ class Url extends ThinkUrl
|
|||||||
}
|
}
|
||||||
if (!empty($rule) && $match = $this->getRuleUrl($rule, $vars, $domain)) {
|
if (!empty($rule) && $match = $this->getRuleUrl($rule, $vars, $domain)) {
|
||||||
$url = $match[0];
|
$url = $match[0];
|
||||||
if ($domain && !empty($match[1])) $domain = $match[1];
|
if ($domain && !empty($match[1])) {
|
||||||
if (!is_null($match[2])) $suffix = $match[2];
|
$domain = $match[1];
|
||||||
|
}
|
||||||
|
if (!is_null($match[2])) {
|
||||||
|
$suffix = $match[2];
|
||||||
|
}
|
||||||
if (!$this->app->http->isBind()) {
|
if (!$this->app->http->isBind()) {
|
||||||
$url = $this->app->http->getName() . '/' . $url;
|
$url = $this->app->http->getName() . '/' . $url;
|
||||||
}
|
}
|
||||||
} elseif (!empty($rule) && isset($name)) {
|
} elseif (!empty($rule) && isset($name)) {
|
||||||
throw new InvalidArgumentException('route name not exists:' . $name);
|
throw new \InvalidArgumentException('route name not exists:' . $name);
|
||||||
} else {
|
} else {
|
||||||
// 检测URL绑定
|
// 检测URL绑定
|
||||||
$bind = $this->route->getDomainBind($domain && is_string($domain) ? $domain : null);
|
$bind = $this->route->getDomainBind($domain && is_string($domain) ? $domain : null);
|
||||||
if ($bind && 0 === strpos($url, $bind)) {
|
if ($bind && strpos($url, $bind) === 0) {
|
||||||
$url = substr($url, strlen($bind) + 1);
|
$url = substr($url, strlen($bind) + 1);
|
||||||
}
|
}
|
||||||
// 路由标识不存在 直接解析
|
// 路由标识不存在 直接解析
|
||||||
@ -147,13 +129,13 @@ class Url extends ThinkUrl
|
|||||||
$file = $request->baseFile();
|
$file = $request->baseFile();
|
||||||
$depr = $this->route->config('pathinfo_depr');
|
$depr = $this->route->config('pathinfo_depr');
|
||||||
[$uri, $url] = [$request->url(), str_replace('/', $depr, $url)];
|
[$uri, $url] = [$request->url(), str_replace('/', $depr, $url)];
|
||||||
if ($file && 0 !== strpos($uri, $file)) {
|
if ($file && strpos($uri, $file) !== 0) {
|
||||||
$file = str_replace('\\', '/', dirname($file));
|
$file = str_replace('\\', '/', dirname($file));
|
||||||
}
|
}
|
||||||
/*=====- 多应用绑定 URL 生成处理 -=====*/
|
/* =====- 多应用绑定 URL 生成处理 -===== */
|
||||||
$app = $this->app->http->getName();
|
$app = $this->app->http->getName();
|
||||||
if ($this->app->http->isBind()) {
|
if ($this->app->http->isBind()) {
|
||||||
if (preg_match("#^{$app}({$depr}|\.|$)#i", $url)) {
|
if (preg_match("#^{$app}({$depr}|\\.|$)#i", $url)) {
|
||||||
$url = trim(substr($url, strlen($app)), $depr);
|
$url = trim(substr($url, strlen($app)), $depr);
|
||||||
} elseif (substr_count($url, $depr) >= 2) {
|
} elseif (substr_count($url, $depr) >= 2) {
|
||||||
$file = 'index.php';
|
$file = 'index.php';
|
||||||
@ -161,7 +143,7 @@ class Url extends ThinkUrl
|
|||||||
}
|
}
|
||||||
$url = rtrim($file, '/') . '/' . ltrim($url, '/');
|
$url = rtrim($file, '/') . '/' . ltrim($url, '/');
|
||||||
// URL后缀
|
// URL后缀
|
||||||
if ('/' == substr($url, -1) || '' == $url) {
|
if (substr($url, -1) == '/' || $url == '') {
|
||||||
$suffix = '';
|
$suffix = '';
|
||||||
} else {
|
} else {
|
||||||
$suffix = $this->parseSuffix($suffix);
|
$suffix = $this->parseSuffix($suffix);
|
||||||
@ -190,4 +172,40 @@ class Url extends ThinkUrl
|
|||||||
// URL 组装
|
// URL 组装
|
||||||
return $domain . rtrim($this->root, '/') . '/' . ltrim($url, '/');
|
return $domain . rtrim($this->root, '/') . '/' . ltrim($url, '/');
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
/**
|
||||||
|
* 直接解析 URL 地址
|
||||||
|
* @param string $url URL
|
||||||
|
* @param bool|string $domain Domain
|
||||||
|
*/
|
||||||
|
protected function parseUrl(string $url, &$domain): string
|
||||||
|
{
|
||||||
|
$request = $this->app->request;
|
||||||
|
if (strpos($url, '/') === 0) {
|
||||||
|
$url = substr($url, 1);
|
||||||
|
} elseif (strpos($url, '\\') !== false) {
|
||||||
|
$url = ltrim(str_replace('\\', '/', $url), '/');
|
||||||
|
} elseif (strpos($url, '@') === 0) {
|
||||||
|
$url = substr($url, 1);
|
||||||
|
} else {
|
||||||
|
$attrs = str2arr($url, '/');
|
||||||
|
$action = empty($attrs) ? $request->action() : array_pop($attrs);
|
||||||
|
$contrl = empty($attrs) ? $request->controller() : array_pop($attrs);
|
||||||
|
$module = empty($attrs) ? $this->app->http->getName() : array_pop($attrs);
|
||||||
|
// 拼装新的链接地址
|
||||||
|
$url = NodeService::nameTolower($contrl) . '/' . $action;
|
||||||
|
$bind = $this->app->config->get('app.domain_bind', []);
|
||||||
|
if ($key = array_search($module, $bind)) {
|
||||||
|
if (isset($bind[$_SERVER['SERVER_NAME']])) {
|
||||||
|
$domain = $_SERVER['SERVER_NAME'];
|
||||||
|
}
|
||||||
|
$domain = is_bool($domain) ? $key : $domain;
|
||||||
|
} elseif ($key = array_search($module, $this->app->config->get('app.app_map', []))) {
|
||||||
|
$url = $key . '/' . $url;
|
||||||
|
} else {
|
||||||
|
$url = $module . '/' . $url;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $url;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -1,38 +1,40 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// +----------------------------------------------------------------------
|
declare(strict_types=1);
|
||||||
// | Library for ThinkAdmin
|
/**
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 版权所有 2014~2025 ThinkAdmin [ thinkadmin.top ]
|
* | Payment Plugin for ThinkAdmin
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 官方网站: https://thinkadmin.top
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 开源协议 ( https://mit-license.org )
|
* | 官方网站: https://thinkadmin.top
|
||||||
// | 免费声明 ( https://thinkadmin.top/disclaimer )
|
* +----------------------------------------------------------------------
|
||||||
// +----------------------------------------------------------------------
|
* | 开源协议 ( https://mit-license.org )
|
||||||
// | gitee 仓库地址 :https://gitee.com/zoujingli/ThinkLibrary
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
// | github 仓库地址 :https://github.com/zoujingli/ThinkLibrary
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
declare (strict_types=1);
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
namespace think\admin\support\command;
|
namespace think\admin\support\command;
|
||||||
|
|
||||||
use think\admin\Command;
|
use think\admin\Command;
|
||||||
|
use think\admin\Exception;
|
||||||
use think\admin\service\SystemService;
|
use think\admin\service\SystemService;
|
||||||
use think\console\Input;
|
use think\console\Input;
|
||||||
use think\console\input\Argument;
|
use think\console\input\Argument;
|
||||||
use think\console\Output;
|
use think\console\Output;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 数据库修复优化指令
|
* 数据库修复优化指令.
|
||||||
* @class Database
|
* @class Database
|
||||||
* @package think\admin\support\command
|
|
||||||
*/
|
*/
|
||||||
class Database extends Command
|
class Database extends Command
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* 指令任务配置
|
* 指令任务配置.
|
||||||
*/
|
*/
|
||||||
public function configure()
|
public function configure()
|
||||||
{
|
{
|
||||||
@ -42,30 +44,29 @@ class Database extends Command
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 任务执行入口
|
* 任务执行入口.
|
||||||
* @param \think\console\Input $input
|
* @throws Exception
|
||||||
* @param \think\console\Output $output
|
|
||||||
* @return void
|
|
||||||
* @throws \think\admin\Exception
|
|
||||||
*/
|
*/
|
||||||
protected function execute(Input $input, Output $output): void
|
protected function execute(Input $input, Output $output): void
|
||||||
{
|
{
|
||||||
if ($this->app->db->connect()->getConfig('type') === 'sqlite') {
|
if ($this->app->db->connect()->getConfig('type') === 'sqlite') {
|
||||||
$this->setQueueError("Sqlite 数据库不支持 REPAIR 和 OPTIMIZE 操作!");
|
$this->setQueueError('Sqlite 数据库不支持 REPAIR 和 OPTIMIZE 操作!');
|
||||||
}
|
}
|
||||||
$action = $input->getArgument('action');
|
$action = $input->getArgument('action');
|
||||||
if (method_exists($this, $method = "_{$action}")) $this->$method();
|
if (method_exists($this, $method = "_{$action}")) {
|
||||||
else $this->output->error('Wrong operation, currently allow repair|optimize');
|
$this->{$method}();
|
||||||
|
} else {
|
||||||
|
$this->output->error('Wrong operation, currently allow repair|optimize');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 修复所有数据表
|
* 修复所有数据表.
|
||||||
* @return void
|
* @throws Exception
|
||||||
* @throws \think\admin\Exception
|
|
||||||
*/
|
*/
|
||||||
protected function _repair(): void
|
protected function _repair(): void
|
||||||
{
|
{
|
||||||
$this->setQueueProgress("正在获取需要修复的数据表", '0');
|
$this->setQueueProgress('正在获取需要修复的数据表', '0');
|
||||||
[$tables, $total, $count] = SystemService::getTables();
|
[$tables, $total, $count] = SystemService::getTables();
|
||||||
$this->setQueueProgress("总共需要修复 {$total} 张数据表", '0');
|
$this->setQueueProgress("总共需要修复 {$total} 张数据表", '0');
|
||||||
foreach ($tables as $table) {
|
foreach ($tables as $table) {
|
||||||
@ -77,13 +78,12 @@ class Database extends Command
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 优化所有数据表
|
* 优化所有数据表.
|
||||||
* @return void
|
* @throws Exception
|
||||||
* @throws \think\admin\Exception
|
|
||||||
*/
|
*/
|
||||||
protected function _optimize(): void
|
protected function _optimize(): void
|
||||||
{
|
{
|
||||||
$this->setQueueProgress("正在获取需要优化的数据表", '0');
|
$this->setQueueProgress('正在获取需要优化的数据表', '0');
|
||||||
[$tables, $total, $count] = SystemService::getTables();
|
[$tables, $total, $count] = SystemService::getTables();
|
||||||
$this->setQueueProgress("总共需要优化 {$total} 张数据表", '0');
|
$this->setQueueProgress("总共需要优化 {$total} 张数据表", '0');
|
||||||
foreach ($tables as $table) {
|
foreach ($tables as $table) {
|
||||||
@ -93,4 +93,4 @@ class Database extends Command
|
|||||||
}
|
}
|
||||||
$this->setQueueSuccess("已完成对 {$total} 张数据表优化操作");
|
$this->setQueueSuccess("已完成对 {$total} 张数据表优化操作");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,20 +1,22 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// +----------------------------------------------------------------------
|
declare(strict_types=1);
|
||||||
// | Library for ThinkAdmin
|
/**
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 版权所有 2014~2025 ThinkAdmin [ thinkadmin.top ]
|
* | Payment Plugin for ThinkAdmin
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 官方网站: https://thinkadmin.top
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 开源协议 ( https://mit-license.org )
|
* | 官方网站: https://thinkadmin.top
|
||||||
// | 免费声明 ( https://thinkadmin.top/disclaimer )
|
* +----------------------------------------------------------------------
|
||||||
// +----------------------------------------------------------------------
|
* | 开源协议 ( https://mit-license.org )
|
||||||
// | gitee 仓库地址 :https://gitee.com/zoujingli/ThinkLibrary
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
// | github 仓库地址 :https://github.com/zoujingli/ThinkLibrary
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
declare (strict_types=1);
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
namespace think\admin\support\command;
|
namespace think\admin\support\command;
|
||||||
|
|
||||||
@ -24,17 +26,18 @@ use think\admin\extend\PhinxExtend;
|
|||||||
use think\admin\Library;
|
use think\admin\Library;
|
||||||
use think\admin\service\SystemService;
|
use think\admin\service\SystemService;
|
||||||
use think\console\input\Option;
|
use think\console\input\Option;
|
||||||
|
use think\db\exception\DataNotFoundException;
|
||||||
|
use think\db\exception\DbException;
|
||||||
|
use think\db\exception\ModelNotFoundException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 生成数据安装包
|
* 生成数据安装包.
|
||||||
* @class Package
|
* @class Package
|
||||||
* @package think\admin\support\command
|
|
||||||
*/
|
*/
|
||||||
class Package extends Command
|
class Package extends Command
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* 系统指定配置
|
* 系统指定配置.
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public function configure()
|
public function configure()
|
||||||
{
|
{
|
||||||
@ -47,9 +50,8 @@ class Package extends Command
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 生成系统安装数据包
|
* 生成系统安装数据包.
|
||||||
* @return void
|
* @throws Exception
|
||||||
* @throws \think\admin\Exception
|
|
||||||
*/
|
*/
|
||||||
public function handle()
|
public function handle()
|
||||||
{
|
{
|
||||||
@ -73,8 +75,7 @@ class Package extends Command
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建数据表
|
* 创建数据表.
|
||||||
* @return boolean
|
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
private function createScheme(): bool
|
private function createScheme(): bool
|
||||||
@ -87,7 +88,9 @@ class Package extends Command
|
|||||||
[$tables] = SystemService::getTables();
|
[$tables] = SystemService::getTables();
|
||||||
} else {
|
} else {
|
||||||
$tables = Library::$sapp->config->get('phinx.tables', []);
|
$tables = Library::$sapp->config->get('phinx.tables', []);
|
||||||
if (empty($tables)) [$tables] = SystemService::getTables();
|
if (empty($tables)) {
|
||||||
|
[$tables] = SystemService::getTables();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 去除忽略的数据表
|
// 去除忽略的数据表
|
||||||
@ -98,7 +101,9 @@ class Package extends Command
|
|||||||
[$prefix, $groups] = ['', []];
|
[$prefix, $groups] = ['', []];
|
||||||
foreach ($tables as $table) {
|
foreach ($tables as $table) {
|
||||||
$attr = explode('_', $table);
|
$attr = explode('_', $table);
|
||||||
if ($attr[0] === 'plugin') array_shift($attr);
|
if ($attr[0] === 'plugin') {
|
||||||
|
array_shift($attr);
|
||||||
|
}
|
||||||
if (empty($prefix) || $prefix !== $attr[0]) {
|
if (empty($prefix) || $prefix !== $attr[0]) {
|
||||||
$prefix = $attr[0];
|
$prefix = $attr[0];
|
||||||
}
|
}
|
||||||
@ -121,12 +126,11 @@ class Package extends Command
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建数据包
|
* 创建数据包.
|
||||||
* @return boolean
|
* @throws Exception
|
||||||
* @throws \think\admin\Exception
|
* @throws DataNotFoundException
|
||||||
* @throws \think\db\exception\DataNotFoundException
|
* @throws DbException
|
||||||
* @throws \think\db\exception\DbException
|
* @throws ModelNotFoundException
|
||||||
* @throws \think\db\exception\ModelNotFoundException
|
|
||||||
*/
|
*/
|
||||||
private function createBackup(): bool
|
private function createBackup(): bool
|
||||||
{
|
{
|
||||||
@ -142,7 +146,9 @@ class Package extends Command
|
|||||||
|
|
||||||
// 去除忽略的数据表
|
// 去除忽略的数据表
|
||||||
$ignore = Library::$sapp->config->get('phinx.ignore', []);
|
$ignore = Library::$sapp->config->get('phinx.ignore', []);
|
||||||
if (empty($ignore)) $ignore = ['system_queue', 'system_oplog'];
|
if (empty($ignore)) {
|
||||||
|
$ignore = ['system_queue', 'system_oplog'];
|
||||||
|
}
|
||||||
$tables = array_unique(array_diff($tables, $ignore, ['migrations']));
|
$tables = array_unique(array_diff($tables, $ignore, ['migrations']));
|
||||||
|
|
||||||
// 创建数据库记录安装脚本
|
// 创建数据库记录安装脚本
|
||||||
@ -152,9 +158,8 @@ class Package extends Command
|
|||||||
if (file_put_contents($target, $phinx['text']) !== false) {
|
if (file_put_contents($target, $phinx['text']) !== false) {
|
||||||
$this->setQueueMessage(4, 2, '成功创建数据包安装脚本!');
|
$this->setQueueMessage(4, 2, '成功创建数据包安装脚本!');
|
||||||
return true;
|
return true;
|
||||||
} else {
|
|
||||||
$this->setQueueMessage(4, 2, '创建数据包安装脚本失败!');
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
$this->setQueueMessage(4, 2, '创建数据包安装脚本失败!');
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,20 +1,22 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// +----------------------------------------------------------------------
|
declare(strict_types=1);
|
||||||
// | Library for ThinkAdmin
|
/**
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 版权所有 2014~2025 ThinkAdmin [ thinkadmin.top ]
|
* | Payment Plugin for ThinkAdmin
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 官方网站: https://thinkadmin.top
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 开源协议 ( https://mit-license.org )
|
* | 官方网站: https://thinkadmin.top
|
||||||
// | 免费声明 ( https://thinkadmin.top/disclaimer )
|
* +----------------------------------------------------------------------
|
||||||
// +----------------------------------------------------------------------
|
* | 开源协议 ( https://mit-license.org )
|
||||||
// | gitee 仓库地址 :https://gitee.com/zoujingli/ThinkLibrary
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
// | github 仓库地址 :https://github.com/zoujingli/ThinkLibrary
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
declare (strict_types=1);
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
namespace think\admin\support\command;
|
namespace think\admin\support\command;
|
||||||
|
|
||||||
@ -27,16 +29,13 @@ use think\console\input\Option;
|
|||||||
use think\console\Output;
|
use think\console\Output;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 组件安装指令
|
* 组件安装指令.
|
||||||
* @class Publish
|
* @class Publish
|
||||||
* @package think\admin\support\command
|
|
||||||
*/
|
*/
|
||||||
class Publish extends Command
|
class Publish extends Command
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 任务参数配置
|
* 任务参数配置.
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public function configure()
|
public function configure()
|
||||||
{
|
{
|
||||||
@ -47,9 +46,7 @@ class Publish extends Command
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 任务合并执行
|
* 任务合并执行.
|
||||||
* @param \think\console\Input $input
|
|
||||||
* @param \think\console\Output $output
|
|
||||||
* @return null|void
|
* @return null|void
|
||||||
*/
|
*/
|
||||||
public function execute(Input $input, Output $output)
|
public function execute(Input $input, Output $output)
|
||||||
@ -59,7 +56,7 @@ class Publish extends Command
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 安装数据库
|
* 安装数据库.
|
||||||
* @return $this
|
* @return $this
|
||||||
*/
|
*/
|
||||||
private function plugin(): Publish
|
private function plugin(): Publish
|
||||||
@ -78,28 +75,27 @@ class Publish extends Command
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 初始化组件文件
|
* 初始化组件文件.
|
||||||
* @param string $copy 应用资源目录
|
* @param string $copy 应用资源目录
|
||||||
* @param boolean $force 是否强制替换
|
* @param bool $force 是否强制替换
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
private function copy(string $copy, bool $force = false)
|
private function copy(string $copy, bool $force = false)
|
||||||
{
|
{
|
||||||
// 复制系统配置文件
|
// 复制系统配置文件
|
||||||
$frdir = rtrim($copy, '\\/') . DIRECTORY_SEPARATOR . 'config';
|
$frdir = rtrim($copy, '\/') . DIRECTORY_SEPARATOR . 'config';
|
||||||
ToolsExtend::copy($frdir, syspath('config'), [], $force, false);
|
ToolsExtend::copy($frdir, syspath('config'), [], $force, false);
|
||||||
|
|
||||||
// 复制静态资料文件
|
// 复制静态资料文件
|
||||||
$frdir = rtrim($copy, '\\/') . DIRECTORY_SEPARATOR . 'public';
|
$frdir = rtrim($copy, '\/') . DIRECTORY_SEPARATOR . 'public';
|
||||||
ToolsExtend::copy($frdir, syspath('public'), [], true, false);
|
ToolsExtend::copy($frdir, syspath('public'), [], true, false);
|
||||||
|
|
||||||
// 复制数据库脚本
|
// 复制数据库脚本
|
||||||
$frdir = rtrim($copy, '\\/') . DIRECTORY_SEPARATOR . 'database';
|
$frdir = rtrim($copy, '\/') . DIRECTORY_SEPARATOR . 'database';
|
||||||
ToolsExtend::copy($frdir, syspath('database/migrations'), [], $force, false);
|
ToolsExtend::copy($frdir, syspath('database/migrations'), [], $force, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 解析 json 包
|
* 解析 json 包.
|
||||||
* @return $this
|
* @return $this
|
||||||
*/
|
*/
|
||||||
private function parse(): Publish
|
private function parse(): Publish
|
||||||
@ -112,16 +108,16 @@ class Publish extends Command
|
|||||||
$type = $package['type'] ?? '';
|
$type = $package['type'] ?? '';
|
||||||
$config = $package['extra']['config'] ?? [];
|
$config = $package['extra']['config'] ?? [];
|
||||||
$versions[$package['name']] = [
|
$versions[$package['name']] = [
|
||||||
'type' => $config['type'] ?? ($type === 'think-admin-plugin' ? 'plugin' : 'library'),
|
'type' => $config['type'] ?? ($type === 'think-admin-plugin' ? 'plugin' : 'library'),
|
||||||
'name' => $config['name'] ?? ($package['name'] ?? ''),
|
'name' => $config['name'] ?? ($package['name'] ?? ''),
|
||||||
'icon' => $config['icon'] ?? '',
|
'icon' => $config['icon'] ?? '',
|
||||||
'cover' => $config['cover'] ?? '',
|
'cover' => $config['cover'] ?? '',
|
||||||
'super' => $config['super'] ?? false,
|
'super' => $config['super'] ?? false,
|
||||||
'license' => (array)($config['license'] ?? ($package['license'] ?? [])),
|
'license' => (array)($config['license'] ?? ($package['license'] ?? [])),
|
||||||
'version' => $config['version'] ?? ($package['version'] ?? ''),
|
'version' => $config['version'] ?? ($package['version'] ?? ''),
|
||||||
'homepage' => $config['homepage'] ?? ($package['homepage'] ?? ''),
|
'homepage' => $config['homepage'] ?? ($package['homepage'] ?? ''),
|
||||||
'document' => $config['document'] ?? ($package['document'] ?? ''),
|
'document' => $config['document'] ?? ($package['document'] ?? ''),
|
||||||
'platforms' => $config['platforms'] ?? [],
|
'platforms' => $config['platforms'] ?? [],
|
||||||
'description' => $config['description'] ?? ($package['description'] ?? ''),
|
'description' => $config['description'] ?? ($package['description'] ?? ''),
|
||||||
];
|
];
|
||||||
// 生成服务配置
|
// 生成服务配置
|
||||||
@ -148,7 +144,7 @@ class Publish extends Command
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 写入服务配置
|
// 写入服务配置
|
||||||
$header = "// Automatically Generated At: " . date('Y-m-d H:i:s') . PHP_EOL . 'declare(strict_types=1);';
|
$header = '// Automatically Generated At: ' . date('Y-m-d H:i:s') . PHP_EOL . 'declare(strict_types=1);';
|
||||||
$content = '<?php' . PHP_EOL . $header . PHP_EOL . 'return ' . var_export($services, true) . ';';
|
$content = '<?php' . PHP_EOL . $header . PHP_EOL . 'return ' . var_export($services, true) . ';';
|
||||||
@file_put_contents(syspath('vendor/services.php'), $content);
|
@file_put_contents(syspath('vendor/services.php'), $content);
|
||||||
|
|
||||||
@ -158,4 +154,4 @@ class Publish extends Command
|
|||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,25 +1,25 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// +----------------------------------------------------------------------
|
declare(strict_types=1);
|
||||||
// | Library for ThinkAdmin
|
/**
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 版权所有 2014~2025 ThinkAdmin [ thinkadmin.top ]
|
* | Payment Plugin for ThinkAdmin
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 官方网站: https://thinkadmin.top
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 开源协议 ( https://mit-license.org )
|
* | 官方网站: https://thinkadmin.top
|
||||||
// | 免费声明 ( https://thinkadmin.top/disclaimer )
|
* +----------------------------------------------------------------------
|
||||||
// +----------------------------------------------------------------------
|
* | 开源协议 ( https://mit-license.org )
|
||||||
// | gitee 仓库地址 :https://gitee.com/zoujingli/ThinkLibrary
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
// | github 仓库地址 :https://github.com/zoujingli/ThinkLibrary
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
declare (strict_types=1);
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
namespace think\admin\support\command;
|
namespace think\admin\support\command;
|
||||||
|
|
||||||
use Error;
|
|
||||||
use Exception;
|
|
||||||
use Psr\Log\NullLogger;
|
use Psr\Log\NullLogger;
|
||||||
use think\admin\Command;
|
use think\admin\Command;
|
||||||
use think\admin\model\SystemQueue;
|
use think\admin\model\SystemQueue;
|
||||||
@ -28,54 +28,54 @@ use think\console\Input;
|
|||||||
use think\console\input\Argument;
|
use think\console\input\Argument;
|
||||||
use think\console\input\Option;
|
use think\console\input\Option;
|
||||||
use think\console\Output;
|
use think\console\Output;
|
||||||
use Throwable;
|
use think\db\exception\DataNotFoundException;
|
||||||
|
use think\db\exception\DbException;
|
||||||
|
use think\db\exception\ModelNotFoundException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 异步任务管理指令
|
* 异步任务管理指令.
|
||||||
* @class Queue
|
* @class Queue
|
||||||
* @package think\admin\support\command
|
|
||||||
*/
|
*/
|
||||||
class Queue extends Command
|
class Queue extends Command
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 任务等待处理
|
* 任务等待处理.
|
||||||
* @var integer
|
* @var int
|
||||||
*/
|
*/
|
||||||
const STATE_WAIT = 1;
|
public const STATE_WAIT = 1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 任务正在处理
|
* 任务正在处理.
|
||||||
* @var integer
|
* @var int
|
||||||
*/
|
*/
|
||||||
const STATE_LOCK = 2;
|
public const STATE_LOCK = 2;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 任务处理完成
|
* 任务处理完成.
|
||||||
* @var integer
|
* @var int
|
||||||
*/
|
*/
|
||||||
const STATE_DONE = 3;
|
public const STATE_DONE = 3;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 任务处理失败
|
* 任务处理失败.
|
||||||
* @var integer
|
* @var int
|
||||||
*/
|
*/
|
||||||
const STATE_ERROR = 4;
|
public const STATE_ERROR = 4;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 监听进程指令
|
* 监听进程指令.
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
const QUEUE_LISTEN = 'xadmin:queue listen';
|
public const QUEUE_LISTEN = 'xadmin:queue listen';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 当前任务编号
|
* 当前任务编号.
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
protected $code;
|
protected $code;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 指令任务配置
|
* 指令任务配置.
|
||||||
*/
|
*/
|
||||||
public function configure()
|
public function configure()
|
||||||
{
|
{
|
||||||
@ -90,34 +90,35 @@ class Queue extends Command
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 任务执行入口
|
* 任务执行入口.
|
||||||
* @param Input $input
|
|
||||||
* @param Output $output
|
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
protected function execute(Input $input, Output $output)
|
protected function execute(Input $input, Output $output)
|
||||||
{
|
{
|
||||||
$action = $input->hasOption('daemon') ? 'start' : $input->getArgument('action');
|
$action = $input->hasOption('daemon') ? 'start' : $input->getArgument('action');
|
||||||
if (method_exists($this, $method = "{$action}Action")) return $this->$method();
|
if (method_exists($this, $method = "{$action}Action")) {
|
||||||
$this->output->error("># Wrong operation, Allow stop|start|status|query|listen|clean|dorun|webstop|webstart|webstatus");
|
return $this->{$method}();
|
||||||
|
}
|
||||||
|
$this->output->error('># Wrong operation, Allow stop|start|status|query|listen|clean|dorun|webstop|webstart|webstatus');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 停止 WebServer 调试进程
|
* 停止 WebServer 调试进程.
|
||||||
*/
|
*/
|
||||||
protected function webStopAction()
|
protected function webStopAction()
|
||||||
{
|
{
|
||||||
$root = syspath('public/');
|
$root = syspath('public/');
|
||||||
if (count($result = $this->process->query("{$root} {$root}router.php")) < 1) {
|
if (count($result = $this->process->query("{$root} {$root}router.php")) < 1) {
|
||||||
$this->output->writeln("># There are no WebServer processes to stop");
|
$this->output->writeln('># There are no WebServer processes to stop');
|
||||||
} else foreach ($result as $item) {
|
} else {
|
||||||
$this->process->close(intval($item['pid']));
|
foreach ($result as $item) {
|
||||||
$this->output->writeln("># Successfully sent end signal to process {$item['pid']}");
|
$this->process->close(intval($item['pid']));
|
||||||
|
$this->output->writeln("># Successfully sent end signal to process {$item['pid']}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 启动 WebServer 调试进程
|
* 启动 WebServer 调试进程.
|
||||||
*/
|
*/
|
||||||
protected function webStartAction()
|
protected function webStartAction()
|
||||||
{
|
{
|
||||||
@ -128,13 +129,17 @@ class Queue extends Command
|
|||||||
$command = "php -S {$host}:{$port} -t {$root} {$root}router.php";
|
$command = "php -S {$host}:{$port} -t {$root} {$root}router.php";
|
||||||
$this->output->comment(">$ {$command}");
|
$this->output->comment(">$ {$command}");
|
||||||
if (count($result = $this->process->query($command)) > 0) {
|
if (count($result = $this->process->query($command)) > 0) {
|
||||||
if ($this->process->isWin()) $this->process->exec("start {$prot}://{$host}:{$port}");
|
if ($this->process->isWin()) {
|
||||||
|
$this->process->exec("start {$prot}://{$host}:{$port}");
|
||||||
|
}
|
||||||
$this->output->writeln("># WebServer process already exist for pid {$result[0]['pid']}");
|
$this->output->writeln("># WebServer process already exist for pid {$result[0]['pid']}");
|
||||||
} else {
|
} else {
|
||||||
$this->process->create($command, 2000);
|
$this->process->create($command, 2000);
|
||||||
if (count($result = $this->process->query($command)) > 0) {
|
if (count($result = $this->process->query($command)) > 0) {
|
||||||
$this->output->writeln("># WebServer process started successfully for pid {$result[0]['pid']}");
|
$this->output->writeln("># WebServer process started successfully for pid {$result[0]['pid']}");
|
||||||
if ($this->process->isWin()) $this->process->exec("start {$prot}://{$host}:{$port}");
|
if ($this->process->isWin()) {
|
||||||
|
$this->process->exec("start {$prot}://{$host}:{$port}");
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
$this->output->writeln('># WebServer process failed to start');
|
$this->output->writeln('># WebServer process failed to start');
|
||||||
}
|
}
|
||||||
@ -142,7 +147,7 @@ class Queue extends Command
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查看 WebServer 调试进程
|
* 查看 WebServer 调试进程.
|
||||||
*/
|
*/
|
||||||
protected function webStatusAction()
|
protected function webStatusAction()
|
||||||
{
|
{
|
||||||
@ -151,7 +156,7 @@ class Queue extends Command
|
|||||||
$this->output->comment(">$ {$result[0]['cmd']}");
|
$this->output->comment(">$ {$result[0]['cmd']}");
|
||||||
$this->output->writeln("># WebServer process {$result[0]['pid']} running");
|
$this->output->writeln("># WebServer process {$result[0]['pid']} running");
|
||||||
} else {
|
} else {
|
||||||
$this->output->writeln("># The WebServer process is not running");
|
$this->output->writeln('># The WebServer process is not running');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -161,18 +166,20 @@ class Queue extends Command
|
|||||||
protected function stopAction()
|
protected function stopAction()
|
||||||
{
|
{
|
||||||
if (count($result = $this->process->thinkQuery('xadmin:queue')) < 1) {
|
if (count($result = $this->process->thinkQuery('xadmin:queue')) < 1) {
|
||||||
$this->output->writeln("># There are no task processes to stop");
|
$this->output->writeln('># There are no task processes to stop');
|
||||||
} else foreach ($result as $item) {
|
} else {
|
||||||
$this->process->close(intval($item['pid']));
|
foreach ($result as $item) {
|
||||||
$this->output->writeln("># Successfully sent end signal to process {$item['pid']}");
|
$this->process->close(intval($item['pid']));
|
||||||
|
$this->output->writeln("># Successfully sent end signal to process {$item['pid']}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 启动后台任务
|
* 启动后台任务
|
||||||
* @throws \think\db\exception\DataNotFoundException
|
* @throws DataNotFoundException
|
||||||
* @throws \think\db\exception\DbException
|
* @throws DbException
|
||||||
* @throws \think\db\exception\ModelNotFoundException
|
* @throws ModelNotFoundException
|
||||||
*/
|
*/
|
||||||
protected function startAction()
|
protected function startAction()
|
||||||
{
|
{
|
||||||
@ -180,7 +187,7 @@ class Queue extends Command
|
|||||||
$this->output->comment(">$ {$this->process->think(static::QUEUE_LISTEN)}");
|
$this->output->comment(">$ {$this->process->think(static::QUEUE_LISTEN)}");
|
||||||
if (count($result = $this->process->thinkQuery(static::QUEUE_LISTEN)) > 0) {
|
if (count($result = $this->process->thinkQuery(static::QUEUE_LISTEN)) > 0) {
|
||||||
if (is_file($lock = syspath('runtime/cache/time.queue')) && intval(file_get_contents($lock)) + 60 < time()) {
|
if (is_file($lock = syspath('runtime/cache/time.queue')) && intval(file_get_contents($lock)) + 60 < time()) {
|
||||||
$this->output->writeln("># The task monitoring delay has exceeded 60 seconds, and the monitoring will be restarted.");
|
$this->output->writeln('># The task monitoring delay has exceeded 60 seconds, and the monitoring will be restarted.');
|
||||||
$this->process->close(intval($result[0]['pid'])) && $this->process->thinkExec(static::QUEUE_LISTEN, 1000);
|
$this->process->close(intval($result[0]['pid'])) && $this->process->thinkExec(static::QUEUE_LISTEN, 1000);
|
||||||
} else {
|
} else {
|
||||||
$this->output->writeln("># Queue daemons already exist for pid {$result[0]['pid']}");
|
$this->output->writeln("># Queue daemons already exist for pid {$result[0]['pid']}");
|
||||||
@ -190,7 +197,7 @@ class Queue extends Command
|
|||||||
if (count($result = $this->process->thinkQuery(static::QUEUE_LISTEN)) > 0) {
|
if (count($result = $this->process->thinkQuery(static::QUEUE_LISTEN)) > 0) {
|
||||||
$this->output->writeln("># Queue daemons started successfully for pid {$result[0]['pid']}");
|
$this->output->writeln("># Queue daemons started successfully for pid {$result[0]['pid']}");
|
||||||
} else {
|
} else {
|
||||||
$this->output->writeln("># Queue daemons failed to start");
|
$this->output->writeln('># Queue daemons failed to start');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -201,8 +208,10 @@ class Queue extends Command
|
|||||||
protected function queryAction()
|
protected function queryAction()
|
||||||
{
|
{
|
||||||
$items = $this->process->thinkQuery('xadmin:queue');
|
$items = $this->process->thinkQuery('xadmin:queue');
|
||||||
if (count($items) > 0) foreach ($items as $item) {
|
if (count($items) > 0) {
|
||||||
$this->output->writeln("># {$item['pid']}\t{$item['cmd']}");
|
foreach ($items as $item) {
|
||||||
|
$this->output->writeln("># {$item['pid']}\t{$item['cmd']}");
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
$this->output->writeln('># No related task process found');
|
$this->output->writeln('># No related task process found');
|
||||||
}
|
}
|
||||||
@ -211,7 +220,7 @@ class Queue extends Command
|
|||||||
/**
|
/**
|
||||||
* 清理所有任务
|
* 清理所有任务
|
||||||
* @throws \think\admin\Exception
|
* @throws \think\admin\Exception
|
||||||
* @throws \think\db\exception\DbException
|
* @throws DbException
|
||||||
*/
|
*/
|
||||||
protected function cleanAction()
|
protected function cleanAction()
|
||||||
{
|
{
|
||||||
@ -244,13 +253,12 @@ class Queue extends Command
|
|||||||
if (count($result = $this->process->thinkQuery(static::QUEUE_LISTEN)) > 0) {
|
if (count($result = $this->process->thinkQuery(static::QUEUE_LISTEN)) > 0) {
|
||||||
$this->output->writeln("Listening for main process {$result[0]['pid']} running");
|
$this->output->writeln("Listening for main process {$result[0]['pid']} running");
|
||||||
} else {
|
} else {
|
||||||
$this->output->writeln("The Listening main process is not running");
|
$this->output->writeln('The Listening main process is not running');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 启动任务监听
|
* 启动任务监听.
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
protected function listenAction()
|
protected function listenAction()
|
||||||
{
|
{
|
||||||
@ -258,7 +266,7 @@ class Queue extends Command
|
|||||||
set_time_limit(0) && PHP_SAPI !== 'cli' && ignore_user_abort(true);
|
set_time_limit(0) && PHP_SAPI !== 'cli' && ignore_user_abort(true);
|
||||||
$this->app->db->setLog(new NullLogger());
|
$this->app->db->setLog(new NullLogger());
|
||||||
$this->createListenProcess();
|
$this->createListenProcess();
|
||||||
} catch (Exception $exception) {
|
} catch (\Exception $exception) {
|
||||||
trace_file($exception) && usleep(3000000);
|
trace_file($exception) && usleep(3000000);
|
||||||
$this->output->write('=============== EXCEPTION ===============');
|
$this->output->write('=============== EXCEPTION ===============');
|
||||||
$this->output->write($exception->getMessage());
|
$this->output->write($exception->getMessage());
|
||||||
@ -268,8 +276,56 @@ class Queue extends Command
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 执行任务监听
|
* 执行指定任务
|
||||||
* @return void
|
* @throws \think\admin\Exception
|
||||||
|
*/
|
||||||
|
protected function doRunAction()
|
||||||
|
{
|
||||||
|
$this->code = trim($this->input->getArgument('code'));
|
||||||
|
if (empty($this->code)) {
|
||||||
|
$this->output->error('Task number needs to be specified for task execution');
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
set_time_limit(0) && PHP_SAPI !== 'cli' && ignore_user_abort(true);
|
||||||
|
$this->queue->initialize($this->code);
|
||||||
|
if (empty($this->queue->record) || intval($this->queue->record->getAttr('status')) !== static::STATE_WAIT) {
|
||||||
|
// 这里不做任何处理(该任务可能在其它地方已经在执行)
|
||||||
|
$this->output->warning("The or status of task {$this->code} is abnormal");
|
||||||
|
} else {
|
||||||
|
// 锁定任务状态,防止任务再次被执行
|
||||||
|
SystemQueue::mk()->strict(false)->where(['code' => $this->code])->inc('attempts')->update([
|
||||||
|
'enter_time' => microtime(true), 'outer_time' => 0, 'exec_pid' => getmypid(), 'exec_desc' => '', 'status' => static::STATE_LOCK,
|
||||||
|
]);
|
||||||
|
$this->queue->progress(2, '>>> 任务处理开始 <<<', '0');
|
||||||
|
// 执行任务内容
|
||||||
|
defined('WorkQueueCall') or define('WorkQueueCall', true);
|
||||||
|
defined('WorkQueueCode') or define('WorkQueueCode', $this->code);
|
||||||
|
if (class_exists($command = $this->queue->record->getAttr('command'))) {
|
||||||
|
// 自定义任务,支持返回消息(支持异常结束,异常码可选择 3|4 设置任务状态)
|
||||||
|
/* @var \think\admin\Queue|QueueService $class */
|
||||||
|
$class = $this->app->make($command, [], true);
|
||||||
|
if ($class instanceof \think\admin\Queue) {
|
||||||
|
$this->updateQueue(static::STATE_DONE, $class->initialize($this->queue)->execute($this->queue->data) ?: '');
|
||||||
|
} elseif ($class instanceof QueueService) {
|
||||||
|
$this->updateQueue(static::STATE_DONE, $class->initialize($this->queue->code)->execute($this->queue->data) ?: '');
|
||||||
|
} else {
|
||||||
|
throw new \think\admin\Exception("自定义 {$command} 未继承 think\\admin\\Queue 或 think\\admin\\service\\QueueService");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 自定义指令,不支持返回消息(支持异常结束,异常码可选择 3|4 设置任务状态)
|
||||||
|
$attr = explode(' ', trim(preg_replace('|\s+|', ' ', $command)));
|
||||||
|
$this->updateQueue(static::STATE_DONE, $this->app->console->call(array_shift($attr), $attr)->fetch(), false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (\Error|\Exception|\Throwable $exception) {
|
||||||
|
$isDone = intval($exception->getCode()) === static::STATE_DONE;
|
||||||
|
$this->updateQueue($isDone ? static::STATE_DONE : static::STATE_ERROR, $exception->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行任务监听.
|
||||||
*/
|
*/
|
||||||
private function createListenProcess()
|
private function createListenProcess()
|
||||||
{
|
{
|
||||||
@ -278,76 +334,32 @@ class Queue extends Command
|
|||||||
while (true) {
|
while (true) {
|
||||||
@file_put_contents(syspath('runtime/cache/time.queue'), strval(time()));
|
@file_put_contents(syspath('runtime/cache/time.queue'), strval(time()));
|
||||||
[$map, $start] = [[['status', '=', static::STATE_WAIT], ['exec_time', '<=', time()]], microtime(true)];
|
[$map, $start] = [[['status', '=', static::STATE_WAIT], ['exec_time', '<=', time()]], microtime(true)];
|
||||||
foreach (SystemQueue::mk()->where($map)->order('exec_time asc')->cursor() as $queue) try {
|
foreach (SystemQueue::mk()->where($map)->order('exec_time asc')->cursor() as $queue) {
|
||||||
$args = "xadmin:queue dorun {$queue['code']} -";
|
try {
|
||||||
$this->output->comment(">$ {$this->process->think($args)}");
|
$args = "xadmin:queue dorun {$queue['code']} -";
|
||||||
if (count($this->process->thinkQuery($args)) > 0) {
|
$this->output->comment(">$ {$this->process->think($args)}");
|
||||||
$this->output->writeln("># Already in progress -> [{$queue['code']}] {$queue['title']}");
|
if (count($this->process->thinkQuery($args)) > 0) {
|
||||||
} else {
|
$this->output->writeln("># Already in progress -> [{$queue['code']}] {$queue['title']}");
|
||||||
$this->process->thinkExec($args);
|
|
||||||
$this->output->writeln("># Created new process -> [{$queue['code']}] {$queue['title']}");
|
|
||||||
}
|
|
||||||
} catch (Exception $exception) {
|
|
||||||
$queue->save(['status' => static::STATE_ERROR, 'outer_time' => time(), 'exec_desc' => $exception->getMessage()]);
|
|
||||||
$this->output->error("># Execution failed -> [{$queue['code']}] {$queue['title']},{$exception->getMessage()}");
|
|
||||||
}
|
|
||||||
if (microtime(true) < $start + 1) usleep(1000000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 执行指定任务
|
|
||||||
* @return void
|
|
||||||
* @throws \think\admin\Exception
|
|
||||||
*/
|
|
||||||
protected function doRunAction()
|
|
||||||
{
|
|
||||||
$this->code = trim($this->input->getArgument('code'));
|
|
||||||
if (empty($this->code)) {
|
|
||||||
$this->output->error('Task number needs to be specified for task execution');
|
|
||||||
} else try {
|
|
||||||
set_time_limit(0) && PHP_SAPI !== 'cli' && ignore_user_abort(true);
|
|
||||||
$this->queue->initialize($this->code);
|
|
||||||
if (empty($this->queue->record) || intval($this->queue->record->getAttr('status')) !== static::STATE_WAIT) {
|
|
||||||
// 这里不做任何处理(该任务可能在其它地方已经在执行)
|
|
||||||
$this->output->warning("The or status of task {$this->code} is abnormal");
|
|
||||||
} else {
|
|
||||||
// 锁定任务状态,防止任务再次被执行
|
|
||||||
SystemQueue::mk()->strict(false)->where(['code' => $this->code])->inc('attempts')->update([
|
|
||||||
'enter_time' => microtime(true), 'outer_time' => 0, 'exec_pid' => getmypid(), 'exec_desc' => '', 'status' => static::STATE_LOCK,
|
|
||||||
]);
|
|
||||||
$this->queue->progress(2, '>>> 任务处理开始 <<<', '0');
|
|
||||||
// 执行任务内容
|
|
||||||
defined('WorkQueueCall') or define('WorkQueueCall', true);
|
|
||||||
defined('WorkQueueCode') or define('WorkQueueCode', $this->code);
|
|
||||||
if (class_exists($command = $this->queue->record->getAttr('command'))) {
|
|
||||||
// 自定义任务,支持返回消息(支持异常结束,异常码可选择 3|4 设置任务状态)
|
|
||||||
/**@var \think\admin\Queue|QueueService $class */
|
|
||||||
$class = $this->app->make($command, [], true);
|
|
||||||
if ($class instanceof \think\admin\Queue) {
|
|
||||||
$this->updateQueue(static::STATE_DONE, $class->initialize($this->queue)->execute($this->queue->data) ?: '');
|
|
||||||
} elseif ($class instanceof QueueService) {
|
|
||||||
$this->updateQueue(static::STATE_DONE, $class->initialize($this->queue->code)->execute($this->queue->data) ?: '');
|
|
||||||
} else {
|
} else {
|
||||||
throw new \think\admin\Exception("自定义 {$command} 未继承 think\admin\Queue 或 think\admin\service\QueueService");
|
$this->process->thinkExec($args);
|
||||||
|
$this->output->writeln("># Created new process -> [{$queue['code']}] {$queue['title']}");
|
||||||
}
|
}
|
||||||
} else {
|
} catch (\Exception $exception) {
|
||||||
// 自定义指令,不支持返回消息(支持异常结束,异常码可选择 3|4 设置任务状态)
|
$queue->save(['status' => static::STATE_ERROR, 'outer_time' => time(), 'exec_desc' => $exception->getMessage()]);
|
||||||
$attr = explode(' ', trim(preg_replace('|\s+|', ' ', $command)));
|
$this->output->error("># Execution failed -> [{$queue['code']}] {$queue['title']},{$exception->getMessage()}");
|
||||||
$this->updateQueue(static::STATE_DONE, $this->app->console->call(array_shift($attr), $attr)->fetch(), false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (Exception|Throwable|Error $exception) {
|
if (microtime(true) < $start + 1) {
|
||||||
$isDone = intval($exception->getCode()) === static::STATE_DONE;
|
usleep(1000000);
|
||||||
$this->updateQueue($isDone ? static::STATE_DONE : static::STATE_ERROR, $exception->getMessage());
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 修改当前任务状态
|
* 修改当前任务状态
|
||||||
* @param integer $status 任务状态
|
* @param int $status 任务状态
|
||||||
* @param string $message 消息内容
|
* @param string $message 消息内容
|
||||||
* @param boolean $isSplit 是否分隔
|
* @param bool $isSplit 是否分隔
|
||||||
* @throws \think\admin\Exception
|
* @throws \think\admin\Exception
|
||||||
*/
|
*/
|
||||||
private function updateQueue(int $status, string $message, bool $isSplit = true)
|
private function updateQueue(int $status, string $message, bool $isSplit = true)
|
||||||
@ -369,10 +381,12 @@ class Queue extends Command
|
|||||||
$this->queue->progress($status, '>>> 任务处理失败 <<<');
|
$this->queue->progress($status, '>>> 任务处理失败 <<<');
|
||||||
}
|
}
|
||||||
// 注册循环任务
|
// 注册循环任务
|
||||||
if (($time = intval($this->queue->record->getAttr('loops_time'))) > 0) try {
|
if (($time = intval($this->queue->record->getAttr('loops_time'))) > 0) {
|
||||||
$this->queue->initialize($this->code)->reset($time);
|
try {
|
||||||
} catch (Exception|Throwable|Error $exception) {
|
$this->queue->initialize($this->code)->reset($time);
|
||||||
$this->app->log->error("Queue {$this->queue->record->getAttr('code')} Loops Failed. {$exception->getMessage()}");
|
} catch (\Error|\Exception|\Throwable $exception) {
|
||||||
|
$this->app->log->error("Queue {$this->queue->record->getAttr('code')} Loops Failed. {$exception->getMessage()}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,39 +1,42 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// +----------------------------------------------------------------------
|
declare(strict_types=1);
|
||||||
// | Library for ThinkAdmin
|
/**
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 版权所有 2014~2025 ThinkAdmin [ thinkadmin.top ]
|
* | Payment Plugin for ThinkAdmin
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 官方网站: https://thinkadmin.top
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 开源协议 ( https://mit-license.org )
|
* | 官方网站: https://thinkadmin.top
|
||||||
// | 免费声明 ( https://thinkadmin.top/disclaimer )
|
* +----------------------------------------------------------------------
|
||||||
// +----------------------------------------------------------------------
|
* | 开源协议 ( https://mit-license.org )
|
||||||
// | gitee 仓库地址 :https://gitee.com/zoujingli/ThinkLibrary
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
// | github 仓库地址 :https://github.com/zoujingli/ThinkLibrary
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
declare (strict_types=1);
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
namespace think\admin\support\command;
|
namespace think\admin\support\command;
|
||||||
|
|
||||||
use think\admin\Command;
|
use think\admin\Command;
|
||||||
|
use think\admin\Exception;
|
||||||
use think\admin\service\SystemService;
|
use think\admin\service\SystemService;
|
||||||
use think\console\Input;
|
use think\console\Input;
|
||||||
use think\console\input\Argument;
|
use think\console\input\Argument;
|
||||||
use think\console\Output;
|
use think\console\Output;
|
||||||
|
use think\db\exception\DbException;
|
||||||
use think\helper\Str;
|
use think\helper\Str;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 数据库字符替换
|
* 数据库字符替换.
|
||||||
* @class Replace
|
* @class Replace
|
||||||
* @package think\admin\support\command
|
|
||||||
*/
|
*/
|
||||||
class Replace extends Command
|
class Replace extends Command
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* 指令任务配置
|
* 指令任务配置.
|
||||||
*/
|
*/
|
||||||
protected function configure()
|
protected function configure()
|
||||||
{
|
{
|
||||||
@ -44,23 +47,24 @@ class Replace extends Command
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 任务执行入口
|
* 任务执行入口.
|
||||||
* @param \think\console\Input $input
|
* @throws Exception
|
||||||
* @param \think\console\Output $output
|
* @throws DbException
|
||||||
* @return void
|
|
||||||
* @throws \think\admin\Exception
|
|
||||||
* @throws \think\db\exception\DbException
|
|
||||||
*/
|
*/
|
||||||
protected function execute(Input $input, Output $output)
|
protected function execute(Input $input, Output $output)
|
||||||
{
|
{
|
||||||
$search = $input->getArgument('search');
|
$search = $input->getArgument('search');
|
||||||
$repalce = $input->getArgument('replace');
|
$repalce = $input->getArgument('replace');
|
||||||
if ($search === '') $this->setQueueError('查找替换字符内容不能为空!');
|
if ($search === '') {
|
||||||
if ($repalce === '') $this->setQueueError('目标替换字符内容不能为空!');
|
$this->setQueueError('查找替换字符内容不能为空!');
|
||||||
|
}
|
||||||
|
if ($repalce === '') {
|
||||||
|
$this->setQueueError('目标替换字符内容不能为空!');
|
||||||
|
}
|
||||||
[$tables, $total, $count] = SystemService::getTables();
|
[$tables, $total, $count] = SystemService::getTables();
|
||||||
foreach ($tables as $table) {
|
foreach ($tables as $table) {
|
||||||
$data = [];
|
$data = [];
|
||||||
$this->setQueueMessage($total, ++$count, sprintf("准备替换数据表 %s", Str::studly($table)));
|
$this->setQueueMessage($total, ++$count, sprintf('准备替换数据表 %s', Str::studly($table)));
|
||||||
foreach ($this->app->db->table($table)->getFields() as $field => $attrs) {
|
foreach ($this->app->db->table($table)->getFields() as $field => $attrs) {
|
||||||
if (preg_match('/char|text/', $attrs['type'])) {
|
if (preg_match('/char|text/', $attrs['type'])) {
|
||||||
$data[$field] = $this->app->db->raw(sprintf('REPLACE(`%s`,"%s","%s")', $field, $search, $repalce));
|
$data[$field] = $this->app->db->raw(sprintf('REPLACE(`%s`,"%s","%s")', $field, $search, $repalce));
|
||||||
@ -68,11 +72,11 @@ class Replace extends Command
|
|||||||
}
|
}
|
||||||
if (count($data) > 0) {
|
if (count($data) > 0) {
|
||||||
$this->app->db->table($table)->master()->where('1=1')->update($data);
|
$this->app->db->table($table)->master()->where('1=1')->update($data);
|
||||||
$this->setQueueMessage($total, $count, sprintf("成功替换数据表 %s", Str::studly($table)), 1);
|
$this->setQueueMessage($total, $count, sprintf('成功替换数据表 %s', Str::studly($table)), 1);
|
||||||
} else {
|
} else {
|
||||||
$this->setQueueMessage($total, $count, sprintf("无需替换数据表 %s", Str::studly($table)), 1);
|
$this->setQueueMessage($total, $count, sprintf('无需替换数据表 %s', Str::studly($table)), 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$this->setQueueSuccess("批量替换 {$total} 张数据表成功");
|
$this->setQueueSuccess("批量替换 {$total} 张数据表成功");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,36 +1,41 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// +----------------------------------------------------------------------
|
declare(strict_types=1);
|
||||||
// | Library for ThinkAdmin
|
/**
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 版权所有 2014~2025 ThinkAdmin [ thinkadmin.top ]
|
* | Payment Plugin for ThinkAdmin
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 官方网站: https://thinkadmin.top
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 开源协议 ( https://mit-license.org )
|
* | 官方网站: https://thinkadmin.top
|
||||||
// | 免费声明 ( https://thinkadmin.top/disclaimer )
|
* +----------------------------------------------------------------------
|
||||||
// +----------------------------------------------------------------------
|
* | 开源协议 ( https://mit-license.org )
|
||||||
// | gitee 仓库地址 :https://gitee.com/zoujingli/ThinkLibrary
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
// | github 仓库地址 :https://github.com/zoujingli/ThinkLibrary
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
declare (strict_types=1);
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
namespace think\admin\support\command;
|
namespace think\admin\support\command;
|
||||||
|
|
||||||
use think\admin\Command;
|
use think\admin\Command;
|
||||||
|
use think\admin\Exception;
|
||||||
use think\admin\extend\DataExtend;
|
use think\admin\extend\DataExtend;
|
||||||
use think\admin\model\SystemMenu;
|
use think\admin\model\SystemMenu;
|
||||||
|
use think\db\exception\DataNotFoundException;
|
||||||
|
use think\db\exception\DbException;
|
||||||
|
use think\db\exception\ModelNotFoundException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 重置并清理系统菜单
|
* 重置并清理系统菜单.
|
||||||
* @class Sysmenu
|
* @class Sysmenu
|
||||||
* @package think\admin\support\command
|
|
||||||
*/
|
*/
|
||||||
class Sysmenu extends Command
|
class Sysmenu extends Command
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* 指令任务配置
|
* 指令任务配置.
|
||||||
*/
|
*/
|
||||||
public function configure()
|
public function configure()
|
||||||
{
|
{
|
||||||
@ -39,12 +44,11 @@ class Sysmenu extends Command
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 任务执行入口
|
* 任务执行入口.
|
||||||
* @return void
|
* @throws Exception
|
||||||
* @throws \think\admin\Exception
|
* @throws DataNotFoundException
|
||||||
* @throws \think\db\exception\DataNotFoundException
|
* @throws DbException
|
||||||
* @throws \think\db\exception\DbException
|
* @throws ModelNotFoundException
|
||||||
* @throws \think\db\exception\ModelNotFoundException
|
|
||||||
*/
|
*/
|
||||||
public function handle()
|
public function handle()
|
||||||
{
|
{
|
||||||
@ -55,20 +59,24 @@ class Sysmenu extends Command
|
|||||||
foreach (DataExtend::arr2tree($menus) as $sub1) {
|
foreach (DataExtend::arr2tree($menus) as $sub1) {
|
||||||
$pid1 = $this->write($sub1);
|
$pid1 = $this->write($sub1);
|
||||||
$this->setQueueMessage($total, ++$count, "重写1级菜单:{$sub1['title']}");
|
$this->setQueueMessage($total, ++$count, "重写1级菜单:{$sub1['title']}");
|
||||||
if (!empty($sub1['sub'])) foreach ($sub1['sub'] as $sub2) {
|
if (!empty($sub1['sub'])) {
|
||||||
$pid2 = $this->write($sub2, $pid1);
|
foreach ($sub1['sub'] as $sub2) {
|
||||||
$this->setQueueMessage($total, ++$count, "重写2级菜单:-> {$sub2['title']}");
|
$pid2 = $this->write($sub2, $pid1);
|
||||||
if (!empty($sub2['sub'])) foreach ($sub2['sub'] as $sub3) {
|
$this->setQueueMessage($total, ++$count, "重写2级菜单:-> {$sub2['title']}");
|
||||||
$this->write($sub3, $pid2);
|
if (!empty($sub2['sub'])) {
|
||||||
$this->setQueueMessage($total, ++$count, "重写3级菜单:-> -> {$sub3['title']}");
|
foreach ($sub2['sub'] as $sub3) {
|
||||||
|
$this->write($sub3, $pid2);
|
||||||
|
$this->setQueueMessage($total, ++$count, "重写3级菜单:-> -> {$sub3['title']}");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$this->setQueueMessage($total, $count, "完成重置系统菜单编号!");
|
$this->setQueueMessage($total, $count, '完成重置系统菜单编号!');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 写入单项菜单数据
|
* 写入单项菜单数据.
|
||||||
* @param array $arr 单项菜单数据
|
* @param array $arr 单项菜单数据
|
||||||
* @param mixed $pid 上级菜单编号
|
* @param mixed $pid 上级菜单编号
|
||||||
* @return int|string
|
* @return int|string
|
||||||
@ -76,13 +84,13 @@ class Sysmenu extends Command
|
|||||||
private function write(array $arr, $pid = 0)
|
private function write(array $arr, $pid = 0)
|
||||||
{
|
{
|
||||||
return SystemMenu::mk()->insertGetId([
|
return SystemMenu::mk()->insertGetId([
|
||||||
'pid' => $pid,
|
'pid' => $pid,
|
||||||
'url' => $arr['url'],
|
'url' => $arr['url'],
|
||||||
'icon' => $arr['icon'],
|
'icon' => $arr['icon'],
|
||||||
'node' => $arr['node'],
|
'node' => $arr['node'],
|
||||||
'title' => $arr['title'],
|
'title' => $arr['title'],
|
||||||
'params' => $arr['params'],
|
'params' => $arr['params'],
|
||||||
'target' => $arr['target'],
|
'target' => $arr['target'],
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,53 +1,53 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// +----------------------------------------------------------------------
|
declare(strict_types=1);
|
||||||
// | Library for ThinkAdmin
|
/**
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 版权所有 2014~2025 ThinkAdmin [ thinkadmin.top ]
|
* | Payment Plugin for ThinkAdmin
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 官方网站: https://thinkadmin.top
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 开源协议 ( https://mit-license.org )
|
* | 官方网站: https://thinkadmin.top
|
||||||
// | 免费声明 ( https://thinkadmin.top/disclaimer )
|
* +----------------------------------------------------------------------
|
||||||
// +----------------------------------------------------------------------
|
* | 开源协议 ( https://mit-license.org )
|
||||||
// | gitee 仓库地址 :https://gitee.com/zoujingli/ThinkLibrary
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
// | github 仓库地址 :https://github.com/zoujingli/ThinkLibrary
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
declare (strict_types=1);
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
namespace think\admin\support\middleware;
|
namespace think\admin\support\middleware;
|
||||||
|
|
||||||
use Closure;
|
|
||||||
use think\admin\Exception;
|
use think\admin\Exception;
|
||||||
use think\admin\extend\JwtExtend;
|
use think\admin\extend\JwtExtend;
|
||||||
use think\App;
|
use think\App;
|
||||||
use think\exception\HttpResponseException;
|
use think\exception\HttpResponseException;
|
||||||
use think\Request;
|
use think\Request;
|
||||||
use think\Response;
|
use think\Response;
|
||||||
|
use think\Session;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 兼容会话中间键
|
* 兼容会话中间键.
|
||||||
* @class JwtSession
|
* @class JwtSession
|
||||||
* @package think\admin\support\middleware
|
|
||||||
*/
|
*/
|
||||||
class JwtSession
|
class JwtSession
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* 当前 App 对象
|
* 当前 App 对象
|
||||||
* @var \think\App
|
* @var App
|
||||||
*/
|
*/
|
||||||
protected $app;
|
protected $app;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 当前 Session 对象
|
* 当前 Session 对象
|
||||||
* @var \think\Session
|
* @var Session
|
||||||
*/
|
*/
|
||||||
protected $session;
|
protected $session;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct
|
* Construct.
|
||||||
* @param \think\App $app
|
|
||||||
*/
|
*/
|
||||||
public function __construct(App $app)
|
public function __construct(App $app)
|
||||||
{
|
{
|
||||||
@ -56,23 +56,22 @@ class JwtSession
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 中间键处理
|
* 中间键处理.
|
||||||
* @param \think\Request $request
|
|
||||||
* @param \Closure $next
|
|
||||||
* @return \think\Response
|
|
||||||
*/
|
*/
|
||||||
public function handle(Request $request, Closure $next): Response
|
public function handle(Request $request, \Closure $next): Response
|
||||||
{
|
{
|
||||||
// 处理 Jwt 请求,请求头存在 jwt-token 字段
|
// 处理 Jwt 请求,请求头存在 jwt-token 字段
|
||||||
if (($token = $request->header('jwt-token', ''))) try {
|
if ($token = $request->header('jwt-token', '')) {
|
||||||
if (preg_match('#^\s*([\w\-]+\.[\w\-]+\.[\w\-]+)\s*$#', $token, $match)) {
|
try {
|
||||||
JwtExtend::verify($match[1]);
|
if (preg_match('#^\s*([\w\-]+\.[\w\-]+\.[\w\-]+)\s*$#', $token, $match)) {
|
||||||
$sessionId = JwtExtend::$sessionId;
|
JwtExtend::verify($match[1]);
|
||||||
} else {
|
$sessionId = JwtExtend::$sessionId;
|
||||||
throw new Exception('令牌格式错误!', 401);
|
} else {
|
||||||
|
throw new Exception('令牌格式错误!', 401);
|
||||||
|
}
|
||||||
|
} catch (\Exception $exception) {
|
||||||
|
throw new HttpResponseException(json(['code' => $exception->getCode(), 'info' => lang($exception->getMessage())]));
|
||||||
}
|
}
|
||||||
} catch (\Exception $exception) {
|
|
||||||
throw new HttpResponseException(json(['code' => $exception->getCode(), 'info' => lang($exception->getMessage())]));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (empty($sessionId)) {
|
if (empty($sessionId)) {
|
||||||
@ -102,12 +101,11 @@ class JwtSession
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 保存会话数据
|
* 保存会话数据.
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public function end()
|
public function end()
|
||||||
{
|
{
|
||||||
$this->session->save();
|
$this->session->save();
|
||||||
JwtExtend::$sessionId = '';
|
JwtExtend::$sessionId = '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,25 +1,25 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// +----------------------------------------------------------------------
|
declare(strict_types=1);
|
||||||
// | Library for ThinkAdmin
|
/**
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 版权所有 2014~2025 ThinkAdmin [ thinkadmin.top ]
|
* | Payment Plugin for ThinkAdmin
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 官方网站: https://thinkadmin.top
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 开源协议 ( https://mit-license.org )
|
* | 官方网站: https://thinkadmin.top
|
||||||
// | 免费声明 ( https://thinkadmin.top/disclaimer )
|
* +----------------------------------------------------------------------
|
||||||
// +----------------------------------------------------------------------
|
* | 开源协议 ( https://mit-license.org )
|
||||||
// | gitee 仓库地址 :https://gitee.com/zoujingli/ThinkLibrary
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
// | github 仓库地址 :https://github.com/zoujingli/ThinkLibrary
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
declare (strict_types=1);
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
namespace think\admin\support\middleware;
|
namespace think\admin\support\middleware;
|
||||||
|
|
||||||
use Closure;
|
|
||||||
use SplFileInfo;
|
|
||||||
use think\admin\extend\ToolsExtend;
|
use think\admin\extend\ToolsExtend;
|
||||||
use think\admin\Library;
|
use think\admin\Library;
|
||||||
use think\admin\Plugin;
|
use think\admin\Plugin;
|
||||||
@ -31,33 +31,31 @@ use think\Request;
|
|||||||
use think\Response;
|
use think\Response;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 多应用调度中间键
|
* 多应用调度中间键.
|
||||||
* @class MultAccess
|
* @class MultAccess
|
||||||
* @package think\admin\support\middleware
|
|
||||||
*/
|
*/
|
||||||
class MultAccess
|
class MultAccess
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* 应用实例
|
* 应用实例.
|
||||||
* @var App
|
* @var App
|
||||||
*/
|
*/
|
||||||
private $app;
|
private $app;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 应用路径
|
* 应用路径.
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
private $appPath;
|
private $appPath;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 应用空间
|
* 应用空间.
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
private $appSpace;
|
private $appSpace;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* App constructor.
|
* App constructor.
|
||||||
* @param App $app
|
|
||||||
*/
|
*/
|
||||||
public function __construct(App $app)
|
public function __construct(App $app)
|
||||||
{
|
{
|
||||||
@ -65,70 +63,73 @@ class MultAccess
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 多应用解析
|
* 多应用解析.
|
||||||
* @param Request $request
|
|
||||||
* @param Closure $next
|
|
||||||
* @return Response
|
|
||||||
*/
|
*/
|
||||||
public function handle(Request $request, Closure $next): Response
|
public function handle(Request $request, \Closure $next): Response
|
||||||
{
|
{
|
||||||
[$this->appPath, $this->appSpace] = ['', ''];
|
[$this->appPath, $this->appSpace] = ['', ''];
|
||||||
if (!$this->parseMultiApp()) return $next($request);
|
if (!$this->parseMultiApp()) {
|
||||||
|
return $next($request);
|
||||||
|
}
|
||||||
return $this->app->middleware->pipeline('app')->send($request)->then(function ($request) use ($next) {
|
return $this->app->middleware->pipeline('app')->send($request)->then(function ($request) use ($next) {
|
||||||
return $next($request);
|
return $next($request);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 解析多应用
|
* 解析多应用.
|
||||||
* @return bool
|
|
||||||
*/
|
*/
|
||||||
private function parseMultiApp(): bool
|
private function parseMultiApp(): bool
|
||||||
{
|
{
|
||||||
$defaultApp = $this->app->config->get('route.default_app') ?: 'index';
|
$defaultApp = $this->app->config->get('route.default_app') ?: 'index';
|
||||||
[$script, $pathinfo] = [$this->scriptName(), $this->app->request->pathinfo()];
|
[$script, $pathinfo] = [$this->scriptName(), $this->app->request->pathinfo()];
|
||||||
if ($script && !in_array($script, ['index', 'router', 'think'])) {
|
if ($script && !in_array($script, ['index', 'router', 'think'])) {
|
||||||
$this->app->request->setPathinfo(preg_replace("#^{$script}\.php(/|\.|$)#i", '', $pathinfo) ?: '/');
|
$this->app->request->setPathinfo(preg_replace("#^{$script}\\.php(/|\\.|$)#i", '', $pathinfo) ?: '/');
|
||||||
return $this->setMultiApp($script, true);
|
return $this->setMultiApp($script, true);
|
||||||
} else {
|
}
|
||||||
// 域名绑定处理
|
// 域名绑定处理
|
||||||
$domains = $this->app->config->get('app.domain_bind', []);
|
$domains = $this->app->config->get('app.domain_bind', []);
|
||||||
if (!empty($domains)) foreach ([$this->app->request->host(true), $this->app->request->subDomain(), '*'] as $key) {
|
if (!empty($domains)) {
|
||||||
if (isset($domains[$key])) return $this->setMultiApp($domains[$key], true);
|
foreach ([$this->app->request->host(true), $this->app->request->subDomain(), '*'] as $key) {
|
||||||
}
|
if (isset($domains[$key])) {
|
||||||
$name = current(explode('/', $pathinfo));
|
return $this->setMultiApp($domains[$key], true);
|
||||||
if (strpos($name, '.')) $name = strstr($name, '.', true);
|
|
||||||
// 应用绑定与插件处理
|
|
||||||
$addons = Plugin::get();
|
|
||||||
$appmap = $this->app->config->get('app.app_map', []);
|
|
||||||
if (isset($appmap[$name])) {
|
|
||||||
$appName = $appmap[$name] instanceof Closure ? (call_user_func_array($appmap[$name], [$this->app]) ?: $name) : $appmap[$name];
|
|
||||||
} elseif ($name && (in_array($name, $appmap) || in_array($name, $this->app->config->get('app.deny_app_list', [])))) {
|
|
||||||
throw new HttpException(404, "app not exists: {$name}");
|
|
||||||
} elseif ($name && isset($appmap['*'])) {
|
|
||||||
$appName = $appmap['*'];
|
|
||||||
} else {
|
|
||||||
$appName = $name ?: $defaultApp;
|
|
||||||
if (!isset($addons[$appName]) && !is_dir($this->app->getBasePath() . $appName)) {
|
|
||||||
return $this->app->config->get('app.app_express', false) && $this->setMultiApp($defaultApp, false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 插件绑定处理
|
}
|
||||||
if (isset($addons[$appName])) {
|
$name = current(explode('/', $pathinfo));
|
||||||
[$this->appPath, $this->appSpace] = [$addons[$appName]['path'], $addons[$appName]['space']];
|
if (strpos($name, '.')) {
|
||||||
}
|
$name = strstr($name, '.', true);
|
||||||
if ($name) {
|
}
|
||||||
$this->app->request->setRoot('/' . $name);
|
// 应用绑定与插件处理
|
||||||
$this->app->request->setPathinfo(strpos($pathinfo, '/') ? ltrim(strstr($pathinfo, '/'), '/') : '');
|
$addons = Plugin::get();
|
||||||
|
$appmap = $this->app->config->get('app.app_map', []);
|
||||||
|
if (isset($appmap[$name])) {
|
||||||
|
$appName = $appmap[$name] instanceof \Closure ? (call_user_func_array($appmap[$name], [$this->app]) ?: $name) : $appmap[$name];
|
||||||
|
} elseif ($name && (in_array($name, $appmap) || in_array($name, $this->app->config->get('app.deny_app_list', [])))) {
|
||||||
|
throw new HttpException(404, "app not exists: {$name}");
|
||||||
|
} elseif ($name && isset($appmap['*'])) {
|
||||||
|
$appName = $appmap['*'];
|
||||||
|
} else {
|
||||||
|
$appName = $name ?: $defaultApp;
|
||||||
|
if (!isset($addons[$appName]) && !is_dir($this->app->getBasePath() . $appName)) {
|
||||||
|
return $this->app->config->get('app.app_express', false) && $this->setMultiApp($defaultApp, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 插件绑定处理
|
||||||
|
if (isset($addons[$appName])) {
|
||||||
|
[$this->appPath, $this->appSpace] = [$addons[$appName]['path'], $addons[$appName]['space']];
|
||||||
|
}
|
||||||
|
if ($name) {
|
||||||
|
$this->app->request->setRoot('/' . $name);
|
||||||
|
$this->app->request->setPathinfo(strpos($pathinfo, '/') ? ltrim(strstr($pathinfo, '/'), '/') : '');
|
||||||
|
}
|
||||||
|
|
||||||
return $this->setMultiApp($appName ?? $defaultApp, $this->app->http->isBind());
|
return $this->setMultiApp($appName ?? $defaultApp, $this->app->http->isBind());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取当前运行入口名称
|
* 获取当前运行入口名称.
|
||||||
* @codeCoverageIgnore
|
* @codeCoverageIgnore
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
private function scriptName(): string
|
private function scriptName(): string
|
||||||
{
|
{
|
||||||
@ -137,10 +138,9 @@ class MultAccess
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置应用参数
|
* 设置应用参数.
|
||||||
* @param string $appName 应用名称
|
* @param string $appName 应用名称
|
||||||
* @param boolean $appBind 应用绑定
|
* @param bool $appBind 应用绑定
|
||||||
* @return boolean
|
|
||||||
*/
|
*/
|
||||||
private function setMultiApp(string $appName, bool $appBind): bool
|
private function setMultiApp(string $appName, bool $appBind): bool
|
||||||
{
|
{
|
||||||
@ -154,24 +154,24 @@ class MultAccess
|
|||||||
$this->app->config->set(['view_path' => $this->appPath . 'view' . DIRECTORY_SEPARATOR, 'tpl_replace_string' => $uris], 'view');
|
$this->app->config->set(['view_path' => $this->appPath . 'view' . DIRECTORY_SEPARATOR, 'tpl_replace_string' => $uris], 'view');
|
||||||
// 初始化多应用文件
|
// 初始化多应用文件
|
||||||
return $this->loadMultiApp($this->appPath);
|
return $this->loadMultiApp($this->appPath);
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 加载应用文件
|
* 加载应用文件.
|
||||||
* @param string $appPath 应用路径
|
* @param string $appPath 应用路径
|
||||||
* @codeCoverageIgnore
|
* @codeCoverageIgnore
|
||||||
* @return boolean
|
|
||||||
*/
|
*/
|
||||||
private function loadMultiApp(string $appPath): bool
|
private function loadMultiApp(string $appPath): bool
|
||||||
{
|
{
|
||||||
[$ext, $fmaps] = [$this->app->getConfigExt(), []];
|
[$ext, $fmaps] = [$this->app->getConfigExt(), []];
|
||||||
// 加载应用函数文件
|
// 加载应用函数文件
|
||||||
if (is_file($file = "{$appPath}common{$ext}")) Library::load($file);
|
if (is_file($file = "{$appPath}common{$ext}")) {
|
||||||
|
Library::load($file);
|
||||||
|
}
|
||||||
// 加载应用配置文件
|
// 加载应用配置文件
|
||||||
ToolsExtend::find($appPath . 'config', 1, function (SplFileInfo $info) use ($ext) {
|
ToolsExtend::find($appPath . 'config', 1, function (\SplFileInfo $info) use ($ext) {
|
||||||
if ($info->isFile() && strtolower(".{$info->getExtension()}") === $ext) {
|
if ($info->isFile() && strtolower(".{$info->getExtension()}") === $ext) {
|
||||||
$this->app->config->load($info->getPathname(), $info->getBasename($ext));
|
$this->app->config->load($info->getPathname(), $info->getBasename($ext));
|
||||||
}
|
}
|
||||||
@ -198,4 +198,4 @@ class MultAccess
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,20 +1,22 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// +----------------------------------------------------------------------
|
declare(strict_types=1);
|
||||||
// | Library for ThinkAdmin
|
/**
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 版权所有 2014~2025 ThinkAdmin [ thinkadmin.top ]
|
* | Payment Plugin for ThinkAdmin
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 官方网站: https://thinkadmin.top
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 开源协议 ( https://mit-license.org )
|
* | 官方网站: https://thinkadmin.top
|
||||||
// | 免费声明 ( https://thinkadmin.top/disclaimer )
|
* +----------------------------------------------------------------------
|
||||||
// +----------------------------------------------------------------------
|
* | 开源协议 ( https://mit-license.org )
|
||||||
// | gitee 仓库地址 :https://gitee.com/zoujingli/ThinkLibrary
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
// | github 仓库地址 :https://github.com/zoujingli/ThinkLibrary
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
declare (strict_types=1);
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
namespace think\admin\support\middleware;
|
namespace think\admin\support\middleware;
|
||||||
|
|
||||||
@ -25,21 +27,19 @@ use think\Request;
|
|||||||
use think\Response;
|
use think\Response;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 后台权限中间键
|
* 后台权限中间键.
|
||||||
* @class RbacAccess
|
* @class RbacAccess
|
||||||
* @package think\admin\support\middleware
|
|
||||||
*/
|
*/
|
||||||
class RbacAccess
|
class RbacAccess
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* 当前 App 对象
|
* 当前 App 对象
|
||||||
* @var \think\App
|
* @var App
|
||||||
*/
|
*/
|
||||||
protected $app;
|
protected $app;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct
|
* Construct.
|
||||||
* @param \think\App $app
|
|
||||||
*/
|
*/
|
||||||
public function __construct(App $app)
|
public function __construct(App $app)
|
||||||
{
|
{
|
||||||
@ -47,10 +47,7 @@ class RbacAccess
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 中间键处理
|
* 中间键处理.
|
||||||
* @param \think\Request $request
|
|
||||||
* @param \Closure $next
|
|
||||||
* @return \think\Response
|
|
||||||
*/
|
*/
|
||||||
public function handle(Request $request, \Closure $next): Response
|
public function handle(Request $request, \Closure $next): Response
|
||||||
{
|
{
|
||||||
@ -81,4 +78,4 @@ class RbacAccess
|
|||||||
$loginPage = preg_match('#^(/|https?://)#', $loginUrl) ? $loginUrl : sysuri($loginUrl);
|
$loginPage = preg_match('#^(/|https?://)#', $loginUrl) ? $loginUrl : sysuri($loginUrl);
|
||||||
throw new HttpResponseException(json(['code' => 0, 'info' => lang('请重新登录!'), 'url' => $loginPage]));
|
throw new HttpResponseException(json(['code' => 0, 'info' => lang('请重新登录!'), 'url' => $loginPage]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,10 +1,32 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
/**
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
* | Payment Plugin for ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
* | 官方网站: https://thinkadmin.top
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
* | 开源协议 ( https://mit-license.org )
|
||||||
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
namespace think\admin\tests;
|
namespace think\admin\tests;
|
||||||
|
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
use think\admin\extend\CodeExtend;
|
use think\admin\extend\CodeExtend;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
* @coversNothing
|
||||||
|
*/
|
||||||
class CodeTest extends TestCase
|
class CodeTest extends TestCase
|
||||||
{
|
{
|
||||||
public function testUuidCreate()
|
public function testUuidCreate()
|
||||||
@ -19,4 +41,4 @@ class CodeTest extends TestCase
|
|||||||
$encode = CodeExtend::encrypt($value, 'thinkadmin');
|
$encode = CodeExtend::encrypt($value, 'thinkadmin');
|
||||||
$this->assertEquals($value, CodeExtend::decrypt($encode, 'thinkadmin'), '验证加密解密');
|
$this->assertEquals($value, CodeExtend::decrypt($encode, 'thinkadmin'), '验证加密解密');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,10 +1,32 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
/**
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
* | Payment Plugin for ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
* | 官方网站: https://thinkadmin.top
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
* | 开源协议 ( https://mit-license.org )
|
||||||
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
namespace think\admin\tests;
|
namespace think\admin\tests;
|
||||||
|
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
use think\admin\extend\JwtExtend;
|
use think\admin\extend\JwtExtend;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
* @coversNothing
|
||||||
|
*/
|
||||||
class JwtTest extends TestCase
|
class JwtTest extends TestCase
|
||||||
{
|
{
|
||||||
public function testJwtCreateAndVerify()
|
public function testJwtCreateAndVerify()
|
||||||
@ -15,4 +37,4 @@ class JwtTest extends TestCase
|
|||||||
$result = JwtExtend::verify($token, $jwtkey);
|
$result = JwtExtend::verify($token, $jwtkey);
|
||||||
$this->assertEquals($testdata['user'], $result['user']);
|
$this->assertEquals($testdata['user'], $result['user']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,14 +1,36 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
/**
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
* | Payment Plugin for ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
* | 官方网站: https://thinkadmin.top
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
* | 开源协议 ( https://mit-license.org )
|
||||||
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
namespace think\admin\tests;
|
namespace think\admin\tests;
|
||||||
|
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
use think\admin\model\SystemUser;
|
use think\admin\model\SystemUser;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
* @coversNothing
|
||||||
|
*/
|
||||||
class ModelTest extends TestCase
|
class ModelTest extends TestCase
|
||||||
{
|
{
|
||||||
public function testVirtualModel()
|
public function testVirtualModel()
|
||||||
{
|
{
|
||||||
$this->assertEquals(m('SystemUser')->getTable(), SystemUser::mk()->getTable(), '动态模型测试');
|
$this->assertEquals(m('SystemUser')->getTable(), SystemUser::mk()->getTable(), '动态模型测试');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,19 +1,41 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
/**
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
* | Payment Plugin for ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
* | 官方网站: https://thinkadmin.top
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
* | 开源协议 ( https://mit-license.org )
|
||||||
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
namespace think\admin\tests;
|
namespace think\admin\tests;
|
||||||
|
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
* @coversNothing
|
||||||
|
*/
|
||||||
class StorageTest extends TestCase
|
class StorageTest extends TestCase
|
||||||
{
|
{
|
||||||
public function testInit()
|
public function testInit()
|
||||||
{
|
{
|
||||||
$this->assertEquals(1, 1);
|
$this->assertEquals(1, 1);
|
||||||
}
|
}
|
||||||
// public function testAlist()
|
// public function testAlist()
|
||||||
// {
|
// {
|
||||||
// $alist = AlistStorage::instance();
|
// $alist = AlistStorage::instance();
|
||||||
// $alist->set('test.tt', $content = uniqid());
|
// $alist->set('test.tt', $content = uniqid());
|
||||||
// $this->assertEquals($alist->get('test.tt'), $content);
|
// $this->assertEquals($alist->get('test.tt'), $content);
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,22 +1,39 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
/**
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
* | Payment Plugin for ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
* | 官方网站: https://thinkadmin.top
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
* | 开源协议 ( https://mit-license.org )
|
||||||
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
use think\facade\Db;
|
use think\facade\Db;
|
||||||
|
|
||||||
include_once dirname(__DIR__) . '/vendor/autoload.php';
|
include_once dirname(__DIR__) . '/vendor/autoload.php';
|
||||||
include_once dirname(__DIR__) . '/vendor/topthink/framework/src/helper.php';
|
include_once dirname(__DIR__) . '/vendor/topthink/framework/src/helper.php';
|
||||||
|
|
||||||
Db::setConfig([
|
Db::setConfig([
|
||||||
'default' => 'mysql',
|
'default' => 'mysql',
|
||||||
'connections' => [
|
'connections' => [
|
||||||
'mysql' => [
|
'mysql' => [
|
||||||
'type' => 'mysql',
|
'type' => 'mysql',
|
||||||
'hostname' => '127.0.0.1',
|
'hostname' => '127.0.0.1',
|
||||||
'database' => 'admin_v6',
|
'database' => 'admin_v6',
|
||||||
'username' => 'admin_v6',
|
'username' => 'admin_v6',
|
||||||
'password' => 'FbYBHcWKr2',
|
'password' => 'FbYBHcWKr2',
|
||||||
'hostport' => '3306',
|
'hostport' => '3306',
|
||||||
'charset' => 'utf8mb4',
|
'charset' => 'utf8mb4',
|
||||||
'debug' => true,
|
'debug' => true,
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
]);
|
]);
|
||||||
|
|||||||
@ -1,20 +1,22 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// +----------------------------------------------------------------------
|
declare(strict_types=1);
|
||||||
// | Account Plugin for ThinkAdmin
|
/**
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 版权所有 2014~2025 ThinkAdmin [ thinkadmin.top ]
|
* | Payment Plugin for ThinkAdmin
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 官方网站: https://thinkadmin.top
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 免责声明 ( https://thinkadmin.top/disclaimer )
|
* | 官方网站: https://thinkadmin.top
|
||||||
// | 会员免费 ( https://thinkadmin.top/vip-introduce )
|
* +----------------------------------------------------------------------
|
||||||
// +----------------------------------------------------------------------
|
* | 开源协议 ( https://mit-license.org )
|
||||||
// | gitee 代码仓库:https://gitee.com/zoujingli/think-plugs-account
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
// | github 代码仓库:https://github.com/zoujingli/think-plugs-account
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
declare (strict_types=1);
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
namespace plugin\account;
|
namespace plugin\account;
|
||||||
|
|
||||||
@ -23,24 +25,23 @@ use think\admin\Plugin;
|
|||||||
/**
|
/**
|
||||||
* 插件注册服务
|
* 插件注册服务
|
||||||
* @class Service
|
* @class Service
|
||||||
* @package plugin\account
|
|
||||||
*/
|
*/
|
||||||
class Service extends Plugin
|
class Service extends Plugin
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* 定义插件名称
|
* 定义插件名称.
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
protected $appName = '账号管理';
|
protected $appName = '账号管理';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 定义安装包名
|
* 定义安装包名.
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
protected $package = 'zoujingli/think-plugs-account';
|
protected $package = 'zoujingli/think-plugs-account';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 定义插件菜单
|
* 定义插件菜单.
|
||||||
* @return array[]
|
* @return array[]
|
||||||
*/
|
*/
|
||||||
public static function menu(): array
|
public static function menu(): array
|
||||||
@ -57,4 +58,4 @@ class Service extends Plugin
|
|||||||
],
|
],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,42 +1,47 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// +----------------------------------------------------------------------
|
declare(strict_types=1);
|
||||||
// | Account Plugin for ThinkAdmin
|
/**
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 版权所有 2014~2025 ThinkAdmin [ thinkadmin.top ]
|
* | Payment Plugin for ThinkAdmin
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 官方网站: https://thinkadmin.top
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 免责声明 ( https://thinkadmin.top/disclaimer )
|
* | 官方网站: https://thinkadmin.top
|
||||||
// | 会员免费 ( https://thinkadmin.top/vip-introduce )
|
* +----------------------------------------------------------------------
|
||||||
// +----------------------------------------------------------------------
|
* | 开源协议 ( https://mit-license.org )
|
||||||
// | gitee 代码仓库:https://gitee.com/zoujingli/think-plugs-account
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
// | github 代码仓库:https://github.com/zoujingli/think-plugs-account
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
declare (strict_types=1);
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
namespace plugin\account\controller;
|
namespace plugin\account\controller;
|
||||||
|
|
||||||
use plugin\account\model\PluginAccountBind;
|
use plugin\account\model\PluginAccountBind;
|
||||||
use plugin\account\service\Account;
|
use plugin\account\service\Account;
|
||||||
use think\admin\Controller;
|
use think\admin\Controller;
|
||||||
|
use think\admin\Exception;
|
||||||
use think\admin\helper\QueryHelper;
|
use think\admin\helper\QueryHelper;
|
||||||
|
use think\db\exception\DataNotFoundException;
|
||||||
|
use think\db\exception\DbException;
|
||||||
|
use think\db\exception\ModelNotFoundException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 终端账号管理
|
* 终端账号管理.
|
||||||
* @class Device
|
* @class Device
|
||||||
* @package plugin\account\controller\user
|
|
||||||
*/
|
*/
|
||||||
class Device extends Controller
|
class Device extends Controller
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* 终端账号管理
|
* 终端账号管理.
|
||||||
* @auth true
|
* @auth true
|
||||||
* @menu true
|
* @menu true
|
||||||
* @throws \think\db\exception\DataNotFoundException
|
* @throws DataNotFoundException
|
||||||
* @throws \think\db\exception\DbException
|
* @throws DbException
|
||||||
* @throws \think\db\exception\ModelNotFoundException
|
* @throws ModelNotFoundException
|
||||||
*/
|
*/
|
||||||
public function index()
|
public function index()
|
||||||
{
|
{
|
||||||
@ -51,10 +56,9 @@ class Device extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 账号接口配置
|
* 账号接口配置.
|
||||||
* @auth true
|
* @auth true
|
||||||
* @return void
|
* @throws Exception
|
||||||
* @throws \think\admin\Exception
|
|
||||||
*/
|
*/
|
||||||
public function config()
|
public function config()
|
||||||
{
|
{
|
||||||
@ -90,17 +94,17 @@ class Device extends Controller
|
|||||||
public function state()
|
public function state()
|
||||||
{
|
{
|
||||||
PluginAccountBind::mSave($this->_vali([
|
PluginAccountBind::mSave($this->_vali([
|
||||||
'status.in:0,1' => '状态值范围异常!',
|
'status.in:0,1' => '状态值范围异常!',
|
||||||
'status.require' => '状态值不能为空!',
|
'status.require' => '状态值不能为空!',
|
||||||
]));
|
]));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 删除终端账号
|
* 删除终端账号.
|
||||||
* @auth true
|
* @auth true
|
||||||
*/
|
*/
|
||||||
public function remove()
|
public function remove()
|
||||||
{
|
{
|
||||||
PluginAccountBind::mDelete();
|
PluginAccountBind::mDelete();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,41 +1,45 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// +----------------------------------------------------------------------
|
declare(strict_types=1);
|
||||||
// | Account Plugin for ThinkAdmin
|
/**
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 版权所有 2014~2025 ThinkAdmin [ thinkadmin.top ]
|
* | Payment Plugin for ThinkAdmin
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 官方网站: https://thinkadmin.top
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 免责声明 ( https://thinkadmin.top/disclaimer )
|
* | 官方网站: https://thinkadmin.top
|
||||||
// | 会员免费 ( https://thinkadmin.top/vip-introduce )
|
* +----------------------------------------------------------------------
|
||||||
// +----------------------------------------------------------------------
|
* | 开源协议 ( https://mit-license.org )
|
||||||
// | gitee 代码仓库:https://gitee.com/zoujingli/think-plugs-account
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
// | github 代码仓库:https://github.com/zoujingli/think-plugs-account
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
declare (strict_types=1);
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
namespace plugin\account\controller;
|
namespace plugin\account\controller;
|
||||||
|
|
||||||
use plugin\account\model\PluginAccountUser;
|
use plugin\account\model\PluginAccountUser;
|
||||||
use think\admin\Controller;
|
use think\admin\Controller;
|
||||||
use think\admin\helper\QueryHelper;
|
use think\admin\helper\QueryHelper;
|
||||||
|
use think\db\exception\DataNotFoundException;
|
||||||
|
use think\db\exception\DbException;
|
||||||
|
use think\db\exception\ModelNotFoundException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用户账号管理
|
* 用户账号管理.
|
||||||
* @class Master
|
* @class Master
|
||||||
* @package plugin\account\controller\user
|
|
||||||
*/
|
*/
|
||||||
class Master extends Controller
|
class Master extends Controller
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* 用户账号管理
|
* 用户账号管理.
|
||||||
* @auth true
|
* @auth true
|
||||||
* @menu true
|
* @menu true
|
||||||
* @throws \think\db\exception\DataNotFoundException
|
* @throws DataNotFoundException
|
||||||
* @throws \think\db\exception\DbException
|
* @throws DbException
|
||||||
* @throws \think\db\exception\ModelNotFoundException
|
* @throws ModelNotFoundException
|
||||||
*/
|
*/
|
||||||
public function index()
|
public function index()
|
||||||
{
|
{
|
||||||
@ -55,17 +59,17 @@ class Master extends Controller
|
|||||||
public function state()
|
public function state()
|
||||||
{
|
{
|
||||||
PluginAccountUser::mSave($this->_vali([
|
PluginAccountUser::mSave($this->_vali([
|
||||||
'status.in:0,1' => '状态值范围异常!',
|
'status.in:0,1' => '状态值范围异常!',
|
||||||
'status.require' => '状态值不能为空!',
|
'status.require' => '状态值不能为空!',
|
||||||
]));
|
]));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 删除主账号
|
* 删除主账号.
|
||||||
* @auth true
|
* @auth true
|
||||||
*/
|
*/
|
||||||
public function remove()
|
public function remove()
|
||||||
{
|
{
|
||||||
PluginAccountUser::mDelete();
|
PluginAccountUser::mDelete();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,61 +1,54 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// +----------------------------------------------------------------------
|
declare(strict_types=1);
|
||||||
// | Account Plugin for ThinkAdmin
|
/**
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 版权所有 2014~2025 ThinkAdmin [ thinkadmin.top ]
|
* | Payment Plugin for ThinkAdmin
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 官方网站: https://thinkadmin.top
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 免责声明 ( https://thinkadmin.top/disclaimer )
|
* | 官方网站: https://thinkadmin.top
|
||||||
// | 会员免费 ( https://thinkadmin.top/vip-introduce )
|
* +----------------------------------------------------------------------
|
||||||
// +----------------------------------------------------------------------
|
* | 开源协议 ( https://mit-license.org )
|
||||||
// | gitee 代码仓库:https://gitee.com/zoujingli/think-plugs-account
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
// | github 代码仓库:https://github.com/zoujingli/think-plugs-account
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
declare (strict_types=1);
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
namespace plugin\account\controller;
|
namespace plugin\account\controller;
|
||||||
|
|
||||||
use plugin\account\model\PluginAccountMsms;
|
use plugin\account\model\PluginAccountMsms;
|
||||||
use plugin\account\service\Message as MessageService;
|
|
||||||
use plugin\account\service\message\Alisms;
|
use plugin\account\service\message\Alisms;
|
||||||
|
use plugin\account\service\Message as MessageService;
|
||||||
use think\admin\Controller;
|
use think\admin\Controller;
|
||||||
|
use think\admin\Exception;
|
||||||
use think\admin\helper\QueryHelper;
|
use think\admin\helper\QueryHelper;
|
||||||
|
use think\db\exception\DataNotFoundException;
|
||||||
|
use think\db\exception\DbException;
|
||||||
|
use think\db\exception\ModelNotFoundException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 手机短信管理
|
* 手机短信管理.
|
||||||
* @class Message
|
* @class Message
|
||||||
* @package plugin\account\controller
|
|
||||||
*/
|
*/
|
||||||
class Message extends Controller
|
class Message extends Controller
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 缓存配置名称
|
* 缓存配置名称.
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
protected $smskey;
|
protected $smskey;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 初始化控制器
|
* 手机短信管理.
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
protected function initialize()
|
|
||||||
{
|
|
||||||
parent::initialize();
|
|
||||||
$this->smskey = 'plugin.account.smscfg';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 手机短信管理
|
|
||||||
* @auth true
|
* @auth true
|
||||||
* @menu true
|
* @menu true
|
||||||
* @return void
|
* @throws DataNotFoundException
|
||||||
* @throws \think\db\exception\DataNotFoundException
|
* @throws DbException
|
||||||
* @throws \think\db\exception\DbException
|
* @throws ModelNotFoundException
|
||||||
* @throws \think\db\exception\ModelNotFoundException
|
|
||||||
*/
|
*/
|
||||||
public function index()
|
public function index()
|
||||||
{
|
{
|
||||||
@ -68,10 +61,9 @@ class Message extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 修改短信配置
|
* 修改短信配置.
|
||||||
* @auth true
|
* @auth true
|
||||||
* @return void
|
* @throws Exception
|
||||||
* @throws \think\admin\Exception
|
|
||||||
*/
|
*/
|
||||||
public function config()
|
public function config()
|
||||||
{
|
{
|
||||||
@ -85,4 +77,13 @@ class Message extends Controller
|
|||||||
$this->success('修改配置成功!');
|
$this->success('修改配置成功!');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
/**
|
||||||
|
* 初始化控制器.
|
||||||
|
*/
|
||||||
|
protected function initialize()
|
||||||
|
{
|
||||||
|
parent::initialize();
|
||||||
|
$this->smskey = 'plugin.account.smscfg';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -1,61 +1,62 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// +----------------------------------------------------------------------
|
declare(strict_types=1);
|
||||||
// | Account Plugin for ThinkAdmin
|
/**
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 版权所有 2014~2025 ThinkAdmin [ thinkadmin.top ]
|
* | Payment Plugin for ThinkAdmin
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 官方网站: https://thinkadmin.top
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 免责声明 ( https://thinkadmin.top/disclaimer )
|
* | 官方网站: https://thinkadmin.top
|
||||||
// | 会员免费 ( https://thinkadmin.top/vip-introduce )
|
* +----------------------------------------------------------------------
|
||||||
// +----------------------------------------------------------------------
|
* | 开源协议 ( https://mit-license.org )
|
||||||
// | gitee 代码仓库:https://gitee.com/zoujingli/think-plugs-account
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
// | github 代码仓库:https://github.com/zoujingli/think-plugs-account
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
declare (strict_types=1);
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
namespace plugin\account\controller\api;
|
namespace plugin\account\controller\api;
|
||||||
|
|
||||||
use plugin\account\service\Account;
|
use plugin\account\service\Account;
|
||||||
|
use plugin\account\service\contract\AccountInterface;
|
||||||
use think\admin\Controller;
|
use think\admin\Controller;
|
||||||
use think\exception\HttpResponseException;
|
use think\exception\HttpResponseException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 接口授权抽象类
|
* 接口授权抽象类.
|
||||||
* @class Auth
|
* @class Auth
|
||||||
* @package plugin\account\controller\api
|
|
||||||
*/
|
*/
|
||||||
abstract class Auth extends Controller
|
abstract class Auth extends Controller
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 接口类型
|
* 接口类型.
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
protected $type;
|
protected $type;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 主账号编号
|
* 主账号编号.
|
||||||
* @var integer
|
* @var int
|
||||||
*/
|
*/
|
||||||
protected $unid;
|
protected $unid;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 子账号编号
|
* 子账号编号.
|
||||||
* @var integer
|
* @var int
|
||||||
*/
|
*/
|
||||||
protected $usid;
|
protected $usid;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 终端账号接口
|
* 终端账号接口.
|
||||||
* @var \plugin\account\service\contract\AccountInterface
|
* @var AccountInterface
|
||||||
*/
|
*/
|
||||||
protected $account;
|
protected $account;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 控制器初始化
|
* 控制器初始化.
|
||||||
*/
|
*/
|
||||||
protected function initialize()
|
protected function initialize()
|
||||||
{
|
{
|
||||||
@ -69,7 +70,9 @@ abstract class Auth extends Controller
|
|||||||
if (empty($token)) {
|
if (empty($token)) {
|
||||||
$token = $this->request->header('api-token', '');
|
$token = $this->request->header('api-token', '');
|
||||||
}
|
}
|
||||||
if (empty($token)) $this->error('需要登录授权', [], 401);
|
if (empty($token)) {
|
||||||
|
$this->error('需要登录授权', [], 401);
|
||||||
|
}
|
||||||
// 读取用户账号数据
|
// 读取用户账号数据
|
||||||
$this->account = Account::mk('', $token);
|
$this->account = Account::mk('', $token);
|
||||||
$login = $this->account->check();
|
$login = $this->account->check();
|
||||||
@ -91,7 +94,6 @@ abstract class Auth extends Controller
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 检查用户状态
|
* 检查用户状态
|
||||||
* @param boolean $isBind
|
|
||||||
* @return $this
|
* @return $this
|
||||||
*/
|
*/
|
||||||
protected function checkUserStatus(bool $isBind = true): Auth
|
protected function checkUserStatus(bool $isBind = true): Auth
|
||||||
@ -109,4 +111,4 @@ abstract class Auth extends Controller
|
|||||||
}
|
}
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,20 +1,22 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// +----------------------------------------------------------------------
|
declare(strict_types=1);
|
||||||
// | Account Plugin for ThinkAdmin
|
/**
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 版权所有 2014~2025 ThinkAdmin [ thinkadmin.top ]
|
* | Payment Plugin for ThinkAdmin
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 官方网站: https://thinkadmin.top
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 免责声明 ( https://thinkadmin.top/disclaimer )
|
* | 官方网站: https://thinkadmin.top
|
||||||
// | 会员免费 ( https://thinkadmin.top/vip-introduce )
|
* +----------------------------------------------------------------------
|
||||||
// +----------------------------------------------------------------------
|
* | 开源协议 ( https://mit-license.org )
|
||||||
// | gitee 代码仓库:https://gitee.com/zoujingli/think-plugs-account
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
// | github 代码仓库:https://github.com/zoujingli/think-plugs-account
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
declare (strict_types=1);
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
namespace plugin\account\controller\api;
|
namespace plugin\account\controller\api;
|
||||||
|
|
||||||
@ -28,24 +30,22 @@ use think\admin\extend\JwtExtend;
|
|||||||
use think\exception\HttpResponseException;
|
use think\exception\HttpResponseException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 通用登录注册接口
|
* 通用登录注册接口.
|
||||||
* @class Login
|
* @class Login
|
||||||
* @package plugin\account\controller\api
|
|
||||||
*/
|
*/
|
||||||
class Login extends Controller
|
class Login extends Controller
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* 通过手机号登录
|
* 通过手机号登录.
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public function in()
|
public function in()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$data = $this->_vali([
|
$data = $this->_vali([
|
||||||
'type.require' => '类型为空',
|
'type.require' => '类型为空',
|
||||||
'phone.mobile' => '手机号错误',
|
'phone.mobile' => '手机号错误',
|
||||||
'phone.require' => '手机号为空',
|
'phone.require' => '手机号为空',
|
||||||
'verify.require' => '验证码为空'
|
'verify.require' => '验证码为空',
|
||||||
]);
|
]);
|
||||||
if (Account::field($data['type']) !== 'phone') {
|
if (Account::field($data['type']) !== 'phone') {
|
||||||
$this->error('不支持登录');
|
$this->error('不支持登录');
|
||||||
@ -59,7 +59,9 @@ class Login extends Controller
|
|||||||
} else {
|
} else {
|
||||||
// 通过手机查询所有终端
|
// 通过手机查询所有终端
|
||||||
$account = Account::mk('', $inset);
|
$account = Account::mk('', $inset);
|
||||||
if ($account->isNull()) $this->error('手机未注册');
|
if ($account->isNull()) {
|
||||||
|
$this->error('手机未注册');
|
||||||
|
}
|
||||||
// 如果当前终端账号不存在则创建
|
// 如果当前终端账号不存在则创建
|
||||||
if ($account->getType() !== $data['type']) {
|
if ($account->getType() !== $data['type']) {
|
||||||
$account = Account::mk($data['type'], $inset);
|
$account = Account::mk($data['type'], $inset);
|
||||||
@ -79,8 +81,7 @@ class Login extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 自动授权登录
|
* 自动授权登录.
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public function auto()
|
public function auto()
|
||||||
{
|
{
|
||||||
@ -89,7 +90,9 @@ class Login extends Controller
|
|||||||
$vars = CodeExtend::decrypt($data['code'], JwtExtend::jwtkey());
|
$vars = CodeExtend::decrypt($data['code'], JwtExtend::jwtkey());
|
||||||
if (is_array($vars) && isset($vars['unid'])) {
|
if (is_array($vars) && isset($vars['unid'])) {
|
||||||
$user = PluginAccountUser::mk()->findOrEmpty($vars['unid']);
|
$user = PluginAccountUser::mk()->findOrEmpty($vars['unid']);
|
||||||
if ($user->isEmpty()) $this->error('无效账号!');
|
if ($user->isEmpty()) {
|
||||||
|
$this->error('无效账号!');
|
||||||
|
}
|
||||||
$inset = ['phone' => $user->getAttr('phone')];
|
$inset = ['phone' => $user->getAttr('phone')];
|
||||||
$account = Account::mk(Account::WAP, $inset);
|
$account = Account::mk(Account::WAP, $inset);
|
||||||
$account->set(['unid' => $user->getAttr('id')] + $inset);
|
$account->set(['unid' => $user->getAttr('id')] + $inset);
|
||||||
@ -105,18 +108,17 @@ class Login extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 通过密码登录
|
* 通过密码登录.
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public function pass()
|
public function pass()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$data = $this->_vali([
|
$data = $this->_vali([
|
||||||
'type.require' => '接口类型为空',
|
'type.require' => '接口类型为空',
|
||||||
'phone.mobile' => '登录手机错误',
|
'phone.mobile' => '登录手机错误',
|
||||||
'phone.require' => '登录手机为空',
|
'phone.require' => '登录手机为空',
|
||||||
'uniqid.require' => '拼图编号为空',
|
'uniqid.require' => '拼图编号为空',
|
||||||
'verify.require' => '拼图位置为空',
|
'verify.require' => '拼图位置为空',
|
||||||
'password.require' => '登录密码为空',
|
'password.require' => '登录密码为空',
|
||||||
]);
|
]);
|
||||||
if (Account::field($data['type']) !== 'phone') {
|
if (Account::field($data['type']) !== 'phone') {
|
||||||
@ -128,7 +130,9 @@ class Login extends Controller
|
|||||||
$inset = ['phone' => $data['phone'], 'deleted' => 0];
|
$inset = ['phone' => $data['phone'], 'deleted' => 0];
|
||||||
// 通过手机查询所有终端
|
// 通过手机查询所有终端
|
||||||
$account = Account::mk('', $inset);
|
$account = Account::mk('', $inset);
|
||||||
if ($account->isNull()) $this->error('手机未注册');
|
if ($account->isNull()) {
|
||||||
|
$this->error('手机未注册');
|
||||||
|
}
|
||||||
if ($account->pwdVerify($data['password'])) {
|
if ($account->pwdVerify($data['password'])) {
|
||||||
// 如果当前终端账号不存在则创建
|
// 如果当前终端账号不存在则创建
|
||||||
if ($account->getType() !== $data['type']) {
|
if ($account->getType() !== $data['type']) {
|
||||||
@ -149,15 +153,14 @@ class Login extends Controller
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 通过短信找回密码
|
* 通过短信找回密码
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public function forget()
|
public function forget()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$data = $this->_vali([
|
$data = $this->_vali([
|
||||||
'type.require' => '接口类型为空',
|
'type.require' => '接口类型为空',
|
||||||
'phone.mobile' => '登录手机错误',
|
'phone.mobile' => '登录手机错误',
|
||||||
'phone.require' => '登录手机为空',
|
'phone.require' => '登录手机为空',
|
||||||
'verify.require' => '短信验证为空',
|
'verify.require' => '短信验证为空',
|
||||||
'passwd.require' => '密码不能为空',
|
'passwd.require' => '密码不能为空',
|
||||||
]);
|
]);
|
||||||
@ -165,7 +168,9 @@ class Login extends Controller
|
|||||||
Message::clearVerifyCode($data['phone'], Message::tForget);
|
Message::clearVerifyCode($data['phone'], Message::tForget);
|
||||||
$inset = ['phone' => $data['phone'], 'deleted' => 0];
|
$inset = ['phone' => $data['phone'], 'deleted' => 0];
|
||||||
$account = Account::mk($data['type'], $inset);
|
$account = Account::mk($data['type'], $inset);
|
||||||
if ($account->isNull()) $this->error('账号不存在');
|
if ($account->isNull()) {
|
||||||
|
$this->error('账号不存在');
|
||||||
|
}
|
||||||
$account->pwdModify($data['passwd']);
|
$account->pwdModify($data['passwd']);
|
||||||
$this->success('重置成功', $account->expire()->get(true));
|
$this->success('重置成功', $account->expire()->get(true));
|
||||||
} else {
|
} else {
|
||||||
@ -179,19 +184,18 @@ class Login extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用户注册绑定
|
* 用户注册绑定.
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public function register()
|
public function register()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$data = $this->_vali([
|
$data = $this->_vali([
|
||||||
'type.require' => '接口类型为空',
|
'type.require' => '接口类型为空',
|
||||||
'phone.mobile' => '登录手机错误',
|
'phone.mobile' => '登录手机错误',
|
||||||
'phone.require' => '登录手机为空',
|
'phone.require' => '登录手机为空',
|
||||||
'verify.require' => '短信验证为空',
|
'verify.require' => '短信验证为空',
|
||||||
'passwd.require' => '密码不能为空',
|
'passwd.require' => '密码不能为空',
|
||||||
'fphone.default' => ''
|
'fphone.default' => '',
|
||||||
]);
|
]);
|
||||||
if (Message::checkVerifyCode($data['verify'], $data['phone'], Message::tRegister)) {
|
if (Message::checkVerifyCode($data['verify'], $data['phone'], Message::tRegister)) {
|
||||||
Message::clearVerifyCode($data['phone'], Message::tRegister);
|
Message::clearVerifyCode($data['phone'], Message::tRegister);
|
||||||
@ -214,14 +218,13 @@ class Login extends Controller
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 发送短信验证码
|
* 发送短信验证码
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public function send()
|
public function send()
|
||||||
{
|
{
|
||||||
$data = $this->_vali([
|
$data = $this->_vali([
|
||||||
'type.default' => 'login',
|
'type.default' => 'login',
|
||||||
'phone.mobile' => '手机号错误',
|
'phone.mobile' => '手机号错误',
|
||||||
'phone.require' => '手机号为空',
|
'phone.require' => '手机号为空',
|
||||||
'uniqid.require' => '拼图编号为空',
|
'uniqid.require' => '拼图编号为空',
|
||||||
'verify.require' => '拼图位置为空',
|
'verify.require' => '拼图位置为空',
|
||||||
]);
|
]);
|
||||||
@ -240,7 +243,6 @@ class Login extends Controller
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 生成拼图验证码
|
* 生成拼图验证码
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public function image()
|
public function image()
|
||||||
{
|
{
|
||||||
@ -250,24 +252,23 @@ class Login extends Controller
|
|||||||
];
|
];
|
||||||
$image = ImageVerify::render($images[array_rand($images)]);
|
$image = ImageVerify::render($images[array_rand($images)]);
|
||||||
$this->success('生成拼图成功', [
|
$this->success('生成拼图成功', [
|
||||||
'bgimg' => $image['bgimg'],
|
'bgimg' => $image['bgimg'],
|
||||||
'water' => $image['water'],
|
'water' => $image['water'],
|
||||||
'uniqid' => $image['code'],
|
'uniqid' => $image['code'],
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 实时验证结果
|
* 实时验证结果.
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public function verify()
|
public function verify()
|
||||||
{
|
{
|
||||||
$data = $this->_vali([
|
$data = $this->_vali([
|
||||||
'uniqid.require' => '拼图验证为空',
|
'uniqid.require' => '拼图验证为空',
|
||||||
'verify.require' => '拼图数值为空'
|
'verify.require' => '拼图数值为空',
|
||||||
]);
|
]);
|
||||||
// state: [ -1:需要刷新, 0:验证失败, 1:验证成功 ]
|
// state: [ -1:需要刷新, 0:验证失败, 1:验证成功 ]
|
||||||
$state = ImageVerify::verify($data['uniqid'], $data['verify']);
|
$state = ImageVerify::verify($data['uniqid'], $data['verify']);
|
||||||
$this->success('验证结果', ['state' => $state]);
|
$this->success('验证结果', ['state' => $state]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,32 +1,36 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// +----------------------------------------------------------------------
|
declare(strict_types=1);
|
||||||
// | Account Plugin for ThinkAdmin
|
/**
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 版权所有 2014~2025 ThinkAdmin [ thinkadmin.top ]
|
* | Payment Plugin for ThinkAdmin
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 官方网站: https://thinkadmin.top
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 免责声明 ( https://thinkadmin.top/disclaimer )
|
* | 官方网站: https://thinkadmin.top
|
||||||
// | 会员免费 ( https://thinkadmin.top/vip-introduce )
|
* +----------------------------------------------------------------------
|
||||||
// +----------------------------------------------------------------------
|
* | 开源协议 ( https://mit-license.org )
|
||||||
// | gitee 代码仓库:https://gitee.com/zoujingli/think-plugs-account
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
// | github 代码仓库:https://github.com/zoujingli/think-plugs-account
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
declare (strict_types=1);
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
namespace plugin\account\controller\api;
|
namespace plugin\account\controller\api;
|
||||||
|
|
||||||
use app\wechat\service\WechatService;
|
use app\wechat\service\WechatService;
|
||||||
use plugin\account\service\Account;
|
use plugin\account\service\Account;
|
||||||
use think\admin\Controller;
|
use think\admin\Controller;
|
||||||
|
use think\admin\Exception;
|
||||||
use think\Response;
|
use think\Response;
|
||||||
|
use WeChat\Exceptions\InvalidResponseException;
|
||||||
|
use WeChat\Exceptions\LocalCacheException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 微信服务号入口
|
* 微信服务号入口.
|
||||||
* @class Wechat
|
* @class Wechat
|
||||||
* @package plugin\account\controller\api
|
|
||||||
* @example 域名请修改为自己的地址,放到网页代码合适位置
|
* @example 域名请修改为自己的地址,放到网页代码合适位置
|
||||||
*
|
*
|
||||||
* <meta name="referrer" content="always">
|
* <meta name="referrer" content="always">
|
||||||
@ -37,9 +41,8 @@ use think\Response;
|
|||||||
*/
|
*/
|
||||||
class Wechat extends Controller
|
class Wechat extends Controller
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 通道认证类型
|
* 通道认证类型.
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
private const type = Account::WECHAT;
|
private const type = Account::WECHAT;
|
||||||
@ -51,29 +54,16 @@ class Wechat extends Controller
|
|||||||
private $source;
|
private $source;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 微信调度器
|
* 微信调度器.
|
||||||
* @var WechatService
|
* @var WechatService
|
||||||
*/
|
*/
|
||||||
private $wechat;
|
private $wechat;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 控制器初始化
|
* 生成微信网页签名.
|
||||||
*/
|
* @throws InvalidResponseException
|
||||||
protected function initialize()
|
* @throws LocalCacheException
|
||||||
{
|
* @throws Exception
|
||||||
if (Account::field(static::type)) {
|
|
||||||
$this->wechat = WechatService::instance();
|
|
||||||
$this->source = input('source') ?: $this->request->server('http_referer', $this->request->url(true));
|
|
||||||
} else {
|
|
||||||
$this->error('接口未开通');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 生成微信网页签名
|
|
||||||
* @throws \WeChat\Exceptions\InvalidResponseException
|
|
||||||
* @throws \WeChat\Exceptions\LocalCacheException
|
|
||||||
* @throws \think\admin\Exception
|
|
||||||
*/
|
*/
|
||||||
public function jssdk()
|
public function jssdk()
|
||||||
{
|
{
|
||||||
@ -81,11 +71,10 @@ class Wechat extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 微信网页授权脚本
|
* 微信网页授权脚本.
|
||||||
* @return \think\Response
|
* @throws InvalidResponseException
|
||||||
* @throws \WeChat\Exceptions\InvalidResponseException
|
* @throws LocalCacheException
|
||||||
* @throws \WeChat\Exceptions\LocalCacheException
|
* @throws Exception
|
||||||
* @throws \think\admin\Exception
|
|
||||||
* @remark 基于 sessionStorage 标识的登录机制
|
* @remark 基于 sessionStorage 标识的登录机制
|
||||||
*/
|
*/
|
||||||
public function oauth(): Response
|
public function oauth(): Response
|
||||||
@ -99,9 +88,15 @@ class Wechat extends Controller
|
|||||||
if (empty($fansinfo['is_snapshotuser'])) {
|
if (empty($fansinfo['is_snapshotuser'])) {
|
||||||
// 筛选保存数据
|
// 筛选保存数据
|
||||||
$data = ['appid' => WechatService::getAppid(), 'openid' => $result['openid'], 'extra' => $fansinfo];
|
$data = ['appid' => WechatService::getAppid(), 'openid' => $result['openid'], 'extra' => $fansinfo];
|
||||||
if (isset($fansinfo['unionid'])) $data['unionid'] = $fansinfo['unionid'];
|
if (isset($fansinfo['unionid'])) {
|
||||||
if (isset($fansinfo['nickname'])) $data['nickname'] = $fansinfo['nickname'];
|
$data['unionid'] = $fansinfo['unionid'];
|
||||||
if (isset($fansinfo['headimgurl'])) $data['headimg'] = $fansinfo['headimgurl'];
|
}
|
||||||
|
if (isset($fansinfo['nickname'])) {
|
||||||
|
$data['nickname'] = $fansinfo['nickname'];
|
||||||
|
}
|
||||||
|
if (isset($fansinfo['headimgurl'])) {
|
||||||
|
$data['headimg'] = $fansinfo['headimgurl'];
|
||||||
|
}
|
||||||
$result['userinfo'] = Account::mk(static::type)->set($data, true);
|
$result['userinfo'] = Account::mk(static::type)->set($data, true);
|
||||||
// 返回数据给前端
|
// 返回数据给前端
|
||||||
$script[] = "window.WeChatOpenid='{$result['openid']}'";
|
$script[] = "window.WeChatOpenid='{$result['openid']}'";
|
||||||
@ -116,4 +111,17 @@ class Wechat extends Controller
|
|||||||
$script[] = '';
|
$script[] = '';
|
||||||
return Response::create(join(";\n", $script))->contentType('application/javascript');
|
return Response::create(join(";\n", $script))->contentType('application/javascript');
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
/**
|
||||||
|
* 控制器初始化.
|
||||||
|
*/
|
||||||
|
protected function initialize()
|
||||||
|
{
|
||||||
|
if (Account::field(static::type)) {
|
||||||
|
$this->wechat = WechatService::instance();
|
||||||
|
$this->source = input('source') ?: $this->request->server('http_referer', $this->request->url(true));
|
||||||
|
} else {
|
||||||
|
$this->error('接口未开通');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -1,20 +1,22 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// +----------------------------------------------------------------------
|
declare(strict_types=1);
|
||||||
// | Account Plugin for ThinkAdmin
|
/**
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 版权所有 2014~2025 ThinkAdmin [ thinkadmin.top ]
|
* | Payment Plugin for ThinkAdmin
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 官方网站: https://thinkadmin.top
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 免责声明 ( https://thinkadmin.top/disclaimer )
|
* | 官方网站: https://thinkadmin.top
|
||||||
// | 会员免费 ( https://thinkadmin.top/vip-introduce )
|
* +----------------------------------------------------------------------
|
||||||
// +----------------------------------------------------------------------
|
* | 开源协议 ( https://mit-license.org )
|
||||||
// | gitee 代码仓库:https://gitee.com/zoujingli/think-plugs-account
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
// | github 代码仓库:https://github.com/zoujingli/think-plugs-account
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
declare (strict_types=1);
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
namespace plugin\account\controller\api;
|
namespace plugin\account\controller\api;
|
||||||
|
|
||||||
@ -28,39 +30,25 @@ use WeMini\Live;
|
|||||||
use WeMini\Qrcode;
|
use WeMini\Qrcode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 微信小程序入口
|
* 微信小程序入口.
|
||||||
* @class Wxapp
|
* @class Wxapp
|
||||||
* @package plugin\account\controller\api
|
|
||||||
*/
|
*/
|
||||||
class Wxapp extends Controller
|
class Wxapp extends Controller
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* 接口通道类型
|
* 接口通道类型.
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
private $type = Account::WXAPP;
|
private $type = Account::WXAPP;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 小程序配置参数
|
* 小程序配置参数.
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
private $params;
|
private $params;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 接口初始化
|
* 换取会话.
|
||||||
* @throws \think\admin\Exception
|
|
||||||
*/
|
|
||||||
protected function initialize()
|
|
||||||
{
|
|
||||||
if (Account::field($this->type)) {
|
|
||||||
$this->params = WechatService::getWxconf();
|
|
||||||
} else {
|
|
||||||
$this->error('接口未开通');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 换取会话
|
|
||||||
*/
|
*/
|
||||||
public function session()
|
public function session()
|
||||||
{
|
{
|
||||||
@ -68,9 +56,9 @@ class Wxapp extends Controller
|
|||||||
$input = $this->_vali(['code.require' => '凭证编码为空']);
|
$input = $this->_vali(['code.require' => '凭证编码为空']);
|
||||||
[$openid, $unionid, $sesskey] = $this->applySesskey($input['code']);
|
[$openid, $unionid, $sesskey] = $this->applySesskey($input['code']);
|
||||||
$data = [
|
$data = [
|
||||||
'appid' => $this->params['appid'],
|
'appid' => $this->params['appid'],
|
||||||
'openid' => $openid,
|
'openid' => $openid,
|
||||||
'unionid' => $unionid,
|
'unionid' => $unionid,
|
||||||
'session_key' => $sesskey,
|
'session_key' => $sesskey,
|
||||||
];
|
];
|
||||||
$this->success('授权换取成功', Account::mk($this->type)->set($data, true));
|
$this->success('授权换取成功', Account::mk($this->type)->set($data, true));
|
||||||
@ -83,28 +71,30 @@ class Wxapp extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 数据解密
|
* 数据解密.
|
||||||
*/
|
*/
|
||||||
public function decode()
|
public function decode()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$input = $this->_vali([
|
$input = $this->_vali([
|
||||||
'iv.require' => '解密向量为空',
|
'iv.require' => '解密向量为空',
|
||||||
'code.require' => '授权编码为空',
|
'code.require' => '授权编码为空',
|
||||||
'encrypted.require' => '密文内容为空',
|
'encrypted.require' => '密文内容为空',
|
||||||
]);
|
]);
|
||||||
[$openid, $unionid, $input['session_key']] = $this->applySesskey($input['code']);
|
[$openid, $unionid, $input['session_key']] = $this->applySesskey($input['code']);
|
||||||
$result = Crypt::instance($this->params)->decode($input['iv'], $input['session_key'], $input['encrypted']);
|
$result = Crypt::instance($this->params)->decode($input['iv'], $input['session_key'], $input['encrypted']);
|
||||||
if (is_array($result) && isset($result['avatarUrl']) && isset($result['nickName'])) {
|
if (is_array($result) && isset($result['avatarUrl'], $result['nickName'])) {
|
||||||
$data = [
|
$data = [
|
||||||
'extra' => $result,
|
'extra' => $result,
|
||||||
'appid' => $this->params['appid'],
|
'appid' => $this->params['appid'],
|
||||||
'openid' => $openid,
|
'openid' => $openid,
|
||||||
'unionid' => $unionid,
|
'unionid' => $unionid,
|
||||||
'headimg' => $result['avatarUrl'],
|
'headimg' => $result['avatarUrl'],
|
||||||
'nickname' => $result['nickName'],
|
'nickname' => $result['nickName'],
|
||||||
];
|
];
|
||||||
if ($data['nickname'] === '微信用户') unset($data['headimg'], $data['nickname']);
|
if ($data['nickname'] === '微信用户') {
|
||||||
|
unset($data['headimg'], $data['nickname']);
|
||||||
|
}
|
||||||
$this->success('解密成功', Account::mk($this->type)->set($data, true));
|
$this->success('解密成功', Account::mk($this->type)->set($data, true));
|
||||||
} elseif (is_array($result)) {
|
} elseif (is_array($result)) {
|
||||||
if (!empty($result['phoneNumber'])) {
|
if (!empty($result['phoneNumber'])) {
|
||||||
@ -127,15 +117,14 @@ class Wxapp extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 快速获取手机号
|
* 快速获取手机号.
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public function phone()
|
public function phone()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$input = $this->_vali([
|
$input = $this->_vali([
|
||||||
'code.require' => '授权编码为空',
|
'code.require' => '授权编码为空',
|
||||||
'openid.require' => '用户编号为空'
|
'openid.require' => '用户编号为空',
|
||||||
]);
|
]);
|
||||||
$result = Crypt::instance($this->params)->getPhoneNumber($input['code']);
|
$result = Crypt::instance($this->params)->getPhoneNumber($input['code']);
|
||||||
if (is_array($result)) {
|
if (is_array($result)) {
|
||||||
@ -151,36 +140,9 @@ class Wxapp extends Controller
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 换取会话授权
|
|
||||||
* @param string $code 授权编号
|
|
||||||
* @return void|array [openid, unionid, sessionkey]
|
|
||||||
*/
|
|
||||||
private function applySesskey(string $code): array
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
$cache = $this->app->cache->get($code, []);
|
|
||||||
if (isset($cache['openid']) && isset($cache['session_key'])) {
|
|
||||||
return [$cache['openid'], $cache['unionid'] ?? '', $cache['session_key']];
|
|
||||||
}
|
|
||||||
$result = Crypt::instance($this->params)->session($code);
|
|
||||||
if (isset($result['openid']) && isset($result['session_key'])) {
|
|
||||||
$this->app->cache->set($code, $result, 7200);
|
|
||||||
return [$result['openid'], $result['unionid'] ?? '', $result['session_key']];
|
|
||||||
} else {
|
|
||||||
$this->error($result['errmsg'] ?? '换取失败');
|
|
||||||
}
|
|
||||||
} catch (HttpResponseException $exception) {
|
|
||||||
throw $exception;
|
|
||||||
} catch (\Exception $exception) {
|
|
||||||
trace_file($exception);
|
|
||||||
$this->error("授权失败,{$exception->getMessage()}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取小程序码
|
* 获取小程序码
|
||||||
* @return void|\think\Response
|
* @return Response|void
|
||||||
*/
|
*/
|
||||||
public function qrcode(): Response
|
public function qrcode(): Response
|
||||||
{
|
{
|
||||||
@ -205,7 +167,7 @@ class Wxapp extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取直播列表
|
* 获取直播列表.
|
||||||
*/
|
*/
|
||||||
public function getLiveList()
|
public function getLiveList()
|
||||||
{
|
{
|
||||||
@ -222,15 +184,15 @@ class Wxapp extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取回放源视频
|
* 获取回放源视频.
|
||||||
*/
|
*/
|
||||||
public function getLiveInfo()
|
public function getLiveInfo()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$data = $this->_vali([
|
$data = $this->_vali([
|
||||||
'start.default' => 0,
|
'start.default' => 0,
|
||||||
'limit.default' => 10,
|
'limit.default' => 10,
|
||||||
'action.default' => 'get_replay',
|
'action.default' => 'get_replay',
|
||||||
'room_id.require' => '直播间号为空',
|
'room_id.require' => '直播间号为空',
|
||||||
]);
|
]);
|
||||||
$result = Live::instance($this->params)->getLiveInfo($data);
|
$result = Live::instance($this->params)->getLiveInfo($data);
|
||||||
@ -242,4 +204,43 @@ class Wxapp extends Controller
|
|||||||
$this->error($exception->getMessage());
|
$this->error($exception->getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
/**
|
||||||
|
* 接口初始化.
|
||||||
|
* @throws \think\admin\Exception
|
||||||
|
*/
|
||||||
|
protected function initialize()
|
||||||
|
{
|
||||||
|
if (Account::field($this->type)) {
|
||||||
|
$this->params = WechatService::getWxconf();
|
||||||
|
} else {
|
||||||
|
$this->error('接口未开通');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 换取会话授权.
|
||||||
|
* @param string $code 授权编号
|
||||||
|
* @return array|void [openid, unionid, sessionkey]
|
||||||
|
*/
|
||||||
|
private function applySesskey(string $code): array
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$cache = $this->app->cache->get($code, []);
|
||||||
|
if (isset($cache['openid'], $cache['session_key'])) {
|
||||||
|
return [$cache['openid'], $cache['unionid'] ?? '', $cache['session_key']];
|
||||||
|
}
|
||||||
|
$result = Crypt::instance($this->params)->session($code);
|
||||||
|
if (isset($result['openid'], $result['session_key'])) {
|
||||||
|
$this->app->cache->set($code, $result, 7200);
|
||||||
|
return [$result['openid'], $result['unionid'] ?? '', $result['session_key']];
|
||||||
|
}
|
||||||
|
$this->error($result['errmsg'] ?? '换取失败');
|
||||||
|
} catch (HttpResponseException $exception) {
|
||||||
|
throw $exception;
|
||||||
|
} catch (\Exception $exception) {
|
||||||
|
trace_file($exception);
|
||||||
|
$this->error("授权失败,{$exception->getMessage()}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -1,20 +1,22 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// +----------------------------------------------------------------------
|
declare(strict_types=1);
|
||||||
// | Account Plugin for ThinkAdmin
|
/**
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 版权所有 2014~2025 ThinkAdmin [ thinkadmin.top ]
|
* | Payment Plugin for ThinkAdmin
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 官方网站: https://thinkadmin.top
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 免责声明 ( https://thinkadmin.top/disclaimer )
|
* | 官方网站: https://thinkadmin.top
|
||||||
// | 会员免费 ( https://thinkadmin.top/vip-introduce )
|
* +----------------------------------------------------------------------
|
||||||
// +----------------------------------------------------------------------
|
* | 开源协议 ( https://mit-license.org )
|
||||||
// | gitee 代码仓库:https://gitee.com/zoujingli/think-plugs-account
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
// | github 代码仓库:https://github.com/zoujingli/think-plugs-account
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
declare (strict_types=1);
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
namespace plugin\account\controller\api\auth;
|
namespace plugin\account\controller\api\auth;
|
||||||
|
|
||||||
@ -22,20 +24,17 @@ use plugin\account\controller\api\Auth;
|
|||||||
use plugin\account\model\PluginAccountAuth;
|
use plugin\account\model\PluginAccountAuth;
|
||||||
use plugin\account\model\PluginAccountBind;
|
use plugin\account\model\PluginAccountBind;
|
||||||
use plugin\account\service\Message;
|
use plugin\account\service\Message;
|
||||||
use think\admin\service\RuntimeService;
|
|
||||||
use think\admin\Storage;
|
use think\admin\Storage;
|
||||||
use think\exception\HttpResponseException;
|
use think\exception\HttpResponseException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用户账号管理
|
* 用户账号管理.
|
||||||
* @class Center
|
* @class Center
|
||||||
* @package plugin\account\controller\api\auth
|
|
||||||
*/
|
*/
|
||||||
class Center extends Auth
|
class Center extends Auth
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* 获取账号信息
|
* 获取账号信息.
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public function get()
|
public function get()
|
||||||
{
|
{
|
||||||
@ -43,16 +42,15 @@ class Center extends Auth
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 修改帐号信息
|
* 修改帐号信息.
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public function set()
|
public function set()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$data = $this->checkUserStatus()->_vali([
|
$data = $this->checkUserStatus()->_vali([
|
||||||
'headimg.default' => '',
|
'headimg.default' => '',
|
||||||
'nickname.default' => '',
|
'nickname.default' => '',
|
||||||
'password.default' => '',
|
'password.default' => '',
|
||||||
'region_prov.default' => '',
|
'region_prov.default' => '',
|
||||||
'region_city.default' => '',
|
'region_city.default' => '',
|
||||||
'region_area.default' => '',
|
'region_area.default' => '',
|
||||||
@ -66,8 +64,14 @@ class Center extends Auth
|
|||||||
$this->account->pwdModify($data['password']);
|
$this->account->pwdModify($data['password']);
|
||||||
unset($data['password']);
|
unset($data['password']);
|
||||||
}
|
}
|
||||||
foreach ($data as $k => $v) if ($v === '') unset($data[$k]);
|
foreach ($data as $k => $v) {
|
||||||
if (empty($data)) $this->success('无需修改', $this->account->get());
|
if ($v === '') {
|
||||||
|
unset($data[$k]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (empty($data)) {
|
||||||
|
$this->success('无需修改', $this->account->get());
|
||||||
|
}
|
||||||
$this->success('修改成功', $this->account->bind(['id' => $this->unid], $data));
|
$this->success('修改成功', $this->account->bind(['id' => $this->unid], $data));
|
||||||
} catch (HttpResponseException $exception) {
|
} catch (HttpResponseException $exception) {
|
||||||
throw $exception;
|
throw $exception;
|
||||||
@ -77,39 +81,39 @@ class Center extends Auth
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 注销当前账号
|
* 注销当前账号.
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public function forbid()
|
public function forbid()
|
||||||
{
|
{
|
||||||
if (($user = $this->account->user())->isExists()) try {
|
if (($user = $this->account->user())->isExists()) {
|
||||||
$this->app->db->transaction(function () use ($user) {
|
try {
|
||||||
$user->save(['deleted' => 1, 'remark' => '用户主动申请注销账号!']);
|
$this->app->db->transaction(function () use ($user) {
|
||||||
PluginAccountAuth::mk()->where(['usid' => $this->usid])->delete();
|
$user->save(['deleted' => 1, 'remark' => '用户主动申请注销账号!']);
|
||||||
PluginAccountBind::mk()->where(['unid' => $this->unid])->delete();
|
PluginAccountAuth::mk()->where(['usid' => $this->usid])->delete();
|
||||||
});
|
PluginAccountBind::mk()->where(['unid' => $this->unid])->delete();
|
||||||
$this->success('账号注销成功!');
|
});
|
||||||
} catch (HttpResponseException $exception) {
|
$this->success('账号注销成功!');
|
||||||
throw $exception;
|
} catch (HttpResponseException $exception) {
|
||||||
} catch (\Exception $exception) {
|
throw $exception;
|
||||||
$this->error($exception->getMessage());
|
} catch (\Exception $exception) {
|
||||||
|
$this->error($exception->getMessage());
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
$this->error('未完成注册!');
|
$this->error('未完成注册!');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 绑定主账号
|
* 绑定主账号.
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public function bind()
|
public function bind()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$data = $this->_vali([
|
$data = $this->_vali([
|
||||||
'phone.mobile' => '手机号错误',
|
'phone.mobile' => '手机号错误',
|
||||||
'phone.require' => '手机号为空',
|
'phone.require' => '手机号为空',
|
||||||
'verify.require' => '验证码为空',
|
'verify.require' => '验证码为空',
|
||||||
'passwd.default' => ''
|
'passwd.default' => '',
|
||||||
]);
|
]);
|
||||||
if (Message::checkVerifyCode($data['verify'], $data['phone'])) {
|
if (Message::checkVerifyCode($data['verify'], $data['phone'])) {
|
||||||
Message::clearVerifyCode($data['phone']);
|
Message::clearVerifyCode($data['phone']);
|
||||||
@ -137,12 +141,11 @@ class Center extends Auth
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 解除账号关联
|
* 解除账号关联.
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public function unbind()
|
public function unbind()
|
||||||
{
|
{
|
||||||
$this->account->unBind();
|
$this->account->unBind();
|
||||||
$this->success('关联成功', $this->account->get());
|
$this->success('关联成功', $this->account->get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,101 +1,106 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// +----------------------------------------------------------------------
|
declare(strict_types=1);
|
||||||
// | Account Plugin for ThinkAdmin
|
/**
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 版权所有 2014~2025 ThinkAdmin [ thinkadmin.top ]
|
* | Payment Plugin for ThinkAdmin
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 官方网站: https://thinkadmin.top
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 开源协议 ( https://mit-license.org )
|
* | 官方网站: https://thinkadmin.top
|
||||||
// | 免责声明 ( https://thinkadmin.top/disclaimer )
|
* +----------------------------------------------------------------------
|
||||||
// +----------------------------------------------------------------------
|
* | 开源协议 ( https://mit-license.org )
|
||||||
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
$extra = [];
|
$extra = [];
|
||||||
|
|
||||||
return array_merge($extra, [
|
return array_merge($extra, [
|
||||||
// 通用
|
// 通用
|
||||||
'用户管理' => 'User Management',
|
'用户管理' => 'User Management',
|
||||||
'回 收 站' => 'Recycle Bin',
|
'回 收 站' => 'Recycle Bin',
|
||||||
'排序权重' => 'Sort Weight',
|
'排序权重' => 'Sort Weight',
|
||||||
'头像' => 'Avatar',
|
'头像' => 'Avatar',
|
||||||
'账号状态' => 'Account Status',
|
'账号状态' => 'Account Status',
|
||||||
'操作面板' => 'Actions',
|
'操作面板' => 'Actions',
|
||||||
'已激活' => 'Activated',
|
'已激活' => 'Activated',
|
||||||
'已禁用' => 'Disabled',
|
'已禁用' => 'Disabled',
|
||||||
'已启用' => 'Enabled',
|
'已启用' => 'Enabled',
|
||||||
'已冻结的用户' => 'Frozen Users',
|
'已冻结的用户' => 'Frozen Users',
|
||||||
'已激活的用户' => 'Activated Users',
|
'已激活的用户' => 'Activated Users',
|
||||||
'删 除' => 'Delete',
|
'删 除' => 'Delete',
|
||||||
'保存数据' => 'Save Data',
|
'保存数据' => 'Save Data',
|
||||||
'取消编辑' => 'Cancel Edit',
|
'取消编辑' => 'Cancel Edit',
|
||||||
'保存配置' => 'Save Configuration',
|
'保存配置' => 'Save Configuration',
|
||||||
'取消修改' => 'Cancel Modification',
|
'取消修改' => 'Cancel Modification',
|
||||||
'确定要取消编辑吗?' => 'Are you sure you want to cancel editing?',
|
'确定要取消编辑吗?' => 'Are you sure you want to cancel editing?',
|
||||||
'确定要取消修改吗?' => 'Are you sure you want to cancel the modification?',
|
'确定要取消修改吗?' => 'Are you sure you want to cancel the modification?',
|
||||||
'确定要永久删除此账号吗?' => 'Are you sure you want to permanently delete this account?',
|
'确定要永久删除此账号吗?' => 'Are you sure you want to permanently delete this account?',
|
||||||
'全部' => 'All',
|
'全部' => 'All',
|
||||||
'搜 索' => 'Search',
|
'搜 索' => 'Search',
|
||||||
'导 出' => 'Export',
|
'导 出' => 'Export',
|
||||||
|
|
||||||
// 设备管理
|
// 设备管理
|
||||||
'账号接口配置' => 'Account Interface Configuration',
|
'账号接口配置' => 'Account Interface Configuration',
|
||||||
'账号配置' => 'Account Configuration',
|
'账号配置' => 'Account Configuration',
|
||||||
'终端类型' => 'Device Type',
|
'终端类型' => 'Device Type',
|
||||||
'绑定手机' => 'Bound Mobile',
|
'绑定手机' => 'Bound Mobile',
|
||||||
'用户姓名' => 'User Name',
|
'用户姓名' => 'User Name',
|
||||||
'用户昵称' => 'User Nickname',
|
'用户昵称' => 'User Nickname',
|
||||||
'关联账号' => 'Associated Account',
|
'关联账号' => 'Associated Account',
|
||||||
'使用状态' => 'Status',
|
'使用状态' => 'Status',
|
||||||
'首次登录' => 'First Login',
|
'首次登录' => 'First Login',
|
||||||
'请输入绑定手机' => 'Please enter bound mobile',
|
'请输入绑定手机' => 'Please enter bound mobile',
|
||||||
'请输入用户姓名' => 'Please enter user name',
|
'请输入用户姓名' => 'Please enter user name',
|
||||||
'请输入用户昵称' => 'Please enter user nickname',
|
'请输入用户昵称' => 'Please enter user nickname',
|
||||||
'请选择绑定时间' => 'Please select binding time',
|
'请选择绑定时间' => 'Please select binding time',
|
||||||
'用户账号数据' => 'User Account Data',
|
'用户账号数据' => 'User Account Data',
|
||||||
|
|
||||||
// 主账号管理
|
// 主账号管理
|
||||||
'用户编号' => 'User Code',
|
'用户编号' => 'User Code',
|
||||||
'绑定邮箱' => 'Bound Email',
|
'绑定邮箱' => 'Bound Email',
|
||||||
'绑定时间' => 'Binding Time',
|
'绑定时间' => 'Binding Time',
|
||||||
'请输入用户编号' => 'Please enter user code',
|
'请输入用户编号' => 'Please enter user code',
|
||||||
'请输入绑定邮箱' => 'Please enter bound email',
|
'请输入绑定邮箱' => 'Please enter bound email',
|
||||||
|
|
||||||
// 消息管理
|
// 消息管理
|
||||||
'短信配置' => 'SMS Configuration',
|
'短信配置' => 'SMS Configuration',
|
||||||
'消息编号' => 'Message Code',
|
'消息编号' => 'Message Code',
|
||||||
'短信类型' => 'SMS Type',
|
'短信类型' => 'SMS Type',
|
||||||
'发送手机' => 'Send Mobile',
|
'发送手机' => 'Send Mobile',
|
||||||
'短信内容' => 'SMS Content',
|
'短信内容' => 'SMS Content',
|
||||||
'发送时间' => 'Send Time',
|
'发送时间' => 'Send Time',
|
||||||
'发送失败' => 'Send Failed',
|
'发送失败' => 'Send Failed',
|
||||||
'发送成功' => 'Send Success',
|
'发送成功' => 'Send Success',
|
||||||
'请输入消息编号' => 'Please enter message code',
|
'请输入消息编号' => 'Please enter message code',
|
||||||
'请输入发送手机' => 'Please enter send mobile',
|
'请输入发送手机' => 'Please enter send mobile',
|
||||||
'请输入短信内容' => 'Please enter SMS content',
|
'请输入短信内容' => 'Please enter SMS content',
|
||||||
'请选择发送时间' => 'Please select send time',
|
'请选择发送时间' => 'Please select send time',
|
||||||
|
|
||||||
// 短信配置
|
// 短信配置
|
||||||
'服务区域' => 'Service Region',
|
'服务区域' => 'Service Region',
|
||||||
'阿里云账号' => 'Aliyun Account',
|
'阿里云账号' => 'Aliyun Account',
|
||||||
'阿里云密钥' => 'Aliyun Secret Key',
|
'阿里云密钥' => 'Aliyun Secret Key',
|
||||||
'短信签名' => 'SMS Signature',
|
'短信签名' => 'SMS Signature',
|
||||||
'短信模板编号' => 'SMS Template Code',
|
'短信模板编号' => 'SMS Template Code',
|
||||||
'请输入阿里云账号' => 'Please enter Aliyun account',
|
'请输入阿里云账号' => 'Please enter Aliyun account',
|
||||||
'请输入阿里云密钥' => 'Please enter Aliyun secret key',
|
'请输入阿里云密钥' => 'Please enter Aliyun secret key',
|
||||||
'请输入短信签名' => 'Please enter SMS signature',
|
'请输入短信签名' => 'Please enter SMS signature',
|
||||||
'请输入短信模板编号' => 'Please enter SMS template code',
|
'请输入短信模板编号' => 'Please enter SMS template code',
|
||||||
|
|
||||||
// 账号配置
|
// 账号配置
|
||||||
'认证有效时间' => 'Authentication Expire Time',
|
'认证有效时间' => 'Authentication Expire Time',
|
||||||
'登录自动注册' => 'Auto Register on Login',
|
'登录自动注册' => 'Auto Register on Login',
|
||||||
'默认昵称前缀' => 'Default Nickname Prefix',
|
'默认昵称前缀' => 'Default Nickname Prefix',
|
||||||
'默认用户头像' => 'Default User Avatar',
|
'默认用户头像' => 'Default User Avatar',
|
||||||
'开放接口通道' => 'Open Interface Channels',
|
'开放接口通道' => 'Open Interface Channels',
|
||||||
'设置为 0 表示永不过期,建议设置有效时间达到系统自动回收令牌。' => 'Set to 0 means never expires. It is recommended to set an expiration time for automatic token recycling.',
|
'设置为 0 表示永不过期,建议设置有效时间达到系统自动回收令牌。' => 'Set to 0 means never expires. It is recommended to set an expiration time for automatic token recycling.',
|
||||||
'启用自动登录时,通过验证码登录时账号不存在会自动创建!' => 'When auto login is enabled, accounts that do not exist will be automatically created when logging in with verification code!',
|
'启用自动登录时,通过验证码登录时账号不存在会自动创建!' => 'When auto login is enabled, accounts that do not exist will be automatically created when logging in with verification code!',
|
||||||
'用户绑定账号后会自动使用此前缀与手机号后4位拼接为新默认昵称。' => 'After user binds account, this prefix will be automatically combined with the last 4 digits of mobile number as new default nickname.',
|
'用户绑定账号后会自动使用此前缀与手机号后4位拼接为新默认昵称。' => 'After user binds account, this prefix will be automatically combined with the last 4 digits of mobile number as new default nickname.',
|
||||||
'当用户未设置头像时,自动使用此头像设置的图片链接。' => 'When user has not set avatar, automatically use the image link set in this avatar.',
|
'当用户未设置头像时,自动使用此头像设置的图片链接。' => 'When user has not set avatar, automatically use the image link set in this avatar.',
|
||||||
'请输入默认昵称前缀' => 'Please enter default nickname prefix',
|
'请输入默认昵称前缀' => 'Please enter default nickname prefix',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|||||||
@ -1,37 +1,36 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// +----------------------------------------------------------------------
|
declare(strict_types=1);
|
||||||
// | Account Plugin for ThinkAdmin
|
/**
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 版权所有 2014~2025 ThinkAdmin [ thinkadmin.top ]
|
* | Payment Plugin for ThinkAdmin
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 官方网站: https://thinkadmin.top
|
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
// | 免责声明 ( https://thinkadmin.top/disclaimer )
|
* | 官方网站: https://thinkadmin.top
|
||||||
// | 会员免费 ( https://thinkadmin.top/vip-introduce )
|
* +----------------------------------------------------------------------
|
||||||
// +----------------------------------------------------------------------
|
* | 开源协议 ( https://mit-license.org )
|
||||||
// | gitee 代码仓库:https://gitee.com/zoujingli/think-plugs-account
|
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
// | github 代码仓库:https://github.com/zoujingli/think-plugs-account
|
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||||||
// +----------------------------------------------------------------------
|
* +----------------------------------------------------------------------
|
||||||
|
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||||||
declare (strict_types=1);
|
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||||||
|
* +----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
namespace plugin\account\model;
|
namespace plugin\account\model;
|
||||||
|
|
||||||
use think\admin\Model;
|
use think\admin\Model;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 模型抽象类
|
* 模型抽象类.
|
||||||
* @class Abs
|
* @class Abs
|
||||||
* @package plugin\account\model
|
|
||||||
*/
|
*/
|
||||||
abstract class Abs extends Model
|
abstract class Abs extends Model
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 格式化输出时间
|
* 格式化输出时间.
|
||||||
* @param mixed $value
|
* @param mixed $value
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public function getCreateTimeAttr($value): string
|
public function getCreateTimeAttr($value): string
|
||||||
{
|
{
|
||||||
@ -39,9 +38,8 @@ abstract class Abs extends Model
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 格式化输出时间
|
* 格式化输出时间.
|
||||||
* @param mixed $value
|
* @param mixed $value
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public function getUpdateTimeAttr($value): string
|
public function getUpdateTimeAttr($value): string
|
||||||
{
|
{
|
||||||
@ -49,9 +47,8 @@ abstract class Abs extends Model
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 时间写入格式化
|
* 时间写入格式化.
|
||||||
* @param mixed $value
|
* @param mixed $value
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public function setCreateTimeAttr($value): string
|
public function setCreateTimeAttr($value): string
|
||||||
{
|
{
|
||||||
@ -59,9 +56,8 @@ abstract class Abs extends Model
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 时间写入格式化
|
* 时间写入格式化.
|
||||||
* @param mixed $value
|
* @param mixed $value
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public function setUpdateTimeAttr($value): string
|
public function setUpdateTimeAttr($value): string
|
||||||
{
|
{
|
||||||
@ -69,9 +65,8 @@ abstract class Abs extends Model
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 字段属性处理
|
* 字段属性处理.
|
||||||
* @param mixed $value
|
* @param mixed $value
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public function setExtraAttr($value): string
|
public function setExtraAttr($value): string
|
||||||
{
|
{
|
||||||
@ -79,12 +74,11 @@ abstract class Abs extends Model
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 字段属性处理
|
* 字段属性处理.
|
||||||
* @param mixed $value
|
* @param mixed $value
|
||||||
* @return array
|
|
||||||
*/
|
*/
|
||||||
public function getExtraAttr($value): array
|
public function getExtraAttr($value): array
|
||||||
{
|
{
|
||||||
return empty($value) ? [] : (is_string($value) ? json_decode($value, true) : $value);
|
return empty($value) ? [] : (is_string($value) ? json_decode($value, true) : $value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user