Browse Source

统一修改文件换行符
修复后台提示两次的BUG
修复上传不能传xls和xlsx文件的BUG

Karson 7 years ago
parent
commit
a0eca04ae9
54 changed files with 5708 additions and 5646 deletions
  1. 42 42
      .travis.yml
  2. 190 190
      LICENSE
  3. 40 40
      application/admin/command/Addon/stubs/config.stub
  4. 6 6
      application/admin/command/Addon/stubs/info.stub
  5. 37 37
      application/admin/command/Crud/stubs/controller.stub
  6. 33 33
      application/admin/command/Crud/stubs/model.stub
  7. 12 12
      application/admin/command/Crud/stubs/relationmodel.stub
  8. 27 27
      application/admin/command/Crud/stubs/validate.stub
  9. 1 1
      application/admin/common.php
  10. 349 349
      application/admin/controller/Addon.php
  11. 283 283
      application/admin/controller/Ajax.php
  12. 83 83
      application/admin/controller/Category.php
  13. 50 50
      application/admin/controller/Dashboard.php
  14. 103 103
      application/admin/controller/Index.php
  15. 95 95
      application/admin/controller/general/Attachment.php
  16. 229 229
      application/admin/controller/general/Config.php
  17. 82 82
      application/admin/controller/general/Profile.php
  18. 394 394
      application/admin/library/traits/Backend.php
  19. 34 34
      application/admin/model/Admin.php
  20. 74 74
      application/admin/model/AdminLog.php
  21. 21 21
      application/admin/model/AuthGroup.php
  22. 10 10
      application/admin/model/AuthGroupAccess.php
  23. 20 20
      application/admin/model/AuthRule.php
  24. 18 18
      application/admin/tags.php
  25. 27 27
      application/admin/validate/Category.php
  26. 25 25
      application/build.php
  27. 19 19
      application/command.php
  28. 302 302
      application/common.php
  29. 15 15
      application/common/controller/Api.php
  30. 461 461
      application/common/controller/Backend.php
  31. 83 83
      application/common/controller/Frontend.php
  32. 19 19
      application/common/model/Attachment.php
  33. 161 161
      application/common/model/Config.php
  34. 249 249
      application/config.php
  35. 2 2
      application/extra/addons.php
  36. 115 115
      application/index/controller/Ajax.php
  37. 28 28
      application/index/controller/Index.php
  38. 216 216
      application/index/view/index/index.html
  39. 30 30
      application/route.php
  40. 34 34
      application/tags.php
  41. 25 25
      build.php
  42. 32 32
      composer.json
  43. 187 187
      extend/fast/Rsa.php
  44. 8 8
      public/.htaccess
  45. 34 34
      public/admin.php
  46. 1 1
      public/assets/css/backend.min.css
  47. 560 499
      public/assets/js/require-backend.min.js
  48. 1 0
      public/assets/js/require-form.js
  49. 770 770
      public/assets/less/backend.less
  50. 12 12
      public/assets/less/frontend.less
  51. 24 24
      public/index.php
  52. 2 2
      public/robots.txt
  53. 17 17
      public/router.php
  54. 16 16
      think

File diff suppressed because it is too large
+ 42 - 42
.travis.yml


+ 190 - 190
LICENSE

@@ -1,191 +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 2017 Karson
-
-   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
+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 2017 Karson
+
+   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.

+ 40 - 40
application/admin/command/Addon/stubs/config.stub

@@ -1,40 +1,40 @@
-<?php
-
-return [
-    [
-        //配置唯一标识
-        'name'    => 'usernmae',
-        //显示的标题
-        'title'   => '用户名',
-        //类型
-        'type'    => 'string',
-        //数据字典
-        'content' => [
-        ],
-        //值
-        'value'   => '',
-        //验证规则 
-        'rule'    => 'required',
-        //错误消息
-        'msg'     => '',
-        //提示消息
-        'tip'     => '',
-        //成功消息
-        'ok'      => '',
-        //扩展信息
-        'extend'  => ''
-    ],
-    [
-        'name'    => 'password',
-        'title'   => '密码',
-        'type'    => 'string',
-        'content' => [
-        ],
-        'value'   => '',
-        'rule'    => 'required',
-        'msg'     => '',
-        'tip'     => '',
-        'ok'      => '',
-        'extend'  => ''
-    ],
-];
+<?php
+
+return [
+    [
+        //配置唯一标识
+        'name'    => 'usernmae',
+        //显示的标题
+        'title'   => '用户名',
+        //类型
+        'type'    => 'string',
+        //数据字典
+        'content' => [
+        ],
+        //值
+        'value'   => '',
+        //验证规则 
+        'rule'    => 'required',
+        //错误消息
+        'msg'     => '',
+        //提示消息
+        'tip'     => '',
+        //成功消息
+        'ok'      => '',
+        //扩展信息
+        'extend'  => ''
+    ],
+    [
+        'name'    => 'password',
+        'title'   => '密码',
+        'type'    => 'string',
+        'content' => [
+        ],
+        'value'   => '',
+        'rule'    => 'required',
+        'msg'     => '',
+        'tip'     => '',
+        'ok'      => '',
+        'extend'  => ''
+    ],
+];

+ 6 - 6
application/admin/command/Addon/stubs/info.stub

@@ -1,7 +1,7 @@
-name = {%name%}
-title = 插件名称
-intro = FastAdmin插件
-author = yourname
-website = http://www.fastadmin.net
-version = 1.0.0
+name = {%name%}
+title = 插件名称
+intro = FastAdmin插件
+author = yourname
+website = http://www.fastadmin.net
+version = 1.0.0
 state = 1

+ 37 - 37
application/admin/command/Crud/stubs/controller.stub

@@ -1,37 +1,37 @@
-<?php
-
-namespace {%controllerNamespace%};
-
-use app\common\controller\Backend;
-
-use think\Controller;
-use think\Request;
-
-/**
- * {%tableComment%}
- *
- * @icon {%iconName%}
- */
-class {%controllerName%} extends Backend
-{
-    
-    /**
-     * {%modelName%}模型对象
-     */
-    protected $model = null;
-
-    public function _initialize()
-    {
-        parent::_initialize();
-        $this->model = model('{%modelName%}');
-{%controllerAssignList%}
-    }
-    
-    /**
-     * 默认生成的控制器所继承的父类中有index/add/edit/del/multi五个方法
-     * 因此在当前控制器中可不用编写增删改查的代码,如果需要自己控制这部分逻辑
-     * 需要将application/admin/library/traits/Backend.php中对应的方法复制到当前控制器,然后进行修改
-     */
-    
-{%controllerIndex%}
-}
+<?php
+
+namespace {%controllerNamespace%};
+
+use app\common\controller\Backend;
+
+use think\Controller;
+use think\Request;
+
+/**
+ * {%tableComment%}
+ *
+ * @icon {%iconName%}
+ */
+class {%controllerName%} extends Backend
+{
+    
+    /**
+     * {%modelName%}模型对象
+     */
+    protected $model = null;
+
+    public function _initialize()
+    {
+        parent::_initialize();
+        $this->model = model('{%modelName%}');
+{%controllerAssignList%}
+    }
+    
+    /**
+     * 默认生成的控制器所继承的父类中有index/add/edit/del/multi五个方法
+     * 因此在当前控制器中可不用编写增删改查的代码,如果需要自己控制这部分逻辑
+     * 需要将application/admin/library/traits/Backend.php中对应的方法复制到当前控制器,然后进行修改
+     */
+    
+{%controllerIndex%}
+}

+ 33 - 33
application/admin/command/Crud/stubs/model.stub

@@ -1,33 +1,33 @@
-<?php
-
-namespace {%modelNamespace%};
-
-use think\Model;
-
-class {%modelName%} extends Model
-{
-    // 表名
-    protected ${%modelTableType%} = '{%modelTableName%}';
-    
-    // 自动写入时间戳字段
-    protected $autoWriteTimestamp = {%modelAutoWriteTimestamp%};
-
-    // 定义时间戳字段名
-    protected $createTime = {%createTime%};
-    protected $updateTime = {%updateTime%};
-    
-    // 追加属性
-    protected $append = [
-{%appendAttrList%}
-    ];
-    
-{%modelInit%}
-    
-{%getEnumList%}
-
-{%getAttrList%}
-
-{%setAttrList%}
-
-{%modelRelationMethod%}
-}
+<?php
+
+namespace {%modelNamespace%};
+
+use think\Model;
+
+class {%modelName%} extends Model
+{
+    // 表名
+    protected ${%modelTableType%} = '{%modelTableName%}';
+    
+    // 自动写入时间戳字段
+    protected $autoWriteTimestamp = {%modelAutoWriteTimestamp%};
+
+    // 定义时间戳字段名
+    protected $createTime = {%createTime%};
+    protected $updateTime = {%updateTime%};
+    
+    // 追加属性
+    protected $append = [
+{%appendAttrList%}
+    ];
+    
+{%modelInit%}
+    
+{%getEnumList%}
+
+{%getAttrList%}
+
+{%setAttrList%}
+
+{%modelRelationMethod%}
+}

+ 12 - 12
application/admin/command/Crud/stubs/relationmodel.stub

@@ -1,12 +1,12 @@
-<?php
-
-namespace {%modelNamespace%};
-
-use think\Model;
-
-class {%relationModelName%} extends Model
-{
-    // 表名
-    protected ${%relationModelTableType%} = '{%relationModelTableName%}';
-    
-}
+<?php
+
+namespace {%modelNamespace%};
+
+use think\Model;
+
+class {%relationModelName%} extends Model
+{
+    // 表名
+    protected ${%relationModelTableType%} = '{%relationModelTableName%}';
+    
+}

+ 27 - 27
application/admin/command/Crud/stubs/validate.stub

@@ -1,27 +1,27 @@
-<?php
-
-namespace {%validateNamespace%};
-
-use think\Validate;
-
-class {%validateName%} extends Validate
-{
-    /**
-     * 验证规则
-     */
-    protected $rule = [
-    ];
-    /**
-     * 提示消息
-     */
-    protected $message = [
-    ];
-    /**
-     * 验证场景
-     */
-    protected $scene = [
-        'add'  => [],
-        'edit' => [],
-    ];
-    
-}
+<?php
+
+namespace {%validateNamespace%};
+
+use think\Validate;
+
+class {%validateName%} extends Validate
+{
+    /**
+     * 验证规则
+     */
+    protected $rule = [
+    ];
+    /**
+     * 提示消息
+     */
+    protected $message = [
+    ];
+    /**
+     * 验证场景
+     */
+    protected $scene = [
+        'add'  => [],
+        'edit' => [],
+    ];
+    
+}

+ 1 - 1
application/admin/common.php

@@ -114,7 +114,7 @@ function build_toolbar($btns = NULL, $attr = [])
             continue;
         }
         list($href, $class, $icon, $text, $title) = $btnAttr[$v];
-        $extend = $v == 'import' ? 'id="btn-import-' . \fast\Random::alpha() . '" data-url="ajax/upload" data-mimetype="csv,xsl,xslx" data-multiple="false"' : '';
+        $extend = $v == 'import' ? 'id="btn-import-' . \fast\Random::alpha() . '" data-url="ajax/upload" data-mimetype="csv,xls,xlsx" data-multiple="false"' : '';
         $html[] = '<a href="' . $href . '" class="' . $class . '" title="' . $title . '" ' . $extend . '><i class="' . $icon . '"></i> ' . $text . '</a>';
     }
     return implode(' ', $html);

+ 349 - 349
application/admin/controller/Addon.php

@@ -1,349 +1,349 @@
-<?php
-
-namespace app\admin\controller;
-
-use app\common\controller\Backend;
-use think\addons\AddonException;
-use think\addons\Service;
-use think\Config;
-use think\Exception;
-
-/**
- * 插件管理
- *
- * @icon fa fa-circle-o
- */
-class Addon extends Backend
-{
-
-    protected $model = null;
-
-    public function _initialize()
-    {
-        parent::_initialize();
-    }
-
-    /**
-     * 查看
-     */
-    public function index()
-    {
-        $addons = get_addon_list();
-        foreach ($addons as $k => &$v)
-        {
-            $config = get_addon_config($v['name']);
-            $v['config'] = $config ? 1 : 0;
-        }
-        $this->assignconfig(['addons' => $addons]);
-        return $this->view->fetch();
-    }
-
-    /**
-     * 配置
-     */
-    public function config($ids = NULL)
-    {
-        $name = $this->request->get("name");
-        if (!$name)
-        {
-            $this->error(__('Parameter %s can not be empty', $ids ? 'id' : 'name'));
-        }
-        if (!is_dir(ADDON_PATH . $name))
-        {
-            $this->error(__('Directory not found'));
-        }
-        $info = get_addon_info($name);
-        $config = get_addon_fullconfig($name);
-        if (!$info)
-            $this->error(__('No Results were found'));
-        if ($this->request->isPost())
-        {
-            $params = $this->request->post("row/a");
-            if ($params)
-            {
-                $configList = [];
-                foreach ($config as $k => &$v)
-                {
-                    if (isset($params[$v['name']]))
-                    {
-                        if ($v['type'] == 'array')
-                        {
-                            $fieldarr = $valuearr = [];
-                            $field = $params[$v['name']]['field'];
-                            $value = $params[$v['name']]['value'];
-
-                            foreach ($field as $m => $n)
-                            {
-                                if ($n != '')
-                                {
-                                    $fieldarr[] = $field[$m];
-                                    $valuearr[] = $value[$m];
-                                }
-                            }
-                            $params[$v['name']] = array_combine($fieldarr, $valuearr);
-                            $value = $params[$v['name']];
-                        }
-                        else
-                        {
-                            $value = is_array($params[$v['name']]) ? implode(',', $params[$v['name']]) : $params[$v['name']];
-                        }
-
-                        $v['value'] = $value;
-                    }
-                }
-                try
-                {
-                    //更新配置文件
-                    set_addon_fullconfig($name, $config);
-                    $this->success();
-                }
-                catch (Exception $e)
-                {
-                    $this->error($e->getMessage());
-                }
-            }
-            $this->error(__('Parameter %s can not be empty', ''));
-        }
-        $this->view->assign("addon", ['info' => $info, 'config' => $config]);
-        return $this->view->fetch();
-    }
-
-    /**
-     * 安装
-     */
-    public function install()
-    {
-        $name = $this->request->post("name");
-        $force = (int) $this->request->post("force");
-        if (!$name)
-        {
-            $this->error(__('Parameter %s can not be empty', 'name'));
-        }
-        try
-        {
-            $uid = $this->request->post("uid");
-            $token = $this->request->post("token");
-            Service::install($name, $force, ['uid' => $uid, 'token' => $token]);
-            $info = get_addon_info($name);
-            $info['config'] = get_addon_config($name) ? 1 : 0;
-            $this->success(__('Install successful'), null, ['addon' => $info]);
-        }
-        catch (AddonException $e)
-        {
-            $this->result($e->getData(), $e->getCode(), $e->getMessage());
-        }
-        catch (Exception $e)
-        {
-            $this->error($e->getMessage(), $e->getCode());
-        }
-    }
-
-    /**
-     * 卸载
-     */
-    public function uninstall()
-    {
-        $name = $this->request->post("name");
-        $force = (int) $this->request->post("force");
-        if (!$name)
-        {
-            $this->error(__('Parameter %s can not be empty', 'name'));
-        }
-        try
-        {
-            Service::uninstall($name, $force);
-            $this->success(__('Uninstall successful'));
-        }
-        catch (AddonException $e)
-        {
-            $this->result($e->getData(), $e->getCode(), $e->getMessage());
-        }
-        catch (Exception $e)
-        {
-            $this->error($e->getMessage());
-        }
-    }
-
-    /**
-     * 禁用启用
-     */
-    public function state()
-    {
-        $name = $this->request->post("name");
-        $action = $this->request->post("action");
-        $force = (int) $this->request->post("force");
-        if (!$name)
-        {
-            $this->error(__('Parameter %s can not be empty', 'name'));
-        }
-        try
-        {
-            $action = $action == 'enable' ? $action : 'disable';
-            //调用启用、禁用的方法
-            Service::$action($name, $force);
-            $this->success(__('Operate successful'));
-        }
-        catch (AddonException $e)
-        {
-            $this->result($e->getData(), $e->getCode(), $e->getMessage());
-        }
-        catch (Exception $e)
-        {
-            $this->error($e->getMessage());
-        }
-    }
-
-    /**
-     * 本地上传
-     */
-    public function local()
-    {
-        Config::set('default_return_type', 'json');
-
-        $file = $this->request->file('file');
-        $addonTmpDir = RUNTIME_PATH . 'addons' . DS;
-        if (!is_dir($addonTmpDir))
-        {
-            @mkdir($addonTmpDir, 0755, true);
-        }
-        $info = $file->rule('uniqid')->validate(['size' => 10240000, 'ext' => 'zip'])->move($addonTmpDir);
-        if ($info)
-        {
-            $tmpName = substr($info->getFilename(), 0, stripos($info->getFilename(), '.'));
-            $tmpAddonDir = ADDON_PATH . $tmpName . DS;
-            $tmpFile = $addonTmpDir . $info->getSaveName();
-            try
-            {
-                Service::unzip($tmpName);
-                @unlink($tmpFile);
-                $infoFile = $tmpAddonDir . 'info.ini';
-                if (!is_file($infoFile))
-                {
-                    throw new Exception(__('Addon info file was not found'));
-                }
-
-                $config = Config::parse($infoFile, '', $tmpName);
-                $name = isset($config['name']) ? $config['name'] : '';
-                if (!$name)
-                {
-                    throw new Exception(__('Addon info file data incorrect'));
-                }
-
-                $newAddonDir = ADDON_PATH . $name . DS;
-                if (is_dir($newAddonDir))
-                {
-                    throw new Exception(__('Addon already exists'));
-                }
-
-                //重命名插件文件夹
-                rename($tmpAddonDir, $newAddonDir);
-                try
-                {
-                    //默认禁用该插件
-                    $info = get_addon_info($name);
-                    if ($info['state'])
-                    {
-                        $info['state'] = 0;
-                        set_addon_info($name, $info);
-                    }
-
-                    //执行插件的安装方法
-                    $class = get_addon_class($name);
-                    if (class_exists($class))
-                    {
-                        $addon = new $class();
-                        $addon->install();
-                    }
-
-                    //导入SQL
-                    Service::importsql($name);
-
-                    $info['config'] = get_addon_config($name) ? 1 : 0;
-                    $this->success(__('Offline installed tips'), null, ['addon' => $info]);
-                }
-                catch (Exception $e)
-                {
-                    @rmdirs($newAddonDir);
-                    throw new Exception($e->getMessage());
-                }
-            }
-            catch (Exception $e)
-            {
-                @unlink($tmpFile);
-                @rmdirs($tmpAddonDir);
-                $this->error($e->getMessage());
-            }
-        }
-        else
-        {
-            // 上传失败获取错误信息
-            $this->error($file->getError());
-        }
-    }
-
-    /**
-     * 刷新缓存
-     */
-    public function refresh()
-    {
-        try
-        {
-            Service::refresh();
-            $this->success(__('Operate successful'));
-        }
-        catch (Exception $e)
-        {
-            $this->error($e->getMessage());
-        }
-    }
-
-    /**
-     * 已装插件
-     */
-    public function downloaded()
-    {
-        $offset = (int) $this->request->get("offset");
-        $limit = (int) $this->request->get("limit");
-        $filter = $this->request->get("filter");
-        $filter = (array) json_decode($filter, true);
-        foreach ($filter as $k => &$v)
-        {
-            $v = htmlspecialchars(strip_tags($v));
-        }
-        unset($v);
-        $where = ['status' => 'normal'];
-        if (isset($filter['id']))
-        {
-            $where['id'] = (int) $filter['id'];
-        }
-        if (isset($filter['name']))
-        {
-            $where['name'] = ['like', "%{$filter['name']}%"];
-        }
-        if (isset($filter['title']))
-        {
-            $where['title'] = ['like', "%{$filter['title']}%"];
-        }
-
-        $addons = get_addon_list();
-        $list = [];
-        foreach ($addons as $k => $v)
-        {
-            $v['flag'] = '';
-            $v['banner'] = '';
-            $v['image'] = '';
-            $v['donateimage'] = '';
-            $v['demourl'] = '';
-            $v['price'] = '0.00';
-            $v['url'] = '/addons/' . $v['name'];
-            $v['createtime'] = 0;
-            $list[] = $v;
-        }
-        $list = array_slice($list, $offset, $limit);
-        $result = array("total" => count($addons), "rows" => $list);
-
-        $callback = $this->request->get('callback') ? "jsonp" : "json";
-        return $callback($result);
-    }
-
-}
+<?php
+
+namespace app\admin\controller;
+
+use app\common\controller\Backend;
+use think\addons\AddonException;
+use think\addons\Service;
+use think\Config;
+use think\Exception;
+
+/**
+ * 插件管理
+ *
+ * @icon fa fa-circle-o
+ */
+class Addon extends Backend
+{
+
+    protected $model = null;
+
+    public function _initialize()
+    {
+        parent::_initialize();
+    }
+
+    /**
+     * 查看
+     */
+    public function index()
+    {
+        $addons = get_addon_list();
+        foreach ($addons as $k => &$v)
+        {
+            $config = get_addon_config($v['name']);
+            $v['config'] = $config ? 1 : 0;
+        }
+        $this->assignconfig(['addons' => $addons]);
+        return $this->view->fetch();
+    }
+
+    /**
+     * 配置
+     */
+    public function config($ids = NULL)
+    {
+        $name = $this->request->get("name");
+        if (!$name)
+        {
+            $this->error(__('Parameter %s can not be empty', $ids ? 'id' : 'name'));
+        }
+        if (!is_dir(ADDON_PATH . $name))
+        {
+            $this->error(__('Directory not found'));
+        }
+        $info = get_addon_info($name);
+        $config = get_addon_fullconfig($name);
+        if (!$info)
+            $this->error(__('No Results were found'));
+        if ($this->request->isPost())
+        {
+            $params = $this->request->post("row/a");
+            if ($params)
+            {
+                $configList = [];
+                foreach ($config as $k => &$v)
+                {
+                    if (isset($params[$v['name']]))
+                    {
+                        if ($v['type'] == 'array')
+                        {
+                            $fieldarr = $valuearr = [];
+                            $field = $params[$v['name']]['field'];
+                            $value = $params[$v['name']]['value'];
+
+                            foreach ($field as $m => $n)
+                            {
+                                if ($n != '')
+                                {
+                                    $fieldarr[] = $field[$m];
+                                    $valuearr[] = $value[$m];
+                                }
+                            }
+                            $params[$v['name']] = array_combine($fieldarr, $valuearr);
+                            $value = $params[$v['name']];
+                        }
+                        else
+                        {
+                            $value = is_array($params[$v['name']]) ? implode(',', $params[$v['name']]) : $params[$v['name']];
+                        }
+
+                        $v['value'] = $value;
+                    }
+                }
+                try
+                {
+                    //更新配置文件
+                    set_addon_fullconfig($name, $config);
+                    $this->success();
+                }
+                catch (Exception $e)
+                {
+                    $this->error($e->getMessage());
+                }
+            }
+            $this->error(__('Parameter %s can not be empty', ''));
+        }
+        $this->view->assign("addon", ['info' => $info, 'config' => $config]);
+        return $this->view->fetch();
+    }
+
+    /**
+     * 安装
+     */
+    public function install()
+    {
+        $name = $this->request->post("name");
+        $force = (int) $this->request->post("force");
+        if (!$name)
+        {
+            $this->error(__('Parameter %s can not be empty', 'name'));
+        }
+        try
+        {
+            $uid = $this->request->post("uid");
+            $token = $this->request->post("token");
+            Service::install($name, $force, ['uid' => $uid, 'token' => $token]);
+            $info = get_addon_info($name);
+            $info['config'] = get_addon_config($name) ? 1 : 0;
+            $this->success(__('Install successful'), null, ['addon' => $info]);
+        }
+        catch (AddonException $e)
+        {
+            $this->result($e->getData(), $e->getCode(), $e->getMessage());
+        }
+        catch (Exception $e)
+        {
+            $this->error($e->getMessage(), $e->getCode());
+        }
+    }
+
+    /**
+     * 卸载
+     */
+    public function uninstall()
+    {
+        $name = $this->request->post("name");
+        $force = (int) $this->request->post("force");
+        if (!$name)
+        {
+            $this->error(__('Parameter %s can not be empty', 'name'));
+        }
+        try
+        {
+            Service::uninstall($name, $force);
+            $this->success(__('Uninstall successful'));
+        }
+        catch (AddonException $e)
+        {
+            $this->result($e->getData(), $e->getCode(), $e->getMessage());
+        }
+        catch (Exception $e)
+        {
+            $this->error($e->getMessage());
+        }
+    }
+
+    /**
+     * 禁用启用
+     */
+    public function state()
+    {
+        $name = $this->request->post("name");
+        $action = $this->request->post("action");
+        $force = (int) $this->request->post("force");
+        if (!$name)
+        {
+            $this->error(__('Parameter %s can not be empty', 'name'));
+        }
+        try
+        {
+            $action = $action == 'enable' ? $action : 'disable';
+            //调用启用、禁用的方法
+            Service::$action($name, $force);
+            $this->success(__('Operate successful'));
+        }
+        catch (AddonException $e)
+        {
+            $this->result($e->getData(), $e->getCode(), $e->getMessage());
+        }
+        catch (Exception $e)
+        {
+            $this->error($e->getMessage());
+        }
+    }
+
+    /**
+     * 本地上传
+     */
+    public function local()
+    {
+        Config::set('default_return_type', 'json');
+
+        $file = $this->request->file('file');
+        $addonTmpDir = RUNTIME_PATH . 'addons' . DS;
+        if (!is_dir($addonTmpDir))
+        {
+            @mkdir($addonTmpDir, 0755, true);
+        }
+        $info = $file->rule('uniqid')->validate(['size' => 10240000, 'ext' => 'zip'])->move($addonTmpDir);
+        if ($info)
+        {
+            $tmpName = substr($info->getFilename(), 0, stripos($info->getFilename(), '.'));
+            $tmpAddonDir = ADDON_PATH . $tmpName . DS;
+            $tmpFile = $addonTmpDir . $info->getSaveName();
+            try
+            {
+                Service::unzip($tmpName);
+                @unlink($tmpFile);
+                $infoFile = $tmpAddonDir . 'info.ini';
+                if (!is_file($infoFile))
+                {
+                    throw new Exception(__('Addon info file was not found'));
+                }
+
+                $config = Config::parse($infoFile, '', $tmpName);
+                $name = isset($config['name']) ? $config['name'] : '';
+                if (!$name)
+                {
+                    throw new Exception(__('Addon info file data incorrect'));
+                }
+
+                $newAddonDir = ADDON_PATH . $name . DS;
+                if (is_dir($newAddonDir))
+                {
+                    throw new Exception(__('Addon already exists'));
+                }
+
+                //重命名插件文件夹
+                rename($tmpAddonDir, $newAddonDir);
+                try
+                {
+                    //默认禁用该插件
+                    $info = get_addon_info($name);
+                    if ($info['state'])
+                    {
+                        $info['state'] = 0;
+                        set_addon_info($name, $info);
+                    }
+
+                    //执行插件的安装方法
+                    $class = get_addon_class($name);
+                    if (class_exists($class))
+                    {
+                        $addon = new $class();
+                        $addon->install();
+                    }
+
+                    //导入SQL
+                    Service::importsql($name);
+
+                    $info['config'] = get_addon_config($name) ? 1 : 0;
+                    $this->success(__('Offline installed tips'), null, ['addon' => $info]);
+                }
+                catch (Exception $e)
+                {
+                    @rmdirs($newAddonDir);
+                    throw new Exception($e->getMessage());
+                }
+            }
+            catch (Exception $e)
+            {
+                @unlink($tmpFile);
+                @rmdirs($tmpAddonDir);
+                $this->error($e->getMessage());
+            }
+        }
+        else
+        {
+            // 上传失败获取错误信息
+            $this->error($file->getError());
+        }
+    }
+
+    /**
+     * 刷新缓存
+     */
+    public function refresh()
+    {
+        try
+        {
+            Service::refresh();
+            $this->success(__('Operate successful'));
+        }
+        catch (Exception $e)
+        {
+            $this->error($e->getMessage());
+        }
+    }
+
+    /**
+     * 已装插件
+     */
+    public function downloaded()
+    {
+        $offset = (int) $this->request->get("offset");
+        $limit = (int) $this->request->get("limit");
+        $filter = $this->request->get("filter");
+        $filter = (array) json_decode($filter, true);
+        foreach ($filter as $k => &$v)
+        {
+            $v = htmlspecialchars(strip_tags($v));
+        }
+        unset($v);
+        $where = ['status' => 'normal'];
+        if (isset($filter['id']))
+        {
+            $where['id'] = (int) $filter['id'];
+        }
+        if (isset($filter['name']))
+        {
+            $where['name'] = ['like', "%{$filter['name']}%"];
+        }
+        if (isset($filter['title']))
+        {
+            $where['title'] = ['like', "%{$filter['title']}%"];
+        }
+
+        $addons = get_addon_list();
+        $list = [];
+        foreach ($addons as $k => $v)
+        {
+            $v['flag'] = '';
+            $v['banner'] = '';
+            $v['image'] = '';
+            $v['donateimage'] = '';
+            $v['demourl'] = '';
+            $v['price'] = '0.00';
+            $v['url'] = '/addons/' . $v['name'];
+            $v['createtime'] = 0;
+            $list[] = $v;
+        }
+        $list = array_slice($list, $offset, $limit);
+        $result = array("total" => count($addons), "rows" => $list);
+
+        $callback = $this->request->get('callback') ? "jsonp" : "json";
+        return $callback($result);
+    }
+
+}

+ 283 - 283
application/admin/controller/Ajax.php

