新增一对多CRUD功能

新增一键生成tagsinput组件
新增autocomplete和tagsinput前端组件
新增配置全局启用上传时使用完整URL功能
新增附件列表上传归类
新增后台管理布局个性化配置
新增插件安装成功导入测试数据提示
新增后缀生成icon缓存
新增全局列表图片缩略图样式
优化插件安装后自动刷新JS缓存
优化后台管理左侧菜单展现方式
优化全局样式
优化fieldlist组件
优化上传组件归类功能
优化Bootstrap-table固定列高度
优化Layer弹窗焦点框
pull/354/MERGE
Karson 2021-12-16 10:47:18 +08:00
parent 824f337481
commit a7317ec08c
127 changed files with 8778 additions and 1491 deletions

View File

@ -7,7 +7,7 @@ use think\Config;
/**
* @website https://github.com/calinrada/php-apidoc
* @author Calin Rada <rada.calin@gmail.com>
* @author Karson <karsonzhang@163.com>
* @author Karson <karson@fastadmin.net>
*/
class Builder
{

View File

@ -11,6 +11,7 @@ use think\console\Output;
use think\Db;
use think\Exception;
use think\exception\ErrorException;
use think\exception\PDOException;
use think\Lang;
use think\Loader;
@ -254,12 +255,14 @@ class Crud extends Command
->addOption('fields', 'i', Option::VALUE_OPTIONAL, 'model visible fields', null)
->addOption('force', 'f', Option::VALUE_OPTIONAL, 'force override or force delete,without tips', null)
->addOption('local', 'l', Option::VALUE_OPTIONAL, 'local model', 1)
->addOption('import', 'a', Option::VALUE_OPTIONAL, 'enable import function', 0)
->addOption('relation', 'r', Option::VALUE_OPTIONAL | Option::VALUE_IS_ARRAY, 'relation table name without prefix', null)
->addOption('relationmodel', 'e', Option::VALUE_OPTIONAL | Option::VALUE_IS_ARRAY, 'relation model name', null)
->addOption('relationforeignkey', 'k', Option::VALUE_OPTIONAL | Option::VALUE_IS_ARRAY, 'relation foreign key', null)
->addOption('relationprimarykey', 'p', Option::VALUE_OPTIONAL | Option::VALUE_IS_ARRAY, 'relation primary key', null)
->addOption('relationfields', 's', Option::VALUE_OPTIONAL | Option::VALUE_IS_ARRAY, 'relation table fields', null)
->addOption('relationmode', 'o', Option::VALUE_OPTIONAL | Option::VALUE_IS_ARRAY, 'relation table mode,hasone or belongsto', null)
->addOption('relationmode', 'o', Option::VALUE_OPTIONAL | Option::VALUE_IS_ARRAY, 'relation table mode,hasone/belongsto/hasmany', null)
->addOption('relationcontroller', 'w', Option::VALUE_OPTIONAL | Option::VALUE_IS_ARRAY, 'relation table controller,only work at hasmany mode', null)
->addOption('delete', 'd', Option::VALUE_OPTIONAL, 'delete all files generated by CRUD', null)
->addOption('menu', 'u', Option::VALUE_OPTIONAL, 'create menu when CRUD completed', null)
->addOption('setcheckboxsuffix', null, Option::VALUE_OPTIONAL | Option::VALUE_IS_ARRAY, 'automatically generate checkbox component with suffix', null)
@ -303,6 +306,8 @@ class Crud extends Command
$force = $input->getOption('force');
//是否为本地model,为0时表示为全局model将会把model放在app/common/model中
$local = $input->getOption('local');
//是否启用导入功能
$import = $input->getOption('import');
if (!$table) {
throw new Exception('table name can\'t empty');
@ -323,6 +328,8 @@ class Crud extends Command
$relationPrimaryKey = $input->getOption('relationprimarykey');
//关联表显示字段
$relationFields = $input->getOption('relationfields');
//关联表显示字段
$relationController = $input->getOption('relationcontroller');
//复选框后缀
$setcheckboxsuffix = $input->getOption('setcheckboxsuffix');
//单选框后缀
@ -482,8 +489,10 @@ class Crud extends Command
'relationFields' => isset($relationFields[$index]) ? explode(',', $relationFields[$index]) : [],
//关联模式
'relationMode' => isset($relationMode[$index]) ? $relationMode[$index] : 'belongsto',
//关联模型控制器
'relationController' => isset($relationController[$index]) ? $relationController[$index] : '',
//关联表外键
'relationForeignKey' => isset($relationForeignKey[$index]) ? $relationForeignKey[$index] : Loader::parseName($relationName) . '_id',
'relationForeignKey' => isset($relationForeignKey[$index]) ? $relationForeignKey[$index] : '',
//关联表主键
'relationPrimaryKey' => isset($relationPrimaryKey[$index]) ? $relationPrimaryKey[$index] : '',
];
@ -506,7 +515,8 @@ class Crud extends Command
$baseFileName = Loader::parseName(array_pop($baseNameArr), 0);
array_push($baseNameArr, $baseFileName);
$controllerBaseName = strtolower(implode(DS, $baseNameArr));
$controllerUrl = strtolower(implode('/', $baseNameArr));
//$controllerUrl = strtolower(implode('/', $baseNameArr));
$controllerUrl = $this->getControllerUrl($moduleName, $baseNameArr);
//视图文件
$viewArr = $controllerArr;
@ -630,6 +640,7 @@ class Crud extends Command
$editList = [];
$javascriptList = [];
$langList = [];
$operateButtonList = [];
$field = 'id';
$order = 'id';
$priDefined = false;
@ -662,7 +673,7 @@ class Crud extends Command
if (!in_array($relationPrimaryKey, $fieldArr)) {
throw new Exception('table [' . $modelTableName . '] must be contain field [' . $relationPrimaryKey . ']');
}
} else {
} elseif ($relation['relationMode'] == 'belongsto') {
$relationForeignKey = $relation['relationForeignKey'] ? $relation['relationForeignKey'] : Loader::parseName($relation['relationName']) . "_id";
$relationPrimaryKey = $relation['relationPrimaryKey'] ? $relation['relationPrimaryKey'] : $relation['relationPriKey'];
if (!in_array($relationForeignKey, $fieldArr)) {
@ -671,6 +682,17 @@ class Crud extends Command
if (!in_array($relationPrimaryKey, $relation['relationFieldList'])) {
throw new Exception('relation table [' . $relation['relationTableName'] . '] must be contain field [' . $relationPrimaryKey . ']');
}
} elseif ($relation['relationMode'] == 'hasmany') {
$relationForeignKey = $relation['relationForeignKey'] ? $relation['relationForeignKey'] : $table . "_id";
$relationPrimaryKey = $relation['relationPrimaryKey'] ? $relation['relationPrimaryKey'] : $priKey;
if (!in_array($relationForeignKey, $relation['relationFieldList'])) {
throw new Exception('relation table [' . $relation['relationTableName'] . '] must be contain field [' . $relationForeignKey . ']');
}
if (!in_array($relationPrimaryKey, $fieldArr)) {
throw new Exception('table [' . $modelTableName . '] must be contain field [' . $relationPrimaryKey . ']');
}
$relation['relationColumnList'] = [];
$relation['relationFieldList'] = [];
}
$relation['relationForeignKey'] = $relationForeignKey;
$relation['relationPrimaryKey'] = $relationPrimaryKey;
@ -686,8 +708,15 @@ class Crud extends Command
$appendAttrList = [];
$controllerAssignList = [];
$headingHtml = '{:build_heading()}';
$controllerImport = '';
$importHtml = '';
$recyclebinHtml = '';
if ($import) {
$controllerImport = $this->getReplacedStub('mixins/import', []);
$importHtml = '<a href="javascript:;" class="btn btn-danger btn-import {:$auth->check(\'' . $controllerUrl . '/import\')?\'\':\'hide\'}" title="{:__(\'Import\')}" id="btn-import-file" data-url="ajax/upload" data-mimetype="csv,xls,xlsx" data-multiple="false"><i class="fa fa-upload"></i> {:__(\'Import\')}</a>';
}
//循环所有字段,开始构造视图的HTML和JS信息
foreach ($columnList as $k => $v) {
$field = $v['COLUMN_NAME'];
@ -867,7 +896,9 @@ class Crud extends Command
$defaultValue = '';
$attrArr['data-rule'] = 'required';
$cssClassArr[] = 'selectpage';
$selectpageController = str_replace('_', '/', substr($field, 0, strripos($field, '_')));
$selectpageTable = substr($field, 0, strripos($field, '_'));
$selectpageField = '';
$selectpageController = str_replace('_', '/', $selectpageTable);
$attrArr['data-source'] = $selectpageController . "/index";
//如果是类型表需要特殊处理下
if ($selectpageController == 'category') {
@ -883,6 +914,22 @@ class Crud extends Command
if ($this->isMatchSuffix($field, $this->selectpagesSuffix)) {
$attrArr['data-multiple'] = 'true';
}
$tableInfo = null;
try {
$tableInfo = \think\Db::name($selectpageTable)->getTableInfo();
if (isset($tableInfo['fields'])) {
foreach ($tableInfo['fields'] as $m => $n) {
if (in_array($n, ['nickname', 'title', 'name'])) {
$selectpageField = $n;
break;
}
}
}
} catch (\Exception $e) {
}
if (!$selectpageField) {
foreach ($this->fieldSelectpageMap as $m => $n) {
if (in_array($field, $n)) {
$attrArr['data-field'] = $m;
@ -890,6 +937,7 @@ class Crud extends Command
}
}
}
}
//因为有自动完成可输入其它内容
$step = array_intersect($cssClassArr, ['selectpage']) ? 0 : $step;
$attrArr['class'] = implode(' ', $cssClassArr);
@ -948,6 +996,33 @@ class Crud extends Command
//循环关联表,追加语言包和JS列
foreach ($relations as $index => $relation) {
if ($relation['relationMode'] == 'hasmany') {
$relationFieldText = ucfirst(strtolower($relation['relationName'])) . ' List';
// 语言列表
if ($relation['relationTableInfo']['Comment']) {
$langList[] = $this->getLangItem($relationFieldText, rtrim($relation['relationTableInfo']['Comment'], "") . "列表");
}
$relationTableName = $relation['relationTableName'];
$relationTableName = stripos($relationTableName, $prefix) === 0 ? substr($relationTableName, strlen($prefix)) : $relationTableName;
list($realtionControllerNamespace, $realtionControllerName, $realtionControllerFile, $realtionControllerArr) = $this->getControllerData($moduleName, $relation['relationController'], $relationTableName);
$realtionControllerArr = array_map("strtolower", $realtionControllerArr);
if (count($realtionControllerArr) > 1) {
$realtionControllerArr = [implode('.', $realtionControllerArr)];
}
$realtionControllerArr[] = 'index';
$realtionControllerArr[] = $relation['relationForeignKey'] . '/{ids}';
$relationControllerUrl = implode('/', $realtionControllerArr);
//构造JS列信息
$operateButtonList[] = "{name: 'addtabs',title: __('{$relationFieldText}'),text: __('{$relationFieldText}'),classname: 'btn btn-xs btn-info btn-dialog',icon: 'fa fa-list',url: '" . $relationControllerUrl . "'}";
//echo "php think crud -t {$relation['relationTableName']} -c {$relation['relationController']} -m {$relation['relationModel']} -i " . implode(',', $relation['relationFields']);
//不存在关联表控制器的情况下才进行生成
if (!is_file($realtionControllerFile)) {
exec("php think crud -t {$relation['relationTableName']} -c {$relation['relationController']} -m {$relation['relationModel']} -i " . implode(',', $relation['relationFields']));
}
}
foreach ($relation['relationColumnList'] as $k => $v) {
// 不显示的字段直接过滤掉
if ($relation['relationFields'] && !in_array($v['COLUMN_NAME'], $relation['relationFields'])) {
@ -969,7 +1044,7 @@ class Crud extends Command
}
//JS最后一列加上操作列
$javascriptList[] = str_repeat(" ", 24) . "{field: 'operate', title: __('Operate'), table: table, events: Table.api.events.operate, formatter: Table.api.formatter.operate}";
$javascriptList[] = str_repeat(" ", 24) . "{field: 'operate', title: __('Operate'), table: table, events: Table.api.events.operate, " . ($operateButtonList ? "buttons: [" . implode(',', $operateButtonList) . "], " : "") . "formatter: Table.api.formatter.operate}";
$addList = implode("\n", array_filter($addList));
$editList = implode("\n", array_filter($editList));
$javascriptList = implode(",\n", array_filter($javascriptList));
@ -1032,9 +1107,11 @@ class Crud extends Command
'relationSearch' => $relations ? 'true' : 'false',
'relationWithList' => '',
'relationMethodList' => '',
'controllerImport' => $controllerImport,
'controllerIndex' => '',
'recyclebinJs' => '',
'headingHtml' => $headingHtml,
'importHtml' => $importHtml,
'recyclebinHtml' => $recyclebinHtml,
'visibleFieldList' => $fields ? "\$row->visible(['" . implode("','", array_filter(in_array($priKey, explode(',', $fields)) ? explode(',', $fields) : explode(',', $priKey . ',' . $fields))) . "']);" : '',
'appendAttrList' => implode(",\n", $appendAttrList),
@ -1047,24 +1124,30 @@ class Crud extends Command
//如果使用关联模型
if ($relations) {
$relationWithList = $relationMethodList = $relationVisibleFieldList = [];
$relationKeyArr = ['hasone' => 'hasOne', 'belongsto' => 'belongsTo', 'hasmany' => 'hasMany'];
foreach ($relations as $index => $relation) {
//需要构造关联的方法
$relation['relationMethod'] = strtolower($relation['relationName']);
//关联的模式
$relation['relationMode'] = $relation['relationMode'] == 'hasone' ? 'hasOne' : 'belongsTo';
$relation['relationMode'] = strtolower($relation['relationMode']);
$relation['relationMode'] = array_key_exists($relation['relationMode'], $relationKeyArr) ? $relationKeyArr[$relation['relationMode']] : '';
//关联字段
$relation['relationPrimaryKey'] = $relation['relationPrimaryKey'] ? $relation['relationPrimaryKey'] : $priKey;
//构造关联模型的方法
$relationMethodList[] = $this->getReplacedStub('mixins' . DS . 'modelrelationmethod' . ($relation['relationMode'] == 'hasMany' ? '-hasmany' : ''), $relation);
if ($relation['relationMode'] == 'hasMany') {
continue;
}
//预载入的方法
$relationWithList[] = $relation['relationMethod'];
unset($relation['relationColumnList'], $relation['relationFieldList'], $relation['relationTableInfo']);
//构造关联模型的方法
$relationMethodList[] = $this->getReplacedStub('mixins' . DS . 'modelrelationmethod', $relation);
//如果设置了显示主表字段,则必须显式将关联表字段显示
if ($fields) {
$relationVisibleFieldList[] = "\$row->visible(['{$relation['relationMethod']}']);";
@ -1080,8 +1163,10 @@ class Crud extends Command
$data['relationMethodList'] = implode("\n\n", $relationMethodList);
$data['relationVisibleFieldList'] = implode("\n\t\t\t\t", $relationVisibleFieldList);
if ($relationWithList) {
//需要重写index方法
$data['controllerIndex'] = $this->getReplacedStub('controllerindex', $data);
}
} elseif ($fields) {
$data = array_merge($data, ['relationWithList' => '', 'relationMethodList' => '', 'relationVisibleFieldList' => '']);
//需要重写index方法
@ -1220,6 +1305,28 @@ EOD;
return true;
}
/**
* 获取控制器URL
* @param string $moduleName
* @param array $baseNameArr
* @return string
*/
protected function getControllerUrl($moduleName, $baseNameArr)
{
for ($i = 0; $i < count($baseNameArr) - 1; $i++) {
$temp = array_slice($baseNameArr, 0, $i + 1);
$temp[$i] = ucfirst($temp[$i]);
$controllerFile = APP_PATH . $moduleName . DS . 'controller' . DS . implode(DS, $temp) . '.php';
//检测父级目录同名控制器是否存在存在则变更URL格式
if (is_file($controllerFile)) {
$baseNameArr = [implode('.', $baseNameArr)];
break;
}
}
$controllerUrl = strtolower(implode('/', $baseNameArr));
return $controllerUrl;
}
/**
* 获取控制器相关信息
* @param $module
@ -1269,14 +1376,14 @@ EOD;
$arr = [];
if (!$name) {
$parseName = Loader::parseName($table, 1);
$parseArr = [$table];
} else {
$name = str_replace('_', '/', $table);
}
$name = str_replace(['.', '/', '\\'], '/', $name);
$arr = explode('/', $name);
$parseName = ucfirst(array_pop($arr));
$parseArr = $arr;
array_push($parseArr, $parseName);
}
//类名不能为内部关键字
if (in_array(strtolower($parseName), $this->internalKeywords)) {
throw new Exception('Unable to use internal variable:' . $parseName);

View File

@ -25,10 +25,7 @@ class {%controllerName%} extends Backend
{%controllerAssignList%}
}
public function import()
{
parent::import();
}
{%controllerImport%}
/**
* 默认生成的控制器所继承的父类中有index/add/edit/del/multi五个基础方法、destroy/restore/recyclebin三个回收站方法

View File

@ -10,7 +10,7 @@
<a href="javascript:;" class="btn btn-success btn-add {:$auth->check('{%controllerUrl%}/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('{%controllerUrl%}/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('{%controllerUrl%}/del')?'':'hide'}" title="{:__('Delete')}" ><i class="fa fa-trash"></i> {:__('Delete')}</a>
<a href="javascript:;" class="btn btn-danger btn-import {:$auth->check('{%controllerUrl%}/import')?'':'hide'}" title="{:__('Import')}" id="btn-import-file" data-url="ajax/upload" data-mimetype="csv,xls,xlsx" data-multiple="false"><i class="fa fa-upload"></i> {:__('Import')}</a>
{%importHtml%}
<div class="dropdown btn-group {:$auth->check('{%controllerUrl%}/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>

View File

@ -0,0 +1,4 @@
public function import()
{
parent::import();
}

View File

@ -0,0 +1,5 @@
public function {%relationMethod%}s()
{
return $this->{%relationMode%}('{%relationClassName%}', '{%relationForeignKey%}', '{%relationPrimaryKey%}');
}

View File

@ -194,33 +194,3 @@ if (!function_exists('build_heading')) {
return $result;
}
}
if (!function_exists('build_suffix_image')) {
/**
* 生成文件后缀图片
* @param string $suffix 后缀
* @param null $background
* @return string
*/
function build_suffix_image($suffix, $background = null)
{
$suffix = mb_substr(strtoupper($suffix), 0, 4);
$total = unpack('L', hash('adler32', $suffix, true))[1];
$hue = $total % 360;
list($r, $g, $b) = hsv2rgb($hue / 360, 0.3, 0.9);
$background = $background ? $background : "rgb({$r},{$g},{$b})";
$icon = <<<EOT
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
<path style="fill:#E2E5E7;" d="M128,0c-17.6,0-32,14.4-32,32v448c0,17.6,14.4,32,32,32h320c17.6,0,32-14.4,32-32V128L352,0H128z"/>
<path style="fill:#B0B7BD;" d="M384,128h96L352,0v96C352,113.6,366.4,128,384,128z"/>
<polygon style="fill:#CAD1D8;" points="480,224 384,128 480,128 "/>
<path style="fill:{$background};" d="M416,416c0,8.8-7.2,16-16,16H48c-8.8,0-16-7.2-16-16V256c0-8.8,7.2-16,16-16h352c8.8,0,16,7.2,16,16 V416z"/>
<path style="fill:#CAD1D8;" d="M400,432H96v16h304c8.8,0,16-7.2,16-16v-16C416,424.8,408.8,432,400,432z"/>
<g><text><tspan x="220" y="380" font-size="124" font-family="Verdana, Helvetica, Arial, sans-serif" fill="white" text-anchor="middle">{$suffix}</tspan></text></g>
</svg>
EOT;
return $icon;
}
}

View File

@ -25,13 +25,13 @@ class Addon extends Backend
public function _initialize()
{
parent::_initialize();
if (!$this->auth->isSuperAdmin() && in_array($this->request->action(), ['install', 'uninstall', 'local', 'upgrade'])) {
if (!$this->auth->isSuperAdmin() && in_array($this->request->action(), ['install', 'uninstall', 'local', 'upgrade', 'authorization', 'testdata'])) {
$this->error(__('Access is allowed only to the super management group'));
}
}
/**
* 查看
* 插件列表
*/
public function index()
{
@ -41,6 +41,18 @@ class Addon extends Backend
$v['config'] = $config ? 1 : 0;
$v['url'] = str_replace($this->request->server('SCRIPT_NAME'), '', $v['url']);
}
if ($this->request->isAjax()) {
$result = [];
debug('begin');
try {
$result = Service::addons($this->request->get());
} catch (\Exception $e) {
$this->error($e->getMessage());
}
debug('end');
\think\Log::record("tx:" . debug('begin', 'end', 6) . 's');
return json($result);
}
$this->assignconfig(['addons' => $addons, 'api_url' => config('fastadmin.api_url'), 'faversion' => config('fastadmin.version')]);
return $this->view->fetch();
}
@ -57,13 +69,10 @@ class Addon extends Backend
if (!preg_match("/^[a-zA-Z0-9]+$/", $name)) {
$this->error(__('Addon name incorrect'));
}
if (!is_dir(ADDON_PATH . $name)) {
$this->error(__('Directory not found'));
}
$info = get_addon_info($name);
$config = get_addon_fullconfig($name);
if (!$info) {
$this->error(__('No Results were found'));
$this->error(__('Addon not exists'));
}
if ($this->request->isPost()) {
$params = $this->request->post("row/a", [], 'trim');
@ -80,13 +89,19 @@ class Addon extends Backend
}
}
try {
$addon = get_addon_instance($name);
//插件自定义配置实现逻辑
if (method_exists($addon, 'config')) {
$addon->config($name, $config);
} else {
//更新配置文件
set_addon_fullconfig($name, $config);
Service::refresh();
$this->success();
}
} catch (Exception $e) {
$this->error(__($e->getMessage()));
}
$this->success();
}
$this->error(__('Parameter %s can not be empty', ''));
}
@ -212,6 +227,9 @@ class Addon extends Backend
{
Config::set('default_return_type', 'json');
if (!config('app_debug')) {
$this->error(__('Only work at debug mode'));
}
$info = [];
$file = $this->request->file('file');
try {
@ -275,6 +293,29 @@ class Addon extends Backend
$this->success(__('Operate successful'), '', ['addon' => $info]);
}
/**
* 测试数据
*/
public function testdata()
{
$name = $this->request->post("name");
if (!$name) {
$this->error(__('Parameter %s can not be empty', 'name'));
}
if (!preg_match("/^[a-zA-Z0-9]+$/", $name)) {
$this->error(__('Addon name incorrect'));
}
try {
Service::importsql($name, 'testdata.sql');
} catch (AddonException $e) {
$this->result($e->getData(), $e->getCode(), __($e->getMessage()));
} catch (Exception $e) {
$this->error(__($e->getMessage()), $e->getCode());
}
$this->success(__('Import successful'), '');
}
/**
* 已装插件
*/
@ -285,22 +326,7 @@ class Addon extends Backend
$filter = $this->request->get("filter");
$search = $this->request->get("search");
$search = htmlspecialchars(strip_tags($search));
$onlineaddons = Cache::get("onlineaddons");
if (!is_array($onlineaddons) && config('fastadmin.api_url')) {
$onlineaddons = [];
$result = Http::sendRequest(config('fastadmin.api_url') . '/addon/index', [], 'GET', [
CURLOPT_HTTPHEADER => ['Accept-Encoding:gzip'],
CURLOPT_ENCODING => "gzip"
]);
if ($result['ret']) {
$json = (array)json_decode($result['msg'], true);
$rows = isset($json['rows']) ? $json['rows'] : [];
foreach ($rows as $index => $row) {
$onlineaddons[$row['name']] = $row;
}
}
Cache::set("onlineaddons", $onlineaddons, 600);
}
$onlineaddons = $this->getAddonList();
$filter = (array)json_decode($filter, true);
$addons = get_addon_list();
$list = [];
@ -311,6 +337,7 @@ class Addon extends Backend
if (isset($onlineaddons[$v['name']])) {
$v = array_merge($v, $onlineaddons[$v['name']]);
$v['price'] = '-';
} else {
$v['category_id'] = 0;
$v['flag'] = '';
@ -321,9 +348,9 @@ class Addon extends Backend
$v['price'] = __('None');
$v['screenshots'] = [];
$v['releaselist'] = [];
}
$v['url'] = addon_url($v['name']);
$v['url'] = str_replace($this->request->server('SCRIPT_NAME'), '', $v['url']);
}
$v['createtime'] = filemtime(ADDON_PATH . $v['name']);
if ($filter && isset($filter['category_id']) && is_numeric($filter['category_id']) && $filter['category_id'] != $v['category_id']) {
continue;
@ -340,6 +367,105 @@ class Addon extends Backend
return $callback($result);
}
/**
* 登录
*/
public function login()
{
$params = [
'account' => $this->request->post('account'),
'password' => $this->request->post('password'),
'url' => $this->request->url(true),
'faversion' => config('fastadmin.version')
];
try {
$result = Service::login($params);
} catch (Exception $e) {
$this->error(__($e->getMessage()));
}
return json($result);
}
/**
* 会员信息
*/
public function userinfo()
{
$params = [
'uid' => $this->request->post('uid'),
'token' => $this->request->post('token'),
'url' => $this->request->url(true),
'faversion' => config('fastadmin.version')
];
try {
$result = Service::userinfo($params);
} catch (Exception $e) {
$this->error($e->getMessage());
}
return json($result);
}
/**
* 退出
*/
public function logout()
{
$params = [
'uid' => $this->request->post('uid'),
'token' => $this->request->post('token'),
'url' => $this->request->url(true),
'faversion' => config('fastadmin.version')
];
try {
$result = Service::logout($params);
} catch (Exception $e) {
$this->error(__($e->getMessage()));
}
return json($result);
}
/**
* 检测
*/
public function isbuy()
{
$name = $this->request->post("name");
$uid = $this->request->post("uid");
$token = $this->request->post("token");
$version = $this->request->post("version");
$faversion = $this->request->post("faversion");
$extend = [
'uid' => $uid,
'token' => $token,
'version' => $version,
'faversion' => $faversion
];
try {
$result = Service::isBuy($name, $extend);
} catch (Exception $e) {
$this->error(__($e->getMessage()));
}
return json($result);
}
/**
* 刷新授权
*/
public function authorization()
{
$params = [
'uid' => $this->request->post('uid'),
'token' => $this->request->post('token'),
'faversion' => $this->request->post('faversion'),
];
try {
Service::authorization($params);
} catch (Exception $e) {
$this->error(__($e->getMessage()));
}
$this->success(__('Operate successful'));
}
/**
* 获取插件相关表
*/
@ -360,4 +486,31 @@ class Addon extends Backend
$tables = array_values($tables);
$this->success('', null, ['tables' => $tables]);
}
protected function getAddonList()
{
$onlineaddons = Cache::get("onlineaddons");
if (!is_array($onlineaddons) && config('fastadmin.api_url')) {
$onlineaddons = [];
$params = [
'uid' => $this->request->post('uid'),
'token' => $this->request->post('token'),
'version' => config('fastadmin.version'),
'faversion' => config('fastadmin.version'),
];
$json = [];
try {
$json = Service::addons($params);
} catch (\Exception $e) {
}
$rows = isset($json['rows']) ? $json['rows'] : [];
foreach ($rows as $index => $row) {
$onlineaddons[$row['name']] = $row;
}
Cache::set("onlineaddons", $onlineaddons, 600);
}
return $onlineaddons;
}
}

View File

