Compare commits
24 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3e329a4ea3 | ||
|
|
f015a90b89 | ||
|
|
75c668b966 | ||
|
|
f3e5a041d1 | ||
|
|
3b219cfe7f | ||
|
|
ed99fe79fd | ||
|
|
846b8ffafc | ||
|
|
47ef5d9f10 | ||
|
|
70ec12f406 | ||
|
|
e15b56ecc9 | ||
|
|
af275e1c6a | ||
|
|
20d4038159 | ||
|
|
475a1ef84d | ||
|
|
9307e724a9 | ||
|
|
6616e96724 | ||
|
|
963febc15c | ||
|
|
f78edd2fd5 | ||
|
|
83aa399f95 | ||
|
|
3096aa8985 | ||
|
|
c7f7ca9af7 | ||
|
|
352484c69e | ||
|
|
dfe15f7e88 | ||
|
|
4d7365921e | ||
|
|
d613f3c26f |
@@ -39,7 +39,13 @@
|
||||
|
||||
> EasyAdmin8 使用 Composer 来管理项目依赖。因此,在使用 EasyAdmin8 之前,请确保你的机器已经安装了 Composer。
|
||||
|
||||
### 通过git下载安装包,composer安装依赖包
|
||||
### 通过一键安装命令
|
||||
|
||||
```
|
||||
if [ -f /usr/bin/curl ];then curl -sSO https://easyadmin8.top/auto-install-EasyAdmin8.sh;else wget -O auto-install-EasyAdmin8.sh https://easyadmin8.top/auto-install-EasyAdmin8.sh;fi;bash auto-install-EasyAdmin8.sh
|
||||
```
|
||||
|
||||
### 通过`git`下载安装包,`composer`安装依赖包
|
||||
|
||||
```
|
||||
1.下载安装包
|
||||
|
||||
@@ -36,11 +36,9 @@ class Index extends AdminController
|
||||
$mysqlVersion = Db::query("select version() as version")[0]['version'] ?? '未知';
|
||||
$phpVersion = phpversion();
|
||||
$versions = compact('tpVersion', 'mysqlVersion', 'phpVersion');
|
||||
$quicks = SystemQuick::field('id,title,icon,href')
|
||||
->where(['status' => 1])
|
||||
->order('sort', 'desc')
|
||||
->limit(8)
|
||||
->select();
|
||||
$quick_list = SystemQuick::field('id,title,icon,href')
|
||||
->where(['status' => 1])->order('sort', 'desc')->limit(50)->select()->toArray();
|
||||
$quicks = array_chunk($quick_list, 8);
|
||||
$this->assign(compact('quicks', 'versions'));
|
||||
return $this->fetch();
|
||||
}
|
||||
@@ -55,7 +53,7 @@ class Index extends AdminController
|
||||
*/
|
||||
public function editAdmin(Request $request): string
|
||||
{
|
||||
$id = $this->adminUid;
|
||||
$id = $this->adminUid;
|
||||
$row = (new SystemAdmin())
|
||||
->withoutField('password')
|
||||
->find($id);
|
||||
@@ -66,15 +64,20 @@ class Index extends AdminController
|
||||
$rule = [];
|
||||
$this->validate($post, $rule);
|
||||
try {
|
||||
$save = $row
|
||||
->allowField(['head_img', 'phone', 'remark', 'update_time'])
|
||||
->save($post);
|
||||
}catch (Exception $e) {
|
||||
$login_type = $post['login_type'] ?? 1;
|
||||
if ($login_type == 2) {
|
||||
$ga_secret = (new SystemAdmin())->where('id', $id)->value('ga_secret');
|
||||
if (empty($ga_secret)) $this->error('请先绑定谷歌验证器');
|
||||
}
|
||||
$save = $row->allowField(['head_img', 'phone', 'remark', 'update_time', 'login_type'])->save($post);
|
||||
}catch (\PDOException $e) {
|
||||
$this->error('保存失败');
|
||||
}
|
||||
$save ? $this->success('保存成功') : $this->error('保存失败');
|
||||
}
|
||||
$this->assign('row', $row);
|
||||
$notes = (new SystemAdmin())->notes;
|
||||
$this->assign('notes', $notes);
|
||||
return $this->fetch();
|
||||
}
|
||||
|
||||
@@ -82,13 +85,10 @@ class Index extends AdminController
|
||||
* 修改密码
|
||||
* @param Request $request
|
||||
* @return string
|
||||
* @throws DataNotFoundException
|
||||
* @throws DbException
|
||||
* @throws ModelNotFoundException
|
||||
*/
|
||||
public function editPassword(Request $request): string
|
||||
{
|
||||
$id = $this->adminUid;
|
||||
$id = $this->adminUid;
|
||||
$row = (new SystemAdmin())
|
||||
->withoutField('password')
|
||||
->find($id);
|
||||
@@ -124,4 +124,37 @@ class Index extends AdminController
|
||||
return $this->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置谷歌验证码
|
||||
* @param Request $request
|
||||
* @return string
|
||||
* @throws Exception
|
||||
*/
|
||||
public function set2fa(Request $request): string
|
||||
{
|
||||
$id = $this->adminUid;
|
||||
$row = (new SystemAdmin())->withoutField('password')->find($id);
|
||||
if (!$row) $this->error('用户信息不存在');
|
||||
// You can see: https://gitee.com/wolf-code/authenticator
|
||||
$ga = new \Wolfcode\Authenticator\google\PHPGangstaGoogleAuthenticator();
|
||||
if (!$request->isAjax()) {
|
||||
$old_secret = $row->ga_secret;
|
||||
$secret = $ga->createSecret(32);
|
||||
$ga_title = $this->isDemo ? 'EasyAdmin8演示环境' : '可自定义修改显示标题';
|
||||
$dataUri = $ga->getQRCode($ga_title, $secret)->getDataUri();
|
||||
$this->assign(compact('row', 'dataUri', 'old_secret', 'secret'));
|
||||
return $this->fetch();
|
||||
}
|
||||
$this->isDemo && $this->error('演示环境下不允许修改');
|
||||
$post = $request->post();
|
||||
$ga_secret = $post['ga_secret'] ?? '';
|
||||
$ga_code = $post['ga_code'] ?? '';
|
||||
if (empty($ga_code)) $this->error('请输入验证码');
|
||||
if (!$ga->verifyCode($ga_secret, $ga_code)) $this->error('验证码错误');
|
||||
$row->ga_secret = $ga_secret;
|
||||
$row->login_type = 2;
|
||||
$row->save();
|
||||
$this->success('操作成功');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -56,6 +56,11 @@ class Login extends AdminController
|
||||
if ($admin->status == 0) {
|
||||
$this->error('账号已被禁用');
|
||||
}
|
||||
if ($admin->login_type == 2) {
|
||||
if (empty($post['ga_code'])) $this->error('请输入谷歌验证码', ['is_ga_code' => true]);
|
||||
$ga = new \Wolfcode\Authenticator\google\PHPGangstaGoogleAuthenticator();
|
||||
if (!$ga->verifyCode($admin->ga_secret, $post['ga_code'])) $this->error('谷歌验证码错误');;
|
||||
}
|
||||
$admin->login_num += 1;
|
||||
$admin->save();
|
||||
$admin = $admin->toArray();
|
||||
|
||||
@@ -22,6 +22,7 @@ use think\response\Json;
|
||||
*/
|
||||
class Log extends AdminController
|
||||
{
|
||||
protected array $ignoreLog = ['record'];
|
||||
|
||||
public function __construct(App $app)
|
||||
{
|
||||
@@ -98,7 +99,7 @@ class Log extends AdminController
|
||||
/**
|
||||
* @NodeAnnotation(title="框架日志")
|
||||
*/
|
||||
public function record(): string
|
||||
public function record(): Json|string
|
||||
{
|
||||
return (new \Wolfcode\PhpLogviewer\thinkphp\LogViewer())->fetch();
|
||||
}
|
||||
|
||||
@@ -7,9 +7,11 @@ use app\admin\service\annotation\NodeAnnotation;
|
||||
use app\admin\service\SystemLogService;
|
||||
use app\common\traits\JumpTrait;
|
||||
use app\Request;
|
||||
use ReflectionClass;
|
||||
use Closure;
|
||||
use Doctrine\Common\Annotations\AnnotationReader;
|
||||
use Doctrine\Common\Annotations\DocParser;
|
||||
use ReflectionException;
|
||||
|
||||
class SystemLog
|
||||
{
|
||||
@@ -26,9 +28,13 @@ class SystemLog
|
||||
'mobile',
|
||||
];
|
||||
|
||||
/**
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
public function handle(Request $request, Closure $next)
|
||||
{
|
||||
$params = $request->param();
|
||||
$response = $next($request);
|
||||
$params = $request->param();
|
||||
if (isset($params['s'])) unset($params['s']);
|
||||
foreach ($params as $key => $val) {
|
||||
in_array($key, $this->sensitiveParams) && $params[$key] = "***********";
|
||||
@@ -39,9 +45,9 @@ class SystemLog
|
||||
if (env('APP_DEBUG')) {
|
||||
trace(['url' => $url, 'method' => $method, 'params' => $params,], 'requestDebugInfo');
|
||||
}
|
||||
$response = $next($request);
|
||||
if ($request->isAjax()) {
|
||||
if (in_array($method, ['post', 'put', 'delete'])) {
|
||||
|
||||
$title = '';
|
||||
try {
|
||||
$pathInfo = $request->pathinfo();
|
||||
@@ -53,7 +59,10 @@ class SystemLog
|
||||
if ($_name && $_controller && $_action) {
|
||||
$className = "app\admin\controller\\{$_name}\\{$_controller}";
|
||||
$reflectionClass = new \ReflectionClass($className);
|
||||
$parser = new DocParser();
|
||||
$properties = $reflectionClass->getDefaultProperties();
|
||||
$ignoreLog = $properties['ignoreLog'] ?? [];
|
||||
if (in_array($_action, $ignoreLog)) return $response;
|
||||
$parser = new DocParser();
|
||||
$parser->setIgnoreNotImportedAnnotations(true);
|
||||
$reader = new AnnotationReader($parser);
|
||||
$controllerAnnotation = $reader->getClassAnnotation($reflectionClass, ControllerAnnotation::class);
|
||||
|
||||
@@ -10,6 +10,13 @@ class SystemAdmin extends TimeModel
|
||||
|
||||
protected $deleteTime = 'delete_time';
|
||||
|
||||
public array $notes = [
|
||||
'login_type' => [
|
||||
1 => '密码登录',
|
||||
2 => '密码 + 谷歌验证码登录'
|
||||
],
|
||||
];
|
||||
|
||||
public function getAuthList()
|
||||
{
|
||||
$list = (new SystemAuth())
|
||||
|
||||
@@ -44,14 +44,13 @@ class SystemLogService
|
||||
$this->tablePrefix = Config::get('database.connections.mysql.prefix');
|
||||
$this->tableSuffix = date('Ym', time());
|
||||
$this->tableName = "{$this->tablePrefix}system_log_{$this->tableSuffix}";
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取实例对象
|
||||
* @return SystemLogService|object
|
||||
* @return SystemLogService
|
||||
*/
|
||||
public static function instance()
|
||||
public static function instance(): SystemLogService
|
||||
{
|
||||
if (is_null(self::$instance)) {
|
||||
self::$instance = new static();
|
||||
@@ -85,15 +84,16 @@ class SystemLogService
|
||||
*/
|
||||
public function detectTable(): bool
|
||||
{
|
||||
$_key = "system_log_{$this->tableName}_table";
|
||||
// 手动删除日志表时候 记得清除缓存
|
||||
$isset = Cache::get("systemLog{$this->tableName}Table");
|
||||
$isset = Cache::get($_key);
|
||||
if ($isset) return true;
|
||||
$check = Db::query("show tables like '{$this->tableName}'");
|
||||
if (empty($check)) {
|
||||
$sql = $this->getCreateSql();
|
||||
Db::execute($sql);
|
||||
}
|
||||
Cache::set("system_log_{$this->tableName}_table", !empty($check));
|
||||
Cache::set($_key, !empty($check));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -30,6 +30,15 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">登录方式</label>
|
||||
<div class="layui-input-block">
|
||||
{foreach notes.login_type as $key=>$val}
|
||||
<input type="radio" name="login_type" lay-skin="primary" title="{$val}" value="{$key}" lay-filter="loginType-filter" {if $key==$row.login_type}checked=""{/if}>
|
||||
{/foreach}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item layui-form-text">
|
||||
<label class="layui-form-label">备注信息</label>
|
||||
<div class="layui-input-block">
|
||||
|
||||
45
app/admin/view/index/set2fa.html
Normal file
@@ -0,0 +1,45 @@
|
||||
<div class="layuimini-container">
|
||||
<form id="app-form" class="layui-form layuimini-form" autocomplete="off">
|
||||
{if $old_secret}
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-header">提示</div>
|
||||
<div class="layui-card-body">
|
||||
当前账号已经绑定过了 谷歌验证码 ,如果重新保存将替换
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label required">验证秘钥</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="ga_secret" class="layui-input" value="{$secret}" readonly disabled>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label required">二维码</label>
|
||||
<div class="layui-input-block">
|
||||
<img src="{$dataUri}" alt="二维码" style="width: 200px;height: 200px">
|
||||
<div class="layui-text layui-font-cyan layui-font-12">
|
||||
使用
|
||||
<a href="https://2fas.com" target="_blank"><span class="layui-text layui-font-blue">2FAS</span></a>
|
||||
或者
|
||||
<a href="https://cn.bing.com/search?q=Google+Authenticator" target="_blank"><span class="layui-text layui-font-blue">Google Authenticator</span></a>
|
||||
APP 扫描二维码 后 输入验证码 进行绑定
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label required">谷歌验证码</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="ga_code" class="layui-input" maxlength="6" lay-verify="required" placeholder="扫描二维码,输入验证码" value="">
|
||||
</div>
|
||||
</div>
|
||||
<div class=" hr-line">
|
||||
</div>
|
||||
<div class="layui-form-item text-center">
|
||||
<button type="submit" class="layui-btn layui-btn-normal layui-btn-sm" lay-submit>确认</button>
|
||||
<button type="reset" class="layui-btn layui-btn-primary layui-btn-sm">重置</button>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
</div>
|
||||
@@ -69,16 +69,27 @@
|
||||
<div class="layui-card-body">
|
||||
<div class="welcome-module">
|
||||
<div class="layui-row layui-col-space10">
|
||||
<div class="swiper mySwiper">
|
||||
<div class="swiper-wrapper">
|
||||
{foreach $quicks as $value}
|
||||
|
||||
{foreach $quicks as $vo}
|
||||
<div class="layui-col-xs3 layuimini-qiuck-module">
|
||||
<a layuimini-content-href="{:url($vo['href'])}" data-title="{$vo['title']}">
|
||||
<i class="{$vo['icon']|raw}"></i>
|
||||
<cite>{$vo['title']}</cite>
|
||||
</a>
|
||||
<div class="swiper-slide">
|
||||
{foreach $value as $vo}
|
||||
|
||||
<div class="layui-col-xs3 layuimini-qiuck-module">
|
||||
<a layuimini-content-href="{:url($vo['href'])}" data-title="{$vo['title']}">
|
||||
<i class="{$vo['icon']|raw}"></i>
|
||||
<cite>{$vo['title']}</cite>
|
||||
</a>
|
||||
</div>
|
||||
{/foreach}
|
||||
|
||||
</div>
|
||||
{/foreach}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
{/foreach}
|
||||
|
||||
<div class="swiper-pagination"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -21,10 +21,12 @@
|
||||
IS_SUPER_ADMIN: "{$isSuperAdmin|default='false'}",
|
||||
VERSION: "{$version|default='1.0.0'}",
|
||||
CSRF_TOKEN: "{:token()}",
|
||||
ADMIN_UPLOAD_URL: "{$adminUploadUrl|DEFAULT=''}",
|
||||
EDITOR_TYPE: "{$adminEditor|default='ueditor'}",
|
||||
ADMIN_UPLOAD_URL: "{$adminUploadUrl|default=''}",
|
||||
IFRAME_OPEN_TOP: "{$iframeOpenTop|default=0}",
|
||||
EDITOR_TYPE: "{$adminEditor|default='wangEditor'}",
|
||||
};
|
||||
</script>
|
||||
<script src="/static/plugs/xmSelect/xm-select.js" charset="utf-8"></script>
|
||||
<script src="/static/plugs/layui-v2.x/layui.js" charset="utf-8"></script>
|
||||
<script src="/static/plugs/require-2.3.6/require.js" charset="utf-8"></script>
|
||||
<script src="/static/config-admin.js?v={$version}" charset="utf-8"></script>
|
||||
|
||||
@@ -22,6 +22,11 @@
|
||||
<span class="bind-password icon icon-4"></span>
|
||||
</div>
|
||||
|
||||
<div class="item layui-hide" id="gaCode">
|
||||
<span class="icon icon-3"></span>
|
||||
<input type="text" name="ga_code" placeholder="谷歌验证码" maxlength="6">
|
||||
</div>
|
||||
|
||||
{if $captcha == 1}
|
||||
<div id="validatePanel" class="item" style="width: 137px;">
|
||||
<input type="text" name="captcha" placeholder="请输入验证码" maxlength="4">
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<form id="app-form" class="layui-form layuimini-form layui-form-pane">
|
||||
|
||||
<div class="layui-row">
|
||||
<div class="layui-col-xl5 layui-col-lg5 layui-col-md5 layui-col-sm5 layui-col-xs5">
|
||||
<div class="layui-col-xl5 layui-col-lg5 layui-col-md12 layui-col-sm12 layui-col-xs12">
|
||||
<!-- 可以使用该方式 推荐写法-->
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">商品分类</label>
|
||||
@@ -89,7 +89,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-col-xl7 layui-col-lg7 layui-col-md7 layui-col-sm7 layui-col-xs7">
|
||||
<div class="layui-col-xl7 layui-col-lg7 layui-col-md12 layui-col-sm12 layui-col-xs12">
|
||||
<div class="layui-form-item layui-form-text">
|
||||
<label class="layui-form-label">商品描述</label>
|
||||
<div class="layui-input-block">
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<form id="app-form" class="layui-form layuimini-form layui-form-pane">
|
||||
|
||||
<div class="layui-row">
|
||||
<div class="layui-col-xl5 layui-col-lg5 layui-col-md5 layui-col-sm5 layui-col-xs5">
|
||||
<div class="layui-col-xl5 layui-col-lg5 layui-col-md12 layui-col-sm12 layui-col-xs12">
|
||||
<!-- 可以使用该方式 推荐写法-->
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">商品分类</label>
|
||||
@@ -89,7 +89,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-col-xl7 layui-col-lg7 layui-col-md7 layui-col-sm7 layui-col-xs7">
|
||||
<div class="layui-col-xl7 layui-col-lg7 layui-col-md12 layui-col-sm12 layui-col-xs12">
|
||||
<div class="layui-form-item layui-form-text">
|
||||
<label class="layui-form-label">商品描述</label>
|
||||
<div class="layui-input-block">
|
||||
|
||||
@@ -1,4 +1,11 @@
|
||||
<link rel="stylesheet" href="/static/plugs/zTree/fontawesome.css">
|
||||
<link rel="stylesheet" href="/static/plugs/zTree/zTreeStyle.css?v={$version}">
|
||||
<script src='/static/plugs/jquery-3.4.1/jquery-3.4.1.min.js'></script>
|
||||
<script src='/static/plugs/zTree/jquery.ztree.core.js'></script>
|
||||
<script src='/static/plugs/zTree/jquery.ztree.excheck.js'></script>
|
||||
|
||||
<div class="layuimini-container">
|
||||
|
||||
<form id="app-form" class="layui-form layuimini-form">
|
||||
|
||||
<div class="layui-form-item">
|
||||
@@ -10,8 +17,8 @@
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label required">分配节点</label>
|
||||
<div class="layui-input-block">
|
||||
<div id="node_ids" class="demo-tree-more"></div>
|
||||
<div class="layui-input-block" id="zTree">
|
||||
<ul id="tree" class="ztree"></ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -24,4 +31,4 @@
|
||||
</div>
|
||||
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -54,6 +54,15 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">新标签页窗口</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="radio" name="iframe_open_top" value="0" title="不允许" {if 1!=sysConfig('site','iframe_open_top')}checked{/if}>
|
||||
<input type="radio" name="iframe_open_top" value="1" title="允许" {if 1==sysConfig('site','iframe_open_top')}checked{/if}>
|
||||
<br>
|
||||
<tip>是否允许弹框在新标签页打开。</tip>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">默认编辑器</label>
|
||||
|
||||
@@ -190,6 +190,9 @@ class AdminController extends BaseController
|
||||
case '%*':
|
||||
$where[] = [$key, 'LIKE', "%{$val}"];
|
||||
break;
|
||||
case 'in':
|
||||
$where[] = [$key, 'IN', $val];
|
||||
break;
|
||||
case 'range':
|
||||
[$beginTime, $endTime] = explode(' - ', $val);
|
||||
$where[] = [$key, '>=', strtotime($beginTime)];
|
||||
@@ -240,6 +243,7 @@ class AdminController extends BaseController
|
||||
'version' => env('APP_DEBUG') ? time() : ConfigService::getVersion(),
|
||||
'adminUploadUrl' => url('ajax/upload', [], false),
|
||||
'adminEditor' => sysConfig('site', 'editor_type') ?: 'wangEditor',
|
||||
'iframeOpenTop' => sysConfig('site', 'iframe_open_top') ?: 0,
|
||||
];
|
||||
View::assign($data);
|
||||
}
|
||||
|
||||
@@ -14,6 +14,6 @@ class Index extends BaseController
|
||||
public function index(): Redirect
|
||||
{
|
||||
// 这是项目首页 系统默认跳转后台页面
|
||||
return redirect('/' . Env::get('EASYADMIN.ADMIN', false));
|
||||
return redirect('/' . Env::get('EASYADMIN.ADMIN', 'admin'));
|
||||
}
|
||||
}
|
||||
@@ -27,6 +27,9 @@ class Install extends BaseController
|
||||
}elseif (!extension_loaded("PDO")) {
|
||||
$errorInfo = '当前未开启PDO,无法进行安装';
|
||||
}
|
||||
if (!is_file(root_path() . '.env')) {
|
||||
$errorInfo = '.env 文件不存在,请先配置 .env 文件';
|
||||
}
|
||||
if (!$request->isAjax()) {
|
||||
$currentHost = '://';
|
||||
$result = compact('errorInfo', 'currentHost', 'isInstall');
|
||||
|
||||
@@ -37,7 +37,8 @@
|
||||
"qiniu/php-sdk": "v7.11.0",
|
||||
"ext-mysqli": "*",
|
||||
"ext-pdo": "*",
|
||||
"wolf-leo/phplogviewer": "^0.05.0"
|
||||
"wolf-leo/phplogviewer": "^0.11.3",
|
||||
"wolfcode/authenticator": "^0.0.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/var-dumper": ">=4.2",
|
||||
|
||||
@@ -97,6 +97,8 @@ CREATE TABLE `ea_system_admin`
|
||||
`create_time` int(11) DEFAULT NULL COMMENT '创建时间',
|
||||
`update_time` int(11) DEFAULT NULL COMMENT '更新时间',
|
||||
`delete_time` int(11) DEFAULT NULL COMMENT '删除时间',
|
||||
`login_type` tinyint unsigned NOT NULL DEFAULT '1' COMMENT '登录方式',
|
||||
`ga_secret` varchar(32) NOT NULL DEFAULT '' COMMENT '谷歌验证码秘钥',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `username` (`username`) USING BTREE,
|
||||
KEY `phone` (`phone`)
|
||||
@@ -106,7 +108,7 @@ CREATE TABLE `ea_system_admin`
|
||||
-- Records of ea_system_admin
|
||||
-- ----------------------------
|
||||
INSERT INTO `ea_system_admin`
|
||||
VALUES ('1', null, '/static/admin/images/head.jpg', 'admin', 'a33b679d5581a8692988ec9f92ad2d6a2259eaa7', 'admin', 'admin', '0', '0', '1', '1589454169', '1589476815', null);
|
||||
VALUES ('1', null, '/static/admin/images/head.jpg', 'admin', 'a33b679d5581a8692988ec9f92ad2d6a2259eaa7', 'admin', 'admin', '0', '0', '1', '1589454169', '1589476815', null,1,'');
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for ea_system_auth
|
||||
|
||||
@@ -134,6 +134,12 @@ html.dark, body {
|
||||
color: #a29c9c;
|
||||
}
|
||||
|
||||
.layui-form-item xm-select {
|
||||
min-height: 30px !important;
|
||||
line-height: 30px !important;
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
/** 按钮背景色 */
|
||||
.layuimini-container .layuimini-btn-primary {
|
||||
color: #fff;
|
||||
@@ -253,36 +259,10 @@ table样式
|
||||
|
||||
.layuimini-container .layui-table-tool {
|
||||
background-color: #ffffff;
|
||||
border-bottom: none !important;
|
||||
padding: 10px;
|
||||
padding-bottom: 15px !important;
|
||||
}
|
||||
|
||||
.dark .layuimini-container .layui-table-tool {
|
||||
background-color: var(--lay-color-bg-1);
|
||||
border-bottom: none !important;
|
||||
padding-bottom: 15px !important;
|
||||
}
|
||||
|
||||
.layuimini-container .layui-table-view {
|
||||
border: none !important;
|
||||
}
|
||||
|
||||
.layuimini-container .layui-table-box {
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
border-color: #e6e6e6;
|
||||
}
|
||||
|
||||
.dark .layuimini-container .layui-table-box {
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
border-color: #363636;
|
||||
}
|
||||
|
||||
.layuimini-container .layui-table-page, .layui-table-total {
|
||||
border-width: 0px 0 0;
|
||||
}
|
||||
|
||||
.layuimini-container .layui-table-box .layui-table-header th {
|
||||
font-weight: bold !important;
|
||||
color: #565656 !important;
|
||||
@@ -329,10 +309,6 @@ table样式
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
按钮
|
||||
*/
|
||||
.layuimini-container .layui-btn-success {
|
||||
color: #fff;
|
||||
background-color: #4bb368;
|
||||
@@ -360,14 +336,6 @@ table样式
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.layuimini-container .layui-table-tool-self {
|
||||
right: 0px;
|
||||
}
|
||||
|
||||
.layuimini-container .layui-table-tool {
|
||||
padding: 10px 0px;
|
||||
}
|
||||
|
||||
/**
|
||||
弹出层样式
|
||||
*/
|
||||
@@ -513,6 +481,18 @@ table样式
|
||||
.form-search .layui-input-inline input, .form-search .layui-input-inline select {
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
.tableSelect {
|
||||
margin: 5px !important;
|
||||
min-width: auto !important;
|
||||
left: 1px !important;
|
||||
right: 1px !important;
|
||||
}
|
||||
|
||||
.tableSelect img {
|
||||
object-fit: cover;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
|
||||
.layuimini-qiuck-module a i {
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
width: 80%;
|
||||
height: 60px;
|
||||
line-height: 60px;
|
||||
text-align: center;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
define(["jquery", "easy-admin", "echarts", "echarts-theme", "miniAdmin", "miniTab"], function ($, ea, echarts, undefined, miniAdmin, miniTab) {
|
||||
define(["jquery", "easy-admin", "echarts", "echarts-theme", "miniAdmin", "miniTab", "swiper"], function ($, ea, echarts, undefined, miniAdmin, miniTab) {
|
||||
|
||||
return {
|
||||
index: function () {
|
||||
@@ -50,6 +50,14 @@ define(["jquery", "easy-admin", "echarts", "echarts-theme", "miniAdmin", "miniTa
|
||||
},
|
||||
welcome: function () {
|
||||
miniTab.listen();
|
||||
|
||||
new Swiper('.mySwiper', {
|
||||
pagination: {
|
||||
el: '.swiper-pagination',
|
||||
clickable: true,
|
||||
},
|
||||
})
|
||||
|
||||
/**
|
||||
* 查看公告信息
|
||||
**/
|
||||
@@ -156,10 +164,22 @@ define(["jquery", "easy-admin", "echarts", "echarts-theme", "miniAdmin", "miniTa
|
||||
})
|
||||
},
|
||||
editAdmin: function () {
|
||||
let form = layui.form
|
||||
form.on('radio(loginType-filter)', function (data) {
|
||||
let elem = data.elem
|
||||
let value = elem.value
|
||||
if (value === '2') {
|
||||
let width = screen.width < 768 ? '85%' : '60%'
|
||||
ea.open('绑定谷歌验证码', ea.url('index/set2fa'), width, '75%')
|
||||
}
|
||||
});
|
||||
ea.listen();
|
||||
},
|
||||
editPassword: function () {
|
||||
ea.listen();
|
||||
}
|
||||
},
|
||||
set2fa: function () {
|
||||
ea.listen();
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
define(["easy-admin"], function (ea) {
|
||||
define(["jquery", "easy-admin"], function ($, ea) {
|
||||
|
||||
return {
|
||||
index: function () {
|
||||
@@ -39,6 +39,12 @@ define(["easy-admin"], function (ea) {
|
||||
window.location = ea.url('index');
|
||||
})
|
||||
}, function (res) {
|
||||
let data = res.data
|
||||
if (data.is_ga_code) {
|
||||
let elem = $('#gaCode')
|
||||
elem.removeClass('layui-hide');
|
||||
elem.find('input').focus()
|
||||
}
|
||||
ea.msg.error(res.msg, function () {
|
||||
$('#refreshCaptcha').trigger("click");
|
||||
});
|
||||
|
||||
@@ -42,6 +42,14 @@ define(["jquery", "easy-admin"], function ($, ea) {
|
||||
{field: 'virtual_sales', width: 100, title: '虚拟销量'},
|
||||
{field: 'sales', width: 80, title: '销量'},
|
||||
{field: 'status', title: '状态', width: 85, selectList: {0: '禁用', 1: '启用'}, templet: ea.table.switch},
|
||||
// 演示多选,实际数据库并无 status2 字段,搜索后会报错
|
||||
{
|
||||
field: 'status2', title: '演示多选', width: 105, search: 'xmSelect', selectList: {1: '模拟选项1', 2: '模拟选项2', 3: '模拟选项3', 4: '模拟选项4', 5: '模拟选项5'},
|
||||
searchOp: 'in', templet: function (res) {
|
||||
// 根据自己实际项目进行输出
|
||||
return res?.status2 || '模拟数据'
|
||||
}
|
||||
},
|
||||
{field: 'create_time', minWidth: 80, title: '创建时间', search: 'range'},
|
||||
{
|
||||
width: 250,
|
||||
|
||||
@@ -1,89 +1,107 @@
|
||||
define(["jquery", "easy-admin"], function ($, ea) {
|
||||
|
||||
var init = {
|
||||
table_elem: '#currentTable',
|
||||
table_render_id: 'currentTableRenderId',
|
||||
index_url: 'system.auth/index',
|
||||
add_url: 'system.auth/add',
|
||||
edit_url: 'system.auth/edit',
|
||||
delete_url: 'system.auth/delete',
|
||||
export_url: 'system.auth/export',
|
||||
modify_url: 'system.auth/modify',
|
||||
authorize_url: 'system.auth/authorize',
|
||||
};
|
||||
var init = {
|
||||
table_elem: '#currentTable',
|
||||
table_render_id: 'currentTableRenderId',
|
||||
index_url: 'system.auth/index',
|
||||
add_url: 'system.auth/add',
|
||||
edit_url: 'system.auth/edit',
|
||||
delete_url: 'system.auth/delete',
|
||||
export_url: 'system.auth/export',
|
||||
modify_url: 'system.auth/modify',
|
||||
authorize_url: 'system.auth/authorize',
|
||||
};
|
||||
|
||||
return {
|
||||
return {
|
||||
|
||||
index: function () {
|
||||
ea.table.render({
|
||||
init: init,
|
||||
cols: [[
|
||||
{type: "checkbox"},
|
||||
{field: 'id', width: 80, title: 'ID', searchOp: '='},
|
||||
{field: 'sort', width: 80, title: '排序', edit: 'text'},
|
||||
{field: 'title', minWidth: 80, title: '权限名称'},
|
||||
{field: 'remark', minWidth: 80, title: '备注信息'},
|
||||
{field: 'status', title: '状态', width: 85, search: 'select', selectList: {0: '禁用', 1: '启用'}, templet: ea.table.switch},
|
||||
{field: 'create_time', minWidth: 80, title: '创建时间', search: 'range'},
|
||||
{
|
||||
width: 250,
|
||||
title: '操作',
|
||||
templet: ea.table.tool,
|
||||
operat: [
|
||||
'edit',
|
||||
[{
|
||||
text: '授权',
|
||||
url: init.authorize_url,
|
||||
method: 'open',
|
||||
auth: 'authorize',
|
||||
class: 'layui-btn layui-btn-normal layui-btn-xs',
|
||||
}],
|
||||
'delete'
|
||||
]
|
||||
}
|
||||
]],
|
||||
});
|
||||
|
||||
ea.listen();
|
||||
},
|
||||
add: function () {
|
||||
ea.listen();
|
||||
},
|
||||
edit: function () {
|
||||
ea.listen();
|
||||
},
|
||||
authorize: function () {
|
||||
var tree = layui.tree;
|
||||
|
||||
ea.request.get(
|
||||
{
|
||||
url: window.location.href,
|
||||
}, function (res) {
|
||||
res.data = res.data || [];
|
||||
tree.render({
|
||||
elem: '#node_ids',
|
||||
data: res.data,
|
||||
showCheckbox: true,
|
||||
id: 'nodeDataId',
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
ea.listen(function (data) {
|
||||
var checkedData = tree.getChecked('nodeDataId');
|
||||
var ids = [];
|
||||
$.each(checkedData, function (i, v) {
|
||||
ids.push(v.id);
|
||||
if (v.children !== undefined && v.children.length > 0) {
|
||||
$.each(v.children, function (ii, vv) {
|
||||
ids.push(vv.id);
|
||||
});
|
||||
}
|
||||
index: function () {
|
||||
ea.table.render({
|
||||
init: init,
|
||||
cols: [[
|
||||
{type: "checkbox"},
|
||||
{field: 'id', width: 80, title: 'ID', searchOp: '='},
|
||||
{field: 'sort', width: 80, title: '排序', edit: 'text'},
|
||||
{field: 'title', minWidth: 80, title: '权限名称'},
|
||||
{field: 'remark', minWidth: 80, title: '备注信息'},
|
||||
{field: 'status', title: '状态', width: 85, search: 'select', selectList: {0: '禁用', 1: '启用'}, templet: ea.table.switch},
|
||||
{field: 'create_time', minWidth: 80, title: '创建时间', search: 'range'},
|
||||
{
|
||||
width: 250,
|
||||
title: '操作',
|
||||
templet: ea.table.tool,
|
||||
operat: [
|
||||
'edit',
|
||||
[{
|
||||
text: '授权',
|
||||
url: init.authorize_url,
|
||||
method: 'open',
|
||||
auth: 'authorize',
|
||||
class: 'layui-btn layui-btn-normal layui-btn-xs',
|
||||
}],
|
||||
'delete'
|
||||
]
|
||||
}
|
||||
]],
|
||||
});
|
||||
data.node = JSON.stringify(ids);
|
||||
return data;
|
||||
});
|
||||
|
||||
ea.listen();
|
||||
},
|
||||
add: function () {
|
||||
ea.listen();
|
||||
},
|
||||
edit: function () {
|
||||
ea.listen();
|
||||
},
|
||||
authorize: function () {
|
||||
|
||||
let setting = {
|
||||
check: {
|
||||
enable: true,
|
||||
chkStyle: "checkbox",
|
||||
},
|
||||
view: {
|
||||
showIcon: true,
|
||||
showLine: true,
|
||||
selectedMulti: false,
|
||||
dblClickExpand: false
|
||||
}, callback: {
|
||||
onClick: function (e, treeId, treeNode, clickFlag) {
|
||||
treeObj.checkNode(treeNode, !treeNode.checked, true);
|
||||
}
|
||||
}
|
||||
};
|
||||
let treeObj
|
||||
let treeData = []
|
||||
ea.request.get({url: window.location.href}, function (res) {
|
||||
res.data = res.data || [];
|
||||
$.each(res.data, function (index, value) {
|
||||
treeData[index] = []
|
||||
treeData[index].id = value.id
|
||||
treeData[index].name = value.title
|
||||
treeData[index].pId = 0
|
||||
treeData[index].open = true
|
||||
let children = value.children
|
||||
treeData[index]['children'] = []
|
||||
$.each(children, function (idx, val) {
|
||||
treeData[index]['children'].push({id: val.id, name: val.title, checked: val.checked, pId: value.id})
|
||||
})
|
||||
})
|
||||
$.fn.zTree.init($("#tree"), setting, treeData);
|
||||
treeObj = $.fn.zTree.getZTreeObj("tree");
|
||||
}
|
||||
);
|
||||
|
||||
ea.listen(function (data) {
|
||||
let checkedData = treeObj.getCheckedNodes();
|
||||
let ids = []
|
||||
for (var i = 0; i < checkedData.length; i++) {
|
||||
ids.push(checkedData[i].id)
|
||||
}
|
||||
data.node = JSON.stringify(ids);
|
||||
return data;
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
}
|
||||
)
|
||||
|
||||
@@ -21,6 +21,7 @@ require.config({
|
||||
"iconPickerFa": ["plugs/lay-module/iconPicker/iconPickerFa"],
|
||||
"autocomplete": ["plugs/lay-module/autocomplete/autocomplete"],
|
||||
"vue": ["plugs/vue-2.6.10/vue.min"],
|
||||
"swiper": ["plugs/swiper/swiper-bundle.min"],
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -19,9 +19,13 @@ define(["jquery", "tableSelect"], function ($, tableSelect) {
|
||||
table_render_id: 'currentTableRenderId',
|
||||
upload_url: 'ajax/upload',
|
||||
upload_exts: 'doc|gif|ico|icon|jpg|mp3|mp4|p12|pem|png|rar',
|
||||
csrf_token: window.CONFIG.CSRF_TOKEN
|
||||
csrf_token: window.CONFIG.CSRF_TOKEN,
|
||||
wait_submit: false,
|
||||
xmSelectList: {},
|
||||
xmSelectModel: {},
|
||||
};
|
||||
|
||||
|
||||
var admin = {
|
||||
config: {
|
||||
shade: [0.02, '#000'],
|
||||
@@ -112,6 +116,7 @@ define(["jquery", "tableSelect"], function ($, tableSelect) {
|
||||
// @todo 刷新csrf-token
|
||||
let token = data.responseJSON ? data.responseJSON.__token__ : ''
|
||||
init.csrf_token = token
|
||||
init.wait_submit = false
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -367,6 +372,15 @@ define(["jquery", "tableSelect"], function ($, tableSelect) {
|
||||
'</div>\n' +
|
||||
'</div>';
|
||||
break;
|
||||
case 'xmSelect':
|
||||
formHtml += '\t<div class="layui-form-item layui-inline">\n' +
|
||||
'<label class="layui-form-label">' + d.title + '</label>\n' +
|
||||
'<div class="layui-input-inline">\n' +
|
||||
'<div id="c-' + d.fieldAlias + '" class="tableSearch-xmSelect xmSelect-' + d.fieldAlias + '" name="' + d.fieldAlias + '" data-search-op="' + d.searchOp + '"></div>\n' +
|
||||
'</div>\n' +
|
||||
'</div>';
|
||||
init.xmSelectList[d.fieldAlias] = d.selectList
|
||||
break;
|
||||
case 'range':
|
||||
d.searchOp = 'range';
|
||||
formHtml += '\t<div class="layui-form-item layui-inline">\n' +
|
||||
@@ -820,6 +834,17 @@ define(["jquery", "tableSelect"], function ($, tableSelect) {
|
||||
return value;
|
||||
},
|
||||
listenTableSearch: function (tableId) {
|
||||
if (Object.keys(init.xmSelectList).length > 0) {
|
||||
$.each(init.xmSelectList, function (index, value) {
|
||||
const keysArray = Object.keys(value).map((key) => {
|
||||
return {name: value[key], value: key}
|
||||
})
|
||||
init.xmSelectModel[index] = xmSelect.render({
|
||||
el: '.xmSelect-' + index, language: 'zn', data: keysArray, name: index,
|
||||
filterable: true, paging: true, pageSize: 10, theme: {color: '#16b777'}, toolbar: {show: true},
|
||||
})
|
||||
})
|
||||
}
|
||||
form.on('submit(' + tableId + '_filter)', function (data) {
|
||||
var dataField = data.field;
|
||||
var formatFilter = {},
|
||||
@@ -974,6 +999,22 @@ define(["jquery", "tableSelect"], function ($, tableSelect) {
|
||||
before: function () {
|
||||
},
|
||||
success: function (layero, index) {
|
||||
if (window.CONFIG.IFRAME_OPEN_TOP == '1') {
|
||||
let iframeUrl = ``
|
||||
try {
|
||||
let iframeId = $('iframe:eq(0)').attr('id')
|
||||
let iframe = document.getElementById(iframeId)
|
||||
iframeUrl = iframe.contentWindow.location.href
|
||||
} catch (e) {
|
||||
iframeUrl = location.href
|
||||
}
|
||||
let _winTopBtn = `
|
||||
<span class="_winTopBtn layui-btn layui-btn-primary layui-btn-xs"
|
||||
style="position: absolute;top: 14px;right: 120px;color: #fff;border-color: #fff;" onclick="window.open('${iframeUrl}')">
|
||||
新标签页打开
|
||||
</span>`
|
||||
$('.layui-layer-iframe').append(_winTopBtn)
|
||||
}
|
||||
},
|
||||
end: function () {
|
||||
index = null
|
||||
@@ -1144,6 +1185,11 @@ define(["jquery", "tableSelect"], function ($, tableSelect) {
|
||||
if (tableId === undefined || tableId === '' || tableId == null) {
|
||||
tableId = init.table_render_id;
|
||||
}
|
||||
if (Object.keys(init.xmSelectModel).length > 0) {
|
||||
$.each(init.xmSelectModel, function (index, value) {
|
||||
init.xmSelectModel[index].setValue([])
|
||||
})
|
||||
}
|
||||
table.reload(tableId, {
|
||||
page: {
|
||||
curr: 1
|
||||
@@ -1365,6 +1411,10 @@ define(["jquery", "tableSelect"], function ($, tableSelect) {
|
||||
url = admin.url(url);
|
||||
}
|
||||
form.on('submit(' + filter + ')', function (data) {
|
||||
if (init.wait_submit) {
|
||||
layer.msg('你点击太快了', {icon: 16, shade: 0.3, shadeClose: false, time: 1000})
|
||||
return false
|
||||
}
|
||||
var dataField = data.field;
|
||||
var editorList = document.querySelectorAll(".editor");
|
||||
// 富文本数据处理
|
||||
@@ -1392,6 +1442,7 @@ define(["jquery", "tableSelect"], function ($, tableSelect) {
|
||||
if (typeof preposeCallback === 'function') {
|
||||
dataField = preposeCallback(dataField);
|
||||
}
|
||||
init.wait_submit = true
|
||||
admin.api.form(url, dataField, ok, no, ex, refresh);
|
||||
return false;
|
||||
});
|
||||
|
||||
@@ -700,14 +700,6 @@
|
||||
margin-top: -6px !important;
|
||||
}
|
||||
|
||||
.layuimini-menu-left .layui-nav .layui-nav-mored,.layuimini-menu-left .layui-nav-itemed>a .layui-nav-more{
|
||||
margin-top: -9px!important;
|
||||
}
|
||||
|
||||
.layuimini-menu-left-zoom.layui-nav .layui-nav-mored,.layuimini-menu-left-zoom.layui-nav-itemed>a .layui-nav-more{
|
||||
margin-top: -9px!important;
|
||||
}
|
||||
|
||||
.layuimini-menu-left .layui-nav-more:before,.layuimini-menu-left-zoom .layui-nav-more:before {
|
||||
content: "\e61a";
|
||||
}
|
||||
|
||||
13
public/static/plugs/swiper/swiper-bundle.min.css
vendored
Normal file
17
public/static/plugs/swiper/swiper-bundle.min.js
vendored
Normal file
@@ -10,14 +10,8 @@
|
||||
**************************提示********************************/
|
||||
|
||||
(function () {
|
||||
/**
|
||||
* 编辑器资源文件根路径。它所表示的含义是:以编辑器实例化页面为当前路径,指向编辑器资源文件(即dialog等文件夹)的路径。
|
||||
* 鉴于很多同学在使用编辑器的时候出现的种种路径问题,此处强烈建议大家使用"相对于网站根目录的相对路径"进行配置。
|
||||
* "相对于网站根目录的相对路径"也就是以斜杠开头的形如"/myProject/ueditor/"这样的路径。
|
||||
* 如果站点中有多个不在同一层级的页面需要实例化编辑器,且引用了同一UEditor的时候,此处的URL可能不适用于每个页面的编辑器。
|
||||
* 因此,UEditor提供了针对不同页面的编辑器可单独配置的根路径,具体来说,在需要实例化编辑器的页面最顶部写上如下代码即可。当然,需要令此处的URL等于对应的配置。
|
||||
* window.UEDITOR_HOME_URL = "/xxxx/xxxx/";
|
||||
*/
|
||||
// 资源文件根路径,如果你的页面不是放在根目录下,请注意修改这个路径
|
||||
// 通常情况下这个可以配置成静态资源CDN的地址
|
||||
window.UEDITOR_HOME_URL = "/static/plugs/ueditor/";
|
||||
var URL, CORS_URL;
|
||||
if (window.UEDITOR_HOME_URL) {
|
||||
@@ -29,6 +23,8 @@
|
||||
} else {
|
||||
URL = getUEBasePath();
|
||||
}
|
||||
// 需要能跨域的静态资源请求,主要用户弹窗页面等静态资源
|
||||
// 通常情况下这个可以配置成静态资源CDN的地址
|
||||
if (window.UEDITOR_CORS_URL) {
|
||||
CORS_URL = window.UEDITOR_CORS_URL;
|
||||
} else if (window.__msRoot) {
|
||||
@@ -38,6 +34,7 @@
|
||||
} else {
|
||||
CORS_URL = getUEBasePath();
|
||||
}
|
||||
|
||||
/**
|
||||
* 配置项主体。注意,此处所有涉及到路径的配置别遗漏URL变量。
|
||||
*/
|
||||
@@ -53,10 +50,19 @@
|
||||
|
||||
// 服务器统一请求接口路径
|
||||
serverUrl: "/" + (window.CONFIG.ADMIN || 'admin') + "/ajax/uploadUEditor",
|
||||
|
||||
// 从服务器获取配置
|
||||
loadConfigFromServer: true,
|
||||
|
||||
// 服务器统一请求头信息,会在所有请求中带上该信息
|
||||
serverHeaders: {
|
||||
// 'Authorization': 'Bearer xxx'
|
||||
},
|
||||
// 服务器返回参数统一转换方法,可以在这里统一处理返回参数
|
||||
serverResponsePrepare: function (res) {
|
||||
// console.log('serverResponsePrepare', res);
|
||||
return res;
|
||||
},
|
||||
|
||||
//工具栏上的所有的功能按钮和下拉框,可以在new编辑器的实例时选择自己需要的重新定义
|
||||
toolbars: [
|
||||
@@ -114,8 +120,8 @@
|
||||
"|",
|
||||
"imagenone", // 图片默认
|
||||
"imageleft", // 图片左浮动
|
||||
"imageright", // 图片右浮动
|
||||
"imagecenter", // 图片居中
|
||||
"imageright", // 图片右浮动
|
||||
"|",
|
||||
"simpleupload", // 单图上传
|
||||
"insertimage", // 多图上传
|
||||
@@ -154,12 +160,15 @@
|
||||
"print", // 打印
|
||||
"preview", // 预览
|
||||
"searchreplace", // 查询替换
|
||||
"|",
|
||||
"contentimport",
|
||||
"help", // 帮助
|
||||
]
|
||||
]
|
||||
|
||||
// 自定义工具栏按钮点击,返回 true 表示已经处理点击,会阻止默认事件
|
||||
, toolbarCallback: function (cmd, editor) {
|
||||
// console.log('toolbarCallback',cmd, editor);
|
||||
// switch(cmd){
|
||||
// case 'insertimage':
|
||||
// editor.execCommand('insertHtml', '<p><img src="xxxxx" /></p>');
|
||||
@@ -176,6 +185,33 @@
|
||||
// }
|
||||
}
|
||||
|
||||
// 自定义上传功能
|
||||
, uploadServiceEnable: false
|
||||
// 自定义上传函数,需要在这个函数中实现自定义上传逻辑
|
||||
// type 上传类型,image 图片,video 视频,audio 音频,attachment 附件
|
||||
// file 文件对象
|
||||
// callback 回调函数,需要在上传完成后调用 callback.success、callback.error、callback.progress
|
||||
// option 上传配置,其他一些未来扩展配置
|
||||
, uploadServiceUpload: function(type, file, callback, option ) {
|
||||
console.log('uploadServiceUpload', type, file, callback, option);
|
||||
// var i = 0;
|
||||
// var call = function(){
|
||||
// i++;
|
||||
// if(i > 3){
|
||||
// callback.success({
|
||||
// "state": "SUCCESS",
|
||||
// "url": "https://ms-assets.modstart.com/demo/modstart.jpg",
|
||||
// })
|
||||
// return;
|
||||
// }
|
||||
// setTimeout(function(){
|
||||
// callback.progress(0.3 * i);
|
||||
// call();
|
||||
// },500);
|
||||
// }
|
||||
// call();
|
||||
}
|
||||
|
||||
// 插入图片自定义配置
|
||||
, imageConfig: {
|
||||
// 禁止本地上传
|
||||
@@ -316,7 +352,8 @@
|
||||
// 是否开启初始化时即全屏,默认关闭
|
||||
, fullscreen: false
|
||||
|
||||
//,imagePopup:true //图片操作的浮层开关,默认打开
|
||||
// 图片操作的浮层开关,默认打开
|
||||
//,imagePopup:true
|
||||
|
||||
// 自动同步编辑器要提交的数据
|
||||
//,autoSyncData:true
|
||||
@@ -359,17 +396,8 @@
|
||||
// 提交到后台的数据是否包含整个html字符串
|
||||
, allHtmlEnabled: false
|
||||
|
||||
//insertorderedlist
|
||||
//有序列表的下拉配置,值留空时支持多语言自动识别,若配置值,则以此值为准
|
||||
//,'insertorderedlist':{
|
||||
// //自定的样式
|
||||
// 'num':'1,2,3...',
|
||||
// 'num1':'1),2),3)...',
|
||||
// 'num2':'(1),(2),(3)...',
|
||||
// 'cn':'一,二,三....',
|
||||
// 'cn1':'一),二),三)....',
|
||||
// 'cn2':'(一),(二),(三)....',
|
||||
// //系统自带
|
||||
// 'decimal' : '' , //'1,2,3...'
|
||||
// 'lower-alpha' : '' , // 'a,b,c...'
|
||||
// 'lower-roman' : '' , //'i,ii,iii...'
|
||||
@@ -380,8 +408,6 @@
|
||||
//insertunorderedlist
|
||||
//无序列表的下拉配置,值留空时支持多语言自动识别,若配置值,则以此值为准
|
||||
//,insertunorderedlist : { //自定的样式
|
||||
// 'dash' :'— 破折号', //-破折号
|
||||
// 'dot':' 。 小圆圈', //系统自带
|
||||
// 'circle' : '', // '○ 小圆圈'
|
||||
// 'disc' : '', // '● 小圆点'
|
||||
// 'square' : '' //'■ 小方块'
|
||||
@@ -465,6 +491,12 @@
|
||||
"forecolor", // 字体颜色
|
||||
// "shadowcolor", // 字体阴影
|
||||
"backcolor", // 背景色
|
||||
"imagenone",
|
||||
"imageleft",
|
||||
"imagecenter",
|
||||
"imageright",
|
||||
"insertimage",
|
||||
"formula",
|
||||
// "justifyleft", // 居左对齐
|
||||
// "justifycenter", // 居中对齐
|
||||
// "justifyright", // 居右对齐
|
||||
@@ -513,19 +545,19 @@
|
||||
// 是否自动长高,默认true
|
||||
, autoHeightEnabled: true
|
||||
|
||||
//scaleEnabled
|
||||
//是否可以拉伸长高,默认true(当开启时,自动长高失效)
|
||||
// 是否可以拉伸长高,默认true(当开启时,自动长高失效)
|
||||
//,scaleEnabled:false
|
||||
//,minFrameWidth:800 //编辑器拖动时最小宽度,默认800
|
||||
//,minFrameHeight:220 //编辑器拖动时最小高度,默认220
|
||||
|
||||
//autoFloatEnabled
|
||||
//是否保持toolbar的位置不动,默认true
|
||||
//,autoFloatEnabled:true
|
||||
//浮动时工具栏距离浏览器顶部的高度,用于某些具有固定头部的页面
|
||||
//,topOffset:30
|
||||
//编辑器底部距离工具栏高度(如果参数大于等于编辑器高度,则设置无效)
|
||||
//,toolbarTopOffset:400
|
||||
// 编辑器最小高度,默认220
|
||||
, minFrameHeight: 220
|
||||
|
||||
// 是否保持toolbar的位置不动,默认true
|
||||
, autoFloatEnabled: true
|
||||
// 浮动时工具栏距离浏览器顶部的高度,用于某些具有固定头部的页面
|
||||
, topOffset: 0
|
||||
// 编辑器底部距离工具栏高度(如果参数大于等于编辑器高度,则设置无效)
|
||||
, toolbarTopOffset: 0
|
||||
|
||||
//设置远程图片是否抓取到本地保存
|
||||
, catchRemoteImageEnable: true //设置是否抓取远程图片
|
||||
@@ -595,7 +627,15 @@
|
||||
// 允许进入编辑器的 div 标签自动变成 p 标签
|
||||
, allowDivTransToP: true
|
||||
// 默认产出的数据中的color自动从rgb格式变成16进制格式
|
||||
, rgb2Hex: true
|
||||
, rgb2Hex: true,
|
||||
|
||||
tipError: function (msg, param) {
|
||||
if (window && window.MS && window.MS.dialog) {
|
||||
window.MS.dialog.tipError(msg);
|
||||
} else {
|
||||
alert(msg);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function getUEBasePath(docUrl, confUrl) {
|
||||
@@ -651,4 +691,4 @@
|
||||
window.UE = {
|
||||
getUEBasePath: getUEBasePath
|
||||
};
|
||||
})();
|
||||
})();
|
||||
2575
public/static/plugs/xmSelect/xm-select.js
Normal file
6110
public/static/plugs/zTree/fontawesome.css
vendored
Normal file
BIN
public/static/plugs/zTree/img/diy/1_close.png
Normal file
|
After Width: | Height: | Size: 601 B |
BIN
public/static/plugs/zTree/img/diy/1_open.png
Normal file
|
After Width: | Height: | Size: 580 B |
BIN
public/static/plugs/zTree/img/diy/2.png
Normal file
|
After Width: | Height: | Size: 570 B |
BIN
public/static/plugs/zTree/img/diy/3.png
Normal file
|
After Width: | Height: | Size: 762 B |
BIN
public/static/plugs/zTree/img/diy/4.png
Normal file
|
After Width: | Height: | Size: 399 B |
BIN
public/static/plugs/zTree/img/diy/5.png
Normal file
|
After Width: | Height: | Size: 710 B |
BIN
public/static/plugs/zTree/img/diy/6.png
Normal file
|
After Width: | Height: | Size: 432 B |
BIN
public/static/plugs/zTree/img/diy/7.png
Normal file
|
After Width: | Height: | Size: 534 B |
BIN
public/static/plugs/zTree/img/diy/8.png
Normal file
|
After Width: | Height: | Size: 529 B |
BIN
public/static/plugs/zTree/img/diy/9.png
Normal file
|
After Width: | Height: | Size: 467 B |
BIN
public/static/plugs/zTree/img/line_conn.gif
Normal file
|
After Width: | Height: | Size: 45 B |
BIN
public/static/plugs/zTree/img/loading.gif
Normal file
|
After Width: | Height: | Size: 381 B |
BIN
public/static/plugs/zTree/img/zTreeStandard.gif
Normal file
|
After Width: | Height: | Size: 5.4 KiB |
BIN
public/static/plugs/zTree/img/zTreeStandard.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
3
public/static/plugs/zTree/jquery.ztree.all.min.js
vendored
Normal file
2017
public/static/plugs/zTree/jquery.ztree.core.js
Normal file
652
public/static/plugs/zTree/jquery.ztree.excheck.js
Normal file
@@ -0,0 +1,652 @@
|
||||
/*
|
||||
* JQuery zTree excheck
|
||||
* v3.5.48
|
||||
* http://treejs.cn/
|
||||
*
|
||||
* Copyright (c) 2010 Hunter.z
|
||||
*
|
||||
* Licensed same as jquery - MIT License
|
||||
* http://www.opensource.org/licenses/mit-license.php
|
||||
*
|
||||
* Date: 2020-11-21
|
||||
*/
|
||||
|
||||
(function ($) {
|
||||
//default consts of excheck
|
||||
var _consts = {
|
||||
event: {
|
||||
CHECK: "ztree_check"
|
||||
},
|
||||
id: {
|
||||
CHECK: "_check"
|
||||
},
|
||||
checkbox: {
|
||||
STYLE: "checkbox",
|
||||
DEFAULT: "chk",
|
||||
DISABLED: "disable",
|
||||
FALSE: "false",
|
||||
TRUE: "true",
|
||||
FULL: "full",
|
||||
PART: "part",
|
||||
FOCUS: "focus"
|
||||
},
|
||||
radio: {
|
||||
STYLE: "radio",
|
||||
TYPE_ALL: "all",
|
||||
TYPE_LEVEL: "level"
|
||||
}
|
||||
},
|
||||
//default setting of excheck
|
||||
_setting = {
|
||||
check: {
|
||||
enable: false,
|
||||
autoCheckTrigger: false,
|
||||
chkStyle: _consts.checkbox.STYLE,
|
||||
nocheckInherit: false,
|
||||
chkDisabledInherit: false,
|
||||
radioType: _consts.radio.TYPE_LEVEL,
|
||||
chkboxType: {
|
||||
"Y": "ps",
|
||||
"N": "ps"
|
||||
}
|
||||
},
|
||||
data: {
|
||||
key: {
|
||||
checked: "checked"
|
||||
}
|
||||
},
|
||||
callback: {
|
||||
beforeCheck: null,
|
||||
onCheck: null
|
||||
}
|
||||
},
|
||||
//default root of excheck
|
||||
_initRoot = function (setting) {
|
||||
var r = data.getRoot(setting);
|
||||
r.radioCheckedList = [];
|
||||
},
|
||||
//default cache of excheck
|
||||
_initCache = function (treeId) {
|
||||
},
|
||||
//default bind event of excheck
|
||||
_bindEvent = function (setting) {
|
||||
var o = setting.treeObj,
|
||||
c = consts.event;
|
||||
o.bind(c.CHECK, function (event, srcEvent, treeId, node) {
|
||||
event.srcEvent = srcEvent;
|
||||
tools.apply(setting.callback.onCheck, [event, treeId, node]);
|
||||
});
|
||||
},
|
||||
_unbindEvent = function (setting) {
|
||||
var o = setting.treeObj,
|
||||
c = consts.event;
|
||||
o.unbind(c.CHECK);
|
||||
},
|
||||
//default event proxy of excheck
|
||||
_eventProxy = function (e) {
|
||||
var target = e.target,
|
||||
setting = data.getSetting(e.data.treeId),
|
||||
tId = "", node = null,
|
||||
nodeEventType = "", treeEventType = "",
|
||||
nodeEventCallback = null, treeEventCallback = null;
|
||||
|
||||
if (tools.eqs(e.type, "mouseover")) {
|
||||
if (setting.check.enable && tools.eqs(target.tagName, "span") && target.getAttribute("treeNode" + consts.id.CHECK) !== null) {
|
||||
tId = tools.getNodeMainDom(target).id;
|
||||
nodeEventType = "mouseoverCheck";
|
||||
}
|
||||
} else if (tools.eqs(e.type, "mouseout")) {
|
||||
if (setting.check.enable && tools.eqs(target.tagName, "span") && target.getAttribute("treeNode" + consts.id.CHECK) !== null) {
|
||||
tId = tools.getNodeMainDom(target).id;
|
||||
nodeEventType = "mouseoutCheck";
|
||||
}
|
||||
} else if (tools.eqs(e.type, "click")) {
|
||||
if (setting.check.enable && tools.eqs(target.tagName, "span") && target.getAttribute("treeNode" + consts.id.CHECK) !== null) {
|
||||
tId = tools.getNodeMainDom(target).id;
|
||||
nodeEventType = "checkNode";
|
||||
}
|
||||
}
|
||||
if (tId.length > 0) {
|
||||
node = data.getNodeCache(setting, tId);
|
||||
switch (nodeEventType) {
|
||||
case "checkNode" :
|
||||
nodeEventCallback = _handler.onCheckNode;
|
||||
break;
|
||||
case "mouseoverCheck" :
|
||||
nodeEventCallback = _handler.onMouseoverCheck;
|
||||
break;
|
||||
case "mouseoutCheck" :
|
||||
nodeEventCallback = _handler.onMouseoutCheck;
|
||||
break;
|
||||
}
|
||||
}
|
||||
var proxyResult = {
|
||||
stop: nodeEventType === "checkNode",
|
||||
node: node,
|
||||
nodeEventType: nodeEventType,
|
||||
nodeEventCallback: nodeEventCallback,
|
||||
treeEventType: treeEventType,
|
||||
treeEventCallback: treeEventCallback
|
||||
};
|
||||
return proxyResult
|
||||
},
|
||||
//default init node of excheck
|
||||
_initNode = function (setting, level, n, parentNode, isFirstNode, isLastNode, openFlag) {
|
||||
if (!n) return;
|
||||
var checked = data.nodeChecked(setting, n);
|
||||
n.checkedOld = checked;
|
||||
if (typeof n.nocheck == "string") n.nocheck = tools.eqs(n.nocheck, "true");
|
||||
n.nocheck = !!n.nocheck || (setting.check.nocheckInherit && parentNode && !!parentNode.nocheck);
|
||||
if (typeof n.chkDisabled == "string") n.chkDisabled = tools.eqs(n.chkDisabled, "true");
|
||||
n.chkDisabled = !!n.chkDisabled || (setting.check.chkDisabledInherit && parentNode && !!parentNode.chkDisabled);
|
||||
if (typeof n.halfCheck == "string") n.halfCheck = tools.eqs(n.halfCheck, "true");
|
||||
n.halfCheck = !!n.halfCheck;
|
||||
n.check_Child_State = -1;
|
||||
n.check_Focus = false;
|
||||
n.getCheckStatus = function () {
|
||||
return data.getCheckStatus(setting, n);
|
||||
};
|
||||
|
||||
if (setting.check.chkStyle == consts.radio.STYLE && setting.check.radioType == consts.radio.TYPE_ALL && checked) {
|
||||
var r = data.getRoot(setting);
|
||||
r.radioCheckedList.push(n);
|
||||
}
|
||||
},
|
||||
//add dom for check
|
||||
_beforeA = function (setting, node, html) {
|
||||
if (setting.check.enable) {
|
||||
data.makeChkFlag(setting, node);
|
||||
html.push("<span ID='", node.tId, consts.id.CHECK, "' class='", view.makeChkClass(setting, node), "' treeNode", consts.id.CHECK, (node.nocheck === true ? " style='display:none;'" : ""), "></span>");
|
||||
}
|
||||
},
|
||||
//update zTreeObj, add method of check
|
||||
_zTreeTools = function (setting, zTreeTools) {
|
||||
zTreeTools.checkNode = function (node, checked, checkTypeFlag, callbackFlag) {
|
||||
var nodeChecked = data.nodeChecked(setting, node);
|
||||
if (node.chkDisabled === true) return;
|
||||
if (checked !== true && checked !== false) {
|
||||
checked = !nodeChecked;
|
||||
}
|
||||
callbackFlag = !!callbackFlag;
|
||||
|
||||
if (nodeChecked === checked && !checkTypeFlag) {
|
||||
return;
|
||||
} else if (callbackFlag && tools.apply(this.setting.callback.beforeCheck, [this.setting.treeId, node], true) == false) {
|
||||
return;
|
||||
}
|
||||
if (tools.uCanDo(this.setting) && this.setting.check.enable && node.nocheck !== true) {
|
||||
data.nodeChecked(setting, node, checked);
|
||||
var checkObj = $$(node, consts.id.CHECK, this.setting);
|
||||
if (checkTypeFlag || this.setting.check.chkStyle === consts.radio.STYLE) view.checkNodeRelation(this.setting, node);
|
||||
view.setChkClass(this.setting, checkObj, node);
|
||||
view.repairParentChkClassWithSelf(this.setting, node);
|
||||
if (callbackFlag) {
|
||||
this.setting.treeObj.trigger(consts.event.CHECK, [null, this.setting.treeId, node]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
zTreeTools.checkAllNodes = function (checked) {
|
||||
view.repairAllChk(this.setting, !!checked);
|
||||
}
|
||||
|
||||
zTreeTools.getCheckedNodes = function (checked) {
|
||||
checked = (checked !== false);
|
||||
var children = data.nodeChildren(setting, data.getRoot(this.setting));
|
||||
return data.getTreeCheckedNodes(this.setting, children, checked);
|
||||
}
|
||||
|
||||
zTreeTools.getChangeCheckedNodes = function () {
|
||||
var children = data.nodeChildren(setting, data.getRoot(this.setting));
|
||||
return data.getTreeChangeCheckedNodes(this.setting, children);
|
||||
}
|
||||
|
||||
zTreeTools.setChkDisabled = function (node, disabled, inheritParent, inheritChildren) {
|
||||
disabled = !!disabled;
|
||||
inheritParent = !!inheritParent;
|
||||
inheritChildren = !!inheritChildren;
|
||||
view.repairSonChkDisabled(this.setting, node, disabled, inheritChildren);
|
||||
view.repairParentChkDisabled(this.setting, node.getParentNode(), disabled, inheritParent);
|
||||
}
|
||||
|
||||
var _updateNode = zTreeTools.updateNode;
|
||||
zTreeTools.updateNode = function (node, checkTypeFlag) {
|
||||
if (_updateNode) _updateNode.apply(zTreeTools, arguments);
|
||||
if (!node || !this.setting.check.enable) return;
|
||||
var nObj = $$(node, this.setting);
|
||||
if (nObj.get(0) && tools.uCanDo(this.setting)) {
|
||||
var checkObj = $$(node, consts.id.CHECK, this.setting);
|
||||
if (checkTypeFlag == true || this.setting.check.chkStyle === consts.radio.STYLE) view.checkNodeRelation(this.setting, node);
|
||||
view.setChkClass(this.setting, checkObj, node);
|
||||
view.repairParentChkClassWithSelf(this.setting, node);
|
||||
}
|
||||
}
|
||||
},
|
||||
//method of operate data
|
||||
_data = {
|
||||
getRadioCheckedList: function (setting) {
|
||||
var checkedList = data.getRoot(setting).radioCheckedList;
|
||||
for (var i = 0, j = checkedList.length; i < j; i++) {
|
||||
if (!data.getNodeCache(setting, checkedList[i].tId)) {
|
||||
checkedList.splice(i, 1);
|
||||
i--;
|
||||
j--;
|
||||
}
|
||||
}
|
||||
return checkedList;
|
||||
},
|
||||
getCheckStatus: function (setting, node) {
|
||||
if (!setting.check.enable || node.nocheck || node.chkDisabled) return null;
|
||||
var checked = data.nodeChecked(setting, node),
|
||||
r = {
|
||||
checked: checked,
|
||||
half: node.halfCheck ? node.halfCheck : (setting.check.chkStyle == consts.radio.STYLE ? (node.check_Child_State === 2) : (checked ? (node.check_Child_State > -1 && node.check_Child_State < 2) : (node.check_Child_State > 0)))
|
||||
};
|
||||
return r;
|
||||
},
|
||||
getTreeCheckedNodes: function (setting, nodes, checked, results) {
|
||||
if (!nodes) return [];
|
||||
var onlyOne = (checked && setting.check.chkStyle == consts.radio.STYLE && setting.check.radioType == consts.radio.TYPE_ALL);
|
||||
results = !results ? [] : results;
|
||||
for (var i = 0, l = nodes.length; i < l; i++) {
|
||||
var node = nodes[i];
|
||||
var children = data.nodeChildren(setting, node);
|
||||
var nodeChecked = data.nodeChecked(setting, node);
|
||||
if (node.nocheck !== true && node.chkDisabled !== true && nodeChecked == checked) {
|
||||
results.push(node);
|
||||
if (onlyOne) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
data.getTreeCheckedNodes(setting, children, checked, results);
|
||||
if (onlyOne && results.length > 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return results;
|
||||
},
|
||||
getTreeChangeCheckedNodes: function (setting, nodes, results) {
|
||||
if (!nodes) return [];
|
||||
results = !results ? [] : results;
|
||||
for (var i = 0, l = nodes.length; i < l; i++) {
|
||||
var node = nodes[i];
|
||||
var children = data.nodeChildren(setting, node);
|
||||
var nodeChecked = data.nodeChecked(setting, node);
|
||||
if (node.nocheck !== true && node.chkDisabled !== true && nodeChecked != node.checkedOld) {
|
||||
results.push(node);
|
||||
}
|
||||
data.getTreeChangeCheckedNodes(setting, children, results);
|
||||
}
|
||||
return results;
|
||||
},
|
||||
makeChkFlag: function (setting, node) {
|
||||
if (!node) return;
|
||||
var chkFlag = -1;
|
||||
var children = data.nodeChildren(setting, node);
|
||||
if (children) {
|
||||
for (var i = 0, l = children.length; i < l; i++) {
|
||||
var cNode = children[i];
|
||||
var nodeChecked = data.nodeChecked(setting, cNode);
|
||||
var tmp = -1;
|
||||
if (setting.check.chkStyle == consts.radio.STYLE) {
|
||||
if (cNode.nocheck === true || cNode.chkDisabled === true) {
|
||||
tmp = cNode.check_Child_State;
|
||||
} else if (cNode.halfCheck === true) {
|
||||
tmp = 2;
|
||||
} else if (nodeChecked) {
|
||||
tmp = 2;
|
||||
} else {
|
||||
tmp = cNode.check_Child_State > 0 ? 2 : 0;
|
||||
}
|
||||
if (tmp == 2) {
|
||||
chkFlag = 2;
|
||||
break;
|
||||
} else if (tmp == 0) {
|
||||
chkFlag = 0;
|
||||
}
|
||||
} else if (setting.check.chkStyle == consts.checkbox.STYLE) {
|
||||
if (cNode.nocheck === true || cNode.chkDisabled === true) {
|
||||
tmp = cNode.check_Child_State;
|
||||
} else if (cNode.halfCheck === true) {
|
||||
tmp = 1;
|
||||
} else if (nodeChecked) {
|
||||
tmp = (cNode.check_Child_State === -1 || cNode.check_Child_State === 2) ? 2 : 1;
|
||||
} else {
|
||||
tmp = (cNode.check_Child_State > 0) ? 1 : 0;
|
||||
}
|
||||
if (tmp === 1) {
|
||||
chkFlag = 1;
|
||||
break;
|
||||
} else if (tmp === 2 && chkFlag > -1 && i > 0 && tmp !== chkFlag) {
|
||||
chkFlag = 1;
|
||||
break;
|
||||
} else if (chkFlag === 2 && tmp > -1 && tmp < 2) {
|
||||
chkFlag = 1;
|
||||
break;
|
||||
} else if (tmp > -1) {
|
||||
chkFlag = tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
node.check_Child_State = chkFlag;
|
||||
}
|
||||
},
|
||||
//method of event proxy
|
||||
_event = {},
|
||||
//method of event handler
|
||||
_handler = {
|
||||
onCheckNode: function (event, node) {
|
||||
if (node.chkDisabled === true) return false;
|
||||
var setting = data.getSetting(event.data.treeId);
|
||||
if (tools.apply(setting.callback.beforeCheck, [setting.treeId, node], true) == false) return true;
|
||||
var nodeChecked = data.nodeChecked(setting, node);
|
||||
data.nodeChecked(setting, node, !nodeChecked);
|
||||
view.checkNodeRelation(setting, node);
|
||||
var checkObj = $$(node, consts.id.CHECK, setting);
|
||||
view.setChkClass(setting, checkObj, node);
|
||||
view.repairParentChkClassWithSelf(setting, node);
|
||||
setting.treeObj.trigger(consts.event.CHECK, [event, setting.treeId, node]);
|
||||
return true;
|
||||
},
|
||||
onMouseoverCheck: function (event, node) {
|
||||
if (node.chkDisabled === true) return false;
|
||||
var setting = data.getSetting(event.data.treeId),
|
||||
checkObj = $$(node, consts.id.CHECK, setting);
|
||||
node.check_Focus = true;
|
||||
view.setChkClass(setting, checkObj, node);
|
||||
return true;
|
||||
},
|
||||
onMouseoutCheck: function (event, node) {
|
||||
if (node.chkDisabled === true) return false;
|
||||
var setting = data.getSetting(event.data.treeId),
|
||||
checkObj = $$(node, consts.id.CHECK, setting);
|
||||
node.check_Focus = false;
|
||||
view.setChkClass(setting, checkObj, node);
|
||||
return true;
|
||||
}
|
||||
},
|
||||
//method of tools for zTree
|
||||
_tools = {},
|
||||
//method of operate ztree dom
|
||||
_view = {
|
||||
checkNodeRelation: function (setting, node) {
|
||||
var pNode, i, l,
|
||||
r = consts.radio;
|
||||
var nodeChecked = data.nodeChecked(setting, node);
|
||||
if (setting.check.chkStyle == r.STYLE) {
|
||||
var checkedList = data.getRadioCheckedList(setting);
|
||||
if (nodeChecked) {
|
||||
if (setting.check.radioType == r.TYPE_ALL) {
|
||||
for (i = checkedList.length - 1; i >= 0; i--) {
|
||||
pNode = checkedList[i];
|
||||
var pNodeChecked = data.nodeChecked(setting, pNode);
|
||||
if (pNodeChecked && pNode != node) {
|
||||
data.nodeChecked(setting, pNode, false);
|
||||
checkedList.splice(i, 1);
|
||||
|
||||
view.setChkClass(setting, $$(pNode, consts.id.CHECK, setting), pNode);
|
||||
if (pNode.parentTId != node.parentTId) {
|
||||
view.repairParentChkClassWithSelf(setting, pNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
checkedList.push(node);
|
||||
} else {
|
||||
var parentNode = (node.parentTId) ? node.getParentNode() : data.getRoot(setting);
|
||||
var children = data.nodeChildren(setting, parentNode);
|
||||
for (i = 0, l = children.length; i < l; i++) {
|
||||
pNode = children[i];
|
||||
var pNodeChecked = data.nodeChecked(setting, pNode);
|
||||
if (pNodeChecked && pNode != node) {
|
||||
data.nodeChecked(setting, pNode, false);
|
||||
view.setChkClass(setting, $$(pNode, consts.id.CHECK, setting), pNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (setting.check.radioType == r.TYPE_ALL) {
|
||||
for (i = 0, l = checkedList.length; i < l; i++) {
|
||||
if (node == checkedList[i]) {
|
||||
checkedList.splice(i, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
var children = data.nodeChildren(setting, node);
|
||||
if (nodeChecked && (!children || children.length == 0 || setting.check.chkboxType.Y.indexOf("s") > -1)) {
|
||||
view.setSonNodeCheckBox(setting, node, true);
|
||||
}
|
||||
if (!nodeChecked && (!children || children.length == 0 || setting.check.chkboxType.N.indexOf("s") > -1)) {
|
||||
view.setSonNodeCheckBox(setting, node, false);
|
||||
}
|
||||
if (nodeChecked && setting.check.chkboxType.Y.indexOf("p") > -1) {
|
||||
view.setParentNodeCheckBox(setting, node, true);
|
||||
}
|
||||
if (!nodeChecked && setting.check.chkboxType.N.indexOf("p") > -1) {
|
||||
view.setParentNodeCheckBox(setting, node, false);
|
||||
}
|
||||
}
|
||||
},
|
||||
makeChkClass: function (setting, node) {
|
||||
var c = consts.checkbox, r = consts.radio,
|
||||
fullStyle = "";
|
||||
var nodeChecked = data.nodeChecked(setting, node);
|
||||
if (node.chkDisabled === true) {
|
||||
fullStyle = c.DISABLED;
|
||||
} else if (node.halfCheck) {
|
||||
fullStyle = c.PART;
|
||||
} else if (setting.check.chkStyle == r.STYLE) {
|
||||
fullStyle = (node.check_Child_State < 1) ? c.FULL : c.PART;
|
||||
} else {
|
||||
fullStyle = nodeChecked ? ((node.check_Child_State === 2 || node.check_Child_State === -1) ? c.FULL : c.PART) : ((node.check_Child_State < 1) ? c.FULL : c.PART);
|
||||
}
|
||||
var chkName = setting.check.chkStyle + "_" + (nodeChecked ? c.TRUE : c.FALSE) + "_" + fullStyle;
|
||||
chkName = (node.check_Focus && node.chkDisabled !== true) ? chkName + "_" + c.FOCUS : chkName;
|
||||
return consts.className.BUTTON + " " + c.DEFAULT + " " + chkName;
|
||||
},
|
||||
repairAllChk: function (setting, checked) {
|
||||
if (setting.check.enable && setting.check.chkStyle === consts.checkbox.STYLE) {
|
||||
var root = data.getRoot(setting);
|
||||
var children = data.nodeChildren(setting, root);
|
||||
for (var i = 0, l = children.length; i < l; i++) {
|
||||
var node = children[i];
|
||||
if (node.nocheck !== true && node.chkDisabled !== true) {
|
||||
data.nodeChecked(setting, node, checked);
|
||||
}
|
||||
view.setSonNodeCheckBox(setting, node, checked);
|
||||
}
|
||||
}
|
||||
},
|
||||
repairChkClass: function (setting, node) {
|
||||
if (!node) return;
|
||||
data.makeChkFlag(setting, node);
|
||||
if (node.nocheck !== true) {
|
||||
var checkObj = $$(node, consts.id.CHECK, setting);
|
||||
view.setChkClass(setting, checkObj, node);
|
||||
}
|
||||
},
|
||||
repairParentChkClass: function (setting, node) {
|
||||
if (!node || !node.parentTId) return;
|
||||
var pNode = node.getParentNode();
|
||||
view.repairChkClass(setting, pNode);
|
||||
view.repairParentChkClass(setting, pNode);
|
||||
},
|
||||
repairParentChkClassWithSelf: function (setting, node) {
|
||||
if (!node) return;
|
||||
var children = data.nodeChildren(setting, node);
|
||||
if (children && children.length > 0) {
|
||||
view.repairParentChkClass(setting, children[0]);
|
||||
} else {
|
||||
view.repairParentChkClass(setting, node);
|
||||
}
|
||||
},
|
||||
repairSonChkDisabled: function (setting, node, chkDisabled, inherit) {
|
||||
if (!node) return;
|
||||
if (node.chkDisabled != chkDisabled) {
|
||||
node.chkDisabled = chkDisabled;
|
||||
}
|
||||
view.repairChkClass(setting, node);
|
||||
var children = data.nodeChildren(setting, node);
|
||||
if (children && inherit) {
|
||||
for (var i = 0, l = children.length; i < l; i++) {
|
||||
var sNode = children[i];
|
||||
view.repairSonChkDisabled(setting, sNode, chkDisabled, inherit);
|
||||
}
|
||||
}
|
||||
},
|
||||
repairParentChkDisabled: function (setting, node, chkDisabled, inherit) {
|
||||
if (!node) return;
|
||||
if (node.chkDisabled != chkDisabled && inherit) {
|
||||
node.chkDisabled = chkDisabled;
|
||||
}
|
||||
view.repairChkClass(setting, node);
|
||||
view.repairParentChkDisabled(setting, node.getParentNode(), chkDisabled, inherit);
|
||||
},
|
||||
setChkClass: function (setting, obj, node) {
|
||||
if (!obj) return;
|
||||
if (node.nocheck === true) {
|
||||
obj.hide();
|
||||
} else {
|
||||
obj.show();
|
||||
}
|
||||
obj.attr('class', view.makeChkClass(setting, node));
|
||||
},
|
||||
setParentNodeCheckBox: function (setting, node, value, srcNode) {
|
||||
var checkObj = $$(node, consts.id.CHECK, setting);
|
||||
if (!srcNode) srcNode = node;
|
||||
data.makeChkFlag(setting, node);
|
||||
if (node.nocheck !== true && node.chkDisabled !== true) {
|
||||
data.nodeChecked(setting, node, value);
|
||||
view.setChkClass(setting, checkObj, node);
|
||||
if (setting.check.autoCheckTrigger && node != srcNode) {
|
||||
setting.treeObj.trigger(consts.event.CHECK, [null, setting.treeId, node]);
|
||||
}
|
||||
}
|
||||
if (node.parentTId) {
|
||||
var pSign = true;
|
||||
if (!value) {
|
||||
var pNodes = data.nodeChildren(setting, node.getParentNode());
|
||||
for (var i = 0, l = pNodes.length; i < l; i++) {
|
||||
var pNode = pNodes[i];
|
||||
var nodeChecked = data.nodeChecked(setting, pNode);
|
||||
if ((pNode.nocheck !== true && pNode.chkDisabled !== true && nodeChecked)
|
||||
|| ((pNode.nocheck === true || pNode.chkDisabled === true) && pNode.check_Child_State > 0)) {
|
||||
pSign = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (pSign) {
|
||||
view.setParentNodeCheckBox(setting, node.getParentNode(), value, srcNode);
|
||||
}
|
||||
}
|
||||
},
|
||||
setSonNodeCheckBox: function (setting, node, value, srcNode) {
|
||||
if (!node) return;
|
||||
var checkObj = $$(node, consts.id.CHECK, setting);
|
||||
if (!srcNode) srcNode = node;
|
||||
|
||||
var hasDisable = false;
|
||||
var children = data.nodeChildren(setting, node);
|
||||
if (children) {
|
||||
for (var i = 0, l = children.length; i < l; i++) {
|
||||
var sNode = children[i];
|
||||
view.setSonNodeCheckBox(setting, sNode, value, srcNode);
|
||||
if (sNode.chkDisabled === true) hasDisable = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (node != data.getRoot(setting) && node.chkDisabled !== true) {
|
||||
if (hasDisable && node.nocheck !== true) {
|
||||
data.makeChkFlag(setting, node);
|
||||
}
|
||||
if (node.nocheck !== true && node.chkDisabled !== true) {
|
||||
data.nodeChecked(setting, node, value);
|
||||
if (!hasDisable) node.check_Child_State = (children && children.length > 0) ? (value ? 2 : 0) : -1;
|
||||
} else {
|
||||
node.check_Child_State = -1;
|
||||
}
|
||||
view.setChkClass(setting, checkObj, node);
|
||||
if (setting.check.autoCheckTrigger && node != srcNode && node.nocheck !== true && node.chkDisabled !== true) {
|
||||
setting.treeObj.trigger(consts.event.CHECK, [null, setting.treeId, node]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
},
|
||||
|
||||
_z = {
|
||||
tools: _tools,
|
||||
view: _view,
|
||||
event: _event,
|
||||
data: _data
|
||||
};
|
||||
$.extend(true, $.fn.zTree.consts, _consts);
|
||||
$.extend(true, $.fn.zTree._z, _z);
|
||||
|
||||
var zt = $.fn.zTree,
|
||||
tools = zt._z.tools,
|
||||
consts = zt.consts,
|
||||
view = zt._z.view,
|
||||
data = zt._z.data,
|
||||
event = zt._z.event,
|
||||
$$ = tools.$;
|
||||
|
||||
data.nodeChecked = function (setting, node, newChecked) {
|
||||
if (!node) {
|
||||
return false;
|
||||
}
|
||||
var key = setting.data.key.checked;
|
||||
if (typeof newChecked !== 'undefined') {
|
||||
if (typeof newChecked === "string") {
|
||||
newChecked = tools.eqs(newChecked, "true");
|
||||
}
|
||||
newChecked = !!newChecked;
|
||||
node[key] = newChecked;
|
||||
} else if (typeof node[key] == "string"){
|
||||
node[key] = tools.eqs(node[key], "true");
|
||||
} else {
|
||||
node[key] = !!node[key];
|
||||
}
|
||||
return node[key];
|
||||
};
|
||||
|
||||
data.exSetting(_setting);
|
||||
data.addInitBind(_bindEvent);
|
||||
data.addInitUnBind(_unbindEvent);
|
||||
data.addInitCache(_initCache);
|
||||
data.addInitNode(_initNode);
|
||||
data.addInitProxy(_eventProxy, true);
|
||||
data.addInitRoot(_initRoot);
|
||||
data.addBeforeA(_beforeA);
|
||||
data.addZTreeTools(_zTreeTools);
|
||||
|
||||
var _createNodes = view.createNodes;
|
||||
view.createNodes = function (setting, level, nodes, parentNode, index) {
|
||||
if (_createNodes) _createNodes.apply(view, arguments);
|
||||
if (!nodes) return;
|
||||
view.repairParentChkClassWithSelf(setting, parentNode);
|
||||
}
|
||||
var _removeNode = view.removeNode;
|
||||
view.removeNode = function (setting, node) {
|
||||
var parentNode = node.getParentNode();
|
||||
if (_removeNode) _removeNode.apply(view, arguments);
|
||||
if (!node || !parentNode) return;
|
||||
view.repairChkClass(setting, parentNode);
|
||||
view.repairParentChkClass(setting, parentNode);
|
||||
}
|
||||
|
||||
var _appendNodes = view.appendNodes;
|
||||
view.appendNodes = function (setting, level, nodes, parentNode, index, initFlag, openFlag) {
|
||||
var html = "";
|
||||
if (_appendNodes) {
|
||||
html = _appendNodes.apply(view, arguments);
|
||||
}
|
||||
if (parentNode) {
|
||||
data.makeChkFlag(setting, parentNode);
|
||||
}
|
||||
return html;
|
||||
}
|
||||
})(jQuery);
|
||||
BIN
public/static/plugs/zTree/webfonts/fa-regular-400.woff2
Normal file
BIN
public/static/plugs/zTree/webfonts/fa-solid-900.woff2
Normal file
250
public/static/plugs/zTree/zTreeStyle.css
Normal file
@@ -0,0 +1,250 @@
|
||||
/**
|
||||
* @author zhixin wen <wenzhixin2010@gmail.com>
|
||||
* version: 1.2.0
|
||||
* https://github.com/wenzhixin/font-awesome-zTree
|
||||
*/
|
||||
.ztree * {
|
||||
font-size: 14px;
|
||||
font-family: inherit;
|
||||
}
|
||||
|
||||
.ztree .fa, .ztree .fab, .ztree .fad, .ztree .fal, .ztree .far, .ztree .fas {
|
||||
font-family: "Font Awesome 5 Free";
|
||||
}
|
||||
|
||||
.ztree .ztree-search {
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
.ztree .ztree-search input {
|
||||
padding: 5px 10px;
|
||||
}
|
||||
|
||||
.ztree .ztree-search .search-clear {
|
||||
padding: 5px 10px;
|
||||
font-size: 12px;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.ztree li ul {
|
||||
position: relative;
|
||||
background: none;
|
||||
margin-left: 12px;
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
.ztree li ul.line {
|
||||
background: none;
|
||||
}
|
||||
|
||||
.ztree li ul::before {
|
||||
content: "";
|
||||
display: block;
|
||||
width: 0;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
border-left: 1px dotted #ccc;
|
||||
}
|
||||
|
||||
.ztree li li {
|
||||
position: relative;
|
||||
padding-left: 9px;
|
||||
line-height: inherit;
|
||||
}
|
||||
|
||||
.ztree li li::before {
|
||||
content: "";
|
||||
display: block;
|
||||
width: 10px;
|
||||
height: 0;
|
||||
border-top: 1px dotted #ccc;
|
||||
position: absolute;
|
||||
top: 13px;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.ztree li .noline_open + a + ul li::before {
|
||||
border-top: none;
|
||||
}
|
||||
|
||||
.ztree li .noline_open + a + ul::before {
|
||||
border-left: none;
|
||||
}
|
||||
|
||||
.ztree li span.node_name {
|
||||
margin-right: 6px;
|
||||
}
|
||||
|
||||
.ztree li span.button[class$=Page] {
|
||||
width: 15px;
|
||||
}
|
||||
|
||||
.ztree li span.button::before {
|
||||
display: block;
|
||||
line-height: 26px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.ztree li span.button.roots_docu, .ztree li span.button.center_docu, .ztree li span.button.bottom_docu {
|
||||
position: relative;
|
||||
height: 26px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.ztree li span.button.roots_docu::before, .ztree li span.button.center_docu::before, .ztree li span.button.bottom_docu::before {
|
||||
content: "";
|
||||
display: block;
|
||||
width: 18px;
|
||||
height: 0;
|
||||
border-top: 1px dotted #ccc;
|
||||
position: absolute;
|
||||
top: 13px;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.ztree li span.button.root_open::before, .ztree li span.button.roots_open::before, .ztree li span.button.center_open::before, .ztree li span.button.bottom_open::before, .ztree li span.button.noline_open::before {
|
||||
content: "\f146";
|
||||
color: #3c8dbc;
|
||||
}
|
||||
|
||||
.ztree li span.button.root_close::before, .ztree li span.button.roots_close::before, .ztree li span.button.center_close::before, .ztree li span.button.bottom_close::before, .ztree li span.button.noline_close::before {
|
||||
content: "\f0fe";
|
||||
color: #3c8dbc;
|
||||
}
|
||||
|
||||
.ztree li span.button.chk {
|
||||
color: #6b6b6b;
|
||||
}
|
||||
|
||||
.ztree li span.button.chk[class$=focus]::before {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.ztree li span.button.chk[class$=disable] {
|
||||
color: #ccc;
|
||||
}
|
||||
|
||||
.ztree li span.button.chk.checkbox_true_full::before, .ztree li span.button.chk.checkbox_true_disable::before, .ztree li span.button.chk.checkbox_true_full_focus::before {
|
||||
content: "\f14a";
|
||||
font-weight: normal !important;
|
||||
color: #16b777;
|
||||
}
|
||||
|
||||
.ztree li span.button.chk.checkbox_false_full::before, .ztree li span.button.chk.checkbox_false_disable::before, .ztree li span.button.chk.checkbox_false_full_focus::before {
|
||||
content: "\f0c8";
|
||||
font-weight: normal !important;
|
||||
}
|
||||
|
||||
.ztree li span.button.chk.checkbox_true_part::before, .ztree li span.button.chk.checkbox_true_part_focus::before, .ztree li span.button.chk.checkbox_false_part::before, .ztree li span.button.chk.checkbox_false_part_focus::before {
|
||||
content: "\f146";
|
||||
font-weight: bold !important;
|
||||
color: #16B777;
|
||||
}
|
||||
|
||||
.ztree li span.button.chk.radio_true_full::before, .ztree li span.button.chk.radio_true_disable::before, .ztree li span.button.chk.radio_true_full_focus::before {
|
||||
content: "\f058";
|
||||
font-weight: normal !important;
|
||||
}
|
||||
|
||||
.ztree li span.button.chk.radio_false_full::before, .ztree li span.button.chk.radio_false_disable::before, .ztree li span.button.chk.radio_false_full_focus::before {
|
||||
content: "\f111";
|
||||
font-weight: normal !important;
|
||||
}
|
||||
|
||||
.ztree li span.button.chk.radio_true_part::before, .ztree li span.button.chk.radio_true_part_focus::before, .ztree li span.button.chk.radio_false_part::before, .ztree li span.button.chk.radio_false_part_focus::before {
|
||||
content: "\f192";
|
||||
font-weight: normal !important;
|
||||
}
|
||||
|
||||
.ztree li span.button.ico_open::before {
|
||||
content: "\f07c";
|
||||
}
|
||||
|
||||
.ztree li span.button.ico_close::before {
|
||||
content: "\f07b";
|
||||
}
|
||||
|
||||
.ztree li span.button.ico_docu::before {
|
||||
content: "\f15b";
|
||||
}
|
||||
|
||||
.ztree li span.button.add::before {
|
||||
content: "\f067";
|
||||
}
|
||||
|
||||
.ztree li span.button.edit::before {
|
||||
content: "\f044";
|
||||
}
|
||||
|
||||
.ztree li span.button.remove::before {
|
||||
content: "\f2ed";
|
||||
}
|
||||
|
||||
.ztree li span.button.fa_history_ico_open::before, .ztree li span.button.fa_history_ico_close::before, .ztree li span.button.fa_history_ico_docu::before {
|
||||
font-weight: bold !important;
|
||||
content: "\f1da";
|
||||
}
|
||||
|
||||
.ztree li span.button.fa_tasks_ico_open::before {
|
||||
font-weight: bold !important;
|
||||
content: "\f233";
|
||||
}
|
||||
|
||||
.ztree li span.button.firstPage::before {
|
||||
content: "\f100";
|
||||
}
|
||||
|
||||
.ztree li span.button.prevPage::before {
|
||||
content: "\f053";
|
||||
}
|
||||
|
||||
.ztree li span.button.nextPage::before {
|
||||
content: "\f054";
|
||||
}
|
||||
|
||||
.ztree li span.button.lastPage::before {
|
||||
content: "\f101";
|
||||
}
|
||||
|
||||
.ztree li a span.button[style="width:0px;height:0px;"]::before, .ztree li a span.button[style^=background]::before {
|
||||
content: "";
|
||||
}
|
||||
|
||||
.ztree li a.curSelectedNode, .ztree li a.tmpTargetNode_inner {
|
||||
height: 26px;
|
||||
}
|
||||
|
||||
.ztree li > a {
|
||||
height: 26px;
|
||||
line-height: 26px;
|
||||
}
|
||||
|
||||
.ztree li > span {
|
||||
height: 26px;
|
||||
}
|
||||
|
||||
.ztree li:last-child::before {
|
||||
height: auto;
|
||||
top: 13px;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
.ztree li span.button.switch,
|
||||
.ztree li span.button.chk,
|
||||
.ztree li a span.button,
|
||||
.ztree li span.button[class$=Page] {
|
||||
position: relative;
|
||||
width: 21px;
|
||||
height: 26px;
|
||||
background: none;
|
||||
background-position: center center !important;
|
||||
padding: 2px 0;
|
||||
vertical-align: middle;
|
||||
display: inline-block;
|
||||
font: normal normal normal 15px/1 "Font Awesome 5 Free";
|
||||
text-rendering: auto;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
@@ -10,10 +10,22 @@
|
||||
<link rel="stylesheet" href="/static/common/css/insatll.css?v={:time()}" media="all">
|
||||
</head>
|
||||
<body>
|
||||
<h1><img src="/static/common/images/logo-1.png"></h1>
|
||||
<h1><img src="/static/common/images/logo-1.png" alt="" style="width: 100px;height: 100px;"></h1>
|
||||
<h2>安装 EasyAdmin8 后台系统</h2>
|
||||
<div class="content">
|
||||
<form class="layui-form layui-form-pane" action="">
|
||||
<div class="layui-card">
|
||||
<blockquote class="layui-elem-quote layui-font-green" style="text-align: left;padding: 5px 10px;">
|
||||
<div class="layui-row">
|
||||
<div class="layui-col-lg6 layui-col-xl6 layui-col-xs6 layui-col-sm6 layui-col-xs6">
|
||||
官网教程:<a href="https://EasyAdmin8.top?spm=001.3e3c9d.29f459" target="_blank" class="layui-font-blue">EasyAdmin8.top</a>
|
||||
</div>
|
||||
<div class="layui-col-lg6 layui-col-xl6 layui-col-xs6 layui-col-sm6 layui-col-xs6">
|
||||
常见问题:<a href="https://EasyAdmin8.top/guide/question.html?spm=001.3e3c9d.29f460" target="_blank" class="layui-font-blue">Question</a>
|
||||
</div>
|
||||
</div>
|
||||
</blockquote>
|
||||
</div>
|
||||
{if $errorInfo}
|
||||
<div class="error">
|
||||
{$errorInfo}
|
||||
|
||||