@@ -1,283 +1,283 @@
-<?php
-
-namespace app\admin\controller;
-
-use app\common\controller\Backend;
-use fast\Random;
-use think\Cache;
-use think\Config;
-use think\Db;
-use think\Lang;
-
-/**
- * Ajax异步请求接口
- * @internal
- */
-class Ajax extends Backend
-{
-
-    protected $noNeedLogin = ['lang'];
-    protected $noNeedRight = ['*'];
-    protected $layout = '';
-
-    public function _initialize()
-    {
-        parent::_initialize();
-
-        //设置过滤方法
-        $this->request->filter(['strip_tags', 'htmlspecialchars']);
-    }
-
-    /**
-     * 加载语言包
-     */
-    public function lang()
-    {
-        header('Content-Type: application/javascript');
-        $controllername = input("controllername");
-        //默认只加载了控制器对应的语言名,你还根据控制器名来加载额外的语言包
-        $this->loadlang($controllername);
-        return jsonp(Lang::get(), 200, [], ['json_encode_param' => JSON_FORCE_OBJECT | JSON_UNESCAPED_UNICODE]);
-    }
-
-    /**
-     * 上传文件
-     */
-    public function upload()
-    {
-        Config::set('default_return_type', 'json');
-        $file = $this->request->file('file');
-        if (empty($file))
-        {
-            $this->error("未上传文件或超出服务器上传限制");
-        }
-
-        //判断是否已经存在附件
-        $sha1 = $file->hash();
-
-        $upload = Config::get('upload');
-
-        preg_match('/(\d+)(\w+)/', $upload['maxsize'], $matches);
-        $type = strtolower($matches[2]);
-        $typeDict = ['b' => 0, 'k' => 1, 'kb' => 1, 'm' => 2, 'mb' => 2, 'gb' => 3, 'g' => 3];
-        $size = (int) $upload['maxsize'] * pow(1024, isset($typeDict[$type]) ? $typeDict[$type] : 0);
-        $fileInfo = $file->getInfo();
-        $suffix = strtolower(pathinfo($fileInfo['name'], PATHINFO_EXTENSION));
-        $suffix = $suffix ? $suffix : 'file';
-        $replaceArr = [
-            '{year}'     => date("Y"),
-            '{mon}'      => date("m"),
-            '{day}'      => date("d"),
-            '{hour}'     => date("H"),
-            '{min}'      => date("i"),
-            '{sec}'      => date("s"),
-            '{random}'   => Random::alnum(16),
-            '{random32}' => Random::alnum(32),
-            '{filename}' => $suffix ? substr($fileInfo['name'], 0, strripos($fileInfo['name'], '.')) : $fileInfo['name'],
-            '{suffix}'   => $suffix,
-            '{.suffix}'  => $suffix ? '.' . $suffix : '',
-            '{filemd5}'  => md5_file($fileInfo['tmp_name']),
-        ];
-        $savekey = $upload['savekey'];
-        $savekey = str_replace(array_keys($replaceArr), array_values($replaceArr), $savekey);
-
-        $uploadDir = substr($savekey, 0, strripos($savekey, '/') + 1);
-        $fileName = substr($savekey, strripos($savekey, '/') + 1);
-        //
-        $splInfo = $file->validate(['size' => $size])->move(ROOT_PATH . '/public' . $uploadDir, $fileName);
-        if ($splInfo)
-        {
-            $imagewidth = $imageheight = 0;
-            if (in_array($suffix, ['gif', 'jpg', 'jpeg', 'bmp', 'png', 'swf']))
-            {
-                $imgInfo = getimagesize($splInfo->getPathname());
-                $imagewidth = isset($imgInfo[0]) ? $imgInfo[0] : $imagewidth;
-                $imageheight = isset($imgInfo[1]) ? $imgInfo[1] : $imageheight;
-            }
-            $params = array(
-                'filesize'    => $fileInfo['size'],
-                'imagewidth'  => $imagewidth,
-                'imageheight' => $imageheight,
-                'imagetype'   => $suffix,
-                'imageframes' => 0,
-                'mimetype'    => $fileInfo['type'],
-                'url'         => $uploadDir . $splInfo->getSaveName(),
-                'uploadtime'  => time(),
-                'storage'     => 'local',
-                'sha1'        => $sha1,
-            );
-            $attachment = model("attachment");
-            $attachment->data(array_filter($params));
-            $attachment->save();
-            \think\Hook::listen("upload_after", $attachment);
-            $this->success('上传成功', null, [
-                'url' => $uploadDir . $splInfo->getSaveName()
-            ]);
-        }
-        else
-        {
-            // 上传失败获取错误信息
-            $this->error($file->getError());
-        }
-    }
-
-    /**
-     * 通用排序
-     */
-    public function weigh()
-    {
-        //排序的数组
-        $ids = $this->request->post("ids");
-        //拖动的记录ID
-        $changeid = $this->request->post("changeid");
-        //操作字段
-        $field = $this->request->post("field");
-        //操作的数据表
-        $table = $this->request->post("table");
-        //排序的方式
-        $orderway = $this->request->post("orderway", 'strtolower');
-        $orderway = $orderway == 'asc' ? 'ASC' : 'DESC';
-        $sour = $weighdata = [];
-        $ids = explode(',', $ids);
-        $prikey = 'id';
-        $pid = $this->request->post("pid");
-        //限制更新的字段
-        $field = in_array($field, ['weigh']) ? $field : 'weigh';
-
-        // 如果设定了pid的值,此时只匹配满足条件的ID,其它忽略
-        if ($pid !== '')
-        {
-            $hasids = [];
-            $list = Db::name($table)->where($prikey, 'in', $ids)->where('pid', 'in', $pid)->field('id,pid')->select();
-            foreach ($list as $k => $v)
-            {
-                $hasids[] = $v['id'];
-            }
-            $ids = array_values(array_intersect($ids, $hasids));
-        }
-
-        //直接修复排序
-        $one = Db::name($table)->field("{$field},COUNT(*) AS nums")->group($field)->having('nums > 1')->find();
-        if ($one)
-        {
-            $list = Db::name($table)->field("$prikey,$field")->order($field, $orderway)->select();
-            foreach ($list as $k => $v)
-            {
-                Db::name($table)->where($prikey, $v[$prikey])->update([$field => $k + 1]);
-            }
-            $this->success();
-        }
-        else
-        {
-            $list = Db::name($table)->field("$prikey,$field")->where($prikey, 'in', $ids)->order($field, $orderway)->select();
-            foreach ($list as $k => $v)
-            {
-                $sour[] = $v[$prikey];
-                $weighdata[$v[$prikey]] = $v[$field];
-            }
-            $position = array_search($changeid, $ids);
-            $desc_id = $sour[$position];    //移动到目标的ID值,取出所处改变前位置的值
-            $sour_id = $changeid;
-            $desc_value = $weighdata[$desc_id];
-            $sour_value = $weighdata[$sour_id];
-            //echo "移动的ID:{$sour_id}\n";
-            //echo "替换的ID:{$desc_id}\n";
-            $weighids = array();
-            $temp = array_values(array_diff_assoc($ids, $sour));
-            foreach ($temp as $m => $n)
-            {
-                if ($n == $sour_id)
-                {
-                    $offset = $desc_id;
-                }
-                else
-                {
-                    if ($sour_id == $temp[0])
-                    {
-                        $offset = isset($temp[$m + 1]) ? $temp[$m + 1] : $sour_id;
-                    }
-                    else
-                    {
-                        $offset = isset($temp[$m - 1]) ? $temp[$m - 1] : $sour_id;
-                    }
-                }
-                $weighids[$n] = $weighdata[$offset];
-                Db::name($table)->where($prikey, $n)->update([$field => $weighdata[$offset]]);
-            }
-            $this->success();
-        }
-    }
-
-    /**
-     * 清空系统缓存
-     */
-    public function wipecache()
-    {
-        $wipe_cache_type = ['TEMP_PATH', 'LOG_PATH', 'CACHE_PATH'];
-        foreach ($wipe_cache_type as $item)
-        {
-            $dir = constant($item);
-            if (!is_dir($dir))
-                continue;
-            rmdirs($dir);
-        }
-        Cache::clear();
-        \think\Hook::listen("wipecache_after");
-        $this->success();
-    }
-
-    /**
-     * 读取分类数据,联动列表
-     */
-    public function category()
-    {
-        $type = $this->request->get('type');
-        $pid = $this->request->get('pid');
-        $where = ['status' => 'normal'];
-        $categorylist = null;
-        if ($pid !== '')
-        {
-            if ($type)
-            {
-                $where['type'] = $type;
-            }
-            if ($pid)
-            {
-                $where['pid'] = $pid;
-            }
-
-            $categorylist = Db::name('category')->where($where)->field('id as value,name')->order('weigh desc,id desc')->select();
-        }
-        $this->success('', null, $categorylist);
-    }
-
-    /**
-     * 读取省市区数据,联动列表
-     */
-    public function area()
-    {
-        $province = $this->request->get('province');
-        $city = $this->request->get('city');
-        $where = ['pid' => 0, 'level' => 1];
-        $provincelist = null;
-        if ($province !== '')
-        {
-            if ($province)
-            {
-                $where['pid'] = $province;
-                $where['level'] = 2;
-            }
-            if ($city !== '')
-            {
-                if ($city)
-                {
-                    $where['pid'] = $city;
-                    $where['level'] = 3;
-                }
-                $provincelist = Db::name('area')->where($where)->field('id as value,name')->select();
-            }
-        }
-        $this->success('', null, $provincelist);
-    }
-
-}
+<?php
+
+namespace app\admin\controller;
+
+use app\common\controller\Backend;
+use fast\Random;
+use think\Cache;
+use think\Config;
+use think\Db;
+use think\Lang;
+
+/**
+ * Ajax异步请求接口
+ * @internal
+ */
+class Ajax extends Backend
+{
+
+    protected $noNeedLogin = ['lang'];
+    protected $noNeedRight = ['*'];
+    protected $layout = '';
+
+    public function _initialize()
+    {
+        parent::_initialize();
+
+        //设置过滤方法
+        $this->request->filter(['strip_tags', 'htmlspecialchars']);
+    }
+
+    /**
+     * 加载语言包
+     */
+    public function lang()
+    {
+        header('Content-Type: application/javascript');
+        $controllername = input("controllername");
+        //默认只加载了控制器对应的语言名,你还根据控制器名来加载额外的语言包
+        $this->loadlang($controllername);
+        return jsonp(Lang::get(), 200, [], ['json_encode_param' => JSON_FORCE_OBJECT | JSON_UNESCAPED_UNICODE]);
+    }
+
+    /**
+     * 上传文件
+     */
+    public function upload()
+    {
+        Config::set('default_return_type', 'json');
+        $file = $this->request->file('file');
+        if (empty($file))
+        {
+            $this->error("未上传文件或超出服务器上传限制");
+        }
+
+        //判断是否已经存在附件
+        $sha1 = $file->hash();
+
+        $upload = Config::get('upload');
+
+        preg_match('/(\d+)(\w+)/', $upload['maxsize'], $matches);
+        $type = strtolower($matches[2]);
+        $typeDict = ['b' => 0, 'k' => 1, 'kb' => 1, 'm' => 2, 'mb' => 2, 'gb' => 3, 'g' => 3];
+        $size = (int) $upload['maxsize'] * pow(1024, isset($typeDict[$type]) ? $typeDict[$type] : 0);
+        $fileInfo = $file->getInfo();
+        $suffix = strtolower(pathinfo($fileInfo['name'], PATHINFO_EXTENSION));
+        $suffix = $suffix ? $suffix : 'file';
+        $replaceArr = [
+            '{year}'     => date("Y"),
+            '{mon}'      => date("m"),
+            '{day}'      => date("d"),
+            '{hour}'     => date("H"),
+            '{min}'      => date("i"),
+            '{sec}'      => date("s"),
+            '{random}'   => Random::alnum(16),
+            '{random32}' => Random::alnum(32),
+            '{filename}' => $suffix ? substr($fileInfo['name'], 0, strripos($fileInfo['name'], '.')) : $fileInfo['name'],
+            '{suffix}'   => $suffix,
+            '{.suffix}'  => $suffix ? '.' . $suffix : '',
+            '{filemd5}'  => md5_file($fileInfo['tmp_name']),
+        ];
+        $savekey = $upload['savekey'];
+        $savekey = str_replace(array_keys($replaceArr), array_values($replaceArr), $savekey);
+
+        $uploadDir = substr($savekey, 0, strripos($savekey, '/') + 1);
+        $fileName = substr($savekey, strripos($savekey, '/') + 1);
+        //
+        $splInfo = $file->validate(['size' => $size])->move(ROOT_PATH . '/public' . $uploadDir, $fileName);
+        if ($splInfo)
+        {
+            $imagewidth = $imageheight = 0;
+            if (in_array($suffix, ['gif', 'jpg', 'jpeg', 'bmp', 'png', 'swf']))
+            {
+                $imgInfo = getimagesize($splInfo->getPathname());
+                $imagewidth = isset($imgInfo[0]) ? $imgInfo[0] : $imagewidth;
+                $imageheight = isset($imgInfo[1]) ? $imgInfo[1] : $imageheight;
+            }
+            $params = array(
+                'filesize'    => $fileInfo['size'],
+                'imagewidth'  => $imagewidth,
+                'imageheight' => $imageheight,
+                'imagetype'   => $suffix,
+                'imageframes' => 0,
+                'mimetype'    => $fileInfo['type'],
+                'url'         => $uploadDir . $splInfo->getSaveName(),
+                'uploadtime'  => time(),
+                'storage'     => 'local',
+                'sha1'        => $sha1,
+            );
+            $attachment = model("attachment");
+            $attachment->data(array_filter($params));
+            $attachment->save();
+            \think\Hook::listen("upload_after", $attachment);
+            $this->success('上传成功', null, [
+                'url' => $uploadDir . $splInfo->getSaveName()
+            ]);
+        }
+        else
+        {
+            // 上传失败获取错误信息
+            $this->error($file->getError());
+        }
+    }
+
+    /**
+     * 通用排序
+     */
+    public function weigh()
+    {
+        //排序的数组
+        $ids = $this->request->post("ids");
+        //拖动的记录ID
+        $changeid = $this->request->post("changeid");
+        //操作字段
+        $field = $this->request->post("field");
+        //操作的数据表
+        $table = $this->request->post("table");
+        //排序的方式
+        $orderway = $this->request->post("orderway", 'strtolower');
+        $orderway = $orderway == 'asc' ? 'ASC' : 'DESC';
+        $sour = $weighdata = [];
+        $ids = explode(',', $ids);
+        $prikey = 'id';
+        $pid = $this->request->post("pid");
+        //限制更新的字段
+        $field = in_array($field, ['weigh']) ? $field : 'weigh';
+
+        // 如果设定了pid的值,此时只匹配满足条件的ID,其它忽略
+        if ($pid !== '')
+        {
+            $hasids = [];
+            $list = Db::name($table)->where($prikey, 'in', $ids)->where('pid', 'in', $pid)->field('id,pid')->select();
+            foreach ($list as $k => $v)
+            {
+                $hasids[] = $v['id'];
+            }
+            $ids = array_values(array_intersect($ids, $hasids));
+        }
+
+        //直接修复排序
+        $one = Db::name($table)->field("{$field},COUNT(*) AS nums")->group($field)->having('nums > 1')->find();
+        if ($one)
+        {
+            $list = Db::name($table)->field("$prikey,$field")->order($field, $orderway)->select();
+            foreach ($list as $k => $v)
+            {
+                Db::name($table)->where($prikey, $v[$prikey])->update([$field => $k + 1]);
+            }
+            $this->success();
+        }
+        else
+        {
+            $list = Db::name($table)->field("$prikey,$field")->where($prikey, 'in', $ids)->order($field, $orderway)->select();
+            foreach ($list as $k => $v)
+            {
+                $sour[] = $v[$prikey];
+                $weighdata[$v[$prikey]] = $v[$field];
+            }
+            $position = array_search($changeid, $ids);
+            $desc_id = $sour[$position];    //移动到目标的ID值,取出所处改变前位置的值
+            $sour_id = $changeid;
+            $desc_value = $weighdata[$desc_id];
+            $sour_value = $weighdata[$sour_id];
+            //echo "移动的ID:{$sour_id}\n";
+            //echo "替换的ID:{$desc_id}\n";
+            $weighids = array();
+            $temp = array_values(array_diff_assoc($ids, $sour));
+            foreach ($temp as $m => $n)
+            {
+                if ($n == $sour_id)
+                {
+                    $offset = $desc_id;
+                }
+                else
+                {
+                    if ($sour_id == $temp[0])
+                    {
+                        $offset = isset($temp[$m + 1]) ? $temp[$m + 1] : $sour_id;
+                    }
+                    else
+                    {
+                        $offset = isset($temp[$m - 1]) ? $temp[$m - 1] : $sour_id;
+                    }
+                }
+                $weighids[$n] = $weighdata[$offset];
+                Db::name($table)->where($prikey, $n)->update([$field => $weighdata[$offset]]);
+            }
+            $this->success();
+        }
+    }
+
+    /**
+     * 清空系统缓存
+     */
+    public function wipecache()
+    {
+        $wipe_cache_type = ['TEMP_PATH', 'LOG_PATH', 'CACHE_PATH'];
+        foreach ($wipe_cache_type as $item)
+        {
+            $dir = constant($item);
+            if (!is_dir($dir))
+                continue;
+            rmdirs($dir);
+        }
+        Cache::clear();
+        \think\Hook::listen("wipecache_after");
+        $this->success();
+    }
+
+    /**
+     * 读取分类数据,联动列表
+     */
+    public function category()
+    {
+        $type = $this->request->get('type');
+        $pid = $this->request->get('pid');
+        $where = ['status' => 'normal'];
+        $categorylist = null;
+        if ($pid !== '')
+        {
+            if ($type)
+            {
+                $where['type'] = $type;
+            }
+            if ($pid)
+            {
+                $where['pid'] = $pid;
+            }
+
+            $categorylist = Db::name('category')->where($where)->field('id as value,name')->order('weigh desc,id desc')->select();
+        }
+        $this->success('', null, $categorylist);
+    }
+
+    /**
+     * 读取省市区数据,联动列表
+     */
+    public function area()
+    {
+        $province = $this->request->get('province');
+        $city = $this->request->get('city');
+        $where = ['pid' => 0, 'level' => 1];
+        $provincelist = null;
+        if ($province !== '')
+        {
+            if ($province)
+            {
+                $where['pid'] = $province;
+                $where['level'] = 2;
+            }
+            if ($city !== '')
+            {
+                if ($city)
+                {
+                    $where['pid'] = $city;
+                    $where['level'] = 3;
+                }
+                $provincelist = Db::name('area')->where($where)->field('id as value,name')->select();
+            }
+        }
+        $this->success('', null, $provincelist);
+    }
+
+}

+ 83 - 83
application/admin/controller/Category.php

@@ -1,83 +1,83 @@
-<?php
-
-namespace app\admin\controller;
-
-use app\common\controller\Backend;
-use app\common\model\Category as CategoryModel;
-use fast\Tree;
-
-/**
- * 分类管理
- *
- * @icon fa fa-list
- * @remark 用于统一管理网站的所有分类,分类可进行无限级分类
- */
-class Category extends Backend
-{
-
-    protected $model = null;
-    protected $categorylist = [];
-    protected $noNeedRight = ['selectpage'];
-
-    public function _initialize()
-    {
-        parent::_initialize();
-        $this->request->filter(['strip_tags']);
-        $this->model = model('Category');
-
-        $tree = Tree::instance();
-        $tree->init(collection($this->model->order('weigh desc,id desc')->select())->toArray(), 'pid');
-        $this->categorylist = $tree->getTreeList($tree->getTreeArray(0), 'name');
-        $categorydata = [0 => ['type' => 'all', 'name' => __('None')]];
-        foreach ($this->categorylist as $k => $v)
-        {
-            $categorydata[$v['id']] = $v;
-        }
-        $this->view->assign("flagList", $this->model->getFlagList());
-        $this->view->assign("typeList", CategoryModel::getTypeList());
-        $this->view->assign("parentList", $categorydata);
-    }
-
-    /**
-     * 查看
-     */
-    public function index()
-    {
-        if ($this->request->isAjax())
-        {
-            $search = $this->request->request("search");
-            //构造父类select列表选项数据
-            $list = [];
-            if ($search)
-            {
-                foreach ($this->categorylist as $k => $v)
-                {
-                    if (stripos($v['name'], $search) !== false || stripos($v['nickname'], $search) !== false)
-                    {
-                        $list[] = $v;
-                    }
-                }
-            }
-            else
-            {
-                $list = $this->categorylist;
-            }
-            $total = count($list);
-            $result = array("total" => $total, "rows" => $list);
-
-            return json($result);
-        }
-        return $this->view->fetch();
-    }
-
-    /**
-     * Selectpage搜索
-     * 
-     * @internal
-     */
-    public function selectpage()
-    {
-        return parent::selectpage();
-    }
-
-}
+<?php
+
+namespace app\admin\controller;
+
+use app\common\controller\Backend;
+use app\common\model\Category as CategoryModel;
+use fast\Tree;
+
+/**
+ * 分类管理
+ *
+ * @icon fa fa-list
+ * @remark 用于统一管理网站的所有分类,分类可进行无限级分类
+ */
+class Category extends Backend
+{
+
+    protected $model = null;
+    protected $categorylist = [];
+    protected $noNeedRight = ['selectpage'];
+
+    public function _initialize()
+    {
+        parent::_initialize();
+        $this->request->filter(['strip_tags']);
+        $this->model = model('Category');
+
+        $tree = Tree::instance();
+        $tree->init(collection($this->model->order('weigh desc,id desc')->select())->toArray(), 'pid');
+        $this->categorylist = $tree->getTreeList($tree->getTreeArray(0), 'name');
+        $categorydata = [0 => ['type' => 'all', 'name' => __('None')]];
+        foreach ($this->categorylist as $k => $v)
+        {
+            $categorydata[$v['id']] = $v;
+        }
+        $this->view->assign("flagList", $this->model->getFlagList());
+        $this->view->assign("typeList", CategoryModel::getTypeList());
+        $this->view->assign("parentList", $categorydata);
+    }
+
+    /**
+     * 查看
+     */
+    public function index()
+    {
+        if ($this->request->isAjax())
+        {
+            $search = $this->request->request("search");
+            //构造父类select列表选项数据
+            $list = [];
+            if ($search)
+            {
+                foreach ($this->categorylist as $k => $v)
+                {
+                    if (stripos($v['name'], $search) !== false || stripos($v['nickname'], $search) !== false)
+                    {
+                        $list[] = $v;
+                    }
+                }
+            }
+            else
+            {
+                $list = $this->categorylist;
+            }
+            $total = count($list);
+            $result = array("total" => $total, "rows" => $list);
+
+            return json($result);
+        }
+        return $this->view->fetch();
+    }
+
+    /**
+     * Selectpage搜索
+     * 
+     * @internal
+     */
+    public function selectpage()
+    {
+        return parent::selectpage();
+    }
+
+}

+ 50 - 50
application/admin/controller/Dashboard.php

@@ -1,50 +1,50 @@
-<?php
-
-namespace app\admin\controller;
-
-use app\common\controller\Backend;
-
-/**
- * 控制台
- *
- * @icon fa fa-dashboard
- * @remark 用于展示当前系统中的统计数据、统计报表及重要实时数据
- */
-class Dashboard extends Backend
-{
-
-    /**
-     * 查看
-     */
-    public function index()
-    {
-        $seventtime = \fast\Date::unixtime('day', -7);
-        $paylist = $createlist = [];
-        for ($i = 0; $i < 7; $i++)
-        {
-            $day = date("Y-m-d", $seventtime + ($i * 86400));
-            $createlist[$day] = mt_rand(20, 200);
-            $paylist[$day] = mt_rand(1, mt_rand(1, $createlist[$day]));
-        }
-        $hooks = config('addons.hooks');
-        $uploadmode = isset($hooks['upload_config_init']) && $hooks['upload_config_init'] ? implode(',', $hooks['upload_config_init']) : 'local';
-        $this->view->assign([
-            'totaluser'        => 35200,
-            'totalviews'       => 219390,
-            'totalorder'       => 32143,
-            'totalorderamount' => 174800,
-            'todayuserlogin'   => 321,
-            'todayusersignup'  => 430,
-            'todayorder'       => 2324,
-            'unsettleorder'    => 132,
-            'sevendnu'         => '80%',
-            'sevendau'         => '32%',
-            'paylist'          => $paylist,
-            'createlist'       => $createlist,
-            'uploadmode'       => $uploadmode
-        ]);
-
-        return $this->view->fetch();
-    }
-
-}
+<?php
+
+namespace app\admin\controller;
+
+use app\common\controller\Backend;
+
+/**
+ * 控制台
+ *
+ * @icon fa fa-dashboard
+ * @remark 用于展示当前系统中的统计数据、统计报表及重要实时数据
+ */
+class Dashboard extends Backend
+{
+
+    /**
+     * 查看
+     */
+    public function index()
+    {
+        $seventtime = \fast\Date::unixtime('day', -7);
+        $paylist = $createlist = [];
+        for ($i = 0; $i < 7; $i++)
+        {
+            $day = date("Y-m-d", $seventtime + ($i * 86400));
+            $createlist[$day] = mt_rand(20, 200);
+            $paylist[$day] = mt_rand(1, mt_rand(1, $createlist[$day]));
+        }
+        $hooks = config('addons.hooks');
+        $uploadmode = isset($hooks['upload_config_init']) && $hooks['upload_config_init'] ? implode(',', $hooks['upload_config_init']) : 'local';
+        $this->view->assign([
+            'totaluser'        => 35200,
+            'totalviews'       => 219390,
+            'totalorder'       => 32143,
+            'totalorderamount' => 174800,
+            'todayuserlogin'   => 321,
+            'todayusersignup'  => 430,
+            'todayorder'       => 2324,
+            'unsettleorder'    => 132,
+            'sevendnu'         => '80%',
+            'sevendau'         => '32%',
+            'paylist'          => $paylist,
+            'createlist'       => $createlist,
+            'uploadmode'       => $uploadmode
+        ]);
+
+        return $this->view->fetch();
+    }
+
+}

+ 103 - 103
application/admin/controller/Index.php

@@ -1,103 +1,103 @@
-<?php
-
-namespace app\admin\controller;
-
-use app\common\controller\Backend;
-use think\Validate;
-
-/**
- * 后台首页
- * @internal
- */
-class Index extends Backend
-{
-
-    protected $noNeedLogin = ['login'];
-    protected $noNeedRight = ['index', 'logout'];
-    protected $layout = '';
-
-    public function _initialize()
-    {
-        parent::_initialize();
-    }
-
-    /**
-     * 后台首页
-     */
-    public function index()
-    {
-        //
-        $menulist = $this->auth->getSidebar([
-            'dashboard' => 'hot',
-            'addon'     => ['new', 'red', 'badge'],
-            'auth/rule' => 'side',
-            'general'   => ['18', 'purple'],
-                ], $this->view->site['fixedpage']);
-        $this->view->assign('menulist', $menulist);
-        $this->view->assign('title', __('Home'));
-        return $this->view->fetch();
-    }
-
-    /**
-     * 管理员登录
-     */
-    public function login()
-    {
-        $url = $this->request->get('url', 'index/index');
-        if ($this->auth->isLogin())
-        {
-            $this->error(__("You've logged in, do not login again"), $url);
-        }
-        if ($this->request->isPost())
-        {
-            $username = $this->request->post('username');
-            $password = $this->request->post('password');
-            $keeplogin = $this->request->post('keeplogin');
-            $token = $this->request->post('__token__');
-            $rule = [
-                'username'  => 'require|length:3,30',
-                'password'  => 'require|length:3,30',
-                '__token__' => 'token',
-            ];
-            $data = [
-                'username'  => $username,
-                'password'  => $password,
-                '__token__' => $token,
-            ];
-            $validate = new Validate($rule);
-            $result = $validate->check($data);
-            if (!$result)
-            {
-                $this->error($validate->getError(), $url, ['token' => $this->request->token()]);
-            }
-            \app\admin\model\AdminLog::setTitle(__('Login'));
-            $result = $this->auth->login($username, $password, $keeplogin ? 86400 : 0);
-            if ($result === true)
-            {
-                $this->success(__('Login successful'), $url, ['url' => $url, 'id' => $this->auth->id, 'username' => $username, 'avatar' => $this->auth->avatar]);
-            }
-            else
-            {
-                $this->error(__('Username or password is incorrect'), $url, ['token' => $this->request->token()]);
-            }
-        }
-
-        // 根据客户端的cookie,判断是否可以自动登录
-        if ($this->auth->autologin())
-        {
-            $this->redirect($url);
-        }
-        \think\Hook::listen("login_init", $this->request);
-        return $this->view->fetch();
-    }
-
-    /**
-     * 注销登录
-     */
-    public function logout()
-    {
-        $this->auth->logout();
-        $this->success(__('Logout successful'), 'index/login');
-    }
-
-}
+<?php
+
+namespace app\admin\controller;
+
+use app\common\controller\Backend;
+use think\Validate;
+
+/**
+ * 后台首页
+ * @internal
+ */
+class Index extends Backend
+{
+
+    protected $noNeedLogin = ['login'];
+    protected $noNeedRight = ['index', 'logout'];
+    protected $layout = '';
+
+    public function _initialize()
+    {
+        parent::_initialize();
+    }
+
+    /**
+     * 后台首页
+     */
+    public function index()
+    {
+        //
+        $menulist = $this->auth->getSidebar([
+            'dashboard' => 'hot',
+            'addon'     => ['new', 'red', 'badge'],
+            'auth/rule' => 'side',
+            'general'   => ['18', 'purple'],
+                ], $this->view->site['fixedpage']);
+        $this->view->assign('menulist', $menulist);
+        $this->view->assign('title', __('Home'));
+        return $this->view->fetch();
+    }
+
+    /**
+     * 管理员登录
+     */
+    public function login()
+    {
+        $url = $this->request->get('url', 'index/index');
+        if ($this->auth->isLogin())
+        {
+            $this->error(__("You've logged in, do not login again"), $url);
+        }
+        if ($this->request->isPost())
+        {
+            $username = $this->request->post('username');
+            $password = $this->request->post('password');
+            $keeplogin = $this->request->post('keeplogin');
+            $token = $this->request->post('__token__');
+            $rule = [
+                'username'  => 'require|length:3,30',
+                'password'  => 'require|length:3,30',
+                '__token__' => 'token',
+            ];
+            $data = [
+                'username'  => $username,
+                'password'  => $password,
+                '__token__' => $token,
+            ];
+            $validate = new Validate($rule);
+            $result = $validate->check($data);
+            if (!$result)
+            {
+                $this->error($validate->getError(), $url, ['token' => $this->request->token()]);
+            }
+            \app\admin\model\AdminLog::setTitle(__('Login'));
+            $result = $this->auth->login($username, $password, $keeplogin ? 86400 : 0);
+            if ($result === true)
+            {
+                $this->success(__('Login successful'), $url, ['url' => $url, 'id' => $this->auth->id, 'username' => $username, 'avatar' => $this->auth->avatar]);
+            }
+            else
+            {
+                $this->error(__('Username or password is incorrect'), $url, ['token' => $this->request->token()]);
+            }
+        }
+
+        // 根据客户端的cookie,判断是否可以自动登录
+        if ($this->auth->autologin())
+        {
+            $this->redirect($url);
+        }
+        \think\Hook::listen("login_init", $this->request);
+        return $this->view->fetch();
+    }
+
+    /**
+     * 注销登录
+     */
+    public function logout()
+    {
+        $this->auth->logout();
+        $this->success(__('Logout successful'), 'index/login');
+    }
+
+}

