初始化版本库

This commit is contained in:
david 2021-02-02 15:48:07 +08:00
commit d1921a2753
700 changed files with 85048 additions and 0 deletions

2
.dockerignore Normal file
View File

@ -0,0 +1,2 @@
.git
*

17
.env.example Normal file
View 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
View File

@ -0,0 +1,9 @@
/.git
/.idea
/.vscode
/composer
/db
/composer.lock
*.bat
*.log
.env

1
.htaccess Normal file
View File

@ -0,0 +1 @@

36
README.md Normal file
View 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
View 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
View 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
View 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");
}
}
}
}

View 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;
}
}

View File

@ -0,0 +1,14 @@
<?php
namespace app\common\exception;
use Exception;
/**
* Class BusinessException
* @access private 常驻内存运行,禁止执行器调用
* @package app\common\exception
*/
class BusinessException extends Exception
{
}

View 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));
}
}

View 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
View 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' => []]);
}
}

View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View File

@ -0,0 +1 @@
!.gitignore

14
app/view/index/view.html Normal file
View 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
View File

@ -0,0 +1 @@
!.gitignore

10
bin/iyuu.php Normal file
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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

View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View File

@ -0,0 +1,5 @@
*.js linguist-language=JavaScript
*.css linguist-language=JavaScript
*.html linguist-language=JavaScript

1
public/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/.idea

12
public/404.html Normal file
View 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
View 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
View 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
View 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
View 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
}
]
}

View 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
View File

@ -0,0 +1,10 @@
{
"code": 1,
"msg": "上传成功",
"data": {
"url": [
"../images/logo.png",
"../images/captcha.jpg"
]
}
}

803
public/css/layuimini.css Normal file
View 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
View 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;}

View 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 157 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

BIN
public/images/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

179
public/index.html Normal file
View 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
View 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
View 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', // 省市县区三级联动下拉选择器
});

File diff suppressed because one or more lines are too long

View 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"
}
}
}
}
});
});

View 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">&#xe615;</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>&#xe603;</i> ' +
'<i class="layui-icon" id="' + PAGE_ID + '-next" data-index="2" next>&#xe602;</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);
});

File diff suppressed because it is too large Load Diff

View 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);
});

View 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);
});

View 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);
});

View 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);
})
;

View 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);
});

View 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;
}

View 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);
});

View 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('&#xe643;');
}
}
}
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);
})

View 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;
}

View 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 += '&nbsp;&nbsp;';
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);
});

Binary file not shown.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,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