Browse Source

新增CRUD编辑时添加htmlentities处理
新增CRUD一键生成fieldlist组件
修复Date类一处命名错误
修复带下划线字段枚举型列表错误
修复插件配置下拉列表配置失效的BUG
修复表单重置时selectpicker和citypicker的错误
优化注册登录后的跳转
优化上传或选择文件后的验证提示

Karson 6 years ago
parent
commit
ba215a4593
36 changed files with 377 additions and 284 deletions
  1. 33 12
      application/admin/command/Crud.php
  2. 10 0
      application/admin/command/Crud/stubs/html/fieldlist.stub
  3. 1 1
      application/admin/command/Crud/stubs/html/heading-html.stub
  4. 4 3
      application/admin/command/Install/fastadmin.sql
  5. 3 1
      application/admin/controller/Addon.php
  6. 2 1
      application/admin/controller/Category.php
  7. 12 15
      application/admin/controller/user/User.php
  8. 4 2
      application/admin/lang/zh-cn/dashboard.php
  9. 8 9
      application/admin/view/addon/config.html
  10. 3 3
      application/admin/view/auth/admin/edit.html
  11. 1 1
      application/admin/view/auth/group/edit.html
  12. 4 4
      application/admin/view/auth/rule/edit.html
  13. 1 1
      application/admin/view/category/add.html
  14. 5 5
      application/admin/view/category/edit.html
  15. 191 150
      application/admin/view/dashboard/index.html
  16. 6 6
      application/admin/view/general/config/index.html
  17. 3 3
      application/admin/view/general/profile/index.html
  18. 1 1
      application/admin/view/user/group/edit.html
  19. 3 3
      application/admin/view/user/rule/edit.html
  20. 5 5
      application/admin/view/user/user/edit.html
  21. 1 1
      application/config.php
  22. 0 1
      application/index/controller/Index.php
  23. 4 4
      application/index/controller/User.php
  24. 1 1
      application/index/view/user/login.html
  25. 5 5
      application/index/view/user/profile.html
  26. 1 1
      application/index/view/user/register.html
  27. 3 0
      extend/fast/Date.php
  28. 1 1
      public/assets/js/backend.js
  29. 6 4
      public/assets/js/backend/category.js
  30. 0 17
      public/assets/js/backend/dashboard.js
  31. 1 1
      public/assets/js/frontend.js
  32. 27 11
      public/assets/js/require-backend.min.js
  33. 13 3
      public/assets/js/require-form.js
  34. 1 1
      public/assets/js/require-frontend.min.js
  35. 9 3
      public/assets/js/require-table.js
  36. 4 4
      public/assets/js/require-upload.js

+ 33 - 12
application/admin/command/Crud.php

@@ -59,6 +59,11 @@ class Crud extends Command
     protected $citySuffix = ['city'];
 
     /**
+     * JSON后缀
+     */
+    protected $jsonSuffix = ['json'];
+
+    /**
      * Selectpage对应的后缀
      */
     protected $selectpageSuffix = ['_id', '_ids'];
@@ -167,6 +172,7 @@ class Crud extends Command
             ->addOption('intdatesuffix', null, Option::VALUE_OPTIONAL | Option::VALUE_IS_ARRAY, 'automatically generate date component with suffix', null)
             ->addOption('switchsuffix', null, Option::VALUE_OPTIONAL | Option::VALUE_IS_ARRAY, 'automatically generate switch component with suffix', null)
             ->addOption('citysuffix', null, Option::VALUE_OPTIONAL | Option::VALUE_IS_ARRAY, 'automatically generate citypicker component with suffix', null)