@ -11,6 +11,7 @@ use think\Cache;
use think\Config;
use think\Db;
use think\Lang;
use think\Response;
use think\Validate;
/**
@ -37,17 +38,19 @@ class Ajax extends Backend
*/
public function lang()
{
header('Content-Type: application/javascript');
header("Cache-Control: public");
header("Pragma: cache");
$header = ['Content-Type' => 'application/javascript'];
if (!config('app_debug')) {
$offset = 30 * 60 * 60 * 24; // 缓存一个月
header("Expires: " . gmdate("D, d M Y H:i:s", time() + $offset) . " GMT");
$header['Cache-Control'] = 'public';
$header['Pragma'] = 'cache';
$header['Expires'] = gmdate("D, d M Y H:i:s", time() + $offset) . " GMT";
}
$controllername = input("controllername");
//默认只加载了控制器对应的语言名,你还根据控制器名来加载额外的语言包
$this->loadlang($controllername);
return jsonp(Lang::get(), 200, [], ['json_encode_param' => JSON_FORCE_OBJECT | JSON_UNESCAPED_UNICODE]);
return jsonp(Lang::get(), 200, $header, ['json_encode_param' => JSON_FORCE_OBJECT | JSON_UNESCAPED_UNICODE]);
}
/**
@ -296,10 +299,15 @@ class Ajax extends Backend
public function icon()
{
$suffix = $this->request->request("suffix");
header('Content-type: image/svg+xml');
$suffix = $suffix ? $suffix : "FILE";
echo build_suffix_image($suffix);
exit;
$data = build_suffix_image($suffix);
$header = ['Content-Type' => 'image/svg+xml'];
$offset = 30 * 60 * 60 * 24; // 缓存一个月
$header['Cache-Control'] = 'public';
$header['Pragma'] = 'cache';
$header['Expires'] = gmdate("D, d M Y H:i:s", time() + $offset) . " GMT";
$response = Response::create($data, '', 200, $header);
return $response;
}
}

View File

@ -6,6 +6,7 @@ use app\admin\model\AdminLog;
use app\common\controller\Backend;
use think\Config;
use think\Hook;
use think\Session;
use think\Validate;
/**
@ -31,6 +32,13 @@ class Index extends Backend
*/
public function index()
{
$cookieArr = ['adminskin' => "/^skin\-([a-z\-]+)\$/i", 'multiplenav' => "/^(0|1)\$/", 'multipletab' => "/^(0|1)\$/"];
foreach ($cookieArr as $key => $regex) {
$cookieValue = $this->request->cookie($key);
if (!is_null($cookieValue) && preg_match($regex, $cookieValue)) {
config('fastadmin.' . $key, $cookieValue);
}
}
//左侧菜单
list($menulist, $navlist, $fixedmenu, $referermenu) = $this->auth->getSidebar([
'dashboard' => 'hot',
@ -44,6 +52,7 @@ class Index extends Backend
$this->success('', null, ['menulist' => $menulist, 'navlist' => $navlist]);
}
}
$this->assignconfig('cookie', ['prefix' => config('cookie.prefix')]);
$this->view->assign('menulist', $menulist);
$this->view->assign('navlist', $navlist);
$this->view->assign('fixedmenu', $fixedmenu);
@ -99,6 +108,7 @@ class Index extends Backend
// 根据客户端的cookie,判断是否可以自动登录
if ($this->auth->autologin()) {
Session::delete("referer");
$this->redirect($url);
}
$background = Config::get('fastadmin.login_background');

View File

@ -118,7 +118,7 @@ class Rule extends Backend
//这里需要针对name做唯一验证
$ruleValidate = \think\Loader::validate('AuthRule');
$ruleValidate->rule([
'name' => 'require|format|unique:AuthRule,name,' . $row->id,
'name' => 'require|unique:AuthRule,name,' . $row->id,
]);
$result = $row->validate()->save($params);
if ($result === false) {

View File

@ -88,6 +88,9 @@ class Config extends Backend
*/
public function add()
{
if (!config('app_debug')) {
$this->error(__('Only work at development environment'));
}
if ($this->request->isPost()) {
$this->token();
$params = $this->request->post("row/a", [], 'trim');
@ -166,6 +169,9 @@ class Config extends Backend
*/
public function del($ids = "")
{
if (!config('app_debug')) {
$this->error(__('Only work at development environment'));
}
$name = $this->request->post('name');
$config = ConfigModel::getByName($name);
if ($name && $config) {

View File

@ -201,13 +201,13 @@ return [
'Third group 2' => '三级管理组2',
'Dashboard tips' => '用于展示当前系统中的统计数据、统计报表及重要实时数据',
'Config tips' => '可以在此增改系统的变量和分组,也可以自定义分组和变量',
'Category tips' => '用于管理网站的所有分类,分类可进行无限级分类,分类类型请在常规管理->系统配置->字典配置中添加',
'Category tips' => '分类类型请在常规管理->系统配置->字典配置中添加',
'Attachment tips' => '主要用于管理上传到服务器或第三方存储的数据',
'Addon tips' => '可在线安装、卸载、禁用、启用、配置、升级插件,插件升级前请做好备份。',
'Admin tips' => '一个管理员可以有多个角色组,左侧的菜单根据管理员所拥有的权限进行生成',
'Admin log tips' => '管理员可以查看自己所拥有的权限的管理员日志',
'Group tips' => '角色组可以有多个,角色有上下级层级关系,如果子角色有角色组和管理员的权限则可以派生属于自己组别的下级角色组或管理员',
'Rule tips' => '规则通常对应一个控制器的方法,同时左侧的菜单栏数据也从规则中体现,通常建议通过命令行进行生成规则节点',
'Rule tips' => '菜单规则通常对应一个控制器的方法,同时菜单栏数据也从规则中获取',
'Access is allowed only to the super management group' => '仅超级管理组能访问',
'Local addon' => '本地插件',
// 前台菜单

View File

@ -10,26 +10,31 @@ return [
'Donate' => '打赏作者',
'Warmtips' => '温馨提示',
'Pay now' => '立即支付',
'Offline install' => '离线安装',
'Local install' => '本地安装',
'Refresh addon cache' => '刷新插件缓存',
'Userinfo' => '会员信息',
'Reload authorization' => '刷新授权',
'Online store' => '在线商店',
'Local addon' => '本地插件',
'Conflict tips' => '此插件中发现和现有系统中部分文件发现冲突!以下文件将会被影响,请备份好相关文件后再继续操作',
'Login tips' => '此处登录账号为<a href="https://www.fastadmin.net" target="_blank">FastAdmin官网账号</a>',
'Logined tips' => '你好!%s<br />当前你已经登录,将同步保存你的购买记录',
'Pay tips' => '扫码支付后如果仍然无法立即下载,请不要重复支付,请稍后再重试安装!',
'Pay tips' => '扫码支付后如果仍然无法安装,请不要重复支付,请稍后再重试安装!',
'Pay successful tips' => '购买成功!请点击继续安装按钮完成安装!',
'Pay click tips' => '请点击这里在新窗口中进行支付!',
'Pay new window tips' => '请在新弹出的窗口中进行支付,支付完成后再重新点击安装按钮进行安装!',
'Upgrade tips' => '确认升级<b>《%s》</b><p class="text-danger">1、请务必做好代码和数据库备份备份备份<br>2、升级后如出现冗余数据请根据需要移除即可!<br>3、不建议在生产环境升级请在本地完成升级测试</p>如有重要数据请备份后再操作!',
'Offline installed tips' => '安装成功!清除浏览器缓存和框架缓存后生效!',
'Online installed tips' => '安装成功!清除浏览器缓存和框架缓存后生效!',
'Not login tips' => '你当前未登录FastAdmin登录后将同步已购买的记录,下载时无需二次付费',
'Not login tips' => '你当前未登录FastAdmin请登录后操作',
'Please login and try to install' => '请登录FastAdmin后再进行离线安装',
'Not installed tips' => '请安装后再访问插件前台页面!',
'Not enabled tips' => '插件已经禁用,请启用后再访问插件前台页面!',
'New version tips' => '发现新版本:%s 点击查看更新日志',
'Store now available tips' => '插件市场暂不可用,是否切换到本地插件?',
'Testdata tips' => '你还可以继续导入测试数据!',
'Import testdata' => '导入测试数据',
'Skip testdata' => '暂不导入',
'Store not available tips' => '插件市场暂不可用,是否切换到本地插件?',
'Switch to the local' => '切换到本地插件',
'try to reload' => '重新尝试加载',
'Please disable the add before trying to upgrade' => '请先禁用插件再进行升级',
@ -41,6 +46,7 @@ return [
'View addon screenshots' => '点击查看插件截图',
'Click to toggle status' => '点击切换插件状态',
'Click to contact developer' => '点击与插件开发者取得联系',
'Continue installation' => '继续安装',
'My addons' => '我购买的插件',
'Index' => '前台',
'All' => '全部',
@ -84,13 +90,18 @@ return [
'Install successful' => '安装成功',
'Uninstall successful' => '卸载成功',
'Operate successful' => '操作成功',
'Import successful' => '导入测试数据成功!清除浏览器缓存和框架缓存后生效!',
'Initialize successful' => '初始化成功',
'Initialize template not found' => '初始化模板未找到',
'Addon name incorrect' => '插件名称不正确',
'Addon info file was not found' => '插件配置文件未找到',
'Addon info file data incorrect' => '插件配置信息不正确',
'Addon already exists' => '插件已经存在',
'Addon not exists' => '插件不存在',
'Addon package download failed' => '插件下载失败',
'Conflicting file found' => '发现冲突文件',
'Invalid addon package' => '未验证的插件',
'No initialize method' => '未找到初始化方法',
'No permission to write temporary files' => '没有权限写入临时文件',
'The addon file does not exist' => '插件主启动程序不存在',
'The configuration file content is incorrect' => '配置文件不完整',
@ -98,6 +109,7 @@ return [
'Unable to extract the file' => '无法解压ZIP文件',
'Unable to open file \'%s\' for writing' => '文件(%s)没有写入权限',
'Are you sure you want to unstall %s?' => '确认卸载<b>《%s》</b>?',
'Are you sure you want to refresh authorization?' => '确认刷新应用插件授权?',
'Delete all the addon file and cannot be recovered!' => '卸载将会删除所有插件文件且不可找回!!!',
'Delete all the addon database and cannot be recovered!' => '删除所有插件相关数据表且不可找回!!!',
'Please backup important data manually before uninstall!' => '如有重要数据请备份后再操作!!!',

View File

@ -74,6 +74,7 @@ return [
'Name already exist' => '变量名称已经存在',
'Add new config' => '点击添加新的配置',
'Send a test message' => '发送测试邮件',
'Only work at development environment' => '只允许在开发环境开操作',
'This is a test mail content' => '这是一封来自%s的校验邮件,用于校验邮件配置是否正常!',
'This is a test mail' => '这是一封来自%s的邮件',
'Please input your email' => '请输入测试接收者邮箱',

View File

@ -8,14 +8,18 @@ return [
'You can\'t use fixed and boxed layouts together' => '盒子模型和固定布局不能同时启作用',
'Boxed Layout' => '盒子布局',
'Activate the boxed layout' => '盒子布局最大宽度将被限定为1250px',
'Toggle Sidebar' => '切换菜单栏',
'Toggle the left sidebar\'s state (open or collapse)' => '切换菜单栏的展或收起',
'Toggle Sidebar' => '收起菜单栏',
'Toggle the left sidebar\'s state (open or collapse)' => '切换菜单栏的展或收起',
'Sidebar Expand on Hover' => '菜单栏自动展开',
'Let the sidebar mini expand on hover' => '鼠标移到菜单栏自动展开',
'Toggle Right Sidebar Slide' => '切换右侧操作栏',
'Toggle between slide over content and push content effects' => '切换右侧操作栏覆盖或独占',
'Toggle Right Sidebar Skin' => '切换右侧操作栏背景',
'Toggle between dark and light skins for the right sidebar' => '将右侧操作栏背景亮色或深色切换',
'Multiple nav' => '多级菜单导航',
'Toggle the top menu state (multiple or single)' => '切换顶部菜单为多级菜单导航模式',
'Multiple tab' => '多选项卡',
'Always show multiple tab when multiple nav is set' => '当配置为多级菜单导航时是否启用多选项卡',
'Show sub menu' => '显示菜单栏子菜单',
'Always show sub menu' => '菜单栏子菜单将始终显示',
'Disable top menu badge' => '禁用顶部彩色小角标',

View File

@ -16,7 +16,7 @@ class AuthRule extends Validate
* 验证规则
*/
protected $rule = [
'name' => 'require|format|unique:AuthRule',
'name' => 'require|unique:AuthRule',
'title' => 'require',
];

View File

@ -111,7 +111,7 @@
<div class="form-group layer-footer">
<label class="control-label col-xs-12 col-sm-2"></label>
<div class="col-xs-12 col-sm-8">
<button type="submit" class="btn btn-success btn-embossed disabled">{:__('OK')}</button>
<button type="submit" class="btn btn-primary btn-embossed disabled">{:__('OK')}</button>
<button type="reset" class="btn btn-default btn-embossed">{:__('Reset')}</button>
</div>
</div>

View File

@ -61,6 +61,7 @@
.btn-toggle {
padding: 0;
}
</style>
<div class="panel panel-default panel-intro">
<div class="panel-heading">
@ -80,9 +81,11 @@
<div id="toolbar" class="toolbar">
<a href="javascript:;" class="btn btn-primary btn-refresh" title="{:__('Refresh')}" data-force-refresh="false"><i class="fa fa-refresh"></i> </a>
{if $Think.config.fastadmin.api_url}
{if $Think.config.app_debug}
<button type="button" id="faupload-addon" class="btn btn-danger faupload btn-mini-xs" data-url="addon/local" data-chunking="false" data-mimetype="zip,fastaddon" data-multiple="false"><i class="fa fa-upload"></i>
{:__('Offline install')}
{:__('Local install')}
</button>
{/if}
<div class="btn-group">
<a href="#" class="btn btn-info btn-switch active btn-mini-xs" data-type="all"><i class="fa fa-list"></i> {:__('All')}</a>
<a href="#" class="btn btn-info btn-switch btn-mini-xs" data-type="free"><i class="fa fa-gift"></i> {:__('Free')}</a>
@ -90,6 +93,7 @@
<a href="#" class="btn btn-info btn-switch btn-mini-xs" data-type="local" data-url="addon/downloaded"><i class="fa fa-laptop"></i> {:__('Local addon')}</a>
</div>
<a class="btn btn-primary btn-userinfo btn-mini-xs" href="javascript:;"><i class="fa fa-user"></i> {:__('Userinfo')}</a>
<a class="btn btn-warning btn-authorization btn-mini-xs" href="javascript:;"><i class="fa fa-cloud"></i> {:__('Reload authorization')}</a>
{/if}
</div>
<table id="table" class="table table-striped table-bordered table-hover" width="100%">
@ -190,22 +194,10 @@
<strong>{:__('Warning')}</strong><br/>{:__('Logined tips', '<%=username%>')}
</div>
</fieldset>
<div class="breadcrumb"><a href="https://www.fastadmin.net/user/myaddon.html" target="_blank"><i class="fa fa-money"></i> {:__('My addons')}</a></div>
<div class="breadcrumb"><a href="https://www.fastadmin.net/user/myaddon.html" target="_blank"><i class="fa fa-cube"></i> {:__('My addons')}</a></div>
</form>
</div>
</script>
<script id="paytpl" type="text/html">
<div class="payimg" style="background:url('<%=payimg%>') 0 0 no-repeat;background-size:cover;">
<%if(paycode){%>
<div class="alipaycode">
<%=paycode%>
</div>
<div class="wechatcode">
<%=paycode%>
</div>
<%}%>
</div>
</script>
<script id="uninstalltpl" type="text/html">
<div class="">
<div class=""><%=#__("Are you sure you want to unstall %s?", addon['title'])%>
@ -245,7 +237,7 @@
<% var label = labelarr[item.id % 5]; %>
<% var addon = item.addon; %>
<div class="operate" data-id="<%=item.id%>" data-name="<%=item.name%>">
<span class="operate" data-id="<%=item.id%>" data-name="<%=item.name%>">
<% if(!addon){ %>
<% if(typeof item.releaselist !="undefined" && item.releaselist.length>1){%>
<span class="btn-group">
@ -309,6 +301,6 @@
<a href="javascript:;" class="btn btn-xs btn-danger btn-uninstall" title="{:__('Uninstall')}"><i class="fa fa-times"></i>
{:__('Uninstall')}</a>
<% } %>
</div>
</span>
</script>
<!--@formatter:on-->

View File

@ -39,7 +39,7 @@
<div class="form-group hidden layer-footer">
<label class="control-label col-xs-12 col-sm-2"></label>
<div class="col-xs-12 col-sm-8">
<button type="submit" class="btn btn-success btn-embossed disabled">{:__('OK')}</button>
<button type="submit" class="btn btn-primary btn-embossed disabled">{:__('OK')}</button>
<button type="reset" class="btn btn-default btn-embossed">{:__('Reset')}</button>
</div>
</div>

View File

@ -45,7 +45,7 @@
<div class="form-group hidden layer-footer">
<label class="control-label col-xs-12 col-sm-2"></label>
<div class="col-xs-12 col-sm-8">
<button type="submit" class="btn btn-success btn-embossed disabled">{:__('OK')}</button>
<button type="submit" class="btn btn-primary btn-embossed disabled">{:__('OK')}</button>
<button type="reset" class="btn btn-default btn-embossed">{:__('Reset')}</button>
</div>
</div>

View File

@ -31,7 +31,7 @@
<div class="form-group hidden layer-footer">
<label class="control-label col-xs-12 col-sm-2"></label>
<div class="col-xs-12 col-sm-8">
<button type="submit" class="btn btn-success btn-embossed disabled">{:__('OK')}</button>
<button type="submit" class="btn btn-primary btn-embossed disabled">{:__('OK')}</button>
<button type="reset" class="btn btn-default btn-embossed">{:__('Reset')}</button>
</div>
</div>

View File

@ -31,7 +31,7 @@
<div class="form-group hidden layer-footer">
<label class="control-label col-xs-12 col-sm-2 col-xs-2"></label>
<div class="col-xs-12 col-sm-8">
<button type="submit" class="btn btn-success btn-embossed disabled">{:__('OK')}</button>
<button type="submit" class="btn btn-primary btn-embossed disabled">{:__('OK')}</button>
<button type="reset" class="btn btn-default btn-embossed">{:__('Reset')}</button>
</div>
</div>

View File

@ -34,17 +34,12 @@
<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">
<span class="input-group-addon"><i class="fa fa-circle-o" id="icon-style"></i></span>
<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>
</div>
<div class="form-group">
<label for="weigh" class="control-label col-xs-12 col-sm-2">{:__('Weigh')}:</label>
<div class="col-xs-12 col-sm-8">
<input type="text" class="form-control" id="weigh" name="row[weigh]" value="0" data-rule="required" />
</div>
</div>
<div class="form-group">
<label for="remark" class="control-label col-xs-12 col-sm-2">{:__('Condition')}:</label>
<div class="col-xs-12 col-sm-8">
@ -69,6 +64,12 @@
<textarea class="form-control" id="remark" name="row[remark]"></textarea>
</div>
</div>
<div class="form-group">
<label for="weigh" class="control-label col-xs-12 col-sm-2">{:__('Weigh')}:</label>
<div class="col-xs-12 col-sm-8">
<input type="text" class="form-control" id="weigh" name="row[weigh]" value="0" data-rule="required" />
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Status')}:</label>
<div class="col-xs-12 col-sm-8">
@ -78,7 +79,7 @@
<div class="form-group hidden layer-footer">
<div class="col-xs-2"></div>
<div class="col-xs-12 col-sm-8">
<button type="submit" class="btn btn-success btn-embossed disabled">{:__('OK')}</button>
<button type="submit" class="btn btn-primary btn-embossed disabled">{:__('OK')}</button>
<button type="reset" class="btn btn-default btn-embossed">{:__('Reset')}</button>
</div>
</div>

View File

@ -34,17 +34,12 @@
<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">
<span class="input-group-addon"><i class="{$row.icon}" id="icon-style"></i></span>
<input type="text" class="form-control" id="icon" name="row[icon]" value="{$row.icon}" />
<a href="javascript:;" class="btn-search-icon input-group-addon">{:__('Search icon')}</a>
</div>
</div>
</div>
<div class="form-group">
<label for="weigh" class="control-label col-xs-12 col-sm-2">{:__('Weigh')}:</label>
<div class="col-xs-12 col-sm-8">
<input type="text" class="form-control" id="weigh" name="row[weigh]" value="{$row.weigh}" data-rule="required" />
</div>
</div>
<div class="form-group">
<label for="remark" class="control-label col-xs-12 col-sm-2">{:__('Condition')}:</label>
<div class="col-xs-12 col-sm-8">
@ -66,7 +61,13 @@
<div class="form-group">
<label for="remark" class="control-label col-xs-12 col-sm-2">{:__('Remark')}:</label>
<div class="col-xs-12 col-sm-8">
<textarea class="form-control" id="remark" name="row[remark]">{$row.remark|htmlentities}</textarea>
<textarea class="form-control" id="remark" name="row[remark]">{$row.remark|__|htmlentities}</textarea>
</div>
</div>
<div class="form-group">
<label for="weigh" class="control-label col-xs-12 col-sm-2">{:__('Weigh')}:</label>
<div class="col-xs-12 col-sm-8">
<input type="text" class="form-control" id="weigh" name="row[weigh]" value="{$row.weigh}" data-rule="required" />
</div>
</div>
<div class="form-group">
@ -78,7 +79,7 @@
<div class="form-group hidden layer-footer">
<div class="col-xs-2"></div>
<div class="col-xs-12 col-sm-8">
<button type="submit" class="btn btn-success btn-embossed disabled">{:__('OK')}</button>
<button type="submit" class="btn btn-primary btn-embossed disabled">{:__('OK')}</button>
<button type="reset" class="btn btn-default btn-embossed">{:__('Reset')}</button>
</div>
</div>

View File

@ -93,7 +93,7 @@
<div class="form-group layer-footer">
<label class="control-label col-xs-12 col-sm-2"></label>
<div class="col-xs-12 col-sm-8">
<button type="submit" class="btn btn-success btn-embossed disabled">{:__('OK')}</button>
<button type="submit" class="btn btn-primary btn-embossed disabled">{:__('OK')}</button>
<button type="reset" class="btn btn-default btn-embossed">{:__('Reset')}</button>
</div>
</div>

View File

@ -89,7 +89,7 @@
<div class="form-group layer-footer">
<label class="control-label col-xs-12 col-sm-2"></label>
<div class="col-xs-12 col-sm-8">
<button type="submit" class="btn btn-success btn-embossed disabled">{:__('OK')}</button>
<button type="submit" class="btn btn-primary btn-embossed disabled">{:__('OK')}</button>
<button type="reset" class="btn btn-default btn-embossed">{:__('Reset')}</button>
</div>
</div>

View File

@ -9,6 +9,13 @@
display: block;
float:left;
}
.skin-list li.active a {
opacity: 1;
filter: alpha(opacity=100);
}
.skin-list li.active p {
color: #fff;
}
</style>
<!-- Control Sidebar -->
<aside class="control-sidebar control-sidebar-dark">
@ -23,8 +30,8 @@
<!-- Home tab content -->
<div class="tab-pane active" id="control-sidebar-setting-tab">
<h4 class="control-sidebar-heading">{:__('Layout Options')}</h4>
<div class="form-group"><label class="control-sidebar-subheading"><input type="checkbox" data-layout="fixed" class="pull-right"> {:__('Fixed Layout')}</label><p>{:__("You can't use fixed and boxed layouts together")}</p></div>
<div class="form-group"><label class="control-sidebar-subheading"><input type="checkbox" data-layout="layout-boxed" class="pull-right"> {:__('Boxed Layout')}</label><p>{:__('Activate the boxed layout')}</p></div>
<div class="form-group"><label class="control-sidebar-subheading"><input type="checkbox" data-config="multiplenav" {if $Think.config.fastadmin.multiplenav}checked{/if} class="pull-right"> {:__('Multiple Nav')}</label><p>{:__("Toggle the top menu state (multiple or single)")}</p></div>
<div class="form-group"><label class="control-sidebar-subheading"><input type="checkbox" data-config="multipletab" {if $Think.config.fastadmin.multipletab}checked{/if} class="pull-right"> {:__('Multiple Tab')}</label><p>{:__("Always show multiple tab when multiple nav is set")}</p></div>
<div class="form-group"><label class="control-sidebar-subheading"><input type="checkbox" data-layout="sidebar-collapse" class="pull-right"> {:__('Toggle Sidebar')}</label><p>{:__("Toggle the left sidebar's state (open or collapse)")}</p></div>
<div class="form-group"><label class="control-sidebar-subheading"><input type="checkbox" data-enable="expandOnHover" class="pull-right"> {:__('Sidebar Expand on Hover')}</label><p>{:__('Let the sidebar mini expand on hover')}</p></div>
<div class="form-group"><label class="control-sidebar-subheading"><input type="checkbox" data-menu="show-submenu" class="pull-right"> {:__('Show sub menu')}</label><p>{:__('Always show sub menu')}</p></div>

View File

@ -30,7 +30,7 @@
</div>
<!--如果想始终显示子菜单,则给ul加上show-submenu类即可,当multiplenav开启的情况下默认为展开-->
<ul class="sidebar-menu {if $Think.config.fastadmin.multiplenav}show-submenu{/if}">
<ul class="sidebar-menu {if $Think.config.fastadmin.multiplenav||$Think.cookie.show_submenu}show-submenu{/if}">
<!-- 菜单可以在 后台管理->权限管理->菜单规则 中进行增删改排序 -->
{$menulist}

View File

@ -6,8 +6,6 @@
-moz-border-radius: 3px;
border-radius: 3px;
margin-bottom: 20px;
-webkit-box-shadow: 0 1px 0px rgba(0, 0, 0, 0.05);
box-shadow: 0 1px 0px rgba(0, 0, 0, 0.05);
}
.sm-st-icon {
@ -27,7 +25,6 @@
}
.sm-st-info {
font-size: 12px;
padding-top: 2px;
}
@ -125,6 +122,7 @@
.stat .name {
overflow: hidden;
text-overflow: ellipsis;
margin: 5px 0;
}
.stat.lg .value {
@ -132,6 +130,9 @@
line-height: 28px;
}
.stat-col {
margin:0 0 10px 0;
}
.stat.lg .name {
font-size: 16px;
}
@ -155,7 +156,7 @@
}
#statistics .panel h5 {
font-size: 13px;
font-size: 14px;
}
</style>
<div class="panel panel-default panel-intro">
@ -211,7 +212,7 @@
<div class="row">
<div class="col-lg-8">
<div id="echart" class="btn-refresh" style="height:200px;width:100%;"></div>
<div id="echart" class="btn-refresh" style="height:300px;width:100%;"></div>
</div>
<div class="col-lg-4">
<div class="card sameheight-item stats">
@ -224,7 +225,7 @@
<div class="name"> {:__('Today user signup')}</div>
</div>
<div class="progress">
<div class="progress-bar progress-bar-success" style="width: 30%"></div>
<div class="progress-bar progress-bar-success" style="width: 20%"></div>
</div>
</div>
<div class="col-xs-6 stat-col">
@ -234,7 +235,7 @@
<div class="name"> {:__('Today user login')}</div>
</div>
<div class="progress">
<div class="progress-bar progress-bar-success" style="width: 25%"></div>
<div class="progress-bar progress-bar-success" style="width: 20%"></div>
</div>
</div>
<div class="col-xs-6 stat-col">
@ -244,7 +245,7 @@
<div class="name"> {:__('Three dnu')}</div>
</div>
<div class="progress">
<div class="progress-bar progress-bar-success" style="width: 25%"></div>
<div class="progress-bar progress-bar-success" style="width: 20%"></div>
</div>
</div>
<div class="col-xs-6 stat-col">
@ -254,7 +255,7 @@
<div class="name"> {:__('Seven dnu')}</div>
</div>
<div class="progress">
<div class="progress-bar progress-bar-success" style="width: 25%"></div>
<div class="progress-bar progress-bar-success" style="width: 20%"></div>
</div>
</div>
<div class="col-xs-6 stat-col">
@ -264,7 +265,7 @@
<div class="name"> {:__('Seven dau')}</div>
</div>
<div class="progress">
<div class="progress-bar progress-bar-success" style="width: 25%"></div>
<div class="progress-bar progress-bar-success" style="width: 20%"></div>
</div>
</div>
<div class="col-xs-6 stat-col">
@ -274,7 +275,7 @@
<div class="name"> {:__('Thirty dau')}</div>
</div>
<div class="progress">
<div class="progress-bar progress-bar-success" style="width: 25%"></div>
<div class="progress-bar progress-bar-success" style="width: 20%"></div>
</div>
</div>
</div>
@ -308,7 +309,7 @@
</div>
</div>
<div class="col-xs-6 col-md-3">
<div class="panel bg-aqua-gradient no-border">
<div class="panel bg-teal-gradient no-border">
<div class="panel-body">
<div class="ibox-title">
<span class="label label-primary pull-right">{:__('Real time')}</span>

View File

@ -3,16 +3,25 @@
<div class="form-group">
<label for="c-third" class="control-label col-xs-12 col-sm-2">{:__('Upload to third')}:</label>
<div class="col-xs-12 col-sm-8">
<input type="text" name="row[third]" id="c-third" class="form-control" />
<input type="text" name="row[third]" id="c-third" class="form-control"/>
<ul class="row list-inline faupload-preview" id="p-third"></ul>
</div>
</div>
<div class="form-group">
<label for="c-third" class="control-label col-xs-12 col-sm-2"></label>
<div class="col-xs-12 col-sm-8">
<button type="button" id="faupload-third" class="btn btn-danger faupload" data-multiple="true" data-input-id="c-third" ><i class="fa fa-upload"></i> {:__("Upload to third")}</button>
<div style="width:180px;display:inline-block;">
<select name="category-third" id="category-third" class="form-control selectpicker">
<option value="">{:__('Please select category')}</option>
{foreach name="categoryList" id="item"}
<option value="{$key}">{$item}</option>
{/foreach}
</select>
</div>
<button type="button" id="faupload-third" class="btn btn-danger faupload" data-multiple="true" data-input-id="c-third" data-preview-id="p-third"><i class="fa fa-upload"></i> {:__("Upload to third")}</button>
{if $config.upload.chunking}
<button type="button" id="faupload-third-chunking" class="btn btn-danger faupload" data-chunking="true" data-maxsize="1gb" data-multiple="true" data-input-id="c-third" ><i class="fa fa-upload"></i> {:__("Upload to third by chunk")}</button>
<button type="button" id="faupload-third-chunking" class="btn btn-danger faupload" data-chunking="true" data-maxsize="1gb" data-multiple="true" data-input-id="c-third" data-preview-id="p-third"><i class="fa fa-upload"></i> {:__("Upload to third by chunk")}</button>
{/if}
</div>
</div>
@ -21,27 +30,29 @@
<div class="form-group">
<label for="c-local" class="control-label col-xs-12 col-sm-2">{:__('Upload to local')}:</label>
<div class="col-xs-12 col-sm-8">
<input type="text" name="row[local]" id="c-local" class="form-control" />
<input type="text" name="row[local]" id="c-local" class="form-control"/>
<ul class="row list-inline faupload-preview" id="p-local"></ul>
</div>
</div>
<div class="form-group">
<label for="c-local" class="control-label col-xs-12 col-sm-2"></label>
<div class="col-xs-12 col-sm-8">
<button type="button" id="faupload-local" class="btn btn-primary faupload" data-input-id="c-local" data-url="{:url('ajax/upload')}"><i class="fa fa-upload"></i> {:__("Upload to local")}</button>
<div style="width:180px;display:inline-block;">
<select name="category-local" id="category-local" class="form-control selectpicker">
<option value="">{:__('Please select category')}</option>
{foreach name="categoryList" id="item"}
<option value="{$key}">{$item}</option>
{/foreach}
</select>
</div>
<button type="button" id="faupload-local" class="btn btn-primary faupload" data-input-id="c-local" data-multiple="true" data-preview-id="p-local" data-url="{:url('ajax/upload')}"><i class="fa fa-upload"></i> {:__("Upload to local")}</button>
{if $config.upload.chunking}
<button type="button" id="faupload-local-chunking" class="btn btn-primary faupload" data-chunking="true" data-maxsize="1gb" data-input-id="c-local" data-url="{:url('ajax/upload')}"><i class="fa fa-upload"></i> {:__("Upload to local by chunk")}</button>
<button type="button" id="faupload-local-chunking" class="btn btn-primary faupload" data-chunking="true" data-maxsize="1gb" data-input-id="c-local" data-multiple="true" data-preview-id="p-local" data-url="{:url('ajax/upload')}"><i class="fa fa-upload"></i> {:__("Upload to local by chunk")}</button>
{/if}
</div>
</div>
<div class="form-group">
<label for="c-editor" class="control-label col-xs-12 col-sm-2">{:__('Upload from editor')}:</label>
<div class="col-xs-12 col-sm-8">
<textarea name="row[editor]" id="c-editor" cols="60" rows="5" class="form-control editor"></textarea>
</div>
</div>
<div class="form-group hidden layer-footer">
<div class="col-xs-2"></div>
<div class="col-xs-12 col-sm-8">

View File

@ -82,7 +82,7 @@
<div class="form-group hide layer-footer">
<label class="control-label col-xs-12 col-sm-2"></label>
<div class="col-xs-12 col-sm-8">
<button type="submit" class="btn btn-success btn-embossed disabled">{:__('OK')}</button>
<button type="submit" class="btn btn-primary btn-embossed disabled">{:__('OK')}</button>
<button type="reset" class="btn btn-default btn-embossed">{:__('Reset')}</button>
</div>
</div>

View File

@ -25,6 +25,7 @@
.edit-form table tr th:nth-last-child(-n + 2), .edit-form table tr td:nth-last-child(-n + 2) {
display: none;
}
.edit-form table tr td .msg-box {
display: none;
}
@ -37,9 +38,11 @@
{foreach $siteList as $index=>$vo}
<li class="{$vo.active?'active':''}"><a href="#{$vo.name}" data-toggle="tab">{:__($vo.title)}</a></li>
{/foreach}
{if $Think.config.app_debug}
<li data-toggle="tooltip" title="{:__('Add new config')}">
<a href="#addcfg" data-toggle="tab"><i class="fa fa-plus"></i></a>
</li>
{/if}
</ul>
</div>
@ -56,8 +59,10 @@
<tr>
<th width="15%">{:__('Title')}</th>
<th width="68%">{:__('Value')}</th>
{if $Think.config.app_debug}
<th width="15%">{:__('Name')}</th>
<th width="2%"></th>
{/if}
</tr>
</thead>
<tbody>
@ -174,8 +179,10 @@
</div>
</td>
{if $Think.config.app_debug}
<td>{php}echo "{\$site.". $item['name'] . "}";{/php}</td>
<td>{if $item['id']>17}<a href="javascript:;" class="btn-delcfg text-muted" data-name="{$item.name}"><i class="fa fa-times"></i></a>{/if}</td>
<td>{if $item['id']>18}<a href="javascript:;" class="btn-delcfg text-muted" data-name="{$item.name}"><i class="fa fa-times"></i></a>{/if}</td>
{/if}
</tr>
{/foreach}
</tbody>
@ -183,11 +190,15 @@
<tr>
<td></td>
<td>
<button type="submit" class="btn btn-success btn-embossed">{:__('OK')}</button>
<div class="layer-footer">
<button type="submit" class="btn btn-primary btn-embossed disabled">{:__('OK')}</button>
<button type="reset" class="btn btn-default btn-embossed">{:__('Reset')}</button>
</div>
</td>
{if $Think.config.app_debug}
<td></td>
<td></td>
{/if}
</tr>
</tfoot>
</table>
@ -321,8 +332,12 @@ value2|title2</textarea>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2"></label>
<div class="col-xs-12 col-sm-4">
<button type="submit" class="btn btn-success btn-embossed">{:__('OK')}</button>
{if !$Think.config.app_debug}
<button type="button" class="btn btn-primary disabled">{:__('Only work at development environment')}</button>
{else/}
<button type="submit" class="btn btn-primary btn-embossed">{:__('OK')}</button>
<button type="reset" class="btn btn-default btn-embossed">{:__('Reset')}</button>
{/if}
</div>
</div>

View File

@ -4,7 +4,7 @@
<!-- 加载样式及META信息 -->
{include file="common/meta" /}
</head>
<body class="hold-transition {$Think.config.fastadmin.adminskin|default='skin-black-green'} sidebar-mini fixed {:$Think.config.fastadmin.multipletab?'multipletab':''} {:$Think.config.fastadmin.multiplenav?'multiplenav':''}" id="tabs">
<body class="hold-transition {$Think.config.fastadmin.adminskin|default='skin-black-green'} sidebar-mini {:$Think.cookie.sidebar_collapse?'sidebar-collapse':''} fixed {:$Think.config.fastadmin.multipletab?'multipletab':''} {:$Think.config.fastadmin.multiplenav?'multiplenav':''}" id="tabs">
<div class="wrapper">

View File

@ -31,7 +31,7 @@
<div class="form-group layer-footer">
<label class="control-label col-xs-12 col-sm-2"></label>
<div class="col-xs-12 col-sm-8">
<button type="submit" class="btn btn-success btn-embossed disabled">{:__('OK')}</button>
<button type="submit" class="btn btn-primary btn-embossed disabled">{:__('OK')}</button>
<button type="reset" class="btn btn-default btn-embossed">{:__('Reset')}</button>
</div>
</div>

View File

@ -31,7 +31,7 @@
<div class="form-group layer-footer">
<label class="control-label col-xs-12 col-sm-2"></label>
<div class="col-xs-12 col-sm-8">
<button type="submit" class="btn btn-success btn-embossed disabled">{:__('OK')}</button>
<button type="submit" class="btn btn-primary btn-embossed disabled">{:__('OK')}</button>
<button type="reset" class="btn btn-default btn-embossed">{:__('Reset')}</button>
</div>
</div>

View File

@ -46,7 +46,7 @@
<div class="form-group layer-footer">
<label class="control-label col-xs-12 col-sm-2"></label>
<div class="col-xs-12 col-sm-8">
<button type="submit" class="btn btn-success btn-embossed disabled">{:__('OK')}</button>
<button type="submit" class="btn btn-primary btn-embossed disabled">{:__('OK')}</button>
<button type="reset" class="btn btn-default btn-embossed">{:__('Reset')}</button>
</div>
</div>

View File

@ -45,7 +45,7 @@
<div class="form-group layer-footer">
<label class="control-label col-xs-12 col-sm-2"></label>
<div class="col-xs-12 col-sm-8">
<button type="submit" class="btn btn-success btn-embossed disabled">{:__('OK')}</button>
<button type="submit" class="btn btn-primary btn-embossed disabled">{:__('OK')}</button>
<button type="reset" class="btn btn-default btn-embossed">{:__('Reset')}</button>
</div>
</div>

View File

@ -144,7 +144,7 @@
<div class="form-group layer-footer">
<label class="control-label col-xs-12 col-sm-2"></label>
<div class="col-xs-12 col-sm-8">
<button type="submit" class="btn btn-success btn-embossed disabled">{:__('OK')}</button>
<button type="submit" class="btn btn-primary btn-embossed disabled">{:__('OK')}</button>
<button type="reset" class="btn btn-default btn-embossed">{:__('Reset')}</button>
</div>
</div>

View File

@ -258,7 +258,8 @@ if (!function_exists('addtion')) {
if (isset($v[$n])) {
$curr = array_flip(explode(',', $v[$n]));
$v[$fieldsArr[$n]['display']] = implode(',', array_intersect_key($result[$n], $curr));
$linedata = array_intersect_key($result[$n], $curr);
$v[$fieldsArr[$n]['display']] = $fieldsArr[$n]['column'] == '*' ? $linedata : implode(',', $linedata);
}
}
}
@ -481,3 +482,33 @@ if (!function_exists('check_ip_allowed')) {
}
}
}
if (!function_exists('build_suffix_image')) {
/**
* 生成文件后缀图片
* @param string $suffix 后缀
* @param null $background
* @return string
*/
function build_suffix_image($suffix, $background = null)
{
$suffix = mb_substr(strtoupper($suffix), 0, 4);
$total = unpack('L', hash('adler32', $suffix, true))[1];
$hue = $total % 360;
list($r, $g, $b) = hsv2rgb($hue / 360, 0.3, 0.9);
$background = $background ? $background : "rgb({$r},{$g},{$b})";
$icon = <<<EOT
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
<path style="fill:#E2E5E7;" d="M128,0c-17.6,0-32,14.4-32,32v448c0,17.6,14.4,32,32,32h320c17.6,0,32-14.4,32-32V128L352,0H128z"/>
<path style="fill:#B0B7BD;" d="M384,128h96L352,0v96C352,113.6,366.4,128,384,128z"/>
<polygon style="fill:#CAD1D8;" points="480,224 384,128 480,128 "/>
<path style="fill:{$background};" d="M416,416c0,8.8-7.2,16-16,16H48c-8.8,0-16-7.2-16-16V256c0-8.8,7.2-16,16-16h352c8.8,0,16,7.2,16,16 V416z"/>
<path style="fill:#CAD1D8;" d="M400,432H96v16h304c8.8,0,16-7.2,16-16v-16C416,424.8,408.8,432,400,432z"/>
<g><text><tspan x="220" y="380" font-size="124" font-family="Verdana, Helvetica, Arial, sans-serif" fill="white" text-anchor="middle">{$suffix}</tspan></text></g>
</svg>
EOT;
return $icon;
}
}

View File

@ -227,9 +227,7 @@ class Auth
}
//直接登录会员
$this->direct($user->id);
return true;
return $this->direct($user->id);
}
/**
@ -558,7 +556,7 @@ class Auth
/**
* 设置错误信息
*
* @param $error 错误信息
* @param string $error 错误信息
* @return Auth
*/
public function setError($error)

View File

@ -18,7 +18,7 @@ class Email
/**
* phpmailer对象
*/
protected $mail = [];
protected $mail = null;
/**
* 错误内容
@ -122,7 +122,7 @@ class Email
$emailArr[key($emailArr)] = $name;
}
foreach ($emailArr as $address => $name) {
$this->mail->addCC($address, $name);
$this->mail->addCC($name, $address);
}
return $this;
}

View File

@ -82,6 +82,7 @@ class Token
* 判断Token是否可用(check别名)
* @access public
* @param string $token Token标识
* @param int $user_id 会员ID
* @return bool
*/
public static function has($token, $user_id)
@ -92,6 +93,7 @@ class Token
/**
* 判断Token是否可用
* @param string $token Token标识
* @param int $user_id 会员ID
* @return bool
*/
public static function check($token, $user_id)
@ -115,7 +117,7 @@ class Token
* 写入Token
* @access public
* @param string $token Token标识
* @param mixed $user_id 存储数据
* @param mixed $user_id 会员ID
* @param int|null $expire 有效时间 0为永久
* @return boolean
*/
@ -148,7 +150,7 @@ class Token
/**
* 清除Token
* @access public
* @param int user_id 用户编号
* @param int user_id 会员ID
* @return boolean
*/
public static function clear($user_id = null)

View File

@ -16,18 +16,6 @@ use think\Hook;
class Upload
{
/**
* 验证码有效时长
* @var int
*/
protected static $expire = 120;
/**
* 最大允许检测的次数
* @var int
*/
protected static $maxCheckNums = 10;
protected $merging = false;
protected $chunkDir = null;
@ -37,7 +25,7 @@ class Upload
protected $error = '';
/**
* @var \think\File
* @var File
*/
protected $file = null;
protected $fileInfo = null;
@ -51,16 +39,29 @@ class Upload
}
}
/**
* 设置分片目录
* @param $dir
*/
public function setChunkDir($dir)
{
$this->chunkDir = $dir;
}
/**
* 获取文件
* @return File
*/
public function getFile()
{
return $this->file;
}
/**
* 设置文件
* @param $file
* @throws UploadException
*/
public function setFile($file)
{
if (empty($file)) {
@ -79,6 +80,11 @@ class Upload
$this->checkExecutable();
}
/**
* 检测是否为可执行脚本
* @return bool
* @throws UploadException
*/
protected function checkExecutable()
{
//禁止上传PHP和HTML文件
@ -88,6 +94,11 @@ class Upload
return true;
}
/**
* 检测文件类型
* @return bool
* @throws UploadException
*/
protected function checkMimetype()
{
$mimetypeArr = explode(',', strtolower($this->config['mimetype']));
@ -105,6 +116,12 @@ class Upload
throw new UploadException(__('Uploaded file format is limited'));
}
/**
* 检测是否图片
* @param bool $force
* @return bool
* @throws UploadException
*/
protected function checkImage($force = false)
{
//验证是否为图片文件
@ -121,6 +138,10 @@ class Upload
}
}
/**
* 检测文件大小
* @throws UploadException
*/
protected function checkSize()
{
preg_match('/([0-9\.]+)(\w+)/', $this->config['maxsize'], $matches);
@ -135,11 +156,22 @@ class Upload
}
}
/**
* 获取后缀
* @return string
*/
public function getSuffix()
{
return $this->fileInfo['suffix'] ?: 'file';
}
/**
* 获取存储的文件名
* @param string $savekey
* @param string $filename
* @param string $md5
* @return mixed|null
*/
public function getSavekey($savekey = null, $filename = null, $md5 = null)
{
if ($filename) {
@ -384,11 +416,19 @@ class Upload
return $attachment;
}
/**
* 设置错误信息
* @param $msg
*/
public function setError($msg)
{
$this->error = $msg;
}
/**
* 获取错误信息
* @return string
*/
public function getError()
{
return $this->error;

View File

@ -65,6 +65,10 @@ class Attachment extends Model
return '';
}
/**
* 获取Mimetype列表
* @return array
*/
public static function getMimetypeList()
{
$data = [

View File

@ -175,6 +175,8 @@ class Config extends Model
if (!preg_match("/^((?:[a-z]+:)?\/\/)(.*)/i", $uploadurl) && substr($uploadurl, 0, 1) !== '/') {
$uploadurl = url($uploadurl, '', false);
}
$uploadcfg['fullmode'] = isset($uploadcfg['fullmode']) && $uploadcfg['fullmode'] ? true : false;
$uploadcfg['thumbstyle'] = $uploadcfg['thumbstyle'] ?? '';
$upload = [
'cdnurl' => $uploadcfg['cdnurl'],
@ -187,6 +189,8 @@ class Config extends Model
'savekey' => $uploadcfg['savekey'],
'multipart' => [],
'multiple' => $uploadcfg['multiple'],
'fullmode' => $uploadcfg['fullmode'],
'thumbstyle' => $uploadcfg['thumbstyle'],
'storage' => 'local'
];
return $upload;

View File

@ -7,7 +7,7 @@
<link rel="shortcut icon" href="__CDN__/assets/img/favicon.ico" />
<style type="text/css">
*{box-sizing:border-box;margin:0;padding:0;font-family:Lantinghei SC,Open Sans,Arial,Hiragino Sans GB,Microsoft YaHei,"微软雅黑",STHeiti,WenQuanYi Micro Hei,SimSun,sans-serif;-webkit-font-smoothing:antialiased}
body{padding:70px 50px;background:#edf1f4;font-weight:400;font-size:1pc;-webkit-text-size-adjust:none;color:#333}
body{padding:70px 50px;background:#f4f6f8;font-weight:400;font-size:1pc;-webkit-text-size-adjust:none;color:#333}
a{outline:0;color:#3498db;text-decoration:none;cursor:pointer}
.system-message{margin:20px auto;padding:50px 0px;background:#fff;box-shadow:0 0 30px hsla(0,0%,39%,.06);text-align:center;width:100%;border-radius:2px;}
.system-message h1{margin:0;margin-bottom:9pt;color:#444;font-weight:400;font-size:30px}

View File

@ -39,7 +39,7 @@ $langSet == 'en' && $lang = array_combine(array_keys($lang), array_keys($lang));
article,aside,details,figcaption,figure,footer,header,hgroup,nav,section {display:block;}
html {font-size:16px;line-height:24px;width:100%;height:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%;overflow-y:scroll;overflow-x:hidden;}
img {vertical-align:middle;max-width:100%;height:auto;border:0;-ms-interpolation-mode:bicubic;}
body {min-height:100%;background:#edf1f4;text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-family:"Helvetica Neue",Helvetica,"PingFang SC","Hiragino Sans GB","Microsoft YaHei",,Arial,sans-serif;}
body {min-height:100%;background:#f4f6f8;text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-family:"Helvetica Neue",Helvetica,"PingFang SC","Hiragino Sans GB","Microsoft YaHei",,Arial,sans-serif;}
.clearfix {clear:both;zoom:1;}
.clearfix:before,.clearfix:after {content:"\0020";display:block;height:0;visibility:hidden;}
.clearfix:after {clear:both;}

View File

@ -21,7 +21,7 @@ return [
/**
* 可上传的文件类型
*/
'mimetype' => 'jpg,png,bmp,jpeg,gif,zip,rar,xls,xlsx,wav,mp4,mp3,pdf',
'mimetype' => 'jpg,png,bmp,jpeg,gif,webp,zip,rar,xls,xlsx,wav,mp4,mp3,webm,pdf',
/**
* 是否支持批量上传
*/
@ -34,4 +34,12 @@ return [
* 默认分片大小
*/
'chunksize' => 2097152,
/**
* 完整URL模式
*/
'fullmode' => false,
/**
* 缩略图样式
*/
'thumbstyle' => '',
];

View File

@ -4,6 +4,7 @@ namespace app\index\controller;
use app\common\controller\Frontend;
use think\Lang;
use think\Response;
/**
* Ajax异步请求接口
@ -21,18 +22,35 @@ class Ajax extends Frontend
*/
public function lang()
{
header('Content-Type: application/javascript');
header("Cache-Control: public");
header("Pragma: cache");
$header = ['Content-Type' => 'application/javascript'];
if (!config('app_debug')) {
$offset = 30 * 60 * 60 * 24; // 缓存一个月
header("Expires: " . gmdate("D, d M Y H:i:s", time() + $offset) . " GMT");
$header['Cache-Control'] = 'public';
$header['Pragma'] = 'cache';
$header['Expires'] = gmdate("D, d M Y H:i:s", time() + $offset) . " GMT";
}
$controllername = input("controllername");
$this->loadlang($controllername);
//强制输出JSON Object
$result = jsonp(Lang::get(), 200, [], ['json_encode_param' => JSON_FORCE_OBJECT | JSON_UNESCAPED_UNICODE]);
return $result;
return jsonp(Lang::get(), 200, $header, ['json_encode_param' => JSON_FORCE_OBJECT | JSON_UNESCAPED_UNICODE]);
}
/**
* 生成后缀图标
*/
public function icon()
{
$suffix = $this->request->request("suffix");
$suffix = $suffix ? $suffix : "FILE";
$data = build_suffix_image($suffix);
$header = ['Content-Type' => 'image/svg+xml'];
$offset = 30 * 60 * 60 * 24; // 缓存一个月
$header['Cache-Control'] = 'public';
$header['Pragma'] = 'cache';
$header['Expires'] = gmdate("D, d M Y H:i:s", time() + $offset) . " GMT";
$response = Response::create($data, '', 200, $header);
return $response;
}
/**

View File

@ -301,6 +301,10 @@ class User extends Frontend
$timeArr = explode(' - ', $filterArr['createtime']);
$where['createtime'] = ['between', [strtotime($timeArr[0]), strtotime($timeArr[1])]];
}
$search = $this->request->get('search');
if ($search) {
$where['filename'] = ['like', '%' . $search . '%'];
}
$model = new Attachment();
$offset = $this->request->get("offset", 0);

View File

@ -1,17 +1,17 @@
<!--@formatter:off-->
{if "[type]" == 'email'}
<input type="text" name="captcha" class="form-control input-lg" data-rule="required;length(4);integer[+];remote({:url('api/validate/check_ems_correct')}, event=[event], email:#email)" />
<input type="text" name="captcha" class="form-control" data-rule="required;length(4);integer[+];remote({:url('api/validate/check_ems_correct')}, event=[event], email:#email)" />
<span class="input-group-btn" style="padding:0;border:none;">
<a href="javascript:;" class="btn btn-info btn-captcha btn-lg" data-url="{:url('api/ems/send')}" data-type="email" data-event="[event]">发送验证码</a>
</span>
{elseif "[type]" == 'mobile'/}
<input type="text" name="captcha" class="form-control input-lg" data-rule="required;length(4);integer[+];remote({:url('api/validate/check_sms_correct')}, event=[event], mobile:#mobile)" />
<input type="text" name="captcha" class="form-control" data-rule="required;length(4);integer[+];remote({:url('api/validate/check_sms_correct')}, event=[event], mobile:#mobile)" />
<span class="input-group-btn" style="padding:0;border:none;">
<a href="javascript:;" class="btn btn-info btn-captcha btn-lg" data-url="{:url('api/sms/send')}" data-type="mobile" data-event="[event]">发送验证码</a>
</span>
{elseif "[type]" == 'wechat'/}
{if get_addon_info('wechat')}
<input type="text" name="captcha" class="form-control input-lg" data-rule="required;length(4);remote({:addon_url('wechat/captcha/check')}, event=[event])" />
<input type="text" name="captcha" class="form-control" data-rule="required;length(4);remote({:addon_url('wechat/captcha/check')}, event=[event])" />
<span class="input-group-btn" style="padding:0;border:none;">
<a href="javascript:;" class="btn btn-info btn-captcha btn-lg" data-url="{:addon_url('wechat/captcha/send')}" data-type="wechat" data-event="[event]">获取验证码</a>
</span>
@ -19,9 +19,9 @@
请在后台插件管理中安装《微信管理插件》
{/if}
{elseif "[type]" == 'text' /}
<input type="text" name="captcha" class="form-control input-lg" data-rule="required;length(4)" />
<input type="text" name="captcha" class="form-control" data-rule="required;length(4)" />
<span class="input-group-btn" style="padding:0;border:none;">
<img src="{:captcha_src()}" width="100" height="40" onclick="this.src = '{:captcha_src()}?r=' + Math.random();"/>
<img src="{:captcha_src()}" width="100" height="32" onclick="this.src = '{:captcha_src()}?r=' + Math.random();"/>
</span>
{/if}
<!--@formatter:on-->

View File

@ -7,7 +7,7 @@
<body>
<nav class="navbar navbar-inverse navbar-fixed-top" role="navigation">
<nav class="navbar navbar-white navbar-fixed-top" role="navigation">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#header-navbar">
@ -23,8 +23,9 @@
<li><a href="{:url('/')}">{:__('Home')}</a></li>
<li class="dropdown">
{if $user}
<a href="{:url('user/index')}" class="dropdown-toggle" data-toggle="dropdown" style="padding-top: 10px;height: 50px;">
<a href="{:url('user/index')}" class="dropdown-toggle" data-toggle="dropdown">
<span class="avatar-img"><img src="{$user.avatar|htmlentities|cdnurl}" alt=""></span>
<span class="visible-xs-inline-block" style="padding:5px;">{$user.nickname} <b class="caret"></b></span>
</a>
{else /}
<a href="{:url('user/index')}" class="dropdown-toggle" data-toggle="dropdown">{:__('User center')} <b class="caret"></b></a>
@ -52,7 +53,7 @@
</main>
<footer class="footer" style="clear:both">
<p class="copyright">Copyright&nbsp;©&nbsp;2017-2020 {$site.name|htmlentities} All Rights Reserved <a href="https://beian.miit.gov.cn" target="_blank">{$site.beian|htmlentities}</a></p>
<p class="copyright">Copyright&nbsp;©&nbsp;{:date("Y")} {$site.name|htmlentities} All Rights Reserved <a href="https://beian.miit.gov.cn" target="_blank">{$site.beian|htmlentities}</a></p>
</footer>
{include file="common/script" /}

View File

@ -31,7 +31,7 @@
<div class="form-group normal-footer">
<label class="control-label col-xs-12 col-sm-2"></label>
<div class="col-xs-12 col-sm-8">
<button type="submit" class="btn btn-success btn-embossed disabled">{:__('Submit')}</button>
<button type="submit" class="btn btn-primary btn-embossed disabled">{:__('Submit')}</button>
<button type="reset" class="btn btn-default btn-embossed">{:__('Reset')}</button>
</div>
</div>

View File

@ -21,8 +21,7 @@
<div class="panel-body">
<h2 class="page-header">
{:__('Member center')}
<a href="{:url('user/profile')}" class="btn btn-success pull-right"><i class="fa fa-pencil"></i>
{:__('Profile')}</a>
<a href="{:url('user/profile')}" class="btn btn-primary pull-right"><i class="fa fa-pencil"></i> {:__('Profile')}</a>
</h2>
<div class="row user-baseinfo">
<div class="col-md-3 col-sm-3 col-xs-2 text-center user-center">
@ -36,10 +35,8 @@
<!-- Heading -->
<h4><a href="{:url('user/profile')}">{$user.nickname|htmlentities}</a></h4>
<!-- Paragraph -->
<p>
<a href="{:url('user/profile')}">
<p class="text-muted">
{$user.bio|default=__("This guy hasn't written anything yet")|htmlentities}
</a>
</p>
<!-- Success -->
</div>

View File

@ -8,14 +8,14 @@
<div class="form-group">
<label class="control-label" for="account">{:__('Account')}</label>
<div class="controls">
<input class="form-control input-lg" id="account" type="text" name="account" value="" data-rule="required" placeholder="{:__('Email/Mobile/Username')}" autocomplete="off">
<input class="form-control" id="account" type="text" name="account" value="" data-rule="required" placeholder="{:__('Email/Mobile/Username')}" autocomplete="off">
<div class="help-block"></div>
</div>
</div>
<div class="form-group">
<label class="control-label" for="password">{:__('Password')}</label>
<div class="controls">
<input class="form-control input-lg" id="password" type="password" name="password" data-rule="required;password" placeholder="{:__('Password')}" autocomplete="off">
<input class="form-control" id="password" type="password" name="password" data-rule="required;password" placeholder="{:__('Password')}" autocomplete="off">
</div>
</div>
<div class="form-group">
@ -30,6 +30,7 @@
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary btn-lg btn-block">{:__('Sign in')}</button>
<a href="{:url('user/register')}?url={$url|urlencode|htmlentities}" class="btn btn-default btn-lg btn-block mt-3 no-border">还没有账号?点击注册</a>
</div>
</form>
</div>
@ -68,7 +69,7 @@
<div class="input-group">
<input type="text" name="captcha" class="form-control" data-rule="required;length(4);integer[+];remote({:url('api/validate/check_ems_correct')}, event=resetpwd, email:#email)"/>
<span class="input-group-btn" style="padding:0;border:none;">
<a href="javascript:;" class="btn btn-info btn-captcha" data-url="{:url('api/ems/send')}" data-type="email" data-event="resetpwd">{:__('Send verification code')}</a>
<a href="javascript:;" class="btn btn-primary btn-captcha" data-url="{:url('api/ems/send')}" data-type="email" data-event="resetpwd">{:__('Send verification code')}</a>
</span>
</div>
<span class="msg-box"></span>
@ -85,7 +86,7 @@
<div class="form-group form-footer">
<label class="control-label col-xs-12 col-sm-3"></label>
<div class="col-xs-12 col-sm-8">
<button type="submit" class="btn btn-md btn-info">{:__('Ok')}</button>
<button type="submit" class="btn btn-md btn-primary">{:__('Ok')}</button>
</div>
</div>
</form>

View File

@ -95,7 +95,7 @@
<div class="form-group normal-footer">
<label class="control-label col-xs-12 col-sm-2"></label>
<div class="col-xs-12 col-sm-8">
<button type="submit" class="btn btn-success btn-embossed disabled">{:__('Ok')}</button>
<button type="submit" class="btn btn-primary btn-embossed disabled">{:__('Ok')}</button>
<button type="reset" class="btn btn-default btn-embossed">{:__('Reset')}</button>
</div>
</div>
@ -134,7 +134,7 @@
<div class="form-group" style="margin-bottom:0;">
<label class="control-label col-xs-12 col-sm-3"></label>
<div class="col-xs-12 col-sm-8">
<button type="submit" class="btn btn-md btn-info">{:__('Submit')}</button>
<button type="submit" class="btn btn-md btn-primary">{:__('Submit')}</button>
</div>
</div>
</div>
@ -168,7 +168,7 @@
<div class="form-group" style="margin-bottom:0;">
<label class="control-label col-xs-12 col-sm-3"></label>
<div class="col-xs-12 col-sm-8">
<button type="submit" class="btn btn-md btn-info">{:__('Submit')}</button>
<button type="submit" class="btn btn-md btn-primary">{:__('Submit')}</button>
</div>
</div>
</div>

View File

@ -9,28 +9,28 @@
<div class="form-group">
<label class="control-label required">{:__('Email')}<span class="text-success"></span></label>
<div class="controls">
<input type="text" name="email" id="email" data-rule="required;email" class="form-control input-lg" placeholder="{:__('Email')}">
<input type="text" name="email" id="email" data-rule="required;email" class="form-control" placeholder="{:__('Email')}">
<p class="help-block"></p>
</div>
</div>
<div class="form-group">
<label class="control-label">{:__('Username')}</label>
<div class="controls">
<input type="text" id="username" name="username" data-rule="required;username" class="form-control input-lg" placeholder="{:__('Username must be 3 to 30 characters')}">
<input type="text" id="username" name="username" data-rule="required;username" class="form-control" placeholder="{:__('Username must be 3 to 30 characters')}">
<p class="help-block"></p>
</div>
</div>
<div class="form-group">
<label class="control-label">{:__('Password')}</label>
<div class="controls">
<input type="password" id="password" name="password" data-rule="required;password" class="form-control input-lg" placeholder="{:__('Password must be 6 to 30 characters')}">
<input type="password" id="password" name="password" data-rule="required;password" class="form-control" placeholder="{:__('Password must be 6 to 30 characters')}">
<p class="help-block"></p>
</div>
</div>
<div class="form-group">
<label class="control-label">{:__('Mobile')}</label>
<div class="controls">
<input type="text" id="mobile" name="mobile" data-rule="required;mobile" class="form-control input-lg" placeholder="{:__('Mobile')}">
<input type="text" id="mobile" name="mobile" data-rule="required;mobile" class="form-control" placeholder="{:__('Mobile')}">
<p class="help-block"></p>
</div>
</div>
@ -49,6 +49,7 @@
<div class="form-group">
<button type="submit" class="btn btn-primary btn-lg btn-block">{:__('Sign up')}</button>
<a href="{:url('user/login')}?url={$url|urlencode|htmlentities}" class="btn btn-default btn-lg btn-block mt-3 no-border">已经有账号?点击登录</a>
</div>
</form>
</div>

View File

@ -1,6 +1,6 @@
@import url("../css/bootstrap.css");
@import url("../css/fastadmin.css");
@import url("../css/skins/skin-black-green.css");
@import url("../css/skins/skin-black-blue.css");
@import url("../css/iconfont.css");
@import url("../libs/font-awesome/css/font-awesome.min.css");
@import url("../libs/toastr/toastr.min.css");
@ -12,19 +12,227 @@
@import url("../libs/bootstrap-select/dist/css/bootstrap-select.min.css");
@import url("../libs/fastadmin-selectpage/selectpage.css");
@import url("../libs/bootstrap-slider/slider.css");
.m-1 {
margin-top: 5px !important;
margin-right: 5px !important;
margin-bottom: 5px !important;
margin-left: 5px !important;
}
.mt-1 {
margin-top: 5px !important;
}
.mr-1 {
margin-right: 5px !important;
}
.mb-1 {
margin-bottom: 5px !important;
}
.ml-1 {
margin-left: 5px !important;
}
.mx-1 {
margin-left: 5px !important;
margin-right: 5px !important;
}
.my-1 {
margin-top: 5px !important;
margin-bottom: 5px !important;
}
.m-2 {
margin-top: 10px !important;
margin-right: 10px !important;
margin-bottom: 10px !important;
margin-left: 10px !important;
}
.mt-2 {
margin-top: 10px !important;
}
.mr-2 {
margin-right: 10px !important;
}
.mb-2 {
margin-bottom: 10px !important;
}
.ml-2 {
margin-left: 10px !important;
}
.mx-2 {
margin-left: 10px !important;
margin-right: 10px !important;
}
.my-2 {
margin-top: 10px !important;
margin-bottom: 10px !important;
}
.m-3 {
margin-top: 15px !important;
margin-right: 15px !important;
margin-bottom: 15px !important;
margin-left: 15px !important;
}
.mt-3 {
margin-top: 15px !important;
}
.mr-3 {
margin-right: 15px !important;
}
.mb-3 {
margin-bottom: 15px !important;
}
.ml-3 {
margin-left: 15px !important;
}
.mx-3 {
margin-left: 15px !important;
margin-right: 15px !important;
}
.my-3 {
margin-top: 15px !important;
margin-bottom: 15px !important;
}
.m-4 {
margin-top: 20px !important;
margin-right: 20px !important;
margin-bottom: 20px !important;
margin-left: 20px !important;
}
.mt-4 {
margin-top: 20px !important;
}
.mr-4 {
margin-right: 20px !important;
}
.mb-4 {
margin-bottom: 20px !important;
}
.ml-4 {
margin-left: 20px !important;
}
.mx-4 {
margin-left: 20px !important;
margin-right: 20px !important;
}
.my-4 {
margin-top: 20px !important;
margin-bottom: 20px !important;
}
.p-1 {
padding-top: 5px !important;
padding-right: 5px !important;
padding-bottom: 5px !important;
padding-left: 5px !important;
}
.pt-1 {
padding-top: 5px !important;
}
.pr-1 {
padding-right: 5px !important;
}
.pb-1 {
padding-bottom: 5px !important;
}
.pl-1 {
padding-left: 5px !important;
}
.px-1 {
padding-left: 5px !important;
padding-right: 5px !important;
}
.py-1 {
padding-top: 5px !important;
padding-bottom: 5px !important;
}
.p-2 {
padding-top: 10px !important;
padding-right: 10px !important;
padding-bottom: 10px !important;
padding-left: 10px !important;
}
.pt-2 {
padding-top: 10px !important;
}
.pr-2 {
padding-right: 10px !important;
}
.pb-2 {
padding-bottom: 10px !important;
}
.pl-2 {
padding-left: 10px !important;
}
.px-2 {
padding-left: 10px !important;
padding-right: 10px !important;
}
.py-2 {
padding-top: 10px !important;
padding-bottom: 10px !important;
}
.p-3 {
padding-top: 15px !important;
padding-right: 15px !important;
padding-bottom: 15px !important;
padding-left: 15px !important;
}
.pt-3 {
padding-top: 15px !important;
}
.pr-3 {
padding-right: 15px !important;
}
.pb-3 {
padding-bottom: 15px !important;
}
.pl-3 {
padding-left: 15px !important;
}
.px-3 {
padding-left: 15px !important;
padding-right: 15px !important;
}
.py-3 {
padding-top: 15px !important;
padding-bottom: 15px !important;
}
.p-4 {
padding-top: 20px !important;
padding-right: 20px !important;
padding-bottom: 20px !important;
padding-left: 20px !important;
}
.pt-4 {
padding-top: 20px !important;
}
.pr-4 {
padding-right: 20px !important;
}
.pb-4 {
padding-bottom: 20px !important;
}
.pl-4 {
padding-left: 20px !important;
}
.px-4 {
padding-left: 20px !important;
padding-right: 20px !important;
}
.py-4 {
padding-top: 20px !important;
padding-bottom: 20px !important;
}
html,
body {
height: 100%;
}
body {
background: #f1f4f6;
font-size: 13px;
font-size: 14px;
line-height: 1.5715;
}
body.is-dialog {
background: #fff;
}
.dropdown-menu > li > a {
font-size: 13px;
padding: 5px 12px;
}
.selection {
@ -36,10 +244,10 @@ body.is-dialog {
position: relative;
}
.main-header .navbar .dropdown-menu {
font-size: 13px;
font-size: 14px;
}
.main-header .navbar .dropdown-menu > li > a {
padding: 5px 20px;
padding: 8px 15px;
}
.bootstrap-dialog .modal-dialog {
/*width: 70%;*/
@ -96,11 +304,11 @@ html.ios-fix body .tab-pane {
@media (max-width: 991px) {
.main-header .navbar-custom-menu a.btn-danger {
color: #fff;
background-color: #e74c3c;
background-color: #f75444;
}
.main-header .navbar-custom-menu a.btn-primary {
color: #fff;
background-color: #2c3e50;
background-color: #444c69;
}
}
.common-search-table {
@ -139,6 +347,9 @@ table.table-template {
.sp_container .sp_element_box .msg-box {
left: inherit;
}
.card-views .card-view {
padding: 5px 0;
}
}
.toast-top-right-index {
top: 62px;
@ -148,7 +359,7 @@ table.table-template {
background: #f0f0f0;
clear: both;
color: #999;
font-size: 12px;
font-size: 13px;
font-weight: 500;
line-height: 1;
margin-bottom: -5px;
@ -485,7 +696,7 @@ form.form-horizontal .control-label {
height: 100%;
padding: 0;
line-height: 28px;
font-size: 12px;
font-size: 13px;
vertical-align: middle;
opacity: 1;
overflow: hidden;
@ -589,25 +800,20 @@ form.form-horizontal .control-label {
.sidebar-menu > li .badge {
margin-top: 0;
}
.sidebar-menu .treeview-menu > li > a {
font-size: inherit;
}
.sidebar-collapse .user-panel > .image img {
width: 25px;
height: 25px;
}
@media (min-width: 768px) {
.sidebar-mini.sidebar-collapse .sidebar-menu > li:hover > .treeview-menu {
top: 42px;
}
.sidebar-mini.sidebar-collapse .sidebar-menu > li:hover > a > .pull-right-container {
top: 7px !important;
right: 10px;
height: 17px;
}
}
.fieldlist dd {
display: block;
margin: 5px 0;
margin: 8px 0;
}
.fieldlist dd input {
display: inline-block;
@ -620,7 +826,6 @@ form.form-horizontal .control-label {
width: 110px;
display: inline-block;
text-decoration: none;
font-weight: bold;
}
/* 弹窗中的表单 */
.form-layer {
@ -759,8 +964,15 @@ form.form-horizontal .control-label {
padding: 10px 0;
}
.bootstrap-table .fixed-table-toolbar .dropdown-menu {
overflow: inherit;
}
.bootstrap-table .fixed-table-toolbar .columns-right .dropdown-menu {
overflow: auto;
}
.bootstrap-table .bs-bars .fixed-table-toolbar .dropdown-menu > li:hover > a {
background-color: #e1e3e9;
color: #333;
}
.bootstrap-table .fa-toggle-on.fa-2x {
font-size: 1.86em;
}
@ -769,6 +981,18 @@ form.form-horizontal .control-label {
margin-right: 0;
white-space: nowrap;
}
.bootstrap-table .table:not(.table-condensed) > tbody > tr > th,
.bootstrap-table .table:not(.table-condensed) > tfoot > tr > th,
.bootstrap-table .table:not(.table-condensed) > thead > tr > td,
.bootstrap-table .table:not(.table-condensed) > tbody > tr > td,
.bootstrap-table .table:not(.table-condensed) > tfoot > tr > td {
padding: 8px 15px;
height: 47px;
}
.fixed-table-container tbody td .th-inner,
.fixed-table-container thead th .th-inner {
padding: 8px 10px;
}
.toolbar {
margin-top: 10px;
margin-bottom: 10px;
@ -793,7 +1017,7 @@ table.table-nowrap thead > tr > th {
white-space: nowrap;
}
.fixed-table-container thead th .sortable {
padding-right: 0;
padding: 8px 15px;
}
.dropdown-submenu {
position: relative;
@ -910,11 +1134,12 @@ table.table-nowrap thead > tr > th {
}
.layui-layer-fast .layui-layer-btn a {
background-color: #95a5a6;
border-color: #95a5a6;
color: #fff !important;
height: 31px;
height: 32px;
line-height: 32px;
margin-top: 0;
border: 1px solid transparent;
font-size: 13px;
border: none;
}
.layui-layer-fast .layui-layer-btn .layui-layer-btn0 {
background-color: #18bc9c;
@ -924,16 +1149,30 @@ table.table-nowrap thead > tr > th {
padding: 8px 20px;
background-color: #ecf0f1;
height: auto;
min-height: 53px;
text-align: inherit !important;
}
.layui-layer-fast .layui-layer-confirm {
position: absolute;
width: 1px;
height: 1px;
width: 100%;
height: 100%;
left: 0;
bottom: 0;
border: none;
border: 1px solid transparent;
background: transparent;
color: transparent;
}
.layui-layer-fast .layui-layer-confirm:focus {
border: 1px solid #444c69;
-webkit-border-radius: 2px;
-webkit-background-clip: padding-box;
-moz-border-radius: 2px;
-moz-background-clip: padding;
border-radius: 2px;
background-clip: padding-box;
}
.layui-layer-fast .layui-layer-confirm:focus-visible {
outline: 0;
}
.layui-layer-fast .layui-layer-tab .layui-layer-title span.layui-this {
height: 46px;
@ -1030,6 +1269,9 @@ table.table-nowrap thead > tr > th {
.fixed-table-toolbar > .bs-bars {
float: none !important;
}
.fixed-table-toolbar .toolbar .btn {
min-height: 33px;
}
.fixed-table-toolbar .toolbar a.btn-refresh,
.fixed-table-toolbar .toolbar a.btn-del,
.fixed-table-toolbar .toolbar a.btn-add,
@ -1037,7 +1279,8 @@ table.table-nowrap thead > tr > th {
.fixed-table-toolbar .toolbar a.btn-import,
.fixed-table-toolbar .toolbar a.btn-more,
.fixed-table-toolbar .toolbar a.btn-recyclebin,
.fixed-table-toolbar .toolbar .btn-mini-xs {
.fixed-table-toolbar .toolbar .btn-mini-xs,
.fixed-table-toolbar .toolbar .btn-multi {
font-size: 0;
}
.fixed-table-toolbar .toolbar a.btn-refresh .fa,
@ -1047,7 +1290,8 @@ table.table-nowrap thead > tr > th {
.fixed-table-toolbar .toolbar a.btn-import .fa,
.fixed-table-toolbar .toolbar a.btn-more .fa,
.fixed-table-toolbar .toolbar a.btn-recyclebin .fa,
.fixed-table-toolbar .toolbar .btn-mini-xs .fa {
.fixed-table-toolbar .toolbar .btn-mini-xs .fa,
.fixed-table-toolbar .toolbar .btn-multi .fa {
font-size: initial;
}
.fixed-table-toolbar .search {
@ -1148,7 +1392,6 @@ table.table-nowrap thead > tr > th {
color: #d2d6de !important;
}
.jumpto input {
height: 31px;
width: 50px;
margin-left: 5px;
margin-right: 5px;
@ -1199,4 +1442,87 @@ table.table-nowrap thead > tr > th {
-o-transform: rotate(-90deg);
transform: rotate(-90deg);
}
.sidebar-menu .treeview-menu > li {
margin: 4px 0 4px 0;
}
.bootstrap-tagsinput {
background-color: #fff;
border: 1px solid #ccc;
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
display: inline-block;
padding: 4px 6px;
margin-bottom: 10px;
color: #555;
vertical-align: middle;
width: 100%;
line-height: 22px;
cursor: text;
}
.bootstrap-tagsinput input {
border: none;
box-shadow: none;
outline: none;
background-color: transparent;
padding: 0;
margin: 0;
font-size: 13px;
width: 80px;
max-width: inherit;
}
.bootstrap-tagsinput input:focus {
border: none;
box-shadow: none;
}
.bootstrap-tagsinput .tagsinput-text {
display: inline-block;
overflow: auto;
visibility: hidden;
height: 1px;
position: absolute;
bottom: -1px;
left: 0;
}
.bootstrap-tagsinput .tag {
margin-right: 2px;
color: white;
}
.bootstrap-tagsinput .tag [data-role="remove"] {
margin-left: 5px;
cursor: pointer;
}
.bootstrap-tagsinput .tag [data-role="remove"]:after {
content: "x";
padding: 0px 2px;
}
.bootstrap-tagsinput .tag [data-role="remove"]:hover {
background-color: rgba(255, 255, 255, 0.16);
}
.autocomplete-suggestions {
border-radius: 2px;
background: #FFF;
overflow: auto;
min-width: 200px;
-webkit-box-shadow: 0px 20px 30px rgba(83, 88, 93, 0.05), 0px 0px 30px rgba(83, 88, 93, 0.1);
-moz-box-shadow: 0px 20px 30px rgba(83, 88, 93, 0.05), 0px 0px 30px rgba(83, 88, 93, 0.1);
box-shadow: 0px 20px 30px rgba(83, 88, 93, 0.05), 0px 0px 30px rgba(83, 88, 93, 0.1);
}
.autocomplete-suggestions strong {
font-weight: normal;
color: red;
}
.autocomplete-suggestions .autocomplete-suggestion {
padding: 5px 10px;
white-space: nowrap;
overflow: hidden;
}
.autocomplete-suggestions .autocomplete-selected {
background: #F0F0F0;
}
.autocomplete-suggestions .autocomplete-group {
padding: 5px 10px;
}
.autocomplete-suggestions .autocomplete-group strong {
display: block;
border-bottom: 1px solid #ddd;
}
/*# sourceMappingURL=backend.css.map */

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@ -168,14 +168,14 @@ h6,
}
/* General Links */
a {
color: #3c8dbc;
color: #4397fd;
}
a:hover,
a:active,
a:focus {
outline: none;
text-decoration: none;
color: #72afd2;
color: #8fc1fe;
}
/* Page Header */
.page-header {
@ -255,7 +255,7 @@ a:focus {
float: left;
background-color: transparent;
background-image: none;
padding: 16.5px 15px;
padding: 16px 15px;
font-family: fontAwesome;
}
.main-header .sidebar-toggle:before {
@ -367,7 +367,7 @@ a:focus {
color: #fff;
border: 0;
margin: 0;
padding: 16.5px 15px;
padding: 16px 15px;
}
@media (max-width: 991px) {
.navbar-custom-menu .navbar-nav > li {
@ -522,7 +522,7 @@ a:focus {
}
.sidebar-menu > li {
position: relative;
margin: 0;
margin: 5px 0;
padding: 0;
}
.sidebar-menu > li > a {
@ -565,20 +565,27 @@ a:focus {
.sidebar-menu .treeview-menu {
display: none;
list-style: none;
padding: 0;
padding: 0px 0;
margin: 0;
padding-left: 5px;
}
.sidebar-menu .treeview-menu .treeview-menu {
padding-left: 20px;
}
.sidebar-menu .treeview-menu:before,
.sidebar-menu .treeview-menu:after {
content: "";
display: table;
}
.sidebar-menu .treeview-menu.menu-open {
display: block;
}
.sidebar-menu .treeview-menu > li {
margin: 0;
}
.sidebar-menu .treeview-menu > li > a {
padding: 12px 5px 12px 15px;
display: block;
font-size: 12px;
}
.sidebar-menu .treeview-menu > li > a > .fa,
.sidebar-menu .treeview-menu > li > a > .glyphicon,
@ -595,6 +602,9 @@ a:focus {
* Component: Sidebar Mini
*/
@media (min-width: 768px) {
.sidebar-mini.sidebar-collapse .sidebar-menu:hover {
overflow: visible;
}
.sidebar-mini.sidebar-collapse .content-wrapper,
.sidebar-mini.sidebar-collapse .right-side,
.sidebar-mini.sidebar-collapse .main-footer {
@ -615,16 +625,26 @@ a:focus {
.sidebar-mini.sidebar-collapse .sidebar-menu > li > a {
margin-right: 0;
}
.sidebar-mini.sidebar-collapse .sidebar-menu > li > a > span {
border-top-right-radius: 4px;
}
.sidebar-mini.sidebar-collapse .sidebar-menu > li:not(.treeview) > a > span {
border-bottom-right-radius: 4px;
}
.sidebar-mini.sidebar-collapse .sidebar-menu > li > .treeview-menu {
padding-top: 5px;
padding-bottom: 5px;
border-bottom-right-radius: 4px;
scrollbar-width: thin;
scrollbar-color: rgba(255, 255, 255, 0.15) transparent;
/* Works on Chrome, Edge, and Safari */
}
.sidebar-mini.sidebar-collapse .sidebar-menu > li > .treeview-menu::-webkit-scrollbar {
width: 8px;
}
.sidebar-mini.sidebar-collapse .sidebar-menu > li > .treeview-menu::-webkit-scrollbar-track {
background: transparent;
}
.sidebar-mini.sidebar-collapse .sidebar-menu > li > .treeview-menu::-webkit-scrollbar-thumb {
background-color: rgba(255, 255, 255, 0.15);
border-radius: 20px;
border: 3px solid transparent;
}
.sidebar-mini.sidebar-collapse .sidebar-menu > li:hover > a {
width: 230px;
}
.sidebar-mini.sidebar-collapse .sidebar-menu > li:hover > a > span:not(.pull-right),
.sidebar-mini.sidebar-collapse .sidebar-menu > li:hover > .treeview-menu {
@ -635,21 +655,21 @@ a:focus {
}
.sidebar-mini.sidebar-collapse .sidebar-menu > li:hover > a > span {
top: 0;
margin-left: -3px;
padding: 12px 5px 12px 20px;
background-color: inherit;
}
.sidebar-mini.sidebar-collapse .sidebar-menu > li:hover > a > .pull-right-container {
display: block!important;
float: right;
width: auto!important;
left: 200px!important;
left: 195px!important;
top: 10px!important;
}
.sidebar-mini.sidebar-collapse .sidebar-menu > li:hover > a > .pull-right-container > .label:not(:first-of-type) {
display: none;
}
.sidebar-mini.sidebar-collapse .sidebar-menu > li:hover > .treeview-menu {
top: 44px;
top: 46px;
margin-left: 0;
}
.sidebar-mini.sidebar-collapse .main-sidebar .user-panel > .info,
@ -683,9 +703,6 @@ a:focus {
white-space: nowrap;
overflow: hidden;
}
.sidebar-menu:hover {
overflow: visible;
}
.sidebar-form,
.sidebar-menu > li.header {
overflow: hidden;
@ -1333,7 +1350,7 @@ a:focus {
appearance: none;
}
.form-control:focus {
border-color: #3c8dbc;
border-color: #4397fd;
box-shadow: none;
}
.form-control::-moz-placeholder,
@ -1375,15 +1392,15 @@ select.form-control {
color: #f39c12;
}
.form-group.has-error label {
color: #e74c3c;
color: #f75444;
}
.form-group.has-error .form-control,
.form-group.has-error .input-group-addon {
border-color: #e74c3c;
border-color: #f75444;
box-shadow: none;
}
.form-group.has-error .help-block {
color: #e74c3c;
color: #f75444;
}
/* Input group */
.input-group .input-group-addon {
@ -1401,17 +1418,17 @@ select.form-control {
}
/* support Font Awesome icons in form-control */
.form-control-feedback.fa {
line-height: 31px;
line-height: 33px;
}
.input-lg + .form-control-feedback.fa,
.input-group-lg + .form-control-feedback.fa,
.form-group-lg .form-control + .form-control-feedback.fa {
line-height: 42px;
line-height: 45px;
}
.input-sm + .form-control-feedback.fa,
.input-group-sm + .form-control-feedback.fa,
.form-group-sm .form-control + .form-control-feedback.fa {
line-height: 28px;
line-height: 30px;
}
/*
* Component: Progress Bar
@ -1496,7 +1513,7 @@ select.form-control {
}
.progress-bar-light-blue,
.progress-bar-primary {
background-color: #3c8dbc;
background-color: #4397fd;
}
.progress-striped .progress-bar-light-blue,
.progress-striped .progress-bar-primary {
@ -1516,7 +1533,7 @@ select.form-control {
}
.progress-bar-aqua,
.progress-bar-info {
background-color: #3498db;
background-color: #1688f1;
}
.progress-striped .progress-bar-aqua,
.progress-striped .progress-bar-info {
@ -1536,7 +1553,7 @@ select.form-control {
}
.progress-bar-red,
.progress-bar-danger {
background-color: #e74c3c;
background-color: #f75444;
}
.progress-striped .progress-bar-red,
.progress-striped .progress-bar-danger {
@ -1636,13 +1653,13 @@ select.form-control {
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);
}
.box.box-primary {
border-top-color: #3c8dbc;
border-top-color: #4397fd;
}
.box.box-info {
border-top-color: #3498db;
border-top-color: #1688f1;
}
.box.box-danger {
border-top-color: #e74c3c;
border-top-color: #f75444;
}
.box.box-warning {
border-top-color: #f39c12;
@ -1697,36 +1714,36 @@ select.form-control {
color: #444;
}
.box.box-solid.box-primary {
border: 1px solid #3c8dbc;
border: 1px solid #4397fd;
}
.box.box-solid.box-primary > .box-header {
color: #fff;
background: #3c8dbc;
background-color: #3c8dbc;
background: #4397fd;
background-color: #4397fd;
}
.box.box-solid.box-primary > .box-header a,
.box.box-solid.box-primary > .box-header .btn {
color: #fff;
}
.box.box-solid.box-info {
border: 1px solid #3498db;
border: 1px solid #1688f1;
}
.box.box-solid.box-info > .box-header {
color: #fff;
background: #3498db;
background-color: #3498db;
background: #1688f1;
background-color: #1688f1;
}
.box.box-solid.box-info > .box-header a,
.box.box-solid.box-info > .box-header .btn {
color: #fff;
}
.box.box-solid.box-danger {
border: 1px solid #e74c3c;
border: 1px solid #f75444;
}
.box.box-solid.box-danger > .box-header {
color: #fff;
background: #e74c3c;
background-color: #e74c3c;
background: #f75444;
background-color: #f75444;
}
.box.box-solid.box-danger > .box-header a,
.box.box-solid.box-danger > .box-header .btn {
@ -2013,7 +2030,7 @@ select.form-control {
.todo-list > li .tools {
display: none;
float: right;
color: #e74c3c;
color: #f75444;
}
.todo-list > li .tools > .fa,
.todo-list > li .tools > .glyphicon,
@ -2035,19 +2052,19 @@ select.form-control {
background: #d2d6de !important;
}
.todo-list .danger {
border-left-color: #e74c3c;
border-left-color: #f75444;
}
.todo-list .warning {
border-left-color: #f39c12;
}
.todo-list .info {
border-left-color: #3498db;
border-left-color: #1688f1;
}
.todo-list .success {
border-left-color: #18bc9c;
}
.todo-list .primary {
border-left-color: #3c8dbc;
border-left-color: #4397fd;
}
.todo-list .handle {
display: inline-block;
@ -2087,7 +2104,7 @@ select.form-control {
border: 2px solid #18bc9c;
}
.chat .item > .offline {
border: 2px solid #e74c3c;
border: 2px solid #f75444;
}
.chat .item > .message {
margin-left: 55px;
@ -2521,13 +2538,13 @@ select.form-control {
background-color: #fff;
}
.callout.callout-danger {
border-color: #d62c1a;
border-color: #f52713;
}
.callout.callout-warning {
border-color: #c87f0a;
}
.callout.callout-info {
border-color: #217dbb;
border-color: #0c6ec8;
}
.callout.callout-success {
border-color: #128f76;
@ -2563,13 +2580,13 @@ select.form-control {
}
.alert-danger,
.alert-error {
border-color: #e43725;
border-color: #f63e2c;
}
.alert-warning {
border-color: #e08e0b;
}
.alert-info {
border-color: #258cd1;
border-color: #0d7be0;
}
.alert-primary-light {
background-color: #E2E5E8;
@ -2637,7 +2654,7 @@ select.form-control {
.nav-pills > li.active > a,
.nav-pills > li.active > a:hover,
.nav-pills > li.active > a:focus {
border-top-color: #3c8dbc;
border-top-color: #4397fd;
}
.nav-pills > li.active > a {
font-weight: 600;
@ -2654,7 +2671,7 @@ select.form-control {
background: transparent;
color: #444;
border-top: 0;
border-left-color: #3c8dbc;
border-left-color: #4397fd;
}
.nav-stacked > li.header {
border-bottom: 1px solid #ddd;
@ -2702,7 +2719,7 @@ select.form-control {
border-color: transparent;
}
.nav-tabs-custom > .nav-tabs > li.active {
border-top-color: #3c8dbc;
border-top-color: #4397fd;
}
.nav-tabs-custom > .nav-tabs > li.active > a,
.nav-tabs-custom > .nav-tabs > li.active:hover > a {
@ -2759,13 +2776,13 @@ select.form-control {
color: #999;
}
.nav-tabs-custom.tab-primary > .nav-tabs > li.active {
border-top-color: #3c8dbc;
border-top-color: #4397fd;
}
.nav-tabs-custom.tab-info > .nav-tabs > li.active {
border-top-color: #3498db;
border-top-color: #1688f1;
}
.nav-tabs-custom.tab-danger > .nav-tabs > li.active {
border-top-color: #e74c3c;
border-top-color: #f75444;
}
.nav-tabs-custom.tab-warning > .nav-tabs > li.active {
border-top-color: #f39c12;
@ -3082,22 +3099,22 @@ table.text-center th {
color: #999;
}
.direct-chat-danger .right > .direct-chat-text {
background: #e74c3c;
border-color: #e74c3c;
background: #f75444;
border-color: #f75444;
color: #fff;
}
.direct-chat-danger .right > .direct-chat-text:after,
.direct-chat-danger .right > .direct-chat-text:before {
border-left-color: #e74c3c;
border-left-color: #f75444;
}
.direct-chat-primary .right > .direct-chat-text {
background: #3c8dbc;
border-color: #3c8dbc;
background: #4397fd;
border-color: #4397fd;
color: #fff;
}
.direct-chat-primary .right > .direct-chat-text:after,
.direct-chat-primary .right > .direct-chat-text:before {
border-left-color: #3c8dbc;
border-left-color: #4397fd;
}
.direct-chat-warning .right > .direct-chat-text {
background: #f39c12;
@ -3109,13 +3126,13 @@ table.text-center th {
border-left-color: #f39c12;
}
.direct-chat-info .right > .direct-chat-text {
background: #3498db;
border-color: #3498db;
background: #1688f1;
border-color: #1688f1;
color: #fff;
}
.direct-chat-info .right > .direct-chat-text:after,
.direct-chat-info .right > .direct-chat-text:before {
border-left-color: #3498db;
border-left-color: #1688f1;
}
.direct-chat-success .right > .direct-chat-text {
background: #18bc9c;
@ -3203,7 +3220,7 @@ table.text-center th {
}
.modal-primary .modal-header,
.modal-primary .modal-footer {
border-color: #307095;
border-color: #117bfc;
}
.modal-warning .modal-header,
.modal-warning .modal-footer {
@ -3211,7 +3228,7 @@ table.text-center th {
}
.modal-info .modal-header,
.modal-info .modal-footer {
border-color: #217dbb;
border-color: #0c6ec8;
}
.modal-success .modal-header,
.modal-success .modal-footer {
@ -3219,7 +3236,7 @@ table.text-center th {
}
.modal-danger .modal-header,
.modal-danger .modal-footer {
border-color: #d62c1a;
border-color: #f52713;
}
/*
* Component: Social Widgets
@ -3285,7 +3302,7 @@ table.text-center th {
.close,
.mailbox-attachment-close {
float: right;
font-size: 18px;
font-size: 19.5px;
font-weight: bold;
line-height: 1;
color: #000;
@ -3632,7 +3649,7 @@ button.close {
*/
.btn-social {
position: relative;
padding-left: 41px;
padding-left: 42px;
text-align: left;
white-space: nowrap;
overflow: hidden;
@ -3643,45 +3660,45 @@ button.close {
left: 0;
top: 0;
bottom: 0;
width: 29px;
line-height: 31px;
width: 30px;
line-height: 32px;
font-size: 1.6em;
text-align: center;
border-right: 1px solid rgba(0, 0, 0, 0.2);
}
.btn-social.btn-lg {
padding-left: 57px;
padding-left: 60px;
}
.btn-social.btn-lg > :first-child {
line-height: 41px;
width: 41px;
line-height: 44px;
width: 44px;
font-size: 1.8em;
}
.btn-social.btn-sm {
padding-left: 36px;
padding-left: 38px;
}
.btn-social.btn-sm > :first-child {
line-height: 26px;
width: 26px;
line-height: 28px;
width: 28px;
font-size: 1.4em;
}
.btn-social.btn-xs {
padding-left: 29px;
padding-left: 30px;
}
.btn-social.btn-xs > :first-child {
line-height: 19px;
width: 19px;
line-height: 20px;
width: 20px;
font-size: 1.2em;
}
.btn-social-icon {
position: relative;
padding-left: 41px;
padding-left: 42px;
text-align: left;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
height: 31px;
width: 31px;
height: 32px;
width: 32px;
padding: 0;
}
.btn-social-icon > :first-child {
@ -3689,34 +3706,34 @@ button.close {
left: 0;
top: 0;
bottom: 0;
width: 29px;
line-height: 31px;
width: 30px;
line-height: 32px;
font-size: 1.6em;
text-align: center;
border-right: 1px solid rgba(0, 0, 0, 0.2);
}
.btn-social-icon.btn-lg {
padding-left: 57px;
padding-left: 60px;
}
.btn-social-icon.btn-lg > :first-child {
line-height: 41px;
width: 41px;
line-height: 44px;
width: 44px;
font-size: 1.8em;
}
.btn-social-icon.btn-sm {
padding-left: 36px;
padding-left: 38px;
}
.btn-social-icon.btn-sm > :first-child {
line-height: 26px;
width: 26px;
line-height: 28px;
width: 28px;
font-size: 1.4em;
}
.btn-social-icon.btn-xs {
padding-left: 29px;
padding-left: 30px;
}
.btn-social-icon.btn-xs > :first-child {
line-height: 19px;
width: 19px;
line-height: 20px;
width: 20px;
font-size: 1.2em;
}
.btn-social-icon > :first-child {
@ -3725,20 +3742,20 @@ button.close {
width: 100%;
}
.btn-social-icon.btn-lg {
height: 41px;
width: 41px;
height: 44px;
width: 44px;
padding-left: 0;
padding-right: 0;
}
.btn-social-icon.btn-sm {
height: 28px;
width: 28px;
height: 30px;
width: 30px;
padding-left: 0;
padding-right: 0;
}
.btn-social-icon.btn-xs {
height: 21px;
width: 21px;
height: 22px;
width: 22px;
padding-left: 0;
padding-right: 0;
}
@ -5175,14 +5192,14 @@ fieldset[disabled] .btn-yahoo.active {
height: 34px;
}
.select2-container--default.select2-container--open {
border-color: #3c8dbc;
border-color: #4397fd;
}
.select2-dropdown {
border: 1px solid #d2d6de;
border-radius: 0;
}
.select2-container--default .select2-results__option--highlighted[aria-selected] {
background-color: #3c8dbc;
background-color: #4397fd;
color: white;
}
.select2-results__option {
@ -5214,7 +5231,7 @@ fieldset[disabled] .btn-yahoo.active {
.select2-dropdown .select2-search__field:focus,
.select2-search--inline .select2-search__field:focus {
outline: none;
border: 1px solid #3c8dbc;
border: 1px solid #4397fd;
}
.select2-container--default .select2-results__option[aria-disabled=true] {
color: #999;
@ -5231,14 +5248,14 @@ fieldset[disabled] .btn-yahoo.active {
border-radius: 0;
}
.select2-container--default .select2-selection--multiple:focus {
border-color: #3c8dbc;
border-color: #4397fd;
}
.select2-container--default.select2-container--focus .select2-selection--multiple {
border-color: #d2d6de;
}
.select2-container--default .select2-selection--multiple .select2-selection__choice {
background-color: #3c8dbc;
border-color: #367fa9;
background-color: #4397fd;
border-color: #2a89fd;
padding: 1px 10px;
color: #fff;
}
@ -5362,7 +5379,7 @@ fieldset[disabled] .btn-yahoo.active {
.alert-danger,
.alert-error,
.modal-danger .modal-body {
background-color: #e74c3c !important;
background-color: #f75444 !important;
}
.bg-yellow,
.callout.callout-warning,
@ -5374,14 +5391,14 @@ fieldset[disabled] .btn-yahoo.active {
.callout.callout-info,
.alert-info,
.modal-info .modal-body {
background-color: #3498db !important;
background-color: #1688f1 !important;
}
.bg-blue {
background-color: #0073b7 !important;
background-color: #1688f1 !important;
}
.bg-light-blue,
.modal-primary .modal-body {
background-color: #3c8dbc !important;
background-color: #4397fd !important;
}
.bg-green,
.callout.callout-success,
@ -5423,7 +5440,7 @@ fieldset[disabled] .btn-yahoo.active {
.bg-red-active,
.modal-danger .modal-header,
.modal-danger .modal-footer {
background-color: #e43321 !important;
background-color: #f63927 !important;
}
.bg-yellow-active,
.modal-warning .modal-header,
@ -5433,15 +5450,15 @@ fieldset[disabled] .btn-yahoo.active {
.bg-aqua-active,
.modal-info .modal-header,
.modal-info .modal-footer {
background-color: #2489cc !important;
background-color: #0d78db !important;
}
.bg-blue-active {
background-color: #005384 !important;
background-color: #0c6ec8 !important;
}
.bg-light-blue-active,
.modal-primary .modal-header,
.modal-primary .modal-footer {
background-color: #357ca5 !important;
background-color: #2586fd !important;
}
.bg-green-active,
.modal-success .modal-header,
@ -5477,22 +5494,22 @@ fieldset[disabled] .btn-yahoo.active {
filter: alpha(opacity=65);
}
.text-red {
color: #e74c3c !important;
color: #f75444 !important;
}
.text-yellow {
color: #f39c12 !important;
}
.text-aqua {
color: #3498db !important;
color: #1688f1 !important;
}
.text-blue {
color: #0073b7 !important;
color: #1688f1 !important;
}
.text-black {
color: #111 !important;
}
.text-light-blue {
color: #3c8dbc !important;
color: #4397fd !important;
}
.text-green {
color: #18bc9c !important;
@ -5595,30 +5612,30 @@ fieldset[disabled] .btn-yahoo.active {
color: #fff;
}
.bg-light-blue-gradient {
background: #3c8dbc !important;
background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #3c8dbc), color-stop(1, #67a8ce)) !important;
background: -ms-linear-gradient(bottom, #3c8dbc, #67a8ce) !important;
background: -moz-linear-gradient(center bottom, #3c8dbc 0%, #67a8ce 100%) !important;
background: -o-linear-gradient(#67a8ce, #3c8dbc) !important;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#67a8ce', endColorstr='#3c8dbc', GradientType=0) !important;
background: #4397fd !important;
background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #4397fd), color-stop(1, #80b8fe)) !important;
background: -ms-linear-gradient(bottom, #4397fd, #80b8fe) !important;
background: -moz-linear-gradient(center bottom, #4397fd 0%, #80b8fe 100%) !important;
background: -o-linear-gradient(#80b8fe, #4397fd) !important;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80b8fe', endColorstr='#4397fd', GradientType=0) !important;
color: #fff;
}
.bg-blue-gradient {
background: #0073b7 !important;
background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #0073b7), color-stop(1, #0089db)) !important;
background: -ms-linear-gradient(bottom, #0073b7, #0089db) !important;
background: -moz-linear-gradient(center bottom, #0073b7 0%, #0089db 100%) !important;
background: -o-linear-gradient(#0089db, #0073b7) !important;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0089db', endColorstr='#0073b7', GradientType=0) !important;
background: #1688f1 !important;
background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #1688f1), color-stop(1, #3899f3)) !important;
background: -ms-linear-gradient(bottom, #1688f1, #3899f3) !important;
background: -moz-linear-gradient(center bottom, #1688f1 0%, #3899f3 100%) !important;
background: -o-linear-gradient(#3899f3, #1688f1) !important;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#3899f3', endColorstr='#1688f1', GradientType=0) !important;
color: #fff;
}
.bg-aqua-gradient {
background: #3498db !important;
background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #3498db), color-stop(1, #52a7e0)) !important;
background: -ms-linear-gradient(bottom, #3498db, #52a7e0) !important;
background: -moz-linear-gradient(center bottom, #3498db 0%, #52a7e0 100%) !important;
background: -o-linear-gradient(#52a7e0, #3498db) !important;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#52a7e0', endColorstr='#3498db', GradientType=0) !important;
background: #1688f1 !important;
background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #1688f1), color-stop(1, #3899f3)) !important;
background: -ms-linear-gradient(bottom, #1688f1, #3899f3) !important;
background: -moz-linear-gradient(center bottom, #1688f1 0%, #3899f3 100%) !important;
background: -o-linear-gradient(#3899f3, #1688f1) !important;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#3899f3', endColorstr='#1688f1', GradientType=0) !important;
color: #fff;
}
.bg-yellow-gradient {
@ -5649,12 +5666,12 @@ fieldset[disabled] .btn-yahoo.active {
color: #fff;
}
.bg-red-gradient {
background: #e74c3c !important;
background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #e74c3c), color-stop(1, #ed7669)) !important;
background: -ms-linear-gradient(bottom, #e74c3c, #ed7669) !important;
background: -moz-linear-gradient(center bottom, #e74c3c 0%, #ed7669 100%) !important;
background: -o-linear-gradient(#ed7669, #e74c3c) !important;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ed7669', endColorstr='#e74c3c', GradientType=0) !important;
background: #f75444 !important;
background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #f75444), color-stop(1, #f98175)) !important;
background: -ms-linear-gradient(bottom, #f75444, #f98175) !important;
background: -moz-linear-gradient(center bottom, #f75444 0%, #f98175 100%) !important;
background: -o-linear-gradient(#f98175, #f75444) !important;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#f98175', endColorstr='#f75444', GradientType=0) !important;
color: #fff;
}
.bg-black-gradient {

View File

@ -11,14 +11,288 @@
@import url("../libs/bootstrap-select/dist/css/bootstrap-select.min.css");
@import url("../libs/fastadmin-selectpage/selectpage.css");
@import url("../libs/bootstrap-slider/slider.css");
.m-1 {
margin-top: 5px !important;
margin-right: 5px !important;
margin-bottom: 5px !important;
margin-left: 5px !important;
}
.mt-1 {
margin-top: 5px !important;
}
.mr-1 {
margin-right: 5px !important;
}
.mb-1 {
margin-bottom: 5px !important;
}
.ml-1 {
margin-left: 5px !important;
}
.mx-1 {
margin-left: 5px !important;
margin-right: 5px !important;
}
.my-1 {
margin-top: 5px !important;
margin-bottom: 5px !important;
}
.m-2 {
margin-top: 10px !important;
margin-right: 10px !important;
margin-bottom: 10px !important;
margin-left: 10px !important;
}
.mt-2 {
margin-top: 10px !important;
}
.mr-2 {
margin-right: 10px !important;
}
.mb-2 {
margin-bottom: 10px !important;
}
.ml-2 {
margin-left: 10px !important;
}
.mx-2 {
margin-left: 10px !important;
margin-right: 10px !important;
}
.my-2 {
margin-top: 10px !important;
margin-bottom: 10px !important;
}
.m-3 {
margin-top: 15px !important;
margin-right: 15px !important;
margin-bottom: 15px !important;
margin-left: 15px !important;
}
.mt-3 {
margin-top: 15px !important;
}
.mr-3 {
margin-right: 15px !important;
}
.mb-3 {
margin-bottom: 15px !important;
}
.ml-3 {
margin-left: 15px !important;
}
.mx-3 {
margin-left: 15px !important;
margin-right: 15px !important;
}
.my-3 {
margin-top: 15px !important;
margin-bottom: 15px !important;
}
.m-4 {
margin-top: 20px !important;
margin-right: 20px !important;
margin-bottom: 20px !important;
margin-left: 20px !important;
}
.mt-4 {
margin-top: 20px !important;
}
.mr-4 {
margin-right: 20px !important;
}
.mb-4 {
margin-bottom: 20px !important;
}
.ml-4 {
margin-left: 20px !important;
}
.mx-4 {
margin-left: 20px !important;
margin-right: 20px !important;
}
.my-4 {
margin-top: 20px !important;
margin-bottom: 20px !important;
}
.p-1 {
padding-top: 5px !important;
padding-right: 5px !important;
padding-bottom: 5px !important;
padding-left: 5px !important;
}
.pt-1 {
padding-top: 5px !important;
}
.pr-1 {
padding-right: 5px !important;
}
.pb-1 {
padding-bottom: 5px !important;
}
.pl-1 {
padding-left: 5px !important;
}
.px-1 {
padding-left: 5px !important;
padding-right: 5px !important;
}
.py-1 {
padding-top: 5px !important;
padding-bottom: 5px !important;
}
.p-2 {
padding-top: 10px !important;
padding-right: 10px !important;
padding-bottom: 10px !important;
padding-left: 10px !important;
}
.pt-2 {
padding-top: 10px !important;
}
.pr-2 {
padding-right: 10px !important;
}
.pb-2 {
padding-bottom: 10px !important;
}
.pl-2 {
padding-left: 10px !important;
}
.px-2 {
padding-left: 10px !important;
padding-right: 10px !important;
}
.py-2 {
padding-top: 10px !important;
padding-bottom: 10px !important;
}
.p-3 {
padding-top: 15px !important;
padding-right: 15px !important;
padding-bottom: 15px !important;
padding-left: 15px !important;
}
.pt-3 {
padding-top: 15px !important;
}
.pr-3 {
padding-right: 15px !important;
}
.pb-3 {
padding-bottom: 15px !important;
}
.pl-3 {
padding-left: 15px !important;
}
.px-3 {
padding-left: 15px !important;
padding-right: 15px !important;
}
.py-3 {
padding-top: 15px !important;
padding-bottom: 15px !important;
}
.p-4 {
padding-top: 20px !important;
padding-right: 20px !important;
padding-bottom: 20px !important;
padding-left: 20px !important;
}
.pt-4 {
padding-top: 20px !important;
}
.pr-4 {
padding-right: 20px !important;
}
.pb-4 {
padding-bottom: 20px !important;
}
.pl-4 {
padding-left: 20px !important;
}
.px-4 {
padding-left: 20px !important;
padding-right: 20px !important;
}
.py-4 {
padding-top: 20px !important;
padding-bottom: 20px !important;
}
html,
body {
height: 100%;
}
body {
padding-top: 50px;
font-size: 13px;
padding-top: 60px;
font-size: 14px;
background: #f4f6f8;
height: 100%;
line-height: 1.5715;
-webkit-font-smoothing: antialiased;
text-rendering: optimizeLegibility;
-moz-osx-font-smoothing: grayscale;
font-feature-settings: 'liga';
-webkit-text-size-adjust: 100%;
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Ubuntu, Helvetica Neue, Helvetica, Arial, PingFang SC, Hiragino Sans GB, Microsoft YaHei UI, Microsoft YaHei, Source Han Sans CN, sans-serif;
font-weight: 400;
color: #616161;
}
a {
color: #007bff;
}
a:hover,
a:focus {
color: #007bff;
}
.navbar-white {
background-color: #fff;
border-color: #fff;
box-shadow: 0 1px 8px rgba(0, 0, 0, 0.08);
}
.navbar-white .dropdown-menu {
border-radius: 5px;
-webkit-box-shadow: 0px 20px 30px rgba(83, 88, 93, 0.05), 0px 0px 30px rgba(83, 88, 93, 0.1);
-moz-box-shadow: 0px 20px 30px rgba(83, 88, 93, 0.05), 0px 0px 30px rgba(83, 88, 93, 0.1);
box-shadow: 0px 20px 30px rgba(83, 88, 93, 0.05), 0px 0px 30px rgba(83, 88, 93, 0.1);
}
@media (min-width: 768px) {
.navbar-white .navbar-brand {
height: 60px;
line-height: 27px;
}
.navbar-white .navbar-nav > li > a {
height: 60px;
line-height: 27px;
color: #555;
}
.navbar-white .navbar-nav > li > a:hover,
.navbar-white .navbar-nav > li > a:focus {
color: #007bff;
}
.navbar-white .navbar-nav > .active > a,
.navbar-white .navbar-nav > .active > a:hover,
.navbar-white .navbar-nav > .active > a:focus {
background-color: inherit;
color: #007bff;
}
}
@media (max-width: 768px) {
body {
padding-top: 50px;
}
.navbar-white .navbar-nav .open .dropdown-menu {
background: #eee;
}
.navbar-white .navbar-toggle {
border-color: #ddd;
}
.navbar-white .navbar-toggle .icon-bar {
background-color: #888;
}
.navbar-white .navbar-collapse.in {
border-top-color: #f5f5f5;
}
}
.dropdown:hover .dropdown-menu {
display: block;
@ -30,12 +304,37 @@ body {
.navbar-nav > li > a {
font-size: 14px;
}
#header-navbar li.dropdown ul.dropdown-menu {
min-width: 100px;
}
.dropdown-menu > li > a {
font-size: 13px;
font-size: 14px;
padding: 5px 20px;
}
.dropdown-menu {
border-radius: 2px;
border: 0px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
padding: 5px 0px;
}
.dropdown-menu li a {
padding-top: 10px !important;
padding-bottom: 10px;
}
.dropdown-menu > li > a {
font-weight: 400;
color: #444;
padding: 5px 15px;
padding-bottom: 10px;
}
.dropdown-menu > li > a:hover,
.dropdown-menu > li > a:focus {
text-decoration: none;
color: #777;
background: rgba(0, 0, 0, 0.05);
}
.toast-top-center {
top: 50px;
top: 60px;
}
#toast-container > div {
-webkit-box-shadow: none;
@ -149,9 +448,6 @@ input.selectpage {
.checkbox > label > input {
margin: 2px 0 0;
}
#header-navbar li.dropdown ul.dropdown-menu {
min-width: 94px;
}
form.form-horizontal .control-label {
font-weight: normal;
}
@ -282,7 +578,7 @@ form.form-horizontal .control-label {
.nav-pills > li.active > a {
border: none;
color: #fff;
background: #46c37b;
background: #007bff;
-webkit-transition: all 0.3s ease;
-moz-transition: all 0.3s ease;
-o-transition: all 0.3s ease;
@ -309,7 +605,6 @@ form.form-horizontal .control-label {
width: 110px;
display: inline-block;
text-decoration: none;
font-weight: bold;
}
/* 弹窗中的表单 */
.form-layer {
@ -413,7 +708,7 @@ footer.footer .copyright a:hover {
font-size: 16px;
text-align: center;
color: #616161;
background-color: #ececec;
background-color: #efefef;
-webkit-transition: all 0.3s ease;
-moz-transition: all 0.3s ease;
-o-transition: all 0.3s ease;
@ -436,9 +731,6 @@ footer.footer .copyright a:hover {
.login-section .login-main {
padding: 40px 45px 20px 45px;
}
.login-section .control-label {
font-size: 13px;
}
.login-section .n-bootstrap .form-group {
position: relative;
}
@ -461,7 +753,7 @@ main.content {
overflow: auto;
padding: 15px;
padding-top: 20px;
min-height: calc(100vh - 125px);
min-height: calc(100vh - 135px);
}
.sidenav {
padding: 20px 0 10px 0;
@ -508,11 +800,11 @@ main.content {
padding: 10px 15px 10px 35px;
}
.sidenav .list-group .list-group-item.active {
border-left: 2px solid #46c37b;
border-left: 2px solid #007bff;
background-color: rgba(245, 245, 245, 0.38);
}
.sidenav .list-group .list-group-item.active > a {
color: #46c37b;
color: #007bff;
}
.nav li .avatar-text,
.nav li .avatar-img {
@ -594,11 +886,113 @@ main.content {
font-size: 14px;
}
.jumpto input {
height: 31px;
width: 50px;
margin-left: 5px;
margin-right: 5px;
text-align: center;
display: inline-block;
}
.fixed-columns,
.fixed-columns-right {
position: absolute;
top: 0;
height: 100%;
min-height: 41px;
background-color: #fff;
box-sizing: border-box;
z-index: 2;
box-shadow: 0 -1px 8px rgba(0, 0, 0, 0.08);
}
.fixed-columns .fixed-table-body,
.fixed-columns-right .fixed-table-body {
min-height: 41px;
overflow-x: hidden !important;
}
.fixed-columns {
left: 0;
}
.fixed-columns-right {
right: 0;
box-shadow: -1px 0 8px rgba(0, 0, 0, 0.08);
}
.bootstrap-tagsinput {
background-color: #fff;
border: 1px solid #ccc;
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
display: inline-block;
padding: 4px 6px;
margin-bottom: 10px;
color: #555;
vertical-align: middle;
width: 100%;
line-height: 22px;
cursor: text;
}
.bootstrap-tagsinput input {
border: none;
box-shadow: none;
outline: none;
background-color: transparent;
padding: 0;
margin: 0;
font-size: 13px;
width: 80px;
max-width: inherit;
}
.bootstrap-tagsinput input:focus {
border: none;
box-shadow: none;
}
.bootstrap-tagsinput .tagsinput-text {
display: inline-block;
overflow: auto;
visibility: hidden;
height: 1px;
position: absolute;
bottom: -1px;
left: 0;
}
.bootstrap-tagsinput .tag {
margin-right: 2px;
color: white;
}
.bootstrap-tagsinput .tag [data-role="remove"] {
margin-left: 5px;
cursor: pointer;
}
.bootstrap-tagsinput .tag [data-role="remove"]:after {
content: "x";
padding: 0px 2px;
}
.bootstrap-tagsinput .tag [data-role="remove"]:hover {
background-color: rgba(255, 255, 255, 0.16);
}
.autocomplete-suggestions {
border-radius: 2px;
background: #FFF;
overflow: auto;
min-width: 200px;
-webkit-box-shadow: 0px 20px 30px rgba(83, 88, 93, 0.05), 0px 0px 30px rgba(83, 88, 93, 0.1);
-moz-box-shadow: 0px 20px 30px rgba(83, 88, 93, 0.05), 0px 0px 30px rgba(83, 88, 93, 0.1);
box-shadow: 0px 20px 30px rgba(83, 88, 93, 0.05), 0px 0px 30px rgba(83, 88, 93, 0.1);
}
.autocomplete-suggestions strong {
font-weight: normal;
color: red;
}
.autocomplete-suggestions .autocomplete-suggestion {
padding: 5px 10px;
white-space: nowrap;
overflow: hidden;
}
.autocomplete-suggestions .autocomplete-selected {
background: #F0F0F0;
}
.autocomplete-suggestions .autocomplete-group {
padding: 5px 10px;
}
.autocomplete-suggestions .autocomplete-group strong {
display: block;
border-bottom: 1px solid #ddd;
}
/*# sourceMappingURL=frontend.css.map */

File diff suppressed because one or more lines are too long

View File

@ -1 +0,0 @@
/*# sourceMappingURL=lesshat.css.map */

View File

@ -96,9 +96,6 @@
color: #a19fcb;
background: #57539c;
}
.skin-blue .sidebar-menu > li > a {
border-left: 3px solid transparent;
}
.skin-blue .sidebar-menu > li:hover > a,
.skin-blue .sidebar-menu > li.active > a {
color: #fff;
@ -163,6 +160,15 @@
border-bottom-right-radius: 2px;
border-bottom-left-radius: 0;
}
.skin-blue .sidebar-menu > li > a {
border-left: 3px solid transparent;
padding-left: 12px;
}
@media (min-width: 768px) {
.skin-blue.sidebar-mini.sidebar-collapse .sidebar-menu > li:hover > a > span:not(.pull-right) {
margin-left: -3px;
}
}
.skin-blue .sidebar-form input[type="text"]::-moz-placeholder {
color: #fff;
opacity: 1;
@ -304,9 +310,6 @@
color: #848484;
background: #f9fafc;
}
.skin-blue-light .sidebar-menu > li > a {
border-left: 3px solid transparent;
}
.skin-blue-light .sidebar-menu > li:hover > a,
.skin-blue-light .sidebar-menu > li.active > a {
color: #000;
@ -374,6 +377,15 @@
border-left: 1px solid #d2d6de;
}
}
.skin-blue-light .sidebar-menu > li > a {
border-left: 3px solid transparent;
padding-left: 12px;
}
@media (min-width: 768px) {
.skin-blue-light.sidebar-mini.sidebar-collapse .sidebar-menu > li:hover > a > span:not(.pull-right) {
margin-left: -3px;
}
}
.skin-blue-light .main-footer {
border-top-color: #d2d6de;
}
@ -496,9 +508,6 @@
color: #a19fcb;
background: #57539c;
}
.skin-black .sidebar-menu > li > a {
border-left: 3px solid transparent;
}
.skin-black .sidebar-menu > li:hover > a,
.skin-black .sidebar-menu > li.active > a {
color: #fff;
@ -563,6 +572,15 @@
border-bottom-right-radius: 2px;
border-bottom-left-radius: 0;
}
.skin-black .sidebar-menu > li > a {
border-left: 3px solid transparent;
padding-left: 12px;
}
@media (min-width: 768px) {
.skin-black.sidebar-mini.sidebar-collapse .sidebar-menu > li:hover > a > span:not(.pull-right) {
margin-left: -3px;
}
}
@media (max-width: 767px) {
.skin-black.multiplenav .main-header .navbar {
background-color: #605ca8;
@ -708,9 +726,6 @@
color: #848484;
background: #f9fafc;
}
.skin-black-light .sidebar-menu > li > a {
border-left: 3px solid transparent;
}
.skin-black-light .sidebar-menu > li:hover > a,
.skin-black-light .sidebar-menu > li.active > a {
color: #000;
@ -778,6 +793,15 @@
border-left: 1px solid #d2d6de;
}
}
.skin-black-light .sidebar-menu > li > a {
border-left: 3px solid transparent;
padding-left: 12px;
}
@media (min-width: 768px) {
.skin-black-light.sidebar-mini.sidebar-collapse .sidebar-menu > li:hover > a > span:not(.pull-right) {
margin-left: -3px;
}
}
.skin-black-light .main-sidebar {
-webkit-box-shadow: 7px 0 14px rgba(0, 0, 0, 0.03);
box-shadow: 7px 0 14px rgba(0, 0, 0, 0.03);
@ -887,9 +911,6 @@
color: #a19fcb;
background: #57539c;
}
.skin-green .sidebar-menu > li > a {
border-left: 3px solid transparent;
}
.skin-green .sidebar-menu > li:hover > a,
.skin-green .sidebar-menu > li.active > a {
color: #fff;
@ -954,6 +975,15 @@
border-bottom-right-radius: 2px;
border-bottom-left-radius: 0;
}
.skin-green .sidebar-menu > li > a {
border-left: 3px solid transparent;
padding-left: 12px;
}
@media (min-width: 768px) {
.skin-green.sidebar-mini.sidebar-collapse .sidebar-menu > li:hover > a > span:not(.pull-right) {
margin-left: -3px;
}
}
@media (max-width: 767px) {
.skin-green.multiplenav .sidebar .mobilenav a.btn-app {
background: #807dba;
@ -1050,9 +1080,6 @@
color: #848484;
background: #f9fafc;
}
.skin-green-light .sidebar-menu > li > a {
border-left: 3px solid transparent;
}
.skin-green-light .sidebar-menu > li:hover > a,
.skin-green-light .sidebar-menu > li.active > a {
color: #000;
@ -1120,6 +1147,15 @@
border-left: 1px solid #d2d6de;
}
}
.skin-green-light .sidebar-menu > li > a {
border-left: 3px solid transparent;
padding-left: 12px;
}
@media (min-width: 768px) {
.skin-green-light.sidebar-mini.sidebar-collapse .sidebar-menu > li:hover > a > span:not(.pull-right) {
margin-left: -3px;
}
}
.skin-green-light .main-sidebar {
-webkit-box-shadow: 7px 0 14px rgba(0, 0, 0, 0.03);
box-shadow: 7px 0 14px rgba(0, 0, 0, 0.03);
@ -1143,10 +1179,10 @@
* ---------
*/
.skin-red .main-header {
background-color: #e74c3c;
background-color: #f75444;
}
.skin-red .main-header .navbar {
background-color: #e74c3c;
background-color: #f75444;
}
.skin-red .main-header .navbar .nav > li > a {
color: #fff;
@ -1175,7 +1211,7 @@
color: #fff;
}
.skin-red .main-header .navbar .sidebar-toggle:hover {
background-color: #e43725;
background-color: #f63e2c;
}
@media (max-width: 767px) {
.skin-red .main-header .navbar .dropdown-menu li.divider {
@ -1185,30 +1221,30 @@
color: #fff;
}
.skin-red .main-header .navbar .dropdown-menu li a:hover {
background: #e43725;
background: #f63e2c;
}
}
.skin-red .main-header .logo {
background-color: #e43725;
background-color: #f63e2c;
color: #fff;
border-bottom: 0 solid transparent;
}
.skin-red .main-header .logo:hover {
background-color: #e43321;
background-color: #f63927;
}
@media (max-width: 767px) {
.skin-red .main-header .logo {
background-color: #e74c3c;
background-color: #f75444;
color: #fff;
border-bottom: 0 solid transparent;
border-right: none;
}
.skin-red .main-header .logo:hover {
background-color: #e64837;
background-color: #f7503f;
}
}
.skin-red .main-header li.user-header {
background-color: #e74c3c;
background-color: #f75444;
}
.skin-red .content-header {
background: transparent;
@ -1229,14 +1265,11 @@
color: #a19fcb;
background: #57539c;
}
.skin-red .sidebar-menu > li > a {
border-left: 3px solid transparent;
}
.skin-red .sidebar-menu > li:hover > a,
.skin-red .sidebar-menu > li.active > a {
color: #fff;
background: #5b57a3;
border-left-color: #e74c3c;
border-left-color: #f75444;
}
.skin-red .sidebar-menu > li > .treeview-menu {
background: #555299;
@ -1296,13 +1329,22 @@
border-bottom-right-radius: 2px;
border-bottom-left-radius: 0;
}
.skin-red .sidebar-menu > li > a {
border-left: 3px solid transparent;
padding-left: 12px;
}
@media (min-width: 768px) {
.skin-red.sidebar-mini.sidebar-collapse .sidebar-menu > li:hover > a > span:not(.pull-right) {
margin-left: -3px;
}
}
@media (max-width: 767px) {
.skin-red.multiplenav .sidebar .mobilenav a.btn-app {
background: #807dba;
color: #fff;
}
.skin-red.multiplenav .sidebar .mobilenav a.btn-app.active {
background: #e74c3c;
background: #f75444;
color: #fff;
}
}
@ -1311,10 +1353,10 @@
* ---------
*/
.skin-red-light .main-header {
background-color: #e74c3c;
background-color: #f75444;
}
.skin-red-light .main-header .navbar {
background-color: #e74c3c;
background-color: #f75444;
}
.skin-red-light .main-header .navbar .nav > li > a {
color: #fff;
@ -1343,7 +1385,7 @@
color: #fff;
}
.skin-red-light .main-header .navbar .sidebar-toggle:hover {
background-color: #e43725;
background-color: #f63e2c;
}
@media (max-width: 767px) {
.skin-red-light .main-header .navbar .dropdown-menu li.divider {
@ -1353,19 +1395,19 @@
color: #fff;
}
.skin-red-light .main-header .navbar .dropdown-menu li a:hover {
background: #e43725;
background: #f63e2c;
}
}
.skin-red-light .main-header .logo {
background-color: #e74c3c;
background-color: #f75444;
color: #fff;
border-bottom: 0 solid transparent;
}
.skin-red-light .main-header .logo:hover {
background-color: #e64837;
background-color: #f7503f;
}
.skin-red-light .main-header li.user-header {
background-color: #e74c3c;
background-color: #f75444;
}
.skin-red-light .content-header {
background: transparent;
@ -1392,17 +1434,14 @@
color: #848484;
background: #f9fafc;
}
.skin-red-light .sidebar-menu > li > a {
border-left: 3px solid transparent;
}
.skin-red-light .sidebar-menu > li:hover > a,
.skin-red-light .sidebar-menu > li.active > a {
color: #000;
background: #f4f4f5;
border-left-color: #e74c3c;
border-left-color: #f75444;
}
.skin-red-light .sidebar-menu > li.active {
border-left-color: #e74c3c;
border-left-color: #f75444;
}
.skin-red-light .sidebar-menu > li > .treeview-menu {
background: #f4f4f5;
@ -1462,6 +1501,15 @@
border-left: 1px solid #d2d6de;
}
}
.skin-red-light .sidebar-menu > li > a {
border-left: 3px solid transparent;
padding-left: 12px;
}
@media (min-width: 768px) {
.skin-red-light.sidebar-mini.sidebar-collapse .sidebar-menu > li:hover > a > span:not(.pull-right) {
margin-left: -3px;
}
}
.skin-red-light .main-sidebar {
-webkit-box-shadow: 7px 0 14px rgba(0, 0, 0, 0.03);
box-shadow: 7px 0 14px rgba(0, 0, 0, 0.03);
@ -1476,7 +1524,7 @@
color: #757575;
}
.skin-red-light.multiplenav .sidebar .mobilenav a.btn-app.active {
background: #e74c3c;
background: #f75444;
color: #fff;
}
}
@ -1571,9 +1619,6 @@
color: #a19fcb;
background: #57539c;
}
.skin-yellow .sidebar-menu > li > a {
border-left: 3px solid transparent;
}
.skin-yellow .sidebar-menu > li:hover > a,
.skin-yellow .sidebar-menu > li.active > a {
color: #fff;
@ -1638,6 +1683,15 @@
border-bottom-right-radius: 2px;
border-bottom-left-radius: 0;
}
.skin-yellow .sidebar-menu > li > a {
border-left: 3px solid transparent;
padding-left: 12px;
}
@media (min-width: 768px) {
.skin-yellow.sidebar-mini.sidebar-collapse .sidebar-menu > li:hover > a > span:not(.pull-right) {
margin-left: -3px;
}
}
@media (max-width: 767px) {
.skin-yellow.multiplenav .sidebar .mobilenav a.btn-app {
background: #807dba;
@ -1734,9 +1788,6 @@
color: #848484;
background: #f9fafc;
}
.skin-yellow-light .sidebar-menu > li > a {
border-left: 3px solid transparent;
}
.skin-yellow-light .sidebar-menu > li:hover > a,
.skin-yellow-light .sidebar-menu > li.active > a {
color: #000;
@ -1804,6 +1855,15 @@
border-left: 1px solid #d2d6de;
}
}
.skin-yellow-light .sidebar-menu > li > a {
border-left: 3px solid transparent;
padding-left: 12px;
}
@media (min-width: 768px) {
.skin-yellow-light.sidebar-mini.sidebar-collapse .sidebar-menu > li:hover > a > span:not(.pull-right) {
margin-left: -3px;
}
}
.skin-yellow-light .main-sidebar {
-webkit-box-shadow: 7px 0 14px rgba(0, 0, 0, 0.03);
box-shadow: 7px 0 14px rgba(0, 0, 0, 0.03);
@ -1910,9 +1970,6 @@
color: #a19fcb;
background: #57539c;
}
.skin-purple .sidebar-menu > li > a {
border-left: 3px solid transparent;
}
.skin-purple .sidebar-menu > li:hover > a,
.skin-purple .sidebar-menu > li.active > a {
color: #fff;
@ -1977,6 +2034,15 @@
border-bottom-right-radius: 2px;
border-bottom-left-radius: 0;
}
.skin-purple .sidebar-menu > li > a {
border-left: 3px solid transparent;
padding-left: 12px;
}
@media (min-width: 768px) {
.skin-purple.sidebar-mini.sidebar-collapse .sidebar-menu > li:hover > a > span:not(.pull-right) {
margin-left: -3px;
}
}
.skin-purple .sidebar-form input[type="text"]::-moz-placeholder {
color: #fff;
opacity: 1;
@ -2121,9 +2187,6 @@
color: #848484;
background: #f9fafc;
}
.skin-purple-light .sidebar-menu > li > a {
border-left: 3px solid transparent;
}
.skin-purple-light .sidebar-menu > li:hover > a,
.skin-purple-light .sidebar-menu > li.active > a {
color: #000;
@ -2191,6 +2254,15 @@
border-left: 1px solid #d2d6de;
}
}
.skin-purple-light .sidebar-menu > li > a {
border-left: 3px solid transparent;
padding-left: 12px;
}
@media (min-width: 768px) {
.skin-purple-light.sidebar-mini.sidebar-collapse .sidebar-menu > li:hover > a > span:not(.pull-right) {
margin-left: -3px;
}
}
.skin-purple-light .main-sidebar {
-webkit-box-shadow: 7px 0 14px rgba(0, 0, 0, 0.03);
box-shadow: 7px 0 14px rgba(0, 0, 0, 0.03);
@ -2327,9 +2399,6 @@
color: #a19fcb;
background: #57539c;
}
.skin-black-blue .sidebar-menu > li > a {
border-left: 3px solid transparent;
}
.skin-black-blue .sidebar-menu > li:hover > a,
.skin-black-blue .sidebar-menu > li.active > a {
color: #fff;
@ -2400,9 +2469,6 @@
.skin-black-blue .treeview-menu > li.active > a {
background-color: #f5549f;
}
.skin-black-blue .sidebar-menu > li > a {
border-left: 3px solid transparent;
}
.skin-black-blue .sidebar-menu > li.active > a {
color: #fff;
background: #f5549f;
@ -2569,9 +2635,6 @@
color: #a19fcb;
background: #57539c;
}
.skin-black-purple .sidebar-menu > li > a {
border-left: 3px solid transparent;
}
.skin-black-purple .sidebar-menu > li:hover > a,
.skin-black-purple .sidebar-menu > li.active > a {
color: #fff;
@ -2642,9 +2705,6 @@
.skin-black-purple .treeview-menu > li.active > a {
background-color: #f5549f;
}
.skin-black-purple .sidebar-menu > li > a {
border-left: 3px solid transparent;
}
.skin-black-purple .sidebar-menu > li.active > a {
color: #fff;
background: #f5549f;
@ -2811,9 +2871,6 @@
color: #a19fcb;
background: #57539c;
}
.skin-black-green .sidebar-menu > li > a {
border-left: 3px solid transparent;
}
.skin-black-green .sidebar-menu > li:hover > a,
.skin-black-green .sidebar-menu > li.active > a {
color: #fff;
@ -2884,9 +2941,6 @@
.skin-black-green .treeview-menu > li.active > a {
background-color: #f5549f;
}
.skin-black-green .sidebar-menu > li > a {
border-left: 3px solid transparent;
}
.skin-black-green .sidebar-menu > li.active > a {
color: #fff;
background: #f5549f;
@ -3053,9 +3107,6 @@
color: #a19fcb;
background: #57539c;
}
.skin-black-red .sidebar-menu > li > a {
border-left: 3px solid transparent;
}
.skin-black-red .sidebar-menu > li:hover > a,
.skin-black-red .sidebar-menu > li.active > a {
color: #fff;
@ -3126,9 +3177,6 @@
.skin-black-red .treeview-menu > li.active > a {
background-color: #f5549f;
}
.skin-black-red .sidebar-menu > li > a {
border-left: 3px solid transparent;
}
.skin-black-red .sidebar-menu > li.active > a {
color: #fff;
background: #f5549f;
@ -3295,9 +3343,6 @@
color: #a19fcb;
background: #57539c;
}
.skin-black-yellow .sidebar-menu > li > a {
border-left: 3px solid transparent;
}
.skin-black-yellow .sidebar-menu > li:hover > a,
.skin-black-yellow .sidebar-menu > li.active > a {
color: #fff;
@ -3368,9 +3413,6 @@
.skin-black-yellow .treeview-menu > li.active > a {
background-color: #f5549f;
}
.skin-black-yellow .sidebar-menu > li > a {
border-left: 3px solid transparent;
}
.skin-black-yellow .sidebar-menu > li.active > a {
color: #fff;
background: #f5549f;
@ -3537,9 +3579,6 @@
color: #a19fcb;
background: #57539c;
}
.skin-black-pink .sidebar-menu > li > a {
border-left: 3px solid transparent;
}
.skin-black-pink .sidebar-menu > li:hover > a,
.skin-black-pink .sidebar-menu > li.active > a {
color: #fff;
@ -3610,9 +3649,6 @@
.skin-black-pink .treeview-menu > li.active > a {
background-color: #f5549f;
}
.skin-black-pink .sidebar-menu > li > a {
border-left: 3px solid transparent;
}
.skin-black-pink .sidebar-menu > li.active > a {
color: #fff;
background: #f5549f;

View File

@ -116,9 +116,6 @@
color: #4b646f;
background: #1a2226;
}
.skin-black-blue .sidebar-menu > li > a {
border-left: 3px solid transparent;
}
.skin-black-blue .sidebar-menu > li:hover > a,
.skin-black-blue .sidebar-menu > li.active > a {
color: #fff;
@ -189,9 +186,6 @@
.skin-black-blue .treeview-menu > li.active > a {
background-color: #4e73df;
}
.skin-black-blue .sidebar-menu > li > a {
border-left: 3px solid transparent;
}
.skin-black-blue .sidebar-menu > li.active > a {
color: #fff;
background: #4e73df;

View File

@ -116,9 +116,6 @@
color: #4b646f;
background: #1a2226;
}
.skin-black-green .sidebar-menu > li > a {
border-left: 3px solid transparent;
}
.skin-black-green .sidebar-menu > li:hover > a,
.skin-black-green .sidebar-menu > li.active > a {
color: #fff;
@ -189,9 +186,6 @@
.skin-black-green .treeview-menu > li.active > a {
background-color: #18bc9c;
}
.skin-black-green .sidebar-menu > li > a {
border-left: 3px solid transparent;
}
.skin-black-green .sidebar-menu > li.active > a {
color: #fff;
background: #18bc9c;

View File

@ -99,9 +99,6 @@
color: #848484;
background: #f9fafc;
}
.skin-black-light .sidebar-menu > li > a {
border-left: 3px solid transparent;
}
.skin-black-light .sidebar-menu > li:hover > a,
.skin-black-light .sidebar-menu > li.active > a {
color: #000;
@ -169,6 +166,15 @@
border-left: 1px solid #d2d6de;
}
}
.skin-black-light .sidebar-menu > li > a {
border-left: 3px solid transparent;
padding-left: 12px;
}
@media (min-width: 768px) {
.skin-black-light.sidebar-mini.sidebar-collapse .sidebar-menu > li:hover > a > span:not(.pull-right) {
margin-left: -3px;
}
}
.skin-black-light .main-sidebar {
-webkit-box-shadow: 7px 0 14px rgba(0, 0, 0, 0.03);
box-shadow: 7px 0 14px rgba(0, 0, 0, 0.03);

View File

@ -116,9 +116,6 @@
color: #4b646f;
background: #1a2226;
}
.skin-black-pink .sidebar-menu > li > a {
border-left: 3px solid transparent;
}
.skin-black-pink .sidebar-menu > li:hover > a,
.skin-black-pink .sidebar-menu > li.active > a {
color: #fff;
@ -189,9 +186,6 @@
.skin-black-pink .treeview-menu > li.active > a {
background-color: #f5549f;
}
.skin-black-pink .sidebar-menu > li > a {
border-left: 3px solid transparent;
}
.skin-black-pink .sidebar-menu > li.active > a {
color: #fff;
background: #f5549f;

View File

@ -116,9 +116,6 @@
color: #4b646f;
background: #1a2226;
}
.skin-black-purple .sidebar-menu > li > a {
border-left: 3px solid transparent;
}
.skin-black-purple .sidebar-menu > li:hover > a,
.skin-black-purple .sidebar-menu > li.active > a {
color: #fff;
@ -189,9 +186,6 @@
.skin-black-purple .treeview-menu > li.active > a {
background-color: #605ca8;
}
.skin-black-purple .sidebar-menu > li > a {
border-left: 3px solid transparent;
}
.skin-black-purple .sidebar-menu > li.active > a {
color: #fff;
background: #605ca8;

View File

@ -116,9 +116,6 @@
color: #4b646f;
background: #1a2226;
}
.skin-black-red .sidebar-menu > li > a {
border-left: 3px solid transparent;
}
.skin-black-red .sidebar-menu > li:hover > a,
.skin-black-red .sidebar-menu > li.active > a {
color: #fff;
@ -187,15 +184,12 @@
padding-left: 18px;
}
.skin-black-red .treeview-menu > li.active > a {
background-color: #e74c3c;
}
.skin-black-red .sidebar-menu > li > a {
border-left: 3px solid transparent;
background-color: #f75444;
}
.skin-black-red .sidebar-menu > li.active > a {
color: #fff;
background: #e74c3c;
border-left-color: #e74c3c;
background: #f75444;
border-left-color: #f75444;
}
.skin-black-red .sidebar-menu > li:hover > a {
border-left-color: transparent;
@ -220,11 +214,11 @@
.skin-black-red.sidebar-collapse .sidebar-menu li:hover > a,
.skin-black-red.sidebar-collapse .sidebar-menu li.active > a {
color: #fff;
background: #e74c3c;
background: #f75444;
}
.skin-black-red.sidebar-collapse .sidebar-menu .treeview-menu li.active > a {
color: #fff;
background: #e74c3c;
background: #f75444;
}
.skin-black-red.sidebar-collapse .sidebar-menu .treeview-menu li.treeview > a {
background: transparent;
@ -236,7 +230,7 @@
color: #fff;
}
.skin-black-red.multiplenav .sidebar .mobilenav a.btn-app.active {
background: #e74c3c;
background: #f75444;
color: #fff;
}
}

View File

@ -116,9 +116,6 @@
color: #4b646f;
background: #1a2226;
}
.skin-black-yellow .sidebar-menu > li > a {
border-left: 3px solid transparent;
}
.skin-black-yellow .sidebar-menu > li:hover > a,
.skin-black-yellow .sidebar-menu > li.active > a {
color: #fff;
@ -189,9 +186,6 @@
.skin-black-yellow .treeview-menu > li.active > a {
background-color: #f39c12;
}
.skin-black-yellow .sidebar-menu > li > a {
border-left: 3px solid transparent;
}
.skin-black-yellow .sidebar-menu > li.active > a {
color: #fff;
background: #f39c12;

View File

@ -99,9 +99,6 @@
color: #4b646f;
background: #1a2226;
}
.skin-black .sidebar-menu > li > a {
border-left: 3px solid transparent;
}
.skin-black .sidebar-menu > li:hover > a,
.skin-black .sidebar-menu > li.active > a {
color: #fff;
@ -166,6 +163,15 @@
border-bottom-right-radius: 2px;
border-bottom-left-radius: 0;
}
.skin-black .sidebar-menu > li > a {
border-left: 3px solid transparent;
padding-left: 12px;
}
@media (min-width: 768px) {
.skin-black.sidebar-mini.sidebar-collapse .sidebar-menu > li:hover > a > span:not(.pull-right) {
margin-left: -3px;
}
}
@media (max-width: 767px) {
.skin-black.multiplenav .main-header .navbar {
background-color: #222d32;

View File

@ -81,9 +81,6 @@
color: #848484;
background: #f9fafc;
}
.skin-blue-light .sidebar-menu > li > a {
border-left: 3px solid transparent;
}
.skin-blue-light .sidebar-menu > li:hover > a,
.skin-blue-light .sidebar-menu > li.active > a {
color: #000;
@ -151,6 +148,15 @@
border-left: 1px solid #d2d6de;
}
}
.skin-blue-light .sidebar-menu > li > a {
border-left: 3px solid transparent;
padding-left: 12px;
}
@media (min-width: 768px) {
.skin-blue-light.sidebar-mini.sidebar-collapse .sidebar-menu > li:hover > a > span:not(.pull-right) {
margin-left: -3px;
}
}
.skin-blue-light .main-footer {
border-top-color: #d2d6de;
}

View File

@ -96,9 +96,6 @@
color: #a4b7ef;
background: #3d65dc;
}
.skin-blue .sidebar-menu > li > a {
border-left: 3px solid transparent;
}
.skin-blue .sidebar-menu > li:hover > a,
.skin-blue .sidebar-menu > li.active > a {
color: #fff;
@ -163,6 +160,15 @@
border-bottom-right-radius: 2px;
border-bottom-left-radius: 0;
}
.skin-blue .sidebar-menu > li > a {
border-left: 3px solid transparent;
padding-left: 12px;
}
@media (min-width: 768px) {
.skin-blue.sidebar-mini.sidebar-collapse .sidebar-menu > li:hover > a > span:not(.pull-right) {
margin-left: -3px;
}
}
.skin-blue .sidebar-form input[type="text"]::-moz-placeholder {
color: #fff;
opacity: 1;

View File

@ -84,9 +84,6 @@
color: #848484;
background: #f9fafc;
}
.skin-green-light .sidebar-menu > li > a {
border-left: 3px solid transparent;
}
.skin-green-light .sidebar-menu > li:hover > a,
.skin-green-light .sidebar-menu > li.active > a {
color: #000;
@ -154,6 +151,15 @@
border-left: 1px solid #d2d6de;
}
}
.skin-green-light .sidebar-menu > li > a {
border-left: 3px solid transparent;
padding-left: 12px;
}
@media (min-width: 768px) {
.skin-green-light.sidebar-mini.sidebar-collapse .sidebar-menu > li:hover > a > span:not(.pull-right) {
margin-left: -3px;
}
}
.skin-green-light .main-sidebar {
-webkit-box-shadow: 7px 0 14px rgba(0, 0, 0, 0.03);
box-shadow: 7px 0 14px rgba(0, 0, 0, 0.03);

View File

@ -89,9 +89,6 @@
color: #4b646f;
background: #1a2226;
}
.skin-green .sidebar-menu > li > a {
border-left: 3px solid transparent;
}
.skin-green .sidebar-menu > li:hover > a,
.skin-green .sidebar-menu > li.active > a {
color: #fff;
@ -156,6 +153,15 @@
border-bottom-right-radius: 2px;
border-bottom-left-radius: 0;
}
.skin-green .sidebar-menu > li > a {
border-left: 3px solid transparent;
padding-left: 12px;
}
@media (min-width: 768px) {
.skin-green.sidebar-mini.sidebar-collapse .sidebar-menu > li:hover > a > span:not(.pull-right) {
margin-left: -3px;
}
}
@media (max-width: 767px) {
.skin-green.multiplenav .sidebar .mobilenav a.btn-app {
background: #374850;

View File

@ -84,9 +84,6 @@
color: #848484;
background: #f9fafc;
}
.skin-purple-light .sidebar-menu > li > a {
border-left: 3px solid transparent;
}
.skin-purple-light .sidebar-menu > li:hover > a,
.skin-purple-light .sidebar-menu > li.active > a {
color: #000;
@ -154,6 +151,15 @@
border-left: 1px solid #d2d6de;
}
}
.skin-purple-light .sidebar-menu > li > a {
border-left: 3px solid transparent;
padding-left: 12px;
}
@media (min-width: 768px) {
.skin-purple-light.sidebar-mini.sidebar-collapse .sidebar-menu > li:hover > a > span:not(.pull-right) {
margin-left: -3px;
}
}
.skin-purple-light .main-sidebar {
-webkit-box-shadow: 7px 0 14px rgba(0, 0, 0, 0.03);
box-shadow: 7px 0 14px rgba(0, 0, 0, 0.03);

View File

@ -86,9 +86,6 @@
color: #a19fcb;
background: #57539c;
}
.skin-purple .sidebar-menu > li > a {
border-left: 3px solid transparent;
}
.skin-purple .sidebar-menu > li:hover > a,
.skin-purple .sidebar-menu > li.active > a {
color: #fff;
@ -153,6 +150,15 @@
border-bottom-right-radius: 2px;
border-bottom-left-radius: 0;
}
.skin-purple .sidebar-menu > li > a {
border-left: 3px solid transparent;
padding-left: 12px;
}
@media (min-width: 768px) {
.skin-purple.sidebar-mini.sidebar-collapse .sidebar-menu > li:hover > a > span:not(.pull-right) {
margin-left: -3px;
}
}
.skin-purple .sidebar-form input[type="text"]::-moz-placeholder {
color: #fff;
opacity: 1;

View File

@ -3,10 +3,10 @@
* ---------
*/
.skin-red-light .main-header {
background-color: #e74c3c;
background-color: #f75444;
}
.skin-red-light .main-header .navbar {
background-color: #e74c3c;
background-color: #f75444;
}
.skin-red-light .main-header .navbar .nav > li > a {
color: #fff;
@ -35,7 +35,7 @@
color: #fff;
}
.skin-red-light .main-header .navbar .sidebar-toggle:hover {
background-color: #e43725;
background-color: #f63e2c;
}
@media (max-width: 767px) {
.skin-red-light .main-header .navbar .dropdown-menu li.divider {
@ -45,19 +45,19 @@
color: #fff;
}
.skin-red-light .main-header .navbar .dropdown-menu li a:hover {
background: #e43725;
background: #f63e2c;
}
}
.skin-red-light .main-header .logo {
background-color: #e74c3c;
background-color: #f75444;
color: #fff;
border-bottom: 0 solid transparent;
}
.skin-red-light .main-header .logo:hover {
background-color: #e64837;
background-color: #f7503f;
}
.skin-red-light .main-header li.user-header {
background-color: #e74c3c;
background-color: #f75444;
}
.skin-red-light .content-header {
background: transparent;
@ -84,17 +84,14 @@
color: #848484;
background: #f9fafc;
}
.skin-red-light .sidebar-menu > li > a {
border-left: 3px solid transparent;
}
.skin-red-light .sidebar-menu > li:hover > a,
.skin-red-light .sidebar-menu > li.active > a {
color: #000;
background: #f4f4f5;
border-left-color: #e74c3c;
border-left-color: #f75444;
}
.skin-red-light .sidebar-menu > li.active {
border-left-color: #e74c3c;
border-left-color: #f75444;
}
.skin-red-light .sidebar-menu > li > .treeview-menu {
background: #f4f4f5;
@ -154,6 +151,15 @@
border-left: 1px solid #d2d6de;
}
}
.skin-red-light .sidebar-menu > li > a {
border-left: 3px solid transparent;
padding-left: 12px;
}
@media (min-width: 768px) {
.skin-red-light.sidebar-mini.sidebar-collapse .sidebar-menu > li:hover > a > span:not(.pull-right) {
margin-left: -3px;
}
}
.skin-red-light .main-sidebar {
-webkit-box-shadow: 7px 0 14px rgba(0, 0, 0, 0.03);
box-shadow: 7px 0 14px rgba(0, 0, 0, 0.03);
@ -168,7 +174,7 @@
color: #757575;
}
.skin-red-light.multiplenav .sidebar .mobilenav a.btn-app.active {
background: #e74c3c;
background: #f75444;
color: #fff;
}
}

View File

@ -3,10 +3,10 @@
* ---------
*/
.skin-red .main-header {
background-color: #e74c3c;
background-color: #f75444;
}
.skin-red .main-header .navbar {
background-color: #e74c3c;
background-color: #f75444;
}
.skin-red .main-header .navbar .nav > li > a {
color: #fff;
@ -35,7 +35,7 @@
color: #fff;
}
.skin-red .main-header .navbar .sidebar-toggle:hover {
background-color: #e43725;
background-color: #f63e2c;
}
@media (max-width: 767px) {
.skin-red .main-header .navbar .dropdown-menu li.divider {
@ -45,30 +45,30 @@
color: #fff;
}
.skin-red .main-header .navbar .dropdown-menu li a:hover {
background: #e43725;
background: #f63e2c;
}
}
.skin-red .main-header .logo {
background-color: #e43725;
background-color: #f63e2c;
color: #fff;
border-bottom: 0 solid transparent;
}
.skin-red .main-header .logo:hover {
background-color: #e43321;
background-color: #f63927;
}
@media (max-width: 767px) {
.skin-red .main-header .logo {
background-color: #e74c3c;
background-color: #f75444;
color: #fff;
border-bottom: 0 solid transparent;
border-right: none;
}
.skin-red .main-header .logo:hover {
background-color: #e64837;
background-color: #f7503f;
}
}
.skin-red .main-header li.user-header {
background-color: #e74c3c;
background-color: #f75444;
}
.skin-red .content-header {
background: transparent;
@ -89,14 +89,11 @@
color: #4b646f;
background: #1a2226;
}
.skin-red .sidebar-menu > li > a {
border-left: 3px solid transparent;
}
.skin-red .sidebar-menu > li:hover > a,
.skin-red .sidebar-menu > li.active > a {
color: #fff;
background: #1e282c;
border-left-color: #e74c3c;
border-left-color: #f75444;
}
.skin-red .sidebar-menu > li > .treeview-menu {
background: #2c3b41;
@ -156,13 +153,22 @@
border-bottom-right-radius: 2px;
border-bottom-left-radius: 0;
}
.skin-red .sidebar-menu > li > a {
border-left: 3px solid transparent;
padding-left: 12px;
}
@media (min-width: 768px) {
.skin-red.sidebar-mini.sidebar-collapse .sidebar-menu > li:hover > a > span:not(.pull-right) {
margin-left: -3px;
}
}
@media (max-width: 767px) {
.skin-red.multiplenav .sidebar .mobilenav a.btn-app {
background: #374850;
color: #fff;
}
.skin-red.multiplenav .sidebar .mobilenav a.btn-app.active {
background: #e74c3c;
background: #f75444;
color: #fff;
}
}

View File

@ -84,9 +84,6 @@
color: #848484;
background: #f9fafc;
}
.skin-yellow-light .sidebar-menu > li > a {
border-left: 3px solid transparent;
}
.skin-yellow-light .sidebar-menu > li:hover > a,
.skin-yellow-light .sidebar-menu > li.active > a {
color: #000;
@ -154,6 +151,15 @@
border-left: 1px solid #d2d6de;
}
}
.skin-yellow-light .sidebar-menu > li > a {
border-left: 3px solid transparent;
padding-left: 12px;
}
@media (min-width: 768px) {
.skin-yellow-light.sidebar-mini.sidebar-collapse .sidebar-menu > li:hover > a > span:not(.pull-right) {
margin-left: -3px;
}
}
.skin-yellow-light .main-sidebar {
-webkit-box-shadow: 7px 0 14px rgba(0, 0, 0, 0.03);
box-shadow: 7px 0 14px rgba(0, 0, 0, 0.03);

View File

@ -89,9 +89,6 @@
color: #4b646f;
background: #1a2226;
}
.skin-yellow .sidebar-menu > li > a {
border-left: 3px solid transparent;
}
.skin-yellow .sidebar-menu > li:hover > a,
.skin-yellow .sidebar-menu > li.active > a {
color: #fff;
@ -156,6 +153,15 @@
border-bottom-right-radius: 2px;
border-bottom-left-radius: 0;
}
.skin-yellow .sidebar-menu > li > a {
border-left: 3px solid transparent;
padding-left: 12px;
}
@media (min-width: 768px) {
.skin-yellow.sidebar-mini.sidebar-collapse .sidebar-menu > li:hover > a > span:not(.pull-right) {
margin-left: -3px;
}
}
@media (max-width: 767px) {
.skin-yellow.multiplenav .sidebar .mobilenav a.btn-app {
background: #374850;

View File

@ -0,0 +1,209 @@
.m-1 {
margin-top: 5px !important;
margin-right: 5px !important;
margin-bottom: 5px !important;
margin-left: 5px !important;
}
.mt-1 {
margin-top: 5px !important;
}
.mr-1 {
margin-right: 5px !important;
}
.mb-1 {
margin-bottom: 5px !important;
}
.ml-1 {
margin-left: 5px !important;
}
.mx-1 {
margin-left: 5px !important;
margin-right: 5px !important;
}
.my-1 {
margin-top: 5px !important;
margin-bottom: 5px !important;
}
.m-2 {
margin-top: 10px !important;
margin-right: 10px !important;
margin-bottom: 10px !important;
margin-left: 10px !important;
}
.mt-2 {
margin-top: 10px !important;
}
.mr-2 {
margin-right: 10px !important;
}
.mb-2 {
margin-bottom: 10px !important;
}
.ml-2 {
margin-left: 10px !important;
}
.mx-2 {
margin-left: 10px !important;
margin-right: 10px !important;
}
.my-2 {
margin-top: 10px !important;
margin-bottom: 10px !important;
}
.m-3 {
margin-top: 15px !important;
margin-right: 15px !important;
margin-bottom: 15px !important;
margin-left: 15px !important;
}
.mt-3 {
margin-top: 15px !important;
}
.mr-3 {
margin-right: 15px !important;
}
.mb-3 {
margin-bottom: 15px !important;
}
.ml-3 {
margin-left: 15px !important;
}
.mx-3 {
margin-left: 15px !important;
margin-right: 15px !important;
}
.my-3 {
margin-top: 15px !important;
margin-bottom: 15px !important;
}
.m-4 {
margin-top: 20px !important;
margin-right: 20px !important;
margin-bottom: 20px !important;
margin-left: 20px !important;
}
.mt-4 {
margin-top: 20px !important;
}
.mr-4 {
margin-right: 20px !important;
}
.mb-4 {
margin-bottom: 20px !important;
}
.ml-4 {
margin-left: 20px !important;
}
.mx-4 {
margin-left: 20px !important;
margin-right: 20px !important;
}
.my-4 {
margin-top: 20px !important;
margin-bottom: 20px !important;
}
.p-1 {
padding-top: 5px !important;
padding-right: 5px !important;
padding-bottom: 5px !important;
padding-left: 5px !important;
}
.pt-1 {
padding-top: 5px !important;
}
.pr-1 {
padding-right: 5px !important;
}
.pb-1 {
padding-bottom: 5px !important;
}
.pl-1 {
padding-left: 5px !important;
}
.px-1 {
padding-left: 5px !important;
padding-right: 5px !important;
}
.py-1 {
padding-top: 5px !important;
padding-bottom: 5px !important;
}
.p-2 {
padding-top: 10px !important;
padding-right: 10px !important;
padding-bottom: 10px !important;
padding-left: 10px !important;
}
.pt-2 {
padding-top: 10px !important;
}
.pr-2 {
padding-right: 10px !important;
}
.pb-2 {
padding-bottom: 10px !important;
}
.pl-2 {
padding-left: 10px !important;
}
.px-2 {
padding-left: 10px !important;
padding-right: 10px !important;
}
.py-2 {
padding-top: 10px !important;
padding-bottom: 10px !important;
}
.p-3 {
padding-top: 15px !important;
padding-right: 15px !important;
padding-bottom: 15px !important;
padding-left: 15px !important;
}
.pt-3 {
padding-top: 15px !important;
}
.pr-3 {
padding-right: 15px !important;
}
.pb-3 {
padding-bottom: 15px !important;
}
.pl-3 {
padding-left: 15px !important;
}
.px-3 {
padding-left: 15px !important;
padding-right: 15px !important;
}
.py-3 {
padding-top: 15px !important;
padding-bottom: 15px !important;
}
.p-4 {
padding-top: 20px !important;
padding-right: 20px !important;
padding-bottom: 20px !important;
padding-left: 20px !important;
}
.pt-4 {
padding-top: 20px !important;
}
.pr-4 {
padding-right: 20px !important;
}
.pb-4 {
padding-bottom: 20px !important;
}
.pl-4 {
padding-left: 20px !important;
}
.px-4 {
padding-left: 20px !important;
padding-right: 20px !important;
}
.py-4 {
padding-top: 20px !important;
padding-bottom: 20px !important;
}
/*# sourceMappingURL=tinycss.css.map */

View File

@ -305,14 +305,38 @@ function _init() {
//Destroy if it exists
$(".sidebar").slimScroll({destroy: true}).height("auto").css("overflow", "inherit");
if (!$("body").hasClass('sidebar-collapse')) {
$(".sidebar").off("mousewheel").css("margin-top", 0);
$('.sidebar .treeview-menu').off('mousewheel').removeAttr("style");
//Add slimscroll
$(".sidebar").slimscroll({
height: ($(window).height() - $(".main-header").height()) + "px",
color: "rgba(0,0,0,0.2)",
size: "8px"
});
}
$(".sidebar").trigger("mouseover");
} else {
var sidebarHeight = $(".sidebar").height();
var maxHeight = $(window).height() - $(".main-header").height();
var overflowHeight = sidebarHeight + $(".main-header").height() - $(window).height();
if (overflowHeight > 0) {
$(".sidebar").height(maxHeight);
$(".sidebar").on("mousewheel", function (e) {
e.preventDefault();
if (e.originalEvent.pageX < $(".sidebar").width()) {
var marginTop = parseInt($(".sidebar").css("margin-top").replace("px", "")) + e.originalEvent.wheelDelta;
if (marginTop < 0 && Math.abs(marginTop) > overflowHeight) {
marginTop = Math.min(overflowHeight, marginTop);
marginTop = -overflowHeight;
}
marginTop = Math.min(0, marginTop);
$(".sidebar").css("margin-top", marginTop);
}
});
$('.sidebar .treeview-menu').on('mousewheel', function (e) {
e.stopPropagation();
});
}
}
}
}
}
@ -370,11 +394,13 @@ function _init() {
var screenWidth = $.AdminLTE.options.screenSizes.sm - 1;
//Expand sidebar on hover
$('.main-sidebar').hover(function () {
if ($.AdminLTE.options.sidebarExpandOnHover) {
if ($('body').hasClass('sidebar-mini')
&& $("body").hasClass('sidebar-collapse')
&& $(window).width() > screenWidth) {
_this.expand();
}
}
}, function () {
if ($('body').hasClass('sidebar-mini')
&& $('body').hasClass('sidebar-expanded-on-hover')
@ -385,10 +411,12 @@ function _init() {
},
expand: function () {
$("body").removeClass('sidebar-collapse').addClass('sidebar-expanded-on-hover');
$.AdminLTE.layout.fixSidebar();
},
collapse: function () {
if ($('body').hasClass('sidebar-expanded-on-hover')) {
$('body').removeClass('sidebar-expanded-on-hover').addClass('sidebar-collapse');
// $.AdminLTE.layout.fixSidebar();
}
}
};
@ -404,13 +432,36 @@ function _init() {
$.AdminLTE.tree = function (menu) {
var _this = this;
var animationSpeed = $.AdminLTE.options.animationSpeed;
$(document).off('mouseenter', menu + ' .sidebar-menu > li')
.on('mouseenter', menu + ' .sidebar-menu > li', function () {
var treemenu = $(this).find("> .treeview-menu");
if (treemenu.length > 0) {
if ($("body").hasClass("sidebar-collapse")) {
var liHeight = $(this).height();
var headerHeight = $(".main-header").height();
var maxBottomHeight = $(window).height() - ($(this).offset().top + headerHeight);
var maxTopHeight = $(window).height() - maxBottomHeight - liHeight;
var maxHeight = maxBottomHeight;
if (maxBottomHeight < 300 || maxTopHeight > maxBottomHeight) {
treemenu.css("top", "unset").css("bottom", liHeight);
maxHeight = maxTopHeight;
}
treemenu.css("max-height", maxHeight).css("overflow-y", "auto");
} else {
treemenu.css("max-height", "inherit").css("overflow-y", "unset");
}
}
});
$(document).off('click', menu + ' li a')
.on('click', menu + ' li a', function (e) {
//Get the clicked link and the next element
var $this = $(this);
var checkElement = $this.next();
//Check if the next element is a menu and is visible
if ((checkElement.is('.treeview-menu')) && (checkElement.is(':visible')) && (!$('body').hasClass('sidebar-collapse'))) {
if ((checkElement.is('.treeview-menu')) && (checkElement.is(':visible'))) {
if ($("body").hasClass("sidebar-collapse") && $this.parent().parent().hasClass("sidebar-menu")) {
return false;
}
//Close the menu
checkElement.slideUp(animationSpeed, function () {
checkElement.removeClass('menu-open');
@ -450,8 +501,9 @@ function _init() {
$this.parent().addClass("active");
}
// modified by FastAdmin
if ($(".show-submenu", menu).size() == 0) {
if ($(".show-submenu", menu).size() == 0 && $this.parent().parent().hasClass("sidebar-menu")) {
$this.parent().siblings().find("ul.menu-open").slideUp();
$this.parent().siblings("li.treeview-open").removeClass("treeview-open");
}
}
//if this isn't a link, prevent the page from being redirected

File diff suppressed because it is too large Load Diff

View File

@ -4,7 +4,7 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template'], function
// 初始化表格参数配置
Table.api.init({
extend: {
index_url: Config.api_url ? Config.api_url + '/addon/index' : "addon/downloaded",
index_url: Config.api_url ? 'addon/index' : "addon/downloaded",
add_url: '',
edit_url: '',
del_url: '',
@ -17,16 +17,9 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template'], function
// 弹窗自适应宽高
var area = Fast.config.openArea != undefined ? Fast.config.openArea : [$(window).width() > 800 ? '800px' : '95%', $(window).height() > 600 ? '600px' : '95%'];
table.on('load-success.bs.table', function (e, json) {
if (json && typeof json.category != 'undefined' && $(".nav-category li").size() == 2) {
$.each(json.category, function (i, j) {
$("<li><a href='javascript:;' data-id='" + j.id + "'>" + j.name + "</a></li>").insertBefore($(".nav-category li:last"));
});
}
});
table.on('load-error.bs.table', function (e, status, res) {
if (status == 404 && $(".btn-switch.active").data("type") != "local") {
Layer.confirm(__('Store now available tips'), {
var switch_local = function () {
if ($(".btn-switch.active").data("type") != "local") {
Layer.confirm(__('Store not available tips'), {
title: __('Warmtips'),
btn: [__('Switch to the local'), __('Try to reload')]
}, function (index) {
@ -40,6 +33,19 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template'], function
});
return false;
}
};
table.on('load-success.bs.table', function (e, json) {
if (json && typeof json.category != 'undefined' && $(".nav-category li").size() == 2) {
$.each(json.category, function (i, j) {
$("<li><a href='javascript:;' data-id='" + j.id + "'>" + j.name + "</a></li>").insertBefore($(".nav-category li:last"));
});
}
if (typeof json.rows === 'undefined' && typeof json.code != 'undefined') {
switch_local();
}
});
table.on('load-error.bs.table', function (e, status, res) {
switch_local();
});
table.on('post-body.bs.table', function (e, settings, json, xhr) {
var parenttable = table.closest('.bootstrap-table');
@ -156,7 +162,6 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template'], function
});
return res;
},
dataType: 'jsonp',
templateView: false,
clickToSelect: false,
search: true,
@ -167,7 +172,7 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template'], function
commonSearch: true,
searchFormVisible: true,
searchFormTemplate: 'searchformtpl',
pageSize: 50,
pageSize: 5,
});
// 为表格绑定事件
@ -177,8 +182,31 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template'], function
require(['upload'], function (Upload) {
Upload.api.upload("#faupload-addon", function (data, ret) {
Config['addons'][data.addon.name] = data.addon;
Toastr.success(ret.msg);
operate(data.addon.name, 'enable', false);
var addon = data.addon;
var testdata = data.addon.testdata;
operate(data.addon.name, 'enable', false, function (data, ret) {
Layer.alert(__('Offline installed tips') + (testdata ? __('Testdata tips') : ""), {
btn: testdata ? [__('Import testdata'), __('Skip testdata')] : [__('OK')],
title: __('Warning'),
yes: function (index) {
if (testdata) {
Fast.api.ajax({
url: 'addon/testdata',
data: {
name: addon.name,
version: addon.version,
faversion: Config.faversion
}
}, function (data, ret) {
Layer.close(index);
});
} else {
Layer.close(index);
}
},
icon: 1
});
});
return false;
}, function (data, ret) {
if (ret.msg && ret.msg.match(/(login|登录)/g)) {
@ -192,7 +220,7 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template'], function
}
});
//检测是否登录
// 检测是否登录
$(document).on("mousedown", "#faupload-addon", function (e) {
var userinfo = Controller.api.userinfo.get();
var uid = userinfo ? userinfo.id : 0;
@ -219,9 +247,14 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template'], function
$(".btn-switch").removeClass("active");
$(this).addClass("active");
$("form.form-commonsearch input[name='type']").val($(this).data("type"));
var method = $(this).data("type") == 'local' ? 'hideColumn' : 'showColumn';
table.bootstrapTable(method, 'price');
table.bootstrapTable(method, 'downloads');
table.bootstrapTable('refresh', {url: ($(this).data("url") ? $(this).data("url") : $.fn.bootstrapTable.defaults.extend.index_url), pageNumber: 1});
return false;
});
// 切换分类
$(document).on("click", ".nav-category li a", function () {
$(".nav-category li").removeClass("active");
$(this).parent().addClass("active");
@ -265,17 +298,18 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template'], function
btn: [__('Login'), __('Register')],
yes: function (index, layero) {
Fast.api.ajax({
url: Config.api_url + '/user/login',
dataType: 'jsonp',
url: 'addon/login',
type: 'post',
data: {
account: $("#inputAccount", layero).val(),
password: $("#inputPassword", layero).val(),
_method: 'POST'
version: Config.faversion,
}
}, function (data, ret) {
Controller.api.userinfo.set(data);
Layer.closeAll();
Layer.alert(ret.msg);
Layer.alert(ret.msg, {title: __('Warning'), icon: 0});
return false;
}, function (data, ret) {
});
},
@ -298,10 +332,9 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template'], function
});
} else {
Fast.api.ajax({
url: Config.api_url + '/user/index',
dataType: 'jsonp',
url: 'addon/userinfo',
data: {
user_id: userinfo.id,
uid: userinfo.id,
token: userinfo.token,
}
}, function (data) {
@ -313,17 +346,16 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template'], function
btn: [__('Logout'), __('Cancel')],
yes: function () {
Fast.api.ajax({
url: Config.api_url + '/user/logout',
dataType: 'jsonp',
url: 'addon/logout',
data: {uid: userinfo.id, token: userinfo.token}
}, function (data, ret) {
Controller.api.userinfo.set(null);
Layer.closeAll();
Layer.alert(ret.msg);
Layer.alert(ret.msg, {title: __('Warning'), icon: 0});
}, function (data, ret) {
Controller.api.userinfo.set(null);
Layer.closeAll();
Layer.alert(ret.msg);
Layer.alert(ret.msg, {title: __('Warning'), icon: 0});
});
}
});
@ -337,6 +369,28 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template'], function
}
});
//刷新授权
$(document).on("click", ".btn-authorization", function () {
var userinfo = Controller.api.userinfo.get();
if (!userinfo) {
$(".btn-userinfo").trigger("click");
return false;
}
Layer.confirm(__('Are you sure you want to refresh authorization?'), {icon: 3, title: __('Warmtips')}, function () {
Fast.api.ajax({
url: 'addon/authorization',
data: {
uid: userinfo.id,
token: userinfo.token
}
}, function (data, ret) {
$(".btn-refresh").trigger("click");
Layer.closeAll();
});
});
return false;
});
var install = function (name, version, force) {
var userinfo = Controller.api.userinfo.get();
var uid = userinfo ? userinfo.id : 0;
@ -354,30 +408,35 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template'], function
}, function (data, ret) {
Layer.closeAll();
Config['addons'][data.addon.name] = ret.data.addon;
Layer.alert(__('Online installed tips'), {
btn: [__('OK')],
operate(data.addon.name, 'enable', false, function () {
Layer.alert(__('Online installed tips') + (data.addon.testdata ? __('Testdata tips') : ""), {
btn: data.addon.testdata ? [__('Import testdata'), __('Skip testdata')] : [__('OK')],
title: __('Warning'),
yes: function (index) {
if (data.addon.testdata) {
Fast.api.ajax({
url: 'addon/testdata',
data: {
name: name,
uid: uid,
token: token,
version: version,
faversion: Config.faversion
}
}, function (data, ret) {
Layer.close(index);
});
} else {
Layer.close(index);
}
},
icon: 1
});
Controller.api.refresh(table, name);
}, function (data, ret) {
//如果是需要购买的插件则弹出二维码提示
if (ret && ret.code === -1) {
//扫码支付
Layer.open({
content: Template("paytpl", ret.data),
shade: 0.8,
area: area,
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) {
}, function (data, ret) {
var area = Fast.config.openArea != undefined ? Fast.config.openArea : [$(window).width() > 650 ? '650px' : '95%', $(window).height() > 710 ? '710px' : '95%'];
if (ret && ret.code === -2) {
//如果登录已经超时,重新提醒登录
if (uid && uid != ret.data.uid) {
Controller.api.userinfo.set(null);
@ -387,7 +446,31 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template'], function
top.Fast.api.open(ret.data.payurl, __('Pay now'), {
area: area,
end: function () {
top.Layer.alert(__('Pay tips'));
Fast.api.ajax({
url: 'addon/isbuy',
data: {
name: name,
force: force ? 1 : 0,
uid: uid,
token: token,
version: version,
faversion: Config.faversion
}
}, function () {
top.Layer.alert(__('Pay successful tips'), {
btn: [__('Continue installation')],
title: __('Warning'),
icon: 1,
yes: function (index) {
top.Layer.close(index);
install(name, version);
}
});
return false;
}, function () {
console.log(__('Canceled'));
return false;
});
}
});
} else if (ret && ret.code === -3) {
@ -407,7 +490,7 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template'], function
});
} else {
Layer.alert(ret.msg);
Layer.alert(ret.msg, {title: __('Warning'), icon: 0});
}
return false;
});
@ -439,13 +522,13 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template'], function
});
} else {
Layer.alert(ret.msg);
Layer.alert(ret.msg, {title: __('Warning'), icon: 0});
}
return false;
});
};
var operate = function (name, action, force) {
var operate = function (name, action, force, success) {
Fast.api.ajax({
url: 'addon/state',
data: {name: name, action: action, force: force ? 1 : 0}
@ -453,6 +536,9 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template'], function
var addon = Config['addons'][name];
addon.state = action === 'enable' ? 1 : 0;
Layer.closeAll();
if (typeof success === 'function') {
success(data, ret);
}
Controller.api.refresh(table, name);
}, function (data, ret) {
if (ret && ret.code === -3) {
@ -467,12 +553,12 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template'], function
},
yes: function () {
operate(name, action, true);
operate(name, action, true, success);
}
});
} else {
Layer.alert(ret.msg);
Layer.alert(ret.msg, {title: __('Warning'), icon: 0});
}
return false;
});
@ -490,7 +576,7 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template'], function
Layer.closeAll();
Controller.api.refresh(table, name);
}, function (data, ret) {
Layer.alert(ret.msg);
Layer.alert(ret.msg, {title: __('Warning')});
return false;
});
};
@ -554,7 +640,7 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template'], function
}
var version = $(this).data("version");
Layer.confirm(__('Upgrade tips', Config['addons'][name].title), function () {
Layer.confirm(__('Upgrade tips', Config['addons'][name].title), function (index, layero) {
upgrade(name, version);
});
});
@ -646,10 +732,17 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template'], function
refresh: function (table, name) {
//刷新左侧边栏
Fast.api.refreshmenu();
//刷新插件JS缓存
Fast.api.ajax({url: require.toUrl('addons.js'), loading: false}, function () {
return false;
}, function () {
return false;
});
//刷新行数据
if ($(".operate[data-name='" + name + "']").length > 0) {
var index = $(".operate[data-name='" + name + "']").closest("tr[data-index]").data("index");
var tr = $(".operate[data-name='" + name + "']").closest("tr[data-index]");
var index = tr.data("index");
var row = Table.api.getrowbyindex(table, index);
row.addon = typeof Config['addons'][name] !== 'undefined' ? Config['addons'][name] : undefined;
table.bootstrapTable("updateRow", {index: index, row: row});

View File

@ -180,6 +180,9 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template'], function
Form.api.bindevent($("form[role=form]"), function (data) {
Fast.api.refreshmenu();
});
$(document).on('change keyup', "#icon", function () {
$(this).prev().find("i").prop("class", $(this).val());
});
$(document).on('click', ".btn-search-icon", function () {
if (iconlist.length == 0) {
$.get(Config.site.cdnurl + "/assets/libs/font-awesome/less/variables.less", function (ret) {
@ -195,7 +198,7 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template'], function
}
});
$(document).on('click', '#chooseicon ul li', function () {
$("input[name='row[icon]']").val('fa fa-' + $(this).data("font"));
$("input[name='row[icon]']").val('fa fa-' + $(this).data("font")).trigger("change");
Layer.closeAll();
});
$(document).on('keyup', 'input.js-icon-search', function () {

View File

@ -143,6 +143,8 @@ define(['jquery', 'bootstrap', 'backend', 'form', 'table'], function ($, undefin
showToggle: false,
showExport: false,
maintainSelected: true,
fixedColumns: true,
fixedRightNumber: 1,
columns: [
[
{field: 'state', checkbox: multiple, visible: multiple, operate: false},
@ -161,9 +163,9 @@ define(['jquery', 'bootstrap', 'backend', 'form', 'table'], function ($, undefin
},
formatter: Controller.api.formatter.mimetype
},
{field: 'createtime', title: __('Createtime'), formatter: Table.api.formatter.datetime, datetimeFormat: 'YYYY-MM-DD', operate: 'RANGE', addclass: 'datetimerange', sortable: true},
{field: 'createtime', title: __('Createtime'), width: 120, formatter: Table.api.formatter.datetime, datetimeFormat: 'YYYY-MM-DD', operate: 'RANGE', addclass: 'datetimerange', sortable: true},
{
field: 'operate', title: __('Operate'), events: {
field: 'operate', title: __('Operate'), width: 85, events: {
'click .btn-chooseone': function (e, value, row, index) {
Fast.api.close({url: row.url, multiple: multiple});
},
@ -199,6 +201,10 @@ define(['jquery', 'bootstrap', 'backend', 'form', 'table'], function ($, undefin
// 为表格绑定事件
Table.api.bindevent(table);
require(['upload'], function (Upload) {
$("#toolbar .faupload").data("category", function (file) {
var category = $("ul.nav-tabs[data-field='category'] li.active a").data("value");
return category;
});
Upload.api.upload($("#toolbar .faupload"), function () {
$(".btn-refresh").trigger("click");
});
@ -207,7 +213,17 @@ define(['jquery', 'bootstrap', 'backend', 'form', 'table'], function ($, undefin
add: function () {
//上传完成后刷新父窗口
$(".faupload").data("upload-complete", function (files) {
setTimeout(function () {
window.parent.$(".btn-refresh").trigger("click");
}, 100);
});
// 获取上传类别
$("#faupload-third,#faupload-third-chunking").data("category", function (file) {
return $("#category-third").val();
});
// 获取上传类别
$("#faupload-local,#faupload-local-chunking").data("category", function (file) {
return $("#category-local").val();
});
Controller.api.bindevent();
},

View File

@ -26,8 +26,8 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'upload'], function (
[
{field: 'id', title: 'ID'},
{field: 'title', title: __('Title')},
{field: 'url', title: __('Url'), formatter: Table.api.formatter.url},
{field: 'ip', title: __('IP')},
{field: 'url', title: __('Url'), align: 'left', formatter: Table.api.formatter.url},
{field: 'ip', title: __('ip'), formatter:Table.api.formatter.search},
{field: 'createtime', title: __('Createtime'), formatter: Table.api.formatter.datetime, operate: 'RANGE', addclass: 'datetimerange', sortable: true},
]
],

View File

@ -56,7 +56,7 @@ define(['jquery', 'bootstrap', 'backend', 'addtabs', 'adminlte', 'form'], functi
$(document).on("click fa.event.toggleitem", ".sidebar-menu li > a", function (e) {
var nextul = $(this).next("ul");
if (nextul.length == 0 && (!$(this).parent("li").hasClass("treeview") || ($("body").hasClass("multiplenav") && $(this).parent().parent().hasClass("sidebar-menu")))) {
$(".sidebar-menu li").removeClass("active");
$(".sidebar-menu li").not($(this).parents("li")).removeClass("active");
}
//当外部触发隐藏的a时,触发父辈a的事件
if (!$(this).closest("ul").is(":visible")) {
@ -236,6 +236,12 @@ define(['jquery', 'bootstrap', 'backend', 'addtabs', 'adminlte', 'form'], functi
}
}
var createCookie = function (name, value) {
var date = new Date();
date.setTime(date.getTime() + (365 * 24 * 60 * 60 * 1000));
document.cookie = encodeURIComponent(Config.cookie.prefix + name) + "=" + encodeURIComponent(value) + "; expires=" + date.toGMTString();
};
var my_skins = [
"skin-blue",
"skin-black",
@ -256,9 +262,39 @@ define(['jquery', 'bootstrap', 'backend', 'addtabs', 'adminlte', 'form'], functi
"skin-black-yellow",
"skin-black-pink",
];
setup();
function change_layout(cls) {
// 皮肤切换
$("[data-skin]").on('click', function (e) {
var skin = $(this).data('skin');
if (!$("body").hasClass(skin)) {
$("body").removeClass(my_skins.join(' ')).addClass(skin);
var cssfile = Config.site.cdnurl + "/assets/css/skins/" + skin + ".css";
$('head').append('<link rel="stylesheet" href="' + cssfile + '" type="text/css" />');
$(".skin-list li.active").removeClass("active");
$(".skin-list li a[data-skin='" + skin + "']").parent().addClass("active");
createCookie('adminskin', skin);
}
return false;
});
// 收起菜单栏切换
$("[data-layout='sidebar-collapse']").on('click', function () {
$(".sidebar-toggle").trigger("click");
});
// 切换子菜单显示和菜单小图标的显示
$("[data-menu]").on('click', function () {
if ($(this).data("menu") == 'show-submenu') {
$("ul.sidebar-menu").toggleClass("show-submenu");
createCookie('show_submenu', $(this).prop("checked") ? 1 : 0)
} else {
nav.toggleClass("disable-top-badge");
}
});
// 右侧控制栏切换
$("[data-controlsidebar]").on('click', function () {
var cls = $(this).data('controlsidebar');
$("body").toggleClass(cls);
AdminLTE.layout.fixSidebar();
//Fix the problem with right sidebar and layout boxed
@ -270,48 +306,6 @@ define(['jquery', 'bootstrap', 'backend', 'addtabs', 'adminlte', 'form'], functi
}
AdminLTE.controlSidebar._fix($(".control-sidebar-bg"));
AdminLTE.controlSidebar._fix($(".control-sidebar"));
}
function change_skin(cls) {
if (!$("body").hasClass(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;
}
function setup() {
var tmp = localStorage.getItem('skin');
if (tmp && $.inArray(tmp, my_skins) != -1)
change_skin(tmp);
// 皮肤切换
$("[data-skin]").on('click', function (e) {
if ($(this).hasClass('knob'))
return;
e.preventDefault();
change_skin($(this).data('skin'));
});
// 布局切换
$("[data-layout]").on('click', function () {
change_layout($(this).data('layout'));
});
// 切换子菜单显示和菜单小图标的显示
$("[data-menu]").on('click', function () {
if ($(this).data("menu") == 'show-submenu') {
$("ul.sidebar-menu").toggleClass("show-submenu");
} else {
nav.toggleClass("disable-top-badge");
}
});
// 右侧控制栏切换
$("[data-controlsidebar]").on('click', function () {
change_layout($(this).data('controlsidebar'));
var slide = !AdminLTE.options.controlSidebarOptions.slide;
AdminLTE.options.controlSidebarOptions.slide = slide;
if (!slide)
@ -332,10 +326,33 @@ define(['jquery', 'bootstrap', 'backend', 'addtabs', 'adminlte', 'form'], functi
// 菜单栏展开或收起
$("[data-enable='expandOnHover']").on('click', function () {
$(this).attr('disabled', true);
$.AdminLTE.options.sidebarExpandOnHover = $(this).prop("checked") ? 1 : 0;
localStorage.setItem('sidebarExpandOnHover', $.AdminLTE.options.sidebarExpandOnHover);
AdminLTE.pushMenu.expandOnHover();
if (!$('body').hasClass('sidebar-collapse'))
$("[data-layout='sidebar-collapse']").click();
$.AdminLTE.layout.fixSidebar();
});
// 切换菜单栏
$(document).on("click", ".sidebar-toggle", function () {
var value = $("body").hasClass("sidebar-collapse") ? 1 : 0;
setTimeout(function () {
$(window).trigger("resize");
}, 300);
createCookie('sidebar_collapse', value);
});
// 切换多级菜单
$(document).on("click", "[data-config='multiplenav']", function () {
var value = $(this).prop("checked") ? 1 : 0;
createCookie('multiplenav', value);
location.reload();
});
// 切换多选项卡
$(document).on("click", "[data-config='multipletab']", function () {
var value = $(this).prop("checked") ? 1 : 0;
$("body").toggleClass("multipletab", value);
createCookie('multipletab', value);
});
// 重设选项
@ -355,8 +372,17 @@ define(['jquery', 'bootstrap', 'backend', 'addtabs', 'adminlte', 'form'], functi
$("[data-menu='disable-top-badge']").attr('checked', 'checked');
}
var sidebarExpandOnHover = localStorage.getItem('sidebarExpandOnHover');
if (sidebarExpandOnHover == '1') {
$("[data-enable='expandOnHover']").trigger("click");
}
$.each(my_skins, function (i, j) {
if ($("body").hasClass(j)) {
$(".skin-list li a[data-skin='" + j + "']").parent().addClass("active");
}
});
$(window).resize();
},

View File

@ -4,7 +4,7 @@
* @author: pppscn <35696959@qq.com>
* @update 2017-05-07 <https://gitee.com/pp/fastadmin>
*
* @author: Karson <karsonzhang@163.com>
* @author: Karson <karson@fastadmin.net>
* @update 2018-04-05 <https://gitee.com/karson/fastadmin>
*/

View File

@ -138,27 +138,32 @@ define(['jquery', 'bootstrap', 'frontend', 'form', 'template'], function ($, und
sortName: 'id',
showToggle: false,
showExport: false,
fixedColumns: true,
fixedRightNumber: 1,
columns: [
[
{field: 'state', checkbox: multiple, visible: multiple, operate: false},
{field: 'id', title: __('Id'), operate: false},
{
field: 'url', title: __('Preview'), formatter: function (value, row, index) {
var html = '';
if (row.mimetype.indexOf("image") > -1) {
var style = row.storage === 'upyun' ? '!/fwfh/120x90' : '';
return '<a href="' + row.fullurl + '" target="_blank"><img src="' + row.fullurl + style + '" alt="" style="max-height:90px;max-width:120px"></a>';
html = '<a href="' + row.fullurl + '" target="_blank"><img src="' + row.fullurl + row.thumb_style + '" alt="" style="max-height:60px;max-width:120px"></a>';
} else {
return '<a href="' + row.fullurl + '" target="_blank"><img src="' + Fast.api.fixurl("ajax/icon") + "?suffix=" + row.imagetype + '" alt="" style="max-height:90px;max-width:120px"></a>';
html = '<a href="' + row.fullurl + '" target="_blank"><img src="' + Fast.api.fixurl("ajax/icon") + "?suffix=" + row.imagetype + '" alt="" style="max-height:90px;max-width:120px"></a>';
}
return '<div style="width:120px;margin:0 auto;text-align:center;overflow:hidden;white-space: nowrap;text-overflow: ellipsis;">' + html + '</div>';
}
}, operate: false
},
{field: 'filename', title: __('Filename'), formatter: Table.api.formatter.search, operate: 'like'},
{field: 'filename', title: __('Filename'), formatter: function (value, row, index) {
return '<div style="width:150px;margin:0 auto;text-align:center;overflow:hidden;white-space: nowrap;text-overflow: ellipsis;">' + Table.api.formatter.search.call(this, value, row, index) + '</div>';
}, operate: 'like'},
{field: 'imagewidth', title: __('Imagewidth'), operate: false},
{field: 'imageheight', title: __('Imageheight'), operate: false},
{field: 'mimetype', title: __('Mimetype'), formatter: Table.api.formatter.search},
{field: 'createtime', title: __('Createtime'), formatter: Table.api.formatter.datetime, operate: 'RANGE', addclass: 'datetimerange', sortable: true},
{field: 'createtime', title: __('Createtime'), width: 120, formatter: Table.api.formatter.datetime, datetimeFormat: 'YYYY-MM-DD', operate: 'RANGE', addclass: 'datetimerange', sortable: true},
{
field: 'operate', title: __('Operate'), events: {
field: 'operate', title: __('Operate'), width: 85, events: {
'click .btn-chooseone': function (e, value, row, index) {
Fast.api.close({url: row.url, multiple: multiple});
},

File diff suppressed because one or more lines are too long

View File

@ -1,7 +1,7 @@
define(['jquery', 'bootstrap', 'upload', 'validator', 'validator-lang'], function ($, undefined, Upload, Validator, undefined) {
var Form = {
config: {
fieldlisttpl: '<dd class="form-inline"><input type="text" name="<%=name%>[<%=index%>][key]" class="form-control" value="<%=row.key%>" size="10" /> <input type="text" name="<%=name%>[<%=index%>][value]" class="form-control" value="<%=row.value%>" /> <span class="btn btn-sm btn-danger btn-remove"><i class="fa fa-times"></i></span> <span class="btn btn-sm btn-primary btn-dragsort"><i class="fa fa-arrows"></i></span></dd>'
fieldlisttpl: '<dd class="form-inline"><input type="text" name="<%=name%>[<%=index%>][key]" class="form-control" value="<%=key%>" placeholder="<%=options.keyPlaceholder||\'\'%>" size="10" /> <input type="text" name="<%=name%>[<%=index%>][value]" class="form-control" value="<%=value%>" placeholder="<%=options.valuePlaceholder||\'\'%>" /> <span class="btn btn-sm btn-danger btn-remove"><i class="fa fa-times"></i></span> <span class="btn btn-sm btn-primary btn-dragsort"><i class="fa fa-arrows"></i></span></dd>'
},
events: {
validator: function (form, success, error, submit) {
@ -216,7 +216,7 @@ define(['jquery', 'bootstrap', 'upload', 'validator', 'validator-lang'], functio
$(this).on('cancel.daterangepicker', function (ev, picker) {
$(this).val('').trigger('blur');
});
$(this).daterangepicker($.extend(true, options, $(this).data()), callback);
$(this).daterangepicker($.extend(true, options, $(this).data() || {}, $(this).data("daterangepicker-options") || {}), callback);
});
});
}
@ -262,20 +262,24 @@ define(['jquery', 'bootstrap', 'upload', 'validator', 'validator-lang'], functio
if (value !== "") {
urlArr.push(inputObj.val());
}
urlArr.push(data.url)
var result = urlArr.join(",");
if (maxcount > 0) {
var nums = value === '' ? 0 : value.split(/\,/).length;
var files = data.url !== "" ? data.url.split(/\,/) : [];
$.each(files, function (i, j) {
var url = Config.upload.fullmode ? Fast.api.cdnurl(j) : j;
urlArr.push(url);
});
if (maxcount > 0) {
var remains = maxcount - nums;
if (files.length > remains) {
Toastr.error(__('You can choose up to %d file%s', remains));
return false;
}
}
var result = urlArr.join(",");
inputObj.val(result).trigger("change").trigger("validate");
} else {
$("#" + input_id).val(data.url).trigger("change").trigger("validate");
var url = Config.upload.fullmode ? Fast.api.cdnurl(data.url) : data.url;
$("#" + input_id).val(url).trigger("change").trigger("validate");
}
}
});
@ -288,10 +292,10 @@ define(['jquery', 'bootstrap', 'upload', 'validator', 'validator-lang'], functio
if ($(".fieldlist", form).size() > 0) {
require(['dragsort', 'template'], function (undefined, Template) {
//刷新隐藏textarea的值
var refresh = function (name) {
var refresh = function (container) {
var data = {};
var name = container.data("name");
var textarea = $("textarea[name='" + name + "']", form);
var container = $(".fieldlist[data-name='" + name + "']");
var template = container.data("template");
$.each($("input,select,textarea", container).serializeArray(), function (i, j) {
var reg = /\[(\w+)\]\[(\w+)\]$/g;
@ -318,13 +322,8 @@ define(['jquery', 'bootstrap', 'upload', 'validator', 'validator-lang'], functio
});
textarea.val(JSON.stringify(result));
};
//监听文本框改变事件
$(document).on('change keyup changed', ".fieldlist input,.fieldlist textarea,.fieldlist select", function () {
refresh($(this).closest(".fieldlist").data("name"));
});
//追加控制
$(".fieldlist", form).on("click", ".btn-append,.append", function (e, row) {
var container = $(this).closest(".fieldlist");
//追加一行数据
var append = function (container, row, initial) {
var tagName = container.data("tag") || (container.is("table") ? "tr" : "dd");
var index = container.data("index");
var name = container.data("name");
@ -333,51 +332,88 @@ define(['jquery', 'bootstrap', 'upload', 'validator', 'validator-lang'], functio
index = index ? parseInt(index) : 0;
container.data("index", index + 1);
row = row ? row : {};
var vars = {index: index, name: name, data: data, row: row};
row = typeof row.key === 'undefined' || typeof row.value === 'undefined' ? {key: '', value: row} : row;
var options = container.data("fieldlist-options") || {};
var vars = {index: index, name: name, data: data, options: options, key: row.key, value: row.value, row: row.value};
var html = template ? Template(template, vars) : Template.render(Form.config.fieldlisttpl, vars);
$(html).attr("fieldlist-item", true).insertBefore($(tagName + ":last", container));
$(this).trigger("fa.event.appendfieldlist", $(this).closest(tagName).prev());
var obj = $(html);
if ((options.deleteBtn === false || options.removeBtn === false) && initial)
obj.find(".btn-remove").remove();
if (options.dragsortBtn === false && initial)
obj.find(".btn-dragsort").remove();
if ((options.readonlyKey === true || options.disableKey === true) && initial) {
obj.find("input[name$='[key]']").prop("readonly", true);
}
obj.attr("fieldlist-item", true);
obj.insertAfter($(tagName + "[fieldlist-item]", container).length > 0 ? $(tagName + "[fieldlist-item]:last", container) : $(tagName + ":first", container));
//兼容旧版本事件
$(".btn-append,.append", container).trigger("fa.event.appendfieldlist", obj);
//新版本事件
container.trigger("fa.event.appendfieldlist", obj);
return obj;
};
var fieldlist = $(".fieldlist", form);
//监听文本框改变事件
$(document).on('change keyup changed', ".fieldlist input,.fieldlist textarea,.fieldlist select", function () {
var container = $(this).closest(".fieldlist");
refresh(container);
});
//移除控制
$(".fieldlist", form).on("click", ".btn-remove", function () {
//追加控制(点击按钮)
fieldlist.on("click", ".btn-append,.append", function (e, row) {
var container = $(this).closest(".fieldlist");
append(container, row);
// refresh(container);
});
//移除控制(点击按钮)
fieldlist.on("click", ".btn-remove", function () {
var container = $(this).closest(".fieldlist");
var tagName = container.data("tag") || (container.is("table") ? "tr" : "dd");
$(this).closest(tagName).remove();
refresh(container.data("name"));
refresh(container);
});
//渲染数据&拖拽排序
$(".fieldlist", form).each(function () {
var container = this;
var tagName = $(this).data("tag") || ($(this).is("table") ? "tr" : "dd");
$(this).dragsort({
itemSelector: tagName,
dragSelector: ".btn-dragsort",
dragEnd: function () {
refresh($(this).closest(".fieldlist").data("name"));
},
placeHolderTemplate: $("<" + tagName + "/>")
//追加控制(通过事件)
fieldlist.on("fa.event.appendtofieldlist", function (e, row) {
var container = $(this);
append(container, row);
refresh(container);
});
var textarea = $("textarea[name='" + $(this).data("name") + "']", form);
if (textarea.val() == '') {
return true;
}
var template = $(this).data("template");
textarea.on("fa.event.refreshfieldlist", function () {
//根据textarea内容重新渲染
fieldlist.on("fa.event.refreshfieldlist", function () {
var container = $(this);
var textarea = $("textarea[name='" + container.data("name") + "']", form);
//先清空已有的数据
$("[fieldlist-item]", container).remove();
var json = {};
try {
json = JSON.parse($(this).val());
json = JSON.parse(textarea.val());
} catch (e) {
}
$.each(json, function (i, j) {
$(".btn-append,.append", container).trigger('click', template ? j : {
key: i, value: j
append(container, {key: i, value: j}, true);
});
});
//拖拽排序
fieldlist.each(function () {
var container = $(this);
var tagName = container.data("tag") || (container.is("table") ? "tr" : "dd");
container.dragsort({
itemSelector: tagName,
dragSelector: ".btn-dragsort",
dragEnd: function () {
refresh(container);
},
placeHolderTemplate: $("<" + tagName + "/>")
});
textarea.trigger("fa.event.refreshfieldlist");
if (typeof container.data("options") === 'object' && container.data("options").appendBtn === false) {
$(".btn-append,.append", container).hide();
}
$("textarea[name='" + container.data("name") + "']", form).on("fa.event.refreshfieldlist", function () {
//兼容旧版本事件
$(this).closest(".fieldlist").trigger("fa.event.refreshfieldlist");
});
});
fieldlist.trigger("fa.event.refreshfieldlist");
});
}
},
switcher: function (form) {
@ -429,6 +465,20 @@ define(['jquery', 'bootstrap', 'upload', 'validator', 'validator-lang'], functio
});
});
}
},
tagsinput: function (form) {
if ($("[data-role='tagsinput']", form).size() > 0) {
require(['tagsinput', 'autocomplete'], function () {
$("[data-role='tagsinput']").tagsinput();
});
}
},
autocomplete: function (form) {
if ($("[data-role='autocomplete']", form).size() > 0) {
require(['autocomplete'], function () {
$("[data-role='autocomplete']").autocomplete();
});
}
}
},
api: {
@ -531,6 +581,10 @@ define(['jquery', 'bootstrap', 'upload', 'validator', 'validator-lang'], functio
events.slider(form);
events.switcher(form);
events.tagsinput(form);
events.autocomplete(form);
},
custom: {}
},

View File

@ -7140,7 +7140,8 @@ define('upload',['jquery', 'bootstrap', 'dropzone', 'template'], function ($, un
if ($(button).data("multiple") && inputObj.val() !== "") {
urlArr.push(inputObj.val());
}
urlArr.push(data.url);
var url = Config.upload.fullmode ? Fast.api.cdnurl(data.url) : data.url;
urlArr.push(url);
inputObj.val(urlArr.join(",")).trigger("change").trigger("validate");
}
//如果有回调函数
@ -7285,6 +7286,11 @@ define('upload',['jquery', 'bootstrap', 'dropzone', 'template'], function ($, un
delete options.success;
delete options.url;
multipart = $.isArray(multipart) ? {} : multipart;
var params = $(this).data("params") || {};
var category = typeof params.category !== 'undefined' ? params.category : ($(this).data("category") || '');
if (category) {
// multipart.category = category;
}
Upload.list[id] = new Dropzone(this, $.extend({
url: url,
@ -7331,6 +7337,16 @@ define('upload',['jquery', 'bootstrap', 'dropzone', 'template'], function ($, un
$(">i", this.element).addClass("dz-message");
this.options.elementHtml = $(this.element).html();
},
sending: function (file, xhr, formData) {
if (typeof file.category !== 'undefined') {
formData.append('category', file.category);
}
},
addedfile: function (file) {
var params = $(this.element).data("params") || {};
var category = typeof params.category !== 'undefined' ? params.category : ($(this.element).data("category") || '');
file.category = typeof category === 'function' ? category.call(this, file) : category;
},
addedfiles: function (files) {
if (this.options.maxFiles && (!this.options.maxFiles || this.options.maxFiles > 1) && this.options.inputId) {
var inputObj = $("#" + this.options.inputId);
@ -7360,7 +7376,8 @@ define('upload',['jquery', 'bootstrap', 'dropzone', 'template'], function ($, un
error: function (file, response, xhr) {
var responseObj = $("<div>" + (xhr && typeof xhr.responseText !== 'undefined' ? xhr.responseText : response) + "</div>");
responseObj.find("style, title, script").remove();
var ret = {code: 0, data: null, msg: responseObj.text()};
var msg = responseObj.text() || __('Network error');
var ret = {code: 0, data: null, msg: msg};
Upload.events.onUploadError(this, ret, file);
},
uploadprogress: function (file, progress, bytesSent) {
@ -7460,6 +7477,7 @@ define('upload',['jquery', 'bootstrap', 'dropzone', 'template'], function ($, un
}
var suffix = /[\.]?([a-zA-Z0-9]+)$/.exec(j);
suffix = suffix ? suffix[1] : 'file';
j = Config.upload.fullmode ? Fast.api.cdnurl(j) : j;
var value = (json && typeof json[i] !== 'undefined' ? json[i] : null);
var data = {url: j, fullurl: Fast.api.cdnurl(j), data: $(that).data(), key: i, index: i, value: value, row: value, suffix: suffix};
var html = tpl ? Template(tpl, data) : Template.render(Upload.config.previewtpl, data);
@ -9844,7 +9862,7 @@ define('upload',['jquery', 'bootstrap', 'dropzone', 'template'], function ($, un
define('form',['jquery', 'bootstrap', 'upload', 'validator', 'validator-lang'], function ($, undefined, Upload, Validator, undefined) {
var Form = {
config: {
fieldlisttpl: '<dd class="form-inline"><input type="text" name="<%=name%>[<%=index%>][key]" class="form-control" value="<%=row.key%>" size="10" /> <input type="text" name="<%=name%>[<%=index%>][value]" class="form-control" value="<%=row.value%>" /> <span class="btn btn-sm btn-danger btn-remove"><i class="fa fa-times"></i></span> <span class="btn btn-sm btn-primary btn-dragsort"><i class="fa fa-arrows"></i></span></dd>'
fieldlisttpl: '<dd class="form-inline"><input type="text" name="<%=name%>[<%=index%>][key]" class="form-control" value="<%=key%>" placeholder="<%=options.keyPlaceholder||\'\'%>" size="10" /> <input type="text" name="<%=name%>[<%=index%>][value]" class="form-control" value="<%=value%>" placeholder="<%=options.valuePlaceholder||\'\'%>" /> <span class="btn btn-sm btn-danger btn-remove"><i class="fa fa-times"></i></span> <span class="btn btn-sm btn-primary btn-dragsort"><i class="fa fa-arrows"></i></span></dd>'
},
events: {
validator: function (form, success, error, submit) {
@ -10105,20 +10123,24 @@ define('form',['jquery', 'bootstrap', 'upload', 'validator', 'validator-lang'],
if (value !== "") {
urlArr.push(inputObj.val());
}
urlArr.push(data.url)
var result = urlArr.join(",");
if (maxcount > 0) {
var nums = value === '' ? 0 : value.split(/\,/).length;
var files = data.url !== "" ? data.url.split(/\,/) : [];
$.each(files, function (i, j) {
var url = Config.upload.fullmode ? Fast.api.cdnurl(j) : j;
urlArr.push(url);
});
if (maxcount > 0) {
var remains = maxcount - nums;
if (files.length > remains) {
Toastr.error(__('You can choose up to %d file%s', remains));
return false;
}
}
var result = urlArr.join(",");
inputObj.val(result).trigger("change").trigger("validate");
} else {
$("#" + input_id).val(data.url).trigger("change").trigger("validate");
var url = Config.upload.fullmode ? Fast.api.cdnurl(data.url) : data.url;
$("#" + input_id).val(url).trigger("change").trigger("validate");
}
}
});
@ -10131,10 +10153,10 @@ define('form',['jquery', 'bootstrap', 'upload', 'validator', 'validator-lang'],
if ($(".fieldlist", form).size() > 0) {
require(['dragsort', 'template'], function (undefined, Template) {
//刷新隐藏textarea的值
var refresh = function (name) {
var refresh = function (container) {
var data = {};
var name = container.data("name");
var textarea = $("textarea[name='" + name + "']", form);
var container = $(".fieldlist[data-name='" + name + "']");
var template = container.data("template");
$.each($("input,select,textarea", container).serializeArray(), function (i, j) {
var reg = /\[(\w+)\]\[(\w+)\]$/g;
@ -10161,13 +10183,8 @@ define('form',['jquery', 'bootstrap', 'upload', 'validator', 'validator-lang'],
});
textarea.val(JSON.stringify(result));
};
//监听文本框改变事件
$(document).on('change keyup changed', ".fieldlist input,.fieldlist textarea,.fieldlist select", function () {
refresh($(this).closest(".fieldlist").data("name"));
});
//追加控制
$(".fieldlist", form).on("click", ".btn-append,.append", function (e, row) {
var container = $(this).closest(".fieldlist");
//追加一行数据
var append = function (container, row, initial) {
var tagName = container.data("tag") || (container.is("table") ? "tr" : "dd");
var index = container.data("index");
var name = container.data("name");
@ -10176,51 +10193,88 @@ define('form',['jquery', 'bootstrap', 'upload', 'validator', 'validator-lang'],
index = index ? parseInt(index) : 0;
container.data("index", index + 1);
row = row ? row : {};
var vars = {index: index, name: name, data: data, row: row};
row = typeof row.key === 'undefined' || typeof row.value === 'undefined' ? {key: '', value: row} : row;
var options = typeof data.options === 'object' ? data.options : {};
var vars = {index: index, name: name, data: data, options: options, key: row.key, value: row.value, row: row.value};
var html = template ? Template(template, vars) : Template.render(Form.config.fieldlisttpl, vars);
$(html).attr("fieldlist-item", true).insertBefore($(tagName + ":last", container));
$(this).trigger("fa.event.appendfieldlist", $(this).closest(tagName).prev());
var obj = $(html);
if ((options.deleteBtn === false || options.removeBtn === false) && initial)
obj.find(".btn-remove").remove();
if (options.dragsortBtn === false && initial)
obj.find(".btn-dragsort").remove();
if ((options.readonlyKey === true || options.disableKey === true) && initial) {
obj.find("input[name$='[key]']").prop("readonly", true);
}
obj.attr("fieldlist-item", true);
obj.insertAfter($(tagName + "[fieldlist-item]", container).length > 0 ? $(tagName + "[fieldlist-item]:last", container) : $(tagName + ":first", container));
//兼容旧版本事件
$(".btn-append,.append", container).trigger("fa.event.appendfieldlist", obj);
//新版本事件
container.trigger("fa.event.appendfieldlist", obj);
return obj;
};
var fieldlist = $(".fieldlist", form);
//监听文本框改变事件
$(document).on('change keyup changed', ".fieldlist input,.fieldlist textarea,.fieldlist select", function () {
var container = $(this).closest(".fieldlist");
refresh(container);
});
//移除控制
$(".fieldlist", form).on("click", ".btn-remove", function () {
//追加控制(点击按钮)
fieldlist.on("click", ".btn-append,.append", function (e, row) {
var container = $(this).closest(".fieldlist");
append(container, row);
// refresh(container);
});
//移除控制(点击按钮)
fieldlist.on("click", ".btn-remove", function () {
var container = $(this).closest(".fieldlist");
var tagName = container.data("tag") || (container.is("table") ? "tr" : "dd");
$(this).closest(tagName).remove();
refresh(container.data("name"));
refresh(container);
});
//渲染数据&拖拽排序
$(".fieldlist", form).each(function () {
var container = this;
var tagName = $(this).data("tag") || ($(this).is("table") ? "tr" : "dd");
$(this).dragsort({
itemSelector: tagName,
dragSelector: ".btn-dragsort",
dragEnd: function () {
refresh($(this).closest(".fieldlist").data("name"));
},
placeHolderTemplate: $("<" + tagName + "/>")
//追加控制(通过事件)
fieldlist.on("fa.event.appendtofieldlist", function (e, row) {
var container = $(this);
append(container, row);
refresh(container);
});
var textarea = $("textarea[name='" + $(this).data("name") + "']", form);
if (textarea.val() == '') {
return true;
}
var template = $(this).data("template");
textarea.on("fa.event.refreshfieldlist", function () {
//根据textarea内容重新渲染
fieldlist.on("fa.event.refreshfieldlist", function () {
var container = $(this);
var textarea = $("textarea[name='" + container.data("name") + "']", form);
//先清空已有的数据
$("[fieldlist-item]", container).remove();
var json = {};
try {
json = JSON.parse($(this).val());
json = JSON.parse(textarea.val());
} catch (e) {
}
$.each(json, function (i, j) {
$(".btn-append,.append", container).trigger('click', template ? j : {
key: i, value: j
append(container, {key: i, value: j}, true);
});
});
//拖拽排序
fieldlist.each(function () {
var container = $(this);
var tagName = container.data("tag") || (container.is("table") ? "tr" : "dd");
container.dragsort({
itemSelector: tagName,
dragSelector: ".btn-dragsort",
dragEnd: function () {
refresh(container);
},
placeHolderTemplate: $("<" + tagName + "/>")
});
textarea.trigger("fa.event.refreshfieldlist");
if (typeof container.data("options") === 'object' && container.data("options").appendBtn === false) {
$(".btn-append,.append", container).hide();
}
$("textarea[name='" + container.data("name") + "']", form).on("fa.event.refreshfieldlist", function () {
//兼容旧版本事件
$(this).closest(".fieldlist").trigger("fa.event.refreshfieldlist");
});
});
fieldlist.trigger("fa.event.refreshfieldlist");
});
}
},
switcher: function (form) {
@ -10387,7 +10441,7 @@ define('form',['jquery', 'bootstrap', 'upload', 'validator', 'validator-lang'],
* @author: pppscn <35696959@qq.com>
* @update 2017-05-07 <https://gitee.com/pp/fastadmin>
*
* @author: Karson <karsonzhang@163.com>
* @author: Karson <karson@fastadmin.net>
* @update 2018-04-05 <https://gitee.com/karson/fastadmin>
*/
@ -11228,11 +11282,13 @@ define("bootstrap-table-jumpto", ["bootstrap-table"], (function (global) {
if (typeof that.options.height !== 'undefined') paginationHeight = 0;
var height = that.$tableContainer.outerHeight(true) - scrollHeight - paginationHeight + 1;
$fixedColumns.css({
height: height
height: height,
"min-height": "calc(100% - " + (paginationHeight + scrollHeight) + "px)"
});
$fixedBody.css({
height: height - $fixedHeader.height()
height: height - $fixedHeader.height(),
"min-height": "calc(100% - " + $fixedHeader.height() + "px)",
overflow: "hidden"
});
return $fixedBody;
@ -12013,9 +12069,12 @@ define('table',['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstr
var data = [];
value = value === null ? '' : value.toString();
var arr = value != '' ? value.split(",") : [];
var url;
$.each(arr, function (index, value) {
url = Fast.api.cdnurl(value);
data.push({
src: Fast.api.cdnurl(value),
src: url,
thumb: url + Config.upload.thumbstyle
});
});
Layer.photos({
@ -12040,7 +12099,7 @@ define('table',['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstr
value = value == null || value.length === 0 ? '' : value.toString();
value = value ? value : '/assets/img/blank.gif';
var classname = typeof this.classname !== 'undefined' ? this.classname : 'img-sm img-center';
return '<a href="javascript:"><img class="' + classname + '" src="' + Fast.api.cdnurl(value) + '" /></a>';
return '<a href="javascript:"><img class="' + classname + '" src="' + Fast.api.cdnurl(value, true) + Config.upload.thumbstyle + '" /></a>';
},
images: function (value, row, index) {
value = value == null || value.length === 0 ? '' : value.toString();
@ -12049,7 +12108,7 @@ define('table',['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstr
var html = [];
$.each(arr, function (i, value) {
value = value ? value : '/assets/img/blank.gif';
html.push('<a href="javascript:"><img class="' + classname + '" src="' + Fast.api.cdnurl(value) + '" /></a>');
html.push('<a href="javascript:"><img class="' + classname + '" src="' + Fast.api.cdnurl(value, true) + Config.upload.thumbstyle + '" /></a>');
});
return html.join(' ');
},
@ -13834,6 +13893,7 @@ define("drop", function(){});
self.elem.hidden.val('');
self.elem.clear_btn.remove();
}
self.prop.current_page = 1;
self.suggest(self);
}
@ -14336,15 +14396,18 @@ define("drop", function(){});
console.error('formatItem内容格式化函数内容设置不正确');
itemText = arr_candidate[i];
}
} else itemText = arr_candidate[i];
} else {
itemText = arr_candidate[i];
}
var pkey = arr_primary_key[i];
var list = $('<li>').html(itemText).attr({
pkey: arr_primary_key[i],
pkey: pkey,
index: i
});
if (!p.formatItem) list.attr('title', itemText);
//Set selected item highlight
if ($.inArray(arr_primary_key[i].toString(), keyArr) !== -1) {
if (pkey !== null && pkey !== '' && $.inArray(pkey.toString(), keyArr) !== -1) {
list.addClass(self.css_class.selected);
}
//cache item data
@ -14611,7 +14674,12 @@ define("drop", function(){});
var p = self.option, jsonarr = new Array();
self.elem.results.find('li').each(function (i, row) {
var $row = $(row), data = $row.data('dataObj');
var text = data[p.showField] || $row.text();
var text;
if (p.formatItem && $.isFunction(p.formatItem)) {
text = p.formatItem(row);
} else {
text = data[p.showField] || $row.text();
}
var value = $row.attr('pkey');
var item = {text: text, value: value};
if (!self.isAlreadySelected(self, item)) {

View File

@ -611,9 +611,12 @@ define(['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstrap-table
var data = [];
value = value === null ? '' : value.toString();
var arr = value != '' ? value.split(",") : [];
var url;
$.each(arr, function (index, value) {
url = Fast.api.cdnurl(value);
data.push({
src: Fast.api.cdnurl(value),
src: url,
thumb: url + Config.upload.thumbstyle
});
});
Layer.photos({
@ -638,7 +641,7 @@ define(['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstrap-table
value = value == null || value.length === 0 ? '' : value.toString();
value = value ? value : '/assets/img/blank.gif';
var classname = typeof this.classname !== 'undefined' ? this.classname : 'img-sm img-center';
return '<a href="javascript:"><img class="' + classname + '" src="' + Fast.api.cdnurl(value) + '" /></a>';
return '<a href="javascript:"><img class="' + classname + '" src="' + Fast.api.cdnurl(value, true) + Config.upload.thumbstyle + '" /></a>';
},
images: function (value, row, index) {
value = value == null || value.length === 0 ? '' : value.toString();
@ -647,7 +650,7 @@ define(['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstrap-table
var html = [];
$.each(arr, function (i, value) {
value = value ? value : '/assets/img/blank.gif';
html.push('<a href="javascript:"><img class="' + classname + '" src="' + Fast.api.cdnurl(value) + '" /></a>');
html.push('<a href="javascript:"><img class="' + classname + '" src="' + Fast.api.cdnurl(value, true) + Config.upload.thumbstyle + '" /></a>');
});
return html.join(' ');
},

View File

@ -27,7 +27,8 @@ define(['jquery', 'bootstrap', 'dropzone', 'template'], function ($, undefined,
if ($(button).data("multiple") && inputObj.val() !== "") {
urlArr.push(inputObj.val());
}
urlArr.push(data.url);
var url = Config.upload.fullmode ? Fast.api.cdnurl(data.url) : data.url;
urlArr.push(url);
inputObj.val(urlArr.join(",")).trigger("change").trigger("validate");
}
//如果有回调函数
@ -169,9 +170,15 @@ define(['jquery', 'bootstrap', 'dropzone', 'template'], function ($, undefined,
}(maxsize));
var options = $(this).data() || {};
options = $.extend(true, {}, options, $(this).data("upload-options") || {});
delete options.success;
delete options.url;
multipart = $.isArray(multipart) ? {} : multipart;
var params = $(this).data("params") || {};
var category = typeof params.category !== 'undefined' ? params.category : ($(this).data("category") || '');
if (category) {
// multipart.category = category;
}
Upload.list[id] = new Dropzone(this, $.extend({
url: url,
@ -218,6 +225,16 @@ define(['jquery', 'bootstrap', 'dropzone', 'template'], function ($, undefined,
$(">i", this.element).addClass("dz-message");
this.options.elementHtml = $(this.element).html();
},
sending: function (file, xhr, formData) {
if (typeof file.category !== 'undefined') {
formData.append('category', file.category);
}
},
addedfile: function (file) {
var params = $(this.element).data("params") || {};
var category = typeof params.category !== 'undefined' ? params.category : ($(this.element).data("category") || '');
file.category = typeof category === 'function' ? category.call(this, file) : category;
},
addedfiles: function (files) {
if (this.options.maxFiles && (!this.options.maxFiles || this.options.maxFiles > 1) && this.options.inputId) {
var inputObj = $("#" + this.options.inputId);
@ -247,7 +264,8 @@ define(['jquery', 'bootstrap', 'dropzone', 'template'], function ($, undefined,
error: function (file, response, xhr) {
var responseObj = $("<div>" + (xhr && typeof xhr.responseText !== 'undefined' ? xhr.responseText : response) + "</div>");
responseObj.find("style, title, script").remove();
var ret = {code: 0, data: null, msg: responseObj.text()};
var msg = responseObj.text() || __('Network error');
var ret = {code: 0, data: null, msg: msg};
Upload.events.onUploadError(this, ret, file);
},
uploadprogress: function (file, progress, bytesSent) {
@ -347,6 +365,7 @@ define(['jquery', 'bootstrap', 'dropzone', 'template'], function ($, undefined,
}
var suffix = /[\.]?([a-zA-Z0-9]+)$/.exec(j);
suffix = suffix ? suffix[1] : 'file';
j = Config.upload.fullmode ? Fast.api.cdnurl(j) : j;
var value = (json && typeof json[i] !== 'undefined' ? json[i] : null);
var data = {url: j, fullurl: Fast.api.cdnurl(j), data: $(that).data(), key: i, index: i, value: value, row: value, suffix: suffix};
var html = tpl ? Template(tpl, data) : Template.render(Upload.config.previewtpl, data);

View File

@ -0,0 +1,654 @@
/*
* bootstrap-tagsinput v0.8.0
*
* For details, see the web site: https://github.com/bootstrap-tagsinput/bootstrap-tagsinput
*/
(function ($) {
"use strict";
var defaultOptions = {
tagClass: function (item) {
return 'label label-info';
},
focusClass: 'focus',
itemValue: function (item) {
return item ? item.toString() : item;
},
itemText: function (item) {
return this.itemValue(item);
},
itemTitle: function (item) {
return null;
},
freeInput: true,
addOnBlur: true,
maxTags: undefined,
maxChars: undefined,
confirmKeys: [13, 44],
delimiter: ',',
inputMinWidth: 80,
delimiterRegex: null,
cancelConfirmKeysOnEmpty: false,
onTagExists: function (item, $tag) {
$tag.hide().fadeIn();
},
trimValue: false,
allowDuplicates: false,
triggerChange: true
};
/**
* Constructor function
*/
function TagsInput(element, options) {
this.isInit = true;
this.itemsArray = [];
this.$element = $(element);
this.$element.hide();
this.isSelect = (element.tagName === 'SELECT');
this.multiple = (this.isSelect && element.hasAttribute('multiple'));
this.objectItems = options && options.itemValue;
this.placeholderText = element.hasAttribute('placeholder') ? this.$element.attr('placeholder') : '';
this.inputSize = Math.max(1, this.placeholderText.length);
this.$container = $('<div class="bootstrap-tagsinput"></div>');
this.$input = $('<input type="text" placeholder="' + this.placeholderText + '"/>').appendTo(this.$container);
this.$element.before(this.$container);
this.build(options);
this.isInit = false;
}
TagsInput.prototype = {
constructor: TagsInput,
/**
* Adds the given item as a new tag. Pass true to dontPushVal to prevent
* updating the elements val()
*/
add: function (item, dontPushVal, options) {
var self = this;
if (self.options.maxTags && self.itemsArray.length >= self.options.maxTags)
return;
// Ignore falsey values, except false
if (item !== false && !item)
return;
// Trim value
if (typeof item === "string" && self.options.trimValue) {
item = $.trim(item);
}
// Throw an error when trying to add an object while the itemValue option was not set
if (typeof item === "object" && !self.objectItems)
throw("Can't add objects when itemValue option is not set");
// Ignore strings only containg whitespace
if (item.toString().match(/^\s*$/))
return;
// If SELECT but not multiple, remove current tag
if (self.isSelect && !self.multiple && self.itemsArray.length > 0)
self.remove(self.itemsArray[0]);
if (typeof item === "string" && this.$element[0].tagName === 'INPUT') {
var delimiter = (self.options.delimiterRegex) ? self.options.delimiterRegex : self.options.delimiter;
var items = item.split(delimiter);
if (items.length > 1) {
for (var i = 0; i < items.length; i++) {
this.add(items[i], true);
}
if (!dontPushVal)
self.pushVal(self.options.triggerChange);
return;
}
}
var itemValue = self.options.itemValue(item),
itemText = self.options.itemText(item),
tagClass = self.options.tagClass(item),
itemTitle = self.options.itemTitle(item);
// Ignore items allready added
var existing = $.grep(self.itemsArray, function (item) {
return self.options.itemValue(item) === itemValue;
})[0];
if (existing && !self.options.allowDuplicates) {
// Invoke onTagExists
if (self.options.onTagExists) {
var $existingTag = $(".tag", self.$container).filter(function () {
return $(this).data("item") === existing;
});
self.options.onTagExists(item, $existingTag);
}
return;
}
// if length greater than limit
if (self.items().toString().length + item.length + 1 > self.options.maxInputLength)
return;
// raise beforeItemAdd arg
var beforeItemAddEvent = $.Event('beforeItemAdd', {item: item, cancel: false, options: options});
self.$element.trigger(beforeItemAddEvent);
if (beforeItemAddEvent.cancel)
return;
// register item in internal array and map
self.itemsArray.push(item);
// add a tag element
var $tag = $('<span class="tag ' + htmlEncode(tagClass) + (itemTitle !== null ? ('" title="' + itemTitle) : '') + '">' + htmlEncode(itemText) + '<span data-role="remove"></span></span>');
$tag.data('item', item);
self.findInputWrapper().before($tag);
$tag.after(' ');
// Check to see if the tag exists in its raw or uri-encoded form
var optionExists = (
$('option[value="' + encodeURIComponent(itemValue) + '"]', self.$element).length ||
$('option[value="' + htmlEncode(itemValue) + '"]', self.$element).length
);
// add <option /> if item represents a value not present in one of the <select />'s options
if (self.isSelect && !optionExists) {
var $option = $('<option selected>' + htmlEncode(itemText) + '</option>');
$option.data('item', item);
$option.attr('value', itemValue);
self.$element.append($option);
}
if (!dontPushVal)
self.pushVal(self.options.triggerChange);
// Add class when reached maxTags
if (self.options.maxTags === self.itemsArray.length || self.items().toString().length === self.options.maxInputLength)
self.$container.addClass('bootstrap-tagsinput-max');
// If using autocomplete, once the tag has been added, clear the autocomplete value so it does not stick around in the input.
if (self.options.autocomplete) {
// self.$input.autocomplete('clear');
}
if (this.isInit) {
self.$element.trigger($.Event('itemAddedOnInit', {item: item, options: options}));
} else {
self.$element.trigger($.Event('itemAdded', {item: item, options: options}));
}
},
/**
* Removes the given item. Pass true to dontPushVal to prevent updating the
* elements val()
*/
remove: function (item, dontPushVal, options) {
var self = this;
if (self.objectItems) {
if (typeof item === "object")
item = $.grep(self.itemsArray, function (other) {
return self.options.itemValue(other) == self.options.itemValue(item);
});
else
item = $.grep(self.itemsArray, function (other) {
return self.options.itemValue(other) == item;
});
item = item[item.length - 1];
}
if (item) {
var beforeItemRemoveEvent = $.Event('beforeItemRemove', {item: item, cancel: false, options: options});
self.$element.trigger(beforeItemRemoveEvent);
if (beforeItemRemoveEvent.cancel)
return;
$('.tag', self.$container).filter(function () {
return $(this).data('item') === item;
}).remove();
$('option', self.$element).filter(function () {
return $(this).data('item') === item;
}).remove();
if ($.inArray(item, self.itemsArray) !== -1)
self.itemsArray.splice($.inArray(item, self.itemsArray), 1);
}
if (!dontPushVal)
self.pushVal(self.options.triggerChange);
// Remove class when reached maxTags
if (self.options.maxTags > self.itemsArray.length)
self.$container.removeClass('bootstrap-tagsinput-max');
self.$element.trigger($.Event('itemRemoved', {item: item, options: options}));
},
/**
* Removes all items
*/
removeAll: function () {
var self = this;
$('.tag', self.$container).remove();
$('option', self.$element).remove();
while (self.itemsArray.length > 0)
self.itemsArray.pop();
self.pushVal(self.options.triggerChange);
},
/**
* Refreshes the tags so they match the text/value of their corresponding
* item.
*/
refresh: function () {
var self = this;
$('.tag', self.$container).each(function () {
var $tag = $(this),
item = $tag.data('item'),
itemValue = self.options.itemValue(item),
itemText = self.options.itemText(item),
tagClass = self.options.tagClass(item);
// Update tag's class and inner text
$tag.attr('class', null);
$tag.addClass('tag ' + htmlEncode(tagClass));
$tag.contents().filter(function () {
return this.nodeType == 3;
})[0].nodeValue = htmlEncode(itemText);
if (self.isSelect) {
var option = $('option', self.$element).filter(function () {
return $(this).data('item') === item;
});
option.attr('value', itemValue);
}
});
},
/**
* Returns the items added as tags
*/
items: function () {
return this.itemsArray;
},
/**
* Assembly value by retrieving the value of each item, and set it on the
* element.
*/
pushVal: function () {
var self = this,
val = $.map(self.items(), function (item) {
return self.options.itemValue(item).toString();
});
self.$element.val(val, true);
if (self.options.triggerChange)
self.$element.trigger('change');
},
/**
* Initializes the tags input behaviour on the element
*/
build: function (options) {
var self = this;
self.options = $.extend({}, defaultOptions, options);
// When itemValue is set, freeInput should always be false
if (self.objectItems)
self.options.freeInput = false;
makeOptionItemFunction(self.options, 'itemValue');
makeOptionItemFunction(self.options, 'itemText');
makeOptionFunction(self.options, 'tagClass');
if (self.options.autocomplete) {
var autocomplete = self.options.autocomplete || {};
// makeOptionFunction(autocomplete, 'lookup');
self.$input.autocomplete($.extend(true, {}, {
type: 'post',
params: function (q) {
var params = {};
params['name'] = self.$element.prop("name");
params['tags'] = self.$element.val();
return params;
},
onSelect: function (suggestion) {
self.add(suggestion.value);
self.$input.val('').width(self.options.inputMinWidth).focus();
}
}, autocomplete));
}
self.$container.on('click', $.proxy(function (event) {
if (!self.$element.attr('disabled')) {
self.$input.removeAttr('disabled');
}
self.$input.focus();
if (self.options.autocomplete && self.$input.autocomplete().visible) {
clearTimeout(self.$input.autocomplete().blurTimeoutId);
}
}, self));
if (self.options.addOnBlur && self.options.freeInput) {
self.$input.on('focusout', $.proxy(function (event) {
// HACK: only process on focusout when no autocomplete opened, to
// avoid adding the autocomplete text as tag
if (!self.options.autocomplete) {
self.add(self.$input.val());
self.$input.val('').css("width", self.options.inputMinWidth);
} else {
var autocomplete = self.$input.autocomplete();
setTimeout(function () {
if (!autocomplete.visible && self.$input.val() !== '') {
self.add(self.$input.val());
self.$input.val('').css("width", self.options.inputMinWidth);
}
}, 210);
}
}, self));
}
// Toggle the 'focus' css class on the container when it has focus
self.$container.on({
focusin: function () {
self.$container.addClass(self.options.focusClass);
},
focusout: function () {
self.$container.removeClass(self.options.focusClass);
},
});
self.$container.on('keydown', 'input', $.proxy(function (event) {
var $input = $(event.target),
$inputWrapper = self.findInputWrapper();
if (self.$element.attr('disabled')) {
self.$input.attr('disabled', 'disabled');
return;
}
switch (event.which) {
// BACKSPACE
case 8:
if (doGetCaretPosition($input[0]) === 0) {
var prev = $inputWrapper.prev();
if (prev.length) {
self.remove(prev.data('item'));
}
}
break;
// DELETE
case 46:
if (doGetCaretPosition($input[0]) === 0) {
var next = $inputWrapper.next();
if (next.length) {
self.remove(next.data('item'));
}
}
break;
// LEFT ARROW
case 37:
// Try to move the input before the previous tag
var $prevTag = $inputWrapper.prev();
if ($input.val().length === 0 && $prevTag[0]) {
$prevTag.before($inputWrapper);
$input.focus();
}
break;
// RIGHT ARROW
case 39:
// Try to move the input after the next tag
var $nextTag = $inputWrapper.next();
if ($input.val().length === 0 && $nextTag[0]) {
$nextTag.after($inputWrapper);
$input.focus();
}
break;
default:
// ignore
}
$input.css('width', self.getInputTextWidth());
}, self));
self.$container.on('keypress', 'input', $.proxy(function (event) {
var $input = $(event.target);
if (self.$element.attr('disabled')) {
self.$input.attr('disabled', 'disabled');
return;
}
var text = $input.val(),
maxLengthReached = self.options.maxChars && text.length >= self.options.maxChars;
if (self.options.freeInput && (keyCombinationInList(event, self.options.confirmKeys) || maxLengthReached)) {
// Only attempt to add a tag if there is data in the field
if (text.length !== 0) {
self.add(maxLengthReached ? text.substr(0, self.options.maxChars) : text);
$input.val('').css("width", self.options.inputMinWidth);
}
// If the field is empty, let the event triggered fire as usual
if (self.options.cancelConfirmKeysOnEmpty === false) {
event.preventDefault();
}
}
$input.css('width', self.getInputTextWidth());
}, self));
// Remove icon clicked
self.$container.on('click', '[data-role=remove]', $.proxy(function (event) {
if (self.$element.attr('disabled')) {
return;
}
self.remove($(event.target).closest('.tag').data('item'));
}, self));
// Only add existing value as tags when using strings as tags
if (self.options.itemValue === defaultOptions.itemValue) {
if (self.$element[0].tagName === 'INPUT') {
self.add(self.$element.val());
} else {
$('option', self.$element).each(function () {
self.add($(this).attr('value'), true);
});
}
}
},
/**
* Removes all tagsinput behaviour and unregsiter all event handlers
*/
destroy: function () {
var self = this;
// Unbind events
self.$container.off('keypress', 'input');
self.$container.off('click', '[role=remove]');
self.$container.remove();
self.$element.removeData('tagsinput');
self.$element.show();
},
/**
* Sets focus on the tagsinput
*/
focus: function () {
this.$input.focus();
},
/**
* Returns the internal input element
*/
input: function () {
return this.$input;
},
/**
* Returns the element which is wrapped around the internal input. This
* is normally the $container, but typeahead.js moves the $input element.
*/
findInputWrapper: function () {
var elt = this.$input[0],
container = this.$container[0];
while (elt && elt.parentNode !== container)
elt = elt.parentNode;
return $(elt);
},
/**
* Get input text width
* @returns {number}
*/
getInputTextWidth: function () {
var $input = this.$input;
var self = this;
var msgspan = $input.next().length > 0 ? $input.next() : $("<span />").addClass("tagsinput-text").insertAfter($input);
var textWidth = msgspan.text($input.val()).outerWidth();
textWidth = Math.max(textWidth, self.options.inputMinWidth);
textWidth = Math.min(textWidth, self.$container.innerWidth());
return textWidth;
}
};
/**
* Register JQuery plugin
*/
$.fn.tagsinput = function (arg1, arg2, arg3) {
var results = [];
this.each(function () {
var tagsinput = $(this).data('tagsinput');
// Initialize a new tags input
if (!tagsinput) {
tagsinput = new TagsInput(this, $.extend(true, {}, arg1, $(this).data('tagsinput-options') || {}));
$(this).data('tagsinput', tagsinput);
results.push(tagsinput);
if (this.tagName === 'SELECT') {
$('option', $(this)).attr('selected', 'selected');
}
// Init tags from $(this).val()
$(this).val($(this).val());
} else if (!arg1 && !arg2) {
// tagsinput already exists
// no function, trying to init
results.push(tagsinput);
} else if (tagsinput[arg1] !== undefined) {
// Invoke function on existing tags input
if (tagsinput[arg1].length === 3 && arg3 !== undefined) {
var retVal = tagsinput[arg1](arg2, null, arg3);
} else {
var retVal = tagsinput[arg1](arg2);
}
if (retVal !== undefined)
results.push(retVal);
}
});
return results.length > 1 ? results : results[0];
};
$.fn.tagsinput.Constructor = TagsInput;
/**
* Most options support both a string or number as well as a function as
* option value. This function makes sure that the option with the given
* key in the given options is wrapped in a function
*/
function makeOptionItemFunction(options, key) {
if (typeof options[key] !== 'function') {
var propertyName = options[key];
options[key] = function (item) {
return item[propertyName];
};
}
}
function makeOptionFunction(options, key) {
if (typeof options[key] !== 'function') {
var value = options[key];
options[key] = function () {
return value;
};
}
}
/**
* HtmlEncodes the given value
*/
var htmlEncodeContainer = $('<div />');
function htmlEncode(value) {
if (value) {
return htmlEncodeContainer.text(value).html();
} else {
return '';
}
}
/**
* Returns the position of the caret in the given input field
* http://flightschool.acylt.com/devnotes/caret-position-woes/
*/
function doGetCaretPosition(oField) {
var iCaretPos = 0;
if (document.selection) {
oField.focus();
var oSel = document.selection.createRange();
oSel.moveStart('character', -oField.value.length);
iCaretPos = oSel.text.length;
} else if (oField.selectionStart || oField.selectionStart == '0') {
iCaretPos = oField.selectionStart;
}
return (iCaretPos);
}
/**
* Returns boolean indicates whether user has pressed an expected key combination.
* @param object keyPressEvent: JavaScript event object, refer
* http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
* @param object lookupList: expected key combinations, as in:
* [13, {which: 188, shiftKey: true}]
*/
function keyCombinationInList(keyPressEvent, lookupList) {
var found = false;
$.each(lookupList, function (index, keyCombination) {
if (typeof (keyCombination) === 'number' && keyPressEvent.which === keyCombination) {
found = true;
return false;
}
if (keyPressEvent.which === keyCombination.which) {
var alt = !keyCombination.hasOwnProperty('altKey') || keyPressEvent.altKey === keyCombination.altKey,
shift = !keyCombination.hasOwnProperty('shiftKey') || keyPressEvent.shiftKey === keyCombination.shiftKey,
ctrl = !keyCombination.hasOwnProperty('ctrlKey') || keyPressEvent.ctrlKey === keyCombination.ctrlKey;
if (alt && shift && ctrl) {
found = true;
return false;
}
}
});
return found;
}
})(window.jQuery);

Some files were not shown because too many files have changed in this diff Show More