+ 95 - 95
application/admin/controller/general/Attachment.php

@@ -1,95 +1,95 @@
-<?php
-
-namespace app\admin\controller\general;
-
-use app\common\controller\Backend;
-
-/**
- * 附件管理
- *
- * @icon fa fa-circle-o
- * @remark 主要用于管理上传到又拍云的数据或上传至本服务的上传数据
- */
-class Attachment extends Backend
-{
-
-    protected $model = null;
-
-    public function _initialize()
-    {
-        parent::_initialize();
-        $this->model = model('Attachment');
-    }
-
-    /**
-     * 查看
-     */
-    public function index()
-    {
-        //设置过滤方法
-        $this->request->filter(['strip_tags']);
-        if ($this->request->isAjax())
-        {
-            list($where, $sort, $order, $offset, $limit) = $this->buildparams();
-            $total = $this->model
-                    ->where($where)
-                    ->order($sort, $order)
-                    ->count();
-
-            $list = $this->model
-                    ->where($where)
-                    ->order($sort, $order)
-                    ->limit($offset, $limit)
-                    ->select();
-            $cdnurl = preg_replace("/\/(\w+)\.php$/i", '', $this->request->root());
-            foreach ($list as $k => &$v)
-            {
-                $v['fullurl'] = ($v['storage'] == 'local' ? $cdnurl : $this->view->config['upload']['cdnurl']) . $v['url'];
-            }
-            unset($v);
-            $result = array("total" => $total, "rows" => $list);
-
-            return json($result);
-        }
-        return $this->view->fetch();
-    }
-
-    /**
-     * 选择附件
-     */
-    public function select()
-    {
-        if ($this->request->isAjax())
-        {
-            return $this->index();
-        }
-        return $this->view->fetch();
-    }
-
-    /**
-     * 添加
-     */
-    public function add()
-    {
-        if ($this->request->isAjax())
-        {
-            $this->error();
-        }
-        return $this->view->fetch();
-    }
-
-    public function del($ids = "")
-    {
-        if ($ids)
-        {
-            $count = $this->model->destroy($ids);
-            if ($count)
-            {
-                \think\Hook::listen("upload_after", $this);
-                $this->success();
-            }
-        }
-        $this->error(__('Parameter %s can not be empty', 'ids'));
-    }
-
-}
+<?php
+
+namespace app\admin\controller\general;
+
+use app\common\controller\Backend;
+
+/**
+ * 附件管理
+ *
+ * @icon fa fa-circle-o
+ * @remark 主要用于管理上传到又拍云的数据或上传至本服务的上传数据
+ */
+class Attachment extends Backend
+{
+
+    protected $model = null;
+
+    public function _initialize()
+    {
+        parent::_initialize();
+        $this->model = model('Attachment');
+    }
+
+    /**
+     * 查看
+     */
+    public function index()
+    {
+        //设置过滤方法
+        $this->request->filter(['strip_tags']);
+        if ($this->request->isAjax())
+        {
+            list($where, $sort, $order, $offset, $limit) = $this->buildparams();
+            $total = $this->model
+                    ->where($where)
+                    ->order($sort, $order)
+                    ->count();
+
+            $list = $this->model
+                    ->where($where)
+                    ->order($sort, $order)
+                    ->limit($offset, $limit)
+                    ->select();
+            $cdnurl = preg_replace("/\/(\w+)\.php$/i", '', $this->request->root());
+            foreach ($list as $k => &$v)
+            {
+                $v['fullurl'] = ($v['storage'] == 'local' ? $cdnurl : $this->view->config['upload']['cdnurl']) . $v['url'];
+            }
+            unset($v);
+            $result = array("total" => $total, "rows" => $list);
+
+            return json($result);
+        }
+        return $this->view->fetch();
+    }
+
+    /**
+     * 选择附件
+     */
+    public function select()
+    {
+        if ($this->request->isAjax())
+        {
+            return $this->index();
+        }
+        return $this->view->fetch();
+    }
+
+    /**
+     * 添加
+     */
+    public function add()
+    {
+        if ($this->request->isAjax())
+        {
+            $this->error();
+        }
+        return $this->view->fetch();
+    }
+
+    public function del($ids = "")
+    {
+        if ($ids)
+        {
+            $count = $this->model->destroy($ids);
+            if ($count)
+            {
+                \think\Hook::listen("upload_after", $this);
+                $this->success();
+            }
+        }
+        $this->error(__('Parameter %s can not be empty', 'ids'));
+    }
+
+}

+ 229 - 229
application/admin/controller/general/Config.php

@@ -1,229 +1,229 @@
-<?php
-
-namespace app\admin\controller\general;
-
-use app\common\controller\Backend;
-use app\common\library\Email;
-use app\common\model\Config as ConfigModel;
-use think\Exception;
-
-/**
- * 系统配置
- *
- * @icon fa fa-circle-o
- */
-class Config extends Backend
-{
-
-    protected $model = null;
-    protected $noNeedRight = ['check'];
-
-    public function _initialize()
-    {
-        parent::_initialize();
-        $this->model = model('Config');
-    }
-
-    public function index()
-    {
-        $siteList = [];
-        $groupList = ConfigModel::getGroupList();
-        foreach ($groupList as $k => $v)
-        {
-            $siteList[$k]['name'] = $k;
-            $siteList[$k]['title'] = $v;
-            $siteList[$k]['list'] = [];
-        }
-
-        foreach ($this->model->all() as $k => $v)
-        {
-            if (!isset($siteList[$v['group']]))
-            {
-                continue;
-            }
-            $value = $v->toArray();
-            $value['title'] = __($value['title']);
-            if (in_array($value['type'], ['select', 'selects', 'checkbox', 'radio']))
-            {
-                $value['value'] = explode(',', $value['value']);
-            }
-            if ($value['type'] == 'array')
-            {
-                $value['value'] = (array) json_decode($value['value'], TRUE);
-            }
-            $value['content'] = json_decode($value['content'], TRUE);
-            $siteList[$v['group']]['list'][] = $value;
-        }
-        $index = 0;
-        foreach ($siteList as $k => &$v)
-        {
-            $v['active'] = !$index ? true : false;
-            $index++;
-        }
-        $this->view->assign('siteList', $siteList);
-        $this->view->assign('typeList', ConfigModel::getTypeList());
-        $this->view->assign('groupList', ConfigModel::getGroupList());
-        return $this->view->fetch();
-    }
-
-    /**
-     * 添加
-     */
-    public function add()
-    {
-        if ($this->request->isPost())
-        {
-            $params = $this->request->post("row/a");
-            if ($params)
-            {
-                foreach ($params as $k => &$v)
-                {
-                    $v = is_array($v) ? implode(',', $v) : $v;
-                }
-                try
-                {
-                    if (in_array($params['type'], ['select', 'selects', 'checkbox', 'radio', 'array']))
-                    {
-                        $params['content'] = ConfigModel::decode($params['content']);
-                    }
-                    else
-                    {
-                        $params['content'] = '';
-                    }
-                    $result = $this->model->create($params);
-                    if ($result !== false)
-                    {
-                        try
-                        {
-                            $this->refreshFile();
-                            $this->success();
-                        }
-                        catch (Exception $e)
-                        {
-                            $this->error($e->getMessage());
-                        }
-                    }
-                    else
-                    {
-                        $this->error($this->model->getError());
-                    }
-                }
-                catch (Exception $e)
-                {
-                    $this->error($e->getMessage());
-                }
-            }
-            $this->error(__('Parameter %s can not be empty', ''));
-        }
-        return $this->view->fetch();
-    }
-
-    public function edit($ids = NULL)
-    {
-        if ($this->request->isPost())
-        {
-            $row = $this->request->post("row/a");
-            if ($row)
-            {
-                $configList = [];
-                foreach ($this->model->all() as $v)
-                {
-                    if (isset($row[$v['name']]))
-                    {
-                        $value = $row[$v['name']];
-                        if (is_array($value) && isset($value['field']))
-                        {
-                            $value = json_encode(\app\common\model\Config::getArrayData($value), JSON_UNESCAPED_UNICODE);
-                        }
-                        else
-                        {
-                            $value = is_array($value) ? implode(',', $value) : $value;
-                        }
-                        $v['value'] = $value;
-                        $configList[] = $v->toArray();
-                    }
-                }
-                $this->model->allowField(true)->saveAll($configList);
-                try
-                {
-                    $this->refreshFile();
-                    $this->success();
-                }
-                catch (Exception $e)
-                {
-                    $this->error($e->getMessage());
-                }
-            }
-            $this->error(__('Parameter %s can not be empty', ''));
-        }
-    }
-
-    protected function refreshFile()
-    {
-        $config = [];
-        foreach ($this->model->all() as $k => $v)
-        {
-
-            $value = $v->toArray();
-            if (in_array($value['type'], ['selects', 'checkbox', 'images', 'files']))
-            {
-                $value['value'] = explode(',', $value['value']);
-            }
-            if ($value['type'] == 'array')
-            {
-                $value['value'] = (array) json_decode($value['value'], TRUE);
-            }
-            $config[$value['name']] = $value['value'];
-        }
-        file_put_contents(APP_PATH . 'extra' . DS . 'site.php', '<?php' . "\n\nreturn " . var_export($config, true) . ";");
-    }
-
-    /**
-     * @internal
-     */
-    public function check()
-    {
-        $params = $this->request->post("row/a");
-        if ($params)
-        {
-
-            $config = $this->model->get($params);
-            if (!$config)
-            {
-                return json(['ok' => '']);
-            }
-            else
-            {
-                return json(['error' => __('Name already exist')]);
-            }
-        }
-        else
-        {
-            return json(['error' => __('Invalid parameters')]);
-        }
-    }
-
-    /**
-     * 发送测试邮件
-     * @internal
-     */
-    public function emailtest()
-    {
-        $receiver = $this->request->request("receiver");
-        $email = new Email;
-        $result = $email
-                ->to($receiver)
-                ->subject(__("This is a test mail"))
-                ->message('<div style="min-height:550px; padding: 100px 55px 200px;">' . __('This is a test mail content') . '</div>')
-                ->send();
-        if ($result)
-        {
-            $this->success();
-        }
-        else
-        {
-            $this->error($email->getError());
-        }
-    }
-
-}
+<?php
+
+namespace app\admin\controller\general;
+
+use app\common\controller\Backend;
+use app\common\library\Email;
+use app\common\model\Config as ConfigModel;
+use think\Exception;
+
+/**
+ * 系统配置
+ *
+ * @icon fa fa-circle-o
+ */
+class Config extends Backend
+{
+
+    protected $model = null;
+    protected $noNeedRight = ['check'];
+
+    public function _initialize()
+    {
+        parent::_initialize();
+        $this->model = model('Config');
+    }
+
+    public function index()
+    {
+        $siteList = [];
+        $groupList = ConfigModel::getGroupList();
+        foreach ($groupList as $k => $v)
+        {
+            $siteList[$k]['name'] = $k;
+            $siteList[$k]['title'] = $v;
+            $siteList[$k]['list'] = [];
+        }
+
+        foreach ($this->model->all() as $k => $v)
+        {
+            if (!isset($siteList[$v['group']]))
+            {
+                continue;
+            }
+            $value = $v->toArray();
+            $value['title'] = __($value['title']);
+            if (in_array($value['type'], ['select', 'selects', 'checkbox', 'radio']))
+            {
+                $value['value'] = explode(',', $value['value']);
+            }
+            if ($value['type'] == 'array')
+            {
+                $value['value'] = (array) json_decode($value['value'], TRUE);
+            }
+            $value['content'] = json_decode($value['content'], TRUE);
+            $siteList[$v['group']]['list'][] = $value;
+        }
+        $index = 0;
+        foreach ($siteList as $k => &$v)
+        {
+            $v['active'] = !$index ? true : false;
+            $index++;
+        }
+        $this->view->assign('siteList', $siteList);
+        $this->view->assign('typeList', ConfigModel::getTypeList());
+        $this->view->assign('groupList', ConfigModel::getGroupList());
+        return $this->view->fetch();
+    }
+
+    /**
+     * 添加
+     */
+    public function add()
+    {
+        if ($this->request->isPost())
+        {
+            $params = $this->request->post("row/a");
+            if ($params)
+            {
+                foreach ($params as $k => &$v)
+                {
+                    $v = is_array($v) ? implode(',', $v) : $v;
+                }
+                try
+                {
+                    if (in_array($params['type'], ['select', 'selects', 'checkbox', 'radio', 'array']))
+                    {
+                        $params['content'] = ConfigModel::decode($params['content']);
+                    }
+                    else
+                    {
+                        $params['content'] = '';
+                    }
+                    $result = $this->model->create($params);
+                    if ($result !== false)
+                    {
+                        try
+                        {
+                            $this->refreshFile();
+                            $this->success();
+                        }
+                        catch (Exception $e)
+                        {
+                            $this->error($e->getMessage());
+                        }
+                    }
+                    else
+                    {
+                        $this->error($this->model->getError());
+                    }
+                }
+                catch (Exception $e)
+                {
+                    $this->error($e->getMessage());
+                }
+            }
+            $this->error(__('Parameter %s can not be empty', ''));
+        }
+        return $this->view->fetch();
+    }
+
+    public function edit($ids = NULL)
+    {
+        if ($this->request->isPost())
+        {
+            $row = $this->request->post("row/a");
+            if ($row)
+            {
+                $configList = [];
+                foreach ($this->model->all() as $v)
+                {
+                    if (isset($row[$v['name']]))
+                    {
+                        $value = $row[$v['name']];
+                        if (is_array($value) && isset($value['field']))
+                        {
+                            $value = json_encode(\app\common\model\Config::getArrayData($value), JSON_UNESCAPED_UNICODE);
+                        }
+                        else
+                        {
+                            $value = is_array($value) ? implode(',', $value) : $value;
+                        }
+                        $v['value'] = $value;
+                        $configList[] = $v->toArray();
+                    }
+                }
+                $this->model->allowField(true)->saveAll($configList);
+                try
+                {
+                    $this->refreshFile();
+                    $this->success();
+                }
+                catch (Exception $e)
+                {
+                    $this->error($e->getMessage());
+                }
+            }
+            $this->error(__('Parameter %s can not be empty', ''));
+        }
+    }
+
+    protected function refreshFile()
+    {
+        $config = [];
+        foreach ($this->model->all() as $k => $v)
+        {
+
+            $value = $v->toArray();
+            if (in_array($value['type'], ['selects', 'checkbox', 'images', 'files']))
+            {
+                $value['value'] = explode(',', $value['value']);
+            }
+            if ($value['type'] == 'array')
+            {
+                $value['value'] = (array) json_decode($value['value'], TRUE);
+            }
+            $config[$value['name']] = $value['value'];
+        }
+        file_put_contents(APP_PATH . 'extra' . DS . 'site.php', '<?php' . "\n\nreturn " . var_export($config, true) . ";");
+    }
+
+    /**
+     * @internal
+     */
+    public function check()
+    {
+        $params = $this->request->post("row/a");
+        if ($params)
+        {
+
+            $config = $this->model->get($params);
+            if (!$config)
+            {
+                return json(['ok' => '']);
+            }
+            else
+            {
+                return json(['error' => __('Name already exist')]);
+            }
+        }
+        else
+        {
+            return json(['error' => __('Invalid parameters')]);
+        }
+    }
+
+    /**
+     * 发送测试邮件
+     * @internal
+     */
+    public function emailtest()
+    {
+        $receiver = $this->request->request("receiver");
+        $email = new Email;
+        $result = $email
+                ->to($receiver)
+                ->subject(__("This is a test mail"))
+                ->message('<div style="min-height:550px; padding: 100px 55px 200px;">' . __('This is a test mail content') . '</div>')
+                ->send();
+        if ($result)
+        {
+            $this->success();
+        }
+        else
+        {
+            $this->error($email->getError());
+        }
+    }
+
+}

+ 82 - 82
application/admin/controller/general/Profile.php

@@ -1,82 +1,82 @@
-<?php
-
-namespace app\admin\controller\general;
-
-use think\Session;
-use app\admin\model\AdminLog;
-use app\common\controller\Backend;
-use fast\Random;
-
-/**
- * 个人配置
- *
- * @icon fa fa-user
- */
-class Profile extends Backend
-{
-
-    /**
-     * 查看
-     */
-    public function index()
-    {
-        //设置过滤方法
-        $this->request->filter(['strip_tags']);
-        if ($this->request->isAjax())
-        {
-            $model = model('AdminLog');
-            list($where, $sort, $order, $offset, $limit) = $this->buildparams();
-
-            $total = $model
-                    ->where($where)
-                    ->where('admin_id', $this->auth->id)
-                    ->order($sort, $order)
-                    ->count();
-
-            $list = $model
-                    ->where($where)
-                    ->where('admin_id', $this->auth->id)
-                    ->order($sort, $order)
-                    ->limit($offset, $limit)
-                    ->select();
-
-            $result = array("total" => $total, "rows" => $list);
-
-            return json($result);
-        }
-        return $this->view->fetch();
-    }
-
-    /**
-     * 更新个人信息
-     */
-    public function update()
-    {
-        if ($this->request->isPost())
-        {
-            $params = $this->request->post("row/a");
-            $params = array_filter(array_intersect_key($params, array_flip(array('email', 'nickname', 'password', 'avatar'))));
-            unset($v);
-            if (isset($params['password']))
-            {
-                $params['salt'] = Random::alnum();
-                $params['password'] = md5(md5($params['password']) . $params['salt']);
-            }
-            if ($params)
-            {
-                model('admin')->where('id', $this->auth->id)->update($params);
-                //因为个人资料面板读取的Session显示,修改自己资料后同时更新Session
-                $admin = Session::get('admin');
-                $admin_id = $admin ? $admin->id : 0;
-                if($this->auth->id==$admin_id){
-                    $admin = model('admin')->get(['id' => $admin_id]);
-                    Session::set("admin", $admin);
-                }
-                $this->success();
-            }
-            $this->error();
-        }
-        return;
-    }
-
-}
+<?php
+
+namespace app\admin\controller\general;
+
+use think\Session;
+use app\admin\model\AdminLog;
+use app\common\controller\Backend;
+use fast\Random;
+
+/**
+ * 个人配置
+ *
+ * @icon fa fa-user
+ */
+class Profile extends Backend
+{
+
+    /**
+     * 查看
+     */
+    public function index()
+    {
+        //设置过滤方法
+        $this->request->filter(['strip_tags']);
+        if ($this->request->isAjax())
+        {
+            $model = model('AdminLog');
+            list($where, $sort, $order, $offset, $limit) = $this->buildparams();
+
+            $total = $model
+                    ->where($where)
+                    ->where('admin_id', $this->auth->id)
+                    ->order($sort, $order)
+                    ->count();
+
+            $list = $model
+                    ->where($where)
+                    ->where('admin_id', $this->auth->id)
+                    ->order($sort, $order)
+                    ->limit($offset, $limit)
+                    ->select();
+
+            $result = array("total" => $total, "rows" => $list);
+
+            return json($result);
+        }
+        return $this->view->fetch();
+    }
+
+    /**
+     * 更新个人信息
+     */
+    public function update()
+    {
+        if ($this->request->isPost())
+        {
+            $params = $this->request->post("row/a");
+            $params = array_filter(array_intersect_key($params, array_flip(array('email', 'nickname', 'password', 'avatar'))));
+            unset($v);
+            if (isset($params['password']))
+            {
+                $params['salt'] = Random::alnum();
+                $params['password'] = md5(md5($params['password']) . $params['salt']);
+            }
+            if ($params)
+            {
+                model('admin')->where('id', $this->auth->id)->update($params);
+                //因为个人资料面板读取的Session显示,修改自己资料后同时更新Session
+                $admin = Session::get('admin');
+                $admin_id = $admin ? $admin->id : 0;
+                if($this->auth->id==$admin_id){
+                    $admin = model('admin')->get(['id' => $admin_id]);
+                    Session::set("admin", $admin);
+                }
+                $this->success();
+            }
+            $this->error();
+        }
+        return;
+    }
+
+}

+ 394 - 394
application/admin/library/traits/Backend.php