+            ->addOption('jsonsuffix', null, Option::VALUE_OPTIONAL | Option::VALUE_IS_ARRAY, 'automatically generate fieldlist 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)
@@ -228,6 +234,8 @@ class Crud extends Command
         $switchsuffix = $input->getOption('switchsuffix');
         //城市后缀
         $citysuffix = $input->getOption('citysuffix');
+        //JSON配置后缀
+        $jsonsuffix = $input->getOption('jsonsuffix');
         //selectpage后缀
         $selectpagesuffix = $input->getOption('selectpagesuffix');
         //selectpage多选后缀
@@ -261,6 +269,9 @@ class Crud extends Command
         if ($citysuffix) {
             $this->citySuffix = $citysuffix;
         }
+        if ($jsonsuffix) {
+            $this->jsonSuffix = $jsonsuffix;
+        }
         if ($selectpagesuffix) {
             $this->selectpageSuffix = $selectpagesuffix;
         }
@@ -581,7 +592,7 @@ class Crud extends Command
                     $cssClassArr = ['form-control'];
                     $fieldName = "row[{$field}]";
                     $defaultValue = $v['COLUMN_DEFAULT'];
-                    $editValue = "{\$row.{$field}}";
+                    $editValue = "{\$row.{$field}|htmlentities}";
                     // 如果默认值非null,则是一个必选项
                     if ($v['IS_NULLABLE'] == 'NO') {
                         $attrArr['data-rule'] = 'required';
@@ -688,6 +699,12 @@ class Crud extends Command
                         $attrArr['data-toggle'] = "city-picker";
                         $formAddElement = sprintf("<div class='control-relative'>%s</div>", Form::input('text', $fieldName, $defaultValue, $attrArr));
                         $formEditElement = sprintf("<div class='control-relative'>%s</div>", Form::input('text', $fieldName, $editValue, $attrArr));
+                    } elseif ($inputType == 'fieldlist') {
+                        $itemArr = $this->getItemArray($itemArr, $field, $v['COLUMN_COMMENT']);
+                        $itemKey = isset($itemArr['key']) ? ucfirst($itemArr['key']) : 'Key';
+                        $itemValue = isset($itemArr['value']) ? ucfirst($itemArr['value']) : 'Value';
+                        $formAddElement = $this->getReplacedStub('html/' . $inputType, ['field' => $field, 'fieldName' => $fieldName, 'itemKey' => $itemKey, 'itemValue' => $itemValue, 'fieldValue' => $defaultValue]);
+                        $formEditElement = $this->getReplacedStub('html/' . $inputType, ['field' => $field, 'fieldName' => $fieldName, 'itemKey' => $itemKey, 'itemValue' => $itemValue, 'fieldValue' => $editValue]);
                     } else {
                         $search = $replace = '';
                         //特殊字段为关联搜索
@@ -753,7 +770,7 @@ class Crud extends Command
                 }
 
                 //过滤text类型字段
-                if ($v['DATA_TYPE'] != 'text') {
+                if ($v['DATA_TYPE'] != 'text' && $inputType != 'fieldlist') {
                     //主键
                     if ($v['COLUMN_KEY'] == 'PRI' && !$priDefined) {
                         $priDefined = true;
@@ -768,7 +785,7 @@ class Crud extends Command
                         $javascriptList[] = $this->getJsColumn($field, $v['DATA_TYPE'], $inputType && in_array($inputType, ['select', 'checkbox', 'radio']) ? '_text' : '', $itemArr);
                     }
                     if ($this->headingFilterField && $this->headingFilterField == $field && $itemArr) {
-                        $headingHtml = $this->getReplacedStub('html/heading-html', ['field' => $field]);
+                        $headingHtml = $this->getReplacedStub('html/heading-html', ['field' => $field, 'fieldName' => Loader::parseName($field, 1, false)]);
                     }
                     //排序方式,如果有指定排序字段,否则按主键排序
                     $order = $field == $this->sortField ? $this->sortField : $order;
@@ -1081,9 +1098,9 @@ EOD;
     /**
      * 获取已解析相关信息
      * @param string $module 模块名称
-     * @param string $name 自定义名称
-     * @param string $table 数据表名
-     * @param string $type 解析类型,本例中为controller、model、validate
+     * @param string $name   自定义名称
+     * @param string $table  数据表名
+     * @param string $type   解析类型,本例中为controller、model、validate
      * @return array
      */
     protected function getParseNameData($module, $name, $table, $type)
@@ -1113,7 +1130,7 @@ EOD;
     /**
      * 写入到文件
      * @param string $name
-     * @param array $data
+     * @param array  $data
      * @param string $pathname
      * @return mixed
      */
@@ -1134,7 +1151,7 @@ EOD;
     /**
      * 获取替换后的数据
      * @param string $name
-     * @param array $data
+     * @param array  $data
      * @return string
      */
     protected function getReplacedStub($name, $data)
@@ -1199,7 +1216,7 @@ EOD;
 
     /**
      * 读取数据和语言数组列表
-     * @param array $arr
+     * @param array   $arr
      * @param boolean $withTpl
      * @return array
      */
@@ -1314,13 +1331,17 @@ EOD;
         if ($this->isMatchSuffix($fieldsName, $this->citySuffix) && ($v['DATA_TYPE'] == 'varchar' || $v['DATA_TYPE'] == 'char')) {
             $inputType = "citypicker";
         }
+        // 指定后缀结尾JSON配置
+        if ($this->isMatchSuffix($fieldsName, $this->jsonSuffix) && ($v['DATA_TYPE'] == 'varchar' || $v['DATA_TYPE'] == 'text')) {
+            $inputType = "fieldlist";
+        }
         return $inputType;
     }
 
     /**
      * 判断是否符合指定后缀
-     * @param string $field 字段名称
-     * @param mixed $suffixArr 后缀
+     * @param string $field     字段名称
+     * @param mixed  $suffixArr 后缀
      * @return boolean
      */
     protected function isMatchSuffix($field, $suffixArr)
@@ -1387,7 +1408,7 @@ EOD;
      * @param string $field
      * @param string $datatype
      * @param string $extend
-     * @param array $itemArr
+     * @param array  $itemArr
      * @return string
      */
     protected function getJsColumn($field, $datatype = '', $extend = '', $itemArr = [])

+ 10 - 0
application/admin/command/Crud/stubs/html/fieldlist.stub

@@ -0,0 +1,10 @@
+
+            <dl class="fieldlist" data-name="{%fieldName%}">
+                <dd>
+                    <ins>{:__('{%itemKey%}')}</ins>
+                    <ins>{:__('{%itemValue%}')}</ins>
+                </dd>
+                <dd><a href="javascript:;" class="btn btn-sm btn-success btn-append"><i class="fa fa-plus"></i> {:__('Append')}</a></dd>
+                <textarea name="{%fieldName%}" class="form-control hide" cols="30" rows="5">{%fieldValue%}</textarea>
+            </dl>
+

+ 1 - 1
application/admin/command/Crud/stubs/html/heading-html.stub

@@ -3,7 +3,7 @@
         {:build_heading(null,FALSE)}
         <ul class="nav nav-tabs" data-field="{%field%}">
             <li class="active"><a href="#t-all" data-value="" data-toggle="tab">{:__('All')}</a></li>
-            {foreach name="{%field%}List" item="vo"}
+            {foreach name="{%fieldName%}List" item="vo"}
             <li><a href="#t-{$key}" data-value="{$key}" data-toggle="tab">{$vo}</a></li>
             {/foreach}
         </ul>

+ 4 - 3
application/admin/command/Install/fastadmin.sql

@@ -162,7 +162,7 @@ CREATE TABLE `fa_auth_rule` (
 BEGIN;
 INSERT INTO `fa_auth_rule` VALUES (1, 'file', 0, 'dashboard', 'Dashboard', 'fa fa-dashboard', '', 'Dashboard tips', 1, 1497429920, 1497429920, 143, 'normal');
 INSERT INTO `fa_auth_rule` VALUES (2, 'file', 0, 'general', 'General', 'fa fa-cogs', '', '', 1, 1497429920, 1497430169, 137, 'normal');
-INSERT INTO `fa_auth_rule` VALUES (3, 'file', 0, 'category', 'Category', 'fa fa-list', '', 'Category tips', 1, 1497429920, 1497429920, 119, 'normal');
+INSERT INTO `fa_auth_rule` VALUES (3, 'file', 0, 'category', 'Category', 'fa fa-leaf', '', 'Category tips', 1, 1497429920, 1497429920, 119, 'normal');
 INSERT INTO `fa_auth_rule` VALUES (4, 'file', 0, 'addon', 'Addon', 'fa fa-rocket', '', 'Addon tips', 1, 1502035509, 1502035509, 0, 'normal');
 INSERT INTO `fa_auth_rule` VALUES (5, 'file', 0, 'auth', 'Auth', 'fa fa-group', '', '', 1, 1497429920, 1497430092, 99, 'normal');
 INSERT INTO `fa_auth_rule` VALUES (6, 'file', 2, 'general/config', 'Config', 'fa fa-cog', '', 'Config tips', 1, 1497429920, 1497430683, 60, 'normal');
@@ -313,7 +313,7 @@ CREATE TABLE `fa_config` (
 -- ----------------------------
 BEGIN;
 INSERT INTO `fa_config` VALUES (1, 'name', 'basic', 'Site name', '请填写站点名称', 'string', 'FastAdmin', '', 'required', '');
-INSERT INTO `fa_config` VALUES (2, 'beian', 'basic', 'Beian', '粤ICP备15054802号-4', 'string', '', '', '', '');
+INSERT INTO `fa_config` VALUES (2, 'beian', 'basic', 'Beian', '粤ICP备15000000号-1', 'string', '', '', '', '');
 INSERT INTO `fa_config` VALUES (3, 'cdnurl', 'basic', 'Cdn url', '如果静态资源使用第三方云储存请配置该值', 'string', '', '', '', '');
 INSERT INTO `fa_config` VALUES (4, 'version', 'basic', 'Version', '如果静态资源有变动请重新配置该值', 'string', '1.0.1', '', 'required', '');
 INSERT INTO `fa_config` VALUES (5, 'timezone', 'basic', 'Timezone', '', 'string', 'Asia/Shanghai', '', 'required', '');
@@ -382,6 +382,7 @@ CREATE TABLE `fa_test` (
   `keywords` varchar(100) NOT NULL DEFAULT '' COMMENT '关键字',
   `description` varchar(255) NOT NULL DEFAULT '' COMMENT '描述',
   `city` varchar(100) NOT NULL DEFAULT '' COMMENT '省市',
+  `json` varchar(255) DEFAULT NULL COMMENT '配置:key=名称,value=值',
   `price` float(10,2) unsigned NOT NULL DEFAULT '0.00' COMMENT '价格',
   `views` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '点击',
   `startdate` date DEFAULT NULL COMMENT '开始日期',
@@ -403,7 +404,7 @@ CREATE TABLE `fa_test` (
 -- Records of fa_test
 -- ----------------------------
 BEGIN;
-INSERT INTO `fa_test` VALUES (1, 0, 12, '12,13', 'monday', 'hot,index', 'male', 'music,reading', '我是一篇测试文章', '<p>我是测试内容</p>', '/assets/img/avatar.png', '/assets/img/avatar.png,/assets/img/qrcode.png', '/assets/img/avatar.png', '关键字', '描述', '广西壮族自治区/百色市/平果县', 0.00, 0, '2017-07-10', '2017-07-10 18:24:45', 2017, '18:24:45', 1499682285, 1499682526, 1499682526, NULL, 0, 1, 'normal', '1');
+INSERT INTO `fa_test` VALUES (1, 0, 12, '12,13', 'monday', 'hot,index', 'male', 'music,reading', '我是一篇测试文章', '<p>我是测试内容</p>', '/assets/img/avatar.png', '/assets/img/avatar.png,/assets/img/qrcode.png', '/assets/img/avatar.png', '关键字', '描述', '广西壮族自治区/百色市/平果县', '{\"a\":\"1\",\"b\":\"2\"}', 0.00, 0, '2017-07-10', '2017-07-10 18:24:45', 2017, '18:24:45', 1499682285, 1499682526, 1499682526, NULL, 0, 1, 'normal', '1');
 COMMIT;
 
 -- ----------------------------

+ 3 - 1
application/admin/controller/Addon.php

@@ -13,7 +13,7 @@ use think\Exception;
 /**
  * 插件管理
  *
- * @icon fa fa-circle-o
+ * @icon   fa fa-cube
  * @remark 可在线安装、卸载、禁用、启用插件,同时支持添加本地插件。FastAdmin已上线插件商店 ,你可以发布你的免费或付费插件:<a href="https://www.fastadmin.net/store.html" target="_blank">https://www.fastadmin.net/store.html</a>
  */
 class Addon extends Backend
@@ -34,6 +34,7 @@ class Addon extends Backend
         foreach ($addons as $k => &$v) {
             $config = get_addon_config($v['name']);
             $v['config'] = $config ? 1 : 0;
+            $v['url'] = str_replace($this->request->server('SCRIPT_NAME'), '', $v['url']);
         }
         $this->assignconfig(['addons' => $addons]);
         return $this->view->fetch();
@@ -320,6 +321,7 @@ class Addon extends Backend
                 $v['releaselist'] = [];
             }
             $v['url'] = addon_url($v['name']);
+            $v['url'] = str_replace($this->request->server('SCRIPT_NAME'), '', $v['url']);
             $v['createtime'] = filemtime(ADDON_PATH . $v['name']);
             if ($filter && isset($filter['category_id']) && is_numeric($filter['category_id']) && $filter['category_id'] != $v['category_id']) {
                 continue;

+ 2 - 1
application/admin/controller/Category.php

@@ -25,7 +25,6 @@ class Category extends Backend
     public function _initialize()
     {
         parent::_initialize();
-        $this->request->filter(['strip_tags']);
         $this->model = model('app\common\model\Category');
 
         $tree = Tree::instance();
@@ -47,6 +46,8 @@ class Category extends Backend
      */
     public function index()
     {
+        //设置过滤方法
+        $this->request->filter(['strip_tags']);
         if ($this->request->isAjax()) {
             $search = $this->request->request("search");
             $type = $this->request->request("type");

+ 12 - 15
application/admin/controller/user/User.php

@@ -33,27 +33,24 @@ class User extends Backend
     {
         //设置过滤方法
         $this->request->filter(['strip_tags']);
-        if ($this->request->isAjax())
-        {
+        if ($this->request->isAjax()) {
             //如果发送的来源是Selectpage,则转发到Selectpage
-            if ($this->request->request('keyField'))
-            {
+            if ($this->request->request('keyField')) {
                 return $this->selectpage();
             }
             list($where, $sort, $order, $offset, $limit) = $this->buildparams();
             $total = $this->model
-                    ->with('group')
-                    ->where($where)
-                    ->order($sort, $order)
-                    ->count();
+                ->with('group')
+                ->where($where)
+                ->order($sort, $order)
+                ->count();
             $list = $this->model
-                    ->with('group')
-                    ->where($where)
-                    ->order($sort, $order)
-                    ->limit($offset, $limit)
-                    ->select();
-            foreach ($list as $k => $v)
-            {
+                ->with('group')
+                ->where($where)
+                ->order($sort, $order)
+                ->limit($offset, $limit)
+                ->select();
+            foreach ($list as $k => $v) {
                 $v->hidden(['password', 'salt']);
             }
             $result = array("total" => $total, "rows" => $list);

+ 4 - 2
application/admin/lang/zh-cn/dashboard.php

@@ -31,8 +31,9 @@ return [
     'Recent discussion'       => '最新发贴',
     'Server info'             => '服务器信息',
     'PHP version'             => 'PHP版本',
-    'Fastadmin version'       => 'FastAdmin版本',
-    'Fastadmin addon version' => 'FastAdmin插件版本',
+    'Fastadmin version'       => '主框架版本',
+    'Fastadmin addon version' => '插件版本',
+    'Thinkphp version'        => 'ThinkPHP版本',
     'Sapi name'               => '运行方式',
     'Debug mode'              => '调试模式',
     'Software'                => '环境信息',
@@ -42,5 +43,6 @@ return [
     'Cdn url'                 => '静态资源CDN',
     'Timezone'                => '时区',
     'Language'                => '语言',
+    'View more'               => '查看更多',
     'Security tips'           => '<i class="fa fa-warning"></i> 安全提示:你正在使用默认的后台登录入口,为了你的网站安全,建议你修改后台登录入口,<a href="https://forum.fastadmin.net/thread/7640" target="_blank">点击查看修改方法</a>',
 ];

+ 8 - 9
application/admin/view/addon/config.html

@@ -21,10 +21,10 @@
                     <div class="col-sm-8 col-xs-12">
                         {switch $item.type}
                         {case string}
-                        <input {$item.extend} type="text" name="row[{$item.name}]" value="{$item.value}" class="form-control" data-rule="{$item.rule}" data-tip="{$item.tip}"/>
+                        <input {$item.extend} type="text" name="row[{$item.name}]" value="{$item.value|htmlentities}" class="form-control" data-rule="{$item.rule}" data-tip="{$item.tip}"/>
                         {/case}
                         {case text}
-                        <textarea {$item.extend} name="row[{$item.name}]" class="form-control" data-rule="{$item.rule}" rows="5" data-tip="{$item.tip}">{$item.value}</textarea>
+                        <textarea {$item.extend} name="row[{$item.name}]" class="form-control" data-rule="{$item.rule}" rows="5" data-tip="{$item.tip}">{$item.value|htmlentities}</textarea>
                         {/case}
                         {case array}
                         <dl class="fieldlist" data-name="row[{$item.name}]">
@@ -33,14 +33,14 @@
                                 <ins>{:__('Array value')}</ins>
                             </dd>
                             <dd><a href="javascript:;" class="btn btn-sm btn-success btn-append"><i class="fa fa-plus"></i> {:__('Append')}</a></dd>
-                            <textarea name="row[{$item.name}]" cols="30" rows="5" class="hide">{$item.value|json_encode}</textarea>
+                            <textarea name="row[{$item.name}]" cols="30" rows="5" class="hide">{$item.value|json_encode|htmlentities}</textarea>
                         </dl>
                         {/case}
                         {case datetime}
-                        <input {$item.extend} type="text" name="row[{$item.name}]" value="{$item.value}" class="form-control datetimepicker" data-tip="{$item.tip}" data-rule="{$item.rule}"/>
+                        <input {$item.extend} type="text" name="row[{$item.name}]" value="{$item.value|htmlentities}" class="form-control datetimepicker" data-tip="{$item.tip}" data-rule="{$item.rule}"/>
                         {/case}
                         {case number}
-                        <input {$item.extend} type="number" name="row[{$item.name}]" value="{$item.value}" class="form-control" data-tip="{$item.tip}" data-rule="{$item.rule}"/>
+                        <input {$item.extend} type="number" name="row[{$item.name}]" value="{$item.value|htmlentities}" class="form-control" data-tip="{$item.tip}" data-rule="{$item.rule}"/>
                         {/case}
                         {case checkbox}
                         {foreach name="item.content" item="vo"}
@@ -56,15 +56,14 @@
                         {case value="selects"}
                         <select {$item.extend} name="row[{$item.name}]{$item.type=='selects'?'[]':''}" class="form-control selectpicker" data-tip="{$item.tip}" {$item.type=='selects'?'multiple':''}>
                             {foreach name="item.content" item="vo"}
-                            <option value="{$key}" {in name="key" value="$item.value" }selected{
-                            /in}>{$vo}</option>
+                            <option value="{$key}" {in name="key" value="$item.value" }selected{/in}>{$vo}</option>
                             {/foreach}
                         </select>
                         {/case}
                         {case value="image" break="0"}{/case}
                         {case value="images"}
                         <div class="form-inline">
-                            <input id="c-{$item.name}" class="form-control" size="37" name="row[{$item.name}]" type="text" value="{$item.value}" data-tip="{$item.tip}">
+                            <input id="c-{$item.name}" class="form-control" size="35" name="row[{$item.name}]" type="text" value="{$item.value|htmlentities}" data-tip="{$item.tip}">
                             <span><button type="button" id="plupload-{$item.name}" class="btn btn-danger plupload" data-input-id="c-{$item.name}" data-mimetype="image/*" data-multiple="{$item.type=='image'?'false':'true'}" data-preview-id="p-{$item.name}"><i class="fa fa-upload"></i> {:__('Upload')}</button></span>
                             <span><button type="button" id="fachoose-{$item.name}" class="btn btn-primary fachoose" data-input-id="c-{$item.name}" data-mimetype="image/*" data-multiple="{$item.type=='image'?'false':'true'}"><i class="fa fa-list"></i> {:__('Choose')}</button></span>
                             <ul class="row list-inline plupload-preview" id="p-{$item.name}"></ul>
@@ -73,7 +72,7 @@
                         {case value="file" break="0"}{/case}
                         {case value="files"}
                         <div class="form-inline">
-                            <input id="c-{$item.name}" class="form-control" size="37" name="row[{$item.name}]" type="text" value="{$item.value}" data-tip="{$item.tip}">
+                            <input id="c-{$item.name}" class="form-control" size="35" name="row[{$item.name}]" type="text" value="{$item.value|htmlentities}" data-tip="{$item.tip}">
                             <span><button type="button" id="plupload-{$item.name}" class="btn btn-danger plupload" data-input-id="c-{$item.name}" data-multiple="{$item.type=='file'?'false':'true'}"><i class="fa fa-upload"></i> {:__('Upload')}</button></span>
                             <span><button type="button" id="fachoose-{$item.name}" class="btn btn-primary fachoose" data-input-id="c-{$item.name}" data-multiple="{$item.type=='file'?'false':'true'}"><i class="fa fa-list"></i> {:__('Choose')}</button></span>
                         </div>

+ 3 - 3
application/admin/view/auth/admin/edit.html

@@ -8,19 +8,19 @@
     <div class="form-group">
         <label for="username" class="control-label col-xs-12 col-sm-2">{:__('Username')}:</label>
         <div class="col-xs-12 col-sm-8">
-            <input type="text" class="form-control" id="username" name="row[username]" value="{$row.username}" data-rule="required;username" />
+            <input type="text" class="form-control" id="username" name="row[username]" value="{$row.username|htmlentities}" data-rule="required;username" />
         </div>
     </div>
     <div class="form-group">
         <label for="email" class="control-label col-xs-12 col-sm-2">{:__('Email')}:</label>
         <div class="col-xs-12 col-sm-8">
-            <input type="email" class="form-control" id="email" name="row[email]" value="{$row.email}" data-rule="required;email" />
+            <input type="email" class="form-control" id="email" name="row[email]" value="{$row.email|htmlentities}" data-rule="required;email" />
         </div>
     </div>
     <div class="form-group">
         <label for="nickname" class="control-label col-xs-12 col-sm-2">{:__('Nickname')}:</label>
         <div class="col-xs-12 col-sm-8">
-            <input type="text" class="form-control" id="nickname" name="row[nickname]" autocomplete="off" value="{$row.nickname}" data-rule="required" />
+            <input type="text" class="form-control" id="nickname" name="row[nickname]" autocomplete="off" value="{$row.nickname|htmlentities}" data-rule="required" />
         </div>
     </div>
     <div class="form-group">

+ 1 - 1
application/admin/view/auth/group/edit.html

@@ -9,7 +9,7 @@
     <div class="form-group">
         <label 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]" value="{$row.name}" data-rule="required" />
+            <input type="text" class="form-control" id="name" name="row[name]" value="{$row.name|htmlentities}" data-rule="required" />
         </div>
     </div>
     <div class="form-group">

+ 4 - 4
application/admin/view/auth/rule/edit.html

@@ -14,13 +14,13 @@
     <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]" data-placeholder-node="{:__('Node tips')}" data-placeholder-menu="{:__('Menu tips')}" 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|htmlentities}" data-rule="required" />
         </div>
     </div>
     <div class="form-group">
         <label class="control-label col-xs-12 col-sm-2">{:__('Title')}:</label>
         <div class="col-xs-12 col-sm-8">
-            <input type="text" class="form-control" id="title" name="row[title]" value="{$row.title}" data-rule="required" />
+            <input type="text" class="form-control" id="title" name="row[title]" value="{$row.title|htmlentities}" data-rule="required" />
         </div>
     </div>
     <div class="form-group">
@@ -41,13 +41,13 @@
     <div class="form-group">
         <label for="remark" class="control-label col-xs-12 col-sm-2">{:__('Condition')}:</label>
         <div class="col-xs-12 col-sm-8">
-            <textarea class="form-control" id="condition" name="row[condition]">{$row.condition}</textarea>
+            <textarea class="form-control" id="condition" name="row[condition]">{$row.condition|htmlentities}</textarea>
         </div>
     </div>
     <div class="form-group">
         <label for="remark" class="control-label col-xs-12 col-sm-2">{:__('Remark')}:</label>
         <div class="col-xs-12 col-sm-8">
-            <textarea class="form-control" id="remark" name="row[remark]">{$row.remark}</textarea>
+            <textarea class="form-control" id="remark" name="row[remark]">{$row.remark|htmlentities}</textarea>
         </div>
     </div>
     <div class="form-group">

+ 1 - 1
application/admin/view/category/add.html

@@ -56,7 +56,7 @@
         <label for="c-image" class="control-label col-xs-12 col-sm-2">{:__('Image')}:</label>
         <div class="col-xs-12 col-sm-8">
             <div class="input-group">
-                <input id="c-image" class="form-control" size="50" name="row[image]" type="text" value="">
+                <input id="c-image" class="form-control" size="35" name="row[image]" type="text" value="">
                 <div class="input-group-addon no-border no-padding">
                     <span><button type="button" id="plupload-image" class="btn btn-danger plupload" data-input-id="c-image" data-mimetype="image/gif,image/jpeg,image/png,image/jpg,image/bmp" data-multiple="false" data-preview-id="p-image"><i class="fa fa-upload"></i> {:__('Upload')}</button></span>
                     <span><button type="button" id="fachoose-image" class="btn btn-primary fachoose" data-input-id="c-image" data-mimetype="image/*" data-multiple="false"><i class="fa fa-list"></i> {:__('Choose')}</button></span>

+ 5 - 5
application/admin/view/category/edit.html

@@ -27,13 +27,13 @@
     <div class="form-group">
         <label for="c-name" class="control-label col-xs-12 col-sm-2">{:__('Name')}:</label>
         <div class="col-xs-12 col-sm-8">
-            <input id="c-name" data-rule="required" class="form-control" name="row[name]" type="text" value="{$row.name}">
+            <input id="c-name" data-rule="required" class="form-control" name="row[name]" type="text" value="{$row.name|htmlentities}">
         </div>
     </div>
     <div class="form-group">
         <label for="c-nickname" class="control-label col-xs-12 col-sm-2">{:__('Nickname')}:</label>
         <div class="col-xs-12 col-sm-8">
-            <input id="c-nickname" data-rule="required" class="form-control" name="row[nickname]" type="text" value="{$row.nickname}">
+            <input id="c-nickname" data-rule="required" class="form-control" name="row[nickname]" type="text" value="{$row.nickname|htmlentities}">
         </div>
     </div>
     <div class="form-group">
@@ -52,7 +52,7 @@
         <label for="c-image" class="control-label col-xs-12 col-sm-2">{:__('Image')}:</label>
         <div class="col-xs-12 col-sm-8">
             <div class="input-group">
-                <input id="c-image" class="form-control" size="50" name="row[image]" type="text" value="{$row.image}">
+                <input id="c-image" class="form-control" size="35" name="row[image]" type="text" value="{$row.image}">
                 <div class="input-group-addon no-border no-padding">
                     <span><button type="button" id="plupload-image" class="btn btn-danger plupload" data-input-id="c-image" data-mimetype="image/gif,image/jpeg,image/png,image/jpg,image/bmp" data-multiple="false" data-preview-id="p-image"><i class="fa fa-upload"></i> {:__('Upload')}</button></span>
                     <span><button type="button" id="fachoose-image" class="btn btn-primary fachoose" data-input-id="c-image" data-mimetype="image/*" data-multiple="false"><i class="fa fa-list"></i> {:__('Choose')}</button></span>
@@ -65,13 +65,13 @@
     <div class="form-group">
         <label for="c-keywords" class="control-label col-xs-12 col-sm-2">{:__('Keywords')}:</label>
         <div class="col-xs-12 col-sm-8">
-            <input id="c-keywords" class="form-control" name="row[keywords]" type="text" value="{$row.keywords}">
+            <input id="c-keywords" class="form-control" name="row[keywords]" type="text" value="{$row.keywords|htmlentities}">
         </div>
     </div>
     <div class="form-group">
         <label for="c-description" class="control-label col-xs-12 col-sm-2">{:__('Description')}:</label>
         <div class="col-xs-12 col-sm-8">
-            <textarea id="c-description" class="form-control" name="row[description]">{$row.description}</textarea>
+            <textarea id="c-description" class="form-control" name="row[description]">{$row.description|htmlentities}</textarea>
         </div>
     </div>
     <div class="form-group">

+ 191 - 150
application/admin/view/dashboard/index.html

@@ -1,53 +1,62 @@
 <style type="text/css">
     .sm-st {
-        background:#fff;
-        padding:20px;
-        -webkit-border-radius:3px;
-        -moz-border-radius:3px;
-        border-radius:3px;
-        margin-bottom:20px;
-        -webkit-box-shadow: 0 1px 0px rgba(0,0,0,0.05);
-        box-shadow: 0 1px 0px rgba(0,0,0,0.05);
+        background: #fff;
+        padding: 20px;
+        -webkit-border-radius: 3px;
+        -moz-border-radius: 3px;
+        border-radius: 3px;
+        margin-bottom: 20px;
+        -webkit-box-shadow: 0 1px 0px rgba(0, 0, 0, 0.05);
+        box-shadow: 0 1px 0px rgba(0, 0, 0, 0.05);
     }
+
     .sm-st-icon {
-        width:60px;
-        height:60px;
-        display:inline-block;
-        line-height:60px;
-        text-align:center;
-        font-size:30px;
-        background:#eee;
-        -webkit-border-radius:5px;
-        -moz-border-radius:5px;
-        border-radius:5px;
-        float:left;
-        margin-right:10px;
-        color:#fff;
+        width: 60px;
+        height: 60px;
+        display: inline-block;
+        line-height: 60px;
+        text-align: center;
+        font-size: 30px;
+        background: #eee;
+        -webkit-border-radius: 5px;
+        -moz-border-radius: 5px;
+        border-radius: 5px;
+        float: left;
+        margin-right: 10px;
+        color: #fff;
     }
+
     .sm-st-info {
-        font-size:12px;
-        padding-top:2px;
+        font-size: 12px;
+        padding-top: 2px;
     }
+
     .sm-st-info span {
-        display:block;
-        font-size:24px;
-        font-weight:600;
+        display: block;
+        font-size: 24px;
+        font-weight: 600;
     }
+
     .orange {
-        background:#fa8564 !important;
+        background: #fa8564 !important;
     }
+
     .tar {
-        background:#45cf95 !important;
+        background: #45cf95 !important;
     }
+
     .sm-st .green {
-        background:#86ba41 !important;
+        background: #86ba41 !important;
     }
+
     .pink {
-        background:#AC75F0 !important;
+        background: #AC75F0 !important;
     }
+
     .yellow-b {
         background: #fdd752 !important;
     }
+
     .stat-elem {
 
         background-color: #fff;
@@ -58,12 +67,12 @@
 
     .stat-info {
         text-align: center;
-        background-color:#fff;
+        background-color: #fff;
         border-radius: 5px;
         margin-top: -5px;
         padding: 8px;
-        -webkit-box-shadow: 0 1px 0px rgba(0,0,0,0.05);
-        box-shadow: 0 1px 0px rgba(0,0,0,0.05);
+        -webkit-box-shadow: 0 1px 0px rgba(0, 0, 0, 0.05);
+        box-shadow: 0 1px 0px rgba(0, 0, 0, 0.05);
         font-style: italic;
     }
 
@@ -75,12 +84,15 @@
     .st-red {
         background-color: #F05050;
     }
+
     .st-green {
         background-color: #27C24C;
     }
+
     .st-violet {
         background-color: #7266ba;
     }
+
     .st-blue {
         background-color: #23b7e5;
     }
@@ -92,7 +104,7 @@
         text-align: center;
         vertical-align: middle;
         width: 50px;
-        float:left;
+        float: left;
     }
 
     .stat {
@@ -100,26 +112,42 @@
         overflow: hidden;
         text-overflow: ellipsis;
         display: inline-block;
-        margin-right: 10px; }
+        margin-right: 10px;
+    }
+
     .stat .value {
         font-size: 20px;
         line-height: 24px;
         overflow: hidden;
         text-overflow: ellipsis;
-        font-weight: 500; }
+        font-weight: 500;
+    }
+
     .stat .name {
         overflow: hidden;
-        text-overflow: ellipsis; }
+        text-overflow: ellipsis;
+    }
+
     .stat.lg .value {
         font-size: 26px;
-        line-height: 28px; }
+        line-height: 28px;
+    }
+
     .stat.lg .name {
-        font-size: 16px; }
-    .stat-col .progress {height:2px;}
-    .stat-col .progress-bar {line-height:2px;height:2px;}
+        font-size: 16px;
+    }
+
+    .stat-col .progress {
+        height: 2px;
+    }
+
+    .stat-col .progress-bar {
+        line-height: 2px;
+        height: 2px;
+    }
 
     .item {
-        padding:30px 0;
+        padding: 30px 0;
     }
 </style>
 {if preg_match('/\/admin\/|admin\.php|admin_d75KABNWt\.php/i', url())}
@@ -187,60 +215,60 @@
                             <div class="card-block">
                                 <div class="row row-sm stats-container">
                                     <div class="col-xs-6 stat-col">
-                                        <div class="stat-icon"> <i class="fa fa-rocket"></i> </div>
+                                        <div class="stat-icon"><i class="fa fa-rocket"></i></div>
                                         <div class="stat">
-                                            <div class="value"> {$todayusersignup} </div>
-                                            <div class="name"> {:__('Today user signup')} </div>
+                                            <div class="value"> {$todayusersignup}</div>
+                                            <div class="name"> {:__('Today user signup')}</div>
                                         </div>
                                         <div class="progress">
                                             <div class="progress-bar progress-bar-success" style="width: 30%"></div>
                                         </div>
                                     </div>
                                     <div class="col-xs-6 stat-col">
-                                        <div class="stat-icon"> <i class="fa fa-shopping-cart"></i> </div>
+                                        <div class="stat-icon"><i class="fa fa-shopping-cart"></i></div>
                                         <div class="stat">
-                                            <div class="value"> {$todayuserlogin} </div>
-                                            <div class="name"> {:__('Today user login')} </div>
+                                            <div class="value"> {$todayuserlogin}</div>
+                                            <div class="name"> {:__('Today user login')}</div>
                                         </div>
                                         <div class="progress">
                                             <div class="progress-bar progress-bar-success" style="width: 25%"></div>
                                         </div>
                                     </div>
                                     <div class="col-xs-6  stat-col">
-                                        <div class="stat-icon"> <i class="fa fa-line-chart"></i> </div>
+                                        <div class="stat-icon"><i class="fa fa-line-chart"></i></div>
                                         <div class="stat">
-                                            <div class="value"> {$todayorder} </div>
-                                            <div class="name"> {:__('Today order')} </div>
+                                            <div class="value"> {$todayorder}</div>
+                                            <div class="name"> {:__('Today order')}</div>
                                         </div>
                                         <div class="progress">
                                             <div class="progress-bar progress-bar-success" style="width: 25%"></div>
                                         </div>
                                     </div>
                                     <div class="col-xs-6  stat-col">
-                                        <div class="stat-icon"> <i class="fa fa-users"></i> </div>
+                                        <div class="stat-icon"><i class="fa fa-users"></i></div>
                                         <div class="stat">
-                                            <div class="value"> {$unsettleorder} </div>
-                                            <div class="name"> {:__('Unsettle order')} </div>
+                                            <div class="value"> {$unsettleorder}</div>
+                                            <div class="name"> {:__('Unsettle order')}</div>
                                         </div>
                                         <div class="progress">
                                             <div class="progress-bar progress-bar-success" style="width: 25%"></div>
                                         </div>
                                     </div>
                                     <div class="col-xs-6  stat-col">
-                                        <div class="stat-icon"> <i class="fa fa-list-alt"></i> </div>
+                                        <div class="stat-icon"><i class="fa fa-list-alt"></i></div>
                                         <div class="stat">
-                                            <div class="value"> {$sevendnu} </div>
-                                            <div class="name"> {:__('Seven dnu')} </div>
+                                            <div class="value"> {$sevendnu}</div>
+                                            <div class="name"> {:__('Seven dnu')}</div>
                                         </div>
                                         <div class="progress">
                                             <div class="progress-bar progress-bar-success" style="width: 25%"></div>
                                         </div>
                                     </div>
                                     <div class="col-xs-6 stat-col">
-                                        <div class="stat-icon"> <i class="fa fa-dollar"></i> </div>
+                                        <div class="stat-icon"><i class="fa fa-dollar"></i></div>
                                         <div class="stat">
-                                            <div class="value"> {$sevendau} </div>
-                                            <div class="name"> {:__('Seven dau')} </div>
+                                            <div class="value"> {$sevendau}</div>
+                                            <div class="name"> {:__('Seven dau')}</div>
                                         </div>
                                         <div class="progress">
                                             <div class="progress-bar progress-bar-success" style="width: 25%"></div>
@@ -299,11 +327,15 @@
                                     <div class="row">
                                         <div class="col-md-6">
                                             <h1 class="no-margins">1234</h1>
-                                            <div class="font-bold"><i class="fa fa-commenting"></i> <small>{:__('Comment count')}</small></div>
+                                            <div class="font-bold"><i class="fa fa-commenting"></i>
+                                                <small>{:__('Comment count')}</small>
+                                            </div>
                                         </div>
                                         <div class="col-md-6">
                                             <h1 class="no-margins">6754</h1>
-                                            <div class="font-bold"><i class="fa fa-heart"></i> <small>{:__('Like count')}</small></div>
+                                            <div class="font-bold"><i class="fa fa-heart"></i>
+                                                <small>{:__('Like count')}</small>
+                                            </div>
                                         </div>
                                     </div>
                                 </div>
@@ -322,11 +354,15 @@
                                     <div class="row">
                                         <div class="col-md-6">
                                             <h1 class="no-margins">5302</h1>
-                                            <div class="font-bold"><i class="fa fa-commenting"></i> <small>{:__('Comment count')}</small></div>
+                                            <div class="font-bold"><i class="fa fa-commenting"></i>
+                                                <small>{:__('Comment count')}</small>
+                                            </div>
                                         </div>
                                         <div class="col-md-6">
                                             <h1 class="no-margins">8205</h1>
-                                            <div class="font-bold"><i class="fa fa-user"></i> <small>{:__('Like count')}</small></div>
+                                            <div class="font-bold"><i class="fa fa-user"></i>
+                                                <small>{:__('Like count')}</small>
+                                            </div>
                                         </div>
                                     </div>
                                 </div>
@@ -335,85 +371,118 @@
                     </div>
                 </div>
 
-                <!--如果需要删除最新新闻和最新发贴,删除HTML后还需要删除dashboard.js中的代码-->
                 <div class="row">
                     <div class="col-lg-4">
                         <div class="box box-danger">
-                            <div class="box-header">
+                            <div class="box-header with-border">
                                 <h3 class="box-title">{:__('Recent news')}</h3>
+
                                 <div class="box-tools pull-right">
-                                    <a href="https://www.fastadmin.net" target="_blank" class="btn btn-box-tool">{:__('More')}</a>
                                 </div>
                             </div>
-                            <div class="box-body" id="news-list">
-                                
+                            <div class="box-body">
+                                <ul class="products-list product-list-in-box">
+                                    {for start="1" end="8"}
+                                    <li class="item">
+                                        <div class="product-img">
+                                            <img src="__CDN__/assets/img/avatar.png" style="height:40px;width:40px;">
+                                        </div>
+                                        <div class="product-info">
+                                            <a href="https://www.fastadmin.net" target="_blank" class="product-title">
+                                                FastAdmin
+                                                <span class="label label-{:$i%3===0?'warning':($i%2===0?'success':'info')} pull-right">开源免费</span>
+                                            </a>
+                                            <span class="product-description">
+                                              一款基于ThinkPHP5+Bootstrap的极速后台开发框架
+                                            </span>
+                                        </div>
+                                    </li>
+                                    {/for}
+                                </ul>
                             </div>
                         </div>
                     </div>
                     <div class="col-lg-4">
                         <div class="box box-success">
-                            <div class="box-header">
+                            <div class="box-header with-border">
                                 <h3 class="box-title">{:__('Recent discussion')}</h3>
+
                                 <div class="box-tools pull-right">
-                                    <a href="https://forum.fastadmin.net" class="btn btn-box-tool">{:__('More')}</a>
                                 </div>
                             </div>
-                            <div class="box-body" id="discussion-list">
-                                
+                            <div class="box-body">
+                                <ul class="nav nav-pills nav-stacked">
+                                    <li><a href="https://www.fastadmin.net" target="_blank">一款基于ThinkPHP5+Bootstrap的极速后台开发框架<span class="pull-right text-red"><i class="fa fa-angle-down"></i> 12%</span></a></li>
+                                    <li><a href="https://www.fastadmin.net" target="_blank">一键生成CRUD控制器模型和视图 <span class="pull-right text-green"><i class="fa fa-angle-up"></i> 4%</span></a></li>
+                                    <li><a href="https://www.fastadmin.net" target="_blank">一键压缩打包JS和CSS文件 <span class="pull-right text-red"><i class="fa fa-angle-down"></i> 3%</span></a></li>
+                                    <li><a href="https://www.fastadmin.net" target="_blank">一键生成控制器菜单和规则 <span class="pull-right text-green"><i class="fa fa-angle-up"></i> 8%</span></a></li>
+                                    <li><a href="https://www.fastadmin.net" target="_blank">一键生成API接口文档 <span class="pull-right text-yellow"><i class="fa fa-angle-left"></i> 0%</span></a></li>
+                                    <li><a href="https://www.fastadmin.net" target="_blank">强大的插件扩展功能,在线安装卸载升级插件 <span class="pull-right text-red"><i class="fa fa-angle-down"></i> 10%</span></a></li>
+                                    <li><a href="https://www.fastadmin.net" target="_blank">通用的会员模块和API模块 <span class="pull-right text-green"><i class="fa fa-angle-up"></i> 2%</span></a></li>
+                                    <li><a href="https://www.fastadmin.net" target="_blank">共用同一账号体系的Web端会员中心权限验证和API接口会员权限验证 <span class="pull-right text-red"><i class="fa fa-angle-down"></i> 6%</span></a></li>
+                                    <li><a href="https://www.fastadmin.net" target="_blank">二级域名部署支持,同时域名支持绑定到插件 <span class="pull-right text-yellow"><i class="fa fa-angle-left"></i> 0%</span></a></li>
+                                    <li><a href="https://www.fastadmin.net" target="_blank">多语言支持,服务端及客户端支持 <span class="pull-right text-yellow"><i class="fa fa-angle-left"></i> 0%</span></a></li>
+                                    <li><a href="https://www.fastadmin.net" target="_blank">基于Bootstrap开发,自适应手机、平板、PC <span class="pull-right text-green"><i class="fa fa-angle-up"></i> 4%</span></a></li>
+                                </ul>
                             </div>
                         </div>
                     </div>
                     <div class="col-lg-4">
                         <div class="box box-info">
                             <div class="box-header"><h3 class="box-title">{:__('Server info')}</h3></div>
-                            <div class="box-body">
+                            <div class="box-body" style="padding-top:0;">
                                 <table class="table table-striped">
                                     <tbody>
-                                        <tr>
-                                            <td width="140">{:__('FastAdmin version')}</td>
-                                            <td>{$Think.config.fastadmin.version} <a href="javascript:;" class="btn btn-xs btn-checkversion">检查最新版</a></td>
-                                        </tr>
-                                        <tr>
-                                            <td>{:__('FastAdmin addon version')}</td>
-                                            <td>{$addonversion}</td>
-                                        </tr>
-                                        <tr>
-                                            <td>{:__('Sapi name')}</td>
-                                            <td>{:php_sapi_name()}</td>
-                                        </tr>
-                                        <tr>
-                                            <td>{:__('Debug mode')}</td>
-                                            <td>{$Think.config.app_debug?__('Yes'):__('No')}</td>
-                                        </tr>
-                                        <tr>
-                                            <td>{:__('Software')}</td>
-                                            <td>{$Think.server.SERVER_SOFTWARE}</td>
-                                        </tr>
-                                        <tr>
-                                            <td>{:__('Upload mode')}</td>
-                                            <td>{$uploadmode}</td>
-                                        </tr>
-                                        <tr>
-                                            <td>{:__('Upload url')}</td>
-                                            <td>{$config.upload.uploadurl}</td>
-                                        </tr>
-                                        <tr>
-                                            <td>{:__('Upload Cdn url')}</td>
-                                            <td>{$config.upload.cdnurl}</td>
-                                        </tr>
-                                        <tr>
-                                            <td>{:__('Timezone')}</td>
-                                            <td>{:date_default_timezone_get()}</td>
-                                        </tr>
-                                        <tr>
-                                            <td>{:__('Cdn url')}</td>
-                                            <td>__CDN__</td>
-                                        </tr>
-                                        <tr>
-                                            <td>{:__('Language')}</td>
-                                            <td>{$config.language}</td>
-                                        </tr>
-                                    </tbody></table>
+                                    <tr>
+                                        <td width="140">{:__('FastAdmin version')}</td>
+                                        <td>{$Think.config.fastadmin.version} <a href="javascript:;" class="btn btn-xs btn-checkversion">检查最新版</a></td>
+                                    </tr>
+                                    <tr>
+                                        <td>{:__('FastAdmin addon version')}</td>
+                                        <td>{$addonversion}</td>
+                                    </tr>
+                                    <tr>
+                                        <td>{:__('Thinkphp version')}</td>
+                                        <td>{:THINK_VERSION}</td>
+                                    </tr>
+                                    <tr>
+                                        <td>{:__('Sapi name')}</td>
+                                        <td>{:php_sapi_name()}</td>
+                                    </tr>
+                                    <tr>
+                                        <td>{:__('Debug mode')}</td>
+                                        <td>{$Think.config.app_debug?__('Yes'):__('No')}</td>
+                                    </tr>
+                                    <tr>
+                                        <td>{:__('Software')}</td>
+                                        <td>{$Think.server.SERVER_SOFTWARE}</td>
+                                    </tr>
+                                    <tr>
+                                        <td>{:__('Upload mode')}</td>
+                                        <td>{$uploadmode}</td>
+                                    </tr>
+                                    <tr>
+                                        <td>{:__('Upload url')}</td>
+                                        <td>{$config.upload.uploadurl}</td>
+                                    </tr>
+                                    <tr>
+                                        <td>{:__('Upload Cdn url')}</td>
+                                        <td>{$config.upload.cdnurl}</td>
+                                    </tr>
+                                    <tr>
+                                        <td>{:__('Timezone')}</td>
+                                        <td>{:date_default_timezone_get()}</td>
+                                    </tr>
+                                    <tr>
+                                        <td>{:__('Cdn url')}</td>
+                                        <td>__CDN__</td>
+                                    </tr>
+                                    <tr>
+                                        <td>{:__('Language')}</td>
+                                        <td>{$config.language}</td>
+                                    </tr>
+                                    </tbody>
+                                </table>
                             </div>
                         </div>
                     </div>
@@ -429,38 +498,10 @@
         </div>
     </div>
 </div>
-<script id="newstpl" type="text/html">
-    <ul class="nav nav-stacked">
-        <%for(var i=0;i < news.length;i++){%>
-        <%var item=news[i];%>
-        <li>
-            <a href="<%=item.url%>" target="_blank">
-                <span class="text"><%=item.title%></span>
-            </a>
-        </li>
-        <%}%>
-    </ul>
-</script>
-<script id="discussiontpl" type="text/html">
-    <ul class="products-list product-list-in-box">
-        <%for(var i=0;i < news.length;i++){%>
-        <%var item=news[i];%>
-        <li class="item">
-            <div class="">
-                <a href="<%=item.url%>" target="_blank" class="product-title"><%=item.title%>
-                    <span class="label label-warning pull-right"><%=item.comments_count%></span></a>
-                <span class="product-description">
-                    <%=item.last_time%>
-                </span>
-            </div>
-        </li>
-        <%}%>
-    </ul>
-</script>
 <script>
     var Orderdata = {
-    column: {:json_encode(array_keys($paylist))},
-            paydata: {:json_encode(array_values($paylist))},
-            createdata: {:json_encode(array_values($createlist))},
+        column: {:json_encode(array_keys($paylist))},
+        paydata: {:json_encode(array_values($paylist))},
+        createdata: {:json_encode(array_values($createlist))},
     };
 </script>

+ 6 - 6
application/admin/view/general/config/index.html

@@ -52,13 +52,13 @@
                                             <div class="col-sm-8 col-xs-12">
                                                 {switch $item.type}
                                                 {case string}
-                                                <input {$item.extend} type="text" name="row[{$item.name}]" value="{$item.value}" class="form-control" data-rule="{$item.rule}" data-tip="{$item.tip}" />
+                                                <input {$item.extend} type="text" name="row[{$item.name}]" value="{$item.value|htmlentities}" class="form-control" data-rule="{$item.rule}" data-tip="{$item.tip}" />
                                                 {/case}
                                                 {case text}
-                                                <textarea {$item.extend} name="row[{$item.name}]" class="form-control" data-rule="{$item.rule}" rows="5" data-tip="{$item.tip}">{$item.value}</textarea>
+                                                <textarea {$item.extend} name="row[{$item.name}]" class="form-control" data-rule="{$item.rule}" rows="5" data-tip="{$item.tip}">{$item.value|htmlentities}</textarea>
                                                 {/case}
                                                 {case editor}
-                                                <textarea {$item.extend} name="row[{$item.name}]" id="editor-{$item.name}" class="form-control editor" data-rule="{$item.rule}" rows="5" data-tip="{$item.tip}">{$item.value}</textarea>
+                                                <textarea {$item.extend} name="row[{$item.name}]" id="editor-{$item.name}" class="form-control editor" data-rule="{$item.rule}" rows="5" data-tip="{$item.tip}">{$item.value|htmlentities}</textarea>
                                                 {/case}
                                                 {case array}
                                                 <dl class="fieldlist" data-name="row[{$item.name}]">
@@ -67,7 +67,7 @@
                                                         <ins>{:__('Array value')}</ins>
                                                     </dd>
                                                     <dd><a href="javascript:;" class="btn btn-sm btn-success btn-append"><i class="fa fa-plus"></i> {:__('Append')}</a></dd>
-                                                    <textarea name="row[{$item.name}]" class="form-control hide" cols="30" rows="5">{$item.value}</textarea>
+                                                    <textarea name="row[{$item.name}]" class="form-control hide" cols="30" rows="5">{$item.value|htmlentities}</textarea>
                                                 </dl>
                                                 {/case}
                                                 {case datetime}
@@ -97,7 +97,7 @@
                                                 {case value="image" break="0"}{/case}
                                                 {case value="images"}
                                                 <div class="form-inline">
-                                                    <input id="c-{$item.name}" class="form-control" size="50" name="row[{$item.name}]" type="text" value="{$item.value}" data-tip="{$item.tip}">
+                                                    <input id="c-{$item.name}" class="form-control" size="50" name="row[{$item.name}]" type="text" value="{$item.value|htmlentities}" data-tip="{$item.tip}">
                                                     <span><button type="button" id="plupload-{$item.name}" class="btn btn-danger plupload" data-input-id="c-{$item.name}" data-mimetype="image/*" data-multiple="{$item.type=='image'?'false':'true'}" data-preview-id="p-{$item.name}"><i class="fa fa-upload"></i> {:__('Upload')}</button></span>
                                                     <span><button type="button" id="fachoose-{$item.name}" class="btn btn-primary fachoose" data-input-id="c-{$item.name}" data-mimetype="image/*" data-multiple="{$item.type=='image'?'false':'true'}"><i class="fa fa-list"></i> {:__('Choose')}</button></span>
                                                     <span class="msg-box n-right" for="c-{$item.name}"></span>
@@ -107,7 +107,7 @@
                                                 {case value="file" break="0"}{/case}
                                                 {case value="files"}
                                                 <div class="form-inline">
-                                                    <input id="c-{$item.name}" class="form-control" size="50" name="row[{$item.name}]" type="text" value="{$item.value}" data-tip="{$item.tip}">
+                                                    <input id="c-{$item.name}" class="form-control" size="50" name="row[{$item.name}]" type="text" value="{$item.value|htmlentities}" data-tip="{$item.tip}">
                                                     <span><button type="button" id="plupload-{$item.name}" class="btn btn-danger plupload" data-input-id="c-{$item.name}" data-multiple="{$item.type=='file'?'false':'true'}"><i class="fa fa-upload"></i> {:__('Upload')}</button></span>
                                                     <span><button type="button" id="fachoose-{$item.name}" class="btn btn-primary fachoose" data-input-id="c-{$item.name}" data-multiple="{$item.type=='file'?'false':'true'}"><i class="fa fa-list"></i> {:__('Choose')}</button></span>
                                                     <span class="msg-box n-right" for="c-{$item.name}"></span>

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

@@ -60,15 +60,15 @@
                         <p class="text-muted text-center">{$admin.email}</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}" disabled/>
+                            <input type="text" class="form-control" id="username" name="row[username]" value="{$admin.username|htmlentities}" disabled/>
                         </div>
                         <div class="form-group">
                             <label for="email" class="control-label">{:__('Email')}:</label>
-                            <input type="text" class="form-control" id="email" name="row[email]" value="{$admin.email}" data-rule="required;email"/>
+                            <input type="text" class="form-control" id="email" name="row[email]" value="{$admin.email|htmlentities}" data-rule="required;email"/>
                         </div>
                         <div class="form-group">
                             <label for="nickname" class="control-label">{:__('Nickname')}:</label>
-                            <input type="text" class="form-control" id="nickname" name="row[nickname]" value="{$admin.nickname}" data-rule="required"/>
+                            <input type="text" class="form-control" id="nickname" name="row[nickname]" value="{$admin.nickname|htmlentities}" data-rule="required"/>
                         </div>
                         <div class="form-group">
                             <label for="password" class="control-label">{:__('Password')}:</label>

+ 1 - 1
application/admin/view/user/group/edit.html

@@ -3,7 +3,7 @@
     <div class="form-group">
         <label for="c-name" class="control-label col-xs-12 col-sm-2">{:__('Name')}:</label>
         <div class="col-xs-12 col-sm-8">
-            <input id="c-name" class="form-control" name="row[name]" type="text" value="{$row.name}">
+            <input id="c-name" class="form-control" name="row[name]" type="text" value="{$row.name|htmlentities}">
         </div>
     </div>
     <div class="form-group">

+ 3 - 3
application/admin/view/user/rule/edit.html

@@ -15,19 +15,19 @@
     <div class="form-group">
         <label for="c-name" class="control-label col-xs-12 col-sm-2">{:__('Name')}:</label>
         <div class="col-xs-12 col-sm-8">
-            <input id="c-name" class="form-control" name="row[name]" type="text" placeholder="{:__('Controller/Action')}" value="{$row.name}">
+            <input id="c-name" class="form-control" name="row[name]" type="text" placeholder="{:__('Controller/Action')}" value="{$row.name|htmlentities}">
         </div>
     </div>
     <div class="form-group">
         <label for="c-title" class="control-label col-xs-12 col-sm-2">{:__('Title')}:</label>
         <div class="col-xs-12 col-sm-8">
-            <input id="c-title" class="form-control" name="row[title]" type="text" value="{$row.title}">
+            <input id="c-title" class="form-control" name="row[title]" type="text" value="{$row.title|htmlentities}">
         </div>
     </div>
     <div class="form-group">
         <label for="remark" class="control-label col-xs-12 col-sm-2">{:__('Remark')}:</label>
         <div class="col-xs-12 col-sm-8">
-            <textarea class="form-control" id="remark" name="row[remark]">{$row.remark}</textarea>
+            <textarea class="form-control" id="remark" name="row[remark]">{$row.remark|htmlentities}</textarea>
         </div>
     </div>
     <div class="form-group">

+ 5 - 5
application/admin/view/user/user/edit.html

@@ -9,13 +9,13 @@
     <div class="form-group">
         <label for="c-username" class="control-label col-xs-12 col-sm-2">{:__('Username')}:</label>
         <div class="col-xs-12 col-sm-4">
-            <input id="c-username" data-rule="required" class="form-control" name="row[username]" type="text" value="{$row.username}">
+            <input id="c-username" data-rule="required" class="form-control" name="row[username]" type="text" value="{$row.username|htmlentities}">
         </div>
     </div>
     <div class="form-group">
         <label for="c-nickname" class="control-label col-xs-12 col-sm-2">{:__('Nickname')}:</label>
         <div class="col-xs-12 col-sm-4">
-            <input id="c-nickname" data-rule="required" class="form-control" name="row[nickname]" type="text" value="{$row.nickname}">
+            <input id="c-nickname" data-rule="required" class="form-control" name="row[nickname]" type="text" value="{$row.nickname|htmlentities}">
         </div>
     </div>
     <div class="form-group">
@@ -27,13 +27,13 @@
     <div class="form-group">
         <label for="c-email" class="control-label col-xs-12 col-sm-2">{:__('Email')}:</label>
         <div class="col-xs-12 col-sm-4">
-            <input id="c-email" data-rule="" class="form-control" name="row[email]" type="text" value="{$row.email}">
+            <input id="c-email" data-rule="" class="form-control" name="row[email]" type="text" value="{$row.email|htmlentities}">
         </div>
     </div>
     <div class="form-group">
         <label for="c-mobile" class="control-label col-xs-12 col-sm-2">{:__('Mobile')}:</label>
         <div class="col-xs-12 col-sm-4">
-            <input id="c-mobile" data-rule="" class="form-control" name="row[mobile]" type="text" value="{$row.mobile}">
+            <input id="c-mobile" data-rule="" class="form-control" name="row[mobile]" type="text" value="{$row.mobile|htmlentities}">
         </div>
     </div>
     <div class="form-group">
@@ -71,7 +71,7 @@
     <div class="form-group">
         <label for="c-bio" class="control-label col-xs-12 col-sm-2">{:__('Bio')}:</label>
         <div class="col-xs-12 col-sm-8">
-            <input id="c-bio" data-rule="" class="form-control" name="row[bio]" type="text" value="{$row.bio}">
+            <input id="c-bio" data-rule="" class="form-control" name="row[bio]" type="text" value="{$row.bio|htmlentities}">
         </div>
     </div>
     <div class="form-group">

+ 1 - 1
application/config.php

@@ -272,7 +272,7 @@ return [
         //自动检测更新
         'checkupdate'         => false,
         //版本号
-        'version'             => '1.0.0.20190418_beta',
+        'version'             => '1.0.0.20190510_beta',
         //API接口地址
         'api_url'             => 'https://api.fastadmin.net',
     ],

+ 0 - 1
application/index/controller/Index.php

@@ -3,7 +3,6 @@
 namespace app\index\controller;
 
 use app\common\controller\Frontend;
-use app\common\library\Token;
 
 class Index extends Frontend
 {

+ 4 - 4
application/index/controller/User.php

@@ -75,7 +75,7 @@ class User extends Frontend
      */
     public function register()
     {
-        $url = $this->request->request('url');
+        $url = $this->request->request('url', '', 'trim');
         if ($this->auth->id) {
             $this->success(__('You\'ve logged in, do not login again'), $url ? $url : url('user/index'));
         }
@@ -127,7 +127,7 @@ class User extends Frontend
         //判断来源
         $referer = $this->request->server('HTTP_REFERER');
         if (!$url && (strtolower(parse_url($referer, PHP_URL_HOST)) == strtolower($this->request->host()))
-            && !preg_match("/(user\/login|user\/register)/i", $referer)) {
+            && !preg_match("/(user\/login|user\/register|user\/logout)/i", $referer)) {
             $url = $referer;
         }
         $this->view->assign('url', $url);
@@ -140,7 +140,7 @@ class User extends Frontend
      */
     public function login()
     {
-        $url = $this->request->request('url');
+        $url = $this->request->request('url', '', 'trim');
         if ($this->auth->id) {
             $this->success(__('You\'ve logged in, do not login again'), $url ? $url : url('user/index'));
         }
@@ -181,7 +181,7 @@ class User extends Frontend
         //判断来源
         $referer = $this->request->server('HTTP_REFERER');
         if (!$url && (strtolower(parse_url($referer, PHP_URL_HOST)) == strtolower($this->request->host()))
-            && !preg_match("/(user\/login|user\/register)/i", $referer)) {
+            && !preg_match("/(user\/login|user\/register|user\/logout)/i", $referer)) {
             $url = $referer;
         }
         $this->view->assign('url', $url);

+ 1 - 1
application/index/view/user/login.html

@@ -1,6 +1,6 @@
 <div id="content-container" class="container">
     <div class="user-section login-section">
-        <div class="logon-tab clearfix"> <a class="active">{:__('Sign in')}</a> <a href="{:url('user/register')}">{:__('Sign up')}</a> </div>
+        <div class="logon-tab clearfix"> <a class="active">{:__('Sign in')}</a> <a href="{:url('user/register')}?url={$url|urlencode}">{:__('Sign up')}</a> </div>
         <div class="login-main"> 
             <form name="form" id="login-form" class="form-vertical" method="POST" action="">
                 <input type="hidden" name="url" value="{$url}" />

+ 5 - 5
application/index/view/user/profile.html

@@ -53,26 +53,26 @@
                         <div class="form-group">
                             <label class="control-label col-xs-12 col-sm-2">{:__('Username')}:</label>
                             <div class="col-xs-12 col-sm-4">
-                                <input type="text" class="form-control" id="username" name="username" value="{$user.username}" data-rule="required;username;remote({:url('api/validate/check_username_available')}, id={$user.id})" placeholder="">
+                                <input type="text" class="form-control" id="username" name="username" value="{$user.username|htmlentities}" data-rule="required;username;remote({:url('api/validate/check_username_available')}, id={$user.id})" placeholder="">
                             </div>
                         </div>
                         <div class="form-group">
                             <label class="control-label col-xs-12 col-sm-2">{:__('Nickname')}:</label>
                             <div class="col-xs-12 col-sm-4">
-                                <input type="text" class="form-control" id="nickname" name="nickname" value="{$user.nickname}" data-rule="required" placeholder="">
+                                <input type="text" class="form-control" id="nickname" name="nickname" value="{$user.nickname|htmlentities}" data-rule="required" placeholder="">
                             </div>
                         </div>
                         <div class="form-group">
                             <label for="c-bio" class="control-label col-xs-12 col-sm-2">{:__('Intro')}:</label>
                             <div class="col-xs-12 col-sm-8">
-                                <input id="c-bio" data-rule="" data-tip="一句话介绍一下你自己" class="form-control" name="bio" type="text" value="{$user.bio}">
+                                <input id="c-bio" data-rule="" data-tip="一句话介绍一下你自己" class="form-control" name="bio" type="text" value="{$user.bio|htmlentities}">
                             </div>
                         </div>
                         <div class="form-group">
                             <label for="c-email" class="control-label col-xs-12 col-sm-2">{:__('Email')}:</label>
                             <div class="col-xs-12 col-sm-4">
                                 <div class="input-group">
-                                    <input type="text" class="form-control" id="c-email" name="email" value="{$user.email}" disabled placeholder="">
+                                    <input type="text" class="form-control" id="c-email" name="email" value="{$user.email|htmlentities}" disabled placeholder="">
                                     <span class="input-group-btn" style="padding:0;border:none;">
                                         <a href="javascript:;" class="btn btn-info btn-change" data-type="email">{:__('Change')}</a>
                                     </span>
@@ -84,7 +84,7 @@
                             <label for="c-mobile" class="control-label col-xs-12 col-sm-2">{:__('Mobile')}:</label>
                             <div class="col-xs-12 col-sm-4">
                                 <div class="input-group">
-                                    <input type="text" class="form-control" id="c-mobile" name="mobile" value="{$user.mobile}" disabled placeholder="">
+                                    <input type="text" class="form-control" id="c-mobile" name="mobile" value="{$user.mobile|htmlentities}" disabled placeholder="">
                                     <span class="input-group-btn" style="padding:0;border:none;">
                                         <a href="javascript:;" class="btn btn-info btn-change" data-type="mobile">{:__('Change')}</a>
                                     </span>

+ 1 - 1
application/index/view/user/register.html

@@ -1,6 +1,6 @@
 <div id="content-container" class="container">
     <div class="user-section login-section">
-        <div class="logon-tab clearfix"> <a href="{:url('user/login')}">{:__('Sign in')}</a> <a class="active">{:__('Sign up')}</a> </div>
+        <div class="logon-tab clearfix"> <a href="{:url('user/login')}?url={$url|urlencode}">{:__('Sign in')}</a> <a class="active">{:__('Sign up')}</a> </div>
         <div class="login-main"> 
             <form name="form1" id="register-form" class="form-vertical" method="POST" action="">
                 <input type="hidden" name="invite_user_id" value="0" />

+ 3 - 0
extend/fast/Date.php

@@ -2,6 +2,9 @@
 
 namespace fast;
 
+use DateTime;
+use DateTimeZone;
+
 /**
  * 日期时间处理类
  */

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

@@ -241,7 +241,7 @@ define(['fast', 'template', 'moment'], function (Fast, Template, Moment) {
             }
             //tooltip和popover
             if (!('ontouchstart' in document.documentElement)) {
-                $('body').tooltip({selector: '[data-toggle="tooltip"]', container: 'body'});
+                $('body').tooltip({selector: '[data-toggle="tooltip"]'});
             }
             $('body').popover({selector: '[data-toggle="popover"]'});
         }

+ 6 - 4
public/assets/js/backend/category.js

@@ -28,10 +28,10 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
                     [
                         {checkbox: true},
                         {field: 'id', title: __('Id')},
-                        {field: 'type', title: __('Type'), searchList: Config.searchList, formatter: Table.api.formatter.normal},
+                        {field: 'type', title: __('Type'), operate: false, searchList: Config.searchList, formatter: Table.api.formatter.normal},
                         {field: 'name', title: __('Name'), align: 'left'},
                         {field: 'nickname', title: __('Nickname')},
-                        {field: 'flag', title: __('Flag'), operate: false, formatter: Table.api.formatter.flag},
+                        {field: 'flag', title: __('Flag'), formatter: Table.api.formatter.flag},
                         {field: 'image', title: __('Image'), operate: false, formatter: Table.api.formatter.image},
                         {field: 'weigh', title: __('Weigh')},
                         {field: 'status', title: __('Status'), operate: false, formatter: Table.api.formatter.status},
@@ -68,7 +68,9 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
         },
         add: function () {
             Controller.api.bindevent();
-            $("#c-type").trigger("change");
+            setTimeout(function () {
+                $("#c-type").trigger("change");
+            }, 100);
         },
         edit: function () {
             Controller.api.bindevent();
@@ -79,7 +81,7 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
                     $("#c-pid option[data-type='all']").prop("selected", true);
                     $("#c-pid option").removeClass("hide");
                     $("#c-pid option[data-type!='" + $(this).val() + "'][data-type!='all']").addClass("hide");
-                    $("#c-pid").selectpicker("refresh");
+                    $("#c-pid").data("selectpicker") && $("#c-pid").selectpicker("refresh");
                 });
                 Form.api.bindevent($("form[role=form]"));
             }

+ 0 - 17
public/assets/js/backend/dashboard.js

@@ -108,23 +108,6 @@ define(['jquery', 'bootstrap', 'backend', 'addtabs', 'table', 'echarts', 'echart
                 top.window.$("[data-toggle=checkupdate]").trigger("click");
             });
 
-            //读取FastAdmin的更新信息和社区动态
-            $.ajax({
-                url: Config.fastadmin.api_url + '/news/index',
-                type: 'post',
-                dataType: 'jsonp',
-                success: function (ret) {
-                    $("#news-list").html(Template("newstpl", {news: ret.newslist}));
-                }
-            });
-            $.ajax({
-                url: Config.fastadmin.api_url + '/forum/discussion',
-                type: 'post',
-                dataType: 'jsonp',
-                success: function (ret) {
-                    $("#discussion-list").html(Template("discussiontpl", {news: ret.discussionlist}));
-                }
-            });
         }
     };
 

+ 1 - 1
public/assets/js/frontend.js

@@ -51,7 +51,7 @@ define(['fast', 'template', 'moment'], function (Fast, Template, Moment) {
             });
             //tooltip和popover
             if (!('ontouchstart' in document.documentElement)) {
-                $('body').tooltip({selector: '[data-toggle="tooltip"]', container: 'body'});
+                $('body').tooltip({selector: '[data-toggle="tooltip"]'});
             }
             $('body').popover({selector: '[data-toggle="popover"]'});
         }

+ 27 - 11
public/assets/js/require-backend.min.js

@@ -5856,7 +5856,7 @@ define('backend',['fast', 'template', 'moment'], function (Fast, Template, Momen
             }
             //tooltip和popover
             if (!('ontouchstart' in document.documentElement)) {
-                $('body').tooltip({selector: '[data-toggle="tooltip"]', container: 'body'});
+                $('body').tooltip({selector: '[data-toggle="tooltip"]'});
             }
             $('body').popover({selector: '[data-toggle="popover"]'});
         }
@@ -6201,7 +6201,7 @@ define('upload',['jquery', 'bootstrap', 'plupload', 'template'], function ($, un
                 onInit: function (up) {
                     //修复少数安卓浏览器无法上传图片的Bug
                     var input = $("input[type=file]", $(up.settings.button).next());
-                    if (input && input.prop("accept").match(/image\/jpeg/)) {
+                    if (input && input.prop("accept") && input.prop("accept").match(/image\/jpeg/)) {
                         input.prop("accept", "image/jpg," + input.prop("accept"));
                     }
                 },
@@ -6260,7 +6260,7 @@ define('upload',['jquery', 'bootstrap', 'plupload', 'template'], function ($, un
                                 urlArr.push(inputObj.val());
                             }
                             urlArr.push(data.url);
-                            inputObj.val(urlArr.join(",")).trigger("change");
+                            inputObj.val(urlArr.join(",")).trigger("change").trigger("validate");
                         }
                         //如果有回调函数
                         var onDomUploadSuccess = $(button).data("upload-success");
@@ -6502,7 +6502,7 @@ define('upload',['jquery', 'bootstrap', 'plupload', 'template'], function ($, un
                                                 urlArr.push($(that).val());
                                             }
                                             urlArr.push(data.url);
-                                            $(that).val(urlArr.join(",")).trigger("change");
+                                            $(that).val(urlArr.join(",")).trigger("change").trigger("validate");
                                         });
                                     }
                                 }
@@ -6524,7 +6524,7 @@ define('upload',['jquery', 'bootstrap', 'plupload', 'template'], function ($, un
                                                     urlArr.push($(that).val());
                                                 }
                                                 urlArr.push(data.url);
-                                                $(that).val(urlArr.join(",")).trigger("change");
+                                                $(that).val(urlArr.join(",")).trigger("change").trigger("validate");
                                             });
                                         });
                                     }
@@ -8882,7 +8882,7 @@ define('validator',['validator-core', 'validator-lang'], function (Validator, un
 define('form',['jquery', 'bootstrap', 'upload', 'validator'], function ($, undefined, Upload, Validator) {
     var Form = {
         config: {
-            fieldlisttpl: '<dd class="form-inline"><input type="text" name="<%=name%>[<%=index%>][key]" class="form-control" value="<%=row.key%>" size="10" /> <input type="text" name="<%=name%>[<%=index%>][value]" class="form-control" value="<%=row.value%>" size="30" /> <span class="btn btn-sm btn-danger btn-remove"><i class="fa fa-times"></i></span> <span class="btn btn-sm btn-primary btn-dragsort"><i class="fa fa-arrows"></i></span></dd>'
+            fieldlisttpl: '<dd class="form-inline"><input type="text" name="<%=name%>[<%=index%>][key]" class="form-control" value="<%=row.key%>" size="10" /> <input type="text" name="<%=name%>[<%=index%>][value]" class="form-control" value="<%=row.value%>" /> <span class="btn btn-sm btn-danger btn-remove"><i class="fa fa-times"></i></span> <span class="btn btn-sm btn-primary btn-dragsort"><i class="fa fa-arrows"></i></span></dd>'
         },
         events: {
             validator: function (form, success, error, submit) {
@@ -8970,6 +8970,11 @@ define('form',['jquery', 'bootstrap', 'upload', 'validator'], function ($, undef
                 if ($(".selectpicker", form).size() > 0) {
                     require(['bootstrap-select', 'bootstrap-select-lang'], function () {
                         $('.selectpicker', form).selectpicker();
+                        $(form).on("reset", function () {
+                            setTimeout(function () {
+                                $('.selectpicker').selectpicker('refresh').trigger("change");
+                            }, 1);
+                        });
                     });
                 }
             },
@@ -9014,6 +9019,11 @@ define('form',['jquery', 'bootstrap', 'upload', 'validator'], function ($, undef
                 //绑定城市远程插件
                 if ($("[data-toggle='city-picker']", form).size() > 0) {
                     require(['citypicker'], function () {
+                        $(form).on("reset", function () {
+                            setTimeout(function () {
+                                $("[data-toggle='city-picker']").citypicker('refresh');
+                            }, 1);
+                        });
                     });
                 }
             },
@@ -9123,9 +9133,9 @@ define('form',['jquery', 'bootstrap', 'upload', 'validator'], function ($, undef
                                             return false;
                                         }
                                     }
-                                    inputObj.val(result).trigger("change");
+                                    inputObj.val(result).trigger("change").trigger("validate");
                                 } else {
-                                    $("#" + input_id).val(data.url).trigger("change");
+                                    $("#" + input_id).val(data.url).trigger("change").trigger("validate");
                                 }
                             }
                         });
@@ -10375,13 +10385,19 @@ define('table',['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstr
                     //渲染Flag
                     var html = [];
                     var arr = value.split(',');
+                    var color, display, label;
                     $.each(arr, function (i, value) {
                         value = value === null ? '' : value.toString();
                         if (value == '')
                             return true;
-                        var color = value && typeof colorArr[value] !== 'undefined' ? colorArr[value] : 'primary';
-                        var display = typeof that.searchList !== 'undefined' && typeof that.searchList[value] !== 'undefined' ? that.searchList[value] : __(value.charAt(0).toUpperCase() + value.slice(1));
-                        html.push('<a href="javascript:;" class="searchit" data-toggle="tooltip" title="' + __('Click to search %s', display) + '" data-field="' + field + '" data-value="' + value + '"><span class="label label-' + color + '">' + display + '</span></a>');
+                        color = value && typeof colorArr[value] !== 'undefined' ? colorArr[value] : 'primary';
+                        display = typeof that.searchList !== 'undefined' && typeof that.searchList[value] !== 'undefined' ? that.searchList[value] : __(value.charAt(0).toUpperCase() + value.slice(1));
+                        label = '<span class="label label-' + color + '">' + display + '</span>';
+                        if (that.operate) {
+                            html.push('<a href="javascript:;" class="searchit" data-toggle="tooltip" title="' + __('Click to search %s', display) + '" data-field="' + field + '" data-value="' + value + '">' + label + '</a>');
+                        } else {
+                            html.push(label);
+                        }
                     });
                     return html.join(' ');
                 },

+ 13 - 3
public/assets/js/require-form.js

@@ -1,7 +1,7 @@
 define(['jquery', 'bootstrap', 'upload', 'validator'], function ($, undefined, Upload, Validator) {
     var Form = {
         config: {
-            fieldlisttpl: '<dd class="form-inline"><input type="text" name="<%=name%>[<%=index%>][key]" class="form-control" value="<%=row.key%>" size="10" /> <input type="text" name="<%=name%>[<%=index%>][value]" class="form-control" value="<%=row.value%>" size="30" /> <span class="btn btn-sm btn-danger btn-remove"><i class="fa fa-times"></i></span> <span class="btn btn-sm btn-primary btn-dragsort"><i class="fa fa-arrows"></i></span></dd>'
+            fieldlisttpl: '<dd class="form-inline"><input type="text" name="<%=name%>[<%=index%>][key]" class="form-control" value="<%=row.key%>" size="10" /> <input type="text" name="<%=name%>[<%=index%>][value]" class="form-control" value="<%=row.value%>" /> <span class="btn btn-sm btn-danger btn-remove"><i class="fa fa-times"></i></span> <span class="btn btn-sm btn-primary btn-dragsort"><i class="fa fa-arrows"></i></span></dd>'
         },
         events: {
             validator: function (form, success, error, submit) {
@@ -89,6 +89,11 @@ define(['jquery', 'bootstrap', 'upload', 'validator'], function ($, undefined, U
                 if ($(".selectpicker", form).size() > 0) {
                     require(['bootstrap-select', 'bootstrap-select-lang'], function () {
                         $('.selectpicker', form).selectpicker();
+                        $(form).on("reset", function () {
+                            setTimeout(function () {
+                                $('.selectpicker').selectpicker('refresh').trigger("change");
+                            }, 1);
+                        });
                     });
                 }
             },
@@ -133,6 +138,11 @@ define(['jquery', 'bootstrap', 'upload', 'validator'], function ($, undefined, U
                 //绑定城市远程插件
                 if ($("[data-toggle='city-picker']", form).size() > 0) {
                     require(['citypicker'], function () {
+                        $(form).on("reset", function () {
+                            setTimeout(function () {
+                                $("[data-toggle='city-picker']").citypicker('refresh');
+                            }, 1);
+                        });
                     });
                 }
             },
@@ -242,9 +252,9 @@ define(['jquery', 'bootstrap', 'upload', 'validator'], function ($, undefined, U
                                             return false;
                                         }
                                     }
-                                    inputObj.val(result).trigger("change");
+                                    inputObj.val(result).trigger("change").trigger("validate");
                                 } else {
-                                    $("#" + input_id).val(data.url).trigger("change");
+                                    $("#" + input_id).val(data.url).trigger("change").trigger("validate");
                                 }
                             }
                         });

+ 1 - 1
public/assets/js/require-frontend.min.js

@@ -5665,7 +5665,7 @@ define('frontend',['fast', 'template', 'moment'], function (Fast, Template, Mome
             });
             //tooltip和popover
             if (!('ontouchstart' in document.documentElement)) {
-                $('body').tooltip({selector: '[data-toggle="tooltip"]', container: 'body'});
+                $('body').tooltip({selector: '[data-toggle="tooltip"]'});
             }
             $('body').popover({selector: '[data-toggle="popover"]'});
         }

+ 9 - 3
public/assets/js/require-table.js

@@ -521,13 +521,19 @@ define(['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstrap-table
                     //渲染Flag
                     var html = [];
                     var arr = value.split(',');
+                    var color, display, label;
                     $.each(arr, function (i, value) {
                         value = value === null ? '' : value.toString();
                         if (value == '')
                             return true;
-                        var color = value && typeof colorArr[value] !== 'undefined' ? colorArr[value] : 'primary';
-                        var display = typeof that.searchList !== 'undefined' && typeof that.searchList[value] !== 'undefined' ? that.searchList[value] : __(value.charAt(0).toUpperCase() + value.slice(1));
-                        html.push('<a href="javascript:;" class="searchit" data-toggle="tooltip" title="' + __('Click to search %s', display) + '" data-field="' + field + '" data-value="' + value + '"><span class="label label-' + color + '">' + display + '</span></a>');
+                        color = value && typeof colorArr[value] !== 'undefined' ? colorArr[value] : 'primary';
+                        display = typeof that.searchList !== 'undefined' && typeof that.searchList[value] !== 'undefined' ? that.searchList[value] : __(value.charAt(0).toUpperCase() + value.slice(1));
+                        label = '<span class="label label-' + color + '">' + display + '</span>';
+                        if (that.operate) {
+                            html.push('<a href="javascript:;" class="searchit" data-toggle="tooltip" title="' + __('Click to search %s', display) + '" data-field="' + field + '" data-value="' + value + '">' + label + '</a>');
+                        } else {
+                            html.push(label);
+                        }
                     });
                     return html.join(' ');
                 },

+ 4 - 4
public/assets/js/require-upload.js

@@ -10,7 +10,7 @@ define(['jquery', 'bootstrap', 'plupload', 'template'], function ($, undefined,
                 onInit: function (up) {
                     //修复少数安卓浏览器无法上传图片的Bug
                     var input = $("input[type=file]", $(up.settings.button).next());
-                    if (input && input.prop("accept").match(/image\/jpeg/)) {
+                    if (input && input.prop("accept") && input.prop("accept").match(/image\/jpeg/)) {
                         input.prop("accept", "image/jpg," + input.prop("accept"));
                     }
                 },
@@ -69,7 +69,7 @@ define(['jquery', 'bootstrap', 'plupload', 'template'], function ($, undefined,
                                 urlArr.push(inputObj.val());
                             }
                             urlArr.push(data.url);
-                            inputObj.val(urlArr.join(",")).trigger("change");
+                            inputObj.val(urlArr.join(",")).trigger("change").trigger("validate");
                         }
                         //如果有回调函数
                         var onDomUploadSuccess = $(button).data("upload-success");
@@ -311,7 +311,7 @@ define(['jquery', 'bootstrap', 'plupload', 'template'], function ($, undefined,
                                                 urlArr.push($(that).val());
                                             }
                                             urlArr.push(data.url);
-                                            $(that).val(urlArr.join(",")).trigger("change");
+                                            $(that).val(urlArr.join(",")).trigger("change").trigger("validate");
                                         });
                                     }
                                 }
@@ -333,7 +333,7 @@ define(['jquery', 'bootstrap', 'plupload', 'template'], function ($, undefined,
                                                     urlArr.push($(that).val());
                                                 }
                                                 urlArr.push(data.url);
-                                                $(that).val(urlArr.join(",")).trigger("change");
+                                                $(that).val(urlArr.join(",")).trigger("change").trigger("validate");
                                             });
                                         });
                                     }