12 Commits

Author SHA1 Message Date
wolfcode
150e0ecd23 Update composer.json 2025-03-26 16:09:01 +08:00
wolfcode
e9ed0cd8f6 Merge branch 'main' of https://github.com/easyadmin8/EasyAdmin8 2025-03-26 14:03:22 +08:00
wolfcode
187d4343b3 refactor(admin): remove unused 'where' option in system module
- Remove unnecessary 'where' option from various models in system module
- Simplify query methods by removing redundant 'where' calls
- Affected models: Config, Node, SystemAdmin, SystemMenu, SystemNode
2025-03-26 14:00:58 +08:00
wolfcode
9bc0185b6b refactor(admin): improve error handling in Admin controller
- Enhance error messages by appending exception details
- Remove unnecessary password field handling in update scenario
2025-03-26 11:20:06 +08:00
wolfcode
652b17d6a6 refactor(admin): move auth_ids explode logic to model
- Remove auth_ids explode logic from Admin controller
- Add getAuthIdsAttr method to SystemAdmin model for auth_ids parsing
- This change improves code organization and reusability
2025-03-26 10:03:59 +08:00
wolfcode
ed8c3d545b refactor(admin):适配新版 think-orm remove console.log and refactor MallGoods model
- Remove unnecessary console.log statement from log.js
- Refactor MallGoods model to use getOptions method for deleteTime
2025-03-25 18:38:07 +08:00
wolfcode
12b38c7bf5 refactor(admin): optimize log data processing and display
- Update log data serialization and deserialization method
- Improve log data display format in the admin interface- Refactor log model initialization and table suffix handling
- Optimize time model configuration for better timestamp management
2025-03-25 18:08:35 +08:00
wolfcode
fc202be987 build(deps): update topthink/think-orm to 4.0.3
- Specify version 4.0.3 for topthink/think-orm in composer.json
- This change pins the ORM package to a specific version for stability and compatibility
2025-03-25 15:02:33 +08:00
wolfcode
71e069712a style(easy-admin): adjust image height in admin table
- Change image height from 40 to 30 in the admin table
2025-03-19 18:32:26 +08:00
wolfcode
ca4080d5e6 feat(config-admin): integrate lazyload for image optimization
- Add lazyload plugin to config-admin.js
- Implement lazyload functionality in easy-admin.js
- Add lazyload.min.js file to project
2025-03-18 17:10:46 +08:00
wolfcode
4bbe287626 refactor(system): upgrade tabs functionality and improve error handling
- Replace element.on with tabs.on for better tab management Add success and error handling for form submission
- Update HTML structure to use layui-tabs for improved UI
- Remove unnecessary Vue import
2025-03-17 18:02:06 +08:00
wolfcode
e316cd40e0 🚀 Layui v2.10.0 2025-03-17 18:01:02 +08:00
28 changed files with 254 additions and 142 deletions

View File

@@ -213,4 +213,23 @@ class Ajax extends AdminController
return json($config); return json($config);
} }
} }
public function composerInfo(): Json
{
$lockFilePath = root_path() . '/composer.lock';
$list = [];
if (file_exists($lockFilePath)) {
$lockFileContent = file_get_contents($lockFilePath);
if ($lockFileContent !== false) {
$lockData = json_decode($lockFileContent, true);
if (!empty($lockData['packages'])) {
foreach ($lockData['packages'] as $package) {
$list[] = ['name' => $package['name'], 'version' => $package['version']];
}
}
}
}
$this->success('success', $list);
}
} }

View File

@@ -70,7 +70,7 @@ class Admin extends AdminController
try { try {
$save = $this->model->save($post); $save = $this->model->save($post);
}catch (\Exception $e) { }catch (\Exception $e) {
$this->error('保存失败'); $this->error('保存失败' . $e->getMessage());
} }
$save ? $this->success('保存成功') : $this->error('保存失败'); $save ? $this->success('保存成功') : $this->error('保存失败');
} }
@@ -88,18 +88,14 @@ class Admin extends AdminController
$post['auth_ids'] = implode(',', array_keys($authIds)); $post['auth_ids'] = implode(',', array_keys($authIds));
$rule = []; $rule = [];
$this->validate($post, $rule); $this->validate($post, $rule);
if (isset($row['password'])) {
unset($row['password']);
}
try { try {
$save = $row->save($post); $save = $row->save($post);
TriggerService::updateMenu($id); TriggerService::updateMenu($id);
}catch (\Exception $e) { }catch (\Exception $e) {
$this->error('保存失败'); $this->error('保存失败' . $e->getMessage());
} }
$save ? $this->success('保存成功') : $this->error('保存失败'); $save ? $this->success('保存成功') : $this->error('保存失败');
} }
$row->auth_ids = explode(',', $row->auth_ids ?: '');
$this->assign('row', $row); $this->assign('row', $row);
return $this->fetch(); return $this->fetch();
} }

