mirror of
https://github.com/ledccn/IYUUPlus.git
synced 2024-09-20 07:05:28 +00:00
初始化版本库
This commit is contained in:
commit
d1921a2753
2
.dockerignore
Normal file
2
.dockerignore
Normal file
|
@ -0,0 +1,2 @@
|
|||
.git
|
||||
*
|
17
.env.example
Normal file
17
.env.example
Normal file
|
@ -0,0 +1,17 @@
|
|||
APP_DEBUG=true
|
||||
|
||||
SERVER_PROCESS_GROUP=''
|
||||
SERVER_PROCESS_USER=''
|
||||
|
||||
DB_CONNECTION=mysql
|
||||
DB_HOST=127.0.0.1
|
||||
DB_PORT=3306
|
||||
DB_DATABASE=test
|
||||
DB_USERNAME=root
|
||||
DB_PASSWORD=123456
|
||||
|
||||
SESSION_DRIVER=file
|
||||
|
||||
REDIS_HOST=127.0.0.1
|
||||
REDIS_PASSWORD=null
|
||||
REDIS_PORT=6379
|
9
.gitignore
vendored
Normal file
9
.gitignore
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
/.git
|
||||
/.idea
|
||||
/.vscode
|
||||
/composer
|
||||
/db
|
||||
/composer.lock
|
||||
*.bat
|
||||
*.log
|
||||
.env
|
36
README.md
Normal file
36
README.md
Normal file
|
@ -0,0 +1,36 @@
|
|||
# 介绍
|
||||
|
||||
IYUUAutoReseed项目的升级版,常驻内存运行;集成webui界面、辅种、下载、定时访问URL、动态域名ddns等常用功能,提供完善的插件机制。
|
||||
|
||||
IYUU自动辅种工具,目前能对国内大部分的PT站点自动辅种,支持下载器集群,支持多盘位,支持多下载目录,支持远程连接等。
|
||||
|
||||
|
||||
|
||||
# 技术栈
|
||||
|
||||
| 类型 | 感谢 | 简介 |
|
||||
| -------- | ----------------------------------------- | ------------------------------------------------------------ |
|
||||
| 常驻服务 | webman | php语言编写,基于[workerman](https://www.workerman.net/)开发的高性能HTTP服务框架 |
|
||||
| 前端界面 | layui2.5.7、font-awesome-4.7.0、layuimini | layui(谐音:类UI) 是一款采用自身模块规范编写的前端 UI 框架 |
|
||||
| 开发语言 | PHP、HTML5、CSS3、JavaScript、Shell | |
|
||||
|
||||
|
||||
|
||||
# 支持的下载器
|
||||
|
||||
1. transmission
|
||||
2. qBittorrent
|
||||
|
||||
|
||||
|
||||
# 支持自动辅种的站点
|
||||
|
||||
学校、杜比、家园、天空、朋友、馒头、萌猫、我堡、猫站、铂金家、烧包、北洋、TCCF、南洋、TTG、映客、城市、52pt、brobits、备胎、SSD、CHD、ptmsg、leaguehd、聆音、瓷器、hdarea、eastgame(TLF)、1ptba、hdtime、hd4fans、opencd、hdbug、hdstreet、joyhd、u2、upxin(HDU)、oshen、discfan(GZT)、cnscg圣城(已删除)、北邮、CCFBits、dicmusic、天雪、葡萄、HDRoute、伊甸园hdbd、海胆haidan、HDfans、龙之家、百川PT。
|
||||
|
||||
|
||||
|
||||
# 接口开发文档
|
||||
|
||||
如果您懂得其他语言的开发,可以基于接口做成任何您喜欢的样子,比如手机APP,二进制包,Windows的GUI程序,浏览器插件等。欢迎分享您的作品!
|
||||
|
||||
实时更新的接口文档:http://api.iyuu.cn/docs.php
|
124
app/common/Config.php
Normal file
124
app/common/Config.php
Normal file
|
@ -0,0 +1,124 @@
|
|||
<?php
|
||||
namespace app\common;
|
||||
|
||||
/**
|
||||
* 配置文件读写类
|
||||
* @access private 常驻内存运行,禁止执行器调用
|
||||
*/
|
||||
class Config
|
||||
{
|
||||
/**
|
||||
* 扩展名映射表
|
||||
*/
|
||||
const extMap = [
|
||||
'array' => '.php',
|
||||
'json' => '.json',
|
||||
'object'=> '.data',
|
||||
];
|
||||
|
||||
/**
|
||||
* 写入配置
|
||||
* @param string $filename 文件名
|
||||
* @param mixed $data 数据
|
||||
* @param string $type 数据类型
|
||||
* @param bool $absolutePath 绝对路径
|
||||
* @return bool|int
|
||||
*/
|
||||
public static function set(string $filename, $data, string $type = 'array', bool $absolutePath = false)
|
||||
{
|
||||
if (empty($filename)) {
|
||||
return false;
|
||||
}
|
||||
$file_name = $absolutePath ? $filename : static::createFilePath($filename, $type);
|
||||
|
||||
clearstatcache();
|
||||
if (file_exists($file_name)) {
|
||||
chmod($file_name, 0777);
|
||||
}
|
||||
switch (strtolower($type)) {
|
||||
case 'object':
|
||||
$str = serialize($data);
|
||||
break;
|
||||
case 'json':
|
||||
$str = json_encode($data, JSON_UNESCAPED_UNICODE);
|
||||
break;
|
||||
case 'array':
|
||||
$str = '<?php'.PHP_EOL.'return ' . var_export($data, true) . ';'.PHP_EOL;
|
||||
break;
|
||||
default:
|
||||
$str = $data;
|
||||
break;
|
||||
}
|
||||
|
||||
$writeLen = file_put_contents($file_name, $str);
|
||||
return $writeLen === 0 ? false : $writeLen;
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取配置
|
||||
* @param string $filename 文件名
|
||||
* @param string $type 数据类型
|
||||
* @param null $default 默认值
|
||||
* @param bool $absolutePath 绝对路径
|
||||
* @return false|string|null|array
|
||||
*/
|
||||
public static function get(string $filename, string $type = 'array', $default = null, bool $absolutePath = false)
|
||||
{
|
||||
if (empty($filename)) {
|
||||
return $default;
|
||||
}
|
||||
$file_name = $absolutePath ? $filename : static::createFilePath($filename, $type);
|
||||
|
||||
clearstatcache();
|
||||
if (is_file($file_name)) {
|
||||
switch (strtolower($type)) {
|
||||
case 'object':
|
||||
$d = @unserialize(file_get_contents($file_name, false, null));
|
||||
break;
|
||||
case 'json':
|
||||
$d = json_decode(file_get_contents($file_name, false, null), JSON_UNESCAPED_UNICODE);
|
||||
break;
|
||||
case 'array':
|
||||
$d = include $file_name;
|
||||
break;
|
||||
default:
|
||||
$d = file_get_contents($file_name, false, null);
|
||||
break;
|
||||
}
|
||||
return $d;
|
||||
}
|
||||
|
||||
return $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除配置
|
||||
* @param string $name
|
||||
* @param bool $absolutePath
|
||||
* @return bool
|
||||
*/
|
||||
public static function delete(string $name, bool $absolutePath = false)
|
||||
{
|
||||
if ($name === null || $name === '') {
|
||||
return false;
|
||||
}
|
||||
$file_name = $absolutePath ? $name : db_path() . DIRECTORY_SEPARATOR . $name;
|
||||
clearstatcache();
|
||||
if (is_file($file_name)) {
|
||||
return @unlink($file_name);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建文件路径
|
||||
* @param string $name
|
||||
* @param string $type
|
||||
* @return string
|
||||
*/
|
||||
public static function createFilePath(string $name = '', string $type = 'array'):string
|
||||
{
|
||||
$ext = isset(self::extMap[$type]) ? self::extMap[$type] : self::extMap['object'];
|
||||
return db_path() . DIRECTORY_SEPARATOR . $name . $ext;
|
||||
}
|
||||
}
|
60
app/common/Constant.php
Normal file
60
app/common/Constant.php
Normal file
|
@ -0,0 +1,60 @@
|
|||
<?php
|
||||
namespace app\common;
|
||||
|
||||
/**
|
||||
* 全局常量定义
|
||||
* @access private 常驻内存运行,禁止执行器调用
|
||||
*/
|
||||
class Constant
|
||||
{
|
||||
const UserAgent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36';
|
||||
|
||||
//用户登录后用来保存IYUU token的Session键名
|
||||
const Session_Token_Key = 'token';
|
||||
/**
|
||||
* API定义
|
||||
*/
|
||||
const API_BASE = 'http://api.iyuu.cn';
|
||||
const API = [
|
||||
'login' => '/user/login',
|
||||
'sites' => '/api/sites',
|
||||
'infohash'=> '/api/infohash',
|
||||
'hash' => '/api/hash',
|
||||
'notify' => '/api/notify',
|
||||
'recommend' => '/Api/GetRecommendSites'
|
||||
];
|
||||
|
||||
/**
|
||||
* 配置文件默认保存格式
|
||||
*/
|
||||
const config_format = 'json';
|
||||
|
||||
/**
|
||||
* 编辑配置时配置文件的键名
|
||||
*/
|
||||
const config_filename = 'config_filename';
|
||||
|
||||
/**
|
||||
* 编辑配置时动作的键名
|
||||
*/
|
||||
const action = 'action';
|
||||
|
||||
/**
|
||||
* 模拟数据库主键UUID的键名
|
||||
*/
|
||||
const uuid = 'uuid';
|
||||
|
||||
/**
|
||||
* 接口返回的数据结构
|
||||
* @var array
|
||||
*/
|
||||
const RS = [
|
||||
'ret' => 200,
|
||||
'data' => [],
|
||||
'msg' => ''
|
||||
];
|
||||
|
||||
/**
|
||||
* 全局错误码
|
||||
*/
|
||||
}
|
101
app/common/ICheck.php
Normal file
101
app/common/ICheck.php
Normal file
|
@ -0,0 +1,101 @@
|
|||
<?php
|
||||
namespace app\common;
|
||||
|
||||
/**
|
||||
* 检查扩展与函数
|
||||
*/
|
||||
class ICheck
|
||||
{
|
||||
/**
|
||||
* 待检查扩展列表
|
||||
* @var array
|
||||
*/
|
||||
private static $extends = [
|
||||
//Win
|
||||
'1' => [
|
||||
'json',
|
||||
'curl',
|
||||
'mbstring',
|
||||
],
|
||||
//Linux
|
||||
'2' => [
|
||||
'json',
|
||||
'curl',
|
||||
'mbstring',
|
||||
'pcntl',
|
||||
'posix',
|
||||
]
|
||||
];
|
||||
|
||||
/**
|
||||
* 待检查函数列表
|
||||
* @var array
|
||||
*/
|
||||
private static $functions = [
|
||||
//Win
|
||||
'1' => [
|
||||
'usleep',
|
||||
'sleep',
|
||||
'ob_start',
|
||||
'ob_end_clean',
|
||||
'ob_get_contents',
|
||||
'proc_open',
|
||||
'proc_close',
|
||||
],
|
||||
//Linux
|
||||
'2' => [
|
||||
'chdir',
|
||||
'usleep',
|
||||
'sleep',
|
||||
'ob_start',
|
||||
'ob_end_clean',
|
||||
'ob_get_contents',
|
||||
'proc_open',
|
||||
'proc_close',
|
||||
'pcntl_fork',
|
||||
'posix_setsid',
|
||||
'posix_getpid',
|
||||
'posix_getppid',
|
||||
'pcntl_wait',
|
||||
'posix_kill',
|
||||
'pcntl_signal',
|
||||
'pcntl_alarm',
|
||||
'pcntl_waitpid',
|
||||
'pcntl_signal_dispatch',
|
||||
'stream_socket_server',
|
||||
'stream_socket_client',
|
||||
]
|
||||
];
|
||||
|
||||
/**
|
||||
* 解析运行环境
|
||||
* @param int $currentOs
|
||||
*/
|
||||
public static function analysis($currentOs)
|
||||
{
|
||||
//检查版本
|
||||
if(version_compare(PHP_VERSION, "7.2.0", "<"))
|
||||
{
|
||||
exit('php version < 7.2.0');
|
||||
}
|
||||
//检查扩展
|
||||
$waitExtends = static::$extends[$currentOs];
|
||||
foreach ($waitExtends as $extend)
|
||||
{
|
||||
if (!extension_loaded($extend))
|
||||
{
|
||||
exit("php_{$extend}.(dll/so) is not load,please check php.ini file");
|
||||
}
|
||||
}
|
||||
//检查函数
|
||||
$waitFunctions = static::$functions[$currentOs];
|
||||
foreach ($waitFunctions as $func)
|
||||
{
|
||||
if (!function_exists($func))
|
||||
{
|
||||
exit("function $func may be disabled,please check disable_functions in php.ini");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
46
app/common/components/Curl.php
Normal file
46
app/common/components/Curl.php
Normal file
|
@ -0,0 +1,46 @@
|
|||
<?php
|
||||
namespace app\common\components;
|
||||
|
||||
use app\common\Constant;
|
||||
use Curl\Curl as ICurl;
|
||||
|
||||
/**
|
||||
* 单例Curl
|
||||
* @access private 常驻内存运行,禁止执行器调用
|
||||
*/
|
||||
class Curl
|
||||
{
|
||||
/**
|
||||
* 单例
|
||||
* @var null | ICurl
|
||||
*/
|
||||
protected static $_instance = null;
|
||||
|
||||
/**
|
||||
* 私有化构造函数,避免外部new
|
||||
*/
|
||||
private function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* 单例
|
||||
* @param bool $reset
|
||||
* @return ICurl
|
||||
*/
|
||||
public static function one($reset = true)
|
||||
{
|
||||
if (self::$_instance === null) {
|
||||
self::$_instance = new ICurl();
|
||||
} else {
|
||||
// 重置
|
||||
if ($reset) {
|
||||
self::$_instance->reset();
|
||||
}
|
||||
}
|
||||
|
||||
// 设置UserAgent
|
||||
self::$_instance->setUserAgent(Constant::UserAgent);
|
||||
return self::$_instance;
|
||||
}
|
||||
}
|
14
app/common/exception/BusinessException.php
Normal file
14
app/common/exception/BusinessException.php
Normal file
|
@ -0,0 +1,14 @@
|
|||
<?php
|
||||
namespace app\common\exception;
|
||||
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* Class BusinessException
|
||||
* @access private 常驻内存运行,禁止执行器调用
|
||||
* @package app\common\exception
|
||||
*/
|
||||
class BusinessException extends Exception
|
||||
{
|
||||
|
||||
}
|
51
app/common/exception/Handler.php
Normal file
51
app/common/exception/Handler.php
Normal file
|
@ -0,0 +1,51 @@
|
|||
<?php
|
||||
namespace app\common\exception;
|
||||
|
||||
use Throwable;
|
||||
use Webman\Exception\ExceptionHandler;
|
||||
use Webman\Http\Request;
|
||||
use Webman\Http\Response;
|
||||
|
||||
/**
|
||||
* @access private 常驻内存运行,禁止执行器调用
|
||||
* Class Handler
|
||||
* @package app\common\exception
|
||||
*/
|
||||
class Handler extends ExceptionHandler
|
||||
{
|
||||
/**
|
||||
* 记录日志
|
||||
* @param Throwable $exception
|
||||
*/
|
||||
public function report(Throwable $exception)
|
||||
{
|
||||
//仅调试模式记录日志
|
||||
if ($this->_debug) {
|
||||
parent::report($exception);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 渲染返回
|
||||
* @param Request $request
|
||||
* @param Throwable $exception
|
||||
* @return Response
|
||||
*/
|
||||
public function render(Request $request, Throwable $exception) : Response
|
||||
{
|
||||
$header = [
|
||||
'Content-Type' => 'application/json; charset=utf-8',
|
||||
'Connection' => 'close',
|
||||
'Pragma' => 'no-cache'
|
||||
];
|
||||
$code = $exception->getCode();
|
||||
$error = $exception->getMessage();
|
||||
$rs = [
|
||||
'ret' => $code,
|
||||
'data' => [],
|
||||
'msg' => $error
|
||||
];
|
||||
$this->_debug && $rs['traces'] = (string)$exception;
|
||||
return new Response(200, $header, json_encode($rs, JSON_UNESCAPED_UNICODE));
|
||||
}
|
||||
}
|
26
app/common/middleware/AuthCheck.php
Normal file
26
app/common/middleware/AuthCheck.php
Normal file
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
namespace app\common\middleware;
|
||||
|
||||
use Webman\MiddlewareInterface;
|
||||
use Webman\Http\Response;
|
||||
use Webman\Http\Request;
|
||||
use app\common\Constant;
|
||||
|
||||
/**
|
||||
* [中间件] 拦截未登录的Session
|
||||
* @access private 常驻内存运行,禁止执行器调用
|
||||
*/
|
||||
class AuthCheck implements MiddlewareInterface
|
||||
{
|
||||
public function process(Request $request, callable $next) : Response
|
||||
{
|
||||
$session = $request->session();
|
||||
$action = $request->action;
|
||||
$skip = in_array($action, ['Login', 'checkLogin', 'BindToken']); // 严格区分大小写
|
||||
// 拦截条件:token不存在 & 非登录操作
|
||||
if (!$skip && !$session->get(Constant::Session_Token_Key)) {
|
||||
return redirect('/page/login.html');
|
||||
}
|
||||
return $next($request);
|
||||
}
|
||||
}
|
159
app/controller/Api.php
Normal file
159
app/controller/Api.php
Normal file
|
@ -0,0 +1,159 @@
|
|||
<?php
|
||||
namespace app\controller;
|
||||
|
||||
use support\Request;
|
||||
use support\Response;
|
||||
use app\common\exception\BusinessException;
|
||||
use app\common\Config;
|
||||
use app\common\Constant;
|
||||
use app\domain\Config as domainConfig;
|
||||
use app\domain\Users as domainUsers;
|
||||
|
||||
/**
|
||||
* Class Api
|
||||
* @access private 常驻内存运行,禁止执行器调用
|
||||
* @package app\controller
|
||||
*/
|
||||
class Api extends BaseController
|
||||
{
|
||||
/**
|
||||
* 登录 [跳过AuthCheck中间件]
|
||||
* @param Request $request
|
||||
* @return Response
|
||||
*/
|
||||
public function Login(Request $request): Response
|
||||
{
|
||||
$rs = self::RS;
|
||||
$token = $request->get('token');
|
||||
if (check_token($token)) {
|
||||
$rs = domainUsers::checkToken($token, $request);
|
||||
} else {
|
||||
$rs['ret'] = 401;
|
||||
$rs['msg'] = 'Token格式错误!';
|
||||
}
|
||||
|
||||
return json($rs);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询用户Session是否已登录 [跳过AuthCheck中间件]
|
||||
* @desc 因静态页无法响应301/302状态码,所以加入此接口供前端主动调用
|
||||
* @param Request $request
|
||||
* @return Response
|
||||
*/
|
||||
public function checkLogin(Request $request): Response
|
||||
{
|
||||
$rs = self::RS;
|
||||
$rs['data'] = [
|
||||
'is_login' => domainUsers::isLogin($request)
|
||||
];
|
||||
|
||||
return json($rs);
|
||||
}
|
||||
|
||||
/**
|
||||
* 爱语飞飞Token与用户站点进行绑定 [跳过AuthCheck中间件]
|
||||
* @param Request $request
|
||||
* @return Response
|
||||
*/
|
||||
public function BindToken(Request $request): Response
|
||||
{
|
||||
$rs = self::RS;
|
||||
$token = $request->post('token');
|
||||
if (check_token($token)) {
|
||||
$rs = domainUsers::bindToken($token, $request);
|
||||
} else {
|
||||
$rs['ret'] = 401;
|
||||
$rs['msg'] = 'Token格式错误!';
|
||||
}
|
||||
|
||||
return json($rs);
|
||||
}
|
||||
|
||||
/**
|
||||
* 退出登录
|
||||
* @param Request $request
|
||||
* @return Response
|
||||
*/
|
||||
public function Logout(Request $request): Response
|
||||
{
|
||||
$request->session()->flush();
|
||||
return json(self::RS);
|
||||
}
|
||||
|
||||
/**
|
||||
* 版本信息
|
||||
* @param Request $request
|
||||
* @return mixed
|
||||
*/
|
||||
public function Version(Request $request): Response
|
||||
{
|
||||
return json(config());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取菜单
|
||||
* @param Request $request
|
||||
* @return Response
|
||||
*/
|
||||
public function Menu(Request $request): Response
|
||||
{
|
||||
$filepath = public_path() . DIRECTORY_SEPARATOR . 'api' . DIRECTORY_SEPARATOR . 'init.json';
|
||||
$init = Config::get($filepath, 'json', [], true);
|
||||
//TODO 前端菜单注入接口
|
||||
return json($init);
|
||||
}
|
||||
|
||||
/**
|
||||
* 配置接口{增、删、改、查}
|
||||
* @param Request $request
|
||||
* @return Response
|
||||
*/
|
||||
public function Config(Request $request): Response
|
||||
{
|
||||
$rs = self::RS;
|
||||
$key = Constant::config_filename;
|
||||
// 取值优先级:get > post
|
||||
$config_filename = $request->get($key) ? $request->get($key) : $request->post($key); // 值对应( /db/?.ext )这个文件名
|
||||
if ($config_filename) {
|
||||
$rs = domainConfig::main($config_filename, $request);
|
||||
} else {
|
||||
$rs['ret'] = 403;
|
||||
$rs['msg'] = 'config_filename错误!';
|
||||
}
|
||||
return json($rs);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取站点列表
|
||||
* @param Request $request
|
||||
* @return Response
|
||||
* @throws BusinessException
|
||||
*/
|
||||
public function sitesList(Request $request): Response
|
||||
{
|
||||
$rs = self::RS;
|
||||
$data = Config::get('sites', Constant::config_format);
|
||||
if (empty($data)) {
|
||||
throw new BusinessException('您的账号尚未进行用户验证。', 401);
|
||||
}
|
||||
$sites = array_keys($data);
|
||||
sort($sites);
|
||||
$rs['data']['sites'] = $sites;
|
||||
$rs['data']['total'] = count($sites);
|
||||
return json($rs);
|
||||
}
|
||||
|
||||
/**
|
||||
* 清理缓存
|
||||
* @param Request $request
|
||||
* @return Response
|
||||
*/
|
||||
public function Clear(Request $request): Response
|
||||
{
|
||||
$config = config('server');
|
||||
$log_file = Config::set($config['log_file'], date('Y-m-d H:i:s').' 清理日志'.PHP_EOL, 'raw', true);
|
||||
$stdout_file = Config::set($config['stdout_file'], date('Y-m-d H:i:s').' 清理日志'.PHP_EOL, 'raw', true);
|
||||
return json(['code' => 1, 'msg' => '清理成功', 'data' => []]);
|
||||
}
|
||||
}
|
60
app/controller/BaseController.php
Normal file
60
app/controller/BaseController.php
Normal file
|
@ -0,0 +1,60 @@
|
|||
<?php
|
||||
namespace app\controller;
|
||||
|
||||
use app\common\exception\BusinessException;
|
||||
use app\common\Constant;
|
||||
use app\domain\Users as domainUsers;
|
||||
use support\Request;
|
||||
use support\Response;
|
||||
|
||||
/**
|
||||
* 控制器基类
|
||||
* @access private 常驻内存运行,禁止执行器调用
|
||||
*/
|
||||
class BaseController
|
||||
{
|
||||
/**
|
||||
* 接口返回数据结构
|
||||
* @var array
|
||||
*/
|
||||
const RS = Constant::RS;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* 接口参数
|
||||
* @param string $name 接口参数名字
|
||||
* @param mixed $value 接口参数解析后的值
|
||||
*/
|
||||
public function __set($name, $value) {
|
||||
$this->$name = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取接口参数
|
||||
* @param string $name 接口参数名字
|
||||
* @return mixed
|
||||
* @throws BusinessException
|
||||
*/
|
||||
public function __get($name) {
|
||||
if(!isset($this->$name) || empty($name)) {
|
||||
throw new BusinessException(sprintf('$this->%s not null', $name));
|
||||
}
|
||||
|
||||
return $this->$name;
|
||||
}
|
||||
|
||||
/**
|
||||
* 默认控制器
|
||||
* @descr 检查未登录重定向
|
||||
* @param Request $request
|
||||
* @return Response
|
||||
*/
|
||||
public function index(Request $request)
|
||||
{
|
||||
$url = domainUsers::isLogin($request) ? '/index.html' : '/page/login.html';
|
||||
return redirect($url);
|
||||
}
|
||||
}
|
46
app/controller/Index.php
Normal file
46
app/controller/Index.php
Normal file
|
@ -0,0 +1,46 @@
|
|||
<?php
|
||||
namespace app\controller;
|
||||
|
||||
use app\domain\Users as domainUsers;
|
||||
use support\Request;
|
||||
use support\Response;
|
||||
|
||||
/**
|
||||
* Class Index
|
||||
* @access private 常驻内存运行,禁止执行器调用
|
||||
* @package app\controller
|
||||
*/
|
||||
class Index
|
||||
{
|
||||
/**
|
||||
* 默认控制器
|
||||
* @descr 检查未登录重定向
|
||||
* @param Request $request
|
||||
* @return Response
|
||||
*/
|
||||
public function index(Request $request): Response
|
||||
{
|
||||
$url = domainUsers::isLogin($request) ? '/index.html' : '/page/login.html';
|
||||
return redirect($url);
|
||||
}
|
||||
|
||||
public function view(Request $request): Response
|
||||
{
|
||||
return view('index/view', ['name' => 'webman']);
|
||||
}
|
||||
|
||||
public function json(Request $request): Response
|
||||
{
|
||||
return json(['code' => 0, 'msg' => 'ok']);
|
||||
}
|
||||
|
||||
public function file(Request $request): Response
|
||||
{
|
||||
$file = $request->file('upload');
|
||||
if ($file && $file->isValid()) {
|
||||
$file->move(public_path().'/files/myfile.'.$file->getUploadExtension());
|
||||
return json(['code' => 0, 'msg' => 'upload success']);
|
||||
}
|
||||
return json(['code' => 1, 'msg' => 'file not found']);
|
||||
}
|
||||
}
|
33
app/controller/Status.php
Normal file
33
app/controller/Status.php
Normal file
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
namespace app\controller;
|
||||
|
||||
use support\Request;
|
||||
use support\Response;
|
||||
use app\common\exception\BusinessException;
|
||||
use app\common\Config;
|
||||
use app\common\Constant;
|
||||
|
||||
/**
|
||||
* Class Status
|
||||
* @package app\controller
|
||||
*/
|
||||
class Status extends BaseController
|
||||
{
|
||||
/**
|
||||
* 系统日志
|
||||
* @param Request $request
|
||||
* @return Response
|
||||
*/
|
||||
public function syslog(Request $request): Response
|
||||
{
|
||||
$rs = self::RS;
|
||||
$config = config('server');
|
||||
$log_file = Config::get($config['log_file'], 'raw', '', true);
|
||||
$stdout_file = Config::get($config['stdout_file'], 'raw', '', true);
|
||||
$rs['data'] = [
|
||||
'log_file' => $log_file,
|
||||
'stdout_file' => $stdout_file,
|
||||
];
|
||||
return json($rs);
|
||||
}
|
||||
}
|
111
app/controller/Task.php
Normal file
111
app/controller/Task.php
Normal file
|
@ -0,0 +1,111 @@
|
|||
<?php
|
||||
namespace app\controller;
|
||||
|
||||
use support\Request;
|
||||
use support\Response;
|
||||
use app\domain\Crontab;
|
||||
use app\domain\Reseed as domainReseed;
|
||||
|
||||
/**
|
||||
* Class Task
|
||||
* @access private 常驻内存运行,禁止执行器调用
|
||||
* @package app\controller
|
||||
*/
|
||||
class Task extends BaseController
|
||||
{
|
||||
|
||||
/**
|
||||
* 根据参数,解析辅种的站点和下载器
|
||||
* @param Request $request
|
||||
* @return Response
|
||||
*/
|
||||
public function reseedConfig(Request $request): Response
|
||||
{
|
||||
$rs = self::RS;
|
||||
$uuid = $request->get('uuid');
|
||||
return json(domainReseed::configParser($uuid));
|
||||
}
|
||||
|
||||
/**
|
||||
* 开启|关闭,计划任务
|
||||
* @param Request $request
|
||||
* @return Response
|
||||
*/
|
||||
public function switch(Request $request): Response
|
||||
{
|
||||
$rs = self::RS;
|
||||
$uuid = $request->get('uuid');
|
||||
$switch = $request->get('switch');
|
||||
return json(domainReseed::configParser($uuid));
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行计划任务
|
||||
* @param Request $request
|
||||
* @return Response
|
||||
*/
|
||||
public function start(Request $request): Response
|
||||
{
|
||||
$rs = self::RS;
|
||||
$uuid = $request->get('uuid');
|
||||
$rs['data'] = [
|
||||
'success' => Crontab::runCron($uuid)
|
||||
];
|
||||
return json($rs);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查看任务的log
|
||||
* @param Request $request
|
||||
* @return Response
|
||||
*/
|
||||
public function logs(Request $request): Response
|
||||
{
|
||||
$rs = self::RS;
|
||||
$uuid = $request->get('uuid');
|
||||
$rs['data'] = [
|
||||
'uuid' => $uuid,
|
||||
'logs' => Crontab::readLogs($uuid)
|
||||
];
|
||||
return json($rs);
|
||||
}
|
||||
|
||||
/**
|
||||
* 清空任务log
|
||||
* @param Request $request
|
||||
* @return Response
|
||||
*/
|
||||
public function clearLogs(Request $request): Response
|
||||
{
|
||||
$rs = self::RS;
|
||||
$uuid = $request->get('uuid');
|
||||
$rs['data'] = [
|
||||
'uuid' => $uuid,
|
||||
'success' => Crontab::clearLogs($uuid)
|
||||
];
|
||||
return json($rs);
|
||||
}
|
||||
|
||||
/**
|
||||
* 停止正在执行的计划任务
|
||||
* @param Request $request
|
||||
* @return Response
|
||||
*/
|
||||
public function stop(Request $request): Response
|
||||
{
|
||||
$rs = self::RS;
|
||||
$uuid = $request->get('uuid');
|
||||
return json(domainReseed::configParser($uuid));
|
||||
}
|
||||
|
||||
/**
|
||||
* 调试接口
|
||||
* @param Request $request
|
||||
* @return Response
|
||||
*/
|
||||
public function test(Request $request): Response
|
||||
{
|
||||
$rs = self::RS;
|
||||
return json($rs);
|
||||
}
|
||||
}
|
42
app/domain/Command.php
Normal file
42
app/domain/Command.php
Normal file
|
@ -0,0 +1,42 @@
|
|||
<?php
|
||||
namespace app\domain;
|
||||
|
||||
/**
|
||||
* 解析计划任务命令
|
||||
* Class Command
|
||||
* @package app\domain
|
||||
*/
|
||||
class Command
|
||||
{
|
||||
public static function parse(array $param):string
|
||||
{
|
||||
$taskType = $param['type'] ?? null;
|
||||
switch ($taskType) {
|
||||
case 'reseed':
|
||||
return PHP_BINARY . ' ' . BASE_PATH . DIRECTORY_SEPARATOR . 'bin/iyuu.php '.$param['uuid'];
|
||||
default:
|
||||
return 'date';
|
||||
}
|
||||
}
|
||||
|
||||
public static function Reseed()
|
||||
{}
|
||||
|
||||
public static function Download()
|
||||
{}
|
||||
|
||||
public static function Url()
|
||||
{}
|
||||
|
||||
public static function Shell()
|
||||
{}
|
||||
|
||||
public static function Patch()
|
||||
{}
|
||||
|
||||
public static function Ddns()
|
||||
{}
|
||||
|
||||
public static function ClearLog()
|
||||
{}
|
||||
}
|
160
app/domain/Config.php
Normal file
160
app/domain/Config.php
Normal file
|
@ -0,0 +1,160 @@
|
|||
<?php
|
||||
namespace app\domain;
|
||||
|
||||
use app\common\Config as Conf;
|
||||
use app\common\Constant;
|
||||
use support\Request;
|
||||
|
||||
/**
|
||||
* 配置文件的增删改查
|
||||
* @access private 常驻内存运行,禁止执行器调用
|
||||
*/
|
||||
class Config
|
||||
{
|
||||
/**
|
||||
* 配置文件名 [不含扩展名]
|
||||
*/
|
||||
const filename = [
|
||||
'clients' => 'clients',
|
||||
'crontab' => 'crontab',
|
||||
'default' => 'default',
|
||||
'filter' => 'filter',
|
||||
'folder' => 'folder',
|
||||
'init' => 'init',
|
||||
'iyuu' => 'iyuu',
|
||||
'mail' => 'mail',
|
||||
'sites' => 'sites',
|
||||
'sms' => 'sms',
|
||||
'user' => 'user',
|
||||
'user_sites'=> 'user_sites',
|
||||
'weixin' => 'weixin',
|
||||
];
|
||||
|
||||
/**
|
||||
* 主入口
|
||||
* @param string $config_filename 配置文件名
|
||||
* @param Request $request 请求对象
|
||||
* @return array
|
||||
*/
|
||||
public static function main(string $config_filename, Request $request):array
|
||||
{
|
||||
$rs = Constant::RS;
|
||||
// 取值优先级:get > post
|
||||
$action = $request->get(Constant::action) ? $request->get(Constant::action) : $request->post(Constant::action);
|
||||
if ($action === 'get') {
|
||||
// 返回原始数据
|
||||
$rs['data'] = Conf::get($config_filename, Constant::config_format, []);
|
||||
return $rs;
|
||||
} else {
|
||||
switch ($config_filename) {
|
||||
case 'clients':
|
||||
case 'filter':
|
||||
case 'folder':
|
||||
case 'crontab':
|
||||
return self::uuid($config_filename, $request);
|
||||
case 'user_sites':
|
||||
return self::uuid($config_filename, $request, 'name');
|
||||
default:
|
||||
return self::default($config_filename, $request);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 用UUID模拟数据库主键实现配置的增删改查
|
||||
* @param string $config_filename 配置文件名
|
||||
* @param Request $request 请求对象
|
||||
* @param null $PRIMARY 主键
|
||||
* @return array
|
||||
*/
|
||||
public static function uuid(string $config_filename, Request $request, $PRIMARY = null):array
|
||||
{
|
||||
$rs = Constant::RS;
|
||||
$old_config = Conf::get($config_filename, Constant::config_format, []);
|
||||
// 取值优先级:get > post
|
||||
$action = $request->get(Constant::action) ? $request->get(Constant::action) : $request->post(Constant::action);
|
||||
switch ($action) {
|
||||
case 'add': // 增
|
||||
$data = $request->post();
|
||||
self::createDataExcludeKeys($data);
|
||||
$uuid = is_null($PRIMARY) ? getUUID() : ($data[$PRIMARY] ?? getUUID());
|
||||
$data[Constant::uuid] = $uuid;
|
||||
$config_filename === self::filename['crontab'] and Crontab::createHock($data); //计划任务
|
||||
$data = array_merge($old_config, [$data[Constant::uuid] => $data]);
|
||||
Conf::set($config_filename, $data, Constant::config_format);
|
||||
env('APP_DEBUG', false) and Conf::set($config_filename, $data, 'array'); // 调试
|
||||
$rs['data'] = ['add_num' => 1];
|
||||
break;
|
||||
case 'del': // 删
|
||||
$uuid = $request->get(Constant::uuid);
|
||||
$config_filename === self::filename['crontab'] and Crontab::deleteHock($uuid); //计划任务
|
||||
if ($uuid && array_key_exists($uuid, $old_config)) {
|
||||
unset($old_config[$uuid]);
|
||||
Conf::set($config_filename, $old_config, Constant::config_format);
|
||||
env('APP_DEBUG', false) and Conf::set($config_filename, $old_config, 'array'); // 调试
|
||||
$rs['data'] = ['delete_num' => 1];
|
||||
}
|
||||
break;
|
||||
case 'edit': // 改
|
||||
$data = $request->post();
|
||||
self::createDataExcludeKeys($data);
|
||||
$uuid = $request->post(Constant::uuid);
|
||||
if ($uuid && array_key_exists($uuid, $old_config)) {
|
||||
$config_filename === self::filename['crontab'] and Crontab::createHock($data); //计划任务
|
||||
$old_config[$uuid] = $data;
|
||||
Conf::set($config_filename, $old_config, Constant::config_format);
|
||||
env('APP_DEBUG', false) and Conf::set($config_filename, $old_config, 'array'); // 调试
|
||||
$rs['data'] = ['update_num' => 1];
|
||||
}
|
||||
break;
|
||||
default: // 查 tableList
|
||||
$total = count($old_config);
|
||||
if ($total >= 1) {
|
||||
$rs['data'] = [
|
||||
'total' => $total,
|
||||
'items' => array_values($old_config)
|
||||
];
|
||||
} else {
|
||||
$rs['data'] = [
|
||||
'total' => 0,
|
||||
'items' => []
|
||||
];
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return $rs;
|
||||
}
|
||||
|
||||
/**
|
||||
* 简单操作的增删改查
|
||||
* @param string $config_filename
|
||||
* @param Request $request
|
||||
* @return array
|
||||
*/
|
||||
public static function default(string $config_filename, Request $request):array
|
||||
{
|
||||
$data = $request->post();
|
||||
self::createDataExcludeKeys($data);
|
||||
Conf::set($config_filename, $data, Constant::config_format);
|
||||
return Constant::RS;
|
||||
}
|
||||
|
||||
/**
|
||||
* 排除字段
|
||||
* @param $data
|
||||
*/
|
||||
protected static function createDataExcludeKeys(&$data) {
|
||||
if (is_array($data)) {
|
||||
foreach ([Constant::config_filename, Constant::action] as $key) {
|
||||
unset($data[$key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 把旧配置格式转换为新格式 [兼容性处理]
|
||||
*/
|
||||
public static function format()
|
||||
{}
|
||||
}
|
326
app/domain/Crontab.php
Normal file
326
app/domain/Crontab.php
Normal file
|
@ -0,0 +1,326 @@
|
|||
<?php
|
||||
namespace app\domain;
|
||||
|
||||
use app\common\Config as Conf;
|
||||
use app\common\Constant;
|
||||
use app\domain\Config as domainConfig;
|
||||
|
||||
/**
|
||||
* 计划任务相关
|
||||
* @access private 常驻内存运行,禁止执行器调用
|
||||
*/
|
||||
class Crontab
|
||||
{
|
||||
// 定时任务目录
|
||||
const cron_dir = 'cron_dir';
|
||||
|
||||
// 任务锁目录
|
||||
const lock_dir = 'lock_dir';
|
||||
|
||||
// 任务日志记录目录
|
||||
const log_dir = 'log_dir';
|
||||
|
||||
// 任务执行进程目录
|
||||
const pid_dir = 'pid_dir';
|
||||
|
||||
// 任务运行状态目录
|
||||
const run_dir = 'run_dir';
|
||||
|
||||
// 定时任务文件名后缀
|
||||
const cron_suffix = '.crontab';
|
||||
|
||||
// 任务锁后缀
|
||||
const lock_suffix = '.lock';
|
||||
|
||||
// 任务进程后缀
|
||||
const pid_suffix = '.pid';
|
||||
|
||||
// 管理员用户名,用户名密码都为空字符串时说明不用验证
|
||||
public static $adminName = '';
|
||||
|
||||
// 管理员密码,用户名密码都为空字符串时说明不用验证
|
||||
public static $adminPassword = '';
|
||||
|
||||
/**
|
||||
* linux系统的crontab任务永远在第1秒执行,且添加定时任务后的1分钟之内是不会执行该任务(即使语法上完全满足)
|
||||
* @var mixed
|
||||
*/
|
||||
const cron_minute = '%s %s %s %s %s';
|
||||
const cron_second = '%s %s %s %s %s %s';
|
||||
|
||||
/**
|
||||
* where可能的值
|
||||
*/
|
||||
const WHERE = [
|
||||
'day','day_n','hour','hour_n','minute','minute_n','second','second_n','week','month'
|
||||
];
|
||||
|
||||
/**
|
||||
* 构造方法
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* 进程启动时执行
|
||||
*/
|
||||
public static function onWorkerStart()
|
||||
{
|
||||
// db目录
|
||||
if(!is_dir(db_path()))
|
||||
{
|
||||
mkdir(db_path(), 0777, true);
|
||||
}
|
||||
|
||||
// 初始化目录
|
||||
$sys_dir = [self::cron_dir, self::run_dir, self::pid_dir, self::lock_dir, self::log_dir];
|
||||
array_walk($sys_dir, function ($v, $k){
|
||||
$dir = cron_path() . DIRECTORY_SEPARATOR . $v;
|
||||
!is_dir($dir) and mkdir($dir, 0777, true);
|
||||
});
|
||||
|
||||
// 初始化计划任务文件
|
||||
$cron = Conf::get(domainConfig::filename['crontab'], Constant::config_format, []);
|
||||
array_walk($cron, function ($v, $k){
|
||||
self::createHock($v);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建计划任务 钩子
|
||||
* @param array $param
|
||||
*/
|
||||
public static function createHock(array &$param)
|
||||
{
|
||||
$param['startTime'] = $param['startTime'] ?? time();
|
||||
$param['crontab'] = $param['crontab'] ?? self::parseCron($param);
|
||||
$param['command'] = self::parseCommand($param);
|
||||
//$param['command'] = $param['command'] ?? self::parseCommand($param);
|
||||
if (isset($param['switch']) && booleanParse($param['switch'])) {
|
||||
$filename = self::getFilePath($param['uuid'], self::cron_dir, self::cron_suffix);
|
||||
self::writeCronFile($filename, $param);
|
||||
} else {
|
||||
self::deleteHock($param['uuid']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除计划任务 钩子
|
||||
* @param string $uuid uuid或文件名
|
||||
* @return bool
|
||||
*/
|
||||
public static function deleteHock(string $uuid)
|
||||
{
|
||||
if (empty($uuid)) {
|
||||
return false;
|
||||
}
|
||||
$file_name = self::getFilePath($uuid, self::cron_dir, self::cron_suffix);
|
||||
clearstatcache();
|
||||
if (is_file($file_name)) {
|
||||
return @unlink($file_name);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为Linux的Crontab语法
|
||||
* @param array $param 数据
|
||||
* array(
|
||||
* 'where' => ''
|
||||
* 'weeks' => ''
|
||||
* 'day' => ''
|
||||
* 'hour' => ''
|
||||
* 'minute' => ''
|
||||
* )
|
||||
* @return string
|
||||
* 0 1 2 3 4 5
|
||||
* * * * * * *
|
||||
* - - - - - -
|
||||
* | | | | | |
|
||||
* | | | | | +----- day of week (0 - 6) (Sunday=0)
|
||||
* | | | | +----- month (1 - 12)
|
||||
* | | | +------- day of month (1 - 31)
|
||||
* | | +--------- hour (0 - 23)
|
||||
* | +----------- min (0 - 59)
|
||||
* +------------- sec (0-59)
|
||||
*/
|
||||
public static function parseCron(array $param):string
|
||||
{
|
||||
$cron = '';
|
||||
$where = isset($param['where']) ? $param['where'] : null; //条件
|
||||
$weeks = isset($param['weeks']) ? $param['weeks'] : null; //星期
|
||||
$day = isset($param['day']) ? $param['day'] : null; //天
|
||||
$hour = isset($param['hour']) ? $param['hour'] : null; //时
|
||||
$minute= isset($param['minute']) ? $param['minute'] : null; //分
|
||||
$second= isset($param['second']) ? $param['second'] : '*'; //秒
|
||||
if ($where === null || !in_array($where, self::WHERE)) {
|
||||
throw new \InvalidArgumentException('Invalid cron param where');
|
||||
}
|
||||
|
||||
//TODO:参数验证
|
||||
|
||||
switch ($where) {
|
||||
case 'day': //每天
|
||||
$cron = sprintf(self::cron_minute, $minute, $hour, '*', '*', '*');
|
||||
break;
|
||||
case 'day_n': //N天
|
||||
$cron = sprintf(self::cron_minute, $minute, $hour, '*/'.$day, '*', '*');
|
||||
break;
|
||||
case 'hour': //每小时
|
||||
$cron = sprintf(self::cron_minute, $minute, '*', '*', '*', '*');
|
||||
break;
|
||||
case 'hour_n': //N小时
|
||||
$cron = sprintf(self::cron_minute, $minute, '*/'.$hour, '*', '*', '*');
|
||||
break;
|
||||
case 'minute': //每分钟
|
||||
$cron = sprintf(self::cron_minute, '*', '*', '*', '*', '*');
|
||||
break;
|
||||
case 'minute_n': //N分钟
|
||||
$cron = sprintf(self::cron_minute, '*/'.$minute, '*', '*', '*', '*');
|
||||
break;
|
||||
case 'second': //每秒
|
||||
$cron = sprintf(self::cron_second, '*', '*', '*', '*', '*', '*');
|
||||
break;
|
||||
case 'second_n': //N秒
|
||||
$cron = sprintf(self::cron_second, '*/'.$second, '*', '*', '*', '*', '*');
|
||||
break;
|
||||
case 'week': //每周
|
||||
$cron = sprintf(self::cron_minute, $minute, $hour, '*', '*', $weeks);
|
||||
break;
|
||||
case 'month': //每月
|
||||
$cron = sprintf(self::cron_minute, $minute, $hour, '*', $day, '*');
|
||||
break;
|
||||
}
|
||||
|
||||
return $cron;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析计划任务命令
|
||||
* @param array $param
|
||||
* @return string
|
||||
*/
|
||||
public static function parseCommand(array $param):string
|
||||
{
|
||||
return Command::parse($param);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建计划任务文件
|
||||
* @param string $filename 文件的完整路径
|
||||
* @param mixed $param 数据
|
||||
* @return bool|int 结果
|
||||
*/
|
||||
public static function writeCronFile($filename, $param)
|
||||
{
|
||||
return Conf::set($filename, $param, 'json', true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文件路径
|
||||
* @param string $filename 文件名
|
||||
* @param string $dir 子目录
|
||||
* @param string $suffix 扩展名
|
||||
* @return string 文件的完整路径
|
||||
*/
|
||||
public static function getFilePath($filename = '', $dir = 'cron_dir', $suffix = '.crontab')
|
||||
{
|
||||
clearstatcache();
|
||||
$_dir = cron_path() . DIRECTORY_SEPARATOR . $dir;
|
||||
if(!is_dir($_dir))
|
||||
{
|
||||
mkdir($_dir, 0777, true);
|
||||
}
|
||||
return $_dir . DIRECTORY_SEPARATOR . $filename . $suffix;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据任务名字,拼接lock文件路径
|
||||
* @param string $filename
|
||||
* @return string
|
||||
*/
|
||||
public static function getLockFile($filename = '')
|
||||
{
|
||||
return self::getFilePath($filename, self::lock_dir, self::lock_suffix);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据任务名字,拼接pid文件路径
|
||||
* @param string $filename
|
||||
* @return string
|
||||
*/
|
||||
public static function getPidFile($filename = '')
|
||||
{
|
||||
return self::getFilePath($filename, self::pid_dir, self::pid_suffix);
|
||||
}
|
||||
|
||||
/**
|
||||
* 拼接任务log文件的完整路径
|
||||
* @param string $filename
|
||||
* @return string
|
||||
*/
|
||||
public static function getLogFile($filename = '')
|
||||
{
|
||||
return self::getFilePath($filename, self::log_dir, '.log');
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据uuid运行任务
|
||||
* @param string $uuid
|
||||
* @return bool
|
||||
*/
|
||||
public static function runCron(string $uuid = ''):bool
|
||||
{
|
||||
$cronFilename = Config::filename['crontab'];
|
||||
$cronAll = Conf::get($cronFilename, Constant::config_format, []);
|
||||
$cron = array_key_exists($uuid, $cronAll) ? $cronAll[$uuid] : [];
|
||||
if (isset($cron['switch']) && booleanParse($cron['switch'])) {
|
||||
self::execute($cron['command'], $cron['uuid']);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取计划任务的日志
|
||||
* @param string $uuid
|
||||
* @return string
|
||||
*/
|
||||
public static function readLogs(string $uuid = ''):string
|
||||
{
|
||||
$logFile = self::getLogFile($uuid);
|
||||
$log = Conf::get($logFile, 'raw', '', true);
|
||||
return $log;
|
||||
}
|
||||
|
||||
/**
|
||||
* 清空计划任务日志
|
||||
* @param string $uuid
|
||||
* @return bool
|
||||
*/
|
||||
public static function clearLogs(string $uuid = ''):bool
|
||||
{
|
||||
$logFile = self::getLogFile($uuid);
|
||||
$ret = Conf::set($logFile, date('Y-m-d H:i:s').' 清理日志'.PHP_EOL, 'raw', true);
|
||||
return is_bool($ret) ? $ret : ($ret >= 10 ? true : false);
|
||||
}
|
||||
|
||||
/**
|
||||
* 异步执行命令
|
||||
* @descr 原理为php的程序执行函数后台执行
|
||||
* @param string $cmd
|
||||
* @param string $logFile
|
||||
*/
|
||||
public static function execute($cmd = '', $logFile = '')
|
||||
{
|
||||
$logFile = self::getLogFile($logFile);
|
||||
if(DIRECTORY_SEPARATOR === '\\')
|
||||
{
|
||||
pclose(popen('start /B '.$cmd.' >> '.$logFile, 'r'));
|
||||
} else {
|
||||
pclose(popen($cmd.' >> '.$logFile.' 2>&1 &', 'r'));
|
||||
//exec($cmd.' >> '.$logFile.' 2>&1 &');
|
||||
}
|
||||
}
|
||||
}
|
97
app/domain/Reseed.php
Normal file
97
app/domain/Reseed.php
Normal file
|
@ -0,0 +1,97 @@
|
|||
<?php
|
||||
namespace app\domain;
|
||||
|
||||
use app\common\Config as Conf;
|
||||
use app\common\Constant;
|
||||
|
||||
/**
|
||||
* 辅种相关
|
||||
* Class Reseed
|
||||
* @access private 常驻内存运行,禁止执行器调用
|
||||
* @package app\domain
|
||||
*/
|
||||
class Reseed
|
||||
{
|
||||
/**
|
||||
* 根据参数,解析辅种的站点和下载器
|
||||
* @param string $uuid
|
||||
* @return array
|
||||
*/
|
||||
public static function configParser($uuid = ''):array
|
||||
{
|
||||
$rs = [
|
||||
'sites' => [],
|
||||
'clients' => [],
|
||||
];
|
||||
|
||||
$cronFilename = Config::filename['crontab'];
|
||||
$cron = Conf::get($cronFilename, Constant::config_format, []);
|
||||
$cron = array_key_exists($uuid, $cron) ? $cron[$uuid] : [];
|
||||
//检查使能
|
||||
if (isset($cron['switch']) && $cron['switch'] === 'on') {
|
||||
//IYUU密钥
|
||||
$iyuu = self::iyuuConfig();
|
||||
$rs['iyuu.cn'] = $iyuu['iyuu.cn'];
|
||||
|
||||
//默认
|
||||
$default = self::defaultConfig();
|
||||
$rs['default'] = $default;
|
||||
|
||||
//解析站点
|
||||
$sites = self::userSitesConfig();
|
||||
if (!empty($cron['sites']) && !empty($sites)) {
|
||||
$key = $cron['sites'];
|
||||
$rs['sites'] = array_filter($sites, function ($v, $k) use ($key) {
|
||||
return array_key_exists($k, $key);
|
||||
}, ARRAY_FILTER_USE_BOTH);
|
||||
}
|
||||
|
||||
//解析下载器
|
||||
$clients = self::clientsConfig();
|
||||
if (!empty($cron['clients']) && !empty($clients)) {
|
||||
$key = $cron['clients'];
|
||||
$rs['clients'] = array_filter($clients, function ($k) use ($key) {
|
||||
return array_key_exists($k, $key);
|
||||
}, ARRAY_FILTER_USE_KEY);
|
||||
}
|
||||
}
|
||||
|
||||
return $rs;
|
||||
}
|
||||
|
||||
/**
|
||||
* IYUU密钥
|
||||
* @return array
|
||||
*/
|
||||
public static function iyuuConfig():array
|
||||
{
|
||||
return Conf::get(Config::filename['iyuu'], Constant::config_format, []);
|
||||
}
|
||||
|
||||
/**
|
||||
* 默认配置
|
||||
* @return array
|
||||
*/
|
||||
public static function defaultConfig():array
|
||||
{
|
||||
return Conf::get(Config::filename['default'], Constant::config_format, []);
|
||||
}
|
||||
|
||||
/**
|
||||
* 客户端
|
||||
* @return array
|
||||
*/
|
||||
public static function clientsConfig():array
|
||||
{
|
||||
return Conf::get(Config::filename['clients'], Constant::config_format, []);
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户拥有的站点
|
||||
* @return array
|
||||
*/
|
||||
public static function userSitesConfig():array
|
||||
{
|
||||
return Conf::get(Config::filename['user_sites'], Constant::config_format, []);
|
||||
}
|
||||
}
|
96
app/domain/Users.php
Normal file
96
app/domain/Users.php
Normal file
|
@ -0,0 +1,96 @@
|
|||
<?php
|
||||
namespace app\domain;
|
||||
|
||||
use support\Request;
|
||||
use app\common\components\Curl;
|
||||
use app\common\Constant;
|
||||
use app\common\Config;
|
||||
|
||||
/**
|
||||
* 用户逻辑操作类 [无状态静态类]
|
||||
* @access private 常驻内存运行,禁止执行器调用
|
||||
*/
|
||||
class Users
|
||||
{
|
||||
/**
|
||||
* 检查用户Session是否已登录
|
||||
* @param Request $request
|
||||
* @return bool
|
||||
*/
|
||||
public static function isLogin(Request $request):bool
|
||||
{
|
||||
$session = $request->session();
|
||||
$has = $session->has('token');
|
||||
return $has ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查token及绑定状态
|
||||
* @param string $token
|
||||
* @param Request $request
|
||||
* @return array
|
||||
*/
|
||||
public static function checkToken(string $token, Request $request):array
|
||||
{
|
||||
$login = false;
|
||||
$curl = Curl::one();
|
||||
$api_url = Constant::API_BASE;
|
||||
$api_action = Constant::API['sites'];
|
||||
$url = sprintf('%s%s?sign=%s&version=%s', $api_url, $api_action, $token, IYUU_VERSION());
|
||||
$res = $curl->get($url);
|
||||
$rs = json_decode($res->response, true);
|
||||
if ($rs['ret'] === 200 && isset($rs['data']['sites']) && is_array($rs['data']['sites'])) {
|
||||
$sites = array_column($rs['data']['sites'], null, 'site');
|
||||
Config::set('sites', $sites, Constant::config_format);
|
||||
Config::set('iyuu', ['iyuu.cn' => $token], Constant::config_format);
|
||||
$login = true;
|
||||
} else {
|
||||
if (($rs['ret'] === 403) && isset($rs['data']['recommend']) && is_array($rs['data']['recommend'])) {
|
||||
//用户未绑定合作站点
|
||||
$recommend = $rs['data']['recommend'];
|
||||
Config::set('recommend', $recommend, Constant::config_format);
|
||||
Config::set('iyuu', ['iyuu.cn' => $token], Constant::config_format);
|
||||
//$login = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ($login) {
|
||||
// 验证通过,写入Session
|
||||
$session = $request->session();
|
||||
$session->set(Constant::Session_Token_Key, $token);
|
||||
}
|
||||
return $rs;
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户绑定
|
||||
* @descr 接口地址 https://api.iyuu.cn/index.php?s=App.User.Login
|
||||
* 接口文档 https://api.iyuu.cn/docs.php?service=App.User.Login&detail=1&type=fold
|
||||
* @param string $token
|
||||
* @param Request $request
|
||||
* @return array
|
||||
*/
|
||||
public static function bindToken(string $token, Request $request):array
|
||||
{
|
||||
$curl = Curl::one();
|
||||
$url = Constant::API_BASE . Constant::API['login'];
|
||||
$data = [
|
||||
'token' => $token,
|
||||
'id' => $request->post('id') + 0,
|
||||
'passkey'=> sha1($request->post('passkey')), // 避免泄露用户passkey秘钥
|
||||
'site' => $request->post('site'),
|
||||
];
|
||||
$res = $curl->get($url, $data);
|
||||
$rs = json_decode($res->response, true);
|
||||
if (isset($rs['ret']) && ($rs['ret'] === 200) && isset($rs['data']['success']) && $rs['data']['success']) {
|
||||
//绑定成功
|
||||
return self::checkToken($token, $request);
|
||||
} else {
|
||||
//绑定失败
|
||||
$msg = !empty($rs['msg']) ? $rs['msg'] : '远端服务器无响应,请稍后重试!';
|
||||
$msg = !empty($rs['data']['errmsg']) ? $rs['data']['errmsg'] : $msg;
|
||||
$rs['msg'] = $msg;
|
||||
return $rs;
|
||||
}
|
||||
}
|
||||
}
|
70
app/functions.php
Normal file
70
app/functions.php
Normal file
|
@ -0,0 +1,70 @@
|
|||
<?php
|
||||
/**
|
||||
* 返回IYUU当前版本号
|
||||
*/
|
||||
function IYUU_VERSION():string
|
||||
{
|
||||
return '2.0.0';
|
||||
}
|
||||
|
||||
/**
|
||||
* 微信推送 爱语飞飞
|
||||
* @param string $text
|
||||
* @param string $desp
|
||||
* @return false|string
|
||||
*/
|
||||
function ff($text = '', $desp = '')
|
||||
{
|
||||
$token = env('IYUU', '');
|
||||
$desp = ($desp=='')?date("Y-m-d H:i:s") :$desp;
|
||||
$postdata = http_build_query(array(
|
||||
'text' => $text,
|
||||
'desp' => $desp
|
||||
));
|
||||
$opts = array('http' => array(
|
||||
'method' => 'POST',
|
||||
'header' => 'Content-type: application/x-www-form-urlencoded',
|
||||
'content' => $postdata
|
||||
));
|
||||
$context = stream_context_create($opts);
|
||||
$result = file_get_contents('http://iyuu.cn/'.$token.'.send', false, $context);
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取全局唯一的UUID
|
||||
* @param int $pid
|
||||
* @return string
|
||||
*/
|
||||
function getUUID(int $pid = 0):string
|
||||
{
|
||||
if (function_exists('posix_getpid')) {
|
||||
$pid = posix_getpid();
|
||||
}
|
||||
return sprintf('pid%d_%d_%s', $pid, mt_rand(1, 9999), uniqid());
|
||||
}
|
||||
|
||||
/**
|
||||
* 粗略验证字符串是否为IYUU的token
|
||||
* @param string $token
|
||||
* @return bool
|
||||
*/
|
||||
function check_token($token = ''):bool
|
||||
{
|
||||
return (strlen($token) < 60) && (strpos($token, 'IYUU') === 0) && (strpos($token, 'T') < 15);
|
||||
}
|
||||
|
||||
/**
|
||||
* 异步执行命令
|
||||
* @descr 原理为php的程序执行函数后台执行
|
||||
* @param string $cmd
|
||||
*/
|
||||
function run_exec($cmd = '')
|
||||
{
|
||||
if(DIRECTORY_SEPARATOR === '\\')
|
||||
{
|
||||
pclose(popen('start /B '.$cmd, 'r'));
|
||||
} else {
|
||||
pclose(popen($cmd, 'r'));
|
||||
}
|
||||
}
|
28
app/model/Test.php
Normal file
28
app/model/Test.php
Normal file
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
namespace app\model;
|
||||
|
||||
use support\Model;
|
||||
|
||||
class Test extends Model
|
||||
{
|
||||
/**
|
||||
* The table associated with the model.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $table = 'test';
|
||||
|
||||
/**
|
||||
* The primary key associated with the table.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $primaryKey = 'id';
|
||||
|
||||
/**
|
||||
* Indicates if the model should be timestamped.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $timestamps = false;
|
||||
}
|
1
app/plugins/.gitignore
vendored
Normal file
1
app/plugins/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
!.gitignore
|
14
app/view/index/view.html
Normal file
14
app/view/index/view.html
Normal file
|
@ -0,0 +1,14 @@
|
|||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="shortcut icon" href="/favicon.ico" />
|
||||
<title>webman</title>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
hello <?=htmlspecialchars($name)?>
|
||||
</body>
|
||||
</html>
|
1
bin/.gitignore
vendored
Normal file
1
bin/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
!.gitignore
|
10
bin/iyuu.php
Normal file
10
bin/iyuu.php
Normal file
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
require_once dirname(__DIR__) . '/init.php';
|
||||
require_once ROOT_PATH . '/src/helper.php';
|
||||
echo microtime(true).' 当前脚本路径:'.__FILE__.PHP_EOL;
|
||||
use IYUU\Reseed\AutoReseed;
|
||||
use Workerman\Autoloader;
|
||||
|
||||
Autoloader::setRootPath(ROOT_PATH);
|
||||
AutoReseed::init();
|
||||
AutoReseed::call();
|
58
composer.json
Normal file
58
composer.json
Normal file
|
@ -0,0 +1,58 @@
|
|||
{
|
||||
"name": "workerman/webman",
|
||||
"type": "library",
|
||||
"keywords": [
|
||||
"high performance",
|
||||
"http service"
|
||||
],
|
||||
"homepage": "http://www.workerman.net",
|
||||
"license": "MIT",
|
||||
"description": "High performance HTTP Service Framework.",
|
||||
"authors": [
|
||||
{
|
||||
"name": "walkor",
|
||||
"email": "walkor@workerman.net",
|
||||
"homepage": "http://www.workerman.net",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"support": {
|
||||
"email": "walkor@workerman.net",
|
||||
"issues": "https://github.com/walkor/webman/issues",
|
||||
"forum": "http://wenda.workerman.net/",
|
||||
"wiki": "http://workerman.net/doc/webman",
|
||||
"source": "https://github.com/walkor/webman"
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.2",
|
||||
"workerman/webman-framework": "^1.0",
|
||||
"monolog/monolog": "^2.0",
|
||||
"vlucas/phpdotenv": "5.1.0",
|
||||
"rhilip/bencode": "^1.1",
|
||||
"workerman/crontab": "^1.0",
|
||||
"curl/curl": "^2.3",
|
||||
"ext-posix": "*",
|
||||
"ext-pcntl": "*",
|
||||
"ext-json": "*",
|
||||
"ext-mbstring": "*",
|
||||
"ext-curl": "*",
|
||||
"symfony/process": "^5.2",
|
||||
"ledccn/bittorrentclient": "dev-master"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-event": "For better performance. "
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"IYUU\\": "src/"
|
||||
},
|
||||
"files": [
|
||||
"./support/helpers.php"
|
||||
]
|
||||
},
|
||||
"scripts": {
|
||||
"post-autoload-dump": [
|
||||
"@php -r \"file_exists('.env') || copy('.env.example', '.env');\""
|
||||
]
|
||||
}
|
||||
}
|
18
config/app.php
Normal file
18
config/app.php
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is part of webman.
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the MIT-LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @author walkor<walkor@workerman.net>
|
||||
* @copyright walkor<walkor@workerman.net>
|
||||
* @link http://www.workerman.net/
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
return [
|
||||
'debug' => env('APP_DEBUG', false),
|
||||
'default_timezone' => 'Asia/Shanghai',
|
||||
];
|
19
config/autoload.php
Normal file
19
config/autoload.php
Normal file
|
@ -0,0 +1,19 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is part of webman.
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the MIT-LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @author walkor<walkor@workerman.net>
|
||||
* @copyright walkor<walkor@workerman.net>
|
||||
* @link http://www.workerman.net/
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
return [
|
||||
'files' => [
|
||||
base_path() . '/app/functions.php'
|
||||
]
|
||||
];
|
22
config/bootstrap.php
Normal file
22
config/bootstrap.php
Normal file
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is part of webman.
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the MIT-LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @author walkor<walkor@workerman.net>
|
||||
* @copyright walkor<walkor@workerman.net>
|
||||
* @link http://www.workerman.net/
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
return [
|
||||
support\bootstrap\Container::class,
|
||||
support\bootstrap\Session::class,
|
||||
//support\bootstrap\db\Laravel::class,
|
||||
//support\bootstrap\Redis::class,
|
||||
support\bootstrap\Log::class,
|
||||
support\bootstrap\Translation::class,
|
||||
];
|
26
config/container.php
Normal file
26
config/container.php
Normal file
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is part of webman.
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the MIT-LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @author walkor<walkor@workerman.net>
|
||||
* @copyright walkor<walkor@workerman.net>
|
||||
* @link http://www.workerman.net/
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
|
||||
// 如果你需要自动依赖注入(包括注解注入)。
|
||||
// 请先运行 composer require php-di/php-di && composer require doctrine/annotations
|
||||
// 并将下面的代码注释解除,并注释掉最后一行 return new Webman\Container;
|
||||
/*$builder = new \DI\ContainerBuilder();
|
||||
$builder->addDefinitions(config('dependence', []));
|
||||
$builder->useAutowiring(true);
|
||||
$builder->useAnnotations(true);
|
||||
return $builder->build();*/
|
||||
|
||||
|
||||
return new Webman\Container;
|
66
config/database.php
Normal file
66
config/database.php
Normal file
|
@ -0,0 +1,66 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is part of webman.
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the MIT-LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @author walkor<walkor@workerman.net>
|
||||
* @copyright walkor<walkor@workerman.net>
|
||||
* @link http://www.workerman.net/
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
return [
|
||||
|
||||
'default' => 'mysql',
|
||||
|
||||
'connections' => [
|
||||
|
||||
'mysql' => [
|
||||
'driver' => 'mysql',
|
||||
'host' => env('DB_HOST', '127.0.0.1'),
|
||||
'port' => env('DB_PORT', '3306'),
|
||||
'database' => env('DB_DATABASE', 'forge'),
|
||||
'username' => env('DB_USERNAME', 'forge'),
|
||||
'password' => env('DB_PASSWORD', ''),
|
||||
'unix_socket' => env('DB_SOCKET', ''),
|
||||
'charset' => 'utf8',
|
||||
'collation' => 'utf8_unicode_ci',
|
||||
'prefix' => '',
|
||||
'strict' => true,
|
||||
'engine' => null,
|
||||
],
|
||||
|
||||
'sqlite' => [
|
||||
'driver' => 'sqlite',
|
||||
'database' => env('DB_DATABASE', ''),
|
||||
'prefix' => '',
|
||||
],
|
||||
|
||||
'pgsql' => [
|
||||
'driver' => 'pgsql',
|
||||
'host' => env('DB_HOST', '127.0.0.1'),
|
||||
'port' => env('DB_PORT', '5432'),
|
||||
'database' => env('DB_DATABASE', 'forge'),
|
||||
'username' => env('DB_USERNAME', 'forge'),
|
||||
'password' => env('DB_PASSWORD', ''),
|
||||
'charset' => 'utf8',
|
||||
'prefix' => '',
|
||||
'schema' => 'public',
|
||||
'sslmode' => 'prefer',
|
||||
],
|
||||
|
||||
'sqlsrv' => [
|
||||
'driver' => 'sqlsrv',
|
||||
'host' => env('DB_HOST', 'localhost'),
|
||||
'port' => env('DB_PORT', '1433'),
|
||||
'database' => env('DB_DATABASE', 'forge'),
|
||||
'username' => env('DB_USERNAME', 'forge'),
|
||||
'password' => env('DB_PASSWORD', ''),
|
||||
'charset' => 'utf8',
|
||||
'prefix' => '',
|
||||
],
|
||||
],
|
||||
];
|
17
config/dependence.php
Normal file
17
config/dependence.php
Normal file
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is part of webman.
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the MIT-LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @author walkor<walkor@workerman.net>
|
||||
* @copyright walkor<walkor@workerman.net>
|
||||
* @link http://www.workerman.net/
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
return [
|
||||
|
||||
];
|
17
config/exception.php
Normal file
17
config/exception.php
Normal file
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is part of webman.
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the MIT-LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @author walkor<walkor@workerman.net>
|
||||
* @copyright walkor<walkor@workerman.net>
|
||||
* @link http://www.workerman.net/
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
return [
|
||||
'' => app\common\exception\Handler::class,
|
||||
];
|
31
config/log.php
Normal file
31
config/log.php
Normal file
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is part of webman.
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the MIT-LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @author walkor<walkor@workerman.net>
|
||||
* @copyright walkor<walkor@workerman.net>
|
||||
* @link http://www.workerman.net/
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
return [
|
||||
'default' => [
|
||||
'handlers' => [
|
||||
[
|
||||
'class' => Monolog\Handler\RotatingFileHandler::class,
|
||||
'constructor' => [
|
||||
runtime_path() . '/logs/webman.log',
|
||||
Monolog\Logger::DEBUG,
|
||||
],
|
||||
'formatter' => [
|
||||
'class' => Monolog\Formatter\LineFormatter::class,
|
||||
'constructor' => [ null, 'Y-m-d H:i:s', true],
|
||||
],
|
||||
]
|
||||
],
|
||||
],
|
||||
];
|
21
config/middleware.php
Normal file
21
config/middleware.php
Normal file
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is part of webman.
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the MIT-LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @author walkor<walkor@workerman.net>
|
||||
* @copyright walkor<walkor@workerman.net>
|
||||
* @link http://www.workerman.net/
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
return [
|
||||
'' => [
|
||||
//support\middleware\AuthCheckTest::class,
|
||||
//support\middleware\AccessControlTest::class,
|
||||
app\common\middleware\AuthCheck::class,
|
||||
]
|
||||
];
|
49
config/process.php
Normal file
49
config/process.php
Normal file
|
@ -0,0 +1,49 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is part of webman.
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the MIT-LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @author walkor<walkor@workerman.net>
|
||||
* @copyright walkor<walkor@workerman.net>
|
||||
* @link http://www.workerman.net/
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
use support\view\Raw;
|
||||
use support\view\Twig;
|
||||
use support\view\Blade;
|
||||
use support\view\ThinkPHP;
|
||||
|
||||
return [
|
||||
// 文件更新检测
|
||||
'IYUUFileMonitor' => [
|
||||
'handler' => process\FileMonitor::class,
|
||||
'reloadable' => false,
|
||||
'constructor' => [
|
||||
// 监控这些目录
|
||||
'monitor_dir' => [
|
||||
app_path(),
|
||||
config_path(),
|
||||
base_path() . '/process',
|
||||
base_path() . '/support',
|
||||
base_path() . '/resource'
|
||||
],
|
||||
// 监控这些后缀的文件
|
||||
'monitor_extenstions' => [
|
||||
'php', 'html', 'htm'
|
||||
]
|
||||
]
|
||||
],
|
||||
// 其它进程
|
||||
/*'websocket' => [
|
||||
'handler' => process\Websocket::class,
|
||||
'listen' => 'websocket://0.0.0.0:8888',
|
||||
'count' => 1,
|
||||
],*/
|
||||
'IYUUTask' => [
|
||||
'handler' => process\Task::class
|
||||
],
|
||||
];
|
22
config/redis.php
Normal file
22
config/redis.php
Normal file
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is part of webman.
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the MIT-LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @author walkor<walkor@workerman.net>
|
||||
* @copyright walkor<walkor@workerman.net>
|
||||
* @link http://www.workerman.net/
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
return [
|
||||
'default' => [
|
||||
'host' => env('REDIS_HOST', '127.0.0.1'),
|
||||
'password' => env('REDIS_PASSWORD', null),
|
||||
'port' => env('REDIS_PORT', 6379),
|
||||
'database' => env('REDIS_DB', 0),
|
||||
],
|
||||
];
|
22
config/route.php
Normal file
22
config/route.php
Normal file
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is part of webman.
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the MIT-LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @author walkor<walkor@workerman.net>
|
||||
* @copyright walkor<walkor@workerman.net>
|
||||
* @link http://www.workerman.net/
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
use Webman\Route;
|
||||
|
||||
|
||||
Route::any('/test', function ($request) {
|
||||
return response('test');
|
||||
});
|
||||
|
||||
Route::any('/route-test', 'app\controller\Index@index');
|
15
config/server.php
Normal file
15
config/server.php
Normal file
|
@ -0,0 +1,15 @@
|
|||
<?php
|
||||
return [
|
||||
'listen' => 'http://0.0.0.0:8787',
|
||||
'transport' => 'tcp',
|
||||
'context' => [],
|
||||
'name' => 'IYUUAutoReseed',
|
||||
'count' => env('SERVER_PROCESS_COUNT', 1),
|
||||
'user' => env('SERVER_PROCESS_USER', ''),
|
||||
'group' => env('SERVER_PROCESS_GROUP', ''),
|
||||
'pid_file' => runtime_path() . '/webman.pid',
|
||||
'log_file' => runtime_path() . '/workerman.log',
|
||||
'max_request' => 1000,
|
||||
'stdout_file' => runtime_path() . '/logs/stdout.log',
|
||||
'max_package_size' => 10*1024*1024
|
||||
];
|
42
config/session.php
Normal file
42
config/session.php
Normal file
|
@ -0,0 +1,42 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is part of webman.
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the MIT-LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @author walkor<walkor@workerman.net>
|
||||
* @copyright walkor<walkor@workerman.net>
|
||||
* @link http://www.workerman.net/
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
return [
|
||||
|
||||
'type' => 'file', // or redis or redis_cluster
|
||||
|
||||
'handler' => Webman\FileSessionHandler::class,
|
||||
|
||||
'config' => [
|
||||
'file' => [
|
||||
'save_path' => runtime_path() . '/sessions',
|
||||
],
|
||||
'redis' => [
|
||||
'host' => '127.0.0.1',
|
||||
'port' => 6379,
|
||||
'auth' => '',
|
||||
'timeout' => 2,
|
||||
'database' => '',
|
||||
'prefix' => 'redis_session_',
|
||||
],
|
||||
'redis_cluster' => [
|
||||
'host' => ['127.0.0.1:7000', '127.0.0.1:7001', '127.0.0.1:7001'],
|
||||
'timeout' => 2,
|
||||
'auth' => '',
|
||||
'prefix' => 'redis_session_',
|
||||
]
|
||||
],
|
||||
|
||||
'session_name' => 'PHPSID',
|
||||
];
|
23
config/static.php
Normal file
23
config/static.php
Normal file
|
@ -0,0 +1,23 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is part of webman.
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the MIT-LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @author walkor<walkor@workerman.net>
|
||||
* @copyright walkor<walkor@workerman.net>
|
||||
* @link http://www.workerman.net/
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
/**
|
||||
* 静态文件设置
|
||||
*/
|
||||
return [
|
||||
'enable' => true, // 是否支持静态文件
|
||||
'middleware' => [ // 静态文件中间件
|
||||
support\middleware\StaticFile::class,
|
||||
],
|
||||
];
|
25
config/translation.php
Normal file
25
config/translation.php
Normal file
|
@ -0,0 +1,25 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is part of webman.
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the MIT-LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @author walkor<walkor@workerman.net>
|
||||
* @copyright walkor<walkor@workerman.net>
|
||||
* @link http://www.workerman.net/
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
/**
|
||||
* 多语言配置
|
||||
*/
|
||||
return [
|
||||
// 默认语言
|
||||
'locale' => 'zh_CN',
|
||||
// 回退语言
|
||||
'fallback_locale' => ['zh_CN', 'en'],
|
||||
// 语言文件存放的文件夹
|
||||
'path' => base_path() . '/resource/translations',
|
||||
];
|
22
config/view.php
Normal file
22
config/view.php
Normal file
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is part of webman.
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the MIT-LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @author walkor<walkor@workerman.net>
|
||||
* @copyright walkor<walkor@workerman.net>
|
||||
* @link http://www.workerman.net/
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
use support\view\Raw;
|
||||
use support\view\Twig;
|
||||
use support\view\Blade;
|
||||
use support\view\ThinkPHP;
|
||||
|
||||
return [
|
||||
'handler' => Raw::class
|
||||
];
|
123
docker/AMD64/Dockerfile
Normal file
123
docker/AMD64/Dockerfile
Normal file
|
@ -0,0 +1,123 @@
|
|||
FROM alpine:latest
|
||||
#FROM alpine:3.12
|
||||
#FROM alpine:3.8
|
||||
#FROM swoft/alphp:base
|
||||
#FROM swoft/alphp:cli
|
||||
|
||||
LABEL maintainer="david <367013672@qq.com>" version="1.0"
|
||||
|
||||
##
|
||||
# ---------- env settings ----------
|
||||
##
|
||||
|
||||
# --build-arg timezone=Asia/Shanghai
|
||||
ARG timezone
|
||||
# prod pre test dev
|
||||
ARG app_env=prod
|
||||
# default use www-data user
|
||||
# ARG add_user=www-data
|
||||
|
||||
ENV APP_ENV=${app_env:-"prod"} \
|
||||
TIMEZONE=${timezone:-"Asia/Shanghai"} \
|
||||
cron="3 */10 * * *"
|
||||
|
||||
##
|
||||
# ---------- building ----------
|
||||
##
|
||||
|
||||
RUN set -ex \
|
||||
# change apk source repo
|
||||
#&& sed -i 's/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/' /etc/apk/repositories \
|
||||
&& apk update \
|
||||
&& apk add --no-cache \
|
||||
# Install base packages ('ca-certificates' will install 'nghttp2-libs')
|
||||
ca-certificates \
|
||||
curl \
|
||||
tar \
|
||||
# xz \
|
||||
libressl \
|
||||
# openssh \
|
||||
openssl \
|
||||
wget \
|
||||
zip \
|
||||
unzip \
|
||||
git \
|
||||
tzdata \
|
||||
pcre \
|
||||
# install php7 and some extensions
|
||||
php7 \
|
||||
# php7-common \
|
||||
# php7-bcmath \
|
||||
php7-curl \
|
||||
# php7-ctype \
|
||||
php7-dom \
|
||||
# php7-fileinfo \
|
||||
# php7-gettext \
|
||||
# php7-gd \
|
||||
# php7-iconv \
|
||||
# php7-imagick \
|
||||
php7-json \
|
||||
php7-mbstring \
|
||||
#php7-mongodb \
|
||||
# php7-mysqlnd \
|
||||
php7-openssl \
|
||||
php7-opcache \
|
||||
php7-pdo \
|
||||
# php7-pdo_mysql \
|
||||
php7-pdo_sqlite \
|
||||
php7-phar \
|
||||
php7-pcntl \
|
||||
php7-posix \
|
||||
# php7-redis \
|
||||
php7-simplexml \
|
||||
php7-sockets \
|
||||
# php7-sodium \
|
||||
php7-session \
|
||||
# php7-sysvshm \
|
||||
# php7-sysvmsg \
|
||||
# php7-sysvsem \
|
||||
# php7-tokenizer \
|
||||
php7-zip \
|
||||
php7-zlib \
|
||||
php7-xml \
|
||||
&& git clone https://github.com/ledccn/IYUUPlus.git /IYUU \
|
||||
&& cd /IYUU && php -r "file_exists('.env') || copy('.env.example', '.env');" \
|
||||
&& apk del --purge *-dev \
|
||||
# install latest composer
|
||||
&& wget https://getcomposer.org/composer.phar \
|
||||
&& mv composer.phar /usr/local/bin/composer \
|
||||
# make it executable
|
||||
&& chmod +x /usr/local/bin/composer \
|
||||
# ---------- some config,clear work ----------
|
||||
&& cd /etc/php7 \
|
||||
# - config PHP
|
||||
&& { \
|
||||
echo "upload_max_filesize=100M"; \
|
||||
echo "post_max_size=108M"; \
|
||||
echo "memory_limit=1024M"; \
|
||||
echo "date.timezone=${TIMEZONE}"; \
|
||||
} | tee conf.d/99-overrides.ini \
|
||||
# - config timezone
|
||||
&& ln -sf /usr/share/zoneinfo/${TIMEZONE} /etc/localtime \
|
||||
&& echo "${TIMEZONE}" > /etc/timezone \
|
||||
&& crontab -l > /tmp/crontab.bak \
|
||||
&& echo "$cron cd /IYUU && git fetch --all && git reset --hard origin/master" >> /tmp/crontab.bak \
|
||||
&& echo '10 */12 * * * /usr/bin/php /IYUU/start.php restart -d' >> /tmp/crontab.bak \
|
||||
&& crontab /tmp/crontab.bak \
|
||||
# ---------- some config work ----------
|
||||
# - ensure 'www-data' user exists(82 is the standard uid/gid for "www-data" in Alpine)
|
||||
# && addgroup -g 82 -S ${add_user} \
|
||||
# && adduser -u 82 -D -S -G ${add_user} ${add_user} \
|
||||
# # - create user dir
|
||||
# && mkdir -p /data \
|
||||
# && chown -R ${add_user}:${add_user} /data \
|
||||
&& rm -rf /var/cache/apk/* /tmp/* /usr/share/man /usr/share/php7 \
|
||||
&& cp /IYUU/docker/entrypoint.sh /entrypoint.sh \
|
||||
&& chmod +x /entrypoint.sh \
|
||||
&& echo -e "\033[42;37m Build Completed :).\033[0m\n"
|
||||
|
||||
EXPOSE 8787
|
||||
VOLUME ["/IYUU/db", "/IYUU"]
|
||||
WORKDIR /IYUU
|
||||
ENTRYPOINT ["/entrypoint.sh"]
|
||||
# CMD /run.sh
|
4
docker/AMD64/build.sh
Normal file
4
docker/AMD64/build.sh
Normal file
|
@ -0,0 +1,4 @@
|
|||
#!/bin/sh
|
||||
docker build -f Dockerfile -t iyuuplus:latest .
|
||||
docker run -it -v /root/plus:/IYUU/db -p 8787:8787 --network bridge --name IYUUPlus --restart always -d iyuuplus:latest
|
||||
docker exec -it IYUUPlus sh
|
121
docker/Arm64v8/Dockerfile
Normal file
121
docker/Arm64v8/Dockerfile
Normal file
|
@ -0,0 +1,121 @@
|
|||
# FROM arm64v8/alpine
|
||||
# FROM arm64v8/alpine:latest
|
||||
FROM arm64v8/alpine:3.12
|
||||
|
||||
LABEL maintainer="david <367013672@qq.com>" version="1.0"
|
||||
|
||||
##
|
||||
# ---------- env settings ----------
|
||||
##
|
||||
|
||||
# --build-arg timezone=Asia/Shanghai
|
||||
ARG timezone
|
||||
# prod pre test dev
|
||||
ARG app_env=prod
|
||||
# default use www-data user
|
||||
# ARG add_user=www-data
|
||||
|
||||
ENV APP_ENV=${app_env:-"prod"} \
|
||||
TIMEZONE=${timezone:-"Asia/Shanghai"} \
|
||||
cron="3 */10 * * *"
|
||||
|
||||
##
|
||||
# ---------- building ----------
|
||||
##
|
||||
|
||||
RUN set -ex \
|
||||
# change apk source repo
|
||||
#&& sed -i 's/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/' /etc/apk/repositories \
|
||||
&& apk update \
|
||||
&& apk add --no-cache \
|
||||
# Install base packages ('ca-certificates' will install 'nghttp2-libs')
|
||||
ca-certificates \
|
||||
curl \
|
||||
tar \
|
||||
# xz \
|
||||
libressl \
|
||||
# openssh \
|
||||
openssl \
|
||||
wget \
|
||||
zip \
|
||||
unzip \
|
||||
git \
|
||||
tzdata \
|
||||
pcre \
|
||||
# install php7 and some extensions
|
||||
php7 \
|
||||
# php7-common \
|
||||
# php7-bcmath \
|
||||
php7-curl \
|
||||
# php7-ctype \
|
||||
php7-dom \
|
||||
# php7-fileinfo \
|
||||
# php7-gettext \
|
||||
# php7-gd \
|
||||
# php7-iconv \
|
||||
# php7-imagick \
|
||||
php7-json \
|
||||
php7-mbstring \
|
||||
#php7-mongodb \
|
||||
# php7-mysqlnd \
|
||||
php7-openssl \
|
||||
php7-opcache \
|
||||
php7-pdo \
|
||||
# php7-pdo_mysql \
|
||||
php7-pdo_sqlite \
|
||||
php7-phar \
|
||||
php7-pcntl \
|
||||
php7-posix \
|
||||
# php7-redis \
|
||||
php7-simplexml \
|
||||
php7-sockets \
|
||||
# php7-sodium \
|
||||
php7-session \
|
||||
# php7-sysvshm \
|
||||
# php7-sysvmsg \
|
||||
# php7-sysvsem \
|
||||
# php7-tokenizer \
|
||||
php7-zip \
|
||||
php7-zlib \
|
||||
php7-xml \
|
||||
&& git clone https://github.com/ledccn/IYUUPlus.git /IYUU \
|
||||
&& cd /IYUU && php -r "file_exists('.env') || copy('.env.example', '.env');" \
|
||||
&& apk del --purge *-dev \
|
||||
# install latest composer
|
||||
&& wget https://getcomposer.org/composer.phar \
|
||||
&& mv composer.phar /usr/local/bin/composer \
|
||||
# make it executable
|
||||
&& chmod +x /usr/local/bin/composer \
|
||||
# ---------- some config,clear work ----------
|
||||
&& cd /etc/php7 \
|
||||
# - config PHP
|
||||
&& { \
|
||||
echo "upload_max_filesize=100M"; \
|
||||
echo "post_max_size=108M"; \
|
||||
echo "memory_limit=1024M"; \
|
||||
echo "date.timezone=${TIMEZONE}"; \
|
||||
} | tee conf.d/99-overrides.ini \
|
||||
# - config timezone
|
||||
&& ln -sf /usr/share/zoneinfo/${TIMEZONE} /etc/localtime \
|
||||
&& echo "${TIMEZONE}" > /etc/timezone \
|
||||
&& crontab -l > /tmp/crontab.bak \
|
||||
&& echo "$cron cd /IYUU && git fetch --all && git reset --hard origin/master" >> /tmp/crontab.bak \
|
||||
&& echo '10 */12 * * * /usr/bin/php /IYUU/start.php restart -d' >> /tmp/crontab.bak \
|
||||
&& crontab /tmp/crontab.bak \
|
||||
# ---------- some config work ----------
|
||||
# - ensure 'www-data' user exists(82 is the standard uid/gid for "www-data" in Alpine)
|
||||
# && addgroup -g 82 -S ${add_user} \
|
||||
# && adduser -u 82 -D -S -G ${add_user} ${add_user} \
|
||||
# # - create user dir
|
||||
# && mkdir -p /data \
|
||||
# && chown -R ${add_user}:${add_user} /data \
|
||||
&& rm -rf /var/cache/apk/* /tmp/* /usr/share/man /usr/share/php7 \
|
||||
&& cp /IYUU/docker/entrypoint.sh /entrypoint.sh \
|
||||
&& chmod +x /entrypoint.sh \
|
||||
&& echo -e "\033[42;37m Build Completed :).\033[0m\n"
|
||||
|
||||
EXPOSE 8787
|
||||
VOLUME ["/IYUU/db", "/IYUU"]
|
||||
WORKDIR /IYUU
|
||||
ENTRYPOINT ["/entrypoint.sh"]
|
||||
# CMD /run.sh
|
4
docker/Arm64v8/build.n1.sh
Normal file
4
docker/Arm64v8/build.n1.sh
Normal file
|
@ -0,0 +1,4 @@
|
|||
#!/bin/sh
|
||||
docker build -t iyuuplus:arm64v8 .
|
||||
docker run -it -v /root/plus:/IYUU/db -v /var/lib/transmission/torrents:/torrents -v /var/lib/qbittorrent/.local/share/data/qBittorrent/BT_backup:/BT_backup -p 8787:8787 --network bridge --name IYUUPlus --restart always -d iyuuplus:arm64v8
|
||||
docker exec -it IYUUPlus sh
|
5
docker/Arm64v8/build.sh
Normal file
5
docker/Arm64v8/build.sh
Normal file
|
@ -0,0 +1,5 @@
|
|||
#!/bin/sh
|
||||
#ARM平台通用脚本
|
||||
docker build -f Dockerfile -t iyuuplus:arm64v8 .
|
||||
docker run -it -v /root/plus:/IYUU/db -p 8787:8787 --network bridge --name IYUUPlus --restart always -d iyuuplus:arm64v8
|
||||
docker exec -it IYUUPlus sh
|
2
docker/Arm64v8/push.sh
Normal file
2
docker/Arm64v8/push.sh
Normal file
|
@ -0,0 +1,2 @@
|
|||
docker image tag iyuuplus:arm64v8 iyuucn/iyuuplus:arm64v8
|
||||
docker image push iyuucn/iyuuplus:arm64v8
|
137
docker/Readme.md
Normal file
137
docker/Readme.md
Normal file
|
@ -0,0 +1,137 @@
|
|||
# 使用方法:
|
||||
### 1.拉取镜像、创建容器,运行
|
||||
|
||||
#### ARM平台通用方法
|
||||
|
||||
```
|
||||
docker run -d \
|
||||
--name IYUUAutoReseed \
|
||||
-e cron='0 9 * * 0' \
|
||||
-v /root/config.php:/config.php \
|
||||
--restart=always \
|
||||
iyuucn/iyuuautoreseed:arm64v8
|
||||
```
|
||||
#### 小钢炮方法:
|
||||
|
||||
```
|
||||
docker run -d \
|
||||
--name IYUUAutoReseed \
|
||||
-e cron='0 8 * * 0' \
|
||||
-v /root/config.php:/config.php \
|
||||
-v /var/lib/transmission/torrents:/torrents \
|
||||
-v /var/lib/qbittorrent/.local/share/data/qBittorrent/BT_backup:/BT_backup \
|
||||
--restart always \
|
||||
iyuucn/iyuuautoreseed:arm64v8
|
||||
```
|
||||
|
||||
#### AMD64平台(MAC OS、台式、服务器、NAS等)
|
||||
|
||||
```
|
||||
docker run -d \
|
||||
--name IYUUAutoReseed \
|
||||
-e cron='0 9 * * 0' \
|
||||
-v /root/config.php:/config.php \
|
||||
--restart=always \
|
||||
iyuucn/iyuuautoreseed:latest
|
||||
```
|
||||
|
||||
|
||||
**命令解释**
|
||||
|
||||
| 参数 | 解释 |
|
||||
| ----------- | ------------------------------------------------------------ |
|
||||
| `--name` | 容器名字 |
|
||||
| `-e` | 环境变量,定时任务执行时间 |
|
||||
| `-v` | 本地目录或文件:容器目录文件,资源挂载到容器。<br />请把你的配置文件放在/root/config.php,会把你的配置映射进容器内。 |
|
||||
| `--restart` | 启动模式 |
|
||||
|
||||
------
|
||||
|
||||
|
||||
### 2.停止
|
||||
|
||||
```
|
||||
docker stop IYUUAutoReseed
|
||||
```
|
||||
|
||||
|
||||
### 3.运行
|
||||
|
||||
```
|
||||
docker start IYUUAutoReseed
|
||||
```
|
||||
|
||||
### 4.删除容器
|
||||
```
|
||||
docker rm IYUUAutoReseed
|
||||
```
|
||||
|
||||
### 5.删除镜像
|
||||
```
|
||||
docker rmi iyuucn/iyuuautoreseed:arm64v8
|
||||
```
|
||||
|
||||
|
||||
|
||||
------
|
||||
|
||||
|
||||
|
||||
#### 功能
|
||||
|
||||
IYUU自动辅种工具,功能分为两大块:自动辅种、自动转移。
|
||||
|
||||
- 自动辅种:目前能对国内大部分的PT站点自动辅种,支持下载器集群,支持多盘位,支持多下载目录,支持远程连接等;
|
||||
|
||||
- 自动转移:可以实现各下载器之间自动转移做种客户端,让下载器各司其职(专职的保种、专职的下载)。
|
||||
|
||||
#### 原理
|
||||
|
||||
IYUU自动辅种工具(英文名:IYUUAutoReseed),是一款PHP语言编写的Private Tracker辅种脚本,通过计划任务或常驻内存,按指定频率调用transmission、qBittorrent下载软件的API接口,提取正在做种的info_hash提交到辅种服务器API接口(辅种过程和PT站没有任何交互),根据API接口返回的数据拼接种子连接,提交给下载器,自动辅种各个站点。
|
||||
|
||||
#### 优势
|
||||
|
||||
- 全程自动化,无需人工干预;
|
||||
- 支持多盘位,多做种目录,多下载器,支持远程下载器;
|
||||
- 辅种精确度高,精度可配置;
|
||||
- 支持微信通知,消息即时达;
|
||||
- 自动对合集包,进行拆包辅种(暂未开发)
|
||||
- 安全:所有隐私信息只在本地存储,绝不发送给第三方。
|
||||
- 拥有专业的问答社区和交流群
|
||||
|
||||
#### 支持的下载器
|
||||
|
||||
1. transmission
|
||||
2. qBittorrent
|
||||
|
||||
#### 运行环境
|
||||
|
||||
具备PHP运行环境的所有平台,例如:Linux、Windows、MacOS!
|
||||
|
||||
官方下载的记得开启curl、json、mbstring,这3个扩展。
|
||||
|
||||
1. Windows安装php环境:https://www.php.net/downloads
|
||||
|
||||
#### 源码仓库
|
||||
|
||||
- github仓库:https://github.com/ledccn/IYUUAutoReseed
|
||||
- 码云仓库:https://gitee.com/ledc/IYUUAutoReseed
|
||||
|
||||
|
||||
#### 使用方法
|
||||
|
||||
- 博客:https://www.iyuu.cn/
|
||||
|
||||
#### 接口开发文档
|
||||
|
||||
如果您懂得其他语言的开发,可以基于接口做成任何您喜欢的样子,比如手机APP,二进制包,Windows的GUI程序,浏览器插件等。欢迎分享您的作品!
|
||||
|
||||
实时更新的接口文档:http://api.iyuu.cn/docs.php
|
||||
|
||||
|
||||
#### 需求提交/错误反馈
|
||||
|
||||
- QQ群:859882209[2000人.入门群],931954050[1000人.进阶群]
|
||||
- 问答社区:http://wenda.iyuu.cn
|
||||
- 博客:https://www.iyuu.cn/
|
||||
- issues: https://gitee.com/ledc/IYUUAutoReseed/issues
|
10
docker/entrypoint.sh
Normal file
10
docker/entrypoint.sh
Normal file
|
@ -0,0 +1,10 @@
|
|||
#!/bin/sh
|
||||
set -e
|
||||
envFile="/IYUU/.env"
|
||||
if [ ! -f "$envFile" ]; then
|
||||
git clone https://github.com/ledccn/IYUUPlus.git /IYUU
|
||||
cd /IYUU && php -r "file_exists('.env') || copy('.env.example', '.env');"
|
||||
fi
|
||||
cd /IYUU && git fetch --all && git reset --hard origin/master
|
||||
/usr/bin/php /IYUU/start.php start -d
|
||||
/usr/sbin/crond -f
|
20
docker/example.sh
Normal file
20
docker/example.sh
Normal file
|
@ -0,0 +1,20 @@
|
|||
#!/bin/sh
|
||||
export PATH=$PATH:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/root/bin
|
||||
## 相关命令
|
||||
# 1. 手动执行辅种
|
||||
docker exec IYUUPlus php ./bin/iyuu.php
|
||||
|
||||
# 2. 手动删除辅种缓存
|
||||
docker exec -it IYUUPlus rm -rf ./runtime/torrent/cachehash
|
||||
|
||||
# 3. 手动删除转移缓存
|
||||
docker exec -it IYUUPlus rm -rf ./runtime/torrent/cachemove
|
||||
|
||||
# 4. 查看当前定时任务
|
||||
docker exec -it IYUUPlus crontab -l
|
||||
|
||||
# 5. 修改定时任务(推荐修改docker容器的环境变量:参数cron)
|
||||
docker exec -it IYUUPlus crontab -e
|
||||
|
||||
# 6. 进入容器内交互终端
|
||||
docker exec -it IYUUPlus sh
|
62
init.php
Normal file
62
init.php
Normal file
|
@ -0,0 +1,62 @@
|
|||
<?php
|
||||
echo <<<EOF
|
||||
IIIIIIIIIIYYYYYYY YYYYYYYUUUUUUUU UUUUUUUUUUUUUUUU UUUUUUUU
|
||||
I::::::::IY:::::Y Y:::::YU::::::U U::::::UU::::::U U::::::U
|
||||
I::::::::IY:::::Y Y:::::YU::::::U U::::::UU::::::U U::::::U
|
||||
II::::::IIY::::::Y Y::::::YUU:::::U U:::::UUUU:::::U U:::::UU
|
||||
I::::I YYY:::::Y Y:::::YYY U:::::U U:::::U U:::::U U:::::U
|
||||
I::::I Y:::::Y Y:::::Y U:::::D D:::::U U:::::D D:::::U
|
||||
I::::I Y:::::Y:::::Y U:::::D D:::::U U:::::D D:::::U
|
||||
I::::I Y:::::::::Y U:::::D D:::::U U:::::D D:::::U
|
||||
I::::I Y:::::::Y U:::::D D:::::U U:::::D D:::::U
|
||||
I::::I Y:::::Y U:::::D D:::::U U:::::D D:::::U
|
||||
I::::I Y:::::Y U:::::D D:::::U U:::::D D:::::U
|
||||
I::::I Y:::::Y U::::::U U::::::U U::::::U U::::::U
|
||||
II::::::II Y:::::Y U:::::::UUU:::::::U U:::::::UUU:::::::U
|
||||
I::::::::I YYYY:::::YYYY UU:::::::::::::UU UU:::::::::::::UU
|
||||
I::::::::I Y:::::::::::Y UU:::::::::UU UU:::::::::UU
|
||||
IIIIIIIIII YYYYYYYYYYYYY UUUUUUUUU UUUUUUUUU
|
||||
|
||||
EOF;
|
||||
echo microtime(true).' 当前时间:'.date('Y-m-d H:i:s').PHP_EOL;
|
||||
echo microtime(true).' 当前操作系统:'.PHP_OS.PHP_EOL;
|
||||
echo microtime(true).' 当前运行环境:'.PHP_OS_FAMILY.PHP_EOL;
|
||||
echo microtime(true).' 当前接口类型:'.PHP_SAPI.PHP_EOL;
|
||||
echo microtime(true).' PHP二进制文件:'.PHP_BINARY.PHP_EOL;
|
||||
echo microtime(true).' PHP版本号:'.PHP_VERSION.PHP_EOL;
|
||||
echo microtime(true).' 正在加载composer包管理器...'.PHP_EOL;
|
||||
require_once __DIR__ . '/vendor/autoload.php';
|
||||
echo microtime(true).' composer依赖载入完成!'.PHP_EOL;
|
||||
|
||||
// 定义目录
|
||||
defined('ROOT_PATH') or define('ROOT_PATH', __DIR__);
|
||||
defined('DB_PATH') or define('DB_PATH', __DIR__ . DIRECTORY_SEPARATOR . 'db');
|
||||
defined('RUNTIME_PATH') or define('RUNTIME_PATH', __DIR__ . DIRECTORY_SEPARATOR . 'runtime');
|
||||
defined('CRONATB_PATH') or define('CRONATB_PATH', RUNTIME_PATH . DIRECTORY_SEPARATOR . 'crontab');
|
||||
defined('TORRENT_PATH') or define('TORRENT_PATH', RUNTIME_PATH . DIRECTORY_SEPARATOR . 'torrent');
|
||||
defined('DS') or define('DS', DIRECTORY_SEPARATOR);
|
||||
|
||||
// 严格开发模式
|
||||
error_reporting(E_ALL);
|
||||
ini_set('display_errors', 1);
|
||||
|
||||
// 永不超时
|
||||
ini_set('max_execution_time', 0);
|
||||
set_time_limit(0);
|
||||
|
||||
// 内存限制,如果外面设置的内存比 /etc/php/php-cli.ini 大,就不要设置了
|
||||
if (intval(ini_get("memory_limit")) < 1024) {
|
||||
ini_set('memory_limit', '1024M');
|
||||
}
|
||||
|
||||
// 限定CLI
|
||||
if (PHP_SAPI != 'cli') {
|
||||
exit("You must run the CLI environment\n");
|
||||
}
|
||||
|
||||
// 设置时区
|
||||
date_default_timezone_set('Asia/Shanghai');
|
||||
echo microtime(true).' 环境变量初始化完成!'.PHP_EOL.PHP_EOL;
|
||||
|
||||
// 命令行参数
|
||||
global $argv;
|
104
process/FileMonitor.php
Normal file
104
process/FileMonitor.php
Normal file
|
@ -0,0 +1,104 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is part of webman.
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the MIT-LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @author walkor<walkor@workerman.net>
|
||||
* @copyright walkor<walkor@workerman.net>
|
||||
* @link http://www.workerman.net/
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
namespace process;
|
||||
|
||||
use Workerman\Timer;
|
||||
use Workerman\Worker;
|
||||
|
||||
class FileMonitor
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $_paths = [];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $_extensions = [];
|
||||
|
||||
/**
|
||||
* pidFile
|
||||
*/
|
||||
const pidFile = 'IYUUFileMonitor.pid';
|
||||
|
||||
/**
|
||||
* FileMonitor constructor.
|
||||
* @param $monitor_dir
|
||||
* @param $monitor_extenstions
|
||||
*/
|
||||
public function __construct($monitor_dir, $monitor_extenstions)
|
||||
{
|
||||
\file_put_contents(runtime_path() . \DIRECTORY_SEPARATOR . self::pidFile, \posix_getpid());
|
||||
if (Worker::$daemonize) {
|
||||
#return;
|
||||
}
|
||||
$this->_paths = (array)$monitor_dir;
|
||||
$this->_extensions = $monitor_extenstions;
|
||||
Timer::add(1, function () {
|
||||
foreach ($this->_paths as $path) {
|
||||
$this->check_files_change($path);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 析构方法
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
is_file(runtime_path() . \DIRECTORY_SEPARATOR . self::pidFile) and @\unlink(runtime_path() . \DIRECTORY_SEPARATOR . self::pidFile);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $monitor_dir
|
||||
*/
|
||||
public function check_files_change($monitor_dir)
|
||||
{
|
||||
static $last_mtime;
|
||||
if (!$last_mtime) {
|
||||
$last_mtime = time();
|
||||
}
|
||||
|
||||
clearstatcache();
|
||||
|
||||
if (!is_dir($monitor_dir)) {
|
||||
return;
|
||||
}
|
||||
// recursive traversal directory
|
||||
$dir_iterator = new \RecursiveDirectoryIterator($monitor_dir);
|
||||
$iterator = new \RecursiveIteratorIterator($dir_iterator);
|
||||
foreach ($iterator as $file) {
|
||||
/** var SplFileInfo $file */
|
||||
if (is_dir($file)) {
|
||||
continue;
|
||||
}
|
||||
// check mtime
|
||||
if ($last_mtime < $file->getMTime() && in_array($file->getExtension(), $this->_extensions)) {
|
||||
$var = 0;
|
||||
exec("php -l " . $file, $out, $var);
|
||||
if ($var) {
|
||||
$last_mtime = $file->getMTime();
|
||||
continue;
|
||||
}
|
||||
echo $file . " update and reload\n";
|
||||
// send SIGUSR1 signal to master process for reload
|
||||
posix_kill(posix_getppid(), SIGUSR1);
|
||||
$last_mtime = $file->getMTime();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
169
process/Task.php
Normal file
169
process/Task.php
Normal file
|
@ -0,0 +1,169 @@
|
|||
<?php
|
||||
namespace process;
|
||||
|
||||
use Workerman\Lib\Timer;
|
||||
use Workerman\Crontab\Crontab;
|
||||
use app\common\Constant;
|
||||
use app\common\Config as Conf;
|
||||
use app\domain\Crontab as domainCron;
|
||||
|
||||
class Task
|
||||
{
|
||||
/**
|
||||
* pidFile
|
||||
*/
|
||||
const pidFile = 'IYUUTask.pid';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private static $cron_dir = '';
|
||||
|
||||
/**
|
||||
* 定时任务命令缓存,当filemtime发生变化时将重新缓存,避免频繁读取磁盘
|
||||
* @var array
|
||||
*/
|
||||
private static $cron_cache = array();
|
||||
|
||||
/**
|
||||
* file scanner interval
|
||||
* 定时任务文件扫描间隔值介于0-60之间,保证在$interval内扫描次数大于等于2次,可根据CPU运转压力适当调整,建议值为0.9
|
||||
* @var float
|
||||
*/
|
||||
private static $interval = 1;
|
||||
|
||||
/**
|
||||
* 构造方法
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
// 保存当前进程pid
|
||||
\file_put_contents(runtime_path() . \DIRECTORY_SEPARATOR . self::pidFile, \posix_getpid());
|
||||
// 初始化cron
|
||||
domainCron::onWorkerStart();
|
||||
// 初始化计划任务的绝对路径
|
||||
self::$cron_dir = cron_path() . DIRECTORY_SEPARATOR . domainCron::cron_dir;
|
||||
//添加扫描器
|
||||
Timer::add(self::$interval, array($this, 'startScan'));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 析构方法
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
// 删除当前进程pid文件
|
||||
is_file(runtime_path() . \DIRECTORY_SEPARATOR . self::pidFile) and @\unlink(runtime_path() . \DIRECTORY_SEPARATOR . self::pidFile);
|
||||
}
|
||||
|
||||
/**
|
||||
* 进程启动时执行
|
||||
*/
|
||||
public function onWorkerStart()
|
||||
{
|
||||
// 每10秒执行
|
||||
new Crontab('*/10 * * * * *', function(){
|
||||
//echo date('Y-m-d H:i:s')."\n";
|
||||
});
|
||||
|
||||
// 每天的10点10执行,注意这里省略了秒位
|
||||
new Crontab('10 10 * * *', function(){
|
||||
//echo date('Y-m-d H:i:s')."\n";
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 启动扫描器并分析计划任务
|
||||
*/
|
||||
public function startScan()
|
||||
{
|
||||
clearstatcache();
|
||||
$pattern = self::$cron_dir . '/*' .domainCron::cron_suffix;
|
||||
// 扫描任务目录
|
||||
foreach (glob($pattern) as $cron_file) {
|
||||
$filename = basename($cron_file);
|
||||
$fileMtime = filemtime($cron_file);
|
||||
// 初次读取任务文件并缓存到变量(self::$cron_cache)
|
||||
if (empty(self::$cron_cache[$filename])) {
|
||||
$this->addCache($cron_file, $filename, $fileMtime);
|
||||
}
|
||||
|
||||
// 任务缓存判断
|
||||
if (self::$cron_cache[$filename]['fileMtime'] === $fileMtime) {
|
||||
// 命中缓存
|
||||
} else {
|
||||
// 未命中缓存
|
||||
echo $cron_file.'修改时间:'.date('Y-m-d H:i:s', $fileMtime).PHP_EOL;
|
||||
// 清理定时器
|
||||
$this->clearTimer($filename);
|
||||
$this->addCache($cron_file, $filename, $fileMtime);
|
||||
}
|
||||
}
|
||||
//清理计划任务缓存
|
||||
$this->clearCache();
|
||||
//cli(self::$cron_cache);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建计划任务缓存
|
||||
* @param string $cron_file
|
||||
* @param string $filename
|
||||
* @param int $fileMtime
|
||||
* @return array
|
||||
*/
|
||||
public function addCache(string $cron_file, string $filename, int $fileMtime):array
|
||||
{
|
||||
$cron = Conf::get($cron_file, Constant::config_format, [], true);
|
||||
self::$cron_cache[$filename] = $cron;
|
||||
self::$cron_cache[$filename]['fileMtime'] = $fileMtime;
|
||||
// 添加定时器
|
||||
$this->addTimer($cron, $filename);
|
||||
return $cron;
|
||||
}
|
||||
|
||||
/**
|
||||
* 清理计划任务缓存
|
||||
*/
|
||||
public function clearCache()
|
||||
{
|
||||
clearstatcache();
|
||||
foreach (self::$cron_cache as $filename => $cron) {
|
||||
$cron_file = self::$cron_dir . DIRECTORY_SEPARATOR . $filename;
|
||||
if (!is_file($cron_file)) {
|
||||
unset(self::$cron_cache[$filename]);
|
||||
// 清理定时器
|
||||
$this->clearTimer($filename);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加定时器
|
||||
* @param array $cron
|
||||
* @param string $filename
|
||||
*/
|
||||
public function addTimer(array $cron, string $filename)
|
||||
{
|
||||
new Crontab($cron['crontab'], function () use ($cron) {
|
||||
domainCron::execute($cron['command'], $cron['uuid']);
|
||||
}, $filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* 清理定时器
|
||||
* @param string $filename
|
||||
*/
|
||||
public function clearTimer(string $filename = '')
|
||||
{
|
||||
$_instances = Crontab::getAll(); // Crontab对象数组
|
||||
foreach ($_instances as $id => $crontab) {
|
||||
$name = $crontab->getName();
|
||||
// 关键条件
|
||||
if (is_string($name) && ($name === $filename)) {
|
||||
$crontab->remove($id); //移除定时器
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
41
process/Websocket.php
Normal file
41
process/Websocket.php
Normal file
|
@ -0,0 +1,41 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is part of webman.
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the MIT-LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @author walkor<walkor@workerman.net>
|
||||
* @copyright walkor<walkor@workerman.net>
|
||||
* @link http://www.workerman.net/
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
namespace process;
|
||||
|
||||
use Workerman\Connection\TcpConnection;
|
||||
|
||||
class Websocket
|
||||
{
|
||||
public function onConnect(TcpConnection $connection)
|
||||
{
|
||||
echo "onConnect\n";
|
||||
}
|
||||
|
||||
public function onWebSocketConnect(TcpConnection $connection, $http_buffer)
|
||||
{
|
||||
echo "onWebSocketConnect\n";
|
||||
}
|
||||
|
||||
public function onMessage(TcpConnection $connection, $data)
|
||||
{
|
||||
$connection->send($data);
|
||||
}
|
||||
|
||||
public function onClose(TcpConnection $connection)
|
||||
{
|
||||
echo "onClose\n";
|
||||
}
|
||||
|
||||
}
|
5
public/.gitattributes
vendored
Normal file
5
public/.gitattributes
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
*.js linguist-language=JavaScript
|
||||
|
||||
*.css linguist-language=JavaScript
|
||||
|
||||
*.html linguist-language=JavaScript
|
1
public/.gitignore
vendored
Normal file
1
public/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
/.idea
|
12
public/404.html
Normal file
12
public/404.html
Normal file
|
@ -0,0 +1,12 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>404 Not Found - webman</title>
|
||||
</head>
|
||||
<body>
|
||||
<center>
|
||||
<h1>404 Not Found</h1>
|
||||
</center>
|
||||
<hr>
|
||||
<center><a href="https://www.workerman.net">webman</a></center>
|
||||
</body>
|
||||
</html>
|
21
public/LICENSE
Normal file
21
public/LICENSE
Normal file
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2019 layuimini
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
76
public/README.md
Normal file
76
public/README.md
Normal file
|
@ -0,0 +1,76 @@
|
|||
layuimini后台模板
|
||||
===============
|
||||
# 项目介绍
|
||||
最简洁、清爽、易用的layui后台框架模板。
|
||||
|
||||
项目会不定时进行更新,建议star和watch一份。
|
||||
|
||||
技术交流QQ群:[1165301500](https://jq.qq.com/?_wv=1027&k=eUm5xKG1)、[667813249🈵](https://jq.qq.com/?_wv=1027&k=5lyiE2Q)、[561838086🈵](https://jq.qq.com/?_wv=1027&k=5JRGVfe)
|
||||
|
||||
# 主要特性
|
||||
* 界面足够简洁清爽,响应式且适配手机端。
|
||||
* 一个接口`几行代码而已`直接初始化整个框架,无需复杂操作。
|
||||
* 页面支持多配色方案,可自行选择喜欢的配色。
|
||||
* 支持多tab,可以打开多窗口。
|
||||
* 支持无限级菜单和对font-awesome图标库的完美支持。
|
||||
* 失效以及报错菜单无法直接打开,并给出弹出层提示`完美的线上用户体验`。
|
||||
* url地址hash定位,可以清楚看到当前tab的地址信息。
|
||||
* 刷新页面会保留当前的窗口,并且会定位当前窗口对应左侧菜单栏。
|
||||
* 支持font-awesome图标选择插件
|
||||
|
||||
|
||||
# 代码仓库(iframe 多tab版)
|
||||
|
||||
### v2版
|
||||
* 在线预览地址:[http://layuimini.99php.cn/iframe/v2/index.html](http://layuimini.99php.cn/iframe/v2/index.html)
|
||||
* GitHub仓库地址:[https://github.com/zhongshaofa/layuimini/tree/v2](https://github.com/zhongshaofa/layuimini/tree/v2)
|
||||
* Gitee仓库地址:[https://gitee.com/zhongshaofa/layuimini/tree/v2](https://gitee.com/zhongshaofa/layuimini/tree/v2)
|
||||
### v1版
|
||||
* 在线预览地址:[http://layuimini.99php.cn/iframe/v1/index.html](http://layuimini.99php.cn/iframe/v1/index.html)
|
||||
* GitHub仓库地址:[https://github.com/zhongshaofa/layuimini/tree/master](https://github.com/zhongshaofa/layuimini/tree/master)
|
||||
* Gitee仓库地址:[https://gitee.com/zhongshaofa/layuimini/tree/master](https://gitee.com/zhongshaofa/layuimini/tree/master)
|
||||
|
||||
# 代码仓库(onepage 单页版)
|
||||
|
||||
### v2版
|
||||
* 在线预览地址:[http://layuimini.99php.cn/onepage/v2/index.html](http://layuimini.99php.cn/onepage/v2/index.html)
|
||||
* GitHub仓库地址:[https://github.com/zhongshaofa/layuimini/tree/v2-onepage](https://github.com/zhongshaofa/layuimini/tree/v2-onepage)
|
||||
* Gitee仓库地址:[https://gitee.com/zhongshaofa/layuimini/tree/v2-onepage](https://gitee.com/zhongshaofa/layuimini/tree/v2-onepage)
|
||||
|
||||
### v1版
|
||||
* 在线预览地址:[http://layuimini.99php.cn/onepage/v1/index.html](http://layuimini.99php.cn/onepage/v1/index.html)
|
||||
* GitHub仓库地址:[https://github.com/zhongshaofa/layuimini/tree/onepage](https://github.com/zhongshaofa/layuimini/tree/onepage)
|
||||
* Gitee仓库地址:[https://gitee.com/zhongshaofa/layuimini/tree/onepage](https://gitee.com/zhongshaofa/layuimini/tree/onepage)
|
||||
|
||||
# 下载方式
|
||||
|
||||
### iframe v2版
|
||||
* GitHub下载命令:`git clone https://github.com/zhongshaofa/layuimini -b v2`
|
||||
* Gitee下载命令:`git clone https://gitee.com/zhongshaofa/layuimini -b v2`
|
||||
### iframe v1版
|
||||
* GitHub下载命令:`git clone https://github.com/zhongshaofa/layuimini -b master`
|
||||
* Gitee下载命令:`git clone https://gitee.com/zhongshaofa/layuimini -b master`
|
||||
### 单页版 v2版
|
||||
* GitHub下载命令:`git clone https://github.com/zhongshaofa/layuimini -b v2-onepage`
|
||||
* Gitee下载命令:`git clone https://gitee.com/zhongshaofa/layuimini -b v2-onepage`
|
||||
### 单页版 v1版
|
||||
* GitHub下载命令:`git clone https://github.com/zhongshaofa/layuimini -b onepage`
|
||||
* Gitee下载命令:`git clone https://gitee.com/zhongshaofa/layuimini -b onepage`
|
||||
### 发行版地址
|
||||
* GitHub发版地址:[https://github.com/zhongshaofa/layuimini/releases](https://github.com/zhongshaofa/layuimini/releases)
|
||||
* Gitee发版地址:[https://gitee.com/zhongshaofa/layuimini/releases](https://gitee.com/zhongshaofa/layuimini/releases)
|
||||
|
||||
# 效果预览
|
||||
> 总体预览
|
||||
|
||||
![Image text](./images/home.png)
|
||||
|
||||
# 使用说明
|
||||
|
||||
文档地址:[查看文档](http://layuimini.99php.cn/docs/)
|
||||
|
||||
# 捐赠支持
|
||||
|
||||
开源项目不易,若此项目能得到你的青睐,可以捐赠支持作者持续开发与维护,感谢所有支持开源的朋友。
|
||||
|
||||
![Image text](https://chung-common.oss-cn-beijing.aliyuncs.com/donate_qrcode.png)
|
573
public/api/init.json
Normal file
573
public/api/init.json
Normal file
|
@ -0,0 +1,573 @@
|
|||
{
|
||||
"homeInfo": {
|
||||
"title": "首页",
|
||||
"href": "page/welcome.html?t=1"
|
||||
},
|
||||
"logoInfo": {
|
||||
"title": "IYUU PLUS",
|
||||
"image": "images/logo.png",
|
||||
"href": ""
|
||||
},
|
||||
"menuInfo": [{
|
||||
"id": 1,
|
||||
"title": "运营后台",
|
||||
"icon": "fa fa-address-book fa-fw",
|
||||
"href": null,
|
||||
"target": "_self",
|
||||
"sort_num": 1,
|
||||
"parent_id": 0,
|
||||
"assign_admin_roles": "",
|
||||
"assgin_admin_usernames": null,
|
||||
"child": [{
|
||||
"id": 101,
|
||||
"title": "首页",
|
||||
"icon": "fa fa fa-home",
|
||||
"href": "page/welcome.html",
|
||||
"target": "_self",
|
||||
"sort_num": 0,
|
||||
"parent_id": 1,
|
||||
"assign_admin_roles": "super",
|
||||
"assgin_admin_usernames": ""
|
||||
},
|
||||
{
|
||||
"id": 33399,
|
||||
"title": "系统状态",
|
||||
"icon": "fa fa-dashboard",
|
||||
"href": "",
|
||||
"target": "_self",
|
||||
"sort_num": 1,
|
||||
"parent_id": 1,
|
||||
"assign_admin_roles": "super",
|
||||
"assgin_admin_usernames": "",
|
||||
"child": [{
|
||||
"id": 37725,
|
||||
"title": "概览",
|
||||
"icon": "fa fa-pie-chart fa-fw",
|
||||
"href": "page/status/overview.html",
|
||||
"target": "_self",
|
||||
"sort_num": 0,
|
||||
"parent_id": 33399,
|
||||
"assign_admin_roles": "",
|
||||
"assgin_admin_usernames": null
|
||||
},
|
||||
{
|
||||
"id": 22895,
|
||||
"title": "主机监控",
|
||||
"icon": "fa fa-desktop fa-fw",
|
||||
"href": "page/status/hoststat.html",
|
||||
"target": "_self",
|
||||
"sort_num": 1,
|
||||
"parent_id": 33399,
|
||||
"assign_admin_roles": "super",
|
||||
"assgin_admin_usernames": ""
|
||||
},
|
||||
{
|
||||
"id": 42488,
|
||||
"title": "日志",
|
||||
"icon": "fa fa-refresh fa-fw fa-spin",
|
||||
"href": "",
|
||||
"target": "_self",
|
||||
"sort_num": 2,
|
||||
"parent_id": 33399,
|
||||
"assign_admin_roles": "super",
|
||||
"assgin_admin_usernames": "",
|
||||
"child": [{
|
||||
"id": 63033,
|
||||
"title": "辅种日志",
|
||||
"icon": "fa fa-clone fa-fw",
|
||||
"href": "page/status/reseedlog.html",
|
||||
"target": "_self",
|
||||
"sort_num": 0,
|
||||
"parent_id": 42488,
|
||||
"assign_admin_roles": "",
|
||||
"assgin_admin_usernames": null
|
||||
},
|
||||
{
|
||||
"id": 93886,
|
||||
"title": "下载日志",
|
||||
"icon": "fa fa-download fa-fw",
|
||||
"href": "page/status/downlog.html",
|
||||
"target": "_self",
|
||||
"sort_num": 1,
|
||||
"parent_id": 42488,
|
||||
"assign_admin_roles": "super",
|
||||
"assgin_admin_usernames": ""
|
||||
},
|
||||
{
|
||||
"id": 77375,
|
||||
"title": "订阅日志",
|
||||
"icon": "fa fa-feed fa-fw",
|
||||
"href": "page/status/feedlog.html",
|
||||
"target": "_self",
|
||||
"sort_num": 2,
|
||||
"parent_id": 42488,
|
||||
"assign_admin_roles": "super",
|
||||
"assgin_admin_usernames": ""
|
||||
},
|
||||
{
|
||||
"id": 76063,
|
||||
"title": "削刮日志",
|
||||
"icon": "fa fa-imdb fa-fw",
|
||||
"href": "page/status/shavinglog.html",
|
||||
"target": "_self",
|
||||
"sort_num": 3,
|
||||
"parent_id": 42488,
|
||||
"assign_admin_roles": "super",
|
||||
"assgin_admin_usernames": ""
|
||||
},
|
||||
{
|
||||
"id": 63702,
|
||||
"title": "分享日志",
|
||||
"icon": "fa fa-share fa-fw",
|
||||
"href": "page/status/sharelog.html",
|
||||
"target": "_self",
|
||||
"sort_num": 4,
|
||||
"parent_id": 42488,
|
||||
"assign_admin_roles": "super",
|
||||
"assgin_admin_usernames": ""
|
||||
},
|
||||
{
|
||||
"id": 24407,
|
||||
"title": "系统日志",
|
||||
"icon": "fa fa-microchip fa-fw",
|
||||
"href": "page/status/syslog.html",
|
||||
"target": "_self",
|
||||
"sort_num": 9,
|
||||
"parent_id": 42488,
|
||||
"assign_admin_roles": "super",
|
||||
"assgin_admin_usernames": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 80638,
|
||||
"title": "系统设置",
|
||||
"icon": "fa fa-gears",
|
||||
"href": "",
|
||||
"target": "_self",
|
||||
"sort_num": 2,
|
||||
"parent_id": 1,
|
||||
"assign_admin_roles": "super",
|
||||
"assgin_admin_usernames": "",
|
||||
"child": [{
|
||||
"id": 45407,
|
||||
"title": "用户认证",
|
||||
"icon": "fa fa-address-card fa-fw",
|
||||
"href": "page/setting/user.html",
|
||||
"target": "_self",
|
||||
"sort_num": 0,
|
||||
"parent_id": 80638,
|
||||
"assign_admin_roles": "super",
|
||||
"assgin_admin_usernames": ""
|
||||
},
|
||||
{
|
||||
"id": 58581,
|
||||
"title": "常规设置",
|
||||
"icon": "fa fa-cog fa-fw",
|
||||
"href": "page/setting/default.html",
|
||||
"target": "_self",
|
||||
"sort_num": 1,
|
||||
"parent_id": 80638,
|
||||
"assign_admin_roles": "super",
|
||||
"assgin_admin_usernames": ""
|
||||
},
|
||||
{
|
||||
"id": 46548,
|
||||
"title": "站点设置",
|
||||
"icon": "fa fa-globe fa-fw",
|
||||
"href": "page/setting/sites.html",
|
||||
"target": "_self",
|
||||
"sort_num": 2,
|
||||
"parent_id": 80638,
|
||||
"assign_admin_roles": "super",
|
||||
"assgin_admin_usernames": ""
|
||||
},
|
||||
{
|
||||
"id": 39158,
|
||||
"title": "下载器设置",
|
||||
"icon": "fa fa-cloud-download fa-fw",
|
||||
"href": "page/setting/clients.html",
|
||||
"target": "_self",
|
||||
"sort_num": 3,
|
||||
"parent_id": 80638,
|
||||
"assign_admin_roles": "super",
|
||||
"assgin_admin_usernames": ""
|
||||
},
|
||||
{
|
||||
"id": 32612,
|
||||
"title": "目录设置",
|
||||
"icon": "fa fa-folder fa-fw",
|
||||
"href": "page/setting/folder.html",
|
||||
"target": "_self",
|
||||
"sort_num": 4,
|
||||
"parent_id": 80638,
|
||||
"assign_admin_roles": "",
|
||||
"assgin_admin_usernames": null
|
||||
},
|
||||
{
|
||||
"id": 29585,
|
||||
"title": "标签设置",
|
||||
"icon": "fa fa-tags fa-fw",
|
||||
"href": "page/setting/tags.html",
|
||||
"target": "_self",
|
||||
"sort_num": 5,
|
||||
"parent_id": 80638,
|
||||
"assign_admin_roles": "",
|
||||
"assgin_admin_usernames": null
|
||||
},
|
||||
{
|
||||
"id": 61661,
|
||||
"title": "过滤器设置",
|
||||
"icon": "fa fa-filter fa-fw",
|
||||
"href": "page/setting/filter.html",
|
||||
"target": "_self",
|
||||
"sort_num": 6,
|
||||
"parent_id": 80638,
|
||||
"assign_admin_roles": "super",
|
||||
"assgin_admin_usernames": ""
|
||||
},
|
||||
{
|
||||
"id": 26278,
|
||||
"title": "通知设置",
|
||||
"icon": "fa fa-bell-o fa-fw",
|
||||
"href": "",
|
||||
"target": "_self",
|
||||
"sort_num": 9,
|
||||
"parent_id": 80638,
|
||||
"assign_admin_roles": "super",
|
||||
"assgin_admin_usernames": "",
|
||||
"child": [{
|
||||
"id": 89240,
|
||||
"title": "微信配置",
|
||||
"icon": "fa fa-weixin fa-fw",
|
||||
"href": "page/setting/weixin.html",
|
||||
"target": "_self",
|
||||
"sort_num": 0,
|
||||
"parent_id": 26278,
|
||||
"assign_admin_roles": "",
|
||||
"assgin_admin_usernames": null
|
||||
},
|
||||
{
|
||||
"id": 17982,
|
||||
"title": "邮箱配置",
|
||||
"icon": "fa fa-envelope fa-fw",
|
||||
"href": "page/setting/mail.html",
|
||||
"target": "_self",
|
||||
"sort_num": 2,
|
||||
"parent_id": 26278,
|
||||
"assign_admin_roles": "super",
|
||||
"assgin_admin_usernames": ""
|
||||
},
|
||||
{
|
||||
"id": 98077,
|
||||
"title": "短信配置",
|
||||
"icon": "fa fa-comment-o fa-fw",
|
||||
"href": "page/setting/sms.html",
|
||||
"target": "_self",
|
||||
"sort_num": 3,
|
||||
"parent_id": 26278,
|
||||
"assign_admin_roles": "super",
|
||||
"assgin_admin_usernames": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 71926,
|
||||
"title": "计划任务",
|
||||
"icon": "fa fa-calendar",
|
||||
"href": "page/crontab.html",
|
||||
"target": "_self",
|
||||
"sort_num": 4,
|
||||
"parent_id": 1,
|
||||
"assign_admin_roles": "super",
|
||||
"assgin_admin_usernames": ""
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"title": "管理中心",
|
||||
"icon": "fa fa-building fa-fw",
|
||||
"href": "",
|
||||
"target": "_self",
|
||||
"sort_num": 2,
|
||||
"parent_id": 0,
|
||||
"assign_admin_roles": "super",
|
||||
"assgin_admin_usernames": "",
|
||||
"child": [{
|
||||
"id": 48539,
|
||||
"title": "种子管理",
|
||||
"icon": "fa fa-database",
|
||||
"href": "",
|
||||
"target": "_self",
|
||||
"sort_num": 0,
|
||||
"parent_id": 2,
|
||||
"assign_admin_roles": "super",
|
||||
"assgin_admin_usernames": "",
|
||||
"child": [{
|
||||
"id": 69699,
|
||||
"title": "概览",
|
||||
"icon": "fa fa-pie-chart fa-fw",
|
||||
"href": "page/torrent/overview.html",
|
||||
"target": "_self",
|
||||
"sort_num": 0,
|
||||
"parent_id": 48539,
|
||||
"assign_admin_roles": "super",
|
||||
"assgin_admin_usernames": ""
|
||||
},
|
||||
{
|
||||
"id": 50256,
|
||||
"title": "全部种子",
|
||||
"icon": "fa fa-file fa-fw",
|
||||
"href": "page/torrent/index.html",
|
||||
"target": "_self",
|
||||
"sort_num": 0,
|
||||
"parent_id": 48539,
|
||||
"assign_admin_roles": "super",
|
||||
"assgin_admin_usernames": ""
|
||||
},
|
||||
{
|
||||
"id": 10409,
|
||||
"title": "错误种子",
|
||||
"icon": "fa fa-exclamation-circle fa-fw",
|
||||
"href": "page/torrent/error.html",
|
||||
"target": "_self",
|
||||
"sort_num": 0,
|
||||
"parent_id": 48539,
|
||||
"assign_admin_roles": "",
|
||||
"assgin_admin_usernames": null
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 86647,
|
||||
"title": "站点管理",
|
||||
"icon": "fa fa-diamond",
|
||||
"href": "page/sites/index.html",
|
||||
"target": "_self",
|
||||
"sort_num": 1,
|
||||
"parent_id": 2,
|
||||
"assign_admin_roles": "super",
|
||||
"assgin_admin_usernames": ""
|
||||
},
|
||||
{
|
||||
"id": 10978,
|
||||
"title": "用户管理",
|
||||
"icon": "fa fa-user",
|
||||
"href": "page/users/index.html",
|
||||
"target": "_self",
|
||||
"sort_num": 2,
|
||||
"parent_id": 2,
|
||||
"assign_admin_roles": "super",
|
||||
"assgin_admin_usernames": ""
|
||||
},
|
||||
{
|
||||
"id": 15534,
|
||||
"title": "权限管理",
|
||||
"icon": "fa fa-id-card",
|
||||
"href": "page/auth/index.html",
|
||||
"target": "_self",
|
||||
"sort_num": 3,
|
||||
"parent_id": 2,
|
||||
"assign_admin_roles": "super",
|
||||
"assgin_admin_usernames": ""
|
||||
},
|
||||
{
|
||||
"id": 23,
|
||||
"title": "菜单管理",
|
||||
"icon": "fa fa-sitemap",
|
||||
"href": "page/menu/index.html",
|
||||
"target": "_self",
|
||||
"sort_num": 8,
|
||||
"parent_id": 2,
|
||||
"assign_admin_roles": "super",
|
||||
"assgin_admin_usernames": ""
|
||||
},
|
||||
{
|
||||
"id": 202,
|
||||
"title": "表单示例",
|
||||
"icon": "fa fa-file-text",
|
||||
"href": "",
|
||||
"target": "_self",
|
||||
"sort_num": 97,
|
||||
"parent_id": 2,
|
||||
"assign_admin_roles": "super",
|
||||
"assgin_admin_usernames": "",
|
||||
"child": [{
|
||||
"id": 2001,
|
||||
"title": "表格示例",
|
||||
"icon": "fa fa-calendar fa-fw",
|
||||
"href": "page/table.html",
|
||||
"target": "_self",
|
||||
"sort_num": 0,
|
||||
"parent_id": 202,
|
||||
"assign_admin_roles": "super",
|
||||
"assgin_admin_usernames": ""
|
||||
},
|
||||
{
|
||||
"id": 2002,
|
||||
"title": "普通表单",
|
||||
"icon": "fa fa-list-alt fa-fw",
|
||||
"href": "page/form.html",
|
||||
"target": "_self",
|
||||
"sort_num": 1,
|
||||
"parent_id": 202,
|
||||
"assign_admin_roles": "super",
|
||||
"assgin_admin_usernames": ""
|
||||
},
|
||||
{
|
||||
"id": 203,
|
||||
"title": "分步表单",
|
||||
"icon": "fa fa-navicon fa-fw",
|
||||
"href": "page/form-step.html",
|
||||
"target": "_self",
|
||||
"sort_num": 2,
|
||||
"parent_id": 202,
|
||||
"assign_admin_roles": "super",
|
||||
"assgin_admin_usernames": ""
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 204,
|
||||
"title": "其它界面",
|
||||
"icon": "fa fa-snowflake-o",
|
||||
"href": "",
|
||||
"target": "_self",
|
||||
"sort_num": 98,
|
||||
"parent_id": 2,
|
||||
"assign_admin_roles": "super",
|
||||
"assgin_admin_usernames": "",
|
||||
"child": [{
|
||||
"id": 201,
|
||||
"title": "系统设置",
|
||||
"icon": "fa fa-gears fa-fw",
|
||||
"href": "page/setting.html",
|
||||
"target": "_self",
|
||||
"sort_num": 0,
|
||||
"parent_id": 204,
|
||||
"assign_admin_roles": "",
|
||||
"assgin_admin_usernames": null
|
||||
},
|
||||
{
|
||||
"id": 2003,
|
||||
"title": "按钮示例",
|
||||
"icon": "fa fa-snowflake-o fa-fw",
|
||||
"href": "page/button.html",
|
||||
"target": "_self",
|
||||
"sort_num": 0,
|
||||
"parent_id": 204,
|
||||
"assign_admin_roles": "",
|
||||
"assgin_admin_usernames": null
|
||||
},
|
||||
{
|
||||
"id": 2004,
|
||||
"title": "弹出层",
|
||||
"icon": "fa fa-shield fa-fw",
|
||||
"href": "page/layer.html",
|
||||
"target": "_self",
|
||||
"sort_num": 0,
|
||||
"parent_id": 204,
|
||||
"assign_admin_roles": "",
|
||||
"assgin_admin_usernames": null
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 205,
|
||||
"title": "组件",
|
||||
"icon": "fa fa-lemon-o",
|
||||
"href": "",
|
||||
"target": "_self",
|
||||
"sort_num": 99,
|
||||
"parent_id": 2,
|
||||
"assign_admin_roles": "super",
|
||||
"assgin_admin_usernames": "",
|
||||
"child": [{
|
||||
"id": 2005,
|
||||
"title": "图标列表",
|
||||
"icon": "fa fa-dot-circle-o fa-fw",
|
||||
"href": "page/icon.html",
|
||||
"target": "_self",
|
||||
"sort_num": 0,
|
||||
"parent_id": 205,
|
||||
"assign_admin_roles": "",
|
||||
"assgin_admin_usernames": null
|
||||
},
|
||||
{
|
||||
"id": 2006,
|
||||
"title": "文件上传",
|
||||
"icon": "fa fa-arrow-up fa-fw",
|
||||
"href": "page/upload.html",
|
||||
"target": "_self",
|
||||
"sort_num": 0,
|
||||
"parent_id": 205,
|
||||
"assign_admin_roles": "",
|
||||
"assgin_admin_usernames": null
|
||||
},
|
||||
{
|
||||
"id": 2007,
|
||||
"title": "富文本编辑器",
|
||||
"icon": "fa fa-edit fa-fw",
|
||||
"href": "page/editor.html",
|
||||
"target": "_self",
|
||||
"sort_num": 0,
|
||||
"parent_id": 205,
|
||||
"assign_admin_roles": "",
|
||||
"assgin_admin_usernames": null
|
||||
},
|
||||
{
|
||||
"id": 2008,
|
||||
"title": "省市县区选择器",
|
||||
"icon": "fa fa-rocket fa-fw",
|
||||
"href": "page/area.html",
|
||||
"target": "_self",
|
||||
"sort_num": 0,
|
||||
"parent_id": 205,
|
||||
"assign_admin_roles": "",
|
||||
"assgin_admin_usernames": null
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"title": "应用市场",
|
||||
"icon": "fa fa-cloud fa-fw",
|
||||
"href": "http://www.iyuu.cn",
|
||||
"target": "_self",
|
||||
"sort_num": 3,
|
||||
"parent_id": 0,
|
||||
"assign_admin_roles": "super",
|
||||
"assgin_admin_usernames": null,
|
||||
"child": [{
|
||||
"id": 21,
|
||||
"title": "应用市场",
|
||||
"icon": "fa fa-cloud fa-fw",
|
||||
"href": "page/plugins/index.html",
|
||||
"target": "_self",
|
||||
"sort_num": 1,
|
||||
"parent_id": 3,
|
||||
"assign_admin_roles": "",
|
||||
"assgin_admin_usernames": null
|
||||
},
|
||||
{
|
||||
"id": 22,
|
||||
"title": "我的应用",
|
||||
"icon": "fa fa-rocket fa-fw",
|
||||
"href": "page/plugins/mine.html",
|
||||
"target": "_self",
|
||||
"sort_num": 2,
|
||||
"parent_id": 3,
|
||||
"assign_admin_roles": "",
|
||||
"assgin_admin_usernames": null
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
127
public/api/table.json
Normal file
127
public/api/table.json
Normal file
|
@ -0,0 +1,127 @@
|
|||
{
|
||||
"code": 0,
|
||||
"msg": "",
|
||||
"count": 1000,
|
||||
"data": [
|
||||
{
|
||||
"id": 10000,
|
||||
"username": "user-0",
|
||||
"sex": "女",
|
||||
"city": "城市-0",
|
||||
"sign": "签名-0",
|
||||
"experience": 255,
|
||||
"logins": 24,
|
||||
"wealth": 82830700,
|
||||
"classify": "作家",
|
||||
"score": 57
|
||||
},
|
||||
{
|
||||
"id": 10001,
|
||||
"username": "user-1",
|
||||
"sex": "男",
|
||||
"city": "城市-1",
|
||||
"sign": "签名-1",
|
||||
"experience": 884,
|
||||
"logins": 58,
|
||||
"wealth": 64928690,
|
||||
"classify": "词人",
|
||||
"score": 27
|
||||
},
|
||||
{
|
||||
"id": 10002,
|
||||
"username": "user-2",
|
||||
"sex": "女",
|
||||
"city": "城市-2",
|
||||
"sign": "签名-2",
|
||||
"experience": 650,
|
||||
"logins": 77,
|
||||
"wealth": 6298078,
|
||||
"classify": "酱油",
|
||||
"score": 31
|
||||
},
|
||||
{
|
||||
"id": 10003,
|
||||
"username": "user-3",
|
||||
"sex": "女",
|
||||
"city": "城市-3",
|
||||
"sign": "签名-3",
|
||||
"experience": 362,
|
||||
"logins": 157,
|
||||
"wealth": 37117017,
|
||||
"classify": "诗人",
|
||||
"score": 68
|
||||
},
|
||||
{
|
||||
"id": 10004,
|
||||
"username": "user-4",
|
||||
"sex": "男",
|
||||
"city": "城市-4",
|
||||
"sign": "签名-4",
|
||||
"experience": 807,
|
||||
"logins": 51,
|
||||
"wealth": 76263262,
|
||||
"classify": "作家",
|
||||
"score": 6
|
||||
},
|
||||
{
|
||||
"id": 10005,
|
||||
"username": "user-5",
|
||||
"sex": "女",
|
||||
"city": "城市-5",
|
||||
"sign": "签名-5",
|
||||
"experience": 173,
|
||||
"logins": 68,
|
||||
"wealth": 60344147,
|
||||
"classify": "作家",
|
||||
"score": 87
|
||||
},
|
||||
{
|
||||
"id": 10006,
|
||||
"username": "user-6",
|
||||
"sex": "女",
|
||||
"city": "城市-6",
|
||||
"sign": "签名-6",
|
||||
"experience": 982,
|
||||
"logins": 37,
|
||||
"wealth": 57768166,
|
||||
"classify": "作家",
|
||||
"score": 34
|
||||
},
|
||||
{
|
||||
"id": 10007,
|
||||
"username": "user-7",
|
||||
"sex": "男",
|
||||
"city": "城市-7",
|
||||
"sign": "签名-7",
|
||||
"experience": 727,
|
||||
"logins": 150,
|
||||
"wealth": 82030578,
|
||||
"classify": "作家",
|
||||
"score": 28
|
||||
},
|
||||
{
|
||||
"id": 10008,
|
||||
"username": "user-8",
|
||||
"sex": "男",
|
||||
"city": "城市-8",
|
||||
"sign": "签名-8",
|
||||
"experience": 951,
|
||||
"logins": 133,
|
||||
"wealth": 16503371,
|
||||
"classify": "词人",
|
||||
"score": 14
|
||||
},
|
||||
{
|
||||
"id": 10009,
|
||||
"username": "user-9",
|
||||
"sex": "女",
|
||||
"city": "城市-9",
|
||||
"sign": "签名-9",
|
||||
"experience": 484,
|
||||
"logins": 25,
|
||||
"wealth": 86801934,
|
||||
"classify": "词人",
|
||||
"score": 75
|
||||
}
|
||||
]
|
||||
}
|
23
public/api/tableSelect.json
Normal file
23
public/api/tableSelect.json
Normal file
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"code": 0,
|
||||
"msg": "",
|
||||
"count": 16,
|
||||
"data": [
|
||||
{ "id":"001", "username":"张玉林", "sex":"女" },
|
||||
{ "id":"002", "username":"刘晓军", "sex":"男" },
|
||||
{ "id":"003", "username":"张恒", "sex":"男" },
|
||||
{ "id":"004", "username":"朱一", "sex":"男" },
|
||||
{ "id":"005", "username":"刘佳能", "sex":"女" },
|
||||
{ "id":"006", "username":"晓梅", "sex":"女" },
|
||||
{ "id":"007", "username":"马冬梅", "sex":"女" },
|
||||
{ "id":"008", "username":"刘晓庆", "sex":"女" },
|
||||
{ "id":"009", "username":"刘晓庆", "sex":"女" },
|
||||
{ "id":"010", "username":"刘晓庆", "sex":"女" },
|
||||
{ "id":"011", "username":"刘晓庆", "sex":"女" },
|
||||
{ "id":"012", "username":"刘晓庆", "sex":"女" },
|
||||
{ "id":"013", "username":"刘晓庆", "sex":"女" },
|
||||
{ "id":"014", "username":"刘晓庆", "sex":"女" },
|
||||
{ "id":"015", "username":"刘晓庆", "sex":"女" },
|
||||
{ "id":"016", "username":"刘晓庆", "sex":"女" }
|
||||
]
|
||||
}
|
10
public/api/upload.json
Normal file
10
public/api/upload.json
Normal file
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"code": 1,
|
||||
"msg": "上传成功",
|
||||
"data": {
|
||||
"url": [
|
||||
"../images/logo.png",
|
||||
"../images/captcha.jpg"
|
||||
]
|
||||
}
|
||||
}
|
803
public/css/layuimini.css
Normal file
803
public/css/layuimini.css
Normal file
|
@ -0,0 +1,803 @@
|
|||
/**
|
||||
配色方案(如有需要,请自行配置)
|
||||
*/
|
||||
/**头部-配色*/
|
||||
.layui-layout-admin .layui-header {
|
||||
background-color: #1aa094 !important;
|
||||
}
|
||||
|
||||
.layui-header > ul > .layui-nav-item.layui-this, .layuimini-tool i:hover {
|
||||
background-color: #197971 !important;
|
||||
}
|
||||
|
||||
.layui-header .layuimini-header-content > ul > .layui-nav-item.layui-this, .layuimini-tool i:hover {
|
||||
background-color: #197971 !important;
|
||||
}
|
||||
|
||||
/**logo-配色*/
|
||||
.layui-layout-admin .layuimini-logo {
|
||||
background-color: #243346 !important;
|
||||
}
|
||||
|
||||
/**左侧-配色*/
|
||||
.layui-side.layui-bg-black, .layui-side.layui-bg-black > .layuimini-menu-left > ul {
|
||||
background-color: #2f4056 !important;
|
||||
}
|
||||
|
||||
.layuimini-menu-left .layui-nav .layui-nav-child a:hover:not(.layui-this) {
|
||||
background-color: #3b3f4b;
|
||||
}
|
||||
|
||||
/**左侧菜单选中-配色*/
|
||||
.layui-layout-admin .layui-nav-tree .layui-this, .layui-layout-admin .layui-nav-tree .layui-this > a, .layui-layout-admin .layui-nav-tree .layui-nav-child dd.layui-this, .layui-layout-admin .layui-nav-tree .layui-nav-child dd.layui-this a {
|
||||
background-color: #1aa094 !important;
|
||||
}
|
||||
|
||||
|
||||
/**头部样式 */
|
||||
.layui-layout-admin .header {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
.layuimini-header-menu, .layui-header {
|
||||
height: 60px !important;
|
||||
}
|
||||
|
||||
.layuimini-header-menu > .layui-nav-item {
|
||||
color: #1b1d21;
|
||||
height: 60px !important;
|
||||
line-height: 60px !important;
|
||||
}
|
||||
|
||||
.layui-header > .layui-layout-right > .layui-nav-item {
|
||||
height: 60px !important;
|
||||
line-height: 60px !important;
|
||||
}
|
||||
|
||||
.layui-layout-left {
|
||||
left: 295px !important;
|
||||
}
|
||||
|
||||
.layui-nav.layui-layout-left.layuimini-header-menu.layuimini-pc-show {
|
||||
font-weight: bold;
|
||||
transition: all .2s;
|
||||
}
|
||||
|
||||
|
||||
/**logo演示(通用) */
|
||||
.layui-layout-admin .layuimini-logo {
|
||||
font-weight: bold;
|
||||
color: #ffffff !important;
|
||||
height: 60px !important;
|
||||
line-height: 60px !important;
|
||||
overflow: hidden;
|
||||
line-height: 64px;
|
||||
transition: all .2s !important;
|
||||
}
|
||||
|
||||
.layui-layout-admin .layuimini-logo img {
|
||||
display: inline-block;
|
||||
height: 40px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.layui-layout-admin .layuimini-logo h1 {
|
||||
display: inline-block;
|
||||
margin: 0 0 0 12px;
|
||||
color: #ffffff;
|
||||
font-weight: 600;
|
||||
font-size: 20px;
|
||||
font-family: Avenir, Helvetica Neue, Arial, Helvetica, sans-serif;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
/**缩放工具(通用) */
|
||||
.layuimini-tool {
|
||||
position: absolute !important;
|
||||
top: 0;
|
||||
left: 235px;
|
||||
width: 60px;
|
||||
height: 100%;
|
||||
line-height: 60px;
|
||||
text-align: center;
|
||||
color: #ffffff !important;
|
||||
transition: all .2s;
|
||||
}
|
||||
|
||||
/**缩放工具(缩放) */
|
||||
.layuimini-tool i {
|
||||
display: block;
|
||||
color: #bbe3df;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
border-radius: 3px;
|
||||
text-align: center;
|
||||
margin-top: 15px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
|
||||
.layuimini-page-header {
|
||||
overflow: hidden;
|
||||
display: block;
|
||||
height: 35px;
|
||||
line-height: 35px;
|
||||
margin-bottom: 0;
|
||||
border-radius: 0;
|
||||
border-bottom: 1px solid #e1dddd;
|
||||
}
|
||||
|
||||
.layuimini-page-header .layui-breadcrumb {
|
||||
border-top: 1px solid #f6f6f6;
|
||||
padding: 0 15px;
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
|
||||
/**左侧菜单栏 (通用) */
|
||||
.layui-side.layui-bg-black {
|
||||
transition: all .2s;
|
||||
}
|
||||
|
||||
.layui-side.layui-bg-black > .layuimini-menu-left > ul {
|
||||
transition: all .2s;
|
||||
}
|
||||
|
||||
.layui-side.layui-bg-black > .layuimini-menu-left > ul > .layui-nav-item:first-child {
|
||||
border-top: 1px solid #4b5461;
|
||||
}
|
||||
|
||||
.layuimini-menu-left .layui-nav .layui-nav-item a {
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
padding-right: 30px;
|
||||
}
|
||||
|
||||
.layuimini-menu-left .layui-nav .layui-nav-item > a {
|
||||
padding-top: 5px;
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
|
||||
.layuimini-menu-left .layui-nav .layui-nav-child .layui-nav-child {
|
||||
background: 0 0 !important
|
||||
}
|
||||
|
||||
.layuimini-menu-left .layui-nav .layui-nav-more {
|
||||
right: 15px;
|
||||
}
|
||||
|
||||
.layuimini-menu-left .layui-nav .layui-nav-item a:hover {
|
||||
background-color: transparent !important;
|
||||
}
|
||||
|
||||
.layuimini-menu-left .layui-nav {
|
||||
background-color: transparent !important;
|
||||
}
|
||||
|
||||
|
||||
/**左侧菜单栏 (正常) */
|
||||
.layui-layout-body .layui-nav-itemed .layui-nav-child a, .layui-layout-body .layuimini-menu-left .layui-nav .layui-nav-child a {
|
||||
padding-left: 35px;
|
||||
}
|
||||
|
||||
.layui-layout-body .layuimini-menu-left .layui-nav .layui-nav-child .layui-nav-child a {
|
||||
padding-left: 45px;
|
||||
}
|
||||
|
||||
.layui-layout-body .layuimini-menu-left .layui-nav .layui-nav-child .layui-nav-child .layui-nav-child a {
|
||||
padding-left: 55px;
|
||||
}
|
||||
|
||||
.layui-layout-body .layuimini-menu-left .layui-nav .layui-nav-child .layui-nav-child .layui-nav-child .layui-nav-child a {
|
||||
padding-left: 65px;
|
||||
}
|
||||
|
||||
.layui-layout-body .layuimini-menu-left .layui-nav .layui-nav-itemed > .layui-nav-child {
|
||||
padding: 5px 0;
|
||||
}
|
||||
|
||||
/**内容主体(通用) */
|
||||
.layui-layout-admin .layui-body {
|
||||
/*position: fixed;*/
|
||||
overflow: hidden;
|
||||
bottom: 0px !important;
|
||||
top: 60px !important;
|
||||
transition: all .2s;
|
||||
}
|
||||
|
||||
/**选择配色方案 */
|
||||
.layuimini-color .color-title {
|
||||
padding: 10px 0 10px 20px;
|
||||
border-bottom: 1px solid #d9dada;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.layuimini-color .color-content {
|
||||
padding: 10px 5px 0 5px;
|
||||
}
|
||||
|
||||
.layuimini-color .color-content ul {
|
||||
list-style: none;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.layuimini-color .color-content ul li {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
width: 80px;
|
||||
height: 50px;
|
||||
margin: 0 15px 15px 0;
|
||||
padding: 2px 2px 4px 2px;
|
||||
background-color: #f2f2f2;
|
||||
cursor: pointer;
|
||||
font-size: 12px;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.layuimini-color .color-content li.layui-this:after, .layuimini-color .color-content li:hover:after {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 4px;
|
||||
top: -5px;
|
||||
left: -5px;
|
||||
border-color: #d8d8d8;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.layuimini-color .color-content li:after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
z-index: 20;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
width: 1px;
|
||||
height: 0;
|
||||
border: 1px solid #f2f2f2;
|
||||
transition: all .3s;
|
||||
-webkit-transition: all .3s;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
|
||||
/**其它 */
|
||||
.layui-tab-item {
|
||||
width: 100% !important;
|
||||
height: 100% !important;
|
||||
}
|
||||
|
||||
.layui-nav-item.layui-this {
|
||||
background-color: #1b1d21;
|
||||
}
|
||||
|
||||
.layui-width-height {
|
||||
width: 100%;
|
||||
height: 95%;
|
||||
}
|
||||
|
||||
.layui-tab {
|
||||
margin: 0 0 0 0;
|
||||
z-index: 99999;
|
||||
}
|
||||
|
||||
.text-center {
|
||||
height: 30px !important;
|
||||
line-height: 30px !important;
|
||||
text-align: center !important;
|
||||
}
|
||||
|
||||
.layui-nav {
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
.layui-nav .layui-this:after, .layui-nav-bar, .layui-nav-tree .layui-nav-itemed:after {
|
||||
width: 0 !important;
|
||||
height: 0 !important;
|
||||
}
|
||||
|
||||
.layui-layout-admin .layui-side {
|
||||
top: 60px !important;
|
||||
}
|
||||
|
||||
.layui-tab-card {
|
||||
box-shadow: 0px 0px 0px #888888;
|
||||
border-bottom: 0;
|
||||
}
|
||||
|
||||
|
||||
/*打开页面动画*/
|
||||
.layui-tab-item.layui-show {
|
||||
animation: moveTop 1s;
|
||||
-webkit-animation: moveTop 1s;
|
||||
animation-fill-mode: both;
|
||||
-webkit-animation-fill-mode: both;
|
||||
position: relative;
|
||||
height: 100%;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
@keyframes moveTop {
|
||||
0% {
|
||||
opacity: 0;
|
||||
-webkit-transform: translateY(30px);
|
||||
-ms-transform: translateY(30px);
|
||||
transform: translateY(30px);
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
-webkit-transform: translateY(0);
|
||||
-ms-transform: translateY(0);
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
@-o-keyframes moveTop {
|
||||
0% {
|
||||
opacity: 0;
|
||||
-webkit-transform: translateY(30px);
|
||||
-ms-transform: translateY(30px);
|
||||
transform: translateY(30px);
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
-webkit-transform: translateY(0);
|
||||
-ms-transform: translateY(0);
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
@-moz-keyframes moveTop {
|
||||
0% {
|
||||
opacity: 0;
|
||||
-webkit-transform: translateY(30px);
|
||||
-ms-transform: translateY(30px);
|
||||
transform: translateY(30px);
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
-webkit-transform: translateY(0);
|
||||
-ms-transform: translateY(0);
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
@-webkit-keyframes moveTop {
|
||||
0% {
|
||||
opacity: 0;
|
||||
-webkit-transform: translateY(30px);
|
||||
-ms-transform: translateY(30px);
|
||||
transform: translateY(30px);
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
-webkit-transform: translateY(0);
|
||||
-ms-transform: translateY(0);
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
/**自定义滚动条样式 */
|
||||
::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
height: 6px
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-track {
|
||||
background-color: transparent;
|
||||
-webkit-border-radius: 2em;
|
||||
-moz-border-radius: 2em;
|
||||
border-radius: 2em;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background-color: #9c9da0;
|
||||
-webkit-border-radius: 2em;
|
||||
-moz-border-radius: 2em;
|
||||
border-radius: 2em
|
||||
}
|
||||
|
||||
|
||||
.layuimini-content-page {
|
||||
overflow: auto;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
|
||||
/*移动端遮罩层*/
|
||||
.layuimini-make {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
top: 0;
|
||||
z-index: 1000;
|
||||
background: rgba(0, 0, 0, .5);
|
||||
display: none;
|
||||
}
|
||||
|
||||
.layuimini-mini .layui-header {
|
||||
z-index: 1001;
|
||||
}
|
||||
|
||||
/**初始化加载层*/
|
||||
.layuimini-loader {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #ffffff;
|
||||
z-index: 999999;
|
||||
}
|
||||
|
||||
.layuimini-loader .layuimini-loader-inner {
|
||||
display: block;
|
||||
position: relative;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
width: 150px;
|
||||
height: 150px;
|
||||
margin: -75px 0 0 -75px;
|
||||
border-radius: 50%;
|
||||
border: 3px solid transparent;
|
||||
border-top-color: #1E9FFF;
|
||||
animation: spin 2s linear infinite;
|
||||
}
|
||||
|
||||
.layuimini-loader .layuimini-loader-inner:before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 5px;
|
||||
left: 5px;
|
||||
right: 5px;
|
||||
bottom: 5px;
|
||||
border-radius: 50%;
|
||||
border: 3px solid transparent;
|
||||
border-top-color: #1E9FFF;
|
||||
animation: spin 3s linear infinite;
|
||||
}
|
||||
|
||||
.layuimini-loader .layuimini-loader-inner:after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 15px;
|
||||
left: 15px;
|
||||
right: 15px;
|
||||
bottom: 15px;
|
||||
border-radius: 50%;
|
||||
border: 3px solid transparent;
|
||||
border-top-color: #1E9FFF;
|
||||
animation: spin 1.5s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
to {
|
||||
transform: rotate(1turn);
|
||||
}
|
||||
}
|
||||
|
||||
/*系统设置*/
|
||||
|
||||
.layuimini-color .layui-word-aux {
|
||||
position: absolute;
|
||||
left: 60px;
|
||||
top: 12px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.layuimini-color .layui-input-block {
|
||||
margin-left: 15px;
|
||||
min-height: 36px;
|
||||
}
|
||||
|
||||
.layuimini-color .more-menu-list {
|
||||
width: 100%;
|
||||
margin-top: 30px;
|
||||
}
|
||||
|
||||
|
||||
.layuimini-color .more-menu-item:first-child {
|
||||
border-top: 1px solid #e8e8e8;
|
||||
}
|
||||
|
||||
.layuimini-color .more-menu-item .layui-icon {
|
||||
font-size: 18px;
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
.layuimini-color .more-menu-item {
|
||||
color: #595959;
|
||||
height: 50px;
|
||||
line-height: 50px;
|
||||
font-size: 16px;
|
||||
padding: 0 25px;
|
||||
border-bottom: 1px solid #e8e8e8;
|
||||
font-style: normal;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.layuimini-color .more-menu-item:hover {
|
||||
background-color: whitesmoke;
|
||||
}
|
||||
|
||||
.layuimini-color .more-menu-item:after {
|
||||
color: #8c8c8c;
|
||||
right: 16px;
|
||||
content: "\e602";
|
||||
position: absolute;
|
||||
font-family: layui-icon !important;
|
||||
}
|
||||
|
||||
/**
|
||||
菜单缩放
|
||||
*/
|
||||
.popup-tips .layui-layer-TipsG{
|
||||
display: none;
|
||||
}
|
||||
.popup-tips.layui-layer-tips .layui-layer-content{
|
||||
padding: 0;
|
||||
}
|
||||
.popup-tips .layui-nav-tree{
|
||||
width: 150px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
/**左侧菜单字体间距*/
|
||||
.layuimini-menu-left .layui-nav-item a span {
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
|
||||
/**头部菜单字体间距*/
|
||||
.layui-layout-admin .layui-header .layuimini-header-menu.layuimini-pc-show,.layui-layout-admin .layui-header .layuimini-header-menu.layuimini-mobile-show {
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
|
||||
|
||||
/**左侧菜单更多下拉样式*/
|
||||
.layuimini-menu-left .layui-nav-more,.layuimini-menu-left-zoom .layui-nav-more {
|
||||
font-family: layui-icon !important;
|
||||
font-size: 12px;
|
||||
font-style: normal;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
overflow: hidden;
|
||||
width: auto;
|
||||
height: auto;
|
||||
line-height: normal;
|
||||
border: none;
|
||||
display: inline-block;
|
||||
margin-top: -6px !important;
|
||||
}
|
||||
|
||||
.layuimini-menu-left .layui-nav-child .layui-nav-more {
|
||||
margin-top: -6px !important;
|
||||
}
|
||||
|
||||
.layuimini-menu-left .layui-nav .layui-nav-mored,.layuimini-menu-left .layui-nav-itemed>a .layui-nav-more{
|
||||
margin-top: -9px!important;
|
||||
}
|
||||
|
||||
.layuimini-menu-left-zoom.layui-nav .layui-nav-mored,.layuimini-menu-left-zoom.layui-nav-itemed>a .layui-nav-more{
|
||||
margin-top: -9px!important;
|
||||
}
|
||||
|
||||
.layuimini-menu-left .layui-nav-more:before,.layuimini-menu-left-zoom .layui-nav-more:before {
|
||||
content: "\e61a";
|
||||
}
|
||||
.layuimini-menu-left .layui-nav-itemed > a > .layui-nav-more,.layuimini-menu-left-zoom .layui-nav-itemed > a > .layui-nav-more {
|
||||
transform: rotate(180deg);
|
||||
-ms-transform: rotate(180deg);
|
||||
-moz-transform: rotate(180deg);
|
||||
-webkit-transform: rotate(180deg);
|
||||
-o-transform: rotate(180deg);
|
||||
width: 12px;
|
||||
text-align: center;
|
||||
border-style:none;
|
||||
}
|
||||
|
||||
.layuimini-menu-left .layui-nav-itemed > a > .layui-nav-more:before,.layuimini-menu-left-zoom .layui-nav-itemed > a > .layui-nav-more:before {
|
||||
content: '\e61a';
|
||||
background-color: transparent;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
/**修复左侧菜单字体不对齐的问题*/
|
||||
.layuimini-menu-left .layui-nav-item a .fa,.layuimini-menu-left .layui-nav-item a .layui-icon{
|
||||
width: 20px;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
PC版样式
|
||||
*/
|
||||
@media screen and (min-width: 1025px) {
|
||||
/**头部样式(缩放) */
|
||||
.layuimini-mini .layui-layout-left.layuimini-header-menu.layuimini-pc-show {
|
||||
left: 155px !important;
|
||||
}
|
||||
|
||||
/**logo演示(缩放) */
|
||||
.layuimini-mini .layui-layout-admin .layuimini-logo {
|
||||
width: 60px !important;
|
||||
}
|
||||
|
||||
.layuimini-mini .layui-layout-admin .layuimini-logo h1 {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/**左侧菜单栏(缩放) */
|
||||
.layuimini-mini .layuimini-menu-left {
|
||||
width: 80px !important;
|
||||
}
|
||||
|
||||
.layuimini-mini .layui-side.layui-bg-black, .layuimini-mini .layuimini-menu-left > ul, .layuimini-mini .layuimini-menu-left > ul li i {
|
||||
width: 60px !important;
|
||||
}
|
||||
|
||||
.layuimini-mini .layuimini-menu-left > ul li span:first-child {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.layuimini-mini .layuimini-menu-left > ul li span:last-child {
|
||||
float: right;
|
||||
right: 7px;
|
||||
}
|
||||
|
||||
.layuimini-mini .layuimini-menu-left .layui-nav .layui-nav-item a {
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
padding-right: 0px !important;
|
||||
}
|
||||
|
||||
/**内容主体(缩放) */
|
||||
.layuimini-mini .layui-layout-admin .layui-body {
|
||||
left: 60px !important;
|
||||
}
|
||||
|
||||
.layuimini-mini .layuimini-tool {
|
||||
left: 95px !important;
|
||||
}
|
||||
|
||||
.layuimini-pc-show{
|
||||
display: block;
|
||||
}
|
||||
.layuimini-mobile-show{
|
||||
display: none;
|
||||
}
|
||||
|
||||
/**菜单缩放*/
|
||||
.layuimini-mini .layuimini-menu-left .layui-nav-more,.layuimini-mini .layuimini-menu-left .layui-nav-child{
|
||||
display: none!important;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
手机自适应样式
|
||||
*/
|
||||
@media screen and (max-width: 1024px) {
|
||||
|
||||
.layuimini-pc-show{
|
||||
display: none;
|
||||
}
|
||||
.layuimini-mobile-show{
|
||||
display: block;
|
||||
}
|
||||
|
||||
.layuimini-header-content {
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.layui-layout-admin .layui-body .layui-tab-item.layui-show {
|
||||
border-top: 1px solid #e2e2e2;
|
||||
}
|
||||
|
||||
.layuimini-all .layui-layout-left.layuimini-header-menu {
|
||||
left: 15px !important
|
||||
}
|
||||
|
||||
.layuimini-mini .layui-layout-left.layuimini-header-menu {
|
||||
left: 205px !important
|
||||
}
|
||||
|
||||
.layui-layout-admin .layui-nav.layui-layout-right > li:not(.layuimini-setting) {
|
||||
width: 40px !important;
|
||||
}
|
||||
|
||||
.layui-layout-admin .layui-nav.layui-layout-right > li:not(.layuimini-setting) a {
|
||||
padding: 0 15px;
|
||||
}
|
||||
|
||||
.layuimini-all .layui-layout-admin .layui-body {
|
||||
left: 0px !important;
|
||||
}
|
||||
|
||||
.layuimini-mini .layui-layout-admin .layuimini-menu-left, .layuimini-mini .layui-header .layuimini-logo {
|
||||
left: 0;
|
||||
transition: left .2s;
|
||||
z-index: 1001 !important;
|
||||
}
|
||||
|
||||
.layuimini-all .layui-layout-admin .layuimini-menu-left, .layuimini-all .layui-header .layuimini-logo {
|
||||
left: -200px;
|
||||
transition: left .2s;
|
||||
top: 0;
|
||||
z-index: 1002;
|
||||
}
|
||||
|
||||
.layuimini-mini .layui-layout-admin .layui-body {
|
||||
left: 0!important;
|
||||
transition: left .2s;
|
||||
top: 0;
|
||||
z-index: 998;
|
||||
}
|
||||
|
||||
.layuimini-mini .layuimini-make {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.layuimini-multi-module .layuimini-header-content .layuimini-tool {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.layuimini-single-module .layuimini-header-content .layuimini-tool {
|
||||
left: 15px;
|
||||
}
|
||||
|
||||
.layuimini-mini .layuimini-site-mobile {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.layuimini-site-mobile {
|
||||
display: block !important;
|
||||
position: fixed;
|
||||
z-index: 100000;
|
||||
bottom: 15px;
|
||||
left: 15px;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
border-radius: 2px;
|
||||
text-align: center;
|
||||
background-color: rgba(0, 0, 0, .7);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.layuimini-header-content {
|
||||
z-index: 997;
|
||||
}
|
||||
|
||||
.layuimini-content-page {
|
||||
-webkit-overflow-scrolling: touch;
|
||||
}
|
||||
|
||||
/*修复UC之类的浏览器点击无效*/
|
||||
.layuimini-make {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.layuimini-site-mobile {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@media screen and (max-width: 550px){
|
||||
|
||||
/**头部右侧数据*/
|
||||
.layuimini-multi-module.layuimini-mini .layuimini-header-content .layui-layout-right {
|
||||
display: none;
|
||||
}
|
||||
}
|
13
public/css/public.css
Normal file
13
public/css/public.css
Normal file
|
@ -0,0 +1,13 @@
|
|||
.layuimini-content-page{background-color:#f2f2f2!important;}
|
||||
.layuimini-container {border:1px solid #f2f2f2;border-radius:5px;background-color:#f2f2f2}
|
||||
.layuimini-main {margin:10px 10px 10px 10px;border:5px solid #ffffff;border-radius:5px;background-color:#ffffff}
|
||||
.layui-breadcrumb>* {font-size: 13px;!important;}
|
||||
|
||||
/**必填红点 */
|
||||
.layuimini-form>.layui-form-item>.required:after {content:'*';color:red;position:absolute;margin-left:4px;font-weight:bold;line-height:1.8em;top:6px;right:5px;}
|
||||
.layuimini-form>.layui-form-item>.layui-form-label {width:120px !important;}
|
||||
.layuimini-form>.layui-form-item>.layui-input-block {margin-left:150px !important;}
|
||||
.layuimini-form>.layui-form-item>.layui-input-block >tip {display:inline-block;margin-top:10px;line-height:10px;font-size:10px;color:#a29c9c;}
|
||||
|
||||
/**搜索框*/
|
||||
.layuimini-container .table-search-fieldset {margin: 0;border: 1px solid #e6e6e6;padding: 10px 20px 5px 20px;color: #6b6b6b;}
|
95
public/css/themes/default.css
Normal file
95
public/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;
|
||||
}
|
BIN
public/favicon.ico
Normal file
BIN
public/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.2 KiB |
BIN
public/images/captcha.jpg
Normal file
BIN
public/images/captcha.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.4 KiB |
BIN
public/images/home.png
Normal file
BIN
public/images/home.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 157 KiB |
BIN
public/images/icon-login.png
Normal file
BIN
public/images/icon-login.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.7 KiB |
BIN
public/images/logo.png
Normal file
BIN
public/images/logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 22 KiB |
179
public/index.html
Normal file
179
public/index.html
Normal file
|
@ -0,0 +1,179 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>IYUUAutoReseed PLUS</title>
|
||||
<meta name="keywords" content="layuimini,layui,layui模板,layui后台,后台模板,admin,admin模板,layui mini">
|
||||
<meta name="description" content="layuimini基于layui的轻量级前端后台管理框架,最简洁、易用的后台框架模板,面向所有层次的前后端程序,只需提供一个接口就直接初始化整个框架,无需复杂操作。">
|
||||
<meta name="renderer" content="webkit">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||
<meta http-equiv="Access-Control-Allow-Origin" content="*">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black">
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<meta name="format-detection" content="telephone=no">
|
||||
<link rel="icon" href="/favicon.ico">
|
||||
<link rel="stylesheet" href="lib/layui-v2.5.7/css/layui.css" media="all">
|
||||
<link rel="stylesheet" href="lib/font-awesome-4.7.0/css/font-awesome.min.css" media="all">
|
||||
<link rel="stylesheet" href="css/layuimini.css?v=2.0.1" media="all">
|
||||
<link rel="stylesheet" href="css/themes/default.css" media="all">
|
||||
<link rel="stylesheet" href="css/public.css" media="all">
|
||||
<!--[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>
|
||||
<![endif]-->
|
||||
<style id="layuimini-bg-color">
|
||||
</style>
|
||||
</head>
|
||||
<body class="layui-layout-body layuimini-all">
|
||||
<div class="layui-layout layui-layout-admin">
|
||||
|
||||
<div class="layui-header header">
|
||||
<div class="layui-logo layuimini-logo layuimini-back-home"></div>
|
||||
|
||||
<div class="layuimini-header-content">
|
||||
<a>
|
||||
<div class="layuimini-tool"><i title="展开" class="fa fa-outdent" data-side-fold="1"></i></div>
|
||||
</a>
|
||||
|
||||
<!--电脑端头部菜单-->
|
||||
<ul class="layui-nav layui-layout-left layuimini-header-menu layuimini-menu-header-pc layuimini-pc-show">
|
||||
</ul>
|
||||
|
||||
<!--手机端头部菜单-->
|
||||
<ul class="layui-nav layui-layout-left layuimini-header-menu layuimini-mobile-show">
|
||||
<li class="layui-nav-item">
|
||||
<a href="javascript:;"><i class="fa fa-list-ul"></i> 选择模块</a>
|
||||
<dl class="layui-nav-child layuimini-menu-header-mobile">
|
||||
</dl>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<ul class="layui-nav layui-layout-right">
|
||||
|
||||
<li class="layui-nav-item" lay-unselect>
|
||||
<a href="javascript:;" data-refresh="刷新"><i class="fa fa-refresh"></i></a>
|
||||
</li>
|
||||
<li class="layui-nav-item" lay-unselect>
|
||||
<a href="javascript:;" data-clear="清理" class="layuimini-clear"><i class="fa fa-trash-o"></i></a>
|
||||
</li>
|
||||
<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 layuimini-setting">
|
||||
<a href="javascript:;">admin</a>
|
||||
<dl class="layui-nav-child">
|
||||
<dd>
|
||||
<a href="javascript:;" layuimini-content-href="page/user-setting.html" data-title="基本资料" data-icon="fa fa-gears">基本资料<span class="layui-badge-dot"></span></a>
|
||||
</dd>
|
||||
<dd>
|
||||
<a href="javascript:;" layuimini-content-href="page/user-password.html" data-title="修改密码" data-icon="fa fa-gears">修改密码</a>
|
||||
</dd>
|
||||
<dd>
|
||||
<hr>
|
||||
</dd>
|
||||
<dd>
|
||||
<a href="javascript:;" class="login-out">退出登录</a>
|
||||
</dd>
|
||||
</dl>
|
||||
</li>
|
||||
<li class="layui-nav-item layuimini-select-bgcolor" lay-unselect>
|
||||
<a href="javascript:;" data-bgcolor="配色方案"><i class="fa fa-ellipsis-v"></i></a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!--无限极左侧菜单-->
|
||||
<div class="layui-side layui-bg-black layuimini-menu-left">
|
||||
</div>
|
||||
|
||||
<!--初始化加载层-->
|
||||
<div class="layuimini-loader">
|
||||
<div class="layuimini-loader-inner"></div>
|
||||
</div>
|
||||
|
||||
<!--手机端遮罩层-->
|
||||
<div class="layuimini-make"></div>
|
||||
|
||||
<!-- 移动导航 -->
|
||||
<div class="layuimini-site-mobile"><i class="layui-icon"></i></div>
|
||||
|
||||
<div class="layui-body">
|
||||
|
||||
<div class="layui-card layuimini-page-header layui-hide">
|
||||
<div class="layui-breadcrumb layuimini-page-title">
|
||||
<a lay-href="" href="/">主页</a><span lay-separator="">/</span>
|
||||
<a><cite>常规管理</cite></a><span lay-separator="">/</span>
|
||||
<a><cite>系统设置</cite></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layuimini-content-page">
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- 模板:表格行工具条 -->
|
||||
<script type="text/html" id="tableRowToolbar">
|
||||
<button class="layui-btn layui-btn-xs" lay-event="edit">编辑</button>
|
||||
<button class="layui-btn layui-btn-xs layui-btn-danger" lay-event="delete">删除</button>
|
||||
</script>
|
||||
<script src="lib/layui-v2.5.7/layui.js" charset="utf-8"></script>
|
||||
<script src="js/lay-config.js?v=2.0.0" charset="utf-8"></script>
|
||||
<script src="js/function.js?v=2.0.0" charset="utf-8"></script>
|
||||
<script>
|
||||
layui.use(['jquery', 'layer', 'miniAdmin', 'miniTongji'], function () {
|
||||
let $ = layui.jquery,
|
||||
layer = layui.layer,
|
||||
miniAdmin = layui.miniAdmin,
|
||||
miniTongji = layui.miniTongji;
|
||||
|
||||
let options = {
|
||||
iniUrl: "/Api/Menu", // 初始化接口
|
||||
clearUrl: "/Api/Clear", // 缓存清理接口
|
||||
renderPageVersion: true, // 初始化页面是否加版本号
|
||||
bgColorDefault: false, // 主题默认配置
|
||||
multiModule: true, // 是否开启多模块
|
||||
menuChildOpen: false, // 是否默认展开菜单
|
||||
loadingTime: 0, // 初始化加载时间
|
||||
pageAnim: true, // 切换菜单动画
|
||||
};
|
||||
miniAdmin.render(options);
|
||||
|
||||
// 统计代码,只统计指定域名
|
||||
miniTongji.render({
|
||||
specific: true,
|
||||
domains: [
|
||||
'iyuu.cn',
|
||||
'www.iyuu.cn',
|
||||
'wenda.iyuu.cn',
|
||||
],
|
||||
});
|
||||
|
||||
//退出登录
|
||||
$('.login-out').on("click", function () {
|
||||
$.getJSON('/Api/Logout', function (data) {
|
||||
layer.msg('退出登录成功', function () {
|
||||
window.location = '/page/login.html';
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
//登录检测
|
||||
$.ajax({
|
||||
url: '/Api/checkLogin',
|
||||
type:'get',
|
||||
success:function(data){
|
||||
if (data.ret !== 200 || data.data.is_login !== true) {
|
||||
layer.msg('您暂未登录,正在前往登录入口……', function () {
|
||||
window.location = '/page/login.html';
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
60
public/js/function.js
Normal file
60
public/js/function.js
Normal file
|
@ -0,0 +1,60 @@
|
|||
/**
|
||||
* 根据ID获取DOM元素对象
|
||||
* @param {string} id
|
||||
*/
|
||||
function getById(id) {
|
||||
return document.getElementById(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化Layui输入框数组
|
||||
* @description 适用于input 、checkbox 、 switch
|
||||
* @param {string} field 待格式化的字段
|
||||
* @param {object} obj 数据对象
|
||||
*/
|
||||
function format_input(field, obj) {
|
||||
for (let key in obj[field]) {
|
||||
let k = field +'['+ key +']';
|
||||
obj[k] = obj[field][key];
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* 包装的Ajax请求
|
||||
* @param {string} url URL
|
||||
* @param {object} fd 表单数据
|
||||
* @param {string} msg 成功后提示消息
|
||||
* @param {boolean} reload 成功后是否刷新窗口
|
||||
*/
|
||||
function ajax(url, fd, msg, reload) {
|
||||
let $ = layui.jquery;
|
||||
$.ajax({
|
||||
url: url,
|
||||
type: "POST",
|
||||
data: fd,
|
||||
success: function (d) {
|
||||
console.log(d);
|
||||
if (d.ret === 200) {
|
||||
layer.msg(msg, function () {
|
||||
if(reload) {
|
||||
window.location.reload();
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
if (d.msg.length > 0) {
|
||||
layer.alert(d.msg, {icon: 2, title: '出错提示'});
|
||||
} else {
|
||||
layer.alert('未知错误,请截图当前界面,然后求助于QQ群:859882209、931954050、924099912!', {icon: 2, title: '出错提示'});
|
||||
}
|
||||
}
|
||||
},
|
||||
complete: function () {
|
||||
},
|
||||
error : function(request) {
|
||||
layer.alert('未知错误,请截图当前界面,然后求助于QQ群:859882209、931954050、924099912!', {icon: 2, title: '出错提示'});
|
||||
}
|
||||
});
|
||||
}
|
29
public/js/lay-config.js
Normal file
29
public/js/lay-config.js
Normal file
|
@ -0,0 +1,29 @@
|
|||
/**
|
||||
* date:2019/08/16
|
||||
* author:Mr.Chung
|
||||
* description:此处放layui自定义扩展
|
||||
*/
|
||||
|
||||
window.rootPath = (function (src) {
|
||||
src = document.scripts[document.scripts.length - 1].src;
|
||||
return src.substring(0, src.lastIndexOf("/") + 1);
|
||||
})();
|
||||
|
||||
layui.config({
|
||||
base: rootPath + "lay-module/",
|
||||
version: true
|
||||
}).extend({
|
||||
miniAdmin: "layuimini/miniAdmin", // layuimini后台扩展
|
||||
miniMenu: "layuimini/miniMenu", // layuimini菜单扩展
|
||||
miniPage: "layuimini/miniPage", // layuimini 单页扩展
|
||||
miniTheme: "layuimini/miniTheme", // layuimini 主题扩展
|
||||
miniTongji: "layuimini/miniTongji", // layuimini 统计扩展
|
||||
step: 'step-lay/step', // 分步表单扩展
|
||||
treetable: 'treetable-lay/treetable', //table树形扩展
|
||||
tableSelect: 'tableSelect/tableSelect', // table选择扩展
|
||||
iconPickerFa: 'iconPicker/iconPickerFa', // fa图标选择扩展
|
||||
echarts: 'echarts/echarts', // echarts图表扩展
|
||||
echartsTheme: 'echarts/echartsTheme', // echarts图表主题扩展
|
||||
wangEditor: 'wangEditor/wangEditor', // wangEditor富文本扩展
|
||||
layarea: 'layarea/layarea', // 省市县区三级联动下拉选择器
|
||||
});
|
19
public/js/lay-module/echarts/echarts.js
Normal file
19
public/js/lay-module/echarts/echarts.js
Normal file
File diff suppressed because one or more lines are too long
492
public/js/lay-module/echarts/echartsTheme.js
Normal file
492
public/js/lay-module/echarts/echartsTheme.js
Normal file
|
@ -0,0 +1,492 @@
|
|||
layui.define(function(exports) {
|
||||
exports('echartsTheme',
|
||||
{
|
||||
"color": [
|
||||
"#3fb1e3",
|
||||
"#6be6c1",
|
||||
"#626c91",
|
||||
"#a0a7e6",
|
||||
"#c4ebad",
|
||||
"#96dee8"
|
||||
],
|
||||
"backgroundColor": "rgba(252,252,252,0)",
|
||||
"textStyle": {},
|
||||
"title": {
|
||||
"textStyle": {
|
||||
"color": "#666666"
|
||||
},
|
||||
"subtextStyle": {
|
||||
"color": "#999999"
|
||||
}
|
||||
},
|
||||
"line": {
|
||||
"itemStyle": {
|
||||
"normal": {
|
||||
"borderWidth": "3"
|
||||
}
|
||||
},
|
||||
"lineStyle": {
|
||||
"normal": {
|
||||
"width": "4"
|
||||
}
|
||||
},
|
||||
"symbolSize": "10",
|
||||
"symbol": "emptyCircle",
|
||||
"smooth": true
|
||||
},
|
||||
"radar": {
|
||||
"itemStyle": {
|
||||
"normal": {
|
||||
"borderWidth": "3"
|
||||
}
|
||||
},
|
||||
"lineStyle": {
|
||||
"normal": {
|
||||
"width": "4"
|
||||
}
|
||||
},
|
||||
"symbolSize": "10",
|
||||
"symbol": "emptyCircle",
|
||||
"smooth": true
|
||||
},
|
||||
"bar": {
|
||||
"itemStyle": {
|
||||
"normal": {
|
||||
"barBorderWidth": 0,
|
||||
"barBorderColor": "#ccc"
|
||||
},
|
||||
"emphasis": {
|
||||
"barBorderWidth": 0,
|
||||
"barBorderColor": "#ccc"
|
||||
}
|
||||
}
|
||||
},
|
||||
"pie": {
|
||||
"itemStyle": {
|
||||
"normal": {
|
||||
"borderWidth": 0,
|
||||
"borderColor": "#ccc"
|
||||
},
|
||||
"emphasis": {
|
||||
"borderWidth": 0,
|
||||
"borderColor": "#ccc"
|
||||
}
|
||||
}
|
||||
},
|
||||
"scatter": {
|
||||
"itemStyle": {
|
||||
"normal": {
|
||||
"borderWidth": 0,
|
||||
"borderColor": "#ccc"
|
||||
},
|
||||
"emphasis": {
|
||||
"borderWidth": 0,
|
||||
"borderColor": "#ccc"
|
||||
}
|
||||
}
|
||||
},
|
||||
"boxplot": {
|
||||
"itemStyle": {
|
||||
"normal": {
|
||||
"borderWidth": 0,
|
||||
"borderColor": "#ccc"
|
||||
},
|
||||
"emphasis": {
|
||||
"borderWidth": 0,
|
||||
"borderColor": "#ccc"
|
||||
}
|
||||
}
|
||||
},
|
||||
"parallel": {
|
||||
"itemStyle": {
|
||||
"normal": {
|
||||
"borderWidth": 0,
|
||||
"borderColor": "#ccc"
|
||||
},
|
||||
"emphasis": {
|
||||
"borderWidth": 0,
|
||||
"borderColor": "#ccc"
|
||||
}
|
||||
}
|
||||
},
|
||||
"sankey": {
|
||||
"itemStyle": {
|
||||
"normal": {
|
||||
"borderWidth": 0,
|
||||
"borderColor": "#ccc"
|
||||
},
|
||||
"emphasis": {
|
||||
"borderWidth": 0,
|
||||
"borderColor": "#ccc"
|
||||
}
|
||||
}
|
||||
},
|
||||
"funnel": {
|
||||
"itemStyle": {
|
||||
"normal": {
|
||||
"borderWidth": 0,
|
||||
"borderColor": "#ccc"
|
||||
},
|
||||
"emphasis": {
|
||||
"borderWidth": 0,
|
||||
"borderColor": "#ccc"
|
||||
}
|
||||
}
|
||||
},
|
||||
"gauge": {
|
||||
"itemStyle": {
|
||||
"normal": {
|
||||
"borderWidth": 0,
|
||||
"borderColor": "#ccc"
|
||||
},
|
||||
"emphasis": {
|
||||
"borderWidth": 0,
|
||||
"borderColor": "#ccc"
|
||||
}
|
||||
}
|
||||
},
|
||||
"candlestick": {
|
||||
"itemStyle": {
|
||||
"normal": {
|
||||
"color": "#e6a0d2",
|
||||
"color0": "transparent",
|
||||
"borderColor": "#e6a0d2",
|
||||
"borderColor0": "#3fb1e3",
|
||||
"borderWidth": "2"
|
||||
}
|
||||
}
|
||||
},
|
||||
"graph": {
|
||||
"itemStyle": {
|
||||
"normal": {
|
||||
"borderWidth": 0,
|
||||
"borderColor": "#ccc"
|
||||
}
|
||||
},
|
||||
"lineStyle": {
|
||||
"normal": {
|
||||
"width": "1",
|
||||
"color": "#cccccc"
|
||||
}
|
||||
},
|
||||
"symbolSize": "10",
|
||||
"symbol": "emptyCircle",
|
||||
"smooth": true,
|
||||
"color": [
|
||||
"#3fb1e3",
|
||||
"#6be6c1",
|
||||
"#626c91",
|
||||
"#a0a7e6",
|
||||
"#c4ebad",
|
||||
"#96dee8"
|
||||
],
|
||||
"label": {
|
||||
"normal": {
|
||||
"textStyle": {
|
||||
"color": "#ffffff"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"map": {
|
||||
"itemStyle": {
|
||||
"normal": {
|
||||
"areaColor": "#eeeeee",
|
||||
"borderColor": "#aaaaaa",
|
||||
"borderWidth": 0.5
|
||||
},
|
||||
"emphasis": {
|
||||
"areaColor": "rgba(63,177,227,0.25)",
|
||||
"borderColor": "#3fb1e3",
|
||||
"borderWidth": 1
|
||||
}
|
||||
},
|
||||
"label": {
|
||||
"normal": {
|
||||
"textStyle": {
|
||||
"color": "#ffffff"
|
||||
}
|
||||
},
|
||||
"emphasis": {
|
||||
"textStyle": {
|
||||
"color": "rgb(63,177,227)"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"geo": {
|
||||
"itemStyle": {
|
||||
"normal": {
|
||||
"areaColor": "#eeeeee",
|
||||
"borderColor": "#aaaaaa",
|
||||
"borderWidth": 0.5
|
||||
},
|
||||
"emphasis": {
|
||||
"areaColor": "rgba(63,177,227,0.25)",
|
||||
"borderColor": "#3fb1e3",
|
||||
"borderWidth": 1
|
||||
}
|
||||
},
|
||||
"label": {
|
||||
"normal": {
|
||||
"textStyle": {
|
||||
"color": "#ffffff"
|
||||
}
|
||||
},
|
||||
"emphasis": {
|
||||
"textStyle": {
|
||||
"color": "rgb(63,177,227)"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"categoryAxis": {
|
||||
"axisLine": {
|
||||
"show": true,
|
||||
"lineStyle": {
|
||||
"color": "#cccccc"
|
||||
}
|
||||
},
|
||||
"axisTick": {
|
||||
"show": false,
|
||||
"lineStyle": {
|
||||
"color": "#333"
|
||||
}
|
||||
},
|
||||
"axisLabel": {
|
||||
"show": true,
|
||||
"textStyle": {
|
||||
"color": "#999999"
|
||||
}
|
||||
},
|
||||
"splitLine": {
|
||||
"show": true,
|
||||
"lineStyle": {
|
||||
"color": [
|
||||
"#eeeeee"
|
||||
]
|
||||
}
|
||||
},
|
||||
"splitArea": {
|
||||
"show": false,
|
||||
"areaStyle": {
|
||||
"color": [
|
||||
"rgba(250,250,250,0.05)",
|
||||
"rgba(200,200,200,0.02)"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"valueAxis": {
|
||||
"axisLine": {
|
||||
"show": true,
|
||||
"lineStyle": {
|
||||
"color": "#cccccc"
|
||||
}
|
||||
},
|
||||
"axisTick": {
|
||||
"show": false,
|
||||
"lineStyle": {
|
||||
"color": "#333"
|
||||
}
|
||||
},
|
||||
"axisLabel": {
|
||||
"show": true,
|
||||
"textStyle": {
|
||||
"color": "#999999"
|
||||
}
|
||||
},
|
||||
"splitLine": {
|
||||
"show": true,
|
||||
"lineStyle": {
|
||||
"color": [
|
||||
"#eeeeee"
|
||||
]
|
||||
}
|
||||
},
|
||||
"splitArea": {
|
||||
"show": false,
|
||||
"areaStyle": {
|
||||
"color": [
|
||||
"rgba(250,250,250,0.05)",
|
||||
"rgba(200,200,200,0.02)"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"logAxis": {
|
||||
"axisLine": {
|
||||
"show": true,
|
||||
"lineStyle": {
|
||||
"color": "#cccccc"
|
||||
}
|
||||
},
|
||||
"axisTick": {
|
||||
"show": false,
|
||||
"lineStyle": {
|
||||
"color": "#333"
|
||||
}
|
||||
},
|
||||
"axisLabel": {
|
||||
"show": true,
|
||||
"textStyle": {
|
||||
"color": "#999999"
|
||||
}
|
||||
},
|
||||
"splitLine": {
|
||||
"show": true,
|
||||
"lineStyle": {
|
||||
"color": [
|
||||
"#eeeeee"
|
||||
]
|
||||
}
|
||||
},
|
||||
"splitArea": {
|
||||
"show": false,
|
||||
"areaStyle": {
|
||||
"color": [
|
||||
"rgba(250,250,250,0.05)",
|
||||
"rgba(200,200,200,0.02)"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"timeAxis": {
|
||||
"axisLine": {
|
||||
"show": true,
|
||||
"lineStyle": {
|
||||
"color": "#cccccc"
|
||||
}
|
||||
},
|
||||
"axisTick": {
|
||||
"show": false,
|
||||
"lineStyle": {
|
||||
"color": "#333"
|
||||
}
|
||||
},
|
||||
"axisLabel": {
|
||||
"show": true,
|
||||
"textStyle": {
|
||||
"color": "#999999"
|
||||
}
|
||||
},
|
||||
"splitLine": {
|
||||
"show": true,
|
||||
"lineStyle": {
|
||||
"color": [
|
||||
"#eeeeee"
|
||||
]
|
||||
}
|
||||
},
|
||||
"splitArea": {
|
||||
"show": false,
|
||||
"areaStyle": {
|
||||
"color": [
|
||||
"rgba(250,250,250,0.05)",
|
||||
"rgba(200,200,200,0.02)"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"toolbox": {
|
||||
"iconStyle": {
|
||||
"normal": {
|
||||
"borderColor": "#999999"
|
||||
},
|
||||
"emphasis": {
|
||||
"borderColor": "#666666"
|
||||
}
|
||||
}
|
||||
},
|
||||
"legend": {
|
||||
"textStyle": {
|
||||
"color": "#999999"
|
||||
}
|
||||
},
|
||||
"tooltip": {
|
||||
"axisPointer": {
|
||||
"lineStyle": {
|
||||
"color": "#cccccc",
|
||||
"width": 1
|
||||
},
|
||||
"crossStyle": {
|
||||
"color": "#cccccc",
|
||||
"width": 1
|
||||
}
|
||||
}
|
||||
},
|
||||
"timeline": {
|
||||
"lineStyle": {
|
||||
"color": "#626c91",
|
||||
"width": 1
|
||||
},
|
||||
"itemStyle": {
|
||||
"normal": {
|
||||
"color": "#626c91",
|
||||
"borderWidth": 1
|
||||
},
|
||||
"emphasis": {
|
||||
"color": "#626c91"
|
||||
}
|
||||
},
|
||||
"controlStyle": {
|
||||
"normal": {
|
||||
"color": "#626c91",
|
||||
"borderColor": "#626c91",
|
||||
"borderWidth": 0.5
|
||||
},
|
||||
"emphasis": {
|
||||
"color": "#626c91",
|
||||
"borderColor": "#626c91",
|
||||
"borderWidth": 0.5
|
||||
}
|
||||
},
|
||||
"checkpointStyle": {
|
||||
"color": "#3fb1e3",
|
||||
"borderColor": "rgba(63,177,227,0.15)"
|
||||
},
|
||||
"label": {
|
||||
"normal": {
|
||||
"textStyle": {
|
||||
"color": "#626c91"
|
||||
}
|
||||
},
|
||||
"emphasis": {
|
||||
"textStyle": {
|
||||
"color": "#626c91"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"visualMap": {
|
||||
"color": [
|
||||
"#2a99c9",
|
||||
"#afe8ff"
|
||||
]
|
||||
},
|
||||
"dataZoom": {
|
||||
"backgroundColor": "rgba(255,255,255,0)",
|
||||
"dataBackgroundColor": "rgba(222,222,222,1)",
|
||||
"fillerColor": "rgba(114,230,212,0.25)",
|
||||
"handleColor": "#cccccc",
|
||||
"handleSize": "100%",
|
||||
"textStyle": {
|
||||
"color": "#999999"
|
||||
}
|
||||
},
|
||||
"markPoint": {
|
||||
"label": {
|
||||
"normal": {
|
||||
"textStyle": {
|
||||
"color": "#ffffff"
|
||||
}
|
||||
},
|
||||
"emphasis": {
|
||||
"textStyle": {
|
||||
"color": "#ffffff"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
399
public/js/lay-module/iconPicker/iconPickerFa.js
Normal file
399
public/js/lay-module/iconPicker/iconPickerFa.js
Normal file
|
@ -0,0 +1,399 @@
|
|||
/**
|
||||
* fa图标选择器 根据开源项目https://gitee.com/wujiawei0926/iconpicker修改而来
|
||||
* @author wujiawei0926@yeah.net chung@99php.cn
|
||||
* @version 1.1
|
||||
*/
|
||||
|
||||
layui.define(['laypage', 'form'], function (exports) {
|
||||
"use strict";
|
||||
|
||||
var IconPicker = function () {
|
||||
this.v = '1.1';
|
||||
}, _MOD = 'iconPickerFa',
|
||||
_this = this,
|
||||
$ = layui.jquery,
|
||||
laypage = layui.laypage,
|
||||
form = layui.form,
|
||||
BODY = 'body',
|
||||
TIPS = '请选择图标';
|
||||
|
||||
/**
|
||||
* 渲染组件
|
||||
*/
|
||||
IconPicker.prototype.render = function (options) {
|
||||
var opts = options,
|
||||
// DOM选择器
|
||||
elem = opts.elem,
|
||||
// 数据类型:fontClass/unicode
|
||||
url = opts.url,
|
||||
// 是否分页:true/false
|
||||
page = opts.page == null ? true : opts.page,
|
||||
// 每页显示数量
|
||||
limit = opts.limit == null ? 12 : opts.limit,
|
||||
// 是否开启搜索:true/false
|
||||
search = opts.search == null ? true : opts.search,
|
||||
// 每个图标格子的宽度:'43px'或'20%'
|
||||
cellWidth = opts.cellWidth,
|
||||
// 点击回调
|
||||
click = opts.click,
|
||||
// 渲染成功后的回调
|
||||
success = opts.success,
|
||||
// json数据
|
||||
data = {},
|
||||
// 唯一标识
|
||||
tmp = new Date().getTime(),
|
||||
// 初始化时input的值
|
||||
ORIGINAL_ELEM_VALUE = $(elem).val(),
|
||||
TITLE = 'layui-select-title',
|
||||
TITLE_ID = 'layui-select-title-' + tmp,
|
||||
ICON_BODY = 'layui-iconpicker-' + tmp,
|
||||
PICKER_BODY = 'layui-iconpicker-body-' + tmp,
|
||||
PAGE_ID = 'layui-iconpicker-page-' + tmp,
|
||||
LIST_BOX = 'layui-iconpicker-list-box',
|
||||
selected = 'layui-form-selected',
|
||||
unselect = 'layui-unselect';
|
||||
|
||||
var a = {
|
||||
init: function () {
|
||||
data = common.getData(url);
|
||||
|
||||
a.hideElem().createSelect().createBody().toggleSelect();
|
||||
a.preventEvent().inputListen();
|
||||
common.loadCss();
|
||||
|
||||
if (success) {
|
||||
success(this.successHandle());
|
||||
}
|
||||
|
||||
return a;
|
||||
},
|
||||
successHandle: function () {
|
||||
var d = {
|
||||
options: opts,
|
||||
data: data,
|
||||
id: tmp,
|
||||
elem: $('#' + ICON_BODY)
|
||||
};
|
||||
return d;
|
||||
},
|
||||
/**
|
||||
* 隐藏elem
|
||||
*/
|
||||
hideElem: function () {
|
||||
$(elem).hide();
|
||||
return a;
|
||||
},
|
||||
/**
|
||||
* 绘制select下拉选择框
|
||||
*/
|
||||
createSelect: function () {
|
||||
var oriIcon = '<i class="fa">';
|
||||
|
||||
// 默认图标
|
||||
if (ORIGINAL_ELEM_VALUE === '') {
|
||||
ORIGINAL_ELEM_VALUE = 'fa-adjust';
|
||||
|
||||
}
|
||||
|
||||
|
||||
oriIcon = '<i class="fa ' + ORIGINAL_ELEM_VALUE + '">';
|
||||
|
||||
oriIcon += '</i>';
|
||||
|
||||
var selectHtml = '<div class="layui-iconpicker layui-unselect layui-form-select" id="' + ICON_BODY + '">' +
|
||||
'<div class="' + TITLE + '" id="' + TITLE_ID + '">' +
|
||||
'<div class="layui-iconpicker-item">' +
|
||||
'<span class="layui-iconpicker-icon layui-unselect">' +
|
||||
oriIcon +
|
||||
'</span>' +
|
||||
'<i class="layui-edge"></i>' +
|
||||
'</div>' +
|
||||
'</div>' +
|
||||
'<div class="layui-anim layui-anim-upbit" style="">' +
|
||||
'123' +
|
||||
'</div>';
|
||||
$(elem).after(selectHtml);
|
||||
return a;
|
||||
},
|
||||
/**
|
||||
* 展开/折叠下拉框
|
||||
*/
|
||||
toggleSelect: function () {
|
||||
var item = '#' + TITLE_ID + ' .layui-iconpicker-item,#' + TITLE_ID + ' .layui-iconpicker-item .layui-edge';
|
||||
a.event('click', item, function (e) {
|
||||
var $icon = $('#' + ICON_BODY);
|
||||
if ($icon.hasClass(selected)) {
|
||||
$icon.removeClass(selected).addClass(unselect);
|
||||
} else {
|
||||
// 隐藏其他picker
|
||||
$('.layui-form-select').removeClass(selected);
|
||||
// 显示当前picker
|
||||
$icon.addClass(selected).removeClass(unselect);
|
||||
}
|
||||
e.stopPropagation();
|
||||
});
|
||||
return a;
|
||||
},
|
||||
/**
|
||||
* 绘制主体部分
|
||||
*/
|
||||
createBody: function () {
|
||||
// 获取数据
|
||||
var searchHtml = '';
|
||||
|
||||
if (search) {
|
||||
searchHtml = '<div class="layui-iconpicker-search">' +
|
||||
'<input class="layui-input">' +
|
||||
'<i class="layui-icon"></i>' +
|
||||
'</div>';
|
||||
}
|
||||
|
||||
// 组合dom
|
||||
var bodyHtml = '<div class="layui-iconpicker-body" id="' + PICKER_BODY + '">' +
|
||||
searchHtml +
|
||||
'<div class="' + LIST_BOX + '"></div> ' +
|
||||
'</div>';
|
||||
$('#' + ICON_BODY).find('.layui-anim').eq(0).html(bodyHtml);
|
||||
a.search().createList().check().page();
|
||||
|
||||
return a;
|
||||
},
|
||||
/**
|
||||
* 绘制图标列表
|
||||
* @param text 模糊查询关键字
|
||||
* @returns {string}
|
||||
*/
|
||||
createList: function (text) {
|
||||
var d = data,
|
||||
l = d.length,
|
||||
pageHtml = '',
|
||||
listHtml = $('<div class="layui-iconpicker-list">')//'<div class="layui-iconpicker-list">';
|
||||
|
||||
// 计算分页数据
|
||||
var _limit = limit, // 每页显示数量
|
||||
_pages = l % _limit === 0 ? l / _limit : parseInt(l / _limit + 1), // 总计多少页
|
||||
_id = PAGE_ID;
|
||||
|
||||
// 图标列表
|
||||
var icons = [];
|
||||
|
||||
for (var i = 0; i < l; i++) {
|
||||
var obj = d[i];
|
||||
|
||||
// 判断是否模糊查询
|
||||
if (text && obj.indexOf(text) === -1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 是否自定义格子宽度
|
||||
var style = '';
|
||||
if (cellWidth !== null) {
|
||||
style += ' style="width:' + cellWidth + '"';
|
||||
}
|
||||
|
||||
// 每个图标dom
|
||||
var icon = '<div class="layui-iconpicker-icon-item" title="' + obj + '" ' + style + '>';
|
||||
|
||||
icon += '<i class="fa ' + obj + '"></i>';
|
||||
|
||||
icon += '</div>';
|
||||
|
||||
icons.push(icon);
|
||||
}
|
||||
|
||||
// 查询出图标后再分页
|
||||
l = icons.length;
|
||||
_pages = l % _limit === 0 ? l / _limit : parseInt(l / _limit + 1);
|
||||
for (var i = 0; i < _pages; i++) {
|
||||
// 按limit分块
|
||||
var lm = $('<div class="layui-iconpicker-icon-limit" id="layui-iconpicker-icon-limit-' + tmp + (i + 1) + '">');
|
||||
|
||||
for (var j = i * _limit; j < (i + 1) * _limit && j < l; j++) {
|
||||
lm.append(icons[j]);
|
||||
}
|
||||
|
||||
listHtml.append(lm);
|
||||
}
|
||||
|
||||
// 无数据
|
||||
if (l === 0) {
|
||||
listHtml.append('<p class="layui-iconpicker-tips">无数据</p>');
|
||||
}
|
||||
|
||||
// 判断是否分页
|
||||
if (page) {
|
||||
$('#' + PICKER_BODY).addClass('layui-iconpicker-body-page');
|
||||
pageHtml = '<div class="layui-iconpicker-page" id="' + PAGE_ID + '">' +
|
||||
'<div class="layui-iconpicker-page-count">' +
|
||||
'<span id="' + PAGE_ID + '-current">1</span>/' +
|
||||
'<span id="' + PAGE_ID + '-pages">' + _pages + '</span>' +
|
||||
' (<span id="' + PAGE_ID + '-length">' + l + '</span>)' +
|
||||
'</div>' +
|
||||
'<div class="layui-iconpicker-page-operate">' +
|
||||
'<i class="layui-icon" id="' + PAGE_ID + '-prev" data-index="0" prev></i> ' +
|
||||
'<i class="layui-icon" id="' + PAGE_ID + '-next" data-index="2" next></i> ' +
|
||||
'</div>' +
|
||||
'</div>';
|
||||
}
|
||||
|
||||
|
||||
$('#' + ICON_BODY).find('.layui-anim').find('.' + LIST_BOX).html('').append(listHtml).append(pageHtml);
|
||||
return a;
|
||||
},
|
||||
// 阻止Layui的一些默认事件
|
||||
preventEvent: function () {
|
||||
var item = '#' + ICON_BODY + ' .layui-anim';
|
||||
a.event('click', item, function (e) {
|
||||
e.stopPropagation();
|
||||
});
|
||||
return a;
|
||||
},
|
||||
// 分页
|
||||
page: function () {
|
||||
var icon = '#' + PAGE_ID + ' .layui-iconpicker-page-operate .layui-icon';
|
||||
|
||||
$(icon).unbind('click');
|
||||
a.event('click', icon, function (e) {
|
||||
var elem = e.currentTarget,
|
||||
total = parseInt($('#' + PAGE_ID + '-pages').html()),
|
||||
isPrev = $(elem).attr('prev') !== undefined,
|
||||
// 按钮上标的页码
|
||||
index = parseInt($(elem).attr('data-index')),
|
||||
$cur = $('#' + PAGE_ID + '-current'),
|
||||
// 点击时正在显示的页码
|
||||
current = parseInt($cur.html());
|
||||
|
||||
// 分页数据
|
||||
if (isPrev && current > 1) {
|
||||
current = current - 1;
|
||||
$(icon + '[prev]').attr('data-index', current);
|
||||
} else if (!isPrev && current < total) {
|
||||
current = current + 1;
|
||||
$(icon + '[next]').attr('data-index', current);
|
||||
}
|
||||
$cur.html(current);
|
||||
|
||||
// 图标数据
|
||||
$('#' + ICON_BODY + ' .layui-iconpicker-icon-limit').hide();
|
||||
$('#layui-iconpicker-icon-limit-' + tmp + current).show();
|
||||
e.stopPropagation();
|
||||
});
|
||||
return a;
|
||||
},
|
||||
/**
|
||||
* 搜索
|
||||
*/
|
||||
search: function () {
|
||||
var item = '#' + PICKER_BODY + ' .layui-iconpicker-search .layui-input';
|
||||
a.event('input propertychange', item, function (e) {
|
||||
var elem = e.target,
|
||||
t = $(elem).val();
|
||||
a.createList(t);
|
||||
});
|
||||
return a;
|
||||
},
|
||||
/**
|
||||
* 点击选中图标
|
||||
*/
|
||||
check: function () {
|
||||
var item = '#' + PICKER_BODY + ' .layui-iconpicker-icon-item';
|
||||
a.event('click', item, function (e) {
|
||||
var el = $(e.currentTarget).find('.fa'),
|
||||
icon = '';
|
||||
|
||||
var clsArr = el.attr('class').split(/[\s\n]/),
|
||||
cls = clsArr[1],
|
||||
icon = cls;
|
||||
$('#' + TITLE_ID).find('.layui-iconpicker-item .fa').html('').attr('class', clsArr.join(' '));
|
||||
|
||||
|
||||
$('#' + ICON_BODY).removeClass(selected).addClass(unselect);
|
||||
$(elem).val(icon).attr('value', icon);
|
||||
// 回调
|
||||
if (click) {
|
||||
click({
|
||||
icon: icon
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
return a;
|
||||
},
|
||||
// 监听原始input数值改变
|
||||
inputListen: function () {
|
||||
var el = $(elem);
|
||||
a.event('change', elem, function () {
|
||||
var value = el.val();
|
||||
})
|
||||
// el.change(function(){
|
||||
|
||||
// });
|
||||
return a;
|
||||
},
|
||||
event: function (evt, el, fn) {
|
||||
$(BODY).on(evt, el, fn);
|
||||
}
|
||||
};
|
||||
|
||||
var common = {
|
||||
/**
|
||||
* 加载样式表
|
||||
*/
|
||||
loadCss: function () {
|
||||
var css = '.layui-iconpicker {max-width: 280px;}.layui-iconpicker .layui-anim{display:none;position:absolute;left:0;top:42px;padding:5px 0;z-index:899;min-width:100%;border:1px solid #d2d2d2;max-height:300px;overflow-y:auto;background-color:#fff;border-radius:2px;box-shadow:0 2px 4px rgba(0,0,0,.12);box-sizing:border-box;}.layui-iconpicker-item{border:1px solid #e6e6e6;width:90px;height:38px;border-radius:4px;cursor:pointer;position:relative;}.layui-iconpicker-icon{border-right:1px solid #e6e6e6;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;display:block;width:60px;height:100%;float:left;text-align:center;background:#fff;transition:all .3s;}.layui-iconpicker-icon i{line-height:38px;font-size:18px;}.layui-iconpicker-item > .layui-edge{left:70px;}.layui-iconpicker-item:hover{border-color:#D2D2D2!important;}.layui-iconpicker-item:hover .layui-iconpicker-icon{border-color:#D2D2D2!important;}.layui-iconpicker.layui-form-selected .layui-anim{display:block;}.layui-iconpicker-body{padding:6px;}.layui-iconpicker .layui-iconpicker-list{background-color:#fff;border:1px solid #ccc;border-radius:4px;}.layui-iconpicker .layui-iconpicker-icon-item{display:inline-block;width:21.1%;line-height:36px;text-align:center;cursor:pointer;vertical-align:top;height:36px;margin:4px;border:1px solid #ddd;border-radius:2px;transition:300ms;}.layui-iconpicker .layui-iconpicker-icon-item i.layui-icon{font-size:17px;}.layui-iconpicker .layui-iconpicker-icon-item:hover{background-color:#eee;border-color:#ccc;-webkit-box-shadow:0 0 2px #aaa,0 0 2px #fff inset;-moz-box-shadow:0 0 2px #aaa,0 0 2px #fff inset;box-shadow:0 0 2px #aaa,0 0 2px #fff inset;text-shadow:0 0 1px #fff;}.layui-iconpicker-search{position:relative;margin:0 0 6px 0;border:1px solid #e6e6e6;border-radius:2px;transition:300ms;}.layui-iconpicker-search:hover{border-color:#D2D2D2!important;}.layui-iconpicker-search .layui-input{cursor:text;display:inline-block;width:86%;border:none;padding-right:0;margin-top:1px;}.layui-iconpicker-search .layui-icon{position:absolute;top:11px;right:4%;}.layui-iconpicker-tips{text-align:center;padding:8px 0;cursor:not-allowed;}.layui-iconpicker-page{margin-top:6px;margin-bottom:-6px;font-size:12px;padding:0 2px;}.layui-iconpicker-page-count{display:inline-block;}.layui-iconpicker-page-operate{display:inline-block;float:right;cursor:default;}.layui-iconpicker-page-operate .layui-icon{font-size:12px;cursor:pointer;}.layui-iconpicker-body-page .layui-iconpicker-icon-limit{display:none;}.layui-iconpicker-body-page .layui-iconpicker-icon-limit:first-child{display:block;}';
|
||||
var $style = $('head').find('style[iconpicker]');
|
||||
if ($style.length === 0) {
|
||||
$('head').append('<style rel="stylesheet" iconpicker>' + css + '</style>');
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取数据
|
||||
*/
|
||||
getData: function (url) {
|
||||
var iconlist = [];
|
||||
$.ajax({
|
||||
url: url,
|
||||
type: 'get',
|
||||
contentType: "application/x-www-form-urlencoded; charset=UTF-8",
|
||||
async: false,
|
||||
success: function (ret) {
|
||||
var exp = /fa-var-(.*):/ig;
|
||||
var result;
|
||||
while ((result = exp.exec(ret)) != null) {
|
||||
iconlist.push('fa-' + result[1]);
|
||||
}
|
||||
},
|
||||
error: function (xhr, textstatus, thrown) {
|
||||
layer.msg('fa图标接口有误');
|
||||
}
|
||||
});
|
||||
return iconlist;
|
||||
}
|
||||
};
|
||||
|
||||
a.init();
|
||||
return new IconPicker();
|
||||
};
|
||||
|
||||
/**
|
||||
* 选中图标
|
||||
* @param filter lay-filter
|
||||
* @param iconName 图标名称,自动识别fontClass/unicode
|
||||
*/
|
||||
IconPicker.prototype.checkIcon = function (filter, iconName) {
|
||||
var el = $('*[lay-filter=' + filter + ']'),
|
||||
p = el.next().find('.layui-iconpicker-item .fa'),
|
||||
c = iconName;
|
||||
|
||||
if (c.indexOf('#xe') > 0) {
|
||||
p.html(c);
|
||||
} else {
|
||||
p.html('').attr('class', 'fa ' + c);
|
||||
}
|
||||
el.attr('value', c).val(c);
|
||||
};
|
||||
|
||||
var iconPicker = new IconPicker();
|
||||
exports(_MOD, iconPicker);
|
||||
});
|
4040
public/js/lay-module/layarea/layarea.js
Normal file
4040
public/js/lay-module/layarea/layarea.js
Normal file
File diff suppressed because it is too large
Load Diff
332
public/js/lay-module/layuimini/miniAdmin.js
Normal file
332
public/js/lay-module/layuimini/miniAdmin.js
Normal file
|
@ -0,0 +1,332 @@
|
|||
/**
|
||||
* date:2020/02/27
|
||||
* author:Mr.Chung
|
||||
* version:2.0
|
||||
* description:layuimini 主体框架扩展
|
||||
*/
|
||||
layui.define(["jquery", "miniMenu", "element","miniPage", "miniTheme"], function (exports) {
|
||||
var $ = layui.$,
|
||||
element = layui.element,
|
||||
layer = layui.layer,
|
||||
miniMenu = layui.miniMenu,
|
||||
miniTheme = layui.miniTheme,
|
||||
miniPage = layui.miniPage;
|
||||
|
||||
if (!/http(s*):\/\//.test(location.href)) {
|
||||
var tips = "请先将项目部署至web容器(Apache/Tomcat/Nginx/IIS/等),否则部分数据将无法显示";
|
||||
return layer.alert(tips);
|
||||
}
|
||||
|
||||
var miniAdmin = {
|
||||
|
||||
/**
|
||||
* 后台框架初始化
|
||||
* @param options.iniUrl 后台初始化接口地址
|
||||
* @param options.clearUrl 后台清理缓存接口
|
||||
* @param options.renderPageVersion 初始化页面是否加版本号
|
||||
* @param options.bgColorDefault 默认皮肤
|
||||
* @param options.multiModule 是否开启多模块
|
||||
* @param options.menuChildOpen 是否展开子菜单
|
||||
* @param options.loadingTime 初始化加载时间
|
||||
* @param options.pageAnim 切换菜单动画
|
||||
*/
|
||||
render: function (options) {
|
||||
options.iniUrl = options.iniUrl || null;
|
||||
options.clearUrl = options.clearUrl || null;
|
||||
options.renderPageVersion = options.renderPageVersion || false;
|
||||
options.bgColorDefault = options.bgColorDefault || 0;
|
||||
options.multiModule = options.multiModule || false;
|
||||
options.menuChildOpen = options.menuChildOpen || false;
|
||||
options.loadingTime = options.loadingTime || 1;
|
||||
options.pageAnim = options.pageAnim || false;
|
||||
$.getJSON(options.iniUrl, function (data) {
|
||||
if (data == null) {
|
||||
miniAdmin.error('暂无菜单信息')
|
||||
} else {
|
||||
miniAdmin.renderLogo(data.logoInfo);
|
||||
miniAdmin.renderClear(options.clearUrl);
|
||||
miniAdmin.renderAnim(options.pageAnim);
|
||||
miniAdmin.listen({
|
||||
homeInfo:data.homeInfo,
|
||||
multiModule: options.multiModule,
|
||||
});
|
||||
miniMenu.render({
|
||||
menuList: data.menuInfo,
|
||||
multiModule: options.multiModule,
|
||||
menuChildOpen: options.menuChildOpen
|
||||
});
|
||||
miniPage.render({
|
||||
homeInfo:data.homeInfo,
|
||||
menuList: data.menuInfo,
|
||||
multiModule: options.multiModule,
|
||||
renderPageVersion: options.renderPageVersion,
|
||||
menuChildOpen: options.menuChildOpen,
|
||||
listenSwichCallback: function () {
|
||||
miniAdmin.renderDevice();
|
||||
}
|
||||
});
|
||||
miniTheme.render({
|
||||
bgColorDefault: options.bgColorDefault,
|
||||
listen: true,
|
||||
});
|
||||
miniAdmin.deleteLoader(options.loadingTime);
|
||||
}
|
||||
}).fail(function () {
|
||||
miniAdmin.error('菜单接口有误');
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 初始化logo
|
||||
* @param data
|
||||
*/
|
||||
renderLogo: function (data) {
|
||||
var html = '<a href="javascript:;"><img src="' + data.image + '" alt="logo"><h1>' + data.title + '</h1></a>';
|
||||
$('.layuimini-logo').html(html);
|
||||
},
|
||||
|
||||
/**
|
||||
* 初始化缓存地址
|
||||
* @param clearUrl
|
||||
*/
|
||||
renderClear: function (clearUrl) {
|
||||
$('.layuimini-clear').attr('data-href',clearUrl);
|
||||
},
|
||||
|
||||
/**
|
||||
* 切换菜单动画
|
||||
* @param anim
|
||||
*/
|
||||
renderAnim: function (anim) {
|
||||
if (anim) {
|
||||
$('#layuimini-bg-color').after('<style id="layuimini-page-anim">' +
|
||||
'.layuimini-page-anim {-webkit-animation-name:layuimini-upbit;-webkit-animation-duration:.3s;-webkit-animation-fill-mode:both;}\n' +
|
||||
'@keyframes layuimini-upbit {0% {transform:translate3d(0,30px,0);opacity:.3;}\n' +
|
||||
'100% {transform:translate3d(0,0,0);opacity:1;}\n' +
|
||||
'}\n' +
|
||||
'</style>');
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 进入全屏
|
||||
*/
|
||||
fullScreen: function () {
|
||||
var el = document.documentElement;
|
||||
var rfs = el.requestFullScreen || el.webkitRequestFullScreen;
|
||||
if (typeof rfs != "undefined" && rfs) {
|
||||
rfs.call(el);
|
||||
} else if (typeof window.ActiveXObject != "undefined") {
|
||||
var wscript = new ActiveXObject("WScript.Shell");
|
||||
if (wscript != null) {
|
||||
wscript.SendKeys("{F11}");
|
||||
}
|
||||
} else if (el.msRequestFullscreen) {
|
||||
el.msRequestFullscreen();
|
||||
} else if (el.oRequestFullscreen) {
|
||||
el.oRequestFullscreen();
|
||||
} else if (el.webkitRequestFullscreen) {
|
||||
el.webkitRequestFullscreen();
|
||||
} else if (el.mozRequestFullScreen) {
|
||||
el.mozRequestFullScreen();
|
||||
} else {
|
||||
miniAdmin.error('浏览器不支持全屏调用!');
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 退出全屏
|
||||
*/
|
||||
exitFullScreen: function () {
|
||||
var el = document;
|
||||
var cfs = el.cancelFullScreen || el.webkitCancelFullScreen || el.exitFullScreen;
|
||||
if (typeof cfs != "undefined" && cfs) {
|
||||
cfs.call(el);
|
||||
} else if (typeof window.ActiveXObject != "undefined") {
|
||||
var wscript = new ActiveXObject("WScript.Shell");
|
||||
if (wscript != null) {
|
||||
wscript.SendKeys("{F11}");
|
||||
}
|
||||
} else if (el.msExitFullscreen) {
|
||||
el.msExitFullscreen();
|
||||
} else if (el.oRequestFullscreen) {
|
||||
el.oCancelFullScreen();
|
||||
}else if (el.mozCancelFullScreen) {
|
||||
el.mozCancelFullScreen();
|
||||
} else if (el.webkitCancelFullScreen) {
|
||||
el.webkitCancelFullScreen();
|
||||
} else {
|
||||
miniAdmin.error('浏览器不支持全屏调用!');
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 初始化设备端
|
||||
*/
|
||||
renderDevice: function () {
|
||||
if (miniAdmin.checkMobile()) {
|
||||
$('.layuimini-tool i').attr('data-side-fold', 1);
|
||||
$('.layuimini-tool i').attr('class', 'fa fa-outdent');
|
||||
$('.layui-layout-body').removeClass('layuimini-mini');
|
||||
$('.layui-layout-body').addClass('layuimini-all');
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* 初始化加载时间
|
||||
* @param loadingTime
|
||||
*/
|
||||
deleteLoader: function (loadingTime) {
|
||||
setTimeout(function () {
|
||||
$('.layuimini-loader').fadeOut();
|
||||
}, loadingTime * 1000)
|
||||
},
|
||||
|
||||
/**
|
||||
* 成功
|
||||
* @param title
|
||||
* @returns {*}
|
||||
*/
|
||||
success: function (title) {
|
||||
return layer.msg(title, {icon: 1, shade: this.shade, scrollbar: false, time: 2000, shadeClose: true});
|
||||
},
|
||||
|
||||
/**
|
||||
* 失败
|
||||
* @param title
|
||||
* @returns {*}
|
||||
*/
|
||||
error: function (title) {
|
||||
return layer.msg(title, {icon: 2, shade: this.shade, scrollbar: false, time: 3000, shadeClose: true});
|
||||
},
|
||||
|
||||
/**
|
||||
* 判断是否为手机
|
||||
* @returns {boolean}
|
||||
*/
|
||||
checkMobile: function () {
|
||||
var ua = navigator.userAgent.toLocaleLowerCase();
|
||||
var pf = navigator.platform.toLocaleLowerCase();
|
||||
var isAndroid = (/android/i).test(ua) || ((/iPhone|iPod|iPad/i).test(ua) && (/linux/i).test(pf))
|
||||
|| (/ucweb.*linux/i.test(ua));
|
||||
var isIOS = (/iPhone|iPod|iPad/i).test(ua) && !isAndroid;
|
||||
var isWinPhone = (/Windows Phone|ZuneWP7/i).test(ua);
|
||||
var clientWidth = document.documentElement.clientWidth;
|
||||
if (!isAndroid && !isIOS && !isWinPhone && clientWidth > 1024) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 监听
|
||||
* @param options
|
||||
*/
|
||||
listen: function (options) {
|
||||
options.homeInfo = options.homeInfo || {};
|
||||
|
||||
/**
|
||||
* 清理
|
||||
*/
|
||||
$('body').on('click', '[data-clear]', function () {
|
||||
var loading = layer.load(0, {shade: false, time: 2 * 1000});
|
||||
sessionStorage.clear();
|
||||
|
||||
// 判断是否清理服务端
|
||||
var clearUrl = $(this).attr('data-href');
|
||||
if (clearUrl != undefined && clearUrl != '' && clearUrl != null) {
|
||||
$.getJSON(clearUrl, function (data, status) {
|
||||
layer.close(loading);
|
||||
if (data.code != 1) {
|
||||
return miniAdmin.error(data.msg);
|
||||
} else {
|
||||
return miniAdmin.success(data.msg);
|
||||
}
|
||||
}).fail(function () {
|
||||
layer.close(loading);
|
||||
return miniAdmin.error('清理缓存接口有误');
|
||||
});
|
||||
} else {
|
||||
layer.close(loading);
|
||||
return miniAdmin.success('清除缓存成功');
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* 刷新
|
||||
*/
|
||||
$('body').on('click', '[data-refresh]', function () {
|
||||
miniPage.refresh(options);
|
||||
miniAdmin.success('刷新成功');
|
||||
});
|
||||
|
||||
/**
|
||||
* 监听提示信息
|
||||
*/
|
||||
$("body").on("mouseenter", ".layui-nav-tree .menu-li", function () {
|
||||
if (miniAdmin.checkMobile()) {
|
||||
return false;
|
||||
}
|
||||
var classInfo = $(this).attr('class'),
|
||||
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>" ;
|
||||
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 });
|
||||
element.render();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
$("body").on("mouseleave", ".popup-tips", function () {
|
||||
if (miniAdmin.checkMobile()) {
|
||||
return false;
|
||||
}
|
||||
var isShow = $('.layuimini-tool i').attr('data-side-fold');
|
||||
if (isShow == 0) {
|
||||
try {
|
||||
layer.close(window.openTips);
|
||||
} catch (e) {
|
||||
console.log(e.message);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* 全屏
|
||||
*/
|
||||
$('body').on('click', '[data-check-screen]', function () {
|
||||
var check = $(this).attr('data-check-screen');
|
||||
if (check == 'full') {
|
||||
miniAdmin.fullScreen();
|
||||
$(this).attr('data-check-screen', 'exit');
|
||||
$(this).html('<i class="fa fa-compress"></i>');
|
||||
} else {
|
||||
miniAdmin.exitFullScreen();
|
||||
$(this).attr('data-check-screen', 'full');
|
||||
$(this).html('<i class="fa fa-arrows-alt"></i>');
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* 点击遮罩层
|
||||
*/
|
||||
$('body').on('click', '.layuimini-make', function () {
|
||||
miniAdmin.renderDevice();
|
||||
});
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
exports("miniAdmin", miniAdmin);
|
||||
});
|
249
public/js/lay-module/layuimini/miniMenu.js
Normal file
249
public/js/lay-module/layuimini/miniMenu.js
Normal file
|
@ -0,0 +1,249 @@
|
|||
/**
|
||||
* date:2020/02/27
|
||||
* author:Mr.Chung
|
||||
* version:2.0
|
||||
* description:layuimini 菜单框架扩展
|
||||
*/
|
||||
layui.define(["element","laytpl" ,"jquery"], function (exports) {
|
||||
var element = layui.element,
|
||||
$ = layui.$,
|
||||
laytpl = layui.laytpl,
|
||||
layer = layui.layer;
|
||||
|
||||
var miniMenu = {
|
||||
|
||||
/**
|
||||
* 菜单初始化
|
||||
* @param options.menuList 菜单数据信息
|
||||
* @param options.multiModule 是否开启多模块
|
||||
* @param options.menuChildOpen 是否展开子菜单
|
||||
*/
|
||||
render: function (options) {
|
||||
options.menuList = options.menuList || [];
|
||||
options.multiModule = options.multiModule || false;
|
||||
options.menuChildOpen = options.menuChildOpen || false;
|
||||
if (options.multiModule) {
|
||||
miniMenu.renderMultiModule(options.menuList, options.menuChildOpen);
|
||||
} else {
|
||||
miniMenu.renderSingleModule(options.menuList, options.menuChildOpen);
|
||||
}
|
||||
miniMenu.listen();
|
||||
},
|
||||
|
||||
/**
|
||||
* 单模块
|
||||
* @param menuList 菜单数据
|
||||
* @param menuChildOpen 是否默认展开
|
||||
*/
|
||||
renderSingleModule: function (menuList, menuChildOpen) {
|
||||
menuList = menuList || [];
|
||||
var leftMenuHtml = '',
|
||||
childOpenClass = '',
|
||||
leftMenuCheckDefault = 'layui-this';
|
||||
var me = this ;
|
||||
if (menuChildOpen) childOpenClass = ' layui-nav-itemed';
|
||||
leftMenuHtml = this.renderLeftMenu(menuList,{ childOpenClass:childOpenClass }) ;
|
||||
$('.layui-layout-body').addClass('layuimini-single-module'); //单模块标识
|
||||
$('.layuimini-header-menu').remove();
|
||||
$('.layuimini-menu-left').html(leftMenuHtml);
|
||||
|
||||
element.init();
|
||||
},
|
||||
|
||||
/**
|
||||
* 渲染一级菜单
|
||||
*/
|
||||
compileMenu: function(menu,isSub){
|
||||
var menuHtml = '<li {{#if( d.menu){ }} data-menu="{{d.menu}}" {{#}}} class="layui-nav-item menu-li {{d.childOpenClass}} {{d.className}}" {{#if( d.id){ }} id="{{d.id}}" {{#}}}> <a {{#if( d.href){ }} layuimini-href="{{d.href}}" {{#}}} {{#if( d.target){ }} target="{{d.target}}" {{#}}} href="javascript:;">{{#if( d.icon){ }} <i class="{{d.icon}}"></i> {{#}}} <span class="layui-left-nav">{{d.title}}</span></a> {{# if(d.children){}} {{d.children}} {{#}}} </li>' ;
|
||||
if(isSub){
|
||||
menuHtml = '<dd class="menu-dd {{d.childOpenClass}} {{ d.className }}"> <a href="javascript:;" {{#if( d.menu){ }} data-menu="{{d.menu}}" {{#}}} {{#if( d.id){ }} id="{{d.id}}" {{#}}} {{#if(( !d.child || !d.child.length ) && d.href){ }} layuimini-href="{{d.href}}" {{#}}} {{#if( d.target){ }} target="{{d.target}}" {{#}}}> {{#if( d.icon){ }} <i class="{{d.icon}}"></i> {{#}}} <span class="layui-left-nav"> {{d.title}}</span></a> {{# if(d.children){}} {{d.children}} {{#}}}</dd>'
|
||||
}
|
||||
return laytpl(menuHtml).render(menu);
|
||||
},
|
||||
compileMenuContainer :function(menu,isSub){
|
||||
var wrapperHtml = '<ul class="layui-nav layui-nav-tree layui-left-nav-tree {{d.className}}" id="{{d.id}}">{{d.children}}</ul>' ;
|
||||
if(isSub){
|
||||
wrapperHtml = '<dl class="layui-nav-child ">{{d.children}}</dl>' ;
|
||||
}
|
||||
if(!menu.children){
|
||||
return "";
|
||||
}
|
||||
return laytpl(wrapperHtml).render(menu);
|
||||
},
|
||||
|
||||
each:function(list,callback){
|
||||
var _list = [];
|
||||
for(var i = 0 ,length = list.length ; i<length ;i++ ){
|
||||
_list[i] = callback(i,list[i]) ;
|
||||
}
|
||||
return _list ;
|
||||
},
|
||||
renderChildrenMenu:function(menuList,options){
|
||||
var me = this ;
|
||||
menuList = menuList || [] ;
|
||||
var html = this.each(menuList,function (idx,menu) {
|
||||
if(menu.child && menu.child.length){
|
||||
menu.children = me.renderChildrenMenu(menu.child,{ childOpenClass: options.childOpenClass || '' });
|
||||
}
|
||||
menu.className = "" ;
|
||||
menu.childOpenClass = options.childOpenClass || ''
|
||||
return me.compileMenu(menu,true)
|
||||
}).join("");
|
||||
return me.compileMenuContainer({ children:html },true)
|
||||
},
|
||||
renderLeftMenu :function(leftMenus,options){
|
||||
options = options || {};
|
||||
var me = this ;
|
||||
var leftMenusHtml = me.each(leftMenus || [],function (idx,leftMenu) { // 左侧菜单遍历
|
||||
var children = me.renderChildrenMenu(leftMenu.child, { childOpenClass:options.childOpenClass });
|
||||
var leftMenuHtml = me.compileMenu({
|
||||
href:leftMenu.href,
|
||||
target:leftMenu.target,
|
||||
childOpenClass:options.childOpenClass,
|
||||
icon:leftMenu.icon,
|
||||
title:leftMenu.title,
|
||||
children:children
|
||||
});
|
||||
return leftMenuHtml ;
|
||||
}).join("");
|
||||
|
||||
leftMenusHtml = me.compileMenuContainer({ id:options.parentMenuId,className:options.leftMenuCheckDefault,children:leftMenusHtml }) ;
|
||||
return leftMenusHtml ;
|
||||
},
|
||||
/**
|
||||
* 多模块
|
||||
* @param menuList 菜单数据
|
||||
* @param menuChildOpen 是否默认展开
|
||||
*/
|
||||
renderMultiModule: function (menuList, menuChildOpen) {
|
||||
menuList = menuList || [];
|
||||
var me = this ;
|
||||
var headerMenuHtml = '',
|
||||
headerMobileMenuHtml = '',
|
||||
leftMenuHtml = '',
|
||||
leftMenuCheckDefault = 'layui-this',
|
||||
childOpenClass = '',
|
||||
headerMenuCheckDefault = 'layui-this';
|
||||
|
||||
if (menuChildOpen) childOpenClass = ' layui-nav-itemed';
|
||||
var headerMenuHtml = this.each(menuList, function (index, val) { //顶部菜单渲染
|
||||
var menu = 'multi_module_' + index ;
|
||||
var id = menu+"HeaderId";
|
||||
var topMenuItemHtml = "" ;
|
||||
topMenuItemHtml = me.compileMenu({
|
||||
className:headerMenuCheckDefault,
|
||||
menu:menu,
|
||||
id:id,
|
||||
title:val.title,
|
||||
href:"",
|
||||
target:"",
|
||||
children:""
|
||||
});
|
||||
leftMenuHtml+=me.renderLeftMenu(val.child,{
|
||||
parentMenuId:menu,
|
||||
childOpenClass:childOpenClass,
|
||||
leftMenuCheckDefault:leftMenuCheckDefault
|
||||
});
|
||||
headerMobileMenuHtml +=me.compileMenu({ id:id,menu:menu,id:id,icon:val.icon, title:val.title, },true);
|
||||
headerMenuCheckDefault = "";
|
||||
leftMenuCheckDefault = "layui-hide" ;
|
||||
return topMenuItemHtml ;
|
||||
}).join("");
|
||||
$('.layui-layout-body').addClass('layuimini-multi-module'); //多模块标识
|
||||
$('.layuimini-menu-header-pc').html(headerMenuHtml); //电脑
|
||||
$('.layuimini-menu-left').html(leftMenuHtml);
|
||||
$('.layuimini-menu-header-mobile').html(headerMobileMenuHtml); //手机
|
||||
element.init();
|
||||
},
|
||||
|
||||
/**
|
||||
* 监听
|
||||
*/
|
||||
listen: function () {
|
||||
|
||||
/**
|
||||
* 菜单模块切换
|
||||
*/
|
||||
$('body').on('click', '[data-menu]', function () {
|
||||
var loading = layer.load(0, {shade: false, time: 2 * 1000});
|
||||
var menuId = $(this).attr('data-menu');
|
||||
// header
|
||||
$(".layuimini-header-menu .layui-nav-item.layui-this").removeClass('layui-this');
|
||||
$(this).addClass('layui-this');
|
||||
// left
|
||||
$(".layuimini-menu-left .layui-nav.layui-nav-tree.layui-this").addClass('layui-hide');
|
||||
$(".layuimini-menu-left .layui-nav.layui-nav-tree.layui-this.layui-hide").removeClass('layui-this');
|
||||
$("#" + menuId).removeClass('layui-hide');
|
||||
$("#" + menuId).addClass('layui-this');
|
||||
layer.close(loading);
|
||||
});
|
||||
|
||||
/**
|
||||
* 菜单缩放
|
||||
*/
|
||||
$('body').on('click', '.layuimini-site-mobile', function () {
|
||||
var loading = layer.load(0, {shade: false, time: 2 * 1000});
|
||||
var isShow = $('.layuimini-tool [data-side-fold]').attr('data-side-fold');
|
||||
if (isShow == 1) { // 缩放
|
||||
$('.layuimini-tool [data-side-fold]').attr('data-side-fold', 0);
|
||||
$('.layuimini-tool [data-side-fold]').attr('class', 'fa fa-indent');
|
||||
$('.layui-layout-body').removeClass('layuimini-all');
|
||||
$('.layui-layout-body').addClass('layuimini-mini');
|
||||
} else { // 正常
|
||||
$('.layuimini-tool [data-side-fold]').attr('data-side-fold', 1);
|
||||
$('.layuimini-tool [data-side-fold]').attr('class', 'fa fa-outdent');
|
||||
$('.layui-layout-body').removeClass('layuimini-mini');
|
||||
$('.layui-layout-body').addClass('layuimini-all');
|
||||
layer.close(window.openTips);
|
||||
}
|
||||
element.init();
|
||||
layer.close(loading);
|
||||
});
|
||||
/**
|
||||
* 菜单缩放
|
||||
*/
|
||||
$('body').on('click', '[data-side-fold]', function () {
|
||||
var loading = layer.load(0, {shade: false, time: 2 * 1000});
|
||||
var isShow = $('.layuimini-tool [data-side-fold]').attr('data-side-fold');
|
||||
if (isShow == 1) { // 缩放
|
||||
$('.layuimini-tool [data-side-fold]').attr('data-side-fold', 0);
|
||||
$('.layuimini-tool [data-side-fold]').attr('class', 'fa fa-indent');
|
||||
$('.layui-layout-body').removeClass('layuimini-all');
|
||||
$('.layui-layout-body').addClass('layuimini-mini');
|
||||
// $(".menu-li").each(function (idx,el) {
|
||||
// $(el).addClass("hidden-sub-menu");
|
||||
// });
|
||||
|
||||
} else { // 正常
|
||||
$('.layuimini-tool [data-side-fold]').attr('data-side-fold', 1);
|
||||
$('.layuimini-tool [data-side-fold]').attr('class', 'fa fa-outdent');
|
||||
$('.layui-layout-body').removeClass('layuimini-mini');
|
||||
$('.layui-layout-body').addClass('layuimini-all');
|
||||
// $(".menu-li").each(function (idx,el) {
|
||||
// $(el).removeClass("hidden-sub-menu");
|
||||
// });
|
||||
layer.close(window.openTips);
|
||||
}
|
||||
element.init();
|
||||
layer.close(loading);
|
||||
});
|
||||
|
||||
/**
|
||||
* 手机端点开模块
|
||||
*/
|
||||
$('body').on('click', '.layuimini-header-menu.layuimini-mobile-show dd', function () {
|
||||
var loading = layer.load(0, {shade: false, time: 2 * 1000});
|
||||
var check = $('.layuimini-tool [data-side-fold]').attr('data-side-fold');
|
||||
if(check === "1"){
|
||||
$('.layuimini-site-mobile').trigger("click");
|
||||
element.init();
|
||||
}
|
||||
layer.close(loading);
|
||||
});
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
|
||||
exports("miniMenu", miniMenu);
|
||||
});
|
394
public/js/lay-module/layuimini/miniPage.js
Normal file
394
public/js/lay-module/layuimini/miniPage.js
Normal file
|
@ -0,0 +1,394 @@
|
|||
/**
|
||||
* date:2020/02/27
|
||||
* author:Mr.Chung
|
||||
* version:2.0
|
||||
* description:layuimini 单页框架扩展
|
||||
*/
|
||||
layui.define(["element", "jquery"], function (exports) {
|
||||
var element = layui.element,
|
||||
$ = layui.$,
|
||||
// miniAdmin = layui.miniAdmin,
|
||||
layer = layui.layer;
|
||||
|
||||
|
||||
var miniPage = {
|
||||
|
||||
/**
|
||||
* 初始化tab
|
||||
* @param options
|
||||
*/
|
||||
render: function (options) {
|
||||
options.homeInfo = options.homeInfo || {};
|
||||
options.menuList = options.menuList || [];
|
||||
options.multiModule = options.multiModule || false;
|
||||
options.renderPageVersion = options.renderPageVersion || false;
|
||||
options.listenSwichCallback = options.listenSwichCallback || function () {
|
||||
};
|
||||
var href = location.hash.replace(/^#\//, '');
|
||||
if (href === null || href === undefined || href === '') {
|
||||
miniPage.renderHome(options);
|
||||
} else {
|
||||
miniPage.renderPage(href, options);
|
||||
if (options.multiModule) {
|
||||
miniPage.listenSwitchMultiModule(href);
|
||||
} else {
|
||||
miniPage.listenSwitchSingleModule(href);
|
||||
}
|
||||
}
|
||||
miniPage.listen(options);
|
||||
miniPage.listenHash(options);
|
||||
},
|
||||
|
||||
/**
|
||||
* 初始化主页
|
||||
* @param options
|
||||
*/
|
||||
renderHome: function (options) {
|
||||
options.homeInfo = options.homeInfo || {};
|
||||
options.homeInfo.href = options.homeInfo.href || '';
|
||||
options.renderPageVersion = options.renderPageVersion || false;
|
||||
$('.layuimini-page-header').addClass('layui-hide');
|
||||
miniPage.renderPageContent(options.homeInfo.href, options);
|
||||
},
|
||||
|
||||
/**
|
||||
* 初始化页面
|
||||
* @param href
|
||||
* @param options
|
||||
*/
|
||||
renderPage: function (href, options) {
|
||||
miniPage.renderPageTitle(href, options);
|
||||
miniPage.renderPageContent(href, options);
|
||||
},
|
||||
|
||||
/**
|
||||
* 初始化页面标题
|
||||
* @param href
|
||||
* @param options
|
||||
*/
|
||||
renderPageTitle: function (href, options) {
|
||||
options.homeInfo = options.homeInfo || {};
|
||||
options.homeInfo.title = options.homeInfo.title || '主页';
|
||||
options.menuList = options.menuList || [];
|
||||
$('.layuimini-page-header').removeClass('layui-hide');
|
||||
var pageTitleHtml = '<a lay-href="" href="javascript:;" class="layuimini-back-home">' + options.homeInfo.title + '</a><span lay-separator="">/</span>\n';
|
||||
var pageTitleArray = miniPage.buildPageTitleArray(href, options.menuList);
|
||||
if (pageTitleArray.length > 0) {
|
||||
for (var key in pageTitleArray) {
|
||||
key = parseInt(key);
|
||||
if (key !== pageTitleArray.length - 1) {
|
||||
pageTitleHtml += '<a><cite>' + pageTitleArray[key] + '</cite></a><span lay-separator="">/</span>\n';
|
||||
} else {
|
||||
pageTitleHtml += '<a><cite>' + pageTitleArray[key] + '</cite></a>\n';
|
||||
}
|
||||
}
|
||||
} else {
|
||||
var title = sessionStorage.getItem('layuimini_page_title');
|
||||
if (title === null || title === undefined || title === '') {
|
||||
$('.layuimini-page-header').addClass('layui-hide');
|
||||
} else {
|
||||
pageTitleHtml += '<a><cite>' + title + '</cite></a>\n';
|
||||
}
|
||||
}
|
||||
$('.layuimini-page-header .layuimini-page-title').empty().html(pageTitleHtml);
|
||||
},
|
||||
|
||||
/**
|
||||
* 初始化页面内容
|
||||
* @param options
|
||||
* @param href
|
||||
*/
|
||||
renderPageContent: function (href, options) {
|
||||
options.renderPageVersion = options.renderPageVersion || false;
|
||||
var container = '.layuimini-content-page';
|
||||
if (options.renderPageVersion) {
|
||||
var v = new Date().getTime();
|
||||
href = href.indexOf("?") > -1 ? href + '&v=' + v : href + '?v=' + v;
|
||||
}
|
||||
if ($(".layuimini-page-header").hasClass("layui-hide")) {
|
||||
$(container).removeAttr("style");
|
||||
} else {
|
||||
$(container).attr("style", "height: calc(100% - 36px)");
|
||||
}
|
||||
$(container).html('');
|
||||
$.ajax({
|
||||
url: href,
|
||||
type: 'get',
|
||||
dataType: 'html',
|
||||
success: function (data) {
|
||||
$(container).html(data);
|
||||
element.init();
|
||||
},
|
||||
error: function (xhr, textstatus, thrown) {
|
||||
return layer.msg('Status:' + xhr.status + ',' + xhr.statusText + ',请稍后再试!');
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 刷新页面内容
|
||||
* @param options
|
||||
*/
|
||||
refresh: function (options) {
|
||||
var href = location.hash.replace(/^#\//, '');
|
||||
if (href === null || href === undefined || href === '') {
|
||||
miniPage.renderHome(options);
|
||||
} else {
|
||||
miniPage.renderPageContent(href, options);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 构建页面标题数组
|
||||
* @param href
|
||||
* @param menuList
|
||||
*/
|
||||
buildPageTitleArray: function (href, menuList) {
|
||||
var array = [],
|
||||
newArray = [];
|
||||
for (key in menuList) {
|
||||
var item = menuList[key];
|
||||
if (item.href === href) {
|
||||
array.push(item.title);
|
||||
break;
|
||||
}
|
||||
if (item.child) {
|
||||
newArray = miniPage.buildPageTitleArray(href, item.child);
|
||||
if (newArray.length > 0) {
|
||||
newArray.unshift(item.title);
|
||||
array = array.concat(newArray);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return array;
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取指定链接内容
|
||||
* @param href
|
||||
* @returns {string}
|
||||
*/
|
||||
getHrefContent: function (href) {
|
||||
var content = '';
|
||||
var v = new Date().getTime();
|
||||
$.ajax({
|
||||
url: href.indexOf("?") > -1 ? href + '&v=' + v : href + '?v=' + v,
|
||||
type: 'get',
|
||||
dataType: 'html',
|
||||
async: false,
|
||||
success: function (data) {
|
||||
content = data;
|
||||
},
|
||||
error: function (xhr, textstatus, thrown) {
|
||||
return layer.msg('Status:' + xhr.status + ',' + xhr.statusText + ',请稍后再试!');
|
||||
}
|
||||
});
|
||||
return content;
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取弹出层的宽高
|
||||
* @returns {jQuery[]}
|
||||
*/
|
||||
getOpenWidthHeight: function () {
|
||||
var clienWidth = $(".layuimini-content-page").width();
|
||||
var clientHeight = $(".layuimini-content-page").height();
|
||||
var offsetLeft = $(".layuimini-content-page").offset().left;
|
||||
var offsetTop = $(".layuimini-content-page").offset().top;
|
||||
return [clienWidth, clientHeight, offsetTop, offsetLeft];
|
||||
},
|
||||
|
||||
/**
|
||||
* 单模块切换
|
||||
* @param tabId
|
||||
*/
|
||||
listenSwitchSingleModule: function (tabId) {
|
||||
$("[layuimini-href]").each(function () {
|
||||
if ($(this).attr("layuimini-href") === tabId) {
|
||||
// 自动展开菜单栏
|
||||
var addMenuClass = function ($element, type) {
|
||||
if (type === 1) {
|
||||
$element.addClass('layui-this');
|
||||
if ($element.hasClass('layui-nav-item') && $element.hasClass('layui-this')) {
|
||||
$(".layuimini-header-menu li").attr('class', 'layui-nav-item');
|
||||
} else {
|
||||
addMenuClass($element.parent().parent(), 2);
|
||||
}
|
||||
} else {
|
||||
$element.addClass('layui-nav-itemed');
|
||||
if ($element.hasClass('layui-nav-item') && $element.hasClass('layui-nav-itemed')) {
|
||||
$(".layuimini-header-menu li").attr('class', 'layui-nav-item');
|
||||
} else {
|
||||
addMenuClass($element.parent().parent(), 2);
|
||||
}
|
||||
}
|
||||
};
|
||||
addMenuClass($(this).parent(), 1);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 多模块切换
|
||||
* @param tabId
|
||||
*/
|
||||
listenSwitchMultiModule: function (tabId) {
|
||||
$("[layuimini-href]").each(function () {
|
||||
if ($(this).attr("layuimini-href") === tabId) {
|
||||
|
||||
// 自动展开菜单栏
|
||||
var addMenuClass = function ($element, type) {
|
||||
if (type === 1) {
|
||||
$element.addClass('layui-this');
|
||||
if ($element.hasClass('layui-nav-item') && $element.hasClass('layui-this')) {
|
||||
var moduleId = $element.parent().attr('id');
|
||||
$(".layuimini-header-menu li").attr('class', 'layui-nav-item');
|
||||
$("#" + moduleId + "HeaderId").addClass("layui-this");
|
||||
$(".layuimini-menu-left .layui-nav.layui-nav-tree").attr('class', 'layui-nav layui-nav-tree layui-hide');
|
||||
$("#" + moduleId).attr('class', 'layui-nav layui-nav-tree layui-this');
|
||||
} else {
|
||||
addMenuClass($element.parent().parent(), 2);
|
||||
}
|
||||
} else {
|
||||
$element.addClass('layui-nav-itemed');
|
||||
if ($element.hasClass('layui-nav-item') && $element.hasClass('layui-nav-itemed')) {
|
||||
var moduleId = $element.parent().attr('id');
|
||||
$(".layuimini-header-menu li").attr('class', 'layui-nav-item');
|
||||
$("#" + moduleId + "HeaderId").addClass("layui-this");
|
||||
$(".layuimini-menu-left .layui-nav.layui-nav-tree").attr('class', 'layui-nav layui-nav-tree layui-hide');
|
||||
$("#" + moduleId).attr('class', 'layui-nav layui-nav-tree layui-this');
|
||||
} else {
|
||||
addMenuClass($element.parent().parent(), 2);
|
||||
}
|
||||
}
|
||||
};
|
||||
addMenuClass($(this).parent(), 1);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 修改hash地址定位
|
||||
* @param href
|
||||
*/
|
||||
hashChange: function (href) {
|
||||
window.location.hash = "/" + href;
|
||||
},
|
||||
|
||||
/**
|
||||
* 修改hash地址为主页
|
||||
*/
|
||||
hashHome: function () {
|
||||
window.location.hash = "/";
|
||||
},
|
||||
|
||||
/**
|
||||
* 监听
|
||||
* @param options
|
||||
*/
|
||||
listen: function (options) {
|
||||
|
||||
/**
|
||||
* 打开新窗口
|
||||
*/
|
||||
$('body').on('click', '[layuimini-href]', function () {
|
||||
var loading = layer.load(0, {shade: false, time: 2 * 1000});
|
||||
var href = $(this).attr('layuimini-href'),
|
||||
target = $(this).attr('target');
|
||||
if(!href) return ;
|
||||
var me = this ;
|
||||
var el = $("[layuimini-href='"+href+"']",".layuimini-menu-left") ;
|
||||
layer.close(window.openTips);
|
||||
if(el.length){
|
||||
$(el).closest(".layui-nav-tree").find(".layui-this").removeClass("layui-this");
|
||||
$(el).parent().addClass("layui-this");
|
||||
}
|
||||
if (target === '_blank') {
|
||||
layer.close(loading);
|
||||
window.open(href, "_blank");
|
||||
return false;
|
||||
}
|
||||
miniPage.hashChange(href);
|
||||
$('.layuimini-menu-left').attr('layuimini-page-add', 'yes');
|
||||
layer.close(loading);
|
||||
});
|
||||
|
||||
/**
|
||||
* 在子页面上打开新窗口
|
||||
*/
|
||||
$('body').on('click', '[layuimini-content-href]', function () {
|
||||
var loading = parent.layer.load(0, {shade: false, time: 2 * 1000});
|
||||
var href = $(this).attr('layuimini-content-href'),
|
||||
title = $(this).attr('data-title'),
|
||||
target = $(this).attr('target');
|
||||
if(!href) return ;
|
||||
var me = this ;
|
||||
var el = $("[layuimini-href='"+href+"']",".layuimini-menu-left") ;
|
||||
layer.close(window.openTips);
|
||||
if(el.length){
|
||||
$(el).closest(".layui-nav-tree").find(".layui-this").removeClass("layui-this");
|
||||
$(el).parent().addClass("layui-this");
|
||||
}
|
||||
if (target === '_blank') {
|
||||
parent.layer.close(loading);
|
||||
window.open(href, "_blank");
|
||||
return false;
|
||||
}
|
||||
sessionStorage.setItem('layuimini_page_title', title);
|
||||
miniPage.hashChange(href);
|
||||
parent.layer.close(loading);
|
||||
});
|
||||
|
||||
/**
|
||||
* 返回主页
|
||||
*/
|
||||
$('body').on('click', '.layuimini-back-home', function () {
|
||||
miniPage.hashHome();
|
||||
});
|
||||
|
||||
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* 监听hash变化
|
||||
* @returns {boolean}
|
||||
*/
|
||||
listenHash: function (options) {
|
||||
options.homeInfo = options.homeInfo || {};
|
||||
options.multiModule = options.multiModule || false;
|
||||
options.listenSwichCallback = options.listenSwichCallback || function () {
|
||||
};
|
||||
window.onhashchange = function () {
|
||||
var href = location.hash.replace(/^#\//, '');
|
||||
if (typeof options.listenSwichCallback === 'function') {
|
||||
options.listenSwichCallback();
|
||||
}
|
||||
if (href === null || href === undefined || href === '') {
|
||||
$("[layuimini-href]").parent().removeClass('layui-this');
|
||||
miniPage.renderHome(options);
|
||||
} else {
|
||||
miniPage.renderPage(href, options);
|
||||
}
|
||||
if ($('.layuimini-menu-left').attr('layuimini-page-add') === 'yes') {
|
||||
$('.layuimini-menu-left').attr('layuimini-page-add', 'no');
|
||||
} else {
|
||||
// 从页面中打开的话,浏览器前进后退、需要重新定位菜单焦点
|
||||
$("[layuimini-href]").parent().removeClass('layui-this');
|
||||
if (options.multiModule) {
|
||||
miniPage.listenSwitchMultiModule(href);
|
||||
} else {
|
||||
miniPage.listenSwitchSingleModule(href);
|
||||
}
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
|
||||
};
|
||||
|
||||
exports("miniPage", miniPage);
|
||||
});
|
474
public/js/lay-module/layuimini/miniTheme.js
Normal file
474
public/js/lay-module/layuimini/miniTheme.js
Normal file
|
@ -0,0 +1,474 @@
|
|||
/**
|
||||
* date:2020/02/28
|
||||
* author:Mr.Chung
|
||||
* version:2.0
|
||||
* description:layuimini tab框架扩展
|
||||
*/
|
||||
layui.define(["jquery", "layer"], function (exports) {
|
||||
var $ = layui.$,
|
||||
layer = layui.layer;
|
||||
|
||||
var miniTheme = {
|
||||
|
||||
/**
|
||||
* 主题配置项
|
||||
* @param bgcolorId
|
||||
* @returns {{headerLogo, menuLeftHover, headerRight, menuLeft, headerRightThis, menuLeftThis}|*|*[]}
|
||||
*/
|
||||
config: function (bgcolorId) {
|
||||
var bgColorConfig = [
|
||||
{
|
||||
headerRightBg: '#ffffff', //头部右侧背景色
|
||||
headerRightBgThis: '#e4e4e4', //头部右侧选中背景色,
|
||||
headerRightColor: 'rgba(107, 107, 107, 0.7)', //头部右侧字体颜色,
|
||||
headerRightChildColor: 'rgba(107, 107, 107, 0.7)', //头部右侧下拉字体颜色,
|
||||
headerRightColorThis: '#565656', //头部右侧鼠标选中,
|
||||
headerRightNavMore: 'rgba(160, 160, 160, 0.7)', //头部右侧更多下拉颜色,
|
||||
headerRightNavMoreBg: '#1E9FFF', //头部右侧更多下拉列表选中背景色,
|
||||
headerRightNavMoreColor: '#ffffff', //头部右侧更多下拉列表字体色,
|
||||
headerRightToolColor: '#565656', //头部缩放按钮样式,
|
||||
headerLogoBg: '#192027', //logo背景颜色,
|
||||
headerLogoColor: 'rgb(191, 187, 187)', //logo字体颜色,
|
||||
leftMenuNavMore: 'rgb(191, 187, 187)', //左侧菜单更多下拉样式,
|
||||
leftMenuBg: '#28333E', //左侧菜单背景,
|
||||
leftMenuBgThis: '#1E9FFF', //左侧菜单选中背景,
|
||||
leftMenuChildBg: '#0c0f13', //左侧菜单子菜单背景,
|
||||
leftMenuColor: 'rgb(191, 187, 187)', //左侧菜单字体颜色,
|
||||
leftMenuColorThis: '#ffffff', //左侧菜单选中字体颜色,
|
||||
tabActiveColor: '#1e9fff', //tab选项卡选中颜色,
|
||||
},
|
||||
{
|
||||
headerRightBg: '#23262e', //头部右侧背景色
|
||||
headerRightBgThis: '#0c0c0c', //头部右侧选中背景色,
|
||||
headerRightColor: 'rgba(255,255,255,.7)', //头部右侧字体颜色,
|
||||
headerRightChildColor: '#676767', //头部右侧下拉字体颜色,
|
||||
headerRightColorThis: '#ffffff', //头部右侧鼠标选中,
|
||||
headerRightNavMore: 'rgba(255,255,255,.7)', //头部右侧更多下拉颜色,
|
||||
headerRightNavMoreBg: '#1aa094', //头部右侧更多下拉列表选中背景色,
|
||||
headerRightNavMoreColor: '#ffffff', //头部右侧更多下拉列表字体色,
|
||||
headerRightToolColor: '#bbe3df', //头部缩放按钮样式,
|
||||
headerLogoBg: '#0c0c0c', //logo背景颜色,
|
||||
headerLogoColor: '#ffffff', //logo字体颜色,
|
||||
leftMenuNavMore: 'rgb(191, 187, 187)', //左侧菜单更多下拉样式,
|
||||
leftMenuBg: '#23262e', //左侧菜单背景,
|
||||
leftMenuBgThis: '#737373', //左侧菜单选中背景,
|
||||
leftMenuChildBg: 'rgba(0,0,0,.3)', //左侧菜单子菜单背景,
|
||||
leftMenuColor: 'rgb(191, 187, 187)', //左侧菜单字体颜色,
|
||||
leftMenuColorThis: '#ffffff', //左侧菜单选中字体颜色,
|
||||
tabActiveColor: '#23262e', //tab选项卡选中颜色,
|
||||
},
|
||||
{
|
||||
headerRightBg: '#ffa4d1', //头部右侧背景色
|
||||
headerRightBgThis: '#bf7b9d', //头部右侧选中背景色,
|
||||
headerRightColor: 'rgba(255,255,255,.7)', //头部右侧字体颜色,
|
||||
headerRightChildColor: '#676767', //头部右侧下拉字体颜色,
|
||||
headerRightColorThis: '#ffffff', //头部右侧鼠标选中,
|
||||
headerRightNavMore: 'rgba(255,255,255,.7)', //头部右侧更多下拉颜色,
|
||||
headerRightNavMoreBg: '#ffa4d1', //头部右侧更多下拉列表选中背景色,
|
||||
headerRightNavMoreColor: '#ffffff', //头部右侧更多下拉列表字体色,
|
||||
headerRightToolColor: '#bbe3df', //头部缩放按钮样式,
|
||||
headerLogoBg: '#e694bd', //logo背景颜色,
|
||||
headerLogoColor: '#ffffff', //logo字体颜色,
|
||||
leftMenuNavMore: 'rgb(191, 187, 187)', //左侧菜单更多下拉样式,
|
||||
leftMenuBg: '#1f1f1f', //左侧菜单背景,
|
||||
leftMenuBgThis: '#737373', //左侧菜单选中背景,
|
||||
leftMenuChildBg: 'rgba(0,0,0,.3)', //左侧菜单子菜单背景,
|
||||
leftMenuColor: 'rgb(191, 187, 187)', //左侧菜单字体颜色,
|
||||
leftMenuColorThis: '#ffffff', //左侧菜单选中字体颜色,
|
||||
tabActiveColor: '#ffa4d1', //tab选项卡选中颜色,
|
||||
},
|
||||
{
|
||||
headerRightBg: '#1aa094', //头部右侧背景色
|
||||
headerRightBgThis: '#197971', //头部右侧选中背景色,
|
||||
headerRightColor: 'rgba(255,255,255,.7)', //头部右侧字体颜色,
|
||||
headerRightChildColor: '#676767', //头部右侧下拉字体颜色,
|
||||
headerRightColorThis: '#ffffff', //头部右侧鼠标选中,
|
||||
headerRightNavMore: 'rgba(255,255,255,.7)', //头部右侧更多下拉颜色,
|
||||
headerRightNavMoreBg: '#1aa094', //头部右侧更多下拉列表选中背景色,
|
||||
headerRightNavMoreColor: '#ffffff', //头部右侧更多下拉列表字体色,
|
||||
headerRightToolColor: '#bbe3df', //头部缩放按钮样式,
|
||||
headerLogoBg: '#0c0c0c', //logo背景颜色,
|
||||
headerLogoColor: '#ffffff', //logo字体颜色,
|
||||
leftMenuNavMore: 'rgb(191, 187, 187)', //左侧菜单更多下拉样式,
|
||||
leftMenuBg: '#23262e', //左侧菜单背景,
|
||||
leftMenuBgThis: '#1aa094', //左侧菜单选中背景,
|
||||
leftMenuChildBg: 'rgba(0,0,0,.3)', //左侧菜单子菜单背景,
|
||||
leftMenuColor: 'rgb(191, 187, 187)', //左侧菜单字体颜色,
|
||||
leftMenuColorThis: '#ffffff', //左侧菜单选中字体颜色,
|
||||
tabActiveColor: '#1aa094', //tab选项卡选中颜色,
|
||||
},
|
||||
{
|
||||
headerRightBg: '#1e9fff', //头部右侧背景色
|
||||
headerRightBgThis: '#0069b7', //头部右侧选中背景色,
|
||||
headerRightColor: 'rgba(255,255,255,.7)', //头部右侧字体颜色,
|
||||
headerRightChildColor: '#676767', //头部右侧下拉字体颜色,
|
||||
headerRightColorThis: '#ffffff', //头部右侧鼠标选中,
|
||||
headerRightNavMore: 'rgba(255,255,255,.7)', //头部右侧更多下拉颜色,
|
||||
headerRightNavMoreBg: '#1e9fff', //头部右侧更多下拉列表选中背景色,
|
||||
headerRightNavMoreColor: '#ffffff', //头部右侧更多下拉列表字体色,
|
||||
headerRightToolColor: '#bbe3df', //头部缩放按钮样式,
|
||||
headerLogoBg: '#0c0c0c', //logo背景颜色,
|
||||
headerLogoColor: '#ffffff', //logo字体颜色,
|
||||
leftMenuNavMore: 'rgb(191, 187, 187)', //左侧菜单更多下拉样式,
|
||||
leftMenuBg: '#1f1f1f', //左侧菜单背景,
|
||||
leftMenuBgThis: '#1e9fff', //左侧菜单选中背景,
|
||||
leftMenuChildBg: 'rgba(0,0,0,.3)', //左侧菜单子菜单背景,
|
||||
leftMenuColor: 'rgb(191, 187, 187)', //左侧菜单字体颜色,
|
||||
leftMenuColorThis: '#ffffff', //左侧菜单选中字体颜色,
|
||||
tabActiveColor: '#1e9fff', //tab选项卡选中颜色,
|
||||
},
|
||||
{
|
||||
headerRightBg: '#ffb800', //头部右侧背景色
|
||||
headerRightBgThis: '#d09600', //头部右侧选中背景色,
|
||||
headerRightColor: 'rgba(255,255,255,.7)', //头部右侧字体颜色,
|
||||
headerRightChildColor: '#676767', //头部右侧下拉字体颜色,
|
||||
headerRightColorThis: '#ffffff', //头部右侧鼠标选中,
|
||||
headerRightNavMore: 'rgba(255,255,255,.7)', //头部右侧更多下拉颜色,
|
||||
headerRightNavMoreBg: '#d09600', //头部右侧更多下拉列表选中背景色,
|
||||
headerRightNavMoreColor: '#ffffff', //头部右侧更多下拉列表字体色,
|
||||
headerRightToolColor: '#bbe3df', //头部缩放按钮样式,
|
||||
headerLogoBg: '#243346', //logo背景颜色,
|
||||
headerLogoColor: '#ffffff', //logo字体颜色,
|
||||
leftMenuNavMore: 'rgb(191, 187, 187)', //左侧菜单更多下拉样式,
|
||||
leftMenuBg: '#2f4056', //左侧菜单背景,
|
||||
leftMenuBgThis: '#8593a7', //左侧菜单选中背景,
|
||||
leftMenuChildBg: 'rgba(0,0,0,.3)', //左侧菜单子菜单背景,
|
||||
leftMenuColor: 'rgb(191, 187, 187)', //左侧菜单字体颜色,
|
||||
leftMenuColorThis: '#ffffff', //左侧菜单选中字体颜色,
|
||||
tabActiveColor: '#ffb800', //tab选项卡选中颜色,
|
||||
},
|
||||
{
|
||||
headerRightBg: '#e82121', //头部右侧背景色
|
||||
headerRightBgThis: '#ae1919', //头部右侧选中背景色,
|
||||
headerRightColor: 'rgba(255,255,255,.7)', //头部右侧字体颜色,
|
||||
headerRightChildColor: '#676767', //头部右侧下拉字体颜色,
|
||||
headerRightColorThis: '#ffffff', //头部右侧鼠标选中,
|
||||
headerRightNavMore: 'rgba(255,255,255,.7)', //头部右侧更多下拉颜色,
|
||||
headerRightNavMoreBg: '#ae1919', //头部右侧更多下拉列表选中背景色,
|
||||
headerRightNavMoreColor: '#ffffff', //头部右侧更多下拉列表字体色,
|
||||
headerRightToolColor: '#bbe3df', //头部缩放按钮样式,
|
||||
headerLogoBg: '#0c0c0c', //logo背景颜色,
|
||||
headerLogoColor: '#ffffff', //logo字体颜色,
|
||||
leftMenuNavMore: 'rgb(191, 187, 187)', //左侧菜单更多下拉样式,
|
||||
leftMenuBg: '#1f1f1f', //左侧菜单背景,
|
||||
leftMenuBgThis: '#3b3f4b', //左侧菜单选中背景,
|
||||
leftMenuChildBg: 'rgba(0,0,0,.3)', //左侧菜单子菜单背景,
|
||||
leftMenuColor: 'rgb(191, 187, 187)', //左侧菜单字体颜色,
|
||||
leftMenuColorThis: '#ffffff', //左侧菜单选中字体颜色,
|
||||
tabActiveColor: '#e82121', //tab选项卡选中颜色,
|
||||
},
|
||||
{
|
||||
headerRightBg: '#963885', //头部右侧背景色
|
||||
headerRightBgThis: '#772c6a', //头部右侧选中背景色,
|
||||
headerRightColor: 'rgba(255,255,255,.7)', //头部右侧字体颜色,
|
||||
headerRightChildColor: '#676767', //头部右侧下拉字体颜色,
|
||||
headerRightColorThis: '#ffffff', //头部右侧鼠标选中,
|
||||
headerRightNavMore: 'rgba(255,255,255,.7)', //头部右侧更多下拉颜色,
|
||||
headerRightNavMoreBg: '#772c6a', //头部右侧更多下拉列表选中背景色,
|
||||
headerRightNavMoreColor: '#ffffff', //头部右侧更多下拉列表字体色,
|
||||
headerRightToolColor: '#bbe3df', //头部缩放按钮样式,
|
||||
headerLogoBg: '#243346', //logo背景颜色,
|
||||
headerLogoColor: '#ffffff', //logo字体颜色,
|
||||
leftMenuNavMore: 'rgb(191, 187, 187)', //左侧菜单更多下拉样式,
|
||||
leftMenuBg: '#2f4056', //左侧菜单背景,
|
||||
leftMenuBgThis: '#586473', //左侧菜单选中背景,
|
||||
leftMenuChildBg: 'rgba(0,0,0,.3)', //左侧菜单子菜单背景,
|
||||
leftMenuColor: 'rgb(191, 187, 187)', //左侧菜单字体颜色,
|
||||
leftMenuColorThis: '#ffffff', //左侧菜单选中字体颜色,
|
||||
tabActiveColor: '#963885', //tab选项卡选中颜色,
|
||||
},
|
||||
{
|
||||
headerRightBg: '#2D8CF0', //头部右侧背景色
|
||||
headerRightBgThis: '#0069b7', //头部右侧选中背景色,
|
||||
headerRightColor: 'rgba(255,255,255,.7)', //头部右侧字体颜色,
|
||||
headerRightChildColor: '#676767', //头部右侧下拉字体颜色,
|
||||
headerRightColorThis: '#ffffff', //头部右侧鼠标选中,
|
||||
headerRightNavMore: 'rgba(255,255,255,.7)', //头部右侧更多下拉颜色,
|
||||
headerRightNavMoreBg: '#0069b7', //头部右侧更多下拉列表选中背景色,
|
||||
headerRightNavMoreColor: '#ffffff', //头部右侧更多下拉列表字体色,
|
||||
headerRightToolColor: '#bbe3df', //头部缩放按钮样式,
|
||||
headerLogoBg: '#0069b7', //logo背景颜色,
|
||||
headerLogoColor: '#ffffff', //logo字体颜色,
|
||||
leftMenuNavMore: 'rgb(191, 187, 187)', //左侧菜单更多下拉样式,
|
||||
leftMenuBg: '#1f1f1f', //左侧菜单背景,
|
||||
leftMenuBgThis: '#2D8CF0', //左侧菜单选中背景,
|
||||
leftMenuChildBg: 'rgba(0,0,0,.3)', //左侧菜单子菜单背景,
|
||||
leftMenuColor: 'rgb(191, 187, 187)', //左侧菜单字体颜色,
|
||||
leftMenuColorThis: '#ffffff', //左侧菜单选中字体颜色,
|
||||
tabActiveColor: '#2d8cf0', //tab选项卡选中颜色,
|
||||
},
|
||||
{
|
||||
headerRightBg: '#ffb800', //头部右侧背景色
|
||||
headerRightBgThis: '#d09600', //头部右侧选中背景色,
|
||||
headerRightColor: 'rgba(255,255,255,.7)', //头部右侧字体颜色,
|
||||
headerRightChildColor: '#676767', //头部右侧下拉字体颜色,
|
||||
headerRightColorThis: '#ffffff', //头部右侧鼠标选中,
|
||||
headerRightNavMore: 'rgba(255,255,255,.7)', //头部右侧更多下拉颜色,
|
||||
headerRightNavMoreBg: '#d09600', //头部右侧更多下拉列表选中背景色,
|
||||
headerRightNavMoreColor: '#ffffff', //头部右侧更多下拉列表字体色,
|
||||
headerRightToolColor: '#bbe3df', //头部缩放按钮样式,
|
||||
headerLogoBg: '#d09600', //logo背景颜色,
|
||||
headerLogoColor: '#ffffff', //logo字体颜色,
|
||||
leftMenuNavMore: 'rgb(191, 187, 187)', //左侧菜单更多下拉样式,
|
||||
leftMenuBg: '#2f4056', //左侧菜单背景,
|
||||
leftMenuBgThis: '#3b3f4b', //左侧菜单选中背景,
|
||||
leftMenuChildBg: 'rgba(0,0,0,.3)', //左侧菜单子菜单背景,
|
||||
leftMenuColor: 'rgb(191, 187, 187)', //左侧菜单字体颜色,
|
||||
leftMenuColorThis: '#ffffff', //左侧菜单选中字体颜色,
|
||||
tabActiveColor: '#ffb800', //tab选项卡选中颜色,
|
||||
},
|
||||
{
|
||||
headerRightBg: '#e82121', //头部右侧背景色
|
||||
headerRightBgThis: '#ae1919', //头部右侧选中背景色,
|
||||
headerRightColor: 'rgba(255,255,255,.7)', //头部右侧字体颜色,
|
||||
headerRightChildColor: '#676767', //头部右侧下拉字体颜色,
|
||||
headerRightColorThis: '#ffffff', //头部右侧鼠标选中,
|
||||
headerRightNavMore: 'rgba(255,255,255,.7)', //头部右侧更多下拉颜色,
|
||||
headerRightNavMoreBg: '#ae1919', //头部右侧更多下拉列表选中背景色,
|
||||
headerRightNavMoreColor: '#ffffff', //头部右侧更多下拉列表字体色,
|
||||
headerRightToolColor: '#bbe3df', //头部缩放按钮样式,
|
||||
headerLogoBg: '#d91f1f', //logo背景颜色,
|
||||
headerLogoColor: '#ffffff', //logo字体颜色,
|
||||
leftMenuNavMore: 'rgb(191, 187, 187)', //左侧菜单更多下拉样式,
|
||||
leftMenuBg: '#1f1f1f', //左侧菜单背景,
|
||||
leftMenuBgThis: '#3b3f4b', //左侧菜单选中背景,
|
||||
leftMenuChildBg: 'rgba(0,0,0,.3)', //左侧菜单子菜单背景,
|
||||
leftMenuColor: 'rgb(191, 187, 187)', //左侧菜单字体颜色,
|
||||
leftMenuColorThis: '#ffffff', //左侧菜单选中字体颜色,
|
||||
tabActiveColor: '#e82121', //tab选项卡选中颜色,
|
||||
},
|
||||
{
|
||||
headerRightBg: '#963885', //头部右侧背景色
|
||||
headerRightBgThis: '#772c6a', //头部右侧选中背景色,
|
||||
headerRightColor: 'rgba(255,255,255,.7)', //头部右侧字体颜色,
|
||||
headerRightChildColor: '#676767', //头部右侧下拉字体颜色,
|
||||
headerRightColorThis: '#ffffff', //头部右侧鼠标选中,
|
||||
headerRightNavMore: 'rgba(255,255,255,.7)', //头部右侧更多下拉颜色,
|
||||
headerRightNavMoreBg: '#772c6a', //头部右侧更多下拉列表选中背景色,
|
||||
headerRightNavMoreColor: '#ffffff', //头部右侧更多下拉列表字体色,
|
||||
headerRightToolColor: '#bbe3df', //头部缩放按钮样式,
|
||||
headerLogoBg: '#772c6a', //logo背景颜色,
|
||||
headerLogoColor: '#ffffff', //logo字体颜色,
|
||||
leftMenuNavMore: 'rgb(191, 187, 187)', //左侧菜单更多下拉样式,
|
||||
leftMenuBg: '#2f4056', //左侧菜单背景,
|
||||
leftMenuBgThis: '#626f7f', //左侧菜单选中背景,
|
||||
leftMenuChildBg: 'rgba(0,0,0,.3)', //左侧菜单子菜单背景,
|
||||
leftMenuColor: 'rgb(191, 187, 187)', //左侧菜单字体颜色,
|
||||
leftMenuColorThis: '#ffffff', //左侧菜单选中字体颜色,
|
||||
tabActiveColor: '#963885', //tab选项卡选中颜色,
|
||||
}
|
||||
];
|
||||
if (bgcolorId === undefined) {
|
||||
return bgColorConfig;
|
||||
} else {
|
||||
return bgColorConfig[bgcolorId];
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 初始化
|
||||
* @param options
|
||||
*/
|
||||
render: function (options) {
|
||||
options.bgColorDefault = options.bgColorDefault || false;
|
||||
options.listen = options.listen || false;
|
||||
var bgcolorId = sessionStorage.getItem('layuiminiBgcolorId');
|
||||
if (bgcolorId === null || bgcolorId === undefined || bgcolorId === '') {
|
||||
bgcolorId = options.bgColorDefault;
|
||||
}
|
||||
miniTheme.buildThemeCss(bgcolorId);
|
||||
if (options.listen) miniTheme.listen(options);
|
||||
},
|
||||
|
||||
/**
|
||||
* 构建主题样式
|
||||
* @param bgcolorId
|
||||
* @returns {boolean}
|
||||
*/
|
||||
buildThemeCss: function (bgcolorId) {
|
||||
if (!bgcolorId) {
|
||||
return false;
|
||||
}
|
||||
var bgcolorData = miniTheme.config(bgcolorId);
|
||||
var styleHtml = '/*头部右侧背景色 headerRightBg */\n' +
|
||||
'.layui-layout-admin .layui-header {\n' +
|
||||
' background-color: ' + bgcolorData.headerRightBg + ' !important;\n' +
|
||||
'}\n' +
|
||||
'\n' +
|
||||
'/*头部右侧选中背景色 headerRightBgThis */\n' +
|
||||
'.layui-layout-admin .layui-header .layuimini-header-content > ul > .layui-nav-item.layui-this, .layuimini-tool i:hover {\n' +
|
||||
' background-color: ' + bgcolorData.headerRightBgThis + ' !important;\n' +
|
||||
'}\n' +
|
||||
'\n' +
|
||||
'/*头部右侧字体颜色 headerRightColor */\n' +
|
||||
'.layui-layout-admin .layui-header .layui-nav .layui-nav-item a {\n' +
|
||||
' color: ' + bgcolorData.headerRightColor + ';\n' +
|
||||
'}\n' +
|
||||
'/**头部右侧下拉字体颜色 headerRightChildColor */\n' +
|
||||
'.layui-layout-admin .layui-header .layui-nav .layui-nav-item .layui-nav-child a {\n' +
|
||||
' color: ' + bgcolorData.headerRightChildColor + '!important;\n' +
|
||||
'}\n'+
|
||||
'\n' +
|
||||
'/*头部右侧鼠标选中 headerRightColorThis */\n' +
|
||||
'.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 {\n' +
|
||||
' color: ' + bgcolorData.headerRightColorThis + ' !important;\n' +
|
||||
'}\n' +
|
||||
'\n' +
|
||||
'/*头部右侧更多下拉颜色 headerRightNavMore */\n' +
|
||||
'.layui-header .layui-nav .layui-nav-more {\n' +
|
||||
' border-top-color: ' + bgcolorData.headerRightNavMore + ' !important;\n' +
|
||||
'}\n' +
|
||||
'\n' +
|
||||
'/*头部右侧更多下拉颜色 headerRightNavMore */\n' +
|
||||
'.layui-header .layui-nav .layui-nav-mored, .layui-header .layui-nav-itemed > a .layui-nav-more {\n' +
|
||||
' border-color: transparent transparent ' + bgcolorData.headerRightNavMore + ' !important;\n' +
|
||||
'}\n' +
|
||||
'\n' +
|
||||
'/**头部右侧更多下拉配置色 headerRightNavMoreBg headerRightNavMoreColor */\n' +
|
||||
'.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 {\n' +
|
||||
' background-color: ' + bgcolorData.headerRightNavMoreBg + ' !important;\n' +
|
||||
' color:' + bgcolorData.headerRightNavMoreColor + ' !important;\n' +
|
||||
'}\n' +
|
||||
'\n' +
|
||||
'/*头部缩放按钮样式 headerRightToolColor */\n' +
|
||||
'.layui-layout-admin .layui-header .layuimini-tool i {\n' +
|
||||
' color: ' + bgcolorData.headerRightToolColor + ';\n' +
|
||||
'}\n' +
|
||||
'\n' +
|
||||
'/*logo背景颜色 headerLogoBg */\n' +
|
||||
'.layui-layout-admin .layuimini-logo {\n' +
|
||||
' background-color: ' + bgcolorData.headerLogoBg + ' !important;\n' +
|
||||
'}\n' +
|
||||
'\n' +
|
||||
'/*logo字体颜色 headerLogoColor */\n' +
|
||||
'.layui-layout-admin .layuimini-logo h1 {\n' +
|
||||
' color: ' + bgcolorData.headerLogoColor + ';\n' +
|
||||
'}\n' +
|
||||
'\n' +
|
||||
'/*左侧菜单更多下拉样式 leftMenuNavMore */\n' +
|
||||
'.layuimini-menu-left .layui-nav .layui-nav-more,.layuimini-menu-left-zoom.layui-nav .layui-nav-more {\n' +
|
||||
' border-top-color: ' + bgcolorData.leftMenuNavMore + ';\n' +
|
||||
'}\n' +
|
||||
'\n' +
|
||||
'/*左侧菜单更多下拉样式 leftMenuNavMore */\n' +
|
||||
'.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 {\n' +
|
||||
' border-color: transparent transparent ' + bgcolorData.leftMenuNavMore + ' !important;\n' +
|
||||
'}\n' +
|
||||
'\n' +
|
||||
'/*左侧菜单背景 leftMenuBg */\n' +
|
||||
'.layui-side.layui-bg-black, .layui-side.layui-bg-black > .layuimini-menu-left > ul, .layuimini-menu-left-zoom > ul {\n' +
|
||||
' background-color: ' + bgcolorData.leftMenuBg + ' !important;\n' +
|
||||
'}\n' +
|
||||
'\n' +
|
||||
'/*左侧菜单选中背景 leftMenuBgThis */\n' +
|
||||
'.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 {\n' +
|
||||
' background-color: ' + bgcolorData.leftMenuBgThis + ' !important\n' +
|
||||
'}\n' +
|
||||
'\n' +
|
||||
'/*左侧菜单子菜单背景 leftMenuChildBg */\n' +
|
||||
'.layuimini-menu-left .layui-nav-itemed > .layui-nav-child{\n' +
|
||||
' background-color: ' + bgcolorData.leftMenuChildBg + ' !important;\n' +
|
||||
'}\n' +
|
||||
'\n' +
|
||||
'/*左侧菜单字体颜色 leftMenuColor */\n' +
|
||||
'.layuimini-menu-left .layui-nav .layui-nav-item a, .layuimini-menu-left-zoom.layui-nav .layui-nav-item a {\n' +
|
||||
' color: ' + bgcolorData.leftMenuColor + ' !important;\n' +
|
||||
'}\n' +
|
||||
'\n' +
|
||||
'/*左侧菜单选中字体颜色 leftMenuColorThis */\n' +
|
||||
'.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 {\n' +
|
||||
' color:' + bgcolorData.leftMenuColorThis + ' !important;\n' +
|
||||
'}\n' +
|
||||
'\n' +
|
||||
'/**tab选项卡选中颜色 tabActiveColor */\n' +
|
||||
'.layuimini-tab .layui-tab-title .layui-this .layuimini-tab-active {\n' +
|
||||
' background-color: ' + bgcolorData.tabActiveColor + ';\n' +
|
||||
'}\n';
|
||||
$('#layuimini-bg-color').html(styleHtml);
|
||||
},
|
||||
|
||||
/**
|
||||
* 构建主题选择html
|
||||
* @param options
|
||||
* @returns {string}
|
||||
*/
|
||||
buildBgColorHtml: function (options) {
|
||||
options.bgColorDefault = options.bgColorDefault || 0;
|
||||
var bgcolorId = parseInt(sessionStorage.getItem('layuiminiBgcolorId'));
|
||||
if (isNaN(bgcolorId)) bgcolorId = options.bgColorDefault;
|
||||
var bgColorConfig = miniTheme.config();
|
||||
var html = '';
|
||||
$.each(bgColorConfig, function (key, val) {
|
||||
if (key === bgcolorId) {
|
||||
html += '<li class="layui-this" data-select-bgcolor="' + key + '">\n';
|
||||
} else {
|
||||
html += '<li data-select-bgcolor="' + key + '">\n';
|
||||
}
|
||||
html += '<a href="javascript:;" data-skin="skin-blue" style="" class="clearfix full-opacity-hover">\n' +
|
||||
'<div><span style="display:block; width: 20%; float: left; height: 12px; background: ' + val.headerLogoBg + ';"></span><span style="display:block; width: 80%; float: left; height: 12px; background: ' + val.headerRightBg + ';"></span></div>\n' +
|
||||
'<div><span style="display:block; width: 20%; float: left; height: 40px; background: ' + val.leftMenuBg + ';"></span><span style="display:block; width: 80%; float: left; height: 40px; background: #ffffff;"></span></div>\n' +
|
||||
'</a>\n' +
|
||||
'</li>';
|
||||
});
|
||||
return html;
|
||||
},
|
||||
|
||||
/**
|
||||
* 监听
|
||||
* @param options
|
||||
*/
|
||||
listen: function (options) {
|
||||
$('body').on('click', '[data-bgcolor]', function () {
|
||||
var loading = layer.load(0, {shade: false, time: 2 * 1000});
|
||||
var clientHeight = (document.documentElement.clientHeight) - 60;
|
||||
var bgColorHtml = miniTheme.buildBgColorHtml(options);
|
||||
var html = '<div class="layuimini-color">\n' +
|
||||
'<div class="color-title">\n' +
|
||||
'<span>配色方案</span>\n' +
|
||||
'</div>\n' +
|
||||
'<div class="color-content">\n' +
|
||||
'<ul>\n' + bgColorHtml + '</ul>\n' +
|
||||
'</div>\n' +
|
||||
'<div class="more-menu-list">\n' +
|
||||
'<a class="more-menu-item" href="https://api.iyuu.cn/docs.php" target="_blank"><i class="layui-icon layui-icon-read" style="font-size: 19px;"></i> 开发文档</a>\n' +
|
||||
'<a class="more-menu-item" href="https://github.com/ledccn/IYUUAutoReseed" target="_blank"><i class="layui-icon layui-icon-tabs" style="font-size: 16px;"></i> 开源地址</a>\n' +
|
||||
'<a class="more-menu-item" href="http://www.iyuu.cn" target="_blank"><i class="layui-icon layui-icon-theme"></i> 官方网站</a>\n' +
|
||||
'</div>' +
|
||||
'</div>';
|
||||
layer.open({
|
||||
type: 1,
|
||||
title: false,
|
||||
closeBtn: 0,
|
||||
shade: 0.2,
|
||||
anim: 2,
|
||||
shadeClose: true,
|
||||
id: 'layuiminiBgColor',
|
||||
area: ['340px', clientHeight + 'px'],
|
||||
offset: 'rb',
|
||||
content: html,
|
||||
success: function (index, layero) {
|
||||
},
|
||||
end: function () {
|
||||
$('.layuimini-select-bgcolor').removeClass('layui-this');
|
||||
}
|
||||
});
|
||||
layer.close(loading);
|
||||
});
|
||||
|
||||
$('body').on('click', '[data-select-bgcolor]', 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);
|
||||
miniTheme.render({
|
||||
bgColorDefault: bgcolorId,
|
||||
listen: false,
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
exports("miniTheme", miniTheme);
|
||||
|
||||
})
|
||||
;
|
40
public/js/lay-module/layuimini/miniTongji.js
Normal file
40
public/js/lay-module/layuimini/miniTongji.js
Normal file
|
@ -0,0 +1,40 @@
|
|||
/**
|
||||
* date:2020/03/01
|
||||
* author:Mr.Chung
|
||||
* version:2.0
|
||||
* description:layuimini 统计框架扩展
|
||||
*/
|
||||
layui.define(["jquery"], function (exports) {
|
||||
var $ = layui.$;
|
||||
|
||||
var miniTongji = {
|
||||
|
||||
/**
|
||||
* 初始化
|
||||
* @param options
|
||||
*/
|
||||
render: function (options) {
|
||||
options.specific = options.specific || false;
|
||||
options.domains = options.domains || [];
|
||||
var domain = window.location.hostname;
|
||||
if (options.specific === false || (options.specific === true && options.domains.indexOf(domain) >=0)) {
|
||||
miniTongji.listen();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 监听统计代码
|
||||
*/
|
||||
listen: function () {
|
||||
var _hmt = _hmt || [];
|
||||
(function () {
|
||||
var hm = document.createElement("script");
|
||||
hm.src = "https://hm.baidu.com/hm.js?d97abf6d61c21d773f97835defbdef4e";
|
||||
var s = document.getElementsByTagName("script")[0];
|
||||
s.parentNode.insertBefore(hm, s);
|
||||
})();
|
||||
}
|
||||
};
|
||||
|
||||
exports("miniTongji", miniTongji);
|
||||
});
|
79
public/js/lay-module/step-lay/step.css
Normal file
79
public/js/lay-module/step-lay/step.css
Normal file
|
@ -0,0 +1,79 @@
|
|||
.lay-step {
|
||||
font-size: 0;
|
||||
width: 400px;
|
||||
margin: 0 auto;
|
||||
max-width: 100%;
|
||||
padding-left: 200px;
|
||||
}
|
||||
|
||||
.step-item {
|
||||
display: inline-block;
|
||||
line-height: 26px;
|
||||
position: relative;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.step-item-tail {
|
||||
width: 100%;
|
||||
padding: 0 10px;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 13px;
|
||||
}
|
||||
|
||||
.step-item-tail i {
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
height: 1px;
|
||||
vertical-align: top;
|
||||
background: #c2c2c2;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.step-item-tail .step-item-tail-done {
|
||||
background: #009688;
|
||||
}
|
||||
|
||||
.step-item-head {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
height: 26px;
|
||||
width: 26px;
|
||||
text-align: center;
|
||||
vertical-align: top;
|
||||
color: #009688;
|
||||
border: 1px solid #009688;
|
||||
border-radius: 50%;
|
||||
background: #ffffff;
|
||||
}
|
||||
|
||||
.step-item-head.step-item-head-active {
|
||||
background: #009688;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.step-item-main {
|
||||
display: block;
|
||||
position: relative;
|
||||
margin-left: -50%;
|
||||
margin-right: 50%;
|
||||
padding-left: 26px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.step-item-main-title {
|
||||
font-weight: bolder;
|
||||
color: #555555;
|
||||
}
|
||||
|
||||
.step-item-main-desc {
|
||||
color: #aaaaaa;
|
||||
}
|
||||
|
||||
.lay-step + [carousel-item]:before {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.lay-step + [carousel-item] > * {
|
||||
background-color: transparent;
|
||||
}
|
101
public/js/lay-module/step-lay/step.js
Normal file
101
public/js/lay-module/step-lay/step.js
Normal file
|
@ -0,0 +1,101 @@
|
|||
layui.define(['layer', 'carousel'], function (exports) {
|
||||
var $ = layui.jquery;
|
||||
var layer = layui.layer;
|
||||
var carousel = layui.carousel;
|
||||
|
||||
// 添加步骤条dom节点
|
||||
var renderDom = function (elem, stepItems, postion) {
|
||||
var stepDiv = '<div class="lay-step">';
|
||||
for (var i = 0; i < stepItems.length; i++) {
|
||||
stepDiv += '<div class="step-item">';
|
||||
// 线
|
||||
if (i < (stepItems.length - 1)) {
|
||||
if (i < postion) {
|
||||
stepDiv += '<div class="step-item-tail"><i class="step-item-tail-done"></i></div>';
|
||||
} else {
|
||||
stepDiv += '<div class="step-item-tail"><i class=""></i></div>';
|
||||
}
|
||||
}
|
||||
|
||||
// 数字
|
||||
var number = stepItems[i].number;
|
||||
if (!number) {
|
||||
number = i + 1;
|
||||
}
|
||||
if (i == postion) {
|
||||
stepDiv += '<div class="step-item-head step-item-head-active"><i class="layui-icon">' + number + '</i></div>';
|
||||
} else if (i < postion) {
|
||||
stepDiv += '<div class="step-item-head"><i class="layui-icon layui-icon-ok"></i></div>';
|
||||
} else {
|
||||
stepDiv += '<div class="step-item-head "><i class="layui-icon">' + number + '</i></div>';
|
||||
}
|
||||
|
||||
// 标题和描述
|
||||
var title = stepItems[i].title;
|
||||
var desc = stepItems[i].desc;
|
||||
if (title || desc) {
|
||||
stepDiv += '<div class="step-item-main">';
|
||||
if (title) {
|
||||
stepDiv += '<div class="step-item-main-title">' + title + '</div>';
|
||||
}
|
||||
if (desc) {
|
||||
stepDiv += '<div class="step-item-main-desc">' + desc + '</div>';
|
||||
}
|
||||
stepDiv += '</div>';
|
||||
}
|
||||
stepDiv += '</div>';
|
||||
}
|
||||
stepDiv += '</div>';
|
||||
|
||||
$(elem).prepend(stepDiv);
|
||||
|
||||
// 计算每一个条目的宽度
|
||||
var bfb = 100 / stepItems.length;
|
||||
$('.step-item').css('width', bfb + '%');
|
||||
};
|
||||
|
||||
var step = {
|
||||
// 渲染步骤条
|
||||
render: function (param) {
|
||||
param.indicator = 'none'; // 不显示指示器
|
||||
param.arrow = 'always'; // 始终显示箭头
|
||||
param.autoplay = false; // 关闭自动播放
|
||||
if (!param.stepWidth) {
|
||||
param.stepWidth = '400px';
|
||||
}
|
||||
|
||||
// 渲染轮播图
|
||||
carousel.render(param);
|
||||
|
||||
// 渲染步骤条
|
||||
var stepItems = param.stepItems;
|
||||
renderDom(param.elem, stepItems, 0);
|
||||
$('.lay-step').css('width', param.stepWidth);
|
||||
|
||||
//监听轮播切换事件
|
||||
carousel.on('change(' + param.filter + ')', function (obj) {
|
||||
$(param.elem).find('.lay-step').remove();
|
||||
renderDom(param.elem, stepItems, obj.index);
|
||||
$('.lay-step').css('width', param.stepWidth);
|
||||
});
|
||||
|
||||
// 隐藏左右箭头按钮
|
||||
$(param.elem).find('.layui-carousel-arrow').css('display', 'none');
|
||||
|
||||
// 去掉轮播图的背景颜色
|
||||
$(param.elem).css('background-color', 'transparent');
|
||||
},
|
||||
// 下一步
|
||||
next: function (elem) {
|
||||
$(elem).find('.layui-carousel-arrow[lay-type=add]').trigger('click');
|
||||
},
|
||||
// 上一步
|
||||
pre: function (elem) {
|
||||
$(elem).find('.layui-carousel-arrow[lay-type=sub]').trigger('click');
|
||||
}
|
||||
};
|
||||
|
||||
layui.link(layui.cache.base + 'step-lay/step.css');
|
||||
|
||||
exports('step', step);
|
||||
});
|
272
public/js/lay-module/tableSelect/tableSelect.js
Normal file
272
public/js/lay-module/tableSelect/tableSelect.js
Normal file
|
@ -0,0 +1,272 @@
|
|||
layui.define(['table', 'jquery', 'form'], function (exports) {
|
||||
"use strict";
|
||||
|
||||
var MOD_NAME = 'tableSelect',
|
||||
$ = layui.jquery,
|
||||
table = layui.table,
|
||||
form = layui.form;
|
||||
var tableSelect = function () {
|
||||
this.v = '1.1.0';
|
||||
};
|
||||
|
||||
/**
|
||||
* 初始化表格选择器
|
||||
*/
|
||||
tableSelect.prototype.render = function (opt) {
|
||||
var elem = $(opt.elem);
|
||||
var tableDone = opt.table.done || function(){};
|
||||
|
||||
//默认设置
|
||||
opt.searchKey = opt.searchKey || 'keyword';
|
||||
opt.searchPlaceholder = opt.searchPlaceholder || '关键词搜索';
|
||||
opt.checkedKey = opt.checkedKey;
|
||||
opt.table.page = opt.table.page || true;
|
||||
opt.table.height = opt.height || 315;
|
||||
|
||||
//最小宽度
|
||||
opt.width = opt.width || '530';
|
||||
|
||||
//多搜索条件
|
||||
opt.searchType = opt.searchType || 'one';
|
||||
opt.searchList = opt.searchList || [{key: opt.searchKey, placeholder: opt.searchPlaceholder}];
|
||||
|
||||
elem.off('click').on('click', function(e) {
|
||||
e.stopPropagation();
|
||||
|
||||
if($('div.tableSelect').length >= 1){
|
||||
return false;
|
||||
}
|
||||
|
||||
var t = elem.offset().top + elem.outerHeight()+"px";
|
||||
var l = elem.offset().left +"px";
|
||||
var tableName = "tableSelect_table_" + new Date().getTime();
|
||||
var tableBox = '<div class="tableSelect layui-anim layui-anim-upbit" style="left:'+l+';top:'+t+';border: 1px solid #d2d2d2;background-color: #fff;box-shadow: 0 2px 4px rgba(0,0,0,.12);padding:10px 10px 0 10px;position: absolute;z-index:66666666;margin: 5px 0;border-radius: 2px;min-width:'+opt.width+'px;">';
|
||||
tableBox += '<div class="tableSelectBar">';
|
||||
tableBox += '<form class="layui-form" action="" style="display:inline-block;">';
|
||||
|
||||
//判断是否多搜索条件
|
||||
if(opt.searchType == 'more'){
|
||||
$.each(opt.searchList, function (index, item) {
|
||||
tableBox += '<input style="display:inline-block;width:190px;height:30px;vertical-align:middle;margin-right:-1px;border: 1px solid #C9C9C9;" type="text" name="'+item.searchKey+'" placeholder="'+item.searchPlaceholder+'" autocomplete="off" class="layui-input">';
|
||||
});
|
||||
}else{
|
||||
tableBox += '<input style="display:inline-block;width:190px;height:30px;vertical-align:middle;margin-right:-1px;border: 1px solid #C9C9C9;" type="text" name="'+opt.searchKey+'" placeholder="'+opt.searchPlaceholder+'" autocomplete="off" class="layui-input">';
|
||||
}
|
||||
|
||||
tableBox += '<button class="layui-btn layui-btn-sm layui-btn-primary tableSelect_btn_search" lay-submit lay-filter="tableSelect_btn_search"><i class="layui-icon layui-icon-search"></i></button>';
|
||||
tableBox += '</form>';
|
||||
tableBox += '<button style="float:right;" class="layui-btn layui-btn-sm tableSelect_btn_select">选择<span></span></button>';
|
||||
tableBox += '</div>';
|
||||
tableBox += '<table id="'+tableName+'" lay-filter="'+tableName+'"></table>';
|
||||
tableBox += '</div>';
|
||||
tableBox = $(tableBox);
|
||||
$('body').append(tableBox);
|
||||
|
||||
//数据缓存
|
||||
var checkedData = [];
|
||||
|
||||
//渲染TABLE
|
||||
opt.table.elem = "#"+tableName;
|
||||
opt.table.id = tableName;
|
||||
opt.table.done = function(res, curr, count){
|
||||
defaultChecked(res, curr, count);
|
||||
setChecked(res, curr, count);
|
||||
tableDone(res, curr, count);
|
||||
};
|
||||
var tableSelect_table = table.render(opt.table);
|
||||
|
||||
//分页选中保存数组
|
||||
table.on('radio('+tableName+')', function(obj){
|
||||
if(opt.checkedKey){
|
||||
checkedData = table.checkStatus(tableName).data
|
||||
}
|
||||
updataButton(table.checkStatus(tableName).data.length)
|
||||
})
|
||||
table.on('checkbox('+tableName+')', function(obj){
|
||||
if(opt.checkedKey){
|
||||
if(obj.checked){
|
||||
for (var i=0;i<table.checkStatus(tableName).data.length;i++){
|
||||
checkedData.push(table.checkStatus(tableName).data[i])
|
||||
}
|
||||
}else{
|
||||
if(obj.type=='all'){
|
||||
for (var j=0;j<table.cache[tableName].length;j++) {
|
||||
for (var i=0;i<checkedData.length;i++){
|
||||
if(checkedData[i][opt.checkedKey] == table.cache[tableName][j][opt.checkedKey]){
|
||||
checkedData.splice(i,1)
|
||||
}
|
||||
}
|
||||
}
|
||||
}else{
|
||||
//因为LAYUI问题,操作到变化全选状态时获取到的obj为空,这里用函数获取未选中的项。
|
||||
function nu (){
|
||||
var noCheckedKey = '';
|
||||
for (var i=0;i<table.cache[tableName].length;i++){
|
||||
if(!table.cache[tableName][i].LAY_CHECKED){
|
||||
noCheckedKey = table.cache[tableName][i][opt.checkedKey];
|
||||
}
|
||||
}
|
||||
return noCheckedKey
|
||||
}
|
||||
var noCheckedKey = obj.data[opt.checkedKey] || nu();
|
||||
for (var i=0;i<checkedData.length;i++){
|
||||
if(checkedData[i][opt.checkedKey] == noCheckedKey){
|
||||
checkedData.splice(i,1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
checkedData = uniqueObjArray(checkedData, opt.checkedKey);
|
||||
updataButton(checkedData.length)
|
||||
}else{
|
||||
updataButton(table.checkStatus(tableName).data.length)
|
||||
}
|
||||
});
|
||||
|
||||
//渲染表格后选中
|
||||
function setChecked (res, curr, count) {
|
||||
for(var i=0;i<res.data.length;i++){
|
||||
for (var j=0;j<checkedData.length;j++) {
|
||||
if(res.data[i][opt.checkedKey] == checkedData[j][opt.checkedKey]){
|
||||
res.data[i].LAY_CHECKED = true;
|
||||
var index= res.data[i]['LAY_TABLE_INDEX'];
|
||||
var checkbox = $('#'+tableName+'').next().find('tr[data-index=' + index + '] input[type="checkbox"]');
|
||||
checkbox.prop('checked', true).next().addClass('layui-form-checked');
|
||||
var radio = $('#'+tableName+'').next().find('tr[data-index=' + index + '] input[type="radio"]');
|
||||
radio.prop('checked', true).next().addClass('layui-form-radioed').find("i").html('');
|
||||
}
|
||||
}
|
||||
}
|
||||
var checkStatus = table.checkStatus(tableName);
|
||||
if(checkStatus.isAll){
|
||||
$('#'+tableName+'').next().find('.layui-table-header th[data-field="0"] input[type="checkbox"]').prop('checked', true);
|
||||
$('#'+tableName+'').next().find('.layui-table-header th[data-field="0"] input[type="checkbox"]').next().addClass('layui-form-checked');
|
||||
}
|
||||
updataButton(checkedData.length)
|
||||
}
|
||||
|
||||
//写入默认选中值(puash checkedData)
|
||||
function defaultChecked (res, curr, count){
|
||||
if(opt.checkedKey && elem.attr('ts-selected')){
|
||||
var selected = elem.attr('ts-selected').split(",");
|
||||
for(var i=0;i<res.data.length;i++){
|
||||
for(var j=0;j<selected.length;j++){
|
||||
if(res.data[i][opt.checkedKey] == selected[j]){
|
||||
checkedData.push(res.data[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
checkedData = uniqueObjArray(checkedData, opt.checkedKey);
|
||||
}
|
||||
}
|
||||
|
||||
//更新选中数量
|
||||
function updataButton (n) {
|
||||
tableBox.find('.tableSelect_btn_select span').html(n==0?'':'('+n+')')
|
||||
}
|
||||
|
||||
//数组去重
|
||||
function uniqueObjArray(arr, type){
|
||||
var newArr = [];
|
||||
var tArr = [];
|
||||
if(arr.length == 0){
|
||||
return arr;
|
||||
}else{
|
||||
if(type){
|
||||
for(var i=0;i<arr.length;i++){
|
||||
if(!tArr[arr[i][type]]){
|
||||
newArr.push(arr[i]);
|
||||
tArr[arr[i][type]] = true;
|
||||
}
|
||||
}
|
||||
return newArr;
|
||||
}else{
|
||||
for(var i=0;i<arr.length;i++){
|
||||
if(!tArr[arr[i]]){
|
||||
newArr.push(arr[i]);
|
||||
tArr[arr[i]] = true;
|
||||
}
|
||||
}
|
||||
return newArr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//FIX位置
|
||||
var overHeight = (elem.offset().top + elem.outerHeight() + tableBox.outerHeight() - $(window).scrollTop()) > $(window).height();
|
||||
var overWidth = (elem.offset().left + tableBox.outerWidth()) > $(window).width();
|
||||
overHeight && tableBox.css({'top':'auto','bottom':'0px'});
|
||||
overWidth && tableBox.css({'left':'auto','right':'5px'})
|
||||
|
||||
//关键词搜索
|
||||
form.on('submit(tableSelect_btn_search)', function(data){
|
||||
tableSelect_table.reload({
|
||||
where: data.field,
|
||||
page: {
|
||||
curr: 1
|
||||
}
|
||||
});
|
||||
return false;
|
||||
});
|
||||
|
||||
//双击行选中
|
||||
table.on('rowDouble('+tableName+')', function(obj){
|
||||
var checkStatus = {data:[obj.data]};
|
||||
selectDone(checkStatus);
|
||||
})
|
||||
|
||||
//按钮选中
|
||||
tableBox.find('.tableSelect_btn_select').on('click', function() {
|
||||
var checkStatus = table.checkStatus(tableName);
|
||||
if(checkedData.length > 1){
|
||||
checkStatus.data = checkedData;
|
||||
}
|
||||
selectDone(checkStatus);
|
||||
})
|
||||
|
||||
//写值回调和关闭
|
||||
function selectDone (checkStatus){
|
||||
if(opt.checkedKey){
|
||||
var selected = [];
|
||||
for(var i=0;i<checkStatus.data.length;i++){
|
||||
selected.push(checkStatus.data[i][opt.checkedKey])
|
||||
}
|
||||
elem.attr("ts-selected",selected.join(","));
|
||||
}
|
||||
opt.done(elem, checkStatus);
|
||||
tableBox.remove();
|
||||
delete table.cache[tableName];
|
||||
checkedData = [];
|
||||
}
|
||||
|
||||
//点击其他区域关闭
|
||||
$(document).mouseup(function(e){
|
||||
var userSet_con = $(''+opt.elem+',.tableSelect');
|
||||
if(!userSet_con.is(e.target) && userSet_con.has(e.target).length === 0){
|
||||
tableBox.remove();
|
||||
delete table.cache[tableName];
|
||||
checkedData = [];
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 隐藏选择器
|
||||
*/
|
||||
tableSelect.prototype.hide = function (opt) {
|
||||
$('.tableSelect').remove();
|
||||
}
|
||||
|
||||
//自动完成渲染
|
||||
var tableSelect = new tableSelect();
|
||||
|
||||
//FIX 滚动时错位
|
||||
if(window.top == window.self){
|
||||
$(window).scroll(function () {
|
||||
tableSelect.hide();
|
||||
});
|
||||
}
|
||||
|
||||
exports(MOD_NAME, tableSelect);
|
||||
})
|
18
public/js/lay-module/treetable-lay/treetable.css
Normal file
18
public/js/lay-module/treetable-lay/treetable.css
Normal file
|
@ -0,0 +1,18 @@
|
|||
.treeTable-empty {
|
||||
width: 20px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.treeTable-icon {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.treeTable-icon .layui-icon-triangle-d:before {
|
||||
content: "\e623";
|
||||
}
|
||||
|
||||
.treeTable-icon.open .layui-icon-triangle-d:before {
|
||||
content: "\e625";
|
||||
background-color: transparent;
|
||||
}
|
||||
|
206
public/js/lay-module/treetable-lay/treetable.js
Normal file
206
public/js/lay-module/treetable-lay/treetable.js
Normal file
|
@ -0,0 +1,206 @@
|
|||
layui.define(['layer', 'table'], function (exports) {
|
||||
var $ = layui.jquery;
|
||||
var layer = layui.layer;
|
||||
var table = layui.table;
|
||||
|
||||
var treetable = {
|
||||
// 渲染树形表格
|
||||
render: function (param) {
|
||||
// 检查参数
|
||||
if (!treetable.checkParam(param)) {
|
||||
return;
|
||||
}
|
||||
// 获取数据
|
||||
if (param.data) {
|
||||
treetable.init(param, param.data);
|
||||
} else {
|
||||
$.getJSON(param.url, param.where, function (res) {
|
||||
treetable.init(param, res.data);
|
||||
});
|
||||
}
|
||||
},
|
||||
// 渲染表格
|
||||
init: function (param, data) {
|
||||
var mData = [];
|
||||
var doneCallback = param.done;
|
||||
var tNodes = data;
|
||||
// 补上id和pid字段
|
||||
for (var i = 0; i < tNodes.length; i++) {
|
||||
var tt = tNodes[i];
|
||||
if (!tt.id) {
|
||||
if (!param.treeIdName) {
|
||||
layer.msg('参数treeIdName不能为空', {icon: 5});
|
||||
return;
|
||||
}
|
||||
tt.id = tt[param.treeIdName];
|
||||
}
|
||||
if (!tt.pid) {
|
||||
if (!param.treePidName) {
|
||||
layer.msg('参数treePidName不能为空', {icon: 5});
|
||||
return;
|
||||
}
|
||||
tt.pid = tt[param.treePidName];
|
||||
}
|
||||
}
|
||||
|
||||
// 对数据进行排序
|
||||
var sort = function (s_pid, data) {
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
if (data[i].pid == s_pid) {
|
||||
var len = mData.length;
|
||||
if (len > 0 && mData[len - 1].id == s_pid) {
|
||||
mData[len - 1].isParent = true;
|
||||
}
|
||||
mData.push(data[i]);
|
||||
sort(data[i].id, data);
|
||||
}
|
||||
}
|
||||
};
|
||||
sort(param.treeSpid, tNodes);
|
||||
|
||||
// 重写参数
|
||||
param.url = undefined;
|
||||
param.data = mData;
|
||||
param.page = {
|
||||
count: param.data.length,
|
||||
limit: param.data.length
|
||||
};
|
||||
param.cols[0][param.treeColIndex].templet = function (d) {
|
||||
var mId = d.id;
|
||||
var mPid = d.pid;
|
||||
var isDir = d.isParent;
|
||||
var emptyNum = treetable.getEmptyNum(mPid, mData);
|
||||
var iconHtml = '';
|
||||
for (var i = 0; i < emptyNum; i++) {
|
||||
iconHtml += '<span class="treeTable-empty"></span>';
|
||||
}
|
||||
if (isDir) {
|
||||
iconHtml += '<i class="layui-icon layui-icon-triangle-d"></i> <i class="layui-icon layui-icon-layer"></i>';
|
||||
} else {
|
||||
iconHtml += '<i class="layui-icon layui-icon-file"></i>';
|
||||
}
|
||||
iconHtml += ' ';
|
||||
var ttype = isDir ? 'dir' : 'file';
|
||||
var vg = '<span class="treeTable-icon open" lay-tid="' + mId + '" lay-tpid="' + mPid + '" lay-ttype="' + ttype + '">';
|
||||
return vg + iconHtml + d[param.cols[0][param.treeColIndex].field] + '</span>'
|
||||
};
|
||||
|
||||
param.done = function (res, curr, count) {
|
||||
$(param.elem).next().addClass('treeTable');
|
||||
$('.treeTable .layui-table-page').css('display', 'none');
|
||||
$(param.elem).next().attr('treeLinkage', param.treeLinkage);
|
||||
// 绑定事件换成对body绑定
|
||||
/*$('.treeTable .treeTable-icon').click(function () {
|
||||
treetable.toggleRows($(this), param.treeLinkage);
|
||||
});*/
|
||||
if (param.treeDefaultClose) {
|
||||
treetable.foldAll(param.elem);
|
||||
}
|
||||
if (doneCallback) {
|
||||
doneCallback(res, curr, count);
|
||||
}
|
||||
};
|
||||
|
||||
// 渲染表格
|
||||
table.render(param);
|
||||
},
|
||||
// 计算缩进的数量
|
||||
getEmptyNum: function (pid, data) {
|
||||
var num = 0;
|
||||
if (!pid) {
|
||||
return num;
|
||||
}
|
||||
var tPid;
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
if (pid == data[i].id) {
|
||||
num += 1;
|
||||
tPid = data[i].pid;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return num + treetable.getEmptyNum(tPid, data);
|
||||
},
|
||||
// 展开/折叠行
|
||||
toggleRows: function ($dom, linkage) {
|
||||
var type = $dom.attr('lay-ttype');
|
||||
if ('file' == type) {
|
||||
return;
|
||||
}
|
||||
var mId = $dom.attr('lay-tid');
|
||||
var isOpen = $dom.hasClass('open');
|
||||
if (isOpen) {
|
||||
$dom.removeClass('open');
|
||||
} else {
|
||||
$dom.addClass('open');
|
||||
}
|
||||
$dom.closest('tbody').find('tr').each(function () {
|
||||
var $ti = $(this).find('.treeTable-icon');
|
||||
var pid = $ti.attr('lay-tpid');
|
||||
var ttype = $ti.attr('lay-ttype');
|
||||
var tOpen = $ti.hasClass('open');
|
||||
if (mId == pid) {
|
||||
if (isOpen) {
|
||||
$(this).hide();
|
||||
if ('dir' == ttype && tOpen == isOpen) {
|
||||
$ti.trigger('click');
|
||||
}
|
||||
} else {
|
||||
$(this).show();
|
||||
if (linkage && 'dir' == ttype && tOpen == isOpen) {
|
||||
$ti.trigger('click');
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
// 检查参数
|
||||
checkParam: function (param) {
|
||||
if (!param.treeSpid && param.treeSpid != 0) {
|
||||
layer.msg('参数treeSpid不能为空', {icon: 5});
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!param.treeColIndex && param.treeColIndex != 0) {
|
||||
layer.msg('参数treeColIndex不能为空', {icon: 5});
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
// 展开所有
|
||||
expandAll: function (dom) {
|
||||
$(dom).next('.treeTable').find('.layui-table-body tbody tr').each(function () {
|
||||
var $ti = $(this).find('.treeTable-icon');
|
||||
var ttype = $ti.attr('lay-ttype');
|
||||
var tOpen = $ti.hasClass('open');
|
||||
if ('dir' == ttype && !tOpen) {
|
||||
$ti.trigger('click');
|
||||
}
|
||||
});
|
||||
},
|
||||
// 折叠所有
|
||||
foldAll: function (dom) {
|
||||
$(dom).next('.treeTable').find('.layui-table-body tbody tr').each(function () {
|
||||
var $ti = $(this).find('.treeTable-icon');
|
||||
var ttype = $ti.attr('lay-ttype');
|
||||
var tOpen = $ti.hasClass('open');
|
||||
if ('dir' == ttype && tOpen) {
|
||||
$ti.trigger('click');
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
layui.link(layui.cache.base + 'treetable-lay/treetable.css');
|
||||
|
||||
// 给图标列绑定事件
|
||||
$('body').on('click', '.treeTable .treeTable-icon', function () {
|
||||
var treeLinkage = $(this).parents('.treeTable').attr('treeLinkage');
|
||||
if ('true' == treeLinkage) {
|
||||
treetable.toggleRows($(this), true);
|
||||
} else {
|
||||
treetable.toggleRows($(this), false);
|
||||
}
|
||||
});
|
||||
|
||||
exports('treetable', treetable);
|
||||
});
|
BIN
public/js/lay-module/wangEditor/fonts/w-e-icon.woff
Normal file
BIN
public/js/lay-module/wangEditor/fonts/w-e-icon.woff
Normal file
Binary file not shown.
411
public/js/lay-module/wangEditor/wangEditor.css
Normal file
411
public/js/lay-module/wangEditor/wangEditor.css
Normal file
File diff suppressed because one or more lines are too long
4678
public/js/lay-module/wangEditor/wangEditor.js
Normal file
4678
public/js/lay-module/wangEditor/wangEditor.js
Normal file
File diff suppressed because one or more lines are too long
1
public/js/lay-module/wangEditor/wangEditor.min.css
vendored
Normal file
1
public/js/lay-module/wangEditor/wangEditor.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
4
public/js/lay-module/wangEditor/wangEditor.min.js
vendored
Normal file
4
public/js/lay-module/wangEditor/wangEditor.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
public/js/lay-module/wangEditor/wangEditor.min.js.map
Normal file
1
public/js/lay-module/wangEditor/wangEditor.min.js.map
Normal file
File diff suppressed because one or more lines are too long
7
public/lib/font-awesome-4.7.0/HELP-US-OUT.txt
Normal file
7
public/lib/font-awesome-4.7.0/HELP-US-OUT.txt
Normal file
|
@ -0,0 +1,7 @@
|
|||
I hope you love Font Awesome. If you've found it useful, please do me a favor and check out my latest project,
|
||||
Fort Awesome (https://fortawesome.com). It makes it easy to put the perfect icons on your website. Choose from our awesome,
|
||||
comprehensive icon sets or copy and paste your own.
|
||||
|
||||
Please. Check it out.
|
||||
|
||||
-Dave Gandy
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user