commit
fbc2634b88
6419 changed files with 1404096 additions and 0 deletions
-
13.gitignore
-
20HuoCMS_close_source/.example.env
-
42HuoCMS_close_source/.travis.yml
-
201HuoCMS_close_source/LICENSE
-
32HuoCMS_close_source/LICENSE.txt
-
124HuoCMS_close_source/README.md
-
22HuoCMS_close_source/app/AppService.php
-
118HuoCMS_close_source/app/BaseController.php
-
82HuoCMS_close_source/app/ExceptionHandle.php
-
309HuoCMS_close_source/app/Plugin.php
-
8HuoCMS_close_source/app/Request.php
-
101HuoCMS_close_source/app/command/BaiduTongji.php
-
61HuoCMS_close_source/app/command/CreateController.php
-
53HuoCMS_close_source/app/command/CreateLink.php
-
28HuoCMS_close_source/app/command/CreateModel.php
-
59HuoCMS_close_source/app/command/WebDiagnosis.php
-
55HuoCMS_close_source/app/command/WebDiagnosis2.php
-
55HuoCMS_close_source/app/command/WebDiagnosis3.php
-
30HuoCMS_close_source/app/command/service/Server.php
-
149HuoCMS_close_source/app/command/service/TaskServer.php
-
171HuoCMS_close_source/app/command/service/TongJiServer.php
-
55HuoCMS_close_source/app/command/service/step/CheckIncluded.php
-
124HuoCMS_close_source/app/command/service/step/CheckKeywords.php
-
78HuoCMS_close_source/app/command/service/step/CheckLinks.php
-
156HuoCMS_close_source/app/command/service/step/CheckSSL301.php
-
136HuoCMS_close_source/app/command/service/step/CheckTplCode.php
-
138HuoCMS_close_source/app/command/stubs/controller.stub
-
113HuoCMS_close_source/app/command/stubs/model.stub
-
1300HuoCMS_close_source/app/common.php
-
1HuoCMS_close_source/app/controller/api/.gitignore
-
204HuoCMS_close_source/app/controller/backend/AccountController.php
-
322HuoCMS_close_source/app/controller/backend/AdminController.php
-
40HuoCMS_close_source/app/controller/backend/AdminLoginLogController.php
-
182HuoCMS_close_source/app/controller/backend/AdminMenuController.php
-
41HuoCMS_close_source/app/controller/backend/AdminOptLogController.php
-
140HuoCMS_close_source/app/controller/backend/AdvertisementController.php
-
158HuoCMS_close_source/app/controller/backend/AttachmentCateController.php
-
508HuoCMS_close_source/app/controller/backend/AttachmentController.php
-
90HuoCMS_close_source/app/controller/backend/BaseController.php
-
537HuoCMS_close_source/app/controller/backend/CategoryController.php
-
1110HuoCMS_close_source/app/controller/backend/ContentController.php
-
146HuoCMS_close_source/app/controller/backend/ContentTagController.php
-
68HuoCMS_close_source/app/controller/backend/DashboardController.php
-
146HuoCMS_close_source/app/controller/backend/DatabaseController.php
-
686HuoCMS_close_source/app/controller/backend/DesignController.php
-
27HuoCMS_close_source/app/controller/backend/ExcelController.php
-
585HuoCMS_close_source/app/controller/backend/FormController.php
-
14HuoCMS_close_source/app/controller/backend/GoogleStatisticsController.php
-
154HuoCMS_close_source/app/controller/backend/InnerChartController.php
-
130HuoCMS_close_source/app/controller/backend/InquiryCategoryController.php
-
231HuoCMS_close_source/app/controller/backend/InquiryController.php
-
152HuoCMS_close_source/app/controller/backend/InquiryEmailController.php
-
153HuoCMS_close_source/app/controller/backend/JobCateController.php
-
154HuoCMS_close_source/app/controller/backend/JobCityController.php
-
164HuoCMS_close_source/app/controller/backend/JobController.php
-
356HuoCMS_close_source/app/controller/backend/KeywordController.php
-
91HuoCMS_close_source/app/controller/backend/KeywordQueryController.php
-
129HuoCMS_close_source/app/controller/backend/KeywordWebsiteController.php
-
255HuoCMS_close_source/app/controller/backend/LinkController.php
-
105HuoCMS_close_source/app/controller/backend/MaterialController.php
-
163HuoCMS_close_source/app/controller/backend/ModuleController.php
-
159HuoCMS_close_source/app/controller/backend/ModuleFieldController.php
-
166HuoCMS_close_source/app/controller/backend/NavCateController.php
-
316HuoCMS_close_source/app/controller/backend/NavController.php
-
52HuoCMS_close_source/app/controller/backend/PluginController.php
-
185HuoCMS_close_source/app/controller/backend/PosterController.php
-
121HuoCMS_close_source/app/controller/backend/RecycleBinController.php
-
108HuoCMS_close_source/app/controller/backend/ResumeController.php
-
186HuoCMS_close_source/app/controller/backend/RoleController.php
-
80HuoCMS_close_source/app/controller/backend/SeoAccountController.php
-
242HuoCMS_close_source/app/controller/backend/SeoCheckController.php
-
54HuoCMS_close_source/app/controller/backend/SeoController.php
-
139HuoCMS_close_source/app/controller/backend/SeoSettingController.php
-
46HuoCMS_close_source/app/controller/backend/SiteMapController.php
-
125HuoCMS_close_source/app/controller/backend/SlideCateController.php
-
134HuoCMS_close_source/app/controller/backend/SlideController.php
-
139HuoCMS_close_source/app/controller/backend/SocialMarketingController.php
-
45HuoCMS_close_source/app/controller/backend/StaticFileController.php
-
617HuoCMS_close_source/app/controller/backend/StatisticsController.php
-
180HuoCMS_close_source/app/controller/backend/SysSettingController.php
-
539HuoCMS_close_source/app/controller/backend/SystemInstallController.php
-
169HuoCMS_close_source/app/controller/backend/TagController.php
-
277HuoCMS_close_source/app/controller/backend/ThemeController.php
-
206HuoCMS_close_source/app/controller/backend/ThemeFileController.php
-
84HuoCMS_close_source/app/controller/backend/UploadController.php
-
287HuoCMS_close_source/app/controller/backend/WebsiteController.php
-
86HuoCMS_close_source/app/controller/backend/WebsiteLangController.php
-
90HuoCMS_close_source/app/controller/backend/WebsiteServerController.php
-
125HuoCMS_close_source/app/controller/backend/WebsiteSettingController.php
-
333HuoCMS_close_source/app/controller/frontend/BaseController.php
-
132HuoCMS_close_source/app/controller/frontend/DesignBaseController.php
-
140HuoCMS_close_source/app/controller/frontend/DesignController.php
-
128HuoCMS_close_source/app/controller/frontend/DetailController.php
-
274HuoCMS_close_source/app/controller/frontend/FormController.php
-
105HuoCMS_close_source/app/controller/frontend/InquiryController.php
-
55HuoCMS_close_source/app/controller/frontend/ListController.php
-
67HuoCMS_close_source/app/controller/frontend/ResumeController.php
-
89HuoCMS_close_source/app/controller/frontend/SearchController.php
-
55HuoCMS_close_source/app/controller/frontend/SeoController.php
-
59HuoCMS_close_source/app/controller/frontend/TagController.php
@ -0,0 +1,13 @@ |
|||
/HuoCMS_close_source/.env |
|||
/.idea |
|||
/.vscode |
|||
/.Ds.store |
|||
*.log |
|||
*.DS_Store |
|||
/HuoCMS_close_source/runtime |
|||
.VSCodeCounter/ |
|||
/HuoCMS_close_source/composer.lock |
|||
/HuoCMS_close_source/public/nginx.htaccess |
|||
/HuoCMS_close_source/public/.htaccess |
|||
/HuoCMS_close_source/public/excel/* |
|||
/docker-compose/mysql/data/ |
|||
@ -0,0 +1,20 @@ |
|||
APP_DEBUG = true |
|||
APP_HOST = http://localhost |
|||
|
|||
[APP] |
|||
DEFAULT_TIMEZONE = Asia/Shanghai |
|||
LAZY_LOAD_SIZE = |
|||
|
|||
[DATABASE] |
|||
TYPE = mysql |
|||
HOSTNAME = 127.0.0.1 |
|||
DATABASE = huo_cms |
|||
USERNAME = root |
|||
PASSWORD = |
|||
HOSTPORT = 3306 |
|||
CHARSET = utf8mb4 |
|||
DEBUG = true |
|||
PREFIX = hc_ |
|||
|
|||
[LANG] |
|||
default_lang = zh |
|||
@ -0,0 +1,42 @@ |
|||
sudo: false |
|||
|
|||
language: php |
|||
|
|||
branches: |
|||
only: |
|||
- stable |
|||
|
|||
cache: |
|||
directories: |
|||
- $HOME/.composer/cache |
|||
|
|||
before_install: |
|||
- composer self-update |
|||
|
|||
install: |
|||
- composer install --no-dev --no-interaction --ignore-platform-reqs |
|||
- zip -r --exclude='*.git*' --exclude='*.zip' --exclude='*.travis.yml' ThinkPHP_Core.zip . |
|||
- composer require --update-no-dev --no-interaction "topthink/think-image:^1.0" |
|||
- composer require --update-no-dev --no-interaction "topthink/think-migration:^1.0" |
|||
- composer require --update-no-dev --no-interaction "topthink/think-captcha:^1.0" |
|||
- composer require --update-no-dev --no-interaction "topthink/think-mongo:^1.0" |
|||
- composer require --update-no-dev --no-interaction "topthink/think-worker:^1.0" |
|||
- composer require --update-no-dev --no-interaction "topthink/think-helper:^1.0" |
|||
- composer require --update-no-dev --no-interaction "topthink/think-queue:^1.0" |
|||
- composer require --update-no-dev --no-interaction "topthink/think-angular:^1.0" |
|||
- composer require --dev --update-no-dev --no-interaction "topthink/think-testing:^1.0" |
|||
- zip -r --exclude='*.git*' --exclude='*.zip' --exclude='*.travis.yml' ThinkPHP_Full.zip . |
|||
|
|||
script: |
|||
- php think unit |
|||
|
|||
deploy: |
|||
provider: releases |
|||
api_key: |
|||
secure: TSF6bnl2JYN72UQOORAJYL+CqIryP2gHVKt6grfveQ7d9rleAEoxlq6PWxbvTI4jZ5nrPpUcBUpWIJHNgVcs+bzLFtyh5THaLqm39uCgBbrW7M8rI26L8sBh/6nsdtGgdeQrO/cLu31QoTzbwuz1WfAVoCdCkOSZeXyT/CclH99qV6RYyQYqaD2wpRjrhA5O4fSsEkiPVuk0GaOogFlrQHx+C+lHnf6pa1KxEoN1A0UxxVfGX6K4y5g4WQDO5zT4bLeubkWOXK0G51XSvACDOZVIyLdjApaOFTwamPcD3S1tfvuxRWWvsCD5ljFvb2kSmx5BIBNwN80MzuBmrGIC27XLGOxyMerwKxB6DskNUO9PflKHDPI61DRq0FTy1fv70SFMSiAtUv9aJRT41NQh9iJJ0vC8dl+xcxrWIjU1GG6+l/ZcRqVx9V1VuGQsLKndGhja7SQ+X1slHl76fRq223sMOql7MFCd0vvvxVQ2V39CcFKao/LB1aPH3VhODDEyxwx6aXoTznvC/QPepgWsHOWQzKj9ftsgDbsNiyFlXL4cu8DWUty6rQy8zT2b4O8b1xjcwSUCsy+auEjBamzQkMJFNlZAIUrukL/NbUhQU37TAbwsFyz7X0E/u/VMle/nBCNAzgkMwAUjiHM6FqrKKBRWFbPrSIixjfjkCnrMEPw= |
|||
file: |
|||
- ThinkPHP_Core.zip |
|||
- ThinkPHP_Full.zip |
|||
skip_cleanup: true |
|||
on: |
|||
tags: true |
|||
@ -0,0 +1,201 @@ |
|||
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: |
|||
|
|||
(a) You must give any other recipients of the Work or |
|||
Derivative Works a copy of this License; and |
|||
|
|||
(b) You must cause any modified files to carry prominent notices |
|||
stating that You changed the files; and |
|||
|
|||
(c) 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 |
|||
|
|||
(d) 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 [yyyy] [name of copyright owner] |
|||
|
|||
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. |
|||
@ -0,0 +1,32 @@ |
|||
|
|||
ThinkPHP遵循Apache2开源协议发布,并提供免费使用。 |
|||
版权所有Copyright © 2006-2016 by ThinkPHP (http://thinkphp.cn) |
|||
All rights reserved。 |
|||
ThinkPHP® 商标和著作权所有者为上海顶想信息科技有限公司。 |
|||
|
|||
Apache Licence是著名的非盈利开源组织Apache采用的协议。 |
|||
该协议和BSD类似,鼓励代码共享和尊重原作者的著作权, |
|||
允许代码修改,再作为开源或商业软件发布。需要满足 |
|||
的条件: |
|||
1. 需要给代码的用户一份Apache Licence ; |
|||
2. 如果你修改了代码,需要在被修改的文件中说明; |
|||
3. 在延伸的代码中(修改和有源代码衍生的代码中)需要 |
|||
带有原来代码中的协议,商标,专利声明和其他原来作者规 |
|||
定需要包含的说明; |
|||
4. 如果再发布的产品中包含一个Notice文件,则在Notice文 |
|||
件中需要带有本协议内容。你可以在Notice中增加自己的 |
|||
许可,但不可以表现为对Apache Licence构成更改。 |
|||
具体的协议参考:http://www.apache.org/licenses/LICENSE-2.0 |
|||
|
|||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
|||
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
|||
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
|||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
|||
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
|||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
|||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN |
|||
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|||
POSSIBILITY OF SUCH DAMAGE. |
|||
@ -0,0 +1,124 @@ |
|||
# HuoCMS |
|||
## 声明 |
|||
HuoCMS是一款免费的开源可商用网站建设系统,但是商用需要在官网: http://www.huocms.com 获取免费授权,授权的域名需要获得备案。 |
|||
获取专属定制版以及更多版本信息,可访问HuoCMS官网,了解更多。 |
|||
## 系统简介 |
|||
基于ThinkPhp6.0+Vue 开发的一套HuoCMS建站系统。 |
|||
HuoCMS是一套内容管理系统同时也是一套企业官网建设系统,能够帮过用户快速搭建自己的网站。可以满足企业站,外贸站,个人博客等一系列的建站需求。HuoCMS的优势: 可以使用统一后台管理多个网站的内容,统一维护,不同内容可以在不同的网站上面共享,方便快捷。 |
|||
HuoCMS亮点 |
|||
``` |
|||
多语言,多站点自由切换 |
|||
后台界面美观 |
|||
附件统一管理,一次上传重复使用 |
|||
网站内容集中管理,一次添加,多个站点共同享用 |
|||
SEO功能强大 |
|||
前台模版自由定义和切换 |
|||
具有丰富的前台模版标签,方便用户自由调用内容 |
|||
。。。。。。。 |
|||
``` |
|||
|
|||
## 系统演示 |
|||
HuoCMS后台演示站点(请使用电脑PC打开) |
|||
地址:http://demo.huocms.com/admin.php |
|||
账号:admin@admin.com |
|||
密码:123123 |
|||
HuoCMS开发群(QQ):714064832 |
|||
前台仓库访问地址: https://gitee.com/njsq/huocms_vue |
|||
前台仓库克隆地址: `https://gitee.com/njsq/huocms_vue.git` |
|||
|
|||
|
|||
## 页面展示 |
|||
 |
|||
|
|||
 |
|||
|
|||
 |
|||
|
|||
 |
|||
|
|||
 |
|||
|
|||
 |
|||
|
|||
 |
|||
|
|||
 |
|||
|
|||
 |
|||
|
|||
|
|||
## 安装教程 |
|||
### 软件下载 |
|||
- 在`git`仓库 `https://gitee.com/digital-flag/huocms.git` ,克隆下载 |
|||
- 在`HuoCMS`官网上`http://www.huocms.com`下载全量安装包 |
|||
|
|||
### 环境推荐 |
|||
``` |
|||
* 最好选择类Unix系统(推荐Linux) |
|||
|
|||
* Nignx/Apache/IIS |
|||
|
|||
* PHP >7.2 |
|||
|
|||
* MySQL 5.7 |
|||
|
|||
环境搭建推荐选择使用bt宝塔面板,简单易用。 |
|||
``` |
|||
### 安装HuoCMS |
|||
1. 勾选许可协议,继续安装 |
|||
|
|||
 |
|||
|
|||
2. 环境监测:检查环境是否都正确,确认无误后,点击下一步。如有X号等错误提示,请根据提示修改服务器环境配置。 |
|||
|
|||
 |
|||
|
|||
3. 配置系统:填写数据库用户名、数据库名、数据库密码、后台管理员账号密码 |
|||
|
|||
 |
|||
|
|||
4. 创建数据库 |
|||
|
|||
 |
|||
|
|||
5. 完成安装,访问后台 |
|||
|
|||
 |
|||
|
|||
### 登录 |
|||
前台地址: http://你的域名 |
|||
后台地址:http://你的域名/admin.php; |
|||
账号密码: |
|||
| 账号 | 密码 | |
|||
| ---- | ---- | |
|||
| admin@admin.com | huocms.com | |
|||
|
|||
或者是你在配置系统安装步骤配置的密码。 |
|||
|
|||
## 问题反馈 |
|||
官方网站: |
|||
http://www.huocms.com |
|||
|
|||
官方QQ群: |
|||
714064832 |
|||
|
|||
## 版权授权 |
|||
- HuoCMS是一款免费的开源可商用系统,但是商用需要在HuoCMS官网http://www.huocms.com/grant.html 上获取授权码,主域名获取授权,授权域名需要取得备案。 |
|||
- 免费的授权需要保留前台的HuoCMS版权,以及后台的版权和Logo,去版权请到HuoCMS官网授权页面http://www.huocms.com/grant.html 获取去版权和Logo的授权。 |
|||
- 禁止将本项目的代码和资源进行任何形式的出售(包括二开后的衍生产品),产生的一切任何后果责任由侵权者自负。 |
|||
- HuoCMS系统允许个人或公司进行任意二开及商用,但是不允许任何形式的破解或绕过系统授权的行为,包括但不限于通过HuoCMS系统建设网站、二次开发、发布衍生版本等情况,对于任何破解或绕过HuoCMS官网授权的行为,我们将保留依法追究法律责任的权力。 |
|||
- HuoCMS官方不对使用本软件所构建网站中的文章、产品和其它任何信息承担责任,不管您通过任何渠道下载本软件,您一旦开始安装HuoCMS,即被视为完全理解并接受HuoCMS授权声明的各项条款。 |
|||
|
|||
## 特别鸣谢 |
|||
- ThinkPHP: https://www.thinkphp.cn/ |
|||
- ThinkCmf: https://www.thinkcmf.com/ |
|||
- Vue: https://cn.vuejs.org/ |
|||
- ElementUI: https://element.eleme.cn/#/zh-CN |
|||
- ElementAdmin: https://panjiachen.github.io/vue-element-admin-site/zh/ |
|||
|
|||
|
|||
|
|||
--- |
|||
版权信息 HuoCMS |
|||
版权所有Copyright © 2021 by HuoCMS (http://www.huocms.com) |
|||
All rights reserved。 |
|||
@ -0,0 +1,22 @@ |
|||
<?php |
|||
declare (strict_types = 1); |
|||
|
|||
namespace app; |
|||
|
|||
use think\Service; |
|||
|
|||
/** |
|||
* 应用服务类 |
|||
*/ |
|||
class AppService extends Service |
|||
{ |
|||
public function register() |
|||
{ |
|||
// 服务注册
|
|||
} |
|||
|
|||
public function boot() |
|||
{ |
|||
// 服务启动
|
|||
} |
|||
} |
|||
@ -0,0 +1,118 @@ |
|||
<?php |
|||
declare (strict_types = 1); |
|||
|
|||
namespace app; |
|||
|
|||
use think\App; |
|||
use think\Container; |
|||
use think\exception\HttpResponseException; |
|||
use think\exception\ValidateException; |
|||
use think\Response; |
|||
use think\Validate; |
|||
|
|||
/** |
|||
* 控制器基础类 |
|||
*/ |
|||
abstract class BaseController |
|||
{ |
|||
/** |
|||
* Request实例 |
|||
* @var \think\Request |
|||
*/ |
|||
protected $request; |
|||
|
|||
/** |
|||
* 应用实例 |
|||
* @var \think\App |
|||
*/ |
|||
protected $app; |
|||
|
|||
/** |
|||
* 是否批量验证 |
|||
* @var bool |
|||
*/ |
|||
protected $batchValidate = false; |
|||
|
|||
/** |
|||
* 构造方法 |
|||
* @access public |
|||
* @param App $app 应用对象 |
|||
*/ |
|||
public function __construct(App $app) |
|||
{ |
|||
$this->app = $app; |
|||
$this->request = $this->app->request; |
|||
// 控制器初始化
|
|||
$this->initialize(); |
|||
} |
|||
|
|||
// 初始化
|
|||
protected function initialize() |
|||
{ |
|||
// 允许跨域
|
|||
$this->cors(); |
|||
} |
|||
|
|||
public function cors() |
|||
{ |
|||
header("access-control-allow-headers: Accept,Authorization,Cache-Control,Content-Type,DNT,If-Modified-Since,Keep-Alive,Origin,Login-Agent,X-Mx-ReqToken,X-Requested-With"); |
|||
header("access-control-allow-methods: GET, POST, PUT, DELETE, HEAD, OPTIONS,PATCH"); |
|||
header("access-control-allow-credentials: true"); |
|||
header("access-control-allow-origin: *"); |
|||
} |
|||
|
|||
/** |
|||
* 验证数据 |
|||
* @access protected |
|||
* @param array $data 数据 |
|||
* @param string|array $validate 验证器名或者验证规则数组 |
|||
* @param array $message 提示信息 |
|||
* @param bool $batch 是否批量验证 |
|||
* @return array|string|true |
|||
* @throws ValidateException |
|||
*/ |
|||
protected function validate(array $data, $validate, array $message = [], bool $batch = false) |
|||
{ |
|||
if (is_array($validate)) { |
|||
$v = new Validate(); |
|||
$v->rule($validate); |
|||
} else { |
|||
if (strpos($validate, '.')) { |
|||
// 支持场景
|
|||
[$validate, $scene] = explode('.', $validate); |
|||
} |
|||
$class = false !== strpos($validate, '\\') ? $validate : $this->app->parseClass('validate', $validate); |
|||
$v = new $class(); |
|||
if (!empty($scene)) { |
|||
$v->scene($scene); |
|||
} |
|||
} |
|||
|
|||
$v->message($message); |
|||
|
|||
// 是否批量验证
|
|||
if ($batch || $this->batchValidate) { |
|||
$v->batch(true); |
|||
} |
|||
|
|||
return $v->failException(true)->check($data); |
|||
} |
|||
|
|||
/** |
|||
* 获取当前的response 输出类型 |
|||
* @access protected |
|||
* @return string |
|||
*/ |
|||
protected function getResponseType(): string |
|||
{ |
|||
if (!$this->app) { |
|||
$this->app = Container::get('app'); |
|||
} |
|||
|
|||
$isAjax = $this->request->isAjax(); |
|||
|
|||
return $isAjax || $this->request->isJson() |
|||
? 'json' |
|||
: 'html'; |
|||
} |
|||
} |
|||
@ -0,0 +1,82 @@ |
|||
<?php |
|||
namespace app; |
|||
|
|||
use app\exception\AuthException; |
|||
use app\exception\BadSysSettingException; |
|||
use app\exception\BaseException; |
|||
use app\exception\ModelException; |
|||
use app\exception\ModelNotUniqueException; |
|||
use app\exception\TokenException; |
|||
use think\db\exception\DataNotFoundException; |
|||
use think\db\exception\ModelNotFoundException; |
|||
use think\exception\Handle; |
|||
use think\exception\HttpException; |
|||
use think\exception\HttpResponseException; |
|||
use think\exception\ValidateException; |
|||
use think\facade\Log; |
|||
use think\Response; |
|||
use Throwable; |
|||
|
|||
/** |
|||
* 应用异常处理类 |
|||
*/ |
|||
class ExceptionHandle extends Handle |
|||
{ |
|||
/** |
|||
* 不需要记录信息(日志)的异常类列表 |
|||
* @var array |
|||
*/ |
|||
protected $ignoreReport = [ |
|||
HttpException::class, |
|||
HttpResponseException::class, |
|||
ModelNotFoundException::class, |
|||
DataNotFoundException::class, |
|||
ValidateException::class, |
|||
]; |
|||
|
|||
/** |
|||
* 记录异常信息(包括日志或者其它方式记录) |
|||
* |
|||
* @access public |
|||
* @param Throwable $exception |
|||
* @return void |
|||
*/ |
|||
public function report(Throwable $exception): void |
|||
{ |
|||
// 使用内置的方式记录异常日志
|
|||
parent::report($exception); |
|||
} |
|||
|
|||
/** |
|||
* Render an exception into an HTTP response. |
|||
* |
|||
* @access public |
|||
* @param \think\Request $request |
|||
* @param Throwable $e |
|||
* @return Response |
|||
*/ |
|||
public function render($request, Throwable $e): Response |
|||
{ |
|||
// 详细错误日志写入文件
|
|||
Log::error($e->getMessage()); |
|||
$str = $this->formatterTraceStr($e); |
|||
Log::error($str); |
|||
if(request()->isAjax() || request()->isJson() || env('APP_DEBUG') == 1){ |
|||
// 添加自定义异常处理机制
|
|||
return jsonReturn($e->getCode() ?: -1, $e->getMessage()); |
|||
} |
|||
|
|||
// 其他错误交给系统处理
|
|||
return parent::render($request, $e); |
|||
} |
|||
|
|||
public function formatterTraceStr(Throwable $e): string |
|||
{ |
|||
$str = "=========手动记录日志=============\n" ; |
|||
$str .= '请求的API是【' . request()->url() . "】\n"; |
|||
$str .= '请求携带的参数是【' . json_encode(request() -> param()) . "】\n"; |
|||
$str .= $e->getTraceAsString(); |
|||
$str .= "\n【".date('Y-m-d H:i:s') . "】=========日志记录结束============="; |
|||
return $str; |
|||
} |
|||
} |
|||
@ -0,0 +1,309 @@ |
|||
<?php |
|||
|
|||
|
|||
namespace app; |
|||
|
|||
use app\model\AdminMenu; |
|||
use think\facade\Cache; |
|||
use think\facade\Db; |
|||
use think\View; |
|||
|
|||
/** |
|||
* 插件类 |
|||
*/ |
|||
abstract class Plugin |
|||
{ |
|||
/** |
|||
* 视图实例对象 |
|||
* @var view |
|||
* @access protected |
|||
*/ |
|||
private $view = null; |
|||
|
|||
public static $vendorLoaded = []; |
|||
|
|||
/** |
|||
* $info = array( |
|||
* 'name'=>'HelloWorld', |
|||
* 'title'=>'HelloWorld', |
|||
* 'description'=>'HelloWorld', |
|||
* 'status'=>1, |
|||
* 'author'=>'ThinkCMF', |
|||
* 'version'=>'1.0' |
|||
* ) |
|||
*/ |
|||
public $info = []; |
|||
private $pluginPath = ''; |
|||
private $name = ''; |
|||
private $configFilePath = ''; |
|||
private $themeRoot = ""; |
|||
|
|||
/** |
|||
* Plugin constructor. |
|||
*/ |
|||
public function __construct() |
|||
{ |
|||
|
|||
$this->name = $this->getName(); |
|||
|
|||
$nameCStyle = parse_name($this->name); |
|||
|
|||
$this->pluginPath = CMS_ROOT . 'plugins/' . $nameCStyle . '/'; |
|||
$this->configFilePath = $this->pluginPath . 'config.php'; |
|||
|
|||
if (empty(self::$vendorLoaded[$this->name])) { |
|||
$pluginVendorAutoLoadFile = $this->pluginPath . 'vendor/autoload.php'; |
|||
if (file_exists($pluginVendorAutoLoadFile)) { |
|||
require_once $pluginVendorAutoLoadFile; |
|||
} |
|||
|
|||
self::$vendorLoaded[$this->name] = true; |
|||
} |
|||
|
|||
$config = $this->getConfig(); |
|||
|
|||
$theme = isset($config['theme']) ? $config['theme'] : ''; |
|||
|
|||
//$depr = "/";
|
|||
|
|||
$root = hcGetRoot(); |
|||
|
|||
$themeDir = empty($theme) ? "" : '/' . $theme; |
|||
|
|||
$themePath = 'view' . $themeDir; |
|||
|
|||
$this->themeRoot = $this->pluginPath . $themePath . '/'; |
|||
|
|||
$pluginRoot = "plugins/{$nameCStyle}"; |
|||
|
|||
$cmfAdminThemePath = config('template.cmf_admin_theme_path'); |
|||
$cmfAdminDefaultTheme = config('template.cmf_admin_default_theme'); |
|||
|
|||
$adminThemePath = "{$cmfAdminThemePath}{$cmfAdminDefaultTheme}"; |
|||
|
|||
$replaceConfig = [ |
|||
'__ROOT__' => $root, |
|||
'__PLUGIN_TMPL__' => $root . '/' . $pluginRoot . '/' . $themePath, |
|||
'__PLUGIN_ROOT__' => $root . '/' . $pluginRoot, |
|||
'__ADMIN_TMPL__' => "{$root}/{$adminThemePath}", |
|||
'__STATIC__' => "{$root}/static", |
|||
'__WEB_ROOT__' => $root |
|||
]; |
|||
|
|||
$app = app(); |
|||
$view = new View($app); |
|||
|
|||
$this->view = $view; |
|||
|
|||
$this->view->engine()->config([ |
|||
'view_base' => $this->themeRoot, |
|||
'tpl_replace_string' => $replaceConfig |
|||
]); |
|||
|
|||
//加载多语言
|
|||
$langSet = $app->lang->getLangSet(); |
|||
$lang_file = $this->pluginPath . "lang/" . $langSet . ".php"; |
|||
$app->lang->load($lang_file); |
|||
|
|||
} |
|||
|
|||
/** |
|||
* 加载模板输出 |
|||
* @access protected |
|||
* @param string $template 模板文件名 |
|||
* @return string |
|||
* @throws \Exception |
|||
*/ |
|||
final protected function fetch($template) |
|||
{ |
|||
if (!is_file($template)) { |
|||
$engineConfig = config('view'); |
|||
$template = $this->themeRoot . $template . '.' . $engineConfig['view_suffix']; |
|||
} |
|||
|
|||
// 模板不存在 抛出异常
|
|||
if (!is_file($template)) { |
|||
throw new TemplateNotFoundException('template not exists:' . $template, $template); |
|||
} |
|||
|
|||
return $this->view->fetch($template); |
|||
} |
|||
|
|||
/** |
|||
* 渲染内容输出 |
|||
* @access protected |
|||
* @param string $content 模板内容 |
|||
* @return mixed |
|||
*/ |
|||
final protected function display($content = '') |
|||
{ |
|||
return $this->view->display($content); |
|||
} |
|||
|
|||
/** |
|||
* 模板变量赋值 |
|||
* @access protected |
|||
* @param mixed $name 要显示的模板变量 |
|||
* @param mixed $value 变量的值 |
|||
* @return void |
|||
*/ |
|||
final protected function assign($name, $value = '') |
|||
{ |
|||
$this->view->assign($name, $value); |
|||
} |
|||
|
|||
/** |
|||
* 获取插件名 |
|||
* @return string |
|||
*/ |
|||
final public function getName() |
|||
{ |
|||
if (empty($this->name)) { |
|||
$class = get_class($this); |
|||
|
|||
$this->name = substr($class, strrpos($class, '\\') + 1, -6); |
|||
} |
|||
|
|||
return $this->name; |
|||
|
|||
} |
|||
|
|||
/** |
|||
* 检查插件信息完整性 |
|||
* @return bool |
|||
*/ |
|||
final public function checkInfo() |
|||
{ |
|||
$infoCheckKeys = ['name', 'title', 'description', 'status', 'author', 'version']; |
|||
foreach ($infoCheckKeys as $value) { |
|||
if (!array_key_exists($value, $this->info)) |
|||
return false; |
|||
} |
|||
return true; |
|||
} |
|||
|
|||
/** |
|||
* 获取插件根目录绝对路径 |
|||
* @return string |
|||
*/ |
|||
final public function getPluginPath() |
|||
{ |
|||
|
|||
return $this->pluginPath; |
|||
} |
|||
|
|||
/** |
|||
* 获取插件配置文件绝对路径 |
|||
* @return string |
|||
*/ |
|||
final public function getConfigFilePath() |
|||
{ |
|||
return $this->configFilePath; |
|||
} |
|||
|
|||
/** |
|||
* |
|||
* @return string |
|||
*/ |
|||
final public function getThemeRoot() |
|||
{ |
|||
return $this->themeRoot; |
|||
} |
|||
|
|||
/** |
|||
* @return View |
|||
*/ |
|||
public function getView() |
|||
{ |
|||
return $this->view; |
|||
} |
|||
|
|||
/** |
|||
* 获取插件的配置数组 |
|||
* @return array |
|||
*/ |
|||
final public function getConfig() |
|||
{ |
|||
$name = $this->getName(); |
|||
|
|||
if (PHP_SAPI != 'cli') { |
|||
static $_config = []; |
|||
if (isset($_config[$name])) { |
|||
return $_config[$name]; |
|||
} |
|||
} |
|||
$pluginCofingKey = 'cmf_'.$name.'_plugin_config'; |
|||
if (Cache::has($pluginCofingKey)){ |
|||
return Cache::get($pluginCofingKey); |
|||
} |
|||
$ttl = mt_rand(600,6000); |
|||
$config = Db::name('plugin')->cache('cmf_'.$name.'_plugin_config_db',$ttl)->where('name', $name)->value('config'); |
|||
|
|||
if (!empty($config) && $config != "null") { |
|||
$config = json_decode($config, true); |
|||
} else { |
|||
$config = $this->getDefaultConfig(); |
|||
} |
|||
Cache::set($pluginCofingKey,$config,$ttl); |
|||
$_config[$name] = $config; |
|||
return $config; |
|||
} |
|||
|
|||
/** |
|||
* 获取插件的配置数组 |
|||
* @return array |
|||
*/ |
|||
final public function getDefaultConfig() |
|||
{ |
|||
$config = []; |
|||
if (file_exists($this->configFilePath)) { |
|||
$tempArr = include $this->configFilePath; |
|||
if (!empty($tempArr) && is_array($tempArr)) { |
|||
foreach ($tempArr as $key => $value) { |
|||
if ($value['type'] == 'group') { |
|||
foreach ($value['options'] as $gkey => $gvalue) { |
|||
foreach ($gvalue['options'] as $ikey => $ivalue) { |
|||
$config[$ikey] = $ivalue['value']; |
|||
} |
|||
} |
|||
} else { |
|||
$config[$key] = $tempArr[$key]['value']; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
return $config; |
|||
} |
|||
|
|||
protected function installSql() |
|||
{ |
|||
//执行安装sql
|
|||
$dbConfig = env(); |
|||
$sqlArr = hcSplitSql($this->pluginPath . '/install.sql', $dbConfig['DATABASE_PREFIX'], $dbConfig['DATABASE_CHARSET']); |
|||
$db = Db::connect(); |
|||
foreach ($sqlArr as $sql) { |
|||
$sqlToExec = $sql . ';'; |
|||
$result = sp_execute_sql($db, $sqlToExec); |
|||
if (!empty($result['error'])) { |
|||
return false; |
|||
} |
|||
} |
|||
return true; |
|||
} |
|||
|
|||
public function editMenu($type = 1, $remark = '') { |
|||
$adminMenuModel = new AdminMenu(); |
|||
if ($type == 1) { //安装
|
|||
$adminMenuModel->where('remark', $remark)->update(['status' => 1]); |
|||
} else {//卸载
|
|||
$adminMenuModel->where('remark', $remark)->update(['status' => 2]); |
|||
} |
|||
} |
|||
|
|||
//必须实现安装
|
|||
abstract public function install(); |
|||
|
|||
//必须卸载插件方法
|
|||
abstract public function uninstall(); |
|||
} |
|||
@ -0,0 +1,8 @@ |
|||
<?php |
|||
namespace app; |
|||
|
|||
// 应用请求对象类
|
|||
class Request extends \think\Request |
|||
{ |
|||
|
|||
} |
|||
@ -0,0 +1,101 @@ |
|||
<?php |
|||
|
|||
namespace app\command; |
|||
|
|||
use think\console\Command; |
|||
use think\console\Input; |
|||
use think\console\Output; |
|||
use think\facade\Db; |
|||
|
|||
class BaiduTongji extends Command |
|||
{ |
|||
protected function configure() |
|||
{ |
|||
$this->setName('baiduTongji') |
|||
->setDescription('百度统计'); |
|||
} |
|||
|
|||
protected function execute(Input $input, Output $output) |
|||
{ |
|||
set_time_limit(0); |
|||
ini_set('memory_limit', '512M'); |
|||
|
|||
/*************************************** 百度统计开始 ************************************************/ |
|||
$url = 'http://api.baidu.com/json/tongji/v1/ReportService/getData'; |
|||
$listUrl = 'https://api.baidu.com/json/tongji/v1/ReportService/getSiteList'; |
|||
|
|||
$accountList = Db::name('seo_account')->field('account,password,token')->where("type=1")->selectOrFail(); |
|||
|
|||
$insertData = [ |
|||
'pv_count' => 0, |
|||
'uv_count' => 0, |
|||
'ip_count' => 0, |
|||
'avg_visit_time' => 0 |
|||
]; |
|||
$totalNum = 0; |
|||
|
|||
foreach ($accountList as $vo) { |
|||
|
|||
$header = [ |
|||
'account_type' => '1', |
|||
'username' => $vo['account'], |
|||
'password' => $vo['password'], |
|||
'token' => $vo['token'], |
|||
]; |
|||
|
|||
$lists = curlPost($listUrl, json_encode(['header' => $header])); |
|||
$website = json_decode($lists['data'], true); |
|||
|
|||
if (empty($website['header']['failures'])) { |
|||
$website = $website['body']['data']['0']['list']; |
|||
} |
|||
|
|||
if (!empty($website)) { |
|||
foreach ($website as $k => $v) { |
|||
|
|||
$totalNum++; |
|||
$info = curlPost($url, json_encode([ |
|||
'body' => [ |
|||
"site_id"=> $v['site_id'], |
|||
"method" => "overview/getOutline" |
|||
], |
|||
'header' => $header |
|||
]))['data']; |
|||
|
|||
$info = json_decode($info, true); |
|||
if (empty($info['body']['data'])) { |
|||
continue; |
|||
} |
|||
|
|||
$info = $info['body']['data']['0']['result']; |
|||
|
|||
if (isset($info['items']['1'])) { |
|||
if (is_numeric($info['items']['1']['1'])) { |
|||
$insertData['pv_count'] += $info['items']['1']['1']; |
|||
} |
|||
|
|||
if (is_numeric($info['items']['1']['2'])) { |
|||
$insertData['uv_count'] += $info['items']['1']['2']; |
|||
} |
|||
|
|||
if (is_numeric($info['items']['1']['3'])) { |
|||
$insertData['ip_count'] += $info['items']['1']['3']; |
|||
} |
|||
|
|||
if (is_numeric($info['items']['1']['5'])) { |
|||
$insertData['avg_visit_time'] += $info['items']['1']['5']; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
if ($totalNum != 0) { |
|||
$insertData['avg_visit_time'] = round($insertData['avg_visit_time'] / $totalNum); |
|||
} |
|||
|
|||
$insertData['count_date'] = date('Y-m-d', strtotime('-1 day')); |
|||
Db::name('baidu_tj_gather')->insert($insertData); |
|||
/*************************************** 百度统计结束 ************************************************/ |
|||
} |
|||
} |
|||
@ -0,0 +1,61 @@ |
|||
<?php |
|||
declare (strict_types = 1); |
|||
|
|||
namespace app\command; |
|||
|
|||
use think\console\command\Make; |
|||
use think\console\input\Option; |
|||
use think\console\input\Argument; |
|||
|
|||
class CreateController extends Make |
|||
{ |
|||
protected $type = "Controller"; |
|||
|
|||
protected function configure() |
|||
{ |
|||
// 指令配置
|
|||
$this->setName('make:hc-controller') |
|||
->addArgument('name', Argument::OPTIONAL, "controller path") |
|||
->setDescription('create a HuoCms controller command'); |
|||
} |
|||
|
|||
protected function getStub(): string |
|||
{ |
|||
$stubPath = __DIR__ . DIRECTORY_SEPARATOR . 'stubs' . DIRECTORY_SEPARATOR; |
|||
|
|||
return $stubPath . 'controller.stub'; |
|||
} |
|||
|
|||
protected function getClassName(string $name): string |
|||
{ |
|||
return parent::getClassName($name) . ($this->app->config->get('route.controller_suffix') ? 'Controller' : ''); |
|||
} |
|||
|
|||
protected function getNamespace(string $app): string |
|||
{ |
|||
return parent::getNamespace($app) . '\\controller'; |
|||
} |
|||
|
|||
protected function buildClass(string $name) |
|||
{ |
|||
$stub = file_get_contents($this->getStub()); |
|||
|
|||
$namespace = trim(implode('\\', array_slice(explode('\\', $name), 0, -1)), '\\'); |
|||
|
|||
$class = str_replace($namespace . '\\', '', $name); |
|||
|
|||
$modelName = str_replace(($this->app->config->get('route.controller_suffix') ? 'Controller' : ''),'',$class); |
|||
|
|||
$funcParam = lcfirst($modelName); |
|||
|
|||
|
|||
return str_replace(['{%className%}', '{%actionSuffix%}', '{%namespace%}', '{%app_namespace%}','{%modelInstance%}','{%modelName%}'], [ |
|||
$class, |
|||
$this->app->config->get('route.action_suffix'), |
|||
$namespace, |
|||
$this->app->getNamespace(), |
|||
$funcParam, |
|||
$modelName, |
|||
], $stub); |
|||
} |
|||
} |
|||
@ -0,0 +1,53 @@ |
|||
<?php |
|||
declare (strict_types = 1); |
|||
|
|||
namespace app\command; |
|||
|
|||
use think\console\Command; |
|||
use think\console\Input; |
|||
use think\console\input\Argument; |
|||
use think\console\input\Option; |
|||
use think\console\Output; |
|||
|
|||
class CreateLink extends Command |
|||
{ |
|||
protected function configure() |
|||
{ |
|||
// 指令配置
|
|||
$this->setName('admin-view:link') |
|||
->setDescription('the app\command\createLink command'); |
|||
} |
|||
|
|||
protected function execute(Input $input, Output $output) |
|||
{ |
|||
foreach ($this->links() as $link => $target) { |
|||
if (file_exists($link)) { |
|||
$output->writeln('<error>' . $link . ' already exists!</error>'); |
|||
} else { |
|||
$this->createLink($target, $link); |
|||
|
|||
$output->writeln('<info>' . $link . ' created successfully.</info>'); |
|||
} |
|||
} |
|||
|
|||
$output->writeln('The links have been created.'); |
|||
} |
|||
|
|||
protected function links(): array |
|||
{ |
|||
return ['public/view' => app()->getRootPath() .'view/']; |
|||
} |
|||
|
|||
public function createLink($target,$link): bool |
|||
{ |
|||
|
|||
if (! windows_os()) { |
|||
return symlink($target, $link); |
|||
} |
|||
|
|||
$mode = is_directory($target) ? 'J' : 'H'; |
|||
|
|||
exec("mklink /{$mode} ".escapeshellarg($link).' '.escapeshellarg($target)); |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,28 @@ |
|||
<?php |
|||
declare (strict_types = 1); |
|||
|
|||
namespace app\command; |
|||
|
|||
use think\console\command\Make; |
|||
use think\console\input\Argument; |
|||
|
|||
class CreateModel extends Make |
|||
{ |
|||
protected function configure() |
|||
{ |
|||
// 指令配置
|
|||
$this->setName('make:hc-model') |
|||
->addArgument('name', Argument::OPTIONAL, "model path") |
|||
->setDescription('create a new model class with five base function'); |
|||
} |
|||
|
|||
protected function getStub(): string |
|||
{ |
|||
return __DIR__ . DIRECTORY_SEPARATOR . 'stubs' . DIRECTORY_SEPARATOR . 'model.stub'; |
|||
} |
|||
|
|||
protected function getNamespace(string $app): string |
|||
{ |
|||
return parent::getNamespace($app) . '\\model'; |
|||
} |
|||
} |
|||
@ -0,0 +1,59 @@ |
|||
<?php |
|||
|
|||
namespace app\command; |
|||
|
|||
use app\command\service\Server; |
|||
use app\command\service\TaskServer; |
|||
use app\command\service\TongJiServer; |
|||
use think\console\Command; |
|||
use think\console\Input; |
|||
use think\console\input\Argument; |
|||
use think\console\input\Option; |
|||
use think\console\Output; |
|||
|
|||
class WebDiagnosis extends Command |
|||
{ |
|||
protected function configure() |
|||
{ |
|||
$this->setName('seo:check') |
|||
->addArgument('action', Argument::OPTIONAL, "start|stop|restart|reload|status|connections", 'start') |
|||
->addOption('host', 'H', Option::VALUE_OPTIONAL, 'the host of workerman service.', null) |
|||
->addOption('port', 'p', Option::VALUE_OPTIONAL, 'the port of workerman service.', null) |
|||
->addOption('daemon', 'd', Option::VALUE_NONE, 'Run the workerman service in daemon mode.') |
|||
->setDescription('网站诊断服务器'); |
|||
} |
|||
|
|||
protected function execute(Input $input, Output $output) |
|||
{ |
|||
$action = $input->getArgument('action'); |
|||
|
|||
if (DIRECTORY_SEPARATOR !== '\\') { |
|||
if (!in_array($action, ['start', 'stop', 'reload', 'restart', 'status', 'connections'])) { |
|||
$output->writeln("<error>Invalid argument action:{$action}, Expected start|stop|restart|reload|status|connections .</error>"); |
|||
return false; |
|||
} |
|||
|
|||
global $argv; |
|||
array_shift($argv); |
|||
array_shift($argv); |
|||
array_shift($argv); |
|||
array_unshift($argv, 'think', $action); |
|||
} |
|||
|
|||
$logo = <<<EOL |
|||
_____ ______ ____ _____ _ _ ______ _____ _ __ |
|||
/ ____ | ____ / __ \ / ____ | | | | | ____ / ____ | |/ / |
|||
| (___ | |__ | | | | | | | |__| | | |__ | | | ' / |
|||
\___ \ | __| | | | | | | | __ | | __| | | | < |
|||
____) | |___ | |__| | | |____ | | | | | |___ | |____ | . \ |
|||
|_____/ |______ \____/ \_____ |_| |_| |______ \_____ |_|\_\ |
|||
EOL; |
|||
$output->writeln($logo . PHP_EOL); |
|||
|
|||
if (!(strtoupper(substr(PHP_OS,0,3))==='WIN')) { |
|||
TongJiServer::start(); |
|||
TaskServer::start(); |
|||
} |
|||
Server::start(); |
|||
} |
|||
} |
|||
@ -0,0 +1,55 @@ |
|||
<?php |
|||
|
|||
namespace app\command; |
|||
|
|||
use app\command\service\Server; |
|||
use app\command\service\TaskServer; |
|||
use app\command\service\TongJiServer; |
|||
use think\console\Command; |
|||
use think\console\Input; |
|||
use think\console\input\Argument; |
|||
use think\console\input\Option; |
|||
use think\console\Output; |
|||
|
|||
class WebDiagnosis2 extends Command |
|||
{ |
|||
protected function configure() |
|||
{ |
|||
$this->setName('seo:check2') |
|||
->addArgument('action', Argument::OPTIONAL, "start|stop|restart|reload|status|connections", 'start') |
|||
->addOption('host', 'H', Option::VALUE_OPTIONAL, 'the host of workerman service.', null) |
|||
->addOption('port', 'p', Option::VALUE_OPTIONAL, 'the port of workerman service.', null) |
|||
->addOption('daemon', 'd', Option::VALUE_NONE, 'Run the workerman service in daemon mode.') |
|||
->setDescription('网站诊断服务器'); |
|||
} |
|||
|
|||
protected function execute(Input $input, Output $output) |
|||
{ |
|||
$action = $input->getArgument('action'); |
|||
|
|||
if (DIRECTORY_SEPARATOR !== '\\') { |
|||
if (!in_array($action, ['start', 'stop', 'reload', 'restart', 'status', 'connections'])) { |
|||
$output->writeln("<error>Invalid argument action:{$action}, Expected start|stop|restart|reload|status|connections .</error>"); |
|||
return false; |
|||
} |
|||
|
|||
global $argv; |
|||
array_shift($argv); |
|||
array_shift($argv); |
|||
array_shift($argv); |
|||
array_unshift($argv, 'think', $action); |
|||
} |
|||
|
|||
$logo = <<<EOL |
|||
_____ ______ ____ _____ _ _ ______ _____ _ __ |
|||
/ ____ | ____ / __ \ / ____ | | | | | ____ / ____ | |/ / |
|||
| (___ | |__ | | | | | | | |__| | | |__ | | | ' / |
|||
\___ \ | __| | | | | | | | __ | | __| | | | < |
|||
____) | |___ | |__| | | |____ | | | | | |___ | |____ | . \ |
|||
|_____/ |______ \____/ \_____ |_| |_| |______ \_____ |_|\_\ |
|||
EOL; |
|||
$output->writeln($logo . PHP_EOL); |
|||
|
|||
TongJiServer::start(); |
|||
} |
|||
} |
|||
@ -0,0 +1,55 @@ |
|||
<?php |
|||
|
|||
namespace app\command; |
|||
|
|||
use app\command\service\Server; |
|||
use app\command\service\TaskServer; |
|||
use app\command\service\TongJiServer; |
|||
use think\console\Command; |
|||
use think\console\Input; |
|||
use think\console\input\Argument; |
|||
use think\console\input\Option; |
|||
use think\console\Output; |
|||
|
|||
class WebDiagnosis3 extends Command |
|||
{ |
|||
protected function configure() |
|||
{ |
|||
$this->setName('seo:check3') |
|||
->addArgument('action', Argument::OPTIONAL, "start|stop|restart|reload|status|connections", 'start') |
|||
->addOption('host', 'H', Option::VALUE_OPTIONAL, 'the host of workerman service.', null) |
|||
->addOption('port', 'p', Option::VALUE_OPTIONAL, 'the port of workerman service.', null) |
|||
->addOption('daemon', 'd', Option::VALUE_NONE, 'Run the workerman service in daemon mode.') |
|||
->setDescription('网站诊断服务器'); |
|||
} |
|||
|
|||
protected function execute(Input $input, Output $output) |
|||
{ |
|||
$action = $input->getArgument('action'); |
|||
|
|||
if (DIRECTORY_SEPARATOR !== '\\') { |
|||
if (!in_array($action, ['start', 'stop', 'reload', 'restart', 'status', 'connections'])) { |
|||
$output->writeln("<error>Invalid argument action:{$action}, Expected start|stop|restart|reload|status|connections .</error>"); |
|||
return false; |
|||
} |
|||
|
|||
global $argv; |
|||
array_shift($argv); |
|||
array_shift($argv); |
|||
array_shift($argv); |
|||
array_unshift($argv, 'think', $action); |
|||
} |
|||
|
|||
$logo = <<<EOL |
|||
_____ ______ ____ _____ _ _ ______ _____ _ __ |
|||
/ ____ | ____ / __ \ / ____ | | | | | ____ / ____ | |/ / |
|||
| (___ | |__ | | | | | | | |__| | | |__ | | | ' / |
|||
\___ \ | __| | | | | | | | __ | | __| | | | < |
|||
____) | |___ | |__| | | |____ | | | | | |___ | |____ | . \ |
|||
|_____/ |______ \____/ \_____ |_| |_| |______ \_____ |_|\_\ |
|||
EOL; |
|||
$output->writeln($logo . PHP_EOL); |
|||
|
|||
TaskServer::start(); |
|||
} |
|||
} |
|||
@ -0,0 +1,30 @@ |
|||
<?php |
|||
namespace app\command\service; |
|||
|
|||
use Workerman\Protocols\Http\Request; |
|||
use \Workerman\Connection\AsyncTcpConnection; |
|||
use Workerman\Connection\TcpConnection; |
|||
use Workerman\Worker; |
|||
|
|||
class Server |
|||
{ |
|||
public static function start() |
|||
{ |
|||
$http_worker = new Worker("http://0.0.0.0:19910"); |
|||
$http_worker->count = 1; |
|||
$http_worker->name = 'task accept'; |
|||
|
|||
$http_worker->onMessage = function(TcpConnection $connection, Request $request) |
|||
{ |
|||
$task_connection = new AsyncTcpConnection('Text://127.0.0.1:19890'); |
|||
$task_connection->send(json_encode($request->post())); |
|||
$task_connection->connect(); |
|||
|
|||
$connection->send(json_encode(['code' => 0, 'data' => '', 'msg' => '任务投递成功'])); |
|||
}; |
|||
|
|||
if(!defined('GLOBAL_START')) { |
|||
Worker::runAll(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,149 @@ |
|||
<?php |
|||
namespace app\command\service; |
|||
|
|||
use app\command\service\step\CheckIncluded; |
|||
use app\command\service\step\CheckKeywords; |
|||
use app\command\service\step\CheckLinks; |
|||
use app\command\service\step\CheckSSL301; |
|||
use app\command\service\step\CheckTplCode; |
|||
use Workerman\Worker; |
|||
use Workerman\Connection\TcpConnection; |
|||
|
|||
class TaskServer |
|||
{ |
|||
public static $db; |
|||
|
|||
public static function start() |
|||
{ |
|||
$taskWorker = new Worker('Text://0.0.0.0:19890'); |
|||
$taskWorker->count = 8; |
|||
$taskWorker->name = 'TaskWorker'; |
|||
|
|||
$taskWorker->onWorkerStart = function (Worker $worker) |
|||
{ |
|||
self::$db = new \Workerman\MySQL\Connection(env('database.hostname'), |
|||
env('database.hostport', 3306), env('database.username'), env('database.password', ''), env('database.database', '')); |
|||
}; |
|||
|
|||
$taskWorker->onMessage = function(TcpConnection $connection, $taskData) |
|||
{ |
|||
$taskData = json_decode($taskData, true); |
|||
|
|||
try { |
|||
switch ($taskData['cmd']) { |
|||
|
|||
case 'code': |
|||
$res = self::codeAnalysis($taskData); |
|||
break; |
|||
case 'web': |
|||
$res = self::webpageAnalysis($taskData); |
|||
break; |
|||
case 'keywords': |
|||
$res = self::keywordsAnalysis($taskData, self::$db); |
|||
break; |
|||
case 'links': |
|||
$res = self::linksAnalysis($taskData, self::$db); |
|||
break; |
|||
case 'article': |
|||
$res = self::articleAnalysis($taskData); |
|||
break; |
|||
|
|||
} |
|||
|
|||
self::$db->update(env('database.prefix') . 'seo_check_task_detail') |
|||
->cols([ |
|||
'remark' => json_encode($res), |
|||
'status' => 2, |
|||
'update_time' => date('Y-m-d H:i:s') |
|||
]) |
|||
->where('task_id=' . $taskData['task_id'] . ' AND code="' . $taskData['cmd'] . '"')->query(); |
|||
|
|||
$has = self::$db->select('id')->from(env('database.prefix') . 'seo_check_task_detail') |
|||
->where('task_id=' . $taskData['task_id'] . ' AND status=1')->row(); |
|||
if (empty($has)) { |
|||
self::$db->update(env('database.prefix') . 'seo_check_task')->cols(array('status'=>'2'))->where("id={$taskData['task_id']}")->query(); |
|||
} |
|||
} catch (\Exception $e) { |
|||
if (strpos($e->getMessage(), '404 Not Found') !== false || strpos($e->getMessage(), '503 Service Temporarily Unavailable') !== false) { |
|||
$connection->send(json_encode(['code' => -1, 'data' => [], 'msg' => '该网站暂时无法访问'])); |
|||
} else { |
|||
$connection->send(json_encode(['code' => -1, 'data' => [], 'msg' => $e->getMessage()])); |
|||
} |
|||
|
|||
return; |
|||
} |
|||
|
|||
$connection->send(json_encode($res)); |
|||
}; |
|||
|
|||
if (strtoupper(substr(PHP_OS,0,3))==='WIN') { |
|||
Worker::runAll(); |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 代码分析 |
|||
* @param $taskData |
|||
* @return array |
|||
*/ |
|||
private static function codeAnalysis($taskData) |
|||
{ |
|||
$analysis = []; |
|||
// 检测301
|
|||
$analysis301 = CheckSSL301::run($taskData); |
|||
// 检测模板代码
|
|||
$analysisTplCode = CheckTplCode::run($taskData); |
|||
|
|||
$analysis = $analysis + $analysis301 + $analysisTplCode; |
|||
|
|||
return dataReturn(101, '代码分析完成', $analysis); |
|||
} |
|||
|
|||
/** |
|||
* 网站收录分析 |
|||
* @param $taskData |
|||
* @return array |
|||
*/ |
|||
private static function webpageAnalysis($taskData) |
|||
{ |
|||
$analysis = CheckIncluded::run($taskData); |
|||
|
|||
return dataReturn(102, '收录分析完成', $analysis); |
|||
} |
|||
|
|||
/** |
|||
* 关键词分析 |
|||
* @param $taskData |
|||
* @param $db |
|||
* @return array |
|||
*/ |
|||
private static function keywordsAnalysis($taskData, $db) |
|||
{ |
|||
$analysis = CheckKeywords::run($taskData, $db); |
|||
|
|||
return dataReturn(103, '关键词分析完成', $analysis); |
|||
} |
|||
|
|||
/** |
|||
* 导入链接分析 |
|||
* @param $taskData |
|||
* @param $db |
|||
* @return array |
|||
*/ |
|||
private static function linksAnalysis($taskData, $db) |
|||
{ |
|||
$analysis = CheckLinks::run($taskData, $db); |
|||
|
|||
return dataReturn(104, '导入链接分析完成', $analysis); |
|||
} |
|||
|
|||
/** |
|||
* 文章分析 |
|||
* @param $taskData |
|||
* @return array |
|||
*/ |
|||
private static function articleAnalysis($taskData) |
|||
{ |
|||
return dataReturn(105, '文章分析完成'); |
|||
} |
|||
} |
|||
@ -0,0 +1,171 @@ |
|||
<?php |
|||
|
|||
namespace app\command\service; |
|||
|
|||
use think\facade\Log; |
|||
use Workerman\Timer; |
|||
use Workerman\Worker; |
|||
|
|||
class TongJiServer |
|||
{ |
|||
public static function start() |
|||
{ |
|||
$task = new Worker(); |
|||
$task->count = 1; |
|||
$task->name = 'pv collect'; |
|||
|
|||
$task->onWorkerStart = function($task) |
|||
{ |
|||
$db = new \Workerman\MySQL\Connection(env('database.hostname'), |
|||
env('database.hostport', 3306), env('database.username'), env('database.password', ''), env('database.database', '')); |
|||
|
|||
/*************************************** 站长之家排名开始 ************************************************/ |
|||
$baiduPcUrl = 'https://apidatav2.chinaz.com/single/baidupc/keywordranking'; |
|||
$baiduMobileUrl = 'https://apidatav2.chinaz.com/single/baidumobile/keywordranking'; |
|||
$pc360Url = 'https://apidatav2.chinaz.com/single/sopc/keywordranking'; |
|||
$sogouMobileUrl = 'https://apidatav2.chinaz.com/single/sogoumobile/keywordranking'; |
|||
file_put_contents('./last_rum_time.log', time()); // 上次执行时间
|
|||
|
|||
$info = $db->select('value')->from(env('database.prefix') . 'sys_setting') |
|||
->where('title="chinaz_token" and seller_id=1')->row(); |
|||
|
|||
if (!empty($info)) { |
|||
$token = $info['value']; |
|||
Timer::add(3600, function () use ($db, $token, $baiduPcUrl, $baiduMobileUrl, $pc360Url, $sogouMobileUrl) { |
|||
if (date('H:i') >= '11:52' || date('H:i') < '11:53') { |
|||
|
|||
$frequency = $db->select('value')->from(env('database.prefix') . 'sys_setting') |
|||
->where('title="keywords_search_time" and seller_id=1')->row(); |
|||
$lastRunTime = file_get_contents('./last_rum_time.log'); |
|||
$canRun = false; |
|||
if ($frequency == 'week') { |
|||
if ((time() - $lastRunTime) / 86400 >= 7) { |
|||
$canRun = true; |
|||
file_put_contents('./last_rum_time.log', time()); |
|||
} |
|||
} elseif($frequency == 'day' && (time() - $lastRunTime) >= 86400) { |
|||
$canRun = true; |
|||
file_put_contents('./last_rum_time.log', time()); |
|||
} else { |
|||
$canRun = true; |
|||
file_put_contents('./last_rum_time.log', time()); |
|||
} |
|||
Log::info('可执行状态:' . $canRun); |
|||
try { |
|||
if ($canRun) { |
|||
Log::info('执行统计开始' . $canRun); |
|||
$keywords = $db->select('id,name,url,website_id,seller_id')->from(env('database.prefix') . 'keyword') |
|||
->where('status=1 and is_del=1')->query(); |
|||
|
|||
foreach ($keywords as $key => $vo) { |
|||
|
|||
$updateData = [ |
|||
'baidu_pc' => 0, |
|||
'baidu_mob' => 0, |
|||
'three_pc' => 0, |
|||
'sougou_mob' => 0 |
|||
]; |
|||
|
|||
// 百度PC
|
|||
$res = curlPost($baiduPcUrl, [ |
|||
'key' => $token, |
|||
'domain' => $vo['url'], |
|||
'keyword' => $vo['name'], |
|||
'top100' => true |
|||
])['data']; |
|||
|
|||
Log::info($vo['name'] . ' 百度PC res>>>>>>>:' . $res); |
|||
$res = json_decode($res, true); |
|||
|
|||
if (!empty($res['Result']['Ranks'])) { |
|||
$rank = explode('-', $res['Result']['Ranks']['0']['RankStr']); |
|||
$updateData['baidu_pc'] = ($rank[0] - 1) * 10 + $rank['1']; |
|||
|
|||
self::writeKeywordsQuery($db, $vo, $res, $rank, 'baidu_pc'); |
|||
} |
|||
|
|||
// 百度移动
|
|||
$res = curlPost($baiduMobileUrl, [ |
|||
'key' => $token, |
|||
'domain' => $vo['url'], |
|||
'keyword' => $vo['name'] |
|||
])['data']; |
|||
|
|||
Log::info($vo['name'] . ' 百度移动 res>>>>>>>:' . $res); |
|||
$res = json_decode($res, true); |
|||
if (!empty($res['Result']['Ranks'])) { |
|||
$rank = explode('-', $res['Result']['Ranks']['0']['RankStr']); |
|||
$updateData['baidu_mob'] = ($rank[0] - 1) * 10 + $rank['1']; |
|||
|
|||
self::writeKeywordsQuery($db, $vo, $res, $rank, 'baidu_mob'); |
|||
} |
|||
|
|||
// 360pc
|
|||
$res = curlPost($pc360Url, [ |
|||
'key' => $token, |
|||
'domain' => $vo['url'], |
|||
'keyword' => $vo['name'] |
|||
])['data']; |
|||
|
|||
Log::info($vo['name'] . ' 360pc res>>>>>>>:' . $res); |
|||
$res = json_decode($res, true); |
|||
if (!empty($res['Result']['Ranks'])) { |
|||
$rank = explode('-', $res['Result']['Ranks']['0']['RankStr']); |
|||
$updateData['three_pc'] = ($rank[0] - 1) * 10 + $rank['1']; |
|||
|
|||
self::writeKeywordsQuery($db, $vo, $res, $rank, 'three_pc'); |
|||
} |
|||
|
|||
// 搜狗移动
|
|||
$res = curlPost($sogouMobileUrl, [ |
|||
'key' => $token, |
|||
'domain' => $vo['url'], |
|||
'keyword' => $vo['name'] |
|||
])['data']; |
|||
|
|||
Log::info($vo['name'] . ' 搜狗移动 res>>>>>>>:' . $res); |
|||
|
|||
$res = json_decode($res, true); |
|||
if (!empty($res['Result']['Ranks'])) { |
|||
$rank = explode('-', $res['Result']['Ranks']['0']['RankStr']); |
|||
$updateData['sougou_mob'] = ($rank[0] - 1) * 10 + $rank['1']; |
|||
|
|||
self::writeKeywordsQuery($db, $vo, $res, $rank, 'sougou_mob'); |
|||
} |
|||
|
|||
$db->update(env('database.prefix') . 'keyword')->cols($updateData)->where('id=' . $vo['id'])->query(); |
|||
} |
|||
} |
|||
} catch (\Exception $e) { |
|||
Log::error($e->getMessage() . '>>>>>> |
|||
' . $e->getTraceAsString()); |
|||
} |
|||
Log::info('执行结束'); |
|||
} |
|||
}); |
|||
|
|||
} |
|||
/*************************************** 站长之家排名结束 ************************************************/ |
|||
}; |
|||
|
|||
if (strtoupper(substr(PHP_OS,0,3))==='WIN') { |
|||
Worker::runAll(); |
|||
} |
|||
} |
|||
|
|||
protected static function writeKeywordsQuery($db, $vo, $res, $rank, $engine) |
|||
{ |
|||
$db->insert(env('database.prefix') . 'keyword_query')->cols([ |
|||
'keyword_id' => $vo['id'], |
|||
'seller_id' => $vo['seller_id'], |
|||
'website_id' => $vo['website_id'], |
|||
'keyword' => $vo['name'], |
|||
'search_engine' => $engine, |
|||
'collect_count' => isset($res['Result']['SiteCount']) ? $res['Result']['SiteCount'] : 0, |
|||
'top_rank' => ($rank[0] - 1) * 10 + $rank['1'], |
|||
'create_time' => time(), |
|||
'page_title' => $res['Result']['Ranks']['0']['Title'] ?? '', |
|||
'page_url' => $res['Result']['Ranks']['0']['Url'] ?? '', |
|||
])->query(); |
|||
} |
|||
} |
|||
@ -0,0 +1,55 @@ |
|||
<?php |
|||
|
|||
namespace app\command\service\step; |
|||
|
|||
use GuzzleHttp\Client; |
|||
|
|||
class CheckIncluded |
|||
{ |
|||
public static function run($taskData) |
|||
{ |
|||
$included = [ |
|||
'status' => 1, |
|||
'count' => 0 |
|||
]; |
|||
|
|||
try { |
|||
|
|||
$client = new Client(); |
|||
$url = 'https://www.baidu.com/s?wd=site%3A' . $taskData['websiteUrl']; |
|||
$jar = new \GuzzleHttp\Cookie\CookieJar(); |
|||
|
|||
$userAgentMap = config('userAgent'); |
|||
$userAgentKey = array_rand($userAgentMap); |
|||
$res = $client->request('GET', $url, [ |
|||
'cookies' => $jar, |
|||
'headers' => [ |
|||
'user-agent' => $userAgentMap[$userAgentKey] |
|||
], |
|||
]); |
|||
|
|||
if ($res->getStatusCode() == 200) { |
|||
$html = \phpQuery::newDocumentHTML($res->getBody()); |
|||
$hasNoInclude = $html['.content_none .nors']->html(); |
|||
if (!empty($hasNoInclude)) { |
|||
$included = [ |
|||
'status' => 2, |
|||
'count' => 0 |
|||
]; |
|||
} else { |
|||
|
|||
$included = [ |
|||
'status' => 1, |
|||
'count' => $html['#content_left .c-span-last p:eq(0) b']->text() |
|||
]; |
|||
} |
|||
} else { |
|||
return $included; |
|||
} |
|||
} catch (\Exception $e) { |
|||
return $included; |
|||
} |
|||
|
|||
return $included; |
|||
} |
|||
} |
|||
@ -0,0 +1,124 @@ |
|||
<?php |
|||
|
|||
namespace app\command\service\step; |
|||
|
|||
use think\facade\Db; |
|||
|
|||
class CheckKeywords |
|||
{ |
|||
public static function run($taskData, $db) |
|||
{ |
|||
$analysis = [ |
|||
'deadLink' => [] |
|||
]; |
|||
$keywords = $taskData['keywords']; |
|||
if (empty($keywords)) { |
|||
return []; |
|||
} |
|||
|
|||
// 处理栏目页
|
|||
$columnPages = $taskData['cate']; |
|||
$cateIds = []; |
|||
$cateId2Alias = []; |
|||
|
|||
$opts = [ |
|||
'http'=> [ |
|||
'method' => "GET", |
|||
'timeout' => 10, |
|||
] |
|||
]; |
|||
$context = stream_context_create($opts); |
|||
|
|||
foreach ($columnPages as $vo) { |
|||
$cateIds[] = $vo['id']; |
|||
$cateId2Alias[$vo['id']] = $vo['alias']; |
|||
|
|||
try { |
|||
|
|||
$nowPageHtml = file_get_contents('http://' . $taskData['websiteUrl'] . $vo['alias'], false, $context); |
|||
echo "查询获取到页面数据" . PHP_EOL; |
|||
$totalWords = self::getCleanContent($nowPageHtml); |
|||
foreach ($keywords as $v) { |
|||
$analysis[$vo['alias']][$v['name']] = round((substr_count($totalWords, $v['name']) |
|||
* mb_strlen($v['name'])) / mb_strlen($totalWords), 4); |
|||
} |
|||
} catch (\Exception $e) { |
|||
echo "获取到死链" . 'http://' . $taskData['websiteUrl'] . $vo['alias'] . PHP_EOL; |
|||
$analysis['deadLink'][] = 'http://' . $taskData['websiteUrl'] . $vo['alias']; |
|||
} |
|||
} |
|||
|
|||
// 处理文章页
|
|||
if (!empty($cateIds)) { |
|||
$pageSize = 20; |
|||
$total = $db->select('count(*) as `c_total`')->from(env('database.prefix') . 'category_sub_content') |
|||
->where("category_id in(" . implode(',', $cateIds) . ")")->row()['c_total']; |
|||
$totalPage = ceil($total / $pageSize); |
|||
for ($nowPage = 1; $nowPage <= $totalPage; $nowPage++) { |
|||
|
|||
$offset = ($nowPage - 1) * $pageSize; |
|||
$articles = $db->select('category_id,sub_content_id')->from(env('database.prefix') . 'category_sub_content') |
|||
->where("category_id in(" . implode(',', $cateIds) . ")")->limit($pageSize)->offset($offset)->query(); |
|||
|
|||
foreach ($articles as $vo) { |
|||
if (isset($cateId2Alias[$vo['category_id']])) { |
|||
|
|||
$url = $cateId2Alias[$vo['category_id']] . '/' . $vo['sub_content_id']; |
|||
|
|||
try { |
|||
$nowPageHtml = file_get_contents('http://' . $taskData['websiteUrl'] . $url, false, $context); |
|||
$totalWords = self::getCleanContent($nowPageHtml); |
|||
foreach ($keywords as $v) { |
|||
$analysis[$url][$v['name']] = round((substr_count($totalWords, $v['name']) * mb_strlen($v['name'])) / mb_strlen($totalWords), 4); |
|||
} |
|||
} catch (\Exception $e) { |
|||
$analysis['deadLink'][] = 'http://' . $taskData['websiteUrl'] . $url; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
|
|||
// 最后统计总数据
|
|||
$analysisFinal = []; |
|||
foreach ($analysis as $key => $vo) { |
|||
if ($key != 'deadLink') { |
|||
$analysisFinal['keywords'][] = '路径 ' . $key . ' 的关键词密度是:' . round(array_sum($vo), 2); |
|||
} else { |
|||
$analysisFinal[$key] = $vo; |
|||
} |
|||
} |
|||
|
|||
return $analysisFinal; |
|||
} |
|||
|
|||
private static function getCleanContent($nowPage) |
|||
{ |
|||
// 获取所有的img的alt
|
|||
$html = \phpQuery::newDocument($nowPage); |
|||
$images = $html['img']; |
|||
$a = $html['a']; |
|||
// 去除js标签内的内容
|
|||
$html['script']->html(''); |
|||
$html['noscript']->html(''); |
|||
$html['style']->html(''); |
|||
|
|||
$imagesAltMap = []; |
|||
foreach ($images as $img) { |
|||
if (!empty(trim(pq($img)->attr('alt')))) { |
|||
$imagesAltMap[] = trim(pq($img)->attr('alt')); |
|||
} |
|||
} |
|||
|
|||
$aTitleMap = []; |
|||
foreach ($a as $item) { |
|||
if (!empty(trim(pq($item)->attr('title')))) { |
|||
$aTitleMap[] = trim(pq($item)->attr('title')); |
|||
} |
|||
} |
|||
|
|||
$cleanWords = trim(str_replace(' ', '', str_replace(PHP_EOL, '', strip_tags($html)))); |
|||
return $cleanWords . implode('', $imagesAltMap) . implode('', $aTitleMap); |
|||
} |
|||
} |
|||
@ -0,0 +1,78 @@ |
|||
<?php |
|||
|
|||
namespace app\command\service\step; |
|||
|
|||
use think\facade\Db; |
|||
|
|||
class CheckLinks |
|||
{ |
|||
public static function run($taskData, $db) |
|||
{ |
|||
$links = $db->select('url,type,position')->from(env('database.prefix') . 'link') |
|||
->where("is_del=1 AND website_id = " . $taskData['websiteId'])->query(); |
|||
|
|||
$inLinks = []; |
|||
$outLinks = []; |
|||
foreach ($links as $vo) { |
|||
|
|||
if ($vo['type'] == 1) { |
|||
|
|||
try { |
|||
$html = file_get_contents($vo['position']); |
|||
if (strstr($html, $vo['url']) == false) { |
|||
$inLinks['linksHave'][] = [ |
|||
'status' => 2, |
|||
'msg' => $vo['position'] . '的友链已经被删除' |
|||
]; |
|||
} else { |
|||
$inLinks['linksHave'][] = [ |
|||
'status' => 1, |
|||
'msg' => $vo['position'] . '的友链正常显示' |
|||
]; |
|||
|
|||
// 检测nofollow
|
|||
$html = \phpQuery::newDocument($html); |
|||
if ($html['a[href="' . $vo['url'] . '"]']->attr('rel') === 'nofollow') { |
|||
$inLinks['nofollow'][] = [ |
|||
'status' => 2, |
|||
'msg' => $vo['position'] . '的友链添加了nofollow' |
|||
]; |
|||
} else { |
|||
$inLinks['nofollow'][] = [ |
|||
'status' => 1, |
|||
'msg' => $vo['position'] . '的友链属性正常' |
|||
]; |
|||
} |
|||
} |
|||
} catch (\Exception $e) { |
|||
$inLinks['linksHave'][] = [ |
|||
'status' => 2, |
|||
'msg' => $vo['position'] . '无法访问' |
|||
]; |
|||
} |
|||
} else if ($vo['type'] == 2) { |
|||
|
|||
try { |
|||
file_get_contents($vo['url']); |
|||
|
|||
$outLinks['linksHave'][] = [ |
|||
'status' => 1, |
|||
'msg' => $vo['url'] . '可以正常访问' |
|||
]; |
|||
} catch (\Exception $e) { |
|||
$outLinks['linksHave'][] = [ |
|||
'status' => 2, |
|||
'msg' => $vo['url'] . '无法访问' |
|||
]; |
|||
} |
|||
} |
|||
} |
|||
|
|||
$analysis = [ |
|||
'inlinks' => $inLinks, |
|||
'outlinks' => $outLinks |
|||
]; |
|||
|
|||
return $analysis; |
|||
} |
|||
} |
|||
@ -0,0 +1,156 @@ |
|||
<?php |
|||
|
|||
namespace app\command\service\step; |
|||
|
|||
use GuzzleHttp\Client; |
|||
|
|||
class CheckSSL301 |
|||
{ |
|||
/** |
|||
* 检测 301 和 ssl |
|||
* @param $taskData |
|||
* @return array |
|||
* @throws \GuzzleHttp\Exception\GuzzleException |
|||
*/ |
|||
public static function run($taskData) |
|||
{ |
|||
$analysis = []; |
|||
$urlMap = explode('.', $taskData['websiteUrl']); |
|||
$client = new Client(); |
|||
|
|||
// 二级域名的情况
|
|||
if (count($urlMap) == 3 && $urlMap[0] != 'www') { |
|||
$analysis['c301'] = [ |
|||
'status' => 2, |
|||
'msg' => '该网站使用的非一级域名,建议使用一级域名' |
|||
]; |
|||
|
|||
$analysis['ssl'] = self::requestWithHttps($client, $taskData); |
|||
|
|||
return $analysis; |
|||
} |
|||
|
|||
// 非二级域名的情况
|
|||
if (count($urlMap) == 3 && $urlMap[0] == 'www') { |
|||
$url = 'http://' . $urlMap['1'] . '.' . $urlMap['2']; |
|||
$domain = $urlMap['1'] . '.' . $urlMap['2']; |
|||
} else { |
|||
$url = 'http://' . $taskData['websiteUrl']; |
|||
$domain = $taskData['websiteUrl']; |
|||
} |
|||
|
|||
$userAgentMap = config('userAgent'); |
|||
$userAgentKey = array_rand($userAgentMap); |
|||
$res = $client->request('GET', $url, [ |
|||
'allow_redirects' => false, |
|||
'headers' => [ |
|||
'user-agent' => $userAgentMap[$userAgentKey] |
|||
], |
|||
]); |
|||
|
|||
// 做了 301 跳转的
|
|||
if ($res->getStatusCode() == 301) { |
|||
// 进一步确认
|
|||
$resHeaders = $res->getHeaders(); |
|||
$location = $resHeaders['Location'][0]; |
|||
|
|||
if (strpos($location, 'https://') !== false) { |
|||
$analysis['ssl'] = [ |
|||
'status' => 1, |
|||
'msg' => '该网站采用了安全的https协议' |
|||
]; |
|||
} else { |
|||
$analysis['ssl'] = [ |
|||
'status' => 2, |
|||
'msg' => '该网站没有采用了安全的https协议' |
|||
]; |
|||
} |
|||
|
|||
$ckDomain = strstr($location, 'www'); |
|||
if ($ckDomain !== false) { |
|||
|
|||
$analysis['c301'] = [ |
|||
'status' => 1, |
|||
'msg' => '该网站采用正确的301跳转方式' |
|||
]; |
|||
|
|||
return $analysis; |
|||
} |
|||
|
|||
// 进一步确认
|
|||
if ($analysis['ssl']['status'] != 1) { |
|||
$analysis['c301'] = [ |
|||
'status' => 2, |
|||
'msg' => '该网站没有采用正确的301跳转方式' |
|||
]; |
|||
|
|||
return $analysis; |
|||
} |
|||
|
|||
// 去请求带https的www域名
|
|||
$res2 = $client->request('GET', 'https://www.' . $domain, [ |
|||
'allow_redirects' => false |
|||
]); |
|||
|
|||
if ($res2->getStatusCode() == 200) { |
|||
$analysis['c301'] = [ |
|||
'status' => 1, |
|||
'msg' => '该网站采用正确的301跳转方式' |
|||
]; |
|||
} else { |
|||
$analysis['c301'] = [ |
|||
'status' => 2, |
|||
'msg' => '该网站没有采用正确的301跳转方式' |
|||
]; |
|||
} |
|||
|
|||
return $analysis; |
|||
} |
|||
|
|||
// 未做 301 跳转的
|
|||
$analysis['c301'] = [ |
|||
'status' => 2, |
|||
'msg' => '该网站没有采用正确的301跳转方式' |
|||
]; |
|||
|
|||
$analysis['ssl'] = self::requestWithHttps($client, $taskData); |
|||
|
|||
return $analysis; |
|||
} |
|||
|
|||
private static function requestWithHttps($client, $taskData) |
|||
{ |
|||
$ssl = []; |
|||
$userAgentMap = config('userAgent'); |
|||
$userAgentKey = array_rand($userAgentMap); |
|||
|
|||
try { |
|||
$res2 = $client->request('GET', 'https://' . $taskData['websiteUrl'], [ |
|||
'allow_redirects' => false, |
|||
'headers' => [ |
|||
'user-agent' => $userAgentMap[$userAgentKey] |
|||
], |
|||
]); |
|||
|
|||
if ($res2->getStatusCode() == 200) { |
|||
$ssl = [ |
|||
'status' => 1, |
|||
'msg' => '该网站采用了安全的https协议' |
|||
]; |
|||
} else { |
|||
$ssl = [ |
|||
'status' => 2, |
|||
'msg' => '该网站没有采用了安全的https协议' |
|||
]; |
|||
} |
|||
} catch (\Exception $e) { |
|||
|
|||
$ssl = [ |
|||
'status' => 2, |
|||
'msg' => '该网站没有采用了安全的https协议' |
|||
]; |
|||
} |
|||
|
|||
return $ssl; |
|||
} |
|||
} |
|||
@ -0,0 +1,136 @@ |
|||
<?php |
|||
|
|||
namespace app\command\service\step; |
|||
|
|||
use think\facade\App; |
|||
|
|||
class CheckTplCode |
|||
{ |
|||
public static function run($taskData) |
|||
{ |
|||
$analysis = [ |
|||
'hn' => [ |
|||
'status' => 1, |
|||
'msg' => [] |
|||
], |
|||
'tags' => [ |
|||
'status' => 1, |
|||
'msg' => [] |
|||
], |
|||
'robots' => [ |
|||
'status' => 1, |
|||
'msg' => 'robots.txt文件正确' |
|||
], |
|||
'sitemap' => [ |
|||
'status' => 1, |
|||
'msg' => 'sitemap文件放置正确' |
|||
], |
|||
'urlLevel' => [ |
|||
'status' => 1, |
|||
'msg' => [] |
|||
], |
|||
'c404' => [ |
|||
'status' => 1, |
|||
'msg' => '404文件放置正确' |
|||
] |
|||
]; |
|||
|
|||
// 目录层级
|
|||
foreach ($taskData['cate'] as $vo) { |
|||
if ($vo['alias'] != '/' && !empty($vo['alias'])) { |
|||
$level = count(array_filter(explode('/', $vo['alias']))); |
|||
if ($level >= 3) { |
|||
$analysis['urlLevel']['status'] = 2; |
|||
$analysis['urlLevel']['msg'][] = $vo['title'] . '页面,url层级太深,达到了' . $level . '层'; |
|||
} |
|||
} |
|||
} |
|||
|
|||
// 404文件
|
|||
$rootPath = App::getRootPath() . 'public'; |
|||
if (!is_file($rootPath . '/system_file/hc_error/404.html')) { |
|||
$analysis['c404']['status'] = 2; |
|||
$analysis['c404']['msg'] = '未正确放置404文件'; |
|||
} |
|||
|
|||
$path = $rootPath . '/themes/website/' . $taskData['websiteId'] . '/' . $taskData['lang'] . '/' . $taskData['theme']; |
|||
if (!is_dir($path)) { |
|||
return $analysis; |
|||
} |
|||
|
|||
$files = scandir($path); |
|||
|
|||
foreach ($files as $value){ |
|||
if($value != '.' && $value != '..' && is_file($path . '/' . $value)){ |
|||
$html = file_get_contents($path . '/' . $value); |
|||
|
|||
// 存在ajax
|
|||
if (strstr($html, '$.ajax') !== false || strstr($html, '$.getJSON') !== false |
|||
|| strstr($html, '$.post') !== false) { |
|||
$analysis['tags']['status'] = 2; |
|||
$analysis['tags']['msg']['ajax'][] = $value . '页面,有ajax异步请求,建议更换。'; |
|||
} |
|||
|
|||
$html = \phpQuery::newDocumentHTML($html); |
|||
|
|||
// 页面为vue.js编写
|
|||
$html['script']->html(''); |
|||
$html['noscript']->html(''); |
|||
$vueJs = str_replace(PHP_EOL, '', trim(strip_tags($html))); |
|||
if (empty($vueJs)) { |
|||
$analysis['tags']['status'] = 2; |
|||
$analysis['tags']['msg']['vuejs'][] = $value . '页面,是Vue.js编写无法收录'; |
|||
} |
|||
|
|||
// 检测h1数量
|
|||
$h1 = $html["h1"]; |
|||
if (count($h1) >= 2) { |
|||
$analysis['hn']['status'] = 2; |
|||
$analysis['hn']['msg']['h1'][] = $value . '有' . count($h1) . '个<h1>标签,数量过多。'; |
|||
} |
|||
|
|||
// 检测iframe框架
|
|||
$iframe = $html["iframe"]; |
|||
if (count($iframe) > 0) { |
|||
$analysis['tags']['status'] = 2; |
|||
$analysis['tags']['msg']['iframe'][] = $value . '页面,存在iframe标签,建议更换。'; |
|||
} |
|||
|
|||
// 检测flash技术
|
|||
$flash = $html["object"]; |
|||
if (count($flash) > 0) { |
|||
$analysis['tags']['status'] = 2; |
|||
$analysis['tags']['msg']['flash'][] = $value . '页面,存在flash标签,建议更换。'; |
|||
} |
|||
|
|||
// alt标签
|
|||
$imgs = $html["img"]; |
|||
foreach($imgs as $imgObj) { |
|||
if (empty(pq($imgObj)->attr('alt'))) { |
|||
$analysis['tags']['status'] = 2; |
|||
$analysis['tags']['msg']['alt'][] = $value . '页面,img标签alt属性缺少或为空'; |
|||
break; |
|||
} |
|||
} |
|||
|
|||
// robots 文件
|
|||
if (!is_file($rootPath . '/robots.txt')) { |
|||
$analysis['robots'] = [ |
|||
'status' => 2, |
|||
'msg' => '未在正确放置robots.txt文件' |
|||
]; |
|||
} |
|||
|
|||
// sitemap
|
|||
if (!is_file($rootPath . '/xml/' . $taskData['websiteId'] . '_sitemap.xml')) { |
|||
$analysis['sitemap'] = [ |
|||
'status' => 2, |
|||
'msg' => '未正确放置sitemap.xml文件' |
|||
]; |
|||
} |
|||
} |
|||
} |
|||
|
|||
return $analysis; |
|||
} |
|||
} |
|||
@ -0,0 +1,138 @@ |
|||
<?php |
|||
declare (strict_types = 1); |
|||
|
|||
namespace {%namespace%}; |
|||
|
|||
use app\model\{%modelName%}; |
|||
use app\validate\{%modelName%}Validate; |
|||
use think\exception\ValidateException; |
|||
|
|||
|
|||
class {%className%} extends BaseController |
|||
{ |
|||
/** |
|||
* 显示资源列表 |
|||
* |
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function index{%actionSuffix%}({%modelName%} ${%modelInstance%}): \think\response\Json |
|||
{ |
|||
$where = [ |
|||
'seller_id' => $this->admin['seller_id'], |
|||
'is_del' => 1, |
|||
]; |
|||
$limit = 10; |
|||
$limitParam = (int)input('limit'); |
|||
if($limitParam){ |
|||
$limit = $limitParam; |
|||
} |
|||
// TODO |
|||
// 添加其他逻辑 |
|||
|
|||
${%modelInstance%}List = ${%modelInstance%}->get{%modelName%}List($where,$limit); |
|||
return json(pageReturn(${%modelInstance%}List)); |
|||
} |
|||
|
|||
/** |
|||
* 保存新建的资源 |
|||
* |
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function save{%actionSuffix%}({%modelName%} ${%modelInstance%}): \think\response\Json |
|||
{ |
|||
if(request()->isPost()){ |
|||
$param = input('post.'); |
|||
// 数据验证 |
|||
try{ |
|||
validate({%modelName%}Validate::class)->scene('save')->check($param); |
|||
}catch(ValidateException $e){ |
|||
return jsonReturn(-1, $e->getError()); |
|||
} |
|||
// TODO |
|||
// 其他逻辑 |
|||
|
|||
$res = ${%modelInstance%} -> add{%modelName%}($param); |
|||
return json($res); |
|||
} |
|||
return jsonReturn(-3,Lang::get('请求方法错误')); |
|||
} |
|||
|
|||
/** |
|||
* 显示指定的资源 |
|||
* |
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
* @throws \app\exception\ModelEmptyException |
|||
*/ |
|||
public function read{%actionSuffix%}({%modelName%} ${%modelInstance%}): \think\response\Json |
|||
{ |
|||
|
|||
$id = (int)input('id'); |
|||
if(!$id){ |
|||
// TODO |
|||
// 修改错误消息 |
|||
return jsonReturn(-1,'ErrorMsg'); |
|||
} |
|||
$where = [ |
|||
'id' => $id, |
|||
'seller_id' => $this->admin['seller_id'] |
|||
]; |
|||
// TODO |
|||
// 其他逻辑 |
|||
$res = ${%modelInstance%}->get{%modelName%}($where); |
|||
return json($res); |
|||
|
|||
} |
|||
|
|||
/** |
|||
* 保存更新的资源 |
|||
|
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function update{%actionSuffix%}({%modelName%} ${%modelInstance%}): \think\response\Json |
|||
{ |
|||
if(request()->isPost()){ |
|||
$param = input('post.'); |
|||
try { |
|||
validate({%modelName%}Validate::class)->scene('update')->check($param); |
|||
} catch (ValidateException $e) { |
|||
return jsonReturn(-1, $e->getError()); |
|||
} |
|||
$where = [ |
|||
'id' => $param['id'], |
|||
'seller_id' => $this->admin['seller_id'], |
|||
'is_del' => 1, |
|||
]; |
|||
$res = ${%modelInstance%} -> update{%modelName%}($where,$param); |
|||
return json($res); |
|||
} |
|||
return jsonReturn(-3,Lang::get('请求方法错误')); |
|||
} |
|||
|
|||
/** |
|||
* 删除指定资源 |
|||
* |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function delete{%actionSuffix%}({%modelName%} ${%modelInstance%}): \think\response\Json |
|||
{ |
|||
if(request()->isPost()){ |
|||
$id = (int)input('id'); |
|||
if(!$id){ |
|||
// TO DO |
|||
// 替换错误提示 |
|||
return jsonReturn(-1,'ErrorMsg'); |
|||
} |
|||
$where = [ |
|||
'id' => $id, |
|||
'seller_id' => $this->admin['seller_id'] |
|||
]; |
|||
$res = ${%modelInstance%}->del{%modelName%}($where); |
|||
return json($res); |
|||
} |
|||
return jsonReturn(-3,Lang::get('请求方法错误')); |
|||
} |
|||
} |
|||
@ -0,0 +1,113 @@ |
|||
<?php |
|||
declare (strict_types = 1); |
|||
|
|||
namespace {%namespace%}; |
|||
|
|||
use app\exception\ModelException; |
|||
use app\exception\ModelEmptyException; |
|||
|
|||
/** |
|||
* @mixin \think\Model |
|||
*/ |
|||
class {%className%} extends Model |
|||
{ |
|||
/** |
|||
* @param array $where |
|||
* @param int $limit |
|||
* @return array |
|||
* @throws ModelException |
|||
*/ |
|||
public function get{%className%}List(array $where = [],int $limit = 10): array |
|||
{ |
|||
try{ |
|||
$res = $this->where($where)->paginate($limit); |
|||
}catch(\Exception $e){ |
|||
throw new ModelException($e->getMessage()); |
|||
} |
|||
return dataReturn($this->sucCode,$this->getMsg,$res); |
|||
|
|||
} |
|||
|
|||
/** |
|||
* @param array $where |
|||
* @return array |
|||
* @throws ModelEmptyException |
|||
* @throws ModelException |
|||
*/ |
|||
public function get{%className%}(array $where = []): array |
|||
{ |
|||
try{ |
|||
$res = $this->where($where)->find(); |
|||
if(empty($res)){ |
|||
throw new ModelEmptyException(); |
|||
} |
|||
}catch(ModelEmptyException $me){ |
|||
throw new ModelEmptyException(); |
|||
}catch(\Exception $e){ |
|||
throw new ModelException($e->getMessage()); |
|||
} |
|||
return dataReturn($this->sucCode,$this->getMsg,$res); |
|||
|
|||
} |
|||
|
|||
/** |
|||
* @param $param |
|||
* @return array |
|||
* @throws ModelException |
|||
*/ |
|||
public function add{%className%}($param): array |
|||
{ |
|||
try{ |
|||
$res = self::create($param); |
|||
}catch(\Exception $e){ |
|||
throw new ModelException($e->getMessage()); |
|||
} |
|||
return dataReturn($this->sucCode,$this->addMsg,$res->id); |
|||
} |
|||
|
|||
/** |
|||
* @param array $where |
|||
* @param array $param |
|||
* @return array |
|||
* @throws ModelException |
|||
*/ |
|||
public function update{%className%}(array $where = [],array $param = []): array |
|||
{ |
|||
try{ |
|||
$res = self::where($where)->update($param); |
|||
}catch(\Exception $e){ |
|||
throw new ModelException($e->getMessage()); |
|||
} |
|||
return dataReturn($this->sucCode,$this->updateMsg,$res); |
|||
} |
|||
|
|||
/** |
|||
* @param $where |
|||
* @return array |
|||
* @throws ModelException |
|||
*/ |
|||
public function softDel{%className%}($where): array |
|||
{ |
|||
try{ |
|||
$res = $this->where($where)->update($this->delData); |
|||
}catch(\Exception $e){ |
|||
throw new ModelException($e->getMessage()); |
|||
} |
|||
return dataReturn($this->sucCode,$this->delMsg,$res); |
|||
} |
|||
|
|||
/** |
|||
* @param $where |
|||
* @return array |
|||
* @throws ModelException |
|||
*/ |
|||
public function del{%className%}($where): array |
|||
{ |
|||
try{ |
|||
$res = $this->where($where)->delete(); |
|||
}catch(\Exception $e){ |
|||
throw new ModelException($e->getMessage()); |
|||
} |
|||
return dataReturn($this->sucCode,$this->delMsg,$res); |
|||
} |
|||
} |
|||
1300
HuoCMS_close_source/app/common.php
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -0,0 +1 @@ |
|||
./* |
|||
@ -0,0 +1,204 @@ |
|||
<?php |
|||
declare (strict_types = 1); |
|||
|
|||
namespace app\controller\backend; |
|||
|
|||
use app\model\PhoneCode; |
|||
use app\model\SysSetting; |
|||
use app\service\PhoneCodeService; |
|||
use app\service\RoleService; |
|||
use app\service\sms\ALiSms; |
|||
use app\validate\LoginValidate; |
|||
use app\model\Admin; |
|||
use think\exception\ValidateException; |
|||
use think\facade\Cache; |
|||
use think\facade\Env; |
|||
use think\facade\Lang; |
|||
|
|||
class AccountController extends \app\BaseController |
|||
{ |
|||
|
|||
/** |
|||
* @param Admin $adminModel |
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelEmptyException |
|||
* @throws \app\exception\ModelException |
|||
* @throws \app\exception\TokenException |
|||
*/ |
|||
public function login(Admin $adminModel): \think\response\Json |
|||
{ |
|||
if (request()->isPost()) { |
|||
$param = request()->only(['account','password']); |
|||
|
|||
$pattern = "/^[\w\.-]+@\w+\.\w+(\.\w+)?$/"; |
|||
if(!env('APP_DEBUG') == true || !(preg_match($pattern,$param['account']) && env('APP_DEBUG') == true)){ |
|||
$param['account'] = $this->RSA_openssl($param['account'], 'decode'); |
|||
$param['password'] = $this->RSA_openssl($param['password'], 'decode'); |
|||
} |
|||
|
|||
// 检验完整性
|
|||
try { |
|||
validate(LoginValidate::class)->scene('login')->check($param); |
|||
} catch (ValidateException $e) { |
|||
return jsonReturn(-1, $e->getError()); |
|||
} |
|||
$where = ['account' => $param['account']]; |
|||
$admin = $adminModel->getAdmin($where,['role'])['data']; |
|||
if (!checkPassword($param['password'], $admin['password'])) { |
|||
return jsonReturn(-2, Lang::get('用户名密码不正确')); |
|||
} |
|||
if ($admin['status'] == 2) { |
|||
return jsonReturn(-3, Lang::get('该账号已经被禁用')); |
|||
} |
|||
|
|||
if ($admin['code_auth'] == 1 && !empty($admin['phone'])) { |
|||
$data = [ |
|||
'phone' => $admin['phone'], |
|||
'code' => random_code_type(6, 'number'), |
|||
'seller_id' => $admin['seller_id'], |
|||
'expired_time' => date('Y-m-d H:i:s', time() + 5 * 60), // 登录验证码5分钟有效
|
|||
]; |
|||
|
|||
//保存发送code记录
|
|||
$codeModel = new PhoneCode(); |
|||
$codeModel->insertGetId([ |
|||
'phone' => $data['phone'], |
|||
'code' => $data['code'], |
|||
'expired_time' => $data['expired_time'] |
|||
]); |
|||
|
|||
Cache::set($admin['phone'] . '_login', time(), 5 * 60); |
|||
if (Env::get('APP_DEBUG')) { |
|||
return jsonReturn(0, 'code_auth', $data); |
|||
} |
|||
|
|||
$res = ALiSms::sendOneAuthMsg($data); |
|||
if ($res['code'] != 0) { |
|||
return json($res); |
|||
} |
|||
return jsonReturn(0, 'code_auth', ['phone' => $admin['phone']]); |
|||
} |
|||
|
|||
return $this->getMenuAndToken($admin); |
|||
} |
|||
return jsonReturn(-1, Lang::get('请求方式错误')); |
|||
} |
|||
|
|||
/** |
|||
* @throws \app\exception\ModelEmptyException |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function authCode(Admin $adminModel): \think\response\Json |
|||
{ |
|||
$param = request()->only(['phone','code']); |
|||
|
|||
$param['phone'] = $this->RSA_openssl($param['phone'], 'decode'); |
|||
$param['code'] = $this->RSA_openssl($param['code'], 'decode'); |
|||
|
|||
$authCodeRes = PhoneCodeService::authCode($param); |
|||
if ($authCodeRes['code'] != 0) { |
|||
return json($authCodeRes); |
|||
} |
|||
|
|||
$where = ['phone' => $param['phone']]; |
|||
$admin = $adminModel->getAdmin($where,['role'])['data']; |
|||
return $this->getMenuAndToken($admin); |
|||
} |
|||
|
|||
/** |
|||
* @throws \app\exception\ModelEmptyException |
|||
* @throws \app\exception\ModelException |
|||
* @throws \app\exception\TokenException |
|||
*/ |
|||
protected function getMenuAndToken($admin): \think\response\Json |
|||
{ |
|||
// 缓存权限数据
|
|||
$roleRes = RoleService::getMenuAndUpdateAuth($admin['id']); |
|||
|
|||
$loginTime = time(); |
|||
// 登录日志
|
|||
$data = [ |
|||
'seller_id' => $admin['seller_id'], |
|||
'admin_id' => $admin['id'], |
|||
'admin_name' => $admin['name'], |
|||
'title' => $admin['name'].Lang('登录后台系统'), |
|||
'ip' => request()->ip(), |
|||
'agent' => request()->header()['user-agent'], |
|||
'login_time' => $loginTime |
|||
]; |
|||
event('AdminLoginLog',$data); |
|||
// 更新最后登录时间
|
|||
$admin->last_login_time = $loginTime; |
|||
$admin->save(); |
|||
|
|||
// 获取密码配置
|
|||
$setting = new SysSetting(); |
|||
$passConf = $setting -> getCustomData(['id'=>120])['data']; |
|||
if(!empty($passConf['value']) && $passConf['status'] == 1){ |
|||
$passConf = json_decode($passConf['value'],true); |
|||
if($passConf['change_duration'] > 0){ |
|||
$admin -> pass_tips = time() - $admin -> pass_last_change > 86400 * 30 * $passConf['change_duration'] ? 1 : 0; |
|||
} |
|||
} |
|||
|
|||
$menu = $roleRes['data']; |
|||
if(empty($menu)){ |
|||
return jsonReturn(-1, Lang::get('请联系管理员分配权限后再登录')); |
|||
} |
|||
|
|||
return jsonReturn(0, Lang::get('登录成功'), [ |
|||
'token' => createUserToken([ |
|||
'uid' => $admin['id'], |
|||
'name' => $admin['name'], |
|||
'seller_id' => $admin['seller_id'] |
|||
],'admin'), |
|||
'user' => $admin, |
|||
'menu' => $menu, |
|||
]); |
|||
} |
|||
|
|||
/** |
|||
* @description RSA公钥加密 私钥解密 |
|||
* @param string $data 待加解密数据 |
|||
* @param string $operate 操作类型 encode:加密 decode:解密 |
|||
* @return string 返回加密内容/解密内容 |
|||
* @throws \Exception |
|||
*/ |
|||
protected function RSA_openssl(string $data, string $operate = 'encode'): string |
|||
{ |
|||
//RSA 公钥
|
|||
$rsa_public = config('system.rsa_public_key'); |
|||
|
|||
//RSA 私钥
|
|||
$rsa_private = config('system.rsa_private_key'); |
|||
|
|||
//RSA 公钥加密
|
|||
if ('encode' == $operate) { |
|||
$public_key = "-----BEGIN PUBLIC KEY-----\n" . wordwrap($rsa_public, 64, "\n", true) . "\n-----END PUBLIC KEY-----"; |
|||
$key = openssl_pkey_get_public($public_key); |
|||
if (!$key) { |
|||
throw new \Exception('公钥不可用,请联系系统维护人员'); |
|||
} |
|||
$return_en = openssl_public_encrypt($data, $crypted, $key); |
|||
if (!$return_en) { |
|||
throw new \Exception('公钥加密失败,请联系系统维护人员'); |
|||
} |
|||
return base64_encode($crypted); |
|||
} |
|||
|
|||
//RSA 私钥解密
|
|||
if ('decode' == $operate) { |
|||
$private_key = "-----BEGIN PRIVATE KEY-----\n" . wordwrap($rsa_private, 64, "\n", true) . "\n-----END PRIVATE KEY-----"; |
|||
$key = openssl_pkey_get_private($private_key); |
|||
if (!$key) { |
|||
throw new \Exception('私钥不可用,请联系系统维护人员'); |
|||
} |
|||
$return_de = openssl_private_decrypt(base64_decode($data), $decrypted, $key); |
|||
if (!$return_de) { |
|||
throw new \Exception('私钥解密失败,请联系系统维护人员'); |
|||
} |
|||
return $decrypted; |
|||
} |
|||
return ''; |
|||
} |
|||
} |
|||
@ -0,0 +1,322 @@ |
|||
<?php |
|||
declare (strict_types = 1); |
|||
|
|||
namespace app\controller\backend; |
|||
|
|||
use app\hctrait\AdminPassTrait; |
|||
use app\model\Admin; |
|||
use app\model\AdminMenu; |
|||
use app\model\SysSetting; |
|||
use app\validate\AdminValidate; |
|||
use think\exception\ValidateException; |
|||
use think\facade\Db; |
|||
use think\facade\Lang; |
|||
use think\facade\Log; |
|||
|
|||
class AdminController extends BaseController |
|||
{ |
|||
|
|||
use AdminPassTrait; |
|||
/** |
|||
* @param Admin $admin |
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function index(Admin $admin): \think\response\Json |
|||
{ |
|||
$where = [ |
|||
['seller_id','=',$this->admin['seller_id']], |
|||
['is_del','=',1] |
|||
]; |
|||
$name = input('name') ?? ''; |
|||
if(!empty($name)){ |
|||
$where[] = ['name','like','%'.$name.'%']; |
|||
} |
|||
$limit = $this->setLimit(); |
|||
$adminList = $admin->getAdminList($where,$limit); |
|||
return json(pageReturn($adminList)); |
|||
} |
|||
|
|||
/** |
|||
* @throws \app\exception\ModelEmptyException |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function read(Admin $Admin): \think\response\Json |
|||
{ |
|||
$id = (int)input('id'); |
|||
if(!$id){ |
|||
return jsonReturn(-1,Lang::get('管理员ID不能为空')); |
|||
} |
|||
$where = [ |
|||
'id' => $id, |
|||
'seller_id' => $this->admin['seller_id'] |
|||
]; |
|||
$res = $Admin->getAdmin($where,['role']); |
|||
return json($res); |
|||
} |
|||
|
|||
/** |
|||
* 新建管理员 |
|||
* |
|||
* @param Admin $admin |
|||
* @return \think\Response |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function save(Admin $admin): \think\Response |
|||
{ |
|||
$param = input('post.'); |
|||
try{ |
|||
validate(AdminValidate::class)->scene('save')->check($param); |
|||
}catch(ValidateException $e){ |
|||
return jsonReturn(-1, $e->getError()); |
|||
} |
|||
// 密码规则验证
|
|||
$err = $this->checkPass($param['password'],$this->admin['seller_id']); |
|||
if(!empty($err['message'])){ |
|||
return jsonReturn(-3,$err['message']); |
|||
} |
|||
$param['password'] = makePassword($param['password']); |
|||
if(isset($param['group'])){ |
|||
unset($param); |
|||
} |
|||
Db::startTrans(); |
|||
try{ |
|||
$res = $admin -> addAdmin($param); |
|||
$res['data']->role()->attach($param['role'],['seller_id'=>$this->admin['seller_id']]); |
|||
event("AdminOptLog",[ |
|||
'admin_id' => $this->admin['uid'], |
|||
'admin_name' => $this->admin['name'], |
|||
'title'=>Lang::get('管理员管理'), |
|||
"content"=>Lang::get('新增管理员').$res['data']['id'], |
|||
]); |
|||
Db::commit(); |
|||
}catch (\Exception $e){ |
|||
Db::rollback(); |
|||
return jsonReturn(-3,$e->getMessage()); |
|||
} |
|||
|
|||
return json($res); |
|||
} |
|||
|
|||
/** |
|||
* 编辑管理员 |
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function update(Admin $admin): \think\response\Json |
|||
{ |
|||
if(request()->isPost()){ |
|||
$param = request()->except(['password'], 'post'); |
|||
$password = request()->post('password'); |
|||
try { |
|||
validate(AdminValidate::class)->scene('update')->check($param); |
|||
} catch (ValidateException $e) { |
|||
return jsonReturn(-1, $e->getError()); |
|||
} |
|||
$where = [ |
|||
'id' => $param['id'], |
|||
'seller_id' => $this->admin['seller_id'], |
|||
'is_del' => 1, |
|||
]; |
|||
Db::startTrans(); |
|||
try{ |
|||
if(isset($param['group']) && $param['group'] == 1){ |
|||
return jsonReturn(-1,Lang::get('系统管理员不能修改')); |
|||
} |
|||
$manager = $admin -> getAdmin($where)['data']; |
|||
$manager->role()->detach(); |
|||
$manager->role()->attach($param['role'],['seller_id'=>$this->admin['seller_id']]); |
|||
if(!empty($password)){ |
|||
// 密码规则验证
|
|||
$err = $this->checkPass($password,$this->admin['seller_id']); |
|||
if(!empty($err['message'])){ |
|||
return jsonReturn(-3,$err['message']); |
|||
} |
|||
$param['password'] = makePassword($password); |
|||
$param['pass_last_change'] = time(); |
|||
} |
|||
unset($param['role']); |
|||
$res = $admin->updateAdmin($where,$param); |
|||
event("AdminOptLog",[ |
|||
'admin_id' => $this->admin['uid'], |
|||
'admin_name' => $this->admin['name'], |
|||
'title'=>Lang::get('管理员管理'), |
|||
"content"=>Lang::get('更新管理员信息').$param['id'], |
|||
]); |
|||
Db::commit(); |
|||
}catch (\Exception $e){ |
|||
Db::rollback(); |
|||
Log::error($e->getMessage()); |
|||
Log::error($e->getTraceAsString()); |
|||
return jsonReturn(-3,$e->getMessage()); |
|||
} |
|||
return json($res); |
|||
} |
|||
return jsonReturn(-3,Lang::get('请求方法错误')); |
|||
} |
|||
|
|||
/** |
|||
* 删除管理员 |
|||
* |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function delete(Admin $admin): \think\response\Json |
|||
{ |
|||
if(request()->isPost()){ |
|||
$id = (int)input('id'); |
|||
if(!$id){ |
|||
return jsonReturn(-1,Lang::get('管理员ID不能为空')); |
|||
} |
|||
$where = [ |
|||
'id' => $id, |
|||
'seller_id' => $this->admin['seller_id'] |
|||
]; |
|||
event("AdminOptLog",[ |
|||
'admin_id' => $this->admin['uid'], |
|||
'admin_name' => $this->admin['name'], |
|||
'title'=>Lang::get('管理员管理'), |
|||
"content"=>Lang::get('删除管理员').$id, |
|||
]); |
|||
$res = $admin->delAdmin($where); |
|||
return json($res); |
|||
} |
|||
return jsonReturn(-3,Lang::get('请求方法错误')); |
|||
} |
|||
|
|||
/** |
|||
* 修改个人资料 |
|||
* |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function selfUpdate(Admin $admin): \think\response\Json |
|||
{ |
|||
if(request()->isPost()){ |
|||
$param = input('post.'); |
|||
try { |
|||
validate(AdminValidate::class)->scene('selfUpdate')->check($param); |
|||
} catch (ValidateException $e) { |
|||
return jsonReturn(-1, $e->getError()); |
|||
} |
|||
|
|||
if ($param['code_auth'] == 1 && empty($param['phone'])) { |
|||
return jsonReturn(-2, Lang::get('开启短信验证登录需填写手机号')); |
|||
} |
|||
|
|||
$where = [ |
|||
'id' => $this->admin['uid'], |
|||
'seller_id' => $this->admin['seller_id'], |
|||
]; |
|||
if (empty($param['password'])) { |
|||
unset($param['password']); |
|||
} else { |
|||
// 密码规则验证
|
|||
$err = $this->checkPass($param['password'],$this->admin['seller_id']); |
|||
if(!empty($err['message'])){ |
|||
return jsonReturn(-5,$err['message']); |
|||
} |
|||
$param['password'] = makePassword($param['password']); |
|||
// 记录密码修改时间
|
|||
$param['pass_last_change'] = time(); |
|||
} |
|||
$res = $admin -> updateAdmin($where,$param); |
|||
return json($res); |
|||
} |
|||
return jsonReturn(-3,Lang::get('请求方法错误')); |
|||
} |
|||
|
|||
/** |
|||
* @throws \app\exception\ModelException |
|||
* @throws \app\exception\ModelEmptyException |
|||
*/ |
|||
public function self(Admin $Admin,AdminMenu $AdminMenu): \think\response\Json |
|||
{ |
|||
$admin = $Admin->getAdmin(['id' => $this->admin['uid'],'seller_id' => $this->admin['seller_id']],['role'])['data']; |
|||
// 获取权限
|
|||
$role = $admin['role']->toArray(); |
|||
|
|||
if(empty($role)){ |
|||
$auth = []; |
|||
}else{ |
|||
$roleIds = array_column($role,'id'); |
|||
if(in_array(1,$roleIds)){ |
|||
$auth = $AdminMenu->getAllAdminMenu(['is_menu'=> 1,'seller_id'=>1])['data']->toArray(); |
|||
}else{ |
|||
$menuIds = array_column($role,'auth'); |
|||
$tmpMenuIds = []; |
|||
foreach ($menuIds as $menuId){ |
|||
$tmp = explode(',',$menuId); |
|||
$tmpMenuIds = array_merge($tmpMenuIds,$tmp); |
|||
} |
|||
$whereIn = array_unique($tmpMenuIds); |
|||
$auth = $AdminMenu -> getAllAdminMenu([['id','in',$whereIn],['is_menu','=',1]])['data']->toArray(); |
|||
} |
|||
} |
|||
$menu = makeTree($auth); |
|||
return jsonReturn(0,'success',[ |
|||
'user' => $admin, |
|||
'menu' => $menu, |
|||
]); |
|||
} |
|||
|
|||
|
|||
/** |
|||
* @throws \app\exception\ModelException |
|||
* @throws \app\exception\ModelEmptyException |
|||
*/ |
|||
public function current(): \think\response\Json |
|||
{ |
|||
$adminModel = new Admin(); |
|||
$adminMenuModel = new AdminMenu(); |
|||
|
|||
$admin = $adminModel->getAdmin(['id' => $this->admin['uid']], ['role'])['data']; |
|||
|
|||
// 缓存权限数据
|
|||
$role = $admin['role']->toArray(); |
|||
|
|||
if (empty($role)) { |
|||
$auth = []; |
|||
} else { |
|||
$roleIds = array_column($role, 'id'); |
|||
if (in_array(1, $roleIds)) { |
|||
$auth = $adminMenuModel->getAllCustomDataModel(['seller_id' => $admin['seller_id'], 'status' => 1],'id asc','id,controller,action,path,frontend_path')['data']->toArray(); |
|||
} else { |
|||
$menuIds = array_column($role, 'auth'); |
|||
$tmpMenuIds = []; |
|||
foreach ($menuIds as $menuId) { |
|||
if($menuId){ |
|||
$tmp = explode(',', $menuId); |
|||
$tmpMenuIds = array_merge($tmpMenuIds, $tmp); |
|||
} |
|||
} |
|||
$whereIn = array_unique($tmpMenuIds); |
|||
$auth = $adminMenuModel->getAllCustomDataModel([ |
|||
['id', 'in', $whereIn], |
|||
['seller_id', '=', $admin['seller_id']], |
|||
['status', '=', 1] |
|||
],'id asc','id,controller,action,path,frontend_path')['data']->toArray(); |
|||
} |
|||
} |
|||
$allowPath = array_filter(array_column($auth, 'frontend_path')); |
|||
$dynamic_content_auth = []; |
|||
// 动态菜单
|
|||
foreach($auth as $val){ |
|||
// 内容 content/index
|
|||
$tempPath = strtolower($val['path']); |
|||
// 如果路径是 /content/index/1 格式
|
|||
if(preg_match('/^\/content\/index\/\d+$/',$tempPath)){ |
|||
$dynamic_content_auth[] = str_replace('/content/index','/addCustomContent',$tempPath); |
|||
$dynamic_content_auth[] = str_replace('/content/index','/updateCustomContent',$tempPath); |
|||
} |
|||
|
|||
// 审核
|
|||
// 如果路径是 /content/checklist/1 格式
|
|||
if(preg_match('/^\/content\/checklist\/\d+$/',$tempPath)){ |
|||
$dynamic_content_auth[] = str_replace('/content/checklist','/auditingContent',$tempPath); |
|||
} |
|||
} |
|||
$allowPath = array_merge($allowPath, $dynamic_content_auth); |
|||
$allowPath = array_merge($allowPath, array_keys(config('rbac.skip_auth'))); |
|||
return jsonReturn(0,'success',$allowPath); |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,40 @@ |
|||
<?php |
|||
declare (strict_types = 1); |
|||
|
|||
namespace app\controller\backend; |
|||
|
|||
use app\model\AdminLoginLog; |
|||
use think\facade\Lang; |
|||
use think\facade\Request; |
|||
|
|||
class AdminLoginLogController extends BaseController |
|||
{ |
|||
/** |
|||
* 显示资源列表 |
|||
* |
|||
* @return \think\Response |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function index(AdminLoginLog $adminLoginLog): \think\Response |
|||
{ |
|||
$where = [ |
|||
'seller_id' => $this->admin['seller_id'], |
|||
]; |
|||
$limit = $this->setLimit(); |
|||
$name = input('admin_name'); |
|||
if($name){ |
|||
$where['admin_name'] = $name; |
|||
} |
|||
$id = input('admin_id'); |
|||
if($id){ |
|||
$where['id'] = $id; |
|||
} |
|||
$adminLogList = $adminLoginLog->getAdminLoginLogList($where,$limit); |
|||
return json(pageReturn($adminLogList)); |
|||
} |
|||
|
|||
public function delete(): \think\response\Json |
|||
{ |
|||
return parent::customDelete(Lang::get('登录日志'),Lang::get('登录日志删除')); |
|||
} |
|||
} |
|||
@ -0,0 +1,182 @@ |
|||
<?php |
|||
declare (strict_types = 1); |
|||
|
|||
namespace app\controller\backend; |
|||
|
|||
use app\model\AdminMenu; |
|||
use app\service\RoleService; |
|||
use app\validate\AdminMenuValidate; |
|||
use Overtrue\Pinyin\Pinyin; |
|||
use think\exception\ValidateException; |
|||
use think\facade\Lang; |
|||
|
|||
|
|||
class AdminMenuController extends BaseController |
|||
{ |
|||
/** |
|||
* 显示资源列表 |
|||
* |
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function index(AdminMenu $adminMenu): \think\response\Json |
|||
{ |
|||
$where = [ |
|||
'seller_id' => $this->admin['seller_id'], |
|||
'is_del' => 1, |
|||
]; |
|||
|
|||
$adminMenuList = $adminMenu->getAllAdminMenu($where)['data']->toArray(); |
|||
// foreach($adminMenuList as $key => $val){
|
|||
// if($val['is_menu'] == 2){
|
|||
// unset($adminMenuList[$key]);
|
|||
// }
|
|||
// }
|
|||
$adminMenuList = generate($adminMenuList); |
|||
|
|||
return jsonReturn(0,'success',$adminMenuList); |
|||
} |
|||
|
|||
/** |
|||
* 保存新建的资源 |
|||
* |
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function save(AdminMenu $adminMenu): \think\response\Json |
|||
{ |
|||
if(request()->isPost()){ |
|||
$param = input('post.'); |
|||
// 数据验证
|
|||
try{ |
|||
validate(AdminMenuValidate::class)->scene('save')->check($param); |
|||
}catch(ValidateException $e){ |
|||
return jsonReturn(-1, $e->getError()); |
|||
} |
|||
$param['path'] = '/' .$param['controller'].'/'.$param['action']; |
|||
$res = $adminMenu -> addAdminMenu($param); |
|||
return json($res); |
|||
} |
|||
return jsonReturn(-3,Lang::get('请求方法错误')); |
|||
} |
|||
|
|||
/** |
|||
* 显示指定的资源 |
|||
* |
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
* @throws \app\exception\ModelEmptyException |
|||
*/ |
|||
public function read(AdminMenu $adminMenu): \think\response\Json |
|||
{ |
|||
|
|||
$id = (int)input('id'); |
|||
if(!$id){ |
|||
// TODO
|
|||
// 修改错误消息
|
|||
return jsonReturn(-1,'ErrorMsg'); |
|||
} |
|||
$where = [ |
|||
'id' => $id, |
|||
'seller_id' => $this->admin['seller_id'] |
|||
]; |
|||
// TODO
|
|||
// 其他逻辑
|
|||
$res = $adminMenu->getAdminMenu($where); |
|||
return json($res); |
|||
|
|||
} |
|||
|
|||
/** |
|||
* 保存更新的资源 |
|||
|
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function update(AdminMenu $adminMenu): \think\response\Json |
|||
{ |
|||
if(request()->isPost()){ |
|||
$param = input('post.'); |
|||
try { |
|||
validate(AdminMenuValidate::class)->scene('update')->check($param); |
|||
} catch (ValidateException $e) { |
|||
return jsonReturn(-1, $e->getError()); |
|||
} |
|||
$param['path'] = '/' .$param['controller'].'/'.$param['action']; |
|||
$where = [ |
|||
'id' => $param['id'], |
|||
'seller_id' => $this->admin['seller_id'], |
|||
'is_del' => 1, |
|||
]; |
|||
$res = $adminMenu -> updateAdminMenu($where,$param); |
|||
return json($res); |
|||
} |
|||
return jsonReturn(-3,Lang::get('请求方法错误')); |
|||
} |
|||
|
|||
/** |
|||
* 删除指定资源 |
|||
* |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function delete(AdminMenu $adminMenu): \think\response\Json |
|||
{ |
|||
if(request()->isPost()){ |
|||
$id = (int)input('id'); |
|||
if(!$id){ |
|||
return jsonReturn(-3,Lang::get('请求方法错误')); |
|||
} |
|||
$where = [ |
|||
'id' => $id, |
|||
'seller_id' => $this->admin['seller_id'] |
|||
]; |
|||
$res = $adminMenu->softDelAdminMenu($where); |
|||
return json($res); |
|||
} |
|||
return jsonReturn(-3,Lang::get('请求方法错误')); |
|||
} |
|||
|
|||
/** |
|||
* 单个控制菜单是否显示 |
|||
* @author:🍁 |
|||
* @Time:2023/5/22 11:12 上午 |
|||
*/ |
|||
public function updateMenuStatus(AdminMenu $adminMenu) |
|||
{ |
|||
$id = $this->request->post('id/d',0); |
|||
$info = $adminMenu->where(['id'=>$id,'is_del'=>1])->field('id,status')->find(); |
|||
if(empty($info)){ |
|||
return jsonReturn(-1,lang('菜单不存在')); |
|||
} |
|||
|
|||
$updateData = [ |
|||
'status'=>$info['status']==1?2:1, |
|||
'update_time'=>date("Y-m-d H:i:s") |
|||
]; |
|||
$res = $adminMenu->where(['id'=>$id])->update($updateData); |
|||
if($res){ |
|||
return jsonReturn(0,lang('修改成功'),$updateData); |
|||
} |
|||
return jsonReturn(-2,lang('修改失败')); |
|||
} |
|||
|
|||
/** |
|||
* 得到当前登录用户的权限节点 |
|||
* @author:🍁 |
|||
* @Time:2023/5/22 11:24 上午 |
|||
*/ |
|||
public function getUserMenuList(AdminMenu $adminMenu) |
|||
{ |
|||
return json(RoleService::getMenuAndUpdateAuth($this->admin['uid'])); |
|||
} |
|||
|
|||
/** |
|||
* 获取动态菜单 |
|||
* @throws \app\exception\ModelException |
|||
* @throws \app\exception\ModelEmptyException |
|||
*/ |
|||
public function getDynamicMenu(): \think\response\Json |
|||
{ |
|||
return json(RoleService::getDynamicMenu($this->admin['uid'])); |
|||
} |
|||
} |
|||
@ -0,0 +1,41 @@ |
|||
<?php |
|||
declare (strict_types = 1); |
|||
|
|||
namespace app\controller\backend; |
|||
|
|||
use app\model\AdminOptLog; |
|||
use think\facade\Lang; |
|||
|
|||
|
|||
class AdminOptLogController extends BaseController |
|||
{ |
|||
/** |
|||
* 显示资源列表 |
|||
* |
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function index(AdminOptLog $adminOptLog): \think\response\Json |
|||
{ |
|||
$where = [ |
|||
'seller_id' => $this->admin['seller_id'], |
|||
]; |
|||
$limit = $this->setLimit(); |
|||
$name = input('admin_name'); |
|||
if($name){ |
|||
$where['admin_name'] = $name; |
|||
} |
|||
$id = input('admin_id'); |
|||
if($id){ |
|||
$where['id'] = $id; |
|||
} |
|||
$adminLogList = $adminOptLog->getAdminOptLogList($where,$limit); |
|||
return json(pageReturn($adminLogList)); |
|||
} |
|||
|
|||
public function delete(): \think\response\Json |
|||
{ |
|||
return parent::customDelete(Lang::get('操作日志'),Lang::get('操作日志删除')); |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,140 @@ |
|||
<?php |
|||
declare (strict_types = 1); |
|||
|
|||
namespace app\controller\backend; |
|||
|
|||
use app\model\Advertisement; |
|||
use app\model\Attachment; |
|||
use app\validate\AdvertisementValidate; |
|||
use think\exception\ValidateException; |
|||
use think\facade\Lang; |
|||
|
|||
|
|||
class AdvertisementController extends BaseController |
|||
{ |
|||
/** |
|||
* 显示资源列表 |
|||
* |
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function index(Advertisement $advertisement): \think\response\Json |
|||
{ |
|||
$where = [ |
|||
'seller_id' => $this->admin['seller_id'], |
|||
'is_del' => 1, |
|||
]; |
|||
$title = input('title'); |
|||
if ($title) { |
|||
$where = [ 'title' => $title]; |
|||
} |
|||
$limit = $this->setLimit(); |
|||
$with = [ |
|||
'attachment' => function($query){ |
|||
$query->field('id,name,type,url'); |
|||
} |
|||
]; |
|||
$advertisementList = $advertisement->getAdvertisementList($where,$limit,'*',$with); |
|||
return json(pageReturn($advertisementList)); |
|||
} |
|||
|
|||
/** |
|||
* 保存新建的资源 |
|||
* |
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function save(Advertisement $advertisement): \think\response\Json |
|||
{ |
|||
if(request()->isPost()){ |
|||
$param = input('post.'); |
|||
$param['seller_id'] = $this->admin['seller_id']; |
|||
// 数据验证
|
|||
try{ |
|||
validate(AdvertisementValidate::class)->scene('save')->check($param); |
|||
}catch(ValidateException $e){ |
|||
return jsonReturn(-1, $e->getError()); |
|||
} |
|||
$param['expiration_date'] = date('Y-m-d',strtotime($param['expiration_date'])); |
|||
$param['status'] = 2; // 默认状态禁用
|
|||
$res = $advertisement -> addAdvertisement($param); |
|||
optEventLog($res['data']['id'],Lang::get('广告'),Lang::get('新增')); |
|||
return json($res); |
|||
} |
|||
return jsonReturn(-3,Lang::get('请求方法错误')); |
|||
} |
|||
|
|||
/** |
|||
* 显示指定的资源 |
|||
* |
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
* @throws \app\exception\ModelEmptyException |
|||
*/ |
|||
public function read(Advertisement $advertisement): \think\response\Json |
|||
{ |
|||
|
|||
$id = (int)input('id'); |
|||
if(!$id){ |
|||
return jsonReturn(-1,Lang::get('广告ID不能为空')); |
|||
} |
|||
$where = [ |
|||
'id' => $id, |
|||
'seller_id' => $this->admin['seller_id'] |
|||
]; |
|||
$res = $advertisement->getAdvertisement($where,'',['attachment'=>function($q){ |
|||
$q->field('id,name,type,url'); |
|||
}]); |
|||
return json($res); |
|||
} |
|||
|
|||
/** |
|||
* 保存更新的资源 |
|||
|
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function update(Advertisement $advertisement): \think\response\Json |
|||
{ |
|||
if(request()->isPost()){ |
|||
$param = input('post.'); |
|||
try { |
|||
validate(AdvertisementValidate::class)->scene('update')->check($param); |
|||
} catch (ValidateException $e) { |
|||
return jsonReturn(-1, $e->getError()); |
|||
} |
|||
$where = [ |
|||
'id' => $param['id'], |
|||
'seller_id' => $this->admin['seller_id'], |
|||
]; |
|||
$param['expiration_date'] = date('Y-m-d',strtotime($param['expiration_date'])); |
|||
$res = $advertisement -> updateAdvertisement($where,$param); |
|||
optEventLog($param['id'],Lang::get('广告'),Lang::get('更新')); |
|||
return json($res); |
|||
} |
|||
return jsonReturn(-3,Lang::get('请求方法错误')); |
|||
} |
|||
|
|||
/** |
|||
* 删除指定资源 |
|||
* |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function delete(Advertisement $advertisement): \think\response\Json |
|||
{ |
|||
if(request()->isPost()){ |
|||
$id = (int)input('id'); |
|||
if(!$id){ |
|||
return jsonReturn(-1,'ErrorMsg'); |
|||
} |
|||
$where = [ |
|||
'id' => $id, |
|||
'seller_id' => $this->admin['seller_id'] |
|||
]; |
|||
optEventLog($id,Lang::get('广告'),Lang::get('删除')); |
|||
$res = $advertisement->softDelAdvertisement($where); |
|||
return json($res); |
|||
} |
|||
return jsonReturn(-3,Lang::get('请求方法错误')); |
|||
} |
|||
} |
|||
@ -0,0 +1,158 @@ |
|||
<?php |
|||
declare (strict_types = 1); |
|||
|
|||
namespace app\controller\backend; |
|||
|
|||
use app\model\AttachmentCate; |
|||
use app\service\CacheService; |
|||
use app\validate\AttachmentCateValidate; |
|||
use think\exception\ValidateException; |
|||
use think\facade\Lang; |
|||
|
|||
|
|||
class AttachmentCateController extends BaseController |
|||
{ |
|||
/** |
|||
* 显示资源列表 |
|||
* |
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function index(AttachmentCate $attachmentCate): \think\response\Json |
|||
{ |
|||
$where = [ |
|||
['seller_id' ,'=', $this->admin['seller_id']], |
|||
]; |
|||
$title = input('title'); |
|||
if(!empty($title)){ |
|||
$where[] = ['title', 'like', '%' . $title . '%']; |
|||
} |
|||
$attachmentCateList = $attachmentCate->getAllCustomArrayData($where)['data']; |
|||
$attachmentCateList = makeTree($attachmentCateList); |
|||
array_unshift($attachmentCateList,[ |
|||
'id' => 0, |
|||
'parent_id' => 0, |
|||
'path' => 0, |
|||
'title'=> Lang::get('全部分类'), |
|||
'children' => [], |
|||
]); |
|||
return jsonReturn(0,Lang::get('成功'),$attachmentCateList); |
|||
} |
|||
|
|||
/** |
|||
* 保存新建的资源 |
|||
* |
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
* @throws \app\exception\ModelNotUniqueException |
|||
* @throws \ReflectionException |
|||
*/ |
|||
public function save(AttachmentCate $attachmentCate): \think\response\Json |
|||
{ |
|||
if(request()->isPost()){ |
|||
$param = input('post.'); |
|||
// 数据验证
|
|||
try{ |
|||
validate(AttachmentCateValidate::class)->scene('save')->check($param); |
|||
}catch(ValidateException $e){ |
|||
return jsonReturn(-1, $e->getError()); |
|||
} |
|||
$param['seller_id'] = $this->admin['seller_id']; |
|||
$attachmentCate->saveUnique(['title'=>$param['title'],'seller_id'=>$param['seller_id'],'parent_id'=>$param['parent_id']],'栏目已经存在'); |
|||
// 完善栏目数据
|
|||
if ($param['parent_id']) { |
|||
$parentCate = $attachmentCate->getCustomData(['id' => $param['parent_id'], 'seller_id' => $param['seller_id']])['data']; |
|||
$param['path'] = $parentCate['path'] . '-' . $param['parent_id']; |
|||
} else { |
|||
$param['path'] = 0; |
|||
} |
|||
$res = $attachmentCate -> addAttachmentCate($param); |
|||
CacheService::deleteRelationCacheByObject($attachmentCate); |
|||
return json($res); |
|||
} |
|||
return jsonReturn(-3,Lang::get('请求方法错误')); |
|||
} |
|||
|
|||
/** |
|||
* 显示指定的资源 |
|||
* |
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
* @throws \app\exception\ModelEmptyException |
|||
*/ |
|||
public function read(AttachmentCate $attachmentCate): \think\response\Json |
|||
{ |
|||
|
|||
$id = (int)input('id'); |
|||
if(!$id){ |
|||
return jsonReturn(-1,Lang::get('分类ID不能为空')); |
|||
} |
|||
$where = [ |
|||
'id' => $id, |
|||
]; |
|||
// 其他逻辑
|
|||
$res = $attachmentCate->getAttachmentCate($where); |
|||
return json($res); |
|||
|
|||
} |
|||
|
|||
/** |
|||
* 保存更新的资源 |
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
* @throws \ReflectionException |
|||
*/ |
|||
public function update(AttachmentCate $attachmentCate): \think\response\Json |
|||
{ |
|||
if(request()->isPost()){ |
|||
$param = input('post.'); |
|||
try { |
|||
validate(AttachmentCateValidate::class)->scene('update')->check($param); |
|||
} catch (ValidateException $e) { |
|||
return jsonReturn(-1, $e->getError()); |
|||
} |
|||
$where = [ |
|||
'id' => $param['id'], |
|||
'seller_id' => $this->admin['seller_id'], |
|||
]; |
|||
$res = $attachmentCate -> updateAttachmentCate($where,$param); |
|||
CacheService::deleteRelationCacheByObject($attachmentCate); |
|||
return json($res); |
|||
} |
|||
return jsonReturn(-3,Lang::get('请求方法错误')); |
|||
} |
|||
|
|||
/** |
|||
* 删除指定资源 |
|||
* |
|||
* @throws \app\exception\ModelException |
|||
* @throws \ReflectionException |
|||
*/ |
|||
public function delete(AttachmentCate $attachmentCate): \think\response\Json |
|||
{ |
|||
if(request()->isPost()){ |
|||
$id = (int)input('id'); |
|||
if(!$id){ |
|||
return jsonReturn(-1,lang('分类ID不能为空')); |
|||
} |
|||
$where = [ |
|||
'id' => $id, |
|||
'seller_id' => $this->admin['seller_id'] |
|||
]; |
|||
$subCate = $attachmentCate -> getAllCustomArrayData(['seller_id'=>$this->admin['seller_id'],'parent_id'=>$id])['data']; |
|||
if(!empty($subCate)){ |
|||
return jsonReturn(-1,Lang::get('分类下面有子分类,不能直接删除')); |
|||
} |
|||
$cate = $attachmentCate -> getCustomData($where,['attachment'=>function($q){ |
|||
$q->where('is_del',1); |
|||
}])['data']->toArray(); |
|||
if(!empty($cate['attachment'])){ |
|||
return jsonReturn(-2,Lang::get('分类下有附件不能直接删除')); |
|||
} |
|||
$res = $attachmentCate->delAttachmentCate($where); |
|||
CacheService::deleteRelationCacheByObject($attachmentCate); |
|||
return json($res); |
|||
} |
|||
return jsonReturn(-3,Lang::get('请求方法错误')); |
|||
} |
|||
} |
|||
@ -0,0 +1,508 @@ |
|||
<?php |
|||
declare (strict_types = 1); |
|||
|
|||
namespace app\controller\backend; |
|||
|
|||
use app\exception\ModelException; |
|||
use app\model\Attachment; |
|||
use app\model\AttachmentCate; |
|||
use app\model\Model; |
|||
use app\model\RecycleBin; |
|||
use app\model\SysSetting; |
|||
use app\service\CacheService; |
|||
use app\service\ThemeService; |
|||
use app\service\upload\Upload; |
|||
use app\validate\AttachmentValidate; |
|||
use think\exception\ValidateException; |
|||
use think\facade\App; |
|||
use think\facade\Db; |
|||
use think\facade\Lang; |
|||
use think\file\UploadedFile; |
|||
use think\Image; |
|||
|
|||
class AttachmentController extends BaseController |
|||
{ |
|||
protected $type = [ |
|||
'file' => 4, |
|||
'image' => 2, |
|||
'video' => 3, |
|||
'mp3' => 5, |
|||
'zip' => 1, |
|||
]; |
|||
|
|||
/** |
|||
* 显示资源列表 |
|||
* |
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function index(Attachment $attachment): \think\response\Json |
|||
{ |
|||
$type = (int)input('type'); |
|||
$where = [ |
|||
['seller_id' ,'=', $this->admin['seller_id']], |
|||
['is_del' ,'=', 1], |
|||
]; |
|||
$cate_id = (int)input('cate_id'); |
|||
if($cate_id){ |
|||
$Cate = new AttachmentCate(); |
|||
$cate = $Cate -> getCustomData(['id'=>$cate_id,'seller_id'=>$this->admin['seller_id']])['data']; |
|||
$path = $cate['path'] . '-' . $cate['id']; |
|||
$cates = $Cate -> getAllCustomArrayData([['path','like',$path.'%'],['seller_id','=',$this->admin['seller_id']]])['data']; |
|||
$ids = array_column($cates,'id'); |
|||
array_unshift($ids,$cate['id']); |
|||
if(count($ids) == 1){ |
|||
$where[] = ['attachment_cate_id', '=', $ids[0]]; |
|||
}else{ |
|||
$where[] = ['attachment_cate_id', 'in', $ids]; |
|||
} |
|||
} |
|||
if($type){ |
|||
$where[] = ['type', '=', $type]; |
|||
} |
|||
$name = input('name'); |
|||
if(!empty($name)){ |
|||
$where[] = ['name', 'like', '%' . $name . '%']; |
|||
} |
|||
$limit = $this->setLimit(); |
|||
$attachmentList = $attachment->getAttachmentList($where,$limit); |
|||
|
|||
$res = pageReturn($attachmentList); |
|||
foreach ($res['data'] as &$value) { |
|||
$value['prefix_url'] = ''; |
|||
$value['suffix_url'] = ''; |
|||
if (strpos($value['url'], 'http') === false) { |
|||
if (strpos($value['url'], 'storage/') === false) { |
|||
$value['prefix_url'] = 'http://' . $this->request->host() . 'storage/'; |
|||
$value['suffix_url'] = $value['url']; |
|||
$value['url'] = 'http://' . $this->request->host() . $value['url']; |
|||
continue; |
|||
} |
|||
$value['url'] = 'http://' . $this->request->host() . $value['url']; |
|||
//前缀,后缀
|
|||
$urlStr = explode('storage/', $value['url']); |
|||
$value['prefix_url'] = $urlStr[0] . 'storage/'; |
|||
$value['suffix_url'] = $urlStr[1]; |
|||
} |
|||
} |
|||
|
|||
return json($res); |
|||
} |
|||
|
|||
// 修改附件路径
|
|||
public function editFileUrl() |
|||
{ |
|||
$param = $this->request->param(); |
|||
if (empty($param['id']) || empty($param['name']) || empty($param['suffix_url'])) { |
|||
return json(dataReturn(-1, Lang::get('必填项不能为空!'))); |
|||
} |
|||
|
|||
$attachmentModel = new Attachment(); |
|||
$info = $attachmentModel->where('id', $param['id'])->find(); |
|||
|
|||
if (!isset($info['id'])) { |
|||
return json(dataReturn(-1, Lang::get('文件不存在!'))); |
|||
} |
|||
|
|||
$param['suffix_url'] = str_replace('..', '', $param['suffix_url']); |
|||
$param['suffix_url'] = str_replace('//', '/', $param['suffix_url']); |
|||
|
|||
$oldUrl = $info['url']; |
|||
$oldPathUrl = CMS_ROOT . 'public' . $oldUrl; |
|||
$newUrl = 'storage/' . $param['suffix_url']; |
|||
$newPathUrl = CMS_ROOT . 'public/' . $newUrl; |
|||
|
|||
$updateData = [ |
|||
'name' => $param['name'], |
|||
'description' => $param['description'], |
|||
'url' => $newUrl, |
|||
]; |
|||
|
|||
$fileInfo = pathinfo($newPathUrl); |
|||
|
|||
mkdirs($fileInfo['dirname']); |
|||
|
|||
$copyRes = true; |
|||
if ($oldPathUrl != $newPathUrl) { |
|||
$copyRes = copy($oldPathUrl, $newPathUrl); |
|||
} |
|||
|
|||
if ($copyRes) { |
|||
// 复制成功
|
|||
$res = $attachmentModel->where('id', $param['id'])->update($updateData); |
|||
} else { |
|||
$res = false; |
|||
} |
|||
|
|||
if ($res === false) { |
|||
return json(dataReturn(-1, lang('修改失败'))); |
|||
} else { |
|||
return json(dataReturn(0, lang('修改成功'))); |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 保存新建的资源 |
|||
* |
|||
* @return \think\response\Json |
|||
* @throws \ReflectionException |
|||
*/ |
|||
public function save(Attachment $attachment): \think\response\Json |
|||
{ |
|||
if(request()->isPost()){ |
|||
$param = input('post.'); |
|||
foreach($param as &$val){ |
|||
try{ |
|||
validate(AttachmentValidate::class)->scene('save')->check($val); |
|||
$val['seller_id'] = $this->admin['seller_id']; |
|||
}catch (ValidateException $e){ |
|||
return jsonReturn(-1, $e->getError()); |
|||
} |
|||
|
|||
if ($val['storage'] == 5 && strpos($val['url'], 'http') !== 0) { |
|||
return jsonReturn(-1, lang('网络附件链接地址请以http开头')); |
|||
} |
|||
|
|||
if ($val['storage'] == 5) { |
|||
// 网络附件根据url的后缀识别是什么类型
|
|||
$file_type = fileFormat($val['url']); |
|||
$val['type'] = $this->type[$file_type]; |
|||
} |
|||
} |
|||
$res = $attachment->addAllCustomData($param); |
|||
CacheService::deleteRelationCacheByObject($attachment); |
|||
return json($res); |
|||
} |
|||
return jsonReturn(-3,Lang::get('请求方法错误')); |
|||
} |
|||
|
|||
/** |
|||
* 显示指定的资源 |
|||
* |
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function read(Attachment $attachment): \think\response\Json |
|||
{ |
|||
|
|||
$id = (int)input('id'); |
|||
if(!$id){ |
|||
return jsonReturn(-1,lang('附件ID不能为空')); |
|||
} |
|||
$where = [ |
|||
'id' => $id, |
|||
'seller_id' => $this->admin['seller_id'], |
|||
'is_del' => 1, |
|||
]; |
|||
$res = $attachment->getAttachment($where); |
|||
return json($res); |
|||
} |
|||
|
|||
/** |
|||
* 保存更新的资源 |
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
* @throws \ReflectionException |
|||
*/ |
|||
public function update(Attachment $attachment): \think\response\Json |
|||
{ |
|||
if(request()->isPost()){ |
|||
$param = input('post.'); |
|||
$seller_id = $this->admin['seller_id']; |
|||
try { |
|||
validate(AttachmentValidate::class)->scene('update')->check($param); |
|||
} catch (ValidateException $e) { |
|||
return jsonReturn(-1, $e->getError()); |
|||
} |
|||
|
|||
if (isset($param['storage']) && $param['storage'] == 5 && strpos($param['url'], 'http') !== 0) { |
|||
return jsonReturn(-1, lang('网络附件链接地址请以http开头')); |
|||
} |
|||
|
|||
if (isset($param['storage']) && $param['storage'] == 5) { |
|||
// 网络附件根据url的后缀识别是什么类型
|
|||
$file_type = fileFormat($param['url']); |
|||
$param['type'] = $this->type[$file_type]; |
|||
} |
|||
|
|||
$where = [ |
|||
'id' => $param['id'], |
|||
'seller_id' => $seller_id, |
|||
]; |
|||
$res = $attachment -> updateAttachment($where,$param); |
|||
CacheService::deleteRelationCacheByObject($attachment); |
|||
return json($res); |
|||
} |
|||
return jsonReturn(-3,Lang::get('请求方法错误')); |
|||
} |
|||
|
|||
/** |
|||
* 删除指定资源 |
|||
* |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function delete(Attachment $Attachment): \think\response\Json |
|||
{ |
|||
$idArr = $this->request->param('id'); |
|||
if(is_string($idArr)){ |
|||
$ids = explode(',',$idArr); |
|||
}else{ |
|||
$ids = $idArr; |
|||
} |
|||
$where = [ |
|||
['id','in',$ids], |
|||
['seller_id','=',$this->admin['seller_id']] |
|||
]; |
|||
$attachment = $Attachment -> getAllCustomArrayData($where)['data']; |
|||
Db::startTrans(); |
|||
try{ |
|||
$binData=[]; |
|||
foreach ($attachment as $val){ |
|||
// 复制删除内容到回收站表
|
|||
$binData[] = [ |
|||
'seller_id' => $this->admin['seller_id'], |
|||
'object_id' => $val['id'], |
|||
'sub_id' => 0, |
|||
'module_id' => 0, |
|||
'table_name' => '附件-attachment', |
|||
'title' => !empty($val['name']) ? $val['name'] : '附件' . $val['id'], |
|||
'admin_id' => $this->admin['uid'], |
|||
'name' => $this->admin['name'], |
|||
]; |
|||
} |
|||
$recycleBin = new RecycleBin(); |
|||
$recycleBin -> addAllCustomData($binData); |
|||
$Attachment -> updateAttachment($where,['is_del'=>2,'delete_time'=>time()]); |
|||
CacheService::deleteRelationCacheByObject($Attachment); |
|||
optEventLog($idArr,Lang::get('附件'),Lang::get('删除')); |
|||
Db::commit(); |
|||
}catch (\Exception $e){ |
|||
Db::rollback(); |
|||
return jsonReturn(-1,Lang::get('删除失败')); |
|||
} |
|||
|
|||
return jsonReturn(0,Lang::get('删除成功')); |
|||
} |
|||
|
|||
/** |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function uploadAndSave(Attachment $attachment): \think\response\Json |
|||
{ |
|||
if(request()->isPost()){ |
|||
set_time_limit(0); |
|||
$file = request()->file('file'); |
|||
$reduceImg = request()->file('reduce_img'); |
|||
if(empty($file)){ |
|||
return jsonReturn(-8,lang('文件上传失败,请重新尝试')); |
|||
} |
|||
$seller_id = $this->admin['seller_id']; |
|||
|
|||
$attachmentModel = new Attachment(); |
|||
$has = $attachmentModel->checkFileExist($this->admin['seller_id'], $file->hash()); |
|||
if ($has['code'] == 0) { |
|||
$reduceImgData = !empty($reduceImg)?$this->singleUpload($reduceImg,$seller_id)['data']:[]; |
|||
|
|||
$updateData = [ |
|||
'update_time' => time(), |
|||
'reduce_img'=> !empty($reduceImgData)?$reduceImgData['getUploadFileInfo']['url']:"", |
|||
'attachment_cate_id' => $this->request->param('attachment_cate_id/d',0), |
|||
]; |
|||
// 更新時間
|
|||
$attachmentModel->where('id', $has['data']['id'])->update($updateData); |
|||
return json($has); |
|||
} |
|||
|
|||
$fileData = $this->singleUpload($file,$seller_id)['data']; |
|||
$reduceImgData = !empty($reduceImg)?$this->singleUpload($reduceImg,$seller_id)['data']:[]; |
|||
|
|||
$fileData['getUploadFileInfo']['seller_id'] = $seller_id; |
|||
$fileData['getUploadFileInfo']['type'] = $fileData['fileType']; |
|||
$fileData['getUploadFileInfo']['size'] = round($fileData['fileSize'] / 1024,2); |
|||
$fileData['getUploadFileInfo']['attachment_cate_id'] =$this->request->param('attachment_cate_id/d',0); |
|||
$fileData['getUploadFileInfo']['reduce_img'] = !empty($reduceImgData)?$reduceImgData['getUploadFileInfo']['url']:""; |
|||
|
|||
$attachment = new Attachment(); |
|||
$res = $attachment->addAttachment($fileData['getUploadFileInfo']); |
|||
optEventLog($res['data']['id'],Lang::get('附件'),Lang::get('添加')); |
|||
return json($res); |
|||
} |
|||
return jsonReturn(-3,lang('请求方法错误')); |
|||
} |
|||
|
|||
/** |
|||
* @throws ModelException |
|||
*/ |
|||
private function singleUpload($file,$seller_id) |
|||
{ |
|||
// 查看文件类型
|
|||
$fileName = $file->getOriginalName(); |
|||
$fileExt = $file->getOriginalExtension(); |
|||
$file_type = fileFormat($fileName); |
|||
$fileType = $this->type[$file_type]; |
|||
|
|||
$Settings = new SysSetting(); |
|||
$uploadSetting = $Settings->getAllCustomArrayData(['parent_id'=>1,'group'=>'upload','status'=>1],'id desc','id,group,title,value')['data']; |
|||
$uploadSetting = getColumnForKeyArray($uploadSetting,'title'); |
|||
$limitSize = $uploadSetting[$file_type.'_size']['value'] * 1024; // byte
|
|||
$fileSize = $file->getSize(); // 单位byte
|
|||
if($fileSize > $limitSize){ |
|||
throw new ModelException(lang('文件过大,请修改上传限制或者替换小的文件'),-1); |
|||
} |
|||
$extArr = explode(',',$uploadSetting[$file_type.'_ext']['value']); |
|||
if(!in_array($fileExt,$extArr)){ |
|||
throw new ModelException(lang('文件格式错误,请重新上传'),-2); |
|||
} |
|||
$type = $this->getUploadType(); |
|||
$upload = new Upload(); |
|||
$info = $upload->create($file,$seller_id, $type,$file_type); |
|||
if(!$info){ |
|||
throw new ModelException(lang('上传失败请重新尝试'),-3); |
|||
} |
|||
|
|||
$getUploadFileInfo = $upload->getUploadFileInfo()['data']; |
|||
$waterConfig = SysSetting::where(['group'=>'upload'])->column("value",'title'); |
|||
|
|||
//上传的是图片格式,
|
|||
if($type=="local" && $file_type=="image" && isset($waterConfig['water_status'])&& $waterConfig['water_status']==1){ |
|||
$fullPath ='./'.$getUploadFileInfo['url']; |
|||
$waterFontPath = $this->getWaterFontPath($waterConfig['water_font_path']??""); |
|||
$originalImage = Image::open($fullPath); |
|||
$originalImage->text($waterConfig['water_text']??'HuoCMS',App::getRootPath()."public/system_file/alifont/ali-Regular.woff", |
|||
$waterConfig['water_font_size']??20,$waterConfig['water_font_color']??"#18171b",$waterFontPath)->save($fullPath); |
|||
} |
|||
|
|||
return dataReturn(0,'上传成功', |
|||
[ |
|||
'fileType'=>$fileType, |
|||
'fileSize'=>$fileSize, |
|||
'getUploadFileInfo'=>$getUploadFileInfo |
|||
]); |
|||
} |
|||
|
|||
public function sliceUploadAndSave(Upload $uploader): \think\response\Json |
|||
{ |
|||
$params = $this->request->param(); |
|||
$params['resource_chunk'] = $this->request->file('resource_chunk'); |
|||
$file_type = fileFormat('abc.'.$params['resource_type']); |
|||
|
|||
$Settings = new SysSetting(); |
|||
$uploadSetting = $Settings->getAllCustomArrayData(['parent_id'=>1,'group'=>'upload','status'=>1],'id desc','id,group,title,value')['data']; |
|||
$uploadSetting = getColumnForKeyArray($uploadSetting,'title'); |
|||
$extArr = explode(',',$uploadSetting[$file_type.'_ext']['value']); |
|||
if(!in_array($params['resource_type'],$extArr)){ |
|||
return jsonReturn(-2,lang('文件格式错误,请重新上传')); |
|||
} |
|||
|
|||
$res = $uploader->tmpMove($params['resource_chunk'],$file_type,$params['resource_temp_path'],$params['chunk_index']); |
|||
if($res){ |
|||
$tmPath = runtime_path() . 'slice/'.$file_type.'/'.$params['resource_temp_path']; |
|||
$num = getFileNumber($tmPath); |
|||
if($num == $params['chunk_total']){ |
|||
try { |
|||
$filepath = $uploader->mergeBlob($tmPath,$params['resource_temp_path'],$params['chunk_total'],$params['resource_type']); |
|||
$type = $this->getUploadType(); |
|||
$file = new UploadedFile($filepath,$params['resource_temp_path'].'.'.$params['resource_type']); |
|||
if($type == 'local'){ |
|||
if(!file_exists(public_path() . 'storage/' . $file_type.'/'. date('Ymd'))){ |
|||
@mkdir(public_path() . 'storage/' . $file_type.'/'. date('Ymd'),0755,true); |
|||
} |
|||
copy($filepath,public_path() . 'storage/' . $file_type.'/'. date('Ymd') .'/'.$params['resource_temp_path'] .'.'.$params['resource_type']); |
|||
$cateId = (int)input('attachment_cate_id'); |
|||
$uploadInfo['name'] = $params['resource_name']; |
|||
$uploadInfo['url'] = 'storage/' . $file_type.'/'. date('Ymd') .'/'.$params['resource_temp_path'] .'.'.$params['resource_type']; |
|||
$uploadInfo['mime_type'] = $params['resource_type']; |
|||
$uploadInfo['storage'] = 1; |
|||
$uploadInfo['type'] = $this->type[$file_type]; |
|||
$uploadInfo['size'] = round($file->getSize() / 1024,2); |
|||
$uploadInfo['attachment_cate_id'] = $cateId; |
|||
$attachment = new Attachment(); |
|||
$res = $attachment->addAttachment($uploadInfo); |
|||
optEventLog($res['data']['id'],Lang::get('附件'),Lang::get('添加')); |
|||
(new ThemeService()) -> deleteFile($tmPath); |
|||
return json($res); |
|||
}else{ |
|||
$upload = new Upload(); |
|||
$res = $upload->create($file,$this->admin['seller_id'], $type); |
|||
if($res){ |
|||
$fileSize = $file->getSize(); |
|||
$fileType = $this->type[$file_type]; |
|||
$res = $this->getResponse($fileType,$fileSize,$upload); |
|||
(new ThemeService()) -> deleteFile($tmPath); |
|||
return json($res); |
|||
}else{ |
|||
return jsonReturn(-1,Lang::get('上传失败')); |
|||
} |
|||
} |
|||
} catch (\Exception $e) { |
|||
return jsonReturn(-1,$e->getMessage(),[]); |
|||
} |
|||
|
|||
}else{ |
|||
return jsonReturn(1,Lang::get('上传成功'),$res); |
|||
} |
|||
}else{ |
|||
return jsonReturn(-1,Lang::get('上传失败'),$res); |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function getResponse($fileType, $fileSize, $upload) |
|||
{ |
|||
$uploadInfo = $upload->getUploadFileInfo(); |
|||
$cateId = (int)input('attachment_cate_id'); |
|||
if ($uploadInfo['code'] == 0) { |
|||
$uploadInfo['data']['type'] = $fileType; |
|||
$uploadInfo['data']['size'] = round($fileSize / 1024,2); |
|||
$uploadInfo['data']['attachment_cate_id'] = $cateId; |
|||
$attachment = new Attachment(); |
|||
$res = $attachment->addAttachment($uploadInfo['data']); |
|||
optEventLog($res['data']['id'],Lang::get('附件'),Lang::get('添加')); |
|||
return $res; |
|||
} else { |
|||
return $uploadInfo; |
|||
} |
|||
} |
|||
|
|||
public function getFileType() |
|||
{ |
|||
|
|||
} |
|||
|
|||
/** |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function getUploadType() |
|||
{ |
|||
// 文件信息提取
|
|||
$where = [ |
|||
'seller_id' => $this->admin['seller_id'], |
|||
'group' => 'upload', |
|||
'title' => 'storage' |
|||
]; |
|||
$place = new SysSetting(); |
|||
return $place->getSysSetting($where)['data']->toArray()['value']; |
|||
} |
|||
|
|||
/** |
|||
* 得到文字水印的位置 |
|||
*/ |
|||
private function getWaterFontPath($fontPath) |
|||
{ |
|||
$arr = [ |
|||
'右下'=>Image::WATER_SOUTHEAST, |
|||
'左上'=>Image::WATER_NORTHWEST, |
|||
'上居中'=>Image::WATER_NORTH, |
|||
'右上'=>Image::WATER_NORTHEAST, |
|||
'左居中'=>Image::WATER_WEST, |
|||
'居中'=>Image::WATER_CENTER, |
|||
'右居中'=>Image::WATER_EAST, |
|||
'左下'=>Image::WATER_SOUTHWEST, |
|||
'下居中'=>Image::WATER_SOUTH, |
|||
]; |
|||
return !isset($arr[$fontPath])?Image::WATER_SOUTHEAST:$arr[$fontPath]; |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,90 @@ |
|||
<?php |
|||
|
|||
declare (strict_types = 1); |
|||
|
|||
namespace app\controller\backend; |
|||
|
|||
use app\BaseController as AppBaseController; |
|||
use app\model\Model; |
|||
use think\facade\Lang; |
|||
use think\facade\Request; |
|||
|
|||
class BaseController extends AppBaseController |
|||
{ |
|||
public $admin; |
|||
public $lang; |
|||
/** |
|||
* 控制器中间件 |
|||
* @var array |
|||
*/ |
|||
protected $middleware = [ |
|||
'login', |
|||
'auth', |
|||
]; |
|||
|
|||
public function initialize() |
|||
{ |
|||
parent::initialize(); |
|||
self::createInstallFile(); |
|||
$this->admin = $this->request->admin; |
|||
session('adminId', $this->admin['uid']); |
|||
$this->lang = config('lang.allow_lang_list'); |
|||
} |
|||
|
|||
public function setLimit(): int |
|||
{ |
|||
$limit = 10; |
|||
$limitPage = (int)input('param.limit'); |
|||
if($limitPage){ |
|||
$limit = $limitPage; |
|||
} |
|||
return $limit; |
|||
} |
|||
|
|||
private static function createInstallFile() |
|||
{ |
|||
if(!hcInstalled() && is_dir(app()->getRootPath().'data/install/')){ |
|||
$url = env('app_host') . '/install'; |
|||
redirect($url); |
|||
} |
|||
|
|||
// 更新版本标识
|
|||
updateVersion(); |
|||
} |
|||
|
|||
public function customDelete($opt,$title='批量删除'): \think\response\Json |
|||
{ |
|||
$ids = $this->request->param('id'); |
|||
if(is_string($ids)){ |
|||
$ids = explode(',',$ids); |
|||
} |
|||
$className = str_replace('backend.','',Request::controller()); |
|||
$modelName = '\\app\\model\\' . $className; |
|||
$model = new $modelName(); |
|||
try{ |
|||
$model->whereIn('id',$ids)->delete(); |
|||
optEventLog(json_encode($ids),$title,$opt); |
|||
}catch (\Exception $e){ |
|||
return jsonReturn(-1,Lang::get('删除失败')); |
|||
} |
|||
return jsonReturn(0,Lang::get('删除成功')); |
|||
} |
|||
|
|||
public function customSoftDelete($opt,$title='批量删除'): \think\response\Json |
|||
{ |
|||
$ids = $this->request->param('id'); |
|||
if(is_string($ids)){ |
|||
$ids = explode(',',$ids); |
|||
} |
|||
$className = str_replace('backend.','',Request::controller()); |
|||
$modelName = '\\app\\model\\' . $className; |
|||
$model = new $modelName(); |
|||
try{ |
|||
$model->whereIn('id',$ids)->update(['is_del'=>2,'delete_time'=>time()]); |
|||
optEventLog(json_encode($ids),$title,$opt); |
|||
}catch (\Exception $e){ |
|||
return jsonReturn(-1,Lang::get('删除失败')); |
|||
} |
|||
return jsonReturn(0,Lang::get('删除成功')); |
|||
} |
|||
} |
|||
@ -0,0 +1,537 @@ |
|||
<?php |
|||
declare (strict_types = 1); |
|||
|
|||
namespace app\controller\backend; |
|||
|
|||
use app\exception\ModelException; |
|||
use app\model\AdminMenu; |
|||
use app\model\Attachment; |
|||
use app\model\Category; |
|||
use app\model\CategoryCheck; |
|||
use app\model\Route; |
|||
use app\model\ThemeFile; |
|||
use app\model\Website; |
|||
use app\service\ApiService; |
|||
use app\service\CacheService; |
|||
use app\service\CategoryService; |
|||
use app\service\StaticFileService; |
|||
use app\validate\CategoryValidate; |
|||
use Overtrue\Pinyin\Pinyin; |
|||
use think\exception\ValidateException; |
|||
use think\facade\Cache; |
|||
use think\facade\Db; |
|||
use think\facade\Lang; |
|||
|
|||
class CategoryController extends BaseController |
|||
{ |
|||
|
|||
protected $cacheKeyArr = 'hc_module_cate_arr'; |
|||
|
|||
/** |
|||
* 栏目列表 |
|||
* |
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
* @throws \app\exception\ModelEmptyException |
|||
*/ |
|||
public function index(Category $category): \think\response\Json |
|||
{ |
|||
$websiteId = (int)input('param.website_id'); |
|||
if(!$websiteId){ |
|||
return jsonReturn(-1,Lang::get('网站ID不能为空')); |
|||
} |
|||
$where = [ |
|||
['seller_id','=', $this->admin['seller_id']], |
|||
['website_id','=',$websiteId], |
|||
]; |
|||
$lang = input('lang'); |
|||
if(empty($lang)){ |
|||
$lang = config('lang.default_lang'); |
|||
} |
|||
$Website = new Website(); |
|||
$website = $Website -> getCustomArrayData(['id'=>$websiteId,'seller_id'=>$this->admin['seller_id']])['data']; |
|||
$domain = $website['domain']; |
|||
if($lang != config('lang.default_lang')){ |
|||
$domain = $domain .'/'.$lang; |
|||
} |
|||
$title = $this->request->param('title',''); |
|||
|
|||
$checkStatus = $this->request->param('need_check',0); |
|||
if($checkStatus == 1){ |
|||
$where[] = ['need_check','=',$checkStatus]; |
|||
} |
|||
|
|||
if(!empty($title)) { |
|||
$where[] = ['title', 'like', '%' . $title . '%']; |
|||
} |
|||
$where[] = ['lang','=',$lang]; |
|||
$with = [ |
|||
'thumbnail' => function($query){ |
|||
$query->field('id,name,url'); |
|||
} |
|||
]; |
|||
|
|||
//栏目管理搜索栏目名称
|
|||
$categoryTitle = $this->request->param("category_title/s",'','trim,strip_tags'); |
|||
if(!empty($categoryTitle)){ |
|||
$categoryIdPath = $category->where([ |
|||
['seller_id','=', $this->admin['seller_id']], |
|||
['website_id','=',$websiteId], |
|||
['lang','=',$lang], |
|||
['title','like',"%{$categoryTitle}%"], |
|||
])->column('path','id'); |
|||
if(empty($categoryIdPath)){ |
|||
return jsonReturn(0,'内容不存在'); |
|||
} |
|||
$selectIds = []; |
|||
foreach ($categoryIdPath as $pathId => $paths){ |
|||
$paths = explode('-',$paths); |
|||
for ($i=1;$i<count($paths)-1;$i++){ |
|||
$selectIds[$paths[$i]] = $paths[$i]; |
|||
} |
|||
$selectIds[$pathId] = $pathId; |
|||
} |
|||
$where[] = ['id','in',$selectIds]; |
|||
} |
|||
|
|||
|
|||
$themeFileModel = new ThemeFile(); |
|||
$designFileList = $themeFileModel->getAllCustomArrayData([['is_design', '=', 1]])['data']; |
|||
$newDesignFileList = []; |
|||
foreach ($designFileList as $value) { |
|||
$value['file_name'] = str_replace('.html', '', $value['file']); |
|||
$newDesignFileList[$value['file']] = $value; |
|||
$newDesignFileList[$value['file_name']] = $value; |
|||
} |
|||
$categoryList = $category->getAllCustomArrayData($where,'id asc','id,seller_id,website_id,module_id,parent_id,title,lang,alias,type,path,thumbnail,sort,status,list_tpl',$with)['data']; |
|||
foreach($categoryList as &$item){ |
|||
if($item['type'] == 1 || $item['type'] == 4){ |
|||
if(!empty($item['alias'])){ |
|||
if($item['alias'] == '/'){ |
|||
$item['fullUrl'] = 'http://' . $domain; |
|||
}else{ |
|||
$item['fullUrl'] = 'http://' . $domain . $item['alias'].'.'.config('route.url_html_suffix'); |
|||
} |
|||
}else{ |
|||
$item['fullUrl'] = 'http://' . $domain . '/list/index/'.$item['id'].'.'.config('route.url_html_suffix'); |
|||
} |
|||
}else if($item['type'] == 3){ |
|||
$item['fullUrl'] = $item['alias']; |
|||
}else{ |
|||
$item['fullUrl'] = 'javascript:;'; |
|||
} |
|||
|
|||
$item['is_design'] = 0; |
|||
$item['design_path'] = ''; |
|||
if (isset($newDesignFileList[$item['list_tpl']])) { |
|||
$item['is_design'] = 1; |
|||
$item['design_path'] = $newDesignFileList[$item['list_tpl']]['design_path']; |
|||
} |
|||
} |
|||
if($checkStatus != 1){ |
|||
$categoryList = makeTree($categoryList); |
|||
} |
|||
return jsonReturn(0,'success',$categoryList); |
|||
} |
|||
|
|||
/** |
|||
* 保存新建的资源 |
|||
* |
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
* @throws \app\exception\ModelEmptyException |
|||
*/ |
|||
public function save(CategoryService $categoryService,Category $Category): \think\response\Json |
|||
{ |
|||
if(request()->isPost()){ |
|||
$param = input('post.'); |
|||
$param['alias'] = $param['alias'] ?? ''; |
|||
$param['module_id'] = $param['module_id'] ?? 1; |
|||
$param['is_menu'] = $param['is_menu'] ?? 2; |
|||
// 数据验证
|
|||
try{ |
|||
if(!empty($param['parent_map'])){ |
|||
$param = $this->getMapCateData($param); |
|||
} |
|||
validate(CategoryValidate::class)->scene('save')->check($param); |
|||
}catch(ValidateException $e){ |
|||
return jsonReturn(-1, $e->getError()); |
|||
} |
|||
if (in_array($param['alias'], StaticFileService::$forbidNames)) { |
|||
return jsonReturn(-2,lang('别名已被系统占用,请修改别名')); |
|||
} |
|||
$param['seller_id'] = $this->admin['seller_id']; |
|||
$category = $Category->existCategory(['title'=>$param['title'],'seller_id'=>$param['seller_id'],'website_id'=>$param['website_id'],'lang'=>$param['lang'],'parent_id'=>$param['parent_id']])['data']; |
|||
if(!empty($category)){ |
|||
return jsonReturn(-2,'栏目已经存在'); |
|||
} |
|||
if(in_array($param['type'],[1,4]) && empty($param['alias'])){ |
|||
if($param['list_tpl'] == 'index'){ |
|||
$param['alias'] = '/'; |
|||
}else{ |
|||
$param['alias'] = $this->getAlias($param['title'],$param['website_id'],$param['lang'],$param['seller_id']); |
|||
} |
|||
} |
|||
if(!empty($param['alias']) && $param['alias'] != 'javascript:;'){ |
|||
$category = $Category->existCategory(['title'=>$param['alias'],'seller_id'=>$param['seller_id'],'website_id'=>$param['website_id'],'lang'=>$param['lang']])['data']; |
|||
} |
|||
if(!empty($category)){ |
|||
return jsonReturn(-3,lang('栏目别名已经存在')); |
|||
} |
|||
if ($param['need_check'] == 1 && (empty($param['check_list']) || !is_array($param['check_list']))) { |
|||
return jsonReturn(-3,'请设置审核人员!'); |
|||
} |
|||
if (!empty($param['field_list'])) { |
|||
$keyArr = []; |
|||
foreach ($param['field_list'] as $value) { |
|||
if (isset($keyArr[$value['key']])) { |
|||
return jsonReturn(-5,lang('自定义字段名称重复:') . $value['key']); |
|||
} |
|||
$keyArr[$value['key']] = $value; |
|||
} |
|||
$param['field_list'] = json_encode($param['field_list'], JSON_UNESCAPED_UNICODE); |
|||
} |
|||
return $categoryService -> createCategory($param); |
|||
} |
|||
return jsonReturn(-3,Lang::get(lang('请求方法错误'))); |
|||
} |
|||
|
|||
/** |
|||
* 栏目详情 |
|||
* |
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
* @throws \app\exception\ModelEmptyException |
|||
*/ |
|||
public function read(Category $category,Attachment $attachment): \think\response\Json |
|||
{ |
|||
$param = input('param.'); |
|||
try { |
|||
validate(CategoryValidate::class)->scene('read')->check($param); |
|||
} catch (ValidateException $e) { |
|||
return jsonReturn(-1, $e->getError()); |
|||
} |
|||
$param['seller_id']= $this->admin['seller_id']; |
|||
$with = [ |
|||
'thumbnail' => function($query){ |
|||
$query->field('id,name,url'); |
|||
},'banner' => function($query){ |
|||
$query->field('id,name,url'); |
|||
} |
|||
]; |
|||
$res = $category->getCategory($param,$with); |
|||
|
|||
if (!empty($res['data']['content'])) { |
|||
$res['data']['content'] = htmlspecialchars_decode($res['data']['content']); |
|||
} |
|||
$res['data']['check_list'] = []; |
|||
if ($res['data']['need_check'] == 1) { |
|||
$checkModel = new CategoryCheck(); |
|||
$checkList = $checkModel->where([ |
|||
['category_id', '=', $res['data']['id']], |
|||
['status', '=', 1], |
|||
['type','=',1] |
|||
])->select()->toArray(); |
|||
|
|||
$res['data']['check_list'] = $checkList; |
|||
} |
|||
if (!empty($res['data']['field_list'])) { |
|||
$res['data']['field_list'] = json_decode($res['data']['field_list'], true); |
|||
} |
|||
return json($res); |
|||
} |
|||
|
|||
/** |
|||
* 保存更新的资源 |
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
* @throws \app\exception\ModelEmptyException |
|||
*/ |
|||
public function update(CategoryService $categoryService,Category $Category): \think\response\Json |
|||
{ |
|||
if(request()->isPost()){ |
|||
$param = input('post.'); |
|||
$param['is_menu'] = $param['is_menu'] ?? 2; |
|||
try { |
|||
if(!empty($param['parent_map'])){ |
|||
$param = $this->getMapCateData($param); |
|||
} |
|||
validate(CategoryValidate::class)->scene('update')->check($param); |
|||
} catch (ValidateException $e) { |
|||
return jsonReturn(-1, $e->getError()); |
|||
} |
|||
if (in_array($param['alias'], StaticFileService::$forbidNames)) { |
|||
return jsonReturn(-2,lang('别名已被系统占用,请修改别名')); |
|||
} |
|||
$param['seller_id'] = $this->admin['seller_id']; |
|||
if(in_array($param['type'],[1,4]) && empty($param['alias'])){ |
|||
if($param['list_tpl'] == 'index'){ |
|||
$param['alias'] = '/'; |
|||
}else{ |
|||
$param['alias'] = $this->getAlias($param['title'],$param['website_id'],$param['lang'],$param['seller_id']); |
|||
} |
|||
} |
|||
$category = $Category->existCategory(['title'=>$param['title'],'seller_id'=>$param['seller_id'],'website_id'=>$param['website_id'],'lang'=>$param['lang'],'parent_id'=>$param['parent_id']])['data']; |
|||
if(!empty($category) && $category['id'] != $param['id']){ |
|||
return jsonReturn(-2,lang('栏目已经存在')); |
|||
} |
|||
$category = $Category->existCategory(['title'=>$param['alias'],'seller_id'=>$param['seller_id'],'website_id'=>$param['website_id']])['data']; |
|||
if(!empty($category) && $category['id'] != $param['id']){ |
|||
return jsonReturn(-3,lang('栏目别名已经存在')); |
|||
} |
|||
if (isset($param['need_check']) && $param['need_check'] == 1 && (empty($param['check_list']) || !is_array($param['check_list']))) { |
|||
return jsonReturn(-3,lang('请设置审核人员')); |
|||
} |
|||
if (!empty($param['field_list'])) { |
|||
$keyArr = []; |
|||
foreach ($param['field_list'] as $value) { |
|||
if (isset($keyArr[$value['key']])) { |
|||
return jsonReturn(-5,lang('自定义字段名称重复:') . $value['key']); |
|||
} |
|||
$keyArr[$value['key']] = $value; |
|||
} |
|||
$param['field_list'] = json_encode($param['field_list'], JSON_UNESCAPED_UNICODE); |
|||
} |
|||
$this->deleteCateCacheKey($param['website_id'],$param['lang']); |
|||
return $categoryService -> updateCategory($param); |
|||
} |
|||
return jsonReturn(-3,Lang::get('请求方法错误')); |
|||
} |
|||
|
|||
/** |
|||
* 删除栏目 |
|||
* @param Category $category |
|||
* @param Route $route |
|||
* @return \think\response\Json |
|||
*/ |
|||
public function delete(Category $category,Route $route): \think\response\Json |
|||
{ |
|||
if(request()->isPost()){ |
|||
$param = input('post.'); |
|||
try { |
|||
validate(CategoryValidate::class)->scene('delete')->check($param); |
|||
} catch (ValidateException $e) { |
|||
return jsonReturn(-1, $e->getError()); |
|||
} |
|||
$where = [ |
|||
'id' => $param['id'], |
|||
'seller_id' => $this->admin['seller_id'], |
|||
'website_id' => $param['website_id'], |
|||
'lang' => $param['lang'] |
|||
]; |
|||
Db::startTrans(); |
|||
try { |
|||
$subCate = $category -> getAllCustomArrayData(['seller_id'=>$this->admin['seller_id'],'parent_id'=>$param['id']])['data']; |
|||
$this->deleteCateCacheKey($param['website_id'],$param['lang']); |
|||
if(!empty($subCate)){ |
|||
return jsonReturn(-1,lang('栏目下面有子栏目,不能直接删除')); |
|||
} |
|||
$res = $category->delCategory($where); |
|||
$route->delRoute(['seller_id' => $this->admin['seller_id'],'category_id'=>$param['id']]); |
|||
$route->getRoutes($param['website_id'], $this->admin['seller_id'], $param['lang']); |
|||
// 把动态菜单删除
|
|||
$menu = new AdminMenu(); |
|||
// 审核 /content/checkList/41
|
|||
$menu -> delCustomData(['path'=>'/content/checkList/'.$param['id']]); |
|||
// 内容 /content/index/5
|
|||
$menu -> delCustomData(['path'=>'/content/index/'.$param['id']]); |
|||
|
|||
CacheService::deleteRelationCacheByObject($route); |
|||
CacheService::deleteRelationCacheByObject($category); |
|||
$optAdmin = request()->admin; |
|||
event("AdminOptLog",[ |
|||
'admin_id' => $optAdmin['uid'], |
|||
'admin_name' => $optAdmin['name'], |
|||
'title'=>lang("栏目管理"), |
|||
"content"=>lang("删除栏目,栏目ID为").$param['id'], |
|||
]); |
|||
Db::commit(); |
|||
CacheService::clear(); |
|||
}catch (ModelException $me){ |
|||
Db::rollback(); |
|||
return jsonReturn(50023,$me->getMessage()); |
|||
}catch (\Exception $e){ |
|||
Db::rollback(); |
|||
return jsonReturn(50024,$e->getMessage()); |
|||
} |
|||
return json($res); |
|||
} |
|||
return jsonReturn(-3,Lang::get('请求方法错误')); |
|||
} |
|||
|
|||
|
|||
/** |
|||
* 分组获取栏目列表 |
|||
* @param Category $Category |
|||
* @return \think\response\Json |
|||
*/ |
|||
public function getModuleCate(Category $Category): \think\response\Json |
|||
{ |
|||
$param = input('get.'); |
|||
try { |
|||
validate(CategoryValidate::class)->scene('getModuleCate')->check($param); |
|||
} catch (ValidateException $e) { |
|||
return jsonReturn(-1, $e->getError()); |
|||
} |
|||
|
|||
$Website = new Website(); |
|||
$website = $Website->getAllCustomArrayData([['id','in',$param['site_id']],['seller_id','=',$this->admin['seller_id']]] |
|||
,'id asc','id,seller_id,title,domain')['data']; |
|||
$website = getColumnForKeyArray($website,'id'); |
|||
|
|||
$category = $Category -> getAllCustomArrayData([['website_id','in',$param['site_id']],['seller_id','=',$this->admin['seller_id']],['lang','=',$param['lang']]],'id asc')['data']; |
|||
$category = getArrayGroupBy($category,'website_id'); |
|||
$response = []; |
|||
foreach($category as $key => $cate){ |
|||
$tmpCategory = $this->makeTree($cate); |
|||
$tmpCategory = $this->imp($tmpCategory); |
|||
$tmpCate = $website[$key]; |
|||
$tmpCate['category'] = $tmpCategory; |
|||
$response[] = $tmpCate; |
|||
} |
|||
|
|||
return jsonReturn(0,lang('成功'),$response); |
|||
} |
|||
|
|||
public function makeTree($data, int $pid=0, int $level=0): array |
|||
{ |
|||
$tree = array(); |
|||
$tmpTree = []; |
|||
foreach ($data as $key => &$value) { |
|||
$str = str_repeat('--',$level); |
|||
$value['title'] = $str . $value['title']; |
|||
if ($value['parent_id'] == $pid) { |
|||
$value['level'] = $level; |
|||
unset($data[$key]); |
|||
$tmpTree[] = $value; |
|||
$value['children'] = $this->makeTree($data, $value['id'],$level+1); |
|||
$tree[] = $value; |
|||
}else{ |
|||
$tmpTree[] = $value; |
|||
} |
|||
} |
|||
return $tree; |
|||
} |
|||
|
|||
public function imp($tree, $children='children'): array |
|||
{ |
|||
$impArr = array(); |
|||
foreach($tree as $w) { |
|||
if(isset($w[$children])) { |
|||
$t = $w[$children]; |
|||
unset($w[$children]); |
|||
$impArr[] = $w; |
|||
if(is_array($t)) $impArr = array_merge($impArr, $this->imp($t, $children)); |
|||
} else { |
|||
$impArr[] = $w; |
|||
} |
|||
} |
|||
return $impArr; |
|||
} |
|||
|
|||
/** |
|||
* 栏目复制 |
|||
* @throws ModelException |
|||
* @throws \Exception |
|||
*/ |
|||
public function copy(CategoryService $categoryService): \think\response\Json |
|||
{ |
|||
set_time_limit(300); |
|||
$param = input('post.'); |
|||
try { |
|||
validate(CategoryValidate::class)->scene('copy')->check($param); |
|||
} catch (ValidateException $e) { |
|||
return jsonReturn(-1, $e->getError()); |
|||
} |
|||
foreach ($param['target_site'] as $val){ |
|||
if(empty($val) || !is_numeric($val)){ |
|||
return jsonReturn(-1,lang('目标站点数据异常,请检查')); |
|||
} |
|||
} |
|||
$res = $categoryService -> copyCate($param['original_site'],$param['target_site'],$param['lang'],$this->admin['seller_id']); |
|||
return json($res); |
|||
} |
|||
|
|||
/** |
|||
* @throws \app\exception\ModelEmptyException |
|||
* @throws ModelException |
|||
*/ |
|||
public function getMapCateData(&$param) |
|||
{ |
|||
$Category = new Category(); |
|||
$param['parent_path'] = json_encode($param['parent_map']); |
|||
$param['parent_map'] = array_pop($param['parent_map']); |
|||
$mapCate = $Category->getCategory(['id'=>$param['parent_map'],'seller_id'=>$this->admin['seller_id']])['data']->toArray(); |
|||
foreach($mapCate as $k => $v){ |
|||
if($k == 'parent_id'){ |
|||
continue; |
|||
} |
|||
if(empty($param[$k]) && !in_array($k,['id','create_time','update_time'])){ |
|||
$param[$k] = $v; |
|||
} |
|||
} |
|||
return $param; |
|||
} |
|||
|
|||
public function deleteCateCacheKey($siteId,$lang) |
|||
{ |
|||
$cateCacheKey = 'hc_cate_' . $this->admin['seller_id'] . '_' . $siteId .'_' . $lang; |
|||
Cache::delete($cateCacheKey); |
|||
$moduleCateArr = Cache::get($this->cacheKeyArr); |
|||
if(!empty($moduleCateArr)){ |
|||
foreach ($moduleCateArr as $cate){ |
|||
$tmpCate = explode('_',str_replace('hc_module_cate_' . $this->admin['seller_id'] . '_' . $lang .'_','',$cate)); |
|||
if(in_array($siteId,$tmpCate)){ |
|||
$moduleCateCacheKey = 'hc_module_cate_' . $this->admin['seller_id'] . '_' . $lang .'_' . $siteId; |
|||
Cache::delete($moduleCateCacheKey); |
|||
unset($moduleCateArr[$cate]); |
|||
} |
|||
} |
|||
Cache::set($this->cacheKeyArr,$moduleCateArr); |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* @throws ModelException |
|||
* @throws \app\exception\ModelEmptyException |
|||
*/ |
|||
public function getAlias($title, $siteId, $lang, $sellerId): string |
|||
{ |
|||
$pinyin = new Pinyin(); |
|||
$cacheKey = $sellerId .'_'.$siteId .'_'. $lang . '_website_cache_key'; |
|||
$settingData = Cache::get($cacheKey); |
|||
if(empty($settingData)){ |
|||
$settingData = ApiService::setWebsiteSetting($sellerId,$siteId,$lang); |
|||
} |
|||
|
|||
if(!empty($settingData['alias_rule']) && $settingData['alias_rule'] == 1){ |
|||
$alias = strtolower('/' . $pinyin -> abbr($title)); |
|||
}else{ |
|||
$alias = strtolower('/' . $pinyin -> permalink($title,'')); |
|||
} |
|||
return $alias; |
|||
} |
|||
|
|||
public function copyToOtherLang(CategoryService $categoryService): \think\response\Json |
|||
{ |
|||
$param = $this->request->only(['from','to','site_id']); |
|||
try { |
|||
validate(CategoryValidate::class)->scene('copyCategoryToAnotherLang')->check($param); |
|||
} catch (ValidateException $e) { |
|||
return jsonReturn(-1, $e->getError()); |
|||
} |
|||
return json($categoryService -> copyCategoryToOtherLang($param['from'],$param['to'],$param['site_id'],$this->admin['seller_id'])); |
|||
|
|||
} |
|||
|
|||
public function updateStatus(CategoryService $categoryService): \think\response\Json |
|||
{ |
|||
$param = $this->request->only(['id','status']); |
|||
try { |
|||
validate(CategoryValidate::class)->scene('updateStatus')->check($param); |
|||
} catch (ValidateException $e) { |
|||
return jsonReturn(-1, $e->getError()); |
|||
} |
|||
return json($categoryService -> updateStatus($param['id'],$param['status'],$this->admin['seller_id'])); |
|||
} |
|||
} |
|||
1110
HuoCMS_close_source/app/controller/backend/ContentController.php
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -0,0 +1,146 @@ |
|||
<?php |
|||
declare (strict_types = 1); |
|||
|
|||
namespace app\controller\backend; |
|||
|
|||
use app\model\ContentTag; |
|||
use app\taglib\HcTaglib; |
|||
use app\validate\ContentTagValidate; |
|||
use think\exception\ValidateException; |
|||
use think\facade\Lang; |
|||
|
|||
|
|||
class ContentTagController extends BaseController |
|||
{ |
|||
|
|||
public function initialize() |
|||
{ |
|||
define('ADMIN_SITE_ID',(int)input('site_id')); |
|||
define('ADMIN_SELLER_ID',$this->admin['seller_id']); |
|||
parent::initialize(); |
|||
} |
|||
|
|||
/** |
|||
* 显示资源列表 |
|||
* |
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function index(ContentTag $contentTag): \think\response\Json |
|||
{ |
|||
$where = [ |
|||
'seller_id' => $this->admin['seller_id'], |
|||
'is_del' => 1, |
|||
]; |
|||
$limit = 10; |
|||
$limitParam = (int)input('limit'); |
|||
if($limitParam){ |
|||
$limit = $limitParam; |
|||
} |
|||
// TODO
|
|||
// 添加其他逻辑
|
|||
|
|||
$contentTagList = $contentTag->getContentTagList($where,$limit); |
|||
return json(pageReturn($contentTagList)); |
|||
} |
|||
|
|||
/** |
|||
* 保存新建的资源 |
|||
* |
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function save(ContentTag $contentTag): \think\response\Json |
|||
{ |
|||
if(request()->isPost()){ |
|||
$param = input('post.'); |
|||
// 数据验证
|
|||
try{ |
|||
validate(ContentTagValidate::class)->scene('save')->check($param); |
|||
}catch(ValidateException $e){ |
|||
return jsonReturn(-1, $e->getError()); |
|||
} |
|||
// TODO
|
|||
// 其他逻辑
|
|||
|
|||
$res = $contentTag -> addContentTag($param); |
|||
return json($res); |
|||
} |
|||
return jsonReturn(-3,Lang::get('请求方法错误')); |
|||
} |
|||
|
|||
/** |
|||
* 显示指定的资源 |
|||
* |
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
* @throws \app\exception\ModelEmptyException |
|||
*/ |
|||
public function read(HcTaglib $hcTaglib): \think\response\Json |
|||
{ |
|||
|
|||
$param = input('post.'); |
|||
try { |
|||
validate(ContentTagValidate::class)->scene('read')->check($param); |
|||
} catch (ValidateException $e) { |
|||
return jsonReturn(-1, $e->getError()); |
|||
} |
|||
|
|||
$param['seller_id'] = $this->admin['seller_id']; |
|||
$func = 'tag' . ucfirst($param['title']); |
|||
// $hcTaglib = new HcTaglib(new Template());
|
|||
$hcTaglib->$func(); |
|||
dd($param); |
|||
|
|||
} |
|||
|
|||
/** |
|||
* 保存更新的资源 |
|||
|
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function update(ContentTag $contentTag): \think\response\Json |
|||
{ |
|||
if(request()->isPost()){ |
|||
$param = input('post.'); |
|||
try { |
|||
validate(ContentTagValidate::class)->scene('update')->check($param); |
|||
} catch (ValidateException $e) { |
|||
return jsonReturn(-1, $e->getError()); |
|||
} |
|||
$where = [ |
|||
'id' => $param['id'], |
|||
'seller_id' => $this->admin['seller_id'], |
|||
'is_del' => 1, |
|||
]; |
|||
$res = $contentTag -> updateContentTag($where,$param); |
|||
return json($res); |
|||
} |
|||
return jsonReturn(-3,Lang::get('请求方法错误')); |
|||
} |
|||
|
|||
/** |
|||
* 删除指定资源 |
|||
* |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function delete(ContentTag $contentTag): \think\response\Json |
|||
{ |
|||
if(request()->isPost()){ |
|||
$id = (int)input('id'); |
|||
if(!$id){ |
|||
// TO DO
|
|||
// 替换错误提示
|
|||
return jsonReturn(-1,'ErrorMsg'); |
|||
} |
|||
$where = [ |
|||
'id' => $id, |
|||
'seller_id' => $this->admin['seller_id'] |
|||
]; |
|||
$res = $contentTag->delContentTag($where); |
|||
return json($res); |
|||
} |
|||
return jsonReturn(-3,Lang::get('请求方法错误')); |
|||
} |
|||
} |
|||
@ -0,0 +1,68 @@ |
|||
<?php |
|||
declare (strict_types = 1); |
|||
|
|||
namespace app\controller\backend; |
|||
|
|||
|
|||
|
|||
use think\facade\Db; |
|||
|
|||
class DashboardController extends BaseController |
|||
{ |
|||
/** |
|||
* 后台首页看板 |
|||
* |
|||
*/ |
|||
public function index(): \think\Response |
|||
{ |
|||
if(!hcInstalled()){ |
|||
createInstallFile(); |
|||
} |
|||
$install_date = filectime(app()->getRootPath().'public/system_file/install.lock'); |
|||
// 运行天数
|
|||
$total_day = (int)ceil((time() - $install_date) / (24*3600)) ?: 1; |
|||
// 总站点数
|
|||
$site_count = Db::name('website')->where('seller_id',$this->admin['seller_id'])->count('id'); |
|||
// 总访客数
|
|||
$visit_count = count(Db::name('visit_log')->distinct(true)->field('ip,visited_time')->select()->toArray()); |
|||
// 总文章数 (模型为系统文章模型)
|
|||
$article_count = Db::name('sub_content')->where('is_del',1)->count('id'); |
|||
// 总询盘数
|
|||
$inquiry_count = Db::name('inquiry')->where('is_del',1)->count('id'); |
|||
// 总关键词数
|
|||
$keyword_count = Db::name('keyword')->where('is_del',1)->count('id'); |
|||
// 总导入链接数
|
|||
$in_link_count = Db::name('link')->where(['type'=>1,'is_del'=>1])->count('id'); |
|||
// 总导出链接数
|
|||
$out_link_count = Db::name('link')->where(['type'=>2,'is_del'=>1])->count('id'); |
|||
// 授权信息 // https://www.huocms.com/auth
|
|||
$domain = request()->param('domain'); |
|||
if(empty($domain)){ |
|||
$auth_info = null; |
|||
}else{ |
|||
$authRes = curlPost(config('system.auth_query_url'),['domain'=> request()->param('domain')])['data']; |
|||
$auth_info = json_decode($authRes,true); |
|||
if(empty($auth_info['data'])){ |
|||
$auth_info = null; |
|||
}else{ |
|||
$auth_info = $auth_info['data']; |
|||
} |
|||
$websiteTitle = Db::name('website')->where('domain',$domain)->where('seller_id',$this->admin['seller_id'])->value('title'); |
|||
} |
|||
return jsonReturn(0,'success',[ |
|||
'total_day' => $total_day, |
|||
'site_count' => $site_count, |
|||
'visit_count' => $visit_count, |
|||
'article_count' => $article_count, |
|||
'inquiry_count' => $inquiry_count, |
|||
'keyword_count' => $keyword_count, |
|||
'in_link_count' => $in_link_count, |
|||
'out_link_count' => $out_link_count, |
|||
'auth_info' => $auth_info, |
|||
'version' => file_get_contents(app()->getRootPath().'version'), |
|||
'website_title' => $websiteTitle ?? '', |
|||
]); |
|||
|
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,146 @@ |
|||
<?php |
|||
|
|||
namespace app\controller\backend; |
|||
|
|||
use app\model\Database; |
|||
use app\service\MysqlBackupService; |
|||
use think\App; |
|||
use think\facade\Db; |
|||
use think\facade\Env; |
|||
|
|||
class DatabaseController extends BaseController |
|||
{ |
|||
|
|||
protected $service; |
|||
|
|||
/** |
|||
* @throws \Exception |
|||
*/ |
|||
public function __construct(App $app) |
|||
{ |
|||
parent::__construct($app); |
|||
$config = array( |
|||
'level' => 5,//数据库备份卷大小
|
|||
'compress' => 0,//数据库备份文件是否启用压缩 0不压缩 1 压缩
|
|||
); |
|||
$this->service = new MysqlBackupService($config); |
|||
} |
|||
|
|||
/** |
|||
* 数据表列表 |
|||
* @return \think\response\Json |
|||
*/ |
|||
public function tableList(): \think\response\Json |
|||
{ |
|||
return json($this->service->dataList()); |
|||
} |
|||
|
|||
/** |
|||
* 备份文件列表 |
|||
* @return mixed |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function index() |
|||
{ |
|||
$path = app()->getRootPath() .'backup/'; |
|||
$glob = hcScanDir($path.'*'); |
|||
if(empty($glob)){ |
|||
return jsonReturn(0,'success'); |
|||
} |
|||
arsort($glob); |
|||
$data = []; |
|||
foreach ($glob as $key => $val){ |
|||
$tmp = [ |
|||
'id' => $key+1, |
|||
'title' => $val, |
|||
'size' => sprintf("%.2f",filesize($path.$val) / 1000) .'kb' , |
|||
]; |
|||
array_push($data,$tmp); |
|||
} |
|||
return jsonReturn(0,lang('成功'),$data); |
|||
} |
|||
|
|||
/** |
|||
* @param $name |
|||
* @return mixed |
|||
*/ |
|||
public function detail($name) |
|||
{ |
|||
return jsonReturn($this->service->detail($name)); |
|||
} |
|||
|
|||
/** |
|||
* 数据库备份 |
|||
* @throws \app\exception\ModelException |
|||
* @throws \think\db\exception\BindParamException |
|||
*/ |
|||
public function backup(): \think\response\Json |
|||
{ |
|||
return $this->service->backupDatabase($this->admin['seller_id']); |
|||
} |
|||
|
|||
/** |
|||
* 文件恢复 |
|||
* @return \think\response\Json |
|||
*/ |
|||
public function restore(): \think\response\Json |
|||
{ |
|||
if(!request()->isPost()){ |
|||
return jsonReturn(-1,lang('方法请求错误')); |
|||
} |
|||
$filename = input('post.filename'); |
|||
$res = $this->service->import($filename,0); |
|||
return json($res); |
|||
} |
|||
|
|||
|
|||
/** |
|||
* 数据表优化 |
|||
* @param $name |
|||
* @throws \Exception |
|||
*/ |
|||
public function optimize($name): \think\response\Json |
|||
{ |
|||
$this->service->optimize($name); |
|||
return jsonReturn(0,lang('优化成功')); |
|||
} |
|||
|
|||
/** |
|||
* 数据表修复 |
|||
* @param $name |
|||
* @throws \Exception |
|||
*/ |
|||
public function repair($name): \think\response\Json |
|||
{ |
|||
$this->service->repair($name); |
|||
return jsonReturn(0,lang('修复成功')); |
|||
} |
|||
|
|||
/** |
|||
* @return \think\response\File |
|||
*/ |
|||
public function downloadFile(): \think\response\File |
|||
{ |
|||
try { |
|||
$time = intval($this->request->param('filename')); |
|||
$file =$this->service->getFile('time', $time); |
|||
$fileName = $file[0]; |
|||
return download($fileName,$time); |
|||
}catch (UploadFailException $e){ |
|||
return app('json')->fail(lang('下载失败')); |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* @throws \Exception |
|||
*/ |
|||
public function delete(): \think\response\Json |
|||
{ |
|||
$filename = $this->request->param('filename'); |
|||
if(empty($filename)){ |
|||
return jsonReturn(-2,lang('文件名不能为空')); |
|||
} |
|||
return $this->service->delFile($filename); |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,686 @@ |
|||
<?php |
|||
|
|||
namespace app\controller\backend; |
|||
|
|||
use app\model\BigField; |
|||
use app\model\Category; |
|||
use app\model\CategorySubContent; |
|||
use app\model\SubContent; |
|||
use app\model\Theme; |
|||
use app\model\ThemeFile; |
|||
use app\model\Website; |
|||
use app\model\WebsiteSetting; |
|||
use app\service\ApiService; |
|||
use app\service\ThemeFileService; |
|||
use app\service\ThemeService; |
|||
use app\validate\WebsiteSettingValidate; |
|||
use think\exception\ValidateException; |
|||
use think\response\Json; |
|||
|
|||
class DesignController extends BaseController |
|||
{ |
|||
protected $designBase = 'public/design/designPage'; |
|||
|
|||
protected function sanitizeFileName($file) |
|||
{ |
|||
//sanitize, remove double dot .. and remove get parameters if any
|
|||
$file = CMS_ROOT . 'public/design/designPage/' . preg_replace('@\?.*$@', '', preg_replace('@\.{2,}@', '', preg_replace('@[^\/\\a-zA-Z0-9\-\._]@', '', $file))); |
|||
return $file; |
|||
} |
|||
|
|||
public function save() |
|||
{ |
|||
return $this->publish(1); |
|||
|
|||
// $param = $this->request->param();
|
|||
// // 数据验证
|
|||
// try {
|
|||
// validate(WebsiteSettingValidate::class)->scene('read')->check($param);
|
|||
// } catch (ValidateException $e) {
|
|||
// return jsonReturn(-1, $e->getError());
|
|||
// }
|
|||
//
|
|||
// define('MAX_FILE_LIMIT', 1024 * 1024 * 2);//2 Megabytes max html file size
|
|||
//
|
|||
// $html = "";
|
|||
// if (isset($_POST['startTemplateUrl']) && !empty($_POST['startTemplateUrl'])) {
|
|||
// $startTemplateUrl = $this->sanitizeFileName($_POST['startTemplateUrl']);
|
|||
// $html = file_get_contents($startTemplateUrl);
|
|||
// } else if (isset($_POST['html'])) {
|
|||
// $html = substr($_POST['html'], 0, MAX_FILE_LIMIT);
|
|||
// }
|
|||
//
|
|||
// $where = [
|
|||
// 'seller_id' => $this->admin['seller_id'],
|
|||
// 'website_id' => $param['website_id'],
|
|||
// 'lang' => $param['lang'],
|
|||
// 'is_active' => 1
|
|||
// ];
|
|||
// $Theme = new Theme();
|
|||
// $theme = $Theme->getActiveTheme($where)['data']->toArray();
|
|||
// $themeName = $theme['theme'];
|
|||
//
|
|||
// $pathInfo = pathinfo($param['file']);
|
|||
// $filename = $pathInfo['filename'];
|
|||
//// $file = $this->sanitizeFileName($_POST['file']);
|
|||
// $file = CMS_ROOT . "view/website/{$param['website_id']}/{$param['lang']}/{$themeName}/single_{$filename}.html";
|
|||
//
|
|||
// if (file_put_contents($file, $html)) {
|
|||
// echo "保存成功 $file";
|
|||
// } else {
|
|||
// header($_SERVER['SERVER_PROTOCOL'] . ' 500 Internal Server Error', true, 500);
|
|||
// echo "保存失败! $file\n可能的原因是缺少写权限或文件路径不正确!";
|
|||
// }
|
|||
// exit();
|
|||
} |
|||
|
|||
/** |
|||
* @param $saveType 1保存2发布 |
|||
* @return Json|void |
|||
*/ |
|||
public function publish($saveType = 2) |
|||
{ |
|||
$param = $this->request->param(); |
|||
// 数据验证
|
|||
try { |
|||
validate(WebsiteSettingValidate::class)->scene('read')->check($param); |
|||
} catch (ValidateException $e) { |
|||
return jsonReturn(-1, $e->getError()); |
|||
} |
|||
|
|||
define('MAX_FILE_LIMIT', 1024 * 1024 * 2);//2 Megabytes max html file size
|
|||
|
|||
$html = ""; |
|||
if (isset($param['startTemplateUrl']) && !empty($param['startTemplateUrl'])) { |
|||
$startTemplateUrl = $this->sanitizeFileName($param['startTemplateUrl']); |
|||
$html = file_get_contents($startTemplateUrl); |
|||
} else if (isset($_POST['html'])) { |
|||
$html = substr($_POST['html'], 0, MAX_FILE_LIMIT); |
|||
} |
|||
|
|||
preg_match_all( '~<img.*?src=["\']+(.*?)["\']+.*>~' , $html, $match ); |
|||
|
|||
$imgTagArr = $match[0]; |
|||
$imgSrcArr = $match[1]; |
|||
$maxImgSize = config('system.lazy_load_size'); // 读取文件大小,大于 配置文件 做懒加载
|
|||
|
|||
$oldImgTagArr = []; |
|||
$newImgTagArr = []; |
|||
|
|||
foreach ($imgSrcArr as $key => $value) { |
|||
// 没有需要懒加载的标签,跳过
|
|||
if (strpos($imgTagArr[$key], 'lazy-img') === false) { |
|||
continue; |
|||
} |
|||
|
|||
if (empty($value)) { |
|||
continue; |
|||
} |
|||
if (strpos($value, 'data:') === 0) { |
|||
continue; |
|||
} |
|||
|
|||
if (strpos($value, 'http:') === 0) { |
|||
$fileUrl = $value; |
|||
|
|||
$res = @get_headers($fileUrl,true); |
|||
if (!isset($res['Content-Length'])) { |
|||
continue; |
|||
} |
|||
|
|||
$filesize = round($res['Content-Length']/1024,2); |
|||
} |
|||
else { |
|||
$publicPath = CMS_ROOT . 'public'; |
|||
if (strpos($value, '/') !== 0) { |
|||
$publicPath .= '/'; |
|||
} |
|||
$fileUrl = $publicPath . $value; |
|||
|
|||
if (!file_exists($fileUrl)) { |
|||
continue; |
|||
} |
|||
|
|||
$filesize = filesize($fileUrl); |
|||
$filesize /= pow(1024, 1); |
|||
} |
|||
|
|||
if ($filesize > $maxImgSize) { |
|||
$imgTagArr[$key] = str_replace("data-src='{$value}'", '', $imgTagArr[$key]); |
|||
|
|||
$imgTagReplace = str_replace($value, '/system_file/loading.png', $imgTagArr[$key]); |
|||
$replaceStr = " data-src='{$value}' "; |
|||
$imgTagReplace = substr_replace($imgTagReplace, $replaceStr, 4, 0); |
|||
$oldImgTagArr[] = $imgTagArr[$key]; |
|||
$newImgTagArr[] = $imgTagReplace; |
|||
} |
|||
} |
|||
|
|||
if (!empty($oldImgTagArr)) { |
|||
$html = str_replace($oldImgTagArr, $newImgTagArr, $html); |
|||
} |
|||
|
|||
$jsStr = ' |
|||
<script id="loadingJs" src="/system_file/js/huocms-loading.js"></script> |
|||
</head>'; |
|||
|
|||
if (strpos($html, '/system_file/js/huocms-loading.js') === false) { |
|||
$html = str_replace('</head>', $jsStr, $html); |
|||
} |
|||
|
|||
// 去除图片展示的当前的域名
|
|||
$imgStr = 'src="' . request()->header()['origin']; |
|||
$html = str_replace($imgStr, 'src="', $html); |
|||
// 去除动态添加所显示出的类名
|
|||
$html = str_replace('<script id="baseJs" src="/system_file/js/base.min.js"></script>', '', $html); |
|||
// 去除swiper生成的类名、属性等
|
|||
$html = str_replace('swiper-initialized swiper-horizontal swiper-backface-hidden', '', $html); |
|||
$html = str_replace('swiper-slide-prev', '', $html); |
|||
$html = str_replace('swiper-slide-active', '', $html); |
|||
$html = str_replace('swiper-slide-next', '', $html); |
|||
$html = str_replace('<span class="swiper-notification" aria-live="assertive" aria-atomic="true"></span>', '', $html); |
|||
$pattern = '/role=(\"|\')(.*?)>/i'; |
|||
$replacement = '>'; |
|||
$html = preg_replace($pattern, $replacement, $html); |
|||
$pattern = '/id=(\"|\')swiper-wrapper-(.*?)>/i'; |
|||
$html = preg_replace($pattern, $replacement, $html); |
|||
|
|||
$html = \phpQuery::newDocument($html); |
|||
|
|||
// 根据section的顺序确定各个部分插入的顺序
|
|||
|
|||
$html['head #viewHelp']->remove();//移除可视化时用于方便界面编辑的css
|
|||
|
|||
$blockHtmlArr = []; |
|||
$where = [ |
|||
'seller_id' => $this->admin['seller_id'], |
|||
'website_id' => $param['website_id'], |
|||
'lang' => $param['lang'], |
|||
'is_active' => 1 |
|||
]; |
|||
$Theme = new Theme(); |
|||
$themeFileModel = new ThemeFile(); |
|||
$theme = $Theme->getActiveTheme($where)['data']->toArray(); |
|||
$themeName = $theme['theme']; |
|||
|
|||
$BigField = new BigField(); |
|||
$version = $BigField->where([ |
|||
['seller_id', '=', $this->admin['seller_id']], |
|||
['theme_id', '=', $theme['id']], |
|||
])->max('version'); |
|||
$version = $version ?: 0; |
|||
$version++; |
|||
|
|||
$version = intval($version); |
|||
|
|||
\phpQuery::each($html['body .huocms-block'], function ($key, $item) use ($html, &$blockHtmlArr, $param, $themeName, $saveType, $theme, $version) { |
|||
$domObj = $html['.huocms-block:eq('.$key.')']; |
|||
$includePath = $domObj->attr('data-inclue-path'); // 自己有包含路径或某个子元素有包含路径,需要将代码替换掉
|
|||
|
|||
$components = $domObj->find('.huocms-components'); |
|||
foreach ($components as $obj) { |
|||
$subIncludePath = pq($obj)->attr('data-inclue-path'); |
|||
if (!empty($subIncludePath)) { |
|||
if (pq($obj)->hasClass('huocms-static-edit')) { |
|||
$content = pq($obj)->htmlOuter(); |
|||
$themeFileName = "{$subIncludePath}.html"; |
|||
$filename = $subIncludePath; |
|||
ThemeService::saveThemeFileHistory($param['website_id'], $param['lang'], $theme, $this->admin['seller_id'], $themeFileName, $filename, $content, '', '', $version); |
|||
} |
|||
|
|||
$includeHtml = ' |
|||
{include file="'.$subIncludePath.'"} |
|||
'; |
|||
$next = pq($obj)->next(); |
|||
$parent = pq($obj)->parent(); |
|||
if (empty($next->html())) { |
|||
pq($obj)->remove(); |
|||
$parent->append($includeHtml); |
|||
} else { |
|||
pq($obj)->remove(); |
|||
$next->before($includeHtml); |
|||
} |
|||
} |
|||
} |
|||
|
|||
$blockHtml = ''; |
|||
if (!empty($includePath)) { |
|||
if ($domObj->hasClass('huocms-static-edit')) { |
|||
$content = $domObj->htmlOuter(); |
|||
$themeFileName = "{$includePath}.html"; |
|||
$filename = $includePath; |
|||
ThemeService::saveThemeFileHistory($param['website_id'], $param['lang'], $theme, $this->admin['seller_id'], $themeFileName, $filename, $content, '', '', $version); |
|||
} |
|||
|
|||
$domObj = ' |
|||
{include file="'.$includePath.'"} |
|||
'; |
|||
$blockHtml = $domObj; |
|||
$blockHtmlArr[] = $blockHtml; |
|||
return $item; |
|||
} |
|||
|
|||
$tmpTemplate = $domObj->attr('data-huocms-block'); |
|||
$blockId = $domObj->attr('data-huocms-blockid'); |
|||
$blockType = $this->getBlockType($domObj); |
|||
|
|||
// echo $blockType . '<br/>';
|
|||
|
|||
if (!empty($tmpTemplate) && !empty($blockId)) { |
|||
|
|||
$blockTemplatePath = CMS_ROOT . $this->designBase . DIRECTORY_SEPARATOR . $tmpTemplate; |
|||
$blockHtml = file_get_contents($blockTemplatePath); |
|||
$blockHtml = $this->replaceHtml($blockType, $blockId, $blockHtml, $domObj); |
|||
} else { |
|||
$blockHtml = $domObj; |
|||
} |
|||
|
|||
$blockHtmlArr[] = $blockHtml; |
|||
return $item; |
|||
}); |
|||
|
|||
$html['body .huocms-block']->remove(); |
|||
$html['body #think_page_trace']->remove(); |
|||
$html['body #think_page_trace_open']->remove(); |
|||
$blockHtmlArr = array_reverse($blockHtmlArr); |
|||
foreach ($blockHtmlArr as $value) { |
|||
$html['body']->prepend($value); |
|||
} |
|||
// exit();
|
|||
//保存生成的html
|
|||
|
|||
$pathInfo = pathinfo($param['file']); |
|||
$filename = $pathInfo['filename']; |
|||
|
|||
$filePath = CMS_ROOT . "public/themes/website/{$param['website_id']}/{$param['lang']}/{$themeName}/{$filename}.html"; |
|||
$viewFilePath = CMS_ROOT . "public/themes/hc_original/{$themeName}/{$filename}.html"; |
|||
|
|||
// 替换SEO
|
|||
$html['head meta[name="description"]']->remove(); |
|||
$html['head meta[name="keywords"]']->remove(); |
|||
$html['head title']->remove(); |
|||
$html['head']->prepend($this->getSeoHtml()); |
|||
|
|||
$themeFileName = "{$filename}.html"; |
|||
|
|||
// 保存至版本数据库中
|
|||
$content = $html->html(); |
|||
// 多个换行仅保留一个换行
|
|||
$content = preg_replace("/(\r?\n[ \t]*){2,}/", "\n", $content); |
|||
ThemeService::saveThemeFileHistory($param['website_id'], $param['lang'], $theme, $this->admin['seller_id'], $themeFileName, $filename, $content, '', '', $version); |
|||
|
|||
if ($saveType == 1) { |
|||
echo "保存成功 !"; |
|||
return; |
|||
} |
|||
|
|||
//更新theme_file
|
|||
$themeService = new ThemeService(); |
|||
$suffix = config('view.view_suffix'); |
|||
$res = $themeService->publishThemeFile($theme['id'],$param['website_id'],$this->admin['seller_id'],$suffix, $version); |
|||
$res = $res->getData(); |
|||
if ($res['code'] != 0) { |
|||
echo $res['msg']; |
|||
return; |
|||
} |
|||
|
|||
$themeFileModel->updateThemeFile([ |
|||
['file', '=', $themeFileName], |
|||
['website_id', '=', $param['website_id']], |
|||
['lang', '=', $param['lang']], |
|||
], ['is_design' => 1, 'design_path' => $themeFileName]); |
|||
|
|||
echo "发布成功 !"; |
|||
return; |
|||
} |
|||
|
|||
protected function getBlockType($node) { |
|||
$classes = explode( ' ', $node->attr('class')); |
|||
$blockType = ''; |
|||
foreach ($classes as $class) { |
|||
if ($class != 'huocms-components' && $class != 'huocms-block') { |
|||
$blockType = $class; |
|||
break; |
|||
} |
|||
} |
|||
return $blockType; |
|||
} |
|||
|
|||
public function replaceHtml($blockType, $id, $html, $node) |
|||
{ |
|||
if (strpos($blockType, 'block') !== false) { |
|||
// 替换模板里的navID
|
|||
$blockHtml = str_replace('hcTaglib:category id="1"', 'hcTaglib:category id="' . $id . '"', $html); |
|||
} elseif ($blockType == 'huocms-nav') { |
|||
// 替换模板里的navID
|
|||
$blockHtml = str_replace('hcTaglib:nav cid="2"', 'hcTaglib:nav cid="' . $id . '"', $html); |
|||
} elseif ($blockType == 'huocms-banner') { |
|||
// 替换模板里的navID
|
|||
$blockHtml = str_replace('hcTaglib:slide cid="1"', 'hcTaglib:slide cid="' . $id . '"', $html); |
|||
} else { |
|||
$blockHtml = $node; |
|||
} |
|||
return $blockHtml; |
|||
} |
|||
|
|||
public function getSeoHtml() |
|||
{ |
|||
return ' |
|||
<title>{$current_cate.seo_title|default=$current_cate.title}</title> |
|||
<meta name="description" content="{$current_cate.seo_description|default=$current_cate.title}"> |
|||
<meta name="keywords" content="{$current_cate.seo_keywords|default=$current_cate.title}">'; |
|||
} |
|||
|
|||
|
|||
// setting接口
|
|||
public function getSetting() |
|||
{ |
|||
|
|||
} |
|||
|
|||
/** |
|||
* 单个链接列表接口 |
|||
* 基础链接:客服链接,icp备案链接,公安备案链接 |
|||
* 栏目链接 |
|||
* 内容链接 |
|||
* @return Json |
|||
*/ |
|||
public function getLinkList() |
|||
{ |
|||
$param = $this->request->param(); |
|||
// 数据验证
|
|||
try { |
|||
validate(WebsiteSettingValidate::class)->scene('read')->check($param); |
|||
} catch (ValidateException $e) { |
|||
return jsonReturn(-1, $e->getError()); |
|||
} |
|||
$where = [ |
|||
'seller_id' => $this->admin['seller_id'], |
|||
'website_id' => $param['website_id'], |
|||
'lang' => $param['lang'], |
|||
]; |
|||
|
|||
$websiteSetting = new WebsiteSetting(); |
|||
$res = $websiteSetting->getWebsiteSetting($where); |
|||
$res['data'] = $res['data']->toArray(); |
|||
$res['data']['setting'] = json_decode($res['data']['setting'], true); |
|||
$link = [ |
|||
'name' => '基本链接', |
|||
'value' => '', |
|||
'child' => [ |
|||
[ |
|||
'name' => '客服链接', |
|||
'value' => $res['data']['setting']['customer_code'] ?? '', |
|||
], |
|||
[ |
|||
'name' => 'icp备案链接', |
|||
'value' => $res['data']['setting']['icp_link'] ?? '', |
|||
], |
|||
[ |
|||
'name' => '公网安备链接', |
|||
'value' => $res['data']['setting']['gwa_link'] ?? '', |
|||
], |
|||
] |
|||
]; |
|||
|
|||
$categoryList = $this->categoryList(); |
|||
|
|||
$cate = [ |
|||
'name' => '栏目链接', |
|||
'value' => '', |
|||
'child' => $categoryList, |
|||
]; |
|||
|
|||
|
|||
$data = [ |
|||
'link' => $link, |
|||
'cate' => $cate, |
|||
'content' => [], |
|||
]; |
|||
|
|||
return jsonReturn(0, '成功', $data); |
|||
} |
|||
|
|||
// 导航接口
|
|||
public function getNavList() |
|||
{ |
|||
|
|||
} |
|||
|
|||
// 友情链接接口
|
|||
public function getFriendLink() |
|||
{ |
|||
|
|||
} |
|||
|
|||
public function getCategoryList() |
|||
{ |
|||
return jsonReturn(0, '成功', $this->categoryList()); |
|||
} |
|||
|
|||
public function categoryListSetWhere(&$where, $type) |
|||
{ |
|||
switch ($type) { |
|||
case 'suq_block1': |
|||
case 'suq_block2_contact': |
|||
case 'suq_block3': |
|||
case 'suq_block4': |
|||
case 'suq_block5': |
|||
case 'suq_block6': |
|||
case 'suq_footer': |
|||
$where[] = ['type', 'in', [2,3]]; |
|||
$where[] = ['id', '>', 1]; |
|||
break; |
|||
case 'suq_block2': |
|||
$where[] = ['id', '>', 1]; |
|||
break; |
|||
default: |
|||
break; |
|||
} |
|||
} |
|||
|
|||
// 栏目列表接口
|
|||
protected function categoryList() |
|||
{ |
|||
$param = $this->request->param(); |
|||
$where = [ |
|||
['seller_id', '=', $this->admin['seller_id']], |
|||
['website_id', '=', $param['website_id']], |
|||
]; |
|||
$lang = $param['lang'] ?? ''; |
|||
if (empty($lang)) { |
|||
$lang = 'zh'; |
|||
} |
|||
$Website = new Website(); |
|||
$website = $Website->getWebsite(['id' => $param['website_id'], 'seller_id' => $this->admin['seller_id']])['data']; |
|||
$domain = $website['domain']; |
|||
if ($lang != 'zh') { |
|||
$domain = $domain . '/' . $lang; |
|||
} |
|||
$where[] = ['lang', '=', $lang]; |
|||
|
|||
if(isset($param['type'])) { |
|||
$this->categoryListSetWhere($where, $param['type']); |
|||
} |
|||
|
|||
$cateModel = new Category(); |
|||
$categoryList = $cateModel->where($where)->field('id,type,title,alias')->select()->each(function (&$item) use ($domain) { |
|||
if ($item['type'] == 1 || $item['type'] == 4) { |
|||
if (!empty($item['alias'])) { |
|||
if ($item['alias'] == '/') { |
|||
$item['fullUrl'] = 'http://' . $domain; |
|||
} else { |
|||
$item['fullUrl'] = 'http://' . $domain . $item['alias'] . '.' . config('route.url_html_suffix'); |
|||
} |
|||
} else { |
|||
$item['fullUrl'] = 'http://' . $domain . '/list/index/' . $item['id'] . '.' . config('route.url_html_suffix'); |
|||
} |
|||
} else if ($item['type'] == 3) { |
|||
$item['fullUrl'] = $item['alias']; |
|||
} else { |
|||
$item['fullUrl'] = 'javascript:;'; |
|||
} |
|||
}); |
|||
return $categoryList->toArray(); |
|||
} |
|||
|
|||
// 栏目内容接口
|
|||
public function getCategoryData() |
|||
{ |
|||
$param = $this->request->param(); |
|||
$categoryModel = new Category(); |
|||
$contentModel = new SubContent(); |
|||
$category = []; |
|||
$subCategory = []; |
|||
//获取此栏目数据和下面所有子栏目数据,并且拿到所有栏目下的内容数据
|
|||
if ($param['type'] == 'suq_block1') { |
|||
//获取选择栏目的的标题和副标题,再获取子栏目的名称和缩略图
|
|||
//最后获取子栏目的内容列表
|
|||
$category = $categoryModel->getCategory([ |
|||
['id', '=', $param['category_id']], |
|||
['type', 'in', [2,3]], |
|||
], [], 'id, type, title, sub_title, alias')['data']; |
|||
$subCategory = $categoryModel->where([ |
|||
['parent_id', '=', $param['category_id']], |
|||
['type', 'in', [2,3]], |
|||
])->with(['thumbnail'])->field('id, type, title, sub_title, desc, thumbnail, alias')->select(); |
|||
|
|||
foreach ($subCategory as &$subCate) { |
|||
$subCate['content'] = $contentModel->alias('a') |
|||
->join('category_sub_content b', 'b.sub_content_id = a.id', 'left') |
|||
->with(['thumbnail']) |
|||
->where([ |
|||
['b.category_id', '=', $subCate['id']] |
|||
]) |
|||
->field('a.id, title, thumbnail') |
|||
->select(); |
|||
} |
|||
} else if ($param['type'] == 'suq_block2' || |
|||
$param['type'] == 'suq_block3' || |
|||
$param['type'] == 'suq_block4' || |
|||
$param['type'] == 'suq_footer') { |
|||
$category = $categoryModel->getCategory([ |
|||
['id', '=', $param['category_id']], |
|||
['type', 'in', [2,3]], |
|||
], ['thumbnail'], 'id, type, title, sub_title, desc, alias, thumbnail, description')['data']; |
|||
$contentList = $contentModel->alias('a') |
|||
->join('category_sub_content b', 'b.sub_content_id = a.id', 'left') |
|||
->with(['thumbnail']) |
|||
->where([ |
|||
['b.category_id', '=', $param['category_id']] |
|||
]) |
|||
->field('a.id, title, sub_title, description, thumbnail') |
|||
->select()->toArray(); |
|||
|
|||
foreach ($contentList as &$value) { |
|||
if (isset($value['thumbnail']['url'])) { |
|||
$value['thumbnail_url'] = $value['thumbnail']['url']; |
|||
} |
|||
if (in_array($category['type'], [1,2,4])) { |
|||
$value['href'] = hcUrl('detail/index', ['cid' => $param['category_id'], 'id' => $value['id']]); |
|||
} else { |
|||
$value['href'] = $category['alias']; |
|||
} |
|||
} |
|||
|
|||
$category['content'] = $contentList; |
|||
} else if ($param['type'] == 'suq_block5' || |
|||
$param['type'] == 'suq_block6' || |
|||
$param['type'] == 'suq_block2_contact') { |
|||
$category = $categoryModel->getCategory([ |
|||
['id', '=', $param['category_id']], |
|||
['type', 'in', [2,3]], |
|||
], ['thumbnail'], 'id, type, title, sub_title, desc, alias, thumbnail, description, seo_description')['data']; |
|||
} |
|||
$returnData = [ |
|||
'category' => $category, |
|||
'subCategory' => $subCategory, |
|||
]; |
|||
return jsonReturn(0, '成功', $returnData); |
|||
|
|||
} |
|||
|
|||
// 内容列表接口
|
|||
public function getContentList() |
|||
{ |
|||
|
|||
} |
|||
|
|||
|
|||
// 内容详情接口
|
|||
|
|||
// 幻灯片接口
|
|||
|
|||
// 广告接口
|
|||
|
|||
|
|||
// 获取模板文件历史版本
|
|||
public function getHistoryList() |
|||
{ |
|||
$param = $this->request->param(); |
|||
$initPage = $param['init_page'] ?? 'index'; |
|||
$initPageName = $initPage . '.html'; |
|||
$param['limit'] = $param['limit'] ?? 100; |
|||
|
|||
$themeModel = new Theme(); |
|||
$themeId = $themeModel->where([ |
|||
['website_id', '=', $param['website_id']], |
|||
['lang', '=', $param['lang']], |
|||
['is_active', '=', 1], |
|||
])->value('id'); |
|||
|
|||
if (empty($themeId)) { |
|||
return jsonReturn(-1, '当前站点没有激活的模板,请先去安装模板'); |
|||
} |
|||
|
|||
// 获取当前模板文件id
|
|||
$themeFileModel = new ThemeFile(); |
|||
$themeFileId = $themeFileModel->where([ |
|||
['website_id', '=', $param['website_id']], |
|||
['lang', '=', $param['lang']], |
|||
['theme_id', '=', $themeId], |
|||
['file', '=', $initPageName], |
|||
])->value('id'); |
|||
|
|||
if (empty($themeFileId)) { |
|||
return jsonReturn(-2, '模板文件不存在'); |
|||
} |
|||
|
|||
$bigFieldModel = new BigField(); |
|||
$list = $bigFieldModel->alias('a') |
|||
->join('admin b', 'b.id = a.admin_id', 'left') |
|||
->join('theme_file c', 'a.theme_file_id = c.id') |
|||
->where([ |
|||
['a.theme_id', '=', $themeId], |
|||
['a.theme_file_id', '=', $themeFileId], |
|||
])->field('a.*, b.name as admin_name, c.file')->order('id desc')->paginate($param['limit']); |
|||
|
|||
return json(pageReturn(dataReturn(0, '', $list))); |
|||
} |
|||
|
|||
public function setPreviewPage() |
|||
{ |
|||
$param = $this->request->param(); |
|||
$initPage = $param['init_page'] ?? 'index'; |
|||
$initPageName = $initPage . '.html'; |
|||
$version = $param['version'] ?? 1; // 将此版本的所有文件都塞入view下
|
|||
|
|||
$themeModel = new Theme(); |
|||
$theme = $themeModel->where([ |
|||
['website_id', '=', $param['website_id']], |
|||
['lang', '=', $param['lang']], |
|||
['is_active', '=', 1], |
|||
])->field('id, theme')->find(); |
|||
|
|||
if (empty($theme['id'])) { |
|||
return jsonReturn(-1, '当前站点没有激活的模板,请先去安装模板'); |
|||
} |
|||
|
|||
ThemeService::updatePreviewFile($param, $version, $theme); |
|||
|
|||
session('history-view', time()); |
|||
|
|||
return jsonReturn(0, '预览初始化成功'); |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,27 @@ |
|||
<?php |
|||
|
|||
namespace app\controller\backend; |
|||
|
|||
use think\facade\Cache; |
|||
use think\response\Json; |
|||
|
|||
class ExcelController |
|||
{ |
|||
|
|||
|
|||
/** |
|||
* 下载 |
|||
* @return array|Json |
|||
*/ |
|||
public function downInquiryExcel() |
|||
{ |
|||
$token = input('param.token'); |
|||
$data = Cache::get( $token ); |
|||
// Cache::delete($token);
|
|||
if(!empty($data)){ |
|||
return createDownloadExcel( $data['file_name'], $data['sheet_name'], $data['head'], $data['data'], $data['matched']); |
|||
} |
|||
return jsonReturn(-1,'已过期'); |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,585 @@ |
|||
<?php |
|||
|
|||
namespace app\controller\backend; |
|||
|
|||
use app\model\DiyForm; |
|||
use Overtrue\Pinyin\Pinyin; |
|||
use PhpOffice\PhpSpreadsheet\Spreadsheet; |
|||
use PhpOffice\PhpSpreadsheet\Writer\Xlsx; |
|||
use think\facade\Cache; |
|||
use think\facade\Db; |
|||
|
|||
class FormController extends BaseController |
|||
{ |
|||
public function index(DiyForm $diyFormModel) |
|||
{ |
|||
$limit = input('param.limit'); |
|||
$name = input('param.name'); |
|||
|
|||
$where[] = ['is_del', '=', 1]; |
|||
$where[] = ['seller_id', '=', $this->admin['seller_id']]; |
|||
if (!empty($name)) { |
|||
$where[] = ['name', 'like', '%' . $name . '%']; |
|||
} |
|||
|
|||
try { |
|||
|
|||
$list = $diyFormModel->where($where)->order('id desc')->paginate($limit); |
|||
} catch (\Exception $e) { |
|||
return jsonReturn(-1, $e->getMessage()); |
|||
} |
|||
|
|||
return json(pageReturn(dataReturn(0, lang('成功'), $list))); |
|||
} |
|||
|
|||
public function info(DiyForm $diyFormModel) |
|||
{ |
|||
$id = $this->request->param('id'); |
|||
|
|||
$info = $diyFormModel->where('id', $id)->find(); |
|||
if (empty($info)) { |
|||
return jsonReturn(-3, lang('该表单不存在')); |
|||
} |
|||
|
|||
return jsonReturn(0, lang('获取成功'), $info); |
|||
} |
|||
|
|||
public function add(DiyForm $diyFormModel) |
|||
{ |
|||
$param = input('post.'); |
|||
|
|||
if (empty($param['name'])) { |
|||
return jsonReturn(-1, lang('请输入表单名称')); |
|||
} |
|||
|
|||
try { |
|||
|
|||
$has = $diyFormModel->where('name', $param['name'])->find(); |
|||
if (!empty($has)) { |
|||
return jsonReturn(-3, lang('该表单已经存在')); |
|||
} |
|||
|
|||
$pinyinModel = new Pinyin(); |
|||
$tableName = $pinyinModel->abbr($param['name']); |
|||
$has = $diyFormModel->where('table', $tableName)->find(); |
|||
if (!empty($has)) { |
|||
$tableName = $tableName . '_' . uniqid(); |
|||
} |
|||
|
|||
$param['seller_id'] = $this->admin['seller_id']; |
|||
$param['table'] = $tableName; |
|||
$param['code'] = uniqid(); // 表单唯一标识
|
|||
$param['create_time'] = date('Y-m-d H:i:s'); |
|||
|
|||
$diyFormModel->insert($param); |
|||
} catch (\Exception $e) { |
|||
return jsonReturn(-4, $e->getMessage()); |
|||
} |
|||
|
|||
return jsonReturn(0, lang('添加成功')); |
|||
} |
|||
|
|||
public function edit(DiyForm $diyFormModel) |
|||
{ |
|||
$param = input('post.'); |
|||
|
|||
if (empty($param['name'])) { |
|||
return jsonReturn(-1, lang('请输入表单名称')); |
|||
} |
|||
|
|||
try { |
|||
|
|||
$has = $diyFormModel->where('name', $param['name'])->where('id', '<>', $param['id'])->find(); |
|||
if (!empty($has)) { |
|||
return jsonReturn(-3, lang('该表单已经存在')); |
|||
} |
|||
|
|||
$pinyinModel = new Pinyin(); |
|||
$tableName = $pinyinModel->abbr($param['name']); |
|||
$has = $diyFormModel->where('table', $tableName)->where('id', '<>', $param['id'])->find(); |
|||
if (!empty($has)) { |
|||
$tableName = $tableName . '_' . uniqid(); |
|||
} |
|||
|
|||
$param['table'] = $tableName; |
|||
$param['update_time'] = date('Y-m-d H:i:s'); |
|||
$diyFormModel->where('id', $param['id'])->update($param); |
|||
} catch (\Exception $e) { |
|||
return jsonReturn(-4, $e->getMessage()); |
|||
} |
|||
|
|||
return jsonReturn(0, lang('编辑成功')); |
|||
} |
|||
|
|||
public function del(DiyForm $diyFormModel) |
|||
{ |
|||
$id = input('param.id'); |
|||
try { |
|||
$info = $diyFormModel->where('id', $id)->find(); |
|||
if ($info['status'] == 2) { |
|||
return jsonReturn(-1, lang('该表单已经发布,请先卸载')); |
|||
} |
|||
|
|||
$diyFormModel->where('id', $id)->delete(); |
|||
} catch (\Exception $e) { |
|||
return jsonReturn(-2, $e->getMessage()); |
|||
} |
|||
|
|||
return jsonReturn(0, lang('删除成功')); |
|||
} |
|||
|
|||
public function detail(DiyForm $diyFormModel) |
|||
{ |
|||
$param = input('param.'); |
|||
try { |
|||
|
|||
$info = $diyFormModel->where('id', $param['id'])->find(); |
|||
$formJson = json_decode($info['design_content'], true); |
|||
|
|||
$field2Dict = []; |
|||
$header = []; |
|||
|
|||
foreach ($formJson as $vo) { |
|||
if (!isset($vo['field'])) { |
|||
continue; |
|||
} |
|||
|
|||
$header[] = [ |
|||
'label' => $vo['title'], |
|||
'property' => $vo['field'], |
|||
'type' => $vo['type'], |
|||
'options' => $vo['options'] ?? '' |
|||
]; |
|||
|
|||
// 为了方便字典翻译,优化前端显示
|
|||
if (isset($vo['options'])) { |
|||
|
|||
$dictDataMap = []; |
|||
foreach ($vo['options'] as $k => $v) { |
|||
$dictDataMap[$v['value']] = $v['label']; |
|||
} |
|||
|
|||
$field2Dict[$vo['field']] = $dictDataMap; |
|||
} |
|||
|
|||
if ($vo['type'] == 'switch') { |
|||
$dictDataMap = []; |
|||
$dictDataMap[$vo['props']['activeValue']] = $vo['props']['activeText']; |
|||
$dictDataMap[$vo['props']['inactiveValue']] = $vo['props']['inactiveText']; |
|||
$field2Dict[$vo['field']] = $dictDataMap; |
|||
} |
|||
|
|||
} |
|||
|
|||
$param['queryParams'] = json_decode($param['queryParams'], true); |
|||
|
|||
if (!empty($param['queryParams']) && |
|||
!empty($param['queryParams']['condition']) && |
|||
!empty($param['queryParams']['childTips'])) { |
|||
|
|||
$where = $this->buildWhere($param['queryParams']['childTips']); |
|||
if ($param['queryParams']['condition'] == 'and') { |
|||
|
|||
|
|||
$data = Db::table(makeFormTable($info['table']))->where($where) |
|||
->order('id', 'desc')->paginate($param['limit']); |
|||
} else if ($param['queryParams']['condition'] == 'or') { |
|||
|
|||
$data = Db::table(makeFormTable($info['table']))->whereOr($where) |
|||
->order('id', 'desc')->paginate($param['limit']); |
|||
} |
|||
|
|||
} else { |
|||
|
|||
$data = Db::table(makeFormTable($info['table'])) |
|||
->order('id', 'desc')->paginate($param['limit']); |
|||
} |
|||
|
|||
$data = $data->each(function ($item) use ($field2Dict) { |
|||
|
|||
foreach ($item as $key => $vo) { |
|||
|
|||
if (isset($field2Dict[$key])) { |
|||
|
|||
$showValueMap = []; |
|||
$valueMap = explode(',', $vo); |
|||
|
|||
foreach ($valueMap as $valueKey) { |
|||
$showValueMap[] = isset($field2Dict[$key][$valueKey]) ? $field2Dict[$key][$valueKey] : $valueKey; |
|||
} |
|||
|
|||
$item[$key] = implode(',', $showValueMap); |
|||
} |
|||
} |
|||
|
|||
return $item; |
|||
}); |
|||
|
|||
} catch (\Exception $e) { |
|||
return jsonReturn(-3, $e->getMessage() . $e->getLine()); |
|||
} |
|||
|
|||
return jsonReturn(0, 'success', [ |
|||
'header' => $header, |
|||
'data' => $data->getCollection(), |
|||
'total' => $data->total() |
|||
]); |
|||
} |
|||
|
|||
public function deploy(DiyForm $diyFormModel) |
|||
{ |
|||
$id = input('param.id'); |
|||
$info = $diyFormModel->where('id', $id)->find(); |
|||
|
|||
if ($info['status'] == 2) { |
|||
return jsonReturn(-1, lang('该表单已经发布,无需再次发布')); |
|||
} |
|||
|
|||
if (empty($info['design_content'])) { |
|||
return jsonReturn(-2, lang('请先完成表单设计')); |
|||
} |
|||
|
|||
$tableName = makeFormTable($info['table']); |
|||
$title = $info['name']; |
|||
|
|||
$column = ''; |
|||
$columnMap = json_decode($info['design_content'], true); |
|||
foreach ($columnMap as $key => $vo) { |
|||
|
|||
if (empty($vo['field'])) { |
|||
continue; |
|||
} |
|||
|
|||
// 强迫症为了dd打印的时候格式对其,其实没啥意义
|
|||
$tab = ''; |
|||
if ($key > 0) { |
|||
$tab = ' '; |
|||
} |
|||
|
|||
$column .= $tab . '`' . $vo['field'] . '` varchar(255) NULL DEFAULT NULL COMMENT "' . $vo['title'] . '",' . PHP_EOL; |
|||
} |
|||
|
|||
try { |
|||
|
|||
$sql = <<<EOL |
|||
CREATE TABLE `{$tableName}` ( |
|||
`id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT "id", |
|||
{$column} `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT "创建时间", |
|||
`update_time` datetime NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT "更新时间", |
|||
`visitor_id` varchar(255) DEFAULT '' COMMENT '前端标识', |
|||
`sub_id` int(11) DEFAULT 0 COMMENT '关联内容id', |
|||
`ip` varchar(20) DEFAULT '', |
|||
`user_agent` varchar(255) DEFAULT '' COMMENT '浏览器标识', |
|||
PRIMARY KEY (`id`) |
|||
)ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 COMMENT='{$title}'; |
|||
EOL; |
|||
Db::execute($sql); |
|||
|
|||
$diyFormModel->where('id', $id)->update([ |
|||
'status' => 2, |
|||
'update_time' => date('Y-m-d H:i:s') |
|||
]); |
|||
} catch (\Exception $e) { |
|||
return jsonReturn(-4, $e->getMessage()); |
|||
} |
|||
|
|||
return jsonReturn(0, lang('部署成功')); |
|||
} |
|||
|
|||
public function undeploy(DiyForm $diyFormModel) |
|||
{ |
|||
$id = input('param.id'); |
|||
|
|||
$info = $diyFormModel->where('id', $id)->find(); |
|||
if ($info['status'] != 2) { |
|||
return jsonReturn(-1, lang('该表单尚未发布,无法卸载')); |
|||
} |
|||
|
|||
try { |
|||
|
|||
Db::query('DROP TABLE IF EXISTS `' . makeFormTable($info['table']) . '`'); |
|||
$diyFormModel->where('id', $id)->update([ |
|||
'status' => 1, |
|||
'update_time' => date('Y-m-d H:i:s') |
|||
]); |
|||
} catch (\Exception $e) { |
|||
return jsonReturn(-1, $e->getMessage()); |
|||
} |
|||
|
|||
return jsonReturn(0, lang('卸载成功')); |
|||
} |
|||
|
|||
// 获取问题和答案详情
|
|||
public function quesDetail(DiyForm $diyFormModel) |
|||
{ |
|||
$param = input('param.'); |
|||
try { |
|||
|
|||
$info = $diyFormModel->where('id', $param['id'])->find(); |
|||
$formJson = json_decode($info['design_content'], true); |
|||
|
|||
$field2Dict = []; |
|||
$header = []; |
|||
|
|||
foreach ($formJson as $vo) { |
|||
if (!isset($vo['field'])) { |
|||
continue; |
|||
} |
|||
|
|||
$header[$vo['field']] = [ |
|||
'label' => $vo['title'], |
|||
'property' => $vo['field'], |
|||
'type' => $vo['type'], |
|||
'options' => [] |
|||
]; |
|||
|
|||
if ($vo['type'] == 'switch') { |
|||
$header[$vo['field']]['options'][$vo['props']['activeValue']] = ['label' => $vo['props']['activeText']]; |
|||
$header[$vo['field']]['options'][$vo['props']['inactiveValue']] = ['label' => $vo['props']['inactiveText']]; |
|||
} |
|||
|
|||
if (!empty($vo['options'])) { |
|||
foreach ($vo['options'] as $v) { |
|||
$header[$vo['field']]['options'][$v['value']] = $v; |
|||
} |
|||
} |
|||
} |
|||
|
|||
$param['queryParams'] = json_decode($param['queryParams'], true); |
|||
|
|||
if (!empty($param['queryParams']) && |
|||
!empty($param['queryParams']['condition']) && |
|||
!empty($param['queryParams']['childTips'])) { |
|||
|
|||
$where = $this->buildWhere($param['queryParams']['childTips']); |
|||
|
|||
if ($param['queryParams']['condition'] == 'and') { |
|||
|
|||
$data = Db::table(makeFormTable($info['table']))->where($where)->select(); |
|||
|
|||
} else if ($param['queryParams']['condition'] == 'or') { |
|||
|
|||
$data = Db::table(makeFormTable($info['table']))->whereOr($where)->select(); |
|||
} else { |
|||
$data = []; |
|||
} |
|||
} else { |
|||
$data = Db::table(makeFormTable($info['table']))->select(); |
|||
} |
|||
|
|||
|
|||
$newData = []; |
|||
$quesNum = 1; |
|||
foreach ($header as $key => $value) { |
|||
foreach ($data as $item) { |
|||
if (!isset($item[$key])) { |
|||
continue; |
|||
} |
|||
|
|||
$newData[$key]['quesNum'] = $quesNum; |
|||
$newData[$key]['type'] = $value['type']; |
|||
$newData[$key]['ques'] = $value['label']; |
|||
|
|||
if (!isset($newData[$key]['total'])) { |
|||
$newData[$key]['total'] = 0; |
|||
} |
|||
if ($value['type'] == 'input' || $value['type'] == 'timePicker' || $value['type'] == 'datePicker') { |
|||
$newData[$key]['type_name'] = '填空'; |
|||
$newData[$key]['type'] = 'list'; |
|||
// 填空题 ,填的才是答案,使用列表展示
|
|||
$newData[$key]['total']++; |
|||
|
|||
$newData[$key]['detail'][] = [ |
|||
'id' => $item['id'], |
|||
'answer' => $item[$key], |
|||
]; |
|||
} else if ($value['type'] == 'radio' || $value['type'] == 'select' || $value['type'] == 'switch') { |
|||
$newData[$key]['type_name'] = '单选'; |
|||
$newData[$key]['type'] = 'radio'; |
|||
// 单选题 使用饼图展示,需要计算百分比
|
|||
$newData[$key]['total']++; |
|||
|
|||
if (isset($newData[$key]['detail'][$item[$key]]['count'])) { |
|||
$newData[$key]['detail'][$item[$key]]['count']++; |
|||
} else { |
|||
$newData[$key]['detail'][$item[$key]]['answer'] = $value['options'][$item[$key]]['label']; |
|||
$newData[$key]['detail'][$item[$key]]['count'] = 1; |
|||
} |
|||
} else if ($value['type'] == 'slider' || $value['type'] == 'rate') { |
|||
$newData[$key]['type_name'] = '滑块/打分'; |
|||
$newData[$key]['type'] = 'rate'; |
|||
$newData[$key]['total']++; |
|||
if (isset($newData[$key]['detail'][$item[$key]]['count'])) { |
|||
$newData[$key]['detail'][$item[$key]]['count']++; |
|||
} else { |
|||
$newData[$key]['detail'][$item[$key]]['answer'] = $item[$key]; |
|||
$newData[$key]['detail'][$item[$key]]['count'] = 1; |
|||
} |
|||
} else if ($value['type'] == 'checkbox') { |
|||
$newData[$key]['type_name'] = '多选'; |
|||
// 多选题 默认使用柱状图,需要计算百分比
|
|||
$answer = explode(',', $item[$key]); |
|||
foreach ($answer as $v) { |
|||
$newData[$key]['total']++; |
|||
|
|||
if (isset($newData[$key]['detail'][$v]['count'])) { |
|||
$newData[$key]['detail'][$v]['count']++; |
|||
} else { |
|||
$newData[$key]['detail'][$v]['answer'] = $value['options'][$v]['label']; |
|||
$newData[$key]['detail'][$v]['count'] = 1; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
$quesNum++; |
|||
} |
|||
|
|||
// 整理成前端echart需要的数据
|
|||
foreach ($newData as &$value) { |
|||
if ($value['type'] == 'list') { |
|||
continue; |
|||
} |
|||
$newDetail = []; |
|||
foreach ($value['detail'] as $v) { |
|||
$newDetail['data'][] = [ |
|||
'name' => $v['answer'], |
|||
'value' => $v['count'], |
|||
]; |
|||
$newDetail['nameArr'][] = $v['answer']; |
|||
$newDetail['valueArr'][] = $v['count']; |
|||
} |
|||
$value['detail'] = $newDetail; |
|||
} |
|||
|
|||
// dd($newData);
|
|||
|
|||
} catch (\Exception $e) { |
|||
return jsonReturn(-3, $e->getMessage() . $e->getLine()); |
|||
} |
|||
|
|||
return jsonReturn(0, lang('成功'), [ |
|||
'header' => array_values($header), |
|||
'data' => $newData, |
|||
'total' => count($newData), |
|||
]); |
|||
} |
|||
|
|||
private function buildWhere($childTips) |
|||
{ |
|||
$where = []; |
|||
|
|||
foreach ($childTips as $vo) { |
|||
|
|||
switch ($vo['rule']) { |
|||
|
|||
case 'eq': |
|||
$where[] = [$vo['field'], '=', $vo['val']]; |
|||
break; |
|||
case 'like': |
|||
$where[] = [$vo['field'], 'like', '%' . $vo['val'] . '%']; |
|||
break; |
|||
case 'left_like': |
|||
$where[] = [$vo['field'], 'like', '%' . $vo['val']]; |
|||
break; |
|||
case 'right_like': |
|||
$where[] = [$vo['field'], 'like', $vo['val'] . '%']; |
|||
break; |
|||
case 'neq': |
|||
$where[] = [$vo['field'], '<>', $vo['val']]; |
|||
break; |
|||
case 'gt': |
|||
$where[] = [$vo['field'], '>', $vo['val']]; |
|||
break; |
|||
case 'gte': |
|||
$where[] = [$vo['field'], '>=', $vo['val']]; |
|||
break; |
|||
break; |
|||
case 'lt': |
|||
$where[] = [$vo['field'], '<', $vo['val']]; |
|||
break; |
|||
case 'lte': |
|||
$where[] = [$vo['field'], '<=', $vo['val']]; |
|||
break; |
|||
} |
|||
} |
|||
|
|||
return $where; |
|||
} |
|||
|
|||
/** |
|||
* 表单下载 |
|||
*/ |
|||
public function exportForm() |
|||
{ |
|||
$id = $this->request->param('id/d', 0); |
|||
$queryParams = $this->request->param('queryParams', ''); |
|||
|
|||
$queryParams = !empty($queryParams) ? json_decode($queryParams, true) : []; |
|||
//通过id找到表单的表名
|
|||
$diyFormModel = new DiyForm(); |
|||
$tableInfo = $diyFormModel->where([ |
|||
'id' => $id, |
|||
'is_del' => 1, |
|||
'seller_id' => $this->admin['seller_id'] |
|||
])->field('table,id')->find(); |
|||
if (empty($tableInfo)) { |
|||
return jsonReturn(-1, '表单不存在'); |
|||
} |
|||
$tableName = $tableInfo['table']; |
|||
$tableName = makeFormTable($tableName); |
|||
$tableStruct = Db::query("SHOW FULL COLUMNS FROM {$tableName}"); |
|||
|
|||
$columnList = $keys = $title = []; |
|||
|
|||
foreach ($tableStruct as $struct) { |
|||
if (in_array($struct['Field'], ['id', 'sub_id'])) { |
|||
continue; |
|||
} |
|||
$title[] = $struct['Comment']; |
|||
$keys[] =$struct['Field']; |
|||
} |
|||
|
|||
$list = []; |
|||
if (!empty($queryParams) && |
|||
!empty($queryParams['condition']) && |
|||
!empty($queryParams['childTips'])) { |
|||
|
|||
$where = $this->buildWhere($queryParams['childTips']); |
|||
if ($queryParams['condition'] == 'and') { |
|||
$list = Db::table($tableName)->where($where) |
|||
->order('id', 'desc')->select(); |
|||
} else if ($queryParams['condition'] == 'or') { |
|||
$list = Db::table($tableName)->whereOr($where) |
|||
->order('id', 'desc')->select(); |
|||
} |
|||
} else { |
|||
$list = Db::table($tableName) |
|||
->order('id', 'desc')->select(); |
|||
} |
|||
|
|||
$spreadsheet = new Spreadsheet(); |
|||
$activeWorksheet = $spreadsheet->getActiveSheet(); |
|||
$total = count($keys); |
|||
for ($i = 0; $i < $total; $i++) { |
|||
$column = getSheetColLabel($i + 1); |
|||
$cell = $column . '1'; |
|||
$columnList[] = $column; |
|||
$activeWorksheet->setCellValue($cell, $title[$i]); |
|||
} |
|||
|
|||
foreach ($list as $k => $v) { |
|||
for ($x = 0; $x < $total; $x++) { |
|||
$activeWorksheet->setCellValue($columnList[$x] . ($k + 2), $v[$keys[$x]]); |
|||
} |
|||
} |
|||
|
|||
if(!file_exists('excel')){ |
|||
mkdir("excel",0777,true); |
|||
} |
|||
$writer = new Xlsx($spreadsheet); |
|||
$filename = 'form'.date("YmdHis").'.xlsx'; |
|||
$writer->save("./excel/".$filename); |
|||
return jsonReturn(0, '成功', ['url' => '/excel/'.$filename]); |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,14 @@ |
|||
<?php |
|||
|
|||
namespace app\controller\backend; |
|||
|
|||
use app\service\GoogleRequest; |
|||
|
|||
class GoogleStatisticsController extends \app\BaseController |
|||
{ |
|||
public function read() { |
|||
$googleStatistics = new GoogleRequest(); |
|||
$googleStatistics->start(); |
|||
|
|||
} |
|||
} |
|||
@ -0,0 +1,154 @@ |
|||
<?php |
|||
declare (strict_types = 1); |
|||
|
|||
namespace app\controller\backend; |
|||
|
|||
use app\exception\ModelException; |
|||
use app\model\InnerChart; |
|||
use app\validate\InnerChartValidate; |
|||
use think\exception\ValidateException; |
|||
use think\facade\Lang; |
|||
|
|||
class InnerChartController extends BaseController |
|||
{ |
|||
/** |
|||
* 显示资源列表 |
|||
* |
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function index(InnerChart $innerChart): \think\response\Json |
|||
{ |
|||
|
|||
$limit = $this->setLimit(); |
|||
$type = input('type'); |
|||
$siteId = (int)input('website_id'); |
|||
if(empty($type)){ |
|||
$type = 1; |
|||
} |
|||
$where = [ |
|||
['seller_id' ,'=', $this->admin['seller_id']], |
|||
['type' ,'=', $type], |
|||
]; |
|||
|
|||
if ($type != 2) { |
|||
$where[] = ['website_id','=',$siteId]; |
|||
} |
|||
|
|||
$keyword = input('keyword'); |
|||
if($keyword){ |
|||
$where[] = ['keyword','like','%'.$keyword.'%']; |
|||
} |
|||
try{ |
|||
$innerList = $innerChart->where($where)->order('id','desc')->paginate($limit)->each(function(&$item){ |
|||
$count = (int)$item->content()->sum('total'); |
|||
$item -> count = $count; |
|||
$item -> save(); |
|||
}); |
|||
}catch(\Exception $e){ |
|||
throw new ModelException($e->getMessage()); |
|||
} |
|||
|
|||
return json(['code'=>0,'total'=>$innerList->total(),'msg'=>'success','data'=>$innerList->all()]); |
|||
} |
|||
|
|||
/** |
|||
* 保存新建的资源 |
|||
* |
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function save(InnerChart $innerChart): \think\response\Json |
|||
{ |
|||
if(request()->isPost()){ |
|||
$param = input('post.'); |
|||
$param['seller_id'] = $this->admin['seller_id']; |
|||
if(empty($param['website_id'])){ |
|||
$param['website_id'] = 0; |
|||
} |
|||
// 数据验证
|
|||
try{ |
|||
validate(InnerChartValidate::class)->scene('save')->check($param); |
|||
}catch(ValidateException $e){ |
|||
return jsonReturn(-1, $e->getError()); |
|||
} |
|||
|
|||
$res = $innerChart -> addInnerChart($param); |
|||
return json($res); |
|||
} |
|||
return jsonReturn(-3,Lang::get('请求方法错误')); |
|||
} |
|||
|
|||
/** |
|||
* 显示指定的资源 |
|||
* |
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
* @throws \app\exception\ModelEmptyException |
|||
*/ |
|||
public function read(InnerChart $innerChart): \think\response\Json |
|||
{ |
|||
|
|||
$id = (int)input('id'); |
|||
if(!$id){ |
|||
return jsonReturn(-1,lang('内链ID不能为空')); |
|||
} |
|||
$where = [ |
|||
'id' => $id, |
|||
'seller_id' => $this->admin['seller_id'] |
|||
]; |
|||
$res = $innerChart->getInnerChart($where); |
|||
return json($res); |
|||
|
|||
} |
|||
|
|||
/** |
|||
* 保存更新的资源 |
|||
|
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function update(InnerChart $innerChart): \think\response\Json |
|||
{ |
|||
if(request()->isPost()){ |
|||
$param = input('post.'); |
|||
try { |
|||
validate(InnerChartValidate::class)->scene('update')->check($param); |
|||
} catch (ValidateException $e) { |
|||
return jsonReturn(-1, $e->getError()); |
|||
} |
|||
if(empty($param['website_id'])){ |
|||
$param['website_id'] = 0; |
|||
} |
|||
$where = [ |
|||
'id' => $param['id'], |
|||
'seller_id' => $this->admin['seller_id'], |
|||
]; |
|||
$res = $innerChart -> updateInnerChart($where,$param); |
|||
return json($res); |
|||
} |
|||
return jsonReturn(-3,Lang::get('请求方法错误')); |
|||
} |
|||
|
|||
/** |
|||
* 删除指定资源 |
|||
* |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function delete(InnerChart $innerChart): \think\response\Json |
|||
{ |
|||
if(request()->isPost()){ |
|||
$id = (int)input('id'); |
|||
if(!$id){ |
|||
return jsonReturn(-1,lang('内链ID不能为空')); |
|||
} |
|||
$where = [ |
|||
'id' => $id, |
|||
'seller_id' => $this->admin['seller_id'] |
|||
]; |
|||
$res = $innerChart->delInnerChart($where); |
|||
return json($res); |
|||
} |
|||
return jsonReturn(-3,Lang::get('请求方法错误')); |
|||
} |
|||
} |
|||
@ -0,0 +1,130 @@ |
|||
<?php |
|||
|
|||
|
|||
namespace app\controller\backend; |
|||
|
|||
use \app\validate\InquiryCategoryValidate; |
|||
use app\model\InquiryCategory; |
|||
use think\exception\ValidateException; |
|||
use \think\response\Json; |
|||
|
|||
class InquiryCategoryController extends BaseController |
|||
{ |
|||
|
|||
/** |
|||
* 获取线索列表,可按条件查询 |
|||
* @return Json |
|||
*/ |
|||
|
|||
public function index(): Json |
|||
{ |
|||
if (request()->isGet()) { |
|||
$param['seller_id'] = $this->admin['seller_id']; |
|||
|
|||
$inquiryCategory = new InquiryCategory(); |
|||
$res = $inquiryCategory->getInquiryCategoryList($param); |
|||
|
|||
return json($res); |
|||
} |
|||
return jsonReturn(-2, lang('请求方法错误')); |
|||
} |
|||
|
|||
/** |
|||
* 询单类别查询 |
|||
* @return Json |
|||
*/ |
|||
|
|||
public function read(): Json |
|||
{ |
|||
if (request()->isGet()) { |
|||
$param = input('get.'); |
|||
$param['seller_id'] = $this->admin['seller_id']; |
|||
|
|||
try { |
|||
validate(InquiryCategoryValidate::class)->scene('read')->check($param); |
|||
} catch (ValidateException $e) { |
|||
return jsonReturn(-4, $e->getMessage()); |
|||
} |
|||
|
|||
$inquiryCategory = new InquiryCategory(); |
|||
$res = $inquiryCategory->getInquiryCategory($param); |
|||
|
|||
return json($res); |
|||
} |
|||
return jsonReturn(-2, lang('请求方法错误')); |
|||
} |
|||
|
|||
/** |
|||
* 新增询单类别 |
|||
* @return Json |
|||
*/ |
|||
|
|||
public function save(): Json |
|||
{ |
|||
if (request()->isPost()) { |
|||
$param = input('post.'); |
|||
$param['seller_id'] = $this->admin['seller_id']; |
|||
|
|||
try { |
|||
validate(InquiryCategoryValidate::class)->scene('save')->check($param); |
|||
} catch (ValidateException $e) { |
|||
return jsonReturn(-4, $e->getMessage()); |
|||
} |
|||
|
|||
$inquiryCategory = new InquiryCategory(); |
|||
$res = $inquiryCategory->addInquiryCategory($param); |
|||
|
|||
return json($res); |
|||
} |
|||
return jsonReturn(-2, lang('请求方法错误')); |
|||
} |
|||
|
|||
/** |
|||
* 更新询单类别 |
|||
* @return Json |
|||
*/ |
|||
|
|||
public function update(): Json |
|||
{ |
|||
if (request()->isPost()) { |
|||
$param = input('post.'); |
|||
$param['seller_id'] = $this->admin['seller_id']; |
|||
|
|||
try { |
|||
validate(InquiryCategoryValidate::class)->scene('update')->check($param); |
|||
} catch (ValidateException $e) { |
|||
return jsonReturn(-4, $e->getMessage()); |
|||
} |
|||
|
|||
$inquiryCategory = new InquiryCategory(); |
|||
$res = $inquiryCategory->updateInquiryCategory($param); |
|||
return json($res); |
|||
} |
|||
return jsonReturn(-2, lang('请求方法错误')); |
|||
} |
|||
|
|||
/** |
|||
* 删除询单类别 |
|||
* @return Json |
|||
*/ |
|||
|
|||
public function delete(): Json |
|||
{ |
|||
if (request()->isPost()) { |
|||
$param = input('post.'); |
|||
$param['seller_id'] = $this->admin['seller_id']; |
|||
|
|||
try { |
|||
validate(InquiryCategoryValidate::class)->scene('read')->check($param); |
|||
} catch (ValidateException $e) { |
|||
return jsonReturn(-4, $e->getMessage()); |
|||
} |
|||
|
|||
$inquiryCategory = new InquiryCategory(); |
|||
$res = $inquiryCategory->deleteInquiryCategory($param); |
|||
|
|||
return jsonReturn($res['code'], $res['msg']); |
|||
} |
|||
return jsonReturn(-2, lang('请求方法错误')); |
|||
} |
|||
} |
|||
@ -0,0 +1,231 @@ |
|||
<?php |
|||
|
|||
namespace app\controller\backend; |
|||
|
|||
use app\model\Inquiry; |
|||
use app\model\RecycleBin; |
|||
use app\validate\InquiryValidate; |
|||
use PhpOffice\PhpSpreadsheet\Spreadsheet; |
|||
use PhpOffice\PhpSpreadsheet\Writer\Xlsx; |
|||
use think\exception\ValidateException; |
|||
use think\facade\Cache; |
|||
use think\facade\Lang; |
|||
use think\response\Json; |
|||
|
|||
class InquiryController extends BaseController { |
|||
|
|||
/** |
|||
* 查询询单列表 |
|||
* @return Json |
|||
*/ |
|||
public function index(): Json |
|||
{ |
|||
if (request()->isGet()) { |
|||
$siteId = (int)input('website_id'); |
|||
if(empty($siteId)){ |
|||
return jsonReturn(-1,Lang::get('网站ID不能为空')); |
|||
} |
|||
$where = [ |
|||
'seller_id' => $this->admin['seller_id'], |
|||
'website_id' => $siteId, |
|||
'is_del' => 1, |
|||
]; |
|||
$limit = $this->setLimit(); |
|||
$inquiry = new Inquiry(); |
|||
$res = $inquiry->getInquiryList($where,'*', $limit); |
|||
return json(pageReturn($res)); |
|||
} |
|||
return jsonReturn(-2, lang('请求方法错误')); |
|||
} |
|||
|
|||
/** |
|||
* 新增询单信息 |
|||
* @return Json |
|||
* @method Post |
|||
*/ |
|||
public function backendSave(): Json |
|||
{ |
|||
if(request()->isPost()){ |
|||
$param = input('post.'); |
|||
$param['seller_id'] = $this->admin['seller_id']; |
|||
|
|||
if (empty($param['phone']) && empty($param['wechat']) && empty($param['email']) && empty($param['qq']) && empty($param['telphone'])) { |
|||
return jsonReturn(-4, lang('联系方式必须填写一个')); |
|||
} |
|||
try { |
|||
validate(InquiryValidate::class)->scene('save')->check($param); |
|||
} catch (ValidateException $e){ |
|||
return jsonReturn(-4, $e->getMessage()); |
|||
} |
|||
$inquiry = new Inquiry(); |
|||
$res = $inquiry -> addInquiry($param); |
|||
return json($res); |
|||
} |
|||
return jsonReturn(-2, lang('请求方法错误')); |
|||
} |
|||
|
|||
/** |
|||
* 询单信息查询 |
|||
* @return Json |
|||
* @method Post |
|||
*/ |
|||
public function read(): Json |
|||
{ |
|||
if (request()->isGet()) { |
|||
$param = input('get.'); |
|||
try { |
|||
validate(InquiryValidate::class)->scene('read')->check($param); |
|||
} catch (ValidateException $e){ |
|||
return jsonReturn(-4, $e->getMessage()); |
|||
} |
|||
$param['seller_id'] = $this->admin['seller_id']; |
|||
|
|||
$inquiry = new Inquiry(); |
|||
$res = $inquiry->getInquiry($param); |
|||
|
|||
return json($res); |
|||
} |
|||
return jsonReturn(-2, lang('请求方法错误')); |
|||
} |
|||
|
|||
/** |
|||
* 更新询单信息 |
|||
* @return Json |
|||
* @method Post |
|||
*/ |
|||
public function update(): Json |
|||
{ |
|||
if(request()->isPost()) { |
|||
$param = input('post.'); |
|||
$param['seller_id'] = $this->admin['seller_id']; |
|||
|
|||
if (empty($param['mobile']) && empty($param['wechat']) && empty($param['email']) && empty($param['qq'])) { |
|||
return jsonReturn(-4, lang('联系方式必须填写一个')); |
|||
} |
|||
|
|||
try { |
|||
validate(InquiryValidate::class)->scene('update')->check($param); |
|||
} catch (ValidateException $e){ |
|||
return jsonReturn(-4, $e->getMessage()); |
|||
} |
|||
|
|||
$inquiry = new Inquiry(); |
|||
$res = $inquiry->updateInquiry($param); |
|||
|
|||
return json($res); |
|||
} |
|||
return jsonReturn(-2, lang('请求方法错误')); |
|||
} |
|||
|
|||
/** |
|||
* 删除询单信息 |
|||
* @return Json |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function delete(): Json |
|||
{ |
|||
if (request()->isPost()) { |
|||
$param = input('post.'); |
|||
$param['seller_id'] = $this->admin['seller_id']; |
|||
|
|||
try { |
|||
validate(InquiryValidate::class)->scene('read')->check($param); |
|||
} catch (ValidateException $e){ |
|||
return jsonReturn(-4, $e->getMessage()); |
|||
} |
|||
|
|||
$Inquiry = new Inquiry(); |
|||
$inquiry = $Inquiry->getInquiry($param)['data']; |
|||
if(empty($inquiry)){ |
|||
jsonReturn(-3, lang('询盘不存在')); |
|||
} |
|||
// 复制删除内容到回收站表
|
|||
$recycleBin = new RecycleBin(); |
|||
$binData = [ |
|||
'seller_id' => $param['seller_id'], |
|||
'object_id' => $inquiry['id'], |
|||
'sub_id' => 0, |
|||
'module_id' => 0, |
|||
'table_name' => lang('询盘'), |
|||
'title' => !empty($inquiry['title']) ? $inquiry['title'] : lang('询盘内容') . $inquiry['id'], |
|||
'admin_id' => $this->admin['uid'], |
|||
'name' => $this->admin['name'], |
|||
]; |
|||
$recycleBin -> addRecycleBin($binData); |
|||
$inquiry->is_del = 2; |
|||
$inquiry->delete_time = time(); |
|||
$inquiry->save(); |
|||
return jsonReturn(0, lang('删除成功')); |
|||
} |
|||
return jsonReturn(-2, lang('请求方法错误')); |
|||
} |
|||
|
|||
|
|||
public function batch_delete(): Json |
|||
{ |
|||
if (request()->isPost()) { |
|||
$param = input('post.'); |
|||
try { |
|||
validate(InquiryValidate::class)->scene('batch')->check($param); |
|||
} catch (\Exception $e) { |
|||
return jsonReturn(-4, $e->getMessage()); |
|||
} |
|||
|
|||
$where = [ |
|||
['seller_id' ,'=', $this->admin['seller_id']], |
|||
['ids','in', $param['ids']], |
|||
]; |
|||
|
|||
$linkWebsite = new Inquiry(); |
|||
$res = $linkWebsite->batchDeleteInquiry($where); |
|||
|
|||
return jsonReturn($res['code'], $res['msg']); |
|||
} |
|||
return jsonReturn(-1, lang('请求方法错误')); |
|||
} |
|||
|
|||
/** |
|||
* 导出询盘的内容 |
|||
* @return |
|||
*/ |
|||
public function exportInquiry() |
|||
{ |
|||
if(!file_exists('excel')){ |
|||
mkdir("excel",0777,true); |
|||
} |
|||
|
|||
$Inquiry = new Inquiry(); |
|||
$siteId = $this->request->param("website_id/d",0); |
|||
$list = $Inquiry->where(['is_del'=>1,'website_id'=>$siteId])->alias('i')->join("inquiry_category ic",'ic.id = i.inquiry_type','left') |
|||
->column('i.*,ic.name cate_name'); |
|||
|
|||
$title = [ |
|||
'公司名称', '联系人姓名', '询盘内容', '固定电话', "号码", '邮箱', 'qq', '询盘类型', '公司地址', '企业网址', '询盘来源', '来源网址', 'ip', '预算金额', '需求说明', |
|||
]; |
|||
$keys = ['company_name', 'contacts_name' , 'content', 'telphone', 'phone', 'email', 'qq', 'cate_name', |
|||
'company_address', 'company_site', 'referer', 'referer_web', 'ip', 'expect_amount', 'explain']; |
|||
$columnList = []; |
|||
$spreadsheet = new Spreadsheet(); |
|||
$activeWorksheet = $spreadsheet->getActiveSheet(); |
|||
$total = count($title); |
|||
for ($i=0;$i<$total;$i++){ |
|||
$column = getSheetColLabel($i + 1); |
|||
$cell = $column . '1'; |
|||
$columnList[] = $column; |
|||
$activeWorksheet->setCellValue($cell, $title[$i]); |
|||
} |
|||
|
|||
foreach ($list as $k=>$v){ |
|||
for ($x=0;$x<$total;$x++){ |
|||
$activeWorksheet->setCellValue($columnList[$x] . ($k + 2),$v[$keys[$x]]); |
|||
} |
|||
} |
|||
$writer = new Xlsx($spreadsheet); |
|||
$filename = '询盘导出'.date("YmdHis").'.xlsx'; |
|||
$writer->save("./excel/".$filename); |
|||
return jsonReturn(0, '成功', ['url' => '/excel/'.$filename]); |
|||
|
|||
} |
|||
|
|||
|
|||
} |
|||
@ -0,0 +1,152 @@ |
|||
<?php |
|||
|
|||
|
|||
namespace app\controller\backend; |
|||
|
|||
use app\model\InquiryEmail; |
|||
use app\model\WebsiteInquiryEmail; |
|||
use app\validate\InquiryEmailValidate; |
|||
use think\facade\Db; |
|||
use think\facade\Lang; |
|||
use \think\response\Json; |
|||
|
|||
class InquiryEmailController extends BaseController |
|||
{ |
|||
|
|||
/** |
|||
* @param InquiryEmail $InquiryEmail |
|||
* @return Json |
|||
* @throws \think\db\exception\DbException |
|||
*/ |
|||
public function index (InquiryEmail $InquiryEmail): Json |
|||
{ |
|||
if (request()->isGet()) { |
|||
$siteId = (int)input('website_id'); |
|||
if(!$siteId){ |
|||
return jsonReturn(-1,Lang::get('网站ID不能为空')); |
|||
} |
|||
$limit = $this->setLimit(); |
|||
$where = [ |
|||
'seller_id' => $this->admin['seller_id'], |
|||
'website_id' => $siteId, |
|||
]; |
|||
$WebsiteInquiryEmail = new WebsiteInquiryEmail(); |
|||
$ids = $WebsiteInquiryEmail->where($where)->column('inquiry_email_id'); |
|||
if(empty($ids)){ |
|||
return json(['code' => 0, 'msg' => 'ok', 'count' => 0, 'data' => []]); |
|||
} |
|||
$emailWhere = [ |
|||
['seller_id','=',$this->admin['seller_id']], |
|||
['id','in',$ids] |
|||
]; |
|||
|
|||
$inquiryEmail = $InquiryEmail -> where($emailWhere)->paginate($limit)->each(function(&$item)use($WebsiteInquiryEmail){ |
|||
$ids = $WebsiteInquiryEmail->where($where = [ |
|||
'seller_id' => $this->admin['seller_id'], |
|||
'inquiry_email_id' => $item['id'], |
|||
])->column('website_id'); |
|||
$item['website_id'] = $ids; |
|||
}); |
|||
return json(['code' => 0, 'msg' => 'ok', 'count' => $inquiryEmail->total(), 'data' => $inquiryEmail->all()]); |
|||
} |
|||
return jsonReturn(-2, lang('请求方法错误')); |
|||
} |
|||
|
|||
/** |
|||
* @return Json |
|||
*/ |
|||
|
|||
public function save(InquiryEmail $InquiryEmail): Json |
|||
{ |
|||
if (request()->isPost()) { |
|||
$param = input('post.'); |
|||
try { |
|||
validate(InquiryEmailValidate::class)->scene('save')->check($param); |
|||
} catch (\Exception $e) { |
|||
return jsonReturn(-4, $e->getMessage()); |
|||
} |
|||
$param['seller_id'] = $this->admin['seller_id']; |
|||
$siteIds = $param['website_id']; |
|||
unset($param['website_id']); |
|||
Db::startTrans(); |
|||
try{ |
|||
$res = $InquiryEmail -> addInquiryEmail($param); |
|||
$inquiryEmail = $res['data']; |
|||
$inquiryEmail->website()->attach($siteIds,['seller_id'=>$param['seller_id']]); |
|||
Db::commit(); |
|||
}catch (\Exception $e){ |
|||
Db::rollback(); |
|||
return jsonReturn(0,lang('系统错误请重试')); |
|||
} |
|||
|
|||
return json($res); |
|||
} |
|||
return jsonReturn(-2, lang('请求方法错误')); |
|||
} |
|||
|
|||
/** |
|||
* @return Json |
|||
*/ |
|||
|
|||
public function update(InquiryEmail $InquiryEmail): Json |
|||
{ |
|||
if (request()->isPost()) { |
|||
$param = input('post.'); |
|||
|
|||
try { |
|||
validate(InquiryEmailValidate::class)->scene('update')->check($param); |
|||
} catch (\Exception $e) { |
|||
return jsonReturn(-4, $e->getMessage()); |
|||
} |
|||
Db::startTrans(); |
|||
try{ |
|||
$param['seller_id'] = $this->admin['seller_id']; |
|||
$inquiryEmail = $InquiryEmail->getInquiryEmail(['id'=>$param['id'],'seller_id'=>$param['seller_id']])['data']; |
|||
$inquiryEmail->website()->detach(); |
|||
$inquiryEmail->website()->attach($param['website_id'],['seller_id'=>$param['seller_id']]); |
|||
$inquiryEmail->email = $param['email']; |
|||
if(isset($param['email'])){ |
|||
$inquiryEmail->status = $param['status']; |
|||
} |
|||
$inquiryEmail->save(); |
|||
Db::commit(); |
|||
}catch (\Exception $e){ |
|||
Db::rollback(); |
|||
return jsonReturn(-1,lang('系统错误请重试')); |
|||
} |
|||
|
|||
return jsonReturn(0,lang('保存成功')); |
|||
} |
|||
return jsonReturn(-2, lang('请求方法错误')); |
|||
} |
|||
|
|||
/** |
|||
* @return Json |
|||
*/ |
|||
|
|||
public function delete(InquiryEmail $InquiryEmail): Json |
|||
{ |
|||
if (request()->isPost()) { |
|||
$param = input('post.'); |
|||
$param['seller_id'] = $this->admin['seller_id']; |
|||
try { |
|||
validate(InquiryEmailValidate::class)->scene('read')->check($param); |
|||
} catch (\Exception $e) { |
|||
return jsonReturn(-4, $e->getMessage()); |
|||
} |
|||
Db::startTrans(); |
|||
try{ |
|||
$inquiryEmail = $InquiryEmail->getInquiryEmail(['id'=>$param['id'],'seller_id'=>$param['seller_id']])['data']; |
|||
$inquiryEmail->website()->detach(); |
|||
$inquiryEmail->delete(); |
|||
Db::commit(); |
|||
}catch (\Exception $e){ |
|||
Db::rollback(); |
|||
return jsonReturn(0,lang('系统错误请重试')); |
|||
} |
|||
|
|||
return jsonReturn(0, lang('删除成功')); |
|||
} |
|||
return jsonReturn(-2, lang('请求方法错误')); |
|||
} |
|||
} |
|||
@ -0,0 +1,153 @@ |
|||
<?php |
|||
declare (strict_types = 1); |
|||
|
|||
namespace app\controller\backend; |
|||
|
|||
use app\model\Job; |
|||
use app\model\JobCate; |
|||
use app\validate\JobCateValidate; |
|||
use think\exception\ValidateException; |
|||
use think\facade\Lang; |
|||
|
|||
|
|||
class JobCateController extends BaseController |
|||
{ |
|||
/** |
|||
* 显示资源列表 |
|||
* |
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function index(JobCate $jobCate): \think\response\Json |
|||
{ |
|||
$where = [ |
|||
'seller_id' => $this->admin['seller_id'], |
|||
'is_del' => 1, |
|||
]; |
|||
$limit = 10; |
|||
$limitParam = (int)input('limit'); |
|||
if($limitParam){ |
|||
$limit = $limitParam; |
|||
} |
|||
// TODO
|
|||
// 添加其他逻辑
|
|||
|
|||
$jobCateList = $jobCate->getJobCateList($where,$limit); |
|||
return json(pageReturn($jobCateList)); |
|||
} |
|||
|
|||
/** |
|||
* 保存新建的资源 |
|||
* |
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function save(JobCate $jobCate): \think\response\Json |
|||
{ |
|||
if(request()->isPost()){ |
|||
$param = input('post.'); |
|||
$param['seller_id'] = $this->admin['seller_id']; |
|||
// 数据验证
|
|||
try{ |
|||
validate(JobCateValidate::class)->scene('save')->check($param); |
|||
}catch(ValidateException $e){ |
|||
return jsonReturn(-1, $e->getError()); |
|||
} |
|||
// TODO
|
|||
// 其他逻辑
|
|||
|
|||
$res = $jobCate -> addJobCate($param); |
|||
return json($res); |
|||
} |
|||
return jsonReturn(-3,Lang::get('请求方法错误')); |
|||
} |
|||
|
|||
/** |
|||
* 显示指定的资源 |
|||
* |
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
* @throws \app\exception\ModelEmptyException |
|||
*/ |
|||
public function read(JobCate $jobCate): \think\response\Json |
|||
{ |
|||
|
|||
$id = (int)input('id'); |
|||
if(!$id){ |
|||
// TODO
|
|||
// 修改错误消息
|
|||
return jsonReturn(-1,'ErrorMsg'); |
|||
} |
|||
$where = [ |
|||
'id' => $id, |
|||
'seller_id' => $this->admin['seller_id'] |
|||
]; |
|||
// TODO
|
|||
// 其他逻辑
|
|||
$res = $jobCate->getJobCate($where); |
|||
return json($res); |
|||
|
|||
} |
|||
|
|||
/** |
|||
* 保存更新的资源 |
|||
|
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function update(JobCate $jobCate): \think\response\Json |
|||
{ |
|||
if(request()->isPost()){ |
|||
$param = input('post.'); |
|||
try { |
|||
validate(JobCateValidate::class)->scene('update')->check($param); |
|||
} catch (ValidateException $e) { |
|||
return jsonReturn(-1, $e->getError()); |
|||
} |
|||
$where = [ |
|||
'id' => $param['id'], |
|||
'seller_id' => $this->admin['seller_id'], |
|||
'is_del' => 1, |
|||
]; |
|||
$res = $jobCate -> updateJobCate($where,$param); |
|||
return json($res); |
|||
} |
|||
return jsonReturn(-3,Lang::get('请求方法错误')); |
|||
} |
|||
|
|||
/** |
|||
* 删除指定资源 |
|||
* |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function delete(JobCate $jobCate, Job $job): \think\response\Json |
|||
{ |
|||
if(request()->isPost()){ |
|||
$id = (int)input('id'); |
|||
$seller_id = $this->admin['seller_id']; |
|||
if(!$id){ |
|||
// TODO 替换错误提示
|
|||
return jsonReturn(-1,'ErrorMsg'); |
|||
} |
|||
|
|||
// TODO 分类使用判断
|
|||
$job_where = [ |
|||
'job_cate_id' => $id, |
|||
'seller_id' => $seller_id, |
|||
]; |
|||
$has = $job->getJob($job_where); |
|||
if ($has['code'] == 0) { |
|||
return jsonReturn(-3, lang('工作类别在使用中')); |
|||
} else { |
|||
$where = [ |
|||
'id' => $id, |
|||
'seller_id' => $seller_id, |
|||
]; |
|||
$res = $jobCate->softDelJobCate($where); |
|||
return json($res); |
|||
} |
|||
|
|||
} |
|||
return jsonReturn(-3,Lang::get('请求方法错误')); |
|||
} |
|||
} |
|||
@ -0,0 +1,154 @@ |
|||
<?php |
|||
declare (strict_types = 1); |
|||
|
|||
namespace app\controller\backend; |
|||
|
|||
use app\model\Job; |
|||
use app\model\JobCity; |
|||
use app\validate\JobCityValidate; |
|||
use think\exception\ValidateException; |
|||
use think\facade\Lang; |
|||
|
|||
|
|||
class JobCityController extends BaseController |
|||
{ |
|||
/** |
|||
* 显示资源列表 |
|||
* |
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function index(JobCity $jobCity): \think\response\Json |
|||
{ |
|||
$where = [ |
|||
'seller_id' => $this->admin['seller_id'], |
|||
'is_del' => 1, |
|||
]; |
|||
$limit = 10; |
|||
$limitParam = (int)input('limit'); |
|||
if($limitParam){ |
|||
$limit = $limitParam; |
|||
} |
|||
// TODO
|
|||
// 添加其他逻辑
|
|||
|
|||
$jobCityList = $jobCity->getJobCityList($where,$limit); |
|||
return json(pageReturn($jobCityList)); |
|||
} |
|||
|
|||
/** |
|||
* 保存新建的资源 |
|||
* |
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function save(JobCity $jobCity): \think\response\Json |
|||
{ |
|||
if(request()->isPost()){ |
|||
$param = input('post.'); |
|||
$param['seller_id'] = $this->admin['seller_id']; |
|||
// 数据验证
|
|||
try{ |
|||
validate(JobCityValidate::class)->scene('save')->check($param); |
|||
}catch(ValidateException $e){ |
|||
return jsonReturn(-1, $e->getError()); |
|||
} |
|||
// TODO
|
|||
// 其他逻辑
|
|||
|
|||
$res = $jobCity -> addJobCity($param); |
|||
return json($res); |
|||
} |
|||
return jsonReturn(-3,Lang::get('请求方法错误')); |
|||
} |
|||
|
|||
/** |
|||
* 显示指定的资源 |
|||
* |
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
* @throws \app\exception\ModelEmptyException |
|||
*/ |
|||
public function read(JobCity $jobCity): \think\response\Json |
|||
{ |
|||
|
|||
$id = (int)input('id'); |
|||
if(!$id){ |
|||
// TODO
|
|||
// 修改错误消息
|
|||
return jsonReturn(-1,'ErrorMsg'); |
|||
} |
|||
$where = [ |
|||
'id' => $id, |
|||
'seller_id' => $this->admin['seller_id'] |
|||
]; |
|||
// TODO
|
|||
// 其他逻辑
|
|||
$res = $jobCity->getJobCity($where); |
|||
return json($res); |
|||
|
|||
} |
|||
|
|||
/** |
|||
* 保存更新的资源 |
|||
|
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function update(JobCity $jobCity): \think\response\Json |
|||
{ |
|||
if(request()->isPost()){ |
|||
$param = input('post.'); |
|||
try { |
|||
validate(JobCityValidate::class)->scene('update')->check($param); |
|||
} catch (ValidateException $e) { |
|||
return jsonReturn(-1, $e->getError()); |
|||
} |
|||
$where = [ |
|||
'id' => $param['id'], |
|||
'seller_id' => $this->admin['seller_id'], |
|||
'is_del' => 1, |
|||
]; |
|||
$res = $jobCity -> updateJobCity($where,$param); |
|||
return json($res); |
|||
} |
|||
return jsonReturn(-3,Lang::get('请求方法错误')); |
|||
} |
|||
|
|||
/** |
|||
* 删除指定资源 |
|||
* |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function delete(JobCity $jobCity, Job $job): \think\response\Json |
|||
{ |
|||
if(request()->isPost()){ |
|||
$id = (int)input('id'); |
|||
$seller_id = $this->admin['seller_id']; |
|||
if(!$id){ |
|||
// TO DO
|
|||
// 替换错误提示
|
|||
return jsonReturn(-1,'ErrorMsg'); |
|||
} |
|||
|
|||
// TODO 分类使用判断
|
|||
$job_where = [ |
|||
'job_city_id' => $id, |
|||
'seller_id' => $seller_id, |
|||
]; |
|||
|
|||
$has = $job->getJob($job_where); |
|||
if ($has['code'] == 0) { |
|||
return jsonReturn(-3, lang('工作类别在使用中')); |
|||
} else { |
|||
$where = [ |
|||
'id' => $id, |
|||
'seller_id' => $this->admin['seller_id'] |
|||
]; |
|||
$res = $jobCity->softDelJobCity($where); |
|||
return json($res); |
|||
} |
|||
} |
|||
return jsonReturn(-3,Lang::get('请求方法错误')); |
|||
} |
|||
} |
|||
@ -0,0 +1,164 @@ |
|||
<?php |
|||
declare (strict_types = 1); |
|||
|
|||
namespace app\controller\backend; |
|||
|
|||
use app\exception\ModelEmptyException; |
|||
use app\exception\ModelException; |
|||
use app\model\Job; |
|||
use app\model\JobCate; |
|||
use app\model\JobCity; |
|||
use app\model\Website; |
|||
use app\validate\JobValidate; |
|||
use think\exception\ValidateException; |
|||
use think\facade\Lang; |
|||
use think\response\Json; |
|||
|
|||
class JobController extends BaseController |
|||
{ |
|||
/** |
|||
* 显示资源列表 |
|||
* |
|||
* @return Json |
|||
* @throws ModelException |
|||
*/ |
|||
public function index(Job $job): Json |
|||
{ |
|||
$seller_id = $this->admin['seller_id']; |
|||
$job_city_id = input('job_city_id'); |
|||
$job_cate_id = input('job_cate_id'); |
|||
$title = input('title'); |
|||
|
|||
$where = [ |
|||
'seller_id' => $seller_id, |
|||
'is_del' => 1, |
|||
]; |
|||
$limit = 10; |
|||
$limitParam = (int)input('limit'); |
|||
if($limitParam){ |
|||
$limit = $limitParam; |
|||
} |
|||
// TODO
|
|||
// 添加其他逻辑
|
|||
if (!empty($job_city_id)) { |
|||
$where['job_city_id'] = $job_city_id; |
|||
} |
|||
|
|||
if (!empty($job_cate_id)) { |
|||
$where['job_cate_id'] = $job_cate_id; |
|||
} |
|||
|
|||
if (!empty($title)) { |
|||
// 模糊查询
|
|||
$jobList = $job->searchJob($where,$title, $limit); |
|||
} else { |
|||
$jobList = $job->getJobList($where,$limit); |
|||
} |
|||
|
|||
return json(pageReturn($jobList)); |
|||
} |
|||
|
|||
/** |
|||
* 保存新建的资源 |
|||
* |
|||
* @return Json |
|||
* @throws ModelException |
|||
*/ |
|||
public function save(Job $job): Json |
|||
{ |
|||
if(request()->isPost()){ |
|||
$param = input('post.'); |
|||
$param['seller_id'] = $this->admin['seller_id']; |
|||
|
|||
// 数据验证
|
|||
try{ |
|||
validate(JobValidate::class)->scene('save')->check($param); |
|||
}catch(ValidateException $e){ |
|||
return jsonReturn(-1, $e->getError()); |
|||
} |
|||
|
|||
$res = $job -> addJob($param); |
|||
return json($res); |
|||
} |
|||
return jsonReturn(-3,Lang::get('请求方法错误')); |
|||
} |
|||
|
|||
/** |
|||
* 显示指定的资源 |
|||
* |
|||
* @return Json |
|||
* @throws ModelException |
|||
* @throws ModelEmptyException |
|||
*/ |
|||
public function read(Job $job): Json |
|||
{ |
|||
|
|||
$id = (int)input('id'); |
|||
if(!$id){ |
|||
return jsonReturn(-1,lang('不能为空')); |
|||
} |
|||
$siteId = (int)input('website_id'); |
|||
$where = [ |
|||
'id' => $id, |
|||
'seller_id' => $this->admin['seller_id'], |
|||
'website_id' => $siteId, |
|||
]; |
|||
$jobRes = $job->getJob($where,['jobCity','jobCity'])['data']->toArray(); |
|||
|
|||
|
|||
return jsonReturn(0, lang('查询成功'), $jobRes); |
|||
|
|||
} |
|||
|
|||
/** |
|||
* 保存更新的资源 |
|||
|
|||
* @return Json |
|||
* @throws ModelException |
|||
*/ |
|||
public function update(Job $job): Json |
|||
{ |
|||
if(request()->isPost()){ |
|||
$param = input('post.'); |
|||
$param['seller_id'] = $this->admin['seller_id']; |
|||
try { |
|||
validate(JobValidate::class)->scene('update')->check($param); |
|||
} catch (ValidateException $e) { |
|||
return jsonReturn(-1, $e->getError()); |
|||
} |
|||
$where = [ |
|||
'id' => $param['id'], |
|||
'seller_id' => $this->admin['seller_id'], |
|||
'is_del' => 1, |
|||
'website_id' => $param['website_id'] |
|||
]; |
|||
$res = $job -> updateJob($where,$param); |
|||
return json($res); |
|||
} |
|||
return jsonReturn(-3,Lang::get('请求方法错误')); |
|||
} |
|||
|
|||
/** |
|||
* 删除指定资源 |
|||
* |
|||
* @throws ModelException |
|||
*/ |
|||
public function delete(Job $job): Json |
|||
{ |
|||
if(request()->isPost()){ |
|||
$id = (int)input('id'); |
|||
if(!$id){ |
|||
return jsonReturn(-1,lang('职位ID不能为空')); |
|||
} |
|||
$siteId = (int)input('website_id'); |
|||
$where = [ |
|||
'id' => $id, |
|||
'seller_id' => $this->admin['seller_id'], |
|||
'website_id' => $siteId, |
|||
]; |
|||
$res = $job->delJob($where); |
|||
return json($res); |
|||
} |
|||
return jsonReturn(-3,Lang::get('请求方法错误')); |
|||
} |
|||
} |
|||
@ -0,0 +1,356 @@ |
|||
<?php |
|||
|
|||
|
|||
namespace app\controller\backend; |
|||
|
|||
|
|||
use app\model\Keyword; |
|||
use app\model\KeywordQuery; |
|||
use app\model\Website; |
|||
use app\service\ExcelService; |
|||
use app\service\KeywordService; |
|||
use app\service\MonitorService; |
|||
use app\validate\KeywordValidate; |
|||
use think\exception\ValidateException; |
|||
use think\facade\Lang; |
|||
use think\response\Json; |
|||
|
|||
class KeywordController extends BaseController |
|||
{ |
|||
public $header = ['关键词名称','关键词链接','关键词位置','关键词状态']; |
|||
public $map = ['name','url','position','status']; |
|||
|
|||
/** |
|||
* 读取数据列表 |
|||
* @return Json |
|||
* @method Post |
|||
* @error_number 0: 成功, -1: 数据库查询失败, -2: 请求方法错误, -3: 数据重复, -4:数据缺少或校验不通过, |
|||
*/ |
|||
public function index(Keyword $Keyword): Json |
|||
{ |
|||
if (request()->isGet()) { |
|||
$websiteId = (int)input('website_id', '', 'trim'); |
|||
if(!$websiteId){ |
|||
return jsonReturn(-1,Lang::get('站点不能为空')); |
|||
} |
|||
$where = [ |
|||
'website_id' => $websiteId, |
|||
'seller_id' => $this->admin['seller_id'], |
|||
]; |
|||
$limit = $this->setLimit(); |
|||
$res = $Keyword->getKeywordList($where, $limit,'id,website_id,name,url,position,sort,baidu_pc,baidu_mob,three_pc,sougou_mob,status',['website']); |
|||
return json(pageReturn($res)); |
|||
} |
|||
return jsonReturn(-2, Lang::get('请求方法错误')); |
|||
} |
|||
|
|||
/** |
|||
* 读取数据 |
|||
* @return Json |
|||
*/ |
|||
public function read(Keyword $Keyword) |
|||
{ |
|||
if (request()->isGet()) { |
|||
$param = input('get.'); |
|||
try { |
|||
validate(KeywordValidate::class)->scene('read')->check($param); |
|||
} catch (ValidateException $e) { |
|||
return jsonReturn(-4, $e->getMessage()); |
|||
} |
|||
$param['seller_id'] = $this->admin['seller_id']; |
|||
|
|||
$res = $Keyword->getKeyword($param); |
|||
return json($res); |
|||
} |
|||
return jsonReturn(-2, Lang::get('请求方法错误')); |
|||
} |
|||
|
|||
/** |
|||
* 保存 |
|||
* @param Keyword $Keyword |
|||
* @return Json |
|||
* @throws \app\exception\ModelException |
|||
* @throws \app\exception\ModelNotUniqueException |
|||
*/ |
|||
public function save(Keyword $Keyword): Json |
|||
{ |
|||
if (request()->isPost()) { |
|||
$param = input('post.'); |
|||
|
|||
try { |
|||
validate(KeywordValidate::class)->scene('save')->check($param); |
|||
} catch (ValidateException $e) { |
|||
return jsonReturn(-4, $e->getMessage()); |
|||
} |
|||
$param['seller_id'] = $this->admin['seller_id']; |
|||
$uniqueWhere = [ |
|||
'website_id' => $param['website_id'], |
|||
'name' => $param['name'], |
|||
'url' => $param['url'] |
|||
]; |
|||
$Keyword->saveUnique($uniqueWhere,Lang::get('关键词已经存在')); |
|||
|
|||
$res = $Keyword->addKeyword($param); |
|||
|
|||
return json($res); |
|||
} |
|||
return jsonReturn(-2, Lang::get('请求方法错误')); |
|||
} |
|||
|
|||
/** |
|||
* 编辑 |
|||
* @param Keyword $Keyword |
|||
* @return Json |
|||
* @throws \app\exception\ModelException |
|||
* @throws \app\exception\ModelNotUniqueException |
|||
*/ |
|||
public function update(Keyword $Keyword): Json |
|||
{ |
|||
if (request()->isPost()) { |
|||
$param = input('post.'); |
|||
|
|||
try { |
|||
validate(KeywordValidate::class)->scene('update')->check($param); |
|||
} catch (ValidateException $e) { |
|||
return jsonReturn(-4, $e->getMessage()); |
|||
} |
|||
$uniqueWhere = [ |
|||
'website_id' => $param['website_id'], |
|||
'name' => $param['name'], |
|||
'url' => $param['url'] |
|||
]; |
|||
$Keyword->updateUnique($uniqueWhere,$param['id'],Lang::get('关键词已经存在')); |
|||
$updateWhere = [ |
|||
'id' => $param['id'], |
|||
'seller_id' => $this->admin['seller_id'], |
|||
'website_id' => $param['website_id'], |
|||
]; |
|||
$res = $Keyword->updateKeyword($updateWhere,$param); |
|||
|
|||
return json($res); |
|||
} |
|||
return jsonReturn(-2, Lang::get('请求方法错误')); |
|||
} |
|||
|
|||
/** |
|||
* 删除数据 |
|||
* @return Json |
|||
*/ |
|||
public function delete(Keyword $Keyword): Json |
|||
{ |
|||
if (request()->isPost()) { |
|||
$param = input('post.'); |
|||
try { |
|||
validate(KeywordValidate::class)->scene('delete')->check($param); |
|||
} catch (ValidateException $e) { |
|||
return jsonReturn(-4, $e->getMessage()); |
|||
} |
|||
|
|||
if(empty($param['keyword_id'])){ |
|||
jsonReturn(0, lang('删除成功')); |
|||
}else{ |
|||
if(count($param['keyword_id'])){ |
|||
$where = [ |
|||
'id' => $param['keyword_id'][0], |
|||
'seller_id' => $this->admin['seller_id'], |
|||
'website_id' => $param['website_id'] |
|||
]; |
|||
}else{ |
|||
$where = [ |
|||
['id' , 'in',$param['keyword_id']], |
|||
['seller_id' ,'=', $param['seller_id']], |
|||
['website_id', '=', $param['website_id']] |
|||
]; |
|||
} |
|||
$res = $Keyword->deleteKeyword($where); |
|||
return json($res); |
|||
} |
|||
} |
|||
return jsonReturn(-2, Lang::get('请求方法错误')); |
|||
} |
|||
|
|||
/** |
|||
* 导入关键词 |
|||
* @param ExcelService $excelService |
|||
* @param Keyword $Keyword |
|||
* @return Json |
|||
* @throws \PhpOffice\PhpSpreadsheet\Exception |
|||
* @throws \PhpOffice\PhpSpreadsheet\Reader\Exception |
|||
*/ |
|||
public function import(ExcelService $excelService,Keyword $Keyword): Json |
|||
{ |
|||
$param = input('post.'); |
|||
$param['file'] = request()->file('file'); |
|||
try { |
|||
validate(KeywordValidate::class)->scene('import')->check($param); |
|||
} catch (ValidateException $e) { |
|||
return jsonReturn(-4, $e->getMessage()); |
|||
} |
|||
$data = $excelService->readData($param['file']); |
|||
if(empty($data)){ |
|||
return jsonReturn(-1,Lang::get('数据读取失败或者文件加为空,请检查')); |
|||
} |
|||
$data = $this->checkData($data); |
|||
if(isset($data['code'])){ |
|||
return json($data); |
|||
} |
|||
$data = $this->dealWithData($data,$param['website_id']); |
|||
|
|||
$res = $Keyword->addAllCustomData($data); |
|||
|
|||
return json($res); |
|||
} |
|||
|
|||
/** |
|||
* @param $data |
|||
* @return array |
|||
*/ |
|||
public function checkData($data): array |
|||
{ |
|||
$header = array_shift($data); |
|||
if(count($header) != 4){ |
|||
return dataReturn(-2,Lang::get('数据格式错误,请参考样例')); |
|||
} |
|||
$i = 0; |
|||
foreach($header as $value){ |
|||
if($value != $this->header[$i]){ |
|||
return dataReturn(-3,Lang::get('数据格式错误,请参考样例')); |
|||
} |
|||
$i++; |
|||
} |
|||
return $data; |
|||
} |
|||
|
|||
/** |
|||
* @param $data |
|||
* @param $siteId |
|||
* @return array |
|||
*/ |
|||
public function dealWithData($data,$siteId): array |
|||
{ |
|||
$tmpData = []; |
|||
foreach($data as $val){ |
|||
if(!empty($val)){ |
|||
$tmp = ['website_id' => $siteId]; |
|||
$tmp['seller_id'] = $this->admin['seller_id']; |
|||
$i = 0; |
|||
foreach($val as $vv){ |
|||
if($i == 0 && empty($vv)){ |
|||
break; |
|||
} |
|||
if($i == 3){ |
|||
if($vv == '正常'){ |
|||
$vv = 1; |
|||
}else{ |
|||
$vv = 2; |
|||
} |
|||
} |
|||
$tmp[$this->map[$i]] = $vv; |
|||
if($i == 3){ |
|||
array_push($tmpData,$tmp); |
|||
} |
|||
$i++; |
|||
} |
|||
} |
|||
} |
|||
return $tmpData; |
|||
} |
|||
|
|||
/** |
|||
* 关键词模版 |
|||
* @return Json |
|||
*/ |
|||
public function template(): Json |
|||
{ |
|||
return jsonReturn(0,'success',config('system.keyword_template_path')); |
|||
} |
|||
|
|||
/** |
|||
* @throws \app\exception\ModelEmptyException |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function monitor(MonitorService $monitorService): Json |
|||
{ |
|||
$param = input('get.'); |
|||
try { |
|||
validate(KeywordValidate::class)->scene('monitor')->check($param); |
|||
} catch (ValidateException $e) { |
|||
return jsonReturn(-4, $e->getMessage()); |
|||
} |
|||
$param['seller_id'] = $this->admin['seller_id']; |
|||
return $monitorService->getMonitorData($param); |
|||
} |
|||
|
|||
public function echarts() |
|||
{ |
|||
$param = $this->request->param(); |
|||
try { |
|||
validate(KeywordValidate::class)->scene('echarts')->check($param); |
|||
} catch (ValidateException $e) { |
|||
return jsonReturn(-4, $e->getMessage()); |
|||
} |
|||
|
|||
$keywordQueryModel = new KeywordQuery(); |
|||
|
|||
$startTime = time() - ($param['days'] * 86400); |
|||
|
|||
$list = $keywordQueryModel->where('create_time', '>=', $startTime) |
|||
->where('search_engine', $param['search_engine']) |
|||
->where('keyword_id', $param['id'])->select(); |
|||
$list = $list ? $list->toArray() : []; |
|||
|
|||
$days = []; |
|||
$values = []; |
|||
foreach ($list as $value) { |
|||
$days[] = $value['create_time']; |
|||
$values[] = $value['top_rank']; |
|||
} |
|||
$data = [ |
|||
'days' => array_values($days), |
|||
'values' => $values, |
|||
]; |
|||
|
|||
return jsonReturn(0, 'success', $data); |
|||
} |
|||
|
|||
// 单个更新排名
|
|||
public function updateRank() |
|||
{ |
|||
$param = $this->request->param(); |
|||
try { |
|||
validate(KeywordValidate::class)->scene('updateRank')->check($param); |
|||
} catch (ValidateException $e) { |
|||
return jsonReturn(-4, $e->getMessage()); |
|||
} |
|||
|
|||
$token = KeywordService::getChinaZToken($this->admin['seller_id']); |
|||
$keywordModel = new Keyword(); |
|||
$keywordData = $keywordModel->where([ |
|||
['id', '=', $param['id']] |
|||
])->findOrEmpty(); |
|||
|
|||
if (!isset($keywordData['name'])) { |
|||
return jsonReturn(-2, Lang::get('关键词不存在!')); |
|||
} |
|||
|
|||
switch ($param['search_engine']) { |
|||
case 'baidu_pc' : |
|||
KeywordService::baiduPcRank($token, $keywordData); |
|||
break; |
|||
case 'baidu_mob': |
|||
KeywordService::baiduMobileRank($token, $keywordData); |
|||
break; |
|||
case 'three_pc': |
|||
KeywordService::pc360Rank($token, $keywordData); |
|||
break; |
|||
case 'sougou_mob': |
|||
KeywordService::sougouMobileRank($token, $keywordData); |
|||
break; |
|||
default: |
|||
return jsonReturn(-3, Lang::get('搜索引擎不存在')); |
|||
break; |
|||
} |
|||
return jsonReturn(0, Lang::get('执行成功!')); |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,91 @@ |
|||
<?php |
|||
declare (strict_types = 1); |
|||
|
|||
namespace app\controller\backend; |
|||
|
|||
use app\model\KeywordQuery; |
|||
use app\service\MonitorService; |
|||
use app\validate\KeywordQueryValidate; |
|||
use think\exception\ValidateException; |
|||
use think\facade\Lang; |
|||
|
|||
|
|||
class KeywordQueryController extends BaseController |
|||
{ |
|||
|
|||
/** |
|||
* 显示资源列表 |
|||
* |
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function index(MonitorService $monitorService): \think\response\Json |
|||
{ |
|||
$param = input('get.'); |
|||
try { |
|||
validate(KeywordQueryValidate::class)->scene('monitor')->check($param); |
|||
} catch (ValidateException $e) { |
|||
return jsonReturn(-4, $e->getMessage()); |
|||
} |
|||
$param['seller_id'] = $this->admin['seller_id']; |
|||
return $monitorService->keywordMonitor($param); |
|||
} |
|||
|
|||
/** |
|||
* 显示指定的资源 |
|||
* |
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
* @throws \app\exception\ModelEmptyException |
|||
*/ |
|||
public function read(KeywordQuery $keywordQuery): \think\response\Json |
|||
{ |
|||
|
|||
$id = (int)input('id'); |
|||
if(!$id){ |
|||
return jsonReturn(-1,Lang::get('关键词ID')); |
|||
} |
|||
$where = [ |
|||
'id' => $id, |
|||
'seller_id' => $this->admin['seller_id'] |
|||
]; |
|||
// TODO
|
|||
// 其他逻辑
|
|||
$res = $keywordQuery->getKeywordQuery($where); |
|||
return json($res); |
|||
|
|||
} |
|||
|
|||
|
|||
public function save(KeywordQuery $keywordQuery) |
|||
{ |
|||
$param = input('keywordmonitor'); |
|||
foreach ( $param as &$val) { |
|||
$val['ranks'] = json_encode($val['ranks']); |
|||
} |
|||
unset($val); |
|||
$res = $keywordQuery->saveAll($param); |
|||
|
|||
dd($res); |
|||
} |
|||
|
|||
//获取关键词查询列表
|
|||
public function list() |
|||
{ |
|||
$param = $this->request->param(); |
|||
$param['limit'] = $param['limit'] ?? 10; |
|||
|
|||
if (empty($param['keyword_id']) || empty($param['engine'])) { |
|||
return jsonReturn(-1, Lang::get('参数错误')); |
|||
} |
|||
|
|||
$keywordQueryModel = new KeywordQuery(); |
|||
$list = $keywordQueryModel->getKeywordQueryList([ |
|||
['keyword_id', '=', $param['keyword_id']], |
|||
['search_engine', '=', $param['engine']] |
|||
], intval($param['limit'])); |
|||
|
|||
return json(pageReturn($list)); |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,129 @@ |
|||
<?php |
|||
|
|||
|
|||
namespace app\controller\backend; |
|||
|
|||
|
|||
use app\model\KeywordWebsite; |
|||
use app\validate\KeywordWebsiteValidate; |
|||
use think\exception\ValidateException; |
|||
use think\facade\Lang; |
|||
use think\response\Json; |
|||
|
|||
class KeywordWebsiteController extends BaseController |
|||
{ |
|||
/** |
|||
* 读取数据列表 |
|||
* @return Json |
|||
* @method Post |
|||
* @error_number 0: 成功, -1: 数据库查询失败, -2: 请求方法错误, -3: 数据重复, -4:数据缺少或校验不通过, |
|||
*/ |
|||
public function index(): Json |
|||
{ |
|||
if (\request()->isGet()) { |
|||
$param = input('get.'); |
|||
$param['seller_id'] = $this->admin['seller_id']; |
|||
|
|||
|
|||
$keyword = new KeywordWebsite(); |
|||
$res = $keyword->getKeywordWebsiteList($param); |
|||
return json($res); |
|||
} |
|||
return jsonReturn(-2, Lang::get('请求方法错误')); |
|||
} |
|||
|
|||
/** |
|||
* 读取数据 |
|||
* @return Json |
|||
*/ |
|||
public function read() |
|||
{ |
|||
if (request()->isGet()) { |
|||
$param = input('get.'); |
|||
$param['seller_id'] = $this->admin['seller_id']; |
|||
|
|||
try { |
|||
validate(KeywordWebsiteValidate::class)->scene('read')->check($param); |
|||
} catch (ValidateException $e) { |
|||
return jsonReturn(-4, $e->getMessage()); |
|||
} |
|||
|
|||
$KeywordWebsite = new KeywordWebsite(); |
|||
$res = $KeywordWebsite->getKeywordWebsite($param); |
|||
return json($res); |
|||
} |
|||
return jsonReturn(-2, Lang::get('请求方法错误')); |
|||
} |
|||
|
|||
/** |
|||
* 存入数据 |
|||
* @return Json |
|||
*/ |
|||
public function save() |
|||
{ |
|||
if (request()->isPost()) { |
|||
$param = input('post.'); |
|||
$param['seller_id'] = $this->admin['seller_id']; |
|||
|
|||
try { |
|||
validate(KeywordWebsiteValidate::class)->scene('save')->check($param); |
|||
} catch (ValidateException $e) { |
|||
return jsonReturn(-4, $e->getMessage()); |
|||
} |
|||
|
|||
$KeywordWebsite = new KeywordWebsite(); |
|||
$res = $KeywordWebsite->addKeywordWebsite($param); |
|||
|
|||
return jsonReturn($res['code'], $res['msg'], $res['data']); |
|||
} |
|||
return jsonReturn(-2, Lang::get('请求方法错误')); |
|||
} |
|||
|
|||
/** |
|||
* 更新数据 |
|||
* @return Json |
|||
*/ |
|||
public function update(): Json |
|||
{ |
|||
if (request()->isPost()) { |
|||
$param = input('post.'); |
|||
$param['seller_id'] = $this->admin['seller_id']; |
|||
|
|||
try { |
|||
validate(KeywordWebsiteValidate::class)->scene('update')->check($param); |
|||
} catch (ValidateException $e) { |
|||
return jsonReturn(-4, $e->getMessage()); |
|||
} |
|||
|
|||
$KeywordWebsite = new KeywordWebsite(); |
|||
$res = $KeywordWebsite->updateKeywordWebsite($param); |
|||
|
|||
return jsonReturn($res['code'], $res['msg']); |
|||
} |
|||
return jsonReturn(-2, Lang::get('请求方法错误')); |
|||
} |
|||
|
|||
/** |
|||
* 删除数据 |
|||
* @return Json |
|||
*/ |
|||
public function delete() |
|||
{ |
|||
if (request()->isPost()) { |
|||
$param = input('post.'); |
|||
$param['seller_id'] = $this->admin['seller_id']; |
|||
|
|||
try { |
|||
validate(KeywordWebsiteValidate::class)->scene('read')->check($param); |
|||
} catch (ValidateException $e) { |
|||
return jsonReturn(-4, $e->getMessage()); |
|||
} |
|||
|
|||
$KeywordWebsite = new KeywordWebsite(); |
|||
$res = $KeywordWebsite->deleteKeywordWebsite($param); |
|||
|
|||
return jsonReturn($res['code'], $res['msg']); |
|||
} |
|||
return jsonReturn(-2, Lang::get('请求方法错误')); |
|||
} |
|||
} |
|||
@ -0,0 +1,255 @@ |
|||
<?php |
|||
|
|||
|
|||
namespace app\controller\backend; |
|||
|
|||
|
|||
use app\exception\ModelEmptyException; |
|||
use app\exception\ModelException; |
|||
use app\model\Link; |
|||
use app\model\LinkWebsite; |
|||
use app\model\Model; |
|||
use app\model\RecycleBin; |
|||
use app\service\CacheService; |
|||
use app\validate\LinkValidate; |
|||
use think\facade\Cache; |
|||
use think\facade\Db; |
|||
use think\facade\Lang; |
|||
use think\response\Json; |
|||
|
|||
class LinkController extends BaseController |
|||
{ |
|||
/** |
|||
* 友情链接列表 |
|||
* @key id, seller_id |
|||
* @return Json |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function index(Link $link): Json |
|||
{ |
|||
if(request()->isGet()) { |
|||
$param = input('get.'); |
|||
$param['seller_id'] = $this->admin['seller_id']; |
|||
try { |
|||
validate(LinkValidate::class)->scene('index')->check($param); |
|||
} catch (\Exception $e) { |
|||
return jsonReturn(-4, $e->getMessage()); |
|||
} |
|||
$where = [ |
|||
'website_id' => $param['website_id'], |
|||
'seller_id' => $param['seller_id'], |
|||
'type' => $param['type'], |
|||
'is_del' => 1 |
|||
]; |
|||
$limit = $this->setLimit(); |
|||
// 翻页数据
|
|||
$res = $link->getLinkList($where,$limit); |
|||
$data = pageReturn($res); |
|||
|
|||
// 统计数据
|
|||
$total = $data['count']; |
|||
$changeNum = 0; |
|||
if($total){ |
|||
$now = mktime(0,0,0,date('m'),1,date('Y')); |
|||
// 上月总数
|
|||
$lastMonthNum = $link->where($where)->whereTime('create_time','<',$now)->count(); |
|||
$changeNum = $total - $lastMonthNum; |
|||
} |
|||
$data['change'] = $changeNum; |
|||
return json($data); |
|||
} |
|||
return jsonReturn(-2, Lang::get('请求方法错误')); |
|||
} |
|||
|
|||
/** |
|||
* 读取单条友情链接信息 |
|||
* @return Json |
|||
*/ |
|||
|
|||
public function read(Link $link): Json |
|||
{ |
|||
if (request()->isGet()) { |
|||
$param = input('get.'); |
|||
$param['seller_id'] = $this->admin['seller_id']; |
|||
try { |
|||
validate(LinkValidate::class)->scene('read')->check($param); |
|||
} catch (\Exception $e) { |
|||
return jsonReturn(-4, $e->getMessage()); |
|||
} |
|||
$param['is_del'] = 1; |
|||
$res = $link->getLink($param); |
|||
return json($res); |
|||
} |
|||
return jsonReturn(-2, Lang::get('请求方法错误')); |
|||
} |
|||
|
|||
/** |
|||
* 新增友情链接 |
|||
* @return Json |
|||
* @throws \app\exception\ModelException |
|||
* @throws \app\exception\ModelNotUniqueException |
|||
*/ |
|||
public function save(Link $link): Json |
|||
{ |
|||
if(request()->isPost()) { |
|||
$param = input('post.'); |
|||
$param['seller_id'] = $this->admin['seller_id']; |
|||
|
|||
try { |
|||
validate(LinkValidate::class)->scene('save')->check($param); |
|||
} catch (\Exception $e) { |
|||
return jsonReturn(-4, $e->getMessage()); |
|||
} |
|||
if(isset($param['add_time']) && empty($param['add_time'])){ |
|||
unset($param['add_time']); |
|||
} |
|||
if(isset($param['end_time']) && empty($param['end_time'])){ |
|||
unset($param['end_time']); |
|||
} |
|||
$link->saveUnique(['seller_id'=>$param['seller_id'],'website_id'=>$param['website_id'],'type'=>$param['type'],'name'=>$param['name'],'is_del'=>1],'友情链接已经存在'); |
|||
$res = $link->addLink($param); |
|||
CacheService::deleteCacheList('Link_cache_list'); |
|||
return json($res); |
|||
} |
|||
return jsonReturn(-2, Lang::get('请求方法错误')); |
|||
} |
|||
|
|||
/** |
|||
* 更新友情链接信息 |
|||
* @return Json |
|||
* @throws \app\exception\ModelException |
|||
* @throws \app\exception\ModelNotUniqueException |
|||
*/ |
|||
public function update(Link $link): Json |
|||
{ |
|||
if (request()->isPost()) |
|||
{ |
|||
$param = input('post.'); |
|||
|
|||
try { |
|||
validate(LinkValidate::class)->scene('update')->check($param); |
|||
} catch (\Exception $e) { |
|||
return jsonReturn(-4, $e->getMessage()); |
|||
} |
|||
$where = [ |
|||
'id' => $param['id'], |
|||
'seller_id' => $this->admin['seller_id'], |
|||
'website_id' => $param['website_id'], |
|||
]; |
|||
if(isset($param['add_time']) && empty($param['add_time'])){ |
|||
unset($param['add_time']); |
|||
} |
|||
if(isset($param['end_time']) && empty($param['end_time'])){ |
|||
unset($param['end_time']); |
|||
} |
|||
$link->updateUnique([ |
|||
'seller_id' => $this->admin['seller_id'], |
|||
'website_id' => $param['website_id'], |
|||
'type' => $param['type'], |
|||
'name' => $param['name'], |
|||
],$param['id'],lang('友情链接名称已存在')); |
|||
$link->updateUnique([ |
|||
'seller_id' => $this->admin['seller_id'], |
|||
'website_id' => $param['website_id'], |
|||
'type' => $param['type'], |
|||
'url' => $param['url'], |
|||
],$param['id'],lang('友情链接地址已存在')); |
|||
$res = $link->updateLink($where,$param); |
|||
CacheService::deleteCacheList('Link_cache_list'); |
|||
return json($res); |
|||
} |
|||
return jsonReturn(-2, Lang::get('请求方法错误')); |
|||
} |
|||
|
|||
/** |
|||
* 删除友情链接信息 |
|||
* @return Json |
|||
* @throws ModelException |
|||
*/ |
|||
public function delete(Link $link,RecycleBin $recycleBin): Json |
|||
{ |
|||
if (!request()->isPost()) { |
|||
return jsonReturn(-2, Lang::get('请求方法错误')); |
|||
} |
|||
$param = input('post.'); |
|||
try { |
|||
validate(LinkValidate::class)->scene('read')->check($param); |
|||
} catch (\Exception $e) { |
|||
return jsonReturn(-4, $e->getMessage()); |
|||
} |
|||
$param['seller_id'] = $this->admin['seller_id']; |
|||
$where = [ |
|||
'id' => $param['id'], |
|||
'seller_id' => $param['seller_id'], |
|||
'website_id' => $param['website_id'], |
|||
'is_del' => 1, |
|||
]; |
|||
Db::startTrans(); |
|||
try{ |
|||
$res = $link->softDelLink($where); |
|||
CacheService::deleteCacheList('Link_cache_list'); |
|||
if($res['data'] == 1){ |
|||
$binData = [ |
|||
'object_id' => $param['id'], |
|||
'table_name' => 'link', |
|||
'title' => "友情链接{$param['id']}", |
|||
'admin_id' => $this->admin['uid'], |
|||
'name' => $this->admin['name'], |
|||
]; |
|||
$recycleBin->addRecycleBin($binData); |
|||
} |
|||
Db::commit(); |
|||
}catch (\Exception $e){ |
|||
Db::rollback(); |
|||
return jsonReturn(-3,$e->getMessage()); |
|||
} |
|||
return json($res); |
|||
|
|||
} |
|||
|
|||
/** |
|||
* @throws ModelException |
|||
*/ |
|||
public function copy(Link $link): Json |
|||
{ |
|||
if(!request()->isPost()){ |
|||
return jsonReturn(-1, Lang::get('请求方法错误')); |
|||
} |
|||
$param = input('post.'); |
|||
try { |
|||
validate(LinkValidate::class)->scene('copy')->check($param); |
|||
} catch (\Exception $e) { |
|||
return jsonReturn(-4, $e->getMessage()); |
|||
} |
|||
if($param['website_id'] == $param['copy_site_id']){ |
|||
return jsonReturn(-5, lang('目标网站ID和复制网站ID不能相等')); |
|||
} |
|||
$where = [ |
|||
'seller_id' => $this->admin['seller_id'], |
|||
'website_id' => $param['copy_site_id'], |
|||
'is_del' => 1, |
|||
]; |
|||
$selfWhere = [ |
|||
'seller_id' => $this->admin['seller_id'], |
|||
'website_id' => $param['website_id'], |
|||
'is_del' => 1, |
|||
]; |
|||
$field = ['name','url','sort','target','is_del']; |
|||
$linkList = $link->getAllLink($where,$field)['data']->toArray(); |
|||
$selfList = $link->getAllLink($selfWhere,$field)['data']->toArray(); |
|||
$flag = array_column($selfList,'name'); |
|||
if(!empty($linkList)){ |
|||
foreach($linkList as $key => &$val){ |
|||
$val['website_id'] = $param['website_id']; |
|||
if(in_array($val['name'],$flag)){ |
|||
unset($linkList[$key]); |
|||
} |
|||
} |
|||
unset($val); |
|||
$res = json($link->addAllLink($linkList)); |
|||
}else{ |
|||
$res = jsonReturn(0,0,Lang::get('成功')); |
|||
} |
|||
return $res; |
|||
} |
|||
} |
|||
@ -0,0 +1,105 @@ |
|||
<?php |
|||
|
|||
namespace app\controller\backend; |
|||
|
|||
use app\model\PosterMaterial; |
|||
use app\model\SysSetting; |
|||
use app\service\upload\Upload; |
|||
use think\facade\Lang; |
|||
|
|||
class MaterialController extends BaseController |
|||
{ |
|||
public function index() |
|||
{ |
|||
$posterModel = new PosterMaterial(); |
|||
|
|||
$list = $posterModel->getMaterialList([]); |
|||
foreach ($list['data'] as $v) { |
|||
$v['source'] = str_replace("\\", '/', $v['source']); |
|||
} |
|||
|
|||
return json($list); |
|||
} |
|||
|
|||
public function upload() |
|||
{ |
|||
if (request()->isPost()) { |
|||
set_time_limit(0); |
|||
$file = request()->file('file'); |
|||
if (empty($file)) { |
|||
return jsonReturn(-8, Lang::get('文件上传失败,请重新尝试')); |
|||
} |
|||
|
|||
$imageSize = getimagesize($file); |
|||
$seller_id = $this->admin['seller_id']; |
|||
// 查看文件类型
|
|||
$fileName = $file->getOriginalName(); |
|||
$fileExt = $file->getOriginalExtension(); |
|||
$file_type = fileFormat($fileName); |
|||
|
|||
// 附件大小和类型验证
|
|||
// 获取上传配置
|
|||
$Settings = new SysSetting(); |
|||
$uploadSetting = $Settings->getAllCustomArrayData(['parent_id' => 1, 'group' => 'upload', 'status' => 1], 'id desc', 'id,group,title,value')['data']; |
|||
$uploadSetting = getColumnForKeyArray($uploadSetting, 'title'); |
|||
$limitSize = $uploadSetting[$file_type . '_size']['value'] * 1024; // byte
|
|||
$fileSize = $file->getSize(); // 单位byte
|
|||
if ($fileSize > $limitSize) { |
|||
return jsonReturn(-1, Lang::get('文件过大,请修改上传限制或者替换小的文件')); |
|||
} |
|||
$extArr = explode(',', $uploadSetting[$file_type . '_ext']['value']); |
|||
if (!in_array($fileExt, $extArr)) { |
|||
return jsonReturn(-2, Lang::get('文件格式错误,请重新上传')); |
|||
} |
|||
|
|||
$type = $this->getUploadType(); |
|||
$upload = new Upload(); |
|||
$upload->create($file, $seller_id, $type, $file_type); |
|||
$res = $upload->getUploadFileInfo()['data']; |
|||
$res['width'] = $imageSize[0]; |
|||
$res['height'] = $imageSize[1]; |
|||
$res['type'] = $fileExt; |
|||
if (strpos($res['url'], 'http') === false) { |
|||
$res['url'] = request()->domain() . '/' . $res['url']; |
|||
} |
|||
|
|||
return jsonReturn(0, Lang::get('上传成功'), $res); |
|||
} |
|||
|
|||
return jsonReturn(-3, Lang::get('请求方法错误')); |
|||
} |
|||
|
|||
public function add() |
|||
{ |
|||
if (request()->isPost()) { |
|||
|
|||
$param = input('post.'); |
|||
|
|||
$posterModel = new PosterMaterial(); |
|||
return json($posterModel->addMaterial($param)); |
|||
} |
|||
} |
|||
|
|||
public function del() |
|||
{ |
|||
$id = input('param.id'); |
|||
$posterModel = new PosterMaterial(); |
|||
|
|||
return json($posterModel->delMaterial($id)); |
|||
} |
|||
|
|||
/** |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function getUploadType() |
|||
{ |
|||
// 文件信息提取
|
|||
$where = [ |
|||
'seller_id' => $this->admin['seller_id'], |
|||
'group' => 'upload', |
|||
'title' => 'storage' |
|||
]; |
|||
$place = new SysSetting(); |
|||
return $place->getSysSetting($where)['data']->toArray()['value']; |
|||
} |
|||
} |
|||
@ -0,0 +1,163 @@ |
|||
<?php |
|||
declare (strict_types = 1); |
|||
|
|||
namespace app\controller\backend; |
|||
|
|||
use app\model\Module; |
|||
use app\service\CacheService; |
|||
use app\service\ModuleFieldService; |
|||
use app\service\ModuleService; |
|||
use app\validate\ModuleValidate; |
|||
use think\exception\ValidateException; |
|||
use think\facade\Lang; |
|||
|
|||
|
|||
class ModuleController extends BaseController |
|||
{ |
|||
|
|||
/** |
|||
* 资源列表 |
|||
* @param Module $module |
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function index(Module $module): \think\response\Json |
|||
{ |
|||
$where = [ |
|||
'seller_id' => $this->admin['seller_id'], |
|||
]; |
|||
$limit = $this->setLimit(); |
|||
|
|||
$moduleList = $module->getModuleList($where,$limit); |
|||
return json(pageReturn($moduleList)); |
|||
} |
|||
|
|||
/** |
|||
* 保存新建的资源 |
|||
* |
|||
* @return \think\Response\Json |
|||
* @throws \Exception |
|||
*/ |
|||
public function save(ModuleService $moduleService): \think\response\Json |
|||
{ |
|||
if(request()->isPost()){ |
|||
$param = input('post.'); |
|||
// 数据验证
|
|||
try{ |
|||
validate(ModuleValidate::class)->scene('save')->check($param); |
|||
}catch(ValidateException $e){ |
|||
return jsonReturn(-1, $e->getError()); |
|||
} |
|||
// 数据库前缀
|
|||
$prefix = config('database.connections')[config('database.default')]['prefix']; |
|||
$param['database_table'] = $prefix . $param['table']; |
|||
$param['status'] = 1; |
|||
$param['seller_id'] = $this->admin['seller_id']; |
|||
$res = $moduleService -> save($param); |
|||
|
|||
// 系统模型添加
|
|||
// $model = new Module();
|
|||
// $res = $model->addModule($param);
|
|||
return json($res); |
|||
|
|||
} |
|||
return jsonReturn(-3,Lang::get('请求方法错误')); |
|||
} |
|||
|
|||
/** |
|||
* 显示指定的资源 |
|||
* |
|||
* @return \think\Response\Json |
|||
* @throws \app\exception\ModelException |
|||
* @throws \app\exception\ModelEmptyException |
|||
*/ |
|||
public function read(Module $module): \think\response\Json |
|||
{ |
|||
|
|||
$id = (int)input('id'); |
|||
if(!$id){ |
|||
return jsonReturn(-1,Lang::get('模型ID不能为空')); |
|||
} |
|||
$where = [ |
|||
'id' => $id, |
|||
'seller_id' => $this->admin['seller_id'] |
|||
]; |
|||
$res = $module->getModule($where); |
|||
return json($res); |
|||
|
|||
} |
|||
|
|||
/** |
|||
* 保存更新的资源 |
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
* @throws \ReflectionException |
|||
*/ |
|||
public function update(Module $module): \think\response\Json |
|||
{ |
|||
if(request()->isPost()){ |
|||
$param = request()->only(['id','title','description','status']); |
|||
try { |
|||
validate(ModuleValidate::class)->scene('update')->check($param); |
|||
} catch (ValidateException $e) { |
|||
return jsonReturn(-1, $e->getError()); |
|||
} |
|||
$where = [ |
|||
'id' => $param['id'], |
|||
'seller_id' => $this->admin['seller_id'], |
|||
]; |
|||
$res = $module -> updateModule($where,$param); |
|||
CacheService::deleteRelationCacheByObject($module); |
|||
return json($res); |
|||
} |
|||
return jsonReturn(-3,Lang::get('请求方法错误')); |
|||
} |
|||
|
|||
/** |
|||
* 删除指定资源 |
|||
* |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function delete(ModuleService $moduleService): \think\response\Json |
|||
{ |
|||
if(request()->isPost()){ |
|||
$id = (int)input('id'); |
|||
if(!$id){ |
|||
return jsonReturn(-1,'ErrorMsg'); |
|||
} |
|||
$param = [ |
|||
'id' => $id, |
|||
'seller_id' => $this->admin['seller_id'] |
|||
]; |
|||
$res = $moduleService->destroy($param); |
|||
|
|||
return json($res); |
|||
} |
|||
return jsonReturn(-3,Lang::get('请求方法错误')); |
|||
} |
|||
|
|||
/** |
|||
* 模型表 |
|||
* @param ModuleService $moduleService |
|||
* @return \think\response\Json |
|||
*/ |
|||
public function all(ModuleService $moduleService): \think\response\Json |
|||
{ |
|||
return $moduleService -> getAllModuleTable($this->admin['seller_id']); |
|||
} |
|||
|
|||
/** |
|||
* 模型表字段 |
|||
* @param ModuleFieldService $moduleFieldService |
|||
* @return \think\response\Json |
|||
*/ |
|||
public function field(ModuleFieldService $moduleFieldService): \think\response\Json |
|||
{ |
|||
$table = $this->request->param('table'); |
|||
if(empty($table)){ |
|||
return jsonReturn(-1,Lang::get('表名不能为空')); |
|||
} |
|||
$res = $moduleFieldService -> getModuleTableField($table); |
|||
return json($res); |
|||
} |
|||
} |
|||
@ -0,0 +1,159 @@ |
|||
<?php |
|||
declare (strict_types = 1); |
|||
|
|||
namespace app\controller\backend; |
|||
|
|||
use app\model\ModuleField; |
|||
use app\service\ContentService; |
|||
use app\service\ModuleFieldService; |
|||
use app\validate\ModuleFieldValidate; |
|||
use think\exception\ValidateException; |
|||
use think\facade\Lang; |
|||
|
|||
|
|||
class ModuleFieldController extends BaseController |
|||
{ |
|||
|
|||
protected $paramKeys = ['id','module_id','form_title','table_field','validate_rule', |
|||
'type','length','default','status','placeholder','is_null','form_validate', |
|||
'order','settings','attach_data' |
|||
]; |
|||
|
|||
/** |
|||
* 显示资源列表 |
|||
* |
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function index(ModuleField $moduleField): \think\response\Json |
|||
{ |
|||
$moduleId = (int)input('module_id'); |
|||
if(!$moduleId){ |
|||
return jsonReturn(-1,Lang::get('模型ID不能为空')); |
|||
} |
|||
$where = [ |
|||
'seller_id' => $this->admin['seller_id'], |
|||
'module_id' => $moduleId, |
|||
]; |
|||
$moduleFieldList = $moduleField->where($where)->select()->each(function(&$item){ |
|||
if($item['form_type'] == 'reference'){ |
|||
$service = new ContentService(); |
|||
$item['attach_data'] = $service->getModuleContent($item['settings']['table'],$item['seller_id'])['data']; |
|||
} |
|||
|
|||
})->toArray(); |
|||
$list = getColumnForKeyArray($moduleFieldList,'order'); |
|||
$len = count($list); |
|||
$tmp = []; |
|||
$res = $this->sortField($list,$len,'id',$tmp); |
|||
return jsonReturn(0,Lang::get('成功'),$res); |
|||
} |
|||
|
|||
/** |
|||
* 保存新建的资源 |
|||
* |
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelEmptyException |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function save(ModuleFieldService $moduleFieldService,ModuleField $field): \think\response\Json |
|||
{ |
|||
if(request()->isPost()){ |
|||
$param = request()->only($this->paramKeys); |
|||
// 数据验证
|
|||
try{ |
|||
validate(ModuleFieldValidate::class)->scene('save')->check($param); |
|||
}catch(ValidateException $e){ |
|||
return jsonReturn(-1, $e->getError()); |
|||
} |
|||
$param['seller_id'] = $this->admin['seller_id']; |
|||
$res = $moduleFieldService->save($param); |
|||
return json($res); |
|||
|
|||
} |
|||
return jsonReturn(-3,Lang::get('请求方法错误')); |
|||
} |
|||
|
|||
/** |
|||
* 显示指定的资源 |
|||
* |
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
* @throws \app\exception\ModelEmptyException |
|||
*/ |
|||
public function read(ModuleField $moduleField): \think\response\Json |
|||
{ |
|||
|
|||
$id = (int)input('id'); |
|||
if(!$id){ |
|||
return jsonReturn(-1,'字段ID不能为空'); |
|||
} |
|||
$where = [ |
|||
'id' => $id, |
|||
'seller_id' => $this->admin['seller_id'] |
|||
]; |
|||
// 其他逻辑
|
|||
$res = $moduleField->getModuleField($where); |
|||
return json($res); |
|||
|
|||
} |
|||
|
|||
/** |
|||
* 保存更新的资源 |
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelEmptyException |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function update(ModuleFieldService $moduleFieldService): \think\response\Json |
|||
{ |
|||
if(request()->isPost()){ |
|||
$param = request()->only($this->paramKeys); |
|||
try { |
|||
validate(ModuleFieldValidate::class)->scene('update')->check($param); |
|||
} catch (ValidateException $e) { |
|||
return jsonReturn(-1, $e->getError()); |
|||
} |
|||
$param['seller_id'] = $this->admin['seller_id']; |
|||
$res = $moduleFieldService -> update($param); |
|||
return json($res); |
|||
} |
|||
return jsonReturn(-3,Lang::get('请求方法错误')); |
|||
} |
|||
|
|||
/** |
|||
* 删除指定资源 |
|||
* |
|||
* @throws \app\exception\ModelException |
|||
* @throws \app\exception\ModelEmptyException |
|||
*/ |
|||
public function delete(ModuleFieldService $moduleField): \think\response\Json |
|||
{ |
|||
if(request()->isPost()){ |
|||
$param = request()->only(['id','module_id']); |
|||
try { |
|||
validate(ModuleFieldValidate::class)->scene('delete')->check($param); |
|||
} catch (ValidateException $e) { |
|||
return jsonReturn(-1, $e->getError()); |
|||
} |
|||
$where = [ |
|||
'id' => $param['id'], |
|||
'module_id' => $param['module_id'], |
|||
'seller_id' => $this->admin['seller_id'] |
|||
]; |
|||
$res = $moduleField->destroy($where); |
|||
return json($res); |
|||
} |
|||
return jsonReturn(-3,Lang::get('请求方法错误')); |
|||
} |
|||
|
|||
public function sortField($data,$len,$key,&$tmp) |
|||
{ |
|||
if(isset($data[$key])){ |
|||
array_push($tmp,$data[$key]); |
|||
if($len > 0){ |
|||
$this->sortField($data,$len,$data[$key]['table_field'],$tmp); |
|||
} |
|||
} |
|||
return $tmp; |
|||
} |
|||
} |
|||
@ -0,0 +1,166 @@ |
|||
<?php |
|||
declare (strict_types = 1); |
|||
|
|||
namespace app\controller\backend; |
|||
|
|||
use app\model\Nav; |
|||
use app\model\NavCate; |
|||
use app\service\CacheService; |
|||
use app\validate\NavCateValidate; |
|||
use think\exception\ValidateException; |
|||
use think\facade\Lang; |
|||
|
|||
|
|||
class NavCateController extends BaseController |
|||
{ |
|||
/** |
|||
* 显示资源列表 |
|||
* |
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function index(NavCate $navCate): \think\response\Json |
|||
{ |
|||
$siteId = (int)input('website_id'); |
|||
if(!$siteId){ |
|||
return jsonReturn(-1,Lang::get('网站ID不能为空')); |
|||
} |
|||
$lang = input('lang'); |
|||
$where = [ |
|||
'seller_id' => $this->admin['seller_id'], |
|||
'website_id' => $siteId, |
|||
'lang' => $lang |
|||
]; |
|||
|
|||
$navCateList = $navCate->getAllCustomArrayData($where,'id asc'); |
|||
return json($navCateList); |
|||
} |
|||
|
|||
/** |
|||
* 保存新建的资源 |
|||
* |
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
* @throws \app\exception\ModelNotUniqueException |
|||
* @throws \ReflectionException |
|||
*/ |
|||
public function save(NavCate $navCate): \think\response\Json |
|||
{ |
|||
if(request()->isPost()){ |
|||
$param = input('post.'); |
|||
// 数据验证
|
|||
try{ |
|||
validate(NavCateValidate::class)->scene('save')->check($param); |
|||
}catch(ValidateException $e){ |
|||
return jsonReturn(-1, $e->getError()); |
|||
} |
|||
// 唯一验证
|
|||
$navCate -> saveUnique( |
|||
[ |
|||
'seller_id'=>$this->admin['seller_id'], |
|||
'website_id' => $param['website_id'], |
|||
'title'=>$param['title'], |
|||
'lang' => $param['lang'], |
|||
],'导航分类已存在'); |
|||
|
|||
$res = $navCate -> addNavCate($param); |
|||
CacheService::deleteRelationCacheByObject($navCate); |
|||
return json($res); |
|||
} |
|||
return jsonReturn(-3,Lang::get('请求方法错误')); |
|||
} |
|||
|
|||
/** |
|||
* 显示指定的资源 |
|||
* |
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
* @throws \app\exception\ModelEmptyException |
|||
*/ |
|||
public function read(NavCate $navCate): \think\response\Json |
|||
{ |
|||
|
|||
$id = (int)input('id'); |
|||
if(!$id){ |
|||
return jsonReturn(-1,lang('导航分类ID不能为空')); |
|||
} |
|||
$where = [ |
|||
'id' => $id, |
|||
'seller_id' => $this->admin['seller_id'] |
|||
]; |
|||
$res = $navCate->getNavCate($where); |
|||
return json($res); |
|||
|
|||
} |
|||
|
|||
/** |
|||
* 保存更新的资源 |
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelNotUniqueException |
|||
* @throws \app\exception\ModelException |
|||
* @throws \ReflectionException |
|||
*/ |
|||
public function update(NavCate $navCate): \think\response\Json |
|||
{ |
|||
if(request()->isPost()){ |
|||
$param = input('post.'); |
|||
try { |
|||
validate(NavCateValidate::class)->scene('update')->check($param); |
|||
} catch (ValidateException $e) { |
|||
return jsonReturn(-1, $e->getError()); |
|||
} |
|||
// 唯一验证
|
|||
$navCate -> updateUnique( |
|||
[ |
|||
'seller_id'=>$this->admin['seller_id'], |
|||
'website_id' => $param['website_id'], |
|||
'title'=>$param['title'], |
|||
'lang' => $param['lang'], |
|||
],$param['id'],lang('导航分类已存在')); |
|||
$where = [ |
|||
'id' => $param['id'], |
|||
'seller_id' => $this->admin['seller_id'], |
|||
]; |
|||
$res = $navCate -> updateNavCate($where,$param); |
|||
CacheService::deleteRelationCacheByObject($navCate); |
|||
return json($res); |
|||
} |
|||
return jsonReturn(-3,Lang::get('请求方法错误')); |
|||
} |
|||
|
|||
/** |
|||
* 删除指定资源 |
|||
* |
|||
* @throws \app\exception\ModelException |
|||
* @throws \ReflectionException |
|||
*/ |
|||
public function delete(NavCate $navCate,Nav $Nav): \think\response\Json |
|||
{ |
|||
if(request()->isPost()){ |
|||
$param = input('post.'); |
|||
try { |
|||
validate(NavCateValidate::class)->scene('delete')->check($param); |
|||
} catch (ValidateException $e) { |
|||
return jsonReturn(-1, $e->getError()); |
|||
} |
|||
$whereNav = [ |
|||
'nav_cate_id' => $param['id'], |
|||
'seller_id' => $this->admin['seller_id'], |
|||
'website_id' => $param['website_id'], |
|||
]; |
|||
$nav = $Nav->getNavList($whereNav)['data']->toArray(); |
|||
if(!empty($nav)){ |
|||
return jsonReturn(-2,lang('分类下有菜单不能直接删除')); |
|||
} |
|||
$where = [ |
|||
'id' => $param['id'], |
|||
'seller_id' => $this->admin['seller_id'], |
|||
'website_id' => $param['website_id'], |
|||
]; |
|||
$res = $navCate->delNavCate($where); |
|||
CacheService::deleteRelationCacheByObject($navCate); |
|||
return json($res); |
|||
} |
|||
return jsonReturn(-3,Lang::get('请求方法错误')); |
|||
} |
|||
} |
|||
@ -0,0 +1,316 @@ |
|||
<?php |
|||
declare (strict_types = 1); |
|||
|
|||
namespace app\controller\backend; |
|||
|
|||
use app\model\Category; |
|||
use app\model\Model; |
|||
use app\model\Nav; |
|||
use app\model\NavCate; |
|||
use app\model\Route; |
|||
use app\service\CacheService; |
|||
use app\validate\NavValidate; |
|||
use think\exception\ValidateException; |
|||
use think\facade\Db; |
|||
use think\facade\Lang; |
|||
|
|||
|
|||
class NavController extends BaseController |
|||
{ |
|||
/** |
|||
* 导航列表 |
|||
* |
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
* @throws \app\exception\ModelEmptyException |
|||
*/ |
|||
public function index(Nav $nav): \think\response\Json |
|||
{ |
|||
$param = input('param.'); |
|||
try{ |
|||
validate(NavValidate::class)->scene('index')->check($param); |
|||
}catch (ValidateException $e){ |
|||
return jsonReturn(-1,$e->getError()); |
|||
} |
|||
$where = [ |
|||
'seller_id' => $this->admin['seller_id'], |
|||
'nav_cate_id' => $param['cate_id'], |
|||
'website_id' => $param['website_id'], |
|||
'lang' => $param['lang'], |
|||
]; |
|||
$navList = $nav->getAllCustomArrayData($where)['data']; |
|||
$navList = makeTree($navList); |
|||
return jsonReturn(0,'success',$navList); |
|||
} |
|||
|
|||
/** |
|||
* 新增导航 |
|||
* |
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
* @throws \app\exception\ModelEmptyException |
|||
* @throws \app\exception\ModelNotUniqueException |
|||
* @throws \ReflectionException |
|||
*/ |
|||
public function save(Nav $nav,NavCate $NavCate): \think\response\Json |
|||
{ |
|||
if(request()->isPost()){ |
|||
$param = input('post.'); |
|||
// 数据验证
|
|||
try{ |
|||
validate(NavValidate::class)->scene('save')->check($param); |
|||
}catch(ValidateException $e) { |
|||
return jsonReturn(-1, $e->getError()); |
|||
} |
|||
$param['seller_id'] = $this->admin['seller_id']; |
|||
if(empty($param['sort'])){ |
|||
// 设置排序
|
|||
$maxOrder = $nav->getMaxOrderNav(['parent_id' => $param['parent_id'],'seller_id' => $this->admin['seller_id']], 'sort')['data']; |
|||
if (!empty($maxOrder)) { |
|||
$param['sort'] = (int)$maxOrder + 10; |
|||
} |
|||
} |
|||
// 设置网站ID
|
|||
$navCate = $NavCate -> getNavCate(['id'=>$param['nav_cate_id'],'seller_id'=>$this->admin['seller_id']])['data']; |
|||
$param['website_id'] = $navCate['website_id']; |
|||
// 唯一性验证
|
|||
$nav->saveUnique(['title'=>$param['title'],'lang'=>$param['lang'],'nav_cate_id'=>$param['nav_cate_id'],'website_id'=>$param['website_id'],'seller_id'=>$param['seller_id'],'parent_id'=>$param['parent_id']],'导航已存在'); |
|||
// 设置URL
|
|||
if($param['type'] == 2){ |
|||
$this->setNavUrl($param); |
|||
} |
|||
$res = $nav -> addNav($param); |
|||
CacheService::deleteRelationCacheByObject($nav); |
|||
return json($res); |
|||
} |
|||
return jsonReturn(-3,Lang::get('请求方法错误')); |
|||
} |
|||
|
|||
/** |
|||
* 导航详情 |
|||
* |
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
* @throws \app\exception\ModelEmptyException |
|||
*/ |
|||
public function read(Nav $nav): \think\response\Json |
|||
{ |
|||
|
|||
$param = input('param.'); |
|||
try { |
|||
validate(NavValidate::class)->scene('read')->check($param); |
|||
}catch (ValidateException $e){ |
|||
return jsonReturn(-1,$e->getError()); |
|||
} |
|||
|
|||
$where = [ |
|||
'id' => $param['id'], |
|||
'seller_id' => $this->admin['seller_id'], |
|||
'website_id' => $param['website_id'], |
|||
]; |
|||
$res = $nav->getNav($where); |
|||
return json($res); |
|||
|
|||
} |
|||
|
|||
/** |
|||
* 更新导航 |
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
* @throws \app\exception\ModelEmptyException |
|||
* @throws \app\exception\ModelNotUniqueException |
|||
* @throws \ReflectionException |
|||
*/ |
|||
public function update(Nav $nav, NavCate $NavCate): \think\response\Json |
|||
{ |
|||
if(request()->isPost()){ |
|||
$param = input('post.'); |
|||
try { |
|||
validate(NavValidate::class)->scene('update')->check($param); |
|||
} catch (ValidateException $e) { |
|||
return jsonReturn(-1, $e->getError()); |
|||
} |
|||
// 设置网站ID
|
|||
$navCate = $NavCate -> getNavCate(['id'=>$param['nav_cate_id'],'seller_id'=>$this->admin['seller_id']])['data']; |
|||
$param['website_id'] = $navCate['website_id']; |
|||
// 唯一性验证
|
|||
$nav->updateUnique(['title'=>$param['title'],'website_id'=>$param['website_id'],'nav_cate_id'=>$param['nav_cate_id'],'seller_id'=>$this->admin['seller_id']],$param['id'],'导航已存在'); |
|||
// 设置url
|
|||
if($param['type'] == 2){ |
|||
$this->setNavUrl($param); |
|||
} |
|||
if(empty($param['sort'])){ |
|||
// 设置排序
|
|||
$maxOrder = $nav->getMaxOrderNav(['parent_id' => $param['parent_id'],'seller_id' => $this->admin['seller_id']], 'sort')['data']; |
|||
if (!empty($maxOrder)) { |
|||
$param['sort'] = (int)$maxOrder + 10; |
|||
} |
|||
} |
|||
|
|||
|
|||
$where = [ |
|||
'id' => $param['id'], |
|||
'seller_id' => $this->admin['seller_id'], |
|||
]; |
|||
$res = $nav -> updateNav($where,$param); |
|||
CacheService::deleteRelationCacheByObject($nav); |
|||
return json($res); |
|||
} |
|||
return jsonReturn(-3,Lang::get('请求方法错误')); |
|||
} |
|||
|
|||
/** |
|||
* 删除导航 |
|||
* |
|||
* @throws \app\exception\ModelException |
|||
* @throws \app\exception\ModelEmptyException |
|||
* @throws \ReflectionException |
|||
*/ |
|||
public function delete(Nav $nav): \think\response\Json |
|||
{ |
|||
if(request()->isPost()){ |
|||
$param = input('post.'); |
|||
try { |
|||
validate(NavValidate::class)->scene('delete')->check($param); |
|||
}catch(ValidateException $e){ |
|||
return jsonReturn(-1,$e->getError()); |
|||
} |
|||
$where = [ |
|||
'id' => $param['id'], |
|||
'seller_id' => $this->admin['seller_id'], |
|||
'website_id' => $param['website_id'], |
|||
]; |
|||
$children = $nav->getNavList([ |
|||
'parent_id' => $param['id'], |
|||
'seller_id' => $this->admin['seller_id'], |
|||
'website_id' => $param['website_id'], |
|||
])['data']->toArray(); |
|||
if(count($children)){ |
|||
$res = ['code'=>-4,'msg'=>lang('有子菜单不能删除')]; |
|||
}else{ |
|||
$res = $nav->delNav($where); |
|||
CacheService::deleteRelationCacheByObject($nav); |
|||
} |
|||
return json($res); |
|||
} |
|||
return jsonReturn(-3,Lang::get('请求方法错误')); |
|||
} |
|||
|
|||
/** |
|||
* 设置导航路由 |
|||
* @throws \app\exception\ModelEmptyException |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function setNavUrl(&$param) |
|||
{ |
|||
$param['href'] = $this->getHrefByCategoryId($param['category_id'],$this->admin['seller_id']); |
|||
} |
|||
|
|||
/** |
|||
* @throws \app\exception\ModelEmptyException |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function getHrefByCategoryId($categoryId, $sellerId) |
|||
{ |
|||
$Category = new Category(); |
|||
$category = $Category -> getCustomArrayData(['id'=>$categoryId,'seller_id' => $sellerId])['data']; |
|||
if($category['type'] == 2){ |
|||
$href = 'javascript:;'; |
|||
}else if($category['type'] == 3){ |
|||
$href = $category['alias']; |
|||
} else{ |
|||
$Route = new Route(); |
|||
$route = $Route -> getCustomArrayData(['full_url'=> 'List/index?id='.$categoryId,'seller_id'=> $sellerId])['data']; |
|||
$href = $route['url']; |
|||
} |
|||
return $href; |
|||
} |
|||
|
|||
/** |
|||
* @throws \app\exception\ModelException |
|||
* @throws \app\exception\ModelEmptyException |
|||
* @throws \ReflectionException |
|||
*/ |
|||
public function batchCreate(): \think\response\Json |
|||
{ |
|||
$param = $this->request->only(['category_ids','nav_cate_id','target','lang','website_id']); |
|||
try { |
|||
validate(NavValidate::class)->scene('batchCreate')->check($param); |
|||
} catch (ValidateException $e) { |
|||
return jsonReturn(-1, $e->getError()); |
|||
} |
|||
// 获取所有栏目
|
|||
$category = new Category(); |
|||
$whereCate = [ |
|||
['seller_id','=',$this->admin['seller_id']], |
|||
['website_id','=',$param['website_id']], |
|||
['lang','=',$param['lang']] |
|||
]; |
|||
if($param['category_ids'] != 0 || !empty($param['category_ids'])){ |
|||
$whereCate[] = ['id','in',$param['category_ids']]; |
|||
} |
|||
$categories = $category -> getAllCustomArrayData($whereCate,'id asc')['data']; |
|||
// 查询目前导航表中的最大ID
|
|||
$prefix = env('database.prefix'); |
|||
$navTable = $prefix . 'nav'; |
|||
$res = Db::query("SHOW TABLE STATUS WHERE NAME = '$navTable'"); |
|||
$maxId = $res[0]['Auto_increment']; |
|||
$targetIds = range($maxId, $maxId + count($categories) - 1); |
|||
// 栏目ID
|
|||
$cateIds = array_column($categories,'id'); |
|||
$mapIds = array_combine($cateIds,$targetIds); |
|||
// 生成导航插入数据
|
|||
$nav = []; |
|||
foreach($categories as $cate){ |
|||
$tmp = []; |
|||
$href = $this->getHrefByCategoryId($cate['id'],$this->admin['seller_id']); |
|||
$tmp['href'] = $href; |
|||
$tmp['nav_cate_id'] = $param['nav_cate_id']; |
|||
$tmp['lang'] = $param['lang']; |
|||
$tmp['target'] = $param['target']; |
|||
$tmp['sort'] = $cate['sort']; |
|||
$tmp['title'] = $cate['title']; |
|||
$tmp['category_id'] = $cate['id']; |
|||
$tmp['status'] = 1; |
|||
$tmp['no_follow'] = 2; |
|||
$tmp['website_id'] = $param['website_id']; |
|||
$tmp['seller_id'] = $this->admin['seller_id']; |
|||
if($cate['parent_id']){ |
|||
$tmp['parent_id'] = $mapIds[$cate['parent_id']]; |
|||
}else{ |
|||
$tmp['parent_id'] = 0; |
|||
} |
|||
$tmp['id'] = $mapIds[$cate['id']]; |
|||
$nav[] = $tmp; |
|||
} |
|||
// 插入导航数据
|
|||
$Nav = new Nav(); |
|||
Db::name('nav')->insertAll($nav); |
|||
CacheService::deleteRelationCacheByObject($Nav); |
|||
return jsonReturn(0); |
|||
|
|||
} |
|||
|
|||
/** |
|||
* 更新导航状态 |
|||
* @throws \ReflectionException |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function updateStatus(): \think\response\Json |
|||
{ |
|||
$param = $this->request->only(['id','status']); |
|||
try { |
|||
validate(NavValidate::class)->scene('updateStatus')->check($param); |
|||
} catch (ValidateException $e) { |
|||
return jsonReturn(-1, $e->getError()); |
|||
} |
|||
$Nav = new Nav(); |
|||
$where = [ |
|||
'id' => $param['id'], |
|||
'seller_id' => $this->admin['seller_id'], |
|||
]; |
|||
$res = $Nav -> updateNav($where,['status'=>$param['status']]); |
|||
CacheService::deleteRelationCacheByObject($Nav); |
|||
return json($res); |
|||
} |
|||
} |
|||
@ -0,0 +1,52 @@ |
|||
<?php |
|||
|
|||
|
|||
namespace app\controller\backend; |
|||
|
|||
|
|||
use app\model\Plugin as PluginModel; |
|||
use app\service\PluginService; |
|||
use think\facade\Lang; |
|||
|
|||
class PluginController extends BaseController |
|||
{ |
|||
public function index() |
|||
{ |
|||
$pluginModel = new PluginModel(); |
|||
$plugins = $pluginModel->getList(); |
|||
return jsonReturn(0, Lang::get('成功'), $plugins); |
|||
} |
|||
|
|||
public function install() |
|||
{ |
|||
$param = $this->request->only(['name' => '']); |
|||
|
|||
$res = PluginService::install($param['name']); |
|||
if ($res === true) { |
|||
return jsonReturn(0, lang('安装成功')); |
|||
} |
|||
return jsonReturn(-1, lang('安装失败') . $res); |
|||
} |
|||
|
|||
public function uninstall() |
|||
{ |
|||
$param = $this->request->only(['name' => '']); |
|||
|
|||
$res = PluginService::uninstall($param['name']); |
|||
if ($res === true) { |
|||
return jsonReturn(0, lang('卸载成功')); |
|||
} |
|||
return jsonReturn(-1, lang('插件卸载失败') . $res); |
|||
} |
|||
|
|||
public function editStatus() |
|||
{ |
|||
$param = $this->request->only(['name' => '', 'status' => 1]); |
|||
|
|||
$res = PluginService::editStatus($param['name'], $param['status']); |
|||
|
|||
return json($res); |
|||
} |
|||
} |
|||
|
|||
|
|||
@ -0,0 +1,185 @@ |
|||
<?php |
|||
|
|||
namespace app\controller\backend; |
|||
|
|||
use app\model\Poster; |
|||
use Kkokk\Poster\PosterManager; |
|||
|
|||
class PosterController extends BaseController |
|||
{ |
|||
public function index() |
|||
{ |
|||
$posterModel = new Poster(); |
|||
return json($posterModel->getPosterList([])); |
|||
} |
|||
|
|||
public function add() |
|||
{ |
|||
if (request()->isPost()) { |
|||
$param = input('post.'); |
|||
$param['id'] = $param['id'] ?? 0; |
|||
|
|||
if (empty($param['name'])) { |
|||
return jsonReturn(-1, lang('请填写海报名称')); |
|||
} |
|||
$posterModel = new Poster(); |
|||
if ($posterModel->where([ |
|||
['id', '<>', $param['id']], |
|||
['name', '=', $param['name']] |
|||
])->value('id')) { |
|||
return jsonReturn(-1, lang('海报名称已存在')); |
|||
} |
|||
|
|||
try { |
|||
$preview = $this->makePreview($param, 'cover'); |
|||
} catch (\Exception $e) { |
|||
return jsonReturn(-3, 'error', $e->getTrace()); |
|||
} |
|||
|
|||
$addParam = [ |
|||
'name' => $param['name'], |
|||
'preview' => request()->domain() . '/' . ltrim($preview['url'], './'), |
|||
'status' => 1, |
|||
'design_content' => json_encode($param) |
|||
]; |
|||
|
|||
if (!empty($param['id'])) { |
|||
return json($posterModel->editPoster([['id', '=', $param['id']]],$addParam)); |
|||
} |
|||
|
|||
return json($posterModel->addPoster($addParam)); |
|||
} |
|||
} |
|||
|
|||
public function copy() { |
|||
if (!request()->isPost()) { |
|||
return jsonReturn(-1, lang('请求错误')); |
|||
} |
|||
|
|||
$param = input('post.'); |
|||
if (empty($param['id'])) { |
|||
return jsonReturn(-2, lang('参数错误')); |
|||
} |
|||
$posterModel = new Poster(); |
|||
$data = $posterModel->where('id', '=', $param['id'])->findOrEmpty(); |
|||
if (empty($data)) { |
|||
return jsonReturn(-3, lang('找不到要复制的海报')); |
|||
} |
|||
|
|||
$designContent = json_decode($data['design_content'], true); |
|||
|
|||
$designContent['name'] = $designContent['name'] . lang('-副本'); |
|||
unset($designContent['id']); |
|||
$addParam = [ |
|||
'name' => $designContent['name'], |
|||
'preview' => $data['preview'], |
|||
'status' => 1, |
|||
'design_content' => json_encode($designContent) |
|||
]; |
|||
$res = $posterModel->addPoster($addParam); |
|||
if ($res['code'] == 0) { |
|||
$res['msg'] = lang('复制成功'); |
|||
} |
|||
return json($res); |
|||
} |
|||
|
|||
public function edit() |
|||
{ |
|||
$id = input('param.id'); |
|||
|
|||
$posterModel = new Poster(); |
|||
return json($posterModel->getDesignInfoById($id)); |
|||
} |
|||
|
|||
public function del() |
|||
{ |
|||
$id = input('param.id'); |
|||
|
|||
$posterModel = new Poster(); |
|||
return json($posterModel->del($id)); |
|||
} |
|||
|
|||
public function preview() |
|||
{ |
|||
try { |
|||
|
|||
$posterData = input('post.'); |
|||
$result = $this->makePreview($posterData); |
|||
|
|||
return jsonReturn(0, 'success', request()->domain() . '/' . ltrim($result['url'], './')); |
|||
} catch (\Exception $e) { |
|||
file_put_contents('./error.log', $e->getFile() . ' --- ' . $e->getLine() . ' --- ' . $e->getMessage() . PHP_EOL, FILE_APPEND); |
|||
return jsonReturn(-1, $e->getMessage()); |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* @param $posterData |
|||
* @param $type |
|||
* @return mixed |
|||
*/ |
|||
protected function makePreview($posterData, $type = 'temp') |
|||
{ |
|||
$name = uniqid(); |
|||
|
|||
if ($type == 'temp') { |
|||
$PosterManager = new PosterManager('./poster_preview/temp/' . $name . '.' . $posterData['type']); |
|||
} else { |
|||
$PosterManager = new PosterManager('./poster_preview/cover/' . $name . '.' . $posterData['type']); |
|||
} |
|||
|
|||
$temp = $PosterManager; |
|||
|
|||
if ($posterData['activeName'] == 'img' && !empty($posterData['img_src'])) { |
|||
$temp = $temp->buildImDst($posterData['img_src'], $posterData['width'], $posterData['height']); |
|||
} else { |
|||
$temp = $temp->buildIm($posterData['width'], $posterData['height'], $this->hex2rgba($posterData['color'])); |
|||
} |
|||
|
|||
if (isset($posterData['item']) && !empty($posterData['item'])) { |
|||
foreach ($posterData['item'] as $vo) { |
|||
if ($vo['t'] == 'text') { |
|||
$font = '/system_file/alifont/' . $vo['fn'] . '.woff'; |
|||
$temp = $temp->buildText($vo['v'], $vo['x'], $vo['y'], $vo['s'], $this->hex2rgba($vo['c']), $vo['w'], $font, $vo['a'], $vo['w'], 1, 0, $vo['rotate']); |
|||
} else if ($vo['t'] == 'image') { |
|||
$temp = $temp->buildImage($vo['v'], $vo['x'], $vo['y'], 0, 0, $vo['w'], $vo['h'], $this->hex2rgba($vo['c']), 'normal', $vo['rotate']); |
|||
} else if ($vo['t'] == 'qrcode') { |
|||
$temp = $temp->buildQr($vo['v'], $vo['x'], $vo['y'], 0, 0, $vo['w'], $vo['h'], 4, 1, $vo['rotate']); |
|||
} |
|||
} |
|||
} |
|||
|
|||
return $temp->getPoster(); |
|||
} |
|||
|
|||
protected function hex2rgba($color) |
|||
{ |
|||
$hexColor = str_replace('#', '', $color); |
|||
$lens = strlen($hexColor); |
|||
|
|||
if ($lens != 3 && $lens != 6) { |
|||
return false; |
|||
} |
|||
|
|||
$newColor = ''; |
|||
if ($lens == 3) { |
|||
|
|||
for ($i = 0; $i < $lens; $i++) { |
|||
$newColor .= $hexColor[$i] . $hexColor[$i]; |
|||
} |
|||
} else { |
|||
|
|||
$newColor = $hexColor; |
|||
} |
|||
|
|||
$hex = str_split($newColor, 2); |
|||
$rgba = []; |
|||
|
|||
foreach ($hex as $vls) { |
|||
$rgba[] = hexdec($vls); |
|||
} |
|||
|
|||
$rgba[] = 1; |
|||
return $rgba; |
|||
} |
|||
} |
|||
@ -0,0 +1,121 @@ |
|||
<?php |
|||
declare (strict_types = 1); |
|||
|
|||
namespace app\controller\backend; |
|||
|
|||
use app\model\RecycleBin; |
|||
use app\service\ModuleFieldService; |
|||
use think\facade\Db; |
|||
use think\facade\Lang; |
|||
|
|||
|
|||
class RecycleBinController extends BaseController |
|||
{ |
|||
/** |
|||
* 显示资源列表 |
|||
* |
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function index(RecycleBin $recycleBin): \think\response\Json |
|||
{ |
|||
$where = [ |
|||
'seller_id' => $this->admin['seller_id'], |
|||
]; |
|||
$table = input('param.table_name') ?: ''; |
|||
if($table){ |
|||
$where['table_name'] = $table; |
|||
} |
|||
$limit = $this->setLimit(); |
|||
$recycleBinList = $recycleBin->getRecycleBinList($where,$limit); |
|||
return json(pageReturn($recycleBinList)); |
|||
} |
|||
|
|||
/** |
|||
* 回收站清空 |
|||
* |
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function clean(RecycleBin $recycleBin): \think\response\Json |
|||
{ |
|||
if(request()->isPost()){ |
|||
$res = $recycleBin -> delRecycleBin(['seller_id'=>$this->admin['seller_id']]); |
|||
return json($res); |
|||
} |
|||
return jsonReturn(-3,Lang::get('请求方法错误')); |
|||
} |
|||
|
|||
/** |
|||
* 单条数据恢复 |
|||
* |
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
* @throws \app\exception\ModelEmptyException |
|||
* @throws \think\db\exception\DbException |
|||
*/ |
|||
public function restore(ModuleFieldService $fieldService): \think\response\Json |
|||
{ |
|||
if(request()->isPost()){ |
|||
$id = (int)input('id'); |
|||
if(!$id){ |
|||
return jsonReturn(-1,Lang::get('数据ID不能为空')); |
|||
} |
|||
return $fieldService->resotreData($id,$this->admin['seller_id']); |
|||
} |
|||
return jsonReturn(-3,Lang::get('请求方法错误')); |
|||
|
|||
} |
|||
|
|||
/** |
|||
* 删除指定资源 |
|||
* |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function delete(RecycleBin $recycleBin): \think\response\Json |
|||
{ |
|||
if(request()->isPost()){ |
|||
$id = (int)input('id'); |
|||
if(!$id){ |
|||
return jsonReturn(-1,Lang::get('数据ID不能为空')); |
|||
} |
|||
$where = [ |
|||
'id' => $id, |
|||
'seller_id' => $this->admin['seller_id'] |
|||
]; |
|||
$res = $recycleBin->delRecycleBin($where); |
|||
return json($res); |
|||
} |
|||
return jsonReturn(-3,Lang::get('请求方法错误')); |
|||
} |
|||
|
|||
/** |
|||
* 恢复多条数据 |
|||
* @throws \think\db\exception\DbException |
|||
*/ |
|||
public function allRestore(RecycleBin $recycleBin): \think\response\Json |
|||
{ |
|||
if(!request()->isPost()){ |
|||
return jsonReturn(-4,Lang::get('请求方法错误')); |
|||
} |
|||
$ids = input('param.ids'); |
|||
if(!is_array($ids)){ |
|||
return jsonReturn(-1,Lang::get('恢复数据参数错误')); |
|||
} |
|||
if(empty($ids)){ |
|||
return jsonReturn(-2,Lang::get('恢复数据参数不能为空')); |
|||
} |
|||
$tableName = $recycleBin->whereIn('id',$ids)->column('table_name'); |
|||
if(empty($tableName)){ |
|||
return jsonReturn(-5,Lang::get('恢复数据不存在')); |
|||
} |
|||
$table = array_unique($tableName); |
|||
if(count($table) > 1){ |
|||
return jsonReturn(-3,Lang::get('请选择相同类型的内容恢复')); |
|||
} |
|||
$recycleBin->whereIn('id',$ids)->where('seller_id',$this->admin['seller_id'])->delete(); |
|||
$res = Db::name($table[0])->whereIn('id',$ids)->update(['is_del'=>1,'delete_time'=>0,'update_time'=>time()]); |
|||
return jsonReturn(0,Lang::get('恢复成功'),$res); |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,108 @@ |
|||
<?php |
|||
declare (strict_types = 1); |
|||
|
|||
namespace app\controller\backend; |
|||
|
|||
use app\model\Attachment; |
|||
use app\model\Resume; |
|||
use think\facade\Lang; |
|||
|
|||
class ResumeController extends BaseController |
|||
{ |
|||
/** |
|||
* 简历列表 |
|||
* |
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function index(Resume $resume): \think\response\Json |
|||
{ |
|||
$where = [ |
|||
['seller_id' ,'=', $this->admin['seller_id']], |
|||
['is_del' ,'=', 1], |
|||
]; |
|||
$limit = 10; |
|||
$limitParam = (int)input('limit'); |
|||
if($limitParam){ |
|||
$limit = $limitParam; |
|||
} |
|||
// 添加其他逻辑
|
|||
$param = $this->request->only(['username'=>'','phone'=>'','start_time'=>'','end_time'=>'','email'=>'']); |
|||
if(!empty($param['username'])){ |
|||
$where[] = ['username','like','%'.$param['username'.'%']]; |
|||
} |
|||
if(!empty($param['phone'])){ |
|||
$where[] = ['phone','like','%'.$param['phone'.'%']]; |
|||
} |
|||
if(!empty($param['email'])){ |
|||
$where[] = ['email','like','%'.$param['email'.'%']]; |
|||
} |
|||
if(!empty($param['start_time']) && !empty($param['end_time']) ){ |
|||
$where[] = ['create_time','between',[$param['start_time'],$param['end_time']]]; |
|||
} |
|||
$attachment = new Attachment(); |
|||
$resumeList = $resume->where($where)->paginate($limit)->each(function($item)use($attachment){ |
|||
$file = $attachment->field('id,name,url')->where('id',$item->attachment_id)->findOrEmpty(); |
|||
if(empty($file)){ |
|||
$item->attachment = null; |
|||
}else{ |
|||
$item->attachment = $file; |
|||
} |
|||
}); |
|||
return json(['code' => 0, 'msg' => 'ok', 'count' => $resumeList->total(), 'data' => $resumeList->all()]); |
|||
} |
|||
|
|||
/** |
|||
* 删除简历 |
|||
* |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function delete(Resume $resume): \think\response\Json |
|||
{ |
|||
if(request()->isPost()){ |
|||
$id = (int)input('id'); |
|||
if(!$id){ |
|||
return jsonReturn(-1,Lang::get('ID不能为空')); |
|||
} |
|||
$where = [ |
|||
'id' => $id, |
|||
'seller_id' => $this->admin['seller_id'] |
|||
]; |
|||
$res = $resume->softDelResume($where); |
|||
return json($res); |
|||
} |
|||
return jsonReturn(-3,Lang::get('请求方法错误')); |
|||
} |
|||
|
|||
public function save(Resume $resume): \think\response\Json |
|||
{ |
|||
if(request()->isPost()){ |
|||
$param = $this->request->only(['nav_content','html_content','md_content','username']); |
|||
$res = $resume->addCustomData($param); |
|||
return json($res); |
|||
} |
|||
return jsonReturn(-3,Lang::get('请求方法错误')); |
|||
} |
|||
|
|||
public function read(Resume $resume): \think\response\Json |
|||
{ |
|||
if(request()->isGet()){ |
|||
$id = (int)$this->request->param('id'); |
|||
$res = $resume->getCustomData(['id'=>$id]); |
|||
return json($res); |
|||
} |
|||
return jsonReturn(-3,Lang::get('请求方法错误')); |
|||
} |
|||
|
|||
public function update(Resume $resume): \think\response\Json |
|||
{ |
|||
if(request()->isPost()){ |
|||
$param = $this->request->only(['nav_content','html_content','md_content','username','id']); |
|||
$id = (int) $param['id']; |
|||
unset($param['id']); |
|||
$res = $resume->updateCustomData([['id','=',$id]],$param); |
|||
return json($res); |
|||
} |
|||
return jsonReturn(-3,Lang::get('请求方法错误')); |
|||
} |
|||
} |
|||
@ -0,0 +1,186 @@ |
|||
<?php |
|||
declare (strict_types=1); |
|||
|
|||
namespace app\controller\backend; |
|||
|
|||
use app\model\Admin; |
|||
use app\model\AdminMenu; |
|||
use app\model\Role; |
|||
use app\service\RoleService; |
|||
use app\validate\RoleValidate; |
|||
use think\exception\ValidateException; |
|||
use think\facade\Cache; |
|||
use think\facade\Lang; |
|||
|
|||
|
|||
class RoleController extends BaseController |
|||
{ |
|||
/** |
|||
* 显示资源列表 |
|||
* |
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function index(Role $role): \think\response\Json |
|||
{ |
|||
$where = [ |
|||
'seller_id' => $this->admin['seller_id'], |
|||
]; |
|||
|
|||
$roleList = $role->getRoleList($where); |
|||
return json($roleList); |
|||
} |
|||
|
|||
/** |
|||
* 保存新建的资源 |
|||
* |
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
* @throws \app\exception\ModelNotUniqueException |
|||
*/ |
|||
public function save(Role $role): \think\response\Json |
|||
{ |
|||
if (request()->isPost()) { |
|||
$param = request()->only(['title', 'status']); |
|||
// 数据验证
|
|||
try { |
|||
validate(RoleValidate::class)->scene('save')->check($param); |
|||
} catch (ValidateException $e) { |
|||
return jsonReturn(-1, $e->getError()); |
|||
} |
|||
$param['seller_id'] = $this->admin['seller_id']; |
|||
|
|||
$role->saveUnique(['seller_id' => $param['seller_id'], 'title' => $param['title']], lang('角色已经存在')); |
|||
|
|||
$res = $role->addRole($param); |
|||
return json($res); |
|||
} |
|||
return jsonReturn(-3, Lang::get('请求方法错误')); |
|||
} |
|||
|
|||
/** |
|||
* 显示指定的资源 |
|||
* |
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
* @throws \app\exception\ModelEmptyException |
|||
*/ |
|||
public function read(Role $role): \think\response\Json |
|||
{ |
|||
|
|||
$id = (int)input('id'); |
|||
if (!$id) { |
|||
return jsonReturn(-1, Lang::get('角色ID不能为空')); |
|||
} |
|||
$where = [ |
|||
'id' => $id, |
|||
'seller_id' => $this->admin['seller_id'] |
|||
]; |
|||
$res = $role->getRole($where, ['website']); |
|||
if (!empty($res['data']['kid_auth'])) { |
|||
$res['data']['auth'] = explode(',', $res['data']['kid_auth']); |
|||
} else { |
|||
$res['data']['auth'] = []; |
|||
} |
|||
$res['data']['website_id'] = array_column($res['data']['website']->toArray(), 'id'); |
|||
return json($res); |
|||
} |
|||
|
|||
/** |
|||
* 保存更新的资源 |
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
* @throws \app\exception\ModelNotUniqueException |
|||
* @throws \app\exception\ModelEmptyException |
|||
*/ |
|||
public function update(Role $role): \think\response\Json |
|||
{ |
|||
if (request()->isPost()) { |
|||
$param = input('post.'); |
|||
try { |
|||
validate(RoleValidate::class)->scene('update')->check($param); |
|||
} catch (ValidateException $e) { |
|||
return jsonReturn(-1, $e->getError()); |
|||
} |
|||
if ($param['group'] == 1) { |
|||
jsonReturn(-2, Lang::get('系统默认角色,不能编辑')); |
|||
} |
|||
$where = [ |
|||
'id' => $param['id'], |
|||
'seller_id' => $this->admin['seller_id'], |
|||
]; |
|||
$roleInfo = $role->getRole($where)['data']; |
|||
if (empty($roleInfo)) { |
|||
return jsonReturn(-3, Lang::get('角色不存在')); |
|||
} |
|||
$role->updateUnique(['seller_id' => $this->admin['seller_id'], 'title' => $param['title']], $param['id'], lang('角色已经存在')); |
|||
if (!empty($param['auth'])) { |
|||
$len = count($param['auth']); |
|||
foreach ($param['auth'] as $key => $val) { |
|||
if ($val == 2) { |
|||
break; |
|||
} |
|||
if ($len == $key + 1) { |
|||
$param['auth'][] = 2; |
|||
} |
|||
} |
|||
$param['auth'] = implode(',', $param['auth']); |
|||
} |
|||
$roleInfo->website()->detach(); |
|||
$roleInfo->website()->attach($param['website_id']); |
|||
unset($param['website_id']); |
|||
if(!empty($param['kid_auth'])){ |
|||
$param['kid_auth'] = implode(',', $param['kid_auth']); |
|||
}else{ |
|||
$param['kid_auth'] = ''; |
|||
} |
|||
$res = $role->updateRole($where, $param); |
|||
return json($res); |
|||
} |
|||
return jsonReturn(-3, Lang::get('请求方法错误')); |
|||
} |
|||
|
|||
/** |
|||
* 删除指定资源 |
|||
* |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function delete(Role $role): \think\response\Json |
|||
{ |
|||
if (request()->isPost()) { |
|||
$id = (int)input('id'); |
|||
if (!$id) { |
|||
return jsonReturn(-1, Lang::get('Id不能为空')); |
|||
} |
|||
if ($id == 1) { |
|||
return jsonReturn(-2, Lang::get('系统默认角色,不能删除')); |
|||
} |
|||
$where = [ |
|||
'id' => $id, |
|||
'seller_id' => $this->admin['seller_id'] |
|||
]; |
|||
$res = $role->delRole($where); |
|||
return json($res); |
|||
} |
|||
return jsonReturn(-3, Lang::get('请求方法错误')); |
|||
} |
|||
|
|||
|
|||
/** |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function getAuth(AdminMenu $AdminMenu): \think\response\Json |
|||
{ |
|||
$auth = $AdminMenu->getAllAdminMenu(['seller_id' => $this->admin['seller_id'], 'status' => 1])['data']->toArray(); |
|||
$auth = generate($auth); |
|||
return jsonReturn(0, Lang::get('成功'), $auth); |
|||
} |
|||
|
|||
public function getMenuAndUpdateAuth() |
|||
{ |
|||
$adminId = $this->admin['uid']; |
|||
$res = RoleService::getMenuAndUpdateAuth($adminId); |
|||
|
|||
return json($res); |
|||
} |
|||
} |
|||
@ -0,0 +1,80 @@ |
|||
<?php |
|||
|
|||
namespace app\controller\backend; |
|||
|
|||
use app\model\SeoAccount; |
|||
use app\validate\SeoAccountValidate; |
|||
use think\exception\ValidateException; |
|||
use think\response\Json; |
|||
|
|||
/** |
|||
* SEO账号灌管理 |
|||
*/ |
|||
class SeoAccountController extends BaseController |
|||
{ |
|||
|
|||
public function lists(SeoAccount $seoModel): Json |
|||
{ |
|||
$limit = input('param.limit'); |
|||
$where = []; |
|||
|
|||
$list = $seoModel->getAccountList($where, $limit); |
|||
return json(pageReturn($list)); |
|||
} |
|||
|
|||
public function add(SeoAccount $seoModel): Json |
|||
{ |
|||
$param = input('post.'); |
|||
|
|||
$has = $seoModel->field('id')->where('account', $param['account'])->find(); |
|||
if (!empty($has)) { |
|||
return jsonReturn(-2, lang('该账号已经存在')); |
|||
} |
|||
|
|||
try { |
|||
|
|||
validate(SeoAccountValidate::class)->check($param); |
|||
} catch (ValidateException $e) { |
|||
return jsonReturn(-1, $e->getError()); |
|||
} |
|||
|
|||
$param['create_time'] = date('Y-m-d H:i:s'); |
|||
|
|||
$seoModel->insert($param); |
|||
return jsonReturn(0, lang('添加账号成功')); |
|||
} |
|||
|
|||
public function info(SeoAccount $seoModel): Json |
|||
{ |
|||
$info = $seoModel->where('id', input('param.id'))->find(); |
|||
return jsonReturn(0, lang('查询成功'), $info); |
|||
} |
|||
|
|||
public function edit(SeoAccount $seoModel): Json |
|||
{ |
|||
$param = input('post.'); |
|||
|
|||
$has = $seoModel->field('id')->where('account', $param['account'])->where('id', '<>', $param['id'])->find(); |
|||
if (!empty($has)) { |
|||
return jsonReturn(-2, lang('该账号已经存在')); |
|||
} |
|||
|
|||
try { |
|||
validate(SeoAccountValidate::class)->check($param); |
|||
} catch (ValidateException $e) { |
|||
return jsonReturn(-1, $e->getError()); |
|||
} |
|||
|
|||
$param['update_time'] = date('Y-m-d H:i:s'); |
|||
|
|||
$seoModel->where('id', $param['id'])->update($param); |
|||
return jsonReturn(0, lang('编辑账号成功')); |
|||
} |
|||
|
|||
public function del(SeoAccount $seoModel) |
|||
{ |
|||
$seoModel->where('id', input('param.id'))->delete(); |
|||
|
|||
return jsonReturn(0, lang('删除成功')); |
|||
} |
|||
} |
|||
@ -0,0 +1,242 @@ |
|||
<?php |
|||
|
|||
declare (strict_types=1); |
|||
|
|||
namespace app\controller\backend; |
|||
|
|||
use think\facade\Db; |
|||
|
|||
class SeoCheckController extends BaseController |
|||
{ |
|||
public function index() |
|||
{ |
|||
$limit = input('param.limit'); |
|||
$where = []; |
|||
|
|||
$list = Db::name('seo_check_task')->where($where)->order('create_time desc')->paginate($limit); |
|||
|
|||
return json(pageReturn(['code' => 0, 'data' => $list, 'msg' => lang('成功')])); |
|||
} |
|||
|
|||
public function check() |
|||
{ |
|||
$param = $this->request->param(); |
|||
if ($param['flag'] == 'progress') { |
|||
|
|||
$taskDetail = Db::name('seo_check_task_detail')->where('task_id', $param['task_id'])->select(); |
|||
$isEnd = true; |
|||
$checkData = []; |
|||
$success = 0; |
|||
$error = 0; |
|||
foreach ($taskDetail as $vo) { |
|||
if ($vo['status'] == 1) { |
|||
$isEnd = false; |
|||
} |
|||
|
|||
if (!empty($vo['remark'])) { |
|||
$data = json_decode($vo['remark'], true); |
|||
$checkData[] = $data; |
|||
|
|||
if ($data['code'] == 101) { |
|||
foreach ($data['data'] as $key => $v) { |
|||
if ($v['status'] == 1) { |
|||
$success++; |
|||
continue; |
|||
} |
|||
if ($key == 'tags') { |
|||
$error += isset($v['msg']['ajax']) ? count($v['msg']['ajax']) : 0; |
|||
$error += isset($v['msg']['alt']) ? count($v['msg']['alt']) : 0; |
|||
continue; |
|||
} |
|||
if (is_array($v['msg'])) { |
|||
$error += count($v['msg']); |
|||
} else { |
|||
$error ++; |
|||
} |
|||
} |
|||
} |
|||
|
|||
if ($data['code'] == 102) { |
|||
if ($data['data']['status'] == 1) { |
|||
$success++; |
|||
} else { |
|||
$error++; |
|||
} |
|||
} |
|||
|
|||
if ($data['code'] == 103) { |
|||
$error += isset($data['data']['deadLink']) ? count($data['data']['deadLink']) : 0; |
|||
$error += isset($data['data']['keywords']) ? count($data['data']['keywords']) : 0; |
|||
} |
|||
|
|||
if ($data['code'] == 104) { |
|||
if (isset($data['data']['inlinks']['linksHave'])) { |
|||
foreach ($data['data']['inlinks']['linksHave'] as $v) { |
|||
if ($v['status'] == 1) { |
|||
$success++; |
|||
} else { |
|||
$error++; |
|||
} |
|||
} |
|||
} |
|||
if (isset($data['data']['inlinks']['nofollow'])) { |
|||
foreach ($data['data']['inlinks']['nofollow'] as $v) { |
|||
if ($v['status'] == 1) { |
|||
$success++; |
|||
} else { |
|||
$error++; |
|||
} |
|||
} |
|||
} |
|||
if (isset($data['data']['outlinks']['linksHave'])) { |
|||
foreach ($data['data']['outlinks']['linksHave'] as $v) { |
|||
if ($v['status'] == 1) { |
|||
$success++; |
|||
} else { |
|||
$error++; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
if ($isEnd) { |
|||
Db::name('seo_check_task')->where('id', $param['task_id'])->update([ |
|||
'status' => 2, |
|||
'update_time' => date('Y-m-d H:i:s') |
|||
]); |
|||
} |
|||
|
|||
return json(['code' => 0, 'data' => [ |
|||
'success' => $success, |
|||
'error' => $error, |
|||
'check_data' => $checkData, |
|||
'is_end' => $isEnd, |
|||
'task' => Db::name('seo_check_task')->where('id', $param['task_id'])->find() |
|||
], 'msg' => 'success']); |
|||
} |
|||
|
|||
$websiteId = input('param.website_id'); |
|||
$list = Db::name('theme')->field('lang,theme')->where('is_active', 1)->where('website_id', $websiteId)->select(); |
|||
|
|||
return jsonReturn(0, 'success', $list); |
|||
} |
|||
|
|||
public function start() |
|||
{ |
|||
if (request()->isPost()) { |
|||
|
|||
$param = input('post.'); |
|||
|
|||
$hasRun = Db::name('seo_check_task')->field('id')->where('website_id', $param['website_id'])->where('status', 1)->find(); |
|||
if (!empty($hasRun)) { |
|||
return jsonReturn(-1, lang('该站点正在检测中')); |
|||
} |
|||
|
|||
Db::startTrans(); |
|||
try { |
|||
|
|||
$taskId = Db::name('seo_check_task')->insertGetId([ |
|||
'website_id' => $param['website_id'], |
|||
'website_url' => $param['website_url'], |
|||
'lang' => $param['lang'], |
|||
'theme' => $param['theme'], |
|||
'status' => 1, |
|||
'create_time' => date('Y-m-d H:i:s') |
|||
]); |
|||
|
|||
$params = [ |
|||
[ |
|||
'task_id' => $taskId, |
|||
'status' => 1, |
|||
'code' => 'code', |
|||
'create_time' => date('Y-m-d H:i:s') |
|||
], |
|||
[ |
|||
'task_id' => $taskId, |
|||
'status' => 1, |
|||
'code' => 'web', |
|||
'create_time' => date('Y-m-d H:i:s') |
|||
], |
|||
[ |
|||
'task_id' => $taskId, |
|||
'status' => 1, |
|||
'code' => 'keywords', |
|||
'create_time' => date('Y-m-d H:i:s') |
|||
], |
|||
[ |
|||
'task_id' => $taskId, |
|||
'status' => 1, |
|||
'code' => 'links', |
|||
'create_time' => date('Y-m-d H:i:s') |
|||
], |
|||
[ |
|||
'task_id' => $taskId, |
|||
'status' => 1, |
|||
'code' => 'article', |
|||
'create_time' => date('Y-m-d H:i:s') |
|||
], |
|||
]; |
|||
|
|||
Db::name('seo_check_task_detail')->insertAll($params); |
|||
|
|||
Db::commit(); |
|||
} catch (\Exception $e) { |
|||
Db::rollback(); |
|||
return jsonReturn(-2, $e->getMessage()); |
|||
} |
|||
|
|||
$taskData = [ |
|||
'task_id' => $taskId, |
|||
'websiteId' => $param['website_id'], |
|||
'start_time' => date('Y-m-d H:i:s'), |
|||
'lang' => $param['lang'], |
|||
'theme' => $param['theme'], |
|||
'websiteUrl' => $param['website_url'], |
|||
'cate' => Db::name('category')->field('id,title,alias')->where('status', 1) |
|||
->where('lang', $param['lang']) |
|||
->where('type', '<>', 3)->where('website_id', $param['website_id'])->select(), |
|||
'keywords' => Db::name('keyword')->field('name')->where('is_del', 1)->where('website_id', $param['website_id'])->select() |
|||
]; |
|||
|
|||
// 以text协议发送$task_data数据
|
|||
$taskData['cmd'] = 'code'; |
|||
$this->sendData($taskData); |
|||
$taskData['cmd'] = 'web'; |
|||
$this->sendData($taskData); |
|||
$taskData['cmd'] = 'keywords'; |
|||
$this->sendData($taskData); |
|||
$taskData['cmd'] = 'links'; |
|||
$this->sendData($taskData); |
|||
$taskData['cmd'] = 'article'; |
|||
$this->sendData($taskData); |
|||
|
|||
return jsonReturn(0, lang('启动成功'), $taskData); |
|||
} |
|||
} |
|||
|
|||
public function del() |
|||
{ |
|||
|
|||
if (!request()->isPost()) { |
|||
return jsonReturn(-1, lang('请求错误')); |
|||
} |
|||
|
|||
$param = $this->request->only(['id']); |
|||
|
|||
Db::name('seo_check_task')->where('id', '=', $param['id'])->delete(); |
|||
Db::name('seo_check_task_detail')->where('task_id', '=', $param['id'])->delete(); |
|||
|
|||
return jsonReturn(0, lang('删除成功')); |
|||
} |
|||
|
|||
protected function sendData($data) |
|||
{ |
|||
// 与服务端建立连接
|
|||
$client = stream_socket_client('tcp://127.0.0.1:19890'); |
|||
fwrite($client, json_encode($data) . "\n"); |
|||
//关闭句柄
|
|||
fclose($client); |
|||
} |
|||
} |
|||
@ -0,0 +1,54 @@ |
|||
<?php |
|||
|
|||
namespace app\controller\backend; |
|||
|
|||
use app\model\BaiduTjGather; |
|||
use app\model\SeoAccount; |
|||
|
|||
class SeoController extends BaseController |
|||
{ |
|||
|
|||
public function baidu(SeoAccount $seoAccount, BaiduTjGather $baiduTjGather): \think\response\Json |
|||
{ |
|||
$account = $seoAccount->field('id,account')->where('type', 1)->where('status', 1)->select(); |
|||
$pvData = $baiduTjGather->getYesterdayData()['data']; |
|||
|
|||
if (empty($pvData)) { |
|||
$pvData = [ |
|||
'pv_count' => 0, |
|||
'uv_count' => 0, |
|||
'ip_count' => 0, |
|||
'avg_visit_time' => '00:00:00' |
|||
]; |
|||
} else { |
|||
|
|||
$pvData['avg_visit_time'] = $this->changeTimeType($pvData['avg_visit_time']); |
|||
} |
|||
|
|||
$data = [ |
|||
'account' => $account, |
|||
'pvData' => $pvData |
|||
]; |
|||
|
|||
return jsonReturn(0, lang('查询成功'), $data); |
|||
} |
|||
|
|||
|
|||
/** |
|||
* 计算时长 |
|||
* @param $seconds |
|||
* @return string |
|||
*/ |
|||
protected function changeTimeType($seconds): string |
|||
{ |
|||
if ($seconds > 3600) { |
|||
$hours = intval($seconds / 3600); |
|||
$minutes = $seconds % 3600; |
|||
$time = $hours . ":" . gmstrftime('%M:%S', $minutes); |
|||
} else { |
|||
$time = gmstrftime('%H:%M:%S', $seconds); |
|||
} |
|||
|
|||
return $time; |
|||
} |
|||
} |
|||
@ -0,0 +1,139 @@ |
|||
<?php |
|||
declare (strict_types = 1); |
|||
|
|||
namespace app\controller\backend; |
|||
|
|||
use app\model\SeoSetting; |
|||
use app\validate\SeoSettingValidate; |
|||
use think\exception\ValidateException; |
|||
use think\facade\Lang; |
|||
|
|||
|
|||
class SeoSettingController extends BaseController |
|||
{ |
|||
/** |
|||
* 显示资源列表 |
|||
* |
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function index(SeoSetting $seoSetting): \think\response\Json |
|||
{ |
|||
$where = [ |
|||
'seller_id' => $this->admin['seller_id'], |
|||
]; |
|||
$limit = 10; |
|||
$limitParam = (int)input('limit'); |
|||
if($limitParam){ |
|||
$limit = $limitParam; |
|||
} |
|||
// TODO
|
|||
// 添加其他逻辑
|
|||
|
|||
$seoSettingList = $seoSetting->getSeoSettingList($where,$limit); |
|||
return json(pageReturn($seoSettingList)); |
|||
} |
|||
|
|||
/** |
|||
* 保存新建的资源 |
|||
* |
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function save(SeoSetting $seoSetting): \think\response\Json |
|||
{ |
|||
if(request()->isPost()){ |
|||
$param = input('post.'); |
|||
$param['seller_id'] = $this->admin['seller_id']; |
|||
|
|||
// 数据验证
|
|||
try{ |
|||
validate(SeoSettingValidate::class)->scene('save')->check($param); |
|||
}catch(ValidateException $e){ |
|||
return jsonReturn(-1, $e->getError()); |
|||
} |
|||
// TODO
|
|||
// 其他逻辑
|
|||
|
|||
$res = $seoSetting -> addSeoSetting($param); |
|||
return json($res); |
|||
} |
|||
return jsonReturn(-3,Lang::get('请求方法错误')); |
|||
} |
|||
|
|||
/** |
|||
* 显示指定的资源 |
|||
* |
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
* @throws \app\exception\ModelEmptyException |
|||
*/ |
|||
public function read(SeoSetting $seoSetting): \think\response\Json |
|||
{ |
|||
|
|||
$id = (int)input('id'); |
|||
if(!$id){ |
|||
// TODO
|
|||
// 修改错误消息
|
|||
return jsonReturn(-1,'ErrorMsg'); |
|||
} |
|||
$where = [ |
|||
'id' => $id, |
|||
'seller_id' => $this->admin['seller_id'] |
|||
]; |
|||
// TODO
|
|||
// 其他逻辑
|
|||
$res = $seoSetting->getSeoSetting($where); |
|||
return json($res); |
|||
|
|||
} |
|||
|
|||
/** |
|||
* 保存更新的资源 |
|||
|
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function update(SeoSetting $seoSetting): \think\response\Json |
|||
{ |
|||
if(request()->isPost()){ |
|||
$param = input('post.'); |
|||
try { |
|||
validate(SeoSettingValidate::class)->scene('update')->check($param); |
|||
} catch (ValidateException $e) { |
|||
return jsonReturn(-1, $e->getError()); |
|||
} |
|||
$where = [ |
|||
'id' => $param['id'], |
|||
'seller_id' => $this->admin['seller_id'], |
|||
]; |
|||
$res = $seoSetting -> updateSeoSetting($where,$param); |
|||
return json($res); |
|||
} |
|||
return jsonReturn(-3,Lang::get('请求方法错误')); |
|||
} |
|||
|
|||
/** |
|||
* 删除指定资源 |
|||
* |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function delete(SeoSetting $seoSetting): \think\response\Json |
|||
{ |
|||
if(request()->isPost()){ |
|||
$id = (int)input('id'); |
|||
if(!$id){ |
|||
// TO DO
|
|||
// 替换错误提示
|
|||
return jsonReturn(-1,'ErrorMsg'); |
|||
} |
|||
$where = [ |
|||
'id' => $id, |
|||
'seller_id' => $this->admin['seller_id'] |
|||
]; |
|||
$res = $seoSetting->delSeoSetting($where); |
|||
return json($res); |
|||
} |
|||
return jsonReturn(-3,Lang::get('请求方法错误')); |
|||
} |
|||
} |
|||
@ -0,0 +1,46 @@ |
|||
<?php |
|||
declare (strict_types = 1); |
|||
|
|||
namespace app\controller\backend; |
|||
|
|||
|
|||
use app\model\Website; |
|||
use app\service\Sitemap; |
|||
use think\facade\Lang; |
|||
|
|||
|
|||
class SiteMapController extends BaseController |
|||
{ |
|||
/** |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function gen() { |
|||
$website_id = input('website_id'); |
|||
$where = [ |
|||
'seller_id' => $this->admin['seller_id'], |
|||
'website_id' => $website_id, |
|||
]; |
|||
|
|||
$sitemap = new Sitemap($where['seller_id'], $where['website_id']); |
|||
$sitemap->scan(); |
|||
$silian = $sitemap->siliamGen(); |
|||
|
|||
// 生成xml文件
|
|||
$path = $sitemap->sitemapGen(); |
|||
|
|||
|
|||
$websiteWhere = [ |
|||
'id' => $website_id |
|||
]; |
|||
$param = [ |
|||
'sitemap_url' => $path, |
|||
'silian_url' => $silian, |
|||
]; |
|||
|
|||
$website = new Website(); |
|||
$res = $website->updateWebsite($websiteWhere, $param); |
|||
|
|||
return jsonReturn($res['code'], Lang('生成成功'), $res['data']); |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,125 @@ |
|||
<?php |
|||
declare (strict_types = 1); |
|||
|
|||
namespace app\controller\backend; |
|||
|
|||
use app\model\SlideCate; |
|||
use app\validate\SlideCateValidate; |
|||
use think\exception\ValidateException; |
|||
use think\facade\Lang; |
|||
|
|||
|
|||
class SlideCateController extends BaseController |
|||
{ |
|||
/** |
|||
* 显示资源列表 |
|||
* |
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function index(SlideCate $slideCate): \think\response\Json |
|||
{ |
|||
$where = [ |
|||
'seller_id' => $this->admin['seller_id'], |
|||
]; |
|||
$limit = $this->setLimit(); |
|||
|
|||
$slideCateList = $slideCate->getSlideCateList($where,$limit); |
|||
return json(pageReturn($slideCateList)); |
|||
} |
|||
|
|||
/** |
|||
* 保存新建的资源 |
|||
* |
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function save(SlideCate $slideCate): \think\response\Json |
|||
{ |
|||
if(request()->isPost()){ |
|||
$param = input('post.'); |
|||
// 数据验证
|
|||
try{ |
|||
validate(SlideCateValidate::class)->scene('save')->check($param); |
|||
}catch(ValidateException $e){ |
|||
return jsonReturn(-1, $e->getError()); |
|||
} |
|||
|
|||
$res = $slideCate -> addSlideCate($param); |
|||
return json($res); |
|||
} |
|||
return jsonReturn(-3,Lang::get('请求方法错误')); |
|||
} |
|||
|
|||
/** |
|||
* 显示指定的资源 |
|||
* |
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
* @throws \app\exception\ModelEmptyException |
|||
*/ |
|||
public function read(SlideCate $slideCate): \think\response\Json |
|||
{ |
|||
|
|||
$id = (int)input('id'); |
|||
if(!$id){ |
|||
return jsonReturn(-1,Lang::get('分类ID不能为空')); |
|||
} |
|||
$where = [ |
|||
'id' => $id, |
|||
'seller_id' => $this->admin['seller_id'] |
|||
]; |
|||
// TODO
|
|||
// 其他逻辑
|
|||
$res = $slideCate->getSlideCate($where); |
|||
return json($res); |
|||
|
|||
} |
|||
|
|||
/** |
|||
* 保存更新的资源 |
|||
|
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function update(SlideCate $slideCate): \think\response\Json |
|||
{ |
|||
if(request()->isPost()){ |
|||
$param = input('post.'); |
|||
try { |
|||
validate(SlideCateValidate::class)->scene('update')->check($param); |
|||
} catch (ValidateException $e) { |
|||
return jsonReturn(-1, $e->getError()); |
|||
} |
|||
$where = [ |
|||
'id' => $param['id'], |
|||
'seller_id' => $this->admin['seller_id'], |
|||
]; |
|||
$res = $slideCate -> updateSlideCate($where,$param); |
|||
return json($res); |
|||
} |
|||
return jsonReturn(-3,Lang::get('请求方法错误')); |
|||
} |
|||
|
|||
/** |
|||
* 删除指定资源 |
|||
* |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function delete(SlideCate $slideCate): \think\response\Json |
|||
{ |
|||
if(request()->isPost()){ |
|||
$id = (int)input('id'); |
|||
if(!$id){ |
|||
return jsonReturn(-1,Lang::get('分类ID不能为空')); |
|||
} |
|||
$where = [ |
|||
'id' => $id, |
|||
'seller_id' => $this->admin['seller_id'] |
|||
]; |
|||
$res = $slideCate->delSlideCate($where); |
|||
return json($res); |
|||
} |
|||
return jsonReturn(-3,Lang::get('请求方法错误')); |
|||
} |
|||
} |
|||
@ -0,0 +1,134 @@ |
|||
<?php |
|||
declare (strict_types = 1); |
|||
|
|||
namespace app\controller\backend; |
|||
|
|||
use app\model\Slide; |
|||
use app\service\CacheService; |
|||
use app\validate\SlideValidate; |
|||
use think\exception\ValidateException; |
|||
use think\facade\Lang; |
|||
|
|||
|
|||
class SlideController extends BaseController |
|||
{ |
|||
/** |
|||
* 显示资源列表 |
|||
* |
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function index(Slide $slide): \think\response\Json |
|||
{ |
|||
$where = [ |
|||
'seller_id' => $this->admin['seller_id'], |
|||
'slide_cate_id' => (int)input('slide_cate_id'), |
|||
]; |
|||
$slideList = $slide->getAllCustomArrayData($where,'sort desc','*',['attachment'=>function($q){ |
|||
$q->field('id,name,url,type'); |
|||
}]); |
|||
return json($slideList); |
|||
} |
|||
|
|||
/** |
|||
* 保存新建的资源 |
|||
* |
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
* @throws \ReflectionException |
|||
*/ |
|||
public function save(Slide $slide): \think\response\Json |
|||
{ |
|||
if(request()->isPost()){ |
|||
$param = input('post.'); |
|||
// 数据验证
|
|||
try{ |
|||
validate(SlideValidate::class)->scene('save')->check($param); |
|||
}catch(ValidateException $e){ |
|||
return jsonReturn(-1, $e->getError()); |
|||
} |
|||
|
|||
$res = $slide -> addSlide($param); |
|||
CacheService::deleteRelationCacheByObject($slide); |
|||
return json($res); |
|||
} |
|||
return jsonReturn(-3,Lang::get('请求方法错误')); |
|||
} |
|||
|
|||
/** |
|||
* 显示指定的资源 |
|||
* |
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
* @throws \app\exception\ModelEmptyException |
|||
*/ |
|||
public function read(Slide $slide): \think\response\Json |
|||
{ |
|||
|
|||
$id = (int)input('id'); |
|||
if(!$id){ |
|||
return jsonReturn(-1,Lang::get('幻灯片ID')); |
|||
} |
|||
$where = [ |
|||
'id' => $id, |
|||
'seller_id' => $this->admin['seller_id'] |
|||
]; |
|||
// 其他逻辑
|
|||
$res = $slide->getSlide($where,['attachment'=>function($q){ |
|||
$q->field('id,name,url,type'); |
|||
}]); |
|||
return json($res); |
|||
|
|||
} |
|||
|
|||
/** |
|||
* 保存更新的资源 |
|||
|
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
*@throws \ReflectionException |
|||
*/ |
|||
public function update(Slide $slide): \think\response\Json |
|||
{ |
|||
if(request()->isPost()){ |
|||
$param = input('post.'); |
|||
try { |
|||
validate(SlideValidate::class)->scene('update')->check($param); |
|||
} catch (ValidateException $e) { |
|||
return jsonReturn(-1, $e->getError()); |
|||
} |
|||
$where = [ |
|||
'id' => $param['id'], |
|||
'seller_id' => $this->admin['seller_id'], |
|||
]; |
|||
$res = $slide -> updateSlide($where,$param); |
|||
CacheService::deleteRelationCacheByObject($slide); |
|||
return json($res); |
|||
} |
|||
return jsonReturn(-3,Lang::get('请求方法错误')); |
|||
} |
|||
|
|||
/** |
|||
* 删除指定资源 |
|||
* |
|||
* @throws \app\exception\ModelException |
|||
* @throws \ReflectionException |
|||
*/ |
|||
public function delete(Slide $slide): \think\response\Json |
|||
{ |
|||
if(request()->isPost()){ |
|||
$id = (int)input('id'); |
|||
if(!$id){ |
|||
return jsonReturn(-1,Lang::get('幻灯片ID')); |
|||
} |
|||
$where = [ |
|||
'id' => $id, |
|||
'seller_id' => $this->admin['seller_id'] |
|||
]; |
|||
$res = $slide->delSlide($where); |
|||
CacheService::deleteRelationCacheByObject($slide); |
|||
return json($res); |
|||
} |
|||
return jsonReturn(-3,Lang::get('请求方法错误')); |
|||
} |
|||
} |
|||
@ -0,0 +1,139 @@ |
|||
<?php |
|||
declare (strict_types = 1); |
|||
|
|||
namespace app\controller\backend; |
|||
|
|||
use app\model\SocialMarketing; |
|||
use app\validate\SocialMarketingValidate; |
|||
use think\exception\ValidateException; |
|||
use think\facade\Lang; |
|||
|
|||
|
|||
class SocialMarketingController extends BaseController |
|||
{ |
|||
/** |
|||
* 显示资源列表 |
|||
* |
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function index(SocialMarketing $socialMarketing): \think\response\Json |
|||
{ |
|||
$where = [ |
|||
'seller_id' => $this->admin['seller_id'], |
|||
]; |
|||
$limit = 10; |
|||
$limitParam = (int)input('limit'); |
|||
if($limitParam){ |
|||
$limit = $limitParam; |
|||
} |
|||
// TODO
|
|||
// 添加其他逻辑
|
|||
|
|||
$socialMarketingList = $socialMarketing->getSocialMarketingList($where,$limit); |
|||
return json(pageReturn($socialMarketingList)); |
|||
} |
|||
|
|||
/** |
|||
* 保存新建的资源 |
|||
* |
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function save(SocialMarketing $socialMarketing): \think\response\Json |
|||
{ |
|||
if(request()->isPost()){ |
|||
$param = input('post.'); |
|||
$param['seller_id'] = $this->admin['seller_id']; |
|||
|
|||
// 数据验证
|
|||
try{ |
|||
validate(SocialMarketingValidate::class)->scene('save')->check($param); |
|||
}catch(ValidateException $e){ |
|||
return jsonReturn(-1, $e->getError()); |
|||
} |
|||
// TODO
|
|||
// 其他逻辑
|
|||
|
|||
$res = $socialMarketing -> addSocialMarketing($param); |
|||
return json($res); |
|||
} |
|||
return jsonReturn(-3,Lang::get('请求方法错误')); |
|||
} |
|||
|
|||
/** |
|||
* 显示指定的资源 |
|||
* |
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
* @throws \app\exception\ModelEmptyException |
|||
*/ |
|||
public function read(SocialMarketing $socialMarketing): \think\response\Json |
|||
{ |
|||
|
|||
$id = (int)input('id'); |
|||
if(!$id){ |
|||
// TODO
|
|||
// 修改错误消息
|
|||
return jsonReturn(-1,'ErrorMsg'); |
|||
} |
|||
$where = [ |
|||
'id' => $id, |
|||
'seller_id' => $this->admin['seller_id'] |
|||
]; |
|||
// TODO
|
|||
// 其他逻辑
|
|||
$res = $socialMarketing->getSocialMarketing($where); |
|||
return json($res); |
|||
|
|||
} |
|||
|
|||
/** |
|||
* 保存更新的资源 |
|||
|
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function update(SocialMarketing $socialMarketing): \think\response\Json |
|||
{ |
|||
if(request()->isPost()){ |
|||
$param = input('post.'); |
|||
try { |
|||
validate(SocialMarketingValidate::class)->scene('update')->check($param); |
|||
} catch (ValidateException $e) { |
|||
return jsonReturn(-1, $e->getError()); |
|||
} |
|||
$where = [ |
|||
'id' => $param['id'], |
|||
'seller_id' => $this->admin['seller_id'], |
|||
]; |
|||
$res = $socialMarketing -> updateSocialMarketing($where,$param); |
|||
return json($res); |
|||
} |
|||
return jsonReturn(-3,Lang::get('请求方法错误')); |
|||
} |
|||
|
|||
/** |
|||
* 删除指定资源 |
|||
* |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function delete(SocialMarketing $socialMarketing): \think\response\Json |
|||
{ |
|||
if(request()->isPost()){ |
|||
$id = (int)input('id'); |
|||
if(!$id){ |
|||
// TO DO
|
|||
// 替换错误提示
|
|||
return jsonReturn(-1,'ErrorMsg'); |
|||
} |
|||
$where = [ |
|||
'id' => $id, |
|||
'seller_id' => $this->admin['seller_id'] |
|||
]; |
|||
$res = $socialMarketing->delSocialMarketing($where); |
|||
return json($res); |
|||
} |
|||
return jsonReturn(-3,Lang::get('请求方法错误')); |
|||
} |
|||
} |
|||
@ -0,0 +1,45 @@ |
|||
<?php |
|||
|
|||
namespace app\controller\backend; |
|||
|
|||
use app\service\StaticFileService; |
|||
|
|||
class StaticFileController extends BaseController |
|||
{ |
|||
|
|||
public function updateCategoryCache() |
|||
{ |
|||
$param = $this->request->only(['site_id', 'lang']); |
|||
|
|||
$param['admin'] = $this->admin; |
|||
|
|||
$staticService = new StaticFileService(); |
|||
$res = $staticService->updateCategoryCache($param); |
|||
|
|||
return json($res); |
|||
} |
|||
|
|||
public function createCategory() |
|||
{ |
|||
$param = $this->request->only(['site_id', 'lang', 'category_id' => 0, 'has_child']); |
|||
$param['admin'] = $this->admin; |
|||
$param['category_id'] = $param['category_id'] ?? 0; |
|||
|
|||
$staticService = new StaticFileService(); |
|||
$res = $staticService->createCategory($param['category_id'], $param, $param['has_child']); |
|||
|
|||
return json($res); |
|||
} |
|||
|
|||
public function createContent() |
|||
{ |
|||
$param = $this->request->only(['site_id', 'lang', 'category_id' => 0]); |
|||
$param['admin'] = $this->admin; |
|||
$param['category_id'] = $param['category_id'] ?? 0; |
|||
|
|||
$staticService = new StaticFileService(); |
|||
$res = $staticService->createContent($param['category_id'], $param); |
|||
|
|||
return json($res); |
|||
} |
|||
} |
|||
@ -0,0 +1,617 @@ |
|||
<?php |
|||
|
|||
namespace app\controller\backend; |
|||
|
|||
use app\exception\BadSysSettingException; |
|||
use app\model\BaiduTjGather; |
|||
use app\model\SeoAccount; |
|||
use app\model\SysSetting; |
|||
use app\model\Visit; |
|||
use app\model\VisitLog; |
|||
use app\model\Website; |
|||
use think\facade\Lang; |
|||
|
|||
class StatisticsController extends BaseController |
|||
{ |
|||
public $header = ''; |
|||
public $url = 'http://api.baidu.com/json/tongji/v1/ReportService/getData'; |
|||
protected $baiduInfo; |
|||
private $site_id = 0; |
|||
|
|||
/** |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function setConfig() |
|||
{ |
|||
$id = input('param.id') ?? 0; |
|||
if (!empty($id)) { |
|||
|
|||
$info = (new SeoAccount())->where('id', $id)->find(); |
|||
$this->baiduInfo = [ |
|||
'account_type' => '1', |
|||
'username' => $info['account'], |
|||
'password' => $info['password'], |
|||
'token' => $info['token'], |
|||
]; |
|||
} else { |
|||
$this->baiduInfo = null; |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* @throws \app\exception\ModelException |
|||
* @throws BadSysSettingException |
|||
*/ |
|||
public function initialize() |
|||
{ |
|||
parent::initialize(); |
|||
} |
|||
|
|||
/** |
|||
* @throws BadSysSettingException |
|||
*/ |
|||
public function baiduErrorReturn($response) |
|||
{ |
|||
if(!empty($response['header']['failures'])){ |
|||
throw new BadSysSettingException($response['header']['failures'][0]['message']); |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* @throws BadSysSettingException |
|||
*/ |
|||
public function getResponse($data) |
|||
{ |
|||
$data = json_encode(['body'=>$data, "header"=>$this->header]); |
|||
$response = $this->https_request($this->url, $data); |
|||
$response = json_decode($response,true); |
|||
$this->baiduErrorReturn($response); |
|||
return $response; |
|||
} |
|||
|
|||
/** |
|||
* @throws BadSysSettingException |
|||
*/ |
|||
public function lists(): \think\response\Json |
|||
{ |
|||
$url = 'https://api.baidu.com/json/tongji/v1/ReportService/getSiteList'; |
|||
$data = json_encode(["header"=>$this->header]); |
|||
$response = $this->https_request($url, $data); |
|||
$response = json_decode($response, true); |
|||
$this->baiduErrorReturn($response); |
|||
return jsonReturn(0, Lang::get('查询成功'), $response['body']['data']['0']['list']); |
|||
} |
|||
|
|||
public function indexLists() |
|||
{ |
|||
$websiteModel = new Website(); |
|||
$list = $websiteModel->field('*, id as site_id, domain')->select(); |
|||
return jsonReturn(0, Lang::get('查询成功'), $list); |
|||
} |
|||
|
|||
// 首页趋势图
|
|||
public function indexQST() |
|||
{ |
|||
ini_set('memory_limit', '512M'); |
|||
|
|||
$websiteId = $this->request->request('website_id')?$this->request->request('website_id'):1; |
|||
$type = $this->request->request('type')?$this->request->request('type'):1; |
|||
|
|||
$nowDay = date('Y-m-d'); |
|||
// 今天
|
|||
$startTime = strtotime($nowDay); |
|||
$endTime = strtotime(date('Y-m-d', strtotime('+1 day'))); |
|||
if ($type==2) { // 昨天
|
|||
$startTime = strtotime(date('Y-m-d', strtotime('-1 day'))); |
|||
$endTime = strtotime($nowDay) - 1; |
|||
} elseif ($type==3) { // 最近7天
|
|||
$startTime = strtotime(date('Y-m-d', strtotime('-6 day'))); |
|||
$endTime = strtotime(date('Y-m-d', strtotime('+1 day'))); |
|||
} elseif ($type==4) { // 最近30天
|
|||
$startTime = strtotime(date('Y-m-d', strtotime('-29 day'))); |
|||
$endTime = strtotime(date('Y-m-d', strtotime('+1 day'))); |
|||
} |
|||
|
|||
$visitModel = new VisitLog(); |
|||
|
|||
$list = $visitModel->where([ |
|||
['create_time', '>=', $startTime], |
|||
['create_time', '<=', $endTime], |
|||
['website_id', '=', $websiteId], |
|||
])->select()->toArray(); |
|||
|
|||
$newList = []; |
|||
|
|||
if ($type == 1 || $type == 2) { |
|||
$maxH = 23; |
|||
if ($type == 1) { |
|||
$maxH = date('H'); |
|||
} |
|||
|
|||
for ($i = 0; $i <= $maxH; $i++) { |
|||
if ($i < 10) { |
|||
$i = '0' . $i; |
|||
} |
|||
$i = (string)$i; |
|||
|
|||
$newList[$i] = 0; |
|||
} |
|||
} else { |
|||
for ($i = $startTime; $i <= $endTime;) { |
|||
$dateStr = date('Y-m-d', $i); |
|||
$newList[$dateStr] = 0; |
|||
$i += 86400; |
|||
} |
|||
} |
|||
|
|||
$type1List = $type2List = $type3List = $newList; |
|||
|
|||
$type2Unique = []; // 校验唯一
|
|||
$type3Unique = []; // 校验唯一
|
|||
|
|||
// type 为1和2,时间间隔为小时。否则为天
|
|||
foreach ($list as $value) { |
|||
if ($type == 1 || $type == 2) { |
|||
$key = date('H', strtotime($value['create_time'])); |
|||
} else { |
|||
$key = date('Y-m-d', strtotime($value['create_time'])); |
|||
} |
|||
$type1List[$key] ++; |
|||
if (!isset($type2Unique[$key][$value['agent']])) { |
|||
$type2Unique[$key][$value['agent']] = 1; |
|||
$type2List[$key] ++; |
|||
} |
|||
if (!isset($type3Unique[$key][$value['ip']])) { |
|||
$type3Unique[$key][$value['ip']] = 1; |
|||
$type3List[$key] ++; |
|||
} |
|||
} |
|||
|
|||
$returnData['pv_list'] = array_values($type1List); |
|||
$returnData['uv_list'] = array_values($type2List); |
|||
$returnData['ip_list'] = array_values($type3List); |
|||
$returnData['time'] = array_keys($type1List); |
|||
foreach ($returnData['time'] as &$value) { |
|||
$value = (string)$value; |
|||
} |
|||
|
|||
return jsonReturn(0, Lang::get('查询成功'), $returnData); |
|||
} |
|||
|
|||
// 首页地区分布图
|
|||
public function indexArea() |
|||
{ |
|||
$websiteId = $this->request->request('website_id')?$this->request->request('website_id'):1; |
|||
$type = $this->request->request('type')?$this->request->request('type'):1; |
|||
|
|||
$nowDay = date('Y-m-d'); |
|||
// 今天
|
|||
$startTime = strtotime($nowDay); |
|||
$endTime = strtotime(date('Y-m-d', strtotime('+1 day'))); |
|||
if ($type==2) { // 昨天
|
|||
$startTime = strtotime(date('Y-m-d', strtotime('-1 day'))); |
|||
$endTime = strtotime($nowDay) - 1; |
|||
} elseif ($type==3) { // 最近7天
|
|||
$startTime = strtotime(date('Y-m-d', strtotime('-6 day'))); |
|||
$endTime = strtotime(date('Y-m-d', strtotime('+1 day'))); |
|||
} elseif ($type==4) { // 最近30天
|
|||
$startTime = strtotime(date('Y-m-d', strtotime('-29 day'))); |
|||
$endTime = strtotime(date('Y-m-d', strtotime('+1 day'))); |
|||
} |
|||
|
|||
$visitModel = new VisitLog(); |
|||
|
|||
$list = $visitModel->where([ |
|||
['create_time', '>=', $startTime], |
|||
['create_time', '<=', $endTime], |
|||
['website_id', '=', $websiteId], |
|||
['visited_area', '<>', '内网ip'], |
|||
])->select()->toArray(); |
|||
|
|||
$total = count($list); |
|||
$newData = []; |
|||
foreach ($list as $value) { |
|||
$areaArr = explode('-', $value['visited_area']); |
|||
$province = $areaArr[0]; |
|||
if (!isset($newData[$province])) { |
|||
$newData[$province] = [ |
|||
'name' => $province, |
|||
'value' => 1, |
|||
'pv_ratio' => bcmul(1 / $total, 100, 2), |
|||
]; |
|||
} else { |
|||
$newData[$province]['value']++; |
|||
$newData[$province]['pv_ratio'] = bcmul($newData[$province]['value']/$total, 100, 2); |
|||
} |
|||
} |
|||
|
|||
return jsonReturn(0, Lang::get('查询成功'), array_values($newData)); |
|||
} |
|||
|
|||
/** |
|||
* 访客年龄分布 |
|||
* @return false|string|\think\response\Json |
|||
* @throws BadSysSettingException |
|||
*/ |
|||
public function age() |
|||
{ |
|||
$data = [ |
|||
"site_id"=> $this->request->param('site_id') ? $this->request->param('site_id') : $this->site_id, |
|||
"method" => "overview/getAge" |
|||
]; |
|||
$response = $this->getResponse($data); |
|||
$response = $response['body']['data']['0']['result']; |
|||
return jsonReturn(0, '查询成功', $response); |
|||
} |
|||
|
|||
/** |
|||
* 今日昨日浏览量分析 |
|||
* @throws BadSysSettingException |
|||
*/ |
|||
public function outline(): \think\response\Json |
|||
{ |
|||
$data = [ |
|||
"site_id"=> $this->request->param('site_id')?$this->request->param('site_id'):$this->site_id, |
|||
"method" => "overview/getOutline" |
|||
]; |
|||
$response = $this->getResponse($data); |
|||
$response = $response['body']['data']['0']['result']; |
|||
foreach ($response['items'] as $key => $value) { |
|||
if(is_numeric($value[5]) && $value[5] != '--'){ |
|||
$response['items'][$key][5] = $this->secToTime($value[5]); |
|||
}elseif(is_array($value[5]) && $value[5]['val'] != '--'){ |
|||
$response['items'][$key][5]['val'] = $this->secToTime($value[5]['val']); |
|||
} |
|||
} |
|||
return jsonReturn(0, Lang::get('查询成功'),$response); |
|||
} |
|||
|
|||
/** |
|||
* 趋势图 |
|||
* pv_count (浏览量PV) |
|||
* visitor_count (访客数UV) |
|||
* ip_count (IP 数) |
|||
* bounce_ratio (跳出率,%) |
|||
* avg_visit_time (平均访问时长,秒) |
|||
* trans_count (转化次数) |
|||
* @throws BadSysSettingException |
|||
*/ |
|||
public function qxt() |
|||
{ |
|||
$type = $this->request->request('type')?$this->request->request('type'):1; |
|||
$contrast = $this->request->request('contrast')?$this->request->request('contrast'):1; |
|||
$metrics = $this->request->request('metrics')?$this->request->request('metrics'):'pv_count'; |
|||
switch ($metrics) { |
|||
case 'visitor_count': |
|||
$name = Lang::get('访客数(UV)'); |
|||
break; |
|||
case 'ip_count': |
|||
$name = Lang::get('IP数'); |
|||
break; |
|||
case 'bounce_ratio': |
|||
$name = Lang::get('跳出率'); |
|||
break; |
|||
case 'avg_visit_time': |
|||
$name = Lang::get('平均访问时长'); |
|||
break; |
|||
case 'trans_count': |
|||
$name = Lang::get('转化次数'); |
|||
break; |
|||
default: |
|||
$name = Lang::get('浏览量(PV)'); |
|||
break; |
|||
} |
|||
$et = date('Ymd', time()); |
|||
if($type==1){ |
|||
$st = date('Ymd', time()); |
|||
if($contrast==1){ |
|||
$start_date2 = date('Ymd', time()-(3600*24)); |
|||
$end_date2 = date('Ymd', time()-(3600*24)); |
|||
}elseif($contrast==2){ |
|||
$start_date2 = date('Ymd', time()-(3600*24*7)); |
|||
$end_date2 = date('Ymd', time()-(3600*24*7)); |
|||
} |
|||
}elseif ($type==2) { |
|||
$st = date('Ymd', strtotime('-1 day')); |
|||
$et = date('Ymd', strtotime('-1 day')); |
|||
if($contrast==1){ |
|||
$start_date2 = date('Ymd', strtotime('-1 day')-(3600*24)); |
|||
$end_date2 = date('Ymd', strtotime('-1 day')-(3600*24)); |
|||
}elseif($contrast==2){ |
|||
$start_date2 = date('Ymd', time()-(3600*24*7)); |
|||
$end_date2 = date('Ymd', time()-(3600*24*7)); |
|||
} |
|||
}elseif ($type==3) { |
|||
$st = date('Ymd', strtotime('-6 day')); |
|||
}elseif ($type==4) { |
|||
$st = date('Ymd', strtotime('-29 day')); |
|||
} |
|||
if($contrast && ($type == 1 or $type == 2)){ |
|||
$data = [ |
|||
"site_id"=> $this->request->param('site_id')?$this->request->param('site_id'):$this->site_id, |
|||
"start_date" => $st, |
|||
"end_date" => $et, |
|||
"start_date2" => $start_date2, |
|||
"end_date2" => $end_date2, |
|||
"metrics" => $metrics, |
|||
"method" => "overview/getTimeTrendRpt" |
|||
]; |
|||
}else{ |
|||
$data = [ |
|||
"site_id"=> $this->request->param('site_id')?$this->request->param('site_id'):$this->site_id, |
|||
"start_date" => $st, |
|||
"end_date" => $et, |
|||
"metrics" => $metrics, |
|||
"method" => "overview/getTimeTrendRpt" |
|||
]; |
|||
} |
|||
$response = $this->getResponse($data); |
|||
$result = $response['body']['data']['0']['result']['items']; |
|||
|
|||
$new = []; |
|||
$new[0] = $result[1]; |
|||
$new[1] = $result[2]; |
|||
if($metrics != 'avg_visit_time'){ |
|||
foreach ($new as $key => $value) { |
|||
foreach ($value as $k => $v) { |
|||
$count = count($value); |
|||
if($type == 3 || $type == 4){ |
|||
$new[$key][$k][0] = date('Y/m/d', strtotime('-'.($count-$k-1).' day')); |
|||
$new[$key][$k][1] = $v[0]; |
|||
} |
|||
if($k<=10){ |
|||
array_push($new[$key][$k], $k.':00-'.$k.':59'); |
|||
}else{ |
|||
array_push($new[$key][$k], $k.':00-'.$k.':59'); |
|||
} |
|||
} |
|||
} |
|||
}else{ |
|||
if($type == 3 || $type ==4){ |
|||
$anew = []; |
|||
$anew[0] = $result[1]; |
|||
foreach ($anew as $key => $value) { |
|||
foreach ($value as $k => $v) { |
|||
$count = count($value); |
|||
$anew[$key][$k][0] = date('Y/m/d', strtotime('-'.($count-$k-1).' day')); |
|||
$anew[$key][$k][1] = $v[0]; |
|||
if($k<=10){ |
|||
array_push($anew[$key][$k], $k.':00-'.$k.':59'); |
|||
}else{ |
|||
array_push($anew[$key][$k], $k.':00-'.$k.':59'); |
|||
} |
|||
array_push($anew[$key][$k],$this->secToTime($v[0])); |
|||
} |
|||
} |
|||
return json_encode(['code'=>0, 'msg'=> Lang::get('查询成功'),'name'=>$name,'data'=>$anew]); |
|||
}else{ |
|||
foreach ($new as $key => $value) { |
|||
foreach ($value as $k => $v) { |
|||
if($k<=10){ |
|||
array_push($new[$key][$k], $k.':00-'.$k.':59'); |
|||
}else{ |
|||
array_push($new[$key][$k], $k.':00-'.$k.':59'); |
|||
} |
|||
array_push($new[$key][$k],$this->secToTime($v[1])); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
return jsonReturn(0, Lang::get('查询成功'),['name'=>$name,'data'=>$new]); |
|||
} |
|||
|
|||
// /**
|
|||
// * 关键词消费排名
|
|||
// * @throws BadSysSettingException
|
|||
// */
|
|||
// public function search_word()
|
|||
// {
|
|||
// $type = $this->request->request('type')?$this->request->request('type'):1;
|
|||
// $se = $this->getSTAndET($type);
|
|||
// $data = [
|
|||
// "site_id"=> $this->request->param('site_id')?$this->request->param('site_id'):$this->site_id,
|
|||
// "start_date" => $se['st'],
|
|||
// "end_date" => $se['st'],
|
|||
// "metrics" => "pv_count,visit_count,visitor_count",
|
|||
// "method" => "overview/getWord"
|
|||
// ];
|
|||
// $response = $this->getResponse($data);
|
|||
// $response = $response['body']['data']['0']['result'];
|
|||
// return jsonReturn(0, '查询成功',$response);
|
|||
// }
|
|||
|
|||
/** |
|||
* Top10搜索词 |
|||
* @throws BadSysSettingException |
|||
*/ |
|||
public function search_word() |
|||
{ |
|||
$type = $this->request->request('type')?$this->request->request('type'):1; |
|||
$se = $this->getSTAndET($type); |
|||
$data = [ |
|||
"site_id"=> $this->request->param('site_id')?$this->request->param('site_id'):$this->site_id, |
|||
"start_date" => $se['st'], |
|||
"end_date" => $se['st'], |
|||
"metrics" => "pv_count,pv_ratio", |
|||
"method" => "source/searchword/a" |
|||
]; |
|||
$response = $this->getResponse($data); |
|||
$response = $response['body']['data']['0']['result']; |
|||
|
|||
$list = $response['items'][0] ?? []; |
|||
|
|||
if (count($list) > 10) { |
|||
$list = array_slice($list, 0, 10); |
|||
$response['items'][0] = $list; |
|||
} |
|||
return jsonReturn(0, Lang::get('查询成功'),$response); |
|||
} |
|||
|
|||
|
|||
|
|||
public function https_request($url,$data) |
|||
{ |
|||
// 初始化
|
|||
$curl = curl_init(); |
|||
// 设置
|
|||
curl_setopt($curl,CURLOPT_URL,$url); |
|||
// 检查ssl证书
|
|||
curl_setopt($curl,CURLOPT_SSL_VERIFYPEER,FALSE); |
|||
// 从检查本地证书检查是否ssl加密
|
|||
curl_setopt($curl,CURLOPT_SSL_VERIFYHOST,$url); |
|||
// 判断$data 判断是否post
|
|||
if ( !empty($data) ) { |
|||
curl_setopt($curl,CURLOPT_POST,1);// 开启post
|
|||
curl_setopt($curl,CURLOPT_POSTFIELDS,$data);// 发送post $data
|
|||
} |
|||
// 返回结果 是文件流的方式返回
|
|||
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); |
|||
$response = curl_exec($curl); |
|||
$err = curl_error($curl); |
|||
curl_close($curl); |
|||
if($err){ |
|||
return false; |
|||
}else{ |
|||
return $response; |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 网站概况(来源网站、搜索词、入口页面、受访页面、新老访客) |
|||
* @throws BadSysSettingException |
|||
*/ |
|||
public function get_common_track_rpt(): \think\response\Json |
|||
{ |
|||
$type = $this->request->request('type') ? $this->request->request('type') : 1; |
|||
$se = $this->getSTAndET($type); |
|||
$data = [ |
|||
"site_id"=> $this->request->param('site_id')?$this->request->param('site_id'):$this->site_id, |
|||
"start_date" => $se['st'], |
|||
"end_date" => $se['et'], |
|||
"method" => "overview/getCommonTrackRpt" |
|||
]; |
|||
$response = $this->getResponse($data); |
|||
$response = $response['body']['data']['0']['result']; |
|||
foreach ($response['visitType'] as $key => $value) { |
|||
$response['visitType'][$key]['avg_visit_time'] = $this->secToTime($value['avg_visit_time']); |
|||
} |
|||
return jsonReturn(0, Lang::get('查询成功'), $response); |
|||
} |
|||
|
|||
/** |
|||
* 网站概况(地域分布) |
|||
* @throws BadSysSettingException |
|||
*/ |
|||
public function area() |
|||
{ |
|||
$type = $this->request->request('type')?$this->request->request('type'):2; |
|||
$se = $this->getSTAndET($type); |
|||
$data = [ |
|||
"site_id"=> $this->request->param('site_id')?$this->request->param('site_id'):$this->site_id, |
|||
"start_date" => $se['st'], |
|||
"end_date" => $se['et'], |
|||
"metrics"=> "pv_count,pv_ratio", |
|||
"method" => "visit/district/a" |
|||
]; |
|||
$response = $this->getResponse($data); |
|||
$response = $response['body']['data']['0']['result']; |
|||
$new = []; |
|||
foreach ($response['items'][0] as $key => $value) { |
|||
$new[$key]['name'] = $value[0]['name']; |
|||
$new[$key]['area'] = $value[0]['area']; |
|||
} |
|||
foreach ($response['items'][1] as $key => $value) { |
|||
$new[$key]['pv_count'] = $value[0]; |
|||
$new[$key]['pv_ratio'] = $value[1]; |
|||
} |
|||
return jsonReturn(0, Lang::get('查询成功'),$new); |
|||
} |
|||
|
|||
/** |
|||
* |
|||
* 网站概况(地域分布Top10) |
|||
* |
|||
* @throws BadSysSettingException |
|||
*/ |
|||
public function area_top(): \think\response\Json |
|||
{ |
|||
$type = $this->request->request('type')?$this->request->request('type'):2; |
|||
$se = $this->getSTAndET($type); |
|||
$data = [ |
|||
"site_id"=> $this->request->param('site_id')?$this->request->param('site_id'):$this->site_id, |
|||
"start_date" => $se['st'], |
|||
"end_date" => $se['et'], |
|||
"metrics"=> "pv_count,pv_ratio", |
|||
"method" => "visit/district/a" |
|||
]; |
|||
|
|||
$response = $this->getResponse($data); |
|||
$response = $response['body']['data']['0']['result']; |
|||
$new = []; |
|||
foreach ($response['items'][0] as $key => $value) { |
|||
$new[$key]['name'] = $value[0]['name']; |
|||
$new[$key]['area'] = $value[0]['area']; |
|||
} |
|||
foreach ($response['items'][1] as $key => $value) { |
|||
$new[$key]['pv_count'] = $value[0]; |
|||
$new[$key]['pv_ratio'] = $value[1]; |
|||
} |
|||
$new = array_slice($new, 0, 10); |
|||
return jsonReturn(0, Lang::get('查询成功'), $new); |
|||
} |
|||
|
|||
public function http_request($url,$data) |
|||
{ |
|||
// 初始化
|
|||
$curl = curl_init(); |
|||
// 设置
|
|||
curl_setopt($curl,CURLOPT_URL,$url); |
|||
// 检查ssl证书
|
|||
curl_setopt($curl,CURLOPT_SSL_VERIFYPEER,FALSE); |
|||
// 从检查本地证书检查是否ssl加密
|
|||
curl_setopt($curl,CURLOPT_SSL_VERIFYHOST,$url); |
|||
// 判断$data 判断是否post
|
|||
if ( !empty($data) ) { |
|||
curl_setopt($curl,CURLOPT_POST,1);// 开启post
|
|||
curl_setopt($curl,CURLOPT_POSTFIELDS,$data);// 发送post $data
|
|||
} |
|||
// 返回结果 是文件流的方式返回
|
|||
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); |
|||
$response = curl_exec($curl); |
|||
|
|||
$err = curl_error($curl); |
|||
curl_close($curl); |
|||
return $response; |
|||
} |
|||
|
|||
// 获取开始日期和结束日期
|
|||
public function getSTAndET($type): array |
|||
{ |
|||
$et = date('Ymd', time()); |
|||
if($type==1){ |
|||
$st = date('Ymd', time()); |
|||
}elseif ($type==2) { |
|||
$st = date('Ymd', strtotime('-1 day')); |
|||
$et = date('Ymd', strtotime('-1 day')); |
|||
}elseif ($type==3) { |
|||
$st = date('Ymd', strtotime('-6 day')); |
|||
}else { |
|||
$st = date('Ymd', strtotime('-29 day')); |
|||
} |
|||
return ['st' => $st,'et'=>$et]; |
|||
} |
|||
|
|||
public function secToTime($sec) |
|||
{ |
|||
|
|||
if (is_numeric($sec)) { |
|||
$strSecond = gmstrftime('%H:%M:%S', $sec); |
|||
} else { |
|||
$strSecond = $sec; |
|||
} |
|||
|
|||
return $strSecond; |
|||
} |
|||
|
|||
|
|||
} |
|||
@ -0,0 +1,180 @@ |
|||
<?php |
|||
declare (strict_types = 1); |
|||
|
|||
namespace app\controller\backend; |
|||
|
|||
use app\model\SysSetting; |
|||
use app\service\CacheService; |
|||
use app\validate\SysSettingValidate; |
|||
use think\exception\ValidateException; |
|||
use think\facade\Cache; |
|||
use think\facade\Lang; |
|||
|
|||
|
|||
class SysSettingController extends BaseController |
|||
{ |
|||
protected $group = ['email','upload','sem','analysis','others','company']; |
|||
|
|||
/** |
|||
* 显示资源列表 |
|||
* |
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function index(SysSetting $sysSetting): \think\response\Json |
|||
{ |
|||
$where = [ |
|||
'seller_id' => $this->admin['seller_id'], |
|||
'status' => 1, |
|||
]; |
|||
$order = 'sort asc,id asc'; |
|||
$sysSettingList = $sysSetting->getAllCustomArrayData($where,$order)['data']; |
|||
$sysSettingList = makeTree($sysSettingList); |
|||
return jsonReturn(0,Lang::get('成功'),$sysSettingList); |
|||
} |
|||
|
|||
/** |
|||
* 保存新建的资源 |
|||
* |
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function save(SysSetting $sysSetting): \think\response\Json |
|||
{ |
|||
if(request()->isPost()){ |
|||
$param = input('post.'); |
|||
// 数据验证
|
|||
try{ |
|||
validate(SysSettingValidate::class)->scene('save')->check($param); |
|||
}catch(ValidateException $e){ |
|||
return jsonReturn(-1, $e->getError()); |
|||
} |
|||
$res = $sysSetting -> addCustomData($param); |
|||
return json($res); |
|||
} |
|||
return jsonReturn(-3,Lang::get('请求方法错误')); |
|||
} |
|||
|
|||
/** |
|||
* 显示指定的资源 |
|||
* |
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function read(SysSetting $sysSetting): \think\response\Json |
|||
{ |
|||
$param = input('param.'); |
|||
// 数据验证
|
|||
try{ |
|||
validate(SysSettingValidate::class)->scene('read')->check($param); |
|||
}catch(ValidateException $e){ |
|||
return jsonReturn(-1, $e->getError()); |
|||
} |
|||
$where = [ |
|||
['group','=',$param['group']], |
|||
['seller_id','=',$this->admin['seller_id']], |
|||
]; |
|||
$order = 'sort asc'; |
|||
$res = $sysSetting->getAllCustomArrayData($where,$order)['data']; |
|||
$res = generate($res); |
|||
return jsonReturn(0,Lang::get('成功'),$res); |
|||
} |
|||
|
|||
/** |
|||
* 保存更新的资源 |
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException*@throws \ReflectionException |
|||
* @throws \ReflectionException |
|||
*/ |
|||
public function update(SysSetting $sysSetting): \think\response\Json |
|||
{ |
|||
if(request()->isPost()){ |
|||
$param = input('post.'); |
|||
if(empty($param['group'])){ |
|||
return jsonReturn(-1,Lang::get('配置分组不能为空')); |
|||
} |
|||
if(!in_array($param['group'],$this->group)){ |
|||
return jsonReturn(-2,Lang::get('配置分组类型错误')); |
|||
} |
|||
if($param['group'] == 'setting'){ |
|||
Cache::delete('hc_company_'. $this->admin['seller_id']); |
|||
} |
|||
try { |
|||
validate(SysSettingValidate::class)->check($param); |
|||
} catch (\Exception $e) { |
|||
return jsonReturn(-1, $e->getMessage()); |
|||
} |
|||
$where = [ |
|||
'seller_id' => $this->admin['seller_id'], |
|||
]; |
|||
foreach($param as $key => $val){ |
|||
$whereVal = array_merge($where,['title'=>$key]); |
|||
$sysSetting -> updateSysSetting($whereVal,['value'=>$val]); |
|||
} |
|||
CacheService::deleteRelationCacheByObject($sysSetting); |
|||
return jsonReturn(0,Lang::get("保存成功")); |
|||
} |
|||
return jsonReturn(-3,Lang::get('请求方法错误')); |
|||
} |
|||
|
|||
/** |
|||
* @throws \app\exception\ModelException |
|||
* @throws \ReflectionException |
|||
*/ |
|||
public function emailClear(SysSetting $sysSetting): \think\response\Json |
|||
{ |
|||
$sysSetting -> updateSysSetting(['seller_id' => $this->admin['seller_id'],'group'=>'email'],['value'=>'']); |
|||
CacheService::deleteRelationCacheByObject($sysSetting); |
|||
return jsonReturn(0,Lang::get("成功")); |
|||
} |
|||
|
|||
public function clearCache(): \think\response\Json |
|||
{ |
|||
CacheService::clear(); |
|||
return jsonReturn(0, Lang::get("成功")); |
|||
} |
|||
|
|||
/** |
|||
* |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function password(): \think\response\Json |
|||
{ |
|||
$param = $this->request->only([ |
|||
'status','length','string_type','special_char','change_duration' |
|||
]); |
|||
try { |
|||
validate(SysSettingValidate::class)->scene('pass')->check($param); |
|||
} catch (\Exception $e) { |
|||
return jsonReturn(-1, $e->getMessage()); |
|||
} |
|||
$sysSetting = new SysSetting(); |
|||
$status = $param['status'] ?? 2; |
|||
unset($param['status']); |
|||
$value = json_encode($param); |
|||
$where = [ |
|||
'id' => '120', |
|||
'seller_id' => $this->admin['seller_id'], |
|||
]; |
|||
$res = $sysSetting -> updateSysSetting($where,['value'=>$value,'status'=>$status]); |
|||
return json($res); |
|||
|
|||
} |
|||
|
|||
/** |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function passInfo(): \think\response\Json |
|||
{ |
|||
$sysSetting = new SysSetting(); |
|||
$where = [ |
|||
'id' => '120', |
|||
'seller_id' => $this->admin['seller_id'], |
|||
]; |
|||
$res = $sysSetting -> getSysSetting($where); |
|||
if(!empty($res['data']['value'])){ |
|||
$res['data']['value'] = json_decode($res['data']['value'],true); |
|||
} |
|||
return json($res); |
|||
} |
|||
} |
|||
@ -0,0 +1,539 @@ |
|||
<?php |
|||
declare (strict_types=1); |
|||
|
|||
namespace app\controller\backend; |
|||
|
|||
use app\BaseController; |
|||
use app\exception\InstallException; |
|||
use app\model\Admin; |
|||
use app\model\Model; |
|||
use app\model\Route; |
|||
use app\model\Website; |
|||
use app\model\WebsiteLang; |
|||
use app\model\WebsiteServer; |
|||
use app\model\WebsiteSetting; |
|||
use app\service\ThemeService; |
|||
use app\validate\SystemInstallValidate; |
|||
use think\exception\ValidateException; |
|||
use think\facade\Db; |
|||
use think\facade\Log; |
|||
use think\facade\View; |
|||
use think\Validate; |
|||
|
|||
class SystemInstallController extends BaseController |
|||
{ |
|||
/** |
|||
* 显示资源列表 |
|||
* |
|||
*/ |
|||
public function index() |
|||
{ |
|||
if (hcInstalled()) { |
|||
return redirect('/admin.php'); |
|||
} |
|||
|
|||
// 向huocms官网请求是否认证
|
|||
$domain = request()->host(); |
|||
|
|||
if (!empty($domain)) { |
|||
$authRes = curlPost(config('system.auth_query_url'), ['domain' => $domain])['data']; |
|||
Log::info('auth_query_url:' . $authRes); |
|||
} |
|||
|
|||
$year = date('Y', time()); |
|||
$month = date('m', time()); |
|||
$day = date('d', time()); |
|||
View::assign(['year' => $year, 'month' => $month, 'day' => $day]); |
|||
return View::fetch(CMS_ROOT . 'data/install/install.html'); |
|||
} |
|||
|
|||
public function monitor(): string |
|||
{ |
|||
// if (file_exists_case('data/conf/config.php')) {
|
|||
// @unlink('data/conf/config.php');
|
|||
// }
|
|||
$data = []; |
|||
$data['phpversion'] = @phpversion(); |
|||
$data['os'] = PHP_OS; |
|||
$tmp = function_exists('gd_info') ? gd_info() : []; |
|||
// $server = $_SERVER["SERVER_SOFTWARE"];
|
|||
// $host = $this->request->host();
|
|||
// $name = $_SERVER["SERVER_NAME"];
|
|||
// $max_execution_time = ini_get('max_execution_time');
|
|||
// $allow_reference = (ini_get('allow_call_time_pass_reference') ? '<font color=green>[√]On</font>' : '<font color=red>[×]Off</font>');
|
|||
// $allow_url_fopen = (ini_get('allow_url_fopen') ? '<font color=green>[√]On</font>' : '<font color=red>[×]Off</font>');
|
|||
// $safe_mode = (ini_get('safe_mode') ? '<font color=red>[×]On</font>' : '<font color=green>[√]Off</font>');
|
|||
$err = 0; |
|||
if (empty($tmp['GD Version'])) { |
|||
$gd = '/system_file/install/image/success_icon.jpg'; |
|||
$err++; |
|||
} else { |
|||
$gd = '/system_file/install/image/error_icon.png ' . $tmp['GD Version']; |
|||
} |
|||
|
|||
if (class_exists('pdo')) { |
|||
$data['pdo'] = '/system_file/install/image/success_icon.jpg'; |
|||
} else { |
|||
$data['pdo'] = '/system_file/install/image/error_icon.png'; |
|||
$err++; |
|||
} |
|||
|
|||
if (extension_loaded('pdo_mysql')) { |
|||
$data['pdo_mysql'] = '/system_file/install/image/success_icon.jpg'; |
|||
} else { |
|||
$data['pdo_mysql'] = '/system_file/install/image/error_icon.png'; |
|||
$err++; |
|||
} |
|||
|
|||
if (extension_loaded('curl')) { |
|||
$data['curl'] = '/system_file/install/image/success_icon.jpg'; |
|||
} else { |
|||
$data['curl'] = '/system_file/install/image/error_icon.png'; |
|||
$err++; |
|||
} |
|||
|
|||
if (extension_loaded('gd')) { |
|||
$data['gd'] = '/system_file/install/image/success_icon.jpg'; |
|||
} else { |
|||
$data['gd'] = '/system_file/install/image/error_icon.png'; |
|||
if (function_exists('imagettftext')) { |
|||
$data['gd'] .= '/system_file/install/image/error_icon.png'; |
|||
} |
|||
$err++; |
|||
} |
|||
|
|||
if (extension_loaded('mbstring')) { |
|||
$data['mbstring'] = '/system_file/install/image/success_icon.jpg'; |
|||
} else { |
|||
$data['mbstring'] = '/system_file/install/image/error_icon.png'; |
|||
if (function_exists('imagettftext')) { |
|||
$data['mbstring'] .= '/system_file/install/image/error_icon.png'; |
|||
} |
|||
$err++; |
|||
} |
|||
|
|||
if (extension_loaded('fileinfo')) { |
|||
$data['fileinfo'] = '/system_file/install/image/success_icon.jpg'; |
|||
} else { |
|||
$data['fileinfo'] = '/system_file/install/image/error_icon.png'; |
|||
$err++; |
|||
} |
|||
|
|||
if (ini_get('file_uploads')) { |
|||
$data['upload_size'] = ini_get('upload_max_filesize'); |
|||
} else { |
|||
$data['upload_size'] = '未开启'; |
|||
$err++; |
|||
} |
|||
|
|||
if (function_exists('session_start')) { |
|||
$data['session'] = '/system_file/install/image/success_icon.jpg'; |
|||
} else { |
|||
$data['session'] = '/system_file/install/image/error_icon.png'; |
|||
$err++; |
|||
} |
|||
|
|||
if (version_compare(phpversion(), '7.2.0', '>=') && version_compare(phpversion(), '7.0.0', '<') && ini_get('always_populate_raw_post_data') != -1) { |
|||
$data['always_populate_raw_post_data'] = '未关闭'; |
|||
$data['show_always_populate_raw_post_data_tip'] = true; |
|||
$err++; |
|||
} else { |
|||
$data['always_populate_raw_post_data'] = '已关闭'; |
|||
} |
|||
|
|||
$folders = [ |
|||
realpath(CMS_ROOT . 'data') . DIRECTORY_SEPARATOR, |
|||
realpath(CMS_ROOT . 'runtime') . DIRECTORY_SEPARATOR, |
|||
realpath(CMS_ROOT . 'public/themes') . DIRECTORY_SEPARATOR, |
|||
realpath(CMS_ROOT . 'public/storage') . DIRECTORY_SEPARATOR, |
|||
realpath(CMS_ROOT . 'public/poster_preview') . DIRECTORY_SEPARATOR, |
|||
]; |
|||
$newFolders = []; |
|||
foreach ($folders as $dir) { |
|||
$testDir = $dir; |
|||
sp_dir_create($testDir); |
|||
if (sp_testwrite($testDir)) { |
|||
$newFolders[$dir]['w'] = true; |
|||
} else { |
|||
$newFolders[$dir]['w'] = false; |
|||
$err++; |
|||
} |
|||
if (is_readable($testDir)) { |
|||
$newFolders[$dir]['r'] = true; |
|||
} else { |
|||
$newFolders[$dir]['r'] = false; |
|||
$err++; |
|||
} |
|||
if ($newFolders[$dir]['w'] && $newFolders[$dir]['r']) { |
|||
$newFolders[$dir]['icon'] = '/system_file/install/image/success_icon.jpg'; |
|||
} else { |
|||
$newFolders[$dir]['icon'] = '/system_file/install/image/error_icon.png'; |
|||
|
|||
} |
|||
} |
|||
$data['err'] = $err; |
|||
$data['folders'] = $newFolders; |
|||
View::assign($data); |
|||
return View::fetch(CMS_ROOT . 'data/install/monitor.html'); |
|||
} |
|||
|
|||
public function configure(): string |
|||
{ |
|||
return View::fetch(CMS_ROOT . 'data/install/configure.html'); |
|||
} |
|||
|
|||
public function create(): string |
|||
{ |
|||
$param = request()->param(); |
|||
if (empty($param['username'])) { |
|||
$param['username'] = 'admin@huocms.com'; |
|||
} |
|||
if (empty($param['password'])) { |
|||
$param['password'] = 'huocms.com'; |
|||
} |
|||
$dbConfig = [ |
|||
'type' => 'mysql', |
|||
// 连接名
|
|||
'hostname' => $param['hostname'], |
|||
// 用户名
|
|||
'username' => $param['username'], |
|||
// 密码
|
|||
'password' => $param['password'], |
|||
// 端口
|
|||
'hostport' => $param['hostport'], |
|||
// 数据库编码默认采用utf8mb4
|
|||
'charset' => $param['charset'], |
|||
// 数据库表前缀
|
|||
'prefix' => $param['prefix'], |
|||
]; |
|||
$this->updateDbConfig($dbConfig); |
|||
$sql = "CREATE DATABASE IF NOT EXISTS `{$param['database']}` DEFAULT CHARACTER SET " . $param['charset']; |
|||
$db = Db::connect('install_db'); |
|||
$db->execute($sql); |
|||
$dbConfig['database'] = $param['database']; |
|||
$this->exchangeEnv($dbConfig); |
|||
session('install.db_config', $dbConfig); |
|||
$sql = hcSplitSql(CMS_ROOT . '/data/install/install.sql', $dbConfig['prefix'], $dbConfig['charset']); |
|||
session('install.sql', $sql); |
|||
View::assign('sql_count', count($sql)); |
|||
session('install.error', 0); |
|||
session('install.admin_info', [ |
|||
'name' => $param['admin'], |
|||
'account' => $param['email'], |
|||
'password' => makePassword($param['admin_pass']) |
|||
]); |
|||
return View::fetch(CMS_ROOT . 'data/install/create.html'); |
|||
} |
|||
|
|||
public function install() |
|||
{ |
|||
$dbConfig = session('install.db_config'); |
|||
$sql = session('install.sql'); |
|||
|
|||
if (empty($dbConfig) || empty($sql)) { |
|||
return json([ |
|||
'code' => -1, |
|||
'data' => '', |
|||
'msg' => '非法安装!' |
|||
]); |
|||
} |
|||
|
|||
$sqlIndex = $this->request->param('sql_index', 0, 'intval'); |
|||
|
|||
$this->updateDbConfig($dbConfig); |
|||
$db = Db::connect('install_db'); |
|||
|
|||
if ($sqlIndex >= count($sql)) { |
|||
return json([ |
|||
'code' => 200, |
|||
'data' => '', |
|||
'msg' => '安装完成!' |
|||
]); |
|||
} |
|||
|
|||
$sqlToExec = $sql[$sqlIndex] . ';'; |
|||
|
|||
$result = sp_execute_sql($db, $sqlToExec); |
|||
|
|||
if (!empty($result['error'])) { |
|||
return json([ |
|||
'code' => -1, |
|||
'data' => [ |
|||
'sql' => $sqlToExec, |
|||
'exception' => $result['exception'] |
|||
], |
|||
'msg' => '安装失败!' |
|||
]); |
|||
} else { |
|||
return json([ |
|||
'code' => 0, |
|||
'data' => $result, |
|||
'msg' => '安装成功!' |
|||
]); |
|||
} |
|||
} |
|||
|
|||
public function exchangeEnv($dbConfig) |
|||
{ |
|||
$envFile = CMS_ROOT . '.env'; |
|||
$example = CMS_ROOT . '.example.env'; |
|||
|
|||
if (file_exists($example)) { |
|||
copy($example, $envFile); |
|||
} else { |
|||
touch($envFile); |
|||
$initArray = [ |
|||
"APP_DEBUG = true", |
|||
"APP_HOST = http://localhost", |
|||
"", |
|||
"[APP]", |
|||
"DEFAULT_TIMEZONE = Asia/Shanghai", |
|||
"", |
|||
"[DATABASE]", |
|||
"TYPE = mysql", |
|||
"HOSTNAME = 127.0.0.1", |
|||
"DATABASE = huo_cms", |
|||
"USERNAME = root", |
|||
"PASSWORD = ", |
|||
"HOSTPORT = 3306", |
|||
"CHARSET = utf8mb4", |
|||
"DEBUG = true", |
|||
"PREFIX = hc_", |
|||
"", |
|||
"[LANG]", |
|||
"default_lang = zh", |
|||
]; |
|||
file_put_contents($envFile, implode(PHP_EOL, $initArray)); |
|||
} |
|||
|
|||
$merge = [ |
|||
'app_debug' => true, |
|||
'app_host' => request()->domain(), |
|||
]; |
|||
$data = []; |
|||
foreach (array_merge($merge, $dbConfig) as $key => $val) { |
|||
$key = strtoupper($key); |
|||
$data[$key] = $val; |
|||
} |
|||
|
|||
$this->updateEnv($envFile, $data); |
|||
} |
|||
|
|||
public function updateEnv($envFile, $data = array()) |
|||
{ |
|||
$oldEnv = file($envFile); |
|||
if (!count($data)) { |
|||
return; |
|||
} |
|||
if (array_keys($data) === range(0, count($data) - 1)) { |
|||
return; |
|||
} |
|||
$pattern = '/([^\=]*)\=[^\n]*/'; |
|||
$newEnv = []; |
|||
foreach ($oldEnv as $line) { |
|||
preg_match($pattern, $line, $matches); |
|||
|
|||
if (!count($matches)) { |
|||
$newEnv[] = $line; |
|||
continue; |
|||
} |
|||
|
|||
if (!key_exists(trim($matches[1]), $data)) { |
|||
$newEnv[] = $line; |
|||
continue; |
|||
} |
|||
|
|||
$line = trim($matches[1]) . "={$data[trim($matches[1])]}\n"; |
|||
$newEnv[] = $line; |
|||
} |
|||
$newContent = implode('', $newEnv); |
|||
|
|||
file_put_contents($envFile, $newContent); |
|||
} |
|||
|
|||
public function userCheck(): \think\response\Json |
|||
{ |
|||
$param = request()->param(); |
|||
try { |
|||
validate(SystemInstallValidate::class)->check($param); |
|||
} catch (ValidateException $e) { |
|||
return jsonReturn(-1, $e->getError()); |
|||
} |
|||
return jsonReturn(0, 'success'); |
|||
} |
|||
|
|||
public function testPass(): \think\response\Json |
|||
{ |
|||
$param = request()->param(); |
|||
$dbConfig = [ |
|||
'type' => 'mysql', |
|||
// 连接名
|
|||
'hostname' => $param['hostname'], |
|||
// 数据库名
|
|||
'username' => $param['username'], |
|||
// 密码
|
|||
'password' => $param['password'], |
|||
// 端口
|
|||
'hostport' => $param['hostport'], |
|||
]; |
|||
$this->updateDbConfig($dbConfig); |
|||
$supportInnoDb = false; |
|||
try { |
|||
$db = Db::connect('install_db'); |
|||
$engines = $db->query("SHOW ENGINES;"); |
|||
foreach ($engines as $engine) { |
|||
if ($engine['Engine'] == 'InnoDB' && $engine['Support'] != 'NO') { |
|||
$supportInnoDb = true; |
|||
break; |
|||
} |
|||
} |
|||
} catch (\Exception $e) { |
|||
return jsonReturn(-1, '数据库账号或密码不正确!' . $e->getMessage()); |
|||
} |
|||
if (!$supportInnoDb) { |
|||
return jsonReturn(-2, '数据库账号密码验证通过,但不支持InnoDb!'); |
|||
} else { |
|||
return jsonReturn(0, 'success'); |
|||
} |
|||
} |
|||
|
|||
public function installCompleteCheck(): \think\response\Json |
|||
{ |
|||
|
|||
$admin = session("install.admin_info"); |
|||
if (empty($admin)) { |
|||
return jsonReturn(-1, '用户创建失败,请重试'); |
|||
} |
|||
Db::startTrans(); |
|||
try { |
|||
// 创建管理员
|
|||
$Admin = new Admin(); |
|||
$admin['seller_id'] = 1; |
|||
$admin['status'] = 1; |
|||
$admin['group'] = 1; |
|||
$res = $Admin->addAdmin($admin)['data']; |
|||
$res->role()->attach(1, ['seller_id' => 1]); |
|||
session('adminId', $res['id']); |
|||
$website = new Website(); |
|||
$siteParam = [ |
|||
'title' => '演示站点', |
|||
'domain' => request()->host() |
|||
]; |
|||
// 创建站点
|
|||
// 1. 保存站点到数据库
|
|||
$res = $website->addWebsite($siteParam); |
|||
if ($res['data'] != 1) { |
|||
throw new InstallException(); |
|||
} |
|||
// 2. 生成一份默认的站点配置,配置的值为空
|
|||
$tmpData = config('system.website_setting'); |
|||
$sysData = [ |
|||
"setting" => json_encode($tmpData), |
|||
"website_id" => $res['data'], |
|||
"lang" => "zh" |
|||
]; |
|||
$siteSetting = new WebsiteSetting(); |
|||
$siteSetting->addWebsiteSetting($sysData); |
|||
// 3. 选择站点语言简体中文,服务器为本地服务器
|
|||
$langData[] = [ |
|||
'seller_id' => 1, |
|||
'website_id' => $res['data'], |
|||
'lang_name' => '简体中文', |
|||
'lang' => 'zh', |
|||
]; |
|||
$WebsiteLang = new WebsiteLang(); |
|||
$WebsiteLang->addWebsiteLang($langData); |
|||
$serverData = [ |
|||
'seller_id' => 1, |
|||
'website_id' => $res['data'], |
|||
'type' => 1, |
|||
]; |
|||
$WebsiteServer = new WebsiteServer(); |
|||
$WebsiteServer->addWebsiteServer($serverData); |
|||
// 4.生成路由
|
|||
$Route = new Route(); |
|||
$Route->updateRoute(['seller_id' => 1], ['website_id' => $res['data']]); |
|||
$Route->getRoutes($res['data'], 1, 'zh'); |
|||
// 5.安装模版
|
|||
$ThemeService = new ThemeService(); |
|||
$ThemeService->installTheme('demo', $res['data'], 1); |
|||
|
|||
createInstallFile(); |
|||
session("install.step", 4); |
|||
Db::commit(); |
|||
} catch (InstallException $e) { |
|||
@unlink(CMS_ROOT . 'public/system_file/install.lock'); |
|||
Db::rollback(); |
|||
dump($e->getLine()); |
|||
dd($e->getTrace()); |
|||
return jsonReturn(-3, '安装失败,请清空数据库后重试'); |
|||
} catch (\Exception $e) { |
|||
@unlink(CMS_ROOT . 'public/system_file/install.lock'); |
|||
Db::rollback(); |
|||
return jsonReturn(-1, '用户创建失败,请重试' . $e->getMessage()); |
|||
} |
|||
return jsonReturn(0, 'success'); |
|||
} |
|||
|
|||
public function completeCheck(): \think\response\Json |
|||
{ |
|||
if (session("install.step") == 4) { |
|||
return jsonReturn(0, '安装成功'); |
|||
} else { |
|||
return jsonReturn(-1, '安装失败'); |
|||
} |
|||
} |
|||
|
|||
public function complete(): string |
|||
{ |
|||
return View::fetch(CMS_ROOT . 'data/install/complete.html'); |
|||
} |
|||
|
|||
private function updateDbConfig($dbConfig) |
|||
{ |
|||
$oldDbConfig = config('database'); |
|||
$oldDbConfig['connections']['install_db'] = $dbConfig; |
|||
config($oldDbConfig, 'database'); |
|||
} |
|||
|
|||
public function write_ini_file($assoc_arr, $path, $has_sections = FALSE): bool |
|||
{ |
|||
$content = ""; |
|||
if ($has_sections) { |
|||
foreach ($assoc_arr as $key => $elem) { |
|||
$content .= "[" . $key . "]n"; |
|||
foreach ($elem as $key2 => $elem2) { |
|||
if (is_array($elem2)) { |
|||
for ($i = 0; $i < count($elem2); $i++) { |
|||
$content .= $key2 . "[] = " . $elem2[$i] . "\r\n"; |
|||
} |
|||
} else if ($elem2 == "") { |
|||
$content .= $key2 . " = n"; |
|||
} else { |
|||
$content .= $key2 . " = " . $elem2 . "\r\n"; |
|||
} |
|||
} |
|||
} |
|||
} else { |
|||
foreach ($assoc_arr as $key => $elem) { |
|||
if (is_array($elem)) { |
|||
for ($i = 0; $i < count($elem); $i++) { |
|||
$content .= $key . "[] = " . $elem[$i] . "\r\n"; |
|||
} |
|||
} else if ($elem == "") { |
|||
$content .= $key . " = n"; |
|||
} else { |
|||
$content .= $key . " = " . $elem . "\r\n"; |
|||
} |
|||
} |
|||
} |
|||
if (!$handle = fopen($path, 'w')) { |
|||
return false; |
|||
} |
|||
if (!fwrite($handle, $content)) { |
|||
return false; |
|||
} |
|||
fclose($handle); |
|||
return true; |
|||
} |
|||
} |
|||
@ -0,0 +1,169 @@ |
|||
<?php |
|||
declare (strict_types = 1); |
|||
|
|||
namespace app\controller\backend; |
|||
|
|||
use app\exception\ModelException; |
|||
use app\model\RecycleBin; |
|||
use app\model\Tag; |
|||
use app\validate\TagValidate; |
|||
use Overtrue\Pinyin\Pinyin; |
|||
use think\exception\ValidateException; |
|||
use think\facade\Lang; |
|||
|
|||
class TagController extends BaseController |
|||
{ |
|||
/** |
|||
* 显示资源列表 |
|||
* |
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function index(Tag $tag): \think\response\Json |
|||
{ |
|||
$websiteId = (int)input('param.website_id'); |
|||
if(!$websiteId){ |
|||
return jsonReturn(-1,Lang::get('网站ID不能为空')); |
|||
} |
|||
$lang = input('lang'); |
|||
if(empty($lang)){ |
|||
$lang = 'zh'; |
|||
} |
|||
$limit = $this->setLimit(); |
|||
$title = input('title') ?: ''; |
|||
$where = [ |
|||
['seller_id', '=' ,$this->admin['seller_id']], |
|||
['website_id' ,'=', $websiteId], |
|||
['lang','=',$lang], |
|||
['is_del','=',1], |
|||
]; |
|||
if($title){ |
|||
array_push($where,['title','like','%'.$title.'%']); |
|||
} |
|||
try{ |
|||
$tagList = $tag->where($where)->paginate($limit)->each(function(&$item){ |
|||
$contentNum = $item->subContent()->where('is_del',1)->count(); |
|||
$item -> article_count = $contentNum; |
|||
$item -> save(); |
|||
}); |
|||
}catch(\Exception $e){ |
|||
throw new ModelException($e->getMessage()); |
|||
} |
|||
return json(['code'=>0,'total'=>$tagList->total(),'msg'=>Lang::get('成功'),'data'=>$tagList->all()]); |
|||
} |
|||
|
|||
/** |
|||
* 保存新建的资源 |
|||
* |
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
* @throws \app\exception\ModelNotUniqueException |
|||
*/ |
|||
public function save(Tag $tag): \think\response\Json |
|||
{ |
|||
if(request()->isPost()){ |
|||
$param = input('post.'); |
|||
// 数据验证
|
|||
try{ |
|||
validate(TagValidate::class)->scene('save')->check($param); |
|||
}catch(ValidateException $e){ |
|||
return jsonReturn(-1, $e->getError()); |
|||
} |
|||
$param['seller_id'] = $this->admin['seller_id']; |
|||
$param['unique_tag'] = $param['seller_id'] . '-' . $param['website_id'] . '-' . $param['lang'] .'-' . $param['title']; |
|||
$tag->saveUnique(['unique_tag'=> $param['unique_tag'],'is_del'=>1],Lang::get('标签名称已经存在')); |
|||
$pinyin = new Pinyin(); |
|||
$param['first_letter'] = strtoupper(substr($pinyin->abbr($param['title']),0,1)); |
|||
$param = $this->setSEO($param); |
|||
$res = $tag -> addTag($param); |
|||
return json($res); |
|||
} |
|||
return jsonReturn(-3,Lang::get('请求方法错误')); |
|||
} |
|||
|
|||
/** |
|||
* 保存更新的资源 |
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException*@throws \app\exception\ModelNotUniqueException |
|||
* @throws \app\exception\ModelNotUniqueException |
|||
*/ |
|||
public function update(Tag $tag): \think\response\Json |
|||
{ |
|||
if(request()->isPost()){ |
|||
$param = input('post.'); |
|||
try { |
|||
validate(TagValidate::class)->scene('update')->check($param); |
|||
} catch (ValidateException $e) { |
|||
return jsonReturn(-1, $e->getError()); |
|||
} |
|||
$where = [ |
|||
'id' => $param['id'], |
|||
'seller_id' => $this->admin['seller_id'], |
|||
'is_del' => 1, |
|||
]; |
|||
$param = $this->setSEO($param); |
|||
$param['unique_tag'] = $this->admin['seller_id'] . '-' . $param['website_id'] . '-' . $param['lang'] .'-'. $param['title']; |
|||
$tag->updateUnique(['unique_tag' => $param['unique_tag']],$param['id'],Lang::get('标签名称已经存在')); |
|||
$pinyin = new Pinyin(); |
|||
$param['first_letter'] = strtoupper(substr($pinyin->abbr($param['title']),0,1)); |
|||
$res = $tag -> updateTag($where,$param); |
|||
return json($res); |
|||
} |
|||
return jsonReturn(-3,Lang::get('请求方法错误')); |
|||
} |
|||
|
|||
/** |
|||
* 删除指定资源 |
|||
* |
|||
* @throws \app\exception\ModelException |
|||
* @throws \app\exception\ModelEmptyException |
|||
*/ |
|||
public function delete(Tag $Tag,RecycleBin $recycleBin): \think\response\Json |
|||
{ |
|||
if(request()->isPost()){ |
|||
$id = (int)input('id'); |
|||
if(!$id){ |
|||
return jsonReturn(-1,Lang::get('标签ID不能为空')); |
|||
} |
|||
$where = [ |
|||
'id' => $id, |
|||
'seller_id' => $this->admin['seller_id'], |
|||
]; |
|||
$tag = $Tag->getTag($where)['data']; |
|||
// 复制删除内容到回收站表
|
|||
$binData = [ |
|||
'seller_id' => $this->admin['seller_id'], |
|||
'object_id' => $id, |
|||
'sub_id' => '', |
|||
'module_id' => '', |
|||
'table_name' => 'tag', |
|||
'title' => $tag['title'], |
|||
'admin_id' => $this->admin['seller_id'], |
|||
'name' => $this->admin['name'], |
|||
]; |
|||
$recycleBin -> addRecycleBin($binData); |
|||
$res = $Tag -> softDelTag($where); |
|||
return json($res); |
|||
} |
|||
return jsonReturn(-3,Lang::get('请求方法错误')); |
|||
} |
|||
|
|||
/** |
|||
* 配置SEO |
|||
* @param $param |
|||
* @return mixed |
|||
*/ |
|||
public function setSEO($param) |
|||
{ |
|||
if(empty($param['seo_title'])){ |
|||
$param['seo_title'] = $param['title']; |
|||
} |
|||
if(empty($param['seo_keywords'])){ |
|||
$param['seo_keywords'] = $param['title']; |
|||
} |
|||
if(empty($param['seo_description'])){ |
|||
$param['seo_description'] = $param['title']; |
|||
} |
|||
return $param; |
|||
} |
|||
} |
|||
@ -0,0 +1,277 @@ |
|||
<?php |
|||
declare (strict_types = 1); |
|||
|
|||
namespace app\controller\backend; |
|||
|
|||
use app\exception\ModelEmptyException; |
|||
use app\exception\ModelException; |
|||
use app\model\Theme; |
|||
use app\model\ThemeFile; |
|||
use app\service\ThemeService; |
|||
use app\validate\ThemeValidate; |
|||
use think\exception\ValidateException; |
|||
use think\facade\Db; |
|||
use think\facade\Lang; |
|||
use think\response\Json; |
|||
|
|||
|
|||
class ThemeController extends BaseController |
|||
{ |
|||
/** |
|||
* 已安装模板 |
|||
* |
|||
* @return Json |
|||
* @throws ModelException |
|||
*/ |
|||
public function index(Theme $theme): Json |
|||
{ |
|||
$website_id = (int)input('param.website_id'); |
|||
if(!$website_id){ |
|||
return jsonReturn(-1,Lang::get('网站ID不能为空')); |
|||
} |
|||
$lang = input('param.lang') ?: config('lang.default_lang'); |
|||
$where = [ |
|||
['seller_id','=',$this->admin['seller_id']], |
|||
['website_id','=',$website_id], |
|||
['lang','=',$lang] |
|||
]; |
|||
|
|||
$limit = $this->setLimit(); |
|||
$themeList = $theme->getThemeList($where,$limit); |
|||
return json(pageReturn($themeList)); |
|||
} |
|||
|
|||
/** |
|||
* 模板完整更新 |
|||
* |
|||
* @return Json |
|||
* @throws ModelException*@throws \app\exception\ModelEmptyException |
|||
* @throws ModelEmptyException |
|||
*/ |
|||
public function update(ThemeService $themeService): Json |
|||
{ |
|||
if(request()->isPost()){ |
|||
$param = input('post.'); |
|||
try { |
|||
validate(ThemeValidate::class)->scene('update')->check($param); |
|||
} catch (ValidateException $e) { |
|||
return jsonReturn(-1, $e->getError()); |
|||
} |
|||
$suffix = config('view.view_suffix'); |
|||
|
|||
return $themeService->updateTheme($param['theme_id'],$param['website_id'],$this->admin['seller_id'],$suffix); |
|||
} |
|||
return jsonReturn(-3,Lang::get('请求方法错误')); |
|||
} |
|||
|
|||
/** |
|||
* 系统模版 |
|||
* |
|||
* @param Theme $themeModel |
|||
* @return Json |
|||
*/ |
|||
public function install(Theme $themeModel): Json |
|||
{ |
|||
$themesDirs = hcScanDir("themes/hc_original/*", GLOB_ONLYDIR); |
|||
$themes = []; |
|||
foreach ($themesDirs as $dir) { |
|||
$manifest = "themes/hc_original/$dir/manifest.json"; |
|||
if (hcFileExist($manifest)) { |
|||
$manifest = file_get_contents($manifest); |
|||
$theme = json_decode($manifest, true); |
|||
} |
|||
$theme['theme'] = $dir; |
|||
$themes[] = $theme; |
|||
} |
|||
return jsonReturn(0,Lang::get('成功'),$themes); |
|||
} |
|||
|
|||
/** |
|||
* 模版安装 |
|||
* |
|||
* @throws ModelException |
|||
*/ |
|||
public function installTheme(ThemeService $service): Json |
|||
{ |
|||
if ($this->request->isPost()) { |
|||
set_time_limit(300); |
|||
$param = input('post.'); |
|||
try { |
|||
validate(ThemeValidate::class)->scene('installTheme')->check($param); |
|||
}catch (ValidateException $e){ |
|||
return jsonReturn(-1,$e->getError()); |
|||
} |
|||
$suffix = config('view.view_suffix'); |
|||
return $service->installTheme($param['theme'],$param['website_id'],$this->admin['seller_id'],$suffix,$param['lang']); |
|||
} |
|||
return jsonReturn(-3,Lang::get('请求方法错误')); |
|||
} |
|||
|
|||
/** |
|||
* 卸载模板 |
|||
* @throws ModelEmptyException |
|||
* @throws ModelException |
|||
*/ |
|||
public function uninstall(ThemeService $service): Json |
|||
{ |
|||
if ($this->request->isPost()) { |
|||
$param = input('post.'); |
|||
try { |
|||
validate(ThemeValidate::class)->scene('uninstall')->check($param); |
|||
}catch (ValidateException $e){ |
|||
return jsonReturn(-1,$e->getError()); |
|||
} |
|||
return $service->uninstallTheme($param['theme_id'],$param['website_id'],$this->admin['seller_id']); |
|||
} |
|||
return jsonReturn(-3,Lang::get('请求方法错误')); |
|||
} |
|||
|
|||
/** |
|||
* 模板文件 |
|||
* |
|||
* @throws ModelException |
|||
*/ |
|||
public function tmpFile(ThemeFile $ThemeFile): Json |
|||
{ |
|||
$param = input('param.'); |
|||
try { |
|||
validate(ThemeValidate::class)->scene('tmpFile')->check($param); |
|||
} catch (ValidateException $e) { |
|||
return jsonReturn(-1, $e->getError()); |
|||
} |
|||
$limit = $this->setLimit(); |
|||
$where = [ |
|||
'seller_id' => $this->admin['seller_id'], |
|||
'theme_id' => $param['theme_id'], |
|||
'website_id' => $param['website_id'], |
|||
]; |
|||
$res = $ThemeFile -> getThemeFileList($where,'id,name,file,real_path',$limit); |
|||
return json(pageReturn($res)); |
|||
} |
|||
|
|||
/** |
|||
* |
|||
* @param ThemeFile $ThemeFile |
|||
* @return Json |
|||
* @throws ModelException |
|||
*/ |
|||
public function templateFile(ThemeFile $ThemeFile): Json |
|||
{ |
|||
$param = input('param.'); |
|||
try { |
|||
validate(ThemeValidate::class)->scene('templateFile')->check($param); |
|||
} catch (ValidateException $e) { |
|||
return jsonReturn(-1, $e->getError()); |
|||
} |
|||
$theme = new Theme(); |
|||
$activeTheme = $theme->getActiveTheme(['seller_id'=>$this->admin['seller_id'],'website_id'=>$param['website_id'],'lang'=>$param['lang'],'is_active'=>1])['data']; |
|||
if(empty($activeTheme)){ |
|||
return jsonReturn(-1,Lang::get('未安装或启用模版')); |
|||
} |
|||
$where = [ |
|||
'seller_id' => $this->admin['seller_id'], |
|||
'theme_id' => $activeTheme['id'], |
|||
'website_id' => $param['website_id'], |
|||
]; |
|||
$template = $ThemeFile -> getAllCustomArrayData($where)['data']; |
|||
|
|||
return jsonReturn(0,Lang::get('成功'),$template); |
|||
} |
|||
|
|||
/** |
|||
* 启用模版 |
|||
* |
|||
* @throws ModelException |
|||
*/ |
|||
public function active(Theme $Theme): Json |
|||
{ |
|||
if(request()->isPost()){ |
|||
$param = input('post.'); |
|||
try { |
|||
validate(ThemeValidate::class)->scene('active')->check($param); |
|||
} catch (ValidateException $e) { |
|||
return jsonReturn(-1, $e->getError()); |
|||
} |
|||
Db::startTrans(); |
|||
try{ |
|||
// 将所有模版暂停启用
|
|||
$Theme->updateTheme(['seller_id'=>$this->admin['seller_id'],'website_id'=>$param['website_id'],'lang'=>$param['lang']],['is_active'=>2]); |
|||
// 启用当前模版
|
|||
$res = $Theme->updateTheme(['id'=>$param['theme_id'],'seller_id'=>$this->admin['seller_id'],'website_id'=>$param['website_id'],'lang'=>$param['lang']],['is_active'=>1]); |
|||
Db::commit(); |
|||
}catch (\Exception $e){ |
|||
Db::rollback(); |
|||
return jsonReturn(-3,Lang::get('模版安装启用错误')); |
|||
} |
|||
return json($res); |
|||
} |
|||
return jsonReturn(-3,Lang::get('请求方法错误')); |
|||
} |
|||
|
|||
/** |
|||
* 所有目录 |
|||
* @throws ModelEmptyException |
|||
* @throws ModelException |
|||
*/ |
|||
public function allFilePath(ThemeService $service): Json |
|||
{ |
|||
$param = input('param.'); |
|||
try { |
|||
validate(ThemeValidate::class)->scene('allFilePath')->check($param); |
|||
}catch (ValidateException $e){ |
|||
return jsonReturn(-1,$e->getError()); |
|||
} |
|||
return $service->filesPath($param['website_id'],$param['lang']); |
|||
} |
|||
|
|||
public function allFiles(ThemeService $service): Json |
|||
{ |
|||
$param = input('param.'); |
|||
try { |
|||
validate(ThemeValidate::class)->scene('allFiles')->check($param); |
|||
}catch (ValidateException $e){ |
|||
return jsonReturn(-1,$e->getError()); |
|||
} |
|||
return $service->files($param['path'],(int)$param['website_id'],$param['lang']); |
|||
} |
|||
|
|||
public function dealWithImg(): Json |
|||
{ |
|||
$sourcePath = input('post.source'); |
|||
$terminalPath = input('post.terminal'); |
|||
|
|||
$sourceFiles = glob($sourcePath.'/*'); |
|||
|
|||
$tmpFiles = []; |
|||
foreach ($sourceFiles as $sourceFile) { |
|||
$key = pathinfo($sourceFile,PATHINFO_FILENAME); |
|||
$ext = pathinfo($sourceFile,PATHINFO_EXTENSION); |
|||
$tmpFiles[$key] = $ext; |
|||
} |
|||
$terminalFiles = glob($terminalPath.'/*'); |
|||
$termFiles = []; |
|||
foreach ($terminalFiles as $val) { |
|||
$key = pathinfo($val,PATHINFO_FILENAME); |
|||
$ext = pathinfo($val,PATHINFO_EXTENSION); |
|||
$termFiles[$key] = $ext; |
|||
} |
|||
foreach ($termFiles as $key => $term){ |
|||
if($term != $tmpFiles[$key]){ |
|||
$formName = $terminalPath .'/' . $key . '.' . $term; |
|||
$toName = $terminalPath.'/' . $key . '.' . $tmpFiles[$key]; |
|||
rename($formName,$toName); |
|||
} |
|||
} |
|||
return jsonReturn(0,'success'); |
|||
} |
|||
|
|||
public function delete(ThemeService $service): Json |
|||
{ |
|||
$theme = input('param.theme'); |
|||
if(empty($theme)){ |
|||
return jsonReturn(-1,Lang::get('模版名称不能为空')); |
|||
} |
|||
$res = $service -> delOriginalTheme($theme); |
|||
return json($res); |
|||
} |
|||
} |
|||
@ -0,0 +1,206 @@ |
|||
<?php |
|||
declare (strict_types = 1); |
|||
|
|||
namespace app\controller\backend; |
|||
|
|||
use app\exception\ModelEmptyException; |
|||
use app\model\Theme; |
|||
use app\model\ThemeFile; |
|||
use app\service\CacheService; |
|||
use app\service\ComponentDataService; |
|||
use app\service\ThemeFileService; |
|||
use app\validate\ThemeFileValidate; |
|||
use think\exception\ValidateException; |
|||
use think\facade\Lang; |
|||
|
|||
|
|||
class ThemeFileController extends BaseController |
|||
{ |
|||
/** |
|||
* 显示资源列表 |
|||
* |
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function index(ThemeFile $themeFile): \think\response\Json |
|||
{ |
|||
$where = [ |
|||
'seller_id' => $this->admin['seller_id'], |
|||
'is_del' => 1, |
|||
]; |
|||
$limit = $this->setLimit(); |
|||
$themeFileList = $themeFile->getThemeFileList($where,$limit); |
|||
return json(pageReturn($themeFileList)); |
|||
} |
|||
|
|||
/** |
|||
* 保存新建的资源 |
|||
* |
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
* @throws \ReflectionException |
|||
*/ |
|||
public function save(ThemeFile $themeFile): \think\response\Json |
|||
{ |
|||
if(request()->isPost()){ |
|||
$param = input('post.'); |
|||
// 数据验证
|
|||
try{ |
|||
validate(ThemeFileValidate::class)->scene('save')->check($param); |
|||
}catch(ValidateException $e){ |
|||
return jsonReturn(-1, $e->getError()); |
|||
} |
|||
// TODO
|
|||
// 其他逻辑
|
|||
|
|||
$res = $themeFile -> addThemeFile($param); |
|||
CacheService::deleteRelationCacheByObject($themeFile); |
|||
return json($res); |
|||
} |
|||
return jsonReturn(-3,Lang::get('请求方法错误')); |
|||
} |
|||
|
|||
/** |
|||
* 显示指定的资源 |
|||
* |
|||
* @return \think\response\Json |
|||
*/ |
|||
public function read(ThemeFileService $themeFileService): \think\response\Json |
|||
{ |
|||
$path = input('param.path'); |
|||
|
|||
if (strpos($path, '..') !== false) { |
|||
return jsonReturn(-1,Lang::get('文件路径有误')); |
|||
} |
|||
|
|||
if(empty($path)){ |
|||
return jsonReturn(-1,Lang::get('文件路径不能为空')); |
|||
} |
|||
|
|||
// 不是可编辑文件
|
|||
$ext = pathinfo($path, PATHINFO_EXTENSION); |
|||
|
|||
if (!in_array($ext, ['js', 'json', 'html', 'css', 'less', 'htm', 'sass'])) { |
|||
return jsonReturn(-1,Lang::get('不支持的编辑文件')); |
|||
} |
|||
|
|||
return $themeFileService->readSource($path); |
|||
} |
|||
|
|||
/** |
|||
* 保存更新的资源 |
|||
* @return \think\response\Json |
|||
* @throws \ReflectionException |
|||
*/ |
|||
public function update(ThemeFileService $themeFileService): \think\response\Json |
|||
{ |
|||
if(request()->isPost()){ |
|||
$param = input('post.'); |
|||
try { |
|||
validate(ThemeFileValidate::class)->scene('update')->check($param); |
|||
} catch (ValidateException $e) { |
|||
return jsonReturn(-1, $e->getError()); |
|||
} |
|||
return $themeFileService -> updateResource($param['path'],$param['content']); |
|||
} |
|||
return jsonReturn(-3,Lang::get('请求方法错误')); |
|||
} |
|||
|
|||
/** |
|||
* 更新单个文件 |
|||
* @param ThemeFileService $themeFileService |
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
* @throws \ReflectionException |
|||
*/ |
|||
public function singleUpdate(ThemeFileService $themeFileService): \think\response\Json |
|||
{ |
|||
if(request()->isPost()){ |
|||
$path = input('param.path'); |
|||
$path = str_replace('\\', '/', $path); |
|||
$path = trim($path,'/'); |
|||
if(empty($path)){ |
|||
return jsonReturn(-1,Lang::get('文件路径不能为空')); |
|||
} |
|||
|
|||
$res = $themeFileService -> updateThemeFile($path); |
|||
return json($res); |
|||
} |
|||
return jsonReturn(-3,Lang::get('请求方法错误')); |
|||
} |
|||
|
|||
/** |
|||
* 模板设计 |
|||
* @throws \app\exception\ModelEmptyException |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function design(ThemeFileService $themeFileService) |
|||
{ |
|||
$param = input('param.'); |
|||
try { |
|||
validate(ThemeFileValidate::class)->scene('design')->check($param); |
|||
} catch (ValidateException $e) { |
|||
return jsonReturn(-1, $e->getError()); |
|||
} |
|||
$url = '/'; |
|||
if(!empty($param['url'])){ |
|||
$url = $param['url']; |
|||
} |
|||
define('ADMIN_SITE_ID',$param['website_id']); |
|||
define('ADMIN_SELLER_ID',$this->admin['seller_id']); |
|||
return $themeFileService -> design($param['theme_id'],$param['website_id'],$this->admin['seller_id'],$url); |
|||
} |
|||
|
|||
/** |
|||
* @throws ModelEmptyException |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function compData(ThemeFileService $themeFileService) |
|||
{ |
|||
$param = input('param.'); |
|||
try { |
|||
validate(ThemeFileValidate::class)->scene('design')->check($param); |
|||
} catch (ValidateException $e) { |
|||
return jsonReturn(-1, $e->getError()); |
|||
} |
|||
define('ADMIN_SITE_ID',$param['website_id']); |
|||
define('ADMIN_SELLER_ID',$this->admin['seller_id']); |
|||
define('ADMIN_LANG',$param['lang']); |
|||
return $themeFileService -> compData($this->admin['seller_id'],$param['theme_id'],$param['website_id'],$param['url'],$param['block']); |
|||
} |
|||
|
|||
/** |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function active(Theme $Theme,ThemeFile $ThemeFile): \think\response\Json |
|||
{ |
|||
$siteId = (int)input('website_id'); |
|||
$lang = input('lang'); |
|||
if(empty($siteId)){ |
|||
return jsonReturn(-1,Lang::get('站点ID不能为空')); |
|||
} |
|||
$themeWhere = [ |
|||
'seller_id' => $this->admin['seller_id'], |
|||
'website_id' => $siteId, |
|||
'lang' => $lang, |
|||
'is_active' => 1 |
|||
]; |
|||
try{ |
|||
$theme = $Theme->getTheme($themeWhere)['data']; |
|||
}catch (ModelEmptyException $e){ |
|||
return jsonReturn(-1,Lang::get('该站点没有启用的模板')); |
|||
} |
|||
$fileWhere = [ |
|||
'seller_id' => $this->admin['seller_id'], |
|||
'website_id' => $siteId, |
|||
'theme_id' => $theme['id'], |
|||
]; |
|||
$list = $ThemeFile->getThemeAllFile($fileWhere); |
|||
return json($list); |
|||
} |
|||
|
|||
public function singleUpdateFile() |
|||
{ |
|||
|
|||
} |
|||
} |
|||
@ -0,0 +1,84 @@ |
|||
<?php |
|||
declare (strict_types = 1); |
|||
|
|||
namespace app\controller\backend; |
|||
|
|||
use app\model\SysSetting; |
|||
use app\service\upload\Upload; |
|||
use think\facade\Lang; |
|||
use think\Request; |
|||
|
|||
class UploadController extends BaseController |
|||
{ |
|||
protected $type = [ |
|||
'file' => 4, |
|||
'image' => 2, |
|||
'video' => 3, |
|||
'mp3' => 5, |
|||
'zip' => 1, |
|||
]; |
|||
|
|||
/** |
|||
* 保存新建的资源 |
|||
* |
|||
* @param \think\Request $request |
|||
* @return \think\Response |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function save(Request $request): \think\Response |
|||
{ |
|||
if(request()->isPost()){ |
|||
$file = request()->file('file'); |
|||
if(empty($file)){ |
|||
return jsonReturn(-2,Lang::get('文件不能为空')); |
|||
} |
|||
$seller_id = $this->admin['seller_id']; |
|||
// 查看文件类型
|
|||
$fileName = $file->getOriginalName(); |
|||
$fileExt = $file->getOriginalExtension(); |
|||
$file_type = fileFormat($fileName); |
|||
$fileType = $this->type[$file_type]; |
|||
// 附件大小和类型验证
|
|||
// 获取上传配置
|
|||
$Settings = new SysSetting(); |
|||
$uploadSetting = $Settings->getAllCustomArrayData(['parent_id'=>1,'group'=>'upload','status'=>1],'id desc','id,group,title,value')['data']; |
|||
$uploadSetting = getColumnForKeyArray($uploadSetting,'title'); |
|||
$limitSize = $uploadSetting[$file_type.'_size']['value'] * 1024; // byte
|
|||
$fileSize = $file->getSize(); // 单位byte
|
|||
if($fileSize > $limitSize){ |
|||
return jsonReturn(-1,Lang::get('文件过大,请修改上传限制或者替换小的文件')); |
|||
} |
|||
$extArr = explode(',',$uploadSetting[$file_type.'_ext']['value']); |
|||
if(!in_array($fileExt,$extArr)){ |
|||
return jsonReturn(-2,Lang::get('文件格式错误,请重新上传')); |
|||
} |
|||
// 文件信息提取
|
|||
$where = [ |
|||
'seller_id' => $seller_id, |
|||
'group' => 'upload', |
|||
'title' => 'storage' |
|||
]; |
|||
$place = new SysSetting(); |
|||
$type = $place->getSysSetting($where)['data']->toArray()['value']; |
|||
|
|||
$upload = new Upload(); |
|||
$info = $upload->create($file,$seller_id, $type,$file_type); |
|||
|
|||
if ($info) { |
|||
$uploadInfo = $upload->getUploadFileInfo(); |
|||
if ($uploadInfo['code'] == 0) { |
|||
$uploadInfo['data']['type'] = $fileType; |
|||
$uploadInfo['data']['size'] = round($fileSize / 1024,2); |
|||
$uploadInfo['data']['mime_type'] = $fileExt; |
|||
} |
|||
return json($uploadInfo); |
|||
}else{ |
|||
return jsonReturn(-1, Lang::get('上传失败请重新尝试')); |
|||
} |
|||
} |
|||
return jsonReturn(-3,Lang::get('请求方法错误')); |
|||
} |
|||
|
|||
|
|||
|
|||
} |
|||
@ -0,0 +1,287 @@ |
|||
<?php |
|||
declare (strict_types = 1); |
|||
|
|||
namespace app\controller\backend; |
|||
|
|||
use app\model\Admin; |
|||
use app\model\Route; |
|||
use app\model\Website; |
|||
use app\model\WebsiteLang; |
|||
use app\model\WebsiteSetting; |
|||
use app\service\CacheService; |
|||
use app\service\SitemapService; |
|||
use app\service\WebsiteLangService; |
|||
use app\validate\WebsiteValidate; |
|||
use app\service\WebsiteService; |
|||
use think\facade\Db; |
|||
use think\exception\ValidateException; |
|||
use think\facade\Lang; |
|||
|
|||
|
|||
class WebsiteController extends BaseController |
|||
{ |
|||
/** |
|||
* 显示资源列表 |
|||
* |
|||
* @return \think\Response |
|||
* @throws \app\exception\ModelException |
|||
* @throws \app\exception\ModelEmptyException |
|||
*/ |
|||
public function index(Website $website): \think\response\Json |
|||
{ |
|||
$where = [ |
|||
['seller_id','=', $this->admin['seller_id']], |
|||
]; |
|||
$uid = $this -> admin['uid']; |
|||
$authSiteId = []; |
|||
if($uid != 1){ |
|||
$admin = new Admin(); |
|||
$adminInfo = $admin -> getAdmin(['seller_id' => $this->admin['seller_id'],'id' => $uid],['role.website'])['data'] -> toArray(); |
|||
$authSite = array_column($adminInfo['role'],'website'); |
|||
foreach($authSite as $val){ |
|||
$authSiteId = array_merge($authSiteId,array_column($val,'id')); |
|||
} |
|||
$authSiteId = array_unique($authSiteId); |
|||
$where[] = ['id','in',$authSiteId]; |
|||
} |
|||
$websiteList = $website->getAllCustomArrayData($where)['data']; |
|||
$websiteList = makeTree($websiteList); |
|||
return jsonReturn(0,Lang::get('成功'),$websiteList); |
|||
} |
|||
|
|||
/** |
|||
* 保存新建的资源 |
|||
* |
|||
* @return \think\Response |
|||
* @throws \app\exception\ModelException |
|||
* @throws \app\exception\ModelNotUniqueException |
|||
*/ |
|||
public function save(Website $website): \think\response\Json |
|||
{ |
|||
if(request()->isPost()){ |
|||
$param = input('post.'); |
|||
// 数据验证
|
|||
try{ |
|||
validate(WebsiteValidate::class)->scene('save')->check($param); |
|||
}catch(ValidateException $e){ |
|||
return jsonReturn(-1, $e->getError()); |
|||
} |
|||
$website->saveUnique(['seller_id'=>$this->admin['seller_id'],'title'=>$param['title']],'网站名称已存在'); |
|||
$param['seller_id'] = $this->admin['seller_id']; |
|||
$param['status'] = 1; |
|||
Db::startTrans(); |
|||
try{ |
|||
// 1. 保存站点到数据库
|
|||
$res = $website -> addWebsite($param); |
|||
if($param['parent_id'] == 0){ |
|||
$this->selfData($res['data'],$param['domain'],$param['parent_id']); |
|||
}else{ |
|||
$this->sonData($res['data'],$param['domain'],$param['parent_id']); |
|||
} |
|||
CacheService::deleteRelationCacheByObject($website); |
|||
Db::commit(); |
|||
}catch(\Exception $e){ |
|||
Db::rollback(); |
|||
return jsonReturn(-5,$e->getMessage()); |
|||
} |
|||
return json($res); |
|||
} |
|||
return jsonReturn(-3,Lang::get('请求方法错误')); |
|||
} |
|||
|
|||
|
|||
/** |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function selfData($siteId, $domain, $parentId) |
|||
{ |
|||
// 2. 生成一份默认的站点配置,配置的值为空
|
|||
$tmpData = config('system.website_setting'); |
|||
$sysData = [ |
|||
"setting"=> json_encode($tmpData), |
|||
"website_id"=>$siteId, |
|||
"lang"=>config('lang.default_lang') |
|||
]; |
|||
$siteSetting = new WebsiteSetting(); |
|||
$siteSetting -> addWebsiteSetting($sysData); |
|||
// 3. 选择站点语言简体中文,服务器为本地服务器
|
|||
$langData[]= [ |
|||
'seller_id' => $this->admin['seller_id'], |
|||
'website_id' => $siteId, |
|||
'lang_name' => '简体中文', |
|||
'lang' => config('lang.default_lang'), |
|||
]; |
|||
$WebsiteLang = new WebsiteLang(); |
|||
$WebsiteLang->addWebsiteLang($langData); |
|||
} |
|||
|
|||
/** |
|||
* @throws \app\exception\ModelEmptyException |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function sonData($siteId, $domain, $parentId) |
|||
{ |
|||
$website = new Website(); |
|||
// 1. 写入父站点的路由
|
|||
$parent = $website -> getWebsite(['id'=>$parentId,'seller_id'=>$this->admin['seller_id']])['data']; |
|||
$parentDomain = $parent['domain']; |
|||
$start = $parentId . '_' ; |
|||
$path = CMS_ROOT . 'route'; |
|||
$files = glob("$path/$start*.php"); |
|||
foreach ($files as $file){ |
|||
$tmpStr = str_replace($parentDomain,$domain,file_get_contents($file)); |
|||
$basename = str_replace($start,$siteId.'_',basename($file)); |
|||
file_put_contents($path . DIRECTORY_SEPARATOR . $basename,$tmpStr); |
|||
} |
|||
// 父站点路由copy一份到子站点保存到数据库
|
|||
$route = new Route(); |
|||
$routes = $route -> getAllCustomArrayData(['seller_id'=>$this->admin['seller_id'],'website_id'=>$parentId])['data']; |
|||
foreach ($routes as &$val){ |
|||
$val['website_id'] = $siteId; |
|||
$val['seller_id'] = $this->admin['seller_id']; |
|||
unset($val['id']); |
|||
unset($val['create_time']); |
|||
unset($val['update_time']); |
|||
} |
|||
unset($val); |
|||
$route->addAllCustomData($routes); |
|||
// 2. 写入语言+配置
|
|||
$WebsiteLang = new WebsiteLang(); |
|||
$parentLang = $WebsiteLang->getAllCustomArrayData(['id'=>$parentId,'seller_id'=>$this->admin['seller_id']])['data']; |
|||
$lang = array_column($parentLang,'lang'); |
|||
$websiteLangService = new WebsiteLangService(); |
|||
$websiteLangService->setSiteLang(['seller_id'=>$this->admin['seller_id'],'site_id'=>$siteId,'lang'=>$lang]); |
|||
} |
|||
|
|||
/** |
|||
* 显示指定的资源 |
|||
* |
|||
* @return \think\Response |
|||
* @throws \app\exception\ModelException |
|||
* @throws \app\exception\ModelEmptyException |
|||
*/ |
|||
public function read(Website $website): \think\response\Json |
|||
{ |
|||
$id = (int)input('id'); |
|||
if(!$id){ |
|||
return jsonReturn(-1,Lang::get('网站ID不能为空')); |
|||
} |
|||
$where = [ |
|||
'id' => $id, |
|||
'seller_id' => $this->admin['seller_id'] |
|||
]; |
|||
$res = $website->getWebsite($where); |
|||
return json($res); |
|||
|
|||
} |
|||
|
|||
/** |
|||
* 设置网站状态 |
|||
* @param Website $website |
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function setStatus(Website $website) |
|||
{ |
|||
if(!request()->isPost()){ |
|||
return jsonReturn(-3,Lang::get('请求方法错误')); |
|||
} |
|||
$param = $this->request->only(['id' => 0, 'status' => 1]); |
|||
|
|||
try { |
|||
validate(WebsiteValidate::class)->scene('setStatus')->check($param); |
|||
} catch (ValidateException $e) { |
|||
return jsonReturn(-1, $e->getError()); |
|||
} |
|||
|
|||
$where = [ |
|||
'id' => $param['id'], |
|||
'seller_id' => $this->admin['seller_id'], |
|||
]; |
|||
|
|||
if ($param['status'] == 2) { |
|||
$childWhere = [ |
|||
'parent_id' => $param['id'], |
|||
'seller_id' => $this->admin['seller_id'], |
|||
]; |
|||
$website->updateWebsite($childWhere, ['status' => $param['status']]); |
|||
} |
|||
$res = $website->updateWebsite($where, ['status' => $param['status']]); |
|||
return json($res); |
|||
} |
|||
|
|||
/** |
|||
* 保存更新的资源 |
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
* @throws \app\exception\ModelEmptyException |
|||
* @throws \ReflectionException |
|||
*/ |
|||
public function update(Website $website): \think\response\Json |
|||
{ |
|||
if(request()->isPost()){ |
|||
$param = input('post.'); |
|||
try { |
|||
validate(WebsiteValidate::class)->scene('update')->check($param); |
|||
} catch (ValidateException $e) { |
|||
return jsonReturn(-1, $e->getError()); |
|||
} |
|||
$where = [ |
|||
'id' => $param['id'], |
|||
'seller_id' => $this->admin['seller_id'], |
|||
]; |
|||
$site = $website->getWebsite($where)['data']; |
|||
if($param['domain'] != $site['domain']){ |
|||
// 修改路由域名配置
|
|||
$routePath = app()->getRootPath() . 'route'. DIRECTORY_SEPARATOR; |
|||
$fileArr = hcScanDir($routePath.'*'); |
|||
foreach($fileArr as $val){ |
|||
$siteId = $param['id']; |
|||
$pattern = '/^'.$siteId.'_/'; |
|||
if(is_file($routePath . $val) && preg_match($pattern,$val)){ |
|||
$conArr = str_replace($site['domain'],$param['domain'],file_get_contents($routePath.$val)); |
|||
file_put_contents($routePath.$val,$conArr); |
|||
} |
|||
} |
|||
} |
|||
$res = $website -> updateWebsite($where,$param); |
|||
CacheService::deleteRelationCacheByObject($website); |
|||
return json($res); |
|||
} |
|||
return jsonReturn(-3,Lang::get('请求方法错误')); |
|||
} |
|||
|
|||
/** |
|||
* 删除指定资源 |
|||
* |
|||
*/ |
|||
public function delete(WebsiteService $websiteService): \think\response\Json |
|||
{ |
|||
if(request()->isPost()){ |
|||
$id = (int)input('id'); |
|||
if(!$id){ |
|||
return jsonReturn(-1,Lang::get('网站ID不能为空')); |
|||
} |
|||
|
|||
$res = $websiteService->deleteSite($id,$this->admin['seller_id']); |
|||
|
|||
return json($res); |
|||
} |
|||
return jsonReturn(-3,Lang::get('请求方法错误')); |
|||
} |
|||
|
|||
/** |
|||
* xml文件 |
|||
* @param SitemapService $sitemapService |
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelEmptyException |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function sitemap(SitemapService $sitemapService): \think\response\Json |
|||
{ |
|||
$siteId = (int)$this->request->param('website_id'); |
|||
$sellerId = $this->admin['seller_id']; |
|||
$res = $sitemapService -> makeSitemap($siteId,$sellerId); |
|||
return json($res); |
|||
} |
|||
} |
|||
@ -0,0 +1,86 @@ |
|||
<?php |
|||
declare (strict_types = 1); |
|||
|
|||
namespace app\controller\backend; |
|||
|
|||
use app\model\Model; |
|||
use app\model\Website; |
|||
use app\model\WebsiteLang; |
|||
use app\model\WebsiteSetting; |
|||
use app\service\CacheService; |
|||
use app\service\WebsiteLangService; |
|||
use app\validate\WebsiteLangValidate; |
|||
use think\Cookie; |
|||
use think\exception\ValidateException; |
|||
use think\facade\Lang; |
|||
|
|||
|
|||
class WebsiteLangController extends BaseController |
|||
{ |
|||
/** |
|||
* 显示资源列表 |
|||
* |
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function index(WebsiteLang $websiteLang): \think\response\Json |
|||
{ |
|||
$siteId = (int)input('site_id'); |
|||
if(!$siteId){ |
|||
return jsonReturn(-1, Lang::get('站点ID不能为空')); |
|||
} |
|||
$where = [ |
|||
'seller_id' => $this->admin['seller_id'], |
|||
'website_id' => $siteId, |
|||
]; |
|||
$websiteLangList = $websiteLang->getAllCustomArrayData($where,'id asc'); |
|||
return json($websiteLangList); |
|||
} |
|||
|
|||
/** |
|||
* 保存新建的资源 |
|||
* |
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
* @throws \ReflectionException |
|||
*/ |
|||
public function save(WebsiteLangService $websiteLangService): \think\response\Json |
|||
{ |
|||
if(request()->isPost()){ |
|||
$param = input('post.'); |
|||
// 数据验证
|
|||
try{ |
|||
validate(WebsiteLangValidate::class)->scene('save')->check($param); |
|||
}catch(ValidateException $e){ |
|||
return jsonReturn(-1, $e->getError()); |
|||
} |
|||
$param['seller_id'] = $this->admin['seller_id']; |
|||
$res = $websiteLangService -> setSiteLang($param); |
|||
CacheService::deleteRelationCacheByObject(WebsiteLang::class); |
|||
return json($res); |
|||
} |
|||
return jsonReturn(-3,Lang::get('请求方法错误')); |
|||
} |
|||
|
|||
/** |
|||
* 系统语言 |
|||
* @return \think\response\Json |
|||
*/ |
|||
public function system(): \think\response\Json |
|||
{ |
|||
if(request()->isGet()){ |
|||
$lang = config('system.lang'); |
|||
return json(['code'=>0,'msg'=>'success','data'=>$lang]); |
|||
} |
|||
return jsonReturn(-3,Lang::get('请求方法错误')); |
|||
} |
|||
|
|||
/** |
|||
* 切换语言 |
|||
*/ |
|||
public function changeLang(\think\Lang $lang,Cookie $cookie){ |
|||
$val = $this->request->param('lang/s',''); |
|||
$cookie->set($lang->getConfig()['cookie_var'], $val); |
|||
return jsonReturn(0,Lang::get('操作成功')); |
|||
} |
|||
} |
|||
@ -0,0 +1,90 @@ |
|||
<?php |
|||
declare (strict_types = 1); |
|||
|
|||
namespace app\controller\backend; |
|||
|
|||
use app\model\WebsiteServer; |
|||
use app\validate\WebsiteServerValidate; |
|||
use think\exception\ValidateException; |
|||
use think\facade\Lang; |
|||
|
|||
|
|||
class WebsiteServerController extends BaseController |
|||
{ |
|||
|
|||
/** |
|||
* 保存新建的资源 |
|||
* |
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function save(WebsiteServer $websiteServer): \think\response\Json |
|||
{ |
|||
if(request()->isPost()){ |
|||
$param = input('post.'); |
|||
// 数据验证
|
|||
try{ |
|||
validate(WebsiteServerValidate::class)->scene('save')->check($param); |
|||
}catch(ValidateException $e){ |
|||
return jsonReturn(-1, $e->getError()); |
|||
} |
|||
$param['seller_id'] = $this->admin['seller_id']; |
|||
|
|||
$res = $websiteServer -> addWebsiteServer($param); |
|||
return json($res); |
|||
} |
|||
return jsonReturn(-3,Lang::get('请求方法错误')); |
|||
} |
|||
|
|||
/** |
|||
* 显示指定的资源 |
|||
* |
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
* @throws \app\exception\ModelEmptyException |
|||
*/ |
|||
public function read(WebsiteServer $websiteServer): \think\response\Json |
|||
{ |
|||
|
|||
$siteId = (int)input('site_id'); |
|||
if(!$siteId){ |
|||
// 修改错误消息
|
|||
return jsonReturn(-1,Lang::get('网站ID不能为空')); |
|||
} |
|||
$where = [ |
|||
'website_id' => $siteId, |
|||
'seller_id' => $this->admin['seller_id'] |
|||
]; |
|||
$res = $websiteServer->getWebsiteServer($where); |
|||
return json($res); |
|||
|
|||
} |
|||
|
|||
/** |
|||
* 保存更新的资源 |
|||
|
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function update(WebsiteServer $websiteServer): \think\response\Json |
|||
{ |
|||
if(request()->isPost()){ |
|||
$param = input('post.'); |
|||
try { |
|||
validate(WebsiteServerValidate::class)->scene('update')->check($param); |
|||
} catch (ValidateException $e) { |
|||
return jsonReturn(-1, $e->getError()); |
|||
} |
|||
$where = [ |
|||
'seller_id' => $this->admin['seller_id'], |
|||
'website_id' => $param['website_id'], |
|||
]; |
|||
unset($param['website_id']); |
|||
$res = $websiteServer -> updateWebsiteServer($where,$param); |
|||
return json($res); |
|||
} |
|||
return jsonReturn(-3,Lang::get('请求方法错误')); |
|||
} |
|||
|
|||
|
|||
} |
|||
@ -0,0 +1,125 @@ |
|||
<?php |
|||
declare (strict_types = 1); |
|||
|
|||
namespace app\controller\backend; |
|||
|
|||
use app\model\Attachment; |
|||
use app\model\Model; |
|||
use app\model\WebsiteSetting; |
|||
use app\validate\WebsiteSettingValidate; |
|||
use think\exception\ValidateException; |
|||
use think\facade\Cache; |
|||
use think\facade\Cookie; |
|||
use think\facade\Lang; |
|||
|
|||
|
|||
class WebsiteSettingController extends BaseController |
|||
{ |
|||
/** |
|||
* 保存新建的资源 |
|||
* |
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
* @throws \app\exception\ModelNotUniqueException |
|||
*/ |
|||
public function save(WebsiteSetting $websiteSetting): \think\response\Json |
|||
{ |
|||
if(request()->isPost()){ |
|||
$param = input('post.'); |
|||
// 数据验证
|
|||
try{ |
|||
validate(WebsiteSettingValidate::class)->scene('save')->check($param); |
|||
}catch(ValidateException $e){ |
|||
return jsonReturn(-1, $e->getError()); |
|||
} |
|||
$param['seller_id'] = $this->admin['seller_id']; |
|||
$param['setting'] = json_encode($param['setting']); |
|||
$websiteSetting->saveUnique(['seller_id'=>$param['seller_id'],'website_id'=>$param['website_id'],'lang'=>$param['lang']],'相同配置已经存在,请编辑'); |
|||
$res = $websiteSetting -> addWebsiteSetting($param); |
|||
return json($res); |
|||
} |
|||
return jsonReturn(-3,Lang::get('请求方法错误')); |
|||
} |
|||
|
|||
/** |
|||
* 显示指定的资源 |
|||
* |
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
* @throws \app\exception\ModelEmptyException |
|||
*/ |
|||
public function read(WebsiteSetting $websiteSetting,Attachment $attachment): \think\response\Json |
|||
{ |
|||
$param = input('param.'); |
|||
// 数据验证
|
|||
try{ |
|||
validate(WebsiteSettingValidate::class)->scene('read')->check($param); |
|||
}catch(ValidateException $e){ |
|||
return jsonReturn(-1, $e->getError()); |
|||
} |
|||
$where = [ |
|||
'seller_id' => $this->admin['seller_id'], |
|||
'website_id' => $param['website_id'], |
|||
'lang' => $param['lang'], |
|||
]; |
|||
$cacheKey = $this->admin['seller_id'] .'_'.$param['website_id'] .'_'. $param['lang'] . '_website_cache_key'; |
|||
Cache::delete($cacheKey); |
|||
$res = $websiteSetting->getWebsiteSetting($where); |
|||
$res['data'] = $res['data']->toArray(); |
|||
$res['data']['setting'] = json_decode($res['data']['setting'],true); |
|||
if(!empty($res['data']['setting']['logo'])){ |
|||
$attach = $attachment->getAttachment(['id'=>$res['data']['setting']['logo'],'seller_id'=>$this->admin['seller_id']])['data']; |
|||
if(!empty($attach)){ |
|||
$res['data']['setting']['logo'] = $attach; |
|||
} |
|||
} |
|||
if(!empty($res['data']['setting']['wechat_code'])){ |
|||
$attach = $attachment->getAttachment(['id'=>$res['data']['setting']['wechat_code'],'seller_id'=>$this->admin['seller_id']])['data']; |
|||
if(!empty($attach)){ |
|||
$res['data']['setting']['wechat_code'] = $attach; |
|||
} |
|||
} |
|||
if(!empty($res['data']['setting']['dark_logo'])){ |
|||
$attach = $attachment->getAttachment(['id'=>$res['data']['setting']['dark_logo'],'seller_id'=>$this->admin['seller_id']])['data']; |
|||
if(!empty($attach)){ |
|||
$res['data']['setting']['dark_logo'] = $attach; |
|||
} |
|||
} |
|||
return json($res); |
|||
|
|||
} |
|||
|
|||
/** |
|||
* 保存更新的资源 |
|||
* @return \think\response\Json |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function update(WebsiteSetting $websiteSetting): \think\response\Json |
|||
{ |
|||
if(request()->isPost()){ |
|||
$param = input('post.'); |
|||
try { |
|||
validate(WebsiteSettingValidate::class)->scene('update')->check($param); |
|||
} catch (ValidateException $e) { |
|||
return jsonReturn(-1, $e->getError()); |
|||
} |
|||
$where = [ |
|||
'seller_id' => $this->admin['seller_id'], |
|||
'website_id' => $param['website_id'], |
|||
'lang' => $param['lang'], |
|||
]; |
|||
$setting = json_encode($param['setting']); |
|||
$res = $websiteSetting -> updateWebsiteSetting($where,['setting'=>$setting]); |
|||
$siteCacheKey = $this->admin['seller_id'] .'_'.$param['website_id'] .'_'. $param['lang'] . '_website_cache_key'; |
|||
Cache::delete($siteCacheKey); |
|||
|
|||
if(config('lang')['use_cookie']){ |
|||
Cookie::set(config('lang')['cookie_var'],$param['lang']); |
|||
} |
|||
|
|||
return json($res); |
|||
} |
|||
return jsonReturn(-3,Lang::get('请求方法错误')); |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,333 @@ |
|||
<?php |
|||
declare (strict_types = 1); |
|||
|
|||
namespace app\controller\frontend; |
|||
|
|||
use app\BaseController as AppBaseController; |
|||
use app\model\Theme; |
|||
use app\model\VisitLog; |
|||
use app\model\Website; |
|||
use app\service\ApiService; |
|||
use think\facade\Cache; |
|||
use think\facade\View; |
|||
use Overtrue\PHPOpenCC\OpenCC; |
|||
|
|||
class BaseController extends AppBaseController |
|||
{ |
|||
protected $rootDomain; |
|||
protected $domain; |
|||
protected $siteId; |
|||
protected $sellerId; |
|||
protected $theme; |
|||
protected $lang; |
|||
protected $realLang; |
|||
protected $viewBase; |
|||
protected $settingData; |
|||
protected $parentSiteId; |
|||
protected $realSiteId; |
|||
protected $viewSiteId; |
|||
protected $preview; |
|||
|
|||
/** |
|||
* @throws \app\exception\ModelException |
|||
* @throws \Exception |
|||
*/ |
|||
public function initialize() |
|||
{ |
|||
$this->setCommonParam(); |
|||
$this->getRootDomain(); |
|||
$this->setRealSiteId(); |
|||
$this->getActiveTheme(); |
|||
$this->setVisitedData(); |
|||
parent::initialize(); |
|||
} |
|||
|
|||
/** |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function setCommonParam() |
|||
{ |
|||
// 更新版本标识
|
|||
updateVersion(); |
|||
$domain = $this->request->host(); |
|||
$Website = new Website(); |
|||
$website = $Website->getWebsiteByDomain($domain,'id,domain,seller_id,parent_id,status')['data']; |
|||
|
|||
if ($website['status'] == 2) { |
|||
$this->to404(); |
|||
} |
|||
|
|||
// 是否为预览状态
|
|||
$historyViewTime = session('history-view'); |
|||
$preview = $this->request->param('preview', ''); |
|||
if (!empty($preview)) { |
|||
if ((time() - $historyViewTime) < 30 * 60) { |
|||
// 30分钟内可预览
|
|||
$this->preview = 1; |
|||
} else { |
|||
header('Location: /'); |
|||
return; |
|||
} |
|||
} |
|||
|
|||
$this->domain = $domain; |
|||
$this->siteId = $website['id']; |
|||
$this->parentSiteId = $website['parent_id']; |
|||
$this->sellerId = $website['seller_id']; |
|||
$this->realLang = $this->setLang(); |
|||
$this->lang = $this->setRealLang(); |
|||
$this->viewBase = config('view.view_dir_name'); |
|||
define('INDEX_SITE_ID',$this->siteId); |
|||
define('INDEX_SELLER_ID',$this->sellerId); |
|||
define('INDEX_LANG',$this->lang); |
|||
} |
|||
|
|||
public function getRootDomain() |
|||
{ |
|||
$rootDomain = $this->request->rootDomain(); |
|||
if( $rootDomain === 'com.cn'){ |
|||
$domainArr = explode('.',$this->domain); |
|||
array_shift($domainArr); |
|||
$this->rootDomain = implode('.',$domainArr); |
|||
}else{ |
|||
$this->rootDomain = $rootDomain; |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* @throws \app\exception\ModelException |
|||
* @throws \app\exception\ModelEmptyException |
|||
*/ |
|||
public function getActiveTheme() |
|||
{ |
|||
$Theme = new Theme(); |
|||
$theme = $Theme->getActiveTheme(['seller_id'=>$this->sellerId,'website_id'=>$this->viewSiteId,'lang'=>$this->lang,'is_active'=>1])['data']->toArray(); |
|||
$cacheKey = $this->sellerId .'_'.$this->siteId .'_'. $this->lang . '_website_cache_key'; |
|||
$settingData = Cache::get($cacheKey); |
|||
if(empty($settingData)){ |
|||
$settingData = ApiService::setWebsiteSetting($this->sellerId,$this->siteId,$this->lang); |
|||
} |
|||
$this->settingData = $settingData; |
|||
|
|||
if(isMobile() && !empty($settingData['common_template']) && $settingData['common_template'] == 2){ |
|||
$this->theme = 'm_' . $theme['theme']; |
|||
}else{ |
|||
$this->theme = $theme['theme']; |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function setRealSiteId() |
|||
{ |
|||
$siteId = $this->siteId; |
|||
$Theme = new Theme(); |
|||
$theme = $Theme->getActiveTheme(['seller_id'=>$this->sellerId,'website_id'=>$siteId,'lang'=>$this->lang,'is_active'=>1])['data']; |
|||
$this->viewSiteId = $siteId; |
|||
|
|||
// 本站点没有安装启用模板,页面加载用父级的模板
|
|||
if ($this->parentSiteId && empty($theme)){ |
|||
$this->viewSiteId = $this->parentSiteId; |
|||
} |
|||
|
|||
if($this->parentSiteId){ |
|||
$siteId = $this->parentSiteId; |
|||
} |
|||
define('INDEX_REAL_SITE_ID',$siteId); |
|||
return $this->realSiteId = $siteId; |
|||
} |
|||
|
|||
public function setRealLang(): string |
|||
{ |
|||
return $this->realLang == config('lang.traditional_chinese') ? 'zh' : $this->realLang; |
|||
} |
|||
|
|||
public function setLang(): string |
|||
{ |
|||
return getLang(); |
|||
} |
|||
|
|||
protected function assign($name,$value = ''): \think\View |
|||
{ |
|||
return View::assign($name, $value); |
|||
} |
|||
|
|||
/** |
|||
* 加载模板输出 |
|||
* @access protected |
|||
* @param string $template 模板文件名 |
|||
* @param array $vars 模板输出变量 |
|||
* @return mixed |
|||
*/ |
|||
protected function fetch(string $template = '', array $vars = []) |
|||
{ |
|||
$template = $this->parseTemplate($template); |
|||
$this->_initializeView($this->viewSiteId,$this->lang,$this->theme); |
|||
|
|||
$html = View::fetch($template, $vars); |
|||
$replace = <<<EOL |
|||
<script id="baseJs" src="/system_file/js/base.min.js"></script> |
|||
</head> |
|||
EOL; |
|||
$html = str_replace('</head>', $replace, $html); |
|||
if($this->realLang == config('lang.traditional_chinese')){ |
|||
$html = OpenCC::s2tw($html); |
|||
} |
|||
return $html; |
|||
} |
|||
|
|||
/** |
|||
* 加载模板输出(system_file) |
|||
* @access protected |
|||
* @param string $template 模板文件名 |
|||
* @param array $vars 模板输出变量 |
|||
* @return mixed |
|||
*/ |
|||
protected function fetchSystem(string $template = '', array $vars = []) |
|||
{ |
|||
$template = $this->parseTemplateSystem($template); |
|||
$this->_initializeViewSystem($this->viewSiteId,$this->lang,$this->theme); |
|||
|
|||
$html = View::fetch($template, $vars); |
|||
$replace = <<<EOL |
|||
<script id="baseJs" src="/system_file/js/base.min.js"></script> |
|||
</head> |
|||
EOL; |
|||
$html = str_replace('</head>', $replace, $html); |
|||
if($this->realLang == config('lang.traditional_chinese')){ |
|||
$html = OpenCC::s2tw($html); |
|||
} |
|||
return $html; |
|||
} |
|||
|
|||
/** |
|||
* 定位模板 |
|||
* @param $template |
|||
* @return string |
|||
*/ |
|||
private function parseTemplate($template): string |
|||
{ |
|||
$path = CMS_ROOT . $this->viewBase . DIRECTORY_SEPARATOR . $this->viewSiteId.DIRECTORY_SEPARATOR .$this->lang.DIRECTORY_SEPARATOR.$this->theme; |
|||
|
|||
if (!empty($this->preview)) { |
|||
$path = CMS_ROOT . 'public/themes/preview/'.$this->theme; |
|||
} |
|||
|
|||
$ext = getFileExt($template); |
|||
$path .= DIRECTORY_SEPARATOR . ltrim($template,'/'); |
|||
if( $ext != config('view.view_suffix')){ |
|||
$path .= '.'.config('view.view_suffix'); |
|||
} |
|||
return $path ; |
|||
} |
|||
|
|||
/** |
|||
* 定位模板 |
|||
* @param $template |
|||
* @return string |
|||
*/ |
|||
private function parseTemplateSystem($template): string |
|||
{ |
|||
$path = CMS_ROOT . 'public/system_file' . DIRECTORY_SEPARATOR; |
|||
$ext = getFileExt($template); |
|||
$path .= DIRECTORY_SEPARATOR . ltrim($template,'/'); |
|||
if( $ext != config('view.view_suffix')){ |
|||
$path .= '.'.config('view.view_suffix'); |
|||
} |
|||
return $path ; |
|||
} |
|||
|
|||
/** |
|||
* 常量替换 |
|||
* @param $siteId |
|||
* @param $lang |
|||
* @param $themeName |
|||
*/ |
|||
protected function _initializeView($siteId,$lang,$themeName) |
|||
{ |
|||
if (!empty($this->preview)) { |
|||
$viewReplaceStr = [ |
|||
'__TMPL__' => "/themes/preview/{$themeName}", |
|||
'__STATIC__' => empty($this->settingData['static_file']) ? "/themes/preview/{$themeName}/static" : $this->settingData['static_file'] , |
|||
]; |
|||
|
|||
View::engine()->config([ |
|||
'view_path' => CMS_ROOT . '/public/themes/preview/' .$this->theme . '/', |
|||
'tpl_replace_string' => $viewReplaceStr, |
|||
'display_cache' => false, |
|||
'tpl_cache' => false, |
|||
]); |
|||
} else { |
|||
$viewReplaceStr = [ |
|||
'__TMPL__' => "/themes/website/{$siteId}/{$lang}/{$themeName}", |
|||
'__STATIC__' => empty($this->settingData['static_file']) ? "/themes/website/{$siteId}/{$lang}/{$themeName}/static" : $this->settingData['static_file'] , |
|||
]; |
|||
View::engine()->config([ |
|||
'view_path' => CMS_ROOT . $this->viewBase . DIRECTORY_SEPARATOR . $siteId. DIRECTORY_SEPARATOR .$this->lang.DIRECTORY_SEPARATOR.$this->theme .DIRECTORY_SEPARATOR, |
|||
'tpl_replace_string' => $viewReplaceStr, |
|||
'display_cache' => false, |
|||
'tpl_cache' => false, |
|||
]); |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 常量替换 |
|||
* @param $siteId |
|||
* @param $lang |
|||
* @param $themeName |
|||
*/ |
|||
protected function _initializeViewSystem($siteId,$lang,$themeName) |
|||
{ |
|||
$viewReplaceStr = [ |
|||
'__TMPL__' => "/themes/website/{$siteId}/{$lang}/{$themeName}", |
|||
'__STATIC__' => empty($this->settingData['static_file']) ? "/themes/website/{$siteId}/{$lang}/{$themeName}/static" : $this->settingData['static_file'] , |
|||
]; |
|||
|
|||
View::engine()->config([ |
|||
'view_path' => CMS_ROOT . 'public/system_file' . DIRECTORY_SEPARATOR, |
|||
'tpl_replace_string' => $viewReplaceStr, |
|||
'display_cache' => false, |
|||
'tpl_cache' => false, |
|||
]); |
|||
} |
|||
|
|||
/** |
|||
* @throws \Exception |
|||
*/ |
|||
private function setVisitedData() |
|||
{ |
|||
$VisitLog = new VisitLog(); |
|||
$ip = request()->ip(); |
|||
$agent = !empty(request()->header()['user-agent']) ? request()->header()['user-agent'] : '未知设备'; |
|||
$address = getLocationByIp($ip,2); |
|||
if(empty($address['province'])){ |
|||
$area = "内网ip"; |
|||
}else{ |
|||
$area = $address['province']."-".$address['city']; |
|||
} |
|||
$url = $this->request->domain().$this->request->url(); |
|||
$device = getDeviceInfo($agent); |
|||
$param = [ |
|||
'seller_id' => $this->sellerId, |
|||
'website_id' => $this->siteId, |
|||
'domain' => $this->domain, |
|||
'referrer' => empty($_SERVER['HTTP_REFERER']) ? '未知' : $_SERVER['HTTP_REFERER'], |
|||
'url' => $url, |
|||
'ip' => $ip, |
|||
'agent' => $agent, |
|||
'visited_area' => $area, |
|||
'visited_device' => $device['deviceOs'] .'/'.$device['deviceVersion'], |
|||
'visited_time' => date('Y-m-d',time()) |
|||
]; |
|||
|
|||
$VisitLog -> addCustomData($param); |
|||
} |
|||
|
|||
public function to404() |
|||
{ |
|||
header('Location: /system_file/hc_error/404.html'); |
|||
exit(); |
|||
} |
|||
} |
|||
@ -0,0 +1,132 @@ |
|||
<?php |
|||
|
|||
namespace app\controller\frontend; |
|||
|
|||
use think\facade\View; |
|||
|
|||
class DesignBaseController extends BaseController |
|||
{ |
|||
protected $designBase = 'public/design/designPage'; |
|||
protected $designPath = ''; |
|||
|
|||
public function initialize() |
|||
{ |
|||
parent::initialize(); |
|||
$this->setPath(); |
|||
} |
|||
|
|||
public function setPath() |
|||
{ |
|||
$this->designPath = CMS_ROOT . 'public/design/'; |
|||
} |
|||
|
|||
/** |
|||
* 加载模板输出(system_file) |
|||
* @access protected |
|||
* @param string $template 模板文件名 |
|||
* @param array $vars 模板输出变量 |
|||
* @return mixed |
|||
*/ |
|||
protected function fetchDesign(string $template = '', array $vars = []) |
|||
{ |
|||
$template = $this->parseTemplateDesign($template); |
|||
$this->_initializeViewDesign($this->realSiteId,$this->lang); |
|||
|
|||
$html = View::fetch($template, $vars); |
|||
$replace = <<<EOL |
|||
<script id="baseJs" src="/system_file/js/base.min.js"></script> |
|||
</head> |
|||
EOL; |
|||
$html = str_replace('</head>', $replace, $html); |
|||
return $html; |
|||
} |
|||
|
|||
/** |
|||
* |
|||
* 定位模板 |
|||
* @param $template |
|||
* @return string |
|||
*/ |
|||
private function parseTemplateDesign($template): string |
|||
{ |
|||
$path = CMS_ROOT . "public/design/designPage" . DIRECTORY_SEPARATOR; |
|||
$ext = getFileExt($template); |
|||
$path .= DIRECTORY_SEPARATOR . ltrim($template,'/'); |
|||
if( $ext != config('view.view_suffix')){ |
|||
$path .= '.'.config('view.view_suffix'); |
|||
} |
|||
return $path ; |
|||
} |
|||
|
|||
/** |
|||
* 常量替换 |
|||
* @param $siteId |
|||
* @param $lang |
|||
*/ |
|||
protected function _initializeViewDesign($siteId,$lang) |
|||
{ |
|||
$viewReplaceStr = [ |
|||
'__TMPL__' => "/design/designPage", |
|||
'__STATIC__' => empty($this->settingData['static_file']) ? "/design/designPage/static" : $this->settingData['static_file'] , |
|||
]; |
|||
|
|||
View::engine()->config([ |
|||
'view_path' => CMS_ROOT . $this->designBase . DIRECTORY_SEPARATOR, |
|||
'tpl_replace_string' => $viewReplaceStr, |
|||
'display_cache' => false, |
|||
'tpl_cache' => false, |
|||
]); |
|||
} |
|||
|
|||
/** |
|||
* 加载模板输出(system_file) |
|||
* @access protected |
|||
* @param string $template 模板文件名 |
|||
* @param array $vars 模板输出变量 |
|||
* @return mixed |
|||
*/ |
|||
protected function fetchDesignPage(string $template = '', array $vars = []) |
|||
{ |
|||
$template = $this->parseTemplateDesignPage($template); |
|||
$this->_initializeViewDesignPage($this->realSiteId,$this->lang); |
|||
|
|||
return View::fetch($template, $vars); |
|||
} |
|||
|
|||
/** |
|||
* |
|||
* 定位模板 |
|||
* @param $template |
|||
* @return string |
|||
*/ |
|||
private function parseTemplateDesignPage($template): string |
|||
{ |
|||
$path = CMS_ROOT . "design/designPage/{$this->realSiteId}/{$this->lang}" . DIRECTORY_SEPARATOR; |
|||
$ext = getFileExt($template); |
|||
$path .= DIRECTORY_SEPARATOR . ltrim($template,'/'); |
|||
if( $ext != config('view.view_suffix')){ |
|||
$path .= '.'.config('view.view_suffix'); |
|||
} |
|||
return $path ; |
|||
} |
|||
|
|||
/** |
|||
* 常量替换 |
|||
* @param $siteId |
|||
* @param $lang |
|||
*/ |
|||
protected function _initializeViewDesignPage($siteId,$lang) |
|||
{ |
|||
$viewReplaceStr = [ |
|||
'__TMPL__' => "/design/designPage/{$siteId}/{$lang}", |
|||
'__STATIC__' => empty($this->settingData['static_file']) ? "/design/designPage/{$siteId}/{$lang}/static" : $this->settingData['static_file'] , |
|||
]; |
|||
|
|||
View::engine()->config([ |
|||
'view_path' => CMS_ROOT . $this->designBase . DIRECTORY_SEPARATOR . $siteId. DIRECTORY_SEPARATOR .$this->lang.DIRECTORY_SEPARATOR, |
|||
'tpl_replace_string' => $viewReplaceStr, |
|||
'display_cache' => false, |
|||
'tpl_cache' => false, |
|||
]); |
|||
} |
|||
} |
|||
@ -0,0 +1,140 @@ |
|||
<?php |
|||
|
|||
namespace app\controller\frontend; |
|||
|
|||
use app\model\BigField; |
|||
use app\model\Category; |
|||
use app\model\Theme; |
|||
use app\model\ThemeFile; |
|||
use app\model\WebsiteSetting; |
|||
use app\validate\DesignValidate; |
|||
use think\exception\ValidateException; |
|||
|
|||
class DesignController extends DesignBaseController |
|||
{ |
|||
public function index() |
|||
{ |
|||
$param = $this->request->param(); |
|||
$param['html'] = $param['html'] ?? ''; |
|||
// 数据验证
|
|||
try{ |
|||
validate(DesignValidate::class)->scene('index')->check($param); |
|||
}catch(ValidateException $e){ |
|||
return jsonReturn(-1, $e->getError()); |
|||
} |
|||
|
|||
// 获取当前站的模板目录
|
|||
$themeModel = new Theme(); |
|||
$theme = $themeModel->where([ |
|||
['website_id', '=', $param['website_id']], |
|||
['lang', '=', $param['lang']], |
|||
['is_active', '=', 1], |
|||
])->value('theme'); |
|||
|
|||
if (empty($theme)) { |
|||
return jsonReturn(-1, lang('当前站点没有激活的模板,请去安装模板')); |
|||
} |
|||
|
|||
//search for html files in demo and my-pages folders
|
|||
// $htmlFiles = glob("{design/designPage/*\/*.html,design/designPage/*.html,design/demo/*\/*.html,design/demo/*.html}", GLOB_BRACE);
|
|||
// $htmlFiles = glob("{design/designPage/*\/*.html,design/designPage/*.html}", GLOB_BRACE);
|
|||
// $htmlFiles = glob("{themes/hc_original/{$theme}/*.html,themes/hc_original/{$theme}/*\/*.html}", GLOB_BRACE);
|
|||
//
|
|||
//
|
|||
// $files = [];
|
|||
// foreach ($htmlFiles as $file) {
|
|||
// $file = mb_substr($file, 7);
|
|||
// $pathInfo = pathinfo($file);
|
|||
// if (in_array($pathInfo['basename'], array('new-page-blank-template.html', 'editor.html'))) continue;//skip template files
|
|||
//
|
|||
// $filename = $pathInfo['filename'];
|
|||
//// var_dump($filename);
|
|||
//
|
|||
// $folder = preg_replace('@/.+?$@', '', $pathInfo['dirname']);
|
|||
// $subfolder = preg_replace('@^.+?/@', '', $pathInfo['dirname']);
|
|||
//
|
|||
// if ($filename == 'index' && $subfolder) {
|
|||
//// $filename = $subfolder;
|
|||
// }
|
|||
// $url = $pathInfo['dirname'] . '/' . $pathInfo['basename'];
|
|||
// $name = ucfirst($filename);
|
|||
//
|
|||
//// dump($pathInfo['basename']);
|
|||
//
|
|||
// $files[] = [
|
|||
// 'name' => $name,
|
|||
// 'file' => $filename,
|
|||
// 'title' => $name,
|
|||
//// 'url' => '../themes/' . $url,
|
|||
// 'url' => '/' . $pathInfo['basename'],
|
|||
// 'folder' => '../themes/' . $folder,
|
|||
// ];
|
|||
//
|
|||
//// $files .= "{name:'$name', file:'$filename', title:'$name', url: '$url', folder:'$folder'},";
|
|||
// }
|
|||
|
|||
// 获取当前网站所有有模板的栏目的路由
|
|||
$category = new Category(); |
|||
$list = $category->where([ |
|||
['website_id', '=', $param['website_id']], |
|||
['lang', '=', $param['lang']], |
|||
['type', 'in', [4]], |
|||
['status', '=', 1], |
|||
['list_tpl', '<>', ''], |
|||
])->field('id, title, list_tpl, alias')->group('list_tpl')->select()->toArray(); |
|||
|
|||
if (empty($list)) { |
|||
return jsonReturn(-1, lang('当前站点已安装模板,但没有栏目使用单页模板,如当前站是子站,需要编辑父站点的数据,请回后台切换至父站点')); |
|||
} |
|||
|
|||
$files = []; |
|||
$initPage = ''; |
|||
foreach ($list as $value) { |
|||
$pathInfo = pathinfo($value['list_tpl']); |
|||
|
|||
if ($param['html'] == $value['list_tpl']) { |
|||
$initPage = $pathInfo['filename']; |
|||
} |
|||
|
|||
$file = [ |
|||
'name' => $pathInfo['filename'], |
|||
'file' => $value['list_tpl'], |
|||
'title' => $value['list_tpl'], |
|||
// 'url' => '../themes/' . $url,
|
|||
'url' => $value['alias'], |
|||
'folder' => $value['title'], |
|||
]; |
|||
$files[] = $file; |
|||
} |
|||
// dd($files);
|
|||
|
|||
$where = [ |
|||
'website_id' => $param['website_id'], |
|||
'lang' => $param['lang'], |
|||
]; |
|||
// 获取系统配置
|
|||
$websiteSetting = new WebsiteSetting(); |
|||
$res = $websiteSetting->getWebsiteSetting($where); |
|||
$res['data'] = $res['data']->toArray(); |
|||
$setting = $res['data']['setting']; |
|||
$initPage = $initPage ?: $files[0]['name']; |
|||
|
|||
$data = [ |
|||
'website_id' => $param['website_id'], |
|||
'lang' => $param['lang'], |
|||
'setting' => $setting, |
|||
'pages' => json_encode($files), |
|||
'init_page' => $initPage, |
|||
]; |
|||
$this->assign($data); |
|||
|
|||
return $this->fetchDesign('editor'); |
|||
} |
|||
|
|||
public function getDesignHtml() |
|||
{ |
|||
$param = $this->request->param(); |
|||
|
|||
return $this->fetchDesign($param['html_path']); |
|||
} |
|||
} |
|||
@ -0,0 +1,128 @@ |
|||
<?php |
|||
declare (strict_types = 1); |
|||
|
|||
namespace app\controller\frontend; |
|||
|
|||
use app\exception\ModelEmptyException; |
|||
use app\exception\ModelException; |
|||
use app\model\Category; |
|||
use app\model\SysSetting; |
|||
use app\service\ContentService; |
|||
use app\validate\ContentValidate; |
|||
use think\exception\HttpException; |
|||
use think\exception\ValidateException; |
|||
use think\facade\Cache; |
|||
use think\facade\Log; |
|||
use think\facade\View; |
|||
|
|||
class DetailController extends BaseController |
|||
{ |
|||
|
|||
/** |
|||
* 内容详情 |
|||
* @param Category $Category |
|||
* @return mixed |
|||
* @throws \app\exception\ModelEmptyException |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function index(Category $Category) |
|||
{ |
|||
$id = (int)input('id'); |
|||
$cid = (int)input('cid'); |
|||
$cateCacheKey = 'hc_detail_cate_' .$this->sellerId.'_'.$this->siteId.'_'.$this->lang.'_'. $cid ; |
|||
$category = cache($cateCacheKey); |
|||
if(empty($category)){ |
|||
try { |
|||
$category = $Category->getCategory(['id' => $cid, 'seller_id' => $this->sellerId, 'website_id' => $this->siteId,'lang' => $this->lang],['module.moduleField'])['data']->toArray(); |
|||
Cache::set($cateCacheKey,$category); |
|||
}catch (ModelEmptyException $me){ |
|||
$category = $Category->getCategory(['id' => $cid, 'seller_id' => $this->sellerId, 'website_id' => $this->realSiteId,'lang' => $this->lang],['module.moduleField'])['data']->toArray(); |
|||
Cache::set($cateCacheKey,$category); |
|||
} |
|||
} |
|||
if (!empty($category['content'])) { |
|||
$category['content'] = htmlspecialchars_decode($category['content']); |
|||
} |
|||
$contentService = new ContentService(); |
|||
$param = [ |
|||
'cate' => $category, |
|||
'id' => $id, |
|||
'seller_id' => $this->sellerId, |
|||
'website_id' => $this->siteId, |
|||
'lang' => $this->lang, |
|||
'field' => '*', |
|||
'main_content' => 1 |
|||
]; |
|||
$content = $contentService->getContentDetail($param); |
|||
$content->hits = $content->hits + 1; |
|||
$content->save(); |
|||
|
|||
if (!empty($content['content'])) { |
|||
$content['content'] = htmlspecialchars_decode($content['content']); |
|||
} |
|||
|
|||
$where = [ |
|||
'group' => 'company', |
|||
'title' => 'huocms_powerby', |
|||
]; |
|||
$huocmsPowerby = SysSetting::where($where)->value('value'); |
|||
if ($huocmsPowerby) { |
|||
$category['seo_title'] = $content['seo_title'] ?: $content['title']; |
|||
$category['seo_keyword'] = $content['seo_keyword'] ?: $content['title']; |
|||
$category['seo_description'] = $content['seo_description'] ?: $content['title']; |
|||
$category['seo_title'] .= "-$huocmsPowerby"; |
|||
$category['seo_keyword'] .= ",$huocmsPowerby"; |
|||
$category['seo_description'] .= ",$huocmsPowerby"; |
|||
} |
|||
|
|||
$this->assign('hc_content',$content->toArray()); |
|||
$this->assign('current_cate',$category); |
|||
$this->assign('root_domain',$this->rootDomain); |
|||
$template = !empty($content['detail_tpl']) ? $content['detail_tpl'] : $category['detail_tpl']; |
|||
return $this->fetch($template); |
|||
} |
|||
|
|||
/** |
|||
* 文件预览 |
|||
* @throws ModelException |
|||
* @throws ModelEmptyException |
|||
*/ |
|||
public function preview() |
|||
{ |
|||
$param = $this->request->only(['id','cid','lang'=>$this->lang,'website_id'=>$this->realSiteId]); |
|||
$Category = new Category(); |
|||
$category = $Category->getCustomArrayData(['id' => $param['cid'], 'website_id' => $param['website_id'],'lang' => $param['lang']],['module.moduleField'])['data']; |
|||
if(empty($category)){ |
|||
Log::error("栏目不存在"); |
|||
throw new HttpException(404,'资源不存在'); |
|||
} |
|||
$param['cate'] = $category; |
|||
$param['seller_id'] = $this->sellerId; |
|||
$param['field'] = '*'; |
|||
$param['main_content'] = 1; |
|||
if (!empty($category['content'])) { |
|||
$category['content'] = htmlspecialchars_decode($category['content']); |
|||
} |
|||
$contentService = new ContentService(); |
|||
$content = $contentService->getPreviewContent($param); |
|||
if(empty($content)){ |
|||
Log::error("内容不存在"); |
|||
throw new HttpException(404,'资源不存在'); |
|||
} |
|||
if (!empty($content['content'])) { |
|||
$content['content'] = htmlspecialchars_decode($content['content']); |
|||
} |
|||
if($category['id'] == 41 && empty($content['content'])){ |
|||
if(empty($content['main_content']['file']['url'])){ |
|||
return redirect('/404.html'); |
|||
}else{ |
|||
$url = $content['main_content']['file']['url']; |
|||
return redirect($url); |
|||
} |
|||
} |
|||
View::assign('hc_content',$content->toArray()); |
|||
View::assign('current_cate',$category); |
|||
$template = !empty($content['detail_tpl']) ? $content['detail_tpl'] : $category['detail_tpl']; |
|||
return $this->fetch($template); |
|||
} |
|||
} |
|||
@ -0,0 +1,274 @@ |
|||
<?php |
|||
|
|||
namespace app\controller\frontend; |
|||
|
|||
use app\model\Attachment; |
|||
use app\model\customModel\Down; |
|||
use app\model\DiyForm; |
|||
use app\model\SubContent; |
|||
use app\model\SysSetting; |
|||
use app\service\upload\Upload; |
|||
use think\facade\Db; |
|||
|
|||
class FormController extends BaseController |
|||
{ |
|||
protected $type = [ |
|||
'file' => 4, |
|||
'image' => 2, |
|||
'video' => 3, |
|||
'mp3' => 5, |
|||
'zip' => 1, |
|||
]; |
|||
|
|||
public function index() |
|||
{ |
|||
$code = $this->request->param('code'); |
|||
|
|||
$formModel = new DiyForm(); |
|||
$formData = $formModel->where('code', $code)->findOrEmpty(); |
|||
if (empty($formData)) { |
|||
$this->to404(); |
|||
} |
|||
|
|||
$this->assign('formData', $formData); |
|||
|
|||
$html = $this->formHtml(); |
|||
|
|||
$html = str_replace(['{formData_name}', '{formData_designContent}', '{formData_designOption}', '{formData_code}'], |
|||
[$formData['name'],$formData['design_content'],$formData['design_option'],$formData['code']], $html); |
|||
|
|||
return $html; |
|||
} |
|||
|
|||
public function save() |
|||
{ |
|||
$param = $this->request->param(); |
|||
|
|||
$code = $param['code']; |
|||
unset($param['code']); |
|||
$formModel = new DiyForm(); |
|||
$formData = $formModel->where('code', $code)->findOrEmpty(); |
|||
if (empty($formData)) { |
|||
return jsonReturn(-1, lang('提交失败')); |
|||
} |
|||
|
|||
$tableName = 'diyform_' . $formData['table']; |
|||
|
|||
foreach ($param as &$value) { |
|||
if (is_array($value)) { |
|||
$value = implode(',', $value); |
|||
} |
|||
} |
|||
|
|||
$param['ip'] = $this->request->ip(); |
|||
$param['user_agent'] = $this->request->header('user-agent'); |
|||
|
|||
Db::name($tableName)->insert($param); |
|||
|
|||
return jsonReturn(0, lang('提交成功')); |
|||
} |
|||
|
|||
// 上传文件
|
|||
public function uploadFormFile() |
|||
{ |
|||
if(!request()->isPost()){ |
|||
return jsonReturn(-1, lang('请求错误')); |
|||
} |
|||
|
|||
$file = request()->file('file'); |
|||
if(empty($file)){ |
|||
return jsonReturn(-2,lang('文件不能为空')); |
|||
} |
|||
$seller_id = $this->sellerId; |
|||
// 查看文件类型
|
|||
$fileName = $file->getOriginalName(); |
|||
$fileExt = $file->getOriginalExtension(); |
|||
$file_type = fileFormat($fileName); |
|||
$fileType = $this->type[$file_type]; |
|||
// 附件大小和类型验证
|
|||
// 获取上传配置
|
|||
$Settings = new SysSetting(); |
|||
$uploadSetting = $Settings->getAllCustomArrayData(['parent_id'=>1,'group'=>'upload','status'=>1],'id desc','id,group,title,value')['data']; |
|||
$uploadSetting = getColumnForKeyArray($uploadSetting,'title'); |
|||
$limitSize = $uploadSetting[$file_type.'_size']['value'] * 1024; // byte
|
|||
$fileSize = $file->getSize(); // 单位byte
|
|||
if($fileSize > $limitSize){ |
|||
return jsonReturn(-1,lang('文件过大,请修改上传限制或者替换小的文件')); |
|||
} |
|||
$extArr = explode(',',$uploadSetting[$file_type.'_ext']['value']); |
|||
if(!in_array($fileExt,$extArr)){ |
|||
return jsonReturn(-2,lang('文件格式错误,请重新上传')); |
|||
} |
|||
// 文件信息提取
|
|||
$where = [ |
|||
'seller_id' => $seller_id, |
|||
'group' => 'upload', |
|||
'title' => 'storage' |
|||
]; |
|||
$place = new SysSetting(); |
|||
$type = $place->getSysSetting($where)['data']->toArray()['value']; |
|||
|
|||
$upload = new Upload(); |
|||
$info = $upload->create($file,$seller_id, $type,$file_type); |
|||
|
|||
if ($info) { |
|||
$uploadInfo = $upload->getUploadFileInfo(); |
|||
if ($uploadInfo['code'] == 0) { |
|||
$uploadInfo['data']['type'] = $fileType; |
|||
$uploadInfo['data']['size'] = round($fileSize / 1024,2); |
|||
$uploadInfo['data']['mime_type'] = $fileExt; |
|||
} |
|||
return json($uploadInfo); |
|||
}else{ |
|||
return jsonReturn(-1, lang('上传失败请重新尝试')); |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 下载文件 |
|||
* @return void |
|||
*/ |
|||
public function downFile() |
|||
{ |
|||
$param = $this->request->param(); |
|||
|
|||
if (empty($param)) { |
|||
$this->to404(); |
|||
} |
|||
|
|||
$id = intval($param['id']); |
|||
$downFlag = false; // 可下载标识
|
|||
$downModel = new Down(); |
|||
$downData = $downModel->where('sub_id', '=', $id)->findOrEmpty(); |
|||
if (empty($downData)) { |
|||
$this->to404(); |
|||
} |
|||
|
|||
$subContentModel = new SubContent(); |
|||
$downData['title'] = $subContentModel->where('id', '=', $downData['sub_id'])->value('title'); |
|||
$formData = []; |
|||
if ($downData['is_form'] == '是') { |
|||
$formModel = new DiyForm(); |
|||
$formData = $formModel->where('id', '=', $downData['form_id'])->where('status', '=', 2)->findOrEmpty(); |
|||
if (empty($formData)) { |
|||
$this->to404(); |
|||
} |
|||
$tableName = 'diyform_' . $formData['table']; |
|||
|
|||
$where = [ |
|||
['sub_id', '=', $id], |
|||
['ip', '=', $this->request->ip()], |
|||
['user_agent', '=', $this->request->header('user-agent')], |
|||
['visitor_id', '=', $this->request->param('visitor_id')] |
|||
]; |
|||
|
|||
$id = Db::name($tableName)->where($where)->value('id'); |
|||
|
|||
if (!empty($id)) { |
|||
$downFlag = true; |
|||
} |
|||
} else { |
|||
$downFlag = true; |
|||
} |
|||
|
|||
if ($downFlag) { |
|||
$fileModel = new Attachment(); |
|||
$downData['fileArr'] = $fileModel->where('id', 'in', json_decode($downData['file'], true))->select()->toArray(); |
|||
} |
|||
|
|||
$this->assign('downData', $downData); |
|||
$this->assign('formData', $formData); |
|||
$this->assign('downFlag', $downFlag); |
|||
$this->assign('visitor_id', $this->request->param('visitor_id')); |
|||
|
|||
return $this->fetchSystem('down/index'); |
|||
} |
|||
|
|||
/** |
|||
* 问卷html |
|||
* @return string |
|||
*/ |
|||
protected function formHtml() |
|||
{ |
|||
$html = <<<EOF |
|||
<!DOCTYPE html> |
|||
<html lang="en"> |
|||
<head> |
|||
<meta charset="UTF-8"> |
|||
<meta http-equiv="X-UA-Compatible" content="IE=edge"> |
|||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
|||
<title>{formData_name}</title> |
|||
</head> |
|||
<body> |
|||
<div class="container" style="display: block;max-width:1200px;margin: 0 auto; "> |
|||
<div id="app-3" class="formBox" style="padding-top: 50px"> |
|||
<template> |
|||
<form-create |
|||
v-model="fapi" |
|||
:rule="rule" |
|||
:option="option" |
|||
@submit="onSubmit" |
|||
></form-create> |
|||
</template> |
|||
</div> |
|||
</div> |
|||
</body> |
|||
<!-- import Vue.js --> |
|||
<!-- <script src="//vuejs.org/js/vue.min.js"></script>--> |
|||
<!-- 生产环境版本,优化了尺寸和速度 --> |
|||
<script src="/system_file/form/vue@2"></script> |
|||
<!-- import stylesheet --> |
|||
<link rel="stylesheet" href="/system_file/form/index.css"> |
|||
<!-- import element --> |
|||
<script src="/system_file/form/index.js"></script> |
|||
<!-- import form-create/element --> |
|||
<script src="/system_file/form/form-create.min.js"></script> |
|||
<!-- import form-create/designer --> |
|||
<script src="/system_file/form/index.min.js"></script> |
|||
|
|||
<script src="/system_file/form/jquery-3.4.1.min.js"></script> |
|||
<script> |
|||
//FcDesigner 生成的`JSON`
|
|||
// const FcDesignerRule = '[{"type":"input","field":"cuk5qqdw3umc","title":"输入框","info":"","_fc_drag_tag":"input","hidden":false,"display":true}]';
|
|||
const FcDesignerRule = '{formData_designContent}'; |
|||
|
|||
//FcDesigner 生成的`options`
|
|||
// const FcDesignerOptions = '{"form":{"labelPosition":"right","size":"mini","labelWidth":"125px","hideRequiredAsterisk":false,"showMessage":true,"inlineMessage":false}}';
|
|||
const FcDesignerOptions = '{formData_designOption}'; |
|||
|
|||
const code = '{formData_code}'; |
|||
|
|||
console.log(FcDesignerOptions, 'asdasdasdasdsada') |
|||
|
|||
var app3 = new Vue({ |
|||
el: '#app-3', |
|||
data: { |
|||
fapi: null, |
|||
rule: formCreate.parseJson(FcDesignerRule), |
|||
option: formCreate.parseJson(FcDesignerOptions) |
|||
}, |
|||
methods: { |
|||
onSubmit (formData) { |
|||
formData.code = code |
|||
//todo 提交表单
|
|||
console.log(formData, '提交表单提交表单提交表单') |
|||
|
|||
$.post('/addFormData.html', formData, function(res) { |
|||
console.log(res, '接口返回'); |
|||
if (res.code == 0) { |
|||
alert('提交成功') |
|||
} else { |
|||
alert('提交失败') |
|||
} |
|||
}); |
|||
} |
|||
} |
|||
}) |
|||
</script> |
|||
|
|||
</html> |
|||
EOF; |
|||
|
|||
return $html; |
|||
} |
|||
} |
|||
@ -0,0 +1,105 @@ |
|||
<?php |
|||
declare (strict_types = 1); |
|||
|
|||
namespace app\controller\frontend; |
|||
|
|||
use app\model\Inquiry; |
|||
use app\model\SysSetting; |
|||
use app\model\Website; |
|||
use app\service\EmailService; |
|||
use app\validate\frontend\InquiryValidate; |
|||
use GuzzleHttp\Client; |
|||
use think\exception\ValidateException; |
|||
use think\facade\Cache; |
|||
use think\facade\Log; |
|||
|
|||
class InquiryController extends BaseController |
|||
{ |
|||
/** |
|||
* 保存新建的资源 |
|||
* |
|||
* @return \think\Response |
|||
* @throws \app\exception\ModelException |
|||
* @throws \app\exception\ModelEmptyException |
|||
*/ |
|||
public function save(): \think\Response |
|||
{ |
|||
// 获取用户的 IP 地址或其他标识
|
|||
$identifier = request()->ip(); |
|||
|
|||
// 设置限制时间窗口(例如:1分钟)
|
|||
$window = 60; |
|||
|
|||
// 设置允许的最大请求数
|
|||
$maxRequests = 5; |
|||
|
|||
// 生成存储请求计数的缓存键
|
|||
$cacheKey = 'request_rate_limit:' . $identifier; |
|||
|
|||
// 获取当前时间内已发送的请求次数
|
|||
$requestCount = (int)Cache::get($cacheKey,0); |
|||
|
|||
// 如果请求次数超过限制,则返回错误响应
|
|||
if ($requestCount >= $maxRequests) { |
|||
return json(['status' => 'error', 'message' => '请求频率过高,请稍后再试']); |
|||
} |
|||
|
|||
$param = request()->param(); |
|||
if(empty($param)){ |
|||
return jsonReturn(-1,lang('请填写询盘信息')); |
|||
} |
|||
try{ |
|||
validate(InquiryValidate::class)->check($param); |
|||
}catch (ValidateException $e){ |
|||
return jsonReturn(-1, $e->getError()); |
|||
} |
|||
// 获取询盘收件箱
|
|||
$webSite = new Website(); |
|||
$site = $webSite->getWebsite(['domain' => $this->domain],['inquiryEmail'])['data']->toArray(); |
|||
$email = []; |
|||
if(!empty($site['inquiryEmail'])){ |
|||
$email = array_column($site['inquiryEmail'],'email'); |
|||
} |
|||
$inquiry = new Inquiry(); |
|||
$param['seller_id'] = $this->sellerId; |
|||
$param['website_id'] = $this->siteId; |
|||
$param['ip'] = request()->ip(); |
|||
$param['inquiry_type'] = 1; |
|||
$res = $inquiry -> addInquiry($param); |
|||
try{ |
|||
// 获取suwork配置
|
|||
$sysSetting = new SysSetting(); |
|||
$setting = $sysSetting->getAllSysSetting([['title','like','suwork_%']])['data']->toArray(); |
|||
$key = array_column($setting,'title'); |
|||
$setting = array_combine($key,$setting); |
|||
if(!empty($setting['suwork_appid']['value']) && !empty($setting['suwork_secret']['value']) && !empty($setting['suwork_api']['value'])){ |
|||
$suworkAccept = config('system.suwork_accept'); |
|||
$data = array_intersect_key($param,$suworkAccept); |
|||
$data['referer_type'] = 1; |
|||
$data['referer_web'] = empty($_SERVER['HTTP_REFERER']) ? '未知' : $_SERVER['HTTP_REFERER']; |
|||
$data['appid'] = $setting['suwork_appid']['value']; |
|||
$data['secret'] = $setting['suwork_secret']['value']; |
|||
$data['inquiry_time'] = date('Y-m-d H:i:s',time()); |
|||
$option = [ |
|||
'form_params' => $data, |
|||
]; |
|||
$client = new Client(); |
|||
$response = $client->post($setting['suwork_api']['value'],$option); |
|||
$result = json_decode($response->getBody()->getContents(),true); |
|||
if($result['code'] != 0){ |
|||
Log::record($result['msg'],'info'); |
|||
} |
|||
} |
|||
// 发送邮件
|
|||
$EmailService = new EmailService(); |
|||
$EmailService->sendEmail($this->domain.lang('网站收到询盘'),$email); |
|||
}catch (\Exception $e){ |
|||
Log::error($e->getMessage()); |
|||
return jsonReturn(0,lang('提交成功'),1); |
|||
} |
|||
// 增加请求计数
|
|||
Cache::set($cacheKey,$requestCount + 1, $window); |
|||
return json($res); |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,55 @@ |
|||
<?php |
|||
declare (strict_types = 1); |
|||
|
|||
namespace app\controller\frontend; |
|||
|
|||
use app\exception\ModelEmptyException; |
|||
use app\model\Category; |
|||
use app\model\SysSetting; |
|||
|
|||
class ListController extends BaseController |
|||
{ |
|||
|
|||
/** |
|||
* @param Category $Category |
|||
* @return mixed |
|||
* @throws \app\exception\ModelEmptyException |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function index(Category $Category) |
|||
{ |
|||
$id = (int)input('id'); |
|||
$with=['thumbnail'=>function($q){ |
|||
$q->field('id,name,url,type'); |
|||
},'banner'=>function($q){ |
|||
$q->field('id,name,url,type'); |
|||
} |
|||
]; |
|||
try { |
|||
$category = $Category->getCategory(['id' => $id, 'seller_id' => $this->sellerId, 'website_id' => $this->siteId,'lang' => $this->lang],$with)['data']->toArray(); |
|||
}catch (ModelEmptyException $me){ |
|||
$category = $Category->getCategory(['id' => $id, 'seller_id' => $this->sellerId, 'website_id' => $this->realSiteId,'lang' => $this->lang],$with)['data']->toArray(); |
|||
} |
|||
|
|||
if (!empty($category['content'])) { |
|||
$category['content'] = htmlspecialchars_decode($category['content']); |
|||
} |
|||
|
|||
$where = [ |
|||
'group' => 'company', |
|||
'title' => 'huocms_powerby', |
|||
]; |
|||
$huocmsPowerby = SysSetting::where($where)->value('value'); |
|||
if ($huocmsPowerby) { |
|||
$category['seo_title'] .= " - $huocmsPowerby"; |
|||
$category['seo_keywords'] .= ",$huocmsPowerby"; |
|||
$category['seo_description'] .= ",$huocmsPowerby"; |
|||
} |
|||
|
|||
$this->assign('current_cate',$category); |
|||
$this->assign('root_domain',$this->rootDomain); |
|||
$template = $category['list_tpl']; |
|||
return $this->fetch($template); |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,67 @@ |
|||
<?php |
|||
declare (strict_types = 1); |
|||
|
|||
namespace app\controller\frontend; |
|||
|
|||
use app\model\Attachment; |
|||
use app\model\Resume; |
|||
use app\service\upload\Upload; |
|||
use app\validate\frontend\ResumeValidate; |
|||
use think\exception\ValidateException; |
|||
use think\Request; |
|||
|
|||
class ResumeController extends BaseController |
|||
{ |
|||
private $allowExtension = [ |
|||
'pdf','doc','docx' |
|||
]; |
|||
|
|||
/** |
|||
* 保存新建的资源 |
|||
* |
|||
* @param \think\Request $request |
|||
* @return \think\Response |
|||
* @throws \app\exception\ModelException |
|||
*/ |
|||
public function save(Request $request,Upload $upload) |
|||
{ |
|||
//
|
|||
$param = $request->only(['username','phone','email','remark']); |
|||
try{ |
|||
validate(ResumeValidate::class)->check($param); |
|||
}catch (ValidateException $e){ |
|||
return jsonReturn(-1, $e->getError()); |
|||
} |
|||
$file = $request->file('resume_file'); |
|||
if(empty($file)){ |
|||
return jsonReturn(-1,'简历不能为空'); |
|||
} |
|||
$extension = strtolower($file->getOriginalExtension()); |
|||
if(!in_array($extension,$this->allowExtension)){ |
|||
// return jsonReturn(-1,'简历文件格式不对,请上传pdf或者word文件');
|
|||
} |
|||
// 查看文件类型
|
|||
$fileName = $file->getOriginalName(); |
|||
$file_type = fileFormat($fileName); |
|||
$upload = new Upload(); |
|||
$info = $upload->create($file,$this->sellerId, 'local',$file_type); |
|||
if(!$info){ |
|||
jsonReturn(-1,'简历上传失败,请重新尝试'); |
|||
} |
|||
$info = $upload->getUploadFileInfo()['data']; |
|||
$attachment = new Attachment(); |
|||
$info['size'] = round($file->getSize() / 1024,2); |
|||
$info['seller_id'] = $this->sellerId; |
|||
$info['attachment_cate_id'] = 0; |
|||
$info['type'] = 4; |
|||
$res = $attachment->addCustomData($info)['data']; |
|||
if(empty($res)){ |
|||
jsonReturn(-2,'简历上传失败,请重新尝试'); |
|||
} |
|||
$resume = new Resume(); |
|||
$param['website_id'] = $this->siteId; |
|||
$param['attachment_id'] = $res['id']; |
|||
$res = $resume -> addCustomData($param); |
|||
return json($res); |
|||
} |
|||
} |
|||
@ -0,0 +1,89 @@ |
|||
<?php |
|||
|
|||
|
|||
namespace app\controller\frontend; |
|||
|
|||
|
|||
use app\model\Category; |
|||
use app\model\CategorySubContent; |
|||
use app\model\SubContent; |
|||
use app\model\SysSetting; |
|||
|
|||
class SearchController extends BaseController |
|||
{ |
|||
/** |
|||
* @throws \app\exception\ModelEmptyException |
|||
* @throws \app\exception\ModelException |
|||
* @throws \think\db\exception\DbException |
|||
*/ |
|||
public function index(Category $Category) |
|||
{ |
|||
//拿到搜索页数据,主要为了拿seo数据
|
|||
$with=['thumbnail'=>function($q){ |
|||
$q->field('id,name,url,type'); |
|||
},'banner'=>function($q){ |
|||
$q->field('id,name,url,type'); |
|||
} |
|||
]; |
|||
$where = [ |
|||
['seller_id', '=', $this->sellerId], |
|||
['website_id', '=', $this->realSiteId], |
|||
['is_search', '=', 1], |
|||
]; |
|||
$category = $Category->getCategory($where,$with)['data']->toArray(); |
|||
$settingWhere = [ |
|||
'group' => 'company', |
|||
'title' => 'huocms_powerby', |
|||
]; |
|||
$huocmsPowerby = SysSetting::where($settingWhere)->value('value'); |
|||
if ($huocmsPowerby) { |
|||
$category['seo_title'] .= " - $huocmsPowerby"; |
|||
$category['seo_keywords'] .= ",$huocmsPowerby"; |
|||
$category['seo_description'] .= ",$huocmsPowerby"; |
|||
} |
|||
$this->assign('current_cate',$category); |
|||
|
|||
//搜索
|
|||
$param = $this->request->param(); |
|||
$keywords = $param['q']; |
|||
$this->assign('keywords',$keywords); |
|||
|
|||
// 获取可以查询的栏目
|
|||
$category = new Category(); |
|||
$categories = $category -> getAllCustomArrayData($where,'id desc','id')['data']; |
|||
$cateIds = array_column($categories,'id'); |
|||
|
|||
$cateSub = new CategorySubContent(); |
|||
$cateSubWhere = [ |
|||
['category_id','in',$cateIds] |
|||
]; |
|||
$cateSubCon = $cateSub->getAllCategorySubContent($cateSubWhere)['data']; |
|||
$subIds = array_column($cateSubCon,'sub_content_id'); |
|||
|
|||
$SubContent = new SubContent(); |
|||
$content = $SubContent->with(['thumbnail'=>function($q){ |
|||
$q->field('id,name,url,type'); |
|||
},'category'])->where(['seller_id'=>$this->sellerId,'is_del'=>1]); |
|||
if(!empty($param['q'])){ |
|||
$content = $content -> whereLike('title|description|sub_title','%' . $keywords . '%'); |
|||
} |
|||
$param['siteId'] = $this->realSiteId; |
|||
$param['sellerId'] = $this->sellerId; |
|||
$data = $content->whereIn('id',$subIds) |
|||
->order('id','desc') |
|||
->paginate([ |
|||
'page' => $param['page'] ?? 1, |
|||
'list_rows' => $param['limit'] ?? 10, |
|||
])->each(function (&$item)use($param){ |
|||
if(!empty($item['category'])) { |
|||
$item['category'] = $item->toArray()['category']; |
|||
$item['category_id'] = $item['category'][0]['id']; |
|||
} |
|||
$item['thumbnail'] = $item->toArray()['thumbnail']; |
|||
}); |
|||
$data->appends(['q' => $keywords]); |
|||
$this->assign('list', $data->items()); |
|||
$this->assign('list_page', $data->render()); |
|||
return $this->fetch(config('view.view_search_page_name')); |
|||
} |
|||
} |
|||
@ -0,0 +1,55 @@ |
|||
<?php |
|||
declare (strict_types = 1); |
|||
|
|||
namespace app\controller\frontend; |
|||
|
|||
class SeoController extends BaseController |
|||
{ |
|||
|
|||
/** |
|||
* robots文件读取 |
|||
* |
|||
*/ |
|||
public function getRobots() |
|||
{ |
|||
$filename = $this->siteId . '_robots.txt'; |
|||
$path = app() -> getRootPath() . 'public/robots/' . $filename ; |
|||
if(!hcFileExist($path)){ |
|||
$sysRobots = app() -> getRootPath() . 'public/robots/robots.txt' ; |
|||
touch($path); |
|||
copy($sysRobots,$path); |
|||
} |
|||
header("Content-type:text/html;"); |
|||
$content = file_get_contents($path); |
|||
$content = '<pre>' . str_replace("\n",'<pre>',$content); |
|||
echo $content; |
|||
exit; |
|||
} |
|||
|
|||
/** |
|||
* sitemap xml文件读取 |
|||
* |
|||
*/ |
|||
public function getSitemapXml() |
|||
{ |
|||
$filename = $this->siteId . '_sitemap.xml'; |
|||
$path = app() -> getRootPath() . 'public/xml/' . $filename; |
|||
$content = @file_get_contents($path); |
|||
header("Content-type:text/xml;"); |
|||
echo $content; |
|||
exit; |
|||
} |
|||
|
|||
/** |
|||
* sitemap html文件读取 |
|||
* |
|||
*/ |
|||
public function getSitemapHtml() |
|||
{ |
|||
$filename = $this->siteId . '_sitemap.html'; |
|||
$path = app() -> getRootPath() . 'public/sitemap_html/' . $filename; |
|||
echo @file_get_contents($path); |
|||
exit; |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,59 @@ |
|||
<?php |
|||
declare (strict_types = 1); |
|||
|
|||
namespace app\controller\frontend; |
|||
|
|||
use app\model\Tag; |
|||
use think\Request; |
|||
|
|||
class TagController extends BaseController |
|||
{ |
|||
/** |
|||
* 显示资源列表 |
|||
* |
|||
* @return \think\Response |
|||
*/ |
|||
public function index() |
|||
{ |
|||
$tagModel = new Tag(); |
|||
//标签整合展示
|
|||
$param = $this->request->param(); |
|||
$allTag = $tagModel->where([ |
|||
'website_id' => $this->siteId, |
|||
'seller_id' => $this->sellerId, |
|||
'lang' => $this->lang, |
|||
])->group('first_letter')->column('first_letter'); |
|||
|
|||
$charArr = ['A', 'B', 'C', 'D', 'E', 'F', 'G', "H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"]; |
|||
foreach ($charArr as $key => $value) { |
|||
if (!in_array($value, $allTag)) { |
|||
unset($charArr[$key]); |
|||
} |
|||
} |
|||
$charArr = array_values($charArr); |
|||
|
|||
$this->assign('allTag', $charArr); |
|||
|
|||
$param['name'] = $param['name'] ?? $charArr[0]; |
|||
$param['page'] = $param['page'] ?? 1; |
|||
$param['limit'] = $param['limit'] ?? 80; |
|||
//默认获取A首字母开头的标签
|
|||
|
|||
$tagList = $tagModel->where([ |
|||
'website_id' => $this->siteId, |
|||
'seller_id' => $this->sellerId, |
|||
'lang' => $this->lang, |
|||
])->where('first_letter', '=', $param['name'])->paginate( |
|||
[ |
|||
'page' => $param['page'], |
|||
'list_rows' => $param['limit'], |
|||
] |
|||
); |
|||
|
|||
$this->assign('tagList', $tagList); |
|||
$this->assign('name', $param['name']); |
|||
|
|||
return $this->fetch(config('view.view_tag_page_name')); |
|||
} |
|||
|
|||
} |
|||
Some files were not shown because too many files changed in this diff
Write
Preview
Loading…
Cancel
Save
Reference in new issue