feat(初始化): init
						commit
						ad56dae1b8
					
				| 
						 | 
					@ -0,0 +1,19 @@
 | 
				
			||||||
 | 
					APP_DEBUG = true
 | 
				
			||||||
 | 
					APP_TRACE = true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[APP]
 | 
				
			||||||
 | 
					DEFAULT_TIMEZONE = Asia/Shanghai
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[DATABASE]
 | 
				
			||||||
 | 
					TYPE = mysql
 | 
				
			||||||
 | 
					HOSTNAME = 127.0.0.1
 | 
				
			||||||
 | 
					DATABASE = dev_bee_cms
 | 
				
			||||||
 | 
					USERNAME = dev_bee_cms
 | 
				
			||||||
 | 
					PASSWORD = dT7yH5fmd28JG6ER
 | 
				
			||||||
 | 
					HOSTPORT = 3306
 | 
				
			||||||
 | 
					CHARSET = utf8mb4
 | 
				
			||||||
 | 
					DEBUG = true
 | 
				
			||||||
 | 
					PREFIX = bee_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[LANG]
 | 
				
			||||||
 | 
					default_lang = zh-cn
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,16 @@
 | 
				
			||||||
 | 
					.env
 | 
				
			||||||
 | 
					/.idea
 | 
				
			||||||
 | 
					/.vscode
 | 
				
			||||||
 | 
					backup/data/*
 | 
				
			||||||
 | 
					/config/extra
 | 
				
			||||||
 | 
					*.log
 | 
				
			||||||
 | 
					runtime/*
 | 
				
			||||||
 | 
					storage/*
 | 
				
			||||||
 | 
					public/storage/*
 | 
				
			||||||
 | 
					.DS_Store
 | 
				
			||||||
 | 
					/Test.php
 | 
				
			||||||
 | 
					nginx.htaccess
 | 
				
			||||||
 | 
					dump.rdb
 | 
				
			||||||
 | 
					/app/controller/api/Test.php
 | 
				
			||||||
 | 
					public/.user.ini
 | 
				
			||||||
 | 
					public/.well-known/
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,7 @@
 | 
				
			||||||
 | 
					<html>
 | 
				
			||||||
 | 
					<head><title>404 Not Found</title></head>
 | 
				
			||||||
 | 
					<body>
 | 
				
			||||||
 | 
					<center><h1>404 Not Found</h1></center>
 | 
				
			||||||
 | 
					<hr><center>nginx</center>
 | 
				
			||||||
 | 
					</body>
 | 
				
			||||||
 | 
					</html>
 | 
				
			||||||
| 
						 | 
					@ -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,31 @@
 | 
				
			||||||
 | 
					## 本CMS基于ThinkPHP 6.0.9开发
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					> - 运行环境要求 PHP7.4+
 | 
				
			||||||
 | 
					> - MySql版本限制 5.7.*(需要支持json函数)
 | 
				
			||||||
 | 
					> - [富文本编辑器选择wangEditorv3.1.1](https://github.com/wangfupeng1988/wangEditor)
 | 
				
			||||||
 | 
					> - [上传插件选择filepond4.7.1](https://github.com/pqina/filepond)
 | 
				
			||||||
 | 
					> - 默认上传插件修改为使用layui组件库自带的
 | 
				
			||||||
 | 
					> 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<hr /><br />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**PHP扩展依赖列表**
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					> - fileinfo
 | 
				
			||||||
 | 
					> - exif 需要安装在mbsting扩展之后
 | 
				
			||||||
 | 
					> - gd
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<hr /><br />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**PHP组件列表**
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					> -
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<hr /><br />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**前端组件列表**
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					> -
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<hr /><br />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1 @@
 | 
				
			||||||
 | 
					deny from all
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,15 @@
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace app\building;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					interface ManagerInterface
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    // 审核录入资料
 | 
				
			||||||
 | 
					    public function checkInfo();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // 审核加班
 | 
				
			||||||
 | 
					    public function checkOvertime();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // 审核
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,313 @@
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					declare (strict_types=1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace app\command;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use think\console\Command;
 | 
				
			||||||
 | 
					use think\console\Input;
 | 
				
			||||||
 | 
					use think\console\input\Option;
 | 
				
			||||||
 | 
					use think\console\Output;
 | 
				
			||||||
 | 
					use think\facade\Db;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Generate extends Command
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    protected string $controller;
 | 
				
			||||||
 | 
					    protected string $name;
 | 
				
			||||||
 | 
					    protected string $title;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    protected string $namespace;//控制器命名空间
 | 
				
			||||||
 | 
					    protected string $viewDir;//view目录
 | 
				
			||||||
 | 
					    protected string $jsFullDir;//js完整路径目录
 | 
				
			||||||
 | 
					    protected string $jsDir;//js相对路径目录
 | 
				
			||||||
 | 
					    protected string $controllerFullPath;//控制器完整路径
 | 
				
			||||||
 | 
					    protected string $className;//控制器类名
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    protected function configure()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        // 指令配置
 | 
				
			||||||
 | 
					        $this->setName('generate')
 | 
				
			||||||
 | 
					            ->setDescription('生成后台基础crud')
 | 
				
			||||||
 | 
					            ->addOption('title', 't', Option::VALUE_REQUIRED, '标题')
 | 
				
			||||||
 | 
					            ->addOption('name', null, Option::VALUE_REQUIRED, '权限标识')
 | 
				
			||||||
 | 
					            ->addOption('controller', null, Option::VALUE_REQUIRED, '控制器命名空间');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    protected function setInfo(string $controller, string $name, string $title)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $this->name       = $name;
 | 
				
			||||||
 | 
					        $this->controller = $controller;
 | 
				
			||||||
 | 
					        $this->title      = $title;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->controllerFullPath = $this->getControllerPathName();
 | 
				
			||||||
 | 
					        $this->viewDir            = $this->getViewDirName();
 | 
				
			||||||
 | 
					        $this->jsFullDir          = $this->getJsFullDirName();
 | 
				
			||||||
 | 
					        $this->jsDir              = $this->getJsDirName();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $controllerPath  = explode('/', trim($controller, '/'));
 | 
				
			||||||
 | 
					        $this->className = $controllerPath[count($controllerPath) - 1];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $namespace       = 'app\\controller\\'.implode('\\', array_slice($controllerPath, 0, count($controllerPath) - 1));
 | 
				
			||||||
 | 
					        $this->namespace = $namespace;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    protected function execute(Input $input, Output $output)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $title      = $input->getOption('title') ? trim($input->getOption('title')) : '';
 | 
				
			||||||
 | 
					        $name       = $input->getOption('name') ? trim($input->getOption('name')) : '';
 | 
				
			||||||
 | 
					        $controller = $input->getOption('controller') ? trim($input->getOption('controller')) : '';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->setInfo($controller, $name, $title);
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            $output->writeln('开始创建');
 | 
				
			||||||
 | 
					            $output->writeln('1.菜单表生成数据...');
 | 
				
			||||||
 | 
					            $dbRes = $this->createDb([
 | 
				
			||||||
 | 
					                'title' => $title, 'name' => $name, 'controller' => $controller
 | 
				
			||||||
 | 
					            ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $successList = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if ($dbRes) {
 | 
				
			||||||
 | 
					                $output->info('菜单表数据生成成功!');
 | 
				
			||||||
 | 
					                $successList[] = '菜单数据生成!';
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                $output->warning('菜单表数据生成失败');
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $output->writeln('2.生成控制器...');
 | 
				
			||||||
 | 
					            if (is_file($this->controllerFullPath)) {
 | 
				
			||||||
 | 
					                $output->error('控制器: '.$controller.' 已存在!');
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (!is_dir(dirname($this->controllerFullPath))) {
 | 
				
			||||||
 | 
					                mkdir(dirname($this->controllerFullPath), 0755, true);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // 生成控制器
 | 
				
			||||||
 | 
					            file_put_contents($this->controllerFullPath, $this->buildController());
 | 
				
			||||||
 | 
					            $output->info($this->controllerFullPath.' 控制器生成成功!');
 | 
				
			||||||
 | 
					            $successList[] = '创建文件:'.$this->controllerFullPath;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $output->writeln('3.生成视图文件...');
 | 
				
			||||||
 | 
					            if (!is_dir($this->viewDir)) {
 | 
				
			||||||
 | 
					                mkdir($this->viewDir, 0755, true);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            foreach (['index', 'add', 'edit'] as $action) {
 | 
				
			||||||
 | 
					                $actionHtml = sprintf('%s/%s.html', $this->viewDir, $action);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if (is_file($actionHtml)) {
 | 
				
			||||||
 | 
					                    $output->error($actionHtml.' 视图文件已存在!');
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                file_put_contents($actionHtml, $this->buildView($action));
 | 
				
			||||||
 | 
					                $output->info($actionHtml.' 文件创建成功');
 | 
				
			||||||
 | 
					                $successList[] = '创建文件:'.$actionHtml;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $output->info('视图文件生成成功!');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $jsPath = sprintf('%s/%s.js', $this->jsFullDir, unCamelize($this->className, '_'));
 | 
				
			||||||
 | 
					            $output->writeln('4.生成js文件...');
 | 
				
			||||||
 | 
					            if (!is_dir($this->jsFullDir)) {
 | 
				
			||||||
 | 
					                mkdir($this->jsFullDir, 0755, true);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            file_put_contents($jsPath, $this->buildJs());
 | 
				
			||||||
 | 
					            $output->info($jsPath.' js文件创建成功!');
 | 
				
			||||||
 | 
					            $successList[] = '创建文件:'.$jsPath;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $output->newLine();
 | 
				
			||||||
 | 
					            $output->writeln('信息汇总');
 | 
				
			||||||
 | 
					            // 汇总信息
 | 
				
			||||||
 | 
					            foreach ($successList as $success) {
 | 
				
			||||||
 | 
					                $output->info($success);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $output->newLine();
 | 
				
			||||||
 | 
					            $output->info(sprintf('此时可访问路径查看是否创建成功 /%s/index', unCamelize($controller)));
 | 
				
			||||||
 | 
					            $output->newLine();
 | 
				
			||||||
 | 
					            $output->warning('请注意,控制器中 $noNeedRight 默认开启了所有权限,如需纳入权限控制,请删除并在角色中选择对应权限');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // 指令输出
 | 
				
			||||||
 | 
					            $output->info('创建完成');
 | 
				
			||||||
 | 
					        } catch (\Exception $e) {
 | 
				
			||||||
 | 
					            $output->error($e->getMessage());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 构建控制器内容
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return array|false|string|string[]
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    protected function buildController()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $controllerStubPath = __DIR__.DIRECTORY_SEPARATOR.'stubs/controller.stub';
 | 
				
			||||||
 | 
					        $stub               = file_get_contents($controllerStubPath);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return str_replace(['{%className%}', '{%namespace%}'], [
 | 
				
			||||||
 | 
					            $this->className,
 | 
				
			||||||
 | 
					            $this->namespace,
 | 
				
			||||||
 | 
					        ], $stub);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 构建视图文件内容
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param  string  $action
 | 
				
			||||||
 | 
					     * @return array|false|string|string[]
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    protected function buildView(string $action)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $actionStubPath = __DIR__.DIRECTORY_SEPARATOR.'stubs/'.$action.'.stub';
 | 
				
			||||||
 | 
					        $stub           = file_get_contents($actionStubPath);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return str_replace(['{%path%}', '{%jsPath%}'], [
 | 
				
			||||||
 | 
					            '/'.unCamelize($this->controller),
 | 
				
			||||||
 | 
					            $this->jsDir.'/'.unCamelize($this->className, '_').'.js',
 | 
				
			||||||
 | 
					        ], $stub);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 构建js文件内容
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return false|string
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    protected function buildJs()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $actionStubPath = __DIR__.DIRECTORY_SEPARATOR.'stubs/js.stub';
 | 
				
			||||||
 | 
					        return file_get_contents($actionStubPath);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 获取控制器完整路径
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return string
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    protected function getControllerPathName(): string
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return $this->app->getBasePath().'controller/'.ltrim(str_replace('\\', '/', $this->controller), '/').'.php';
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 获取对应view完整目录
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return string
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    protected function getViewDirName(): string
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return $this->app->getRootPath().'view/'.ltrim(unCamelize($this->controller, '_'), '/');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 获取对应js完整目录
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return string
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    protected function getJsFullDirName(): string
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $dir = $this->app->getRootPath().'public/static/'.ltrim(unCamelize($this->controller, '_'), '/');
 | 
				
			||||||
 | 
					        return str_replace('/manager/', '/manager/js/', $dir);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 获取对应js相对目录
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return string
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    protected function getJsDirName(): string
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return explode('/manager/', $this->jsFullDir)[1] ?? '';
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 自动添加菜单表数据
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param  array  $data
 | 
				
			||||||
 | 
					     * @return bool
 | 
				
			||||||
 | 
					     * @throws \Exception
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function createDb(array $data): bool
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $menuTable = 'menu';
 | 
				
			||||||
 | 
					        $now       = date('Y-m-d H:i:s');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!isset($data['title']) || !isset($data['name']) || !isset($data['controller'])) {
 | 
				
			||||||
 | 
					            throw new \Exception('参数错误 请添加:--title 标题 --name 权限标识,如aaa/bbb --controller 控制器 如manager/aaa/Bbb');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (empty($data['title']) || empty($data['name']) || empty($data['controller'])) {
 | 
				
			||||||
 | 
					            throw new \Exception('参数错误 请添加:--title 标题 --name 权限标识,如aaa/bbb --controller 控制器 如manager/aaa/Bbb');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // 检查权限标识是否已存在
 | 
				
			||||||
 | 
					        $already = Db::name('menu')->where('name', $data['name'])->whereOr('title', $data['title'])->count();
 | 
				
			||||||
 | 
					        if ($already) {
 | 
				
			||||||
 | 
					            throw new \Exception('菜单名称或标识已存在');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $href         = unCamelize($data['controller']);
 | 
				
			||||||
 | 
					        $insertMaster = [
 | 
				
			||||||
 | 
					            'pid'        => 0,
 | 
				
			||||||
 | 
					            'title'      => $data['title'], //名称
 | 
				
			||||||
 | 
					            'icon'       => $data['icon'] ?? 'fa-align-justify', //菜单图标
 | 
				
			||||||
 | 
					            'name'       => $data['name'], //权限标识
 | 
				
			||||||
 | 
					            'href'       => $href.'/index',//链接
 | 
				
			||||||
 | 
					            'type'       => 'menu',
 | 
				
			||||||
 | 
					            'is_show'    => 1,
 | 
				
			||||||
 | 
					            'status'     => 1,
 | 
				
			||||||
 | 
					            'remark'     => 'command generate',
 | 
				
			||||||
 | 
					            'created_at' => $now,
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $masterId = Db::name($menuTable)->insertGetId($insertMaster);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $masterPath = sprintf(',0,%d,', $masterId);
 | 
				
			||||||
 | 
					        Db::name($menuTable)->where('id', $masterId)->update([
 | 
				
			||||||
 | 
					            'path' => $masterPath
 | 
				
			||||||
 | 
					        ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $insertName = trim($data['name'], '/');
 | 
				
			||||||
 | 
					        $insertHref = '/'.trim($href, '/');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $actionArr = $this->actionList();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // 基于权限标识生成下级列表 默认index add del edit modify
 | 
				
			||||||
 | 
					        $insertAll = [];
 | 
				
			||||||
 | 
					        foreach (array_keys($actionArr) as $action) {
 | 
				
			||||||
 | 
					            $insertAll[] = [
 | 
				
			||||||
 | 
					                'pid'        => $masterId,
 | 
				
			||||||
 | 
					                'title'      => $actionArr[$action]['title'], //名称
 | 
				
			||||||
 | 
					                'icon'       => '', //菜单图标
 | 
				
			||||||
 | 
					                'name'       => $insertName.':'.$action, //权限标识
 | 
				
			||||||
 | 
					                'href'       => $insertHref.'/'.$action,//链接
 | 
				
			||||||
 | 
					                'type'       => 'action',
 | 
				
			||||||
 | 
					                'is_show'    => 1,
 | 
				
			||||||
 | 
					                'status'     => 1,
 | 
				
			||||||
 | 
					                'remark'     => 'command generate',
 | 
				
			||||||
 | 
					                'path'       => $masterPath,//此时的path为负极path
 | 
				
			||||||
 | 
					                'created_at' => $now,
 | 
				
			||||||
 | 
					            ];
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // 插入自己菜单
 | 
				
			||||||
 | 
					        Db::name($menuTable)->insertAll($insertAll);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // 批量更新自己菜单path
 | 
				
			||||||
 | 
					        Db::execute("update bee_$menuTable set `path`=concat(`path`, `id`, ',') where pid=$masterId");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    protected function actionList(): array
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return [
 | 
				
			||||||
 | 
					            'index'  => ['title' => '查看'],
 | 
				
			||||||
 | 
					            'add'    => ['title' => '添加'],
 | 
				
			||||||
 | 
					            'edit'   => ['title' => '编辑'],
 | 
				
			||||||
 | 
					            'del'    => ['title' => '删除'],
 | 
				
			||||||
 | 
					            'modify' => ['title' => '属性设置'],
 | 
				
			||||||
 | 
					            'sort'   => ['title' => '排序'],
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,53 @@
 | 
				
			||||||
 | 
					{layout name="manager/layout" /}
 | 
				
			||||||
 | 
					<div class="layuimini-container location-operate-page">
 | 
				
			||||||
 | 
					    <div class="layuimini-main">
 | 
				
			||||||
 | 
					        <div class="layui-form layuimini-form">
 | 
				
			||||||
 | 
					            <div class="layui-form-item">
 | 
				
			||||||
 | 
					                <label class="layui-form-label required">名称</label>
 | 
				
			||||||
 | 
					                <div class="layui-input-block">
 | 
				
			||||||
 | 
					                    <input type="text" name="name" placeholder="请输入名称" class="layui-input" value="" maxlength="250">
 | 
				
			||||||
 | 
					                </div>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            <div class="layui-form-item layui-row">
 | 
				
			||||||
 | 
					                <label class="layui-form-label required">封面图</label>
 | 
				
			||||||
 | 
					                <div class="layui-inline layui-col-xs12 layui-col-md8">
 | 
				
			||||||
 | 
					                    <div class="layui-row upload-file-div">
 | 
				
			||||||
 | 
					                        <div class=" layui-col-xs12 layui-col-md8">
 | 
				
			||||||
 | 
					                            <input class="layui-input upload-file-value" name="cover" type="text" value="{$item.cover ?? ''}">
 | 
				
			||||||
 | 
					                            <div class="layui-form-mid layui-word-aux">图片尺寸:xxx*xxx</div>
 | 
				
			||||||
 | 
					                        </div>
 | 
				
			||||||
 | 
					                        <div class="layui-col-xs12 layui-col-md3">
 | 
				
			||||||
 | 
					                            <span>
 | 
				
			||||||
 | 
					                                <button type="button" class="layui-btn layui-btn-danger upload-btn">
 | 
				
			||||||
 | 
					                                    <i class="fa fa-upload"></i> 上传
 | 
				
			||||||
 | 
					                                </button>
 | 
				
			||||||
 | 
					                            </span>
 | 
				
			||||||
 | 
					                            <span>
 | 
				
			||||||
 | 
					                                <button type="button" class="layui-btn layui-btn-primary upload-choose-btn" data-type="image" data-multiple="false">
 | 
				
			||||||
 | 
					                                    <i class="fa fa-list"></i> 选择
 | 
				
			||||||
 | 
					                                </button>
 | 
				
			||||||
 | 
					                            </span>
 | 
				
			||||||
 | 
					                        </div>
 | 
				
			||||||
 | 
					                        <ul class="layui-row layui-col-xs12 layui-col-md9 preview-list layui-col-space5"></ul>
 | 
				
			||||||
 | 
					                    </div>
 | 
				
			||||||
 | 
					                </div>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            <div class="layui-form-item">
 | 
				
			||||||
 | 
					                <label class="layui-form-label required">内容</label>
 | 
				
			||||||
 | 
					                <div class="layui-input-block">
 | 
				
			||||||
 | 
					                    <textarea name="content" class="layui-textarea tinymce-editor"></textarea>
 | 
				
			||||||
 | 
					                </div>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            <div class="layui-form-item">
 | 
				
			||||||
 | 
					                <div class="layui-input-block">
 | 
				
			||||||
 | 
					                    <button class="layui-btn layui-btn-normal" data-url="{%path%}/add" lay-submit lay-filter="saveBtn">确认保存</button>
 | 
				
			||||||
 | 
					                </div>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<script src="__MANAGER__/{%jsPath%}?v={:mt_rand()}"></script>
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,178 @@
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					declare (strict_types = 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace {%namespace%};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use Exception;
 | 
				
			||||||
 | 
					use app\model\Log;
 | 
				
			||||||
 | 
					use think\Collection;
 | 
				
			||||||
 | 
					use think\response\View;
 | 
				
			||||||
 | 
					use think\response\Json;
 | 
				
			||||||
 | 
					use app\controller\manager\Base;
 | 
				
			||||||
 | 
					use think\db\exception\DbException;
 | 
				
			||||||
 | 
					use think\exception\ValidateException;
 | 
				
			||||||
 | 
					use think\db\exception\DataNotFoundException;
 | 
				
			||||||
 | 
					use think\db\exception\ModelNotFoundException;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class {%className%} extends Base
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    protected $noNeedLogin = ['index', 'add', 'edit', 'del', 'modify'];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 列表
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @throws Exception
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function index()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if ($this->request->isPost()) {
 | 
				
			||||||
 | 
					            //            $params = input();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $res = [
 | 
				
			||||||
 | 
					                'total'   => 5,
 | 
				
			||||||
 | 
					                'current' => 1,
 | 
				
			||||||
 | 
					                'size'    => 10,
 | 
				
			||||||
 | 
					                'list'    => new Collection(),
 | 
				
			||||||
 | 
					            ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $res['list'] = [
 | 
				
			||||||
 | 
					                ['id' => 1, 'name' => '张伟', 'status' => '111', 'sort' => 11],
 | 
				
			||||||
 | 
					                ['id' => 2, 'name' => '王兴龙', 'status' => '222', 'sort' => 12],
 | 
				
			||||||
 | 
					                ['id' => 3, 'name' => '菜盘', 'status' => '333', 'sort' => 13],
 | 
				
			||||||
 | 
					                ['id' => 4, 'name' => '老郑', 'status' => '444', 'sort' => 14],
 | 
				
			||||||
 | 
					                ['id' => 5, 'name' => '大帅比', 'status' => '555', 'sort' => 15]
 | 
				
			||||||
 | 
					            ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return $this->json(0, 'success', $res);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->view();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 添加
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return Json|View
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function add()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if ($this->request->isPost()) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            try {
 | 
				
			||||||
 | 
					                $input = input('post.');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                // 添加逻辑 TODO
 | 
				
			||||||
 | 
					                return $this->json();
 | 
				
			||||||
 | 
					            } catch (Exception $e) {
 | 
				
			||||||
 | 
					                return $this->json(4001, '添加失败');
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->view();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 编辑
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return \think\response\Json|\think\response\View
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function edit()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $id = input('id');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //通过ID查询
 | 
				
			||||||
 | 
					        $item = ['id' => 11, 'name' => '标题', 'cover' => '/xxx/xxx/xxx.jpg', 'content' => '我是大帅比'];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (empty($item)) {
 | 
				
			||||||
 | 
					            return $this->json(4000, '没有相关的商品记录!');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($this->request->isPost()) {
 | 
				
			||||||
 | 
					            try {
 | 
				
			||||||
 | 
					                $input = input('post.');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                // 更新逻辑
 | 
				
			||||||
 | 
					                return $this->json();
 | 
				
			||||||
 | 
					            } catch (Exception $e) {
 | 
				
			||||||
 | 
					                return $this->json(5000, $e->getMessage());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->data['item'] = $item;
 | 
				
			||||||
 | 
					        $this->data['id']   = $id;
 | 
				
			||||||
 | 
					        return $this->view();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 更新属性
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @throws ModelNotFoundException
 | 
				
			||||||
 | 
					     * @throws DbException
 | 
				
			||||||
 | 
					     * @throws DataNotFoundException
 | 
				
			||||||
 | 
					     * @throws Exception
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function modify()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (!$this->request->isPost()) {
 | 
				
			||||||
 | 
					            return $this->json(4000, '非法请求');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $item     = input('post.');
 | 
				
			||||||
 | 
					        $validate = $this->validateByApi($item, [
 | 
				
			||||||
 | 
					            'field' => 'require',
 | 
				
			||||||
 | 
					            'value' => 'require',
 | 
				
			||||||
 | 
					        ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($validate !== true) {
 | 
				
			||||||
 | 
					            return $validate;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // 通过ID查询
 | 
				
			||||||
 | 
					        if (!$info = []) {
 | 
				
			||||||
 | 
					//            return $this->json(4001, '记录不存在');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $update = [$item['field'] => $item['value']];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					//            $info->save($update);
 | 
				
			||||||
 | 
					            return $this->json();
 | 
				
			||||||
 | 
					        } catch (ValidateException $e) {
 | 
				
			||||||
 | 
					            return $this->json(4001, $e->getError());
 | 
				
			||||||
 | 
					        } catch (Exception $e) {
 | 
				
			||||||
 | 
					            return $this->json(5000, '修改失败');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 删除
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return \think\response\Json
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function del(): Json
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (!$this->request->isPost()) {
 | 
				
			||||||
 | 
					            return $this->json(4000, '非法请求');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $ids = $this->request->param('ids/a', []);
 | 
				
			||||||
 | 
					        if (empty($ids)) {
 | 
				
			||||||
 | 
					            $ids[] = $this->request->param('id/d', 0);
 | 
				
			||||||
 | 
					            $ids   = array_filter($ids);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            if (count($ids)) {
 | 
				
			||||||
 | 
					                //删除逻辑 TODO
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                Log::write(get_class(), 'del', '删除操作,涉及到的ID为:'.implode(',', $ids));
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        } catch (Exception $e) {
 | 
				
			||||||
 | 
					            return $this->json(5000, $e->getMessage());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->json();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,54 @@
 | 
				
			||||||
 | 
					{layout name="manager/layout" /}
 | 
				
			||||||
 | 
					<div class="layuimini-container location-operate-page">
 | 
				
			||||||
 | 
					    <div class="layuimini-main">
 | 
				
			||||||
 | 
					        <div class="layui-form layuimini-form">
 | 
				
			||||||
 | 
					            <div class="layui-form-item">
 | 
				
			||||||
 | 
					                <label class="layui-form-label required">名称</label>
 | 
				
			||||||
 | 
					                <div class="layui-input-block">
 | 
				
			||||||
 | 
					                    <input type="text" name="name" placeholder="请输入名称" class="layui-input" value="{$item.name ?? ''}" maxlength="250">
 | 
				
			||||||
 | 
					                </div>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            <div class="layui-form-item layui-row">
 | 
				
			||||||
 | 
					                <label class="layui-form-label required">封面图</label>
 | 
				
			||||||
 | 
					                <div class="layui-inline layui-col-xs12 layui-col-md8">
 | 
				
			||||||
 | 
					                    <div class="layui-row upload-file-div">
 | 
				
			||||||
 | 
					                        <div class=" layui-col-xs12 layui-col-md8">
 | 
				
			||||||
 | 
					                            <input class="layui-input upload-file-value" name="cover" type="text" value="{$item.cover ?? ''}">
 | 
				
			||||||
 | 
					                            <div class="layui-form-mid layui-word-aux">图片尺寸:xxx*xxx</div>
 | 
				
			||||||
 | 
					                        </div>
 | 
				
			||||||
 | 
					                        <div class="layui-col-xs12 layui-col-md3">
 | 
				
			||||||
 | 
					                            <span>
 | 
				
			||||||
 | 
					                                <button type="button" class="layui-btn layui-btn-danger upload-btn">
 | 
				
			||||||
 | 
					                                    <i class="fa fa-upload"></i> 上传
 | 
				
			||||||
 | 
					                                </button>
 | 
				
			||||||
 | 
					                            </span>
 | 
				
			||||||
 | 
					                            <span>
 | 
				
			||||||
 | 
					                                <button type="button" class="layui-btn layui-btn-primary upload-choose-btn" data-type="image" data-multiple="false">
 | 
				
			||||||
 | 
					                                    <i class="fa fa-list"></i> 选择
 | 
				
			||||||
 | 
					                                </button>
 | 
				
			||||||
 | 
					                            </span>
 | 
				
			||||||
 | 
					                        </div>
 | 
				
			||||||
 | 
					                        <ul class="layui-row layui-col-xs12 layui-col-md9 preview-list layui-col-space5"></ul>
 | 
				
			||||||
 | 
					                    </div>
 | 
				
			||||||
 | 
					                </div>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            <div class="layui-form-item">
 | 
				
			||||||
 | 
					                <label class="layui-form-label required">内容</label>
 | 
				
			||||||
 | 
					                <div class="layui-input-block">
 | 
				
			||||||
 | 
					                    <textarea name="content" class="layui-textarea tinymce-editor">{$item.content ?? ''}</textarea>
 | 
				
			||||||
 | 
					                </div>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            <div class="layui-form-item">
 | 
				
			||||||
 | 
					                <div class="layui-input-block">
 | 
				
			||||||
 | 
					                    <input type="hidden" name="id" value="{$item.id ?? 0}">
 | 
				
			||||||
 | 
					                    <button class="layui-btn layui-btn-normal" data-url="{%path%}/edit" lay-submit lay-filter="saveBtn">确认保存</button>
 | 
				
			||||||
 | 
					                </div>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<script src="__MANAGER__/{%jsPath%}?v={:mt_rand()}"></script>
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,68 @@
 | 
				
			||||||
 | 
					{layout name="manager/layout" /}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<div class="layui-row layui-col-space12">
 | 
				
			||||||
 | 
					    <div class="layui-col-xs12 layui-col-md12">
 | 
				
			||||||
 | 
					        <div class="layuimini-container location-index-page">
 | 
				
			||||||
 | 
					            <div class="layuimini-main">
 | 
				
			||||||
 | 
					                <fieldset class="table-search-fieldset" style="display: none">
 | 
				
			||||||
 | 
					                    <legend>搜索信息</legend>
 | 
				
			||||||
 | 
					                    <div style="margin: 10px 10px 10px 10px">
 | 
				
			||||||
 | 
					                        <form class="layui-form layui-form-pane" action="">
 | 
				
			||||||
 | 
					                            <div class="layui-form-item">
 | 
				
			||||||
 | 
					                                <div class="layui-inline">
 | 
				
			||||||
 | 
					                                    <label class="layui-form-label">下拉选择</label>
 | 
				
			||||||
 | 
					                                    <div class="layui-input-block">
 | 
				
			||||||
 | 
					                                        <select name="status">
 | 
				
			||||||
 | 
					                                            <option value=""></option>
 | 
				
			||||||
 | 
					                                            <option value="sss">SSS</option>
 | 
				
			||||||
 | 
					                                            <option value="bbb">XXX</option>
 | 
				
			||||||
 | 
					                                        </select>
 | 
				
			||||||
 | 
					                                    </div>
 | 
				
			||||||
 | 
					                                </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                                <div class="layui-inline">
 | 
				
			||||||
 | 
					                                    <label class="layui-form-label">关键词</label>
 | 
				
			||||||
 | 
					                                    <div class="layui-input-block">
 | 
				
			||||||
 | 
					                                        <input class="layui-input" name="keyword" placeholder="支持模糊查询">
 | 
				
			||||||
 | 
					                                    </div>
 | 
				
			||||||
 | 
					                                </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                                <div class="layui-inline">
 | 
				
			||||||
 | 
					                                    <button type="submit" class="layui-btn layui-btn-primary"  lay-submit lay-filter="data-search-btn"><i class="layui-icon"></i> 搜 索</button>
 | 
				
			||||||
 | 
					                                </div>
 | 
				
			||||||
 | 
					                            </div>
 | 
				
			||||||
 | 
					                        </form>
 | 
				
			||||||
 | 
					                    </div>
 | 
				
			||||||
 | 
					                </fieldset>
 | 
				
			||||||
 | 
					                <div class="image-table">
 | 
				
			||||||
 | 
					                    <table id="table-container" class="layui-table" data-url="{%path%}/index" lay-filter="table-container-filter"></table>
 | 
				
			||||||
 | 
					                </div>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<!-- 隐藏列 -->
 | 
				
			||||||
 | 
					<!-- 编辑单元格提交url -->
 | 
				
			||||||
 | 
					<input type="hidden" id="row-modify" data-url="{%path%}/modify">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<!-- 列-上下架 -->
 | 
				
			||||||
 | 
					<script type="text/html" id="row-saleable">
 | 
				
			||||||
 | 
					    <input type="checkbox" name="saleable" value="{{d.id}}" lay-skin="switch" lay-text="是|否" lay-filter="changeSaleable" {{ d.saleable == 1 ? 'checked' : '' }}>
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<!-- 操作列 -->
 | 
				
			||||||
 | 
					<script type="text/html" id="row-operate">
 | 
				
			||||||
 | 
					    <a class="layui-btn layui-btn-primary layui-btn-xs" data-href="{%path%}/edit.html?id={{d.id}}" data-title="编辑" lay-event="edit">编辑</a>
 | 
				
			||||||
 | 
					    <a class="layui-btn layui-btn-danger layui-btn-xs" data-href="{%path%}/del.html" lay-event="del">删除</a>
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<!-- toolbar -->
 | 
				
			||||||
 | 
					<script type="text/html" id="toolbar-tpl">
 | 
				
			||||||
 | 
					    <a class="layui-btn layui-btn-primary layui-btn-sm" data-table-refresh lay-event="refresh"><i class="fa fa-refresh"></i></a>
 | 
				
			||||||
 | 
					    <a class="layui-btn layui-btn-normal layui-btn-sm" data-href="{%path%}/add.html" data-title="添加" lay-event="add">添加</a>
 | 
				
			||||||
 | 
					    <a class="layui-btn layui-btn-danger layui-btn-sm" data-href="{%path%}/del.html" lay-event="del">删除</a>
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<script src="__MANAGER__/{%jsPath%}?v={:mt_rand()}"></script>
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,211 @@
 | 
				
			||||||
 | 
					layui.use(['laytpl', 'table', 'jquery', 'form', 'miniTab', 'xmSelect', 'laydate'], function () {
 | 
				
			||||||
 | 
					    let $ = layui.jquery,
 | 
				
			||||||
 | 
					        table       = layui.table,
 | 
				
			||||||
 | 
					        xmSelect    = layui.xmSelect,
 | 
				
			||||||
 | 
					        miniTab     = layui.miniTab,
 | 
				
			||||||
 | 
					        laydate     = layui.laydate,
 | 
				
			||||||
 | 
					        form        = layui.form;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**** index begin ***/
 | 
				
			||||||
 | 
					    if ($('.location-index-page').length > 0) {
 | 
				
			||||||
 | 
					        miniTab.listen();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // 渲染表格
 | 
				
			||||||
 | 
					        let listUrl = $('#table-container').data('url');
 | 
				
			||||||
 | 
					        let insTb = table.render({
 | 
				
			||||||
 | 
					            elem: '#table-container',
 | 
				
			||||||
 | 
					            title: '列表',
 | 
				
			||||||
 | 
					            defaultToolbar: ['filter', 'exports', {
 | 
				
			||||||
 | 
					                title: '搜索' //自定义头部工具栏右侧图标。如无需自定义,去除该参数即可
 | 
				
			||||||
 | 
					                , layEvent: 'search'
 | 
				
			||||||
 | 
					                , icon: 'layui-icon-search'
 | 
				
			||||||
 | 
					            }],
 | 
				
			||||||
 | 
					            toolbar: '#toolbar-tpl',
 | 
				
			||||||
 | 
					            method: 'POST',
 | 
				
			||||||
 | 
					            url: listUrl,
 | 
				
			||||||
 | 
					            page: true,
 | 
				
			||||||
 | 
					            limit: 20,
 | 
				
			||||||
 | 
					            limits: [20,50,100,200,500,1000],
 | 
				
			||||||
 | 
					            request: {
 | 
				
			||||||
 | 
					                pageName: 'page',
 | 
				
			||||||
 | 
					                limitName: 'size',
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            parseData: function (res) {
 | 
				
			||||||
 | 
					                return {
 | 
				
			||||||
 | 
					                    "code": res.code, //解析接口状态
 | 
				
			||||||
 | 
					                    "msg": res.msg, //解析提示文本
 | 
				
			||||||
 | 
					                    "count": res.data.total, //解析数据长度
 | 
				
			||||||
 | 
					                    "data": res.data.list //解析数据列表
 | 
				
			||||||
 | 
					                };
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            cols: [[
 | 
				
			||||||
 | 
					                {type: 'checkbox'},
 | 
				
			||||||
 | 
					                {field: 'name', title: '名称', minWidth: 200},
 | 
				
			||||||
 | 
					                {templet: '#row-saleable', minWidth: 120,align: 'center', title: '上下架'},
 | 
				
			||||||
 | 
					                {field: 'sort', width: 150, align: 'center', title: '排序', edit: 'text'},
 | 
				
			||||||
 | 
					                {field: 'published_at', title: '发布日期', minWidth: 150, hide: true},
 | 
				
			||||||
 | 
					                {templet: '#row-operate', width: 280, align: 'center', title: '操作'}
 | 
				
			||||||
 | 
					            ]],
 | 
				
			||||||
 | 
					            done: function () {
 | 
				
			||||||
 | 
					                Tools.setInsTb(insTb);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //监听工具条 注意区别toolbar和tool  toolbar是表头上的工具条 tool是行中的工具条
 | 
				
			||||||
 | 
					        table.on('toolbar(table-container-filter)', function (obj) {
 | 
				
			||||||
 | 
					            let layEvent = obj.event;
 | 
				
			||||||
 | 
					            let insTb = Tools.getInsTb();
 | 
				
			||||||
 | 
					            let url = $($(this).context).data('href')
 | 
				
			||||||
 | 
					            let title = $($(this).context).data('title')
 | 
				
			||||||
 | 
					            let width = $($(this).context).data('width') ? $($(this).context).data('width') : '100%';
 | 
				
			||||||
 | 
					            let height = $($(this).context).data('height') ? $($(this).context).data('height') : '100%';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            let checkStatus = table.checkStatus('table-container');
 | 
				
			||||||
 | 
					            let selected = checkStatus.data;
 | 
				
			||||||
 | 
					            let ids = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            switch (layEvent) {
 | 
				
			||||||
 | 
					                // toolbar 删除
 | 
				
			||||||
 | 
					                case 'del':
 | 
				
			||||||
 | 
					                    if (checkStatus.data.length <= 0) {
 | 
				
			||||||
 | 
					                        layer.msg('请先选择数据');
 | 
				
			||||||
 | 
					                        return false;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    // let selected = checkStatus.data;
 | 
				
			||||||
 | 
					                    // let ids = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    $.each(selected, function (index, val) {
 | 
				
			||||||
 | 
					                        ids.push(val.id);
 | 
				
			||||||
 | 
					                    })
 | 
				
			||||||
 | 
					                    delRow(url, ids, insTb);
 | 
				
			||||||
 | 
					                    return false;
 | 
				
			||||||
 | 
					                // toolbar 刷新
 | 
				
			||||||
 | 
					                case 'refresh':
 | 
				
			||||||
 | 
					                    refreshTab(insTb);
 | 
				
			||||||
 | 
					                    return false;
 | 
				
			||||||
 | 
					                // toolbar 搜索
 | 
				
			||||||
 | 
					                case 'search':
 | 
				
			||||||
 | 
					                    let search = $('.table-search-fieldset');
 | 
				
			||||||
 | 
					                    if (search.hasClass('div-show')) {
 | 
				
			||||||
 | 
					                        search.css('display', 'none').removeClass('div-show');
 | 
				
			||||||
 | 
					                    } else {
 | 
				
			||||||
 | 
					                        search.css('display', 'block').addClass('div-show');
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    return false;
 | 
				
			||||||
 | 
					                // 其他 默认为打开弹出层
 | 
				
			||||||
 | 
					                default:
 | 
				
			||||||
 | 
					                    if (layEvent !== 'LAYTABLE_COLS' && layEvent !== 'LAYTABLE_EXPORT') {
 | 
				
			||||||
 | 
					                        openLayer(url, title, width, height);
 | 
				
			||||||
 | 
					                        return false;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //监听行工具条
 | 
				
			||||||
 | 
					        table.on('tool(table-container-filter)', function (obj) {
 | 
				
			||||||
 | 
					            let data = obj.data;
 | 
				
			||||||
 | 
					            let layEvent = obj.event;
 | 
				
			||||||
 | 
					            let url = $($(this).context).data('href');
 | 
				
			||||||
 | 
					            let title = $($(this).context).data('title');
 | 
				
			||||||
 | 
					            let width = $($(this).context).data('width') ? $($(this).context).data('width') : '100%';
 | 
				
			||||||
 | 
					            let height = $($(this).context).data('height') ? $($(this).context).data('height') : '100%';
 | 
				
			||||||
 | 
					            let insTb = Tools.getInsTb();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            switch (layEvent) {
 | 
				
			||||||
 | 
					                // 行 删除
 | 
				
			||||||
 | 
					                case 'del':
 | 
				
			||||||
 | 
					                    let ids = [data.id];
 | 
				
			||||||
 | 
					                    delRow(url, ids, insTb);
 | 
				
			||||||
 | 
					                    return false;
 | 
				
			||||||
 | 
					                //其他 默认为打开弹出层
 | 
				
			||||||
 | 
					                default:
 | 
				
			||||||
 | 
					                    openLayer(url, title, width, height);
 | 
				
			||||||
 | 
					                    return false;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        changeSwitch('changeSaleable');//监听上下架
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let modifyUrl = $('#row-modify').data('url');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        table.on('edit(table-container)', function (obj) {
 | 
				
			||||||
 | 
					            let id = obj.data.id;
 | 
				
			||||||
 | 
					            $.ajax(modifyUrl, {
 | 
				
			||||||
 | 
					                data: {"id": id, "field": obj.field, "value": obj.value}
 | 
				
			||||||
 | 
					                ,dataType : 'json'
 | 
				
			||||||
 | 
					                ,type: 'POST'
 | 
				
			||||||
 | 
					            })
 | 
				
			||||||
 | 
					            .done(function (res) {
 | 
				
			||||||
 | 
					                if (res.code === 0) {
 | 
				
			||||||
 | 
					                    insTb.reload();
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            })
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // switch变更
 | 
				
			||||||
 | 
					        function changeSwitch(filter) {
 | 
				
			||||||
 | 
					            form.on('switch(' + filter + ')', function (obj) {
 | 
				
			||||||
 | 
					                let val = obj.elem.checked ? 1 : 0;
 | 
				
			||||||
 | 
					                $.post(modifyUrl, {id: this.value, field: this.name, value: val}, function (res) {
 | 
				
			||||||
 | 
					                    layer.msg(res.msg)
 | 
				
			||||||
 | 
					                    if (res.code !== 0) {
 | 
				
			||||||
 | 
					                        //操作不成功则刷新页面
 | 
				
			||||||
 | 
					                        insTb.reload();
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                })
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // 监听搜索操作
 | 
				
			||||||
 | 
					        form.on('submit(data-search-btn)', function (data) {
 | 
				
			||||||
 | 
					            //执行搜索重载
 | 
				
			||||||
 | 
					            table.reload('table-container', {
 | 
				
			||||||
 | 
					                page: {curr: 1}
 | 
				
			||||||
 | 
					                , where: data.field
 | 
				
			||||||
 | 
					            }, 'data');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return false;
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    /*** index end ***/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if ($('.location-operate-page').length > 0) {
 | 
				
			||||||
 | 
					        let parentCategory = $('#parent-category');
 | 
				
			||||||
 | 
					        let categoryList = parentCategory.data('list') ? parentCategory.data('list') : [];
 | 
				
			||||||
 | 
					        xmSelect.render({
 | 
				
			||||||
 | 
					            el: '#parent-category',
 | 
				
			||||||
 | 
					            paging: false,
 | 
				
			||||||
 | 
					            autoRow: true,
 | 
				
			||||||
 | 
					            clickClose: true,
 | 
				
			||||||
 | 
					            name: 'category_id',
 | 
				
			||||||
 | 
					            tips: '请选择分类',
 | 
				
			||||||
 | 
					            direction: 'auto',
 | 
				
			||||||
 | 
					            height: 'auto',
 | 
				
			||||||
 | 
					            model: {
 | 
				
			||||||
 | 
					                icon: 'hidden',
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            prop: {
 | 
				
			||||||
 | 
					                name: 'title',
 | 
				
			||||||
 | 
					                value: 'id',
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            tree: {
 | 
				
			||||||
 | 
					                show: true,
 | 
				
			||||||
 | 
					                strict: false,
 | 
				
			||||||
 | 
					                clickCheck: true,
 | 
				
			||||||
 | 
					                expandedKeys: true,
 | 
				
			||||||
 | 
					                clickExpand: false
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            theme: {
 | 
				
			||||||
 | 
					                color: '#1e84ff',
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            data: categoryList
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        laydate.render({
 | 
				
			||||||
 | 
					            elem: '#published-at',
 | 
				
			||||||
 | 
					            type: 'datetime',
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,739 @@
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					// +----------------------------------------------------------------------
 | 
				
			||||||
 | 
					// | ThinkPHP [ WE CAN DO IT JUST THINK ]
 | 
				
			||||||
 | 
					// +----------------------------------------------------------------------
 | 
				
			||||||
 | 
					// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved.
 | 
				
			||||||
 | 
					// +----------------------------------------------------------------------
 | 
				
			||||||
 | 
					// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
 | 
				
			||||||
 | 
					// +----------------------------------------------------------------------
 | 
				
			||||||
 | 
					// | Author: 流年 <liu21st@gmail.com>
 | 
				
			||||||
 | 
					// +----------------------------------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use think\Collection;
 | 
				
			||||||
 | 
					use think\db\exception\DbException;
 | 
				
			||||||
 | 
					use think\exception\ClassNotFoundException;
 | 
				
			||||||
 | 
					use think\facade\Config as CConfig;
 | 
				
			||||||
 | 
					use think\Model;
 | 
				
			||||||
 | 
					use think\Paginator;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 应用公共文件
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if (!function_exists('widget')) {
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 渲染输出Widget
 | 
				
			||||||
 | 
					     * @param  string  $name  Widget名称
 | 
				
			||||||
 | 
					     * @param  array  $data  传入的参数
 | 
				
			||||||
 | 
					     * @return mixed
 | 
				
			||||||
 | 
					     * milo 2019-05-08 从TP5.1代码中拿来修改的
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    function widget($name, $data = [])
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return action($name, $data, 'widget');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					if (!function_exists('action')) {
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 调用模块的操作方法 参数格式 [模块/控制器/]操作
 | 
				
			||||||
 | 
					     * @param  string  $url  调用地址
 | 
				
			||||||
 | 
					     * @param  string|array  $vars  调用参数 支持字符串和数组
 | 
				
			||||||
 | 
					     * @param  string  $layer  要调用的控制层名称
 | 
				
			||||||
 | 
					     * @param  bool  $appendSuffix  是否添加类名后缀
 | 
				
			||||||
 | 
					     * @return mixed
 | 
				
			||||||
 | 
					     * milo 2019-05-08 从TP5.1代码中拿来修改的
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    function action($url, $vars = [], $layer = 'controller', $appendSuffix = false)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $info   = pathinfo($url);
 | 
				
			||||||
 | 
					        $action = $info['basename'];
 | 
				
			||||||
 | 
					        $module = '.' != $info['dirname'] ? $info['dirname'] : request()->controller();
 | 
				
			||||||
 | 
					        $class  = controller($module, $layer);
 | 
				
			||||||
 | 
					        if (is_scalar($vars)) {
 | 
				
			||||||
 | 
					            if (strpos($vars, '=')) {
 | 
				
			||||||
 | 
					                parse_str($vars, $vars);
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                $vars = [$vars];
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return app()->invokeMethod([$class, $action.config('route.action_suffix')], $vars);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					if (!function_exists('controller')) {
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 实例化(分层)控制器 格式:[模块名/]控制器名
 | 
				
			||||||
 | 
					     * @access public
 | 
				
			||||||
 | 
					     * @param  string  $name  资源地址
 | 
				
			||||||
 | 
					     * @param  string  $layer  控制层名称
 | 
				
			||||||
 | 
					     * @param  bool  $appendSuffix  是否添加类名后缀
 | 
				
			||||||
 | 
					     * @param  string  $empty  空控制器名称
 | 
				
			||||||
 | 
					     * @return object
 | 
				
			||||||
 | 
					     * @throws ClassNotFoundException
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * milo 2019-05-08 从TP5.1代码中拿来修改的
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    function controller($name, $layer = 'controller', $empty = '')
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $class = parseClass($name, $layer);
 | 
				
			||||||
 | 
					        if (class_exists($class)) {
 | 
				
			||||||
 | 
					            return app()->make($class);
 | 
				
			||||||
 | 
					        } elseif ($empty && class_exists($emptyClass = app()->parseClass($layer, $empty))) {
 | 
				
			||||||
 | 
					            return app()->make($emptyClass);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        throw new ClassNotFoundException('class not exists:'.$class, $class);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if (!function_exists('parseClass')) {
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 解析模块和类名
 | 
				
			||||||
 | 
					     * @access protected
 | 
				
			||||||
 | 
					     * @param  string  $name  资源地址
 | 
				
			||||||
 | 
					     * @param  string  $layer  验证层名称
 | 
				
			||||||
 | 
					     * @param  bool  $appendSuffix  是否添加类名后缀
 | 
				
			||||||
 | 
					     * @return array
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * milo 2019-05-08 从TP5.1代码中拿来修改的
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    function parseClass($name, $layer)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (false !== strpos($name, '\\')) {
 | 
				
			||||||
 | 
					            $class = $name;
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            if (strpos($name, '/')) {
 | 
				
			||||||
 | 
					                $names = explode('/', $name, 2);
 | 
				
			||||||
 | 
					                $name  = $names[1];
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            $class = app()->parseClass($layer, $name);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return $class;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if (!function_exists('randomStr')) {
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 获取随机字符串
 | 
				
			||||||
 | 
					     * @param  int  $type  0:数字(默认);1:全部;2:小写字母;3:大写字母;4:字母;
 | 
				
			||||||
 | 
					     * @param  int  $len  字符串长度
 | 
				
			||||||
 | 
					     * @return string
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    function randomStr($type = 0, $len = 5)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $strPol = "0123456789";
 | 
				
			||||||
 | 
					        if ($type == 1) {
 | 
				
			||||||
 | 
					            $strPol = "ABCDEFGHIJKLMOPQRSTUVWYZ0123456789abcdefghijklmopqrstuvwyz";
 | 
				
			||||||
 | 
					        } elseif ($type == 2) {
 | 
				
			||||||
 | 
					            $strPol = "abcdefghijklmopqrstuvwyz";
 | 
				
			||||||
 | 
					        } elseif ($type == 3) {
 | 
				
			||||||
 | 
					            $strPol = "ABCDEFGHIJKLMOPQRSTUVWYZ";
 | 
				
			||||||
 | 
					        } elseif ($type == 4) {
 | 
				
			||||||
 | 
					            $strPol = "ABCDEFGHIJKLMOPQRSTUVWYZabcdefghijklmopqrstuvwyz";
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        $max = strlen($strPol) - 1;
 | 
				
			||||||
 | 
					        $str = '';
 | 
				
			||||||
 | 
					        for ($i = 0; $i < $len; $i++) {
 | 
				
			||||||
 | 
					            $str .= $strPol[rand(0, $max)];
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return $str;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if (!function_exists('isMobile')) {
 | 
				
			||||||
 | 
					    //判断访问终端是否为移动端
 | 
				
			||||||
 | 
					    function isMobile()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        // 如果有HTTP_X_WAP_PROFILE则一定是移动设备
 | 
				
			||||||
 | 
					        if (isset($_SERVER['HTTP_X_WAP_PROFILE'])) {
 | 
				
			||||||
 | 
					            return true;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        // 如果via信息含有wap则一定是移动设备,部分服务商会屏蔽该信息
 | 
				
			||||||
 | 
					        if (isset($_SERVER['HTTP_VIA'])) {
 | 
				
			||||||
 | 
					            // 找不到为flase,否则为true
 | 
				
			||||||
 | 
					            return stristr($_SERVER['HTTP_VIA'], "wap") ? true : false;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        // 脑残法,判断手机发送的客户端标志,兼容性有待提高。其中'MicroMessenger'是电脑微信
 | 
				
			||||||
 | 
					        if (isset($_SERVER['HTTP_USER_AGENT'])) {
 | 
				
			||||||
 | 
					            $clientkeywords = [
 | 
				
			||||||
 | 
					                'nokia', 'sony', 'ericsson', 'mot', 'samsung', 'htc', 'sgh', 'lg', 'sharp', 'sie-', 'philips',
 | 
				
			||||||
 | 
					                'panasonic', 'alcatel', 'lenovo', 'iphone', 'ipod', 'blackberry', 'meizu', 'android', 'netfront',
 | 
				
			||||||
 | 
					                'symbian', 'ucweb', 'windowsce', 'palm', 'operamini', 'operamobi', 'openwave', 'nexusone', 'cldc',
 | 
				
			||||||
 | 
					                'midp', 'wap', 'mobile', 'MicroMessenger'
 | 
				
			||||||
 | 
					            ];
 | 
				
			||||||
 | 
					            // 从HTTP_USER_AGENT中查找手机浏览器的关键字
 | 
				
			||||||
 | 
					            if (preg_match("/(".implode('|', $clientkeywords).")/i", strtolower($_SERVER['HTTP_USER_AGENT']))) {
 | 
				
			||||||
 | 
					                return true;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        // 协议法,因为有可能不准确,放到最后判断
 | 
				
			||||||
 | 
					        if (isset ($_SERVER['HTTP_ACCEPT'])) {
 | 
				
			||||||
 | 
					            // 如果只支持wml并且不支持html那一定是移动设备
 | 
				
			||||||
 | 
					            // 如果支持wml和html但是wml在html之前则是移动设备
 | 
				
			||||||
 | 
					            if ((strpos($_SERVER['HTTP_ACCEPT'], 'vnd.wap.wml') !== false) && (strpos($_SERVER['HTTP_ACCEPT'],
 | 
				
			||||||
 | 
					                        'text/html') === false || (strpos($_SERVER['HTTP_ACCEPT'],
 | 
				
			||||||
 | 
					                            'vnd.wap.wml') < strpos($_SERVER['HTTP_ACCEPT'], 'text/html')))) {
 | 
				
			||||||
 | 
					                return true;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					//根据栏目获取路径
 | 
				
			||||||
 | 
					if (!function_exists('getUri')) {
 | 
				
			||||||
 | 
					    function getUri($cate)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $url = '';
 | 
				
			||||||
 | 
					        if (!empty($cate)) {
 | 
				
			||||||
 | 
					            if ($cate['is_index']) {
 | 
				
			||||||
 | 
					                $url = '/';
 | 
				
			||||||
 | 
					            } elseif (!empty($cate['url'])) {
 | 
				
			||||||
 | 
					                $url = $cate['url'];
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                $url = url($cate['template'].'/index', ['category_id' => $cate['id']]);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return $url;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//根据文件大小转换为文字
 | 
				
			||||||
 | 
					if (!function_exists('sizeToStr')) {
 | 
				
			||||||
 | 
					    function sizeToStr($size)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (!is_numeric($size) || $size <= 0) {
 | 
				
			||||||
 | 
					            return '';
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        $size = $size / 1024;
 | 
				
			||||||
 | 
					        if ($size < 1024) {
 | 
				
			||||||
 | 
					            return sprintf("%.2fK", $size);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        $size = $size / 1024;
 | 
				
			||||||
 | 
					        if ($size < 1024) {
 | 
				
			||||||
 | 
					            return sprintf("%.2fM", $size);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        $size = $size / 1024;
 | 
				
			||||||
 | 
					        return sprintf("%.2fG", $size);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//根据路径获取文件名
 | 
				
			||||||
 | 
					if (!function_exists('getKeyByPath')) {
 | 
				
			||||||
 | 
					    function getKeyByPath($path)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return substr($path, strrpos($path, '/') + 1);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//富文本中提取图片路径
 | 
				
			||||||
 | 
					if (!function_exists('getImageUrlFromText')) {
 | 
				
			||||||
 | 
					    function getImageUrlFromText($content)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        preg_match_all('/<img.*?src="(.*?)".*?>/is', $content, $imgs);
 | 
				
			||||||
 | 
					        $data = [];
 | 
				
			||||||
 | 
					        if (!empty($imgs) && !empty($imgs[1])) {
 | 
				
			||||||
 | 
					            foreach ($imgs[1] as $img) {
 | 
				
			||||||
 | 
					                if (substr($img, 0, 4) != 'http') {
 | 
				
			||||||
 | 
					                    $key        = getKeyByPath($img);
 | 
				
			||||||
 | 
					                    $data[$key] = $img;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return $data;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 是否http开头
 | 
				
			||||||
 | 
					if (!function_exists('isHttpUrl')) {
 | 
				
			||||||
 | 
					    function isHttpUrl(string $url): bool
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return substr(trim($url), 0, 4) == 'http';
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//富文本中提取视频路径
 | 
				
			||||||
 | 
					if (!function_exists('getVideoUrlFromText')) {
 | 
				
			||||||
 | 
					    function getVideoUrlFromText($content)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        preg_match_all('/<video.*?src="(.*?)".*?>/is', $content, $videos);
 | 
				
			||||||
 | 
					        $data = [];
 | 
				
			||||||
 | 
					        if (!empty($videos) && !empty($videos[1])) {
 | 
				
			||||||
 | 
					            foreach ($videos[1] as $video) {
 | 
				
			||||||
 | 
					                if (substr($video, 0, 4) != 'http') {
 | 
				
			||||||
 | 
					                    $key        = getKeyByPath($video);
 | 
				
			||||||
 | 
					                    $data[$key] = $video;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return $data;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//获取目录下的所有文件
 | 
				
			||||||
 | 
					if (!function_exists('getAllFilesByPath')) {
 | 
				
			||||||
 | 
					    function getAllFilesByPath($path, $rootPath)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (is_dir($path) && file_exists($path)) {
 | 
				
			||||||
 | 
					            $items = scandir($path);
 | 
				
			||||||
 | 
					            $files = [];
 | 
				
			||||||
 | 
					            foreach ($items as $item) {
 | 
				
			||||||
 | 
					                if (substr($item, 0, 1) != '.' && strpos($item, '_') == false) {
 | 
				
			||||||
 | 
					                    $itemPath = $path.'/'.$item;
 | 
				
			||||||
 | 
					                    if (is_file($itemPath)) {
 | 
				
			||||||
 | 
					                        $size         = filesize($itemPath);
 | 
				
			||||||
 | 
					                        $files[$item] = [
 | 
				
			||||||
 | 
					                            'path'     => str_replace($rootPath, '/', $itemPath),
 | 
				
			||||||
 | 
					                            'realPath' => $itemPath,
 | 
				
			||||||
 | 
					                            'size'     => $size,
 | 
				
			||||||
 | 
					                            'sizeStr'  => sizeToStr($size),
 | 
				
			||||||
 | 
					                            'suffix'   => strtolower(substr($item, strrpos($item, '.') + 1))    //后缀
 | 
				
			||||||
 | 
					                        ];
 | 
				
			||||||
 | 
					                    } elseif (is_dir($itemPath)) {
 | 
				
			||||||
 | 
					                        $childFiles = getAllFilesByPath($itemPath, $rootPath);
 | 
				
			||||||
 | 
					                        if (!empty($childFiles)) {
 | 
				
			||||||
 | 
					                            $files = array_merge($files, $childFiles);
 | 
				
			||||||
 | 
					                        } else {
 | 
				
			||||||
 | 
					                            rmdir($itemPath);
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            return $files;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return [];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//过滤get输入
 | 
				
			||||||
 | 
					if (!function_exists('getFilter')) {
 | 
				
			||||||
 | 
					    function getFilter($value)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $getFilter = "'|(and|or)\b.+?(>|<|=|in|like)|\/\*.+?\*\/|<\s*script\b|\bEXEC\b|UNION.+?SELECT|UPDATE.+?SET|INSERT\s+INTO.+?VALUES|(SELECT|DELETE).+?FROM|(CREATE|ALTER|DROP|TRUNCATE)\s+(TABLE|DATABASE)";
 | 
				
			||||||
 | 
					        $forArray  = false;
 | 
				
			||||||
 | 
					        if (is_array($value)) {
 | 
				
			||||||
 | 
					            $forFilter = implode($value);
 | 
				
			||||||
 | 
					            $forArray  = true;
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            $forFilter = $value;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (preg_match("/".$getFilter."/is", $forFilter) == 1) {
 | 
				
			||||||
 | 
					            $value = $forArray ? [] : '';
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return filterExp($value);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//过滤post录入
 | 
				
			||||||
 | 
					if (!function_exists('postFilter')) {
 | 
				
			||||||
 | 
					    function postFilter($value)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $postFilter = "\b(and|or)\b.{1,6}?(=|>|<|\bin\b|\blike\b)|\/\*.+?\*\/|<\s*script\b|\bEXEC\b|UNION.+?SELECT|UPDATE.+?SET|INSERT\s+INTO.+?VALUES|(SELECT|DELETE).+?FROM|(CREATE|ALTER|DROP|TRUNCATE)\s+(TABLE|DATABASE)";
 | 
				
			||||||
 | 
					        $forArray   = false;
 | 
				
			||||||
 | 
					        if (is_array($value)) {
 | 
				
			||||||
 | 
					            $forFilter = implode($value);
 | 
				
			||||||
 | 
					            $forArray  = true;
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            $forFilter = $value;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (preg_match("/".$postFilter."/is", $forFilter) == 1) {
 | 
				
			||||||
 | 
					            $value = $forArray ? [] : '';
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return filterExp($value);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//过滤cookie数据
 | 
				
			||||||
 | 
					if (!function_exists('cookieFilter')) {
 | 
				
			||||||
 | 
					    function cookieFilter($value)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $cookieFilter = "\b(and|or)\b.{1,6}?(=|>|<|\bin\b|\blike\b)|\/\*.+?\*\/|<\s*script\b|\bEXEC\b|UNION.+?SELECT|UPDATE.+?SET|INSERT\s+INTO.+?VALUES|(SELECT|DELETE).+?FROM|(CREATE|ALTER|DROP|TRUNCATE)\s+(TABLE|DATABASE)";
 | 
				
			||||||
 | 
					        $forArray     = false;
 | 
				
			||||||
 | 
					        if (is_array($value)) {
 | 
				
			||||||
 | 
					            $forFilter = implode($value);
 | 
				
			||||||
 | 
					            $forArray  = true;
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            $forFilter = $value;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (preg_match("/".$cookieFilter."/is", $forFilter) == 1) {
 | 
				
			||||||
 | 
					            $value = $forArray ? [] : '';
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return filterExp($value);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if (!function_exists('filterExp')) {
 | 
				
			||||||
 | 
					    function filterExp($value)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $filter   = '/^(\s)+(EXP|NEQ|GT|EGT|LT|ELT|OR|XOR|LIKE|NOTLIKE|NOT LIKE|NOT BETWEEN|NOTBETWEEN|BETWEEN|NOTIN|NOT IN|IN)(\s)+$/i';
 | 
				
			||||||
 | 
					        $forArray = false;
 | 
				
			||||||
 | 
					        if (is_array($value)) {
 | 
				
			||||||
 | 
					            $forFilter = implode($value);
 | 
				
			||||||
 | 
					            $forArray  = true;
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            $forFilter = $value;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (preg_match($filter, $forFilter) == 1) {
 | 
				
			||||||
 | 
					            $value = $forArray ? [] : '';
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return $value;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if (!function_exists('arrayHtmlFilter')) {
 | 
				
			||||||
 | 
					    function arrayHtmlFilter($arr)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        foreach ($arr as $k => $one) {
 | 
				
			||||||
 | 
					            if (is_array($one)) {
 | 
				
			||||||
 | 
					                $arr[$k] = arrayHtmlFilter($one);
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                $one     = trim($one);
 | 
				
			||||||
 | 
					                $arr[$k] = strip_tags($one);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return $arr;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if (!function_exists('toCamelString')) {
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 转驼峰
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param  string  $string
 | 
				
			||||||
 | 
					     * @param  false  $small  默认false 为true首字母小写
 | 
				
			||||||
 | 
					     * @return string
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    function toCamelString(string $string, bool $small = false): string
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        //例: xxx_yYy_zzZ 和 xxX-yyy-Zzz
 | 
				
			||||||
 | 
					        //1. 字符串转小写 xxx_yyy_zzz xxx-yyy-zzz
 | 
				
			||||||
 | 
					        //2. -和_转空格 xxx yyy zzz
 | 
				
			||||||
 | 
					        //3. 单词首字母大写 Xxx Yyy Zzz
 | 
				
			||||||
 | 
					        //4. 清除空格 XxxYyyZzz
 | 
				
			||||||
 | 
					        //处理下划线、减号 统统专程大驼峰 如xxx_yyy_zzz xxx-yyy-zzz 均转为 XxxYyyZzz
 | 
				
			||||||
 | 
					        $string = strtolower($string);
 | 
				
			||||||
 | 
					        $string = str_replace('-', ' ', $string);
 | 
				
			||||||
 | 
					        $string = str_replace('_', ' ', $string);
 | 
				
			||||||
 | 
					        $string = str_replace(' ', '', ucwords($string));
 | 
				
			||||||
 | 
					        if ($small) {
 | 
				
			||||||
 | 
					            $string = lcfirst($string);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return $string;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if (!function_exists('unCamelize')) {
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 驼峰命名转特定分隔符[如下划线]命名
 | 
				
			||||||
 | 
					     * @param  string  $camelCaps
 | 
				
			||||||
 | 
					     * @param  string  $separator
 | 
				
			||||||
 | 
					     * @return string
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    function unCamelize(string $camelCaps, string $separator = '-'): string
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return strtolower(preg_replace('/([a-z])([A-Z])/', "$1".$separator."$2", $camelCaps));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if (!function_exists('generateRand')) {
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 生成随机数
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param  int  $length  长度
 | 
				
			||||||
 | 
					     * @param  string  $type  模式 默认mix混合 number纯数字 alpha字母
 | 
				
			||||||
 | 
					     * @return string
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    function generateRand(int $length = 8, string $type = 'mix'): string
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $alphabet    = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
 | 
				
			||||||
 | 
					        $number      = '0123456789';
 | 
				
			||||||
 | 
					        $alphabetLen = strlen($alphabet) - 1;
 | 
				
			||||||
 | 
					        $numberLen   = 9;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        switch ($type) {
 | 
				
			||||||
 | 
					            case 'number':
 | 
				
			||||||
 | 
					                $str = $number;
 | 
				
			||||||
 | 
					                $len = $numberLen;
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            case 'alpha':
 | 
				
			||||||
 | 
					                $str = $alphabet;
 | 
				
			||||||
 | 
					                $len = $alphabetLen;
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            default:
 | 
				
			||||||
 | 
					                $str = $alphabet.$number;
 | 
				
			||||||
 | 
					                $len = $alphabetLen + $numberLen;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $randStr = '';
 | 
				
			||||||
 | 
					        $str     = str_shuffle($str);
 | 
				
			||||||
 | 
					        for ($i = 0; $i < $length; $i++) {
 | 
				
			||||||
 | 
					            $num     = mt_rand(0, $len);
 | 
				
			||||||
 | 
					            $randStr .= $str[$num];
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return $randStr;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if (!function_exists('generateCode')) {
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 生成特定编码
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param  string  $type  类型 默认mix混合 number纯数字 alpha字母
 | 
				
			||||||
 | 
					     * @param  int  $len  随机数长度
 | 
				
			||||||
 | 
					     * @return string
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    function generateCode(string $type = 'number', int $len = 6): string
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        //#时间戳+微秒+6位随机数
 | 
				
			||||||
 | 
					        $time    = microtime(true);
 | 
				
			||||||
 | 
					        $timeStr = str_replace('.', '', $time);
 | 
				
			||||||
 | 
					        return sprintf("%s%s", $timeStr, generateRand($len, $type));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if (!function_exists('checkMobile')) {
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 检测手机号
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param  string  $mobile
 | 
				
			||||||
 | 
					     * @return bool
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    function checkMobile(string $mobile): bool
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (preg_match("/^1[3456789]{1}\d{9}$/", $mobile)) {
 | 
				
			||||||
 | 
					            return true;
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            return false;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if (!function_exists('arrayKeysFilter')) {
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 数组键名过滤
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param  array  $data
 | 
				
			||||||
 | 
					     * @param  array  $allowKeys
 | 
				
			||||||
 | 
					     * @return array
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    function arrayKeysFilter(array $data, array $allowKeys): array
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $list = [];
 | 
				
			||||||
 | 
					        foreach ($data as $key => $val) {
 | 
				
			||||||
 | 
					            if (in_array($key, $allowKeys)) {
 | 
				
			||||||
 | 
					                $list[$key] = $val;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return $list;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if (!function_exists('getFilesize')) {
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 尺寸单位转换
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param $num
 | 
				
			||||||
 | 
					     * @return string
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    function getFilesize($num): string
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $p      = 0;
 | 
				
			||||||
 | 
					        $format = 'B';
 | 
				
			||||||
 | 
					        if ($num > 0 && $num < 1024) {
 | 
				
			||||||
 | 
					            return number_format($num).' '.$format;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if ($num >= 1024 && $num < pow(1024, 2)) {
 | 
				
			||||||
 | 
					            $p      = 1;
 | 
				
			||||||
 | 
					            $format = 'KB';
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if ($num >= pow(1024, 2) && $num < pow(1024, 3)) {
 | 
				
			||||||
 | 
					            $p      = 2;
 | 
				
			||||||
 | 
					            $format = 'MB';
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if ($num >= pow(1024, 3) && $num < pow(1024, 4)) {
 | 
				
			||||||
 | 
					            $p      = 3;
 | 
				
			||||||
 | 
					            $format = 'GB';
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if ($num >= pow(1024, 4) && $num < pow(1024, 5)) {
 | 
				
			||||||
 | 
					            $p      = 3;
 | 
				
			||||||
 | 
					            $format = 'TB';
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        $num /= pow(1024, $p);
 | 
				
			||||||
 | 
					        return number_format($num, 3).' '.$format;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if (!function_exists('arrayNullToString')) {
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 数组|或数据集中null值转为空字符串,并以数组格式返回
 | 
				
			||||||
 | 
					     * 通常用于api json 返回内容null转换
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param  array  $data  【array|collection】
 | 
				
			||||||
 | 
					     * @return array
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    function arrayNullToString(array $data): array
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if ($data instanceof Collection || $data instanceof Model) {
 | 
				
			||||||
 | 
					            $data = $data->toArray();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        // 判断是否可以遍历
 | 
				
			||||||
 | 
					        if (is_iterable($data)) {
 | 
				
			||||||
 | 
					            foreach ($data as $key => $val) {
 | 
				
			||||||
 | 
					                if ($val instanceof Collection || $data instanceof Model) {
 | 
				
			||||||
 | 
					                    $val = $val->toArray();
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                if (is_iterable($val)) {
 | 
				
			||||||
 | 
					                    $data[$key] = arrayNullToString($val);
 | 
				
			||||||
 | 
					                } elseif ($val === null) {
 | 
				
			||||||
 | 
					                    $data[$key] = '';
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            $data = [];
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return $data;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if (!function_exists('arrayKeysExcludeFilter')) {
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 数组键名排除过滤
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param  array  $data
 | 
				
			||||||
 | 
					     * @param  array  $excludeKeys  排除的字段
 | 
				
			||||||
 | 
					     * @return array
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    function arrayKeysExcludeFilter(array $data, array $excludeKeys): array
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        foreach ($data as $key => $val) {
 | 
				
			||||||
 | 
					            if (in_array($key, $excludeKeys)) {
 | 
				
			||||||
 | 
					                unset($data[$key]);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return $data;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if (!function_exists('getLatelyWeekDate')) {
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 获取本周的周一 到周日的日期
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    function getLatelyWeekDate()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        //本周一
 | 
				
			||||||
 | 
					        $oneDate     = date('Y-m-d 00:00:00', (time() - ((date('w') == 0 ? 7 : date('w')) - 1) * 86400)); //w为星期几的数字形式,这里0为周日
 | 
				
			||||||
 | 
					        $oneDateTime = strtotime($oneDate);
 | 
				
			||||||
 | 
					        //返回周一到周天  1-7
 | 
				
			||||||
 | 
					        return [
 | 
				
			||||||
 | 
					            "1" => ["date" => $oneDate],
 | 
				
			||||||
 | 
					            "2" => ["date" => date('Y-m-d 00:00:00', $oneDateTime + ((86400 * 1)))],
 | 
				
			||||||
 | 
					            "3" => ["date" => date('Y-m-d 00:00:00', $oneDateTime + ((86400 * 2)))],
 | 
				
			||||||
 | 
					            "4" => ["date" => date('Y-m-d 00:00:00', $oneDateTime + ((86400 * 3)))],
 | 
				
			||||||
 | 
					            "5" => ["date" => date('Y-m-d 00:00:00', $oneDateTime + ((86400 * 4)))],
 | 
				
			||||||
 | 
					            "6" => ["date" => date('Y-m-d 00:00:00', $oneDateTime + ((86400 * 5)))],
 | 
				
			||||||
 | 
					            "7" => ["date" => date('Y-m-d 00:00:00', $oneDateTime + ((86400 * 6)))],
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if (!function_exists('stringDesensitization')) {
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 字符串脱敏 默认给手机号脱敏 其他未兼容
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param  string  $string
 | 
				
			||||||
 | 
					     * @param  string  $s
 | 
				
			||||||
 | 
					     * @param  int  $start
 | 
				
			||||||
 | 
					     * @param  int  $len
 | 
				
			||||||
 | 
					     * @return string
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    function stringDesensitization(string $string, string $s = '****', int $start = 3, int $len = 4): string
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return substr_replace($string, $s, $start, $len);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if (!function_exists('resourceJoin')) {
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 资源拼接前缀  如/xxx/xxxx/xxx.jpg 拼接为前缀http://www.xxx.com/xxx/xxxx/xxx.jpg
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param  string  $string
 | 
				
			||||||
 | 
					     * @param  string  $domain
 | 
				
			||||||
 | 
					     * @return string
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    function resourceJoin(string $string, string $domain = ''): string
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (empty($string)) {
 | 
				
			||||||
 | 
					            return '';
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (isHttpUrl($string)) {
 | 
				
			||||||
 | 
					            return $string;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        CConfig::load('extra/qiniu', 'qiniu');
 | 
				
			||||||
 | 
					        $customDomain = config('qiniu')['customDomain'] ?? '';
 | 
				
			||||||
 | 
					        $domain       = $customDomain ?: $domain;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $domain.$string;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if (!function_exists('checkPathExistWithMake')) {
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 检测文件夹是否存在,不存在时自动创建(需要有写入权限)
 | 
				
			||||||
 | 
					     * 支持递归创建
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param  string  $absolutePath
 | 
				
			||||||
 | 
					     * @return bool
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    function checkPathExistWithMake(string $absolutePath): bool
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            $absolutePath = rtrim($absolutePath, '/');
 | 
				
			||||||
 | 
					            if (empty($absolutePath)) {
 | 
				
			||||||
 | 
					                return false;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (!is_dir($absolutePath)) {
 | 
				
			||||||
 | 
					                return mkdir($absolutePath, 0777, true);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return true;
 | 
				
			||||||
 | 
					        } catch (\Exception $e) {
 | 
				
			||||||
 | 
					            return false;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if (!function_exists('replaceStoragePath'))
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    function replaceStoragePath ($content, $domain = ''){
 | 
				
			||||||
 | 
					        if (empty($domain)) {
 | 
				
			||||||
 | 
					            CConfig::load('extra/qiniu', 'qiniu');
 | 
				
			||||||
 | 
					            $customDomain = config('qiniu')['customDomain'] ?? '';
 | 
				
			||||||
 | 
					            $domain = $customDomain ?: request()->domain();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        $pregRule = "/<[img|IMG].*?src=[\'|\"][\/storage]{1}(.*?(?:[\.jpg|\.jpeg|\.png|\.gif|\.bmp]))[\'|\"].*?[\/]?>/";
 | 
				
			||||||
 | 
					        return preg_replace($pregRule, '< img src="' . $domain . '/${1}" style="max-width:100%">', (string)$content  );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if (!function_exists('periodDate')) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 获取期间日期所有日期
 | 
				
			||||||
 | 
					     * @param $startDate
 | 
				
			||||||
 | 
					     * @param $endDate
 | 
				
			||||||
 | 
					     * @return array
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    function periodDate($startDate, $endDate): array
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $startTime = strtotime($startDate);
 | 
				
			||||||
 | 
					        $endTime   = strtotime($endDate);
 | 
				
			||||||
 | 
					        $arr       = array();
 | 
				
			||||||
 | 
					        while ($startTime <= $endTime) {
 | 
				
			||||||
 | 
					            $arr[]     = date('Y-m-d', $startTime);
 | 
				
			||||||
 | 
					            $startTime = strtotime('+1 day', $startTime);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return $arr;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,42 @@
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace app\controller;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use app\service\Redis;
 | 
				
			||||||
 | 
					use think\response\View;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * 控制器基础类
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					class Base extends BaseController
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    //需要向模板传递的值
 | 
				
			||||||
 | 
					    protected $data = [];
 | 
				
			||||||
 | 
					    //系统配置信息
 | 
				
			||||||
 | 
					    protected $system = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    protected $auth = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    protected $authId = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    protected $redis = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // 初始化
 | 
				
			||||||
 | 
					    protected function initialize()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $this->middleware = [
 | 
				
			||||||
 | 
					            'login' => ['except' => $this->noNeedLogin],
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->auth         = session('frontend_auth') ?? [];
 | 
				
			||||||
 | 
					        $this->data['auth'] = $this->auth;
 | 
				
			||||||
 | 
					        $this->authId       = $this->auth['id'] ?? 0;
 | 
				
			||||||
 | 
					        $this->redis        = Redis::instance();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    //模板
 | 
				
			||||||
 | 
					    protected function view($template = ''): View
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return view($template)->assign($this->data);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,254 @@
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					declare (strict_types=1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace app\controller;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use think\{App, Request, response\Json, response\Redirect, response\View, Validate};
 | 
				
			||||||
 | 
					use Exception;
 | 
				
			||||||
 | 
					use think\exception\ValidateException;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * 控制器基础类
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					abstract class BaseController
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 无需登录的方法,同时也就不需要鉴权了
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @var array
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    protected $noNeedLogin = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 无需鉴权的方法,但需要登录
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @var array
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    protected $noNeedRight = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Request实例
 | 
				
			||||||
 | 
					     * @var Request
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    protected $request;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 应用实例
 | 
				
			||||||
 | 
					     * @var App
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    protected $app;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 是否批量验证
 | 
				
			||||||
 | 
					     * @var bool
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    protected $batchValidate = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 控制器中间件
 | 
				
			||||||
 | 
					     * @var array
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    protected $middleware = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 构造方法
 | 
				
			||||||
 | 
					     * @access public
 | 
				
			||||||
 | 
					     * @param  App  $app  应用对象
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function __construct(App $app)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $this->app     = $app;
 | 
				
			||||||
 | 
					        $this->request = $this->app->request;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // 控制器初始化
 | 
				
			||||||
 | 
					        $this->initialize();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // 初始化
 | 
				
			||||||
 | 
					    protected function initialize()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 验证数据
 | 
				
			||||||
 | 
					     * @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, '.')) {
 | 
				
			||||||
 | 
					                // 支持场景
 | 
				
			||||||
 | 
					                list($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);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 验证器
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param  array  $data
 | 
				
			||||||
 | 
					     * @param $validate
 | 
				
			||||||
 | 
					     * @param  array  $message
 | 
				
			||||||
 | 
					     * @param  bool  $batch
 | 
				
			||||||
 | 
					     * @return Json|bool
 | 
				
			||||||
 | 
					     * @throws Exception
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    protected function validateByApi(array $data, $validate, array $message = [], bool $batch = false)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            $this->validate($data, $validate, $message, $batch);
 | 
				
			||||||
 | 
					            return true;
 | 
				
			||||||
 | 
					        } catch (ValidateException $e) {
 | 
				
			||||||
 | 
					            $msg = $e->getMessage();
 | 
				
			||||||
 | 
					            if ($batch) {
 | 
				
			||||||
 | 
					                $msg = implode(',', $e->getError());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return $this->json(4000, $msg);
 | 
				
			||||||
 | 
					        } catch (Exception $e) {
 | 
				
			||||||
 | 
					            throw $e;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 验证器
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param  array  $data
 | 
				
			||||||
 | 
					     * @param $validate
 | 
				
			||||||
 | 
					     * @param  array  $message
 | 
				
			||||||
 | 
					     * @param  bool  $batch
 | 
				
			||||||
 | 
					     * @return Redirect
 | 
				
			||||||
 | 
					     * @throws Exception
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    protected function validateByView(array $data, $validate, array $message = [], bool $batch = false): Redirect
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            $this->validate($data, $validate, $message, $batch);
 | 
				
			||||||
 | 
					        } catch (ValidateException $e) {
 | 
				
			||||||
 | 
					            $msg = $e->getMessage();
 | 
				
			||||||
 | 
					            if ($batch) {
 | 
				
			||||||
 | 
					                $msg = implode(',', $e->getError());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return $this->error( $msg);
 | 
				
			||||||
 | 
					        } catch (Exception $e) {
 | 
				
			||||||
 | 
					            throw $e;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 操作成功跳转的快捷方法
 | 
				
			||||||
 | 
					     * @access protected
 | 
				
			||||||
 | 
					     * @param  mixed  $msg  提示信息
 | 
				
			||||||
 | 
					     * @param  string|null  $url  跳转的URL地址
 | 
				
			||||||
 | 
					     * @param  mixed  $data  返回的数据
 | 
				
			||||||
 | 
					     * @param  integer  $wait  跳转等待时间
 | 
				
			||||||
 | 
					     * @param  array  $header  发送的Header信息
 | 
				
			||||||
 | 
					     * @return Redirect
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    protected function success($msg = '', string $url = null, $data = '', int $wait = 3, array $header = []): Redirect
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (is_null($url) && isset($_SERVER["HTTP_REFERER"])) {
 | 
				
			||||||
 | 
					            $url = $_SERVER["HTTP_REFERER"];
 | 
				
			||||||
 | 
					        } elseif ($url) {
 | 
				
			||||||
 | 
					            $url = (strpos($url, '://') || 0 === strpos($url, '/')) ? $url : $this->app->route->buildUrl($url);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $result = [
 | 
				
			||||||
 | 
					            'code' => 1,
 | 
				
			||||||
 | 
					            'msg'  => $msg,
 | 
				
			||||||
 | 
					            'data' => $data,
 | 
				
			||||||
 | 
					            'url'  => $url,
 | 
				
			||||||
 | 
					            'wait' => $wait,
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					        return $this->redirect(url('error/404', $result));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 操作错误跳转的快捷方法
 | 
				
			||||||
 | 
					     * @access protected
 | 
				
			||||||
 | 
					     * @param  mixed  $msg  提示信息
 | 
				
			||||||
 | 
					     * @param  string|null  $url  跳转的URL地址
 | 
				
			||||||
 | 
					     * @param  mixed  $data  返回的数据
 | 
				
			||||||
 | 
					     * @param  integer  $wait  跳转等待时间
 | 
				
			||||||
 | 
					     * @return Redirect
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    protected function error($msg = '', string $url = null, $data = '', int $wait = 3): Redirect
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (is_null($url)) {
 | 
				
			||||||
 | 
					            $referer = $_SERVER['HTTP_REFERER'] ?? null;
 | 
				
			||||||
 | 
					            if (empty($referer)) {
 | 
				
			||||||
 | 
					                $url = $this->request->isAjax() ? '' : '/';
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                $url = $this->request->isAjax() ? '' : 'javascript:history.back(-1);';
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        } elseif ($url) {
 | 
				
			||||||
 | 
					            $url = (strpos($url, '://') || 0 === strpos($url, '/')) ? $url : $this->app->route->buildUrl($url);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        $result = [
 | 
				
			||||||
 | 
					            'code' => 0,
 | 
				
			||||||
 | 
					            'msg'  => $msg,
 | 
				
			||||||
 | 
					            'data' => $data,
 | 
				
			||||||
 | 
					            'url'  => $url,
 | 
				
			||||||
 | 
					            'wait' => $wait,
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->redirect(url('error/404', $result));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 返回封装后的API数据到客户端
 | 
				
			||||||
 | 
					     * 以json格式抛出异常
 | 
				
			||||||
 | 
					     * @access protected
 | 
				
			||||||
 | 
					     * @param  integer  $code  返回的code
 | 
				
			||||||
 | 
					     * @param  mixed  $msg  提示信息
 | 
				
			||||||
 | 
					     * @param  mixed  $data  要返回的数据
 | 
				
			||||||
 | 
					     * @return Json
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    protected function json(int $code = 0, $msg = '操作成功', $data = []): Json
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $result = [
 | 
				
			||||||
 | 
					            'code' => $code,
 | 
				
			||||||
 | 
					            'msg'  => $msg,
 | 
				
			||||||
 | 
					            'data' => $data
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					        return json($result);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * URL重定向
 | 
				
			||||||
 | 
					     * @access protected
 | 
				
			||||||
 | 
					     * @param  string  $url  跳转的URL表达式
 | 
				
			||||||
 | 
					     * @return Redirect
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    protected function redirect($url): Redirect
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (!is_string($url)) {
 | 
				
			||||||
 | 
					            $url = $url->__toString();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return redirect($url);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,61 @@
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace app\controller;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use app\service\Redis;
 | 
				
			||||||
 | 
					use think\response\View;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Error extends BaseController
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public function __call($method, $args)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if(request()->isAjax()) {
 | 
				
			||||||
 | 
					            return $this->json(4004, 'error request!');
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            $referer = $_SERVER['HTTP_REFERER'] ?? null;
 | 
				
			||||||
 | 
					            if (empty($referer)) {
 | 
				
			||||||
 | 
					                $url = '/';
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                $domain = $this->request->domain();
 | 
				
			||||||
 | 
					                $urlInfo = parse_url($referer);
 | 
				
			||||||
 | 
					                $scheme = $urlInfo['scheme'] ?? '';
 | 
				
			||||||
 | 
					                $requestSrc = '';
 | 
				
			||||||
 | 
					                if (!empty($scheme)) {
 | 
				
			||||||
 | 
					                    $requestSrc = $scheme.'://'.($urlInfo['host'] ?? '');
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                if($domain != $requestSrc) {
 | 
				
			||||||
 | 
					                    $url = '/';
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    $url = 'javascript:history.back(-1);';
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            $result = [
 | 
				
			||||||
 | 
					                'code' => 404,
 | 
				
			||||||
 | 
					                'msg'  => '无效请求! 没有找到相关资源',
 | 
				
			||||||
 | 
					                'data' => [],
 | 
				
			||||||
 | 
					                'url'  => $url,
 | 
				
			||||||
 | 
					                'wait' => 5,
 | 
				
			||||||
 | 
					            ];
 | 
				
			||||||
 | 
					            return view('/manager/error/jump')->assign($result);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function jump()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $param = request()->param();
 | 
				
			||||||
 | 
					        return view()->assign($param);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function notice(): View
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (Redis::instance()->get('activity_close') == 0) {
 | 
				
			||||||
 | 
					            header('Location:/coupon/index');
 | 
				
			||||||
 | 
					            exit;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return view();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,102 @@
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace app\controller;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use app\service\wx\WechatPay;
 | 
				
			||||||
 | 
					use Exception;
 | 
				
			||||||
 | 
					use think\facade\Log;
 | 
				
			||||||
 | 
					use think\response\Redirect;
 | 
				
			||||||
 | 
					use think\response\View;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Index
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @return \think\response\View
 | 
				
			||||||
 | 
					     * @throws Exception
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function index(): View
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        exit;
 | 
				
			||||||
 | 
					        return view();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 退出
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return Redirect
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function logout(): Redirect
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        session('frontend_auth', null);
 | 
				
			||||||
 | 
					        $req = $this->request->header('referer');
 | 
				
			||||||
 | 
					        return $this->redirect($req);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 微信的回调
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @throws \EasyWeChat\Kernel\Exceptions\Exception
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function callback()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if ($this->request->isPost()) {
 | 
				
			||||||
 | 
					            $app      = WechatPay::getInstance();
 | 
				
			||||||
 | 
					            $response = $app->handlePaidNotify(function ($message, $fail) {
 | 
				
			||||||
 | 
					                //                $aa = '{"appid":"wxa02e44170bc722cd","bank_type":"OTHERS","cash_fee":"1","fee_type":"CNY","is_subscribe":"N","mch_id":"1605090111","nonce_str":"60f7d8a1e4ac8","openid":"oKrEm0ehgsy2ZTWzEva4tbLuUgFw","out_trade_no":"16268555858753004863","result_code":"SUCCESS","return_code":"SUCCESS","sign":"DB3F6CDCB7FBB3B9DDF7C0CC8BBD5AAD","time_end":"20210721162000","total_fee":"1","trade_type":"JSAPI","transaction_id":"4200001200202107217942681078"}';
 | 
				
			||||||
 | 
					                //                $message = json_decode($aa, true);
 | 
				
			||||||
 | 
					                $m     = json_encode($message, JSON_UNESCAPED_UNICODE);
 | 
				
			||||||
 | 
					                if (!$order = OrderRepository::getInstance()->findOneByWhere(['coding' => $message['out_trade_no']])) {
 | 
				
			||||||
 | 
					                    $this->log(sprintf("[微信支付回调][%s][%s]订单支付成功,但系统查无此订单 info:%s", date('Y-m-d H:i:s'), $message['out_trade_no'], $m), 'error');
 | 
				
			||||||
 | 
					                    return true;//订单不存在
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                //记录日志
 | 
				
			||||||
 | 
					                $this->log(sprintf("[微信支付回调][%s][%s]订单支付成功 info:%s", date('Y-m-d H:i:s'), $message['out_trade_no'], $m), 'info');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if ($message['return_code'] === 'SUCCESS') { // return_code 表示通信状态,不代表支付状态
 | 
				
			||||||
 | 
					                    //更改订单状态
 | 
				
			||||||
 | 
					                    try {
 | 
				
			||||||
 | 
					                        $res = false;
 | 
				
			||||||
 | 
					                        // 用户是否支付成功
 | 
				
			||||||
 | 
					                        if (isset($message['result_code']) && $message['result_code'] === 'SUCCESS') {
 | 
				
			||||||
 | 
					                            //记录日志
 | 
				
			||||||
 | 
					                            $res = OrderRepository::getInstance()->setPaid($order['coding']);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                            $this->log(sprintf("[微信支付回调][%s][%s]订单支付成功 修改订单状态为%s", date('Y-m-d H:i:s'), $message['out_trade_no'], $res), 'info');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                            // 用户支付失败
 | 
				
			||||||
 | 
					                        } elseif (isset($message['result_code']) && $message['result_code'] === 'FAIL') {
 | 
				
			||||||
 | 
					                            //记录日志
 | 
				
			||||||
 | 
					                            $this->log(sprintf("[微信支付回调][%s][%s]订单支付失败 修改订单状态为%s", date('Y-m-d H:i:s'), $message['out_trade_no'], $res), 'info');
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        if (!$res) {
 | 
				
			||||||
 | 
					                            return $fail('Order status edit failed.');
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                    } catch (Exception $e) {
 | 
				
			||||||
 | 
					                        $this->log(sprintf("[微信支付回调][%s][%s]订单支付失败 失败原因:%s", date('Y-m-d H:i:s'), $message['out_trade_no'], $e->getMessage()), 'info');
 | 
				
			||||||
 | 
					                        //错误信息 触发
 | 
				
			||||||
 | 
					                        return $fail('Order error.');
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    return $fail('通信失败,请稍后再通知我');
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                return true;
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $response->send();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 记录订单日志
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param string $message
 | 
				
			||||||
 | 
					     * @param string $type
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    private function log(string $message, string $type = 'info'): void
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        Log::channel('order')->write($message, $type);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,116 @@
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace app\controller;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use app\model\Account;
 | 
				
			||||||
 | 
					use app\service\wx\Wechat;
 | 
				
			||||||
 | 
					use think\response\Redirect;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Login extends Base
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    protected $noNeedLogin = ['index', 'temp'];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function index(): Redirect
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (env('app_dev', false)) {
 | 
				
			||||||
 | 
					            $this->temp();
 | 
				
			||||||
 | 
					            exit;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        $code   = input('code/s', '');
 | 
				
			||||||
 | 
					        $wechat = Wechat::getInstance();
 | 
				
			||||||
 | 
					        if (empty($code)) {
 | 
				
			||||||
 | 
					            $redirectUrl = $wechat->oauth->scopes(['snsapi_userinfo'])->redirect(request()->domain().'/login/index');
 | 
				
			||||||
 | 
					            header('Location:'.$redirectUrl);
 | 
				
			||||||
 | 
					            exit;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $user = $wechat->oauth->userFromCode($code);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($userInfo = $user->getRaw()) {
 | 
				
			||||||
 | 
					            unset($userInfo['privilege']);
 | 
				
			||||||
 | 
					            $field = 'id,openid,nickname,sex,headimgurl,unionid,business_id,phone_active,mobile';
 | 
				
			||||||
 | 
					            if (!$account = Account::field($field)->where('openid', $userInfo['openid'])->find()) {
 | 
				
			||||||
 | 
					                $userInfo['created_at'] = date('Y-m-d H:i:s');
 | 
				
			||||||
 | 
					                $create                 = Account::create($userInfo);
 | 
				
			||||||
 | 
					                $account                = [
 | 
				
			||||||
 | 
					                    'id'           => $create['id'],
 | 
				
			||||||
 | 
					                    'openid'       => $create['openid'],
 | 
				
			||||||
 | 
					                    'nickname'     => $create['nickname'],
 | 
				
			||||||
 | 
					                    'sex'          => $create['sex'],
 | 
				
			||||||
 | 
					                    'headimgurl'   => $create['headimgurl'],
 | 
				
			||||||
 | 
					                    'unionid'      => $create['unionid'],
 | 
				
			||||||
 | 
					                    'business_id'  => $create['business_id'],
 | 
				
			||||||
 | 
					                    'phone_active' => $create['phone_active'],
 | 
				
			||||||
 | 
					                ];
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            session('frontend_auth', $account);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return $this->redirect('/login/bind');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 本地登录 模拟微信code
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return \think\response\Redirect
 | 
				
			||||||
 | 
					     * @throws \think\db\exception\DataNotFoundException
 | 
				
			||||||
 | 
					     * @throws \think\db\exception\DbException
 | 
				
			||||||
 | 
					     * @throws \think\db\exception\ModelNotFoundException
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function temp(): Redirect
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $openid = 'o3LH9jktzObHsQOK-Uu83D4tr_Tg';//拙言号
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $field   = ['id', 'openid', 'nickname', 'sex', 'headimgurl', 'unionid', 'business_id', 'phone_active', 'mobile'];
 | 
				
			||||||
 | 
					        $account = Account::field($field)->where('openid', $openid)->find();
 | 
				
			||||||
 | 
					        if (!$account) {
 | 
				
			||||||
 | 
					            $account = Account::findById(1, $field);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        session('frontend_auth', $account->toArray());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->redirect('/coupon/game');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 绑定手机
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return \think\response\Redirect|\think\response\View|\think\response\Json
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function bind()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if ($this->auth && $this->auth['phone_active'] > 0) {
 | 
				
			||||||
 | 
					            if ($this->auth['business_id']) {
 | 
				
			||||||
 | 
					                // 是商户负责人时 再次检验身份 避免用户身份变更但缓存未更新
 | 
				
			||||||
 | 
					//                $businessId = Account::where('id', $this->authId)->value('business_id');
 | 
				
			||||||
 | 
					//                if ($businessId > 0) {
 | 
				
			||||||
 | 
					//                    if ($businessId != $this->authId) {
 | 
				
			||||||
 | 
					//                        $this->auth['business_id'] = $businessId;
 | 
				
			||||||
 | 
					//                        session('frontend_auth', $this->auth);
 | 
				
			||||||
 | 
					//                    }
 | 
				
			||||||
 | 
					//                }
 | 
				
			||||||
 | 
					                return $this->redirect('/business/my');
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            return $this->redirect('/coupon/index');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($this->request->isPost()) {
 | 
				
			||||||
 | 
					            $phone = input('phone/s', '');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (!checkMobile($phone)) {
 | 
				
			||||||
 | 
					                return $this->json(4000, '请填写正确的手机号');
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $this->auth['mobile']       = $phone;
 | 
				
			||||||
 | 
					            $this->auth['phone_active'] = 1;
 | 
				
			||||||
 | 
					            session('frontend_auth', $this->auth);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            Account::where('id', $this->authId)->save(['phone_active' => 1, 'mobile' => $phone]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $url = $this->auth['business_id'] ? '/business/my' : '/coupon/index';
 | 
				
			||||||
 | 
					            return $this->json(0, 'success', ['url' => $url]);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->view();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,158 @@
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace app\controller;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use app\model\File;
 | 
				
			||||||
 | 
					use app\validate\Upload as VUpload;
 | 
				
			||||||
 | 
					use think\facade\Config;
 | 
				
			||||||
 | 
					use think\facade\Filesystem;
 | 
				
			||||||
 | 
					use think\facade\Lang;
 | 
				
			||||||
 | 
					use think\response\Json;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * 文件上传
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Class Upload
 | 
				
			||||||
 | 
					 * @package app\controller\api\file
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					class Upload extends Base
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    protected $noNeedLogin = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // 图片上传是否进行压缩[max-width:1920px]
 | 
				
			||||||
 | 
					    private bool $isCompress = false;
 | 
				
			||||||
 | 
					    private $validate = null;
 | 
				
			||||||
 | 
					    // 文件上传对外默认保存目录(相对路径)
 | 
				
			||||||
 | 
					    private string $uploadPath = '';
 | 
				
			||||||
 | 
					    private $videoUploadPath;
 | 
				
			||||||
 | 
					    // 文件上传对外默认保存目录是否有写权限
 | 
				
			||||||
 | 
					    private bool $uploadPathIsWritable = false;
 | 
				
			||||||
 | 
					    private $videoUploadPathIsWritable = 0;
 | 
				
			||||||
 | 
					    protected bool $saveToOos = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function initialize()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        parent::initialize();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//        $system = System::getSystem();
 | 
				
			||||||
 | 
					//        if (!empty($system)) {
 | 
				
			||||||
 | 
					//            $this->isCompress = $system['compress'] ?? true;
 | 
				
			||||||
 | 
					//        }
 | 
				
			||||||
 | 
					        $this->validate        = new VUpload();
 | 
				
			||||||
 | 
					        $this->uploadPath      = Config::get('filesystem.disks.local.url');
 | 
				
			||||||
 | 
					        $this->videoUploadPath = Config::get('filesystem.disks.video.url');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!is_writable(app()->getRootPath().'public'.$this->uploadPath)) {
 | 
				
			||||||
 | 
					            mkdir(app()->getRootPath().'public'.$this->uploadPath, 0777, true);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        $this->uploadPathIsWritable = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!is_writable(app()->getRootPath().'public'.$this->videoUploadPath)) {
 | 
				
			||||||
 | 
					            mkdir(app()->getRootPath().'public'.$this->videoUploadPath, 0777, true);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->videoUploadPathIsWritable = 1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 通用文件上传
 | 
				
			||||||
 | 
					     * @return Json
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function file()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $file = request()->file('file');
 | 
				
			||||||
 | 
					        if (empty($file)) {
 | 
				
			||||||
 | 
					            return $this->json(4001, '请上传的文件');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($this->validate->checkFile($file)) {
 | 
				
			||||||
 | 
					            try {
 | 
				
			||||||
 | 
					                if (!$this->uploadPathIsWritable) {
 | 
				
			||||||
 | 
					                    throw new \Exception('上传文件夹需要写入权限');
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                $src            = Filesystem::putFile('files/'.date('Ym'), $file, 'uniqid');
 | 
				
			||||||
 | 
					                $src            = $this->uploadPath.'/'.$src;
 | 
				
			||||||
 | 
					                $return['src']  = $src;
 | 
				
			||||||
 | 
					                $return['name'] = $file->getOriginalName();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                //加入上传文件表
 | 
				
			||||||
 | 
					                File::add($file, $src, $file->md5());
 | 
				
			||||||
 | 
					            } catch (\Exception $e) {
 | 
				
			||||||
 | 
					                return $this->json(4003, $e->getMessage());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return $this->json(0, 'success', $return);
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $errorMsg = Lang::get($this->validate->getError());
 | 
				
			||||||
 | 
					            return $this->json(4002, $errorMsg);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 通用图片上传
 | 
				
			||||||
 | 
					     * @return Json
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function image()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $image = request()->file('image');
 | 
				
			||||||
 | 
					        if (empty($image)) {
 | 
				
			||||||
 | 
					            return $this->json(4001, '请上传图片文件');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!in_array($image->getMime(), ['image/png', 'image/jpeg', 'image/bmp'])) {
 | 
				
			||||||
 | 
					            return $this->json(4001, '请上传png|jpeg|jpg|bmp格式图片');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($image->getSize() > 1.5 * 1024 * 1024) {
 | 
				
			||||||
 | 
					            return $this->json(4001, '图片超出尺寸要求');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            if (!$this->uploadPathIsWritable) {
 | 
				
			||||||
 | 
					                throw new \Exception('上传文件夹需要写入权限');
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            $src                = Filesystem::putFile('images/'.date('Ym'), $image, 'uniqid');
 | 
				
			||||||
 | 
					            $src                = $this->uploadPath.'/'.$src;
 | 
				
			||||||
 | 
					            $return['src']      = $src;
 | 
				
			||||||
 | 
					        } catch (\Exception $e) {
 | 
				
			||||||
 | 
					            return $this->json(4003, $e->getMessage());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->json(0, 'success', $return);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 通用视频上传
 | 
				
			||||||
 | 
					     * @return Json
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function video()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            $file = request()->file('video');
 | 
				
			||||||
 | 
					            $md5  = $file->md5();//文件md5
 | 
				
			||||||
 | 
					            if ($this->validate->checkVideo($file)) {
 | 
				
			||||||
 | 
					                if (!$this->videoUploadPathIsWritable) {
 | 
				
			||||||
 | 
					                    throw new \Exception('上传文件夹需要写入权限');
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                $src                = Filesystem::putFile('videos/'.date('Ym'), $file, 'uniqid');
 | 
				
			||||||
 | 
					                $src                = $this->uploadPath.'/'.$src;
 | 
				
			||||||
 | 
					                $return['src']      = $src;
 | 
				
			||||||
 | 
					                $return['full_src'] = resourceJoin($src);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                //加入上传文件表
 | 
				
			||||||
 | 
					                File::add($file, $src, $md5, 'video');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                return $this->json(0, 'success', $return);
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                $errorMsg = Lang::get($this->validate->getError());
 | 
				
			||||||
 | 
					                return $this->json(4002, $errorMsg);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        } catch (\Exception $e) {
 | 
				
			||||||
 | 
					            return $this->json(4000, $e->getMessage());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,30 @@
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace app\controller\api;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use app\controller\BaseController;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * API控制器基础类
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					class Base extends BaseController
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    // 布尔值数字关系
 | 
				
			||||||
 | 
					    public const BOOL_FALSE = 0;
 | 
				
			||||||
 | 
					    public const BOOL_TRUE  = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    protected function initialize()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        parent::initialize();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->middleware = [
 | 
				
			||||||
 | 
					            'jwt',
 | 
				
			||||||
 | 
					            'apiLogin' => ['except' => $this->noNeedLogin]
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function __call($method, $args)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return $this->json(4004, 'error request!');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,244 @@
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace app\controller\api\v1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use app\controller\api\Base;
 | 
				
			||||||
 | 
					use app\model\Account;
 | 
				
			||||||
 | 
					use app\model\CheckLog;
 | 
				
			||||||
 | 
					use app\model\OvertimeLog;
 | 
				
			||||||
 | 
					use app\model\Position;
 | 
				
			||||||
 | 
					use app\model\Worksite;
 | 
				
			||||||
 | 
					use app\repository\CommonRepository;
 | 
				
			||||||
 | 
					use app\repository\OperationRepository;
 | 
				
			||||||
 | 
					use app\validate\CommonValidate;
 | 
				
			||||||
 | 
					use think\Collection;
 | 
				
			||||||
 | 
					use think\db\exception\DataNotFoundException;
 | 
				
			||||||
 | 
					use think\db\exception\DbException;
 | 
				
			||||||
 | 
					use think\db\exception\ModelNotFoundException;
 | 
				
			||||||
 | 
					use think\response\Json;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Common extends Base
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    protected $noNeedLogin = [
 | 
				
			||||||
 | 
					        'slidePositions',
 | 
				
			||||||
 | 
					        'slides',
 | 
				
			||||||
 | 
					        'getCurrentWorksite',
 | 
				
			||||||
 | 
					        'worksiteList',
 | 
				
			||||||
 | 
					        'positionList',
 | 
				
			||||||
 | 
					        'notice',
 | 
				
			||||||
 | 
					    ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 发送短信验证码
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @OA\Post(
 | 
				
			||||||
 | 
					     *     path="/common/send-code",
 | 
				
			||||||
 | 
					     *     tags={"common"},
 | 
				
			||||||
 | 
					     *     operationId="sendCode",
 | 
				
			||||||
 | 
					     * )
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function sendCode(): Json
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $input    = input('post.');
 | 
				
			||||||
 | 
					        $validate = new CommonValidate();
 | 
				
			||||||
 | 
					        if (!$validate->scene('send_sms')->check($input)) {
 | 
				
			||||||
 | 
					            return $this->json(4001, '参数错误');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (!in_array($input['type'], ['register', 'login', 'binding'])) {
 | 
				
			||||||
 | 
					            return $this->json(4002, '参数错误');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//        CommonRepository::getInstance()->sendSms($input['phone'], $input['type']);
 | 
				
			||||||
 | 
					        return $this->json();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 查看轮播图可视位置配置信息
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function slidePositions(): Json
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $repo = OperationRepository::getInstance();
 | 
				
			||||||
 | 
					        $list = $repo->slidePositions();
 | 
				
			||||||
 | 
					        return $this->json(0, 'success', $list);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 轮播图
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function slides(): Json
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $size     = $this->request->param('size/d', 0);
 | 
				
			||||||
 | 
					        $position = trim($this->request->param('position/s', ''));
 | 
				
			||||||
 | 
					        if (empty($position)) {
 | 
				
			||||||
 | 
					            return $this->json();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            $repo = OperationRepository::getInstance();
 | 
				
			||||||
 | 
					            $list = $repo->slideListByPosition($position, $size);
 | 
				
			||||||
 | 
					            $domain = $this->request->domain();
 | 
				
			||||||
 | 
					            $list->each(function ($item) use ($domain) {
 | 
				
			||||||
 | 
					                $item->src = resourceJoin($item->src, $domain);
 | 
				
			||||||
 | 
					                unset($item->created_at);
 | 
				
			||||||
 | 
					                unset($item->sort);
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					        } catch (\Exception $e) {
 | 
				
			||||||
 | 
					            $list = new Collection();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->json(0, 'success', $list);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // 根据经纬度获取所在工地 500米
 | 
				
			||||||
 | 
					    public function getCurrentWorksite(): Json
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $lng = input('lng/s');
 | 
				
			||||||
 | 
					        $lat = input('lat/s');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (empty($lng) || empty($lat)) {
 | 
				
			||||||
 | 
					            return $this->json(4002, "参数错误");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->json(0, 'success', Worksite::getNearest($lng, $lat, 200));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // 工地列表 todo 如果有相关用户 则获取该用户相关的工地列表 如工人 则只获取其参与过的工地列表 需要添加一个字段来确认是否根据用户过滤
 | 
				
			||||||
 | 
					    public function worksiteList(): Json
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $page       = input('page/d', 1);
 | 
				
			||||||
 | 
					        $size       = input('size/d', 500);
 | 
				
			||||||
 | 
					        $keyword    = input('keyword/s');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//        $accountId = $this->request->user['user_id'] ?? 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $where = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!empty($keyword)) {
 | 
				
			||||||
 | 
					            $where[] = ['name|address', 'like', '%'.$keyword.'%'];
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $where[] = ['status', '=', Worksite::COMMON_ON];
 | 
				
			||||||
 | 
					        $query   = Worksite::where($where);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $total = $query->count();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $res = [
 | 
				
			||||||
 | 
					            'total'   => $total,
 | 
				
			||||||
 | 
					            'current' => $page ?: 1,
 | 
				
			||||||
 | 
					            'size'    => $size ?: 500,
 | 
				
			||||||
 | 
					            'list'    => new Collection(),
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($total > 0) {
 | 
				
			||||||
 | 
					            $res['list'] = $query->page($page, $size)
 | 
				
			||||||
 | 
					                ->field('id,name')
 | 
				
			||||||
 | 
					                ->order('sort', 'desc')
 | 
				
			||||||
 | 
					                ->order('id', 'desc')
 | 
				
			||||||
 | 
					                ->select();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->json(0, 'success', $res);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // 技术岗位列表
 | 
				
			||||||
 | 
					    public function positionList(): Json
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $page       = input('page/d', 1);
 | 
				
			||||||
 | 
					        $size       = input('size/d', 500);
 | 
				
			||||||
 | 
					        $keyword    = input('keyword/s');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $where = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!empty($keyword)) {
 | 
				
			||||||
 | 
					            $where[] = ['name', 'like', '%'.$keyword.'%'];
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $query   = Position::where($where);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $total = $query->count();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $res = [
 | 
				
			||||||
 | 
					            'total'   => $total,
 | 
				
			||||||
 | 
					            'current' => $page ?: 1,
 | 
				
			||||||
 | 
					            'size'    => $size ?: 500,
 | 
				
			||||||
 | 
					            'list'    => new Collection(),
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($total > 0) {
 | 
				
			||||||
 | 
					            $res['list'] = $query->page($page, $size)
 | 
				
			||||||
 | 
					                ->field('id,name')
 | 
				
			||||||
 | 
					                ->order('sort', 'desc')
 | 
				
			||||||
 | 
					                ->order('id', 'desc')
 | 
				
			||||||
 | 
					                ->select();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->json(0, 'success', $res);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 加班申请详情
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return \think\response\Json
 | 
				
			||||||
 | 
					     * @throws \think\db\exception\DataNotFoundException
 | 
				
			||||||
 | 
					     * @throws \think\db\exception\DbException
 | 
				
			||||||
 | 
					     * @throws \think\db\exception\ModelNotFoundException
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function overtimeInfo(): Json
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $accountId = $this->request->user['user_id'] ?? 0;
 | 
				
			||||||
 | 
					        $id = input('id/d');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!$account = Account::where('id', $accountId)->field('id,role')->find()) {
 | 
				
			||||||
 | 
					            return $this->json(6001, '请先登录'.$accountId, $account);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!$item = OvertimeLog::find($id)) {
 | 
				
			||||||
 | 
					            return $this->json(4004, '加班记录不存在');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($item['account_id'] != $accountId && $account['role'] != Account::ROLE_MANAGER) {
 | 
				
			||||||
 | 
					            return $this->json(4003, '无权查看');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->json(0,'success', $item);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 获取通知消息 在打卡页面每次加载都需要请求此接口,查看是否需要展示信息
 | 
				
			||||||
 | 
					     * 如果有登录token就查询用户相关小题
 | 
				
			||||||
 | 
					     * 如果没有登录token则返回空
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return \think\response\Json
 | 
				
			||||||
 | 
					     * @throws \think\db\exception\DataNotFoundException
 | 
				
			||||||
 | 
					     * @throws \think\db\exception\DbException
 | 
				
			||||||
 | 
					     * @throws \think\db\exception\ModelNotFoundException
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function notice(): Json
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $accountId = $this->request->user['user_id'] ?? 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($accountId == 0) {
 | 
				
			||||||
 | 
					            return $this->json(0, 'success', ['notice' => 0, 'msg' => '', 'id' => 0]);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!$account = Account::find($accountId)) {
 | 
				
			||||||
 | 
					            return $this->json(0, 'success', ['notice' => 0, 'msg' => '', 'id' => 0]);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($account['role'] != Account::ROLE_NORMAL) {
 | 
				
			||||||
 | 
					            return $this->json(0, 'success', ['notice' => 0, 'msg' => '', 'id' => 0]);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $checkLog = CheckLog::where('account_id', $accountId)->where('is_register', Account::COMMON_ON)->order('id', 'desc')->find();
 | 
				
			||||||
 | 
					        if (empty($checkLog)) {
 | 
				
			||||||
 | 
					            return $this->json(0, 'success', ['notice' => 0, 'msg' => '', 'id' => 0]);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($checkLog['status'] != -1) {
 | 
				
			||||||
 | 
					            return $this->json(0, 'success', ['notice' => 0, 'msg' => '', 'id' => 0]);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->json(0, 'success', ['notice' => 1, 'msg' => $checkLog['refund_reason'], 'id' => $checkLog['id']]);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,394 @@
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace app\controller\api\v1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use app\controller\api\Base;
 | 
				
			||||||
 | 
					use app\model\Account;
 | 
				
			||||||
 | 
					use app\model\GoodsArea;
 | 
				
			||||||
 | 
					use app\model\GoodsCategory;
 | 
				
			||||||
 | 
					use think\Collection;
 | 
				
			||||||
 | 
					use think\facade\Log;
 | 
				
			||||||
 | 
					use think\response\Json;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Goods extends Base
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    protected $noNeedLogin = [
 | 
				
			||||||
 | 
					        'list', 'detail', 'category', 'area'
 | 
				
			||||||
 | 
					    ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // 物品列表
 | 
				
			||||||
 | 
					    public function list(): Json
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $page       = input('page/d', 1);
 | 
				
			||||||
 | 
					        $size       = input('size/d', 20);
 | 
				
			||||||
 | 
					        $keyword    = input('keyword/s');
 | 
				
			||||||
 | 
					        $categoryId = input('category_id/d', 0);
 | 
				
			||||||
 | 
					        $areaId     = input('area_id/d', 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $where = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!empty($keyword)) {
 | 
				
			||||||
 | 
					            $where[] = ['a.nickname|g.title|gc.title|g.phone|ga.title', 'like', '%'.$keyword.'%'];
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($categoryId > 0) {
 | 
				
			||||||
 | 
					            $where[] = ['g.category_id', '=', $categoryId];
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($areaId > 0) {
 | 
				
			||||||
 | 
					            $where[] = ['g.area_id', '=', $areaId];
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $where[] = ['g.status', '=', 0];//进行中
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $query = \app\model\Goods::alias('g')
 | 
				
			||||||
 | 
					            ->leftJoin('goods_category gc', 'gc.id = g.category_id')
 | 
				
			||||||
 | 
					            ->leftJoin('account a', 'a.id = g.account_id')
 | 
				
			||||||
 | 
					            ->leftJoin('goods_area ga', 'ga.id = g.area_id')
 | 
				
			||||||
 | 
					            ->field('g.id,g.cover,g.title,g.images,price,original_price')
 | 
				
			||||||
 | 
					            ->where($where);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $total = $query->count();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $res = [
 | 
				
			||||||
 | 
					            'total'   => $total,
 | 
				
			||||||
 | 
					            'current' => $page ?: 1,
 | 
				
			||||||
 | 
					            'size'    => $size ?: 20,
 | 
				
			||||||
 | 
					            'list'    => new Collection(),
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($total > 0) {
 | 
				
			||||||
 | 
					            $res['list'] = $query->page($page, $size)->order('g.sort', 'desc')->order('g.id', 'desc')->select();
 | 
				
			||||||
 | 
					            $domain      = request()->domain(true);
 | 
				
			||||||
 | 
					            $res['list']->each(function ($item) use ($domain) {
 | 
				
			||||||
 | 
					                $item->cover = resourceJoin((string) $item->cover, $domain);
 | 
				
			||||||
 | 
					                $images      = explode(',', $item->images);
 | 
				
			||||||
 | 
					                foreach ($images as $k => $img) {
 | 
				
			||||||
 | 
					                    if (!empty($img)) {
 | 
				
			||||||
 | 
					                        $images[$k] = resourceJoin($img, $domain);
 | 
				
			||||||
 | 
					                    } else {
 | 
				
			||||||
 | 
					                        unset($images[$k]);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                $item->images = $images;
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->json(0, 'success', $res);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // 物品详情
 | 
				
			||||||
 | 
					    public function detail(): Json
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $id = input('id/d', 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $field = 'g.id,g.title,g.cover,g.images,g.content,g.price,g.original_price,g.phone,ga.title as area_name,gc.title as category_name';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $item = \app\model\Goods::alias('g')
 | 
				
			||||||
 | 
					            ->leftJoin('goods_area ga','ga.id = g.area_id')
 | 
				
			||||||
 | 
					            ->leftJoin('goods_category gc','gc.id = g.category_id')
 | 
				
			||||||
 | 
					            ->where('g.status', 0)
 | 
				
			||||||
 | 
					            ->where('g.id', $id)
 | 
				
			||||||
 | 
					            ->field($field)
 | 
				
			||||||
 | 
					            ->find();
 | 
				
			||||||
 | 
					        if (!$item) {
 | 
				
			||||||
 | 
					            return $this->json(4004, '物品不存在或已售出');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $domain      = request()->domain(true);
 | 
				
			||||||
 | 
					        $item->cover = resourceJoin((string) $item->cover, $domain);
 | 
				
			||||||
 | 
					        $images      = explode(',', $item->images);
 | 
				
			||||||
 | 
					        foreach ($images as &$img) {
 | 
				
			||||||
 | 
					            $img = resourceJoin($img, $domain);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        $item->images = $images;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->json(0, 'success', $item);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 物品添加
 | 
				
			||||||
 | 
					     * @return \think\response\Json
 | 
				
			||||||
 | 
					     * @throws \think\db\exception\DataNotFoundException
 | 
				
			||||||
 | 
					     * @throws \think\db\exception\DbException
 | 
				
			||||||
 | 
					     * @throws \think\db\exception\ModelNotFoundException
 | 
				
			||||||
 | 
					     * @throws \Exception
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function add(): Json
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (!$this->request->isPost()) {
 | 
				
			||||||
 | 
					            return $this->json(4000, '无效请求');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $accountId = $this->request->user['user_id'] ?? 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!$account = Account::field('id,nickname,status')->find((int) $accountId)) {
 | 
				
			||||||
 | 
					            return $this->json(6001, '请先登录');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($account['status'] != Account::STATUS_NORMAL) {
 | 
				
			||||||
 | 
					            return $this->json(4003, '用户状态异常');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $input = input('post.');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $rules = [
 | 
				
			||||||
 | 
					            'title|标题'         => 'require|max:100|min:4',
 | 
				
			||||||
 | 
					            'cover|封面图'        => 'require',
 | 
				
			||||||
 | 
					            'category_id|所属分类' => 'require',
 | 
				
			||||||
 | 
					            'area_id|所属小区'     => 'require',
 | 
				
			||||||
 | 
					            'price|价格'         => 'require|number',
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $validate = $this->validateByApi($input, $rules);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($validate !== true) {
 | 
				
			||||||
 | 
					            return $validate;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!isset($input['images']) && !isset($input['content'])) {
 | 
				
			||||||
 | 
					            return $this->json(4005, '详情组图和内容至少填一个');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            $originalPrice = 0;
 | 
				
			||||||
 | 
					            if (isset($input['original_price'])) {
 | 
				
			||||||
 | 
					                $originalPrice = $input['original_price'] ?: $input['price'];
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            \app\model\Goods::create([
 | 
				
			||||||
 | 
					                'title'          => $input['title'],
 | 
				
			||||||
 | 
					                'cover'          => $input['cover'],
 | 
				
			||||||
 | 
					                'category_id'    => $input['category_id'],
 | 
				
			||||||
 | 
					                'content'        => $input['content'] ?? '',
 | 
				
			||||||
 | 
					                'phone'          => $input['phone'] ?? '',
 | 
				
			||||||
 | 
					                'price'          => $input['price'] ?? 0,
 | 
				
			||||||
 | 
					                'original_price' => $originalPrice,
 | 
				
			||||||
 | 
					                'account_id'     => $accountId,
 | 
				
			||||||
 | 
					                'area_id'        => $input['area_id'] ?? 0,
 | 
				
			||||||
 | 
					                'images'         => $input['images'] ?? '',
 | 
				
			||||||
 | 
					                'created_at'     => date('Y-m-d H:i:s'),
 | 
				
			||||||
 | 
					            ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return $this->json();
 | 
				
			||||||
 | 
					        } catch (\Exception $e) {
 | 
				
			||||||
 | 
					            Log::error('闲置物品添加失败:line '.$e->getLine().' '.$e->getMessage());
 | 
				
			||||||
 | 
					            return $this->json(5000, '物品添加失败');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 物品编辑
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return \think\response\Json
 | 
				
			||||||
 | 
					     * @throws \think\db\exception\DataNotFoundException
 | 
				
			||||||
 | 
					     * @throws \think\db\exception\DbException
 | 
				
			||||||
 | 
					     * @throws \think\db\exception\ModelNotFoundException
 | 
				
			||||||
 | 
					     * @throws \Exception
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function edit(): Json
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (!$this->request->isPost()) {
 | 
				
			||||||
 | 
					            return $this->json(4000, '无效请求');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $accountId = $this->request->user['user_id'] ?? 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!$account = Account::field('id,nickname,status')->find((int) $accountId)) {
 | 
				
			||||||
 | 
					            return $this->json(6001, '请先登录');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($account['status'] != Account::STATUS_NORMAL) {
 | 
				
			||||||
 | 
					            return $this->json(4003, '用户状态异常');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $input = input('post.');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $rules = [
 | 
				
			||||||
 | 
					            'id|ID'            => 'require|number',
 | 
				
			||||||
 | 
					            'title|标题'         => 'require|max:100|min:4',
 | 
				
			||||||
 | 
					            'cover|封面图'        => 'require',
 | 
				
			||||||
 | 
					            'category_id|所属分类' => 'require',
 | 
				
			||||||
 | 
					            'area_id|所属小区'     => 'require',
 | 
				
			||||||
 | 
					            'price|价格'         => 'require|number',
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $validate = $this->validateByApi($input, $rules);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($validate !== true) {
 | 
				
			||||||
 | 
					            return $validate;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            if (!$item = \app\model\Goods::find((int) $input['id'])) {
 | 
				
			||||||
 | 
					                return $this->json(4004, '记录不存在');
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if ($item['account_id'] != $accountId) {
 | 
				
			||||||
 | 
					                return $this->json(4003, '不是您发布的物品');
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (!isset($input['images']) && !isset($input['content'])) {
 | 
				
			||||||
 | 
					                return $this->json(4005, '详情组图和内容至少填一个');
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $originalPrice = 0;
 | 
				
			||||||
 | 
					            if (isset($input['original_price'])) {
 | 
				
			||||||
 | 
					                $originalPrice = $input['original_price'] ?: $input['price'];
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $item->save([
 | 
				
			||||||
 | 
					                'title'          => $input['title'],
 | 
				
			||||||
 | 
					                'cover'          => $input['cover'],
 | 
				
			||||||
 | 
					                'category_id'    => $input['category_id'],
 | 
				
			||||||
 | 
					                'content'        => $input['content'] ?? '',
 | 
				
			||||||
 | 
					                'phone'          => $input['phone'] ?? '',
 | 
				
			||||||
 | 
					                'price'          => $input['price'] ?? 0,
 | 
				
			||||||
 | 
					                'original_price' => $originalPrice,
 | 
				
			||||||
 | 
					                'area_id'        => $input['area_id'] ?? 0,
 | 
				
			||||||
 | 
					                'images'         => $input['images'] ?? '',
 | 
				
			||||||
 | 
					            ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return $this->json();
 | 
				
			||||||
 | 
					        } catch (\Exception $e) {
 | 
				
			||||||
 | 
					            Log::error('闲置物品编辑失败:line '.$e->getLine().' '.$e->getMessage());
 | 
				
			||||||
 | 
					            return $this->json(5000, '物品编辑失败');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 删除
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return \think\response\Json
 | 
				
			||||||
 | 
					     * @throws \think\db\exception\DataNotFoundException
 | 
				
			||||||
 | 
					     * @throws \think\db\exception\DbException
 | 
				
			||||||
 | 
					     * @throws \think\db\exception\ModelNotFoundException
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function del(): Json
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (!$this->request->isPost()) {
 | 
				
			||||||
 | 
					            return $this->json(4000, '无效请求');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $accountId = $this->request->user['user_id'] ?? 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!$account = Account::field('id,nickname,status')->find((int) $accountId)) {
 | 
				
			||||||
 | 
					            return $this->json(6001, '请先登录');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($account['status'] != Account::STATUS_NORMAL) {
 | 
				
			||||||
 | 
					            return $this->json(4003, '用户状态异常');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $ids = input('id');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            $ids = explode(',', $ids);
 | 
				
			||||||
 | 
					            if (!empty($ids)) {
 | 
				
			||||||
 | 
					                \app\model\Goods::whereIn('id', $ids)->where('account_id', $accountId)->delete();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return $this->json();
 | 
				
			||||||
 | 
					        } catch (\Exception $e) {
 | 
				
			||||||
 | 
					            Log::error('闲置物品删除失败:line '.$e->getLine().' '.$e->getMessage());
 | 
				
			||||||
 | 
					            return $this->json(5000, '闲置物品删除失败');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // 小区
 | 
				
			||||||
 | 
					    public function area(): Json
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $page    = input('page/d', 1);
 | 
				
			||||||
 | 
					        $size    = input('size/d', 20);
 | 
				
			||||||
 | 
					        $keyword = input('keyword/s');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $where = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!empty($keyword)) {
 | 
				
			||||||
 | 
					            $where[] = ['title', 'like', '%'.$keyword.'%'];
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $query = GoodsArea::field('id,title')->where($where);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $total = $query->count();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $res = [
 | 
				
			||||||
 | 
					            'total'   => $total,
 | 
				
			||||||
 | 
					            'current' => $page ?: 1,
 | 
				
			||||||
 | 
					            'size'    => $size ?: 20,
 | 
				
			||||||
 | 
					            'list'    => new Collection(),
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($total > 0) {
 | 
				
			||||||
 | 
					            $res['list'] = $query->page($page, $size)->order('sort', 'desc')->order('id', 'desc')->select();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->json(0, 'success', $res);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // 分类
 | 
				
			||||||
 | 
					    public function category(): Json
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $keyword = input('keyword/s');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $where = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!empty($keyword)) {
 | 
				
			||||||
 | 
					            $where[] = ['title', 'like', '%'.$keyword.'%'];
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $res = GoodsCategory::field('id,title')->where($where)->order('sort', 'desc')->order('id', 'asc')->select();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->json(0, 'success', $res);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 设置状态 0=展示 1=不展示(已完成)
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return \think\response\Json
 | 
				
			||||||
 | 
					     * @throws \think\db\exception\DataNotFoundException
 | 
				
			||||||
 | 
					     * @throws \think\db\exception\DbException
 | 
				
			||||||
 | 
					     * @throws \think\db\exception\ModelNotFoundException
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function setStatus(): Json
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (!$this->request->isPost()) {
 | 
				
			||||||
 | 
					            return $this->json(4000, '无效请求');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $accountId = $this->request->user['user_id'] ?? 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!$account = Account::field('id,nickname,status')->find((int) $accountId)) {
 | 
				
			||||||
 | 
					            return $this->json(6001, '请先登录');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($account['status'] != Account::STATUS_NORMAL) {
 | 
				
			||||||
 | 
					            return $this->json(4003, '用户状态异常');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $id = input('id/d');
 | 
				
			||||||
 | 
					        $status = input('status/d', 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!in_array($status, [0, 1])) {
 | 
				
			||||||
 | 
					            return $this->json(4001, '参数错误');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            if (!$item = \app\model\Goods::findById($id, ['id', 'status', 'account_id'])) {
 | 
				
			||||||
 | 
					                return $this->json(4004, '物品不存在');
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if ($item['account_id'] != $accountId) {
 | 
				
			||||||
 | 
					                return $this->json(4003, '不是您发布的物品');
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $item->save([
 | 
				
			||||||
 | 
					                'status' => $status
 | 
				
			||||||
 | 
					            ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return $this->json();
 | 
				
			||||||
 | 
					        } catch (\Exception $e) {
 | 
				
			||||||
 | 
					            Log::error('闲置物品状态修改失败:line '.$e->getLine().' '.$e->getMessage());
 | 
				
			||||||
 | 
					            return $this->json(5000, '状态设置失败');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,178 @@
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace app\controller\api\v1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use app\controller\api\Base;
 | 
				
			||||||
 | 
					use app\exception\RepositoryException;
 | 
				
			||||||
 | 
					use app\repository\AccountRepository;
 | 
				
			||||||
 | 
					use app\service\ExtraConfig;
 | 
				
			||||||
 | 
					use app\service\order\Compute;
 | 
				
			||||||
 | 
					use Exception;
 | 
				
			||||||
 | 
					use think\facade\Config;
 | 
				
			||||||
 | 
					use think\facade\Config as CConfig;
 | 
				
			||||||
 | 
					use think\response\Json;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Index extends Base
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    protected $noNeedLogin = [
 | 
				
			||||||
 | 
					        'baseConfig',
 | 
				
			||||||
 | 
					        'statement',
 | 
				
			||||||
 | 
					        'agreement',
 | 
				
			||||||
 | 
					        'about',
 | 
				
			||||||
 | 
					        'notice',
 | 
				
			||||||
 | 
					        'safeNotice',
 | 
				
			||||||
 | 
					        'handbook',
 | 
				
			||||||
 | 
					        'computeDay',
 | 
				
			||||||
 | 
					        'computeMonth',
 | 
				
			||||||
 | 
					    ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function index(): Json
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return json(['code' => 0, 'msg' => 'I am index']);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 小程序个性装修配置
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function miniProgramSetting(): Json
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $conf = ExtraConfig::miniProgram();
 | 
				
			||||||
 | 
					        return $this->json(0, 'success', $conf);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 基础配置
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return Json
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function baseConfig(): Json
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            Config::load('extra/base', 'base');
 | 
				
			||||||
 | 
					            $baseConfig                     = config('base');
 | 
				
			||||||
 | 
					            $baseConfig['show_video']       = $baseConfig['show_video'] ?? 0;
 | 
				
			||||||
 | 
					            $baseConfig['hide_video_cover'] = $baseConfig['hide_video_cover'] ?? '';
 | 
				
			||||||
 | 
					            $res                            = [
 | 
				
			||||||
 | 
					                'video_upload_max' => 50,//视频最大上传50M
 | 
				
			||||||
 | 
					                'hide_video_cover' => resourceJoin($baseConfig['hide_video_cover']),//视频隐藏后 用来替换的图片
 | 
				
			||||||
 | 
					            ];
 | 
				
			||||||
 | 
					            return $this->json(0, 'success', $res);
 | 
				
			||||||
 | 
					        } catch (Exception $e) {
 | 
				
			||||||
 | 
					            return $this->json(5000, '获取基础配置失败');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 免责声明
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return Json
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function statement(): Json
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            CConfig::load('extra/statement', 'statement');
 | 
				
			||||||
 | 
					            $content = config('statement')['content'] ?? '';
 | 
				
			||||||
 | 
					            return $this->json(0, 'success', ['content' => replaceStoragePath($content)]);
 | 
				
			||||||
 | 
					        } catch (Exception $e) {
 | 
				
			||||||
 | 
					            return $this->json(5000, '获取免责声明失败');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 用户协议
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return Json
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function agreement(): Json
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            CConfig::load('extra/agreement', 'agreement');
 | 
				
			||||||
 | 
					            $content = config('agreement')['content'] ?? '';
 | 
				
			||||||
 | 
					            return $this->json(0, 'success', ['content' => replaceStoragePath($content)]);
 | 
				
			||||||
 | 
					        } catch (Exception $e) {
 | 
				
			||||||
 | 
					            return $this->json(5000, '获取用户协议失败');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 关于我们
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return Json
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function about(): Json
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            CConfig::load('extra/about', 'about');
 | 
				
			||||||
 | 
					            $res            = config('about') ?? [];
 | 
				
			||||||
 | 
					            $res['content'] = replaceStoragePath($res['content']);
 | 
				
			||||||
 | 
					            return $this->json(0, 'success', $res);
 | 
				
			||||||
 | 
					        } catch (Exception $e) {
 | 
				
			||||||
 | 
					            return $this->json(5000, '获取关于我们失败');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 安全公告
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return Json
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function safeNotice(): Json
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            CConfig::load('extra/safeNotice', 'safeNotice');
 | 
				
			||||||
 | 
					            $res            = config('safeNotice') ?? [];
 | 
				
			||||||
 | 
					            $res['content'] = replaceStoragePath($res['content'] ?? '');
 | 
				
			||||||
 | 
					            return $this->json(0, 'success', $res);
 | 
				
			||||||
 | 
					        } catch (Exception $e) {
 | 
				
			||||||
 | 
					            return $this->json(5000, '获取安全公告失败'.$e->getMessage());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 公告
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return Json
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function notice(): Json
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            CConfig::load('extra/notice', 'notice');
 | 
				
			||||||
 | 
					            $res            = config('notice') ?? [];
 | 
				
			||||||
 | 
					            $res['content'] = replaceStoragePath($res['content'] ?? '');
 | 
				
			||||||
 | 
					            return $this->json(0, 'success', $res);
 | 
				
			||||||
 | 
					        } catch (Exception $e) {
 | 
				
			||||||
 | 
					            return $this->json(5000, '获取公告失败'.$e->getMessage());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 员工手册
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return Json
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function handbook(): Json
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            CConfig::load('extra/handbook', 'handbook');
 | 
				
			||||||
 | 
					            $res            = config('handbook') ?? [];
 | 
				
			||||||
 | 
					            $res['content'] = replaceStoragePath($res['content'] ?? '');
 | 
				
			||||||
 | 
					            return $this->json(0, 'success', $res);
 | 
				
			||||||
 | 
					        } catch (Exception $e) {
 | 
				
			||||||
 | 
					            return $this->json(5000, '获取员工手册失败'.$e->getMessage());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // 定时任务 每月指定时间统计日工资 需要在月工资统计前执行
 | 
				
			||||||
 | 
					    public function computeDay(): Json
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        \app\service\Pay::statistic();
 | 
				
			||||||
 | 
					        return $this->json(0,'success', '统计日工资');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // 定时任务 每月指定时间统计月工资 需要在月工资统计前执行
 | 
				
			||||||
 | 
					    public function computeMonth(): Json
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        \app\service\Pay::generateMonthLog();
 | 
				
			||||||
 | 
					        return $this->json(0,'success', '统计月工资');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,637 @@
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace app\controller\api\v1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use app\controller\api\Base;
 | 
				
			||||||
 | 
					use app\model\Account;
 | 
				
			||||||
 | 
					use app\model\AccountWorksite;
 | 
				
			||||||
 | 
					use app\model\CheckLog;
 | 
				
			||||||
 | 
					use app\model\ClockLog;
 | 
				
			||||||
 | 
					use app\model\OvertimeLog;
 | 
				
			||||||
 | 
					use app\model\Position;
 | 
				
			||||||
 | 
					use app\model\Worksite;
 | 
				
			||||||
 | 
					use app\service\Math;
 | 
				
			||||||
 | 
					use Exception;
 | 
				
			||||||
 | 
					use Lcobucci\Clock\Clock;
 | 
				
			||||||
 | 
					use think\Collection;
 | 
				
			||||||
 | 
					use think\response\Json;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * 负责人相关
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Class Manager
 | 
				
			||||||
 | 
					 * @package app\controller\api\v1
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					class Manager extends Base
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    protected $noNeedLogin = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 查看审核详情
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return Json
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function checkDetail(): Json
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            $accountId = $this->request->user['user_id'] ?? 0;
 | 
				
			||||||
 | 
					            $id        = input('id/d');//待审核记录ID
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (!$account = Account::findById($accountId, ['id, role'])) {
 | 
				
			||||||
 | 
					                return $this->json(6001, '请先登录');
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if ($account['role'] <= Account::COMMON_ON) {
 | 
				
			||||||
 | 
					                // 工地负责人才能查看
 | 
				
			||||||
 | 
					                return $this->json(4003, '无查看权限');
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (!$item = CheckLog::findById($id)) {
 | 
				
			||||||
 | 
					                return $this->json(4004, '记录不存在');
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $item = arrayNullToString($item->toArray());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $fields = Account::needCheckFields();
 | 
				
			||||||
 | 
					            array_push($fields, 'id', 'role', 'work_at', 'worksite_id');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $user = Account::findById($item['account_id'], $fields)->toArray();
 | 
				
			||||||
 | 
					            $user = arrayNullToString($user);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $positionList          = Position::column('name', 'id');
 | 
				
			||||||
 | 
					            $item['position_name'] = $positionList[$item['position']] ?? '';
 | 
				
			||||||
 | 
					            $user['position_name'] = $positionList[$user['position']] ?? '';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // user角色为工人时,需要判断当前人是否是该工地的负责人
 | 
				
			||||||
 | 
					            if (!empty($user) && $user['role'] == Account::COMMON_ON) {
 | 
				
			||||||
 | 
					                $managerIds = AccountWorksite::where('worksite_id', $user['worksite_id'])->column('account_id');
 | 
				
			||||||
 | 
					                if (!in_array($accountId, $managerIds)) {
 | 
				
			||||||
 | 
					                    return $this->json(4003, '无查看权限2');
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $item['account'] = $user;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return $this->json(0, 'success', $item);
 | 
				
			||||||
 | 
					        } catch (Exception $e) {
 | 
				
			||||||
 | 
					            return $this->json(4000, '没有相关的用户记录'.$e->getMessage());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // 审核列表(员工资料提交的审核)
 | 
				
			||||||
 | 
					    public function checkList(): Json
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $page    = input('page/d', 1);
 | 
				
			||||||
 | 
					        $size    = input('size/d', 20);
 | 
				
			||||||
 | 
					        $keyword = input('keyword/s');
 | 
				
			||||||
 | 
					        $status  = input('status/d', 0);//状态 0=待审核 1=已审核(包含1通过 -1不通过)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $accountId = $this->request->user['user_id'] ?? 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!$account = Account::findById($accountId, ['id, role'])) {
 | 
				
			||||||
 | 
					            return $this->json(6001, '请先登录');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($account['role'] <= Account::COMMON_ON) {
 | 
				
			||||||
 | 
					            return $this->json(4003, '无查看权限');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $where = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!empty($keyword)) {
 | 
				
			||||||
 | 
					            $where[] = ['cl.real_name|cl.mobile', 'like', '%'.$keyword.'%'];
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($status == 0) {
 | 
				
			||||||
 | 
					            $where[] = ['cl.status', '=', 0];
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            $where[] = ['cl.status', 'in', [1, -1]];
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // 负责工地
 | 
				
			||||||
 | 
					        $worksiteIds = AccountWorksite::where('account_id', $accountId)->column('worksite_id');
 | 
				
			||||||
 | 
					        $where[]     = ['cl.worksite_id', 'in', $worksiteIds];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $query = CheckLog::alias('cl')
 | 
				
			||||||
 | 
					            ->leftJoin('account a', 'a.id = cl.account_id')
 | 
				
			||||||
 | 
					            ->leftJoin('position p', 'p.id = cl.position')
 | 
				
			||||||
 | 
					            ->field('cl.id,cl.real_name,cl.status,cl.created_at,p.name as position_name')
 | 
				
			||||||
 | 
					            ->where($where);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $total = $query->count();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $res = [
 | 
				
			||||||
 | 
					            'total'   => $total,
 | 
				
			||||||
 | 
					            'current' => $page ?: 1,
 | 
				
			||||||
 | 
					            'size'    => $size ?: 20,
 | 
				
			||||||
 | 
					            'list'    => new Collection(),
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($total > 0) {
 | 
				
			||||||
 | 
					            $res['list'] = $query->page($page, $size)->order('cl.id', 'desc')->select();
 | 
				
			||||||
 | 
					            $res['list']->each(function ($item) {
 | 
				
			||||||
 | 
					                $item->created_at = date('Y年m月d日 H:i:s', strtotime($item->created_at));
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					            $res['list'] = arrayNullToString($res['list']->toArray());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->json(0, 'success', $res);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 审核资料(工人信息注册或二次修改审核)
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return Json
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function checkInfo(): Json
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            $accountId = $this->request->user['user_id'] ?? 0;
 | 
				
			||||||
 | 
					            $type      = input('type/d', 1);//类型 1=通过 0=不通过
 | 
				
			||||||
 | 
					            $id        = input('id/d');//待审核记录ID
 | 
				
			||||||
 | 
					            $reason    = input('reason/s');//不通过原因
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (!in_array($type, [0, 1])) {
 | 
				
			||||||
 | 
					                return $this->json(4001, '审核参数错误');
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (!$account = Account::findById($accountId, ['id, role'])) {
 | 
				
			||||||
 | 
					                return $this->json(6001, '请先登录');
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if ($account['role'] <= Account::COMMON_ON) {
 | 
				
			||||||
 | 
					                // 工地负责人才能操作
 | 
				
			||||||
 | 
					                return $this->json(4003, '无此权限');
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (!$item = CheckLog::findById($id)) {
 | 
				
			||||||
 | 
					                return $this->json(4004, '记录不存在');
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if ($item['status'] != CheckLog::COMMON_OFF) {
 | 
				
			||||||
 | 
					                return $this->json(4002, '状态错误');
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $user = Account::getUser($item['account_id']);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // user角色为工人时,需要判断当前人是否是该工地的负责人
 | 
				
			||||||
 | 
					            if (!empty($user) && $user['role'] == Account::COMMON_ON) {
 | 
				
			||||||
 | 
					                $managerIds = AccountWorksite::where('worksite_id', $user['worksite_id'])->column('account_id');
 | 
				
			||||||
 | 
					                if (!in_array($accountId, $managerIds)) {
 | 
				
			||||||
 | 
					                    return $this->json(4003, '无此权限2');
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // 审核不通过
 | 
				
			||||||
 | 
					            if ($type == 0) {
 | 
				
			||||||
 | 
					                Account::where('id', $item['account_id'])->save(['checking' => Account::COMMON_OFF]);
 | 
				
			||||||
 | 
					                $item->save(['status' => -1, 'refund_reason' => $reason]);
 | 
				
			||||||
 | 
					                return $this->json();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $now = date('Y-m-d H:i:s');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $update = $item->toArray();
 | 
				
			||||||
 | 
					            if ($update['is_register'] == CheckLog::COMMON_ON) {
 | 
				
			||||||
 | 
					                $update['role']    = CheckLog::COMMON_ON;
 | 
				
			||||||
 | 
					                $update['work_at'] = $now;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            $update['checking'] = Account::COMMON_OFF;
 | 
				
			||||||
 | 
					            unset($update['id']);
 | 
				
			||||||
 | 
					            unset($update['account_id']);
 | 
				
			||||||
 | 
					            unset($update['is_register']);
 | 
				
			||||||
 | 
					            unset($update['status']);
 | 
				
			||||||
 | 
					            unset($update['created_at']);
 | 
				
			||||||
 | 
					            unset($update['check_at']);
 | 
				
			||||||
 | 
					            unset($update['refund_reason']);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            Account::where('id', $item['account_id'])->save($update);
 | 
				
			||||||
 | 
					            $item->save(['status' => 1, 'check_at' => $now]);
 | 
				
			||||||
 | 
					            return $this->json();
 | 
				
			||||||
 | 
					        } catch (Exception $e) {
 | 
				
			||||||
 | 
					            return $this->json(4000, '没有相关的用户记录'.$e->getMessage());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // 打卡记录
 | 
				
			||||||
 | 
					    public function clockList(): Json
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $page   = input('page/d', 1);
 | 
				
			||||||
 | 
					        $size   = input('size/d', 20);
 | 
				
			||||||
 | 
					        $status = input('status/d', 0);//状态 0=待审核 1=已审核(包含1通过 -1不通过)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $accountId = $this->request->user['user_id'] ?? 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!$account = Account::findById($accountId, ['id, role'])) {
 | 
				
			||||||
 | 
					            return $this->json(6001, '请先登录');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($account['role'] <= Account::COMMON_ON) {
 | 
				
			||||||
 | 
					            return $this->json(4003, '无权限');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $where = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($status == 0) {
 | 
				
			||||||
 | 
					            $where[] = ['cl.status', '=', 0];
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            $where[] = ['cl.status', 'in', [1, -1]];
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // 负责工地
 | 
				
			||||||
 | 
					        $worksiteIds = AccountWorksite::where('account_id', $accountId)->column('worksite_id');
 | 
				
			||||||
 | 
					        $where[]     = ['cl.worksite_id', 'in', $worksiteIds];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $query = \app\model\ClockLog::alias('cl')
 | 
				
			||||||
 | 
					            ->leftJoin('account a', 'a.id = cl.account_id')
 | 
				
			||||||
 | 
					            ->leftJoin('worksite w', 'w.id = cl.worksite_id')
 | 
				
			||||||
 | 
					            ->field('cl.*,w.name as worksite_name,a.real_name as worker_name')
 | 
				
			||||||
 | 
					            ->where($where);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $total = $query->count();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $res = [
 | 
				
			||||||
 | 
					            'total'   => $total,
 | 
				
			||||||
 | 
					            'current' => $page ?: 1,
 | 
				
			||||||
 | 
					            'size'    => $size ?: 20,
 | 
				
			||||||
 | 
					            'list'    => new Collection(),
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($total > 0) {
 | 
				
			||||||
 | 
					            $res['list'] = $query->page($page, $size)->order('cl.id', 'desc')->select();
 | 
				
			||||||
 | 
					            $res['list']->each(function ($item) {
 | 
				
			||||||
 | 
					                $item->type_text = $item->type == 'in' ? '上班' : '下班';
 | 
				
			||||||
 | 
					                switch ($item->status) {
 | 
				
			||||||
 | 
					                    case 0:
 | 
				
			||||||
 | 
					                        $item->status_text = '待确认';
 | 
				
			||||||
 | 
					                        break;
 | 
				
			||||||
 | 
					                    case 1:
 | 
				
			||||||
 | 
					                        $item->status_text = '已确认';
 | 
				
			||||||
 | 
					                        break;
 | 
				
			||||||
 | 
					                    case -1:
 | 
				
			||||||
 | 
					                        $item->status_text = '不通过';
 | 
				
			||||||
 | 
					                        break;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                unset($item->check_by);
 | 
				
			||||||
 | 
					                unset($item->check_at);
 | 
				
			||||||
 | 
					                unset($item->account_id);
 | 
				
			||||||
 | 
					                unset($item->create_time);
 | 
				
			||||||
 | 
					                unset($item->type);
 | 
				
			||||||
 | 
					                unset($item->worksite_id);
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					            $res['list'] = arrayNullToString($res['list']->toArray());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->json(0, 'success', $res);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 审核打卡 支持批量
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return Json
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function checkClock(): Json
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            $accountId = $this->request->user['user_id'] ?? 0;
 | 
				
			||||||
 | 
					            $type      = input('type/d', 1);//类型 1=通过 0=不通过
 | 
				
			||||||
 | 
					            $ids       = input('id/s');//待审核记录ID 多个用逗号分割
 | 
				
			||||||
 | 
					            $ids       = explode(',', $ids);
 | 
				
			||||||
 | 
					            $ids       = array_filter($ids);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (!in_array($type, [0, 1])) {
 | 
				
			||||||
 | 
					                return $this->json(4001, '审核参数错误');
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (!$account = Account::findById($accountId, ['id, role'])) {
 | 
				
			||||||
 | 
					                return $this->json(6001, '请先登录');
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if ($account['role'] <= Account::COMMON_ON) {
 | 
				
			||||||
 | 
					                // 工地负责人才能操作
 | 
				
			||||||
 | 
					                return $this->json(4003, '无此权限');
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $worksiteIds = AccountWorksite::where('account_id', $accountId)->column('worksite_id');
 | 
				
			||||||
 | 
					            if (ClockLog::whereIn('id', $ids)->whereNotIn('worksite_id', $worksiteIds)->count() > 0) {
 | 
				
			||||||
 | 
					                return $this->json(4003, '部分记录不在您权限操作的范围');
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            ClockLog::whereIn('id', $ids)->where('status', ClockLog::COMMON_OFF)->update([
 | 
				
			||||||
 | 
					                'status'   => $type == 1 ? 1 : -1,
 | 
				
			||||||
 | 
					                'check_at' => date('Y-m-d H:i:s'),
 | 
				
			||||||
 | 
					                'check_by' => $accountId
 | 
				
			||||||
 | 
					            ]);
 | 
				
			||||||
 | 
					            return $this->json();
 | 
				
			||||||
 | 
					        } catch (Exception $e) {
 | 
				
			||||||
 | 
					            return $this->json(5000, '审核失败'.$e->getMessage());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // 加班记录
 | 
				
			||||||
 | 
					    public function overtimeList(): Json
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $page   = input('page/d', 1);
 | 
				
			||||||
 | 
					        $size   = input('size/d', 20);
 | 
				
			||||||
 | 
					        $status = input('status/d', 0);//状态 0=待审核 1=已审核(包含1通过 -1不通过)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $accountId = $this->request->user['user_id'] ?? 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!$account = Account::findById($accountId, ['id, role'])) {
 | 
				
			||||||
 | 
					            return $this->json(6001, '请先登录');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($account['role'] <= Account::COMMON_ON) {
 | 
				
			||||||
 | 
					            return $this->json(4003, '无权限');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $where = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($status == 0) {
 | 
				
			||||||
 | 
					            $where[] = ['cl.status', '=', 0];
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            $where[] = ['cl.status', 'in', [1, -1]];
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // 负责工地
 | 
				
			||||||
 | 
					        $worksiteIds = AccountWorksite::where('account_id', $accountId)->column('worksite_id');
 | 
				
			||||||
 | 
					        $where[]     = ['cl.worksite_id', 'in', $worksiteIds];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $query = \app\model\OvertimeLog::alias('cl')
 | 
				
			||||||
 | 
					            ->leftJoin('account a', 'a.id = cl.account_id')
 | 
				
			||||||
 | 
					            ->leftJoin('worksite w', 'w.id = cl.worksite_id')
 | 
				
			||||||
 | 
					            ->field('cl.*,w.name as worksite_name,a.real_name as worker_name')
 | 
				
			||||||
 | 
					            ->where($where);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $total = $query->count();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $res = [
 | 
				
			||||||
 | 
					            'total'   => $total,
 | 
				
			||||||
 | 
					            'current' => $page ?: 1,
 | 
				
			||||||
 | 
					            'size'    => $size ?: 20,
 | 
				
			||||||
 | 
					            'list'    => new Collection(),
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($total > 0) {
 | 
				
			||||||
 | 
					            $res['list'] = $query->page($page, $size)->order('cl.id', 'desc')->select();
 | 
				
			||||||
 | 
					            $res['list']->each(function ($item) {
 | 
				
			||||||
 | 
					                switch ($item->status) {
 | 
				
			||||||
 | 
					                    case 0:
 | 
				
			||||||
 | 
					                        $item->status_text = '待确认';
 | 
				
			||||||
 | 
					                        break;
 | 
				
			||||||
 | 
					                    case 1:
 | 
				
			||||||
 | 
					                        $item->status_text = '已确认';
 | 
				
			||||||
 | 
					                        break;
 | 
				
			||||||
 | 
					                    case -1:
 | 
				
			||||||
 | 
					                        $item->status_text = '不通过';
 | 
				
			||||||
 | 
					                        break;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                $item->create_time = date('Y年m月d日 H:i:s', $item->create_time);
 | 
				
			||||||
 | 
					                $item->worktime    = date('Y年m月d日', strtotime($item->day));
 | 
				
			||||||
 | 
					                unset($item->check_by);
 | 
				
			||||||
 | 
					                unset($item->check_at);
 | 
				
			||||||
 | 
					                unset($item->account_id);
 | 
				
			||||||
 | 
					                unset($item->created_at);
 | 
				
			||||||
 | 
					                unset($item->type);
 | 
				
			||||||
 | 
					                unset($item->day);
 | 
				
			||||||
 | 
					                unset($item->day_text);
 | 
				
			||||||
 | 
					                unset($item->worksite_id);
 | 
				
			||||||
 | 
					                unset($item->is_statistic
 | 
				
			||||||
 | 
					                );
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					            $res['list'] = arrayNullToString($res['list']->toArray());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->json(0, 'success', $res);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 审核加班 支持批量
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return Json
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function checkOvertime(): Json
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            $accountId = $this->request->user['user_id'] ?? 0;
 | 
				
			||||||
 | 
					            $type      = input('type/d', 1);//类型 1=通过 0=不通过
 | 
				
			||||||
 | 
					            $ids       = input('id/s');//待审核记录ID 多个用逗号分割
 | 
				
			||||||
 | 
					            $ids       = explode(',', $ids);
 | 
				
			||||||
 | 
					            $ids       = array_filter($ids);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (!in_array($type, [0, 1])) {
 | 
				
			||||||
 | 
					                return $this->json(4001, '审核参数错误');
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (!$account = Account::findById($accountId, ['id, role'])) {
 | 
				
			||||||
 | 
					                return $this->json(6001, '请先登录');
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if ($account['role'] <= Account::COMMON_ON) {
 | 
				
			||||||
 | 
					                // 工地负责人才能操作
 | 
				
			||||||
 | 
					                return $this->json(4003, '无此权限');
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $worksiteIds = AccountWorksite::where('account_id', $accountId)->column('worksite_id');
 | 
				
			||||||
 | 
					            if (OvertimeLog::whereIn('id', $ids)->whereNotIn('worksite_id', $worksiteIds)->count() > 0) {
 | 
				
			||||||
 | 
					                return $this->json(4003, '部分记录不在您权限操作的范围');
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            OvertimeLog::whereIn('id', $ids)->where('status', ClockLog::COMMON_OFF)->update([
 | 
				
			||||||
 | 
					                'status'   => $type == 1 ? 1 : -1,
 | 
				
			||||||
 | 
					                'check_at' => date('Y-m-d H:i:s'),
 | 
				
			||||||
 | 
					                'check_by' => $accountId
 | 
				
			||||||
 | 
					            ]);
 | 
				
			||||||
 | 
					            return $this->json();
 | 
				
			||||||
 | 
					        } catch (Exception $e) {
 | 
				
			||||||
 | 
					            return $this->json(5000, '审核失败'.$e->getMessage());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // 工资记录
 | 
				
			||||||
 | 
					    public function payListMock(): Json
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $page   = input('page/d', 1);
 | 
				
			||||||
 | 
					        $size   = input('size/d', 20);
 | 
				
			||||||
 | 
					        $status = input('status/d', -1);
 | 
				
			||||||
 | 
					        $date   = input('data/s', '');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $accountId = $this->request->user['user_id'] ?? 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $where = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!empty($keyword)) {
 | 
				
			||||||
 | 
					            $where[] = ['w.name', 'like', '%'.$keyword.'%'];
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($status >= 0) {
 | 
				
			||||||
 | 
					            $where[] = ['w.status', '=', $status];
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!empty($date)) {
 | 
				
			||||||
 | 
					            $date    = str_replace('_', '', $date);
 | 
				
			||||||
 | 
					            $where[] = ['cl.time', '=', $date];
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $where[] = ['cl.account_id', '=', $accountId];
 | 
				
			||||||
 | 
					        //        $query   = \app\model\ClockLog::alias('cl')
 | 
				
			||||||
 | 
					        //            ->leftJoin('worksite w', 'w.id = cl.worksite_id')
 | 
				
			||||||
 | 
					        //            ->field('cl.*,w.name as worksite_name')
 | 
				
			||||||
 | 
					        //            ->where($where);
 | 
				
			||||||
 | 
					        //
 | 
				
			||||||
 | 
					        //        $total = $query->count();
 | 
				
			||||||
 | 
					        $total = 20;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $res = [
 | 
				
			||||||
 | 
					            'total'   => $total,
 | 
				
			||||||
 | 
					            'current' => $page ?: 1,
 | 
				
			||||||
 | 
					            'size'    => $size ?: 20,
 | 
				
			||||||
 | 
					            'info'    => [],
 | 
				
			||||||
 | 
					            'list'    => new Collection(),
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($total > 0) {
 | 
				
			||||||
 | 
					            $res['info'] = [
 | 
				
			||||||
 | 
					                'amount'          => 999999,//工资总金额
 | 
				
			||||||
 | 
					                'base_amount'     => 20000,//基本工资
 | 
				
			||||||
 | 
					                'overtime_amount' => 20000,//加班工资
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                'not_amount'  => 20000,//未发放
 | 
				
			||||||
 | 
					                'done_amount' => 20000,//已发放
 | 
				
			||||||
 | 
					            ];
 | 
				
			||||||
 | 
					            $res['list'] = [
 | 
				
			||||||
 | 
					                [
 | 
				
			||||||
 | 
					                    'name'            => '张珊珊',
 | 
				
			||||||
 | 
					                    'status'          => 0,
 | 
				
			||||||
 | 
					                    'status_text'     => '待发放',
 | 
				
			||||||
 | 
					                    'base_amount'     => 7500,
 | 
				
			||||||
 | 
					                    'overtime_amount' => 0,
 | 
				
			||||||
 | 
					                    'amount'          => 7500,
 | 
				
			||||||
 | 
					                ],
 | 
				
			||||||
 | 
					                [
 | 
				
			||||||
 | 
					                    'name'            => '李珊珊',
 | 
				
			||||||
 | 
					                    'status'          => 0,
 | 
				
			||||||
 | 
					                    'status_text'     => '待发放',
 | 
				
			||||||
 | 
					                    'base_amount'     => 7500,
 | 
				
			||||||
 | 
					                    'overtime_amount' => 0,
 | 
				
			||||||
 | 
					                    'amount'          => 7500,
 | 
				
			||||||
 | 
					                ],
 | 
				
			||||||
 | 
					                [
 | 
				
			||||||
 | 
					                    'name'            => '王珊珊',
 | 
				
			||||||
 | 
					                    'status'          => 0,
 | 
				
			||||||
 | 
					                    'status_text'     => '待发放',
 | 
				
			||||||
 | 
					                    'base_amount'     => 7500,
 | 
				
			||||||
 | 
					                    'overtime_amount' => 0,
 | 
				
			||||||
 | 
					                    'amount'          => 7500,
 | 
				
			||||||
 | 
					                ],
 | 
				
			||||||
 | 
					                [
 | 
				
			||||||
 | 
					                    'name'            => '张珊珊',
 | 
				
			||||||
 | 
					                    'status'          => 0,
 | 
				
			||||||
 | 
					                    'status_text'     => '待发放',
 | 
				
			||||||
 | 
					                    'base_amount'     => 7500,
 | 
				
			||||||
 | 
					                    'overtime_amount' => 0,
 | 
				
			||||||
 | 
					                    'amount'          => 7500,
 | 
				
			||||||
 | 
					                ],
 | 
				
			||||||
 | 
					                [
 | 
				
			||||||
 | 
					                    'name'            => '刘珊珊',
 | 
				
			||||||
 | 
					                    'status'          => 0,
 | 
				
			||||||
 | 
					                    'status_text'     => '待发放',
 | 
				
			||||||
 | 
					                    'base_amount'     => 7500,
 | 
				
			||||||
 | 
					                    'overtime_amount' => 0,
 | 
				
			||||||
 | 
					                    'amount'          => 7500,
 | 
				
			||||||
 | 
					                ],
 | 
				
			||||||
 | 
					                [
 | 
				
			||||||
 | 
					                    'name'            => '谢珊珊',
 | 
				
			||||||
 | 
					                    'status'          => 0,
 | 
				
			||||||
 | 
					                    'status_text'     => '待发放',
 | 
				
			||||||
 | 
					                    'base_amount'     => 7500,
 | 
				
			||||||
 | 
					                    'overtime_amount' => 0,
 | 
				
			||||||
 | 
					                    'amount'          => 7500,
 | 
				
			||||||
 | 
					                ],
 | 
				
			||||||
 | 
					                [
 | 
				
			||||||
 | 
					                    'name'            => '吴珊珊',
 | 
				
			||||||
 | 
					                    'status'          => 0,
 | 
				
			||||||
 | 
					                    'status_text'     => '待发放',
 | 
				
			||||||
 | 
					                    'base_amount'     => 7500,
 | 
				
			||||||
 | 
					                    'overtime_amount' => 0,
 | 
				
			||||||
 | 
					                    'amount'          => 7500,
 | 
				
			||||||
 | 
					                ],
 | 
				
			||||||
 | 
					            ];
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->json(0, 'success', $res);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // 工资记录
 | 
				
			||||||
 | 
					    public function payList(): Json
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $page   = input('page/d', 1);
 | 
				
			||||||
 | 
					        $size   = input('size/d', 20);
 | 
				
			||||||
 | 
					        $status = input('status/d', -1);
 | 
				
			||||||
 | 
					        $date   = input('date/s', '');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $accountId = $this->request->user['user_id'] ?? 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $where = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!empty($date)) {
 | 
				
			||||||
 | 
					            $date    = str_replace('_', '', $date);
 | 
				
			||||||
 | 
					            $where[] = ['pml.time', '=', $date];
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $worksiteIds = AccountWorksite::where('account_id', $accountId)->column('worksite_id');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $total = 0;
 | 
				
			||||||
 | 
					        $res   = [
 | 
				
			||||||
 | 
					            'total'   => $total,
 | 
				
			||||||
 | 
					            'current' => $page ?: 1,
 | 
				
			||||||
 | 
					            'size'    => $size ?: 20,
 | 
				
			||||||
 | 
					            'info'    => [],
 | 
				
			||||||
 | 
					            'list'    => new Collection(),
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (empty($worksiteIds)) {
 | 
				
			||||||
 | 
					            return $this->json(0, 'success', $res);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // 当前明确说明 负责人和工地是一对一关系
 | 
				
			||||||
 | 
					        $where[] = ['pml.worksite_id', '=', $worksiteIds[0]];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $query = \app\model\PayMonthLog::alias('pml')
 | 
				
			||||||
 | 
					            //            ->leftJoin('account a', 'a.id = pml.account_id')
 | 
				
			||||||
 | 
					            ->where($where);
 | 
				
			||||||
 | 
					        // 汇总信息
 | 
				
			||||||
 | 
					        $info = $query->fieldRaw('sum(pml.amount) as amount, sum(pml.base_amount) as base_amount,
 | 
				
			||||||
 | 
					            sum(pml.overtime_amount) as overtime_amount')->find()->toArray();
 | 
				
			||||||
 | 
					        // 已发放工资
 | 
				
			||||||
 | 
					        $doneAmount = $query->where('pml.status', 1)->fieldRaw('sum(pml.amount) as amount')->find()->toArray();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $res['info'] = [
 | 
				
			||||||
 | 
					            'amount'          => $info['amount'] ?? 0,
 | 
				
			||||||
 | 
					            'base_amount'     => $info['base_amount'] ?? 0,
 | 
				
			||||||
 | 
					            'overtime_amount' => $info['overtime_amount'] ?? 0,
 | 
				
			||||||
 | 
					            'done_amount'     => $doneAmount['amount'] ?? 0,
 | 
				
			||||||
 | 
					            'not_amount'      => Math::sub($info['amount'] ?? 0, $doneAmount['amount'] ?? 0),
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($status >= 0) {
 | 
				
			||||||
 | 
					            $where[] = ['pml.status', '=', $status];
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $query = \app\model\PayMonthLog::alias('pml')
 | 
				
			||||||
 | 
					            ->leftJoin('account a', 'a.id = pml.account_id')
 | 
				
			||||||
 | 
					            ->where($where);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $total        = $query->count();
 | 
				
			||||||
 | 
					        $res['total'] = $total;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($total > 0) {
 | 
				
			||||||
 | 
					            $res['list'] = $query->field('pml.id,pml.status,pml.amount,pml.base_amount,pml.overtime_amount,a.real_name as name')->page($page, $size)->order('pml.id', 'desc')->select();
 | 
				
			||||||
 | 
					            $res['list']->each(function ($item) {
 | 
				
			||||||
 | 
					                $item->status_text = $item->status == 1 ? '已发放' : '待发放';
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->json(0, 'success', $res);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,403 @@
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace app\controller\api\v1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use app\controller\api\Base;
 | 
				
			||||||
 | 
					use app\exception\RepositoryException;
 | 
				
			||||||
 | 
					use app\model\Account;
 | 
				
			||||||
 | 
					use app\model\AccountRecord;
 | 
				
			||||||
 | 
					use app\repository\AccountRepository;
 | 
				
			||||||
 | 
					use app\service\File;
 | 
				
			||||||
 | 
					use app\service\Jwt;
 | 
				
			||||||
 | 
					use app\service\wx\WechatApplets;
 | 
				
			||||||
 | 
					use app\validate\User as UserValidate;
 | 
				
			||||||
 | 
					use EasyWeChat\Kernel\Exceptions\InvalidConfigException;
 | 
				
			||||||
 | 
					use Exception;
 | 
				
			||||||
 | 
					use think\Collection;
 | 
				
			||||||
 | 
					use think\db\exception\DataNotFoundException;
 | 
				
			||||||
 | 
					use think\db\exception\DbException;
 | 
				
			||||||
 | 
					use think\db\exception\ModelNotFoundException;
 | 
				
			||||||
 | 
					use think\facade\Log;
 | 
				
			||||||
 | 
					use think\response\Json;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class User extends Base
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    protected $noNeedLogin = [
 | 
				
			||||||
 | 
					        'login',
 | 
				
			||||||
 | 
					        'tempLogin',
 | 
				
			||||||
 | 
					        'signInfo',
 | 
				
			||||||
 | 
					        'signToday',
 | 
				
			||||||
 | 
					        'checkActive'
 | 
				
			||||||
 | 
					    ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 登录  成功返回token及用户信息
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return Json
 | 
				
			||||||
 | 
					     * @throws InvalidConfigException
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function login(): Json
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $params = input();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Log::error('进入参数');
 | 
				
			||||||
 | 
					        Log::error($params);
 | 
				
			||||||
 | 
					        Log::error('参数结束');
 | 
				
			||||||
 | 
					        $validate = new UserValidate();
 | 
				
			||||||
 | 
					        if (!$validate->scene('wx_applets')->check($params)) {
 | 
				
			||||||
 | 
					            return $this->json(4000, $validate->getError());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        $minApp = WechatApplets::getInstance();
 | 
				
			||||||
 | 
					        $jsCode = $params['code'];
 | 
				
			||||||
 | 
					        $wxUser = $minApp->auth->session($jsCode);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (isset($wxUser['errcode']) && $wxUser['errcode'] != 0) {
 | 
				
			||||||
 | 
					            return $this->json(4001, $wxUser['errcode'].';'.$wxUser['errmsg'] ?? '登录失败');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        // $wxUser success has [session_key, openid, unionid]
 | 
				
			||||||
 | 
					        // 有效期2小时
 | 
				
			||||||
 | 
					        $wxUser['expire_time'] = time() + 7200;
 | 
				
			||||||
 | 
					        $wxUser['session_key'] = $wxUser['session_key'] ?? '';
 | 
				
			||||||
 | 
					        $openID                = $wxUser['openid'];
 | 
				
			||||||
 | 
					        $unionid               = $wxUser['unionid'] ?? '';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (empty($openID) && empty($unionid)) {
 | 
				
			||||||
 | 
					            return $this->json(4002, '登录失败');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        $isActive    = $params['is_active'] ?? 0;
 | 
				
			||||||
 | 
					        $isActive    = (is_numeric($isActive) && $isActive > 0) ? AccountRepository::BOOL_TRUE : AccountRepository::BOOL_FALSE;
 | 
				
			||||||
 | 
					        $phoneActive = $params['phone_active'] ?? 0;
 | 
				
			||||||
 | 
					        $phoneActive = (is_numeric($phoneActive) && $phoneActive > 0) ? AccountRepository::BOOL_TRUE : AccountRepository::BOOL_FALSE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            $repo    = AccountRepository::getInstance();
 | 
				
			||||||
 | 
					            $account = $repo->findByOpenID($openID);
 | 
				
			||||||
 | 
					            if (!$account && !empty($unionid)) {
 | 
				
			||||||
 | 
					                $account = $repo->findByUnionId($unionid);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $now = date('Y-m-d H:i:s');
 | 
				
			||||||
 | 
					            if (!$account) {
 | 
				
			||||||
 | 
					                // 自动注册
 | 
				
			||||||
 | 
					                $account = $repo->create([
 | 
				
			||||||
 | 
					                    'unionid'      => $unionid ?? '',
 | 
				
			||||||
 | 
					                    'openid'       => $openID,
 | 
				
			||||||
 | 
					                    'last_login'   => $now,
 | 
				
			||||||
 | 
					                    'login_ip'     => $this->request->ip(),
 | 
				
			||||||
 | 
					                    'created_at'   => $now,
 | 
				
			||||||
 | 
					                    'nickname'     => $params['nickname'] ?? '',
 | 
				
			||||||
 | 
					                    'headimgurl'   => $params['headimgurl'] ?? '',
 | 
				
			||||||
 | 
					                    'mobile'       => $params['mobile'] ?? '',
 | 
				
			||||||
 | 
					                    'status'       => AccountRepository::STATUS_NORMAL,
 | 
				
			||||||
 | 
					                    'is_active'    => $isActive,
 | 
				
			||||||
 | 
					                    'phone_active' => $phoneActive,
 | 
				
			||||||
 | 
					                    'session_key'  => $wxUser['session_key'] ?? '',
 | 
				
			||||||
 | 
					                ]);
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                $updateData = [
 | 
				
			||||||
 | 
					                    'last_login'  => date('Y-m-d H:i:s'),
 | 
				
			||||||
 | 
					                    'login_ip'    => $this->request->ip(),
 | 
				
			||||||
 | 
					                    'session_key' => $wxUser['session_key'] ?? '',
 | 
				
			||||||
 | 
					                ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                // 更新资料
 | 
				
			||||||
 | 
					                $modifyStringList = ['headimgurl', 'nickname', 'mobile'];
 | 
				
			||||||
 | 
					                foreach ($modifyStringList as $modifyKey) {
 | 
				
			||||||
 | 
					                    if (isset($account[$modifyKey]) && empty($account[$modifyKey])) {
 | 
				
			||||||
 | 
					                        $updateData[$modifyKey] = $params[$modifyKey] ?? '';
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                if (empty($account['gender'])) {
 | 
				
			||||||
 | 
					                    $updateData['gender'] = $params['gender'] ?? 0;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                if (isset($account['is_active']) && $account['is_active'] == AccountRepository::BOOL_FALSE) {
 | 
				
			||||||
 | 
					                    $updateData['is_active'] = $isActive;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                if (isset($account['phone_active']) && $account['phone_active'] == AccountRepository::BOOL_FALSE) {
 | 
				
			||||||
 | 
					                    $updateData['phone_active'] = $phoneActive;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                $repo->update($updateData, ['id' => $account['id']]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                $account = $repo->findById($account['id']);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        } catch (RepositoryException | Exception $e) {
 | 
				
			||||||
 | 
					            return $this->json(4003, '登录失败!'.$e->getMessage());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $account = $account->toArray();
 | 
				
			||||||
 | 
					        $jwtData = [
 | 
				
			||||||
 | 
					            'user_id'     => $account['id'],
 | 
				
			||||||
 | 
					            'open_id'     => $openID,
 | 
				
			||||||
 | 
					            'session_key' => $wxUser['session_key'],
 | 
				
			||||||
 | 
					            'expire_time' => $wxUser['expire_time'],
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $account['headimgurl'] = File::convertCompleteFileUrl($account['headimgurl']);
 | 
				
			||||||
 | 
					        $fields                = [
 | 
				
			||||||
 | 
					            'coding', 'real_name', 'nickname', 'headimgurl', 'gender', 'mobile',
 | 
				
			||||||
 | 
					            'status', 'is_active', 'phone_active'
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $accountData = arrayKeysFilter($account, $fields);
 | 
				
			||||||
 | 
					        $data        = [
 | 
				
			||||||
 | 
					            'account_id' => $account['id'],
 | 
				
			||||||
 | 
					            'token'      => Jwt::generate($jwtData),
 | 
				
			||||||
 | 
					            'expire'     => $wxUser['expire_time'],
 | 
				
			||||||
 | 
					            'openid'     => $openID,
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					        $data        = array_merge($data, $accountData);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->json(0, 'success', $data);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 获取用户信息
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return Json
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function info(): Json
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            $accountId = $this->request->user['user_id'] ?? 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $user = Account::getUser($accountId);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return $this->json(0, 'success', $user);
 | 
				
			||||||
 | 
					        } catch (Exception $e) {
 | 
				
			||||||
 | 
					            return $this->json(4000, '没有相关的用户记录'.$e->getMessage());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 修改用户信息
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function updateInfo(): Json
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            $params = input('post.');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $rules = [
 | 
				
			||||||
 | 
					                'field|修改项'  => 'require|in:nickname',
 | 
				
			||||||
 | 
					                'value|修改内容' => 'require',
 | 
				
			||||||
 | 
					            ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $accountId = $this->request->user['user_id'] ?? 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $validate = $this->validateByApi($params, $rules, ['field.in' => '参数错误']);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if ($validate !== true) {
 | 
				
			||||||
 | 
					                return $validate;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (!$customer = Account::findById($accountId)) {
 | 
				
			||||||
 | 
					                return $this->json(4004, '用户不存在');
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $customer->save([
 | 
				
			||||||
 | 
					                $params['field'] => $params['value']
 | 
				
			||||||
 | 
					            ]);
 | 
				
			||||||
 | 
					        } catch (Exception $e) {
 | 
				
			||||||
 | 
					            Log::error('修改用户信息失败'.$e->getMessage());
 | 
				
			||||||
 | 
					            return $this->json(5000, '修改失败!'.$e->getMessage());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->json();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 临时登录  通过openid登录 仅用于接口测试阶段
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return Json
 | 
				
			||||||
 | 
					     * @throws DataNotFoundException
 | 
				
			||||||
 | 
					     * @throws DbException
 | 
				
			||||||
 | 
					     * @throws ModelNotFoundException
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function tempLogin(): Json
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $params = $this->request->param();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!isset($params['openid'])) {
 | 
				
			||||||
 | 
					            return $this->json(4001, '参数错误');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!$user = AccountRepository::getInstance()->findByOpenID($params['openid'])) {
 | 
				
			||||||
 | 
					            return $this->json(4004, '账号不存在');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $data = [
 | 
				
			||||||
 | 
					            'token'  => Jwt::generate(['user_id' => $user['id'], 'nickname' => $user['nickname']]),
 | 
				
			||||||
 | 
					            'expire' => Jwt::expire()
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->json(0, 'success', $data);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 用户操作记录 分享、咨询
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return Json
 | 
				
			||||||
 | 
					     * @throws Exception
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function record(): Json
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (!$this->request->isPost()) {
 | 
				
			||||||
 | 
					            return $this->json(4000, '无效请求');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $accountId = $this->request->user['user_id'] ?? 0;
 | 
				
			||||||
 | 
					        $params    = input('post.');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $rules = [
 | 
				
			||||||
 | 
					            'type|操作类型' => 'require|in:content,other,spu,activity',
 | 
				
			||||||
 | 
					            'action|操作' => 'require',
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (isset($params['type']) && $params['type'] == AccountRecord::TYPE_CONTENT) {
 | 
				
			||||||
 | 
					            $rules['id|ID'] = 'require';
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $validate = $this->validateByApi($params, $rules, ['type.in' => '类型错误', 'id.require' => '此类型 ID必传']);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($validate !== true) {
 | 
				
			||||||
 | 
					            return $validate;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            $relationId = $params['id'] ?? 0;
 | 
				
			||||||
 | 
					            $relationId = is_numeric($relationId) ? $relationId : 0;
 | 
				
			||||||
 | 
					            AccountRecord::record($accountId, $params['type'], $params['action'], $relationId);
 | 
				
			||||||
 | 
					        } catch (Exception $e) {
 | 
				
			||||||
 | 
					            AccountRepository::log('记录用户操作失败', $e);
 | 
				
			||||||
 | 
					            return $this->json(5001, '操作失败');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->json();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 绑定手机
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return bool|Json
 | 
				
			||||||
 | 
					     * @throws Exception
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function bindPhone()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (!$this->request->isPost()) {
 | 
				
			||||||
 | 
					            return $this->json(4000, '无效请求');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $accountId = $this->request->user['user_id'] ?? 0;
 | 
				
			||||||
 | 
					        $params    = input('post.');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $rules = [
 | 
				
			||||||
 | 
					            'encryptedData|加密数据' => 'require',
 | 
				
			||||||
 | 
					            'iv|IV'              => 'require',
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $validate = $this->validateByApi($params, $rules);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($validate !== true) {
 | 
				
			||||||
 | 
					            return $validate;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            if (!$account = Account::findById($accountId)) {
 | 
				
			||||||
 | 
					                return $this->json(4000, '用户不存在');
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // 解密手机相关数据  若存在手机则覆盖
 | 
				
			||||||
 | 
					            $minApp      = WechatApplets::getInstance();
 | 
				
			||||||
 | 
					            $sessionKey  = $this->request->user['session_key'] ?? '';
 | 
				
			||||||
 | 
					            $decryptData = $minApp->encryptor->decryptData($sessionKey, $params['iv'], $params['encryptedData']);
 | 
				
			||||||
 | 
					            $phone       = $decryptData['phoneNumber'] ?? ''; // 通过iv和加密数据 解密出手机号
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (Account::where('id', '<>', $accountId)->where('mobile', $phone)->count() > 0) {
 | 
				
			||||||
 | 
					                return $this->json(4000, '该手机已被绑定,若有绑定错误,请联系客服');
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if ($phone) {
 | 
				
			||||||
 | 
					                $account->save(['mobile' => $phone, 'phone_active' => Account::COMMON_ON]);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return $this->json(0, 'success', ['phone' => $phone]);
 | 
				
			||||||
 | 
					        } catch (Exception $e) {
 | 
				
			||||||
 | 
					            AccountRepository::log('手机绑定失败', $e);
 | 
				
			||||||
 | 
					            return $this->json(5001, '手机绑定失败');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // 打卡页面信息
 | 
				
			||||||
 | 
					    public function signInfo(): Json
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $list = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $week    = ['日', '一', '二', '三', '四', '五', '六'];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $info    = [
 | 
				
			||||||
 | 
					            'today' => date('Y年m月d日'),
 | 
				
			||||||
 | 
					            'week'  => '星期'.$week[date('w')],
 | 
				
			||||||
 | 
					            'now' => date('H:i:s'),
 | 
				
			||||||
 | 
					            'is_sign' => (int) !empty($list),
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->json(0, 'success', ['info' => $info]);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // 今日打卡记录
 | 
				
			||||||
 | 
					    public function signToday(): Json
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $accountId = $this->request->user['user_id'] ?? 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $list = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($accountId > 0) {
 | 
				
			||||||
 | 
					            $where   = [];
 | 
				
			||||||
 | 
					            $where[] = ['cl.created_at', '>', date('Y-m-d 00:00:00')];
 | 
				
			||||||
 | 
					            $where[] = ['cl.created_at', '<', date('Y-m-d 23:59:59')];
 | 
				
			||||||
 | 
					            $where[] = ['cl.account_id', '=', $accountId];
 | 
				
			||||||
 | 
					            $list    = \app\model\ClockLog::alias('cl')
 | 
				
			||||||
 | 
					                ->leftJoin('worksite w', 'w.id = cl.worksite_id')
 | 
				
			||||||
 | 
					                ->field('cl.*,w.name as worksite_name')
 | 
				
			||||||
 | 
					                ->where($where)
 | 
				
			||||||
 | 
					                ->order('cl.id', 'desc')
 | 
				
			||||||
 | 
					                ->select();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $list->each(function ($item) {
 | 
				
			||||||
 | 
					                $item->type_text = $item->type == 'in' ? '上班' : '下班';
 | 
				
			||||||
 | 
					                switch ($item->status) {
 | 
				
			||||||
 | 
					                    case 0:
 | 
				
			||||||
 | 
					                        $item->status_text = '待确认';
 | 
				
			||||||
 | 
					                        break;
 | 
				
			||||||
 | 
					                    case 1:
 | 
				
			||||||
 | 
					                        $item->status_text = '已确认';
 | 
				
			||||||
 | 
					                        break;
 | 
				
			||||||
 | 
					                    case -1:
 | 
				
			||||||
 | 
					                        $item->status_text = '不通过';
 | 
				
			||||||
 | 
					                        break;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                $item->time = date('H:i:s', $item->create_time);
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					            $list = $list->toArray();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->json(0, 'success', ['list' => $list]);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function checkActive(): Json
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            $openid = input('openid/s');
 | 
				
			||||||
 | 
					            if (empty($openid)) {
 | 
				
			||||||
 | 
					                return $this->json(0,'success', ['status' => 0]);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $isActive = (int)Account::where('openid', $openid)->value('is_active');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return $this->json(0, 'success', ['status' => $isActive]);
 | 
				
			||||||
 | 
					        } catch (Exception $e) {
 | 
				
			||||||
 | 
					            return $this->json(4000, '检查账号是否微信授权是不'.$e->getMessage());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,673 @@
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace app\controller\api\v1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use app\controller\api\Base;
 | 
				
			||||||
 | 
					use app\controller\manager\Clock;
 | 
				
			||||||
 | 
					use app\exception\RepositoryException;
 | 
				
			||||||
 | 
					use app\model\Account;
 | 
				
			||||||
 | 
					use app\model\AccountRecord;
 | 
				
			||||||
 | 
					use app\model\AccountWorksite;
 | 
				
			||||||
 | 
					use app\model\CheckLog;
 | 
				
			||||||
 | 
					use app\model\ClockLog;
 | 
				
			||||||
 | 
					use app\model\OvertimeLog;
 | 
				
			||||||
 | 
					use app\model\PayLog;
 | 
				
			||||||
 | 
					use app\model\Worksite;
 | 
				
			||||||
 | 
					use app\repository\AccountRepository;
 | 
				
			||||||
 | 
					use app\service\File;
 | 
				
			||||||
 | 
					use app\service\Jwt;
 | 
				
			||||||
 | 
					use app\service\wx\WechatApplets;
 | 
				
			||||||
 | 
					use app\validate\User as UserValidate;
 | 
				
			||||||
 | 
					use EasyWeChat\Kernel\Exceptions\InvalidConfigException;
 | 
				
			||||||
 | 
					use Exception;
 | 
				
			||||||
 | 
					use think\Collection;
 | 
				
			||||||
 | 
					use think\db\exception\DataNotFoundException;
 | 
				
			||||||
 | 
					use think\db\exception\DbException;
 | 
				
			||||||
 | 
					use think\db\exception\ModelNotFoundException;
 | 
				
			||||||
 | 
					use think\facade\Log;
 | 
				
			||||||
 | 
					use think\response\Json;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * 工人相关
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Class Worker
 | 
				
			||||||
 | 
					 * @package app\controller\api\v1
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					class Worker extends Base
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    protected $noNeedLogin = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 注册工人资料
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function register(): Json
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (!$this->request->isPost()) {
 | 
				
			||||||
 | 
					            return $this->json(4000, '无效请求');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $accountId = $this->request->user['user_id'] ?? 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!$account = Account::findById($accountId)) {
 | 
				
			||||||
 | 
					            return $this->json(6001, '请先登录');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($account['role'] != Account::COMMON_OFF) {
 | 
				
			||||||
 | 
					            return $this->json(4003, '您无需提交资料');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($account['checking'] == Account::COMMON_ON) {
 | 
				
			||||||
 | 
					            return $this->json(4002, '您已提交资料,等待审核中');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $post = input('post.');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $rules = [
 | 
				
			||||||
 | 
					            'real_name|姓名'            => 'require|max:50|min:2',
 | 
				
			||||||
 | 
					            'mobile|手机号'              => 'require',
 | 
				
			||||||
 | 
					            'pay|工资'                  => 'require|number|min:0',
 | 
				
			||||||
 | 
					            'emergency_contact|紧急联系人' => 'require',
 | 
				
			||||||
 | 
					            'emergency_phone|紧急联系人电话' => 'require',
 | 
				
			||||||
 | 
					            'bank_card_name|银行卡户名'    => 'require',
 | 
				
			||||||
 | 
					            'bank_card_number|银行卡号'   => 'require',
 | 
				
			||||||
 | 
					            'bank_name|开户行'           => 'require|max:100',
 | 
				
			||||||
 | 
					            'card_number|身份证'         => 'require|max:20|min:15',
 | 
				
			||||||
 | 
					            'position|岗位'             => 'require|number',
 | 
				
			||||||
 | 
					            'worksite_id|工地'          => 'require|number',
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $message = [
 | 
				
			||||||
 | 
					            'worksite_id.number'   => '工地必选',
 | 
				
			||||||
 | 
					            'worksite_id.position' => '岗位必选',
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $validate = $this->validateByApi($post, $rules, $message);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($validate !== true) {
 | 
				
			||||||
 | 
					            return $validate;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $fields = [
 | 
				
			||||||
 | 
					            'real_name', 'mobile', 'pay', 'emergency_contact', 'emergency_phone', 'bank_card_name', 'bank_card_number',
 | 
				
			||||||
 | 
					            'bank_name', 'card_number', 'position', 'worksite_id'
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					        $post   = array_filter($post, function ($item, $key) use ($fields) {
 | 
				
			||||||
 | 
					            return in_array($key, $fields);
 | 
				
			||||||
 | 
					        }, ARRAY_FILTER_USE_BOTH);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $post['account_id']  = $accountId;
 | 
				
			||||||
 | 
					        $post['is_register'] = CheckLog::COMMON_ON;
 | 
				
			||||||
 | 
					        $post['created_at']  = date('Y-m-d H:i:s');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            CheckLog::create($post);
 | 
				
			||||||
 | 
					            $account->save(['checking' => Account::COMMON_ON]);
 | 
				
			||||||
 | 
					        } catch (Exception $e) {
 | 
				
			||||||
 | 
					            return $this->json(5000, '资料录入失败');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return $this->json();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 修改用户信息 字段区分:1.负责人审核 2.不需要审核 如nickname
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function updateInfo(): Json
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            $params = input('post.');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $rules = [
 | 
				
			||||||
 | 
					                'field|修改项'  => 'require',
 | 
				
			||||||
 | 
					                'value|修改内容' => 'require',
 | 
				
			||||||
 | 
					            ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $accountId = $this->request->user['user_id'] ?? 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $validate = $this->validateByApi($params, $rules);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if ($validate !== true) {
 | 
				
			||||||
 | 
					                return $validate;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (!$customer = Account::findById($accountId)) {
 | 
				
			||||||
 | 
					                return $this->json(4004, '用户不存在');
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $needCheckFields = Account::needCheckFields();
 | 
				
			||||||
 | 
					            // 需要审核的字段
 | 
				
			||||||
 | 
					            if (in_array($params['field'], $needCheckFields)) {
 | 
				
			||||||
 | 
					                // 字段值未改变
 | 
				
			||||||
 | 
					                if ($params['value'] == ($customer[$params['field']] ?? '')) {
 | 
				
			||||||
 | 
					                    return $this->json();
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                $insert = [];
 | 
				
			||||||
 | 
					                $update = [];
 | 
				
			||||||
 | 
					                foreach ($needCheckFields as $field) {
 | 
				
			||||||
 | 
					                    $insert[$field] = $field == $params['field'] ? $params['value'] : $customer[$field];
 | 
				
			||||||
 | 
					                    if ($field == $params['field']) {
 | 
				
			||||||
 | 
					                        $update[$field] = $params['value'];
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if (!$checkLog = CheckLog::where('account_id', $accountId)->where('status', CheckLog::COMMON_OFF)
 | 
				
			||||||
 | 
					                    ->find()) {
 | 
				
			||||||
 | 
					                    // 没有待审核的记录则新增
 | 
				
			||||||
 | 
					                    $insert['created_at']  = date('Y-m-d H:i:s');
 | 
				
			||||||
 | 
					                    $insert['account_id']  = $accountId;
 | 
				
			||||||
 | 
					                    $insert['worksite_id'] = $customer['worksite_id'];
 | 
				
			||||||
 | 
					                    CheckLog::create($insert);
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    $checkLog->save($update);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                $customer->save(['checking' => Account::COMMON_ON]);
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                $customer->save([
 | 
				
			||||||
 | 
					                    $params['field'] => $params['value']
 | 
				
			||||||
 | 
					                ]);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        } catch (Exception $e) {
 | 
				
			||||||
 | 
					            Log::error('工人资料修改失败'.$e->getMessage());
 | 
				
			||||||
 | 
					            return $this->json(5000, '修改资料失败!'.$e->getMessage());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->json();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 工人打卡
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function sign(): Json
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            $input = input('post.');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $rules = [
 | 
				
			||||||
 | 
					                'type|打卡类型'      => 'require|in:in,out',
 | 
				
			||||||
 | 
					                'lat|维度'         => 'require',
 | 
				
			||||||
 | 
					                'lng|经度'         => 'require',
 | 
				
			||||||
 | 
					                'worksite_id|工地' => 'require|number',
 | 
				
			||||||
 | 
					            ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $validate = $this->validateByApi($input, $rules, ['type.in' => '打卡类型错误']);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if ($validate !== true) {
 | 
				
			||||||
 | 
					                return $validate;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $accountId = $this->request->user['user_id'] ?? 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (!$customer = Account::findById($accountId)) {
 | 
				
			||||||
 | 
					                return $this->json(6001, '请先登录');
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if ($customer['role'] != Account::ROLE_WORKER) {
 | 
				
			||||||
 | 
					                return $this->json(4003, '完成审核后方可打卡');
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $worksite = Worksite::getNearest($input['lng'], $input['lat']);
 | 
				
			||||||
 | 
					            if (empty($worksite) || $worksite['id'] != $input['worksite_id']) {
 | 
				
			||||||
 | 
					                return $this->json(4004, '定位错误,请在工地200米范围内打卡!');
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $time = time();
 | 
				
			||||||
 | 
					            //            $time = $time - 86401 * 3;
 | 
				
			||||||
 | 
					            $now = date('Y-m-d H:i:s', $time);
 | 
				
			||||||
 | 
					            $day = date('Ymd', $time);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (ClockLog::where('account_id', $accountId)->where('type', $input['type'])->where('create_time', '>', time() - 60)->count()) {
 | 
				
			||||||
 | 
					                return $this->json(4001, '打卡频率过快!');
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            ClockLog::create([
 | 
				
			||||||
 | 
					                'account_id'  => $accountId,
 | 
				
			||||||
 | 
					                'type'        => $input['type'],
 | 
				
			||||||
 | 
					                'worksite_id' => $input['worksite_id'],
 | 
				
			||||||
 | 
					                'created_at'  => $now,
 | 
				
			||||||
 | 
					                'create_time' => $time,
 | 
				
			||||||
 | 
					                'day'         => $day,
 | 
				
			||||||
 | 
					                'indexs'      => $accountId.'-'.$input['worksite_id'].'-'.$day,
 | 
				
			||||||
 | 
					            ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // 创建当日工资初始记录
 | 
				
			||||||
 | 
					            PayLog::createWhenNotExists($accountId, $input['worksite_id'], $day);
 | 
				
			||||||
 | 
					        } catch (Exception $e) {
 | 
				
			||||||
 | 
					            Log::error('工人打卡失败'.$e->getMessage());
 | 
				
			||||||
 | 
					            return $this->json(5000, '打卡失败!');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->json();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // 我的打卡
 | 
				
			||||||
 | 
					    public function clockList(): Json
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $page       = input('page/d', 1);
 | 
				
			||||||
 | 
					        $size       = input('size/d', 20);
 | 
				
			||||||
 | 
					        $keyword    = input('keyword/s');
 | 
				
			||||||
 | 
					        $worksiteId = input('worksite_id/d', 0);
 | 
				
			||||||
 | 
					        $begin      = input('begin_at/s', '');
 | 
				
			||||||
 | 
					        $end        = input('end_at/s', '');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $accountId = $this->request->user['user_id'] ?? 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $where = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!empty($keyword)) {
 | 
				
			||||||
 | 
					            $where[] = ['w.name', 'like', '%'.$keyword.'%'];
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($worksiteId > 0) {
 | 
				
			||||||
 | 
					            $where[] = ['cl.worksite_id', '=', $worksiteId];
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!empty($begin)) {
 | 
				
			||||||
 | 
					            $where[] = ['cl.created_at', '>', $begin.' 00:00:00'];
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!empty($end)) {
 | 
				
			||||||
 | 
					            $where[] = ['cl.created_at', '<', $end.' 23:59:59'];
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $where[] = ['cl.account_id', '=', $accountId];
 | 
				
			||||||
 | 
					        $query   = \app\model\ClockLog::alias('cl')
 | 
				
			||||||
 | 
					            ->leftJoin('worksite w', 'w.id = cl.worksite_id')
 | 
				
			||||||
 | 
					            ->field('cl.*,w.name as worksite_name')
 | 
				
			||||||
 | 
					            ->where($where);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $total = $query->count();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $res = [
 | 
				
			||||||
 | 
					            'total'   => $total,
 | 
				
			||||||
 | 
					            'current' => $page ?: 1,
 | 
				
			||||||
 | 
					            'size'    => $size ?: 20,
 | 
				
			||||||
 | 
					            'list'    => new Collection(),
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($total > 0) {
 | 
				
			||||||
 | 
					            $res['list'] = $query->page($page, $size)->order('cl.id', 'desc')->select();
 | 
				
			||||||
 | 
					            $res['list']->each(function ($item) {
 | 
				
			||||||
 | 
					                $item->type_text = $item->type == 'in' ? '上班' : '下班';
 | 
				
			||||||
 | 
					                switch ($item->status) {
 | 
				
			||||||
 | 
					                    case 0:
 | 
				
			||||||
 | 
					                        $item->status_text = '待确认';
 | 
				
			||||||
 | 
					                        break;
 | 
				
			||||||
 | 
					                    case 1:
 | 
				
			||||||
 | 
					                        $item->status_text = '已确认';
 | 
				
			||||||
 | 
					                        break;
 | 
				
			||||||
 | 
					                    case -1:
 | 
				
			||||||
 | 
					                        $item->status_text = '不通过';
 | 
				
			||||||
 | 
					                        break;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                $item->time = date('H:i:s', $item->create_time);
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->json(0, 'success', $res);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 提交加班
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function overtime(): Json
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            $input = input('post.');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $rules = [
 | 
				
			||||||
 | 
					                'day|加班日期'       => 'require|date',
 | 
				
			||||||
 | 
					                'time|加班时长'      => 'require|float',
 | 
				
			||||||
 | 
					                'worksite_id|工地' => 'require|number',
 | 
				
			||||||
 | 
					            ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $validate = $this->validateByApi($input, $rules, ['worksite_id.number' => '工地必传']);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if ($validate !== true) {
 | 
				
			||||||
 | 
					                return $validate;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $accountId = $this->request->user['user_id'] ?? 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (!$customer = Account::findById($accountId)) {
 | 
				
			||||||
 | 
					                return $this->json(6001, '请先登录');
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if ($customer['role'] != Account::ROLE_WORKER) {
 | 
				
			||||||
 | 
					                return $this->json(4003, '还不是工人');
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $time = time();
 | 
				
			||||||
 | 
					            $now  = date('Y-m-d H:i:s', $time);
 | 
				
			||||||
 | 
					            $day  = date('Ymd', strtotime($input['day']));
 | 
				
			||||||
 | 
					            OvertimeLog::create([
 | 
				
			||||||
 | 
					                'account_id'  => $accountId,
 | 
				
			||||||
 | 
					                'worksite_id' => $input['worksite_id'],
 | 
				
			||||||
 | 
					                'day_text'    => $input['day'],
 | 
				
			||||||
 | 
					                'day'         => $day,
 | 
				
			||||||
 | 
					                'time'        => $input['time'],
 | 
				
			||||||
 | 
					                'remarks'     => $input['remarks'] ?? '',
 | 
				
			||||||
 | 
					                'indexs'      => $accountId.'-'.$input['worksite_id'].'-'.$day,
 | 
				
			||||||
 | 
					                'created_at'  => $now,
 | 
				
			||||||
 | 
					                'create_time' => $time,
 | 
				
			||||||
 | 
					            ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // 创建当日工资初始记录
 | 
				
			||||||
 | 
					            PayLog::createWhenNotExists($accountId, $input['worksite_id'], $day);
 | 
				
			||||||
 | 
					        } catch (Exception $e) {
 | 
				
			||||||
 | 
					            Log::error('工人加班提交失败'.$e->getMessage());
 | 
				
			||||||
 | 
					            return $this->json(5000, '加班申请失败!');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->json();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // 我的加班记录
 | 
				
			||||||
 | 
					    public function overtimeList(): Json
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $page       = input('page/d', 1);
 | 
				
			||||||
 | 
					        $size       = input('size/d', 20);
 | 
				
			||||||
 | 
					        $keyword    = input('keyword/s');
 | 
				
			||||||
 | 
					        $worksiteId = input('worksite_id/d', 0);
 | 
				
			||||||
 | 
					        $begin      = input('begin_at/s', '');
 | 
				
			||||||
 | 
					        $end        = input('end_at/s', '');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $accountId = $this->request->user['user_id'] ?? 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $where = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!empty($keyword)) {
 | 
				
			||||||
 | 
					            $where[] = ['w.name', 'like', '%'.$keyword.'%'];
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($worksiteId > 0) {
 | 
				
			||||||
 | 
					            $where[] = ['ol.worksite_id', '=', $worksiteId];
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!empty($begin)) {
 | 
				
			||||||
 | 
					            $where[] = ['ol.created_at', '>', $begin.' 00:00:00'];
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!empty($end)) {
 | 
				
			||||||
 | 
					            $where[] = ['ol.created_at', '<', $end.' 23:59:59'];
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $where[] = ['ol.account_id', '=', $accountId];
 | 
				
			||||||
 | 
					        $query   = \app\model\OvertimeLog::alias('ol')
 | 
				
			||||||
 | 
					            ->leftJoin('worksite w', 'w.id = ol.worksite_id')
 | 
				
			||||||
 | 
					            ->field('ol.*,w.name as worksite_name')
 | 
				
			||||||
 | 
					            ->where($where);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $total = $query->count();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $res = [
 | 
				
			||||||
 | 
					            'total'   => $total,
 | 
				
			||||||
 | 
					            'current' => $page ?: 1,
 | 
				
			||||||
 | 
					            'size'    => $size ?: 20,
 | 
				
			||||||
 | 
					            'list'    => new Collection(),
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($total > 0) {
 | 
				
			||||||
 | 
					            $res['list'] = $query->page($page, $size)->order('ol.id', 'desc')->select();
 | 
				
			||||||
 | 
					            $res['list']->each(function ($item) {
 | 
				
			||||||
 | 
					                switch ($item->status) {
 | 
				
			||||||
 | 
					                    case 0:
 | 
				
			||||||
 | 
					                        $item->status_text = '待确认';
 | 
				
			||||||
 | 
					                        break;
 | 
				
			||||||
 | 
					                    case 1:
 | 
				
			||||||
 | 
					                        $item->status_text = '已确认';
 | 
				
			||||||
 | 
					                        break;
 | 
				
			||||||
 | 
					                    case -1:
 | 
				
			||||||
 | 
					                        $item->status_text = '不通过';
 | 
				
			||||||
 | 
					                        break;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                $item->create_time = date('Y年m月d日 H:i:s', $item->create_time);
 | 
				
			||||||
 | 
					                $item->worktime    = date('Y年m月d日', strtotime($item->day));
 | 
				
			||||||
 | 
					                unset($item->check_at);
 | 
				
			||||||
 | 
					                unset($item->check_by);
 | 
				
			||||||
 | 
					                unset($item->created_at);
 | 
				
			||||||
 | 
					                unset($item->worksite_id);
 | 
				
			||||||
 | 
					                unset($item->is_statistic);
 | 
				
			||||||
 | 
					                unset($item->day);
 | 
				
			||||||
 | 
					                unset($item->day_text);
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->json(0, 'success', $res);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // 加班申请被打回后再次编辑
 | 
				
			||||||
 | 
					    public function overtimeEdit(): Json
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $id    = input('id');
 | 
				
			||||||
 | 
					        $input = input('post.');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $rules = [
 | 
				
			||||||
 | 
					            'worksite_id|工地' => 'require|number',
 | 
				
			||||||
 | 
					            'day|加班日期'       => 'require|date',
 | 
				
			||||||
 | 
					            'time|加班时长'      => 'require|float',
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $validate = $this->validateByApi($input, $rules);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($validate !== true) {
 | 
				
			||||||
 | 
					            return $validate;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $accountId = $this->request->user['user_id'] ?? 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!$item = OvertimeLog::where('id', $id)->find()) {
 | 
				
			||||||
 | 
					            return $this->json(4004, '记录不存在');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($item['account_id'] != $accountId) {
 | 
				
			||||||
 | 
					            return $this->json(4003, '不是你提交的加班申请');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($item['status'] != OvertimeLog::STATUS_NO) {
 | 
				
			||||||
 | 
					            return $this->json(4003, '当前状态不能编辑');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $item->save([
 | 
				
			||||||
 | 
					            'day'         => date('Ymd', strtotime($input['day'])),
 | 
				
			||||||
 | 
					            'worksite_id' => $input['worksite_id'],
 | 
				
			||||||
 | 
					            'time'        => $input['time'],
 | 
				
			||||||
 | 
					            'remarks'     => $input['remarks'] ?? '',
 | 
				
			||||||
 | 
					            'status'      => OvertimeLog::COMMON_OFF,
 | 
				
			||||||
 | 
					        ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->json(0, 'success');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // 加班申请被打回后删除
 | 
				
			||||||
 | 
					    public function overtimeDel(): Json
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $id = input('id');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $accountId = $this->request->user['user_id'] ?? 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!$item = OvertimeLog::where('id', $id)->find()) {
 | 
				
			||||||
 | 
					            return $this->json(4004, '记录不存在');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($item['account_id'] != $accountId) {
 | 
				
			||||||
 | 
					            return $this->json(4003, '不是你提交的加班申请');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($item['status'] != OvertimeLog::STATUS_NO) {
 | 
				
			||||||
 | 
					            return $this->json(4003, '当前状态不能删除');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $item->delete();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->json(0, 'success');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // 我的工资记录
 | 
				
			||||||
 | 
					    public function payListMock(): Json
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $page = input('page/d', 1);
 | 
				
			||||||
 | 
					        $size = input('size/d', 20);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $accountId = $this->request->user['user_id'] ?? 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $where = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!empty($keyword)) {
 | 
				
			||||||
 | 
					            $where[] = ['w.name', 'like', '%'.$keyword.'%'];
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $where[] = ['cl.account_id', '=', $accountId];
 | 
				
			||||||
 | 
					        //        $query   = \app\model\ClockLog::alias('cl')
 | 
				
			||||||
 | 
					        //            ->leftJoin('worksite w', 'w.id = cl.worksite_id')
 | 
				
			||||||
 | 
					        //            ->field('cl.*,w.name as worksite_name')
 | 
				
			||||||
 | 
					        //            ->where($where);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //        $total = $query->count();
 | 
				
			||||||
 | 
					        $total = 10;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $res = [
 | 
				
			||||||
 | 
					            'total'   => $total,
 | 
				
			||||||
 | 
					            'current' => $page ?: 1,
 | 
				
			||||||
 | 
					            'size'    => $size ?: 20,
 | 
				
			||||||
 | 
					            'list'    => new Collection(),
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($total > 0) {
 | 
				
			||||||
 | 
					            $res['list'] = [
 | 
				
			||||||
 | 
					                [
 | 
				
			||||||
 | 
					                    'status'          => 0,
 | 
				
			||||||
 | 
					                    'status_text'     => '待发放',
 | 
				
			||||||
 | 
					                    'date'            => '2022年11月',
 | 
				
			||||||
 | 
					                    'base_amount'     => 7500,
 | 
				
			||||||
 | 
					                    'overtime_amount' => 500,
 | 
				
			||||||
 | 
					                    'amount'          => 8000,
 | 
				
			||||||
 | 
					                ],
 | 
				
			||||||
 | 
					                [
 | 
				
			||||||
 | 
					                    'status'          => 1,
 | 
				
			||||||
 | 
					                    'status_text'     => '已发放',
 | 
				
			||||||
 | 
					                    'date'            => '2022年10月',
 | 
				
			||||||
 | 
					                    'base_amount'     => 7500,
 | 
				
			||||||
 | 
					                    'overtime_amount' => 500,
 | 
				
			||||||
 | 
					                    'amount'          => 8000,
 | 
				
			||||||
 | 
					                ],
 | 
				
			||||||
 | 
					                [
 | 
				
			||||||
 | 
					                    'status'          => 0,
 | 
				
			||||||
 | 
					                    'status_text'     => '已发放',
 | 
				
			||||||
 | 
					                    'date'            => '2022年09月',
 | 
				
			||||||
 | 
					                    'base_amount'     => 7500,
 | 
				
			||||||
 | 
					                    'overtime_amount' => 500,
 | 
				
			||||||
 | 
					                    'amount'          => 8000,
 | 
				
			||||||
 | 
					                ],
 | 
				
			||||||
 | 
					                [
 | 
				
			||||||
 | 
					                    'status'          => 0,
 | 
				
			||||||
 | 
					                    'status_text'     => '已发放',
 | 
				
			||||||
 | 
					                    'date'            => '2022年08月',
 | 
				
			||||||
 | 
					                    'base_amount'     => 7500,
 | 
				
			||||||
 | 
					                    'overtime_amount' => 0,
 | 
				
			||||||
 | 
					                    'amount'          => 7500,
 | 
				
			||||||
 | 
					                ],
 | 
				
			||||||
 | 
					                [
 | 
				
			||||||
 | 
					                    'status'          => 0,
 | 
				
			||||||
 | 
					                    'status_text'     => '已发放',
 | 
				
			||||||
 | 
					                    'date'            => '2022年08月',
 | 
				
			||||||
 | 
					                    'base_amount'     => 7500,
 | 
				
			||||||
 | 
					                    'overtime_amount' => 0,
 | 
				
			||||||
 | 
					                    'amount'          => 7500,
 | 
				
			||||||
 | 
					                ],
 | 
				
			||||||
 | 
					                [
 | 
				
			||||||
 | 
					                    'status'          => 0,
 | 
				
			||||||
 | 
					                    'status_text'     => '已发放',
 | 
				
			||||||
 | 
					                    'date'            => '2022年07月',
 | 
				
			||||||
 | 
					                    'base_amount'     => 7500,
 | 
				
			||||||
 | 
					                    'overtime_amount' => 0,
 | 
				
			||||||
 | 
					                    'amount'          => 7500,
 | 
				
			||||||
 | 
					                ],
 | 
				
			||||||
 | 
					                [
 | 
				
			||||||
 | 
					                    'status'          => 0,
 | 
				
			||||||
 | 
					                    'status_text'     => '已发放',
 | 
				
			||||||
 | 
					                    'date'            => '2022年06月',
 | 
				
			||||||
 | 
					                    'base_amount'     => 7500,
 | 
				
			||||||
 | 
					                    'overtime_amount' => 0,
 | 
				
			||||||
 | 
					                    'amount'          => 7500,
 | 
				
			||||||
 | 
					                ],
 | 
				
			||||||
 | 
					            ];
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->json(0, 'success', $res);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // 我的工资记录
 | 
				
			||||||
 | 
					    public function payList(): Json
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $page = input('page/d', 1);
 | 
				
			||||||
 | 
					        $size = input('size/d', 20);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $accountId = $this->request->user['user_id'] ?? 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $where = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $where[] = ['pml.account_id', '=', $accountId];
 | 
				
			||||||
 | 
					        $query   = \app\model\PayMonthLog::alias('pml')
 | 
				
			||||||
 | 
					            ->leftJoin('account a', 'a.id = pml.account_id')
 | 
				
			||||||
 | 
					            ->where($where)
 | 
				
			||||||
 | 
					            ->group('pml.time')
 | 
				
			||||||
 | 
					            ->fieldRaw('pml.time,pml.year,pml.month,sum(pml.amount) as amount,sum(pml.base_amount) as base_amount,sum(pml.overtime_amount) as overtime_amount');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $total = $query->count();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $res = [
 | 
				
			||||||
 | 
					            'total'   => $total,
 | 
				
			||||||
 | 
					            'current' => $page ?: 1,
 | 
				
			||||||
 | 
					            'size'    => $size ?: 20,
 | 
				
			||||||
 | 
					            'list'    => new Collection(),
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($total > 0) {
 | 
				
			||||||
 | 
					            // 获取按月已发工资
 | 
				
			||||||
 | 
					            $paidMonth = \app\model\PayMonthLog::alias('pml')
 | 
				
			||||||
 | 
					                ->leftJoin('account a', 'a.id = pml.account_id')
 | 
				
			||||||
 | 
					                ->where($where)
 | 
				
			||||||
 | 
					                ->where('pml.status', 1)
 | 
				
			||||||
 | 
					                ->group('pml.time')
 | 
				
			||||||
 | 
					                ->page($page, $size)
 | 
				
			||||||
 | 
					                ->order('time', 'desc')
 | 
				
			||||||
 | 
					                ->fieldRaw('sum(pml.amount) as amount,pml.time')
 | 
				
			||||||
 | 
					                ->select()->toArray();
 | 
				
			||||||
 | 
					            $monthPay  = [];
 | 
				
			||||||
 | 
					            foreach ($paidMonth as $p) {
 | 
				
			||||||
 | 
					                $monthPay[$p['time']] = $p['amount'];
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $res['list'] = $query->page($page, $size)->order('time', 'desc')->select();
 | 
				
			||||||
 | 
					            $res['list']->each(function ($item) use ($monthPay) {
 | 
				
			||||||
 | 
					                $item->date        = $item['year'].'年'.$item['month'].'月';
 | 
				
			||||||
 | 
					                $item->done        = $monthPay[$item->time] ?? 0;
 | 
				
			||||||
 | 
					                $item->status      = 0;
 | 
				
			||||||
 | 
					                $item->status_text = '待发放';
 | 
				
			||||||
 | 
					                if ($item->amount <= $item->done) {
 | 
				
			||||||
 | 
					                    $item->status      = 1;
 | 
				
			||||||
 | 
					                    $item->status_text = '已发放';
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                unset($item->year);
 | 
				
			||||||
 | 
					                unset($item->month);
 | 
				
			||||||
 | 
					                unset($item->think_count);
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->json(0, 'success', $res);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // 获取审核记录
 | 
				
			||||||
 | 
					    public function checkDetail(): Json
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $id = input('id');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!$item = CheckLog::where('id', $id)->find()) {
 | 
				
			||||||
 | 
					            return $this->json(4004, '记录不存在');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        $item = arrayNullToString($item->toArray());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->json(0, 'success', $item);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,167 @@
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace app\controller\api\v1\file;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use app\controller\api\Base;
 | 
				
			||||||
 | 
					use app\model\File;
 | 
				
			||||||
 | 
					use app\model\System;
 | 
				
			||||||
 | 
					use app\service\Image;
 | 
				
			||||||
 | 
					use app\validate\Upload as VUpload;
 | 
				
			||||||
 | 
					use think\facade\Config;
 | 
				
			||||||
 | 
					use think\facade\Filesystem;
 | 
				
			||||||
 | 
					use think\facade\Lang;
 | 
				
			||||||
 | 
					use think\response\Json;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * 文件上传
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Class Upload
 | 
				
			||||||
 | 
					 * @package app\controller\api\file
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					class Upload extends Base
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    protected $noNeedLogin = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // 图片上传是否进行压缩[max-width:1920px]
 | 
				
			||||||
 | 
					    private bool $isCompress = true;
 | 
				
			||||||
 | 
					    private $validate = null;
 | 
				
			||||||
 | 
					    // 文件上传对外默认保存目录(相对路径)
 | 
				
			||||||
 | 
					    private string $uploadPath = '';
 | 
				
			||||||
 | 
					    private $videoUploadPath;
 | 
				
			||||||
 | 
					    // 文件上传对外默认保存目录是否有写权限
 | 
				
			||||||
 | 
					    private bool $uploadPathIsWritable = false;
 | 
				
			||||||
 | 
					    private $videoUploadPathIsWritable = 0;
 | 
				
			||||||
 | 
					    protected bool $saveToOos = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function initialize()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        parent::initialize();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $system = System::getSystem();
 | 
				
			||||||
 | 
					        if (!empty($system)) {
 | 
				
			||||||
 | 
					            $this->isCompress = $system['compress'] ?? true;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        $this->validate        = new VUpload();
 | 
				
			||||||
 | 
					        $this->uploadPath      = Config::get('filesystem.disks.local.url');
 | 
				
			||||||
 | 
					        $this->videoUploadPath = Config::get('filesystem.disks.video.url');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!is_writable(app()->getRootPath().'public'.$this->uploadPath)) {
 | 
				
			||||||
 | 
					            mkdir(app()->getRootPath().'public'.$this->uploadPath, 0777, true);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        $this->uploadPathIsWritable = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!is_writable(app()->getRootPath().'public'.$this->videoUploadPath)) {
 | 
				
			||||||
 | 
					            mkdir(app()->getRootPath().'public'.$this->videoUploadPath, 0777, true);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->videoUploadPathIsWritable = 1;
 | 
				
			||||||
 | 
					        $this->cancelTimeLimit();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 通用文件上传
 | 
				
			||||||
 | 
					     * @return Json
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function file()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $file = request()->file('file');
 | 
				
			||||||
 | 
					        if (empty($file)) {
 | 
				
			||||||
 | 
					            return $this->json(4001, '请上传的文件');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($this->validate->checkFile($file)) {
 | 
				
			||||||
 | 
					            try {
 | 
				
			||||||
 | 
					                if (!$this->uploadPathIsWritable) {
 | 
				
			||||||
 | 
					                    throw new \Exception('上传文件夹需要写入权限');
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                $src            = Filesystem::putFile('files/'.date('Ym'), $file, 'uniqid');
 | 
				
			||||||
 | 
					                $src            = $this->uploadPath.'/'.$src;
 | 
				
			||||||
 | 
					                $return['src']  = $src;
 | 
				
			||||||
 | 
					                $return['name'] = $file->getOriginalName();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                //加入上传文件表
 | 
				
			||||||
 | 
					                File::add($file, $src, $file->md5());
 | 
				
			||||||
 | 
					            } catch (\Exception $e) {
 | 
				
			||||||
 | 
					                return $this->json(4003, $e->getMessage());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return $this->json(0, 'success', $return);
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $errorMsg = Lang::get($this->validate->getError());
 | 
				
			||||||
 | 
					            return $this->json(4002, $errorMsg);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 通用图片上传
 | 
				
			||||||
 | 
					     * @return Json
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function image()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $image = request()->file('image');
 | 
				
			||||||
 | 
					        if (empty($image)) {
 | 
				
			||||||
 | 
					            return $this->json(4001, '请上传图片文件');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        $md5 = $image->md5();//文件md5
 | 
				
			||||||
 | 
					        if ($this->validate->checkImage($image)) {
 | 
				
			||||||
 | 
					            try {
 | 
				
			||||||
 | 
					                if (!$this->uploadPathIsWritable) {
 | 
				
			||||||
 | 
					                    throw new \Exception('上传文件夹需要写入权限');
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                $src                = Filesystem::putFile('images/'.date('Ym'), $image, 'uniqid');
 | 
				
			||||||
 | 
					                $src                = $this->uploadPath.'/'.$src;
 | 
				
			||||||
 | 
					                $return['src']      = $src;
 | 
				
			||||||
 | 
					                $return['full_src'] = resourceJoin($src);
 | 
				
			||||||
 | 
					                if ($this->isCompress) {
 | 
				
			||||||
 | 
					                    Image::resize($src);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                //加入上传文件表
 | 
				
			||||||
 | 
					                File::add($image, $src, $md5);
 | 
				
			||||||
 | 
					            } catch (\Exception $e) {
 | 
				
			||||||
 | 
					                return $this->json(4003, $e->getMessage());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return $this->json(0, 'success', $return);
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $errorMsg = Lang::get($this->validate->getError());
 | 
				
			||||||
 | 
					            return $this->json(4002, $errorMsg);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 通用视频上传
 | 
				
			||||||
 | 
					     * @return Json
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function video()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            $file = request()->file('video');
 | 
				
			||||||
 | 
					            $md5  = $file->md5();//文件md5
 | 
				
			||||||
 | 
					            if ($this->validate->checkVideo($file)) {
 | 
				
			||||||
 | 
					                if (!$this->videoUploadPathIsWritable) {
 | 
				
			||||||
 | 
					                    throw new \Exception('上传文件夹需要写入权限');
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                $src                = Filesystem::putFile('videos/'.date('Ym'), $file, 'uniqid');
 | 
				
			||||||
 | 
					                $src                = $this->uploadPath.'/'.$src;
 | 
				
			||||||
 | 
					                $return['src']      = $src;
 | 
				
			||||||
 | 
					                $return['full_src'] = resourceJoin($src);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                //加入上传文件表
 | 
				
			||||||
 | 
					                File::add($file, $src, $md5, 'video');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                return $this->json(0, 'success', $return);
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                $errorMsg = Lang::get($this->validate->getError());
 | 
				
			||||||
 | 
					                return $this->json(4002, $errorMsg);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        } catch (\Exception $e) {
 | 
				
			||||||
 | 
					            return $this->json(4000, $e->getMessage());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,507 @@
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace app\controller\manager;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use app\model\Log;
 | 
				
			||||||
 | 
					use app\service\AliOss;
 | 
				
			||||||
 | 
					use think\facade\Config;
 | 
				
			||||||
 | 
					use Exception;
 | 
				
			||||||
 | 
					use app\model\Attachment as AttachmentModel;
 | 
				
			||||||
 | 
					use think\db\exception\DataNotFoundException;
 | 
				
			||||||
 | 
					use think\db\exception\DbException;
 | 
				
			||||||
 | 
					use think\db\exception\ModelNotFoundException;
 | 
				
			||||||
 | 
					use think\exception\ValidateException;
 | 
				
			||||||
 | 
					use think\response\Json;
 | 
				
			||||||
 | 
					use think\response\View;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * 附件管理 - 素材管理
 | 
				
			||||||
 | 
					 * Class Attachment
 | 
				
			||||||
 | 
					 * @package app\controller\manager
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					class Attachment extends Base
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    protected $noNeedLogin = ['file', 'getSize', 'md5List', 'pathDirHandle', 'toOss', 'delLostFile', 'test'];
 | 
				
			||||||
 | 
					    protected $DIRECTORY_SEPARATOR = "/";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    protected function initialize()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        parent::initialize(); // TODO: Change the autogenerated stub
 | 
				
			||||||
 | 
					        $this->DIRECTORY_SEPARATOR = DIRECTORY_SEPARATOR == "\\" ? "/" : DIRECTORY_SEPARATOR;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 删除
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return Json
 | 
				
			||||||
 | 
					     * @throws DataNotFoundException
 | 
				
			||||||
 | 
					     * @throws DbException
 | 
				
			||||||
 | 
					     * @throws ModelNotFoundException
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function del(): Json
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if ($this->request->isPost()) {
 | 
				
			||||||
 | 
					            $ids = input('post.ids/a', []);
 | 
				
			||||||
 | 
					            if (empty($ids)) {
 | 
				
			||||||
 | 
					                $ids[] = input('post.id/d');
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $items = AttachmentModel::whereIn('id', $ids)->where('is_dir', AttachmentModel::COMMON_ON)->select();
 | 
				
			||||||
 | 
					            if ($items->where('is_dir', AttachmentModel::COMMON_ON)->count()) {
 | 
				
			||||||
 | 
					                $dirPaths = [];
 | 
				
			||||||
 | 
					                foreach ($items->toArray() as $item) {
 | 
				
			||||||
 | 
					                    $dirPaths[] = $item['path'].$item['name'].$this->DIRECTORY_SEPARATOR;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                if (AttachmentModel::where('path', 'in', $dirPaths)->count()) {
 | 
				
			||||||
 | 
					                    return $this->json(4001, '待删除目录下存在内容!');
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            AttachmentModel::deleteByIds($ids);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            //            Log::write(get_class().'Del', 'del', '涉及到的ID为:'.implode(',', $ids));
 | 
				
			||||||
 | 
					            return $this->json();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return $this->json(4001, '非法请求!');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 单个字段编辑
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return Json
 | 
				
			||||||
 | 
					     * @throws Exception
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function modify(): Json
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if ($this->request->isPost()) {
 | 
				
			||||||
 | 
					            $item     = input('post.');
 | 
				
			||||||
 | 
					            $validate = $this->validateByApi($item, [
 | 
				
			||||||
 | 
					                'field' => 'require',
 | 
				
			||||||
 | 
					                'value' => 'require',
 | 
				
			||||||
 | 
					            ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if ($validate !== true) {
 | 
				
			||||||
 | 
					                return $validate;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (!$info = AttachmentModel::findById($item['id'])) {
 | 
				
			||||||
 | 
					                return $this->json(4001, '记录不存在');
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if ($item['field'] == 'name' && $info['is_dir'] == AttachmentModel::COMMON_ON) {
 | 
				
			||||||
 | 
					                return $this->json(4002, '目录名称不能修改');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $update = [$item['field'] => $item['value']];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            try {
 | 
				
			||||||
 | 
					                $info->save($update);
 | 
				
			||||||
 | 
					                return $this->json();
 | 
				
			||||||
 | 
					            } catch (ValidateException $e) {
 | 
				
			||||||
 | 
					                return $this->json(4001, $e->getError());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return $this->json(4000, '非法请求');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 添加
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return Json|View
 | 
				
			||||||
 | 
					     * @throws Exception
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function add()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if ($this->request->isPost()) {
 | 
				
			||||||
 | 
					            $item = input('post.');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $validate = $this->validateByApi($item, [
 | 
				
			||||||
 | 
					                'title|合集标题'     => 'require',
 | 
				
			||||||
 | 
					                'user|虚拟用户'      => 'require',
 | 
				
			||||||
 | 
					                'headimg|虚拟用户头像' => 'require',
 | 
				
			||||||
 | 
					            ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if ($validate !== true) {
 | 
				
			||||||
 | 
					                return $validate;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            try {
 | 
				
			||||||
 | 
					                $now                = date('Y-m-d H:i:s');
 | 
				
			||||||
 | 
					                $item['created_at'] = $now;
 | 
				
			||||||
 | 
					                $item['created_by'] = $this->auth['user_id'];
 | 
				
			||||||
 | 
					                AttachmentModel::create($item);
 | 
				
			||||||
 | 
					                return $this->json();
 | 
				
			||||||
 | 
					            } catch (ValidateException $e) {
 | 
				
			||||||
 | 
					                return $this->json(4001, $e->getError());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->view();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 添加文件夹
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return Json|View
 | 
				
			||||||
 | 
					     * @throws Exception
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function addFolder()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if ($this->request->isPost()) {
 | 
				
			||||||
 | 
					            $item = input('post.');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $validate = $this->validateByApi($item, [
 | 
				
			||||||
 | 
					                'name|文件夹名称' => 'require|alphaDash|max:20',
 | 
				
			||||||
 | 
					                'path|文件路径'  => 'require',
 | 
				
			||||||
 | 
					            ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // 例 name=dir4 path=/storage/dir1/dir2/dir3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // 去首尾/
 | 
				
			||||||
 | 
					            $path = trim($item['path'], $this->DIRECTORY_SEPARATOR);
 | 
				
			||||||
 | 
					            // 全路径 如 /storage/dir1/dir2/dir3/dir4/  注意前后都有/
 | 
				
			||||||
 | 
					            $fullPath = $this->DIRECTORY_SEPARATOR.$path.$this->DIRECTORY_SEPARATOR.$item['name'].$this->DIRECTORY_SEPARATOR;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if ($validate !== true) {
 | 
				
			||||||
 | 
					                return $validate;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            AttachmentModel::pathDirHandle($fullPath);
 | 
				
			||||||
 | 
					            return $this->json();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $path = input('path/s', AttachmentModel::ROOT_PATH);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->data['path'] = $path;
 | 
				
			||||||
 | 
					        return $this->view();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 图片列表
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return View|Json
 | 
				
			||||||
 | 
					     * @throws Exception
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function image()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $path     = input('post.path', AttachmentModel::ROOT_PATH);
 | 
				
			||||||
 | 
					        $path     = $this->DIRECTORY_SEPARATOR.trim($path, $this->DIRECTORY_SEPARATOR).$this->DIRECTORY_SEPARATOR;
 | 
				
			||||||
 | 
					        $path     = str_replace("\\", "/", $path);
 | 
				
			||||||
 | 
					        $type     = input('type/s', 'image');
 | 
				
			||||||
 | 
					        $selected = input('selected', false);
 | 
				
			||||||
 | 
					        $multiple = input('multiple', false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Config::load('extra/base', 'base');
 | 
				
			||||||
 | 
					        $baseConfig = config('base');
 | 
				
			||||||
 | 
					        $config     = $this->ossConfig();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $oss = $baseConfig['oss'] == 'true' ? ($config['customDomain'] ?? '') : '';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($this->request->isPost()) {
 | 
				
			||||||
 | 
					            $items = $this->list($path, ['image']);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return $this->json(0, '操作成功', $items);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->data['path']     = $path;
 | 
				
			||||||
 | 
					        $this->data['oss']      = $oss;
 | 
				
			||||||
 | 
					        $this->data['type']     = $type;
 | 
				
			||||||
 | 
					        $this->data['multiple'] = $multiple;
 | 
				
			||||||
 | 
					        $this->data['selected'] = $selected;
 | 
				
			||||||
 | 
					        return $this->view();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    protected function ossConfig(string $provider = 'qiniu')
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        Config::load('extra/'.$provider, $provider);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return config($provider);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 视频列表
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return View|Json
 | 
				
			||||||
 | 
					     * @throws Exception
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function video()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $path     = input('post.path', AttachmentModel::ROOT_PATH);
 | 
				
			||||||
 | 
					        $path     = $this->DIRECTORY_SEPARATOR.trim($path, $this->DIRECTORY_SEPARATOR).$this->DIRECTORY_SEPARATOR;
 | 
				
			||||||
 | 
					        $path     = str_replace("\\", "/", $path);
 | 
				
			||||||
 | 
					        $type     = input('type/s', 'video');
 | 
				
			||||||
 | 
					        $selected = input('selected', false);
 | 
				
			||||||
 | 
					        $multiple = input('multiple', false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Config::load('extra/base', 'base');
 | 
				
			||||||
 | 
					        $baseConfig = config('base');
 | 
				
			||||||
 | 
					        $config     = $this->ossConfig();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $oss = $baseConfig['oss'] == 'true' ? ($config['customDomain'] ?? '') : '';
 | 
				
			||||||
 | 
					        if ($this->request->isPost()) {
 | 
				
			||||||
 | 
					            $items = $this->list($path, ['video']);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return $this->json(0, '操作成功', $items);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->data['path']     = $path;
 | 
				
			||||||
 | 
					        $this->data['oss']      = $oss;
 | 
				
			||||||
 | 
					        $this->data['type']     = $type;
 | 
				
			||||||
 | 
					        $this->data['multiple'] = $multiple;
 | 
				
			||||||
 | 
					        $this->data['selected'] = $selected;
 | 
				
			||||||
 | 
					        return $this->view();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 文件列表
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return View|Json
 | 
				
			||||||
 | 
					     * @throws Exception
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function file()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $baseConfig = config('base');
 | 
				
			||||||
 | 
					        $config     = $this->ossConfig();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $oss      = $baseConfig['oss'] == 'true' ? ($config['customDomain'] ?? '') : '';
 | 
				
			||||||
 | 
					        $type     = input('type/s', 'all');
 | 
				
			||||||
 | 
					        $selected = input('selected', false);
 | 
				
			||||||
 | 
					        $multiple = input('multiple', false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($this->request->isPost()) {
 | 
				
			||||||
 | 
					            $page         = input('post.page', 1);
 | 
				
			||||||
 | 
					            $size         = input('post.size', 20);
 | 
				
			||||||
 | 
					            $searchParams = input('searchParams');
 | 
				
			||||||
 | 
					            $where        = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if ($searchParams) {
 | 
				
			||||||
 | 
					                foreach ($searchParams as $key => $param) {
 | 
				
			||||||
 | 
					                    if (!empty($param)) {
 | 
				
			||||||
 | 
					                        if (is_string($param)) {
 | 
				
			||||||
 | 
					                            if ($key == 'is_oss') {
 | 
				
			||||||
 | 
					                                if ($param >= 0) {
 | 
				
			||||||
 | 
					                                    $where[] = ['is_oss', '=', $param];
 | 
				
			||||||
 | 
					                                }
 | 
				
			||||||
 | 
					                            } else {
 | 
				
			||||||
 | 
					                                $where[] = [$key, 'like', '%'.$param.'%'];
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                        } elseif (is_array($param)) {
 | 
				
			||||||
 | 
					                            //数组空元素去除
 | 
				
			||||||
 | 
					                            foreach ($param as $k => $val) {
 | 
				
			||||||
 | 
					                                if (empty($val)) {
 | 
				
			||||||
 | 
					                                    unset($param[$k]);
 | 
				
			||||||
 | 
					                                }
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                            if (!empty($param)) {
 | 
				
			||||||
 | 
					                                $where[] = [$key, 'in', $param];
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if ($type !== 'all') {
 | 
				
			||||||
 | 
					                $where[] = ['type', '=', $type];
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $items = AttachmentModel::findList($where, [], $page, $size, function ($q) {
 | 
				
			||||||
 | 
					                return $q->where('type', '<>', 'dir')->order('updated_at', 'desc');
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $items['list']->each(function ($item) {
 | 
				
			||||||
 | 
					                $item->size_text = getFilesize($item['size'] ?? 0);
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return $this->json(0, '操作成功', $items);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->data['oss']      = $oss;
 | 
				
			||||||
 | 
					        $this->data['type']     = $type;
 | 
				
			||||||
 | 
					        $this->data['multiple'] = $multiple;
 | 
				
			||||||
 | 
					        $this->data['selected'] = $selected;
 | 
				
			||||||
 | 
					        return $this->view();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 一键删除失效记录 即oss不存在&&本地不存在
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return Json
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function delLostFile(): Json
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if ($this->request->isPost()) {
 | 
				
			||||||
 | 
					            $total = AttachmentModel::where('type', '<>', AttachmentModel::TYPE_DIR)
 | 
				
			||||||
 | 
					                ->where('is_dir', AttachmentModel::COMMON_OFF)
 | 
				
			||||||
 | 
					                ->where('is_oss', AttachmentModel::COMMON_OFF)
 | 
				
			||||||
 | 
					                ->where('has_local', AttachmentModel::COMMON_OFF)
 | 
				
			||||||
 | 
					                ->count();
 | 
				
			||||||
 | 
					            if ($total === 0) {
 | 
				
			||||||
 | 
					                return $this->json(0, 'success', ['total' => $total]);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (AttachmentModel::where('type', '<>', AttachmentModel::TYPE_DIR)
 | 
				
			||||||
 | 
					                ->where('is_dir', AttachmentModel::COMMON_OFF)
 | 
				
			||||||
 | 
					                ->where('is_oss', AttachmentModel::COMMON_OFF)
 | 
				
			||||||
 | 
					                ->where('has_local', AttachmentModel::COMMON_OFF)
 | 
				
			||||||
 | 
					                ->delete()) {
 | 
				
			||||||
 | 
					                return $this->json(0, 'success', ['total' => $total]);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            return $this->json(4004, '删除失败');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return $this->json(4000, '请求错误');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 一键上传本地文件到OSS
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return Json
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function toOss(): Json
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if ($this->request->isPost()) {
 | 
				
			||||||
 | 
					            Config::load('extra/alioss', 'alioss');
 | 
				
			||||||
 | 
					            Config::load('extra/base', 'base');
 | 
				
			||||||
 | 
					            $config     = config('alioss');
 | 
				
			||||||
 | 
					            $baseConfig = config('base');
 | 
				
			||||||
 | 
					            if ($baseConfig['oss'] != 'true') {
 | 
				
			||||||
 | 
					                return $this->json('4000', '配置未开启OSS上传');
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $ossObject = AliOss::instance();
 | 
				
			||||||
 | 
					            $bucket    = $config['bucket'];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $total = AttachmentModel::where('type', '<>', AttachmentModel::TYPE_DIR)
 | 
				
			||||||
 | 
					                ->where('is_dir', AttachmentModel::COMMON_OFF)
 | 
				
			||||||
 | 
					                ->where('is_oss', AttachmentModel::COMMON_OFF)
 | 
				
			||||||
 | 
					                ->field('id')
 | 
				
			||||||
 | 
					                ->count();
 | 
				
			||||||
 | 
					            $done  = 0;
 | 
				
			||||||
 | 
					            $none  = 0;
 | 
				
			||||||
 | 
					            if ($total === 0) {
 | 
				
			||||||
 | 
					                return $this->json(0, 'success', ['total' => $total, 'done' => $done, 'none' => $none]);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            try {
 | 
				
			||||||
 | 
					                AttachmentModel::where('type', '<>', AttachmentModel::TYPE_DIR)
 | 
				
			||||||
 | 
					                    ->where('is_dir', AttachmentModel::COMMON_OFF)
 | 
				
			||||||
 | 
					                    ->where('is_oss', AttachmentModel::COMMON_OFF)
 | 
				
			||||||
 | 
					                    ->field('id,src')
 | 
				
			||||||
 | 
					                    ->chunk(3, function ($items) use ($ossObject, $bucket, &$done, &$none) {
 | 
				
			||||||
 | 
					                        $doneIds = [];
 | 
				
			||||||
 | 
					                        $noneIds = [];
 | 
				
			||||||
 | 
					                        foreach ($items as $item) {
 | 
				
			||||||
 | 
					                            if ($item['src']) {
 | 
				
			||||||
 | 
					                                $realPath = public_path().ltrim($item['src'], $this->DIRECTORY_SEPARATOR);
 | 
				
			||||||
 | 
					                                if (!file_exists($realPath)) {
 | 
				
			||||||
 | 
					                                    $none++;
 | 
				
			||||||
 | 
					                                    $noneIds[] = $item['id'];
 | 
				
			||||||
 | 
					                                    continue;
 | 
				
			||||||
 | 
					                                }
 | 
				
			||||||
 | 
					                                $pathInfo = pathinfo($item['src']);
 | 
				
			||||||
 | 
					                                $object   = ltrim($item['src'], $this->DIRECTORY_SEPARATOR);
 | 
				
			||||||
 | 
					                                //是否存在
 | 
				
			||||||
 | 
					                                if (!$ossObject->doesObjectExist($bucket, $object)) {
 | 
				
			||||||
 | 
					                                    //创建目录
 | 
				
			||||||
 | 
					                                    $ossObject->createObjectDir($bucket, ltrim($pathInfo['dirname'], $this->DIRECTORY_SEPARATOR));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                                    $ossObject->uploadFile($bucket, $object, $realPath);
 | 
				
			||||||
 | 
					                                }
 | 
				
			||||||
 | 
					                                $doneIds[] = $item['id'];
 | 
				
			||||||
 | 
					                                $done++;
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        // 失效标记
 | 
				
			||||||
 | 
					                        if ($noneIds) {
 | 
				
			||||||
 | 
					                            $update = ['is_oss' => AttachmentModel::COMMON_OFF, 'has_local' => AttachmentModel::COMMON_OFF];
 | 
				
			||||||
 | 
					                            (new AttachmentModel())->where('id', 'in', $noneIds)->update($update);
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        // 完成标记
 | 
				
			||||||
 | 
					                        if ($doneIds) {
 | 
				
			||||||
 | 
					                            $update = ['is_oss' => AttachmentModel::COMMON_ON];
 | 
				
			||||||
 | 
					                            (new AttachmentModel())->where('id', 'in', $doneIds)->update($update);
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                return $this->json(0, 'success', ['total' => $total, 'done' => $done, 'none' => $none]);
 | 
				
			||||||
 | 
					            } catch (Exception $e) {
 | 
				
			||||||
 | 
					                \think\facade\Log::error('本地文件一键上传OSS失败 '.$e->getMessage());
 | 
				
			||||||
 | 
					                return $this->json(0, 'success', ['total' => $total, 'done' => $done, 'none' => $none]);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 指定类型附件列表
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param  array  $type
 | 
				
			||||||
 | 
					     * @param  string  $path
 | 
				
			||||||
 | 
					     * @return array
 | 
				
			||||||
 | 
					     * @throws Exception
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    protected function list(string $path, array $type): array
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $type[]  = 'dir';
 | 
				
			||||||
 | 
					        $where[] = ['path', '=', $path];
 | 
				
			||||||
 | 
					        $where[] = ['type', 'in', $type];
 | 
				
			||||||
 | 
					        $items   = AttachmentModel::findList($where, [], 1, 0, function ($q) {
 | 
				
			||||||
 | 
					            return $q->order('is_dir', 'desc')->order('updated_at', 'desc');
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					        $items['list']->each(function ($item) {
 | 
				
			||||||
 | 
					            $item->size_text = getFilesize($item['size'] ?? 0);
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					        $items['path'] = $path;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $items;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 获取文件大小
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return Json
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function getSize(): Json
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $path  = input('post.path', '');
 | 
				
			||||||
 | 
					        $types = input('post.type/a', []);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $size = '';
 | 
				
			||||||
 | 
					        if (empty($path)) {
 | 
				
			||||||
 | 
					            return $this->json(0, '操作成功', $size);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        $path  = str_replace("\\", "/", $path);
 | 
				
			||||||
 | 
					        $total = AttachmentModel::where('path', 'like', $path.'%')
 | 
				
			||||||
 | 
					            ->when(!empty($types), function ($q) use ($types) {
 | 
				
			||||||
 | 
					                $q->where('type', 'in', $types);
 | 
				
			||||||
 | 
					            })
 | 
				
			||||||
 | 
					            ->sum('size');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->json(0, '操作成功', getFilesize($total));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // 将没有md5的文件 更新md5  仅针对本地文件
 | 
				
			||||||
 | 
					    public function md5List()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $noMd5List = AttachmentModel::whereNull('md5')->select();
 | 
				
			||||||
 | 
					        $update    = [];
 | 
				
			||||||
 | 
					        foreach ($noMd5List as $item) {
 | 
				
			||||||
 | 
					            try {
 | 
				
			||||||
 | 
					                if (!empty($item['src'])) {
 | 
				
			||||||
 | 
					                    $arr        = [];
 | 
				
			||||||
 | 
					                    $path       = public_path().ltrim($item['src'], $this->DIRECTORY_SEPARATOR);
 | 
				
			||||||
 | 
					                    $file       = new \think\File($path);
 | 
				
			||||||
 | 
					                    $arr['md5'] = $file->md5();
 | 
				
			||||||
 | 
					                    $arr['id']  = $item['id'];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    $update[] = $arr;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            } catch (Exception $e) {
 | 
				
			||||||
 | 
					                continue;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        (new AttachmentModel())->saveAll($update);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,105 @@
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace app\controller\manager;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use app\controller\BaseController;
 | 
				
			||||||
 | 
					use app\service\File as FileTool;
 | 
				
			||||||
 | 
					use Exception;
 | 
				
			||||||
 | 
					use think\exception\ValidateException;
 | 
				
			||||||
 | 
					use think\response\Json;
 | 
				
			||||||
 | 
					use think\response\Redirect;
 | 
				
			||||||
 | 
					use think\response\View;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * 控制器基础类
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					class Base extends BaseController
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    protected $data = [];
 | 
				
			||||||
 | 
					    protected $auth = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    protected function initialize()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $this->middleware      = [
 | 
				
			||||||
 | 
					            'auth' => ['except' => array_merge($this->noNeedLogin, $this->noNeedRight)],
 | 
				
			||||||
 | 
					            'log'
 | 
				
			||||||
 | 
					            //            'jwt'  => ['except' => $this->noNeedRight],
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					        $this->auth            = session('auth');
 | 
				
			||||||
 | 
					        $this->data['member']  = $this->auth;
 | 
				
			||||||
 | 
					        $this->data['_token']  = $this->auth['token'] ?? '';
 | 
				
			||||||
 | 
					        $this->data['groupId'] = $this->auth['groupId'] ?? 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->fileDomain();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    //变量赋值到模板
 | 
				
			||||||
 | 
					    protected function view(string $template = '')
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return view($template)->assign($this->data);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @param  string  $msg
 | 
				
			||||||
 | 
					     * @param  string|null  $url
 | 
				
			||||||
 | 
					     * @param  string  $data
 | 
				
			||||||
 | 
					     * @param  int  $wait
 | 
				
			||||||
 | 
					     * @return Redirect
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    protected function error($msg = '', string $url = null, $data = '', int $wait = 3): Redirect
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (is_null($url)) {
 | 
				
			||||||
 | 
					            $url = $this->request->isAjax() ? '' : 'javascript:history.back(-1);';
 | 
				
			||||||
 | 
					        } elseif ($url) {
 | 
				
			||||||
 | 
					            $url = (strpos($url, '://') || 0 === strpos($url, '/')) ? $url : $this->app->route->buildUrl($url);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        $result = [
 | 
				
			||||||
 | 
					            'code' => 0,
 | 
				
			||||||
 | 
					            'msg'  => $msg,
 | 
				
			||||||
 | 
					            'data' => $data,
 | 
				
			||||||
 | 
					            'url'  => $url,
 | 
				
			||||||
 | 
					            'wait' => $wait,
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->redirect(url('/manager/error/jump', $result));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function __call($name, $args)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return $this->view('/manager/error/jump');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 验证器
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param  array  $data
 | 
				
			||||||
 | 
					     * @param $validate
 | 
				
			||||||
 | 
					     * @param  array  $message
 | 
				
			||||||
 | 
					     * @param  bool  $batch
 | 
				
			||||||
 | 
					     * @return Redirect
 | 
				
			||||||
 | 
					     * @throws Exception
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    protected function validateError(array $data, $validate, array $message = [], bool $batch = false): Redirect
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            parent::validate($data, $validate, $message, $batch);
 | 
				
			||||||
 | 
					        } catch (ValidateException $e) {
 | 
				
			||||||
 | 
					            $msg = $e->getMessage();
 | 
				
			||||||
 | 
					            if ($batch) {
 | 
				
			||||||
 | 
					                $msg = implode(',', $e->getError());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return $this->error($msg);
 | 
				
			||||||
 | 
					        } catch (Exception $e) {
 | 
				
			||||||
 | 
					            throw $e;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 文件域名前缀
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function fileDomain()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $this->data['fileDomain'] = FileTool::getFileDomain();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,224 @@
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					declare (strict_types=1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace app\controller\manager;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use app\model\ClockLog;
 | 
				
			||||||
 | 
					use Exception;
 | 
				
			||||||
 | 
					use app\model\Log;
 | 
				
			||||||
 | 
					use think\Collection;
 | 
				
			||||||
 | 
					use think\response\View;
 | 
				
			||||||
 | 
					use think\response\Json;
 | 
				
			||||||
 | 
					use think\db\exception\DbException;
 | 
				
			||||||
 | 
					use think\exception\ValidateException;
 | 
				
			||||||
 | 
					use think\db\exception\DataNotFoundException;
 | 
				
			||||||
 | 
					use think\db\exception\ModelNotFoundException;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Clock extends Base
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    protected $noNeedLogin = ['index', 'add', 'edit', 'del', 'modify'];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 列表
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @throws Exception
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function index()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $accountId = input('user_id/d', 0);
 | 
				
			||||||
 | 
					        if ($this->request->isPost()) {
 | 
				
			||||||
 | 
					            $params = input('searchParams/a');
 | 
				
			||||||
 | 
					            $page   = input('page/d', 1);
 | 
				
			||||||
 | 
					            $size   = input('size/d', 20);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $where = [];
 | 
				
			||||||
 | 
					            if (!empty($params)) {
 | 
				
			||||||
 | 
					                foreach ($params as $key => $param) {
 | 
				
			||||||
 | 
					                    $param = trim($param);
 | 
				
			||||||
 | 
					                    if ($key == 'keyword') {
 | 
				
			||||||
 | 
					                        $where[] = ['w.name|a.nickname|a.mobile|a.real_name|a2.nickname|a2.real_name', 'like', '%'.$param.'%'];
 | 
				
			||||||
 | 
					                        continue;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    if ($param == '0' || !empty($param)) {
 | 
				
			||||||
 | 
					                        $where[] = ['cl.'.$key, '=', $param];
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if ($accountId > 0) {
 | 
				
			||||||
 | 
					                $where[] = ['cl.account_id', '=', $accountId];
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $query = ClockLog::alias('cl')
 | 
				
			||||||
 | 
					                ->leftJoin('account a', 'a.id = cl.account_id')
 | 
				
			||||||
 | 
					                ->leftJoin('account a2', 'a2.id = cl.check_by')
 | 
				
			||||||
 | 
					                ->leftJoin('worksite w', 'w.id = cl.worksite_id')
 | 
				
			||||||
 | 
					                ->where($where);
 | 
				
			||||||
 | 
					            $total = $query->count();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $res = [
 | 
				
			||||||
 | 
					                'total'   => $total,
 | 
				
			||||||
 | 
					                'current' => $page ?: 1,
 | 
				
			||||||
 | 
					                'size'    => $size ?: 20,
 | 
				
			||||||
 | 
					                'list'    => [],
 | 
				
			||||||
 | 
					            ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if ($total > 0) {
 | 
				
			||||||
 | 
					                $typeText    = ClockLog::typeText();
 | 
				
			||||||
 | 
					                $statusText  = ClockLog::statusText();
 | 
				
			||||||
 | 
					                $res['list'] = $query->fieldRaw('cl.*,a.nickname,a.real_name,a.mobile,w.name as worksite_name,a2.nickname as check_nickname,a2.real_name as check_name')->page($page, $size)->order('cl.id', 'desc')->select();
 | 
				
			||||||
 | 
					                $res['list']->each(function ($item) use ($typeText, $statusText) {
 | 
				
			||||||
 | 
					                    $item->type_text    = $typeText[$item->type] ?? '其他';
 | 
				
			||||||
 | 
					                    $item->status_text  = $statusText[$item->status] ?? '其他';
 | 
				
			||||||
 | 
					                    $item->account_text = $item->nickname.'-'.$item->real_name.'-'.$item->mobile;//用户信息
 | 
				
			||||||
 | 
					                    $item->check_text   = $item->check_by ? $item->check_nickname.'-'.$item->check_name : '';//审核人信息
 | 
				
			||||||
 | 
					                });
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return $this->json(0, 'success', $res);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->data['userId'] = $accountId;
 | 
				
			||||||
 | 
					        $this->data['worksiteList'] = \app\model\Worksite::list();
 | 
				
			||||||
 | 
					        return $this->view();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 添加
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return Json|View
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function add()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if ($this->request->isPost()) {
 | 
				
			||||||
 | 
					            try {
 | 
				
			||||||
 | 
					                $input = input('post.');
 | 
				
			||||||
 | 
					                if (!isset($input['name'])) {
 | 
				
			||||||
 | 
					                    return $this->json(4000, '参数错误');
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                ClockLog::create([
 | 
				
			||||||
 | 
					                    'name' => $input['name'] ?? '',
 | 
				
			||||||
 | 
					                ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                return $this->json();
 | 
				
			||||||
 | 
					            } catch (Exception $e) {
 | 
				
			||||||
 | 
					                return $this->json(4001, '添加失败'.$e->getMessage());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->view();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 编辑
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return \think\response\Json|\think\response\View
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function edit()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $id = input('id');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //通过ID查询
 | 
				
			||||||
 | 
					        $item = ClockLog::where('id', (int) $id)->find();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (empty($item)) {
 | 
				
			||||||
 | 
					            return $this->json(4000, '没有相关记录!');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($this->request->isPost()) {
 | 
				
			||||||
 | 
					            try {
 | 
				
			||||||
 | 
					                $input = input('post.');
 | 
				
			||||||
 | 
					                if (!isset($input['name'])) {
 | 
				
			||||||
 | 
					                    return $this->json(4000, '参数错误');
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                $item->save([
 | 
				
			||||||
 | 
					                    'name' => $input['name'] ?? '',
 | 
				
			||||||
 | 
					                ]);
 | 
				
			||||||
 | 
					                return $this->json();
 | 
				
			||||||
 | 
					            } catch (Exception $e) {
 | 
				
			||||||
 | 
					                return $this->json(5000, $e->getMessage());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->data['item'] = $item;
 | 
				
			||||||
 | 
					        $this->data['id']   = $id;
 | 
				
			||||||
 | 
					        return $this->view();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 更新属性
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @throws ModelNotFoundException
 | 
				
			||||||
 | 
					     * @throws DbException
 | 
				
			||||||
 | 
					     * @throws DataNotFoundException
 | 
				
			||||||
 | 
					     * @throws Exception
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function modify()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (!$this->request->isPost()) {
 | 
				
			||||||
 | 
					            return $this->json(4000, '非法请求');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $item     = input('post.');
 | 
				
			||||||
 | 
					        $validate = $this->validateByApi($item, [
 | 
				
			||||||
 | 
					            'field' => 'require',
 | 
				
			||||||
 | 
					            'value' => 'require',
 | 
				
			||||||
 | 
					        ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($validate !== true) {
 | 
				
			||||||
 | 
					            return $validate;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // 通过ID查询
 | 
				
			||||||
 | 
					        if (!$info = ClockLog::where('id', (int) $item['id'])->find()) {
 | 
				
			||||||
 | 
					            return $this->json(4001, '记录不存在');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $update = [$item['field'] => $item['value']];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            $info->save($update);
 | 
				
			||||||
 | 
					            return $this->json();
 | 
				
			||||||
 | 
					        } catch (ValidateException $e) {
 | 
				
			||||||
 | 
					            return $this->json(4001, $e->getError());
 | 
				
			||||||
 | 
					        } catch (Exception $e) {
 | 
				
			||||||
 | 
					            return $this->json(5000, '修改失败');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 删除
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return \think\response\Json
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function del(): Json
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (!$this->request->isPost()) {
 | 
				
			||||||
 | 
					            return $this->json(4000, '非法请求');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $ids = $this->request->param('ids/a', []);
 | 
				
			||||||
 | 
					        if (empty($ids)) {
 | 
				
			||||||
 | 
					            $ids[] = $this->request->param('id/d', 0);
 | 
				
			||||||
 | 
					            $ids   = array_filter($ids);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            if (count($ids)) {
 | 
				
			||||||
 | 
					                //删除逻辑
 | 
				
			||||||
 | 
					                if (\app\model\Account::whereIn('ClockLog', $ids)->count() > 0) {
 | 
				
			||||||
 | 
					                    return $this->json(4000, '所选岗位已分配给用户,请先移除后再删除');
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                ClockLog::whereIn('id', $ids)->delete();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                Log::write(get_class(), 'del', '删除操作,涉及到的ID为:'.implode(',', $ids));
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        } catch (Exception $e) {
 | 
				
			||||||
 | 
					            return $this->json(5000, $e->getMessage());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->json();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,153 @@
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace app\controller\manager;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use Exception;
 | 
				
			||||||
 | 
					use think\facade\Config as CConfig;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * 额外配置
 | 
				
			||||||
 | 
					 * Class Config
 | 
				
			||||||
 | 
					 * @package app\controller\manager
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					class Config extends Base
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    private string $extraPath = '';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    protected function initialize()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        parent::initialize();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->extraPath = config_path() . 'extra/';
 | 
				
			||||||
 | 
					        if (!is_dir($this->extraPath)) {
 | 
				
			||||||
 | 
					            if (is_writable(config_path())) {
 | 
				
			||||||
 | 
					                mkdir($this->extraPath, 0777, true);
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                halt('请联系系统管理人员配置文件夹读写权限!请添加'.$this->extraPath.'文件夹的读写权限');
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        } elseif (!is_writable($this->extraPath)) {
 | 
				
			||||||
 | 
					            halt('请联系系统管理人员配置文件夹读写权限!请添加'.$this->extraPath.'文件夹的读写权限');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function other()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if ($this->request->isPost()) {
 | 
				
			||||||
 | 
					            $data = input("post.");
 | 
				
			||||||
 | 
					            unset($data['_token']);
 | 
				
			||||||
 | 
					            $php  = var_export($data, true);
 | 
				
			||||||
 | 
					            file_put_contents($this->extraPath . 'other.php', '<?php' . PHP_EOL . 'return ' . $php . ';');
 | 
				
			||||||
 | 
					            return $this->json();
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            CConfig::load('extra/other', 'other');
 | 
				
			||||||
 | 
					            $this->data['item'] = config('other');
 | 
				
			||||||
 | 
					            return $this->view();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function wechat()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if ($this->request->isPost()) {
 | 
				
			||||||
 | 
					            $data = input("post.");
 | 
				
			||||||
 | 
					            unset($data['_token']);
 | 
				
			||||||
 | 
					            $php  = var_export($data, true);
 | 
				
			||||||
 | 
					            file_put_contents($this->extraPath . 'wechat.php', '<?php' . PHP_EOL . 'return ' . $php . ';');
 | 
				
			||||||
 | 
					            return $this->json();
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            CConfig::load('extra/wechat', 'wechat');
 | 
				
			||||||
 | 
					            $this->data['item'] = config('wechat');
 | 
				
			||||||
 | 
					            return $this->view();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function alipay()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if ($this->request->isPost()) {
 | 
				
			||||||
 | 
					            $data = input("post.");
 | 
				
			||||||
 | 
					            unset($data['_token']);
 | 
				
			||||||
 | 
					            $php  = var_export($data, true);
 | 
				
			||||||
 | 
					            file_put_contents($this->extraPath . 'alipay.php', '<?php' . PHP_EOL . 'return ' . $php . ';');
 | 
				
			||||||
 | 
					            return $this->json();
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            CConfig::load('extra/alipay', 'alipay');
 | 
				
			||||||
 | 
					            $this->data['item'] = config('alipay');
 | 
				
			||||||
 | 
					            return $this->view();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 小程序配置
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function miniProgram()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if ($this->request->isPost()) {
 | 
				
			||||||
 | 
					            $data = input("post.");
 | 
				
			||||||
 | 
					            unset($data['_token']);
 | 
				
			||||||
 | 
					            unset($data['image']);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // 字符串与数组转换
 | 
				
			||||||
 | 
					            $data['poster'] = empty($data['poster'] ?? '') ? [] : explode(',', $data['poster']);
 | 
				
			||||||
 | 
					            $footBarList = array_values($data['footBar'] ?? []);
 | 
				
			||||||
 | 
					            foreach ($footBarList as &$item) {
 | 
				
			||||||
 | 
					                $icons = empty($item['icon']) ? [] : explode(',', $item['icon']);
 | 
				
			||||||
 | 
					                $item['icon'] = array_filter($icons);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            unset($item);
 | 
				
			||||||
 | 
					            $data['footBar'] = $footBarList;
 | 
				
			||||||
 | 
					            // 按sort排序
 | 
				
			||||||
 | 
					            $recommendList = $data['recommend'] ?? [];
 | 
				
			||||||
 | 
					            if (count($recommendList)) {
 | 
				
			||||||
 | 
					                $recommendKeys = array_column($recommendList, 'sort');
 | 
				
			||||||
 | 
					                array_multisort($recommendKeys, SORT_ASC, $recommendList);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            $data['recommend'] = array_values($recommendList);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $php = var_export($data, true);
 | 
				
			||||||
 | 
					            file_put_contents($this->extraPath . 'mini_program.php', '<?php' . PHP_EOL . 'return ' . $php . ';');
 | 
				
			||||||
 | 
					            return $this->json();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            CConfig::load('extra/mini_program', 'mini_program');
 | 
				
			||||||
 | 
					            $data = config('mini_program');
 | 
				
			||||||
 | 
					            if ($data) {
 | 
				
			||||||
 | 
					                $data['poster'] = implode(',', $data['poster'] ?? []);
 | 
				
			||||||
 | 
					                $footBarList = $data['footBar'] ?? [];
 | 
				
			||||||
 | 
					                foreach ($footBarList as &$item) {
 | 
				
			||||||
 | 
					                    $item['icon'] = implode(',', $item['icon'] ?? []);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                unset($item);
 | 
				
			||||||
 | 
					                $data['footBar'] = $footBarList;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            // 底部默认导航
 | 
				
			||||||
 | 
					            $data['footBarIcons'] = [
 | 
				
			||||||
 | 
					                ['key' => 'home', 'name' => '首页', 'aux' => '图标大小为 40 * 40; 第1图为默认图,第2图为高亮图', 'multi' => 1],
 | 
				
			||||||
 | 
					                ['key' => 'category', 'name' => '分类', 'aux' => '图标大小为 40 * 40; 第1图为默认图,第2图为高亮图', 'multi' => 1],
 | 
				
			||||||
 | 
					                ['key' => 'my', 'name' => '我的', 'aux' => '图标大小为 40 * 40; 第1图为默认图,第2图为高亮图', 'multi' => 1],
 | 
				
			||||||
 | 
					                ['key' => 'cart', 'name' => '购物车', 'aux' => '图标大小为 120 * 120', 'multi' => 0],
 | 
				
			||||||
 | 
					            ];
 | 
				
			||||||
 | 
					            $this->data = array_merge($this->data, $data);
 | 
				
			||||||
 | 
					            return $this->view();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function __call($name, $args)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if ($this->request->isPost()) {
 | 
				
			||||||
 | 
					            try {
 | 
				
			||||||
 | 
					                $data = input("post.");
 | 
				
			||||||
 | 
					                $php = var_export($data, true);
 | 
				
			||||||
 | 
					                file_put_contents(config_path().'extra/'.$name.'.php', '<?php'.PHP_EOL.'return '.$php.';');
 | 
				
			||||||
 | 
					                return $this->json();
 | 
				
			||||||
 | 
					            } catch (Exception $e) {
 | 
				
			||||||
 | 
					                return $this->json(4001, $e->getMessage());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            CConfig::load('extra/'.$name, $name);
 | 
				
			||||||
 | 
					            $this->data['item']   = config($name);
 | 
				
			||||||
 | 
					            $this->data['action'] = $name;
 | 
				
			||||||
 | 
					            return $this->view('manager/config/'.unCamelize($name, '_'));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,11 @@
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					namespace app\controller\manager;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Error
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public function jump()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $param = request()->param();
 | 
				
			||||||
 | 
					        return view()->assign($param);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,143 @@
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					namespace app\controller\manager;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use app\model\{File as MFile, Archives, Block, Category, Link, Slide, Log};
 | 
				
			||||||
 | 
					use app\service\Tool;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class File extends Base
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    protected $noNeedLogin = ['delPath', 'del', 'unuse', 'getAllFilesInUse', 'list', 'index'];
 | 
				
			||||||
 | 
					    //删除磁盘上的文件
 | 
				
			||||||
 | 
					    public function delPath()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if ($this->request->isPost()) {
 | 
				
			||||||
 | 
					            $paths = input('post.paths/a');
 | 
				
			||||||
 | 
					            if(!empty($paths)){
 | 
				
			||||||
 | 
					                foreach($paths as $path){
 | 
				
			||||||
 | 
					                    Tool::delFile($path);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                Log::write('file', 'delPath', '批量删除了磁盘文件,涉及到的文件路径为:' . implode(',', $paths));
 | 
				
			||||||
 | 
					                return $this->json();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            return $this->json(2, '待删除文件列表为空');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return $this->json(1, '非法请求!');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    //删除文件记录
 | 
				
			||||||
 | 
					    public function del()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if ($this->request->isPost()) {
 | 
				
			||||||
 | 
					            $ids = input('post.ids/a');
 | 
				
			||||||
 | 
					            if(empty($ids) || !is_array($ids)) {
 | 
				
			||||||
 | 
					                return $this->json(2, '参数错误,请核对之后再操作!');
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            $items = MFile::getListByIds($ids);
 | 
				
			||||||
 | 
					            if(!empty($items)){
 | 
				
			||||||
 | 
					                $delIds = [];
 | 
				
			||||||
 | 
					                foreach($items as $item){
 | 
				
			||||||
 | 
					                    $delIds[] = $item['id'];
 | 
				
			||||||
 | 
					                    if($item['type'] == MFile::IMG){
 | 
				
			||||||
 | 
					                        Tool::delFile($item['src'], 1);
 | 
				
			||||||
 | 
					                    }else{
 | 
				
			||||||
 | 
					                        Tool::delFile($item['src']);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                MFile::destroy($delIds);
 | 
				
			||||||
 | 
					                Log::write('file', 'del', '批量删除了文件,涉及到的文件ID为:' . implode(',', $delIds));
 | 
				
			||||||
 | 
					                return $this->json();
 | 
				
			||||||
 | 
					            }else{
 | 
				
			||||||
 | 
					                return $this->json(3, '待删除文件列表为空');
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return $this->json(1, '非法请求!');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 未使用文件列表,
 | 
				
			||||||
 | 
					     * 1. 遍历数据库中使用的图片视频及文件路径
 | 
				
			||||||
 | 
					     * 2. 遍历上传目录中的文件
 | 
				
			||||||
 | 
					     * 3. 数据对比,找出存在目录中的文件&不在数据库中的文件
 | 
				
			||||||
 | 
					     * 4. 页面上显示查找出来的文件
 | 
				
			||||||
 | 
					    */
 | 
				
			||||||
 | 
					    public function unuse()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $filesInUse = $this->getAllFilesInUse();    //数据库中在使用的文件
 | 
				
			||||||
 | 
					        $rootPath = app()->getRootPath();
 | 
				
			||||||
 | 
					        $uploadPath = $rootPath . 'storage';
 | 
				
			||||||
 | 
					        $uploadedFiles = getAllFilesByPath($uploadPath, $rootPath); //磁盘上上传的文件
 | 
				
			||||||
 | 
					        $files = MFile::getAll();
 | 
				
			||||||
 | 
					        $dbUploadedFiles = [];  //数据库中上传的文件
 | 
				
			||||||
 | 
					        foreach($files as $file){
 | 
				
			||||||
 | 
					            $src = trim($file['src']);
 | 
				
			||||||
 | 
					            if(!empty($src)){
 | 
				
			||||||
 | 
					                $key = getKeyByPath($src);
 | 
				
			||||||
 | 
					                $dbUploadedFiles[$key] = $file;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $uploadedNotInUseFiles = array_diff_key($uploadedFiles, $filesInUse);   //磁盘上上传未使用的文件
 | 
				
			||||||
 | 
					        $dbUploadedNotInUseFiles = array_diff_key($dbUploadedFiles, $filesInUse);    //数据库中上传未使用的文件
 | 
				
			||||||
 | 
					        $bothNotInUseFiles = array_intersect_key($uploadedNotInUseFiles, $dbUploadedNotInUseFiles);  //磁盘和数据库中,两边都未使用
 | 
				
			||||||
 | 
					        $this->data['uploadedNotInUseFiles'] = $uploadedNotInUseFiles;
 | 
				
			||||||
 | 
					        $this->data['dbUploadedNotInUseFiles'] = $dbUploadedNotInUseFiles;
 | 
				
			||||||
 | 
					        $this->data['bothNotInUseFilesKey'] = array_keys($bothNotInUseFiles);
 | 
				
			||||||
 | 
					        return $this->view();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    //获取所有在使用的文件
 | 
				
			||||||
 | 
					    private function getAllFilesInUse()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $files = [];
 | 
				
			||||||
 | 
					        $blockFiles = Block::getFilesInUse();
 | 
				
			||||||
 | 
					        if(!empty($blockFiles)){
 | 
				
			||||||
 | 
					            $files = array_merge($files, $blockFiles);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        $slideFiles = Slide::getFilesInUse();
 | 
				
			||||||
 | 
					        if(!empty($slideFiles)){
 | 
				
			||||||
 | 
					            $files = array_merge($files, $slideFiles);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        $linkFiles = Link::getFilesInUse();
 | 
				
			||||||
 | 
					        if(!empty($linkFiles)){
 | 
				
			||||||
 | 
					            $files = array_merge($files, $linkFiles);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        $categoryFiles = Category::getFilesInUse();
 | 
				
			||||||
 | 
					        if(!empty($categoryFiles)){
 | 
				
			||||||
 | 
					            $files = array_merge($files, $categoryFiles);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        $articleFiles = Archives::getFilesInUse();
 | 
				
			||||||
 | 
					        if(!empty($articleFiles)){
 | 
				
			||||||
 | 
					            $files = array_merge($files, $articleFiles);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return $files;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    //ajax获取文件列表
 | 
				
			||||||
 | 
					    public function list()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if($this->request->isAjax()){
 | 
				
			||||||
 | 
					            $page = input('param.page/d', 1);
 | 
				
			||||||
 | 
					            $size = input('param.size/d', 20);
 | 
				
			||||||
 | 
					            if(!is_integer($page) || $page < 1){
 | 
				
			||||||
 | 
					                $page = 1;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            if (!is_integer($size) || $size < 1) {
 | 
				
			||||||
 | 
					                $size = 20;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            $type = input('param.type', '');
 | 
				
			||||||
 | 
					            if(!in_array($type, array_keys(MFile::getTypes()))){
 | 
				
			||||||
 | 
					                $type = '';
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            $items = MFile::getList($type, $page, $size);
 | 
				
			||||||
 | 
					            return $this->json(0, 'ok', $items);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return $this->json(1, '无此操作');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    //列表
 | 
				
			||||||
 | 
					    public function index()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $items = MFile::getListPage();
 | 
				
			||||||
 | 
					        $this->data['items'] = $items;
 | 
				
			||||||
 | 
					        $this->data['types'] = MFile::getTypes();
 | 
				
			||||||
 | 
					        return $this->view();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,272 @@
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					declare (strict_types=1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace app\controller\manager;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use app\model\Account;
 | 
				
			||||||
 | 
					use app\model\GoodsArea;
 | 
				
			||||||
 | 
					use app\model\GoodsCategory;
 | 
				
			||||||
 | 
					use Exception;
 | 
				
			||||||
 | 
					use app\model\Log;
 | 
				
			||||||
 | 
					use think\Collection;
 | 
				
			||||||
 | 
					use think\response\View;
 | 
				
			||||||
 | 
					use think\response\Json;
 | 
				
			||||||
 | 
					use think\db\exception\DbException;
 | 
				
			||||||
 | 
					use think\exception\ValidateException;
 | 
				
			||||||
 | 
					use think\db\exception\DataNotFoundException;
 | 
				
			||||||
 | 
					use think\db\exception\ModelNotFoundException;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Goods extends Base
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    protected $noNeedLogin = ['searchAccount'];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 列表
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @throws Exception
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function index()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if ($this->request->isPost()) {
 | 
				
			||||||
 | 
					            $params = input('searchParams/a');
 | 
				
			||||||
 | 
					            $page   = input('page/d', 1);
 | 
				
			||||||
 | 
					            $size   = input('size/d', 20);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $where = [];
 | 
				
			||||||
 | 
					            if (!empty($params)) {
 | 
				
			||||||
 | 
					                foreach ($params as $key => $param) {
 | 
				
			||||||
 | 
					                    $param = trim($param);
 | 
				
			||||||
 | 
					                    if ($key == 'keyword') {
 | 
				
			||||||
 | 
					                        $where[] = ['a.nickname|g.title|gc.title|g.phone|ga.title', 'like', '%'.$param.'%'];
 | 
				
			||||||
 | 
					                        continue;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    if ($param == '0' || !empty($param)) {
 | 
				
			||||||
 | 
					                        $where[] = ['g.'.$key, 'like', '%'.$param.'%'];
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $query = \app\model\Goods::alias('g')
 | 
				
			||||||
 | 
					                ->leftJoin('goods_category gc', 'gc.id = g.category_id')
 | 
				
			||||||
 | 
					                ->leftJoin('account a', 'a.id = g.account_id')
 | 
				
			||||||
 | 
					                ->leftJoin('goods_area ga', 'ga.id = g.area_id')
 | 
				
			||||||
 | 
					                ->field('g.*,gc.title as category_title,a.nickname,ga.title as area_name')
 | 
				
			||||||
 | 
					                ->where($where);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $total = $query->count();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $res = [
 | 
				
			||||||
 | 
					                'total'   => $total,
 | 
				
			||||||
 | 
					                'current' => $page ?: 1,
 | 
				
			||||||
 | 
					                'size'    => $size ?: 20,
 | 
				
			||||||
 | 
					                'list'    => new Collection(),
 | 
				
			||||||
 | 
					            ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if ($total > 0) {
 | 
				
			||||||
 | 
					                $res['list'] = $query->page($page, $size)->order('g.sort', 'desc')->order('g.id', 'desc')->select();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return $this->json(0, 'success', $res);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->view();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 添加
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return Json|View
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function add()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if ($this->request->isPost()) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            try {
 | 
				
			||||||
 | 
					                $input = input('post.');
 | 
				
			||||||
 | 
					                //                $images = input('img_images/a', []);
 | 
				
			||||||
 | 
					                \app\model\Goods::create([
 | 
				
			||||||
 | 
					                    'title'          => $input['title'],
 | 
				
			||||||
 | 
					                    'cover'          => $input['cover'],
 | 
				
			||||||
 | 
					                    'category_id'    => $input['category_id'],
 | 
				
			||||||
 | 
					                    'content'        => $input['content'] ?? '',
 | 
				
			||||||
 | 
					                    'phone'          => $input['phone'] ?? '',
 | 
				
			||||||
 | 
					                    'price'          => $input['price'] ?? 0,
 | 
				
			||||||
 | 
					                    'original_price' => $input['original_price'] ?? $input['price'],
 | 
				
			||||||
 | 
					                    'account_id'     => $input['account_id'] ?? 0,
 | 
				
			||||||
 | 
					                    'status'         => $input['status'] ?? 0,
 | 
				
			||||||
 | 
					                    'area_id'        => $input['area_id'] ?? 0,
 | 
				
			||||||
 | 
					                    'images'         => $input['images'] ?? '',
 | 
				
			||||||
 | 
					                ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                return $this->json();
 | 
				
			||||||
 | 
					            } catch (Exception $e) {
 | 
				
			||||||
 | 
					                return $this->json(4001, '添加失败'.$e->getMessage());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->data['cateList'] = GoodsCategory::order('sort', 'desc')
 | 
				
			||||||
 | 
					            ->order('id', 'desc')
 | 
				
			||||||
 | 
					            ->column('id,title');
 | 
				
			||||||
 | 
					        $this->data['areaList'] = GoodsArea::order('sort', 'desc')
 | 
				
			||||||
 | 
					            ->order('id', 'desc')
 | 
				
			||||||
 | 
					            ->column('id,title');
 | 
				
			||||||
 | 
					        return $this->view();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 编辑
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return \think\response\Json|\think\response\View
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function edit()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $id = input('id');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //通过ID查询
 | 
				
			||||||
 | 
					        $item = \app\model\Goods::findById((int) $id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (empty($item)) {
 | 
				
			||||||
 | 
					            return $this->json(4000, '没有相关的记录!');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($this->request->isPost()) {
 | 
				
			||||||
 | 
					            try {
 | 
				
			||||||
 | 
					                $input = input('post.');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                $item->save([
 | 
				
			||||||
 | 
					                    'title'          => $input['title'],
 | 
				
			||||||
 | 
					                    'cover'          => $input['cover'],
 | 
				
			||||||
 | 
					                    'category_id'    => $input['category_id'],
 | 
				
			||||||
 | 
					                    'content'        => $input['content'],
 | 
				
			||||||
 | 
					                    'phone'          => $input['phone'],
 | 
				
			||||||
 | 
					                    'price'          => $input['price'],
 | 
				
			||||||
 | 
					                    'original_price' => $input['original_price'],
 | 
				
			||||||
 | 
					                    'account_id'     => $input['account_id'] ?? 0,
 | 
				
			||||||
 | 
					                    'status'         => $input['status'] ?? 0,
 | 
				
			||||||
 | 
					                    'area_id'        => $input['area_id'] ?? 0,
 | 
				
			||||||
 | 
					                    'images'         => $input['images'] ?? '',
 | 
				
			||||||
 | 
					                ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                return $this->json();
 | 
				
			||||||
 | 
					            } catch (Exception $e) {
 | 
				
			||||||
 | 
					                return $this->json(5000, $e->getMessage());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $bindAccount = Account::where('id', $item['account_id'])->column('id,nickname,mobile');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $accountList = [];
 | 
				
			||||||
 | 
					        foreach ($bindAccount as $ac) {
 | 
				
			||||||
 | 
					            $accountList[] = [
 | 
				
			||||||
 | 
					                'account_desc' => $ac['nickname'].'【手机:'.$ac['mobile'].'】',
 | 
				
			||||||
 | 
					                'id'           => $ac['id'], 'selected' => true
 | 
				
			||||||
 | 
					            ];
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        $this->data['jsonStr']  = $bindAccount ? json_encode($accountList, JSON_UNESCAPED_UNICODE) : json_encode([]);
 | 
				
			||||||
 | 
					        $this->data['item']     = $item;
 | 
				
			||||||
 | 
					        $this->data['id']       = $id;
 | 
				
			||||||
 | 
					        $this->data['cateList'] = GoodsCategory::order('sort', 'desc')
 | 
				
			||||||
 | 
					            ->order('id', 'desc')
 | 
				
			||||||
 | 
					            ->column('id,title');
 | 
				
			||||||
 | 
					        $this->data['areaList'] = GoodsArea::order('sort', 'desc')
 | 
				
			||||||
 | 
					            ->order('id', 'desc')
 | 
				
			||||||
 | 
					            ->column('id,title');
 | 
				
			||||||
 | 
					        return $this->view();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 更新属性
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @throws ModelNotFoundException
 | 
				
			||||||
 | 
					     * @throws DbException
 | 
				
			||||||
 | 
					     * @throws DataNotFoundException
 | 
				
			||||||
 | 
					     * @throws Exception
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function modify()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (!$this->request->isPost()) {
 | 
				
			||||||
 | 
					            return $this->json(4000, '非法请求');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $item     = input('post.');
 | 
				
			||||||
 | 
					        $validate = $this->validateByApi($item, [
 | 
				
			||||||
 | 
					            'field' => 'require',
 | 
				
			||||||
 | 
					            'value' => 'require',
 | 
				
			||||||
 | 
					        ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($validate !== true) {
 | 
				
			||||||
 | 
					            return $validate;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // 通过ID查询
 | 
				
			||||||
 | 
					        if (!$info = \app\model\Goods::findById((int) $item['id'])) {
 | 
				
			||||||
 | 
					            return $this->json(4001, '记录不存在');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $update = [$item['field'] => $item['value']];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            $info->save($update);
 | 
				
			||||||
 | 
					            return $this->json();
 | 
				
			||||||
 | 
					        } catch (ValidateException $e) {
 | 
				
			||||||
 | 
					            return $this->json(4001, $e->getError());
 | 
				
			||||||
 | 
					        } catch (Exception $e) {
 | 
				
			||||||
 | 
					            return $this->json(5000, '修改失败');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 删除
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return \think\response\Json
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function del(): Json
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (!$this->request->isPost()) {
 | 
				
			||||||
 | 
					            return $this->json(4000, '非法请求');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $ids = $this->request->param('ids/a', []);
 | 
				
			||||||
 | 
					        if (empty($ids)) {
 | 
				
			||||||
 | 
					            $ids[] = $this->request->param('id/d', 0);
 | 
				
			||||||
 | 
					            $ids   = array_filter($ids);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            if (count($ids)) {
 | 
				
			||||||
 | 
					                \app\model\Goods::whereIn('id', $ids)->delete();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                Log::write(get_class(), 'del', '删除操作,涉及到的ID为:'.implode(',', $ids));
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        } catch (Exception $e) {
 | 
				
			||||||
 | 
					            return $this->json(5000, $e->getMessage());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->json();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 搜索用户
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function searchAccount(): Json
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $keyword = input('keyword/s', '');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $list = [];
 | 
				
			||||||
 | 
					        if (!empty($keyword)) {
 | 
				
			||||||
 | 
					            $res  = Account::findList([], ['id', 'nickname', 'mobile'], 1, 1000, function ($q) use ($keyword) {
 | 
				
			||||||
 | 
					                return $q->where('nickname', 'like', '%'.$keyword.'%')
 | 
				
			||||||
 | 
					                    ->whereOr('mobile', 'like', '%'.$keyword.'%');
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					            $list = $res['list']->toArray();
 | 
				
			||||||
 | 
					            foreach ($list as &$item) {
 | 
				
			||||||
 | 
					                $item['account_desc'] = $item['nickname'].'【手机:'.$item['mobile'].'】';
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            unset($item);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->json(0, 'success', $list);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,206 @@
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					declare (strict_types = 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace app\controller\manager;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use Exception;
 | 
				
			||||||
 | 
					use app\model\Log;
 | 
				
			||||||
 | 
					use think\Collection;
 | 
				
			||||||
 | 
					use think\response\View;
 | 
				
			||||||
 | 
					use think\response\Json;
 | 
				
			||||||
 | 
					use app\controller\manager\Base;
 | 
				
			||||||
 | 
					use think\db\exception\DbException;
 | 
				
			||||||
 | 
					use think\exception\ValidateException;
 | 
				
			||||||
 | 
					use think\db\exception\DataNotFoundException;
 | 
				
			||||||
 | 
					use think\db\exception\ModelNotFoundException;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class GoodsCategory extends Base
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    protected $noNeedLogin = ['index', 'add', 'edit', 'del', 'modify'];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 列表
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @throws Exception
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function index()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if ($this->request->isPost()) {
 | 
				
			||||||
 | 
					            $params = input('searchParams/a');
 | 
				
			||||||
 | 
					            $page   = input('page/d', 1);
 | 
				
			||||||
 | 
					            $size   = input('size/d', 20);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $where = [];
 | 
				
			||||||
 | 
					            if (!empty($params)) {
 | 
				
			||||||
 | 
					                foreach ($params as $key => $param) {
 | 
				
			||||||
 | 
					                    $param = trim($param);
 | 
				
			||||||
 | 
					                    if ($key == 'keyword') {
 | 
				
			||||||
 | 
					                        $where[] = ['title', 'like', '%'.$param.'%'];
 | 
				
			||||||
 | 
					                        continue;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    if ($param == '0' || !empty($param)) {
 | 
				
			||||||
 | 
					                        $where[] = [$key, 'like', '%'.$param.'%'];
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $query = \app\model\GoodsCategory::where($where);
 | 
				
			||||||
 | 
					            $total = $query->count();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $res = [
 | 
				
			||||||
 | 
					                'total'   => $total,
 | 
				
			||||||
 | 
					                'current' => $page ?: 1,
 | 
				
			||||||
 | 
					                'size'    => $size ?: 20,
 | 
				
			||||||
 | 
					                'list'    => new Collection(),
 | 
				
			||||||
 | 
					            ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if ($total > 0) {
 | 
				
			||||||
 | 
					                $res['list'] = $query->page($page, $size)->order('sort', 'desc')->order('id', 'desc')->select();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return $this->json(0, 'success', $res);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->view();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 添加
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return Json|View
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function add()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if ($this->request->isPost()) {
 | 
				
			||||||
 | 
					            try {
 | 
				
			||||||
 | 
					                $input = input('post.');
 | 
				
			||||||
 | 
					                if (!isset($input['title'])) {
 | 
				
			||||||
 | 
					                    return $this->json(4000, '参数错误');
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                \app\model\GoodsCategory::create([
 | 
				
			||||||
 | 
					                    'title' => $input['title'] ?? '',
 | 
				
			||||||
 | 
					                ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                return $this->json();
 | 
				
			||||||
 | 
					            } catch (Exception $e) {
 | 
				
			||||||
 | 
					                return $this->json(4001, '添加失败'.$e->getMessage());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->view();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 编辑
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return \think\response\Json|\think\response\View
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function edit()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $id = input('id');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //通过ID查询
 | 
				
			||||||
 | 
					        $item = \app\model\GoodsCategory::where('id', (int)$id)->find();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (empty($item)) {
 | 
				
			||||||
 | 
					            return $this->json(4000, '没有相关记录!');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($this->request->isPost()) {
 | 
				
			||||||
 | 
					            try {
 | 
				
			||||||
 | 
					                $input = input('post.');
 | 
				
			||||||
 | 
					                if (!isset($input['title'])) {
 | 
				
			||||||
 | 
					                    return $this->json(4000, '参数错误');
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                $item->save([
 | 
				
			||||||
 | 
					                    'title' => $input['title'] ?? '',
 | 
				
			||||||
 | 
					                ]);
 | 
				
			||||||
 | 
					                return $this->json();
 | 
				
			||||||
 | 
					            } catch (Exception $e) {
 | 
				
			||||||
 | 
					                return $this->json(5000, $e->getMessage());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->data['item'] = $item;
 | 
				
			||||||
 | 
					        $this->data['id']   = $id;
 | 
				
			||||||
 | 
					        return $this->view();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 更新属性
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @throws ModelNotFoundException
 | 
				
			||||||
 | 
					     * @throws DbException
 | 
				
			||||||
 | 
					     * @throws DataNotFoundException
 | 
				
			||||||
 | 
					     * @throws Exception
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function modify()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (!$this->request->isPost()) {
 | 
				
			||||||
 | 
					            return $this->json(4000, '非法请求');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $item     = input('post.');
 | 
				
			||||||
 | 
					        $validate = $this->validateByApi($item, [
 | 
				
			||||||
 | 
					            'field' => 'require',
 | 
				
			||||||
 | 
					            'value' => 'require',
 | 
				
			||||||
 | 
					        ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($validate !== true) {
 | 
				
			||||||
 | 
					            return $validate;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // 通过ID查询
 | 
				
			||||||
 | 
					        if (!$info = \app\model\GoodsCategory::where('id', (int)$item['id'])->find()) {
 | 
				
			||||||
 | 
					            return $this->json(4001, '记录不存在');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $update = [$item['field'] => $item['value']];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            $info->save($update);
 | 
				
			||||||
 | 
					            return $this->json();
 | 
				
			||||||
 | 
					        } catch (ValidateException $e) {
 | 
				
			||||||
 | 
					            return $this->json(4001, $e->getError());
 | 
				
			||||||
 | 
					        } catch (Exception $e) {
 | 
				
			||||||
 | 
					            return $this->json(5000, '修改失败');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 删除
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return \think\response\Json
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function del(): Json
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (!$this->request->isPost()) {
 | 
				
			||||||
 | 
					            return $this->json(4000, '非法请求');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $ids = $this->request->param('ids/a', []);
 | 
				
			||||||
 | 
					        if (empty($ids)) {
 | 
				
			||||||
 | 
					            $ids[] = $this->request->param('id/d', 0);
 | 
				
			||||||
 | 
					            $ids   = array_filter($ids);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            if (count($ids)) {
 | 
				
			||||||
 | 
					                //删除逻辑
 | 
				
			||||||
 | 
					                if (\app\model\Goods::whereIn('area_id', $ids)->count() > 0) {
 | 
				
			||||||
 | 
					                    return $this->json(4000, '所选分类下存在发布物品,请先移除物品后再删除');
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                \app\model\GoodsCategory::whereIn('id', $ids)->delete();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                Log::write(get_class(), 'del', '删除操作,涉及到的ID为:'.implode(',', $ids));
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        } catch (Exception $e) {
 | 
				
			||||||
 | 
					            return $this->json(5000, $e->getMessage());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->json();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,98 @@
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace app\controller\manager;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use app\model\Overview;
 | 
				
			||||||
 | 
					use app\model\Spu;
 | 
				
			||||||
 | 
					use app\repository\CmsRepository;
 | 
				
			||||||
 | 
					use Exception;
 | 
				
			||||||
 | 
					use think\db\exception\DataNotFoundException;
 | 
				
			||||||
 | 
					use think\db\exception\DbException;
 | 
				
			||||||
 | 
					use think\db\exception\ModelNotFoundException;
 | 
				
			||||||
 | 
					use think\response\Json;
 | 
				
			||||||
 | 
					use think\response\View;
 | 
				
			||||||
 | 
					use app\model\Member;
 | 
				
			||||||
 | 
					use app\model\Menu;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Index extends Base
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    protected $noNeedLogin = ['index', 'init'];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 后台初始页面 随后进入dashboard页面
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return View
 | 
				
			||||||
 | 
					     * @throws DataNotFoundException
 | 
				
			||||||
 | 
					     * @throws DbException
 | 
				
			||||||
 | 
					     * @throws ModelNotFoundException
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function index(): View
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $auth               = session('auth');
 | 
				
			||||||
 | 
					        $this->data['user'] = Member::findById($auth['user_id'] ?? 0, ['id', 'username', 'nickname', 'mobile']);
 | 
				
			||||||
 | 
					        return $this->view();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 控制台
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return Json|View
 | 
				
			||||||
 | 
					     * @throws Exception
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function dashboard()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if ($this->request->isPost()) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return $this->json(0, '操作成功', []);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->data['count'] = 0;
 | 
				
			||||||
 | 
					        return $this->view();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 菜单初始化
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return Json
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function init(): Json
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        \think\facade\Config::load('extra/base', 'base');
 | 
				
			||||||
 | 
					        $config = config('base');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $title = $config['admin_title'] ?: '大向天诚商城管理系统';
 | 
				
			||||||
 | 
					//        $title = mb_strlen($title) > 3 ? mb_substr($title, 0, 3).'...' : $title;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $res             = [];
 | 
				
			||||||
 | 
					        $res['homeInfo'] = ['title' => '控制台', 'href' => "manager/index/dashboard"];
 | 
				
			||||||
 | 
					        $res['logoInfo'] = [
 | 
				
			||||||
 | 
					            'title' => $title,
 | 
				
			||||||
 | 
					            'href'  => "",
 | 
				
			||||||
 | 
					            'image' => $config['logo'] ?: '/static/manager/image/logo.png'
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $menus           = CmsRepository::getInstance()->getMenuList(Menu::TYPE_MENU, Menu::SHOW_YES)->toArray();
 | 
				
			||||||
 | 
					        $userId          = $this->auth['user_id'] ?? 0;
 | 
				
			||||||
 | 
					        $menus           = CmsRepository::getInstance()->handMenuRule($userId, $menus);
 | 
				
			||||||
 | 
					        $menus           = CmsRepository::getInstance()->buildMenuChild(0, $menus, 'child');
 | 
				
			||||||
 | 
					        $res['menuInfo'] = $menus;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return json($res);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 缓存清理
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return Json
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function clear(): Json
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $res = ['code' => 1, 'msg' => '服务端清理缓存成功'];
 | 
				
			||||||
 | 
					        sleep(2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return json($res);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,56 @@
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace app\controller\manager;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use app\model\Log as LogModel;
 | 
				
			||||||
 | 
					use Exception;
 | 
				
			||||||
 | 
					use think\response\Json;
 | 
				
			||||||
 | 
					use think\response\View;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * 日志
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Class Feedback
 | 
				
			||||||
 | 
					 * @package app\controller\manager
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					class Log extends Base
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 列表
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return View|Json
 | 
				
			||||||
 | 
					     * @throws Exception
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function index()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if ($this->request->isPost()) {
 | 
				
			||||||
 | 
					            $page         = input('page/d', 1);
 | 
				
			||||||
 | 
					            $limit        = input('size/d', 20);
 | 
				
			||||||
 | 
					            $searchParams = input('searchParams');
 | 
				
			||||||
 | 
					            $search       = [];
 | 
				
			||||||
 | 
					            if ($searchParams) {
 | 
				
			||||||
 | 
					                foreach ($searchParams as $key => $param) {
 | 
				
			||||||
 | 
					                    if ($param) {
 | 
				
			||||||
 | 
					                        if ($key == 'begin_time') {
 | 
				
			||||||
 | 
					                            $begin    = strtotime($param.' 00:00:00');
 | 
				
			||||||
 | 
					                            $search[] = ['create_time', '>', $begin];
 | 
				
			||||||
 | 
					                        } elseif ($key == 'end_time') {
 | 
				
			||||||
 | 
					                            $end      = strtotime($param.' 23:59:59');
 | 
				
			||||||
 | 
					                            $search[] = ['create_time', '<', $end];
 | 
				
			||||||
 | 
					                        } else {
 | 
				
			||||||
 | 
					                            $search[] = [$key, 'like', '%'.$param.'%'];
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $items = LogModel::findList($search, [], $page, $limit, function ($q) {
 | 
				
			||||||
 | 
					                return $q->with(['memberName'])->order('create_time', 'desc');
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return $this->json(0, '操作成功', $items);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->view();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,80 @@
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace app\controller\manager;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use app\service\Jwt;
 | 
				
			||||||
 | 
					use Exception;
 | 
				
			||||||
 | 
					use app\model\{Member, LoginLog};
 | 
				
			||||||
 | 
					use app\controller\BaseController;
 | 
				
			||||||
 | 
					use think\response\Json;
 | 
				
			||||||
 | 
					use think\response\View;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Login extends BaseController
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    protected $noNeedLogin = ['index'];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @return View|Json
 | 
				
			||||||
 | 
					     * @throws Exception
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function index()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (request()->isPost()) {
 | 
				
			||||||
 | 
					            $param    = input('post.data');
 | 
				
			||||||
 | 
					            $username = trim($param['username']);
 | 
				
			||||||
 | 
					            $password = trim($param['password']);
 | 
				
			||||||
 | 
					            $captcha  = trim($param['captcha'] ?? '');
 | 
				
			||||||
 | 
					            if (!captcha_check($captcha)) {
 | 
				
			||||||
 | 
					                return $this->json(4001, '验证码错误'.$captcha);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (empty($username) || empty($password)) {
 | 
				
			||||||
 | 
					                return $this->json(4001, '用户名和密码不能为空');
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            $member = Member::getByUserName($username);
 | 
				
			||||||
 | 
					            if (empty($member)) {
 | 
				
			||||||
 | 
					                return $this->json(4002, '用户名或密码错误');
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            if ($member['password'] != md5($password.$username)) {
 | 
				
			||||||
 | 
					                return $this->json(4003, '用户名或密码错误');
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            if ($member['status'] != Member::STATUS_NORMAL) {
 | 
				
			||||||
 | 
					                return $this->json(4004, '账号已被禁用');
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $userInfo = [
 | 
				
			||||||
 | 
					                'user_id'    => $member['id'],
 | 
				
			||||||
 | 
					                'username'   => $member['username'],
 | 
				
			||||||
 | 
					                'nickname'   => $member['nickname'],
 | 
				
			||||||
 | 
					                'is_teacher' => $member['is_teacher'],
 | 
				
			||||||
 | 
					                'account_id' => $member['account_id'],//绑定的前台用户ID
 | 
				
			||||||
 | 
					            ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $jwtToken = Jwt::generate($userInfo, env('app.expire', 7200));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $userInfo['token'] = $jwtToken;//jwt生成token
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            //记录最后登陆时间
 | 
				
			||||||
 | 
					            $ip   = request()->ip();
 | 
				
			||||||
 | 
					            $time = time();
 | 
				
			||||||
 | 
					            Member::updateById($member['id'], [
 | 
				
			||||||
 | 
					                'login_time' => $time,
 | 
				
			||||||
 | 
					                'login_ip'   => $ip
 | 
				
			||||||
 | 
					            ]);
 | 
				
			||||||
 | 
					            LoginLog::create([
 | 
				
			||||||
 | 
					                'member_id'   => $member['id'],
 | 
				
			||||||
 | 
					                'name'        => $member['username'],
 | 
				
			||||||
 | 
					                'ip'          => $ip,
 | 
				
			||||||
 | 
					                'create_time' => $time
 | 
				
			||||||
 | 
					            ]);
 | 
				
			||||||
 | 
					            session('auth', $userInfo);
 | 
				
			||||||
 | 
					            return $this->json(0, 'success', ['url' => '/manager']);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $viewData = [];
 | 
				
			||||||
 | 
					        \think\facade\Config::load('extra/base', 'base');
 | 
				
			||||||
 | 
					        $config                 = config('base');
 | 
				
			||||||
 | 
					        $viewData['loginTitle'] = $config['login_title'] ?? '大向天诚商城管理系统';
 | 
				
			||||||
 | 
					        return view()->assign($viewData);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,21 @@
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					namespace app\controller\manager;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use app\controller\BaseController;
 | 
				
			||||||
 | 
					use think\response\Redirect;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Logout extends BaseController
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    protected $noNeedLogin = ['index'];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 退出
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return Redirect
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function index(): Redirect
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        session(null);
 | 
				
			||||||
 | 
					        return redirect(url('/manager/login/index'));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,390 @@
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace app\controller\manager;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use app\model\Log;
 | 
				
			||||||
 | 
					use app\model\Member as MemberModel;
 | 
				
			||||||
 | 
					use app\model\Role as RoleModel;
 | 
				
			||||||
 | 
					use Exception;
 | 
				
			||||||
 | 
					use tauthz\facade\Enforcer;
 | 
				
			||||||
 | 
					use think\db\exception\DataNotFoundException;
 | 
				
			||||||
 | 
					use think\db\exception\DbException;
 | 
				
			||||||
 | 
					use think\db\exception\ModelNotFoundException;
 | 
				
			||||||
 | 
					use think\exception\ValidateException;
 | 
				
			||||||
 | 
					use think\facade\Db;
 | 
				
			||||||
 | 
					use think\response\Json;
 | 
				
			||||||
 | 
					use think\response\Redirect;
 | 
				
			||||||
 | 
					use think\response\View;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * (后台)人员管理
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Class Member
 | 
				
			||||||
 | 
					 * @package app\controller\manager
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					class Member extends Base
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 删除
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return Json
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function del(): Json
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if ($this->request->isPost()) {
 | 
				
			||||||
 | 
					            $ids = input('post.ids/a', []);
 | 
				
			||||||
 | 
					            if (empty($ids)) {
 | 
				
			||||||
 | 
					                $ids[] = input('post.id/d');
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            MemberModel::deleteByIds($ids);
 | 
				
			||||||
 | 
					            foreach ($ids as $id) {
 | 
				
			||||||
 | 
					                Enforcer::deleteRolesForUser($id);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            Log::write(get_class().'Del', 'del', '涉及到的ID为:'.implode(',', $ids));
 | 
				
			||||||
 | 
					            return $this->json();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return $this->json(4001, '非法请求!');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 个人详情
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return Json|View|Redirect
 | 
				
			||||||
 | 
					     * @throws DataNotFoundException
 | 
				
			||||||
 | 
					     * @throws DbException
 | 
				
			||||||
 | 
					     * @throws ModelNotFoundException
 | 
				
			||||||
 | 
					     * @throws Exception
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function profile()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $id = $this->auth['user_id'] ?? 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!$item = MemberModel::findById($id)) {
 | 
				
			||||||
 | 
					            if ($this->request->isAjax()) {
 | 
				
			||||||
 | 
					                return $this->json(4001, '记录不存在');
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            return $this->error('记录不存在');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($this->request->isPost()) {
 | 
				
			||||||
 | 
					            $post = input('post.');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $validate = $this->validateByApi($post, [
 | 
				
			||||||
 | 
					                'mobile|手机号'  => 'require|unique:member,mobile,'.$id,
 | 
				
			||||||
 | 
					                'nickname|昵称' => 'require|chsAlphaNum|min:2|max:10',
 | 
				
			||||||
 | 
					                'remark|备注信息' => 'max:255',
 | 
				
			||||||
 | 
					            ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if ($validate !== true) {
 | 
				
			||||||
 | 
					                return $validate;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (!checkMobile($post['mobile'])) {
 | 
				
			||||||
 | 
					                return $this->json(4002, '请输入正确的手机号码');
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            try {
 | 
				
			||||||
 | 
					                $item->save($post);
 | 
				
			||||||
 | 
					                return $this->json();
 | 
				
			||||||
 | 
					            } catch (ValidateException $e) {
 | 
				
			||||||
 | 
					                return $this->json(4001, $e->getError());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->data['item'] = $item;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->view();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 编辑
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return Json|View
 | 
				
			||||||
 | 
					     * @throws DataNotFoundException
 | 
				
			||||||
 | 
					     * @throws DbException
 | 
				
			||||||
 | 
					     * @throws ModelNotFoundException
 | 
				
			||||||
 | 
					     * @throws Exception
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function edit()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $id = input('id/d', 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!$info = MemberModel::findById($id)) {
 | 
				
			||||||
 | 
					            return $this->json(4001, '记录不存在');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($this->request->isPost()) {
 | 
				
			||||||
 | 
					            $item = input('post.');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $validate = $this->validateByApi($item, [
 | 
				
			||||||
 | 
					                'mobile|手机号'  => 'require|unique:member,mobile,'.$id,
 | 
				
			||||||
 | 
					                'nickname|昵称' => 'require|chsAlphaNum|min:2|max:10',
 | 
				
			||||||
 | 
					                'remark|备注信息' => 'max:255',
 | 
				
			||||||
 | 
					            ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if ($validate !== true) {
 | 
				
			||||||
 | 
					                return $validate;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (!checkMobile($item['mobile'])) {
 | 
				
			||||||
 | 
					                return $this->json(4002, '请输入正确的手机号码');
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $roles = [];
 | 
				
			||||||
 | 
					            if ($item['roles']) {
 | 
				
			||||||
 | 
					                $roles         = $item['roles'];
 | 
				
			||||||
 | 
					                $item['roles'] = implode(',', $item['roles']);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            Db::startTrans();
 | 
				
			||||||
 | 
					            try {
 | 
				
			||||||
 | 
					                $info->save($item);
 | 
				
			||||||
 | 
					                //删除所有角色
 | 
				
			||||||
 | 
					                Enforcer::deleteRolesForUser($id);
 | 
				
			||||||
 | 
					                //新增角色
 | 
				
			||||||
 | 
					                foreach ($roles as $role) {
 | 
				
			||||||
 | 
					                    Enforcer::addRoleForUser($id, $role);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                Db::commit();
 | 
				
			||||||
 | 
					                return $this->json();
 | 
				
			||||||
 | 
					            } catch (ValidateException $e) {
 | 
				
			||||||
 | 
					                Db::rollback();
 | 
				
			||||||
 | 
					                return $this->json(4001, $e->getError());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->data['item']     = $info;
 | 
				
			||||||
 | 
					        $this->data['roleJson'] = $this->roleJson(explode(',', $info['roles']));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->view();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 单个字段编辑
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return Json
 | 
				
			||||||
 | 
					     * @throws DataNotFoundException
 | 
				
			||||||
 | 
					     * @throws DbException
 | 
				
			||||||
 | 
					     * @throws ModelNotFoundException
 | 
				
			||||||
 | 
					     * @throws Exception
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function modify(): Json
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if ($this->request->isPost()) {
 | 
				
			||||||
 | 
					            $item     = input('post.');
 | 
				
			||||||
 | 
					            $validate = $this->validateByApi($item, [
 | 
				
			||||||
 | 
					                'field' => 'require',
 | 
				
			||||||
 | 
					                'value' => 'require',
 | 
				
			||||||
 | 
					            ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if ($validate !== true) {
 | 
				
			||||||
 | 
					                return $validate;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (!$info = MemberModel::findById($item['id'])) {
 | 
				
			||||||
 | 
					                return $this->json(4001, '记录不存在');
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $update = [$item['field'] => $item['value']];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            try {
 | 
				
			||||||
 | 
					                $info->save($update);
 | 
				
			||||||
 | 
					                return $this->json();
 | 
				
			||||||
 | 
					            } catch (ValidateException $e) {
 | 
				
			||||||
 | 
					                return $this->json(4001, $e->getError());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return $this->json(4000, '非法请求');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 添加
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return Json|View
 | 
				
			||||||
 | 
					     * @throws Exception
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function add()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if ($this->request->isPost()) {
 | 
				
			||||||
 | 
					            $item = input('post.');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $validate = $this->validateByApi($item, [
 | 
				
			||||||
 | 
					                'username|用户名' => 'require|alphaDash|min:4|max:16|unique:member',
 | 
				
			||||||
 | 
					                'mobile|手机号'   => 'require|unique:member',
 | 
				
			||||||
 | 
					                'nickname|昵称'  => 'require|chsAlphaNum|min:2|max:10',
 | 
				
			||||||
 | 
					                'password|密码'  => 'require|min:4|max:16',
 | 
				
			||||||
 | 
					                'remark|备注信息'  => 'max:255',
 | 
				
			||||||
 | 
					            ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if ($validate !== true) {
 | 
				
			||||||
 | 
					                return $validate;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (!checkMobile($item['mobile'])) {
 | 
				
			||||||
 | 
					                return $this->json(4002, '请输入正确的手机号码');
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $roles = [];
 | 
				
			||||||
 | 
					            if ($item['roles']) {
 | 
				
			||||||
 | 
					                $roles         = $item['roles'];
 | 
				
			||||||
 | 
					                $item['roles'] = implode(',', $item['roles']);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            Db::startTrans();
 | 
				
			||||||
 | 
					            try {
 | 
				
			||||||
 | 
					                $item['password'] = md5($item['password'].$item['username']);
 | 
				
			||||||
 | 
					                $member           = MemberModel::create($item);
 | 
				
			||||||
 | 
					                foreach ($roles as $role) {
 | 
				
			||||||
 | 
					                    Enforcer::addRoleForUser($member['id'], $role);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                Db::commit();
 | 
				
			||||||
 | 
					                return $this->json();
 | 
				
			||||||
 | 
					            } catch (ValidateException $e) {
 | 
				
			||||||
 | 
					                Db::rollback();
 | 
				
			||||||
 | 
					                return $this->json(4001, $e->getError());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->data['roleJson'] = $this->roleJson();
 | 
				
			||||||
 | 
					        return $this->view();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 修改密码
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return Json|View|Redirect
 | 
				
			||||||
 | 
					     * @throws Exception
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function password()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $id = input('id/d', 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!$item = MemberModel::findById($id)) {
 | 
				
			||||||
 | 
					            if ($this->request->isAjax()) {
 | 
				
			||||||
 | 
					                return $this->json(4001, '记录不存在');
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            return $this->error('记录不存在');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($this->request->isPost()) {
 | 
				
			||||||
 | 
					            $post     = input('post.');
 | 
				
			||||||
 | 
					            $validate = $this->validateByApi($post, [
 | 
				
			||||||
 | 
					                'password|密码' => 'require|confirm',
 | 
				
			||||||
 | 
					            ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if ($validate !== true) {
 | 
				
			||||||
 | 
					                return $validate;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $password = md5($post['password'].$item['username']);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            try {
 | 
				
			||||||
 | 
					                $item->save(['password' => $password]);
 | 
				
			||||||
 | 
					                return $this->json();
 | 
				
			||||||
 | 
					            } catch (ValidateException $e) {
 | 
				
			||||||
 | 
					                return $this->json(4001, $e->getError());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->data['item'] = $item;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->view();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 个人修改密码
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return Json|View
 | 
				
			||||||
 | 
					     * @throws Exception
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function myPassword()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $id = $this->auth['user_id'] ?? 0;
 | 
				
			||||||
 | 
					        if (!$item = MemberModel::findById($id)) {
 | 
				
			||||||
 | 
					            return $this->json(4001, '记录不存在');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($this->request->isPost()) {
 | 
				
			||||||
 | 
					            $post     = input('post.');
 | 
				
			||||||
 | 
					            $validate = $this->validateByApi($post, [
 | 
				
			||||||
 | 
					                'old-password|旧密码' => 'require',
 | 
				
			||||||
 | 
					                'password|密码'      => 'require|confirm',
 | 
				
			||||||
 | 
					            ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if ($validate !== true) {
 | 
				
			||||||
 | 
					                return $validate;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if ($item['password'] !== md5($post['old-password'].$item['username'])) {
 | 
				
			||||||
 | 
					                return $this->json(4002, '原始密码错误');
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $password = md5($post['password'].$item['username']);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            try {
 | 
				
			||||||
 | 
					                $item->save(['password' => $password]);
 | 
				
			||||||
 | 
					                return $this->json();
 | 
				
			||||||
 | 
					            } catch (ValidateException $e) {
 | 
				
			||||||
 | 
					                return $this->json(4001, $e->getError());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->data['item'] = $item;
 | 
				
			||||||
 | 
					        return $this->view();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 列表
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return View|Json
 | 
				
			||||||
 | 
					     * @throws Exception
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function index()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if ($this->request->isPost()) {
 | 
				
			||||||
 | 
					            $page         = input('page/d', 1);
 | 
				
			||||||
 | 
					            $limit        = input('size/d', 20);
 | 
				
			||||||
 | 
					            $searchParams = input('searchParams');
 | 
				
			||||||
 | 
					            $where        = [];
 | 
				
			||||||
 | 
					            if ($searchParams) {
 | 
				
			||||||
 | 
					                foreach ($searchParams as $key => $param) {
 | 
				
			||||||
 | 
					                    if (!empty($param)) {
 | 
				
			||||||
 | 
					                        $where[] = [$key, 'like', '%'.$param.'%'];
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if ($this->auth['username'] != 'admin') {
 | 
				
			||||||
 | 
					                $where[] = ['username', '<>', 'admin'];
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            $items   = MemberModel::findList($where, [], $page, $limit, function ($q) {
 | 
				
			||||||
 | 
					                return $q->order('id', 'desc');
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return $this->json(0, '操作成功', $items);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return $this->view();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 构造角色json数据
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param  array  $selected
 | 
				
			||||||
 | 
					     * @return false|string
 | 
				
			||||||
 | 
					     * @throws DataNotFoundException
 | 
				
			||||||
 | 
					     * @throws DbException
 | 
				
			||||||
 | 
					     * @throws ModelNotFoundException
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    private function roleJson(array $selected = [])
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $roles = RoleModel::where('status', RoleModel::STATUS_NORMAL)
 | 
				
			||||||
 | 
					            ->order('sort', 'desc')
 | 
				
			||||||
 | 
					            ->select()
 | 
				
			||||||
 | 
					            ->toArray();
 | 
				
			||||||
 | 
					        foreach ($roles as $k => $m) {
 | 
				
			||||||
 | 
					            $roles[$k]['checked'] = in_array($m['id'], $selected);
 | 
				
			||||||
 | 
					            $roles[$k]['spread']  = true;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return json_encode($roles, JSON_UNESCAPED_UNICODE);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,263 @@
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace app\controller\manager;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use app\repository\CmsRepository;
 | 
				
			||||||
 | 
					use app\model\Log;
 | 
				
			||||||
 | 
					use app\model\Menu as MenuModel;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use app\validate\MenuValidate;
 | 
				
			||||||
 | 
					use Exception;
 | 
				
			||||||
 | 
					use think\db\exception\DataNotFoundException;
 | 
				
			||||||
 | 
					use think\db\exception\DbException;
 | 
				
			||||||
 | 
					use think\db\exception\ModelNotFoundException;
 | 
				
			||||||
 | 
					use think\exception\ValidateException;
 | 
				
			||||||
 | 
					use think\facade\Db;
 | 
				
			||||||
 | 
					use think\response\Json;
 | 
				
			||||||
 | 
					use think\response\View;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * 菜单管理
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Class Menu
 | 
				
			||||||
 | 
					 * @package app\controller\manager
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					class Menu extends Base
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 删除
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return Json
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function del(): Json
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if ($this->request->isPost()) {
 | 
				
			||||||
 | 
					            $ids = input('post.ids/a', []);
 | 
				
			||||||
 | 
					            if (empty($ids)) {
 | 
				
			||||||
 | 
					                $ids[] = input('post.id/d');
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            $repo = CmsRepository::getInstance();
 | 
				
			||||||
 | 
					            if ($repo->hasChildrenMenuByIds($ids)) {
 | 
				
			||||||
 | 
					                return $this->json(4002, '待删除数据存在子数据');
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            $repo->delMenuByIds($ids);
 | 
				
			||||||
 | 
					            Log::write('menuDel', 'del', '删除了菜单,涉及到的ID为:'.implode(',', $ids));
 | 
				
			||||||
 | 
					            return $this->json();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return $this->json(4001, '非法请求!');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 规则
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return string[]
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    private function rule(): array
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return [
 | 
				
			||||||
 | 
					            'pid|父级菜单'    => 'require|number',
 | 
				
			||||||
 | 
					            'title|标题'    => 'require|max:100',
 | 
				
			||||||
 | 
					            'name|路由标识'   => 'require',
 | 
				
			||||||
 | 
					            'remark|备注信息' => 'max:255',
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 编辑
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return Json|View
 | 
				
			||||||
 | 
					     * @throws DataNotFoundException
 | 
				
			||||||
 | 
					     * @throws DbException
 | 
				
			||||||
 | 
					     * @throws ModelNotFoundException
 | 
				
			||||||
 | 
					     * @throws Exception
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function edit()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $id = input('id/d', 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!$info = MenuModel::findById($id)) {
 | 
				
			||||||
 | 
					            return $this->json(4001, '记录不存在');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($this->request->isPost()) {
 | 
				
			||||||
 | 
					            $item     = input('post.');
 | 
				
			||||||
 | 
					            $validate = $this->validateByApi($item, $this->rule());
 | 
				
			||||||
 | 
					            if ($validate !== true) {
 | 
				
			||||||
 | 
					                return $validate;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            try {
 | 
				
			||||||
 | 
					                $oldPath      = $info['path'];
 | 
				
			||||||
 | 
					                $item['path'] = MenuModel::getPath($item['pid']);
 | 
				
			||||||
 | 
					                $info->save($item);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                //刷新所有路径
 | 
				
			||||||
 | 
					                $oldPath = $oldPath.','.$id;
 | 
				
			||||||
 | 
					                $newPath = $item['path'].','.$id;
 | 
				
			||||||
 | 
					                if ($oldPath != $newPath) {
 | 
				
			||||||
 | 
					                    MenuModel::refreshPath();
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                return $this->json();
 | 
				
			||||||
 | 
					            } catch (ValidateException $e) {
 | 
				
			||||||
 | 
					                return $this->json(4001, $e->getError());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $disabled               = MenuModel::getAllChildrenIds($id);
 | 
				
			||||||
 | 
					        $disabled[]             = $id;
 | 
				
			||||||
 | 
					        $this->data['menuList'] = $this->menuJson([$info['pid']], $disabled);
 | 
				
			||||||
 | 
					        $this->data['item']     = $info;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->view();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 单个字段编辑
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return Json
 | 
				
			||||||
 | 
					     * @throws DataNotFoundException
 | 
				
			||||||
 | 
					     * @throws DbException
 | 
				
			||||||
 | 
					     * @throws ModelNotFoundException
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function modify(): Json
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if ($this->request->isPost()) {
 | 
				
			||||||
 | 
					            $item     = input('post.');
 | 
				
			||||||
 | 
					            $validate = new MenuValidate();
 | 
				
			||||||
 | 
					            if (!$validate->scene('menu_modify')->check($item)) {
 | 
				
			||||||
 | 
					                return $this->json(4002, $validate->getError());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (!$info = MenuModel::findById($item['id'])) {
 | 
				
			||||||
 | 
					                return $this->json(4001, '记录不存在');
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $update = [$item['field'] => $item['value']];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            try {
 | 
				
			||||||
 | 
					                $info->save($update);
 | 
				
			||||||
 | 
					                return $this->json();
 | 
				
			||||||
 | 
					            } catch (ValidateException $e) {
 | 
				
			||||||
 | 
					                return $this->json(4001, $e->getError());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return $this->json(4000, '非法请求');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 添加
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return Json|View
 | 
				
			||||||
 | 
					     * @throws Exception
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function add()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $id = input('id/d', 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($this->request->isPost()) {
 | 
				
			||||||
 | 
					            $item     = input('post.');
 | 
				
			||||||
 | 
					            $validate = $this->validateByApi($item, $this->rule());
 | 
				
			||||||
 | 
					            if ($validate !== true) {
 | 
				
			||||||
 | 
					                return $validate;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            try {
 | 
				
			||||||
 | 
					                $item['path'] = MenuModel::getPath($item['pid']);
 | 
				
			||||||
 | 
					                MenuModel::create($item);
 | 
				
			||||||
 | 
					                return $this->json();
 | 
				
			||||||
 | 
					            } catch (ValidateException $e) {
 | 
				
			||||||
 | 
					                return $this->json(4001, $e->getError());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $selected               = $id > 0 ? [$id] : [];
 | 
				
			||||||
 | 
					        $this->data['menuList'] = $this->menuJson($selected);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->view();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 常规权限生成
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return Json|View
 | 
				
			||||||
 | 
					     * @throws Exception
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function generate()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $id = input('id/d', 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($this->request->isPost()) {
 | 
				
			||||||
 | 
					            $id = input('id/d', 0);
 | 
				
			||||||
 | 
					            if (!$item = MenuModel::findById($id)) {
 | 
				
			||||||
 | 
					                return $this->json(4002, '记录不存在');
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if ($item['type'] != MenuModel::TYPE_MENU) {
 | 
				
			||||||
 | 
					                return $this->json(4003, '仅菜单类型可操作');
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            Db::startTrans();
 | 
				
			||||||
 | 
					            try {
 | 
				
			||||||
 | 
					                //自动生成常规操作
 | 
				
			||||||
 | 
					                MenuModel::generate($id, $item['name'], $item['path']);
 | 
				
			||||||
 | 
					                Db::commit();
 | 
				
			||||||
 | 
					                return $this->json();
 | 
				
			||||||
 | 
					            } catch (ValidateException $e) {
 | 
				
			||||||
 | 
					                Db::rollback();
 | 
				
			||||||
 | 
					                return $this->json(4001, $e->getError());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $selected               = $id > 0 ? [$id] : [];
 | 
				
			||||||
 | 
					        $this->data['menuList'] = $this->menuJson($selected);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->view();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 列表
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return View|Json
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function index()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if ($this->request->isPost()) {
 | 
				
			||||||
 | 
					            $menus = CmsRepository::getInstance()->getMenuList();
 | 
				
			||||||
 | 
					            $menus->each(function ($item) {
 | 
				
			||||||
 | 
					                if ($item['type'] == 'menu') {
 | 
				
			||||||
 | 
					                    $item->open = false;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					            $res = [
 | 
				
			||||||
 | 
					                'code'  => 0,
 | 
				
			||||||
 | 
					                'msg'   => 'success',
 | 
				
			||||||
 | 
					                'count' => $menus->count(),
 | 
				
			||||||
 | 
					                'data'  => $menus->toArray(),
 | 
				
			||||||
 | 
					            ];
 | 
				
			||||||
 | 
					            return json($res);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return $this->view();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * xmSelect插件 json数据
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param  array  $selected
 | 
				
			||||||
 | 
					     * @param  array  $disabled
 | 
				
			||||||
 | 
					     * @return false|string
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    private function menuJson(array $selected = [], array $disabled = [])
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $categoryList[] = ['title' => '顶级菜单', 'id' => 0, 'prefix' => '', 'disabled' => false, 'open' => true, 'selected' => in_array(0, $selected)];
 | 
				
			||||||
 | 
					        $menus          = CmsRepository::getInstance()->getMenuList();
 | 
				
			||||||
 | 
					        $menus          = $menus->toArray();
 | 
				
			||||||
 | 
					        foreach ($menus as $k => $m) {
 | 
				
			||||||
 | 
					            $menus[$k]['selected'] = in_array($m['id'], $selected);
 | 
				
			||||||
 | 
					            $menus[$k]['disabled'] = in_array($m['id'], $disabled);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        $menus        = CmsRepository::getInstance()->buildMenuChild(0, $menus);
 | 
				
			||||||
 | 
					        $categoryList = array_merge($categoryList, CmsRepository::getInstance()->handleSelectedList($menus));
 | 
				
			||||||
 | 
					        return json_encode($categoryList, JSON_UNESCAPED_UNICODE);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,161 @@
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace app\controller\manager;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use app\exception\TraitException;
 | 
				
			||||||
 | 
					use app\model\Log;
 | 
				
			||||||
 | 
					use app\model\Message AS MessageModel;
 | 
				
			||||||
 | 
					use app\model\ScriptManagement AS ScriptManagementModel;
 | 
				
			||||||
 | 
					use app\repository\AccountRepository;
 | 
				
			||||||
 | 
					use think\facade\Db;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Message extends Base
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function index()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $repo = AccountRepository::getInstance();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($this->request->isPost()) {
 | 
				
			||||||
 | 
					            $page = $this->request->param('page/d', 1);
 | 
				
			||||||
 | 
					            $size = $this->request->param('size/d', 30);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $whereMap   = [];
 | 
				
			||||||
 | 
					            $orders     = ['send_at' => 'desc', 'id' => 'desc'];
 | 
				
			||||||
 | 
					            $whereMap[] = ['type', '<>', MessageModel::TYPE_REMINDERS];
 | 
				
			||||||
 | 
					            $whereMap[] = ['is_push', '=', MessageModel::COMMON_OFF];
 | 
				
			||||||
 | 
					            $res        = $repo->messageList($whereMap, [], $page, $size, null, $orders);
 | 
				
			||||||
 | 
					            $list       = $res['list'];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $msgTypeTextList   = $repo->messageTypeTextList();
 | 
				
			||||||
 | 
					            $msgTargetTextList = $repo->messageTargetTextList();
 | 
				
			||||||
 | 
					            foreach ($list as $item) {
 | 
				
			||||||
 | 
					                $item['type_text']   = $msgTypeTextList[$item['type']] ?? '';
 | 
				
			||||||
 | 
					                $item['target_text'] = $msgTargetTextList[$item['target']] ?? '';
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            $res['list'] = $list;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return $this->json(0, 'success', $res);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->view();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function add()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $repo = AccountRepository::getInstance();
 | 
				
			||||||
 | 
					        if ($this->request->isPost()) {
 | 
				
			||||||
 | 
					            $item          = $this->request->param('item/a', []);
 | 
				
			||||||
 | 
					            $targetListStr = $this->request->param('target_list_str/s', '');
 | 
				
			||||||
 | 
					            $fdata = $this->request->param('fdata/a', []);
 | 
				
			||||||
 | 
					            if (empty($fdata)) {
 | 
				
			||||||
 | 
					                return $this->json(4001, "发送时间必填");
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            foreach ($fdata as $fdatum) {
 | 
				
			||||||
 | 
					                if (!isset($fdatum['send_at'])||empty($fdatum['send_at'])) {
 | 
				
			||||||
 | 
					                    return $this->json(4001, "发送时间必填");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            unset($item["send_at"]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            Db::startTrans();
 | 
				
			||||||
 | 
					            try {
 | 
				
			||||||
 | 
					                $type       = $item['type'] ?? '';
 | 
				
			||||||
 | 
					                $target     = $item['target'] ?? '';
 | 
				
			||||||
 | 
					                $targetList = empty($targetListStr) ? [] : explode(',', $targetListStr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                foreach ($fdata as $sitem){
 | 
				
			||||||
 | 
					                    $item["send_at"] = $sitem['send_at'];
 | 
				
			||||||
 | 
					                    $item["content"] = $sitem['content'];
 | 
				
			||||||
 | 
					                    $repo->addMessage($type, $target, $targetList, $item);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                Db::commit();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                return $this->json();
 | 
				
			||||||
 | 
					            } catch (TraitException $e) {
 | 
				
			||||||
 | 
					                Db::rollback();
 | 
				
			||||||
 | 
					                return $this->json(4001, $e->getMessage());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->data['typeList']   = $repo->messageTypeTextList();
 | 
				
			||||||
 | 
					        $this->data['targetList'] = $repo->messageTargetTextList();
 | 
				
			||||||
 | 
					        $scriptManagement = ScriptManagementModel::getAll();
 | 
				
			||||||
 | 
					        $this->data["script_management"] = $scriptManagement;
 | 
				
			||||||
 | 
					        $this->data["script_management_json"] = json_encode($scriptManagement);
 | 
				
			||||||
 | 
					        return $this->view();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function edit()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $repo = AccountRepository::getInstance();
 | 
				
			||||||
 | 
					        $id   = $this->request->param('id/d', 0);
 | 
				
			||||||
 | 
					        $msg  = $repo->messageInfo($id);
 | 
				
			||||||
 | 
					        if (empty($msg)) {
 | 
				
			||||||
 | 
					            return $this->json(4000, '没有相关的消息记录');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($this->request->isPost()) {
 | 
				
			||||||
 | 
					            $item          = $this->request->param('item/a', []);
 | 
				
			||||||
 | 
					            $targetListStr = $this->request->param('target_list_str/s', '');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            try {
 | 
				
			||||||
 | 
					                $type       = $item['type'] ?? '';
 | 
				
			||||||
 | 
					                $target     = $item['target'] ?? '';
 | 
				
			||||||
 | 
					                $targetList = empty($targetListStr) ? [] : explode(',', $targetListStr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                $repo->editMessage($id, $type, $target, $targetList, $item);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            } catch (TraitException $e) {
 | 
				
			||||||
 | 
					                return $this->json(4001, $e->getMessage());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return $this->json();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $targetAids = empty($msg['target_list'] ?? '') ? [] : explode(',', $msg['target_list']);
 | 
				
			||||||
 | 
					        $whereMap[] = ['id', 'in', $targetAids];
 | 
				
			||||||
 | 
					        $targetList = $repo->findList($whereMap)['list']->toArray();
 | 
				
			||||||
 | 
					        foreach ($targetList as &$item) {
 | 
				
			||||||
 | 
					            $item['account_desc2'] = $item['nickname'].'【姓名:'.$item['real_name'].'】';
 | 
				
			||||||
 | 
					            $item['selected']      = true;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->data['id']             = $id;
 | 
				
			||||||
 | 
					        $this->data['item']           = $msg;
 | 
				
			||||||
 | 
					        $this->data['targetListJson'] = json_encode($targetList, JSON_UNESCAPED_UNICODE);
 | 
				
			||||||
 | 
					        $this->data['typeList']       = $repo->messageTypeTextList();
 | 
				
			||||||
 | 
					        $this->data['targetList']     = $repo->messageTargetTextList();
 | 
				
			||||||
 | 
					        $scriptManagement = ScriptManagementModel::getAll();
 | 
				
			||||||
 | 
					        $this->data["script_management"] = $scriptManagement;
 | 
				
			||||||
 | 
					        $this->data["script_management_json"] = json_encode($scriptManagement);
 | 
				
			||||||
 | 
					        return $this->view();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function del()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (!$this->request->isPost()) {
 | 
				
			||||||
 | 
					            return $this->json(4000, '非法请求');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $ids = $this->request->param('ids/a', []);
 | 
				
			||||||
 | 
					        if (empty($ids)) {
 | 
				
			||||||
 | 
					            $ids[] = $this->request->param('id/d', 0);
 | 
				
			||||||
 | 
					            $ids   = array_filter($ids);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (count($ids)) {
 | 
				
			||||||
 | 
					            AccountRepository::getInstance()->deleteMessages($ids);
 | 
				
			||||||
 | 
					            Log::write(get_class(), 'del', '删除了message,涉及到的ID为:'.implode(',', $ids));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return $this->json();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,58 @@
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace app\controller\manager;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use app\model\AccountRecord;
 | 
				
			||||||
 | 
					use app\model\Overview as OverviewModel;
 | 
				
			||||||
 | 
					use app\model\AccountRole;
 | 
				
			||||||
 | 
					use app\model\Appointment;
 | 
				
			||||||
 | 
					use app\model\Account;
 | 
				
			||||||
 | 
					use Exception;
 | 
				
			||||||
 | 
					use think\response\Json;
 | 
				
			||||||
 | 
					use think\response\View;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Overview extends Base
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 客户分析
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return Json|View
 | 
				
			||||||
 | 
					     * @throws Exception
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function customer()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if ($this->request->isPost()) {
 | 
				
			||||||
 | 
					            $page    = input('page/d', 1);
 | 
				
			||||||
 | 
					            $limit   = input('size/d', 10);
 | 
				
			||||||
 | 
					            $params = input('searchParams');
 | 
				
			||||||
 | 
					            $keyword = $params['keyword'] ?? '';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $items = OverviewModel::findList([], [], $page, $limit, function ($q) use ($keyword) {
 | 
				
			||||||
 | 
					                return $q->alias('o')->leftJoin('account a', 'a.id = o.account_id')
 | 
				
			||||||
 | 
					                    ->field('o.*,a.nickname,a.real_name,a.mobile')
 | 
				
			||||||
 | 
					                    ->when(!empty($keyword), function ($q) use ($keyword) {
 | 
				
			||||||
 | 
					                        $q->where('a.nickname|a.real_name|a.mobile', 'like', '%'.$keyword.'%');
 | 
				
			||||||
 | 
					                    })
 | 
				
			||||||
 | 
					                    ->where('a.phone_active', Account::COMMON_ON)
 | 
				
			||||||
 | 
					                    ->order('customer', 'desc')
 | 
				
			||||||
 | 
					                    ->order('shares', 'desc')
 | 
				
			||||||
 | 
					                    ->order('views', 'desc')
 | 
				
			||||||
 | 
					                    ->order('asks', 'desc');
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $items['list'] = $items['list']->each(function ($item) {
 | 
				
			||||||
 | 
					                $item->position = '客户';
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return $this->json(0, '操作成功', $items);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $today          = date('Y-m-d 00:00:00');
 | 
				
			||||||
 | 
					        $count['new']   = Account::where('created_at', '>', $today)->count();
 | 
				
			||||||
 | 
					        $count['total'] = Account::where('phone_active', Account::COMMON_ON)->count();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->data['count'] = $count;
 | 
				
			||||||
 | 
					        return $this->view();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,382 @@
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace app\controller\manager;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use app\exception\RepositoryException;
 | 
				
			||||||
 | 
					use app\model\Account;
 | 
				
			||||||
 | 
					use app\model\Account as AccountModel;
 | 
				
			||||||
 | 
					use app\model\PayMonthLog;
 | 
				
			||||||
 | 
					use app\model\Position;
 | 
				
			||||||
 | 
					use app\model\Worksite;
 | 
				
			||||||
 | 
					use app\repository\AccountRepository;
 | 
				
			||||||
 | 
					use app\service\Math;
 | 
				
			||||||
 | 
					use Exception;
 | 
				
			||||||
 | 
					use think\db\exception\DataNotFoundException;
 | 
				
			||||||
 | 
					use think\db\exception\DbException;
 | 
				
			||||||
 | 
					use think\db\exception\ModelNotFoundException;
 | 
				
			||||||
 | 
					use think\exception\ValidateException;
 | 
				
			||||||
 | 
					use think\facade\Db;
 | 
				
			||||||
 | 
					use think\facade\Log;
 | 
				
			||||||
 | 
					use think\response\Json;
 | 
				
			||||||
 | 
					use think\response\Redirect;
 | 
				
			||||||
 | 
					use think\response\View;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * 工资列表 月
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Class Pay
 | 
				
			||||||
 | 
					 * @package app\controller\manager
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					class Pay extends Base
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    protected $noNeedLogin = ['getAccountList', 'list'];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 详情
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return View
 | 
				
			||||||
 | 
					     * @throws RepositoryException
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function detail(): View
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $id   = input('id/d', 0);
 | 
				
			||||||
 | 
					        $item = PayMonthLog::findById($id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $orderNum                = 0;
 | 
				
			||||||
 | 
					        $orderScoreNum           = 0;
 | 
				
			||||||
 | 
					        $totalPrice              = 0;
 | 
				
			||||||
 | 
					        $totalScore              = 0;
 | 
				
			||||||
 | 
					        $item['total_price']     = Math::fen2Yuan($totalPrice);
 | 
				
			||||||
 | 
					        $item['order_num']       = $orderNum;
 | 
				
			||||||
 | 
					        $item['order_score_num'] = $orderScoreNum;
 | 
				
			||||||
 | 
					        $item['order_newest']    = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->data['item'] = $item;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->view();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 编辑
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return Redirect|Json|View
 | 
				
			||||||
 | 
					     * @throws Exception
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function edit()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $id = input('id/d', 0);
 | 
				
			||||||
 | 
					        if (!$info = PayMonthLog::findById($id)) {
 | 
				
			||||||
 | 
					            if ($this->request->isPost()) {
 | 
				
			||||||
 | 
					                return $this->json(4000, '记录不存在');
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                return $this->error('记录不存在');
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $all = PayMonthLog::where('account_id', $info['account_id'])->where('time', $info['time'])
 | 
				
			||||||
 | 
					            ->fieldRaw('sum(amount) as amount,sum(base_amount) as base_amount,sum(overtime_amount) as overtime_amount')
 | 
				
			||||||
 | 
					            ->find();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $info['amount']          = $all['amount'];
 | 
				
			||||||
 | 
					        $info['base_amount']     = $all['base_amount'];
 | 
				
			||||||
 | 
					        $info['overtime_amount'] = $all['overtime_amount'];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($this->request->isPost()) {
 | 
				
			||||||
 | 
					            $item     = input('post.');
 | 
				
			||||||
 | 
					            $validate = $this->validateByApi($item, [
 | 
				
			||||||
 | 
					                'status' => 'require',
 | 
				
			||||||
 | 
					            ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if ($validate !== true) {
 | 
				
			||||||
 | 
					                return $validate;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            try {
 | 
				
			||||||
 | 
					                PayMonthLog::where('account_id', $info['account_id'])->where('time', $info['time'])->save(['status' => $item['status']]);
 | 
				
			||||||
 | 
					                return $this->json();
 | 
				
			||||||
 | 
					            } catch (ValidateException $e) {
 | 
				
			||||||
 | 
					                return $this->json(4001, $e->getError());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->data['item']    = $info;
 | 
				
			||||||
 | 
					        $this->data['account'] = Account::findById($info['account_id']);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->view();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 单个字段编辑
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return Json
 | 
				
			||||||
 | 
					     * @throws DataNotFoundException
 | 
				
			||||||
 | 
					     * @throws DbException
 | 
				
			||||||
 | 
					     * @throws ModelNotFoundException
 | 
				
			||||||
 | 
					     * @throws Exception
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function modify(): Json
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if ($this->request->isPost()) {
 | 
				
			||||||
 | 
					            $item     = input('post.');
 | 
				
			||||||
 | 
					            $validate = $this->validateByApi($item, [
 | 
				
			||||||
 | 
					                'field' => 'require',
 | 
				
			||||||
 | 
					                'value' => 'require',
 | 
				
			||||||
 | 
					            ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if ($validate !== true) {
 | 
				
			||||||
 | 
					                return $validate;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (!$info = PayMonthLog::findById($item['id'])) {
 | 
				
			||||||
 | 
					                return $this->json(4001, '记录不存在');
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $update = [$item['field'] => $item['value']];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            try {
 | 
				
			||||||
 | 
					                $info->save($update);
 | 
				
			||||||
 | 
					                return $this->json();
 | 
				
			||||||
 | 
					            } catch (ValidateException $e) {
 | 
				
			||||||
 | 
					                return $this->json(4001, $e->getError());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return $this->json(4000, '非法请求');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 列表
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return View|Json
 | 
				
			||||||
 | 
					     * @throws Exception
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function index()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $accountId = input('user_id/d', 0);
 | 
				
			||||||
 | 
					        $worksite  = Worksite::list();
 | 
				
			||||||
 | 
					        $position  = Position::list();
 | 
				
			||||||
 | 
					        if ($this->request->isPost()) {
 | 
				
			||||||
 | 
					            $page         = input('page/d', 1);
 | 
				
			||||||
 | 
					            $size         = input('size/d', 20);
 | 
				
			||||||
 | 
					            $searchParams = input('searchParams');
 | 
				
			||||||
 | 
					            $search       = [];
 | 
				
			||||||
 | 
					            if ($searchParams) {
 | 
				
			||||||
 | 
					                foreach ($searchParams as $key => $param) {
 | 
				
			||||||
 | 
					                    if ($param || $param == '0') {
 | 
				
			||||||
 | 
					                        switch ($key) {
 | 
				
			||||||
 | 
					                            case 'keyword':
 | 
				
			||||||
 | 
					                                $search[] = ['a.nickname|a.real_name|a.mobile', 'like', '%'.$param.'%'];
 | 
				
			||||||
 | 
					                                break;
 | 
				
			||||||
 | 
					                            default:
 | 
				
			||||||
 | 
					                                $search[] = ['pml.'.$key, '=', $param];
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if ($accountId > 0) {
 | 
				
			||||||
 | 
					                $search[] = ['pml.account_id', '=', $accountId];
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            try {
 | 
				
			||||||
 | 
					                $total = 0;
 | 
				
			||||||
 | 
					                $res   = [
 | 
				
			||||||
 | 
					                    'total'   => $total,
 | 
				
			||||||
 | 
					                    'current' => $page ?: 1,
 | 
				
			||||||
 | 
					                    'size'    => $size ?: 20,
 | 
				
			||||||
 | 
					                    'info'    => [],
 | 
				
			||||||
 | 
					                    'list'    => [],
 | 
				
			||||||
 | 
					                ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                $query = PayMonthLog::alias('pml')
 | 
				
			||||||
 | 
					                    ->leftJoin('account a', 'a.id = pml.account_id')
 | 
				
			||||||
 | 
					                    ->where($search);
 | 
				
			||||||
 | 
					                // 汇总信息
 | 
				
			||||||
 | 
					                $info = $query->fieldRaw('sum(pml.amount) as amount, sum(pml.base_amount) as base_amount,
 | 
				
			||||||
 | 
					            sum(pml.overtime_amount) as overtime_amount')->find();
 | 
				
			||||||
 | 
					                // 已发放工资
 | 
				
			||||||
 | 
					                $doneAmount = $query->where('pml.status', 1)->fieldRaw('sum(pml.amount) as amount')->find();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                $res['info'] = [
 | 
				
			||||||
 | 
					                    'amount'          => $info['amount'] ?? 0,
 | 
				
			||||||
 | 
					                    'base_amount'     => $info['base_amount'] ?? 0,
 | 
				
			||||||
 | 
					                    'overtime_amount' => $info['overtime_amount'] ?? 0,
 | 
				
			||||||
 | 
					                    'done_amount'     => $doneAmount['amount'] ?? 0,
 | 
				
			||||||
 | 
					                    'not_amount'      => Math::sub($info['amount'] ?? 0, $doneAmount['amount'] ?? 0),
 | 
				
			||||||
 | 
					                ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                $query = PayMonthLog::alias('pml')
 | 
				
			||||||
 | 
					                    ->leftJoin('account a', 'a.id = pml.account_id')
 | 
				
			||||||
 | 
					                    ->leftJoin('worksite w', 'w.id = a.worksite_id')
 | 
				
			||||||
 | 
					                    ->leftJoin('position p', 'p.id = a.position')
 | 
				
			||||||
 | 
					                    ->where($search)
 | 
				
			||||||
 | 
					                    ->group('account_id,time');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                $total        = $query->count();
 | 
				
			||||||
 | 
					                $res['total'] = $total;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if ($total > 0) {
 | 
				
			||||||
 | 
					                    $res['list'] = $query->field('pml.id,sum(pml.amount) as amount,sum(pml.base_amount) as base_amount,pml.status,pml.year,pml.month,
 | 
				
			||||||
 | 
					                    sum(pml.overtime_amount) as overtime_amount,pml.account_id,pml.time,a.nickname,a.real_name,a.mobile,w.name as worksite_name,
 | 
				
			||||||
 | 
					                    p.name as position_text')
 | 
				
			||||||
 | 
					                        ->page($page, $size)->order('pml.id', 'desc')->select();
 | 
				
			||||||
 | 
					                    $res['list']->each(function ($item) {
 | 
				
			||||||
 | 
					                        $item->status_text = $item->status == 1 ? '已发放' : '待发放';
 | 
				
			||||||
 | 
					                        $item->time_text   = $item->year.'年'.$item->month.'月';
 | 
				
			||||||
 | 
					                    });
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                return $this->json(0, 'success', $res);
 | 
				
			||||||
 | 
					            } catch (RepositoryException $e) {
 | 
				
			||||||
 | 
					                return $this->json(4001, $e->getMessage());
 | 
				
			||||||
 | 
					            } catch (Exception $e) {
 | 
				
			||||||
 | 
					                return $this->json(5001, '获取工资列表失败'.$e->getMessage());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->data['userId']       = $accountId;
 | 
				
			||||||
 | 
					        $this->data['worksiteList'] = $worksite;
 | 
				
			||||||
 | 
					        $this->data['positionList'] = $position;
 | 
				
			||||||
 | 
					        return $this->view();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 获取客户列表
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return Json
 | 
				
			||||||
 | 
					     * @throws DataNotFoundException
 | 
				
			||||||
 | 
					     * @throws DbException
 | 
				
			||||||
 | 
					     * @throws ModelNotFoundException|Exception
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function getAccountList(): Json
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if ($this->request->isPost()) {
 | 
				
			||||||
 | 
					            $keyword = input('keyword/s', '');
 | 
				
			||||||
 | 
					            $page    = input('page/d', 1);
 | 
				
			||||||
 | 
					            $size    = input('size/d', 10);
 | 
				
			||||||
 | 
					            $id      = input('id', '');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $relationIds = explode(',', $id);//已选记录
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $where = [];
 | 
				
			||||||
 | 
					            if (!empty($keyword)) {
 | 
				
			||||||
 | 
					                $where[] = ['nickname|real_name|mobile', 'like', '%'.$keyword.'%'];
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $res = AccountModel::findList($where, ['id', 'nickname', 'real_name', 'mobile'], $page, $size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if ($res['total'] > 0 && $relationIds) {
 | 
				
			||||||
 | 
					                $res['list'] = $res['list']->toArray();
 | 
				
			||||||
 | 
					                foreach ($res['list'] as &$item) {
 | 
				
			||||||
 | 
					                    $item['name_text'] = sprintf("昵称:%s;真实姓名:%s,手机号:%s", $item['nickname'], $item['real_name'], $item['mobile']);
 | 
				
			||||||
 | 
					                    if (count($relationIds) > 0 && in_array($item['id'], $relationIds)) {
 | 
				
			||||||
 | 
					                        $item['selected'] = true;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return $this->json(0, '操作成功', $res);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return $this->json(4001, '非法请求');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 每月工资列表 与index的区别是  index按人与月份的汇总 几个工地的工资都进行了汇总
 | 
				
			||||||
 | 
					     * list则是按每个工地单独统计
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return View|Json
 | 
				
			||||||
 | 
					     * @throws Exception
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function list()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $accountId = input('user_id/d', 0);
 | 
				
			||||||
 | 
					        $time      = input('time/d', 0);
 | 
				
			||||||
 | 
					        $worksite  = Worksite::list();
 | 
				
			||||||
 | 
					        $position  = Position::list();
 | 
				
			||||||
 | 
					        if ($this->request->isPost()) {
 | 
				
			||||||
 | 
					            $page         = input('page/d', 1);
 | 
				
			||||||
 | 
					            $size         = input('size/d', 20);
 | 
				
			||||||
 | 
					            $searchParams = input('searchParams');
 | 
				
			||||||
 | 
					            $search       = [];
 | 
				
			||||||
 | 
					            if ($searchParams) {
 | 
				
			||||||
 | 
					                foreach ($searchParams as $key => $param) {
 | 
				
			||||||
 | 
					                    if ($param || $param == '0') {
 | 
				
			||||||
 | 
					                        switch ($key) {
 | 
				
			||||||
 | 
					                            case 'keyword':
 | 
				
			||||||
 | 
					                                $search[] = ['a.nickname|a.real_name|a.mobile', 'like', '%'.$param.'%'];
 | 
				
			||||||
 | 
					                                break;
 | 
				
			||||||
 | 
					                            default:
 | 
				
			||||||
 | 
					                                $search[] = ['pml.'.$key, '=', $param];
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if ($accountId > 0) {
 | 
				
			||||||
 | 
					                $search[] = ['pml.account_id', '=', $accountId];
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if ($time > 0) {
 | 
				
			||||||
 | 
					                $search[] = ['pml.time', '=', $time];
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            try {
 | 
				
			||||||
 | 
					                $total = 0;
 | 
				
			||||||
 | 
					                $res   = [
 | 
				
			||||||
 | 
					                    'total'   => $total,
 | 
				
			||||||
 | 
					                    'current' => $page ?: 1,
 | 
				
			||||||
 | 
					                    'size'    => $size ?: 20,
 | 
				
			||||||
 | 
					                    'info'    => [],
 | 
				
			||||||
 | 
					                    'list'    => [],
 | 
				
			||||||
 | 
					                ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                $query = PayMonthLog::alias('pml')
 | 
				
			||||||
 | 
					                    ->leftJoin('account a', 'a.id = pml.account_id')
 | 
				
			||||||
 | 
					                    ->where($search);
 | 
				
			||||||
 | 
					                // 汇总信息
 | 
				
			||||||
 | 
					                $info = $query->fieldRaw('sum(pml.amount) as amount, sum(pml.base_amount) as base_amount,
 | 
				
			||||||
 | 
					            sum(pml.overtime_amount) as overtime_amount')->find();
 | 
				
			||||||
 | 
					                // 已发放工资
 | 
				
			||||||
 | 
					                $doneAmount = $query->where('pml.status', 1)->fieldRaw('sum(pml.amount) as amount')->find();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                $res['info'] = [
 | 
				
			||||||
 | 
					                    'amount'          => $info['amount'] ?? 0,
 | 
				
			||||||
 | 
					                    'base_amount'     => $info['base_amount'] ?? 0,
 | 
				
			||||||
 | 
					                    'overtime_amount' => $info['overtime_amount'] ?? 0,
 | 
				
			||||||
 | 
					                    'done_amount'     => $doneAmount['amount'] ?? 0,
 | 
				
			||||||
 | 
					                    'not_amount'      => Math::sub($info['amount'] ?? 0, $doneAmount['amount'] ?? 0),
 | 
				
			||||||
 | 
					                ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                $query = PayMonthLog::alias('pml')
 | 
				
			||||||
 | 
					                    ->leftJoin('account a', 'a.id = pml.account_id')
 | 
				
			||||||
 | 
					                    ->leftJoin('worksite w', 'w.id = pml.worksite_id')//注意此处需要使用pml表
 | 
				
			||||||
 | 
					                    ->leftJoin('position p', 'p.id = a.position')
 | 
				
			||||||
 | 
					                    ->where($search);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                $total        = $query->count();
 | 
				
			||||||
 | 
					                $res['total'] = $total;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if ($total > 0) {
 | 
				
			||||||
 | 
					                    $res['list'] = $query->field('pml.*,a.nickname,a.real_name,a.mobile,w.name as worksite_name,
 | 
				
			||||||
 | 
					                    p.name as position_text')
 | 
				
			||||||
 | 
					                        ->page($page, $size)->order('pml.id', 'desc')->select();
 | 
				
			||||||
 | 
					                    $res['list']->each(function ($item) {
 | 
				
			||||||
 | 
					                        $item->status_text = $item->status == 1 ? '已发放' : '待发放';
 | 
				
			||||||
 | 
					                        $item->time_text   = $item->year.'年'.$item->month.'月';
 | 
				
			||||||
 | 
					                    });
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                return $this->json(0, 'success', $res);
 | 
				
			||||||
 | 
					            } catch (RepositoryException $e) {
 | 
				
			||||||
 | 
					                return $this->json(4001, $e->getMessage());
 | 
				
			||||||
 | 
					            } catch (Exception $e) {
 | 
				
			||||||
 | 
					                return $this->json(5001, '获取工资列表2失败'.$e->getMessage());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->data['userId']       = $accountId;
 | 
				
			||||||
 | 
					        $this->data['time']         = $time;
 | 
				
			||||||
 | 
					        $this->data['worksiteList'] = $worksite;
 | 
				
			||||||
 | 
					        $this->data['positionList'] = $position;
 | 
				
			||||||
 | 
					        return $this->view();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,204 @@
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					declare (strict_types = 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace app\controller\manager;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use Exception;
 | 
				
			||||||
 | 
					use app\model\Log;
 | 
				
			||||||
 | 
					use think\Collection;
 | 
				
			||||||
 | 
					use think\response\View;
 | 
				
			||||||
 | 
					use think\response\Json;
 | 
				
			||||||
 | 
					use think\db\exception\DbException;
 | 
				
			||||||
 | 
					use think\exception\ValidateException;
 | 
				
			||||||
 | 
					use think\db\exception\DataNotFoundException;
 | 
				
			||||||
 | 
					use think\db\exception\ModelNotFoundException;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Position extends Base
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    protected $noNeedLogin = ['index', 'add', 'edit', 'del', 'modify'];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 列表
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @throws Exception
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function index()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if ($this->request->isPost()) {
 | 
				
			||||||
 | 
					            $params = input('searchParams/a');
 | 
				
			||||||
 | 
					            $page   = input('page/d', 1);
 | 
				
			||||||
 | 
					            $size   = input('size/d', 20);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $where = [];
 | 
				
			||||||
 | 
					            if (!empty($params)) {
 | 
				
			||||||
 | 
					                foreach ($params as $key => $param) {
 | 
				
			||||||
 | 
					                    $param = trim($param);
 | 
				
			||||||
 | 
					                    if ($key == 'keyword') {
 | 
				
			||||||
 | 
					                        $where[] = ['name', 'like', '%'.$param.'%'];
 | 
				
			||||||
 | 
					                        continue;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    if ($param == '0' || !empty($param)) {
 | 
				
			||||||
 | 
					                        $where[] = [$key, 'like', '%'.$param.'%'];
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $query = \app\model\Position::where($where);
 | 
				
			||||||
 | 
					            $total = $query->count();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $res = [
 | 
				
			||||||
 | 
					                'total'   => $total,
 | 
				
			||||||
 | 
					                'current' => $page ?: 1,
 | 
				
			||||||
 | 
					                'size'    => $size ?: 20,
 | 
				
			||||||
 | 
					                'list'    => new Collection(),
 | 
				
			||||||
 | 
					            ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if ($total > 0) {
 | 
				
			||||||
 | 
					                $res['list'] = $query->page($page, $size)->order('sort', 'desc')->order('id', 'desc')->select();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return $this->json(0, 'success', $res);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->view();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 添加
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return Json|View
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function add()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if ($this->request->isPost()) {
 | 
				
			||||||
 | 
					            try {
 | 
				
			||||||
 | 
					                $input = input('post.');
 | 
				
			||||||
 | 
					                if (!isset($input['name'])) {
 | 
				
			||||||
 | 
					                    return $this->json(4000, '参数错误');
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                \app\model\Position::create([
 | 
				
			||||||
 | 
					                    'name' => $input['name'] ?? '',
 | 
				
			||||||
 | 
					                ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                return $this->json();
 | 
				
			||||||
 | 
					            } catch (Exception $e) {
 | 
				
			||||||
 | 
					                return $this->json(4001, '添加失败'.$e->getMessage());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->view();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 编辑
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return \think\response\Json|\think\response\View
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function edit()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $id = input('id');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //通过ID查询
 | 
				
			||||||
 | 
					        $item = \app\model\Position::where('id', (int)$id)->find();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (empty($item)) {
 | 
				
			||||||
 | 
					            return $this->json(4000, '没有相关记录!');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($this->request->isPost()) {
 | 
				
			||||||
 | 
					            try {
 | 
				
			||||||
 | 
					                $input = input('post.');
 | 
				
			||||||
 | 
					                if (!isset($input['name'])) {
 | 
				
			||||||
 | 
					                    return $this->json(4000, '参数错误');
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                $item->save([
 | 
				
			||||||
 | 
					                    'name' => $input['name'] ?? '',
 | 
				
			||||||
 | 
					                ]);
 | 
				
			||||||
 | 
					                return $this->json();
 | 
				
			||||||
 | 
					            } catch (Exception $e) {
 | 
				
			||||||
 | 
					                return $this->json(5000, $e->getMessage());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->data['item'] = $item;
 | 
				
			||||||
 | 
					        $this->data['id']   = $id;
 | 
				
			||||||
 | 
					        return $this->view();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 更新属性
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @throws ModelNotFoundException
 | 
				
			||||||
 | 
					     * @throws DbException
 | 
				
			||||||
 | 
					     * @throws DataNotFoundException
 | 
				
			||||||
 | 
					     * @throws Exception
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function modify()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (!$this->request->isPost()) {
 | 
				
			||||||
 | 
					            return $this->json(4000, '非法请求');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $item     = input('post.');
 | 
				
			||||||
 | 
					        $validate = $this->validateByApi($item, [
 | 
				
			||||||
 | 
					            'field' => 'require',
 | 
				
			||||||
 | 
					            'value' => 'require',
 | 
				
			||||||
 | 
					        ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($validate !== true) {
 | 
				
			||||||
 | 
					            return $validate;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // 通过ID查询
 | 
				
			||||||
 | 
					        if (!$info = \app\model\Position::where('id', (int)$item['id'])->find()) {
 | 
				
			||||||
 | 
					            return $this->json(4001, '记录不存在');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $update = [$item['field'] => $item['value']];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            $info->save($update);
 | 
				
			||||||
 | 
					            return $this->json();
 | 
				
			||||||
 | 
					        } catch (ValidateException $e) {
 | 
				
			||||||
 | 
					            return $this->json(4001, $e->getError());
 | 
				
			||||||
 | 
					        } catch (Exception $e) {
 | 
				
			||||||
 | 
					            return $this->json(5000, '修改失败');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 删除
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return \think\response\Json
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function del(): Json
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (!$this->request->isPost()) {
 | 
				
			||||||
 | 
					            return $this->json(4000, '非法请求');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $ids = $this->request->param('ids/a', []);
 | 
				
			||||||
 | 
					        if (empty($ids)) {
 | 
				
			||||||
 | 
					            $ids[] = $this->request->param('id/d', 0);
 | 
				
			||||||
 | 
					            $ids   = array_filter($ids);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            if (count($ids)) {
 | 
				
			||||||
 | 
					                //删除逻辑
 | 
				
			||||||
 | 
					                if (\app\model\Account::whereIn('position', $ids)->count() > 0) {
 | 
				
			||||||
 | 
					                    return $this->json(4000, '所选岗位已分配给用户,请先移除后再删除');
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                \app\model\Position::whereIn('id', $ids)->delete();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                Log::write(get_class(), 'del', '删除操作,涉及到的ID为:'.implode(',', $ids));
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        } catch (Exception $e) {
 | 
				
			||||||
 | 
					            return $this->json(5000, $e->getMessage());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->json();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,277 @@
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace app\controller\manager;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use app\model\Log;
 | 
				
			||||||
 | 
					use app\model\Menu;
 | 
				
			||||||
 | 
					use app\model\Menu as MenuModel;
 | 
				
			||||||
 | 
					use app\model\Role as RoleModel;
 | 
				
			||||||
 | 
					use app\model\Rules;
 | 
				
			||||||
 | 
					use app\repository\CmsRepository;
 | 
				
			||||||
 | 
					use Exception;
 | 
				
			||||||
 | 
					use think\db\exception\DataNotFoundException;
 | 
				
			||||||
 | 
					use think\db\exception\DbException;
 | 
				
			||||||
 | 
					use think\db\exception\ModelNotFoundException;
 | 
				
			||||||
 | 
					use think\exception\ValidateException;
 | 
				
			||||||
 | 
					use think\facade\Db;
 | 
				
			||||||
 | 
					use think\response\Json;
 | 
				
			||||||
 | 
					use think\response\View;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * 角色管理
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Class Role
 | 
				
			||||||
 | 
					 * @package app\controller\manager
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					class Role extends Base
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 删除
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return Json
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function del(): Json
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if ($this->request->isPost()) {
 | 
				
			||||||
 | 
					            $ids = input('post.ids/a', []);
 | 
				
			||||||
 | 
					            if (empty($ids)) {
 | 
				
			||||||
 | 
					                $ids[] = input('post.id/d');
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            RoleModel::deleteByIds($ids);
 | 
				
			||||||
 | 
					            Log::write(get_class().'Del', 'del', '涉及到的ID为:'.implode(',', $ids));
 | 
				
			||||||
 | 
					            return $this->json();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return $this->json(4001, '非法请求!');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 编辑
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return Json|View
 | 
				
			||||||
 | 
					     * @throws DataNotFoundException
 | 
				
			||||||
 | 
					     * @throws DbException
 | 
				
			||||||
 | 
					     * @throws ModelNotFoundException
 | 
				
			||||||
 | 
					     * @throws Exception
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function edit()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $id = input('id/d', 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!$info = RoleModel::findById($id)) {
 | 
				
			||||||
 | 
					            return $this->json(4001, '记录不存在');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($this->request->isPost()) {
 | 
				
			||||||
 | 
					            $item     = input('post.');
 | 
				
			||||||
 | 
					            $validate = $this->validateByApi($item, [
 | 
				
			||||||
 | 
					                'title' => 'require',
 | 
				
			||||||
 | 
					            ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if ($validate !== true) {
 | 
				
			||||||
 | 
					                return $validate;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            try {
 | 
				
			||||||
 | 
					                $info->save($item);
 | 
				
			||||||
 | 
					                return $this->json();
 | 
				
			||||||
 | 
					            } catch (ValidateException $e) {
 | 
				
			||||||
 | 
					                return $this->json(4001, $e->getError());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->data['item'] = $info;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->view();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 单个字段编辑
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return Json
 | 
				
			||||||
 | 
					     * @throws DataNotFoundException
 | 
				
			||||||
 | 
					     * @throws DbException
 | 
				
			||||||
 | 
					     * @throws ModelNotFoundException
 | 
				
			||||||
 | 
					     * @throws Exception
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function modify(): Json
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if ($this->request->isPost()) {
 | 
				
			||||||
 | 
					            $item     = input('post.');
 | 
				
			||||||
 | 
					            $validate = $this->validateByApi($item, [
 | 
				
			||||||
 | 
					                'field' => 'require',
 | 
				
			||||||
 | 
					                'value' => 'require',
 | 
				
			||||||
 | 
					            ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if ($validate !== true) {
 | 
				
			||||||
 | 
					                return $validate;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (!$info = RoleModel::findById($item['id'])) {
 | 
				
			||||||
 | 
					                return $this->json(4001, '记录不存在');
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $update = [$item['field'] => $item['value']];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            try {
 | 
				
			||||||
 | 
					                $info->save($update);
 | 
				
			||||||
 | 
					                return $this->json();
 | 
				
			||||||
 | 
					            } catch (ValidateException $e) {
 | 
				
			||||||
 | 
					                return $this->json(4001, $e->getError());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return $this->json(4000, '非法请求');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 添加
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return Json|View
 | 
				
			||||||
 | 
					     * @throws Exception
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function add()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if ($this->request->isPost()) {
 | 
				
			||||||
 | 
					            $item = input('post.');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $validate = $this->validateByApi($item, [
 | 
				
			||||||
 | 
					                'title' => 'require',
 | 
				
			||||||
 | 
					            ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if ($validate !== true) {
 | 
				
			||||||
 | 
					                return $validate;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            try {
 | 
				
			||||||
 | 
					                RoleModel::create($item);
 | 
				
			||||||
 | 
					                return $this->json();
 | 
				
			||||||
 | 
					            } catch (ValidateException $e) {
 | 
				
			||||||
 | 
					                return $this->json(4001, $e->getError());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->view();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 角色权限
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return Json|View
 | 
				
			||||||
 | 
					     * @throws Exception
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function rule()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $id = input('id/d', 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!$item = RoleModel::findById($id)) {
 | 
				
			||||||
 | 
					            return $this->json(4001, '记录不存在');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($this->request->isPost()) {
 | 
				
			||||||
 | 
					            $ids    = input('post.ids');
 | 
				
			||||||
 | 
					            $roleUpdate = $ids;//角色更新数据
 | 
				
			||||||
 | 
					            $ids    = explode(',', $ids);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            Db::startTrans();
 | 
				
			||||||
 | 
					            try {
 | 
				
			||||||
 | 
					                //查询角色已有权限
 | 
				
			||||||
 | 
					                $hasRules = Rules::where('ptype', 'p')->where('v0', $id)->select()->toArray();
 | 
				
			||||||
 | 
					                //角色最新权限列表
 | 
				
			||||||
 | 
					                $currentRules = MenuModel::where('id', 'in', $ids)->field('name')->select()->toArray();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                foreach ($currentRules as &$rule) {
 | 
				
			||||||
 | 
					                    $route = explode(':', $rule['name']);
 | 
				
			||||||
 | 
					                    $v1 = $route[0];
 | 
				
			||||||
 | 
					                    $v2 = $route[1] ?? 'index';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    $rule['ptype'] = 'p';
 | 
				
			||||||
 | 
					                    $rule['v0'] = $id;
 | 
				
			||||||
 | 
					                    $rule['v1'] = $v1;
 | 
				
			||||||
 | 
					                    $rule['v2'] = $v2;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                foreach ($hasRules as $k => $has) {
 | 
				
			||||||
 | 
					                    foreach ($currentRules as $m => $current) {
 | 
				
			||||||
 | 
					                        if ($has['ptype'] == $current['ptype'] && $has['v0'] == $current['v0'] && $has['v1'] == $current['v1'] && $has['v2'] == $current['v2']) {
 | 
				
			||||||
 | 
					                            unset($currentRules[$m]);//删除当前权限列表已存在的 currentRules剩下的就是需要添加的记录
 | 
				
			||||||
 | 
					                            unset($hasRules[$k]);//删除已有权限中存在的 hasRules剩下的就是需要删除的记录
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                $insert = $currentRules;//需要添加的数据
 | 
				
			||||||
 | 
					                $delete = $hasRules;//需要删除的数据
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                $deleteIds = array_column($delete, 'id');//需要删除的ID
 | 
				
			||||||
 | 
					                (new Rules())->saveAll($insert);
 | 
				
			||||||
 | 
					                (new Rules())->where('id', 'in', $deleteIds)->delete();
 | 
				
			||||||
 | 
					                cache('tauthz', null);//权限缓存清空
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                $item->save(['rules' => $roleUpdate]);
 | 
				
			||||||
 | 
					                Db::commit();
 | 
				
			||||||
 | 
					                return $this->json();
 | 
				
			||||||
 | 
					            } catch (ValidateException $e) {
 | 
				
			||||||
 | 
					                Db::rollback();
 | 
				
			||||||
 | 
					                return $this->json(4001, $e->getError());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $selected = explode(',', $item['rules']);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->data['authJson'] = $this->authJson($selected);
 | 
				
			||||||
 | 
					        $this->data['item']     = $item;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->view();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 构造json数据
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param  array  $selected
 | 
				
			||||||
 | 
					     * @return false|string
 | 
				
			||||||
 | 
					     * @throws DataNotFoundException
 | 
				
			||||||
 | 
					     * @throws DbException
 | 
				
			||||||
 | 
					     * @throws ModelNotFoundException
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    private function authJson(array $selected = [])
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $username = session('auth')['username'] ?? '';//非超级管理员admin 部分展示权限
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $menus = Menu::field("id,pid,title,sort")
 | 
				
			||||||
 | 
					            ->where('status', Menu::STATUS_NORMAL)
 | 
				
			||||||
 | 
					            ->when($username != 'admin', function ($q) {
 | 
				
			||||||
 | 
					                $q->where('show_role', 1);
 | 
				
			||||||
 | 
					            })
 | 
				
			||||||
 | 
					            ->order('sort', 'desc')
 | 
				
			||||||
 | 
					            ->order('id', 'asc')
 | 
				
			||||||
 | 
					            ->select()->toArray();
 | 
				
			||||||
 | 
					        foreach ($menus as $k => $m) {
 | 
				
			||||||
 | 
					            $menus[$k]['checked'] = in_array($m['id'], $selected);
 | 
				
			||||||
 | 
					            $menus[$k]['open']    = true;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        $menus = CmsRepository::getInstance()->buildMenuChild(0, $menus);
 | 
				
			||||||
 | 
					        return json_encode($menus, JSON_UNESCAPED_UNICODE);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 列表
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return View|Json
 | 
				
			||||||
 | 
					     * @throws Exception
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function index()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if ($this->request->isPost()) {
 | 
				
			||||||
 | 
					            $page  = input('page/d', 1);
 | 
				
			||||||
 | 
					            $limit = input('size/d', 20);
 | 
				
			||||||
 | 
					            $items = RoleModel::findList([], [], $page, $limit, function ($q) {
 | 
				
			||||||
 | 
					                return $q->order('sort', 'desc')->order('id', 'asc');
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return $this->json(0, '操作成功', $items);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->data['username'] = $this->auth['username'] ?? '';
 | 
				
			||||||
 | 
					        return $this->view();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,282 @@
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace app\controller\manager;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use app\model\Log;
 | 
				
			||||||
 | 
					use app\repository\CmsRepository;
 | 
				
			||||||
 | 
					use app\repository\OperationRepository;
 | 
				
			||||||
 | 
					use app\validate\Slide as VSlide;
 | 
				
			||||||
 | 
					use Exception;
 | 
				
			||||||
 | 
					use think\db\exception\DataNotFoundException;
 | 
				
			||||||
 | 
					use think\db\exception\DbException;
 | 
				
			||||||
 | 
					use think\db\exception\ModelNotFoundException;
 | 
				
			||||||
 | 
					use think\exception\ValidateException;
 | 
				
			||||||
 | 
					use think\response\Json;
 | 
				
			||||||
 | 
					use think\response\View;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Slide extends Base
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 编辑
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return Json|View
 | 
				
			||||||
 | 
					     * @throws DbException
 | 
				
			||||||
 | 
					     * @throws ModelNotFoundException
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function edit()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $id = $this->request->param('id/d', 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!$slide = OperationRepository::getInstance()->findSlideById($id)) {
 | 
				
			||||||
 | 
					            return $this->json(4001, '数据不存在');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($this->request->isPost()) {
 | 
				
			||||||
 | 
					            $item     = input('post.item/a');
 | 
				
			||||||
 | 
					            $validate = new VSlide();
 | 
				
			||||||
 | 
					            if (!$validate->scene('slide')->check($item)) {
 | 
				
			||||||
 | 
					                return $this->json(4002, $validate->getError());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            unset($item['id']);
 | 
				
			||||||
 | 
					            OperationRepository::getInstance()->updateSlide($item, $id);
 | 
				
			||||||
 | 
					            event('UpdateBanner');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return $this->json();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->data['item'] = $slide;
 | 
				
			||||||
 | 
					        $this->data['positionsJson']    = $this->xmSelectPositionsJson([$slide['position']]);
 | 
				
			||||||
 | 
					        $this->data['id']   = $id;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->view();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 添加
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return View|Json
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function add()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $repo = OperationRepository::getInstance();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($this->request->isPost()) {
 | 
				
			||||||
 | 
					            $item     = input('post.item/a');
 | 
				
			||||||
 | 
					            $validate = new VSlide();
 | 
				
			||||||
 | 
					            if (!$validate->scene('slide')->check($item)) {
 | 
				
			||||||
 | 
					                return $this->json(4002, $validate->getError());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $item['type']       = $item['type'] ?? 'img';
 | 
				
			||||||
 | 
					            $repo->createSlide($item);
 | 
				
			||||||
 | 
					            event('UpdateBanner');
 | 
				
			||||||
 | 
					            return $this->json();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->data['positionsJson']    = $this->xmSelectPositionsJson();
 | 
				
			||||||
 | 
					        return $this->view();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 轮播图列表
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return Json|View
 | 
				
			||||||
 | 
					     * @throws Exception
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function index()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $repo = OperationRepository::getInstance();
 | 
				
			||||||
 | 
					        if ($this->request->isPost()) {
 | 
				
			||||||
 | 
					            $position   = $this->request->param('position/s', '');
 | 
				
			||||||
 | 
					            $page       = $this->request->param('page/d', 1);
 | 
				
			||||||
 | 
					            $size       = $this->request->param('size/d', 30);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $whereMap   = [];
 | 
				
			||||||
 | 
					            $orders     = ['sort'=>'asc'];
 | 
				
			||||||
 | 
					            if (!empty($position)) {
 | 
				
			||||||
 | 
					                $whereMap[] = ['position', '=', $position];
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $list = $repo->slideList($whereMap, [], $page, $size, null, $orders);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return $this->json(0, 'success', $list);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->data['positions'] = $repo->slidePositions();
 | 
				
			||||||
 | 
					        return $this->view();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 排序
 | 
				
			||||||
 | 
					     * @return Json
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function sort()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (!$this->request->isPost()) {
 | 
				
			||||||
 | 
					            return $this->json(4000, '非法请求');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            $id     = $this->request->param('id/d', 0);
 | 
				
			||||||
 | 
					            $sort   = $this->request->param('sort/d', 0);
 | 
				
			||||||
 | 
					            OperationRepository::getInstance()->updateSlide(['sort'=>$sort], $id);
 | 
				
			||||||
 | 
					            event('UpdateBanner');
 | 
				
			||||||
 | 
					        } catch (Exception $e) {
 | 
				
			||||||
 | 
					            return $this->json(4001, '排序失败');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return $this->json();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 删除
 | 
				
			||||||
 | 
					     * @return Json
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function del()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (!$this->request->isPost()) {
 | 
				
			||||||
 | 
					            return $this->json(4000, '非法请求');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $ids = $this->request->param('ids/a', []);
 | 
				
			||||||
 | 
					        if (empty($ids)) {
 | 
				
			||||||
 | 
					            $ids[] = $this->request->param('id/d', 0);
 | 
				
			||||||
 | 
					            $ids = array_filter($ids);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (count($ids)) {
 | 
				
			||||||
 | 
					            OperationRepository::getInstance()->deleteSlides($ids);
 | 
				
			||||||
 | 
					            event('UpdateBanner');
 | 
				
			||||||
 | 
					            Log::write(get_class(), 'del', '删除了轮播图,涉及到的ID为:'.implode(',', $ids));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return $this->json();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 显示位置下拉选项数据
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param array $selected
 | 
				
			||||||
 | 
					     * @param array $disabled
 | 
				
			||||||
 | 
					     * @return false|string
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    private function xmSelectPositionsJson(array $selected = [], array $disabled = [])
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $positionList = OperationRepository::getInstance()->slidePositions();
 | 
				
			||||||
 | 
					        foreach ($positionList as $k => $item) {
 | 
				
			||||||
 | 
					            $positionList[$k]['selected'] = in_array($item['key'], $selected);
 | 
				
			||||||
 | 
					            $positionList[$k]['disabled'] = in_array($item['key'], $disabled);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        $positionList = CmsRepository::getInstance()->handleSelectedList($positionList);
 | 
				
			||||||
 | 
					        return json_encode($positionList, JSON_UNESCAPED_UNICODE);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 轮播图显示位置管理
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function position()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $repo = OperationRepository::getInstance();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($this->request->isPost()) {
 | 
				
			||||||
 | 
					            $list = $repo->slidePositionList([], [], 1, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return $this->json(0, 'success', $list);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return $this->view();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 添加显示位置信息
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return Json|View
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function addPosition()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $repo = OperationRepository::getInstance();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($this->request->isPost()) {
 | 
				
			||||||
 | 
					            $item     = input('post.item/a');
 | 
				
			||||||
 | 
					            try {
 | 
				
			||||||
 | 
					                $this->validate($item, [
 | 
				
			||||||
 | 
					                    'title|标题' => 'max:250',
 | 
				
			||||||
 | 
					                    'key|位置标识' => 'require|max:100|alphaDash'
 | 
				
			||||||
 | 
					                ]);
 | 
				
			||||||
 | 
					            } catch (ValidateException $e) {
 | 
				
			||||||
 | 
					                return $this->json(4002, $e->getError());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if ($repo->slidePositionExists($item['key'])) {
 | 
				
			||||||
 | 
					                return $this->json(4003, '当前位置标识已存在!');
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $repo->createSlidePosition($item);
 | 
				
			||||||
 | 
					            return $this->json();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->view();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 编辑显示位置信息
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return Json|View
 | 
				
			||||||
 | 
					     * @throws DbException
 | 
				
			||||||
 | 
					     * @throws ModelNotFoundException
 | 
				
			||||||
 | 
					     * @throws DataNotFoundException
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function editPosition()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $id = $this->request->param('id/d', 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!$position = OperationRepository::getInstance()->findSlidePositionById($id)) {
 | 
				
			||||||
 | 
					            return $this->json(4001, '数据不存在');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($this->request->isPost()) {
 | 
				
			||||||
 | 
					            $item     = input('post.item/a');
 | 
				
			||||||
 | 
					            try {
 | 
				
			||||||
 | 
					                $this->validate($item, [
 | 
				
			||||||
 | 
					                    'title|标题' => 'max:250'
 | 
				
			||||||
 | 
					                ]);
 | 
				
			||||||
 | 
					            } catch (ValidateException $e) {
 | 
				
			||||||
 | 
					                return $this->json(4002, $e->getError());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            unset($item['id']);
 | 
				
			||||||
 | 
					            unset($item['key']);
 | 
				
			||||||
 | 
					            OperationRepository::getInstance()->updateSlidePosition($item, $id);
 | 
				
			||||||
 | 
					            return $this->json();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->data['item'] = $position;
 | 
				
			||||||
 | 
					        $this->data['id']   = $id;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->view();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 删除显示位置信息
 | 
				
			||||||
 | 
					     * @return Json
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function delPosition()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (!$this->request->isPost()) {
 | 
				
			||||||
 | 
					            return $this->json(4000, '非法请求');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $ids = $this->request->param('ids/a', []);
 | 
				
			||||||
 | 
					        if (empty($ids)) {
 | 
				
			||||||
 | 
					            $ids[] = $this->request->param('id/d', 0);
 | 
				
			||||||
 | 
					            $ids = array_filter($ids);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (count($ids)) {
 | 
				
			||||||
 | 
					            OperationRepository::getInstance()->deleteSlidePositions($ids);
 | 
				
			||||||
 | 
					            Log::write(get_class(), 'delPosition', '删除了轮播显示位置,涉及到的ID为:'.implode(',', $ids));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->json();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,63 @@
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace app\controller\manager;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use app\service\Tool;
 | 
				
			||||||
 | 
					use app\model\{System as MSystem, Log};
 | 
				
			||||||
 | 
					use app\service\Image;
 | 
				
			||||||
 | 
					use think\facade\Cache;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class System extends Base
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 获取当前系统设置
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return void
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function index()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if ($this->request->isPost()) {
 | 
				
			||||||
 | 
					            $item = input('post.item/a');
 | 
				
			||||||
 | 
					            $img  = input('post.img');
 | 
				
			||||||
 | 
					            $system = MSystem::getSystem();
 | 
				
			||||||
 | 
					            if (empty($system)) {
 | 
				
			||||||
 | 
					                if(!empty($img)){
 | 
				
			||||||
 | 
					                    $item['mark_img'] = $img;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                $system = MSystem::create($item);
 | 
				
			||||||
 | 
					                Log::write('system', 'index', "系统设置,ID:{$system->id}");
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                if (!empty($img)) {
 | 
				
			||||||
 | 
					                    Image::delImg($system['mark_img']);
 | 
				
			||||||
 | 
					                    $item['mark_img'] = $img;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                MSystem::update($item, ['id' => $system['id']]);
 | 
				
			||||||
 | 
					                Log::write('system', 'index', "系统设置,ID:{$system['id']}");
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            return $this->json();
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            $item = MSystem::getSystem();
 | 
				
			||||||
 | 
					            $positions = Image::getMarkPosition();
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            $this->data['item'] = $item;
 | 
				
			||||||
 | 
					            $this->data['positions'] = $positions;
 | 
				
			||||||
 | 
					            return $this->view();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function other()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return $this->view();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function clearCache()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        Cache::clear();
 | 
				
			||||||
 | 
					        $cachePath = app()->getRuntimePath().'cache';
 | 
				
			||||||
 | 
					        $tempPath = app()->getRuntimePath().'temp';
 | 
				
			||||||
 | 
					        Tool::removeByPath($cachePath);
 | 
				
			||||||
 | 
					        Tool::removeByPath($tempPath);
 | 
				
			||||||
 | 
					        clearstatcache();
 | 
				
			||||||
 | 
					        return $this->json();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,230 @@
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace app\controller\manager;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use app\exception\RepositoryException;
 | 
				
			||||||
 | 
					use app\service\Image;
 | 
				
			||||||
 | 
					use app\model\{System, File};
 | 
				
			||||||
 | 
					use app\validate\Upload as VUpload;
 | 
				
			||||||
 | 
					use think\facade\{Filesystem, Config, Lang};
 | 
				
			||||||
 | 
					use think\Image as TImage;
 | 
				
			||||||
 | 
					use app\controller\BaseController;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Upload extends BaseController
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    protected $noNeedLogin = ['video', 'file', 'image', 'wangImage'];
 | 
				
			||||||
 | 
					    private $isCompress = true;
 | 
				
			||||||
 | 
					    private $validate;
 | 
				
			||||||
 | 
					    private $uploadPath;
 | 
				
			||||||
 | 
					    private $videoUploadPath;
 | 
				
			||||||
 | 
					    private $uploadPathIsWritable = 0;
 | 
				
			||||||
 | 
					    private $videoUploadPathIsWritable = 0;
 | 
				
			||||||
 | 
					    private $DIRECTORY_SEPARATOR = "/";
 | 
				
			||||||
 | 
					    public function initialize()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $system = System::getSystem();
 | 
				
			||||||
 | 
					        if (!empty($system)) {
 | 
				
			||||||
 | 
					            $this->isCompress = $system['compress'] ?? true;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        $this->validate        = new VUpload();
 | 
				
			||||||
 | 
					        $this->uploadPath      = Config::get('filesystem.disks.local.url');
 | 
				
			||||||
 | 
					        $this->videoUploadPath = Config::get('filesystem.disks.video.url');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!is_writable(app()->getRootPath().'public'.$this->uploadPath)) {
 | 
				
			||||||
 | 
					            mkdir(app()->getRootPath().'public'.$this->uploadPath, 0777, true);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        $this->uploadPathIsWritable = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!is_writable(app()->getRootPath().'public'.$this->videoUploadPath)) {
 | 
				
			||||||
 | 
					            mkdir(app()->getRootPath().'public'.$this->videoUploadPath, 0777,true);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        $this->videoUploadPathIsWritable = 1;
 | 
				
			||||||
 | 
					        $this->DIRECTORY_SEPARATOR = DIRECTORY_SEPARATOR == "\\" ? "/" : DIRECTORY_SEPARATOR;
 | 
				
			||||||
 | 
					        ini_set('max_execution_time', '0');
 | 
				
			||||||
 | 
					        ini_set("memory_limit", '-1');
 | 
				
			||||||
 | 
					        set_time_limit(0);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    //视频上传
 | 
				
			||||||
 | 
					    public function video()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $video = request()->file('video_video');
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            if ($this->validate->checkVideo($video)) {
 | 
				
			||||||
 | 
					                if (!$this->videoUploadPathIsWritable) {
 | 
				
			||||||
 | 
					                    throw new \Exception('上传文件夹需要写入权限');
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                $md5 = $video->md5();//文件md5
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                $path    = request()->param('path/s', '');//指定路径 基于public下  若为空则默认
 | 
				
			||||||
 | 
					                $hasPath = !empty($path);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                // 去除以/storage/开头的部分  如/storage/20210808/test => 20210808/test
 | 
				
			||||||
 | 
					                $path     = ltrim(trim($path, $this->DIRECTORY_SEPARATOR), \app\model\Attachment::ROOT_NAME.$this->DIRECTORY_SEPARATOR);
 | 
				
			||||||
 | 
					                $datePath = $hasPath ? $path : 'videos'.$this->DIRECTORY_SEPARATOR.date('Ym');//自定义目录
 | 
				
			||||||
 | 
					                $src      = Filesystem::putFile($datePath, $video, 'uniqid');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                $src = $this->uploadPath.'/'.$src;
 | 
				
			||||||
 | 
					                $return['src'] = $src;
 | 
				
			||||||
 | 
					                File::add($video, $src, $md5, 'video');    //加入上传文件表
 | 
				
			||||||
 | 
					                return $this->json(0, 'ok', $return);
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                $errorMsg = Lang::get($this->validate->getError());
 | 
				
			||||||
 | 
					                return $this->json(1, $errorMsg);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        } catch (RepositoryException $e) {
 | 
				
			||||||
 | 
					            return $this->json(1, $e->getMessage());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    //文件上传(通用)
 | 
				
			||||||
 | 
					    public function file()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $file     = request()->file('file_file');
 | 
				
			||||||
 | 
					        $md5      = $file->md5();//文件md5
 | 
				
			||||||
 | 
					        $fileName = $file->getOriginalName();//原始文件名
 | 
				
			||||||
 | 
					//        if ($fileItem = File::where('md5', $md5)->find()) {
 | 
				
			||||||
 | 
					//            $return['src']          = $fileItem['src'];
 | 
				
			||||||
 | 
					//            $return['name']         = $fileName;
 | 
				
			||||||
 | 
					//            $fileItem['updated_at'] = date('Y-m-d H:i:s');
 | 
				
			||||||
 | 
					//            return $this->json(200, '该文件已存在 路径为:'.$fileItem['path'], $return);
 | 
				
			||||||
 | 
					//        }
 | 
				
			||||||
 | 
					        if ($this->validate->checkFile($file)) {
 | 
				
			||||||
 | 
					            try {
 | 
				
			||||||
 | 
					                if (!$this->uploadPathIsWritable) {
 | 
				
			||||||
 | 
					                    throw new \Exception('上传文件夹需要写入权限');
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                $src            = Filesystem::putFile('files'.$this->DIRECTORY_SEPARATOR.date('Ym'), $file, 'uniqid');
 | 
				
			||||||
 | 
					                $src            = $this->uploadPath.$this->DIRECTORY_SEPARATOR.$src;
 | 
				
			||||||
 | 
					                $return['src']  = $src;
 | 
				
			||||||
 | 
					                $return['name'] = $fileName;
 | 
				
			||||||
 | 
					                File::add($file, $src, $md5, 'file');    //加入上传文件表
 | 
				
			||||||
 | 
					            } catch (\Exception $e) {
 | 
				
			||||||
 | 
					                return $this->json(1, $e->getMessage());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            return $this->json(0, 'ok', $return);
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            $errorMsg = Lang::get($this->validate->getError());
 | 
				
			||||||
 | 
					            return $this->json(1, $errorMsg);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    //图片上传(通用)
 | 
				
			||||||
 | 
					    public function image()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        // 字段名 image-image避免冲突 layui组件自动生成的隐藏file input框中name容易重名冲突
 | 
				
			||||||
 | 
					        $image   = request()->file('image_image');
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            $res = $this->uploadImage($image);
 | 
				
			||||||
 | 
					            return $this->json(0, '上传成功', $res);
 | 
				
			||||||
 | 
					        } catch (RepositoryException $e) {
 | 
				
			||||||
 | 
					            return $this->json(1, $e->getMessage());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function uploadImage($image)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        // 字段名 image-image避免冲突 layui组件自动生成的隐藏file input框中name容易重名冲突
 | 
				
			||||||
 | 
					        $md5     = $image->md5();//文件md5
 | 
				
			||||||
 | 
					        $path    = request()->param('path/s', '');//指定路径 基于public下  若为空则默认
 | 
				
			||||||
 | 
					        $hasPath = !empty($path);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($this->validate->checkImage($image)) {
 | 
				
			||||||
 | 
					            //            if ($fileItem = File::where('md5', $md5)->find()) {
 | 
				
			||||||
 | 
					            //                $return['src']          = $fileItem['src'];
 | 
				
			||||||
 | 
					            //                $fileItem['updated_at'] = date('Y-m-d H:i:s');
 | 
				
			||||||
 | 
					            //
 | 
				
			||||||
 | 
					            //                return $this->json(200, '该文件已存在 路径为:'.$fileItem['path'], $return);
 | 
				
			||||||
 | 
					            //            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            try {
 | 
				
			||||||
 | 
					                if (!$this->uploadPathIsWritable) {
 | 
				
			||||||
 | 
					                    throw new \Exception('上传文件夹需要写入权限');
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                // 去除以/storage/开头的部分  如/storage/20210808/test => 20210808/test
 | 
				
			||||||
 | 
					                if (strpos(trim($path, $this->DIRECTORY_SEPARATOR), \app\model\Attachment::ROOT_NAME.$this->DIRECTORY_SEPARATOR) === 0) {
 | 
				
			||||||
 | 
					                    $path = substr(trim($path, $this->DIRECTORY_SEPARATOR), strlen(\app\model\Attachment::ROOT_NAME.$this->DIRECTORY_SEPARATOR));
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                $datePath = $hasPath ? $path : 'images'.$this->DIRECTORY_SEPARATOR.date('Ym');//自定义目录
 | 
				
			||||||
 | 
					                $datePath = ($datePath == $this->DIRECTORY_SEPARATOR."storage") ? $this->DIRECTORY_SEPARATOR : $datePath;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                $src      = Filesystem::putFile($datePath, $image, 'uniqid');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                $src      = $this->uploadPath . $this->DIRECTORY_SEPARATOR . $src;
 | 
				
			||||||
 | 
					                $suffix   = strtolower($image->getOriginalExtension());
 | 
				
			||||||
 | 
					                if ($suffix == 'gif') {
 | 
				
			||||||
 | 
					                    $return['thumb_src'] = $src;    //TODO获取GIF缩略图
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    $return['thumb_src'] = Image::getThumb($src, 100, 100, TImage::THUMB_SCALING);   //上传返回缩略图宽度为100
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                $return['src'] = $src;
 | 
				
			||||||
 | 
					                if ($this->isCompress) {
 | 
				
			||||||
 | 
					                    Image::resize($src);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                File::add($image, $src, $md5);    //加入上传文件表
 | 
				
			||||||
 | 
					            } catch (\Exception $e) {
 | 
				
			||||||
 | 
					                throw new RepositoryException($e->getMessage());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            return $return;
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            $errorMsg = Lang::get($this->validate->getError());
 | 
				
			||||||
 | 
					            throw new RepositoryException($errorMsg);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    //富文本编辑器上传图片
 | 
				
			||||||
 | 
					    public function tinyImage()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $image = request()->file('file');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!$image) {
 | 
				
			||||||
 | 
					            // 字段名不对
 | 
				
			||||||
 | 
					            header("HTTP/1.1 404 config field error");
 | 
				
			||||||
 | 
					            exit;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!$this->uploadPathIsWritable) {
 | 
				
			||||||
 | 
					            header("HTTP/1.1 403 Insufficient folder permissions");
 | 
				
			||||||
 | 
					            exit;
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            $md5 = $image->md5();//文件md5
 | 
				
			||||||
 | 
					//            if ($fileItem = File::where('md5', $md5)->find()) {
 | 
				
			||||||
 | 
					//                $fileItem['updated_at'] = date('Y-m-d H:i:s');
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//                $fileItem->save();
 | 
				
			||||||
 | 
					//                $res['location'] = $fileItem['src'];
 | 
				
			||||||
 | 
					//                return json($res);
 | 
				
			||||||
 | 
					//            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (!in_array(strtolower($image->getMime()), ['image/png','image/jpeg','image/jpg','image/gif'])) {
 | 
				
			||||||
 | 
					                header("HTTP/1.1 400 MIME TYPE ERROR");
 | 
				
			||||||
 | 
					                exit;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            checkPathExistWithMake(public_path().$this->uploadPath.'/images/'.date('Ym'));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // tinymce富文本对图片进行操作后(xuan)上传的是blob文件。
 | 
				
			||||||
 | 
					            // 针对blob文件未读取到后缀名 自动生成后缀 默认用mimetype后缀 如image/jpeg =》jpeg
 | 
				
			||||||
 | 
					            $newFileName = $image->hashName('uniqid');
 | 
				
			||||||
 | 
					            if (isset(explode('.',$newFileName)[1]) && empty(explode('.',$newFileName)[1])) {
 | 
				
			||||||
 | 
					                $ext = explode('/', $image->getOriginalMime());
 | 
				
			||||||
 | 
					                $newFileName .= $ext[1];
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $src    = Filesystem::putFileAs('images/'.date('Ym'), $image, $newFileName);
 | 
				
			||||||
 | 
					            $src    = $this->uploadPath.$this->DIRECTORY_SEPARATOR.$src;
 | 
				
			||||||
 | 
					            if ($this->isCompress) {
 | 
				
			||||||
 | 
					                // 剪切
 | 
				
			||||||
 | 
					                //Image::resize($src);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            File::add($image, $src, $md5);    //加入上传文件表
 | 
				
			||||||
 | 
					            $res['location'] = $src;
 | 
				
			||||||
 | 
					            return json($res);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,306 @@
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					declare (strict_types=1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace app\controller\manager;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use app\model\Account;
 | 
				
			||||||
 | 
					use app\model\Account as AccountModel;
 | 
				
			||||||
 | 
					use app\model\AccountWorksite;
 | 
				
			||||||
 | 
					use Exception;
 | 
				
			||||||
 | 
					use app\model\Log;
 | 
				
			||||||
 | 
					use think\Collection;
 | 
				
			||||||
 | 
					use think\response\View;
 | 
				
			||||||
 | 
					use think\response\Json;
 | 
				
			||||||
 | 
					use think\db\exception\DbException;
 | 
				
			||||||
 | 
					use think\exception\ValidateException;
 | 
				
			||||||
 | 
					use think\db\exception\DataNotFoundException;
 | 
				
			||||||
 | 
					use think\db\exception\ModelNotFoundException;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Worksite extends Base
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    protected $noNeedLogin = ['getAccountList'];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 列表
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @throws Exception
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function index()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if ($this->request->isPost()) {
 | 
				
			||||||
 | 
					            $params = input('searchParams/a');
 | 
				
			||||||
 | 
					            $page   = input('page/d', 1);
 | 
				
			||||||
 | 
					            $size   = input('size/d', 20);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $where = [];
 | 
				
			||||||
 | 
					            if (!empty($params)) {
 | 
				
			||||||
 | 
					                foreach ($params as $key => $param) {
 | 
				
			||||||
 | 
					                    $param = trim($param);
 | 
				
			||||||
 | 
					                    if ($key == 'keyword') {
 | 
				
			||||||
 | 
					                        $where[] = ['w.name', 'like', '%'.$param.'%'];
 | 
				
			||||||
 | 
					                        continue;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    if ($param == '0' || !empty($param)) {
 | 
				
			||||||
 | 
					                        $where[] = ['w.'.$key, 'like', '%'.$param.'%'];
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $query = \app\model\Worksite::alias('w')->leftJoin('account a', 'a.id = w.manager_id')->where($where);
 | 
				
			||||||
 | 
					            $total = $query->count();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $res = [
 | 
				
			||||||
 | 
					                'total'   => $total,
 | 
				
			||||||
 | 
					                'current' => $page ?: 1,
 | 
				
			||||||
 | 
					                'size'    => $size ?: 20,
 | 
				
			||||||
 | 
					                'list'    => new Collection(),
 | 
				
			||||||
 | 
					            ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if ($total > 0) {
 | 
				
			||||||
 | 
					                $res['list'] = $query->fieldRaw('w.*,a.nickname,a.real_name,a.mobile')->page($page, $size)->order('w.sort', 'desc')->order('w.id', 'desc')->select();
 | 
				
			||||||
 | 
					                $statusText  = \app\model\Worksite::statusText();
 | 
				
			||||||
 | 
					                $res['list']->each(function ($item) use ($statusText) {
 | 
				
			||||||
 | 
					                    $item->status_text = $statusText[$item->status] ?? '';
 | 
				
			||||||
 | 
					                    $item->manager     = ($item->nickname ? '昵称:'.$item->nickname : '') .($item->real_name ? '  姓名:'.$item->real_name : ''). ($item->mobile ? '  手机:'.$item->mobile : '');
 | 
				
			||||||
 | 
					                });
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return $this->json(0, 'success', $res);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->view();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 添加
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return Json|View
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function add()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if ($this->request->isPost()) {
 | 
				
			||||||
 | 
					            try {
 | 
				
			||||||
 | 
					                $input = input('post.');
 | 
				
			||||||
 | 
					                if (!isset($input['name'])) {
 | 
				
			||||||
 | 
					                    return $this->json(4000, '参数错误');
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                $insert = [
 | 
				
			||||||
 | 
					                    'name'       => $input['name'] ?? '',
 | 
				
			||||||
 | 
					                    'lng'        => $input['lng'] ?? '',
 | 
				
			||||||
 | 
					                    'lat'        => $input['lat'] ?? '',
 | 
				
			||||||
 | 
					                    'address'    => $input['address'] ?? '',
 | 
				
			||||||
 | 
					                    'manager_id' => $input['manager_id'] ?? 0,
 | 
				
			||||||
 | 
					                ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if ($input['manager_id'] > 0) {
 | 
				
			||||||
 | 
					                    if (AccountWorksite::where('account_id', $input['manager_id'])->count() > 0) {
 | 
				
			||||||
 | 
					                        return $this->json(4003, '该负责人已绑定其他工地');
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                $item = \app\model\Worksite::create($insert);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if ($input['manager_id'] > 0) {
 | 
				
			||||||
 | 
					                    AccountWorksite::where('worksite_id', $item->id)->delete();
 | 
				
			||||||
 | 
					                    AccountWorksite::create([
 | 
				
			||||||
 | 
					                        'worksite_id' => $item->id,
 | 
				
			||||||
 | 
					                        'account_id'  => $input['manager_id'],
 | 
				
			||||||
 | 
					                    ]);
 | 
				
			||||||
 | 
					                    Account::where('id', $input['manager_id'])->save(['role' => Account::ROLE_MANAGER]);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                return $this->json();
 | 
				
			||||||
 | 
					            } catch (Exception $e) {
 | 
				
			||||||
 | 
					                return $this->json(4001, '添加失败'.$e->getMessage());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->view();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 编辑
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return \think\response\Json|\think\response\View
 | 
				
			||||||
 | 
					     * @throws \think\db\exception\DataNotFoundException
 | 
				
			||||||
 | 
					     * @throws \think\db\exception\DbException
 | 
				
			||||||
 | 
					     * @throws \think\db\exception\ModelNotFoundException
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function edit()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $id = input('id');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //通过ID查询
 | 
				
			||||||
 | 
					        $item = \app\model\Worksite::where('id', (int) $id)->find();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (empty($item)) {
 | 
				
			||||||
 | 
					            return $this->json(4000, '没有相关记录!');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($this->request->isPost()) {
 | 
				
			||||||
 | 
					            try {
 | 
				
			||||||
 | 
					                $input = input('post.');
 | 
				
			||||||
 | 
					                if (!isset($input['name']) || !isset($input['lng']) || !isset($input['lat'])) {
 | 
				
			||||||
 | 
					                    return $this->json(4000, '参数错误');
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                Account::where('id', $item['manager_id'])->save(['role' => Account::ROLE_NORMAL]);
 | 
				
			||||||
 | 
					                AccountWorksite::where('worksite_id', $id)->delete();
 | 
				
			||||||
 | 
					                if ($input['manager_id'] > 0) {
 | 
				
			||||||
 | 
					                    if (AccountWorksite::where('account_id', $input['manager_id'])->where('worksite_id', '<>', $id)->count() > 0) {
 | 
				
			||||||
 | 
					                        return $this->json(4003, '该负责人已绑定其他工地');
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    AccountWorksite::create([
 | 
				
			||||||
 | 
					                        'worksite_id' => $id,
 | 
				
			||||||
 | 
					                        'account_id'  => $input['manager_id'],
 | 
				
			||||||
 | 
					                    ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    Account::where('id', $input['manager_id'])->save(['role' => Account::ROLE_MANAGER]);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                $item->save([
 | 
				
			||||||
 | 
					                    'name'       => $input['name'] ?? '',
 | 
				
			||||||
 | 
					                    'lng'        => $input['lng'] ?? '',
 | 
				
			||||||
 | 
					                    'lat'        => $input['lat'] ?? '',
 | 
				
			||||||
 | 
					                    'address'    => $input['address'] ?? '',
 | 
				
			||||||
 | 
					                    'manager_id' => $input['manager_id'] ?? 0,
 | 
				
			||||||
 | 
					                ]);
 | 
				
			||||||
 | 
					                return $this->json();
 | 
				
			||||||
 | 
					            } catch (Exception $e) {
 | 
				
			||||||
 | 
					                return $this->json(5000, $e->getMessage());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $bindAccount = Account::where('id', $item['manager_id'])->column('id,nickname,real_name,mobile');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $accountList = [];
 | 
				
			||||||
 | 
					        foreach ($bindAccount as $ac) {
 | 
				
			||||||
 | 
					            $accountList[] = [
 | 
				
			||||||
 | 
					                'name_text' => $ac['nickname'].'【姓名:'.$ac['real_name'].'】【手机:'.$ac['mobile'].'】',
 | 
				
			||||||
 | 
					                'id'           => $ac['id'], 'selected' => true
 | 
				
			||||||
 | 
					            ];
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        $this->data['jsonStr']  = $bindAccount ? json_encode($accountList, JSON_UNESCAPED_UNICODE) : json_encode([]);
 | 
				
			||||||
 | 
					        $this->data['item'] = $item;
 | 
				
			||||||
 | 
					        $this->data['id']   = $id;
 | 
				
			||||||
 | 
					        return $this->view();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 更新属性
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @throws ModelNotFoundException
 | 
				
			||||||
 | 
					     * @throws DbException
 | 
				
			||||||
 | 
					     * @throws DataNotFoundException
 | 
				
			||||||
 | 
					     * @throws Exception
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function modify()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (!$this->request->isPost()) {
 | 
				
			||||||
 | 
					            return $this->json(4000, '非法请求');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $item     = input('post.');
 | 
				
			||||||
 | 
					        $validate = $this->validateByApi($item, [
 | 
				
			||||||
 | 
					            'field' => 'require',
 | 
				
			||||||
 | 
					            'value' => 'require',
 | 
				
			||||||
 | 
					        ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($validate !== true) {
 | 
				
			||||||
 | 
					            return $validate;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // 通过ID查询
 | 
				
			||||||
 | 
					        if (!$info = \app\model\Worksite::where('id', (int) $item['id'])->find()) {
 | 
				
			||||||
 | 
					            return $this->json(4001, '记录不存在');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $update = [$item['field'] => $item['value']];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            $info->save($update);
 | 
				
			||||||
 | 
					            return $this->json();
 | 
				
			||||||
 | 
					        } catch (ValidateException $e) {
 | 
				
			||||||
 | 
					            return $this->json(4001, $e->getError());
 | 
				
			||||||
 | 
					        } catch (Exception $e) {
 | 
				
			||||||
 | 
					            return $this->json(5000, '修改失败');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 删除
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return \think\response\Json
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function del(): Json
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (!$this->request->isPost()) {
 | 
				
			||||||
 | 
					            return $this->json(4000, '非法请求');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $ids = $this->request->param('ids/a', []);
 | 
				
			||||||
 | 
					        if (empty($ids)) {
 | 
				
			||||||
 | 
					            $ids[] = $this->request->param('id/d', 0);
 | 
				
			||||||
 | 
					            $ids   = array_filter($ids);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            if (count($ids)) {
 | 
				
			||||||
 | 
					                //删除逻辑
 | 
				
			||||||
 | 
					                if (\app\model\Account::whereIn('Worksite', $ids)->count() > 0) {
 | 
				
			||||||
 | 
					                    return $this->json(4000, '所选岗位已分配给用户,请先移除后再删除');
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                \app\model\Worksite::whereIn('id', $ids)->delete();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                Log::write(get_class(), 'del', '删除操作,涉及到的ID为:'.implode(',', $ids));
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        } catch (Exception $e) {
 | 
				
			||||||
 | 
					            return $this->json(5000, $e->getMessage());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->json();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 获取客户列表
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return Json
 | 
				
			||||||
 | 
					     * @throws DataNotFoundException
 | 
				
			||||||
 | 
					     * @throws DbException
 | 
				
			||||||
 | 
					     * @throws ModelNotFoundException|Exception
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function getAccountList(): Json
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if ($this->request->isPost()) {
 | 
				
			||||||
 | 
					            $keyword = input('keyword/s', '');
 | 
				
			||||||
 | 
					            $page    = input('page/d', 1);
 | 
				
			||||||
 | 
					            $size    = input('size/d', 10);
 | 
				
			||||||
 | 
					            $id      = input('id', '');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $relationIds = explode(',', $id);//已选记录
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $where = [];
 | 
				
			||||||
 | 
					            if (!empty($keyword)) {
 | 
				
			||||||
 | 
					                $where[] = ['nickname|real_name|mobile', 'like', '%'.$keyword.'%'];
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $res = AccountModel::findList($where, ['id', 'nickname', 'real_name', 'mobile'], $page, $size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if ($res['total'] > 0 && $relationIds) {
 | 
				
			||||||
 | 
					                $res['list'] = $res['list']->toArray();
 | 
				
			||||||
 | 
					                foreach ($res['list'] as &$item) {
 | 
				
			||||||
 | 
					                    $item['name_text'] = sprintf("昵称:%s;真实姓名:%s,手机号:%s", $item['nickname'], $item['real_name'], $item['mobile']);
 | 
				
			||||||
 | 
					                    if (count($relationIds) > 0 && in_array($item['id'], $relationIds)) {
 | 
				
			||||||
 | 
					                        $item['selected'] = true;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return $this->json(0, '操作成功', $res);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return $this->json(4001, '非法请求');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,302 @@
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace app\controller\manager\account;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use app\controller\manager\Base;
 | 
				
			||||||
 | 
					use app\exception\RepositoryException;
 | 
				
			||||||
 | 
					use app\model\Account;
 | 
				
			||||||
 | 
					use app\model\Account as AccountModel;
 | 
				
			||||||
 | 
					use app\model\Position;
 | 
				
			||||||
 | 
					use app\model\Worksite;
 | 
				
			||||||
 | 
					use app\repository\AccountRepository;
 | 
				
			||||||
 | 
					use app\service\Math;
 | 
				
			||||||
 | 
					use Exception;
 | 
				
			||||||
 | 
					use think\db\exception\DataNotFoundException;
 | 
				
			||||||
 | 
					use think\db\exception\DbException;
 | 
				
			||||||
 | 
					use think\db\exception\ModelNotFoundException;
 | 
				
			||||||
 | 
					use think\exception\ValidateException;
 | 
				
			||||||
 | 
					use think\facade\Db;
 | 
				
			||||||
 | 
					use think\facade\Log;
 | 
				
			||||||
 | 
					use think\response\Json;
 | 
				
			||||||
 | 
					use think\response\Redirect;
 | 
				
			||||||
 | 
					use think\response\View;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * 用户管理
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Class Footmarks
 | 
				
			||||||
 | 
					 * @package app\controller\manager
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					class Index extends Base
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    protected $noNeedLogin = ['getAccountList'];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 详情
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return View
 | 
				
			||||||
 | 
					     * @throws RepositoryException
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function detail(): View
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $id   = input('id/d', 0);
 | 
				
			||||||
 | 
					        $item = AccountRepository::getInstance()->findById($id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $orderNum                = 0;
 | 
				
			||||||
 | 
					        $orderScoreNum           = 0;
 | 
				
			||||||
 | 
					        $totalPrice              = 0;
 | 
				
			||||||
 | 
					        $totalScore              = 0;
 | 
				
			||||||
 | 
					        $item['total_price']     = Math::fen2Yuan($totalPrice);
 | 
				
			||||||
 | 
					        $item['order_num']       = $orderNum;
 | 
				
			||||||
 | 
					        $item['order_score_num'] = $orderScoreNum;
 | 
				
			||||||
 | 
					        $item['order_newest']    = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->data['item'] = $item;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->view();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 编辑
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return Redirect|Json|View
 | 
				
			||||||
 | 
					     * @throws Exception
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function edit()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $id = input('id/d', 0);
 | 
				
			||||||
 | 
					        if (!$info = AccountRepository::getInstance()->findById($id)) {
 | 
				
			||||||
 | 
					            if ($this->request->isPost()) {
 | 
				
			||||||
 | 
					                return $this->json(4000, '用户不存在');
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                return $this->error('用户不存在');
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($this->request->isPost()) {
 | 
				
			||||||
 | 
					            $item     = input('post.');
 | 
				
			||||||
 | 
					            $validate = $this->validateByApi($item, [
 | 
				
			||||||
 | 
					                'real_name' => 'require',
 | 
				
			||||||
 | 
					                'mobile' => 'require',
 | 
				
			||||||
 | 
					            ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if ($validate !== true) {
 | 
				
			||||||
 | 
					                return $validate;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            try {
 | 
				
			||||||
 | 
					                $info->save($item);
 | 
				
			||||||
 | 
					                return $this->json();
 | 
				
			||||||
 | 
					            } catch (ValidateException $e) {
 | 
				
			||||||
 | 
					                return $this->json(4001, $e->getError());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->data['item'] = $info;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->view();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 工人信息编辑
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return Redirect|Json|View
 | 
				
			||||||
 | 
					     * @throws Exception
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function worker()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $id = input('id/d', 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!$info = Account::find($id)) {
 | 
				
			||||||
 | 
					            if ($this->request->isPost()) {
 | 
				
			||||||
 | 
					                return $this->json(4000, '用户不存在');
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                return $this->error('用户不存在');
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($this->request->isPost()) {
 | 
				
			||||||
 | 
					            $item     = input('post.');
 | 
				
			||||||
 | 
					            $validate = $this->validateByApi($item, [
 | 
				
			||||||
 | 
					                'real_name|姓名'            => 'require',
 | 
				
			||||||
 | 
					                'mobile|电话'               => 'require',
 | 
				
			||||||
 | 
					                'position|岗位'             => 'require',
 | 
				
			||||||
 | 
					                'pay|基本工资'                => 'require',
 | 
				
			||||||
 | 
					                'emergency_contact|紧急联系人' => 'require',
 | 
				
			||||||
 | 
					                'emergency_phone|紧急联系人电话' => 'require',
 | 
				
			||||||
 | 
					                'bank_card_name|银行卡户名'    => 'require',
 | 
				
			||||||
 | 
					                'bank_card_number|银行卡号'   => 'require',
 | 
				
			||||||
 | 
					                'bank_name|开户行'           => 'require',
 | 
				
			||||||
 | 
					                'card_number|身份证'         => 'require',
 | 
				
			||||||
 | 
					            ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if ($validate !== true) {
 | 
				
			||||||
 | 
					                return $validate;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            try {
 | 
				
			||||||
 | 
					                $info->save($item);
 | 
				
			||||||
 | 
					                return $this->json();
 | 
				
			||||||
 | 
					            } catch (ValidateException $e) {
 | 
				
			||||||
 | 
					                return $this->json(4001, $e->getError());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->data['item'] = $info;
 | 
				
			||||||
 | 
					        $this->data['positionList'] = Position::list();
 | 
				
			||||||
 | 
					        $this->data['worksite_name'] = Worksite::where('id', $info['worksite_id'])->value('name');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->view();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 单个字段编辑
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return Json
 | 
				
			||||||
 | 
					     * @throws DataNotFoundException
 | 
				
			||||||
 | 
					     * @throws DbException
 | 
				
			||||||
 | 
					     * @throws ModelNotFoundException
 | 
				
			||||||
 | 
					     * @throws Exception
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function modify(): Json
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if ($this->request->isPost()) {
 | 
				
			||||||
 | 
					            $item     = input('post.');
 | 
				
			||||||
 | 
					            $validate = $this->validateByApi($item, [
 | 
				
			||||||
 | 
					                'field' => 'require',
 | 
				
			||||||
 | 
					                'value' => 'require',
 | 
				
			||||||
 | 
					            ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if ($validate !== true) {
 | 
				
			||||||
 | 
					                return $validate;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (!$info = AccountModel::findById($item['id'])) {
 | 
				
			||||||
 | 
					                return $this->json(4001, '记录不存在');
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $update = [$item['field'] => $item['value']];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            try {
 | 
				
			||||||
 | 
					                $info->save($update);
 | 
				
			||||||
 | 
					                return $this->json();
 | 
				
			||||||
 | 
					            } catch (ValidateException $e) {
 | 
				
			||||||
 | 
					                return $this->json(4001, $e->getError());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return $this->json(4000, '非法请求');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 列表
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return View|Json
 | 
				
			||||||
 | 
					     * @throws Exception
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function index()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $position = Position::list();
 | 
				
			||||||
 | 
					        if ($this->request->isPost()) {
 | 
				
			||||||
 | 
					            $page         = input('page/d', 1);
 | 
				
			||||||
 | 
					            $size         = input('size/d', 20);
 | 
				
			||||||
 | 
					            $searchParams = input('searchParams');
 | 
				
			||||||
 | 
					            $search       = [];
 | 
				
			||||||
 | 
					            if ($searchParams) {
 | 
				
			||||||
 | 
					                foreach ($searchParams as $key => $param) {
 | 
				
			||||||
 | 
					                    if ($param || $param == '0') {
 | 
				
			||||||
 | 
					                        switch ($key) {
 | 
				
			||||||
 | 
					                            case 'keyword':
 | 
				
			||||||
 | 
					                                $search[] = ['nickname|real_name|mobile|emergency_contact|emergency_phone|bank_card_name|bank_card_number|bank_name|card_number', 'like', '%'.$param.'%'];
 | 
				
			||||||
 | 
					                                break;
 | 
				
			||||||
 | 
					                            case 'role':
 | 
				
			||||||
 | 
					                                switch ($param) {
 | 
				
			||||||
 | 
					                                    case -1://全部
 | 
				
			||||||
 | 
					                                        break;
 | 
				
			||||||
 | 
					                                    case Account::ROLE_NORMAL:
 | 
				
			||||||
 | 
					                                    case Account::ROLE_WORKER:
 | 
				
			||||||
 | 
					                                    case Account::ROLE_MANAGER:
 | 
				
			||||||
 | 
					                                        $search[] = ['role', '=', $param];
 | 
				
			||||||
 | 
					                                        break;
 | 
				
			||||||
 | 
					                                    case 3://单独构造的代号 员工 表示工人和负责人
 | 
				
			||||||
 | 
					                                        $search[] = ['role', 'in', [Account::ROLE_WORKER, Account::ROLE_MANAGER]];
 | 
				
			||||||
 | 
					                                        break;
 | 
				
			||||||
 | 
					                                }
 | 
				
			||||||
 | 
					                                break;
 | 
				
			||||||
 | 
					                            default:
 | 
				
			||||||
 | 
					                                $search[] = [$key, 'like', '%'.$param.'%'];
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (empty($searchParams['role'])) {
 | 
				
			||||||
 | 
					                $search[] = ['role', 'in', [Account::ROLE_WORKER, Account::ROLE_MANAGER]];
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            try {
 | 
				
			||||||
 | 
					                $items = Account::findList($search, [], $page, $size, function ($q) {
 | 
				
			||||||
 | 
					                    return $q->order('id', 'desc');
 | 
				
			||||||
 | 
					                });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                $worksite = Worksite::list();
 | 
				
			||||||
 | 
					                $items['list']->each(function ($item) use ($position, $worksite) {
 | 
				
			||||||
 | 
					                    $genderText          = Account::genderText()[$item->gender] ?? '保密';
 | 
				
			||||||
 | 
					                    $item->role_text     = Account::roleText()[$item->role] ?? '其他';
 | 
				
			||||||
 | 
					                    $item->position_text = $position[$item->position] ?? '其他';
 | 
				
			||||||
 | 
					                    $item->worksite_name = $worksite[$item->position] ?? '';
 | 
				
			||||||
 | 
					                    $item->checking_text = Account::checkingText()[$item->checking] ?? '';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    $item->gender_text = $genderText;
 | 
				
			||||||
 | 
					                });
 | 
				
			||||||
 | 
					                return $this->json(0, '操作成功', $items);
 | 
				
			||||||
 | 
					            } catch (RepositoryException $e) {
 | 
				
			||||||
 | 
					                return $this->json(4001, $e->getMessage());
 | 
				
			||||||
 | 
					            } catch (Exception $e) {
 | 
				
			||||||
 | 
					                return $this->json(5001, '获取用户列表失败'.$e->getMessage());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->data['positionList'] = $position;
 | 
				
			||||||
 | 
					        return $this->view();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 获取客户列表
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return Json
 | 
				
			||||||
 | 
					     * @throws DataNotFoundException
 | 
				
			||||||
 | 
					     * @throws DbException
 | 
				
			||||||
 | 
					     * @throws ModelNotFoundException|Exception
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function getAccountList(): Json
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if ($this->request->isPost()) {
 | 
				
			||||||
 | 
					            $keyword = input('keyword/s', '');
 | 
				
			||||||
 | 
					            $page    = input('page/d', 1);
 | 
				
			||||||
 | 
					            $size    = input('size/d', 10);
 | 
				
			||||||
 | 
					            $id      = input('id', '');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $relationIds = explode(',', $id);//已选记录
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $where = [];
 | 
				
			||||||
 | 
					            if (!empty($keyword)) {
 | 
				
			||||||
 | 
					                $where[] = ['nickname|real_name|mobile', 'like', '%'.$keyword.'%'];
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $res = AccountModel::findList($where, ['id', 'nickname', 'real_name', 'mobile'], $page, $size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if ($res['total'] > 0 && $relationIds) {
 | 
				
			||||||
 | 
					                $res['list'] = $res['list']->toArray();
 | 
				
			||||||
 | 
					                foreach ($res['list'] as &$item) {
 | 
				
			||||||
 | 
					                    $item['name_text'] = sprintf("昵称:%s;真实姓名:%s,手机号:%s", $item['nickname'], $item['real_name'], $item['mobile']);
 | 
				
			||||||
 | 
					                    if (count($relationIds) > 0 && in_array($item['id'], $relationIds)) {
 | 
				
			||||||
 | 
					                        $item['selected'] = true;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return $this->json(0, '操作成功', $res);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return $this->json(4001, '非法请求');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,173 @@
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace app\controller\manager\account;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use app\controller\manager\Base;
 | 
				
			||||||
 | 
					use app\model\AccountTag as AccountTagModel;
 | 
				
			||||||
 | 
					use Exception;
 | 
				
			||||||
 | 
					use think\db\exception\DataNotFoundException;
 | 
				
			||||||
 | 
					use think\db\exception\DbException;
 | 
				
			||||||
 | 
					use think\db\exception\ModelNotFoundException;
 | 
				
			||||||
 | 
					use think\exception\ValidateException;
 | 
				
			||||||
 | 
					use think\response\Json;
 | 
				
			||||||
 | 
					use think\response\View;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * 客户标签
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Class Tag
 | 
				
			||||||
 | 
					 * @package app\controller\manager\account
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					class Tag extends Base
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 删除
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return Json
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function del(): Json
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if ($this->request->isPost()) {
 | 
				
			||||||
 | 
					            $ids = input('post.ids/a', []);
 | 
				
			||||||
 | 
					            if (empty($ids)) {
 | 
				
			||||||
 | 
					                $ids[] = input('post.id/d');
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            AccountTagModel::deleteByIds($ids);
 | 
				
			||||||
 | 
					            return $this->json();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return $this->json(4001, '非法请求!');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 编辑
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return Json|View
 | 
				
			||||||
 | 
					     * @throws DataNotFoundException
 | 
				
			||||||
 | 
					     * @throws DbException
 | 
				
			||||||
 | 
					     * @throws ModelNotFoundException
 | 
				
			||||||
 | 
					     * @throws Exception
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function edit()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $id = input('id/d', 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!$info = AccountTagModel::findById($id)) {
 | 
				
			||||||
 | 
					            return $this->json(4001, '记录不存在');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($this->request->isPost()) {
 | 
				
			||||||
 | 
					            $item     = input('post.');
 | 
				
			||||||
 | 
					            $validate = $this->validateByApi($item, [
 | 
				
			||||||
 | 
					                'name' => 'require',
 | 
				
			||||||
 | 
					            ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if ($validate !== true) {
 | 
				
			||||||
 | 
					                return $validate;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            try {
 | 
				
			||||||
 | 
					                $info->save($item);
 | 
				
			||||||
 | 
					                return $this->json();
 | 
				
			||||||
 | 
					            } catch (ValidateException $e) {
 | 
				
			||||||
 | 
					                return $this->json(4001, $e->getError());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->data['item'] = $info;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->view();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 单个字段编辑
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return Json
 | 
				
			||||||
 | 
					     * @throws DataNotFoundException
 | 
				
			||||||
 | 
					     * @throws DbException
 | 
				
			||||||
 | 
					     * @throws ModelNotFoundException
 | 
				
			||||||
 | 
					     * @throws Exception
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function modify(): Json
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if ($this->request->isPost()) {
 | 
				
			||||||
 | 
					            $item     = input('post.');
 | 
				
			||||||
 | 
					            $validate = $this->validateByApi($item, [
 | 
				
			||||||
 | 
					                'field' => 'require',
 | 
				
			||||||
 | 
					                'value' => 'require',
 | 
				
			||||||
 | 
					            ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if ($validate !== true) {
 | 
				
			||||||
 | 
					                return $validate;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (!$info = AccountTagModel::findById($item['id'])) {
 | 
				
			||||||
 | 
					                return $this->json(4001, '记录不存在');
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $update = [$item['field'] => $item['value']];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            try {
 | 
				
			||||||
 | 
					                $info->save($update);
 | 
				
			||||||
 | 
					                return $this->json();
 | 
				
			||||||
 | 
					            } catch (ValidateException $e) {
 | 
				
			||||||
 | 
					                return $this->json(4001, $e->getError());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return $this->json(4000, '非法请求');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 添加
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return Json|View
 | 
				
			||||||
 | 
					     * @throws Exception
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function add()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if ($this->request->isPost()) {
 | 
				
			||||||
 | 
					            $item = input('post.');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $validate = $this->validateByApi($item, [
 | 
				
			||||||
 | 
					                'name' => 'require',
 | 
				
			||||||
 | 
					            ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if ($validate !== true) {
 | 
				
			||||||
 | 
					                return $validate;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            $tag = AccountTagModel::findOne(["name" => $item["name"]]);
 | 
				
			||||||
 | 
					            if (!empty($tag)) {
 | 
				
			||||||
 | 
					                return $this->json(0, "success", ["id" => $tag["id"]]);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            try {
 | 
				
			||||||
 | 
					                $item['created_at'] = date('Y-m-d H:i:s');
 | 
				
			||||||
 | 
					                $id                 = AccountTagModel::insertGetId($item);
 | 
				
			||||||
 | 
					                return $this->json(0, "success", ["id" => $id]);
 | 
				
			||||||
 | 
					            } catch (ValidateException $e) {
 | 
				
			||||||
 | 
					                return $this->json(4001, $e->getError());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->view();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 列表
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return View|Json
 | 
				
			||||||
 | 
					     * @throws Exception
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function index()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if ($this->request->isPost()) {
 | 
				
			||||||
 | 
					            $page  = input('page/d', 1);
 | 
				
			||||||
 | 
					            $limit = input('size/d', 20);
 | 
				
			||||||
 | 
					            $items = AccountTagModel::findList([], [], $page, $limit, function ($q) {
 | 
				
			||||||
 | 
					                return $q->order('sort', 'desc')->order('id', 'asc');
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return $this->json(0, '操作成功', $items);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return $this->view();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,18 @@
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					// 事件定义文件
 | 
				
			||||||
 | 
					return [
 | 
				
			||||||
 | 
					    'bind'      => [
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    'listen'    => [
 | 
				
			||||||
 | 
					        'AppInit'  => [],
 | 
				
			||||||
 | 
					        'HttpRun'  => [],
 | 
				
			||||||
 | 
					        'HttpEnd'  => [],
 | 
				
			||||||
 | 
					        'LogLevel' => [],
 | 
				
			||||||
 | 
					        'LogWrite' => [],
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    'subscribe' => [
 | 
				
			||||||
 | 
					        'app\subscribe\Pay',
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					];
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,10 @@
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace app\exception;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use Exception;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ApiRedirectException extends Exception
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,11 @@
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace app\exception;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use Exception;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 事件异常
 | 
				
			||||||
 | 
					class EventException extends Exception
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,8 @@
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace app\exception;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class RepositoryException extends \Exception
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,10 @@
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace app\exception;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use Exception;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ServiceException extends Exception
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,7 @@
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					namespace app\exception;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class TraitException extends \Exception
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,37 @@
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					namespace app\job;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use app\repository\AccountRepository;
 | 
				
			||||||
 | 
					use think\queue\Job;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class NotifySms
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public function fire(Job $job, $data){
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //短信通知列表
 | 
				
			||||||
 | 
					        if ($data) {
 | 
				
			||||||
 | 
					            foreach ($data as $item) {
 | 
				
			||||||
 | 
					                echo sprintf("短信发送成功!phone:%s time:%s \n", $item['mobile'], date('Y-m-d H:i:s'));
 | 
				
			||||||
 | 
					                sleep(mt_rand(1,3));
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//        if ($job->attempts() > 3) {
 | 
				
			||||||
 | 
					//            //通过这个方法可以检查这个任务已经重试了几次了
 | 
				
			||||||
 | 
					//            echo sprintf('发送短信失败过多');
 | 
				
			||||||
 | 
					//        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //如果任务执行成功后 记得删除任务,不然这个任务会重复执行,直到达到最大重试次数后失败后,执行failed方法
 | 
				
			||||||
 | 
					        $job->delete();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // 也可以重新发布这个任务
 | 
				
			||||||
 | 
					//        $job->release(3); //$delay为延迟时间
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function failed($data){
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // ...任务达到最大重试次数后,失败了
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,10 @@
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					// 全局中间件定义文件
 | 
				
			||||||
 | 
					return [
 | 
				
			||||||
 | 
					    // 全局请求缓存
 | 
				
			||||||
 | 
					    // \think\middleware\CheckRequestCache::class,
 | 
				
			||||||
 | 
					    // 多语言加载
 | 
				
			||||||
 | 
					    //\think\middleware\LoadLangPack::class,
 | 
				
			||||||
 | 
					    // Session初始化
 | 
				
			||||||
 | 
					    \think\middleware\SessionInit::class,
 | 
				
			||||||
 | 
					];  
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,35 @@
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					namespace app\middleware;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use Closure;
 | 
				
			||||||
 | 
					use app\service\Jwt as JwtService;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * API登录认证(需要先调用JWT解析用户信息)
 | 
				
			||||||
 | 
					 * Class ApiLogin
 | 
				
			||||||
 | 
					 * @package app\middleware
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					class ApiLogin
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public function handle($request, Closure $next) {
 | 
				
			||||||
 | 
					        $authorization = $request->authorization ?? '';
 | 
				
			||||||
 | 
					        if (empty($authorization)) {
 | 
				
			||||||
 | 
					            return json(['code' => 6001, 'msg' => '请填写token']);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (!JwtService::validate($authorization)) {
 | 
				
			||||||
 | 
					            return json(['code' => 6001, 'msg' => 'token验证失败或已失效']);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $userInfo = $request->user ?? [];
 | 
				
			||||||
 | 
					        if (!isset($userInfo['user_id']) || empty($userInfo['user_id'])) {
 | 
				
			||||||
 | 
					            return json(['code' => 6001, 'msg' => 'token已失效']);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // 自定义过期时间校验。
 | 
				
			||||||
 | 
					        if(isset($userInfo['expire_time']) && time() >= $userInfo['expire_time']) {
 | 
				
			||||||
 | 
					            return json(['code' => 6001, 'msg' => 'token已失效']);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $next($request);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,50 @@
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace app\middleware;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use Closure;
 | 
				
			||||||
 | 
					use app\model\AuthRule;
 | 
				
			||||||
 | 
					use tauthz\facade\Enforcer;
 | 
				
			||||||
 | 
					use think\facade\Cache;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Auth
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public function handle($request, Closure $next)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $auth = session('auth');
 | 
				
			||||||
 | 
					        if (!$auth) {
 | 
				
			||||||
 | 
					            return redirect(url('manager.login/index'));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $module = 'manager';
 | 
				
			||||||
 | 
					        $controller = unCamelize(request()->controller());
 | 
				
			||||||
 | 
					        $controller = str_replace($module.'.', '', $controller);
 | 
				
			||||||
 | 
					        $controller = str_replace('.', '/', $controller);//兼容多层级目录  如 /manager/test/article/index
 | 
				
			||||||
 | 
					        $action     = unCamelize(request()->action());
 | 
				
			||||||
 | 
					        $roles = Enforcer::getRolesForUser($auth['user_id']);
 | 
				
			||||||
 | 
					//        $per = Enforcer::getPermissionsForUser($roles[0]);
 | 
				
			||||||
 | 
					//        var_dump($controller);
 | 
				
			||||||
 | 
					//        var_dump($action);
 | 
				
			||||||
 | 
					//        var_dump($roles);
 | 
				
			||||||
 | 
					//        var_dump($per);
 | 
				
			||||||
 | 
					//        exit;
 | 
				
			||||||
 | 
					//        return $next($request);//暂时停用权限校验
 | 
				
			||||||
 | 
					//        var_dump($controller);
 | 
				
			||||||
 | 
					//        var_dump($action);
 | 
				
			||||||
 | 
					//        var_dump(Enforcer::hasPermissionForUser(1, $controller, 'group-make'));exit;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        foreach ($roles as $role) {
 | 
				
			||||||
 | 
					            // TODO 关注批量权限检测是否可用
 | 
				
			||||||
 | 
					            //只需要有一个角色具有权限就放通 此处第一个参数不是用户 而是 角色 此方法是检测用户|角色是否具有某个权限的公用方法
 | 
				
			||||||
 | 
					            if (Enforcer::hasPermissionForUser($role, $controller, $action)) {
 | 
				
			||||||
 | 
					                return $next($request);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (request()->isAjax()) {
 | 
				
			||||||
 | 
					            return json(['code' => 4001, 'msg' => '没有权限']);
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            return view('/manager/error/jump')->assign('msg', '很抱歉,您还没有权限,请联系管理员开通!');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,56 @@
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					namespace app\middleware;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use Closure;
 | 
				
			||||||
 | 
					use think\Request;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * CSRF校验
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					class Csrf
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public function handle(Request $request, Closure $next)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if($request->isPost()){
 | 
				
			||||||
 | 
					            $check = $request->checkToken();
 | 
				
			||||||
 | 
					            if(false === $check) {
 | 
				
			||||||
 | 
					//                return $this->csrfError($request);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return $next($request);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    protected function csrfError($request, $msg = '非法请求, 用户身份认证失败!')
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if($request->isAjax()) {
 | 
				
			||||||
 | 
					            return json(['code' => 401, 'msg' => $msg], 200);
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            $referer = $_SERVER['HTTP_REFERER'] ?? null;
 | 
				
			||||||
 | 
					            if (empty($referer)) {
 | 
				
			||||||
 | 
					                $url = '/';
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                $domain = $request->domain();
 | 
				
			||||||
 | 
					                $urlInfo = parse_url($referer);
 | 
				
			||||||
 | 
					                $scheme = $urlInfo['scheme'] ?? '';
 | 
				
			||||||
 | 
					                $requestSrc = '';
 | 
				
			||||||
 | 
					                if (!empty($scheme)) {
 | 
				
			||||||
 | 
					                    $requestSrc = $scheme.'://'.($urlInfo['host'] ?? '');
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                if($domain != $requestSrc) {
 | 
				
			||||||
 | 
					                    $url = '/';
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    $url = 'javascript:history.back(-1);';
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            $errorData = [
 | 
				
			||||||
 | 
					                'code'=> 401,
 | 
				
			||||||
 | 
					                'msg' => $msg,
 | 
				
			||||||
 | 
					                'data' => [],
 | 
				
			||||||
 | 
					                'wait' => 5,
 | 
				
			||||||
 | 
					                'url' => $url
 | 
				
			||||||
 | 
					            ];
 | 
				
			||||||
 | 
					            return view('error/400', $errorData);
 | 
				
			||||||
 | 
					            // 返回401视图 response type has html、json、jsonp、xml、file、view、redirect
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,37 @@
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					namespace app\middleware;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use Closure;
 | 
				
			||||||
 | 
					use app\service\Jwt as JwtService;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * 根据TOKEN解析用户信息
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Class JWT
 | 
				
			||||||
 | 
					 * @package app\middleware
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					class JWT
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public function handle($request, Closure $next)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $authorization = $request->header('Authorization');
 | 
				
			||||||
 | 
					        $tokenStr      = $request->param('token/s', '');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($authorization) {
 | 
				
			||||||
 | 
					            $authorization = str_replace('Bearer ', '', $authorization);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //优先取header中token
 | 
				
			||||||
 | 
					        $token      = $authorization ?: $tokenStr;
 | 
				
			||||||
 | 
					        $userInfo   = [];
 | 
				
			||||||
 | 
					        if (!empty($token)) {
 | 
				
			||||||
 | 
					            $userInfo = JwtService::parse($token);//token中携带的简易用户信息
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $request->user          = $userInfo;
 | 
				
			||||||
 | 
					        // authorization用于移交ApiLogin认证
 | 
				
			||||||
 | 
					        $request->authorization = $token;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $next($request);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,26 @@
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace app\middleware;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use Closure;
 | 
				
			||||||
 | 
					use think\Request;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * 日志记录
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Class Log
 | 
				
			||||||
 | 
					 * @package app\middleware
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					class Log
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public function handle(Request  $request, Closure $next)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $response = $next($request);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // 添加中间件执行代码
 | 
				
			||||||
 | 
					        \app\model\Log::write($request->controller(), $request->action(), $request->pathinfo(), $request->method());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $response;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,25 @@
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace app\middleware;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use Closure;
 | 
				
			||||||
 | 
					use think\Request;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * 前台登录验证
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Class Login
 | 
				
			||||||
 | 
					 * @package app\middleware
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					class Login
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public function handle(Request $request, Closure $next)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (!session('frontend_auth')) {
 | 
				
			||||||
 | 
					            $url = $request->url(true);
 | 
				
			||||||
 | 
					            return redirect(url('login/index').'?url='.urlencode($url));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $next($request);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,92 @@
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace app\model;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use think\model\relation\BelongsToMany;
 | 
				
			||||||
 | 
					use think\model\relation\HasMany;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Account extends Base
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public const ROLE_NORMAL  = '0';//普通用户
 | 
				
			||||||
 | 
					    public const ROLE_WORKER  = '1';//工人
 | 
				
			||||||
 | 
					    public const ROLE_MANAGER = '2';//负责人
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public const STATUS_NORMAL    = 'normal'; //正常
 | 
				
			||||||
 | 
					    public const STATUS_DISABLE   = 'disable';//禁用
 | 
				
			||||||
 | 
					    public const GENDER_UNDEFINED = 0; // 未知
 | 
				
			||||||
 | 
					    public const GENDER_MALE      = 1; // 男性
 | 
				
			||||||
 | 
					    public const GENDER_FEMALE    = 2; // 女性
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // 生成个人补充信息:邀请码、用户编号
 | 
				
			||||||
 | 
					    public static function onAfterInsert($item)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $item->invite_code = md5($item->id, false);
 | 
				
			||||||
 | 
					        $item->coding      = date('y').str_pad((string) $item->id, 10, '0', STR_PAD_LEFT);
 | 
				
			||||||
 | 
					        $item->save();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public static function roleText(): array
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return [
 | 
				
			||||||
 | 
					            self::ROLE_NORMAL  => '普通用户',
 | 
				
			||||||
 | 
					            self::ROLE_WORKER  => '工人',
 | 
				
			||||||
 | 
					            self::ROLE_MANAGER => '工地负责人',
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public static function checkingText(): array
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return [
 | 
				
			||||||
 | 
					            0  => '正常',
 | 
				
			||||||
 | 
					            1  => '资料审核中',
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public static function genderText(): array
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return [
 | 
				
			||||||
 | 
					            self::GENDER_UNDEFINED => '保密',
 | 
				
			||||||
 | 
					            self::GENDER_MALE      => '男',
 | 
				
			||||||
 | 
					            self::GENDER_FEMALE    => '女',
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // 获取用户信息 (包含待审核信息)
 | 
				
			||||||
 | 
					    public static function getUser(int $accountId): array
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $user = self::alias('a')
 | 
				
			||||||
 | 
					            ->leftJoin('position p', 'a.position = p.id')
 | 
				
			||||||
 | 
					            ->where('a.id', $accountId)
 | 
				
			||||||
 | 
					            ->field('a.*,p.name as position_name')
 | 
				
			||||||
 | 
					            ->find();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (empty($user)) {
 | 
				
			||||||
 | 
					            return [];
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $user->headimgurl = resourceJoin($user->headimgurl, request()->domain());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $user['check_info'] = [];//待审核对比信息
 | 
				
			||||||
 | 
					        if ($user->checking == self::COMMON_ON || $user->role == self::ROLE_WORKER) {
 | 
				
			||||||
 | 
					            $user['check_info'] = CheckLog::getCheckInfo($accountId);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $user = $user->toArray();
 | 
				
			||||||
 | 
					        unset($user['sex']);
 | 
				
			||||||
 | 
					        unset($user['unionid']);
 | 
				
			||||||
 | 
					        unset($user['last_login']);
 | 
				
			||||||
 | 
					        unset($user['login_ip']);
 | 
				
			||||||
 | 
					        unset($user['remarks']);
 | 
				
			||||||
 | 
					        unset($user['remarks']);
 | 
				
			||||||
 | 
					        return arrayNullToString($user);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // 工人-需要审核的字段
 | 
				
			||||||
 | 
					    public static function needCheckFields(): array
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return [
 | 
				
			||||||
 | 
					            'real_name', 'mobile', 'position', 'pay', 'emergency_contact', 'emergency_phone', 'bank_card_name', 'bank_card_number',
 | 
				
			||||||
 | 
					            'bank_name', 'card_number'
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,138 @@
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace app\model;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use app\exception\RepositoryException;
 | 
				
			||||||
 | 
					use think\db\exception\DataNotFoundException;
 | 
				
			||||||
 | 
					use think\db\exception\DbException;
 | 
				
			||||||
 | 
					use think\db\exception\ModelNotFoundException;
 | 
				
			||||||
 | 
					use think\model\relation\HasOne;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class AccountCoupon extends Base
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public const STATUS_NORMAL  = 'normal';//正常
 | 
				
			||||||
 | 
					    public const STATUS_USED    = 'used';//已使用
 | 
				
			||||||
 | 
					    public const STATUS_INVALID = 'invalid';//已失效
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public const CODE_SALT        = 'R5S6Y1';//优惠券加密密码盐
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 状态列表
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return string[]
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public static function statusList(): array
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return [self::STATUS_NORMAL, self::STATUS_USED, self::STATUS_INVALID];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 状态列表
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return string[]
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public static function statusText(): array
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return [self::STATUS_NORMAL => '待使用', self::STATUS_USED => '已使用', self::STATUS_INVALID => '已失效'];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function coupon(): HasOne
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return $this->hasOne(Coupon::class, 'id', 'coupon_id')->bind(
 | 
				
			||||||
 | 
					            [
 | 
				
			||||||
 | 
					                'amount',
 | 
				
			||||||
 | 
					                'name',
 | 
				
			||||||
 | 
					                'cover',
 | 
				
			||||||
 | 
					                'type',
 | 
				
			||||||
 | 
					                'condition',
 | 
				
			||||||
 | 
					                'begin_at',
 | 
				
			||||||
 | 
					                'end_at',
 | 
				
			||||||
 | 
					            ]
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    public function account(): HasOne
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return $this->hasOne(Account::class, 'id', 'account_id')->bind(
 | 
				
			||||||
 | 
					            [
 | 
				
			||||||
 | 
					                'nickname',
 | 
				
			||||||
 | 
					                'mobile',
 | 
				
			||||||
 | 
					            ]
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 优惠券使用
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param  int  $accountId
 | 
				
			||||||
 | 
					     * @param  int  $id
 | 
				
			||||||
 | 
					     * @param  string  $orderCoding
 | 
				
			||||||
 | 
					     * @param  string  $checkBy
 | 
				
			||||||
 | 
					     * @return bool
 | 
				
			||||||
 | 
					     * @throws DataNotFoundException
 | 
				
			||||||
 | 
					     * @throws DbException
 | 
				
			||||||
 | 
					     * @throws ModelNotFoundException
 | 
				
			||||||
 | 
					     * @throws RepositoryException
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public static function use(int $accountId, int $id, string $orderCoding = '',$checkBy =""): bool
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $where = ['id' => $id];
 | 
				
			||||||
 | 
					        if (!$accountCoupon = self::findOne($where)) {
 | 
				
			||||||
 | 
					            throw new RepositoryException('您的优惠券不存在');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($accountCoupon['account_id'] != $accountId) {
 | 
				
			||||||
 | 
					            throw new RepositoryException('不是您的优惠券');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!empty($accountCoupon['deleted_at'])) {
 | 
				
			||||||
 | 
					            throw new RepositoryException('您的优惠券不存在-2');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!$coupon = Coupon::findById($accountCoupon['coupon_id'])) {
 | 
				
			||||||
 | 
					            throw new RepositoryException('此优惠券不存在或已下架');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!empty($coupon['deleted_at'])) {
 | 
				
			||||||
 | 
					            throw new RepositoryException('此优惠券已下架');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $now = date('Y-m-d H:i:s');
 | 
				
			||||||
 | 
					        if ($now < $coupon['begin_at'] || $now > $coupon['end_at']) {
 | 
				
			||||||
 | 
					            throw new RepositoryException('此优惠券不在有效期');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if($accountCoupon["status"] != AccountCoupon::STATUS_NORMAL){
 | 
				
			||||||
 | 
					            throw new RepositoryException('优惠券已使用或已失效');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $accountCoupon->save([
 | 
				
			||||||
 | 
					            'used_at'      => $now,
 | 
				
			||||||
 | 
					            'status'       => self::STATUS_USED,
 | 
				
			||||||
 | 
					            'order_coding' => $orderCoding,
 | 
				
			||||||
 | 
					            'check_by' => $checkBy,
 | 
				
			||||||
 | 
					        ]);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 获取首页优惠券
 | 
				
			||||||
 | 
					     * 没有或已领取则返回null
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param  int  $accountId
 | 
				
			||||||
 | 
					     * @return Coupon|array|\think\Model|null
 | 
				
			||||||
 | 
					     * @throws DataNotFoundException
 | 
				
			||||||
 | 
					     * @throws DbException
 | 
				
			||||||
 | 
					     * @throws ModelNotFoundException
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public static function homeCoupon(int $accountId)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (!$coupon = Coupon::homeCoupon()) {
 | 
				
			||||||
 | 
					            return null;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (self::where('account_id', $accountId)->where('coupon_id', $coupon['id'])->count() > 0) {
 | 
				
			||||||
 | 
					            return null;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $coupon;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,161 @@
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace app\model;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use think\model\relation\HasOne;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * 积分与佣金日志
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Class AccountDataLog
 | 
				
			||||||
 | 
					 * @package app\model
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					class AccountDataLog extends Base
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public const TYPE_SCORE      = 'score';//积分
 | 
				
			||||||
 | 
					    public const TYPE_COMMISSION = 'commission';//佣金
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public const ACTION_ORDER             = 'order';//订单返佣
 | 
				
			||||||
 | 
					    public const ACTION_ADMIN_RECHARGE    = 'admin_recharge';//后台充值
 | 
				
			||||||
 | 
					    public const ACTION_ADMIN_OPERATION   = 'admin_operation';//后台操作
 | 
				
			||||||
 | 
					    public const ACTION_WITHDRAWAL_RETURN = 'withdrawal_return';//提现-退回
 | 
				
			||||||
 | 
					    public const ACTION_WITHDRAWAL        = 'withdrawal';//提现-扣除
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // 积分独有
 | 
				
			||||||
 | 
					    public const ACTION_SHARE_REG         = 'share_reg';//分享注册
 | 
				
			||||||
 | 
					    public const ACTION_SHARE_REG_CHILD   = 'share_reg_child';//分享注册-下级分享时获得积分
 | 
				
			||||||
 | 
					    public const ACTION_SHARE_REG_SERVICE = 'share_reg_service';//分享注册-客户分享时客服获得积分
 | 
				
			||||||
 | 
					    public const ACTION_SIGN              = 'sign';//签到
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 记录变更
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param  int  $accountId
 | 
				
			||||||
 | 
					     * @param  string  $name  日志名称(说明) 如 签到打卡、任务完成等等
 | 
				
			||||||
 | 
					     * @param  string  $num  数量
 | 
				
			||||||
 | 
					     * @param  string  $type  类型 目前仅 TYPE_SCORE TYPE_COMMISSION
 | 
				
			||||||
 | 
					     * @param  string  $action  操作 如打卡=sign 任务=task 订单=order
 | 
				
			||||||
 | 
					     * @param  string  $surplus  剩余积分或佣金
 | 
				
			||||||
 | 
					     * @param  string  $operator  操作人
 | 
				
			||||||
 | 
					     * @param  int  $operatorId  操作人ID
 | 
				
			||||||
 | 
					     * @param  string  $remarks  备注
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public static function log(int $accountId, string $name, string $num, string $type, string $action, string $surplus, string $operator = '', int $operatorId = 0, string $remarks = '')
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        self::create([
 | 
				
			||||||
 | 
					            'account_id'  => $accountId,
 | 
				
			||||||
 | 
					            'name'        => $name,
 | 
				
			||||||
 | 
					            'num'         => $num,
 | 
				
			||||||
 | 
					            'type'        => $type,
 | 
				
			||||||
 | 
					            'action'      => $action,
 | 
				
			||||||
 | 
					            'created_at'  => date('Y-m-d H:i:s'),
 | 
				
			||||||
 | 
					            'surplus'     => $surplus,
 | 
				
			||||||
 | 
					            'operator'    => $operator,
 | 
				
			||||||
 | 
					            'operator_id' => $operatorId,
 | 
				
			||||||
 | 
					            'remarks'     => $remarks,
 | 
				
			||||||
 | 
					        ]);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     *  用户
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function account(): HasOne
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return $this->hasOne(Account::class, 'id', 'account_id');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     *  来源用户
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function sourceAccount(): HasOne
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return $this->hasOne(Account::class, 'id', 'source_account_id');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 积分操作类型
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return string[]
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public static function scoreAction(): array
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return [
 | 
				
			||||||
 | 
					            self::ACTION_ORDER             => '订单',
 | 
				
			||||||
 | 
					            self::ACTION_ADMIN_RECHARGE    => '后台充值',
 | 
				
			||||||
 | 
					            self::ACTION_ADMIN_OPERATION   => '后台操作',
 | 
				
			||||||
 | 
					            self::ACTION_SHARE_REG         => '分享注册',
 | 
				
			||||||
 | 
					            self::ACTION_SHARE_REG_CHILD   => '分享注册-下级分享',
 | 
				
			||||||
 | 
					            self::ACTION_SHARE_REG_SERVICE => '分享注册-客服获得积分',
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 佣金操作类型
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return string[]
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public static function commissionAction(): array
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return [
 | 
				
			||||||
 | 
					            self::ACTION_ORDER             => '订单返佣',
 | 
				
			||||||
 | 
					            self::ACTION_ADMIN_RECHARGE    => '后台充值',
 | 
				
			||||||
 | 
					            self::ACTION_ADMIN_OPERATION   => '后台操作',
 | 
				
			||||||
 | 
					            self::ACTION_WITHDRAWAL_RETURN => '提现退回',
 | 
				
			||||||
 | 
					            self::ACTION_WITHDRAWAL        => '提现扣除',
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    //
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 分销明显 根据身份返回不同
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param  int  $accountId
 | 
				
			||||||
 | 
					     * @param  int  $position  身份 0=普通用户 1=一级代理 2=二级代理
 | 
				
			||||||
 | 
					     * @param  array  $options
 | 
				
			||||||
 | 
					     * @return array
 | 
				
			||||||
 | 
					     * @throws \Exception
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public static function salesList(int $accountId, int $position, array $options = []): array
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $page   = $options['page'] ?? 1;
 | 
				
			||||||
 | 
					        $size   = $options['size'] ?? 20;
 | 
				
			||||||
 | 
					        $action = $options['action'] ?? '';//查询具体某类操作
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $where   = [];
 | 
				
			||||||
 | 
					        $where[] = ['account_id', '=', $accountId];
 | 
				
			||||||
 | 
					        $where[] = ['num', '>', 0];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!empty($action)) {
 | 
				
			||||||
 | 
					            $where[] = ['action', '=', $action];
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($position > 0) {
 | 
				
			||||||
 | 
					            $where[] = ['type', '=', self::TYPE_COMMISSION];
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            $where[] = ['type', '=', self::TYPE_SCORE];
 | 
				
			||||||
 | 
					            $where[] = ['action', '=', self::ACTION_ORDER];
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $field = ['id', 'account_id', 'source_account_id', 'name', 'num', 'created_at', 'type'];
 | 
				
			||||||
 | 
					        $list  = self::findList($where, $field, $page, $size, function ($q) {
 | 
				
			||||||
 | 
					            return $q->order('created_at', 'desc')->order('id', 'desc')->with([
 | 
				
			||||||
 | 
					                'sourceAccount' => function ($query) {
 | 
				
			||||||
 | 
					                    $query->field('id,nickname,headimgurl');
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            ]);
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $list['list']->each(function ($item) {
 | 
				
			||||||
 | 
					            $item->account = $item->sourceAccount ? json_decode($item->sourceAccount, true) : [];
 | 
				
			||||||
 | 
					            if ($item['type'] == self::TYPE_SCORE) {
 | 
				
			||||||
 | 
					                $item->num = (int) $item->num;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            unset($item->sourceAccount);
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $list;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,117 @@
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace app\model;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use Exception;
 | 
				
			||||||
 | 
					use think\db\exception\DataNotFoundException;
 | 
				
			||||||
 | 
					use think\db\exception\DbException;
 | 
				
			||||||
 | 
					use think\db\exception\ModelNotFoundException;
 | 
				
			||||||
 | 
					use think\facade\Db;
 | 
				
			||||||
 | 
					use think\model\relation\HasOne;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class AccountRecord extends Base
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public const TYPE_CONTENT = 'content';//内容
 | 
				
			||||||
 | 
					    public const TYPE_SPU     = 'spu';//商品
 | 
				
			||||||
 | 
					    public const TYPE_OTHER   = 'other';//其他
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public const ACTION_COLLECT    = 'collect';//收藏
 | 
				
			||||||
 | 
					    public const ACTION_LIKE       = 'like';//点赞
 | 
				
			||||||
 | 
					    public const ACTION_SHARE      = 'share';//分享
 | 
				
			||||||
 | 
					    public const ACTION_SEARCH     = 'search';//搜索
 | 
				
			||||||
 | 
					    public const ACTION_VIEW       = 'view';//查看
 | 
				
			||||||
 | 
					    public const ACTION_REGISTER   = 'register';//注册
 | 
				
			||||||
 | 
					    public const ACTION_SHARE_VIEW = 'share_view';//分享内容被查看 记录的account_id为分享人ID
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public const COLLECTED = 1;
 | 
				
			||||||
 | 
					    public const LIKED     = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 允许的类型
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return string[]
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public static function allowTypes(): array
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return [
 | 
				
			||||||
 | 
					            self::TYPE_CONTENT, self::TYPE_OTHER, self::TYPE_SPU
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 允许的操作
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return string[]
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public static function allowActions(): array
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return [
 | 
				
			||||||
 | 
					            self::ACTION_COLLECT, self::ACTION_LIKE, self::ACTION_SHARE,
 | 
				
			||||||
 | 
					            self::ACTION_REGISTER, self::ACTION_VIEW, self::ACTION_SHARE_VIEW
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 内容表允许的操作
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return string[]
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public static function archivesActions(): array
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return [
 | 
				
			||||||
 | 
					            self::ACTION_COLLECT, self::ACTION_LIKE, self::ACTION_SHARE,
 | 
				
			||||||
 | 
					            self::ACTION_VIEW
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 不可撤销的操作 即每次都新增记录 如 分享、咨询、注册
 | 
				
			||||||
 | 
					     * 注意:可撤销操作需要防止撤销后重新操作导致的无限制增加统计 即刷数据 如收藏、点赞等
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return string[]
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public static function notUndoActions(): array
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return [self::ACTION_SHARE, self::ACTION_REGISTER, self::ACTION_VIEW];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 操作对应字段
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return string[]
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public static function actionField(): array
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return [
 | 
				
			||||||
 | 
					            self::ACTION_REGISTER   => 'customer',
 | 
				
			||||||
 | 
					            self::ACTION_COLLECT    => 'collects',
 | 
				
			||||||
 | 
					            self::ACTION_LIKE       => 'likes',
 | 
				
			||||||
 | 
					            self::ACTION_VIEW       => 'views',
 | 
				
			||||||
 | 
					            self::ACTION_SHARE      => 'shares',
 | 
				
			||||||
 | 
					            self::ACTION_SHARE_VIEW => 'views',//分享内容被查看 也增加views
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 概览操作对应字段
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return string[]
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public static function overviewField(): array
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return [
 | 
				
			||||||
 | 
					            self::ACTION_REGISTER   => 'customer',
 | 
				
			||||||
 | 
					            self::ACTION_VIEW       => 'views',
 | 
				
			||||||
 | 
					            self::ACTION_SHARE      => 'shares',
 | 
				
			||||||
 | 
					            self::ACTION_SHARE_VIEW => 'views',//分享内容被查看 也增加views
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 模型关联:内容文档
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function archive(): HasOne
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return $this->hasOne(Archives::class, 'id', 'relation_id');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,8 @@
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace app\model;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class AccountSign extends Base
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,13 @@
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace app\model;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * 工地与负责人关联表
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Class AccountWorksite
 | 
				
			||||||
 | 
					 * @package app\model
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					class AccountWorksite extends Base
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,32 @@
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace app\model;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * 活动
 | 
				
			||||||
 | 
					 * Class Activity
 | 
				
			||||||
 | 
					 * @package app\model
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					class Activity extends Base
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    // 是否有正在进行中的活动
 | 
				
			||||||
 | 
					    public static function hasCurrent(): bool
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $now = date('Y-m-d');
 | 
				
			||||||
 | 
					        return self::where('is_current', 1)
 | 
				
			||||||
 | 
					            ->where('begin_at', '<=', $now)
 | 
				
			||||||
 | 
					            ->where('end_at', '>=', $now)
 | 
				
			||||||
 | 
					            ->count() > 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // 指定活动是否是正在进行中的活动
 | 
				
			||||||
 | 
					    public static function isCurrent(int $id): bool
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $now = date('Y-m-d');
 | 
				
			||||||
 | 
					        return self::where('is_current', 1)
 | 
				
			||||||
 | 
					                ->where('id', $id)
 | 
				
			||||||
 | 
					                ->where('begin_at', '<=', $now)
 | 
				
			||||||
 | 
					                ->where('end_at', '>=', $now)
 | 
				
			||||||
 | 
					                ->count() > 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,13 @@
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace app\model;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * 参与活动商家
 | 
				
			||||||
 | 
					 * Class Activity
 | 
				
			||||||
 | 
					 * @package app\model
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					class ActivityBusiness extends Base
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,58 @@
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace app\model;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use think\db\exception\DataNotFoundException;
 | 
				
			||||||
 | 
					use think\db\exception\DbException;
 | 
				
			||||||
 | 
					use think\db\exception\ModelNotFoundException;
 | 
				
			||||||
 | 
					use think\model\relation\HasMany;
 | 
				
			||||||
 | 
					use think\model\relation\HasOne;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Archives extends Base
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public const ORIGINAL_TABLE = 'bee_archives';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public const STATUS_NORMAL  = 1;//正常
 | 
				
			||||||
 | 
					    public const STATUS_DISABLE = 0;//禁用
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 相关记录 点赞|收藏
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return HasMany
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function record(): HasMany
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return $this->hasMany(AccountRecord::class, 'relation_id', 'id');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 是否收藏
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return HasOne
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function collect(): HasOne
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return $this->hasOne(AccountRecord::class, 'relation_id', 'id')->bind(['is_collected' => 'is_record']);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 创建人信息
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return HasOne
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function member(): HasOne
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return $this->hasOne(Member::class, 'id', 'created_by')->bind(['nickname']);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 分类
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return HasOne
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function category(): HasOne
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return $this->hasOne(ArchivesCategory::class, 'id', 'category_id')->bind(['category_title' => 'title']);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,86 @@
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace app\model;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use think\Collection;
 | 
				
			||||||
 | 
					use think\db\exception\DbException;
 | 
				
			||||||
 | 
					use think\db\exception\DataNotFoundException;
 | 
				
			||||||
 | 
					use think\db\exception\ModelNotFoundException;
 | 
				
			||||||
 | 
					use think\model\relation\HasOne;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ArchivesCategory extends Base
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public const TOP_PID = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public const NAME_DIARY = 'diary'; //日记分享
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 获取恒美 关于我们栏目列表
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return string[]
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public static function aboutCategoryId(): array
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $aboutId = self::where('name', 'about')->value('id');
 | 
				
			||||||
 | 
					        return self::where('pid', $aboutId)->column('id');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 获取病种相关模型的栏目 模型名称为:'question', 'diary', 'effect', 'science'
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return string[]
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public static function diseaseCategoryIds(): array
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $modelIds = ArchivesModel::whereIn('name', ArchivesModel::models())->column('id');
 | 
				
			||||||
 | 
					        return self::whereIn('model_id', $modelIds)->column('id');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 检测数据下 是否有子栏目
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param  array  $ids
 | 
				
			||||||
 | 
					     * @return bool
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public static function hasChildrenByIds(array $ids): bool
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return self::whereIn('pid', $ids)->count() > 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 检测数据下 是否有子内容
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param  array  $ids
 | 
				
			||||||
 | 
					     * @return bool
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public static function hasContentByIds(array $ids): bool
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return Archives::whereIn('category_id', $ids)->count() > 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 获取列表
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return ArchivesCategory[]|array|Collection
 | 
				
			||||||
 | 
					     * @throws DataNotFoundException
 | 
				
			||||||
 | 
					     * @throws DbException
 | 
				
			||||||
 | 
					     * @throws ModelNotFoundException
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public static function getList()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return self::field('id,pid,title,name,sort,path,true as open')
 | 
				
			||||||
 | 
					            ->order('sort', 'desc')
 | 
				
			||||||
 | 
					            ->order('id', 'asc')
 | 
				
			||||||
 | 
					            ->select();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 模型
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return HasOne
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function model(): HasOne
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return $this->hasOne(ArchivesModel::class, 'id', 'model_id')->bind(['model' => 'name']);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,53 @@
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace app\model;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * 文档模型
 | 
				
			||||||
 | 
					 * Class ArchivesModel
 | 
				
			||||||
 | 
					 * @package app\model
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					class ArchivesModel extends Base
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 获取恒美内容模型 问题文章|日记分享|效果模拟|科普视频
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return string[]
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public static function models(): array
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return ['question', 'diary', 'effect', 'science'];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 内容模型关联栏目
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return mixed
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public static function categories()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return self::alias('am')
 | 
				
			||||||
 | 
					            ->leftJoin('archives_category ac', 'ac.model_id = am.id')
 | 
				
			||||||
 | 
					            ->field('ac.id,ac.title,ac.model_id, ac.sort,am.name as model_name')
 | 
				
			||||||
 | 
					            ->order('ac.sort', 'desc')
 | 
				
			||||||
 | 
					            ->order('ac.id', 'asc')
 | 
				
			||||||
 | 
					            ->whereIn('am.name', self::models())
 | 
				
			||||||
 | 
					            ->select();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 关于我们栏目
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return mixed
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public static function about()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return self::alias('am')
 | 
				
			||||||
 | 
					            ->leftJoin('archives_category ac', 'ac.model_id = am.id')
 | 
				
			||||||
 | 
					            ->field('ac.id,ac.title,ac.model_id, ac.sort,am.name as model_name')
 | 
				
			||||||
 | 
					            ->order('ac.sort', 'desc')
 | 
				
			||||||
 | 
					            ->order('ac.id', 'asc')
 | 
				
			||||||
 | 
					            ->whereIn('ac.id', ArchivesCategory::aboutCategoryId())
 | 
				
			||||||
 | 
					            ->select();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,118 @@
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace app\model;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use Exception;
 | 
				
			||||||
 | 
					use think\db\exception\DataNotFoundException;
 | 
				
			||||||
 | 
					use think\db\exception\DbException;
 | 
				
			||||||
 | 
					use think\db\exception\ModelNotFoundException;
 | 
				
			||||||
 | 
					use think\facade\Db;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * 文档模型字段
 | 
				
			||||||
 | 
					 * Class ArchivesModelField
 | 
				
			||||||
 | 
					 * @package app\model
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					class ArchivesModelField extends Base
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public const VIRTUAL_YES = 1;//虚拟字段 是
 | 
				
			||||||
 | 
					    public const VIRTUAL_NO  = 0;//虚拟字段 否
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 模型添加字段列表
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param  int  $modelId
 | 
				
			||||||
 | 
					     * @param  string  $modelName
 | 
				
			||||||
 | 
					     * @throws Exception
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public static function setFieldList(int $modelId, string $modelName)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (self::where('model_id', $modelId)->count() <= 0) {
 | 
				
			||||||
 | 
					            $rs     = Db::query("SHOW FULL COLUMNS FROM ".Archives::ORIGINAL_TABLE);
 | 
				
			||||||
 | 
					            $insert = [];
 | 
				
			||||||
 | 
					            foreach ($rs as $val) {
 | 
				
			||||||
 | 
					                $arr             = [];
 | 
				
			||||||
 | 
					                $arr['model_id'] = $modelId;
 | 
				
			||||||
 | 
					                $arr['model']    = $modelName;
 | 
				
			||||||
 | 
					                $arr['name']     = $val['Field'];
 | 
				
			||||||
 | 
					                $arr['title']    = $val['Comment'];
 | 
				
			||||||
 | 
					                $arr['remark']   = $val['Comment'];
 | 
				
			||||||
 | 
					                $insert[]        = $arr;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            (new self())->saveAll($insert);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 同步字段
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param  int  $modelId
 | 
				
			||||||
 | 
					     * @param  string  $modelName
 | 
				
			||||||
 | 
					     * @throws DataNotFoundException
 | 
				
			||||||
 | 
					     * @throws DbException
 | 
				
			||||||
 | 
					     * @throws ModelNotFoundException
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public static function syncFieldList(int $modelId, string $modelName)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $rs           = Db::query("SHOW FULL COLUMNS FROM ".Archives::ORIGINAL_TABLE);
 | 
				
			||||||
 | 
					        $oldFieldList = self::where('model_id', $modelId)->where('is_virtual', self::VIRTUAL_NO)->select();
 | 
				
			||||||
 | 
					        $oldFields    = $oldFieldList->column('name');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $newestFields = [];
 | 
				
			||||||
 | 
					        foreach ($rs as $val) {
 | 
				
			||||||
 | 
					            $newestFields[] = $val['Field'];
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //待删除字段
 | 
				
			||||||
 | 
					        $delete = array_diff($oldFields, $newestFields);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //待新增字段
 | 
				
			||||||
 | 
					        $needInsertFields = array_diff($newestFields, $oldFields);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $insert = [];//新增字段
 | 
				
			||||||
 | 
					        foreach ($rs as $val) {
 | 
				
			||||||
 | 
					            if (in_array($val['Field'], $needInsertFields)) {
 | 
				
			||||||
 | 
					                $arr             = [];
 | 
				
			||||||
 | 
					                $arr['model_id'] = $modelId;
 | 
				
			||||||
 | 
					                $arr['model']    = $modelName;
 | 
				
			||||||
 | 
					                $arr['name']     = $val['Field'];
 | 
				
			||||||
 | 
					                $arr['title']    = $val['Comment'];
 | 
				
			||||||
 | 
					                $arr['remark']   = $val['Comment'];
 | 
				
			||||||
 | 
					                $insert[]        = $arr;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        (new self())->saveAll($insert);
 | 
				
			||||||
 | 
					        (new self())->whereIn('name', $delete)->delete();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 各栏目[模型] 可展示字段列表
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return array
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public static function showFieldList(): array
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $list = self::alias('amf')
 | 
				
			||||||
 | 
					            ->leftJoin('archives_category ac', 'ac.model_id = amf.model_id')
 | 
				
			||||||
 | 
					            ->field('amf.*, ac.id as category_id, ac.title as category_title')
 | 
				
			||||||
 | 
					            ->where('amf.status', self::COMMON_ON)
 | 
				
			||||||
 | 
					            ->where('ac.id', '>', 0)
 | 
				
			||||||
 | 
					            ->select();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $res = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $list = $list->toArray();
 | 
				
			||||||
 | 
					        foreach ($list as $item) {
 | 
				
			||||||
 | 
					            if (!isset($res[$item['category_id']])) {
 | 
				
			||||||
 | 
					                $res[$item['category_id']] = [];
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $res[$item['category_id']][] = $item['name'];
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $res;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,69 @@
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace app\model;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use Exception;
 | 
				
			||||||
 | 
					use think\exception\ValidateException;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Attachment extends Base
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    protected $name = 'file';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public const TYPE_DIR   = 'dir';//目录
 | 
				
			||||||
 | 
					    public const TYPE_IMG   = 'image';//图片
 | 
				
			||||||
 | 
					    public const TYPE_VIDEO = 'video';//视频
 | 
				
			||||||
 | 
					    public const TYPE_FILE  = 'file';//文件
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public const ROOT_NAME = 'storage';//根目录名称
 | 
				
			||||||
 | 
					    public const ROOT_PATH = "/".self::ROOT_NAME;//文件存放根路径
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public static function list(): array
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $where[] = ['src', 'like', '%'.self::ROOT_PATH."/"];
 | 
				
			||||||
 | 
					        return self::findList($where);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 路径目录处理  会逐级检查路径上所有目录是否存在 不存在的目录全部创建[创建到数据库]
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @throws Exception
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public static function pathDirHandle(string $path): bool
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $pathInfo = pathinfo($path);
 | 
				
			||||||
 | 
					        $fullPath = isset($pathInfo['extension']) ? $pathInfo['dirname'] : $pathInfo['dirname']."/".$pathInfo['filename'];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // 全路径 如 /storage/dir1/dir2/dir3/dir4/  注意前后都有/
 | 
				
			||||||
 | 
					        $fullPath = $fullPath."/";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $pathArr = explode("/", trim($fullPath, "/"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $insert = [];
 | 
				
			||||||
 | 
					        $now    = date('Y-m-d H:i:s');
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            // 检测全路径上所有目录是否存在 不存在则创建
 | 
				
			||||||
 | 
					            foreach ($pathArr as $k => $p) {
 | 
				
			||||||
 | 
					                $currentPath = '/';
 | 
				
			||||||
 | 
					                $currentArr  = array_slice($pathArr, 0, $k);
 | 
				
			||||||
 | 
					                if ($currentArr) {
 | 
				
			||||||
 | 
					                    $currentPath = "/".implode('/', $currentArr)."/";
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                if ($currentPath != '/' && self::where('path', $currentPath)->where('name', $p)->count() <= 0) {
 | 
				
			||||||
 | 
					                    $arr               = [];
 | 
				
			||||||
 | 
					                    $arr['path']       = $currentPath;
 | 
				
			||||||
 | 
					                    $arr['name']       = $p;
 | 
				
			||||||
 | 
					                    $arr['created_at'] = $now;
 | 
				
			||||||
 | 
					                    $arr['is_dir']     = self::COMMON_ON;
 | 
				
			||||||
 | 
					                    $arr['type']       = self::TYPE_DIR;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    $insert[] = $arr;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            (new self())->saveAll($insert);
 | 
				
			||||||
 | 
					            return true;
 | 
				
			||||||
 | 
					        } catch (Exception $e) {
 | 
				
			||||||
 | 
					            return false;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,390 @@
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace app\model;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use Exception;
 | 
				
			||||||
 | 
					use think\Collection;
 | 
				
			||||||
 | 
					use think\db\exception\DataNotFoundException;
 | 
				
			||||||
 | 
					use think\db\exception\DbException;
 | 
				
			||||||
 | 
					use think\db\exception\ModelNotFoundException;
 | 
				
			||||||
 | 
					use think\Model;
 | 
				
			||||||
 | 
					use think\Paginator;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Base extends Model
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    protected $autoWriteTimestamp = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // 布尔值数字关系
 | 
				
			||||||
 | 
					    public const BOOL_FALSE = 0;
 | 
				
			||||||
 | 
					    public const BOOL_TRUE  = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public const COMMON_ON  = 1;
 | 
				
			||||||
 | 
					    public const COMMON_OFF = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    //根据Id列表获取列表
 | 
				
			||||||
 | 
					    public static function getListByIds($ids)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (count($ids) == 0 || empty($ids)) {
 | 
				
			||||||
 | 
					            return [];
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return self::where('id', 'in', $ids)->select()->toArray();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    //根据ID获取单条数据
 | 
				
			||||||
 | 
					    public static function getById($id)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if ($id <= 0) {
 | 
				
			||||||
 | 
					            return [];
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return self::where('id', $id)->findOrEmpty()->toArray();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 通过ID查找记录
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param  int  $id
 | 
				
			||||||
 | 
					     * @param  array  $fields
 | 
				
			||||||
 | 
					     * @param  callable|null  $call
 | 
				
			||||||
 | 
					     * @return array|Model|null
 | 
				
			||||||
 | 
					     * @throws DataNotFoundException
 | 
				
			||||||
 | 
					     * @throws DbException
 | 
				
			||||||
 | 
					     * @throws ModelNotFoundException
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public static function findById(int $id, array $fields = [], callable $call = null)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $q = self::when(!empty($fields), function ($q) use ($fields) {
 | 
				
			||||||
 | 
					            $q->field($fields);
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					        if ($call !== null) {
 | 
				
			||||||
 | 
					            $q = $call($q);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return $q->find($id);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 查找单个记录
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param  array  $where
 | 
				
			||||||
 | 
					     * @param  array  $fields
 | 
				
			||||||
 | 
					     * @param  callable|null  $call
 | 
				
			||||||
 | 
					     * @return array|Model|null
 | 
				
			||||||
 | 
					     * @throws DataNotFoundException
 | 
				
			||||||
 | 
					     * @throws DbException
 | 
				
			||||||
 | 
					     * @throws ModelNotFoundException
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public static function findOne(array $where = [], array $fields = [], callable $call = null)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $q = self::when(!empty($fields), function ($q) use ($fields) {
 | 
				
			||||||
 | 
					            $q->field($fields);
 | 
				
			||||||
 | 
					        })->where($where);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($call !== null) {
 | 
				
			||||||
 | 
					            $q = $call($q);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return $q->find();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    //根据ID更新数据
 | 
				
			||||||
 | 
					    public static function updateById($id, $data)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return self::where('id', $id)->update($data);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    //根据where条件和排序获取记录
 | 
				
			||||||
 | 
					    public static function getListByWhereAndOrder($where, $order, $limit = 1)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return self::where($where)
 | 
				
			||||||
 | 
					            ->order($order)
 | 
				
			||||||
 | 
					            ->limit($limit)
 | 
				
			||||||
 | 
					            ->select()
 | 
				
			||||||
 | 
					            ->toArray();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 根据ID删除数据
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param  int  $id
 | 
				
			||||||
 | 
					     * @return bool
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public static function deleteById(int $id): bool
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return self::where('id', $id)->delete();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 根据ID列表删除数据
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param  array  $ids
 | 
				
			||||||
 | 
					     * @return bool
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public static function deleteByIds(array $ids): bool
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return self::whereIn('id', $ids)->delete();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 排序
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param  int  $id  调整ID
 | 
				
			||||||
 | 
					     * @param  string  $type  本次操作类型 向上、向下
 | 
				
			||||||
 | 
					     * @param  int  $num  移动位数
 | 
				
			||||||
 | 
					     * @param  string  $listType  列表的排序方式 默认为降序
 | 
				
			||||||
 | 
					     * @param  array  $where  额外条件 如限制在指定分类下 where[] = ['category_id', '=', 6]
 | 
				
			||||||
 | 
					     * @return array
 | 
				
			||||||
 | 
					     * @throws Exception
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public static function sort(int $id, string $type, int $num = 1, string $listType = 'desc', array $where = []): array
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $res  = ['code' => 0, 'msg' => 'success'];
 | 
				
			||||||
 | 
					        $item = self::getById($id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!$item) {
 | 
				
			||||||
 | 
					            $res['code'] = 1;
 | 
				
			||||||
 | 
					            $res['msg']  = '记录不存在';
 | 
				
			||||||
 | 
					            return $res;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($listType == 'desc') {
 | 
				
			||||||
 | 
					            if ($type == 'down') {
 | 
				
			||||||
 | 
					                $where[] = ['sort', '<', $item['sort']];
 | 
				
			||||||
 | 
					                $order   = "sort desc";
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                $where[] = ['sort', '>', $item['sort']];
 | 
				
			||||||
 | 
					                $order   = "sort asc";
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            if ($type == 'up') {
 | 
				
			||||||
 | 
					                $where[] = ['sort', '<', $item['sort']];
 | 
				
			||||||
 | 
					                $order   = "sort desc";
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                $where[] = ['sort', '>', $item['sort']];
 | 
				
			||||||
 | 
					                $order   = "sort asc";
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $forSortItems = self::getListByWhereAndOrder($where, $order, $num);
 | 
				
			||||||
 | 
					        if (!empty($forSortItems)) {
 | 
				
			||||||
 | 
					            $updateData   = [];
 | 
				
			||||||
 | 
					            $forSortCount = count($forSortItems);
 | 
				
			||||||
 | 
					            for ($i = 0; $i < $forSortCount; $i++) {
 | 
				
			||||||
 | 
					                if ($i == 0) {
 | 
				
			||||||
 | 
					                    $updateData[] = [
 | 
				
			||||||
 | 
					                        'id'   => $forSortItems[$i]['id'],
 | 
				
			||||||
 | 
					                        'sort' => $item['sort']
 | 
				
			||||||
 | 
					                    ];
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    $updateData[] = [
 | 
				
			||||||
 | 
					                        'id'   => $forSortItems[$i]['id'],
 | 
				
			||||||
 | 
					                        'sort' => $forSortItems[$i - 1]['sort']
 | 
				
			||||||
 | 
					                    ];
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            $updateData[] = [
 | 
				
			||||||
 | 
					                'id'   => $item['id'],
 | 
				
			||||||
 | 
					                'sort' => $forSortItems[$i - 1]['sort']
 | 
				
			||||||
 | 
					            ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (!empty($updateData)) {
 | 
				
			||||||
 | 
					                $obj = new static();
 | 
				
			||||||
 | 
					                $obj->saveAll($updateData);
 | 
				
			||||||
 | 
					                return $res;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        $res['code'] = 1;
 | 
				
			||||||
 | 
					        $res['msg']  = '无需调整';
 | 
				
			||||||
 | 
					        return $res;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 查询列表 [带分页 适用于后台]
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param  array  $data  查询数据 格式如下
 | 
				
			||||||
 | 
					     * [
 | 
				
			||||||
 | 
					     *   'fields' => ['id','title','desc'],//查询字段
 | 
				
			||||||
 | 
					     *   'where'  => [
 | 
				
			||||||
 | 
					     *                  ['name', 'like', '%thinkphp%'],
 | 
				
			||||||
 | 
					     *                  ['title', 'like', '%thinkphp%'],
 | 
				
			||||||
 | 
					     *                  ['id', '>', 0],
 | 
				
			||||||
 | 
					     *                  ['status', '=', 1],
 | 
				
			||||||
 | 
					     *               ],//查询条件
 | 
				
			||||||
 | 
					     *   'order'  => ['order'=>'desc','id'=>'desc'],//排序
 | 
				
			||||||
 | 
					     *   'size' => 50,//每页数量
 | 
				
			||||||
 | 
					     * ]
 | 
				
			||||||
 | 
					     * @param  array  $pageParams  分页参数 具体参考:https://www.kancloud.cn/manual/thinkphp6_0/1037638
 | 
				
			||||||
 | 
					     * @param  callable|null  $callback  复杂查询条件 使用闭包查询 此时建议data留空
 | 
				
			||||||
 | 
					     * @return Paginator
 | 
				
			||||||
 | 
					     * @throws DbException
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public static function findListWithPaginate(array $data = [], array $pageParams = [], callable $callback = null): Paginator
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $q      = new static();
 | 
				
			||||||
 | 
					        $fields = isset($data['fields']) && !empty($data['fields']) ? $data['fields'] : [];
 | 
				
			||||||
 | 
					        $where  = isset($data['where']) && !empty($data['where']) ? $data['where'] : [];
 | 
				
			||||||
 | 
					        $order  = isset($data['order']) && !empty($data['order']) ? $data['order'] : [];
 | 
				
			||||||
 | 
					        $limit  = $data['size'] ?? 20;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (count($where)) {
 | 
				
			||||||
 | 
					            $q = $q->where($where);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (count($fields)) {
 | 
				
			||||||
 | 
					            $q = $q->field($fields);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($callback) {
 | 
				
			||||||
 | 
					            $q = $callback($q);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (count($order)) {
 | 
				
			||||||
 | 
					            $q = $q->order($order);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $pageParams['list_rows'] = $limit;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $q->paginate($pageParams);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 查询列表
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param  array  $simpleWhere  简易查询条件
 | 
				
			||||||
 | 
					     * @param  array  $fields  查询字段 []表示全部
 | 
				
			||||||
 | 
					     * @param  int  $page  默认第一页 0不限制
 | 
				
			||||||
 | 
					     * @param  int  $limit  限制条数 0不限制
 | 
				
			||||||
 | 
					     * @param  callable|null  $callback  复杂的条件 使用闭包查询
 | 
				
			||||||
 | 
					     * @param  array  $orders 键值对,排序
 | 
				
			||||||
 | 
					     * @return array
 | 
				
			||||||
 | 
					     * @throws Exception
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public static function findList(array $simpleWhere = [], array $fields = [], int $page = 1, int $limit = 0, callable $callback = null, array $orders = []): array
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $q    = new static();
 | 
				
			||||||
 | 
					        $data = [
 | 
				
			||||||
 | 
					            'total'   => 0,
 | 
				
			||||||
 | 
					            'current' => $page,
 | 
				
			||||||
 | 
					            'size'    => $limit,
 | 
				
			||||||
 | 
					            'list'    => new Collection(),
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (count($fields)) {
 | 
				
			||||||
 | 
					            $q = $q->field($fields);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (count($simpleWhere)) {
 | 
				
			||||||
 | 
					            $q = $q->where($simpleWhere);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($callback) {
 | 
				
			||||||
 | 
					            $q = $callback($q);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $data['total'] = $q->count();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($data['total']) {
 | 
				
			||||||
 | 
					            if (count($orders)) {
 | 
				
			||||||
 | 
					                $q = $q->order($orders);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            if ($page) {
 | 
				
			||||||
 | 
					                $q = $q->page($page);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            if ($limit == 0) {
 | 
				
			||||||
 | 
					                $q = $q->limit(1000);
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                $q = $q->limit($limit);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $data['list'] = $q->select();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $data;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 获取路径
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param  int  $pid
 | 
				
			||||||
 | 
					     * @return string
 | 
				
			||||||
 | 
					     * @throws DataNotFoundException
 | 
				
			||||||
 | 
					     * @throws DbException
 | 
				
			||||||
 | 
					     * @throws ModelNotFoundException
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public static function getPath(int $pid): string
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if ($pid == 0) {
 | 
				
			||||||
 | 
					            $path = ',0,';
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            $parent = self::findById($pid);
 | 
				
			||||||
 | 
					            if (empty($parent)) {
 | 
				
			||||||
 | 
					                $path = ',0,';
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                $path = $parent['path'].$parent['id'].',';
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $path;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 刷新路径
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param  int  $pid
 | 
				
			||||||
 | 
					     * @param  array  $data  默认全部 若data不为空 至少包含[id,path, $pidField]
 | 
				
			||||||
 | 
					     * @param  string  $pidField  父级ID字段名 默认 pid
 | 
				
			||||||
 | 
					     * @throws Exception
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public static function refreshPath(int $pid = 0, array $data = [], string $pidField = 'pid')
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $data           = !empty($data) ? $data : self::column('id,path,'.$pidField);
 | 
				
			||||||
 | 
					        $updateAllPaths = [];
 | 
				
			||||||
 | 
					        self::recursionPath($pid, $data, $updateAllPaths);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        (new static())->saveAll($updateAllPaths);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 获取递归最新路径
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param  int  $pid
 | 
				
			||||||
 | 
					     * @param  array  $data  全部数据 尽量传全部数据
 | 
				
			||||||
 | 
					     * @param  array  $paths
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public static function recursionPath(int $pid, array $data, array &$paths = [])
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        foreach ($data as $k => $v) {
 | 
				
			||||||
 | 
					            if ($pid == $v['pid']) {
 | 
				
			||||||
 | 
					                $arr       = [];
 | 
				
			||||||
 | 
					                $arr['id'] = $v['id'];
 | 
				
			||||||
 | 
					                if ($pid == 0) {
 | 
				
			||||||
 | 
					                    $arr['path'] = ',0,';
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    $arr['path'] = $paths[$v['pid']]['path'].$v['pid'].',';
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                $paths[$v['id']] = $arr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                unset($data[$k]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                self::recursionPath($v['id'], $data, $paths);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 获取所有后代ID[包含孙级]  仅对拥有path字段的表生效
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param  int  $id
 | 
				
			||||||
 | 
					     * @return array
 | 
				
			||||||
 | 
					     * @throws DataNotFoundException
 | 
				
			||||||
 | 
					     * @throws DbException
 | 
				
			||||||
 | 
					     * @throws ModelNotFoundException
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public static function getAllChildrenIds(int $id): array
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $item = self::find($id);
 | 
				
			||||||
 | 
					        if ($item && isset($item['path'])) {
 | 
				
			||||||
 | 
					            $path = $item['path'].$id.',';
 | 
				
			||||||
 | 
					            return self::where('path', 'like', $path.'%')->column('id');
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            return [];
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,29 @@
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace app\model;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * 资料审核日志
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Class CheckLog
 | 
				
			||||||
 | 
					 * @package app\model
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					class CheckLog extends Base
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    // 获取用户待审核或审核失败的资料
 | 
				
			||||||
 | 
					    public static function getCheckInfo(int $accountId)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return self::alias('cl')
 | 
				
			||||||
 | 
					            ->leftJoin('position p', 'p.id = cl.position')
 | 
				
			||||||
 | 
					            ->where('cl.account_id', $accountId)
 | 
				
			||||||
 | 
					//            ->whereIn('cl.status', [self::COMMON_OFF, -1])
 | 
				
			||||||
 | 
					            ->field('cl.*,p.name as position_name')
 | 
				
			||||||
 | 
					            ->order('cl.id', 'desc')
 | 
				
			||||||
 | 
					            ->find();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function account()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return $this->hasOne(Account::class, 'id', 'account_id');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,41 @@
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace app\model;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * 打卡日志
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Class ClockLog
 | 
				
			||||||
 | 
					 * @package app\model
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					class ClockLog extends Base
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public const TYPE_IN  = 'in';//上班
 | 
				
			||||||
 | 
					    public const TYPE_OUT = 'out';//下班
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public const STATUS_TODO = 0;//待审核
 | 
				
			||||||
 | 
					    public const STATUS_YES  = 1;//通过
 | 
				
			||||||
 | 
					    public const STATUS_NO   = -1;//不通过
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function account()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return $this->hasOne(Account::class, 'id', 'account_id');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public static function typeText(): array
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return [
 | 
				
			||||||
 | 
					            self::TYPE_IN  => '上班',
 | 
				
			||||||
 | 
					            self::TYPE_OUT => '下班',
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public static function statusText(): array
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return [
 | 
				
			||||||
 | 
					            self::STATUS_TODO => '待审核',
 | 
				
			||||||
 | 
					            self::STATUS_YES  => '审核通过',
 | 
				
			||||||
 | 
					            self::STATUS_NO   => '审核拒绝',
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,25 @@
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace app\model;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * 配置表
 | 
				
			||||||
 | 
					 * Class Config
 | 
				
			||||||
 | 
					 * @package app\model
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					class Config extends Base
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    // 路径都没有加前缀/ 需要的地方自行添加
 | 
				
			||||||
 | 
					    // 小程序内容详情路径----新闻内容详情 包含: 关于我们模型、普通文章模型
 | 
				
			||||||
 | 
					    public const MINI_PATH_ARCHIVES = 'pagesB/articleDetail/articleDetail';
 | 
				
			||||||
 | 
					    // 小程序病种详情路径----病种内容详情(前端叫法) 包含: 非我们模型、普通文章模型的其他模型 如问题文章、科普视频等
 | 
				
			||||||
 | 
					    public const MINI_PATH_PROBLEM = 'pagesB/problemDetail/problemDetail';
 | 
				
			||||||
 | 
					    // 小程序预约列表界面
 | 
				
			||||||
 | 
					    public const MINI_PATH_APPOINTMENT = 'pagesA/makeAnPppointment/makeAnPppointment';
 | 
				
			||||||
 | 
					    // 小程序消息中心
 | 
				
			||||||
 | 
					    public const MINI_PATH_MESSAGE_CENTER = 'pagesB/messagecenter/messagecenter';
 | 
				
			||||||
 | 
					    // 商品详情
 | 
				
			||||||
 | 
					    public const MINI_PATH_SPU_INFO = 'pagesB/shop-detail/shop-detail';
 | 
				
			||||||
 | 
					    // 课程详情
 | 
				
			||||||
 | 
					    public const MINI_PATH_COURSE_INFO = 'pagesB/course-detail/course-detail';
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,13 @@
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace app\model;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * 优惠券
 | 
				
			||||||
 | 
					 * Class Coupon
 | 
				
			||||||
 | 
					 * @package app\model
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					class Coupon extends Base
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,167 @@
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace app\model;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use app\service\AliOss;
 | 
				
			||||||
 | 
					use Exception;
 | 
				
			||||||
 | 
					use Qiniu\Auth;
 | 
				
			||||||
 | 
					use Qiniu\Storage\UploadManager;
 | 
				
			||||||
 | 
					use think\facade\Config;
 | 
				
			||||||
 | 
					use think\Image;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class File extends Base
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    const IMG   = 'image';
 | 
				
			||||||
 | 
					    const VIDEO = 'video';
 | 
				
			||||||
 | 
					    const FILE  = 'file';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    //获取文件类型
 | 
				
			||||||
 | 
					    public static function getTypes()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return [
 | 
				
			||||||
 | 
					            'image' => '图片',
 | 
				
			||||||
 | 
					            'video' => '视频',
 | 
				
			||||||
 | 
					            'file'  => '文件'
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    //获取文件列表
 | 
				
			||||||
 | 
					    public static function getList($type = '', $page = 1, $per = 20)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $limit = ($page - 1) * $per;
 | 
				
			||||||
 | 
					        if ($type != '') {
 | 
				
			||||||
 | 
					            if (!in_array($type, array_keys(self::getTypes()))) {
 | 
				
			||||||
 | 
					                return [];
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            $items = self::where('type', $type)
 | 
				
			||||||
 | 
					                ->order('id desc');
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            $items = self::order('id desc');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        $items = $items->limit($limit, $per)->select()->toArray();
 | 
				
			||||||
 | 
					        foreach ($items as &$item) {
 | 
				
			||||||
 | 
					            $item['sizeStr'] = sizeToStr($item['size']);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return $items;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    //获取分页列表
 | 
				
			||||||
 | 
					    public static function getListPage($type = '', $per = 20)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if ($type != '') {
 | 
				
			||||||
 | 
					            if (!in_array($type, array_keys(self::getTypes()))) {
 | 
				
			||||||
 | 
					                return [];
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            return self::where('type', $type)
 | 
				
			||||||
 | 
					                ->order('id desc')
 | 
				
			||||||
 | 
					                ->paginate([
 | 
				
			||||||
 | 
					                    'list_rows' => $per,
 | 
				
			||||||
 | 
					                    'query'     => [
 | 
				
			||||||
 | 
					                        'type' => $type
 | 
				
			||||||
 | 
					                    ]
 | 
				
			||||||
 | 
					                ], false);
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            return self::order('id desc')
 | 
				
			||||||
 | 
					                ->paginate([
 | 
				
			||||||
 | 
					                    'list_rows' => $per
 | 
				
			||||||
 | 
					                ], false);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    //添加,$w_h图片尺寸大小,单位像素,只对type=img时有效
 | 
				
			||||||
 | 
					    public static function add($file, $src, $md5, $type = 'image')
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $realPath = public_path().ltrim($src, '/');
 | 
				
			||||||
 | 
					        $oss      = false;
 | 
				
			||||||
 | 
					        if (is_file($realPath) && $type == 'image') {
 | 
				
			||||||
 | 
					            $img = Image::open($realPath);
 | 
				
			||||||
 | 
					            list($w, $h) = $img->size();
 | 
				
			||||||
 | 
					            $w_h = $w.'px * '.$h.'px';
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            $w_h = '';
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $now = date('Y-m-d H:i:s');
 | 
				
			||||||
 | 
					        Attachment::pathDirHandle($src);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Config::load('extra/base', 'base');
 | 
				
			||||||
 | 
					        $baseConfig = config('base');
 | 
				
			||||||
 | 
					        if (isset($baseConfig['oss']) && $baseConfig['oss'] == 'true') {
 | 
				
			||||||
 | 
					            //            //阿里云
 | 
				
			||||||
 | 
					            //            $ossObject = AliOss::instance();
 | 
				
			||||||
 | 
					            //            try {
 | 
				
			||||||
 | 
					            //                $pathInfo = pathinfo($src);
 | 
				
			||||||
 | 
					            //
 | 
				
			||||||
 | 
					            //                $ossConfig = AliOss::config();
 | 
				
			||||||
 | 
					            //                $bucket = $ossConfig['bucket'];
 | 
				
			||||||
 | 
					            //                //是否存在
 | 
				
			||||||
 | 
					            //                if (!$ossObject->doesObjectExist($bucket, ltrim($src, '/'))) {
 | 
				
			||||||
 | 
					            //                    //创建目录
 | 
				
			||||||
 | 
					            //                    $ossObject->createObjectDir($bucket, ltrim($pathInfo['dirname'], '/'));
 | 
				
			||||||
 | 
					            //
 | 
				
			||||||
 | 
					            //                    $ossObject->uploadFile($bucket, ltrim($src, '/'), $realPath);
 | 
				
			||||||
 | 
					            //                }
 | 
				
			||||||
 | 
					            //                $oss = true;
 | 
				
			||||||
 | 
					            //            } catch (Exception $e) {
 | 
				
			||||||
 | 
					            //                \think\facade\Log::error('阿里云OSS上传文件失败 '.$e->getMessage());
 | 
				
			||||||
 | 
					            //            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // 七牛
 | 
				
			||||||
 | 
					            try {
 | 
				
			||||||
 | 
					                Config::load('extra/qiniu', 'qiniu');
 | 
				
			||||||
 | 
					                $conf = config('qiniu');
 | 
				
			||||||
 | 
					                // 控制台获取密钥:https://portal.qiniu.com/user/key
 | 
				
			||||||
 | 
					                $accessKey = $conf['qiniuAccessKey'] ?? '';
 | 
				
			||||||
 | 
					                $secretKey = $conf['qiniuSecretKey'] ?? '';
 | 
				
			||||||
 | 
					                $bucket    = $conf['bucket'] ?? '';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                // 构建鉴权对象
 | 
				
			||||||
 | 
					                $auth = new Auth($accessKey, $secretKey);
 | 
				
			||||||
 | 
					                // 生成上传 Token
 | 
				
			||||||
 | 
					                $token = $auth->uploadToken($bucket);
 | 
				
			||||||
 | 
					                // 要上传文件的本地路径
 | 
				
			||||||
 | 
					                //                $filePath = './php-logo.png';
 | 
				
			||||||
 | 
					                $filePath = $realPath;
 | 
				
			||||||
 | 
					                // 上传到七牛存储后保存的文件名
 | 
				
			||||||
 | 
					                //                $key = 'my-php-logo.png';
 | 
				
			||||||
 | 
					                $key = ltrim($src, '/');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                // 初始化 UploadManager 对象并进行文件的上传。
 | 
				
			||||||
 | 
					                $uploadMgr = new UploadManager();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                // 调用 UploadManager 的 putFile 方法进行文件的上传,该方法会判断文件大小,进而决定使用表单上传还是分片上传,无需手动配置。
 | 
				
			||||||
 | 
					                list($ret, $err) = $uploadMgr->putFile($token, $key, $filePath);
 | 
				
			||||||
 | 
					                if ($err !== null) {
 | 
				
			||||||
 | 
					                    \think\facade\Log::error('七牛云OSS上传文件失败 '.$err);
 | 
				
			||||||
 | 
					                    //                    var_dump($err);
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    //                    var_dump($ret);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            } catch (Exception $e) {
 | 
				
			||||||
 | 
					                \think\facade\Log::error('七牛云OSS上传文件失败 '.$e->getMessage());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // 将src中路径创建
 | 
				
			||||||
 | 
					        return self::create([
 | 
				
			||||||
 | 
					            'type'       => $type,
 | 
				
			||||||
 | 
					            'name'       => $file->getOriginalName(),
 | 
				
			||||||
 | 
					            'md5'        => $md5,
 | 
				
			||||||
 | 
					            'src'        => $src,
 | 
				
			||||||
 | 
					            'path'       => isset(pathinfo($src)['dirname']) ? pathinfo($src)['dirname'].'/' : '',
 | 
				
			||||||
 | 
					            'size'       => $file->getSize(),
 | 
				
			||||||
 | 
					            'suffix'     => $file->getOriginalExtension(),
 | 
				
			||||||
 | 
					            'mime_type'  => $file->getOriginalMime(),
 | 
				
			||||||
 | 
					            'created_at' => $now,
 | 
				
			||||||
 | 
					            'updated_at' => $now,
 | 
				
			||||||
 | 
					            'is_oss'     => $oss,
 | 
				
			||||||
 | 
					            'w_h'        => $w_h
 | 
				
			||||||
 | 
					        ]);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    //获取所有记录
 | 
				
			||||||
 | 
					    public static function getAll()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return self::select()->toArray();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,13 @@
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace app\model;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * 商品
 | 
				
			||||||
 | 
					 * Class Goods
 | 
				
			||||||
 | 
					 * @package app\model
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					class Goods extends Base
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,7 @@
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace app\model;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class GoodsArea extends Base
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,7 @@
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace app\model;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class GoodsCategory extends Base
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,41 @@
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace app\model;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use think\model\relation\HasOne;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Log extends Base
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    //记录操作日志
 | 
				
			||||||
 | 
					    public static function write($controller, $action, $content, $requestType = '')
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $auth = session('auth');
 | 
				
			||||||
 | 
					        return self::create([
 | 
				
			||||||
 | 
					            'member_id'    => $auth['user_id'] ?? 0,
 | 
				
			||||||
 | 
					            'name'         => $auth['username'] ?? 0,
 | 
				
			||||||
 | 
					            'ip'           => request()->ip(),
 | 
				
			||||||
 | 
					            'create_time'  => time(),
 | 
				
			||||||
 | 
					            'controller'   => $controller,
 | 
				
			||||||
 | 
					            'request_type' => $requestType,
 | 
				
			||||||
 | 
					            'action'       => $action,
 | 
				
			||||||
 | 
					            'content'      => $content
 | 
				
			||||||
 | 
					        ]);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @return HasOne
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function memberName(): HasOne
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return $this->hasOne(Member::class, 'id', 'member_id')->bind(['operator' => 'nickname']);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function getCreateTimeAttr($value)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (empty($value)) {
 | 
				
			||||||
 | 
					            return $value;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return date('Y-m-d H:i:s', $value);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,6 @@
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					namespace app\model;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class LoginLog extends Base
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,26 @@
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace app\model;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Member extends Base
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public const STATUS_NORMAL  = 1;//正常
 | 
				
			||||||
 | 
					    public const STATUS_DISABLE = 0;//禁用
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public static function getList($limit = 40)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return self::alias('m')
 | 
				
			||||||
 | 
					            ->leftjoin('auth_group g', 'g.id=m.group_id')
 | 
				
			||||||
 | 
					            ->field('m.id,m.username,m.login_time,m.group_id,g.title')
 | 
				
			||||||
 | 
					            ->order('m.id', 'asc')
 | 
				
			||||||
 | 
					            ->paginate($limit);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    //根据用户名获取管理账号
 | 
				
			||||||
 | 
					    public static function getByUserName($username)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return self::where('username', trim($username))
 | 
				
			||||||
 | 
					            ->findOrEmpty()
 | 
				
			||||||
 | 
					            ->toArray();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,71 @@
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace app\model;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use Exception;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Menu extends Base
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public const SHOW_YES = 1;
 | 
				
			||||||
 | 
					    public const SHOW_NO  = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public const STATUS_NORMAL  = 1;
 | 
				
			||||||
 | 
					    public const STATUS_DISABLE = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public const TYPE_MENU   = 'menu';
 | 
				
			||||||
 | 
					    public const TYPE_ACTION = 'action';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 默认操作
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return string[]
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public static function defaultAction(): array
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return [
 | 
				
			||||||
 | 
					            'index'  => '查看',
 | 
				
			||||||
 | 
					            'add'    => '添加',
 | 
				
			||||||
 | 
					            'edit'   => '编辑',
 | 
				
			||||||
 | 
					            'del'    => '删除',
 | 
				
			||||||
 | 
					            'sort'   => '排序',
 | 
				
			||||||
 | 
					            'modify' => '属性设置',
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 自从生成常规操作权限
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param  int  $id
 | 
				
			||||||
 | 
					     * @param  string  $name
 | 
				
			||||||
 | 
					     * @param  string  $path
 | 
				
			||||||
 | 
					     * @throws Exception
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public static function generate(int $id, string $name, string $path)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $actions = self::defaultAction();
 | 
				
			||||||
 | 
					        $delete  = [];
 | 
				
			||||||
 | 
					        $insert  = [];
 | 
				
			||||||
 | 
					        $created = date('Y-m-d H:i:s');
 | 
				
			||||||
 | 
					        foreach ($actions as $key => $action) {
 | 
				
			||||||
 | 
					            $name     = explode(':', $name)[0];
 | 
				
			||||||
 | 
					            $delete[] = $name.':'.$key;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $arr               = [];
 | 
				
			||||||
 | 
					            $arr['title']      = $action;
 | 
				
			||||||
 | 
					            $arr['pid']        = $id;
 | 
				
			||||||
 | 
					            $arr['name']       = $name.':'.$key;
 | 
				
			||||||
 | 
					            $arr['type']       = self::TYPE_ACTION;
 | 
				
			||||||
 | 
					            $arr['path']       = $path.$id.',';
 | 
				
			||||||
 | 
					            $arr['remark']     = sprintf("自动生成[%s][%s]操作", $name, $action);
 | 
				
			||||||
 | 
					            $arr['created_at'] = $created;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $insert[] = $arr;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //删除已有常规操作
 | 
				
			||||||
 | 
					        self::where('pid', $id)->whereIn('name', $delete)->delete();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //新增常规操作
 | 
				
			||||||
 | 
					        (new self())->saveAll($insert);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,51 @@
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace app\model;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Message extends Base
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    // 消息类型
 | 
				
			||||||
 | 
					    public const TYPE_SYSTEM    = 'system'; // 系统消息
 | 
				
			||||||
 | 
					    public const TYPE_NOTICE    = 'notice'; // 通知消息
 | 
				
			||||||
 | 
					    public const TYPE_REMINDERS = 'reminders'; // 日程提醒
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // 发送范围
 | 
				
			||||||
 | 
					    public const TARGET_ALL  = 'all'; // 所有用户
 | 
				
			||||||
 | 
					    public const TARGET_PART = 'part'; // 部分用户,与target_list组合查询
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 消息类型文本描述
 | 
				
			||||||
 | 
					     * @return string[]
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public static function typeTextList(): array
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return [
 | 
				
			||||||
 | 
					            self::TYPE_SYSTEM    => '系统消息',
 | 
				
			||||||
 | 
					            self::TYPE_NOTICE    => '通知消息',
 | 
				
			||||||
 | 
					            self::TYPE_REMINDERS => '日程提醒',
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 消息类型文本描述
 | 
				
			||||||
 | 
					     * @return string[]
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public static function targetTextList(): array
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return [
 | 
				
			||||||
 | 
					            self::TARGET_ALL  => '所有用户',
 | 
				
			||||||
 | 
					            self::TARGET_PART => '部分用户',
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 获取列表
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public static function getList($per = 20)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return self::order("create_time desc")
 | 
				
			||||||
 | 
					            ->paginate($per);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,12 @@
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					namespace app\model;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * 消息阅读记录
 | 
				
			||||||
 | 
					 * Class MessageLog
 | 
				
			||||||
 | 
					 * @package app\model
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					class MessageLog extends Base
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,18 @@
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					namespace app\model;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Model extends Base 
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    //获取模型列表
 | 
				
			||||||
 | 
					    public static function getList()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return self::order('sort asc')
 | 
				
			||||||
 | 
					        ->select()
 | 
				
			||||||
 | 
					        ->toArray();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    public static function onAfterInsert($model)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $model->sort = $model->id;
 | 
				
			||||||
 | 
					        $model->save();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,23 @@
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace app\model;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use think\model\relation\HasOne;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * 加班日志
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Class OvertimeLog
 | 
				
			||||||
 | 
					 * @package app\model
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					class OvertimeLog extends Base
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public const STATUS_NORMAL = 0;//待审核
 | 
				
			||||||
 | 
					    public const STATUS_YES    = 1;//通过
 | 
				
			||||||
 | 
					    public const STATUS_NO     = -1;//拒绝
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function account(): HasOne
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return $this->hasOne(Account::class, 'id', 'account_id');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,69 @@
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace app\model;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use think\model\relation\HasOne;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * 薪资日志
 | 
				
			||||||
 | 
					 * 以天为周期记录每个工人、工地的基本工资及加班工资情况
 | 
				
			||||||
 | 
					 * 记录的创建,每一次打卡或加班申请就添加当天的记录(每天、每个工地、每个工人最多一条记录)
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * !!!不要删除此表的任何数据!!!
 | 
				
			||||||
 | 
					 * !!!不要删除此表的任何数据!!!
 | 
				
			||||||
 | 
					 * !!!不要删除此表的任何数据!!!
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Class PayLog
 | 
				
			||||||
 | 
					 * @package app\model
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					class PayLog extends Base
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public function account(): HasOne
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return $this->hasOne(Account::class, 'id', 'account_id');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 创建日工资初始记录
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * 若当日记录已存在则不创建
 | 
				
			||||||
 | 
					     * 此时创建的记录 金额等数据都默认为0 需要等审核通过后在指定时间(如每日凌晨)统计相应金额并追加到此记录
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * 使用场景举例:每日凌晨2点定时任务 => 对审核通过的申请计算基本工资及加班工资追加到此记录
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * !!!千万不要因为金额记录为0就把记录删除 后续的统计操作都默认使用update进行追加。若记录不存在则会出现统计不准确的严重后果。!!!
 | 
				
			||||||
 | 
					     * @param  int  $accountId  工人ID
 | 
				
			||||||
 | 
					     * @param  int  $worksiteId  工地ID
 | 
				
			||||||
 | 
					     * @param  int  $time  工作日期(打卡、加班) 格式为Ymd 如:20220925
 | 
				
			||||||
 | 
					     * @return bool
 | 
				
			||||||
 | 
					     * @throws \think\db\exception\DbException
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public static function createWhenNotExists(int $accountId, int $worksiteId, int $time): bool
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $indexs = $accountId.'-'.$worksiteId.'-'.$time;
 | 
				
			||||||
 | 
					        if (self::where('indexs', $indexs)->count() > 0) {
 | 
				
			||||||
 | 
					            return true;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $year  = date('Y', strtotime($time));
 | 
				
			||||||
 | 
					        $month = date('m', strtotime($time));
 | 
				
			||||||
 | 
					        $day   = date('d', strtotime($time));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            self::create([
 | 
				
			||||||
 | 
					                'account_id'  => $accountId,
 | 
				
			||||||
 | 
					                'worksite_id' => $worksiteId,
 | 
				
			||||||
 | 
					                'time'        => $time,
 | 
				
			||||||
 | 
					                'indexs'      => $indexs,
 | 
				
			||||||
 | 
					                'year'        => $year,
 | 
				
			||||||
 | 
					                'month'       => $month,
 | 
				
			||||||
 | 
					                'day'         => $day,
 | 
				
			||||||
 | 
					            ]);
 | 
				
			||||||
 | 
					        } catch (\Exception $exception) {
 | 
				
			||||||
 | 
					            //弱网时,可能会出现并发提交,忽略indexs唯一索引报错
 | 
				
			||||||
 | 
					            \think\facade\Log::error('创建pay_log失败:message:'.$exception->getMessage().' line:'.$exception->getLine());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,20 @@
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace app\model;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use think\model\relation\HasOne;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * 薪资按月统计 所有数据都基于pay_log计算而来
 | 
				
			||||||
 | 
					 * 仅统计上月(含上月)以前
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Class PayMonthLog
 | 
				
			||||||
 | 
					 * @package app\model
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					class PayMonthLog extends Base
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public function account(): HasOne
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return $this->hasOne(Account::class, 'id', 'account_id');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
Some files were not shown because too many files have changed in this diff Show More
		Loading…
	
		Reference in New Issue