View File

@@ -41,12 +41,12 @@ class Config extends AdminController
if ($group == 'upload') { if ($group == 'upload') {
$upload_types = config('admin.upload_types'); $upload_types = config('admin.upload_types');
// 兼容旧版本 // 兼容旧版本
$this->model->where('name', 'upload_allow_type')->update(['value' => implode(',', array_keys($upload_types))]); $this->model->removeOption()->where('name', 'upload_allow_type')->update(['value' => implode(',', array_keys($upload_types))]);
} }
foreach ($post as $key => $val) { foreach ($post as $key => $val) {
if (in_array($key, $notAddFields)) continue; if (in_array($key, $notAddFields)) continue;
if ($this->model->where('name', $key)->count()) { if ($this->model->removeOption()->where('name', $key)->count()) {
$this->model->where('name', $key)->update(['value' => $val,]); $this->model->removeOption()->where('name', $key)->update(['value' => $val,]);
}else { }else {
$this->model->create( $this->model->create(
[ [
@@ -59,7 +59,7 @@ class Config extends AdminController
TriggerService::updateMenu(); TriggerService::updateMenu();
TriggerService::updateSysConfig(); TriggerService::updateSysConfig();
}catch (\Exception $e) { }catch (\Exception $e) {
$this->error('保存失败'); $this->error('保存失败' . $e->getMessage());
} }
$this->success('保存成功'); $this->success('保存成功');
} }

View File

@@ -34,7 +34,7 @@ class Log extends AdminController
} }
[$page, $limit, $where, $excludeFields] = $this->buildTableParams(['month']); [$page, $limit, $where, $excludeFields] = $this->buildTableParams(['month']);
$month = !empty($excludeFields['month']) ? date('Ym', strtotime($excludeFields['month'])) : date('Ym'); $month = !empty($excludeFields['month']) ? date('Ym', strtotime($excludeFields['month'])) : date('Ym');
$model = $this->model->setMonth($month)->with('admin')->where($where); $model = $this->model->setSuffix("_$month")->with('admin')->where($where);
try { try {
$count = $model->count(); $count = $model->count();
$list = $model->page($page, $limit)->order($this->sort)->select(); $list = $model->page($page, $limit)->order($this->sort)->select();
@@ -60,7 +60,8 @@ class Log extends AdminController
$this->error('演示环境下不允许操作'); $this->error('演示环境下不允许操作');
} }
[$page, $limit, $where, $excludeFields] = $this->buildTableParams(['month']); [$page, $limit, $where, $excludeFields] = $this->buildTableParams(['month']);
$tableName = $this->model->getName(); $month = !empty($excludeFields['month']) ? date('Ym', strtotime($excludeFields['month'])) : date('Ym');
$tableName = $this->model->setSuffix("_$month")->getName();
$tableName = CommonTool::humpToLine(lcfirst($tableName)); $tableName = CommonTool::humpToLine(lcfirst($tableName));
$prefix = config('database.connections.mysql.prefix'); $prefix = config('database.connections.mysql.prefix');
$dbList = Db::query("show full columns from {$prefix}{$tableName}"); $dbList = Db::query("show full columns from {$prefix}{$tableName}");
@@ -71,15 +72,18 @@ class Log extends AdminController
$header[] = [$comment, $vo['Field']]; $header[] = [$comment, $vo['Field']];
} }
} }
$month = !empty($excludeFields['month']) ? date('Ym', strtotime($excludeFields['month'])) : date('Ym'); $model = $this->model->setSuffix("_$month")->with('admin')->where($where);
$model = $this->model->setMonth($month)->with('admin')->where($where);
try { try {
$list = $model $list = $model
->where($where) ->where($where)
->limit(100000) ->limit(10000)
->order('id', 'desc') ->order('id', 'desc')
->select() ->select()
->toArray(); ->toArray();
foreach ($list as &$vo) {
$vo['content'] = json_encode($vo['content'], JSON_UNESCAPED_UNICODE);
$vo['response'] = json_encode($vo['response'], JSON_UNESCAPED_UNICODE);
}
}catch (PDOException|DbException $exception) { }catch (PDOException|DbException $exception) {
$this->error($exception->getMessage()); $this->error($exception->getMessage());
} }

View File

