作者 Karson

新增命令行一键生成API文档功能

新增插件绑定二级域名功能
新增加载JS公用模块
新增命令行创建插件自动生成菜单功能
新增后台菜单Fast.api.refreshmenu
新增后台菜单在数据变更后自动刷新的功能
新增require.min.js压缩版
新增从Headers中读取授权token的功能
新增Form.events.daterangepicker时间区别事件
新增Form表单提示成功和失败的回调事件
新增Fast.api.getrowbyid和Fast.api.getrowbyindex方法
新增commonsearch的find_in_set类型搜索
新增Menu::export的方法
新增php think api一键生成API文档功能
新增php think min的压缩参数和调试功能

优化API模块生产环境下错误信息的显示
优化移动端显示移除顶部Logo一行
优化bower.json和composer.json的版本依赖
优化插件管理列表显示
优化后台控制区多作的选项卡数据
优化CRUD生成的复选框样式及文字
优化规则管理的列表显示
优化第三方前端资源,移除冗余资源

修复在启用域名部署下的BUG
修复API初始化接口的BUG
修复会员积分日志模型BUG
修复多语言切换不存在的BUG
修复Backend.php中multi操作不触发模型事件的BUG
正在显示 78 个修改的文件 包含 2402 行增加1859 行删除
{
"directory" : "public/assets/libs"
"directory" : "public/assets/libs",
"ignoredDependencies": [
"file-saver",
"html2canvas",
"jspdf",
"jspdf-autotable"
]
}
\ No newline at end of file
... ...
... ... @@ -16,10 +16,12 @@ FastAdmin是一款基于ThinkPHP5+Bootstrap的极速后台开发框架。
* 基于`Bower`进行前端组件包管理
* 数据库表一键生成`CRUD`,包括控制器、模型、视图、JS、语言包、菜单等
* 一键压缩打包JS和CSS文件,一键CDN静态资源部署
* 一键生成API接口文档
* 强大的插件扩展功能,在线安装卸载升级插件
* 共用同一账号体系的Web端会员中心权限验证和API接口会员权限验证
* 二级域名部署支持,同时域名支持绑定到插件
* 多语言支持,服务端及客户端支持
* 强大的第三方插件支持(CMS、博客、文档生成)
* 强大的第三方模块支持(CMS、博客、文档生成)
* 整合第三方短信接口(阿里云、创蓝短信)
* 无缝整合第三方云存储(七牛、阿里云OSS、又拍云)功能
* 第三方登录(QQ、微信、微博)整合
... ...
... ... @@ -2,14 +2,17 @@
namespace app\admin\command;
use app\common\library\Menu;
use think\addons\AddonException;
use think\addons\Service;
use think\Config;
use think\console\Command;
use think\console\Input;
use think\console\input\Option;
use think\console\Output;
use think\Db;
use think\Exception;
use think\exception\PDOException;
class Addon extends Command
{
... ... @@ -63,14 +66,43 @@ class Addon extends Command
rmdirs($addonDir);
}
mkdir($addonDir);
mkdir($addonDir . DS . 'controller');
$menuList = Menu::export($name);
$createMenu = $this->getCreateMenu($menuList);
$prefix = Config::get('database.prefix');
$createTableSql = '';
try
{
$result = Db::query("SHOW CREATE TABLE `" . $prefix . $name . "`;");
if (isset($result[0]) && isset($result[0]['Create Table']))
{
$createTableSql = $result[0]['Create Table'];
}
}
catch (PDOException $e)
{
}
$data = [
'name' => $name,
'addon' => $name,
'addonClassName' => ucfirst($name)
'name' => $name,
'addon' => $name,
'addonClassName' => ucfirst($name),
'addonInstallMenu' => $createMenu ? "\$menu = " . var_export_short($createMenu, "\t") . ";\n\tMenu::create(\$menu);" : '',
'addonUninstallMenu' => $menuList ? 'Menu::delete("' . $name . '");' : '',
'addonEnableMenu' => $menuList ? 'Menu::enable("' . $name . '");' : '',
'addonDisableMenu' => $menuList ? 'Menu::disable("' . $name . '");' : '',
];
$this->writeToFile("addon", $data, $addonDir . ucfirst($name) . '.php');
$this->writeToFile("config", $data, $addonDir . 'config.php');
$this->writeToFile("info", $data, $addonDir . 'info.ini');
$this->writeToFile("controller", $data, $addonDir . 'controller' . DS . 'Index.php');
if ($createTableSql)
{
$createTableSql = str_replace("`" . $prefix, '`__PREFIX__', $createTableSql);
file_put_contents($addonDir . 'install.sql', $createTableSql);
}
$output->info("Create Successed!");
break;
case 'disable':
... ... @@ -257,6 +289,37 @@ class Addon extends Command
}
/**
* 获取创建菜单的数组
* @param array $menu
* @return array
*/
protected function getCreateMenu($menu)
{
$result = [];
foreach ($menu as $k => & $v)
{
$arr = [
'name' => $v['name'],
'title' => $v['title'],
];
if ($v['icon'] != 'fa fa-circle-o')
{
$arr['icon'] = $v['icon'];
}
if ($v['ismenu'])
{
$arr['ismenu'] = $v['ismenu'];
}
if (isset($v['childlist']) && $v['childlist'])
{
$arr['sublist'] = $this->getCreateMenu($v['childlist']);
}
$result[] = $arr;
}
return $result;
}
/**
* 写入到文件
* @param string $name
* @param array $data
... ...
... ... @@ -2,6 +2,7 @@
namespace addons\{%name%};
use app\common\library\Menu;
use think\Addons;
/**
... ... @@ -16,6 +17,7 @@ class {%addonClassName%} extends Addons
*/
public function install()
{
{%addonInstallMenu%}
return true;
}
... ... @@ -25,6 +27,7 @@ class {%addonClassName%} extends Addons
*/
public function uninstall()
{
{%addonUninstallMenu%}
return true;
}
... ... @@ -34,6 +37,7 @@ class {%addonClassName%} extends Addons
*/
public function enable()
{
{%addonEnableMenu%}
return true;
}
... ... @@ -43,6 +47,7 @@ class {%addonClassName%} extends Addons
*/
public function disable()
{
{%addonDisableMenu%}
return true;
}
... ...
<?php
namespace addons\{%addon%}\controller;
use think\addons\Controller;
class Index extends Controller
{
public function index()
{
$this->error("当前插件暂无前台页面");
}
}
... ...
name = {%name%}
title = 插件名称
title = 插件名称({%name%})
intro = FastAdmin插件
author = yourname
website = http://www.fastadmin.net
... ...
<?php
namespace app\admin\command;
use app\admin\command\Api\library\Builder;
use think\Config;
use think\console\Command;
use think\console\Input;
use think\console\input\Option;
use think\console\Output;
use think\Exception;
class Api extends Command
{
protected function configure()
{
$site = Config::get('site');
$this
->setName('api')
->addOption('url', 'u', Option::VALUE_OPTIONAL, 'default api url', '')
->addOption('module', 'm', Option::VALUE_OPTIONAL, 'module name(admin/index/api)', 'api')
->addOption('output', 'o', Option::VALUE_OPTIONAL, 'output index file name', 'api.html')
->addOption('template', 'e', Option::VALUE_OPTIONAL, '', 'index.html')
->addOption('force', 'f', Option::VALUE_OPTIONAL, 'force override general file', false)
->addOption('title', 't', Option::VALUE_OPTIONAL, 'document title', $site['name'])
->addOption('author', 'a', Option::VALUE_OPTIONAL, 'document author', $site['name'])
->addOption('class', 'c', Option::VALUE_OPTIONAL | Option::VALUE_IS_ARRAY, 'extend class', null)
->addOption('language', 'l', Option::VALUE_OPTIONAL, 'language', 'zh-cn')
->setDescription('Compress js and css file');
}
protected function execute(Input $input, Output $output)
{
$apiDir = __DIR__ . DS . 'Api' . DS;
$force = $input->getOption('force');
$url = $input->getOption('url');
$language = $input->getOption('language');
$langFile = $apiDir . 'lang' . DS . $language . '.php';
if (!is_file($langFile))
{
throw new Exception('language file not found');
}
$lang = include $langFile;
// 目标目录
$output_dir = ROOT_PATH . 'public' . DS;
$output_file = $output_dir . $input->getOption('output');
if (is_file($output_file) && !$force)
{
throw new Exception("api index file already exists!\nIf you need to rebuild again, use the parameter --force=true ");
}
// 模板文件
$template_dir = $apiDir . 'template' . DS;
$template_file = $template_dir . $input->getOption('template');
if (!is_file($template_file))
{
throw new Exception('template file not found');
}
// 额外的类
$classes = $input->getOption('class');
// 标题
$title = $input->getOption('title');
// 作者
$author = $input->getOption('author');
// 模块
$module = $input->getOption('module');
$moduleDir = APP_PATH . $module . DS;
if (!is_dir($moduleDir))
{
throw new Exception('module not found');
}
$controllerDir = $moduleDir . Config::get('url_controller_layer') . DS;
$files = new \RecursiveIteratorIterator(
new \RecursiveDirectoryIterator($controllerDir), \RecursiveIteratorIterator::LEAVES_ONLY
);
foreach ($files as $name => $file)
{
if (!$file->isDir())
{
$filePath = $file->getRealPath();
$classes[] = $this->get_class_from_file($filePath);
}
}
$config = [
'title' => $title,
'author' => $author,
'description' => '',
'apiurl' => $url,
];
$builder = new Builder($classes);
$content = $builder->render($template_file, ['config' => $config, 'lang' => $lang]);
if (!file_put_contents($output_file, $content))
{
throw new Exception('Cannot save the content to ' . $output_file);
}
$output->info("Build Successed!");
}
/**
* get full qualified class name
*
* @param string $path_to_file
* @author JBYRNE http://jarretbyrne.com/2015/06/197/
* @return string
*/
protected function get_class_from_file($path_to_file)
{
//Grab the contents of the file
$contents = file_get_contents($path_to_file);
//Start with a blank namespace and class
$namespace = $class = "";
//Set helper values to know that we have found the namespace/class token and need to collect the string values after them
$getting_namespace = $getting_class = false;
//Go through each token and evaluate it as necessary
foreach (token_get_all($contents) as $token)
{
//If this token is the namespace declaring, then flag that the next tokens will be the namespace name
if (is_array($token) && $token[0] == T_NAMESPACE)
{
$getting_namespace = true;
}
//If this token is the class declaring, then flag that the next tokens will be the class name
if (is_array($token) && $token[0] == T_CLASS)
{
$getting_class = true;
}
//While we're grabbing the namespace name...
if ($getting_namespace === true)
{
//If the token is a string or the namespace separator...
if (is_array($token) && in_array($token[0], [T_STRING, T_NS_SEPARATOR]))
{
//Append the token's value to the name of the namespace
$namespace .= $token[1];
}
else if ($token === ';')
{
//If the token is the semicolon, then we're done with the namespace declaration
$getting_namespace = false;
}
}
//While we're grabbing the class name...
if ($getting_class === true)
{
//If the token is a string, it's the name of the class
if (is_array($token) && $token[0] == T_STRING)
{
//Store the token's value as the class name
$class = $token[1];
//Got what we need, stope here
break;
}
}
}
//Build the fully-qualified class name and return it
return $namespace ? $namespace . '\\' . $class : $class;
}
}
... ...
<?php
return [
'Info' => '基础信息',
'Sandbox' => '在线测试',
'Sampleoutput' => '返回示例',
'Headers' => 'Headers',
'Parameters' => '参数',
'Body' => '正文',
'Name' => '名称',
'Type' => '类型',
'Required' => '必选',
'Description' => '描述',
'Send' => '提交',
'Tokentips' => 'Token在会员注册或登录后都会返回,WEB端同时存在于Cookie中',
'Apiurltips' => 'API接口URL',
'Savetips' => '点击保存后Token和Api url都将保存在本地Localstorage中',
'ReturnHeaders' => '响应头',
'ReturnParameters' => '返回参数',
'Response' => '响应输出',
];
... ...
<?php
namespace app\admin\command\Api\library;
use think\Config;
/**
* @website https://github.com/calinrada/php-apidoc
* @author Calin Rada <rada.calin@gmail.com>
* @author Karson <karsonzhang@163.com>
*/
class Builder
{
/**
*
* @var \think\View
*/
public $view = null;
/**
* parse classes
* @var array
*/
protected $classes = [];
/**
*
* @param array $classes
*/
public function __construct($classes = [])
{
$this->classes = array_merge($this->classes, $classes);
$this->view = \think\View::instance(Config::get('template'), Config::get('view_replace_str'));
}
protected function extractAnnotations()
{
$st_output = [];
foreach ($this->classes as $class)
{
$st_output[] = Extractor::getAllClassAnnotations($class);
}
return end($st_output);
}
protected function generateHeadersTemplate($docs)
{
if (!isset($docs['ApiHeaders']))
{
return [];
}
$headerslist = array();
foreach ($docs['ApiHeaders'] as $params)
{
$tr = array(
'name' => $params['name'],
'type' => $params['type'],
'sample' => isset($params['sample']) ? $params['sample'] : '',
'required' => isset($params['required']) ? $params['required'] : false,
'description' => isset($params['description']) ? $params['description'] : '',
);
$headerslist[] = $tr;
}
return $headerslist;
}
protected function generateParamsTemplate($docs)
{
if (!isset($docs['ApiParams']))
{
return [];
}
$paramslist = array();
foreach ($docs['ApiParams'] as $params)
{
$tr = array(
'name' => $params['name'],
'type' => isset($params['type']) ? $params['type'] : 'string',
'sample' => isset($params['sample']) ? $params['sample'] : '',
'required' => isset($params['required']) ? $params['required'] : true,
'description' => isset($params['description']) ? $params['description'] : '',
);
$paramslist[] = $tr;
}
return $paramslist;
}
protected function generateReturnHeadersTemplate($docs)
{
if (!isset($docs['ApiReturnHeaders']))
{
return [];
}
$headerslist = array();
foreach ($docs['ApiReturnHeaders'] as $params)
{
$tr = array(
'name' => $params['name'],
'type' => 'string',
'sample' => isset($params['sample']) ? $params['sample'] : '',
'required' => isset($params['required']) && $params['required'] ? 'Yes' : 'No',
'description' => isset($params['description']) ? $params['description'] : '',
);
$headerslist[] = $tr;
}
return $headerslist;
}
protected function generateReturnParamsTemplate($st_params)
{
if (!isset($st_params['ApiReturnParams']))
{
return [];
}
$paramslist = array();
foreach ($st_params['ApiReturnParams'] as $params)
{
$tr = array(
'name' => $params['name'],
'type' => isset($params['type']) ? $params['type'] : 'string',
'sample' => isset($params['sample']) ? $params['sample'] : '',
'description' => isset($params['description']) ? $params['description'] : '',
);
$paramslist[] = $tr;
}
return $paramslist;
}
protected function generateBadgeForMethod($data)
{
$method = strtoupper(is_array($data['ApiMethod'][0]) ? $data['ApiMethod'][0]['data'] : $data['ApiMethod'][0]);
$labes = array(
'POST' => 'label-primary',
'GET' => 'label-success',
'PUT' => 'label-warning',
'DELETE' => 'label-danger',
'PATCH' => 'label-default',
'OPTIONS' => 'label-info'
);
return isset($labes[$method]) ? $labes[$method] : $labes['GET'];
}
public function parse()
{
$annotations = $this->extractAnnotations();
$counter = 0;
$section = null;
$docslist = [];
foreach ($annotations as $class => $methods)
{
foreach ($methods as $name => $docs)
{
if (isset($docs['ApiSector'][0]))
{
$section = is_array($docs['ApiSector'][0]) ? $docs['ApiSector'][0]['data'] : $docs['ApiSector'][0];
}
else
{
$section = $class;
}
if (0 === count($docs))
{
continue;
}
$docslist[$section][] = [
'id' => $counter,
'method' => is_array($docs['ApiMethod'][0]) ? $docs['ApiMethod'][0]['data'] : $docs['ApiMethod'][0],
'method_label' => $this->generateBadgeForMethod($docs),
'section' => $section,
'route' => is_array($docs['ApiRoute'][0]) ? $docs['ApiRoute'][0]['data'] : $docs['ApiRoute'][0],
'summary' => is_array($docs['ApiSummary'][0]) ? $docs['ApiSummary'][0]['data'] : $docs['ApiSummary'][0],
'body' => isset($docs['ApiBody'][0]) ? is_array($docs['ApiBody'][0]) ? $docs['ApiBody'][0]['data'] : $docs['ApiBody'][0] : '',
'headerslist' => $this->generateHeadersTemplate($docs),
'paramslist' => $this->generateParamsTemplate($docs),
'returnheaderslist' => $this->generateReturnHeadersTemplate($docs),
'returnparamslist' => $this->generateReturnParamsTemplate($docs),
'return' => isset($docs['ApiReturn']) ? is_array($docs['ApiReturn'][0]) ? $docs['ApiReturn'][0]['data'] : $docs['ApiReturn'][0] : '',
];
$counter++;
}
}
return $docslist;
}
public function getView()
{
return $this->view;
}
/**
* 渲染
* @param string $template
* @param array $vars
* @return string
*/
public function render($template, $vars = [])
{
$docslist = $this->parse();
return $this->view->display(file_get_contents($template), array_merge($vars, ['docslist' => $docslist]));
}
}
... ...
<?php
namespace app\admin\command\Api\library;
/**
* Class imported from https://github.com/eriknyk/Annotations
* @author Erik Amaru Ortiz https://github.com/eriknyk‎
*
* @license http://opensource.org/licenses/bsd-license.php The BSD License
* @author Calin Rada <rada.calin@gmail.com>
*/
class Extractor
{
/**
* Static array to store already parsed annotations
* @var array
*/
private static $annotationCache;
/**
* Indicates that annotations should has strict behavior, 'false' by default
* @var boolean
*/
private $strict = false;
/**
* Stores the default namespace for Objects instance, usually used on methods like getMethodAnnotationsObjects()
* @var string
*/
public $defaultNamespace = '';
/**
* Sets strict variable to true/false
* @param bool $value boolean value to indicate that annotations to has strict behavior
*/
public function setStrict($value)
{
$this->strict = (bool) $value;
}
/**
* Sets default namespace to use in object instantiation
* @param string $namespace default namespace
*/
public function setDefaultNamespace($namespace)
{
$this->defaultNamespace = $namespace;
}
/**
* Gets default namespace used in object instantiation
* @return string $namespace default namespace
*/
public function getDefaultAnnotationNamespace()
{
return $this->defaultNamespace;
}
/**
* Gets all anotations with pattern @SomeAnnotation() from a given class
*
* @param string $className class name to get annotations
* @return array self::$annotationCache all annotated elements
*/
public static function getClassAnnotations($className)
{
if (!isset(self::$annotationCache[$className]))
{
$class = new \ReflectionClass($className);
self::$annotationCache[$className] = self::parseAnnotations($class->getDocComment());
}
return self::$annotationCache[$className];
}
public static function getAllClassAnnotations($className)
{
$class = new \ReflectionClass($className);
foreach ($class->getMethods() as $object)
{
self::$annotationCache['annotations'][$className][$object->name] = self::getMethodAnnotations($className, $object->name);
}
return self::$annotationCache['annotations'];
}
/**
* Gets all anotations with pattern @SomeAnnotation() from a determinated method of a given class
*
* @param string $className class name
* @param string $methodName method name to get annotations
* @return array self::$annotationCache all annotated elements of a method given
*/
public static function getMethodAnnotations($className, $methodName)
{
if (!isset(self::$annotationCache[$className . '::' . $methodName]))
{
try
{
$method = new \ReflectionMethod($className, $methodName);
$class = new \ReflectionClass($className);
if (!$method->isPublic() || $method->isConstructor())
{
$annotations = array();
}
else
{
$annotations = self::consolidateAnnotations($method, $class);
}
}
catch (\ReflectionException $e)
{
$annotations = array();
}
self::$annotationCache[$className . '::' . $methodName] = $annotations;
}
return self::$annotationCache[$className . '::' . $methodName];
}
/**
* Gets all anotations with pattern @SomeAnnotation() from a determinated method of a given class
* and instance its abcAnnotation class
*
* @param string $className class name
* @param string $methodName method name to get annotations
* @return array self::$annotationCache all annotated objects of a method given
*/
public function getMethodAnnotationsObjects($className, $methodName)
{
$annotations = $this->getMethodAnnotations($className, $methodName);
$objects = array();
$i = 0;
foreach ($annotations as $annotationClass => $listParams)
{
$annotationClass = ucfirst($annotationClass);
$class = $this->defaultNamespace . $annotationClass . 'Annotation';
// verify is the annotation class exists, depending if Annotations::strict is true
// if not, just skip the annotation instance creation.
if (!class_exists($class))
{
if ($this->strict)
{
throw new Exception(sprintf('Runtime Error: Annotation Class Not Found: %s', $class));
}
else
{
// silent skip & continue
continue;
}
}
if (empty($objects[$annotationClass]))
{
$objects[$annotationClass] = new $class();
}
foreach ($listParams as $params)
{
if (is_array($params))
{
foreach ($params as $key => $value)
{
$objects[$annotationClass]->set($key, $value);
}
}
else
{
$objects[$annotationClass]->set($i++, $params);
}
}
}
return $objects;
}
private static function consolidateAnnotations($method, $class)
{
$dockblockClass = $class->getDocComment();
$docblockMethod = $method->getDocComment();
$methodName = $method->getName();
$methodAnnotations = self::parseAnnotations($docblockMethod);
$classAnnotations = self::parseAnnotations($dockblockClass);
if (isset($methodAnnotations['ApiInternal']) || $methodName == '_initialize' || $methodName == '_empty')
{
return [];
}
$properties = $class->getDefaultProperties();
$noNeedLogin = isset($properties['noNeedLogin']) ? is_array($properties['noNeedLogin']) ? $properties['noNeedLogin'] : [$properties['noNeedLogin']] : [];
$noNeedRight = isset($properties['noNeedRight']) ? is_array($properties['noNeedRight']) ? $properties['noNeedRight'] : [$properties['noNeedRight']] : [];
preg_match_all("/\*[\s]+(.*)(\\r\\n|\\r|\\n)/U", str_replace('/**', '', $docblockMethod), $methodArr);
preg_match_all("/\*[\s]+(.*)(\\r\\n|\\r|\\n)/U", str_replace('/**', '', $dockblockClass), $classArr);
$methodTitle = isset($methodArr[1]) && isset($methodArr[1][0]) ? $methodArr[1][0] : '';
$classTitle = isset($classArr[1]) && isset($classArr[1][0]) ? $classArr[1][0] : '';
if (!isset($methodAnnotations['ApiMethod']))
{
$methodAnnotations['ApiMethod'] = ['get'];
}
if (!isset($methodAnnotations['ApiSummary']))
{
$methodAnnotations['ApiSummary'] = [$methodTitle];
}
if ($methodAnnotations)
{
foreach ($classAnnotations as $name => $valueClass)
{
if (count($valueClass) !== 1)
{
continue;
}
if ($name === 'ApiRoute')
{
if (isset($methodAnnotations[$name]))
{
$methodAnnotations[$name] = [rtrim($valueClass[0], '/') . $methodAnnotations[$name][0]];
}
else
{
$methodAnnotations[$name] = [rtrim($valueClass[0], '/') . '/' . $method->getName()];
}
}
if ($name === 'ApiSector')
{
$methodAnnotations[$name] = $valueClass;
}
}
}
if (!isset($methodAnnotations['ApiTitle']))
{
$methodAnnotations['ApiTitle'] = [$methodTitle];
}
if (!isset($methodAnnotations['ApiRoute']))
{
$urlArr = [];
$className = $class->getName();
list($prefix, $suffix) = explode('\\' . \think\Config::get('url_controller_layer') . '\\', $className);
$prefixArr = explode('\\', $prefix);
$suffixArr = explode('\\', $suffix);
if ($prefixArr[0] == \think\Config::get('app_namespace'))
{
$prefixArr[0] = '';
}
$urlArr = array_merge($urlArr, $prefixArr);
$urlArr[] = implode('.', array_map(function($item) {
return \think\Loader::parseName($item);
}, $suffixArr));
$urlArr[] = $method->getName();
$methodAnnotations['ApiRoute'] = [implode('/', $urlArr)];
}
if (!isset($methodAnnotations['ApiSector']))
{
$methodAnnotations['ApiSector'] = isset($classAnnotations['ApiSector']) ? $classAnnotations['ApiSector'] : [$classTitle];
}
if (!isset($methodAnnotations['ApiParams']))
{
$params = self::parseCustomAnnotations($docblockMethod, 'param');
foreach ($params as $k => $v)
{
$arr = explode(' ', preg_replace("/[\s]+/", " ", $v));
$methodAnnotations['ApiParams'][] = [
'name' => isset($arr[1]) ? str_replace('$', '', $arr[1]) : '',
'nullable' => false,
'type' => isset($arr[0]) ? $arr[0] : 'string',
'description' => isset($arr[2]) ? $arr[2] : ''
];
}
}
$methodAnnotations['ApiPermissionLogin'] = [!in_array('*', $noNeedLogin) && !in_array($methodName, $noNeedLogin)];
$methodAnnotations['ApiPermissionRight'] = [!in_array('*', $noNeedRight) && !in_array($methodName, $noNeedRight)];
return $methodAnnotations;
}
/**
* Parse annotations
*
* @param string $docblock
* @param string $name
* @return array parsed annotations params
*/
private static function parseCustomAnnotations($docblock, $name = 'param')
{
$annotations = array();
$docblock = substr($docblock, 3, -2);
if (preg_match_all('/@' . $name . '(?:\s*(?:\(\s*)?(.*?)(?:\s*\))?)??\s*(?:\n|\*\/)/', $docblock, $matches))
{
foreach ($matches[1] as $k => $v)
{
$annotations[] = $v;
}
}
return $annotations;
}
/**
* Parse annotations
*
* @param string $docblock
* @return array parsed annotations params
*/
private static function parseAnnotations($docblock)
{
$annotations = array();
// Strip away the docblock header and footer to ease parsing of one line annotations
$docblock = substr($docblock, 3, -2);
if (preg_match_all('/@(?<name>[A-Za-z_-]+)[\s\t]*\((?<args>(?:(?!\)).)*)\)\r?/s', $docblock, $matches))
{
$numMatches = count($matches[0]);
for ($i = 0; $i < $numMatches; ++$i)
{
// annotations has arguments
if (isset($matches['args'][$i]))
{
$argsParts = trim($matches['args'][$i]);
$name = $matches['name'][$i];
$value = self::parseArgs($argsParts);
}
else
{
$value = array();
}
$annotations[$name][] = $value;
}
}
return $annotations;
}
/**
* Parse individual annotation arguments
*
* @param string $content arguments string
* @return array annotated arguments
*/
private static function parseArgs($content)
{
// Replace initial stars
$content = preg_replace('/^\s*\*/m', '', $content);
$data = array();
$len = strlen($content);
$i = 0;
$var = '';
$val = '';
$level = 1;
$prevDelimiter = '';
$nextDelimiter = '';
$nextToken = '';
$composing = false;
$type = 'plain';
$delimiter = null;
$quoted = false;
$tokens = array('"', '"', '{', '}', ',', '=');
while ($i <= $len)
{
$prev_c = substr($content, $i - 1, 1);
$c = substr($content, $i++, 1);
if ($c === '"' && $prev_c !== "\\")
{
$delimiter = $c;
//open delimiter
if (!$composing && empty($prevDelimiter) && empty($nextDelimiter))
{
$prevDelimiter = $nextDelimiter = $delimiter;
$val = '';
$composing = true;
$quoted = true;
}
else
{
// close delimiter
if ($c !== $nextDelimiter)
{
throw new Exception(sprintf(
"Parse Error: enclosing error -> expected: [%s], given: [%s]", $nextDelimiter, $c
));
}
// validating syntax
if ($i < $len)
{
if (',' !== substr($content, $i, 1) && '\\' !== $prev_c)
{
throw new Exception(sprintf(
"Parse Error: missing comma separator near: ...%s<--", substr($content, ($i - 10), $i)
));
}
}
$prevDelimiter = $nextDelimiter = '';
$composing = false;
$delimiter = null;
}
}
elseif (!$composing && in_array($c, $tokens))
{
switch ($c)
{
case '=':
$prevDelimiter = $nextDelimiter = '';
$level = 2;
$composing = false;
$type = 'assoc';
$quoted = false;
break;
case ',':
$level = 3;
// If composing flag is true yet,
// it means that the string was not enclosed, so it is parsing error.
if ($composing === true && !empty($prevDelimiter) && !empty($nextDelimiter))
{
throw new Exception(sprintf(
"Parse Error: enclosing error -> expected: [%s], given: [%s]", $nextDelimiter, $c
));
}
$prevDelimiter = $nextDelimiter = '';
break;
case '{':
$subc = '';
$subComposing = true;
while ($i <= $len)
{
$c = substr($content, $i++, 1);
if (isset($delimiter) && $c === $delimiter)
{
throw new Exception(sprintf(
"Parse Error: Composite variable is not enclosed correctly."
));
}
if ($c === '}')
{
$subComposing = false;
break;
}
$subc .= $c;
}
// if the string is composing yet means that the structure of var. never was enclosed with '}'
if ($subComposing)
{
throw new Exception(sprintf(
"Parse Error: Composite variable is not enclosed correctly. near: ...%s'", $subc
));
}
$val = self::parseArgs($subc);
break;
}
}
else
{
if ($level == 1)
{
$var .= $c;
}
elseif ($level == 2)
{
$val .= $c;
}
}
if ($level === 3 || $i === $len)
{
if ($type == 'plain' && $i === $len)
{
$data = self::castValue($var);
}
else
{
$data[trim($var)] = self::castValue($val, !$quoted);
}
$level = 1;
$var = $val = '';
$composing = false;
$quoted = false;
}
}
return $data;
}
/**
* Try determinate the original type variable of a string
*
* @param string $val string containing possibles variables that can be cast to bool or int
* @param boolean $trim indicate if the value passed should be trimmed after to try cast
* @return mixed returns the value converted to original type if was possible
*/
private static function castValue($val, $trim = false)
{
if (is_array($val))
{
foreach ($val as $key => $value)
{
$val[$key] = self::castValue($value);
}
}
elseif (is_string($val))
{
if ($trim)
{
$val = trim($val);
}
$val = stripslashes($val);
$tmp = strtolower($val);
if ($tmp === 'false' || $tmp === 'true')
{
$val = $tmp === 'true';
}
elseif (is_numeric($val))
{
return $val + 0;
}
unset($tmp);
}
return $val;
}
}
... ...
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="">
<meta name="author" content="{$config.author}">
<title>{$config.title}</title>
<link href="https://cdn.bootcss.com/bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet">
<style type="text/css">
body { padding-top: 70px; margin-bottom: 15px; }
.tab-pane { padding-top: 10px; }
.mt0 { margin-top: 0px; }
.footer { font-size: 12px; color: #666; }
.label { display: inline-block; min-width: 65px; padding: 0.3em 0.6em 0.3em; }
.string { color: green; }
.number { color: darkorange; }
.boolean { color: blue; }
.null { color: magenta; }
.key { color: red; }
.popover { max-width: 400px; max-height: 400px; overflow-y: auto;}
</style>
</head>
<body>
<!-- Fixed navbar -->
<div class="navbar navbar-default navbar-fixed-top" role="navigation">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="http://www.fastadmin.net" target="_blank">{$config.title}</a>
</div>
<div class="navbar-collapse collapse">
<form class="navbar-form navbar-right">
<div class="form-group">
Token:
</div>
<div class="form-group">
<input type="text" class="form-control input-sm" data-toggle="tooltip" title="{$lang.Tokentips}" placeholder="token" id="token" />
</div>
<div class="form-group">
Apiurl:
</div>
<div class="form-group">
<input id="apiUrl" type="text" class="form-control input-sm" data-toggle="tooltip" title="{$lang.Apiurltips}" placeholder="https://api.mydomain.com" value="{$config.apiurl}" />
</div>
<div class="form-group">
<button type="button" class="btn btn-success btn-sm" data-toggle="tooltip" title="{$lang.Savetips}" id="save_data">
<span class="glyphicon glyphicon-floppy-disk" aria-hidden="true"></span>
</button>
</div>
</form>
</div><!--/.nav-collapse -->
</div>
</div>
<div class="container">
<div class="panel-group" id="accordion">
{foreach name="docslist" id="docs"}
<h2>{$key}</h2>
<hr>
{foreach name="docs" id="api" }
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">
<span class="label {$api.method_label}">{$api.method|strtoupper}</span> <a data-toggle="collapse" data-parent="#accordion{$api.id}" href="#collapseOne{$api.id}"> {$api.route}</a>
</h4>
</div>
<div id="collapseOne{$api.id}" class="panel-collapse collapse">
<div class="panel-body">
<!-- Nav tabs -->
<ul class="nav nav-tabs" id="doctab{$api.id}">
<li class="active"><a href="#info{$api.id}" data-toggle="tab">{$lang.Info}</a></li>
<li><a href="#sandbox{$api.id}" data-toggle="tab">{$lang.Sandbox}</a></li>
<li><a href="#sample{$api.id}" data-toggle="tab">{$lang.Sampleoutput}</a></li>
</ul>
<!-- Tab panes -->
<div class="tab-content">
<div class="tab-pane active" id="info{$api.id}">
<div class="well">
{$api.summary}
</div>
<div class="panel panel-default">
<div class="panel-heading"><strong>{$lang.Headers}</strong></div>
<div class="panel-body">
{if $api.headerslist}
<table class="table table-hover">
<thead>
<tr>
<th>{$lang.Name}</th>
<th>{$lang.Type}</th>
<th>{$lang.Required}</th>
<th>{$lang.Description}</th>
</tr>
</thead>
<tbody>
{foreach name="api['headerslist']" id="header"}
<tr>
<td>{$header.name}</td>
<td>{$header.type}</td>
<td>{$header.required?'是':'否'}</td>
<td>{$header.description}</td>
</tr>
{/foreach}
</tbody>
</table>
{else /}
{/if}
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading"><strong>{$lang.Parameters}</strong></div>
<div class="panel-body">
{if $api.paramslist}
<table class="table table-hover">
<thead>
<tr>
<th>{$lang.Name}</th>
<th>{$lang.Type}</th>
<th>{$lang.Required}</th>
<th>{$lang.Description}</th>
</tr>
</thead>
<tbody>
{foreach name="api['paramslist']" id="param"}
<tr>
<td>{$param.name}</td>
<td>{$param.type}</td>
<td>{:$param.required?'是':'否'}</td>
<td>{$param.description}</td>
</tr>
{/foreach}
</tbody>
</table>
{else /}
{/if}
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading"><strong>{$lang.Body}</strong></div>
<div class="panel-body">
{$api.body|default='无'}
</div>
</div>
</div><!-- #info -->
<div class="tab-pane" id="sandbox{$api.id}">
<div class="row">
<div class="col-md-12">
{if $api.headerslist}
<div class="panel panel-default">
<div class="panel-heading"><strong>{$lang.Headers}</strong></div>
<div class="panel-body">
<div class="headers">
{foreach name="api['headerslist']" id="param"}
<div class="form-group">
<label class="control-label" for="{$param.name}">{$param.name}</label>
<input type="{$param.type}" class="form-control input-sm" id="{$param.name}" {if $param.required}required{/if} placeholder="{$param.description} - Ex: {$param.sample}" name="{$param.name}">
</div>
{/foreach}
</div>
</div>
</div>
{/if}
<div class="panel panel-default">
<div class="panel-heading"><strong>{$lang.Parameters}</strong></div>
<div class="panel-body">
<form enctype="application/x-www-form-urlencoded" role="form" action="{$api.route}" method="{$api.method}" name="form{$api.id}" id="form{$api.id}">
{if $api.paramslist}
{foreach name="api['paramslist']" id="param"}
<div class="form-group">
<label class="control-label" for="{$param.name}">{$param.name}</label>
<input type="{$param.type}" class="form-control input-sm" id="{$param.name}" {if $param.required}required{/if} placeholder="{$param.description}{if $param.sample} - 例: {$param.sample}{/if}" name="{$param.name}">
</div>
{/foreach}
{else /}
<div class="form-group">
</div>
{/if}
<div class="form-group">
<button type="submit" class="btn btn-success send" rel="{$api.id}">{$lang.Send}</button>
</div>
</form>
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading"><strong>{$lang.Response}</strong></div>
<div class="panel-body">
<div class="row">
<div class="col-md-12" style="overflow-x:auto">
<pre id="response_headers{$api.id}"></pre>
<pre id="response{$api.id}"></pre>
</div>
</div>
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading"><strong>{$lang.ReturnParameters}</strong></div>
<div class="panel-body">
{if $api.returnparamslist}
<table class="table table-hover">
<thead>
<tr>
<th>{$lang.Name}</th>
<th>{$lang.Type}</th>
<th>{$lang.Description}</th>
</tr>
</thead>
<tbody>
{foreach name="api['returnparamslist']" id="param"}
<tr>
<td>{$param.name}</td>
<td>{$param.type}</td>
<td>{$param.description}</td>
</tr>
{/foreach}
</tbody>
</table>
{else /}
{/if}
</div>
</div>
</div>
</div>
</div><!-- #sandbox -->
<div class="tab-pane" id="sample{$api.id}">
<div class="row">
<div class="col-md-12">
<pre id="sample_response{$api.id}">{$api.return|default='无'}</pre>
</div>
</div>
</div><!-- #sample -->
</div><!-- .tab-content -->
</div>
</div>
</div>
{/foreach}
{/foreach}
</div>
<hr>
<div class="row mt0 footer">
<div class="col-md-6" align="left">
Generated on {:date('Y-m-d H:i:s')}
</div>
<div class="col-md-6" align="right">
<a href="http://www.fastadmin.net" target="_blank">FastAdmin</a>
</div>
</div>
</div> <!-- /container -->
<script src="https://cdn.bootcss.com/jquery/1.10.2/jquery.min.js"></script>
<script src="https://cdn.bootcss.com/bootstrap/3.0.3/js/bootstrap.min.js"></script>
<script type="text/javascript">
function syntaxHighlight(json) {
if (typeof json != 'string') {
json = JSON.stringify(json, undefined, 2);
}
json = json.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
return json.replace(/("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g, function (match) {
var cls = 'number';
if (/^"/.test(match)) {
if (/:$/.test(match)) {
cls = 'key';
} else {
cls = 'string';
}
} else if (/true|false/.test(match)) {
cls = 'boolean';
} else if (/null/.test(match)) {
cls = 'null';
}
return '<span class="' + cls + '">' + match + '</span>';
});
}
function prepareStr(str) {
try {
return syntaxHighlight(JSON.stringify(JSON.parse(str.replace(/'/g, '"')), null, 2));
} catch (e) {
return str;
}
}
var storage = (function () {
var uid = new Date;
var storage;
var result;
try {
(storage = window.localStorage).setItem(uid, uid);
result = storage.getItem(uid) == uid;
storage.removeItem(uid);
return result && storage;
} catch (exception) {
}
}());
$.fn.serializeObject = function ()
{
var o = {};
var a = this.serializeArray();
$.each(a, function () {
if (!this.value) {
return;
}
if (o[this.name] !== undefined) {
if (!o[this.name].push) {
o[this.name] = [o[this.name]];
}
o[this.name].push(this.value || '');
} else {
o[this.name] = this.value || '';
}
});
return o;
};
$(document).ready(function () {
if (storage) {
$('#token').val(storage.getItem('token'));
$('#apiUrl').val(storage.getItem('apiUrl'));
}
$('[data-toggle="tooltip"]').tooltip({
placement: 'bottom'
});
$('code[id^=response]').hide();
$.each($('pre[id^=sample_response],pre[id^=sample_post_body]'), function () {
if ($(this).html() == 'NA') {
return;
}
var str = prepareStr($(this).html());
$(this).html(str);
});
$("[data-toggle=popover]").popover({placement: 'right'});
$('[data-toggle=popover]').on('shown.bs.popover', function () {
var $sample = $(this).parent().find(".popover-content"),
str = $(this).data('content');
if (typeof str == "undefined" || str === "") {
return;
}
var str = prepareStr(str);
$sample.html('<pre>' + str + '</pre>');
});
$('body').on('click', '#save_data', function (e) {
if (storage) {
storage.setItem('token', $('#token').val());
storage.setItem('apiUrl', $('#apiUrl').val());
} else {
alert('Your browser does not support local storage');
}
});
$('body').on('click', '.send', function (e) {
e.preventDefault();
var form = $(this).closest('form');
//added /g to get all the matched params instead of only first
var matchedParamsInRoute = $(form).attr('action').match(/[^{]+(?=\})/g);
var theId = $(this).attr('rel');
//keep a copy of action attribute in order to modify the copy
//instead of the initial attribute
var url = $(form).attr('action');
var serializedData = new FormData();
$(form).find('input').each(function (i, input) {
if ($(input).attr('type') == 'file') {
serializedData.append($(input).attr('name'), $(input)[0].files[0]);
} else {
serializedData.append($(input).attr('name'), $(input).val())
}
});
var index, key, value;
if (matchedParamsInRoute) {
for (index = 0; index < matchedParamsInRoute.length; ++index) {
try {
key = matchedParamsInRoute[index];
value = serializedData[key];
if (typeof value == "undefined")
value = "";
url = url.replace("{" + key + "}", value);
delete serializedData[key];
} catch (err) {
console.log(err);
}
}
}
var headers = {};
var token = $('#token').val();
if (token.length > 0) {
headers[token] = token;
}
$("#sandbox" + theId + " .headers input[type=text]").each(function () {
val = $(this).val();
if (val.length > 0) {
headers[$(this).prop('name')] = val;
}
});
$.ajax({
url: $('#apiUrl').val() + url,
data: $(form).attr('method') == 'get' ? $(form).serialize() : serializedData,
type: $(form).attr('method') + '',
dataType: 'json',
contentType: false,
processData: false,
headers: headers,
success: function (data, textStatus, xhr) {
if (typeof data === 'object') {
var str = JSON.stringify(data, null, 2);
$('#response' + theId).html(syntaxHighlight(str));
} else {
$('#response' + theId).html(data || '');
}
$('#response_headers' + theId).html('HTTP ' + xhr.status + ' ' + xhr.statusText + '<br/><br/>' + xhr.getAllResponseHeaders());
$('#response' + theId).show();
},
error: function (xhr, textStatus, error) {
try {
var str = JSON.stringify($.parseJSON(xhr.responseText), null, 2);
} catch (e) {
var str = xhr.responseText;
}
$('#response_headers' + theId).html('HTTP ' + xhr.status + ' ' + xhr.statusText + '<br/><br/>' + xhr.getAllResponseHeaders());
$('#response' + theId).html(syntaxHighlight(str));
$('#response' + theId).show();
}
});
return false;
});
});
</script>
</body>
</html>
... ...
... ... @@ -580,8 +580,8 @@ class Crud extends Command
}
$formAddElement = $formEditElement = Form::hidden($fieldName, $no, array_merge(['checked' => ''], $attrArr));
$attrArr['id'] = $fieldName . "-switch";
$formAddElement .= sprintf(Form::label("{$attrArr['id']}", "%s abcdefg"), Form::checkbox($fieldName, $yes, $defaultValue === $yes, $attrArr));
$formEditElement .= sprintf(Form::label("{$attrArr['id']}", "%s abcdefg"), Form::checkbox($fieldName, $yes, 0, $attrArr));
$formAddElement .= sprintf(Form::label("{$attrArr['id']}", "%s {:__('Yes')}", ['class'=>'control-label']), Form::checkbox($fieldName, $yes, $defaultValue === $yes, $attrArr));
$formEditElement .= sprintf(Form::label("{$attrArr['id']}", "%s {:__('Yes')}", ['class'=>'control-label']), Form::checkbox($fieldName, $yes, 0, $attrArr));
$formEditElement = str_replace('type="checkbox"', 'type="checkbox" {in name="' . "\$row.{$field}" . '" value="' . $yes . '"}checked{/in}', $formEditElement);
}
else if ($inputType == 'citypicker')
... ... @@ -963,6 +963,7 @@ EOD;
if ($content || !Lang::has($field))
{
$itemArr = [];
$content = str_replace(',', ',', $content);
if (stripos($content, ':') !== false && stripos($content, ',') && stripos($content, '=') !== false)
{
list($fieldLang, $item) = explode(':', $content);
... ... @@ -997,6 +998,7 @@ EOD;
/**
* 读取数据和语言数组列表
* @param array $arr
* @param boolean $withTpl
* @return array
*/
protected function getLangArray($arr, $withTpl = TRUE)
... ... @@ -1035,6 +1037,7 @@ EOD;
protected function getItemArray($item, $field, $comment)
{
$itemArr = [];
$comment = str_replace('', ',', $comment);
if (stripos($comment, ':') !== false && stripos($comment, ',') && stripos($comment, '=') !== false)
{
list($fieldLang, $item) = explode(':', $comment);
... ... @@ -1255,7 +1258,7 @@ EOD;
{
$html .= ", operate:'RANGE', addclass:'datetimerange'";
}
else if (in_array($datatype,['float', 'double', 'decimal']))
else if (in_array($datatype, ['float', 'double', 'decimal']))
{
$html .= ", operate:'BETWEEN'";
}
... ...
... ... @@ -80,6 +80,8 @@ class Install extends Command
$config = preg_replace_callback("/'(hostname|database|username|password|hostport|prefix)'(\s+)=>(\s+)Env::get\((.*)\)\,/", $callback, $config);
// 写入数据库配置
file_put_contents($dbConfigFile, $config);
\think\Cache::rm('__menu__');
$output->info("Install Successed!");
}
... ...
... ... @@ -4,7 +4,7 @@
官网: http://www.fastadmin.net
演示: http://demo.fastadmin.net
Date: 2017年09月15
Date: 2018年03月07
*/
SET FOREIGN_KEY_CHECKS = 0;
... ... @@ -396,6 +396,9 @@ BEGIN;
INSERT INTO `fa_test` VALUES (1, 0, 12, '12,13', 'monday', 'hot,index', 'male', 'music,reading', '我是一篇测试文章', '<p>我是测试内容</p>', '/assets/img/avatar.png', '/assets/img/avatar.png,/assets/img/qrcode.png', '/assets/img/avatar.png', '关键字', '描述', '广西壮族自治区/百色市/平果县', 0.00, 0, '2017-07-10', '2017-07-10 18:24:45', 2017, '18:24:45', 1499682285, 1499682526, 1499682526, 0, 1, 'normal', '1');
COMMIT;
-- ----------------------------
-- Table structure for fa_user
-- ----------------------------
DROP TABLE IF EXISTS `fa_user`;
CREATE TABLE `fa_user` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID',
... ... @@ -431,10 +434,16 @@ CREATE TABLE `fa_user` (
KEY `mobile` (`mobile`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='会员表';
-- ----------------------------
-- Records of fa_user
-- ----------------------------
BEGIN;
INSERT INTO `fa_user` VALUES (1, 1, 'admin', 'admin', 'c13f62012fd6a8fdf06b3452a94430e5', 'rpR6Bv', 'admin@163.com', '13888888888', '/assets/img/avatar.png', 0, 0, '2017-04-15', '', 0, 1, 1, 1516170492, 1516171614, '127.0.0.1', 0, '127.0.0.1', 1491461418, 0, 1516171614, '', 'normal','');
COMMIT;
-- ----------------------------
-- Table structure for fa_user_group
-- ----------------------------
DROP TABLE IF EXISTS `fa_user_group`;
CREATE TABLE `fa_user_group` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
... ... @@ -446,10 +455,16 @@ CREATE TABLE `fa_user_group` (
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COMMENT='会员组表';
-- ----------------------------
-- Records of fa_user_group
-- ----------------------------
BEGIN;
INSERT INTO `fa_user_group` VALUES (1, '默认组', '1,2,3,4,5,6,7,8,9,10,11,12', 1515386468, 1516168298, 'normal');
COMMIT;
-- ----------------------------
-- Table structure for fa_user_rule
-- ----------------------------
DROP TABLE IF EXISTS `fa_user_rule`;
CREATE TABLE `fa_user_rule` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
... ... @@ -465,6 +480,9 @@ CREATE TABLE `fa_user_rule` (
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8 COMMENT='会员规则表';
-- ----------------------------
-- Records of fa_user_rule
-- ----------------------------
BEGIN;
INSERT INTO `fa_user_rule` VALUES (1, 0, 'index', '前台', '', 1, 1516168079, 1516168079, 1, 'normal');
INSERT INTO `fa_user_rule` VALUES (2, 0, 'api', 'API接口', '', 1, 1516168062, 1516168062, 2, 'normal');
... ... @@ -480,6 +498,9 @@ INSERT INTO `fa_user_rule` VALUES (11, 4, 'api/user/index', '会员中心', '',
INSERT INTO `fa_user_rule` VALUES (12, 4, 'api/user/profile', '个人资料', '', 0, 1516015012, 1516015012, 3, 'normal');
COMMIT;
-- ----------------------------
-- Table structure for fa_user_score_log
-- ----------------------------
DROP TABLE IF EXISTS `fa_user_score_log`;
CREATE TABLE `fa_user_score_log` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
... ... @@ -492,6 +513,9 @@ CREATE TABLE `fa_user_score_log` (
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='会员积分变动表';
-- ----------------------------
-- Table structure for fa_user_token
-- ----------------------------
DROP TABLE IF EXISTS `fa_user_token`;
CREATE TABLE `fa_user_token` (
`token` varchar(50) NOT NULL COMMENT 'Token',
... ... @@ -501,4 +525,30 @@ CREATE TABLE `fa_user_token` (
PRIMARY KEY (`token`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='会员Token表';
-- ----------------------------
-- Table structure for fa_version
-- ----------------------------
DROP TABLE IF EXISTS `fa_version`;
CREATE TABLE `fa_version` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID',
`oldversion` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '旧版本号',
`newversion` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '新版本号',
`packagesize` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '包大小',
`content` varchar(500) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '升级内容',
`downloadurl` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '下载地址',
`enforce` tinyint(1) UNSIGNED NOT NULL DEFAULT 0 COMMENT '强制更新',
`createtime` int(10) NOT NULL DEFAULT 0 COMMENT '创建时间',
`updatetime` int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '更新时间',
`weigh` int(10) NOT NULL DEFAULT 0 COMMENT '权重',
`status` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '状态',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '版本表' ROW_FORMAT = Compact;
-- ----------------------------
-- Table structure for fa_version
-- ----------------------------
BEGIN;
INSERT INTO `fa_version` (`id`, `oldversion`, `newversion`, `packagesize`, `content`, `downloadurl`, `enforce`, `createtime`, `updatetime`, `weigh`, `status`) VALUES
(1, '1.1.1,2', '1.2.1', '20M', '更新内容', 'http://www.fastadmin.net/download.html', 1, 1520425318, 0, 0, 'normal');
COMMIT;
SET FOREIGN_KEY_CHECKS = 1;
... ...
... ... @@ -56,7 +56,6 @@ class Menu extends Command
{
throw new Exception("There is no menu to delete");
}
$readyMenu = [];
$output->info("Are you sure you want to delete all those menu? Type 'yes' to continue: ");
$line = fgets(STDIN);
if (trim($line) != 'yes')
... ...
... ... @@ -27,6 +27,7 @@ class Min extends Command
->setName('min')
->addOption('module', 'm', Option::VALUE_REQUIRED, 'module name(frontend or backend),use \'all\' when build all modules', null)
->addOption('resource', 'r', Option::VALUE_REQUIRED, 'resource name(js or css),use \'all\' when build all resources', null)
->addOption('optimize', 'o', Option::VALUE_OPTIONAL, 'optimize type(uglify|closure|none)', 'none')
->setDescription('Compress js and css file');
}
... ... @@ -34,6 +35,7 @@ class Min extends Command
{
$module = $input->getOption('module') ?: '';
$resource = $input->getOption('resource') ?: '';
$optimize = $input->getOption('optimize') ?: 'none';
if (!$module || !in_array($module, ['frontend', 'backend', 'all']))
{
... ... @@ -89,6 +91,7 @@ class Min extends Command
'cssBaseUrl' => $this->options['cssBaseUrl'],
'jsBasePath' => str_replace(DS, '/', ROOT_PATH . $this->options['jsBaseUrl']),
'cssBasePath' => str_replace(DS, '/', ROOT_PATH . $this->options['cssBaseUrl']),
'optimize' => $optimize,
'ds' => DS,
];
... ... @@ -117,11 +120,19 @@ class Min extends Command
$output->info("Compress " . $data["{$res}BaseName"] . ".{$res}");
// 执行压缩
echo exec("{$nodeExec} \"{$minPath}r.js\" -o \"{$tempFile}\" >> \"{$minPath}node.log\"");
$command = "{$nodeExec} \"{$minPath}r.js\" -o \"{$tempFile}\" >> \"{$minPath}node.log\"";
if ($output->isDebug())
{
$output->warning($command);
}
echo exec($command);
}
}
@unlink($tempFile);
if (!$output->isDebug())
{
@unlink($tempFile);
}
$output->info("Build Successed!");
}
... ...
({
cssIn: "{%cssBasePath%}{%cssBaseName%}.css",
out: "{%cssBasePath%}{%cssBaseName%}.min.css",
optimizeCss: "default"
optimizeCss: "default",
optimize: "{%optimize%}"
})
\ No newline at end of file
... ...
... ... @@ -2,7 +2,8 @@
{%config%}
,
optimizeCss: "standard",
optimize: "none", //可使用uglify|closure|none
optimize: "{%optimize%}", //可使用uglify|closure|none
preserveLicenseComments: false,
removeCombined: false,
baseUrl: "{%jsBasePath%}", //JS文件所在的基础目录
name: "{%jsBaseName%}", //来源文件,不包含后缀
... ...
... ... @@ -5,6 +5,7 @@ namespace app\admin\controller;
use app\common\controller\Backend;
use think\addons\AddonException;
use think\addons\Service;
use think\Cache;
use think\Config;
use think\Exception;
... ... @@ -190,6 +191,7 @@ class Addon extends Backend
$action = $action == 'enable' ? $action : 'disable';
//调用启用、禁用的方法
Service::$action($name, $force);
Cache::rm('__menu__');
$this->success(__('Operate successful'));
}
catch (AddonException $e)
... ... @@ -314,6 +316,7 @@ class Addon extends Backend
];
//调用更新的方法
Service::upgrade($name, $extend);
Cache::rm('__menu__');
$this->success(__('Operate successful'));
}
catch (AddonException $e)
... ... @@ -370,7 +373,10 @@ class Addon extends Backend
$list[] = $v;
}
$total = count($list);
$list = array_slice($list, $offset, $limit);
if ($limit)
{
$list = array_slice($list, $offset, $limit);
}
$result = array("total" => $total, "rows" => $list);
$callback = $this->request->get('callback') ? "jsonp" : "json";
... ...
... ... @@ -29,13 +29,21 @@ class Index extends Backend
*/
public function index()
{
//
//左侧菜单
$menulist = $this->auth->getSidebar([
'dashboard' => 'hot',
'addon' => ['new', 'red', 'badge'],
'auth/rule' => 'side',
'auth/rule' => __('Menu'),
'general' => ['new', 'purple'],
], $this->view->site['fixedpage']);
$action = $this->request->request('action');
if ($this->request->isPost())
{
if ($action == 'refreshmenu')
{
$this->success('', null, ['menulist' => $menulist]);
}
}
$this->view->assign('menulist', $menulist);
$this->view->assign('title', __('Home'));
return $this->view->fetch();
... ...
... ... @@ -13,6 +13,6 @@ return [
'Menu tips' => '规则任意,不可重复,仅做层级显示,无需匹配控制器和方法',
'Node tips' => '控制器/方法名',
'The non-menu rule must have parent' => '非菜单规则节点必须有父级',
'If not necessary, use the command line to build rule' => '非必要情况下请直接使用命令行php think menu来生成',
'If not necessary, use the command line to build rule' => '非必要情况下请直接使用命令行<a href="http://doc.fastadmin.net/docs/command.html#一键生成菜单" target="_blank">php think menu</a>来生成',
'Name only supports letters, numbers, underscore and slash' => 'URL规则只能是小写字母、数字、下划线和/组成',
];
... ...
... ... @@ -12,6 +12,8 @@ return [
'Avatar' => '头像',
'Level' => '等级',
'Gender' => '性别',
'Male' => '男',
'FeMale' => '女',
'Birthday' => '生日',
'Bio' => '格言',
'Score' => '积分',
... ...
... ... @@ -273,7 +273,7 @@ class Auth extends \fast\Auth
$groupIds[] = $v['id'];
}
// 取出所有分组
$groupList = model('AuthGroup')->all(['status' => 'normal']);
$groupList = \app\admin\model\AuthGroup::where(['status' => 'normal'])->select();
$objList = [];
foreach ($groups as $K => $v)
{
... ... @@ -310,8 +310,8 @@ class Auth extends \fast\Auth
if (!$this->isSuperAdmin())
{
$groupIds = $this->getChildrenGroupIds(false);
$authGroupList = model('AuthGroupAccess')
->field('uid,group_id')
$authGroupList = \app\admin\model\AuthGroupAccess::
field('uid,group_id')
->where('group_id', 'in', $groupIds)
->select();
... ... @@ -407,7 +407,7 @@ class Auth extends \fast\Auth
$select_id = 0;
$pinyin = new \Overtrue\Pinyin\Pinyin('Overtrue\Pinyin\MemoryFileDictLoader');
// 必须将结果集转换为数组
$ruleList = collection(model('AuthRule')->where('status', 'normal')->where('ismenu', 1)->order('weigh', 'desc')->cache("__menu__")->select())->toArray();
$ruleList = collection(\app\admin\model\AuthRule::where('status', 'normal')->where('ismenu', 1)->order('weigh', 'desc')->cache("__menu__")->select())->toArray();
foreach ($ruleList as $k => &$v)
{
if (!in_array($v['name'], $userRule))
... ...
... ... @@ -267,7 +267,8 @@ trait Backend
{
$this->model->where($this->dataLimitField, 'in', $adminIds);
}
$count = $this->model->where($this->model->getPk(), 'in', $ids)->update($values);
$this->model->where($this->model->getPk(), 'in', $ids);
$count = $this->model->allowField(true)->isUpdate(true)->save($values);
if ($count)
{
$this->success();
... ...
... ... @@ -2,6 +2,7 @@
namespace app\admin\model;
use think\Cache;
use think\Model;
class AuthRule extends Model
... ... @@ -13,8 +14,16 @@ class AuthRule extends Model
protected $createTime = 'createtime';
protected $updateTime = 'updatetime';
protected static function init()
{
self::afterWrite(function ($row) {
Cache::rm('__menu__');
});
}
public function getTitleAttr($value, $data)
{
return __($value);
}
}
... ...
... ... @@ -10,6 +10,12 @@
.payimg .alipaycode {position:absolute;left:265px;top:442px;}
.payimg .wechatcode {position:absolute;left:660px;top:442px;}
.thumbnail img{width:100%;}
.fixed-table-toolbar .pull-right.search {
min-width: 300px;
}
.status-disabled .noimage {
background:#d2d6de;
}
</style>
<div id="warmtips" class="alert alert-dismissable alert-danger hide">
<button type="button" class="close" data-dismiss="alert">×</button>
... ... @@ -158,10 +164,10 @@
</table>
</script>
<script id="itemtpl" type="text/html">
<div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 mt-4">
<% var labelarr = ['primary', 'success', 'info', 'danger', 'warning']; %>
<% var label = labelarr[item.id % 5]; %>
<% var addon = typeof addons[item.name]!= 'undefined' ? addons[item.name] : null; %>
<% var labelarr = ['primary', 'success', 'info', 'danger', 'warning']; %>
<% var label = labelarr[item.id % 5]; %>
<% var addon = typeof addons[item.name]!= 'undefined' ? addons[item.name] : null; %>
<div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 mt-4 status-<%=addon ? (addon.state==1?'enabled':'disabled') : 'uninstalled'%>">
<div class="thumbnail addon">
<%if(addon){%>
<span>
... ...
... ... @@ -31,7 +31,7 @@
<label for="icon" class="control-label col-xs-12 col-sm-2">{:__('Icon')}:</label>
<div class="col-xs-12 col-sm-8">
<div class="input-group input-groupp-md">
<input type="text" class="form-control" id="icon" name="row[icon]" value="fa fa-dot" />
<input type="text" class="form-control" id="icon" name="row[icon]" value="fa fa-circle-o" />
<a href="javascript:;" class="btn-search-icon input-group-addon">{:__('Search icon')}</a>
</div>
</div>
... ...
<style>
.bootstrap-table tr td .text-muted {color:#888;}
</style>
<div class="panel panel-default panel-intro">
{:build_heading()}
... ... @@ -6,7 +9,17 @@
<div class="tab-pane fade active in" id="one">
<div class="widget-body no-padding">
<div id="toolbar" class="toolbar">
{:build_toolbar()}
<a href="javascript:;" class="btn btn-primary btn-refresh" title="{:__('Refresh')}" ><i class="fa fa-refresh"></i> </a>
<a href="javascript:;" class="btn btn-success btn-add {:$auth->check('auth/rule/add')?'':'hide'}" title="{:__('Add')}" ><i class="fa fa-plus"></i> {:__('Add')}</a>
<a href="javascript:;" class="btn btn-success btn-edit btn-disabled disabled {:$auth->check('auth/rule/edit')?'':'hide'}" title="{:__('Edit')}" ><i class="fa fa-pencil"></i> {:__('Edit')}</a>
<a href="javascript:;" class="btn btn-danger btn-del btn-disabled disabled {:$auth->check('auth/rule/del')?'':'hide'}" title="{:__('Delete')}" ><i class="fa fa-trash"></i> {:__('Delete')}</a>
<div class="dropdown btn-group {:$auth->check('auth/rule/multi')?'':'hide'}">
<a class="btn btn-primary btn-more dropdown-toggle btn-disabled disabled" data-toggle="dropdown"><i class="fa fa-cog"></i> {:__('More')}</a>
<ul class="dropdown-menu text-left" role="menu">
<li><a class="btn btn-link btn-multi btn-disabled disabled" href="javascript:;" data-params="status=normal"><i class="fa fa-eye"></i> {:__('Set to normal')}</a></li>
<li><a class="btn btn-link btn-multi btn-disabled disabled" href="javascript:;" data-params="status=hidden"><i class="fa fa-eye-slash"></i> {:__('Set to hidden')}</a></li>
</ul>
</div>
<a href="javascript:;" class="btn btn-danger btn-toggle-all"><i class="fa fa-plus"></i> {:__('Toggle all')}</a>
</div>
<table id="table" class="table table-bordered table-hover"
... ...
<div class="panel panel-default panel-intro">
<div class="panel-heading">
{:build_heading()}
{:build_heading(null,FALSE)}
<ul class="nav nav-tabs">
<li class="active"><a href="#all" data-toggle="tab">{:__('All')}</a></li>
{foreach name="typeList" item="vo"}
... ...
... ... @@ -43,147 +43,15 @@
<li><a href="javascript:;" data-skin="skin-yellow-light" class="clearfix full-opacity-hover"><div><span style="display:block; width: 20%; float: left; height: 7px;" class="bg-yellow-active"></span><span class="bg-yellow" style="display:block; width: 80%; float: left; height: 7px;"></span></div><div><span style="display:block; width: 20%; float: left; height: 20px; background: #f9fafc;"></span><span style="display:block; width: 80%; float: left; height: 20px; background: #f4f5f7;"></span></div></a><p class="text-center no-margin" style="font-size: 12px;">Yellow Light</p></li>
</ul>
</div>
<!-- /.tab-pane -->
<!-- Home tab content -->
<div class="tab-pane" id="control-sidebar-home-tab">
<h3 class="control-sidebar-heading">{:__('Recent Activity')}</h3>
<ul class="control-sidebar-menu">
<li>
<a href="javascript:void(0)">
<i class="menu-icon fa fa-birthday-cake bg-red"></i>
<div class="menu-info">
<h4 class="control-sidebar-subheading">Langdon's Birthday</h4>
<p>Will be 23 on April 24th</p>
</div>
</a>
</li>
<li>
<a href="javascript:void(0)">
<i class="menu-icon fa fa-user bg-yellow"></i>
<div class="menu-info">
<h4 class="control-sidebar-subheading">Frodo Updated His Profile</h4>
<p>New phone +1(800)555-1234</p>
</div>
</a>
</li>
<li>
<a href="javascript:void(0)">
<i class="menu-icon fa fa-envelope-o bg-light-blue"></i>
<div class="menu-info">
<h4 class="control-sidebar-subheading">Nora Joined Mailing List</h4>
<p>nora@example.com</p>
</div>
</a>
</li>
<li>
<a href="javascript:void(0)">
<i class="menu-icon fa fa-file-code-o bg-green"></i>
<div class="menu-info">
<h4 class="control-sidebar-subheading">Cron Job 254 Executed</h4>
<p>Execution time 5 seconds</p>
</div>
</a>
</li>
</ul>
<!-- /.control-sidebar-menu -->
<h3 class="control-sidebar-heading">{:__('Tasks Progress')}</h3>
<ul class="control-sidebar-menu">
<li>
<a href="javascript:void(0)">
<h4 class="control-sidebar-subheading">
Custom Template Design
<span class="label label-danger pull-right">70%</span>
</h4>
<div class="progress progress-xxs">
<div class="progress-bar progress-bar-danger" style="width: 70%"></div>
</div>
</a>
</li>
<li>
<a href="javascript:void(0)">
<h4 class="control-sidebar-subheading">
Update Resume
<span class="label label-success pull-right">95%</span>
</h4>
<div class="progress progress-xxs">
<div class="progress-bar progress-bar-success" style="width: 95%"></div>
</div>
</a>
</li>
<li>
<a href="javascript:void(0)">
<h4 class="control-sidebar-subheading">
Laravel Integration
<span class="label label-warning pull-right">50%</span>
</h4>
<div class="progress progress-xxs">
<div class="progress-bar progress-bar-warning" style="width: 50%"></div>
</div>
</a>
</li>
<li>
<a href="javascript:void(0)">
<h4 class="control-sidebar-subheading">
Back End Framework
<span class="label label-primary pull-right">68%</span>
</h4>
<div class="progress progress-xxs">
<div class="progress-bar progress-bar-primary" style="width: 68%"></div>
</div>
</a>
</li>
</ul>
<!-- /.control-sidebar-menu -->
<h4 class="control-sidebar-heading">{:__('Home')}</h4>
</div>
<!-- /.tab-pane -->
<!-- Stats tab content -->
<div class="tab-pane" id="control-sidebar-stats-tab">Stats Tab Content</div>
<!-- /.tab-pane -->
<!-- Settings tab content -->
<div class="tab-pane" id="control-sidebar-settings-tab">
<form method="post">
<h3 class="control-sidebar-heading">General Settings</h3>
<!-- /.form-group -->
<div class="form-group">
<label class="control-sidebar-subheading">
Allow mail redirect
<input type="checkbox" class="pull-right" checked>
</label>
<p>
Other sets of options are available
</p>
</div>
<!-- /.form-group -->
<div class="form-group">
<label class="control-sidebar-subheading">
Expose author name in posts
<input type="checkbox" class="pull-right" checked>
</label>
<p>
Allow the user to show his name in blog posts
</p>
</div>
<!-- /.form-group -->
<!-- /.form-group -->
</form>
<h4 class="control-sidebar-heading">{:__('Setting')}</h4>
</div>
<!-- /.tab-pane -->
</div>
... ...
<!-- Logo -->
<a href="javascript:;" class="logo">
<a href="javascript:;" class="logo hidden-xs">
<!-- 迷你模式下Logo的大小为50X50 -->
<span class="logo-mini">{$site.name|mb_substr=0,4,'utf-8'|mb_strtoupper='utf-8'}</span>
<!-- 普通模式下Logo -->
... ...
... ... @@ -29,10 +29,10 @@
<!--如果想始终显示子菜单,则给ul加上show-submenu类即可-->
<ul class="sidebar-menu">
{$menulist}
<li class="header">{:__('Links')}</li>
<li><a href="http://doc.fastadmin.net" target="_blank"><i class="fa fa-list text-red"></i> <span>{:__('Docs')}</span></a></li>
<li><a href="http://forum.fastadmin.net" target="_blank"><i class="fa fa-comment text-yellow"></i> <span>{:__('Forum')}</span></a></li>
<li><a href="https://jq.qq.com/?_wv=1027&k=487PNBb" target="_blank"><i class="fa fa-qq text-aqua"></i> <span>{:__('QQ qun')}</span></a></li>
<li class="header" data-rel="external">{:__('Links')}</li>
<li data-rel="external"><a href="http://doc.fastadmin.net" target="_blank"><i class="fa fa-list text-red"></i> <span>{:__('Docs')}</span></a></li>
<li data-rel="external"><a href="http://forum.fastadmin.net" target="_blank"><i class="fa fa-comment text-yellow"></i> <span>{:__('Forum')}</span></a></li>
<li data-rel="external"><a href="https://jq.qq.com/?_wv=1027&k=487PNBb" target="_blank"><i class="fa fa-qq text-aqua"></i> <span>{:__('QQ qun')}</span></a></li>
</ul>
</section>
<!-- /.sidebar -->
\ No newline at end of file
... ...
<script src="__CDN__/assets/js/require.js" data-main="__CDN__/assets/js/require-backend{$Think.config.app_debug?'':'.min'}.js?v={$site.version}"></script>
\ No newline at end of file
<script src="__CDN__/assets/js/require{$Think.config.app_debug?'':'.min'}.js" data-main="__CDN__/assets/js/require-backend{$Think.config.app_debug?'':'.min'}.js?v={$site.version}"></script>
\ No newline at end of file
... ...
... ... @@ -6,7 +6,7 @@
<div class="tab-pane fade active in" id="one">
<div class="widget-body no-padding">
<div id="toolbar" class="toolbar">
{:build_toolbar()}
{:build_toolbar('refresh,add,edit,del')}
<div class="dropdown btn-group {:$auth->check('user/rule/multi')?'':'hide'}">
<a class="btn btn-primary btn-more dropdown-toggle btn-disabled disabled" data-toggle="dropdown"><i class="fa fa-cog"></i> {:__('More')}</a>
<ul class="dropdown-menu text-left" role="menu">
... ...
<?php
//配置文件
return [
'exception_handle' => '\\app\\api\\library\\ExceptionHandle',
];
... ...
... ... @@ -2,9 +2,9 @@
namespace app\api\controller;
use app\api\model\Area;
use app\common\controller\Api;
use fast\Version;
use app\common\model\Area;
use app\common\model\Version;
use fast\Random;
use think\Config;
... ...
<?php
namespace app\api\library;
use Exception;
use think\exception\Handle;
/**
* 自定义API模块的错误显示
*/
class ExceptionHandle extends Handle
{
public function render(Exception $e)
{
// 在生产环境下返回code信息
if (!\think\Config::get('app_debug'))
{
$statuscode = $code = 500;
$msg = 'An error occurred';
// 验证异常
if ($e instanceof \think\exception\ValidateException)
{
$code = 0;
$statuscode = 200;
$msg = $e->getError();
}
// Http异常
if ($e instanceof \think\exception\HttpException)
{
$statuscode = $code = $e->getStatusCode();
}
return json(['code' => $code, 'msg' => $msg, 'time' => time(), 'data' => null], $statuscode);
}
//其它此交由系统处理
return parent::render($e);
}
}
... ...
... ... @@ -16,4 +16,5 @@ return [
'app\admin\command\Install',
'app\admin\command\Min',
'app\admin\command\Addon',
'app\admin\command\Api',
];
... ...
... ... @@ -22,7 +22,7 @@ if (!function_exists('__'))
array_shift($vars);
$lang = '';
}
return think\Lang::get($name, $vars, $lang);
return \think\Lang::get($name, $vars, $lang);
}
}
... ... @@ -89,7 +89,7 @@ if (!function_exists('cdnurl'))
*/
function cdnurl($url)
{
return preg_match("/^https?:\/\/(.*)/i", $url) ? $url : think\Config::get('upload.cdnurl') . $url;
return preg_match("/^https?:\/\/(.*)/i", $url) ? $url : \think\Config::get('upload.cdnurl') . $url;
}
}
... ... @@ -208,7 +208,6 @@ if (!function_exists('mb_ucfirst'))
}
if (!function_exists('addtion'))
{
... ... @@ -300,3 +299,37 @@ if (!function_exists('addtion'))
}
}
if (!function_exists('var_export_short'))
{
/**
* 返回打印数组结构
* @param string $var 数组
* @param string $indent 缩进字符
* @return string
*/
function var_export_short($var, $indent = "")
{
switch (gettype($var))
{
case "string":
return '"' . addcslashes($var, "\\\$\"\r\n\t\v\f") . '"';
case "array":
$indexed = array_keys($var) === range(0, count($var) - 1);
$r = [];
foreach ($var as $key => $value)
{
$r[] = "$indent "
. ($indexed ? "" : var_export_short($key) . " => ")
. var_export_short($value, "$indent ");
}
return "[\n" . implode(",\n", $r) . "\n" . $indent . "]";
case "boolean":
return $var ? "TRUE" : "FALSE";
default:
return var_export($var, TRUE);
}
}
}
\ No newline at end of file
... ...
... ... @@ -52,6 +52,11 @@ class Common
{
Config::set('app_trace', false);
}
// 切换多语言
if (Config::get('lang_switch_on') && $request->get('lang'))
{
\think\Cookie::set('think_var', $request->get('lang'));
}
}
public function addonBegin(&$request)
... ...
... ... @@ -91,7 +91,7 @@ class Api
$actionname = strtolower($this->request->action());
// token
$token = $this->request->request('token') ?: $this->request->cookie('token');
$token = $this->request->server('HTTP_TOKEN', $this->request->request('token', \think\Cookie::get('token')));
$path = str_replace('.', '/', $controllername) . '/' . $actionname;
// 设置当前请求的URI
... ... @@ -104,7 +104,7 @@ class Api
//检测是否登录
if (!$this->auth->isLogin())
{
$this->error(__('Please login first'));
$this->error(__('Please login first'), null, 401);
}
// 判断是否需要验证权限
if (!$this->auth->match($this->noNeedRight))
... ... @@ -112,7 +112,7 @@ class Api
// 判断控制器和方法判断是否有对应权限
if (!$this->auth->check($path))
{
$this->error(__('You have no permission'));
$this->error(__('You have no permission'), null, 403);
}
}
}
... ... @@ -141,38 +141,40 @@ class Api
* 操作成功返回的数据
* @param string $msg 提示信息
* @param mixed $data 要返回的数据
* @param int $code 错误码,默认为1
* @param string $type 输出类型
* @param array $header 发送的 Header 信息
*/
protected function success($msg = '', $data = '', $type = 'json', array $header = [])
protected function success($msg = '', $data = null, $code = 1, $type = 'json', array $header = [])
{
$this->result($data, 1, $msg, $type, $header);
$this->result($msg, $data, $code, $type, $header);
}
/**
* 操作失败返回的数据
* @param string $msg 提示信息
* @param mixed $data 要返回的数据
* @param int $code 错误码,默认为0
* @param string $type 输出类型
* @param array $header 发送的 Header 信息
*/
protected function error($msg = '', $data = '', $type = 'json', array $header = [])
protected function error($msg = '', $data = null, $code = 0, $type = 'json', array $header = [])
{
$this->result($data, 0, $msg, $type, $header);
$this->result($msg, $data, $code, $type, $header);
}
/**
* 返回封装后的 API 数据到客户端
* @access protected
* @param mixed $msg 提示信息
* @param mixed $data 要返回的数据
* @param int $code 返回的 code
* @param mixed $msg 提示信息
* @param string $type 返回数据格式
* @param array $header 发送的 Header 信息
* @return void
* @throws HttpResponseException
*/
protected function result($data, $code = 0, $msg = '', $type = '', array $header = [])
protected function result($msg, $data = null, $code = 0, $type = 'json', array $header = [])
{
$result = [
'code' => $code,
... ... @@ -181,20 +183,21 @@ class Api
'data' => $data,
];
$type = $type ?: $this->getResponseType();
$response = Response::create($result, $type)->header($header);
if (isset($header['statuscode']))
{
$code = $header['statuscode'];
unset($header['statuscode']);
}
else
{
$code = $code >= 1000 ? 200 : $code;
}
$response = Response::create($result, $type, $code)->header($header);
throw new HttpResponseException($response);
}
/**
* 未找到请求的接口
*/
public function _empty()
{
return $this->error('Api not found');
}
/**
* 前置操作
* @access protected
* @param string $method 前置操作方法名
... ...
... ... @@ -144,6 +144,7 @@ class Backend extends Controller
$url = preg_replace_callback("/([\?|&]+)ref=addtabs(&?)/i", function($matches) {
return $matches[2] == '&' ? $matches[1] : '';
}, $this->request->url());
$url = url($url, '', false);
$this->redirect('index/index', [], 302, ['referer' => $url]);
exit;
}
... ... @@ -290,6 +291,10 @@ class Backend extends Controller
case '<=':
$where[] = [$k, $sym, intval($v)];
break;
case 'FINDIN':
case 'FIND_IN_SET':
$where[] = "FIND_IN_SET('{$v}', `{$k}`)";
break;
case 'IN':
case 'IN(...)':
case 'NOT IN':
... ... @@ -401,21 +406,21 @@ class Backend extends Controller
//搜索关键词,客户端输入以空格分开,这里接收为数组
$word = (array) $this->request->request("q_word/a");
//当前页
$page = $this->request->request("page");
$page = $this->request->request("pageNumber");
//分页大小
$pagesize = $this->request->request("per_page");
$pagesize = $this->request->request("pageSize");
//搜索条件
$andor = $this->request->request("and_or");
$andor = $this->request->request("andOr");
//排序方式
$orderby = (array) $this->request->request("order_by/a");
$orderby = (array) $this->request->request("orderBy/a");
//显示的字段
$field = $this->request->request("field");
$field = $this->request->request("showField");
//主键
$primarykey = $this->request->request("pkey_name");
$primarykey = $this->request->request("keyField");
//主键值
$primaryvalue = $this->request->request("pkey_value");
$primaryvalue = $this->request->request("keyValue");
//搜索字段
$searchfield = (array) $this->request->request("search_field/a");
$searchfield = (array) $this->request->request("searchField/a");
//自定义搜索条件
$custom = (array) $this->request->request("custom/a");
$order = [];
... ...
... ... @@ -58,8 +58,7 @@ class Frontend extends Controller
$actionname = strtolower($this->request->action());
// token
$token = $this->request->request('token');
$token = $token ? $token : \think\Cookie::get('token');
$token = $this->request->server('HTTP_TOKEN', $this->request->request('token', \think\Cookie::get('token')));
$path = str_replace('.', '/', $controllername) . '/' . $actionname;
// 设置当前请求的URI
... ...
<?php
return [
'addon %s not found' => '插件未找到',
'addon %s is disabled' => '插件已禁用',
'addon controller %s not found' => '插件控制器未找到',
'addon action %s not found' => '插件控制器方法未找到',
'addon can not be empty' => '插件不能为空',
'addon %s not found' => '插件未找到',
'addon %s is disabled' => '插件已禁用',
'addon controller %s not found' => '插件控制器未找到',
'addon action %s not found' => '插件控制器方法未找到',
'addon can not be empty' => '插件不能为空',
'Keep login' => '保持会话',
'Forgot password' => '忘记密码?',
'Sign in' => '登入',
'Username' => '用户名',
'User id' => '会员ID',
'Username' => '用户名',
'Nickname' => '昵称',
'Password' => '密码',
'Sign up' => '注 册',
'Sign in' => '登 录',
'Sign out' => '注 销',
'Guest' => '游客',
'Welcome' => '%s,你好!',
'Add' => '添加',
'Edit' => '编辑',
'Delete' => '删除',
'Move' => '移动',
'Name' => '名称',
'Status' => '状态',
'Weigh' => '权重',
'Operate' => '操作',
'Warning' => '温馨提示',
'Default' => '默认',
'Article' => '文章',
'Page' => '单页',
'OK' => '确定',
'Cancel' => '取消',
'Loading' => '加载中',
'More' => '更多',
'Normal' => '正常',
'Hidden' => '隐藏',
'Submit' => '提交',
'Reset' => '重置',
'Execute' => '执行',
'Close' => '关闭',
'Search' => '搜索',
'Refresh' => '刷新',
'First' => '首页',
'Previous' => '上一页',
'Next' => '下一页',
'Last' => '末页',
'None' => '无',
'Home' => '主页',
'Online' => '在线',
'Logout' => '注销',
'Profile' => '个人资料',
'Index' => '首页',
'Hot' => '热门',
'Recommend' => '推荐',
'Dashboard' => '控制台',
'Code' => '编号',
'Message' => '内容',
'Line' => '行号',
'File' => '文件',
'Menu' => '菜单',
'Name' => '名称',
'Weigh' => '权重',
'Type' => '类型',
'Title' => '标题',
'Content' => '内容',
'Status' => '状态',
'Operate' => '操作',
'Append' => '追加',
'Memo' => '备注',
'Parent' => '父级',
'Params' => '参数',
'Permission' => '权限',
'Begin time' => '开始时间',
'End time' => '结束时间',
'Create time' => '创建时间',
'Flag' => '标志',
'Home' => '首页',
'Store' => '插件市场',
'Services' => '服务',
'Download' => '下载',
'Demo' => '演示',
'Donation' => '捐赠',
'Forum' => '社区',
'Docs' => '文档',
'Please login first' => '请登录后再操作',
'Send verification code' => '发送验证码',
'Redirect now' => '立即跳转',
'Operation completed' => '操作成功!',
'Operation failed' => '操作失败!',
'Unknown data format' => '未知的数据格式!',
'Network error' => '网络错误!',
'Advanced search' => '高级搜索',
'Invalid parameters' => '未知参数',
'No results were found' => '记录未找到',
'Parameter %s can not be empty' => '参数%s不能为空',
'You have no permission' => '你没有权限访问',
'An unexpected error occurred' => '发生了一个意外错误,程序猿正在紧急处理中',
'This page will be re-directed in %s seconds' => '页面将在 %s 秒后自动跳转',
];
... ...
... ... @@ -67,7 +67,7 @@ class Menu
AuthRule::destroy($ids);
return true;
}
/**
* 启用菜单
* @param string $name
... ... @@ -83,7 +83,7 @@ class Menu
AuthRule::where('id', 'in', $ids)->update(['status' => 'normal']);
return true;
}
/**
* 禁用菜单
* @param string $name
... ... @@ -101,6 +101,28 @@ class Menu
}
/**
* 导出指定名称的菜单规则
* @param string $name
* @return array
*/
public static function export($name)
{
$ids = self::getAuthRuleIdsByName($name);
if (!$ids)
{
return [];
}
$menuList = [];
$menu = AuthRule::getByName($name);
if ($menu)
{
$ruleList = collection(AuthRule::where('id', 'in', $ids)->select())->toArray();
$menuList = Tree::instance()->init($ruleList)->getTreeArray($menu['id']);
}
return $menuList;
}
/**
* 根据名称获取规则IDS
* @param string $name
* @return array
... ... @@ -112,7 +134,7 @@ class Menu
if ($menu)
{
// 必须将结果集转换为数组
$ruleList = collection(model('AuthRule')->order('weigh', 'desc')->field('id,pid,name')->select())->toArray();
$ruleList = collection(AuthRule::order('weigh', 'desc')->field('id,pid,name')->select())->toArray();
// 构造菜单数据
$ids = Tree::instance()->init($ruleList)->getChildrenIds($menu['id'], true);
}
... ...
<?php
namespace app\api\model;
namespace app\common\model;
use think\Cache;
use think\Model;
... ...
... ... @@ -11,7 +11,7 @@ class ScoreLog Extends Model
{
// 表名
protected $name = 'score_log';
protected $name = 'user_score_log';
// 开启自动写入时间戳字段
protected $autoWriteTimestamp = 'int';
// 定义时间戳字段名
... ...
<?php
namespace app\common\model;
use think\Model;
class Version extends Model
{
// 开启自动写入时间戳字段
protected $autoWriteTimestamp = 'int';
// 定义时间戳字段名
protected $createTime = 'createtime';
protected $updateTime = 'updatetime';
// 定义字段类型
protected $type = [
];
/**
* 检测版本号
*
* @param string $version 客户端版本号
* @return array
*/
public static function check($version)
{
$versionlist = self::where('status', 'normal')->cache('__version__')->order('weigh desc,id desc')->select();
foreach ($versionlist as $k => $v)
{
// 版本正常且新版本号不等于验证的版本号且找到匹配的旧版本
if ($v['status'] == 'normal' && $v['newversion'] !== $version && \fast\Version::check($version, $v['oldversion']))
{
$updateversion = $v;
break;
}
}
if (isset($updateversion))
{
$search = ['{version}', '{newversion}', '{downloadurl}', '{url}', '{packagesize}'];
$replace = [$version, $updateversion['newversion'], $updateversion['downloadurl'], $updateversion['downloadurl'], $updateversion['packagesize']];
$upgradetext = str_replace($search, $replace, $updateversion['content']);
return [
"enforce" => $updateversion['enforce'],
"version" => $version,
"newversion" => $updateversion['newversion'],
"downloadurl" => $updateversion['downloadurl'],
"packagesize" => $updateversion['packagesize'],
"upgradetext" => $upgradetext
];
}
return NULL;
}
}
... ...
... ... @@ -253,7 +253,7 @@ return [
//自动检测更新
'checkupdate' => false,
//版本号
'version' => '1.0.0.20180227_beta',
'version' => '1.0.0.20180308_beta',
'api_url' => 'http://api.fastadmin.net',
],
];
... ...
... ... @@ -97,7 +97,7 @@ return [
'Forum' => '社区',
'Docs' => '文档',
'Please login first' => '请登录后再操作',
'Send verification code' => '发验证码',
'Send verification code' => '发验证码',
'Redirect now' => '立即跳转',
'Operation completed' => '操作成功!',
'Operation failed' => '操作失败!',
... ...
<script src="__CDN__/assets/js/require.js" data-main="__CDN__/assets/js/require-frontend{$Think.config.app_debug?'':'.min'}.js?v={$site.version}"></script>
\ No newline at end of file
<script src="__CDN__/assets/js/require{$Think.config.app_debug?'':'.min'}.js" data-main="__CDN__/assets/js/require-frontend{$Think.config.app_debug?'':'.min'}.js?v={$site.version}"></script>
\ No newline at end of file
... ...
... ... @@ -174,11 +174,9 @@
$("#mainNav").toggleClass("affix", $(window).height() - $(window).scrollTop() <= 50);
});
//发送版本统计信息
try {
var installed = localStorage.getItem("installed");
console.log(installed);
if (!installed) {
$.ajax({
url: "{$Think.config.fastadmin.api_url}/statistics/installed",
... ...
... ... @@ -8,37 +8,31 @@
"dependencies": {
"jquery": "^2.1.4",
"bootstrap": "^3.3.7",
"font-awesome": "fontawesome#^4.6.1",
"font-awesome": "^4.6.1",
"bootstrap-table": "^1.11.0",
"layer": "*",
"layer": "^3.0",
"jstree": "^3.3.2",
"summernote": "^0.8.2",
"jquery-pjax": "^1.9.6",
"moment": "^2.15.2",
"plupload": "^2.2.0",
"toastr": "^2.1.3",
"devbridge-autocomplete": "^1.2.26",
"jcrop": "jcrop#^2.0.4",
"jquery-qrcode": "*",
"jcrop": "^2.0.4",
"eonasdan-bootstrap-datetimepicker": "^4.17.43",
"bootstrap-select": "^1.11.2",
"require-css": "^0.1.8",
"less": "^2.7.1",
"tableExport.jquery.plugin": "^1.9.0",
"jquery-slimscroll": "slimscroll#^1.3.8",
"jquery-slimscroll": "^1.3.8",
"jquery.cookie": "^1.4.1",
"Sortable": "^1.5.0",
"nice-validator": "^1.1.1",
"art-template": "^3.0.1",
"requirejs-plugins": "^1.0.3",
"bootstrap-daterangepicker": "^2.1.25",
"city-picker":"^1.1.0"
},
"devDependencies": {
"dragsort": "https://github.com/karsonzhang/dragsort.git",
"jquery-addtabs": "https://github.com/karsonzhang/jquery-addtabs.git",
"jquery-cxselect": "https://github.com/karsonzhang/cxSelect.git",
"selectpage": "https://github.com/karsonzhang/selectpage.git"
"city-picker": "^1.1.0",
"fastadmin-cxselect": "~1.4.0",
"fastadmin-dragsort": "~1.0.0",
"fastadmin-addtabs": "~1.0.0",
"fastadmin-selectpage": "~1.0.0"
},
"resolutions": {
"jspdf": "1.1.239 || 1.3.2"
... ...
... ... @@ -10,7 +10,7 @@
"license": "Apache-2.0",
"authors": [
{
"name": "karson",
"name": "Karson",
"email": "karsonzhang@163.com"
}
],
... ... @@ -22,7 +22,7 @@
"topthink/think-captcha": "^1.0",
"mtdowling/cron-expression": "^1.2",
"phpmailer/phpmailer": "^5.2",
"karsonzhang/fastadmin-addons": "dev-master",
"karsonzhang/fastadmin-addons": "~1.1.0",
"overtrue/pinyin": "~3.0",
"phpoffice/phpexcel": "^1.8"
},
... ...
此 diff 太大无法显示。
... ... @@ -9,7 +9,7 @@
@import url("../libs/eonasdan-bootstrap-datetimepicker/build/css/bootstrap-datetimepicker.min.css");
@import url("../libs/bootstrap-daterangepicker/daterangepicker.css");
@import url("../libs/nice-validator/dist/jquery.validator.css");
@import url("../libs/selectpage/selectpage.css");
@import url("../libs/fastadmin-selectpage/selectpage.css");
body {
background: #f1f4f6;
}
... ... @@ -44,9 +44,6 @@ body.is-dialog {
position: absolute;
right: 0;
}
.note-dialog .modal {
z-index: 1060;
}
.bootstrap-dialog .modal-dialog {
/*width: 70%;*/
max-width: 885px;
... ... @@ -645,13 +642,16 @@ form.form-horizontal .control-label {
overflow: hidden;
}
.layui-layer-fast .layui-layer-btn a {
background-color: #95a5a6!important;
border-color: #95a5a6!important;
background-color: #95a5a6;
border-color: #95a5a6;
color: #fff!important;
height: 31px;
margin-top: 0;
border: 1px solid transparent;
}
.layui-layer-fast .layui-layer-btn .layui-layer-btn0 {
background-color: #18bc9c!important;
border-color: #18bc9c!important;
background-color: #18bc9c;
border-color: #18bc9c;
}
.layui-layer-fast .layui-layer-footer {
padding: 8px 20px;
... ... @@ -731,6 +731,14 @@ form.form-horizontal .control-label {
.n-bootstrap .input-group > .n-right {
position: absolute;
}
@media (min-width: 564px) {
body.is-dialog .daterangepicker {
min-width: 130px;
}
body.is-dialog .daterangepicker .ranges ul {
width: 130px;
}
}
/*手机版样式*/
@media (max-width: 480px) {
.nav-addtabs {
... ... @@ -739,6 +747,10 @@ form.form-horizontal .control-label {
.fixed-table-toolbar .columns-right.btn-group {
display: none;
}
.fixed .content-wrapper,
.fixed .right-side {
padding-top: 50px;
}
}
/*平板样式*/
@media (max-width: 768px) {
... ...
... ... @@ -41,14 +41,6 @@ body {
-moz-box-shadow: none;
box-shadow: none;
}
.layui-layer-fast {
-webkit-animation-fill-mode: both;
animation-fill-mode: both;
-webkit-animation-duration: .3s;
animation-duration: .3s;
-webkit-animation-name: layer-bounceIn;
animation-name: layer-bounceIn;
}
/*修复nice-validator和summernote的编辑框冲突*/
.nice-validator .note-editor .note-editing-area .note-editable {
display: inherit;
... ... @@ -317,6 +309,8 @@ footer.footer {
color: #aaa;
background: #555;
margin-top: 25px;
position: fixed;
bottom: 0;
}
footer.footer ul {
margin: 60px 0 30px 0;
... ...
define(['backend'], function (Backend) {
});
\ No newline at end of file
... ...
... ... @@ -99,6 +99,9 @@ define(['fast', 'moment'], function (Fast, Moment) {
url = url.replace(/\{ids\}/g, ids);
}
return url;
},
refreshmenu: function () {
top.window.$(".sidebar-menu").trigger("refresh");
}
},
init: function () {
... ...
... ... @@ -56,6 +56,7 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template'], function
commonSearch: false,
searchFormVisible: false,
pageSize: 12,
pagination: false,
queryParams: function (params) {
var filter = params.filter ? JSON.parse(params.filter) : {};
var op = params.op ? JSON.parse(params.op) : {};
... ... @@ -110,16 +111,17 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template'], function
$("#warmtips").removeClass("hide");
$(".btn-switch,.btn-userinfo").addClass("disabled");
}
// 离线安装
require(['upload'], function (Upload) {
Upload.api.plupload("#plupload-addon", function (data, ret) {
Config['addons'][data.addon.name] = data.addon;
$('.btn-refresh').trigger('click');
Toastr.success(ret.msg);
operate(data.addon.name, 'enable', false);
});
});
//查看插件首页
// 查看插件首页
$(document).on("click", ".btn-addonindex", function () {
if ($(this).attr("href") == 'javascript:;') {
Layer.msg(__('Not installed tips'), {icon: 7});
... ... @@ -128,12 +130,14 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template'], function
return false;
}
});
//切换URL
// 切换URL
$(document).on("click", ".btn-switch", function () {
$(".btn-switch").removeClass("active");
$(this).addClass("active");
table.bootstrapTable('refresh', {url: $(this).data("url"), pageNumber: 1});
});
// 会员信息
$(document).on("click", ".btn-userinfo", function () {
var userinfo = Controller.api.userinfo.get();
... ... @@ -195,46 +199,24 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template'], function
}
});
// 点击安装
$(document).on("click", ".btn-install", function () {
var that = this;
var name = $(this).closest(".operate").data("name");
var version = $(this).data("version");
var install = function (name, version, force) {
var userinfo = Controller.api.userinfo.get();
var uid = userinfo ? userinfo.id : 0;
var token = userinfo ? userinfo.token : '';
var install = function (name, force) {
Fast.api.ajax({
url: 'addon/install',
data: {name: name, force: force ? 1 : 0, uid: uid, token: token, version: version, faversion: Config.fastadmin.version}
}, function (data, ret) {
Layer.closeAll();
Config['addons'][data.addon.name] = ret.data.addon;
Layer.alert(__('Online installed tips'), {
btn: [__('OK'), __('Donate')],
title: __('Warning'),
icon: 1,
btn2: function () {
//打赏
Layer.open({
content: Template("paytpl", {payimg: $(that).data("donateimage")}),
shade: 0.8,
area: ['800px', '600px'],
skin: 'layui-layer-msg layui-layer-pay',
title: false,
closeBtn: true,
btn: false,
resize: false,
});
}
});
$('.btn-refresh').trigger('click');
}, function (data, ret) {
//如果是需要购买的插件则弹出二维码提示
if (ret && ret.code === -1) {
//扫码支付
Fast.api.ajax({
url: 'addon/install',
data: {name: name, force: force ? 1 : 0, uid: uid, token: token, version: version, faversion: Config.fastadmin.version}
}, function (data, ret) {
Layer.closeAll();
Config['addons'][data.addon.name] = ret.data.addon;
Layer.alert(__('Online installed tips'), {
btn: [__('OK'), __('Donate')],
title: __('Warning'),
icon: 1,
btn2: function () {
//打赏
Layer.open({
content: Template("paytpl", ret.data),
content: Template("paytpl", {payimg: $(that).data("donateimage")}),
shade: 0.8,
area: ['800px', '600px'],
skin: 'layui-layer-msg layui-layer-pay',
... ... @@ -242,44 +224,157 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template'], function
closeBtn: true,
btn: false,
resize: false,
end: function () {
Layer.alert(__('Pay tips'));
}
});
} else if (ret && ret.code === -2) {
//跳转支付
Layer.alert(__('Pay click tips'), {
btn: [__('Pay now'), __('Cancel')],
icon: 0,
success: function (layero) {
$(".layui-layer-btn0", layero).attr("href", ret.data.payurl).attr("target", "_blank");
}
}, function () {
Layer.alert(__('Pay new window tips'), {icon: 0});
});
}
});
$('.btn-refresh').trigger('click');
Fast.api.refreshmenu();
}, function (data, ret) {
//如果是需要购买的插件则弹出二维码提示
if (ret && ret.code === -1) {
//扫码支付
Layer.open({
content: Template("paytpl", ret.data),
shade: 0.8,
area: ['800px', '600px'],
skin: 'layui-layer-msg layui-layer-pay',
title: false,
closeBtn: true,
btn: false,
resize: false,
end: function () {
Layer.alert(__('Pay tips'));
}
});
} else if (ret && ret.code === -2) {
//跳转支付
Layer.alert(__('Pay click tips'), {
btn: [__('Pay now'), __('Cancel')],
icon: 0,
success: function (layero) {
$(".layui-layer-btn0", layero).attr("href", ret.data.payurl).attr("target", "_blank");
}
}, function () {
Layer.alert(__('Pay new window tips'), {icon: 0});
});
} else if (ret && ret.code === -3) {
//插件目录发现影响全局的文件
Layer.open({
content: Template("conflicttpl", ret.data),
shade: 0.8,
area: ['800px', '600px'],
title: __('Warning'),
btn: [__('Continue install'), __('Cancel')],
end: function () {
} else if (ret && ret.code === -3) {
//插件目录发现影响全局的文件
Layer.open({
content: Template("conflicttpl", ret.data),
shade: 0.8,
area: ['800px', '600px'],
title: __('Warning'),
btn: [__('Continue install'), __('Cancel')],
end: function () {
},
yes: function () {
install(name, true);
}
});
},
yes: function () {
install(name, true);
}
});
} else {
Layer.alert(ret.msg);
}
return false;
});
};
var uninstall = function (name, force) {
Fast.api.ajax({
url: 'addon/uninstall',
data: {name: name, force: force ? 1 : 0}
}, function (data, ret) {
delete Config['addons'][name];
Layer.closeAll();
$('.btn-refresh').trigger('click');
Fast.api.refreshmenu();
}, function (data, ret) {
if (ret && ret.code === -3) {
//插件目录发现影响全局的文件
Layer.open({
content: Template("conflicttpl", ret.data),
shade: 0.8,
area: ['800px', '600px'],
title: __('Warning'),
btn: [__('Continue uninstall'), __('Cancel')],
end: function () {
},
yes: function () {
uninstall(name, true);
}
});
} else {
Layer.alert(ret.msg);
}
return false;
});
};
var operate = function (name, action, force) {
Fast.api.ajax({
url: 'addon/state',
data: {name: name, action: action, force: force ? 1 : 0}
}, function (data, ret) {
var addon = Config['addons'][name];
addon.state = action === 'enable' ? 1 : 0;
Layer.closeAll();
$('.btn-refresh').trigger('click');
Fast.api.refreshmenu();
}, function (data, ret) {
if (ret && ret.code === -3) {
//插件目录发现影响全局的文件
Layer.open({
content: Template("conflicttpl", ret.data),
shade: 0.8,
area: ['800px', '600px'],
title: __('Warning'),
btn: [__('Continue operate'), __('Cancel')],
end: function () {
},
yes: function () {
operate(name, action, true);
}
});
} else {
Layer.alert(ret.msg);
}
return false;
});
};
var upgrade = function (name, version) {
var userinfo = Controller.api.userinfo.get();
var uid = userinfo ? userinfo.id : 0;
var token = userinfo ? userinfo.token : '';
Fast.api.ajax({
url: 'addon/upgrade',
data: {name: name, uid: uid, token: token, version: version, faversion: Config.fastadmin.version}
}, function (data, ret) {
Config['addons'][name].version = version;
Layer.closeAll();
$('.btn-refresh').trigger('click');
Fast.api.refreshmenu();
}, function (data, ret) {
Layer.alert(ret.msg);
return false;
});
};
// 点击安装
$(document).on("click", ".btn-install", function () {
var that = this;
var name = $(this).closest(".operate").data("name");
var version = $(this).data("version");
var userinfo = Controller.api.userinfo.get();
var uid = userinfo ? userinfo.id : 0;
} else {
Layer.alert(ret.msg);
}
return false;
});
};
if ($(that).data("type") !== 'free') {
if (parseInt(uid) === 0) {
return Layer.alert(__('Not login tips'), {
... ... @@ -289,99 +384,36 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template'], function
$(".btn-userinfo").trigger("click");
},
btn2: function () {
install(name, false);
install(name, version, false);
}
});
}
}
install(name, false);
install(name, version, false);
});
//点击卸载
// 点击卸载
$(document).on("click", ".btn-uninstall", function () {
var name = $(this).closest(".operate").data("name");
var uninstall = function (name, force) {
Fast.api.ajax({
url: 'addon/uninstall',
data: {name: name, force: force ? 1 : 0}
}, function (data, ret) {
delete Config['addons'][name];
Layer.closeAll();
$('.btn-refresh').trigger('click');
}, function (data, ret) {
if (ret && ret.code === -3) {
//插件目录发现影响全局的文件
Layer.open({
content: Template("conflicttpl", ret.data),
shade: 0.8,
area: ['800px', '600px'],
title: __('Warning'),
btn: [__('Continue uninstall'), __('Cancel')],
end: function () {
},
yes: function () {
uninstall(name, true);
}
});
} else {
Layer.alert(ret.msg);
}
return false;
});
};
Layer.confirm(__('Uninstall tips'), function () {
uninstall(name, false);
});
});
//点击配置
// 点击配置
$(document).on("click", ".btn-config", function () {
var name = $(this).closest(".operate").data("name");
Fast.api.open("addon/config?name=" + name, __('Setting'));
});
//点击启用/禁用
// 点击启用/禁用
$(document).on("click", ".btn-enable,.btn-disable", function () {
var name = $(this).closest(".operate").data("name");
var action = $(this).data("action");
var operate = function (name, action, force) {
Fast.api.ajax({
url: 'addon/state',
data: {name: name, action: action, force: force ? 1 : 0}
}, function (data, ret) {
var addon = Config['addons'][name];
addon.state = action === 'enable' ? 1 : 0;
Layer.closeAll();
$('.btn-refresh').trigger('click');
}, function (data, ret) {
if (ret && ret.code === -3) {
//插件目录发现影响全局的文件
Layer.open({
content: Template("conflicttpl", ret.data),
shade: 0.8,
area: ['800px', '600px'],
title: __('Warning'),
btn: [__('Continue operate'), __('Cancel')],
end: function () {
},
yes: function () {
operate(name, action, true);
}
});
} else {
Layer.alert(ret.msg);
}
return false;
});
};
operate(name, action, false);
});
//点击升级
// 点击升级
$(document).on("click", ".btn-upgrade", function () {
if ($(this).closest(".operate").find("a.btn-disable").size() > 0) {
Layer.alert(__('Please disable addon first'), {icon: 7});
... ... @@ -389,24 +421,9 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template'], function
}
var name = $(this).closest(".operate").data("name");
var version = $(this).data("version");
var userinfo = Controller.api.userinfo.get();
var uid = userinfo ? userinfo.id : 0;
var token = userinfo ? userinfo.token : '';
var upgrade = function (name) {
Fast.api.ajax({
url: 'addon/upgrade',
data: {name: name, uid: uid, token: token, version: version, faversion: Config.fastadmin.version}
}, function (data, ret) {
Config['addons'][name].version = version;
Layer.closeAll();
$('.btn-refresh').trigger('click');
}, function (data, ret) {
Layer.alert(ret.msg);
return false;
});
};
Layer.confirm(__('Upgrade tips'), function () {
upgrade(name);
upgrade(name, version);
});
});
... ...
... ... @@ -20,7 +20,7 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template'], function
table.bootstrapTable({
url: $.fn.bootstrapTable.defaults.extend.index_url,
sortName: 'weigh',
escape:false,
escape: false,
columns: [
[
{field: 'state', checkbox: true, },
... ... @@ -41,10 +41,11 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template'], function
});
// 为表格绑定事件
Table.api.bindevent(table);//当内容渲染完成后
Table.api.bindevent(table);
//默认隐藏所有子节点
//当内容渲染完成后
table.on('post-body.bs.table', function (e, settings, json, xhr) {
//默认隐藏所有子节点
//$("a.btn[data-id][data-pid][data-pid!=0]").closest("tr").hide();
$(".btn-node-sub.disabled").closest("tr").hide();
... ... @@ -57,8 +58,15 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template'], function
$(this).data("shown", !status);
return false;
});
$(".btn-change[data-id],.btn-delone,.btn-dragsort").data("success", function (data, ret) {
Fast.api.refreshmenu();
});
});
//批量删除后的回调
$(".toolbar > .btn-del,.toolbar .btn-more~ul>li>a").data("success", function (e) {
Fast.api.refreshmenu();
});
//展开隐藏一级
$(document.body).on("click", ".btn-toggle", function (e) {
$("a.btn[data-id][data-pid][data-pid!=0].disabled").closest("tr").hide();
... ... @@ -88,21 +96,21 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template'], function
api: {
formatter: {
title: function (value, row, index) {
return !row.ismenu ? "<span class='text-muted'>" + value + "</span>" : value;
return !row.ismenu || row.status == 'hidden' ? "<span class='text-muted'>" + value + "</span>" : value;
},
name: function (value, row, index) {
return !row.ismenu ? "<span class='text-muted'>" + value + "</span>" : value;
return !row.ismenu || row.status == 'hidden' ? "<span class='text-muted'>" + value + "</span>" : value;
},
menu: function (value, row, index) {
return "<a href='javascript:;' class='btn btn-" + (value ? "info" : "default") + " btn-xs btn-change' data-id='"
+ row.id + "' data-params='ismenu=" + (value ? 0 : 1) + "'>" + (value ? __('Yes') : __('No')) + "</a>";
},
icon: function (value, row, index) {
return '<i class="' + value + '"></i>';
return '<span class="' + (!row.ismenu || row.status == 'hidden' ? 'text-muted' : '') + '"><i class="' + value + '"></i></span>';
},
subnode: function (value, row, index) {
return '<a href="javascript:;" data-id="' + row['id'] + '" data-pid="' + row['pid'] + '" class="btn btn-xs '
+ (row['haschild'] == 1 ? 'btn-success' : 'btn-default disabled') + ' btn-node-sub"><i class="fa fa-sitemap"></i></a>';
return '<a href="javascript:;" data-id="' + row.id + '" data-pid="' + row.pid + '" class="btn btn-xs '
+ (row.haschild == 1 || row.ismenu == 1 ? 'btn-success' : 'btn-default disabled') + ' btn-node-sub"><i class="fa fa-sitemap"></i></a>';
}
},
bindevent: function () {
... ... @@ -113,7 +121,9 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template'], function
$("input[name='row[ismenu]']:checked").trigger("click");
var iconlist = [];
Form.api.bindevent($("form[role=form]"));
Form.api.bindevent($("form[role=form]"), function (data) {
Fast.api.refreshmenu();
});
$(document).on('click', ".btn-search-icon", function () {
if (iconlist.length == 0) {
$.get(Config.site.cdnurl + "/assets/libs/font-awesome/less/variables.less", function (ret) {
... ...
... ... @@ -178,6 +178,21 @@ define(['jquery', 'bootstrap', 'backend', 'addtabs', 'adminlte', 'form'], functi
}
});
//刷新菜单事件
$(document).on('refresh', '.sidebar-menu', function () {
Fast.api.ajax({
url: 'index/index',
data: {action: 'refreshmenu'}
}, function (data) {
$(".sidebar-menu li:not([data-rel='external'])").remove();
$(data.menulist).insertBefore($(".sidebar-menu li:first"));
$("#nav ul li[role='presentation'].active a").trigger('click');
return false;
}, function () {
return false;
});
});
//这一行需要放在点击左侧链接事件之前
var addtabs = Config.referer ? localStorage.getItem("addtabs") : null;
... ... @@ -188,6 +203,7 @@ define(['jquery', 'bootstrap', 'backend', 'addtabs', 'adminlte', 'form'], functi
} else {
$("ul.sidebar-menu li a[url!='javascript:;']:first").trigger("click");
}
//如果是刷新操作则直接返回刷新前的页面
if (Config.referer) {
if (Config.referer === $(addtabs).attr("url")) {
... ... @@ -203,11 +219,6 @@ define(['jquery', 'bootstrap', 'backend', 'addtabs', 'adminlte', 'form'], functi
}
}
/**
* List of all the available skins
*
* @type Array
*/
var my_skins = [
"skin-blue",
"skin-white",
... ... @@ -224,19 +235,13 @@ define(['jquery', 'bootstrap', 'backend', 'addtabs', 'adminlte', 'form'], functi
];
setup();
/**
* Toggles layout classes
*
* @param String cls the layout class to toggle
* @returns void
*/
function change_layout(cls) {
$("body").toggleClass(cls);
AdminLTE.layout.fixSidebar();
//Fix the problem with right sidebar and layout boxed
if (cls == "layout-boxed")
AdminLTE.controlSidebar._fix($(".control-sidebar-bg"));
if ($('body').hasClass('fixed') && cls == 'fixed' && false) {
if ($('body').hasClass('fixed') && cls == 'fixed') {
AdminLTE.pushMenu.expandOnHover();
AdminLTE.layout.activate();
}
... ... @@ -244,61 +249,18 @@ define(['jquery', 'bootstrap', 'backend', 'addtabs', 'adminlte', 'form'], functi
AdminLTE.controlSidebar._fix($(".control-sidebar"));
}
/**
* Replaces the old skin with the new skin
* @param String cls the new skin class
* @returns Boolean false to prevent link's default action
*/
function change_skin(cls) {
if (!$("body").hasClass(cls)) {
$.each(my_skins, function (i) {
$("body").removeClass(my_skins[i]);
});
$("body").addClass(cls);
store('skin', cls);
$("body").removeClass(my_skins.join(' ')).addClass(cls);
localStorage.setItem('skin', cls);
var cssfile = Config.site.cdnurl + "/assets/css/skins/" + cls + ".css";
$('head').append('<link rel="stylesheet" href="' + cssfile + '" type="text/css" />');
}
return false;
}
/**
* Store a new settings in the browser
*
* @param String name Name of the setting
* @param String val Value of the setting
* @returns void
*/
function store(name, val) {
if (typeof (Storage) !== "undefined") {
localStorage.setItem(name, val);
} else {
window.alert('Please use a modern browser to properly view this template!');
}
}
/**
* Get a prestored setting
*
* @param String name Name of of the setting
* @returns String The value of the setting | null
*/
function get(name) {
if (typeof (Storage) !== "undefined") {
return localStorage.getItem(name);
} else {
window.alert('Please use a modern browser to properly view this template!');
}
}
/**
* Retrieve default settings and apply them to the template
*
* @returns void
*/
function setup() {
var tmp = get('skin');
var tmp = localStorage.getItem('skin');
if (tmp && $.inArray(tmp, my_skins))
change_skin(tmp);
... ...
... ... @@ -28,7 +28,7 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
{field: 'id', title: __('Id')},
{field: 'pid', title: __('Pid'), visible: false},
{field: 'title', title: __('Title'), align: 'left'},
{field: 'name', title: __('Name')},
{field: 'name', title: __('Name'), align: 'left'},
{field: 'remark', title: __('Remark')},
{field: 'ismenu', title: __('Ismenu'), formatter: Controller.api.formatter.toggle},
{field: 'createtime', title: __('Createtime'), formatter: Table.api.formatter.datetime, visible: false},
... ...
... ... @@ -104,7 +104,7 @@
var createFormCommon = function (pColumns, that) {
var htmlForm = [];
var opList = ['=', '>', '>=', '<', '<=', '!=', 'LIKE', 'LIKE %...%', 'NOT LIKE', 'IN', 'NOT IN', 'IN(...)', 'NOT IN(...)', 'BETWEEN', 'NOT BETWEEN', 'RANGE', 'NOT RANGE', 'IS NULL', 'IS NOT NULL'];
var opList = ['=', '>', '>=', '<', '<=', '!=', 'FIND_IN_SET', 'LIKE', 'LIKE %...%', 'NOT LIKE', 'IN', 'NOT IN', 'IN(...)', 'NOT IN(...)', 'BETWEEN', 'NOT BETWEEN', 'RANGE', 'NOT RANGE', 'IS NULL', 'IS NOT NULL'];
htmlForm.push(sprintf('<form class="form-horizontal form-commonsearch" action="%s" >', that.options.actionForm));
htmlForm.push('<fieldset>');
if (that.options.titleForm.length > 0)
... ...
... ... @@ -33,6 +33,7 @@
if (!that.options.templateView) {
return;
}
that.options.cardView = true;
};
... ...
... ... @@ -164,8 +164,7 @@ define(['jquery', 'bootstrap', 'toastr', 'layer', 'lang'], function ($, undefine
options.area = [top.$(".tab-pane.active").width() + "px", top.$(".tab-pane.active").height() + "px"];
options.offset = [top.$(".tab-pane.active").scrollTop() + "px", "0px"];
}
Layer.open(options);
return false;
return Layer.open(options);
},
//关闭窗口并回传数据
close: function (data) {
... ...
define(['frontend'], function (Frontend) {
});
\ No newline at end of file
... ...
... ... @@ -7,7 +7,7 @@ require.config({
}
],
//在打包压缩时将会把include中的模块合并到主文件中
include: ['css', 'layer', 'toastr', 'fast', 'backend', 'table', 'form', 'dragsort', 'drag', 'drop', 'addtabs', 'selectpage'],
include: ['css', 'layer', 'toastr', 'fast', 'backend', 'backend-init', 'table', 'form', 'dragsort', 'drag', 'drop', 'addtabs', 'selectpage'],
paths: {
'lang': "empty:",
'form': 'require-form',
... ... @@ -34,22 +34,20 @@ require.config({
'bootstrap-table-mobile': '../libs/bootstrap-table/dist/extensions/mobile/bootstrap-table-mobile',
'bootstrap-table-lang': '../libs/bootstrap-table/dist/locale/bootstrap-table-zh-CN',
'tableexport': '../libs/tableExport.jquery.plugin/tableExport.min',
'dragsort': '../libs/dragsort/jquery.dragsort',
'qrcode': '../libs/jquery-qrcode/jquery.qrcode.min',
'dragsort': '../libs/fastadmin-dragsort/jquery.dragsort',
'sortable': '../libs/Sortable/Sortable.min',
'addtabs': '../libs/jquery-addtabs/jquery.addtabs',
'addtabs': '../libs/fastadmin-addtabs/jquery.addtabs',
'slimscroll': '../libs/jquery-slimscroll/jquery.slimscroll',
'summernote': '../libs/summernote/dist/lang/summernote-zh-CN.min',
'validator-core': '../libs/nice-validator/dist/jquery.validator',
'validator-lang': '../libs/nice-validator/dist/local/zh-CN',
'plupload': '../libs/plupload/js/plupload.min',
'toastr': '../libs/toastr/toastr',
'jstree': '../libs/jstree/dist/jstree.min',
'layer': '../libs/layer/src/layer',
'layer': '../libs/layer/dist/layer',
'cookie': '../libs/jquery.cookie/jquery.cookie',
'cxselect': '../libs/jquery-cxselect/js/jquery.cxselect',
'cxselect': '../libs/fastadmin-cxselect/js/jquery.cxselect',
'template': '../libs/art-template/dist/template-native',
'selectpage': '../libs/selectpage/selectpage',
'selectpage': '../libs/fastadmin-selectpage/selectpage',
'citypicker': '../libs/city-picker/dist/js/city-picker.min',
'citypicker-data': '../libs/city-picker/dist/js/city-picker.data',
},
... ... @@ -106,7 +104,6 @@ require.config({
],
'bootstrap-select': ['css!../libs/bootstrap-select/dist/css/bootstrap-select.min.css', ],
'bootstrap-select-lang': ['bootstrap-select'],
'summernote': ['../libs/summernote/dist/summernote.min', 'css!../libs/summernote/dist/summernote.css'],
// 'toastr': ['css!../libs/toastr/toastr.min.css'],
'jstree': ['css!../libs/jstree/dist/themes/default/style.css', ],
'plupload': {
... ... @@ -116,7 +113,7 @@ require.config({
// 'layer': ['css!../libs/layer/dist/theme/default/layer.css'],
// 'validator-core': ['css!../libs/nice-validator/dist/jquery.validator.css'],
'validator-lang': ['validator-core'],
// 'selectpage': ['css!../libs/selectpage/selectpage.css'],
// 'selectpage': ['css!../libs/fastadmin-selectpage/selectpage.css'],
'citypicker': ['citypicker-data', 'css!../libs/city-picker/dist/css/city-picker.css']
},
baseUrl: requirejs.s.contexts._.config.config.site.cdnurl + '/assets/js/', //资源基础路径
... ... @@ -144,7 +141,7 @@ require(['jquery', 'bootstrap'], function ($, undefined) {
// 初始化
$(function () {
require(['fast'], function (Fast) {
require(['backend', 'addons'], function (Backend, Addons) {
require(['backend', 'backend-init', 'addons'], function (Backend, undefined, Addons) {
//加载相应模块
if (Config.jsname) {
require([Config.jsname], function (Controller) {
... ...
... ... @@ -40,6 +40,9 @@ define(['jquery', 'bootstrap', 'upload', 'validator'], function ($, undefined, U
Form.api.submit($(ret), function (data, ret) {
that.holdSubmit(false);
submitBtn.removeClass("disabled");
if (false === $(this).triggerHandler("success.form", [data, ret])) {
return false;
}
if (typeof success === 'function') {
if (false === success.call($(this), data, ret)) {
return false;
... ... @@ -54,6 +57,9 @@ define(['jquery', 'bootstrap', 'upload', 'validator'], function ($, undefined, U
return false;
}, function (data, ret) {
that.holdSubmit(false);
if (false === $(this).triggerHandler("error.form", [data, ret])) {
return false;
}
submitBtn.removeClass("disabled");
if (typeof error === 'function') {
if (false === error.call($(this), data, ret)) {
... ... @@ -81,13 +87,25 @@ define(['jquery', 'bootstrap', 'upload', 'validator'], function ($, undefined, U
if ($(".selectpage", form).size() > 0) {
require(['selectpage'], function () {
$('.selectpage', form).selectPage({
source: 'ajax/selectpage',
eAjaxSuccess: function (data) {
data.list = typeof data.rows !== 'undefined' ? data.rows : (typeof data.list !== 'undefined' ? data.list : []);
data.totalRow = typeof data.total !== 'undefined' ? data.total : (typeof data.totalRow !== 'undefined' ? data.totalRow : data.list.length);
return data;
}
});
});
//给隐藏的元素添加上validate验证触发事件
$(form).on("change", ".selectpage-input-hidden", function () {
$(document).on("change", ".sp_hidden", function () {
$(this).trigger("validate");
});
$(document).on("change", ".sp_input", function () {
$(this).closest(".sp_container").find(".sp_hidden").trigger("change");
});
$(form).on("reset", function () {
setTimeout(function () {
$('.selectpage', form).selectPageClear();
}, 1);
});
}
},
cxselect: function (form) {
... ... @@ -132,6 +150,48 @@ define(['jquery', 'bootstrap', 'upload', 'validator'], function ($, undefined, U
});
}
},
daterangepicker: function (form) {
//绑定日期时间元素事件
if ($(".datetimerange", form).size() > 0) {
require(['bootstrap-daterangepicker'], function () {
var ranges = {};
ranges[__('Today')] = [Moment().startOf('day'), Moment().endOf('day')];
ranges[__('Yesterday')] = [Moment().subtract(1, 'days').startOf('day'), Moment().subtract(1, 'days').endOf('day')];
ranges[__('Last 7 Days')] = [Moment().subtract(6, 'days').startOf('day'), Moment().endOf('day')];
ranges[__('Last 30 Days')] = [Moment().subtract(29, 'days').startOf('day'), Moment().endOf('day')];
ranges[__('This Month')] = [Moment().startOf('month'), Moment().endOf('month')];
ranges[__('Last Month')] = [Moment().subtract(1, 'month').startOf('month'), Moment().subtract(1, 'month').endOf('month')];
var options = {
timePicker: false,
autoUpdateInput: false,
timePickerSeconds: true,
timePicker24Hour: true,
autoApply: true,
locale: {
format: 'YYYY-MM-DD HH:mm:ss',
customRangeLabel: __("Custom Range"),
applyLabel: __("Apply"),
cancelLabel: __("Clear"),
},
ranges: ranges,
};
var origincallback = function (start, end) {
$(this.element).val(start.format(options.locale.format) + " - " + end.format(options.locale.format));
$(this.element).trigger('blur');
};
$(".datetimerange", form).each(function () {
var callback = typeof $(this).data('callback') == 'function' ? $(this).data('callback') : origincallback;
$(this).on('apply.daterangepicker', function (ev, picker) {
callback.call(picker, picker.startDate, picker.endDate);
});
$(this).on('cancel.daterangepicker', function (ev, picker) {
$(this).val('').trigger('blur');
});
$(this).daterangepicker($.extend({}, options, $(this).data()), callback);
});
});
}
},
plupload: function (form) {
//绑定plupload上传元素事件
if ($(".plupload", form).size() > 0) {
... ... @@ -287,6 +347,8 @@ define(['jquery', 'bootstrap', 'upload', 'validator'], function ($, undefined, U
events.selectpicker(form);
events.daterangepicker(form);
events.selectpage(form);
events.cxselect(form);
... ...
... ... @@ -7,7 +7,7 @@ require.config({
}
],
//在打包压缩时将会把include中的模块合并到主文件中
include: ['css', 'layer', 'toastr', 'fast', 'frontend'],
include: ['css', 'layer', 'toastr', 'fast', 'frontend', 'frontend-init'],
paths: {
'lang': "empty:",
'form': 'require-form',
... ... @@ -34,22 +34,20 @@ require.config({
'bootstrap-table-mobile': '../libs/bootstrap-table/dist/extensions/mobile/bootstrap-table-mobile',
'bootstrap-table-lang': '../libs/bootstrap-table/dist/locale/bootstrap-table-zh-CN',
'tableexport': '../libs/tableExport.jquery.plugin/tableExport.min',
'dragsort': '../libs/dragsort/jquery.dragsort',
'qrcode': '../libs/jquery-qrcode/jquery.qrcode.min',
'dragsort': '../libs/fastadmin-dragsort/jquery.dragsort',
'sortable': '../libs/Sortable/Sortable.min',
'addtabs': '../libs/jquery-addtabs/jquery.addtabs',
'addtabs': '../libs/fastadmin-addtabs/jquery.addtabs',
'slimscroll': '../libs/jquery-slimscroll/jquery.slimscroll',
'summernote': '../libs/summernote/dist/lang/summernote-zh-CN.min',
'validator-core': '../libs/nice-validator/dist/jquery.validator',
'validator-lang': '../libs/nice-validator/dist/local/zh-CN',
'plupload': '../libs/plupload/js/plupload.min',
'toastr': '../libs/toastr/toastr',
'jstree': '../libs/jstree/dist/jstree.min',
'layer': '../libs/layer/src/layer',
'layer': '../libs/layer/dist/layer',
'cookie': '../libs/jquery.cookie/jquery.cookie',
'cxselect': '../libs/jquery-cxselect/js/jquery.cxselect',
'cxselect': '../libs/fastadmin-cxselect/js/jquery.cxselect',
'template': '../libs/art-template/dist/template-native',
'selectpage': '../libs/selectpage/selectpage',
'selectpage': '../libs/fastadmin-selectpage/selectpage',
'citypicker': '../libs/city-picker/dist/js/city-picker.min',
'citypicker-data': '../libs/city-picker/dist/js/city-picker.data',
},
... ... @@ -106,7 +104,6 @@ require.config({
],
'bootstrap-select': ['css!../libs/bootstrap-select/dist/css/bootstrap-select.min.css', ],
'bootstrap-select-lang': ['bootstrap-select'],
'summernote': ['../libs/summernote/dist/summernote.min', 'css!../libs/summernote/dist/summernote.css'],
// 'toastr': ['css!../libs/toastr/toastr.min.css'],
'jstree': ['css!../libs/jstree/dist/themes/default/style.css', ],
'plupload': {
... ... @@ -116,7 +113,7 @@ require.config({
// 'layer': ['css!../libs/layer/dist/theme/default/layer.css'],
// 'validator-core': ['css!../libs/nice-validator/dist/jquery.validator.css'],
'validator-lang': ['validator-core'],
// 'selectpage': ['css!../libs/selectpage/selectpage.css'],
// 'selectpage': ['css!../libs/fastadmin-selectpage/selectpage.css'],
'citypicker': ['citypicker-data', 'css!../libs/city-picker/dist/css/city-picker.css']
},
baseUrl: requirejs.s.contexts._.config.config.site.cdnurl + '/assets/js/', //资源基础路径
... ...
... ... @@ -21,7 +21,7 @@ require.config({
}
],
//在打包压缩时将会把include中的模块合并到主文件中
include: ['css', 'layer', 'toastr', 'fast', 'frontend'],
include: ['css', 'layer', 'toastr', 'fast', 'frontend', 'frontend-init'],
paths: {
'lang': "empty:",
'form': 'require-form',
... ... @@ -48,22 +48,20 @@ require.config({
'bootstrap-table-mobile': '../libs/bootstrap-table/dist/extensions/mobile/bootstrap-table-mobile',
'bootstrap-table-lang': '../libs/bootstrap-table/dist/locale/bootstrap-table-zh-CN',
'tableexport': '../libs/tableExport.jquery.plugin/tableExport.min',
'dragsort': '../libs/dragsort/jquery.dragsort',
'qrcode': '../libs/jquery-qrcode/jquery.qrcode.min',
'dragsort': '../libs/fastadmin-dragsort/jquery.dragsort',
'sortable': '../libs/Sortable/Sortable.min',
'addtabs': '../libs/jquery-addtabs/jquery.addtabs',
'addtabs': '../libs/fastadmin-addtabs/jquery.addtabs',
'slimscroll': '../libs/jquery-slimscroll/jquery.slimscroll',
'summernote': '../libs/summernote/dist/lang/summernote-zh-CN.min',
'validator-core': '../libs/nice-validator/dist/jquery.validator',
'validator-lang': '../libs/nice-validator/dist/local/zh-CN',
'plupload': '../libs/plupload/js/plupload.min',
'toastr': '../libs/toastr/toastr',
'jstree': '../libs/jstree/dist/jstree.min',
'layer': '../libs/layer/src/layer',
'layer': '../libs/layer/dist/layer',
'cookie': '../libs/jquery.cookie/jquery.cookie',
'cxselect': '../libs/jquery-cxselect/js/jquery.cxselect',
'cxselect': '../libs/fastadmin-cxselect/js/jquery.cxselect',
'template': '../libs/art-template/dist/template-native',
'selectpage': '../libs/selectpage/selectpage',
'selectpage': '../libs/fastadmin-selectpage/selectpage',
'citypicker': '../libs/city-picker/dist/js/city-picker.min',
'citypicker-data': '../libs/city-picker/dist/js/city-picker.data',
},
... ... @@ -120,7 +118,6 @@ require.config({
],
'bootstrap-select': ['css!../libs/bootstrap-select/dist/css/bootstrap-select.min.css', ],
'bootstrap-select-lang': ['bootstrap-select'],
'summernote': ['../libs/summernote/dist/summernote.min', 'css!../libs/summernote/dist/summernote.css'],
// 'toastr': ['css!../libs/toastr/toastr.min.css'],
'jstree': ['css!../libs/jstree/dist/themes/default/style.css', ],
'plupload': {
... ... @@ -130,7 +127,7 @@ require.config({
// 'layer': ['css!../libs/layer/dist/theme/default/layer.css'],
// 'validator-core': ['css!../libs/nice-validator/dist/jquery.validator.css'],
'validator-lang': ['validator-core'],
// 'selectpage': ['css!../libs/selectpage/selectpage.css'],
// 'selectpage': ['css!../libs/fastadmin-selectpage/selectpage.css'],
'citypicker': ['citypicker-data', 'css!../libs/city-picker/dist/css/city-picker.css']
},
baseUrl: requirejs.s.contexts._.config.config.site.cdnurl + '/assets/js/', //资源基础路径
... ... @@ -176,1311 +173,8 @@ require(['jquery', 'bootstrap'], function ($, undefined) {
define("require-frontend", function(){});
define('../libs/require-css/css.min',[],function(){if("undefined"==typeof window)return{load:function(a,b,c){c()}};var a=document.getElementsByTagName("head")[0],b=window.navigator.userAgent.match(/Trident\/([^ ;]*)|AppleWebKit\/([^ ;]*)|Opera\/([^ ;]*)|rv\:([^ ;]*)(.*?)Gecko\/([^ ;]*)|MSIE\s([^ ;]*)|AndroidWebKit\/([^ ;]*)/)||0,c=!1,d=!0;b[1]||b[7]?c=parseInt(b[1])<6||parseInt(b[7])<=9:b[2]||b[8]?d=!1:b[4]&&(c=parseInt(b[4])<18);var e={};e.pluginBuilder="./css-builder";var f,g,h,i=function(){f=document.createElement("style"),a.appendChild(f),g=f.styleSheet||f.sheet},j=0,k=[],l=function(a){g.addImport(a),f.onload=function(){m()},j++,31==j&&(i(),j=0)},m=function(){h();var a=k.shift();return a?(h=a[1],void l(a[0])):void(h=null)},n=function(a,b){if(g&&g.addImport||i(),g&&g.addImport)h?k.push([a,b]):(l(a),h=b);else{f.textContent='@import "'+a+'";';var c=setInterval(function(){try{f.sheet.cssRules,clearInterval(c),b()}catch(a){}},10)}},o=function(b,c){var e=document.createElement("link");if(e.type="text/css",e.rel="stylesheet",d)e.onload=function(){e.onload=function(){},setTimeout(c,7)};else var f=setInterval(function(){for(var a=0;a<document.styleSheets.length;a++){var b=document.styleSheets[a];if(b.href==e.href)return clearInterval(f),c()}},10);e.href=b,a.appendChild(e)};return e.normalize=function(a,b){return".css"==a.substr(a.length-4,4)&&(a=a.substr(0,a.length-4)),b(a)},e.load=function(a,b,d,e){(c?n:o)(b.toUrl(a+".css"),d)},e});
/**
@Name:layer v3.1.1 Web弹层组件
@Author:贤心
@Site:http://layer.layui.com
@License:MIT
*/
;!function(window, undefined){
"use strict";
var isLayui = window.layui && layui.define, $, win, ready = {
getPath: function(){
var jsPath = document.currentScript ? document.currentScript.src : function(){
var js = document.scripts
,last = js.length - 1
,src;
for(var i = last; i > 0; i--){
if(js[i].readyState === 'interactive'){
src = js[i].src;
break;
}
}
return src || js[last].src;
}();
return jsPath.substring(0, jsPath.lastIndexOf('/') + 1);
}(),
config: {}, end: {}, minIndex: 0, minLeft: [],
btn: ['&#x786E;&#x5B9A;', '&#x53D6;&#x6D88;'],
//五种原始层模式
type: ['dialog', 'page', 'iframe', 'loading', 'tips'],
//获取节点的style属性值
getStyle: function(node, name){
var style = node.currentStyle ? node.currentStyle : window.getComputedStyle(node, null);
return style[style.getPropertyValue ? 'getPropertyValue' : 'getAttribute'](name);
},
//载入CSS配件
link: function(href, fn, cssname){
//未设置路径,则不主动加载css
if(!layer.path) return;
var head = document.getElementsByTagName("head")[0], link = document.createElement('link');
if(typeof fn === 'string') cssname = fn;
var app = (cssname || href).replace(/\.|\//g, '');
var id = 'layuicss-'+ app, timeout = 0;
link.rel = 'stylesheet';
link.href = layer.path + href;
link.id = id;
if(!document.getElementById(id)){
head.appendChild(link);
}
if(typeof fn !== 'function') return;
//轮询css是否加载完毕
(function poll() {
if(++timeout > 8 * 1000 / 100){
return window.console && console.error('layer.css: Invalid');
};
parseInt(ready.getStyle(document.getElementById(id), 'width')) === 1989 ? fn() : setTimeout(poll, 100);
}());
}
};
//默认内置方法。
var layer = {
v: '3.1.1',
ie: function(){ //ie版本
var agent = navigator.userAgent.toLowerCase();
return (!!window.ActiveXObject || "ActiveXObject" in window) ? (
(agent.match(/msie\s(\d+)/) || [])[1] || '11' //由于ie11并没有msie的标识
) : false;
}(),
index: (window.layer && window.layer.v) ? 100000 : 0,
path: ready.getPath,
config: function(options, fn){
options = options || {};
layer.cache = ready.config = $.extend({}, ready.config, options);
layer.path = ready.config.path || layer.path;
typeof options.extend === 'string' && (options.extend = [options.extend]);
if(ready.config.path) layer.ready();
if(!options.extend) return this;
isLayui
? layui.addcss('modules/layer/' + options.extend)
: ready.link('theme/' + options.extend);
return this;
},
//主体CSS等待事件
ready: function(callback){
var cssname = 'layer', ver = ''
,path = (isLayui ? 'modules/layer/' : 'theme/') + 'default/layer.css?v='+ layer.v + ver;
isLayui ? layui.addcss(path, callback, cssname) : ready.link(path, callback, cssname);
return this;
},
//各种快捷引用
alert: function(content, options, yes){
var type = typeof options === 'function';
if(type) yes = options;
return layer.open($.extend({
content: content,
yes: yes
}, type ? {} : options));
},
confirm: function(content, options, yes, cancel){
var type = typeof options === 'function';
if(type){
cancel = yes;
yes = options;
}
return layer.open($.extend({
content: content,
btn: ready.btn,
yes: yes,
btn2: cancel
}, type ? {} : options));
},
msg: function(content, options, end){ //最常用提示层
var type = typeof options === 'function', rskin = ready.config.skin;
var skin = (rskin ? rskin + ' ' + rskin + '-msg' : '')||'layui-layer-msg';
var anim = doms.anim.length - 1;
if(type) end = options;
return layer.open($.extend({
content: content,
time: 3000,
shade: false,
skin: skin,
title: false,
closeBtn: false,
btn: false,
resize: false,
end: end
}, (type && !ready.config.skin) ? {
skin: skin + ' layui-layer-hui',
anim: anim
} : function(){
options = options || {};
if(options.icon === -1 || options.icon === undefined && !ready.config.skin){
options.skin = skin + ' ' + (options.skin||'layui-layer-hui');
}
return options;
}()));
},
load: function(icon, options){
return layer.open($.extend({
type: 3,
icon: icon || 0,
resize: false,
shade: 0.01
}, options));
},
tips: function(content, follow, options){
return layer.open($.extend({
type: 4,
content: [content, follow],
closeBtn: false,
time: 3000,
shade: false,
resize: false,
fixed: false,
maxWidth: 210
}, options));
}
};
var Class = function(setings){
var that = this;
that.index = ++layer.index;
that.config = $.extend({}, that.config, ready.config, setings);
document.body ? that.creat() : setTimeout(function(){
that.creat();
}, 30);
};
Class.pt = Class.prototype;
//缓存常用字符
var doms = ['layui-layer', '.layui-layer-title', '.layui-layer-main', '.layui-layer-dialog', 'layui-layer-iframe', 'layui-layer-content', 'layui-layer-btn', 'layui-layer-close'];
doms.anim = ['layer-anim-00', 'layer-anim-01', 'layer-anim-02', 'layer-anim-03', 'layer-anim-04', 'layer-anim-05', 'layer-anim-06'];
//默认配置
Class.pt.config = {
type: 0,
shade: 0.3,
fixed: true,
move: doms[1],
title: '&#x4FE1;&#x606F;',
offset: 'auto',
area: 'auto',
closeBtn: 1,
time: 0, //0表示不自动关闭
zIndex: 19891014,
maxWidth: 360,
anim: 0,
isOutAnim: true,
icon: -1,
moveType: 1,
resize: true,
scrollbar: true, //是否允许浏览器滚动条
tips: 2
};
//容器
Class.pt.vessel = function(conType, callback){
var that = this, times = that.index, config = that.config;
var zIndex = config.zIndex + times, titype = typeof config.title === 'object';
var ismax = config.maxmin && (config.type === 1 || config.type === 2);
var titleHTML = (config.title ? '<div class="layui-layer-title" style="'+ (titype ? config.title[1] : '') +'">'
+ (titype ? config.title[0] : config.title)
+ '</div>' : '');
config.zIndex = zIndex;
callback([
//遮罩
config.shade ? ('<div class="layui-layer-shade" id="layui-layer-shade'+ times +'" times="'+ times +'" style="'+ ('z-index:'+ (zIndex-1) +'; ') +'"></div>') : '',
//主体
'<div class="'+ doms[0] + (' layui-layer-'+ready.type[config.type]) + (((config.type == 0 || config.type == 2) && !config.shade) ? ' layui-layer-border' : '') + ' ' + (config.skin||'') +'" id="'+ doms[0] + times +'" type="'+ ready.type[config.type] +'" times="'+ times +'" showtime="'+ config.time +'" conType="'+ (conType ? 'object' : 'string') +'" style="z-index: '+ zIndex +'; width:'+ config.area[0] + ';height:' + config.area[1] + (config.fixed ? '' : ';position:absolute;') +'">'
+ (conType && config.type != 2 ? '' : titleHTML)
+ '<div id="'+ (config.id||'') +'" class="layui-layer-content'+ ((config.type == 0 && config.icon !== -1) ? ' layui-layer-padding' :'') + (config.type == 3 ? ' layui-layer-loading'+config.icon : '') +'">'
+ (config.type == 0 && config.icon !== -1 ? '<i class="layui-layer-ico layui-layer-ico'+ config.icon +'"></i>' : '')
+ (config.type == 1 && conType ? '' : (config.content||''))
+ '</div>'
+ '<span class="layui-layer-setwin">'+ function(){
var closebtn = ismax ? '<a class="layui-layer-min" href="javascript:;"><cite></cite></a><a class="layui-layer-ico layui-layer-max" href="javascript:;"></a>' : '';
config.closeBtn && (closebtn += '<a class="layui-layer-ico '+ doms[7] +' '+ doms[7] + (config.title ? config.closeBtn : (config.type == 4 ? '1' : '2')) +'" href="javascript:;"></a>');
return closebtn;
}() + '</span>'
+ (config.btn ? function(){
var button = '';
typeof config.btn === 'string' && (config.btn = [config.btn]);
for(var i = 0, len = config.btn.length; i < len; i++){
button += '<a class="'+ doms[6] +''+ i +'">'+ config.btn[i] +'</a>'
}
return '<div class="'+ doms[6] +' layui-layer-btn-'+ (config.btnAlign||'') +'">'+ button +'</div>'
}() : '')
+ (config.resize ? '<span class="layui-layer-resize"></span>' : '')
+ '</div>'
], titleHTML, $('<div class="layui-layer-move"></div>'));
return that;
};
//创建骨架
Class.pt.creat = function(){
var that = this
,config = that.config
,times = that.index, nodeIndex
,content = config.content
,conType = typeof content === 'object'
,body = $('body');
if(config.id && $('#'+config.id)[0]) return;
if(typeof config.area === 'string'){
config.area = config.area === 'auto' ? ['', ''] : [config.area, ''];
}
//anim兼容旧版shift
if(config.shift){
config.anim = config.shift;
}
if(layer.ie == 6){
config.fixed = false;
}
switch(config.type){
case 0:
config.btn = ('btn' in config) ? config.btn : ready.btn[0];
layer.closeAll('dialog');
break;
case 2:
var content = config.content = conType ? config.content : [config.content||'http://layer.layui.com', 'auto'];
config.content = '<iframe scrolling="'+ (config.content[1]||'auto') +'" allowtransparency="true" id="'+ doms[4] +''+ times +'" name="'+ doms[4] +''+ times +'" onload="this.className=\'\';" class="layui-layer-load" frameborder="0" src="' + config.content[0] + '"></iframe>';
break;
case 3:
delete config.title;
delete config.closeBtn;
config.icon === -1 && (config.icon === 0);
layer.closeAll('loading');
break;
case 4:
conType || (config.content = [config.content, 'body']);
config.follow = config.content[1];
config.content = config.content[0] + '<i class="layui-layer-TipsG"></i>';
delete config.title;
config.tips = typeof config.tips === 'object' ? config.tips : [config.tips, true];
config.tipsMore || layer.closeAll('tips');
break;
}
//建立容器
that.vessel(conType, function(html, titleHTML, moveElem){
body.append(html[0]);
conType ? function(){
(config.type == 2 || config.type == 4) ? function(){
$('body').append(html[1]);
}() : function(){
if(!content.parents('.'+doms[0])[0]){
content.data('display', content.css('display')).show().addClass('layui-layer-wrap').wrap(html[1]);
$('#'+ doms[0] + times).find('.'+doms[5]).before(titleHTML);
}
}();
}() : body.append(html[1]);
$('.layui-layer-move')[0] || body.append(ready.moveElem = moveElem);
that.layero = $('#'+ doms[0] + times);
config.scrollbar || doms.html.css('overflow', 'hidden').attr('layer-full', times);
}).auto(times);
//遮罩
$('#layui-layer-shade'+ that.index).css({
'background-color': config.shade[1] || '#000'
,'opacity': config.shade[0]||config.shade
});
config.type == 2 && layer.ie == 6 && that.layero.find('iframe').attr('src', content[0]);
//坐标自适应浏览器窗口尺寸
config.type == 4 ? that.tips() : that.offset();
if(config.fixed){
win.on('resize', function(){
that.offset();
(/^\d+%$/.test(config.area[0]) || /^\d+%$/.test(config.area[1])) && that.auto(times);
config.type == 4 && that.tips();
});
}
config.time <= 0 || setTimeout(function(){
layer.close(that.index)
}, config.time);
that.move().callback();
//为兼容jQuery3.0的css动画影响元素尺寸计算
if(doms.anim[config.anim]){
var animClass = 'layer-anim '+ doms.anim[config.anim];
that.layero.addClass(animClass).one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', function(){
$(this).removeClass(animClass);
});
};
//记录关闭动画
if(config.isOutAnim){
that.layero.data('isOutAnim', true);
}
};
//自适应
Class.pt.auto = function(index){
var that = this, config = that.config, layero = $('#'+ doms[0] + index);
if(config.area[0] === '' && config.maxWidth > 0){
//为了修复IE7下一个让人难以理解的bug
if(layer.ie && layer.ie < 8 && config.btn){
layero.width(layero.innerWidth());
}
layero.outerWidth() > config.maxWidth && layero.width(config.maxWidth);
}
var area = [layero.innerWidth(), layero.innerHeight()]
,titHeight = layero.find(doms[1]).outerHeight() || 0
,btnHeight = layero.find('.'+doms[6]).outerHeight() || 0
,setHeight = function(elem){
elem = layero.find(elem);
elem.height(area[1] - titHeight - btnHeight - 2*(parseFloat(elem.css('padding-top'))|0));
};
switch(config.type){
case 2:
setHeight('iframe');
break;
default:
if(config.area[1] === ''){
if(config.maxHeight > 0 && layero.outerHeight() > config.maxHeight){
area[1] = config.maxHeight;
setHeight('.'+doms[5]);
} else if(config.fixed && area[1] >= win.height()){
area[1] = win.height();
setHeight('.'+doms[5]);
}
} else {
setHeight('.'+doms[5]);
}
break;
};
return that;
};
//计算坐标
Class.pt.offset = function(){
var that = this, config = that.config, layero = that.layero;
var area = [layero.outerWidth(), layero.outerHeight()];
var type = typeof config.offset === 'object';
that.offsetTop = (win.height() - area[1])/2;
that.offsetLeft = (win.width() - area[0])/2;
if(type){
that.offsetTop = config.offset[0];
that.offsetLeft = config.offset[1]||that.offsetLeft;
} else if(config.offset !== 'auto'){
if(config.offset === 't'){ //上
that.offsetTop = 0;
} else if(config.offset === 'r'){ //右
that.offsetLeft = win.width() - area[0];
} else if(config.offset === 'b'){ //下
that.offsetTop = win.height() - area[1];
} else if(config.offset === 'l'){ //左
that.offsetLeft = 0;
} else if(config.offset === 'lt'){ //左上角
that.offsetTop = 0;
that.offsetLeft = 0;
} else if(config.offset === 'lb'){ //左下角
that.offsetTop = win.height() - area[1];
that.offsetLeft = 0;
} else if(config.offset === 'rt'){ //右上角
that.offsetTop = 0;
that.offsetLeft = win.width() - area[0];
} else if(config.offset === 'rb'){ //右下角
that.offsetTop = win.height() - area[1];
that.offsetLeft = win.width() - area[0];
} else {
that.offsetTop = config.offset;
}
}
if(!config.fixed){
that.offsetTop = /%$/.test(that.offsetTop) ?
win.height()*parseFloat(that.offsetTop)/100
: parseFloat(that.offsetTop);
that.offsetLeft = /%$/.test(that.offsetLeft) ?
win.width()*parseFloat(that.offsetLeft)/100
: parseFloat(that.offsetLeft);
that.offsetTop += win.scrollTop();
that.offsetLeft += win.scrollLeft();
}
if(layero.attr('minLeft')){
that.offsetTop = win.height() - (layero.find(doms[1]).outerHeight() || 0);
that.offsetLeft = layero.css('left');
}
layero.css({top: that.offsetTop, left: that.offsetLeft});
};
//Tips
Class.pt.tips = function(){
var that = this, config = that.config, layero = that.layero;
var layArea = [layero.outerWidth(), layero.outerHeight()], follow = $(config.follow);
if(!follow[0]) follow = $('body');
var goal = {
width: follow.outerWidth(),
height: follow.outerHeight(),
top: follow.offset().top,
left: follow.offset().left
}, tipsG = layero.find('.layui-layer-TipsG');
var guide = config.tips[0];
config.tips[1] || tipsG.remove();
goal.autoLeft = function(){
if(goal.left + layArea[0] - win.width() > 0){
goal.tipLeft = goal.left + goal.width - layArea[0];
tipsG.css({right: 12, left: 'auto'});
} else {
goal.tipLeft = goal.left;
};
};
//辨别tips的方位
goal.where = [function(){ //上
goal.autoLeft();
goal.tipTop = goal.top - layArea[1] - 10;
tipsG.removeClass('layui-layer-TipsB').addClass('layui-layer-TipsT').css('border-right-color', config.tips[1]);
}, function(){ //右
goal.tipLeft = goal.left + goal.width + 10;
goal.tipTop = goal.top;
tipsG.removeClass('layui-layer-TipsL').addClass('layui-layer-TipsR').css('border-bottom-color', config.tips[1]);
}, function(){ //下
goal.autoLeft();
goal.tipTop = goal.top + goal.height + 10;
tipsG.removeClass('layui-layer-TipsT').addClass('layui-layer-TipsB').css('border-right-color', config.tips[1]);
}, function(){ //左
goal.tipLeft = goal.left - layArea[0] - 10;
goal.tipTop = goal.top;
tipsG.removeClass('layui-layer-TipsR').addClass('layui-layer-TipsL').css('border-bottom-color', config.tips[1]);
}];
goal.where[guide-1]();
/* 8*2为小三角形占据的空间 */
if(guide === 1){
goal.top - (win.scrollTop() + layArea[1] + 8*2) < 0 && goal.where[2]();
} else if(guide === 2){
win.width() - (goal.left + goal.width + layArea[0] + 8*2) > 0 || goal.where[3]()
} else if(guide === 3){
(goal.top - win.scrollTop() + goal.height + layArea[1] + 8*2) - win.height() > 0 && goal.where[0]();
} else if(guide === 4){
layArea[0] + 8*2 - goal.left > 0 && goal.where[1]()
}
layero.find('.'+doms[5]).css({
'background-color': config.tips[1],
'padding-right': (config.closeBtn ? '30px' : '')
});
layero.css({
left: goal.tipLeft - (config.fixed ? win.scrollLeft() : 0),
top: goal.tipTop - (config.fixed ? win.scrollTop() : 0)
});
}
//拖拽层
Class.pt.move = function(){
var that = this
,config = that.config
,_DOC = $(document)
,layero = that.layero
,moveElem = layero.find(config.move)
,resizeElem = layero.find('.layui-layer-resize')
,dict = {};
if(config.move){
moveElem.css('cursor', 'move');
}
moveElem.on('mousedown', function(e){
e.preventDefault();
if(config.move){
dict.moveStart = true;
dict.offset = [
e.clientX - parseFloat(layero.css('left'))
,e.clientY - parseFloat(layero.css('top'))
];
ready.moveElem.css('cursor', 'move').show();
}
});
resizeElem.on('mousedown', function(e){
e.preventDefault();
dict.resizeStart = true;
dict.offset = [e.clientX, e.clientY];
dict.area = [
layero.outerWidth()
,layero.outerHeight()
];
ready.moveElem.css('cursor', 'se-resize').show();
});
_DOC.on('mousemove', function(e){
//拖拽移动
if(dict.moveStart){
var X = e.clientX - dict.offset[0]
,Y = e.clientY - dict.offset[1]
,fixed = layero.css('position') === 'fixed';
e.preventDefault();
dict.stX = fixed ? 0 : win.scrollLeft();
dict.stY = fixed ? 0 : win.scrollTop();
//控制元素不被拖出窗口外
if(!config.moveOut){
var setRig = win.width() - layero.outerWidth() + dict.stX
,setBot = win.height() - layero.outerHeight() + dict.stY;
X < dict.stX && (X = dict.stX);
X > setRig && (X = setRig);
Y < dict.stY && (Y = dict.stY);
Y > setBot && (Y = setBot);
}
layero.css({
left: X
,top: Y
});
}
//Resize
if(config.resize && dict.resizeStart){
var X = e.clientX - dict.offset[0]
,Y = e.clientY - dict.offset[1];
e.preventDefault();
layer.style(that.index, {
width: dict.area[0] + X
,height: dict.area[1] + Y
})
dict.isResize = true;
config.resizing && config.resizing(layero);
}
}).on('mouseup', function(e){
if(dict.moveStart){
delete dict.moveStart;
ready.moveElem.hide();
config.moveEnd && config.moveEnd(layero);
}
if(dict.resizeStart){
delete dict.resizeStart;
ready.moveElem.hide();
}
});
return that;
};
Class.pt.callback = function(){
var that = this, layero = that.layero, config = that.config;
that.openLayer();
if(config.success){
if(config.type == 2){
layero.find('iframe').on('load', function(){
config.success(layero, that.index);
});
} else {
config.success(layero, that.index);
}
}
layer.ie == 6 && that.IE6(layero);
//按钮
layero.find('.'+ doms[6]).children('a').on('click', function(){
var index = $(this).index();
if(index === 0){
if(config.yes){
config.yes(that.index, layero)
} else if(config['btn1']){
config['btn1'](that.index, layero)
} else {
layer.close(that.index);
}
} else {
var close = config['btn'+(index+1)] && config['btn'+(index+1)](that.index, layero);
close === false || layer.close(that.index);
}
});
//取消
function cancel(){
var close = config.cancel && config.cancel(that.index, layero);
close === false || layer.close(that.index);
}
//右上角关闭回调
layero.find('.'+ doms[7]).on('click', cancel);
//点遮罩关闭
if(config.shadeClose){
$('#layui-layer-shade'+ that.index).on('click', function(){
layer.close(that.index);
});
}
//最小化
layero.find('.layui-layer-min').on('click', function(){
var min = config.min && config.min(layero);
min === false || layer.min(that.index, config);
});
//全屏/还原
layero.find('.layui-layer-max').on('click', function(){
if($(this).hasClass('layui-layer-maxmin')){
layer.restore(that.index);
config.restore && config.restore(layero);
} else {
layer.full(that.index, config);
setTimeout(function(){
config.full && config.full(layero);
}, 100);
}
});
config.end && (ready.end[that.index] = config.end);
};
//for ie6 恢复select
ready.reselect = function(){
$.each($('select'), function(index , value){
var sthis = $(this);
if(!sthis.parents('.'+doms[0])[0]){
(sthis.attr('layer') == 1 && $('.'+doms[0]).length < 1) && sthis.removeAttr('layer').show();
}
sthis = null;
});
};
Class.pt.IE6 = function(layero){
//隐藏select
$('select').each(function(index , value){
var sthis = $(this);
if(!sthis.parents('.'+doms[0])[0]){
sthis.css('display') === 'none' || sthis.attr({'layer' : '1'}).hide();
}
sthis = null;
});
};
//需依赖原型的对外方法
Class.pt.openLayer = function(){
var that = this;
//置顶当前窗口
layer.zIndex = that.config.zIndex;
layer.setTop = function(layero){
var setZindex = function(){
layer.zIndex++;
layero.css('z-index', layer.zIndex + 1);
};
layer.zIndex = parseInt(layero[0].style.zIndex);
layero.on('mousedown', setZindex);
return layer.zIndex;
};
};
ready.record = function(layero){
var area = [
layero.width(),
layero.height(),
layero.position().top,
layero.position().left + parseFloat(layero.css('margin-left'))
];
layero.find('.layui-layer-max').addClass('layui-layer-maxmin');
layero.attr({area: area});
};
ready.rescollbar = function(index){
if(doms.html.attr('layer-full') == index){
if(doms.html[0].style.removeProperty){
doms.html[0].style.removeProperty('overflow');
} else {
doms.html[0].style.removeAttribute('overflow');
}
doms.html.removeAttr('layer-full');
}
};
/** 内置成员 */
window.layer = layer;
//获取子iframe的DOM
layer.getChildFrame = function(selector, index){
index = index || $('.'+doms[4]).attr('times');
return $('#'+ doms[0] + index).find('iframe').contents().find(selector);
};
//得到当前iframe层的索引,子iframe时使用
layer.getFrameIndex = function(name){
return $('#'+ name).parents('.'+doms[4]).attr('times');
};
//iframe层自适应宽高
layer.iframeAuto = function(index){
if(!index) return;
var heg = layer.getChildFrame('html', index).outerHeight();
var layero = $('#'+ doms[0] + index);
var titHeight = layero.find(doms[1]).outerHeight() || 0;
var btnHeight = layero.find('.'+doms[6]).outerHeight() || 0;
layero.css({height: heg + titHeight + btnHeight});
layero.find('iframe').css({height: heg});
};
//重置iframe url
layer.iframeSrc = function(index, url){
$('#'+ doms[0] + index).find('iframe').attr('src', url);
};
//设定层的样式
layer.style = function(index, options, limit){
var layero = $('#'+ doms[0] + index)
,contElem = layero.find('.layui-layer-content')
,type = layero.attr('type')
,titHeight = layero.find(doms[1]).outerHeight() || 0
,btnHeight = layero.find('.'+doms[6]).outerHeight() || 0
,minLeft = layero.attr('minLeft');
if(type === ready.type[3] || type === ready.type[4]){
return;
}
if(!limit){
if(parseFloat(options.width) <= 260){
options.width = 260;
};
if(parseFloat(options.height) - titHeight - btnHeight <= 64){
options.height = 64 + titHeight + btnHeight;
};
}
layero.css(options);
btnHeight = layero.find('.'+doms[6]).outerHeight();
if(type === ready.type[2]){
layero.find('iframe').css({
height: parseFloat(options.height) - titHeight - btnHeight
});
} else {
contElem.css({
height: parseFloat(options.height) - titHeight - btnHeight
- parseFloat(contElem.css('padding-top'))
- parseFloat(contElem.css('padding-bottom'))
})
}
};
//最小化
layer.min = function(index, options){
var layero = $('#'+ doms[0] + index)
,titHeight = layero.find(doms[1]).outerHeight() || 0
,left = layero.attr('minLeft') || (181*ready.minIndex)+'px'
,position = layero.css('position');
ready.record(layero);
if(ready.minLeft[0]){
left = ready.minLeft[0];
ready.minLeft.shift();
}
layero.attr('position', position);
layer.style(index, {
width: 180
,height: titHeight
,left: left
,top: win.height() - titHeight
,position: 'fixed'
,overflow: 'hidden'
}, true);
layero.find('.layui-layer-min').hide();
layero.attr('type') === 'page' && layero.find(doms[4]).hide();
ready.rescollbar(index);
if(!layero.attr('minLeft')){
ready.minIndex++;
}
layero.attr('minLeft', left);
};
//还原
layer.restore = function(index){
var layero = $('#'+ doms[0] + index), area = layero.attr('area').split(',');
var type = layero.attr('type');
layer.style(index, {
width: parseFloat(area[0]),
height: parseFloat(area[1]),
top: parseFloat(area[2]),
left: parseFloat(area[3]),
position: layero.attr('position'),
overflow: 'visible'
}, true);
layero.find('.layui-layer-max').removeClass('layui-layer-maxmin');
layero.find('.layui-layer-min').show();
layero.attr('type') === 'page' && layero.find(doms[4]).show();
ready.rescollbar(index);
};
//全屏
layer.full = function(index){
var layero = $('#'+ doms[0] + index), timer;
ready.record(layero);
if(!doms.html.attr('layer-full')){
doms.html.css('overflow','hidden').attr('layer-full', index);
}
clearTimeout(timer);
timer = setTimeout(function(){
var isfix = layero.css('position') === 'fixed';
layer.style(index, {
top: isfix ? 0 : win.scrollTop(),
left: isfix ? 0 : win.scrollLeft(),
width: win.width(),
height: win.height()
}, true);
layero.find('.layui-layer-min').hide();
}, 100);
};
//改变title
layer.title = function(name, index){
var title = $('#'+ doms[0] + (index||layer.index)).find(doms[1]);
title.html(name);
};
//关闭layer总方法
layer.close = function(index){
var layero = $('#'+ doms[0] + index), type = layero.attr('type'), closeAnim = 'layer-anim-close';
if(!layero[0]) return;
var WRAP = 'layui-layer-wrap', remove = function(){
if(type === ready.type[1] && layero.attr('conType') === 'object'){
layero.children(':not(.'+ doms[5] +')').remove();
var wrap = layero.find('.'+WRAP);
for(var i = 0; i < 2; i++){
wrap.unwrap();
}
wrap.css('display', wrap.data('display')).removeClass(WRAP);
} else {
//低版本IE 回收 iframe
if(type === ready.type[2]){
try {
var iframe = $('#'+doms[4]+index)[0];
iframe.contentWindow.document.write('');
iframe.contentWindow.close();
layero.find('.'+doms[5])[0].removeChild(iframe);
} catch(e){}
}
layero[0].innerHTML = '';
layero.remove();
}
typeof ready.end[index] === 'function' && ready.end[index]();
delete ready.end[index];
};
if(layero.data('isOutAnim')){
layero.addClass('layer-anim '+ closeAnim);
}
$('#layui-layer-moves, #layui-layer-shade' + index).remove();
layer.ie == 6 && ready.reselect();
ready.rescollbar(index);
if(layero.attr('minLeft')){
ready.minIndex--;
ready.minLeft.push(layero.attr('minLeft'));
}
if((layer.ie && layer.ie < 10) || !layero.data('isOutAnim')){
remove()
} else {
setTimeout(function(){
remove();
}, 200);
}
};
//关闭所有层
layer.closeAll = function(type){
$.each($('.'+doms[0]), function(){
var othis = $(this);
var is = type ? (othis.attr('type') === type) : 1;
is && layer.close(othis.attr('times'));
is = null;
});
};
/**
拓展模块,layui开始合并在一起
*/
var cache = layer.cache||{}, skin = function(type){
return (cache.skin ? (' ' + cache.skin + ' ' + cache.skin + '-'+type) : '');
};
//仿系统prompt
layer.prompt = function(options, yes){
var style = '';
options = options || {};
if(typeof options === 'function') yes = options;
if(options.area){
var area = options.area;
style = 'style="width: '+ area[0] +'; height: '+ area[1] + ';"';
delete options.area;
}
var prompt, content = options.formType == 2 ? '<textarea class="layui-layer-input"' + style +'>' + (options.value||'') +'</textarea>' : function(){
return '<input type="'+ (options.formType == 1 ? 'password' : 'text') +'" class="layui-layer-input" value="'+ (options.value||'') +'">';
}();
var success = options.success;
delete options.success;
return layer.open($.extend({
type: 1
,btn: ['&#x786E;&#x5B9A;','&#x53D6;&#x6D88;']
,content: content
,skin: 'layui-layer-prompt' + skin('prompt')
,maxWidth: win.width()
,success: function(layero){
prompt = layero.find('.layui-layer-input');
prompt.focus();
typeof success === 'function' && success(layero);
}
,resize: false
,yes: function(index){
var value = prompt.val();
if(value === ''){
prompt.focus();
} else if(value.length > (options.maxlength||500)) {
layer.tips('&#x6700;&#x591A;&#x8F93;&#x5165;'+ (options.maxlength || 500) +'&#x4E2A;&#x5B57;&#x6570;', prompt, {tips: 1});
} else {
yes && yes(value, index, prompt);
}
}
}, options));
};
//tab层
layer.tab = function(options){
options = options || {};
var tab = options.tab || {}
,THIS = 'layui-this'
,success = options.success;
delete options.success;
return layer.open($.extend({
type: 1,
skin: 'layui-layer-tab' + skin('tab'),
resize: false,
title: function(){
var len = tab.length, ii = 1, str = '';
if(len > 0){
str = '<span class="'+ THIS +'">'+ tab[0].title +'</span>';
for(; ii < len; ii++){
str += '<span>'+ tab[ii].title +'</span>';
}
}
return str;
}(),
content: '<ul class="layui-layer-tabmain">'+ function(){
var len = tab.length, ii = 1, str = '';
if(len > 0){
str = '<li class="layui-layer-tabli '+ THIS +'">'+ (tab[0].content || 'no content') +'</li>';
for(; ii < len; ii++){
str += '<li class="layui-layer-tabli">'+ (tab[ii].content || 'no content') +'</li>';
}
}
return str;
}() +'</ul>',
success: function(layero){
var btn = layero.find('.layui-layer-title').children();
var main = layero.find('.layui-layer-tabmain').children();
btn.on('mousedown', function(e){
e.stopPropagation ? e.stopPropagation() : e.cancelBubble = true;
var othis = $(this), index = othis.index();
othis.addClass(THIS).siblings().removeClass(THIS);
main.eq(index).show().siblings().hide();
typeof options.change === 'function' && options.change(index);
});
typeof success === 'function' && success(layero);
}
}, options));
};
//相册层
layer.photos = function(options, loop, key){
var dict = {};
options = options || {};
if(!options.photos) return;
var type = options.photos.constructor === Object;
var photos = type ? options.photos : {}, data = photos.data || [];
var start = photos.start || 0;
dict.imgIndex = (start|0) + 1;
options.img = options.img || 'img';
var success = options.success;
delete options.success;
if(!type){ //页面直接获取
var parent = $(options.photos), pushData = function(){
data = [];
parent.find(options.img).each(function(index){
var othis = $(this);
othis.attr('layer-index', index);
data.push({
alt: othis.attr('alt'),
pid: othis.attr('layer-pid'),
src: othis.attr('layer-src') || othis.attr('src'),
thumb: othis.attr('src')
});
})
};
pushData();
if (data.length === 0) return;
loop || parent.on('click', options.img, function(){
var othis = $(this), index = othis.attr('layer-index');
layer.photos($.extend(options, {
photos: {
start: index,
data: data,
tab: options.tab
},
full: options.full
}), true);
pushData();
})
//不直接弹出
if(!loop) return;
} else if (data.length === 0){
return layer.msg('&#x6CA1;&#x6709;&#x56FE;&#x7247;');
}
//上一张
dict.imgprev = function(key){
dict.imgIndex--;
if(dict.imgIndex < 1){
dict.imgIndex = data.length;
}
dict.tabimg(key);
};
//下一张
dict.imgnext = function(key,errorMsg){
dict.imgIndex++;
if(dict.imgIndex > data.length){
dict.imgIndex = 1;
if (errorMsg) {return};
}
dict.tabimg(key)
};
//方向键
dict.keyup = function(event){
if(!dict.end){
var code = event.keyCode;
event.preventDefault();
if(code === 37){
dict.imgprev(true);
} else if(code === 39) {
dict.imgnext(true);
} else if(code === 27) {
layer.close(dict.index);
}
}
}
//切换
dict.tabimg = function(key){
if(data.length <= 1) return;
photos.start = dict.imgIndex - 1;
layer.close(dict.index);
return layer.photos(options, true, key);
setTimeout(function(){
layer.photos(options, true, key);
}, 200);
}
//一些动作
dict.event = function(){
dict.bigimg.hover(function(){
dict.imgsee.show();
}, function(){
dict.imgsee.hide();
});
dict.bigimg.find('.layui-layer-imgprev').on('click', function(event){
event.preventDefault();
dict.imgprev();
});
dict.bigimg.find('.layui-layer-imgnext').on('click', function(event){
event.preventDefault();
dict.imgnext();
});
$(document).on('keyup', dict.keyup);
};
//图片预加载
function loadImage(url, callback, error) {
var img = new Image();
img.src = url;
if(img.complete){
return callback(img);
}
img.onload = function(){
img.onload = null;
callback(img);
};
img.onerror = function(e){
img.onerror = null;
error(e);
};
};
dict.loadi = layer.load(1, {
shade: 'shade' in options ? false : 0.9,
scrollbar: false
});
loadImage(data[start].src, function(img){
layer.close(dict.loadi);
dict.index = layer.open($.extend({
type: 1,
id: 'layui-layer-photos',
area: function(){
var imgarea = [img.width, img.height];
var winarea = [$(window).width() - 100, $(window).height() - 100];
//如果 实际图片的宽或者高比 屏幕大(那么进行缩放)
if(!options.full && (imgarea[0]>winarea[0]||imgarea[1]>winarea[1])){
var wh = [imgarea[0]/winarea[0],imgarea[1]/winarea[1]];//取宽度缩放比例、高度缩放比例
if(wh[0] > wh[1]){//取缩放比例最大的进行缩放
imgarea[0] = imgarea[0]/wh[0];
imgarea[1] = imgarea[1]/wh[0];
} else if(wh[0] < wh[1]){
imgarea[0] = imgarea[0]/wh[1];
imgarea[1] = imgarea[1]/wh[1];
}
}
return [imgarea[0]+'px', imgarea[1]+'px'];
}(),
title: false,
shade: 0.9,
shadeClose: true,
closeBtn: false,
move: '.layui-layer-phimg img',
moveType: 1,
scrollbar: false,
moveOut: true,
//anim: Math.random()*5|0,
isOutAnim: false,
skin: 'layui-layer-photos' + skin('photos'),
content: '<div class="layui-layer-phimg">'
+'<img src="'+ data[start].src +'" alt="'+ (data[start].alt||'') +'" layer-pid="'+ data[start].pid +'">'
+'<div class="layui-layer-imgsee">'
+(data.length > 1 ? '<span class="layui-layer-imguide"><a href="javascript:;" class="layui-layer-iconext layui-layer-imgprev"></a><a href="javascript:;" class="layui-layer-iconext layui-layer-imgnext"></a></span>' : '')
+'<div class="layui-layer-imgbar" style="display:'+ (key ? 'block' : '') +'"><span class="layui-layer-imgtit"><a href="javascript:;">'+ (data[start].alt||'') +'</a><em>'+ dict.imgIndex +'/'+ data.length +'</em></span></div>'
+'</div>'
+'</div>',
success: function(layero, index){
dict.bigimg = layero.find('.layui-layer-phimg');
dict.imgsee = layero.find('.layui-layer-imguide,.layui-layer-imgbar');
dict.event(layero);
options.tab && options.tab(data[start], layero);
typeof success === 'function' && success(layero);
}, end: function(){
dict.end = true;
$(document).off('keyup', dict.keyup);
}
}, options));
}, function(){
layer.close(dict.loadi);
layer.msg('&#x5F53;&#x524D;&#x56FE;&#x7247;&#x5730;&#x5740;&#x5F02;&#x5E38;<br>&#x662F;&#x5426;&#x7EE7;&#x7EED;&#x67E5;&#x770B;&#x4E0B;&#x4E00;&#x5F20;&#xFF1F;', {
time: 30000,
btn: ['&#x4E0B;&#x4E00;&#x5F20;', '&#x4E0D;&#x770B;&#x4E86;'],
yes: function(){
data.length > 1 && dict.imgnext(true,true);
}
});
});
};
//主入口
ready.run = function(_$){
$ = _$;
win = $(window);
doms.html = $('html');
layer.open = function(deliver){
var o = new Class(deliver);
return o.index;
};
};
//加载方式
window.layui && layui.define ? (
layer.ready()
,layui.define('jquery', function(exports){ //layui加载
layer.path = layui.cache.dir;
ready.run(layui.$);
//暴露模块
window.layer = layer;
exports('layer', layer);
})
) : (
(typeof define === 'function' && define.amd) ? define('layer',['jquery'], function(){ //requirejs加载
ready.run(window.jQuery);
return layer;
}) : function(){ //普通script标签加载
ready.run(window.jQuery);
layer.ready();
}()
);
}(window);
/*! layer-v3.1.1 Web弹层组件 MIT License http://layer.layui.com/ By 贤心 */
;!function(e,t){"use strict";var i,n,a=e.layui&&layui.define,o={getPath:function(){var e=document.currentScript?document.currentScript.src:function(){for(var e,t=document.scripts,i=t.length-1,n=i;n>0;n--)if("interactive"===t[n].readyState){e=t[n].src;break}return e||t[i].src}();return e.substring(0,e.lastIndexOf("/")+1)}(),config:{},end:{},minIndex:0,minLeft:[],btn:["&#x786E;&#x5B9A;","&#x53D6;&#x6D88;"],type:["dialog","page","iframe","loading","tips"],getStyle:function(t,i){var n=t.currentStyle?t.currentStyle:e.getComputedStyle(t,null);return n[n.getPropertyValue?"getPropertyValue":"getAttribute"](i)},link:function(t,i,n){if(r.path){var a=document.getElementsByTagName("head")[0],s=document.createElement("link");"string"==typeof i&&(n=i);var l=(n||t).replace(/\.|\//g,""),f="layuicss-"+l,c=0;s.rel="stylesheet",s.href=r.path+t,s.id=f,document.getElementById(f)||a.appendChild(s),"function"==typeof i&&!function u(){return++c>80?e.console&&console.error("layer.css: Invalid"):void(1989===parseInt(o.getStyle(document.getElementById(f),"width"))?i():setTimeout(u,100))}()}}},r={v:"3.1.1",ie:function(){var t=navigator.userAgent.toLowerCase();return!!(e.ActiveXObject||"ActiveXObject"in e)&&((t.match(/msie\s(\d+)/)||[])[1]||"11")}(),index:e.layer&&e.layer.v?1e5:0,path:o.getPath,config:function(e,t){return e=e||{},r.cache=o.config=i.extend({},o.config,e),r.path=o.config.path||r.path,"string"==typeof e.extend&&(e.extend=[e.extend]),o.config.path&&r.ready(),e.extend?(a?layui.addcss("modules/layer/"+e.extend):o.link("theme/"+e.extend),this):this},ready:function(e){var t="layer",i="",n=(a?"modules/layer/":"theme/")+"default/layer.css?v="+r.v+i;return a?layui.addcss(n,e,t):o.link(n,e,t),this},alert:function(e,t,n){var a="function"==typeof t;return a&&(n=t),r.open(i.extend({content:e,yes:n},a?{}:t))},confirm:function(e,t,n,a){var s="function"==typeof t;return s&&(a=n,n=t),r.open(i.extend({content:e,btn:o.btn,yes:n,btn2:a},s?{}:t))},msg:function(e,n,a){var s="function"==typeof n,f=o.config.skin,c=(f?f+" "+f+"-msg":"")||"layui-layer-msg",u=l.anim.length-1;return s&&(a=n),r.open(i.extend({content:e,time:3e3,shade:!1,skin:c,title:!1,closeBtn:!1,btn:!1,resize:!1,end:a},s&&!o.config.skin?{skin:c+" layui-layer-hui",anim:u}:function(){return n=n||{},(n.icon===-1||n.icon===t&&!o.config.skin)&&(n.skin=c+" "+(n.skin||"layui-layer-hui")),n}()))},load:function(e,t){return r.open(i.extend({type:3,icon:e||0,resize:!1,shade:.01},t))},tips:function(e,t,n){return r.open(i.extend({type:4,content:[e,t],closeBtn:!1,time:3e3,shade:!1,resize:!1,fixed:!1,maxWidth:210},n))}},s=function(e){var t=this;t.index=++r.index,t.config=i.extend({},t.config,o.config,e),document.body?t.creat():setTimeout(function(){t.creat()},30)};s.pt=s.prototype;var l=["layui-layer",".layui-layer-title",".layui-layer-main",".layui-layer-dialog","layui-layer-iframe","layui-layer-content","layui-layer-btn","layui-layer-close"];l.anim=["layer-anim-00","layer-anim-01","layer-anim-02","layer-anim-03","layer-anim-04","layer-anim-05","layer-anim-06"],s.pt.config={type:0,shade:.3,fixed:!0,move:l[1],title:"&#x4FE1;&#x606F;",offset:"auto",area:"auto",closeBtn:1,time:0,zIndex:19891014,maxWidth:360,anim:0,isOutAnim:!0,icon:-1,moveType:1,resize:!0,scrollbar:!0,tips:2},s.pt.vessel=function(e,t){var n=this,a=n.index,r=n.config,s=r.zIndex+a,f="object"==typeof r.title,c=r.maxmin&&(1===r.type||2===r.type),u=r.title?'<div class="layui-layer-title" style="'+(f?r.title[1]:"")+'">'+(f?r.title[0]:r.title)+"</div>":"";return r.zIndex=s,t([r.shade?'<div class="layui-layer-shade" id="layui-layer-shade'+a+'" times="'+a+'" style="'+("z-index:"+(s-1)+"; ")+'"></div>':"",'<div class="'+l[0]+(" layui-layer-"+o.type[r.type])+(0!=r.type&&2!=r.type||r.shade?"":" layui-layer-border")+" "+(r.skin||"")+'" id="'+l[0]+a+'" type="'+o.type[r.type]+'" times="'+a+'" showtime="'+r.time+'" conType="'+(e?"object":"string")+'" style="z-index: '+s+"; width:"+r.area[0]+";height:"+r.area[1]+(r.fixed?"":";position:absolute;")+'">'+(e&&2!=r.type?"":u)+'<div id="'+(r.id||"")+'" class="layui-layer-content'+(0==r.type&&r.icon!==-1?" layui-layer-padding":"")+(3==r.type?" layui-layer-loading"+r.icon:"")+'">'+(0==r.type&&r.icon!==-1?'<i class="layui-layer-ico layui-layer-ico'+r.icon+'"></i>':"")+(1==r.type&&e?"":r.content||"")+'</div><span class="layui-layer-setwin">'+function(){var e=c?'<a class="layui-layer-min" href="javascript:;"><cite></cite></a><a class="layui-layer-ico layui-layer-max" href="javascript:;"></a>':"";return r.closeBtn&&(e+='<a class="layui-layer-ico '+l[7]+" "+l[7]+(r.title?r.closeBtn:4==r.type?"1":"2")+'" href="javascript:;"></a>'),e}()+"</span>"+(r.btn?function(){var e="";"string"==typeof r.btn&&(r.btn=[r.btn]);for(var t=0,i=r.btn.length;t<i;t++)e+='<a class="'+l[6]+t+'">'+r.btn[t]+"</a>";return'<div class="'+l[6]+" layui-layer-btn-"+(r.btnAlign||"")+'">'+e+"</div>"}():"")+(r.resize?'<span class="layui-layer-resize"></span>':"")+"</div>"],u,i('<div class="layui-layer-move"></div>')),n},s.pt.creat=function(){var e=this,t=e.config,a=e.index,s=t.content,f="object"==typeof s,c=i("body");if(!t.id||!i("#"+t.id)[0]){switch("string"==typeof t.area&&(t.area="auto"===t.area?["",""]:[t.area,""]),t.shift&&(t.anim=t.shift),6==r.ie&&(t.fixed=!1),t.type){case 0:t.btn="btn"in t?t.btn:o.btn[0],r.closeAll("dialog");break;case 2:var s=t.content=f?t.content:[t.content||"http://layer.layui.com","auto"];t.content='<iframe scrolling="'+(t.content[1]||"auto")+'" allowtransparency="true" id="'+l[4]+a+'" name="'+l[4]+a+'" onload="this.className=\'\';" class="layui-layer-load" frameborder="0" src="'+t.content[0]+'"></iframe>';break;case 3:delete t.title,delete t.closeBtn,t.icon===-1&&0===t.icon,r.closeAll("loading");break;case 4:f||(t.content=[t.content,"body"]),t.follow=t.content[1],t.content=t.content[0]+'<i class="layui-layer-TipsG"></i>',delete t.title,t.tips="object"==typeof t.tips?t.tips:[t.tips,!0],t.tipsMore||r.closeAll("tips")}if(e.vessel(f,function(n,r,u){c.append(n[0]),f?function(){2==t.type||4==t.type?function(){i("body").append(n[1])}():function(){s.parents("."+l[0])[0]||(s.data("display",s.css("display")).show().addClass("layui-layer-wrap").wrap(n[1]),i("#"+l[0]+a).find("."+l[5]).before(r))}()}():c.append(n[1]),i(".layui-layer-move")[0]||c.append(o.moveElem=u),e.layero=i("#"+l[0]+a),t.scrollbar||l.html.css("overflow","hidden").attr("layer-full",a)}).auto(a),i("#layui-layer-shade"+e.index).css({"background-color":t.shade[1]||"#000",opacity:t.shade[0]||t.shade}),2==t.type&&6==r.ie&&e.layero.find("iframe").attr("src",s[0]),4==t.type?e.tips():e.offset(),t.fixed&&n.on("resize",function(){e.offset(),(/^\d+%$/.test(t.area[0])||/^\d+%$/.test(t.area[1]))&&e.auto(a),4==t.type&&e.tips()}),t.time<=0||setTimeout(function(){r.close(e.index)},t.time),e.move().callback(),l.anim[t.anim]){var u="layer-anim "+l.anim[t.anim];e.layero.addClass(u).one("webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend",function(){i(this).removeClass(u)})}t.isOutAnim&&e.layero.data("isOutAnim",!0)}},s.pt.auto=function(e){var t=this,a=t.config,o=i("#"+l[0]+e);""===a.area[0]&&a.maxWidth>0&&(r.ie&&r.ie<8&&a.btn&&o.width(o.innerWidth()),o.outerWidth()>a.maxWidth&&o.width(a.maxWidth));var s=[o.innerWidth(),o.innerHeight()],f=o.find(l[1]).outerHeight()||0,c=o.find("."+l[6]).outerHeight()||0,u=function(e){e=o.find(e),e.height(s[1]-f-c-2*(0|parseFloat(e.css("padding-top"))))};switch(a.type){case 2:u("iframe");break;default:""===a.area[1]?a.maxHeight>0&&o.outerHeight()>a.maxHeight?(s[1]=a.maxHeight,u("."+l[5])):a.fixed&&s[1]>=n.height()&&(s[1]=n.height(),u("."+l[5])):u("."+l[5])}return t},s.pt.offset=function(){var e=this,t=e.config,i=e.layero,a=[i.outerWidth(),i.outerHeight()],o="object"==typeof t.offset;e.offsetTop=(n.height()-a[1])/2,e.offsetLeft=(n.width()-a[0])/2,o?(e.offsetTop=t.offset[0],e.offsetLeft=t.offset[1]||e.offsetLeft):"auto"!==t.offset&&("t"===t.offset?e.offsetTop=0:"r"===t.offset?e.offsetLeft=n.width()-a[0]:"b"===t.offset?e.offsetTop=n.height()-a[1]:"l"===t.offset?e.offsetLeft=0:"lt"===t.offset?(e.offsetTop=0,e.offsetLeft=0):"lb"===t.offset?(e.offsetTop=n.height()-a[1],e.offsetLeft=0):"rt"===t.offset?(e.offsetTop=0,e.offsetLeft=n.width()-a[0]):"rb"===t.offset?(e.offsetTop=n.height()-a[1],e.offsetLeft=n.width()-a[0]):e.offsetTop=t.offset),t.fixed||(e.offsetTop=/%$/.test(e.offsetTop)?n.height()*parseFloat(e.offsetTop)/100:parseFloat(e.offsetTop),e.offsetLeft=/%$/.test(e.offsetLeft)?n.width()*parseFloat(e.offsetLeft)/100:parseFloat(e.offsetLeft),e.offsetTop+=n.scrollTop(),e.offsetLeft+=n.scrollLeft()),i.attr("minLeft")&&(e.offsetTop=n.height()-(i.find(l[1]).outerHeight()||0),e.offsetLeft=i.css("left")),i.css({top:e.offsetTop,left:e.offsetLeft})},s.pt.tips=function(){var e=this,t=e.config,a=e.layero,o=[a.outerWidth(),a.outerHeight()],r=i(t.follow);r[0]||(r=i("body"));var s={width:r.outerWidth(),height:r.outerHeight(),top:r.offset().top,left:r.offset().left},f=a.find(".layui-layer-TipsG"),c=t.tips[0];t.tips[1]||f.remove(),s.autoLeft=function(){s.left+o[0]-n.width()>0?(s.tipLeft=s.left+s.width-o[0],f.css({right:12,left:"auto"})):s.tipLeft=s.left},s.where=[function(){s.autoLeft(),s.tipTop=s.top-o[1]-10,f.removeClass("layui-layer-TipsB").addClass("layui-layer-TipsT").css("border-right-color",t.tips[1])},function(){s.tipLeft=s.left+s.width+10,s.tipTop=s.top,f.removeClass("layui-layer-TipsL").addClass("layui-layer-TipsR").css("border-bottom-color",t.tips[1])},function(){s.autoLeft(),s.tipTop=s.top+s.height+10,f.removeClass("layui-layer-TipsT").addClass("layui-layer-TipsB").css("border-right-color",t.tips[1])},function(){s.tipLeft=s.left-o[0]-10,s.tipTop=s.top,f.removeClass("layui-layer-TipsR").addClass("layui-layer-TipsL").css("border-bottom-color",t.tips[1])}],s.where[c-1](),1===c?s.top-(n.scrollTop()+o[1]+16)<0&&s.where[2]():2===c?n.width()-(s.left+s.width+o[0]+16)>0||s.where[3]():3===c?s.top-n.scrollTop()+s.height+o[1]+16-n.height()>0&&s.where[0]():4===c&&o[0]+16-s.left>0&&s.where[1](),a.find("."+l[5]).css({"background-color":t.tips[1],"padding-right":t.closeBtn?"30px":""}),a.css({left:s.tipLeft-(t.fixed?n.scrollLeft():0),top:s.tipTop-(t.fixed?n.scrollTop():0)})},s.pt.move=function(){var e=this,t=e.config,a=i(document),s=e.layero,l=s.find(t.move),f=s.find(".layui-layer-resize"),c={};return t.move&&l.css("cursor","move"),l.on("mousedown",function(e){e.preventDefault(),t.move&&(c.moveStart=!0,c.offset=[e.clientX-parseFloat(s.css("left")),e.clientY-parseFloat(s.css("top"))],o.moveElem.css("cursor","move").show())}),f.on("mousedown",function(e){e.preventDefault(),c.resizeStart=!0,c.offset=[e.clientX,e.clientY],c.area=[s.outerWidth(),s.outerHeight()],o.moveElem.css("cursor","se-resize").show()}),a.on("mousemove",function(i){if(c.moveStart){var a=i.clientX-c.offset[0],o=i.clientY-c.offset[1],l="fixed"===s.css("position");if(i.preventDefault(),c.stX=l?0:n.scrollLeft(),c.stY=l?0:n.scrollTop(),!t.moveOut){var f=n.width()-s.outerWidth()+c.stX,u=n.height()-s.outerHeight()+c.stY;a<c.stX&&(a=c.stX),a>f&&(a=f),o<c.stY&&(o=c.stY),o>u&&(o=u)}s.css({left:a,top:o})}if(t.resize&&c.resizeStart){var a=i.clientX-c.offset[0],o=i.clientY-c.offset[1];i.preventDefault(),r.style(e.index,{width:c.area[0]+a,height:c.area[1]+o}),c.isResize=!0,t.resizing&&t.resizing(s)}}).on("mouseup",function(e){c.moveStart&&(delete c.moveStart,o.moveElem.hide(),t.moveEnd&&t.moveEnd(s)),c.resizeStart&&(delete c.resizeStart,o.moveElem.hide())}),e},s.pt.callback=function(){function e(){var e=a.cancel&&a.cancel(t.index,n);e===!1||r.close(t.index)}var t=this,n=t.layero,a=t.config;t.openLayer(),a.success&&(2==a.type?n.find("iframe").on("load",function(){a.success(n,t.index)}):a.success(n,t.index)),6==r.ie&&t.IE6(n),n.find("."+l[6]).children("a").on("click",function(){var e=i(this).index();if(0===e)a.yes?a.yes(t.index,n):a.btn1?a.btn1(t.index,n):r.close(t.index);else{var o=a["btn"+(e+1)]&&a["btn"+(e+1)](t.index,n);o===!1||r.close(t.index)}}),n.find("."+l[7]).on("click",e),a.shadeClose&&i("#layui-layer-shade"+t.index).on("click",function(){r.close(t.index)}),n.find(".layui-layer-min").on("click",function(){var e=a.min&&a.min(n);e===!1||r.min(t.index,a)}),n.find(".layui-layer-max").on("click",function(){i(this).hasClass("layui-layer-maxmin")?(r.restore(t.index),a.restore&&a.restore(n)):(r.full(t.index,a),setTimeout(function(){a.full&&a.full(n)},100))}),a.end&&(o.end[t.index]=a.end)},o.reselect=function(){i.each(i("select"),function(e,t){var n=i(this);n.parents("."+l[0])[0]||1==n.attr("layer")&&i("."+l[0]).length<1&&n.removeAttr("layer").show(),n=null})},s.pt.IE6=function(e){i("select").each(function(e,t){var n=i(this);n.parents("."+l[0])[0]||"none"===n.css("display")||n.attr({layer:"1"}).hide(),n=null})},s.pt.openLayer=function(){var e=this;r.zIndex=e.config.zIndex,r.setTop=function(e){var t=function(){r.zIndex++,e.css("z-index",r.zIndex+1)};return r.zIndex=parseInt(e[0].style.zIndex),e.on("mousedown",t),r.zIndex}},o.record=function(e){var t=[e.width(),e.height(),e.position().top,e.position().left+parseFloat(e.css("margin-left"))];e.find(".layui-layer-max").addClass("layui-layer-maxmin"),e.attr({area:t})},o.rescollbar=function(e){l.html.attr("layer-full")==e&&(l.html[0].style.removeProperty?l.html[0].style.removeProperty("overflow"):l.html[0].style.removeAttribute("overflow"),l.html.removeAttr("layer-full"))},e.layer=r,r.getChildFrame=function(e,t){return t=t||i("."+l[4]).attr("times"),i("#"+l[0]+t).find("iframe").contents().find(e)},r.getFrameIndex=function(e){return i("#"+e).parents("."+l[4]).attr("times")},r.iframeAuto=function(e){if(e){var t=r.getChildFrame("html",e).outerHeight(),n=i("#"+l[0]+e),a=n.find(l[1]).outerHeight()||0,o=n.find("."+l[6]).outerHeight()||0;n.css({height:t+a+o}),n.find("iframe").css({height:t})}},r.iframeSrc=function(e,t){i("#"+l[0]+e).find("iframe").attr("src",t)},r.style=function(e,t,n){var a=i("#"+l[0]+e),r=a.find(".layui-layer-content"),s=a.attr("type"),f=a.find(l[1]).outerHeight()||0,c=a.find("."+l[6]).outerHeight()||0;a.attr("minLeft");s!==o.type[3]&&s!==o.type[4]&&(n||(parseFloat(t.width)<=260&&(t.width=260),parseFloat(t.height)-f-c<=64&&(t.height=64+f+c)),a.css(t),c=a.find("."+l[6]).outerHeight(),s===o.type[2]?a.find("iframe").css({height:parseFloat(t.height)-f-c}):r.css({height:parseFloat(t.height)-f-c-parseFloat(r.css("padding-top"))-parseFloat(r.css("padding-bottom"))}))},r.min=function(e,t){var a=i("#"+l[0]+e),s=a.find(l[1]).outerHeight()||0,f=a.attr("minLeft")||181*o.minIndex+"px",c=a.css("position");o.record(a),o.minLeft[0]&&(f=o.minLeft[0],o.minLeft.shift()),a.attr("position",c),r.style(e,{width:180,height:s,left:f,top:n.height()-s,position:"fixed",overflow:"hidden"},!0),a.find(".layui-layer-min").hide(),"page"===a.attr("type")&&a.find(l[4]).hide(),o.rescollbar(e),a.attr("minLeft")||o.minIndex++,a.attr("minLeft",f)},r.restore=function(e){var t=i("#"+l[0]+e),n=t.attr("area").split(",");t.attr("type");r.style(e,{width:parseFloat(n[0]),height:parseFloat(n[1]),top:parseFloat(n[2]),left:parseFloat(n[3]),position:t.attr("position"),overflow:"visible"},!0),t.find(".layui-layer-max").removeClass("layui-layer-maxmin"),t.find(".layui-layer-min").show(),"page"===t.attr("type")&&t.find(l[4]).show(),o.rescollbar(e)},r.full=function(e){var t,a=i("#"+l[0]+e);o.record(a),l.html.attr("layer-full")||l.html.css("overflow","hidden").attr("layer-full",e),clearTimeout(t),t=setTimeout(function(){var t="fixed"===a.css("position");r.style(e,{top:t?0:n.scrollTop(),left:t?0:n.scrollLeft(),width:n.width(),height:n.height()},!0),a.find(".layui-layer-min").hide()},100)},r.title=function(e,t){var n=i("#"+l[0]+(t||r.index)).find(l[1]);n.html(e)},r.close=function(e){var t=i("#"+l[0]+e),n=t.attr("type"),a="layer-anim-close";if(t[0]){var s="layui-layer-wrap",f=function(){if(n===o.type[1]&&"object"===t.attr("conType")){t.children(":not(."+l[5]+")").remove();for(var a=t.find("."+s),r=0;r<2;r++)a.unwrap();a.css("display",a.data("display")).removeClass(s)}else{if(n===o.type[2])try{var f=i("#"+l[4]+e)[0];f.contentWindow.document.write(""),f.contentWindow.close(),t.find("."+l[5])[0].removeChild(f)}catch(c){}t[0].innerHTML="",t.remove()}"function"==typeof o.end[e]&&o.end[e](),delete o.end[e]};t.data("isOutAnim")&&t.addClass("layer-anim "+a),i("#layui-layer-moves, #layui-layer-shade"+e).remove(),6==r.ie&&o.reselect(),o.rescollbar(e),t.attr("minLeft")&&(o.minIndex--,o.minLeft.push(t.attr("minLeft"))),r.ie&&r.ie<10||!t.data("isOutAnim")?f():setTimeout(function(){f()},200)}},r.closeAll=function(e){i.each(i("."+l[0]),function(){var t=i(this),n=e?t.attr("type")===e:1;n&&r.close(t.attr("times")),n=null})};var f=r.cache||{},c=function(e){return f.skin?" "+f.skin+" "+f.skin+"-"+e:""};r.prompt=function(e,t){var a="";if(e=e||{},"function"==typeof e&&(t=e),e.area){var o=e.area;a='style="width: '+o[0]+"; height: "+o[1]+';"',delete e.area}var s,l=2==e.formType?'<textarea class="layui-layer-input"'+a+">"+(e.value||"")+"</textarea>":function(){return'<input type="'+(1==e.formType?"password":"text")+'" class="layui-layer-input" value="'+(e.value||"")+'">'}(),f=e.success;return delete e.success,r.open(i.extend({type:1,btn:["&#x786E;&#x5B9A;","&#x53D6;&#x6D88;"],content:l,skin:"layui-layer-prompt"+c("prompt"),maxWidth:n.width(),success:function(e){s=e.find(".layui-layer-input"),s.focus(),"function"==typeof f&&f(e)},resize:!1,yes:function(i){var n=s.val();""===n?s.focus():n.length>(e.maxlength||500)?r.tips("&#x6700;&#x591A;&#x8F93;&#x5165;"+(e.maxlength||500)+"&#x4E2A;&#x5B57;&#x6570;",s,{tips:1}):t&&t(n,i,s)}},e))},r.tab=function(e){e=e||{};var t=e.tab||{},n="layui-this",a=e.success;return delete e.success,r.open(i.extend({type:1,skin:"layui-layer-tab"+c("tab"),resize:!1,title:function(){var e=t.length,i=1,a="";if(e>0)for(a='<span class="'+n+'">'+t[0].title+"</span>";i<e;i++)a+="<span>"+t[i].title+"</span>";return a}(),content:'<ul class="layui-layer-tabmain">'+function(){var e=t.length,i=1,a="";if(e>0)for(a='<li class="layui-layer-tabli '+n+'">'+(t[0].content||"no content")+"</li>";i<e;i++)a+='<li class="layui-layer-tabli">'+(t[i].content||"no content")+"</li>";return a}()+"</ul>",success:function(t){var o=t.find(".layui-layer-title").children(),r=t.find(".layui-layer-tabmain").children();o.on("mousedown",function(t){t.stopPropagation?t.stopPropagation():t.cancelBubble=!0;var a=i(this),o=a.index();a.addClass(n).siblings().removeClass(n),r.eq(o).show().siblings().hide(),"function"==typeof e.change&&e.change(o)}),"function"==typeof a&&a(t)}},e))},r.photos=function(t,n,a){function o(e,t,i){var n=new Image;return n.src=e,n.complete?t(n):(n.onload=function(){n.onload=null,t(n)},void(n.onerror=function(e){n.onerror=null,i(e)}))}var s={};if(t=t||{},t.photos){var l=t.photos.constructor===Object,f=l?t.photos:{},u=f.data||[],d=f.start||0;s.imgIndex=(0|d)+1,t.img=t.img||"img";var y=t.success;if(delete t.success,l){if(0===u.length)return r.msg("&#x6CA1;&#x6709;&#x56FE;&#x7247;")}else{var p=i(t.photos),h=function(){u=[],p.find(t.img).each(function(e){var t=i(this);t.attr("layer-index",e),u.push({alt:t.attr("alt"),pid:t.attr("layer-pid"),src:t.attr("layer-src")||t.attr("src"),thumb:t.attr("src")})})};if(h(),0===u.length)return;if(n||p.on("click",t.img,function(){var e=i(this),n=e.attr("layer-index");r.photos(i.extend(t,{photos:{start:n,data:u,tab:t.tab},full:t.full}),!0),h()}),!n)return}s.imgprev=function(e){s.imgIndex--,s.imgIndex<1&&(s.imgIndex=u.length),s.tabimg(e)},s.imgnext=function(e,t){s.imgIndex++,s.imgIndex>u.length&&(s.imgIndex=1,t)||s.tabimg(e)},s.keyup=function(e){if(!s.end){var t=e.keyCode;e.preventDefault(),37===t?s.imgprev(!0):39===t?s.imgnext(!0):27===t&&r.close(s.index)}},s.tabimg=function(e){if(!(u.length<=1))return f.start=s.imgIndex-1,r.close(s.index),r.photos(t,!0,e)},s.event=function(){s.bigimg.hover(function(){s.imgsee.show()},function(){s.imgsee.hide()}),s.bigimg.find(".layui-layer-imgprev").on("click",function(e){e.preventDefault(),s.imgprev()}),s.bigimg.find(".layui-layer-imgnext").on("click",function(e){e.preventDefault(),s.imgnext()}),i(document).on("keyup",s.keyup)},s.loadi=r.load(1,{shade:!("shade"in t)&&.9,scrollbar:!1}),o(u[d].src,function(n){r.close(s.loadi),s.index=r.open(i.extend({type:1,id:"layui-layer-photos",area:function(){var a=[n.width,n.height],o=[i(e).width()-100,i(e).height()-100];if(!t.full&&(a[0]>o[0]||a[1]>o[1])){var r=[a[0]/o[0],a[1]/o[1]];r[0]>r[1]?(a[0]=a[0]/r[0],a[1]=a[1]/r[0]):r[0]<r[1]&&(a[0]=a[0]/r[1],a[1]=a[1]/r[1])}return[a[0]+"px",a[1]+"px"]}(),title:!1,shade:.9,shadeClose:!0,closeBtn:!1,move:".layui-layer-phimg img",moveType:1,scrollbar:!1,moveOut:!0,isOutAnim:!1,skin:"layui-layer-photos"+c("photos"),content:'<div class="layui-layer-phimg"><img src="'+u[d].src+'" alt="'+(u[d].alt||"")+'" layer-pid="'+u[d].pid+'"><div class="layui-layer-imgsee">'+(u.length>1?'<span class="layui-layer-imguide"><a href="javascript:;" class="layui-layer-iconext layui-layer-imgprev"></a><a href="javascript:;" class="layui-layer-iconext layui-layer-imgnext"></a></span>':"")+'<div class="layui-layer-imgbar" style="display:'+(a?"block":"")+'"><span class="layui-layer-imgtit"><a href="javascript:;">'+(u[d].alt||"")+"</a><em>"+s.imgIndex+"/"+u.length+"</em></span></div></div></div>",success:function(e,i){s.bigimg=e.find(".layui-layer-phimg"),s.imgsee=e.find(".layui-layer-imguide,.layui-layer-imgbar"),s.event(e),t.tab&&t.tab(u[d],e),"function"==typeof y&&y(e)},end:function(){s.end=!0,i(document).off("keyup",s.keyup)}},t))},function(){r.close(s.loadi),r.msg("&#x5F53;&#x524D;&#x56FE;&#x7247;&#x5730;&#x5740;&#x5F02;&#x5E38;<br>&#x662F;&#x5426;&#x7EE7;&#x7EED;&#x67E5;&#x770B;&#x4E0B;&#x4E00;&#x5F20;&#xFF1F;",{time:3e4,btn:["&#x4E0B;&#x4E00;&#x5F20;","&#x4E0D;&#x770B;&#x4E86;"],yes:function(){u.length>1&&s.imgnext(!0,!0)}})})}},o.run=function(t){i=t,n=i(e),l.html=i("html"),r.open=function(e){var t=new s(e);return t.index}},e.layui&&layui.define?(r.ready(),layui.define("jquery",function(t){r.path=layui.cache.dir,o.run(layui.$),e.layer=r,t("layer",r)})):"function"==typeof define&&define.amd?define('layer',["jquery"],function(){return o.run(e.jQuery),r}):function(){o.run(e.jQuery),r.ready()}()}(window);
/*
* Toastr
* Copyright 2012-2015
... ... @@ -2124,8 +818,7 @@ define('fast',['jquery', 'bootstrap', 'toastr', 'layer', 'lang'], function ($, u
options.area = [top.$(".tab-pane.active").width() + "px", top.$(".tab-pane.active").height() + "px"];
options.offset = [top.$(".tab-pane.active").scrollTop() + "px", "0px"];
}
Layer.open(options);
return false;
return Layer.open(options);
},
//关闭窗口并回传数据
close: function (data) {
... ... @@ -2330,3 +1023,6 @@ define('frontend',['fast'], function (Fast) {
return Frontend;
});
define('frontend-init',['frontend'], function (Frontend) {
});
... ...
define(['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstrap-table', 'bootstrap-table-lang', 'bootstrap-table-mobile', 'bootstrap-table-export', 'bootstrap-table-commonsearch', 'bootstrap-table-template'], function ($, undefined, Moment) {
define(['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstrap-table', 'bootstrap-table-lang', 'bootstrap-table-export', 'bootstrap-table-commonsearch', 'bootstrap-table-template'], function ($, undefined, Moment) {
var Table = {
list: {},
// Bootstrap-table 基础配置
... ... @@ -32,7 +32,6 @@ define(['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstrap-table
paginationPreText: __("Previous"),
paginationNextText: __("Next"),
paginationLastText: __("Last"),
mobileResponsive: true, //是否自适应移动端
cardView: false, //卡片视图
checkOnInit: true, //是否在初始化时判断
escape: true, //是否对内容进行转义
... ... @@ -152,7 +151,7 @@ define(['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstrap-table
}
});
// 处理选中筛选框后按钮的状态统一变更
table.on('check.bs.table uncheck.bs.table check-all.bs.table uncheck-all.bs.table fa.event.check', function () {
table.on('check.bs.table uncheck.bs.table check-all.bs.table uncheck-all.bs.table', function () {
var ids = Table.api.selectedids(table);
$(Table.config.disabledbtn, toolbar).toggleClass('disabled', !ids.length);
});
... ... @@ -176,7 +175,7 @@ define(['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstrap-table
Fast.api.ajax({
url: options.extend.import_url,
data: {file: data.url},
}, function () {
}, function (data, ret) {
table.bootstrapTable('refresh');
});
});
... ... @@ -217,7 +216,8 @@ define(['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstrap-table
$("tbody", table).dragsort({
itemSelector: 'tr:visible',
dragSelector: "a.btn-dragsort",
dragEnd: function () {
dragEnd: function (a, b) {
var element = $("a.btn-dragsort", this);
var data = table.bootstrapTable('getData');
var current = data[parseInt($(this).data("index"))];
var options = table.bootstrapTable('getOptions');
... ... @@ -238,7 +238,21 @@ define(['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstrap-table
table: options.extend.table
}
};
Fast.api.ajax(params, function (data) {
Fast.api.ajax(params, function (data, ret) {
var success = $(element).data("success") || $.noop;
if (typeof success === 'function') {
if (false === success.call(element, data, ret)) {
return false;
}
}
table.bootstrapTable('refresh');
}, function () {
var error = $(element).data("error") || $.noop;
if (typeof error === 'function') {
if (false === error.call(element, data, ret)) {
return false;
}
}
table.bootstrapTable('refresh');
});
},
... ... @@ -246,7 +260,9 @@ define(['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstrap-table
});
});
$(table).on("click", "input[data-id][name='checkbox']", function (e) {
table.trigger('fa.event.check');
var ids = $(this).data("id");
var row = Table.api.getrowbyid(ids);
table.trigger('check.bs.table', [row, this]);
});
$(table).on("click", "[data-id].btn-change", function (e) {
e.preventDefault();
... ... @@ -255,14 +271,7 @@ define(['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstrap-table
$(table).on("click", "[data-id].btn-edit", function (e) {
e.preventDefault();
var ids = $(this).data("id");
var row = {};
var options = table.bootstrapTable("getOptions");
$.each(table.bootstrapTable('getData'), function (i, j) {
if (j[options.pk] == ids) {
row = j;
return false;
}
});
var row = Table.api.getrowbyid(ids);
row.ids = ids;
var url = Table.api.replaceurl(options.extend.edit_url, row, table);
Fast.api.open(url, __('Edit'), $(this).data() || {});
... ... @@ -293,8 +302,21 @@ define(['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstrap-table
url = this.replaceurl(url, {ids: ids}, table);
var params = typeof data.params !== "undefined" ? (typeof data.params == 'object' ? $.param(data.params) : data.params) : '';
var options = {url: url, data: {action: action, ids: ids, params: params}};
Fast.api.ajax(options, function (data) {
Fast.api.ajax(options, function (data, ret) {
var success = $(element).data("success") || $.noop;
if (typeof success === 'function') {
if (false === success.call(element, data, ret)) {
return false;
}
}
table.bootstrapTable('refresh');
}, function (data, ret) {
var error = $(element).data("error") || $.noop;
if (typeof error === 'function') {
if (false === error.call(element, data, ret)) {
return false;
}
}
});
},
// 单元格元素事件
... ... @@ -521,6 +543,22 @@ define(['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstrap-table
index = parseInt(index);
var data = table.bootstrapTable('getData');
return typeof data[index] !== 'undefined' ? data[index] : null;
},
// 根据行索引获取行数据
getrowbyindex: function (table, index) {
return Table.api.getrowdata(table, index);
},
// 根据主键ID获取行数据
getrowbyid: function (table, id) {
var row = {};
var options = table.bootstrapTable("getOptions");
$.each(table.bootstrapTable('getData'), function (i, j) {
if (j[options.pk] == id) {
row = j;
return false;
}
});
return row;
}
},
};
... ...
var requirejs,require,define;!function(global,setTimeout){function commentReplace(e,t){return t||""}function isFunction(e){return"[object Function]"===ostring.call(e)}function isArray(e){return"[object Array]"===ostring.call(e)}function each(e,t){if(e){var i;for(i=0;i<e.length&&(!e[i]||!t(e[i],i,e));i+=1);}}function eachReverse(e,t){if(e){var i;for(i=e.length-1;i>-1&&(!e[i]||!t(e[i],i,e));i-=1);}}function hasProp(e,t){return hasOwn.call(e,t)}function getOwn(e,t){return hasProp(e,t)&&e[t]}function eachProp(e,t){var i;for(i in e)if(hasProp(e,i)&&t(e[i],i))break}function mixin(e,t,i,r){return t&&eachProp(t,function(t,n){!i&&hasProp(e,n)||(!r||"object"!=typeof t||!t||isArray(t)||isFunction(t)||t instanceof RegExp?e[n]=t:(e[n]||(e[n]={}),mixin(e[n],t,i,r)))}),e}function bind(e,t){return function(){return t.apply(e,arguments)}}function scripts(){return document.getElementsByTagName("script")}function defaultOnError(e){throw e}function getGlobal(e){if(!e)return e;var t=global;return each(e.split("."),function(e){t=t[e]}),t}function makeError(e,t,i,r){var n=new Error(t+"\nhttp://requirejs.org/docs/errors.html#"+e);return n.requireType=e,n.requireModules=r,i&&(n.originalError=i),n}function newContext(e){function t(e){var t,i;for(t=0;t<e.length;t++)if(i=e[t],"."===i)e.splice(t,1),t-=1;else if(".."===i){if(0===t||1===t&&".."===e[2]||".."===e[t-1])continue;t>0&&(e.splice(t-1,2),t-=2)}}function i(e,i,r){var n,o,a,s,u,c,d,p,f,l,h,m,g=i&&i.split("/"),v=y.map,x=v&&v["*"];if(e&&(e=e.split("/"),d=e.length-1,y.nodeIdCompat&&jsSuffixRegExp.test(e[d])&&(e[d]=e[d].replace(jsSuffixRegExp,"")),"."===e[0].charAt(0)&&g&&(m=g.slice(0,g.length-1),e=m.concat(e)),t(e),e=e.join("/")),r&&v&&(g||x)){a=e.split("/");e:for(s=a.length;s>0;s-=1){if(c=a.slice(0,s).join("/"),g)for(u=g.length;u>0;u-=1)if(o=getOwn(v,g.slice(0,u).join("/")),o&&(o=getOwn(o,c))){p=o,f=s;break e}!l&&x&&getOwn(x,c)&&(l=getOwn(x,c),h=s)}!p&&l&&(p=l,f=h),p&&(a.splice(0,f,p),e=a.join("/"))}return n=getOwn(y.pkgs,e),n?n:e}function r(e){isBrowser&&each(scripts(),function(t){if(t.getAttribute("data-requiremodule")===e&&t.getAttribute("data-requirecontext")===q.contextName)return t.parentNode.removeChild(t),!0})}function n(e){var t=getOwn(y.paths,e);if(t&&isArray(t)&&t.length>1)return t.shift(),q.require.undef(e),q.makeRequire(null,{skipMap:!0})([e]),!0}function o(e){var t,i=e?e.indexOf("!"):-1;return i>-1&&(t=e.substring(0,i),e=e.substring(i+1,e.length)),[t,e]}function a(e,t,r,n){var a,s,u,c,d=null,p=t?t.name:null,f=e,l=!0,h="";return e||(l=!1,e="_@r"+(T+=1)),c=o(e),d=c[0],e=c[1],d&&(d=i(d,p,n),s=getOwn(j,d)),e&&(d?h=s&&s.normalize?s.normalize(e,function(e){return i(e,p,n)}):e.indexOf("!")===-1?i(e,p,n):e:(h=i(e,p,n),c=o(h),d=c[0],h=c[1],r=!0,a=q.nameToUrl(h))),u=!d||s||r?"":"_unnormalized"+(A+=1),{prefix:d,name:h,parentMap:t,unnormalized:!!u,url:a,originalName:f,isDefine:l,id:(d?d+"!"+h:h)+u}}function s(e){var t=e.id,i=getOwn(S,t);return i||(i=S[t]=new q.Module(e)),i}function u(e,t,i){var r=e.id,n=getOwn(S,r);!hasProp(j,r)||n&&!n.defineEmitComplete?(n=s(e),n.error&&"error"===t?i(n.error):n.on(t,i)):"defined"===t&&i(j[r])}function c(e,t){var i=e.requireModules,r=!1;t?t(e):(each(i,function(t){var i=getOwn(S,t);i&&(i.error=e,i.events.error&&(r=!0,i.emit("error",e)))}),r||req.onError(e))}function d(){globalDefQueue.length&&(each(globalDefQueue,function(e){var t=e[0];"string"==typeof t&&(q.defQueueMap[t]=!0),O.push(e)}),globalDefQueue=[])}function p(e){delete S[e],delete k[e]}function f(e,t,i){var r=e.map.id;e.error?e.emit("error",e.error):(t[r]=!0,each(e.depMaps,function(r,n){var o=r.id,a=getOwn(S,o);!a||e.depMatched[n]||i[o]||(getOwn(t,o)?(e.defineDep(n,j[o]),e.check()):f(a,t,i))}),i[r]=!0)}function l(){var e,t,i=1e3*y.waitSeconds,o=i&&q.startTime+i<(new Date).getTime(),a=[],s=[],u=!1,d=!0;if(!x){if(x=!0,eachProp(k,function(e){var i=e.map,c=i.id;if(e.enabled&&(i.isDefine||s.push(e),!e.error))if(!e.inited&&o)n(c)?(t=!0,u=!0):(a.push(c),r(c));else if(!e.inited&&e.fetched&&i.isDefine&&(u=!0,!i.prefix))return d=!1}),o&&a.length)return e=makeError("timeout","Load timeout for modules: "+a,null,a),e.contextName=q.contextName,c(e);d&&each(s,function(e){f(e,{},{})}),o&&!t||!u||!isBrowser&&!isWebWorker||w||(w=setTimeout(function(){w=0,l()},50)),x=!1}}function h(e){hasProp(j,e[0])||s(a(e[0],null,!0)).init(e[1],e[2])}function m(e,t,i,r){e.detachEvent&&!isOpera?r&&e.detachEvent(r,t):e.removeEventListener(i,t,!1)}function g(e){var t=e.currentTarget||e.srcElement;return m(t,q.onScriptLoad,"load","onreadystatechange"),m(t,q.onScriptError,"error"),{node:t,id:t&&t.getAttribute("data-requiremodule")}}function v(){var e;for(d();O.length;){if(e=O.shift(),null===e[0])return c(makeError("mismatch","Mismatched anonymous define() module: "+e[e.length-1]));h(e)}q.defQueueMap={}}var x,b,q,E,w,y={waitSeconds:7,baseUrl:"./",paths:{},bundles:{},pkgs:{},shim:{},config:{}},S={},k={},M={},O=[],j={},P={},R={},T=1,A=1;return E={require:function(e){return e.require?e.require:e.require=q.makeRequire(e.map)},exports:function(e){if(e.usingExports=!0,e.map.isDefine)return e.exports?j[e.map.id]=e.exports:e.exports=j[e.map.id]={}},module:function(e){return e.module?e.module:e.module={id:e.map.id,uri:e.map.url,config:function(){return getOwn(y.config,e.map.id)||{}},exports:e.exports||(e.exports={})}}},b=function(e){this.events=getOwn(M,e.id)||{},this.map=e,this.shim=getOwn(y.shim,e.id),this.depExports=[],this.depMaps=[],this.depMatched=[],this.pluginMaps={},this.depCount=0},b.prototype={init:function(e,t,i,r){r=r||{},this.inited||(this.factory=t,i?this.on("error",i):this.events.error&&(i=bind(this,function(e){this.emit("error",e)})),this.depMaps=e&&e.slice(0),this.errback=i,this.inited=!0,this.ignore=r.ignore,r.enabled||this.enabled?this.enable():this.check())},defineDep:function(e,t){this.depMatched[e]||(this.depMatched[e]=!0,this.depCount-=1,this.depExports[e]=t)},fetch:function(){if(!this.fetched){this.fetched=!0,q.startTime=(new Date).getTime();var e=this.map;return this.shim?void q.makeRequire(this.map,{enableBuildCallback:!0})(this.shim.deps||[],bind(this,function(){return e.prefix?this.callPlugin():this.load()})):e.prefix?this.callPlugin():this.load()}},load:function(){var e=this.map.url;P[e]||(P[e]=!0,q.load(this.map.id,e))},check:function(){if(this.enabled&&!this.enabling){var e,t,i=this.map.id,r=this.depExports,n=this.exports,o=this.factory;if(this.inited){if(this.error)this.emit("error",this.error);else if(!this.defining){if(this.defining=!0,this.depCount<1&&!this.defined){if(isFunction(o)){if(this.events.error&&this.map.isDefine||req.onError!==defaultOnError)try{n=q.execCb(i,o,r,n)}catch(t){e=t}else n=q.execCb(i,o,r,n);if(this.map.isDefine&&void 0===n&&(t=this.module,t?n=t.exports:this.usingExports&&(n=this.exports)),e)return e.requireMap=this.map,e.requireModules=this.map.isDefine?[this.map.id]:null,e.requireType=this.map.isDefine?"define":"require",c(this.error=e)}else n=o;if(this.exports=n,this.map.isDefine&&!this.ignore&&(j[i]=n,req.onResourceLoad)){var a=[];each(this.depMaps,function(e){a.push(e.normalizedMap||e)}),req.onResourceLoad(q,this.map,a)}p(i),this.defined=!0}this.defining=!1,this.defined&&!this.defineEmitted&&(this.defineEmitted=!0,this.emit("defined",this.exports),this.defineEmitComplete=!0)}}else hasProp(q.defQueueMap,i)||this.fetch()}},callPlugin:function(){var e=this.map,t=e.id,r=a(e.prefix);this.depMaps.push(r),u(r,"defined",bind(this,function(r){var n,o,d,f=getOwn(R,this.map.id),l=this.map.name,h=this.map.parentMap?this.map.parentMap.name:null,m=q.makeRequire(e.parentMap,{enableBuildCallback:!0});return this.map.unnormalized?(r.normalize&&(l=r.normalize(l,function(e){return i(e,h,!0)})||""),o=a(e.prefix+"!"+l,this.map.parentMap),u(o,"defined",bind(this,function(e){this.map.normalizedMap=o,this.init([],function(){return e},null,{enabled:!0,ignore:!0})})),d=getOwn(S,o.id),void(d&&(this.depMaps.push(o),this.events.error&&d.on("error",bind(this,function(e){this.emit("error",e)})),d.enable()))):f?(this.map.url=q.nameToUrl(f),void this.load()):(n=bind(this,function(e){this.init([],function(){return e},null,{enabled:!0})}),n.error=bind(this,function(e){this.inited=!0,this.error=e,e.requireModules=[t],eachProp(S,function(e){0===e.map.id.indexOf(t+"_unnormalized")&&p(e.map.id)}),c(e)}),n.fromText=bind(this,function(i,r){var o=e.name,u=a(o),d=useInteractive;r&&(i=r),d&&(useInteractive=!1),s(u),hasProp(y.config,t)&&(y.config[o]=y.config[t]);try{req.exec(i)}catch(e){return c(makeError("fromtexteval","fromText eval for "+t+" failed: "+e,e,[t]))}d&&(useInteractive=!0),this.depMaps.push(u),q.completeLoad(o),m([o],n)}),void r.load(e.name,m,n,y))})),q.enable(r,this),this.pluginMaps[r.id]=r},enable:function(){k[this.map.id]=this,this.enabled=!0,this.enabling=!0,each(this.depMaps,bind(this,function(e,t){var i,r,n;if("string"==typeof e){if(e=a(e,this.map.isDefine?this.map:this.map.parentMap,!1,!this.skipMap),this.depMaps[t]=e,n=getOwn(E,e.id))return void(this.depExports[t]=n(this));this.depCount+=1,u(e,"defined",bind(this,function(e){this.undefed||(this.defineDep(t,e),this.check())})),this.errback?u(e,"error",bind(this,this.errback)):this.events.error&&u(e,"error",bind(this,function(e){this.emit("error",e)}))}i=e.id,r=S[i],hasProp(E,i)||!r||r.enabled||q.enable(e,this)})),eachProp(this.pluginMaps,bind(this,function(e){var t=getOwn(S,e.id);t&&!t.enabled&&q.enable(e,this)})),this.enabling=!1,this.check()},on:function(e,t){var i=this.events[e];i||(i=this.events[e]=[]),i.push(t)},emit:function(e,t){each(this.events[e],function(e){e(t)}),"error"===e&&delete this.events[e]}},q={config:y,contextName:e,registry:S,defined:j,urlFetched:P,defQueue:O,defQueueMap:{},Module:b,makeModuleMap:a,nextTick:req.nextTick,onError:c,configure:function(e){if(e.baseUrl&&"/"!==e.baseUrl.charAt(e.baseUrl.length-1)&&(e.baseUrl+="/"),"string"==typeof e.urlArgs){var t=e.urlArgs;e.urlArgs=function(e,i){return(i.indexOf("?")===-1?"?":"&")+t}}var i=y.shim,r={paths:!0,bundles:!0,config:!0,map:!0};eachProp(e,function(e,t){r[t]?(y[t]||(y[t]={}),mixin(y[t],e,!0,!0)):y[t]=e}),e.bundles&&eachProp(e.bundles,function(e,t){each(e,function(e){e!==t&&(R[e]=t)})}),e.shim&&(eachProp(e.shim,function(e,t){isArray(e)&&(e={deps:e}),!e.exports&&!e.init||e.exportsFn||(e.exportsFn=q.makeShimExports(e)),i[t]=e}),y.shim=i),e.packages&&each(e.packages,function(e){var t,i;e="string"==typeof e?{name:e}:e,i=e.name,t=e.location,t&&(y.paths[i]=e.location),y.pkgs[i]=e.name+"/"+(e.main||"main").replace(currDirRegExp,"").replace(jsSuffixRegExp,"")}),eachProp(S,function(e,t){e.inited||e.map.unnormalized||(e.map=a(t,null,!0))}),(e.deps||e.callback)&&q.require(e.deps||[],e.callback)},makeShimExports:function(e){function t(){var t;return e.init&&(t=e.init.apply(global,arguments)),t||e.exports&&getGlobal(e.exports)}return t},makeRequire:function(t,n){function o(i,r,u){var d,p,f;return n.enableBuildCallback&&r&&isFunction(r)&&(r.__requireJsBuild=!0),"string"==typeof i?isFunction(r)?c(makeError("requireargs","Invalid require call"),u):t&&hasProp(E,i)?E[i](S[t.id]):req.get?req.get(q,i,t,o):(p=a(i,t,!1,!0),d=p.id,hasProp(j,d)?j[d]:c(makeError("notloaded",'Module name "'+d+'" has not been loaded yet for context: '+e+(t?"":". Use require([])")))):(v(),q.nextTick(function(){v(),f=s(a(null,t)),f.skipMap=n.skipMap,f.init(i,r,u,{enabled:!0}),l()}),o)}return n=n||{},mixin(o,{isBrowser:isBrowser,toUrl:function(e){var r,n=e.lastIndexOf("."),o=e.split("/")[0],a="."===o||".."===o;return n!==-1&&(!a||n>1)&&(r=e.substring(n,e.length),e=e.substring(0,n)),q.nameToUrl(i(e,t&&t.id,!0),r,!0)},defined:function(e){return hasProp(j,a(e,t,!1,!0).id)},specified:function(e){return e=a(e,t,!1,!0).id,hasProp(j,e)||hasProp(S,e)}}),t||(o.undef=function(e){d();var i=a(e,t,!0),n=getOwn(S,e);n.undefed=!0,r(e),delete j[e],delete P[i.url],delete M[e],eachReverse(O,function(t,i){t[0]===e&&O.splice(i,1)}),delete q.defQueueMap[e],n&&(n.events.defined&&(M[e]=n.events),p(e))}),o},enable:function(e){var t=getOwn(S,e.id);t&&s(e).enable()},completeLoad:function(e){var t,i,r,o=getOwn(y.shim,e)||{},a=o.exports;for(d();O.length;){if(i=O.shift(),null===i[0]){if(i[0]=e,t)break;t=!0}else i[0]===e&&(t=!0);h(i)}if(q.defQueueMap={},r=getOwn(S,e),!t&&!hasProp(j,e)&&r&&!r.inited){if(!(!y.enforceDefine||a&&getGlobal(a)))return n(e)?void 0:c(makeError("nodefine","No define call for "+e,null,[e]));h([e,o.deps||[],o.exportsFn])}l()},nameToUrl:function(e,t,i){var r,n,o,a,s,u,c,d=getOwn(y.pkgs,e);if(d&&(e=d),c=getOwn(R,e))return q.nameToUrl(c,t,i);if(req.jsExtRegExp.test(e))s=e+(t||"");else{for(r=y.paths,n=e.split("/"),o=n.length;o>0;o-=1)if(a=n.slice(0,o).join("/"),u=getOwn(r,a)){isArray(u)&&(u=u[0]),n.splice(0,o,u);break}s=n.join("/"),s+=t||(/^data\:|^blob\:|\?/.test(s)||i?"":".js"),s=("/"===s.charAt(0)||s.match(/^[\w\+\.\-]+:/)?"":y.baseUrl)+s}return y.urlArgs&&!/^blob\:/.test(s)?s+y.urlArgs(e,s):s},load:function(e,t){req.load(q,e,t)},execCb:function(e,t,i,r){return t.apply(r,i)},onScriptLoad:function(e){if("load"===e.type||readyRegExp.test((e.currentTarget||e.srcElement).readyState)){interactiveScript=null;var t=g(e);q.completeLoad(t.id)}},onScriptError:function(e){var t=g(e);if(!n(t.id)){var i=[];return eachProp(S,function(e,r){0!==r.indexOf("_@r")&&each(e.depMaps,function(e){if(e.id===t.id)return i.push(r),!0})}),c(makeError("scripterror",'Script error for "'+t.id+(i.length?'", needed by: '+i.join(", "):'"'),e,[t.id]))}}},q.require=q.makeRequire(),q}function getInteractiveScript(){return interactiveScript&&"interactive"===interactiveScript.readyState?interactiveScript:(eachReverse(scripts(),function(e){if("interactive"===e.readyState)return interactiveScript=e}),interactiveScript)}var req,s,head,baseElement,dataMain,src,interactiveScript,currentlyAddingScript,mainScript,subPath,version="2.3.2",commentRegExp=/\/\*[\s\S]*?\*\/|([^:"'=]|^)\/\/.*$/gm,cjsRequireRegExp=/[^.]\s*require\s*\(\s*["']([^'"\s]+)["']\s*\)/g,jsSuffixRegExp=/\.js$/,currDirRegExp=/^\.\//,op=Object.prototype,ostring=op.toString,hasOwn=op.hasOwnProperty,isBrowser=!("undefined"==typeof window||"undefined"==typeof navigator||!window.document),isWebWorker=!isBrowser&&"undefined"!=typeof importScripts,readyRegExp=isBrowser&&"PLAYSTATION 3"===navigator.platform?/^complete$/:/^(complete|loaded)$/,defContextName="_",isOpera="undefined"!=typeof opera&&"[object Opera]"===opera.toString(),contexts={},cfg={},globalDefQueue=[],useInteractive=!1;if("undefined"==typeof define){if("undefined"!=typeof requirejs){if(isFunction(requirejs))return;cfg=requirejs,requirejs=void 0}"undefined"==typeof require||isFunction(require)||(cfg=require,require=void 0),req=requirejs=function(e,t,i,r){var n,o,a=defContextName;return isArray(e)||"string"==typeof e||(o=e,isArray(t)?(e=t,t=i,i=r):e=[]),o&&o.context&&(a=o.context),n=getOwn(contexts,a),n||(n=contexts[a]=req.s.newContext(a)),o&&n.configure(o),n.require(e,t,i)},req.config=function(e){return req(e)},req.nextTick="undefined"!=typeof setTimeout?function(e){setTimeout(e,4)}:function(e){e()},require||(require=req),req.version=version,req.jsExtRegExp=/^\/|:|\?|\.js$/,req.isBrowser=isBrowser,s=req.s={contexts:contexts,newContext:newContext},req({}),each(["toUrl","undef","defined","specified"],function(e){req[e]=function(){var t=contexts[defContextName];return t.require[e].apply(t,arguments)}}),isBrowser&&(head=s.head=document.getElementsByTagName("head")[0],baseElement=document.getElementsByTagName("base")[0],baseElement&&(head=s.head=baseElement.parentNode)),req.onError=defaultOnError,req.createNode=function(e,t,i){var r=e.xhtml?document.createElementNS("http://www.w3.org/1999/xhtml","html:script"):document.createElement("script");return r.type=e.scriptType||"text/javascript",r.charset="utf-8",r.async=!0,r},req.load=function(e,t,i){var r,n=e&&e.config||{};if(isBrowser)return r=req.createNode(n,t,i),r.setAttribute("data-requirecontext",e.contextName),r.setAttribute("data-requiremodule",t),!r.attachEvent||r.attachEvent.toString&&r.attachEvent.toString().indexOf("[native code")<0||isOpera?(r.addEventListener("load",e.onScriptLoad,!1),r.addEventListener("error",e.onScriptError,!1)):(useInteractive=!0,r.attachEvent("onreadystatechange",e.onScriptLoad)),r.src=i,n.onNodeCreated&&n.onNodeCreated(r,n,t,i),currentlyAddingScript=r,baseElement?head.insertBefore(r,baseElement):head.appendChild(r),currentlyAddingScript=null,r;if(isWebWorker)try{setTimeout(function(){},0),importScripts(i),e.completeLoad(t)}catch(r){e.onError(makeError("importscripts","importScripts failed for "+t+" at "+i,r,[t]))}},isBrowser&&!cfg.skipDataMain&&eachReverse(scripts(),function(e){if(head||(head=e.parentNode),dataMain=e.getAttribute("data-main"))return mainScript=dataMain,cfg.baseUrl||mainScript.indexOf("!")!==-1||(src=mainScript.split("/"),mainScript=src.pop(),subPath=src.length?src.join("/")+"/":"./",cfg.baseUrl=subPath),mainScript=mainScript.replace(jsSuffixRegExp,""),req.jsExtRegExp.test(mainScript)&&(mainScript=dataMain),cfg.deps=cfg.deps?cfg.deps.concat(mainScript):[mainScript],!0}),define=function(e,t,i){var r,n;"string"!=typeof e&&(i=t,t=e,e=null),isArray(t)||(i=t,t=null),!t&&isFunction(i)&&(t=[],i.length&&(i.toString().replace(commentRegExp,commentReplace).replace(cjsRequireRegExp,function(e,i){t.push(i)}),t=(1===i.length?["require"]:["require","exports","module"]).concat(t))),useInteractive&&(r=currentlyAddingScript||getInteractiveScript(),r&&(e||(e=r.getAttribute("data-requiremodule")),n=contexts[r.getAttribute("data-requirecontext")])),n?(n.defQueue.push([e,t,i]),n.defQueueMap[e]=!0):globalDefQueue.push([e,t,i])},define.amd={jQuery:!0},req.exec=function(text){return eval(text)},req(cfg)}}(this,"undefined"==typeof setTimeout?void 0:setTimeout);
//# sourceMappingURL=require.min.js.map
\ No newline at end of file
... ...
... ... @@ -15,7 +15,7 @@
@import url("../libs/eonasdan-bootstrap-datetimepicker/build/css/bootstrap-datetimepicker.min.css");
@import url("../libs/bootstrap-daterangepicker/daterangepicker.css");
@import url("../libs/nice-validator/dist/jquery.validator.css");
@import url("../libs/selectpage/selectpage.css");
@import url("../libs/fastadmin-selectpage/selectpage.css");
@main-bg: #f1f4f6;
@panel-intro-bg: darken(@main-bg,3%);
... ... @@ -54,7 +54,6 @@ body.is-dialog {
}
}
}
.note-dialog .modal {z-index:1060;}
.bootstrap-dialog .modal-dialog {
/*width: 70%;*/
... ... @@ -668,13 +667,16 @@ form.form-horizontal .control-label {
background: #ecf0f1;
overflow:hidden;
a {
background-color: #95a5a6!important;
border-color: #95a5a6!important;
background-color: #95a5a6;
border-color: #95a5a6;
color:#fff!important;
height:31px;
margin-top:0;
border: 1px solid transparent;
}
.layui-layer-btn0{
background-color: #18bc9c!important;
border-color: #18bc9c!important;
background-color: #18bc9c;
border-color: #18bc9c;
}
}
.layui-layer-footer {
... ... @@ -763,6 +765,14 @@ form.form-horizontal .control-label {
position:absolute;
}
}
@media (min-width: 564px){
body.is-dialog .daterangepicker {
min-width: 130px;
}
body.is-dialog .daterangepicker .ranges ul {
width: 130px;
}
}
/*手机版样式*/
@media (max-width: @screen-phone) {
... ... @@ -774,6 +784,9 @@ form.form-horizontal .control-label {
display:none;
}
}
.fixed .content-wrapper, .fixed .right-side {
padding-top: 50px;
}
}
/*平板样式*/
@media (max-width: @screen-tablet) {
... ...
... ... @@ -61,15 +61,6 @@ body {
.box-shadow(none);
}
.layui-layer-fast {
-webkit-animation-fill-mode: both;
animation-fill-mode: both;
-webkit-animation-duration: .3s;
animation-duration: .3s;
-webkit-animation-name: layer-bounceIn;
animation-name: layer-bounceIn;
}
/*修复nice-validator和summernote的编辑框冲突*/
.nice-validator .note-editor .note-editing-area .note-editable{
display:inherit;
... ... @@ -329,7 +320,7 @@ body {
}
}
footer.footer{width:100%;color: #aaa;background: #555;margin-top:25px;}
footer.footer{width:100%;color: #aaa;background: #555;margin-top:25px;position: fixed;bottom: 0;}
footer.footer ul{margin:60px 0 30px 0;padding:0;}
footer.footer ul li.f-tit{margin-bottom:10px;font-size: 14px;color: #fff;}
footer.footer ul li{line-height: 26px;white-space: nowrap;list-style: none;margin:0;padding:0;}
... ...