ソースを参照

修复selectpage树状显示的bug
修复后台表格图片点击弹出新窗口的BUG
优化后台站点名称、用户昵称头像的显示渲染
优化后台宽度自适应
增强后台管理员安全鉴权

Karson 6 年 前
コミット
678be2f3a9

+ 1 - 0
application/admin/command/Install/fastadmin.sql

@@ -23,6 +23,7 @@ CREATE TABLE `fa_admin` (
   `email` varchar(100) NOT NULL DEFAULT '' COMMENT '电子邮箱',
   `loginfailure` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '失败次数',
   `logintime` int(10) DEFAULT NULL COMMENT '登录时间',
+  `loginip` varchar(50) DEFAULT NULL COMMENT '登录IP',
   `createtime` int(10) DEFAULT NULL COMMENT '创建时间',
   `updatetime` int(10) DEFAULT NULL COMMENT '更新时间',
   `token` varchar(59) NOT NULL DEFAULT '' COMMENT 'Session标识',

+ 33 - 21
application/admin/controller/general/Config.php

@@ -6,6 +6,7 @@ use app\common\controller\Backend;
 use app\common\library\Email;
 use app\common\model\Config as ConfigModel;
 use think\Exception;
+use think\Validate;
 
 /**
  * 系统配置
@@ -50,8 +51,8 @@ class Config extends Backend
             if (in_array($value['type'], ['select', 'selects', 'checkbox', 'radio'])) {
                 $value['value'] = explode(',', $value['value']);
             }
-            $value['content'] = json_decode($value['content'], TRUE);
-			$value['tip'] = htmlspecialchars($value['tip']);
+            $value['content'] = json_decode($value['content'], true);
+            $value['tip'] = htmlspecialchars($value['tip']);
             $siteList[$v['group']]['list'][] = $value;
         }
         $index = 0;
@@ -106,7 +107,7 @@ class Config extends Backend
      * 编辑
      * @param null $ids
      */
-    public function edit($ids = NULL)
+    public function edit($ids = null)
     {
         if ($this->request->isPost()) {
             $row = $this->request->post("row/a");
@@ -136,11 +137,15 @@ class Config extends Backend
         }
     }
 
+    /**
+     * 删除
+     * @param string $ids
+     */
     public function del($ids = "")
     {
-        $name = $this->request->request('name');
+        $name = $this->request->post('name');
         $config = ConfigModel::getByName($name);
-        if ($config) {
+        if ($name && $config) {
             try {
                 $config->delete();
                 $this->refreshFile();
@@ -160,17 +165,19 @@ class Config extends Backend
     {
         $config = [];
         foreach ($this->model->all() as $k => $v) {
-
             $value = $v->toArray();
             if (in_array($value['type'], ['selects', 'checkbox', 'images', 'files'])) {
                 $value['value'] = explode(',', $value['value']);
             }
             if ($value['type'] == 'array') {
-                $value['value'] = (array)json_decode($value['value'], TRUE);
+                $value['value'] = (array)json_decode($value['value'], true);
             }
             $config[$value['name']] = $value['value'];
         }
-        file_put_contents(APP_PATH . 'extra' . DS . 'site.php', '<?php' . "\n\nreturn " . var_export($config, true) . ";");
+        file_put_contents(
+            APP_PATH . 'extra' . DS . 'site.php',
+            '<?php' . "\n\nreturn " . var_export($config, true) . ";"
+        );
     }
 
     /**
@@ -181,7 +188,6 @@ class Config extends Backend
     {
         $params = $this->request->post("row/a");
         if ($params) {
-
             $config = $this->model->get($params);
             if (!$config) {
                 return $this->success();
@@ -200,19 +206,25 @@ class Config extends Backend
     public function emailtest()
     {
         $row = $this->request->post('row/a');
-        \think\Config::set('site', array_merge(\think\Config::get('site'), $row));
-        $receiver = $this->request->request("receiver");
-        $email = new Email;
-        $result = $email
-            ->to($receiver)
-            ->subject(__("This is a test mail"))
-            ->message('<div style="min-height:550px; padding: 100px 55px 200px;">' . __('This is a test mail content') . '</div>')
-            ->send();
-        if ($result) {
-            $this->success();
+        $receiver = $this->request->post("receiver");
+        if ($receiver) {
+            if (!Validate::is($receiver, "email")) {
+                $this->error(__('Please input correct email'));
+            }
+            \think\Config::set('site', array_merge(\think\Config::get('site'), $row));
+            $email = new Email;
+            $result = $email
+                ->to($receiver)
+                ->subject(__("This is a test mail"))
+                ->message('<div style="min-height:550px; padding: 100px 55px 200px;">' . __('This is a test mail content') . '</div>')
+                ->send();
+            if ($result) {
+                $this->success();
+            } else {
+                $this->error($email->getError());
+            }
         } else {
-            $this->error($email->getError());
+            return $this->error(__('Invalid parameters'));
         }
     }
-
 }

+ 17 - 19
application/admin/controller/general/Profile.php

@@ -22,23 +22,22 @@ class Profile extends Backend
     {
         //设置过滤方法
         $this->request->filter(['strip_tags']);
-        if ($this->request->isAjax())
-        {
+        if ($this->request->isAjax()) {
             $model = model('AdminLog');
             list($where, $sort, $order, $offset, $limit) = $this->buildparams();
 
             $total = $model
-                    ->where($where)
-                    ->where('admin_id', $this->auth->id)
-                    ->order($sort, $order)
-                    ->count();
+                ->where($where)
+                ->where('admin_id', $this->auth->id)
+                ->order($sort, $order)
+                ->count();
 
             $list = $model
-                    ->where($where)
-                    ->where('admin_id', $this->auth->id)
-                    ->order($sort, $order)
-                    ->limit($offset, $limit)
-                    ->select();
+                ->where($where)
+                ->where('admin_id', $this->auth->id)
+                ->order($sort, $order)
+                ->limit($offset, $limit)
+                ->select();
 
             $result = array("total" => $total, "rows" => $list);
 
@@ -52,18 +51,18 @@ class Profile extends Backend
      */
     public function update()
     {
-        if ($this->request->isPost())
-        {
+        if ($this->request->isPost()) {
             $params = $this->request->post("row/a");
-            $params = array_filter(array_intersect_key($params, array_flip(array('email', 'nickname', 'password', 'avatar'))));
+            $params = array_filter(array_intersect_key(
+                $params,
+                array_flip(array('email', 'nickname', 'password', 'avatar'))
+            ));
             unset($v);
-            if (isset($params['password']))
-            {
+            if (isset($params['password'])) {
                 $params['salt'] = Random::alnum();
                 $params['password'] = md5(md5($params['password']) . $params['salt']);
             }
-            if ($params)
-            {
+            if ($params) {
                 $admin = Admin::get($this->auth->id);
                 $admin->save($params);
                 //因为个人资料面板读取的Session显示,修改自己资料后同时更新Session
@@ -74,5 +73,4 @@ class Profile extends Backend
         }
         return;
     }
-
 }

+ 1 - 1
application/admin/lang/zh-cn/dashboard.php

@@ -44,5 +44,5 @@ return [
     'Timezone'                => '时区',
     'Language'                => '语言',
     'View more'               => '查看更多',
-    'Security tips'           => '<i class="fa fa-warning"></i> 安全提示:你正在使用默认的后台登录入口,为了你的网站安全,建议你修改后台登录入口,<a href="https://forum.fastadmin.net/thread/7640" target="_blank">点击查看修改方法</a>',
+    'Security tips'           => '<i class="fa fa-warning"></i> 安全提示:你正在使用默认的后台登录入口,为了你的网站安全,强烈建议你修改后台登录入口,<a href="https://forum.fastadmin.net/thread/7640" target="_blank">点击查看修改方法</a>',
 ];

+ 1 - 0
application/admin/lang/zh-cn/general/config.php

@@ -57,4 +57,5 @@ return [
     'This is a test mail content' => '这是一封来自FastAdmin校验邮件,用于校验邮件配置是否正常!',
     'This is a test mail'         => '这是一封来自FastAdmin的邮件',
     'Please input your email'     => '请输入测试接收者邮箱',
+    'Please input correct email'  => '请输入正确的邮箱地址',
 ];

+ 43 - 10
application/admin/library/Auth.php

@@ -30,9 +30,9 @@ class Auth extends \fast\Auth
     /**
      * 管理员登录
      *
-     * @param   string $username 用户名
-     * @param   string $password 密码
-     * @param   int    $keeptime 有效时长
+     * @param string $username 用户名
+     * @param string $password 密码
+     * @param int    $keeptime 有效时长
      * @return  boolean
      */
     public function login($username, $password, $keeptime = 0)
@@ -58,6 +58,7 @@ class Auth extends \fast\Auth
         }
         $admin->loginfailure = 0;
         $admin->logintime = time();
+        $admin->loginip = request()->ip(0, false);
         $admin->token = Random::uuid();
         $admin->save();
         Session::set("admin", $admin->toArray());
@@ -101,6 +102,11 @@ class Auth extends \fast\Auth
             if ($key != md5(md5($id) . md5($keeptime) . md5($expiretime) . $admin->token)) {
                 return false;
             }
+            $ip = request()->ip(0, false);
+            //IP有变动
+            if ($admin->loginip != $ip) {
+                return false;
+            }
             Session::set("admin", $admin->toArray());
             //刷新自动登录的时效
             $this->keeplogin($keeptime);
@@ -113,7 +119,7 @@ class Auth extends \fast\Auth
     /**
      * 刷新保持登录的Cookie
      *
-     * @param   int $keeptime
+     * @param int $keeptime
      * @return  boolean
      */
     protected function keeplogin($keeptime = 0)
@@ -178,6 +184,9 @@ class Auth extends \fast\Auth
                 return false;
             }
         }
+        if (!isset($admin['loginip']) || $admin['loginip'] != request()->ip(0, false)) {
+            return false;
+        }
         $this->logined = true;
         return true;
     }
@@ -258,10 +267,17 @@ class Auth extends \fast\Auth
         foreach ($groups as $k => $v) {
             $groupIds[] = $v['id'];
         }
+        $originGroupIds = $groupIds;
+        foreach ($groups as $k => $v) {
+            if (in_array($v['pid'], $originGroupIds)) {
+                $groupIds = array_diff($groupIds, [$v['id']]);
+                unset($groups[$k]);
+            }
+        }
         // 取出所有分组
         $groupList = \app\admin\model\AuthGroup::where(['status' => 'normal'])->select();
         $objList = [];
-        foreach ($groups as $K => $v) {
+        foreach ($groups as $k => $v) {
             if ($v['rules'] === '*') {
                 $objList = $groupList;
                 break;
@@ -295,7 +311,6 @@ class Auth extends \fast\Auth
             field('uid,group_id')
                 ->where('group_id', 'in', $groupIds)
                 ->select();
-
             foreach ($authGroupList as $k => $v) {
                 $childrenAdminIds[] = $v['uid'];
             }
@@ -340,7 +355,7 @@ class Auth extends \fast\Auth
     /**
      * 获取左侧和顶部菜单栏
      *
-     * @param array  $params    URL对应的badge数据
+     * @param array  $params URL对应的badge数据
      * @param string $fixedPage 默认页
      * @return array
      */
@@ -435,18 +450,36 @@ class Auth extends \fast\Auth
                 $selectParentIds = $tree->getParentsIds($select_id, true);
             }
             foreach ($topList as $index => $item) {
-                $childList = Tree::instance()->getTreeMenu($item['id'], '<li class="@class" pid="@pid"><a href="@url@addtabs" addtabs="@id" url="@url" py="@py" pinyin="@pinyin"><i class="@icon"></i> <span>@title</span> <span class="pull-right-container">@caret @badge</span></a> @childlist</li>', $select_id, '', 'ul', 'class="treeview-menu"');
+                $childList = Tree::instance()->getTreeMenu(
+                    $item['id'],
+                    '<li class="@class" pid="@pid"><a href="@url@addtabs" addtabs="@id" url="@url" py="@py" pinyin="@pinyin"><i class="@icon"></i> <span>@title</span> <span class="pull-right-container">@caret @badge</span></a> @childlist</li>',
+                    $select_id,
+                    '',
+                    'ul',
+                    'class="treeview-menu"'
+                );
                 $current = in_array($item['id'], $selectParentIds);
                 $url = $childList ? 'javascript:;' : url($item['url']);
                 $addtabs = $childList || !$url ? "" : (stripos($url, "?") !== false ? "&" : "?") . "ref=addtabs";
-                $childList = str_replace('" pid="' . $item['id'] . '"', ' treeview ' . ($current ? '' : 'hidden') . '" pid="' . $item['id'] . '"', $childList);
+                $childList = str_replace(
+                    '" pid="' . $item['id'] . '"',
+                    ' treeview ' . ($current ? '' : 'hidden') . '" pid="' . $item['id'] . '"',
+                    $childList
+                );
                 $nav .= '<li class="' . ($current ? 'active' : '') . '"><a href="' . $url . $addtabs . '" addtabs="' . $item['id'] . '" url="' . $url . '"><i class="' . $item['icon'] . '"></i> <span>' . $item['title'] . '</span> <span class="pull-right-container"> </span></a> </li>';
                 $menu .= $childList;
             }
         } else {
             // 构造菜单数据
             Tree::instance()->init($ruleList);
-            $menu = Tree::instance()->getTreeMenu(0, '<li class="@class"><a href="@url@addtabs" addtabs="@id" url="@url" py="@py" pinyin="@pinyin"><i class="@icon"></i> <span>@title</span> <span class="pull-right-container">@caret @badge</span></a> @childlist</li>', $select_id, '', 'ul', 'class="treeview-menu"');
+            $menu = Tree::instance()->getTreeMenu(
+                0,
+                '<li class="@class"><a href="@url@addtabs" addtabs="@id" url="@url" py="@py" pinyin="@pinyin"><i class="@icon"></i> <span>@title</span> <span class="pull-right-container">@caret @badge</span></a> @childlist</li>',
+                $select_id,
+                '',
+                'ul',
+                'class="treeview-menu"'
+            );
             if ($selected) {
                 $nav .= '<li role="presentation" id="tab_' . $selected['id'] . '" class="' . ($referer ? '' : 'active') . '"><a href="#con_' . $selected['id'] . '" node-id="' . $selected['id'] . '" aria-controls="' . $selected['id'] . '" role="tab" data-toggle="tab"><i class="' . $selected['icon'] . ' fa-fw"></i> <span>' . $selected['title'] . '</span> </a></li>';
             }

+ 6 - 6
application/admin/view/common/header.html

@@ -1,9 +1,9 @@
 <!-- Logo -->
 <a href="javascript:;" class="logo">
     <!-- 迷你模式下Logo的大小为50X50 -->
-    <span class="logo-mini">{$site.name|mb_substr=0,4,'utf-8'|mb_strtoupper='utf-8'}</span>
+    <span class="logo-mini">{$site.name|mb_substr=0,4,'utf-8'|mb_strtoupper='utf-8'|htmlentities}</span>
     <!-- 普通模式下Logo -->
-    <span class="logo-lg"><b>{$site.name|mb_substr=0,4,'utf-8'}</b>{$site.name|mb_substr=4,null,'utf-8'}</span>
+    <span class="logo-lg"><b>{$site.name|mb_substr=0,4,'utf-8'|htmlentities}</b>{$site.name|mb_substr=4,null,'utf-8'|htmlentities}</span>
 </a>
 
 <!-- 顶部通栏样式 -->
@@ -72,16 +72,16 @@
                 <!-- 账号信息下拉框 -->
                 <li class="dropdown user user-menu">
                     <a href="#" class="dropdown-toggle" data-toggle="dropdown">
-                        <img src="{$admin.avatar|cdnurl}" class="user-image" alt="{$admin.nickname}">
-                        <span class="hidden-xs">{$admin.nickname}</span>
+                        <img src="{$admin.avatar|cdnurl|htmlentities}" class="user-image" alt="{$admin.nickname|htmlentities}">
+                        <span class="hidden-xs">{$admin.nickname|htmlentities}</span>
                     </a>
                     <ul class="dropdown-menu">
                         <!-- User image -->
                         <li class="user-header">
-                            <img src="{$admin.avatar|cdnurl}" class="img-circle" alt="">
+                            <img src="{$admin.avatar|cdnurl|htmlentities}" class="img-circle" alt="">
 
                             <p>
-                                {$admin.nickname}
+                                {$admin.nickname|htmlentities}
                                 <small>{$admin.logintime|date="Y-m-d H:i:s",###}</small>
                             </p>
                         </li>

+ 2 - 2
application/admin/view/common/menu.html

@@ -3,10 +3,10 @@
     <!-- 管理员信息 -->
     <div class="user-panel hidden-xs">
         <div class="pull-left image">
-            <a href="general/profile" class="addtabsit"><img src="{$admin.avatar|cdnurl}" class="img-circle" /></a>
+            <a href="general/profile" class="addtabsit"><img src="{$admin.avatar|cdnurl|htmlentities}" class="img-circle" /></a>
         </div>
         <div class="pull-left info">
-            <p>{$admin.nickname}</p>
+            <p>{$admin.nickname|htmlentities}</p>
             <i class="fa fa-circle text-success"></i> {:__('Online')}
         </div>
     </div>

+ 1 - 1
application/admin/view/common/script.html

@@ -1 +1 @@
-<script src="__CDN__/assets/js/require{$Think.config.app_debug?'':'.min'}.js" data-main="__CDN__/assets/js/require-backend{$Think.config.app_debug?'':'.min'}.js?v={$site.version}"></script>
+<script src="__CDN__/assets/js/require{$Think.config.app_debug?'':'.min'}.js" data-main="__CDN__/assets/js/require-backend{$Think.config.app_debug?'':'.min'}.js?v={$site.version|htmlentities}"></script>

+ 4 - 4
application/admin/view/general/profile/index.html

@@ -46,18 +46,18 @@
             <div class="panel-body">
 
                 <form id="update-form" role="form" data-toggle="validator" method="POST" action="{:url('general.profile/update')}">
-                    <input type="hidden" id="c-avatar" name="row[avatar]" value="{$admin.avatar}"/>
+                    <input type="hidden" id="c-avatar" name="row[avatar]" value="{$admin.avatar|htmlentities}"/>
                     <div class="box-body box-profile">
 
                         <div class="profile-avatar-container">
-                            <img class="profile-user-img img-responsive img-circle plupload" src="{$admin.avatar|cdnurl}" alt="">
+                            <img class="profile-user-img img-responsive img-circle plupload" src="{$admin.avatar|cdnurl|htmlentities}" alt="">
                             <div class="profile-avatar-text img-circle">{:__('Click to edit')}</div>
                             <button id="plupload-avatar" class="plupload" data-input-id="c-avatar"><i class="fa fa-upload"></i> {:__('Upload')}</button>
                         </div>
 
-                        <h3 class="profile-username text-center">{$admin.username}</h3>
+                        <h3 class="profile-username text-center">{$admin.username|htmlentities}</h3>
 
-                        <p class="text-muted text-center">{$admin.email}</p>
+                        <p class="text-muted text-center">{$admin.email|htmlentities}</p>
                         <div class="form-group">
                             <label for="username" class="control-label">{:__('Username')}:</label>
                             <input type="text" class="form-control" id="username" name="row[username]" value="{$admin.username|htmlentities}" disabled/>

+ 1 - 1
application/common/controller/Backend.php

@@ -490,7 +490,7 @@ class Backend extends Controller
                     'pid'       => isset($item['pid']) ? $item['pid'] : 0
                 ];
             }
-            if ($istree) {
+            if ($istree && !$primaryvalue) {
                 $tree = Tree::instance();
                 $tree->init(collection($list)->toArray(), 'pid');
                 $list = $tree->getTreeList($tree->getTreeArray(0), $field);

+ 1 - 1
application/index/view/common/script.html

@@ -1 +1 @@
-<script src="__CDN__/assets/js/require{$Think.config.app_debug?'':'.min'}.js" data-main="__CDN__/assets/js/require-frontend{$Think.config.app_debug?'':'.min'}.js?v={$site.version}"></script>
+<script src="__CDN__/assets/js/require{$Think.config.app_debug?'':'.min'}.js" data-main="__CDN__/assets/js/require-frontend{$Think.config.app_debug?'':'.min'}.js?v={$site.version|htmlentities}"></script>

+ 1 - 1
application/index/view/layout/default.html

@@ -61,7 +61,7 @@
 
         <footer class="footer" style="clear:both">
             <!-- FastAdmin是开源程序,建议在您的网站底部保留一个FastAdmin的链接 -->
-            <p class="copyright">Copyright&nbsp;©&nbsp;2017-2019 Powered by <a href="https://www.fastadmin.net" target="_blank">FastAdmin</a> All Rights Reserved {$site.name} {:__('Copyrights')} <a href="http://www.miibeian.gov.cn" target="_blank">{$site.beian}</a></p>
+            <p class="copyright">Copyright&nbsp;©&nbsp;2017-2019 Powered by <a href="https://www.fastadmin.net" target="_blank">FastAdmin</a> All Rights Reserved {$site.name|htmlentities} {:__('Copyrights')} <a href="http://www.miibeian.gov.cn" target="_blank">{$site.beian|htmlentities}</a></p>
         </footer>
 
         {include file="common/script" /}

+ 2 - 2
public/assets/css/backend.css

@@ -918,7 +918,7 @@ table.table-nowrap thead > tr > th {
   }
 }
 /*平板样式*/
-@media (max-width: 768px) {
+@media (max-width: 767px) {
   body .wrapper .main-header .logo {
     background: none;
     color: #fff;
@@ -997,4 +997,4 @@ table.table-nowrap thead > tr > th {
 .btn-switcher .text-gray {
   color: #d2d6de !important;
 }
-/*# sourceMappingURL=../css/backend.css.map */
+/*# sourceMappingURL=backend.css.map */

ファイルの差分が大きいため隠しています
+ 1 - 1
public/assets/css/backend.min.css


+ 7 - 1
public/assets/js/backend/addon.js

@@ -533,7 +533,13 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template'], function
                     return '<a href="javascript:;" data-toggle="tooltip" title="' + __('Click to toggle status') + '" class="btn btn-toggle btn-' + (row.addon.state == 1 ? "disable" : "enable") + '" data-action="' + (row.addon.state == 1 ? "disable" : "enable") + '" data-name="' + row.name + '"><i class="fa ' + (row.addon.state == 0 ? 'fa-toggle-on fa-rotate-180 text-gray' : 'fa-toggle-on text-success') + ' fa-2x"></i></a>';
                 },
                 author: function (value, row, index) {
-                    return '<a href="https://wpa.qq.com/msgrd?v=3&uin=' + row.qq + '&site=fastadmin.net&menu=yes" target="_blank" data-toggle="tooltip" title="' + __('Click to contact developer') + '" class="text-primary">' + value + '</a>';
+                    var url = 'javascript:';
+                    if (typeof row.homepage !== 'undefined') {
+                        url = row.homepage;
+                    } else if (typeof row.qq !== 'undefined') {
+                        url = 'https://wpa.qq.com/msgrd?v=3&uin=' + row.qq + '&site=fastadmin.net&menu=yes';
+                    }
+                    return '<a href="' + url + '" target="_blank" data-toggle="tooltip" title="' + __('Click to contact developer') + '" class="text-primary">' + value + '</a>';
                 },
                 price: function (value, row, index) {
                     if (isNaN(value)) {

+ 3 - 3
public/assets/js/backend/general/config.js

@@ -67,8 +67,8 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
                 var that = this;
                 Layer.prompt({title: __('Please input your email'), formType: 0}, function (value, index) {
                     Backend.api.ajax({
-                        url: "general/config/emailtest?receiver=" + value,
-                        data: $(that).closest("form").serialize()
+                        url: "general/config/emailtest",
+                        data: $(that).closest("form").serialize() + "&receiver=" + value
                     });
                 });
 
@@ -79,7 +79,7 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
                 var that = this;
                 Layer.confirm(__('Are you sure you want to delete this item?'), {icon: 3, title:'提示'}, function (index) {
                     Backend.api.ajax({
-                        url: "general/config/del?receiver=" + value,
+                        url: "general/config/del",
                         data: {name: $(that).data("name")}
                     }, function () {
                         $(that).closest("tr").remove();

ファイルの差分が大きいため隠しています
+ 22 - 35
public/assets/js/echarts.min.js


ファイルの差分が大きいため隠しています
+ 627 - 622
public/assets/js/require-backend.min.js


+ 6 - 2
public/assets/js/require-table.js

@@ -434,7 +434,7 @@ define(['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstrap-table
                 image: function (value, row, index) {
                     value = value ? value : '/assets/img/blank.gif';
                     var classname = typeof this.classname !== 'undefined' ? this.classname : 'img-sm img-center';
-                    return '<a href="javascript:void(0)" target="_blank"><img class="' + classname + '" src="' + Fast.api.cdnurl(value) + '" /></a>';
+                    return '<a href="javascript:"><img class="' + classname + '" src="' + Fast.api.cdnurl(value) + '" /></a>';
                 },
                 images: function (value, row, index) {
                     value = value === null ? '' : value.toString();
@@ -443,10 +443,14 @@ define(['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstrap-table
                     var html = [];
                     $.each(arr, function (i, value) {
                         value = value ? value : '/assets/img/blank.gif';
-                        html.push('<a href="javascript:void(0)" target="_blank"><img class="' + classname + '" src="' + Fast.api.cdnurl(value) + '" /></a>');
+                        html.push('<a href="javascript:"><img class="' + classname + '" src="' + Fast.api.cdnurl(value) + '" /></a>');
                     });
                     return html.join(' ');
                 },
+                content: function (value, row, index) {
+                    var width = this.width != undefined ? this.width : 250;
+                    return "<div style='white-space: nowrap; text-overflow:ellipsis; overflow: hidden; max-width:" + width + "px;'>" + value + "</div>";
+                },
                 status: function (value, row, index) {
                     var custom = {normal: 'success', hidden: 'gray', deleted: 'danger', locked: 'info'};
                     if (typeof this.custom !== 'undefined') {

+ 3 - 2
public/assets/less/backend.less

@@ -16,6 +16,7 @@
 @import url("../libs/nice-validator/dist/jquery.validator.css");
 @import url("../libs/bootstrap-select/dist/css/bootstrap-select.min.css");
 @import url("../libs/fastadmin-selectpage/selectpage.css");
+@import url("../libs/bootstrap-slider/slider.css");
 
 @main-bg: #f1f4f6;
 @panel-intro-bg: darken(@main-bg, 3%);
@@ -954,7 +955,7 @@ table.table-nowrap {
     }
     //样式二关闭按钮
     .layui-layer-close2, .layui-layer-close2:hover {
-      background: url('../libs/layer/dist/theme/default/icon.png') no-repeat -149px -31px !important;
+      background: url('../libs/fastadmin-layer/dist/theme/default/icon.png') no-repeat -149px -31px !important;
       top: -30px;
       right: -30px;
       &:after {
@@ -1045,7 +1046,7 @@ table.table-nowrap {
 }
 
 /*平板样式*/
-@media (max-width: @screen-tablet) {
+@media (max-width: @screen-xs-max) {
 
   body .wrapper .main-header .logo {
     background: none;