Browse Source

风云公司门户网站

LST 1 year ago
commit
e271f8738b
100 changed files with 21266 additions and 0 deletions
  1. 0 0
      .htaccess
  2. 191 0
      LICENSE
  3. 103 0
      README.md
  4. 26 0
      api.php
  5. 391 0
      apps/admin/controller/IndexController.php
  6. 70 0
      apps/admin/controller/content/CompanyController.php
  7. 563 0
      apps/admin/controller/content/ContentController.php
  8. 537 0
      apps/admin/controller/content/ContentSortController.php
  9. 224 0
      apps/admin/controller/content/DeleCacheController.php
  10. 244 0
      apps/admin/controller/content/ExtFieldController.php
  11. 354 0
      apps/admin/controller/content/FormController.php
  12. 175 0
      apps/admin/controller/content/LabelController.php
  13. 213 0
      apps/admin/controller/content/LinkController.php
  14. 128 0
      apps/admin/controller/content/MessageController.php
  15. 207 0
      apps/admin/controller/content/ModelController.php
  16. 271 0
      apps/admin/controller/content/SingleController.php
  17. 82 0
      apps/admin/controller/content/SiteController.php
  18. 195 0
      apps/admin/controller/content/SlideController.php
  19. 157 0
      apps/admin/controller/content/TagsController.php
  20. 118 0
      apps/admin/controller/member/MemberCommentController.php
  21. 292 0
      apps/admin/controller/member/MemberController.php
  22. 193 0
      apps/admin/controller/member/MemberFieldController.php
  23. 187 0
      apps/admin/controller/member/MemberGroupController.php
  24. 303 0
      apps/admin/controller/system/AreaController.php
  25. 231 0
      apps/admin/controller/system/ConfigController.php
  26. 248 0
      apps/admin/controller/system/DatabaseController.php
  27. 152 0
      apps/admin/controller/system/ImageExtController.php
  28. 275 0
      apps/admin/controller/system/MenuController.php
  29. 249 0
      apps/admin/controller/system/RoleController.php
  30. 40 0
      apps/admin/controller/system/SyslogController.php
  31. 172 0
      apps/admin/controller/system/TypeController.php
  32. 408 0
      apps/admin/controller/system/UpgradeController.php
  33. 227 0
      apps/admin/controller/system/UserController.php
  34. 225 0
      apps/admin/model/IndexModel.php
  35. 44 0
      apps/admin/model/content/CompanyModel.php
  36. 346 0
      apps/admin/model/content/ContentModel.php
  37. 267 0
      apps/admin/model/content/ContentSortModel.php
  38. 93 0
      apps/admin/model/content/ExtFieldModel.php
  39. 238 0
      apps/admin/model/content/FormModel.php
  40. 89 0
      apps/admin/model/content/LabelModel.php
  41. 85 0
      apps/admin/model/content/LinkModel.php
  42. 103 0
      apps/admin/model/content/MessageModel.php
  43. 140 0
      apps/admin/model/content/ModelModel.php
  44. 196 0
      apps/admin/model/content/SingleModel.php
  45. 50 0
      apps/admin/model/content/SiteModel.php
  46. 85 0
      apps/admin/model/content/SlideModel.php
  47. 65 0
      apps/admin/model/content/TagsModel.php
  48. 136 0
      apps/admin/model/member/MemberCommentModel.php
  49. 79 0
      apps/admin/model/member/MemberFieldModel.php
  50. 98 0
      apps/admin/model/member/MemberGroupModel.php
  51. 122 0
      apps/admin/model/member/MemberModel.php
  52. 101 0
      apps/admin/model/system/AreaModel.php
  53. 66 0
      apps/admin/model/system/ConfigModel.php
  54. 102 0
      apps/admin/model/system/DatabaseModel.php
  55. 161 0
      apps/admin/model/system/MenuModel.php
  56. 169 0
      apps/admin/model/system/RoleModel.php
  57. 29 0
      apps/admin/model/system/SyslogModel.php
  58. 89 0
      apps/admin/model/system/TypeModel.php
  59. 166 0
      apps/admin/model/system/UserModel.php
  60. 20 0
      apps/admin/view/default/common/foot.html
  61. 137 0
      apps/admin/view/default/common/head.html
  62. 36 0
      apps/admin/view/default/common/ueditor.html
  63. 122 0
      apps/admin/view/default/content/company.html
  64. 952 0
      apps/admin/view/default/content/content.html
  65. 615 0
      apps/admin/view/default/content/contentsort.html
  66. 135 0
      apps/admin/view/default/content/delecache.html
  67. 68 0
      apps/admin/view/default/content/exform.html
  68. 76 0
      apps/admin/view/default/content/exmessage.html
  69. 230 0
      apps/admin/view/default/content/extfield.html
  70. 327 0
      apps/admin/view/default/content/form.html
  71. 254 0
      apps/admin/view/default/content/label.html
  72. 170 0
      apps/admin/view/default/content/link.html
  73. 148 0
      apps/admin/view/default/content/message.html
  74. 191 0
      apps/admin/view/default/content/model.html
  75. 426 0
      apps/admin/view/default/content/single.html
  76. 107 0
      apps/admin/view/default/content/site.html
  77. 187 0
      apps/admin/view/default/content/slide.html
  78. 105 0
      apps/admin/view/default/content/tags.html
  79. 265 0
      apps/admin/view/default/css/comm.css
  80. 28 0
      apps/admin/view/default/css/jquery.treetable.css
  81. 102 0
      apps/admin/view/default/css/login.css
  82. 7 0
      apps/admin/view/default/font-awesome/HELP-US-OUT.txt
  83. 2337 0
      apps/admin/view/default/font-awesome/css/font-awesome.css
  84. 4 0
      apps/admin/view/default/font-awesome/css/font-awesome.min.css
  85. BIN
      apps/admin/view/default/font-awesome/fonts/FontAwesome.otf
  86. BIN
      apps/admin/view/default/font-awesome/fonts/fontawesome-webfont.eot
  87. 2671 0
      apps/admin/view/default/font-awesome/fonts/fontawesome-webfont.svg
  88. BIN
      apps/admin/view/default/font-awesome/fonts/fontawesome-webfont.ttf
  89. BIN
      apps/admin/view/default/font-awesome/fonts/fontawesome-webfont.woff
  90. BIN
      apps/admin/view/default/font-awesome/fonts/fontawesome-webfont.woff2
  91. 34 0
      apps/admin/view/default/font-awesome/less/animated.less
  92. 25 0
      apps/admin/view/default/font-awesome/less/bordered-pulled.less
  93. 12 0
      apps/admin/view/default/font-awesome/less/core.less
  94. 6 0
      apps/admin/view/default/font-awesome/less/fixed-width.less
  95. 18 0
      apps/admin/view/default/font-awesome/less/font-awesome.less
  96. 789 0
      apps/admin/view/default/font-awesome/less/icons.less
  97. 13 0
      apps/admin/view/default/font-awesome/less/larger.less
  98. 19 0
      apps/admin/view/default/font-awesome/less/list.less
  99. 60 0
      apps/admin/view/default/font-awesome/less/mixins.less
  100. 0 0
      apps/admin/view/default/font-awesome/less/path.less

+ 0 - 0
.htaccess


+ 191 - 0
LICENSE

@@ -0,0 +1,191 @@
+Apache License
+Version 2.0, January 2004
+http://www.apache.org/licenses/
+
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+1. Definitions.
+
+"License" shall mean the terms and conditions for use, reproduction, and
+distribution as defined by Sections 1 through 9 of this document.
+
+"Licensor" shall mean the copyright owner or entity authorized by the copyright
+owner that is granting the License.
+
+"Legal Entity" shall mean the union of the acting entity and all other entities
+that control, are controlled by, or are under common control with that entity.
+For the purposes of this definition, "control" means (i) the power, direct or
+indirect, to cause the direction or management of such entity, whether by
+contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the
+outstanding shares, or (iii) beneficial ownership of such entity.
+
+"You" (or "Your") shall mean an individual or Legal Entity exercising
+permissions granted by this License.
+
+"Source" form shall mean the preferred form for making modifications, including
+but not limited to software source code, documentation source, and configuration
+files.
+
+"Object" form shall mean any form resulting from mechanical transformation or
+translation of a Source form, including but not limited to compiled object code,
+generated documentation, and conversions to other media types.
+
+"Work" shall mean the work of authorship, whether in Source or Object form, made
+available under the License, as indicated by a copyright notice that is included
+in or attached to the work (an example is provided in the Appendix below).
+
+"Derivative Works" shall mean any work, whether in Source or Object form, that
+is based on (or derived from) the Work and for which the editorial revisions,
+annotations, elaborations, or other modifications represent, as a whole, an
+original work of authorship. For the purposes of this License, Derivative Works
+shall not include works that remain separable from, or merely link (or bind by
+name) to the interfaces of, the Work and Derivative Works thereof.
+
+"Contribution" shall mean any work of authorship, including the original version
+of the Work and any modifications or additions to that Work or Derivative Works
+thereof, that is intentionally submitted to Licensor for inclusion in the Work
+by the copyright owner or by an individual or Legal Entity authorized to submit
+on behalf of the copyright owner. For the purposes of this definition,
+"submitted" means any form of electronic, verbal, or written communication sent
+to the Licensor or its representatives, including but not limited to
+communication on electronic mailing lists, source code control systems, and
+issue tracking systems that are managed by, or on behalf of, the Licensor for
+the purpose of discussing and improving the Work, but excluding communication
+that is conspicuously marked or otherwise designated in writing by the copyright
+owner as "Not a Contribution."
+
+"Contributor" shall mean Licensor and any individual or Legal Entity on behalf
+of whom a Contribution has been received by Licensor and subsequently
+incorporated within the Work.
+
+2. Grant of Copyright License.
+
+Subject to the terms and conditions of this License, each Contributor hereby
+grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
+irrevocable copyright license to reproduce, prepare Derivative Works of,
+publicly display, publicly perform, sublicense, and distribute the Work and such
+Derivative Works in Source or Object form.
+
+3. Grant of Patent License.
+
+Subject to the terms and conditions of this License, each Contributor hereby
+grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
+irrevocable (except as stated in this section) patent license to make, have
+made, use, offer to sell, sell, import, and otherwise transfer the Work, where
+such license applies only to those patent claims licensable by such Contributor
+that are necessarily infringed by their Contribution(s) alone or by combination
+of their Contribution(s) with the Work to which such Contribution(s) was
+submitted. If You institute patent litigation against any entity (including a
+cross-claim or counterclaim in a lawsuit) alleging that the Work or a
+Contribution incorporated within the Work constitutes direct or contributory
+patent infringement, then any patent licenses granted to You under this License
+for that Work shall terminate as of the date such litigation is filed.
+
+4. Redistribution.
+
+You may reproduce and distribute copies of the Work or Derivative Works thereof
+in any medium, with or without modifications, and in Source or Object form,
+provided that You meet the following conditions:
+
+You must give any other recipients of the Work or Derivative Works a copy of
+this License; and
+You must cause any modified files to carry prominent notices stating that You
+changed the files; and
+You must retain, in the Source form of any Derivative Works that You distribute,
+all copyright, patent, trademark, and attribution notices from the Source form
+of the Work, excluding those notices that do not pertain to any part of the
+Derivative Works; and
+If the Work includes a "NOTICE" text file as part of its distribution, then any
+Derivative Works that You distribute must include a readable copy of the
+attribution notices contained within such NOTICE file, excluding those notices
+that do not pertain to any part of the Derivative Works, in at least one of the
+following places: within a NOTICE text file distributed as part of the
+Derivative Works; within the Source form or documentation, if provided along
+with the Derivative Works; or, within a display generated by the Derivative
+Works, if and wherever such third-party notices normally appear. The contents of
+the NOTICE file are for informational purposes only and do not modify the
+License. You may add Your own attribution notices within Derivative Works that
+You distribute, alongside or as an addendum to the NOTICE text from the Work,
+provided that such additional attribution notices cannot be construed as
+modifying the License.
+You may add Your own copyright statement to Your modifications and may provide
+additional or different license terms and conditions for use, reproduction, or
+distribution of Your modifications, or for any such Derivative Works as a whole,
+provided Your use, reproduction, and distribution of the Work otherwise complies
+with the conditions stated in this License.
+
+5. Submission of Contributions.
+
+Unless You explicitly state otherwise, any Contribution intentionally submitted
+for inclusion in the Work by You to the Licensor shall be under the terms and
+conditions of this License, without any additional terms or conditions.
+Notwithstanding the above, nothing herein shall supersede or modify the terms of
+any separate license agreement you may have executed with Licensor regarding
+such Contributions.
+
+6. Trademarks.
+
+This License does not grant permission to use the trade names, trademarks,
+service marks, or product names of the Licensor, except as required for
+reasonable and customary use in describing the origin of the Work and
+reproducing the content of the NOTICE file.
+
+7. Disclaimer of Warranty.
+
+Unless required by applicable law or agreed to in writing, Licensor provides the
+Work (and each Contributor provides its Contributions) on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
+including, without limitation, any warranties or conditions of TITLE,
+NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are
+solely responsible for determining the appropriateness of using or
+redistributing the Work and assume any risks associated with Your exercise of
+permissions under this License.
+
+8. Limitation of Liability.
+
+In no event and under no legal theory, whether in tort (including negligence),
+contract, or otherwise, unless required by applicable law (such as deliberate
+and grossly negligent acts) or agreed to in writing, shall any Contributor be
+liable to You for damages, including any direct, indirect, special, incidental,
+or consequential damages of any character arising as a result of this License or
+out of the use or inability to use the Work (including but not limited to
+damages for loss of goodwill, work stoppage, computer failure or malfunction, or
+any and all other commercial damages or losses), even if such Contributor has
+been advised of the possibility of such damages.
+
+9. Accepting Warranty or Additional Liability.
+
+While redistributing the Work or Derivative Works thereof, You may choose to
+offer, and charge a fee for, acceptance of support, warranty, indemnity, or
+other liability obligations and/or rights consistent with this License. However,
+in accepting such obligations, You may act only on Your own behalf and on Your
+sole responsibility, not on behalf of any other Contributor, and only if You
+agree to indemnify, defend, and hold each Contributor harmless for any liability
+incurred by, or claims asserted against, such Contributor by reason of your
+accepting any such warranty or additional liability.
+
+END OF TERMS AND CONDITIONS
+
+APPENDIX: How to apply the Apache License to your work
+
+To apply the Apache License to your work, attach the following boilerplate
+notice, with the fields enclosed by brackets "{}" replaced with your own
+identifying information. (Don't include the brackets!) The text should be
+enclosed in the appropriate comment syntax for the file format. We also
+recommend that a file or class name and description of purpose be included on
+the same "printed page" as the copyright notice for easier identification within
+third-party archives.
+
+   Copyright 2018 Hunan AoYun Network Technology Co., Ltd.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.

+ 103 - 0
README.md

@@ -0,0 +1,103 @@
+# PbootCMS
+
+### PbootCMS是全新内核且永久开源免费的PHP企业网站开发建设管理系统,是一套高效、简洁、 强悍的可免费商用的PHP CMS源码,能够满足各类企业网站开发建设的需要。系统采用简单到想哭的模板标签,只要懂HTML就可快速开发企业网站。官方提供了大量网站模板免费下载和使用,将致力于为广大开发者和企业提供最佳的网站开发建设解决方案。
+* 系统采用高效、简洁、强悍的模板标签,只要懂HTML就可快速开发企业网站;
+* 系统采用PHP语言开发,使用自主研发的高速多层开发框架及缓存技术;
+* 系统默认采用sqlite轻型数据库,放入PHP空间即可直接使用,可选mysql等数据库,满足各类存储需求;
+* 系统采用响应式管理后台,满足各类设备随时管理的需要;
+* 系统支持后台在线升级,满足系统及时升级更新的需要;
+* 系统支持内容模型、多语言、自定义表单、筛选、多条件搜索、小程序、APP等功能;
+* 系统支持多种URL模式及模型、栏目、内容自定义地址名称,满足各类网站推广优化的需要。
+
+##  简单到想哭的模板标签:
+```
+1、全局标签示意:
+{pboot:sitetitle} 站点标题 
+{pboot:sitelogo} 站点logo
+
+2、列表页标签示意:
+{pboot:list num=10 order=date}
+	<p><a href="[list:link]">[list:title]</a></p>
+{/pboot:list}
+
+3、内容页标签示意:
+{content:title} 标题
+{content:subtitle}副标题
+{content:author} 作者
+{content:source} 来源
+
+更多简单到想哭的标签请参考开发手册...
+
+```
+
+##  主要功能:
+* 支持自定义模板
+* 支持站点信息后台配置
+* 支持无限极栏目
+* 支持自定义内容模型
+* 支持自定义内容字段
+* 支持专题单页内容
+* 支持列表内容管理
+* 支持内容复制移动
+* 支持自定义栏目地址
+* 支持自定义内容地址
+* 支持多语言区域建站
+* 支持手机独立模板
+* 支持手机版域名绑定
+* 支持首页分页
+* 支持页面SEO优化
+* 支持在线留言
+* 支持幻N组灯片轮播
+* 支持友情链接
+* 支持自定义表单
+* 支持多条件筛选
+* 支持多条件搜索
+* 支持验证码开关
+* 支持留言发送到多邮箱
+* 支持API对接
+* 支持小程序/APP开发
+* 支持Ajax远程获取数据
+* 支持自定义标签
+* 支持全站伪静态
+* 支持前端动态缓存
+* 支持系统角色管理
+* 支持完整角色权限管理
+* 支持多用户在线管理
+* 支持系统日志功能
+* 支持数据库在线管理
+* 支持后台在线升级
+* 支持自定义URL模式
+
+##  系统安装:
+
+发布的源码默认采用sqlite数据库,放入PHP(7.0+)空间即可直接使用(不支持php8.0)。 
+
+如果需要启用Mysql版本,请导入目录下数据库文件/static/backup/sql/xxx.sql,同时请注意使用最新日期名字的脚本文件,并修改config/database数据库连接文件信息。
+
+系统后台默认访问路径:http://ip/admin.php   账号:admin   密码:123456,
+
+
+##  升级说明:
+
+* 使用后台在线升级(推荐):
+
+支持跨版本升级,会自动升级数据库及代码文件。
+
+* 使用全包升级:
+
+支持跨版本升级,保留config、data、static、template目录,其余全部用新版替换, 同时如果涉及到的中间版本有升级数据库,需要使用群文件数据库脚本升级数据库。
+
+
+##  授权声明:
+1、PbootCMS是免费可商用的建站系统,用户通过官网获取免费域名授权码即算授权成功,并且永久有效。对于已经授权的域名也不存在未来收费的说法,大家可以放心使用。
+
+2、PbootCMS系统允许个人或公司进行任意二开及商用,但是不允许任何形式的破解或绕过系统授权的行为,包括但不限于通过PbootCMS系统建设网站、二次开发、发布衍生版本等情况,对于任何破解或绕过PbootCMS官网授权的行为,我们将保留依法追究法律责任的权力。
+
+3、PbootCMS除了一个授权文件代码外,其它代码全部开源,并使用Apache2开源协议。对于任何基于PbootCMS进行二开的系统,应该遵守Apache2开源协议的有关要求。
+
+4、PbootCMS官方不对使用本软件所构建网站中的文章、商品和其它任何信息承担责任,不管您通过任何渠道下载本软件,您一旦开始安装PbootCMS,即被视为完全理解并接受PbootCMS授权声明的各项条款。
+
+##  联系我们:
+官方网站:https://www.pbootcms.com/
+
+Gitee:https://gitee.com/hnaoyun/PbootCMS 

+ 26 - 0
api.php

@@ -0,0 +1,26 @@
+<?php
+/**
+ * @copyright (C)2016-2099 Hnaoyun Inc.
+ * @author XingMeng
+ * @email hnxsh@foxmail.com
+ * @date 2016年11月5日
+ *  API入口文件
+ */
+
+// 定义为入口文件
+define('IS_INDEX', true);
+
+// 入口文件地址绑定
+define('URL_BIND', 'api');
+
+// PHP版本检测
+if (PHP_VERSION < '5.3') {
+    echo json_encode(array(
+        'code' => 0,
+        'data' => 'The version of your server PHP is too low, and the program requires PHP version not less than 5.3.'
+    ));
+    exit();
+}
+
+// 引用内核启动文件
+require dirname(__FILE__) . '/core/start.php';

+ 391 - 0
apps/admin/controller/IndexController.php

@@ -0,0 +1,391 @@
+<?php
+/**
+ * @copyright (C)2016-2099 Hnaoyun Inc.
+ * @author XingMeng
+ * @email hnxsh@foxmail.com
+ * @date 2017年3月13日
+ *  默认主页
+ */
+namespace app\admin\controller;
+
+use core\basic\Controller;
+use app\admin\model\IndexModel;
+
+class IndexController extends Controller
+{
+
+    private $model;
+
+    public function __construct()
+    {
+        $this->model = new IndexModel();
+    }
+
+    // 登录页面
+    public function index()
+    {
+        if (session('sid')) {
+            location(url('admin/Index/home'));
+        }
+        $this->assign('admin_check_code', $this->config('admin_check_code'));
+        $this->display('index.html');
+    }
+
+    // 主页面
+    public function home()
+    {
+        // 手动修改数据名称
+        if (get('action') == 'moddb') {
+            if ($this->modDB()) {
+                alert_back('修改成功!');
+            } else {
+                alert_back('修改失败!');
+            }
+        }
+
+        // 删除修改后老数据库(上一步无法直接修改删除)
+        if (issetSession('deldb')) {
+            @unlink(ROOT_PATH . session('deldb'));
+            unset($_SESSION['deldb']);
+        }
+
+        $dbsecurity = true;
+        // 如果是sqlite数据库,并且路径为默认的,则标记为不安全
+        if (get_db_type() == 'sqlite') {
+            // 数据库配置含有默认名字则进行修改
+            if (strpos($this->config('database.dbname'), 'pbootcms') !== false) {
+                if (get_user_ip() != '127.0.0.1' && $this->modDB()) { // 非本地测试时尝试自动修改数据库名称
+                    $dbsecurity = true;
+                } else {
+                    $dbsecurity = false;
+                }
+            } elseif (file_exists(ROOT_PATH . '/data/pbootcms.db')) { // 存在多余的默认数据库文件则改名
+                rename(ROOT_PATH . '/data/pbootcms.db', ROOT_PATH . '/data/' . get_uniqid() . '.db');
+            }
+        } elseif (file_exists(ROOT_PATH . '/data/pbootcms.db')) {
+            rename(ROOT_PATH . '/data/pbootcms.db', ROOT_PATH . '/data/' . get_uniqid() . '.db');
+        }
+
+        $this->assign('dbsecurity', $dbsecurity);
+
+        if (!session('pwsecurity')) {
+            location(url('/admin/Index/ucenter'));
+        }
+
+        $this->assign('server', get_server_info());
+        $this->assign('branch', $this->config('upgrade_branch') == '3.X.dev' ? '3.X.dev' : '3.X');
+        $this->assign('revise', $this->config('revise_version') ?: '0');
+        $this->assign('snuser', $this->config('sn_user') ?: '0');
+        $this->assign('site', get_http_url());
+
+        $this->assign('user_info', $this->model->getUserInfo(session('ucode')));
+
+        $this->assign('sum_msg', model('admin.content.Message')->getCount());
+
+        // 内容模型菜单
+        $model = model('admin.content.Model');
+        $models = $model->getModelMenu();
+        foreach ($models as $key => $value) {
+            $models[$key]->count = $model->getModelCount($value->mcode)->count;
+        }
+
+        $this->assign('model_msg', $models);
+        $this->display('system/home.html');
+    }
+
+    // 异步登录验证
+    public function login()
+    {
+        if (!$_POST) {
+            return;
+        }
+
+        // 在安装了gd库时才执行验证码验证
+        if (extension_loaded("gd") && $this->config('admin_check_code') && strtolower(post('checkcode', 'var')) != session('checkcode')) {
+            json(0, '验证码错误!');
+        }
+
+        // 就收数据
+        $username = post('username');
+        $password = post('password');
+
+        if (!preg_match('/^[\x{4e00}-\x{9fa5}\w\-\.@]+$/u', $username)) {
+            json(0, '用户名含有不允许的特殊字符!');
+        }
+
+        if (!$username) {
+            json(0, '用户名不能为空!');
+        }
+
+        if (!$password) {
+            json(0, '密码不能为空!');
+        }
+
+        if (!!$time = $this->checkLoginBlack()) {
+            $this->log('登录锁定!');
+            json(0, '您登录失败次数太多已被锁定,请' . $time . '秒后再试!');
+        }
+
+        // 执行用户登录
+        $where = array(
+            'username' => $username,
+            'password' => encrypt_string($password)
+        );
+
+        // 判断数据库写入权限
+        if ((get_db_type() == 'sqlite') && !is_writable(ROOT_PATH . $this->config('database.dbname'))) {
+            json(0, '数据库目录写入权限不足!');
+        }
+
+        if (!!$login = $this->model->login($where)) {
+
+            session_regenerate_id(true);
+            session('sid', encrypt_string(session_id() . $login->id)); // 会话标识
+            session('M', M);
+
+            session('id', $login->id); // 用户id
+            session('ucode', $login->ucode); // 用户编码
+            session('username', $login->username); // 用户名
+            session('realname', $login->realname); // 真实名字
+
+            if ($where['password'] != '14e1b600b1fd579f47433b88e8d85291') {
+                session('pwsecurity', true);
+            }
+
+            session('acodes', $login->acodes); // 用户管理区域
+            if ($login->acodes) { // 当前显示区域
+                session('acode', $login->acodes[0]);
+            } else {
+                session('acode', '');
+            }
+
+            session('rcodes', $login->rcodes); // 用户角色代码表
+            session('levels', $login->levels); // 用户权限URL列表
+            session('menu_tree', $login->menus); // 菜单树
+            session('area_map', $login->area_map); // 区域代码名称映射表
+            session('area_tree', $login->area_tree); // 用户区域树
+
+            $this->log('登录成功!');
+            json(1, url('admin/Index/home'));
+        } else {
+            $this->setLoginBlack();
+            $this->log('登录失败!');
+            session('checkcode', mt_rand(10000, 99999)); // 登录失败,随机打乱原有验证码
+            json(0, '用户名或密码错误!');
+        }
+    }
+
+    // 退出登录
+    public function loginOut()
+    {
+        session_unset();
+        location(url('/admin/Index/index'));
+    }
+
+    // 用户中心,修改密码
+    public function ucenter()
+    {
+        if ($_POST) {
+            $username = post('username'); // 用户名
+            $realname = post('realname'); // 真实姓名
+            $cpassword = post('cpassword'); // 现在密码
+            $password = post('password'); // 新密码
+            $rpassword = post('rpassword'); // 确认密码
+
+            if (!$username) {
+                alert_back('用户名不能为空!');
+            }
+            if (!$cpassword) {
+                alert_back('当前密码不能为空!');
+            }
+
+            if (!preg_match('/^[\x{4e00}-\x{9fa5}\w\-\.@]+$/u', $username)) {
+                alert_back('用户名含有不允许的特殊字符!');
+            }
+
+            $data = array(
+                'username' => $username,
+                'realname' => $realname,
+                'update_user' => $username
+            );
+
+            // 如果有修改密码,则添加数据
+            if ($password) {
+                if ($password != $rpassword) {
+                    alert_back('确认密码不正确!');
+                }
+                $data['password'] = encrypt_string($password);
+                if ($data['password'] != '14e1b600b1fd579f47433b88e8d85291') {
+                    session('pwsecurity', true);
+                } else {
+                    session('pwsecurity', false);
+                }
+            }
+
+            // 检查现有密码
+            if ($this->model->checkUserPwd(encrypt_string($cpassword))) {
+                if ($this->model->modUserInfo($data)) {
+                    session('username', post('username'));
+                    session('realname', post('realname'));
+                    $this->log('用户资料成功!');
+                    success('用户资料修改成功!', -1);
+                }
+            } else {
+                $this->log('用户资料修改时当前密码错误!');
+                alert_location('当前密码错误!', -1);
+            }
+        }
+        $this->display('system/ucenter.html');
+    }
+
+    // 切换显示的数据区域
+    public function area()
+    {
+        if ($_POST) {
+            $acode = post('acode');
+            if (in_array($acode, session('acodes'))) {
+                session('acode', $acode);
+                cookie('lg', $acode); // 同步切换前台语言
+            }
+            location(url('admin/Index/home'));
+        }
+    }
+
+    // 清理缓存
+    public function clearCache()
+    {
+        if (get('delall')) {
+            $rs = path_delete(RUN_PATH);
+        } else {
+            $rs = (path_delete(RUN_PATH . '/cache') && path_delete(RUN_PATH . '/complile') && path_delete(RUN_PATH . '/config') && path_delete(RUN_PATH . '/upgrade'));
+        }
+        cache_config(); // 清理缓存后立即生成新的配置
+        if ($rs) {
+            if (extension_loaded('Zend OPcache')) {
+                opcache_reset(); // 在启用了OPcache加速器时同时清理
+            }
+            $this->log('清理缓存成功!');
+            alert_back('清理缓存成功!', 1);
+        } else {
+            $this->log('清理缓存失败!');
+            alert_back('清理缓存失败!', 0);
+        }
+    }
+	
+	// 清理系统缓存
+    public function clearOnlySysCache()
+    {
+        if (get('delall')) {
+            $rs = path_delete(RUN_PATH);
+        } else {
+            $rs = (path_delete(RUN_PATH . '/complile') && path_delete(RUN_PATH . '/config') && path_delete(RUN_PATH . '/upgrade'));
+        }
+        cache_config(); // 清理缓存后立即生成新的配置
+        if ($rs) {
+            if (extension_loaded('Zend OPcache')) {
+                opcache_reset(); // 在启用了OPcache加速器时同时清理
+            }
+            $this->log('清理缓存成功!');
+            alert_back('清理缓存成功!', 1);
+        } else {
+            $this->log('清理缓存失败!');
+            alert_back('清理缓存失败!', 0);
+        }
+    }
+	
+    // 清理会话
+    public function clearSession()
+    {
+        ignore_user_abort(true); // 后台运行
+        set_time_limit(7200);
+        ob_start();
+        $output['code'] = 1;
+        $output['data'] = '执行成功,后台自动清理中!';
+        $output['tourl'] = '';
+        echo json_encode($output);
+        ob_end_flush();
+        flush();
+        $rs = path_delete(RUN_PATH . '/session', false, array(
+            'sess_' . session_id()
+        ));
+    }
+
+    // 文件上传方法
+    public function upload()
+    {
+        $upload = upload('upload');
+        if (is_array($upload)) {
+            json(1, $upload);
+        } else {
+            json(0, $upload);
+        }
+    }
+
+    // 检查是否在黑名单
+    private function checkLoginBlack()
+    {
+        // 读取黑名单
+        $ip_black = RUN_PATH . '/data/' . md5('login_black') . '.php';
+        if (file_exists($ip_black)) {
+            $data = require $ip_black;
+            $user_ip = get_user_ip();
+            $lock_time = $this->config('lock_time') ?: 900;
+            $lock_count = $this->config('lock_count') ?: 5;
+            if (isset($data[$user_ip]) && $data[$user_ip]['count'] >= $lock_count && time() - $data[$user_ip]['time'] < $lock_time) {
+                return $lock_time - (time() - $data[$user_ip]['time']); // 返回剩余秒数
+            }
+        }
+        return false;
+    }
+
+    // 添加登录黑名单
+    private function setLoginBlack()
+    {
+        // 读取黑名单
+        $ip_black = RUN_PATH . '/data/' . md5('login_black') . '.php';
+        if (file_exists($ip_black)) {
+            $data = require $ip_black;
+        } else {
+            $data = array();
+        }
+
+        // 添加IP
+        $user_ip = get_user_ip();
+        $lock_time = $this->config('lock_time') ?: 900;
+        $lock_count = $this->config('lock_count') ?: 5;
+        if (isset($data[$user_ip]) && $data[$user_ip]['count'] < $lock_count && time() - $data[$user_ip]['time'] < $lock_time) {
+            $data[$user_ip] = array(
+                'time' => time(),
+                'count' => $data[get_user_ip()]['count'] + 1
+            );
+        } else {
+            $data[$user_ip] = array(
+                'time' => time(),
+                'count' => 1
+            );
+        }
+
+        // 写入黑名单
+        check_file($ip_black, true);
+        return file_put_contents($ip_black, "<?php\nreturn " . var_export($data, true) . ";");
+    }
+
+    // 修改数据库名称
+    private function modDB()
+    {
+        $file = CONF_PATH . '/database.php';
+        $sname = $this->config('database.dbname');
+        $dname = '/data/' . get_uniqid() . '.db';
+        $sconfig = file_get_contents($file);
+        $dconfig = str_replace($sname, $dname, $sconfig);
+        if (file_put_contents($file, $dconfig)) {
+            if (!copy(ROOT_PATH . $sname, ROOT_PATH . $dname)) {
+                file_put_contents($file, $sconfig); // 回滚配置
+            } else {
+                session('deldb', $sname);
+                return true;
+            }
+        }
+        return false;
+    }
+}

+ 70 - 0
apps/admin/controller/content/CompanyController.php

@@ -0,0 +1,70 @@
+<?php
+/**
+ * @copyright (C)2016-2099 Hnaoyun Inc.
+ * @author XingMeng
+ * @email hnxsh@foxmail.com
+ * @date 2017年04月17日
+ *  公司设置控制器 
+ */
+namespace app\admin\controller\content;
+
+use core\basic\Controller;
+use app\admin\model\content\CompanyModel;
+
+class CompanyController extends Controller
+{
+
+    private $model;
+
+    public function __construct()
+    {
+        $this->model = new CompanyModel();
+    }
+
+    // 显示公司设置
+    public function index()
+    {
+        // 获取公司配置
+        $this->assign('companys', $this->model->getList());
+        $this->display('content/company.html');
+    }
+
+    // 修改公司设置
+    public function mod()
+    {
+        if (! $_POST) {
+            return;
+        }
+        $data = array(
+            'name' => post('name'),
+            'address' => post('address'),
+            'postcode' => post('postcode'),
+            'contact' => post('contact'),
+            'mobile' => post('mobile'),
+            'phone' => post('phone'),
+            'fax' => post('fax'),
+            'email' => post('email'),
+            'qq' => post('qq'),
+            'weixin' => post('weixin'),
+            'blicense' => post('blicense'),
+            'other' => post('other')
+        );
+        
+        if ($this->model->checkCompany()) {
+            if ($this->model->modCompany($data)) {
+                $this->log('修改公司信息成功!');
+                success('修改成功!', - 1);
+            } else {
+                location(- 1);
+            }
+        } else {
+            $data['acode'] = session('acode');
+            if ($this->model->addCompany($data)) {
+                $this->log('修改公司信息成功!');
+                success('修改成功!', - 1);
+            } else {
+                location(- 1);
+            }
+        }
+    }
+}

+ 563 - 0
apps/admin/controller/content/ContentController.php

@@ -0,0 +1,563 @@
+<?php
+/**
+ * @copyright (C)2016-2099 Hnaoyun Inc.
+ * @author XingMeng
+ * @email hnxsh@foxmail.com
+ * @date  2017年12月15日
+ *  文章控制器
+ */
+namespace app\admin\controller\content;
+
+use core\basic\Controller;
+use app\admin\model\content\ContentModel;
+
+class ContentController extends Controller
+{
+
+    private $model;
+
+    private $blank;
+
+    public function __construct()
+    {
+        $this->model = new ContentModel();
+    }
+
+    // 文章列表
+    public function index()
+    {
+        if ((! ! $id = get('id', 'int')) && $result = $this->model->getContent($id)) {
+            $this->assign('more', true);
+            $this->assign('content', $result);
+        } else {
+            $this->assign('list', true);
+            if (! $mcode = get('mcode', 'var')) {
+                error('传递的模型编码参数有误,请核对后重试!');
+            }
+            
+            if (isset($_GET['keyword'])) {
+                if (! ! $scode = get('scode', 'var')) {
+                    $result = $this->model->findContent($mcode, $scode, get('keyword', 'vars'));
+                } else {
+                    $result = $this->model->findContentAll($mcode, get('keyword', 'vars'));
+                }
+            } elseif (! ! $scode = get('scode', 'int')) {
+                $result = $this->model->findContent($mcode, $scode, '');
+            } else {
+                $result = $this->model->getList($mcode);
+            }
+            $this->assign('contents', $result);
+            
+            // 文章分类下拉列表
+            $sort_model = model('admin.content.ContentSort');
+            $sort_select = $sort_model->getListSelect($mcode);
+            $this->assign('search_select', $this->makeSortSelect($sort_select, get('scode')));
+            $this->assign('sort_select', $this->makeSortSelect($sort_select, session('addscode')));
+            $this->assign('subsort_select', $this->makeSortSelect($sort_select));
+            
+            // 模型名称
+            $this->assign('model_name', model('admin.content.Model')->getName($mcode));
+            
+            // 扩展字段
+            $this->assign('extfield', model('admin.content.ExtField')->getModelField($mcode));
+            
+            $this->assign('baidu_zz_token', $this->config('baidu_zz_token'));
+            $this->assign('baidu_ks_token', $this->config('baidu_ks_token'));
+            
+            // 前端地址连接符判断
+            $url_break_char = $this->config('url_break_char') ?: '_';
+            $this->assign('url_break_char', $url_break_char);
+            
+            // 获取会员分组
+            $this->assign('groups', model('admin.member.MemberGroup')->getSelect());
+        }
+        
+        $this->display('content/content.html');
+    }
+
+    // 文章增加
+    public function add()
+    {
+        if ($_POST) {
+            
+            // 获取数据
+            $scode = post('scode');
+            $subscode = post('subscode');
+            $title = post('title');
+            $titlecolor = post('titlecolor');
+            $subtitle = post('subtitle');
+            $filename = trim(post('filename'), '/');
+            $author = post('author');
+            $source = post('source');
+            $outlink = post('outlink');
+            $date = post('date');
+            $ico = post('ico');
+            $pics = post('pics');
+            
+            // 获取多图标题
+            $picstitle = post('picstitle');
+            if ($picstitle) {
+                $picstitle = implode(',', $picstitle);
+            }
+            
+            $content = post('content');
+            $tags = str_replace(',', ',', post('tags'));
+            $enclosure = post('enclosure');
+            $keywords = post('keywords');
+            $description = post('description');
+            $status = post('status', 'int');
+            $istop = post('istop', 'int', '', '', 0);
+            $isrecommend = post('isrecommend', 'int', '', '', 0);
+            $isheadline = post('isheadline', 'int', '', '', 0);
+            
+            $gid = post('gid', 'int') ?: 0;
+            $gtype = post('gtype', 'int') ?: 4;
+            $gnote = post('gnote');
+            
+            if (! $scode) {
+                alert_back('内容分类不能为空!');
+            }
+            
+            if (! $title) {
+                alert_back('文章标题不能为空!');
+            }
+            
+            if ($filename && ! preg_match('/^[a-zA-Z0-9\-_\/]+$/', $filename)) {
+                alert_back('内容URL名称只允许字母、数字、横线、下划线组成!');
+            }
+            
+            // 自动提起前一百个字符为描述
+            if (! $description && isset($_POST['content'])) {
+                $description = escape_string(clear_html_blank(substr_both(strip_tags($_POST['content']), 0, 150)));
+            }
+            
+            // 无缩略图时,自动提取文章第一张图为缩略图
+            if (! $ico && preg_match('/<img\s+.*?src=\s?[\'|\"](.*?(\.gif|\.jpg|\.png|\.jpeg))[\'|\"].*?[\/]?>/i', decode_string($content), $srcs) && isset($srcs[1])) {
+                $ico = $srcs[1];
+            }
+            
+            // 缩放缩略图
+            if ($ico) {
+                resize_img(ROOT_PATH . $ico, '', $this->config('ico.max_width'), $this->config('ico.max_height'));
+            }
+            
+            // 检查自定义URL名称
+            if ($filename) {
+                while ($this->model->checkFilename($filename)) {
+                    $filename = $filename . '-' . mt_rand(1, 20);
+                }
+            }
+            
+            // 记住新增栏目
+            session('addscode', $scode);
+            
+            // 构建数据
+            $data = array(
+                'acode' => session('acode'),
+                'scode' => $scode,
+                'subscode' => $subscode,
+                'title' => $title,
+                'titlecolor' => $titlecolor,
+                'subtitle' => $subtitle,
+                'filename' => $filename,
+                'author' => $author,
+                'source' => $source,
+                'outlink' => $outlink,
+                'date' => $date,
+                'ico' => $ico,
+                'pics' => $pics,
+                'picstitle' => $picstitle,
+                'content' => $content,
+                'tags' => $tags,
+                'enclosure' => $enclosure,
+                'keywords' => $keywords,
+                'description' => clear_html_blank($description),
+                'sorting' => 255,
+                'status' => $status,
+                'istop' => $istop,
+                'isrecommend' => $isrecommend,
+                'isheadline' => $isheadline,
+                'gid' => $gid,
+                'gtype' => $gtype,
+                'gnote' => $gnote,
+                'visits' => 0,
+                'likes' => 0,
+                'oppose' => 0,
+                'create_user' => session('username'),
+                'update_user' => session('username')
+            );
+            
+            // 执行添加
+            if (! ! $id = $this->model->addContent($data)) {
+                // 扩展内容添加
+                foreach ($_POST as $key => $value) {
+                    if (preg_match('/^ext_[\w\-]+$/', $key)) {
+                        if (! isset($data2['contentid'])) {
+                            $data2['contentid'] = $id;
+                        }
+                        $temp = post($key);
+                        if (is_array($temp)) {
+                            $data2[$key] = implode(',', $temp);
+                        } else {
+                            $data2[$key] = str_replace("\r\n", '<br>', $temp);
+                        }
+                    }
+                }
+                if (isset($data2)) {
+                    if (! $this->model->addContentExt($data2)) {
+                        $this->model->delContent($id);
+                        $this->log('新增文章失败!');
+                        error('新增失败!', - 1);
+                    }
+                }
+                
+                $this->log('新增文章成功!');
+                if (! ! $backurl = get('backurl')) {
+                    success('新增成功!', base64_decode($backurl));
+                } else {
+                    success('新增成功!', url('/admin/Content/index/mcode/' . get('mcode')));
+                }
+            } else {
+                $this->log('新增文章失败!');
+                error('新增失败!', - 1);
+            }
+        }
+    }
+
+    // 生成分类选择
+    private function makeSortSelect($tree, $selectid = null)
+    {
+        $list_html = '';
+        foreach ($tree as $value) {
+            // 默认选择项
+            if ($selectid == $value->scode) {
+                $select = "selected='selected'";
+            } else {
+                $select = '';
+            }
+            $list_html .= "<option value='{$value->scode}' $select>{$this->blank}{$value->name}";
+            // 子菜单处理
+            if ($value->son) {
+                $this->blank .= '  ';
+                $list_html .= $this->makeSortSelect($value->son, $selectid);
+            }
+        }
+        // 循环完后回归位置
+        $this->blank = substr($this->blank, 0, - 6);
+        return $list_html;
+    }
+
+    // 文章删除
+    public function del()
+    {
+        // 执行批量删除
+        if ($_POST) {
+            if (! ! $list = post('list')) {
+                if ($this->model->delContentList($list)) {
+                    $this->model->delContentExtList($list);
+                    $this->log('批量删除文章成功!');
+                    success('批量删除成功!', - 1);
+                } else {
+                    $this->log('批量删除文章失败!');
+                    error('批量删除失败!', - 1);
+                }
+            } else {
+                alert_back('请选择要删除的内容!');
+            }
+        }
+        
+        if (! $id = get('id', 'int')) {
+            error('传递的参数值错误!', - 1);
+        }
+        
+        if ($this->model->delContent($id)) {
+            $this->model->delContentExt($id);
+            $this->log('删除文章' . $id . '成功!');
+            success('删除成功!', - 1);
+        } else {
+            $this->log('删除文章' . $id . '失败!');
+            error('删除失败!', - 1);
+        }
+    }
+
+    // 文章修改
+    public function mod()
+    {
+        if (! ! $submit = post('submit')) {
+            switch ($submit) {
+                case 'sorting': // 修改列表排序
+                    $listall = post('listall');
+                    if ($listall) {
+                        $sorting = post('sorting');
+                        foreach ($listall as $key => $value) {
+                            if ($sorting[$key] === '' || ! is_numeric($sorting[$key]))
+                                $sorting[$key] = 255;
+                            $this->model->modContent($value, "sorting=" . $sorting[$key]);
+                        }
+                        $this->log('修改内容排序成功!');
+                        success('修改成功!', - 1);
+                    } else {
+                        alert_back('排序失败,无任何内容!');
+                    }
+                    break;
+                case 'copy':
+                    $list = post('list');
+                    $scode = post('scode');
+                    if (! $list) {
+                        alert_back('请选择要复制的内容!');
+                    }
+                    if (! $scode) {
+                        alert_back('请选择目标栏目!');
+                    }
+                    if ($this->model->copyContent($list, $scode)) {
+                        $this->log('复制内容成功!');
+                        success('复制内容成功!', - 1);
+                    } else {
+                        alert_back('复制内容失败!');
+                    }
+                    break;
+                case 'move':
+                    $list = post('list');
+                    $scode = post('scode');
+                    if (! $list) {
+                        alert_back('请选择要移动的内容!');
+                    }
+                    if (! $scode) {
+                        alert_back('请选择目标栏目!');
+                    }
+                    
+                    if ($this->model->modContent($list, "scode='" . $scode . "'")) {
+                        $this->log('移动内容成功!');
+                        success('移动内容成功!', - 1);
+                    } else {
+                        alert_back('移动内容失败!');
+                    }
+                    break;
+                case 'baiduzz':
+                    $list = post('list');
+                    $urls = post('urls');
+                    if (! $list) {
+                        alert_back('请选择要推送的内容!');
+                    }
+                    // 依次推送
+                    $domain = get_http_url();
+                    if (! $token = $this->config('baidu_zz_token')) {
+                        alert_back('请先到系统配置中填写百度普通收录推送token值!');
+                    }
+                    $api = "http://data.zz.baidu.com/urls?site=$domain&token=$token";
+                    foreach ($list as $key => $value) {
+                        $url = $domain . $urls[$value];
+                        $this->log('百度普通收录推送:' . $url);
+                        $post_urls[] = $url;
+                    }
+                    $result = post_baidu($api, $post_urls);
+                    if (isset($result->error)) {
+                        alert_back('百度普通收录推送发生错误:' . $result->message);
+                    } elseif (isset($result->success)) {
+                        alert_back('成功推送' . $result->success . '条,今天剩余可推送' . $result->remain . '条数!');
+                    } else {
+                        alert_back('发生未知错误!');
+                    }
+                case 'baiduks':
+                    $list = post('list');
+                    $urls = post('urls');
+                    if (! $list) {
+                        alert_back('请选择要推送的内容!');
+                    }
+                    // 依次推送
+                    $domain = get_http_url();
+                    if (! $token = $this->config('baidu_ks_token')) {
+                        alert_back('请先到系统配置中填写百度快速收录推送token值!');
+                    }
+                    $api = "http://data.zz.baidu.com/urls?site=$domain&token=$token&type=daily";
+                    foreach ($list as $key => $value) {
+                        $url = $domain . $urls[$value];
+                        $this->log('百度快速收录推送:' . $url);
+                        $post_urls[] = $url;
+                    }
+                    $result = post_baidu($api, $post_urls);
+                    if (isset($result->error)) {
+                        alert_back('百度快速收录推送发生错误:' . $result->message);
+                    } elseif (isset($result->success_daily)) {
+                        alert_back('成功推送' . $result->success_daily . '条,今天剩余可推送' . $result->remain_daily . '条数!');
+                    } else {
+                        alert_back('发生未知错误!');
+                    }
+            }
+        }
+        
+        if (! $id = get('id', 'int')) {
+            error('传递的参数值错误!', - 1);
+        }
+        
+        // 单独修改状态
+        if (($field = get('field', 'var')) && ! is_null($value = get('value', 'var'))) {
+            if ($this->model->modContent($id, "$field='$value',update_user='" . session('username') . "'")) {
+                location(- 1);
+            } else {
+                alert_back('修改失败!');
+            }
+        }
+        
+        // 修改操作
+        if ($_POST) {
+            
+            // 获取数据
+            $scode = post('scode');
+            $subscode = post('subscode');
+            $title = post('title');
+            $titlecolor = post('titlecolor');
+            $subtitle = post('subtitle');
+            $filename = trim(post('filename'), '/');
+            $author = post('author');
+            $source = post('source');
+            $outlink = post('outlink');
+            $date = post('date');
+            $ico = post('ico');
+            $pics = post('pics');
+            
+            // 获取多图标题
+            $picstitle = post('picstitle');
+            if ($picstitle) {
+                $picstitle = implode(',', $picstitle);
+            }
+            
+            $content = post('content');
+            $tags = str_replace(',', ',', post('tags'));
+            $enclosure = post('enclosure');
+            $keywords = post('keywords');
+            $description = post('description');
+            $status = post('status', 'int');
+            $istop = post('istop', 'int', '', '', 0);
+            $isrecommend = post('isrecommend', 'int', '', '', 0);
+            $isheadline = post('isheadline', 'int', '', '', 0);
+            
+            $gid = post('gid', 'int') ?: 0;
+            $gtype = post('gtype', 'int') ?: 4;
+            $gnote = post('gnote');
+            
+            if (! $scode) {
+                alert_back('内容分类不能为空!');
+            }
+            
+            if (! $title) {
+                alert_back('文章标题不能为空!');
+            }
+            
+            if ($filename && ! preg_match('/^[a-zA-Z0-9\-_\/]+$/', $filename)) {
+                alert_back('内容URL名称只允许字母、数字、横线、下划线组成!');
+            }
+            
+            // 自动提起前一百个字符为描述
+            if (! $description && isset($_POST['content'])) {
+                $description = escape_string(clear_html_blank(substr_both(strip_tags($_POST['content']), 0, 150)));
+            }
+            
+            // 无缩略图时,自动提取文章第一张图为缩略图
+            if (! $ico && preg_match('/<img\s+.*?src=\s?[\'|\"](.*?(\.gif|\.jpg|\.png|\.jpeg))[\'|\"].*?[\/]?>/i', decode_string($content), $srcs) && isset($srcs[1])) {
+                $ico = $srcs[1];
+            }
+            
+            // 缩放缩略图
+            if ($ico) {
+                resize_img(ROOT_PATH . $ico, '', $this->config('ico.max_width'), $this->config('ico.max_height'));
+            }
+            
+            if ($filename) {
+                while ($this->model->checkFilename($filename, "id<>$id")) {
+                    $filename = $filename . '-' . mt_rand(1, 20);
+                }
+            }
+            
+            // 构建数据
+            $data = array(
+                'scode' => $scode,
+                'subscode' => $subscode,
+                'title' => $title,
+                'titlecolor' => $titlecolor,
+                'subtitle' => $subtitle,
+                'filename' => $filename,
+                'author' => $author,
+                'source' => $source,
+                'outlink' => $outlink,
+                'date' => $date,
+                'ico' => $ico,
+                'pics' => $pics,
+                'picstitle' => $picstitle,
+                'content' => $content,
+                'tags' => $tags,
+                'enclosure' => $enclosure,
+                'keywords' => $keywords,
+                'description' => clear_html_blank($description),
+                'status' => $status,
+                'istop' => $istop,
+                'isrecommend' => $isrecommend,
+                'isheadline' => $isheadline,
+                'gid' => $gid,
+                'gtype' => $gtype,
+                'gnote' => $gnote,
+                'update_user' => session('username')
+            );
+            
+            // 执行添加
+            if ($this->model->modContent($id, $data)) {
+                // 扩展内容修改
+                foreach ($_POST as $key => $value) {
+                    if (preg_match('/^ext_[\w\-]+$/', $key)) {
+                        $temp = post($key);
+                        if (is_array($temp)) {
+                            $data2[$key] = implode(',', $temp);
+                        } else {
+                            $data2[$key] = str_replace("\r\n", '<br>', $temp);
+                        }
+                    }
+                }
+                if (isset($data2)) {
+                    if ($this->model->findContentExt($id)) {
+                        $this->model->modContentExt($id, $data2);
+                    } else {
+                        $data2['contentid'] = $id;
+                        $this->model->addContentExt($data2);
+                    }
+                }
+                
+                $this->log('修改文章' . $id . '成功!');
+                if (! ! $backurl = get('backurl')) {
+                    success('修改成功!', base64_decode($backurl));
+                } else {
+                    success('修改成功!', url('/admin/Content/index/mcode/2'));
+                }
+            } else {
+                location(- 1);
+            }
+        } else {
+            // 调取修改内容
+            $this->assign('mod', true);
+            if (! $result = $this->model->getContent($id)) {
+                error('编辑的内容已经不存在!', - 1);
+            }
+            $this->assign('content', $result);
+            
+            if (! $mcode = get('mcode', 'var')) {
+                error('传递的模型编码参数有误,请核对后重试!');
+            }
+            
+            // 文章分类
+            $sort_model = model('admin.content.ContentSort');
+            $sort_select = $sort_model->getListSelect($mcode);
+            $this->assign('sort_select', $this->makeSortSelect($sort_select, $result->scode));
+            $this->assign('subsort_select', $this->makeSortSelect($sort_select, $result->subscode));
+            
+            // 模型名称
+            $this->assign('model_name', model('admin.content.Model')->getName($mcode));
+            
+            // 扩展字段
+            $this->assign('extfield', model('admin.content.ExtField')->getModelField($mcode));
+            
+            // 获取会员分组
+            $this->assign('groups', model('admin.member.MemberGroup')->getSelect());
+            
+            $this->display('content/content.html');
+        }
+    }
+}

+ 537 - 0
apps/admin/controller/content/ContentSortController.php

@@ -0,0 +1,537 @@
+<?php
+/**
+ * @copyright (C)2016-2099 Hnaoyun Inc.
+ * @author XingMeng
+ * @email hnxsh@foxmail.com
+ * @date 2017年12月26日
+ *  内容栏目控制器
+ */
+namespace app\admin\controller\content;
+
+use core\basic\Controller;
+use app\admin\model\content\ContentSortModel;
+
+class ContentSortController extends Controller
+{
+
+    private $count;
+
+    private $blank;
+
+    private $outData = array();
+
+    private $model;
+
+    public function __construct()
+    {
+        $this->model = new ContentSortModel();
+    }
+
+    // 内容栏目列表
+    public function index()
+    {
+        $this->assign('list', true);
+        $tree = $this->model->getList();
+        $sorts = $this->makeSortList($tree);
+        $this->assign('sorts', $sorts);
+        
+        // 内容模型
+        $models = model('admin.content.Model');
+        $this->assign('allmodels', $models->getSelectAll());
+        $this->assign('models', $models->getSelect());
+        
+        // 内容栏目下拉表
+        $sort_tree = $this->model->getSelect();
+        $sort_select = $this->makeSortSelect($sort_tree);
+        $this->assign('sort_select', $sort_select);
+        
+        // 模板文件
+        $htmldir = $this->config('tpl_html_dir') ? '/' . $this->config('tpl_html_dir') : '';
+        $this->assign('tpls', file_list(ROOT_PATH . current($this->config('tpl_dir')) . '/' . $this->model->getTheme() . $htmldir));
+        
+        // 前端地址连接符判断
+        $url_break_char = $this->config('url_break_char') ?: '_';
+        $this->assign('url_break_char', $url_break_char);
+        
+        // 获取会员分组
+        $this->assign('groups', model('admin.member.MemberGroup')->getSelect());
+        
+        $this->display('content/contentsort.html');
+    }
+
+    // 生成无限级内容栏目列表
+    private function makeSortList($tree)
+    {
+        // 循环生成
+        foreach ($tree as $value) {
+            $this->count ++;
+            $this->outData[$this->count] = new \stdClass();
+            foreach ($value as $k => $v) {
+                $this->outData[$this->count]->$k = $v;
+            }
+            
+            if ($value->son) {
+                $this->outData[$this->count]->son = true;
+            } else {
+                $this->outData[$this->count]->son = false;
+            }
+            
+            // 子菜单处理
+            if ($value->son) {
+                $this->blank .= '  ';
+                $this->makeSortList($value->son);
+            }
+        }
+        
+        // 循环完后回归缩进位置
+        $this->blank = substr($this->blank, 6);
+        return $this->outData;
+    }
+
+    // 内容栏目增加
+    public function add()
+    {
+        if ($_POST) {
+            if (! ! $multiplename = post('multiplename')) {
+                $multiplename = str_replace(',', ',', $multiplename);
+                $pcode = post('pcode', 'var');
+                $type = post('type');
+                $mcode = post('mcode');
+                $listtpl = basename(post('listtpl'));
+                $contenttpl = basename(post('contenttpl'));
+                $status = post('status');
+                
+                if (! $pcode) { // 父编码默认为0
+                    $pcode = 0;
+                }
+                
+                if (! $mcode) {
+                    alert_back('栏目模型必须选择!');
+                }
+                
+                if (! $type) {
+                    alert_back('栏目类型不能为空!');
+                }
+                
+                $names = explode(',', $multiplename);
+                $lastcode = $this->model->getLastCode();
+                $scode = get_auto_code($lastcode);
+                foreach ($names as $key => $value) {
+                    $data[] = array(
+                        'acode' => session('acode'),
+                        'pcode' => $pcode,
+                        'scode' => $scode,
+                        'name' => $value,
+                        'mcode' => $mcode,
+                        'listtpl' => $listtpl,
+                        'contenttpl' => $contenttpl,
+                        'status' => $status,
+                        'gid' => 0,
+                        'gtype' => 4,
+                        'subname' => '',
+                        'filename' => '',
+                        'outlink' => '',
+                        'ico' => '',
+                        'pic' => '',
+                        'title' => '',
+                        'keywords' => '',
+                        'description' => '',
+                        'sorting' => 255,
+                        'create_user' => session('username'),
+                        'update_user' => session('username')
+                    );
+                    $scode = get_auto_code($scode);
+                }
+            } else {
+                // 获取数据
+                $scode = get_auto_code($this->model->getLastCode()); // 自动编码;
+                $pcode = post('pcode', 'var');
+                $name = post('name');
+                $type = post('type');
+                $mcode = post('mcode');
+                $listtpl = basename(post('listtpl'));
+                $contenttpl = basename(post('contenttpl'));
+                $status = post('status');
+                $subname = post('subname');
+                $filename = trim(post('filename'), '/');
+                $outlink = post('outlink');
+                $ico = post('ico');
+                $pic = post('pic');
+                $title = post('title');
+                $keywords = post('keywords');
+                $description = post('description');
+                
+                $gid = post('gid', 'int') ?: 0;
+                $gtype = post('gtype', 'int') ?: 4;
+                $gnote = post('gnote');
+                
+                $def1 = post('def1');
+                $def2 = post('def2');
+                $def3 = post('def3');
+                
+                if (! $scode) {
+                    alert_back('编码不能为空!');
+                }
+                
+                if (! $pcode) { // 父编码默认为0
+                    $pcode = 0;
+                }
+                
+                if (! $name) {
+                    alert_back('栏目名不能为空!');
+                }
+                
+                if (! $mcode) {
+                    alert_back('栏目模型必须选择!');
+                }
+                
+                if (! $type) {
+                    alert_back('栏目类型不能为空!');
+                }
+                
+                if ($filename && ! preg_match('/^[a-zA-Z0-9\-\/]+$/', $filename)) {
+                    alert_back('URL名称只允许字母、数字、横线、斜线组成!');
+                }
+                
+                if ($filename && $this->model->checkUrlname($filename)) {
+                    alert_back('URL名称与模型URL名称冲突,请换一个名称!');
+                }
+                
+                // 缩放缩略图
+                if ($ico) {
+                    resize_img(ROOT_PATH . $ico, '', $this->config('ico.max_width'), $this->config('ico.max_height'));
+                }
+                
+                // 检查编码
+                if ($this->model->checkSort("scode='$scode'")) {
+                    alert_back('该内容栏目编号已经存在,不能再使用!');
+                }
+                
+                // 检查自定义URL名称
+                if ($filename) {
+                    while ($this->model->checkFilename($filename)) {
+                        $filename = $filename . '_' . mt_rand(1, 20);
+                    }
+                }
+                
+                // 构建数据
+                $data = array(
+                    'acode' => session('acode'),
+                    'pcode' => $pcode,
+                    'scode' => $scode,
+                    'name' => $name,
+                    'mcode' => $mcode,
+                    'listtpl' => $listtpl,
+                    'contenttpl' => $contenttpl,
+                    'status' => $status,
+                    'gid' => $gid,
+                    'gtype' => $gtype,
+                    'gnote' => $gnote,
+                    'subname' => $subname,
+                    'def1' => $def1,
+                    'def2' => $def2,
+                    'def3' => $def3,
+                    'filename' => $filename,
+                    'outlink' => $outlink,
+                    'ico' => $ico,
+                    'pic' => $pic,
+                    'title' => $title,
+                    'keywords' => $keywords,
+                    'description' => $description,
+                    'sorting' => 255,
+                    'create_user' => session('username'),
+                    'update_user' => session('username')
+                );
+            }
+            
+            // 执行添加
+            if ($this->model->addSort($data)) {
+                if ($type == 1 && ! $outlink) { // 在填写了外链时不生成单页
+                    if ($multiplename) {
+                        foreach ($data as $key => $value) {
+                            $this->addSingle($value['scode'], $value['name']);
+                        }
+                    } else {
+                        $this->addSingle($scode, $name);
+                    }
+                }
+                $this->log('新增数据内容栏目' . $scode . '成功!');
+                success('新增成功!', url('/admin/ContentSort/index'));
+            } else {
+                $this->log('新增数据内容栏目' . $scode . '失败!');
+                error('新增失败!', - 1);
+            }
+        }
+    }
+
+    // 生成内容栏目下拉选择
+    private function makeSortSelect($tree, $selectid = null)
+    {
+        $list_html = '';
+        foreach ($tree as $value) {
+            // 默认选择项
+            if ($selectid == $value->scode) {
+                $select = "selected='selected'";
+            } else {
+                $select = '';
+            }
+            if (get('scode') != $value->scode) { // 不显示本身,避免出现自身为自己的父节点
+                $list_html .= "<option value='{$value->scode}' $select>{$this->blank}{$value->name}</option>";
+            }
+            // 子菜单处理
+            if ($value->son) {
+                $this->blank .= '  ';
+                $list_html .= $this->makeSortSelect($value->son, $selectid);
+            }
+        }
+        // 循环完后回归位置
+        $this->blank = substr($this->blank, 0, - 6);
+        return $list_html;
+    }
+
+    // 内容栏目删除
+    public function del()
+    {
+        // 执行批量删除
+        if ($_POST) {
+            if (! ! $list = post('list')) {
+                if ($this->model->delSortList($list)) {
+                    $this->log('批量删除栏目成功!');
+                    success('批量删除成功!', - 1);
+                } else {
+                    $this->log('批量删除栏目失败!');
+                    error('批量删除失败!', - 1);
+                }
+            } else {
+                alert_back('请选择要删除的栏目!');
+            }
+        }
+        
+        if (! $scode = get('scode', 'var')) {
+            error('传递的参数值错误!', - 1);
+        }
+        if ($this->model->delSort($scode)) {
+            $this->log('删除数据内容栏目' . $scode . '成功!');
+            success('删除成功!', - 1);
+        } else {
+            $this->log('删除数据内容栏目' . $scode . '失败!');
+            error('删除失败!', - 1);
+        }
+    }
+
+    // 内容栏目修改
+    public function mod()
+    {
+        if (! ! $submit = post('submit')) {
+            switch ($submit) {
+                case 'sorting': // 修改列表排序
+                    $listall = post('listall');
+                    if ($listall) {
+                        $sorting = post('sorting');
+                        foreach ($listall as $key => $value) {
+                            if ($sorting[$key] === '' || ! is_numeric($sorting[$key]))
+                                $sorting[$key] = 255;
+                            $this->model->modSortSorting($value, "sorting=" . $sorting[$key]);
+                        }
+                        $this->log('批量修改栏目排序成功!');
+                        success('修改成功!', - 1);
+                    } else {
+                        alert_back('排序失败,无任何内容!');
+                    }
+                    break;
+            }
+        }
+        
+        if (! $scode = get('scode', 'var')) {
+            error('传递的参数值错误!', - 1);
+        }
+        
+        // 单独修改状态
+        if (($field = get('field', 'var')) && ! is_null($value = get('value', 'var'))) {
+            if ($this->model->modSort($scode, "$field='$value',update_user='" . session('username') . "'")) {
+                $this->log('修改数据内容栏目' . $scode . '状态' . $value . '成功!');
+                location(- 1);
+            } else {
+                $this->log('修改数据内容栏目' . $scode . '状态' . $value . '失败!');
+                alert_back('修改失败!');
+            }
+        }
+        
+        // 修改操作
+        if ($_POST) {
+            
+            // 获取数据
+            $pcode = post('pcode', 'var');
+            $name = post('name');
+            $mcode = post('mcode');
+            $type = post('type');
+            $listtpl = basename(post('listtpl'));
+            $contenttpl = basename(post('contenttpl'));
+            $status = post('status');
+            $subname = post('subname');
+            $filename = trim(post('filename'), '/');
+            $outlink = post('outlink');
+            $ico = post('ico');
+            $pic = post('pic');
+            $title = post('title');
+            $keywords = post('keywords');
+            $description = post('description');
+            $modsub = post('modsub', 'int');
+            
+            $gid = post('gid', 'int') ?: 0;
+            $gtype = post('gtype', 'int') ?: 4;
+            $gnote = post('gnote');
+            
+            $def1 = post('def1');
+            $def2 = post('def2');
+            $def3 = post('def3');
+            
+            if (! $pcode) { // 父编码默认为0
+                $pcode = 0;
+            }
+            
+            if (! $name) {
+                alert_back('栏目名不能为空!');
+            }
+            
+            if (! $mcode) {
+                alert_back('栏目模型必须选择!');
+            }
+            
+            if (! $type) {
+                alert_back('栏目类型不能为空!');
+            }
+            
+            if ($filename && ! preg_match('/^[a-zA-Z0-9\-\/]+$/', $filename)) {
+                alert_back('URL名称只允许字母、数字、横线、斜线组成!');
+            }
+            
+            if ($filename && $this->model->checkUrlname($filename)) {
+                alert_back('URL名称与模型URL名称冲突,请换一个名称!');
+            }
+            
+            // 缩放缩略图
+            if ($ico) {
+                resize_img(ROOT_PATH . $ico, '', $this->config('ico.max_width'), $this->config('ico.max_height'));
+            }
+            
+            if ($filename) {
+                while ($this->model->checkFilename($filename, "scode<>'$scode'")) {
+                    $filename = $filename . '-' . mt_rand(1, 20);
+                }
+            }
+            
+            // 构建数据
+            $data = array(
+                'pcode' => $pcode,
+                'name' => $name,
+                'mcode' => $mcode,
+                'listtpl' => $listtpl,
+                'contenttpl' => $contenttpl,
+                'status' => $status,
+                'gid' => $gid,
+                'gtype' => $gtype,
+                'gnote' => $gnote,
+                'subname' => $subname,
+                'def1' => $def1,
+                'def2' => $def2,
+                'def3' => $def3,
+                'filename' => $filename,
+                'outlink' => $outlink,
+                'ico' => $ico,
+                'pic' => $pic,
+                'title' => $title,
+                'keywords' => $keywords,
+                'description' => $description,
+                'update_user' => session('username')
+            );
+            
+            // 执行添加
+            if ($this->model->modSort($scode, $data, $modsub)) {
+                // 如果修改为单页并且跳转,则删除单页内容,否则判断是否存在内容,不存在则添加
+                if ($type == 1 && $outlink) {
+                    $this->model->delContent($scode);
+                } elseif ($type == 1 && ! $this->model->findContent($scode)) {
+                    $this->addSingle($scode, $name);
+                }
+                
+                $this->log('修改数据内容栏目' . $scode . '成功!');
+                success('修改成功!', url('/admin/ContentSort/index'));
+            } else {
+                location(- 1);
+            }
+        } else { // 调取修改内容
+            $this->assign('mod', true);
+            
+            $sort = $this->model->getSort($scode);
+            if (! $sort) {
+                error('编辑的内容已经不存在!', - 1);
+            }
+            $this->assign('sort', $sort);
+            
+            // 父编码下拉选择
+            $sort_tree = $this->model->getSelect();
+            $sort_select = $this->makeSortSelect($sort_tree, $sort->pcode);
+            $this->assign('sort_select', $sort_select);
+            
+            // 模板文件
+            $htmldir = $this->config('tpl_html_dir') ? '/' . $this->config('tpl_html_dir') : '';
+            $this->assign('tpls', file_list(ROOT_PATH . current($this->config('tpl_dir')) . '/' . $this->model->getTheme() . $htmldir));
+            
+            // 内容模型
+            $models = model('admin.content.Model');
+            $this->assign('models', $models->getSelect());
+            
+            // 获取会员分组
+            $this->assign('groups', model('admin.member.MemberGroup')->getSelect());
+            
+            $this->display('content/contentsort.html');
+        }
+    }
+
+    // 添加栏目时执行单页内容增加
+    public function addSingle($scode, $title)
+    {
+        // 构建数据
+        $data = array(
+            'acode' => session('acode'),
+            'scode' => $scode,
+            'subscode' => '',
+            'title' => $title,
+            'titlecolor' => '#333333',
+            'subtitle' => '',
+            'filename' => '',
+            'author' => session('realname'),
+            'source' => '本站',
+            'outlink' => '',
+            'date' => date('Y-m-d H:i:s'),
+            'ico' => '',
+            'pics' => '',
+            'content' => '',
+            'tags' => '',
+            'enclosure' => '',
+            'keywords' => '',
+            'description' => '',
+            'sorting' => 255,
+            'status' => 1,
+            'istop' => 0,
+            'isrecommend' => 0,
+            'isheadline' => 0,
+            'gid' => 0,
+            'gtype' => 4,
+            'gnote' => '',
+            'visits' => 0,
+            'likes' => 0,
+            'oppose' => 0,
+            'create_user' => session('username'),
+            'update_user' => session('username')
+        );
+        
+        // 执行添加
+        if ($this->model->addSingle($data)) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+}

+ 224 - 0
apps/admin/controller/content/DeleCacheController.php

@@ -0,0 +1,224 @@
+<?php
+/**
+ * @author xsh
+ * @email hnxsh@foxmail.com
+ * @date 2021年10月31日
+ *
+ */
+namespace app\admin\controller\content;
+
+use core\basic\Controller;
+use app\home\controller\GetPageController;
+use core\basic\Config;
+
+class DeleCacheController extends GetPageController
+{
+
+    public function index($type = null, $data = null)
+    {
+        if ($type || ! ! $type = get('type', 'int')) {
+                        
+            // 设置基础信息
+            $this->setinfo();
+            
+            // 执行更新过程
+            switch ($type) {
+                case '1':
+                    $this->deleIndex();
+					$this->deleSort("0");
+                    json(1, '更新更新首页和栏目成功');
+                    break;
+                case '2':
+                    $this->deleSortAll("0");
+                    json(1, '更新全部栏目分页成功');
+                    break;
+				case '3':
+                    $this->deleContont($data);
+                    json(1, '更新内容成功');
+                    break;
+                default:
+                    json(0, '传递参数错误');
+            }
+        } else {
+            $sort_model = model('admin.content.ContentSort');
+            $sort_tree = $sort_model->getSelect();
+            $this->assign('sort_select', $this->makeSortSelect($sort_tree));
+            $this->assign('sort_select2', $this->makeSortSelect($sort_tree, true));
+            $this->display('content/delecache.html');
+        }
+    }
+
+    // 删除首页缓存
+    private function deleIndex()
+    {
+        $path = '/';
+		$lg = cookie('lg');
+		$wap = '';
+		$cacheFile = RUN_PATH . '/cache/' . md5(get_http_url() . $path . $lg . $wap) . '.html';
+		unlink($cacheFile);
+		if (Config::get('open_wap')){
+		$wap = 'wap';
+		$cacheFilewap = RUN_PATH . '/cache/' . md5(get_http_url() . $path . $lg . $wap) . '.html';
+		unlink($cacheFilewap);
+		}
+    }
+
+    // 删除栏目首页缓存
+    private function deleSort($scode = null)
+    {
+		$lg = cookie('lg');
+		$wap = '';
+        $scode = $scode ?: get('scode', 'var');
+        if (! $scode) {
+            $scodes = $this->model->getScodes('1,2');
+        } else {
+            $scodes = $this->model->getSubScodes($scode);
+        }
+        
+        $err = '';
+        foreach ($scodes as $value) {
+            $sort = $this->model->getSort($value);
+            if ($sort) {
+                if ($sort->type == 1) {
+					$link = $this->parser->parserLink($sort->type, $sort->urlname, 'list', $sort->scode, $sort->filename, '', '');
+					$cacheFile = RUN_PATH . '/cache/' . md5(get_http_url() . $link . $lg . $wap) . '.html';
+					unlink($cacheFile);
+					if (Config::get('open_wap')){
+							$wap = 'wap';
+							$cacheFilewap = RUN_PATH . '/cache/' . md5(get_http_url() . $link . $lg . $wap) . '.html';
+							unlink($cacheFilewap);
+						}
+                } else {
+                    $pagelink = $this->parser->parserLink($sort->type, $sort->urlname, 'list', $sort->scode, $sort->filename, '', '');
+                    $page = 10;
+                    for ($i = 1; $i <= $page; $i ++) {
+                        if ($i > 1) {
+                            $path = rtrim($pagelink, '/') . '_' . $i . '/';
+                        } else {
+                            $path = $pagelink;
+                        }						
+						$cacheFile = RUN_PATH . '/cache/' . md5(get_http_url() . $path . $lg . $wap) . '.html';
+						if (Config::get('open_wap')){
+							$wap = 'wap';
+							$cacheFilewap = RUN_PATH . '/cache/' . md5(get_http_url() . $path . $lg . $wap) . '.html';
+							unlink($cacheFilewap);
+						}
+						unlink($cacheFile);
+                    }
+                }
+            }
+        }
+    }
+	// 删除全部栏目缓存
+	private function deleSortAll($scode = null)
+    {
+		$lg = cookie('lg');
+		$wap = '';
+        $scode = $scode ?: get('scode', 'var');
+        if (! $scode) {
+            $scodes = $this->model->getScodes('1,2');
+        } else {
+            $scodes = $this->model->getSubScodes($scode);
+        }
+        
+        $err = '';
+        foreach ($scodes as $value) {
+            $sort = $this->model->getSort($value);
+            if ($sort) {
+                if ($sort->type == 1) {
+					$link = $this->parser->parserLink($sort->type, $sort->urlname, 'list', $sort->scode, $sort->filename, '', '');
+					$cacheFile = RUN_PATH . '/cache/' . md5(get_http_url() . $link . $lg . $wap) . '.html';
+					unlink($cacheFile);
+					if (Config::get('open_wap')){
+							$wap = 'wap';
+							$cacheFilewap = RUN_PATH . '/cache/' . md5(get_http_url() . $link . $lg . $wap) . '.html';
+							unlink($cacheFilewap);
+						}
+                } else {
+                    $pagelink = $this->parser->parserLink($sort->type, $sort->urlname, 'list', $sort->scode, $sort->filename, '', '');
+                    $page = 5000;
+					$jishu = 1;
+                    for ($i = 2; $i <= $page; $i ++) {
+                        if ($i > 1) {
+                            $path = rtrim($pagelink, '/') . '_' . $i . '/';
+                        } else {
+                            $path = $pagelink;
+                        }
+						
+						$cacheFile = RUN_PATH . '/cache/' . md5(get_http_url() . $path . $lg . $wap) . '.html';
+						if(!file_exists($cacheFile)){
+							$jishu ++;
+							if($jishu > 100){
+							break;
+							}
+						}
+						if (Config::get('open_wap')){
+							$wap = 'wap';
+							$cacheFilewap = RUN_PATH . '/cache/' . md5(get_http_url() . $path . $lg . $wap) . '.html';
+							unlink($cacheFilewap);
+						}
+						unlink($cacheFile);
+                    }
+                }
+            }
+        }
+    }
+
+
+    // 删除详情页面缓存
+    private function deleContont()
+    {		$lg = cookie('lg');
+			$wap = '';
+		    $idzuixiao = get('idzuixiao', 'var');
+			$idzuida = get('idzuida', 'var');
+			for($i=$idzuixiao;$i<=$idzuida;$i++){
+			$data = $this->model->getContent($i);
+            if ($data) {
+                $path = $this->parser->parserLink($data->type, $data->urlname, 'content', $data->scode, $data->sortfilename, $data->id, $data->filename);
+				$cacheFile = RUN_PATH . '/cache/' . md5(get_http_url() . $path . $lg . $wap) . '.html';
+				unlink($cacheFile);
+				if (Config::get('open_wap')){
+					$wap = 'wap';
+					$cacheFilewap = RUN_PATH . '/cache/' . md5(get_http_url() . $path . $lg . $wap) . '.html';
+					unlink($cacheFilewap);
+				}
+            }	
+			}
+    }
+
+    // 更新内容栏目下拉选择
+    private function makeSortSelect($tree, $ext_about = false)
+    {
+        $list_html = '';
+        foreach ($tree as $value) {
+            if (get('scode') != $value->scode) { // 不显示本身,避免出现自身为自己的父节点
+                if (($ext_about && $value->type == 1) || $value->outlink != '') {
+                    $list_html .= "<option value='{$value->scode}' disabled='disabled'>{$this->blank}{$value->name}</option>";
+                } else {
+                    $list_html .= "<option value='{$value->scode}' >{$this->blank}{$value->name}</option>";
+                }
+            }
+            // 子菜单处理
+            if ($value->son) {
+                $this->blank .= '  ';
+                $list_html .= $this->makeSortSelect($value->son, $ext_about);
+            }
+        }
+        // 循环完后回归位置
+        $this->blank = substr($this->blank, 0, - 6);
+        return $list_html;
+    }
+
+    // 设置公共信息
+    private function setinfo()
+    {
+        // 设置前台模板路径,避免后端调用问题
+        if (($tpl_dir = Config::get('tpl_dir')) && array_key_exists('home', $tpl_dir)) {
+            $this->assign('tplpath', ROOT_PATH . $tpl_dir['home']);
+        } else {
+            $this->assign('tplpath', APP_PATH . '/home/view');
+        }
+        // 定义当前操作为更新静态,后期动作判断
+        define('DeleCache', true);
+    }
+}

+ 244 - 0
apps/admin/controller/content/ExtFieldController.php

@@ -0,0 +1,244 @@
+<?php
+/**
+ * @copyright (C)2016-2099 Hnaoyun Inc.
+ * @author XingMeng
+ * @email hnxsh@foxmail.com
+ * @date 2018年3月1日
+ *  扩展字段控制器
+ */
+namespace app\admin\controller\content;
+
+use core\basic\Controller;
+use app\admin\model\content\ExtFieldModel;
+
+class ExtFieldController extends Controller
+{
+
+    private $model;
+
+    public function __construct()
+    {
+        $this->model = new ExtFieldModel();
+    }
+
+    // 扩展字段列表
+    public function index()
+    {
+        if ((! ! $id = get('id', 'int')) && $result = $this->model->getExtField($id)) {
+            $this->assign('more', true);
+            $this->assign('extfield', $result);
+        } else {
+            $this->assign('list', true);
+            if (! ! ($field = get('field', 'var')) && ! ! ($keyword = get('keyword', 'vars'))) {
+                $result = $this->model->findExtField($field, $keyword);
+            } else {
+                $result = $this->model->getList();
+            }
+            
+            // 内容模型
+            $models = model('admin.content.Model');
+            $this->assign('models', $models->getSelect());
+            
+            $this->assign('extfields', $result);
+        }
+        $this->display('content/extfield.html');
+    }
+
+    // 扩展字段增加
+    public function add()
+    {
+        if ($_POST) {
+            // 获取数据
+            $mcode = post('mcode');
+            $name = post('name', 'var');
+            $type = post('type', 'int');
+            if (! ! $value = post('value')) {
+                $value = str_replace("\r\n", ",", $value); // 替换回车
+                $value = str_replace(",", ",", $value); // 替换中文逗号分割符
+            }
+            $description = post('description');
+            $sorting = post('sorting', 'int');
+            
+            if (! $mcode) {
+                alert_back('内容模型不能为空!');
+            }
+            
+            if (! $name) {
+                alert_back('字段名称不能为空!');
+            } else {
+                $name = "ext_" . $name;
+            }
+            
+            if (! $type) {
+                alert_back('字段类型不能为空!');
+            }
+            
+            if (! $description) {
+                alert_back('字段描述不能为空!');
+            }
+            
+            // 构建数据
+            $data = array(
+                'mcode' => $mcode,
+                'name' => $name,
+                'type' => $type,
+                'value' => $value,
+                'description' => $description,
+                'sorting' => $sorting
+            );
+            
+            // 字段类型及长度
+            switch ($type) {
+                case '2': // 多行
+                    $mysql = 'varchar(1000)';
+                    $sqlite = 'TEXT(1000)';
+                    break;
+                case '7': // 时间日期
+                    $mysql = 'datetime';
+                    $sqlite = 'TEXT';
+                    break;
+                case '8': // 编辑器
+                    $mysql = 'TEXT';
+                    $sqlite = 'TEXT(10000)';
+                    break;
+                case '10': // 多图
+                    $mysql = 'varchar(1000)';
+                    $sqlite = 'TEXT(1000)';
+                    break;
+                default:
+                    $mysql = 'varchar(200)';
+                    $sqlite = 'TEXT(200)';
+            }
+            
+            // 字段不存在时创建
+            if (! $this->model->isExistField($name)) {
+                if (get_db_type() == 'sqlite') {
+                    $result = $this->model->amd("ALTER TABLE ay_content_ext ADD COLUMN $name $sqlite NULL");
+                } else {
+                    $result = $this->model->amd("ALTER TABLE ay_content_ext ADD $name $mysql NULL COMMENT '$description'");
+                    //添加索引
+                    $this->model->amd("create index ay_content_{$name}_index on ay_content_ext ($name)");
+                }
+            } elseif ($this->model->checkExtField($name)) { // 字段存在且已使用则 报错
+                alert_back('字段已经存在,不能重复添加!');
+            }
+            
+            // 执行扩展字段记录添加
+            if ($this->model->addExtField($data)) {
+                $this->log('新增扩展字段成功!');
+                if (! ! $backurl = get('backurl')) {
+                    success('新增成功!', base64_decode($backurl));
+                } else {
+                    success('新增成功!', url('/admin/ExtField/index'));
+                }
+            } else {
+                $this->log('新增扩展字段失败!');
+                error('新增失败!', - 1);
+            }
+        }
+    }
+
+    // 扩展字段删除
+    public function del()
+    {
+        if (! $id = get('id', 'int')) {
+            error('传递的参数值错误!', - 1);
+        }
+        
+        $name = $this->model->getExtFieldName($id);
+        if ($this->model->delExtField($id)) {
+            // mysql数据库执行字段删除,sqlite暂时不支持
+            if (! ! $name) {
+                if (get_db_type() == 'mysql') {
+                    $result = $this->model->amd("ALTER TABLE ay_content_ext DROP COLUMN $name");
+                    //删除索引(如果有)
+                    $contentExt = $this->model->checkExtIndex();
+                    foreach ($contentExt as $items){
+                        if($items[2] == "ay_content_{$name}_index"){
+                            $this->model->amd("ALTER table ay_content_ext drop key ay_content_{$name}_index");
+                        }
+                    }
+                }
+            }
+            $this->log('删除扩展字段' . $id . '成功!');
+            success('删除成功!', - 1);
+        } else {
+            $this->log('删除扩展字段' . $id . '失败!');
+            error('删除失败!', - 1);
+        }
+    }
+
+    // 扩展字段修改
+    public function mod()
+    {
+        if (! $id = get('id', 'int')) {
+            error('传递的参数值错误!', - 1);
+        }
+        
+        // 单独修改状态
+        if (($field = get('field', 'var')) && ! is_null($value = get('value', 'var'))) {
+            if ($this->model->modExtField($id, "$field='$value',update_user='" . session('username') . "'")) {
+                location(- 1);
+            } else {
+                alert_back('修改失败!');
+            }
+        }
+        
+        // 修改操作
+        if ($_POST) {
+            
+            // 获取数据
+            $mcode = post('mcode');
+            $type = post('type');
+            if (! ! $value = post('value')) {
+                $value = str_replace("\r\n", ",", $value); // 替换回车
+                $value = str_replace(",", ",", $value); // 替换中文逗号分割符
+            }
+            $description = post('description');
+            $sorting = post('sorting', 'int');
+            
+            if (! $mcode) {
+                alert_back('内容模型不能为空!');
+            }
+            
+            if (! $description) {
+                alert_back('字段描述不能为空!');
+            }
+            
+            // 构建数据
+            $data = array(
+                'mcode' => $mcode,
+                'type' => $type,
+                'value' => $value,
+                'description' => $description,
+                'sorting' => $sorting
+            );
+            
+            // 执行修改
+            if ($this->model->modExtField($id, $data)) {
+                $this->log('修改扩展字段' . $id . '成功!');
+                if (! ! $backurl = get('backurl')) {
+                    success('修改成功!', base64_decode($backurl));
+                } else {
+                    success('修改成功!', url('/admin/ExtField/index'));
+                }
+            } else {
+                location(- 1);
+            }
+        } else {
+            
+            // 调取修改内容
+            $this->assign('mod', true);
+            if (! $result = $this->model->getExtField($id)) {
+                error('编辑的内容已经不存在!', - 1);
+            }
+            
+            // 内容模型
+            $models = model('admin.content.Model');
+            $this->assign('models', $models->getSelect());
+            
+            $this->assign('extfield', $result);
+            $this->display('content/extfield.html');
+        }
+    }
+}

+ 354 - 0
apps/admin/controller/content/FormController.php

@@ -0,0 +1,354 @@
+<?php
+/**
+ * @copyright (C)2016-2099 Hnaoyun Inc.
+ * @author XingMeng
+ * @email hnxsh@foxmail.com
+ * @date 2018年5月28日 
+ *  自定义表单控制器
+ */
+namespace app\admin\controller\content;
+
+use core\basic\Controller;
+use app\admin\model\content\FormModel;
+
+class FormController extends Controller
+{
+
+    private $model;
+
+    public function __construct()
+    {
+        $this->model = new FormModel();
+    }
+
+    // 自定义表单列表
+    public function index()
+    {
+        if ((! ! $fcode = get('fcode', 'var')) && $form = $this->model->getFormByCode($fcode)) {
+            $this->assign('form', $form);
+            if (get('action') == 'showdata') {
+                $this->assign('showdata', true);
+                $this->assign('fields', $this->model->getFormFieldByCode($fcode)); // 获取字段
+                $table = $this->model->getFormTableByCode($fcode);
+                if (get('export')) {
+                    $this->assign('formdata', $this->model->getFormData($table, false));
+                    header('Content-Type:application/vnd.ms-excel');
+                    header('Cache-Control: max-age=0');
+                    header("Content-Disposition:filename=" . $form->form_name . "-" . date("YmdHis") . ".xls");
+                    $this->display('content/exform.html');
+                } else {
+                    $this->assign('formdata', $this->model->getFormData($table, true));
+                }
+            }
+            if (get('action') == 'showfield') {
+                $this->assign('showfield', true);
+                $this->assign('fields', $this->model->getFormFieldByCode($fcode));
+            }
+        } else {
+            $this->assign('list', true);
+            if (! ! ($field = get('field', 'var')) && ! ! ($keyword = get('keyword', 'vars'))) {
+                $result = $this->model->findForm($field, $keyword);
+            } else {
+                $result = $this->model->getList();
+            }
+            
+            $this->assign('forms', $result);
+        }
+        $this->display('content/form.html');
+    }
+
+    // 自定义表单增加
+    public function add()
+    {
+        if ($_POST) {
+            if (get('action') == 'addform') {
+                $fcode = get_auto_code($this->model->getLastCode());
+                $form_name = post('form_name');
+                $table_name = 'ay_diy_' . post('table_name', 'var');
+                
+                if (! $form_name) {
+                    alert_back('表单名称不能为空!');
+                }
+                
+                if (! $table_name) {
+                    alert_back('表单数据表不能为空!');
+                }
+                
+                $data = array(
+                    'fcode' => $fcode,
+                    'form_name' => $form_name,
+                    'table_name' => $table_name,
+                    'create_user' => session('username'),
+                    'update_user' => session('username')
+                );
+                
+                if (get_db_type() == 'sqlite') {
+                    $result = $this->model->amd("CREATE TABLE `$table_name` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,`create_time` TEXT NOT NULL)");
+                } else {
+                    $result = $this->model->amd("CREATE TABLE `$table_name` (`id` int(10) unsigned NOT NULL AUTO_INCREMENT,`create_time` datetime NOT NULL,PRIMARY KEY (`id`))ENGINE=MyISAM DEFAULT CHARSET=utf8");
+                }
+                
+                if ($this->model->addForm($data)) {
+                    $this->log('新增自定义表单成功!');
+                    if (! ! $backurl = get('backurl')) {
+                        success('新增成功!', base64_decode($backurl));
+                    } else {
+                        success('新增成功!', url('/admin/Form/index'));
+                    }
+                } else {
+                    $this->log('新增自定义表单失败!');
+                    error('新增失败!', - 1);
+                }
+            } else {
+                // 获取数据
+                $fcode = post('fcode', 'var');
+                $name = post('name', 'var');
+                $length = post('length', 'int') ?: 20;
+                $required = post('required', 'int') ?: 0;
+                $description = post('description');
+                $sorting = post('sorting', 'int') ?: 255;
+                
+                if (! $fcode) {
+                    alert_back('表单编码不能为空!');
+                }
+                
+                if (! $name) {
+                    alert_back('字段名称不能为空!');
+                }
+                
+                if (! $description) {
+                    alert_back('字段描述不能为空!');
+                }
+                
+                // 构建数据
+                $data = array(
+                    'fcode' => $fcode,
+                    'name' => $name,
+                    'length' => $length,
+                    'required' => $required,
+                    'description' => $description,
+                    'sorting' => $sorting,
+                    'create_user' => session('username'),
+                    'update_user' => session('username')
+                );
+                
+                // 获取表名称
+                $table = $this->model->getFormTableByCode($fcode);
+                
+                // 字段类型及长度
+                $mysql = "varchar($length)";
+                $sqlite = "TEXT($length)";
+                
+                // 字段不存在时创建
+                if (! $this->model->isExistField($table, $name)) {
+                    if (get_db_type() == 'sqlite') {
+                        $result = $this->model->amd("ALTER TABLE $table ADD COLUMN $name $sqlite NULL");
+                    } else {
+                        $result = $this->model->amd("ALTER TABLE $table ADD $name $mysql NULL COMMENT '$description'");
+                    }
+                } elseif ($this->model->checkFormField($fcode, $name)) {
+                    alert_back('字段已经存在,不能重复添加!');
+                }
+                
+                // 执行自定义表单记录添加
+                if ($this->model->addFormField($data)) {
+                    $this->log('新增表单字段成功!');
+                    if (! ! $backurl = get('backurl')) {
+                        success('新增成功!', base64_decode($backurl));
+                    } else {
+                        success('新增成功!', url('/admin/Form/index/fcode/' . $fcode . '/action/showfield'));
+                    }
+                } else {
+                    $this->log('新增表单字段失败!');
+                    error('新增失败!', - 1);
+                }
+            }
+        }
+    }
+
+    // 自定义表单删除
+    public function del()
+    {
+        if (! $id = get('id', 'int')) {
+            error('传递的参数值错误!', - 1);
+        }
+        
+        // 删除表单
+        if (get('action') == 'delform') {
+            if ($id == 1) {
+                alert_back('留言表单不允许删除');
+            }
+            $table = $this->model->getFormTable($id);
+            $fcode = $this->model->getFormCode($id);
+            if ($this->model->delForm($id)) {
+                $this->model->delFormFieldByCode($fcode); // 删除字段记录
+                $this->model->amd("DROP TABLE IF EXISTS $table"); // 删除表
+                $this->log('删除自定义表单' . $id . '成功!');
+                success('删除成功!', - 1);
+            } else {
+                $this->log('删除自定义表单' . $id . '失败!');
+                error('删除失败!', - 1);
+            }
+        } elseif (get('action') == 'deldata') {
+            // 获取表单
+            if (! $fcode = get('fcode', 'var')) {
+                error('传递的参数值fcode错误!', - 1);
+            }
+            $table = $this->model->getFormTableByCode($fcode);
+            if ($this->model->delFormData($table, $id)) {
+                $this->log('删除表单数据' . $id . '成功!');
+                success('删除成功!', - 1);
+            } else {
+                $this->log('删除表单数据' . $id . '失败!');
+                error('删除失败!', - 1);
+            }
+        } else {
+            
+            // 获取表单
+            if (! $fcode = get('fcode', 'var')) {
+                error('传递的参数值fcode错误!', - 1);
+            }
+            
+            // 获取操作表
+            $table = $this->model->getFormTableByCode($fcode);
+            $name = $this->model->getFormFieldName($id);
+            
+            if ($this->model->delFormField($id)) {
+                // mysql数据库执行字段删除,sqlite暂时不支持
+                if (! ! $name) {
+                    if (get_db_type() == 'mysql') {
+                        $result = $this->model->amd("ALTER TABLE $table DROP COLUMN $name");
+                    }
+                }
+                $this->log('删除自定义表单' . $id . '成功!');
+                success('删除成功!', - 1);
+            } else {
+                $this->log('删除自定义表单' . $id . '失败!');
+                error('删除失败!', - 1);
+            }
+        }
+    }
+
+    // 自定义表单修改
+    public function mod()
+    {
+        if (! $id = get('id', 'int')) {
+            error('传递的参数值错误!', - 1);
+        }
+        
+        // 单独修改状态
+        if (($field = get('field', 'var')) && ! is_null($value = get('value', 'var'))) {
+            if ($this->model->modFormField($id, "$field='$value',update_user='" . session('username') . "'")) {
+                location(- 1);
+            } else {
+                alert_back('修改失败!');
+            }
+        }
+        
+        if (get('action') == 'addmenu') {
+            if ($this->model->addFormMenu($id)) {
+                $this->log('添加自定义表单' . $id . '到菜单成功!');
+                if (! ! $backurl = get('backurl')) {
+                    success('添加成功!', base64_decode($backurl));
+                } else {
+                    success('添加成功!', url('/admin/Form/index'));
+                }
+            } else {
+                location(- 1);
+            }
+        }
+        
+        // 修改操作
+        if ($_POST) {
+            
+            // 修改表单
+            if (get('action') == 'modform') {
+                $form_name = post('form_name');
+                
+                if (! $form_name) {
+                    alert_back('表单名称不能为空!');
+                }
+                $data = array(
+                    'form_name' => $form_name,
+                    'update_user' => session('username')
+                );
+                
+                // 执行修改
+                if ($this->model->modForm($id, $data)) {
+                    $this->log('修改自定义表单' . $id . '成功!');
+                    if (! ! $backurl = get('backurl')) {
+                        success('修改成功!', base64_decode($backurl));
+                    } else {
+                        success('修改成功!', url('/admin/Form/index'));
+                    }
+                } else {
+                    location(- 1);
+                }
+            } else {
+                
+                // 获取数据
+                $description = post('description');
+                $required = post('required', 'int') ?: 0;
+                $sorting = post('sorting', 'int') ?: 255;
+                
+                if (! $description) {
+                    alert_back('字段描述不能为空!');
+                }
+                
+                // 构建数据
+                $data = array(
+                    'description' => $description,
+                    'required' => $required,
+                    'sorting' => $sorting,
+                    'update_user' => session('username')
+                );
+                
+                // 执行修改
+                if ($this->model->modFormField($id, $data)) {
+                    $this->log('修改表单字段' . $id . '成功!');
+                    if (! ! $backurl = get('backurl')) {
+                        success('修改成功!', base64_decode($backurl));
+                    } else {
+                        success('修改成功!', url('/admin/Form/index'));
+                    }
+                } else {
+                    location(- 1);
+                }
+            }
+        } else {
+            
+            // 调取修改内容
+            $this->assign('mod', true);
+            
+            if (get('action') == 'modform') {
+                if (! $result = $this->model->getForm($id)) {
+                    error('编辑的内容已经不存在!', - 1);
+                }
+                
+                $this->assign('form', $result);
+            } else {
+                if (! $result = $this->model->getFormField($id)) {
+                    error('编辑的内容已经不存在!', - 1);
+                }
+                $this->assign('field', $result);
+            }
+            $this->display('content/form.html');
+        }
+    }
+
+    // 清空
+    public function clear()
+    {
+        // 获取表单
+        if (! $fcode = get('fcode', 'var')) {
+            error('传递的参数值fcode错误!', - 1);
+        }
+        $table = $this->model->getFormTableByCode($fcode);
+        
+        if ($this->model->clearFormData($table)) {
+            alert_location('清空成功!', - 1);
+        } else {
+            alert_location('清空失败!', - 1);
+        }
+    }
+}

+ 175 - 0
apps/admin/controller/content/LabelController.php

@@ -0,0 +1,175 @@
+<?php
+/**
+ * @copyright (C)2016-2099 Hnaoyun Inc.
+ * @author XingMeng
+ * @email hnxsh@foxmail.com
+ * @date 2018年03月23日
+ *  自定义标签控制器
+ */
+namespace app\admin\controller\content;
+
+use core\basic\Controller;
+use app\admin\model\content\LabelModel;
+
+class LabelController extends Controller
+{
+
+    private $model;
+
+    public function __construct()
+    {
+        $this->model = new LabelModel();
+    }
+
+    // 自定义标签列表
+    public function index()
+    {
+        // 修改参数配置
+        if ($_POST) {
+            foreach ($_POST as $key => $value) {
+                if (preg_match('/^[\w\-]+$/', $key)) { // 带有违规字符时不带入查询
+                    $data = post($key);
+                    $data = str_replace("\r\n", "<br>", $data); // 多行文本时替换回车
+                    $this->model->modValue($key, $data);
+                }
+            }
+            success('修改成功!', url('admin/Label/index'));
+        }
+        $this->assign('list', true);
+        $this->assign('labels', $this->model->getList());
+        $this->display('content/label.html');
+    }
+
+    // 自定义标签字段增加
+    public function add()
+    {
+        if ($_POST) {
+            // 获取数据
+            $name = post('name', 'var');
+            $description = post('description');
+            $type = post('type');
+            
+            if (! $name) {
+                alert_back('标签名称不能为空!');
+            }
+
+            if ($name && ! preg_match('/^[a-zA-Z0-9\_\/]+$/', $name)) {
+                alert_back('标签名称只允许字母、数字、下划线组成!');
+            }
+
+            if (! $description) {
+                alert_back('标题描述不能为空!');
+            }
+            
+            if (! $type) {
+                alert_back('标签类型不能为空!');
+            }
+            
+            // 检查标签名称
+            if ($this->model->checkLabel("name='$name'")) {
+                alert_back('该自定义标签称已经存在,不能再使用!');
+            }
+            
+            // 构建数据
+            $data = array(
+                'name' => $name,
+                'description' => $description,
+                'value' => '', // 添加时设置为空
+                'type' => $type,
+                'create_user' => session('username'),
+                'update_user' => session('username')
+            );
+            
+            // 执行添加
+            if ($this->model->addLabel($data)) {
+                $this->log('修改自定义标签' . $name . '成功!');
+                if (! ! $backurl = get('backurl')) {
+                    success('新增成功!', base64_decode($backurl));
+                } else {
+                    success('新增成功!', url('admin/Label/index' . get_tab('t2'), false));
+                }
+            } else {
+                $this->log('新增自定义标签' . $name . '失败!');
+                error('新增失败!', url('admin/Label/index' . get_tab('t2'), false));
+            }
+        }
+    }
+
+    // 自定义标签字段删除
+    public function del()
+    {
+        if (! $id = get('id', 'int')) {
+            error('传递的参数值错误!', - 1);
+        }
+        if ($this->model->delLabel($id)) {
+            $this->log('删除自定义标签' . $id . '成功!');
+            success('删除成功!', url('admin/Label/index' . get_tab('t2'), false));
+        } else {
+            $this->log('删除自定义标签' . $id . '失败!');
+            error('删除失败!', - 1);
+        }
+    }
+
+    // 自定义标签字段修改
+    public function mod()
+    {
+        if (! $id = get('id', 'int')) {
+            error('传递的参数值错误!', - 1);
+        }
+        
+        // 修改操作
+        if ($_POST) {
+            // 获取数据
+            $name = post('name', 'var');
+            $description = post('description');
+            $type = post('type');
+            if (! $name) {
+                alert_back('标签名称不能为空!');
+            }
+
+            if ($name && ! preg_match('/^[a-zA-Z0-9\_\/]+$/', $name)) {
+                alert_back('标签名称只允许字母、数字、下划线组成!');
+            }
+
+            if (! $description) {
+                alert_back('标签描述不能为空!');
+            }
+            
+            if (! $type) {
+                alert_back('标签类型不能为空!');
+            }
+            
+            // 检查标签名称
+            if ($this->model->checkLabel("name='$name' AND id<>$id")) {
+                alert_back('该自定义标签名称已经存在,不能再使用!');
+            }
+            
+            // 构建数据
+            $data = array(
+                'name' => $name,
+                'description' => $description,
+                'type' => $type,
+                'update_user' => session('username')
+            );
+            
+            // 执行添加
+            if ($this->model->modLabel($id, $data)) {
+                $this->log('修改自定义标签字段' . $id . '成功!');
+                success('修改成功!', url('admin/Label/index' . get_tab('t2'), false));
+            } else {
+                location(- 1);
+            }
+        } else {
+            $this->assign('mod', true);
+            
+            // 调取修改内容
+            $result = $this->model->getLabel($id);
+            if (! $result) {
+                error('编辑的内容已经不存在!', - 1);
+            }
+            $this->assign('label', $result);
+            
+            $this->display('content/label.html');
+        }
+    }
+}

+ 213 - 0
apps/admin/controller/content/LinkController.php

@@ -0,0 +1,213 @@
+<?php
+/**
+ * @copyright (C)2016-2099 Hnaoyun Inc.
+ * @author XingMeng
+ * @email hnxsh@foxmail.com
+ * @date 2018年3月1日
+ *  友情链接控制器
+ */
+namespace app\admin\controller\content;
+
+use core\basic\Controller;
+use app\admin\model\content\LinkModel;
+
+class LinkController extends Controller
+{
+
+    private $model;
+
+    public function __construct()
+    {
+        $this->model = new LinkModel();
+    }
+
+    // 友情链接列表
+    public function index()
+    {
+        if ((! ! $id = get('id', 'int')) && $result = $this->model->getLink($id)) {
+            $this->assign('more', true);
+            $this->assign('link', $result);
+        } else {
+            $this->assign('list', true);
+            if (! ! ($field = get('field', 'var')) && ! ! ($keyword = get('keyword', 'vars'))) {
+                $result = $this->model->findLink($field, $keyword);
+            } else {
+                $result = $this->model->getList();
+            }
+            $this->assign('gids', $this->model->getGid());
+            $this->assign('links', $result);
+        }
+        $this->display('content/link.html');
+    }
+
+    // 友情链接增加
+    public function add()
+    {
+        if ($_POST) {
+            // 获取数据
+            $gid = post('gid', 'int');
+            $name = post('name');
+            $link = post('link');
+            $logo = post('logo');
+            $sorting = post('sorting');
+            
+            if (! $gid) {
+                $gid = $this->model->getMaxGid() + 1;
+            }
+            
+            if (! $name) {
+                alert_back('名称不能为空!');
+            }
+            
+            if (! $link) {
+                alert_back('链接不能为空!');
+            }
+            
+            if (! $sorting) {
+                $sorting = 255;
+            }
+            
+            // logo图缩放
+            if ($logo) {
+                resize_img(ROOT_PATH . $logo, '', $this->config('ico.max_width'), $this->config('ico.max_height'));
+            }
+            
+            // 构建数据
+            $data = array(
+                'acode' => session('acode'),
+                'gid' => $gid,
+                'name' => $name,
+                'link' => $link,
+                'logo' => $logo,
+                'sorting' => $sorting,
+                'create_user' => session('username'),
+                'update_user' => session('username')
+            );
+            
+            // 执行添加
+            if ($this->model->addLink($data)) {
+                $this->log('新增友情链接成功!');
+                if (! ! $backurl = get('backurl')) {
+                    success('新增成功!', base64_decode($backurl));
+                } else {
+                    success('新增成功!', url('/admin/Link/index'));
+                }
+            } else {
+                $this->log('新增友情链接失败!');
+                error('新增失败!', - 1);
+            }
+        }
+    }
+
+    // 友情链接删除
+    public function del()
+    {
+        if (! $id = get('id', 'int')) {
+            error('传递的参数值错误!', - 1);
+        }
+        
+        if ($this->model->delLink($id)) {
+            $this->log('删除友情链接' . $id . '成功!');
+            success('删除成功!', - 1);
+        } else {
+            $this->log('删除友情链接' . $id . '失败!');
+            error('删除失败!', - 1);
+        }
+    }
+
+    // 友情链接修改
+    public function mod()
+    {
+        if (! ! $submit = post('submit')) {
+            switch ($submit) {
+                case 'sorting': // 修改列表排序
+                    $listall = post('listall');
+                    if ($listall) {
+                        $sorting = post('sorting');
+                        foreach ($listall as $key => $value) {
+                            if ($sorting[$key] === '' || ! is_numeric($sorting[$key]))
+                                $sorting[$key] = 255;
+                            $this->model->modLink($value, "sorting=" . $sorting[$key]);
+                        }
+                        $this->log('批量修改链接排序成功!');
+                        success('修改成功!', - 1);
+                    } else {
+                        alert_back('排序失败,无任何内容!');
+                    }
+                    break;
+            }
+        }
+        
+        if (! $id = get('id', 'int')) {
+            error('传递的参数值错误!', - 1);
+        }
+        
+        // 单独修改状态
+        if (($field = get('field', 'var')) && ! is_null($value = get('value', 'var'))) {
+            if ($this->model->modLink($id, "$field='$value',update_user='" . session('username') . "'")) {
+                location(- 1);
+            } else {
+                alert_back('修改失败!');
+            }
+        }
+        
+        // 修改操作
+        if ($_POST) {
+            
+            // 获取数据
+            $gid = post('gid', 'int');
+            $name = post('name');
+            $link = post('link');
+            $logo = post('logo');
+            $sorting = post('sorting');
+            
+            if (! $gid) {
+                $gid = $this->model->getMaxGid() + 1;
+            }
+            
+            if (! $name) {
+                alert_back('名称不能为空!');
+            }
+            
+            if (! $link) {
+                alert_back('链接不能为空!');
+            }
+            
+            // logo图缩放
+            if ($logo) {
+                resize_img(ROOT_PATH . $logo, '', $this->config('ico.max_width'), $this->config('ico.max_height'));
+            }
+            
+            // 构建数据
+            $data = array(
+                'gid' => $gid,
+                'name' => $name,
+                'link' => $link,
+                'logo' => $logo,
+                'sorting' => $sorting,
+                'update_user' => session('username')
+            );
+            
+            // 执行添加
+            if ($this->model->modLink($id, $data)) {
+                $this->log('修改友情链接' . $id . '成功!');
+                if (! ! $backurl = get('backurl')) {
+                    success('修改成功!', base64_decode($backurl));
+                } else {
+                    success('修改成功!', url('/admin/Link/index'));
+                }
+            } else {
+                location(- 1);
+            }
+        } else {
+            // 调取修改内容
+            $this->assign('mod', true);
+            if (! $result = $this->model->getLink($id)) {
+                error('编辑的内容已经不存在!', - 1);
+            }
+            $this->assign('gids', $this->model->getGid());
+            $this->assign('link', $result);
+            $this->display('content/link.html');
+        }
+    }
+}

+ 128 - 0
apps/admin/controller/content/MessageController.php

@@ -0,0 +1,128 @@
+<?php
+/**
+ * @copyright (C)2016-2099 Hnaoyun Inc.
+ * @author XingMeng
+ * @email hnxsh@foxmail.com
+ * @date 2017年3月29日
+ *  留言控制器
+ */
+namespace app\admin\controller\content;
+
+use core\basic\Controller;
+use app\admin\model\content\MessageModel;
+
+class MessageController extends Controller
+{
+
+    private $model;
+
+    public function __construct()
+    {
+        $this->model = new MessageModel();
+    }
+
+    // 列表
+    public function index()
+    {
+        $this->assign('list', true);
+        $this->assign('fields', $this->model->getFormFieldByCode(1)); // 获取字段
+        
+        if (get('export')) {
+            $this->assign('messages', $this->model->getList(false));
+            header("Content-Type:application/vnd.ms-excel");
+            header('Cache-Control: max-age=0');
+            header("Content-Disposition:filename=留言记录-" . date("YmdHis") . ".xls");
+            $this->display('content/exmessage.html');
+        } else {
+            $this->assign('messages', $this->model->getList(true));
+            $this->display('content/message.html');
+        }
+    }
+
+    // 删除
+    public function del()
+    {
+        if (! $id = get('id', 'int')) {
+            error('传递的参数值错误!', - 1);
+        }
+        
+        if ($this->model->delMessage($id)) {
+            $this->log('删除留言' . $id . '成功!');
+            success('删除成功!', - 1);
+        } else {
+            $this->log('删除留言' . $id . '失败!');
+            error('删除失败!', - 1);
+        }
+    }
+
+    // 修改
+    public function mod()
+    {
+        if (! $id = get('id', 'int')) {
+            error('传递的参数值错误!', - 1);
+        }
+        
+        // 单独修改状态
+        if (($field = get('field', 'var')) && ! is_null($value = get('value', 'var'))) {
+            if ($this->model->modMessage($id, "$field='$value',update_user='" . session('username') . "'")) {
+                location(- 1);
+            } else {
+                alert_back('修改失败!');
+            }
+        }
+        
+        // 修改操作
+        if ($_POST) {
+            // 获取数据
+            $recontent = post('recontent');
+            $status = post('status');
+            
+            // 构建数据
+            $data = array(
+                'recontent' => $recontent,
+                'status' => $status,
+                'update_user' => session('username')
+            );
+            
+            // 执行修改
+            if ($this->model->modMessage($id, $data)) {
+                $this->log('修改留言' . $id . '成功!');
+                if (! ! $backurl = get('backurl')) {
+                    success('修改成功!', base64_decode($backurl));
+                } else {
+                    success('修改成功!', url('/admin/Message/index'));
+                }
+            } else {
+                location(- 1);
+            }
+        } else {
+            // 调取修改内容
+            $this->assign('mod', true);
+            if (! $result = $this->model->getMessage($id)) {
+                error('编辑的内容已经不存在!', - 1);
+            }
+            $this->assign('message', $result);
+            
+            $this->display('content/message.html');
+        }
+    }
+
+    // 清空
+    public function clear()
+    {
+        if($_GET['ids']){
+            $idList = implode("," , explode("and",$_GET['ids']));
+        } else {
+            $idList = null;
+        }
+        if ($this->model->clearMessage($idList)){
+            alert_location('删除成功!', url('/admin/Message/index'));
+        } else {
+            alert_location('删除失败!', url('/admin/Message/index'));
+        }
+
+
+
+
+    }
+}

+ 207 - 0
apps/admin/controller/content/ModelController.php

@@ -0,0 +1,207 @@
+<?php
+/**
+ * @copyright (C)2016-2099 Hnaoyun Inc.
+ * @author XingMeng
+ * @email hnxsh@foxmail.com
+ * @date 2018年3月1日
+ *  内容模型控制器
+ */
+namespace app\admin\controller\content;
+
+use core\basic\Controller;
+use app\admin\model\content\ModelModel;
+
+class ModelController extends Controller
+{
+
+    private $model;
+
+    public function __construct()
+    {
+        $this->model = new ModelModel();
+    }
+
+    // 内容模型列表
+    public function index()
+    {
+        if ((! ! $id = get('id', 'int')) && $result = $this->model->getModel($id)) {
+            $this->assign('more', true);
+            $this->assign('model', $result);
+        } else {
+            $this->assign('list', true);
+            if (! ! ($field = get('field', 'var')) && ! ! ($keyword = get('keyword', 'vars'))) {
+                $result = $this->model->findModel($field, $keyword);
+            } else {
+                $result = $this->model->getList();
+            }
+            $this->assign('models', $result);
+        }
+        $this->display('content/model.html');
+    }
+
+    // 内容模型增加
+    public function add()
+    {
+        if ($_POST) {
+            // 获取数据
+            $mcode = get_auto_code($this->model->getLastCode());
+            $name = post('name');
+            $type = post('type');
+            $urlname = post('urlname');
+            $listtpl = basename(post('listtpl'));
+            $contenttpl = basename(post('contenttpl'));
+            $status = post('status');
+            
+            if (! $name) {
+                alert_back('模型名称不能为空!');
+            }
+            
+            if ($type == 1) {
+                if (! $urlname)
+                    $urlname = 'about';
+            } else {
+                if (! $urlname)
+                    $urlname = 'list';
+            }
+            
+            if ($urlname && ! preg_match('/^[a-zA-Z0-9\-]+$/', $urlname)) {
+                alert_back('模型URL名称只允许字母、数字、横线组成!');
+            }
+            
+            if ($this->model->checkUrlname($urlname, $type)) {
+                alert_back('模型URL名称与其他模型冲突,请换一个名称!');
+            }
+            
+            if ($this->model->checkSortFilename($urlname)) {
+                alert_back('模型URL名称与栏目URL名称冲突,请换一个名称!');
+            }
+            
+            // 构建数据
+            $data = array(
+                'mcode' => $mcode,
+                'name' => $name,
+                'type' => $type,
+                'urlname' => $urlname,
+                'listtpl' => $listtpl,
+                'contenttpl' => $contenttpl,
+                'status' => $status,
+                'issystem' => 0,
+                'create_user' => session('username'),
+                'update_user' => session('username')
+            );
+            
+            // 执行添加
+            if ($this->model->addModel($data)) {
+                $this->log('新增内容模型成功!');
+                if (! ! $backurl = get('backurl')) {
+                    success('新增成功!', base64_decode($backurl));
+                } else {
+                    success('新增成功!', url('/admin/Model/index'));
+                }
+            } else {
+                $this->log('新增内容模型失败!');
+                error('新增失败!', - 1);
+            }
+        }
+    }
+
+    // 内容模型删除
+    public function del()
+    {
+        if (! $id = get('id', 'int')) {
+            error('传递的参数值错误!', - 1);
+        }
+        
+        if ($this->model->delModel($id)) {
+            $this->log('删除内容模型' . $id . '成功!');
+            success('删除成功!', - 1);
+        } else {
+            $this->log('删除内容模型' . $id . '失败!');
+            error('删除失败!', - 1);
+        }
+    }
+
+    // 内容模型修改
+    public function mod()
+    {
+        if (! $id = get('id', 'int')) {
+            error('传递的参数值错误!', - 1);
+        }
+        
+        // 单独修改状态
+        if (($field = get('field', 'var')) && ! is_null($value = get('value', 'var'))) {
+            if ($this->model->modModel($id, "$field='$value',update_user='" . session('username') . "'")) {
+                location(- 1);
+            } else {
+                alert_back('修改失败!');
+            }
+        }
+        
+        // 修改操作
+        if ($_POST) {
+            
+            // 获取数据
+            $name = post('name');
+            $type = post('type');
+            $urlname = post('urlname');
+            $listtpl = basename(post('listtpl'));
+            $contenttpl = basename(post('contenttpl'));
+            $status = post('status');
+            
+            if (! $name) {
+                alert_back('模型名称不能为空!');
+            }
+            
+            if ($type == 1) {
+                if (! $urlname)
+                    $urlname = 'about';
+            } else {
+                if (! $urlname)
+                    $urlname = 'list';
+            }
+            
+            if ($urlname && ! preg_match('/^[a-zA-Z0-9\-]+$/', $urlname)) {
+                alert_back('模型URL名称只允许字母、数字、横线组成!');
+            }
+            
+            if ($this->model->checkUrlname($urlname, $type, "id<>$id")) {
+                alert_back('模型URL名称与其他模型冲突,请换一个名称!');
+            }
+            
+            if ($this->model->checkSortFilename($urlname)) {
+                alert_back('模型URL名称与栏目URL名称冲突,请换一个名称!');
+            }
+            
+            // 构建数据
+            $data = array(
+                'name' => $name,
+                'type' => $type,
+                'urlname' => $urlname,
+                'listtpl' => $listtpl,
+                'contenttpl' => $contenttpl,
+                'status' => $status,
+                'update_user' => session('username')
+            );
+            
+            // 执行添加
+            if ($this->model->modModel($id, $data)) {
+                $this->log('修改内容模型' . $id . '成功!');
+                if (! ! $backurl = get('backurl')) {
+                    success('修改成功!', base64_decode($backurl));
+                } else {
+                    success('修改成功!', url('/admin/Model/index'));
+                }
+            } else {
+                location(- 1);
+            }
+        } else {
+            // 调取修改内容
+            $this->assign('mod', true);
+            if (! $result = $this->model->getModel($id)) {
+                error('编辑的内容已经不存在!', - 1);
+            }
+            $this->assign('model', $result);
+            $this->display('content/model.html');
+        }
+    }
+}

+ 271 - 0
apps/admin/controller/content/SingleController.php

@@ -0,0 +1,271 @@
+<?php
+/**
+ * @copyright (C)2016-2099 Hnaoyun Inc.
+ * @author XingMeng
+ * @email hnxsh@foxmail.com
+ * @date  2017年12月15日
+ *  单页内容控制器
+ */
+namespace app\admin\controller\content;
+
+use core\basic\Controller;
+use app\admin\model\content\SingleModel;
+
+class SingleController extends Controller
+{
+
+    private $model;
+
+    private $blank;
+
+    public function __construct()
+    {
+        $this->model = new SingleModel();
+    }
+
+    // 单页内容列表
+    public function index()
+    {
+        if ((! ! $id = get('id', 'int')) && $result = $this->model->getSingle($id)) {
+            $this->assign('more', true);
+            $this->assign('content', $result);
+        } else {
+            $this->assign('list', true);
+            if (! $mcode = get('mcode', 'var')) {
+                error('传递的模型编码参数有误,请核对后重试!');
+            }
+            
+            if (! ! ($field = get('field', 'var')) && ! ! ($keyword = get('keyword', 'vars'))) {
+                $result = $this->model->findSingle($mcode, $field, $keyword);
+            } else {
+                $result = $this->model->getList($mcode);
+            }
+            $this->assign('baidu_zz_token', $this->config('baidu_zz_token'));
+            $this->assign('baidu_ks_token', $this->config('baidu_ks_token'));
+            
+            // 模型名称
+            $this->assign('model_name', model('admin.content.Model')->getName($mcode));
+            
+            // 前端地址连接符判断
+            $url_break_char = $this->config('url_break_char') ?: '_';
+            $this->assign('url_break_char', $url_break_char);
+            
+            $this->assign('contents', $result);
+        }
+        $this->display('content/single.html');
+    }
+
+    // 单页内容删除
+    public function del()
+    {
+        if (! $id = get('id', 'int')) {
+            error('传递的参数值错误!', - 1);
+        }
+        
+        if ($this->model->delSingle($id)) {
+            $this->log('删除单页内容' . $id . '成功!');
+            success('删除成功!', - 1);
+        } else {
+            $this->log('删除单页内容' . $id . '失败!');
+            error('删除失败!', - 1);
+        }
+    }
+
+    // 单页内容修改
+    public function mod()
+    {
+        // 前端地址连接符判断
+        if (get('baiduzz') || get('baiduxzh')) {
+            $url_break_char = $this->config('url_break_char') ?: '_';
+            $url_rule_sort_suffix = $this->config('url_rule_sort_suffix') ? true : false;
+        }
+        
+        // 站长普通推送
+        if (! ! $id = get('baiduzz')) {
+            $domain = get_http_url();
+            if (! $token = $this->config('baidu_zz_token')) {
+                alert_back('请先到系统配置中填写百度普通收录推送token值!');
+            }
+            
+            $api = "http://data.zz.baidu.com/urls?site=$domain&token=$token";
+            $data = $this->model->getSingle($id);
+            $data->urlname = $data->urlname ?: 'about';
+            if ($data->outlink) {
+                alert_back('链接类型不允许推送!');
+            }
+            if ($data->filename) {
+                $urls[] = $domain . homeurl('/home/Index/' . $data->filename, $url_rule_sort_suffix);
+            } else {
+                $urls[] = $domain . homeurl('/home/Index/' . $data->urlname . $url_break_char . $data->scode, $url_rule_sort_suffix);
+            }
+            $result = post_baidu($api, $urls);
+            if (isset($result->error)) {
+                $this->log('百度普通收录推送失败:' . $urls[0]);
+                alert_back('推送发生错误:' . $result->message);
+            } elseif (isset($result->success)) {
+                $this->log('百度普通收录推送成功:' . $urls[0]);
+                alert_back('成功推送' . $result->success . '条,今天剩余可推送' . $result->remain . '条数!');
+            } else {
+                alert_back('发生未知错误!');
+            }
+        }
+        
+        // 站长快速推送
+        if (! ! $id = get('baiduks')) {
+            $domain = get_http_url();
+            if (! $token = $this->config('baidu_ks_token')) {
+                alert_back('请先到系统配置中填写百度快速收录推送token值!');
+            }
+            
+            $api = "http://data.zz.baidu.com/urls?site=$domain&token=$token&type=daily";
+            $data = $this->model->getSingle($id);
+            $data->urlname = $data->urlname ?: 'about';
+            if ($data->outlink) {
+                alert_back('链接类型不允许推送!');
+            }
+            if ($data->filename) {
+                $urls[] = $domain . homeurl('/home/Index/' . $data->filename, $url_rule_sort_suffix);
+            } else {
+                $urls[] = $domain . homeurl('/home/Index/' . $data->urlname . $url_break_char . $data->scode, $url_rule_sort_suffix);
+            }
+            $result = post_baidu($api, $urls);
+            if (isset($result->error)) {
+                $this->log('百度快速收录推送失败:' . $urls[0]);
+                alert_back('推送发生错误:' . $result->message);
+            } elseif (isset($result->success_daily)) {
+                $this->log('百度快速收录推送成功:' . $urls[0]);
+                alert_back('成功推送' . $result->success_daily . '条,今天剩余可推送' . $result->remain_daily . '条数!');
+            } else {
+                alert_back('发生未知错误!');
+            }
+        }
+        
+        if (! $id = get('id', 'int')) {
+            error('传递的参数值错误!', - 1);
+        }
+        
+        // 单独修改状态
+        if (($field = get('field', 'var')) && ! is_null($value = get('value', 'var'))) {
+            if ($this->model->modSingle($id, "$field='$value',update_user='" . session('username') . "'")) {
+                location(- 1);
+            } else {
+                alert_back('修改失败!');
+            }
+        }
+        
+        // 修改操作
+        if ($_POST) {
+            
+            // 获取数据
+            $title = post('title');
+            $author = post('author');
+            $source = post('source');
+            $ico = post('ico');
+            $pics = post('pics');
+            $content = post('content');
+            $tags = str_replace(',', ',', post('tags'));
+            $titlecolor = post('titlecolor');
+            $subtitle = post('subtitle');
+            $outlink = post('outlink');
+            $date = post('date');
+            $enclosure = post('enclosure');
+            $keywords = post('keywords');
+            $description = post('description');
+            $status = post('status', 'int');
+            
+            // 获取多图标题
+            $picstitle = post('picstitle');
+            if ($picstitle) {
+                $picstitle = implode(',', $picstitle);
+            }
+            
+            if (! $title) {
+                alert_back('单页内容标题不能为空!');
+            }
+            
+            // 自动提起前一百个字符为描述
+            if (! $description && isset($_POST['content'])) {
+                $description = escape_string(clear_html_blank(substr_both(strip_tags($_POST['content']), 0, 150)));
+            }
+            
+            // 无缩略图时,自动提取文章第一张图为缩略图
+            if (! $ico && preg_match('/<img\s+.*?src=\s?[\'|\"](.*?(\.gif|\.jpg|\.png|\.jpeg))[\'|\"].*?[\/]?>/i', decode_string($content), $srcs) && isset($srcs[1])) {
+                $ico = $srcs[1];
+            }
+            
+            // 缩放缩略图
+            if ($ico) {
+                resize_img(ROOT_PATH . $ico, '', $this->config('ico.max_width'), $this->config('ico.max_height'));
+            }
+            
+            // 构建数据
+            $data = array(
+                'title' => $title,
+                'content' => $content,
+                'tags' => $tags,
+                'author' => $author,
+                'source' => $source,
+                'ico' => $ico,
+                'pics' => $pics,
+                'picstitle' => $picstitle,
+                'titlecolor' => $titlecolor,
+                'subtitle' => $subtitle,
+                'outlink' => $outlink,
+                'date' => $date,
+                'enclosure' => $enclosure,
+                'keywords' => $keywords,
+                'description' => clear_html_blank($description),
+                'status' => $status,
+                'update_user' => session('username')
+            );
+            
+            // 执行添加
+            if ($this->model->modSingle($id, $data)) {
+                
+                // 扩展内容修改
+                foreach ($_POST as $key => $value) {
+                    if (preg_match('/^ext_[\w\-]+$/', $key)) {
+                        $temp = post($key);
+                        if (is_array($temp)) {
+                            $data2[$key] = implode(',', $temp);
+                        } else {
+                            $data2[$key] = str_replace("\r\n", '<br>', $temp);
+                        }
+                    }
+                }
+                if (isset($data2)) {
+                    if ($this->model->findContentExt($id)) {
+                        $this->model->modContentExt($id, $data2);
+                    } else {
+                        $data2['contentid'] = $id;
+                        $this->model->addContentExt($data2);
+                    }
+                }
+                
+                $this->log('修改单页内容' . $id . '成功!');
+                if (! ! $backurl = get('backurl')) {
+                    success('修改成功!', base64_decode($backurl));
+                } else {
+                    success('修改成功!', url('/admin/Single/index/mcode/1'));
+                }
+            } else {
+                location(- 1);
+            }
+        } else {
+            // 调取修改内容
+            $this->assign('mod', true);
+            if (! $result = $this->model->getSingle($id)) {
+                error('编辑的内容已经不存在!', - 1);
+            }
+            $this->assign('content', $result);
+            
+            // 扩展字段
+            if (! $mcode = get('mcode', 'var')) {
+                error('传递的模型编码参数有误,请核对后重试!');
+            }
+            $this->assign('extfield', model('admin.content.ExtField')->getModelField($mcode));
+            
+            $this->display('content/single.html');
+        }
+    }
+}

+ 82 - 0
apps/admin/controller/content/SiteController.php

@@ -0,0 +1,82 @@
+<?php
+/**
+ * @copyright (C)2016-2099 Hnaoyun Inc.
+ * @author XingMeng
+ * @email hnxsh@foxmail.com
+ * @date 2017年3月21日
+ *  站点设置控制器
+ */
+namespace app\admin\controller\content;
+
+use core\basic\Controller;
+use app\admin\model\content\SiteModel;
+
+class SiteController extends Controller
+{
+
+    public function __construct()
+    {
+        $this->model = new SiteModel();
+    }
+
+    // 显示站点信息
+    public function index()
+    {
+        // 获取主题列表
+        $themes = dir_list(ROOT_PATH . current($this->config('tpl_dir')));
+        $this->assign('themes', $themes);
+        
+        // 获取系统配置
+        $this->assign('sites', $this->model->getList());
+        
+        // 显示
+        $this->display('content/site.html');
+    }
+
+    // 修改站点信息
+    public function mod()
+    {
+        if (! $_POST) {
+            return;
+        }
+        
+        $data = array(
+            'title' => post('title'),
+            'subtitle' => post('subtitle'),
+            'domain' => post('domain'),
+            'logo' => post('logo'),
+            'keywords' => post('keywords'),
+            'description' => post('description'),
+            'icp' => post('icp'),
+            'theme' => basename(post('theme')) ?: 'default',
+            'statistical' => post('statistical'),
+            'copyright' => post('copyright')
+        );
+        
+        path_delete(RUN_PATH . '/config'); // 清理缓存的配置文件
+        if ($this->model->checkSite()) {
+            if ($this->model->modSite($data)) {
+                $this->log('修改站点信息成功!');
+                success('修改成功!', - 1);
+            } else {
+                location(- 1);
+            }
+        } else {
+            $data['acode'] = session('acode');
+            if ($this->model->addSite($data)) {
+                $this->log('修改站点信息成功!');
+                success('修改成功!', - 1);
+            } else {
+                location(- 1);
+            }
+        }
+    }
+
+    // 服务器基础信息
+    public function server()
+    {
+        $this->assign('server', get_server_info());
+        $this->display('system/server.html');
+    }
+}
+

+ 195 - 0
apps/admin/controller/content/SlideController.php

@@ -0,0 +1,195 @@
+<?php
+/**
+ * @copyright (C)2016-2099 Hnaoyun Inc.
+ * @author XingMeng
+ * @email hnxsh@foxmail.com
+ * @date 2018年3月1日
+ *  轮播图控制器
+ */
+namespace app\admin\controller\content;
+
+use core\basic\Controller;
+use app\admin\model\content\SlideModel;
+
+class SlideController extends Controller
+{
+
+    private $model;
+
+    public function __construct()
+    {
+        $this->model = new SlideModel();
+    }
+
+    // 轮播图列表
+    public function index()
+    {
+        if ((! ! $id = get('id', 'int')) && $result = $this->model->getSlide($id)) {
+            $this->assign('more', true);
+            $this->assign('slide', $result);
+        } else {
+            $this->assign('list', true);
+            if (! ! ($field = get('field', 'var')) && ! ! ($keyword = get('keyword', 'vars'))) {
+                $result = $this->model->findSlide($field, $keyword);
+            } else {
+                $result = $this->model->getList();
+            }
+            $this->assign('gids', $this->model->getGid());
+            $this->assign('slides', $result);
+        }
+        $this->display('content/slide.html');
+    }
+
+    // 轮播图增加
+    public function add()
+    {
+        if ($_POST) {
+            // 获取数据
+            $gid = post('gid', 'int');
+            $pic = post('pic');
+            $link = post('link');
+            $title = post('title');
+            $subtitle = post('subtitle');
+            $sorting = post('sorting', 'int');
+            
+            if (! $gid) {
+                $gid = $this->model->getMaxGid() + 1;
+            }
+            
+            if (! $pic) {
+                alert_back('图片不能为空!');
+            }
+            
+            // 构建数据
+            $data = array(
+                'acode' => session('acode'),
+                'gid' => $gid,
+                'pic' => $pic,
+                'link' => $link,
+                'title' => $title,
+                'subtitle' => $subtitle,
+                'sorting' => $sorting,
+                'create_user' => session('username'),
+                'update_user' => session('username')
+            );
+            
+            // 执行添加
+            if ($this->model->addSlide($data)) {
+                $this->log('新增轮播图成功!');
+                if (! ! $backurl = get('backurl')) {
+                    success('新增成功!', base64_decode($backurl));
+                } else {
+                    success('新增成功!', url('/admin/Slide/index'));
+                }
+            } else {
+                $this->log('新增轮播图失败!');
+                error('新增失败!', - 1);
+            }
+        }
+    }
+
+    // 轮播图删除
+    public function del()
+    {
+        if (! $id = get('id', 'int')) {
+            error('传递的参数值错误!', - 1);
+        }
+        
+        if ($this->model->delSlide($id)) {
+            $this->log('删除轮播图' . $id . '成功!');
+            success('删除成功!', - 1);
+        } else {
+            $this->log('删除轮播图' . $id . '失败!');
+            error('删除失败!', - 1);
+        }
+    }
+
+    // 轮播图修改
+    public function mod()
+    {
+        if (! ! $submit = post('submit')) {
+            switch ($submit) {
+                case 'sorting': // 修改列表排序
+                    $listall = post('listall');
+                    if ($listall) {
+                        $sorting = post('sorting');
+                        foreach ($listall as $key => $value) {
+                            if ($sorting[$key] === '' || ! is_numeric($sorting[$key]))
+                                $sorting[$key] = 255;
+                            $this->model->modSlide($value, "sorting=" . $sorting[$key]);
+                        }
+                        $this->log('批量修改轮播图排序成功!');
+                        success('修改成功!', - 1);
+                    } else {
+                        alert_back('排序失败,无任何内容!');
+                    }
+                    break;
+            }
+        }
+        
+        if (! $id = get('id', 'int')) {
+            error('传递的参数值错误!', - 1);
+        }
+        
+        // 单独修改状态
+        if (($field = get('field', 'var')) && ! is_null($value = get('value', 'var'))) {
+            if ($this->model->modSlide($id, "$field='$value',update_user='" . session('username') . "'")) {
+                location(- 1);
+            } else {
+                alert_back('修改失败!');
+            }
+        }
+        
+        // 修改操作
+        if ($_POST) {
+            
+            // 获取数据
+            $gid = post('gid', 'int');
+            $pic = post('pic');
+            $link = post('link');
+            $title = post('title');
+            $subtitle = post('subtitle');
+            $sorting = post('sorting', 'int');
+            
+            if (! $gid) {
+                $gid = $this->model->getMaxGid() + 1;
+            }
+            
+            if (! $pic) {
+                alert_back('图片不能为空!');
+            }
+            
+            // 构建数据
+            $data = array(
+                'gid' => $gid,
+                'pic' => $pic,
+                'link' => $link,
+                'title' => $title,
+                'subtitle' => $subtitle,
+                'sorting' => $sorting,
+                'update_user' => session('username')
+            );
+            
+            // 执行添加
+            if ($this->model->modSlide($id, $data)) {
+                $this->log('修改轮播图' . $id . '成功!');
+                if (! ! $backurl = get('backurl')) {
+                    success('修改成功!', base64_decode($backurl));
+                } else {
+                    success('修改成功!', url('/admin/Slide/index'));
+                }
+            } else {
+                location(- 1);
+            }
+        } else {
+            // 调取修改内容
+            $this->assign('mod', true);
+            if (! $result = $this->model->getSlide($id)) {
+                error('编辑的内容已经不存在!', - 1);
+            }
+            $this->assign('gids', $this->model->getGid());
+            $this->assign('slide', $result);
+            $this->display('content/slide.html');
+        }
+    }
+}

+ 157 - 0
apps/admin/controller/content/TagsController.php

@@ -0,0 +1,157 @@
+<?php
+/**
+ * @copyright (C)2016-2099 Hnaoyun Inc.
+ * @author XingMeng
+ * @email hnxsh@foxmail.com
+ * @date 2019年07月12日
+ *  内链链接控制器
+ */
+namespace app\admin\controller\content;
+
+use core\basic\Controller;
+use app\admin\model\content\TagsModel;
+
+class TagsController extends Controller
+{
+
+    private $model;
+
+    public function __construct()
+    {
+        $this->model = new TagsModel();
+    }
+
+    // 文章内链列表
+    public function index()
+    {
+        if ((! ! $id = get('id', 'int')) && $result = $this->model->getTags($id)) {
+            $this->assign('more', true);
+            $this->assign('tags', $result);
+        } else {
+            $this->assign('list', true);
+            if (! ! ($field = get('field', 'var')) && ! ! ($keyword = get('keyword', 'vars'))) {
+                $result = $this->model->findTags($field, $keyword);
+            } else {
+                $result = $this->model->getList();
+            }
+            $this->assign('tags', $result);
+        }
+        $this->display('content/tags.html');
+    }
+
+    // 文章内链增加
+    public function add()
+    {
+        if ($_POST) {
+            // 获取数据
+            $name = post('name');
+            $link = post('link');
+            
+            if (! $name) {
+                alert_back('名称不能为空!');
+            }
+            
+            if (! $link) {
+                alert_back('链接不能为空!');
+            }
+            
+            // 构建数据
+            $data = array(
+                'acode' => session('acode'),
+                'name' => $name,
+                'link' => $link,
+                'create_user' => session('username'),
+                'update_user' => session('username')
+            );
+            
+            // 执行添加
+            if ($this->model->addTags($data)) {
+                $this->log('新增文章内链成功!');
+                if (! ! $backurl = get('backurl')) {
+                    success('新增成功!', base64_decode($backurl));
+                } else {
+                    success('新增成功!', url('/admin/Tags/index'));
+                }
+            } else {
+                $this->log('新增文章内链失败!');
+                error('新增失败!', - 1);
+            }
+        }
+    }
+
+    // 文章内链删除
+    public function del()
+    {
+        if (! $id = get('id', 'int')) {
+            error('传递的参数值错误!', - 1);
+        }
+        
+        if ($this->model->delTags($id)) {
+            $this->log('删除文章内链' . $id . '成功!');
+            success('删除成功!', - 1);
+        } else {
+            $this->log('删除文章内链' . $id . '失败!');
+            error('删除失败!', - 1);
+        }
+    }
+
+    // 文章内链修改
+    public function mod()
+    {
+        if (! $id = get('id', 'int')) {
+            error('传递的参数值错误!', - 1);
+        }
+        
+        // 单独修改状态
+        if (($field = get('field', 'var')) && ! is_null($value = get('value', 'var'))) {
+            if ($this->model->modTags($id, "$field='$value',update_user='" . session('username') . "'")) {
+                location(- 1);
+            } else {
+                alert_back('修改失败!');
+            }
+        }
+        
+        // 修改操作
+        if ($_POST) {
+            
+            // 获取数据
+            $name = post('name');
+            $link = post('link');
+            
+            if (! $name) {
+                alert_back('名称不能为空!');
+            }
+            
+            if (! $link) {
+                alert_back('链接不能为空!');
+            }
+            
+            // 构建数据
+            $data = array(
+                'name' => $name,
+                'link' => $link,
+                'update_user' => session('username')
+            );
+            
+            // 执行添加
+            if ($this->model->modTags($id, $data)) {
+                $this->log('修改文章内链' . $id . '成功!');
+                if (! ! $backurl = get('backurl')) {
+                    success('修改成功!', base64_decode($backurl));
+                } else {
+                    success('修改成功!', url('/admin/Tags/index'));
+                }
+            } else {
+                location(- 1);
+            }
+        } else {
+            // 调取修改内容
+            $this->assign('mod', true);
+            if (! $result = $this->model->getTags($id)) {
+                error('编辑的内容已经不存在!', - 1);
+            }
+            $this->assign('tags', $result);
+            $this->display('content/tags.html');
+        }
+    }
+}

+ 118 - 0
apps/admin/controller/member/MemberCommentController.php

@@ -0,0 +1,118 @@
+<?php
+/**
+ * @copyright (C)2016-2099 Hnaoyun Inc.
+ * @author XingMeng
+ * @email hnxsh@foxmail.com
+ * @date 2020年06月27日
+ *  文章评论控制器
+ */
+namespace app\admin\controller\member;
+
+use core\basic\Controller;
+use app\admin\model\member\MemberCommentModel;
+
+class MemberCommentController extends Controller
+{
+
+    private $model;
+
+    public function __construct()
+    {
+        $this->model = new MemberCommentModel();
+    }
+
+    // 文章评论列表
+    public function index()
+    {
+        if ((! ! $id = get('id', 'int')) && $result = $this->model->getComment($id)) {
+            $this->assign('more', true);
+            $this->assign('comment', $result);
+        } else {
+            $this->assign('list', true);
+            if (! ! ($field = get('field', 'var')) && ! ! ($keyword = get('keyword', 'vars'))) {
+                $result = $this->model->findComment($field, $keyword);
+            } else {
+                $result = $this->model->getList();
+            }
+            $this->assign('comments', $result);
+        }
+        $this->display('member/comment.html');
+    }
+
+    // 文章评论删除
+    public function del()
+    {
+        // 执行批量删除
+        if ($_POST) {
+            if (! ! $list = post('list')) {
+                if ($this->model->delCommentList($list)) {
+                    $this->log('批量删除评论成功!');
+                    success('删除成功!', - 1);
+                } else {
+                    $this->log('批量删除评论失败!');
+                    error('删除失败!', - 1);
+                }
+            } else {
+                alert_back('请选择要删除的评论!');
+            }
+        }
+        
+        if (! $id = get('id', 'int')) {
+            error('传递的参数值错误!', - 1);
+        }
+        
+        if ($this->model->delComment($id)) {
+            $this->log('删除文章评论' . $id . '成功!');
+            success('删除成功!', - 1);
+        } else {
+            $this->log('删除文章评论' . $id . '失败!');
+            error('删除失败!', - 1);
+        }
+    }
+
+    // 字段修改
+    public function mod()
+    {
+        if (! ! $submit = post('submit')) {
+            switch ($submit) {
+                case 'verify1':
+                    $list = post('list');
+                    if (! $list) {
+                        alert_back('请选择要操作的评论!');
+                    }
+                    if ($this->model->modCommentList($list, "status=1")) {
+                        $this->log('评论批量审核成功!');
+                        success('审核成功!', - 1);
+                    } else {
+                        alert_back('审核失败!');
+                    }
+                    break;
+                case 'verify0':
+                    $list = post('list');
+                    if (! $list) {
+                        alert_back('请选择要操作的评论!');
+                    }
+                    if ($this->model->modCommentList($list, "status=0")) {
+                        $this->log('评论批量禁用成功!');
+                        success('禁用成功!', - 1);
+                    } else {
+                        alert_back('禁用失败!');
+                    }
+                    break;
+            }
+        }
+        
+        if (! $id = get('id', 'int')) {
+            error('传递的参数值错误!', - 1);
+        }
+        
+        // 单独修改状态
+        if (($field = get('field', 'var')) && ! is_null($value = get('value', 'var'))) {
+            if ($this->model->modComment($id, "$field='$value',update_user='" . session('username') . "'")) {
+                location(- 1);
+            } else {
+                alert_back('修改失败!');
+            }
+        }
+    }
+}

+ 292 - 0
apps/admin/controller/member/MemberController.php

@@ -0,0 +1,292 @@
+<?php
+/**
+ * @copyright (C)2016-2099 Hnaoyun Inc.
+ * @author XingMeng
+ * @email hnxsh@foxmail.com
+ * @date 2019年10月05日
+ *  会员控制器
+ */
+namespace app\admin\controller\member;
+
+use core\basic\Controller;
+use app\admin\model\member\MemberModel;
+
+class MemberController extends Controller
+{
+
+    private $model;
+
+    public function __construct()
+    {
+        $this->model = new MemberModel();
+    }
+
+    // 会员列表
+    public function index()
+    {
+        if ((! ! $id = get('id', 'int')) && $result = $this->model->getMember($id)) {
+            $this->assign('more', true);
+            $this->assign('fields', $this->model->getFields());
+            $this->assign('member', $result);
+        } else {
+            $this->assign('list', true);
+            if (! ! ($field = get('field', 'var')) && ! ! ($keyword = get('keyword', 'vars'))) {
+                $result = $this->model->findMember($field, $keyword);
+            } else {
+                $result = $this->model->getList();
+            }
+            
+            // 会员等级
+            $this->assign('groups', model('admin.member.MemberGroup')->getSelect());
+            $this->assign('members', $result);
+        }
+        $this->display('member/member.html');
+    }
+
+    // 会员增加
+    public function add()
+    {
+        if ($_POST) {
+            // 获取数据
+            $ucode = get_auto_code($this->model->getLastCode(), 1);
+            $username = post('username');
+            $useremail = post('useremail');
+            $usermobile = post('usermobile');
+            $nickname = post('nickname');
+            $password = post('password');
+            $headpic = post('headpic');
+            $status = post('status') ?: 1;
+            $gid = post('gid');
+            $score = post('score');
+            $register_time = get_datetime();
+            
+            if (! $username) {
+                alert_back('用户账号不能为空!');
+            }
+            
+            if (! preg_match('/^[\w\@\.]+$/', $username)) {
+                alert_back('用户账号含有不允许的特殊字符!');
+            }
+            
+            if ($useremail && ! preg_match('/^[\w]+@[\w\.]+\.[a-zA-Z]+$/', $useremail)) {
+                alert_back('邮箱账号格式不正确!');
+            }
+            
+            if ($usermobile && ! preg_match('/^1[0-9]{10}$/', $usermobile)) {
+                alert_back('手机号码格式不正确!');
+            }
+            
+            if ($username && $this->model->checkMember("username='$username' OR useremail='$username' OR usermobile='$username'")) {
+                alert_back('用户名已经存在!');
+            }
+            
+            if ($useremail && $this->model->checkMember("username='$useremail' OR useremail='$useremail' OR usermobile='$useremail'")) {
+                alert_back('邮箱账号已经存在!');
+            }
+            
+            if ($usermobile && $this->model->checkMember("username='$usermobile' OR useremail='$usermobile' OR usermobile='$usermobile'")) {
+                alert_back('手机号码已经存在!');
+            }
+            
+            if (! $password) {
+                alert_back('密码不能为空!');
+            } else {
+                $password = md5(md5($password));
+            }
+            
+            // 构建数据
+            $data = array(
+                'ucode' => $ucode,
+                'username' => $username,
+                'useremail' => $useremail,
+                'usermobile' => $usermobile,
+                'nickname' => $nickname,
+                'password' => $password,
+                'headpic' => $headpic,
+                'status' => $status,
+                'gid' => $gid,
+                'wxid' => '',
+                'qqid' => '',
+                'wbid' => '',
+                'activation' => 1,
+                'score' => $score,
+                'register_time' => $register_time,
+                'login_count' => 0,
+                'last_login_ip' => 0,
+                'last_login_time' => 0
+            );
+            
+            // 执行添加
+            if ($this->model->addMember($data)) {
+                $this->log('新增会员成功!');
+                if (! ! $backurl = get('backurl')) {
+                    success('新增成功!', base64_decode($backurl));
+                } else {
+                    success('新增成功!', url('/admin/Member/index'));
+                }
+            } else {
+                $this->log('新增会员失败!');
+                error('新增失败!', - 1);
+            }
+        }
+    }
+
+    // 会员删除
+    public function del()
+    {
+        // 执行批量删除
+        if ($_POST) {
+            if (! ! $list = post('list')) {
+                if ($this->model->delMemberList($list)) {
+                    $this->log('批量删除会员成功!');
+                    success('删除成功!', - 1);
+                } else {
+                    $this->log('批量删除会员失败!');
+                    error('删除失败!', - 1);
+                }
+            } else {
+                alert_back('请选择要删除的会员!');
+            }
+        }
+        
+        if (! $id = get('id', 'int')) {
+            error('传递的参数值错误!', - 1);
+        }
+        
+        if ($this->model->delMember($id)) {
+            $this->log('删除会员' . $id . '成功!');
+            success('删除成功!', - 1);
+        } else {
+            $this->log('删除会员' . $id . '失败!');
+            error('删除失败!', - 1);
+        }
+    }
+
+    // 会员修改
+    public function mod()
+    {
+        if (! ! $submit = post('submit')) {
+            switch ($submit) {
+                case 'verify1':
+                    $list = post('list');
+                    if (! $list) {
+                        alert_back('请选择要操作的会员!');
+                    }
+                    if ($this->model->modMemberList($list, "status=1")) {
+                        $this->log('会员批量启用成功!');
+                        success('启用成功!', - 1);
+                    } else {
+                        alert_back('启用失败!');
+                    }
+                    break;
+                case 'verify0':
+                    $list = post('list');
+                    if (! $list) {
+                        alert_back('请选择要操作的会员!');
+                    }
+                    if ($this->model->modMemberList($list, "status=0")) {
+                        $this->log('会员批量禁用成功!');
+                        success('禁用成功!', - 1);
+                    } else {
+                        alert_back('禁用失败!');
+                    }
+                    break;
+            }
+        }
+        
+        if (! $id = get('id', 'int')) {
+            error('传递的参数值错误!', - 1);
+        }
+        
+        // 单独修改状态
+        if (($field = get('field', 'var')) && ! is_null($value = get('value', 'var'))) {
+            if ($this->model->modMember($id, "$field='$value'")) {
+                location(- 1);
+            } else {
+                alert_back('修改失败!');
+            }
+        }
+        
+        // 修改操作
+        if ($_POST) {
+            
+            // 获取数据
+            $username = post('username');
+            $useremail = post('useremail');
+            $usermobile = post('usermobile');
+            $nickname = post('nickname');
+            $password = post('password');
+            $headpic = post('headpic');
+            $status = post('status') ?: 1;
+            $gid = post('gid');
+            $score = post('score');
+            
+            if (! $username) {
+                alert_back('用户账号不能为空!');
+            }
+            
+            if (! preg_match('/^[\w\@\.]+$/', $username)) {
+                alert_back('用户账号含有不允许的特殊字符!');
+            }
+            
+            if ($useremail && ! preg_match('/^[\w]+@[\w\.]+\.[a-zA-Z]+$/', $useremail)) {
+                alert_back('邮箱账号格式不正确!');
+            }
+            
+            if ($usermobile && ! preg_match('/^1[0-9]{10}$/', $usermobile)) {
+                alert_back('手机号码格式不正确!');
+            }
+            
+            if ($username && $this->model->checkMember("(username='$username' OR useremail='$username' OR usermobile='$username') AND id<>$id")) {
+                alert_back('用户名已经存在!');
+            }
+            
+            if ($useremail && $this->model->checkMember("(username='$useremail' OR useremail='$useremail' OR usermobile='$useremail') AND id<>$id")) {
+                alert_back('邮箱账号已经存在!');
+            }
+            
+            if ($usermobile && $this->model->checkMember("(username='$usermobile' OR useremail='$usermobile' OR usermobile='$usermobile') AND id<>$id")) {
+                alert_back('手机号码已经存在!');
+            }
+            
+            // 构建数据
+            $data = array(
+                'username' => $username,
+                'useremail' => $useremail,
+                'usermobile' => $usermobile,
+                'nickname' => $nickname,
+                'headpic' => $headpic,
+                'status' => $status,
+                'gid' => $gid,
+                'score' => $score
+            );
+            
+            if ($password) {
+                $data['password'] = md5(md5($password));
+            }
+            
+            // 执行添加
+            if ($this->model->modMember($id, $data)) {
+                $this->log('修改会员成功!');
+                if (! ! $backurl = get('backurl')) {
+                    success('修改成功!', base64_decode($backurl));
+                } else {
+                    success('修改成功!', url('/admin/Member/index'));
+                }
+            } else {
+                $this->log('修改会员失败!');
+                error('修改失败!', - 1);
+            }
+        } else {
+            // 调取修改内容
+            $this->assign('mod', true);
+            if (! $result = $this->model->getMember($id)) {
+                error('编辑的内容已经不存在!', - 1);
+            }
+            // 会员等级
+            $this->assign('groups', model('admin.member.MemberGroup')->getSelect());
+            $this->assign('member', $result);
+            $this->display('member/member.html');
+        }
+    }
+}

+ 193 - 0
apps/admin/controller/member/MemberFieldController.php

@@ -0,0 +1,193 @@
+<?php
+/**
+ * @copyright (C)2016-2099 Hnaoyun Inc.
+ * @author XingMeng
+ * @email hnxsh@foxmail.com
+ * @date 2020年06月25日
+ *  会员字段控制器
+ */
+namespace app\admin\controller\member;
+
+use core\basic\Controller;
+use app\admin\model\member\MemberFieldModel;
+
+class MemberFieldController extends Controller
+{
+
+    private $model;
+
+    public function __construct()
+    {
+        $this->model = new MemberFieldModel();
+    }
+
+    // 会员字段列表
+    public function index()
+    {
+        if ((! ! $id = get('id', 'int')) && $result = $this->model->getField($id)) {
+            $this->assign('more', true);
+            $this->assign('field', $result);
+        } else {
+            $this->assign('list', true);
+            if (! ! ($field = get('field', 'var')) && ! ! ($keyword = get('keyword', 'vars'))) {
+                $result = $this->model->findField($field, $keyword);
+            } else {
+                $result = $this->model->getList();
+            }
+            $this->assign('fields', $result);
+        }
+        $this->display('member/field.html');
+    }
+
+    // 会员字段增加
+    public function add()
+    {
+        if ($_POST) {
+            
+            // 获取数据
+            $name = post('name', 'var');
+            $length = post('length', 'int') ?: 20;
+            $required = post('required', 'int') ?: 0;
+            $description = post('description');
+            $sorting = post('sorting', 'int') ?: 255;
+            $status = post('status') ?: 1;
+            
+            if (! $name) {
+                alert_back('字段名称不能为空!');
+            }
+            
+            if (! preg_match('/^[a-zA-Z][\w]+$/', $name)) {
+                alert_back('字段名称必须以字母开头!');
+            }
+            
+            if (! $description) {
+                alert_back('字段描述不能为空!');
+            }
+            
+            // 构建数据
+            $data = array(
+                'name' => $name,
+                'length' => $length,
+                'required' => $required,
+                'description' => $description,
+                'sorting' => $sorting,
+                'status' => $status,
+                'create_user' => session('username'),
+                'update_user' => session('username')
+            );
+            
+            // 字段类型及长度
+            $mysql = "varchar($length)";
+            $sqlite = "TEXT($length)";
+            
+            // 字段不存在时创建
+            if (! $this->model->isExistField($name)) {
+                if (get_db_type() == 'sqlite') {
+                    $result = $this->model->amd("ALTER TABLE ay_member ADD COLUMN $name $sqlite NULL");
+                } else {
+                    $result = $this->model->amd("ALTER TABLE ay_member ADD $name $mysql NULL COMMENT '$description'");
+                }
+            } elseif ($this->model->checkField($name)) { // 字段存在且已使用则报错
+                alert_back('字段已经存在,不能重复添加!');
+            }
+            
+            // 执行会员字段添加
+            if ($this->model->addField($data)) {
+                $this->log('新增会员字段成功!');
+                if (! ! $backurl = get('backurl')) {
+                    success('新增成功!', base64_decode($backurl));
+                } else {
+                    success('新增成功!', url('/admin/MemberField/index'));
+                }
+            } else {
+                $this->log('新增会员字段失败!');
+                error('新增失败!', - 1);
+            }
+        }
+    }
+
+    // 会员字段删除
+    public function del()
+    {
+        if (! $id = get('id', 'int')) {
+            error('传递的参数值错误!', - 1);
+        }
+        
+        $name = $this->model->getFieldName($id);
+        if ($this->model->delField($id)) {
+            // mysql数据库执行字段删除,sqlite暂时不支持
+            if (! ! $name) {
+                if (get_db_type() == 'mysql') {
+                    $result = $this->model->amd("ALTER TABLE ay_member DROP COLUMN $name");
+                }
+            }
+            $this->log('删除会员字段' . $id . '成功!');
+            success('删除成功!', - 1);
+        } else {
+            $this->log('删除会员字段' . $id . '失败!');
+            error('删除失败!', - 1);
+        }
+    }
+
+    // 会员字段修改
+    public function mod()
+    {
+        if (! $id = get('id', 'int')) {
+            error('传递的参数值错误!', - 1);
+        }
+        
+        // 单独修改状态
+        if (($field = get('field', 'var')) && ! is_null($value = get('value', 'var'))) {
+            if ($this->model->modField($id, "$field='$value',update_user='" . session('username') . "'")) {
+                location(- 1);
+            } else {
+                alert_back('修改失败!');
+            }
+        }
+        
+        // 修改操作
+        if ($_POST) {
+            
+            // 获取数据
+            $required = post('required', 'int') ?: 0;
+            $description = post('description');
+            $sorting = post('sorting', 'int') ?: 255;
+            $status = post('status') ?: 1;
+            
+            if (! $description) {
+                alert_back('字段描述不能为空!');
+            }
+            
+            // 构建数据
+            $data = array(
+                'required' => $required,
+                'description' => $description,
+                'sorting' => $sorting,
+                'status' => $status,
+                'update_user' => session('username')
+            );
+            
+            // 执行会员字段修改
+            if ($this->model->modField($id, $data)) {
+                $this->log('修改会员字段成功!');
+                if (! ! $backurl = get('backurl')) {
+                    success('修改成功!', base64_decode($backurl));
+                } else {
+                    success('修改成功!', url('/admin/MemberField/index'));
+                }
+            } else {
+                $this->log('修改会员字段失败!');
+                error('修改失败!', - 1);
+            }
+        } else {
+            // 调取修改内容
+            $this->assign('mod', true);
+            if (! $result = $this->model->getField($id)) {
+                error('编辑的内容已经不存在!', - 1);
+            }
+            
+            $this->assign('field', $result);
+            $this->display('member/field.html');
+        }
+    }
+}

+ 187 - 0
apps/admin/controller/member/MemberGroupController.php

@@ -0,0 +1,187 @@
+<?php
+/**
+ * @copyright (C)2016-2099 Hnaoyun Inc.
+ * @author XingMeng
+ * @email hnxsh@foxmail.com
+ * @date 2020年06月25日
+ *  会员等级控制器
+ */
+namespace app\admin\controller\member;
+
+use core\basic\Controller;
+use app\admin\model\member\MemberGroupModel;
+
+class MemberGroupController extends Controller
+{
+
+    private $model;
+
+    public function __construct()
+    {
+        $this->model = new MemberGroupModel();
+    }
+
+    // 会员等级列表
+    public function index()
+    {
+        if ((! ! $id = get('id', 'int')) && $result = $this->model->getGroup($id)) {
+            $this->assign('more', true);
+            $this->assign('group', $result);
+        } else {
+            $this->assign('list', true);
+            if (! ! ($field = get('field', 'var')) && ! ! ($keyword = get('keyword', 'vars'))) {
+                $result = $this->model->findGroup($field, $keyword);
+            } else {
+                $result = $this->model->getList();
+            }
+            $this->assign('groups', $result);
+        }
+        $this->display('member/group.html');
+    }
+
+    // 会员等级增加
+    public function add()
+    {
+        if ($_POST) {
+            
+            // 获取数据
+            $gcode = post('gcode', 'int') ?: get_auto_code($this->model->getLastGid(), 1);
+            $gname = post('gname');
+            $description = post('description');
+            $status = post('status') ?: 1;
+            $lscore = post('lscore', 'int') ?: 0;
+            $uscore = post('uscore', 'int') ?: 9999999999;
+            
+            if (! $gcode) {
+                alert_back('等级编号不能为空!');
+            }
+            
+            if (! $gname) {
+                alert_back('等级名称不能为空!');
+            }
+            
+            if ($this->model->findGroupCode($gcode)) {
+                alert_back('等级编码不能重复!');
+            }
+            
+            // 构建数据
+            $data = array(
+                'gcode' => $gcode,
+                'gname' => $gname,
+                'description' => $description,
+                'status' => $status,
+                'lscore' => $lscore,
+                'uscore' => $uscore,
+                'create_user' => session('username'),
+                'update_user' => session('username')
+            );
+            
+            // 执行会员等级添加
+            if ($this->model->addGroup($data)) {
+                $this->log('新增会员等级成功!');
+                if (! ! $backurl = get('backurl')) {
+                    success('新增成功!', base64_decode($backurl));
+                } else {
+                    success('新增成功!', url('/admin/MemberGroup/index'));
+                }
+            } else {
+                $this->log('新增会员等级失败!');
+                error('新增失败!', - 1);
+            }
+        }
+    }
+
+    // 会员等级删除
+    public function del()
+    {
+        if (! $id = get('id', 'int')) {
+            error('传递的参数值错误!', - 1);
+        }
+        
+        if ($this->model->findGroupUser($id)) {
+            error('会员等级下存在用户,无法直接删除!', - 1);
+        }
+        
+        if ($this->model->delGroup($id)) {
+            $this->log('删除会员等级' . $id . '成功!');
+            success('删除成功!', - 1);
+        } else {
+            $this->log('删除会员等级' . $id . '失败!');
+            error('删除失败!', - 1);
+        }
+    }
+
+    // 会员等级修改
+    public function mod()
+    {
+        if (! $id = get('id', 'int')) {
+            error('传递的参数值错误!', - 1);
+        }
+        
+        // 单独修改状态
+        if (($field = get('field', 'var')) && ! is_null($value = get('value', 'var'))) {
+            if ($this->model->modGroup($id, "$field='$value',update_user='" . session('username') . "'")) {
+                location(- 1);
+            } else {
+                alert_back('修改失败!');
+            }
+        }
+        
+        // 修改操作
+        if ($_POST) {
+            
+            // 获取数据
+            $gcode = post('gcode', 'int') ?: get_auto_code($this->model->getLastGid(), 1);
+            $gname = post('gname');
+            $description = post('description');
+            $status = post('status') ?: 1;
+            $lscore = post('lscore', 'int') ?: 0;
+            $uscore = post('uscore', 'int') ?: 9999999999;
+            
+            if (! $gcode) {
+                alert_back('等级编号不能为空!');
+            }
+            
+            if (! $gname) {
+                alert_back('等级名称不能为空!');
+            }
+            
+            if ($this->model->findGroupCode($gcode, $id)) {
+                alert_back('等级编码不能重复!');
+            }
+            
+            // 构建数据
+            $data = array(
+                'gcode' => $gcode,
+                'gname' => $gname,
+                'description' => $description,
+                'status' => $status,
+                'lscore' => $lscore,
+                'uscore' => $uscore,
+                'update_user' => session('username')
+            );
+            
+            // 执行会员等级修改
+            if ($this->model->modGroup($id, $data)) {
+                $this->log('修改会员等级成功!');
+                if (! ! $backurl = get('backurl')) {
+                    success('修改成功!', base64_decode($backurl));
+                } else {
+                    success('修改成功!', url('/admin/MemberGroup/index'));
+                }
+            } else {
+                $this->log('修改会员等级失败!');
+                error('修改失败!', - 1);
+            }
+        } else {
+            // 调取修改内容
+            $this->assign('mod', true);
+            if (! $result = $this->model->getGroup($id)) {
+                error('编辑的内容已经不存在!', - 1);
+            }
+            
+            $this->assign('group', $result);
+            $this->display('member/group.html');
+        }
+    }
+}

+ 303 - 0
apps/admin/controller/system/AreaController.php

@@ -0,0 +1,303 @@
+<?php
+/**
+ * @copyright (C)2016-2099 Hnaoyun Inc.
+ * @author XingMeng
+ * @email hnxsh@foxmail.com
+ * @date 2017年4月3日
+ *  区域控制器
+ */
+namespace app\admin\controller\system;
+
+use core\basic\Controller;
+use app\admin\model\system\AreaModel;
+
+class AreaController extends Controller
+{
+
+    private $count;
+
+    private $blank;
+
+    private $outData = array();
+
+    private $model;
+
+    public function __construct()
+    {
+        $this->model = new AreaModel();
+    }
+
+    // 区域列表
+    public function index()
+    {
+        $this->assign('list', true);
+        $area_tree = $this->model->getList();
+        $areas = $this->makeAreaList($area_tree);
+        $this->assign('areas', $areas);
+        
+        // 区域下拉表
+        $area_tree = $this->model->getSelect();
+        $area_select = $this->makeAreaSelect($area_tree);
+        $this->assign('area_select', $area_select);
+        
+        $this->display('system/area.html');
+    }
+
+    // 生成无限级区域列表
+    private function makeAreaList($tree)
+    {
+        // 循环生成
+        foreach ($tree as $value) {
+            $this->count ++;
+            $this->outData[$this->count] = new \stdClass();
+            $this->outData[$this->count]->id = $value->id;
+            $this->outData[$this->count]->blank = $this->blank;
+            $this->outData[$this->count]->name = $value->name;
+            $this->outData[$this->count]->domain = $value->domain;
+            $this->outData[$this->count]->acode = $value->acode;
+            $this->outData[$this->count]->pcode = $value->pcode;
+            $this->outData[$this->count]->is_default = $value->is_default;
+            $this->outData[$this->count]->create_user = $value->create_user;
+            $this->outData[$this->count]->update_user = $value->update_user;
+            $this->outData[$this->count]->create_time = $value->create_time;
+            $this->outData[$this->count]->update_time = $value->update_time;
+            
+            if ($value->son) {
+                $this->outData[$this->count]->son = true;
+            } else {
+                $this->outData[$this->count]->son = false;
+            }
+            
+            // 子菜单处理
+            if ($value->son) {
+                $this->blank .= '  ';
+                $this->makeAreaList($value->son);
+            }
+        }
+        
+        // 循环完后回归缩进位置
+        $this->blank = substr($this->blank, 6);
+        return $this->outData;
+    }
+
+    // 区域增加
+    public function add()
+    {
+        if ($_POST) {
+            // 获取数据
+            $acode = post('acode', 'var');
+            $pcode = post('pcode', 'var');
+            $name = post('name');
+            $domain = post('domain');
+            $is_default = post('is_default');
+            
+            if (! $acode) {
+                alert_back('编码不能为空!');
+            }
+            
+            if (! $pcode) { // 父编码默认为0
+                $pcode = 0;
+            }
+            
+            if (! $name) {
+                alert_back('区域名称不能为空!');
+            }
+            
+            if ($domain) {
+                $reg = '{^(https://|http://)?([\w\-.]+)([\/]+)?$}';
+                if (preg_match($reg, $domain)) {
+                    $domain = preg_replace($reg, '$2', $domain);
+                } else {
+                    alert_back('要绑定的域名输入有错!');
+                }
+                
+                // 检查绑定
+                if ($this->model->checkArea("domain='$domain'")) {
+                    alert_back('该域名已经绑定其他区域,不能再使用!');
+                }
+            }
+            
+            // 检查编码
+            if ($this->model->checkArea("acode='$acode'")) {
+                alert_back('该区域编号已经存在,不能再使用!');
+            }
+            
+            // 构建数据
+            $data = array(
+                'acode' => $acode,
+                'pcode' => $pcode,
+                'name' => $name,
+                'domain' => $domain,
+                'is_default' => $is_default,
+                'create_user' => session('username'),
+                'update_user' => session('username')
+            );
+            
+            // 执行添加
+            if ($this->model->addArea($data)) {
+                if (session('ucode') == '10001') {
+                    $acodes = session('acodes');
+                    $acodes[] = $acode;
+                    session('acodes', $acodes); // 更新管理员管理区域
+                    $model = model('Index');
+                    $areas = $model->getAreas();
+                    session('area_map', get_mapping($areas, 'name', 'acode')); // 更新区域代码名称映射表
+                    session('area_tree', $model->getUserAreaTree($areas, 0, 'acode', 'pcode', 'son', $acodes)); // 更新当前用户的区域树
+                }
+                $this->log('新增数据区域' . $acode . '成功!');
+                path_delete(RUN_PATH . '/config'); // 清理缓存的配置文件
+                if (! ! $backurl = get('backurl')) {
+                    success('新增成功!', base64_decode($backurl));
+                } else {
+                    success('新增成功!', url('/admin/Area/index'));
+                }
+            } else {
+                $this->log('新增数据区域' . $acode . '失败!');
+                error('新增失败!', - 1);
+            }
+        }
+    }
+
+    // 生成区域选择
+    private function makeAreaSelect($tree, $selectid = null)
+    {
+        $list_html = '';
+        foreach ($tree as $value) {
+            // 默认选择项
+            if ($selectid == $value->acode) {
+                $select = "selected='selected'";
+            } else {
+                $select = '';
+            }
+            if (get('acode') != $value->acode) { // 不显示本身,避免出现自身为自己的父节点
+                $list_html .= "<option value='{$value->acode}' $select>{$this->blank}{$value->acode} {$value->name}</option>";
+            }
+            // 子菜单处理
+            if ($value->son) {
+                $this->blank .= '  ';
+                $list_html .= $this->makeAreaSelect($value->son, $selectid);
+            }
+        }
+        // 循环完后回归位置
+        $this->blank = substr($this->blank, 0, - 6);
+        return $list_html;
+    }
+
+    // 区域删除
+    public function del()
+    {
+        if (! $acode = get('acode', 'var')) {
+            error('传递的参数值错误!', - 1);
+        }
+        
+        if ($acode == 'cn') {
+            error('系统内置区域不允许删除!', - 1);
+        }
+        
+        if ($this->model->delArea($acode)) {
+            path_delete(RUN_PATH . '/config'); // 清理缓存的配置文件
+            $this->log('删除数据区域' . $acode . '成功!');
+            session_unset();
+            success('删除成功,请重新登录', url('/admin/Index/index'));
+        } else {
+            $this->log('删除数据区域' . $acode . '失败!');
+            error('删除失败,请核对是否为默认区域!', - 1);
+        }
+    }
+
+    // 区域修改
+    public function mod()
+    {
+        if (! $acode = get('acode', 'var')) {
+            error('传递的参数值错误!', - 1);
+        }
+        
+        // 修改操作
+        if ($_POST) {
+            // 获取数据
+            $acode_new = post('acode', 'var');
+            $pcode = post('pcode', 'var');
+            $name = post('name');
+            $domain = post('domain');
+            $is_default = post('is_default');
+            
+            if (! $acode_new) {
+                alert_back('编码不能为空!');
+            }
+            
+            if (! $pcode) { // 父编码默认为0
+                $pcode = 0;
+            }
+            
+            if (! $name) {
+                alert_back('区域名称不能为空!');
+            }
+            
+            if ($domain) {
+                $reg = '{^(https://|http://)?([\w\-.]+)([\/]+)?$}';
+                if (preg_match($reg, $domain)) {
+                    $domain = preg_replace($reg, '$2', $domain);
+                } else {
+                    alert_back('要绑定的域名输入有错!');
+                }
+                
+                // 检查绑定
+                if ($this->model->checkArea("domain='$domain' AND acode<>'$acode'")) {
+                    alert_back('该域名已经绑定其他区域,不能再使用!');
+                }
+            }
+            
+            // 检查编码
+            if ($this->model->checkArea("acode='$acode_new' AND acode<>'$acode'")) {
+                alert_back('该区域编号已经存在,不能再使用!');
+            }
+            
+            // 构建数据
+            $data = array(
+                'acode' => $acode_new,
+                'pcode' => $pcode,
+                'name' => $name,
+                'domain' => $domain,
+                'is_default' => $is_default,
+                'update_user' => session('username')
+            );
+            
+            // 执行添加
+            if ($this->model->modArea($acode, $data)) {
+                if (session('ucode') == '10001') {
+                    $acodes = session('acodes');
+                    $acodes[] = $acode_new;
+                    session('acodes', $acodes); // 更新管理员管理区域
+                    $model = model('Index');
+                    $areas = $model->getAreas();
+                    session('area_map', get_mapping($areas, 'name', 'acode')); // 更新区域代码名称映射表
+                    session('area_tree', $model->getUserAreaTree($areas, 0, 'acode', 'pcode', 'son', $acodes)); // 更新当前用户的区域树
+                }
+                $this->log('修改数据区域' . $acode . '成功!');
+                path_delete(RUN_PATH . '/config'); // 清理缓存的配置文件
+                if (! ! $backurl = get('backurl')) {
+                    success('修改成功!', base64_decode($backurl));
+                } else {
+                    success('修改成功!', url('/admin/Area/index'));
+                }
+            } else {
+                location(- 1);
+            }
+        } else { // 调取修改内容
+            $this->assign('mod', true);
+            
+            $area = $this->model->getArea($acode);
+            if (! $area) {
+                error('编辑的内容已经不存在!', - 1);
+            }
+            $this->assign('area', $area);
+            
+            // 父编码下拉选择
+            $area_tree = $this->model->getSelect();
+            $area_select = $this->makeAreaSelect($area_tree, $area->pcode);
+            $this->assign('area_select', $area_select);
+            
+            $this->display('system/area.html');
+        }
+    }
+}

+ 231 - 0
apps/admin/controller/system/ConfigController.php

@@ -0,0 +1,231 @@
+<?php
+/**
+ * @copyright (C)2016-2099 Hnaoyun Inc.
+ * @author XingMeng
+ * @email hnxsh@foxmail.com
+ * @date 2018年01月03日
+ *  应用配置控制器
+ */
+namespace app\admin\controller\system;
+
+use core\basic\Controller;
+use app\admin\model\system\ConfigModel;
+use core\basic\Config;
+
+class ConfigController extends Controller
+{
+
+    private $model;
+
+    public function __construct()
+    {
+        $this->model = new ConfigModel();
+    }
+
+    // 应用配置列表
+    public function index()
+    {
+        if (! ! $action = get('action')) {
+            switch ($action) {
+                case 'sendemail':
+                    $rs = sendmail($this->config(), get('to'), '【' . CMSNAME . '】测试邮件', '欢迎您使用' . CMSNAME . '网站开发管理系统!');
+                    if ($rs === true) {
+                        alert_back('测试邮件发送成功!');
+                    } else {
+                        error('发送失败:' . $rs);
+                    }
+                    break;
+            }
+        }
+        
+        // 修改参数配置
+        if ($_POST) {
+            unset($_POST['upload']); // 去除上传组件
+            if (isset($_POST['sn'])) {
+                $_POST['licensecode'] = base64_encode(post('sn') . '/' . post('sn_user')) . substr(post('sn'), 1, 1);
+            }
+            foreach ($_POST as $key => $value) {
+                if (! preg_match('/^[\w\-]+$/', $key)) {
+                    continue;
+                }
+                $config = array(
+                    'debug',
+                    // 'sn',
+                    // 'sn_user',
+                    'pagenum',
+                    'tpl_html_cache',
+                    'tpl_html_cache_time',
+                    'session_in_sitepath'
+                );
+                if (in_array($key, $config)) {
+                    if ($key == 'tpl_html_cache_time' && ! $value) {
+                        $value = 900;
+                    } else {
+                        $value = post($key);
+                    }
+                    $this->modConfig($key, $value);
+                } else {
+                    $this->modDbConfig($key);
+                }
+            }
+            
+            $this->log('修改参数配置成功!');
+            path_delete(RUN_PATH . '/config'); // 清理缓存的配置文件
+            
+            switch (post('submit')) {
+                case 'email':
+                    success('修改成功!', url('/admin/Config/index' . get_tab('t2'), false));
+                    break;
+                case 'baidu':
+                    success('修改成功!', url('/admin/Config/index' . get_tab('t3'), false));
+                    break;
+                case 'api':
+                    success('修改成功!', url('/admin/Config/index' . get_tab('t4'), false));
+                    break;
+                case 'watermark':
+                    success('修改成功!', url('/admin/Config/index' . get_tab('t5'), false));
+                    break;
+                case 'security':
+                    success('修改成功!', url('/admin/Config/index' . get_tab('t6'), false));
+                    break;
+                case 'urlrule':
+                    success('修改成功!', url('/admin/Config/index' . get_tab('t7'), false));
+                    break;
+                case 'pagetitle':
+                    success('修改成功!', url('/admin/Config/index' . get_tab('t8'), false));
+                    break;
+                case 'member':
+                    success('修改成功!', url('/admin/Config/index' . get_tab('t9'), false));
+                    break;
+                case 'upgrade':
+                    success('修改成功!', url('/admin/Upgrade/index' . get_tab('t2'), false));
+                    break;
+                default:
+                    success('修改成功!', url('/admin/Config/index', false));
+            }
+        }
+        $configs = $this->model->getList();
+        $configs['debug']['value'] = $this->config('debug');
+        if (! $configs['sn']['value']) {
+            $configs['sn']['value'] = $this->config('sn');
+            $configs['sn_user']['value'] = $this->config('sn_user');
+        }
+        $configs['session_in_sitepath']['value'] = $this->config('session_in_sitepath');
+        $configs['pagenum']['value'] = $this->config('pagenum');
+        $configs['url_type']['value'] = $this->config('url_type');
+        $configs['tpl_html_cache']['value'] = $this->config('tpl_html_cache');
+        $configs['tpl_html_cache_time']['value'] = $this->config('tpl_html_cache_time');
+        $this->assign('configs', $configs);
+        
+        $this->assign('groups', model('admin.member.MemberGroup')->getSelect());
+        
+        $this->display('system/config.html');
+    }
+
+    // 修改配置文件
+    private function modConfig($key, $value)
+    {
+        $value = str_replace(' ', '', $value); // 去除空格
+        $value = str_replace(',', ',', $value); // 转换可能输入的中文逗号
+        if (! preg_match('/^[\w\s\,\-]+$/', $value)) {
+            return;
+        }
+        
+        $config = file_get_contents(CONF_PATH . '/config.php');
+        if (preg_match("'$key'", $config)) {
+            if (preg_match('/^[0-9]+$/', $value)) {
+                $config = preg_replace('/(\'' . $key . '\'([\s]+)?=>([\s]+)?)[\w\'\"\s,]+,/', '${1}' . $value . ',', $config);
+            } else {
+                $config = preg_replace('/(\'' . $key . '\'([\s]+)?=>([\s]+)?)[\w\'\"\s,]+,/', '${1}\'' . $value . '\',', $config);
+            }
+        } else {
+            $config = preg_replace('/(return array\()/', "$1\r\n\r\n\t'$key' => '$value',", $config); // 自动新增配置
+        }
+        return file_put_contents(CONF_PATH . '/config.php', $config);
+    }
+
+    // 修改数据库配置
+    private function modDbConfig($key)
+    {
+        $value = post($key);
+        
+        // 如果开启伪静态时自动拷贝文件
+        if ($key == 'url_rule_type' && $value == 2) {
+            $soft = get_server_soft();
+            if ($soft == 'iis') {
+                if (! file_exists(ROOT_PATH . '/web.config')) {
+                    copy(ROOT_PATH . '/rewrite/web.config', ROOT_PATH . '/web.config');
+                }
+            } elseif ($soft == 'apache') {
+                if (! file_exists(ROOT_PATH . '/web.config')) {
+                    copy(ROOT_PATH . '/rewrite/.htaccess', ROOT_PATH . '/.htaccess');
+                }
+            }
+        }
+        
+        // 模板目录修改
+        if (($key == 'tpl_html_dir') && $value) {
+            
+            // 不允许特殊字符
+            if (! preg_match('/^\w+$/', $value)) {
+                return;
+            }
+            
+            $value = basename($value);
+            $htmldir = $this->config('tpl_html_dir');
+            $tpl_path = ROOT_PATH . current($this->config('tpl_dir')) . '/' . model('admin.content.ContentSort')->getTheme();
+            
+            if (! $htmldir || ! file_exists($tpl_path . '/' . $htmldir)) {
+                if (! check_dir($tpl_path . '/' . $value, true)) {
+                    return;
+                } // 原来没有目录时只创建目录,创建失败时直接不修改
+            } else {
+                if ($value != $htmldir) {
+                    if (file_exists($tpl_path . '/' . $value)) {
+                        if (dir_copy($tpl_path . '/' . $htmldir, $tpl_path . '/' . $value)) {
+                            path_delete($tpl_path . '/' . $htmldir, true); // 删除原来的
+                        } else {
+                            return; // 修改失败
+                        }
+                    } else {
+                        if (! rename($tpl_path . '/' . $htmldir, $tpl_path . '/' . $value)) {
+                            return; // 修改失败
+                        }
+                    }
+                }
+            }
+        }
+        
+        if ($key == 'home_upload_ext') {
+            // 不允许特殊扩展
+            if (preg_match('/(php|jsp|asp|exe|sh|cmd|vb|vbs|phtml)/i', $value)) {
+                return;
+            }
+        }
+        
+        // 数据分割处理
+        $hander = array(
+            'content_keyword_replace',
+            'ip_deny',
+            'ip_allow'
+        );
+        if (in_array($key, $hander) && $value) {
+            $value = str_replace("\r\n", ",", $value); // 替换回车
+            $value = str_replace(",", ",", $value); // 替换中文逗号分割符
+        }
+        
+        if ($this->model->checkConfig("name='$key'")) {
+            $this->model->modValue($key, $value);
+        } elseif ($key != 'submit' && $key != 'formcheck') {
+            // 自动新增配置项
+            $data = array(
+                'name' => $key,
+                'value' => $value,
+                'type' => 2,
+                'sorting' => 255,
+                'description' => ''
+            );
+            return $this->model->addConfig($data);
+        }
+    }
+}

+ 248 - 0
apps/admin/controller/system/DatabaseController.php

@@ -0,0 +1,248 @@
+<?php
+/**
+ * @copyright (C)2016-2099 Hnaoyun Inc.
+ * @author XingMeng
+ * @email hnxsh@foxmail.com
+ * @date 2017年5月9日
+ *  数据库管理,只支持MySQL
+ */
+namespace app\admin\controller\system;
+
+use core\basic\Controller;
+use app\admin\model\system\DatabaseModel;
+
+class DatabaseController extends Controller
+{
+
+    private $model;
+
+    private $dbauth;
+
+    function __construct()
+    {
+        $this->model = new DatabaseModel();
+        $this->dbauth = $this->config('database');
+    }
+
+    // 数据库管理
+    public function index()
+    {
+        switch ($this->dbauth['type']) {
+            case 'mysqli':
+            case 'pdo_mysql':
+                $this->assign('db', 'mysql');
+                $this->assign('tables', $this->model->getList());
+                break;
+            case 'sqlite':
+            case 'pdo_sqlite':
+                $this->assign('db', 'sqlite');
+                break;
+            default:
+                error('当前配置的数据库类型不支持在线管理!');
+        }
+        $this->display('system/database.html');
+    }
+
+    // 数据库修改
+    public function mod()
+    {
+        if (! $_POST) {
+            alert_back('非法访问!', - 1);
+        }
+        
+        $submit = post('submit', 'letter', true);
+        
+        switch ($submit) {
+            case 'yh':
+                $tables = self::getTableList();
+                if (! $tables)
+                    alert_back('请选择数据表!');
+                if ($this->model->optimize(implode(',', $tables))) {
+                    // $this->log('优化数据库表成功!');
+                    success('优化成功!', - 1);
+                } else {
+                    // $this->log('优化数据库表失败!');
+                    error('优化失败!', - 1);
+                }
+                break;
+            case 'xf':
+                $tables = self::getTableList();
+                if (! $tables)
+                    alert_back('请选择数据表!');
+                if ($this->model->repair(implode(',', $tables))) {
+                    // $this->log('修复数据库表成功!');
+                    success('修复成功!', - 1);
+                } else {
+                    // $this->log('修复数据库表失败!');
+                    error('修复失败!', - 1);
+                }
+                break;
+            case 'bf':
+                $tables = self::getTableList();
+                if (! $tables)
+                    alert_back('请选择数据表!');
+                if ($this->backupTable($tables)) {
+                    $this->log('备份数据库表成功!');
+                    success('备份表成功!', - 1);
+                } else {
+                    $this->log('备份数据库表失败!');
+                    error('备份失败!', - 1);
+                }
+                break;
+            case 'bfdb':
+                if ($this->backupDB()) {
+                    $this->log('备份数据库成功!');
+                    success('备份数据库成功!', - 1);
+                } else {
+                    $this->log('备份数据库失败!');
+                    error('备份失败!', - 1);
+                }
+                break;
+            case 'bfsqlite':
+                if (copy(DOC_PATH . $this->dbauth['dbname'], DOC_PATH . STATIC_DIR . '/backup/sql/' . get_uniqid() . '_' . date('YmdHis') . '.db')) {
+                    $this->log('备份数据库成功!');
+                    success('备份数据库成功!', - 1);
+                } else {
+                    $this->log('备份数据库失败!');
+                    error('备份失败!', - 1);
+                }
+                break;
+        }
+    }
+
+    // 备份数据表
+    public function backupTable($tables)
+    {
+        $backdir = date('YmdHis');
+        foreach ($tables as $table) {
+            $sql = '';
+            $sql .= $this->header(); // 备份文件头部说明
+            $sql .= $this->tableSql($table); // 表结构信息
+            $fields = $this->model->getFields($table); // 表字段
+            $field_num = $this->model->getFieldNum($table); // 字段数量
+            $all_data = $this->model->getAll($table); // 读取全部数据
+            $sql .= $this->dataSql($table, $fields, $field_num, $all_data); // 生成语句
+            $filename = $backdir . "/" . get_uniqid() . "_" . $backdir . "_" . $table . '.sql'; // 写入文件
+            $result = $this->writeFile($filename, $sql);
+        }
+        return $result;
+    }
+
+    // 备份整个数据库
+    public function backupDB()
+    {
+        $sql = '';
+        $sql .= $this->header(); // 备份文件头部说明
+        $sql .= $this->dbSql(); // 数据库创建语句
+        
+        $tables = $this->model->getTables(); // 获取所有表
+        foreach ($tables as $table) { // 表结构及数据
+            $sql .= $this->tableSql($table); // 表结构信息
+            $fields = $this->model->getFields($table); // 表字段
+            $field_num = $this->model->getFieldNum($table); // 字段数量
+            $all_data = $this->model->getAll($table); // 读取全部数据
+            if ($all_data) {
+                $sql .= $this->dataSql($table, $fields, $field_num, $all_data); // 生成数据语句
+            }
+            $sql .= '-- --------------------------------------------------------' . PHP_EOL . PHP_EOL;
+        }
+        // 写入文件
+        $filename = get_uniqid() . '_' . date('YmdHis') . '_' . $this->dbauth['dbname'] . '.sql';
+        return $this->writeFile($filename, $sql);
+    }
+
+    // 插入数据库备份基础信息
+    private function header()
+    {
+        $sql = '-- Online Database Management SQL Dump' . PHP_EOL;
+        $sql .= '-- 数据库名: ' . $this->dbauth['dbname'] . PHP_EOL;
+        $sql .= '-- 生成日期: ' . date('Y-m-d H:i:s') . PHP_EOL;
+        $sql .= '-- PHP 版本: ' . phpversion() . PHP_EOL . PHP_EOL;
+        
+        $sql .= 'SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";' . PHP_EOL;
+        $sql .= 'SET time_zone = "+08:00";' . PHP_EOL;
+        $sql .= 'SET NAMES utf8;' . PHP_EOL . PHP_EOL;
+        
+        $sql .= '-- --------------------------------------------------------' . PHP_EOL . PHP_EOL;
+        return $sql;
+    }
+
+    // 数据库创建语句
+    private function dbSql()
+    {
+        $sql = '';
+        $sql .= "--" . PHP_EOL;
+        $sql .= "-- 数据库名 `" . $this->dbauth['dbname'] . '`' . PHP_EOL;
+        $sql .= "--" . PHP_EOL . PHP_EOL;
+        
+        // 如果数据库不存在则创建
+        $sql .= "CREATE DATABASE IF NOT EXISTS `" . $this->dbauth['dbname'] . '` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;' . PHP_EOL;
+        // 选择数据库
+        $sql .= "USE `" . $this->dbauth['dbname'] . "`;" . PHP_EOL . PHP_EOL;
+        $sql .= '-- --------------------------------------------------------' . PHP_EOL . PHP_EOL;
+        return $sql;
+    }
+
+    // 表结构语句
+    private function tableSql($table)
+    {
+        $sql = '';
+        $sql .= "--" . PHP_EOL;
+        $sql .= "-- 表的结构 `" . $table . '`' . PHP_EOL;
+        $sql .= "--" . PHP_EOL . PHP_EOL;
+        
+        $sql .= $this->model->tableStru($table); // 表创建语句
+        return $sql;
+    }
+
+    // 数据语句
+    private function dataSql($table, $fields, $fieldNnum, $data)
+    {
+        if (! $data)
+            return;
+        $sql = '';
+        $sql .= "--" . PHP_EOL;
+        $sql .= "-- 转存表中的数据 `" . $table . "`" . PHP_EOL;
+        $sql .= "--" . PHP_EOL;
+        $sql .= PHP_EOL;
+        
+        // 循环每个字段下面的内容
+        
+        $sql .= "INSERT INTO `" . $table . "` (" . implode(',', $fields) . ") VALUES" . PHP_EOL;
+        $brackets = "(";
+        foreach ($data as $value) {
+            $sql .= $brackets;
+            $comma = "";
+            for ($i = 0; $i < $fieldNnum; $i ++) {
+                $sql .= ($comma . "'" . addslashes(decode_string($value[$i])) . "'");
+                $comma = ",";
+            }
+            $sql .= ")";
+            $brackets = "," . PHP_EOL . "(";
+        }
+        $sql .= ';' . PHP_EOL . PHP_EOL;
+        return $sql;
+    }
+
+    // 写入文件
+    private function writeFile($filename, $content)
+    {
+        $sqlfile = DOC_PATH . STATIC_DIR . '/backup/sql/' . $filename;
+        check_file($sqlfile, true);
+        if (file_put_contents($sqlfile, $content)) {
+            return true;
+        }
+    }
+
+    // 获取并检查表名称
+    private function getTableList()
+    {
+        $list = post('list');
+        foreach ($list as $key => $value) {
+            if (! preg_match('/^[\w]+$/', $value)) {
+                unset($list[$key]);
+            }
+        }
+        return $list;
+    }
+}

+ 152 - 0
apps/admin/controller/system/ImageExtController.php

@@ -0,0 +1,152 @@
+<?php
+
+namespace app\admin\controller\system;
+
+use app\admin\model\content\CompanyModel;
+use app\admin\model\content\ContentModel;
+use app\admin\model\content\ContentSortModel;
+use app\admin\model\content\LinkModel;
+use app\admin\model\content\SiteModel;
+use app\admin\model\content\SlideModel;
+use app\admin\model\content\LabelModel;
+use app\home\model\MemberModel;
+use core\basic\Controller;
+
+class ImageExtController extends Controller
+{
+    private $companyModel;
+    private $contentSortModel;
+    private $contentModel;
+    private $linkModel;
+    private $memberModel;
+    private $siteModel;
+    private $slideModel;
+	private $LabelModel;
+
+    public function __construct()
+    {
+        $this->companyModel = new CompanyModel();
+        $this->contentSortModel = new ContentSortModel();
+        $this->contentModel = new ContentModel();
+        $this->linkModel = new LinkModel();
+        $this->memberModel = new MemberModel();
+        $this->siteModel = new SiteModel();
+        $this->slideModel = new SlideModel();
+		$this->LabelModel = new LabelModel();
+    }
+
+    public function index()
+    {
+        $this->display('system/extimage.html');
+    }
+
+    public function checkDataFile()
+    {
+        $count = 30;
+        $page = get('page') ? get('page') : 1;
+        $start = ($page - 1) * $count;
+        $dataArr = [];
+        $company = $this->companyModel->getImage();
+        $contentSort = $this->contentSortModel->getImage();
+        $content = $this->contentModel->getImage();
+        $link = $this->linkModel->getImage();
+        $member = $this->memberModel->getImage();
+        $site = $this->siteModel->getImage();
+        $slide = $this->slideModel->getImage();
+		$label = $this->LabelModel->getImage();
+        $resArr = array_merge_recursive($company, $contentSort, $content, $link, $member, $site, $slide, $label);
+        array_walk_recursive($resArr, function ($key1) use (&$dataArr) {
+            if (!empty($key1)) {
+                $dataArr[] = DOC_PATH . SITE_DIR .$key1;
+            }
+            return $dataArr;
+        });
+        $dataArr = array_unique($dataArr);
+        //获取上传的文件
+        $Filepath = DOC_PATH . STATIC_DIR . '/upload';
+        $fileList = get_dir($Filepath);
+        $fileArr = [];
+        array_walk_recursive($fileList, function ($key) use (&$fileArr) {
+            $fileArr[] = $key;
+            return $fileArr;
+        });
+
+        //对比文件
+        $difference = array_diff($fileArr, $dataArr);
+        $pageList = array_slice($difference, $start, $count);
+        $http = is_https() ? 'https://' : 'http://';
+        foreach ($pageList as &$value) {
+            $value = [
+                'real_path' => $value,
+                'static_path' => $http . $_SERVER['SERVER_NAME'] . str_replace(DOC_PATH, '', $value),
+                'update_time' => date('Y-m-d H:i:s', filemtime($value))
+            ];
+        }
+        $jsonData = ['code' => 0,'msg'=> '', 'count' => count($difference),'data' => $pageList];
+        return json_encode($jsonData);
+
+    }
+
+    public function do_ext()
+    {
+        $type = post('type');
+        $list = post('list');
+
+        $movePath = DOC_PATH . STATIC_DIR . '/backup/ImageExt';
+        check_dir($movePath, true);
+
+        switch ($type){
+            case 0:
+                //清理所选文件
+                foreach ($list as $value){
+                    $fileName = substr(strrchr($value['real_path'], "/"), 1);
+                    $filePath = strstr($value['real_path'],'/static');
+                    $fileDir = str_replace($fileName,'',$filePath);
+                    check_dir($movePath . $fileDir, true);
+                    rename($value['real_path'], $movePath . $filePath);
+                }
+                break;
+            case 1:
+                //清理所有冗余文件
+                //获取上传的文件
+                $Filepath = DOC_PATH . STATIC_DIR . '/upload';
+                $fileList = get_dir($Filepath);
+                $fileArr = [];
+                array_walk_recursive($fileList, function ($key) use (&$fileArr) {
+                    $fileArr[] = $key;
+                    return $fileArr;
+                });
+                //查询数据
+                $dataArr = [];
+                $company = $this->companyModel->getImage();
+                $contentSort = $this->contentSortModel->getImage();
+                $content = $this->contentModel->getImage();
+                $link = $this->linkModel->getImage();
+                $member = $this->memberModel->getImage();
+                $site = $this->siteModel->getImage();
+                $slide = $this->slideModel->getImage();
+				$Label = $this->LabelModel->getImage();
+                $resArr = array_merge_recursive($company, $contentSort, $content, $link, $member, $site, $slide, $Label);
+                array_walk_recursive($resArr, function ($key1) use (&$dataArr) {
+                    if (!empty($key1)) {
+                        $dataArr[] = DOC_PATH . SITE_DIR .$key1;
+                    }
+                    return $dataArr;
+                });
+                $dataArr = array_unique($dataArr);
+                //对比文件并执行文件迁移
+                $difference = array_diff($fileArr, $dataArr);
+                $movePath = DOC_PATH . STATIC_DIR . '/backup/ImageExt/';
+                check_dir($movePath, true);
+                foreach ($difference as $path) {
+                    $fileName = substr(strrchr($path, "/"), 1);
+                    $filePath = strstr($path,'/static');
+                    $fileDir = str_replace($fileName,'',$filePath);
+                    check_dir($movePath . $fileDir, true);
+                    rename($path, $movePath . $filePath);
+                }
+                break;
+        }
+        json(1,'');
+    }
+}

+ 275 - 0
apps/admin/controller/system/MenuController.php

@@ -0,0 +1,275 @@
+<?php
+/**
+ * @copyright (C)2016-2099 Hnaoyun Inc.
+ * @author XingMeng
+ * @email hnxsh@foxmail.com
+ * @date 2017年4月3日
+ *  菜单控制器 
+ */
+namespace app\admin\controller\system;
+
+use core\basic\Controller;
+use app\admin\model\system\MenuModel;
+
+class MenuController extends Controller
+{
+
+    private $count;
+
+    private $blank;
+
+    private $outData = array();
+
+    private $model;
+
+    public function __construct()
+    {
+        $this->model = new MenuModel();
+    }
+
+    // 菜单列表
+    public function index()
+    {
+        $this->assign('list', true);
+        $menus = $this->model->getList();
+        $this->assign('menus', $this->makeMenuList($menus));
+        
+        // 菜单下拉列表
+        $menus = $this->model->getSelect();
+        $this->assign('menu_select', $this->makeMenuSelect($menus));
+        
+        // 获取菜单按钮
+        $this->assign('actions', get_type('T101'));
+        
+        $this->display('system/menu.html');
+    }
+
+    // 生成无限级菜单管理列表
+    private function makeMenuList($tree)
+    {
+        // 循环生成
+        foreach ($tree as $value) {
+            $this->count ++;
+            $this->outData[$this->count] = new \stdClass();
+            $this->outData[$this->count]->id = $value->id;
+            $this->outData[$this->count]->blank = $this->blank;
+            $this->outData[$this->count]->name = $value->name;
+            $this->outData[$this->count]->mcode = $value->mcode;
+            $this->outData[$this->count]->pcode = $value->pcode;
+            $this->outData[$this->count]->sorting = $value->sorting;
+            $this->outData[$this->count]->url = $value->url;
+            $this->outData[$this->count]->status = $value->status;
+            $this->outData[$this->count]->shortcut = $value->shortcut;
+            $this->outData[$this->count]->ico = $value->ico;
+            $this->outData[$this->count]->create_user = $value->create_user;
+            $this->outData[$this->count]->update_user = $value->update_user;
+            $this->outData[$this->count]->create_time = $value->create_time;
+            $this->outData[$this->count]->update_time = $value->update_time;
+            
+            if ($value->son) {
+                $this->outData[$this->count]->son = true;
+            } else {
+                $this->outData[$this->count]->son = false;
+            }
+            // 子菜单处理
+            if ($value->son) {
+                $this->blank .= '  ';
+                $this->makeMenuList($value->son);
+            }
+        }
+        // 循环完后回归缩进位置
+        $this->blank = substr($this->blank, 0, - 6);
+        return $this->outData;
+    }
+
+    // 菜单增加
+    public function add()
+    {
+        if ($_POST) {
+            // 获取数据
+            $mcode = get_auto_code($this->model->getLastCode()); // 自动编码
+            $pcode = post('pcode', 'var');
+            $name = post('name');
+            $url = post('url');
+            $sorting = post('sorting', 'int');
+            $status = post('status', 'int');
+            $shortcut = post('shortcut', 'int');
+            $ico = post('ico');
+            $actions = post('actions', 'array', false, '菜单按钮', array());
+            
+            if (! $mcode) {
+                alert_back('编码不能为空!');
+            }
+            if (! $pcode) {
+                $pcode = 0; // 父编码默认为0
+            }
+            if (! $name) {
+                alert_back('菜单名称不能为空!');
+            }
+            
+            if ($this->model->checkMenu("mcode='$mcode'")) {
+                alert_back('该菜单编号已经存在,不能再使用!');
+            }
+            
+            // 菜单地址自动填充
+            if (! $url) {
+                $url = '/' . M . '/' . $mcode . '/index';
+            }
+            
+            // 构建数据
+            $data = array(
+                'mcode' => $mcode,
+                'pcode' => $pcode,
+                'name' => $name,
+                'url' => $url,
+                'sorting' => $sorting,
+                'status' => $status,
+                'shortcut' => $shortcut,
+                'ico' => $ico,
+                'create_user' => session('username'),
+                'update_user' => session('username')
+            );
+            
+            // 执行添加
+            if ($this->model->addMenu($data, $actions)) {
+                $this->log('新增菜单' . $mcode . '成功!');
+                if (! ! $backurl = get('backurl')) {
+                    success('新增成功!', base64_decode($backurl));
+                } else {
+                    success('新增成功!', url('admin/Menu/index'));
+                }
+            } else {
+                $this->log('新增菜单' . $mcode . '失败!');
+                error('新增失败!', - 1);
+            }
+        }
+    }
+
+    // 生成菜单下拉列表
+    private function makeMenuSelect($tree, $selectid = null)
+    {
+        // 初始化
+        $menu_html = '';
+        // 循环生成
+        foreach ($tree as $value) {
+            // 默认选择项
+            if ($selectid == $value->mcode) {
+                $select = "selected='selected'";
+            } else {
+                $select = '';
+            }
+            if (get('mcode') != $value->mcode) { // 不显示本身,避免出现自身为自己的父节点
+                $menu_html .= "<option value='{$value->mcode}' $select />{$this->blank}{$value->mcode} {$value->name}";
+            }
+            // 子菜单处理
+            if ($value->son) {
+                $this->blank .= '  ';
+                $menu_html .= $this->makeMenuSelect($value->son, $selectid);
+            }
+        }
+        // 循环完后回归位置
+        $this->blank = substr($this->blank, 0, - 6);
+        return $menu_html;
+    }
+
+    // 菜单删除
+    public function del()
+    {
+        if (! $mcode = get('mcode', 'var')) {
+            error('传递的参数值错误!', - 1);
+        }
+        if ($this->model->delMenu($mcode)) {
+            $this->log('删除菜单' . $mcode . '成功!');
+            success('删除成功!', - 1);
+        } else {
+            $this->log('删除菜单' . $mcode . '失败!');
+            error('删除失败!', - 1);
+        }
+    }
+
+    // 菜单修改
+    public function mod()
+    {
+        if (! $mcode = get('mcode', 'var')) {
+            error('传递的参数值错误!', - 1);
+        }
+        
+        // 单独修改状态
+        if (($field = get('field', 'var')) && ! is_null($value = get('value', 'var'))) {
+            if ($this->model->modMenu($mcode, "$field='$value',update_user='" . session('username') . "'")) {
+                $this->log('修改菜单' . $mcode . '状态' . $value . '成功!');
+                location(- 1);
+            } else {
+                $this->log('修改菜单' . $mcode . '状态' . $value . '失败!');
+                alert_back('修改失败!');
+            }
+        }
+        
+        // 修改操作
+        if ($_POST) {
+            // 获取数据
+            $pcode = post('pcode', 'var');
+            $name = post('name');
+            $sorting = post('sorting', 'int');
+            $url = post('url');
+            $status = post('status', 'int');
+            $shortcut = post('shortcut', 'int');
+            $ico = post('ico');
+            $actions = post('actions', 'array', false, '菜单按钮', array());
+            
+            if (! $pcode) {
+                $pcode = 0; // 父编码默认为0
+            }
+            if (! $name) {
+                alert_back('菜单名称不能为空!');
+            }
+            // 菜单地址自动填充
+            if (! $url) {
+                $url = '/' . M . '/' . $mcode . '/index';
+            }
+            
+            // 构建数据
+            $data = array(
+                'pcode' => $pcode,
+                'name' => $name,
+                'sorting' => $sorting,
+                'url' => $url,
+                'status' => $status,
+                'shortcut' => $shortcut,
+                'ico' => $ico,
+                'update_user' => session('username')
+            );
+            
+            // 执行修改
+            if ($this->model->modMenu($mcode, $data, $actions)) {
+                $this->log('修改菜单' . $mcode . '成功!');
+                if (! ! $backurl = get('backurl')) {
+                    success('修改成功!', base64_decode($backurl));
+                } else {
+                    success('修改成功!', url('admin/Menu/index'));
+                }
+            } else {
+                location(- 1);
+            }
+        } else { // 调取修改内容
+            
+            $this->assign('mod', true);
+            
+            $result = $this->model->getMenu($mcode);
+            if (! $result) {
+                error('编辑的内容已经不存在!', - 1);
+            }
+            $this->assign('menu', $result); // 菜单信息
+                                            
+            // 获取菜单按钮组
+            $this->assign('actions', get_type('T101'));
+            
+            // 菜单下拉列表
+            $menus = $this->model->getSelect();
+            $this->assign('menu_select', $this->makeMenuSelect($menus, $result->pcode));
+            
+            // 显示
+            $this->display('system/menu.html');
+        }
+    }
+}

+ 249 - 0
apps/admin/controller/system/RoleController.php

@@ -0,0 +1,249 @@
+<?php
+/**
+ * @copyright (C)2016-2099 Hnaoyun Inc.
+ * @author XingMeng
+ * @email hnxsh@foxmail.com
+ * @date 2017年4月3日
+ *  角色控制器
+ */
+namespace app\admin\controller\system;
+
+use core\basic\Controller;
+use app\admin\model\system\RoleModel;
+
+class RoleController extends Controller
+{
+
+    private $blank;
+
+    private $model;
+
+    public function __construct()
+    {
+        $this->model = new RoleModel();
+    }
+
+    // 角色列表
+    public function index()
+    {
+        $this->assign('list', true);
+        $this->assign('roles', $this->model->getList());
+        
+        // 数据区域选择
+        $area_model = model('admin.system.Area');
+        $area_tree = $area_model->getSelect();
+        $area_checkbox = $this->makeAreaCheckbox($area_tree);
+        $this->assign('area_checkbox', $area_checkbox);
+        
+        // 菜单权限表
+        $menu_model = model('admin.system.Menu');
+        $menu_level = $menu_model->getMenuLevel();
+        $menus = $menu_model->getSelect();
+        $menu_list = $this->makeLevelList($menus, $menu_level);
+        $this->assign('menu_list', $menu_list);
+        
+        $this->display('system/role.html');
+    }
+
+    // 角色增加
+    public function add()
+    {
+        if ($_POST) {
+            // 获取数据
+            $rcode = get_auto_code($this->model->getLastCode()); // 自动编码
+            $name = post('name');
+            $description = post('description');
+            $acodes = post('acodes', 'array', false, '角色数据区域', array()); // 区域
+            $levels = post('levels', 'array', false, '角色权限', array()); // 权限
+            
+            if (! $rcode) {
+                alert_back('编码不能为空!');
+            }
+            
+            if (! $name) {
+                alert_back('角色名不能为空!');
+            }
+            
+            // 检查编码
+            if ($this->model->checkRole("rcode='$rcode'")) {
+                alert_back('该角色编号已经存在,不能再使用!');
+            }
+            
+            // 构建数据
+            $data = array(
+                'rcode' => $rcode,
+                'name' => $name,
+                'description' => $description,
+                'create_user' => session('username'),
+                'update_user' => session('username')
+            );
+            
+            // 执行添加
+            if ($this->model->addRole($data, $acodes, $levels)) {
+                $this->log('修改角色' . $rcode . '成功!');
+                if (! ! $backurl = get('backurl')) {
+                    success('新增成功!', base64_decode($backurl));
+                } else {
+                    success('新增成功!', url('admin/Role/index'));
+                }
+            } else {
+                $this->log('修改角色' . $rcode . '失败!');
+                error('新增失败!', - 1);
+            }
+        }
+    }
+
+    // 生成区域选择,无限制
+    private function makeAreaCheckbox($tree, $checkeds = array())
+    {
+        $list_html = '';
+        foreach ($tree as $values) {
+            if (in_array($values->acode, $checkeds)) {
+                $checked = 'checked="checked"';
+            } else {
+                $checked = '';
+            }
+            if (! $values->son) { // 没有子类才显示选择框
+                $list_html .= "<input type='checkbox' $checked name='acodes[]' value='{$values->acode}' title='{$values->acode}-{$values->name}'>";
+            } else {
+                $list_html .= $this->makeAreaCheckbox($values->son, $checkeds);
+            }
+        }
+        return $list_html;
+    }
+
+    // 生成无限级菜单权限列表
+    private function makeLevelList($menus, $menu_level, $checkeds = array())
+    {
+        $menu_html = '';
+        foreach ($menus as $value) {
+            $string = '';
+            // 根据是否有子栏目生成图标
+            if ($value->son) {
+                $ico = "<i class='fa fa-folder-open-o' aria-hidden='true'></i>";
+            } else {
+                $ico = "<i class='fa fa-folder-o' aria-hidden='true'></i>";
+            }
+            
+            // 选中状态
+            if (in_array($value->url, $checkeds)) {
+                $checked = 'checked="checked"';
+            } else {
+                $checked = '';
+            }
+            
+            // 获取模块及控制器路径
+            if ($value->url) {
+                $pre_url = substr($value->url, 0, get_strpos($value->url, '/', 3) + 1);
+            } else {
+                error('"' . $value->name . '"菜单地址为空,请核对!');
+            }
+            
+            $string = "<input type='checkbox' $checked class='checkbox' lay-skin='primary'  name='levels[]' value='" . $value->url . "' title='浏览'>";
+            $mcode = $value->mcode;
+            if (array_key_exists($mcode, $menu_level)) {
+                foreach ($menu_level[$mcode] as $key2 => $value2) {
+                    $url = $pre_url . $value2->value;
+                    if (in_array($url, $checkeds)) {
+                        $checked = 'checked="checked"';
+                    } else {
+                        $checked = '';
+                    }
+                    $string .= "<input type='checkbox' $checked class='checkbox'lay-skin='primary' name='levels[]' value='$url' title='{$value2->item}'>";
+                }
+            }
+            
+            // 生成菜单html
+            $menu_html .= "<div class='layui-row'><div class='layui-col-md3 layui-col-lg2' style='margin-top:10px;'>{$this->blank} $ico {$value->name}</div><div class='layui-col-md9'>$string</div></div>";
+            
+            // 子菜单处理
+            if ($value->son) {
+                $this->blank .= '  ';
+                $menu_html .= $this->makeLevelList($value->son, $menu_level, $checkeds);
+            }
+        }
+        
+        // 循环完后回归缩进位置
+        $this->blank = substr($this->blank, 0, - 6);
+        return $menu_html;
+    }
+
+    // 角色删除
+    public function del()
+    {
+        if (! $rcode = get('rcode', 'var')) {
+            error('传递的参数值错误!', - 1);
+        }
+        if ($this->model->delRole($rcode)) {
+            $this->log('删除角色' . $rcode . '成功!');
+            success('删除成功!', - 1);
+        } else {
+            $this->log('删除角色' . $rcode . '失败!');
+            error('删除失败!', - 1);
+        }
+    }
+
+    // 角色修改
+    public function mod()
+    {
+        if (! $rcode = get('rcode', 'var')) {
+            error('传递的参数值错误!', - 1);
+        }
+        
+        // 修改操作
+        if ($_POST) {
+            // 获取数据
+            $name = post('name');
+            $description = post('description');
+            $acodes = post('acodes', 'array', false, '角色数据区域', array()); // 区域
+            $levels = post('levels', 'array', false, '角色权限', array()); // 权限
+            
+            if (! $name) {
+                alert_back('角色名不能为空!');
+            }
+            
+            // 构建数据
+            $data = array(
+                'name' => $name,
+                'description' => $description,
+                'update_user' => session('username')
+            );
+            
+            // 执行修改
+            if ($this->model->modRole($rcode, $data, $acodes, $levels)) {
+                $this->log('修改角色' . $rcode . '成功!');
+                if (! ! $backurl = get('backurl')) {
+                    success('修改成功!', base64_decode($backurl));
+                } else {
+                    success('修改成功!', url('admin/Role/index'));
+                }
+            } else {
+                location(- 1);
+            }
+        } else {
+            $this->assign('mod', true);
+            
+            // 调取修改内容
+            $result = $this->model->getRole($rcode);
+            if (! $result) {
+                error('编辑的内容已经不存在!', - 1);
+            }
+            $this->assign('role', $result);
+            
+            // 数据区域选择
+            $area_model = model('admin.system.Area');
+            $area_tree = $area_model->getSelect();
+            $area_checkbox = $this->makeAreaCheckbox($area_tree, $result->acodes);
+            $this->assign('area_checkbox', $area_checkbox);
+            
+            // 菜单权限表
+            $menu_model = model('admin.system.Menu');
+            $menu_level = $menu_model->getMenuLevel();
+            $menus = $menu_model->getSelect();
+            $menu_list = $this->makeLevelList($menus, $menu_level, $result->levels);
+            $this->assign('menu_list', $menu_list);
+            
+            $this->display('system/role.html');
+        }
+    }
+}

+ 40 - 0
apps/admin/controller/system/SyslogController.php

@@ -0,0 +1,40 @@
+<?php
+/**
+ * @copyright (C)2016-2099 Hnaoyun Inc.
+ * @author XingMeng
+ * @email hnxsh@foxmail.com
+ * @date 2017年3月29日
+ *  系统日志控制器
+ */
+namespace app\admin\controller\system;
+
+use core\basic\Controller;
+use app\admin\model\system\SyslogModel;
+
+class SyslogController extends Controller
+{
+
+    private $model;
+
+    public function __construct()
+    {
+        $this->model = new SyslogModel();
+    }
+
+    // 日志列表
+    public function index()
+    {
+        $this->assign('syslogs', $this->model->getList());
+        $this->display('system/syslog.html');
+    }
+
+    // 清理日志
+    public function clear()
+    {
+        if ($this->model->clearLog()) {
+            alert_location('清空成功!', url('/admin/Syslog/index'));
+        } else {
+            alert_location('清空失败!', url('/admin/Syslog/index'));
+        }
+    }
+}

+ 172 - 0
apps/admin/controller/system/TypeController.php

@@ -0,0 +1,172 @@
+<?php
+/**
+ * @copyright (C)2016-2099 Hnaoyun Inc.
+ * @author XingMeng
+ * @email hnxsh@foxmail.com
+ * @date 2017年4月13日
+ *  类型控制器
+ */
+namespace app\admin\controller\system;
+
+use core\basic\Controller;
+use app\admin\model\system\TypeModel;
+
+class TypeController extends Controller
+{
+
+    private $model;
+
+    public function __construct()
+    {
+        $this->model = new TypeModel();
+    }
+
+    // 类型列表
+    public function index()
+    {
+        $this->assign('list', true);
+        if (! ! ($field = get('field', 'var')) && ! ! ($keyword = get('keyword', 'vars'))) {
+            $result = $this->model->findType($field, $keyword);
+        } else {
+            $result = $this->model->getList();
+        }
+        
+        $this->assign('types', $result);
+        
+        // 类型选择
+        $this->assign('type_select', $this->model->getSelect());
+        
+        $this->display('system/type.html');
+    }
+
+    // 类型增加
+    public function add()
+    {
+        if ($_POST) {
+            // 获取数据
+            $tcode = post('tcode', 'var');
+            $name = post('name');
+            $item = post('item');
+            $value = post('value', 'var');
+            $sorting = post('sorting', 'int');
+            
+            if (! $tcode) {
+                $tcode = get_auto_code($this->model->getLastCode()); // 自动编码
+            }
+            
+            if (! $name) {
+                alert_back('类型名不能为空!');
+            }
+            
+            if (! $item) {
+                alert_back('类型项名称不能为空!');
+            }
+            
+            if (is_null($value)) {
+                alert_back('类型项值不能为空!');
+            }
+            
+            // 构建数据
+            $data = array(
+                'tcode' => $tcode,
+                'name' => $name,
+                'item' => $item,
+                'value' => $value,
+                'sorting' => $sorting,
+                'create_user' => session('username'),
+                'update_user' => session('username')
+            );
+            
+            // 执行添加
+            if ($this->model->addType($data)) {
+                $this->log('新增类型' . $tcode . '-' . $item . '成功!');
+                if (! ! $backurl = get('backurl')) {
+                    success('新增成功!', base64_decode($backurl));
+                } else {
+                    success('新增成功!', url('/admin/Type/index'));
+                }
+            } else {
+                $this->log('新增类型' . $tcode . '-' . $item . '失败!');
+                error('新增失败!', - 1);
+            }
+        }
+    }
+
+    // 类型删除
+    public function del()
+    {
+        if (! $id = get('id', 'int')) {
+            error('传递的参数值错误!', - 1);
+        }
+        if ($id < 7) {
+            alert_back('该类型不允许删除!');
+        }
+        
+        if ($this->model->delType($id)) {
+            $this->log('删除类型项' . $id . '成功!');
+            success('删除成功!', - 1);
+        } else {
+            $this->log('删除类型项' . $id . '失败!');
+            error('删除失败!', - 1);
+        }
+    }
+
+    // 类型修改
+    public function mod()
+    {
+        if (! $id = get('id', 'int')) {
+            error('传递的参数值错误!', - 1);
+        }
+        
+        // 修改操作
+        if ($_POST) {
+            // 获取数据
+            $name = post('name');
+            $item = post('item');
+            $value = post('value', 'var');
+            $sorting = post('sorting', 'int');
+            
+            if (! $name) {
+                alert_back('类型名不能为空!');
+            }
+            
+            if (! $item) {
+                alert_back('类型项名称不能为空!');
+            }
+            
+            if (is_null($value)) {
+                alert_back('类型项值不能为空!');
+            }
+            
+            // 构建数据
+            $data = array(
+                'name' => $name,
+                'item' => $item,
+                'value' => $value,
+                'sorting' => $sorting,
+                'update_user' => session('username')
+            );
+            
+            // 执行添加
+            if ($this->model->modType($id, $data)) {
+                $this->log('修改类型项' . $id . '成功!');
+                if (! ! $backurl = get('backurl')) {
+                    success('修改成功!', base64_decode($backurl));
+                } else {
+                    success('修改成功!', url('/admin/Type/index'));
+                }
+            } else {
+                location(- 1);
+            }
+        } else {
+            // 调取修改内容
+            $this->assign('mod', true);
+            
+            if (! $result = $this->model->getType($id)) {
+                error('编辑的内容已经不存在!', - 1);
+            }
+            $this->assign('type', $result);
+            $this->display('system/type.html');
+        }
+    }
+}

+ 408 - 0
apps/admin/controller/system/UpgradeController.php

@@ -0,0 +1,408 @@
+<?php
+/**
+ * @copyright (C)2016-2099 Hnaoyun Inc.
+ * @author XingMeng
+ * @email hnxsh@foxmail.com
+ * @date 2018年8月14日
+ *  在线更新
+ */
+namespace app\admin\controller\system;
+
+use core\basic\Controller;
+use core\basic\Model;
+
+class UpgradeController extends Controller
+{
+
+    // 服务器地址
+    private $server = 'https://www.pbootcms.com';
+
+    // 更新分支
+    private $branch;
+
+    // 强制同步文件
+    private $force;
+
+    // 修改版本
+    private $revise;
+
+    // 文件列表
+    public $files = array();
+
+    public function __construct()
+    {
+        error_reporting(0);
+        $this->branch = $this->config('upgrade_branch') == '3.X.dev' ? '3.X.dev' : '3.X';
+        $this->force = $this->config('upgrade_force') ?: 0;
+        $this->revise = $this->config('revise_version') ?: 0;
+    }
+
+    public function index()
+    {
+        switch (get('action')) {
+            case 'local':
+                $upfile = $this->local();
+                break;
+            default:
+                $upfile = array();
+        }
+        $this->assign('upfile', $upfile);
+        $this->assign('branch', $this->branch);
+        $this->assign('force', $this->force);
+        $this->assign('revise', $this->revise);
+        $this->assign('snuser', $this->config('sn_user') ?: 0);
+        $this->assign('site', get_http_url());
+        $this->display('system/upgrade.html');
+    }
+
+    public function checkCache(){
+        $now = time();
+        $cache = $_SESSION['check_cache'];
+        if(!$cache){
+            $_SESSION['check_cache'] = time();
+            json(1,'');
+        }else{
+            $sub = $now - $cache;
+            if($sub > 3600){
+                $_SESSION['check_cache'] = time();
+                json(1,'');
+            }else{
+                json(0,'');
+            }
+        }
+    }
+
+    // 检查更新
+    public function check()
+    {
+        // 清理目录,检查下载目录及备份目录
+        path_delete(RUN_PATH . '/upgrade', true);
+        if (! check_dir(RUN_PATH . '/upgrade', true)) {
+            json(0, '目录写入权限不足,无法正常升级!' . RUN_PATH . '/upgrade');
+        }
+        check_dir(DOC_PATH . STATIC_DIR . '/backup/upgrade', true);
+        
+        $files = $this->getServerList();
+        $db = get_db_type();
+        foreach ($files as $key => $value) {
+            // 过滤掉相对路径
+            $value->path = preg_replace_r('{\.\.(\/|\\\\)}', '', $value->path);
+            $file = ROOT_PATH . $value->path;
+            if (@md5_file($file) != $value->md5) {
+                // 筛选数据库更新脚本
+                if (preg_match('/([\w]+)-([\w\.]+)-update\.sql/i', $file, $matches)) {
+                    if ($matches[1] != $db || ! $this->compareVersion($matches[2], APP_VERSION . '.' . RELEASE_TIME . '.' . $this->revise)) {
+                        continue;
+                    }
+                }
+                if (file_exists($file)) {
+                    $files[$key]->type = '<span style="color:Red">覆盖</span>';
+                    $files[$key]->ltime = date('Y-m-d H:i:s', filemtime($file));
+                } else {
+                    $files[$key]->type = '新增';
+                    $files[$key]->ltime = '无';
+                }
+                $files[$key]->ctime = date('Y-m-d H:i:s', $files[$key]->ctime);
+                $upfile[] = $files[$key];
+            }
+        }
+        if (! $upfile) {
+            json(1, '您的系统无任何文件需要更新!');
+        } else {
+            json(1, $upfile);
+        }
+    }
+
+    // 执行下载
+    public function down()
+    {
+        if (! ! $list = get('list')) {
+            if (! is_array($list)) { // 单个文件转换为数组
+                $list = array(
+                    $list
+                );
+            }
+            $len = count($list) ?: 0;
+            foreach ($list as $value) {
+                // 过滤掉相对路径
+                $value = preg_replace_r('{\.\.(\/|\\\\)}', '', $value);
+                // 本地存储路径
+                $path = RUN_PATH . '/upgrade' . $value;
+                // 自动创建目录
+                if (! check_dir(dirname($path), true)) {
+                    json(0, '目录写入权限不足,无法下载升级文件!' . dirname($path));
+                }
+                
+                // 定义执行下载的类型
+                $types = '.zip|.rar|.doc|.docx|.ppt|.pptx|.xls|.xlsx|.chm|.ttf|.otf|';
+                $pathinfo = explode(".", basename($path));
+                $ext = end($pathinfo); // 获取扩展
+                if (preg_match('/\.' . $ext . '\|/i', $types)) {
+                    $result = $this->getServerDown('/release/' . $this->branch . $value, $path);
+                } else {
+                    $result = $this->getServerFile($value, $path);
+                }
+            }
+            if ($len == 1) {
+                json(1, "更新文件 " . basename($value) . " 下载成功!");
+            } else {
+                json(1, "更新文件" . basename($value) . "等文件全部下载成功!");
+            }
+        } else {
+            json(0, '请选择要下载的文件!');
+        }
+    }
+
+    // 执行更新
+    public function update()
+    {
+        if ($_POST) {
+            if (! ! $list = post('list')) {
+                $list = explode(',', $list);
+                $backdir = date('YmdHis');
+                
+                // 分离文件
+                foreach ($list as $value) {
+                    // 过滤掉相对路径
+                    $value = preg_replace_r('{\.\.(\/|\\\\)}', '', $value);
+                    
+                    if (stripos($value, '/script/') === 0 && preg_match('/\.sql$/i', $value)) {
+                        $sqls[] = $value;
+                    } else {
+                        $path = RUN_PATH . '/upgrade' . $value;
+                        $des_path = ROOT_PATH . $value;
+                        $back_path = DOC_PATH . STATIC_DIR . '/backup/upgrade/' . $backdir . $value;
+                        if (! check_dir(dirname($des_path), true)) {
+                            json(0, '目录写入权限不足,无法正常升级!' . dirname($des_path));
+                        }
+                        if (file_exists($des_path)) { // 文件存在时执行备份
+                            check_dir(dirname($back_path), true);
+                            copy($des_path, $back_path);
+                        }
+                        
+                        // 如果后台入口文件修改过名字,则自动适配
+                        if (stripos($path, 'admin.php') !== false && stripos($_SERVER['SCRIPT_FILENAME'], 'admin.php') === false) {
+                            if (file_exists($_SERVER['SCRIPT_FILENAME'])) {
+                                $des_path = $_SERVER['SCRIPT_FILENAME'];
+                            }
+                        }
+                        
+                        $files[] = array(
+                            'sfile' => $path,
+                            'dfile' => $des_path
+                        );
+                    }
+                }
+                
+                // 更新数据库
+                if (isset($sqls)) {
+                    $db = new DatabaseController();
+                    switch (get_db_type()) {
+                        case 'sqlite':
+                            copy(DOC_PATH . $this->config('database.dbname'), DOC_PATH . STATIC_DIR . '/backup/sql/' . date('YmdHis') . '_' . basename($this->config('database.dbname')));
+                            break;
+                        case 'mysql':
+                            $db->backupDB();
+                            break;
+                    }
+                    sort($sqls); // 排序
+                    foreach ($sqls as $value) {
+                        $path = RUN_PATH . '/upgrade' . $value;
+                        if (file_exists($path)) {
+                            $sql = file_get_contents($path);
+                            if (! $this->upsql($sql)) {
+                                $this->log("数据库 $value 更新失败!");
+                                json(0, "数据库" . basename($value) . " 更新失败!");
+                            }
+                        } else {
+                            json(0, "数据库文件" . basename($value) . "不存在!");
+                        }
+                    }
+                }
+                
+                // 替换文件
+                if (isset($files)) {
+                    foreach ($files as $value) {
+                        if (! copy($value['sfile'], $value['dfile'])) {
+                            $this->log("文件 " . $value['dfile'] . " 更新失败!");
+                            json(0, "文件 " . basename($value['dfile']) . " 更新失败,请重试!");
+                        }
+                    }
+                }
+                
+                // 清理缓存
+                path_delete(RUN_PATH . '/upgrade', true);
+                path_delete(RUN_PATH . '/cache');
+                path_delete(RUN_PATH . '/complite');
+                path_delete(RUN_PATH . '/config');
+                
+                $this->log("系统更新成功!");
+                json(1, '系统更新成功!');
+            } else {
+                json(0, '请选择要更新的文件!');
+            }
+        }
+    }
+
+    // 缓存文件
+    private function local()
+    {
+        $files = $this->getLoaclList(RUN_PATH . '/upgrade');
+        $files = json_decode(json_encode($files));
+        foreach ($files as $key => $value) {
+            $file = ROOT_PATH . $value->path;
+            if (file_exists($file)) {
+                $files[$key]->type = '<span style="color:Red">覆盖</span>';
+                $files[$key]->ltime = date('Y-m-d H:i:s', filemtime($file));
+            } else {
+                $files[$key]->type = '新增';
+                $files[$key]->ltime = '无';
+            }
+            $files[$key]->ctime = date('Y-m-d H:i:s', $files[$key]->ctime);
+            $upfile[] = $files[$key];
+        }
+        return $upfile;
+    }
+
+    // 执行更新数据库
+    private function upsql($sql)
+    {
+        $sql = explode(';', $sql);
+        $model = new Model();
+        foreach ($sql as $value) {
+            $value = trim($value);
+            if ($value) {
+                $model->amd($value);
+            }
+        }
+        return true;
+    }
+
+    // 获取列表
+    private function getServerList()
+    {
+        $param = array(
+            'version' => APP_VERSION . '.' . RELEASE_TIME . '.' . $this->revise,
+            'branch' => $this->branch,
+            'force' => $this->force,
+            'site' => get_http_url(),
+            'snuser' => $this->config('sn_user')
+        );
+        $url = $this->server . '/index.php?p=/upgrade/getlist&' . http_build_query($param);
+        if (! ! $rs = json_decode(get_url($url, '', '', true))) {
+            if ($rs->code) {
+                if (is_array($rs->data)) {
+                    return $rs->data;
+                } else {
+                    json(1, $rs->data);
+                }
+            } else {
+                json(0, $rs->data);
+            }
+        } else {
+            $this->log('连接更新服务器发生错误,请稍后再试!');
+            json(0, '连接更新服务器发生错误,请稍后再试!');
+        }
+    }
+
+    // 获取文件
+    private function getServerFile($source, $des)
+    {
+        $url = $this->server . '/index.php?p=/upgrade/getFile&branch=' . $this->branch;
+        $data['path'] = $source;
+        $file = basename($source);
+        if (! ! $rs = json_decode(get_url($url, $data, '', true))) {
+            if ($rs->code) {
+                if (! file_put_contents($des, base64_decode($rs->data))) {
+                    $this->log("更新文件  " . $file . " 下载失败!");
+                    json(0, "更新文件 " . $file . " 下载失败!");
+                } else {
+                    return true;
+                }
+            } else {
+                json(0, $rs->data);
+            }
+        } else {
+            $this->log("更新文件 " . $file . " 获取失败!");
+            json(0, "更新文件 " . $file . " 获取失败!");
+        }
+    }
+
+    // 获取非文本文件
+    private function getServerDown($source, $des)
+    {
+        $url = $this->server . $source;
+        $file = basename($source);
+        if (($sfile = fopen($url, "rb")) && ($dfile = fopen($des, "wb"))) {
+            while (! feof($sfile)) {
+                $fwrite = fwrite($dfile, fread($sfile, 1024 * 8), 1024 * 8);
+                if ($fwrite === false) {
+                    $this->log("更新文件 " . $file . " 下载失败!");
+                    json(0, "更新文件 " . $file . " 下载失败!");
+                }
+            }
+            if ($sfile) {
+                fclose($sfile);
+            }
+            if ($dfile) {
+                fclose($dfile);
+            }
+            return true;
+        } else {
+            $this->log("更新文件 " . $file . " 获取失败!");
+            json(0, "更新文件 " . $file . " 获取失败!");
+        }
+    }
+
+    // 获取文件列表
+    private function getLoaclList($path)
+    {
+        $files = scandir($path);
+        foreach ($files as $value) {
+            if ($value != '.' && $value != '..') {
+                if (is_dir($path . '/' . $value)) {
+                    $this->getLoaclList($path . '/' . $value);
+                } else {
+                    $file = $path . '/' . $value;
+                    
+                    // 避免中文乱码
+                    if (! mb_check_encoding($file, 'utf-8')) {
+                        $out_path = mb_convert_encoding($file, 'UTF-8', 'GBK');
+                    } else {
+                        $out_path = $file;
+                    }
+                    
+                    $out_path = str_replace(RUN_PATH . '/upgrade', '', $out_path);
+                    
+                    $this->files[] = array(
+                        'path' => $out_path,
+                        'md5' => md5_file($file),
+                        'ctime' => filemtime($file)
+                    );
+                }
+            }
+        }
+        return $this->files;
+    }
+
+    // 比较程序本号
+    private function compareVersion($sv, $cv)
+    {
+        if (empty($sv) || $sv == $cv) {
+            return 0;
+        }
+        $sv = explode('.', $sv);
+        $cv = explode('.', $cv);
+        $len = count($sv) > count($cv) ? count($sv) : count($cv);
+        for ($i = 0; $i < $len; $i ++) {
+            $n1 = $sv[$i] or 0;
+            $n2 = $cv[$i] or 0;
+            if ($n1 > $n2) {
+                return 1;
+            } elseif ($n1 < $n2) {
+                return 0;
+            }
+        }
+        return 0;
+    }
+}

+ 227 - 0
apps/admin/controller/system/UserController.php

@@ -0,0 +1,227 @@
+<?php
+/**
+ * @copyright (C)2016-2099 Hnaoyun Inc.
+ * @author XingMeng
+ * @email hnxsh@foxmail.com
+ * @date 2017年4月3日
+ *  用户控制器
+ */
+namespace app\admin\controller\system;
+
+use core\basic\Controller;
+use app\admin\model\system\UserModel;
+
+class UserController extends Controller
+{
+
+    private $model;
+
+    public function __construct()
+    {
+        $this->model = new UserModel();
+    }
+
+    // 用户列表
+    public function index()
+    {
+        $this->assign('list', true);
+        if ((! ! $field = get('field', 'var')) && (! ! $keyword = get('keyword', 'vars'))) {
+            $result = $this->model->findUser($field, $keyword);
+        } else {
+            $result = $this->model->getList();
+        }
+        $this->assign('users', $result);
+        // 角色列表
+        $role_model = model('admin.system.Role');
+        $this->assign('roles', $role_model->getSelect());
+        
+        $this->display('system/user.html');
+    }
+
+    // 用户新增
+    public function add()
+    {
+        if ($_POST) {
+            // 获取数据
+            $ucode = get_auto_code($this->model->getLastCode());
+            $username = post('username');
+            $realname = post('realname');
+            $password = post('password');
+            $rpassword = post('rpassword');
+            $status = post('status', 'int');
+            $roles = post('roles', 'array', true, '用户角色', array()); // 用户角色
+            
+            if (! $ucode) {
+                alert_back('编码不能为空!');
+            }
+            if (! $username) {
+                alert_back('用户名不能为空!');
+            }
+            if (! $realname) {
+                alert_back('真实名字不能为空!');
+            }
+            if (! $password) {
+                alert_back('密码不能为空!');
+            }
+            if (! $rpassword) {
+                alert_back('确认密码不能为空!');
+            }
+            if ($password != $rpassword) {
+                alert_back('确认密码不正确!');
+            }
+            
+            if (! preg_match('/^[\x{4e00}-\x{9fa5}\w\-\.@]+$/u', $username)) {
+                alert_back('用户名含有不允许的特殊字符!');
+            }
+            
+            // 检查编码重复
+            if ($this->model->checkUser("ucode='$ucode'")) {
+                alert_back('该用户编号已经存在,不能再使用!');
+            }
+            
+            // 检查用户名重复
+            if ($this->model->checkUser("username='$username'")) {
+                alert_back('该用户名已经存在,不能再使用!');
+            }
+            
+            // 构建数据
+            $data = array(
+                'ucode' => $ucode,
+                'username' => $username,
+                'realname' => $realname,
+                'password' => encrypt_string($password),
+                'status' => $status,
+                'login_count' => 0,
+                'last_login_ip' => 0,
+                'create_user' => session('username'),
+                'update_user' => session('username'),
+                'create_time' => get_datetime(),
+                'update_time' => '0000-00-00 00:00:00'
+            );
+            
+            // 执行添加
+            if ($this->model->addUser($data, $roles)) {
+                $this->log('新增用户' . $ucode . '成功!');
+                if (! ! $backurl = get('backurl')) {
+                    success('新增成功!', base64_decode($backurl));
+                } else {
+                    success('新增成功!', url('/admin/User/index'));
+                }
+            } else {
+                $this->log('新增用户' . $ucode . '失败!');
+                error('新增失败', - 1);
+            }
+        }
+    }
+
+    // 用户删除
+    public function del()
+    {
+        if (! $ucode = get('ucode', 'var')) {
+            error('传递的参数值错误!', - 1);
+        }
+        
+        if ($ucode == '10001') {
+            error('内置管理员不允许删除!', - 1);
+        }
+        
+        if ($this->model->delUser($ucode)) {
+            $this->log('删除用户' . $ucode . '成功!');
+            success('删除成功!', - 1);
+        } else {
+            $this->log('删除用户' . $ucode . '失败!');
+            error('删除失败', - 1);
+        }
+    }
+
+    // 用户修改
+    public function mod()
+    {
+        if (! $ucode = get('ucode', 'var')) {
+            error('传递的参数值错误!', - 1);
+        }
+        
+        if ($ucode == '10001') {
+            error('内置管理员不允许此操作!', - 1);
+        }
+        
+        // 单独修改状态
+        if (($field = get('field', 'var')) && ! is_null($value = get('value', 'var'))) {
+            if ($this->model->modUser($ucode, "$field='$value',update_user='" . session('username') . "'")) {
+                location(- 1);
+            } else {
+                alert_back('修改失败!');
+            }
+        }
+        
+        // 修改操作
+        if ($_POST) {
+            // 获取数据
+            $username = post('username');
+            $realname = post('realname');
+            $password = post('password');
+            $rpassword = post('rpassword');
+            $status = post('status', 'int');
+            $roles = post('roles', 'array', true, '用户角色', array()); // 用户角色
+            
+            if (! $username) {
+                alert_back('用户名不能为空!');
+            }
+            if (! $realname) {
+                alert_back('真实名字不能为空!');
+            }
+            
+            if (! preg_match('/^[\x{4e00}-\x{9fa5}\w\-\.@]+$/u', $username)) {
+                alert_back('用户名含有不允许的特殊字符!');
+            }
+            
+            // 检查用户名重复
+            if ($this->model->checkUser("username='$username' AND ucode<>'$ucode'")) {
+                alert_back('该用户名已经存在,不能再使用!');
+            }
+            
+            // 构建数据
+            $data = array(
+                'username' => $username,
+                'realname' => $realname,
+                'status' => $status,
+                'update_user' => session('username')
+            );
+            
+            if ($password) {
+                if (! $rpassword) {
+                    alert_back('确认密码不能为空!');
+                }
+                if ($password != $rpassword) {
+                    alert_back('确认密码不正确!');
+                }
+                $data['password'] = encrypt_string($password);
+            }
+            
+            // 执行添加
+            if ($this->model->modUser($ucode, $data, $roles)) {
+                $this->log('修改用户' . $ucode . '成功!');
+                if (! ! $backurl = get('backurl')) {
+                    success('修改成功!', base64_decode($backurl));
+                } else {
+                    success('修改成功!', url('/admin/User/index'));
+                }
+            } else {
+                location(- 1);
+            }
+        } else { // 调取修改内容
+            $this->assign('mod', true);
+            
+            $result = $this->model->getUser($ucode);
+            if (! $result) {
+                error('编辑的内容已经不存在!', - 1);
+            }
+            $this->assign('user', $result);
+            
+            // 角色列表
+            $role_model = model('admin.system.Role');
+            $this->assign('roles', $role_model->getSelect());
+            $this->display('system/user.html');
+        }
+    }
+}

+ 225 - 0
apps/admin/model/IndexModel.php

@@ -0,0 +1,225 @@
+<?php
+/**
+ * @copyright (C)2016-2099 Hnaoyun Inc.
+ * @author XingMeng
+ * @email hnxsh@foxmail.com
+ * @date 2017年3月13日
+ *  首页模型类
+ */
+namespace app\admin\model;
+
+use core\basic\Model;
+
+class IndexModel extends Model
+{
+
+    // 检查用户账号密码
+    public function login($where)
+    {
+        // 执行登录
+        $result = parent::table('ay_user')->field('id,ucode,username,realname')
+            ->where($where)
+            ->where('status=1')
+            ->find();
+        
+        if ($result) { // 登录成功
+            $this->updateLogin($where); // 执行更新登录记录
+            $menus = $this->getUserMenu($result->ucode); // 用户菜单
+            $result->menus = get_tree($menus, 0, 'mcode', 'pcode'); // 用户菜单树
+            $result->rcodes = $this->getUserRcode($result->ucode); // 用户角色
+            $result->levels = $this->getUserLevel($result->ucode); // 用户权限
+            
+            $acodes = $this->getUserAcode($result->ucode); // 获取用户区域
+            $areas = $this->getAreas();
+            $first_acode = $areas[0]->acode;
+            if (in_array($first_acode, $acodes)) {
+                array_unshift($acodes, $first_acode);
+                $acodes = array_unique($acodes);
+            }
+            $result->acodes = $acodes;
+            $result->area_map = get_mapping($areas, 'name', 'acode'); // 区域代码名称映射表
+            $result->area_tree = $this->getUserAreaTree($areas, 0, 'acode', 'pcode', 'son', $result->acodes); // 当前用户的区域树
+            return $result;
+        } else {
+            return false;
+        }
+    }
+
+    // 用户登录成功后更新登录信息
+    private function updateLogin($where)
+    {
+        $data = array(
+            'last_login_ip' => ip2long(get_user_ip()),
+            'login_count' => '+=1'
+        );
+        return parent::table('ay_user')->where($where)
+            ->autoTime()
+            ->update($data);
+    }
+
+    // 获取用户菜单列表
+    public function getUserMenu($ucode)
+    {
+        if ($ucode == '10001') { // 管理员获所有区域
+            $field = array(
+                'id',
+                'mcode',
+                'pcode',
+                'name',
+                'url',
+                'shortcut',
+                'ico',
+                'sorting',
+                'status'
+            );
+            $order = array(
+                'sorting',
+                'pcode',
+                'id'
+            );
+            $result = parent::table('ay_menu')->distinct()
+                ->field($field)
+                ->order($order)
+                ->select();
+        } else {
+            $table = array(
+                'ay_user',
+                'ay_user_role',
+                'ay_role',
+                'ay_role_level',
+                'ay_menu'
+            );
+            $field = array(
+                'ay_menu.id',
+                'ay_menu.mcode',
+                'ay_menu.pcode',
+                'ay_menu.name',
+                'ay_menu.url',
+                'ay_menu.shortcut',
+                'ay_menu.ico',
+                'ay_menu.sorting',
+                'ay_menu.status'
+            );
+            $where = array(
+                "ay_user.ucode='$ucode'",
+                "ay_user.ucode=ay_user_role.ucode",
+                "ay_role.rcode=ay_user_role.rcode",
+                "ay_role.rcode=ay_role_level.rcode",
+                "ay_menu.url=ay_role_level.level"
+            );
+            $order = array(
+                'ay_menu.sorting',
+                'ay_menu.pcode',
+                'ay_menu.id'
+            );
+            $result = parent::table($table)->distinct()
+                ->field($field)
+                ->where($where)
+                ->order($order)
+                ->select();
+        }
+        return $result;
+    }
+
+    // 获取用户的角色代码
+    public function getUserRcode($ucode)
+    {
+        return parent::table('ay_user_role')->where("ucode='$ucode'")->column('rcode');
+    }
+
+    // 获取用户权限列表
+    public function getUserLevel($ucode)
+    {
+        $table = array(
+            'ay_user',
+            'ay_user_role',
+            'ay_role',
+            'ay_role_level'
+        );
+        $where = array(
+            "ay_user.ucode='$ucode'",
+            "ay_user.ucode=ay_user_role.ucode",
+            "ay_role.rcode=ay_user_role.rcode",
+            "ay_role.rcode=ay_role_level.rcode"
+        );
+        return parent::table($table)->distinct()
+            ->where($where)
+            ->column('ay_role_level.level');
+    }
+
+    // 获取用户可管理的区域代码
+    public function getUserAcode($ucode)
+    {
+        if ($ucode == '10001') { // 管理员获所有区域
+            $result = parent::table('ay_area')->distinct()->column('acode');
+        } else {
+            $table = array(
+                'ay_user',
+                'ay_user_role',
+                'ay_role',
+                'ay_role_area',
+                'ay_area'
+            );
+            $where = array(
+                "ay_user.ucode = '$ucode'",
+                "ay_user.ucode=ay_user_role.ucode",
+                "ay_role.rcode=ay_user_role.rcode",
+                "ay_role.rcode=ay_role_area.rcode",
+                "ay_area.acode=ay_role_area.acode"
+            );
+            $result = parent::table($table)->distinct()
+                ->where($where)
+                ->column('ay_area.acode');
+        }
+        return $result;
+    }
+
+    // 获取区域列表
+    public function getAreas()
+    {
+        $result = parent::table('ay_area')->field('pcode,acode,name,is_default')
+            ->order('is_default DESC,pcode,acode')
+            ->select();
+        return $result;
+    }
+
+    // 生成授权的区域树
+    public function getUserAreaTree($data, $tid, $idField, $pidField, $sonName = 'son', $valid = array())
+    {
+        $tree = array();
+        foreach ($data as $key => $value) {
+            if ($value->$pidField == "$tid") { // 父亲找到儿子
+                $value->$sonName = $this->getUserAreaTree($data, $value->$idField, $idField, $pidField, $sonName, $valid);
+                if ($value->$sonName) {
+                    $tree[] = $value;
+                } elseif (in_array($value->$idField, $valid)) {
+                    $tree[] = $value;
+                }
+            }
+        }
+        return $tree;
+    }
+
+    // 检查当前用户密码
+    public function checkUserPwd($password)
+    {
+        return parent::table('ay_user')->field('id')
+            ->where("id=" . session('id') . " AND password='$password'")
+            ->find();
+    }
+
+    // 修改当前用户信息
+    public function modUserInfo($data)
+    {
+        return parent::table('ay_user')->where("id=" . session('id'))->update($data);
+    }
+
+    // 获取用户信息
+    public function getUserInfo($ucode)
+    {
+        $result = parent::table('ay_user')->field('id,ucode,username,realname,last_login_ip,update_time,login_count')
+            ->where("ucode='$ucode'")
+            ->find();
+        return $result;
+    }
+}

+ 44 - 0
apps/admin/model/content/CompanyModel.php

@@ -0,0 +1,44 @@
+<?php
+/**
+ * @copyright (C)2016-2099 Hnaoyun Inc.
+ * @author XingMeng
+ * @email hnxsh@foxmail.com
+ * @date 2017年3月24日
+ *  公司信息模型类
+ */
+namespace app\admin\model\content;
+
+use core\basic\Model;
+
+class CompanyModel extends Model
+{
+
+    // 获取公司信息
+    public function getList()
+    {
+        return parent::table('ay_company')->where("acode='" . session('acode') . "'")->find();
+    }
+
+    // 检查公司信息
+    public function checkCompany()
+    {
+        return parent::table('ay_company')->where("acode='" . session('acode') . "'")->find();
+    }
+
+    // 增加公司信息
+    public function addCompany($data)
+    {
+        return parent::table('ay_company')->insert($data);
+    }
+
+    // 修改公司信息
+    public function modCompany($data)
+    {
+        return parent::table('ay_company')->where("acode='" . session('acode') . "'")->update($data);
+    }
+
+    public function getImage()
+    {
+        return parent::table('ay_company')->column('weixin');
+    }
+}

+ 346 - 0
apps/admin/model/content/ContentModel.php

@@ -0,0 +1,346 @@
+<?php
+/**
+ * @copyright (C)2016-2099 Hnaoyun Inc.
+ * @author XingMeng
+ * @email hnxsh@foxmail.com
+ * @date 2017年12月15日
+ *  列表文章模型类
+ */
+namespace app\admin\model\content;
+
+use core\basic\Db;
+use core\basic\Model;
+
+class ContentModel extends Model
+{
+
+    protected $scodes = array();
+
+    // 获取文章列表
+    public function getList($mcode, $where = array())
+    {
+        $field = array(
+            'a.id',
+            'b.name as sortname',
+            'a.scode',
+            'c.name as subsortname',
+            'a.subscode',
+            'a.title',
+            'a.subtitle',
+            'a.date',
+            'a.sorting',
+            'a.status',
+            'a.istop',
+            'a.isrecommend',
+            'a.isheadline',
+            'a.visits',
+            'a.ico',
+            'a.pics',
+            'a.filename',
+            'a.outlink',
+            'd.urlname',
+            'b.filename as sortfilename'
+        );
+        $join = array(
+            array(
+                'ay_content_sort b',
+                'a.scode=b.scode',
+                'LEFT'
+            ),
+            array(
+                'ay_content_sort c',
+                'a.subscode=c.scode',
+                'LEFT'
+            ),
+            array(
+                'ay_model d',
+                'b.mcode=d.mcode',
+                'LEFT'
+            )
+        );
+        return parent::table('ay_content a')->field($field)
+            ->where("b.mcode='$mcode'")
+            ->where('d.type=2 OR d.type is null ')
+            ->where("a.acode='" . session('acode') . "'")
+            ->where($where)
+            ->join($join)
+            ->order('a.sorting ASC,a.id DESC')
+            ->page()
+            ->select();
+    }
+
+    // 查找指定分类及子类文章
+    public function findContent($mcode, $scode, $keyword)
+    {
+        $fields = array(
+            'a.id',
+            'b.name as sortname',
+            'a.scode',
+            'c.name as subsortname',
+            'a.subscode',
+            'a.title',
+            'a.subtitle',
+            'a.date',
+            'a.sorting',
+            'a.status',
+            'a.istop',
+            'a.isrecommend',
+            'a.isheadline',
+            'a.visits',
+            'a.ico',
+            'a.pics',
+            'a.filename',
+            'a.outlink',
+            'd.urlname',
+            'b.filename as sortfilename'
+        );
+        $join = array(
+            array(
+                'ay_content_sort b',
+                'a.scode=b.scode',
+                'LEFT'
+            ),
+            array(
+                'ay_content_sort c',
+                'a.subscode=c.scode',
+                'LEFT'
+            ),
+            array(
+                'ay_model d',
+                'b.mcode=d.mcode',
+                'LEFT'
+            )
+        );
+        $this->scodes = array(); // 先清空
+        $scodes = $this->getSubScodes($scode);
+        return parent::table('ay_content a')->field($fields)
+            ->where("b.mcode='$mcode'")
+            ->where('d.type=2 OR d.type is null ')
+            ->where("a.acode='" . session('acode') . "'")
+            ->in('a.scode', $scodes)
+            ->like('a.title', $keyword)
+            ->join($join)
+            ->order('a.sorting ASC,a.id DESC')
+            ->page()
+            ->select();
+    }
+
+    // 在全部栏目查找文章
+    public function findContentAll($mcode, $keyword)
+    {
+        $fields = array(
+            'a.id',
+            'b.name as sortname',
+            'a.scode',
+            'c.name as subsortname',
+            'a.subscode',
+            'a.title',
+            'a.subtitle',
+            'a.date',
+            'a.sorting',
+            'a.status',
+            'a.istop',
+            'a.isrecommend',
+            'a.isheadline',
+            'a.visits',
+            'a.ico',
+            'a.pics',
+            'a.filename',
+            'a.outlink',
+            'd.urlname',
+            'b.filename as sortfilename'
+        );
+        $join = array(
+            array(
+                'ay_content_sort b',
+                'a.scode=b.scode',
+                'LEFT'
+            ),
+            array(
+                'ay_content_sort c',
+                'a.subscode=c.scode',
+                'LEFT'
+            ),
+            array(
+                'ay_model d',
+                'b.mcode=d.mcode',
+                'LEFT'
+            )
+        );
+        return parent::table('ay_content a')->field($fields)
+            ->where("b.mcode='$mcode'")
+            ->where('d.type=2 OR d.type is null ')
+            ->where("a.acode='" . session('acode') . "'")
+            ->like('a.title', $keyword)
+            ->join($join)
+            ->order('a.sorting ASC,a.id DESC')
+            ->page()
+            ->select();
+    }
+
+    // 获取子栏目
+    public function getSubScodes($scode)
+    {
+        if (! $scode) {
+            return;
+        }
+        $this->scodes[] = $scode;
+        $subs = parent::table('ay_content_sort')->where("pcode='$scode'")->column('scode');
+        if ($subs) {
+            foreach ($subs as $value) {
+                $this->getSubScodes($value);
+            }
+        }
+        return $this->scodes;
+    }
+
+    // 检查文章
+    public function checkContent($where)
+    {
+        return parent::table('ay_content')->field('id')
+            ->where($where)
+            ->find();
+    }
+
+    // 获取文章详情
+    public function getContent($id)
+    {
+        $field = array(
+            'a.*',
+            'b.name as sortname',
+            'c.name as subsortname',
+            'd.*'
+        );
+        $join = array(
+            array(
+                'ay_content_sort b',
+                'a.scode=b.scode',
+                'LEFT'
+            ),
+            array(
+                'ay_content_sort c',
+                'a.subscode=c.scode',
+                'LEFT'
+            ),
+            array(
+                'ay_content_ext d',
+                'a.id=d.contentid',
+                'LEFT'
+            )
+        );
+        return parent::table('ay_content a')->field($field)
+            ->where("a.id=$id")
+            ->where("a.acode='" . session('acode') . "'")
+            ->join($join)
+            ->find();
+    }
+
+    // 添加文章
+    public function addContent(array $data)
+    {
+        return parent::table('ay_content')->autoTime()->insertGetId($data);
+    }
+
+    // 删除文章
+    public function delContent($id)
+    {
+        return parent::table('ay_content')->where("id=$id")
+            ->where("acode='" . session('acode') . "'")
+            ->delete();
+    }
+
+    // 删除文章
+    public function delContentList($ids)
+    {
+        return parent::table('ay_content')->where("acode='" . session('acode') . "'")->delete($ids);
+    }
+
+    // 修改文章
+    public function modContent($id, $data)
+    {
+        return parent::table('ay_content')->autoTime()
+            ->in('id', $id)
+            ->where("acode='" . session('acode') . "'")
+            ->update($data);
+    }
+
+    // 复制内容到指定栏目
+    public function copyContent($ids, $scode)
+    {
+        // 查找出要复制的主内容
+        $data = parent::table('ay_content')->in('id', $ids)->select(1);
+        
+        foreach ($data as $key => $value) {
+            // 查找扩展内容
+            $extdata = parent::table('ay_content_ext')->where('contentid=' . $value['id'])->find(1);
+            
+            // 去除主键并修改栏目
+            unset($value['id']);
+            $value['scode'] = $scode;
+            
+            // 插入主内容
+            $id = parent::table('ay_content')->insertGetId($value);
+            
+            // 插入扩展内容
+            if ($id && $extdata) {
+                unset($extdata['extid']);
+                $extdata['contentid'] = $id;
+                $result = parent::table('ay_content_ext')->insert($extdata);
+            } else {
+                $result = $id;
+            }
+        }
+        return $result;
+    }
+
+    // 查找文章扩展内容
+    public function findContentExt($id)
+    {
+        return parent::table('ay_content_ext')->where("contentid=$id")->find();
+    }
+
+    // 添加文章扩展内容
+    public function addContentExt(array $data)
+    {
+        return parent::table('ay_content_ext')->insert($data);
+    }
+
+    // 修改文章扩展内容
+    public function modContentExt($id, $data)
+    {
+        return parent::table('ay_content_ext')->where("contentid=$id")->update($data);
+    }
+
+    // 删除文章扩展内容
+    public function delContentExt($id)
+    {
+        return parent::table('ay_content_ext')->where("contentid=$id")->delete();
+    }
+
+    // 删除文章扩展内容
+    public function delContentExtList($ids)
+    {
+        return parent::table('ay_content_ext')->delete($ids, 'contentid');
+    }
+
+    // 检查自定义URL名称
+    public function checkFilename($filename, $where = array())
+    {
+        return parent::table('ay_content')->field('id')
+            ->where("filename='$filename'")
+            ->where($where)
+            ->find();
+    }
+
+    public function getImage()
+    {
+        $list = parent::table('ay_content')->limit(2000)->column('ico,pics,content');
+        foreach ($list as &$value){
+            preg_match_all('/<img\s+.*?src=\s?[\'|\"](.*?(\.gif|\.jpg|\.png|\.jpeg))[\'|\"].*?[\/]?>/i', decode_string($value['content']), $match);
+            $value['content_img'] = $match[1];
+            $value['pics'] = explode(',',$value['pics']);
+            unset($value['content']);
+        }
+        return $list;
+    }
+}

+ 267 - 0
apps/admin/model/content/ContentSortModel.php

@@ -0,0 +1,267 @@
+<?php
+/**
+ * @copyright (C)2016-2099 Hnaoyun Inc.
+ * @author XingMeng
+ * @email hnxsh@foxmail.com
+ * @date 2017年12月26日
+ *  内容栏目模型类
+ */
+namespace app\admin\model\content;
+
+use core\basic\Model;
+
+class ContentSortModel extends Model
+{
+
+    // 存储分类及子编码
+    protected $scodes = array();
+
+    // 获取内容栏目列表
+    public function getList()
+    {
+        $field = array(
+            'a.*',
+            'b.type',
+            'b.urlname',
+            '(select count(*) from ay_content c where c.scode=a.scode) wzcount'
+        );
+        $join = array(
+            'ay_model b',
+            'a.mcode=b.mcode',
+            'LEFT'
+        );
+        $result = parent::table('ay_content_sort a')->field($field)
+            ->where("a.acode='" . session('acode') . "'")
+            ->join($join)
+            ->order('a.pcode,a.sorting,a.id')
+            ->select();
+        $tree = get_tree($result, 0, 'scode', 'pcode');
+        return $tree;
+    }
+
+    // 获取内容栏目选择列表
+    public function getSelect()
+    {
+        $result = parent::table('ay_content_sort')->field('pcode,scode,name')
+            ->where("acode='" . session('acode') . "'")
+            ->order('pcode,sorting,id')
+            ->select();
+        $tree = get_tree($result, 0, 'scode', 'pcode');
+        return $tree;
+    }
+
+    // 获取单页内容栏目选择列表
+    public function getSingleSelect()
+    {
+        $field = array(
+            'a.pcode',
+            'a.scode',
+            'a.name',
+            'a.outlink'
+        );
+        $join = array(
+            'ay_model b',
+            'a.mcode=b.mcode',
+            'LEFT'
+        );
+        $result = parent::table('ay_content_sort a')->field($field)
+            ->where('b.type=1')
+            ->where("a.outlink=''")
+            ->where("a.acode='" . session('acode') . "'")
+            ->notIn('a.scode', 'select scode from ay_content')
+            ->join($join)
+            ->order('a.pcode,a.sorting,a.id')
+            ->select();
+        return $result;
+    }
+
+    // 获取列表内容栏目选择列表
+    public function getListSelect($mcode)
+    {
+        $field = array(
+            'a.pcode',
+            'a.scode',
+            'a.name',
+            'a.outlink'
+        );
+        $join = array(
+            'ay_model b',
+            'a.mcode=b.mcode',
+            'LEFT'
+        );
+        $result = parent::table('ay_content_sort a')->field($field)
+            ->where('b.type=2')
+            ->where("a.outlink=''")
+            ->where("a.mcode='$mcode'")
+            ->where("a.acode='" . session('acode') . "'")
+            ->join($join)
+            ->order('a.pcode,a.sorting,a.id')
+            ->select();
+        $tree = get_tree($result, 0, 'scode', 'pcode');
+        // 对于父栏目非列表的栏目进行追加到后面
+        foreach ($result as $value) {
+            if ($value->pcode != 0 && result_value_search($value->pcode, $result, 'scode') === false) {
+                $value->son = get_tree($result, $value->scode, 'scode', 'pcode');
+                $tree[] = $value;
+            }
+        }
+        return $tree;
+    }
+
+    // 检查内容栏目
+    public function checkSort($where)
+    {
+        return parent::table('ay_content_sort')->field('id')
+            ->where($where)
+            ->find();
+    }
+
+    // 获取内容栏目详情
+    public function getSort($scode)
+    {
+        $field = array(
+            'a.*',
+            'b.type'
+        );
+        $join = array(
+            'ay_model b',
+            'a.mcode=b.mcode',
+            'LEFT'
+        );
+        return parent::table('ay_content_sort a')->field($field)
+            ->where("a.scode='$scode'")
+            ->where("a.acode='" . session('acode') . "'")
+            ->join($join)
+            ->find();
+    }
+
+    // 获取最后一个code
+    public function getLastCode()
+    {
+        return parent::table('ay_content_sort')->order('id DESC')->value('scode');
+    }
+
+    // 添加内容栏目
+    public function addSort(array $data)
+    {
+        return parent::table('ay_content_sort')->autoTime()->insert($data);
+    }
+
+    // 删除内容栏目及内容
+    public function delSort($scode)
+    {
+        $this->scodes = array(); // 先清空
+        $scodes = $this->getSubScodes($scode); // 获取全部子类
+        $this->delContent($scodes);
+        return parent::table('ay_content_sort')->in('scode', $scodes)
+            ->where("acode='" . session('acode') . "'")
+            ->delete();
+    }
+
+    // 批量删除栏目及内容
+    public function delSortList($scodes)
+    {
+        $this->scodes = array(); // 先清空
+        foreach ($scodes as $value) {
+            $allscode = $this->getSubScodes($value); // 获取全部子类
+        }
+        $this->delContent($allscode);
+        return parent::table('ay_content_sort')->in('scode', $allscode)
+            ->where("acode='" . session('acode') . "'")
+            ->delete();
+    }
+
+    // 修改内容栏目资料
+    public function modSort($scode, $data, $modsub = false)
+    {
+        if ($modsub) {
+            // 同步修改子栏目模型及模板
+            $scodes = $this->getSubScodes($scode);
+            $subdata = array(
+                'mcode' => $data['mcode'],
+                'listtpl' => $data['listtpl'],
+                'contenttpl' => $data['contenttpl']
+            );
+            parent::table('ay_content_sort')->in('scode', $scodes)
+                ->where("acode='" . session('acode') . "'")
+                ->update($subdata);
+        }
+        $result = parent::table('ay_content_sort')->autoTime()
+            ->where("scode='$scode'")
+            ->where("acode='" . session('acode') . "'")
+            ->update($data);
+        return $result;
+    }
+
+    // 修改内容栏目排序
+    public function modSortSorting($id, $data)
+    {
+        $result = parent::table('ay_content_sort')->autoTime()
+            ->where("id='$id'")
+            ->where("acode='" . session('acode') . "'")
+            ->update($data);
+        return $result;
+    }
+
+    // 查找指定单页内容
+    public function findContent($scode)
+    {
+        return parent::table('ay_content')->where("scode='$scode'")->find();
+    }
+
+    // 添加单篇文章
+    public function addSingle(array $data)
+    {
+        return parent::table('ay_content')->autoTime()->insert($data);
+    }
+
+    // 删除指定栏目文章
+    public function delContent($scodes)
+    {
+        return parent::table('ay_content')->in('scode', $scodes)->delete();
+    }
+
+    // 分类子类集
+    private function getSubScodes($scode)
+    {
+        if (! $scode) {
+            return;
+        }
+        $this->scodes[] = $scode;
+        $subs = parent::table('ay_content_sort')->where("pcode='$scode'")->column('scode');
+        if ($subs) {
+            foreach ($subs as $value) {
+                $this->getSubScodes($value);
+            }
+        }
+        return $this->scodes;
+    }
+
+    // 检查自定义URL名称
+    public function checkFilename($filename, $where = array())
+    {
+        return parent::table('ay_content_sort')->field('id')
+            ->where("filename='$filename'")
+            ->where($where)
+            ->find();
+    }
+
+    // 检查URL名字冲突
+    public function checkUrlname($filename)
+    {
+        return parent::table('ay_model')->field('id')
+            ->where("urlname='$filename'")
+            ->find();
+    }
+
+    // 获取当前主题
+    public function getTheme()
+    {
+        return parent::table('ay_site')->where("acode='" . session('acode') . "'")->value('theme');
+    }
+
+    public function getImage()
+    {
+        return parent::table('ay_content_sort')->column('pic,ico');
+    }
+}

+ 93 - 0
apps/admin/model/content/ExtFieldModel.php

@@ -0,0 +1,93 @@
+<?php
+/**
+ * @copyright (C)2016-2099 Hnaoyun Inc.
+ * @author XingMeng
+ * @email hnxsh@foxmail.com
+ * @date 2018年4月7日
+ *  扩展字段模型类
+ */
+namespace app\admin\model\content;
+
+use core\basic\Model;
+
+class ExtFieldModel extends Model
+{
+
+    // 获取扩展字段列表
+    public function getList()
+    {
+        return parent::table('ay_extfield')->order('mcode asc,sorting asc,id asc')
+            ->page()
+            ->select();
+    }
+
+    // 查找扩展字段
+    public function findExtField($field, $keyword)
+    {
+        return parent::table('ay_extfield')->like($field, $keyword)
+            ->order('mcode asc,sorting asc,id asc')
+            ->page()
+            ->select();
+    }
+
+    // 检查扩展字段
+    public function checkExtField($name)
+    {
+        return parent::table('ay_extfield')->where("name='$name'")->find();
+    }
+
+    // 获取模型字段
+    public function getModelField($mcode)
+    {
+        return parent::table('ay_extfield')->where("mcode='$mcode'")
+            ->order('sorting asc,id asc')
+            ->select();
+    }
+
+    // 获取扩展字段详情
+    public function getExtField($id)
+    {
+        return parent::table('ay_extfield')->where("id=$id")->find();
+    }
+
+    // 获取扩展字段名称
+    public function getExtFieldName($id)
+    {
+        return parent::table('ay_extfield')->where("id=$id")->value('name');
+    }
+
+    // 添加扩展字段
+    public function addExtField(array $data)
+    {
+        return parent::table('ay_extfield')->insert($data);
+    }
+
+    // 删除扩展字段
+    public function delExtField($id)
+    {
+        return parent::table('ay_extfield')->where("id=$id")->delete();
+    }
+
+    // 修改扩展字段
+    public function modExtField($id, $data)
+    {
+        return parent::table('ay_extfield')->where("id=$id")->update($data);
+    }
+
+    // 判断字段是否存在
+    public function isExistField($field)
+    {
+        $fields = parent::tableFields('ay_content_ext');
+        if (in_array($field, $fields)) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    //查询content_ext的索引
+    public function checkExtIndex(): array
+    {
+        return parent::table('ay_content_ext')->checkIndexSql();
+    }
+}

+ 238 - 0
apps/admin/model/content/FormModel.php

@@ -0,0 +1,238 @@
+<?php
+/**
+ * @copyright (C)2016-2099 Hnaoyun Inc.
+ * @author XingMeng
+ * @email hnxsh@foxmail.com
+ * @date 2018年5月28日
+ *  自定义表单模型类
+ */
+namespace app\admin\model\content;
+
+use core\basic\Model;
+
+class FormModel extends Model
+{
+
+    // 获取自定义表单列表
+    public function getList()
+    {
+        return parent::table('ay_form')->page()->select();
+    }
+
+    // 查找自定义表单
+    public function findForm($field, $keyword)
+    {
+        return parent::table('ay_form')->like($field, $keyword)
+            ->page()
+            ->select();
+    }
+
+    // 获取最后一个code
+    public function getLastCode()
+    {
+        return parent::table('ay_form')->order('id DESC')->value('fcode');
+    }
+
+    // 获取自定义表单详情
+    public function getForm($id)
+    {
+        return parent::table('ay_form')->where("id=$id")->find();
+    }
+
+    // 获取自定义表单详情
+    public function getFormByCode($fcode)
+    {
+        return parent::table('ay_form')->where("fcode='$fcode'")->find();
+    }
+
+    // 获取自定义表单表
+    public function getFormTable($id)
+    {
+        return parent::table('ay_form')->where("id=$id")->value('table_name');
+    }
+
+    // 获取自定义表单表
+    public function getFormCode($id)
+    {
+        return parent::table('ay_form')->where("id=$id")->value('fcode');
+    }
+
+    // 获取自定义表单表
+    public function getFormTableByCode($fcode)
+    {
+        return parent::table('ay_form')->where("fcode='$fcode'")->value('table_name');
+    }
+
+    // 添加自定义表单
+    public function addForm(array $data)
+    {
+        return parent::table('ay_form')->autoTime()->insert($data);
+    }
+
+    // 删除自定义表单
+    public function delForm($id)
+    {
+        $form = parent::table('ay_form')->field('fcode,form_name')
+            ->where("id=$id")
+            ->find();
+        
+        // 删除可能存在的菜单
+        if (! ! $rs = parent::table('ay_menu')->like('url', '/Form/index/fcode/' . $form->fcode . '/action/showdata')->find()) {
+            parent::table('ay_menu')->where("mcode='" . $rs->mcode . "'")->delete();
+            $menu = session('menu_tree');
+            foreach ($menu as $key => $value) {
+                if (! ! $delkey = result_value_search($rs->mcode, $menu[$key]->son, 'mcode')) {
+                    unset($menu[$key]->son[$delkey]);
+                }
+            }
+        }
+        $result = parent::table('ay_form')->where("id=$id")->delete(); // 删除表单
+        return $result;
+    }
+
+    // 修改自定义表单
+    public function modForm($id, $data)
+    {
+        return parent::table('ay_form')->where("id=$id")
+            ->autoTime()
+            ->update($data);
+    }
+
+    // 获取表单字段
+    public function getFormFieldByCode($fcode)
+    {
+        return parent::table('ay_form_field')->where("fcode='$fcode'")
+            ->order('sorting ASC,id ASC')
+            ->select();
+    }
+
+    // 获取字段详情
+    public function getFormField($id)
+    {
+        return parent::table('ay_form_field')->where("id=$id")->find();
+    }
+
+    // 检查表单字段
+    public function checkFormField($fcode, $name)
+    {
+        return parent::table('ay_form_field')->where("fcode='$fcode' AND name='$name'")->find();
+    }
+
+    // 获取表单字段名称
+    public function getFormFieldName($id)
+    {
+        return parent::table('ay_form_field')->where("id=$id")->value('name');
+    }
+
+    // 新增表单字段
+    public function addFormField(array $data)
+    {
+        return parent::table('ay_form_field')->autoTime()->insert($data);
+    }
+
+    // 删除表单字段
+    public function delFormField($id)
+    {
+        return parent::table('ay_form_field')->where("id=$id")->delete();
+    }
+
+    // 删除表单字段
+    public function delFormFieldByCode($fcode)
+    {
+        return parent::table('ay_form_field')->where("fcode='$fcode'")->delete();
+    }
+
+    // 修改表单字段
+    public function modFormField($id, $data)
+    {
+        return parent::table('ay_form_field')->where("id=$id")
+            ->autoTime()
+            ->update($data);
+    }
+
+    // 判断字段是否存在
+    public function isExistField($table, $field)
+    {
+        $fields = parent::tableFields($table);
+        if (in_array($field, $fields)) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    // 获取表单数据
+    public function getFormData($table, $page = true)
+    {
+        return parent::table($table)->page($page)
+            ->order('id DESC')
+            ->select();
+    }
+
+    // 删除自定义表单数据
+    public function delFormData($table, $id)
+    {
+        return parent::table($table)->where("id=$id")->delete();
+    }
+
+    // 清空自定义表单数据
+    public function clearFormData($table)
+    {
+        return parent::table($table)->delete();
+    }
+
+    // 增加表单数据查看到菜单
+    public function addFormMenu($id)
+    {
+        $form = parent::table('ay_form')->field('fcode,form_name')
+            ->where("id=$id")
+            ->find();
+        
+        $menus = session('menu_tree');
+        
+        // 判断是否已经在菜单中
+        if (! ! $menu = parent::table('ay_menu')->like('url', '/Form/index/fcode/' . $form->fcode . '/action/showdata')->find()) {
+            if ($form->form_name != $menu->name) {
+                // 更新缓存菜单
+                parent::table('ay_menu')->where('mcode="' . $menu->mcode . '"')->update('name="' . $form->form_name . '"');
+                foreach ($menus as $key => $value) {
+                    if ($value->mcode == 'M157') {
+                        if (($skey = result_value_search($menu->mcode, $menus[$key]->son, 'mcode')) !== false) {
+                            $menus[$key]->son[$skey]->name = $form->form_name;
+                        }
+                        break;
+                    }
+                }
+            }
+            return false;
+        }
+        
+        // 构建数据
+        $lastmcode = parent::table('ay_menu')->order('mcode DESC')->value('mcode');
+        $mcode = get_auto_code($lastmcode);
+        $data = array(
+            'mcode' => $mcode,
+            'pcode' => 'M157',
+            'name' => $form->form_name,
+            'url' => '/Form/index/fcode/' . $form->fcode . '/action/showdata',
+            'sorting' => 599,
+            'status' => 1,
+            'shortcut' => 0,
+            'ico' => 'fa-plus-square-o',
+            'create_user' => session('username'),
+            'update_user' => session('username')
+        );
+        
+        // 加入菜单
+        foreach ($menus as $key => $value) {
+            if ($value->mcode == 'M157') {
+                // 未在缓存菜单中才执行添加
+                if (result_value_search($mcode, $menus[$key]->son, 'mcode') === false) {
+                    $menus[$key]->son[] = array_to_object($data);
+                    return parent::table('ay_menu')->autoTime()->insert($data); // 插入到数据库
+                }
+                break;
+            }
+        }
+    }
+}

+ 89 - 0
apps/admin/model/content/LabelModel.php

@@ -0,0 +1,89 @@
+<?php
+/**
+ * @copyright (C)2016-2099 Hnaoyun Inc.
+ * @author XingMeng
+ * @email hnxsh@foxmail.com
+ * @date 2018年03月23日
+ * 自定义标签模型类
+ */
+
+namespace app\admin\model\content;
+
+use core\basic\Model;
+
+class LabelModel extends Model
+{
+
+    // 获取自定义标签列表
+    public function getList()
+    {
+        return parent::table('ay_label')->select();
+    }
+
+    // 检查自定义标签
+    public function checkLabel($where)
+    {
+        return parent::table('ay_label')->field('id')
+            ->where($where)
+            ->find();
+    }
+
+    // 获取自定义标签详情
+    public function getLabel($id)
+    {
+        return parent::table('ay_label')->where("id=$id")->find();
+    }
+
+    // 添加自定义标签
+    public function addLabel(array $data)
+    {
+        return parent::table('ay_label')->autoTime()->insert($data);
+    }
+
+    // 删除自定义标签
+    public function delLabel($id)
+    {
+        return parent::table('ay_label')->where("id='$id'")->delete();
+    }
+
+    // 修改自定义标签
+    public function modLabel($id, $data)
+    {
+        return parent::table('ay_label')->where("id=$id")
+            ->autoTime()
+            ->update($data);
+    }
+
+    // 修改自定义标签值
+    public function modValue($name, $value)
+    {
+        return parent::table('ay_label')->where("name='$name'")
+            ->autoTime()
+            ->update("value='$value'");
+    }
+
+    // 获取配置参数
+    public function getValue()
+    {
+        return parent::table('ay_label')->column('value', 'name');
+    }
+
+    //获取标签图片
+    public function getImage()
+    {
+
+        $resArr = parent::table('ay_label')->column('value');
+        $setArr = [];
+        foreach ($resArr as $key => $content) {
+            $pattern = '/src=&quot;\/(.*?)&quot;/';
+            preg_match_all($pattern, $content, $matches);
+            if (!empty($matches[1])) {
+                unset($resArr[$key]);
+                $setArr = $matches[1];
+            }
+        }
+        return array_merge($resArr, $setArr);
+
+    }
+}
+

+ 85 - 0
apps/admin/model/content/LinkModel.php

@@ -0,0 +1,85 @@
+<?php
+/**
+ * @copyright (C)2016-2099 Hnaoyun Inc.
+ * @author XingMeng
+ * @email hnxsh@foxmail.com
+ * @date 2018年3月1日
+ *  友情链接模型类
+ */
+namespace app\admin\model\content;
+
+use core\basic\Model;
+
+class LinkModel extends Model
+{
+
+    // 获取友情链接列表
+    public function getList()
+    {
+        return parent::table('ay_link')->where("acode='" . session('acode') . "'")
+            ->order('gid asc,sorting asc,id asc')
+            ->page()
+            ->select();
+    }
+
+    // 查找友情链接
+    public function findLink($field, $keyword)
+    {
+        return parent::table('ay_link')->where("acode='" . session('acode') . "'")
+            ->like($field, $keyword)
+            ->order('gid asc,sorting asc,id asc')
+            ->page()
+            ->select();
+    }
+
+    // 获取友情链接详情
+    public function getLink($id)
+    {
+        return parent::table('ay_link')->where("id=$id")
+            ->where("acode='" . session('acode') . "'")
+            ->find();
+    }
+
+    // 获取分组
+    public function getGid()
+    {
+        return parent::table('ay_link')->distinct()
+            ->where("acode='" . session('acode') . "'")
+            ->order('gid')
+            ->column('gid');
+    }
+
+    // 获取最大分组值
+    public function getMaxGid()
+    {
+        return parent::table('ay_link')->max('gid');
+    }
+
+    // 添加友情链接
+    public function addLink(array $data)
+    {
+        return parent::table('ay_link')->autoTime()->insert($data);
+    }
+
+    // 删除友情链接
+    public function delLink($id)
+    {
+        return parent::table('ay_link')->where("id=$id")
+            ->where("acode='" . session('acode') . "'")
+            ->delete();
+    }
+
+    // 修改友情链接
+    public function modLink($id, $data)
+    {
+        return parent::table('ay_link')->autoTime()
+            ->where("id=$id")
+            ->where("acode='" . session('acode') . "'")
+            ->update($data);
+    }
+
+    public function getImage()
+    {
+        return parent::table('ay_link')->column('logo');
+    }
+}

+ 103 - 0
apps/admin/model/content/MessageModel.php

@@ -0,0 +1,103 @@
+<?php
+/**
+ * @copyright (C)2016-2099 Hnaoyun Inc.
+ * @author XingMeng
+ * @email hnxsh@foxmail.com
+ * @date 2017年3月29日
+ *  留言模型类
+ */
+namespace app\admin\model\content;
+
+use core\basic\Model;
+
+class MessageModel extends Model
+{
+
+    // 获取列表
+    public function getList($page = true)
+    {
+        $field = array(
+            'a.*',
+            'b.username',
+            'b.nickname',
+            'b.headpic'
+        );
+        $join = array(
+            'ay_member b',
+            'a.uid=b.id',
+            'LEFT'
+        );
+        return parent::table('ay_message a')->field($field)
+            ->join($join)
+            ->where("a.acode='" . session('acode') . "'")
+            ->order('a.id DESC')
+            ->decode(false)
+            ->page($page)
+            ->select();
+    }
+
+    // 获取详情
+    public function getMessage($id)
+    {
+        $field = array(
+            'a.*',
+            'b.username',
+            'b.nickname',
+            'b.headpic'
+        );
+        $join = array(
+            'ay_member b',
+            'a.uid=b.id',
+            'LEFT'
+        );
+        return parent::table('ay_message a')->field($field)
+            ->join($join)
+            ->where("a.id=$id")
+            ->where("a.acode='" . session('acode') . "'")
+            ->find();
+    }
+
+    // 删除留言
+    public function delMessage($id)
+    {
+        return parent::table('ay_message')->where("id=$id")
+            ->where("acode='" . session('acode') . "'")
+            ->delete();
+    }
+
+    // 修改留言
+    public function modMessage($id, $data)
+    {
+        return parent::table('ay_message')->autoTime()
+            ->where("id=$id")
+            ->where("acode='" . session('acode') . "'")
+            ->update($data);
+    }
+
+    // 获取表单字段
+    public function getFormFieldByCode($fcode)
+    {
+        return parent::table('ay_form_field')->where("fcode='$fcode'")
+            ->order('sorting ASC,id ASC')
+            ->select();
+    }
+
+    // 获取留言数量
+    public function getCount()
+    {
+        $rs = parent::table('ay_message')->field('count(*) as count')
+            ->where("acode='" . session('acode') . "'")
+            ->find();
+        return $rs->count ?: 0;
+    }
+
+    // 删除留言
+    public function clearMessage($where)
+    {
+        if(!$where){
+            return parent::table('ay_message')->delete();
+        } else {
+            return parent::table('ay_message')->delete($where);
+        }
+    }
+}

+ 140 - 0
apps/admin/model/content/ModelModel.php

@@ -0,0 +1,140 @@
+<?php
+/**
+ * @copyright (C)2016-2099 Hnaoyun Inc.
+ * @author XingMeng
+ * @email hnxsh@foxmail.com
+ * @date 2018年3月25日
+ *  内容模型模型类
+ */
+namespace app\admin\model\content;
+
+use core\basic\Model;
+
+class ModelModel extends Model
+{
+
+    // 获取内容模型列表
+    public function getList()
+    {
+        return parent::table('ay_model')->order('id ASC')
+            ->page()
+            ->select();
+    }
+
+    // 获取模型名称
+    public function getName($mcode)
+    {
+        return parent::table('ay_model')->where("mcode='$mcode'")->value('name');
+    }
+
+    // 获取内容模型选择
+    public function getSelectAll()
+    {
+        return parent::table('ay_model')->field('mcode,name,type,listtpl,contenttpl')
+            ->order('id ASC')
+            ->select();
+    }
+
+    // 获取内容模型选择
+    public function getModelMenu()
+    {
+        return parent::table('ay_model')->field('mcode,name,type')
+            ->where('status=1')
+            ->order('id ASC')
+            ->select();
+    }
+
+    // 获取模型内容数量
+    public function getModelCount($mcode)
+    {
+        $join = array(
+            array(
+                'ay_content_sort b',
+                'a.scode=b.scode',
+                'LEFT'
+            ),
+            array(
+                'ay_model d',
+                'b.mcode=d.mcode',
+                'LEFT'
+            )
+        );
+        return parent::table('ay_content a')->field('count(*) as count')
+            ->where("b.mcode='$mcode'")
+            ->where("a.acode='" . session('acode') . "'")
+            ->join($join)
+            ->find();
+    }
+
+    // 获取内容模型选择
+    public function getSelect()
+    {
+        return parent::table('ay_model')->field('mcode,name,type,listtpl,contenttpl')
+            ->where('status=1')
+            ->order('id ASC')
+            ->select();
+    }
+
+    // 查找内容模型
+    public function findModel($field, $keyword)
+    {
+        return parent::table('ay_model')->like($field, $keyword)
+            ->page()
+            ->select();
+    }
+
+    // 获取最后一个code
+    public function getLastCode()
+    {
+        return parent::table('ay_model')->order('id DESC')->value('mcode');
+    }
+
+    // 获取内容模型详情
+    public function getModel($id)
+    {
+        return parent::table('ay_model')->where("id=$id")->find();
+    }
+
+    // 添加内容模型
+    public function addModel(array $data)
+    {
+        return parent::table('ay_model')->autoTime()->insert($data);
+    }
+
+    // 删除内容模型
+    public function delModel($id)
+    {
+        $model = parent::table('ay_model')->where('id=' . $id)->find();
+        if (parent::table('ay_content_sort')->where("mcode='$model->mcode'")->find()) {
+            alert_back('模型下面有栏目,不允许直接删除!');
+        }
+        return parent::table('ay_model')->where("id=$id")
+            ->where("issystem=0")
+            ->delete();
+    }
+
+    // 修改内容模型
+    public function modModel($id, $data)
+    {
+        return parent::table('ay_model')->autoTime()
+            ->where("id=$id")
+            ->update($data);
+    }
+
+    // 检查URL名字冲突
+    public function checkUrlname($urlname, $type, $where = array())
+    {
+        return parent::table('ay_model')->field('id')
+            ->where("urlname='$urlname' AND type<>$type")
+            ->where($where)
+            ->find();
+    }
+
+    // 检查栏目名字冲突
+    public function checkSortFilename($urlname)
+    {
+        return parent::table('ay_content_sort')->field('id')
+            ->where("filename='$urlname'")
+            ->find();
+    }
+}

+ 196 - 0
apps/admin/model/content/SingleModel.php

@@ -0,0 +1,196 @@
+<?php
+/**
+ * @copyright (C)2016-2099 Hnaoyun Inc.
+ * @author XingMeng
+ * @email hnxsh@foxmail.com
+ * @date 2017年12月15日
+ *  单页文章模型类
+ */
+namespace app\admin\model\content;
+
+use core\basic\Model;
+
+class SingleModel extends Model
+{
+
+    // 获取文章列表
+    public function getList($mcode)
+    {
+        $field = array(
+            'a.id',
+            'a.scode',
+            'b.name as sortname',
+            'a.title',
+            'a.date',
+            'a.status',
+            'a.visits',
+            'b.mcode',
+            'a.ico',
+            'a.pics',
+            'a.outlink',
+            'b.filename',
+            'c.urlname'
+        );
+        $join = array(
+            array(
+                'ay_content_sort b',
+                'a.scode=b.scode',
+                'LEFT'
+            ),
+            array(
+                'ay_model c',
+                'b.mcode=c.mcode',
+                'LEFT'
+            )
+        );
+        return parent::table('ay_content a')->distinct()
+            ->field($field)
+            ->where("b.mcode='$mcode'")
+            ->where("a.acode='" . session('acode') . "'")
+            ->where('c.type=1')
+            ->join($join)
+            ->where('a.id IN(SELECT MAX(d.id) FROM ay_content d WHERE d.scode=a.scode)')
+            ->order('a.id DESC')
+            ->select();
+    }
+
+    // 查找文章
+    public function findSingle($mcode, $field, $keyword)
+    {
+        $fields = array(
+            'a.id',
+            'a.scode',
+            'b.name as sortname',
+            'a.title',
+            'a.date',
+            'a.status',
+            'a.visits',
+            'b.mcode',
+            'a.ico',
+            'a.pics',
+            'a.outlink',
+            'b.filename',
+            'c.urlname'
+        );
+        $join = array(
+            array(
+                'ay_content_sort b',
+                'a.scode=b.scode',
+                'LEFT'
+            ),
+            array(
+                'ay_model c',
+                'b.mcode=c.mcode',
+                'LEFT'
+            )
+        );
+        return parent::table('ay_content a')->distinct()
+            ->field($fields)
+            ->where("b.mcode='$mcode'")
+            ->where("a.acode='" . session('acode') . "'")
+            ->where('c.type=1')
+            ->like($field, $keyword)
+            ->join($join)
+            ->group('b.name')
+            ->order('a.id DESC')
+            ->select();
+    }
+
+    // 检查文章
+    public function checkSingle($where)
+    {
+        return parent::table('ay_content')->field('id')
+            ->where($where)
+            ->find();
+    }
+
+    // 获取文章详情
+    public function getSingle($id)
+    {
+        $field = array(
+            'a.*',
+            'b.name as sortname',
+            'c.*',
+            'b.filename',
+            'd.urlname'
+        );
+        $join = array(
+            array(
+                'ay_content_sort b',
+                'a.scode=b.scode',
+                'LEFT'
+            
+            ),
+            array(
+                'ay_content_ext c',
+                'a.id=c.contentid',
+                'LEFT'
+            ),
+            array(
+                'ay_model d',
+                'b.mcode=d.mcode',
+                'LEFT'
+            )
+        );
+        return parent::table('ay_content a')->field($field)
+            ->where("a.id=$id")
+            ->where("a.acode='" . session('acode') . "'")
+            ->join($join)
+            ->find();
+    }
+
+    // 添加文章
+    public function addSingle(array $data)
+    {
+        return parent::table('ay_content')->autoTime()->insert($data);
+    }
+
+    // 删除文章
+    public function delSingle($id)
+    {
+        return parent::table('ay_content')->where("id=$id")
+            ->where("acode='" . session('acode') . "'")
+            ->delete();
+    }
+
+    // 修改文章
+    public function modSingle($id, $data)
+    {
+        return parent::table('ay_content')->autoTime()
+            ->where("id=$id")
+            ->where("acode='" . session('acode') . "'")
+            ->update($data);
+    }
+
+    // 查找文章扩展内容
+    public function findContentExt($id)
+    {
+        return parent::table('ay_content_ext')->where("contentid=$id")->find();
+    }
+
+    // 添加文章扩展内容
+    public function addContentExt(array $data)
+    {
+        return parent::table('ay_content_ext')->insert($data);
+    }
+
+    // 修改文章扩展内容
+    public function modContentExt($id, $data)
+    {
+        return parent::table('ay_content_ext')->where("contentid=$id")->update($data);
+    }
+
+    // 删除文章扩展内容
+    public function delContentExt($id)
+    {
+        return parent::table('ay_content_ext')->where("contentid=$id")->delete();
+    }
+
+    // 检查自定义URL名称
+    public function checkFilename($where)
+    {
+        return parent::table('ay_content')->field('id')
+            ->where($where)
+            ->find();
+    }
+}

+ 50 - 0
apps/admin/model/content/SiteModel.php

@@ -0,0 +1,50 @@
+<?php
+/**
+ * @copyright (C)2016-2099 Hnaoyun Inc.
+ * @author XingMeng
+ * @email hnxsh@foxmail.com
+ * @date 2017年3月24日
+ *  站点配置模型类
+ */
+namespace app\admin\model\content;
+
+use core\basic\Model;
+
+class SiteModel extends Model
+{
+
+    // 获取系统配置信息
+    public function getList()
+    {
+        return parent::table('ay_site')->where("acode='" . session('acode') . "'")->find();
+    }
+
+    // 检查系统配置信息
+    public function checkSite()
+    {
+        return parent::table('ay_site')->where("acode='" . session('acode') . "'")->find();
+    }
+
+    // 增加系统配置信息
+    public function addSite($data)
+    {
+        return parent::table('ay_site')->insert($data);
+    }
+
+    // 修改系统配置信息
+    public function modSite($data)
+    {
+        return parent::table('ay_site')->where("acode='" . session('acode') . "'")->update($data);
+    }
+
+    // 系统数据库版本
+    public function getMysql()
+    {
+        return parent::one('SELECT VERSION()', MYSQLI_NUM);
+    }
+
+    public function getImage()
+    {
+        return parent::table('ay_site')->column('logo');
+    }
+}

+ 85 - 0
apps/admin/model/content/SlideModel.php

@@ -0,0 +1,85 @@
+<?php
+/**
+ * @copyright (C)2016-2099 Hnaoyun Inc.
+ * @author XingMeng
+ * @email hnxsh@foxmail.com
+ * @date 2018年3月1日
+ *  轮播图模型类
+ */
+namespace app\admin\model\content;
+
+use core\basic\Model;
+
+class SlideModel extends Model
+{
+
+    // 获取轮播图列表
+    public function getList()
+    {
+        return parent::table('ay_slide')->where("acode='" . session('acode') . "'")
+            ->order('gid asc,sorting asc,id asc')
+            ->page()
+            ->select();
+    }
+
+    // 查找轮播图
+    public function findSlide($field, $keyword)
+    {
+        return parent::table('ay_slide')->where("acode='" . session('acode') . "'")
+            ->like($field, $keyword)
+            ->order('gid asc,sorting asc,id asc')
+            ->page()
+            ->select();
+    }
+
+    // 获取轮播图详情
+    public function getSlide($id)
+    {
+        return parent::table('ay_slide')->where("id=$id")
+            ->where("acode='" . session('acode') . "'")
+            ->find();
+    }
+
+    // 获取分组
+    public function getGid()
+    {
+        return parent::table('ay_slide')->distinct()
+            ->where("acode='" . session('acode') . "'")
+            ->order('gid')
+            ->column('gid');
+    }
+
+    // 获取最大分组值
+    public function getMaxGid()
+    {
+        return parent::table('ay_slide')->max('gid');
+    }
+
+    // 添加轮播图
+    public function addSlide(array $data)
+    {
+        return parent::table('ay_slide')->autoTime()->insert($data);
+    }
+
+    // 删除轮播图
+    public function delSlide($id)
+    {
+        return parent::table('ay_slide')->where("id=$id")
+            ->where("acode='" . session('acode') . "'")
+            ->delete();
+    }
+
+    // 修改轮播图
+    public function modSlide($id, $data)
+    {
+        return parent::table('ay_slide')->autoTime()
+            ->where("id=$id")
+            ->where("acode='" . session('acode') . "'")
+            ->update($data);
+    }
+
+    public function getImage()
+    {
+        return parent::table('ay_slide')->column('pic');
+    }
+}

+ 65 - 0
apps/admin/model/content/TagsModel.php

@@ -0,0 +1,65 @@
+<?php
+/**
+ * @copyright (C)2016-2099 Hnaoyun Inc.
+ * @author XingMeng
+ * @email hnxsh@foxmail.com
+ * @date 2019年07月12日
+ *  内链链接模型类
+ */
+namespace app\admin\model\content;
+
+use core\basic\Model;
+
+class TagsModel extends Model
+{
+
+    // 获取文章内链列表
+    public function getList()
+    {
+        return parent::table('ay_tags')->where("acode='" . session('acode') . "'")
+            ->order('id asc')
+            ->page()
+            ->select();
+    }
+
+    // 查找文章内链
+    public function findTags($field, $keyword)
+    {
+        return parent::table('ay_tags')->where("acode='" . session('acode') . "'")
+            ->like($field, $keyword)
+            ->order('id asc')
+            ->page()
+            ->select();
+    }
+
+    // 获取文章内链详情
+    public function getTags($id)
+    {
+        return parent::table('ay_tags')->where("id=$id")
+            ->where("acode='" . session('acode') . "'")
+            ->find();
+    }
+
+    // 添加文章内链
+    public function addTags(array $data)
+    {
+        return parent::table('ay_tags')->autoTime()->insert($data);
+    }
+
+    // 删除文章内链
+    public function delTags($id)
+    {
+        return parent::table('ay_tags')->where("id=$id")
+            ->where("acode='" . session('acode') . "'")
+            ->delete();
+    }
+
+    // 修改文章内链
+    public function modTags($id, $data)
+    {
+        return parent::table('ay_tags')->autoTime()
+            ->where("id=$id")
+            ->where("acode='" . session('acode') . "'")
+            ->update($data);
+    }
+}

+ 136 - 0
apps/admin/model/member/MemberCommentModel.php

@@ -0,0 +1,136 @@
+<?php
+/**
+ * @copyright (C)2016-2099 Hnaoyun Inc.
+ * @author XingMeng
+ * @email hnxsh@foxmail.com
+ * @date 2020年06月27日
+ *  文章评论模型类
+ */
+namespace app\admin\model\member;
+
+use core\basic\Model;
+
+class MemberCommentModel extends Model
+{
+
+    // 获取列表
+    public function getList()
+    {
+        $field = array(
+            'a.*',
+            'b.title',
+            'c.username',
+            'c.nickname',
+            'c.headpic'
+        );
+        $join = array(
+            array(
+                'ay_content b',
+                'a.contentid=b.id',
+                'LEFT'
+            ),
+            array(
+                'ay_member c',
+                'a.uid=c.id',
+                'LEFT'
+            )
+        );
+        return parent::table('ay_member_comment a')->field($field)
+            ->join($join)
+            ->order('a.id desc')
+            ->page()
+            ->select();
+    }
+
+    // 查找
+    public function findComment($field, $keyword)
+    {
+        $fields = array(
+            'a.*',
+            'b.title',
+            'c.username',
+            'c.nickname',
+            'c.headpic'
+        );
+        $join = array(
+            array(
+                'ay_content b',
+                'a.contentid=b.id',
+                'LEFT'
+            ),
+            array(
+                'ay_member c',
+                'a.uid=c.id',
+                'LEFT'
+            )
+        );
+        return parent::table('ay_member_comment a')->field($fields)
+            ->join($join)
+            ->like($field, $keyword)
+            ->order('a.id desc')
+            ->page()
+            ->select();
+    }
+
+    // 获取详情
+    public function getComment($id)
+    {
+        $field = array(
+            'a.*',
+            'b.title',
+            'c.username',
+            'c.nickname',
+            'c.headpic',
+            'd.username as pusername',
+            'd.nickname as pnickname'
+        );
+        $join = array(
+            array(
+                'ay_content b',
+                'a.contentid=b.id',
+                'LEFT'
+            ),
+            array(
+                'ay_member c',
+                'a.uid=c.id',
+                'LEFT'
+            ),
+            array(
+                'ay_member d',
+                'a.puid=d.id',
+                'LEFT'
+            )
+        );
+        
+        return parent::table('ay_member_comment a')->field($field)
+            ->join($join)
+            ->where("a.id=$id")
+            ->find();
+    }
+
+    // 删除
+    public function delComment($id)
+    {
+        return parent::table('ay_member_comment')->where("id=$id")->delete();
+    }
+
+    // 删除多个
+    public function delCommentList($ids)
+    {
+        return parent::table('ay_member_comment')->delete($ids);
+    }
+
+    // 修改
+    public function modComment($id, $data)
+    {
+        return parent::table('ay_member_comment')->where("id=$id")
+            ->autoTime()
+            ->update($data);
+    }
+
+    // 修改多个
+    public function modCommentList($ids, $data)
+    {
+        return parent::table('ay_member_comment')->in('id', $ids)->update($data);
+    }
+}

+ 79 - 0
apps/admin/model/member/MemberFieldModel.php

@@ -0,0 +1,79 @@
+<?php
+/**
+ * @copyright (C)2016-2099 Hnaoyun Inc.
+ * @author XingMeng
+ * @email hnxsh@foxmail.com
+ * @date 2020年06月25日
+ *  会员字段模型类
+ */
+namespace app\admin\model\member;
+
+use core\basic\Model;
+
+class MemberFieldModel extends Model
+{
+
+    // 获取会员字段列表
+    public function getList()
+    {
+        return parent::table('ay_member_field')->order('sorting asc,id asc')
+            ->page()
+            ->select();
+    }
+
+    // 查找会员字段
+    public function findField($field, $keyword)
+    {
+        return parent::table('ay_member_field')->like($field, $keyword)
+            ->order('sorting asc,id asc')
+            ->page()
+            ->select();
+    }
+
+    // 检查会员字段
+    public function checkField($name)
+    {
+        return parent::table('ay_member_field')->where("name='$name'")->find();
+    }
+
+    // 获取会员字段详情
+    public function getField($id)
+    {
+        return parent::table('ay_member_field')->where("id=$id")->find();
+    }
+
+    // 获取会员字段名称
+    public function getFieldName($id)
+    {
+        return parent::table('ay_member_field')->where("id=$id")->value('name');
+    }
+
+    // 添加会员字段
+    public function addField(array $data)
+    {
+        return parent::table('ay_member_field')->autoTime()->insert($data);
+    }
+
+    // 删除会员字段
+    public function delField($id)
+    {
+        return parent::table('ay_member_field')->where("id=$id")->delete();
+    }
+
+    // 修改会员字段
+    public function modField($id, $data)
+    {
+        return parent::table('ay_member_field')->where("id=$id")->update($data);
+    }
+
+    // 判断字段是否存在
+    public function isExistField($field)
+    {
+        $fields = parent::tableFields('ay_member');
+        if (in_array($field, $fields)) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+}

+ 98 - 0
apps/admin/model/member/MemberGroupModel.php

@@ -0,0 +1,98 @@
+<?php
+/**
+ * @copyright (C)2016-2099 Hnaoyun Inc.
+ * @author XingMeng
+ * @email hnxsh@foxmail.com
+ * @date 2020年06月25日
+ *  会员等级模型类
+ */
+namespace app\admin\model\member;
+
+use core\basic\Model;
+
+class MemberGroupModel extends Model
+{
+
+    // 获取会员等级列表
+    public function getList()
+    {
+        return parent::table('ay_member_group')->order('gcode,id')
+            ->page()
+            ->select();
+    }
+
+    // 查找会员等级
+    public function findGroup($field, $keyword)
+    {
+        return parent::table('ay_member_group')->like($field, $keyword)
+            ->order('gcode,id')
+            ->page()
+            ->select();
+    }
+
+    // 获取最后一个code
+    public function getLastGid()
+    {
+        return parent::table('ay_member_group')->order('id DESC')->value('gcode');
+    }
+
+    // 获取等级选择列表
+    public function getSelect()
+    {
+        return parent::table('ay_member_group')->field('id,gcode,gname')
+            ->order('gcode,id')
+            ->select();
+    }
+
+    // 获取会员等级详情
+    public function getGroup($id)
+    {
+        return parent::table('ay_member_group')->where("id=$id")->find();
+    }
+
+    // 获取会员等级名称
+    public function getGroupName($id)
+    {
+        return parent::table('ay_member_group')->where("id=$id")->value('gname');
+    }
+
+    // 添加会员等级
+    public function addGroup(array $data)
+    {
+        return parent::table('ay_member_group')->autoTime()->insert($data);
+    }
+
+    // 删除会员等级
+    public function delGroup($id)
+    {
+        return parent::table('ay_member_group')->where("id=$id")->delete();
+    }
+
+    // 修改会员等级
+    public function modGroup($id, $data)
+    {
+        return parent::table('ay_member_group')->where("id=$id")->update($data);
+    }
+
+    // 查找等级下会员是否存在
+    public function findGroupUser($id)
+    {
+        return parent::table('ay_member')->field('id')
+            ->where("gid=$id")
+            ->find();
+    }
+
+    // 查找等级编号
+    public function findGroupCode($gcode, $id = null)
+    {
+        if ($id) {
+            return parent::table('ay_member_group')->field('id')
+                ->where("gcode='$gcode' and id<>$id")
+                ->find();
+        } else {
+            return parent::table('ay_member_group')->field('id')
+                ->where("gcode='$gcode'")
+                ->find();
+        }
+    }
+}

+ 122 - 0
apps/admin/model/member/MemberModel.php

@@ -0,0 +1,122 @@
+<?php
+/**
+ * @copyright (C)2016-2099 Hnaoyun Inc.
+ * @author XingMeng
+ * @email hnxsh@foxmail.com
+ * @date 2019年10月05日
+ *  会员模型类
+ */
+namespace app\admin\model\member;
+
+use core\basic\Model;
+
+class MemberModel extends Model
+{
+
+    // 获取会员列表
+    public function getList()
+    {
+        $field = array(
+            'a.*',
+            'b.gname'
+        );
+        $join = array(
+            'ay_member_group b',
+            'a.gid=b.id',
+            'LEFT'
+        );
+        return parent::table('ay_member a')->field($field)
+            ->join($join)
+            ->order('a.id desc')
+            ->page()
+            ->select();
+    }
+
+    // 查找会员
+    public function findMember($field, $keyword)
+    {
+        $fields = array(
+            'a.*',
+            'b.gname'
+        );
+        $join = array(
+            'ay_member_group b',
+            'a.gid=b.id',
+            'LEFT'
+        );
+        return parent::table('ay_member a')->field($fields)
+            ->join($join)
+            ->like($field, $keyword)
+            ->order('a.id desc')
+            ->page()
+            ->select();
+    }
+
+    // 检查会员
+    public function checkMember($where)
+    {
+        return parent::table('ay_member')->where($where)->find();
+    }
+
+    // 获取最后一个code
+    public function getLastCode()
+    {
+        return parent::table('ay_member')->order('id DESC')->value('ucode');
+    }
+
+    // 获取会员详情
+    public function getMember($id)
+    {
+        $field = array(
+            'a.*',
+            'b.gname'
+        );
+        $join = array(
+            'ay_member_group b',
+            'a.gid=b.id',
+            'LEFT'
+        );
+        return parent::table('ay_member a')->field($field)
+            ->join($join)
+            ->where("a.id=$id")
+            ->find();
+    }
+
+    // 添加会员
+    public function addMember(array $data)
+    {
+        return parent::table('ay_member')->insert($data);
+    }
+
+    // 删除会员
+    public function delMember($id)
+    {
+        return parent::table('ay_member')->where("id=$id")->delete();
+    }
+
+    // 删除会员
+    public function delMemberList($ids)
+    {
+        return parent::table('ay_member')->delete($ids);
+    }
+
+    // 修改会员
+    public function modMember($id, $data)
+    {
+        return parent::table('ay_member')->where("id=$id")->update($data);
+    }
+
+    // 修改会员
+    public function modMemberList($ids, $data)
+    {
+        return parent::table('ay_member')->in('id', $ids)->update($data);
+    }
+
+    // 会员字段
+    public function getFields()
+    {
+        return parent::table('ay_member_field')->where('status=1')
+            ->order('sorting')
+            ->select();
+    }
+}

+ 101 - 0
apps/admin/model/system/AreaModel.php

@@ -0,0 +1,101 @@
+<?php
+/**
+ * @copyright (C)2016-2099 Hnaoyun Inc.
+ * @author XingMeng
+ * @email hnxsh@foxmail.com
+ * @date 2017年04月07日
+ *  区域模型类
+ */
+namespace app\admin\model\system;
+
+use core\basic\Model;
+
+class AreaModel extends Model
+{
+
+    // 获取区域列表
+    public function getList()
+    {
+        $result = parent::table('ay_area')->order('pcode,acode')
+            ->page()
+            ->select();
+        $tree = get_tree($result, 0, 'acode', 'pcode');
+        return $tree;
+    }
+
+    // 获取区域选择列表
+    public function getSelect()
+    {
+        $result = parent::table('ay_area')->field('pcode,acode,name')
+            ->order('pcode,acode')
+            ->select();
+        $tree = get_tree($result, 0, 'acode', 'pcode');
+        return $tree;
+    }
+
+    // 检查区域
+    public function checkArea($where)
+    {
+        return parent::table('ay_area')->field('id')
+            ->where($where)
+            ->find();
+    }
+
+    // 获取区域详情
+    public function getArea($acode)
+    {
+        return parent::table('ay_area')->where("acode='$acode'")->find();
+    }
+
+    // 获取最后一个code
+    public function getLastCode()
+    {
+        return parent::table('ay_area')->order('id DESC')->value('acode');
+    }
+
+    // 添加区域
+    public function addArea(array $data)
+    {
+        if ($data['is_default']) {
+            $this->unsetDefault($data['acode']);
+        }
+        return parent::table('ay_area')->autoTime()->insert($data);
+    }
+
+    // 删除区域
+    public function delArea($acode)
+    {
+        return parent::table('ay_area')->where("acode='$acode' OR pcode='$acode'")
+            ->where('is_default=0')
+            ->delete();
+    }
+
+    // 修改区域资料
+    public function modArea($acode, $data)
+    {
+        $result = parent::table('ay_area')->autoTime()
+            ->where("acode='$acode'")
+            ->update($data);
+        if ($data['is_default']) {
+            $this->unsetDefault($data['acode']);
+        }
+        if ($result && array_key_exists('acode', $data) && $acode != $data['acode']) {
+            $this->modSubArea($acode, $data['acode']);
+        }
+        return $result;
+    }
+
+    // 当父编号改变时,修改子栏目的父编码
+    private function modSubArea($pcode, $pcodeNew)
+    {
+        return parent::table('ay_area')->where("pcode='$pcode'")
+            ->autoTime()
+            ->update("pcode='$pcodeNew'");
+    }
+
+    // 去除$acode以外的默认区域
+    private function unsetDefault($acode)
+    {
+        parent::table('ay_area')->where("acode<>'$acode'")->update('is_default=0');
+    }
+}

+ 66 - 0
apps/admin/model/system/ConfigModel.php

@@ -0,0 +1,66 @@
+<?php
+/**
+ * @copyright (C)2016-2099 Hnaoyun Inc.
+ * @author XingMeng
+ * @email hnxsh@foxmail.com
+ * @date 2018年01月03日
+ * 应用配置模型类
+ */
+namespace app\admin\model\system;
+
+use core\basic\Model;
+
+class ConfigModel extends Model
+{
+
+    // 获取应用配置列表
+    public function getList()
+    {
+        return parent::table('ay_config')->order('sorting,id')->column('name,value,type,description', 'name');
+    }
+
+    // 检查应用配置
+    public function checkConfig($where)
+    {
+        return parent::table('ay_config')->field('id')
+            ->where($where)
+            ->find();
+    }
+
+    // 添加应用配置字段
+    public function addConfig(array $data)
+    {
+        return parent::table('ay_config')->insert($data);
+    }
+
+    // 修改应用配置值
+    public function modValue($name, $value)
+    {
+        return parent::table('ay_config')->where("name='$name'")->update("value='$value'");
+    }
+
+    // 获取区域及主题
+    public function getAreaTheme()
+    {
+        $field = array(
+            'a.*',
+            'b.theme'
+        );
+        $join = array(
+            'ay_site b',
+            'a.acode=b.acode',
+            'LEFT'
+        );
+        return parent::table('ay_area a')->field($field)
+            ->join($join)
+            ->order('is_default DESC')
+            ->select(1);
+    }
+
+    // 获取配置参数
+    public function getConfig()
+    {
+        return parent::table('ay_config')->column('value', 'name');
+    }
+}
+

+ 102 - 0
apps/admin/model/system/DatabaseModel.php

@@ -0,0 +1,102 @@
+<?php
+/**
+ * @copyright (C)2016-2099 Hnaoyun Inc.
+ * @author XingMeng
+ * @email hnxsh@foxmail.com
+ * @date 2017年11月19日
+ *  数据库管理模型类,只兼容MySQL数据库
+ */
+namespace app\admin\model\system;
+
+use core\basic\Model;
+
+class DatabaseModel extends Model
+{
+
+    // 数据库表状态列表
+    public function getList()
+    {
+        return parent::all('SHOW TABLE STATUS');
+    }
+
+    // 获取全部表
+    public function getTables()
+    {
+        $result = parent::all('SHOW TABLES', 2);
+        foreach ($result as $value) {
+            $tables[] = $value[0];
+        }
+        return $tables;
+    }
+
+    // 获取表字段数量
+    public function getFieldNum($table)
+    {
+        return parent::fields($table);
+    }
+
+    // 获取表字段名
+    public function getFields($table)
+    {
+        $one_data = parent::one("SELECT * FROM " . $table); // 读取数据
+        $fields = array();
+        if ($one_data) {
+            foreach ($one_data as $key => $value) {
+                $fields[] = "`$key`";
+            }
+        }
+        return $fields;
+    }
+
+    // 获取一条数据
+    public function getOne($table)
+    {
+        return parent::one("SELECT * FROM " . $table);
+    }
+
+    // 获取全部数据
+    public function getAll($table)
+    {
+        return parent::all("SELECT * FROM " . $table, MYSQLI_NUM);
+    }
+
+    // 数据库表结构
+    public function tableStru($table)
+    {
+        $sql = "DROP TABLE IF EXISTS `" . $table . '`;' . PHP_EOL;
+        $result = parent::one('SHOW CREATE TABLE `' . $table . '`', MYSQLI_ASSOC);
+        return $sql . $result['Create Table'] . ';' . PHP_EOL . PHP_EOL;
+    }
+
+    // 数据库表优化
+    public function optimize($tables)
+    {
+        return parent::query("OPTIMIZE TABLE $tables");
+    }
+
+    // 数据库表修复
+    public function repair($tables)
+    {
+        return parent::query("REPAIR TABLE $tables");
+    }
+
+    // 锁定数据库表
+    public function lock($tablename, $op = "WRITE")
+    {
+        if (parent::query("lock tables " . $tablename . " " . $op)) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    // 解锁数据库标
+    public function unlock()
+    {
+        if (parent::query("unlock tables")) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+}

+ 161 - 0
apps/admin/model/system/MenuModel.php

@@ -0,0 +1,161 @@
+<?php
+/**
+ * @copyright (C)2016-2099 Hnaoyun Inc.
+ * @author XingMeng
+ * @email hnxsh@foxmail.com
+ * @date 2017年4月3日
+ *  菜单管理模型类
+ */
+namespace app\admin\model\system;
+
+use core\basic\Model;
+
+class MenuModel extends Model
+{
+
+    // 获取菜单列表
+    public function getList()
+    {
+        $result = parent::table('ay_menu')->order('pcode,sorting,id')->select();
+        $tree = get_tree($result, 0, 'mcode', 'pcode');
+        return $tree;
+    }
+
+    // 获取菜单选择列表
+    public function getSelect()
+    {
+        $result = parent::table('ay_menu')->field('id,pcode,mcode,name,url,sorting')
+            ->order('pcode,sorting,id')
+            ->select();
+        $tree = get_tree($result, 0, 'mcode', 'pcode');
+        return $tree;
+    }
+
+    // 获取菜单详情
+    public function getMenu($mcode)
+    {
+        $result = parent::table('ay_menu')->where("mcode='$mcode'")->find();
+        if ($result)
+            $result->actions = $this->getMenuAction($result->mcode);
+        return $result;
+    }
+
+    // 检查是否存在
+    public function checkMenu($data)
+    {
+        return parent::table('ay_menu')->where($data)->find();
+    }
+
+    // 获取最后一个code
+    public function getLastCode()
+    {
+        return parent::table('ay_menu')->order('mcode DESC')->value('mcode');
+    }
+
+    // 新增菜单,$actions为菜单功能按钮数组
+    public function addMenu(array $data, array $actions = array())
+    {
+        $result = parent::table('ay_menu')->autoTime()->insert($data);
+        if ($result && $actions) {
+            $this->delMenuAction($data['mcode']);
+            $this->addMenuAction($data['mcode'], $actions);
+        }
+        return $result;
+    }
+
+    // 删除菜单
+    public function delMenu($mcode)
+    {
+        $result = parent::table('ay_menu')->where("mcode='$mcode' OR pcode='$mcode'")->delete();
+        if ($result) {
+            $this->delMenuAction($mcode);
+        }
+        return $result;
+    }
+
+    // 修改菜单
+    public function modMenu($mcode, $data, array $actions = null)
+    {
+        $result = parent::table('ay_menu')->where("mcode='$mcode'")
+            ->autoTime()
+            ->update($data);
+        if ($result) {
+            if (array_key_exists('mcode', $data) && $mcode != $data['mcode']) {
+                $this->modSubMenu($mcode, $data['mcode']);
+            }
+            if (is_array($actions)) {
+                $this->delMenuAction($mcode);
+            }
+            if ($actions) {
+                if (array_key_exists('mcode', $data)) {
+                    $mcode = $data['mcode'];
+                }
+                $this->addMenuAction($mcode, $actions);
+            }
+        }
+        return $result;
+    }
+
+    // 修改子菜单的父菜单
+    private function modSubMenu($mcode, $mcodeNew)
+    {
+        return parent::table('ay_menu')->where("pcode='$mcode'")->update("mcode='$mcodeNew'");
+    }
+
+    // 获取指定菜单的功能数据
+    private function getMenuAction($mcode)
+    {
+        return parent::table('ay_menu_action')->where("mcode='$mcode'")->column('action');
+    }
+
+    // 插入指定菜单功能关联数据
+    private function addMenuAction($mcode, array $actions)
+    {
+        return parent::table('ay_menu_action')->field('mcode,action')
+            ->relation($mcode, $actions)
+            ->insert();
+    }
+
+    // 删除指定菜单功能关联数据
+    private function delMenuAction($mcode)
+    {
+        return parent::table('ay_menu_action')->where("mcode='$mcode'")->delete();
+    }
+
+    // 获取菜单权限功能表
+    public function getMenuLevel()
+    {
+        $table = array(
+            'ay_menu',
+            'ay_menu_action',
+            'ay_type'
+        );
+        $field = array(
+            'ay_menu.mcode',
+            'ay_menu.name',
+            'ay_menu.url',
+            'ay_type.item',
+            'ay_type.value'
+        );
+        $where = array(
+            "ay_type.tcode='T101'",
+            "ay_menu.mcode=ay_menu_action.mcode",
+            "ay_type.value=ay_menu_action.action"
+        );
+        $order = array(
+            'ay_menu.mcode',
+            'ay_type.tcode',
+            'ay_type.sorting'
+        );
+        $result = parent::table($table)->field($field)
+            ->where($where)
+            ->order($order)
+            ->select();
+        $data = array();
+        foreach ($result as $key => $value) {
+            $data[$value->mcode][] = $value;
+        }
+        return $data;
+    }
+}
+

+ 169 - 0
apps/admin/model/system/RoleModel.php

@@ -0,0 +1,169 @@
+<?php
+/**
+ * @copyright (C)2016-2099 Hnaoyun Inc.
+ * @author XingMeng
+ * @email hnxsh@foxmail.com
+ * @date 2017年04月07日
+ *  角色管理模型类
+ */
+namespace app\admin\model\system;
+
+use core\basic\Model;
+
+class RoleModel extends Model
+{
+
+    // 获取角色列表
+    public function getList()
+    {
+        return parent::table('ay_role')->order('rcode,id DESC')
+            ->page()
+            ->select();
+    }
+
+    // 获取角色选择列表
+    public function getSelect()
+    {
+        return parent::table('ay_role')->field('rcode,name')
+            ->order('rcode,id')
+            ->select();
+    }
+
+    // 检查角色
+    public function checkRole($where)
+    {
+        return parent::table('ay_role')->field('id')
+            ->where($where)
+            ->find();
+    }
+
+    // 获取角色详情
+    public function getRole($rcode)
+    {
+        $result = parent::table('ay_role')->where("rcode='$rcode'")->find();
+        if ($result) {
+            $result->acodes = $this->getRoleArea($rcode);
+            $result->levels = $this->getRoleLevel($rcode);
+        }
+        return $result;
+    }
+
+    // 获取最后一个code
+    public function getLastCode()
+    {
+        return parent::table('ay_role')->order('id DESC')->value('rcode');
+    }
+
+    // 添加角色
+    public function addRole(array $data, array $acodes, array $levels)
+    {
+        $result = parent::table('ay_role')->autoTime()->insert($data);
+        if ($result) {
+            if ($acodes) {
+                $this->delRoleArea($data['rcode']);
+                $this->addRoleArea($data['rcode'], $acodes);
+            }
+            if ($levels) {
+                $this->delRoleLevel($data['rcode']);
+                $this->addRoleLevel($data['rcode'], $levels);
+            }
+        }
+        return $result;
+    }
+
+    // 删除角色
+    public function delRole($rcode)
+    {
+        $result = parent::table('ay_role')->where("rcode='$rcode'")->delete();
+        if ($result) {
+            $this->delRoleArea($rcode);
+            $this->delRoleLevel($rcode);
+            $this->delUserRole($rcode);
+        }
+        return $result;
+    }
+
+    // 修改角色资料
+    public function modRole($rcode, $data, array $acodes = null, array $levels = null)
+    {
+        $result = parent::table('ay_role')->where("rcode='$rcode'")
+            ->autoTime()
+            ->update($data);
+        if ($result) {
+            if (is_array($acodes)) {
+                $this->delRoleArea($rcode);
+            }
+            
+            if (is_array($levels)) {
+                $this->delRoleLevel($rcode);
+            }
+            
+            if (array_key_exists('rcode', $data)) {
+                if ($rcode != $data['rcode']) {
+                    $this->modUserRole($rcode, "rcode='" . $data['rcode'] . "'");
+                    $rcode = $data['rcode'];
+                }
+            }
+            if ($acodes) {
+                $this->addRoleArea($rcode, $acodes);
+            }
+            if ($levels) {
+                $this->addRoleLevel($rcode, $levels);
+            }
+        }
+        return $result;
+    }
+
+    // 获取角色的区域数据
+    private function getRoleArea($rcode)
+    {
+        return parent::table('ay_role_area')->where("rcode='$rcode'")->column('acode');
+    }
+
+    // 插入角色区域关联数据
+    private function addRoleArea($rcode, array $acodes)
+    {
+        return parent::table('ay_role_area')->field('rcode,acode')
+            ->relation($rcode, $acodes)
+            ->insert();
+    }
+
+    // 删除角色区域关联数据
+    private function delRoleArea($rcode)
+    {
+        return parent::table('ay_role_area')->where("rcode='$rcode'")->delete();
+    }
+
+    // 获取角色的权限数据
+    private function getRoleLevel($rcode)
+    {
+        return parent::table('ay_role_level')->where("rcode='$rcode'")->column('level');
+    }
+
+    // 插入角色权限关联数据
+    private function addRoleLevel($rcode, array $levels)
+    {
+        return parent::table('ay_role_level')->field('rcode,level')
+            ->relation($rcode, $levels)
+            ->insert();
+    }
+
+    // 删除角色权限关联数据
+    private function delRoleLevel($rcode)
+    {
+        return parent::table('ay_role_level')->where("rcode='$rcode'")->delete();
+    }
+
+    // 删除角色用户关联数据
+    private function delUserRole($rcode)
+    {
+        return parent::table('ay_user_role')->where("rcode='$rcode'")->delete();
+    }
+
+    // 修改角色用户关联数据
+    private function modUserRole($rcode, $data)
+    {
+        return parent::table('ay_user_role')->where("rcode='$rcode'")->update($data);
+    }
+}
+

+ 29 - 0
apps/admin/model/system/SyslogModel.php

@@ -0,0 +1,29 @@
+<?php
+/**
+ * @copyright (C)2016-2099 Hnaoyun Inc.
+ * @author XingMeng
+ * @email hnxsh@foxmail.com
+ * @date 2017年3月29日
+ *  日志模型类
+ */
+namespace app\admin\model\system;
+
+use core\basic\Model;
+
+class SyslogModel extends Model
+{
+
+    // 获取日志列表
+    public function getList()
+    {
+        return parent::table('ay_syslog')->order('id DESC')
+            ->page()
+            ->select();
+    }
+
+    // 删除全部
+    public function clearLog()
+    {
+        return parent::table('ay_syslog')->delete();
+    }
+}

+ 89 - 0
apps/admin/model/system/TypeModel.php

@@ -0,0 +1,89 @@
+<?php
+/**
+ * @copyright (C)2016-2099 Hnaoyun Inc.
+ * @author XingMeng
+ * @email hnxsh@foxmail.com
+ * @date 2017年04月07日
+ *  类型模型类
+ */
+namespace app\admin\model\system;
+
+use core\basic\Model;
+
+class TypeModel extends Model
+{
+
+    // 获取类型列表
+    public function getList()
+    {
+        return parent::table('ay_type')->order('tcode DESC,sorting')
+            ->page()
+            ->select();
+    }
+
+    // 查找类型
+    public function findType($field, $keyword)
+    {
+        return parent::table('ay_type')->like($field, $keyword)
+            ->order('tcode DESC,sorting')
+            ->page()
+            ->select();
+    }
+
+    // 获取类型编码选择
+    public function getSelect()
+    {
+        return parent::table('ay_type')->distinct()
+            ->field('tcode,name')
+            ->order('tcode')
+            ->select();
+    }
+
+    // 检查类型
+    public function checkType($where)
+    {
+        return parent::table('ay_type')->field('id')
+            ->where($where)
+            ->find();
+    }
+
+    // 获取类型详情
+    public function getType($id)
+    {
+        return parent::table('ay_type')->where("id=$id")->find();
+    }
+
+    // 获取指定分类项
+    public function getItem($tcode)
+    {
+        return parent::table('ay_type')->field('item,value')
+            ->where("tcode='$tcode'")
+            ->select();
+    }
+
+    // 获取最后一个code
+    public function getLastCode()
+    {
+        return parent::table('ay_type')->order('id DESC')->value('tcode');
+    }
+
+    // 添加类型
+    public function addType(array $data)
+    {
+        return parent::table('ay_type')->autoTime()->insert($data);
+    }
+
+    // 删除类型
+    public function delType($id)
+    {
+        return parent::table('ay_type')->where("id=$id")->delete();
+    }
+
+    // 修改类型资料
+    public function modType($id, $data)
+    {
+        return parent::table('ay_type')->where("id=$id")
+            ->autoTime()
+            ->update($data);
+    }
+}

+ 166 - 0
apps/admin/model/system/UserModel.php

@@ -0,0 +1,166 @@
+<?php
+/**
+ * @copyright (C)2016-2099 Hnaoyun Inc.
+ * @author XingMeng
+ * @email hnxsh@foxmail.com
+ * @date 2017年04月07日
+ *  用户模型类
+ */
+namespace app\admin\model\system;
+
+use core\basic\Model;
+
+class UserModel extends Model
+{
+
+    // 获取用户列表
+    public function getList()
+    {
+        $result = parent::table('ay_user')->page()
+            ->order('id DESC')
+            ->select();
+        // 获取每用户的第一角色
+        foreach ($result as $key => $value) {
+            if ($value->ucode == '10001') {
+                $value->rolename = '创始人';
+                continue;
+            }
+            $roles = $this->getUserRole($value->ucode);
+            if ($roles) {
+                $value->rolename = $roles[0]->name;
+            } else {
+                $value->rolename = '';
+            }
+        }
+        return $result;
+    }
+
+    // 查找用户资料
+    public function findUser($field, $keyword)
+    {
+        $result = parent::table('ay_user')->like($field, $keyword)
+            ->order('id DESC')
+            ->page()
+            ->select();
+        // 获取每用户的第一角色
+        foreach ($result as $key => $value) {
+            if ($value->ucode == '10001') {
+                $value->rolename = '创始人';
+                continue;
+            }
+            $roles = $this->getUserRole($value->ucode);
+            if ($roles) {
+                $value->rolename = $roles[0]->name;
+            } else {
+                $value->rolename = '';
+            }
+        }
+        return $result;
+    }
+
+    // 获取用户列表
+    public function getSelect()
+    {
+        return parent::table('ay_user')->field('ucode,username,realname')
+            ->order('id DESC')
+            ->select();
+    }
+
+    // 检查用户
+    public function checkUser($where)
+    {
+        return parent::table('ay_user')->field('id')
+            ->where($where)
+            ->find();
+    }
+
+    // 获取用户详情
+    public function getUser($ucode)
+    {
+        $result = parent::table('ay_user')->where("ucode='$ucode'")->find();
+        // 用户角色信息
+        if ($result) {
+            $roles = $this->getUserRole($ucode);
+            $result->roles = $roles;
+            $result->rcodes = get_mapping($roles, 'rcode');
+        }
+        return $result;
+    }
+
+    // 获取最后一个code
+    public function getLastCode()
+    {
+        return parent::table('ay_user')->order('id DESC')->value('ucode');
+    }
+
+    // 添加用户
+    public function addUser(array $data, array $roles)
+    {
+        $result = parent::table('ay_user')->insert($data);
+        if ($result && $roles) {
+            $this->addUserRole($data['ucode'], $roles);
+        }
+        return $result;
+    }
+
+    // 删除用户
+    public function delUser($ucode)
+    {
+        $result = parent::table('ay_user')->where("ucode='$ucode' AND ucode<>10001")->delete();
+        if ($result) {
+            $this->delUserRole($ucode);
+        }
+        return $result;
+    }
+
+    // 修改用户资料
+    public function modUser($ucode, $data, array $roles = null)
+    {
+        $result = parent::table('ay_user')->where("ucode='$ucode'")->update($data);
+        if (is_array($roles)) {
+            $result = $this->delUserRole($ucode);
+            if ($roles) {
+                if (array_key_exists('ucode', $data)) {
+                    $ucode = $data['ucode'];
+                }
+                if ($ucode != '10001')
+                    $result = $this->addUserRole($ucode, $roles);
+            }
+        }
+        return $result;
+    }
+
+    // 获取指定用户角色表
+    private function getUserRole($ucode)
+    {
+        $table = array(
+            'ay_role',
+            'ay_user_role'
+        );
+        $field = array(
+            'ay_role.rcode',
+            'ay_role.name'
+        );
+        $where = array(
+            "ay_user_role.ucode='$ucode'",
+            "ay_role.rcode=ay_user_role.rcode"
+        );
+        return parent::table($table)->field($field)
+            ->where($where)
+            ->select();
+    }
+
+    // 插入用户角色关联数据
+    private function addUserRole($ucode, array $roles)
+    {
+        return parent::table('ay_user_role')->field('ucode,rcode')
+            ->relation($ucode, $roles)
+            ->insert();
+    }
+
+    // 删除用户角色关联数据
+    private function delUserRole($ucode)
+    {
+        return parent::table('ay_user_role')->where("ucode='$ucode' AND ucode<>10001")->delete();
+    }
+}

+ 20 - 0
apps/admin/view/default/common/foot.html

@@ -0,0 +1,20 @@
+<input type="hidden" id="do_check" data-url="{url./admin/Upgrade/check}">
+<input type="hidden" id="do_down" data-url="{url./admin/Upgrade/down}">
+<input type="hidden" id="do_update" data-url="{url./admin/Upgrade/update}">
+<input type="hidden" id="check_version" data-url="/index.php?p=upgrade/check&version={APP_VERSION}.{RELEASE_TIME}.{$revise}&branch={$branch}&snuser={$snuser}&site={$site}">
+<input type="hidden" id="check_cache" data-url="{url./admin/Upgrade/checkCache}">
+</div>
+
+<script type="text/javascript" src="{APP_THEME_DIR}/layui/layui.all.js?v=v2.5.4"></script>
+<script type="text/javascript" src="{APP_THEME_DIR}/js/comm.js?v=v3.1.1"></script>
+<script type="text/javascript" src="{APP_THEME_DIR}/js/mylayui.js?v=v3.1.0"></script>
+
+<script type="text/javascript" src="https://www.pbootcms.com/res/v1/js/update.js?v=v3.1.3" ></script>
+<!-- 让IE8/9支持媒体查询,从而兼容栅格 -->
+<!--[if lt IE 9]>
+  <script src="https://cdn.staticfile.org/html5shiv/r29/html5.min.js"></script>
+  <script src="https://cdn.staticfile.org/respond.js/1.4.2/respond.min.js"></script>
+<![endif]-->
+
+</body>
+</html>

+ 137 - 0
apps/admin/view/default/common/head.html

@@ -0,0 +1,137 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta charset="utf-8">
+  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
+  <meta name="renderer"  content="webkit">
+  <title>{CMSNAME}管理中心-V{APP_VERSION}-{RELEASE_TIME}</title>
+  <link rel="shortcut icon" href="{SITE_DIR}/favicon.ico" type="image/x-icon">
+  <link rel="stylesheet" href="{APP_THEME_DIR}/layui/css/layui.css?v=v2.5.4">
+  <link rel="stylesheet" href="{APP_THEME_DIR}/font-awesome/css/font-awesome.min.css?v=v4.7.0" type="text/css">
+  <link rel="stylesheet" href="{APP_THEME_DIR}/css/comm.css?v=v3.0.6">
+  <link href="{APP_THEME_DIR}/css/jquery.treetable.css" rel="stylesheet" type="text/css" />
+  <script type="text/javascript" src="{APP_THEME_DIR}/js/jquery-1.12.4.min.js"></script>
+  <script type="text/javascript" src="{APP_THEME_DIR}/js/jquery.treetable.js"></script>
+</head>
+
+<body class="layui-layout-body">
+
+<!--定义部分地址方便JS调用-->
+<div style="display: none">
+	<span id="controller" data-controller="{C}"></span>
+	<span id="url" data-url="{URL}"></span>
+	<span id="preurl" data-preurl="{fun=url('/admin',false)}"></span>
+	<span id="sitedir" data-sitedir="{SITE_DIR}"></span>
+	<span id="mcode" data-mcode="{$get.mcode}"></span>
+</div>
+
+<div class="layui-layout layui-layout-admin">
+  <div class="layui-header">
+    <div class="layui-logo">
+    <a href="{url./admin/Index/home}">
+    <img src="{APP_THEME_DIR}/images/logo.png" height="30">
+	    {CMSNAME} 
+	   	{if(LICENSE==3)}
+	   		<span class="layui-badge">SVIP</span>
+	   	{else}
+	   		<span class="layui-badge layui-bg-gray">V{APP_VERSION}</span>	
+	   	{/if}
+    </a>
+    </div>
+    
+    <ul class="menu">
+    	<li class="menu-ico" title="显示或隐藏侧边栏"><i class="fa fa-bars" aria-hidden="true"></i></li>
+	</ul>
+	{if(![$one_area])}
+	<form method="post" action="{url./admin/Index/area}" class="area-select">
+		<input type="hidden" name="formcheck" value="{$formcheck}" > 
+		<div class="layui-col-xs8">
+		   <select name="acode">
+		       {$area_html}
+		   </select>
+		</div>
+		<div class="layui-col-xs4">
+		 	<button type="submit" class="layui-btn layui-btn-sm">切换</button>
+		</div>
+   	</form>
+ 	{/if}
+
+    <ul class="layui-nav layui-layout-right">
+    
+       <li class="layui-nav-item layui-hide-xs">
+      	 <a href="{SITE_DIR}/" target="_blank"><i class="fa fa-home" aria-hidden="true"></i> 网站主页</a>
+       </li>
+
+       <li class="layui-nav-item layui-hide-xs">
+       		<a href="{url./admin/DeleCache/index}"><i class="fa fa-trash-o" aria-hidden="true"></i> 清理缓存</a>
+       </li>
+
+       <li class="layui-nav-item layui-hide-xs">
+	        <a href="javascript:;">
+	          <i class="fa fa-user-circle-o" aria-hidden="true"></i> {$session.realname}
+	        </a>
+	        <dl class="layui-nav-child">
+	          <dd><a href="{url./admin/Index/ucenter}"><i class="fa fa-address-card-o" aria-hidden="true"></i> 密码修改</a></dd>
+	          <dd><a href="{url./admin/Index/loginOut}"><i class="fa fa-sign-out" aria-hidden="true"></i> 退出登录</a></dd>
+	          {if(session('ucode')==10001)}
+	          	<dd><a href="{url./admin/Upgrade/index}"><i class="fa fa-cloud-upload" aria-hidden="true"></i> 在线更新</a></dd>
+	          	<dd><a href="{url./admin/Index/clearSession}" class="ajaxlink"><i class="fa fa-trash-o" aria-hidden="true"></i> 清理会话</a></dd>
+	          {/if}
+	        </dl>
+      </li>
+    </ul>
+  </div>
+  
+  <div class="layui-side layui-bg-black">
+    <div class="layui-side-scroll">
+      <!-- 左侧导航区域(可配合layui已有的垂直导航) -->
+      <ul class="layui-nav layui-nav-tree" id="nav" lay-shrink="all">
+	   {foreach $menu_tree(key,value)}
+        <li class="layui-nav-item nav-item {if([$primary_menu_url]==$value->url)}layui-nav-itemed{/if}">
+          <a class="" href="javascript:;"><i class="fa [value->ico]" aria-hidden="true"></i>[value->name]</a>
+          <dl class="layui-nav-child">
+			{if($value->mcode=='M130')}
+				 {foreach $menu_models(key3,value3,num3)}
+				 	{if($value3->type==1)}
+						<dd><a href="{url./admin/Single/index/mcode/'.$value3->mcode.'}"><i class="fa fa-file-text-o" aria-hidden="true"></i>[value3->name]内容</a></dd>
+					{/if}
+					{if($value3->type==2)}
+						<dd><a href="{url./admin/Content/index/mcode/'.$value3->mcode.'}"><i class="fa fa-file-text-o" aria-hidden="true"></i>[value3->name]内容</a></dd>
+					{/if}
+				 {/foreach}
+			{else}
+				{foreach $value->son(key2,value2,num2)}
+					{if(!isset($value2->status)|| $value2->status==1)}
+	            		<dd><a href="{url.'.$value2->url.'}"><i class="fa [value2->ico]" aria-hidden="true"></i>[value2->name]</a></dd>
+	            	{/if}
+				{/foreach}
+				
+				{if($value->mcode=='M101' && session('ucode')==10001)}
+					<dd><a href="{url./admin/Upgrade/index}"><i class="fa fa-cloud-upload" aria-hidden="true"></i>在线更新</a></dd>
+				{/if}
+		    {/if}
+          </dl>
+        </li>
+		{/foreach}
+		
+		<li style="height:1px;background:#666" class="layui-hide-sm"></li>
+		
+		<li class="layui-nav-item layui-hide-sm">
+		 <a href="{SITE_DIR}/" target="_blank"><i class="fa fa-home" aria-hidden="true"></i> 网站主页</a>
+		</li>
+		
+		<li class="layui-nav-item layui-hide-sm">
+          <a href="{url./admin/Index/ucenter}"><i class="fa fa-address-card-o" aria-hidden="true"></i> 资料修改</a>
+        </li>
+        
+        <li class="layui-nav-item layui-hide-sm">
+         <a href="{url./admin/DeleCache/index}"><i class="fa fa-trash-o" aria-hidden="true"></i> 清理缓存</a>
+        </li>
+        
+        <li class="layui-nav-item layui-hide-sm">
+         <a href="{url./admin/Index/loginOut}"><i class="fa fa-sign-out" aria-hidden="true"></i> 退出登录</a>
+        </li>
+
+      </ul>
+    </div>
+  </div>

+ 36 - 0
apps/admin/view/default/common/ueditor.html

@@ -0,0 +1,36 @@
+<!-- 引入编辑器文件 -->
+<script type="text/javascript" charset="utf-8" src="{CORE_DIR}/extend/ueditor/ueditor.config.js"></script>
+<script type="text/javascript" charset="utf-8" src="{CORE_DIR}/extend/ueditor/ueditor.all.js"> </script>
+<script type="text/javascript" charset="utf-8" src="{CORE_DIR}/extend/ueditor/lang/zh-cn/zh-cn.js"></script>
+<script>
+//初始化编辑器
+$(document).ready(function (e) {
+	var ue = UE.getEditor('editor',{
+		maximumWords:30000 
+	});
+})
+</script>
+
+
+<script type="text/javascript">
+   <!-- 解决源码模式无法保存 -->
+  function editor_init() {
+      $('#edit').submit(function () {
+          editor=UE.getEditor('editor');
+          if(editor.queryCommandState('source')==1) editor.execCommand('source');
+      })
+  }
+ 
+  <!-- 点击后添加到编辑器 -->
+  $(".addedit").on("click",'img',function(){
+	    editor=UE.getEditor('editor');
+		$img = $(this).attr("src");
+		editor.execCommand('inserthtml',"<img src='"+$img+"'>");
+   });
+
+</script>
+
+<script type="text/javascript">editor_init();</script>
+
+
+

+ 122 - 0
apps/admin/view/default/content/company.html

@@ -0,0 +1,122 @@
+{include file='common/head.html'}
+
+<div class="layui-body">
+
+  <div class="layui-tab layui-tab-brief" lay-filter="tab">
+    <ul class="layui-tab-title">
+      <li class="layui-this">公司信息</li>
+    </ul>
+    <div class="layui-tab-content">
+      <div class="layui-tab-item layui-show">
+        <form action="{url./admin/Company/mod}" method="post">
+          <input type="hidden" name="formcheck" value="{$formcheck}">
+          <div class="layui-form-item">
+            <label class="layui-form-label">公司名称</label>
+            <div class="layui-input-block">
+              <input type="text" name="name" value="{$companys->name}" placeholder="请输入公司名称" class="layui-input">
+            </div>
+          </div>
+
+          <div class="layui-form-item">
+            <label class="layui-form-label">公司地址</label>
+            <div class="layui-input-block">
+              <input type="text" name="address" value="{$companys->address}" placeholder="请输入公司地址" class="layui-input">
+            </div>
+          </div>
+
+          <div class="layui-form-item">
+            <label class="layui-form-label">邮政编码</label>
+            <div class="layui-input-block">
+              <input type="text" name="postcode" value="{$companys->postcode}" placeholder="请输入邮政编码"
+                class="layui-input">
+            </div>
+          </div>
+
+          <div class="layui-form-item">
+            <label class="layui-form-label">联系人</label>
+            <div class="layui-input-block">
+              <input type="text" name="contact" value="{$companys->contact}" placeholder="请输入联系人" class="layui-input">
+            </div>
+          </div>
+
+          <div class="layui-form-item">
+            <label class="layui-form-label">手机号码</label>
+            <div class="layui-input-block">
+              <input type="text" name="mobile" value="{$companys->mobile}" placeholder="请输入手机号码" class="layui-input">
+            </div>
+          </div>
+
+          <div class="layui-form-item">
+            <label class="layui-form-label">电话号码</label>
+            <div class="layui-input-block">
+              <input type="text" name="phone" value="{$companys->phone}" placeholder="请输入电话号码" class="layui-input">
+            </div>
+          </div>
+
+          <!-- <div class="layui-form-item">
+            <label class="layui-form-label">传真号码</label>
+            <div class="layui-input-block">
+              <input type="text" name="fax" value="{$companys->fax}" placeholder="请输入传真号码" class="layui-input">
+            </div>
+          </div> -->
+
+          <div class="layui-form-item">
+            <label class="layui-form-label">电子邮箱</label>
+            <div class="layui-input-block">
+              <input type="text" name="email" value="{$companys->email}" placeholder="请输入电子邮箱" class="layui-input">
+            </div>
+          </div>
+
+          <div class="layui-form-item">
+            <label class="layui-form-label">QQ号码</label>
+            <div class="layui-input-block">
+              <input type="text" name="qq" value="{$companys->qq}" placeholder="请输入QQ号码" class="layui-input">
+            </div>
+          </div>
+
+          <div class="layui-form-item">
+            <label class="layui-form-label">微信图标</label>
+            <div class="layui-input-inline">
+              <input type="text" name="weixin" id="weixin" value="{$companys->weixin}" placeholder="请上传微信图标"
+                class="layui-input">
+            </div>
+            <button type="button" class="layui-btn upload" data-des="weixin">
+              <i class="layui-icon">&#xe67c;</i>上传图片
+            </button>
+            <div id="weixin_box" class="pic">
+              <dl>
+                <dt>{if(@[$companys->weixin])}<img src="{SITE_DIR}{$companys->weixin}" data-url="{$companys->weixin}">
+                </dt>
+                <dd>删除</dd>
+              </dl>{/if}
+            </div>
+          </div>
+
+          <div class="layui-form-item">
+            <label class="layui-form-label">营业执照代码</label>
+            <div class="layui-input-block">
+              <input type="text" name="blicense" value="{$companys->blicense}" placeholder="请输入营业执照代码"
+                class="layui-input">
+            </div>
+          </div>
+
+          <div class="layui-form-item">
+            <label class="layui-form-label">其它信息</label>
+            <div class="layui-input-block">
+              <input type="text" name="other" value="{$companys->other}" placeholder="请输入其它信息" class="layui-input">
+            </div>
+          </div>
+
+          <div class="layui-form-item">
+            <div class="layui-input-block">
+              <button class="layui-btn" lay-submit>立即提交</button>
+              <button type="reset" class="layui-btn layui-btn-primary">重置</button>
+            </div>
+          </div>
+        </form>
+      </div>
+    </div>
+  </div>
+</div>
+
+{include file='common/foot.html'}

+ 952 - 0
apps/admin/view/default/content/content.html

@@ -0,0 +1,952 @@
+{include file='common/head.html'}
+
+<div class="layui-body">
+	{if([$list])}
+	<div class="layui-tab layui-tab-brief" lay-filter="tab">
+	  <ul class="layui-tab-title">
+	    <li class="layui-this" lay-id="t1">{$model_name}内容</li>
+	    <li lay-id="t2">{$model_name}新增</li>
+	  </ul>
+	  <div class="layui-tab-content">
+	  	   <div class="layui-tab-item layui-show">
+	  	   		<form action="{url./admin/Content/index/mcode/'.get('mcode').'}" method="get" class="layui-form">
+		  	   		<div class="layui-form-item nospace">
+		  	   			<div class="layui-input-inline">
+		  	   				{$pathinfo}
+					       <select name="scode">
+	                          	<option value="">全部栏目</option>
+                                {$search_select}
+	                       </select>
+					    </div>
+	                     <div class="layui-input-inline">
+	                     	<input type="text" name="keyword"  value="{$get.keyword}"  placeholder="请输入搜索关键字" class="layui-input">
+	                     </div>
+	                     <div class="layui-input-inline">
+	                     	<button class="layui-btn" lay-submit>搜索</button>
+	                     	<a class="layui-btn layui-btn-primary"  href="{url./admin/Content/index/mcode/'.get('mcode').'}">清除搜索</a>
+	                     </div>
+	                </div>
+	                
+	               
+                </form>
+                
+	  	   		<form action="{url./admin/Content/mod}" method="post" id="contentForm" name="contentForm" class="layui-form" onkeydown="if(event.keyCode==13) return false;">
+		            <input type="hidden" name="formcheck" value="{$formcheck}" > 
+		            <table class="layui-table">
+		            	<thead>
+		                    <tr>
+		                    	<th><input type="checkbox" class="checkbox" lay-ignore id="checkall" title="全选"></th>
+		                    	<th>ID</th>
+		                        <th>栏目</th>
+		                        <th>标题</th>
+		                        <th>发布时间</th>
+		                        <th>排序</th>
+		                        <th>状态</th>
+		                        <th>置顶</th>
+		                        <th>推荐</th>
+		                        <th>访问量</th>
+		                        <th>操作</th>
+		                    </tr>
+		                </thead>
+		                <tbody>
+		                    {foreach $contents(key,value)}
+		                    <tr>
+		                    	<td>
+		                    		<input type="checkbox" class="checkbox checkitem" lay-ignore name="list[]" {if($value->outlink)}disabled{/if} value="[value->id]">
+		                    		<input type="hidden" name="listall[]" value="[value->id]">
+		                    	</td>
+		                    	<td>[value->id]</td>
+		                        <td title="[value->scode]">[value->sortname]</td>
+		                        <td title="[value->title]">
+		                        {fun=substr_both($value->title,0,15)}
+		                        {if($value->isheadline)}
+		                        	<span class="layui-badge layui-bg-blue">头</span>
+		                        {/if}
+		                        {if($value->ico)}
+		                        	<span class="layui-badge layui-bg-orange">缩</span>
+		                        {/if}
+		                        {if($value->pics)}
+		                        	<span class="layui-badge">图</span>
+		                        {/if}
+		                        {if($value->outlink)}
+	                            	<span class="layui-badge layui-bg-black">链</span>
+	                            {/if}
+		                        </td>
+		                        <td>[value->date]</td>
+		                        <td class="table-input"><input type="text" lay-ignore class="layui-input" name="sorting[]" value="[value->sorting]"></td>
+		                        <td>
+		                        {if($value->status)}
+			                        <a href="{url./admin/'.C.'/mod/id/'.$value->id.'/field/status/value/0}" class="switch"><i class='fa fa-toggle-on' title="点击关闭"></i></a>
+			                        {else}
+			                        <a href="{url./admin/'.C.'/mod/id/'.$value->id.'/field/status/value/1}" class="switch"><i class='fa fa-toggle-off' title="点击开启"></i></a>
+			                    {/if}
+			                    </td>
+			                    <td>
+		                        {if($value->istop)}
+			                        <a href="{url./admin/'.C.'/mod/id/'.$value->id.'/field/istop/value/0}" class="switch"><i class='fa fa-toggle-on' title="点击关闭"></i></a>
+			                        {else}
+			                        <a href="{url./admin/'.C.'/mod/id/'.$value->id.'/field/istop/value/1}" class="switch"><i class='fa fa-toggle-off' title="点击开启"></i></a>
+			                    {/if}
+			                    </td>
+			                    <td>
+		                        {if($value->isrecommend)}
+			                        <a href="{url./admin/'.C.'/mod/id/'.$value->id.'/field/isrecommend/value/0}" class="switch"><i class='fa fa-toggle-on' title="点击关闭"></i></a>
+			                        {else}
+			                        <a href="{url./admin/'.C.'/mod/id/'.$value->id.'/field/isrecommend/value/1}" class="switch"><i class='fa fa-toggle-off' title="点击开启"></i></a>
+			                    {/if}
+			                    </td>
+			                    <td>[value->visits]</td>
+		                        <td>
+		                         	{if(!$value->outlink)}
+			                        	{php}
+			                        		$Parser=new app\home\controller\ParserController();
+			                        		$link=$Parser->parserLink(2,$value->urlname,'content',$value->scode,$value->sortfilename,$value->id,$value->filename);
+			                        	{/php}
+	
+			                        	<input type="hidden" name="urls[[value->id]]" value="{php}echo $link{/php}">
+			                        	<a href="{php}echo $link{/php}" class="layui-btn layui-btn-xs layui-btn-primary"  target="_blank">查看</a>
+		                        	{/if}
+		                            {fun=get_btn_del($value->id)}
+		                            {if(check_level('mod'))}
+		                            	<a href="{url./admin/Content/mod/mcode/'.get('mcode').'/id/'.$value->id.'}{$btnqs}" class="layui-btn layui-btn-xs" >修改</a>
+		                            {/if}
+		                        </td>
+		                    </tr>
+		                    {/foreach}
+		                </tbody>
+		            </table>
+			       
+			        
+			        <div class="layui-inline" style="float:right">
+			     		<select lay-filter="tourl" class="page-select" >
+							<option value="" selected="">每页显示数量</option>
+							<option value="{url./admin/Content/index/mcode/'.get('mcode').'/pagesize/20}" {if(get('pagesize')==20)}selected{/if}>20条/页</option>
+							<option value="{url./admin/Content/index/mcode/'.get('mcode').'/pagesize/30}" {if(get('pagesize')==30)}selected{/if}>30条/页</option>
+							<option value="{url./admin/Content/index/mcode/'.get('mcode').'/pagesize/50}" {if(get('pagesize')==50)}selected{/if}>50条/页</option>
+							<option value="{url./admin/Content/index/mcode/'.get('mcode').'/pagesize/60}" {if(get('pagesize')==60)}selected{/if}>60条/页</option>
+							<option value="{url./admin/Content/index/mcode/'.get('mcode').'/pagesize/100}" {if(get('pagesize')==100)}selected{/if}>100条/页</option>
+							<option value="{url./admin/Content/index/mcode/'.get('mcode').'/pagesize/150}" {if(get('pagesize')==150)}selected{/if}>150条/页</option>
+							<option value="{url./admin/Content/index/mcode/'.get('mcode').'/pagesize/200}" {if(get('pagesize')==200)}selected{/if}>200条/页</option>
+						</select>
+					</div>
+						
+			        <div class="layui-input-inline">
+				     	 <select name="scode">
+	                        	<option value="">请选择移动/复制到栏目</option>
+	                             {$search_select}
+	                     </select>
+                    </div>
+                    
+                    <div class="layui-btn-group">
+	                    {if(check_level('mod'))}
+	                    	<button type="submit" name="submit" value="copy" class="layui-btn layui-btn-sm">复制</button>
+	                    	<button type="submit" name="submit" value="move" class="layui-btn layui-btn-sm">移动</button>
+	                    {/if}
+	                    
+	                    {if(check_level('del'))}
+				     		<button type="submit" name="submit" onclick="return setDelAction();" class="layui-btn layui-btn-sm">批量删除</button>
+				     	{/if}
+				     	
+				     	{if(check_level('mod'))}
+				     		<button type="submit" name="submit" value="sorting" class="layui-btn layui-btn-sm">保存排序</button>
+					     	{if([$baidu_zz_token])}
+					     		<button type="submit" name="submit" value="baiduzz" class="layui-btn layui-btn-sm">百度普通推送</button>
+					     	{/if}
+					     	{if([$baidu_ks_token])}
+					     		<button type="submit" name="submit" value="baiduks" class="layui-btn layui-btn-sm">百度快速推送</button>
+					     	{/if}
+				     	 {/if}
+			     	 </div>
+			     	<script>
+			     		function setDelAction(){
+			     			document.contentForm.action = "{url./admin/Content/del}"; 
+			     			return confirm("您确定要删除选中的内容么?");
+			     		}
+			     	</script>
+			     	
+			     	<div class="page">
+			     		{$pagebar}
+			     		
+			     	</div>
+			      </form> 
+	  	   </div>
+	  	   
+	  	   <div class="layui-tab-item">
+	  	  		<form action="{url./admin/Content/add/mcode/'.get('mcode').'}" method="post" class="layui-form" lay-filter="content" id="edit">
+		  	     	<input type="hidden" name="formcheck" value="{$formcheck}" > 
+		  	     	<div class="layui-tab">
+					  <ul class="layui-tab-title">
+					    <li class="layui-this">基本内容</li>
+					    <li>高级内容</li>
+					  </ul>
+					  <div class="layui-tab-content">
+					    <div class="layui-tab-item layui-show">
+					    	<div class="layui-form-item">
+			                     <label class="layui-form-label">内容栏目   <span class="layui-text-red">*</span></label>
+			                     <div class="layui-input-block">
+			                     	<select name="scode" lay-verify="required">
+				                        <option value="">请选择内容栏目</option>
+			                        	{$sort_select}
+				                    </select>
+			                     </div>
+			                </div>
+			                
+			                <div class="layui-form-item">
+			                     <label class="layui-form-label">内容标题   <span class="layui-text-red">*</span></label>
+			                     <div class="layui-input-block">
+			                     	<input type="text" name="title" required lay-verify="required" placeholder="请输入内容标题" class="layui-input">
+			                     </div>
+			                </div>
+			                
+			                 {foreach $extfield(key,value)}
+			                	{if($value->type==1)} <!-- 单行文本 -->
+			                	<div class="layui-form-item">
+			                		<label class="layui-form-label">[value->description]</label>
+			                		<div class="layui-input-block">
+				                    	<input type="text" name="[value->name]"  placeholder="请输入[value->description]"  class="layui-input">
+				                	</div>
+				                </div>
+			                	{/if}
+			                	
+			                	{if($value->type==2)}<!-- 多行文本 -->
+			                	<div class="layui-form-item">
+			                		<label class="layui-form-label">[value->description]</label>
+			                		<div class="layui-input-block">
+				                		<textarea name="[value->name]" class="layui-textarea" placeholder="请输入[value->description]"></textarea>
+				                	</div>
+				                </div>
+			                	{/if}
+			                	
+			                    {if($value->type==3)}<!-- 单选 -->
+			                	<div class="layui-form-item">
+			                		<label class="layui-form-label">[value->description]</label>
+			                		<div class="layui-input-block">
+				                		<div>
+				                			{php}
+				                				$radios=explode(',',$value->value);
+				                				foreach ($radios as $value2) {
+	                								echo '<input type="radio" name="'.$value->name.'" value="'.$value2.'" title="'.$value2.'">';
+	            								}
+	            						     {/php}
+					                    </div>
+				                	</div>
+				                </div>
+			                	{/if}
+			                	
+			                    {if($value->type==4)}<!-- 多选 -->
+			                	<div class="layui-form-item">
+			                		<label class="layui-form-label">[value->description]</label>
+			                		<div class="layui-input-block">
+				                		<div>
+				                			{php}
+				                				$checkboxs=explode(',',$value->value);
+				                				foreach ($checkboxs as $value2) {
+	            									echo '<input type="checkbox" name="'.$value->name.'[]" value="'.$value2.'" title="'.$value2.'">';
+	            								}
+	            						     {/php}
+					                    </div>
+				                	</div>
+				                </div>
+			                	{/if}
+			                	
+			                	{if($value->type==5)}<!-- 图片 -->
+			                	<div class="layui-form-item">
+			                		<label class="layui-form-label">[value->description]</label>
+			                		<div class="layui-input-inline">
+				                     	<input type="text" name="[value->name]" id="[value->name]" placeholder="请上传[value->description]"  class="layui-input">
+				                     </div>
+				                     <button type="button" class="layui-btn upload watermark" data-des="[value->name]">
+									 	 <i class="layui-icon">&#xe67c;</i>上传图片
+									 </button>
+									 <div id="[value->name]_box" class="pic"></div>
+				                </div>
+			                	{/if}
+			                	
+			                	{if($value->type==10)}<!-- 多图片 -->
+			                	 <div class="layui-form-item">
+				                     <label class="layui-form-label">[value->description]</label>
+				                     <div class="layui-input-inline">
+				                     	<input type="text" name="[value->name]" id="[value->name]" placeholder="请上传[value->description]"  class="layui-input">
+				                     </div>
+				                     <button type="button" class="layui-btn uploads watermark" data-des="[value->name]">
+									 	 <i class="layui-icon">&#xe67c;</i>上传多图
+									 </button>
+									 <div id="[value->name]_box" class="pic addedit"><dl></dl> <!-- 规避空内容拖动bug --></div>
+				                </div>
+				                {/if}
+			                	
+			                	{if($value->type==6)}<!-- 文件 -->
+			                	<div class="layui-form-item">
+			                		<label class="layui-form-label">[value->description]</label>
+			                		<div class="layui-input-inline">
+				                     	<input type="text" name="[value->name]" id="[value->name]" placeholder="请上传[value->description]"  class="layui-input">
+				                     </div>
+				                     <button type="button" class="layui-btn file" data-des="[value->name]">
+									 	 <i class="layui-icon">&#xe67c;</i>上传文件
+									 </button>
+				                </div>
+			                	{/if}
+			                	
+			                	{if($value->type==7)}<!-- 日期 -->
+				                <div class="layui-form-item">
+				                     <label class="layui-form-label">[value->description]</label>
+				                     <div class="layui-input-block">
+				                     	<input type="text" name="[value->name]" readonly placeholder="请选择[value->description]"  class="layui-input datetime">
+				                     </div>
+				                </div>
+			                	{/if}
+			                	
+			                	{if($value->type==8)}<!-- 编辑器 -->
+			                	<div class="layui-form-item">
+			                		<label class="layui-form-label">[value->description]</label>
+			                		<div class="layui-input-block">
+				                		<script type="text/plain" id="editor_[value->name]" name="[value->name]" style="width:100%;height:240px;"></script>
+				                		<script>
+											//初始化编辑器
+											$(document).ready(function (e) {
+												var ue = UE.getEditor('editor_[value->name]',{
+													maximumWords:10000 
+												});
+											})
+										</script>
+				                	</div>
+				                </div>
+			                	{/if}
+			                	
+			                	{if($value->type==9)}<!-- 下拉 -->
+			                	<div class="layui-form-item">
+			                		<label class="layui-form-label">[value->description]</label>
+			                		<div class="layui-input-block">
+			                			<select name="[value->name]">
+			                				{php}
+				                				$selects=explode(',',$value->value);
+				                				foreach ($selects as $value2) {
+	                								echo '<option value="'.$value2.'">'.$value2.'</option>';
+	            								}
+	            						     {/php}
+			                			</select>
+				                	</div>
+				                 </div>
+			                	 {/if}
+			                	
+			                {/foreach}
+			                
+			                <div class="layui-form-item">
+			                     <label class="layui-form-label">内容</label>
+			                     <div class="layui-input-block">
+			                     	<script type="text/plain" id="editor" name="content" style="width:100%;height:240px;"></script>
+			                     </div>
+			                </div>
+			                
+			                <div class="layui-form-item">
+			                     <label class="layui-form-label">tags</label>
+			                     <div class="layui-input-block">
+			                     	<input type="text" name="tags" placeholder="请输入文章tag,英文逗号隔开" class="layui-input">
+			                     </div>
+			                </div>
+			                
+			                <div class="layui-form-item">
+			                     <label class="layui-form-label">作者</label>
+			                     <div class="layui-input-block">
+			                     	<input type="text" name="author" placeholder="请输入作者" value="{$session.realname}" class="layui-input">
+			                     </div>
+			                </div>
+			                
+			                <div class="layui-form-item">
+			                     <label class="layui-form-label">来源</label>
+			                     <div class="layui-input-block">
+			                     	<input type="text" name="source" placeholder="请输入来源" value="本站" class="layui-input">
+			                     </div>
+			                </div>
+			                
+			                <div class="layui-form-item">
+			                     <label class="layui-form-label">缩略图</label>
+			                     <div class="layui-input-inline">
+			                     	<input type="text" name="ico" id="ico" placeholder="请上传缩略图"  class="layui-input">
+			                     </div>
+			                     <button type="button" class="layui-btn upload watermark" data-des="ico">
+								 	 <i class="layui-icon">&#xe67c;</i>上传图片
+								 </button>
+								 <div id="ico_box" class="pic addedit"></div>
+			                </div>
+			                
+			                <div class="layui-form-item">
+			                     <label class="layui-form-label">轮播多图</label>
+			                     <div class="layui-input-inline">
+			                     	<input type="text" name="pics" id="pics" placeholder="请上传轮播多图"  class="layui-input">
+			                     </div>
+			                     <button type="button" class="layui-btn uploads watermark" data-des="pics">
+								 	 <i class="layui-icon">&#xe67c;</i>上传多图
+								 </button>
+								 <div id="pics_box" class="pic addedit"><dl></dl> <!-- 规避空内容拖动bug --></div>
+			                </div>
+			                
+			                <div class="layui-form-item">
+			                     <label class="layui-form-label">参数</label>
+			                     <div class="layui-input-block">
+									<input type="checkbox" name="istop" value="1" title="置顶">
+			                    	<input type="checkbox" name="isrecommend" value="1" title="推荐">
+			                    	<input type="checkbox" name="isheadline" value="1" title="头条">
+			                     </div>
+			                </div>
+			                
+			                <div class="layui-form-item">
+			                     <label class="layui-form-label">浏览权限</label>
+			                     <div class="layui-input-block">
+									<select name="gid">
+										<option value="">不限制</option>
+				                        {foreach $groups(key,value)}
+				                            <option value="[value->id]">[value->gname]</option>
+				                        {/foreach}
+				                    </select>
+			                     </div>
+			                </div>  
+			                
+			                <div class="layui-form-item">
+			                     <label class="layui-form-label">权限类型</label>
+			                     <div class="layui-input-block">
+			                     	<select name="gtype" id="gtype" >
+			                     		<option value="1">小于</option>
+			                     		<option value="2">小于等于</option>
+			                     		<option value="3">等于</option>
+			                     		<option value="4" selected>大于等于</option>
+			                     		<option value="5">大于</option>
+									</select>
+			                     </div>
+			                </div>  
+					    </div>
+					    
+					    <div class="layui-tab-item ">
+					    	<div class="layui-form-item">
+			                     <label class="layui-form-label">内容副栏目</label>
+			                     <div class="layui-input-block">
+			                     	<select name="subscode">
+				                        <option value="">请选择内容副栏目</option>
+			                        	{$subsort_select}
+				                    </select>
+			                     </div>
+			                </div>
+			                
+					   		 <div class="layui-form-item">
+			                     <label class="layui-form-label">标题颜色</label>
+			                     <div class="layui-input-inline">
+			                     	<input type="text" name="titlecolor" placeholder="请选择标题颜色" value="#333333" class="layui-input jscolor {hash:true}">
+			                     </div>
+			                 </div>
+			                 
+			                 <div class="layui-form-item">
+			                     <label class="layui-form-label">副标题</label>
+			                     <div class="layui-input-block">
+			                     	<input type="text" name="subtitle" placeholder="请输入副标题" class="layui-input">
+			                     </div>
+			                 </div>
+			                 
+			                 <div class="layui-form-item">
+			                     <label class="layui-form-label">URL名称</label>
+			                     <div class="layui-input-block">
+			                     	<input type="text" name="filename" placeholder="请输入URL名称,如:test,test/a/b" class="layui-input">
+			                     </div>
+			                 </div>
+			                 
+			                  <div class="layui-form-item">
+			                     <label class="layui-form-label">跳转外链接</label>
+			                     <div class="layui-input-block">
+			                     	<input type="text" name="outlink" placeholder="请输入跳转外链接" class="layui-input">
+			                     </div>
+			                 </div>
+			                 
+			                <div class="layui-form-item">
+			                     <label class="layui-form-label">权限不足提示</label>
+			                     <div class="layui-input-block">
+			                     	<input type="text" name="gnote" placeholder="请输入权限不足时提示文本"  class="layui-input">
+			                     </div>
+			                </div>
+			                 
+			                 <div class="layui-form-item">
+			                     <label class="layui-form-label">发布时间</label>
+			                     <div class="layui-input-inline">
+			                     	<input type="text" name="date" value="{fun=date('Y-m-d H:i:s')}" readonly placeholder="请选择发布时间"  class="layui-input datetime">
+			                     </div>
+			                     <div class="layui-form-mid layui-word-aux">温馨提示:设置未来时间可定时发布!</div>
+			                </div>
+			                
+			                <div class="layui-form-item">
+		                		<label class="layui-form-label">附件</label>
+		                		<div class="layui-input-inline">
+			                     	<input type="text" name="enclosure" id="enclosure" placeholder="请上传附件"  class="layui-input">
+			                     </div>
+			                     <button type="button" class="layui-btn file" data-des="enclosure">
+								 	 <i class="layui-icon">&#xe67c;</i>上传附件
+								 </button>
+			                </div>
+			                
+			                <div class="layui-form-item">
+			                     <label class="layui-form-label">SEO关键字</label>
+			                     <div class="layui-input-block">
+			                     	<input type="text" name="keywords" placeholder="请输入详情页SEO关键字" class="layui-input">
+			                     </div>
+			                </div>
+			                
+			                <div class="layui-form-item">
+			                     <label class="layui-form-label">SEO描述</label>
+			                     <div class="layui-input-block">
+			                     	<textarea name="description" placeholder="请输入详情页SEO描述" class="layui-textarea"></textarea>
+			                     </div>
+			                </div>
+			                
+			                <div class="layui-form-item">
+			                     <label class="layui-form-label">状态</label>
+			                     <div class="layui-input-block">
+			                     	<input type="radio" name="status" value="1" title="显示" checked>
+									<input type="radio" name="status" value="0" title="隐藏">
+			                     </div>
+			                </div>
+					    </div>
+					  </div>
+					</div>
+					<div class="layui-form-item">
+						 <div class="layui-input-block">
+						    <button class="layui-btn" lay-submit>立即提交</button>
+						    <button type="reset" class="layui-btn layui-btn-primary">重置</button>
+						 </div>
+					</div>
+			   </form>
+	  	   </div>
+	  </div>
+	 </div>
+	{/if} 
+	
+	{if([$mod])}
+	
+	<div class="layui-tab layui-tab-brief" lay-filter="tab">
+	  <ul class="layui-tab-title">
+	    <li class="layui-this">{$model_name}内容修改</li>
+	  </ul>
+	  <div class="layui-tab-content">
+	  	<div class="layui-tab-item layui-show">
+	  		<form action="{url./admin/Content/mod/id/'.[$get.id].'}{$backurl}" method="post" class="layui-form" id="edit">
+	  			<input type="hidden" name="formcheck" value="{$formcheck}" > 
+	  			<div class="layui-tab">
+					  <ul class="layui-tab-title">
+					    <li class="layui-this">基本内容</li>
+					    <li>高级内容</li>
+					  </ul>
+					  <div class="layui-tab-content">
+					    <div class="layui-tab-item layui-show">
+					    	<div class="layui-form-item">
+			                     <label class="layui-form-label">内容栏目   <span class="layui-text-red">*</span></label>
+			                     <div class="layui-input-block">
+			                     	<select name="scode" lay-verify="required">
+				                        <option value="">请选择内容栏目</option>
+			                        	{$sort_select}
+				                    </select>
+			                     </div>
+			                </div>
+			                
+			                <div class="layui-form-item">
+			                     <label class="layui-form-label">内容标题   <span class="layui-text-red">*</span></label>
+			                     <div class="layui-input-block">
+			                     	<input type="text" name="title" required lay-verify="required" value="{$content->title}" placeholder="请输入内容标题" class="layui-input">
+			                     </div>
+			                </div>
+			                
+			                 {foreach $extfield(key,value)}
+			                	{if($value->type==1)} <!-- 单行文本 -->
+			                	<div class="layui-form-item">
+			                		<label class="layui-form-label">[value->description]</label>
+			                		<div class="layui-input-block">
+				                    	<input type="text" name="[value->name]" value="{$content->{$value->name}}"  placeholder="请输入[value->description]"  class="layui-input">
+				                	</div>
+				                </div>
+			                	{/if}
+			                	
+			                	{if($value->type==2)}<!-- 多行文本 -->
+			                	<div class="layui-form-item">
+			                		<label class="layui-form-label">[value->description]</label>
+			                		<div class="layui-input-block">
+				                		<textarea name="[value->name]" class="layui-textarea" placeholder="请输入[value->description]">{php}$name=$value->name;echo str_replace('<br>', "\r\n",$this->vars['content']->$name);{/php}</textarea>
+				                	</div>
+				                </div>
+			                	{/if}
+			                	
+			                    {if($value->type==3)}<!-- 单选 -->
+			                	<div class="layui-form-item">
+			                		<label class="layui-form-label">[value->description]</label>
+			                		<div class="layui-input-block">
+				                		<div>
+	            						     {php}
+				                				$radios=explode(',',$value->value);
+				                				$name=$value->name;
+				                				foreach ($radios as $value2) {
+				                					if($this->vars['content']->$name==$value2){
+	                									echo '<input type="radio" name="'.$value->name.'" value="'.$value2.'" title="'.$value2.'" checked>';
+	                								}else{
+	                									echo '<input type="radio" name="'.$value->name.'" value="'.$value2.'" title="'.$value2.'">';
+	                								}
+	            								}
+	            						     {/php}
+					                    </div>
+				                	</div>
+				                </div>
+			                	{/if}
+			                	
+			                    {if($value->type==4)}<!-- 多选 -->
+			                	<div class="layui-form-item">
+			                		<label class="layui-form-label">[value->description]</label>
+			                		<div class="layui-input-block">
+				                		<div>
+				                			
+	            						     {php}
+				                				$checkboxs=explode(',',$value->value);
+				                				$name=$value->name;
+				                				echo '<input name="'.$value->name.'" type="hidden">';//占位清空
+				                				$values=explode(',',$this->vars['content']->$name);
+				                				foreach ($checkboxs as $value2) {
+				                					if(in_array($value2,$values)){
+	            										echo '<input type="checkbox" name="'.$value->name.'[]" value="'.$value2.'" title="'.$value2.'" checked>';
+	            									}else{
+	            										echo '<input type="checkbox" name="'.$value->name.'[]" value="'.$value2.'" title="'.$value2.'">';
+	            									}
+	            								}
+	            						     {/php}
+					                    </div>
+				                	</div>
+				                </div>
+			                	{/if}
+			                	
+			                	{if($value->type==5)}<!-- 图片 -->
+			                	<div class="layui-form-item">
+			                		<label class="layui-form-label">[value->description]</label>
+			                		<div class="layui-input-inline">
+				                     	<input type="text" name="[value->name]" id="[value->name]" value="{$content->{$value->name}}" placeholder="请上传[value->description]"  class="layui-input">
+				                     </div>
+				                     <button type="button" class="layui-btn upload watermark" data-des="[value->name]">
+									 	 <i class="layui-icon">&#xe67c;</i>上传图片
+									 </button>
+									 {php}$name=$value->name; {/php}
+									 <div id="[value->name]_box" class="pic"><dl><dt>{if([$content]->$name)}<img src='{SITE_DIR}{$content->{$value->name}}' data-url="{$content->{$value->name}}"></dt><dd>删除</dd></dl>{/if}</div>
+				                </div>
+			                	{/if}
+			                	
+			                	{if($value->type==10)}<!-- 多图 -->
+			                	 <div class="layui-form-item">
+				                     <label class="layui-form-label">[value->description]</label>
+				                     <div class="layui-input-inline">
+				                     	<input type="text" name="[value->name]" id="[value->name]" value="{$content->{$value->name}}" placeholder="请上传[value->description]"  class="layui-input">
+				                     </div>
+				                     <button type="button" class="layui-btn uploads watermark" data-des="[value->name]">
+									 	 <i class="layui-icon">&#xe67c;</i>上传多图
+									 </button>
+									 <div id="[value->name]_box" class="pic addedit">
+									 	 <dl></dl> <!-- 规避空内容拖动bug -->
+										 {php}
+										 	$name=$value->name;
+										    if([$content->$name]){
+			                					$pics=explode(',',[$content->$name]);
+			                				}else{
+			                					$pics = array();
+			                				}
+			                				foreach ($pics as $key=>$value) {
+			                					//需要留一个空,不然被解析为标签了
+			                					echo "<dl><dt><img src='".SITE_DIR.$value."' data-url='".$value."'></dt><dd>删除</dd></dl>";
+		          							}
+		         						 {/php}
+	         						 </div>
+				                </div>
+			                	
+			                	{/if}
+			                	
+			                	{if($value->type==6)}<!-- 文件 -->
+			                	<div class="layui-form-item">
+			                		<label class="layui-form-label">[value->description]</label>
+			                		<div class="layui-input-inline">
+				                     	<input type="text" name="[value->name]" id="[value->name]" value="{$content->{$value->name}}" placeholder="请上传[value->description]"  class="layui-input">
+				                     </div>
+				                     <button type="button" class="layui-btn file" data-des="[value->name]">
+									 	 <i class="layui-icon">&#xe67c;</i>上传文件
+									 </button>
+				                </div>
+			                	{/if}
+			                	
+			                	{if($value->type==7)}<!-- 日期 -->
+				                <div class="layui-form-item">
+				                     <label class="layui-form-label">[value->description]</label>
+				                     <div class="layui-input-block">
+				                     	<input type="text" name="[value->name]" value="{$content->{$value->name}}" readonly placeholder="请选择[value->description]"  class="layui-input datetime">
+				                     </div>
+				                </div>
+			                	{/if}
+			                	
+			                	{if($value->type==8)}<!-- 编辑器 -->
+			                	<div class="layui-form-item">
+			                		<label class="layui-form-label">[value->description]</label>
+			                		<div class="layui-input-block">
+			                			{php}
+			                				$name=@$value->name;
+			                			{/php}
+				                		<script type="text/plain" id="editor_[value->name]" name="[value->name]" style="width:100%;height:240px;">{fun=decode_string([$content->$name])}</script>
+				                		<script>
+											//初始化编辑器
+											$(document).ready(function (e) {
+												var ue = UE.getEditor('editor_[value->name]',{
+													maximumWords:10000 
+												});
+											})
+										</script>
+				                	</div>
+				                </div>
+			                	{/if}
+			                	
+			                	{if($value->type==9)}<!-- 下拉 -->
+			                	<div class="layui-form-item">
+			                		<label class="layui-form-label">[value->description]</label>
+			                		<div class="layui-input-block">
+			                			<select name="[value->name]">
+			                				{php}
+				                				$selects=explode(',',$value->value);
+				                				$name=$value->name;
+				                				foreach ($selects as $value2) {
+				                					if($this->vars['content']->$name==$value2){
+				                						echo '<option value="'.$value2.'" selected>'.$value2.'</option>';
+	                								}else{
+	                									echo '<option value="'.$value2.'">'.$value2.'</option>';
+	                								}
+	            								}
+	            						    {/php}
+			                			</select>
+				                	</div>
+				                 </div>
+			                	 {/if}
+			                	
+			                {/foreach}
+			                
+			                <div class="layui-form-item">
+			                     <label class="layui-form-label">内容</label>
+			                     <div class="layui-input-block">
+			                     	<script type="text/plain" id="editor" name="content" style="width:100%;height:240px;">{fun=decode_string([$content->content])}</script>
+			                     </div>
+			                </div>
+			                
+			                <div class="layui-form-item">
+			                     <label class="layui-form-label">tags</label>
+			                     <div class="layui-input-block">
+			                     	<input type="text" name="tags" placeholder="请输入文章tag,英文逗号隔开" value="{$content->tags}" class="layui-input">
+			                     </div>
+			                </div>
+			                
+			                <div class="layui-form-item">
+			                     <label class="layui-form-label">作者</label>
+			                     <div class="layui-input-block">
+			                     	<input type="text" name="author" placeholder="请输入作者" value="{$content->author}" class="layui-input">
+			                     </div>
+			                </div>
+			                
+			                <div class="layui-form-item">
+			                     <label class="layui-form-label">来源</label>
+			                     <div class="layui-input-block">
+			                     	<input type="text" name="source" placeholder="请输入来源" value="{$content->source}" class="layui-input">
+			                     </div>
+			                </div>
+			                
+			                <div class="layui-form-item">
+			                     <label class="layui-form-label">缩略图</label>
+			                     <div class="layui-input-inline">
+			                     	<input type="text" name="ico" id="ico" value="{$content->ico}" placeholder="请上传缩略图"  class="layui-input">
+			                     </div>
+			                     <button type="button" class="layui-btn upload watermark" data-des="ico">
+								 	 <i class="layui-icon">&#xe67c;</i>上传图片
+								 </button>
+								 <div id="ico_box" class="pic addedit">{if([$content->ico])}<dl><dt><img src="{SITE_DIR}{$content->ico}" data-url="{$content->ico}"></dt><dd>删除</dd></dl>{/if}</div>
+			                </div>
+			                
+			                <div class="layui-form-item">
+			                     <label class="layui-form-label">轮播多图</label>
+			                     <div class="layui-input-inline">
+			                     	<input type="text" name="pics" id="pics" value="{$content->pics}" placeholder="请上传轮播多图"  class="layui-input">
+			                     </div>
+			                     <button type="button" class="layui-btn uploads watermark" data-des="pics">
+								 	 <i class="layui-icon">&#xe67c;</i>上传多图
+								 </button>
+								 <div id="pics_box" class="pic addedit">
+								 	 <dl></dl> <!-- 规避空内容拖动bug -->
+									 {php}
+									    if([$content->pics]){
+		                					$pics=explode(',',[$content->pics]);
+		                				}else{
+		                					$pics = array();
+		                				}
+		                				if([$content->picstitle]){
+		                					$picstitle=explode(',',[$content->picstitle]);
+		                				}else{
+		                					$picstitle = array();
+		                				}
+		                				foreach ($pics as $key=>$value) {
+		                					//需要留一个空,不然被解析为标签了
+		                					echo "<dl><dt><img src='".SITE_DIR.$value."' data-url='".$value."'></dt><dd>删除</dd><dt><input type='text' value='".$picstitle[$key ]."' name='picstitle[]' style='width:95%' /></dt></dl>";
+	          							}
+	         						 {/php}
+         						 </div>
+			                </div>
+			                
+			                <div class="layui-form-item">
+			                     <label class="layui-form-label">状态</label>
+			                     <div class="layui-input-block">
+									<input type="checkbox" name="istop" value="1" title="置顶" {if([$content->istop]==1)}checked{/if}>
+			                    	<input type="checkbox" name="isrecommend" value="1" title="推荐" {if([$content->isrecommend]==1)}checked{/if}>
+			                    	<input type="checkbox" name="isheadline" value="1" title="头条" {if([$content->isheadline]==1)}checked{/if}>
+			                     </div>
+			                </div>
+			                
+			                 <div class="layui-form-item">
+			                     <label class="layui-form-label">浏览权限</label>
+			                     <div class="layui-input-block">
+									<select name="gid">
+										<option value="">不限制</option>
+				                        {foreach $groups(key,value)}
+				                            <option value="[value->id]" {if([$content->gid]==$value->id)}selected="selected"{/if}>[value->gname]</option>
+				                        {/foreach}
+				                    </select>
+			                     </div>
+			                </div>  
+			                
+			                <div class="layui-form-item">
+			                     <label class="layui-form-label">权限类型</label>
+			                     <div class="layui-input-block">
+			                     	<select name="gtype" id="gtype" >
+			                     		<option value="1" {if([$content->gtype]==1)}selected="selected"{/if}>小于</option>
+			                     		<option value="2" {if([$content->gtype]==2)}selected="selected"{/if}>小于等于</option>
+			                     		<option value="3" {if([$content->gtype]==3)}selected="selected"{/if}>等于</option>
+			                     		<option value="4" {if([$content->gtype]==4||(![$sort->gtype]))}selected="selected"{/if}>大于等于</option>
+			                     		<option value="5" {if([$content->gtype]==5)}selected="selected"{/if}>大于</option>
+									</select>
+			                     </div>
+			                </div> 
+			                
+					    </div>
+					    
+					    <div class="layui-tab-item ">
+					    	<div class="layui-form-item">
+			                     <label class="layui-form-label">内容副栏目</label>
+			                     <div class="layui-input-block">
+			                     	<select name="subscode">
+				                        <option value="">请选择内容副栏目</option>
+			                        	{$subsort_select}
+				                    </select>
+			                     </div>
+			                </div>
+			                
+					   		 <div class="layui-form-item">
+			                     <label class="layui-form-label">标题颜色</label>
+			                     <div class="layui-input-inline">
+			                     	<input type="text" name="titlecolor" value="{$content->titlecolor}" placeholder="请选择标题颜色"  class="layui-input jscolor {hash:true}">
+			                     </div>
+			                 </div>
+			                 
+			                 <div class="layui-form-item">
+			                     <label class="layui-form-label">副标题</label>
+			                     <div class="layui-input-block">
+			                     	<input type="text" name="subtitle" value="{$content->subtitle}" placeholder="请输入副标题" class="layui-input">
+			                     </div>
+			                 </div>
+			                 
+			                 <div class="layui-form-item">
+			                     <label class="layui-form-label">URL名称</label>
+			                     <div class="layui-input-block">
+			                     	<input type="text" name="filename" value="{$content->filename}" placeholder="请输入URL名称,如:test,test/a/b" class="layui-input">
+			                     </div>
+			                 </div>
+			                 
+			                  <div class="layui-form-item">
+			                     <label class="layui-form-label">跳转外链接</label>
+			                     <div class="layui-input-block">
+			                     	<input type="text" name="outlink" value="{$content->outlink}" placeholder="请输入跳转外链接" class="layui-input">
+			                     </div>
+			                 </div>
+			                 
+			                <div class="layui-form-item">
+			                     <label class="layui-form-label">权限不足提示</label>
+			                     <div class="layui-input-block">
+			                     	<input type="text" name="gnote" value="{$content->gnote}"  placeholder="请输入权限不足时提示文本"  class="layui-input">
+			                     </div>
+			                </div>
+			                 
+			                 <div class="layui-form-item">
+			                     <label class="layui-form-label">发布时间</label>
+			                     <div class="layui-input-inline">
+			                     	<input type="text" name="date" value="{$content->date}" readonly placeholder="请选择发布时间"  class="layui-input datetime">
+			                     </div>
+			                     <div class="layui-form-mid layui-word-aux">温馨提示:设置未来时间可定时发布!</div>
+			                </div>
+			                
+			                <div class="layui-form-item">
+		                		<label class="layui-form-label">附件</label>
+		                		<div class="layui-input-inline">
+			                     	<input type="text" name="enclosure" id="enclosure" value="{$content->enclosure}" placeholder="请上传附件"  class="layui-input">
+			                     </div>
+			                     <button type="button" class="layui-btn file" data-des="enclosure">
+								 	 <i class="layui-icon">&#xe67c;</i>上传附件
+								 </button>
+			                </div>
+			                
+			                <div class="layui-form-item">
+			                     <label class="layui-form-label">SEO关键字</label>
+			                     <div class="layui-input-block">
+			                     	<input type="text" name="keywords" value="{$content->keywords}"  placeholder="请输入详情页SEO关键字" class="layui-input">
+			                     </div>
+			                </div>
+			                
+			                <div class="layui-form-item">
+			                     <label class="layui-form-label">SEO描述</label>
+			                     <div class="layui-input-block">
+			                     	<textarea name="description" placeholder="请输入详情页SEO描述" class="layui-textarea">{$content->description}</textarea>
+			                     </div>
+			                </div>
+			                
+			                <div class="layui-form-item">
+			                     <label class="layui-form-label">状态</label>
+			                     <div class="layui-input-block">
+			                     	<input type="radio" name="status" value="1" title="显示" {if([$content->status]==1)} checked="checked"{/if}>
+									<input type="radio" name="status" value="0" title="隐藏" {if([$content->status]==0)} checked="checked"{/if}>
+			                     </div>
+			                </div>
+					    </div>
+					  </div>
+					</div>
+					<div class="layui-form-item">
+						 <div class="layui-input-block">
+						    <button class="layui-btn" lay-submit>立即提交</button>
+						    <button type="reset" class="layui-btn layui-btn-primary">重置</button>
+						    {fun=get_btn_back()}
+						 </div>
+					</div>
+	  		</form>
+	  	</div>
+	  </div>
+	</div>
+	{/if} 
+
+</div>
+
+<style>.placeHolder {border:dashed 2px gray; }</style>
+<script type="text/javascript" src="{APP_THEME_DIR}/js/jquery.dragsort-0.5.2.min.js"></script>
+<script type="text/javascript">
+$("#pics_box").dragsort({
+	dragSelector: "dl",
+	dragSelectorExclude: "input,textarea,dd",
+	dragBetween: false,
+	dragEnd: saveOrder,
+	placeHolderTemplate: "<dl class='placeHolder'><dt></dt></dl>"
+});
+
+function saveOrder() {
+	var data = $("#pics_box dl dt img").map(function() {
+		return $(this).data("url");
+	}).get();
+	$("input[name=pics]").val(data.join(","))
+};
+
+</script>
+<script type="text/javascript" src="{APP_THEME_DIR}/js/jscolor.js"></script>
+
+{include file='common/ueditor.html'}
+{include file='common/foot.html'}

+ 615 - 0
apps/admin/view/default/content/contentsort.html

@@ -0,0 +1,615 @@
+{include file='common/head.html'}
+
+<div class="layui-body">
+	{if([$list])}
+	<div class="layui-tab layui-tab-brief" lay-filter="tab">
+	  <ul class="layui-tab-title">
+	    <li class="layui-this" lay-id="t1">栏目列表</li>
+	    <li lay-id="t2">栏目新增</li>
+	    <li lay-id="t3">批量新增</li>
+	  </ul>
+	  <div class="layui-tab-content">
+	  	   <div class="layui-tab-item layui-show">
+	  	   		 <form action="{url./admin/ContentSort/mod}" method="post" id="sortForm" name="sortForm">
+	  	   		 <input type="hidden" name="formcheck" value="{$formcheck}" > 
+	  	   		 <table class="layui-table" id="sortTable">
+	  	   		 	  <thead>
+		                    <tr>
+		                        <th><input type="checkbox" lay-ignore id="checkall" title="全选"></th>
+		                        <th>栏目名称</th>
+		                        <th>编码</th>
+		                        <th>URL名称</th>
+		                        <th>模型</th>
+		                        <th>列表页模板</th>
+		                        <th>详情页模板</th>
+		                        <th>排序</th>
+		                        <th>状态</th>
+		                        <th>操作</th>
+		                    </tr>
+		                </thead>
+		                <tbody>
+		                {foreach $sorts(key,value)}
+		                	
+		                    <tr data-tt-id='[value->scode]' data-tt-parent-id="[value->pcode]">
+		                    	<td>
+		                    		<input type="checkbox" class="checkitem" lay-ignore name="list[]" value="[value->scode]">
+		                    		<input type="hidden" name="listall[]" value="[value->id]">
+		                    	</td>
+		                        <td>
+		                            {if($value->son)}
+		                               <i class="fa fa-folder-o" aria-hidden="true"></i>
+		                            {else}
+		                               <i class="fa fa-folder-open-o" aria-hidden="true"></i>
+		                            {/if}
+		                            [value->name]
+		                           
+		                            
+		                            {if($value->outlink)}
+		                            	<a href="[value->outlink]" target="_blank"><i class="fa fa-external-link" aria-hidden="true"></i></a>
+		                            {else}
+		                            	{if($value->type==1)}
+		                            	 <a href="{url./admin/Single/index/mcode}/[value->mcode]&scode=[value->scode]"><i class="fa fa-file-text-o" aria-hidden="true"></i> </a>
+		                            	{else}
+		                            	 <a href="{url./admin/Content/index/mcode}/[value->mcode]&scode=[value->scode]"><i class="fa fa-file-text-o" aria-hidden="true"></i> </a>
+		                            	 {/if}
+		                            {/if}
+		                        </td>
+		                        <td>[value->scode]</td>
+		                        <td>[value->filename]</td>
+		                        <td>
+		                        {foreach $allmodels(key2,value2)}	
+		                        	{if($value2->mcode==$value->mcode)}
+										[value2->name]
+									{/if}                        	
+				                {/foreach}
+								</td>
+		                        <td>[value->listtpl]</td>
+		                        <td>[value->contenttpl]</td>
+		                        <td class="table-input"><input type="text" name="sorting[]" value="[value->sorting]" class="layui-input"></td>
+		                       	<td>
+		                            {if($value->status)}
+		                            <a href="{url./admin/'.C.'/mod/scode/'.$value->scode.'/field/status/value/0}" class="switch"><i class='fa fa-toggle-on' title="点击禁用"></i></a>
+		                            {else}
+		                            <a href="{url./admin/'.C.'/mod/scode/'.$value->scode.'/field/status/value/1}" class="switch"><i class='fa fa-toggle-off' title="点击启用"></i></a>
+		                            {/if}
+		                        </td>
+		                        <td>
+		                        	{if(!$value->outlink)}
+		                        		{php}
+			                        		$Parser=new app\home\controller\ParserController();
+			                        		$link=$Parser->parserLink($value->type,$value->urlname,'list',$value->scode,$value->filename,'','');
+			                        	{/php}
+			                        	<a href="{php}echo $link{/php}" class="layui-btn layui-btn-xs layui-btn-primary"  target="_blank">查看</a>
+		                        	{/if}
+		                
+		                            {fun=get_btn_del($value->scode,'scode')}
+		                            {fun=get_btn_mod($value->scode,'scode')}
+		                        </td>
+		                    </tr>
+		                {/foreach}
+		                </tbody>
+	  	   		 </table>
+	  	   		 <button type="submit" name="submit" value="sorting" class="layui-btn">保存排序</button>
+	  	   		 <button type="submit" name="submit" onclick="return setDelAction();" class="layui-btn">批量删除</button>
+	  	   		 <script>
+		     		function setDelAction(){
+		     			document.sortForm.action = "{url./admin/ContentSort/del}"; 
+		     			return confirm("您确定要删除选中的栏目么?");
+		     		}
+		     		
+		     		$("#sortTable").treetable({ expandable: true,column: 1,indent:20,stringCollapse:'收缩',stringExpand:'展开' });
+		     	</script>
+	  	   		</form>
+	  	    </div>
+	  	    
+	  	     <div class="layui-tab-item">
+	  	     	<form action="{url./admin/ContentSort/add}" method="post" class="layui-form" lay-filter="sort">
+		  	     	<input type="hidden" name="formcheck" value="{$formcheck}" > 
+		  	     	<div class="layui-tab">
+					  <ul class="layui-tab-title">
+					    <li class="layui-this">基本选项</li>
+					    <li>高级选项</li>
+					  </ul>
+					  <div class="layui-tab-content">
+					    <div class="layui-tab-item layui-show">
+					    	<div class="layui-form-item">
+			                     <label class="layui-form-label">父栏目</label>
+			                     <div class="layui-input-block">
+			                     	<select name="pcode">
+				                        <option value="0" >顶级栏目</option>
+				                        {$sort_select}
+				                    </select>
+			                     </div>
+			                </div>
+			                
+			                <div class="layui-form-item">
+			                     <label class="layui-form-label">栏目名称 <span class="layui-text-red">*</span></label>
+			                     <div class="layui-input-block">
+			                     	<input type="text" name="name" required lay-verify="required" placeholder="请输入栏目名称" class="layui-input">
+			                     </div>
+			                </div>
+			                
+			                <div class="layui-form-item">
+			                     <label class="layui-form-label">URL名称 </label>
+			                     <div class="layui-input-block">
+			                     	<input type="text" name="filename"  placeholder="请输入URL名称,如:test,test/a/b/c" class="layui-input">
+			                     </div>
+			                </div>
+			                
+			                <div class="layui-form-item">
+			                     <label class="layui-form-label">内容模型 <span class="layui-text-red">*</span></label>
+			                     <div class="layui-input-block">
+			                     	<select name="mcode" lay-filter="model" lay-verify="required" >
+				                     	<option value="">请选择内容模型</option>
+				                        {foreach $models(key,value)}	                        	
+				                        	<option value="[value->mcode]" data-type="[value->type]"  data-listtpl="[value->listtpl]" data-contenttpl="[value->contenttpl]" >[value->name]</option>
+				                        {/foreach}
+				                    </select>
+			                     </div>
+			                </div>
+			                
+			                 <input type="hidden" value="1" name="type" id="type">
+			                 
+			                 <div class="layui-form-item">
+			                     <label class="layui-form-label">列表页模板</label>
+			                     <div class="layui-input-block">
+				                     <select name="listtpl" id="listtpl">
+				                     	<option value="">无</option>
+				                     	{foreach $tpls(key,value)}
+				                        	<option value="[value]">[value]</option>
+				                        {/foreach}
+				                     </select>
+			                     </div>
+			                </div>
+			                
+			                 <div class="layui-form-item">
+			                     <label class="layui-form-label">详情页模板</label>
+			                     <div class="layui-input-block">
+				                     <select name="contenttpl" id="contenttpl" >
+				                     	<option value="">无</option>
+				                     	{foreach $tpls(key,value)}
+				                        	<option value="[value]">[value]</option>
+				                        {/foreach}
+				                     </select>
+			                     </div>
+			                </div>
+			                
+			                <div class="layui-form-item">
+			                     <label class="layui-form-label">状态</label>
+			                     <div class="layui-input-block">
+			                     	<input type="radio" name="status" value="1" title="显示" checked>
+									<input type="radio" name="status" value="0" title="隐藏">
+			                     </div>
+			                </div>  
+			                
+			               <div class="layui-form-item">
+			                     <label class="layui-form-label">浏览权限</label>
+			                     <div class="layui-input-block">
+									<select name="gid">
+										<option value="">不限制</option>
+				                        {foreach $groups(key,value)}
+				                            <option value="[value->id]">[value->gname]</option>
+				                        {/foreach}
+				                    </select>
+			                     </div>
+			                </div>  
+			                
+			                <div class="layui-form-item">
+			                     <label class="layui-form-label">权限类型</label>
+			                     <div class="layui-input-block">
+			                     	<select name="gtype" id="gtype" >
+			                     		<option value="1">小于</option>
+			                     		<option value="2">小于等于</option>
+			                     		<option value="3">等于</option>
+			                     		<option value="4" selected>大于等于</option>
+			                     		<option value="5">大于</option>
+									</select>
+			                     </div>
+			                </div>   
+			                    
+					    </div>
+					    <div class="layui-tab-item">
+					    	<div class="layui-form-item">
+			                     <label class="layui-form-label">栏目副名称</label>
+			                     <div class="layui-input-block">
+			                     	<input type="text" name="subname" placeholder="请输入栏目副名称" class="layui-input">
+			                     </div>
+			                </div>
+			                
+			                <div class="layui-form-item">
+			                     <label class="layui-form-label">栏目描述1</label>
+			                     <div class="layui-input-block">
+			                     	<input type="text" name="def1"  placeholder="请输入栏目描述1内容"  class="layui-input">
+			                     </div>
+			                </div>
+			                
+			                <div class="layui-form-item">
+			                     <label class="layui-form-label">栏目描述2</label>
+			                     <div class="layui-input-block">
+			                     	<input type="text" name="def2" placeholder="请输入栏目描述2内容"  class="layui-input">
+			                     </div>
+			                </div>
+			                
+			                <div class="layui-form-item">
+			                     <label class="layui-form-label">栏目描述3</label>
+			                     <div class="layui-input-block">
+			                     	<input type="text" name="def3" placeholder="请输入栏目描述3内容"  class="layui-input">
+			                     </div>
+			                </div>
+			                
+			                <div class="layui-form-item">
+			                     <label class="layui-form-label">跳转链接</label>
+			                     <div class="layui-input-block">
+			                     	<input type="text" name="outlink" placeholder="请输入跳转链接" class="layui-input">
+			                     </div>
+			                </div>
+			                
+			                <div class="layui-form-item">
+			                     <label class="layui-form-label">权限不足提示</label>
+			                     <div class="layui-input-block">
+			                     	<input type="text" name="gnote"  placeholder="请输入权限不足时提示文本"  class="layui-input">
+			                     </div>
+			                </div>
+			                
+			                 <div class="layui-form-item">
+			                     <label class="layui-form-label">栏目缩略图</label>
+			                     <div class="layui-input-inline">
+			                     	<input type="text" name="ico" id="ico" placeholder="请上传栏目缩略图"  class="layui-input">
+			                     </div>
+			                     <button type="button" class="layui-btn upload" data-des="ico">
+								 	 <i class="layui-icon">&#xe67c;</i>上传图片
+								 </button>
+								 <div id="ico_box" class="pic"></div>
+			                </div>
+			                
+			                <div class="layui-form-item">
+			                     <label class="layui-form-label">栏目大图</label>
+			                     <div class="layui-input-inline">
+			                     	<input type="text" name="pic" id="pic" placeholder="请上传栏目大图"  class="layui-input">
+			                     </div>
+			                     <button type="button" class="layui-btn upload" data-des="pic">
+								 	 <i class="layui-icon">&#xe67c;</i>上传图片
+								 </button>
+								 <div id="pic_box" class="pic"></div>
+			                </div>
+			                
+			                <div class="layui-form-item">
+			                     <label class="layui-form-label">SEO标题</label>
+			                     <div class="layui-input-block">
+			                     	<input type="text" name="title" placeholder="请输入栏目SEO标题,需前端调用" class="layui-input">
+			                     </div>
+			                </div>
+			                
+			                <div class="layui-form-item">
+			                     <label class="layui-form-label">SEO关键字</label>
+			                     <div class="layui-input-block">
+			                     	<input type="text" name="keywords" placeholder="请输入栏目SEO关键字,需前端调用" class="layui-input">
+			                     </div>
+			                </div>
+			                
+			                <div class="layui-form-item">
+			                     <label class="layui-form-label">SEO描述</label>
+			                     <div class="layui-input-block">
+			                     	<textarea name="description" placeholder="请输入栏目SEO描述,需前端调用" class="layui-textarea"></textarea>
+			                     </div>
+			                </div>
+					    </div>
+					  </div>
+					</div>
+					<div class="layui-form-item">
+						 <div class="layui-input-block">
+						    <button class="layui-btn" lay-submit>立即提交</button>
+						    <button type="reset" class="layui-btn layui-btn-primary">重置</button>
+						 </div>
+					</div>
+				</form>
+	  	     </div>
+	  	     
+	  	     <!-- 批量新增 -->
+	  	     <div class="layui-tab-item">
+	  	     	<form action="{url./admin/ContentSort/add}" method="post" class="layui-form" lay-filter="sort">
+		  	     		<input type="hidden" name="formcheck" value="{$formcheck}" > 
+		  	     		<div class="layui-form-item">
+		                     <label class="layui-form-label">父栏目</label>
+		                     <div class="layui-input-block">
+		                     	<select name="pcode">
+			                        <option value="0" >顶级栏目</option>
+			                        {$sort_select}
+			                    </select>
+		                     </div>
+		                </div>
+		                
+		                <div class="layui-form-item">
+		                     <label class="layui-form-label">栏目名称</label>
+		                     <div class="layui-input-block">
+		                     	<input type="text" name="multiplename" required lay-verify="required" placeholder="请输入栏目名称,多个栏目用逗号隔开" class="layui-input">
+		                     </div>
+		                </div>
+		                
+		                <div class="layui-form-item">
+		                     <label class="layui-form-label">内容模型</label>
+		                     <div class="layui-input-block">
+		                     	<select name="mcode" lay-filter="model" lay-verify="required" >
+			                     	<option value="">请选择内容模型</option>
+			                        {foreach $models(key,value)}	                        	
+			                        	<option value="[value->mcode]" data-type="[value->type]"  data-listtpl="[value->listtpl]" data-contenttpl="[value->contenttpl]" >[value->name]</option>
+			                        {/foreach}
+			                    </select>
+		                     </div>
+		                </div>
+		                
+		                 <input type="hidden" value="1" name="type" id="type">
+		                 
+		                 <div class="layui-form-item">
+		                     <label class="layui-form-label">列表页模板</label>
+		                     <div class="layui-input-block">
+			                     <select name="listtpl" id="listtpl">
+			                     	<option value="">无</option>
+			                     	{foreach $tpls(key,value)}
+			                        	<option value="[value]">[value]</option>
+			                        {/foreach}
+			                     </select>
+		                     </div>
+		                </div>
+		                
+		                 <div class="layui-form-item">
+		                     <label class="layui-form-label">详情页模板</label>
+		                     <div class="layui-input-block">
+			                     <select name="contenttpl" id="contenttpl" >
+			                     	<option value="">无</option>
+			                     	{foreach $tpls(key,value)}
+			                        	<option value="[value]">[value]</option>
+			                        {/foreach}
+			                     </select>
+		                     </div>
+		                </div>
+		                
+		                <div class="layui-form-item">
+		                     <label class="layui-form-label">状态</label>
+		                     <div class="layui-input-block">
+		                     	<input type="radio" name="status" value="1" title="显示" checked>
+								<input type="radio" name="status" value="0" title="隐藏">
+		                     </div>
+		                </div>    
+					<div class="layui-form-item">
+						 <div class="layui-input-block">
+						    <button class="layui-btn" lay-submit>立即提交</button>
+						    <button type="reset" class="layui-btn layui-btn-primary">重置</button>
+						 </div>
+					</div>
+				</form>
+	  	     </div>
+	   </div>
+	</div>
+	{/if} 
+	
+	{if([$mod])}
+	<div class="layui-tab layui-tab-brief" lay-filter="tab">
+	  <ul class="layui-tab-title">
+	    <li class="layui-this">栏目修改</li>
+	  </ul>
+	  <div class="layui-tab-content">
+	  	<div class="layui-tab-item layui-show">
+	  		<form action="{url./admin/ContentSort/mod/scode/'.[$get.scode].'}{$backurl}" method="post" class="layui-form" lay-filter="sort">
+	  	     	<input type="hidden" name="formcheck" value="{$formcheck}" > 
+	  	     	<div class="layui-tab">
+				  <ul class="layui-tab-title">
+				    <li class="layui-this">基本选项</li>
+				    <li>高级选项</li>
+				  </ul>
+				  <div class="layui-tab-content">
+				    <div class="layui-tab-item layui-show">
+				    	<div class="layui-form-item">
+		                     <label class="layui-form-label">父栏目</label>
+		                     <div class="layui-input-block">
+		                     	<select name="pcode" id="pcode">
+			                        <option value="0" >顶级栏目</option>
+			                        {$sort_select}
+			                    </select>
+		                     </div>
+		                </div>
+		                
+		                <div class="layui-form-item">
+		                     <label class="layui-form-label">栏目名称  <span class="layui-text-red">*</span></label>
+		                     <div class="layui-input-block">
+		                     	<input type="text" name="name" required lay-verify="required" value="{$sort->name}" placeholder="请输入栏目名称" class="layui-input">
+		                     </div>
+		                </div>
+		                
+		                <div class="layui-form-item">
+		                     <label class="layui-form-label">URL名称 </label>
+		                     <div class="layui-input-block">
+		                     	<input type="text" name="filename" value="{$sort->filename}"  placeholder="请输入URL名称,如:test,test/a/b/c" class="layui-input">
+		                     </div>
+		                </div>
+		                
+		                <div class="layui-form-item">
+		                     <label class="layui-form-label">内容模型  <span class="layui-text-red">*</span></label>
+		                     <div class="layui-input-block">
+		                     	<select name="mcode" lay-filter="model" lay-verify="required" >
+			                     	<option value="">请选择内容模型</option>
+			                        {foreach $models(key,value)}	                        	
+			                        	<option value="[value->mcode]"  {if($value->mcode==[$sort->mcode])}selected{/if}  data-type="[value->type]"  data-listtpl="[value->listtpl]" data-contenttpl="[value->contenttpl]" >[value->name]</option>
+			                        {/foreach}
+			                    </select>
+		                     </div>
+		                </div>
+		                
+		                 <input type="hidden" name="type" id="type" value="{$sort->type}">
+		                 
+		                 <div class="layui-form-item">
+		                     <label class="layui-form-label">列表页模板</label>
+		                     <div class="layui-input-block">
+			                     <select name="listtpl" id="listtpl">
+			                     	<option value="{$sort->listtpl}">{$sort->listtpl}</option>
+			                     	<option value="">无</option>
+			                     	{foreach $tpls(key,value)}
+			                     		{if($value!=[$sort->listtpl])}
+			                        		<option value="[value]">[value]</option>
+			                        	{/if}
+			                        {/foreach}
+			                     </select>
+		                     </div>
+		                </div>
+		                
+		                 <div class="layui-form-item">
+		                     <label class="layui-form-label">详情页模板</label>
+		                     <div class="layui-input-block">
+			                     <select name="contenttpl" id="contenttpl" >
+			                     	<option value="{$sort->contenttpl}">{$sort->contenttpl}</option>
+			                     	<option value="">无</option>
+			                     	{foreach $tpls(key,value)}
+			                     		{if($value!=[$sort->contenttpl])}
+			                        		<option value="[value]">[value]</option>
+			                        	{/if}
+			                        {/foreach}
+			                     </select>
+		                     </div>
+		                </div>
+		                
+		                <div class="layui-form-item">
+		                     <label class="layui-form-label">同步子栏目模板</label>
+		                     <div class="layui-input-block">
+		                     	<input type="radio" name="modsub" value="1" title="是">
+								<input type="radio" name="modsub" value="0" title="否" checked>
+		                     </div>
+		                </div> 
+		                
+		                <div class="layui-form-item">
+		                     <label class="layui-form-label">状态</label>
+		                     <div class="layui-input-block">
+		                     	<input type="radio" name="status" value="1" title="显示" {if([$sort->status]==1)}checked="checked"{/if}>
+								<input type="radio" name="status" value="0" title="隐藏" {if([$sort->status]==0)}checked="checked"{/if}>
+		                     </div>
+		                </div>
+		                
+		                 <div class="layui-form-item">
+			                     <label class="layui-form-label">浏览权限</label>
+			                     <div class="layui-input-block">
+									<select name="gid">
+										<option value="">不限制</option>
+				                        {foreach $groups(key,value)}
+				                            <option value="[value->id]" {if([$sort->gid]==$value->id)}selected="selected"{/if}>[value->gname]</option>
+				                        {/foreach}
+				                    </select>
+			                     </div>
+			                </div>  
+			                
+			                <div class="layui-form-item">
+			                     <label class="layui-form-label">权限类型</label>
+			                     <div class="layui-input-block">
+			                     	<select name="gtype" id="gtype" >
+			                     		<option value="1" {if([$sort->gtype]==1)}selected="selected"{/if}>小于</option>
+			                     		<option value="2" {if([$sort->gtype]==2)}selected="selected"{/if}>小于等于</option>
+			                     		<option value="3" {if([$sort->gtype]==3)}selected="selected"{/if}>等于</option>
+			                     		<option value="4" {if([$sort->gtype]==4||(![$sort->gtype]))}selected="selected"{/if}>大于等于</option>
+			                     		<option value="5" {if([$sort->gtype]==5)}selected="selected"{/if}>大于</option>
+									</select>
+			                     </div>
+			                </div> 
+
+		                
+				    </div>
+				    <div class="layui-tab-item">
+				    	<div class="layui-form-item">
+		                     <label class="layui-form-label">栏目副名称</label>
+		                     <div class="layui-input-block">
+		                     	<input type="text" name="subname" value="{$sort->subname}" placeholder="请输入栏目副名称" class="layui-input">
+		                     </div>
+		                </div>
+		                
+		                 <div class="layui-form-item">
+		                     <label class="layui-form-label">栏目描述1</label>
+		                     <div class="layui-input-block">
+		                     	<input type="text" name="def1"  value="{$sort->def1}"  placeholder="请输入栏目描述1内容"  class="layui-input">
+		                     </div>
+		                </div>
+		                
+		                <div class="layui-form-item">
+		                     <label class="layui-form-label">栏目描述2</label>
+		                     <div class="layui-input-block">
+		                     	<input type="text" name="def2" value="{$sort->def2}" placeholder="请输入栏目描述2内容"  class="layui-input">
+		                     </div>
+		                </div>
+		                
+		                <div class="layui-form-item">
+		                     <label class="layui-form-label">栏目描述3</label>
+		                     <div class="layui-input-block">
+		                     	<input type="text" name="def3" value="{$sort->def3}" placeholder="请输入栏目描述3内容"  class="layui-input">
+		                     </div>
+		                </div>
+			                
+		                <div class="layui-form-item">
+		                     <label class="layui-form-label">跳转链接</label>
+		                     <div class="layui-input-block">
+		                     	<input type="text" name="outlink" value="{$sort->outlink}" placeholder="请输入跳转链接" class="layui-input">
+		                     </div>
+		                </div>
+		                
+	                    <div class="layui-form-item">
+		                     <label class="layui-form-label">权限不足提示</label>
+		                     <div class="layui-input-block">
+		                     	<input type="text" name="gnote" value="{$sort->gnote}"  placeholder="请输入权限不足时提示文本"  class="layui-input">
+		                     </div>
+		                </div>
+		                
+		                 <div class="layui-form-item">
+		                     <label class="layui-form-label">栏目缩略图</label>
+		                     <div class="layui-input-inline">
+		                     	<input type="text" name="ico" id="ico" value="{$sort->ico}" placeholder="请上传栏目缩略图"  class="layui-input">
+		                     </div>
+		                     <button type="button" class="layui-btn upload" data-des="ico">
+							 	 <i class="layui-icon">&#xe67c;</i>上传图片
+							 </button>
+							 <div id="ico_box" class="pic"><dl><dt>{if([$sort->ico])}<img src='{SITE_DIR}{$sort->ico}' data-url="{$sort->ico}"></dt><dd>删除</dd></dl>{/if}</div>
+		                </div>
+		                
+		                 <div class="layui-form-item">
+		                     <label class="layui-form-label">栏目大图</label>
+		                     <div class="layui-input-inline">
+		                     	<input type="text" name="pic" id="pic" value="{$sort->pic}" placeholder="请上传栏目大图"  class="layui-input">
+		                     </div>
+		                     <button type="button" class="layui-btn upload" data-des="pic">
+							 	 <i class="layui-icon">&#xe67c;</i>上传图片
+							 </button>
+							 <div id="pic_box" class="pic"><dl><dt>{if([$sort->pic])}<img src='{SITE_DIR}{$sort->pic}' data-url="{$sort->pic}"></dt><dd>删除</dd></dl>{/if}</div>
+		                </div>
+		                
+		                <div class="layui-form-item">
+		                     <label class="layui-form-label">SEO标题</label>
+		                     <div class="layui-input-block">
+		                     	<input type="text" name="title" value="{$sort->title}" placeholder="请输入栏目SEO标题,需前端调用" class="layui-input">
+		                     </div>
+		                </div>
+		                
+		                <div class="layui-form-item">
+		                     <label class="layui-form-label">SEO关键字</label>
+		                     <div class="layui-input-block">
+		                     	<input type="text" name="keywords" value="{$sort->keywords}" placeholder="请输入栏目SEO关键字,需前端调用" class="layui-input">
+		                     </div>
+		                </div>
+		                
+		                <div class="layui-form-item">
+		                     <label class="layui-form-label">SEO描述</label>
+		                     <div class="layui-input-block">
+		                     	<textarea name="description" placeholder="请输入栏目SEO描述,需前端调用" class="layui-textarea">{$sort->description}</textarea>
+		                     </div>
+		                </div>
+				    </div>
+				  </div>
+				</div>
+				<div class="layui-form-item">
+					 <div class="layui-input-block">
+					    <button class="layui-btn" lay-submit>立即提交</button>
+					    <button type="reset" class="layui-btn layui-btn-primary">重置</button>
+					    {fun=get_btn_back()}
+					 </div>
+				</div>
+			</form>
+	  	</div>
+	  </div>
+	</div>
+	{/if} 
+</div>
+
+{include file='common/foot.html'}

+ 135 - 0
apps/admin/view/default/content/delecache.html

@@ -0,0 +1,135 @@
+{include file='common/head.html'}
+<style>
+.huancuna{
+display: inline-block;
+padding: 9px 25px;
+font-weight: 400;
+line-height: 20px;
+text-align: right;
+color:#ffffff;
+background-color: #009688;
+border-radius:2px;
+}
+.huancuna:hover{
+background-color: #33aba0;
+color:#ffffff;
+}
+
+</style>
+<div class="layui-body">
+	
+	<div class="layui-tab layui-tab-brief" lay-filter="tab">
+	  <ul class="layui-tab-title">
+	    <li class="layui-this" lay-id="t1">更新缓存</li>
+	  </ul>
+	  
+	  <div class="layui-tab-content">
+  	     <div class="layui-tab-item layui-form  layui-show">
+  	     
+  	     	 <div class="layui-form-item">
+                  <label class="layui-form-label">更新首页和栏目</label>
+                  <button type="button" class="layui-btn deletecache" data-type="1">立即更新首页和栏目</button>
+             </div>
+           
+     		 <div class="layui-form-item">
+                  <label class="layui-form-label">更新栏目分页</label>
+                  <div class="layui-input-inline">
+	                  <select name="scode">
+	                      <option value="0" >全部栏目</option>
+	                      {$sort_select}
+	                  </select>
+                  </div>
+                  <button type="button" class="layui-btn deletecache" data-type="2">立即更新栏目页</button>
+             </div>
+             
+             <div class="layui-form-item">
+                  <label class="layui-form-label">更新内容页</label> &nbsp;&nbsp;起始ID
+				  <input type="text" id="idzuixiao" value="1" placeholder="最小ID"  class="layui-input input" style="width:15%; display:inline;">
+				  &nbsp;&nbsp;结束ID
+				  <input type="text" id="idzuida" value="10" placeholder="最大ID"  class="layui-input input" style="width:15%; display:inline;">
+                  <button type="button" class="layui-btn deletecache" data-type="3">立即更新内容页</button>
+             </div>
+			 <div class="layui-form-item">
+                  <label class="layui-form-label">更新系统缓存</label>
+				  <a href="{url./admin/Index/clearOnlySysCache}" class="ajaxlink huancuna">清理系统缓存</a> 
+
+             </div>
+			 <div class="layui-form-item">
+                  <label class="layui-form-label">更新所有缓存</label>
+				  <a href="{url./admin/Index/clearCache}" class="ajaxlink huancuna">清理所有缓存</a> 
+
+             </div>
+			 <div class="layui-form-item" style="padding-left:20px; line-height:24px;">
+                  功能说明:
+				  <br />1、《更新首页和栏目》:随便使用。
+				  <br />2、《更新栏目分页》:每天发布量<200篇。7天一次。每天发布量<500篇。3天只需使用一次。每天发布量>1000篇。1天只需使用一次。
+				  <br />3、《更新内容页》:根据需要去更新,无全局更新永远不使用。
+				  <br />4、《更新系统缓存》:随便使用。
+				  <br />5、《更新所有缓存》:如果数据量小,随便使用。如果数据量大,无全局更新永远不要使用。
+				  <br />6、一定要做好301,保证链接的唯一性。
+             </div>
+
+  	     </div>
+	   </div>
+	</div>
+	
+</div>
+
+ <script>
+ $(".deletecache").on("click",function(){
+	 var type=$(this).data("type");
+	 var scode=$(this).parents(".layui-form-item").find("select").val();
+	 var idzuixiao=$("#idzuixiao").val();
+	 var idzuida=$("#idzuida").val();
+	 
+	 var lyindex;
+	 layui.use('layer', function(){
+		var layer = layui.layer;
+		lyindex = layer.open({
+			type: 1,
+			title:'温馨提示',
+			closeBtn:0,
+			content: '<div style="padding:20px 10px;"><img src="{APP_THEME_DIR}/layui/css/modules/layer/default/loading-0.gif">正在更新...<div>' 
+		});
+	 });
+	
+	var url= "?p=/DeleCache/index";
+	$.ajax({
+   	  type: 'GET',
+   	  url: url,
+   	  data:{
+   		  type:type,
+   		  scode:scode,
+		  idzuixiao:idzuixiao,
+		  idzuida:idzuida
+   	  },
+   	  dataType: 'json',
+   	  success: function (response, status) {
+   		  if(response.code==1){
+   			 layer.close(lyindex);
+      		 layer.msg(response.data, {icon: 1});
+   		  }else{
+   			layer.close(lyindex);
+   			layer.open({
+	  			  type: 0,
+	  			  title:'错误提示:',
+	  			  closeBtn:0,
+	  			  btn: ['确认'],
+	  			  content: response.data,
+	  			  yes: function(index, layero){
+	  				  layer.close(index); 
+	  			  }
+	  		 });
+   		  }
+        },
+        error:function(xhr,status,error){
+     	  layer.close(lyindex);
+       	  layer.msg("执行更新发生错误!", {icon: 5});
+        }
+   	});
+	
+ });
+ 
+ </script>
+
+{include file='common/foot.html'}

+ 68 - 0
apps/admin/view/default/content/exform.html

@@ -0,0 +1,68 @@
+<html xmlns:x="urn:schemas-microsoft-com:office:excel">
+<head>
+  <meta charset="utf-8">
+  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
+  <title>{$form->form_name}记录导出</title>
+  <style>
+	table,table tr th, table tr td{
+		border:1px solid #333;
+	}
+	table tr th, table tr td{
+		padding:2px 5px;
+	}
+	.text{
+		mso-number-format:\@;
+	}
+	table{
+		margin:10px 0;
+		border-collapse:collapse;
+	}
+	</style>
+	
+	<!--[if gte mso 9]><xml>
+            <x:ExcelWorkbook>
+                <x:ExcelWorksheets>
+                    <x:ExcelWorksheet>
+                        <x:Name>Sheet1</x:Name>
+                        <x:WorksheetOptions>
+                            <x:Print>
+                                <x:ValidPrinterInfo />
+                            </x:Print>
+                        </x:WorksheetOptions>
+                    </x:ExcelWorksheet>
+                </x:ExcelWorksheets>
+            </x:ExcelWorkbook>
+        </xml>
+        <![endif]-->
+	
+</head>
+<body>
+
+
+ <table class="layui-table">
+	<thead>
+		<tr>
+			<th>序号</th>
+			{foreach $fields(key1,value1,num1)}
+			  <th>[value1->description]</th>
+   			{/foreach}
+   			<th>时间</th>
+		</tr>
+	</thead>
+	<tbody>
+		{foreach $formdata(key,value,num)}
+		<tr>
+			<td>[num]</td>
+			{foreach $fields(key2,value2,num2)}
+		      	{php} $field=$value2->name {/php}
+		      	<td class="text">[value->$field]</td>
+ 	   		{/foreach}
+ 	   		<td>[value->create_time]</td>
+		</tr>
+		{/foreach}
+	</tbody>
+</table>
+
+</body>
+</html>
+	

+ 76 - 0
apps/admin/view/default/content/exmessage.html

@@ -0,0 +1,76 @@
+<html xmlns:x="urn:schemas-microsoft-com:office:excel">
+<head>
+  <meta charset="utf-8">
+  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
+  <title>留言记录导出</title>
+  <style>
+	table,table tr th, table tr td{
+		border:1px solid #333;
+	}
+	table tr th, table tr td{
+		padding:2px 5px;
+	}
+	.text{
+		mso-number-format:\@;
+	}
+	table{
+		margin:10px 0;
+		border-collapse:collapse;
+	}
+	</style>
+	
+	<!--[if gte mso 9]><xml>
+            <x:ExcelWorkbook>
+                <x:ExcelWorksheets>
+                    <x:ExcelWorksheet>
+                        <x:Name>Sheet1</x:Name>
+                        <x:WorksheetOptions>
+                            <x:Print>
+                                <x:ValidPrinterInfo />
+                            </x:Print>
+                        </x:WorksheetOptions>
+                    </x:ExcelWorksheet>
+                </x:ExcelWorksheets>
+            </x:ExcelWorkbook>
+        </xml>
+        <![endif]-->
+	
+</head>
+<body>
+
+
+ <table class="layui-table">
+	<thead>
+		<tr>
+			<th>序号</th>
+			{foreach $fields(key1,value1,num1)}
+			  <th class="text">[value1->description]</th>
+   			{/foreach}
+   			<th>时间</th>
+   			<th>访客信息</th>
+   			<th>回复内容</th>
+		</tr>
+	</thead>
+	<tbody>
+		{foreach $messages(key,value,num)}
+		<tr>
+			<td>[num]</td>
+			{foreach $fields(key2,value2,num2)}
+		      	{php} $field=$value2->name {/php}
+		      	<td>[value->$field]</td>
+ 	   		{/foreach}
+ 	   		<td>[value->create_time]</td>
+ 	   		<td>
+	      		IP:{fun=long2ip($value->user_ip)};
+				浏览器:[value->user_bs];
+				操作系统:[value->user_os]
+			</td>
+			<td>[value->recontent]</td>
+		</tr>
+		{/foreach}
+	</tbody>
+</table>
+
+</body>
+</html>
+	

+ 230 - 0
apps/admin/view/default/content/extfield.html

@@ -0,0 +1,230 @@
+{include file='common/head.html'}
+
+<div class="layui-body">
+	{if([$list])}
+	<div class="layui-tab layui-tab-brief" lay-filter="tab">
+	  <ul class="layui-tab-title">
+	    <li class="layui-this" lay-id="t1">扩展字段列表</li>
+	    <li lay-id="t2">扩展字段新增</li>
+	  </ul>
+	  <div class="layui-tab-content">
+	  	   <div class="layui-tab-item layui-show">
+	  	   		<table class="layui-table">
+	            	<thead>
+	                    <tr>
+	                    	<th>序号</th>
+	                        <th>内容模型</th>
+	                        <th>字段描述</th>
+	                        <th>字段名称</th>
+	                        <th>字段类型</th>
+	                        <th>排序</th>
+	                        <th>操作</th>
+	                    </tr>
+	                </thead>
+	                <tbody>
+	                    {foreach $extfields(key,value)}
+	                    <tr>
+	                    	<td>[num]</td>
+	                    	<td>
+	                    		{foreach $models(key2,value2,num2)}	
+	                        		{if($value2->mcode==$value->mcode)}
+										[value2->name]
+									{/if}                        	
+			                	{/foreach}
+							</td>
+	                        <td>[value->description]</td>
+	                        <td>[value->name]</td>
+	                        <td>
+	                        	{if($value->type==1)}单行文本{/if}
+	                    		{if($value->type==2)}多行文本{/if}
+	                    		{if($value->type==3)}单选按钮{/if}
+	                    		{if($value->type==4)}多选按钮{/if}
+	                    		{if($value->type==5)}单图上传{/if}
+	                    		{if($value->type==10)}多图上传{/if}
+	                    		{if($value->type==6)}附件上传{/if}
+	                    		{if($value->type==7)}日期选择{/if}
+	                    		{if($value->type==8)}编辑器{/if}
+	                    		{if($value->type==9)}下拉选择{/if}
+							</td>
+							<td>[value->sorting]</td>
+	                        <td>
+	                            {fun=get_btn_del($value->id)}
+	                            {fun=get_btn_mod($value->id)}
+	                        </td>
+	                    </tr>
+	                    {/foreach}
+	                </tbody>
+	            </table>
+	            <div class="page">{$pagebar}</div>
+	  	   </div>
+	  	   
+	  	    <div class="layui-tab-item">
+	   			<form action="{url./admin/ExtField/add}" method="post" class="layui-form">
+	   				<input type="hidden" name="formcheck" value="{$formcheck}" > 
+	   				<div class="layui-form-item">
+	                     <label class="layui-form-label">内容模型</label>
+	                     <div class="layui-input-block">
+	                     	 <select name="mcode" lay-verify="required">
+		                        <option value="">请选择内容模型</option>
+		                        {foreach $models(key,value)}	                        	
+		                        	<option value="[value->mcode]">[value->name]</option>
+		                        {/foreach}
+		                    </select>
+	                     </div>
+	                </div>
+	                
+	                <div class="layui-form-item">
+	                     <label class="layui-form-label">字段描述</label>
+	                     <div class="layui-input-block">
+	                     	<input type="text" name="description" required lay-verify="required"  placeholder="请输入字段描述,如:产品价格" class="layui-input">
+	                     </div>
+	                </div>
+	                
+	                <div class="layui-form-item">
+	                     <label class="layui-form-label">字段名称</label>
+	                     <div class="layui-input-block">
+	                     	<input type="text" name="name" required maxlength="20" lay-verify="required"  placeholder="请输入字段名称,字母、数组、下划线,如:price" class="layui-input">
+	                     </div>
+	                </div>
+	                
+	                <div class="layui-form-item">
+	                     <label class="layui-form-label">字段类型</label>
+	                     <div class="layui-input-block">
+	                     	 <select name="type" lay-verify="required">
+		                    	<option value="1">单行文本</option>
+		                    	<option value="2">多行文本</option>
+		                    	<option value="3">单选按钮</option>
+		                    	<option value="4">多选按钮</option>
+		                    	<option value="5">单图上传</option>
+		                    	<option value="10">多图上传</option>
+		                    	<option value="6">附件上传</option>
+		                    	<option value="7">日期选择</option>
+		                    	<option value="8">编辑器</option>
+		                    	<option value="9">下拉选择</option>
+		                    </select>
+	                     </div>
+	                </div>
+	                
+	                <div class="layui-form-item">
+	                     <label class="layui-form-label">选择按钮值</label>
+	                     <div class="layui-input-block">
+	                     	<textarea name="value" placeholder="多个选项用逗号隔开或者回车"  class="layui-textarea"></textarea>
+	                     	<div class="layui-form-mid layui-word-aux">只在类型为单选或多选时填写有效。</div>
+	                     </div>
+	                </div>
+	                
+	                <div class="layui-form-item">
+	                     <label class="layui-form-label">排序</label>
+	                     <div class="layui-input-block">
+	                     	<input type="text" name="sorting" required lay-verify="required" value="255" placeholder="请输入排序"  class="layui-input">
+	                     </div>
+	                </div>
+		   			
+	   				<div class="layui-form-item">
+						 <div class="layui-input-block">
+						    <button class="layui-btn" lay-submit>立即提交</button>
+						    <button type="reset" class="layui-btn layui-btn-primary">重置</button>
+						 </div>
+					</div>
+	   			</form>
+	   	 	</div>
+	   </div>
+	 </div>
+	{/if} 
+	
+	{if([$mod])}
+	<div class="layui-tab layui-tab-brief" lay-filter="tab">
+	  <ul class="layui-tab-title">
+	    <li class="layui-this">扩展字段修改</li>
+	  </ul>
+	  <div class="layui-tab-content">
+	  	<div class="layui-tab-item layui-show">
+	  		<form action="{url./admin/ExtField/mod/id/'.[$get.id].'}{$backurl}" method="post" class="layui-form">
+	  			<input type="hidden" name="formcheck" value="{$formcheck}" > 
+	  			<div class="layui-form-item">
+                     <label class="layui-form-label">内容模型</label>
+                     <div class="layui-input-block">
+                     	 <select name="mcode" lay-verify="required">
+	                        <option value="">请选择内容模型</option>
+	                        {foreach $models(key,value)}	                        	
+	                        	<option value="[value->mcode]" {if($value->mcode==[$extfield->mcode])}selected{/if}>[value->name]</option>
+	                        {/foreach}
+	                    </select>
+                     </div>
+                </div>
+                
+                <div class="layui-form-item">
+                     <label class="layui-form-label">字段描述</label>
+                     <div class="layui-input-block">
+                     	<input type="text" name="description"  value="{$extfield->description}" placeholder="请输入字段描述,如:产品价格" class="layui-input">
+                     </div>
+                </div>
+                
+                <div class="layui-form-item">
+                     <label class="layui-form-label">字段名称</label>
+                     <div class="layui-input-block">
+                     	<input type="text" name="name" readonly value="{$extfield->name}" maxlength="20" placeholder="请输入字段名称,字母、数组、下划线,如:price" class="layui-input readonly">
+                     </div>
+                </div>
+                
+                <div class="layui-form-item">
+                     <label class="layui-form-label">字段类型</label>
+                     <div class="layui-input-block">
+                     	 <select name="type" lay-verify="required">
+	                    	{if([$extfield->type]==2)}
+	                    		<option value="2" selected>多行文本</option>
+	                    	{/if}
+	                    	
+	                    	{if([$extfield->type]==7)}
+	                    		<option value="7" selected>日期选择</option>
+	                    	{/if}
+	                    	
+	                    	{if([$extfield->type]==8)}
+	                    		<option value="8" selected>编辑器</option>
+	                    	{/if}
+	                    	
+	                    	{if([$extfield->type]==10)}
+	                    		<option value="10" selected>多图上传</option>
+	                    	{/if}
+	                    	
+	                    	{if([$extfield->type]!=2 && [$extfield->type]!=7 && [$extfield->type]!=8 && [$extfield->type]!=10)}
+	                    		<option value="1" {if([$extfield->type]==1)}selected{/if}>单行文本</option>
+	                    		<option value="3" {if([$extfield->type]==3)}selected{/if}>单选按钮</option>
+	                    		<option value="4" {if([$extfield->type]==4)}selected{/if}>多选按钮</option>
+	                    		<option value="5" {if([$extfield->type]==5)}selected{/if}>单图上传</option>
+	                    		<option value="6" {if([$extfield->type]==6)}selected{/if}>附件上传</option>
+	                    		<option value="9" {if([$extfield->type]==9)}selected{/if}>下拉选择</option>
+	                    	{/if}
+	                    </select>
+                     </div>
+                </div>
+                
+                <div class="layui-form-item">
+                     <label class="layui-form-label">选择按钮值</label>
+                     <div class="layui-input-block">
+                     	<textarea name="value" placeholder="多个选项用逗号或回车隔开"  class="layui-textarea">{$extfield->value}</textarea>
+                     	<div class="layui-form-mid layui-word-aux">只在类型为单选或多选时填写有效,多个选项用逗号或回车隔开。</div>
+                     </div>
+                </div>
+                
+                <div class="layui-form-item">
+                     <label class="layui-form-label">排序</label>
+                     <div class="layui-input-block">
+                     	<input type="text" name="sorting" required lay-verify="required" value="{$extfield->sorting}" placeholder="请输入排序"  class="layui-input">
+                     </div>
+                </div>
+   			
+   				<div class="layui-form-item">
+					 <div class="layui-input-block">
+					    <button class="layui-btn" lay-submit>立即提交</button>
+					    <button type="reset" class="layui-btn layui-btn-primary">重置</button>
+					    {fun=get_btn_back()}
+					 </div>
+				</div>
+	  		</form>
+	  	</div>
+	  </div>
+	 </div>
+	{/if} 
+</div>
+{include file='common/foot.html'}

+ 327 - 0
apps/admin/view/default/content/form.html

@@ -0,0 +1,327 @@
+{include file='common/head.html'}
+
+<div class="layui-body">
+	{if([$list])}
+	<div class="layui-tab layui-tab-brief" lay-filter="tab">
+	  <ul class="layui-tab-title">
+	    <li class="layui-this" lay-id="t1">表单列表</li>
+	    <li lay-id="t2">表单新增</li>
+	  </ul>
+	  <div class="layui-tab-content">
+	  	   <div class="layui-tab-item layui-show">
+	  	   		<table class="layui-table">
+	            	<thead>
+	                    <tr>
+	                    	<th>编码</th>
+							<th>表单名称</th>
+	                        <th>表名称</th>
+	                        <th>数据</th>
+	                        <th>字段</th>
+	                        <th>操作</th>
+	                    </tr>
+	                </thead>
+	                <tbody>
+	                    {foreach $forms(key,value)}
+	                    <tr>
+	                    	<td>[value->fcode]</td>
+							<td>[value->form_name]</td>
+	                    	<td>[value->table_name]</td>
+	                    	<td>
+	                    	{if($value->id==1)}
+	                    	<a href="{url./admin/Message/index}"><i class="fa fa-list"></i> 查看数据</a></td>
+	                    	{else}
+	                    	<a href="{url./admin/Form/index/fcode/'.$value->fcode.'/action/showdata}"><i class="fa fa-list"></i> 查看数据</a></td>
+	                    	{/if}
+	                    	<td><a href="{url./admin/Form/index/fcode/'.$value->fcode.'/action/showfield}"><i class="fa fa-pencil-square-o"></i> 编辑字段</a></td>
+	                        <td>
+								
+	                        	{if($value->id!=1)}
+									<a href="{url./admin/Form/mod/id/'.$value->id.'/action/addmenu}{$btnqs}" class="layui-btn layui-btn-xs layui-btn-primary">添加到菜单</a>
+	                        		<a href="{url./admin/Form/del/id/'.$value->id.'/action/delform}" onclick="return confirm('您确定要删除么?')" class="layui-btn layui-btn-xs layui-btn-danger" title="删除">删除</a>
+	                            {/if}
+	                            <a href="{url./admin/Form/mod/id/'.$value->id.'/action/modform}{$btnqs}" class="layui-btn layui-btn-xs">修改</a>
+								
+	                        </td>
+	                    </tr>
+	                    {/foreach}
+	                </tbody>
+	            </table>
+	            <div class="page">{$pagebar}</div>
+	  	   </div>
+	  	   
+	  	    <div class="layui-tab-item">
+	   			<form action="{url./admin/Form/add/action/addform}" method="post" class="layui-form">
+	   				<input type="hidden" name="formcheck" value="{$formcheck}" > 
+	   				<div class="layui-form-item">
+	                     <label class="layui-form-label">表单名称</label>
+	                     <div class="layui-input-block">
+	                     	<input type="text" name="form_name" maxlength=20 required lay-verify="required"  placeholder="请输入表单名称,如:报名表" class="layui-input">
+	                     </div>
+	                </div>
+	                
+	                <div class="layui-form-item">
+	                     <label class="layui-form-label">表名称</label>
+	                     <div class="layui-input-block">
+	                     	<input type="text" name="table_name" maxlength=30 required lay-verify="required"  placeholder="请输入表名称,如:baoming" class="layui-input">
+	                     </div>
+	                </div>
+	                
+	   				<div class="layui-form-item">
+						 <div class="layui-input-block">
+						    <button class="layui-btn" lay-submit>立即提交</button>
+						    <button type="reset" class="layui-btn layui-btn-primary">重置</button>
+						 </div>
+					</div>
+	   			</form>
+	   	 	</div>
+	   </div>
+	 </div>
+	{/if} 
+	
+	{if([$showdata])}
+	<div class="layui-tab layui-tab-brief" lay-filter="tab">
+	  <ul class="layui-tab-title">
+	    <li class="layui-this" lay-id="t1">{$form->form_name} — 数据</li>
+	  </ul>
+	  <div class="layui-tab-content">
+	  	   <div class="layui-tab-item layui-show">
+	  	   		{foreach $formdata(key,value,num)}
+	  	   		<table class="layui-table table-two">
+	  	   			<thead>
+				  		<tr>
+					  		<th colspan="2">
+					  			{$form->form_name}-[num] 
+					  			<span style="float:right"><a href="{url./admin/Form/del/id/'.$value->id.'/fcode/'.[$form->fcode].'/action/deldata}" onclick="return confirm('您确定要删除么?')" class="layui-btn layui-btn-xs layui-btn-danger" style="margin-bottom:0px" title="删除">删除</a></span>
+					  		</th>
+					  	</tr>
+				    </thead>
+	  	   			<tbody>
+		  	   			{foreach $fields(key2,value2,num2)}
+			  	   			<tr>
+						      	<th>[value2->description]</th>
+						      	{php} $field=$value2->name {/php}
+						      	<td>[value->$field]</td>
+						    </tr>
+		  	   			{/foreach}
+		  	   			<tr>
+					      	<th>时间</th>
+					      	<td>[value->create_time]</td>
+					    </tr>
+	  	   			</tbody>
+	            </table>
+	            {/foreach}
+	            
+	            {if(session('ucode')==10001 && [$formdata])}
+			     	<a href="{url./admin/Form/clear/fcode/'.[$form->fcode].'}"  onclick='return confirm("您确定要清空么?")' class="layui-btn layui-btn-sm">清空记录</a>
+			    {/if}
+			    
+			    {if([$formdata])}
+			    	<a href="{url./admin/Form/index/fcode/'.[$form->fcode].'/action/showdata/export/1}" class="layui-btn layui-btn-sm">导出记录</a>
+			    {/if}
+			    
+	            <div class="page">{$pagebar}</div>
+	  	   </div>
+	  	 </div>
+	  </div>
+	{/if}  	  
+	
+	{if([$showfield])}
+	<div class="layui-tab layui-tab-brief" lay-filter="tab">
+	  <ul class="layui-tab-title">
+	    <li class="layui-this" lay-id="t1">{$form->form_name}-表单字段</li>
+	    <li lay-id="t2">新增字段</li>
+	  </ul>
+	  <div class="layui-tab-content">
+	  	   <div class="layui-tab-item layui-show">
+	  	   		<table class="layui-table">
+	            	<thead>
+	                    <tr>
+	                    	<th width=40>序号</th>
+	                    	<th>描述</th>
+	                    	<th>字段</th>
+	                    	<th>长度</th>
+	                    	<th>是否必填</th>
+	                    	<th>排序</th>
+	                        <th>操作</th>
+	                    </tr>
+	                </thead>
+	                <tbody>
+	                    {foreach $fields(key,value)}
+	                    <tr>
+	                    	<td>[num]</td>
+	                    	<td>[value->description]</td>
+	                    	<td>[value->name]</td>
+	                    	<td>[value->length]</td>
+	                    	<td>
+		                        {if($value->required)}
+		                        <a href="{url./admin/'.C.'/mod/id/'.$value->id.'/field/required/value/0}"><i class='fa fa-toggle-on' title="点击关闭必填"></i></a>
+		                        {else}
+		                        <a href="{url./admin/'.C.'/mod/id/'.$value->id.'/field/required/value/1}"><i class='fa fa-toggle-off' title="点击开启必填"></i></a>
+		                        {/if}
+	                    	</td>
+	                    	<td>[value->sorting]</td>
+	                        <td>
+	                       		<a href="{url./admin/Form/del/id/'.$value->id.'/fcode/'.[$get.fcode].'}" onclick="return confirm('您确定要删除么?')" class="layui-btn layui-btn-xs layui-btn-danger" title="删除">删除</a>
+	                            {fun=get_btn_mod($value->id)}
+	                        </td>
+	                    </tr>
+	                    {/foreach}
+	                </tbody>
+	            </table>
+	            <div class="page">{$pagebar}</div>
+	            <div><a href="{url./admin/Form/index}" class="layui-btn">返回表单</a></div>
+	  	   </div>
+	  	   
+	  	   <div class="layui-tab-item">
+	   			<form action="{url./admin/Form/add}" method="post" class="layui-form">
+					<input type="hidden" name="formcheck" value="{$formcheck}" > 
+	                <div class="layui-form-item">
+	                     <label class="layui-form-label">字段描述</label>
+	                     <div class="layui-input-block">
+	                     	<input type="hidden" value="{$get.fcode}" name="fcode" >
+	                     	<input type="text" name="description" required lay-verify="required"  placeholder="请输入字段描述,如:联系人" class="layui-input">
+	                     </div>
+	                </div>
+	                
+	                <div class="layui-form-item">
+	                     <label class="layui-form-label">字段名称</label>
+	                     <div class="layui-input-block">
+	                     	<input type="text" name="name" required maxlength="20" lay-verify="required"  placeholder="请输入字段名称,必须以字母开头,如:contacts" class="layui-input">
+	                     </div>
+	                </div>
+	                
+	                <div class="layui-form-item">
+	                     <label class="layui-form-label">字段长度</label>
+	                     <div class="layui-input-block">
+	                     	<input type="text" name="length" value="20" required lay-verify="required" class="layui-input">
+	                     </div>
+	                </div>
+	                
+	                <div class="layui-form-item">
+	                     <label class="layui-form-label">是否必填</label>
+	                     <div class="layui-input-block">
+	                     	<input type="radio" name="required" value="1" title="必填" checked>
+							<input type="radio" name="required" value="0" title="非必填"  checked>
+	                     </div>
+	                </div>
+	                
+	                <div class="layui-form-item">
+	                     <label class="layui-form-label">字段排序</label>
+	                     <div class="layui-input-block">
+	                     	<input type="text" name="sorting" value="255" required lay-verify="required" class="layui-input">
+	                     </div>
+	                </div>
+	   			
+	   				<div class="layui-form-item">
+						 <div class="layui-input-block">
+						    <button class="layui-btn" lay-submit>立即提交</button>
+						    <button type="reset" class="layui-btn layui-btn-primary">重置</button>
+						 </div>
+					</div>
+	   			</form>
+	   	 	</div>
+	   	 	
+	   </div>
+	 </div>
+	{/if} 
+	
+	
+	{if(@[$mod])}
+	
+	{if([$form])}
+	<div class="layui-tab layui-tab-brief" lay-filter="tab">
+	  <ul class="layui-tab-title">
+	    <li class="layui-this">自定义表单修改</li>
+	  </ul>
+	  <div class="layui-tab-content">
+	  	<div class="layui-tab-item layui-show">
+	  		<form action="{url./admin/Form/mod/id/'.[$get.id].'/action/modform}{$backurl}" method="post" class="layui-form">
+	  			<input type="hidden" name="formcheck" value="{$formcheck}" > 
+	  			<div class="layui-form-item">
+                     <label class="layui-form-label">表单名称</label>
+                     <div class="layui-input-block">
+                     	<input type="text" name="form_name" maxlength=20 required value="{$form->form_name}" lay-verify="required"  placeholder="请输入表单名称,如:报名表" class="layui-input">
+                     </div>
+                </div>
+                
+                <div class="layui-form-item">
+                     <label class="layui-form-label">表名称</label>
+                     <div class="layui-input-block">
+                     	<input type="text" maxlength=30 required readonly value="{$form->table_name}" lay-verify="required"  placeholder="请输入表名称,如:baoming" class="layui-input readonly">
+                     </div>
+                </div>
+
+   				<div class="layui-form-item">
+					 <div class="layui-input-block">
+					    <button class="layui-btn" lay-submit>立即提交</button>
+					    <button type="reset" class="layui-btn layui-btn-primary">重置</button>
+					    {fun=get_btn_back()}
+					 </div>
+				</div>
+	  		</form>
+	  	</div>
+	  </div>
+	 </div>
+	 {/if} 
+	 
+	 {if(@[$field])}
+	 <div class="layui-tab layui-tab-brief" lay-filter="tab">
+	  <ul class="layui-tab-title">
+	    <li class="layui-this">表单字段修改</li>
+	  </ul>
+	  <div class="layui-tab-content">
+	  	<div class="layui-tab-item layui-show">
+	  		<form action="{url./admin/Form/mod/id/'.[$get.id].'}{$backurl}" method="post" class="layui-form">
+	  			<input type="hidden" name="formcheck" value="{$formcheck}" > 
+                <div class="layui-form-item">
+                     <label class="layui-form-label">字段描述</label>
+                     <div class="layui-input-block">
+                     	<input type="text" name="description"  value="{$field->description}" placeholder="请输入字段描述,如:联系人" class="layui-input">
+                     </div>
+                </div>
+                
+                <div class="layui-form-item">
+                     <label class="layui-form-label">字段名称</label>
+                     <div class="layui-input-block">
+                     	<input type="text" name="name" readonly value="{$field->name}" class="layui-input readonly">
+                     </div>
+                </div>
+                
+                <div class="layui-form-item">
+                     <label class="layui-form-label">字段长度</label>
+                     <div class="layui-input-block">
+                     	<input type="text" name="length" readonly value="{$field->length}" class="layui-input readonly">
+                     </div>
+                </div>
+                
+                <div class="layui-form-item">
+                     <label class="layui-form-label">是否必填</label>
+                     <div class="layui-input-block">
+                     	<input type="radio" name="required" value="1" title="必填" {if([$field->required]==1)}checked{/if}>
+						<input type="radio" name="required" value="0" title="非必填" {if([$field->required]==0)}checked{/if}>
+                     </div>
+                </div>
+                
+                <div class="layui-form-item">
+                     <label class="layui-form-label">字段排序</label>
+                     <div class="layui-input-block">
+                     	<input type="text" name="sorting" value="{$field->sorting}" required lay-verify="required" class="layui-input">
+                     </div>
+                </div>
+   			
+   				<div class="layui-form-item">
+					 <div class="layui-input-block">
+					    <button class="layui-btn" lay-submit>立即提交</button>
+					    <button type="reset" class="layui-btn layui-btn-primary">重置</button>
+					    {fun=get_btn_back()}
+					 </div>
+				</div>
+	  		</form>
+	  	</div>
+	  </div>
+	 </div>
+	 {/if} 
+	 
+	{/if} 
+</div>
+{include file='common/foot.html'}

+ 254 - 0
apps/admin/view/default/content/label.html

@@ -0,0 +1,254 @@
+{include file='common/head.html'}
+
+<div class="layui-body">
+
+	{if([$list])}
+	<div class="layui-tab layui-tab-brief" lay-filter="tab">
+	  <ul class="layui-tab-title">
+	    <li class="layui-this" lay-id="t1">标签内容</li>
+	    <li lay-id="t2">标签管理</li>
+	    <li lay-id="t3">新增标签</li>
+	  </ul>
+	  <div class="layui-tab-content">
+	  	<div class="layui-tab-item layui-show">
+	  		<form action="{url./admin/Label/index}" method="post" class="layui-form">
+	  			<input type="hidden" name="formcheck" value="{$formcheck}" > 
+	  			{foreach $labels(key,value)}
+	  				{if($value->type==1)} <!-- 文本 -->
+		                <div class="layui-form-item">
+		                     <label class="layui-form-label">[value->description]<br><span class="layui-badge layui-bg-gray">{label:[value->name]}</span></label>
+		                     <div class="layui-input-block">
+		                     	<input type="text" name="[value->name]" value="[value->value]" placeholder="请输入[value->description]"  class="layui-input">
+		                     </div>
+		                </div>
+	                {/if}
+	                
+	                {if($value->type==2)}<!-- 日期 -->
+	                	 <div class="layui-form-item">
+		                     <label class="layui-form-label">[value->description]<br><span class="layui-badge layui-bg-gray">{label:[value->name]}</span></label>
+		                     <div class="layui-input-block">
+		                     	<input type="text" name="[value->name]" readonly value="[value->value]" placeholder="请选择[value->description]"  class="layui-input datetime">
+		                     </div>
+		                </div>
+	                {/if}
+	                
+	                {if($value->type==3)}<!-- 图片 -->
+	                	<div class="layui-form-item">
+		                     <label class="layui-form-label">[value->description]<br><span class="layui-badge layui-bg-gray">{label:[value->name]}</span></label>
+		                     <div class="layui-input-inline">
+		                     	<input type="text" name="[value->name]" id="[value->name]" value="[value->value]" placeholder="请上传[value->description]"  class="layui-input">
+		                     </div>
+		                     <button type="button" class="layui-btn upload" data-des="[value->name]">
+							 	 <i class="layui-icon">&#xe67c;</i>上传图片
+							 </button>
+							 <div id="[value->name]_box" class="pic">{if($value->value)}<dl><dt><img src="{SITE_DIR}[value->value]" data-url="[value->value]"></dt><dd>删除</dd></dl>{/if}</div>
+		                </div>
+	                {/if}
+	                
+	                {if($value->type==4)}<!-- 文件 -->
+	                	<div class="layui-form-item">
+		                     <label class="layui-form-label">[value->description]<br><span class="layui-badge layui-bg-gray">{label:[value->name]}</span></label>
+		                     <div class="layui-input-inline">
+		                     	<input type="text" name="[value->name]" id="[value->name]" value="[value->value]" placeholder="请上传[value->description]"  class="layui-input">
+		                     </div>
+		                     <button type="button" class="layui-btn file" data-des="[value->name]">
+							 	 <i class="layui-icon">&#xe67c;</i>上传文件
+							 </button>
+		                </div>
+	                {/if}
+	                
+	                {if($value->type==5)}<!-- 编辑器 -->
+	                	<div class="layui-form-item">
+		                     <label class="layui-form-label">[value->description]<br><span class="layui-badge layui-bg-gray">{label:[value->name]}</span></label>
+		                     <div class="layui-input-block">
+		                     	<script type="text/plain" id="[value->name]" name="[value->name]" style="width:100%;height:240px;">{fun=decode_string($value->value)}</script>
+		                     </div>
+		                </div>
+		                <script>
+							//初始化编辑器
+							$(document).ready(function (e) {
+								var ue = UE.getEditor('[value->name]',{
+									maximumWords:500 
+								});
+							})
+						</script>
+	                {/if}
+	                
+	                {if($value->type==6)} <!-- 开关 -->
+		                <div class="layui-form-item">
+		                     <label class="layui-form-label">[value->description]<br><span class="layui-badge layui-bg-gray">{label:[value->name]}</span></label>
+		                     <div class="layui-input-block">
+		                     	<input type="radio" name="[value->name]" value="1" title="开启" {if($value->value)}checked{/if}>
+      							<input type="radio" name="[value->name]" value="0" title="关闭" {if(!$value->value)}checked{/if}>
+		                     </div>
+		                </div>
+	                {/if}
+	                
+	                {if($value->type==7)} <!-- 多行文本 -->
+		                <div class="layui-form-item">
+		                     <label class="layui-form-label">[value->description]<br><span class="layui-badge layui-bg-gray">{label:[value->name]}</span></label>
+		                     <div class="layui-input-block">
+		                     	<textarea name="[value->name]" class="layui-textarea" placeholder="请输入[value->description]">{fun=str_replace("<br>","\r\n",html_entity_decode($value->value))}</textarea>
+		                     </div>
+		                </div>
+	                {/if}
+	                
+	  			{/foreach}
+	  			<div class="layui-form-item">
+					 <div class="layui-input-block">
+					    <button class="layui-btn" lay-submit>立即提交</button>
+					    <button type="reset" class="layui-btn layui-btn-primary">重置</button>
+					 </div>
+				</div>
+	  		</form>
+	  	</div>
+	  	
+	  	<div class="layui-tab-item">
+	  		<table class="layui-table">
+            	<thead>
+                    <tr>
+                        <th>序号</th>
+                        <th>名称</th>
+                        <th>描述</th>
+                        <th>类型</th>
+                        <th>添加人员</th>
+                        <th>修改人员</th>
+                        <th>添加时间</th>
+                        <th>修改时间</th>
+                        <th>操作</th>
+                    </tr>
+        		</thead>
+                <tbody>
+                {foreach $labels(key,value,num)}
+                    <tr>
+                        <td>[num]</td>
+                        <td>[value->name]</td>
+                        <td>[value->description]</td>
+                        <td>
+                        {if($value->type==1)}单行文本{/if}
+                        {if($value->type==7)}多行文本{/if}
+                        {if($value->type==2)}时间{/if}
+                        {if($value->type==3)}图片{/if}
+                        {if($value->type==4)}附件{/if}
+                        {if($value->type==5)}编辑器{/if}
+                        {if($value->type==6)}开关{/if}
+                        </td>
+                        <td>[value->create_user]</td>
+                        <td>[value->update_user]</td>
+                        <td>[value->create_time]</td>
+                        <td>[value->update_time]</td>
+                        <td>
+                            {fun=get_btn_del($value->id)}
+                            {fun=get_btn_mod($value->id)}
+                        </td>
+                    </tr>
+                {/foreach}
+                </tbody>
+            </table>
+	  	</div>
+	  	
+	  	<div class="layui-tab-item">
+	  		 <form action="{url./admin/Label/add}" method="post" class="layui-form">
+	  		 	<input type="hidden" name="formcheck" value="{$formcheck}" > 
+	  		 	<div class="layui-form-item">
+                     <label class="layui-form-label">标签名称</label>
+                     <div class="layui-input-block">
+                     	<input type="text" name="name" required  lay-verify="required" placeholder="请输入标签名称"  class="layui-input">
+                     	<div class="layui-form-mid layui-word-aux">只能含有字母、数字、下划线</div>
+                     </div>
+                     
+                </div>
+                
+                <div class="layui-form-item">
+                     <label class="layui-form-label">标签描述</label>
+                     <div class="layui-input-block">
+                     	<input type="text" name="description" required  lay-verify="required" placeholder="请输入标签描述"  class="layui-input">
+                     </div>
+                </div>
+                
+                <div class="layui-form-item">
+                     <label class="layui-form-label">标签类型</label>
+                     <div class="layui-input-block">
+                     	<select name="type" lay-verify="required">
+	                    	<option value="1">单行文本</option>
+	                    	<option value="7">多行文本</option>
+	                    	<option value="2">时间</option>
+	                    	<option value="3">图片</option>
+	                    	<option value="4">附件</option>
+	                    	<option value="5">编辑器</option>
+	                    	<option value="6">开关</option>
+	                    </select>
+                     </div>
+                </div>
+                
+                <div class="layui-form-item">
+					 <div class="layui-input-block">
+					    <button class="layui-btn" lay-submit>立即提交</button>
+					    <button type="reset" class="layui-btn layui-btn-primary">重置</button>
+					 </div>
+				</div>
+	  		 </form>
+	  	</div>
+	  	
+	  </div>
+	</div>
+	{/if} 
+	
+	
+	{if([$mod])}
+	
+	<div class="layui-tab layui-tab-brief" lay-filter="tab">
+	  <ul class="layui-tab-title">
+	    <li class="layui-this">标签修改</li>
+	  </ul>
+	  <div class="layui-tab-content">
+	  	<div class="layui-tab-item layui-show">
+	  		  <form action="{url./admin/Label/mod/id/'.[$get.id].'}{$backurl}" method="post" class="layui-form">
+	  		  	<input type="hidden" name="formcheck" value="{$formcheck}" > 
+	  		  	<div class="layui-form-item">
+                     <label class="layui-form-label">标签名称</label>
+                     <div class="layui-input-block">
+                     	<input type="text" name="name" required  lay-verify="required" value="{$label->name}"  placeholder="请输入标签名称"  class="layui-input">
+                     	<div class="layui-form-mid layui-word-aux">只能含有字母、数字、下划线</div>
+                     </div>
+                     
+                </div>
+                
+                <div class="layui-form-item">
+                     <label class="layui-form-label">标签描述</label>
+                     <div class="layui-input-block">
+                     	<input type="text" name="description" required  lay-verify="required"  value="{$label->description}" placeholder="请输入标签描述"  class="layui-input">
+                     </div>
+                </div>
+                
+                <div class="layui-form-item">
+                     <label class="layui-form-label">标签类型</label>
+                     <div class="layui-input-block">
+                     	<select name="type" lay-verify="required">
+	                    	<option value="1" {if([$label->type]==1)}selected{/if}>单行文本</option>
+	                    	<option value="7" {if([$label->type]==7)}selected{/if}>多行文本</option>
+	                    	<option value="2" {if([$label->type]==2)}selected{/if}>时间</option>
+	                    	<option value="3" {if([$label->type]==3)}selected{/if}>图片</option>
+	                    	<option value="4" {if([$label->type]==4)}selected{/if}>附件</option>
+	                    	<option value="5" {if([$label->type]==5)}selected{/if}>编辑器</option>
+	                    	<option value="6" {if([$label->type]==6)}selected{/if}>开关</option>
+	                    </select>
+                     </div>
+                </div>
+                
+                <div class="layui-form-item">
+					 <div class="layui-input-block">
+					    <button class="layui-btn" lay-submit>立即提交</button>
+					    <button type="reset" class="layui-btn layui-btn-primary">重置</button>
+					    {fun=get_btn_back()}
+					 </div>
+				</div>
+	  		  </form>
+	  	</div>
+	  </div>
+	 </div>
+	{/if}
+
+</div>
+{include file='common/ueditor.html'}
+{include file='common/foot.html'}

+ 170 - 0
apps/admin/view/default/content/link.html

@@ -0,0 +1,170 @@
+{include file='common/head.html'}
+
+<div class="layui-body">
+	{if([$list])}
+	<div class="layui-tab layui-tab-brief" lay-filter="tab">
+	  <ul class="layui-tab-title">
+	    <li class="layui-this" lay-id="t1">友情链接列表</li>
+	    <li lay-id="t2">友情链接新增</li>
+	  </ul>
+	  <div class="layui-tab-content">
+	  	<div class="layui-tab-item layui-show">
+	  		<form action="{url./admin/Link/mod}" method="post" class="layui-form" onkeydown="if(event.keyCode==13) return false;">
+		   	 <input type="hidden" name="formcheck" value="{$formcheck}" > 
+	  		<table class="layui-table">
+	  			<thead>
+                    <tr>
+                    	<th>分组(gid)</th>
+                        <th>名称</th>
+                        <th>链接</th>
+                        <th>Logo</th>
+                        <th>排序</th>
+                        <th>操作</th>
+                    </tr>
+                </thead>
+                <tbody>
+                    {foreach $links(key,value)}
+                    <tr>
+                    	<td>[value->gid]</td>
+                        <td>[value->name]</td>
+                        <td>[value->link]</td>
+                        <td><img src="{SITE_DIR}[value->logo]" style="height:20px;"></td>
+                        <td class="table-input">
+                        	<input type="hidden" name="listall[]" value="[value->id]">
+                        	<input type="text" lay-ignore class="layui-input" name="sorting[]" value="[value->sorting]">
+                        </td>
+                        <td>
+                            {fun=get_btn_del($value->id)}
+                            {fun=get_btn_mod($value->id)}
+                        </td>
+                    </tr>
+                    {/foreach}
+                </tbody>
+	  		</table>
+	  		 <button type="submit" name="submit" value="sorting" class="layui-btn layui-btn-sm">保存排序</button>
+            </form>
+	  		<div class="page">{$pagebar}</div>
+	  	</div>
+	  	<div class="layui-tab-item">
+	  		 <form action="{url./admin/Link/add}" method="post" class="layui-form">
+	  		 	<input type="hidden" name="formcheck" value="{$formcheck}" > 
+	  		 	<div class="layui-form-item">
+                     <label class="layui-form-label">分组</label>
+                     <div class="layui-input-block">
+                     	<select name="gid">	
+                     		{foreach $gids(key,value)}
+	                			<option value="[value]" >分组[value]</option>
+	                		{/foreach}
+	                		<option value="" >自动新增分组</option>
+	                	</select>
+                     </div>
+                </div>
+                
+                 <div class="layui-form-item">
+                     <label class="layui-form-label">名称</label>
+                     <div class="layui-input-block">
+                     	<input type="text" name="name" required  lay-verify="required" placeholder="请输入名称"  class="layui-input">
+                     </div>
+                </div>
+                
+                <div class="layui-form-item">
+                     <label class="layui-form-label">链接</label>
+                     <div class="layui-input-block">
+                     	<input type="text" name="link" required  lay-verify="required" placeholder="请输入链接"  class="layui-input">
+                     </div>
+                </div>
+                
+                <div class="layui-form-item">
+                     <label class="layui-form-label">图片</label>
+                     <div class="layui-input-inline">
+                     	<input type="text" name="logo" id="logo" placeholder="请上传图片"  class="layui-input">
+                     </div>
+                     <button type="button" class="layui-btn upload" data-des="logo">
+					 	 <i class="layui-icon">&#xe67c;</i>上传图片
+					 </button>
+					 <div id="logo_box" class="pic"></div>
+                </div>
+                
+                <div class="layui-form-item">
+                     <label class="layui-form-label">排序</label>
+                     <div class="layui-input-block">
+                     	<input type="text" name="sorting" required lay-verify="required" value="255" placeholder="请输入排序"  class="layui-input">
+                     </div>
+                </div>
+                
+                <div class="layui-form-item">
+					 <div class="layui-input-block">
+					    <button class="layui-btn" lay-submit>立即提交</button>
+					    <button type="reset" class="layui-btn layui-btn-primary">重置</button>
+					 </div>
+				</div>
+	  		 </form>
+	  	</div>
+	  </div>
+	</div>
+	{/if} 
+	
+	{if([$mod])}
+	<div class="layui-tab layui-tab-brief" lay-filter="tab">
+	  <ul class="layui-tab-title">
+	    <li class="layui-this">友情链接修改</li>
+	  </ul>
+	  <div class="layui-tab-content">
+	  	<div class="layui-tab-item layui-show">
+	  		 <form action="{url./admin/Link/mod/id/'.[$get.id].'}{$backurl}" method="post" class="layui-form">
+	  		 	<input type="hidden" name="formcheck" value="{$formcheck}" > 
+
+                <div class="layui-form-item">
+                     <label class="layui-form-label">分组</label>
+                     <div class="layui-input-block">
+                     	<input type="text" name="gid" required  lay-verify="required" value="{$link->gid}" placeholder="请输入分组"  class="layui-input">
+                     </div>
+                </div>
+                
+                <div class="layui-form-item">
+                     <label class="layui-form-label">名称</label>
+                     <div class="layui-input-block">
+                     	<input type="text" name="name" required  lay-verify="required" value="{$link->name}" placeholder="请输入名称"  class="layui-input">
+                     </div>
+                </div>
+                
+                <div class="layui-form-item">
+                     <label class="layui-form-label">链接</label>
+                     <div class="layui-input-block">
+                     	<input type="text" name="link" required  lay-verify="required" value="{$link->link}" placeholder="请输入链接"  class="layui-input">
+                     </div>
+                </div>
+                
+                <div class="layui-form-item">
+                     <label class="layui-form-label">图片</label>
+                     <div class="layui-input-inline">
+                     	<input type="text" name="logo" id="logo" placeholder="请上传图片"  value="{$link->logo}" class="layui-input">
+                     </div>
+                     <button type="button" class="layui-btn upload" data-des="logo">
+					 	 <i class="layui-icon">&#xe67c;</i>上传图片
+					 </button>
+					 <div id="logo_box" class="pic">{if([$link->logo])}<dl><dt><img src="{SITE_DIR}{$link->logo}" data-url="{$link->logo}"></dt><dd>删除</dd></dl>{/if}</div>
+                </div>
+                
+                 <div class="layui-form-item">
+                     <label class="layui-form-label">排序</label>
+                     <div class="layui-input-block">
+                     	<input type="text" name="sorting" required lay-verify="required" value="{$link->sorting}" placeholder="请输入排序"  class="layui-input">
+                     </div>
+                </div>
+                
+                 <div class="layui-form-item">
+					 <div class="layui-input-block">
+					    <button class="layui-btn" lay-submit>立即提交</button>
+					    <button type="reset" class="layui-btn layui-btn-primary">重置</button>
+					    {fun=get_btn_back()}
+					 </div>
+				</div>
+				
+	  		 </form>
+	  	</div>
+	  </div>
+	 </div>
+	{/if} 
+</div>
+{include file='common/foot.html'}

+ 148 - 0
apps/admin/view/default/content/message.html

@@ -0,0 +1,148 @@
+{include file='common/head.html'}
+
+<div class="layui-body">
+	{if([$list])}
+	<div class="layui-tab layui-tab-brief" lay-filter="tab">
+	  <ul class="layui-tab-title">
+	    <li class="layui-this" lay-id="t1">留言列表</li>
+	  </ul>
+	  <div class="layui-tab-content">
+		  <form method="get" name="contentForm" >
+	  	   <div class="layui-tab-item layui-show">
+	  	   		{foreach $messages(key,value,num)}
+	  	   		<table class="layui-table table-two">
+	  	   			<thead>
+				  		<tr>
+					  		<th colspan="2">
+								<input type="checkbox" name="checkbox" title="选择" lay-skin="primary" class="check" value="[value->id]">
+								<input type="hidden" name="listall[]" value="[value->id]">
+								在线留言-[num]
+					  			<span style="float:right">
+						  			{if($value->status)}
+		                            <a href="{url./admin/'.C.'/mod/id/'.$value->id.'/field/status/value/0}"><i class='fa fa-toggle-on' title="点击前端隐藏" style="vertical-align:middle"></i></a>
+		                            {else}
+		                            <a href="{url./admin/'.C.'/mod/id/'.$value->id.'/field/status/value/1}"><i class='fa fa-toggle-off' title="点击前端显示" style="vertical-align:middle"></i></a>
+		                            {/if}
+						  			{fun=get_btn_mod($value->id,'id','回复')}
+						  			{fun=get_btn_del($value->id)}
+					  			</span>
+					  		</th>
+					  	</tr>
+				    </thead>
+	  	   			<tbody>
+		  	   			{foreach $fields(key2,value2,num2)}
+			  	   			<tr>
+						      	<th>[value2->description]</th>
+						      	{php} $field=$value2->name {/php}
+						      	<td>[value->$field]</td>
+						    </tr>
+		  	   			{/foreach}
+		  	   			<tr>
+					      	<th>时间</th>
+					      	<td>[value->create_time]</td>
+					    </tr>
+					    <tr>
+					      	<th>访客信息</th>
+					      	<td>
+					      		IP:<a href="http://ip.taobao.com/ipSearch.html?ipAddr={fun=long2ip($value->user_ip)}" target="_blank" title="点击查看归属地">{fun=long2ip($value->user_ip)}</a>;
+								浏览器:[value->user_bs];
+								操作系统:[value->user_os]
+							</td>
+					    </tr>
+					    {if($value->username)}
+					    <tr>
+					      	<th>会员账号</th>
+					      	<td>[value->username]([value->nickname])</td>
+					    </tr>
+					    {/if}
+					    <tr>
+					      	<th>回复内容</th>
+					      	<td>[value->recontent]</td>
+					    </tr>
+	  	   			</tbody>
+	            </table>
+	            {/foreach}
+	            
+	            {if(session('ucode')==10001 && [$messages])}
+			     	<a href="{url./admin/Message/clear}"  onclick='return confirm("您确定要全部清空么?")' class="layui-btn layui-btn-sm">清空全部记录</a>
+			   		<a href="javascript:" onclick="selectall('checkbox')" class="layui-btn layui-btn-sm">全选</a>
+			   		<a href="javascript:" onclick="delselect(this);return false" class="layui-btn layui-btn-sm">清空选中记录</a>
+			    {/if}
+			    
+			    {if([$messages])}
+			    <a href="{url./admin/Message/index/export/1}" class="layui-btn layui-btn-sm">导出记录</a>
+			    {/if}
+			    
+	            <div class="page">{$pagebar}</div>
+	  	   </div>
+		  </form>
+	  	 </div>
+	</div>
+	{/if}
+	
+	{if([$mod])}
+	
+	<div class="layui-tab layui-tab-brief" lay-filter="tab">
+	  <ul class="layui-tab-title">
+	    <li class="layui-this">留言回复</li>
+	  </ul>
+	  <div class="layui-tab-content">
+	  	<div class="layui-tab-item layui-show">
+	  		 <form action="{url./admin/Message/mod/id/'.[$get.id].'}{$backurl}" method="post" class="layui-form">
+	  		 	<input type="hidden" name="formcheck" value="{$formcheck}" > 
+	  		 	<div class="layui-form-item">
+                     <label class="layui-form-label">回复内容</label>
+                     <div class="layui-input-block">
+                     	<textarea name="recontent" placeholder="请输入回复内容" class="layui-textarea">{$message->recontent}</textarea>
+                     </div>
+                </div>
+                
+                <div class="layui-form-item">
+                    <label class="layui-form-label">状态</label>
+                    <div class="layui-input-block">
+                    	<input type="radio" name="status" value="1" title="显示" {if([$message->status]==1)}checked="checked"{/if}>
+						<input type="radio" name="status" value="0" title="隐藏" {if([$message->status]==0)}checked="checked"{/if}>
+                    </div>
+                </div>
+                
+	  		 	<div class="layui-form-item">
+				 <div class="layui-input-block">
+				    <button class="layui-btn" lay-submit lay-filter="formDemo">立即提交</button>
+				    <button type="reset" class="layui-btn layui-btn-primary">重置</button>
+				    {fun=get_btn_back()}
+				 </div>
+			   </div>
+			   
+	  		 </form>
+	  	</div>
+	  </div>
+	 </div>
+
+	{/if} 
+	
+</div>
+<script>
+
+	function selectall(objName){
+		var objNameList=document.getElementsByName(objName);
+		if(null!=objNameList){
+			for(var i=0;i<objNameList.length;i++){
+				objNameList[i].checked="checked";
+			}
+		}
+	}
+
+	function delselect(obj){
+		if(confirm("您确定要删除选中的内容么?")){
+			var check_list = [];
+			$('input[name="checkbox"]:checked').each(function (){
+				check_list.push($(this).val());
+			});
+			var url = $(obj).attr("href");
+			var str = check_list.join("and");
+			// $(obj).attr("href", url + "" + str);
+			location.href = "{url./admin/Message/clear}/ids/" + str;
+		}
+	}
+</script>
+{include file='common/foot.html'}

+ 191 - 0
apps/admin/view/default/content/model.html

@@ -0,0 +1,191 @@
+{include file='common/head.html'}
+
+<div class="layui-body">
+	{if([$list])}
+	<div class="layui-tab layui-tab-brief" lay-filter="tab">
+	  <ul class="layui-tab-title">
+	    <li class="layui-this" lay-id="t1">模型列表</li>
+	    <li lay-id="t2">模型新增</li>
+	  </ul>
+	  <div class="layui-tab-content">
+	  	   <div class="layui-tab-item layui-show">
+	  	   		 <table class="layui-table">
+	            	<thead>
+	                    <tr>
+	                    	<th>序号</th>
+	                        <th>名称</th>
+	                        <th>类型</th>
+	                        <th>URL名称</th>
+	                        <th>列表页模板</th>
+	                        <th>详情页模板</th>
+	                        <th>状态</th>
+	                        <th>操作</th>
+	                    </tr>
+	                </thead>
+	                <tbody>
+	                    {foreach $models(key,value)}
+	                    <tr>
+	                    	<td>[num]</td>
+	                        <td>[value->name]</td>
+	                        <td>
+								{if($value->type==1)}单页{/if}
+	                        	{if($value->type==2)}列表{/if}
+							</td>
+							<td>[value->urlname]</td>
+	                        <td>[value->listtpl]</td>
+	                        <td>[value->contenttpl]</td>
+	                        <td>
+	                            {if($value->status)}
+	                            <a href="{url./admin/'.C.'/mod/id/'.$value->id.'/field/status/value/0}" class="switch"><i class='fa fa-toggle-on' title="点击禁用"></i></a>
+	                            {else}
+	                            <a href="{url./admin/'.C.'/mod/id/'.$value->id.'/field/status/value/1}" class="switch"><i class='fa fa-toggle-off' title="点击启用"></i></a>
+	                            {/if}
+	                        </td>
+	                        <td>
+	                        	{if(!$value->issystem)}
+	                            	{fun=get_btn_del($value->id)}
+	                            {/if}
+	                            {fun=get_btn_mod($value->id)}
+	                        </td>
+	                    </tr>
+	                    {/foreach}
+	                </tbody>
+	            </table>
+	            <div class="page">{$pagebar}</div>
+	  	   </div>
+	  	   
+	  	   <div class="layui-tab-item">
+	  	   		<form action="{url./admin/Model/add}" method="post" class="layui-form">
+	                <input type="hidden" name="formcheck" value="{$formcheck}" > 
+	                <div class="layui-form-item">
+	                     <label class="layui-form-label">模型名称  <span class="layui-text-red">*</span></label>
+	                     <div class="layui-input-block">
+	                     	<input type="text" name="name" required lay-verify="required" placeholder="请输入模型名称" class="layui-input">
+	                     </div>
+	                </div>
+	                
+	                 <div class="layui-form-item">
+	                     <label class="layui-form-label">模型类型  <span class="layui-text-red">*</span></label>
+	                     <div class="layui-input-block">
+	                     	 <select name="type" lay-verify="required">
+		                     	<option value="">请选择模型类型</option>
+		                        <option value="1">单页</option>
+		                        <option value="2">列表</option>
+		                    </select>
+	                     </div>
+	                </div>
+	                
+	                <div class="layui-form-item">
+	                     <label class="layui-form-label">URL名称 </label>
+	                     <div class="layui-input-block">
+	                     	<input type="text" name="urlname"  placeholder="请输入URL地址名称,如:news" class="layui-input">
+	                     </div>
+	                </div>
+	                
+	                <div class="layui-form-item">
+	                     <label class="layui-form-label">列表页模板</label>
+	                     <div class="layui-input-block">
+	                     	<input type="text" name="listtpl" placeholder="请输入列表页模板" class="layui-input">
+	                     </div>
+	                </div>
+	                
+	                <div class="layui-form-item">
+	                     <label class="layui-form-label">详情页模板</label>
+	                     <div class="layui-input-block">
+	                     	<input type="text" name="contenttpl" placeholder="请输入详情页模板" class="layui-input">
+	                     </div>
+	                </div>
+	                
+	                <div class="layui-form-item">
+	                     <label class="layui-form-label">状态</label>
+	                     <div class="layui-input-block">
+	                     	<input type="radio" name="status" value="1" title="启用" checked>
+							<input type="radio" name="status" value="0" title="禁用">
+	                     </div>
+	                </div>
+	  	   		
+	  	   			<div class="layui-form-item">
+						 <div class="layui-input-block">
+						    <button class="layui-btn" lay-submit>立即提交</button>
+						    <button type="reset" class="layui-btn layui-btn-primary">重置</button>
+						 </div>
+					</div>
+
+	  	   		</form>
+	  	   </div>
+	  </div>
+	</div>
+	{/if} 
+	
+	{if([$mod])}
+	<div class="layui-tab layui-tab-brief" lay-filter="tab">
+	  <ul class="layui-tab-title">
+	    <li class="layui-this">模型修改</li>
+	  </ul>
+	  <div class="layui-tab-content">
+	  	<div class="layui-tab-item layui-show">
+	  		<form action="{url./admin/Model/mod/id/'.[$get.id].'}{$backurl}" method="post" class="layui-form">
+	  			<input type="hidden" name="formcheck" value="{$formcheck}" > 
+	  			<div class="layui-form-item">
+                     <label class="layui-form-label">模型名称 <span class="layui-text-red">*</span></label>
+                     <div class="layui-input-block">
+                     	<input type="text" name="name" required lay-verify="required" value="{$model->name}" placeholder="请输入模型名称" class="layui-input">
+                     </div>
+                </div>
+                
+                 <div class="layui-form-item">
+                     <label class="layui-form-label">模型类型  <span class="layui-text-red">*</span></label>
+                     <div class="layui-input-block">
+                     	 <select name="type" lay-verify="required">
+	                     	<option value="">请选择模型类型</option>
+	                        <option value="1" {if([$model->type]==1)}selected{/if}>单页</option>
+	                        <option value="2" {if([$model->type]==2)}selected{/if}>列表</option>
+	                    </select>
+                     </div>
+                </div>
+                
+                <div class="layui-form-item">
+                     <label class="layui-form-label">URL名称</label>
+                     <div class="layui-input-block">
+                     	<input type="text" name="urlname" value="{$model->urlname}" placeholder="请输入URL地址名称,如:news" class="layui-input">
+                     </div>
+                </div>
+                
+                <div class="layui-form-item">
+                     <label class="layui-form-label">列表页模板</label>
+                     <div class="layui-input-block">
+                     	<input type="text" name="listtpl" value="{$model->listtpl}" placeholder="请输入列表页模板" class="layui-input">
+                     </div>
+                </div>
+                
+                <div class="layui-form-item">
+                     <label class="layui-form-label">详情页模板</label>
+                     <div class="layui-input-block">
+                     	<input type="text" name="contenttpl"  value="{$model->contenttpl}" placeholder="请输入详情页模板" class="layui-input">
+                     </div>
+                </div>
+                
+                <div class="layui-form-item">
+                     <label class="layui-form-label">状态</label>
+                     <div class="layui-input-block">
+                     	<input type="radio" name="status" value="1" title="启用" {if([$model->status]==1)}checked{/if}>
+						<input type="radio" name="status" value="0" title="禁用" {if([$model->status]==0)}checked{/if}>
+                     </div>
+                </div>
+  	   		
+  	   			<div class="layui-form-item">
+					 <div class="layui-input-block">
+					    <button class="layui-btn" lay-submit>立即提交</button>
+					    <button type="reset" class="layui-btn layui-btn-primary">重置</button>
+					    {fun=get_btn_back()}
+					 </div>
+				</div>	
+	  		</form>
+	  	</div>
+	  </div>
+	 </div>
+	{/if} 
+
+</div>
+
+{include file='common/foot.html'}

+ 426 - 0
apps/admin/view/default/content/single.html

@@ -0,0 +1,426 @@
+{include file='common/head.html'}
+
+<div class="layui-body">
+	{if([$list])}
+	<div class="layui-tab layui-tab-brief" lay-filter="tab">
+	  <ul class="layui-tab-title">
+	    <li class="layui-this" lay-id="t1">{$model_name}内容</li>
+	  </ul>
+	  <div class="layui-tab-content">
+	  	   <div class="layui-tab-item layui-show">
+	  	   		<form action="{url./admin/Single/index/mcode/'.get('mcode').'}" method="get" class="layui-form">
+		  	   		<div class="layui-form-item nospace">
+		  	   			<div class="layui-input-inline">
+		  	   				{$pathinfo}
+					       <select name="field" class="form-control input-sm" style="width:auto;">
+					       		<option value="b.name" {if(get('field')=='b.name')}selected="selected" {/if}>栏目名称</option>
+                                <option value="a.title" {if(get('field')=='a.title')}selected="selected" {/if} >文章标题</option>
+                                <option value="a.content" {if(get('field')=='a.content')}selected="selected" {/if}>文章内容</option>
+                        	</select>
+					    </div>
+	                     <div class="layui-input-inline">
+	                     	<input type="text" name="keyword"  value="{$get.keyword}"  placeholder="请输入搜索关键字" class="layui-input">
+	                     </div>
+	                     <div class="layui-input-inline">
+	                     	<button class="layui-btn" lay-submit>搜索</button>
+	                     	<a class="layui-btn layui-btn-primary"  href="{url./admin/Single/index/mcode/'.get('mcode').'}">清除搜索</a>
+	                     </div>
+	                </div>
+                </form>
+
+	            <table class="layui-table">
+	            	<thead>
+	                    <tr>
+	                    	<th>ID</th>
+	                        <th>栏目</th>
+	                        <th>标题</th>
+	                        <th>时间</th>
+	                        <th>状态</th>
+	                        <th>访问量</th>
+	                        <th>操作</th>
+	                    </tr>
+	                </thead>
+	                <tbody>
+	                    {foreach $contents(key,value)}
+	                    <tr>
+	                    	<td>[value->id]</td>
+	                        <td title="[value->scode]">[value->sortname]</td>
+	                         <td title="[value->title]">
+		                        {fun=substr_both($value->title,0,15)}
+		                        {if($value->ico)}
+		                        	<span class="layui-badge layui-bg-orange">缩</span>
+		                        {/if}
+		                        {if($value->pics)}
+		                        	<span class="layui-badge">图</span>
+		                        {/if}
+		                        {if($value->outlink)}
+	                            	<span class="layui-badge layui-bg-black">链</span>
+	                            {/if}
+	                        </td>
+	                        <td>[value->date]</td>
+	                        <td>
+	                        {if($value->status)}
+		                        <a href="{url./admin/'.C.'/mod/id/'.$value->id.'/field/status/value/0}" class="switch"><i class='fa fa-toggle-on' title="点击关闭"></i></a>
+		                        {else}
+		                        <a href="{url./admin/'.C.'/mod/id/'.$value->id.'/field/status/value/1}" class="switch"><i class='fa fa-toggle-off' title="点击开启"></i></a>
+		                    {/if}
+		                    </td>
+		                    <td>[value->visits]</td>
+	                        <td>
+	                        	{if(!$value->outlink)}
+	                        		{php}
+			                        		$Parser=new app\home\controller\ParserController();
+			                        		$link=$Parser->parserLink(1,$value->urlname,'about',$value->scode,$value->filename,'','');
+			                       {/php}
+		                        	<a href="{php}echo $link{/php}" class="layui-btn layui-btn-xs layui-btn-primary"  target="_blank">查看</a>
+	                        	{/if}
+	                        	
+	                            {if(check_level('mod'))}
+	                            	<a href="{url./admin/Single/mod/mcode/'.$value->mcode.'/id/'.$value->id.'}{$btnqs}" class="layui-btn layui-btn-xs" >修改</a>
+	                            	{if([$baidu_zz_token] && !$value->outlink)}
+	                            		<a href="{url./admin/'.C.'/mod/baiduzz/'.$value->id.'}" class="layui-btn layui-btn-xs layui-btn-primary" >百度普通推送</a>
+	                            	{/if}
+	                            	{if([$baidu_ks_token] && !$value->outlink)}
+	                            		<a href="{url./admin/'.C.'/mod/baiduks/'.$value->id.'}" class="layui-btn layui-btn-xs layui-btn-primary" >百度快速推送</a>
+	                            	{/if}
+	                            {/if}
+	                        </td>
+	                    </tr>
+	                    {/foreach}
+	                </tbody>
+	            </table>
+	  	   </div>
+	  </div>
+	 </div>
+	{/if} 
+	
+	{if([$mod])}
+	
+	<div class="layui-tab layui-tab-brief" lay-filter="tab">
+	  <ul class="layui-tab-title">
+	    <li class="layui-this">单页修改</li>
+	  </ul>
+	  <div class="layui-tab-content">
+	  	<div class="layui-tab-item layui-show">
+	  		<form action="{url./admin/Single/mod/id/'.[$get.id].'}{$backurl}" method="post" class="layui-form" id="edit">
+	  			<input type="hidden" name="formcheck" value="{$formcheck}" > 
+	  			<div class="layui-tab">
+					  <ul class="layui-tab-title">
+					    <li class="layui-this">基本内容</li>
+					    <li>高级内容</li>
+					  </ul>
+					  <div class="layui-tab-content">
+					    <div class="layui-tab-item layui-show">
+
+			                <div class="layui-form-item">
+			                     <label class="layui-form-label">内容标题   <span class="layui-text-red">*</span></label>
+			                     <div class="layui-input-block">
+			                     	<input type="text" name="title" required lay-verify="required" value="{$content->title}" placeholder="请输入内容标题" class="layui-input">
+			                     </div>
+			                </div>
+			                
+			                 {foreach $extfield(key,value)}
+			                	{if($value->type==1)} <!-- 单行文本 -->
+			                	<div class="layui-form-item">
+			                		<label class="layui-form-label">[value->description]</label>
+			                		<div class="layui-input-block">
+				                    	<input type="text" name="[value->name]" value="{$content->{$value->name}}"  placeholder="请输入[value->description]"  class="layui-input">
+				                	</div>
+				                </div>
+			                	{/if}
+			                	
+			                	{if($value->type==2)}<!-- 多行文本 -->
+			                	<div class="layui-form-item">
+			                		<label class="layui-form-label">[value->description]</label>
+			                		<div class="layui-input-block">
+				                		<textarea name="[value->name]" class="layui-textarea" placeholder="请输入[value->description]">{php}$name=$value->name;echo str_replace('<br>', "\r\n",$this->vars['content']->$name);{/php}</textarea>
+				                	</div>
+				                </div>
+			                	{/if}
+			                	
+			                    {if($value->type==3)}<!-- 单选 -->
+			                	<div class="layui-form-item">
+			                		<label class="layui-form-label">[value->description]</label>
+			                		<div class="layui-input-block">
+				                		<div>
+	            						     {php}
+				                				$radios=explode(',',$value->value);
+				                				$name=$value->name;
+				                				foreach ($radios as $value2) {
+				                					if($this->vars['content']->$name==$value2){
+	                									echo '<input type="radio" name="'.$value->name.'" value="'.$value2.'" title="'.$value2.'" checked>';
+	                								}else{
+	                									echo '<input type="radio" name="'.$value->name.'" value="'.$value2.'" title="'.$value2.'">';
+	                								}
+	            								}
+	            						     {/php}
+					                    </div>
+				                	</div>
+				                </div>
+			                	{/if}
+			                	
+			                    {if($value->type==4)}<!-- 多选 -->
+			                	<div class="layui-form-item">
+			                		<label class="layui-form-label">[value->description]</label>
+			                		<div class="layui-input-block">
+				                		<div>
+	            						     {php}
+				                				$checkboxs=explode(',',$value->value);
+				                				$name=$value->name;
+				                				echo '<input name="'.$value->name.'" type="hidden">';//占位清空
+				                				$values=explode(',',$this->vars['content']->$name);
+				                				foreach ($checkboxs as $value2) {
+				                					if(in_array($value2,$values)){
+	            										echo '<input type="checkbox" name="'.$value->name.'[]" value="'.$value2.'" title="'.$value2.'" checked>';
+	            									}else{
+	            										echo '<input type="checkbox" name="'.$value->name.'[]" value="'.$value2.'" title="'.$value2.'">';
+	            									}
+	            								}
+	            						     {/php}
+					                    </div>
+				                	</div>
+				                </div>
+			                	{/if}
+			                	
+			                	{if($value->type==5)}<!-- 图片 -->
+			                	<div class="layui-form-item">
+			                		<label class="layui-form-label">[value->description]</label>
+			                		<div class="layui-input-inline">
+				                     	<input type="text" name="[value->name]" id="[value->name]" value="{$content->{$value->name}}" placeholder="请上传[value->description]"  class="layui-input">
+				                     </div>
+				                     <button type="button" class="layui-btn upload watermark" data-des="[value->name]">
+									 	 <i class="layui-icon">&#xe67c;</i>上传图片
+									 </button>
+									 {php}$name=$value->name; {/php}
+									 <div id="[value->name]_box" class="pic"><dl><dt>{if([$content]->$name)}<img src='{SITE_DIR}{$content->{$value->name}}' data-url="{$content->{$value->name}}"></dt><dd>删除</dd></dl>{/if}</div>
+				                </div>
+			                	{/if}
+			                	
+			                	{if($value->type==6)}<!-- 文件 -->
+			                	<div class="layui-form-item">
+			                		<label class="layui-form-label">[value->description]</label>
+			                		<div class="layui-input-inline">
+				                     	<input type="text" name="[value->name]" id="[value->name]" value="{$content->{$value->name}}" placeholder="请上传[value->description]"  class="layui-input">
+				                     </div>
+				                     <button type="button" class="layui-btn file" data-des="[value->name]">
+									 	 <i class="layui-icon">&#xe67c;</i>上传文件
+									 </button>
+				                </div>
+			                	{/if}
+			                	
+			                	{if($value->type==7)}<!-- 日期 -->
+				                <div class="layui-form-item">
+				                     <label class="layui-form-label">[value->description]</label>
+				                     <div class="layui-input-block">
+				                     	<input type="text" name="[value->name]" value="{$content->{$value->name}}" readonly placeholder="请选择[value->description]"  class="layui-input datetime">
+				                     </div>
+				                </div>
+			                	{/if}
+			                	
+			                	{if($value->type==8)}<!-- 编辑器 -->
+			                	<div class="layui-form-item">
+			                		<label class="layui-form-label">[value->description]</label>
+			                		<div class="layui-input-block">
+			                			{php}
+			                				$name=@$value->name;
+			                			{/php}
+				                		<script type="text/plain" id="editor_[value->name]" name="[value->name]" style="width:100%;height:240px;">{fun=decode_string([$content->$name])}</script>
+				                		<script>
+											//初始化编辑器
+											$(document).ready(function (e) {
+												var ue = UE.getEditor('editor_[value->name]',{
+													maximumWords:10000 
+												});
+											})
+										</script>
+				                	</div>
+				                </div>
+			                	{/if}
+			                	
+			                	{if($value->type==9)}<!-- 下拉 -->
+			                	<div class="layui-form-item">
+			                		<label class="layui-form-label">[value->description]</label>
+			                		<div class="layui-input-block">
+			                			<select name="[value->name]">
+			                				{php}
+				                				$selects=explode(',',$value->value);
+				                				$name=$value->name;
+				                				foreach ($selects as $value2) {
+				                					if($this->vars['content']->$name==$value2){
+				                						echo '<option value="'.$value2.'" selected>'.$value2.'</option>';
+	                								}else{
+	                									echo '<option value="'.$value2.'">'.$value2.'</option>';
+	                								}
+	            								}
+	            						    {/php}
+			                			</select>
+				                	</div>
+				                 </div>
+			                	 {/if}
+			                	 
+			                {/foreach}
+			                
+			                <div class="layui-form-item">
+			                     <label class="layui-form-label">内容</label>
+			                     <div class="layui-input-block">
+			                     	<script type="text/plain" id="editor" name="content" style="width:100%;height:240px;">{fun=decode_string([$content->content])}</script>
+			                     </div>
+			                </div>
+			                
+			                <div class="layui-form-item">
+			                     <label class="layui-form-label">tags</label>
+			                     <div class="layui-input-block">
+			                     	<input type="text" name="tags" placeholder="请输入文章tag,英文逗号隔开" value="{$content->tags}" class="layui-input">
+			                     </div>
+			                </div>
+			                
+			                <div class="layui-form-item">
+			                     <label class="layui-form-label">作者</label>
+			                     <div class="layui-input-block">
+			                     	<input type="text" name="author" placeholder="请输入作者" value="{$content->author}" class="layui-input">
+			                     </div>
+			                </div>
+			                
+			                <div class="layui-form-item">
+			                     <label class="layui-form-label">来源</label>
+			                     <div class="layui-input-block">
+			                     	<input type="text" name="source" placeholder="请输入来源" value="{$content->source}" class="layui-input">
+			                     </div>
+			                </div>
+			                
+			                <div class="layui-form-item">
+			                     <label class="layui-form-label">缩略图</label>
+			                     <div class="layui-input-inline">
+			                     	<input type="text" name="ico" id="ico" value="{$content->ico}" placeholder="请上传缩略图"  class="layui-input">
+			                     </div>
+			                     <button type="button" class="layui-btn upload watermark" data-des="ico">
+								 	 <i class="layui-icon">&#xe67c;</i>上传图片
+								 </button>
+								 <div id="ico_box" class="pic addedit">{if([$content->ico])}<dl><dt><img src="{SITE_DIR}{$content->ico}" data-url="{$content->ico}"></dt><dd>删除</dd></dl>{/if}</div>
+			                </div>
+			                
+			                <div class="layui-form-item">
+			                     <label class="layui-form-label">轮播多图</label>
+			                     <div class="layui-input-inline">
+			                     	<input type="text" name="pics" id="pics" value="{$content->pics}" placeholder="请上传轮播多图"  class="layui-input">
+			                     </div>
+			                     <button type="button" class="layui-btn uploads watermark" data-des="pics">
+								 	 <i class="layui-icon">&#xe67c;</i>上传多图
+								 </button>
+								 <div id="pics_box" class="pic addedit">
+								 	<dl></dl> <!-- 规避空内容拖动bug -->
+								 	 {php}
+									    if([$content->pics]){
+		                					$pics=explode(',',[$content->pics]);
+		                				}else{
+		                					$pics = array();
+		                				}
+		                				if([$content->picstitle]){
+		                					$picstitle=explode(',',[$content->picstitle]);
+		                				}else{
+		                					$picstitle = array();
+		                				}
+		                				foreach ($pics as $key=>$value) {
+		                					//需要留一个空,不然被解析为标签了
+		                					echo "<dl><dt><img src='".SITE_DIR.$value."' data-url='".$value."'></dt><dd>删除</dd><dt><input type='text' value='".$picstitle[$key ]."' name='picstitle[]' style='width:95%' /></dt></dl>";
+	          							}
+	         						 {/php}
+								 </div>
+			                </div>
+					    </div>
+					    
+					    <div class="layui-tab-item ">
+					    
+					   		 <div class="layui-form-item">
+			                     <label class="layui-form-label">标题颜色</label>
+			                     <div class="layui-input-inline">
+			                     	<input type="text" name="titlecolor" value="{$content->titlecolor}" placeholder="请选择标题颜色"  class="layui-input jscolor {hash:true}">
+			                     </div>
+			                 </div>
+			                 
+			                 <div class="layui-form-item">
+			                     <label class="layui-form-label">副标题</label>
+			                     <div class="layui-input-block">
+			                     	<input type="text" name="subtitle" value="{$content->subtitle}" placeholder="请输入副标题" class="layui-input">
+			                     </div>
+			                 </div>
+
+			                 <div class="layui-form-item">
+			                     <label class="layui-form-label">时间</label>
+			                     <div class="layui-input-inline">
+			                     	<input type="text" name="date" value="{$content->date}" readonly placeholder="请选择发布时间"  class="layui-input datetime">
+			                     </div>
+			                     <div class="layui-form-mid layui-word-aux">温馨提示:单页不支持定时发布!</div>
+			                </div>
+			                
+			                <div class="layui-form-item">
+		                		<label class="layui-form-label">附件</label>
+		                		<div class="layui-input-inline">
+			                     	<input type="text" name="enclosure" id="enclosure" value="{$content->enclosure}" placeholder="请上传附件"  class="layui-input">
+			                     </div>
+			                     <button type="button" class="layui-btn file" data-des="enclosure">
+								 	 <i class="layui-icon">&#xe67c;</i>上传附件
+								 </button>
+			                </div>
+			                
+			                <div class="layui-form-item">
+			                     <label class="layui-form-label">SEO关键字</label>
+			                     <div class="layui-input-block">
+			                     	<input type="text" name="keywords" value="{$content->keywords}"  placeholder="请输入详情页SEO关键字" class="layui-input">
+			                     </div>
+			                </div>
+			                
+			                <div class="layui-form-item">
+			                     <label class="layui-form-label">SEO描述</label>
+			                     <div class="layui-input-block">
+			                     	<textarea name="description" placeholder="请输入详情页SEO描述" class="layui-textarea">{$content->description}</textarea>
+			                     </div>
+			                </div>
+			                
+			                <div class="layui-form-item">
+			                     <label class="layui-form-label">状态</label>
+			                     <div class="layui-input-block">
+			                     	<input type="radio" name="status" value="1" title="显示" {if([$content->status]==1)} checked="checked"{/if}>
+									<input type="radio" name="status" value="0" title="隐藏" {if([$content->status]==0)} checked="checked"{/if}>
+			                     </div>
+			                </div>
+					    </div>
+					  </div>
+					</div>
+					<div class="layui-form-item">
+						 <div class="layui-input-block">
+						    <button class="layui-btn" lay-submit>立即提交</button>
+						    <button type="reset" class="layui-btn layui-btn-primary">重置</button>
+						    {fun=get_btn_back()}
+						 </div>
+					</div>
+	  		</form>
+	  	</div>
+	  </div>
+	</div>
+	{/if} 
+
+</div>
+
+<style>.placeHolder {border:dashed 2px gray; }</style>
+<script type="text/javascript" src="{APP_THEME_DIR}/js/jquery.dragsort-0.5.2.min.js"></script>
+<script type="text/javascript">
+$("#pics_box").dragsort({
+	dragSelector: "dl",
+	dragSelectorExclude: "input,textarea,dd",
+	dragBetween: false,
+	dragEnd: saveOrder,
+	placeHolderTemplate: "<dl class='placeHolder'><dt></dt></dl>"
+});
+
+function saveOrder() {
+	var data = $("#pics_box dl dt img").map(function() {
+		return $(this).data("url");
+	}).get();
+	$("input[name=pics]").val(data.join(","))
+};
+</script>
+<script type="text/javascript" src="{APP_THEME_DIR}/js/jscolor.js"></script>
+
+{include file='common/ueditor.html'}
+{include file='common/foot.html'}

+ 107 - 0
apps/admin/view/default/content/site.html

@@ -0,0 +1,107 @@
+{include file='common/head.html'}
+
+<div class="layui-body">
+	<div class="layui-tab layui-tab-brief" lay-filter="tab">
+	  <ul class="layui-tab-title">
+	    <li class="layui-this">站点信息</li>
+	  </ul>
+	  <div class="layui-tab-content">
+	  	<div class="layui-tab-item layui-show">
+	  		<form action="{url./admin/Site/mod}" method="post" class="layui-form">
+	  			<input type="hidden" name="formcheck" value="{$formcheck}" > 
+	  			<div class="layui-form-item">
+                     <label class="layui-form-label">站点标题</label>
+                     <div class="layui-input-block">
+                     	<input type="text" name="title" value="{$sites->title}" placeholder="请输入站点标题"  class="layui-input">
+                     </div>
+                </div>
+                
+                <div class="layui-form-item">
+                     <label class="layui-form-label">站点副标题</label>
+                     <div class="layui-input-block">
+                     	<input type="text" name="subtitle" value="{$sites->subtitle}" placeholder="请输入站点副标题"  class="layui-input">
+                     </div>
+                </div>
+                
+                <div class="layui-form-item">
+                     <label class="layui-form-label">站点域名</label>
+                     <div class="layui-input-block">
+                     	<input type="text" name="domain" value="{$sites->domain}" placeholder="请输入站点域名"  class="layui-input">
+                     </div>
+                </div>
+                
+                <div class="layui-form-item">
+                     <label class="layui-form-label">站点LOGO</label>
+                     <div class="layui-input-inline">
+                     	<input type="text" name="logo" id="logo" value="{$sites->logo}" placeholder="请上传站点LOGO图"  class="layui-input">
+                     </div>
+                     <button type="button" class="layui-btn upload" data-des="logo">
+					 	 <i class="layui-icon">&#xe67c;</i>上传图片
+					 </button>
+					 <div id="logo_box" class="pic"><dl><dt>{if(@[$sites->logo])}<img src="{SITE_DIR}{$sites->logo}" data-url="{$sites->logo}"></dt><dd>删除</dd></dl>{/if}</div>
+                </div>
+                
+                <div class="layui-form-item">
+                     <label class="layui-form-label">站点关键字</label>
+                     <div class="layui-input-block">
+                     	<input type="text" name="keywords" value="{$sites->keywords}" placeholder="请输入站点关键字"  class="layui-input">
+                     </div>
+                </div>
+                
+                <div class="layui-form-item">
+                     <label class="layui-form-label">站点描述</label>
+                     <div class="layui-input-block">
+                     	<textarea name="description" placeholder="请输入站点描述" class="layui-textarea">{$sites->description}</textarea>
+                     </div>
+                </div>
+                
+                <div class="layui-form-item">
+                     <label class="layui-form-label">站点备案</label>
+                     <div class="layui-input-block">
+                     	<input type="text" name="icp" value="{$sites->icp}" placeholder="请输入站点备案"  class="layui-input">
+                     </div>
+                </div>
+                
+                <div class="layui-form-item">
+				    <label class="layui-form-label">站点模板</label>
+				    <div class="layui-input-block">
+				      <select name="theme">
+                       	{foreach $themes(key,value)} 
+                            {if($value == [$sites->theme])}
+                                <option value="[value]" selected='selected'>[value]</option> 
+                            {else}
+                                <option value="[value]">[value]</option> 
+                            {/if}
+                        {/foreach}
+				      </select>
+				    </div>
+				 </div>
+				 
+				 <div class="layui-form-item">
+                     <label class="layui-form-label">统计代码</label>
+                     <div class="layui-input-block">
+                     	<textarea name="statistical" placeholder="请输入统计代码" class="layui-textarea">{$sites->statistical}</textarea>
+                     </div>
+                </div>
+                
+                <div class="layui-form-item">
+                     <label class="layui-form-label">尾部信息</label>
+                     <div class="layui-input-block">
+                     	<textarea name="copyright" placeholder="请输入尾部信息" class="layui-textarea">{$sites->copyright}</textarea>
+                     </div>
+                </div>
+				
+				<div class="layui-form-item">
+					 <div class="layui-input-block">
+					    <button class="layui-btn" lay-submit>立即提交</button>
+					    <button type="reset" class="layui-btn layui-btn-primary">重置</button>
+					 </div>
+				</div>
+				 
+	  		</form>
+	  	</div>
+	  </div>
+	</div>
+</div>
+
+{include file='common/foot.html'}

+ 187 - 0
apps/admin/view/default/content/slide.html

@@ -0,0 +1,187 @@
+{include file='common/head.html'}
+
+<div class="layui-body">
+	{if([$list])}
+	<div class="layui-tab layui-tab-brief" lay-filter="tab">
+	  <ul class="layui-tab-title">
+	    <li class="layui-this" lay-id="t1">幻灯片列表</li>
+	    <li lay-id="t2">幻灯片新增</li>
+	  </ul>
+	  <div class="layui-tab-content">
+	  	<div class="layui-tab-item layui-show">
+	  		<form action="{url./admin/Slide/mod}" method="post" class="layui-form" onkeydown="if(event.keyCode==13) return false;">
+		    <input type="hidden" name="formcheck" value="{$formcheck}" > 
+	  		<table class="layui-table">
+            	<thead>
+                    <tr>
+                    	<th>分组(gid)</th>
+                        <th>图片</th>
+                        <th>链接</th>
+                        <th>标题</th>
+                        <th>副标题</th>
+                        <th>排序</th>
+                        <th>操作</th>
+                    </tr>
+                </thead>
+                <tbody>
+                    {foreach $slides(key,value)}
+                    <tr>
+                    	<td>[value->gid]</td>
+                        <td><img src="{SITE_DIR}[value->pic]" style="height:30px;"></td>
+                        <td>[value->link]</td>
+                        <td>[value->title]</td>
+                        <td>[value->subtitle]</td>
+                        <td class="table-input">
+                        <input type="hidden" name="listall[]" value="[value->id]">
+                        <input type="text" lay-ignore class="layui-input" name="sorting[]" value="[value->sorting]">
+                        </td>
+                        <td>
+                            {fun=get_btn_del($value->id)}
+                            {fun=get_btn_mod($value->id)}
+                        </td>
+                    </tr>
+                    {/foreach}
+                </tbody>
+            </table>
+            <button type="submit" name="submit" value="sorting" class="layui-btn layui-btn-sm">保存排序</button>
+            </form> 
+            <div class="page">{$pagebar}</div>
+	  	</div>
+	  	
+	  	<div class="layui-tab-item">
+	  		<form action="{url./admin/Slide/add}" method="post" class="layui-form">
+	  			<input type="hidden" name="formcheck" value="{$formcheck}" > 
+	  			<div class="layui-form-item">
+                     <label class="layui-form-label">分组</label>
+                     <div class="layui-input-block">
+                     	<select name="gid" >	
+                     		{foreach $gids(key,value)}
+	                			<option value="[value]" >分组[value]</option>
+	                		{/foreach}
+	                		<option value="" >自动新增分组</option>
+	                	</select>
+                     </div>
+                </div>
+                
+                <div class="layui-form-item">
+                     <label class="layui-form-label">图片</label>
+                     <div class="layui-input-inline">
+                     	<input type="text" name="pic" id="pic" required  lay-verify="required" placeholder="请上传图片"  class="layui-input">
+                     </div>
+                     <button type="button" class="layui-btn upload" data-des="pic">
+					 	 <i class="layui-icon">&#xe67c;</i>上传图片
+					 </button>
+					 <div id="pic_box" class="pic"></div>
+                </div>
+                
+                <div class="layui-form-item">
+                     <label class="layui-form-label">链接</label>
+                     <div class="layui-input-block">
+                     	<input type="text" name="link" placeholder="请输入跳转链接"  class="layui-input">
+                     </div>
+                </div>
+                
+                 <div class="layui-form-item">
+                     <label class="layui-form-label">标题</label>
+                     <div class="layui-input-block">
+                     	<input type="text" name="title" placeholder="请输入标题"  class="layui-input">
+                     </div>
+                </div>
+                
+                <div class="layui-form-item">
+                     <label class="layui-form-label">副标题</label>
+                     <div class="layui-input-block">
+                     	<input type="text" name="subtitle" placeholder="请输入副标题"  class="layui-input">
+                     </div>
+                </div>
+                
+                <div class="layui-form-item">
+                     <label class="layui-form-label">排序</label>
+                     <div class="layui-input-block">
+                     	<input type="text" name="sorting" required lay-verify="required" value="255" placeholder="请输入排序"  class="layui-input">
+                     </div>
+                </div>
+                
+                 <div class="layui-form-item">
+					 <div class="layui-input-block">
+					    <button class="layui-btn" lay-submit>立即提交</button>
+					    <button type="reset" class="layui-btn layui-btn-primary">重置</button>
+					 </div>
+				</div>
+	  		</form>
+	  	</div>
+	  </div>
+	</div>
+	{/if} 
+	
+	{if([$mod])}
+	<div class="layui-tab layui-tab-brief" lay-filter="tab">
+	  <ul class="layui-tab-title">
+	    <li class="layui-this">幻灯片修改</li>
+	  </ul>
+	  <div class="layui-tab-content">
+	  	<div class="layui-tab-item layui-show">
+	  		<form action="{url./admin/Slide/mod/id/'.[$get.id].'}{$backurl}" method="post" class="layui-form">
+	  			<input type="hidden" name="formcheck" value="{$formcheck}" > 
+	  			
+                <div class="layui-form-item">
+                     <label class="layui-form-label">分组</label>
+                     <div class="layui-input-block">
+                     	<input type="text" name="gid" required  lay-verify="required" value="{$slide->gid}" placeholder="请输入分组"  class="layui-input">
+                     </div>
+                </div>
+                
+                <div class="layui-form-item">
+                     <label class="layui-form-label">图片</label>
+                     <div class="layui-input-inline">
+                     	<input type="text" name="pic" id="pic" required  lay-verify="required" value="{$slide->pic}" placeholder="请上传图片"  class="layui-input">
+                     </div>
+                     <button type="button" class="layui-btn upload" data-des="pic">
+					 	 <i class="layui-icon">&#xe67c;</i>上传图片
+					 </button>
+					 <div id="pic_box" class="pic">{if([$slide->pic])}<dl><dt><img src="{SITE_DIR}{$slide->pic}" data-url="{$slide->pic}"></dt><dd>删除</dd></dl>{/if}</div>
+                </div>
+                
+                <div class="layui-form-item">
+                     <label class="layui-form-label">跳转链接</label>
+                     <div class="layui-input-block">
+                     	<input type="text" name="link" value="{$slide->link}"  placeholder="请输入跳转链接"  class="layui-input">
+                     </div>
+                </div>
+                
+                <div class="layui-form-item">
+                     <label class="layui-form-label">标题</label>
+                     <div class="layui-input-block">
+                     	<input type="text" name="title" value="{$slide->title}" placeholder="请输入标题"  class="layui-input">
+                     </div>
+                </div>
+                
+                 <div class="layui-form-item">
+                     <label class="layui-form-label">副标题</label>
+                     <div class="layui-input-block">
+                     	<input type="text" name="subtitle" value="{$slide->subtitle}" placeholder="请输入副标题"  class="layui-input">
+                     </div>
+                </div>
+                
+                 <div class="layui-form-item">
+                     <label class="layui-form-label">排序</label>
+                     <div class="layui-input-block">
+                     	<input type="text" name="sorting" required lay-verify="required" value="{$slide->sorting}" placeholder="请输入排序"  class="layui-input">
+                     </div>
+                </div>
+                
+                 <div class="layui-form-item">
+					 <div class="layui-input-block">
+					    <button class="layui-btn" lay-submit>立即提交</button>
+					    <button type="reset" class="layui-btn layui-btn-primary">重置</button>
+					    {fun=get_btn_back()}
+					 </div>
+				</div>
+	  		</form>
+	  	</div>
+	  </div>
+	</div>
+	{/if} 
+
+</div>
+{include file='common/foot.html'}

+ 105 - 0
apps/admin/view/default/content/tags.html

@@ -0,0 +1,105 @@
+{include file='common/head.html'}
+
+<div class="layui-body">
+	{if([$list])}
+	<div class="layui-tab layui-tab-brief" lay-filter="tab">
+	  <ul class="layui-tab-title">
+	    <li class="layui-this" lay-id="t1">文章内链列表</li>
+	    <li lay-id="t2">文章内链新增</li>
+	  </ul>
+	  <div class="layui-tab-content">
+	  	<div class="layui-tab-item layui-show">
+	  		<table class="layui-table">
+	  			<thead>
+                    <tr>
+                    	<th>序号</th>
+                        <th>名称</th>
+                        <th>链接</th>
+                        <th>操作</th>
+                    </tr>
+                </thead>
+                <tbody>
+                    {foreach $tags(key,value)}
+                    <tr>
+                    	<td>[num]</td>
+                        <td>[value->name]</td>
+                        <td>[value->link]</td>
+                        <td>
+                            {fun=get_btn_del($value->id)}
+                            {fun=get_btn_mod($value->id)}
+                        </td>
+                    </tr>
+                    {/foreach}
+                </tbody>
+	  		</table>
+	  		<div class="page">{$pagebar}</div>
+	  	</div>
+	  	<div class="layui-tab-item">
+	  		 <form action="{url./admin/Tags/add}" method="post" class="layui-form">
+	  		 	<input type="hidden" name="formcheck" value="{$formcheck}" > 
+
+                 <div class="layui-form-item">
+                     <label class="layui-form-label">名称</label>
+                     <div class="layui-input-block">
+                     	<input type="text" name="name" required  lay-verify="required" placeholder="请输入名称"  class="layui-input">
+                     </div>
+                </div>
+                
+                <div class="layui-form-item">
+                     <label class="layui-form-label">链接</label>
+                     <div class="layui-input-block">
+                     	<input type="text" name="link" required  lay-verify="required" placeholder="请输入链接"  class="layui-input">
+                     </div>
+                </div>
+
+                <div class="layui-form-item">
+					 <div class="layui-input-block">
+					    <button class="layui-btn" lay-submit>立即提交</button>
+					    <button type="reset" class="layui-btn layui-btn-primary">重置</button>
+					 </div>
+				</div>
+	  		 </form>
+	  	</div>
+	  </div>
+	</div>
+	{/if} 
+	
+	{if([$mod])}
+	<div class="layui-tab layui-tab-brief" lay-filter="tab">
+	  <ul class="layui-tab-title">
+	    <li class="layui-this">文章内链修改</li>
+	  </ul>
+	  <div class="layui-tab-content">
+	  	<div class="layui-tab-item layui-show">
+	  		 <form action="{url./admin/Tags/mod/id/'.[$get.id].'}{$backurl}" method="post" class="layui-form">
+	  		 	<input type="hidden" name="formcheck" value="{$formcheck}" > 
+
+                <div class="layui-form-item">
+                     <label class="layui-form-label">名称</label>
+                     <div class="layui-input-block">
+                     	<input type="text" name="name" required  lay-verify="required" value="{$tags->name}" placeholder="请输入名称"  class="layui-input">
+                     </div>
+                </div>
+                
+                <div class="layui-form-item">
+                     <label class="layui-form-label">链接</label>
+                     <div class="layui-input-block">
+                     	<input type="text" name="link" required  lay-verify="required" value="{$tags->link}" placeholder="请输入链接"  class="layui-input">
+                     </div>
+                </div>
+                
+                 <div class="layui-form-item">
+					 <div class="layui-input-block">
+					    <button class="layui-btn" lay-submit>立即提交</button>
+					    <button type="reset" class="layui-btn layui-btn-primary">重置</button>
+					    {fun=get_btn_back()}
+					 </div>
+				</div>
+				
+	  		 </form>
+	  	</div>
+	  </div>
+	 </div>
+	{/if} 
+</div>
+{include file='common/foot.html'}

+ 265 - 0
apps/admin/view/default/css/comm.css

@@ -0,0 +1,265 @@
+/*分页样式*/
+.layui-header {
+	height: 50px;
+}
+.layui-body {
+	padding: 10px 15px;
+}
+.layui-layout-admin .layui-body {
+	top: 50px;
+	bottom:0;
+}
+.layui-layout-admin .layui-logo {
+	color: #fff;
+	font-size: 20px;
+	line-height: 50px;
+	height: 50px;
+	overflow:hidden;
+	text-align: left;
+	width: 180px;
+	padding-left: 10px;
+}
+.layui-layout-admin .layui-logo .layui-badge{
+	font-size:10px;
+	padding: 3px;
+	height: 12px;
+	line-height: 12px;
+	top:-3px;
+}
+.layui-layout-admin .layui-logo img {
+	vertical-align: middle;
+	margin-top: -3px;
+}
+.layui-layout-admin .layui-logo a {
+	color: #fff;
+}
+.layui-layout-admin .layui-header .layui-nav .layui-nav-item {
+	height: 50px;
+	line-height: 50px;
+}
+.layui-layout-admin .layui-side {
+	top: 50px;
+}
+.layui-layout-admin .layui-side .layui-nav i {
+	margin-right: 10px;
+}
+.layui-layout-admin .layui-side .layui-nav-child dd {
+	padding-left: 20px;
+}
+.layui-form-label {
+	width: 100px;
+}
+.layui-input-block {
+	margin-left: 130px;
+}
+.layui-layout-left {
+	left: 220px;
+}
+.layui-table .layui-btn {
+	margin: 0.5px 0;
+}
+.layui-table .layui-btn + .layui-btn {
+	margin-left: 0px;
+}
+.layui-form-select dl {
+	z-index: 9999;
+	max-height: 250px;
+}
+.layui-text-red{
+	color:red;
+}
+/*菜单显示按钮*/
+.menu {
+	position: absolute !important;
+	left : 200px;
+	top: 10px;
+	line-height: 30px;
+	color: #ccc;
+	text-align: center;
+	z-index: 999;
+}
+.menu li {
+	width: 30px;
+	background: #2F4056;
+}
+.menu a {
+	color: #ccc;
+}
+.menu .menu-ico {
+	font-size: 20px;
+	cursor: pointer;
+}
+.area-select {
+	position: absolute;
+	left : 250px;
+	top: 10px;
+}
+.area-select select {
+	height: 30px;
+	border: 1px solid #fafafa;
+	padding-left: 5px;
+	border-radius: 2px;
+}
+.area-select .layui-select-title {
+}
+/*桌面快捷图标*/
+.deskbox {
+	height: 90px;
+	border-radius: 5px;
+	color: #666;
+	text-align: center;
+	background: #f2f2f2;
+	margin: 5px;
+}
+.deskbox:hover {
+	background: #e0e0e0;
+}
+.deskbox dd {
+	font-size: 30px;
+	line-height: 50px;
+	color:#009688;
+}
+.deskbox dt {
+	padding-top:15px;
+	color:#999;
+	font-weight: normal;
+}
+.page {
+	clear: both;
+	margin: 10px 0;
+	text-align: center;
+}
+.page a:hover {
+	color:#009688;
+}
+.page-status{
+	border-radius: 2px 0 0 2px;
+}
+.page-last{
+	border-radius: 0 2px 2px 0;
+}
+.page-status,.page-index,.page-pre,.page-num,.page-next,.page-last{
+	display: inline-block;
+	*display: inline;
+	*zoom: 1;
+	vertical-align: middle;
+	padding: 0 15px;
+	height: 28px;
+	line-height: 28px;
+	margin: 0 -1px 5px 0;
+	background-color: #fff;
+	color: #333;
+	font-size: 12px;
+	border: 1px solid #e2e2e2;
+}
+.page-num-current{
+	background-color: #009688;
+	height:30px;
+	line-height: 30px;
+	border-top:none;
+	border-bottom:none;
+	color:#fff;
+}
+a.page-num-current:hover{
+	color:#fff;
+}
+.readonly {
+	background: #fafafa;
+}
+.table-input {
+	padding: 0px 15px!important;
+}
+.table-input input {
+	height: 30px;
+	max-width: 50px;
+	padding: 0px;
+	text-align: center;
+	color: #666;
+}
+.table-two tbody td {
+	text-align: left;
+}
+.table-two tbody th {
+	text-align: right;
+	width: 110px;
+}
+.fa-toggle-on {
+	font-size: 20px;
+	color: #5FB878;
+}
+.fa-toggle-off {
+	font-size: 20px;
+	color: #d2d2d2;
+}
+.pic {
+	margin-left: 130px;
+}
+.pic dl {
+	float: left;
+	position: relative;
+}
+.pic dl dd {
+	position: absolute;
+	right: 5px;
+	top: 5px;
+	cursor: pointer;
+	background: #666;
+	color: #fff;
+	padding: 2px;
+}
+.pic img {
+	max-height: 100px;
+	margin: 5px 0;
+	margin-right: 5px;
+}
+
+@media only screen and (min-width: 450px) {
+.layui-form-item .layui-input-inline {
+	width: 260px;
+}
+}
+
+@media only screen and (max-width: 750px) {
+.layui-body {
+	left: 0px !important;
+}
+.layui-layout-admin .layui-logo {
+	width: 180px;
+	text-align: left;
+	padding-left: 5px;
+}
+.menu {
+	left: 185px;
+}
+.area-select {
+	right: 5px;
+	left: auto;
+}
+.layui-layout-admin .layui-footer {
+	left: 0px !important;
+}
+.layui-layout-admin .layui-side {
+	display: none;
+}
+.layui-body {
+	overflow-x: auto;
+}
+.hidden-xs {
+	display: none;
+}
+.layui-form-label {
+	width: 80px;
+}
+.pic {
+	margin-left: 110px;
+}
+.layui-input-block {
+	margin-left: 110px;
+}
+}
+
+@media only screen and (max-width: 450px) {
+.layui-form-item.nospace .layui-input-inline {
+	margin: 0 0 10px 0px;
+}
+}

+ 28 - 0
apps/admin/view/default/css/jquery.treetable.css

@@ -0,0 +1,28 @@
+table.treetable span.indenter {
+  display: inline-block;
+  margin: 0;
+  padding: 0;
+  text-align: right;
+
+  /* Disable text selection of nodes (for better D&D UX) */
+  user-select: none;
+  -khtml-user-select: none;
+  -moz-user-select: none;
+  -o-user-select: none;
+  -webkit-user-select: none;
+
+  /* Force content-box box model for indenter (Bootstrap compatibility) */
+  -webkit-box-sizing: content-box;
+  -moz-box-sizing: content-box;
+  box-sizing: content-box;
+
+  width: 19px;
+}
+
+table.treetable span.indenter a {
+  background-position: left center;
+  background-repeat: no-repeat;
+  display: inline-block;
+  text-decoration: none;
+  width: 19px;
+}

+ 102 - 0
apps/admin/view/default/css/login.css

@@ -0,0 +1,102 @@
+body, html {
+	height: 100%
+}
+body {
+	background: url(../images/bg.jpg);
+}
+.user-login {
+	position: relative;
+	left: 0;
+	top: 0;
+	padding: 120px 0;
+	min-height: 100%;
+	box-sizing: border-box;
+}
+.user-login-main {
+	width: 375px;
+	margin: 0 auto;
+	box-sizing: border-box;
+	background: #ccc;
+	background-color: rgba(248,248,255,0.2);
+	border-radius: 5px;
+}
+.user-login-header {
+	text-align: center;
+	padding-top: 20px;
+}
+.user-login-header h2 {
+	margin-bottom: 10px;
+	font-weight: 300;
+	font-size: 25px;
+	color: #fff;
+	font-weight: bold;
+}
+.user-login-header p {
+	font-weight: 300;
+	color: #eee;
+}
+.user-login-box {
+	padding: 20px;
+}
+.user-login-icon {
+	position: absolute;
+	left: 1px;
+	top: 1px;
+	width: 38px;
+	line-height: 36px;
+	text-align: center;
+	color: #d2d2d2;
+}
+.user-login-box .layui-form-item {
+	position: relative;
+}
+.user-login-box .layui-form-item .layui-input {
+	padding-left: 38px
+}
+.user-login-codeimg {
+	height: 38px;
+	width: 100%;
+	cursor: pointer;
+	box-sizing: border-box;
+}
+.user-login-footer {
+	position: absolute;
+	left: 0;
+	bottom: 0;
+	width: 100%;
+	line-height: 1.5;
+	padding: 20px;
+	text-align: center;
+	box-sizing: border-box;
+	color: rgba(0,0,0,.5);
+}
+.user-login-footer span {
+	padding: 0 5px;
+}
+.user-login-footer a {
+	color: rgba(0,0,0,.5);
+}
+.user-login-footer a:hover {
+	color: rgba(0,0,0,1);
+}
+
+@media screen and (max-width:768px) {
+.user-login {
+	padding-top: 60px;
+}
+.user-login-main {
+	width: 300px;
+}
+.user-login-box {
+	padding: 10px;
+}
+}
+
+@media \0screen\,screen\9 {/* 只支持IE6、7、8 */
+.user-login-header h2 {
+	color: #000;
+}
+.user-login-header p {
+	color: #999;
+}
+}

+ 7 - 0
apps/admin/view/default/font-awesome/HELP-US-OUT.txt

@@ -0,0 +1,7 @@
+I hope you love Font Awesome. If you've found it useful, please do me a favor and check out my latest project,
+Fort Awesome (https://fortawesome.com). It makes it easy to put the perfect icons on your website. Choose from our awesome,
+comprehensive icon sets or copy and paste your own.
+
+Please. Check it out.
+
+-Dave Gandy

File diff suppressed because it is too large
+ 2337 - 0
apps/admin/view/default/font-awesome/css/font-awesome.css


File diff suppressed because it is too large
+ 4 - 0
apps/admin/view/default/font-awesome/css/font-awesome.min.css


BIN
apps/admin/view/default/font-awesome/fonts/FontAwesome.otf


BIN
apps/admin/view/default/font-awesome/fonts/fontawesome-webfont.eot


File diff suppressed because it is too large
+ 2671 - 0
apps/admin/view/default/font-awesome/fonts/fontawesome-webfont.svg


BIN
apps/admin/view/default/font-awesome/fonts/fontawesome-webfont.ttf


BIN
apps/admin/view/default/font-awesome/fonts/fontawesome-webfont.woff


BIN
apps/admin/view/default/font-awesome/fonts/fontawesome-webfont.woff2


+ 34 - 0
apps/admin/view/default/font-awesome/less/animated.less

@@ -0,0 +1,34 @@
+// Animated Icons
+// --------------------------
+
+.@{fa-css-prefix}-spin {
+  -webkit-animation: fa-spin 2s infinite linear;
+          animation: fa-spin 2s infinite linear;
+}
+
+.@{fa-css-prefix}-pulse {
+  -webkit-animation: fa-spin 1s infinite steps(8);
+          animation: fa-spin 1s infinite steps(8);
+}
+
+@-webkit-keyframes fa-spin {
+  0% {
+    -webkit-transform: rotate(0deg);
+            transform: rotate(0deg);
+  }
+  100% {
+    -webkit-transform: rotate(359deg);
+            transform: rotate(359deg);
+  }
+}
+
+@keyframes fa-spin {
+  0% {
+    -webkit-transform: rotate(0deg);
+            transform: rotate(0deg);
+  }
+  100% {
+    -webkit-transform: rotate(359deg);
+            transform: rotate(359deg);
+  }
+}

+ 25 - 0
apps/admin/view/default/font-awesome/less/bordered-pulled.less

@@ -0,0 +1,25 @@
+// Bordered & Pulled
+// -------------------------
+
+.@{fa-css-prefix}-border {
+  padding: .2em .25em .15em;
+  border: solid .08em @fa-border-color;
+  border-radius: .1em;
+}
+
+.@{fa-css-prefix}-pull-left { float: left; }
+.@{fa-css-prefix}-pull-right { float: right; }
+
+.@{fa-css-prefix} {
+  &.@{fa-css-prefix}-pull-left { margin-right: .3em; }
+  &.@{fa-css-prefix}-pull-right { margin-left: .3em; }
+}
+
+/* Deprecated as of 4.4.0 */
+.pull-right { float: right; }
+.pull-left { float: left; }
+
+.@{fa-css-prefix} {
+  &.pull-left { margin-right: .3em; }
+  &.pull-right { margin-left: .3em; }
+}

+ 12 - 0
apps/admin/view/default/font-awesome/less/core.less

@@ -0,0 +1,12 @@
+// Base Class Definition
+// -------------------------
+
+.@{fa-css-prefix} {
+  display: inline-block;
+  font: normal normal normal @fa-font-size-base/@fa-line-height-base FontAwesome; // shortening font declaration
+  font-size: inherit; // can't have font-size inherit on line above, so need to override
+  text-rendering: auto; // optimizelegibility throws things off #1094
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+
+}

+ 6 - 0
apps/admin/view/default/font-awesome/less/fixed-width.less

@@ -0,0 +1,6 @@
+// Fixed Width Icons
+// -------------------------
+.@{fa-css-prefix}-fw {
+  width: (18em / 14);
+  text-align: center;
+}

+ 18 - 0
apps/admin/view/default/font-awesome/less/font-awesome.less

@@ -0,0 +1,18 @@
+/*!
+ *  Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome
+ *  License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
+ */
+
+@import "variables.less";
+@import "mixins.less";
+@import "path.less";
+@import "core.less";
+@import "larger.less";
+@import "fixed-width.less";
+@import "list.less";
+@import "bordered-pulled.less";
+@import "animated.less";
+@import "rotated-flipped.less";
+@import "stacked.less";
+@import "icons.less";
+@import "screen-reader.less";

+ 789 - 0
apps/admin/view/default/font-awesome/less/icons.less

@@ -0,0 +1,789 @@
+/* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen
+   readers do not read off random characters that represent icons */
+
+.@{fa-css-prefix}-glass:before { content: @fa-var-glass; }
+.@{fa-css-prefix}-music:before { content: @fa-var-music; }
+.@{fa-css-prefix}-search:before { content: @fa-var-search; }
+.@{fa-css-prefix}-envelope-o:before { content: @fa-var-envelope-o; }
+.@{fa-css-prefix}-heart:before { content: @fa-var-heart; }
+.@{fa-css-prefix}-star:before { content: @fa-var-star; }
+.@{fa-css-prefix}-star-o:before { content: @fa-var-star-o; }
+.@{fa-css-prefix}-user:before { content: @fa-var-user; }
+.@{fa-css-prefix}-film:before { content: @fa-var-film; }
+.@{fa-css-prefix}-th-large:before { content: @fa-var-th-large; }
+.@{fa-css-prefix}-th:before { content: @fa-var-th; }
+.@{fa-css-prefix}-th-list:before { content: @fa-var-th-list; }
+.@{fa-css-prefix}-check:before { content: @fa-var-check; }
+.@{fa-css-prefix}-remove:before,
+.@{fa-css-prefix}-close:before,
+.@{fa-css-prefix}-times:before { content: @fa-var-times; }
+.@{fa-css-prefix}-search-plus:before { content: @fa-var-search-plus; }
+.@{fa-css-prefix}-search-minus:before { content: @fa-var-search-minus; }
+.@{fa-css-prefix}-power-off:before { content: @fa-var-power-off; }
+.@{fa-css-prefix}-signal:before { content: @fa-var-signal; }
+.@{fa-css-prefix}-gear:before,
+.@{fa-css-prefix}-cog:before { content: @fa-var-cog; }
+.@{fa-css-prefix}-trash-o:before { content: @fa-var-trash-o; }
+.@{fa-css-prefix}-home:before { content: @fa-var-home; }
+.@{fa-css-prefix}-file-o:before { content: @fa-var-file-o; }
+.@{fa-css-prefix}-clock-o:before { content: @fa-var-clock-o; }
+.@{fa-css-prefix}-road:before { content: @fa-var-road; }
+.@{fa-css-prefix}-download:before { content: @fa-var-download; }
+.@{fa-css-prefix}-arrow-circle-o-down:before { content: @fa-var-arrow-circle-o-down; }
+.@{fa-css-prefix}-arrow-circle-o-up:before { content: @fa-var-arrow-circle-o-up; }
+.@{fa-css-prefix}-inbox:before { content: @fa-var-inbox; }
+.@{fa-css-prefix}-play-circle-o:before { content: @fa-var-play-circle-o; }
+.@{fa-css-prefix}-rotate-right:before,
+.@{fa-css-prefix}-repeat:before { content: @fa-var-repeat; }
+.@{fa-css-prefix}-refresh:before { content: @fa-var-refresh; }
+.@{fa-css-prefix}-list-alt:before { content: @fa-var-list-alt; }
+.@{fa-css-prefix}-lock:before { content: @fa-var-lock; }
+.@{fa-css-prefix}-flag:before { content: @fa-var-flag; }
+.@{fa-css-prefix}-headphones:before { content: @fa-var-headphones; }
+.@{fa-css-prefix}-volume-off:before { content: @fa-var-volume-off; }
+.@{fa-css-prefix}-volume-down:before { content: @fa-var-volume-down; }
+.@{fa-css-prefix}-volume-up:before { content: @fa-var-volume-up; }
+.@{fa-css-prefix}-qrcode:before { content: @fa-var-qrcode; }
+.@{fa-css-prefix}-barcode:before { content: @fa-var-barcode; }
+.@{fa-css-prefix}-tag:before { content: @fa-var-tag; }
+.@{fa-css-prefix}-tags:before { content: @fa-var-tags; }
+.@{fa-css-prefix}-book:before { content: @fa-var-book; }
+.@{fa-css-prefix}-bookmark:before { content: @fa-var-bookmark; }
+.@{fa-css-prefix}-print:before { content: @fa-var-print; }
+.@{fa-css-prefix}-camera:before { content: @fa-var-camera; }
+.@{fa-css-prefix}-font:before { content: @fa-var-font; }
+.@{fa-css-prefix}-bold:before { content: @fa-var-bold; }
+.@{fa-css-prefix}-italic:before { content: @fa-var-italic; }
+.@{fa-css-prefix}-text-height:before { content: @fa-var-text-height; }
+.@{fa-css-prefix}-text-width:before { content: @fa-var-text-width; }
+.@{fa-css-prefix}-align-left:before { content: @fa-var-align-left; }
+.@{fa-css-prefix}-align-center:before { content: @fa-var-align-center; }
+.@{fa-css-prefix}-align-right:before { content: @fa-var-align-right; }
+.@{fa-css-prefix}-align-justify:before { content: @fa-var-align-justify; }
+.@{fa-css-prefix}-list:before { content: @fa-var-list; }
+.@{fa-css-prefix}-dedent:before,
+.@{fa-css-prefix}-outdent:before { content: @fa-var-outdent; }
+.@{fa-css-prefix}-indent:before { content: @fa-var-indent; }
+.@{fa-css-prefix}-video-camera:before { content: @fa-var-video-camera; }
+.@{fa-css-prefix}-photo:before,
+.@{fa-css-prefix}-image:before,
+.@{fa-css-prefix}-picture-o:before { content: @fa-var-picture-o; }
+.@{fa-css-prefix}-pencil:before { content: @fa-var-pencil; }
+.@{fa-css-prefix}-map-marker:before { content: @fa-var-map-marker; }
+.@{fa-css-prefix}-adjust:before { content: @fa-var-adjust; }
+.@{fa-css-prefix}-tint:before { content: @fa-var-tint; }
+.@{fa-css-prefix}-edit:before,
+.@{fa-css-prefix}-pencil-square-o:before { content: @fa-var-pencil-square-o; }
+.@{fa-css-prefix}-share-square-o:before { content: @fa-var-share-square-o; }
+.@{fa-css-prefix}-check-square-o:before { content: @fa-var-check-square-o; }
+.@{fa-css-prefix}-arrows:before { content: @fa-var-arrows; }
+.@{fa-css-prefix}-step-backward:before { content: @fa-var-step-backward; }
+.@{fa-css-prefix}-fast-backward:before { content: @fa-var-fast-backward; }
+.@{fa-css-prefix}-backward:before { content: @fa-var-backward; }
+.@{fa-css-prefix}-play:before { content: @fa-var-play; }
+.@{fa-css-prefix}-pause:before { content: @fa-var-pause; }
+.@{fa-css-prefix}-stop:before { content: @fa-var-stop; }
+.@{fa-css-prefix}-forward:before { content: @fa-var-forward; }
+.@{fa-css-prefix}-fast-forward:before { content: @fa-var-fast-forward; }
+.@{fa-css-prefix}-step-forward:before { content: @fa-var-step-forward; }
+.@{fa-css-prefix}-eject:before { content: @fa-var-eject; }
+.@{fa-css-prefix}-chevron-left:before { content: @fa-var-chevron-left; }
+.@{fa-css-prefix}-chevron-right:before { content: @fa-var-chevron-right; }
+.@{fa-css-prefix}-plus-circle:before { content: @fa-var-plus-circle; }
+.@{fa-css-prefix}-minus-circle:before { content: @fa-var-minus-circle; }
+.@{fa-css-prefix}-times-circle:before { content: @fa-var-times-circle; }
+.@{fa-css-prefix}-check-circle:before { content: @fa-var-check-circle; }
+.@{fa-css-prefix}-question-circle:before { content: @fa-var-question-circle; }
+.@{fa-css-prefix}-info-circle:before { content: @fa-var-info-circle; }
+.@{fa-css-prefix}-crosshairs:before { content: @fa-var-crosshairs; }
+.@{fa-css-prefix}-times-circle-o:before { content: @fa-var-times-circle-o; }
+.@{fa-css-prefix}-check-circle-o:before { content: @fa-var-check-circle-o; }
+.@{fa-css-prefix}-ban:before { content: @fa-var-ban; }
+.@{fa-css-prefix}-arrow-left:before { content: @fa-var-arrow-left; }
+.@{fa-css-prefix}-arrow-right:before { content: @fa-var-arrow-right; }
+.@{fa-css-prefix}-arrow-up:before { content: @fa-var-arrow-up; }
+.@{fa-css-prefix}-arrow-down:before { content: @fa-var-arrow-down; }
+.@{fa-css-prefix}-mail-forward:before,
+.@{fa-css-prefix}-share:before { content: @fa-var-share; }
+.@{fa-css-prefix}-expand:before { content: @fa-var-expand; }
+.@{fa-css-prefix}-compress:before { content: @fa-var-compress; }
+.@{fa-css-prefix}-plus:before { content: @fa-var-plus; }
+.@{fa-css-prefix}-minus:before { content: @fa-var-minus; }
+.@{fa-css-prefix}-asterisk:before { content: @fa-var-asterisk; }
+.@{fa-css-prefix}-exclamation-circle:before { content: @fa-var-exclamation-circle; }
+.@{fa-css-prefix}-gift:before { content: @fa-var-gift; }
+.@{fa-css-prefix}-leaf:before { content: @fa-var-leaf; }
+.@{fa-css-prefix}-fire:before { content: @fa-var-fire; }
+.@{fa-css-prefix}-eye:before { content: @fa-var-eye; }
+.@{fa-css-prefix}-eye-slash:before { content: @fa-var-eye-slash; }
+.@{fa-css-prefix}-warning:before,
+.@{fa-css-prefix}-exclamation-triangle:before { content: @fa-var-exclamation-triangle; }
+.@{fa-css-prefix}-plane:before { content: @fa-var-plane; }
+.@{fa-css-prefix}-calendar:before { content: @fa-var-calendar; }
+.@{fa-css-prefix}-random:before { content: @fa-var-random; }
+.@{fa-css-prefix}-comment:before { content: @fa-var-comment; }
+.@{fa-css-prefix}-magnet:before { content: @fa-var-magnet; }
+.@{fa-css-prefix}-chevron-up:before { content: @fa-var-chevron-up; }
+.@{fa-css-prefix}-chevron-down:before { content: @fa-var-chevron-down; }
+.@{fa-css-prefix}-retweet:before { content: @fa-var-retweet; }
+.@{fa-css-prefix}-shopping-cart:before { content: @fa-var-shopping-cart; }
+.@{fa-css-prefix}-folder:before { content: @fa-var-folder; }
+.@{fa-css-prefix}-folder-open:before { content: @fa-var-folder-open; }
+.@{fa-css-prefix}-arrows-v:before { content: @fa-var-arrows-v; }
+.@{fa-css-prefix}-arrows-h:before { content: @fa-var-arrows-h; }
+.@{fa-css-prefix}-bar-chart-o:before,
+.@{fa-css-prefix}-bar-chart:before { content: @fa-var-bar-chart; }
+.@{fa-css-prefix}-twitter-square:before { content: @fa-var-twitter-square; }
+.@{fa-css-prefix}-facebook-square:before { content: @fa-var-facebook-square; }
+.@{fa-css-prefix}-camera-retro:before { content: @fa-var-camera-retro; }
+.@{fa-css-prefix}-key:before { content: @fa-var-key; }
+.@{fa-css-prefix}-gears:before,
+.@{fa-css-prefix}-cogs:before { content: @fa-var-cogs; }
+.@{fa-css-prefix}-comments:before { content: @fa-var-comments; }
+.@{fa-css-prefix}-thumbs-o-up:before { content: @fa-var-thumbs-o-up; }
+.@{fa-css-prefix}-thumbs-o-down:before { content: @fa-var-thumbs-o-down; }
+.@{fa-css-prefix}-star-half:before { content: @fa-var-star-half; }
+.@{fa-css-prefix}-heart-o:before { content: @fa-var-heart-o; }
+.@{fa-css-prefix}-sign-out:before { content: @fa-var-sign-out; }
+.@{fa-css-prefix}-linkedin-square:before { content: @fa-var-linkedin-square; }
+.@{fa-css-prefix}-thumb-tack:before { content: @fa-var-thumb-tack; }
+.@{fa-css-prefix}-external-link:before { content: @fa-var-external-link; }
+.@{fa-css-prefix}-sign-in:before { content: @fa-var-sign-in; }
+.@{fa-css-prefix}-trophy:before { content: @fa-var-trophy; }
+.@{fa-css-prefix}-github-square:before { content: @fa-var-github-square; }
+.@{fa-css-prefix}-upload:before { content: @fa-var-upload; }
+.@{fa-css-prefix}-lemon-o:before { content: @fa-var-lemon-o; }
+.@{fa-css-prefix}-phone:before { content: @fa-var-phone; }
+.@{fa-css-prefix}-square-o:before { content: @fa-var-square-o; }
+.@{fa-css-prefix}-bookmark-o:before { content: @fa-var-bookmark-o; }
+.@{fa-css-prefix}-phone-square:before { content: @fa-var-phone-square; }
+.@{fa-css-prefix}-twitter:before { content: @fa-var-twitter; }
+.@{fa-css-prefix}-facebook-f:before,
+.@{fa-css-prefix}-facebook:before { content: @fa-var-facebook; }
+.@{fa-css-prefix}-github:before { content: @fa-var-github; }
+.@{fa-css-prefix}-unlock:before { content: @fa-var-unlock; }
+.@{fa-css-prefix}-credit-card:before { content: @fa-var-credit-card; }
+.@{fa-css-prefix}-feed:before,
+.@{fa-css-prefix}-rss:before { content: @fa-var-rss; }
+.@{fa-css-prefix}-hdd-o:before { content: @fa-var-hdd-o; }
+.@{fa-css-prefix}-bullhorn:before { content: @fa-var-bullhorn; }
+.@{fa-css-prefix}-bell:before { content: @fa-var-bell; }
+.@{fa-css-prefix}-certificate:before { content: @fa-var-certificate; }
+.@{fa-css-prefix}-hand-o-right:before { content: @fa-var-hand-o-right; }
+.@{fa-css-prefix}-hand-o-left:before { content: @fa-var-hand-o-left; }
+.@{fa-css-prefix}-hand-o-up:before { content: @fa-var-hand-o-up; }
+.@{fa-css-prefix}-hand-o-down:before { content: @fa-var-hand-o-down; }
+.@{fa-css-prefix}-arrow-circle-left:before { content: @fa-var-arrow-circle-left; }
+.@{fa-css-prefix}-arrow-circle-right:before { content: @fa-var-arrow-circle-right; }
+.@{fa-css-prefix}-arrow-circle-up:before { content: @fa-var-arrow-circle-up; }
+.@{fa-css-prefix}-arrow-circle-down:before { content: @fa-var-arrow-circle-down; }
+.@{fa-css-prefix}-globe:before { content: @fa-var-globe; }
+.@{fa-css-prefix}-wrench:before { content: @fa-var-wrench; }
+.@{fa-css-prefix}-tasks:before { content: @fa-var-tasks; }
+.@{fa-css-prefix}-filter:before { content: @fa-var-filter; }
+.@{fa-css-prefix}-briefcase:before { content: @fa-var-briefcase; }
+.@{fa-css-prefix}-arrows-alt:before { content: @fa-var-arrows-alt; }
+.@{fa-css-prefix}-group:before,
+.@{fa-css-prefix}-users:before { content: @fa-var-users; }
+.@{fa-css-prefix}-chain:before,
+.@{fa-css-prefix}-link:before { content: @fa-var-link; }
+.@{fa-css-prefix}-cloud:before { content: @fa-var-cloud; }
+.@{fa-css-prefix}-flask:before { content: @fa-var-flask; }
+.@{fa-css-prefix}-cut:before,
+.@{fa-css-prefix}-scissors:before { content: @fa-var-scissors; }
+.@{fa-css-prefix}-copy:before,
+.@{fa-css-prefix}-files-o:before { content: @fa-var-files-o; }
+.@{fa-css-prefix}-paperclip:before { content: @fa-var-paperclip; }
+.@{fa-css-prefix}-save:before,
+.@{fa-css-prefix}-floppy-o:before { content: @fa-var-floppy-o; }
+.@{fa-css-prefix}-square:before { content: @fa-var-square; }
+.@{fa-css-prefix}-navicon:before,
+.@{fa-css-prefix}-reorder:before,
+.@{fa-css-prefix}-bars:before { content: @fa-var-bars; }
+.@{fa-css-prefix}-list-ul:before { content: @fa-var-list-ul; }
+.@{fa-css-prefix}-list-ol:before { content: @fa-var-list-ol; }
+.@{fa-css-prefix}-strikethrough:before { content: @fa-var-strikethrough; }
+.@{fa-css-prefix}-underline:before { content: @fa-var-underline; }
+.@{fa-css-prefix}-table:before { content: @fa-var-table; }
+.@{fa-css-prefix}-magic:before { content: @fa-var-magic; }
+.@{fa-css-prefix}-truck:before { content: @fa-var-truck; }
+.@{fa-css-prefix}-pinterest:before { content: @fa-var-pinterest; }
+.@{fa-css-prefix}-pinterest-square:before { content: @fa-var-pinterest-square; }
+.@{fa-css-prefix}-google-plus-square:before { content: @fa-var-google-plus-square; }
+.@{fa-css-prefix}-google-plus:before { content: @fa-var-google-plus; }
+.@{fa-css-prefix}-money:before { content: @fa-var-money; }
+.@{fa-css-prefix}-caret-down:before { content: @fa-var-caret-down; }
+.@{fa-css-prefix}-caret-up:before { content: @fa-var-caret-up; }
+.@{fa-css-prefix}-caret-left:before { content: @fa-var-caret-left; }
+.@{fa-css-prefix}-caret-right:before { content: @fa-var-caret-right; }
+.@{fa-css-prefix}-columns:before { content: @fa-var-columns; }
+.@{fa-css-prefix}-unsorted:before,
+.@{fa-css-prefix}-sort:before { content: @fa-var-sort; }
+.@{fa-css-prefix}-sort-down:before,
+.@{fa-css-prefix}-sort-desc:before { content: @fa-var-sort-desc; }
+.@{fa-css-prefix}-sort-up:before,
+.@{fa-css-prefix}-sort-asc:before { content: @fa-var-sort-asc; }
+.@{fa-css-prefix}-envelope:before { content: @fa-var-envelope; }
+.@{fa-css-prefix}-linkedin:before { content: @fa-var-linkedin; }
+.@{fa-css-prefix}-rotate-left:before,
+.@{fa-css-prefix}-undo:before { content: @fa-var-undo; }
+.@{fa-css-prefix}-legal:before,
+.@{fa-css-prefix}-gavel:before { content: @fa-var-gavel; }
+.@{fa-css-prefix}-dashboard:before,
+.@{fa-css-prefix}-tachometer:before { content: @fa-var-tachometer; }
+.@{fa-css-prefix}-comment-o:before { content: @fa-var-comment-o; }
+.@{fa-css-prefix}-comments-o:before { content: @fa-var-comments-o; }
+.@{fa-css-prefix}-flash:before,
+.@{fa-css-prefix}-bolt:before { content: @fa-var-bolt; }
+.@{fa-css-prefix}-sitemap:before { content: @fa-var-sitemap; }
+.@{fa-css-prefix}-umbrella:before { content: @fa-var-umbrella; }
+.@{fa-css-prefix}-paste:before,
+.@{fa-css-prefix}-clipboard:before { content: @fa-var-clipboard; }
+.@{fa-css-prefix}-lightbulb-o:before { content: @fa-var-lightbulb-o; }
+.@{fa-css-prefix}-exchange:before { content: @fa-var-exchange; }
+.@{fa-css-prefix}-cloud-download:before { content: @fa-var-cloud-download; }
+.@{fa-css-prefix}-cloud-upload:before { content: @fa-var-cloud-upload; }
+.@{fa-css-prefix}-user-md:before { content: @fa-var-user-md; }
+.@{fa-css-prefix}-stethoscope:before { content: @fa-var-stethoscope; }
+.@{fa-css-prefix}-suitcase:before { content: @fa-var-suitcase; }
+.@{fa-css-prefix}-bell-o:before { content: @fa-var-bell-o; }
+.@{fa-css-prefix}-coffee:before { content: @fa-var-coffee; }
+.@{fa-css-prefix}-cutlery:before { content: @fa-var-cutlery; }
+.@{fa-css-prefix}-file-text-o:before { content: @fa-var-file-text-o; }
+.@{fa-css-prefix}-building-o:before { content: @fa-var-building-o; }
+.@{fa-css-prefix}-hospital-o:before { content: @fa-var-hospital-o; }
+.@{fa-css-prefix}-ambulance:before { content: @fa-var-ambulance; }
+.@{fa-css-prefix}-medkit:before { content: @fa-var-medkit; }
+.@{fa-css-prefix}-fighter-jet:before { content: @fa-var-fighter-jet; }
+.@{fa-css-prefix}-beer:before { content: @fa-var-beer; }
+.@{fa-css-prefix}-h-square:before { content: @fa-var-h-square; }
+.@{fa-css-prefix}-plus-square:before { content: @fa-var-plus-square; }
+.@{fa-css-prefix}-angle-double-left:before { content: @fa-var-angle-double-left; }
+.@{fa-css-prefix}-angle-double-right:before { content: @fa-var-angle-double-right; }
+.@{fa-css-prefix}-angle-double-up:before { content: @fa-var-angle-double-up; }
+.@{fa-css-prefix}-angle-double-down:before { content: @fa-var-angle-double-down; }
+.@{fa-css-prefix}-angle-left:before { content: @fa-var-angle-left; }
+.@{fa-css-prefix}-angle-right:before { content: @fa-var-angle-right; }
+.@{fa-css-prefix}-angle-up:before { content: @fa-var-angle-up; }
+.@{fa-css-prefix}-angle-down:before { content: @fa-var-angle-down; }
+.@{fa-css-prefix}-desktop:before { content: @fa-var-desktop; }
+.@{fa-css-prefix}-laptop:before { content: @fa-var-laptop; }
+.@{fa-css-prefix}-tablet:before { content: @fa-var-tablet; }
+.@{fa-css-prefix}-mobile-phone:before,
+.@{fa-css-prefix}-mobile:before { content: @fa-var-mobile; }
+.@{fa-css-prefix}-circle-o:before { content: @fa-var-circle-o; }
+.@{fa-css-prefix}-quote-left:before { content: @fa-var-quote-left; }
+.@{fa-css-prefix}-quote-right:before { content: @fa-var-quote-right; }
+.@{fa-css-prefix}-spinner:before { content: @fa-var-spinner; }
+.@{fa-css-prefix}-circle:before { content: @fa-var-circle; }
+.@{fa-css-prefix}-mail-reply:before,
+.@{fa-css-prefix}-reply:before { content: @fa-var-reply; }
+.@{fa-css-prefix}-github-alt:before { content: @fa-var-github-alt; }
+.@{fa-css-prefix}-folder-o:before { content: @fa-var-folder-o; }
+.@{fa-css-prefix}-folder-open-o:before { content: @fa-var-folder-open-o; }
+.@{fa-css-prefix}-smile-o:before { content: @fa-var-smile-o; }
+.@{fa-css-prefix}-frown-o:before { content: @fa-var-frown-o; }
+.@{fa-css-prefix}-meh-o:before { content: @fa-var-meh-o; }
+.@{fa-css-prefix}-gamepad:before { content: @fa-var-gamepad; }
+.@{fa-css-prefix}-keyboard-o:before { content: @fa-var-keyboard-o; }
+.@{fa-css-prefix}-flag-o:before { content: @fa-var-flag-o; }
+.@{fa-css-prefix}-flag-checkered:before { content: @fa-var-flag-checkered; }
+.@{fa-css-prefix}-terminal:before { content: @fa-var-terminal; }
+.@{fa-css-prefix}-code:before { content: @fa-var-code; }
+.@{fa-css-prefix}-mail-reply-all:before,
+.@{fa-css-prefix}-reply-all:before { content: @fa-var-reply-all; }
+.@{fa-css-prefix}-star-half-empty:before,
+.@{fa-css-prefix}-star-half-full:before,
+.@{fa-css-prefix}-star-half-o:before { content: @fa-var-star-half-o; }
+.@{fa-css-prefix}-location-arrow:before { content: @fa-var-location-arrow; }
+.@{fa-css-prefix}-crop:before { content: @fa-var-crop; }
+.@{fa-css-prefix}-code-fork:before { content: @fa-var-code-fork; }
+.@{fa-css-prefix}-unlink:before,
+.@{fa-css-prefix}-chain-broken:before { content: @fa-var-chain-broken; }
+.@{fa-css-prefix}-question:before { content: @fa-var-question; }
+.@{fa-css-prefix}-info:before { content: @fa-var-info; }
+.@{fa-css-prefix}-exclamation:before { content: @fa-var-exclamation; }
+.@{fa-css-prefix}-superscript:before { content: @fa-var-superscript; }
+.@{fa-css-prefix}-subscript:before { content: @fa-var-subscript; }
+.@{fa-css-prefix}-eraser:before { content: @fa-var-eraser; }
+.@{fa-css-prefix}-puzzle-piece:before { content: @fa-var-puzzle-piece; }
+.@{fa-css-prefix}-microphone:before { content: @fa-var-microphone; }
+.@{fa-css-prefix}-microphone-slash:before { content: @fa-var-microphone-slash; }
+.@{fa-css-prefix}-shield:before { content: @fa-var-shield; }
+.@{fa-css-prefix}-calendar-o:before { content: @fa-var-calendar-o; }
+.@{fa-css-prefix}-fire-extinguisher:before { content: @fa-var-fire-extinguisher; }
+.@{fa-css-prefix}-rocket:before { content: @fa-var-rocket; }
+.@{fa-css-prefix}-maxcdn:before { content: @fa-var-maxcdn; }
+.@{fa-css-prefix}-chevron-circle-left:before { content: @fa-var-chevron-circle-left; }
+.@{fa-css-prefix}-chevron-circle-right:before { content: @fa-var-chevron-circle-right; }
+.@{fa-css-prefix}-chevron-circle-up:before { content: @fa-var-chevron-circle-up; }
+.@{fa-css-prefix}-chevron-circle-down:before { content: @fa-var-chevron-circle-down; }
+.@{fa-css-prefix}-html5:before { content: @fa-var-html5; }
+.@{fa-css-prefix}-css3:before { content: @fa-var-css3; }
+.@{fa-css-prefix}-anchor:before { content: @fa-var-anchor; }
+.@{fa-css-prefix}-unlock-alt:before { content: @fa-var-unlock-alt; }
+.@{fa-css-prefix}-bullseye:before { content: @fa-var-bullseye; }
+.@{fa-css-prefix}-ellipsis-h:before { content: @fa-var-ellipsis-h; }
+.@{fa-css-prefix}-ellipsis-v:before { content: @fa-var-ellipsis-v; }
+.@{fa-css-prefix}-rss-square:before { content: @fa-var-rss-square; }
+.@{fa-css-prefix}-play-circle:before { content: @fa-var-play-circle; }
+.@{fa-css-prefix}-ticket:before { content: @fa-var-ticket; }
+.@{fa-css-prefix}-minus-square:before { content: @fa-var-minus-square; }
+.@{fa-css-prefix}-minus-square-o:before { content: @fa-var-minus-square-o; }
+.@{fa-css-prefix}-level-up:before { content: @fa-var-level-up; }
+.@{fa-css-prefix}-level-down:before { content: @fa-var-level-down; }
+.@{fa-css-prefix}-check-square:before { content: @fa-var-check-square; }
+.@{fa-css-prefix}-pencil-square:before { content: @fa-var-pencil-square; }
+.@{fa-css-prefix}-external-link-square:before { content: @fa-var-external-link-square; }
+.@{fa-css-prefix}-share-square:before { content: @fa-var-share-square; }
+.@{fa-css-prefix}-compass:before { content: @fa-var-compass; }
+.@{fa-css-prefix}-toggle-down:before,
+.@{fa-css-prefix}-caret-square-o-down:before { content: @fa-var-caret-square-o-down; }
+.@{fa-css-prefix}-toggle-up:before,
+.@{fa-css-prefix}-caret-square-o-up:before { content: @fa-var-caret-square-o-up; }
+.@{fa-css-prefix}-toggle-right:before,
+.@{fa-css-prefix}-caret-square-o-right:before { content: @fa-var-caret-square-o-right; }
+.@{fa-css-prefix}-euro:before,
+.@{fa-css-prefix}-eur:before { content: @fa-var-eur; }
+.@{fa-css-prefix}-gbp:before { content: @fa-var-gbp; }
+.@{fa-css-prefix}-dollar:before,
+.@{fa-css-prefix}-usd:before { content: @fa-var-usd; }
+.@{fa-css-prefix}-rupee:before,
+.@{fa-css-prefix}-inr:before { content: @fa-var-inr; }
+.@{fa-css-prefix}-cny:before,
+.@{fa-css-prefix}-rmb:before,
+.@{fa-css-prefix}-yen:before,
+.@{fa-css-prefix}-jpy:before { content: @fa-var-jpy; }
+.@{fa-css-prefix}-ruble:before,
+.@{fa-css-prefix}-rouble:before,
+.@{fa-css-prefix}-rub:before { content: @fa-var-rub; }
+.@{fa-css-prefix}-won:before,
+.@{fa-css-prefix}-krw:before { content: @fa-var-krw; }
+.@{fa-css-prefix}-bitcoin:before,
+.@{fa-css-prefix}-btc:before { content: @fa-var-btc; }
+.@{fa-css-prefix}-file:before { content: @fa-var-file; }
+.@{fa-css-prefix}-file-text:before { content: @fa-var-file-text; }
+.@{fa-css-prefix}-sort-alpha-asc:before { content: @fa-var-sort-alpha-asc; }
+.@{fa-css-prefix}-sort-alpha-desc:before { content: @fa-var-sort-alpha-desc; }
+.@{fa-css-prefix}-sort-amount-asc:before { content: @fa-var-sort-amount-asc; }
+.@{fa-css-prefix}-sort-amount-desc:before { content: @fa-var-sort-amount-desc; }
+.@{fa-css-prefix}-sort-numeric-asc:before { content: @fa-var-sort-numeric-asc; }
+.@{fa-css-prefix}-sort-numeric-desc:before { content: @fa-var-sort-numeric-desc; }
+.@{fa-css-prefix}-thumbs-up:before { content: @fa-var-thumbs-up; }
+.@{fa-css-prefix}-thumbs-down:before { content: @fa-var-thumbs-down; }
+.@{fa-css-prefix}-youtube-square:before { content: @fa-var-youtube-square; }
+.@{fa-css-prefix}-youtube:before { content: @fa-var-youtube; }
+.@{fa-css-prefix}-xing:before { content: @fa-var-xing; }
+.@{fa-css-prefix}-xing-square:before { content: @fa-var-xing-square; }
+.@{fa-css-prefix}-youtube-play:before { content: @fa-var-youtube-play; }
+.@{fa-css-prefix}-dropbox:before { content: @fa-var-dropbox; }
+.@{fa-css-prefix}-stack-overflow:before { content: @fa-var-stack-overflow; }
+.@{fa-css-prefix}-instagram:before { content: @fa-var-instagram; }
+.@{fa-css-prefix}-flickr:before { content: @fa-var-flickr; }
+.@{fa-css-prefix}-adn:before { content: @fa-var-adn; }
+.@{fa-css-prefix}-bitbucket:before { content: @fa-var-bitbucket; }
+.@{fa-css-prefix}-bitbucket-square:before { content: @fa-var-bitbucket-square; }
+.@{fa-css-prefix}-tumblr:before { content: @fa-var-tumblr; }
+.@{fa-css-prefix}-tumblr-square:before { content: @fa-var-tumblr-square; }
+.@{fa-css-prefix}-long-arrow-down:before { content: @fa-var-long-arrow-down; }
+.@{fa-css-prefix}-long-arrow-up:before { content: @fa-var-long-arrow-up; }
+.@{fa-css-prefix}-long-arrow-left:before { content: @fa-var-long-arrow-left; }
+.@{fa-css-prefix}-long-arrow-right:before { content: @fa-var-long-arrow-right; }
+.@{fa-css-prefix}-apple:before { content: @fa-var-apple; }
+.@{fa-css-prefix}-windows:before { content: @fa-var-windows; }
+.@{fa-css-prefix}-android:before { content: @fa-var-android; }
+.@{fa-css-prefix}-linux:before { content: @fa-var-linux; }
+.@{fa-css-prefix}-dribbble:before { content: @fa-var-dribbble; }
+.@{fa-css-prefix}-skype:before { content: @fa-var-skype; }
+.@{fa-css-prefix}-foursquare:before { content: @fa-var-foursquare; }
+.@{fa-css-prefix}-trello:before { content: @fa-var-trello; }
+.@{fa-css-prefix}-female:before { content: @fa-var-female; }
+.@{fa-css-prefix}-male:before { content: @fa-var-male; }
+.@{fa-css-prefix}-gittip:before,
+.@{fa-css-prefix}-gratipay:before { content: @fa-var-gratipay; }
+.@{fa-css-prefix}-sun-o:before { content: @fa-var-sun-o; }
+.@{fa-css-prefix}-moon-o:before { content: @fa-var-moon-o; }
+.@{fa-css-prefix}-archive:before { content: @fa-var-archive; }
+.@{fa-css-prefix}-bug:before { content: @fa-var-bug; }
+.@{fa-css-prefix}-vk:before { content: @fa-var-vk; }
+.@{fa-css-prefix}-weibo:before { content: @fa-var-weibo; }
+.@{fa-css-prefix}-renren:before { content: @fa-var-renren; }
+.@{fa-css-prefix}-pagelines:before { content: @fa-var-pagelines; }
+.@{fa-css-prefix}-stack-exchange:before { content: @fa-var-stack-exchange; }
+.@{fa-css-prefix}-arrow-circle-o-right:before { content: @fa-var-arrow-circle-o-right; }
+.@{fa-css-prefix}-arrow-circle-o-left:before { content: @fa-var-arrow-circle-o-left; }
+.@{fa-css-prefix}-toggle-left:before,
+.@{fa-css-prefix}-caret-square-o-left:before { content: @fa-var-caret-square-o-left; }
+.@{fa-css-prefix}-dot-circle-o:before { content: @fa-var-dot-circle-o; }
+.@{fa-css-prefix}-wheelchair:before { content: @fa-var-wheelchair; }
+.@{fa-css-prefix}-vimeo-square:before { content: @fa-var-vimeo-square; }
+.@{fa-css-prefix}-turkish-lira:before,
+.@{fa-css-prefix}-try:before { content: @fa-var-try; }
+.@{fa-css-prefix}-plus-square-o:before { content: @fa-var-plus-square-o; }
+.@{fa-css-prefix}-space-shuttle:before { content: @fa-var-space-shuttle; }
+.@{fa-css-prefix}-slack:before { content: @fa-var-slack; }
+.@{fa-css-prefix}-envelope-square:before { content: @fa-var-envelope-square; }
+.@{fa-css-prefix}-wordpress:before { content: @fa-var-wordpress; }
+.@{fa-css-prefix}-openid:before { content: @fa-var-openid; }
+.@{fa-css-prefix}-institution:before,
+.@{fa-css-prefix}-bank:before,
+.@{fa-css-prefix}-university:before { content: @fa-var-university; }
+.@{fa-css-prefix}-mortar-board:before,
+.@{fa-css-prefix}-graduation-cap:before { content: @fa-var-graduation-cap; }
+.@{fa-css-prefix}-yahoo:before { content: @fa-var-yahoo; }
+.@{fa-css-prefix}-google:before { content: @fa-var-google; }
+.@{fa-css-prefix}-reddit:before { content: @fa-var-reddit; }
+.@{fa-css-prefix}-reddit-square:before { content: @fa-var-reddit-square; }
+.@{fa-css-prefix}-stumbleupon-circle:before { content: @fa-var-stumbleupon-circle; }
+.@{fa-css-prefix}-stumbleupon:before { content: @fa-var-stumbleupon; }
+.@{fa-css-prefix}-delicious:before { content: @fa-var-delicious; }
+.@{fa-css-prefix}-digg:before { content: @fa-var-digg; }
+.@{fa-css-prefix}-pied-piper-pp:before { content: @fa-var-pied-piper-pp; }
+.@{fa-css-prefix}-pied-piper-alt:before { content: @fa-var-pied-piper-alt; }
+.@{fa-css-prefix}-drupal:before { content: @fa-var-drupal; }
+.@{fa-css-prefix}-joomla:before { content: @fa-var-joomla; }
+.@{fa-css-prefix}-language:before { content: @fa-var-language; }
+.@{fa-css-prefix}-fax:before { content: @fa-var-fax; }
+.@{fa-css-prefix}-building:before { content: @fa-var-building; }
+.@{fa-css-prefix}-child:before { content: @fa-var-child; }
+.@{fa-css-prefix}-paw:before { content: @fa-var-paw; }
+.@{fa-css-prefix}-spoon:before { content: @fa-var-spoon; }
+.@{fa-css-prefix}-cube:before { content: @fa-var-cube; }
+.@{fa-css-prefix}-cubes:before { content: @fa-var-cubes; }
+.@{fa-css-prefix}-behance:before { content: @fa-var-behance; }
+.@{fa-css-prefix}-behance-square:before { content: @fa-var-behance-square; }
+.@{fa-css-prefix}-steam:before { content: @fa-var-steam; }
+.@{fa-css-prefix}-steam-square:before { content: @fa-var-steam-square; }
+.@{fa-css-prefix}-recycle:before { content: @fa-var-recycle; }
+.@{fa-css-prefix}-automobile:before,
+.@{fa-css-prefix}-car:before { content: @fa-var-car; }
+.@{fa-css-prefix}-cab:before,
+.@{fa-css-prefix}-taxi:before { content: @fa-var-taxi; }
+.@{fa-css-prefix}-tree:before { content: @fa-var-tree; }
+.@{fa-css-prefix}-spotify:before { content: @fa-var-spotify; }
+.@{fa-css-prefix}-deviantart:before { content: @fa-var-deviantart; }
+.@{fa-css-prefix}-soundcloud:before { content: @fa-var-soundcloud; }
+.@{fa-css-prefix}-database:before { content: @fa-var-database; }
+.@{fa-css-prefix}-file-pdf-o:before { content: @fa-var-file-pdf-o; }
+.@{fa-css-prefix}-file-word-o:before { content: @fa-var-file-word-o; }
+.@{fa-css-prefix}-file-excel-o:before { content: @fa-var-file-excel-o; }
+.@{fa-css-prefix}-file-powerpoint-o:before { content: @fa-var-file-powerpoint-o; }
+.@{fa-css-prefix}-file-photo-o:before,
+.@{fa-css-prefix}-file-picture-o:before,
+.@{fa-css-prefix}-file-image-o:before { content: @fa-var-file-image-o; }
+.@{fa-css-prefix}-file-zip-o:before,
+.@{fa-css-prefix}-file-archive-o:before { content: @fa-var-file-archive-o; }
+.@{fa-css-prefix}-file-sound-o:before,
+.@{fa-css-prefix}-file-audio-o:before { content: @fa-var-file-audio-o; }
+.@{fa-css-prefix}-file-movie-o:before,
+.@{fa-css-prefix}-file-video-o:before { content: @fa-var-file-video-o; }
+.@{fa-css-prefix}-file-code-o:before { content: @fa-var-file-code-o; }
+.@{fa-css-prefix}-vine:before { content: @fa-var-vine; }
+.@{fa-css-prefix}-codepen:before { content: @fa-var-codepen; }
+.@{fa-css-prefix}-jsfiddle:before { content: @fa-var-jsfiddle; }
+.@{fa-css-prefix}-life-bouy:before,
+.@{fa-css-prefix}-life-buoy:before,
+.@{fa-css-prefix}-life-saver:before,
+.@{fa-css-prefix}-support:before,
+.@{fa-css-prefix}-life-ring:before { content: @fa-var-life-ring; }
+.@{fa-css-prefix}-circle-o-notch:before { content: @fa-var-circle-o-notch; }
+.@{fa-css-prefix}-ra:before,
+.@{fa-css-prefix}-resistance:before,
+.@{fa-css-prefix}-rebel:before { content: @fa-var-rebel; }
+.@{fa-css-prefix}-ge:before,
+.@{fa-css-prefix}-empire:before { content: @fa-var-empire; }
+.@{fa-css-prefix}-git-square:before { content: @fa-var-git-square; }
+.@{fa-css-prefix}-git:before { content: @fa-var-git; }
+.@{fa-css-prefix}-y-combinator-square:before,
+.@{fa-css-prefix}-yc-square:before,
+.@{fa-css-prefix}-hacker-news:before { content: @fa-var-hacker-news; }
+.@{fa-css-prefix}-tencent-weibo:before { content: @fa-var-tencent-weibo; }
+.@{fa-css-prefix}-qq:before { content: @fa-var-qq; }
+.@{fa-css-prefix}-wechat:before,
+.@{fa-css-prefix}-weixin:before { content: @fa-var-weixin; }
+.@{fa-css-prefix}-send:before,
+.@{fa-css-prefix}-paper-plane:before { content: @fa-var-paper-plane; }
+.@{fa-css-prefix}-send-o:before,
+.@{fa-css-prefix}-paper-plane-o:before { content: @fa-var-paper-plane-o; }
+.@{fa-css-prefix}-history:before { content: @fa-var-history; }
+.@{fa-css-prefix}-circle-thin:before { content: @fa-var-circle-thin; }
+.@{fa-css-prefix}-header:before { content: @fa-var-header; }
+.@{fa-css-prefix}-paragraph:before { content: @fa-var-paragraph; }
+.@{fa-css-prefix}-sliders:before { content: @fa-var-sliders; }
+.@{fa-css-prefix}-share-alt:before { content: @fa-var-share-alt; }
+.@{fa-css-prefix}-share-alt-square:before { content: @fa-var-share-alt-square; }
+.@{fa-css-prefix}-bomb:before { content: @fa-var-bomb; }
+.@{fa-css-prefix}-soccer-ball-o:before,
+.@{fa-css-prefix}-futbol-o:before { content: @fa-var-futbol-o; }
+.@{fa-css-prefix}-tty:before { content: @fa-var-tty; }
+.@{fa-css-prefix}-binoculars:before { content: @fa-var-binoculars; }
+.@{fa-css-prefix}-plug:before { content: @fa-var-plug; }
+.@{fa-css-prefix}-slideshare:before { content: @fa-var-slideshare; }
+.@{fa-css-prefix}-twitch:before { content: @fa-var-twitch; }
+.@{fa-css-prefix}-yelp:before { content: @fa-var-yelp; }
+.@{fa-css-prefix}-newspaper-o:before { content: @fa-var-newspaper-o; }
+.@{fa-css-prefix}-wifi:before { content: @fa-var-wifi; }
+.@{fa-css-prefix}-calculator:before { content: @fa-var-calculator; }
+.@{fa-css-prefix}-paypal:before { content: @fa-var-paypal; }
+.@{fa-css-prefix}-google-wallet:before { content: @fa-var-google-wallet; }
+.@{fa-css-prefix}-cc-visa:before { content: @fa-var-cc-visa; }
+.@{fa-css-prefix}-cc-mastercard:before { content: @fa-var-cc-mastercard; }
+.@{fa-css-prefix}-cc-discover:before { content: @fa-var-cc-discover; }
+.@{fa-css-prefix}-cc-amex:before { content: @fa-var-cc-amex; }
+.@{fa-css-prefix}-cc-paypal:before { content: @fa-var-cc-paypal; }
+.@{fa-css-prefix}-cc-stripe:before { content: @fa-var-cc-stripe; }
+.@{fa-css-prefix}-bell-slash:before { content: @fa-var-bell-slash; }
+.@{fa-css-prefix}-bell-slash-o:before { content: @fa-var-bell-slash-o; }
+.@{fa-css-prefix}-trash:before { content: @fa-var-trash; }
+.@{fa-css-prefix}-copyright:before { content: @fa-var-copyright; }
+.@{fa-css-prefix}-at:before { content: @fa-var-at; }
+.@{fa-css-prefix}-eyedropper:before { content: @fa-var-eyedropper; }
+.@{fa-css-prefix}-paint-brush:before { content: @fa-var-paint-brush; }
+.@{fa-css-prefix}-birthday-cake:before { content: @fa-var-birthday-cake; }
+.@{fa-css-prefix}-area-chart:before { content: @fa-var-area-chart; }
+.@{fa-css-prefix}-pie-chart:before { content: @fa-var-pie-chart; }
+.@{fa-css-prefix}-line-chart:before { content: @fa-var-line-chart; }
+.@{fa-css-prefix}-lastfm:before { content: @fa-var-lastfm; }
+.@{fa-css-prefix}-lastfm-square:before { content: @fa-var-lastfm-square; }
+.@{fa-css-prefix}-toggle-off:before { content: @fa-var-toggle-off; }
+.@{fa-css-prefix}-toggle-on:before { content: @fa-var-toggle-on; }
+.@{fa-css-prefix}-bicycle:before { content: @fa-var-bicycle; }
+.@{fa-css-prefix}-bus:before { content: @fa-var-bus; }
+.@{fa-css-prefix}-ioxhost:before { content: @fa-var-ioxhost; }
+.@{fa-css-prefix}-angellist:before { content: @fa-var-angellist; }
+.@{fa-css-prefix}-cc:before { content: @fa-var-cc; }
+.@{fa-css-prefix}-shekel:before,
+.@{fa-css-prefix}-sheqel:before,
+.@{fa-css-prefix}-ils:before { content: @fa-var-ils; }
+.@{fa-css-prefix}-meanpath:before { content: @fa-var-meanpath; }
+.@{fa-css-prefix}-buysellads:before { content: @fa-var-buysellads; }
+.@{fa-css-prefix}-connectdevelop:before { content: @fa-var-connectdevelop; }
+.@{fa-css-prefix}-dashcube:before { content: @fa-var-dashcube; }
+.@{fa-css-prefix}-forumbee:before { content: @fa-var-forumbee; }
+.@{fa-css-prefix}-leanpub:before { content: @fa-var-leanpub; }
+.@{fa-css-prefix}-sellsy:before { content: @fa-var-sellsy; }
+.@{fa-css-prefix}-shirtsinbulk:before { content: @fa-var-shirtsinbulk; }
+.@{fa-css-prefix}-simplybuilt:before { content: @fa-var-simplybuilt; }
+.@{fa-css-prefix}-skyatlas:before { content: @fa-var-skyatlas; }
+.@{fa-css-prefix}-cart-plus:before { content: @fa-var-cart-plus; }
+.@{fa-css-prefix}-cart-arrow-down:before { content: @fa-var-cart-arrow-down; }
+.@{fa-css-prefix}-diamond:before { content: @fa-var-diamond; }
+.@{fa-css-prefix}-ship:before { content: @fa-var-ship; }
+.@{fa-css-prefix}-user-secret:before { content: @fa-var-user-secret; }
+.@{fa-css-prefix}-motorcycle:before { content: @fa-var-motorcycle; }
+.@{fa-css-prefix}-street-view:before { content: @fa-var-street-view; }
+.@{fa-css-prefix}-heartbeat:before { content: @fa-var-heartbeat; }
+.@{fa-css-prefix}-venus:before { content: @fa-var-venus; }
+.@{fa-css-prefix}-mars:before { content: @fa-var-mars; }
+.@{fa-css-prefix}-mercury:before { content: @fa-var-mercury; }
+.@{fa-css-prefix}-intersex:before,
+.@{fa-css-prefix}-transgender:before { content: @fa-var-transgender; }
+.@{fa-css-prefix}-transgender-alt:before { content: @fa-var-transgender-alt; }
+.@{fa-css-prefix}-venus-double:before { content: @fa-var-venus-double; }
+.@{fa-css-prefix}-mars-double:before { content: @fa-var-mars-double; }
+.@{fa-css-prefix}-venus-mars:before { content: @fa-var-venus-mars; }
+.@{fa-css-prefix}-mars-stroke:before { content: @fa-var-mars-stroke; }
+.@{fa-css-prefix}-mars-stroke-v:before { content: @fa-var-mars-stroke-v; }
+.@{fa-css-prefix}-mars-stroke-h:before { content: @fa-var-mars-stroke-h; }
+.@{fa-css-prefix}-neuter:before { content: @fa-var-neuter; }
+.@{fa-css-prefix}-genderless:before { content: @fa-var-genderless; }
+.@{fa-css-prefix}-facebook-official:before { content: @fa-var-facebook-official; }
+.@{fa-css-prefix}-pinterest-p:before { content: @fa-var-pinterest-p; }
+.@{fa-css-prefix}-whatsapp:before { content: @fa-var-whatsapp; }
+.@{fa-css-prefix}-server:before { content: @fa-var-server; }
+.@{fa-css-prefix}-user-plus:before { content: @fa-var-user-plus; }
+.@{fa-css-prefix}-user-times:before { content: @fa-var-user-times; }
+.@{fa-css-prefix}-hotel:before,
+.@{fa-css-prefix}-bed:before { content: @fa-var-bed; }
+.@{fa-css-prefix}-viacoin:before { content: @fa-var-viacoin; }
+.@{fa-css-prefix}-train:before { content: @fa-var-train; }
+.@{fa-css-prefix}-subway:before { content: @fa-var-subway; }
+.@{fa-css-prefix}-medium:before { content: @fa-var-medium; }
+.@{fa-css-prefix}-yc:before,
+.@{fa-css-prefix}-y-combinator:before { content: @fa-var-y-combinator; }
+.@{fa-css-prefix}-optin-monster:before { content: @fa-var-optin-monster; }
+.@{fa-css-prefix}-opencart:before { content: @fa-var-opencart; }
+.@{fa-css-prefix}-expeditedssl:before { content: @fa-var-expeditedssl; }
+.@{fa-css-prefix}-battery-4:before,
+.@{fa-css-prefix}-battery:before,
+.@{fa-css-prefix}-battery-full:before { content: @fa-var-battery-full; }
+.@{fa-css-prefix}-battery-3:before,
+.@{fa-css-prefix}-battery-three-quarters:before { content: @fa-var-battery-three-quarters; }
+.@{fa-css-prefix}-battery-2:before,
+.@{fa-css-prefix}-battery-half:before { content: @fa-var-battery-half; }
+.@{fa-css-prefix}-battery-1:before,
+.@{fa-css-prefix}-battery-quarter:before { content: @fa-var-battery-quarter; }
+.@{fa-css-prefix}-battery-0:before,
+.@{fa-css-prefix}-battery-empty:before { content: @fa-var-battery-empty; }
+.@{fa-css-prefix}-mouse-pointer:before { content: @fa-var-mouse-pointer; }
+.@{fa-css-prefix}-i-cursor:before { content: @fa-var-i-cursor; }
+.@{fa-css-prefix}-object-group:before { content: @fa-var-object-group; }
+.@{fa-css-prefix}-object-ungroup:before { content: @fa-var-object-ungroup; }
+.@{fa-css-prefix}-sticky-note:before { content: @fa-var-sticky-note; }
+.@{fa-css-prefix}-sticky-note-o:before { content: @fa-var-sticky-note-o; }
+.@{fa-css-prefix}-cc-jcb:before { content: @fa-var-cc-jcb; }
+.@{fa-css-prefix}-cc-diners-club:before { content: @fa-var-cc-diners-club; }
+.@{fa-css-prefix}-clone:before { content: @fa-var-clone; }
+.@{fa-css-prefix}-balance-scale:before { content: @fa-var-balance-scale; }
+.@{fa-css-prefix}-hourglass-o:before { content: @fa-var-hourglass-o; }
+.@{fa-css-prefix}-hourglass-1:before,
+.@{fa-css-prefix}-hourglass-start:before { content: @fa-var-hourglass-start; }
+.@{fa-css-prefix}-hourglass-2:before,
+.@{fa-css-prefix}-hourglass-half:before { content: @fa-var-hourglass-half; }
+.@{fa-css-prefix}-hourglass-3:before,
+.@{fa-css-prefix}-hourglass-end:before { content: @fa-var-hourglass-end; }
+.@{fa-css-prefix}-hourglass:before { content: @fa-var-hourglass; }
+.@{fa-css-prefix}-hand-grab-o:before,
+.@{fa-css-prefix}-hand-rock-o:before { content: @fa-var-hand-rock-o; }
+.@{fa-css-prefix}-hand-stop-o:before,
+.@{fa-css-prefix}-hand-paper-o:before { content: @fa-var-hand-paper-o; }
+.@{fa-css-prefix}-hand-scissors-o:before { content: @fa-var-hand-scissors-o; }
+.@{fa-css-prefix}-hand-lizard-o:before { content: @fa-var-hand-lizard-o; }
+.@{fa-css-prefix}-hand-spock-o:before { content: @fa-var-hand-spock-o; }
+.@{fa-css-prefix}-hand-pointer-o:before { content: @fa-var-hand-pointer-o; }
+.@{fa-css-prefix}-hand-peace-o:before { content: @fa-var-hand-peace-o; }
+.@{fa-css-prefix}-trademark:before { content: @fa-var-trademark; }
+.@{fa-css-prefix}-registered:before { content: @fa-var-registered; }
+.@{fa-css-prefix}-creative-commons:before { content: @fa-var-creative-commons; }
+.@{fa-css-prefix}-gg:before { content: @fa-var-gg; }
+.@{fa-css-prefix}-gg-circle:before { content: @fa-var-gg-circle; }
+.@{fa-css-prefix}-tripadvisor:before { content: @fa-var-tripadvisor; }
+.@{fa-css-prefix}-odnoklassniki:before { content: @fa-var-odnoklassniki; }
+.@{fa-css-prefix}-odnoklassniki-square:before { content: @fa-var-odnoklassniki-square; }
+.@{fa-css-prefix}-get-pocket:before { content: @fa-var-get-pocket; }
+.@{fa-css-prefix}-wikipedia-w:before { content: @fa-var-wikipedia-w; }
+.@{fa-css-prefix}-safari:before { content: @fa-var-safari; }
+.@{fa-css-prefix}-chrome:before { content: @fa-var-chrome; }
+.@{fa-css-prefix}-firefox:before { content: @fa-var-firefox; }
+.@{fa-css-prefix}-opera:before { content: @fa-var-opera; }
+.@{fa-css-prefix}-internet-explorer:before { content: @fa-var-internet-explorer; }
+.@{fa-css-prefix}-tv:before,
+.@{fa-css-prefix}-television:before { content: @fa-var-television; }
+.@{fa-css-prefix}-contao:before { content: @fa-var-contao; }
+.@{fa-css-prefix}-500px:before { content: @fa-var-500px; }
+.@{fa-css-prefix}-amazon:before { content: @fa-var-amazon; }
+.@{fa-css-prefix}-calendar-plus-o:before { content: @fa-var-calendar-plus-o; }
+.@{fa-css-prefix}-calendar-minus-o:before { content: @fa-var-calendar-minus-o; }
+.@{fa-css-prefix}-calendar-times-o:before { content: @fa-var-calendar-times-o; }
+.@{fa-css-prefix}-calendar-check-o:before { content: @fa-var-calendar-check-o; }
+.@{fa-css-prefix}-industry:before { content: @fa-var-industry; }
+.@{fa-css-prefix}-map-pin:before { content: @fa-var-map-pin; }
+.@{fa-css-prefix}-map-signs:before { content: @fa-var-map-signs; }
+.@{fa-css-prefix}-map-o:before { content: @fa-var-map-o; }
+.@{fa-css-prefix}-map:before { content: @fa-var-map; }
+.@{fa-css-prefix}-commenting:before { content: @fa-var-commenting; }
+.@{fa-css-prefix}-commenting-o:before { content: @fa-var-commenting-o; }
+.@{fa-css-prefix}-houzz:before { content: @fa-var-houzz; }
+.@{fa-css-prefix}-vimeo:before { content: @fa-var-vimeo; }
+.@{fa-css-prefix}-black-tie:before { content: @fa-var-black-tie; }
+.@{fa-css-prefix}-fonticons:before { content: @fa-var-fonticons; }
+.@{fa-css-prefix}-reddit-alien:before { content: @fa-var-reddit-alien; }
+.@{fa-css-prefix}-edge:before { content: @fa-var-edge; }
+.@{fa-css-prefix}-credit-card-alt:before { content: @fa-var-credit-card-alt; }
+.@{fa-css-prefix}-codiepie:before { content: @fa-var-codiepie; }
+.@{fa-css-prefix}-modx:before { content: @fa-var-modx; }
+.@{fa-css-prefix}-fort-awesome:before { content: @fa-var-fort-awesome; }
+.@{fa-css-prefix}-usb:before { content: @fa-var-usb; }
+.@{fa-css-prefix}-product-hunt:before { content: @fa-var-product-hunt; }
+.@{fa-css-prefix}-mixcloud:before { content: @fa-var-mixcloud; }
+.@{fa-css-prefix}-scribd:before { content: @fa-var-scribd; }
+.@{fa-css-prefix}-pause-circle:before { content: @fa-var-pause-circle; }
+.@{fa-css-prefix}-pause-circle-o:before { content: @fa-var-pause-circle-o; }
+.@{fa-css-prefix}-stop-circle:before { content: @fa-var-stop-circle; }
+.@{fa-css-prefix}-stop-circle-o:before { content: @fa-var-stop-circle-o; }
+.@{fa-css-prefix}-shopping-bag:before { content: @fa-var-shopping-bag; }
+.@{fa-css-prefix}-shopping-basket:before { content: @fa-var-shopping-basket; }
+.@{fa-css-prefix}-hashtag:before { content: @fa-var-hashtag; }
+.@{fa-css-prefix}-bluetooth:before { content: @fa-var-bluetooth; }
+.@{fa-css-prefix}-bluetooth-b:before { content: @fa-var-bluetooth-b; }
+.@{fa-css-prefix}-percent:before { content: @fa-var-percent; }
+.@{fa-css-prefix}-gitlab:before { content: @fa-var-gitlab; }
+.@{fa-css-prefix}-wpbeginner:before { content: @fa-var-wpbeginner; }
+.@{fa-css-prefix}-wpforms:before { content: @fa-var-wpforms; }
+.@{fa-css-prefix}-envira:before { content: @fa-var-envira; }
+.@{fa-css-prefix}-universal-access:before { content: @fa-var-universal-access; }
+.@{fa-css-prefix}-wheelchair-alt:before { content: @fa-var-wheelchair-alt; }
+.@{fa-css-prefix}-question-circle-o:before { content: @fa-var-question-circle-o; }
+.@{fa-css-prefix}-blind:before { content: @fa-var-blind; }
+.@{fa-css-prefix}-audio-description:before { content: @fa-var-audio-description; }
+.@{fa-css-prefix}-volume-control-phone:before { content: @fa-var-volume-control-phone; }
+.@{fa-css-prefix}-braille:before { content: @fa-var-braille; }
+.@{fa-css-prefix}-assistive-listening-systems:before { content: @fa-var-assistive-listening-systems; }
+.@{fa-css-prefix}-asl-interpreting:before,
+.@{fa-css-prefix}-american-sign-language-interpreting:before { content: @fa-var-american-sign-language-interpreting; }
+.@{fa-css-prefix}-deafness:before,
+.@{fa-css-prefix}-hard-of-hearing:before,
+.@{fa-css-prefix}-deaf:before { content: @fa-var-deaf; }
+.@{fa-css-prefix}-glide:before { content: @fa-var-glide; }
+.@{fa-css-prefix}-glide-g:before { content: @fa-var-glide-g; }
+.@{fa-css-prefix}-signing:before,
+.@{fa-css-prefix}-sign-language:before { content: @fa-var-sign-language; }
+.@{fa-css-prefix}-low-vision:before { content: @fa-var-low-vision; }
+.@{fa-css-prefix}-viadeo:before { content: @fa-var-viadeo; }
+.@{fa-css-prefix}-viadeo-square:before { content: @fa-var-viadeo-square; }
+.@{fa-css-prefix}-snapchat:before { content: @fa-var-snapchat; }
+.@{fa-css-prefix}-snapchat-ghost:before { content: @fa-var-snapchat-ghost; }
+.@{fa-css-prefix}-snapchat-square:before { content: @fa-var-snapchat-square; }
+.@{fa-css-prefix}-pied-piper:before { content: @fa-var-pied-piper; }
+.@{fa-css-prefix}-first-order:before { content: @fa-var-first-order; }
+.@{fa-css-prefix}-yoast:before { content: @fa-var-yoast; }
+.@{fa-css-prefix}-themeisle:before { content: @fa-var-themeisle; }
+.@{fa-css-prefix}-google-plus-circle:before,
+.@{fa-css-prefix}-google-plus-official:before { content: @fa-var-google-plus-official; }
+.@{fa-css-prefix}-fa:before,
+.@{fa-css-prefix}-font-awesome:before { content: @fa-var-font-awesome; }
+.@{fa-css-prefix}-handshake-o:before { content: @fa-var-handshake-o; }
+.@{fa-css-prefix}-envelope-open:before { content: @fa-var-envelope-open; }
+.@{fa-css-prefix}-envelope-open-o:before { content: @fa-var-envelope-open-o; }
+.@{fa-css-prefix}-linode:before { content: @fa-var-linode; }
+.@{fa-css-prefix}-address-book:before { content: @fa-var-address-book; }
+.@{fa-css-prefix}-address-book-o:before { content: @fa-var-address-book-o; }
+.@{fa-css-prefix}-vcard:before,
+.@{fa-css-prefix}-address-card:before { content: @fa-var-address-card; }
+.@{fa-css-prefix}-vcard-o:before,
+.@{fa-css-prefix}-address-card-o:before { content: @fa-var-address-card-o; }
+.@{fa-css-prefix}-user-circle:before { content: @fa-var-user-circle; }
+.@{fa-css-prefix}-user-circle-o:before { content: @fa-var-user-circle-o; }
+.@{fa-css-prefix}-user-o:before { content: @fa-var-user-o; }
+.@{fa-css-prefix}-id-badge:before { content: @fa-var-id-badge; }
+.@{fa-css-prefix}-drivers-license:before,
+.@{fa-css-prefix}-id-card:before { content: @fa-var-id-card; }
+.@{fa-css-prefix}-drivers-license-o:before,
+.@{fa-css-prefix}-id-card-o:before { content: @fa-var-id-card-o; }
+.@{fa-css-prefix}-quora:before { content: @fa-var-quora; }
+.@{fa-css-prefix}-free-code-camp:before { content: @fa-var-free-code-camp; }
+.@{fa-css-prefix}-telegram:before { content: @fa-var-telegram; }
+.@{fa-css-prefix}-thermometer-4:before,
+.@{fa-css-prefix}-thermometer:before,
+.@{fa-css-prefix}-thermometer-full:before { content: @fa-var-thermometer-full; }
+.@{fa-css-prefix}-thermometer-3:before,
+.@{fa-css-prefix}-thermometer-three-quarters:before { content: @fa-var-thermometer-three-quarters; }
+.@{fa-css-prefix}-thermometer-2:before,
+.@{fa-css-prefix}-thermometer-half:before { content: @fa-var-thermometer-half; }
+.@{fa-css-prefix}-thermometer-1:before,
+.@{fa-css-prefix}-thermometer-quarter:before { content: @fa-var-thermometer-quarter; }
+.@{fa-css-prefix}-thermometer-0:before,
+.@{fa-css-prefix}-thermometer-empty:before { content: @fa-var-thermometer-empty; }
+.@{fa-css-prefix}-shower:before { content: @fa-var-shower; }
+.@{fa-css-prefix}-bathtub:before,
+.@{fa-css-prefix}-s15:before,
+.@{fa-css-prefix}-bath:before { content: @fa-var-bath; }
+.@{fa-css-prefix}-podcast:before { content: @fa-var-podcast; }
+.@{fa-css-prefix}-window-maximize:before { content: @fa-var-window-maximize; }
+.@{fa-css-prefix}-window-minimize:before { content: @fa-var-window-minimize; }
+.@{fa-css-prefix}-window-restore:before { content: @fa-var-window-restore; }
+.@{fa-css-prefix}-times-rectangle:before,
+.@{fa-css-prefix}-window-close:before { content: @fa-var-window-close; }
+.@{fa-css-prefix}-times-rectangle-o:before,
+.@{fa-css-prefix}-window-close-o:before { content: @fa-var-window-close-o; }
+.@{fa-css-prefix}-bandcamp:before { content: @fa-var-bandcamp; }
+.@{fa-css-prefix}-grav:before { content: @fa-var-grav; }
+.@{fa-css-prefix}-etsy:before { content: @fa-var-etsy; }
+.@{fa-css-prefix}-imdb:before { content: @fa-var-imdb; }
+.@{fa-css-prefix}-ravelry:before { content: @fa-var-ravelry; }
+.@{fa-css-prefix}-eercast:before { content: @fa-var-eercast; }
+.@{fa-css-prefix}-microchip:before { content: @fa-var-microchip; }
+.@{fa-css-prefix}-snowflake-o:before { content: @fa-var-snowflake-o; }
+.@{fa-css-prefix}-superpowers:before { content: @fa-var-superpowers; }
+.@{fa-css-prefix}-wpexplorer:before { content: @fa-var-wpexplorer; }
+.@{fa-css-prefix}-meetup:before { content: @fa-var-meetup; }

+ 13 - 0
apps/admin/view/default/font-awesome/less/larger.less

@@ -0,0 +1,13 @@
+// Icon Sizes
+// -------------------------
+
+/* makes the font 33% larger relative to the icon container */
+.@{fa-css-prefix}-lg {
+  font-size: (4em / 3);
+  line-height: (3em / 4);
+  vertical-align: -15%;
+}
+.@{fa-css-prefix}-2x { font-size: 2em; }
+.@{fa-css-prefix}-3x { font-size: 3em; }
+.@{fa-css-prefix}-4x { font-size: 4em; }
+.@{fa-css-prefix}-5x { font-size: 5em; }

+ 19 - 0
apps/admin/view/default/font-awesome/less/list.less

@@ -0,0 +1,19 @@
+// List Icons
+// -------------------------
+
+.@{fa-css-prefix}-ul {
+  padding-left: 0;
+  margin-left: @fa-li-width;
+  list-style-type: none;
+  > li { position: relative; }
+}
+.@{fa-css-prefix}-li {
+  position: absolute;
+  left: -@fa-li-width;
+  width: @fa-li-width;
+  top: (2em / 14);
+  text-align: center;
+  &.@{fa-css-prefix}-lg {
+    left: (-@fa-li-width + (4em / 14));
+  }
+}

+ 60 - 0
apps/admin/view/default/font-awesome/less/mixins.less

@@ -0,0 +1,60 @@
+// Mixins
+// --------------------------
+
+.fa-icon() {
+  display: inline-block;
+  font: normal normal normal @fa-font-size-base/@fa-line-height-base FontAwesome; // shortening font declaration
+  font-size: inherit; // can't have font-size inherit on line above, so need to override
+  text-rendering: auto; // optimizelegibility throws things off #1094
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+
+}
+
+.fa-icon-rotate(@degrees, @rotation) {
+  -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=@{rotation})";
+  -webkit-transform: rotate(@degrees);
+      -ms-transform: rotate(@degrees);
+          transform: rotate(@degrees);
+}
+
+.fa-icon-flip(@horiz, @vert, @rotation) {
+  -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=@{rotation}, mirror=1)";
+  -webkit-transform: scale(@horiz, @vert);
+      -ms-transform: scale(@horiz, @vert);
+          transform: scale(@horiz, @vert);
+}
+
+
+// Only display content to screen readers. A la Bootstrap 4.
+//
+// See: http://a11yproject.com/posts/how-to-hide-content/
+
+.sr-only() {
+  position: absolute;
+  width: 1px;
+  height: 1px;
+  padding: 0;
+  margin: -1px;
+  overflow: hidden;
+  clip: rect(0,0,0,0);
+  border: 0;
+}
+
+// Use in conjunction with .sr-only to only display content when it's focused.
+//
+// Useful for "Skip to main content" links; see http://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1
+//
+// Credit: HTML5 Boilerplate
+
+.sr-only-focusable() {
+  &:active,
+  &:focus {
+    position: static;
+    width: auto;
+    height: auto;
+    margin: 0;
+    overflow: visible;
+    clip: auto;
+  }
+}

+ 0 - 0
apps/admin/view/default/font-awesome/less/path.less


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