@@ -1,394 +1,394 @@
-<?php
-
-namespace app\admin\library\traits;
-
-trait Backend
-{
-
-    /**
-     * 查看
-     */
-    public function index()
-    {
-        //设置过滤方法
-        $this->request->filter(['strip_tags']);
-        if ($this->request->isAjax())
-        {
-            //如果发送的来源是Selectpage,则转发到Selectpage
-            if ($this->request->request('pkey_name'))
-            {
-                return $this->selectpage();
-            }
-            list($where, $sort, $order, $offset, $limit) = $this->buildparams();
-            $total = $this->model
-                    ->where($where)
-                    ->order($sort, $order)
-                    ->count();
-
-            $list = $this->model
-                    ->where($where)
-                    ->order($sort, $order)
-                    ->limit($offset, $limit)
-                    ->select();
-
-            $result = array("total" => $total, "rows" => $list);
-
-            return json($result);
-        }
-        return $this->view->fetch();
-    }
-
-    /**
-     * 回收站
-     */
-    public function recyclebin()
-    {
-        //设置过滤方法
-        $this->request->filter(['strip_tags']);
-        if ($this->request->isAjax())
-        {
-            list($where, $sort, $order, $offset, $limit) = $this->buildparams();
-            $total = $this->model
-                    ->onlyTrashed()
-                    ->where($where)
-                    ->order($sort, $order)
-                    ->count();
-
-            $list = $this->model
-                    ->onlyTrashed()
-                    ->where($where)
-                    ->order($sort, $order)
-                    ->limit($offset, $limit)
-                    ->select();
-
-            $result = array("total" => $total, "rows" => $list);
-
-            return json($result);
-        }
-        return $this->view->fetch();
-    }
-
-    /**
-     * 添加
-     */
-    public function add()
-    {
-        if ($this->request->isPost())
-        {
-            $params = $this->request->post("row/a");
-            if ($params)
-            {
-                /*
-                 * 已经弃用,如果为了兼容老版可取消注释
-                  foreach ($params as $k => &$v)
-                  {
-                  $v = is_array($v) ? implode(',', $v) : $v;
-                  }
-                 */
-                if ($this->dataLimit)
-                {
-                    $params[$this->dataLimitField] = $this->auth->id;
-                }
-                try
-                {
-                    //是否采用模型验证
-                    if ($this->modelValidate)
-                    {
-                        $name = basename(str_replace('\\', '/', get_class($this->model)));
-                        $validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.add' : true) : $this->modelValidate;
-                        $this->model->validate($validate);
-                    }
-                    $result = $this->model->allowField(true)->save($params);
-                    if ($result !== false)
-                    {
-                        $this->success();
-                    }
-                    else
-                    {
-                        $this->error($this->model->getError());
-                    }
-                }
-                catch (\think\exception\PDOException $e)
-                {
-                    $this->error($e->getMessage());
-                }
-            }
-            $this->error(__('Parameter %s can not be empty', ''));
-        }
-        return $this->view->fetch();
-    }
-
-    /**
-     * 编辑
-     */
-    public function edit($ids = NULL)
-    {
-        $row = $this->model->get($ids);
-        if (!$row)
-            $this->error(__('No Results were found'));
-        $adminIds = $this->getDataLimitAdminIds();
-        if (is_array($adminIds))
-        {
-            if (!in_array($row[$this->dataLimitField], $adminIds))
-            {
-                $this->error(__('You have no permission'));
-            }
-        }
-        if ($this->request->isPost())
-        {
-            $params = $this->request->post("row/a");
-            if ($params)
-            {
-                /*
-                 * 已经弃用,如果为了兼容老版可取消注释
-                  foreach ($params as $k => &$v)
-                  {
-                  $v = is_array($v) ? implode(',', $v) : $v;
-                  }
-                 */
-                try
-                {
-                    //是否采用模型验证
-                    if ($this->modelValidate)
-                    {
-                        $name = basename(str_replace('\\', '/', get_class($this->model)));
-                        $validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.edit' : true) : $this->modelValidate;
-                        $row->validate($validate);
-                    }
-                    $result = $row->allowField(true)->save($params);
-                    if ($result !== false)
-                    {
-                        $this->success();
-                    }
-                    else
-                    {
-                        $this->error($row->getError());
-                    }
-                }
-                catch (\think\exception\PDOException $e)
-                {
-                    $this->error($e->getMessage());
-                }
-            }
-            $this->error(__('Parameter %s can not be empty', ''));
-        }
-        $this->view->assign("row", $row);
-        return $this->view->fetch();
-    }
-
-    /**
-     * 删除
-     */
-    public function del($ids = "")
-    {
-        if ($ids)
-        {
-            $pk = $this->model->getPk();
-            $adminIds = $this->getDataLimitAdminIds();
-            if (is_array($adminIds))
-            {
-                $count = $this->model->where($this->dataLimitField, 'in', $adminIds);
-            }
-            $list = $this->model->where($pk, 'in', $ids)->select();
-            $count = 0;
-            foreach ($list as $k => $v)
-            {
-                $count += $v->delete();
-            }
-            if ($count)
-            {
-                $this->success();
-            }
-            else
-            {
-                $this->error(__('No rows were deleted'));
-            }
-        }
-        $this->error(__('Parameter %s can not be empty', 'ids'));
-    }
-
-    /**
-     * 真实删除
-     */
-    public function destroy($ids = "")
-    {
-        $pk = $this->model->getPk();
-        $adminIds = $this->getDataLimitAdminIds();
-        if (is_array($adminIds))
-        {
-            $count = $this->model->where($this->dataLimitField, 'in', $adminIds);
-        }
-        if ($ids)
-        {
-            $this->model->where($pk, 'in', $ids);
-        }
-        $count = 0;
-        $list = $this->model->onlyTrashed()->select();
-        foreach ($list as $k => $v)
-        {
-            $count += $v->delete(true);
-        }
-        if ($count)
-        {
-            $this->success();
-        }
-        else
-        {
-            $this->error(__('No rows were deleted'));
-        }
-        $this->error(__('Parameter %s can not be empty', 'ids'));
-    }
-
-    /**
-     * 还原
-     */
-    public function restore($ids = "")
-    {
-        $pk = $this->model->getPk();
-        $adminIds = $this->getDataLimitAdminIds();
-        if (is_array($adminIds))
-        {
-            $this->model->where($this->dataLimitField, 'in', $adminIds);
-        }
-        if ($ids)
-        {
-            $this->model->where($pk, 'in', $ids);
-        }
-        $count = $this->model->restore('1=1');
-        if ($count)
-        {
-            $this->success();
-        }
-        $this->error(__('No rows were updated'));
-    }
-
-    /**
-     * 批量更新
-     */
-    public function multi($ids = "")
-    {
-        $ids = $ids ? $ids : $this->request->param("ids");
-        if ($ids)
-        {
-            if ($this->request->has('params'))
-            {
-                parse_str($this->request->post("params"), $values);
-                $values = array_intersect_key($values, array_flip(is_array($this->multiFields) ? $this->multiFields : explode(',', $this->multiFields)));
-                if ($values)
-                {
-                    $adminIds = $this->getDataLimitAdminIds();
-                    if (is_array($adminIds))
-                    {
-                        $this->model->where($this->dataLimitField, 'in', $adminIds);
-                    }
-                    $count = $this->model->where($this->model->getPk(), 'in', $ids)->update($values);
-                    if ($count)
-                    {
-                        $this->success();
-                    }
-                    else
-                    {
-                        $this->error(__('No rows were updated'));
-                    }
-                }
-                else
-                {
-                    $this->error(__('You have no permission'));
-                }
-            }
-        }
-        $this->error(__('Parameter %s can not be empty', 'ids'));
-    }
-
-    /**
-     * 导入
-     */
-    protected function import()
-    {
-        $file = $this->request->request('file');
-        if (!$file)
-        {
-            $this->error(__('Parameter %s can not be empty', 'file'));
-        }
-        $filePath = ROOT_PATH . DS . 'public' . DS . $file;
-        if (!is_file($filePath))
-        {
-            $this->error(__('No results were found'));
-        }
-        $PHPReader = new \PHPExcel_Reader_Excel2007();
-        if (!$PHPReader->canRead($filePath))
-        {
-            $PHPReader = new \PHPExcel_Reader_Excel5();
-            if (!$PHPReader->canRead($filePath))
-            {
-                $PHPReader = new \PHPExcel_Reader_CSV();
-                if (!$PHPReader->canRead($filePath))
-                {
-                    $this->error(__('Unknown data format'));
-                }
-            }
-        }
-
-        $table = $this->model->getQuery()->getTable();
-        $database = \think\Config::get('database.database');
-        $fieldArr = [];
-        $list = db()->query("SELECT COLUMN_NAME,COLUMN_COMMENT FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = ? AND TABLE_SCHEMA = ?", [$table, $database]);
-        foreach ($list as $k => $v)
-        {
-            $fieldArr[$v['COLUMN_COMMENT']] = $v['COLUMN_NAME'];
-        }
-
-        $PHPExcel = $PHPReader->load($filePath); //加载文件
-        $currentSheet = $PHPExcel->getSheet(0);  //读取文件中的第一个工作表
-        $allColumn = $currentSheet->getHighestColumn(); //取得最大的列号
-        $allRow = $currentSheet->getHighestRow(); //取得一共有多少行
-
-        for ($currentRow = 1; $currentRow <= 1; $currentRow++)
-        {
-            for ($currentColumn = 'A'; $currentColumn <= $allColumn; $currentColumn++)
-            {
-                $val = $currentSheet->getCellByColumnAndRow(ord($currentColumn) - 65, $currentRow)->getValue();
-                $fields[] = $val;
-            }
-        }
-        $insert = [];
-        for ($currentRow = 2; $currentRow <= $allRow; $currentRow++)
-        {
-            $values = [];
-            for ($currentColumn = 'A'; $currentColumn <= $allColumn; $currentColumn++)
-            {
-                $val = $currentSheet->getCellByColumnAndRow(ord($currentColumn) - 65, $currentRow)->getValue(); /*                 * ord()将字符转为十进制数 */
-                $values[] = is_null($val) ? '' : $val;
-                //echo iconv('utf-8','gb2312', $val)."\t"; 
-            }
-            $row = [];
-            $temp = array_combine($fields, $values);
-            foreach ($temp as $k => $v)
-            {
-                if (isset($fieldArr[$k]) && $k !== '')
-                {
-                    $row[$fieldArr[$k]] = $v;
-                }
-            }
-            if ($row)
-            {
-                $insert[] = $row;
-            }
-        }
-        if (!$insert)
-        {
-            $this->error(__('No rows were updated'));
-        }
-        try
-        {
-            $this->model->saveAll($insert);
-        }
-        catch (\think\exception\PDOException $exception)
-        {
-            $this->error($exception->getMessage());
-        }
-
-        $this->success();
-    }
-
-}
+<?php
+
+namespace app\admin\library\traits;
+
+trait Backend
+{
+
+    /**
+     * 查看
+     */
+    public function index()
+    {
+        //设置过滤方法
+        $this->request->filter(['strip_tags']);
+        if ($this->request->isAjax())
+        {
+            //如果发送的来源是Selectpage,则转发到Selectpage
+            if ($this->request->request('pkey_name'))
+            {
+                return $this->selectpage();
+            }
+            list($where, $sort, $order, $offset, $limit) = $this->buildparams();
+            $total = $this->model
+                    ->where($where)
+                    ->order($sort, $order)
+                    ->count();
+
+            $list = $this->model
+                    ->where($where)
+                    ->order($sort, $order)
+                    ->limit($offset, $limit)
+                    ->select();
+
+            $result = array("total" => $total, "rows" => $list);
+
+            return json($result);
+        }
+        return $this->view->fetch();
+    }
+
+    /**
+     * 回收站
+     */
+    public function recyclebin()
+    {
+        //设置过滤方法
+        $this->request->filter(['strip_tags']);
+        if ($this->request->isAjax())
+        {
+            list($where, $sort, $order, $offset, $limit) = $this->buildparams();
+            $total = $this->model
+                    ->onlyTrashed()
+                    ->where($where)
+                    ->order($sort, $order)
+                    ->count();
+
+            $list = $this->model
+                    ->onlyTrashed()
+                    ->where($where)
+                    ->order($sort, $order)
+                    ->limit($offset, $limit)
+                    ->select();
+
+            $result = array("total" => $total, "rows" => $list);
+
+            return json($result);
+        }
+        return $this->view->fetch();
+    }
+
+    /**
+     * 添加
+     */
+    public function add()
+    {
+        if ($this->request->isPost())
+        {
+            $params = $this->request->post("row/a");
+            if ($params)
+            {
+                /*
+                 * 已经弃用,如果为了兼容老版可取消注释
+                  foreach ($params as $k => &$v)
+                  {
+                  $v = is_array($v) ? implode(',', $v) : $v;
+                  }
+                 */
+                if ($this->dataLimit)
+                {
+                    $params[$this->dataLimitField] = $this->auth->id;
+                }
+                try
+                {
+                    //是否采用模型验证
+                    if ($this->modelValidate)
+                    {
+                        $name = basename(str_replace('\\', '/', get_class($this->model)));
+                        $validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.add' : true) : $this->modelValidate;
+                        $this->model->validate($validate);
+                    }
+                    $result = $this->model->allowField(true)->save($params);
+                    if ($result !== false)
+                    {
+                        $this->success();
+                    }
+                    else
+                    {
+                        $this->error($this->model->getError());
+                    }
+                }
+                catch (\think\exception\PDOException $e)
+                {
+                    $this->error($e->getMessage());
+                }
+            }
+            $this->error(__('Parameter %s can not be empty', ''));
+        }
+        return $this->view->fetch();
+    }
+
+    /**
+     * 编辑
+     */
+    public function edit($ids = NULL)
+    {
+        $row = $this->model->get($ids);
+        if (!$row)
+            $this->error(__('No Results were found'));
+        $adminIds = $this->getDataLimitAdminIds();
+        if (is_array($adminIds))
+        {
+            if (!in_array($row[$this->dataLimitField], $adminIds))
+            {
+                $this->error(__('You have no permission'));
+            }
+        }
+        if ($this->request->isPost())
+        {
+            $params = $this->request->post("row/a");
+            if ($params)
+            {
+                /*
+                 * 已经弃用,如果为了兼容老版可取消注释
+                  foreach ($params as $k => &$v)
+                  {
+                  $v = is_array($v) ? implode(',', $v) : $v;
+                  }
+                 */
+                try
+                {
+                    //是否采用模型验证
+                    if ($this->modelValidate)
+                    {
+                        $name = basename(str_replace('\\', '/', get_class($this->model)));
+                        $validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.edit' : true) : $this->modelValidate;
+                        $row->validate($validate);
+                    }
+                    $result = $row->allowField(true)->save($params);
+                    if ($result !== false)
+                    {
+                        $this->success();
+                    }
+                    else
+                    {
+                        $this->error($row->getError());
+                    }
+                }
+                catch (\think\exception\PDOException $e)
+                {
+                    $this->error($e->getMessage());
+                }
+            }
+            $this->error(__('Parameter %s can not be empty', ''));
+        }
+        $this->view->assign("row", $row);
+        return $this->view->fetch();
+    }
+
+    /**
+     * 删除
+     */
+    public function del($ids = "")
+    {
+        if ($ids)
+        {
+            $pk = $this->model->getPk();
+            $adminIds = $this->getDataLimitAdminIds();
+            if (is_array($adminIds))
+            {
+                $count = $this->model->where($this->dataLimitField, 'in', $adminIds);
+            }
+            $list = $this->model->where($pk, 'in', $ids)->select();
+            $count = 0;
+            foreach ($list as $k => $v)
+            {
+                $count += $v->delete();
+            }
+            if ($count)
+            {
+                $this->success();
+            }
+            else
+            {
+                $this->error(__('No rows were deleted'));
+            }
+        }
+        $this->error(__('Parameter %s can not be empty', 'ids'));
+    }
+
+    /**
+     * 真实删除
+     */
+    public function destroy($ids = "")
+    {
+        $pk = $this->model->getPk();
+        $adminIds = $this->getDataLimitAdminIds();
+        if (is_array($adminIds))
+        {
+            $count = $this->model->where($this->dataLimitField, 'in', $adminIds);
+        }
+        if ($ids)
+        {
+            $this->model->where($pk, 'in', $ids);
+        }
+        $count = 0;
+        $list = $this->model->onlyTrashed()->select();
+        foreach ($list as $k => $v)
+        {
+            $count += $v->delete(true);
+        }
+        if ($count)
+        {
+            $this->success();
+        }
+        else
+        {
+            $this->error(__('No rows were deleted'));
+        }
+        $this->error(__('Parameter %s can not be empty', 'ids'));
+    }
+
+    /**
+     * 还原
+     */
+    public function restore($ids = "")
+    {
+        $pk = $this->model->getPk();
+        $adminIds = $this->getDataLimitAdminIds();
+        if (is_array($adminIds))
+        {
+            $this->model->where($this->dataLimitField, 'in', $adminIds);
+        }
+        if ($ids)
+        {
+            $this->model->where($pk, 'in', $ids);
+        }
+        $count = $this->model->restore('1=1');
+        if ($count)
+        {
+            $this->success();
+        }
+        $this->error(__('No rows were updated'));
+    }
+
+    /**
+     * 批量更新
+     */
+    public function multi($ids = "")
+    {
+        $ids = $ids ? $ids : $this->request->param("ids");
+        if ($ids)
+        {
+            if ($this->request->has('params'))
+            {
+                parse_str($this->request->post("params"), $values);
+                $values = array_intersect_key($values, array_flip(is_array($this->multiFields) ? $this->multiFields : explode(',', $this->multiFields)));
+                if ($values)
+                {
+                    $adminIds = $this->getDataLimitAdminIds();
+                    if (is_array($adminIds))
+                    {
+                        $this->model->where($this->dataLimitField, 'in', $adminIds);
+                    }
+                    $count = $this->model->where($this->model->getPk(), 'in', $ids)->update($values);
+                    if ($count)
+                    {
+                        $this->success();
+                    }
+                    else
+                    {
+                        $this->error(__('No rows were updated'));
+                    }
+                }
+                else
+                {
+                    $this->error(__('You have no permission'));
+                }
+            }
+        }
+        $this->error(__('Parameter %s can not be empty', 'ids'));
+    }
+
+    /**
+     * 导入
+     */
+    protected function import()
+    {
+        $file = $this->request->request('file');
+        if (!$file)
+        {
+            $this->error(__('Parameter %s can not be empty', 'file'));
+        }
+        $filePath = ROOT_PATH . DS . 'public' . DS . $file;
+        if (!is_file($filePath))
+        {
+            $this->error(__('No results were found'));
+        }
+        $PHPReader = new \PHPExcel_Reader_Excel2007();
+        if (!$PHPReader->canRead($filePath))
+        {
+            $PHPReader = new \PHPExcel_Reader_Excel5();
+            if (!$PHPReader->canRead($filePath))
+            {
+                $PHPReader = new \PHPExcel_Reader_CSV();
+                if (!$PHPReader->canRead($filePath))
+                {
+                    $this->error(__('Unknown data format'));
+                }
+            }
+        }
+
+        $table = $this->model->getQuery()->getTable();
+        $database = \think\Config::get('database.database');
+        $fieldArr = [];
+        $list = db()->query("SELECT COLUMN_NAME,COLUMN_COMMENT FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = ? AND TABLE_SCHEMA = ?", [$table, $database]);
+        foreach ($list as $k => $v)
+        {
+            $fieldArr[$v['COLUMN_COMMENT']] = $v['COLUMN_NAME'];
+        }
+
+        $PHPExcel = $PHPReader->load($filePath); //加载文件
+        $currentSheet = $PHPExcel->getSheet(0);  //读取文件中的第一个工作表
+        $allColumn = $currentSheet->getHighestColumn(); //取得最大的列号
+        $allRow = $currentSheet->getHighestRow(); //取得一共有多少行
+
+        for ($currentRow = 1; $currentRow <= 1; $currentRow++)
+        {
+            for ($currentColumn = 'A'; $currentColumn <= $allColumn; $currentColumn++)
+            {
+                $val = $currentSheet->getCellByColumnAndRow(ord($currentColumn) - 65, $currentRow)->getValue();
+                $fields[] = $val;
+            }
+        }
+        $insert = [];
+        for ($currentRow = 2; $currentRow <= $allRow; $currentRow++)
+        {
+            $values = [];
+            for ($currentColumn = 'A'; $currentColumn <= $allColumn; $currentColumn++)
+            {
+                $val = $currentSheet->getCellByColumnAndRow(ord($currentColumn) - 65, $currentRow)->getValue(); /*                 * ord()将字符转为十进制数 */
+                $values[] = is_null($val) ? '' : $val;
+                //echo iconv('utf-8','gb2312', $val)."\t"; 
+            }
+            $row = [];
+            $temp = array_combine($fields, $values);
+            foreach ($temp as $k => $v)
+            {
+                if (isset($fieldArr[$k]) && $k !== '')
+                {
+                    $row[$fieldArr[$k]] = $v;
+                }
+            }
+            if ($row)
+            {
+                $insert[] = $row;
+            }
+        }
+        if (!$insert)
+        {
+            $this->error(__('No rows were updated'));
+        }
+        try
+        {
+            $this->model->saveAll($insert);
+        }
+        catch (\think\exception\PDOException $exception)
+        {
+            $this->error($exception->getMessage());
+        }
+
+        $this->success();
+    }
+
+}

+ 34 - 34
application/admin/model/Admin.php

@@ -1,34 +1,34 @@
-<?php
-
-namespace app\admin\model;
-
-use think\Model;
-use think\Session;
-
-class Admin extends Model
-{
-
-    // 开启自动写入时间戳字段
-    protected $autoWriteTimestamp = 'int';
-    // 定义时间戳字段名
-    protected $createTime = 'createtime';
-    protected $updateTime = 'updatetime';
-
-    /**
-     * 重置用户密码
-     * @author baiyouwen
-     */
-    public function resetPassword($uid, $NewPassword)
-    {
-        $passwd = $this->encryptPassword($NewPassword);
-        $ret = $this->where(['id' => $uid])->update(['password' => $passwd]);
-        return $ret;
-    }
-
-    // 密码加密
-    protected function encryptPassword($password, $salt = '', $encrypt = 'md5')
-    {
-        return $encrypt($password . $salt);
-    }
-
-}
+<?php
+
+namespace app\admin\model;
+
+use think\Model;
+use think\Session;
+
+class Admin extends Model
+{
+
+    // 开启自动写入时间戳字段
+    protected $autoWriteTimestamp = 'int';
+    // 定义时间戳字段名
+    protected $createTime = 'createtime';
+    protected $updateTime = 'updatetime';
+
+    /**
+     * 重置用户密码
+     * @author baiyouwen
+     */
+    public function resetPassword($uid, $NewPassword)
+    {
+        $passwd = $this->encryptPassword($NewPassword);
+        $ret = $this->where(['id' => $uid])->update(['password' => $passwd]);
+        return $ret;
+    }
+
+    // 密码加密
+    protected function encryptPassword($password, $salt = '', $encrypt = 'md5')
+    {
+        return $encrypt($password . $salt);
+    }
+
+}

+ 74 - 74
application/admin/model/AdminLog.php

@@ -1,74 +1,74 @@
-<?php
-
-namespace app\admin\model;
-
-use think\Model;
-
-class AdminLog extends Model
-{
-
-    // 开启自动写入时间戳字段
-    protected $autoWriteTimestamp = 'int';
-    // 定义时间戳字段名
-    protected $createTime = 'createtime';
-    protected $updateTime = '';
-    //自定义日志标题
-    protected static $title = '';
-    //自定义日志内容
-    protected static $content = '';
-
-    public static function setTitle($title)
-    {
-        self::$title = $title;
-    }
-
-    public static function setContent($content)
-    {
-        self::$content = $content;
-    }
-
-    public static function record($title = '')
-    {
-        $admin = \think\Session::get('admin');
-        $admin_id = $admin ? $admin->id : 0;
-        $username = $admin ? $admin->username : __('Unknown');
-        $content = self::$content;
-        if (!$content)
-        {
-            $content = request()->param();
-            foreach ($content as $k => $v)
-            {
-                if (is_string($v) && strlen($v) > 200 || stripos($k, 'password') !== false)
-                {
-                    unset($content[$k]);
-                }
-            }
-        }
-        $title = self::$title;
-        if (!$title)
-        {
-            $title = [];
-            $breadcrumb = \app\admin\library\Auth::instance()->getBreadcrumb();
-            foreach ($breadcrumb as $k => $v)
-            {
-                $title[] = $v['title'];
-            }
-            $title = implode(' ', $title);
-        }
-        self::create([
-            'title'     => $title,
-            'content'   => !is_scalar($content) ? json_encode($content) : $content,
-            'url'       => request()->url(),
-            'admin_id'  => $admin_id,
-            'username'  => $username,
-            'useragent' => request()->server('HTTP_USER_AGENT'),
-            'ip'        => request()->ip()
-        ]);
-    }
-
-    public function admin()
-    {
-        return $this->belongsTo('Admin', 'admin_id')->setEagerlyType(0);
-    }
-
-}
+<?php
+
+namespace app\admin\model;
+
+use think\Model;
+
+class AdminLog extends Model
+{
+
+    // 开启自动写入时间戳字段
+    protected $autoWriteTimestamp = 'int';
+    // 定义时间戳字段名
+    protected $createTime = 'createtime';
+    protected $updateTime = '';
+    //自定义日志标题
+    protected static $title = '';
+    //自定义日志内容
+    protected static $content = '';
+
+    public static function setTitle($title)
+    {
+        self::$title = $title;
+    }
+
+    public static function setContent($content)
+    {
+        self::$content = $content;
+    }
+
+    public static function record($title = '')
+    {
+        $admin = \think\Session::get('admin');
+        $admin_id = $admin ? $admin->id : 0;
+        $username = $admin ? $admin->username : __('Unknown');
+        $content = self::$content;
+        if (!$content)
+        {
+            $content = request()->param();
+            foreach ($content as $k => $v)
+            {
+                if (is_string($v) && strlen($v) > 200 || stripos($k, 'password') !== false)
+                {
+                    unset($content[$k]);
+                }
+            }
+        }
+        $title = self::$title;
+        if (!$title)
+        {
+            $title = [];
+            $breadcrumb = \app\admin\library\Auth::instance()->getBreadcrumb();
+            foreach ($breadcrumb as $k => $v)
+            {
+                $title[] = $v['title'];
+            }
+            $title = implode(' ', $title);
+        }
+        self::create([
+            'title'     => $title,
+            'content'   => !is_scalar($content) ? json_encode($content) : $content,
+            'url'       => request()->url(),
+            'admin_id'  => $admin_id,
+            'username'  => $username,
+            'useragent' => request()->server('HTTP_USER_AGENT'),
+            'ip'        => request()->ip()
+        ]);
+    }
+
+    public function admin()
+    {
+        return $this->belongsTo('Admin', 'admin_id')->setEagerlyType(0);
+    }
+
+}

+ 21 - 21
application/admin/model/AuthGroup.php

@@ -1,21 +1,21 @@
-<?php
-
-namespace app\admin\model;
-
-use think\Model;
-
-class AuthGroup extends Model
-{
-
-    // 开启自动写入时间戳字段
-    protected $autoWriteTimestamp = 'int';
-    // 定义时间戳字段名
-    protected $createTime = 'createtime';
-    protected $updateTime = 'updatetime';
-
-    public function getNameAttr($value, $data)
-    {
-        return __($value);
-    }
-
-}
+<?php
+
+namespace app\admin\model;
+
+use think\Model;
+
+class AuthGroup extends Model
+{
+
+    // 开启自动写入时间戳字段
+    protected $autoWriteTimestamp = 'int';
+    // 定义时间戳字段名
+    protected $createTime = 'createtime';
+    protected $updateTime = 'updatetime';
+
+    public function getNameAttr($value, $data)
+    {
+        return __($value);
+    }
+
+}

+ 10 - 10
application/admin/model/AuthGroupAccess.php

@@ -1,10 +1,10 @@
-<?php
-
-namespace app\admin\model;
-
-use think\Model;
-
-class AuthGroupAccess extends Model
-{
-    //
-}
+<?php
+
+namespace app\admin\model;
+
+use think\Model;
+
+class AuthGroupAccess extends Model
+{
+    //
+}

+ 20 - 20
application/admin/model/AuthRule.php

@@ -1,20 +1,20 @@
-<?php
-
-namespace app\admin\model;
-
-use think\Model;
-
-class AuthRule extends Model
-{
-
-    // 开启自动写入时间戳字段
-    protected $autoWriteTimestamp = 'int';
-    // 定义时间戳字段名
-    protected $createTime = 'createtime';
-    protected $updateTime = 'updatetime';
-
-    public function getTitleAttr($value, $data)
-    {
-        return __($value);
-    }
-}
+<?php
+
+namespace app\admin\model;
+
+use think\Model;
+
+class AuthRule extends Model
+{
+
+    // 开启自动写入时间戳字段
+    protected $autoWriteTimestamp = 'int';
+    // 定义时间戳字段名
+    protected $createTime = 'createtime';
+    protected $updateTime = 'updatetime';
+
+    public function getTitleAttr($value, $data)
+    {
+        return __($value);
+    }
+}

+ 18 - 18
application/admin/tags.php

@@ -1,18 +1,18 @@
-<?php
-
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2006~2016 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: liu21st <liu21st@gmail.com>
-// +----------------------------------------------------------------------
-// 应用行为扩展定义文件
-return [
-    // 应用结束
-    'app_end'      => [
-        'app\\admin\\behavior\\AdminLog',
-    ],
-];
+<?php
+
+// +----------------------------------------------------------------------
+// | ThinkPHP [ WE CAN DO IT JUST THINK ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2006~2016 http://thinkphp.cn All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
+// +----------------------------------------------------------------------
+// | Author: liu21st <liu21st@gmail.com>
+// +----------------------------------------------------------------------
+// 应用行为扩展定义文件
+return [
+    // 应用结束
+    'app_end'      => [
+        'app\\admin\\behavior\\AdminLog',
+    ],
+];

+ 27 - 27
application/admin/validate/Category.php

@@ -1,27 +1,27 @@
-<?php
-
-namespace app\admin\validate;
-
-use think\Validate;
-
-class Category extends Validate
-{
-    /**
-     * 验证规则
-     */
-    protected $rule = [
-    ];
-    /**
-     * 提示消息
-     */
-    protected $message = [
-    ];
-    /**
-     * 验证场景
-     */
-    protected $scene = [
-        'add'  => [],
-        'edit' => [],
-    ];
-    
-}
+<?php
+
+namespace app\admin\validate;
+
+use think\Validate;
+
+class Category extends Validate
+{
+    /**
+     * 验证规则
+     */
+    protected $rule = [
+    ];
+    /**
+     * 提示消息
+     */
+    protected $message = [
+    ];
+    /**
+     * 验证场景
+     */
+    protected $scene = [
+        'add'  => [],
+        'edit' => [],
+    ];
+    
+}

+ 25 - 25
application/build.php

@@ -1,25 +1,25 @@
-<?php
-
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2006~2016 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: liu21st <liu21st@gmail.com>
-// +----------------------------------------------------------------------
-
-return [
-// 生成应用公共文件
-    '__file__' => [],
-    // 定义demo模块的自动生成 (按照实际定义的文件名生成)
-    'demo'     => [
-        '__file__'   => ['common.php'],
-        '__dir__'    => ['behavior', 'controller', 'model', 'view'],
-        'controller' => ['Index', 'Test', 'UserType'],
-        'model'      => ['User', 'UserType'],
-        'view'       => ['index/index'],
-    ],
-        // 其他更多的模块定义
-];
+<?php
+
+// +----------------------------------------------------------------------
+// | ThinkPHP [ WE CAN DO IT JUST THINK ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2006~2016 http://thinkphp.cn All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
+// +----------------------------------------------------------------------
+// | Author: liu21st <liu21st@gmail.com>
+// +----------------------------------------------------------------------
+
+return [
+// 生成应用公共文件
+    '__file__' => [],
+    // 定义demo模块的自动生成 (按照实际定义的文件名生成)
+    'demo'     => [
+        '__file__'   => ['common.php'],
+        '__dir__'    => ['behavior', 'controller', 'model', 'view'],
+        'controller' => ['Index', 'Test', 'UserType'],
+        'model'      => ['User', 'UserType'],
+        'view'       => ['index/index'],
+    ],
+        // 其他更多的模块定义
+];

+ 19 - 19
application/command.php

@@ -1,19 +1,19 @@
-<?php
-
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: yunwuxin <448901948@qq.com>
-// +----------------------------------------------------------------------
-
-return [
-    'app\admin\command\Crud',
-    'app\admin\command\Menu',
-    'app\admin\command\Install',
-    'app\admin\command\Min',
-    'app\admin\command\Addon',
-];
+<?php
+
+// +----------------------------------------------------------------------
+// | ThinkPHP [ WE CAN DO IT JUST THINK ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
+// +----------------------------------------------------------------------
+// | Author: yunwuxin <448901948@qq.com>
+// +----------------------------------------------------------------------
+
+return [
+    'app\admin\command\Crud',
+    'app\admin\command\Menu',
+    'app\admin\command\Install',
+    'app\admin\command\Min',
+    'app\admin\command\Addon',
+];

+ 302 - 302
application/common.php

