调整统一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

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

View File

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

View File

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

View File

@@ -2,9 +2,9 @@
namespace app\admin\middleware;
use app\Request;
use think\facade\Log;
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">
<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 class="item">
<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>
</div>
{if $captcha == 1}
<div id="validatePanel" class="item" style="width: 137px;">
<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>
{/if}
@@ -37,6 +37,11 @@
<div class="layui-form-item" style="text-align:center; width:100%;height:100%;margin:0px;">
<button class="login-btn" lay-submit>立即登录</button>
</div>
<div class="layui-form-item" style="padding: 10px;">
<div class="layui-btn-container">
{:event_view_content("AdminLoginType")}
</div>
</div>
</form>
</div>
</div>

View File

@@ -1,14 +1,16 @@
<?php
// 应用公共文件
use app\commno\exception\EventException;
use app\common\service\AuthService;
use think\facade\Cache;
use think\facade\Env;
use think\facade\Event;
use think\facade\Filesystem;
use think\facade\Request;
use think\route\Url;
if (!function_exists('__url')) {
/**
* 构建URL地址
* @param string $url
@@ -46,9 +48,8 @@ if (!function_exists('__url')) {
}
if (!function_exists('password')) {
/**
* 密码加密算法
* 密码加密算法.
* @param $value 需要加密的值
* @param $type 加密类型默认为md5 md5, hash
* @return mixed
@@ -56,14 +57,14 @@ if (!function_exists('password')) {
function password($value, $salt = '_encrypt')
{
$value = sha1('ul_' . $salt) . md5($value) . md5($salt) . sha1($value);
return sha1($value);
}
}
if (!function_exists('xdebug')) {
/**
* debug调试
* debug调试.
* @deprecated 不建议使用建议直接使用框架自带的log组件
* @param string|array $data 打印信息
* @param string $type 类型
@@ -77,7 +78,7 @@ if (!function_exists('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);
file_put_contents($file, '[' . date('Y-m-d H:i:s') . '] ' . "========================= {$type} ===========================" . PHP_EOL, FILE_APPEND);
$str = '';
@@ -98,16 +99,14 @@ if (!function_exists('xdebug')) {
}
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);
@@ -118,6 +117,7 @@ if (!function_exists('sysconfig')) {
if (is_null($value)) {
return $default;
}
return $value;
}
@@ -136,14 +136,14 @@ if (!function_exists('sysconfig')) {
if (is_null($value)) {
return $default;
}
return $value;
}
}
if (!function_exists('array_format_key')) {
/**
* 二位数组重新组合数据
* 二位数组重新组合数据.
* @param $array
* @param $key
* @return array
@@ -154,12 +154,12 @@ if (!function_exists('array_format_key')) {
foreach ($array as $vo) {
$newArray[$vo[$key]] = $vo;
}
return $newArray;
}
}
if (!function_exists('auth')) {
/**
* auth权限验证
* @param $node
@@ -172,52 +172,49 @@ if (!function_exists('auth')) {
{
$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
'jump_to_url' => $data,
];
} else {
$code = $code === 0 ? 500 : $code;
$msg = $data;
$data = [];
}
} else if ($data instanceof Url) {
} elseif ($data instanceof Url) {
$data = [
'jump_to_url' => (string)$data
'jump_to_url' => (string) $data,
];
}
return json([
'code' => $code,
'msg' => $msg,
'data' => $data
'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'] : '';
$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";
}
}
@@ -225,7 +222,6 @@ if (!function_exists('unparse_url')) {
if (!function_exists('ua_htmlspecialchars')) {
function ua_htmlspecialchars($string)
{
if (is_null($string)) {
$string = '';
}
@@ -237,7 +233,6 @@ if (!function_exists('ua_htmlspecialchars')) {
if (!function_exists('ua_htmlentities')) {
function ua_htmlentities($string)
{
if (is_null($string)) {
$string = '';
}
@@ -249,7 +244,6 @@ if (!function_exists('ua_htmlentities')) {
if (!function_exists('ua_htmlspecialchars_decode')) {
function ua_htmlspecialchars_decode($string, $flag = ENT_QUOTES | ENT_SUBSTITUTE)
{
if (is_null($string)) {
$string = '';
}
@@ -258,13 +252,30 @@ if (!function_exists('ua_htmlspecialchars_decode')) {
}
}
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_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
namespace app;
namespace app\common\provider;
use think\db\exception\DataNotFoundException;
use think\db\exception\ModelNotFoundException;

View File

@@ -1,10 +1,9 @@
<?php
namespace app;
namespace app\common\provider;
// 应用请求对象类
class Request extends \think\Request
{
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\AdminLoginType\DemoEvent;
$event = [
'bind' => [
@@ -17,6 +18,9 @@ $event = [
'AdminLoginSuccess' => [
LogEvent::class,
],
'AdminLoginType' => [
DemoEvent::class,
],
],
'subscribe' => [

View File

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

View File

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