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