@@ -1,302 +1,302 @@
-<?php
-
-// 公共助手函数
-
-if (!function_exists('__'))
-{
-
-    /**
-     * 获取语言变量值
-     * @param string    $name 语言变量名
-     * @param array     $vars 动态变量值
-     * @param string    $lang 语言
-     * @return mixed
-     */
-    function __($name, $vars = [], $lang = '')
-    {
-        if (is_numeric($name) || !$name)
-            return $name;
-        if (!is_array($vars))
-        {
-            $vars = func_get_args();
-            array_shift($vars);
-            $lang = '';
-        }
-        return think\Lang::get($name, $vars, $lang);
-    }
-
-}
-
-if (!function_exists('format_bytes'))
-{
-
-    /**
-     * 将字节转换为可读文本
-     * @param int $size 大小
-     * @param string $delimiter 分隔符
-     * @return string
-     */
-    function format_bytes($size, $delimiter = '')
-    {
-        $units = array('B', 'KB', 'MB', 'GB', 'TB', 'PB');
-        for ($i = 0; $size >= 1024 && $i < 6; $i++)
-            $size /= 1024;
-        return round($size, 2) . $delimiter . $units[$i];
-    }
-
-}
-
-if (!function_exists('datetime'))
-{
-
-    /**
-     * 将时间戳转换为日期时间
-     * @param int $time 时间戳
-     * @param string $format 日期时间格式
-     * @return string
-     */
-    function datetime($time, $format = 'Y-m-d H:i:s')
-    {
-        $time = is_numeric($time) ? $time : strtotime($time);
-        return date($format, $time);
-    }
-
-}
-
-if (!function_exists('human_date'))
-{
-
-    /**
-     * 获取语义化时间
-     * @param int $time 时间
-     * @param int $local 本地时间
-     * @return string
-     */
-    function human_date($time, $local = null)
-    {
-        return \fast\Date::human($time, $local);
-    }
-
-}
-
-if (!function_exists('cdnurl'))
-{
-
-    /**
-     * 获取上传资源的CDN的地址
-     * @param string $url 资源相对地址
-     * @return string
-     */
-    function cdnurl($url)
-    {
-        return preg_match("/^https?:\/\/(.*)/i", $url) ? $url : think\Config::get('upload.cdnurl') . $url;
-    }
-
-}
-
-
-if (!function_exists('is_really_writable'))
-{
-
-    /**
-     * 判断文件或文件夹是否可写
-     * @param	string $file 文件或目录
-     * @return	bool
-     */
-    function is_really_writable($file)
-    {
-        if (DIRECTORY_SEPARATOR === '/')
-        {
-            return is_writable($file);
-        }
-        if (is_dir($file))
-        {
-            $file = rtrim($file, '/') . '/' . md5(mt_rand());
-            if (($fp = @fopen($file, 'ab')) === FALSE)
-            {
-                return FALSE;
-            }
-            fclose($fp);
-            @chmod($file, 0777);
-            @unlink($file);
-            return TRUE;
-        }
-        elseif (!is_file($file) OR ( $fp = @fopen($file, 'ab')) === FALSE)
-        {
-            return FALSE;
-        }
-        fclose($fp);
-        return TRUE;
-    }
-
-}
-
-if (!function_exists('rmdirs'))
-{
-
-    /**
-     * 删除文件夹
-     * @param string $dirname 目录
-     * @param bool $withself 是否删除自身
-     * @return boolean
-     */
-    function rmdirs($dirname, $withself = true)
-    {
-        if (!is_dir($dirname))
-            return false;
-        $files = new RecursiveIteratorIterator(
-                new RecursiveDirectoryIterator($dirname, RecursiveDirectoryIterator::SKIP_DOTS), RecursiveIteratorIterator::CHILD_FIRST
-        );
-
-        foreach ($files as $fileinfo)
-        {
-            $todo = ($fileinfo->isDir() ? 'rmdir' : 'unlink');
-            $todo($fileinfo->getRealPath());
-        }
-        if ($withself)
-        {
-            @rmdir($dirname);
-        }
-        return true;
-    }
-
-}
-
-if (!function_exists('copydirs'))
-{
-
-    /**
-     * 复制文件夹
-     * @param string $source 源文件夹
-     * @param string $dest 目标文件夹
-     */
-    function copydirs($source, $dest)
-    {
-        if (!is_dir($dest))
-        {
-            mkdir($dest, 0755);
-        }
-        foreach (
-        $iterator = new RecursiveIteratorIterator(
-        new RecursiveDirectoryIterator($source, RecursiveDirectoryIterator::SKIP_DOTS), RecursiveIteratorIterator::SELF_FIRST) as $item
-        )
-        {
-            if ($item->isDir())
-            {
-                $sontDir = $dest . DS . $iterator->getSubPathName();
-                if (!is_dir($sontDir))
-                {
-                    mkdir($sontDir);
-                }
-            }
-            else
-            {
-                copy($item, $dest . DS . $iterator->getSubPathName());
-            }
-        }
-    }
-
-}
-
-if (!function_exists('mb_ucfirst'))
-{
-
-    function mb_ucfirst($string)
-    {
-        return mb_strtoupper(mb_substr($string, 0, 1)) . mb_strtolower(mb_substr($string, 1));
-    }
-
-}
-
-
-if (!function_exists('addtion'))
-{
-
-    /**
-     * 附加关联字段数据
-     * @param array $items 数据列表
-     * @param mixed $fields 渲染的来源字段
-     * @return array
-     */
-    function addtion($items, $fields)
-    {
-        if (!$items || !$fields)
-            return $items;
-        $fieldsArr = [];
-        if (!is_array($fields))
-        {
-            $arr = explode(',', $fields);
-            foreach ($arr as $k => $v)
-            {
-                $fieldsArr[$v] = ['field' => $v];
-            }
-        }
-        else
-        {
-            foreach ($fields as $k => $v)
-            {
-                if (is_array($v))
-                {
-                    $v['field'] = isset($v['field']) ? $v['field'] : $k;
-                }
-                else
-                {
-                    $v = ['field' => $v];
-                }
-                $fieldsArr[$v['field']] = $v;
-            }
-        }
-        foreach ($fieldsArr as $k => &$v)
-        {
-            $v = is_array($v) ? $v : ['field' => $v];
-            $v['display'] = isset($v['display']) ? $v['display'] : str_replace(['_ids', '_id'], ['_names', '_name'], $v['field']);
-            $v['primary'] = isset($v['primary']) ? $v['primary'] : '';
-            $v['column'] = isset($v['column']) ? $v['column'] : 'name';
-            $v['model'] = isset($v['model']) ? $v['model'] : '';
-            $v['table'] = isset($v['table']) ? $v['table'] : '';
-            $v['name'] = isset($v['name']) ? $v['name'] : str_replace(['_ids', '_id'], '', $v['field']);
-        }
-        unset($v);
-        $ids = [];
-        $fields = array_keys($fieldsArr);
-        foreach ($items as $k => $v)
-        {
-            foreach ($fields as $m => $n)
-            {
-                if (isset($v[$n]))
-                {
-                    $ids[$n] = array_merge(isset($ids[$n]) && is_array($ids[$n]) ? $ids[$n] : [], explode(',', $v[$n]));
-                }
-            }
-        }
-        $result = [];
-        foreach ($fieldsArr as $k => $v)
-        {
-            if ($v['model'])
-            {
-                $model = new $v['model'];
-            }
-            else
-            {
-                $model = $v['name'] ? \think\Db::name($v['name']) : \think\Db::table($v['table']);
-            }
-            $primary = $v['primary'] ? $v['primary'] : $model->getPk();
-            $result[$v['field']] = $model->where($primary, 'in', $ids[$v['field']])->column("{$primary},{$v['column']}");
-        }
-
-        foreach ($items as $k => &$v)
-        {
-            foreach ($fields as $m => $n)
-            {
-                if (isset($v[$n]))
-                {
-                    $curr = array_flip(explode(',', $v[$n]));
-
-                    $v[$fieldsArr[$n]['display']] = implode(',', array_intersect_key($result[$n], $curr));
-                }
-            }
-        }
-        return $items;
-    }
-
-}
+<?php
+
+// 公共助手函数
+
+if (!function_exists('__'))
+{
+
+    /**
+     * 获取语言变量值
+     * @param string    $name 语言变量名
+     * @param array     $vars 动态变量值
+     * @param string    $lang 语言
+     * @return mixed
+     */
+    function __($name, $vars = [], $lang = '')
+    {
+        if (is_numeric($name) || !$name)
+            return $name;
+        if (!is_array($vars))
+        {
+            $vars = func_get_args();
+            array_shift($vars);
+            $lang = '';
+        }
+        return think\Lang::get($name, $vars, $lang);
+    }
+
+}
+
+if (!function_exists('format_bytes'))
+{
+
+    /**
+     * 将字节转换为可读文本
+     * @param int $size 大小
+     * @param string $delimiter 分隔符
+     * @return string
+     */
+    function format_bytes($size, $delimiter = '')
+    {
+        $units = array('B', 'KB', 'MB', 'GB', 'TB', 'PB');
+        for ($i = 0; $size >= 1024 && $i < 6; $i++)
+            $size /= 1024;
+        return round($size, 2) . $delimiter . $units[$i];
+    }
+
+}
+
+if (!function_exists('datetime'))
+{
+
+    /**
+     * 将时间戳转换为日期时间
+     * @param int $time 时间戳
+     * @param string $format 日期时间格式
+     * @return string
+     */
+    function datetime($time, $format = 'Y-m-d H:i:s')
+    {
+        $time = is_numeric($time) ? $time : strtotime($time);
+        return date($format, $time);
+    }
+
+}
+
+if (!function_exists('human_date'))
+{
+
+    /**
+     * 获取语义化时间
+     * @param int $time 时间
+     * @param int $local 本地时间
+     * @return string
+     */
+    function human_date($time, $local = null)
+    {
+        return \fast\Date::human($time, $local);
+    }
+
+}
+
+if (!function_exists('cdnurl'))
+{
+
+    /**
+     * 获取上传资源的CDN的地址
+     * @param string $url 资源相对地址
+     * @return string
+     */
+    function cdnurl($url)
+    {
+        return preg_match("/^https?:\/\/(.*)/i", $url) ? $url : think\Config::get('upload.cdnurl') . $url;
+    }
+
+}
+
+
+if (!function_exists('is_really_writable'))
+{
+
+    /**
+     * 判断文件或文件夹是否可写
+     * @param	string $file 文件或目录
+     * @return	bool
+     */
+    function is_really_writable($file)
+    {
+        if (DIRECTORY_SEPARATOR === '/')
+        {
+            return is_writable($file);
+        }
+        if (is_dir($file))
+        {
+            $file = rtrim($file, '/') . '/' . md5(mt_rand());
+            if (($fp = @fopen($file, 'ab')) === FALSE)
+            {
+                return FALSE;
+            }
+            fclose($fp);
+            @chmod($file, 0777);
+            @unlink($file);
+            return TRUE;
+        }
+        elseif (!is_file($file) OR ( $fp = @fopen($file, 'ab')) === FALSE)
+        {
+            return FALSE;
+        }
+        fclose($fp);
+        return TRUE;
+    }
+
+}
+
+if (!function_exists('rmdirs'))
+{
+
+    /**
+     * 删除文件夹
+     * @param string $dirname 目录
+     * @param bool $withself 是否删除自身
+     * @return boolean
+     */
+    function rmdirs($dirname, $withself = true)
+    {
+        if (!is_dir($dirname))
+            return false;
+        $files = new RecursiveIteratorIterator(
+                new RecursiveDirectoryIterator($dirname, RecursiveDirectoryIterator::SKIP_DOTS), RecursiveIteratorIterator::CHILD_FIRST
+        );
+
+        foreach ($files as $fileinfo)
+        {
+            $todo = ($fileinfo->isDir() ? 'rmdir' : 'unlink');
+            $todo($fileinfo->getRealPath());
+        }
+        if ($withself)
+        {
+            @rmdir($dirname);
+        }
+        return true;
+    }
+
+}
+
+if (!function_exists('copydirs'))
+{
+
+    /**
+     * 复制文件夹
+     * @param string $source 源文件夹
+     * @param string $dest 目标文件夹
+     */
+    function copydirs($source, $dest)
+    {
+        if (!is_dir($dest))
+        {
+            mkdir($dest, 0755);
+        }
+        foreach (
+        $iterator = new RecursiveIteratorIterator(
+        new RecursiveDirectoryIterator($source, RecursiveDirectoryIterator::SKIP_DOTS), RecursiveIteratorIterator::SELF_FIRST) as $item
+        )
+        {
+            if ($item->isDir())
+            {
+                $sontDir = $dest . DS . $iterator->getSubPathName();
+                if (!is_dir($sontDir))
+                {
+                    mkdir($sontDir);
+                }
+            }
+            else
+            {
+                copy($item, $dest . DS . $iterator->getSubPathName());
+            }
+        }
+    }
+
+}
+
+if (!function_exists('mb_ucfirst'))
+{
+
+    function mb_ucfirst($string)
+    {
+        return mb_strtoupper(mb_substr($string, 0, 1)) . mb_strtolower(mb_substr($string, 1));
+    }
+
+}
+
+
+if (!function_exists('addtion'))
+{
+
+    /**
+     * 附加关联字段数据
+     * @param array $items 数据列表
+     * @param mixed $fields 渲染的来源字段
+     * @return array
+     */
+    function addtion($items, $fields)
+    {
+        if (!$items || !$fields)
+            return $items;
+        $fieldsArr = [];
+        if (!is_array($fields))
+        {
+            $arr = explode(',', $fields);
+            foreach ($arr as $k => $v)
+            {
+                $fieldsArr[$v] = ['field' => $v];
+            }
+        }
+        else
+        {
+            foreach ($fields as $k => $v)
+            {
+                if (is_array($v))
+                {
+                    $v['field'] = isset($v['field']) ? $v['field'] : $k;
+                }
+                else
+                {
+                    $v = ['field' => $v];
+                }
+                $fieldsArr[$v['field']] = $v;
+            }
+        }
+        foreach ($fieldsArr as $k => &$v)
+        {
+            $v = is_array($v) ? $v : ['field' => $v];
+            $v['display'] = isset($v['display']) ? $v['display'] : str_replace(['_ids', '_id'], ['_names', '_name'], $v['field']);
+            $v['primary'] = isset($v['primary']) ? $v['primary'] : '';
+            $v['column'] = isset($v['column']) ? $v['column'] : 'name';
+            $v['model'] = isset($v['model']) ? $v['model'] : '';
+            $v['table'] = isset($v['table']) ? $v['table'] : '';
+            $v['name'] = isset($v['name']) ? $v['name'] : str_replace(['_ids', '_id'], '', $v['field']);
+        }
+        unset($v);
+        $ids = [];
+        $fields = array_keys($fieldsArr);
+        foreach ($items as $k => $v)
+        {
+            foreach ($fields as $m => $n)
+            {
+                if (isset($v[$n]))
+                {
+                    $ids[$n] = array_merge(isset($ids[$n]) && is_array($ids[$n]) ? $ids[$n] : [], explode(',', $v[$n]));
+                }
+            }
+        }
+        $result = [];
+        foreach ($fieldsArr as $k => $v)
+        {
+            if ($v['model'])
+            {
+                $model = new $v['model'];
+            }
+            else
+            {
+                $model = $v['name'] ? \think\Db::name($v['name']) : \think\Db::table($v['table']);
+            }
+            $primary = $v['primary'] ? $v['primary'] : $model->getPk();
+            $result[$v['field']] = $model->where($primary, 'in', $ids[$v['field']])->column("{$primary},{$v['column']}");
+        }
+
+        foreach ($items as $k => &$v)
+        {
+            foreach ($fields as $m => $n)
+            {
+                if (isset($v[$n]))
+                {
+                    $curr = array_flip(explode(',', $v[$n]));
+
+                    $v[$fieldsArr[$n]['display']] = implode(',', array_intersect_key($result[$n], $curr));
+                }
+            }
+        }
+        return $items;
+    }
+
+}

+ 15 - 15
application/common/controller/Api.php

@@ -1,15 +1,15 @@
-<?php
-
-namespace app\common\controller;
-
-use think\controller\Rest;
-
-class Api extends Rest
-{
-
-    public function _initialize()
-    {
-
-    }
-
-}
+<?php
+
+namespace app\common\controller;
+
+use think\controller\Rest;
+
+class Api extends Rest
+{
+
+    public function _initialize()
+    {
+
+    }
+
+}

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

@@ -1,461 +1,461 @@
-<?php
-
-namespace app\common\controller;
-
-use app\admin\library\Auth;
-use think\Config;
-use think\Controller;
-use think\Hook;
-use think\Lang;
-use think\Session;
-
-/**
- * 后台控制器基类
- */
-class Backend extends Controller
-{
-
-    /**
-     * 无需登录的方法,同时也就不需要鉴权了
-     * @var array
-     */
-    protected $noNeedLogin = [];
-
-    /**
-     * 无需鉴权的方法,但需要登录
-     * @var array
-     */
-    protected $noNeedRight = [];
-
-    /**
-     * 布局模板
-     * @var string
-     */
-    protected $layout = 'default';
-
-    /**
-     * 权限控制类
-     * @var Auth
-     */
-    protected $auth = null;
-
-    /**
-     * 快速搜索时执行查找的字段
-     */
-    protected $searchFields = 'id';
-
-    /**
-     * 是否是关联查询
-     */
-    protected $relationSearch = false;
-
-    /**
-     * 是否开启数据限制
-     * 支持auth/personal
-     * 表示按权限判断/仅限个人 
-     * 默认为禁用,若启用请务必保证表中存在admin_id字段
-     */
-    protected $dataLimit = false;
-
-    /**
-     * 数据限制字段
-     */
-    protected $dataLimitField = 'admin_id';
-
-    /**
-     * 是否开启Validate验证
-     */
-    protected $modelValidate = false;
-
-    /**
-     * 是否开启模型场景验证
-     */
-    protected $modelSceneValidate = false;
-
-    /**
-     * Multi方法可批量修改的字段
-     */
-    protected $multiFields = 'status';
-
-    /**
-     * 引入后台控制器的traits
-     */
-    use \app\admin\library\traits\Backend;
-
-    public function _initialize()
-    {
-        $modulename = $this->request->module();
-        $controllername = strtolower($this->request->controller());
-        $actionname = strtolower($this->request->action());
-
-        $path = str_replace('.', '/', $controllername) . '/' . $actionname;
-
-        // 定义是否Addtabs请求
-        !defined('IS_ADDTABS') && define('IS_ADDTABS', input("addtabs") ? TRUE : FALSE);
-
-        // 定义是否Dialog请求
-        !defined('IS_DIALOG') && define('IS_DIALOG', input("dialog") ? TRUE : FALSE);
-
-        // 定义是否AJAX请求
-        !defined('IS_AJAX') && define('IS_AJAX', $this->request->isAjax());
-
-        $this->auth = Auth::instance();
-
-        // 设置当前请求的URI
-        $this->auth->setRequestUri($path);
-        // 检测是否需要验证登录
-        if (!$this->auth->match($this->noNeedLogin))
-        {
-            //检测是否登录
-            if (!$this->auth->isLogin())
-            {
-                Hook::listen('admin_nologin', $this);
-                $url = Session::get('referer');
-                $url = $url ? $url : $this->request->url();
-                $this->error(__('Please login first'), url('index/login', ['url' => $url]));
-            }
-            // 判断是否需要验证权限
-            if (!$this->auth->match($this->noNeedRight))
-            {
-                // 判断控制器和方法判断是否有对应权限
-                if (!$this->auth->check($path))
-                {
-                    Hook::listen('admin_nopermission', $this);
-                    $this->error(__('You have no permission'), '');
-                }
-            }
-        }
-
-        // 非选项卡时重定向
-        if (!$this->request->isPost() && !IS_AJAX && !IS_ADDTABS && !IS_DIALOG && input("ref") == 'addtabs')
-        {
-            $url = preg_replace_callback("/([\?|&]+)ref=addtabs(&?)/i", function($matches) {
-                return $matches[2] == '&' ? $matches[1] : '';
-            }, $this->request->url());
-            $this->redirect('index/index', [], 302, ['referer' => $url]);
-            exit;
-        }
-
-        // 设置面包屑导航数据
-        $breadcrumb = $this->auth->getBreadCrumb($path);
-        array_pop($breadcrumb);
-        $this->view->breadcrumb = $breadcrumb;
-
-        // 如果有使用模板布局
-        if ($this->layout)
-        {
-            $this->view->engine->layout('layout/' . $this->layout);
-        }
-
-        // 语言检测
-        $lang = strip_tags(Lang::detect());
-
-        $site = Config::get("site");
-
-        $upload = \app\common\model\Config::upload();
-
-        // 上传信息配置后
-        Hook::listen("upload_config_init", $upload);
-
-        // 配置信息
-        $config = [
-            'site'           => array_intersect_key($site, array_flip(['name', 'cdnurl', 'version', 'timezone', 'languages'])),
-            'upload'         => $upload,
-            'modulename'     => $modulename,
-            'controllername' => $controllername,
-            'actionname'     => $actionname,
-            'jsname'         => 'backend/' . str_replace('.', '/', $controllername),
-            'moduleurl'      => rtrim(url("/{$modulename}", '', false), '/'),
-            'language'       => $lang,
-            'fastadmin'      => Config::get('fastadmin'),
-            'referer'        => Session::get("referer")
-        ];
-            
-        Config::set('upload', array_merge(Config::get('upload'), $upload));
-        
-        // 配置信息后
-        Hook::listen("config_init", $config);
-        //加载当前控制器语言包
-        $this->loadlang($controllername);
-        //渲染站点配置
-        $this->assign('site', $site);
-        //渲染配置信息
-        $this->assign('config', $config);
-        //渲染权限对象
-        $this->assign('auth', $this->auth);
-        //渲染管理员对象
-        $this->assign('admin', Session::get('admin'));
-    }
-
-    /**
-     * 加载语言文件
-     * @param string $name
-     */
-    protected function loadlang($name)
-    {
-        Lang::load(APP_PATH . $this->request->module() . '/lang/' . Lang::detect() . '/' . str_replace('.', '/', $name) . '.php');
-    }
-
-    /**
-     * 渲染配置信息
-     * @param mixed $name 键名或数组
-     * @param mixed $value 值 
-     */
-    protected function assignconfig($name, $value = '')
-    {
-        $this->view->config = array_merge($this->view->config ? $this->view->config : [], is_array($name) ? $name : [$name => $value]);
-    }
-
-    /**
-     * 生成查询所需要的条件,排序方式
-     * @param mixed $searchfields 快速查询的字段
-     * @param boolean $relationSearch 是否关联查询
-     * @return array
-     */
-    protected function buildparams($searchfields = null, $relationSearch = null)
-    {
-        $searchfields = is_null($searchfields) ? $this->searchFields : $searchfields;
-        $relationSearch = is_null($relationSearch) ? $this->relationSearch : $relationSearch;
-        $search = $this->request->get("search", '');
-        $filter = $this->request->get("filter", '');
-        $op = $this->request->get("op", '', 'trim');
-        $sort = $this->request->get("sort", "id");
-        $order = $this->request->get("order", "DESC");
-        $offset = $this->request->get("offset", 0);
-        $limit = $this->request->get("limit", 0);
-        $filter = json_decode($filter, TRUE);
-        $op = json_decode($op, TRUE);
-        $filter = $filter ? $filter : [];
-        $where = [];
-        $tableName = '';
-        if ($relationSearch)
-        {
-            if (!empty($this->model))
-            {
-                $class = get_class($this->model);
-                $name = basename(str_replace('\\', '/', $class));
-                $tableName = $this->model->getQuery()->getTable($name) . ".";
-            }
-            $sort = stripos($sort, ".") === false ? $tableName . $sort : $sort;
-        }
-        $adminIds = $this->getDataLimitAdminIds();
-        if (is_array($adminIds))
-        {
-            $where[] = [$this->dataLimitField, 'in', $adminIds];
-        }
-        if ($search)
-        {
-            $searcharr = is_array($searchfields) ? $searchfields : explode(',', $searchfields);
-            foreach ($searcharr as $k => &$v)
-            {
-                $v = stripos($v, ".") === false ? $tableName . $v : $v;
-            }
-            unset($v);
-            $where[] = [implode("|", $searcharr), "LIKE", "%{$search}%"];
-        }
-        foreach ($filter as $k => $v)
-        {
-            $sym = isset($op[$k]) ? $op[$k] : '=';
-            if (stripos($k, ".") === false)
-            {
-                $k = $tableName . $k;
-            }
-            $sym = strtoupper(isset($op[$k]) ? $op[$k] : $sym);
-            switch ($sym)
-            {
-                case '=':
-                case '!=':
-                    $where[] = [$k, $sym, (string) $v];
-                    break;
-                case 'LIKE':
-                case 'NOT LIKE':
-                case 'LIKE %...%':
-                case 'NOT LIKE %...%':
-                    $where[] = [$k, trim(str_replace('%...%', '', $sym)), "%{$v}%"];
-                    break;
-                case '>':
-                case '>=':
-                case '<':
-                case '<=':
-                    $where[] = [$k, $sym, intval($v)];
-                    break;
-                case 'IN':
-                case 'IN(...)':
-                case 'NOT IN':
-                case 'NOT IN(...)':
-                    $where[] = [$k, str_replace('(...)', '', $sym), explode(',', $v)];
-                    break;
-                case 'BETWEEN':
-                case 'NOT BETWEEN':
-                    $arr = array_slice(explode(',', $v), 0, 2);
-                    if (stripos($v, ',') === false || !array_filter($arr))
-                        continue;
-                    //当出现一边为空时改变操作符
-                    if ($arr[0] === '')
-                    {
-                        $sym = $sym == 'BETWEEN' ? '<=' : '>';
-                        $arr = $arr[1];
-                    }
-                    else if ($arr[1] === '')
-                    {
-                        $sym = $sym == 'BETWEEN' ? '>=' : '<';
-                        $arr = $arr[0];
-                    }
-                    $where[] = [$k, $sym, $arr];
-                    break;
-                case 'RANGE':
-                case 'NOT RANGE':
-                    $v = str_replace(' - ', ',', $v);
-                    $arr = array_slice(explode(',', $v), 0, 2);
-                    if (stripos($v, ',') === false || !array_filter($arr))
-                        continue;
-                    //当出现一边为空时改变操作符
-                    if ($arr[0] === '')
-                    {
-                        $sym = $sym == 'RANGE' ? '<=' : '>';
-                        $arr = $arr[1];
-                    }
-                    else if ($arr[1] === '')
-                    {
-                        $sym = $sym == 'RANGE' ? '>=' : '<';
-                        $arr = $arr[0];
-                    }
-                    $where[] = [$k, str_replace('RANGE', 'BETWEEN', $sym) . ' time', $arr];
-                    break;
-                case 'LIKE':
-                case 'LIKE %...%':
-                    $where[] = [$k, 'LIKE', "%{$v}%"];
-                    break;
-                case 'NULL':
-                case 'IS NULL':
-                case 'NOT NULL':
-                case 'IS NOT NULL':
-                    $where[] = [$k, strtolower(str_replace('IS ', '', $sym))];
-                    break;
-                default:
-                    break;
-            }
-        }
-        $where = function($query) use ($where) {
-            foreach ($where as $k => $v)
-            {
-                if (is_array($v))
-                {
-                    call_user_func_array([$query, 'where'], $v);
-                }
-                else
-                {
-                    $query->where($v);
-                }
-            }
-        };
-        return [$where, $sort, $order, $offset, $limit];
-    }
-
-    /**
-     * 获取数据限制的管理员ID
-     * 禁用数据限制时返回的是null
-     * @return mixed
-     */
-    protected function getDataLimitAdminIds()
-    {
-        if (!$this->dataLimit)
-        {
-            return null;
-        }
-        $adminIds = [];
-        if (in_array($this->dataLimit, ['auth', 'personal']))
-        {
-            $adminIds = $this->dataLimit == 'auth' ? $this->auth->getChildrenAdminIds(true) : [$this->auth->id];
-        }
-        return $adminIds;
-    }
-
-    /**
-     * Selectpage的实现方法
-     * 
-     * 当前方法只是一个比较通用的搜索匹配,请按需重载此方法来编写自己的搜索逻辑,$where按自己的需求写即可
-     * 这里示例了所有的参数,所以比较复杂,实现上自己实现只需简单的几行即可
-     * 
-     */
-    protected function selectpage()
-    {
-        //设置过滤方法
-        $this->request->filter(['strip_tags', 'htmlspecialchars']);
-
-        //搜索关键词,客户端输入以空格分开,这里接收为数组
-        $word = (array) $this->request->request("q_word/a");
-        //当前页
-        $page = $this->request->request("page");
-        //分页大小
-        $pagesize = $this->request->request("per_page");
-        //搜索条件
-        $andor = $this->request->request("and_or");
-        //排序方式
-        $orderby = (array) $this->request->request("order_by/a");
-        //显示的字段
-        $field = $this->request->request("field");
-        //主键
-        $primarykey = $this->request->request("pkey_name");
-        //主键值
-        $primaryvalue = $this->request->request("pkey_value");
-        //搜索字段
-        $searchfield = (array) $this->request->request("search_field/a");
-        //自定义搜索条件
-        $custom = (array) $this->request->request("custom/a");
-        $order = [];
-        foreach ($orderby as $k => $v)
-        {
-            $order[$v[0]] = $v[1];
-        }
-        $field = $field ? $field : 'name';
-
-        //如果有primaryvalue,说明当前是初始化传值
-        if ($primaryvalue !== null)
-        {
-            $where = [$primarykey => ['in', $primaryvalue]];
-        }
-        else
-        {
-            $where = function($query) use($word, $andor, $field, $searchfield, $custom) {
-                foreach ($word as $k => $v)
-                {
-                    foreach ($searchfield as $m => $n)
-                    {
-                        $query->where($n, "like", "%{$v}%", $andor);
-                    }
-                }
-                if ($custom && is_array($custom))
-                {
-                    foreach ($custom as $k => $v)
-                    {
-                        $query->where($k, '=', $v);
-                    }
-                }
-            };
-        }
-        $adminIds = $this->getDataLimitAdminIds();
-        if (is_array($adminIds))
-        {
-            $this->model->where($this->dataLimitField, 'in', $adminIds);
-        }
-        $list = [];
-        $total = $this->model->where($where)->count();
-        if ($total > 0)
-        {
-            if (is_array($adminIds))
-            {
-                $this->model->where($this->dataLimitField, 'in', $adminIds);
-            }
-            $list = $this->model->where($where)
-                    ->order($order)
-                    ->page($page, $pagesize)
-                    ->field("{$primarykey},{$field}")
-                    ->field("password,salt", true)
-                    ->select();
-        }
-        //这里一定要返回有list这个字段,total是可选的,如果total<=list的数量,则会隐藏分页按钮
-        return json(['list' => $list, 'total' => $total]);
-    }
-
-}
+<?php
+
+namespace app\common\controller;
+
+use app\admin\library\Auth;
+use think\Config;
+use think\Controller;
+use think\Hook;
+use think\Lang;
+use think\Session;
+
+/**
+ * 后台控制器基类
+ */
+class Backend extends Controller
+{
+
+    /**
+     * 无需登录的方法,同时也就不需要鉴权了
+     * @var array
+     */
+    protected $noNeedLogin = [];
+
+    /**
+     * 无需鉴权的方法,但需要登录
+     * @var array
+     */
+    protected $noNeedRight = [];
+
+    /**
+     * 布局模板
+     * @var string
+     */
+    protected $layout = 'default';
+
+    /**
+     * 权限控制类
+     * @var Auth
+     */
+    protected $auth = null;
+
+    /**
+     * 快速搜索时执行查找的字段
+     */
+    protected $searchFields = 'id';
+
+    /**
+     * 是否是关联查询
+     */
+    protected $relationSearch = false;
+
+    /**
+     * 是否开启数据限制
+     * 支持auth/personal
+     * 表示按权限判断/仅限个人 
+     * 默认为禁用,若启用请务必保证表中存在admin_id字段
+     */
+    protected $dataLimit = false;
+
+    /**
+     * 数据限制字段
+     */
+    protected $dataLimitField = 'admin_id';
+
+    /**
+     * 是否开启Validate验证
+     */
+    protected $modelValidate = false;
+
+    /**
+     * 是否开启模型场景验证
+     */
+    protected $modelSceneValidate = false;
+
+    /**
+     * Multi方法可批量修改的字段
+     */
+    protected $multiFields = 'status';
+
+    /**
+     * 引入后台控制器的traits
+     */
+    use \app\admin\library\traits\Backend;
+
+    public function _initialize()
+    {
+        $modulename = $this->request->module();
+        $controllername = strtolower($this->request->controller());
+        $actionname = strtolower($this->request->action());
+
+        $path = str_replace('.', '/', $controllername) . '/' . $actionname;
+
+        // 定义是否Addtabs请求
+        !defined('IS_ADDTABS') && define('IS_ADDTABS', input("addtabs") ? TRUE : FALSE);
+
+        // 定义是否Dialog请求
+        !defined('IS_DIALOG') && define('IS_DIALOG', input("dialog") ? TRUE : FALSE);
+
+        // 定义是否AJAX请求
+        !defined('IS_AJAX') && define('IS_AJAX', $this->request->isAjax());
+
+        $this->auth = Auth::instance();
+
+        // 设置当前请求的URI
+        $this->auth->setRequestUri($path);
+        // 检测是否需要验证登录
+        if (!$this->auth->match($this->noNeedLogin))
+        {
+            //检测是否登录
+            if (!$this->auth->isLogin())
+            {
+                Hook::listen('admin_nologin', $this);
+                $url = Session::get('referer');
+                $url = $url ? $url : $this->request->url();
+                $this->error(__('Please login first'), url('index/login', ['url' => $url]));
+            }
+            // 判断是否需要验证权限
+            if (!$this->auth->match($this->noNeedRight))
+            {
+                // 判断控制器和方法判断是否有对应权限
+                if (!$this->auth->check($path))
+                {
+                    Hook::listen('admin_nopermission', $this);
+                    $this->error(__('You have no permission'), '');
+                }
+            }
+        }
+
+        // 非选项卡时重定向
+        if (!$this->request->isPost() && !IS_AJAX && !IS_ADDTABS && !IS_DIALOG && input("ref") == 'addtabs')
+        {
+            $url = preg_replace_callback("/([\?|&]+)ref=addtabs(&?)/i", function($matches) {
+                return $matches[2] == '&' ? $matches[1] : '';
+            }, $this->request->url());
+            $this->redirect('index/index', [], 302, ['referer' => $url]);
+            exit;
+        }
+
+        // 设置面包屑导航数据
+        $breadcrumb = $this->auth->getBreadCrumb($path);
+        array_pop($breadcrumb);
+        $this->view->breadcrumb = $breadcrumb;
+
+        // 如果有使用模板布局
+        if ($this->layout)
+        {
+            $this->view->engine->layout('layout/' . $this->layout);
+        }
+
+        // 语言检测
+        $lang = strip_tags(Lang::detect());
+
+        $site = Config::get("site");
+
+        $upload = \app\common\model\Config::upload();
+
+        // 上传信息配置后
+        Hook::listen("upload_config_init", $upload);
+
+        // 配置信息
+        $config = [
+            'site'           => array_intersect_key($site, array_flip(['name', 'cdnurl', 'version', 'timezone', 'languages'])),
+            'upload'         => $upload,
+            'modulename'     => $modulename,
+            'controllername' => $controllername,
+            'actionname'     => $actionname,
+            'jsname'         => 'backend/' . str_replace('.', '/', $controllername),
+            'moduleurl'      => rtrim(url("/{$modulename}", '', false), '/'),
+            'language'       => $lang,
+            'fastadmin'      => Config::get('fastadmin'),
+            'referer'        => Session::get("referer")
+        ];
+            
+        Config::set('upload', array_merge(Config::get('upload'), $upload));
+        
+        // 配置信息后
+        Hook::listen("config_init", $config);
+        //加载当前控制器语言包
+        $this->loadlang($controllername);
+        //渲染站点配置
+        $this->assign('site', $site);
+        //渲染配置信息
+        $this->assign('config', $config);
+        //渲染权限对象
+        $this->assign('auth', $this->auth);
+        //渲染管理员对象
+        $this->assign('admin', Session::get('admin'));
+    }
+
+    /**
+     * 加载语言文件
+     * @param string $name
+     */
+    protected function loadlang($name)
+    {
+        Lang::load(APP_PATH . $this->request->module() . '/lang/' . Lang::detect() . '/' . str_replace('.', '/', $name) . '.php');
+    }
+
+    /**
+     * 渲染配置信息
+     * @param mixed $name 键名或数组
+     * @param mixed $value 值 
+     */
+    protected function assignconfig($name, $value = '')
+    {
+        $this->view->config = array_merge($this->view->config ? $this->view->config : [], is_array($name) ? $name : [$name => $value]);
+    }
+
+    /**
+     * 生成查询所需要的条件,排序方式
+     * @param mixed $searchfields 快速查询的字段
+     * @param boolean $relationSearch 是否关联查询
+     * @return array
+     */
+    protected function buildparams($searchfields = null, $relationSearch = null)
+    {
+        $searchfields = is_null($searchfields) ? $this->searchFields : $searchfields;
+        $relationSearch = is_null($relationSearch) ? $this->relationSearch : $relationSearch;
+        $search = $this->request->get("search", '');
+        $filter = $this->request->get("filter", '');
+        $op = $this->request->get("op", '', 'trim');
+        $sort = $this->request->get("sort", "id");
+        $order = $this->request->get("order", "DESC");
+        $offset = $this->request->get("offset", 0);
+        $limit = $this->request->get("limit", 0);
+        $filter = json_decode($filter, TRUE);
+        $op = json_decode($op, TRUE);
+        $filter = $filter ? $filter : [];
+        $where = [];
+        $tableName = '';
+        if ($relationSearch)
+        {
+            if (!empty($this->model))
+            {
+                $class = get_class($this->model);
+                $name = basename(str_replace('\\', '/', $class));
+                $tableName = $this->model->getQuery()->getTable($name) . ".";
+            }
+            $sort = stripos($sort, ".") === false ? $tableName . $sort : $sort;
+        }
+        $adminIds = $this->getDataLimitAdminIds();
+        if (is_array($adminIds))
+        {
+            $where[] = [$this->dataLimitField, 'in', $adminIds];
+        }
+        if ($search)
+        {
+            $searcharr = is_array($searchfields) ? $searchfields : explode(',', $searchfields);
+            foreach ($searcharr as $k => &$v)
+            {
+                $v = stripos($v, ".") === false ? $tableName . $v : $v;
+            }
+            unset($v);
+            $where[] = [implode("|", $searcharr), "LIKE", "%{$search}%"];
+        }
+        foreach ($filter as $k => $v)
+        {
+            $sym = isset($op[$k]) ? $op[$k] : '=';
+            if (stripos($k, ".") === false)
+            {
+                $k = $tableName . $k;
+            }
+            $sym = strtoupper(isset($op[$k]) ? $op[$k] : $sym);
+            switch ($sym)
+            {
+                case '=':
+                case '!=':
+                    $where[] = [$k, $sym, (string) $v];
+                    break;
+                case 'LIKE':
+                case 'NOT LIKE':
+                case 'LIKE %...%':
+                case 'NOT LIKE %...%':
+                    $where[] = [$k, trim(str_replace('%...%', '', $sym)), "%{$v}%"];
+                    break;
+                case '>':
+                case '>=':
+                case '<':
+                case '<=':
+                    $where[] = [$k, $sym, intval($v)];
+                    break;
+                case 'IN':
+                case 'IN(...)':
+                case 'NOT IN':
+                case 'NOT IN(...)':
+                    $where[] = [$k, str_replace('(...)', '', $sym), explode(',', $v)];
+                    break;
+                case 'BETWEEN':
+                case 'NOT BETWEEN':
+                    $arr = array_slice(explode(',', $v), 0, 2);
+                    if (stripos($v, ',') === false || !array_filter($arr))
+                        continue;
+                    //当出现一边为空时改变操作符
+                    if ($arr[0] === '')
+                    {
+                        $sym = $sym == 'BETWEEN' ? '<=' : '>';
+                        $arr = $arr[1];
+                    }
+                    else if ($arr[1] === '')
+                    {
+                        $sym = $sym == 'BETWEEN' ? '>=' : '<';
+                        $arr = $arr[0];
+                    }
+                    $where[] = [$k, $sym, $arr];
+                    break;
+                case 'RANGE':
+                case 'NOT RANGE':
+                    $v = str_replace(' - ', ',', $v);
+                    $arr = array_slice(explode(',', $v), 0, 2);
+                    if (stripos($v, ',') === false || !array_filter($arr))
+                        continue;
+                    //当出现一边为空时改变操作符
+                    if ($arr[0] === '')
+                    {
+                        $sym = $sym == 'RANGE' ? '<=' : '>';
+                        $arr = $arr[1];
+                    }
+                    else if ($arr[1] === '')
+                    {
+                        $sym = $sym == 'RANGE' ? '>=' : '<';
+                        $arr = $arr[0];
+                    }
+                    $where[] = [$k, str_replace('RANGE', 'BETWEEN', $sym) . ' time', $arr];
+                    break;
+                case 'LIKE':
+                case 'LIKE %...%':
+                    $where[] = [$k, 'LIKE', "%{$v}%"];
+                    break;
+                case 'NULL':
+                case 'IS NULL':
+                case 'NOT NULL':
+                case 'IS NOT NULL':
+                    $where[] = [$k, strtolower(str_replace('IS ', '', $sym))];
+                    break;
+                default:
+                    break;
+            }
+        }
+        $where = function($query) use ($where) {
+            foreach ($where as $k => $v)
+            {
+                if (is_array($v))
+                {
+                    call_user_func_array([$query, 'where'], $v);
+                }
+                else
+                {
+                    $query->where($v);
+                }
+            }
+        };
+        return [$where, $sort, $order, $offset, $limit];
+    }
+
+    /**
+     * 获取数据限制的管理员ID
+     * 禁用数据限制时返回的是null
+     * @return mixed
+     */
+    protected function getDataLimitAdminIds()
+    {
+        if (!$this->dataLimit)
+        {
+            return null;
+        }
+        $adminIds = [];
+        if (in_array($this->dataLimit, ['auth', 'personal']))
+        {
+            $adminIds = $this->dataLimit == 'auth' ? $this->auth->getChildrenAdminIds(true) : [$this->auth->id];
+        }
+        return $adminIds;
+    }
+
+    /**
+     * Selectpage的实现方法
+     * 
+     * 当前方法只是一个比较通用的搜索匹配,请按需重载此方法来编写自己的搜索逻辑,$where按自己的需求写即可
+     * 这里示例了所有的参数,所以比较复杂,实现上自己实现只需简单的几行即可
+     * 
+     */
+    protected function selectpage()
+    {
+        //设置过滤方法
+        $this->request->filter(['strip_tags', 'htmlspecialchars']);
+
+        //搜索关键词,客户端输入以空格分开,这里接收为数组
+        $word = (array) $this->request->request("q_word/a");
+        //当前页
+        $page = $this->request->request("page");
+        //分页大小
+        $pagesize = $this->request->request("per_page");
+        //搜索条件
+        $andor = $this->request->request("and_or");
+        //排序方式
+        $orderby = (array) $this->request->request("order_by/a");
+        //显示的字段
+        $field = $this->request->request("field");
+        //主键
+        $primarykey = $this->request->request("pkey_name");
+        //主键值
+        $primaryvalue = $this->request->request("pkey_value");
+        //搜索字段
+        $searchfield = (array) $this->request->request("search_field/a");
+        //自定义搜索条件
+        $custom = (array) $this->request->request("custom/a");
+        $order = [];
+        foreach ($orderby as $k => $v)
+        {
+            $order[$v[0]] = $v[1];
+        }
+        $field = $field ? $field : 'name';
+
+        //如果有primaryvalue,说明当前是初始化传值
+        if ($primaryvalue !== null)
+        {
+            $where = [$primarykey => ['in', $primaryvalue]];
+        }
+        else
+        {
+            $where = function($query) use($word, $andor, $field, $searchfield, $custom) {
+                foreach ($word as $k => $v)
+                {
+                    foreach ($searchfield as $m => $n)
+                    {
+                        $query->where($n, "like", "%{$v}%", $andor);
+                    }
+                }
+                if ($custom && is_array($custom))
+                {
+                    foreach ($custom as $k => $v)
+                    {
+                        $query->where($k, '=', $v);
+                    }
+                }
+            };
+        }
+        $adminIds = $this->getDataLimitAdminIds();
+        if (is_array($adminIds))
+        {
+            $this->model->where($this->dataLimitField, 'in', $adminIds);
+        }
+        $list = [];
+        $total = $this->model->where($where)->count();
+        if ($total > 0)
+        {
+            if (is_array($adminIds))
+            {
+                $this->model->where($this->dataLimitField, 'in', $adminIds);
+            }
+            $list = $this->model->where($where)
+                    ->order($order)
+                    ->page($page, $pagesize)
+                    ->field("{$primarykey},{$field}")
+                    ->field("password,salt", true)
+                    ->select();
+        }
+        //这里一定要返回有list这个字段,total是可选的,如果total<=list的数量,则会隐藏分页按钮
+        return json(['list' => $list, 'total' => $total]);
+    }
+
+}

+ 83 - 83
application/common/controller/Frontend.php

@@ -1,83 +1,83 @@
-<?php
-
-namespace app\common\controller;
-
-use think\Config;
-use think\Controller;
-use think\Hook;
-use think\Lang;
-
-class Frontend extends Controller
-{
-
-    /**
-     * 布局模板
-     * @var string
-     */
-    protected $layout = '';
-
-    public function _initialize()
-    {
-        //移除HTML标签
-        $this->request->filter('strip_tags');
-        $modulename = $this->request->module();
-        $controllername = strtolower($this->request->controller());
-        $actionname = strtolower($this->request->action());
-
-        // 如果有使用模板布局
-        if ($this->layout)
-        {
-            $this->view->engine->layout('layout/' . $this->layout);
-        }
-
-        // 语言检测
-        $lang = strip_tags(Lang::detect());
-
-        $site = Config::get("site");
-
-        $upload = \app\common\model\Config::upload();
-
-        // 上传信息配置后
-        Hook::listen("upload_config_init", $upload);
-        
-        // 配置信息
-        $config = [
-            'site'           => array_intersect_key($site, array_flip(['name', 'cdnurl', 'version', 'timezone', 'languages'])),
-            'upload'         => $upload,
-            'modulename'     => $modulename,
-            'controllername' => $controllername,
-            'actionname'     => $actionname,
-            'jsname'         => 'frontend/' . str_replace('.', '/', $controllername),
-            'moduleurl'      => rtrim(url("/{$modulename}", '', false), '/'),
-            'language'       => $lang
-        ];
-        
-        Config::set('upload', array_merge(Config::get('upload'), $upload));
-        
-        // 配置信息后
-        Hook::listen("config_init", $config);
-        $this->loadlang($controllername);
-        $this->assign('site', $site);
-        $this->assign('config', $config);
-    }
-
-    /**
-     * 加载语言文件
-     * @param string $name
-     */
-    protected function loadlang($name)
-    {
-        Lang::load(APP_PATH . $this->request->module() . '/lang/' . Lang::detect() . '/' . str_replace('.', '/', $name) . '.php');
-    }
-    
-    /**
-     * 渲染配置信息
-     * @param mixed $name 键名或数组
-     * @param mixed $value 值 
-     */
-    protected function assignconfig($name, $value = '')
-    {
-        $this->view->config = array_merge($this->view->config ? $this->view->config : [], is_array($name) ? $name : [$name => $value]);
-    }
-
-}
+<?php
+
+namespace app\common\controller;
+
+use think\Config;
+use think\Controller;
+use think\Hook;
+use think\Lang;
+
+class Frontend extends Controller
+{
+
+    /**
+     * 布局模板
+     * @var string
+     */
+    protected $layout = '';
+
+    public function _initialize()
+    {
+        //移除HTML标签
+        $this->request->filter('strip_tags');
+        $modulename = $this->request->module();
+        $controllername = strtolower($this->request->controller());
+        $actionname = strtolower($this->request->action());
+
+        // 如果有使用模板布局
+        if ($this->layout)
+        {
+            $this->view->engine->layout('layout/' . $this->layout);
+        }
+
+        // 语言检测
+        $lang = strip_tags(Lang::detect());
+
+        $site = Config::get("site");
+
+        $upload = \app\common\model\Config::upload();
+
+        // 上传信息配置后
+        Hook::listen("upload_config_init", $upload);
+        
+        // 配置信息
+        $config = [
+            'site'           => array_intersect_key($site, array_flip(['name', 'cdnurl', 'version', 'timezone', 'languages'])),
+            'upload'         => $upload,
+            'modulename'     => $modulename,
+            'controllername' => $controllername,
+            'actionname'     => $actionname,
+            'jsname'         => 'frontend/' . str_replace('.', '/', $controllername),
+            'moduleurl'      => rtrim(url("/{$modulename}", '', false), '/'),
+            'language'       => $lang
+        ];
+        
+        Config::set('upload', array_merge(Config::get('upload'), $upload));
+        
+        // 配置信息后
+        Hook::listen("config_init", $config);
+        $this->loadlang($controllername);
+        $this->assign('site', $site);
+        $this->assign('config', $config);
+    }
+
+    /**
+     * 加载语言文件
+     * @param string $name
+     */
+    protected function loadlang($name)
+    {
+        Lang::load(APP_PATH . $this->request->module() . '/lang/' . Lang::detect() . '/' . str_replace('.', '/', $name) . '.php');
+    }
+    
+    /**
+     * 渲染配置信息
+     * @param mixed $name 键名或数组
+     * @param mixed $value 值 
+     */
+    protected function assignconfig($name, $value = '')
+    {
+        $this->view->config = array_merge($this->view->config ? $this->view->config : [], is_array($name) ? $name : [$name => $value]);
+    }
+
+}

+ 19 - 19
application/common/model/Attachment.php

@@ -1,19 +1,19 @@
-<?php
-
-namespace app\common\model;
-
-use think\Model;
-
-class Attachment extends Model
-{
-
-    // 开启自动写入时间戳字段
-    protected $autoWriteTimestamp = 'int';
-    // 定义时间戳字段名
-    protected $createTime = 'createtime';
-    protected $updateTime = 'updatetime';
-    // 定义字段类型
-    protected $type = [
-    ];
-
-}
+<?php
+
+namespace app\common\model;
+
+use think\Model;
+
+class Attachment extends Model
+{
+
+    // 开启自动写入时间戳字段
+    protected $autoWriteTimestamp = 'int';
+    // 定义时间戳字段名
+    protected $createTime = 'createtime';
+    protected $updateTime = 'updatetime';
+    // 定义字段类型
+    protected $type = [
+    ];
+
+}

+ 161 - 161
application/common/model/Config.php

@@ -1,161 +1,161 @@
-<?php
-
-namespace app\common\model;
-
-use think\Model;
-
-class Config extends Model
-{
-
-    // 表名,不含前缀
-    protected $name = 'config';
-    // 自动写入时间戳字段
-    protected $autoWriteTimestamp = false;
-    // 定义时间戳字段名
-    protected $createTime = false;
-    protected $updateTime = false;
-    // 追加属性
-    protected $append = [
-    ];
-
-    /**
-     * 读取配置类型
-     * @return array
-     */
-    public static function getTypeList()
-    {
-        $typeList = [
-            'string'   => __('String'),
-            'text'     => __('Text'),
-            'editor'   => __('Editor'),
-            'number'   => __('Number'),
-            'date'     => __('Date'),
-            'time'     => __('Time'),
-            'datetime' => __('Datetime'),
-            'select'   => __('Select'),
-            'selects'  => __('Selects'),
-            'image'    => __('Image'),
-            'images'   => __('Images'),
-            'file'     => __('File'),
-            'files'    => __('Files'),
-            'checkbox' => __('Checkbox'),
-            'radio'    => __('Radio'),
-            'array'    => __('Array'),
-            'custom'   => __('Custom'),
-        ];
-        return $typeList;
-    }
-
-    public static function getRegexList()
-    {
-        $regexList = [
-            'required' => '必选',
-            'digits'   => '数字',
-            'letters'  => '字母',
-            'date'     => '日期',
-            'time'     => '时间',
-            'email'    => '邮箱',
-            'url'      => '网址',
-            'qq'       => 'QQ号',
-            'IDcard'   => '身份证',
-            'tel'      => '座机电话',
-            'mobile'   => '手机号',
-            'zipcode'  => '邮编',
-            'chinese'  => '中文',
-            'username' => '用户名',
-            'password' => '密码'
-        ];
-        return $regexList;
-    }
-
-    /**
-     * 读取分类分组列表
-     * @return array
-     */
-    public static function getGroupList()
-    {
-        $groupList = config('site.configgroup');
-        foreach ($groupList as $k => &$v)
-        {
-            $v = __($v);
-        }
-        return $groupList;
-    }
-
-    public static function getArrayData($data)
-    {
-        $fieldarr = $valuearr = [];
-        $field = isset($data['field']) ? $data['field'] : [];
-        $value = isset($data['value']) ? $data['value'] : [];
-        foreach ($field as $m => $n)
-        {
-            if ($n != '')
-            {
-                $fieldarr[] = $field[$m];
-                $valuearr[] = $value[$m];
-            }
-        }
-        return $fieldarr ? array_combine($fieldarr, $valuearr) : [];
-    }
-
-    /**
-     * 将字符串解析成键值数组
-     * @param string $text
-     * @return array
-     */
-    public static function decode($text, $split = "\r\n")
-    {
-        $content = explode($split, $text);
-        $arr = [];
-        foreach ($content as $k => $v)
-        {
-            if (stripos($v, "|") !== false)
-            {
-                $item = explode('|', $v);
-                $arr[$item[0]] = $item[1];
-            }
-        }
-        return $arr;
-    }
-
-    /**
-     * 将键值数组转换为字符串
-     * @param array $array
-     * @return string
-     */
-    public static function encode($array, $split = "\r\n")
-    {
-        $content = '';
-        if ($array && is_array($array))
-        {
-            $arr = [];
-            foreach ($array as $k => $v)
-            {
-                $arr[] = "{$k}|{$v}";
-            }
-            $content = implode($split, $arr);
-        }
-        return $content;
-    }
-
-    /**
-     * 本地上传配置信息
-     * @return array
-     */
-    public static function upload()
-    {
-        $uploadcfg = config('upload');
-
-        $upload = [
-            'cdnurl'    => $uploadcfg['cdnurl'],
-            'uploadurl' => $uploadcfg['uploadurl'],
-            'bucket'    => 'local',
-            'maxsize'   => $uploadcfg['maxsize'],
-            'mimetype'  => $uploadcfg['mimetype'],
-            'multipart' => [],
-            'multiple'  => $uploadcfg['multiple'],
-        ];
-        return $upload;
-    }
-
-}
+<?php
+
+namespace app\common\model;
+
+use think\Model;
+
+class Config extends Model
+{
+
+    // 表名,不含前缀
+    protected $name = 'config';
+    // 自动写入时间戳字段
+    protected $autoWriteTimestamp = false;
+    // 定义时间戳字段名
+    protected $createTime = false;
+    protected $updateTime = false;
+    // 追加属性
+    protected $append = [
+    ];
+
+    /**
+     * 读取配置类型
+     * @return array
+     */
+    public static function getTypeList()
+    {
+        $typeList = [
+            'string'   => __('String'),
+            'text'     => __('Text'),
+            'editor'   => __('Editor'),
+            'number'   => __('Number'),
+            'date'     => __('Date'),
+            'time'     => __('Time'),
+            'datetime' => __('Datetime'),
+            'select'   => __('Select'),
+            'selects'  => __('Selects'),
+            'image'    => __('Image'),
+            'images'   => __('Images'),
+            'file'     => __('File'),
+            'files'    => __('Files'),
+            'checkbox' => __('Checkbox'),
+            'radio'    => __('Radio'),
+            'array'    => __('Array'),
+            'custom'   => __('Custom'),
+        ];
+        return $typeList;
+    }
+
+    public static function getRegexList()
+    {
+        $regexList = [
+            'required' => '必选',
+            'digits'   => '数字',
+            'letters'  => '字母',
+            'date'     => '日期',
+            'time'     => '时间',
+            'email'    => '邮箱',
+            'url'      => '网址',
+            'qq'       => 'QQ号',
+            'IDcard'   => '身份证',
+            'tel'      => '座机电话',
+            'mobile'   => '手机号',
+            'zipcode'  => '邮编',
+            'chinese'  => '中文',
+            'username' => '用户名',
+            'password' => '密码'
+        ];
+        return $regexList;
+    }
+
+    /**
+     * 读取分类分组列表
+     * @return array
+     */
+    public static function getGroupList()
+    {
+        $groupList = config('site.configgroup');
+        foreach ($groupList as $k => &$v)
+        {
+            $v = __($v);
+        }
+        return $groupList;
+    }
+
+    public static function getArrayData($data)
+    {
+        $fieldarr = $valuearr = [];
+        $field = isset($data['field']) ? $data['field'] : [];
+        $value = isset($data['value']) ? $data['value'] : [];
+        foreach ($field as $m => $n)
+        {
+            if ($n != '')
+            {
+                $fieldarr[] = $field[$m];
+                $valuearr[] = $value[$m];
+            }
+        }
+        return $fieldarr ? array_combine($fieldarr, $valuearr) : [];
+    }
+
+    /**
+     * 将字符串解析成键值数组
+     * @param string $text
+     * @return array
+     */
+    public static function decode($text, $split = "\r\n")
+    {
+        $content = explode($split, $text);
+        $arr = [];
+        foreach ($content as $k => $v)
+        {
+            if (stripos($v, "|") !== false)
+            {
+                $item = explode('|', $v);
+                $arr[$item[0]] = $item[1];
+            }
+        }
+        return $arr;
+    }
+
+    /**
+     * 将键值数组转换为字符串
+     * @param array $array
+     * @return string
+     */
+    public static function encode($array, $split = "\r\n")
+    {
+        $content = '';
+        if ($array && is_array($array))
+        {
+            $arr = [];
+            foreach ($array as $k => $v)
+            {
+                $arr[] = "{$k}|{$v}";
+            }
+            $content = implode($split, $arr);
+        }
+        return $content;
+    }
+
+    /**
+     * 本地上传配置信息
+     * @return array
+     */
+    public static function upload()
+    {
+        $uploadcfg = config('upload');
+
+        $upload = [
+            'cdnurl'    => $uploadcfg['cdnurl'],
+            'uploadurl' => $uploadcfg['uploadurl'],
+            'bucket'    => 'local',
+            'maxsize'   => $uploadcfg['maxsize'],
+            'mimetype'  => $uploadcfg['mimetype'],
+            'multipart' => [],
+            'multiple'  => $uploadcfg['multiple'],
+        ];
+        return $upload;
+    }
+
+}

+ 249 - 249
application/config.php

@@ -1,249 +1,249 @@
-<?php
-
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2006~2016 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: liu21st <liu21st@gmail.com>
-// +----------------------------------------------------------------------
-
-return [
-    // +----------------------------------------------------------------------
-    // | 应用设置
-    // +----------------------------------------------------------------------
-    // 应用命名空间
-    'app_namespace'          => 'app',
-    // 应用调试模式
-    'app_debug'              => true,
-    // 应用Trace
-    'app_trace'              => false,
-    // 应用模式状态
-    'app_status'             => '',
-    // 是否支持多模块
-    'app_multi_module'       => true,
-    // 入口自动绑定模块
-    'auto_bind_module'       => false,
-    // 注册的根命名空间
-    'root_namespace'         => [],
-    // 扩展函数文件
-    'extra_file_list'        => [THINK_PATH . 'helper' . EXT],
-    // 默认输出类型
-    'default_return_type'    => 'html',
-    // 默认AJAX 数据返回格式,可选json xml ...
-    'default_ajax_return'    => 'json',
-    // 默认JSONP格式返回的处理方法
-    'default_jsonp_handler'  => 'jsonpReturn',
-    // 默认JSONP处理方法
-    'var_jsonp_handler'      => 'callback',
-    // 默认时区
-    'default_timezone'       => 'PRC',
-    // 是否开启多语言
-    'lang_switch_on'         => true,
-    // 默认全局过滤方法 用逗号分隔多个
-    'default_filter'         => '',
-    // 默认语言
-    'default_lang'           => 'zh-cn',
-    // 应用类库后缀
-    'class_suffix'           => false,
-    // 控制器类后缀
-    'controller_suffix'      => false,
-    // +----------------------------------------------------------------------
-    // | 模块设置
-    // +----------------------------------------------------------------------
-    // 默认模块名
-    'default_module'         => 'index',
-    // 禁止访问模块
-    'deny_module_list'       => ['common'],
-    // 默认控制器名
-    'default_controller'     => 'Index',
-    // 默认操作名
-    'default_action'         => 'index',
-    // 默认验证器
-    'default_validate'       => '',
-    // 默认的空控制器名
-    'empty_controller'       => 'Error',
-    // 操作方法后缀
-    'action_suffix'          => '',
-    // 自动搜索控制器
-    'controller_auto_search' => true,
-    // +----------------------------------------------------------------------
-    // | URL设置
-    // +----------------------------------------------------------------------
-    // PATHINFO变量名 用于兼容模式
-    'var_pathinfo'           => 's',
-    // 兼容PATH_INFO获取
-    'pathinfo_fetch'         => ['ORIG_PATH_INFO', 'REDIRECT_PATH_INFO', 'REDIRECT_URL'],
-    // pathinfo分隔符
-    'pathinfo_depr'          => '/',
-    // URL伪静态后缀
-    'url_html_suffix'        => 'html',
-    // URL普通方式参数 用于自动生成
-    'url_common_param'       => false,
-    // URL参数方式 0 按名称成对解析 1 按顺序解析
-    'url_param_type'         => 0,
-    // 是否开启路由
-    'url_route_on'           => true,
-    // 路由使用完整匹配
-    'route_complete_match'   => false,
-    // 路由配置文件(支持配置多个)
-    'route_config_file'      => ['route'],
-    // 是否强制使用路由
-    'url_route_must'         => false,
-    // 域名部署
-    'url_domain_deploy'      => false,
-    // 域名根,如thinkphp.cn
-    'url_domain_root'        => '',
-    // 是否自动转换URL中的控制器和操作名
-    'url_convert'            => true,
-    // 默认的访问控制器层
-    'url_controller_layer'   => 'controller',
-    // 表单请求类型伪装变量
-    'var_method'             => '_method',
-    // 表单ajax伪装变量
-    'var_ajax'               => '_ajax',
-    // 表单pjax伪装变量
-    'var_pjax'               => '_pjax',
-    // 是否开启请求缓存 true自动缓存 支持设置请求缓存规则
-    'request_cache'          => false,
-    // 请求缓存有效期
-    'request_cache_expire'   => null,
-    // +----------------------------------------------------------------------
-    // | 模板设置
-    // +----------------------------------------------------------------------
-    'template'               => [
-        // 模板引擎类型 支持 php think 支持扩展
-        'type'         => 'Think',
-        // 模板路径
-        'view_path'    => '',
-        // 模板后缀
-        'view_suffix'  => 'html',
-        // 模板文件名分隔符
-        'view_depr'    => DS,
-        // 模板引擎普通标签开始标记
-        'tpl_begin'    => '{',
-        // 模板引擎普通标签结束标记
-        'tpl_end'      => '}',
-        // 标签库标签开始标记
-        'taglib_begin' => '{',
-        // 标签库标签结束标记
-        'taglib_end'   => '}',
-        'tpl_cache'    => true,
-    ],
-    // 视图输出字符串内容替换,留空则会自动进行计算
-    'view_replace_str'       => [
-        '__PUBLIC__' => '',
-        '__ROOT__'   => '',
-        '__CDN__'    => '',
-    ],
-    // 默认跳转页面对应的模板文件
-    'dispatch_success_tmpl'  => APP_PATH . 'common' . DS . 'view' . DS . 'tpl' . DS . 'dispatch_jump.tpl',
-    'dispatch_error_tmpl'    => APP_PATH . 'common' . DS . 'view' . DS . 'tpl' . DS . 'dispatch_jump.tpl',
-    // +----------------------------------------------------------------------
-    // | 异常及错误设置
-    // +----------------------------------------------------------------------
-    // 异常页面的模板文件
-    'exception_tmpl'         => APP_PATH . 'common' . DS . 'view' . DS . 'tpl' . DS . 'think_exception.tpl',
-    // 错误显示信息,非调试模式有效
-    'error_message'          => '你所浏览的页面暂时无法访问',
-    // 显示错误信息
-    'show_error_msg'         => false,
-    // 异常处理handle类 留空使用 \think\exception\Handle
-    'exception_handle'       => '',
-    // +----------------------------------------------------------------------
-    // | 日志设置
-    // +----------------------------------------------------------------------
-    'log'                    => [
-        // 日志记录方式,内置 file socket 支持扩展
-        'type'  => 'File',
-        // 日志保存目录
-        'path'  => LOG_PATH,
-        // 日志记录级别
-        'level' => [],
-    ],
-    // +----------------------------------------------------------------------
-    // | Trace设置 开启 app_trace 后 有效
-    // +----------------------------------------------------------------------
-    'trace'                  => [
-        // 内置Html Console 支持扩展
-        'type' => 'Html',
-    ],
-    // +----------------------------------------------------------------------
-    // | 缓存设置
-    // +----------------------------------------------------------------------
-    'cache'                  => [
-        // 驱动方式
-        'type'   => 'File',
-        // 缓存保存目录
-        'path'   => CACHE_PATH,
-        // 缓存前缀
-        'prefix' => '',
-        // 缓存有效期 0表示永久缓存
-        'expire' => 0,
-    ],
-    // +----------------------------------------------------------------------
-    // | 会话设置
-    // +----------------------------------------------------------------------
-    'session'                => [
-        'id'             => '',
-        // SESSION_ID的提交变量,解决flash上传跨域
-        'var_session_id' => '',
-        // SESSION 前缀
-        'prefix'         => 'think',
-        // 驱动方式 支持redis memcache memcached
-        'type'           => '',
-        // 是否自动开启 SESSION
-        'auto_start'     => true,
-    ],
-    // +----------------------------------------------------------------------
-    // | Cookie设置
-    // +----------------------------------------------------------------------
-    'cookie'                 => [
-        // cookie 名称前缀
-        'prefix'    => '',
-        // cookie 保存时间
-        'expire'    => 0,
-        // cookie 保存路径
-        'path'      => '/',
-        // cookie 有效域名
-        'domain'    => '',
-        //  cookie 启用安全传输
-        'secure'    => false,
-        // httponly设置
-        'httponly'  => '',
-        // 是否使用 setcookie
-        'setcookie' => true,
-    ],
-    //分页配置
-    'paginate'               => [
-        'type'      => 'bootstrap',
-        'var_page'  => 'page',
-        'list_rows' => 15,
-    ],
-    //验证码配置
-    'captcha'                => [
-        // 验证码字符集合
-        'codeSet'  => '2345678abcdefhijkmnpqrstuvwxyzABCDEFGHJKLMNPQRTUVWXY',
-        // 验证码字体大小(px)
-        'fontSize' => 16,
-        // 是否画混淆曲线
-        'useCurve' => false,
-        //使用中文验证码
-        'useZh'    => false,
-        // 验证码图片高度
-        'imageH'   => 30,
-        // 验证码图片宽度
-        'imageW'   => 100,
-        // 验证码位数
-        'length'   => 4,
-        // 验证成功后是否重置
-        'reset'    => true
-    ],
-    //FastAdmin配置
-    'fastadmin'              => [
-        'version' => '1.0.0.20171026_beta',
-        'api_url' => 'http://api.fastadmin.net',
-    ],
-];
+<?php
+
+// +----------------------------------------------------------------------
+// | ThinkPHP [ WE CAN DO IT JUST THINK ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2006~2016 http://thinkphp.cn All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
+// +----------------------------------------------------------------------
+// | Author: liu21st <liu21st@gmail.com>
+// +----------------------------------------------------------------------
+
+return [
+    // +----------------------------------------------------------------------
+    // | 应用设置
+    // +----------------------------------------------------------------------
+    // 应用命名空间
+    'app_namespace'          => 'app',
+    // 应用调试模式
+    'app_debug'              => true,
+    // 应用Trace
+    'app_trace'              => false,
+    // 应用模式状态
+    'app_status'             => '',
+    // 是否支持多模块
+    'app_multi_module'       => true,
+    // 入口自动绑定模块
+    'auto_bind_module'       => false,
+    // 注册的根命名空间
+    'root_namespace'         => [],
+    // 扩展函数文件
+    'extra_file_list'        => [THINK_PATH . 'helper' . EXT],
+    // 默认输出类型
+    'default_return_type'    => 'html',
+    // 默认AJAX 数据返回格式,可选json xml ...
+    'default_ajax_return'    => 'json',
+    // 默认JSONP格式返回的处理方法
+    'default_jsonp_handler'  => 'jsonpReturn',
+    // 默认JSONP处理方法
+    'var_jsonp_handler'      => 'callback',
+    // 默认时区
+    'default_timezone'       => 'PRC',
+    // 是否开启多语言
+    'lang_switch_on'         => true,
+    // 默认全局过滤方法 用逗号分隔多个
+    'default_filter'         => '',
+    // 默认语言
+    'default_lang'           => 'zh-cn',
+    // 应用类库后缀
+    'class_suffix'           => false,
+    // 控制器类后缀
+    'controller_suffix'      => false,
+    // +----------------------------------------------------------------------
+    // | 模块设置
+    // +----------------------------------------------------------------------
+    // 默认模块名
+    'default_module'         => 'index',
+    // 禁止访问模块
+    'deny_module_list'       => ['common'],
+    // 默认控制器名
+    'default_controller'     => 'Index',
+    // 默认操作名
+    'default_action'         => 'index',
+    // 默认验证器
+    'default_validate'       => '',
+    // 默认的空控制器名
+    'empty_controller'       => 'Error',
+    // 操作方法后缀
+    'action_suffix'          => '',
+    // 自动搜索控制器
+    'controller_auto_search' => true,
+    // +----------------------------------------------------------------------
+    // | URL设置
+    // +----------------------------------------------------------------------
+    // PATHINFO变量名 用于兼容模式
+    'var_pathinfo'           => 's',
+    // 兼容PATH_INFO获取
+    'pathinfo_fetch'         => ['ORIG_PATH_INFO', 'REDIRECT_PATH_INFO', 'REDIRECT_URL'],
+    // pathinfo分隔符
+    'pathinfo_depr'          => '/',
+    // URL伪静态后缀
+    'url_html_suffix'        => 'html',
+    // URL普通方式参数 用于自动生成
+    'url_common_param'       => false,
+    // URL参数方式 0 按名称成对解析 1 按顺序解析
+    'url_param_type'         => 0,
+    // 是否开启路由
+    'url_route_on'           => true,
+    // 路由使用完整匹配
+    'route_complete_match'   => false,
+    // 路由配置文件(支持配置多个)
+    'route_config_file'      => ['route'],
+    // 是否强制使用路由
+    'url_route_must'         => false,
+    // 域名部署
+    'url_domain_deploy'      => false,
+    // 域名根,如thinkphp.cn
+    'url_domain_root'        => '',
+    // 是否自动转换URL中的控制器和操作名
+    'url_convert'            => true,
+    // 默认的访问控制器层
+    'url_controller_layer'   => 'controller',
+    // 表单请求类型伪装变量
+    'var_method'             => '_method',
+    // 表单ajax伪装变量
+    'var_ajax'               => '_ajax',
+    // 表单pjax伪装变量
+    'var_pjax'               => '_pjax',
+    // 是否开启请求缓存 true自动缓存 支持设置请求缓存规则
+    'request_cache'          => false,
+    // 请求缓存有效期
+    'request_cache_expire'   => null,
+    // +----------------------------------------------------------------------
+    // | 模板设置
+    // +----------------------------------------------------------------------
+    'template'               => [
+        // 模板引擎类型 支持 php think 支持扩展
+        'type'         => 'Think',
+        // 模板路径
+        'view_path'    => '',
+        // 模板后缀
+        'view_suffix'  => 'html',
+        // 模板文件名分隔符
+        'view_depr'    => DS,
+        // 模板引擎普通标签开始标记
+        'tpl_begin'    => '{',
+        // 模板引擎普通标签结束标记
+        'tpl_end'      => '}',
+        // 标签库标签开始标记
+        'taglib_begin' => '{',
+        // 标签库标签结束标记
+        'taglib_end'   => '}',
+        'tpl_cache'    => true,
+    ],
+    // 视图输出字符串内容替换,留空则会自动进行计算
+    'view_replace_str'       => [
+        '__PUBLIC__' => '',
+        '__ROOT__'   => '',
+        '__CDN__'    => '',
+    ],
+    // 默认跳转页面对应的模板文件
+    'dispatch_success_tmpl'  => APP_PATH . 'common' . DS . 'view' . DS . 'tpl' . DS . 'dispatch_jump.tpl',
+    'dispatch_error_tmpl'    => APP_PATH . 'common' . DS . 'view' . DS . 'tpl' . DS . 'dispatch_jump.tpl',
+    // +----------------------------------------------------------------------
+    // | 异常及错误设置
+    // +----------------------------------------------------------------------
+    // 异常页面的模板文件
+    'exception_tmpl'         => APP_PATH . 'common' . DS . 'view' . DS . 'tpl' . DS . 'think_exception.tpl',
+    // 错误显示信息,非调试模式有效
+    'error_message'          => '你所浏览的页面暂时无法访问',
+    // 显示错误信息
+    'show_error_msg'         => false,
+    // 异常处理handle类 留空使用 \think\exception\Handle
+    'exception_handle'       => '',
+    // +----------------------------------------------------------------------
+    // | 日志设置
+    // +----------------------------------------------------------------------
+    'log'                    => [
+        // 日志记录方式,内置 file socket 支持扩展
+        'type'  => 'File',
+        // 日志保存目录
+        'path'  => LOG_PATH,
+        // 日志记录级别
+        'level' => [],
+    ],
+    // +----------------------------------------------------------------------
+    // | Trace设置 开启 app_trace 后 有效
+    // +----------------------------------------------------------------------
+    'trace'                  => [
+        // 内置Html Console 支持扩展
+        'type' => 'Html',
+    ],
+    // +----------------------------------------------------------------------
+    // | 缓存设置
+    // +----------------------------------------------------------------------
+    'cache'                  => [
+        // 驱动方式
+        'type'   => 'File',
+        // 缓存保存目录
+        'path'   => CACHE_PATH,
+        // 缓存前缀
+        'prefix' => '',
+        // 缓存有效期 0表示永久缓存
+        'expire' => 0,
+    ],
+    // +----------------------------------------------------------------------
+    // | 会话设置
+    // +----------------------------------------------------------------------
+    'session'                => [
+        'id'             => '',
+        // SESSION_ID的提交变量,解决flash上传跨域
+        'var_session_id' => '',
+        // SESSION 前缀
+        'prefix'         => 'think',
+        // 驱动方式 支持redis memcache memcached
+        'type'           => '',
+        // 是否自动开启 SESSION
+        'auto_start'     => true,
+    ],
+    // +----------------------------------------------------------------------
+    // | Cookie设置
+    // +----------------------------------------------------------------------
+    'cookie'                 => [
+        // cookie 名称前缀
+        'prefix'    => '',
+        // cookie 保存时间
+        'expire'    => 0,
+        // cookie 保存路径
+        'path'      => '/',
+        // cookie 有效域名
+        'domain'    => '',
+        //  cookie 启用安全传输
+        'secure'    => false,
+        // httponly设置
+        'httponly'  => '',
+        // 是否使用 setcookie
+        'setcookie' => true,
+    ],
+    //分页配置
+    'paginate'               => [
+        'type'      => 'bootstrap',
+        'var_page'  => 'page',
+        'list_rows' => 15,
+    ],
+    //验证码配置
+    'captcha'                => [
+        // 验证码字符集合
+        'codeSet'  => '2345678abcdefhijkmnpqrstuvwxyzABCDEFGHJKLMNPQRTUVWXY',
+        // 验证码字体大小(px)
+        'fontSize' => 16,
+        // 是否画混淆曲线
+        'useCurve' => false,
+        //使用中文验证码
+        'useZh'    => false,
+        // 验证码图片高度
+        'imageH'   => 30,
+        // 验证码图片宽度
+        'imageW'   => 100,
+        // 验证码位数
+        'length'   => 4,
+        // 验证成功后是否重置
+        'reset'    => true
+    ],
+    //FastAdmin配置
+    'fastadmin'              => [
+        'version' => '1.0.0.20171026_beta',
+        'api_url' => 'http://api.fastadmin.net',
+    ],
+];

+ 2 - 2
application/extra/addons.php