@@ -10,6 +10,9 @@ use app\admin\service\annotation\NodeAnnotation;
use app\admin\service\NodeService; use app\admin\service\NodeService;
use app\Request; use app\Request;
use think\App; use think\App;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\response\Json; use think\response\Json;
#[ControllerAnnotation(title: '系统节点管理')] #[ControllerAnnotation(title: '系统节点管理')]
@@ -55,11 +58,11 @@ class Node extends AdminController
try { try {
if ($force == 1) { if ($force == 1) {
$updateNodeList = $model->whereIn('node', array_column($nodeList, 'node'))->select(); $updateNodeList = $model->removeOption()->whereIn('node', array_column($nodeList, 'node'))->select();
$formatNodeList = array_format_key($nodeList, 'node'); $formatNodeList = array_format_key($nodeList, 'node');
foreach ($updateNodeList as $vo) { foreach ($updateNodeList as $vo) {
isset($formatNodeList[$vo['node']]) isset($formatNodeList[$vo['node']])
&& $model->where('id', $vo['id'])->update( && $model->removeOption()->where('id', $vo['id'])->update(
[ [
'title' => $formatNodeList[$vo['node']]['title'], 'title' => $formatNodeList[$vo['node']]['title'],
'is_auth' => $formatNodeList[$vo['node']]['is_auth'], 'is_auth' => $formatNodeList[$vo['node']]['is_auth'],
@@ -67,7 +70,7 @@ class Node extends AdminController
); );
} }
} }
$existNodeList = $model->field('node,title,type,is_auth')->select(); $existNodeList = $model->removeOption()->field('node,title,type,is_auth')->select();
foreach ($nodeList as $key => $vo) { foreach ($nodeList as $key => $vo) {
foreach ($existNodeList as $v) { foreach ($existNodeList as $v) {
if ($vo['node'] == $v->node) { if ($vo['node'] == $v->node) {
@@ -76,8 +79,10 @@ class Node extends AdminController
} }
} }
} }
$model->saveAll($nodeList); if (!empty($nodeList)) {
TriggerService::updateNode(); $model->saveAll($nodeList);
TriggerService::updateNode();
}
}catch (\Exception $e) { }catch (\Exception $e) {
$this->error('节点更新失败'); $this->error('节点更新失败');
} }

View File

@@ -8,6 +8,11 @@ use app\common\model\TimeModel;
class MallCate extends TimeModel class MallCate extends TimeModel
{ {
protected $deleteTime = 'delete_time'; protected function getOptions(): array
{
return [
'deleteTime' => 'delete_time',
];
}
} }

View File

@@ -8,10 +8,12 @@ use think\model\relation\HasOne;
class MallGoods extends TimeModel class MallGoods extends TimeModel
{ {
protected function getOptions(): array
protected $table = ""; {
return [
protected $deleteTime = 'delete_time'; 'deleteTime' => 'delete_time',
];
}
// * +++++++++++++++++++++++++++ // * +++++++++++++++++++++++++++
// | 以下两种写法适用于 with 关联 // | 以下两种写法适用于 with 关联

View File

@@ -8,7 +8,12 @@ use app\common\model\TimeModel;
class SystemAdmin extends TimeModel class SystemAdmin extends TimeModel
{ {
protected $deleteTime = 'delete_time'; protected function getOptions(): array
{
return [
'deleteTime' => 'delete_time',
];
}
public array $notes = [ public array $notes = [
'login_type' => [ 'login_type' => [
@@ -17,12 +22,15 @@ class SystemAdmin extends TimeModel
], ],
]; ];
public function getAuthList() public function getAuthIdsAttr($value): array
{ {
$list = (new SystemAuth()) if (!$value) return [];
->where('status', 1) return explode(',', $value);
->column('title', 'id'); }
return $list;
public function getAuthList(): array
{
return (new SystemAuth())->removeOption()->where('status', 1)->column('title', 'id');
} }
} }

View File

@@ -3,44 +3,52 @@
namespace app\admin\model; namespace app\admin\model;
use app\common\model\TimeModel; use app\common\model\TimeModel;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
class SystemAuth extends TimeModel class SystemAuth extends TimeModel
{ {
protected $deleteTime = 'delete_time'; protected function getOptions(): array
{
return [
'deleteTime' => 'delete_time',
];
}
/** /**
* 根据角色ID获取授权节点 * 根据角色ID获取授权节点
* @param $authId * @param $authId
* @return array * @return array
* @throws \think\db\exception\DataNotFoundException * @throws DataNotFoundException
* @throws \think\db\exception\DbException * @throws DbException
* @throws \think\db\exception\ModelNotFoundException * @throws ModelNotFoundException
*/ */
public function getAuthorizeNodeListByAdminId($authId) public function getAuthorizeNodeListByAdminId($authId): array
{ {
$checkNodeList = (new SystemAuthNode()) $checkNodeList = (new SystemAuthNode())
->where('auth_id', $authId) ->where('auth_id', $authId)
->column('node_id'); ->column('node_id');
$systemNode = new SystemNode(); $systemNode = new SystemNode();
$nodelList = $systemNode $nodeList = $systemNode
->where('is_auth', 1) ->where('is_auth', 1)
->field('id,node,title,type,is_auth') ->field('id,node,title,type,is_auth')
->select() ->select()
->toArray(); ->toArray();
$newNodeList = []; $newNodeList = [];
foreach ($nodelList as $vo) { foreach ($nodeList as $vo) {
if ($vo['type'] == 1) { if ($vo['type'] == 1) {
$vo = array_merge($vo, ['field' => 'node', 'spread' => true]); $vo = array_merge($vo, ['field' => 'node', 'spread' => true]);
$vo['checked'] = false; $vo['checked'] = false;
$vo['title'] = "{$vo['title']}{$vo['node']}"; $vo['title'] = "{$vo['title']}{$vo['node']}";
$children = []; $children = [];
foreach ($nodelList as $v) { foreach ($nodeList as $v) {
if ($v['type'] == 2 && strpos($v['node'], $vo['node'] . '/') !== false) { if ($v['type'] == 2 && strpos($v['node'], $vo['node'] . '/') !== false) {
$v = array_merge($v, ['field' => 'node', 'spread' => true]); $v = array_merge($v, ['field' => 'node', 'spread' => true]);
$v['checked'] = in_array($v['id'], $checkNodeList) ? true : false; $v['checked'] = in_array($v['id'], $checkNodeList) ? true : false;
$v['title'] = "{$v['title']}{$v['node']}"; $v['title'] = "{$v['title']}{$v['node']}";
$children[] = $v; $children[] = $v;
} }
} }
!empty($children) && $vo['children'] = $children; !empty($children) && $vo['children'] = $children;

View File

@@ -4,24 +4,23 @@ namespace app\admin\model;
use app\admin\service\SystemLogService; use app\admin\service\SystemLogService;
use app\common\model\TimeModel; use app\common\model\TimeModel;
use think\model\relation\BelongsTo;
class SystemLog extends TimeModel class SystemLog extends TimeModel
{ {
public function __construct(array $data = []) protected array $type = [
{ 'content' => 'json',
parent::__construct($data); 'response' => 'json',
$this->name = 'system_log_' . date('Ym'); ];
}
public function setMonth($month) protected function init(): void
{ {
SystemLogService::instance()->detectTable(); SystemLogService::instance()->detectTable();
$this->name = 'system_log_' . $month;
return $this;
} }
public function admin()
public function admin(): BelongsTo
{ {
return $this->belongsTo('app\admin\model\SystemAdmin', 'admin_id', 'id'); return $this->belongsTo('app\admin\model\SystemAdmin', 'admin_id', 'id');
} }

View File

@@ -4,31 +4,41 @@ namespace app\admin\model;
use app\common\constants\MenuConstant; use app\common\constants\MenuConstant;
use app\common\model\TimeModel; use app\common\model\TimeModel;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
class SystemMenu extends TimeModel class SystemMenu extends TimeModel
{ {
protected function getOptions(): array
protected $deleteTime = 'delete_time';
public function getPidMenuList()
{ {
$list = $this->field('id,pid,title') return [
->where([ 'deleteTime' => 'delete_time',
['pid', '<>', MenuConstant::HOME_PID], ];
['status', '=', 1], }
])
->select()
->toArray(); /**
* @throws ModelNotFoundException
* @throws DbException
* @throws DataNotFoundException
*/
public function getPidMenuList(): array
{
$list = $this->removeOption()->field('id,pid,title')->where([
['pid', '<>', MenuConstant::HOME_PID],
['status', '=', 1],
])->select()->toArray();
$pidMenuList = $this->buildPidMenu(0, $list); $pidMenuList = $this->buildPidMenu(0, $list);
$pidMenuList = array_merge([[ return array_merge([[
'id' => 0, 'id' => 0,
'pid' => 0, 'pid' => 0,
'title' => '顶级菜单', 'title' => '顶级菜单',
]], $pidMenuList); ]], $pidMenuList);
return $pidMenuList;
} }
protected function buildPidMenu($pid, $list, $level = 0) protected function buildPidMenu($pid, $list, $level = 0): array
{ {
$newList = []; $newList = [];
foreach ($list as $vo) { foreach ($list as $vo) {

View File

@@ -7,22 +7,21 @@ use app\common\model\TimeModel;
class SystemNode extends TimeModel class SystemNode extends TimeModel
{ {
public function getNodeTreeList() public function getNodeTreeList(): array
{ {
$list = $this->select()->toArray(); $list = $this->removeOption()->select()->toArray();
$list = $this->buildNodeTree($list); return $this->buildNodeTree($list);
return $list;
} }
protected function buildNodeTree($list) protected function buildNodeTree($list): array
{ {
$newList = []; $newList = [];
$repeatString = "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"; $repeatString = "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";
foreach ($list as $vo) { foreach ($list as $vo) {
if ($vo['type'] == 1) { if ($vo['type'] == 1) {
$newList[] = $vo; $newList[] = $vo;
foreach ($list as $v) { foreach ($list as $v) {
if ($v['type'] == 2 && strpos($v['node'], $vo['node'] . '/') !== false) { if ($v['type'] == 2 && str_contains($v['node'], $vo['node'] . '/')) {
$v['node'] = "{$repeatString}{$repeatString}" . $v['node']; $v['node'] = "{$repeatString}{$repeatString}" . $v['node'];
$newList[] = $v; $newList[] = $v;
} }

View File

@@ -7,6 +7,11 @@ use app\common\model\TimeModel;
class SystemQuick extends TimeModel class SystemQuick extends TimeModel
{ {
protected $deleteTime = 'delete_time'; protected function getOptions(): array
{
return [
'deleteTime' => 'delete_time',
];
}
} }

View File

@@ -151,12 +151,18 @@
<tr> <tr>
<td>DEBUG模式</td> <td>DEBUG模式</td>
<td> <td>
<button type="button" class="layui-btn layui-btn-xs {:env('APP_DEBUG')?'layui-btn-warm':'layui-bg-gray'}"> <button type="button" class="layui-btn layui-btn-xs {:env('APP_DEBUG')?'layui-bg-cyan':'layui-bg-gray'}">
{:env('APP_DEBUG')?'开启中':'已关闭'} {:env('APP_DEBUG')?'开启中':'已关闭'}
</button> </button>
<span class="layui-badge layui-bg-gray">建议线上环境关闭 APP_DEBUG</span> <span class="layui-badge layui-bg-gray">建议线上环境关闭 APP_DEBUG</span>
</td> </td>
</tr> </tr>
<tr>
<td>composer信息</td>
<td>
<button type="button" class="layui-btn layui-btn-xs layui-bg-cyan" lay-on="showComposerInfo">点击查看</button>
</td>
</tr>
<tr> <tr>
<td>主要特色</td> <td>主要特色</td>
<td> <td>

View File

@@ -1,22 +1,16 @@
<div class="layuimini-container"> <div class="layuimini-container">
<div class="layuimini-main" id="app"> <div class="layuimini-main" id="app">
<div class="layui-tab layui-tab-brief" lay-filter="docDemoTabBrief"> <div class="layui-tabs layui-tabs-card layui-panel " id="docDemoTabBrief">
<ul class="layui-tab-title"> <ul class="layui-tabs-header layui-bg-tint">
<li class="layui-this" data-group="site">网站设置</li> <li class="layui-this" data-group="site">网站设置</li>
<li data-group="logo">LOGO配置</li> <li data-group="logo">LOGO配置</li>
<li data-group="upload">上传配置</li> <li data-group="upload">上传配置</li>
</ul> </ul>
<div class="layui-tab-content"> <div class="layui-tabs-body">
<div class="layui-tab-item layui-show"> <div class="layui-tabs-item layui-show"> {include file="system/config/site" /}</div>
{include file="system/config/site" /} <div class="layui-tabs-item"> {include file="system/config/logo" /}</div>
</div> <div class="layui-tabs-item">{include file="system/config/upload" /}</div>
<div class="layui-tab-item">
{include file="system/config/logo" /}
</div>
<div class="layui-tab-item">
{include file="system/config/upload" /}
</div>
</div> </div>
</div> </div>

View File

@@ -100,21 +100,21 @@ if (!function_exists('auth')) {
$authService = new AuthService(session('admin.id')); $authService = new AuthService(session('admin.id'));
return $authService->checkNode($node); return $authService->checkNode($node);
} }
}
/** /**
* @param string|null $detail * @param string|null $detail
* @param string $name * @param string $name
* @param string $placeholder * @param string $placeholder
* @return string * @return string
*/ */
function editor_textarea(?string $detail, string $name = 'desc', string $placeholder = '请输入'): string function editor_textarea(?string $detail, string $name = 'desc', string $placeholder = '请输入'): string
{ {
$editor_type = sysConfig('site', 'editor_type'); $editor_type = sysConfig('site', 'editor_type');
return match ($editor_type) { return match ($editor_type) {
'ckeditor' => "<textarea name='{$name}' rows='20' class='layui-textarea editor' placeholder='{$placeholder}'>{$detail}</textarea>", 'ckeditor' => "<textarea name='{$name}' rows='20' class='layui-textarea editor' placeholder='{$placeholder}'>{$detail}</textarea>",
'ueditor' => "<script type='text/plain' id='{$name}' name='{$name}' class='editor' data-content='{$detail}'></script>", 'ueditor' => "<script type='text/plain' id='{$name}' name='{$name}' class='editor' data-content='{$detail}'></script>",
'EasyMDE' => "<textarea id='{$name}' class='editor' name='{$name}'>{$detail}</textarea>", 'EasyMDE' => "<textarea id='{$name}' class='editor' name='{$name}'>{$detail}</textarea>",
default => "<div class='wangEditor_div'><textarea name='{$name}' rows='20' class='layui-textarea editor layui-hide'>{$detail}</textarea><div id='editor_toolbar_{$name}'></div><div id='editor_{$name}' style='height: 300px'></div></div>", default => "<div class='wangEditor_div'><textarea name='{$name}' rows='20' class='layui-textarea editor layui-hide'>{$detail}</textarea><div id='editor_toolbar_{$name}'></div><div id='editor_{$name}' style='height: 300px'></div></div>",
}; };
} }
}

View File

@@ -13,28 +13,20 @@ use think\model\concern\SoftDelete;
class TimeModel extends Model class TimeModel extends Model
{ {
/**
* 自动时间戳类型
* @var string
*/
protected $autoWriteTimestamp = true;
/**
* 添加时间
* @var string
*/
protected $createTime = 'create_time';
/**
* 更新时间
* @var string
*/
protected $updateTime = 'update_time';
/** /**
* 软删除 * 软删除
*/ */
use SoftDelete; use SoftDelete;
protected $deleteTime = false;
protected function getOptions(): array
{
return [
'autoWriteTimestamp' => true,
'createTime' => 'create_time',
'updateTime' => 'update_time',
'deleteTime' => false,
];
}
} }

View File

@@ -27,7 +27,7 @@
"topthink/think-view": "^2.0", "topthink/think-view": "^2.0",
"topthink/think-captcha": "^3.0", "topthink/think-captcha": "^3.0",
"topthink/think-filesystem": "^2.0", "topthink/think-filesystem": "^2.0",
"aliyuncs/oss-sdk-php": "^2.6", "aliyuncs/oss-sdk-php": "^2.7.2",
"qcloud/cos-sdk-v5": "^2.6", "qcloud/cos-sdk-v5": "^2.6",
"jianyan74/php-excel": "^1.0.2", "jianyan74/php-excel": "^1.0.2",
"doctrine/annotations": "^2.0.0", "doctrine/annotations": "^2.0.0",

View File

@@ -571,3 +571,22 @@ INSERT INTO `ea_system_uploadfile`
VALUES ('290', 'oss', 'image/jpeg', 'https://lxn-99php.oss-cn-shenzhen.aliyuncs.com/upload/20191111/2c412adf1b30c8be3a913e603c7b6e4a.jpg', '', '', '', '0', 'image/jpeg', '0', 'jpg', '', 1573612437, null, null); VALUES ('290', 'oss', 'image/jpeg', 'https://lxn-99php.oss-cn-shenzhen.aliyuncs.com/upload/20191111/2c412adf1b30c8be3a913e603c7b6e4a.jpg', '', '', '', '0', 'image/jpeg', '0', 'jpg', '', 1573612437, null, null);
INSERT INTO `ea_system_uploadfile` INSERT INTO `ea_system_uploadfile`
VALUES ('296', 'cos', 'image/jpeg', 'https://easyadmin-1251997243.cos.ap-guangzhou.myqcloud.com/upload/20191114/2381eaf81208ac188fa994b6f2579953.jpg', '', '', '', '0', 'image/jpeg', '0', 'jpg', '', 1573612437, null, null); VALUES ('296', 'cos', 'image/jpeg', 'https://easyadmin-1251997243.cos.ap-guangzhou.myqcloud.com/upload/20191114/2381eaf81208ac188fa994b6f2579953.jpg', '', '', '', '0', 'image/jpeg', '0', 'jpg', '', 1573612437, null, null);
-- ----------------------------
-- Table structure for ea_system_log
-- ----------------------------
DROP TABLE IF EXISTS `ea_system_log`;
CREATE TABLE `ea_system_log`
(
`id` int unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID',
`admin_id` int unsigned DEFAULT '0' COMMENT '管理员ID',
`url` varchar(1500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '操作页面',
`method` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '请求方法',
`title` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '日志标题',
`content` json NOT NULL COMMENT '请求数据',
`response` json DEFAULT NULL COMMENT '回调数据',
`ip` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT 'IP',
`useragent` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT 'User-Agent',
`create_time` int DEFAULT NULL COMMENT '操作时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=COMPACT COMMENT='后台操作日志表 - 202412';

View File

@@ -140,6 +140,38 @@ define(["jquery", "easy-admin", "echarts", "echarts-theme", "miniAdmin", "miniTh
echartsRecords.resize(); echartsRecords.resize();
}); });
}) })
let util = layui.util;
util.on({
showComposerInfo: function () {
// <div style="padding: 25px;">12313</div>
let html = ``
ea.request.post({
url: ea.url('ajax/composerInfo'),
}, function (success) {
let data = success.data
data.forEach(function (item) {
html += `${item.name} ${item.version}\r\n`
})
html = `<pre class="layui-code code-demo">${html}</pre>`
layer.open({
type: 1,
title: 'composer 信息',
area: ['50%', '90%'],
shade: 0.8,
shadeClose: true,
content: html,
success: function () {
layui.code({elem: '.code-demo', theme: 'dark', lang: 'php'});
}
})
}, function (error) {
console.error(error)
return false;
})
}
})
}, },
editAdmin: function () { editAdmin: function () {
let form = layui.form let form = layui.form

View File

@@ -1,15 +1,15 @@
define(["jquery", "easy-admin", "vue"], function ($, ea, Vue) { define(["jquery", "easy-admin"], function ($, ea) {
var form = layui.form; var form = layui.form;
return { return {
index: function () { index: function () {
var _group = 'site' var _group = 'site'
var element = layui.element; let tabs = layui.tabs
element.on('tab(docDemoTabBrief)', function (data) { var TABS_ID = 'docDemoTabBrief';
tabs.on(`afterChange(${TABS_ID})`, function (data) {
_group = $(this).data('group') _group = $(this).data('group')
}); })
let _upload_type = upload_type || 'local' let _upload_type = upload_type || 'local'
$('.upload_type').addClass('layui-hide') $('.upload_type').addClass('layui-hide')
$('.' + _upload_type).removeClass('layui-hide') $('.' + _upload_type).removeClass('layui-hide')
@@ -20,12 +20,15 @@ define(["jquery", "easy-admin", "vue"], function ($, ea, Vue) {
$('.' + _upload_type).removeClass('layui-hide') $('.' + _upload_type).removeClass('layui-hide')
}); });
form.on("submit", function (data) { form.on("submit", function (data) {
data.field['group'] = _group data.field['group'] = _group
}); });
ea.listen(); ea.listen('', function (res) {
ea.msg.success(res.msg);
}, function (err) {
ea.msg.error(err.msg);
});
} }
}; };
}); });

View File

@@ -51,7 +51,7 @@ define(["jquery", "easy-admin"], function ($, ea) {
field: 'content', minWidth: 200, title: '请求数据', align: "left", templet: function (res) { field: 'content', minWidth: 200, title: '请求数据', align: "left", templet: function (res) {
let html = '<div class="layui-colla-item">' + let html = '<div class="layui-colla-item">' +
'<div class="layui-colla-title">点击预览</div>' + '<div class="layui-colla-title">点击预览</div>' +
'<div class="layui-colla-content">' + prettyFormat(res.content) + '</div>' + '<div class="layui-colla-content">' + prettyFormat(JSON.stringify(res.content)) + '</div>' +
'</div>' '</div>'
return '<div class="layui-collapse" lay-accordion>' + html + '</div>' return '<div class="layui-collapse" lay-accordion>' + html + '</div>'
} }
@@ -60,7 +60,7 @@ define(["jquery", "easy-admin"], function ($, ea) {
field: 'response', minWidth: 200, title: '回调数据', align: "left", templet: function (res) { field: 'response', minWidth: 200, title: '回调数据', align: "left", templet: function (res) {
let html = '<div class="layui-colla-item">' + let html = '<div class="layui-colla-item">' +
'<div class="layui-colla-title">点击预览</div>' + '<div class="layui-colla-title">点击预览</div>' +
'<div class="layui-colla-content">' + prettyFormat(res.response) + '</div>' + '<div class="layui-colla-content">' + prettyFormat(JSON.stringify(res.response)) + '</div>' +
'</div>' '</div>'
return '<div class="layui-collapse" lay-accordion>' + html + '</div>' return '<div class="layui-collapse" lay-accordion>' + html + '</div>'
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

View File

@@ -22,6 +22,7 @@ require.config({
"vue": ["plugs/vue-2.6.10/vue.min"], "vue": ["plugs/vue-2.6.10/vue.min"],
"swiper": ["plugs/swiper/swiper-bundle.min"], "swiper": ["plugs/swiper/swiper-bundle.min"],
"colorMode": ["plugs/colorMode/colorMode"], "colorMode": ["plugs/colorMode/colorMode"],
"lazyload": ["plugs/lazyload/lazyload.min"],
} }
}); });

View File

@@ -1,4 +1,4 @@
define(["jquery", "tableSelect", "miniTheme", "xmSelect"], function ($, tableSelect, miniTheme, xmSelect) { define(["jquery", "tableSelect", "miniTheme", "xmSelect", "lazyload"], function ($, tableSelect, miniTheme, xmSelect, lazyload) {
//切换日夜模式 //切换日夜模式
window.onInitElemStyle = function () { window.onInitElemStyle = function () {
@@ -748,8 +748,11 @@ define(["jquery", "tableSelect", "miniTheme", "xmSelect"], function ($, tableSel
var values = value.split(option.imageSplit), var values = value.split(option.imageSplit),
valuesHtml = []; valuesHtml = [];
values.forEach((value, index) => { values.forEach((value, index) => {
valuesHtml.push('<img style="max-width: ' + option.imageWidth + 'px; max-height: ' + option.imageHeight + 'px;" src="' + value + '" data-image="' + title + '">'); valuesHtml.push('<img style="max-width: ' + option.imageWidth + 'px; max-height: ' + option.imageHeight + 'px;" class="lazyload" src="/static/common/images/loading.gif" data-src="' + value + '" data-image="' + title + '">');
}); });
$(function () {
$("img.lazyload").lazyload({threshold: 1});
})
return valuesHtml.join(option.imageJoin); return valuesHtml.join(option.imageJoin);
} }
}, },
@@ -1593,7 +1596,7 @@ define(["jquery", "tableSelect", "miniTheme", "xmSelect"], function ($, tableSel
cols: [[ cols: [[
{type: selectCheck}, {type: selectCheck},
{field: 'id', title: 'ID'}, {field: 'id', title: 'ID'},
{field: 'url', minWidth: 80, search: false, title: '图片信息', imageHeight: 40, align: "center", templet: admin.table.image}, {field: 'url', minWidth: 80, search: false, title: '图片信息', imageHeight: 30, align: "center", templet: admin.table.image},
{field: 'original_name', width: 150, title: '文件原名', align: "center"}, {field: 'original_name', width: 150, title: '文件原名', align: "center"},
{field: 'mime_type', width: 120, title: 'mime类型', align: "center"}, {field: 'mime_type', width: 120, title: 'mime类型', align: "center"},
{field: 'create_time', width: 200, title: '创建时间', align: "center", search: 'range'}, {field: 'create_time', width: 200, title: '创建时间', align: "center", search: 'range'},

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,2 @@
/*! Lazy Load 2.0.0-rc.2 - MIT license - Copyright 2007-2019 Mika Tuupola */
!function(t,e){"object"==typeof exports?module.exports=e(t):"function"==typeof define&&define.amd?define([],e):t.LazyLoad=e(t)}("undefined"!=typeof global?global:this.window||this.global,function(t){"use strict";function e(t,e){this.settings=s(r,e||{}),this.images=t||document.querySelectorAll(this.settings.selector),this.observer=null,this.init()}"function"==typeof define&&define.amd&&(t=window);const r={src:"data-src",srcset:"data-srcset",selector:".lazyload",root:null,rootMargin:"0px",threshold:0},s=function(){let t={},e=!1,r=0,o=arguments.length;"[object Boolean]"===Object.prototype.toString.call(arguments[0])&&(e=arguments[0],r++);for(;r<o;r++)!function(r){for(let o in r)Object.prototype.hasOwnProperty.call(r,o)&&(e&&"[object Object]"===Object.prototype.toString.call(r[o])?t[o]=s(!0,t[o],r[o]):t[o]=r[o])}(arguments[r]);return t};if(e.prototype={init:function(){if(!t.IntersectionObserver)return void this.loadImages();let e=this,r={root:this.settings.root,rootMargin:this.settings.rootMargin,threshold:[this.settings.threshold]};this.observer=new IntersectionObserver(function(t){Array.prototype.forEach.call(t,function(t){if(t.isIntersecting){e.observer.unobserve(t.target);let r=t.target.getAttribute(e.settings.src),s=t.target.getAttribute(e.settings.srcset);"img"===t.target.tagName.toLowerCase()?(r&&(t.target.src=r),s&&(t.target.srcset=s)):t.target.style.backgroundImage="url("+r+")"}})},r),Array.prototype.forEach.call(this.images,function(t){e.observer.observe(t)})},loadAndDestroy:function(){this.settings&&(this.loadImages(),this.destroy())},loadImages:function(){if(!this.settings)return;let t=this;Array.prototype.forEach.call(this.images,function(e){let r=e.getAttribute(t.settings.src),s=e.getAttribute(t.settings.srcset);"img"===e.tagName.toLowerCase()?(r&&(e.src=r),s&&(e.srcset=s)):e.style.backgroundImage="url('"+r+"')"})},destroy:function(){this.settings&&(this.observer.disconnect(),this.settings=null)}},t.lazyload=function(t,r){return new e(t,r)},t.jQuery){const r=t.jQuery;r.fn.lazyload=function(t){return t=t||{},t.attribute=t.attribute||"data-src",new e(r.makeArray(this),t),this}}return e});