This commit is contained in:
parent
7c0cb8f2a4
commit
096ec5485f
|
|
@ -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,11 @@
|
|||
.env
|
||||
/.idea
|
||||
/.vscode
|
||||
/.Ds.store
|
||||
*.log
|
||||
*.DS_Store
|
||||
runtime
|
||||
.VSCodeCounter/
|
||||
composer.lock
|
||||
/public/nginx.htaccess
|
||||
/public/.htaccess
|
||||
|
|
@ -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,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);
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1 @@
|
|||
./*
|
||||
|
|
@ -0,0 +1,191 @@
|
|||
<?php
|
||||
declare (strict_types = 1);
|
||||
|
||||
namespace app\controller\backend;
|
||||
|
||||
use app\model\AdminMenu;
|
||||
use app\model\PhoneCode;
|
||||
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;
|
||||
use xiaodi\JWTAuth\Facade\Jwt;
|
||||
|
||||
class AccountController extends \app\BaseController
|
||||
{
|
||||
|
||||
/**
|
||||
* @param Admin $adminModel
|
||||
* @return \think\response\Json
|
||||
* @throws \app\exception\ModelEmptyException
|
||||
* @throws \app\exception\ModelException
|
||||
*/
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @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\TokenException
|
||||
*/
|
||||
protected function getMenuAndToken($admin): \think\response\Json
|
||||
{
|
||||
// 缓存权限数据
|
||||
$roleRes = RoleService::getMenuAndUpdateAuth($admin['id']);
|
||||
// $token = Jwt::token([
|
||||
// 'uid' => $admin['id'],
|
||||
// 'name' => $admin['name'],
|
||||
// 'seller_id' => $admin['seller_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();
|
||||
|
||||
$menu = $roleRes['data'];
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,232 @@
|
|||
<?php
|
||||
declare (strict_types = 1);
|
||||
|
||||
namespace app\controller\backend;
|
||||
|
||||
use app\model\Admin;
|
||||
use app\model\AdminMenu;
|
||||
use app\validate\AdminValidate;
|
||||
use think\exception\ValidateException;
|
||||
use think\facade\Db;
|
||||
use think\facade\Lang;
|
||||
|
||||
class AdminController extends BaseController
|
||||
{
|
||||
|
||||
/**
|
||||
* @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,
|
||||
];
|
||||
$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());
|
||||
}
|
||||
$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)){
|
||||
$param['password'] = makePassword($password);
|
||||
}
|
||||
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();
|
||||
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 {
|
||||
$param['password'] = makePassword($param['password']);
|
||||
}
|
||||
$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,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
@ -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,171 @@
|
|||
<?php
|
||||
declare (strict_types = 1);
|
||||
|
||||
namespace app\controller\backend;
|
||||
|
||||
use app\model\AdminMenu;
|
||||
use app\service\RoleService;
|
||||
use app\validate\AdminMenuValidate;
|
||||
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()
|
||||
{
|
||||
return json(RoleService::getMenuAndUpdateAuth($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,156 @@
|
|||
<?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')['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,462 @@
|
|||
<?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\Db;
|
||||
use think\facade\Lang;
|
||||
use think\file\UploadedFile;
|
||||
|
||||
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开头'));
|
||||
}
|
||||
}
|
||||
$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开头'));
|
||||
}
|
||||
|
||||
$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']:"",
|
||||
];
|
||||
// 更新時間
|
||||
$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);
|
||||
}
|
||||
|
||||
return dataReturn(0,'上传成功',
|
||||
[
|
||||
'fileType'=>$fileType,
|
||||
'fileSize'=>$fileSize,
|
||||
'getUploadFileInfo'=>$upload->getUploadFileInfo()['data']
|
||||
]);
|
||||
}
|
||||
|
||||
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'];
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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,495 @@
|
|||
<?php
|
||||
declare (strict_types = 1);
|
||||
|
||||
namespace app\controller\backend;
|
||||
|
||||
use app\exception\ModelException;
|
||||
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','');
|
||||
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,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'] = '//' . $domain;
|
||||
}else{
|
||||
$item['fullUrl'] = '//' . $domain . $item['alias'].'.'.config('route.url_html_suffix');
|
||||
}
|
||||
}else{
|
||||
$item['fullUrl'] = '//' . $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'];
|
||||
}
|
||||
}
|
||||
$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;
|
||||
// 数据验证
|
||||
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]
|
||||
])->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.');
|
||||
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']);
|
||||
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();
|
||||
Cache::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;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,685 @@
|
|||
<?php
|
||||
declare (strict_types = 1);
|
||||
|
||||
namespace app\controller\backend;
|
||||
|
||||
use app\exception\ModelEmptyException;
|
||||
use app\exception\ModelException;
|
||||
use app\model\InnerChart;
|
||||
use app\model\RecycleBin;
|
||||
use app\model\SubContent;
|
||||
use app\model\SubContentCheck;
|
||||
use app\model\SubContentCheckStep;
|
||||
use app\model\SysSetting;
|
||||
use app\service\CacheService;
|
||||
use app\service\CiZhuaService;
|
||||
use app\service\ContentService;
|
||||
use app\service\ModuleFieldService;
|
||||
use app\service\TranslateService;
|
||||
use app\validate\ContentValidate;
|
||||
use think\db\exception\DbException;
|
||||
use think\Exception;
|
||||
use think\exception\ValidateException;
|
||||
use think\facade\Cache;
|
||||
use think\facade\Db;
|
||||
use think\facade\Lang;
|
||||
use Vtiful\Kernel\Excel;
|
||||
use function Complex\csc;
|
||||
|
||||
class ContentController extends BaseController
|
||||
{
|
||||
|
||||
// 文章批量上传
|
||||
public function articleUpload(ContentService $contentService): \think\response\Json
|
||||
{
|
||||
if($this->request->isPost()){
|
||||
$param = $this->request->param();
|
||||
$file = $this->request->file('file');
|
||||
$param['file'] = $file;
|
||||
if(is_string($param['category_id'])){
|
||||
$param['category_id'] = explode(',', $param['category_id']);
|
||||
}
|
||||
try{
|
||||
validate(ContentValidate::class)->scene('articleUpload')->check($param);
|
||||
}catch (ValidateException $e){
|
||||
return jsonReturn(-1,$e->getError());
|
||||
}
|
||||
$param['admin'] = $this->admin;
|
||||
$res = $contentService->articleUpload($param);
|
||||
CacheService::clear();
|
||||
return json($res);
|
||||
}
|
||||
return jsonReturn(-1,Lang::get('请求方式错误'));
|
||||
}
|
||||
|
||||
// 提取文章简介
|
||||
public function descExtraction(ContentService $contentService): \think\response\Json
|
||||
{
|
||||
$content = input('content');
|
||||
$res = $contentService -> descExtraction($content);
|
||||
return jsonReturn(0,lang('成功'),$res);
|
||||
}
|
||||
|
||||
// 图片本地化
|
||||
public function imgLocal(ContentService $contentService): \think\response\Json
|
||||
{
|
||||
$content = input('content');
|
||||
$website = input('website');
|
||||
$res = $contentService -> imgExtraction($content,$this->admin['seller_id'],$website);
|
||||
return jsonReturn(0,lang('成功'),$res);
|
||||
}
|
||||
|
||||
public function wordSearch(CiZhuaService $ciZhuaService)
|
||||
{
|
||||
$content = input('content');
|
||||
$sysSetting = new SysSetting();
|
||||
$key = $sysSetting->getSysSettingValue([['title','=','cizhua_secret']])['data'];
|
||||
|
||||
if (empty($key)) {
|
||||
return jsonReturn(-1,lang('没有配置密钥,请去系统设置-第三方设置中填写词爪密钥'));
|
||||
}
|
||||
|
||||
$res = $ciZhuaService->wordSearch($key, $content);
|
||||
$res = json_decode($res, true);
|
||||
if ($res['code'] != 0) {
|
||||
return json($res);
|
||||
}
|
||||
return jsonReturn(0,lang('成功'), $res['data']);
|
||||
}
|
||||
|
||||
/**
|
||||
* 内容添加内链
|
||||
* @throws DbException
|
||||
*/
|
||||
public function addInnerChat(ContentService $contentService): \think\response\Json
|
||||
{
|
||||
$param = input('post.');
|
||||
try{
|
||||
validate(ContentValidate::class)->scene('addInnerChat')->check($param);
|
||||
}catch (ValidateException $e){
|
||||
return jsonReturn(422, $e->getError());
|
||||
}
|
||||
$sellerId= $this->admin['seller_id'];
|
||||
$InnerChart = new InnerChart();
|
||||
$innerChart = $InnerChart->getAllInnerChart(['seller_id'=>$sellerId,'website_id'=>$param['website_id'],'status'=>1],'weight desc','id,weight,keyword,url,new_page_open')['data'];
|
||||
if(empty($innerChart)){
|
||||
return jsonReturn(0,lang('成功'),$param['content']);
|
||||
}
|
||||
$subId = (int)input('sub_id');
|
||||
if($subId){
|
||||
$SubContent = new SubContent();
|
||||
$subContent = $SubContent -> getSubContent(['id'=>$subId,'seller_id'=>$this->admin['seller_id'],'is_del'=>1])['data'];
|
||||
}else{
|
||||
$subContent = null;
|
||||
}
|
||||
$content = $contentService->autoLinks($param['content'],$innerChart,$subContent);
|
||||
CacheService::clear();
|
||||
return jsonReturn(0,lang('成功'),$content);
|
||||
}
|
||||
|
||||
/**
|
||||
* 文章列表
|
||||
*
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function index(ContentService $contentService): \think\Response
|
||||
{
|
||||
$status = input('param.status');
|
||||
$categoryIds = input('param.category_id');
|
||||
$title = input('param.title');
|
||||
|
||||
$limit = $this->setLimit();
|
||||
$param = [
|
||||
'seller_id' => $this->admin['seller_id'],
|
||||
'category_ids' => $categoryIds,
|
||||
'limit' => $limit,
|
||||
'lang' => input('param.lang'),
|
||||
'website_id' => (int)input('param.website_id'),
|
||||
'title' => $title,
|
||||
'is_del' => 1,
|
||||
];
|
||||
|
||||
$where = [];
|
||||
switch ($status) {
|
||||
case 1://已发布
|
||||
$where[] = ['status', '=', 1];
|
||||
$where[] = ['publish_time', '<=', date('Y-m-d H:i:s')];
|
||||
$where[] = ['check_status', '=', 3];
|
||||
break;
|
||||
case 2://待发布
|
||||
$where[] = ['status', '=', 1];
|
||||
$where[] = ['publish_time', '>', date('Y-m-d H:i:s')];
|
||||
$where[] = ['check_status', '=', 3];
|
||||
break;
|
||||
case 3://待审核
|
||||
$where[] = ['status', '=', 1];
|
||||
$where[] = ['check_status', 'in', [1,2]];
|
||||
break;
|
||||
case 4://被驳回
|
||||
$where[] = ['status', '=', 1];
|
||||
$where[] = ['check_status', '=', 4];
|
||||
break;
|
||||
case 5://已下线
|
||||
$where[] = ['status', '=', 2];
|
||||
break;
|
||||
case 6://草稿
|
||||
$where[] = ['status', '=', 3];
|
||||
break;
|
||||
}
|
||||
$param['where'] = $where;
|
||||
|
||||
try {
|
||||
$res = $contentService->indexContent($param);
|
||||
} catch (ModelEmptyException | ModelException | DbException $e) {
|
||||
return jsonReturn(50013,$e->getMessage());
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 待审核列表
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function checkList(ContentService $contentService)
|
||||
{
|
||||
$categoryIds = input('param.category_id');
|
||||
$title = input('param.title');
|
||||
$type = $this->request->param('type', 1);
|
||||
|
||||
$contentCheckModel = new SubContentCheck();
|
||||
if ($type == 1) {
|
||||
// 获取需要自己审核的待审核内容id
|
||||
$ids = $contentCheckModel->where([
|
||||
'check_user_id' => $this->admin['uid'],
|
||||
'status' => 2,
|
||||
])->column('real_id');
|
||||
$contentWhere[] = ['id', 'in', $ids];
|
||||
$contentWhere[] = ['check_status', 'in', [1,2]];
|
||||
} else {
|
||||
// 获取自己提交的需要审核的内容id
|
||||
$contentWhere[] = ['admin_id', '=', $this->admin['uid']];
|
||||
}
|
||||
$contentWhere[] = ['status', 'in', [1,2]];
|
||||
|
||||
$limit = $this->setLimit();
|
||||
$param = [
|
||||
'seller_id' => $this->admin['seller_id'],
|
||||
'category_ids' => $categoryIds,
|
||||
'limit' => $limit,
|
||||
'lang' => input('param.lang'),
|
||||
'website_id' => (int)input('param.website_id'),
|
||||
'title' => $title,
|
||||
'is_del' => 1,
|
||||
'where' => $contentWhere
|
||||
];
|
||||
try {
|
||||
$res = $contentService->indexContent($param);
|
||||
} catch (ModelEmptyException | ModelException | DbException $e) {
|
||||
return jsonReturn(50013,$e->getMessage());
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 回收站列表
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function recycleBinList(ContentService $contentService)
|
||||
{
|
||||
$categoryIds = input('param.category_id');
|
||||
$title = input('param.title');
|
||||
|
||||
$limit = $this->setLimit();
|
||||
$param = [
|
||||
'seller_id' => $this->admin['seller_id'],
|
||||
'category_ids' => $categoryIds,
|
||||
'limit' => $limit,
|
||||
'lang' => input('param.lang'),
|
||||
'website_id' => (int)input('param.website_id'),
|
||||
'title' => $title,
|
||||
'is_del' => 2,
|
||||
];
|
||||
try {
|
||||
$res = $contentService->indexContent($param);
|
||||
} catch (ModelEmptyException | ModelException | DbException $e) {
|
||||
return jsonReturn(50013,$e->getMessage());
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量审核
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function checkAll()
|
||||
{
|
||||
$param = $this->request->only([
|
||||
'check_data' => [],
|
||||
'status' => 3,
|
||||
'reason' => '',
|
||||
'files' => '',
|
||||
]);
|
||||
|
||||
// 内容多版本审核
|
||||
|
||||
if (empty($param['check_data']) || !in_array($param['status'], [3,4])) {
|
||||
return jsonReturn(-1, lang('参数错误'));
|
||||
}
|
||||
if (!is_array($param['check_data'])) {
|
||||
return jsonReturn(-1, lang('参数错误'));
|
||||
}
|
||||
|
||||
if (is_array($param['files'])) {
|
||||
$param['files'] = implode(',', $param['files']);
|
||||
}
|
||||
|
||||
Db::startTrans();
|
||||
try {
|
||||
$contentService = new ContentService();
|
||||
foreach ($param['check_data'] as $check) {
|
||||
$newParam = $param;
|
||||
unset($newParam['check_data']);
|
||||
$newParam['real_id'] = $check['id'];
|
||||
$newParam['version'] = $check['version'];
|
||||
$newParam['admin'] = $this->admin;
|
||||
|
||||
$res = $contentService->check($newParam);
|
||||
if ($res['code'] != 0) {
|
||||
throw new Exception($check['id'] . lang('审核失败!版本:')."{$check['version']}!" . $res['code'] . $res['msg']);
|
||||
}
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
Db::rollback();
|
||||
return jsonReturn(-3, $e->getMessage(), $e->getTrace());
|
||||
}
|
||||
Db::commit();
|
||||
return jsonReturn(0, lang('操作成功'));
|
||||
}
|
||||
|
||||
public function editStatus(ContentService $contentService)
|
||||
{
|
||||
$param = $this->request->only([
|
||||
'id' => [],
|
||||
'status' => 1,
|
||||
]);
|
||||
$param['seller_id'] = $this->admin['seller_id'];
|
||||
|
||||
return json($contentService->editStatus($param));
|
||||
}
|
||||
|
||||
/*
|
||||
* 批量删除
|
||||
*/
|
||||
public function delAll(ContentService $contentService)
|
||||
{
|
||||
$param = $this->request->only(['ids']);
|
||||
|
||||
if (!is_array($param['ids'])) {
|
||||
$param['ids'] = explode(',', $param['ids']);
|
||||
}
|
||||
$subContentModel = new SubContent();
|
||||
$list = $subContentModel->where('id', 'in', $param['ids'])->column('id, module_id');
|
||||
|
||||
foreach ($list as $v) {
|
||||
$v['seller_id'] = $this->admin['seller_id'];
|
||||
$v['admin_id'] = $this->admin['uid'];
|
||||
$v['name'] = $this->admin['name'];
|
||||
|
||||
$res = $contentService->deleteContent($v);
|
||||
CacheService::clear();
|
||||
}
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
// 批量恢复
|
||||
public function recoverAll(ModuleFieldService $fieldService)
|
||||
{
|
||||
$param = $this->request->only(['ids']);
|
||||
if (!is_array($param['ids'])) {
|
||||
$param['ids'] = explode(',', $param['ids']);
|
||||
}
|
||||
|
||||
$subContentModel = new SubContent();
|
||||
$list = $subContentModel->where('id', 'in', $param['ids'])->column('id, module_id');
|
||||
|
||||
$ids = array_column($list, 'id');
|
||||
$module_ids = array_column($list, 'module_id');
|
||||
$recycleBin = new RecycleBin();
|
||||
$idArr = $recycleBin->where([
|
||||
['sub_id', 'in', $ids],
|
||||
['module_id', 'in', $module_ids]
|
||||
])->column('id');
|
||||
|
||||
foreach ($idArr as $id) {
|
||||
$res = $fieldService->resotreData($id,$this->admin['seller_id']);
|
||||
}
|
||||
CacheService::clear();
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取栏目字段
|
||||
*
|
||||
*/
|
||||
public function create(ContentService $contentService): \think\response\Json
|
||||
{
|
||||
$categoryId = (int)input('category_id');
|
||||
if(!$categoryId){
|
||||
return jsonReturn(-1,lang('栏目ID不能为空'));
|
||||
}
|
||||
$param = [
|
||||
'seller_id' => $this->admin['seller_id'],
|
||||
'category_id' => $categoryId
|
||||
];
|
||||
try {
|
||||
$res = $contentService->createContent($param);
|
||||
} catch (ModelEmptyException | ModelException $e) {
|
||||
return jsonReturn(-3,$e->getMessage());
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 栏目内容新增
|
||||
*
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function save(ContentService $contentService): \think\Response
|
||||
{
|
||||
if(!request()->isPost()){
|
||||
return jsonReturn(-2,lang('请求方法错误'));
|
||||
}
|
||||
$param = input('post.');
|
||||
try{
|
||||
validate(ContentValidate::class)->scene('save')->check($param);
|
||||
}catch (ValidateException $e){
|
||||
return jsonReturn(422, $e->getError());
|
||||
}
|
||||
$param['admin'] = $this->admin;
|
||||
unset($param['main_content']['id']);//添加接口以防冲突不需要id
|
||||
unset($param['sub_content']['id']);//添加接口以防冲突不需要id
|
||||
if(empty($param['sub_content']['publish_time'])){
|
||||
$param['sub_content']['publish_time'] = date('Y-m-d H:i:s',time());
|
||||
}
|
||||
if(!isset($param['main_content'])){
|
||||
$param['main_content'] = [];
|
||||
}
|
||||
try {
|
||||
$res = $contentService->saveContent($param);
|
||||
} catch (ModelEmptyException | ModelException $e) {
|
||||
return jsonReturn(-3,$e->getMessage());
|
||||
}
|
||||
CacheService::clear();
|
||||
return json($res);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示指定的资源
|
||||
*
|
||||
*/
|
||||
public function read(ContentService $contentService): \think\response\Json
|
||||
{
|
||||
$param = request()->only(['id','module_id','website_id','lang']);
|
||||
try {
|
||||
validate(ContentValidate::class)->scene('read')->check($param);
|
||||
}catch(ValidateException $e){
|
||||
return jsonReturn(-422,$e->getError());
|
||||
}
|
||||
$param['seller_id'] = $this->admin['seller_id'];
|
||||
try {
|
||||
$res = $contentService->readContent($param);
|
||||
} catch (ModelEmptyException | ModelException $e) {
|
||||
return jsonReturn(50025,$e->getMessage());
|
||||
}
|
||||
return $res;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存更新的资源
|
||||
*
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function update(ContentService $contentService): \think\Response
|
||||
{
|
||||
if(!request()->isPost()){
|
||||
return jsonReturn(-2,lang('请求方法错误'));
|
||||
}
|
||||
|
||||
$param = input('post.');
|
||||
try{
|
||||
validate(ContentValidate::class)->scene('update')->check($param);
|
||||
}catch (ValidateException $e){
|
||||
return jsonReturn(422, $e->getError());
|
||||
}
|
||||
|
||||
$param['admin'] = $this->admin;
|
||||
if(empty($param['sub_content']['publish_time'])){
|
||||
$param['sub_content']['publish_time'] = date('Y-m-d H:i:s',time());
|
||||
}
|
||||
try {
|
||||
$res = $contentService->updateContent($param);
|
||||
} catch (ModelEmptyException | ModelException $e) {
|
||||
return jsonReturn(-3,$e->getMessage());
|
||||
}
|
||||
CacheService::clear();
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除指定资源
|
||||
*
|
||||
*/
|
||||
public function delete(ContentService $contentService): \think\response\Json
|
||||
{
|
||||
$param = request()->only(['id','module_id']);
|
||||
try {
|
||||
validate(ContentValidate::class)->scene('delete')->check($param);
|
||||
}catch(ValidateException $e){
|
||||
return jsonReturn(-422,$e->getMessage());
|
||||
}
|
||||
$param['seller_id'] = $this->admin['seller_id'];
|
||||
$param['admin_id'] = $this->admin['uid'];
|
||||
$param['name'] = $this->admin['name'];
|
||||
CacheService::clear();
|
||||
return $contentService->deleteContent($param);
|
||||
|
||||
}
|
||||
|
||||
public function mainContent(ContentService $contentService): \think\response\Json
|
||||
{
|
||||
if(!request()->isGet()){
|
||||
return jsonReturn(-1,lang('请求方法错误'));
|
||||
}
|
||||
$param = request()->param(['module_id','website_id','page','limit']);
|
||||
try {
|
||||
validate(ContentValidate::class)->scene('mainContent')->check($param);
|
||||
}catch(ValidateException $e){
|
||||
return jsonReturn(-422,$e->getMessage());
|
||||
}
|
||||
$limit = (int)input('param.limit') ?: 10;
|
||||
$param = [
|
||||
'seller_id' => $this->admin['seller_id'],
|
||||
'website_id' => $param['website_id'],
|
||||
'module_id' => $param['module_id'],
|
||||
'limit' => $limit,
|
||||
];
|
||||
try {
|
||||
$res = $contentService->mainContent($param);
|
||||
} catch (ModelEmptyException | ModelException | DbException $e) {
|
||||
return jsonReturn(50013,$e->getMessage());
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改置顶
|
||||
* @throws ModelException
|
||||
*/
|
||||
public function topOpt(ContentService $contentService): \think\response\Json
|
||||
{
|
||||
if(request()->isPost()){
|
||||
$param = input('post.');
|
||||
try {
|
||||
validate(ContentValidate::class)->scene('topOpt')->check($param);
|
||||
}catch(ValidateException $e){
|
||||
return jsonReturn(-422,$e->getMessage());
|
||||
}
|
||||
$param['seller_id'] = $this->admin['seller_id'];
|
||||
return $contentService->topOpt($param);
|
||||
}
|
||||
return jsonReturn(-1,lang('请求方法错误'));
|
||||
}
|
||||
|
||||
/**
|
||||
* 推荐和修改状态
|
||||
* @throws ModelException
|
||||
*/
|
||||
public function recommendAndStatus(ContentService $contentService): \think\response\Json
|
||||
{
|
||||
if(request()->isPost()){
|
||||
$param = input('post.');
|
||||
try {
|
||||
validate(ContentValidate::class)->scene('recommendAndStatus')->check($param);
|
||||
}catch(ValidateException $e){
|
||||
return jsonReturn(-422,$e->getMessage());
|
||||
}
|
||||
$param['seller_id'] = $this->admin['seller_id'];
|
||||
CacheService::clear();
|
||||
return $contentService->recommendAndStatus($param);
|
||||
}
|
||||
return jsonReturn(-1,lang('请求方法错误'));
|
||||
}
|
||||
|
||||
public function moduleContent(ContentService $contentService): \think\response\Json
|
||||
{
|
||||
// 关联内容
|
||||
$table = input('param.table');
|
||||
// $field = input('param.field');
|
||||
if(empty($table)){
|
||||
return jsonReturn(-1,lang('表名不能为空'));
|
||||
}
|
||||
// if(empty($field)){
|
||||
// return jsonReturn(-2,'关联字段不能为空');
|
||||
// }
|
||||
|
||||
$res = $contentService -> getModuleContent($table,$this->admin['seller_id']);
|
||||
return jsonReturn($res);
|
||||
}
|
||||
|
||||
/**
|
||||
* excel导入内容
|
||||
*/
|
||||
public function importExcel()
|
||||
{
|
||||
$lang = $this->request->param('lang/s',"zh");
|
||||
if(empty($_FILES['file'])){
|
||||
return jsonReturn(-1,lang("请传入文件"));
|
||||
}
|
||||
$fileName = $_FILES['file'];
|
||||
$temp_file = sys_get_temp_dir();
|
||||
$config = ['path' => $temp_file];
|
||||
$excel = new Excel($config);
|
||||
$tmpName = strrchr($fileName['tmp_name'], '/');
|
||||
//读取文件
|
||||
$sheetList = $excel->openFile($tmpName)->sheetList();
|
||||
|
||||
if (empty($sheetList)) {
|
||||
return jsonReturn(-1, lang('上传文件为空'));
|
||||
}
|
||||
$sheetData = $excel
|
||||
->openSheet($sheetList[0], Excel::SKIP_EMPTY_ROW)->getSheetData();
|
||||
if (!isset($sheetData[1]) || !isset($sheetData[2])) {
|
||||
return jsonReturn(-1, lang('上传文件为空'));
|
||||
}
|
||||
|
||||
$fieldLocation = array();
|
||||
foreach ($sheetData[0] as $key => $value) {
|
||||
$fieldLocation[$value] = $key;
|
||||
}
|
||||
unset($sheetData[0]);
|
||||
$needField = ['标题', '链接', '网站', '类别ID','类别','图片'];
|
||||
foreach ($needField as $key => $value) {
|
||||
if (!isset($fieldLocation[$value])) {
|
||||
return jsonReturn(-1, lang('缺少必要列:') . $value);
|
||||
}
|
||||
}
|
||||
|
||||
//查询栏目id和内容
|
||||
$category = Db::name("category")->where(['seller_id'=>$this->admin['seller_id'],'lang'=>$lang])
|
||||
->column("title","id");
|
||||
if(empty($category)){
|
||||
return jsonReturn(-5, lang("请先添加栏目"));
|
||||
}
|
||||
try{
|
||||
$insertData= $files = $filesUrl = $uploadFiles = [];
|
||||
foreach ($sheetData as $k=>$v){
|
||||
if(empty($v[0])){
|
||||
return jsonReturn(-4,lang("标题不能为空"));
|
||||
}
|
||||
if(!empty($v[5]) && !preg_match('/(http:\/\/)|(https:\/\/)/i', $v[5])){
|
||||
return jsonReturn(-4,lang("图片格式错误"));
|
||||
}
|
||||
if(empty($category[$v[3]])){
|
||||
return jsonReturn(-4,$v[3].lang('对应的分类不存在')."[{$v[4]}]");
|
||||
}
|
||||
if (!empty($v[5]) && !in_array(trim($v[5]),$files)){
|
||||
$files[]=trim($v[5]);
|
||||
$uploadFiles[$k]['url'] = trim($v[5]);
|
||||
$uploadFiles[$k]['seller_id'] = $this->admin['seller_id'];
|
||||
$uploadFiles[$k]['name'] = $v[4];
|
||||
$uploadFiles[$k]['type'] = 2;
|
||||
$uploadFiles[$k]['storage'] = 1;
|
||||
}
|
||||
|
||||
$insertData[$k]['seller_id'] = $this->admin['seller_id'];
|
||||
$insertData[$k]['category_id'] = $v[3];
|
||||
$insertData[$k]['module_id'] = 1;
|
||||
$insertData[$k]['lang'] = $lang;
|
||||
$insertData[$k]['title'] = $v[0];
|
||||
$insertData[$k]['thumbnail'] = $v[5];
|
||||
$insertData[$k]['admin_id'] = $this->admin['uid'];
|
||||
$insertData[$k]['author'] = $v[2];
|
||||
$insertData[$k]['check_status'] = 3;
|
||||
$insertData[$k]['url'] = $v[1];
|
||||
$insertData[$k]['publish_time'] = date("Y-m-d H:i:s");
|
||||
$insertData[$k]['create_time'] =time();
|
||||
}
|
||||
}catch (\Exception $e){
|
||||
throw new ModelException($e->getMessage(),-1);
|
||||
}
|
||||
|
||||
Db::startTrans();
|
||||
try{
|
||||
if(!empty($uploadFiles)){
|
||||
Db::name("attachment")->insertAll($uploadFiles);
|
||||
$filesUrl = Db::name("attachment")->where([['url',"in",$files]])->column("id","url");
|
||||
}
|
||||
foreach ($insertData as $ki=>$data){
|
||||
$data['thumbnail'] = isset($filesUrl[$data['thumbnail']])?$filesUrl[$data['thumbnail']]:0;
|
||||
$sub_id = Db::name("sub_content")->insertGetId($data); //文章的id
|
||||
Db::name("category_sub_content")->insert([
|
||||
"seller_id"=>$data['seller_id'],
|
||||
"category_id"=>$data['category_id'],
|
||||
"sub_content_id"=>$sub_id,
|
||||
]);
|
||||
$mainId = Db::name("article")->insertGetId([
|
||||
"seller_id"=>$data['seller_id'],
|
||||
"lang"=>$lang,
|
||||
"sub_id"=>$sub_id,
|
||||
"create_time"=>time()
|
||||
]);
|
||||
Db::name("sub_content")->where(['id'=>$sub_id])->update(['main_id'=>$mainId]);
|
||||
}
|
||||
Db::commit();
|
||||
}catch (\Exception $e){
|
||||
Db::rollback();
|
||||
throw new ModelException($e->getMessage(),-2);
|
||||
}
|
||||
return jsonReturn(0,lang('导入成功'));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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,667 @@
|
|||
<?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], 'no-lazy') !== 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);
|
||||
}
|
||||
|
||||
$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();
|
||||
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,506 @@
|
|||
<?php
|
||||
|
||||
namespace app\controller\backend;
|
||||
|
||||
use app\model\DiyForm;
|
||||
use Overtrue\Pinyin\Pinyin;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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,183 @@
|
|||
<?php
|
||||
|
||||
namespace app\controller\backend;
|
||||
|
||||
use app\model\Inquiry;
|
||||
use app\model\RecycleBin;
|
||||
use app\validate\InquiryValidate;
|
||||
use think\exception\ValidateException;
|
||||
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('请求方法错误'));
|
||||
}
|
||||
}
|
||||
|
|
@ -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,217 @@
|
|||
<?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\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)
|
||||
{
|
||||
$Category = new Category();
|
||||
$category = $Category -> getCategory(['id'=>$param['category_id'],'seller_id' => $this->admin['seller_id']])['data'];
|
||||
if($category['type'] == 2){
|
||||
$param['href'] = 'javascript:;';
|
||||
}else if($category['type'] == 3){
|
||||
$param['href'] = $category['alias'];
|
||||
} else{
|
||||
$Route = new Route();
|
||||
$route = $Route -> getRoute(['full_url'=> 'List/index?id='.$param['category_id'],'seller_id'=>$this->admin['seller_id']])['data'];
|
||||
$param['href'] = $route['url'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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,182 @@
|
|||
<?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']);
|
||||
$param['kid_auth'] = implode(',', $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,136 @@
|
|||
<?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';
|
||||
$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
|
||||
{
|
||||
Cache::clear();
|
||||
return jsonReturn(0, Lang::get("成功"));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,537 @@
|
|||
<?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@admin.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();
|
||||
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,295 @@
|
|||
<?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'];
|
||||
$data = [];
|
||||
foreach ($template as $val){
|
||||
$file = basename($val['file']);
|
||||
if($param['type'] == 1){
|
||||
if(preg_match('/^list_/',$file) || $file == 'index.html'){
|
||||
$data[] = $val;
|
||||
}
|
||||
}else if($param['type'] == 2){
|
||||
if(preg_match('/^detail/',$file)){
|
||||
$data[] = $val;
|
||||
}
|
||||
}else if($param['type'] == 3){
|
||||
if(preg_match('/^single_/',$file) || $file == 'index.html'){
|
||||
$data[] = $val;
|
||||
}
|
||||
}else{
|
||||
$data[] = $val;
|
||||
}
|
||||
}
|
||||
return jsonReturn(0,Lang::get('成功'),$data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 启用模版
|
||||
*
|
||||
* @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,322 @@
|
|||
<?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;
|
||||
|
||||
class BaseController extends AppBaseController
|
||||
{
|
||||
protected $rootDomain;
|
||||
protected $domain;
|
||||
protected $siteId;
|
||||
protected $sellerId;
|
||||
protected $theme;
|
||||
protected $lang;
|
||||
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->lang = $this->setLang();
|
||||
$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'];
|
||||
}
|
||||
}
|
||||
|
||||
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 setLang(): string
|
||||
{
|
||||
$baseUrl = trim($this->request->baseUrl(),'/');
|
||||
$firstPath = explode('/',$baseUrl)[0];
|
||||
$langArr = config('system.lang');
|
||||
if(empty($firstPath) || !in_array($firstPath,$langArr)){
|
||||
$firstPath = config('lang.default_lang');
|
||||
}
|
||||
return $firstPath;
|
||||
}
|
||||
|
||||
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);
|
||||
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);
|
||||
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,77 @@
|
|||
<?php
|
||||
declare (strict_types = 1);
|
||||
|
||||
namespace app\controller\frontend;
|
||||
|
||||
use app\exception\ModelEmptyException;
|
||||
use app\model\Category;
|
||||
use app\model\SysSetting;
|
||||
use app\service\ContentService;
|
||||
use think\facade\Cache;
|
||||
|
||||
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
|
||||
];
|
||||
$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'] .= " - $huocmsPowerby";
|
||||
$category['seo_keywords'] .= "-$huocmsPowerby";
|
||||
$category['seo_description'] .= ",$huocmsPowerby";
|
||||
$content['seo_title'] .= "-$huocmsPowerby";
|
||||
$content['seo_keyword'] .= ",$huocmsPowerby";
|
||||
$content['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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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,76 @@
|
|||
<?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 GuzzleHttp\Client;
|
||||
use think\facade\Log;
|
||||
|
||||
class InquiryController extends BaseController
|
||||
{
|
||||
/**
|
||||
* 保存新建的资源
|
||||
*
|
||||
* @return \think\Response
|
||||
* @throws \app\exception\ModelException
|
||||
* @throws \app\exception\ModelEmptyException
|
||||
*/
|
||||
public function save(): \think\Response
|
||||
{
|
||||
$param = request()->param();
|
||||
if(empty($param)){
|
||||
return jsonReturn(-1,lang('请填写询盘信息'));
|
||||
}
|
||||
|
||||
// 获取询盘收件箱
|
||||
$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);
|
||||
}
|
||||
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,85 @@
|
|||
<?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');
|
||||
}
|
||||
];
|
||||
$category = $Category->getCategory(['seller_id' => $this->sellerId, 'website_id' => $this->siteId ,'is_search' => 1],$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(['is_search' => 1],'id desc','id')['data'];
|
||||
$cateIds = array_column($categories,'id');
|
||||
|
||||
$cateSub = new CategorySubContent();
|
||||
$cateSubWhere = [
|
||||
['seller_id','=',$this->siteId],
|
||||
['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->siteId;
|
||||
$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'));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
<?php
|
||||
// 事件定义文件
|
||||
return [
|
||||
'bind' => [
|
||||
],
|
||||
|
||||
'listen' => [
|
||||
'AppInit' => [],
|
||||
'HttpRun' => [],
|
||||
'HttpEnd' => [],
|
||||
'LogLevel' => [],
|
||||
'LogWrite' => [],
|
||||
'AdminLoginLog' => [\app\listener\AdminLoginListener::class],
|
||||
'AdminOptLog' => [\app\listener\AdminOperationListener::class],
|
||||
],
|
||||
|
||||
'subscribe' => [
|
||||
],
|
||||
];
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
<?php
|
||||
|
||||
namespace app\exception;
|
||||
|
||||
class AuthException extends BaseException
|
||||
{
|
||||
protected $errCode = 403;
|
||||
|
||||
protected $errMsg = '抱歉,您没有权限,请联系管理处理';
|
||||
|
||||
|
||||
public function __construct($msg = null,$code = null)
|
||||
{
|
||||
if(!$msg){
|
||||
$msg = $this->errMsg;
|
||||
}
|
||||
if(!$code){
|
||||
$code = $this->errCode;
|
||||
}
|
||||
|
||||
parent::__construct($msg,$code);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
<?php
|
||||
|
||||
|
||||
namespace app\exception;
|
||||
|
||||
class BadSysSettingException extends BaseException
|
||||
{
|
||||
protected $errCode = 500025;
|
||||
|
||||
protected $errMsg = '配置未完成';
|
||||
|
||||
|
||||
public function __construct($msg = null,$code = null)
|
||||
{
|
||||
if(!$msg){
|
||||
$msg = $this->errMsg;
|
||||
}
|
||||
if(!$code){
|
||||
$code = $this->errCode;
|
||||
}
|
||||
parent::__construct($msg,$code);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
<?php
|
||||
|
||||
namespace app\exception;
|
||||
|
||||
use think\Exception;
|
||||
|
||||
class BaseException extends Exception
|
||||
{
|
||||
protected $errCode = 5000;
|
||||
|
||||
protected $errMsg = '系统错误';
|
||||
|
||||
public function __construct($msg = null, $code = null)
|
||||
{
|
||||
if(!$msg){
|
||||
$msg = $this->errMsg;
|
||||
}
|
||||
if(!$code){
|
||||
$code = $this->errCode;
|
||||
}
|
||||
|
||||
parent::__construct($msg,$code);
|
||||
}
|
||||
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue