Compare commits
63 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
150e0ecd23 | ||
|
|
e9ed0cd8f6 | ||
|
|
187d4343b3 | ||
|
|
9bc0185b6b | ||
|
|
652b17d6a6 | ||
|
|
ed8c3d545b | ||
|
|
12b38c7bf5 | ||
|
|
fc202be987 | ||
|
|
71e069712a | ||
|
|
ca4080d5e6 | ||
|
|
4bbe287626 | ||
|
|
e316cd40e0 | ||
|
|
a7a3ddef8b | ||
|
|
51f2cbc0f4 | ||
|
|
8acf9f3f6c | ||
|
|
d7b23f305d | ||
|
|
fdfe2a542a | ||
|
|
3d412d9ec6 | ||
|
|
f75ebffa5d | ||
|
|
77881a27ed | ||
|
|
07e11a1c45 | ||
|
|
8531ec89ad | ||
|
|
ff2e842c24 | ||
|
|
3d767643c8 | ||
|
|
08fb6ef4d0 | ||
|
|
32d94bb3e0 | ||
|
|
d93483d9bf | ||
|
|
973e9cb24c | ||
|
|
b510042323 | ||
|
|
b55dd8f67a | ||
|
|
8e488fb46c | ||
|
|
d99e168583 | ||
|
|
d6bb1456fa | ||
|
|
91eac36371 | ||
|
|
1e4486989a | ||
|
|
f9f25b76dd | ||
|
|
7603cdfa7e | ||
|
|
2e0cc85966 | ||
|
|
5814fed0da | ||
|
|
40f7ee82cd | ||
|
|
936cb56c7f | ||
|
|
2d1940522c | ||
|
|
264cf56ae4 | ||
|
|
57ea9a3f47 | ||
|
|
31c06cff69 | ||
|
|
4c8d21fccf | ||
|
|
817582bed5 | ||
|
|
3a0c0c1624 | ||
|
|
30c7615e53 | ||
|
|
9d58da3cc3 | ||
|
|
1f5ca39226 | ||
|
|
82f17301a7 | ||
|
|
4ef7879ae3 | ||
|
|
0c9b369e2e | ||
|
|
e981852422 | ||
|
|
1d258621c8 | ||
|
|
9534f2c2fe | ||
|
|
9fb8dd022a | ||
|
|
fc264630ec | ||
|
|
3d19c8d337 | ||
|
|
4baa4e185d | ||
|
|
88bc6441e5 | ||
|
|
0efb70b3b7 |
13
.example.env
13
.example.env
@@ -1,5 +1,8 @@
|
||||
APP_DEBUG=true
|
||||
|
||||
# 后台系统日志开关
|
||||
APP_ADMIN_SYSTEM_LOG=true
|
||||
|
||||
DEFAULT_TIMEZONE=Asia/Shanghai
|
||||
|
||||
DB_TYPE=mysql
|
||||
@@ -11,6 +14,16 @@ DB_PORT=3306
|
||||
DB_CHARSET=utf8mb4
|
||||
DB_PREFIX=ea8_
|
||||
|
||||
# 限流器开关 若启动需要配置 Redis 服务
|
||||
RATE_LIMITING_STATUS=false
|
||||
|
||||
# Redis配置
|
||||
REDIS_HOST=127.0.0.1
|
||||
REDIS_PORT=6379
|
||||
REDIS_PASSWORD=
|
||||
REDIS_PREFIX=
|
||||
REDIS_DATABASE=0
|
||||
|
||||
# 后台配置项组
|
||||
[EASYADMIN]
|
||||
|
||||
|
||||
12
README.md
12
README.md
@@ -1,8 +1,8 @@
|
||||
<div align="center" dir="auto">
|
||||
<img alt="log" src="/public/static/common/images/logo-8.png" />
|
||||
<img alt="log" src="public/static/common/images/logo-8.png" />
|
||||
|
||||
<p>
|
||||
<img src="https://img.shields.io/badge/php-%3E=8.0.0-brightgreen.svg?style=for-the-badge&logo=php&colorB=ff69b4" alt="php">
|
||||
<img src="https://img.shields.io/badge/php-%3E=8.1.0-brightgreen.svg?style=for-the-badge&logo=php&colorB=ff69b4" alt="php">
|
||||
<img src="https://img.shields.io/badge/mysql-%3E=5.7-brightgreen.svg?style=for-the-badge&logo=mysql&colorB=blue" alt="MySQL">
|
||||
<img src="https://img.shields.io/badge/thinkphp-%3E=8.0.0-brightgreen.svg?style=for-the-badge&logo=thinkphp" alt="ThinkPHP">
|
||||
<img src="https://img.shields.io/badge/layui-%3E=2.9.0-brightgreen.svg?style=for-the-badge&logo=layui&colorB=orange" alt="layui">
|
||||
@@ -21,9 +21,11 @@
|
||||
|
||||
## 项目介绍
|
||||
|
||||
> `EasyAdmin8` 在 [`EasyAdmin`](https://gitee.com/zhongshaofa/easyadmin) 的基础上更新 ThinkPHP 框架到 8.0 ,PHP 最低版本要求不低于 8.0
|
||||
> `EasyAdmin8` 在 [`EasyAdmin`](https://gitee.com/zhongshaofa/easyadmin) 的基础上更新 ThinkPHP 框架到 8.1+ ,PHP 最低版本要求不低于 8.1
|
||||
>
|
||||
> 2025年起 `PHP` 版本要求提升到 `8.1+`, 如果需要 `8.0` 到分支 `v8.0` 中下载
|
||||
>
|
||||
> ThinkPHP v8.0 和 Layui v2.9.x 的快速开发的后台管理系统。
|
||||
> ThinkPHP v8.1+ 和 Layui v2.9.x 的快速开发的后台管理系统。
|
||||
>
|
||||
> 项目地址:[http://easyadmin8.top](http://easyadmin8.top)
|
||||
>
|
||||
@@ -58,7 +60,7 @@ if [ -f /usr/bin/curl ];then curl -sSO https://easyadmin8.top/auto-install-EasyA
|
||||
|
||||
git clone https://gitee.com/EasyAdmin8/EasyAdmin8
|
||||
|
||||
2.安装依赖包(确保 PHP 版本 >= 8.0)
|
||||
2.安装依赖包(确保 PHP 版本 >= 8.1)
|
||||
|
||||
在根目录下 composer install ,如果有报错信息可以使用命令 composer install --ignore-platform-reqs
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ use app\admin\middleware\CheckInstall;
|
||||
use app\admin\middleware\CheckLogin;
|
||||
use app\admin\middleware\CheckAuth;
|
||||
use app\admin\middleware\SystemLog;
|
||||
use app\admin\middleware\RateLimiting;
|
||||
|
||||
// 你可以在这里继续写你需要的路由
|
||||
|
||||
@@ -16,6 +17,8 @@ use app\admin\middleware\SystemLog;
|
||||
|
||||
return [
|
||||
'middleware' => [
|
||||
// 限流中间件
|
||||
RateLimiting::class,
|
||||
// 判断是否已经安装后台系统
|
||||
CheckInstall::class,
|
||||
// 检测是否登录
|
||||
|
||||
@@ -213,4 +213,23 @@ class Ajax extends AdminController
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -4,17 +4,19 @@ namespace app\admin\controller;
|
||||
|
||||
use app\admin\model\SystemAdmin;
|
||||
use app\common\controller\AdminController;
|
||||
use app\common\utils\Helper;
|
||||
use think\captcha\facade\Captcha;
|
||||
use think\db\exception\DataNotFoundException;
|
||||
use think\db\exception\DbException;
|
||||
use think\db\exception\ModelNotFoundException;
|
||||
use app\Request;
|
||||
use think\Response;
|
||||
use Wolfcode\RateLimiting\Attributes\RateLimitingMiddleware;
|
||||
|
||||
class Login extends AdminController
|
||||
{
|
||||
|
||||
protected bool $ignoreAuth = true;
|
||||
protected bool $ignoreLogin = true;
|
||||
|
||||
public function initialize(): void
|
||||
{
|
||||
@@ -34,6 +36,7 @@ class Login extends AdminController
|
||||
* @throws DbException
|
||||
* @throws ModelNotFoundException
|
||||
*/
|
||||
#[RateLimitingMiddleware(key: [Helper::class, 'getIp'], seconds: 1, limit: 1, message: '请求过于频繁')]
|
||||
public function index(Request $request): string
|
||||
{
|
||||
$captcha = env('EASYADMIN.CAPTCHA', 1);
|
||||
|
||||
@@ -8,11 +8,7 @@ use app\admin\service\annotation\ControllerAnnotation;
|
||||
use app\admin\service\annotation\NodeAnnotation;
|
||||
use think\App;
|
||||
|
||||
/**
|
||||
* Class Admin
|
||||
* @package app\admin\controller\system
|
||||
* @ControllerAnnotation(title="商品分类管理")
|
||||
*/
|
||||
#[ControllerAnnotation(title: '商品分类管理')]
|
||||
class Cate extends AdminController
|
||||
{
|
||||
|
||||
|
||||
@@ -4,27 +4,22 @@ namespace app\admin\controller\mall;
|
||||
|
||||
use app\admin\model\MallCate;
|
||||
use app\admin\model\MallGoods;
|
||||
use app\admin\service\annotation\MiddlewareAnnotation;
|
||||
use app\common\controller\AdminController;
|
||||
use app\admin\service\annotation\ControllerAnnotation;
|
||||
use app\admin\service\annotation\NodeAnnotation;
|
||||
use app\Request;
|
||||
use think\App;
|
||||
use think\db\exception\DbException;
|
||||
use think\response\Json;
|
||||
use Wolfcode\Ai\Enum\AiType;
|
||||
use Wolfcode\Ai\Service\AiChatService;
|
||||
|
||||
/**
|
||||
* Class Goods
|
||||
* @package app\admin\controller\mall
|
||||
* @ControllerAnnotation(title="商城商品管理")
|
||||
*/
|
||||
#[ControllerAnnotation(title: '商城商品管理')]
|
||||
class Goods extends AdminController
|
||||
{
|
||||
|
||||
/**
|
||||
* 过滤不需要生成的权限节点 默认 CURD 中会自动生成部分节点 可以在此处过滤
|
||||
* @var array[]
|
||||
*/
|
||||
protected array $ignoreNode = ['export'];
|
||||
#[NodeAnnotation(ignore: ['export'])] // 过滤不需要生成的权限节点 默认 CURD 中会自动生成部分节点 可以在此处过滤
|
||||
protected array $ignoreNode;
|
||||
|
||||
public function __construct(App $app)
|
||||
{
|
||||
@@ -33,10 +28,7 @@ class Goods extends AdminController
|
||||
$this->assign('cate', (new MallCate())->column('title', 'id'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @NodeAnnotation(title="列表")
|
||||
* @throws DbException
|
||||
*/
|
||||
#[NodeAnnotation(title: '列表', auth: true)]
|
||||
public function index(Request $request): Json|string
|
||||
{
|
||||
if ($request->isAjax()) {
|
||||
@@ -55,9 +47,7 @@ class Goods extends AdminController
|
||||
return $this->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* @NodeAnnotation(title="入库")
|
||||
*/
|
||||
#[NodeAnnotation(title: '入库', auth: true)]
|
||||
public function stock(Request $request, $id): string
|
||||
{
|
||||
$row = $this->model->find($id);
|
||||
@@ -79,4 +69,67 @@ class Goods extends AdminController
|
||||
return $this->fetch();
|
||||
}
|
||||
|
||||
#[MiddlewareAnnotation(ignore: MiddlewareAnnotation::IGNORE_LOGIN)]
|
||||
public function no_check_login(Request $request): string
|
||||
{
|
||||
return '这里演示方法不需要经过登录验证';
|
||||
}
|
||||
|
||||
|
||||
#[NodeAnnotation(title: 'AI优化', auth: true)]
|
||||
public function aiOptimization(Request $request): void
|
||||
{
|
||||
$message = $request->post('message');
|
||||
if (empty($message)) $this->error('请输入内容');
|
||||
|
||||
// 演示环境下 默认返回的内容
|
||||
if ($this->isDemo) {
|
||||
$content = <<<EOF
|
||||
演示环境中 默认返回的内容
|
||||
|
||||
我来帮你优化这个标题,让它更有吸引力且更符合电商平台的搜索逻辑:
|
||||
|
||||
"商务男士高端定制马克杯 | 办公室精英必备 | 优质陶瓷防烫手柄"
|
||||
|
||||
这个优化后的标题:
|
||||
1. 突出了目标用户群体(商务男士)
|
||||
2. 强调了产品定位(高端定制)
|
||||
3. 点明了使用场景(办公室)
|
||||
4. 添加了材质和功能特点(优质陶瓷、防烫手柄)
|
||||
5. 使用了吸引人的关键词(精英必备)
|
||||
|
||||
这样的标题不仅更具体,也更容易被搜索引擎识别,同时能精准触达目标客户群。您觉得这个版本如何?
|
||||
EOF;
|
||||
$choices = [['message' => [
|
||||
'role' => 'assistant',
|
||||
'content' => $content,
|
||||
]]];
|
||||
$this->success('success', compact('choices'));
|
||||
}
|
||||
|
||||
try {
|
||||
$result = AiChatService::instance()
|
||||
// 当使用推理模型时,可能存在超时的情况,所以需要设置超时时间为 0
|
||||
// ->setTimeLimit(0)
|
||||
// 请替换为您需要的模型类型
|
||||
->setAiType(AiType::QWEN)
|
||||
// 如果需要指定模型的 API 地址,可自行设置
|
||||
// ->setAiUrl('https://xxx.com')
|
||||
// 请替换为您的模型
|
||||
->setAiModel('qwen-plus')
|
||||
// 请替换为您的 API KEY
|
||||
->setAiKey('sk-1234567890')
|
||||
// 此内容会作为系统提示,会影响到回答的内容 当前仅作为测试使用
|
||||
->setSystemContent('你现在是一位资深的海外电商产品经理')
|
||||
->chat($message);
|
||||
$choices = $result['choices'];
|
||||
}catch (\Throwable $exception) {
|
||||
$choices = [['message' => [
|
||||
'role' => 'assistant',
|
||||
'content' => $exception->getMessage(),
|
||||
]]];
|
||||
}
|
||||
$this->success('success', compact('choices'));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -10,14 +10,9 @@ use app\admin\service\annotation\ControllerAnnotation;
|
||||
use app\admin\service\annotation\NodeAnnotation;
|
||||
use app\Request;
|
||||
use think\App;
|
||||
use think\db\exception\DbException;
|
||||
use think\response\Json;
|
||||
|
||||
/**
|
||||
* Class Admin
|
||||
* @package app\admin\controller\system
|
||||
* @ControllerAnnotation(title="管理员管理")
|
||||
*/
|
||||
#[ControllerAnnotation(title: '管理员管理')]
|
||||
class Admin extends AdminController
|
||||
{
|
||||
|
||||
@@ -33,10 +28,7 @@ class Admin extends AdminController
|
||||
$this->assign('auth_list', $this->model->getAuthList());
|
||||
}
|
||||
|
||||
/**
|
||||
* @NodeAnnotation(title="列表")
|
||||
* @throws DbException
|
||||
*/
|
||||
#[NodeAnnotation(title: '列表', auth: true)]
|
||||
public function index(Request $request): Json|string
|
||||
{
|
||||
if ($request->isAjax()) {
|
||||
@@ -64,9 +56,7 @@ class Admin extends AdminController
|
||||
return $this->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* @NodeAnnotation(title="添加")
|
||||
*/
|
||||
#[NodeAnnotation(title: '添加', auth: true)]
|
||||
public function add(Request $request): string
|
||||
{
|
||||
if ($request->isPost()) {
|
||||
@@ -80,16 +70,14 @@ class Admin extends AdminController
|
||||
try {
|
||||
$save = $this->model->save($post);
|
||||
}catch (\Exception $e) {
|
||||
$this->error('保存失败');
|
||||
$this->error('保存失败' . $e->getMessage());
|
||||
}
|
||||
$save ? $this->success('保存成功') : $this->error('保存失败');
|
||||
}
|
||||
return $this->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* @NodeAnnotation(title="编辑")
|
||||
*/
|
||||
#[NodeAnnotation(title: '编辑', auth: true)]
|
||||
public function edit(Request $request, $id = 0): string
|
||||
{
|
||||
$row = $this->model->find($id);
|
||||
@@ -100,25 +88,19 @@ class Admin extends AdminController
|
||||
$post['auth_ids'] = implode(',', array_keys($authIds));
|
||||
$rule = [];
|
||||
$this->validate($post, $rule);
|
||||
if (isset($row['password'])) {
|
||||
unset($row['password']);
|
||||
}
|
||||
try {
|
||||
$save = $row->save($post);
|
||||
TriggerService::updateMenu($id);
|
||||
}catch (\Exception $e) {
|
||||
$this->error('保存失败');
|
||||
$this->error('保存失败' . $e->getMessage());
|
||||
}
|
||||
$save ? $this->success('保存成功') : $this->error('保存失败');
|
||||
}
|
||||
$row->auth_ids = explode(',', $row->auth_ids ?: '');
|
||||
$this->assign('row', $row);
|
||||
return $this->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* @NodeAnnotation(title="编辑")
|
||||
*/
|
||||
#[NodeAnnotation(title: '设置密码', auth: true)]
|
||||
public function password(Request $request, $id): string
|
||||
{
|
||||
$row = $this->model->find($id);
|
||||
@@ -147,9 +129,7 @@ class Admin extends AdminController
|
||||
return $this->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* @NodeAnnotation(title="删除")
|
||||
*/
|
||||
#[NodeAnnotation(title: '删除', auth: true)]
|
||||
public function delete(Request $request): void
|
||||
{
|
||||
$this->checkPostRequest();
|
||||
@@ -170,9 +150,7 @@ class Admin extends AdminController
|
||||
$save ? $this->success('删除成功') : $this->error('删除失败');
|
||||
}
|
||||
|
||||
/**
|
||||
* @NodeAnnotation(title="属性修改")
|
||||
*/
|
||||
#[NodeAnnotation(title: '属性修改', auth: true)]
|
||||
public function modify(Request $request): void
|
||||
{
|
||||
$this->checkPostRequest();
|
||||
|
||||
@@ -11,11 +11,7 @@ use app\admin\service\annotation\NodeAnnotation;
|
||||
use app\Request;
|
||||
use think\App;
|
||||
|
||||
/**
|
||||
* @ControllerAnnotation(title="角色权限管理")
|
||||
* Class Auth
|
||||
* @package app\admin\controller\system
|
||||
*/
|
||||
#[ControllerAnnotation(title: '角色权限管理', auth: true)]
|
||||
class Auth extends AdminController
|
||||
{
|
||||
|
||||
@@ -30,9 +26,7 @@ class Auth extends AdminController
|
||||
$this->model = new SystemAuth();
|
||||
}
|
||||
|
||||
/**
|
||||
* @NodeAnnotation(title="授权")
|
||||
*/
|
||||
#[NodeAnnotation(title: '授权', auth: true)]
|
||||
public function authorize(Request $request, $id): string
|
||||
{
|
||||
$row = $this->model->find($id);
|
||||
@@ -45,9 +39,7 @@ class Auth extends AdminController
|
||||
return $this->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* @NodeAnnotation(title="授权保存")
|
||||
*/
|
||||
#[NodeAnnotation(title: '授权保存', auth: true)]
|
||||
public function saveAuthorize(Request $request): void
|
||||
{
|
||||
$this->checkPostRequest();
|
||||
|
||||
@@ -9,14 +9,9 @@ use app\admin\service\annotation\ControllerAnnotation;
|
||||
use app\admin\service\annotation\NodeAnnotation;
|
||||
use app\Request;
|
||||
use think\App;
|
||||
use think\facade\Cache;
|
||||
use think\response\Json;
|
||||
|
||||
/**
|
||||
* Class Config
|
||||
* @package app\admin\controller\system
|
||||
* @ControllerAnnotation(title="系统配置管理")
|
||||
*/
|
||||
#[ControllerAnnotation(title: '系统配置管理')]
|
||||
class Config extends AdminController
|
||||
{
|
||||
|
||||
@@ -28,17 +23,13 @@ class Config extends AdminController
|
||||
$this->assign('editor_types', config('admin.editor_types'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @NodeAnnotation(title="列表")
|
||||
*/
|
||||
#[NodeAnnotation(title: '列表', auth: true)]
|
||||
public function index(Request $request): Json|string
|
||||
{
|
||||
return $this->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* @NodeAnnotation(title="保存")
|
||||
*/
|
||||
#[NodeAnnotation(title: '保存', auth: true)]
|
||||
public function save(Request $request): void
|
||||
{
|
||||
$this->checkPostRequest();
|
||||
@@ -50,12 +41,12 @@ class Config extends AdminController
|
||||
if ($group == 'upload') {
|
||||
$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) {
|
||||
if (in_array($key, $notAddFields)) continue;
|
||||
if ($this->model->where('name', $key)->count()) {
|
||||
$this->model->where('name', $key)->update(['value' => $val,]);
|
||||
if ($this->model->removeOption()->where('name', $key)->count()) {
|
||||
$this->model->removeOption()->where('name', $key)->update(['value' => $val,]);
|
||||
}else {
|
||||
$this->model->create(
|
||||
[
|
||||
@@ -68,7 +59,7 @@ class Config extends AdminController
|
||||
TriggerService::updateMenu();
|
||||
TriggerService::updateSysConfig();
|
||||
}catch (\Exception $e) {
|
||||
$this->error('保存失败');
|
||||
$this->error('保存失败' . $e->getMessage());
|
||||
}
|
||||
$this->success('保存成功');
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
namespace app\admin\controller\system;
|
||||
|
||||
use app\admin\service\curd\BuildCurd;
|
||||
use app\admin\service\curd\exceptions\TableException;
|
||||
use app\common\controller\AdminController;
|
||||
use app\admin\service\annotation\ControllerAnnotation;
|
||||
use app\admin\service\annotation\NodeAnnotation;
|
||||
@@ -15,24 +14,16 @@ use think\facade\Db;
|
||||
use think\helper\Str;
|
||||
use think\response\Json;
|
||||
|
||||
/**
|
||||
* @ControllerAnnotation(title="CURD可视化管理")
|
||||
* @package app\admin\controller\system
|
||||
*/
|
||||
#[ControllerAnnotation(title: 'CURD可视化管理')]
|
||||
class CurdGenerate extends AdminController
|
||||
{
|
||||
/**
|
||||
* @NodeAnnotation(title="列表")
|
||||
*/
|
||||
#[NodeAnnotation(title: '列表', auth: true)]
|
||||
public function index(Request $request): Json|string
|
||||
{
|
||||
return $this->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* @NodeAnnotation(title="操作")
|
||||
* @throws TableException
|
||||
*/
|
||||
#[NodeAnnotation(title: '操作', auth: true)]
|
||||
public function save(Request $request, string $type = ''): ?Json
|
||||
{
|
||||
if (!$request->isAjax()) $this->error();
|
||||
@@ -146,6 +137,7 @@ class CurdGenerate extends AdminController
|
||||
$command = $request->post('command', '');
|
||||
if (empty($command)) $this->error('请输入命令');
|
||||
$commandExp = explode(' ', $command);
|
||||
$commandExp = array_values(array_filter($commandExp));
|
||||
try {
|
||||
|
||||
$output = Console::call('curd', [...$commandExp]);
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
namespace app\admin\controller\system;
|
||||
|
||||
use app\admin\model\SystemLog;
|
||||
use app\admin\service\annotation\MiddlewareAnnotation;
|
||||
use app\admin\service\tool\CommonTool;
|
||||
use app\common\controller\AdminController;
|
||||
use app\admin\service\annotation\ControllerAnnotation;
|
||||
@@ -15,24 +16,16 @@ use think\db\exception\PDOException;
|
||||
use think\facade\Db;
|
||||
use think\response\Json;
|
||||
|
||||
/**
|
||||
* @ControllerAnnotation(title="操作日志管理")
|
||||
* Class Auth
|
||||
* @package app\admin\controller\system
|
||||
*/
|
||||
#[ControllerAnnotation(title: '操作日志管理')]
|
||||
class Log extends AdminController
|
||||
{
|
||||
protected array $ignoreLog = ['record'];
|
||||
|
||||
public function __construct(App $app)
|
||||
{
|
||||
parent::__construct($app);
|
||||
$this->model = new SystemLog();
|
||||
}
|
||||
|
||||
/**
|
||||
* @NodeAnnotation(title="列表")
|
||||
*/
|
||||
#[NodeAnnotation(title: '列表', auth: true)]
|
||||
public function index(Request $request): Json|string
|
||||
{
|
||||
if ($request->isAjax()) {
|
||||
@@ -41,7 +34,7 @@ class Log extends AdminController
|
||||
}
|
||||
[$page, $limit, $where, $excludeFields] = $this->buildTableParams(['month']);
|
||||
$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 {
|
||||
$count = $model->count();
|
||||
$list = $model->page($page, $limit)->order($this->sort)->select();
|
||||
@@ -60,16 +53,15 @@ class Log extends AdminController
|
||||
return $this->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* @NodeAnnotation(title="导出")
|
||||
*/
|
||||
#[NodeAnnotation(title: '导出', auth: true)]
|
||||
public function export(): bool
|
||||
{
|
||||
if (env('EASYADMIN.IS_DEMO', false)) {
|
||||
$this->error('演示环境下不允许操作');
|
||||
}
|
||||
[$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));
|
||||
$prefix = config('database.connections.mysql.prefix');
|
||||
$dbList = Db::query("show full columns from {$prefix}{$tableName}");
|
||||
@@ -80,15 +72,18 @@ class Log extends AdminController
|
||||
$header[] = [$comment, $vo['Field']];
|
||||
}
|
||||
}
|
||||
$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 {
|
||||
$list = $model
|
||||
->where($where)
|
||||
->limit(100000)
|
||||
->limit(10000)
|
||||
->order('id', 'desc')
|
||||
->select()
|
||||
->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) {
|
||||
$this->error($exception->getMessage());
|
||||
}
|
||||
@@ -96,9 +91,47 @@ class Log extends AdminController
|
||||
return Excel::exportData($list, $header, $fileName, 'xlsx');
|
||||
}
|
||||
|
||||
/**
|
||||
* @NodeAnnotation(title="框架日志")
|
||||
*/
|
||||
|
||||
#[NodeAnnotation(title: '删除指定日志', auth: true)]
|
||||
public function deleteMonthLog(Request $request)
|
||||
{
|
||||
if (!$request->isAjax()) {
|
||||
return $this->fetch();
|
||||
}
|
||||
|
||||
if ($this->isDemo) $this->error('演示环境下不允许操作');
|
||||
|
||||
$monthsAgo = $request->param('month/d', 0);
|
||||
if ($monthsAgo < 1) $this->error('月份错误');
|
||||
|
||||
$currentDate = new \DateTime();
|
||||
$currentDate->modify("-$monthsAgo months");
|
||||
|
||||
$dbPrefix = env('DB_PREFIX');
|
||||
$dbLike = "{$dbPrefix}system_log_";
|
||||
$tables = Db::query("SHOW TABLES LIKE '$dbLike%'");
|
||||
$threshold = date('Ym', strtotime("-$monthsAgo month"));
|
||||
$tableNames = [];
|
||||
try {
|
||||
foreach ($tables as $table) {
|
||||
$tableName = current($table);
|
||||
if (!preg_match("/^$dbLike\d{6}$/", $tableName)) continue;
|
||||
$datePart = substr($tableName, -6);
|
||||
$issetTable = Db::query("SHOW TABLES LIKE '$tableName'");
|
||||
if (!$issetTable) continue;
|
||||
if ($datePart - $threshold <= 0) {
|
||||
Db::execute("DROP TABLE `$tableName`");
|
||||
$tableNames[] = $tableName;
|
||||
}
|
||||
}
|
||||
}catch (PDOException) {
|
||||
}
|
||||
if (empty($tableNames)) $this->error('没有需要删除的表');
|
||||
$this->success('操作成功 - 共删除 ' . count($tableNames) . ' 张表<br/>' . implode('<br>', $tableNames));
|
||||
}
|
||||
|
||||
#[MiddlewareAnnotation(ignore: MiddlewareAnnotation::IGNORE_LOG)]
|
||||
#[NodeAnnotation(title: '框架日志', auth: true, ignore: NodeAnnotation::IGNORE_NODE)]
|
||||
public function record(): Json|string
|
||||
{
|
||||
return (new \Wolfcode\PhpLogviewer\thinkphp\LogViewer())->fetch();
|
||||
|
||||
@@ -11,14 +11,9 @@ use app\admin\service\annotation\NodeAnnotation;
|
||||
use app\common\controller\AdminController;
|
||||
use app\Request;
|
||||
use think\App;
|
||||
use think\db\exception\DbException;
|
||||
use think\response\Json;
|
||||
|
||||
/**
|
||||
* Class Menu
|
||||
* @package app\admin\controller\system
|
||||
* @ControllerAnnotation(title="菜单管理",auth=true)
|
||||
*/
|
||||
#[ControllerAnnotation(title: '菜单管理')]
|
||||
class Menu extends AdminController
|
||||
{
|
||||
|
||||
@@ -33,10 +28,7 @@ class Menu extends AdminController
|
||||
$this->model = new SystemMenu();
|
||||
}
|
||||
|
||||
/**
|
||||
* @NodeAnnotation(title="列表")
|
||||
* @throws DbException
|
||||
*/
|
||||
#[NodeAnnotation(title: '列表', auth: true)]
|
||||
public function index(Request $request): Json|string
|
||||
{
|
||||
if ($request->isAjax()) {
|
||||
@@ -56,9 +48,7 @@ class Menu extends AdminController
|
||||
return $this->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* @NodeAnnotation(title="添加")
|
||||
*/
|
||||
#[NodeAnnotation(title: '添加', auth: true)]
|
||||
public function add(Request $request): string
|
||||
{
|
||||
$id = $request->param('id');
|
||||
@@ -92,9 +82,7 @@ class Menu extends AdminController
|
||||
return $this->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* @NodeAnnotation(title="编辑")
|
||||
*/
|
||||
#[NodeAnnotation(title: '编辑', auth: true)]
|
||||
public function edit(Request $request, $id = 0): string
|
||||
{
|
||||
$row = $this->model->find($id);
|
||||
@@ -129,9 +117,7 @@ class Menu extends AdminController
|
||||
return $this->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* @NodeAnnotation(title="删除")
|
||||
*/
|
||||
#[NodeAnnotation(title: '删除', auth: true)]
|
||||
public function delete(Request $request): void
|
||||
{
|
||||
$this->checkPostRequest();
|
||||
@@ -151,9 +137,7 @@ class Menu extends AdminController
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @NodeAnnotation(title="属性修改")
|
||||
*/
|
||||
#[NodeAnnotation(title: '属性修改', auth: true)]
|
||||
public function modify(Request $request): void
|
||||
{
|
||||
$this->checkPostRequest();
|
||||
@@ -190,9 +174,7 @@ class Menu extends AdminController
|
||||
$this->success('保存成功');
|
||||
}
|
||||
|
||||
/**
|
||||
* @NodeAnnotation(title="添加菜单提示")
|
||||
*/
|
||||
#[NodeAnnotation(title: '添加菜单提示', auth: true)]
|
||||
public function getMenuTips(): Json
|
||||
{
|
||||
$node = input('get.keywords');
|
||||
|
||||
@@ -10,14 +10,12 @@ use app\admin\service\annotation\NodeAnnotation;
|
||||
use app\admin\service\NodeService;
|
||||
use app\Request;
|
||||
use think\App;
|
||||
use think\db\exception\DataNotFoundException;
|
||||
use think\db\exception\DbException;
|
||||
use think\db\exception\ModelNotFoundException;
|
||||
use think\response\Json;
|
||||
|
||||
/**
|
||||
* @ControllerAnnotation(title="系统节点管理")
|
||||
* Class Node
|
||||
* @package app\admin\controller\system
|
||||
*/
|
||||
#[ControllerAnnotation(title: '系统节点管理')]
|
||||
class Node extends AdminController
|
||||
{
|
||||
|
||||
@@ -27,10 +25,7 @@ class Node extends AdminController
|
||||
$this->model = new SystemNode();
|
||||
}
|
||||
|
||||
/**
|
||||
* @NodeAnnotation(title="列表")
|
||||
* @throws DbException
|
||||
*/
|
||||
#[NodeAnnotation(title: '列表', auth: true)]
|
||||
public function index(Request $request): Json|string
|
||||
{
|
||||
if ($request->isAjax()) {
|
||||
@@ -52,9 +47,7 @@ class Node extends AdminController
|
||||
return $this->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* @NodeAnnotation(title="系统节点更新")
|
||||
*/
|
||||
#[NodeAnnotation(title: '系统节点更新', auth: true)]
|
||||
public function refreshNode($force = 0): void
|
||||
{
|
||||
|
||||
@@ -65,11 +58,11 @@ class Node extends AdminController
|
||||
|
||||
try {
|
||||
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');
|
||||
foreach ($updateNodeList as $vo) {
|
||||
isset($formatNodeList[$vo['node']])
|
||||
&& $model->where('id', $vo['id'])->update(
|
||||
&& $model->removeOption()->where('id', $vo['id'])->update(
|
||||
[
|
||||
'title' => $formatNodeList[$vo['node']]['title'],
|
||||
'is_auth' => $formatNodeList[$vo['node']]['is_auth'],
|
||||
@@ -77,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 ($existNodeList as $v) {
|
||||
if ($vo['node'] == $v->node) {
|
||||
@@ -86,17 +79,17 @@ class Node extends AdminController
|
||||
}
|
||||
}
|
||||
}
|
||||
$model->saveAll($nodeList);
|
||||
TriggerService::updateNode();
|
||||
if (!empty($nodeList)) {
|
||||
$model->saveAll($nodeList);
|
||||
TriggerService::updateNode();
|
||||
}
|
||||
}catch (\Exception $e) {
|
||||
$this->error('节点更新失败');
|
||||
}
|
||||
$this->success('节点更新成功');
|
||||
}
|
||||
|
||||
/**
|
||||
* @NodeAnnotation(title="清除失效节点")
|
||||
*/
|
||||
#[NodeAnnotation(title: '清除失效节点', auth: true)]
|
||||
public function clearNode(): void
|
||||
{
|
||||
$this->checkPostRequest();
|
||||
|
||||
@@ -9,11 +9,7 @@ use app\admin\service\annotation\ControllerAnnotation;
|
||||
use app\admin\service\annotation\NodeAnnotation;
|
||||
use think\App;
|
||||
|
||||
/**
|
||||
* @ControllerAnnotation(title="快捷入口管理")
|
||||
* Class Quick
|
||||
* @package app\admin\controller\system
|
||||
*/
|
||||
#[ControllerAnnotation(title: '快捷入口管理')]
|
||||
class Quick extends AdminController
|
||||
{
|
||||
|
||||
|
||||
@@ -8,10 +8,7 @@ use app\admin\service\annotation\ControllerAnnotation;
|
||||
use app\admin\service\annotation\NodeAnnotation;
|
||||
use think\App;
|
||||
|
||||
/**
|
||||
* @ControllerAnnotation(title="上传文件管理")
|
||||
* @package app\admin\controller\system
|
||||
*/
|
||||
#[ControllerAnnotation(title: '上传文件管理')]
|
||||
class Uploadfile extends AdminController
|
||||
{
|
||||
|
||||
|
||||
0
app/admin/entity/.keep
Normal file
0
app/admin/entity/.keep
Normal file
12
app/admin/entity/Test.php
Normal file
12
app/admin/entity/Test.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\entity;
|
||||
|
||||
use app\common\entity\BaseEntity;
|
||||
|
||||
/**
|
||||
* ThinkORM 4.0 实体模型案例
|
||||
* 可与 Model 并存 或者 单独使用
|
||||
* @package app\admin\entity
|
||||
*/
|
||||
class Test extends BaseEntity {}
|
||||
@@ -35,7 +35,7 @@ class CheckAuth
|
||||
!$check && $this->error('无权限访问');
|
||||
// 判断是否为演示环境
|
||||
if (env('EASYADMIN.IS_DEMO', false) && $request->isPost()) {
|
||||
if (!in_array($currentNode, ['system.log/record', ''])) $this->error('演示环境下不允许修改');
|
||||
if (!in_array($currentNode, ['system.log/record', 'mall.goods/aiOptimization'])) $this->error('演示环境下不允许修改');
|
||||
}
|
||||
}
|
||||
return $next($request);
|
||||
|
||||
@@ -7,6 +7,7 @@ use app\Request;
|
||||
use Closure;
|
||||
use ReflectionClass;
|
||||
use ReflectionException;
|
||||
use app\admin\service\annotation\MiddlewareAnnotation;
|
||||
|
||||
class CheckLogin
|
||||
{
|
||||
@@ -24,13 +25,25 @@ class CheckLogin
|
||||
$controllerClass = 'app\\admin\\controller\\' . $controller;
|
||||
$classObj = new ReflectionClass($controllerClass);
|
||||
$properties = $classObj->getDefaultProperties();
|
||||
$ignoreAuth = $properties['ignoreAuth'] ?? false;
|
||||
$adminUserInfo = session('admin');
|
||||
if (!$ignoreAuth) {
|
||||
// 整个控制器是否忽略登录
|
||||
$ignoreLogin = $properties['ignoreLogin'] ?? false;
|
||||
$adminUserInfo = session('admin');
|
||||
if (!$ignoreLogin) {
|
||||
$noNeedCheck = $properties['noNeedCheck'] ?? [];
|
||||
if (in_array($action, $noNeedCheck)) {
|
||||
return $next($request);
|
||||
}
|
||||
try {
|
||||
$reflectionMethod = new \ReflectionMethod($controllerClass, $action);
|
||||
$attributes = $reflectionMethod->getAttributes(MiddlewareAnnotation::class);
|
||||
foreach ($attributes as $attribute) {
|
||||
$annotation = $attribute->newInstance();
|
||||
$_ignore = (array)$annotation->ignore;
|
||||
// 控制器中的某个方法忽略登录
|
||||
if (in_array('LOGIN', $_ignore)) return $next($request);
|
||||
}
|
||||
}catch (\Throwable) {
|
||||
}
|
||||
if (empty($adminUserInfo)) {
|
||||
return redirect(__url('login/index'));
|
||||
}
|
||||
|
||||
45
app/admin/middleware/RateLimiting.php
Normal file
45
app/admin/middleware/RateLimiting.php
Normal file
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\middleware;
|
||||
|
||||
use app\common\traits\JumpTrait;
|
||||
use app\Request;
|
||||
use Closure;
|
||||
use Wolfcode\RateLimiting\Bootstrap;
|
||||
|
||||
class RateLimiting
|
||||
{
|
||||
use JumpTrait;
|
||||
|
||||
/**
|
||||
* 启用限流器需要开启Redis
|
||||
* @param Request $request
|
||||
* @param Closure $next
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle(Request $request, Closure $next): mixed
|
||||
{
|
||||
// 是否启用限流器
|
||||
if (!env('RATE_LIMITING_STATUS', false)) return $next($request);
|
||||
if ($request->method() == 'GET') return $next($request);
|
||||
$controller = $request->controller();
|
||||
$module = app('http')->getName();
|
||||
$appNamespace = config('app.app_namespace');
|
||||
$controllerClass = "app\\{$module}\\controller\\{$controller}{$appNamespace}";
|
||||
$controllerClass = str_replace('.', '\\', $controllerClass);
|
||||
$action = $request->action();
|
||||
try {
|
||||
Bootstrap::init($controllerClass, $action, [
|
||||
# Redis 相关配置
|
||||
'host' => env('REDIS_HOST', '127.0.0.1'),
|
||||
'port' => (int)env('REDIS_PORT', 6379),
|
||||
'password' => env('REDIS_PASSWORD', ''),
|
||||
'prefix' => env('REDIS_PREFIX', ''),
|
||||
'database' => (int)env('REDIS_DATABASE', 0),
|
||||
]);
|
||||
}catch (\Throwable $exception) {
|
||||
$this->error($exception->getMessage());
|
||||
}
|
||||
return $next($request);
|
||||
}
|
||||
}
|
||||
@@ -3,14 +3,12 @@
|
||||
namespace app\admin\middleware;
|
||||
|
||||
use app\admin\service\annotation\ControllerAnnotation;
|
||||
use app\admin\service\annotation\MiddlewareAnnotation;
|
||||
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
|
||||
@@ -34,7 +32,8 @@ class SystemLog
|
||||
public function handle(Request $request, Closure $next)
|
||||
{
|
||||
$response = $next($request);
|
||||
$params = $request->param();
|
||||
if (!env('APP_ADMIN_SYSTEM_LOG', true)) return $response;
|
||||
$params = $request->param();
|
||||
if (isset($params['s'])) unset($params['s']);
|
||||
foreach ($params as $key => $val) {
|
||||
in_array($key, $this->sensitiveParams) && $params[$key] = "***********";
|
||||
@@ -58,17 +57,25 @@ class SystemLog
|
||||
$_controller = ucfirst($pathInfoExp[1] ?? '');
|
||||
$className = $_controller ? "app\admin\controller\\{$_name}\\{$_controller}" : "app\admin\controller\\{$_name}";
|
||||
if ($_name && $_action) {
|
||||
$reflectionClass = new \ReflectionClass($className);
|
||||
$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);
|
||||
$reflectionAction = $reflectionClass->getMethod($_action);
|
||||
$nodeAnnotation = $reader->getMethodAnnotation($reflectionAction, NodeAnnotation::class);
|
||||
$title = $controllerAnnotation->title . ' - ' . $nodeAnnotation->title;
|
||||
$reflectionMethod = new \ReflectionMethod($className, $_action);
|
||||
$attributes = $reflectionMethod->getAttributes(MiddlewareAnnotation::class);
|
||||
foreach ($attributes as $attribute) {
|
||||
$annotation = $attribute->newInstance();
|
||||
$_ignore = (array)$annotation->ignore;
|
||||
if (in_array('log', array_map('strtolower', $_ignore))) return $response;
|
||||
}
|
||||
$controllerTitle = $nodeTitle = '';
|
||||
$controllerAttributes = (new \ReflectionClass($className))->getAttributes(ControllerAnnotation::class);
|
||||
$actionAttributes = $reflectionMethod->getAttributes(NodeAnnotation::class);
|
||||
foreach ($controllerAttributes as $controllerAttribute) {
|
||||
$controllerAnnotation = $controllerAttribute->newInstance();
|
||||
$controllerTitle = $controllerAnnotation->title ?? '';
|
||||
}
|
||||
foreach ($actionAttributes as $actionAttribute) {
|
||||
$actionAnnotation = $actionAttribute->newInstance();
|
||||
$nodeTitle = $actionAnnotation->title ?? '';
|
||||
}
|
||||
$title = $controllerTitle . ' - ' . $nodeTitle;
|
||||
}
|
||||
}catch (\Throwable $exception) {
|
||||
}
|
||||
|
||||
@@ -8,6 +8,11 @@ use app\common\model\TimeModel;
|
||||
class MallCate extends TimeModel
|
||||
{
|
||||
|
||||
protected $deleteTime = 'delete_time';
|
||||
protected function getOptions(): array
|
||||
{
|
||||
return [
|
||||
'deleteTime' => 'delete_time',
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
@@ -8,10 +8,12 @@ use think\model\relation\HasOne;
|
||||
|
||||
class MallGoods extends TimeModel
|
||||
{
|
||||
|
||||
protected $table = "";
|
||||
|
||||
protected $deleteTime = 'delete_time';
|
||||
protected function getOptions(): array
|
||||
{
|
||||
return [
|
||||
'deleteTime' => 'delete_time',
|
||||
];
|
||||
}
|
||||
|
||||
// * +++++++++++++++++++++++++++
|
||||
// | 以下两种写法适用于 with 关联
|
||||
|
||||
@@ -8,7 +8,12 @@ use app\common\model\TimeModel;
|
||||
class SystemAdmin extends TimeModel
|
||||
{
|
||||
|
||||
protected $deleteTime = 'delete_time';
|
||||
protected function getOptions(): array
|
||||
{
|
||||
return [
|
||||
'deleteTime' => 'delete_time',
|
||||
];
|
||||
}
|
||||
|
||||
public array $notes = [
|
||||
'login_type' => [
|
||||
@@ -17,12 +22,15 @@ class SystemAdmin extends TimeModel
|
||||
],
|
||||
];
|
||||
|
||||
public function getAuthList()
|
||||
public function getAuthIdsAttr($value): array
|
||||
{
|
||||
$list = (new SystemAuth())
|
||||
->where('status', 1)
|
||||
->column('title', 'id');
|
||||
return $list;
|
||||
if (!$value) return [];
|
||||
return explode(',', $value);
|
||||
}
|
||||
|
||||
public function getAuthList(): array
|
||||
{
|
||||
return (new SystemAuth())->removeOption()->where('status', 1)->column('title', 'id');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -3,44 +3,52 @@
|
||||
namespace app\admin\model;
|
||||
|
||||
use app\common\model\TimeModel;
|
||||
use think\db\exception\DataNotFoundException;
|
||||
use think\db\exception\DbException;
|
||||
use think\db\exception\ModelNotFoundException;
|
||||
|
||||
class SystemAuth extends TimeModel
|
||||
{
|
||||
|
||||
protected $deleteTime = 'delete_time';
|
||||
protected function getOptions(): array
|
||||
{
|
||||
return [
|
||||
'deleteTime' => 'delete_time',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据角色ID获取授权节点
|
||||
* @param $authId
|
||||
* @return array
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @throws DataNotFoundException
|
||||
* @throws DbException
|
||||
* @throws ModelNotFoundException
|
||||
*/
|
||||
public function getAuthorizeNodeListByAdminId($authId)
|
||||
public function getAuthorizeNodeListByAdminId($authId): array
|
||||
{
|
||||
$checkNodeList = (new SystemAuthNode())
|
||||
->where('auth_id', $authId)
|
||||
->column('node_id');
|
||||
$systemNode = new SystemNode();
|
||||
$nodelList = $systemNode
|
||||
$systemNode = new SystemNode();
|
||||
$nodeList = $systemNode
|
||||
->where('is_auth', 1)
|
||||
->field('id,node,title,type,is_auth')
|
||||
->select()
|
||||
->toArray();
|
||||
$newNodeList = [];
|
||||
foreach ($nodelList as $vo) {
|
||||
$newNodeList = [];
|
||||
foreach ($nodeList as $vo) {
|
||||
if ($vo['type'] == 1) {
|
||||
$vo = array_merge($vo, ['field' => 'node', 'spread' => true]);
|
||||
$vo = array_merge($vo, ['field' => 'node', 'spread' => true]);
|
||||
$vo['checked'] = false;
|
||||
$vo['title'] = "{$vo['title']}【{$vo['node']}】";
|
||||
$children = [];
|
||||
foreach ($nodelList as $v) {
|
||||
$vo['title'] = "{$vo['title']}【{$vo['node']}】";
|
||||
$children = [];
|
||||
foreach ($nodeList as $v) {
|
||||
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['title'] = "{$v['title']}【{$v['node']}】";
|
||||
$children[] = $v;
|
||||
$v['title'] = "{$v['title']}【{$v['node']}】";
|
||||
$children[] = $v;
|
||||
}
|
||||
}
|
||||
!empty($children) && $vo['children'] = $children;
|
||||
|
||||
@@ -4,24 +4,23 @@ namespace app\admin\model;
|
||||
|
||||
use app\admin\service\SystemLogService;
|
||||
use app\common\model\TimeModel;
|
||||
use think\model\relation\BelongsTo;
|
||||
|
||||
class SystemLog extends TimeModel
|
||||
{
|
||||
|
||||
public function __construct(array $data = [])
|
||||
{
|
||||
parent::__construct($data);
|
||||
$this->name = 'system_log_' . date('Ym');
|
||||
}
|
||||
protected array $type = [
|
||||
'content' => 'json',
|
||||
'response' => 'json',
|
||||
];
|
||||
|
||||
public function setMonth($month)
|
||||
protected function init(): void
|
||||
{
|
||||
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');
|
||||
}
|
||||
|
||||
@@ -4,31 +4,41 @@ namespace app\admin\model;
|
||||
|
||||
use app\common\constants\MenuConstant;
|
||||
use app\common\model\TimeModel;
|
||||
use think\db\exception\DataNotFoundException;
|
||||
use think\db\exception\DbException;
|
||||
use think\db\exception\ModelNotFoundException;
|
||||
|
||||
class SystemMenu extends TimeModel
|
||||
{
|
||||
|
||||
protected $deleteTime = 'delete_time';
|
||||
|
||||
public function getPidMenuList()
|
||||
protected function getOptions(): array
|
||||
{
|
||||
$list = $this->field('id,pid,title')
|
||||
->where([
|
||||
['pid', '<>', MenuConstant::HOME_PID],
|
||||
['status', '=', 1],
|
||||
])
|
||||
->select()
|
||||
->toArray();
|
||||
return [
|
||||
'deleteTime' => 'delete_time',
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @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 = array_merge([[
|
||||
return array_merge([[
|
||||
'id' => 0,
|
||||
'pid' => 0,
|
||||
'title' => '顶级菜单',
|
||||
]], $pidMenuList);
|
||||
return $pidMenuList;
|
||||
}
|
||||
|
||||
protected function buildPidMenu($pid, $list, $level = 0)
|
||||
protected function buildPidMenu($pid, $list, $level = 0): array
|
||||
{
|
||||
$newList = [];
|
||||
foreach ($list as $vo) {
|
||||
|
||||
@@ -7,22 +7,21 @@ use app\common\model\TimeModel;
|
||||
class SystemNode extends TimeModel
|
||||
{
|
||||
|
||||
public function getNodeTreeList()
|
||||
public function getNodeTreeList(): array
|
||||
{
|
||||
$list = $this->select()->toArray();
|
||||
$list = $this->buildNodeTree($list);
|
||||
return $list;
|
||||
$list = $this->removeOption()->select()->toArray();
|
||||
return $this->buildNodeTree($list);
|
||||
}
|
||||
|
||||
protected function buildNodeTree($list)
|
||||
protected function buildNodeTree($list): array
|
||||
{
|
||||
$newList = [];
|
||||
$newList = [];
|
||||
$repeatString = " ";
|
||||
foreach ($list as $vo) {
|
||||
if ($vo['type'] == 1) {
|
||||
$newList[] = $vo;
|
||||
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'];
|
||||
$newList[] = $v;
|
||||
}
|
||||
|
||||
@@ -7,6 +7,11 @@ use app\common\model\TimeModel;
|
||||
class SystemQuick extends TimeModel
|
||||
{
|
||||
|
||||
protected $deleteTime = 'delete_time';
|
||||
protected function getOptions(): array
|
||||
{
|
||||
return [
|
||||
'deleteTime' => 'delete_time',
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,38 +2,20 @@
|
||||
|
||||
namespace app\admin\service\annotation;
|
||||
|
||||
use Doctrine\Common\Annotations\Annotation\Attributes;
|
||||
use Doctrine\Common\Annotations\Annotation\Required;
|
||||
use Doctrine\Common\Annotations\Annotation\Target;
|
||||
use Attribute;
|
||||
|
||||
/**
|
||||
* Class ControllerAnnotation
|
||||
*
|
||||
* @Annotation
|
||||
* @Target("CLASS")
|
||||
* @Attributes({
|
||||
* @Attribute("title", type="string"),
|
||||
* })
|
||||
*
|
||||
* @since 2.0
|
||||
* controller 节点注解类
|
||||
*/
|
||||
#[Attribute]
|
||||
final class ControllerAnnotation
|
||||
{
|
||||
|
||||
/**
|
||||
* Route group prefix for the controller
|
||||
*
|
||||
* @Required()
|
||||
*
|
||||
* @var string
|
||||
* @param string $title
|
||||
* @param bool $auth 是否需要权限
|
||||
* @param string|array $ignore
|
||||
*/
|
||||
public $title = '';
|
||||
|
||||
/**
|
||||
* 是否开启权限控制
|
||||
* @Enum({true,false})
|
||||
* @var bool
|
||||
*/
|
||||
public $auth = true;
|
||||
|
||||
public function __construct(public string $title = '', public bool $auth = true, public string|array $ignore = '')
|
||||
{
|
||||
}
|
||||
}
|
||||
19
app/admin/service/annotation/MiddlewareAnnotation.php
Normal file
19
app/admin/service/annotation/MiddlewareAnnotation.php
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\service\annotation;
|
||||
|
||||
use Attribute;
|
||||
|
||||
#[Attribute(Attribute::IS_REPEATABLE | Attribute::TARGET_METHOD)]
|
||||
final class MiddlewareAnnotation
|
||||
{
|
||||
/** 过滤日志 */
|
||||
const IGNORE_LOG = 'LOG';
|
||||
|
||||
/** 免登录 */
|
||||
const IGNORE_LOGIN = 'LOGIN';
|
||||
|
||||
public function __construct(public string $type = '', public string|array $ignore = '')
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -2,32 +2,24 @@
|
||||
|
||||
namespace app\admin\service\annotation;
|
||||
|
||||
use Doctrine\Common\Annotations\Annotation\Attributes;
|
||||
use Attribute;
|
||||
|
||||
/**
|
||||
* 创建节点注解类
|
||||
*
|
||||
* @Annotation
|
||||
* @Target({"METHOD","CLASS"})
|
||||
* @Attributes({
|
||||
* @Attribute("time", type = "int")
|
||||
* })
|
||||
* action 节点注解类
|
||||
*/
|
||||
#[Attribute(Attribute::IS_REPEATABLE | Attribute::TARGET_METHOD| Attribute::TARGET_PROPERTY)]
|
||||
final class NodeAnnotation
|
||||
{
|
||||
/** 过滤节点 */
|
||||
const IGNORE_NODE = 'NODE';
|
||||
|
||||
/**
|
||||
* 节点名称
|
||||
* @Required()
|
||||
* @var string
|
||||
* @param string $title
|
||||
* @param bool $auth 是否需要权限
|
||||
* @param string|array $ignore
|
||||
*/
|
||||
public string $title;
|
||||
|
||||
/**
|
||||
* 是否开启权限控制
|
||||
* @Enum({true,false})
|
||||
* @var bool
|
||||
*/
|
||||
public bool $auth = true;
|
||||
public function __construct(public string $title = '', public bool $auth = true, public string|array $ignore = '')
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
@@ -68,20 +68,22 @@ class Node
|
||||
// 遍历读取所有方法的注释的参数信息
|
||||
foreach ($methods as $method) {
|
||||
|
||||
// 忽略的节点
|
||||
$properties = $reflectionClass->getDefaultProperties();
|
||||
$ignoreNode = $properties['ignoreNode'] ?? [];
|
||||
if (!empty($ignoreNode)) if (in_array($method->name, $ignoreNode)) continue;
|
||||
// 忽略掉不需要的节点
|
||||
$property = $reflectionClass->getProperty('ignoreNode');
|
||||
$propertyAttributes = $property->getAttributes(NodeAnnotation::class);
|
||||
if (!empty($propertyAttributes[0])) {
|
||||
$propertyAttribute = $propertyAttributes[0]->newInstance();
|
||||
if (in_array($method->name, $propertyAttribute->ignore)) continue;
|
||||
}
|
||||
|
||||
// 读取NodeAnnotation的注解
|
||||
$nodeAnnotation = $reader->getMethodAnnotation($method, NodeAnnotation::class);
|
||||
if (!empty($nodeAnnotation)) {
|
||||
$actionTitle = !empty($nodeAnnotation->title) ? $nodeAnnotation->title : null;
|
||||
$actionAuth = !empty($nodeAnnotation->auth) ? $nodeAnnotation->auth : false;
|
||||
$attributes = $reflectionClass->getMethod($method->name)->getAttributes(NodeAnnotation::class);
|
||||
foreach ($attributes as $attribute) {
|
||||
$annotation = $attribute->newInstance();
|
||||
if (!empty($annotation->ignore)) if (strtolower($annotation->ignore) == 'node') continue;
|
||||
$actionList[] = [
|
||||
'node' => $controllerFormat . '/' . $method->name,
|
||||
'title' => $actionTitle,
|
||||
'is_auth' => $actionAuth,
|
||||
'title' => $annotation->title ?? null,
|
||||
'is_auth' => $annotation->auth ?? false,
|
||||
'type' => 2,
|
||||
];
|
||||
}
|
||||
@@ -89,16 +91,17 @@ class Node
|
||||
// 方法非空才读取控制器注解
|
||||
if (!empty($actionList)) {
|
||||
// 读取Controller的注解
|
||||
$controllerAnnotation = $reader->getClassAnnotation($reflectionClass, ControllerAnnotation::class);
|
||||
$controllerTitle = !empty($controllerAnnotation->title) ? $controllerAnnotation->title : null;
|
||||
$controllerAuth = !empty($controllerAnnotation->auth) ? $controllerAnnotation->auth : false;
|
||||
$nodeList[] = [
|
||||
'node' => $controllerFormat,
|
||||
'title' => $controllerTitle,
|
||||
'is_auth' => $controllerAuth,
|
||||
'type' => 1,
|
||||
];
|
||||
$nodeList = array_merge($nodeList, $actionList);
|
||||
$attributes = $reflectionClass->getAttributes(ControllerAnnotation::class);
|
||||
foreach ($attributes as $attribute) {
|
||||
$controllerAnnotation = $attribute->newInstance();
|
||||
$nodeList[] = [
|
||||
'node' => $controllerFormat,
|
||||
'title' => $controllerAnnotation->title ?? null,
|
||||
'is_auth' => $controllerAnnotation->auth ?? false,
|
||||
'type' => 1,
|
||||
];
|
||||
}
|
||||
$nodeList = array_merge($nodeList, $actionList);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -300,7 +300,7 @@ class BuildCurd
|
||||
}
|
||||
}
|
||||
$this->tableComment = $this->table;
|
||||
}catch (Exception $e) {
|
||||
} catch (Exception $e) {
|
||||
throw new TableException($e->getMessage());
|
||||
}
|
||||
|
||||
@@ -308,11 +308,11 @@ class BuildCurd
|
||||
$nodeArray = explode('_', $this->table);
|
||||
if (count($nodeArray) == 1) {
|
||||
$this->controllerFilename = ucfirst($nodeArray[0]);
|
||||
}else {
|
||||
} else {
|
||||
foreach ($nodeArray as $k => $v) {
|
||||
if ($k == 0) {
|
||||
$this->controllerFilename = "{$v}{$this->DS}";
|
||||
}else {
|
||||
} else {
|
||||
$this->controllerFilename .= ucfirst($v);
|
||||
}
|
||||
}
|
||||
@@ -396,7 +396,7 @@ class BuildCurd
|
||||
}
|
||||
$this->relationArray[$relationTable] = $relation;
|
||||
$this->selectFields[] = $foreignKey;
|
||||
}catch (Exception $e) {
|
||||
} catch (Exception $e) {
|
||||
throw new TableException($e->getMessage());
|
||||
}
|
||||
return $this;
|
||||
@@ -652,7 +652,6 @@ class BuildCurd
|
||||
if (in_array($key, ['describe', 'content', 'details'])) {
|
||||
$this->editorFields[] = $key;
|
||||
}
|
||||
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
@@ -706,7 +705,7 @@ class BuildCurd
|
||||
}
|
||||
}
|
||||
!empty($formatDefine) && $colum['define'] = $formatDefine;
|
||||
}else {
|
||||
} else {
|
||||
$colum['define'] = $define;
|
||||
}
|
||||
}
|
||||
@@ -730,7 +729,8 @@ class BuildCurd
|
||||
$this->getTemplate("controller{$this->DS}select"),
|
||||
[
|
||||
'name' => $name,
|
||||
]);
|
||||
]
|
||||
);
|
||||
return $selectCode;
|
||||
}
|
||||
|
||||
@@ -754,7 +754,8 @@ class BuildCurd
|
||||
[
|
||||
'name' => $name,
|
||||
'values' => $values,
|
||||
]);
|
||||
]
|
||||
);
|
||||
return $selectCode;
|
||||
}
|
||||
|
||||
@@ -775,7 +776,8 @@ class BuildCurd
|
||||
'name' => "notes['$field']",
|
||||
'relation' => $relation,
|
||||
'values' => $field,
|
||||
]);
|
||||
]
|
||||
);
|
||||
return $selectCode;
|
||||
}
|
||||
|
||||
@@ -794,7 +796,8 @@ class BuildCurd
|
||||
[
|
||||
'name' => "notes['$field']",
|
||||
'select' => $select,
|
||||
]);
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -813,7 +816,8 @@ class BuildCurd
|
||||
'field' => $field,
|
||||
'name' => "notes['$field']",
|
||||
'select' => $select,
|
||||
]);
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -832,7 +836,8 @@ class BuildCurd
|
||||
'field' => $field,
|
||||
'name' => "notes['$field']",
|
||||
'select' => $select,
|
||||
]);
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -945,7 +950,6 @@ class BuildCurd
|
||||
$this->tableColumns[$field]['formType'] = 'select';
|
||||
continue;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 关联表
|
||||
@@ -1018,7 +1022,6 @@ class BuildCurd
|
||||
}
|
||||
|
||||
return $this;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1031,20 +1034,21 @@ class BuildCurd
|
||||
$constructRelation = '';
|
||||
if (empty($this->relationArray)) {
|
||||
$controllerIndexMethod = '';
|
||||
}else {
|
||||
} else {
|
||||
$relationCode = '';
|
||||
foreach ($this->relationArray as $key => $val) {
|
||||
$relation = CommonTool::lineToHump($key);
|
||||
$relationCode = "->withJoin('{$relation}', 'LEFT')\r";
|
||||
if (!empty($val['bindSelectField']) && !empty($val['primaryKey'])) {
|
||||
$constructRelation = '$notes["' . lcfirst($val['modelFilename']) . ucfirst($val['bindSelectField']) . '"] = \app\admin\model\\' . $val['modelFilename'] . '::column("' . $val['bindSelectField'] . '", "' . $val['primaryKey'] . '");';
|
||||
$constructRelation = '$notes["' . lcfirst($val['foreignKey']) . '"] = \app\admin\model\\' . $val['modelFilename'] . '::column("' . $val['bindSelectField'] . '", "' . $val['primaryKey'] . '");';
|
||||
}
|
||||
}
|
||||
$controllerIndexMethod = CommonTool::replaceTemplate(
|
||||
$this->getTemplate("controller{$this->DS}indexMethod"),
|
||||
[
|
||||
'relationIndexMethod' => $relationCode,
|
||||
]);
|
||||
]
|
||||
);
|
||||
}
|
||||
$selectList = '';
|
||||
// foreach ($this->relationArray as $relation) {
|
||||
@@ -1071,7 +1075,8 @@ class BuildCurd
|
||||
'indexMethod' => $controllerIndexMethod,
|
||||
'selectList' => $selectList,
|
||||
'constructRelation' => $constructRelation,
|
||||
]);
|
||||
]
|
||||
);
|
||||
$this->fileList[$controllerFile] = $controllerValue;
|
||||
return $this;
|
||||
}
|
||||
@@ -1129,7 +1134,8 @@ class BuildCurd
|
||||
'relationList' => $relationList,
|
||||
// 'selectList' => $selectList,
|
||||
'selectArrays' => CommonTool::replaceArrayString(var_export($selectArrays, true)),
|
||||
]);
|
||||
]
|
||||
);
|
||||
|
||||
|
||||
$this->fileList[$modelFile] = $modelValue;
|
||||
@@ -1165,7 +1171,8 @@ class BuildCurd
|
||||
'relationList' => '',
|
||||
'selectList' => '',
|
||||
'selectArrays' => "[]",
|
||||
]);
|
||||
]
|
||||
);
|
||||
$this->fileList[$relationModelFile] = $relationModelValue;
|
||||
}
|
||||
return $this;
|
||||
@@ -1184,7 +1191,8 @@ class BuildCurd
|
||||
[
|
||||
'controllerUrl' => $this->controllerUrl,
|
||||
'notesScript' => $this->formatNotesScript(),
|
||||
]);
|
||||
]
|
||||
);
|
||||
$this->fileList[$viewIndexFile] = $viewIndexValue;
|
||||
|
||||
// 添加页面
|
||||
@@ -1202,42 +1210,44 @@ class BuildCurd
|
||||
// 根据formType去获取具体模板
|
||||
if ($val['formType'] == 'image') {
|
||||
$templateFile = "view{$this->DS}module{$this->DS}image";
|
||||
}elseif ($val['formType'] == 'images') {
|
||||
} elseif ($val['formType'] == 'images') {
|
||||
$templateFile = "view{$this->DS}module{$this->DS}images";
|
||||
$define = $val['define'] ?? '|';
|
||||
}elseif ($val['formType'] == 'file') {
|
||||
} elseif ($val['formType'] == 'file') {
|
||||
$templateFile = "view{$this->DS}module{$this->DS}file";
|
||||
}elseif ($val['formType'] == 'files') {
|
||||
} elseif ($val['formType'] == 'files') {
|
||||
$templateFile = "view{$this->DS}module{$this->DS}files";
|
||||
$define = $val['define'] ?? '|';
|
||||
}elseif ($val['formType'] == 'editor') {
|
||||
} elseif ($val['formType'] == 'editor') {
|
||||
$templateFile = "view{$this->DS}module{$this->DS}editor";
|
||||
$val['default'] = '""';
|
||||
}elseif ($val['formType'] == 'date') {
|
||||
} elseif ($val['formType'] == 'date') {
|
||||
$templateFile = "view{$this->DS}module{$this->DS}date";
|
||||
$define = 'date';
|
||||
}elseif ($val['formType'] == 'datetime') {
|
||||
} elseif ($val['formType'] == 'datetime') {
|
||||
$templateFile = "view{$this->DS}module{$this->DS}date";
|
||||
$define = 'datetime';
|
||||
}elseif ($val['formType'] == 'radio') {
|
||||
} elseif ($val['formType'] == 'radio') {
|
||||
$templateFile = "view{$this->DS}module{$this->DS}radio";
|
||||
if (!empty($val['define'])) {
|
||||
$define = $this->buildRadioView($field, '{in name="k" value="' . $val['default'] . '"}checked=""{/in}');
|
||||
}
|
||||
}elseif ($val['formType'] == 'checkbox') {
|
||||
} elseif ($val['formType'] == 'checkbox') {
|
||||
$templateFile = "view{$this->DS}module{$this->DS}checkbox";
|
||||
if (!empty($val['define'])) {
|
||||
$define = $this->buildCheckboxView($field, '{in name="k" value="' . $val['default'] . '"}checked=""{/in}');
|
||||
}
|
||||
}elseif ($val['formType'] == 'select') {
|
||||
} elseif ($val['formType'] == 'select') {
|
||||
$templateFile = "view{$this->DS}module{$this->DS}select";
|
||||
if (isset($val['bindRelation'])) {
|
||||
$define = $this->buildOptionView($val['bindRelation']);
|
||||
}elseif (!empty($val['define'])) {
|
||||
$define = $this->buildOptionView($field);
|
||||
} elseif (!empty($val['define'])) {
|
||||
$define = $this->buildOptionView($field);
|
||||
}
|
||||
}elseif ($field == 'remark' || $val['formType'] == 'textarea') {
|
||||
} elseif ($field == 'remark' || $val['formType'] == 'textarea') {
|
||||
$templateFile = "view{$this->DS}module{$this->DS}textarea";
|
||||
} elseif ($field == 'sort') {
|
||||
$templateFile = "view{$this->DS}module{$this->DS}sort";
|
||||
}
|
||||
$addFormList .= CommonTool::replaceTemplate(
|
||||
$this->getTemplate($templateFile),
|
||||
@@ -1247,13 +1257,15 @@ class BuildCurd
|
||||
'required' => $this->buildRequiredHtml($val['required']),
|
||||
'value' => $val['default'],
|
||||
'define' => $define,
|
||||
]);
|
||||
]
|
||||
);
|
||||
}
|
||||
$viewAddValue = CommonTool::replaceTemplate(
|
||||
$this->getTemplate("view{$this->DS}form"),
|
||||
[
|
||||
'formList' => $addFormList,
|
||||
]);
|
||||
]
|
||||
);
|
||||
$this->fileList[$viewAddFile] = $viewAddValue;
|
||||
|
||||
|
||||
@@ -1274,41 +1286,43 @@ class BuildCurd
|
||||
// 根据formType去获取具体模板
|
||||
if ($val['formType'] == 'image') {
|
||||
$templateFile = "view{$this->DS}module{$this->DS}image";
|
||||
}elseif ($val['formType'] == 'images') {
|
||||
} elseif ($val['formType'] == 'images') {
|
||||
$templateFile = "view{$this->DS}module{$this->DS}images";
|
||||
}elseif ($val['formType'] == 'file') {
|
||||
} elseif ($val['formType'] == 'file') {
|
||||
$templateFile = "view{$this->DS}module{$this->DS}file";
|
||||
}elseif ($val['formType'] == 'files') {
|
||||
} elseif ($val['formType'] == 'files') {
|
||||
$templateFile = "view{$this->DS}module{$this->DS}files";
|
||||
}elseif ($val['formType'] == 'editor') {
|
||||
} elseif ($val['formType'] == 'editor') {
|
||||
$templateFile = "view{$this->DS}module{$this->DS}editor";
|
||||
$value = '$row["' . $field . '"]';
|
||||
}elseif ($val['formType'] == 'date') {
|
||||
} elseif ($val['formType'] == 'date') {
|
||||
$templateFile = "view{$this->DS}module{$this->DS}date";
|
||||
$define = 'date';
|
||||
}elseif ($val['formType'] == 'datetime') {
|
||||
} elseif ($val['formType'] == 'datetime') {
|
||||
$templateFile = "view{$this->DS}module{$this->DS}date";
|
||||
$define = 'datetime';
|
||||
}elseif ($val['formType'] == 'radio') {
|
||||
} elseif ($val['formType'] == 'radio') {
|
||||
$templateFile = "view{$this->DS}module{$this->DS}radio";
|
||||
if (!empty($val['define'])) {
|
||||
$define = $this->buildRadioView($field, '{in name="k" value="$row.' . $field . '"}checked=""{/in}');
|
||||
}
|
||||
}elseif ($val['formType'] == 'checkbox') {
|
||||
} elseif ($val['formType'] == 'checkbox') {
|
||||
$templateFile = "view{$this->DS}module{$this->DS}checkbox";
|
||||
if (!empty($val['define'])) {
|
||||
$define = $this->buildCheckboxView($field, '{in name="k" value="$row.' . $field . '"}checked=""{/in}');
|
||||
}
|
||||
}elseif ($val['formType'] == 'select') {
|
||||
} elseif ($val['formType'] == 'select') {
|
||||
$templateFile = "view{$this->DS}module{$this->DS}select";
|
||||
if (isset($val['bindRelation'])) {
|
||||
$define = $this->buildOptionView($val['bindRelation'], '{in name="k" value="$row.' . $field . '"}selected=""{/in}');
|
||||
}elseif (!empty($val['define'])) {
|
||||
$define = $this->buildOptionView($field, '{in name="k" value="$row.' . $field . '"}selected=""{/in}');
|
||||
} elseif (!empty($val['define'])) {
|
||||
$define = $this->buildOptionView($field, '{in name="k" value="$row.' . $field . '"}selected=""{/in}');
|
||||
}
|
||||
}elseif ($field == 'remark' || $val['formType'] == 'textarea') {
|
||||
} elseif ($field == 'remark' || $val['formType'] == 'textarea') {
|
||||
$templateFile = "view{$this->DS}module{$this->DS}textarea";
|
||||
$value = '{$row.' . $field . '|raw|default=\'\'}';
|
||||
} elseif ($field == 'sort') {
|
||||
$templateFile = "view{$this->DS}module{$this->DS}sort";
|
||||
}
|
||||
$editFormList .= CommonTool::replaceTemplate(
|
||||
$this->getTemplate($templateFile),
|
||||
@@ -1318,13 +1332,15 @@ class BuildCurd
|
||||
'required' => $this->buildRequiredHtml($val['required']),
|
||||
'value' => $value,
|
||||
'define' => $define,
|
||||
]);
|
||||
]
|
||||
);
|
||||
}
|
||||
$viewEditValue = CommonTool::replaceTemplate(
|
||||
$this->getTemplate("view{$this->DS}form"),
|
||||
[
|
||||
'formList' => $editFormList,
|
||||
]);
|
||||
]
|
||||
);
|
||||
$this->fileList[$viewEditFile] = $viewEditValue;
|
||||
|
||||
return $this;
|
||||
@@ -1345,31 +1361,33 @@ class BuildCurd
|
||||
|
||||
if ($val['formType'] == 'image') {
|
||||
$templateValue = "{field: '{$field}', title: '{$val['comment']}', templet: ea.table.image}";
|
||||
}elseif ($val['formType'] == 'images') {
|
||||
} elseif ($val['formType'] == 'datetime') {
|
||||
$templateValue = "{field: '{$field}', search: 'range', title: '{$val['comment']}'}";
|
||||
} elseif ($val['formType'] == 'images') {
|
||||
continue;
|
||||
}elseif ($val['formType'] == 'file') {
|
||||
} elseif ($val['formType'] == 'file') {
|
||||
$templateValue = "{field: '{$field}', title: '{$val['comment']}', templet: ea.table.url}";
|
||||
}elseif ($val['formType'] == 'files') {
|
||||
} elseif ($val['formType'] == 'files') {
|
||||
continue;
|
||||
}elseif ($val['formType'] == 'editor') {
|
||||
} elseif ($val['formType'] == 'editor') {
|
||||
continue;
|
||||
}elseif (in_array($field, $this->switchFields)) {
|
||||
} elseif (in_array($field, $this->switchFields)) {
|
||||
if (!empty($val['define'])) {
|
||||
$templateValue = "{field: '{$field}', search: 'select', selectList: notes?.{$field} || {}, title: '{$val['comment']}', templet: ea.table.switch}";
|
||||
}else {
|
||||
} else {
|
||||
$templateValue = "{field: '{$field}', title: '{$val['comment']}', templet: ea.table.switch}";
|
||||
}
|
||||
}elseif (in_array($val['formType'], ['select', 'checkbox', 'radio', 'switch'])) {
|
||||
} elseif (in_array($val['formType'], ['select', 'checkbox', 'radio', 'switch'])) {
|
||||
if (!empty($val['define'])) {
|
||||
$templateValue = "{field: '{$field}', search: 'select', selectList: notes?.{$field} || {}, title: '{$val['comment']}'}";
|
||||
}else {
|
||||
} else {
|
||||
$templateValue = "{field: '{$field}', title: '{$val['comment']}'}";
|
||||
}
|
||||
}elseif ($field == 'remark') {
|
||||
} elseif ($field == 'remark') {
|
||||
$templateValue = "{field: '{$field}', title: '{$val['comment']}', templet: ea.table.text}";
|
||||
}elseif (in_array($field, $this->sortFields)) {
|
||||
} elseif (in_array($field, $this->sortFields)) {
|
||||
$templateValue = "{field: '{$field}', title: '{$val['comment']}', edit: 'text'}";
|
||||
}else {
|
||||
} else {
|
||||
$templateValue = "{field: '{$field}', title: '{$val['comment']}'}";
|
||||
}
|
||||
|
||||
@@ -1382,27 +1400,27 @@ class BuildCurd
|
||||
foreach ($tableVal['tableColumns'] as $field => $val) {
|
||||
if ($val['formType'] == 'image') {
|
||||
$templateValue = "{field: '{$table}.{$field}', title: '{$val['comment']}', templet: ea.table.image}";
|
||||
}elseif ($val['formType'] == 'images') {
|
||||
} elseif ($val['formType'] == 'images') {
|
||||
continue;
|
||||
}elseif ($val['formType'] == 'file') {
|
||||
} elseif ($val['formType'] == 'file') {
|
||||
$templateValue = "{field: '{$table}.{$field}', title: '{$val['comment']}', templet: ea.table.url}";
|
||||
}elseif ($val['formType'] == 'files') {
|
||||
} elseif ($val['formType'] == 'files') {
|
||||
continue;
|
||||
}elseif ($val['formType'] == 'editor') {
|
||||
} elseif ($val['formType'] == 'editor') {
|
||||
continue;
|
||||
}elseif ($val['formType'] == 'select') {
|
||||
} elseif ($val['formType'] == 'select') {
|
||||
$templateValue = "{field: '{$table}.{$field}', title: '{$val['comment']}'}";
|
||||
}elseif ($field == 'remark') {
|
||||
} elseif ($field == 'remark') {
|
||||
$templateValue = "{field: '{$table}.{$field}', title: '{$val['comment']}', templet: ea.table.text}";
|
||||
}elseif (in_array($field, $this->switchFields)) {
|
||||
} elseif (in_array($field, $this->switchFields)) {
|
||||
$templateValue = "{field: '{$table}.{$field}', title: '{$val['comment']}', templet: ea.table.switch}";
|
||||
}elseif (in_array($field, $this->sortFields)) {
|
||||
} elseif (in_array($field, $this->sortFields)) {
|
||||
$templateValue = "{field: '{$table}.{$field}', title: '{$val['comment']}', edit: 'text'}";
|
||||
}else {
|
||||
$templateValue = "{field: '{$table}.{$field}', title: '{$val['comment']}'}";
|
||||
} else {
|
||||
$templateValue = "";
|
||||
}
|
||||
|
||||
$indexCols .= $this->formatColsRow("{$templateValue},\r");
|
||||
if ($templateValue) $indexCols .= $this->formatColsRow("{$templateValue},\r");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1413,7 +1431,8 @@ class BuildCurd
|
||||
[
|
||||
'controllerUrl' => $this->controllerUrl,
|
||||
'indexCols' => $indexCols,
|
||||
]);
|
||||
]
|
||||
);
|
||||
$this->fileList[$jsFile] = $jsValue;
|
||||
return $this;
|
||||
}
|
||||
@@ -1538,4 +1557,4 @@ class BuildCurd
|
||||
{
|
||||
return ' let notes = JSON.parse(\'{$notes|json_encode=256|raw}\');';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,9 +7,7 @@ use app\admin\service\annotation\ControllerAnnotation;
|
||||
use app\admin\service\annotation\NodeAnnotation;
|
||||
use think\App;
|
||||
|
||||
/**
|
||||
* @ControllerAnnotation(title="{{controllerAnnotation}}")
|
||||
*/
|
||||
#[ControllerAnnotation(title: '{{controllerAnnotation}}')]
|
||||
class {{controllerName}} extends AdminController
|
||||
{
|
||||
|
||||
|
||||
7
app/admin/service/curd/templates/view/module/sort.code
Normal file
7
app/admin/service/curd/templates/view/module/sort.code
Normal file
@@ -0,0 +1,7 @@
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">{{comment}}</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="number" name="{{field}}" class="layui-input" lay-affix="number" {{required}} placeholder="请输入{{comment}}" value="{{value}}">
|
||||
</div>
|
||||
</div>
|
||||
@@ -17,9 +17,7 @@ use think\response\Json;
|
||||
trait Curd
|
||||
{
|
||||
|
||||
/**
|
||||
* @NodeAnnotation(title="列表")
|
||||
*/
|
||||
#[NodeAnnotation(title: '列表', auth: true)]
|
||||
public function index(Request $request): Json|string
|
||||
{
|
||||
if ($request->isAjax()) {
|
||||
@@ -40,9 +38,7 @@ trait Curd
|
||||
return $this->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* @NodeAnnotation(title="添加")
|
||||
*/
|
||||
#[NodeAnnotation(title: '添加', auth: true)]
|
||||
public function add(Request $request): string
|
||||
{
|
||||
if ($request->isPost()) {
|
||||
@@ -61,9 +57,7 @@ trait Curd
|
||||
return $this->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* @NodeAnnotation(title="编辑")
|
||||
*/
|
||||
#[NodeAnnotation(title: '编辑', auth: true)]
|
||||
public function edit(Request $request, $id = 0): string
|
||||
{
|
||||
$row = $this->model->find($id);
|
||||
@@ -85,9 +79,7 @@ trait Curd
|
||||
return $this->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* @NodeAnnotation(title="删除")
|
||||
*/
|
||||
#[NodeAnnotation(title: '删除', auth: true)]
|
||||
public function delete(Request $request): void
|
||||
{
|
||||
// 如果不是id作为主键 请在对应的控制器中覆盖重写
|
||||
@@ -103,9 +95,7 @@ trait Curd
|
||||
$save ? $this->success('删除成功') : $this->error('删除失败');
|
||||
}
|
||||
|
||||
/**
|
||||
* @NodeAnnotation(title="导出")
|
||||
*/
|
||||
#[NodeAnnotation(title: '导出', auth: true)]
|
||||
public function export()
|
||||
{
|
||||
if (env('EASYADMIN.IS_DEMO', false)) {
|
||||
@@ -133,9 +123,7 @@ trait Curd
|
||||
return Excel::exportData($list, $header, $fileName, 'xlsx');
|
||||
}
|
||||
|
||||
/**
|
||||
* @NodeAnnotation(title="属性修改")
|
||||
*/
|
||||
#[NodeAnnotation(title: '属性修改', auth: true)]
|
||||
public function modify(Request $request): void
|
||||
{
|
||||
$this->checkPostRequest();
|
||||
|
||||
@@ -26,15 +26,6 @@
|
||||
</ul>
|
||||
|
||||
<ul class="layui-nav layui-layout-right">
|
||||
<!-- <li class="layui-nav-item" lay-unselect>-->
|
||||
<!-- <div class="layui-form ws-header-theme" lay-filter="header-theme">-->
|
||||
<!-- <input type="checkbox" name="theme-mode" id="ID-header-theme-mode" lay-filter="header-theme-mode" lay-skin="switch">-->
|
||||
<!-- <div lay-checkbox>-->
|
||||
<!-- <i class="layui-icon layui-icon-moon"></i> |-->
|
||||
<!-- <i class="layui-icon layui-icon-light"></i>-->
|
||||
<!-- </div>-->
|
||||
<!-- </div>-->
|
||||
<!-- </li>-->
|
||||
<li class="layui-nav-item" lay-unselect>
|
||||
<a href="http://easyadmin8.top" target="_blank"><i class="fa fa-home"></i></a>
|
||||
</li>
|
||||
@@ -47,6 +38,15 @@
|
||||
<li class="layui-nav-item mobile layui-hide-xs" lay-unselect>
|
||||
<a href="javascript:;" data-check-screen="full"><i class="fa fa-arrows-alt"></i></a>
|
||||
</li>
|
||||
<li class="layui-nav-item" lay-unselect>
|
||||
<div class="layui-form ws-header-theme" lay-filter="header-theme">
|
||||
<input type="checkbox" name="theme-mode" lay-filter="header-theme-mode" lay-skin="switch">
|
||||
<div lay-checkbox>
|
||||
<i class="layui-icon layui-icon-moon"></i> |
|
||||
<i class="layui-icon layui-icon-light"></i>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li class="layui-nav-item layuimini-setting">
|
||||
<a href="javascript:;">
|
||||
<img src="{:session('admin.head_img')}" class="layui-nav-img" width="50" height="50">
|
||||
|
||||
@@ -151,12 +151,18 @@
|
||||
<tr>
|
||||
<td>DEBUG模式</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')?'开启中':'已关闭'}
|
||||
</button>
|
||||
<span class="layui-badge layui-bg-gray">建议线上环境关闭 APP_DEBUG</span>
|
||||
</td>
|
||||
</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>
|
||||
<td>主要特色</td>
|
||||
<td>
|
||||
@@ -180,7 +186,7 @@
|
||||
<td>Github</td>
|
||||
<td>
|
||||
<a href="https://github.com/wolf-leo/easyAdmin8" target="_blank">
|
||||
<i class="layui-icon layui-icon-github layui-font-20 layui-font-cyan layui-text"></i>
|
||||
<i class="layui-icon layui-icon-github layui-font-20 layui-font-gray layui-text"></i>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -192,7 +198,7 @@
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-header"><i class="fa fa-paper-plane-o icon"></i>作者心语</div>
|
||||
<div class="layui-card-body layui-text">
|
||||
<p class="layui-font-cyan">
|
||||
<p>
|
||||
本模板基于layui2.9.x以及font-awesome-4.7.0进行实现。
|
||||
<a class="layui-btn layui-btn-xs layui-btn-danger" style="vertical-align: baseline;" target="_blank" href="http://layui.dev/docs">layui文档</a>
|
||||
</p>
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
<meta name="renderer" content="webkit">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
|
||||
<link rel="icon" href="{:sysConfig('site', 'site_ico')}" type="image/x-icon">
|
||||
<!--[if lt IE 9]>
|
||||
<script src="https://cdn.staticfile.org/html5shiv/r29/html5.min.js"></script>
|
||||
<script src="https://cdn.staticfile.org/respond.js/1.4.2/respond.min.js"></script>
|
||||
@@ -26,7 +27,6 @@
|
||||
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,7 +22,7 @@
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">分类排序</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="number" name="sort" class="layui-input" placeholder="请输入分类排序" value="0">
|
||||
<input type="number" name="sort" class="layui-input" lay-affix="number" placeholder="请输入分类排序" value="0">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">分类排序</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="number" name="sort" class="layui-input" placeholder="请输入分类排序" value="{$row.sort|default=''}">
|
||||
<input type="number" name="sort" class="layui-input" lay-affix="number" placeholder="请输入分类排序" value="{$row.sort|default=''}">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -26,9 +26,18 @@
|
||||
<!-- </div>-->
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">商品标题</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="title" class="layui-input" lay-verify="required" placeholder="请输入商品标题" value="">
|
||||
<div class="layui-row">
|
||||
<label class="layui-form-label required">商品标题</label>
|
||||
<div class="layui-input-block layui-col-space5">
|
||||
<div class="layui-col-xs10">
|
||||
<div class="layui-input-wrap">
|
||||
<input type="text" name="title" class="layui-input" lay-verify="required" placeholder="请输入商品标题" value="">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-col-xs2">
|
||||
<button class="layui-btn layui-bg-purple layui-btn-fluid" type="button" lay-on="AiOptimization">AI优化</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -78,7 +87,7 @@
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">分类排序</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="number" name="sort" class="layui-input" placeholder="请输入分类排序" value="0">
|
||||
<input type="number" name="sort" class="layui-input" lay-affix="number" placeholder="请输入分类排序" value="0">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -26,12 +26,22 @@
|
||||
<!-- </div>-->
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">商品标题</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="title" class="layui-input" lay-verify="required" placeholder="请输入商品标题" value="{$row.title|default=''}">
|
||||
<div class="layui-row">
|
||||
<label class="layui-form-label required">商品标题</label>
|
||||
<div class="layui-input-block layui-col-space5">
|
||||
<div class="layui-col-xs10">
|
||||
<div class="layui-input-wrap">
|
||||
<input type="text" name="title" class="layui-input" lay-verify="required" placeholder="请输入商品标题" value="{$row.title|default=''}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-col-xs2">
|
||||
<button class="layui-btn layui-bg-purple layui-btn-fluid" type="button" lay-on="AiOptimization">AI优化</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label required">商品LOGO</label>
|
||||
<div class="layui-input-block layuimini-upload">
|
||||
@@ -78,7 +88,7 @@
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">分类排序</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="number" name="sort" class="layui-input" placeholder="请输入分类排序" value="{$row.sort|default=''}">
|
||||
<input type="number" name="sort" class="layui-input" lay-affix="number" placeholder="请输入分类排序" value="{$row.sort|default=''}">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">入库数量</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="number" name="stock" class="layui-input" lay-verify="required" placeholder="请输入入库数量" value="0">
|
||||
<input type="number" name="stock" class="layui-input" lay-affix="number" lay-verify="required" placeholder="请输入入库数量" value="0">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -1,22 +1,16 @@
|
||||
<div class="layuimini-container">
|
||||
<div class="layuimini-main" id="app">
|
||||
|
||||
<div class="layui-tab layui-tab-brief" lay-filter="docDemoTabBrief">
|
||||
<ul class="layui-tab-title">
|
||||
<div class="layui-tabs layui-tabs-card layui-panel " id="docDemoTabBrief">
|
||||
<ul class="layui-tabs-header layui-bg-tint">
|
||||
<li class="layui-this" data-group="site">网站设置</li>
|
||||
<li data-group="logo">LOGO配置</li>
|
||||
<li data-group="upload">上传配置</li>
|
||||
</ul>
|
||||
<div class="layui-tab-content">
|
||||
<div class="layui-tab-item layui-show">
|
||||
{include file="system/config/site" /}
|
||||
</div>
|
||||
<div class="layui-tab-item">
|
||||
{include file="system/config/logo" /}
|
||||
</div>
|
||||
<div class="layui-tab-item">
|
||||
{include file="system/config/upload" /}
|
||||
</div>
|
||||
<div class="layui-tabs-body">
|
||||
<div class="layui-tabs-item layui-show"> {include file="system/config/site" /}</div>
|
||||
<div class="layui-tabs-item"> {include file="system/config/logo" /}</div>
|
||||
<div class="layui-tabs-item">{include file="system/config/upload" /}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
23
app/admin/view/system/log/delete_month_log.html
Normal file
23
app/admin/view/system/log/delete_month_log.html
Normal file
@@ -0,0 +1,23 @@
|
||||
<div class="layuimini-container">
|
||||
|
||||
<form id="app-form" class="layui-form layuimini-form">
|
||||
|
||||
<div class="layui-form-item">
|
||||
|
||||
<div class="layui-input-group">
|
||||
<div class="layui-input-prefix layui-input-split">删除</div>
|
||||
<label>
|
||||
<input type="number" name="month" lay-affix="number" placeholder="" min="1" class="layui-input" value="3">
|
||||
</label>
|
||||
<div class="layui-input-suffix layui-input-split">个月前的日志</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="hr-line"></div>
|
||||
<div class="layui-form-item text-center">
|
||||
<button type="button" class="layui-btn" lay-submit lay-filter="submit">提交</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
@@ -2,6 +2,7 @@
|
||||
<div class="layuimini-main">
|
||||
<table id="currentTable" class="layui-table layui-hide"
|
||||
data-auth-record="{:auth('system.log/record')}"
|
||||
data-auth-deleteMonthLog="{:auth('system.log/deleteMonthLog')}"
|
||||
lay-filter="currentTable">
|
||||
</table>
|
||||
</div>
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">菜单排序</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="number" name="sort" lay-reqtext="菜单排序不能为空" placeholder="请输入菜单排序" value="0" class="layui-input">
|
||||
<input type="number" name="sort" lay-reqtext="菜单排序不能为空" placeholder="请输入菜单排序" value="0" class="layui-input" lay-affix="number">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">菜单排序</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="number" name="sort" lay-reqtext="菜单排序不能为空" placeholder="请输入菜单排序" value="{$row.sort|default=''}" class="layui-input">
|
||||
<input type="number" name="sort" lay-reqtext="菜单排序不能为空" placeholder="请输入菜单排序" value="{$row.sort|default=''}" class="layui-input" lay-affix="number">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">菜单排序</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="number" name="sort" lay-reqtext="菜单排序不能为空" placeholder="请输入菜单排序" value="0" class="layui-input">
|
||||
<input type="number" name="sort" lay-reqtext="菜单排序不能为空" placeholder="请输入菜单排序" value="0" class="layui-input" lay-affix="number">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">菜单排序</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="number" name="sort" lay-reqtext="菜单排序不能为空" placeholder="请输入菜单排序" value="{$row.sort|default=''}" class="layui-input">
|
||||
<input type="number" name="sort" lay-reqtext="菜单排序不能为空" placeholder="请输入菜单排序" value="{$row.sort|default=''}" class="layui-input" lay-affix="number">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -100,21 +100,21 @@ if (!function_exists('auth')) {
|
||||
$authService = new AuthService(session('admin.id'));
|
||||
return $authService->checkNode($node);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|null $detail
|
||||
* @param string $name
|
||||
* @param string $placeholder
|
||||
* @return string
|
||||
*/
|
||||
function editor_textarea(?string $detail, string $name = 'desc', string $placeholder = '请输入'): string
|
||||
{
|
||||
$editor_type = sysConfig('site', 'editor_type');
|
||||
return match ($editor_type) {
|
||||
'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>",
|
||||
'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>",
|
||||
};
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @param string|null $detail
|
||||
* @param string $name
|
||||
* @param string $placeholder
|
||||
* @return string
|
||||
*/
|
||||
function editor_textarea(?string $detail, string $name = 'desc', string $placeholder = '请输入'): string
|
||||
{
|
||||
$editor_type = sysConfig('site', 'editor_type');
|
||||
return match ($editor_type) {
|
||||
'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>",
|
||||
'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>",
|
||||
};
|
||||
}
|
||||
|
||||
@@ -44,6 +44,12 @@ class AdminController extends BaseController
|
||||
'title',
|
||||
];
|
||||
|
||||
/**
|
||||
* 过滤节点更新
|
||||
* @var array
|
||||
*/
|
||||
protected array $ignoreNode = [];
|
||||
|
||||
/**
|
||||
* 不导出的字段信息
|
||||
* @var array
|
||||
@@ -243,7 +249,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,
|
||||
'iframeOpenTop' => sysConfig('site', 'iframe_open_top') ?: 0,
|
||||
];
|
||||
View::assign($data);
|
||||
}
|
||||
|
||||
22
app/common/entity/BaseEntity.php
Normal file
22
app/common/entity/BaseEntity.php
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace app\common\entity;
|
||||
|
||||
use think\Entity;
|
||||
use think\model\type\DateTime;
|
||||
|
||||
class BaseEntity extends Entity
|
||||
{
|
||||
|
||||
protected function getOptions(): array
|
||||
{
|
||||
return [
|
||||
'type' => [
|
||||
'create_time' => DateTime::class,
|
||||
'update_time' => DateTime::class,
|
||||
'delete_time' => DateTime::class,
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
@@ -13,28 +13,20 @@ use think\model\concern\SoftDelete;
|
||||
class TimeModel extends Model
|
||||
{
|
||||
|
||||
/**
|
||||
* 自动时间戳类型
|
||||
* @var string
|
||||
*/
|
||||
protected $autoWriteTimestamp = true;
|
||||
|
||||
/**
|
||||
* 添加时间
|
||||
* @var string
|
||||
*/
|
||||
protected $createTime = 'create_time';
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
* @var string
|
||||
*/
|
||||
protected $updateTime = 'update_time';
|
||||
|
||||
/**
|
||||
* 软删除
|
||||
*/
|
||||
use SoftDelete;
|
||||
protected $deleteTime = false;
|
||||
|
||||
protected function getOptions(): array
|
||||
{
|
||||
return [
|
||||
'autoWriteTimestamp' => true,
|
||||
'createTime' => 'create_time',
|
||||
'updateTime' => 'update_time',
|
||||
'deleteTime' => false,
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace app\common\service;
|
||||
|
||||
use app\admin\service\annotation\NodeAnnotation;
|
||||
use app\common\constants\AdminConstant;
|
||||
use think\facade\Db;
|
||||
|
||||
@@ -52,7 +53,7 @@ class AuthService
|
||||
/***
|
||||
* 构造方法
|
||||
* AuthService constructor.
|
||||
* @param null $adminId
|
||||
* @param null $adminId
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
@@ -68,7 +69,7 @@ class AuthService
|
||||
|
||||
/**
|
||||
* 检测检测权限
|
||||
* @param null $node
|
||||
* @param null $node
|
||||
* @return bool
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
@@ -87,7 +88,7 @@ class AuthService
|
||||
// 判断是否需要获取当前节点
|
||||
if (empty($node)) {
|
||||
$node = $this->getCurrentNode();
|
||||
} else {
|
||||
}else {
|
||||
$node = $this->parseNodeStr($node);
|
||||
}
|
||||
// 判断是否加入节点控制,优先获取缓存信息
|
||||
@@ -106,9 +107,30 @@ class AuthService
|
||||
if (in_array($node, $this->adminNode)) {
|
||||
return true;
|
||||
}
|
||||
if ($this->checkNodeAnnotationAttrAuth($node)) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function checkNodeAnnotationAttrAuth(string $node): bool
|
||||
{
|
||||
$bool = false;
|
||||
$controller = request()->controller();
|
||||
try {
|
||||
$controllerExplode = explode('.', $controller);
|
||||
[$_name, $_controller] = $controllerExplode;
|
||||
$nodeExplode = explode('/', $node);
|
||||
$action = end($nodeExplode);
|
||||
$reflectionClass = new \ReflectionClass("app\admin\controller\\{$_name}\\{$_controller}");
|
||||
$attributes = $reflectionClass->getMethod($action)->getAttributes(NodeAnnotation::class);
|
||||
foreach ($attributes as $attribute) {
|
||||
$annotation = $attribute->newInstance();
|
||||
$bool = $annotation->auth === false;
|
||||
}
|
||||
}catch (\Throwable) {
|
||||
}
|
||||
return $bool;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前节点
|
||||
* @return string
|
||||
@@ -130,25 +152,25 @@ class AuthService
|
||||
{
|
||||
$nodeList = [];
|
||||
$adminInfo = Db::name($this->config['system_admin'])
|
||||
->where([
|
||||
'id' => $this->adminId,
|
||||
'status' => 1,
|
||||
])->find();
|
||||
->where([
|
||||
'id' => $this->adminId,
|
||||
'status' => 1,
|
||||
])->find();
|
||||
if (!empty($adminInfo) && !empty($adminInfo['auth_ids'])) {
|
||||
$buildAuthSql = Db::name($this->config['system_auth'])
|
||||
->distinct(true)
|
||||
->whereIn('id', $adminInfo['auth_ids'])
|
||||
->field('id')
|
||||
->buildSql(true);
|
||||
->distinct(true)
|
||||
->whereIn('id', $adminInfo['auth_ids'])
|
||||
->field('id')
|
||||
->buildSql(true);
|
||||
$buildAuthNodeSql = Db::name($this->config['system_auth_node'])
|
||||
->distinct(true)
|
||||
->where("auth_id IN {$buildAuthSql}")
|
||||
->field('node_id')
|
||||
->buildSql(true);
|
||||
->distinct(true)
|
||||
->where("auth_id IN {$buildAuthSql}")
|
||||
->field('node_id')
|
||||
->buildSql(true);
|
||||
$nodeList = Db::name($this->config['system_node'])
|
||||
->distinct(true)
|
||||
->where("id IN {$buildAuthNodeSql}")
|
||||
->column('node');
|
||||
->distinct(true)
|
||||
->where("id IN {$buildAuthNodeSql}")
|
||||
->column('node');
|
||||
}
|
||||
return $nodeList;
|
||||
}
|
||||
@@ -162,7 +184,7 @@ class AuthService
|
||||
public function getNodeList()
|
||||
{
|
||||
return Db::name($this->config['system_node'])
|
||||
->column('id,node,title,type,is_auth', 'node');
|
||||
->column('id,node,title,type,is_auth', 'node');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -177,13 +199,13 @@ class AuthService
|
||||
public function getAdminInfo()
|
||||
{
|
||||
return Db::name($this->config['system_admin'])
|
||||
->where('id', $this->adminId)
|
||||
->find();
|
||||
->where('id', $this->adminId)
|
||||
->find();
|
||||
}
|
||||
|
||||
/**
|
||||
* 驼峰转下划线规则
|
||||
* @param string $node
|
||||
* @param string $node
|
||||
* @return string
|
||||
*/
|
||||
public function parseNodeStr($node)
|
||||
|
||||
28
app/common/utils/Helper.php
Normal file
28
app/common/utils/Helper.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace app\common\utils;
|
||||
|
||||
class Helper
|
||||
{
|
||||
|
||||
/**
|
||||
* 获取当前IP地址
|
||||
* @return string
|
||||
*/
|
||||
public static function getIp(): string
|
||||
{
|
||||
return request()->ip();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前登录用户ID
|
||||
* @return int|string
|
||||
*/
|
||||
public static function getAdminUid(): int|string
|
||||
{
|
||||
return session('admin.id') ?: 0;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -22,8 +22,8 @@ class Install extends BaseController
|
||||
// $this->redirect('/');
|
||||
$isInstall = true;
|
||||
$errorInfo = '已安装系统,如需重新安装请删除文件:/config/install/lock/install.lock,或者删除 /install 路由';
|
||||
}elseif (version_compare(phpversion(), '8.0.0', '<')) {
|
||||
$errorInfo = 'PHP版本不能小于8.0.0';
|
||||
}elseif (version_compare(phpversion(), '8.1.0', '<')) {
|
||||
$errorInfo = 'PHP版本不能小于8.1.0';
|
||||
}elseif (!extension_loaded("PDO")) {
|
||||
$errorInfo = '当前未开启PDO,无法进行安装';
|
||||
}
|
||||
@@ -31,9 +31,17 @@ class Install extends BaseController
|
||||
$errorInfo = '.env 文件不存在,请先配置 .env 文件';
|
||||
}
|
||||
if (!$request->isAjax()) {
|
||||
$envInfo = [
|
||||
'DB_HOST' => $isInstall ? '' : env('DB_HOST', '127.0.0.1'),
|
||||
'DB_NAME' => $isInstall ? '' : env('DB_NAME', 'easyadmin8'),
|
||||
'DB_USER' => $isInstall ? '' : env('DB_USER', 'root'),
|
||||
'DB_PASS' => $isInstall ? '' : env('DB_PASS', 'root'),
|
||||
'DB_PORT' => $isInstall ? '' : env('DB_PORT', 3306),
|
||||
'DB_PREFIX' => $isInstall ? '' : env('DB_PREFIX', 'ea8_'),
|
||||
];
|
||||
$currentHost = '://';
|
||||
$result = compact('errorInfo', 'currentHost', 'isInstall');
|
||||
return view('index/install/index', $result);
|
||||
$result = compact('errorInfo', 'currentHost', 'isInstall', 'envInfo');
|
||||
return view('index@install/index', $result);
|
||||
}
|
||||
if ($errorInfo) $this->error($errorInfo);
|
||||
$charset = 'utf8mb4';
|
||||
|
||||
@@ -20,25 +20,27 @@
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=8.0.0",
|
||||
"php": ">=8.1.0",
|
||||
"topthink/framework": "^8.0",
|
||||
"topthink/think-orm": "^3.0",
|
||||
"topthink/think-orm": "^4.0",
|
||||
"topthink/think-multi-app": "^1.1.0",
|
||||
"topthink/think-view": "^2.0",
|
||||
"topthink/think-captcha": "^3.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",
|
||||
"jianyan74/php-excel": "^1.0.2",
|
||||
"doctrine/annotations": "^1.13",
|
||||
"doctrine/annotations": "^2.0.0",
|
||||
"phpoffice/phpspreadsheet": "^1.28",
|
||||
"myclabs/php-enum": "^1.8",
|
||||
"ext-json": "*",
|
||||
"qiniu/php-sdk": "v7.11.0",
|
||||
"ext-mysqli": "*",
|
||||
"ext-pdo": "*",
|
||||
"qiniu/php-sdk": "^7.11.0",
|
||||
"wolf-leo/phplogviewer": "^0.11.3",
|
||||
"wolfcode/authenticator": "^0.0.6"
|
||||
"wolfcode/authenticator": "^0.0.6",
|
||||
"wolfcode/rate-limiting": "^0.1.0",
|
||||
"wolfcode/php-ai": "^0.1.2",
|
||||
"ext-json": "*",
|
||||
"ext-mysqli": "*",
|
||||
"ext-pdo": "*"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/var-dumper": ">=4.2",
|
||||
|
||||
@@ -235,11 +235,11 @@ VALUES ('64', 'oss_domain', 'upload', '填你的', '阿里云oss访问域名', '
|
||||
INSERT INTO `ea_system_config`
|
||||
VALUES ('65', 'logo_title', 'site', 'EasyAdmin', 'LOGO标题', '0', null, null);
|
||||
INSERT INTO `ea_system_config`
|
||||
VALUES ('66', 'logo_image', 'site', '/favicon.ico', 'logo图片', '0', null, null);
|
||||
VALUES ('66', 'logo_image', 'site', '/static/common/images/logo-1.png', 'logo图片', '0', null, null);
|
||||
INSERT INTO `ea_system_config`
|
||||
VALUES ('68', 'site_name', 'site', 'EasyAdmin后台系统', '站点名称', '0', null, null);
|
||||
INSERT INTO `ea_system_config`
|
||||
VALUES ('69', 'site_ico', 'site', '填你的', '浏览器图标', '0', null, null);
|
||||
VALUES ('69', 'site_ico', 'site', '/favicon.ico', '浏览器图标', '0', null, null);
|
||||
INSERT INTO `ea_system_config`
|
||||
VALUES ('70', 'site_copyright', 'site', '填你的', '版权信息', '0', null, null);
|
||||
INSERT INTO `ea_system_config`
|
||||
@@ -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);
|
||||
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);
|
||||
|
||||
-- ----------------------------
|
||||
-- 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';
|
||||
|
||||
1
log.md
1
log.md
@@ -1,2 +1,3 @@
|
||||
> 2025年01月01日 `PHP` 要求升级到 `8.1+`
|
||||
>
|
||||
> 2024年05月 更新 `EasyAdmin8` 重置版,多处语法、写法进行变更
|
||||
59
public/static/admin/css/color.css
Normal file
59
public/static/admin/css/color.css
Normal file
@@ -0,0 +1,59 @@
|
||||
.green {
|
||||
color: #11c26d !important;
|
||||
}
|
||||
|
||||
.red {
|
||||
color: #ff4c52 !important;
|
||||
}
|
||||
|
||||
.cyan {
|
||||
color: #0bb2d4 !important;
|
||||
}
|
||||
|
||||
.purple {
|
||||
color: #9463f7 !important;
|
||||
}
|
||||
|
||||
.blue {
|
||||
color: #3e8ef7 !important;
|
||||
}
|
||||
|
||||
.orange {
|
||||
color: #eb6709 !important;
|
||||
}
|
||||
|
||||
.indigo {
|
||||
color: #6610f2 !important;
|
||||
}
|
||||
|
||||
.pink {
|
||||
color: #e83e8c !important;
|
||||
}
|
||||
|
||||
.teal {
|
||||
color: #20c997 !important;
|
||||
}
|
||||
|
||||
.white {
|
||||
color: #fff !important;
|
||||
}
|
||||
|
||||
.gray {
|
||||
color: #6c757d !important;
|
||||
}
|
||||
|
||||
.gray-dark {
|
||||
color: #343a40 !important;
|
||||
}
|
||||
|
||||
.secondary {
|
||||
color: #6c757d !important;
|
||||
}
|
||||
|
||||
.yellow {
|
||||
color: rgb(255, 214, 102) !important;
|
||||
}
|
||||
|
||||
.magenta {
|
||||
color: #eb2f96 !important;
|
||||
}
|
||||
@@ -1,3 +1,6 @@
|
||||
body {
|
||||
background: #333333;
|
||||
}
|
||||
|
||||
.demo {
|
||||
padding-top: 20px;
|
||||
@@ -170,7 +173,6 @@
|
||||
}
|
||||
|
||||
.container {
|
||||
background: #333333;
|
||||
position: static;
|
||||
font-size: 12px;
|
||||
height: 100%;
|
||||
|
||||
@@ -1,21 +1,23 @@
|
||||
@import url("../../plugs/layui-v2.x/css/layui.css");
|
||||
@import url("../../plugs/font-awesome-4.7.0/css/font-awesome.min.css");
|
||||
@import url("../css/color.css");
|
||||
@import url("../css/themes/index.css");
|
||||
@import url("../css/iconfont.css");
|
||||
|
||||
html, body {
|
||||
height: 100%;
|
||||
background: #f2f2f2;
|
||||
}
|
||||
|
||||
html.dark, body {
|
||||
height: 100%;
|
||||
background: var(--lay-color-bg-1);
|
||||
html,
|
||||
body {
|
||||
font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Helvetica Neue", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
|
||||
}
|
||||
|
||||
.ws-header-theme .layui-form-switch {
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
.ws-header-theme .layui-form-onswitch {
|
||||
background: #333333;
|
||||
border: 1px solid rgba(255, 255, 255, .7);
|
||||
}
|
||||
|
||||
.layuimini-container {
|
||||
min-height: 250px;
|
||||
padding: 15px;
|
||||
@@ -58,10 +60,8 @@ html.dark, body {
|
||||
}
|
||||
|
||||
.hr-line {
|
||||
color: #fff;
|
||||
height: 1px;
|
||||
margin: 30px 0;
|
||||
background-color: #fff;
|
||||
border-top: 1px dashed #e7eaec;
|
||||
}
|
||||
|
||||
@@ -84,7 +84,6 @@ html.dark, body {
|
||||
margin: 0;
|
||||
border: 1px solid #e6e6e6;
|
||||
padding: 10px 20px 5px 20px;
|
||||
color: #6b6b6b;
|
||||
}
|
||||
|
||||
/**数据表格-搜索表单样式*/
|
||||
@@ -134,10 +133,17 @@ html.dark, body {
|
||||
color: #a29c9c;
|
||||
}
|
||||
|
||||
.layui-form-item xm-select {
|
||||
.tableSearch-xmSelect xm-select {
|
||||
min-height: 30px !important;
|
||||
line-height: 30px !important;
|
||||
margin: 0 !important;
|
||||
background-color: var(--lay-color-fill-2);
|
||||
}
|
||||
|
||||
.elem-style-dark .tableSearch-xmSelect xm-select {
|
||||
background-color: var(--lay-color-fill-2);
|
||||
color: var(--lay-color-text-2);
|
||||
border-color: var(--lay-color-border-1) !important;
|
||||
}
|
||||
|
||||
/** 按钮背景色 */
|
||||
@@ -265,7 +271,6 @@ table样式
|
||||
|
||||
.layuimini-container .layui-table-box .layui-table-header th {
|
||||
font-weight: bold !important;
|
||||
color: #565656 !important;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -340,7 +345,7 @@ table样式
|
||||
弹出层样式
|
||||
*/
|
||||
.layui-layer-easy .layui-layer-title {
|
||||
background: #2c3e50 !important;
|
||||
background: var(--lay-color-bg-5);
|
||||
color: #fff !important;
|
||||
border-bottom: none;
|
||||
}
|
||||
@@ -363,7 +368,6 @@ table样式
|
||||
.layui-layer-easy .layui-layer-btn {
|
||||
text-align: center !important;
|
||||
padding: 10px !important;
|
||||
background: #ecf0f1;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
@@ -512,4 +516,5 @@ table样式
|
||||
|
||||
.wangEditor_div {
|
||||
z-index: 99999;
|
||||
border: 1px solid var(--w-e-textarea-slight-border-color);
|
||||
}
|
||||
802
public/static/admin/css/themes/_dark.scss
Normal file
802
public/static/admin/css/themes/_dark.scss
Normal file
@@ -0,0 +1,802 @@
|
||||
// 通常用于背景色
|
||||
$black-color :rgb(2, 17, 20);
|
||||
// 通常用于字体颜色
|
||||
$main-color :rgb(126, 252, 246);
|
||||
// 通常用于边框
|
||||
$less-main-color:rgb(6, 216, 215);
|
||||
|
||||
$plus-main-color:rgb(0, 125, 124);
|
||||
|
||||
// 通常用于激活状态,通常跟背景色搭配
|
||||
$cover-color :rgba(62, 251, 251, 0.05);
|
||||
// 更强的激活状态,适合做选项操作时使用
|
||||
$active-color :rgba(62, 251, 251, 0.5);
|
||||
|
||||
|
||||
$red-color :rgb(255, 0, 0);
|
||||
$yellow-color:rgb(255, 255, 153);
|
||||
$green-color :rgb(0, 255, 0);
|
||||
|
||||
& {
|
||||
background-color: $black-color;
|
||||
color: $main-color;
|
||||
}
|
||||
|
||||
.layuimini-main {
|
||||
background-color: $black-color;
|
||||
}
|
||||
|
||||
.layuimini-container {
|
||||
background-color: $black-color;
|
||||
}
|
||||
|
||||
.layuimini-container .layui-table-tool {
|
||||
background-color: $black-color;
|
||||
}
|
||||
|
||||
$box-shape: polygon(0 0, 100% 0, 100% calc(100% - 10px), calc(100% - 10px) 100%, 0 100%, 0 0);
|
||||
|
||||
.layui-btn {
|
||||
|
||||
&.layui-btn-lg {
|
||||
|
||||
padding-right: 25px;
|
||||
}
|
||||
|
||||
clip-path : $box-shape;
|
||||
padding-right : 10px;
|
||||
position : relative;
|
||||
background-color: transparent;
|
||||
border : 1px solid;
|
||||
color : rgb(126, 252, 246);
|
||||
text-shadow : rgb(126, 252, 246) 0px 0px 1px;
|
||||
background-color: rgb(126, 252, 246);
|
||||
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
display: block;
|
||||
position: absolute;
|
||||
z-index: -1;
|
||||
clip-path: $box-shape;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
left: -0.5px;
|
||||
top: -0.5px;
|
||||
background-color: $black-color;
|
||||
}
|
||||
|
||||
&:hover::after {
|
||||
content: '';
|
||||
display: block;
|
||||
position: absolute;
|
||||
z-index: -1;
|
||||
clip-path: $box-shape;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
left: -0.5px;
|
||||
top: -0.5px;
|
||||
background-color: rgba(126, 252, 246, 0.2);
|
||||
}
|
||||
|
||||
&.layui-btn-disabled {
|
||||
&::after {
|
||||
// todo:实现按钮禁用样式
|
||||
}
|
||||
}
|
||||
|
||||
&.layui-btn-success {
|
||||
text-shadow: rgb(0, 255, 0) 0px 0px 1px;
|
||||
color: rgb(0, 255, 0);
|
||||
background-color: rgba(0, 255, 0);
|
||||
border: unset;
|
||||
|
||||
&:hover::after {
|
||||
background-color: rgba(0, 255, 0, 0.2);
|
||||
}
|
||||
}
|
||||
|
||||
&.layui-btn-danger {
|
||||
text-shadow: rgb(255, 0, 0) 0px 0px 1px;
|
||||
color: rgb(255, 0, 0);
|
||||
background-color: rgb(255, 0, 0);
|
||||
border: unset;
|
||||
|
||||
&:hover::after {
|
||||
background-color: rgba(255, 0, 0, 0.2);
|
||||
}
|
||||
}
|
||||
|
||||
&.layuimini-btn-primary {
|
||||
text-shadow: rgb(255, 255, 153) 0px 0px 1px;
|
||||
color: rgb(255, 255, 153);
|
||||
background-color: rgb(255, 255, 153);
|
||||
border: unset;
|
||||
|
||||
&:hover::after {
|
||||
background-color: rgba(255, 255, 153, 0.2);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
&.layui-btn-primary {
|
||||
border: unset;
|
||||
}
|
||||
|
||||
&.layui-btn-normal {
|
||||
color: $black-color;
|
||||
background-color: $main-color;
|
||||
border: unset;
|
||||
|
||||
&::before {
|
||||
background-color: $main-color;
|
||||
}
|
||||
|
||||
&:hover::after {
|
||||
background-color: $main-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.layui-table {
|
||||
background: $black-color;
|
||||
color: $main-color;
|
||||
|
||||
|
||||
tr {
|
||||
background-color: $cover-color;
|
||||
}
|
||||
|
||||
td {
|
||||
border-color: $less-main-color;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.layui-table-header {
|
||||
background-color: $black-color;
|
||||
}
|
||||
|
||||
.layuimini-container .layui-table-box {
|
||||
border-color: $less-main-color;
|
||||
}
|
||||
|
||||
.layuimini-container .layui-table-box .layui-table-header th {
|
||||
color: $main-color !important;
|
||||
}
|
||||
|
||||
.layui-table-tool .layui-inline[lay-event] {
|
||||
color: $main-color;
|
||||
border: none;
|
||||
position: relative;
|
||||
|
||||
&::after {
|
||||
border-color: $main-color;
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
clip-path: $box-shape;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: calc(100% - 1px);
|
||||
height: calc(100% - 1px);
|
||||
content: '';
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
.layui-table tbody tr:hover {
|
||||
background-color: rgba(126, 252, 246, 0.1);
|
||||
}
|
||||
|
||||
.layuimini-main {
|
||||
border-color: $less-main-color;
|
||||
}
|
||||
|
||||
.layui-table-header {
|
||||
border-color: $less-main-color;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.color-content>ul>li>a>div>span:nth-child(2) {
|
||||
background-color: $black-color !important;
|
||||
}
|
||||
|
||||
.layuimini-color .elem-content li {
|
||||
clip-path: $box-shape;
|
||||
}
|
||||
|
||||
.layuimini-color .elem-content li.layui-this {
|
||||
background-color: $main-color;
|
||||
color: $black-color !important;
|
||||
border-color: $less-main-color;
|
||||
}
|
||||
|
||||
.layuimini-color .more-menu-item {
|
||||
color: $main-color;
|
||||
|
||||
&:hover {
|
||||
background-color: rgba(62, 251, 251, 0.05);
|
||||
}
|
||||
}
|
||||
|
||||
.layui-layout-admin .layui-header {
|
||||
background-color: $cover-color !important;
|
||||
}
|
||||
|
||||
.layuimini-tab .layui-tab-title {
|
||||
background-color: $cover-color !important;
|
||||
border-color: $less-main-color;
|
||||
|
||||
}
|
||||
|
||||
.layuimini-tab .layui-tab-title span {
|
||||
color: $active-color;
|
||||
}
|
||||
|
||||
.layui-header .layuimini-menu-header-pc.layui-nav .layui-nav-item a:hover,
|
||||
.layui-header .layuimini-header-menu.layuimini-pc-show.layui-nav .layui-this a {
|
||||
color: $black-color !important;
|
||||
}
|
||||
|
||||
.layui-layout-admin .layui-header .layui-nav .layui-nav-item a {
|
||||
color: $main-color !important;
|
||||
}
|
||||
|
||||
.layui-layout-admin .layui-header .layui-nav .layui-nav-item {
|
||||
background-color: $active-color;
|
||||
|
||||
}
|
||||
|
||||
|
||||
.layui-layout-admin .layui-header .layuimini-header-content>ul>.layui-nav-item.layui-this,
|
||||
.layuimini-tool i:hover {
|
||||
background-color: $main-color !important;
|
||||
}
|
||||
|
||||
.layuimini-tab .layui-tab-control>li {
|
||||
background-color: $black-color;
|
||||
border-color: $less-main-color;
|
||||
}
|
||||
|
||||
.layuimini-tab .layui-tab-title li {
|
||||
border-color: $less-main-color;
|
||||
}
|
||||
|
||||
.layui-flow-more a *,
|
||||
.layui-laypage input,
|
||||
.layui-table-view select[lay-ignore] {
|
||||
border-color: $less-main-color;
|
||||
background-color: $black-color;
|
||||
color: $main-color;
|
||||
}
|
||||
|
||||
.layui-laypage button,
|
||||
.layui-laypage input {
|
||||
border-color: $less-main-color;
|
||||
background-color: $black-color;
|
||||
color: $main-color;
|
||||
|
||||
}
|
||||
|
||||
.layuimini-container .layui-form-switch {
|
||||
border-color: $less-main-color !important;
|
||||
background-color: $black-color !important;
|
||||
|
||||
}
|
||||
|
||||
.layuimini-container .layui-form-onswitch {
|
||||
background-color: $main-color !important;
|
||||
}
|
||||
|
||||
.layuimini-container .layui-form-switch.layui-form-onswitch i {
|
||||
background-color: $black-color !important;
|
||||
}
|
||||
.layuimini-container .layui-laypage .layui-laypage-curr .layui-laypage-em {
|
||||
background-color: $main-color !important;
|
||||
}
|
||||
|
||||
.layui-laypage .layui-laypage-curr em {
|
||||
color: $black-color !important;
|
||||
}
|
||||
|
||||
.layuimini-tab .layui-tab-title .layui-this .layuimini-tab-active {
|
||||
background-color: $less-main-color;
|
||||
|
||||
}
|
||||
|
||||
.layui-table-view .layui-form-checkbox.layui-form-checked[lay-skin="primary"] i {
|
||||
border-color: $main-color;
|
||||
background-color: $main-color;
|
||||
color: $black-color;
|
||||
}
|
||||
|
||||
.layui-table-view .layui-form-checkbox[lay-skin="primary"] i {
|
||||
background-color: $cover-color;
|
||||
}
|
||||
|
||||
.layui-table-init {
|
||||
background-color: $black-color;
|
||||
}
|
||||
|
||||
.box-border-line {
|
||||
position: relative;
|
||||
border: 1px solid $less-main-color;
|
||||
border-width: 1px;
|
||||
$border-offset: 3px;
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
width: 50px;
|
||||
height: 20px;
|
||||
transition: all 0.2s;
|
||||
border: 1px solid $less-main-color;
|
||||
top: -$border-offset;
|
||||
left: -$border-offset;
|
||||
border-right: none;
|
||||
border-bottom: none;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
&::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
width: 50px;
|
||||
height: 20px;
|
||||
transition: all 0.2s;
|
||||
border: 1px solid $less-main-color;
|
||||
bottom: -$border-offset;
|
||||
right: -$border-offset;
|
||||
border-left: none;
|
||||
border-top: none;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
|
||||
&::after,
|
||||
&::before {
|
||||
width: calc(100% + $border-offset);
|
||||
height: calc(100% + $border-offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.table-search-fieldset {
|
||||
.layui-input-inline {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.layui-form-item:not(:last-child) {
|
||||
margin-right: 10px;
|
||||
@extend .box-border-line;
|
||||
}
|
||||
|
||||
.layui-form-label {
|
||||
border: unset;
|
||||
}
|
||||
}
|
||||
|
||||
.layui-form-pane .layui-form-label {
|
||||
background-color: $cover-color;
|
||||
color: $main-color;
|
||||
}
|
||||
|
||||
.layuimini-container .table-search-fieldset {
|
||||
color: $main-color;
|
||||
border-color: $less-main-color;
|
||||
|
||||
}
|
||||
|
||||
.layui-form-select,
|
||||
.layui-form-autocomplete {
|
||||
dl {
|
||||
|
||||
color: $main-color;
|
||||
background-color: $black-color;
|
||||
border-color: $less-main-color;
|
||||
|
||||
dd {
|
||||
&.layui-this {
|
||||
background-color: $main-color !important;
|
||||
color: $black-color;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: $less-main-color !important;
|
||||
color: $black-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.layui-iconpicker-item,
|
||||
.layui-iconpicker-item:hover {
|
||||
border-color: $less-main-color !important;
|
||||
color: $black-color;
|
||||
|
||||
.layui-iconpicker-icon:hover {
|
||||
border-color: $less-main-color !important;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.layui-nav-child {
|
||||
background-color: $black-color;
|
||||
color: $main-color;
|
||||
}
|
||||
|
||||
.layui-layout-admin .layui-header .layui-nav .layui-nav-item .layui-nav-child a {
|
||||
color: $main-color !important;
|
||||
}
|
||||
|
||||
.layui-badge,
|
||||
.layui-badge-dot,
|
||||
.layui-badge-rim {
|
||||
background-color: $main-color;
|
||||
}
|
||||
|
||||
.layui-nav .layui-nav-child a:hover {
|
||||
background-color: $active-color;
|
||||
}
|
||||
|
||||
.layui-table-tool-panel {
|
||||
background-color: $black-color;
|
||||
}
|
||||
|
||||
.layui-form-checkbox[lay-skin="primary"] span {
|
||||
color: $main-color;
|
||||
}
|
||||
|
||||
.layui-table-tool-panel li:hover {
|
||||
background-color: $active-color;
|
||||
}
|
||||
|
||||
.layui-side.layui-bg-black,
|
||||
.layui-side.layui-bg-black>.layuimini-menu-left>ul,
|
||||
.layuimini-menu-left-zoom>ul {
|
||||
background-color: $black-color !important;
|
||||
|
||||
}
|
||||
|
||||
.layui-side {
|
||||
border-right: 1px solid $main-color;
|
||||
}
|
||||
|
||||
.layui-bg-blue {
|
||||
background-color: #0000ff !important;
|
||||
}
|
||||
|
||||
.layui-bg-orange {
|
||||
background-color: $yellow-color !important;
|
||||
color: $black-color !important;
|
||||
}
|
||||
|
||||
.layui-bg-green {
|
||||
background-color: $green-color !important;
|
||||
color: $black-color !important;
|
||||
}
|
||||
|
||||
.layui-table-hover {
|
||||
background-color: $cover-color;
|
||||
}
|
||||
|
||||
.layui-table-grid-down {
|
||||
background-color: $black-color;
|
||||
color: $main-color;
|
||||
border-color: unset;
|
||||
}
|
||||
|
||||
.layui-table-tips-main {
|
||||
background-color: $main-color;
|
||||
color: $black-color;
|
||||
}
|
||||
|
||||
.layui-layout-admin .layui-header .layuimini-tool i {
|
||||
color: $main-color;
|
||||
}
|
||||
|
||||
.color-red {
|
||||
color: $red-color !important;
|
||||
}
|
||||
|
||||
.layuimini-tab .layui-tab-title .layui-this span {
|
||||
color: $main-color;
|
||||
}
|
||||
|
||||
.layui-card {
|
||||
|
||||
background-color: $cover-color;
|
||||
border-radius: 0;
|
||||
|
||||
@extend .box-border-line;
|
||||
|
||||
.layui-card-header {
|
||||
color: $main-color;
|
||||
}
|
||||
}
|
||||
|
||||
.layui-text {
|
||||
color: $main-color;
|
||||
}
|
||||
|
||||
|
||||
.layuimini-qiuck-module {
|
||||
cursor: pointer;
|
||||
|
||||
a i {
|
||||
background-color: $cover-color;
|
||||
color: $active-color;
|
||||
}
|
||||
|
||||
a cite {
|
||||
color: $active-color;
|
||||
}
|
||||
|
||||
|
||||
&:hover {
|
||||
a i {
|
||||
background-color: $active-color;
|
||||
color: $main-color;
|
||||
}
|
||||
|
||||
a cite {
|
||||
color: $main-color;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
.layui-bg-number {
|
||||
background-color: $cover-color;
|
||||
}
|
||||
|
||||
.layui-input,
|
||||
.layui-select,
|
||||
.layui-textarea,
|
||||
.city-picker-span,
|
||||
.main-input {
|
||||
background-color: $cover-color;
|
||||
color: $main-color;
|
||||
}
|
||||
|
||||
.city-picker-span>.title>span {
|
||||
color: $main-color;
|
||||
|
||||
&:hover {
|
||||
background-color: $main-color;
|
||||
color: $black-color;
|
||||
}
|
||||
}
|
||||
|
||||
.layui-form-radio:hover *,
|
||||
.layui-form-radioed,
|
||||
.layui-form-radioed>i {
|
||||
color: $main-color;
|
||||
}
|
||||
|
||||
.layui-form-checked[lay-skin="primary"] i {
|
||||
border-color: $main-color !important;
|
||||
background-color: $main-color;
|
||||
color: $black-color;
|
||||
}
|
||||
|
||||
.layui-input:focus,
|
||||
.layui-textarea:focus {
|
||||
border-color: $main-color !important;
|
||||
}
|
||||
|
||||
.layui-input:hover,
|
||||
.layui-textarea:hover {
|
||||
border-color: $main-color !important;
|
||||
|
||||
}
|
||||
|
||||
.layui-badge-rim,
|
||||
.layui-border,
|
||||
.layui-colla-content,
|
||||
.layui-colla-item,
|
||||
.layui-collapse,
|
||||
.layui-elem-field,
|
||||
.layui-form-pane .layui-form-item[pane],
|
||||
.layui-form-pane .layui-form-label,
|
||||
.layui-input,
|
||||
.layui-layedit,
|
||||
.layui-layedit-tool,
|
||||
.layui-panel,
|
||||
.layui-quote-nm,
|
||||
.layui-select,
|
||||
.layui-tab-bar,
|
||||
.layui-tab-card,
|
||||
.layui-tab-title,
|
||||
.layui-tab-title .layui-this::after,
|
||||
.layui-textarea {
|
||||
border-color: $main-color !important;
|
||||
}
|
||||
|
||||
.form-search .layui-input-inline input,
|
||||
.form-search .layui-input-inline select {
|
||||
border-width: 0 0 0 1px;
|
||||
}
|
||||
|
||||
.layuimini-tab .layui-tab-tool .layui-nav-child {
|
||||
border-color: $main-color;
|
||||
}
|
||||
|
||||
.layui-nav .layui-nav-child a {
|
||||
color: $main-color;
|
||||
}
|
||||
|
||||
.layui-form-item {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.layuimini-upload .layuimini-upload-btn {
|
||||
background-color: $black-color;
|
||||
}
|
||||
|
||||
.layui-layer {
|
||||
border: 1px solid $main-color;
|
||||
background-color: $black-color;
|
||||
}
|
||||
|
||||
.layui-layer-easy .layui-layer-title {
|
||||
background-color: $plus-main-color !important;
|
||||
color: $main-color !important;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.layui-table td,
|
||||
.layui-table th,
|
||||
.layui-table-col-set,
|
||||
.layui-table-fixed-r,
|
||||
.layui-table-grid-down,
|
||||
.layui-table-header,
|
||||
.layui-table-page,
|
||||
.layui-table-tips-main,
|
||||
.layui-table-tool,
|
||||
.layui-table-total,
|
||||
.layui-table-view,
|
||||
.layui-table[lay-skin="line"],
|
||||
.layui-table[lay-skin="row"] {
|
||||
border-color: $less-main-color;
|
||||
}
|
||||
|
||||
.layui-table tbody tr:hover,
|
||||
.layui-table thead tr,
|
||||
.layui-table-click,
|
||||
.layui-table-header,
|
||||
.layui-table-hover,
|
||||
.layui-table-mend,
|
||||
.layui-table-patch,
|
||||
.layui-table-tool,
|
||||
.layui-table-total,
|
||||
.layui-table-total tr {
|
||||
background-color: $black-color;
|
||||
}
|
||||
|
||||
.hr-line {
|
||||
color: $main-color;
|
||||
border-color: $less-main-color;
|
||||
background-color: $main-color;
|
||||
}
|
||||
|
||||
.layui-layer-easy .layui-layer-btn {
|
||||
background-color: $black-color;
|
||||
border-top: 1px solid $less-main-color;
|
||||
}
|
||||
|
||||
.layui-layer-easy .layui-layer-btn .layui-layer-btn0 {
|
||||
background-color: $main-color;
|
||||
border-color: $less-main-color;
|
||||
color: $main-color !important;
|
||||
clip-path: $box-shape;
|
||||
}
|
||||
|
||||
.layui-layer-easy .layui-layer-btn a {
|
||||
@extend .layui-btn
|
||||
}
|
||||
|
||||
.layui-layer-shade {
|
||||
background-color: #fff !important;
|
||||
}
|
||||
|
||||
.layuimini-menu-left {
|
||||
.layui-nav-tree .layui-nav-item {
|
||||
|
||||
margin: 5px;
|
||||
width: calc(100% - 10px);
|
||||
}
|
||||
|
||||
.layui-nav .layui-nav-item {
|
||||
clip-path: $box-shape;
|
||||
color: $main-color;
|
||||
background-color: $active-color;
|
||||
|
||||
&.layui-this a {
|
||||
background-color: $main-color !important;
|
||||
color: $black-color !important;
|
||||
}
|
||||
|
||||
&.layui-this {
|
||||
background-color: $main-color !important;
|
||||
color: $black-color !important;
|
||||
|
||||
span {
|
||||
background-color: $main-color !important;
|
||||
color: $black-color !important;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.layui-nav .layui-nav-item a:hover {
|
||||
background-color: $active-color !important;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.layuimini-menu-left .layui-nav .layui-nav-item a,
|
||||
.layuimini-menu-left-zoom.layui-nav .layui-nav-item a {
|
||||
color: $main-color !important;
|
||||
}
|
||||
|
||||
.layuimini-menu-left .layui-nav-item a span {
|
||||
color: $main-color !important;
|
||||
|
||||
}
|
||||
|
||||
.layuimini-menu-left .layui-nav-item:hover a span {
|
||||
color: $black-color !important;
|
||||
|
||||
}
|
||||
|
||||
.layui-layout-admin .layuimini-logo {
|
||||
background-color: $black-color !important;
|
||||
|
||||
}
|
||||
|
||||
.layuimini-menu-left .layui-nav-itemed>.layui-nav-child {
|
||||
background-color: $black-color !important;
|
||||
}
|
||||
|
||||
.layuimini-menu-left .layui-nav-tree .layui-this,
|
||||
.layuimini-menu-left .layui-nav-tree .layui-this>a,
|
||||
.layuimini-menu-left .layui-nav-tree .layui-nav-child dd.layui-this,
|
||||
.layuimini-menu-left .layui-nav-tree .layui-nav-child dd.layui-this a,
|
||||
.layuimini-menu-left-zoom.layui-nav-tree .layui-this,
|
||||
.layuimini-menu-left-zoom.layui-nav-tree .layui-this>a,
|
||||
.layuimini-menu-left-zoom.layui-nav-tree .layui-nav-child dd.layui-this,
|
||||
.layuimini-menu-left-zoom.layui-nav-tree .layui-nav-child dd.layui-this a {
|
||||
background-color: $main-color !important;
|
||||
color: $black-color !important;
|
||||
|
||||
.layui-left-nav {
|
||||
color: $black-color !important;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.layui-iconpicker-icon {
|
||||
border-color: $less-main-color !important;
|
||||
background-color: $less-main-color !important;
|
||||
}
|
||||
|
||||
.layui-iconpicker .layui-anim {
|
||||
background-color: $black-color;
|
||||
}
|
||||
|
||||
.layui-iconpicker .layui-iconpicker-list {
|
||||
background-color: $black-color;
|
||||
}
|
||||
|
||||
.layui-header .layui-nav .layui-nav-child dd.layui-this a,
|
||||
.layui-header .layui-nav-child dd.layui-this,
|
||||
.layui-layout-admin .layui-header .layui-nav .layui-nav-item .layui-nav-child .layui-this a {
|
||||
background-color: $active-color !important;
|
||||
}
|
||||
81
public/static/admin/css/themes/_demo.scss
Normal file
81
public/static/admin/css/themes/_demo.scss
Normal file
@@ -0,0 +1,81 @@
|
||||
.layui-btn {
|
||||
color : #808185 !important;
|
||||
background-color: #cde7ff !important;
|
||||
border : 1px solid #d3dde6 !important;
|
||||
}
|
||||
|
||||
.layui-layer-easy .layui-layer-title {
|
||||
background-color: rgb(215, 215, 215) !important;
|
||||
color : #6C6E71 !important;
|
||||
}
|
||||
|
||||
.layui-layer-easy .layui-layer-setwin>a::after {
|
||||
color: #6C6E71 !important;
|
||||
}
|
||||
|
||||
.layui-layer-easy .layui-layer-btn .layui-layer-btn0 {
|
||||
color : #808185 !important;
|
||||
background-color: #cde7ff !important;
|
||||
border : 1px solid #d3dde6 !important;
|
||||
}
|
||||
|
||||
.layuimini-tab .layui-tab-title .layuimini-tab-active {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.layuimini-tab .layui-tab-title li {
|
||||
padding : 0 5px !important;
|
||||
font-size : 12px;
|
||||
border-width: 1px 1px 1px 0 !important;
|
||||
border-style: solid !important;
|
||||
|
||||
}
|
||||
|
||||
.layuimini-tab .layui-tab-title li.layui-this {
|
||||
color : #fff !important;
|
||||
border-color: rgba(0, 0, 255, 1) !important;
|
||||
background : rgba(90, 173, 255, 1) !important;
|
||||
}
|
||||
|
||||
.layuimini-tab .layui-tab-title .layui-this span {
|
||||
color: #fff !important;
|
||||
}
|
||||
|
||||
.layuimini-tab>.layui-tab-title li,
|
||||
.layuimini-tab>.close-box li {
|
||||
line-height: 27px !important;
|
||||
}
|
||||
|
||||
.layuimini-tab>.layui-tab-title,
|
||||
.layuimini-tab>.close-box {
|
||||
height: 28px !important;
|
||||
}
|
||||
|
||||
.layuimini-tab .layui-tab-control>li {
|
||||
height : 28px !important;
|
||||
line-height: 28px !important;
|
||||
}
|
||||
|
||||
.layuimini-container .layui-laypage .layui-laypage-curr .layui-laypage-em {
|
||||
background-color: #6C6E71 !important;
|
||||
}
|
||||
|
||||
.layuimini-container .layui-form-onswitch {
|
||||
background-color: #cde7ff !important;
|
||||
border-color : #cde7ff !important;
|
||||
}
|
||||
|
||||
.layuimini-container .layui-form-switch {
|
||||
|
||||
background-color: #6C6E71;
|
||||
border-color : #6C6E71;
|
||||
}
|
||||
|
||||
.layui-table-tool .layui-inline[lay-event] {
|
||||
border-color: transparent;
|
||||
}
|
||||
|
||||
.layui-form-checked[lay-skin="primary"] i {
|
||||
border-color : #cde7ff !important;
|
||||
background-color: #cde7ff !important;
|
||||
}
|
||||
708
public/static/admin/css/themes/_gtk.scss
Normal file
708
public/static/admin/css/themes/_gtk.scss
Normal file
@@ -0,0 +1,708 @@
|
||||
& {
|
||||
background-color: #f6f5f4;
|
||||
color : #2e3436;
|
||||
}
|
||||
|
||||
.layuimini-container {}
|
||||
|
||||
.layuimini-main {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.layuimini-container .layui-table-box .layui-table-header th {
|
||||
color : #979a9b !important;
|
||||
font-weight : 700 !important;
|
||||
font-weight : bold;
|
||||
text-shadow : none;
|
||||
border-color : #d7d2ce;
|
||||
border-bottom: 1px solid;
|
||||
|
||||
&:not(:last-child) {
|
||||
|
||||
border-right: 1px solid #d7d2ce;
|
||||
}
|
||||
}
|
||||
|
||||
.layui-table-view .layui-table td {
|
||||
|
||||
border-bottom: unset;
|
||||
|
||||
&:not(:last-child) {
|
||||
border-right: 1px solid #d7d2ce;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
.layui-table {
|
||||
color : #2e3436;
|
||||
background: #f6f5f4;
|
||||
}
|
||||
|
||||
.layui-table-view .layui-table[lay-size="sm"] .layui-table-cell {
|
||||
line-height: 30px;
|
||||
}
|
||||
|
||||
.layui-table tbody tr:hover,
|
||||
.layui-table thead tr,
|
||||
.layui-table-click,
|
||||
.layui-table-header,
|
||||
.layui-table-hover,
|
||||
.layui-table-mend,
|
||||
.layui-table-patch,
|
||||
.layui-table-tool,
|
||||
.layui-table-total,
|
||||
.layui-table-total tr {
|
||||
background-color: unset;
|
||||
}
|
||||
|
||||
.layui-table-cell {
|
||||
padding: 0 4px;
|
||||
}
|
||||
|
||||
.layui-table img {
|
||||
height: 25px !important;
|
||||
width : auto !important;
|
||||
}
|
||||
|
||||
.layui-btn {
|
||||
position : relative;
|
||||
outline : none;
|
||||
overflow : visible;
|
||||
line-height : 28px;
|
||||
border-radius : 5px;
|
||||
transition : all .15s cubic-bezier(.25, .46, .45, .94);
|
||||
padding : 4px 9px;
|
||||
user-select : none;
|
||||
color : #2e3436;
|
||||
outline-color : rgba(53, 132, 228, .5);
|
||||
border : 1px solid #cdc7c2;
|
||||
border-bottom-color: rgb(205, 199, 194);
|
||||
border-bottom-color: #bfb8b1;
|
||||
background-color : #f6f5f4;
|
||||
box-shadow : inset 0 1px #fff, 0 1px 2px rgba(0, 0, 0, .07);
|
||||
|
||||
&::before {
|
||||
content : ' ';
|
||||
position : absolute;
|
||||
pointer-events: none;
|
||||
width : 100%;
|
||||
height : 100%;
|
||||
top : 0px;
|
||||
left : 0px;
|
||||
background : linear-gradient(to top, rgba(0, 0, 0, 0.03), transparent);
|
||||
transition : all 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94);
|
||||
}
|
||||
|
||||
&::after {
|
||||
content : '';
|
||||
position : absolute;
|
||||
pointer-events: none;
|
||||
z-index : 2;
|
||||
display : inline-block;
|
||||
border : 2px solid transparent;
|
||||
border-radius : inherit;
|
||||
transition : all 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94);
|
||||
top : -4px;
|
||||
left : -4px;
|
||||
width : calc(100% - -4px);
|
||||
height : calc(100% - -4px);
|
||||
}
|
||||
|
||||
&.layui-btn-normal {
|
||||
color : #fff;
|
||||
border-color : #1b6acb #1b6acb #15539e;
|
||||
background-color: #3c88e5;
|
||||
box-shadow : inset 0 1px #3181e3, 0 1px 2px rgba(0, 0, 0, .07);
|
||||
}
|
||||
|
||||
&.layui-btn-danger {
|
||||
color : #fff;
|
||||
border-color : #b2161d #b2161d #851015;
|
||||
background-color: #e41f28;
|
||||
box-shadow : inset 0 1px #db1a23, 0 1px 2px rgba(0, 0, 0, .07);
|
||||
}
|
||||
|
||||
&.layui-btn-sm {
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
&.layui-btn-xs {
|
||||
line-height: 12px
|
||||
}
|
||||
}
|
||||
|
||||
.layuimini-container .layui-table-tool .layui-inline[lay-event] {
|
||||
@extend .layui-btn;
|
||||
|
||||
line-height : 32px;
|
||||
min-width : 32px;
|
||||
min-height : 32px;
|
||||
padding : 0;
|
||||
border-radius: 9999px;
|
||||
}
|
||||
|
||||
.layui-laydate .layui-this {
|
||||
background-color: #3584e4 !important;
|
||||
|
||||
}
|
||||
|
||||
.layui-laydate-content td,
|
||||
.layui-laydate-content th {
|
||||
|
||||
width : 36px;
|
||||
height : 36px;
|
||||
border-radius: 100%;
|
||||
}
|
||||
|
||||
.laydate-footer-btns span {
|
||||
@extend .layui-btn;
|
||||
|
||||
line-height: 16px;
|
||||
|
||||
&:not(:last-child) {
|
||||
border-right-style : none;
|
||||
border-top-right-radius : 0;
|
||||
border-bottom-right-radius: 0;
|
||||
}
|
||||
|
||||
&:not(:first-child) {
|
||||
border-top-left-radius : 0;
|
||||
border-bottom-left-radius: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.layui-laydate-footer span {
|
||||
@extend .layui-btn;
|
||||
line-height: 16px;
|
||||
}
|
||||
|
||||
.layui-laydate-footer span.layui-laydate-preview {
|
||||
line-height: 22px;
|
||||
}
|
||||
|
||||
.layui-form-checked[lay-skin="primary"] i {
|
||||
border-color : #185fb4 !important;
|
||||
background-color: #5094e8;
|
||||
background-image: linear-gradient(0deg, #3987e5, #5094e8);
|
||||
}
|
||||
|
||||
.layui-form-checkbox[lay-skin="primary"]:hover i {
|
||||
border-color : #185fb4;
|
||||
background-image: linear-gradient(0deg, #5094e8, #6ba5eb);
|
||||
}
|
||||
|
||||
.layui-table-view .layui-form-checkbox[lay-skin="primary"] i {
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.layui-table-view .layui-form-checkbox i {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.layui-layer-title {
|
||||
padding : 0 6px;
|
||||
min-height : 46px;
|
||||
border : 1px solid #bfb8b1;
|
||||
border-top-left-radius : 8px;
|
||||
border-top-right-radius: 8px;
|
||||
background : #f1f0ee linear-gradient(0deg, #dfdcd8, #f4f2f1) !important;
|
||||
color : #2e3436 !important;
|
||||
padding-left : 12px;
|
||||
padding-right : 12px;
|
||||
font-weight : bold;
|
||||
}
|
||||
|
||||
.layui-layer {
|
||||
background-color: #f6f5f4;
|
||||
}
|
||||
|
||||
.layui-layer-easy .layui-layer-title~.layui-layer-setwin>a {
|
||||
position : relative;
|
||||
outline : none;
|
||||
overflow : visible;
|
||||
border-radius: 5px;
|
||||
transition : all .15s cubic-bezier(.25, .46, .45, .94);
|
||||
user-select : none;
|
||||
|
||||
outline-color : rgba(53, 132, 228, .5);
|
||||
border : 1px solid #cdc7c2;
|
||||
border-bottom-color: rgb(205, 199, 194);
|
||||
border-bottom-color: #bfb8b1;
|
||||
background-color : #f6f5f4;
|
||||
box-shadow : inset 0 1px #fff, 0 1px 2px rgba(0, 0, 0, .07);
|
||||
height : 20px;
|
||||
line-height : 20px;
|
||||
width : 20px;
|
||||
text-align : center;
|
||||
display : inline-flex;
|
||||
align-items : center;
|
||||
justify-content : center;
|
||||
|
||||
&::after {
|
||||
color: #2e3436 !important;
|
||||
}
|
||||
}
|
||||
|
||||
.layui-layer-setwin {
|
||||
display : flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.layuimini-container .layui-form-switch.layui-form-onswitch {
|
||||
color : #ffffff;
|
||||
border-color : #185fb4;
|
||||
background-color: #3584e4;
|
||||
text-shadow : 0 1px rgba(53, 132, 228, 0.5), 0 0 2px rgba(255, 255, 255, 0.6);
|
||||
}
|
||||
|
||||
.layuimini-container .layui-form-switch {
|
||||
|
||||
border : 1px solid #cdc7c2;
|
||||
border-radius : 20px;
|
||||
color : rgba(46, 52, 54, 0.2);
|
||||
background-color: #e1dedb;
|
||||
text-shadow : 0 1px rgba(0, 0, 0, 0.1);
|
||||
transition : all 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94);
|
||||
}
|
||||
|
||||
.layui-form-switch {
|
||||
height: 20px;
|
||||
width : 40px;
|
||||
}
|
||||
|
||||
.layui-form-switch {
|
||||
|
||||
padding : 0;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
.layui-form-switch.layui-form-onswitch i {
|
||||
top : 0;
|
||||
height : 20px;
|
||||
width : 20px;
|
||||
margin-left: -20px;
|
||||
|
||||
|
||||
}
|
||||
|
||||
.layui-form-switch i {
|
||||
top : 0;
|
||||
height : 20px;
|
||||
width : 20px;
|
||||
margin-left : -5px;
|
||||
border-radius : 50%;
|
||||
transition : all 150ms cubic-bezier(0.25, 0.46, 0.45, 0.94);
|
||||
color : #2e3436;
|
||||
outline-color : rgba(53, 132, 228, 0.5);
|
||||
border-color : #cdc7c2;
|
||||
border-bottom-color: #bfb8b1;
|
||||
background-color : #f6f5f4;
|
||||
box-shadow : inset 0 1px white, 0 1px rgba(0, 0, 0, 0.1), 0 1px 2px rgba(0, 0, 0, 0.07);
|
||||
}
|
||||
|
||||
.layuimini-main {
|
||||
background-color: unset;
|
||||
}
|
||||
|
||||
.layui-tab-title li {
|
||||
transition : none;
|
||||
padding : 3px 12px;
|
||||
min-height : 30px;
|
||||
min-width : 65px;
|
||||
display : flex;
|
||||
justify-content : center;
|
||||
align-items : center;
|
||||
white-space : nowrap;
|
||||
color : #2e3436;
|
||||
font-weight : normal;
|
||||
user-select : none;
|
||||
border : 0;
|
||||
border-top-style : none;
|
||||
border-right-style : none;
|
||||
border-bottom-style: none;
|
||||
border-left-style : none;
|
||||
|
||||
|
||||
|
||||
&:hover {
|
||||
box-shadow : inset 0 -3px #c8c2bc;
|
||||
background-color: #edebe9;
|
||||
}
|
||||
|
||||
&.layui-this {
|
||||
box-shadow : inset 0 -3px #3584e4;
|
||||
background-color: #f1f0ee;
|
||||
}
|
||||
}
|
||||
|
||||
.layui-tab-title {
|
||||
display : flex;
|
||||
align-items : center;
|
||||
flex-direction: row;
|
||||
padding-left : 4px;
|
||||
padding-right : 4px;
|
||||
}
|
||||
|
||||
.layuimini-tab>.layui-tab-title li,
|
||||
.layuimini-tab>.close-box li {
|
||||
line-height: 20px !important;
|
||||
}
|
||||
|
||||
.layuimini-tab .layui-tab-title .layui-this .layuimini-tab-active {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.layuimini-tab .layui-tab-title .layui-this span {
|
||||
color: #2e3436 !important
|
||||
}
|
||||
|
||||
.layuimini-tab .layui-tab-title span {
|
||||
color: #2e3436 !important
|
||||
}
|
||||
|
||||
.layuimini-tab .layui-tab-title .layuimini-tab-active {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.layuimini-tab .layui-tab-title {
|
||||
background-color: #e1dedb;
|
||||
border-color : #cdc7c2;
|
||||
}
|
||||
|
||||
.layui-layer-easy .layui-layer-btn {
|
||||
background-color: #f2f2f2;
|
||||
}
|
||||
|
||||
.layui-layer-dialog .layui-layer-content {
|
||||
background-color: #f2f2f2;
|
||||
|
||||
}
|
||||
|
||||
.layui-layer-easy .layui-layer-btn a {
|
||||
position : relative;
|
||||
outline : none;
|
||||
overflow : visible;
|
||||
line-height : 22px;
|
||||
height : 22px;
|
||||
border-radius : 5px;
|
||||
transition : all .15s cubic-bezier(.25, .46, .45, .94);
|
||||
padding : 4px 9px;
|
||||
user-select : none;
|
||||
color : #2e3436 !important;
|
||||
outline-color : rgba(53, 132, 228, .5);
|
||||
border : 1px solid #cdc7c2;
|
||||
border-bottom-color: rgb(205, 199, 194);
|
||||
border-bottom-color: #bfb8b1;
|
||||
background-color : #f6f5f4;
|
||||
box-shadow : inset 0 1px #fff, 0 1px 2px rgba(0, 0, 0, .07);
|
||||
|
||||
&::before {
|
||||
content : ' ';
|
||||
position : absolute;
|
||||
pointer-events: none;
|
||||
width : 100%;
|
||||
height : 100%;
|
||||
top : 0px;
|
||||
left : 0px;
|
||||
background : linear-gradient(to top, rgba(0, 0, 0, 0.03), transparent);
|
||||
transition : all 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94);
|
||||
}
|
||||
|
||||
&::after {
|
||||
content : '';
|
||||
position : absolute;
|
||||
pointer-events: none;
|
||||
z-index : 2;
|
||||
display : inline-block;
|
||||
border : 2px solid transparent;
|
||||
border-radius : inherit;
|
||||
transition : all 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94);
|
||||
top : -4px;
|
||||
left : -4px;
|
||||
width : calc(100% - -4px);
|
||||
height : calc(100% - -4px);
|
||||
}
|
||||
|
||||
|
||||
&.layui-layer-btn0 {
|
||||
color : #fff !important;
|
||||
border-color : #1b6acb #1b6acb #15539e;
|
||||
background-color: #3c88e5;
|
||||
box-shadow : inset 0 1px #3181e3, 0 1px 2px rgba(0, 0, 0, .07);
|
||||
}
|
||||
}
|
||||
|
||||
.layui-tab-brief {
|
||||
|
||||
&>.layui-tab-title {
|
||||
|
||||
li {
|
||||
@extend .layui-btn;
|
||||
|
||||
|
||||
&:not(:last-child) {
|
||||
border-right-style : none;
|
||||
border-top-right-radius : 0;
|
||||
border-bottom-right-radius: 0;
|
||||
}
|
||||
|
||||
&:not(:first-child) {
|
||||
border-top-left-radius : 0;
|
||||
border-bottom-left-radius: 0;
|
||||
}
|
||||
|
||||
&.layui-this {
|
||||
color : unset;
|
||||
color : #2e3436;
|
||||
border-color : #cdc7c2;
|
||||
background-color: #d6d1cd;
|
||||
box-shadow : inset 0 1px rgba(255, 255, 255, 0);
|
||||
|
||||
&::after {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
box-shadow : unset;
|
||||
background-color: #edebe9;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.layui-form-radio:hover *,
|
||||
.layui-form-radioed,
|
||||
.layui-form-radioed>i {
|
||||
color: #5094e8;
|
||||
}
|
||||
|
||||
.layui-card {
|
||||
.layui-card-header {
|
||||
padding : 0 6px;
|
||||
min-height : 46px;
|
||||
border-width : 1px;
|
||||
border-style : solid;
|
||||
border-color : #bfb8b1;
|
||||
border-top-left-radius : 8px;
|
||||
border-top-right-radius: 8px;
|
||||
background : #f1f0ee linear-gradient(to top, #dfdcd8, #f4f2f1);
|
||||
box-shadow : inset 0 1px rgba(255, 255, 255, 0.8), inset 0 -2px 2px rgba(0, 0, 0, 0.02);
|
||||
|
||||
.icon {
|
||||
color: #979a9b !important;
|
||||
}
|
||||
}
|
||||
|
||||
.layui-card-body {
|
||||
background-color: #f6f5f4;
|
||||
border : 1px solid #cdc7c2;
|
||||
}
|
||||
}
|
||||
|
||||
.layui-btn,
|
||||
.layui-input,
|
||||
.layui-select,
|
||||
.layui-textarea,
|
||||
.layui-upload-button,
|
||||
.city-picker-span {
|
||||
border-radius: 5px;
|
||||
border : 1px solid #cdc7c2;
|
||||
}
|
||||
|
||||
.layui-side.layui-bg-black,
|
||||
.layui-side.layui-bg-black>.layuimini-menu-left>ul,
|
||||
.layuimini-menu-left-zoom>ul {
|
||||
background-color: #f6f5f4 !important;
|
||||
}
|
||||
|
||||
.layuimini-menu-left {
|
||||
background-color: #fbfafa;
|
||||
border-right : 1px solid #cdc7c2;
|
||||
|
||||
.layui-nav {
|
||||
|
||||
li {
|
||||
&:not(:first-child) {
|
||||
border-top: 1px solid #cdc7c2;
|
||||
}
|
||||
|
||||
|
||||
&.layui-this {
|
||||
a {
|
||||
background-color: #347cd3 !important;
|
||||
color : #fff !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.layuimini-menu-left .layui-nav .layui-this a,
|
||||
|
||||
.layuimini-menu-left-zoom.layui-nav .layui-this a {
|
||||
color: #2e3436 !important;
|
||||
}
|
||||
|
||||
|
||||
.layuimini-menu-left .layui-nav .layui-nav-item.layui-this a:hover,
|
||||
.layuimini-menu-left-zoom.layui-nav .layui-nav-item.layui-this a:hover {
|
||||
color: #fff !important;
|
||||
}
|
||||
|
||||
.layuimini-menu-left .layui-nav .layui-nav-item a,
|
||||
.layuimini-menu-left-zoom.layui-nav .layui-nav-item a {
|
||||
color: #2e3436 !important;
|
||||
|
||||
&:hover {
|
||||
color: #2e3436 !important;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.layuimini-menu-left .layui-nav .layui-nav-item a {
|
||||
height : 30px;
|
||||
line-height: 30px;
|
||||
}
|
||||
|
||||
.layuimini-menu-left .layui-nav-itemed>.layui-nav-child {
|
||||
background-color: rgba(46, 52, 54, 0.05) !important;
|
||||
border-top : 1px solid #d7d2ce;
|
||||
|
||||
dd {
|
||||
border-bottom: 1px solid #d7d2ce;
|
||||
}
|
||||
}
|
||||
|
||||
.layuimini-menu-left .layui-nav-tree .layui-this,
|
||||
.layuimini-menu-left .layui-nav-tree .layui-this>a,
|
||||
.layuimini-menu-left .layui-nav-tree .layui-nav-child dd.layui-this,
|
||||
.layuimini-menu-left .layui-nav-tree .layui-nav-child dd.layui-this a,
|
||||
.layuimini-menu-left-zoom.layui-nav-tree .layui-this,
|
||||
.layuimini-menu-left-zoom.layui-nav-tree .layui-this>a,
|
||||
.layuimini-menu-left-zoom.layui-nav-tree .layui-nav-child dd.layui-this,
|
||||
.layuimini-menu-left-zoom.layui-nav-tree .layui-nav-child dd.layui-this a {
|
||||
background-color: #347cd3 !important;
|
||||
color : #fff !important;
|
||||
}
|
||||
|
||||
.layui-layout-admin .layuimini-logo {
|
||||
background-color: unset !important;
|
||||
}
|
||||
|
||||
|
||||
.layuimini-header-menu>li.layui-nav-item {
|
||||
@extend .layui-btn;
|
||||
margin-top : 10px;
|
||||
height : 30px !important;
|
||||
line-height: 30px !important;
|
||||
|
||||
|
||||
&::after {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
&:not(:last-child) {
|
||||
border-right-style : none;
|
||||
border-top-right-radius : 0;
|
||||
border-bottom-right-radius: 0;
|
||||
}
|
||||
|
||||
&:not(:first-child) {
|
||||
border-top-left-radius : 0;
|
||||
border-bottom-left-radius: 0;
|
||||
}
|
||||
|
||||
&:nth-last-child(2) {
|
||||
border-right-style : solid;
|
||||
border-radius : 5px;
|
||||
border-top-left-radius : 0;
|
||||
border-bottom-left-radius: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.layui-layout-admin .layui-header {
|
||||
background-color: #f6f5f4 !important;
|
||||
}
|
||||
|
||||
.layui-layer-dialog {
|
||||
border-radius: 20px;
|
||||
}
|
||||
|
||||
.layui-layer-iframe {
|
||||
border-radius: 20px;
|
||||
}
|
||||
|
||||
.layuimini-tab .layui-tab-control>li {
|
||||
background-color: #e1dedb;
|
||||
border-style : solid;
|
||||
border-color : #cdc7c2;
|
||||
}
|
||||
|
||||
.form-search .layui-btn {
|
||||
height : 32px;
|
||||
line-height: 22px;
|
||||
}
|
||||
|
||||
.form-search .layui-form-select dl {
|
||||
transition : all 80ms cubic-bezier(0.25, 0.46, 0.45, 0.94);
|
||||
background-color : #ffffff;
|
||||
background-clip : padding-box;
|
||||
border : 1px solid rgba(0, 0, 0, 0.23);
|
||||
border-top-left-radius : 0;
|
||||
border-top-right-radius: 0;
|
||||
border-radius : 9px;
|
||||
border-top-left-radius : 0px;
|
||||
border-top-right-radius: 0px;
|
||||
box-shadow : 0 1px 3px 2px rgba(0, 0, 0, 0.08);
|
||||
top : 28px;
|
||||
}
|
||||
|
||||
.layui-form-select dl dd,
|
||||
.layui-form-select dl dt {
|
||||
height : 30px;
|
||||
line-height: 30px;
|
||||
padding : 0 10px;
|
||||
}
|
||||
|
||||
.layuimini-container .layui-form-select dl dd.layui-this {
|
||||
background-color: #3c88e5 !important;
|
||||
}
|
||||
|
||||
.layui-table-header .layui-table {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.layui-header .layui-nav .layui-nav-child dd.layui-this a,
|
||||
.layui-header .layui-nav-child dd.layui-this,
|
||||
.layui-layout-admin .layui-header .layui-nav .layui-nav-item .layui-nav-child .layui-this a {
|
||||
background-color: #3c88e5 !important;
|
||||
}
|
||||
|
||||
.layuimini-mobile-show {
|
||||
.layui-nav-more {
|
||||
top: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.layui-layer-easy .layui-layer-setwin>span {
|
||||
color: #2e3436;
|
||||
}
|
||||
|
||||
.layui-layer-easy .layui-layer-setwin>span:after {
|
||||
|
||||
color: #2e3436;
|
||||
}
|
||||
|
||||
.layui-layer-easy .layui-layer-setwin .layui-layer-max::after,
|
||||
.layui-layer-easy .layui-layer-setwin .layui-layer-max::before {
|
||||
border-color: #2e3436;
|
||||
}
|
||||
|
||||
.layui-layer-easy .layui-layer-setwin .layui-layer-min::before {
|
||||
background-color: #2e3436;
|
||||
}
|
||||
284
public/static/admin/css/themes/_neomorphic.scss
Normal file
284
public/static/admin/css/themes/_neomorphic.scss
Normal file
@@ -0,0 +1,284 @@
|
||||
$main-color:#61677C;
|
||||
|
||||
& {
|
||||
background-color: #EBECF0;
|
||||
}
|
||||
|
||||
.layui-layout-admin .layui-header {
|
||||
background-color: #EBECF0 !important;
|
||||
|
||||
}
|
||||
|
||||
.layuimini-container .layui-btn-success {
|
||||
|
||||
color: #4bb368;
|
||||
}
|
||||
|
||||
.layuimini-container .layui-btn-danger {
|
||||
color: #f56c6c;
|
||||
}
|
||||
|
||||
.layuimini-container .layuimini-btn-primary {
|
||||
color: #2c3e50;
|
||||
}
|
||||
|
||||
.layuimini-container .layui-btn-primary {
|
||||
color: #5f5f5f;
|
||||
}
|
||||
|
||||
.layuimini-container .layui-btn-normal {
|
||||
color: #1e9fff;
|
||||
}
|
||||
|
||||
.layui-btn {
|
||||
border: 0;
|
||||
outline: 0;
|
||||
border-radius: 10px;
|
||||
background-color: #EBECF0;
|
||||
text-shadow: 1px 1px 0 #FFF;
|
||||
color: $main-color;
|
||||
box-shadow: -5px -5px 20px #FFF, 5px 5px 20px #BABECC;
|
||||
transition: all 0.2s ease-in-out;
|
||||
cursor: pointer;
|
||||
font-weight: 600;
|
||||
|
||||
&:hover {
|
||||
box-shadow: -2px -2px 5px #FFF, 2px 2px 5px #BABECC;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.layui-table-tool .layui-inline[lay-event] {
|
||||
@extend .layui-btn;
|
||||
}
|
||||
|
||||
.layuimini-main {
|
||||
@extend .layui-btn;
|
||||
text-shadow: 0.5px 0.5px 0 #fff;
|
||||
}
|
||||
|
||||
.layui-layer {
|
||||
@extend .layui-btn;
|
||||
}
|
||||
|
||||
.layui-layer-easy .layui-layer-title {
|
||||
background-color: transparent !important;
|
||||
color: $main-color !important;
|
||||
}
|
||||
|
||||
.layui-layer-easy .layui-layer-setwin>span {
|
||||
color: $main-color !important;
|
||||
|
||||
&::before {
|
||||
border-color: $main-color !important;
|
||||
}
|
||||
|
||||
&::after {
|
||||
border-color: $main-color !important;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.layui-layer-easy .layui-layer-setwin .layui-layer-min::before {
|
||||
background-color: $main-color !important;
|
||||
}
|
||||
|
||||
.layui-card {
|
||||
@extend .layui-btn;
|
||||
text-shadow: 0.5px 0.5px 0 #fff;
|
||||
}
|
||||
|
||||
.layuimini-container .layui-table-tool {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.layui-table {
|
||||
background-color: #EBECF0;
|
||||
}
|
||||
|
||||
.panel {
|
||||
@extend .layui-btn;
|
||||
text-shadow: 0.5px 0.5px 0 #fff;
|
||||
}
|
||||
|
||||
.layuimini-qiuck-module {
|
||||
@extend .layui-btn;
|
||||
|
||||
i {
|
||||
background-color: transparent
|
||||
}
|
||||
}
|
||||
|
||||
.layui-side.layui-bg-black,
|
||||
.layui-side.layui-bg-black>.layuimini-menu-left>ul,
|
||||
.layuimini-menu-left-zoom>ul {
|
||||
@extend .layui-btn;
|
||||
background-color: #EBECF0 !important;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
|
||||
.layuimini-menu-left .layui-nav .layui-nav-item a,
|
||||
.layuimini-menu-left-zoom.layui-nav .layui-nav-item a {
|
||||
@extend .layui-btn;
|
||||
|
||||
&:hover {
|
||||
box-shadow: -2px -2px 5px #FFF, 2px 2px 5px #BABECC;
|
||||
}
|
||||
}
|
||||
|
||||
.layui-nav-tree .layui-nav-item {
|
||||
margin: 10px;
|
||||
width: calc(100% - 20px);
|
||||
}
|
||||
|
||||
.layuimini-menu-left .layui-nav-itemed>.layui-nav-child {
|
||||
background-color: transparent !important;
|
||||
}
|
||||
|
||||
.layui-nav-tree .layui-nav-child dd {
|
||||
margin: 10px;
|
||||
width: calc(100% - 20px);
|
||||
}
|
||||
|
||||
.layuimini-menu-left .layui-nav-tree .layui-this,
|
||||
.layuimini-menu-left .layui-nav-tree .layui-this>a,
|
||||
.layuimini-menu-left .layui-nav-tree .layui-nav-child dd.layui-this,
|
||||
.layuimini-menu-left .layui-nav-tree .layui-nav-child dd.layui-this a,
|
||||
.layuimini-menu-left-zoom.layui-nav-tree .layui-this,
|
||||
.layuimini-menu-left-zoom.layui-nav-tree .layui-this>a,
|
||||
.layuimini-menu-left-zoom.layui-nav-tree .layui-nav-child dd.layui-this,
|
||||
.layuimini-menu-left-zoom.layui-nav-tree .layui-nav-child dd.layui-this a {
|
||||
background-color: inherit !important;
|
||||
}
|
||||
|
||||
.layuimini-menu-left .layui-nav .layui-nav-item a:hover,
|
||||
.layuimini-menu-left .layui-nav .layui-this a,
|
||||
.layuimini-menu-left-zoom.layui-nav .layui-nav-item a:hover,
|
||||
.layuimini-menu-left-zoom.layui-nav .layui-this a {
|
||||
color: $main-color !important;
|
||||
}
|
||||
|
||||
.layui-layout-admin .layuimini-logo {
|
||||
background-color: transparent !important;
|
||||
}
|
||||
|
||||
.layui-header {
|
||||
.layuimini-header-menu>.layui-nav-item {
|
||||
@extend .layui-btn;
|
||||
margin: 10px;
|
||||
line-height: 40px !important;
|
||||
height: 40px !important;
|
||||
}
|
||||
|
||||
.layui-nav .layui-nav-item {
|
||||
@extend .layui-btn;
|
||||
margin: 10px;
|
||||
line-height: 40px !important;
|
||||
height: 40px !important;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.layui-btn-xs {
|
||||
padding: 0 9px;
|
||||
}
|
||||
|
||||
.layui-input,
|
||||
.layui-textarea {
|
||||
border: 0;
|
||||
outline: 0;
|
||||
font-size: 16px;
|
||||
border-radius: 320px;
|
||||
padding: 16px;
|
||||
background-color: #EBECF0;
|
||||
text-shadow: 1px 1px 0 #FFF;
|
||||
margin-right: 8px;
|
||||
box-shadow: inset 2px 2px 5px #BABECC, inset -5px -5px 10px #FFF;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
transition: all 0.2s ease-in-out;
|
||||
appearance: none;
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
|
||||
.layuimini-upload .layuimini-upload-btn {
|
||||
background-color: transparent !important;
|
||||
}
|
||||
|
||||
.layui-form-pane .layui-form-label {
|
||||
background-color: transparent;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.layuimini-container .layui-form-select dl dd.layui-this {
|
||||
background-color: transparent !important;
|
||||
color: #2c3e50
|
||||
}
|
||||
|
||||
.layuimini-color .elem-content li.layui-this {
|
||||
text-shadow: 0.5px 0.5px 0 #FFF;
|
||||
}
|
||||
|
||||
.layui-form-select dl {
|
||||
@extend .layui-btn;
|
||||
}
|
||||
|
||||
.layui-form-checkbox {
|
||||
|
||||
@extend .layui-btn;
|
||||
padding: 10px 10px 10px 24px;
|
||||
}
|
||||
|
||||
.layui-form-checkbox>i {
|
||||
left: 6px;
|
||||
top: 10px;
|
||||
text-shadow: 0.5px 0.5px 0 #fff;
|
||||
}
|
||||
|
||||
.layui-form-checked:hover>div,
|
||||
.layui-form-checked>div {
|
||||
|
||||
color: #16b777;
|
||||
}
|
||||
|
||||
.layui-tree,
|
||||
.laytable-cell-checkbox {
|
||||
|
||||
.layui-form-checkbox[lay-skin="primary"] {
|
||||
padding: 13px;
|
||||
}
|
||||
|
||||
.layui-form-checkbox[lay-skin="primary"]>i {
|
||||
left: 5px;
|
||||
top: 5px
|
||||
}
|
||||
}
|
||||
|
||||
.layui-tree-txt {
|
||||
margin-left: 10px
|
||||
}
|
||||
|
||||
.layui-form-radio {
|
||||
@extend .layui-btn;
|
||||
|
||||
}
|
||||
|
||||
.layui-form-radio:hover>*,
|
||||
.layui-form-radioed,
|
||||
.layui-form-radioed>i {
|
||||
color: #16b777;
|
||||
}
|
||||
|
||||
.layui-table-tips-c {
|
||||
text-shadow: 0.5px 0.5px 0 #fff;
|
||||
|
||||
}
|
||||
|
||||
.layuimini-tab .layui-tab-title {
|
||||
background-color: #EBECF0;
|
||||
}
|
||||
|
||||
.layuimini-tab .layui-tab-control>li {
|
||||
background-color: #EBECF0;
|
||||
}
|
||||
344
public/static/admin/css/themes/_nes.scss
Normal file
344
public/static/admin/css/themes/_nes.scss
Normal file
@@ -0,0 +1,344 @@
|
||||
a,
|
||||
button {
|
||||
cursor: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAzElEQVRYR+2X0Q6AIAhF5f8/2jYXZkwEjNSVvVUjDpcrGgT7FUkI2D9xRfQETwNIiWO85wfINfQUEyxBG2ArsLwC0jioGt5zFcwF4OYDPi/mBYKm4t0U8ATgRm3ThFoAqkhNgWkA0jJLvaOVSs7j3qMnSgXWBMiWPXe94QqMBMBc1VZIvaTu5u5pQewq0EqNZvIEMCmxAawK0DNkay9QmfFNAJUXfgGgUkLaE7j/h8fnASkxHTz0DGIBMCnBeeM7AArpUd3mz2x3C7wADglA8BcWMZhZAAAAAElFTkSuQmCC) 14 0, pointer
|
||||
}
|
||||
|
||||
& {
|
||||
cursor: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAABFklEQVRYR9WXURLDIAhE6/0PbSdOtUpcd1Gnpv1KGpTHBpCE1/cXq+vrMph7dGvXZTtpfW10DCA5jrH1H0Jhs5E0hnZdCR+vb5S8Nn8mQCeS9BdSalYJqMBjAGzq59xAESN7VFVUgV8AZB/dZBR7QTFDCqGquvUBVVoEtgIwpQRzmANSFHgWQKExHdIrPeuMvQNDarXe6nC/AutgV3JW+6bgqQLeV8FekRtgV+ToDKEKnACYKsfZjjkam7a0ZpYTytwmgainpC3HvwBocgKOxqRjehoR9DFKNFYtOwCGYCszobeCbl26N6yyQ6g8X/Wex/rBPsNEV6qAMaJPMynIHQCoSqS9JSMmwef51LflTgCRszU7DvAGiV6mHWfsaVUAAAAASUVORK5CYII=), auto;
|
||||
font-family: "ark-pixel";
|
||||
}
|
||||
|
||||
$border-line-width:3px;
|
||||
|
||||
.public-border {
|
||||
border-style: solid;
|
||||
border-width: $border-line-width;
|
||||
border-image-slice: 2;
|
||||
border-image-width: 2;
|
||||
border-image-repeat: stretch;
|
||||
border-image-source: url('data:image/svg+xml;utf8,<?xml version="1.0" encoding="UTF-8" ?><svg version="1.1" width="5" height="5" xmlns="http://www.w3.org/2000/svg"><path d="M2 1 h1 v1 h-1 z M1 2 h1 v1 h-1 z M3 2 h1 v1 h-1 z M2 3 h1 v1 h-1 z" fill="rgb(33,37,41)" /></svg>');
|
||||
border-image-outset: 2;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.layui-btn {
|
||||
|
||||
@extend .public-border;
|
||||
line-height: 32px;
|
||||
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
cursor: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAzElEQVRYR+2X0Q6AIAhF5f8/2jYXZkwEjNSVvVUjDpcrGgT7FUkI2D9xRfQETwNIiWO85wfINfQUEyxBG2ArsLwC0jioGt5zFcwF4OYDPi/mBYKm4t0U8ATgRm3ThFoAqkhNgWkA0jJLvaOVSs7j3qMnSgXWBMiWPXe94QqMBMBc1VZIvaTu5u5pQewq0EqNZvIEMCmxAawK0DNkay9QmfFNAJUXfgGgUkLaE7j/h8fnASkxHTz0DGIBMCnBeeM7AArpUd3mz2x3C7wADglA8BcWMZhZAAAAAElFTkSuQmCC) 14 0, pointer;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
color: #212529;
|
||||
background-color: #fff;
|
||||
border-image-repeat: stretch;
|
||||
|
||||
&::after {
|
||||
position: absolute;
|
||||
top: -$border-line-width;
|
||||
right: -$border-line-width;
|
||||
bottom: -$border-line-width;
|
||||
left: -$border-line-width;
|
||||
content: "";
|
||||
box-shadow: inset (-$border-line-width) (-$border-line-width) #adafbc;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
color: #212529;
|
||||
text-decoration: none;
|
||||
background-color: #e7e7e7;
|
||||
}
|
||||
|
||||
&.layui-btn-sm {
|
||||
line-height: 100%;
|
||||
}
|
||||
|
||||
&.layui-btn-xs {
|
||||
line-height: 16px;
|
||||
}
|
||||
|
||||
&.layui-btn-normal {
|
||||
color: #fff;
|
||||
background-color: #209cee;
|
||||
|
||||
&::after {
|
||||
box-shadow: inset (-$border-line-width) (-$border-line-width) #006bb3;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: #108de0;
|
||||
}
|
||||
}
|
||||
|
||||
&.layui-btn-success {
|
||||
color: #fff;
|
||||
background-color: #92cc41;
|
||||
|
||||
&::after {
|
||||
box-shadow: inset (-$border-line-width) (-$border-line-width) #4aa52e;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: #92cc41;
|
||||
}
|
||||
}
|
||||
|
||||
&.layui-btn-danger {
|
||||
color: #fff;
|
||||
background-color: #e76e55;
|
||||
|
||||
&::after {
|
||||
box-shadow: inset (-$border-line-width) (-$border-line-width) #8c2022;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: #ce372b;
|
||||
}
|
||||
}
|
||||
|
||||
&.layui-btn-warm {
|
||||
color: #212529;
|
||||
background-color: #f7d51d;
|
||||
|
||||
&::after {
|
||||
box-shadow: inset (-$border-line-width) (-$border-line-width) #e59400;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
color: #212529;
|
||||
background-color: #f2c409;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.form-search .layui-btn {
|
||||
line-height: 16px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
|
||||
.layuimini-container .layui-table-tool .layui-inline[lay-event] {
|
||||
@extend .layui-btn;
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
.layui-table img {
|
||||
image-rendering: pixelated;
|
||||
}
|
||||
|
||||
.layui-form-checkbox[lay-skin="primary"] i {
|
||||
@extend .public-border;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.layui-form-checked[lay-skin="primary"] i {
|
||||
background-color: unset;
|
||||
color: #212529;
|
||||
font-weight: bold;
|
||||
font-size: 28px;
|
||||
}
|
||||
|
||||
.layui-btn {
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.layui-btn-sm {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.layui-btn-xs {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.layui-nav * {
|
||||
font-size: 16px;
|
||||
|
||||
}
|
||||
|
||||
.layui-tab-title li {
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.layui-nav-tree .layui-nav-item {
|
||||
border-bottom: 3px solid #212529;
|
||||
}
|
||||
|
||||
.layuimini-header-menu>.layui-nav-item {
|
||||
|
||||
@extend .public-border;
|
||||
|
||||
border-image-outset: 0;
|
||||
}
|
||||
|
||||
.layui-table td,
|
||||
.layui-table th {
|
||||
font-size: 16px;
|
||||
border-width: 0 2px 2px 0;
|
||||
border-style: solid;
|
||||
border-color: #212529
|
||||
}
|
||||
|
||||
.layui-input,
|
||||
.layui-select,
|
||||
.layui-textarea {
|
||||
@extend .public-border;
|
||||
}
|
||||
|
||||
.layui-form-label {
|
||||
background-color: unset;
|
||||
border: unset;
|
||||
text-align: right;
|
||||
color: #212529;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.layuimini-form>.layui-form-item>.layui-input-block tip,
|
||||
.layuimini-form>.layui-form-item>.layui-inline tip {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.layui-layer-easy .layui-layer-title {
|
||||
background: unset !important;
|
||||
color: #212529 !important;
|
||||
font-size: 16px;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
}
|
||||
|
||||
.layui-layer-easy .layui-layer-btn {
|
||||
background: unset !important;
|
||||
}
|
||||
|
||||
.layui-layer-easy .layui-layer-btn a {
|
||||
@extend .layui-btn;
|
||||
color: #212529 !important;
|
||||
|
||||
&.layui-layer-btn0 {
|
||||
color: #fff !important;
|
||||
background-color: #209cee;
|
||||
|
||||
&::after {
|
||||
box-shadow: inset (-$border-line-width) (-$border-line-width) #006bb3;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: #108de0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.layui-layer-dialog .layui-layer-content {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.layui-layer-easy .layui-layer-setwin>span {
|
||||
color: #212529;
|
||||
}
|
||||
|
||||
.layui-layer-easy .layui-layer-setwin>span:after {
|
||||
|
||||
color: #212529;
|
||||
}
|
||||
|
||||
.layui-layer-easy .layui-layer-setwin .layui-layer-max::after,
|
||||
.layui-layer-easy .layui-layer-setwin .layui-layer-max::before {
|
||||
border-color: #212529;
|
||||
}
|
||||
|
||||
.layui-layer-easy .layui-layer-setwin .layui-layer-min::before {
|
||||
background-color: #212529;
|
||||
}
|
||||
|
||||
|
||||
.layui-layer {
|
||||
@extend .public-border;
|
||||
|
||||
}
|
||||
|
||||
.layui-card {
|
||||
@extend .public-border;
|
||||
|
||||
.layui-card-header {
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.layuimini-main {
|
||||
@extend .public-border;
|
||||
}
|
||||
|
||||
.layui-table-box {
|
||||
@extend .public-border;
|
||||
border-image-outset: 1;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.layuimini-container .layui-table-box .layui-table-header th {
|
||||
|
||||
color: #212529 !important;
|
||||
}
|
||||
|
||||
.layui-table tbody tr:hover,
|
||||
.layui-table thead tr,
|
||||
.layui-table-click,
|
||||
.layui-table-header,
|
||||
.layui-table-hover,
|
||||
.layui-table-mend,
|
||||
.layui-table-patch,
|
||||
.layui-table-tool,
|
||||
.layui-table-total,
|
||||
.layui-table-total tr {
|
||||
background-color: unset;
|
||||
}
|
||||
|
||||
.layui-table-header .layui-table {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.layui-badge,
|
||||
.layui-badge-rim {
|
||||
position: relative;
|
||||
border-radius: 0;
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
pointer-events: none;
|
||||
box-shadow: 0 4px #209cee, 0 -4px #209cee, 4px 0 #209cee, -4px 0 #209cee;
|
||||
}
|
||||
|
||||
&.layui-bg-blue {
|
||||
background-color: #209cee;
|
||||
|
||||
&::after {
|
||||
box-shadow: 0 4px #209cee, 0 -4px #209cee, 4px 0 #209cee, -4px 0 #209cee;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
&.layui-bg-gray {
|
||||
background-color: #92cc41;
|
||||
|
||||
&::after {
|
||||
box-shadow: 0 4px #92cc41, 0 -4px #92cc41, 4px 0 #92cc41, -4px 0 #92cc41;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.layuimini-color .elem-content li {
|
||||
cursor: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAzElEQVRYR+2X0Q6AIAhF5f8/2jYXZkwEjNSVvVUjDpcrGgT7FUkI2D9xRfQETwNIiWO85wfINfQUEyxBG2ArsLwC0jioGt5zFcwF4OYDPi/mBYKm4t0U8ATgRm3ThFoAqkhNgWkA0jJLvaOVSs7j3qMnSgXWBMiWPXe94QqMBMBc1VZIvaTu5u5pQewq0EqNZvIEMCmxAawK0DNkay9QmfFNAJUXfgGgUkLaE7j/h8fnASkxHTz0DGIBMCnBeeM7AArpUd3mz2x3C7wADglA8BcWMZhZAAAAAElFTkSuQmCC) 14 0, pointer;
|
||||
}
|
||||
0
public/static/admin/css/themes/_normal.scss
Normal file
0
public/static/admin/css/themes/_normal.scss
Normal file
802
public/static/admin/css/themes/_sicfi.scss
Normal file
802
public/static/admin/css/themes/_sicfi.scss
Normal file
@@ -0,0 +1,802 @@
|
||||
// 通常用于背景色
|
||||
$black-color :rgb(2, 17, 20);
|
||||
// 通常用于字体颜色
|
||||
$main-color :rgb(126, 252, 246);
|
||||
// 通常用于边框
|
||||
$less-main-color:rgb(6, 216, 215);
|
||||
|
||||
$plus-main-color:rgb(0, 125, 124);
|
||||
|
||||
// 通常用于激活状态,通常跟背景色搭配
|
||||
$cover-color :rgba(62, 251, 251, 0.05);
|
||||
// 更强的激活状态,适合做选项操作时使用
|
||||
$active-color :rgba(62, 251, 251, 0.5);
|
||||
|
||||
|
||||
$red-color :rgb(255, 0, 0);
|
||||
$yellow-color:rgb(255, 255, 153);
|
||||
$green-color :rgb(0, 255, 0);
|
||||
|
||||
& {
|
||||
background-color: $black-color;
|
||||
color: $main-color;
|
||||
}
|
||||
|
||||
.layuimini-main {
|
||||
background-color: $black-color;
|
||||
}
|
||||
|
||||
.layuimini-container {
|
||||
background-color: $black-color;
|
||||
}
|
||||
|
||||
.layuimini-container .layui-table-tool {
|
||||
background-color: $black-color;
|
||||
}
|
||||
|
||||
$box-shape: polygon(0 0, 100% 0, 100% calc(100% - 10px), calc(100% - 10px) 100%, 0 100%, 0 0);
|
||||
|
||||
.layui-btn {
|
||||
|
||||
&.layui-btn-lg {
|
||||
|
||||
padding-right: 25px;
|
||||
}
|
||||
|
||||
clip-path : $box-shape;
|
||||
padding-right : 10px;
|
||||
position : relative;
|
||||
background-color: transparent;
|
||||
border : 1px solid;
|
||||
color : rgb(126, 252, 246);
|
||||
text-shadow : rgb(126, 252, 246) 0px 0px 1px;
|
||||
background-color: rgb(126, 252, 246);
|
||||
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
display: block;
|
||||
position: absolute;
|
||||
z-index: -1;
|
||||
clip-path: $box-shape;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
left: -0.5px;
|
||||
top: -0.5px;
|
||||
background-color: $black-color;
|
||||
}
|
||||
|
||||
&:hover::after {
|
||||
content: '';
|
||||
display: block;
|
||||
position: absolute;
|
||||
z-index: -1;
|
||||
clip-path: $box-shape;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
left: -0.5px;
|
||||
top: -0.5px;
|
||||
background-color: rgba(126, 252, 246, 0.2);
|
||||
}
|
||||
|
||||
&.layui-btn-disabled {
|
||||
&::after {
|
||||
// todo:实现按钮禁用样式
|
||||
}
|
||||
}
|
||||
|
||||
&.layui-btn-success {
|
||||
text-shadow: rgb(0, 255, 0) 0px 0px 1px;
|
||||
color: rgb(0, 255, 0);
|
||||
background-color: rgba(0, 255, 0);
|
||||
border: unset;
|
||||
|
||||
&:hover::after {
|
||||
background-color: rgba(0, 255, 0, 0.2);
|
||||
}
|
||||
}
|
||||
|
||||
&.layui-btn-danger {
|
||||
text-shadow: rgb(255, 0, 0) 0px 0px 1px;
|
||||
color: rgb(255, 0, 0);
|
||||
background-color: rgb(255, 0, 0);
|
||||
border: unset;
|
||||
|
||||
&:hover::after {
|
||||
background-color: rgba(255, 0, 0, 0.2);
|
||||
}
|
||||
}
|
||||
|
||||
&.layuimini-btn-primary {
|
||||
text-shadow: rgb(255, 255, 153) 0px 0px 1px;
|
||||
color: rgb(255, 255, 153);
|
||||
background-color: rgb(255, 255, 153);
|
||||
border: unset;
|
||||
|
||||
&:hover::after {
|
||||
background-color: rgba(255, 255, 153, 0.2);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
&.layui-btn-primary {
|
||||
border: unset;
|
||||
}
|
||||
|
||||
&.layui-btn-normal {
|
||||
color: $black-color;
|
||||
background-color: $main-color;
|
||||
border: unset;
|
||||
|
||||
&::before {
|
||||
background-color: $main-color;
|
||||
}
|
||||
|
||||
&:hover::after {
|
||||
background-color: $main-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.layui-table {
|
||||
background: $black-color;
|
||||
color: $main-color;
|
||||
|
||||
|
||||
tr {
|
||||
background-color: $cover-color;
|
||||
}
|
||||
|
||||
td {
|
||||
border-color: $less-main-color;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.layui-table-header {
|
||||
background-color: $black-color;
|
||||
}
|
||||
|
||||
.layuimini-container .layui-table-box {
|
||||
border-color: $less-main-color;
|
||||
}
|
||||
|
||||
.layuimini-container .layui-table-box .layui-table-header th {
|
||||
color: $main-color !important;
|
||||
}
|
||||
|
||||
.layui-table-tool .layui-inline[lay-event] {
|
||||
color: $main-color;
|
||||
border: none;
|
||||
position: relative;
|
||||
|
||||
&::after {
|
||||
border-color: $main-color;
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
clip-path: $box-shape;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: calc(100% - 1px);
|
||||
height: calc(100% - 1px);
|
||||
content: '';
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
.layui-table tbody tr:hover {
|
||||
background-color: rgba(126, 252, 246, 0.1);
|
||||
}
|
||||
|
||||
.layuimini-main {
|
||||
border-color: $less-main-color;
|
||||
}
|
||||
|
||||
.layui-table-header {
|
||||
border-color: $less-main-color;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.color-content>ul>li>a>div>span:nth-child(2) {
|
||||
background-color: $black-color !important;
|
||||
}
|
||||
|
||||
.layuimini-color .elem-content li {
|
||||
clip-path: $box-shape;
|
||||
}
|
||||
|
||||
.layuimini-color .elem-content li.layui-this {
|
||||
background-color: $main-color;
|
||||
color: $black-color !important;
|
||||
border-color: $less-main-color;
|
||||
}
|
||||
|
||||
.layuimini-color .more-menu-item {
|
||||
color: $main-color;
|
||||
|
||||
&:hover {
|
||||
background-color: rgba(62, 251, 251, 0.05);
|
||||
}
|
||||
}
|
||||
|
||||
.layui-layout-admin .layui-header {
|
||||
background-color: $cover-color !important;
|
||||
}
|
||||
|
||||
.layuimini-tab .layui-tab-title {
|
||||
background-color: $cover-color !important;
|
||||
border-color: $less-main-color;
|
||||
|
||||
}
|
||||
|
||||
.layuimini-tab .layui-tab-title span {
|
||||
color: $active-color;
|
||||
}
|
||||
|
||||
.layui-header .layuimini-menu-header-pc.layui-nav .layui-nav-item a:hover,
|
||||
.layui-header .layuimini-header-menu.layuimini-pc-show.layui-nav .layui-this a {
|
||||
color: $black-color !important;
|
||||
}
|
||||
|
||||
.layui-layout-admin .layui-header .layui-nav .layui-nav-item a {
|
||||
color: $main-color !important;
|
||||
}
|
||||
|
||||
.layui-layout-admin .layui-header .layui-nav .layui-nav-item {
|
||||
background-color: $active-color;
|
||||
|
||||
}
|
||||
|
||||
|
||||
.layui-layout-admin .layui-header .layuimini-header-content>ul>.layui-nav-item.layui-this,
|
||||
.layuimini-tool i:hover {
|
||||
background-color: $main-color !important;
|
||||
}
|
||||
|
||||
.layuimini-tab .layui-tab-control>li {
|
||||
background-color: $black-color;
|
||||
border-color: $less-main-color;
|
||||
}
|
||||
|
||||
.layuimini-tab .layui-tab-title li {
|
||||
border-color: $less-main-color;
|
||||
}
|
||||
|
||||
.layui-flow-more a *,
|
||||
.layui-laypage input,
|
||||
.layui-table-view select[lay-ignore] {
|
||||
border-color: $less-main-color;
|
||||
background-color: $black-color;
|
||||
color: $main-color;
|
||||
}
|
||||
|
||||
.layui-laypage button,
|
||||
.layui-laypage input {
|
||||
border-color: $less-main-color;
|
||||
background-color: $black-color;
|
||||
color: $main-color;
|
||||
|
||||
}
|
||||
|
||||
.layuimini-container .layui-form-switch {
|
||||
border-color: $less-main-color !important;
|
||||
background-color: $black-color !important;
|
||||
|
||||
}
|
||||
|
||||
.layuimini-container .layui-form-onswitch {
|
||||
background-color: $main-color !important;
|
||||
}
|
||||
|
||||
.layuimini-container .layui-form-switch.layui-form-onswitch i {
|
||||
background-color: $black-color !important;
|
||||
}
|
||||
.layuimini-container .layui-laypage .layui-laypage-curr .layui-laypage-em {
|
||||
background-color: $main-color !important;
|
||||
}
|
||||
|
||||
.layui-laypage .layui-laypage-curr em {
|
||||
color: $black-color !important;
|
||||
}
|
||||
|
||||
.layuimini-tab .layui-tab-title .layui-this .layuimini-tab-active {
|
||||
background-color: $less-main-color;
|
||||
|
||||
}
|
||||
|
||||
.layui-table-view .layui-form-checkbox.layui-form-checked[lay-skin="primary"] i {
|
||||
border-color: $main-color;
|
||||
background-color: $main-color;
|
||||
color: $black-color;
|
||||
}
|
||||
|
||||
.layui-table-view .layui-form-checkbox[lay-skin="primary"] i {
|
||||
background-color: $cover-color;
|
||||
}
|
||||
|
||||
.layui-table-init {
|
||||
background-color: $black-color;
|
||||
}
|
||||
|
||||
.box-border-line {
|
||||
position: relative;
|
||||
border: 1px solid $less-main-color;
|
||||
border-width: 1px;
|
||||
$border-offset: 3px;
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
width: 50px;
|
||||
height: 20px;
|
||||
transition: all 0.2s;
|
||||
border: 1px solid $less-main-color;
|
||||
top: -$border-offset;
|
||||
left: -$border-offset;
|
||||
border-right: none;
|
||||
border-bottom: none;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
&::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
width: 50px;
|
||||
height: 20px;
|
||||
transition: all 0.2s;
|
||||
border: 1px solid $less-main-color;
|
||||
bottom: -$border-offset;
|
||||
right: -$border-offset;
|
||||
border-left: none;
|
||||
border-top: none;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
|
||||
&::after,
|
||||
&::before {
|
||||
width: calc(100% + $border-offset);
|
||||
height: calc(100% + $border-offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.table-search-fieldset {
|
||||
.layui-input-inline {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.layui-form-item:not(:last-child) {
|
||||
margin-right: 10px;
|
||||
@extend .box-border-line;
|
||||
}
|
||||
|
||||
.layui-form-label {
|
||||
border: unset;
|
||||
}
|
||||
}
|
||||
|
||||
.layui-form-pane .layui-form-label {
|
||||
background-color: $cover-color;
|
||||
color: $main-color;
|
||||
}
|
||||
|
||||
.layuimini-container .table-search-fieldset {
|
||||
color: $main-color;
|
||||
border-color: $less-main-color;
|
||||
|
||||
}
|
||||
|
||||
.layui-form-select,
|
||||
.layui-form-autocomplete {
|
||||
dl {
|
||||
|
||||
color: $main-color;
|
||||
background-color: $black-color;
|
||||
border-color: $less-main-color;
|
||||
|
||||
dd {
|
||||
&.layui-this {
|
||||
background-color: $main-color !important;
|
||||
color: $black-color;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: $less-main-color !important;
|
||||
color: $black-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.layui-iconpicker-item,
|
||||
.layui-iconpicker-item:hover {
|
||||
border-color: $less-main-color !important;
|
||||
color: $black-color;
|
||||
|
||||
.layui-iconpicker-icon:hover {
|
||||
border-color: $less-main-color !important;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.layui-nav-child {
|
||||
background-color: $black-color;
|
||||
color: $main-color;
|
||||
}
|
||||
|
||||
.layui-layout-admin .layui-header .layui-nav .layui-nav-item .layui-nav-child a {
|
||||
color: $main-color !important;
|
||||
}
|
||||
|
||||
.layui-badge,
|
||||
.layui-badge-dot,
|
||||
.layui-badge-rim {
|
||||
background-color: $main-color;
|
||||
}
|
||||
|
||||
.layui-nav .layui-nav-child a:hover {
|
||||
background-color: $active-color;
|
||||
}
|
||||
|
||||
.layui-table-tool-panel {
|
||||
background-color: $black-color;
|
||||
}
|
||||
|
||||
.layui-form-checkbox[lay-skin="primary"] span {
|
||||
color: $main-color;
|
||||
}
|
||||
|
||||
.layui-table-tool-panel li:hover {
|
||||
background-color: $active-color;
|
||||
}
|
||||
|
||||
.layui-side.layui-bg-black,
|
||||
.layui-side.layui-bg-black>.layuimini-menu-left>ul,
|
||||
.layuimini-menu-left-zoom>ul {
|
||||
background-color: $black-color !important;
|
||||
|
||||
}
|
||||
|
||||
.layui-side {
|
||||
border-right: 1px solid $main-color;
|
||||
}
|
||||
|
||||
.layui-bg-blue {
|
||||
background-color: #0000ff !important;
|
||||
}
|
||||
|
||||
.layui-bg-orange {
|
||||
background-color: $yellow-color !important;
|
||||
color: $black-color !important;
|
||||
}
|
||||
|
||||
.layui-bg-green {
|
||||
background-color: $green-color !important;
|
||||
color: $black-color !important;
|
||||
}
|
||||
|
||||
.layui-table-hover {
|
||||
background-color: $cover-color;
|
||||
}
|
||||
|
||||
.layui-table-grid-down {
|
||||
background-color: $black-color;
|
||||
color: $main-color;
|
||||
border-color: unset;
|
||||
}
|
||||
|
||||
.layui-table-tips-main {
|
||||
background-color: $main-color;
|
||||
color: $black-color;
|
||||
}
|
||||
|
||||
.layui-layout-admin .layui-header .layuimini-tool i {
|
||||
color: $main-color;
|
||||
}
|
||||
|
||||
.color-red {
|
||||
color: $red-color !important;
|
||||
}
|
||||
|
||||
.layuimini-tab .layui-tab-title .layui-this span {
|
||||
color: $main-color;
|
||||
}
|
||||
|
||||
.layui-card {
|
||||
|
||||
background-color: $cover-color;
|
||||
border-radius: 0;
|
||||
|
||||
@extend .box-border-line;
|
||||
|
||||
.layui-card-header {
|
||||
color: $main-color;
|
||||
}
|
||||
}
|
||||
|
||||
.layui-text {
|
||||
color: $main-color;
|
||||
}
|
||||
|
||||
|
||||
.layuimini-qiuck-module {
|
||||
cursor: pointer;
|
||||
|
||||
a i {
|
||||
background-color: $cover-color;
|
||||
color: $active-color;
|
||||
}
|
||||
|
||||
a cite {
|
||||
color: $active-color;
|
||||
}
|
||||
|
||||
|
||||
&:hover {
|
||||
a i {
|
||||
background-color: $active-color;
|
||||
color: $main-color;
|
||||
}
|
||||
|
||||
a cite {
|
||||
color: $main-color;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
.layui-bg-number {
|
||||
background-color: $cover-color;
|
||||
}
|
||||
|
||||
.layui-input,
|
||||
.layui-select,
|
||||
.layui-textarea,
|
||||
.city-picker-span,
|
||||
.main-input {
|
||||
background-color: $cover-color;
|
||||
color: $main-color;
|
||||
}
|
||||
|
||||
.city-picker-span>.title>span {
|
||||
color: $main-color;
|
||||
|
||||
&:hover {
|
||||
background-color: $main-color;
|
||||
color: $black-color;
|
||||
}
|
||||
}
|
||||
|
||||
.layui-form-radio:hover *,
|
||||
.layui-form-radioed,
|
||||
.layui-form-radioed>i {
|
||||
color: $main-color;
|
||||
}
|
||||
|
||||
.layui-form-checked[lay-skin="primary"] i {
|
||||
border-color: $main-color !important;
|
||||
background-color: $main-color;
|
||||
color: $black-color;
|
||||
}
|
||||
|
||||
.layui-input:focus,
|
||||
.layui-textarea:focus {
|
||||
border-color: $main-color !important;
|
||||
}
|
||||
|
||||
.layui-input:hover,
|
||||
.layui-textarea:hover {
|
||||
border-color: $main-color !important;
|
||||
|
||||
}
|
||||
|
||||
.layui-badge-rim,
|
||||
.layui-border,
|
||||
.layui-colla-content,
|
||||
.layui-colla-item,
|
||||
.layui-collapse,
|
||||
.layui-elem-field,
|
||||
.layui-form-pane .layui-form-item[pane],
|
||||
.layui-form-pane .layui-form-label,
|
||||
.layui-input,
|
||||
.layui-layedit,
|
||||
.layui-layedit-tool,
|
||||
.layui-panel,
|
||||
.layui-quote-nm,
|
||||
.layui-select,
|
||||
.layui-tab-bar,
|
||||
.layui-tab-card,
|
||||
.layui-tab-title,
|
||||
.layui-tab-title .layui-this::after,
|
||||
.layui-textarea {
|
||||
border-color: $main-color !important;
|
||||
}
|
||||
|
||||
.form-search .layui-input-inline input,
|
||||
.form-search .layui-input-inline select {
|
||||
border-width: 0 0 0 1px;
|
||||
}
|
||||
|
||||
.layuimini-tab .layui-tab-tool .layui-nav-child {
|
||||
border-color: $main-color;
|
||||
}
|
||||
|
||||
.layui-nav .layui-nav-child a {
|
||||
color: $main-color;
|
||||
}
|
||||
|
||||
.layui-form-item {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.layuimini-upload .layuimini-upload-btn {
|
||||
background-color: $black-color;
|
||||
}
|
||||
|
||||
.layui-layer {
|
||||
border: 1px solid $main-color;
|
||||
background-color: $black-color;
|
||||
}
|
||||
|
||||
.layui-layer-easy .layui-layer-title {
|
||||
background-color: $plus-main-color !important;
|
||||
color: $main-color !important;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.layui-table td,
|
||||
.layui-table th,
|
||||
.layui-table-col-set,
|
||||
.layui-table-fixed-r,
|
||||
.layui-table-grid-down,
|
||||
.layui-table-header,
|
||||
.layui-table-page,
|
||||
.layui-table-tips-main,
|
||||
.layui-table-tool,
|
||||
.layui-table-total,
|
||||
.layui-table-view,
|
||||
.layui-table[lay-skin="line"],
|
||||
.layui-table[lay-skin="row"] {
|
||||
border-color: $less-main-color;
|
||||
}
|
||||
|
||||
.layui-table tbody tr:hover,
|
||||
.layui-table thead tr,
|
||||
.layui-table-click,
|
||||
.layui-table-header,
|
||||
.layui-table-hover,
|
||||
.layui-table-mend,
|
||||
.layui-table-patch,
|
||||
.layui-table-tool,
|
||||
.layui-table-total,
|
||||
.layui-table-total tr {
|
||||
background-color: $black-color;
|
||||
}
|
||||
|
||||
.hr-line {
|
||||
color: $main-color;
|
||||
border-color: $less-main-color;
|
||||
background-color: $main-color;
|
||||
}
|
||||
|
||||
.layui-layer-easy .layui-layer-btn {
|
||||
background-color: $black-color;
|
||||
border-top: 1px solid $less-main-color;
|
||||
}
|
||||
|
||||
.layui-layer-easy .layui-layer-btn .layui-layer-btn0 {
|
||||
background-color: $main-color;
|
||||
border-color: $less-main-color;
|
||||
color: $main-color !important;
|
||||
clip-path: $box-shape;
|
||||
}
|
||||
|
||||
.layui-layer-easy .layui-layer-btn a {
|
||||
@extend .layui-btn
|
||||
}
|
||||
|
||||
.layui-layer-shade {
|
||||
background-color: #fff !important;
|
||||
}
|
||||
|
||||
.layuimini-menu-left {
|
||||
.layui-nav-tree .layui-nav-item {
|
||||
|
||||
margin: 5px;
|
||||
width: calc(100% - 10px);
|
||||
}
|
||||
|
||||
.layui-nav .layui-nav-item {
|
||||
clip-path: $box-shape;
|
||||
color: $main-color;
|
||||
background-color: $active-color;
|
||||
|
||||
&.layui-this a {
|
||||
background-color: $main-color !important;
|
||||
color: $black-color !important;
|
||||
}
|
||||
|
||||
&.layui-this {
|
||||
background-color: $main-color !important;
|
||||
color: $black-color !important;
|
||||
|
||||
span {
|
||||
background-color: $main-color !important;
|
||||
color: $black-color !important;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.layui-nav .layui-nav-item a:hover {
|
||||
background-color: $active-color !important;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.layuimini-menu-left .layui-nav .layui-nav-item a,
|
||||
.layuimini-menu-left-zoom.layui-nav .layui-nav-item a {
|
||||
color: $main-color !important;
|
||||
}
|
||||
|
||||
.layuimini-menu-left .layui-nav-item a span {
|
||||
color: $main-color !important;
|
||||
|
||||
}
|
||||
|
||||
.layuimini-menu-left .layui-nav-item:hover a span {
|
||||
color: $black-color !important;
|
||||
|
||||
}
|
||||
|
||||
.layui-layout-admin .layuimini-logo {
|
||||
background-color: $black-color !important;
|
||||
|
||||
}
|
||||
|
||||
.layuimini-menu-left .layui-nav-itemed>.layui-nav-child {
|
||||
background-color: $black-color !important;
|
||||
}
|
||||
|
||||
.layuimini-menu-left .layui-nav-tree .layui-this,
|
||||
.layuimini-menu-left .layui-nav-tree .layui-this>a,
|
||||
.layuimini-menu-left .layui-nav-tree .layui-nav-child dd.layui-this,
|
||||
.layuimini-menu-left .layui-nav-tree .layui-nav-child dd.layui-this a,
|
||||
.layuimini-menu-left-zoom.layui-nav-tree .layui-this,
|
||||
.layuimini-menu-left-zoom.layui-nav-tree .layui-this>a,
|
||||
.layuimini-menu-left-zoom.layui-nav-tree .layui-nav-child dd.layui-this,
|
||||
.layuimini-menu-left-zoom.layui-nav-tree .layui-nav-child dd.layui-this a {
|
||||
background-color: $main-color !important;
|
||||
color: $black-color !important;
|
||||
|
||||
.layui-left-nav {
|
||||
color: $black-color !important;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.layui-iconpicker-icon {
|
||||
border-color: $less-main-color !important;
|
||||
background-color: $less-main-color !important;
|
||||
}
|
||||
|
||||
.layui-iconpicker .layui-anim {
|
||||
background-color: $black-color;
|
||||
}
|
||||
|
||||
.layui-iconpicker .layui-iconpicker-list {
|
||||
background-color: $black-color;
|
||||
}
|
||||
|
||||
.layui-header .layui-nav .layui-nav-child dd.layui-this a,
|
||||
.layui-header .layui-nav-child dd.layui-this,
|
||||
.layui-layout-admin .layui-header .layui-nav .layui-nav-item .layui-nav-child .layui-this a {
|
||||
background-color: $active-color !important;
|
||||
}
|
||||
288
public/static/admin/css/themes/_win7.scss
Normal file
288
public/static/admin/css/themes/_win7.scss
Normal file
@@ -0,0 +1,288 @@
|
||||
& {
|
||||
color: #222;
|
||||
background-color: #f0f0f0;
|
||||
}
|
||||
|
||||
.layui-btn {
|
||||
background: linear-gradient(180deg, #eee 45%, #ddd 0, #bbb);
|
||||
border: 1.5px solid #888;
|
||||
border-radius: 3px;
|
||||
box-shadow: inset 0 -1px 1px hsla(0, 0%, 100%, .8), inset 0 1px 1px #fff;
|
||||
box-sizing: border-box;
|
||||
color: #222;
|
||||
|
||||
|
||||
&:hover {
|
||||
background: linear-gradient(180deg, #e5f4fd 45%, #b3e0f9 0);
|
||||
border-color: #72a2c5;
|
||||
}
|
||||
}
|
||||
|
||||
.layui-layer-easy .layui-layer-btn a {
|
||||
@extend .layui-btn;
|
||||
color: #222 !important;
|
||||
|
||||
height: 26px;
|
||||
line-height: 26px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.layui-layer-title {
|
||||
background: linear-gradient(90deg, hsla(0, 0%, 100%, .4), rgba(0, 0, 0, .1), hsla(0, 0%, 100%, .2)), linear-gradient(55deg, transparent, rgba(0, 0, 0, .1) 20%, rgba(0, 0, 0, .1) 50%, transparent 53%), #4580c4 !important;
|
||||
border: 1px solid rgba(0, 0, 0, .6);
|
||||
border-radius: 6px 6px 0 0;
|
||||
// box-shadow : inset 0 0 .5px .5px #fff;
|
||||
|
||||
height: 27px;
|
||||
line-height: 27px;
|
||||
|
||||
color: #000 !important;
|
||||
letter-spacing: 0;
|
||||
font-size: 12px;
|
||||
text-shadow: 0 0 10px #fff, 0 0 10px #fff, 0 0 10px #fff, 0 0 10px #fff, 0 0 10px #fff, 0 0 10px #fff, 0 0 10px #fff, 0 0 10px #fff;
|
||||
|
||||
padding: 0 80px 0 8px;
|
||||
|
||||
border: 0;
|
||||
box-shadow: inset 0 .5px #fff;
|
||||
|
||||
|
||||
}
|
||||
|
||||
.layui-layer-easy .layui-layer-title~.layui-layer-setwin {
|
||||
height: 27px !important;
|
||||
top: 1px;
|
||||
}
|
||||
|
||||
.layui-layer-easy .layui-layer-title~.layui-layer-setwin>span {
|
||||
height: 20px !important;
|
||||
line-height: 20px !important;
|
||||
|
||||
background: linear-gradient(hsla(0, 0%, 100%, .3), hsla(0, 0%, 100%, .3) 45%, rgba(0, 0, 0, .1) 50%, rgba(0, 0, 0, .1) 75%, hsla(0, 0%, 100%, .5)) !important;
|
||||
border: 0;
|
||||
border-radius: 0;
|
||||
border-bottom-right-radius: 0px;
|
||||
border-right: 1px solid rgba(0, 0, 0, .6);
|
||||
box-shadow: inset 0 0 0 .5px #eee;
|
||||
box-sizing: border-box;
|
||||
|
||||
padding: 0;
|
||||
position: relative;
|
||||
|
||||
margin-left: 0;
|
||||
|
||||
min-width: 26px;
|
||||
text-align: center;
|
||||
|
||||
&:hover {
|
||||
background: radial-gradient(circle at 50% 100%, #2aceda, transparent 60%), linear-gradient(#a9d2e8 50%, #196c9b 0) !important;
|
||||
}
|
||||
|
||||
|
||||
&:last-child {
|
||||
border: 0;
|
||||
border-bottom-right-radius: 5px;
|
||||
|
||||
}
|
||||
|
||||
&:first-child {
|
||||
border-bottom-left-radius: 5px;
|
||||
}
|
||||
|
||||
&.layui-layer-close1 {
|
||||
background-color: #d04a37 !important;
|
||||
min-width: 45px !important;
|
||||
|
||||
|
||||
&:hover {
|
||||
filter: contrast(1.3);
|
||||
background-image: linear-gradient(hsla(0, 0%, 100%, .3), hsla(0, 0%, 100%, .3) 45%, rgba(0, 0, 0, .1) 50%, rgba(0, 0, 0, .1) 75%, hsla(0, 0%, 100%, .5)) !important;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.layui-layer-dialog {
|
||||
border-radius: 20px;
|
||||
}
|
||||
|
||||
.layui-layer-iframe {
|
||||
border-radius: 20px;
|
||||
}
|
||||
|
||||
.layui-layer:not(.layui-layer-loading) {
|
||||
|
||||
.layui-layer-content {
|
||||
background: #f0f0f0;
|
||||
border: 1px solid rgba(0, 0, 0, .6);
|
||||
box-shadow: 0 -1px 1px .5px #fff;
|
||||
margin: 0 6px 0 6px;
|
||||
padding: 6px;
|
||||
border-bottom-width: 0;
|
||||
}
|
||||
|
||||
&::before {
|
||||
background: linear-gradient(transparent 20%, hsla(0, 0%, 100%, .7) 40%, transparent 41%), linear-gradient(90deg, hsla(0, 0%, 100%, .4), rgba(0, 0, 0, .1), hsla(0, 0%, 100%, .2)), linear-gradient(55deg, transparent, rgba(0, 0, 0, .1) 20%, rgba(0, 0, 0, .1) 50%, transparent 53%), #4580c4;
|
||||
border-radius: 6px;
|
||||
content: "";
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
z-index: -1;
|
||||
|
||||
}
|
||||
|
||||
&.layui-layer-iframe {
|
||||
|
||||
&::before {
|
||||
height: calc(100% + 20px);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.layui-layer-easy .layui-layer-btn {
|
||||
background: #f0f0f0;
|
||||
border: 1px solid rgba(0, 0, 0, .6);
|
||||
box-shadow: 0 0 1px .5px #fff;
|
||||
margin: 0 6px 6px;
|
||||
padding: 6px;
|
||||
border-top: 0;
|
||||
text-align: right !important;
|
||||
}
|
||||
|
||||
.layui-card {
|
||||
|
||||
border: 1px solid rgba(0, 0, 0, .6);
|
||||
border-radius: 6px;
|
||||
box-shadow: 0 0 5px 1px rgba(0, 0, 0, .6);
|
||||
font: 9pt Segoe UI, sans-serif;
|
||||
position: relative;
|
||||
z-index: 0;
|
||||
|
||||
&::before {
|
||||
background: linear-gradient(transparent 20%, hsla(0, 0%, 100%, .7) 40%, transparent 41%), linear-gradient(90deg, hsla(0, 0%, 100%, .4), rgba(0, 0, 0, .1), hsla(0, 0%, 100%, .2)), linear-gradient(55deg, transparent, rgba(0, 0, 0, .1) 20%, rgba(0, 0, 0, .1) 50%, transparent 53%), #4580c4;
|
||||
border-radius: 6px;
|
||||
content: "";
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
|
||||
.layui-card-header {
|
||||
align-items: center;
|
||||
background: linear-gradient(90deg, hsla(0, 0%, 100%, .4), rgba(0, 0, 0, .1), hsla(0, 0%, 100%, .2)), linear-gradient(55deg, transparent, rgba(0, 0, 0, .1) 20%, rgba(0, 0, 0, .1) 50%, transparent 53%), #4580c4;
|
||||
border-radius: 6px 6px 0 0;
|
||||
font: 9pt Segoe UI, sans-serif;
|
||||
justify-content: space-between;
|
||||
padding: 6px;
|
||||
border: 0;
|
||||
box-shadow: inset 0 .5px #fff;
|
||||
height: 15px;
|
||||
|
||||
color: #000;
|
||||
letter-spacing: 0;
|
||||
line-height: 15px;
|
||||
text-shadow: 0 0 10px #fff, 0 0 10px #fff, 0 0 10px #fff, 0 0 10px #fff, 0 0 10px #fff, 0 0 10px #fff, 0 0 10px #fff, 0 0 10px #fff;
|
||||
|
||||
}
|
||||
|
||||
.layui-card-body {
|
||||
background: #f0f0f0;
|
||||
border: 1px solid rgba(0, 0, 0, .6);
|
||||
box-shadow: 0 0 1px .5px #fff;
|
||||
margin: 0 6px 6px;
|
||||
padding: 6px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
.layui-tab-brief>.layui-tab-title .layui-this {
|
||||
color: #222;
|
||||
}
|
||||
|
||||
.layuimini-tab .layui-tab-control>li {
|
||||
height: 27px !important;
|
||||
line-height: 27px !important;
|
||||
}
|
||||
|
||||
.layui-form-checkbox[lay-skin="primary"] i {
|
||||
background: #ddd;
|
||||
border: 1px solid #888;
|
||||
box-shadow: inset 0 0 0 1.5px #eee, inset 0 2px 4px #888, inset -2px -3px 4px #fff;
|
||||
box-sizing: border-box;
|
||||
content: "";
|
||||
display: inline-block;
|
||||
height: 13px;
|
||||
margin-right: 6px;
|
||||
width: 13px;
|
||||
color: transparent;
|
||||
}
|
||||
|
||||
.layui-form-checked[lay-skin="primary"] i {
|
||||
color: #16638f;
|
||||
border-color: #888;
|
||||
display: block;
|
||||
font-weight: 700;
|
||||
position: absolute;
|
||||
|
||||
&::before {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.layui-form-radio:hover *,
|
||||
.layui-form-radioed,
|
||||
.layui-form-radioed>i {
|
||||
color: #16638f;
|
||||
}
|
||||
|
||||
.layui-input {
|
||||
background-color: #fff;
|
||||
border: 1px solid #ccc;
|
||||
border-top-color: rgb(204, 204, 204);
|
||||
border-radius: 2px;
|
||||
border-top-color: #888;
|
||||
box-sizing: border-box;
|
||||
font: 9pt Segoe UI, sans-serif;
|
||||
padding: 3px 4px 5px;
|
||||
}
|
||||
|
||||
.layui-input,
|
||||
.layui-select,
|
||||
.layui-textarea {
|
||||
height: unset
|
||||
}
|
||||
|
||||
.layui-form-label {
|
||||
padding: 3px 15px;
|
||||
font: 9pt Segoe UI, sans-serif;
|
||||
}
|
||||
|
||||
|
||||
.layuimini-form>.layui-form-item .required::after {
|
||||
top: 2px;
|
||||
}
|
||||
|
||||
.form-search .layui-input-inline input,
|
||||
.form-search .layui-input-inline select {
|
||||
height: unset;
|
||||
line-height: unset;
|
||||
}
|
||||
|
||||
.form-search .layui-form-label {
|
||||
height: unset;
|
||||
background: unset;
|
||||
text-align: right;
|
||||
border: unset;
|
||||
}
|
||||
|
||||
.layuimini-upload-btn {
|
||||
.layui-btn {
|
||||
height: 25px;
|
||||
line-height: 25px;
|
||||
}
|
||||
}
|
||||
95
public/static/admin/css/themes/default.css
Normal file
95
public/static/admin/css/themes/default.css
Normal file
@@ -0,0 +1,95 @@
|
||||
/*头部右侧背景色 headerRightBg */
|
||||
.layui-layout-admin .layui-header {
|
||||
background-color: #ffffff !important;
|
||||
}
|
||||
|
||||
/*头部右侧选中背景色 headerRightBgThis */
|
||||
.layui-layout-admin .layui-header .layuimini-header-content > ul > .layui-nav-item.layui-this, .layuimini-tool i:hover {
|
||||
background-color: #e4e4e4 !important;
|
||||
}
|
||||
|
||||
/*头部右侧字体颜色 headerRightColor */
|
||||
.layui-layout-admin .layui-header .layui-nav .layui-nav-item a {
|
||||
color: rgba(107, 107, 107, 0.7);
|
||||
}
|
||||
|
||||
/**头部右侧下拉字体颜色 headerRightChildColor */
|
||||
.layui-layout-admin .layui-header .layui-nav .layui-nav-item .layui-nav-child a {
|
||||
color: rgba(107, 107, 107, 0.7) !important;
|
||||
}
|
||||
|
||||
/*头部右侧鼠标选中 headerRightColorThis */
|
||||
.layui-header .layuimini-menu-header-pc.layui-nav .layui-nav-item a:hover, .layui-header .layuimini-header-menu.layuimini-pc-show.layui-nav .layui-this a {
|
||||
color: #565656 !important;
|
||||
}
|
||||
|
||||
/*头部右侧更多下拉颜色 headerRightNavMore */
|
||||
.layui-header .layui-nav .layui-nav-more {
|
||||
border-top-color: rgba(160, 160, 160, 0.7) !important;
|
||||
}
|
||||
|
||||
/*头部右侧更多下拉颜色 headerRightNavMore */
|
||||
.layui-header .layui-nav .layui-nav-mored, .layui-header .layui-nav-itemed > a .layui-nav-more {
|
||||
border-color: transparent transparent rgba(160, 160, 160, 0.7) !important;
|
||||
}
|
||||
|
||||
/**头部右侧更多下拉配置色 headerRightNavMoreBg headerRightNavMoreColor */
|
||||
.layui-header .layui-nav .layui-nav-child dd.layui-this a, .layui-header .layui-nav-child dd.layui-this, .layui-layout-admin .layui-header .layui-nav .layui-nav-item .layui-nav-child .layui-this a {
|
||||
background-color: #1E9FFF !important;
|
||||
color: #ffffff !important;
|
||||
}
|
||||
|
||||
/*头部缩放按钮样式 headerRightToolColor */
|
||||
.layui-layout-admin .layui-header .layuimini-tool i {
|
||||
color: #565656;
|
||||
}
|
||||
|
||||
/*logo背景颜色 headerLogoBg */
|
||||
.layui-layout-admin .layuimini-logo {
|
||||
background-color: #192027 !important;
|
||||
}
|
||||
|
||||
/*logo字体颜色 headerLogoColor */
|
||||
.layui-layout-admin .layuimini-logo h1 {
|
||||
color: rgb(191, 187, 187);
|
||||
}
|
||||
|
||||
/*左侧菜单更多下拉样式 leftMenuNavMore */
|
||||
.layuimini-menu-left .layui-nav .layui-nav-more, .layuimini-menu-left-zoom.layui-nav .layui-nav-more {
|
||||
border-top-color: rgb(191, 187, 187);
|
||||
}
|
||||
|
||||
/*左侧菜单更多下拉样式 leftMenuNavMore */
|
||||
.layuimini-menu-left .layui-nav .layui-nav-mored, .layuimini-menu-left .layui-nav-itemed > a .layui-nav-more, .layuimini-menu-left-zoom.layui-nav .layui-nav-mored, .layuimini-menu-left-zoom.layui-nav-itemed > a .layui-nav-more {
|
||||
border-color: transparent transparent rgb(191, 187, 187) !important;
|
||||
}
|
||||
|
||||
/*左侧菜单背景 leftMenuBg */
|
||||
.layui-side.layui-bg-black, .layui-side.layui-bg-black > .layuimini-menu-left > ul, .layuimini-menu-left-zoom > ul {
|
||||
background-color: #28333E !important;
|
||||
}
|
||||
|
||||
/*左侧菜单选中背景 leftMenuBgThis */
|
||||
.layuimini-menu-left .layui-nav-tree .layui-this, .layuimini-menu-left .layui-nav-tree .layui-this > a, .layuimini-menu-left .layui-nav-tree .layui-nav-child dd.layui-this, .layuimini-menu-left .layui-nav-tree .layui-nav-child dd.layui-this a, .layuimini-menu-left-zoom.layui-nav-tree .layui-this, .layuimini-menu-left-zoom.layui-nav-tree .layui-this > a, .layuimini-menu-left-zoom.layui-nav-tree .layui-nav-child dd.layui-this, .layuimini-menu-left-zoom.layui-nav-tree .layui-nav-child dd.layui-this a {
|
||||
background-color: #1E9FFF !important
|
||||
}
|
||||
|
||||
/*左侧菜单子菜单背景 leftMenuChildBg */
|
||||
.layuimini-menu-left .layui-nav-itemed > .layui-nav-child {
|
||||
background-color: #0c0f13 !important;
|
||||
}
|
||||
|
||||
/*左侧菜单字体颜色 leftMenuColor */
|
||||
.layuimini-menu-left .layui-nav .layui-nav-item a, .layuimini-menu-left-zoom.layui-nav .layui-nav-item a {
|
||||
color: rgb(191, 187, 187) !important;
|
||||
}
|
||||
|
||||
/*左侧菜单选中字体颜色 leftMenuColorThis */
|
||||
.layuimini-menu-left .layui-nav .layui-nav-item a:hover, .layuimini-menu-left .layui-nav .layui-this a, .layuimini-menu-left-zoom.layui-nav .layui-nav-item a:hover, .layuimini-menu-left-zoom.layui-nav .layui-this a {
|
||||
color: #ffffff !important;
|
||||
}
|
||||
|
||||
/**tab选项卡选中颜色 tabActiveColor */
|
||||
.layuimini-tab .layui-tab-title .layui-this .layuimini-tab-active {
|
||||
background-color: #1e9fff;
|
||||
}
|
||||
3050
public/static/admin/css/themes/index.css
Normal file
3050
public/static/admin/css/themes/index.css
Normal file
File diff suppressed because it is too large
Load Diff
41
public/static/admin/css/themes/index.scss
Normal file
41
public/static/admin/css/themes/index.scss
Normal file
@@ -0,0 +1,41 @@
|
||||
.elem-style-normal {
|
||||
@import 'normal';
|
||||
}
|
||||
|
||||
.elem-style-demo {
|
||||
@import 'demo';
|
||||
}
|
||||
|
||||
.elem-style-sicfi {
|
||||
@import 'sicfi';
|
||||
}
|
||||
|
||||
.elem-style-gtk {
|
||||
@import 'gtk';
|
||||
}
|
||||
|
||||
.elem-style-nes {
|
||||
@import 'nes';
|
||||
|
||||
}
|
||||
|
||||
.elem-style-win7 {
|
||||
@import 'win7';
|
||||
}
|
||||
.elem-style-neomorphic {
|
||||
@import 'neomorphic';
|
||||
}
|
||||
.elem-style-dark {
|
||||
@import 'dark';
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "ark-pixel";
|
||||
src : url('./nes/ark-pixel-font-12px/ark-pixel-12px-zh_cn.ttf') format('truetype'),
|
||||
url('./nes/ark-pixel-font-12px/ark-pixel-12px-zh_hk.ttf') format('truetype'),
|
||||
url('./nes/ark-pixel-font-12px/ark-pixel-12px-zh_tr.ttf') format('truetype'),
|
||||
url('./nes/ark-pixel-font-12px/ark-pixel-12px-zh_tw.ttf') format('truetype'),
|
||||
url('./nes/ark-pixel-font-12px/ark-pixel-12px-ja.ttf') format('truetype'),
|
||||
url('./nes/ark-pixel-font-12px/ark-pixel-12px-ko.ttf') format('truetype'),
|
||||
url('./nes/ark-pixel-font-12px/ark-pixel-12px-latin.ttf') format('truetype');
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
Copyright (c) 2021, TakWolf (https://ark-pixel-font.takwolf.com),
|
||||
with Reserved Font Name 'Ark Pixel'.
|
||||
|
||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||
This license is copied below, and is also available with a FAQ at:
|
||||
http://scripts.sil.org/OFL
|
||||
|
||||
|
||||
-----------------------------------------------------------
|
||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||
-----------------------------------------------------------
|
||||
|
||||
PREAMBLE
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||
development of collaborative font projects, to support the font creation
|
||||
efforts of academic and linguistic communities, and to provide a free and
|
||||
open framework in which fonts may be shared and improved in partnership
|
||||
with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and
|
||||
redistributed freely as long as they are not sold by themselves. The
|
||||
fonts, including any derivative works, can be bundled, embedded,
|
||||
redistributed and/or sold with any software provided that any reserved
|
||||
names are not used by derivative works. The fonts and derivatives,
|
||||
however, cannot be released under any other type of license. The
|
||||
requirement for fonts to remain under this license does not apply
|
||||
to any document created using the fonts or their derivatives.
|
||||
|
||||
DEFINITIONS
|
||||
"Font Software" refers to the set of files released by the Copyright
|
||||
Holder(s) under this license and clearly marked as such. This may
|
||||
include source files, build scripts and documentation.
|
||||
|
||||
"Reserved Font Name" refers to any names specified as such after the
|
||||
copyright statement(s).
|
||||
|
||||
"Original Version" refers to the collection of Font Software components as
|
||||
distributed by the Copyright Holder(s).
|
||||
|
||||
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||
or substituting -- in part or in whole -- any of the components of the
|
||||
Original Version, by changing formats or by porting the Font Software to a
|
||||
new environment.
|
||||
|
||||
"Author" refers to any designer, engineer, programmer, technical
|
||||
writer or other person who contributed to the Font Software.
|
||||
|
||||
PERMISSION & CONDITIONS
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||
redistribute, and sell modified and unmodified copies of the Font
|
||||
Software, subject to the following conditions:
|
||||
|
||||
1) Neither the Font Software nor any of its individual components,
|
||||
in Original or Modified Versions, may be sold by itself.
|
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled,
|
||||
redistributed and/or sold with any software, provided that each copy
|
||||
contains the above copyright notice and this license. These can be
|
||||
included either as stand-alone text files, human-readable headers or
|
||||
in the appropriate machine-readable metadata fields within text or
|
||||
binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font
|
||||
Name(s) unless explicit written permission is granted by the corresponding
|
||||
Copyright Holder. This restriction only applies to the primary font name as
|
||||
presented to the users.
|
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||
Software shall not be used to promote, endorse or advertise any
|
||||
Modified Version, except to acknowledge the contribution(s) of the
|
||||
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||
permission.
|
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole,
|
||||
must be distributed entirely under this license, and must not be
|
||||
distributed under any other license. The requirement for fonts to
|
||||
remain under this license does not apply to any document created
|
||||
using the Font Software.
|
||||
|
||||
TERMINATION
|
||||
This license becomes null and void if any of the above conditions are
|
||||
not met.
|
||||
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -48,7 +48,6 @@
|
||||
position: relative;
|
||||
top: 2px;
|
||||
display: block;
|
||||
color: #666;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
@@ -58,6 +57,8 @@
|
||||
.welcome-module {
|
||||
width: 100%;
|
||||
height: 210px;
|
||||
max-height: 210px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.panel {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
define(["jquery", "easy-admin", "echarts", "echarts-theme", "miniAdmin", "miniTab", "swiper"], function ($, ea, echarts, undefined, miniAdmin, miniTab) {
|
||||
define(["jquery", "easy-admin", "echarts", "echarts-theme", "miniAdmin", "miniTheme", "miniTab", "swiper"], function ($, ea, echarts, undefined, miniAdmin, miniTheme, miniTab) {
|
||||
|
||||
return {
|
||||
index: function () {
|
||||
@@ -25,28 +25,6 @@ define(["jquery", "easy-admin", "echarts", "echarts-theme", "miniAdmin", "miniTa
|
||||
})
|
||||
});
|
||||
});
|
||||
layui.form.on('switch(header-theme-mode)', function (data) {
|
||||
let dark_mode = this.checked
|
||||
let that = $('iframe').contents()
|
||||
if (dark_mode) {
|
||||
$('#layuicss-theme-dark').attr({
|
||||
rel: "stylesheet",
|
||||
type: "text/css",
|
||||
href: "/static/admin/css/layui-theme-dark.css"
|
||||
})
|
||||
.appendTo("head");
|
||||
that.find("html").addClass('dark')
|
||||
$('html').addClass('dark')
|
||||
} else {
|
||||
$('#layuicss-theme-dark').attr({
|
||||
rel: "stylesheet",
|
||||
type: "text/css",
|
||||
href: ""
|
||||
})
|
||||
that.find("html").removeClass('dark')
|
||||
$('html').removeClass('dark')
|
||||
}
|
||||
});
|
||||
},
|
||||
welcome: function () {
|
||||
miniTab.listen();
|
||||
@@ -162,6 +140,38 @@ define(["jquery", "easy-admin", "echarts", "echarts-theme", "miniAdmin", "miniTa
|
||||
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 () {
|
||||
let form = layui.form
|
||||
|
||||
@@ -7,7 +7,7 @@ define(["jquery", "easy-admin"], function ($, ea) {
|
||||
}
|
||||
$(function () {
|
||||
if (backgroundUrl) {
|
||||
$('.container').css('background', 'url(' + backgroundUrl + ') 0% 0% / cover no-repeat')
|
||||
$('body').css('background', 'url(' + backgroundUrl + ') 0% 0% / cover no-repeat')
|
||||
}
|
||||
$('.bind-password').on('click', function () {
|
||||
if ($(this).hasClass('icon-5')) {
|
||||
@@ -40,7 +40,7 @@ define(["jquery", "easy-admin"], function ($, ea) {
|
||||
})
|
||||
}, function (res) {
|
||||
let data = res.data
|
||||
if (data.is_ga_code) {
|
||||
if (data?.is_ga_code || false) {
|
||||
let elem = $('#gaCode')
|
||||
elem.removeClass('layui-hide');
|
||||
elem.find('input').focus()
|
||||
|
||||
@@ -85,13 +85,55 @@ define(["jquery", "easy-admin"], function ($, ea) {
|
||||
ea.listen();
|
||||
},
|
||||
add: function () {
|
||||
layui.util.on({
|
||||
AiOptimization: function (data) {
|
||||
let layOn = $(data).attr('lay-on')
|
||||
$(data).attr('lay-on', layOn + 'Loading')
|
||||
aiOptimization(data)
|
||||
},
|
||||
})
|
||||
ea.listen();
|
||||
},
|
||||
edit: function () {
|
||||
layui.util.on({
|
||||
AiOptimization: function (data) {
|
||||
let layOn = $(data).attr('lay-on')
|
||||
$(data).attr('lay-on', layOn + 'Loading')
|
||||
aiOptimization(data)
|
||||
},
|
||||
})
|
||||
ea.listen();
|
||||
},
|
||||
stock: function () {
|
||||
ea.listen();
|
||||
},
|
||||
};
|
||||
|
||||
function aiOptimization(data) {
|
||||
let layOn = $(data).attr('lay-on')
|
||||
let title = $('input[name="title"]').val()
|
||||
|
||||
// 告诉AI 你需要做什么
|
||||
let message = `优化这个标题 ${title}`
|
||||
|
||||
if ($.trim(title) === '') {
|
||||
ea.msg.error('标题不能为空', function () {
|
||||
$(data).attr('lay-on', layOn.split('Loading')[0])
|
||||
})
|
||||
return false
|
||||
}
|
||||
let url = ea.url('mall.goods/aiOptimization')
|
||||
ea.request.post({url: url, data: {message: message}}, function (res) {
|
||||
let content = res.data?.choices[0]?.message?.content
|
||||
// stream 为true 时,AI 内容会逐字输出
|
||||
let stream = true
|
||||
ea.ai.chat(content, {stream: stream}, function () {
|
||||
$(data).attr('lay-on', layOn.split('Loading')[0])
|
||||
})
|
||||
}, function (error) {
|
||||
ea.msg.error(error.msg, function () {
|
||||
$(data).attr('lay-on', layOn.split('Loading')[0])
|
||||
})
|
||||
})
|
||||
}
|
||||
});
|
||||
@@ -1,15 +1,15 @@
|
||||
define(["jquery", "easy-admin", "vue"], function ($, ea, Vue) {
|
||||
define(["jquery", "easy-admin"], function ($, ea) {
|
||||
|
||||
var form = layui.form;
|
||||
|
||||
return {
|
||||
index: function () {
|
||||
var _group = 'site'
|
||||
var element = layui.element;
|
||||
element.on('tab(docDemoTabBrief)', function (data) {
|
||||
let tabs = layui.tabs
|
||||
var TABS_ID = 'docDemoTabBrief';
|
||||
tabs.on(`afterChange(${TABS_ID})`, function (data) {
|
||||
_group = $(this).data('group')
|
||||
});
|
||||
|
||||
})
|
||||
let _upload_type = upload_type || 'local'
|
||||
$('.upload_type').addClass('layui-hide')
|
||||
$('.' + _upload_type).removeClass('layui-hide')
|
||||
@@ -20,12 +20,15 @@ define(["jquery", "easy-admin", "vue"], function ($, ea, Vue) {
|
||||
$('.' + _upload_type).removeClass('layui-hide')
|
||||
});
|
||||
|
||||
|
||||
form.on("submit", function (data) {
|
||||
data.field['group'] = _group
|
||||
});
|
||||
|
||||
ea.listen();
|
||||
ea.listen('', function (res) {
|
||||
ea.msg.success(res.msg);
|
||||
}, function (err) {
|
||||
ea.msg.error(err.msg);
|
||||
});
|
||||
}
|
||||
};
|
||||
});
|
||||
@@ -6,6 +6,7 @@ define(["jquery", "easy-admin"], function ($, ea) {
|
||||
table_render_id: 'currentTableRenderId',
|
||||
index_url: 'system.log/index',
|
||||
export_url: 'system.log/export',
|
||||
deleteMonthLog_url: 'system.log/deleteMonthLog',
|
||||
};
|
||||
|
||||
return {
|
||||
@@ -23,8 +24,15 @@ define(["jquery", "easy-admin"], function ($, ea) {
|
||||
class: 'layui-btn layui-btn-sm',
|
||||
icon: 'fa fa-book',
|
||||
extend: 'data-width="95%" data-height="95%"'
|
||||
},
|
||||
]
|
||||
}, {
|
||||
text: '删除部分日志',
|
||||
url: 'system.log/deleteMonthLog',
|
||||
method: 'open',
|
||||
auth: 'deleteMonthLog',
|
||||
class: 'layui-btn layui-btn-sm layui-btn-danger',
|
||||
icon: 'fa fa-remove',
|
||||
extend: 'data-width="35%" data-height="42%"'
|
||||
},]
|
||||
],
|
||||
cols: [[
|
||||
{field: 'id', width: 80, title: 'ID', search: false},
|
||||
@@ -43,7 +51,7 @@ define(["jquery", "easy-admin"], function ($, ea) {
|
||||
field: 'content', minWidth: 200, title: '请求数据', align: "left", templet: function (res) {
|
||||
let html = '<div class="layui-colla-item">' +
|
||||
'<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>'
|
||||
return '<div class="layui-collapse" lay-accordion>' + html + '</div>'
|
||||
}
|
||||
@@ -52,7 +60,7 @@ define(["jquery", "easy-admin"], function ($, ea) {
|
||||
field: 'response', minWidth: 200, title: '回调数据', align: "left", templet: function (res) {
|
||||
let html = '<div class="layui-colla-item">' +
|
||||
'<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>'
|
||||
return '<div class="layui-collapse" lay-accordion>' + html + '</div>'
|
||||
}
|
||||
@@ -65,5 +73,20 @@ define(["jquery", "easy-admin"], function ($, ea) {
|
||||
});
|
||||
ea.listen();
|
||||
},
|
||||
deleteMonthLog: function () {
|
||||
layui.form.on('submit(submit)', function (data) {
|
||||
let field = data.field
|
||||
let options = {
|
||||
url: ea.url(init.deleteMonthLog_url),
|
||||
data: field,
|
||||
}
|
||||
ea.msg.confirm('确认执行该操作?重要数据请先做好相关备份!', function () {
|
||||
ea.request.post(options, function (rs) {
|
||||
let msg = rs.msg || '未知~'
|
||||
layer.msg(msg.replace(/\n/g, '<br>'), {shade: 0.3, shadeClose: true, time: 2000})
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
@@ -1,31 +1,37 @@
|
||||
body{
|
||||
body {
|
||||
text-align: center;
|
||||
}
|
||||
h1{
|
||||
|
||||
h1 {
|
||||
margin-top: 20px;
|
||||
}
|
||||
h1 img{
|
||||
|
||||
h1 img {
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 28px;
|
||||
font-weight: normal;
|
||||
color: #3C5675;
|
||||
margin-bottom: 0
|
||||
}
|
||||
.content{
|
||||
|
||||
.content {
|
||||
margin-top: 20px;
|
||||
}
|
||||
.content p{
|
||||
|
||||
.content p {
|
||||
margin: 20px;
|
||||
}
|
||||
.content form{
|
||||
margin:0 auto;
|
||||
|
||||
.content form {
|
||||
width: 500px;
|
||||
margin-bottom: 20px;
|
||||
margin: 0 auto 20px;
|
||||
}
|
||||
.content form .bg{
|
||||
|
||||
.content form .bg {
|
||||
margin-top: 20px;
|
||||
background-color: #fff;
|
||||
border: 1px solid #fff;
|
||||
@@ -33,51 +39,68 @@ h2 {
|
||||
padding: 14px 14px;
|
||||
box-shadow: 0 0 8px #cccccc;
|
||||
}
|
||||
.content form .layui-form-item:last-child{
|
||||
margin-bottom:0!important;
|
||||
|
||||
.content form .bg .layui-card {
|
||||
background-color: #fafafa;
|
||||
color: #ff8080;
|
||||
font-size: 15px;
|
||||
font-weight: bold;
|
||||
}
|
||||
.content form .layui-btn{
|
||||
|
||||
.content form .layui-form-item:last-child {
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
|
||||
.content form .layui-btn {
|
||||
margin-top: 20px;
|
||||
}
|
||||
.content .layui-elem-field legend{
|
||||
|
||||
.content .layui-elem-field legend {
|
||||
font-size: 16px;
|
||||
color: #8a8a8a;
|
||||
}
|
||||
.content .tips{
|
||||
|
||||
.content .tips {
|
||||
float: left;
|
||||
margin-top: 5px;
|
||||
margin-bottom: 5px;
|
||||
font-size: 12px;
|
||||
color: #eca6a6
|
||||
}
|
||||
.content .admin-tips{
|
||||
|
||||
.content .admin-tips {
|
||||
float: left;
|
||||
margin-top: 5px;
|
||||
margin-bottom: 5px;
|
||||
font-size: 12px;
|
||||
color: #eca6a6
|
||||
}
|
||||
.content .desc{
|
||||
|
||||
.content .desc {
|
||||
font-size: 16px;
|
||||
color: #4E5465;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
.content .desc a{
|
||||
|
||||
.content .desc a {
|
||||
color: #07adeb;
|
||||
margin-right: 10px;
|
||||
}
|
||||
.content .desc a:first-child{
|
||||
|
||||
.content .desc a:first-child {
|
||||
margin-left: 10px;
|
||||
}
|
||||
.error{
|
||||
|
||||
.error {
|
||||
background: #D83E3E;
|
||||
color: #fff;
|
||||
padding: 15px 20px;
|
||||
border-radius: 5px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
@media screen and (max-width:768px) {
|
||||
.content form{
|
||||
|
||||
@media screen and (max-width: 768px) {
|
||||
.content form {
|
||||
width: 95%;
|
||||
}
|
||||
}
|
||||
BIN
public/static/common/images/loading.gif
Normal file
BIN
public/static/common/images/loading.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.8 KiB |
@@ -5,11 +5,9 @@ require.config({
|
||||
baseUrl: BASE_URL,
|
||||
paths: {
|
||||
"jquery": ["plugs/jquery-3.4.1/jquery-3.4.1.min"],
|
||||
"jquery-particleground": ["plugs/jq-module/jquery.particleground.min"],
|
||||
"echarts": ["plugs/echarts/echarts.min"],
|
||||
"echarts-theme": ["plugs/echarts/echarts-theme"],
|
||||
"easy-admin": ["plugs/easy-admin/easy-admin"],
|
||||
"layuiall": ["plugs/layui-v2.x/layui.all"],
|
||||
"layui": ["plugs/layui-v2.x/layui"],
|
||||
"miniAdmin": ["plugs/lay-module/layuimini/miniAdmin"],
|
||||
"miniMenu": ["plugs/lay-module/layuimini/miniMenu"],
|
||||
@@ -20,8 +18,11 @@ require.config({
|
||||
"tableSelect": ["plugs/lay-module/tableSelect/tableSelect"],
|
||||
"iconPickerFa": ["plugs/lay-module/iconPicker/iconPickerFa"],
|
||||
"autocomplete": ["plugs/lay-module/autocomplete/autocomplete"],
|
||||
"xmSelect": ["plugs/xmSelect/xm-select"],
|
||||
"vue": ["plugs/vue-2.6.10/vue.min"],
|
||||
"swiper": ["plugs/swiper/swiper-bundle.min"],
|
||||
"colorMode": ["plugs/colorMode/colorMode"],
|
||||
"lazyload": ["plugs/lazyload/lazyload.min"],
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
186
public/static/plugs/colorMode/colorMode.js
Normal file
186
public/static/plugs/colorMode/colorMode.js
Normal file
@@ -0,0 +1,186 @@
|
||||
// @ts-ignore
|
||||
define(['jquery'], function (colorMode) {
|
||||
// 'use strict';
|
||||
|
||||
/** @type {jQuery}*/
|
||||
var $ = layui.jquery;
|
||||
|
||||
var MOD_NAME = 'colorMode';
|
||||
var defaultWindow = window;
|
||||
var document = defaultWindow.document;
|
||||
|
||||
var colorMode = {
|
||||
/**
|
||||
* @typedef {object} initOptions
|
||||
* @prop {string} [selector="html"] - 应用于目标元素的 CSS 选择器
|
||||
* @prop {string} [attribute="class"] - 应用于目标元素的 HTML 属性
|
||||
* @prop {string} [initialValue='auto'] - 初始颜色模式
|
||||
* @prop {Object.<string, string>} [modes]- 颜色模式。value 为添加到 HTML 属性上的值
|
||||
* @prop {(mode: string, defaultHandler: (window?: Window) => void) => void} [onChanged] - 用于处理更新的自定义处理程序,指定时,默认行为将被覆盖。
|
||||
* @prop {Storage} [storage=localStorage] - 将数据持久化到 localStorage/sessionStorage 的键。传递 `null` 以禁用持久性
|
||||
* @prop {string | null} [storageKey='color-scheme'] - 持久化使用的 key
|
||||
* @prop {boolean} [disableTransition=true] - 禁用切换时的过渡 {@link https://paco.me/writing/disable-theme-transitions}
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {initOptions} options
|
||||
* @returns {{mode: () => string; setMode: (mode: string, window?: Window) => void; }}
|
||||
*/
|
||||
init: function (options) {
|
||||
var defaults = {
|
||||
selector: 'html',
|
||||
attribute: 'class',
|
||||
initialValue: 'auto',
|
||||
modes: {
|
||||
auto: '',
|
||||
light: 'light',
|
||||
dark: 'dark',
|
||||
},
|
||||
storage: localStorage,
|
||||
storageKey: 'color-scheme',
|
||||
disableTransition: true,
|
||||
};
|
||||
|
||||
var opts = $.extend(true, {}, defaults, options);
|
||||
|
||||
// 当前颜色模式
|
||||
var state;
|
||||
// 系统颜色模式
|
||||
var system;
|
||||
// 初始化 storage
|
||||
var store =
|
||||
opts.storageKey == null
|
||||
? opts.initialValue
|
||||
: (function () {
|
||||
var v = opts.storage.getItem(opts.storageKey);
|
||||
if (!v) {
|
||||
opts.storage.setItem(opts.storageKey, opts.initialValue);
|
||||
return opts.initialValue;
|
||||
}
|
||||
return v;
|
||||
})();
|
||||
|
||||
/**
|
||||
* 更新 HTML 属性值
|
||||
* @param {String} selector
|
||||
* @param {String} attribute
|
||||
* @param {String} value
|
||||
* @param {Window} win
|
||||
*/
|
||||
var updateHTMLAttrs = function (selector, attribute, value, win) {
|
||||
win = win || defaultWindow;
|
||||
var document = win.document;
|
||||
var el = typeof selector === 'string' ? document.querySelector(selector) : undefined;
|
||||
if (!el) return;
|
||||
|
||||
/**@type HTMLStyleElement */
|
||||
var style;
|
||||
|
||||
if (opts.disableTransition) {
|
||||
style = document.createElement('style');
|
||||
style.appendChild(
|
||||
document.createTextNode(
|
||||
'*,*::before,*::after{-webkit-transition:none!important;-moz-transition:none!important;-o-transition:none!important;-ms-transition:none!important;transition:none!important}'
|
||||
)
|
||||
);
|
||||
document.head.appendChild(style);
|
||||
}
|
||||
|
||||
if (attribute === 'class') {
|
||||
var current = value.split(/\s/g);
|
||||
$.each(opts.modes, function (_, modeval) {
|
||||
$.each((modeval || '').split(/\s/g), function (_, v) {
|
||||
if (!v) return;
|
||||
if (current.indexOf(v) !== -1) {
|
||||
el.classList.add(v);
|
||||
} else {
|
||||
el.classList.remove(v);
|
||||
}
|
||||
});
|
||||
});
|
||||
} else {
|
||||
el.setAttribute(attribute, value);
|
||||
}
|
||||
|
||||
if (opts.disableTransition) {
|
||||
// 调用 getComputedStyle 强制浏览器重绘
|
||||
// @ts-expect-error 未使用的变量
|
||||
var _ = window.getComputedStyle(style).opacity;
|
||||
document.head.removeChild(style);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 更新状态
|
||||
* @param {String} mode - 颜色模式
|
||||
*/
|
||||
var updateState = function (mode) {
|
||||
store = opts.storageKey == null ? mode : opts.storage.getItem(opts.storageKey);
|
||||
state = store === 'auto' ? system : store;
|
||||
};
|
||||
|
||||
var prefersColorScheme = function () {
|
||||
var isSupported = window && 'matchMedia' in window && typeof window.matchMedia === 'function';
|
||||
if (!isSupported) {
|
||||
system = 'light';
|
||||
onChanged(system);
|
||||
return;
|
||||
}
|
||||
var darkThemeMediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
|
||||
var update = function () {
|
||||
var preferredDark = darkThemeMediaQuery.matches;
|
||||
system = preferredDark ? 'dark' : 'light';
|
||||
onChanged(system);
|
||||
};
|
||||
update();
|
||||
if ('addEventListener' in darkThemeMediaQuery) {
|
||||
darkThemeMediaQuery.addEventListener('change', update);
|
||||
} else {
|
||||
// @ts-ignore 已弃用
|
||||
darkThemeMediaQuery.addListener(update);
|
||||
}
|
||||
};
|
||||
|
||||
prefersColorScheme();
|
||||
|
||||
function defaultOnChanged(win) {
|
||||
updateHTMLAttrs(opts.selector, opts.attribute, opts.modes[state], win);
|
||||
}
|
||||
|
||||
function onChanged(mode, win) {
|
||||
updateState(mode);
|
||||
if (opts.onChanged) {
|
||||
opts.onChanged(state, defaultOnChanged);
|
||||
} else {
|
||||
defaultOnChanged(win);
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
status:system,
|
||||
setMode: function (mode, win) {
|
||||
if (opts.storageKey) {
|
||||
opts.storage.setItem(opts.storageKey, mode);
|
||||
}
|
||||
onChanged(mode, win);
|
||||
},
|
||||
mode: function () {
|
||||
return state;
|
||||
},
|
||||
};
|
||||
},
|
||||
addStyle: function (id, cssStr) {
|
||||
var el = /** @type {HTMLStyleElement} */ (document.getElementById(id) || document.createElement('style'));
|
||||
if (!el.isConnected) {
|
||||
el.type = 'text/css';
|
||||
el.id = id;
|
||||
document.head.appendChild(el);
|
||||
}
|
||||
el.textContent = cssStr;
|
||||
},
|
||||
};
|
||||
|
||||
return colorMode;
|
||||
});
|
||||
@@ -1,4 +1,15 @@
|
||||
define(["jquery", "tableSelect"], function ($, tableSelect) {
|
||||
define(["jquery", "tableSelect", "miniTheme", "xmSelect", "lazyload"], function ($, tableSelect, miniTheme, xmSelect, lazyload) {
|
||||
|
||||
//切换日夜模式
|
||||
window.onInitElemStyle = function () {
|
||||
miniTheme.renderElemStyle();
|
||||
$('iframe').each(function (index, iframe) {
|
||||
if (typeof iframe.contentWindow.onInitElemStyle == "function") {
|
||||
iframe.contentWindow.onInitElemStyle();
|
||||
}
|
||||
});
|
||||
};
|
||||
window.onInitElemStyle();
|
||||
|
||||
var form = layui.form,
|
||||
layer = layui.layer,
|
||||
@@ -737,8 +748,11 @@ define(["jquery", "tableSelect"], function ($, tableSelect) {
|
||||
var values = value.split(option.imageSplit),
|
||||
valuesHtml = [];
|
||||
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);
|
||||
}
|
||||
},
|
||||
@@ -1582,7 +1596,7 @@ define(["jquery", "tableSelect"], function ($, tableSelect) {
|
||||
cols: [[
|
||||
{type: selectCheck},
|
||||
{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: 'mime_type', width: 120, title: 'mime类型', align: "center"},
|
||||
{field: 'create_time', width: 200, title: '创建时间', align: "center", search: 'range'},
|
||||
@@ -1750,6 +1764,61 @@ define(["jquery", "tableSelect"], function ($, tableSelect) {
|
||||
}
|
||||
},
|
||||
},
|
||||
ai: {
|
||||
chat: function (content, options, cancel) {
|
||||
let id = 'chat_' + (new Date()).getTime()
|
||||
layer.open({
|
||||
'title': options?.title || 'AI建议',
|
||||
type: 1,
|
||||
area: options?.area || ['42%', '60%'],
|
||||
shade: options?.shade || 0,
|
||||
shadeClose: options?.shadeClose || false,
|
||||
scrollbar: options?.scrollbar || false,
|
||||
maxmin: options?.maxmin || true,
|
||||
anim: options?.anim || 0,
|
||||
content: `<div style="padding: 20px;white-space: pre-wrap;" id="${id}"></div>`,
|
||||
success: function (layero, index) {
|
||||
let elem = document.getElementById(id)
|
||||
if (options?.stream) {
|
||||
clearTimeout(aiStreamTimeout)
|
||||
aiStreamCurrentIndex = 0
|
||||
setTimeout(() => {
|
||||
admin.ai.streamOutput(elem, content)
|
||||
}, 300)
|
||||
} else {
|
||||
content = content.replace(/\r\n/g, '<br>').replace(/\n/g, '<br>')
|
||||
setTimeout(() => {
|
||||
elem.innerHTML = content
|
||||
}, 100)
|
||||
}
|
||||
},
|
||||
cancel: function (index, layero) {
|
||||
cancel()
|
||||
}
|
||||
})
|
||||
},
|
||||
streamOutput: function (dom, htmlContent) {
|
||||
const chunkSize = 1;
|
||||
let length = htmlContent.length;
|
||||
if (aiStreamCurrentIndex < length) {
|
||||
const endIndex = Math.min(aiStreamCurrentIndex + chunkSize, length);
|
||||
const chunk = htmlContent.slice(aiStreamCurrentIndex, endIndex);
|
||||
const tempDiv = document.createElement('div');
|
||||
tempDiv.innerHTML = chunk;
|
||||
while (tempDiv.firstChild) {
|
||||
dom.appendChild(tempDiv.firstChild);
|
||||
}
|
||||
aiStreamCurrentIndex = endIndex;
|
||||
aiStreamTimeout = setTimeout(() => {
|
||||
admin.ai.streamOutput(dom, htmlContent);
|
||||
dom.scrollIntoView({behavior: "smooth", block: "end"});
|
||||
}, 60);
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
var aiStreamCurrentIndex = 0;
|
||||
var aiStreamTimeout = null;
|
||||
|
||||
return admin;
|
||||
});
|
||||
|
||||
@@ -607,7 +607,6 @@
|
||||
}
|
||||
|
||||
.layuimini-color .more-menu-item {
|
||||
color: #595959;
|
||||
height: 50px;
|
||||
line-height: 50px;
|
||||
font-size: 16px;
|
||||
@@ -617,10 +616,6 @@
|
||||
display: block;
|
||||
}
|
||||
|
||||
.layuimini-color .more-menu-item:hover {
|
||||
background-color: whitesmoke;
|
||||
}
|
||||
|
||||
.layuimini-color .more-menu-item:after {
|
||||
color: #8c8c8c;
|
||||
right: 16px;
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
*/
|
||||
|
||||
|
||||
define(["jquery", "miniMenu", "miniTheme", "miniTab"], function ($, miniMenu, miniTheme, miniTab) {
|
||||
define(["jquery", "miniMenu", "miniTheme", "miniTab", "colorMode"], function ($, miniMenu, miniTheme, miniTab, colorMode) {
|
||||
|
||||
var $ = layui.$,
|
||||
layer = layui.layer,
|
||||
@@ -104,7 +104,7 @@ define(["jquery", "miniMenu", "miniTheme", "miniTab"], function ($, miniMenu, mi
|
||||
* @param clearUrl
|
||||
*/
|
||||
renderClear: function (clearUrl) {
|
||||
$('.layuimini-clear').attr('data-href',clearUrl);
|
||||
$('.layuimini-clear').attr('data-href', clearUrl);
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -171,7 +171,7 @@ define(["jquery", "miniMenu", "miniTheme", "miniTab"], function ($, miniMenu, mi
|
||||
el.msExitFullscreen();
|
||||
} else if (el.oRequestFullscreen) {
|
||||
el.oCancelFullScreen();
|
||||
}else if (el.mozCancelFullScreen) {
|
||||
} else if (el.mozCancelFullScreen) {
|
||||
el.mozCancelFullScreen();
|
||||
} else if (el.webkitCancelFullScreen) {
|
||||
el.webkitCancelFullScreen();
|
||||
@@ -243,6 +243,92 @@ define(["jquery", "miniMenu", "miniTheme", "miniTab"], function ($, miniMenu, mi
|
||||
*/
|
||||
listen: function () {
|
||||
|
||||
layui.form.on('switch(header-theme-mode)', function (data) {
|
||||
let checked = data.elem.checked;
|
||||
let mode = checked ? 'dark' : 'light';
|
||||
changeTheme(mode);
|
||||
});
|
||||
|
||||
/**
|
||||
* 浅色和暗色主题切换
|
||||
*/
|
||||
const theme = colorMode.init({
|
||||
onChanged(mode, defaultHandler) {
|
||||
const isAppearanceTransition =
|
||||
document.startViewTransition && !window.matchMedia(`(prefers-reduced-motion: reduce)`).matches;
|
||||
const isDark = mode === 'dark';
|
||||
//跟随windows系统主题色的变化而变化,但没法保存选择的元素风格
|
||||
// var darkThemeMediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
|
||||
// var preferredDark = darkThemeMediaQuery.matches;
|
||||
// var currMode = preferredDark ? 'dark' : 'light';
|
||||
// changeTheme(currMode);
|
||||
$('#change-theme').attr('class', `layui-icon layui-icon-${isDark ? 'moon' : 'light'}`);
|
||||
|
||||
if (!isAppearanceTransition) {
|
||||
defaultHandler();
|
||||
} else {
|
||||
rippleViewTransition(isDark, function () {
|
||||
// 动画需要
|
||||
document.documentElement.classList[isDark ? 'add' : 'remove']('dark');
|
||||
defaultHandler();
|
||||
});
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
//切换特效
|
||||
function rippleViewTransition(isDark, callback) {
|
||||
// 移植自 https://github.com/vuejs/vitepress/pull/2347
|
||||
// 支持 Chrome 111+
|
||||
const x = event.clientX;
|
||||
const y = event.clientY;
|
||||
const endRadius = Math.hypot(Math.max(x, innerWidth - x), Math.max(y, innerHeight - y));
|
||||
const transition = document.startViewTransition(function () {
|
||||
callback && callback();
|
||||
});
|
||||
transition.ready.then(function () {
|
||||
var clipPath = [`circle(0px at ${x}px ${y}px)`, `circle(${endRadius}px at ${x}px ${y}px)`];
|
||||
document.documentElement.animate(
|
||||
{
|
||||
clipPath: isDark ? clipPath : [...clipPath].reverse(),
|
||||
},
|
||||
{
|
||||
duration: 300,
|
||||
easing: 'ease-in',
|
||||
pseudoElement: isDark ? '::view-transition-new(root)' : '::view-transition-old(root)',
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
//改变主题
|
||||
function changeTheme(mode) {
|
||||
switch (mode) {
|
||||
case 'dark':
|
||||
localStorage.setItem('layuiminiBgColorId', '1');
|
||||
localStorage.setItem('layuiminiElemStyleName', 'dark');
|
||||
changeBgColor(1);
|
||||
break;
|
||||
case 'light':
|
||||
localStorage.setItem('layuiminiBgColorId', '0');
|
||||
localStorage.setItem('layuiminiElemStyleName', 'normal');
|
||||
changeBgColor(0);
|
||||
break
|
||||
}
|
||||
window.onInitElemStyle()
|
||||
}
|
||||
|
||||
//改变配色
|
||||
function changeBgColor(id) {
|
||||
$('.layuimini-color .color-content ul .layui-this').attr('class', '');
|
||||
$(this).attr('class', 'layui-this');
|
||||
localStorage.setItem('layuiminiBgColorId', id);
|
||||
miniTheme.render({
|
||||
bgColorDefault: id,
|
||||
listen: false,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 清理
|
||||
*/
|
||||
@@ -289,14 +375,14 @@ define(["jquery", "miniMenu", "miniTheme", "miniTab"], function ($, miniMenu, mi
|
||||
tips = $(this).prop("innerHTML"),
|
||||
isShow = $('.layuimini-tool i').attr('data-side-fold');
|
||||
if (isShow == 0 && tips) {
|
||||
tips = "<ul class='layuimini-menu-left-zoom layui-nav layui-nav-tree layui-this'><li class='layui-nav-item layui-nav-itemed'>"+tips+"</li></ul>" ;
|
||||
tips = "<ul class='layuimini-menu-left-zoom layui-nav layui-nav-tree layui-this'><li class='layui-nav-item layui-nav-itemed'>" + tips + "</li></ul>";
|
||||
window.openTips = layer.tips(tips, $(this), {
|
||||
tips: [2, '#2f4056'],
|
||||
time: 300000,
|
||||
skin:"popup-tips",
|
||||
success:function (el) {
|
||||
var left = $(el).position().left - 10 ;
|
||||
$(el).css({ left:left });
|
||||
skin: "popup-tips",
|
||||
success: function (el) {
|
||||
var left = $(el).position().left - 10;
|
||||
$(el).css({left: left});
|
||||
element.render();
|
||||
}
|
||||
});
|
||||
@@ -345,6 +431,5 @@ define(["jquery", "miniMenu", "miniTheme", "miniTab"], function ($, miniMenu, mi
|
||||
};
|
||||
|
||||
|
||||
|
||||
return miniAdmin;
|
||||
});
|
||||
@@ -41,20 +41,20 @@ define(["jquery"], function ($) {
|
||||
headerRightBg: '#23262e', //头部右侧背景色
|
||||
headerRightBgThis: '#0c0c0c', //头部右侧选中背景色,
|
||||
headerRightColor: 'rgba(255,255,255,.7)', //头部右侧字体颜色,
|
||||
headerRightChildColor: '#676767', //头部右侧下拉字体颜色,
|
||||
headerRightColorThis: '#ffffff', //头部右侧鼠标选中,
|
||||
headerRightChildColor: 'rgba(255,255,255,.7)', //头部右侧下拉字体颜色,
|
||||
headerRightColorThis: 'rgba(255,255,255,.7)', //头部右侧鼠标选中,
|
||||
headerRightNavMore: 'rgba(255,255,255,.7)', //头部右侧更多下拉颜色,
|
||||
headerRightNavMoreBg: '#1aa094', //头部右侧更多下拉列表选中背景色,
|
||||
headerRightNavMoreColor: '#ffffff', //头部右侧更多下拉列表字体色,
|
||||
headerRightNavMoreColor: 'rgba(255,255,255,.7)', //头部右侧更多下拉列表字体色,
|
||||
headerRightToolColor: '#bbe3df', //头部缩放按钮样式,
|
||||
headerLogoBg: '#0c0c0c', //logo背景颜色,
|
||||
headerLogoColor: '#ffffff', //logo字体颜色,
|
||||
headerLogoColor: 'rgba(255,255,255,.7)', //logo字体颜色,
|
||||
leftMenuNavMore: 'rgb(191, 187, 187)', //左侧菜单更多下拉样式,
|
||||
leftMenuBg: '#23262e', //左侧菜单背景,
|
||||
leftMenuBgThis: '#737373', //左侧菜单选中背景,
|
||||
leftMenuChildBg: 'rgba(0,0,0,.3)', //左侧菜单子菜单背景,
|
||||
leftMenuColor: 'rgb(191, 187, 187)', //左侧菜单字体颜色,
|
||||
leftMenuColorThis: '#ffffff', //左侧菜单选中字体颜色,
|
||||
leftMenuBgThis: '#484849', //左侧菜单选中背景,
|
||||
leftMenuChildBg: '#23262e', //左侧菜单子菜单背景,
|
||||
leftMenuColor: 'rgba(255,255,255,.9)', //左侧菜单字体颜色,
|
||||
leftMenuColorThis: 'rgba(255,255,255,.7)', //左侧菜单选中字体颜色,
|
||||
tabActiveColor: '#23262e', //tab选项卡选中颜色,
|
||||
},
|
||||
{
|
||||
@@ -272,7 +272,7 @@ define(["jquery"], function ($) {
|
||||
render: function (options) {
|
||||
options.bgColorDefault = options.bgColorDefault || false;
|
||||
options.listen = options.listen || false;
|
||||
var bgcolorId = sessionStorage.getItem('layuiminiBgcolorId');
|
||||
var bgcolorId = localStorage.getItem('layuiminiBgColorId');
|
||||
if (bgcolorId === null || bgcolorId === undefined || bgcolorId === '') {
|
||||
bgcolorId = options.bgColorDefault;
|
||||
}
|
||||
@@ -280,6 +280,21 @@ define(["jquery"], function ($) {
|
||||
if (options.listen) miniTheme.listen(options);
|
||||
},
|
||||
|
||||
renderElemStyle(elemStyleDefault) {
|
||||
elemStyleDefault = elemStyleDefault || 'light';
|
||||
let elemStyleName = localStorage.getItem('layuiminiElemStyleName');
|
||||
if (!elemStyleName) elemStyleName = elemStyleDefault;
|
||||
let themeModeEle = $('input[name=theme-mode]')
|
||||
if (themeModeEle.length > 0) {
|
||||
if (elemStyleName == 'dark') {
|
||||
themeModeEle.prop('checked', true);
|
||||
} else {
|
||||
themeModeEle.prop('checked', false);
|
||||
}
|
||||
layui.form.render('checkbox', 'header-theme-mode');
|
||||
}
|
||||
miniTheme.buildBodyElemStyle(elemStyleName);
|
||||
},
|
||||
/**
|
||||
* 构建主题样式
|
||||
* @param bgcolorId
|
||||
@@ -386,7 +401,85 @@ define(["jquery"], function ($) {
|
||||
'}\n';
|
||||
$('#layuimini-bg-color').html(styleHtml);
|
||||
},
|
||||
configElemStyle() {
|
||||
var listElemStyle = [
|
||||
{
|
||||
title: '标准',
|
||||
className: 'normal'
|
||||
},
|
||||
{
|
||||
title: '原型',
|
||||
className: 'demo',
|
||||
defaultColorConfig: '12'
|
||||
},
|
||||
{
|
||||
title: '科幻',
|
||||
className: 'sicfi'
|
||||
},
|
||||
{
|
||||
title: 'GTK',
|
||||
className: 'gtk'
|
||||
},
|
||||
{
|
||||
title: '像素',
|
||||
className: 'nes',
|
||||
defaultColorConfig: '12'
|
||||
},
|
||||
{
|
||||
title: 'WIN7',
|
||||
className: 'win7',
|
||||
defaultColorConfig: '12'
|
||||
},
|
||||
{
|
||||
title: '拟物',
|
||||
className: 'neomorphic',
|
||||
|
||||
},
|
||||
{
|
||||
title: '暗黑',
|
||||
className: 'dark',
|
||||
defaultColorConfig: '1'
|
||||
|
||||
},
|
||||
]
|
||||
return listElemStyle;
|
||||
},
|
||||
buildBodyElemStyle(className) {
|
||||
|
||||
var listElemStyle = miniTheme.configElemStyle()
|
||||
|
||||
$.each(listElemStyle, function (index, item) {
|
||||
var classNameReal = 'elem-style-' + item.className;
|
||||
if ($('body').hasClass(classNameReal)) {
|
||||
$('body').removeClass(classNameReal);
|
||||
}
|
||||
})
|
||||
|
||||
$('body').addClass('elem-style-' + className)
|
||||
},
|
||||
buildElemStyleHtml(options) {
|
||||
var elemStyleName = localStorage.getItem('layuiminiElemStyleName');
|
||||
if (!elemStyleName) elemStyleName = options.elemStyleDefault;
|
||||
var listElemStyle = miniTheme.configElemStyle()
|
||||
var html = '';
|
||||
$.each(listElemStyle, function (key, val) {
|
||||
|
||||
if (typeof val.defaultColorConfig == 'undefined') {
|
||||
val.defaultColorConfig = '0'
|
||||
}
|
||||
|
||||
if (val.className === elemStyleName) {
|
||||
html += '<li class="layui-this style-item" data-select-style="' + val.className + '" data-default-color-config="' + val.defaultColorConfig + '">\n';
|
||||
} else {
|
||||
html += '<li id="' + val.className + '" class="style-item" data-select-style="' + val.className + '" data-default-color-config="' + val.defaultColorConfig + '">\n';
|
||||
}
|
||||
html +=
|
||||
val.title +
|
||||
|
||||
'</li>';
|
||||
});
|
||||
return html;
|
||||
},
|
||||
/**
|
||||
* 构建主题选择html
|
||||
* @param options
|
||||
@@ -394,7 +487,7 @@ define(["jquery"], function ($) {
|
||||
*/
|
||||
buildBgColorHtml: function (options) {
|
||||
options.bgColorDefault = options.bgColorDefault || 0;
|
||||
var bgcolorId = parseInt(sessionStorage.getItem('layuiminiBgcolorId'));
|
||||
var bgcolorId = parseInt(localStorage.getItem('layuiminiBgColorId'));
|
||||
if (isNaN(bgcolorId)) bgcolorId = options.bgColorDefault;
|
||||
var bgColorConfig = miniTheme.config();
|
||||
var html = '';
|
||||
@@ -457,12 +550,29 @@ define(["jquery"], function ($) {
|
||||
var bgcolorId = $(this).attr('data-select-bgcolor');
|
||||
$('.layuimini-color .color-content ul .layui-this').attr('class', '');
|
||||
$(this).attr('class', 'layui-this');
|
||||
sessionStorage.setItem('layuiminiBgcolorId', bgcolorId);
|
||||
localStorage.setItem('layuiminiBgColorId', bgcolorId);
|
||||
miniTheme.render({
|
||||
bgColorDefault: bgcolorId,
|
||||
listen: false,
|
||||
});
|
||||
});
|
||||
$('body').on('click', '[data-select-style]', function () {
|
||||
var elemStyleName = $(this).attr('data-select-style');
|
||||
|
||||
$(this).attr('class', 'layui-this').siblings().removeClass('layui-this');
|
||||
|
||||
var defaultColorConfig = $(this).attr('data-default-color-config');
|
||||
|
||||
if (defaultColorConfig && defaultColorConfig.length > 0) {
|
||||
localStorage.setItem('layuiminiBgColorId', defaultColorConfig);
|
||||
|
||||
}
|
||||
|
||||
localStorage.setItem('layuiminiElemStyleName', elemStyleName);
|
||||
miniTheme.render({
|
||||
listen: false,
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user