新增前台模块和API模块的权限控制功能

新增CRUD排除字段的功能
新增API模块短信发送、开发示例控制器
新增前台通用的会员权限类Auth
新增前台Token操作类
新增插件管理本地插件的搜索功能
修复压缩打包在Windows下路径中含有空格导致错误的BUG
修复fastadmin.less无法编译为CSS的BUG
优化插件管理中的搜索
优化权限规则的增改
优化后台皮肤Black,实为White
优化跳转页模板在Chrome下自动翻译的BUG
pull/33/head v1.0.0.20180117_beta
Karson 2018-01-17 17:29:22 +08:00
parent 55786edeb0
commit 6a1100f018
53 changed files with 3511 additions and 527 deletions

View File

@ -87,6 +87,11 @@ class Crud extends Command
*/
protected $reservedField = ['admin_id', 'createtime', 'updatetime'];
/**
* 排除字段
*/
protected $ignoreFields = [];
/**
* 排序字段
*/
@ -122,6 +127,7 @@ class Crud extends Command
->addOption('citysuffix', null, Option::VALUE_OPTIONAL | Option::VALUE_IS_ARRAY, 'automatically generate citypicker component with suffix', null)
->addOption('selectpagesuffix', null, Option::VALUE_OPTIONAL | Option::VALUE_IS_ARRAY, 'automatically generate selectpage component with suffix', null)
->addOption('selectpagessuffix', null, Option::VALUE_OPTIONAL | Option::VALUE_IS_ARRAY, 'automatically generate multiple selectpage component with suffix', null)
->addOption('ignorefields', null, Option::VALUE_OPTIONAL | Option::VALUE_IS_ARRAY, 'ignore fields', null)
->addOption('sortfield', null, Option::VALUE_OPTIONAL, 'sort field', null)
->addOption('editorclass', null, Option::VALUE_OPTIONAL, 'automatically generate editor class', null)
->setDescription('Build CRUD controller and model from table');
@ -174,6 +180,8 @@ class Crud extends Command
$selectpagesuffix = $input->getOption('selectpagesuffix');
//selectpage多选后缀
$selectpagessuffix = $input->getOption('selectpagessuffix');
//排除字段
$ignoreFields = $input->getOption('ignorefields');
//排序字段
$sortfield = $input->getOption('sortfield');
//编辑器Class
@ -196,6 +204,8 @@ class Crud extends Command
$this->selectpageSuffix = $selectpagesuffix;
if ($selectpagessuffix)
$this->selectpagesSuffix = $selectpagessuffix;
if ($ignoreFields)
$this->ignoreFields = $ignoreFields;
if ($editorclass)
$this->editorClass = $editorclass;
if ($sortfield)
@ -444,7 +454,7 @@ class Crud extends Command
}
$inputType = '';
//createtime和updatetime是保留字段不能修改和添加
if ($v['COLUMN_KEY'] != 'PRI' && !in_array($field, $this->reservedField))
if ($v['COLUMN_KEY'] != 'PRI' && !in_array($field, $this->reservedField) && !in_array($field, $this->ignoreFields))
{
$inputType = $this->getFieldType($v);

View File

@ -57,8 +57,8 @@ class Min extends Command
{
if (IS_WIN)
{
// Winsows下请手动配置配置该值,一般将该值配置为 '"C:/Program Files/nodejs/node.exe"'除非你的Node安装路径有变更
$nodeExec = '"C:/Program Files/nodejs/node.exe"';
// Winsows下请手动配置配置该值,一般将该值配置为 '"C:\Program Files\nodejs\node.exe"'除非你的Node安装路径有变更
$nodeExec = '"C:\Program Files\nodejs\node.exe"';
}
else
{
@ -117,7 +117,7 @@ class Min extends Command
$output->info("Compress " . $data["{$res}BaseName"] . ".{$res}");
// 执行压缩
echo exec("{$nodeExec} {$minPath}r.js -o {$tempFile} >> {$minPath}node.log");
echo exec("{$nodeExec} \"{$minPath}r.js\" -o \"{$tempFile}\" >> \"{$minPath}node.log\"");
}
}

View File

@ -305,31 +305,15 @@ class Addon extends Backend
{
$offset = (int) $this->request->get("offset");
$limit = (int) $this->request->get("limit");
$filter = $this->request->get("filter");
$filter = (array) json_decode($filter, true);
foreach ($filter as $k => &$v)
{
$v = htmlspecialchars(strip_tags($v));
}
unset($v);
$where = ['status' => 'normal'];
if (isset($filter['id']))
{
$where['id'] = (int) $filter['id'];
}
if (isset($filter['name']))
{
$where['name'] = ['like', "%{$filter['name']}%"];
}
if (isset($filter['title']))
{
$where['title'] = ['like', "%{$filter['title']}%"];
}
$search = $this->request->get("search");
$search = htmlspecialchars(strip_tags($search));
$addons = get_addon_list();
$list = [];
foreach ($addons as $k => $v)
{
if ($search && stripos($v['name'], $search) === FALSE && stripos($v['intro'], $search) === FALSE)
continue;
$v['flag'] = '';
$v['banner'] = '';
$v['image'] = '';
@ -340,8 +324,9 @@ class Addon extends Backend
$v['createtime'] = 0;
$list[] = $v;
}
$total = count($list);
$list = array_slice($list, $offset, $limit);
$result = array("total" => count($addons), "rows" => $list);
$result = array("total" => $total, "rows" => $list);
$callback = $this->request->get('callback') ? "jsonp" : "json";
return $callback($result);

View File

@ -58,7 +58,6 @@ return [
'Uninstall successful' => '卸载成功',
'Operate successful' => '操作成功',
'Addon info file was not found' => '插件配置文件未找到',
'Addon info file data incorrect' => '插件配置文件未找到',
'Addon info file data incorrect' => '插件配置信息不正确',
'Addon already exists' => '上传的插件已经存在',
];

View File

@ -6,10 +6,12 @@ return [
'Remark' => '备注',
'Icon' => '图标',
'Alert' => '警告',
'Name' => '规则URL',
'Name' => '规则',
'Controller/Action' => '控制器名/方法名',
'Ismenu' => '菜单',
'Search icon' => '搜索图标',
'Menu tips' => '规则任意,不可重复,仅做层级显示,无需匹配控制器和方法',
'Node tips' => '控制器/方法名',
'The non-menu rule must have parent' => '非菜单规则节点必须有父级',
'If not necessary, use the command line to build rule' => '非必要情况下请直接使用命令行php think menu来生成',
'Name only supports letters, numbers, underscore and slash' => 'URL规则只能是小写字母、数字、下划线和/组成',

View File

@ -12,13 +12,13 @@
<div class="form-group">
<label for="pid" class="control-label col-xs-12 col-sm-2">{:__('Parent')}:</label>
<div class="col-xs-12 col-sm-8">
{:build_select('row[pid]', $ruledata, null, ['class'=>'form-control selectpicker', 'required'=>''])}
{:build_select('row[pid]', $ruledata, null, ['class'=>'form-control', 'required'=>''])}
</div>
</div>
<div class="form-group">
<label for="name" class="control-label col-xs-12 col-sm-2">{:__('Name')}:</label>
<div class="col-xs-12 col-sm-8">
<input type="text" class="form-control" id="name" name="row[name]" placeholder="{:__('Controller/Action')}" value="" data-rule="required" />
<input type="text" class="form-control" id="name" name="row[name]" data-placeholder-node="{:__('Node tips')}" data-placeholder-menu="{:__('Menu tips')}" value="" data-rule="required" />
</div>
</div>
<div class="form-group">

View File

@ -8,13 +8,13 @@
<div class="form-group">
<label for="pid" class="control-label col-xs-12 col-sm-2">{:__('Parent')}:</label>
<div class="col-xs-12 col-sm-8">
{:build_select('row[pid]', $ruledata, $row['pid'], ['class'=>'form-control selectpicker', 'required'=>''])}
{:build_select('row[pid]', $ruledata, $row['pid'], ['class'=>'form-control', 'required'=>''])}
</div>
</div>
<div class="form-group">
<label for="name" class="control-label col-xs-12 col-sm-2">{:__('Name')}:</label>
<div class="col-xs-12 col-sm-8">
<input type="text" class="form-control" id="name" name="row[name]" placeholder="{:__('Controller/Action')}" value="{$row.name}" data-rule="required" />
<input type="text" class="form-control" id="name" name="row[name]" data-placeholder-node="{:__('Node tips')}" data-placeholder-menu="{:__('Menu tips')}" value="{$row.name}" data-rule="required" />
</div>
</div>
<div class="form-group">

View File

@ -30,13 +30,13 @@
<h4 class="control-sidebar-heading">{:__('Skins')}</h4>
<ul class="list-unstyled clearfix skin-list">
<li><a href="javascript:;" data-skin="skin-blue" style="" class="clearfix full-opacity-hover"><div><span style="display:block; width: 20%; float: left; height: 7px; background: #367fa9;"></span><span class="bg-light-blue" style="display:block; width: 80%; float: left; height: 7px;"></span></div><div><span style="display:block; width: 20%; float: left; height: 20px; background: #222d32;"></span><span style="display:block; width: 80%; float: left; height: 20px; background: #f4f5f7;"></span></div></a><p class="text-center no-margin">Blue</p></li>
<li><a href="javascript:;" data-skin="skin-black" class="clearfix full-opacity-hover"><div style="box-shadow: 0 0 2px rgba(0,0,0,0.1)" class="clearfix"><span style="display:block; width: 20%; float: left; height: 7px; background: #fefefe;"></span><span style="display:block; width: 80%; float: left; height: 7px; background: #fefefe;"></span></div><div><span style="display:block; width: 20%; float: left; height: 20px; background: #222;"></span><span style="display:block; width: 80%; float: left; height: 20px; background: #f4f5f7;"></span></div></a><p class="text-center no-margin">Black</p></li>
<li><a href="javascript:;" data-skin="skin-white" class="clearfix full-opacity-hover"><div style="box-shadow: 0 0 2px rgba(0,0,0,0.1)" class="clearfix"><span style="display:block; width: 20%; float: left; height: 7px; background: #fefefe;"></span><span style="display:block; width: 80%; float: left; height: 7px; background: #fefefe;"></span></div><div><span style="display:block; width: 20%; float: left; height: 20px; background: #222;"></span><span style="display:block; width: 80%; float: left; height: 20px; background: #f4f5f7;"></span></div></a><p class="text-center no-margin">White</p></li>
<li><a href="javascript:;" data-skin="skin-purple" class="clearfix full-opacity-hover"><div><span style="display:block; width: 20%; float: left; height: 7px;" class="bg-purple-active"></span><span class="bg-purple" style="display:block; width: 80%; float: left; height: 7px;"></span></div><div><span style="display:block; width: 20%; float: left; height: 20px; background: #222d32;"></span><span style="display:block; width: 80%; float: left; height: 20px; background: #f4f5f7;"></span></div></a><p class="text-center no-margin">Purple</p></li>
<li><a href="javascript:;" data-skin="skin-green" class="clearfix full-opacity-hover"><div><span style="display:block; width: 20%; float: left; height: 7px;" class="bg-green-active"></span><span class="bg-green" style="display:block; width: 80%; float: left; height: 7px;"></span></div><div><span style="display:block; width: 20%; float: left; height: 20px; background: #222d32;"></span><span style="display:block; width: 80%; float: left; height: 20px; background: #f4f5f7;"></span></div></a><p class="text-center no-margin">Green</p></li>
<li><a href="javascript:;" data-skin="skin-red" class="clearfix full-opacity-hover"><div><span style="display:block; width: 20%; float: left; height: 7px;" class="bg-red-active"></span><span class="bg-red" style="display:block; width: 80%; float: left; height: 7px;"></span></div><div><span style="display:block; width: 20%; float: left; height: 20px; background: #222d32;"></span><span style="display:block; width: 80%; float: left; height: 20px; background: #f4f5f7;"></span></div></a><p class="text-center no-margin">Red</p></li>
<li><a href="javascript:;" data-skin="skin-yellow" class="clearfix full-opacity-hover"><div><span style="display:block; width: 20%; float: left; height: 7px;" class="bg-yellow-active"></span><span class="bg-yellow" style="display:block; width: 80%; float: left; height: 7px;"></span></div><div><span style="display:block; width: 20%; float: left; height: 20px; background: #222d32;"></span><span style="display:block; width: 80%; float: left; height: 20px; background: #f4f5f7;"></span></div></a><p class="text-center no-margin">Yellow</p></li>
<li><a href="javascript:;" data-skin="skin-blue-light" class="clearfix full-opacity-hover"><div><span style="display:block; width: 20%; float: left; height: 7px; background: #367fa9;"></span><span class="bg-light-blue" style="display:block; width: 80%; float: left; height: 7px;"></span></div><div><span style="display:block; width: 20%; float: left; height: 20px; background: #f9fafc;"></span><span style="display:block; width: 80%; float: left; height: 20px; background: #f4f5f7;"></span></div></a><p class="text-center no-margin" style="font-size: 12px">Blue Light</p></li>
<li><a href="javascript:;" data-skin="skin-black-light" class="clearfix full-opacity-hover"><div style="box-shadow: 0 0 2px rgba(0,0,0,0.1)" class="clearfix"><span style="display:block; width: 20%; float: left; height: 7px; background: #fefefe;"></span><span style="display:block; width: 80%; float: left; height: 7px; background: #fefefe;"></span></div><div><span style="display:block; width: 20%; float: left; height: 20px; background: #f9fafc;"></span><span style="display:block; width: 80%; float: left; height: 20px; background: #f4f5f7;"></span></div></a><p class="text-center no-margin" style="font-size: 12px">Black Light</p></li>
<li><a href="javascript:;" data-skin="skin-white-light" class="clearfix full-opacity-hover"><div style="box-shadow: 0 0 2px rgba(0,0,0,0.1)" class="clearfix"><span style="display:block; width: 20%; float: left; height: 7px; background: #fefefe;"></span><span style="display:block; width: 80%; float: left; height: 7px; background: #fefefe;"></span></div><div><span style="display:block; width: 20%; float: left; height: 20px; background: #f9fafc;"></span><span style="display:block; width: 80%; float: left; height: 20px; background: #f4f5f7;"></span></div></a><p class="text-center no-margin" style="font-size: 12px">White Light</p></li>
<li><a href="javascript:;" data-skin="skin-purple-light" class="clearfix full-opacity-hover"><div><span style="display:block; width: 20%; float: left; height: 7px;" class="bg-purple-active"></span><span class="bg-purple" style="display:block; width: 80%; float: left; height: 7px;"></span></div><div><span style="display:block; width: 20%; float: left; height: 20px; background: #f9fafc;"></span><span style="display:block; width: 80%; float: left; height: 20px; background: #f4f5f7;"></span></div></a><p class="text-center no-margin" style="font-size: 12px">Purple Light</p></li>
<li><a href="javascript:;" data-skin="skin-green-light" class="clearfix full-opacity-hover"><div><span style="display:block; width: 20%; float: left; height: 7px;" class="bg-green-active"></span><span class="bg-green" style="display:block; width: 80%; float: left; height: 7px;"></span></div><div><span style="display:block; width: 20%; float: left; height: 20px; background: #f9fafc;"></span><span style="display:block; width: 80%; float: left; height: 20px; background: #f4f5f7;"></span></div></a><p class="text-center no-margin" style="font-size: 12px">Green Light</p></li>
<li><a href="javascript:;" data-skin="skin-red-light" class="clearfix full-opacity-hover"><div><span style="display:block; width: 20%; float: left; height: 7px;" class="bg-red-active"></span><span class="bg-red" style="display:block; width: 80%; float: left; height: 7px;"></span></div><div><span style="display:block; width: 20%; float: left; height: 20px; background: #f9fafc;"></span><span style="display:block; width: 80%; float: left; height: 20px; background: #f4f5f7;"></span></div></a><p class="text-center no-margin" style="font-size: 12px">Red Light</p></li>

View File

@ -0,0 +1,50 @@
<?php
namespace app\api\controller;
use app\api\model\Area;
use app\common\controller\Api;
use fast\Version;
use think\Config;
/**
* 公共接口
*/
class Common extends Api
{
protected $noNeedLogin = '*';
protected $noNeedRight = '*';
public function _initialize()
{
parent::_initialize();
}
/**
* 加载初始化
*
* 必选参数:version<br>
* 可选参数:lng,lat
*/
public function init()
{
if ($version = $this->request->request('version'))
{
$lng = $this->request->request('lng');
$lat = $this->request->request('lat');
$content = [
'citydata' => Area::getCityFromLngLat($lng, $lat),
'versiondata' => Version::check($version),
'uploaddata' => Config::get('upload'),
'coverdata' => Config::get("cover"),
];
$this->success('', $content);
}
else
{
$this->error(__('Invalid parameters'));
}
}
}

View File

@ -0,0 +1,55 @@
<?php
namespace app\api\controller;
use app\common\controller\Api;
/**
* 示例接口
*/
class Demo extends Api
{
//如果$noNeedLogin为空表示所有接口都需要登录才能请求
//如果$noNeedRight为空表示所有接口都需要验证权限才能请求
//如果接口已经设置无需登录,那也就无需鉴权了
//
// 无需登录的接口,*表示全部
protected $noNeedLogin = ['test1'];
// 无需鉴权的接口,*表示全部
protected $noNeedRight = ['test2'];
/**
* 无需登录的接口
*
* 必选参数:<br>
* 可选参数:
*/
public function test1()
{
$this->success('返回成功', ['action' => 'test1']);
}
/**
* 需要登录的接口
*
* 必选参数:token<br>
* 可选参数:
*/
public function test2()
{
$this->success('返回成功', ['action' => 'test2']);
}
/**
* 需要登录且需要验证有相应组的权限
*
* 必选参数:token<br>
* 可选参数:
*/
public function test3()
{
$this->success('返回成功', ['action' => 'test3']);
}
}

View File

@ -0,0 +1,27 @@
<?php
namespace app\api\controller;
use app\common\controller\Api;
/**
* 首页接口
*/
class Index extends Api
{
protected $noNeedLogin = ['*'];
protected $noNeedRight = ['*'];
/**
* 首页
*
* 必选参数:<br>
* 可选参数:lng,lat
*/
public function index()
{
$this->success('请求成功');
}
}

View File

@ -0,0 +1,103 @@
<?php
namespace app\api\controller;
use app\common\controller\Api;
use app\common\library\Sms as Smslib;
use app\common\model\User;
/**
* 短信接口
*/
class Sms extends Api
{
protected $noNeedLogin = '*';
protected $noNeedRight = '*';
public function _initialize()
{
parent::_initialize();
}
/**
* 发送验证码
*
* 必选参数:mobile,type<br>
* 可选参数:
*/
public function send()
{
$mobile = $this->request->request("mobile");
$type = $this->request->request("type");
$type = $type ? $type : 'register';
$last = Smslib::get($mobile, $type);
if ($last && time() - $last['createtime'] < 60)
{
$this->error(__('发送频繁'));
}
if ($type)
{
$userinfo = User::getByMobile($mobile);
if ($type == 'register' && $userinfo)
{
//已被注册
$this->error(__('已被注册'));
}
else if (in_array($type, ['changepwd', 'resetpwd']) && !$userinfo)
{
//未注册
$this->error(__('未注册'));
}
}
$ret = Smslib::send($mobile, '', $type);
if ($ret)
{
$this->success(__('发送成功'));
}
else
{
$this->error(__('发送失败'));
}
}
/**
* 检测验证码
*
* 必选参数:mobile,type,captcha<br>
* 可选参数:
*/
public function check()
{
$mobile = $this->request->request("mobile");
$type = $this->request->request("type");
$type = $type ? $type : 'register';
$captcha = $this->request->request("captcha");
if ($type)
{
$userinfo = User::getByMobile($mobile);
if ($type == 'register' && $userinfo)
{
//已被注册
$this->error(__('已被注册'));
}
else if (in_array($type, ['changepwd', 'resetpwd']) && !$userinfo)
{
//未注册
$this->error(__('未注册'));
}
}
$ret = Smslib::check($mobile, $captcha, $type);
if ($ret)
{
$this->success(__('成功'));
}
else
{
$this->error(__('验证码不正确'));
}
}
}

View File

@ -0,0 +1,91 @@
<?php
return [
'Keep login' => '保持会话',
'Sign in' => '登入',
'Username' => '用户名',
'User id' => '会员ID',
'Username' => '用户名',
'Nickname' => '昵称',
'Password' => '密码',
'Sign up' => '注 册',
'Sign in' => '登 录',
'Sign out' => '注 销',
'Keep login' => '保持会话',
'Guest' => '游客',
'Welcome' => '%s你好',
'Add' => '添加',
'Edit' => '编辑',
'Delete' => '删除',
'Move' => '移动',
'Name' => '名称',
'Status' => '状态',
'Weigh' => '权重',
'Operate' => '操作',
'Warning' => '温馨提示',
'Default' => '默认',
'Article' => '文章',
'Page' => '单页',
'OK' => '确定',
'Cancel' => '取消',
'Loading' => '加载中',
'More' => '更多',
'Normal' => '正常',
'Hidden' => '隐藏',
'Submit' => '提交',
'Reset' => '重置',
'Execute' => '执行',
'Close' => '关闭',
'Search' => '搜索',
'Refresh' => '刷新',
'First' => '首页',
'Previous' => '上一页',
'Next' => '下一页',
'Last' => '末页',
'None' => '无',
'Home' => '主页',
'Online' => '在线',
'Logout' => '注销',
'Profile' => '个人资料',
'Index' => '首页',
'Hot' => '热门',
'Recommend' => '推荐',
'Dashboard' => '控制台',
'Code' => '编号',
'Message' => '内容',
'Line' => '行号',
'File' => '文件',
'Menu' => '菜单',
'Name' => '名称',
'Weigh' => '权重',
'Type' => '类型',
'Title' => '标题',
'Content' => '内容',
'Status' => '状态',
'Operate' => '操作',
'Append' => '追加',
'Memo' => '备注',
'Parent' => '父级',
'Params' => '参数',
'Permission' => '权限',
'Advance search' => '高级搜索',
'Check all' => '选中全部',
'Expand all' => '展开全部',
'Begin time' => '开始时间',
'End time' => '结束时间',
'Create time' => '创建时间',
'Flag' => '标志',
'Please login first' => '请登录后操作',
'Redirect now' => '立即跳转',
'Operation completed' => '操作成功!',
'Operation failed' => '操作失败!',
'Unknown data format' => '未知的数据格式!',
'Network error' => '网络错误!',
'Advanced search' => '高级搜索',
'Invalid parameters' => '未知参数',
'No results were found' => '记录未找到',
'Parameter %s can not be empty' => '参数%s不能为空',
'You have no permission' => '你没有权限访问',
'An unexpected error occurred' => '发生了一个意外错误,程序猿正在紧急处理中',
'This page will be re-directed in %s seconds' => '页面将在 %s 秒后自动跳转',
];

View File

@ -0,0 +1,93 @@
<?php
namespace app\api\model;
use think\Cache;
use think\Model;
/**
* 地区数据模型
*/
class Area extends Model
{
/**
* 根据经纬度获取当前地区信息
*
* @param string $lng 经度
* @param string $lat 纬度
* @return array 城市信息
*/
public static function getAreaFromLngLat($lng, $lat, $level = 3)
{
$namearr = [1 => 'geo:province', 2 => 'geo:city', 3 => 'geo:district'];
$rangearr = [1 => 15000, 2 => 1000, 3 => 200];
$geoname = isset($namearr[$level]) ? $namearr[$level] : $namearr[3];
$georange = isset($rangearr[$level]) ? $rangearr[$level] : $rangearr[3];
$neararea = [];
// 读取范围内的ID
$redis = Cache::store('redis')->handler();
$georadiuslist = [];
if (method_exists($redis, 'georadius'))
{
$georadiuslist = $redis->georadius($geoname, $lng, $lat, $georange, 'km', ['WITHDIST', 'COUNT' => 5, 'ASC']);
}
if ($georadiuslist)
{
list($id, $distance) = $georadiuslist[0];
}
$id = isset($id) && $id ? $id : 3;
return self::get($id);
}
/**
* 根据经纬度获取省份
*
* @param string $lng 经度
* @param string $lat 纬度
* @return array
*/
public static function getProvinceFromLngLat($lng, $lat)
{
$provincedata = [];
$citydata = self::getCityFromLngLat($lng, $lat);
if ($citydata)
{
$provincedata = self::get($citydata['pid']);
}
return $provincedata;
}
/**
* 根据经纬度获取城市
*
* @param string $lng 经度
* @param string $lat 纬度
* @return array
*/
public static function getCityFromLngLat($lng, $lat)
{
$citydata = [];
$districtdata = self::getDistrictFromLngLat($lng, $lat);
if ($districtdata)
{
$citydata = self::get($districtdata['pid']);
}
return $citydata;
}
/**
* 根据经纬度获取地区
*
* @param string $lng 经度
* @param string $lat 纬度
* @return array
*/
public static function getDistrictFromLngLat($lng, $lat)
{
$districtdata = self::getAreaFromLngLat($lng, $lat, 3);
return $districtdata;
}
}

View File

@ -2,14 +2,302 @@
namespace app\common\controller;
use think\controller\Rest;
use app\common\library\Auth;
use think\exception\HttpResponseException;
use think\exception\ValidateException;
use think\Lang;
use think\Loader;
use think\Request;
use think\Response;
class Api extends Rest
/**
* API控制器基类
*/
class Api
{
public function _initialize()
{
/**
* @var Request Request 实例
*/
protected $request;
/**
* @var bool 验证失败是否抛出异常
*/
protected $failException = false;
/**
* @var bool 是否批量验证
*/
protected $batchValidate = false;
/**
* @var array 前置操作方法列表
*/
protected $beforeActionList = [];
/**
* 无需登录的方法,同时也就不需要鉴权了
* @var array
*/
protected $noNeedLogin = [];
/**
* 无需鉴权的方法,但需要登录
* @var array
*/
protected $noNeedRight = [];
/**
* 权限Auth
* @var Auth
*/
protected $auth = null;
/**
* 构造方法
* @access public
* @param Request $request Request 对象
*/
public function __construct(Request $request = null)
{
$this->request = is_null($request) ? Request::instance() : $request;
// 控制器初始化
$this->_initialize();
// 前置操作方法
if ($this->beforeActionList)
{
foreach ($this->beforeActionList as $method => $options)
{
is_numeric($method) ?
$this->beforeAction($options) :
$this->beforeAction($method, $options);
}
}
}
/**
* 初始化操作
* @access protected
*/
protected function _initialize()
{
$this->auth = Auth::instance();
$modulename = $this->request->module();
$controllername = strtolower($this->request->controller());
$actionname = strtolower($this->request->action());
// token
$token = $this->request->request('token');
$path = str_replace('.', '/', $controllername) . '/' . $actionname;
// 设置当前请求的URI
$this->auth->setRequestUri($path);
// 检测是否需要验证登录
if (!$this->auth->match($this->noNeedLogin))
{
//初始化
$this->auth->init($token);
//检测是否登录
if (!$this->auth->isLogin())
{
$this->error(__('Please login first'));
}
// 判断是否需要验证权限
if (!$this->auth->match($this->noNeedRight))
{
// 判断控制器和方法判断是否有对应权限
if (!$this->auth->check($path))
{
$this->error(__('You have no permission'));
}
}
}
else
{
// 如果有传递token才验证是否登录状态
if ($token)
{
$this->auth->init($token);
}
}
// 加载当前控制器语言包
$this->loadlang($controllername);
}
/**
* 加载语言文件
* @param string $name
*/
protected function loadlang($name)
{
Lang::load(APP_PATH . $this->request->module() . '/lang/' . Lang::detect() . '/' . str_replace('.', '/', $name) . '.php');
}
/**
* 操作成功返回的数据
* @param string $msg 提示信息
* @param mixed $data 要返回的数据
* @param string $type 输出类型
* @param array $header 发送的 Header 信息
*/
protected function success($msg = '', $data = '', $type = 'json', array $header = [])
{
$this->result($data, 1, $msg, $type, $header);
}
/**
* 操作失败返回的数据
* @param string $msg 提示信息
* @param mixed $data 要返回的数据
* @param string $type 输出类型
* @param array $header 发送的 Header 信息
*/
protected function error($msg = '', $data = '', $type = 'json', array $header = [])
{
$this->result($data, 0, $msg, $type, $header);
}
/**
* 返回封装后的 API 数据到客户端
* @access protected
* @param mixed $data 要返回的数据
* @param int $code 返回的 code
* @param mixed $msg 提示信息
* @param string $type 返回数据格式
* @param array $header 发送的 Header 信息
* @return void
* @throws HttpResponseException
*/
protected function result($data, $code = 0, $msg = '', $type = '', array $header = [])
{
$result = [
'code' => $code,
'msg' => $msg,
'time' => Request::instance()->server('REQUEST_TIME'),
'data' => $data,
];
$type = $type ?: $this->getResponseType();
$response = Response::create($result, $type)->header($header);
throw new HttpResponseException($response);
}
/**
* 未找到请求的接口
*/
public function _empty()
{
return $this->error('Api not found');
}
/**
* 前置操作
* @access protected
* @param string $method 前置操作方法名
* @param array $options 调用参数 ['only'=>[...]] 或者 ['except'=>[...]]
* @return void
*/
protected function beforeAction($method, $options = [])
{
if (isset($options['only']))
{
if (is_string($options['only']))
{
$options['only'] = explode(',', $options['only']);
}
if (!in_array($this->request->action(), $options['only']))
{
return;
}
}
elseif (isset($options['except']))
{
if (is_string($options['except']))
{
$options['except'] = explode(',', $options['except']);
}
if (in_array($this->request->action(), $options['except']))
{
return;
}
}
call_user_func([$this, $method]);
}
/**
* 设置验证失败后是否抛出异常
* @access protected
* @param bool $fail 是否抛出异常
* @return $this
*/
protected function validateFailException($fail = true)
{
$this->failException = $fail;
return $this;
}
/**
* 验证数据
* @access protected
* @param array $data 数据
* @param string|array $validate 验证器名或者验证规则数组
* @param array $message 提示信息
* @param bool $batch 是否批量验证
* @param mixed $callback 回调方法(闭包)
* @return array|string|true
* @throws ValidateException
*/
protected function validate($data, $validate, $message = [], $batch = false, $callback = null)
{
if (is_array($validate))
{
$v = Loader::validate();
$v->rule($validate);
}
else
{
// 支持场景
if (strpos($validate, '.'))
{
list($validate, $scene) = explode('.', $validate);
}
$v = Loader::validate($validate);
!empty($scene) && $v->scene($scene);
}
// 批量验证
if ($batch || $this->batchValidate)
$v->batch(true);
// 设置错误信息
if (is_array($message))
$v->message($message);
// 使用回调验证
if ($callback && is_callable($callback))
{
call_user_func_array($callback, [$v, &$data]);
}
if (!$v->check($data))
{
if ($this->failException)
{
throw new ValidateException($v->getError());
}
return $v->getError();
}
return true;
}
}

View File

@ -2,11 +2,15 @@
namespace app\common\controller;
use app\common\library\Auth;
use think\Config;
use think\Controller;
use think\Hook;
use think\Lang;
/**
* 前台控制器基类
*/
class Frontend extends Controller
{
@ -16,6 +20,24 @@ class Frontend extends Controller
*/
protected $layout = '';
/**
* 无需登录的方法,同时也就不需要鉴权了
* @var array
*/
protected $noNeedLogin = [];
/**
* 无需鉴权的方法,但需要登录
* @var array
*/
protected $noNeedRight = [];
/**
* 权限Auth
* @var Auth
*/
protected $auth = null;
public function _initialize()
{
//移除HTML标签
@ -29,6 +51,49 @@ class Frontend extends Controller
{
$this->view->engine->layout('layout/' . $this->layout);
}
$this->auth = Auth::instance();
$modulename = $this->request->module();
$controllername = strtolower($this->request->controller());
$actionname = strtolower($this->request->action());
// token
$token = $this->request->request('token');
$token = $token ? $token : \think\Cookie::get('token');
$path = str_replace('.', '/', $controllername) . '/' . $actionname;
// 设置当前请求的URI
$this->auth->setRequestUri($path);
// 检测是否需要验证登录
if (!$this->auth->match($this->noNeedLogin))
{
//初始化
$this->auth->init($token);
//检测是否登录
if (!$this->auth->isLogin())
{
$this->error(__('Please login first'), 'user/login');
}
// 判断是否需要验证权限
if (!$this->auth->match($this->noNeedRight))
{
// 判断控制器和方法判断是否有对应权限
if (!$this->auth->check($path))
{
$this->error(__('You have no permission'));
}
}
}
else
{
// 如果有传递token才验证是否登录状态
if ($token)
{
$this->auth->init($token);
}
}
$this->view->assign('user', $this->auth->getUser());
// 语言检测
$lang = strip_tags(Lang::detect());
@ -56,6 +121,7 @@ class Frontend extends Controller
// 配置信息后
Hook::listen("config_init", $config);
// 加载当前控制器语言包
$this->loadlang($controllername);
$this->assign('site', $site);
$this->assign('config', $config);

View File

@ -0,0 +1,573 @@
<?php
namespace app\common\library;
use app\common\model\User;
use app\common\model\UserRule;
use fast\Random;
use think\Config;
use think\Db;
use think\Hook;
use think\Request;
use think\Validate;
class Auth
{
protected static $instance = null;
protected $_error = '';
protected $_logined = FALSE;
protected $_user = NULL;
protected $_token = '';
protected $keeptime = 0;
protected $requestUri = '';
protected $rules = [];
//默认配置
protected $config = [];
protected $options = [];
protected $allowFields = ['id', 'username', 'nickname', 'mobile', 'avatar', 'score'];
public function __construct($options = [])
{
if ($config = Config::get('user'))
{
$this->options = array_merge($this->config, $config);
}
$this->options = array_merge($this->config, $options);
}
/**
*
* @param array $options 参数
* @return Auth
*/
public static function instance($options = [])
{
if (is_null(self::$instance))
{
self::$instance = new static($options);
}
return self::$instance;
}
/**
* 获取User模型
* @return User
*/
public function getUser()
{
return $this->_user;
}
/**
* 兼容调用user模型的属性
*
* @param string $name
* @return mixed
*/
public function __get($name)
{
return $this->_user ? $this->_user->$name : NULL;
}
/**
* 根据Token初始化
*
* @param string $token Token
* @return boolean
*/
public function init($token)
{
if ($this->_logined)
{
return TRUE;
}
if ($this->_error)
return FALSE;
$data = Token::get($token);
if (!$data)
{
return FALSE;
}
$user_id = intval($data['user_id']);
if ($user_id > 0)
{
$user = User::get($user_id);
if (!$user)
{
$this->setError('Account not exist');
return FALSE;
}
if ($user['status'] != 'normal')
{
$this->setError('Account is locked');
return FALSE;
}
$this->_user = $user;
$this->_logined = TRUE;
$this->_token = $token;
//初始化成功的事件
Hook::listen("user_init_successed", $this->_user);
return TRUE;
}
else
{
$this->setError('You are not logged in');
return FALSE;
}
}
/**
* 注册用户
*
* @param string $username 用户名
* @param string $password 密码
* @param string $email 邮箱
* @param string $mobile 手机号
* @param string $extend 扩展参数
* @return boolean
*/
public function register($username, $password, $email = '', $mobile = '', $extend = [])
{
// 检测用户名或邮箱、手机号是否存在
if (User::getByUsername($username))
{
$this->setError('Username already exist');
return FALSE;
}
if ($email && User::getByEmail($email))
{
$this->setError('Email already exist');
return FALSE;
}
if ($mobile && User::getByMobile($mobile))
{
$this->setError('Mobile already exist');
return FALSE;
}
$ip = request()->ip();
$time = time();
$data = [
'username' => $username,
'password' => $password,
'email' => $email,
'mobile' => $mobile,
'level' => 1,
'score' => 0,
'avatar' => '',
];
$params = array_merge($data, [
'nickname' => $username,
'salt' => Random::alnum(),
'jointime' => $time,
'joinip' => $ip,
'logintime' => $time,
'loginip' => $ip,
'prevtime' => $time,
'status' => 'normal'
]);
$params['password'] = $this->getEncryptPassword($password, $params['salt']);
$params = array_merge($params, $extend);
//账号注册时需要开启事务,避免出现垃圾数据
Db::startTrans();
try
{
$user = User::create($params);
Db::commit();
// 此时的Model中只包含部分数据
$this->_user = User::get($user->id);
//设置Token
$this->_token = Random::uuid();
Token::set($this->_token, $user->id);
//注册成功的事件
Hook::listen("user_register_successed", $this->_user);
return TRUE;
}
catch (Exception $e)
{
$this->setError($e->getMessage());
Db::rollback();
return FALSE;
}
}
/**
* 用户登录
*
* @param string $account 账号,用户名、邮箱、手机号
* @param string $password 密码
* @return array
*/
public function login($account, $password)
{
$field = Validate::is($account, 'email') ? 'email' : (Validate::regex($account, '/^1\d{10}$/') ? 'mobile' : 'username');
$user = User::get([$field => $account]);
if (!$user)
{
$this->setError('Account is incorrect');
return FALSE;
}
if ($user->status != 'normal')
{
$this->setError('Account is locked');
return FALSE;
}
if ($user->password != $this->getEncryptPassword($password, $user->salt))
{
$this->setError('Password is incorrect');
return FALSE;
}
//直接登录会员
$this->direct($user->id);
return TRUE;
}
/**
* 注销
*
* @return bool
*/
public function logout()
{
if (!$this->_logined)
{
$this->setError('You are not logged in');
return false;
}
//设置登录标识
$this->_logined = FALSE;
//删除Token
Token::delete($this->_token);
//注销成功的事件
Hook::listen("user_logout_successed", $this->_user);
return TRUE;
}
/**
* 修改密码
* @param string $newpassword 新密码
* @param string $oldpassword 旧密码
* @param bool $ignoreoldpassword 忽略旧密码
* @return boolean
*/
public function changepwd($newpassword, $oldpassword = '', $ignoreoldpassword = false)
{
if (!$this->_logined)
{
$this->setError('You are not logged in');
return false;
}
//判断旧密码是否正确
if ($this->_user->password == $this->getEncryptPassword($oldpassword, $this->_user->salt) || $ignoreoldpassword)
{
$salt = Random::alnum();
$newpassword = $this->getEncryptPassword($newpassword, $salt);
$this->_user->save(['password' => $newpassword, 'salt' => $salt]);
Token::delete($this->_token);
//修改密码成功的事件
Hook::listen("user_changepwd_successed", $this->_user);
return true;
}
else
{
$this->setError('Password is incorrect');
return false;
}
}
/**
* 直接登录账号
* @param int $user_id
* @return boolean
*/
public function direct($user_id)
{
$user = User::get($user_id);
if ($user)
{
$ip = request()->ip();
$time = time();
//判断连续登录和最大连续登录
if ($user->logintime < \fast\Date::unixtime('day'))
{
$user->successions = $user->logintime < \fast\Date::unixtime('day', -1) ? 1 : $user->successions + 1;
$user->maxsuccessions = max($user->successions, $user->maxsuccessions);
}
$user->prevtime = $user->logintime;
//记录本次登录的IP和时间
$user->loginip = $ip;
$user->logintime = $time;
$user->save();
$this->_user = $user;
$this->_token = Random::uuid();
Token::set($this->_token, $user->id);
//登录成功的事件
Hook::listen("user_login_successed", $this->_user);
return TRUE;
}
else
{
return FALSE;
}
}
/**
* 检测是否是否有对应权限
* @param string $path 控制器/方法
* @param string $module 模块 默认为当前模块
* @return boolean
*/
public function check($path = NULL, $module = NULL)
{
if (!$this->_logined)
return false;
$ruleList = $this->getRuleList();
$rules = [];
foreach ($ruleList as $k => $v)
{
$rules[] = $v['name'];
}
$url = ($module ? $module : request()->module()) . '/' . (is_null($path) ? $this->getRequestUri() : $path);
return in_array($url, $rules) ? TRUE : FALSE;
}
/**
* 判断是否登录
* @return boolean
*/
public function isLogin()
{
if ($this->_logined)
{
return true;
}
return false;
}
/**
* 获取当前Token
* @return string
*/
public function getToken()
{
return $this->_token;
}
/**
* 获取会员基本信息
*/
public function getUserinfo()
{
$data = $this->_user->toArray();
$allowFields = $this->getAllowFields();
$userinfo = array_intersect_key($data, array_flip($allowFields));
$userinfo['token'] = $this->getToken();
return $userinfo;
}
/**
* 获取会员组别规则列表
* @return array
*/
public function getRuleList()
{
if ($this->rules)
return $this->rules;
$group = $this->_user->group;
if (!$group)
{
return [];
}
$rules = explode(',', $group->rules);
$this->rules = UserRule::where('status', 'normal')->where('id', 'in', $rules)->field('id,pid,name,title,ismenu')->select();
return $this->rules;
}
/**
* 获取当前请求的URI
* @return string
*/
public function getRequestUri()
{
return $this->requestUri;
}
/**
* 设置当前请求的URI
* @param string $uri
*/
public function setRequestUri($uri)
{
$this->requestUri = $uri;
}
/**
* 获取允许输出的字段
* @return array
*/
public function getAllowFields()
{
return $this->allowFields;
}
/**
* 设置允许输出的字段
* @param array $fields
*/
public function setAllowFields($fields)
{
$this->allowFields = $fields;
}
/**
* 删除一个指定会员
* @param int $user_id 会员ID
*/
public function delete($user_id)
{
$user = User::get($user_id);
if (!$user)
{
return FALSE;
}
// 调用事务删除账号
$result = Db::transaction(function($db) use($user_id) {
// 删除会员
User::destroy($user_id);
// 删除会员指定的所有Token
Token::clear($user_id);
return TRUE;
});
if ($result)
{
Hook::listen("user_delete_successed", $user);
}
return $result ? TRUE : FALSE;
}
/**
* 获取密码加密后的字符串
* @param string $password 密码
* @param string $salt 密码盐
* @return string
*/
public function getEncryptPassword($password, $salt = '')
{
return md5(md5($password) . $salt);
}
/**
* 检测当前控制器和方法是否匹配传递的数组
*
* @param array $arr 需要验证权限的数组
*/
public function match($arr = [])
{
$request = Request::instance();
$arr = is_array($arr) ? $arr : explode(',', $arr);
if (!$arr)
{
return FALSE;
}
// 是否存在
if (in_array(strtolower($request->action()), $arr) || in_array('*', $arr))
{
return TRUE;
}
// 没找到匹配
return FALSE;
}
/**
* 设置会话有效时间
* @param int $keeptime 默认为永久
*/
public function keeptime($keeptime = 0)
{
$this->keeptime = $keeptime;
}
/**
* 渲染用户数据
* @param array $datalist 二维数组
* @param mixed $fields 加载的字段列表
* @param string $fieldkey 渲染的字段
* @param string $renderkey 结果字段
* @return array
*/
public function render(&$datalist, $fields = [], $fieldkey = 'user_id', $renderkey = 'userinfo')
{
$fields = !$fields ? ['id', 'nickname', 'level', 'avatar'] : (is_array($fields) ? $fields : explode(',', $fields));
$ids = [];
foreach ($datalist as $k => $v)
{
if (!isset($v[$fieldkey]))
continue;
$ids[] = $v[$fieldkey];
}
$list = [];
if ($ids)
{
if (!in_array('id', $fields))
{
$fields[] = 'id';
}
$ids = array_unique($ids);
$selectlist = User::where('id', 'in', $ids)->column($fields);
foreach ($selectlist as $k => $v)
{
$list[$v['id']] = $v;
}
}
foreach ($datalist as $k => &$v)
{
$v[$renderkey] = isset($list[$v[$fieldkey]]) ? $list[$v[$fieldkey]] : NULL;
}
unset($v);
return $datalist;
}
/**
* 设置错误信息
*
* @param $error 错误信息
*/
public function setError($error)
{
$this->_error = $error;
return $this;
}
/**
* 获取错误信息
* @return string
*/
public function getError()
{
return $this->_error ? __($this->_error) : '';
}
}

View File

@ -0,0 +1,138 @@
<?php
namespace app\common\library;
use addons\alisms\library\Alisms;
use app\common\model\MobileCode;
class Sms
{
/**
* 验证码有效时长
* @var int
*/
protected static $expire = 120;
/**
* 最大允许检测的次数
* @var int
*/
protected static $maxCheckNums = 10;
/**
* 获取最后一次手机发送的数据
*
* @param int $mobile 手机号
* @param string $type 类型
* @return array
*/
public static function get($mobile, $type = 'default')
{
return MobileCode::
where(['mobile' => $mobile, 'type' => $type])
->order('id', 'DESC')
->find();
}
/**
* 发送验证码
*
* @param int $mobile 手机号
* @param int $code 验证码
* @param string $type 类型
* @return array
*/
public static function send($mobile, $code = '', $type = 'default')
{
$config = get_addon_config('alisms');
$code = !$code ? mt_rand(1000, 9999) : $code;
$alisms = new Alisms();
$ret = $alisms->mobile($mobile)
->template($config['template'][$type])
->param(['code' => $code])
->send();
if ($ret)
{
$time = time();
MobileCode::create(['type' => $type, 'mobile' => $mobile, 'code' => $code, 'createtime' => $time]);
return TRUE;
}
else
{
return FALSE;
}
}
/**
* 发送通知
* @param int $mobile 手机号
* @param string $template 模板ID
* @param array $params 参数
* @return boolean
*/
public static function notice($mobile, $template, $params = [])
{
$alisms = Alisms::instance();
$ret = $alisms->mobile($mobile)
->template($template)
->param($params)
->send();
return $ret ? TRUE : FALSE;
}
/**
* 校验验证码
*
* @param int $mobile 手机号
* @param int $code 验证码
* @param string $type 类型
* @return boolean
*/
public static function check($mobile, $code, $type = 'default')
{
$time = time() - self::$expire;
$obj = MobileCode::where(['mobile' => $mobile, 'type' => $type])
->order('id', 'DESC')
->find();
if ($obj)
{
if ($obj['createtime'] > $time && $obj['times'] <= self::$maxCheckNums)
{
$correct = $code == $obj['code'];
if (!$correct)
{
$obj->times = $obj->times + 1;
$obj->save();
}
return $correct;
}
else
{
// 过期则清空该手机验证码
self::flush($mobile, $type);
return FALSE;
}
}
else
{
return FALSE;
}
}
/**
* 清空指定手机号验证码
*
* @param int $mobile 手机号
* @param string $type 类型
* @return boolean
*/
public static function flush($mobile, $type = 'default')
{
MobileCode::
where(['mobile' => $mobile, 'type' => $type])
->delete();
return TRUE;
}
}

View File

@ -0,0 +1,84 @@
<?php
namespace app\common\library;
/**
* Token操作类
*/
class Token
{
/**
* 存储Token
* @param string $token Token
* @param int $user_id 会员ID
* @param int $expire 过期时长,0表示无限,单位秒
*/
public static function set($token, $user_id, $expire = 0)
{
$expiretime = $expire ? time() + $expire : 0;
\app\common\model\Token::create(['token' => $token, 'user_id' => $user_id, 'expiretime' => $expiretime]);
}
/**
* 获取Token内的信息
* @param string $token
* @return array
*/
public static function get($token)
{
$data = \app\common\model\Token::get($token);
if ($data)
{
if (!$data['expiretime'] || $data['expiretime'] > time())
{
return $data;
}
else
{
self::delete($token);
}
}
return [];
}
/**
* 判断Token是否可用
* @param string $token Token
* @param int $user_id 会员ID
* @return boolean
*/
public static function check($token, $user_id)
{
$data = self::get($token);
return $data && $data['user_id'] == $user_id ? true : false;
}
/**
* 删除Token
* @param string $token
* @return boolean
*/
public static function delete($token)
{
$data = \app\common\model\Token::get($token);
if ($data)
{
$data->delete();
return true;
}
return false;
}
/**
* 删除指定用户的所有Token
* @param int $user_id
* @return boolean
*/
public static function clear($user_id)
{
\app\common\model\Token::where('user_id', $user_id)->delete();
return true;
}
}

View File

@ -15,8 +15,10 @@ class Attachment extends Model
// 定义字段类型
protected $type = [
];
public function setUploadtimeAttr($value)
{
return strtotime($value);
}
}

View File

@ -4,6 +4,9 @@ namespace app\common\model;
use think\Model;
/**
* 配置模型
*/
class Config extends Model
{

View File

@ -1,5 +1,5 @@
{__NOLAYOUT__}<!DOCTYPE html>
<html lang="en">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>跳转提示</title>

View File

@ -251,7 +251,7 @@ return [
//登录页默认背景图
'login_background' => "/assets/img/loginbg.jpg",
//版本号
'version' => '1.0.0.20171206_beta',
'version' => '1.0.0.20180117_beta',
'api_url' => 'http://api.fastadmin.net',
],
];

View File

@ -7,6 +7,8 @@ use app\common\controller\Frontend;
class Index extends Frontend
{
protected $noNeedLogin = '*';
protected $noNeedRight = '*';
protected $layout = '';
public function _initialize()

View File

@ -44,9 +44,9 @@
<li><a href="http://www.fastadmin.net/service.html" title="FastAdmin增值服务">服务</a></li>
<li><a href="http://www.fastadmin.net/download.html" title="FastAdmin下载">下载</a></li>
<li><a href="http://www.fastadmin.net/demo.html" title="FastAdmin演示">演示</a></li>
<li><a href="http://www.fastadmin.net/donate.html" title="捐赠">捐赠</a></li>
<li><a href="http://forum.fastadmin.net" title="FastAdmin交流社区">社区</a></li>
<li><a href="http://doc.fastadmin.net" title="FastAdmin官方文档">文档</a></li>
<li><a href="http://html.fastadmin.net" title="FastAdmin的HTML版">HTML版</a></li>
</ul>
</div>
<!-- /.navbar-collapse -->
@ -147,7 +147,7 @@
<p>&copy; 2017 FastAdmin. All Rights Reserved.</p>
<ul class="list-inline">
<li>
<a href="https://gitee.com/karsonzhang/fastadmin">码云</a>
<a href="https://gitee.com/karson/fastadmin">码云</a>
</li>
<li>
<a href="https://github.com/karsonzhang/fastadmin">Github</a>

View File

@ -0,0 +1,103 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="">
<meta name="author" content="">
<title>FastAdmin - 基于ThinkPHP5和Bootstrap的极速后台开发框架</title>
<!-- Bootstrap Core CSS -->
<link href="//cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
<!-- Plugin CSS -->
<link href="//cdn.bootcss.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">
<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!--[if lt IE 9]>
<script src="//cdn.bootcss.com/html5shiv/3.7.0/html5shiv.min.js"></script>
<script src="//cdn.bootcss.com/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->
<style>
body {
padding-top: 70px;
}
footer {
background-color: #222;
color:#9d9d9d;
padding:20px 0;
}
</style>
</head>
<body>
<!-- Navigation -->
<nav class="navbar navbar-inverse navbar-fixed-top" role="navigation">
<div class="container">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="http://www.fastadmin.net">FastAdmin</a>
</div>
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav pull-right">
<li><a href="http://www.fastadmin.net">首页</a></li>
<li><a href="http://www.fastadmin.net/store.html" title="FastAdmin插件市场">插件市场</a></li>
<li><a href="http://www.fastadmin.net/service.html" title="FastAdmin增值服务">服务</a></li>
<li><a href="http://www.fastadmin.net/download.html" title="FastAdmin下载">下载</a></li>
<li><a href="http://www.fastadmin.net/demo.html" title="FastAdmin演示">演示</a></li>
<li><a href="http://www.fastadmin.net/donate.html" title="捐赠">捐赠</a></li>
<li><a href="http://forum.fastadmin.net" title="FastAdmin交流社区">社区</a></li>
<li><a href="http://doc.fastadmin.net" title="FastAdmin官方文档">文档</a></li>
</ul>
</div>
<!-- /.navbar-collapse -->
</div>
<!-- /.container -->
</nav>
{__CONTENT__}
<footer>
<div class="container">
<p>&copy; 2017 FastAdmin. All Rights Reserved.</p>
<ul class="list-inline">
<li>
<a href="https://gitee.com/karson/fastadmin">码云</a>
</li>
<li>
<a href="https://github.com/karsonzhang/fastadmin">Github</a>
</li>
<li>
<a href="http://shang.qq.com/wpa/qunwpa?idkey=46c326e570d0f97cfae1f8257ae82322192ec8841c79b2136446df0b3b62028c">QQ群</a>
</li>
</ul>
</div>
</footer>
<!-- jQuery -->
<script src="//cdn.bootcss.com/jquery/2.1.4/jquery.min.js"></script>
<!-- Bootstrap Core JavaScript -->
<script src="//cdn.bootcss.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script>
$(function () {
});
</script>
</body>
</html>

View File

@ -16,9 +16,9 @@
],
"require": {
"php": ">=5.4.0",
"topthink/framework": "5.0.*",
"topthink/framework": "~5.0.14",
"overtrue/wechat": "~3.1",
"endroid/qrcode": "^1.9",
"endroid/qr-code": "^1.9",
"topthink/think-captcha": "^1.0",
"mtdowling/cron-expression": "^1.2",
"phpmailer/phpmailer": "^5.2",

View File

@ -398,6 +398,10 @@ form.form-horizontal .control-label {
.sidebar-mini.sidebar-collapse .sidebar-menu > li:hover > .treeview-menu {
top: 41px;
}
.sidebar-mini.sidebar-collapse .sidebar-menu > li:hover > a > .pull-right-container {
top: 7px!important;
height: 17px;
}
}
.fieldlist dd {
display: block;

File diff suppressed because one or more lines are too long

View File

@ -39,6 +39,14 @@ body {
.wrapper:after {
clear: both;
}
.wrapper:before,
.wrapper:after {
content: " ";
display: table;
}
.wrapper:after {
clear: both;
}
.layout-boxed .wrapper {
max-width: 1250px;
margin: 0 auto;
@ -479,6 +487,14 @@ a:focus {
.user-panel:after {
clear: both;
}
.user-panel:before,
.user-panel:after {
content: " ";
display: table;
}
.user-panel:after {
clear: both;
}
.user-panel > .image > img {
width: 100%;
max-width: 45px;
@ -797,6 +813,14 @@ a:focus {
.control-sidebar-menu > li > a:after {
clear: both;
}
.control-sidebar-menu > li > a:before,
.control-sidebar-menu > li > a:after {
content: " ";
display: table;
}
.control-sidebar-menu > li > a:after {
clear: both;
}
.control-sidebar-menu > li > a > .control-sidebar-subheading {
margin-top: 0;
}
@ -1061,6 +1085,14 @@ a:focus {
.navbar-nav > .messages-menu > .dropdown-menu > li .menu > li > a:after {
clear: both;
}
.navbar-nav > .messages-menu > .dropdown-menu > li .menu > li > a:before,
.navbar-nav > .messages-menu > .dropdown-menu > li .menu > li > a:after {
content: " ";
display: table;
}
.navbar-nav > .messages-menu > .dropdown-menu > li .menu > li > a:after {
clear: both;
}
.navbar-nav > .tasks-menu > .dropdown-menu > li .menu > li > a {
padding: 10px;
}
@ -1123,6 +1155,14 @@ a:focus {
.navbar-nav > .user-menu > .dropdown-menu > .user-body:after {
clear: both;
}
.navbar-nav > .user-menu > .dropdown-menu > .user-body:before,
.navbar-nav > .user-menu > .dropdown-menu > .user-body:after {
content: " ";
display: table;
}
.navbar-nav > .user-menu > .dropdown-menu > .user-body:after {
clear: both;
}
.navbar-nav > .user-menu > .dropdown-menu > .user-body a {
color: #444 !important;
}
@ -1144,6 +1184,14 @@ a:focus {
.navbar-nav > .user-menu > .dropdown-menu > .user-footer:after {
clear: both;
}
.navbar-nav > .user-menu > .dropdown-menu > .user-footer:before,
.navbar-nav > .user-menu > .dropdown-menu > .user-footer:after {
content: " ";
display: table;
}
.navbar-nav > .user-menu > .dropdown-menu > .user-footer:after {
clear: both;
}
.navbar-nav > .user-menu > .dropdown-menu > .user-footer .btn-default {
color: #666666;
}
@ -1776,6 +1824,20 @@ select.form-control {
.box-footer:after {
clear: both;
}
.box-header:before,
.box-body:before,
.box-footer:before,
.box-header:after,
.box-body:after,
.box-footer:after {
content: " ";
display: table;
}
.box-header:after,
.box-body:after,
.box-footer:after {
clear: both;
}
.box-header {
color: #444;
display: block;
@ -1895,6 +1957,14 @@ select.form-control {
.box-comments .box-comment:after {
clear: both;
}
.box-comments .box-comment:before,
.box-comments .box-comment:after {
content: " ";
display: table;
}
.box-comments .box-comment:after {
clear: both;
}
.box-comments .box-comment:last-of-type {
border-bottom: 0;
}
@ -2006,6 +2076,14 @@ select.form-control {
.chat .item:after {
clear: both;
}
.chat .item:before,
.chat .item:after {
content: " ";
display: table;
}
.chat .item:after {
clear: both;
}
.chat .item > img {
width: 40px;
height: 40px;
@ -2053,6 +2131,14 @@ select.form-control {
.chat .item > .attachment:after {
clear: both;
}
.chat .item > .attachment:before,
.chat .item > .attachment:after {
content: " ";
display: table;
}
.chat .item > .attachment:after {
clear: both;
}
.box-input {
max-width: 200px;
}
@ -2164,6 +2250,14 @@ select.form-control {
.timeline > li:after {
clear: both;
}
.timeline > li:before,
.timeline > li:after {
content: " ";
display: table;
}
.timeline > li:after {
clear: both;
}
.timeline > li > .timeline-item {
-webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);
@ -2615,6 +2709,14 @@ select.form-control {
.products-list > .item:after {
clear: both;
}
.products-list > .item:before,
.products-list > .item:after {
content: " ";
display: table;
}
.products-list > .item:after {
clear: both;
}
.products-list .product-img {
float: left;
}
@ -2735,6 +2837,14 @@ table.text-center th {
.direct-chat-msg:after {
clear: both;
}
.direct-chat-msg:before,
.direct-chat-msg:after {
content: " ";
display: table;
}
.direct-chat-msg:after {
clear: both;
}
.direct-chat-messages,
.direct-chat-contacts {
-webkit-transition: -webkit-transform 0.5s ease-in-out;
@ -2835,6 +2945,14 @@ table.text-center th {
.contacts-list > li:after {
clear: both;
}
.contacts-list > li:before,
.contacts-list > li:after {
content: " ";
display: table;
}
.contacts-list > li:after {
clear: both;
}
.contacts-list > li:last-of-type {
border-bottom: none;
}
@ -3065,6 +3183,76 @@ table.text-center th {
height: auto;
float: left;
}
.close,
.mailbox-attachment-close {
float: right;
font-size: 18px;
font-weight: bold;
line-height: 1;
color: #000;
text-shadow: 0 1px 0 #fff;
opacity: 0.2;
filter: alpha(opacity=20);
}
.close:hover,
.close:focus {
color: #000;
text-decoration: none;
cursor: pointer;
opacity: 0.5;
filter: alpha(opacity=50);
}
button.close {
padding: 0;
cursor: pointer;
background: transparent;
border: 0;
-webkit-appearance: none;
}
.clearfix:before,
.clearfix:after,
.content:before,
.content:after {
content: " ";
display: table;
}
.clearfix:after,
.content:after {
clear: both;
}
.center-block {
display: block;
margin-left: auto;
margin-right: auto;
}
.pull-right {
float: right !important;
}
.pull-left {
float: left !important;
}
.hide {
display: none !important;
}
.show {
display: block !important;
}
.invisible {
visibility: hidden;
}
.text-hide {
font: 0/0 a;
color: transparent;
text-shadow: none;
background-color: transparent;
border: 0;
}
.hidden {
display: none !important;
}
.affix {
position: fixed;
}
/*
* Page: Mailbox
* -------------
@ -5426,6 +5614,14 @@ fieldset[disabled] .btn-yahoo.active {
.user-block:after {
clear: both;
}
.user-block:before,
.user-block:after {
content: " ";
display: table;
}
.user-block:after {
clear: both;
}
.user-block img {
width: 40px;
height: 40px;

View File

@ -1,8 +1,560 @@
@import url("../css/bootstrap.min.css");
@import url("../css/fastadmin.min.css");
@import url("../css/skins/skin-green.css");
@import url("../css/iconfont.css");
@import url("../libs/font-awesome/css/font-awesome.min.css");
@import url("../libs/toastr/toastr.min.css");
@import url("../libs/layer/dist/theme/default/layer.css");
@import url("../libs/bootstrap-daterangepicker/daterangepicker.css");
@import url("../libs/nice-validator/dist/jquery.validator.css");
html,
body {
height: 100%;
}
body {
padding-top: 50px;
font-size: 13px;
}
.wow {
visibility: hidden;
}
.img-portfolio {
margin-bottom: 30px;
}
.img-hover:hover {
opacity: 0.8;
}
.dropdown:hover .dropdown-menu {
display: block;
margin-top: 0;
}
.navbar {
border: none;
}
.navbar-nav li > a {
font-size: 13px;
}
.toast-top-center {
top: 50px;
}
#toast-container > div {
-webkit-box-shadow: none;
-moz-box-shadow: none;
box-shadow: none;
}
.layui-layer-fast {
-webkit-animation-fill-mode: both;
animation-fill-mode: both;
-webkit-animation-duration: .3s;
animation-duration: .3s;
-webkit-animation-name: layer-bounceIn;
animation-name: layer-bounceIn;
}
/*修复nice-validator和summernote的编辑框冲突*/
.nice-validator .note-editor .note-editing-area .note-editable {
display: inherit;
}
/*预览区域*/
.plupload-preview {
padding: 10px;
margin-bottom: 0;
}
.plupload-preview li {
margin-bottom: 10px;
}
.plupload-preview .thumbnail {
margin-bottom: 10px;
}
.plupload-preview a {
display: block;
}
.plupload-preview a:first-child {
height: 90px;
}
.plupload-preview a img {
height: 80px;
object-fit: cover;
}
#header-navbar li.dropdown ul.dropdown-menu {
min-width: 94px;
}
.panel-col {
min-height: 400px;
}
.panel-default {
padding: 0 15px;
border-color: #e4ecf3;
}
.panel-default > .panel-heading {
position: relative;
font-size: 16px;
padding: 15px 0;
background: #fff;
border-bottom: 1px solid #f5f5f5;
}
.panel-default > .panel-heading .panel-title {
color: #313131;
}
.panel-default > .panel-heading .panel-title > i {
display: none;
}
.panel-default > .panel-heading .more {
position: absolute;
top: 13px;
right: 0;
display: block;
color: #919191;
-webkit-transition: all 0.3s ease;
-moz-transition: all 0.3s ease;
-o-transition: all 0.3s ease;
transition: all 0.3s ease;
}
.panel-default > .panel-heading .more:hover {
color: #616161;
-webkit-transition: all 0.3s ease;
-moz-transition: all 0.3s ease;
-o-transition: all 0.3s ease;
transition: all 0.3s ease;
}
.panel-default > .panel-heading .panel-bar {
position: absolute;
top: 7px;
right: 0;
display: block;
}
@media (max-width: 767px) {
.panel-default {
padding: 0 10px;
}
.panel-default > .panel-heading {
padding: 10px 0;
}
.panel-default > .panel-heading .more {
top: 8px;
}
> .panel-body {
position: relative;
padding: 15px 0;
}
> .panel-footer {
padding: 15px 0;
background: none;
}
}
@media (max-width: 1920px) {
.panel-default > .panel-body .zuixin {
width: 100%;
border-bottom: 1px solid #f5f5f5;
padding-bottom: 5px;
margin-bottom: 10px;
}
}
@media (max-width: 992px) {
.panel-default > .panel-body .zuixin {
width: 50%;
padding-bottom: 5px;
margin-bottom: 10px;
float: left;
padding-right: 5px;
}
}
.panel-primary > .panel-heading {
background-color: #46c37b;
color: #fff;
}
.panel-primary > .panel-body {
background: #fafafa;
border-bottom-left-radius: 4px;
border-bottom-right-radius: 4px;
}
.panel-gray {
-webkit-box-shadow: 0 2px 4px rgba(0, 0, 0, 0.08);
-moz-box-shadow: 0 2px 4px rgba(0, 0, 0, 0.08);
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.08);
}
.panel-gray > .panel-heading {
background-color: #f5f5f5;
color: #919191;
}
.panel-gray > .panel-body {
color: #919191;
background: #fff;
border-bottom-left-radius: 4px;
border-bottom-right-radius: 4px;
}
.panel-page {
padding: 45px 50px 50px;
min-height: 500px;
}
.panel-page .panel-heading {
background: transparent;
border-bottom: none;
margin: 0 0 30px 0;
padding: 0;
}
.panel-page .panel-heading h2 {
font-size: 25px;
margin-top: 0;
}
@media (max-width: 767px) {
.panel-page {
padding: 15px;
min-height: 300px;
}
}
.nav-pills > li {
margin-right: 5px;
}
.nav-pills > li > a {
padding: 10px 15px;
color: #616161;
-webkit-transition: all 0.3s ease;
-moz-transition: all 0.3s ease;
-o-transition: all 0.3s ease;
transition: all 0.3s ease;
}
.nav-pills > li > a:hover {
-webkit-transition: all 0.3s ease;
-moz-transition: all 0.3s ease;
-o-transition: all 0.3s ease;
transition: all 0.3s ease;
background-color: #f5f5f5;
}
.nav-pills > li.active > a {
border: none;
color: #fff;
background: #46c37b;
-webkit-transition: all 0.3s ease;
-moz-transition: all 0.3s ease;
-o-transition: all 0.3s ease;
transition: all 0.3s ease;
border-radius: 3px;
}
.nav-pills.nav-pills-sm > li > a {
font-size: 12px;
line-height: 1.5;
padding: 4px 13px;
}
.metas {
position: relative;
padding: 10px;
color: #c1c1c1;
}
.metas i {
margin-right: 5px;
}
.metas .addon-price {
float: right;
}
.metas .price {
color: #e83d2c;
font-size: 14px;
margin-right: 0;
}
.metas .free {
color: #238312;
}
.metas .comment {
margin-left: 10px;
}
@media (max-width: 767px) {
.metas .metas {
padding: 5px;
}
.metas .comment {
display: none;
}
}
.text-line {
position: relative;
padding: 30px 0;
text-align: center;
}
.text-line.small {
padding: 10px 0;
}
.text-line.small h5 {
font-size: 14px;
}
.text-line.small h5 > span {
padding: 0 20px;
}
.text-line h5 {
position: relative;
margin-bottom: 20px;
font-size: 32px;
z-index: 1;
color: #313131;
}
.text-line h5 > i {
padding-left: 20px;
background: #fff;
}
.text-line h5 > span {
padding: 0 40px;
}
.text-line .subtitle {
font-size: 16px;
color: #919191;
}
@media (max-width: 767px) {
.text-line {
padding: 20px 0;
}
.text-line h5 {
font-size: 16px;
}
.text-line .subtitle {
font-size: 14px;
}
}
@media (max-width: 767px) {
header.carousel .carousel {
height: 70%;
}
}
footer.footer {
width: 100%;
color: #aaa;
background: #555;
margin-top: 25px;
}
footer.footer ul {
margin: 60px 0 30px 0;
padding: 0;
}
footer.footer ul li.f-tit {
margin-bottom: 10px;
font-size: 14px;
color: #fff;
}
footer.footer ul li {
line-height: 26px;
white-space: nowrap;
list-style: none;
margin: 0;
padding: 0;
}
footer.footer ul li a {
color: #aaa;
}
footer.footer ul li a:hover {
color: #aaa;
text-decoration: underline !important;
}
footer.footer .address {
line-height: 50px;
text-align: center;
background: #393939;
margin: 0;
}
footer p.address a {
color: #aaa;
}
footer p.address a:hover {
color: #fff;
}
@media (max-width: 767px) {
footer.footer {
overflow: hidden;
}
footer.footer .container {
margin: 0 20px;
}
footer.footer ul {
margin: 20px 0 10px 0;
}
footer.footer .address {
padding: 0 10px;
}
}
.rotate {
-webkit-transition-duration: 0.8s;
-moz-transition-duration: 0.8s;
-o-transition-duration: 0.8s;
transition-duration: 0.8s;
-webkit-transition-property: -webkit-transform;
-moz-transition-property: -moz-transform;
-o-transition-property: -o-transform;
transition-property: transform;
overflow: hidden;
}
.rotate:hover {
-webkit-transform: rotate(360deg);
-moz-transform: rotate(360deg);
-o-transform: rotate(360deg);
}
.user-section {
background: #fff;
padding: 15px;
margin-bottom: 20px;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;
border: 1px solid #e4ecf3;
}
.login-section {
margin: 50px auto;
width: 460px;
-webkit-border-radius: 0;
-moz-border-radius: 0;
border-radius: 0;
}
.login-section.login-section-weixin {
min-height: 315px;
}
.login-section .logon-tab {
margin: -15px -15px 0 -15px;
}
.login-section .logon-tab > a {
display: block;
padding: 20px;
float: left;
width: 50%;
font-size: 16px;
text-align: center;
color: #616161;
background-color: #f5f5f5;
-webkit-transition: all 0.3s ease;
-moz-transition: all 0.3s ease;
-o-transition: all 0.3s ease;
transition: all 0.3s ease;
}
.login-section .logon-tab > a:hover {
background-color: #fafafa;
-webkit-transition: all 0.3s ease;
-moz-transition: all 0.3s ease;
-o-transition: all 0.3s ease;
transition: all 0.3s ease;
}
.login-section .logon-tab > a.active {
background-color: #fff;
-webkit-transition: all 0.3s ease;
-moz-transition: all 0.3s ease;
-o-transition: all 0.3s ease;
transition: all 0.3s ease;
}
.login-section .login-main {
padding: 40px 45px 20px 45px;
}
.login-section .control-label {
font-size: 13px;
}
@media (max-width: 767px) {
.login-section {
width: 100%;
margin: 20px auto;
}
.login-section .login-main {
padding: 20px 0 0 0;
}
}
@media (min-width: 768px) {
.login-modal {
width: 350px;
}
.login-modal .modal-body {
padding: 30px 30px 15px 30px;
}
.login-modal .modal-footer {
padding: 30px;
}
}
#content-container {
margin: 30px auto;
min-height: 400px;
}
@media (max-width: 767px) {
#content-container {
min-height: 250px;
}
}
.sidenav {
padding: 20px 0 10px 0;
margin-bottom: 20px;
background-color: #fff;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;
border: 1px solid #e4ecf3;
}
.sidenav .list-group:last-child {
margin-bottom: 0;
}
.sidenav .list-group .list-group-heading {
list-style-type: none;
color: #919191;
margin-bottom: 10px;
margin-left: 35px;
font-size: 14px;
}
.sidenav .list-group .list-group-item {
-webkit-border-radius: 0;
-moz-border-radius: 0;
border-radius: 0;
border: none;
padding: 0;
border-left: 2px solid transparent;
}
.sidenav .list-group .list-group-item:last-child,
.sidenav .list-group .list-group-item:first-child {
-webkit-border-radius: 0;
-moz-border-radius: 0;
border-radius: 0;
}
.sidenav .list-group .list-group-item:hover {
background-color: #f5f5f5;
}
.sidenav .list-group .list-group-item > a {
display: block;
color: #616161;
padding: 10px 15px 10px 35px;
}
.sidenav .list-group .list-group-item.active {
border-left: 2px solid #46c37b;
background: none;
}
.sidenav .list-group .list-group-item.active > a {
color: #46c37b;
}
.flarum-section ul li a {
font-size: 13px;
}
.nav li .avatar-text,
.nav li .avatar-img {
height: 30px;
width: 30px;
line-height: 30px;
font-size: 14px;
}
.nav li .avatar-img {
font-size: 0;
}
.nav li .avatar-img img {
border-radius: 30px;
width: 30px;
height: 30px;
}
.avatar-text,
.avatar-img {
display: inline-block;
box-sizing: content-box;
color: #fff;
text-align: center;
vertical-align: top;
background-color: #e8ecf3;
font-weight: normal;
width: 48px;
height: 48px;
border-radius: 48px;
font-size: 24px;
line-height: 48px;
}
.avatar-img {
font-size: 0;
}
.avatar-img img {
border-radius: 48px;
width: 48px;
height: 48px;
}
/*# sourceMappingURL=frontend.css.map */

File diff suppressed because one or more lines are too long

View File

@ -310,333 +310,333 @@
background-color: #3b8ab8;
}
/*
* Skin: Black
* Skin: White
* -----------
*/
/* skin-black navbar */
.skin-black .main-header {
/* skin-white navbar */
.skin-white .main-header {
-webkit-box-shadow: 0px 1px 1px rgba(0, 0, 0, 0.05);
box-shadow: 0px 1px 1px rgba(0, 0, 0, 0.05);
}
.skin-black .main-header .navbar-toggle {
.skin-white .main-header .navbar-toggle {
color: #333;
}
.skin-black .main-header .navbar-brand {
.skin-white .main-header .navbar-brand {
color: #333;
border-right: 1px solid #eee;
}
.skin-black .main-header .navbar {
.skin-white .main-header .navbar {
background-color: #fff;
}
.skin-black .main-header .navbar .nav > li > a {
.skin-white .main-header .navbar .nav > li > a {
color: #333;
}
.skin-black .main-header .navbar .nav > li > a:hover,
.skin-black .main-header .navbar .nav > li > a:active,
.skin-black .main-header .navbar .nav > li > a:focus,
.skin-black .main-header .navbar .nav .open > a,
.skin-black .main-header .navbar .nav .open > a:hover,
.skin-black .main-header .navbar .nav .open > a:focus,
.skin-black .main-header .navbar .nav > .active > a {
.skin-white .main-header .navbar .nav > li > a:hover,
.skin-white .main-header .navbar .nav > li > a:active,
.skin-white .main-header .navbar .nav > li > a:focus,
.skin-white .main-header .navbar .nav .open > a,
.skin-white .main-header .navbar .nav .open > a:hover,
.skin-white .main-header .navbar .nav .open > a:focus,
.skin-white .main-header .navbar .nav > .active > a {
background: #fff;
color: #999;
}
.skin-black .main-header .navbar .sidebar-toggle {
.skin-white .main-header .navbar .sidebar-toggle {
color: #333;
}
.skin-black .main-header .navbar .sidebar-toggle:hover {
.skin-white .main-header .navbar .sidebar-toggle:hover {
color: #999;
background: #fff;
}
.skin-black .main-header .navbar > .sidebar-toggle {
.skin-white .main-header .navbar > .sidebar-toggle {
color: #333;
border-right: 1px solid #eee;
}
.skin-black .main-header .navbar .navbar-nav > li > a {
.skin-white .main-header .navbar .navbar-nav > li > a {
border-right: 1px solid #eee;
}
.skin-black .main-header .navbar .navbar-custom-menu .navbar-nav > li > a,
.skin-black .main-header .navbar .navbar-right > li > a {
.skin-white .main-header .navbar .navbar-custom-menu .navbar-nav > li > a,
.skin-white .main-header .navbar .navbar-right > li > a {
border-left: 1px solid #eee;
border-right-width: 0;
}
.skin-black .main-header > .logo {
.skin-white .main-header > .logo {
background-color: #fff;
color: #333;
border-bottom: 0 solid transparent;
border-right: 1px solid #eee;
}
.skin-black .main-header > .logo:hover {
.skin-white .main-header > .logo:hover {
background-color: #fcfcfc;
}
@media (max-width: 767px) {
.skin-black .main-header > .logo {
.skin-white .main-header > .logo {
background-color: #222;
color: #fff;
border-bottom: 0 solid transparent;
border-right: none;
}
.skin-black .main-header > .logo:hover {
.skin-white .main-header > .logo:hover {
background-color: #1f1f1f;
}
}
.skin-black .main-header li.user-header {
.skin-white .main-header li.user-header {
background-color: #222;
}
.skin-black .content-header {
.skin-white .content-header {
background: transparent;
box-shadow: none;
}
.skin-black .wrapper,
.skin-black .main-sidebar,
.skin-black .left-side {
.skin-white .wrapper,
.skin-white .main-sidebar,
.skin-white .left-side {
background-color: #222d32;
}
.skin-black .user-panel > .info,
.skin-black .user-panel > .info > a {
.skin-white .user-panel > .info,
.skin-white .user-panel > .info > a {
color: #fff;
}
.skin-black .sidebar-menu > li.header {
.skin-white .sidebar-menu > li.header {
color: #4b646f;
background: #1a2226;
}
.skin-black .sidebar-menu > li > a {
.skin-white .sidebar-menu > li > a {
border-left: 3px solid transparent;
}
.skin-black .sidebar-menu > li:hover > a,
.skin-black .sidebar-menu > li.active > a {
.skin-white .sidebar-menu > li:hover > a,
.skin-white .sidebar-menu > li.active > a {
color: #fff;
background: #1e282c;
border-left-color: #fff;
}
.skin-black .sidebar-menu > li > .treeview-menu {
.skin-white .sidebar-menu > li > .treeview-menu {
margin: 0 1px;
background: #2c3b41;
}
.skin-black .sidebar a {
.skin-white .sidebar a {
color: #b8c7ce;
}
.skin-black .sidebar a:hover {
.skin-white .sidebar a:hover {
text-decoration: none;
}
.skin-black .treeview-menu > li > a {
.skin-white .treeview-menu > li > a {
color: #8aa4af;
}
.skin-black .treeview-menu > li.active > a,
.skin-black .treeview-menu > li > a:hover {
.skin-white .treeview-menu > li.active > a,
.skin-white .treeview-menu > li > a:hover {
color: #fff;
}
.skin-black .sidebar-form {
.skin-white .sidebar-form {
border-radius: 3px;
border: 1px solid #374850;
background-color: #374850;
margin: 10px 10px;
}
.skin-black .sidebar-form input[type="text"],
.skin-black .sidebar-form .btn {
.skin-white .sidebar-form input[type="text"],
.skin-white .sidebar-form .btn {
box-shadow: none;
background-color: #374850;
border: 1px solid transparent;
height: 35px;
}
.skin-black .sidebar-form input[type="text"] {
.skin-white .sidebar-form input[type="text"] {
color: #666;
border-top-left-radius: 2px;
border-top-right-radius: 0;
border-bottom-right-radius: 0;
border-bottom-left-radius: 2px;
}
.skin-black .sidebar-form input[type="text"]:focus,
.skin-black .sidebar-form input[type="text"]:focus + .input-group-btn .btn {
.skin-white .sidebar-form input[type="text"]:focus,
.skin-white .sidebar-form input[type="text"]:focus + .input-group-btn .btn {
background-color: #fff;
color: #666;
}
.skin-black .sidebar-form input[type="text"]:focus + .input-group-btn {
.skin-white .sidebar-form input[type="text"]:focus + .input-group-btn {
background: #fff;
border-top-left-radius: 0;
border-top-right-radius: 2px;
border-bottom-right-radius: 2px;
border-bottom-left-radius: 0;
}
.skin-black .sidebar-form input[type="text"]:focus + .input-group-btn .btn {
.skin-white .sidebar-form input[type="text"]:focus + .input-group-btn .btn {
border-left-color: #fff;
}
.skin-black .sidebar-form .btn {
.skin-white .sidebar-form .btn {
color: #999;
border-top-left-radius: 0;
border-top-right-radius: 2px;
border-bottom-right-radius: 2px;
border-bottom-left-radius: 0;
}
.skin-black .pace .pace-progress {
.skin-white .pace .pace-progress {
background: #222;
}
.skin-black .pace .pace-activity {
.skin-white .pace .pace-activity {
border-top-color: #222;
border-left-color: #222;
}
/*
* Skin: Black
* Skin: White
* -----------
*/
/* skin-black navbar */
.skin-black-light .main-header {
/* skin-white navbar */
.skin-white-light .main-header {
-webkit-box-shadow: 0px 1px 1px rgba(0, 0, 0, 0.05);
box-shadow: 0px 1px 1px rgba(0, 0, 0, 0.05);
}
.skin-black-light .main-header .navbar-toggle {
.skin-white-light .main-header .navbar-toggle {
color: #333;
}
.skin-black-light .main-header .navbar-brand {
.skin-white-light .main-header .navbar-brand {
color: #333;
border-right: 1px solid #eee;
}
.skin-black-light .main-header .navbar {
.skin-white-light .main-header .navbar {
background-color: #fff;
}
.skin-black-light .main-header .navbar .nav > li > a {
.skin-white-light .main-header .navbar .nav > li > a {
color: #333;
}
.skin-black-light .main-header .navbar .nav > li > a:hover,
.skin-black-light .main-header .navbar .nav > li > a:active,
.skin-black-light .main-header .navbar .nav > li > a:focus,
.skin-black-light .main-header .navbar .nav .open > a,
.skin-black-light .main-header .navbar .nav .open > a:hover,
.skin-black-light .main-header .navbar .nav .open > a:focus,
.skin-black-light .main-header .navbar .nav > .active > a {
.skin-white-light .main-header .navbar .nav > li > a:hover,
.skin-white-light .main-header .navbar .nav > li > a:active,
.skin-white-light .main-header .navbar .nav > li > a:focus,
.skin-white-light .main-header .navbar .nav .open > a,
.skin-white-light .main-header .navbar .nav .open > a:hover,
.skin-white-light .main-header .navbar .nav .open > a:focus,
.skin-white-light .main-header .navbar .nav > .active > a {
background: #fff;
color: #999;
}
.skin-black-light .main-header .navbar .sidebar-toggle {
.skin-white-light .main-header .navbar .sidebar-toggle {
color: #333;
}
.skin-black-light .main-header .navbar .sidebar-toggle:hover {
.skin-white-light .main-header .navbar .sidebar-toggle:hover {
color: #999;
background: #fff;
}
.skin-black-light .main-header .navbar > .sidebar-toggle {
.skin-white-light .main-header .navbar > .sidebar-toggle {
color: #333;
border-right: 1px solid #eee;
}
.skin-black-light .main-header .navbar .navbar-nav > li > a {
.skin-white-light .main-header .navbar .navbar-nav > li > a {
border-right: 1px solid #eee;
}
.skin-black-light .main-header .navbar .navbar-custom-menu .navbar-nav > li > a,
.skin-black-light .main-header .navbar .navbar-right > li > a {
.skin-white-light .main-header .navbar .navbar-custom-menu .navbar-nav > li > a,
.skin-white-light .main-header .navbar .navbar-right > li > a {
border-left: 1px solid #eee;
border-right-width: 0;
}
.skin-black-light .main-header > .logo {
.skin-white-light .main-header > .logo {
background-color: #fff;
color: #333;
border-bottom: 0 solid transparent;
border-right: 1px solid #eee;
}
.skin-black-light .main-header > .logo:hover {
.skin-white-light .main-header > .logo:hover {
background-color: #fcfcfc;
}
@media (max-width: 767px) {
.skin-black-light .main-header > .logo {
.skin-white-light .main-header > .logo {
background-color: #222;
color: #fff;
border-bottom: 0 solid transparent;
border-right: none;
}
.skin-black-light .main-header > .logo:hover {
.skin-white-light .main-header > .logo:hover {
background-color: #1f1f1f;
}
}
.skin-black-light .main-header li.user-header {
.skin-white-light .main-header li.user-header {
background-color: #222;
}
.skin-black-light .content-header {
.skin-white-light .content-header {
background: transparent;
box-shadow: none;
}
.skin-black-light .wrapper,
.skin-black-light .main-sidebar,
.skin-black-light .left-side {
.skin-white-light .wrapper,
.skin-white-light .main-sidebar,
.skin-white-light .left-side {
background-color: #f9fafc;
}
.skin-black-light .content-wrapper,
.skin-black-light .main-footer {
.skin-white-light .content-wrapper,
.skin-white-light .main-footer {
border-left: 1px solid #d2d6de;
}
.skin-black-light .user-panel > .info,
.skin-black-light .user-panel > .info > a {
.skin-white-light .user-panel > .info,
.skin-white-light .user-panel > .info > a {
color: #444;
}
.skin-black-light .sidebar-menu > li {
.skin-white-light .sidebar-menu > li {
-webkit-transition: border-left-color 0.3s ease;
-o-transition: border-left-color 0.3s ease;
transition: border-left-color 0.3s ease;
}
.skin-black-light .sidebar-menu > li.header {
.skin-white-light .sidebar-menu > li.header {
color: #848484;
background: #f9fafc;
}
.skin-black-light .sidebar-menu > li > a {
.skin-white-light .sidebar-menu > li > a {
border-left: 3px solid transparent;
font-weight: 600;
}
.skin-black-light .sidebar-menu > li:hover > a,
.skin-black-light .sidebar-menu > li.active > a {
.skin-white-light .sidebar-menu > li:hover > a,
.skin-white-light .sidebar-menu > li.active > a {
color: #000;
background: #f4f4f5;
}
.skin-black-light .sidebar-menu > li.active {
.skin-white-light .sidebar-menu > li.active {
border-left-color: #fff;
}
.skin-black-light .sidebar-menu > li.active > a {
.skin-white-light .sidebar-menu > li.active > a {
font-weight: 600;
}
.skin-black-light .sidebar-menu > li > .treeview-menu {
.skin-white-light .sidebar-menu > li > .treeview-menu {
background: #f4f4f5;
}
.skin-black-light .sidebar a {
.skin-white-light .sidebar a {
color: #444;
}
.skin-black-light .sidebar a:hover {
.skin-white-light .sidebar a:hover {
text-decoration: none;
}
.skin-black-light .treeview-menu > li > a {
.skin-white-light .treeview-menu > li > a {
color: #777;
}
.skin-black-light .treeview-menu > li.active > a,
.skin-black-light .treeview-menu > li > a:hover {
.skin-white-light .treeview-menu > li.active > a,
.skin-white-light .treeview-menu > li > a:hover {
color: #000;
}
.skin-black-light .treeview-menu > li.active > a {
.skin-white-light .treeview-menu > li.active > a {
font-weight: 600;
}
.skin-black-light .sidebar-form {
.skin-white-light .sidebar-form {
border-radius: 3px;
border: 1px solid #d2d6de;
margin: 10px 10px;
}
.skin-black-light .sidebar-form input[type="text"],
.skin-black-light .sidebar-form .btn {
.skin-white-light .sidebar-form input[type="text"],
.skin-white-light .sidebar-form .btn {
box-shadow: none;
background-color: #fff;
border: 1px solid transparent;
height: 35px;
}
.skin-black-light .sidebar-form input[type="text"] {
.skin-white-light .sidebar-form input[type="text"] {
color: #666;
border-top-left-radius: 2px;
border-top-right-radius: 0;
border-bottom-right-radius: 0;
border-bottom-left-radius: 2px;
}
.skin-black-light .sidebar-form input[type="text"]:focus,
.skin-black-light .sidebar-form input[type="text"]:focus + .input-group-btn .btn {
.skin-white-light .sidebar-form input[type="text"]:focus,
.skin-white-light .sidebar-form input[type="text"]:focus + .input-group-btn .btn {
background-color: #fff;
color: #666;
}
.skin-black-light .sidebar-form input[type="text"]:focus + .input-group-btn .btn {
.skin-white-light .sidebar-form input[type="text"]:focus + .input-group-btn .btn {
border-left-color: #fff;
}
.skin-black-light .sidebar-form .btn {
.skin-white-light .sidebar-form .btn {
color: #999;
border-top-left-radius: 0;
border-top-right-radius: 2px;
@ -644,7 +644,7 @@
border-bottom-left-radius: 0;
}
@media (min-width: 768px) {
.skin-black-light.sidebar-mini.sidebar-collapse .sidebar-menu > li > .treeview-menu {
.skin-white-light.sidebar-mini.sidebar-collapse .sidebar-menu > li > .treeview-menu {
border-left: 1px solid #d2d6de;
}
}

View File

@ -1,174 +0,0 @@
/*
* Skin: Black
* -----------
*/
/* skin-black navbar */
.skin-black-light .main-header {
-webkit-box-shadow: 0px 1px 1px rgba(0, 0, 0, 0.05);
box-shadow: 0px 1px 1px rgba(0, 0, 0, 0.05);
}
.skin-black-light .main-header .navbar-toggle {
color: #333;
}
.skin-black-light .main-header .navbar-brand {
color: #333;
border-right: 1px solid #eee;
}
.skin-black-light .main-header .navbar {
background-color: #fff;
}
.skin-black-light .main-header .navbar .nav > li > a {
color: #333;
}
.skin-black-light .main-header .navbar .nav > li > a:hover,
.skin-black-light .main-header .navbar .nav > li > a:active,
.skin-black-light .main-header .navbar .nav > li > a:focus,
.skin-black-light .main-header .navbar .nav .open > a,
.skin-black-light .main-header .navbar .nav .open > a:hover,
.skin-black-light .main-header .navbar .nav .open > a:focus,
.skin-black-light .main-header .navbar .nav > .active > a {
background: #fff;
color: #999;
}
.skin-black-light .main-header .navbar .sidebar-toggle {
color: #333;
}
.skin-black-light .main-header .navbar .sidebar-toggle:hover {
color: #999;
background: #fff;
}
.skin-black-light .main-header .navbar > .sidebar-toggle {
color: #333;
border-right: 1px solid #eee;
}
.skin-black-light .main-header .navbar .navbar-nav > li > a {
border-right: 1px solid #eee;
}
.skin-black-light .main-header .navbar .navbar-custom-menu .navbar-nav > li > a,
.skin-black-light .main-header .navbar .navbar-right > li > a {
border-left: 1px solid #eee;
border-right-width: 0;
}
.skin-black-light .main-header > .logo {
background-color: #fff;
color: #333;
border-bottom: 0 solid transparent;
border-right: 1px solid #eee;
}
.skin-black-light .main-header > .logo:hover {
background-color: #fcfcfc;
}
@media (max-width: 767px) {
.skin-black-light .main-header > .logo {
background-color: #222;
color: #fff;
border-bottom: 0 solid transparent;
border-right: none;
}
.skin-black-light .main-header > .logo:hover {
background-color: #1f1f1f;
}
}
.skin-black-light .main-header li.user-header {
background-color: #222;
}
.skin-black-light .content-header {
background: transparent;
box-shadow: none;
}
.skin-black-light .wrapper,
.skin-black-light .main-sidebar,
.skin-black-light .left-side {
background-color: #f9fafc;
}
.skin-black-light .content-wrapper,
.skin-black-light .main-footer {
border-left: 1px solid #d2d6de;
}
.skin-black-light .user-panel > .info,
.skin-black-light .user-panel > .info > a {
color: #444;
}
.skin-black-light .sidebar-menu > li {
-webkit-transition: border-left-color 0.3s ease;
-o-transition: border-left-color 0.3s ease;
transition: border-left-color 0.3s ease;
}
.skin-black-light .sidebar-menu > li.header {
color: #848484;
background: #f9fafc;
}
.skin-black-light .sidebar-menu > li > a {
border-left: 3px solid transparent;
font-weight: 600;
}
.skin-black-light .sidebar-menu > li:hover > a,
.skin-black-light .sidebar-menu > li.active > a {
color: #000;
background: #f4f4f5;
}
.skin-black-light .sidebar-menu > li.active {
border-left-color: #fff;
}
.skin-black-light .sidebar-menu > li.active > a {
font-weight: 600;
}
.skin-black-light .sidebar-menu > li > .treeview-menu {
background: #f4f4f5;
}
.skin-black-light .sidebar a {
color: #444;
}
.skin-black-light .sidebar a:hover {
text-decoration: none;
}
.skin-black-light .treeview-menu > li > a {
color: #777;
}
.skin-black-light .treeview-menu > li.active > a,
.skin-black-light .treeview-menu > li > a:hover {
color: #000;
}
.skin-black-light .treeview-menu > li.active > a {
font-weight: 600;
}
.skin-black-light .sidebar-form {
border-radius: 3px;
border: 1px solid #d2d6de;
margin: 10px 10px;
}
.skin-black-light .sidebar-form input[type="text"],
.skin-black-light .sidebar-form .btn {
box-shadow: none;
background-color: #fff;
border: 1px solid transparent;
height: 35px;
}
.skin-black-light .sidebar-form input[type="text"] {
color: #666;
border-top-left-radius: 2px;
border-top-right-radius: 0;
border-bottom-right-radius: 0;
border-bottom-left-radius: 2px;
}
.skin-black-light .sidebar-form input[type="text"]:focus,
.skin-black-light .sidebar-form input[type="text"]:focus + .input-group-btn .btn {
background-color: #fff;
color: #666;
}
.skin-black-light .sidebar-form input[type="text"]:focus + .input-group-btn .btn {
border-left-color: #fff;
}
.skin-black-light .sidebar-form .btn {
color: #999;
border-top-left-radius: 0;
border-top-right-radius: 2px;
border-bottom-right-radius: 2px;
border-bottom-left-radius: 0;
}
@media (min-width: 768px) {
.skin-black-light.sidebar-mini.sidebar-collapse .sidebar-menu > li > .treeview-menu {
border-left: 1px solid #d2d6de;
}
}
/*# sourceMappingURL=skin-black-light.css.map */

View File

@ -1,167 +0,0 @@
/*
* Skin: Black
* -----------
*/
/* skin-black navbar */
.skin-black .main-header {
-webkit-box-shadow: 0px 1px 1px rgba(0, 0, 0, 0.05);
box-shadow: 0px 1px 1px rgba(0, 0, 0, 0.05);
}
.skin-black .main-header .navbar-toggle {
color: #333;
}
.skin-black .main-header .navbar-brand {
color: #333;
border-right: 1px solid #eee;
}
.skin-black .main-header .navbar {
background-color: #fff;
}
.skin-black .main-header .navbar .nav > li > a {
color: #333;
}
.skin-black .main-header .navbar .nav > li > a:hover,
.skin-black .main-header .navbar .nav > li > a:active,
.skin-black .main-header .navbar .nav > li > a:focus,
.skin-black .main-header .navbar .nav .open > a,
.skin-black .main-header .navbar .nav .open > a:hover,
.skin-black .main-header .navbar .nav .open > a:focus,
.skin-black .main-header .navbar .nav > .active > a {
background: #fff;
color: #999;
}
.skin-black .main-header .navbar .sidebar-toggle {
color: #333;
}
.skin-black .main-header .navbar .sidebar-toggle:hover {
color: #999;
background: #fff;
}
.skin-black .main-header .navbar > .sidebar-toggle {
color: #333;
border-right: 1px solid #eee;
}
.skin-black .main-header .navbar .navbar-nav > li > a {
border-right: 1px solid #eee;
}
.skin-black .main-header .navbar .navbar-custom-menu .navbar-nav > li > a,
.skin-black .main-header .navbar .navbar-right > li > a {
border-left: 1px solid #eee;
border-right-width: 0;
}
.skin-black .main-header > .logo {
background-color: #fff;
color: #333;
border-bottom: 0 solid transparent;
border-right: 1px solid #eee;
}
.skin-black .main-header > .logo:hover {
background-color: #fcfcfc;
}
@media (max-width: 767px) {
.skin-black .main-header > .logo {
background-color: #222;
color: #fff;
border-bottom: 0 solid transparent;
border-right: none;
}
.skin-black .main-header > .logo:hover {
background-color: #1f1f1f;
}
}
.skin-black .main-header li.user-header {
background-color: #222;
}
.skin-black .content-header {
background: transparent;
box-shadow: none;
}
.skin-black .wrapper,
.skin-black .main-sidebar,
.skin-black .left-side {
background-color: #222d32;
}
.skin-black .user-panel > .info,
.skin-black .user-panel > .info > a {
color: #fff;
}
.skin-black .sidebar-menu > li.header {
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;
background: #1e282c;
border-left-color: #fff;
}
.skin-black .sidebar-menu > li > .treeview-menu {
margin: 0 1px;
background: #2c3b41;
}
.skin-black .sidebar a {
color: #b8c7ce;
}
.skin-black .sidebar a:hover {
text-decoration: none;
}
.skin-black .treeview-menu > li > a {
color: #8aa4af;
}
.skin-black .treeview-menu > li.active > a,
.skin-black .treeview-menu > li > a:hover {
color: #fff;
}
.skin-black .sidebar-form {
border-radius: 3px;
border: 1px solid #374850;
background-color: #374850;
margin: 10px 10px;
}
.skin-black .sidebar-form input[type="text"],
.skin-black .sidebar-form .btn {
box-shadow: none;
background-color: #374850;
border: 1px solid transparent;
height: 35px;
}
.skin-black .sidebar-form input[type="text"] {
color: #666;
border-top-left-radius: 2px;
border-top-right-radius: 0;
border-bottom-right-radius: 0;
border-bottom-left-radius: 2px;
}
.skin-black .sidebar-form input[type="text"]:focus,
.skin-black .sidebar-form input[type="text"]:focus + .input-group-btn .btn {
background-color: #fff;
color: #666;
}
.skin-black .sidebar-form input[type="text"]:focus + .input-group-btn {
background: #fff;
border-top-left-radius: 0;
border-top-right-radius: 2px;
border-bottom-right-radius: 2px;
border-bottom-left-radius: 0;
}
.skin-black .sidebar-form input[type="text"]:focus + .input-group-btn .btn {
border-left-color: #fff;
}
.skin-black .sidebar-form .btn {
color: #999;
border-top-left-radius: 0;
border-top-right-radius: 2px;
border-bottom-right-radius: 2px;
border-bottom-left-radius: 0;
}
.skin-black .pace .pace-progress {
background: #222;
}
.skin-black .pace .pace-activity {
border-top-color: #222;
border-left-color: #222;
}
/*# sourceMappingURL=skin-black.css.map */

View File

@ -0,0 +1,174 @@
/*
* Skin: White
* -----------
*/
/* skin-white navbar */
.skin-white-light .main-header {
-webkit-box-shadow: 0px 1px 1px rgba(0, 0, 0, 0.05);
box-shadow: 0px 1px 1px rgba(0, 0, 0, 0.05);
}
.skin-white-light .main-header .navbar-toggle {
color: #333;
}
.skin-white-light .main-header .navbar-brand {
color: #333;
border-right: 1px solid #eee;
}
.skin-white-light .main-header .navbar {
background-color: #fff;
}
.skin-white-light .main-header .navbar .nav > li > a {
color: #333;
}
.skin-white-light .main-header .navbar .nav > li > a:hover,
.skin-white-light .main-header .navbar .nav > li > a:active,
.skin-white-light .main-header .navbar .nav > li > a:focus,
.skin-white-light .main-header .navbar .nav .open > a,
.skin-white-light .main-header .navbar .nav .open > a:hover,
.skin-white-light .main-header .navbar .nav .open > a:focus,
.skin-white-light .main-header .navbar .nav > .active > a {
background: #fff;
color: #999;
}
.skin-white-light .main-header .navbar .sidebar-toggle {
color: #333;
}
.skin-white-light .main-header .navbar .sidebar-toggle:hover {
color: #999;
background: #fff;
}
.skin-white-light .main-header .navbar > .sidebar-toggle {
color: #333;
border-right: 1px solid #eee;
}
.skin-white-light .main-header .navbar .navbar-nav > li > a {
border-right: 1px solid #eee;
}
.skin-white-light .main-header .navbar .navbar-custom-menu .navbar-nav > li > a,
.skin-white-light .main-header .navbar .navbar-right > li > a {
border-left: 1px solid #eee;
border-right-width: 0;
}
.skin-white-light .main-header > .logo {
background-color: #fff;
color: #333;
border-bottom: 0 solid transparent;
border-right: 1px solid #eee;
}
.skin-white-light .main-header > .logo:hover {
background-color: #fcfcfc;
}
@media (max-width: 767px) {
.skin-white-light .main-header > .logo {
background-color: #222;
color: #fff;
border-bottom: 0 solid transparent;
border-right: none;
}
.skin-white-light .main-header > .logo:hover {
background-color: #1f1f1f;
}
}
.skin-white-light .main-header li.user-header {
background-color: #222;
}
.skin-white-light .content-header {
background: transparent;
box-shadow: none;
}
.skin-white-light .wrapper,
.skin-white-light .main-sidebar,
.skin-white-light .left-side {
background-color: #f9fafc;
}
.skin-white-light .content-wrapper,
.skin-white-light .main-footer {
border-left: 1px solid #d2d6de;
}
.skin-white-light .user-panel > .info,
.skin-white-light .user-panel > .info > a {
color: #444;
}
.skin-white-light .sidebar-menu > li {
-webkit-transition: border-left-color 0.3s ease;
-o-transition: border-left-color 0.3s ease;
transition: border-left-color 0.3s ease;
}
.skin-white-light .sidebar-menu > li.header {
color: #848484;
background: #f9fafc;
}
.skin-white-light .sidebar-menu > li > a {
border-left: 3px solid transparent;
font-weight: 600;
}
.skin-white-light .sidebar-menu > li:hover > a,
.skin-white-light .sidebar-menu > li.active > a {
color: #000;
background: #f4f4f5;
}
.skin-white-light .sidebar-menu > li.active {
border-left-color: #fff;
}
.skin-white-light .sidebar-menu > li.active > a {
font-weight: 600;
}
.skin-white-light .sidebar-menu > li > .treeview-menu {
background: #f4f4f5;
}
.skin-white-light .sidebar a {
color: #444;
}
.skin-white-light .sidebar a:hover {
text-decoration: none;
}
.skin-white-light .treeview-menu > li > a {
color: #777;
}
.skin-white-light .treeview-menu > li.active > a,
.skin-white-light .treeview-menu > li > a:hover {
color: #000;
}
.skin-white-light .treeview-menu > li.active > a {
font-weight: 600;
}
.skin-white-light .sidebar-form {
border-radius: 3px;
border: 1px solid #d2d6de;
margin: 10px 10px;
}
.skin-white-light .sidebar-form input[type="text"],
.skin-white-light .sidebar-form .btn {
box-shadow: none;
background-color: #fff;
border: 1px solid transparent;
height: 35px;
}
.skin-white-light .sidebar-form input[type="text"] {
color: #666;
border-top-left-radius: 2px;
border-top-right-radius: 0;
border-bottom-right-radius: 0;
border-bottom-left-radius: 2px;
}
.skin-white-light .sidebar-form input[type="text"]:focus,
.skin-white-light .sidebar-form input[type="text"]:focus + .input-group-btn .btn {
background-color: #fff;
color: #666;
}
.skin-white-light .sidebar-form input[type="text"]:focus + .input-group-btn .btn {
border-left-color: #fff;
}
.skin-white-light .sidebar-form .btn {
color: #999;
border-top-left-radius: 0;
border-top-right-radius: 2px;
border-bottom-right-radius: 2px;
border-bottom-left-radius: 0;
}
@media (min-width: 768px) {
.skin-white-light.sidebar-mini.sidebar-collapse .sidebar-menu > li > .treeview-menu {
border-left: 1px solid #d2d6de;
}
}
/*# sourceMappingURL=skin-white-light.css.map */

View File

@ -0,0 +1,167 @@
/*
* Skin: White
* -----------
*/
/* skin-white navbar */
.skin-white .main-header {
-webkit-box-shadow: 0px 1px 1px rgba(0, 0, 0, 0.05);
box-shadow: 0px 1px 1px rgba(0, 0, 0, 0.05);
}
.skin-white .main-header .navbar-toggle {
color: #333;
}
.skin-white .main-header .navbar-brand {
color: #333;
border-right: 1px solid #eee;
}
.skin-white .main-header .navbar {
background-color: #fff;
}
.skin-white .main-header .navbar .nav > li > a {
color: #333;
}
.skin-white .main-header .navbar .nav > li > a:hover,
.skin-white .main-header .navbar .nav > li > a:active,
.skin-white .main-header .navbar .nav > li > a:focus,
.skin-white .main-header .navbar .nav .open > a,
.skin-white .main-header .navbar .nav .open > a:hover,
.skin-white .main-header .navbar .nav .open > a:focus,
.skin-white .main-header .navbar .nav > .active > a {
background: #fff;
color: #999;
}
.skin-white .main-header .navbar .sidebar-toggle {
color: #333;
}
.skin-white .main-header .navbar .sidebar-toggle:hover {
color: #999;
background: #fff;
}
.skin-white .main-header .navbar > .sidebar-toggle {
color: #333;
border-right: 1px solid #eee;
}
.skin-white .main-header .navbar .navbar-nav > li > a {
border-right: 1px solid #eee;
}
.skin-white .main-header .navbar .navbar-custom-menu .navbar-nav > li > a,
.skin-white .main-header .navbar .navbar-right > li > a {
border-left: 1px solid #eee;
border-right-width: 0;
}
.skin-white .main-header > .logo {
background-color: #fff;
color: #333;
border-bottom: 0 solid transparent;
border-right: 1px solid #eee;
}
.skin-white .main-header > .logo:hover {
background-color: #fcfcfc;
}
@media (max-width: 767px) {
.skin-white .main-header > .logo {
background-color: #222;
color: #fff;
border-bottom: 0 solid transparent;
border-right: none;
}
.skin-white .main-header > .logo:hover {
background-color: #1f1f1f;
}
}
.skin-white .main-header li.user-header {
background-color: #222;
}
.skin-white .content-header {
background: transparent;
box-shadow: none;
}
.skin-white .wrapper,
.skin-white .main-sidebar,
.skin-white .left-side {
background-color: #222d32;
}
.skin-white .user-panel > .info,
.skin-white .user-panel > .info > a {
color: #fff;
}
.skin-white .sidebar-menu > li.header {
color: #4b646f;
background: #1a2226;
}
.skin-white .sidebar-menu > li > a {
border-left: 3px solid transparent;
}
.skin-white .sidebar-menu > li:hover > a,
.skin-white .sidebar-menu > li.active > a {
color: #fff;
background: #1e282c;
border-left-color: #fff;
}
.skin-white .sidebar-menu > li > .treeview-menu {
margin: 0 1px;
background: #2c3b41;
}
.skin-white .sidebar a {
color: #b8c7ce;
}
.skin-white .sidebar a:hover {
text-decoration: none;
}
.skin-white .treeview-menu > li > a {
color: #8aa4af;
}
.skin-white .treeview-menu > li.active > a,
.skin-white .treeview-menu > li > a:hover {
color: #fff;
}
.skin-white .sidebar-form {
border-radius: 3px;
border: 1px solid #374850;
background-color: #374850;
margin: 10px 10px;
}
.skin-white .sidebar-form input[type="text"],
.skin-white .sidebar-form .btn {
box-shadow: none;
background-color: #374850;
border: 1px solid transparent;
height: 35px;
}
.skin-white .sidebar-form input[type="text"] {
color: #666;
border-top-left-radius: 2px;
border-top-right-radius: 0;
border-bottom-right-radius: 0;
border-bottom-left-radius: 2px;
}
.skin-white .sidebar-form input[type="text"]:focus,
.skin-white .sidebar-form input[type="text"]:focus + .input-group-btn .btn {
background-color: #fff;
color: #666;
}
.skin-white .sidebar-form input[type="text"]:focus + .input-group-btn {
background: #fff;
border-top-left-radius: 0;
border-top-right-radius: 2px;
border-bottom-right-radius: 2px;
border-bottom-left-radius: 0;
}
.skin-white .sidebar-form input[type="text"]:focus + .input-group-btn .btn {
border-left-color: #fff;
}
.skin-white .sidebar-form .btn {
color: #999;
border-top-left-radius: 0;
border-top-right-radius: 2px;
border-bottom-right-radius: 2px;
border-bottom-left-radius: 0;
}
.skin-white .pace .pace-progress {
background: #222;
}
.skin-white .pace .pace-activity {
border-top-color: #222;
border-left-color: #222;
}
/*# sourceMappingURL=skin-white.css.map */

View File

@ -14,6 +14,24 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template'], function
var table = $("#table");
table.on('post-body.bs.table', function (e, settings, json, xhr) {
var parenttable = table.closest('.bootstrap-table');
var d = $(".fixed-table-toolbar", parenttable).find(".search input");
d.off("keyup drop blur");
d.on("keyup", function (e) {
if (e.keyCode == 13) {
var that = this;
var options = table.bootstrapTable('getOptions');
options.pageNumber = 1;
options.queryParams = function (params) {
params.search = $(that).val();
return params;
};
table.bootstrapTable('refresh', {});
}
});
});
Template.helper("Moment", Moment);
Template.helper("addons", Config['addons']);
@ -29,11 +47,11 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template'], function
],
dataType: 'jsonp',
templateView: true,
search: false,
search: true,
showColumns: false,
showToggle: false,
showExport: false,
commonSearch: true,
commonSearch: false,
searchFormVisible: false,
pageSize: 12
});

View File

@ -25,7 +25,7 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template'], function
[
{field: 'state', checkbox: true, },
{field: 'id', title: 'ID'},
{field: 'title', title: __('Title'), align: 'left', align: 'left', formatter: Controller.api.formatter.title},
{field: 'title', title: __('Title'), align: 'left', formatter: Controller.api.formatter.title},
{field: 'icon', title: __('Icon'), formatter: Controller.api.formatter.icon},
{field: 'name', title: __('Name'), align: 'left', formatter: Controller.api.formatter.name},
{field: 'weigh', title: __('Weigh')},
@ -106,6 +106,12 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template'], function
}
},
bindevent: function () {
$(document).on('click', "input[name='row[ismenu]']", function () {
var name = $("input[name='row[name]']");
name.prop("placeholder", $(this).val() == 1 ? name.data("placeholder-menu") : name.data("placeholder-node"));
});
$("input[name='row[ismenu]']:checked").trigger("click");
var iconlist = [];
Form.api.bindevent($("form[role=form]"));
$(document).on('click', ".btn-search-icon", function () {

View File

@ -208,13 +208,13 @@ define(['jquery', 'bootstrap', 'backend', 'addtabs', 'adminlte', 'form'], functi
*/
var my_skins = [
"skin-blue",
"skin-black",
"skin-white",
"skin-red",
"skin-yellow",
"skin-purple",
"skin-green",
"skin-blue-light",
"skin-black-light",
"skin-white-light",
"skin-red-light",
"skin-yellow-light",
"skin-purple-light",

View File

@ -13559,11 +13559,13 @@ $.fn.addtabs = function (options) {
var tabid = 'tab_' + id;
var conid = 'con_' + id;
//如果关闭的是当前激活的TAB激活他的前一个TAB
if (obj.find("li.active").attr('id') == tabid) {
if (obj.find("li.active").not('.tabdrop').attr('id') == tabid) {
if ($("#" + tabid).prev().not(".tabdrop").size() > 0) {
$("#" + tabid).prev().not(".tabdrop").find("a").trigger("click");
} else if ($("#" + tabid).next().size() > 0) {
$("#" + tabid).next().trigger("click");
} else {
$(">li:last > a", navobj).trigger('click');
}
}
//关闭TAB

View File

@ -55,7 +55,7 @@ require.config({
},
// shim依赖配置
shim: {
'addons': ['backend'],
'addons': ['frontend'],
'bootstrap': ['jquery'],
'bootstrap-table': {
deps: [
@ -138,7 +138,7 @@ require(['jquery', 'bootstrap'], function ($, undefined) {
var paths = {};
paths['lang'] = Config.moduleurl + '/ajax/lang?callback=define&controllername=' + Config.controllername;
// 避免目录冲突
paths['backend/'] = 'backend/';
paths['frontend/'] = 'frontend/';
require.config({paths: paths});
// 初始化

View File

@ -69,7 +69,7 @@ require.config({
},
// shim依赖配置
shim: {
'addons': ['backend'],
'addons': ['frontend'],
'bootstrap': ['jquery'],
'bootstrap-table': {
deps: [
@ -152,7 +152,7 @@ require(['jquery', 'bootstrap'], function ($, undefined) {
var paths = {};
paths['lang'] = Config.moduleurl + '/ajax/lang?callback=define&controllername=' + Config.controllername;
// 避免目录冲突
paths['backend/'] = 'backend/';
paths['frontend/'] = 'frontend/';
require.config({paths: paths});
// 初始化

View File

@ -440,6 +440,10 @@ form.form-horizontal .control-label {
.sidebar-mini.sidebar-collapse .sidebar-menu > li:hover > .treeview-menu {
top: 41px;
}
.sidebar-mini.sidebar-collapse .sidebar-menu > li:hover > a > .pull-right-container {
top: 7px!important;
height: 17px;
}
}
.fieldlist dd {

View File

@ -55,3 +55,4 @@
// Utility classes
@import "bootstrap/utilities.less";
@import "bootstrap/responsive-utilities.less";

View File

@ -41,6 +41,8 @@
@import "fastadmin/carousel.less";
@import "fastadmin/modal.less";
@import "fastadmin/social-widgets.less";
@import "bootstrap/close.less";
@import "bootstrap/utilities.less";
//PAGES
//------
@import "fastadmin/mailbox.less";

View File

@ -4,9 +4,534 @@
@import url("../css/bootstrap.min.css");
@import url("../css/fastadmin.min.css");
@import url("../css/skins/skin-green.css");
@import url("../css/iconfont.css");
@import url("../libs/font-awesome/css/font-awesome.min.css");
@import url("../libs/toastr/toastr.min.css");
@import url("../libs/layer/dist/theme/default/layer.css");
@import url("../libs/bootstrap-daterangepicker/daterangepicker.css");
@import url("../libs/nice-validator/dist/jquery.validator.css");
.clearfix() {
&:before,
&:after {
content: " ";
display: table;
}
&:after {
clear: both;
}
}
html,
body {
height: 100%;
}
body {
padding-top: 50px;
font-size:13px;
}
.wow { visibility: hidden; }
.img-portfolio {
margin-bottom: 30px;
}
.img-hover:hover {
opacity: 0.8;
}
.dropdown:hover .dropdown-menu {
display: block;
margin-top: 0;
}
.navbar {
border:none;
}
.navbar-nav {
li > a {
font-size:13px;
}
}
.toast-top-center{
top:50px;
}
#toast-container > div{
.box-shadow(none);
}
.layui-layer-fast {
-webkit-animation-fill-mode: both;
animation-fill-mode: both;
-webkit-animation-duration: .3s;
animation-duration: .3s;
-webkit-animation-name: layer-bounceIn;
animation-name: layer-bounceIn;
}
/*修复nice-validator和summernote的编辑框冲突*/
.nice-validator .note-editor .note-editing-area .note-editable{
display:inherit;
}
/*预览区域*/
.plupload-preview {
padding:10px;
margin-bottom:0;
li {
margin-bottom:10px;
}
.thumbnail {
margin-bottom:10px;
}
a{
display:block;
&:first-child{
height:90px;
}
img{
height:80px;
object-fit: cover;
}
}
}
#header-navbar li.dropdown ul.dropdown-menu {
min-width:94px;
}
.panel-col {
min-height: 400px;
}
.panel-default {
padding: 0 15px;
border-color: #e4ecf3;
> .panel-heading {
position: relative;
font-size: 16px;
padding: 15px 0;
background: #fff;
border-bottom: 1px solid #f5f5f5;
}
> .panel-heading {
.panel-title {
color: #313131;
> i {
display: none;
}
}
.more {
position: absolute;
top: 13px;
right: 0;
display: block;
color: #919191;
.transition(all 0.3s ease);
}
.more:hover {
color: #616161;
.transition(all 0.3s ease);
}
.panel-bar {
position: absolute;
top: 7px;
right: 0;
display: block;
}
}
}
@media (max-width: 767px) {
.panel-default {
padding: 0 10px;
> .panel-heading {
padding: 10px 0;
.more {
top: 8px;
}
}
}
> .panel-body {
position: relative;
padding: 15px 0;
}
> .panel-footer {
padding: 15px 0;
background: none;
}
}
@media (max-width: 1920px) {
.panel-default > .panel-body .zuixin{
width:100%;border-bottom: 1px solid #f5f5f5; padding-bottom:5px; margin-bottom:10px;
}
}
@media (max-width: 992px) {
.panel-default > .panel-body .zuixin{
width:50%; padding-bottom:5px; margin-bottom:10px; float:left; padding-right:5px;
}
}
.panel-primary {
> .panel-heading {
background-color: #46c37b;
color: #fff;
}
> .panel-body {
background: #fafafa;
border-bottom-left-radius: 4px;
border-bottom-right-radius: 4px;
}
}
.panel-gray {
.box-shadow(0 2px 4px rgba(0, 0, 0, 0.08));
> .panel-heading {
background-color: #f5f5f5;
color: #919191;
}
> .panel-body {
color: #919191;
background: #fff;
border-bottom-left-radius: 4px;
border-bottom-right-radius: 4px;
}
}
.panel-page {
padding: 45px 50px 50px;
min-height: 500px;
.panel-heading {
background: transparent;
border-bottom: none;
margin: 0 0 30px 0;
padding: 0;
h2 {
font-size: 25px;
margin-top: 0;
}
}
}
@media (max-width: 767px) {
.panel-page {
padding: 15px;
min-height: 300px;
}
}
.nav-pills > li {
margin-right: 5px;
> a {
padding: 10px 15px;
color: #616161;
.transition(all 0.3s ease);
&:hover {
.transition(all 0.3s ease);
background-color: #f5f5f5;
}
}
&.active > a {
border:none;
color: #fff;
background: #46c37b;
.transition(all 0.3s ease);
border-radius: 3px;
}
}
.nav-pills.nav-pills-sm > li > a {
font-size: 12px;
line-height: 1.5;
padding: 4px 13px;
}
.metas {
position: relative;
padding: 10px;
color: #c1c1c1;
i {
margin-right: 5px;
}
.addon-price {
float: right;
}
.price {
color: #e83d2c;
font-size: 14px;
margin-right: 0;
}
.free {
color: #238312;
}
.comment {
margin-left: 10px;
}
}
@media (max-width: 767px) {
.metas {
.metas {
padding: 5px;
}
.comment {
display: none;
}
}
}
.text-line {
position: relative;
padding: 30px 0;
text-align: center;
&.small {
padding: 10px 0;
h5 {
font-size: 14px;
> span {
padding: 0 20px;
}
}
}
h5 {
position: relative;
margin-bottom: 20px;
font-size: 32px;
z-index: 1;
color: #313131;
> i {
padding-left: 20px;
background: #fff;
}
> span {
padding: 0 40px;
}
}
.subtitle {
font-size: 16px;
color: #919191;
}
}
@media (max-width: 767px) {
.text-line {
padding: 20px 0;
h5 {
font-size: 16px;
}
.subtitle {
font-size: 14px;
}
}
}
@media(max-width:767px) {
header.carousel .carousel {
height: 70%;
}
}
footer.footer{width:100%;color: #aaa;background: #555;margin-top:25px;}
footer.footer ul{margin:60px 0 30px 0;padding:0;}
footer.footer ul li.f-tit{margin-bottom:10px;font-size: 14px;color: #fff;}
footer.footer ul li{line-height: 26px;white-space: nowrap;list-style: none;margin:0;padding:0;}
footer.footer ul li a{color: #aaa;}
footer.footer ul li a:hover{color: #aaa;text-decoration: underline !important;}
footer.footer .address{line-height: 50px;text-align: center;background: #393939;margin:0;}
footer p.address a{color: #aaa;}
footer p.address a:hover{color: #fff;}
@media(max-width:767px) {
footer.footer {overflow: hidden;}
footer.footer .container{margin:0 20px;}
footer.footer ul {margin:20px 0 10px 0;}
footer.footer .address{padding:0 10px;}
}
.rotate{
-webkit-transition-duration: 0.8s;
-moz-transition-duration: 0.8s;
-o-transition-duration: 0.8s;
transition-duration: 0.8s;
-webkit-transition-property: -webkit-transform;
-moz-transition-property: -moz-transform;
-o-transition-property: -o-transform;
transition-property: transform;
overflow:hidden;
&:hover
{
-webkit-transform:rotate(360deg);
-moz-transform:rotate(360deg);
-o-transform:rotate(360deg);
}
}
.user-section {
background: #fff;
padding: 15px;
margin-bottom: 20px;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;
border: 1px solid #e4ecf3;
}
.login-section {
margin: 50px auto;
width: 460px;
-webkit-border-radius: 0;
-moz-border-radius: 0;
border-radius: 0;
&.login-section-weixin {
min-height: 315px;
}
.logon-tab {
margin: -15px -15px 0 -15px;
> a {
display: block;
padding: 20px;
float: left;
width: 50%;
font-size: 16px;
text-align: center;
color: #616161;
background-color: #f5f5f5;
.transition(all 0.3s ease);
&:hover {
background-color: #fafafa;
.transition(all 0.3s ease);
}
&.active {
background-color: #fff;
.transition(all 0.3s ease);
}
}
}
.login-main {
padding: 40px 45px 20px 45px;
}
.control-label {
font-size:13px;
}
}
@media (max-width: 767px) {
.login-section {
width: 100%;
margin: 20px auto;
.login-main {
padding: 20px 0 0 0;
}
}
}
@media (min-width: 768px) {
.login-modal {
width: 350px;
.modal-body {
padding: 30px 30px 15px 30px;
}
.modal-footer {
padding: 30px;
}
}
}
#content-container {
margin: 30px auto;
min-height: 400px;
}
@media (max-width: 767px) {
#content-container {
min-height: 250px;
}
}
.sidenav {
padding: 20px 0 10px 0;
margin-bottom: 20px;
background-color: #fff;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;
border: 1px solid #e4ecf3;
.list-group{
&:last-child {
margin-bottom: 0;
}
.list-group-heading {
list-style-type: none;
color: #919191;
margin-bottom: 10px;
margin-left: 35px;
font-size:14px;
}
.list-group-item {
-webkit-border-radius: 0;
-moz-border-radius: 0;
border-radius: 0;
border: none;
padding: 0;
border-left: 2px solid transparent;
&:last-child,&:first-child {
-webkit-border-radius: 0;
-moz-border-radius: 0;
border-radius: 0;
}
&:hover {
background-color: #f5f5f5;
}
> a {
display: block;
color: #616161;
padding: 10px 15px 10px 35px;
}
&.active {
border-left: 2px solid #46c37b;
background: none;
> a {
color: #46c37b;
}
}
}
}
}
.flarum-section ul li a{font-size:13px;}
.nav li{
.avatar-text,.avatar-img {
height:30px;
width:30px;
line-height:30px;
font-size:14px;
}
.avatar-img{
font-size:0;
img{
border-radius:30px;
width:30px;height:30px;
}
}
}
.avatar-text,.avatar-img {
display: inline-block;
box-sizing: content-box;
color: #fff;
text-align: center;
vertical-align: top;
background-color: #e8ecf3;
font-weight: normal;
width: 48px;
height: 48px;
border-radius: 48px;
font-size: 24px;
line-height: 48px;
}
.avatar-img {
font-size:0;
}
.avatar-img img{
border-radius:48px;
width:48px;height:48px;
}

View File

@ -1,8 +1,8 @@
//All skins in one file
@import "skin-blue.less";
@import "skin-blue-light.less";
@import "skin-black.less";
@import "skin-black-light.less";
@import "skin-white.less";
@import "skin-white-light.less";
@import "skin-green.less";
@import "skin-green-light.less";
@import "skin-red.less";

View File

@ -1,5 +1,5 @@
/*
* Skin: Black
* Skin: White
* -----------
*/
@import "../bootstrap-less/mixins.less";
@ -7,8 +7,8 @@
@import "../fastadmin/variables.less";
@import "../fastadmin/mixins.less";
/* skin-black navbar */
.skin-black-light {
/* skin-white navbar */
.skin-white-light {
//Navbar & Logo
.main-header {
.box-shadow(0px 1px 1px rgba(0, 0, 0, 0.05));

View File

@ -1,5 +1,5 @@
/*
* Skin: Black
* Skin: White
* -----------
*/
@import "../bootstrap-less/mixins.less";
@ -7,8 +7,8 @@
@import "../fastadmin/variables.less";
@import "../fastadmin/mixins.less";
/* skin-black navbar */
.skin-black {
/* skin-white navbar */
.skin-white {
//Navbar & Logo
.main-header {
.box-shadow(0px 1px 1px rgba(0, 0, 0, 0.05));

View File

@ -86,7 +86,7 @@ else
{
if (!is_dir(ROOT_PATH . $v))
{
$errInfo = '请先下载完整包覆盖后再安装,<a href="' . $link['qqun'] . '" target="_blank">群共享下载</a> <a href="' . $link['gitee'] . '" target="_blank">码云下载</a>';
$errInfo = '当前代码不完整请加入QQ群(<a href="' . $link['qqun'] . '" target="_blank">636393962</a>)在群共享免费下载FastAdmin完整包后再尝试安装';
break;
}
}