diff --git a/app/BaseController.php b/app/BaseController.php
index 7980d44..fb75591 100644
--- a/app/BaseController.php
+++ b/app/BaseController.php
@@ -4,97 +4,11 @@ declare(strict_types=1);
namespace app;
-use think\App;
-use think\exception\ValidateException;
-use think\facade\Log;
-use think\Validate;
+use base\BaseControllerBase;
/**
- * 控制器基础类
+ * 控制器基础类.
*/
-abstract class BaseController
+abstract class BaseController extends BaseControllerBase
{
- /**
- * Request实例
- * @var \think\Request
- */
- protected $request;
-
- /**
- * 应用实例
- * @var \think\App
- */
- protected $app;
-
- /**
- * 是否批量验证
- * @var bool
- */
- protected $batchValidate = false;
-
- /**
- * 控制器中间件
- * @var array
- */
- protected $middleware = [];
-
- /**
- * 构造方法
- * @access public
- * @param App $app 应用对象
- */
- public function __construct(App $app)
- {
- $this->app = $app;
- $this->request = $this->app->request;
-
- // 控制器初始化
- $this->initialize();
- }
-
- // 初始化
- protected function initialize()
- {
-
- Log::debug('request url :' . $this->request->url());
- }
-
- /**
- * 验证数据
- * @access protected
- * @param array $data 数据
- * @param string|array $validate 验证器名或者验证规则数组
- * @param array $message 提示信息
- * @param bool $batch 是否批量验证
- * @return array|string|true
- * @throws ValidateException
- */
- protected function validate(array $data, $validate, array $message = [], bool $batch = false)
- {
- if (is_array($validate)) {
- $v = new Validate();
- $v->rule($validate);
- } else if ($validate instanceof Validate) {
- $v = $validate;
- } else {
- if (strpos($validate, '.')) {
- // 支持场景
- list($validate, $scene) = explode('.', $validate);
- }
- $class = false !== strpos($validate, '\\') ? $validate : $this->app->parseClass('validate', $validate);
- $v = new $class();
- if (!empty($scene)) {
- $v->scene($scene);
- }
- }
-
- $v->message($message);
-
- // 是否批量验证
- if ($batch || $this->batchValidate) {
- $v->batch(true);
- }
-
- return $v->failException(true)->check($data);
- }
}
diff --git a/app/admin/config/admin.php b/app/admin/config/admin.php
index b310722..af80f18 100644
--- a/app/admin/config/admin.php
+++ b/app/admin/config/admin.php
@@ -1,5 +1,5 @@
[
-
- ],
-];
diff --git a/app/admin/config/route.php b/app/admin/config/route.php
deleted file mode 100644
index bfae446..0000000
--- a/app/admin/config/route.php
+++ /dev/null
@@ -1,12 +0,0 @@
- [
-
- ],
-];
diff --git a/app/admin/event.php b/app/admin/event.php
index 9fcdd2a..e854c02 100644
--- a/app/admin/event.php
+++ b/app/admin/event.php
@@ -1,5 +1,7 @@
[
diff --git a/app/admin/middleware.php b/app/admin/middleware.php
index bd595d4..0224517 100644
--- a/app/admin/middleware.php
+++ b/app/admin/middleware.php
@@ -1,4 +1,7 @@
build();
-
- $url_data = parse_url($url);
-
- $url_path = $url_data['path'];
-
- $url_arr = explode('/', $url_path);
-
- $app_map = config('app.app_map');
-
- $app_name = array_search($url_arr[1], $app_map);
-
- if (!empty($app_name)) {
- $url_arr[1] = $app_name;
- }
-
- $url_path = implode('/', $url_arr);
-
- $url_data['path'] = $url_path;
-
- $url = unparse_url($url_data);
-
- return $url;
- }
-}
-
-if (!function_exists('password')) {
- /**
- * 密码加密算法.
- * @param $value 需要加密的值
- * @param $type 加密类型,默认为md5 (md5, hash)
- * @return mixed
- */
- function password($value, $salt = '_encrypt')
- {
- $value = sha1('ul_' . $salt) . md5($value) . md5($salt) . sha1($value);
-
- return sha1($value);
- }
-}
-
-if (!function_exists('xdebug')) {
- /**
- * debug调试.
- * @deprecated 不建议使用,建议直接使用框架自带的log组件
- * @param string|array $data 打印信息
- * @param string $type 类型
- * @param string $suffix 文件后缀名
- * @param bool $force
- * @param null $file
- */
- function xdebug($data, $type = 'xdebug', $suffix = null, $force = false, $file = null)
- {
- !is_dir(runtime_path() . 'xdebug/') && mkdir(runtime_path() . 'xdebug/');
- if (is_null($file)) {
- $file = is_null($suffix) ? runtime_path() . 'xdebug/' . date('Ymd') . '.txt' : runtime_path() . 'xdebug/' . date('Ymd') . "_{$suffix}" . '.txt';
- }
- file_put_contents($file, '[' . date('Y-m-d H:i:s') . '] ' . "========================= {$type} ===========================" . PHP_EOL, FILE_APPEND);
-
- $str = '';
-
- if (is_string($data)) {
- $str = $data;
- } else {
- if (is_array($data) || is_object($data)) {
- $str = print_r($data, true);
- } else {
- $str = var_export($data, true);
- }
- }
-
- $str . PHP_EOL;
-
- $force ? file_put_contents($file, $str) : file_put_contents($file, $str, FILE_APPEND);
- }
-}
-
-if (!function_exists('sysconfig')) {
- /**
- * 获取系统配置信息.
- * @param $group
- * @param null|bool|string $name
- * @return array|mixed
- */
- function sysconfig($group, $name = null, $default = null)
- {
- if ($name === true) {
- $value = Cache::get('sysconfig_' . $group);
-
- if (empty($value)) {
- $value = \app\admin\model\SystemConfig::where('name', $group)->value('value');
- Cache::tag('sysconfig')->set('sysconfig_' . $group, $value);
- }
- if (is_null($value)) {
- return $default;
- }
-
- return $value;
- }
-
- $where = ['group' => $group];
- $value = empty($name) ? Cache::get("sysconfig_{$group}") : Cache::get("sysconfig_{$group}_{$name}");
- if (empty($value)) {
- if (!empty($name)) {
- $where['name'] = $name;
- $value = \app\admin\model\SystemConfig::where($where)->value('value');
- Cache::tag('sysconfig')->set("sysconfig_{$group}_{$name}", $value, 3600);
- } else {
- $value = \app\admin\model\SystemConfig::where($where)->column('value', 'name');
- Cache::tag('sysconfig')->set("sysconfig_{$group}", $value, 3600);
- }
- }
- if (is_null($value)) {
- return $default;
- }
-
- return $value;
- }
-}
-
-if (!function_exists('array_format_key')) {
- /**
- * 二位数组重新组合数据.
- * @param $array
- * @param $key
- * @return array
- */
- function array_format_key($array, $key)
- {
- $newArray = [];
- foreach ($array as $vo) {
- $newArray[$vo[$key]] = $vo;
- }
-
- return $newArray;
- }
-}
-
-if (!function_exists('auth')) {
- /**
- * auth权限验证
- * @param $node
- * @return bool
- * @throws \think\db\exception\DataNotFoundException
- * @throws \think\db\exception\DbException
- * @throws \think\db\exception\ModelNotFoundException
- */
- function auth($node = null)
- {
- $authService = new AuthService(session('admin.id'));
- $check = $authService->checkNode($node);
-
- return $check;
- }
-}
-
-function json_message($data = [], $code = 0, $msg = '')
-{
- if (is_string($data)) {
- if (strpos($data, 'http') === 0 || strpos($data, '/') === 0) {
- $data = [
- 'jump_to_url' => $data,
- ];
- } else {
- $code = $code === 0 ? 500 : $code;
- $msg = $data;
- $data = [];
- }
- } elseif ($data instanceof Url) {
- $data = [
- 'jump_to_url' => (string) $data,
- ];
- }
-
- return json([
- 'code' => $code,
- 'msg' => $msg,
- 'data' => $data,
- ]);
-}
-
-if (!function_exists('unparse_url')) {
- function unparse_url($parsed_url)
- {
- $scheme = isset($parsed_url['scheme']) ? $parsed_url['scheme'] . '://' : '';
- $host = isset($parsed_url['host']) ? $parsed_url['host'] : '';
- $port = isset($parsed_url['port']) ? ':' . $parsed_url['port'] : '';
- $user = isset($parsed_url['user']) ? $parsed_url['user'] : '';
- $pass = isset($parsed_url['pass']) ? ':' . $parsed_url['pass'] : '';
- $pass = ($user || $pass) ? "$pass@" : '';
- $path = isset($parsed_url['path']) ? $parsed_url['path'] : '';
- $query = isset($parsed_url['query']) ? '?' . $parsed_url['query'] : '';
- $fragment = isset($parsed_url['fragment']) ? '#' . $parsed_url['fragment'] : '';
-
- return "$scheme$user$pass$host$port$path$query$fragment";
- }
-}
-
-function build_upload_url($url, $upload_type = null)
-{
- if (is_null($upload_type)) {
- $upload_type = sysconfig('upload', 'upload_type', 'local_public');
- }
-
- return Filesystem::disk($upload_type)->url($url);
-}
-
-function event_handle_result($name, $key, $type = 'all', $params = []) : array
-{
- $list_result = Event::trigger($name, $params);
-
- $result = [];
-
- foreach ($list_result as $key_event => $value_event) {
- if (!isset($value_event[$key])) {
- if (Env::get('adminsystem.strict_event')) {
- throw new EventException("Event view {$name} trigger a result without a {$key}");
- }
- continue;
- }
- if ($type == 'all') {
- $result[] = $value_event[$key];
- } elseif ($type == 'last') {
- $result = [];
- $result[] = $value_event[$key];
- } elseif ($type == 'first') {
- $result[] = $value_event[$key];
- break;
- }
- }
-
- return $result;
-}
-
-function event_view_content($name)
-{
- $list_result = event_handle_result($name, 'view_content');
-
- $content = implode('', $list_result);
-
- return $content;
-}
-
-function event_view_replace($content, $name)
-{
- $list_result = event_handle_result($name, 'view_replace');
-
- $content_event = implode('', $list_result);
-
- if (empty($content_event)) {
- return $content;
- }
-
- return $content_event;
-}
-
-function event_view_replace_js($name)
-{
- $list_result = event_handle_result($name, 'view_replace_js');
-
- $content_event = implode('', $list_result);
-
- return "";
-}
-
-function event_response($name, $params = [])
-{
- $list_result = event_handle_result($name, 'response', 'last', $params);
-
- if (empty($list_result)) {
- return;
- }
-
- $response = $list_result[0];
-
- if (is_string($response)) {
- $response = View::create($response);
- }
-
- throw new HttpResponseException($response);
-}
-
-/**
- * 以扩展的架构定位app下的文件位置
- *
- * @param string $file_path 文件路径,不要以/开头,不需要以app开头,会自动定位app或extend/base。
- * @return string
- */
-function app_file_path($file_path)
-{
- $app_file_path = App::getRootPath() . 'app' . DIRECTORY_SEPARATOR . $file_path;
- if (!is_file($app_file_path)) {
- $app_file_path = App::getRootPath() . 'extend' . DIRECTORY_SEPARATOR . 'base' . DIRECTORY_SEPARATOR . $file_path;
- }
-
- return $app_file_path;
-}
+include App::getRootPath() . '/extend/base/helper.php';
diff --git a/app/common/app/functions.php b/app/common/app/functions.php
deleted file mode 100644
index b3d9bbc..0000000
--- a/app/common/app/functions.php
+++ /dev/null
@@ -1 +0,0 @@
-table('{$table}')
- ->setComment('{$table_info.TABLE_COMMENT}')
- {volist name="table_columns" id="column"}->addColumn('{$column.field}', '{$column.type}', [{volist name="column.options" id="option"}'{$key}' => {$option|raw}, {/volist}])
- {/volist}
- {volist name="table_keys_uni" id="vo"}->addIndex('{$vo}',['unique'=>true])
- {/volist}
- {volist name="table_keys_text" id="vo"}->addIndex('{$vo}',['type'=>'fulltext'])
- {/volist}
- {volist name="table_keys" id="vo"}->addIndex('{$vo}')
- {/volist}->create();
- }
-}
diff --git a/app/common/command/timer/config.php b/app/common/command/timer/config.php
deleted file mode 100644
index 32202e4..0000000
--- a/app/common/command/timer/config.php
+++ /dev/null
@@ -1,16 +0,0 @@
- 'http_demo', // 定时任务的名称,不能重复
- 'type' => 'site', // 定时任务的类型,默认只支持site,你也可以重写定时器命令行以支持其他命令
- 'target' => '/tools/timer.ResetPassword/do', // 要访问的地址,如果不是以https开头,那么以后台的系统配置中读取相关配置,如果没有配置则不执行
- 'frequency' => 600 // 执行频率,单位:秒,填写10,则每10秒过后执行一次
- ],
- [
- 'name' => 'clear_log', // 定时任务的名称,不能重复
- 'type' => 'site', // 定时任务的类型,默认只支持site,你也可以重写定时器命令行以支持其他命令
- 'target' => '/tools/timer.ClearLog/do', // 要访问的地址,如果不是以https开头,那么以后台的系统配置中读取相关配置,如果没有配置则不执行
- 'frequency' => 600 // 执行频率,单位:秒,填写10,则每10秒过后执行一次
- ],
-];
diff --git a/app/event.php b/app/event.php
index d64d8de..1be2df1 100644
--- a/app/event.php
+++ b/app/event.php
@@ -2,10 +2,7 @@
// 事件定义文件
-use app\common\event\AdminLoginSuccess\LogEvent;
-use app\common\event\AdminLoginType\DemoEvent;
-
-$event = [
+return [
'bind' => [
],
@@ -16,19 +13,13 @@ $event = [
'LogLevel' => [],
'LogWrite' => [],
'AdminLoginSuccess' => [
- LogEvent::class,
+
],
'AdminLoginType' => [
- DemoEvent::class,
+
],
],
'subscribe' => [
],
];
-
-$listen = include __DIR__ . '/common/app/listen.php';
-
-$event['listen'] = array_merge($event['listen'], $listen);
-
-return $event;
diff --git a/app/middleware.php b/app/middleware.php
index 8b12ac4..4122ec4 100644
--- a/app/middleware.php
+++ b/app/middleware.php
@@ -2,19 +2,6 @@
// 全局中间件定义文件
-$middleware_default = [
- // 全局请求缓存
- // \think\middleware\CheckRequestCache::class,
- // 多语言加载
- // \think\middleware\LoadLangPack::class,
- // Session初始化
- 100 => \think\middleware\SessionInit::class,
+return [
+
];
-
-$middleware_common = include_once __DIR__ . '/common/app/middleware.php';
-
-$middleware = array_merge($middleware_default, $middleware_common);
-
-ksort($middleware);
-
-return $middleware;
diff --git a/app/provider.php b/app/provider.php
index 01dfdd3..926ecfa 100644
--- a/app/provider.php
+++ b/app/provider.php
@@ -2,16 +2,6 @@
// 容器Provider定义文件
-use app\common\provider\ExceptionHandle;
-use app\common\provider\Request;
-use app\common\provider\View;
+return [
-$provider_default = [
- 'think\Request' => Request::class,
- 'think\exception\Handle' => ExceptionHandle::class,
- 'think\View' => View::class,
];
-
-$provider_common = include_once __DIR__ . '/common/app/provider.php';
-
-return array_merge($provider_default, $provider_common);
diff --git a/app/service.php b/app/service.php
index cd91d6d..23fe0c2 100644
--- a/app/service.php
+++ b/app/service.php
@@ -2,18 +2,10 @@
declare(strict_types=1);
-use think\migration\Service;
+use think\UlthonAdminService;
-$service_default = [
- 0 => 'think\\captcha\\CaptchaService',
- 1 => 'think\\app\\Service',
- 2 => Service::class,
+$service = [
+ 10 => UlthonAdminService::class,
];
-$service_common = include_once __DIR__ . '/common/app/service.php';
-
-$service = array_merge($service_default, $service_common);
-
-ksort($service);
-
return $service;
diff --git a/app/tools/controller/timer/ClearLog.php b/app/tools/controller/timer/ClearLog.php
index b2184cf..cb793a9 100644
--- a/app/tools/controller/timer/ClearLog.php
+++ b/app/tools/controller/timer/ClearLog.php
@@ -4,21 +4,8 @@ declare(strict_types=1);
namespace app\tools\controller\timer;
-use app\common\controller\TimerController;
-use think\facade\Db;
-use think\facade\Log;
-use think\Request;
+use base\tools\controller\timer\ClearLogBase;
-class ClearLog extends TimerController
+class ClearLog extends ClearLogBase
{
-
- protected $frequency = 600;
-
- public function do()
- {
- Log::debug('清除3天的日志');
- Db::name('debug_log')->where('create_time', '<', time() - 60 * 60 * 24 * 3)->delete();
-
- return 'success';
- }
}
diff --git a/app/tools/controller/timer/ResetPassword.php b/app/tools/controller/timer/ResetPassword.php
index cc3a0dc..c56b299 100644
--- a/app/tools/controller/timer/ResetPassword.php
+++ b/app/tools/controller/timer/ResetPassword.php
@@ -4,25 +4,8 @@ declare(strict_types=1);
namespace app\tools\controller\timer;
-use app\common\controller\TimerController;
-use think\facade\Console;
+use base\tools\controller\timer\ResetPasswordBase;
-class ResetPassword extends TimerController
+class ResetPassword extends ResetPasswordBase
{
-
- protected $frequency = 600;
-
- public function do()
- {
-
- if (!env('adminsystem.is_demo', false)) {
- return $this->error('本功能只有在演示环境下在能使用', '', '/');
- }
-
- $output = Console::call('admin:resetPassword', [
- '--password=123456'
- ]);
-
- return $output->fetch();
- }
}
diff --git a/extend/base/BaseControllerBase.php b/extend/base/BaseControllerBase.php
new file mode 100644
index 0000000..21680fb
--- /dev/null
+++ b/extend/base/BaseControllerBase.php
@@ -0,0 +1,100 @@
+app = $app;
+ $this->request = $this->app->request;
+
+ // 控制器初始化
+ $this->initialize();
+ }
+
+ // 初始化
+ protected function initialize()
+ {
+
+ Log::debug('request url :' . $this->request->url());
+ }
+
+ /**
+ * 验证数据
+ * @access protected
+ * @param array $data 数据
+ * @param string|array $validate 验证器名或者验证规则数组
+ * @param array $message 提示信息
+ * @param bool $batch 是否批量验证
+ * @return array|string|true
+ * @throws ValidateException
+ */
+ protected function validate(array $data, $validate, array $message = [], bool $batch = false)
+ {
+ if (is_array($validate)) {
+ $v = new Validate();
+ $v->rule($validate);
+ } else if ($validate instanceof Validate) {
+ $v = $validate;
+ } else {
+ if (strpos($validate, '.')) {
+ // 支持场景
+ list($validate, $scene) = explode('.', $validate);
+ }
+ $class = false !== strpos($validate, '\\') ? $validate : $this->app->parseClass('validate', $validate);
+ $v = new $class();
+ if (!empty($scene)) {
+ $v->scene($scene);
+ }
+ }
+
+ $v->message($message);
+
+ // 是否批量验证
+ if ($batch || $this->batchValidate) {
+ $v->batch(true);
+ }
+
+ return $v->failException(true)->check($data);
+ }
+}
diff --git a/extend/base/admin/event.php b/extend/base/admin/event.php
new file mode 100644
index 0000000..9fcdd2a
--- /dev/null
+++ b/extend/base/admin/event.php
@@ -0,0 +1,18 @@
+ [
+ ],
+
+ 'listen' => [
+ 'AppInit' => [],
+ 'HttpRun' => [],
+ 'HttpEnd' => [],
+ 'LogLevel' => [],
+ 'LogWrite' => [],
+ ],
+
+ 'subscribe' => [
+ ],
+];
diff --git a/extend/base/admin/middleware.php b/extend/base/admin/middleware.php
new file mode 100644
index 0000000..bd595d4
--- /dev/null
+++ b/extend/base/admin/middleware.php
@@ -0,0 +1,14 @@
+build();
+
+ $url_data = parse_url($url);
+
+ $url_path = $url_data['path'];
+
+ $url_arr = explode('/', $url_path);
+
+ $app_map = config('app.app_map');
+
+ $app_name = array_search($url_arr[1], $app_map);
+
+ if (!empty($app_name)) {
+ $url_arr[1] = $app_name;
+ }
+
+ $url_path = implode('/', $url_arr);
+
+ $url_data['path'] = $url_path;
+
+ $url = unparse_url($url_data);
+
+ return $url;
+ }
+}
+
+if (!function_exists('password')) {
+ /**
+ * 密码加密算法.
+ * @param $value 需要加密的值
+ * @param $type 加密类型,默认为md5 (md5, hash)
+ * @return mixed
+ */
+ function password($value, $salt = '_encrypt')
+ {
+ $value = sha1('ul_' . $salt) . md5($value) . md5($salt) . sha1($value);
+
+ return sha1($value);
+ }
+}
+
+if (!function_exists('xdebug')) {
+ /**
+ * debug调试.
+ * @deprecated 不建议使用,建议直接使用框架自带的log组件
+ * @param string|array $data 打印信息
+ * @param string $type 类型
+ * @param string $suffix 文件后缀名
+ * @param bool $force
+ * @param null $file
+ */
+ function xdebug($data, $type = 'xdebug', $suffix = null, $force = false, $file = null)
+ {
+ !is_dir(runtime_path() . 'xdebug/') && mkdir(runtime_path() . 'xdebug/');
+ if (is_null($file)) {
+ $file = is_null($suffix) ? runtime_path() . 'xdebug/' . date('Ymd') . '.txt' : runtime_path() . 'xdebug/' . date('Ymd') . "_{$suffix}" . '.txt';
+ }
+ file_put_contents($file, '[' . date('Y-m-d H:i:s') . '] ' . "========================= {$type} ===========================" . PHP_EOL, FILE_APPEND);
+
+ $str = '';
+
+ if (is_string($data)) {
+ $str = $data;
+ } else {
+ if (is_array($data) || is_object($data)) {
+ $str = print_r($data, true);
+ } else {
+ $str = var_export($data, true);
+ }
+ }
+
+ $str . PHP_EOL;
+
+ $force ? file_put_contents($file, $str) : file_put_contents($file, $str, FILE_APPEND);
+ }
+}
+
+if (!function_exists('sysconfig')) {
+ /**
+ * 获取系统配置信息.
+ * @param $group
+ * @param null|bool|string $name
+ * @return array|mixed
+ */
+ function sysconfig($group, $name = null, $default = null)
+ {
+ if ($name === true) {
+ $value = Cache::get('sysconfig_' . $group);
+
+ if (empty($value)) {
+ $value = \app\admin\model\SystemConfig::where('name', $group)->value('value');
+ Cache::tag('sysconfig')->set('sysconfig_' . $group, $value);
+ }
+ if (is_null($value)) {
+ return $default;
+ }
+
+ return $value;
+ }
+
+ $where = ['group' => $group];
+ $value = empty($name) ? Cache::get("sysconfig_{$group}") : Cache::get("sysconfig_{$group}_{$name}");
+ if (empty($value)) {
+ if (!empty($name)) {
+ $where['name'] = $name;
+ $value = \app\admin\model\SystemConfig::where($where)->value('value');
+ Cache::tag('sysconfig')->set("sysconfig_{$group}_{$name}", $value, 3600);
+ } else {
+ $value = \app\admin\model\SystemConfig::where($where)->column('value', 'name');
+ Cache::tag('sysconfig')->set("sysconfig_{$group}", $value, 3600);
+ }
+ }
+ if (is_null($value)) {
+ return $default;
+ }
+
+ return $value;
+ }
+}
+
+if (!function_exists('array_format_key')) {
+ /**
+ * 二位数组重新组合数据.
+ * @param $array
+ * @param $key
+ * @return array
+ */
+ function array_format_key($array, $key)
+ {
+ $newArray = [];
+ foreach ($array as $vo) {
+ $newArray[$vo[$key]] = $vo;
+ }
+
+ return $newArray;
+ }
+}
+
+if (!function_exists('auth')) {
+ /**
+ * auth权限验证
+ * @param $node
+ * @return bool
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ function auth($node = null)
+ {
+ $authService = new AuthService(session('admin.id'));
+ $check = $authService->checkNode($node);
+
+ return $check;
+ }
+}
+
+function json_message($data = [], $code = 0, $msg = '')
+{
+ if (is_string($data)) {
+ if (strpos($data, 'http') === 0 || strpos($data, '/') === 0) {
+ $data = [
+ 'jump_to_url' => $data,
+ ];
+ } else {
+ $code = $code === 0 ? 500 : $code;
+ $msg = $data;
+ $data = [];
+ }
+ } elseif ($data instanceof Url) {
+ $data = [
+ 'jump_to_url' => (string) $data,
+ ];
+ }
+
+ return json([
+ 'code' => $code,
+ 'msg' => $msg,
+ 'data' => $data,
+ ]);
+}
+
+if (!function_exists('unparse_url')) {
+ function unparse_url($parsed_url)
+ {
+ $scheme = isset($parsed_url['scheme']) ? $parsed_url['scheme'] . '://' : '';
+ $host = isset($parsed_url['host']) ? $parsed_url['host'] : '';
+ $port = isset($parsed_url['port']) ? ':' . $parsed_url['port'] : '';
+ $user = isset($parsed_url['user']) ? $parsed_url['user'] : '';
+ $pass = isset($parsed_url['pass']) ? ':' . $parsed_url['pass'] : '';
+ $pass = ($user || $pass) ? "$pass@" : '';
+ $path = isset($parsed_url['path']) ? $parsed_url['path'] : '';
+ $query = isset($parsed_url['query']) ? '?' . $parsed_url['query'] : '';
+ $fragment = isset($parsed_url['fragment']) ? '#' . $parsed_url['fragment'] : '';
+
+ return "$scheme$user$pass$host$port$path$query$fragment";
+ }
+}
+
+function build_upload_url($url, $upload_type = null)
+{
+ if (is_null($upload_type)) {
+ $upload_type = sysconfig('upload', 'upload_type', 'local_public');
+ }
+
+ return Filesystem::disk($upload_type)->url($url);
+}
+
+function event_handle_result($name, $key, $type = 'all', $params = []) : array
+{
+ $list_result = Event::trigger($name, $params);
+
+ $result = [];
+
+ foreach ($list_result as $key_event => $value_event) {
+ if (!isset($value_event[$key])) {
+ if (Env::get('adminsystem.strict_event')) {
+ throw new EventException("Event view {$name} trigger a result without a {$key}");
+ }
+ continue;
+ }
+ if ($type == 'all') {
+ $result[] = $value_event[$key];
+ } elseif ($type == 'last') {
+ $result = [];
+ $result[] = $value_event[$key];
+ } elseif ($type == 'first') {
+ $result[] = $value_event[$key];
+ break;
+ }
+ }
+
+ return $result;
+}
+
+function event_view_content($name)
+{
+ $list_result = event_handle_result($name, 'view_content');
+
+ $content = implode('', $list_result);
+
+ return $content;
+}
+
+function event_view_replace($content, $name)
+{
+ $list_result = event_handle_result($name, 'view_replace');
+
+ $content_event = implode('', $list_result);
+
+ if (empty($content_event)) {
+ return $content;
+ }
+
+ return $content_event;
+}
+
+function event_view_replace_js($name)
+{
+ $list_result = event_handle_result($name, 'view_replace_js');
+
+ $content_event = implode('', $list_result);
+
+ return "";
+}
+
+function event_response($name, $params = [])
+{
+ $list_result = event_handle_result($name, 'response', 'last', $params);
+
+ if (empty($list_result)) {
+ return;
+ }
+
+ $response = $list_result[0];
+
+ if (is_string($response)) {
+ $response = View::create($response);
+ }
+
+ throw new HttpResponseException($response);
+}
+
+/**
+ * 以扩展的架构定位app下的文件位置.
+ *
+ * @param string $file_path 文件路径,不要以/开头,不需要以app开头,会自动定位app或extend/base。
+ * @return string
+ */
+function app_file_path($file_path)
+{
+ $app_file_path = App::getRootPath() . 'app' . DIRECTORY_SEPARATOR . $file_path;
+ if (!is_file($app_file_path)) {
+ $app_file_path = App::getRootPath() . 'extend' . DIRECTORY_SEPARATOR . 'base' . DIRECTORY_SEPARATOR . $file_path;
+ }
+
+ return $app_file_path;
+}
diff --git a/extend/base/tools/controller/timer/ClearLogBase.php b/extend/base/tools/controller/timer/ClearLogBase.php
new file mode 100644
index 0000000..50846b6
--- /dev/null
+++ b/extend/base/tools/controller/timer/ClearLogBase.php
@@ -0,0 +1,22 @@
+where('create_time', '<', time() - 60 * 60 * 24 * 3)->delete();
+
+ return 'success';
+ }
+}
diff --git a/extend/base/tools/controller/timer/ResetPasswordBase.php b/extend/base/tools/controller/timer/ResetPasswordBase.php
new file mode 100644
index 0000000..e47f6ce
--- /dev/null
+++ b/extend/base/tools/controller/timer/ResetPasswordBase.php
@@ -0,0 +1,26 @@
+error('本功能只有在演示环境下在能使用', '', '/');
+ }
+
+ $output = Console::call('admin:resetPassword', [
+ '--password=123456',
+ ]);
+
+ return $output->fetch();
+ }
+}
diff --git a/extend/think/UlthonAdminApp.php b/extend/think/UlthonAdminApp.php
new file mode 100644
index 0000000..14afe5d
--- /dev/null
+++ b/extend/think/UlthonAdminApp.php
@@ -0,0 +1,18 @@
+ [],
+ 'HttpRun' => [],
+ 'HttpEnd' => [],
+ 'LogLevel' => [],
+ 'LogWrite' => [],
+ 'AdminLoginSuccess' => [
+ LogEvent::class,
+ ],
+ 'AdminLoginType' => [
+ DemoEvent::class,
+ ],
+ ];
+
+ $this->app->event->listenEvents($event_listen);
+
+ // 注册验证码服务
+ $this->app->register(CaptchaService::class);
+
+ // 注册多应用服务
+ $this->app->register(AppService::class);
+
+ // 注册数据库迁移服务
+ $this->app->register(Service::class);
+
+ // 绑定标识容器
+
+ $provider_default = [
+ 'think\Request' => Request::class,
+ 'think\exception\Handle' => ExceptionHandle::class,
+ 'think\View' => View::class,
+ ];
+
+ $provider_setting = include App::getRootPath() . '/app/provider.php';
+
+ if (isset($provider_setting['think\App'])) {
+ unset($provider_setting['think\App']);
+ }
+
+ $provider = array_merge($provider_default, $provider_setting);
+
+ $this->app->bind($provider);
+
+ // 导入系统中间件
+
+ $middleware = [
+ // 全局请求缓存
+ // \think\middleware\CheckRequestCache::class,
+ // 多语言加载
+ // \think\middleware\LoadLangPack::class,
+ // Session初始化
+ 100 => \think\middleware\SessionInit::class,
+ ];
+
+ $this->app->middleware->import($middleware);
+ }
+}