调整统一provider目录;增加content事件的快速登录案例;

This commit is contained in:
2023-09-15 14:33:34 +08:00
parent a2c14391b1
commit 4d9434454e
15 changed files with 167 additions and 65 deletions

View File

@@ -47,4 +47,7 @@ STATIC_PATH=/static
OSS_STATIC_PREFIX=static_ulthon_admin OSS_STATIC_PREFIX=static_ulthon_admin
# 没有节点控制的是否放行 # 没有节点控制的是否放行
DEFAULT_AUTH_CHECK=false DEFAULT_AUTH_CHECK=false
# 严格要求部分事件的返回数据,不符则抛出异常
STRICT_EVENT=true

View File

@@ -33,6 +33,7 @@ class Login extends AdminController
*/ */
public function index() public function index()
{ {
$captcha = Env::get('adminsystem.captcha', 1); $captcha = Env::get('adminsystem.captcha', 1);
if ($this->request->isPost()) { if ($this->request->isPost()) {
$post = $this->request->post(); $post = $this->request->post();

View File

@@ -1,14 +1,8 @@
<?php <?php
namespace app\admin\middleware; namespace app\admin\middleware;
use think\Request;
use app\Request;
use CsrfVerify\drive\ThinkphpCache;
use CsrfVerify\entity\CsrfVerifyEntity;
use CsrfVerify\interfaces\CsrfVerifyInterface;
use think\facade\Session;
class CsrfMiddleware class CsrfMiddleware
{ {
@@ -18,7 +12,6 @@ class CsrfMiddleware
{ {
if (env('adminsystem.IS_CSRF', true)) { if (env('adminsystem.IS_CSRF', true)) {
if (!in_array($request->method(), ['GET', 'HEAD', 'OPTIONS'])) { if (!in_array($request->method(), ['GET', 'HEAD', 'OPTIONS'])) {
// 跨域校验 // 跨域校验
$refererUrl = $request->header('REFERER', null); $refererUrl = $request->header('REFERER', null);
$refererInfo = parse_url($refererUrl); $refererInfo = parse_url($refererUrl);
@@ -36,9 +29,9 @@ class CsrfMiddleware
if (!$check) { if (!$check) {
$this->error('请求验证失败,请重新刷新页面!'); $this->error('请求验证失败,请重新刷新页面!');
} }
} }
} }
return $next($request); return $next($request);
} }
} }

View File

@@ -2,9 +2,9 @@
namespace app\admin\middleware; namespace app\admin\middleware;
use app\Request;
use think\facade\Log; use think\facade\Log;
use think\facade\Request as FacadeRequest; use think\facade\Request as FacadeRequest;
use think\Request;
/** /**
* 系统操作日志中间件 * 系统操作日志中间件

View File

@@ -0,0 +1,7 @@
<div class="layui-btn layui-btn-xs" id="demo-login-btn">演示账号快速登录</div>
<script>
$('#demo-login-btn').click(function() {
$('[name="username"]').val('admin')
$('[name="password"]').val('123456')
})
</script>

View File

@@ -12,19 +12,19 @@
<div class="item"> <div class="item">
<span class="icon icon-2"></span> <span class="icon icon-2"></span>
<input type="text" name="username" lay-verify="required" placeholder="请输入登录账号" maxlength="24"/> <input type="text" name="username" lay-verify="required" placeholder="请输入登录账号" maxlength="24" />
</div> </div>
<div class="item"> <div class="item">
<span class="icon icon-3"></span> <span class="icon icon-3"></span>
<input type="password" name="password" lay-verify="required" placeholder="请输入密码" maxlength="20"> <input type="password" name="password" lay-verify="required" placeholder="请输入密码" maxlength="20">
<span class="bind-password icon icon-4"></span> <span class="bind-password icon icon-4"></span>
</div> </div>
{if $captcha == 1} {if $captcha == 1}
<div id="validatePanel" class="item" style="width: 137px;"> <div id="validatePanel" class="item" style="width: 137px;">
<input type="text" name="captcha" placeholder="请输入验证码" maxlength="4"> <input type="text" name="captcha" placeholder="请输入验证码" maxlength="4">
<img id="refreshCaptcha" class="validateImg" src="{:url('login/captcha')}" onclick="this.src='{:url(\'login/captcha\')}?seed='+Math.random()"> <img id="refreshCaptcha" class="validateImg" src="{:url('login/captcha')}" onclick="this.src='{:url(\'login/captcha\')}?seed='+Math.random()">
</div> </div>
{/if} {/if}
@@ -37,6 +37,11 @@
<div class="layui-form-item" style="text-align:center; width:100%;height:100%;margin:0px;"> <div class="layui-form-item" style="text-align:center; width:100%;height:100%;margin:0px;">
<button class="login-btn" lay-submit>立即登录</button> <button class="login-btn" lay-submit>立即登录</button>
</div> </div>
<div class="layui-form-item" style="padding: 10px;">
<div class="layui-btn-container">
{:event_view_content("AdminLoginType")}
</div>
</div>
</form> </form>
</div> </div>
</div> </div>

View File

@@ -1,14 +1,16 @@
<?php <?php
// 应用公共文件 // 应用公共文件
use app\commno\exception\EventException;
use app\common\service\AuthService; use app\common\service\AuthService;
use think\facade\Cache; use think\facade\Cache;
use think\facade\Env;
use think\facade\Event;
use think\facade\Filesystem; use think\facade\Filesystem;
use think\facade\Request;
use think\route\Url; use think\route\Url;
if (!function_exists('__url')) { if (!function_exists('__url')) {
/** /**
* 构建URL地址 * 构建URL地址
* @param string $url * @param string $url
@@ -46,9 +48,8 @@ if (!function_exists('__url')) {
} }
if (!function_exists('password')) { if (!function_exists('password')) {
/** /**
* 密码加密算法 * 密码加密算法.
* @param $value 需要加密的值 * @param $value 需要加密的值
* @param $type 加密类型默认为md5 md5, hash * @param $type 加密类型默认为md5 md5, hash
* @return mixed * @return mixed
@@ -56,14 +57,14 @@ if (!function_exists('password')) {
function password($value, $salt = '_encrypt') function password($value, $salt = '_encrypt')
{ {
$value = sha1('ul_' . $salt) . md5($value) . md5($salt) . sha1($value); $value = sha1('ul_' . $salt) . md5($value) . md5($salt) . sha1($value);
return sha1($value); return sha1($value);
} }
} }
if (!function_exists('xdebug')) { if (!function_exists('xdebug')) {
/** /**
* debug调试 * debug调试.
* @deprecated 不建议使用建议直接使用框架自带的log组件 * @deprecated 不建议使用建议直接使用框架自带的log组件
* @param string|array $data 打印信息 * @param string|array $data 打印信息
* @param string $type 类型 * @param string $type 类型
@@ -77,7 +78,7 @@ if (!function_exists('xdebug')) {
if (is_null($file)) { if (is_null($file)) {
$file = is_null($suffix) ? runtime_path() . 'xdebug/' . date('Ymd') . '.txt' : runtime_path() . 'xdebug/' . date('Ymd') . "_{$suffix}" . '.txt'; $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); file_put_contents($file, '[' . date('Y-m-d H:i:s') . '] ' . "========================= {$type} ===========================" . PHP_EOL, FILE_APPEND);
$str = ''; $str = '';
@@ -98,16 +99,14 @@ if (!function_exists('xdebug')) {
} }
if (!function_exists('sysconfig')) { if (!function_exists('sysconfig')) {
/** /**
* 获取系统配置信息 * 获取系统配置信息.
* @param $group * @param $group
* @param null|bool|string $name * @param null|bool|string $name
* @return array|mixed * @return array|mixed
*/ */
function sysconfig($group, $name = null, $default = null) function sysconfig($group, $name = null, $default = null)
{ {
if ($name === true) { if ($name === true) {
$value = Cache::get('sysconfig_' . $group); $value = Cache::get('sysconfig_' . $group);
@@ -118,6 +117,7 @@ if (!function_exists('sysconfig')) {
if (is_null($value)) { if (is_null($value)) {
return $default; return $default;
} }
return $value; return $value;
} }
@@ -136,14 +136,14 @@ if (!function_exists('sysconfig')) {
if (is_null($value)) { if (is_null($value)) {
return $default; return $default;
} }
return $value; return $value;
} }
} }
if (!function_exists('array_format_key')) { if (!function_exists('array_format_key')) {
/** /**
* 二位数组重新组合数据 * 二位数组重新组合数据.
* @param $array * @param $array
* @param $key * @param $key
* @return array * @return array
@@ -154,12 +154,12 @@ if (!function_exists('array_format_key')) {
foreach ($array as $vo) { foreach ($array as $vo) {
$newArray[$vo[$key]] = $vo; $newArray[$vo[$key]] = $vo;
} }
return $newArray; return $newArray;
} }
} }
if (!function_exists('auth')) { if (!function_exists('auth')) {
/** /**
* auth权限验证 * auth权限验证
* @param $node * @param $node
@@ -172,52 +172,49 @@ if (!function_exists('auth')) {
{ {
$authService = new AuthService(session('admin.id')); $authService = new AuthService(session('admin.id'));
$check = $authService->checkNode($node); $check = $authService->checkNode($node);
return $check; return $check;
} }
} }
function json_message($data = [], $code = 0, $msg = '') function json_message($data = [], $code = 0, $msg = '')
{ {
if (is_string($data)) { if (is_string($data)) {
if (strpos($data, 'http') === 0 || strpos($data, '/') === 0) { if (strpos($data, 'http') === 0 || strpos($data, '/') === 0) {
$data = [ $data = [
'jump_to_url' => $data 'jump_to_url' => $data,
]; ];
} else { } else {
$code = $code === 0 ? 500 : $code; $code = $code === 0 ? 500 : $code;
$msg = $data; $msg = $data;
$data = []; $data = [];
} }
} else if ($data instanceof Url) { } elseif ($data instanceof Url) {
$data = [ $data = [
'jump_to_url' => (string)$data 'jump_to_url' => (string) $data,
]; ];
} }
return json([ return json([
'code' => $code, 'code' => $code,
'msg' => $msg, 'msg' => $msg,
'data' => $data 'data' => $data,
]); ]);
} }
if (!function_exists('unparse_url')) { if (!function_exists('unparse_url')) {
function unparse_url($parsed_url) function unparse_url($parsed_url)
{ {
$scheme = isset($parsed_url['scheme']) ? $parsed_url['scheme'] . '://' : ''; $scheme = isset($parsed_url['scheme']) ? $parsed_url['scheme'] . '://' : '';
$host = isset($parsed_url['host']) ? $parsed_url['host'] : ''; $host = isset($parsed_url['host']) ? $parsed_url['host'] : '';
$port = isset($parsed_url['port']) ? ':' . $parsed_url['port'] : ''; $port = isset($parsed_url['port']) ? ':' . $parsed_url['port'] : '';
$user = isset($parsed_url['user']) ? $parsed_url['user'] : ''; $user = isset($parsed_url['user']) ? $parsed_url['user'] : '';
$pass = isset($parsed_url['pass']) ? ':' . $parsed_url['pass'] : ''; $pass = isset($parsed_url['pass']) ? ':' . $parsed_url['pass'] : '';
$pass = ($user || $pass) ? "$pass@" : ''; $pass = ($user || $pass) ? "$pass@" : '';
$path = isset($parsed_url['path']) ? $parsed_url['path'] : ''; $path = isset($parsed_url['path']) ? $parsed_url['path'] : '';
$query = isset($parsed_url['query']) ? '?' . $parsed_url['query'] : ''; $query = isset($parsed_url['query']) ? '?' . $parsed_url['query'] : '';
$fragment = isset($parsed_url['fragment']) ? '#' . $parsed_url['fragment'] : ''; $fragment = isset($parsed_url['fragment']) ? '#' . $parsed_url['fragment'] : '';
return "$scheme$user$pass$host$port$path$query$fragment"; return "$scheme$user$pass$host$port$path$query$fragment";
} }
} }
@@ -225,7 +222,6 @@ if (!function_exists('unparse_url')) {
if (!function_exists('ua_htmlspecialchars')) { if (!function_exists('ua_htmlspecialchars')) {
function ua_htmlspecialchars($string) function ua_htmlspecialchars($string)
{ {
if (is_null($string)) { if (is_null($string)) {
$string = ''; $string = '';
} }
@@ -237,7 +233,6 @@ if (!function_exists('ua_htmlspecialchars')) {
if (!function_exists('ua_htmlentities')) { if (!function_exists('ua_htmlentities')) {
function ua_htmlentities($string) function ua_htmlentities($string)
{ {
if (is_null($string)) { if (is_null($string)) {
$string = ''; $string = '';
} }
@@ -249,7 +244,6 @@ if (!function_exists('ua_htmlentities')) {
if (!function_exists('ua_htmlspecialchars_decode')) { if (!function_exists('ua_htmlspecialchars_decode')) {
function ua_htmlspecialchars_decode($string, $flag = ENT_QUOTES | ENT_SUBSTITUTE) function ua_htmlspecialchars_decode($string, $flag = ENT_QUOTES | ENT_SUBSTITUTE)
{ {
if (is_null($string)) { if (is_null($string)) {
$string = ''; $string = '';
} }
@@ -258,13 +252,30 @@ if (!function_exists('ua_htmlspecialchars_decode')) {
} }
} }
function build_upload_url($url, $upload_type = null) function build_upload_url($url, $upload_type = null)
{ {
if (is_null($upload_type)) { if (is_null($upload_type)) {
$upload_type = sysconfig('upload', 'upload_type', 'local_public'); $upload_type = sysconfig('upload', 'upload_type', 'local_public');
} }
return Filesystem::disk($upload_type)->url($url); return Filesystem::disk($upload_type)->url($url);
} }
function event_view_content($name)
{
$list_result = Event::trigger($name);
$content = '';
foreach ($list_result as $key_event => $value_event) {
if (!isset($value_event['view_content'])) {
if (Env::get('adminsystem.strict_event')) {
throw new EventException("Event view {$name} trigger a result without a view_content");
}
continue;
}
$content.= $value_event['view_content'];
}
return $content;
}

View File

@@ -0,0 +1,23 @@
<?php
namespace app\common\event\AdminLoginType;
use think\facade\Env;
use think\facade\View;
class DemoEvent
{
public function handle()
{
$content = '';
if (Env::get('adminsystem.is_demo', false)) {
$content = View::layout(false)->fetch('login/ext/demo');
}
// 事件监听处理
return [
'view_content' => $content,
];
}
}

View File

@@ -0,0 +1,9 @@
<?php
namespace app\commno\exception;
use Exception;
class EventException extends Exception
{
}

View File

@@ -1,5 +1,5 @@
<?php <?php
namespace app; namespace app\common\provider;
use think\db\exception\DataNotFoundException; use think\db\exception\DataNotFoundException;
use think\db\exception\ModelNotFoundException; use think\db\exception\ModelNotFoundException;

View File

@@ -1,10 +1,9 @@
<?php <?php
namespace app;
namespace app\common\provider;
// 应用请求对象类 // 应用请求对象类
class Request extends \think\Request class Request extends \think\Request
{ {
protected $filter = ['ua_htmlspecialchars']; protected $filter = ['ua_htmlspecialchars'];
} }

View File

@@ -0,0 +1,39 @@
<?php
namespace app\common\provider;
use think\View as ThinkView;
class View extends ThinkView
{
/**
* 设置布局
* ! 注意layout并非view类的标准方法仅仅是think-view和think-template的特性方法
* ! 但是如果在provider中定制则view的所有操作预期会发生错误
* ! 同时由于后台从设计支出就完全依赖think-view所以专门为此扩展和特性定义方法时没有问题的.
* @param bool|string $name 布局模板名称 false 则关闭布局
* @param string $replace 布局模板内容替换标识
* @return $this
*/
public function layout(bool|string $name, string $replace = ''): static
{
if (false === $name) {
// 关闭布局
$this->config(['layout_on' => false]);
} else {
// 开启布局
$this->config(['layout_on' => true]);
// 名称必须为字符串
if (is_string($name)) {
$this->config(['layout_name' => $name]);
}
if (!empty($replace)) {
$this->config(['layout_item' => $replace]);
}
}
return $this;
}
}

View File

@@ -3,6 +3,7 @@
// 事件定义文件 // 事件定义文件
use app\common\event\AdminLoginSuccess\LogEvent; use app\common\event\AdminLoginSuccess\LogEvent;
use app\common\event\AdminLoginType\DemoEvent;
$event = [ $event = [
'bind' => [ 'bind' => [
@@ -17,6 +18,9 @@ $event = [
'AdminLoginSuccess' => [ 'AdminLoginSuccess' => [
LogEvent::class, LogEvent::class,
], ],
'AdminLoginType' => [
DemoEvent::class,
],
], ],
'subscribe' => [ 'subscribe' => [

View File

@@ -1,9 +1,13 @@
<?php <?php
use app\ExceptionHandle;
use app\Request;
// 容器Provider定义文件 // 容器Provider定义文件
use app\common\provider\ExceptionHandle;
use app\common\provider\Request;
use app\common\provider\View;
return [ return [
'think\Request' => Request::class, 'think\Request' => Request::class,
'think\exception\Handle' => ExceptionHandle::class, 'think\exception\Handle' => ExceptionHandle::class,
'think\View' => View::class,
]; ];

View File

@@ -1,8 +1,7 @@
.demo { .demo {
padding-top: 20px; padding-top: 20px;
text-align: center; text-align: center;
color: #9abcda!important; color: #9abcda !important;
font-size: 14px; font-size: 14px;
} }
@@ -150,7 +149,7 @@
width: 428px; width: 428px;
background: #fff; background: #fff;
border-radius: 0 0 12px 12px; border-radius: 0 0 12px 12px;
padding-bottom: 53px;
} }
.login-main .login-bottom .center { .login-main .login-bottom .center {
@@ -180,19 +179,23 @@ input::-webkit-input-placeholder {
color: #a6aebf; color: #a6aebf;
} }
input::-moz-placeholder { /* Mozilla Firefox 19+ */ input::-moz-placeholder {
/* Mozilla Firefox 19+ */
color: #a6aebf; color: #a6aebf;
} }
input:-moz-placeholder { /* Mozilla Firefox 4 to 18 */ input:-moz-placeholder {
/* Mozilla Firefox 4 to 18 */
color: #a6aebf; color: #a6aebf;
} }
input:-ms-input-placeholder { /* Internet Explorer 10-11 */ input:-ms-input-placeholder {
/* Internet Explorer 10-11 */
color: #a6aebf; color: #a6aebf;
} }
input:-webkit-autofill { /* 取消Chrome记住密码的背景颜色 */ input:-webkit-autofill {
/* 取消Chrome记住密码的背景颜色 */
-webkit-box-shadow: 0 0 0 1000px white inset !important; -webkit-box-shadow: 0 0 0 1000px white inset !important;
} }
@@ -268,7 +271,8 @@ html {
padding: 5px !important; padding: 5px !important;
} }
.footer a, .footer span { .footer a,
.footer span {
color: #fff; color: #fff;
} }