@@ -1,5 +1,5 @@
-<?php
-
+<?php
+
 return array (
   'autoload' => false,
   'hooks' => 

+ 115 - 115
application/index/controller/Ajax.php

@@ -1,115 +1,115 @@
-<?php
-
-namespace app\index\controller;
-
-use app\common\controller\Frontend;
-use fast\Random;
-use think\Config;
-use think\Lang;
-
-/**
- * Ajax异步请求接口
- * @internal
- */
-class Ajax extends Frontend
-{
-
-    protected $noNeedLogin = ['lang'];
-    protected $noNeedRight = ['*'];
-    protected $layout = '';
-
-    /**
-     * 加载语言包
-     */
-    public function lang()
-    {
-        header('Content-Type: application/javascript');
-        $callback = $this->request->get('callback');
-        $controllername = input("controllername");
-        $this->loadlang($controllername);
-        //强制输出JSON Object
-        $result = 'define(' . json_encode(Lang::get(), JSON_FORCE_OBJECT | JSON_UNESCAPED_UNICODE) . ');';
-        return $result;
-    }
-
-    /**
-     * 上传文件
-     */
-    public function upload()
-    {
-        $this->checkLogin();
-        $file = $this->request->file('file');
-
-        //判断是否已经存在附件
-        $sha1 = $file->hash();
-        $uploaded = model("attachment")->where('sha1', $sha1)->find();
-        if ($uploaded)
-        {
-            $this->success('', null, [
-                'url' => $uploaded['url']
-            ]);
-        }
-
-        $upload = Config::get('upload');
-
-        preg_match('/(\d+)(\w+)/', $upload['maxsize'], $matches);
-        $type = strtolower($matches[2]);
-        $typeDict = ['b' => 0, 'k' => 1, 'kb' => 1, 'm' => 2, 'mb' => 2, 'gb' => 3, 'g' => 3];
-        $size = (int) $upload['maxsize'] * pow(1024, isset($typeDict[$type]) ? $typeDict[$type] : 0);
-        $fileInfo = $file->getInfo();
-        $suffix = strtolower(pathinfo($fileInfo['name'], PATHINFO_EXTENSION));
-        $suffix = $suffix ? $suffix : 'file';
-        $replaceArr = [
-            '{year}'     => date("Y"),
-            '{mon}'      => date("m"),
-            '{day}'      => date("d"),
-            '{hour}'     => date("H"),
-            '{min}'      => date("i"),
-            '{sec}'      => date("s"),
-            '{random}'   => Random::alnum(16),
-            '{random32}' => Random::alnum(32),
-            '{filename}' => $suffix ? substr($fileInfo['name'], 0, strripos($fileInfo['name'], '.')) : $fileInfo['name'],
-            '{suffix}'   => $suffix,
-            '{.suffix}'  => $suffix ? '.' . $suffix : '',
-            '{filemd5}'  => md5_file($fileInfo['tmp_name']),
-        ];
-        $savekey = $upload['savekey'];
-        $savekey = str_replace(array_keys($replaceArr), array_values($replaceArr), $savekey);
-
-        $uploadDir = substr($savekey, 0, strripos($savekey, '/') + 1);
-        $fileName = substr($savekey, strripos($savekey, '/') + 1);
-        //
-        $splInfo = $file->validate(['size' => $size])->move(ROOT_PATH . '/public' . $uploadDir, $fileName);
-        if ($splInfo)
-        {
-            $imagewidth = $imageheight = 0;
-            if (in_array($suffix, ['gif', 'jpg', 'jpeg', 'bmp', 'png', 'swf']))
-            {
-                $imgInfo = getimagesize($splInfo->getPathname());
-                $imagewidth = isset($imgInfo[0]) ? $imgInfo[0] : $imagewidth;
-                $imageheight = isset($imgInfo[1]) ? $imgInfo[1] : $imageheight;
-            }
-            $params = array(
-                'filesize'    => $fileInfo['size'],
-                'imagewidth'  => $imagewidth,
-                'imageheight' => $imageheight,
-                'imagetype'   => $suffix,
-                'imageframes' => 0,
-                'mimetype'    => $fileInfo['type'],
-                'url'         => $uploadDir . $splInfo->getSaveName(),
-                'uploadtime'  => time(),
-                'sha1'        => $sha1,
-            );
-            model("attachment")->create(array_filter($params));
-            $this->success('', null, [
-                'url' => $uploadDir . $splInfo->getSaveName()
-            ]);
-        }
-        else
-        {
-            // 上传失败获取错误信息
-            $this->error($file->getError());
-        }
-    }
-
-}
+<?php
+
+namespace app\index\controller;
+
+use app\common\controller\Frontend;
+use fast\Random;
+use think\Config;
+use think\Lang;
+
+/**
+ * Ajax异步请求接口
+ * @internal
+ */
+class Ajax extends Frontend
+{
+
+    protected $noNeedLogin = ['lang'];
+    protected $noNeedRight = ['*'];
+    protected $layout = '';
+
+    /**
+     * 加载语言包
+     */
+    public function lang()
+    {
+        header('Content-Type: application/javascript');
+        $callback = $this->request->get('callback');
+        $controllername = input("controllername");
+        $this->loadlang($controllername);
+        //强制输出JSON Object
+        $result = 'define(' . json_encode(Lang::get(), JSON_FORCE_OBJECT | JSON_UNESCAPED_UNICODE) . ');';
+        return $result;
+    }
+
+    /**
+     * 上传文件
+     */
+    public function upload()
+    {
+        $this->checkLogin();
+        $file = $this->request->file('file');
+
+        //判断是否已经存在附件
+        $sha1 = $file->hash();
+        $uploaded = model("attachment")->where('sha1', $sha1)->find();
+        if ($uploaded)
+        {
+            $this->success('', null, [
+                'url' => $uploaded['url']
+            ]);
+        }
+
+        $upload = Config::get('upload');
+
+        preg_match('/(\d+)(\w+)/', $upload['maxsize'], $matches);
+        $type = strtolower($matches[2]);
+        $typeDict = ['b' => 0, 'k' => 1, 'kb' => 1, 'm' => 2, 'mb' => 2, 'gb' => 3, 'g' => 3];
+        $size = (int) $upload['maxsize'] * pow(1024, isset($typeDict[$type]) ? $typeDict[$type] : 0);
+        $fileInfo = $file->getInfo();
+        $suffix = strtolower(pathinfo($fileInfo['name'], PATHINFO_EXTENSION));
+        $suffix = $suffix ? $suffix : 'file';
+        $replaceArr = [
+            '{year}'     => date("Y"),
+            '{mon}'      => date("m"),
+            '{day}'      => date("d"),
+            '{hour}'     => date("H"),
+            '{min}'      => date("i"),
+            '{sec}'      => date("s"),
+            '{random}'   => Random::alnum(16),
+            '{random32}' => Random::alnum(32),
+            '{filename}' => $suffix ? substr($fileInfo['name'], 0, strripos($fileInfo['name'], '.')) : $fileInfo['name'],
+            '{suffix}'   => $suffix,
+            '{.suffix}'  => $suffix ? '.' . $suffix : '',
+            '{filemd5}'  => md5_file($fileInfo['tmp_name']),
+        ];
+        $savekey = $upload['savekey'];
+        $savekey = str_replace(array_keys($replaceArr), array_values($replaceArr), $savekey);
+
+        $uploadDir = substr($savekey, 0, strripos($savekey, '/') + 1);
+        $fileName = substr($savekey, strripos($savekey, '/') + 1);
+        //
+        $splInfo = $file->validate(['size' => $size])->move(ROOT_PATH . '/public' . $uploadDir, $fileName);
+        if ($splInfo)
+        {
+            $imagewidth = $imageheight = 0;
+            if (in_array($suffix, ['gif', 'jpg', 'jpeg', 'bmp', 'png', 'swf']))
+            {
+                $imgInfo = getimagesize($splInfo->getPathname());
+                $imagewidth = isset($imgInfo[0]) ? $imgInfo[0] : $imagewidth;
+                $imageheight = isset($imgInfo[1]) ? $imgInfo[1] : $imageheight;
+            }
+            $params = array(
+                'filesize'    => $fileInfo['size'],
+                'imagewidth'  => $imagewidth,
+                'imageheight' => $imageheight,
+                'imagetype'   => $suffix,
+                'imageframes' => 0,
+                'mimetype'    => $fileInfo['type'],
+                'url'         => $uploadDir . $splInfo->getSaveName(),
+                'uploadtime'  => time(),
+                'sha1'        => $sha1,
+            );
+            model("attachment")->create(array_filter($params));
+            $this->success('', null, [
+                'url' => $uploadDir . $splInfo->getSaveName()
+            ]);
+        }
+        else
+        {
+            // 上传失败获取错误信息
+            $this->error($file->getError());
+        }
+    }
+
+}

+ 28 - 28
application/index/controller/Index.php

@@ -1,28 +1,28 @@
-<?php
-
-namespace app\index\controller;
-
-use app\common\controller\Frontend;
-
-class Index extends Frontend
-{
-
-    protected $layout = '';
-
-    public function _initialize()
-    {
-        parent::_initialize();
-    }
-
-    public function index()
-    {
-        return $this->view->fetch();
-    }
-
-    public function news()
-    {
-        $newslist = [];
-        return jsonp(['newslist' => $newslist, 'new' => count($newslist), 'url' => 'http://www.fastadmin.net?ref=news']);
-    }
-
-}
+<?php
+
+namespace app\index\controller;
+
+use app\common\controller\Frontend;
+
+class Index extends Frontend
+{
+
+    protected $layout = '';
+
+    public function _initialize()
+    {
+        parent::_initialize();
+    }
+
+    public function index()
+    {
+        return $this->view->fetch();
+    }
+
+    public function news()
+    {
+        $newslist = [];
+        return jsonp(['newslist' => $newslist, 'new' => count($newslist), 'url' => 'http://www.fastadmin.net?ref=news']);
+    }
+
+}

+ 216 - 216
application/index/view/index/index.html

@@ -1,217 +1,217 @@
-<!DOCTYPE html>
-<html>
-
-    <head>
-
-        <meta charset="utf-8">
-        <meta http-equiv="X-UA-Compatible" content="IE=edge">
-        <meta name="viewport" content="width=device-width, initial-scale=1">
-        <meta name="description" content="">
-        <meta name="author" content="">
-
-        <title>FastAdmin - 基于ThinkPHP5和Bootstrap的极速后台开发框架</title>
-
-        <!-- Bootstrap Core CSS -->
-        <link href="//cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
-        <link href="__CDN__/assets/css/index.css" rel="stylesheet">
-
-        <!-- Plugin CSS -->
-        <link href="//cdn.bootcss.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">
-        <link href="//cdn.bootcss.com/simple-line-icons/2.4.1/css/simple-line-icons.min.css" rel="stylesheet">
-
-        <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
-        <!--[if lt IE 9]>
-            <script src="//cdn.bootcss.com/html5shiv/3.7.0/html5shiv.min.js"></script>
-            <script src="//cdn.bootcss.com/respond.js/1.4.2/respond.min.js"></script>
-        <![endif]-->
-    </head>
-
-    <body id="page-top">
-
-        <nav id="mainNav" class="navbar navbar-default navbar-fixed-top">
-            <div class="container">
-                <div class="navbar-header">
-                    <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar-collapse-menu">
-                        <span class="sr-only">Toggle navigation</span><i class="fa fa-bars"></i>
-                    </button>
-                    <a class="navbar-brand page-scroll" href="#page-top"><img src="__CDN__/assets/img/logo.png" style="width:200px;" alt=""></a>
-                </div>
-
-                <div class="collapse navbar-collapse" id="navbar-collapse-menu">
-                    <ul class="nav navbar-nav navbar-right">
-                        <li><a href="http://www.fastadmin.net">首页</a></li>
-                        <li><a href="http://www.fastadmin.net/store.html" title="FastAdmin插件市场">插件市场</a></li>
-                        <li><a href="http://www.fastadmin.net/service.html" title="FastAdmin增值服务">服务</a></li>
-                        <li><a href="http://www.fastadmin.net/download.html" title="FastAdmin下载">下载</a></li>
-                        <li><a href="http://www.fastadmin.net/demo.html" title="FastAdmin演示">演示</a></li>
-                        <li><a href="http://forum.fastadmin.net" title="FastAdmin交流社区">社区</a></li>
-                        <li><a href="http://doc.fastadmin.net" title="FastAdmin官方文档">文档</a></li>
-                        <li><a href="http://html.fastadmin.net" title="FastAdmin的HTML版">HTML版</a></li>
-                    </ul>
-                </div>
-                <!-- /.navbar-collapse -->
-            </div>
-            <!-- /.container-fluid -->
-        </nav>
-
-        <header>
-            <div class="container">
-                <div class="row">
-                    <div class="col-sm-12">
-                        <div class="header-content">
-                            <div class="header-content-inner">
-                                <h1>FastAdmin</h1>
-                                <h3>基于ThinkPHP5和Bootstrap的极速后台开发框架</h3>
-                                <a href="{:url('admin/index/login')}" class="btn btn-outline btn-xl page-scroll">登录后台</a>
-                            </div>
-                        </div>
-                    </div>
-                </div>
-            </div>
-        </header>
-
-        <section id="features" class="features">
-            <div class="container">
-                <div class="row">
-                    <div class="col-lg-12 text-center">
-                        <div class="section-heading">
-                            <h2>功能特性</h2>
-                        </div>
-                    </div>
-                </div>
-                <div class="row">
-                    <div class="col-md-12">
-                        <div class="container-fluid">
-                            <div class="row">
-                                <div class="col-md-4">
-                                    <div class="feature-item">
-                                        <i class="icon-user text-primary"></i>
-                                        <h3>权限管理</h3>
-                                        <p class="text-muted">基于完善的Auth权限控制管理、无限父子级权限分组、可自由分配子级权限、一个管理员可同时属于多个组别</p>
-                                    </div>
-                                </div>
-                                <div class="col-md-4">
-                                    <div class="feature-item">
-                                        <i class="icon-screen-smartphone text-primary"></i>
-                                        <h3>响应式开发</h3>
-                                        <p class="text-muted">基于Bootstrap和AdminLTE进行二次开发,手机、平板、PC均自动适配,无需要担心兼容性问题</p>
-                                    </div>
-                                </div>
-                                <div class="col-md-4">
-                                    <div class="feature-item">
-                                        <i class="icon-present text-primary"></i>
-                                        <h3>多语言</h3>
-                                        <p class="text-muted">不仅仅后台开发支持多语言,同时视图部分和JS部分仍然共享同一个语言包,语法相同且自动加载</p>
-                                    </div>
-                                </div>
-                                <div class="col-md-4">
-                                    <div class="feature-item">
-                                        <i class="icon-layers text-primary"></i>
-                                        <h3>模块化开发</h3>
-                                        <p class="text-muted">控制器、模型、视图、JS一一对应,使用RequireJS进行JS模块化管理,采用Bower进行前端包组件管理</p>
-                                    </div>
-                                </div>
-                                <div class="col-md-4">
-                                    <div class="feature-item">
-                                        <i class="icon-docs text-primary"></i>
-                                        <h3>CRUD</h3>
-                                        <p class="text-muted">控制台进行一键生成控制器、模型、视图和JS文件,同时可一键生成后台权限节点和菜单栏</p>
-                                    </div>
-                                </div>
-                                <div class="col-md-4">
-                                    <div class="feature-item">
-                                        <i class="icon-puzzle text-primary"></i>
-                                        <h3>自由可扩展</h3>
-                                        <p class="text-muted">FastAdmin提供强大的扩展中心,可直接在线安装和卸载插件,同时支持命令行一键操作</p>
-                                    </div>
-                                </div>
-                            </div>
-                        </div>
-                    </div>
-                </div>
-            </div>
-        </section>
-
-        <section class="cta">
-            <div class="cta-content">
-                <div class="container">
-                    <h2>不要犹豫<br>开始行动</h2>
-                    <a href="http://doc.fastadmin.net/docs/contributing.html" class="btn btn-outline btn-xl page-scroll">为FastAdmin贡献代码!</a>
-                </div>
-            </div>
-            <div class="overlay"></div>
-        </section>
-
-        <footer>
-            <div class="container">
-                <p>&copy; 2017 FastAdmin. All Rights Reserved.</p>
-                <ul class="list-inline">
-                    <li>
-                        <a href="https://gitee.com/karsonzhang/fastadmin">码云</a>
-                    </li>
-                    <li>
-                        <a href="https://github.com/karsonzhang/fastadmin">Github</a>
-                    </li>
-                    <li>
-                        <a href="http://shang.qq.com/wpa/qunwpa?idkey=46c326e570d0f97cfae1f8257ae82322192ec8841c79b2136446df0b3b62028c">QQ群</a>
-                    </li>
-                </ul>
-            </div>
-        </footer>
-
-        <!-- jQuery -->
-        <script src="//cdn.bootcss.com/jquery/2.1.4/jquery.min.js"></script>
-
-        <!-- Bootstrap Core JavaScript -->
-        <script src="//cdn.bootcss.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
-
-        <!-- Plugin JavaScript -->
-        <script src="//cdn.bootcss.com/jquery-easing/1.4.1/jquery.easing.min.js"></script>
-
-        <script>
-            $(function () {
-                $(window).on("scroll", function () {
-                    $("#mainNav").toggleClass("affix", $(window).height() - $(window).scrollTop() <= 50);
-                });
-
-
-                //发送版本统计信息
-                try {
-                    var installed = localStorage.getItem("installed");
-                    console.log(installed);
-                    if (!installed) {
-                        $.ajax({
-                            url: "{$Think.config.fastadmin.api_url}/statistics/installed",
-                            data: {
-                                version: "{:config('fastadmin.version')}",
-                                os: "{$Think.PHP_OS}",
-                                sapi: "{$Think.PHP_SAPI}",
-                                tpversion: "{$Think.THINK_VERSION}",
-                                phpversion: "{$Think.PHP_VERSION}",
-                                software: "{$Request.server.SERVER_SOFTWARE}",
-                                url: location.href,
-                            },
-                            dataType: 'jsonp',
-                        });
-                        localStorage.setItem("installed", true);
-                    }
-                } catch (e) {
-
-                }
-
-            });
-        </script>
-
-        <script>
-            var _hmt = _hmt || [];
-            (function () {
-                var hm = document.createElement("script");
-                hm.src = "https://hm.baidu.com/hm.js?f8d0a8c400404989e195270b0bbf060a";
-                var s = document.getElementsByTagName("script")[0];
-                s.parentNode.insertBefore(hm, s);
-            })();
-        </script>
-
-    </body>
-
+<!DOCTYPE html>
+<html>
+
+    <head>
+
+        <meta charset="utf-8">
+        <meta http-equiv="X-UA-Compatible" content="IE=edge">
+        <meta name="viewport" content="width=device-width, initial-scale=1">
+        <meta name="description" content="">
+        <meta name="author" content="">
+
+        <title>FastAdmin - 基于ThinkPHP5和Bootstrap的极速后台开发框架</title>
+
+        <!-- Bootstrap Core CSS -->
+        <link href="//cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
+        <link href="__CDN__/assets/css/index.css" rel="stylesheet">
+
+        <!-- Plugin CSS -->
+        <link href="//cdn.bootcss.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">
+        <link href="//cdn.bootcss.com/simple-line-icons/2.4.1/css/simple-line-icons.min.css" rel="stylesheet">
+
+        <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
+        <!--[if lt IE 9]>
+            <script src="//cdn.bootcss.com/html5shiv/3.7.0/html5shiv.min.js"></script>
+            <script src="//cdn.bootcss.com/respond.js/1.4.2/respond.min.js"></script>
+        <![endif]-->
+    </head>
+
+    <body id="page-top">
+
+        <nav id="mainNav" class="navbar navbar-default navbar-fixed-top">
+            <div class="container">
+                <div class="navbar-header">
+                    <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar-collapse-menu">
+                        <span class="sr-only">Toggle navigation</span><i class="fa fa-bars"></i>
+                    </button>
+                    <a class="navbar-brand page-scroll" href="#page-top"><img src="__CDN__/assets/img/logo.png" style="width:200px;" alt=""></a>
+                </div>
+
+                <div class="collapse navbar-collapse" id="navbar-collapse-menu">
+                    <ul class="nav navbar-nav navbar-right">
+                        <li><a href="http://www.fastadmin.net">首页</a></li>
+                        <li><a href="http://www.fastadmin.net/store.html" title="FastAdmin插件市场">插件市场</a></li>
+                        <li><a href="http://www.fastadmin.net/service.html" title="FastAdmin增值服务">服务</a></li>
+                        <li><a href="http://www.fastadmin.net/download.html" title="FastAdmin下载">下载</a></li>
+                        <li><a href="http://www.fastadmin.net/demo.html" title="FastAdmin演示">演示</a></li>
+                        <li><a href="http://forum.fastadmin.net" title="FastAdmin交流社区">社区</a></li>
+                        <li><a href="http://doc.fastadmin.net" title="FastAdmin官方文档">文档</a></li>
+                        <li><a href="http://html.fastadmin.net" title="FastAdmin的HTML版">HTML版</a></li>
+                    </ul>
+                </div>
+                <!-- /.navbar-collapse -->
+            </div>
+            <!-- /.container-fluid -->
+        </nav>
+
+        <header>
+            <div class="container">
+                <div class="row">
+                    <div class="col-sm-12">
+                        <div class="header-content">
+                            <div class="header-content-inner">
+                                <h1>FastAdmin</h1>
+                                <h3>基于ThinkPHP5和Bootstrap的极速后台开发框架</h3>
+                                <a href="{:url('admin/index/login')}" class="btn btn-outline btn-xl page-scroll">登录后台</a>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </header>
+
+        <section id="features" class="features">
+            <div class="container">
+                <div class="row">
+                    <div class="col-lg-12 text-center">
+                        <div class="section-heading">
+                            <h2>功能特性</h2>
+                        </div>
+                    </div>
+                </div>
+                <div class="row">
+                    <div class="col-md-12">
+                        <div class="container-fluid">
+                            <div class="row">
+                                <div class="col-md-4">
+                                    <div class="feature-item">
+                                        <i class="icon-user text-primary"></i>
+                                        <h3>权限管理</h3>
+                                        <p class="text-muted">基于完善的Auth权限控制管理、无限父子级权限分组、可自由分配子级权限、一个管理员可同时属于多个组别</p>
+                                    </div>
+                                </div>
+                                <div class="col-md-4">
+                                    <div class="feature-item">
+                                        <i class="icon-screen-smartphone text-primary"></i>
+                                        <h3>响应式开发</h3>
+                                        <p class="text-muted">基于Bootstrap和AdminLTE进行二次开发,手机、平板、PC均自动适配,无需要担心兼容性问题</p>
+                                    </div>
+                                </div>
+                                <div class="col-md-4">
+                                    <div class="feature-item">
+                                        <i class="icon-present text-primary"></i>
+                                        <h3>多语言</h3>
+                                        <p class="text-muted">不仅仅后台开发支持多语言,同时视图部分和JS部分仍然共享同一个语言包,语法相同且自动加载</p>
+                                    </div>
+                                </div>
+                                <div class="col-md-4">
+                                    <div class="feature-item">
+                                        <i class="icon-layers text-primary"></i>
+                                        <h3>模块化开发</h3>
+                                        <p class="text-muted">控制器、模型、视图、JS一一对应,使用RequireJS进行JS模块化管理,采用Bower进行前端包组件管理</p>
+                                    </div>
+                                </div>
+                                <div class="col-md-4">
+                                    <div class="feature-item">
+                                        <i class="icon-docs text-primary"></i>
+                                        <h3>CRUD</h3>
+                                        <p class="text-muted">控制台进行一键生成控制器、模型、视图和JS文件,同时可一键生成后台权限节点和菜单栏</p>
+                                    </div>
+                                </div>
+                                <div class="col-md-4">
+                                    <div class="feature-item">
+                                        <i class="icon-puzzle text-primary"></i>
+                                        <h3>自由可扩展</h3>
+                                        <p class="text-muted">FastAdmin提供强大的扩展中心,可直接在线安装和卸载插件,同时支持命令行一键操作</p>
+                                    </div>
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </section>
+
+        <section class="cta">
+            <div class="cta-content">
+                <div class="container">
+                    <h2>不要犹豫<br>开始行动</h2>
+                    <a href="http://doc.fastadmin.net/docs/contributing.html" class="btn btn-outline btn-xl page-scroll">为FastAdmin贡献代码!</a>
+                </div>
+            </div>
+            <div class="overlay"></div>
+        </section>
+
+        <footer>
+            <div class="container">
+                <p>&copy; 2017 FastAdmin. All Rights Reserved.</p>
+                <ul class="list-inline">
+                    <li>
+                        <a href="https://gitee.com/karsonzhang/fastadmin">码云</a>
+                    </li>
+                    <li>
+                        <a href="https://github.com/karsonzhang/fastadmin">Github</a>
+                    </li>
+                    <li>
+                        <a href="http://shang.qq.com/wpa/qunwpa?idkey=46c326e570d0f97cfae1f8257ae82322192ec8841c79b2136446df0b3b62028c">QQ群</a>
+                    </li>
+                </ul>
+            </div>
+        </footer>
+
+        <!-- jQuery -->
+        <script src="//cdn.bootcss.com/jquery/2.1.4/jquery.min.js"></script>
+
+        <!-- Bootstrap Core JavaScript -->
+        <script src="//cdn.bootcss.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
+
+        <!-- Plugin JavaScript -->
+        <script src="//cdn.bootcss.com/jquery-easing/1.4.1/jquery.easing.min.js"></script>
+
+        <script>
+            $(function () {
+                $(window).on("scroll", function () {
+                    $("#mainNav").toggleClass("affix", $(window).height() - $(window).scrollTop() <= 50);
+                });
+
+
+                //发送版本统计信息
+                try {
+                    var installed = localStorage.getItem("installed");
+                    console.log(installed);
+                    if (!installed) {
+                        $.ajax({
+                            url: "{$Think.config.fastadmin.api_url}/statistics/installed",
+                            data: {
+                                version: "{:config('fastadmin.version')}",
+                                os: "{$Think.PHP_OS}",
+                                sapi: "{$Think.PHP_SAPI}",
+                                tpversion: "{$Think.THINK_VERSION}",
+                                phpversion: "{$Think.PHP_VERSION}",
+                                software: "{$Request.server.SERVER_SOFTWARE}",
+                                url: location.href,
+                            },
+                            dataType: 'jsonp',
+                        });
+                        localStorage.setItem("installed", true);
+                    }
+                } catch (e) {
+
+                }
+
+            });
+        </script>
+
+        <script>
+            var _hmt = _hmt || [];
+            (function () {
+                var hm = document.createElement("script");
+                hm.src = "https://hm.baidu.com/hm.js?f8d0a8c400404989e195270b0bbf060a";
+                var s = document.getElementsByTagName("script")[0];
+                s.parentNode.insertBefore(hm, s);
+            })();
+        </script>
+
+    </body>
+
 </html>

+ 30 - 30
application/route.php

@@ -1,30 +1,30 @@
-<?php
-
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2006~2016 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: liu21st <liu21st@gmail.com>
-// +----------------------------------------------------------------------
-
-//如果有定义绑定后台模块则禁用路由规则 
-if (\think\Route::getBind('module') == 'admin'){
-    return [];
-}
-
-return [
-    //别名配置,别名只能是映射到控制器且访问时必须加上请求的方法
-    '__alias__'   => [
-    ],
-    //变量规则
-    '__pattern__' => [
-    ],
-//        域名绑定到模块
-//        '__domain__'  => [
-//            'admin' => 'admin',
-//            'api'   => 'api',
-//        ],
-];
+<?php
+
+// +----------------------------------------------------------------------
+// | ThinkPHP [ WE CAN DO IT JUST THINK ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2006~2016 http://thinkphp.cn All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
+// +----------------------------------------------------------------------
+// | Author: liu21st <liu21st@gmail.com>
+// +----------------------------------------------------------------------
+
+//如果有定义绑定后台模块则禁用路由规则 
+if (\think\Route::getBind('module') == 'admin'){
+    return [];
+}
+
+return [
+    //别名配置,别名只能是映射到控制器且访问时必须加上请求的方法
+    '__alias__'   => [
+    ],
+    //变量规则
+    '__pattern__' => [
+    ],
+//        域名绑定到模块
+//        '__domain__'  => [
+//            'admin' => 'admin',
+//            'api'   => 'api',
+//        ],
+];

+ 34 - 34
application/tags.php

@@ -1,34 +1,34 @@
-<?php
-
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2006~2016 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: liu21st <liu21st@gmail.com>
-// +----------------------------------------------------------------------
-// 应用行为扩展定义文件
-return [
-    // 应用初始化
-    'app_init'     => [],
-    // 应用开始
-    'app_begin'    => [],
-    // 模块初始化
-    'module_init'  => [
-        'app\\common\\behavior\\Common',
-    ],
-    // 模块初始化
-    'addons_init'  => [
-        'app\\common\\behavior\\Common',
-    ],
-    // 操作开始执行
-    'action_begin' => [],
-    // 视图内容过滤
-    'view_filter'  => [],
-    // 日志写入
-    'log_write'    => [],
-    // 应用结束
-    'app_end'      => [],
-];
+<?php
+
+// +----------------------------------------------------------------------
+// | ThinkPHP [ WE CAN DO IT JUST THINK ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2006~2016 http://thinkphp.cn All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
+// +----------------------------------------------------------------------
+// | Author: liu21st <liu21st@gmail.com>
+// +----------------------------------------------------------------------
+// 应用行为扩展定义文件
+return [
+    // 应用初始化
+    'app_init'     => [],
+    // 应用开始
+    'app_begin'    => [],
+    // 模块初始化
+    'module_init'  => [
+        'app\\common\\behavior\\Common',
+    ],
+    // 模块初始化
+    'addons_init'  => [
+        'app\\common\\behavior\\Common',
+    ],
+    // 操作开始执行
+    'action_begin' => [],
+    // 视图内容过滤
+    'view_filter'  => [],
+    // 日志写入
+    'log_write'    => [],
+    // 应用结束
+    'app_end'      => [],
+];

+ 25 - 25
build.php

@@ -1,25 +1,25 @@
-<?php
-
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2006~2016 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: liu21st <liu21st@gmail.com>
-// +----------------------------------------------------------------------
-
-return [
-// 生成应用公共文件
-    '__file__' => ['hello.php', 'test.php'],
-    // 定义demo模块的自动生成 (按照实际定义的文件名生成)
-    'demo' => [
-        '__file__'   => ['common.php'],
-        '__dir__'    => ['behavior', 'controller', 'model', 'view'],
-        'controller' => ['Index', 'Test', 'UserType'],
-        'model'      => ['User', 'UserType'],
-        'view'       => ['index/index'],
-    ],
-        // 其他更多的模块定义
-];
+<?php
+
+// +----------------------------------------------------------------------
+// | ThinkPHP [ WE CAN DO IT JUST THINK ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2006~2016 http://thinkphp.cn All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
+// +----------------------------------------------------------------------
+// | Author: liu21st <liu21st@gmail.com>
+// +----------------------------------------------------------------------
+
+return [
+// 生成应用公共文件
+    '__file__' => ['hello.php', 'test.php'],
+    // 定义demo模块的自动生成 (按照实际定义的文件名生成)
+    'demo' => [
+        '__file__'   => ['common.php'],
+        '__dir__'    => ['behavior', 'controller', 'model', 'view'],
+        'controller' => ['Index', 'Test', 'UserType'],
+        'model'      => ['User', 'UserType'],
+        'view'       => ['index/index'],
+    ],
+        // 其他更多的模块定义
+];

+ 32 - 32
composer.json

@@ -1,32 +1,32 @@
-{
-    "name": "karsonzhang/fastadmin",
-    "description": "the fastest admin framework",
-    "type": "project",
-    "keywords": [
-        "fastadmin",
-        "thinkphp"
-    ],
-    "homepage": "http://www.fastadmin.net/",
-    "license": "Apache-2.0",
-    "authors": [
-        {
-            "name": "karson",
-            "email": "karsonzhang@163.com"
-        }
-    ],
-    "require": {
-        "php": ">=5.4.0",
-        "topthink/framework": "^5.0",
-        "overtrue/wechat": "~3.1",
-        "endroid/qrcode": "^1.9",
-        "topthink/think-captcha": "^1.0",
-        "mtdowling/cron-expression": "^1.2",
-        "phpmailer/phpmailer": "^5.2",
-        "karsonzhang/fastadmin-addons": "dev-master",
-        "overtrue/pinyin": "~3.0",
-        "phpoffice/phpexcel": "^1.8"
-    },
-    "config": {
-        "preferred-install": "dist"
-    }
-}
+{
+    "name": "karsonzhang/fastadmin",
+    "description": "the fastest admin framework",
+    "type": "project",
+    "keywords": [
+        "fastadmin",
+        "thinkphp"
+    ],
+    "homepage": "http://www.fastadmin.net/",
+    "license": "Apache-2.0",
+    "authors": [
+        {
+            "name": "karson",
+            "email": "karsonzhang@163.com"
+        }
+    ],
+    "require": {
+        "php": ">=5.4.0",
+        "topthink/framework": "^5.0",
+        "overtrue/wechat": "~3.1",
+        "endroid/qrcode": "^1.9",
+        "topthink/think-captcha": "^1.0",
+        "mtdowling/cron-expression": "^1.2",
+        "phpmailer/phpmailer": "^5.2",
+        "karsonzhang/fastadmin-addons": "dev-master",
+        "overtrue/pinyin": "~3.0",
+        "phpoffice/phpexcel": "^1.8"
+    },
+    "config": {
+        "preferred-install": "dist"
+    }
+}

+ 187 - 187
extend/fast/Rsa.php

@@ -1,187 +1,187 @@
-<?php
-
-namespace fast;
-
-/**
- * RSA签名类
- */
-class Rsa
-{
-
-    public $publicKey = '';
-    public $privateKey = '';
-    private $_privKey;
-
-    /**
-     * * private key
-     */
-    private $_pubKey;
-
-    /**
-     * * public key
-     */
-    private $_keyPath;
-
-    /**
-     * * the keys saving path
-     */
-
-    /**
-     * * the construtor,the param $path is the keys saving path
-     */
-    function __construct($publicKey = null, $privateKey = null)
-    {
-        $this->setKey($publicKey, $privateKey);
-    }
-
-    /**
-     * 设置公钥和私钥
-     * @param string $publicKey 公钥
-     * @param string $privateKey 私钥
-     */
-    public function setKey($publicKey = null, $privateKey = null)
-    {
-        if (!is_null($publicKey))
-            $this->publicKey = $publicKey;
-        if (!is_null($privateKey))
-            $this->privateKey = $privateKey;
-    }
-
-    /**
-     * * setup the private key
-     */
-    private function setupPrivKey()
-    {
-        if (is_resource($this->_privKey))
-        {
-            return true;
-        }
-        $pem = chunk_split($this->privateKey, 64, "\n");
-        $pem = "-----BEGIN PRIVATE KEY-----\n" . $pem . "-----END PRIVATE KEY-----\n";
-        $this->_privKey = openssl_pkey_get_private($pem);
-        return true;
-    }
-
-    /**
-     * * setup the public key
-     */
-    private function setupPubKey()
-    {
-        if (is_resource($this->_pubKey))
-        {
-            return true;
-        }
-        $pem = chunk_split($this->publicKey, 64, "\n");
-        $pem = "-----BEGIN PUBLIC KEY-----\n" . $pem . "-----END PUBLIC KEY-----\n";
-        $this->_pubKey = openssl_pkey_get_public($pem);
-        return true;
-    }
-
-    /**
-     * * encrypt with the private key
-     */
-    public function privEncrypt($data)
-    {
-        if (!is_string($data))
-        {
-            return null;
-        }
-        $this->setupPrivKey();
-        $r = openssl_private_encrypt($data, $encrypted, $this->_privKey);
-        if ($r)
-        {
-            return base64_encode($encrypted);
-        }
-        return null;
-    }
-
-    /**
-     * * decrypt with the private key
-     */
-    public function privDecrypt($encrypted)
-    {
-        if (!is_string($encrypted))
-        {
-            return null;
-        }
-        $this->setupPrivKey();
-        $encrypted = base64_decode($encrypted);
-        $r = openssl_private_decrypt($encrypted, $decrypted, $this->_privKey);
-        if ($r)
-        {
-            return $decrypted;
-        }
-        return null;
-    }
-
-    /**
-     * * encrypt with public key
-     */
-    public function pubEncrypt($data)
-    {
-        if (!is_string($data))
-        {
-            return null;
-        }
-        $this->setupPubKey();
-        $r = openssl_public_encrypt($data, $encrypted, $this->_pubKey);
-        if ($r)
-        {
-            return base64_encode($encrypted);
-        }
-        return null;
-    }
-
-    /**
-     * * decrypt with the public key
-     */
-    public function pubDecrypt($crypted)
-    {
-        if (!is_string($crypted))
-        {
-            return null;
-        }
-        $this->setupPubKey();
-        $crypted = base64_decode($crypted);
-        $r = openssl_public_decrypt($crypted, $decrypted, $this->_pubKey);
-        if ($r)
-        {
-            return $decrypted;
-        }
-        return null;
-    }
-
-    /**
-     * 构造签名
-     * @param string $dataString 被签名数据
-     * @return string
-     */
-    public function sign($dataString)
-    {
-        $this->setupPrivKey();
-        $signature = false;
-        openssl_sign($dataString, $signature, $this->_privKey);
-        return base64_encode($signature);
-    }
-
-    /**
-     * 验证签名
-     * @param string $dataString 被签名数据
-     * @param string $signString 已经签名的字符串
-     * @return number 1签名正确 0签名错误
-     */
-    public function verify($dataString, $signString)
-    {
-        $this->setupPubKey();
-        $signature = base64_decode($signString);
-        $flg = openssl_verify($dataString, $signature, $this->_pubKey);
-        return $flg;
-    }
-
-    public function __destruct()
-    {
-        is_resource($this->_privKey) && @openssl_free_key($this->_privKey);
-        is_resource($this->_pubKey) && @openssl_free_key($this->_pubKey);
-    }
-
-}
+<?php
+
+namespace fast;
+
+/**
+ * RSA签名类
+ */
+class Rsa
+{
+
+    public $publicKey = '';
+    public $privateKey = '';
+    private $_privKey;
+
+    /**
+     * * private key
+     */
+    private $_pubKey;
+
+    /**
+     * * public key
+     */
+    private $_keyPath;
+
+    /**
+     * * the keys saving path
+     */
+
+    /**
+     * * the construtor,the param $path is the keys saving path
+     */
+    function __construct($publicKey = null, $privateKey = null)
+    {
+        $this->setKey($publicKey, $privateKey);
+    }
+
+    /**
+     * 设置公钥和私钥
+     * @param string $publicKey 公钥
+     * @param string $privateKey 私钥
+     */
+    public function setKey($publicKey = null, $privateKey = null)
+    {
+        if (!is_null($publicKey))
+            $this->publicKey = $publicKey;
+        if (!is_null($privateKey))
+            $this->privateKey = $privateKey;
+    }
+
+    /**
+     * * setup the private key
+     */
+    private function setupPrivKey()
+    {
+        if (is_resource($this->_privKey))
+        {
+            return true;
+        }
+        $pem = chunk_split($this->privateKey, 64, "\n");
+        $pem = "-----BEGIN PRIVATE KEY-----\n" . $pem . "-----END PRIVATE KEY-----\n";
+        $this->_privKey = openssl_pkey_get_private($pem);
+        return true;
+    }
+
+    /**
+     * * setup the public key
+     */
+    private function setupPubKey()
+    {
+        if (is_resource($this->_pubKey))
+        {
+            return true;
+        }
+        $pem = chunk_split($this->publicKey, 64, "\n");
+        $pem = "-----BEGIN PUBLIC KEY-----\n" . $pem . "-----END PUBLIC KEY-----\n";
+        $this->_pubKey = openssl_pkey_get_public($pem);
+        return true;
+    }
+
+    /**
+     * * encrypt with the private key
+     */
+    public function privEncrypt($data)
+    {
+        if (!is_string($data))
+        {
+            return null;
+        }
+        $this->setupPrivKey();
+        $r = openssl_private_encrypt($data, $encrypted, $this->_privKey);
+        if ($r)
+        {
+            return base64_encode($encrypted);
+        }
+        return null;
+    }
+
+    /**
+     * * decrypt with the private key
+     */
+    public function privDecrypt($encrypted)
+    {
+        if (!is_string($encrypted))
+        {
+            return null;
+        }
+        $this->setupPrivKey();
+        $encrypted = base64_decode($encrypted);
+        $r = openssl_private_decrypt($encrypted, $decrypted, $this->_privKey);
+        if ($r)
+        {
+            return $decrypted;
+        }
+        return null;
+    }
+
+    /**
+     * * encrypt with public key
+     */
+    public function pubEncrypt($data)
+    {
+        if (!is_string($data))
+        {
+            return null;
+        }
+        $this->setupPubKey();
+        $r = openssl_public_encrypt($data, $encrypted, $this->_pubKey);
+        if ($r)
+        {
+            return base64_encode($encrypted);
+        }
+        return null;
+    }
+
+    /**
+     * * decrypt with the public key
+     */
+    public function pubDecrypt($crypted)
+    {
+        if (!is_string($crypted))
+        {
+            return null;
+        }
+        $this->setupPubKey();
+        $crypted = base64_decode($crypted);
+        $r = openssl_public_decrypt($crypted, $decrypted, $this->_pubKey);
+        if ($r)
+        {
+            return $decrypted;
+        }
+        return null;
+    }
+
+    /**
+     * 构造签名
+     * @param string $dataString 被签名数据
+     * @return string
+     */
+    public function sign($dataString)
+    {
+        $this->setupPrivKey();
+        $signature = false;
+        openssl_sign($dataString, $signature, $this->_privKey);
+        return base64_encode($signature);
+    }
+
+    /**
+     * 验证签名
+     * @param string $dataString 被签名数据
+     * @param string $signString 已经签名的字符串
+     * @return number 1签名正确 0签名错误
+     */
+    public function verify($dataString, $signString)
+    {
+        $this->setupPubKey();
+        $signature = base64_decode($signString);
+        $flg = openssl_verify($dataString, $signature, $this->_pubKey);
+        return $flg;
+    }
+
+    public function __destruct()
+    {
+        is_resource($this->_privKey) && @openssl_free_key($this->_privKey);
+        is_resource($this->_pubKey) && @openssl_free_key($this->_pubKey);
+    }
+
+}

+ 8 - 8
public/.htaccess

@@ -1,8 +1,8 @@
-<IfModule mod_rewrite.c>
-  Options +FollowSymlinks -Multiviews
-  RewriteEngine On
-
-  RewriteCond %{REQUEST_FILENAME} !-d
-  RewriteCond %{REQUEST_FILENAME} !-f
-  RewriteRule ^(.*)$ index.php [L,E=PATH_INFO:$1]
-</IfModule>
+<IfModule mod_rewrite.c>
+  Options +FollowSymlinks -Multiviews
+  RewriteEngine On
+
+  RewriteCond %{REQUEST_FILENAME} !-d
+  RewriteCond %{REQUEST_FILENAME} !-f
+  RewriteRule ^(.*)$ index.php [L,E=PATH_INFO:$1]
+</IfModule>

+ 34 - 34
public/admin.php

@@ -1,35 +1,35 @@
-<?php
-
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: liu21st <liu21st@gmail.com>
-// +----------------------------------------------------------------------
-// [ 后台入口文件 ]
-// 使用此文件可以达到隐藏admin模块的效果
-// 建议将admin.php改成其它任意的文件名,同时修改config.php中的'deny_module_list',把admin模块也添加进去
-// 定义应用目录
-define('APP_PATH', __DIR__ . '/../application/');
-
-// 判断是否安装FastAdmin
-if (!file_exists(APP_PATH . 'admin/command/Install/install.lock'))
-{
-    header("location:./install.php");
-    exit;
-}
-
-// 加载框架引导文件
-require __DIR__ . '/../thinkphp/base.php';
-
-// 绑定到admin模块
-\think\Route::bind('admin');
-
-// 设置根url
-\think\Url::root('');
-
-// 执行应用
+<?php
+
+// +----------------------------------------------------------------------
+// | ThinkPHP [ WE CAN DO IT JUST THINK ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
+// +----------------------------------------------------------------------
+// | Author: liu21st <liu21st@gmail.com>
+// +----------------------------------------------------------------------
+// [ 后台入口文件 ]
+// 使用此文件可以达到隐藏admin模块的效果
+// 建议将admin.php改成其它任意的文件名,同时修改config.php中的'deny_module_list',把admin模块也添加进去
+// 定义应用目录
+define('APP_PATH', __DIR__ . '/../application/');
+
+// 判断是否安装FastAdmin
+if (!file_exists(APP_PATH . 'admin/command/Install/install.lock'))
+{
+    header("location:./install.php");
+    exit;
+}
+
+// 加载框架引导文件
+require __DIR__ . '/../thinkphp/base.php';
+
+// 绑定到admin模块
+\think\Route::bind('admin');
+
+// 设置根url
+\think\Url::root('');
+
+// 执行应用
 \think\App::run()->send();

File diff suppressed because it is too large
+ 1 - 1
public/assets/css/backend.min.css


File diff suppressed because it is too large
+ 560 - 499
public/assets/js/require-backend.min.js


+ 1 - 0
public/assets/js/require-form.js

@@ -44,6 +44,7 @@ define(['jquery', 'bootstrap', 'upload', 'validator'], function ($, undefined, U
                             parent.$(".btn-refresh").trigger("click");
                             var index = parent.Layer.getFrameIndex(window.name);
                             parent.Layer.close(index);
+                            return false;
                         }, function (data, ret) {
                             that.holdSubmit(false);
                             submitBtn.removeClass("disabled");

File diff suppressed because it is too large
+ 770 - 770
public/assets/less/backend.less


+ 12 - 12
public/assets/less/frontend.less

@@ -1,12 +1,12 @@
-@import (reference) "bootstrap-less/mixins.less";
-@import (reference) "bootstrap-less/variables.less";
-@import "lesshat.less";
-
-@import url("../css/bootstrap.min.css");
-@import url("../css/fastadmin.min.css");
-@import url("../css/skins/skin-green.css");
-@import url("../css/iconfont.css");
-@import url("../libs/font-awesome/css/font-awesome.min.css");
-@import url("../libs/toastr/toastr.min.css");
-@import url("../libs/layer/build/skin/default/layer.css");
-
+@import (reference) "bootstrap-less/mixins.less";
+@import (reference) "bootstrap-less/variables.less";
+@import "lesshat.less";
+
+@import url("../css/bootstrap.min.css");
+@import url("../css/fastadmin.min.css");
+@import url("../css/skins/skin-green.css");
+@import url("../css/iconfont.css");
+@import url("../libs/font-awesome/css/font-awesome.min.css");
+@import url("../libs/toastr/toastr.min.css");
+@import url("../libs/layer/build/skin/default/layer.css");
+

+ 24 - 24
public/index.php

@@ -1,24 +1,24 @@
-<?php
-
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: liu21st <liu21st@gmail.com>
-// +----------------------------------------------------------------------
-// [ 应用入口文件 ]
-// 定义应用目录
-define('APP_PATH', __DIR__ . '/../application/');
-
-// 判断是否安装FastAdmin
-if (!file_exists(APP_PATH . 'admin/command/Install/install.lock'))
-{
-    header("location:./install.php");
-    exit;
-}
-
-// 加载框架引导文件
-require __DIR__ . '/../thinkphp/start.php';
+<?php
+
+// +----------------------------------------------------------------------
+// | ThinkPHP [ WE CAN DO IT JUST THINK ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
+// +----------------------------------------------------------------------
+// | Author: liu21st <liu21st@gmail.com>
+// +----------------------------------------------------------------------
+// [ 应用入口文件 ]
+// 定义应用目录
+define('APP_PATH', __DIR__ . '/../application/');
+
+// 判断是否安装FastAdmin
+if (!file_exists(APP_PATH . 'admin/command/Install/install.lock'))
+{
+    header("location:./install.php");
+    exit;
+}
+
+// 加载框架引导文件
+require __DIR__ . '/../thinkphp/start.php';

+ 2 - 2
public/robots.txt

@@ -1,2 +1,2 @@
-User-agent: *
-Disallow:
+User-agent: *
+Disallow:

+ 17 - 17
public/router.php

@@ -1,17 +1,17 @@
-<?php
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2006~2016 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: liu21st <liu21st@gmail.com>
-// +----------------------------------------------------------------------
-// $Id$
-
-if (is_file($_SERVER["DOCUMENT_ROOT"] . $_SERVER["REQUEST_URI"])) {
-    return false;
-} else {
-    require __DIR__ . "/index.php";
-}
+<?php
+// +----------------------------------------------------------------------
+// | ThinkPHP [ WE CAN DO IT JUST THINK ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2006~2016 http://thinkphp.cn All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
+// +----------------------------------------------------------------------
+// | Author: liu21st <liu21st@gmail.com>
+// +----------------------------------------------------------------------
+// $Id$
+
+if (is_file($_SERVER["DOCUMENT_ROOT"] . $_SERVER["REQUEST_URI"])) {
+    return false;
+} else {
+    require __DIR__ . "/index.php";
+}

+ 16 - 16
think

@@ -1,17 +1,17 @@
-#!/usr/bin/env php
-<?php
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: yunwuxin <448901948@qq.com>
-// +----------------------------------------------------------------------
-
-// 定义项目路径
-define('APP_PATH', __DIR__ . '/application/');
-
-// 加载框架引导文件
+#!/usr/bin/env php
+<?php
+// +----------------------------------------------------------------------
+// | ThinkPHP [ WE CAN DO IT JUST THINK ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
+// +----------------------------------------------------------------------
+// | Author: yunwuxin <448901948@qq.com>
+// +----------------------------------------------------------------------
+
+// 定义项目路径
+define('APP_PATH', __DIR__ . '/application/');
+
+// 加载框架引导文件
 require './thinkphp/console.php';