初始化
commit
82f5a8f3f5
|
@ -0,0 +1,19 @@
|
||||||
|
APP_DEBUG = true
|
||||||
|
APP_TRACE = true
|
||||||
|
|
||||||
|
[APP]
|
||||||
|
DEFAULT_TIMEZONE = Asia/Shanghai
|
||||||
|
|
||||||
|
[DATABASE]
|
||||||
|
TYPE = mysql
|
||||||
|
HOSTNAME = 211.149.245.223
|
||||||
|
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,14 @@
|
||||||
|
.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
|
|
@ -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,645 @@
|
||||||
|
<?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\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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//富文本中提取视频路径
|
||||||
|
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值转为空字符串
|
||||||
|
*
|
||||||
|
* @param array $data
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
function arrayNullToString(array $data): array
|
||||||
|
{
|
||||||
|
foreach ($data as $key => $val) {
|
||||||
|
if (is_array($val)) {
|
||||||
|
$data[$key] = arrayNullToString($val);
|
||||||
|
} elseif ($val === null) {
|
||||||
|
$data[$key] = '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* UUID
|
||||||
|
*/
|
||||||
|
if(!function_exists("createUuid")){
|
||||||
|
function createUuid($prefix = "")
|
||||||
|
{
|
||||||
|
$chars = md5(uniqid(mt_rand(), true));
|
||||||
|
$uuid = substr($chars, 0, 8) . '-'
|
||||||
|
. substr($chars, 8, 4) . '-'
|
||||||
|
. substr($chars, 12, 4) . '-'
|
||||||
|
. substr($chars, 16, 4) . '-'
|
||||||
|
. substr($chars, 20, 12);
|
||||||
|
return $prefix . str_replace("-", "", $uuid);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace app\controller;
|
||||||
|
|
||||||
|
use app\repository\OperationRepository;
|
||||||
|
use Exception;
|
||||||
|
use think\response\View;
|
||||||
|
use think\response\Redirect;
|
||||||
|
use app\repository\CmsRepository;
|
||||||
|
use app\repository\BlockRepository;
|
||||||
|
use think\db\exception\DbException;
|
||||||
|
use think\db\exception\DataNotFoundException;
|
||||||
|
use think\db\exception\ModelNotFoundException;
|
||||||
|
|
||||||
|
class About extends Base
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 列表页
|
||||||
|
*
|
||||||
|
* @return Redirect|View
|
||||||
|
* @throws DataNotFoundException
|
||||||
|
* @throws DbException
|
||||||
|
* @throws ModelNotFoundException
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
$this->setSeo();
|
||||||
|
$about = CmsRepository::getInstance()->getAbout($this->aboutCategory['id']);
|
||||||
|
$this->data['about'] = $about;
|
||||||
|
$this->data['category'] = $this->aboutCategory;
|
||||||
|
|
||||||
|
return $this->view();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,513 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace app\controller;
|
||||||
|
|
||||||
|
use app\exception\RepositoryException;
|
||||||
|
use app\repository\AccountRepository;
|
||||||
|
use app\repository\CommonRepository;
|
||||||
|
use app\repository\GoodsRepository;
|
||||||
|
use app\service\Kd100;
|
||||||
|
use app\validate\Account as VAccount;
|
||||||
|
use app\repository\OrderRepository;
|
||||||
|
use Exception;
|
||||||
|
use GuzzleHttp\Exception\GuzzleException;
|
||||||
|
use think\db\exception\DataNotFoundException;
|
||||||
|
use think\db\exception\DbException;
|
||||||
|
use think\db\exception\ModelNotFoundException;
|
||||||
|
use think\facade\Db;
|
||||||
|
use think\response\Json;
|
||||||
|
use think\response\View;
|
||||||
|
|
||||||
|
class Account extends Base
|
||||||
|
{
|
||||||
|
protected $middleware = ['login'];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 个人中心
|
||||||
|
*
|
||||||
|
* @return View
|
||||||
|
* @throws DbException
|
||||||
|
*/
|
||||||
|
public function index(): View
|
||||||
|
{
|
||||||
|
$this->data['countList'] = OrderRepository::getInstance()->findOrderCount($this->authId);
|
||||||
|
$this->data['markList'] = OrderRepository::getInstance()->auctionMarkList('', [$this->authId]);
|
||||||
|
$this->data['biddingList'] = GoodsRepository::getInstance()->auctionBiddingList($this->authId);
|
||||||
|
return $this->view();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 个人资料
|
||||||
|
*
|
||||||
|
* @return View|Json
|
||||||
|
* @throws RepositoryException
|
||||||
|
*/
|
||||||
|
public function profile()
|
||||||
|
{
|
||||||
|
$repo = AccountRepository::getInstance();
|
||||||
|
$item = $repo->findById($this->authId);
|
||||||
|
if ($this->request->isPost()) {
|
||||||
|
$post = input('post.');
|
||||||
|
$update = [];
|
||||||
|
$update['headimgurl'] = $post['headimgurl'] ?? '';
|
||||||
|
$update['sex'] = $post['sex'];
|
||||||
|
$update['nickname'] = $post['nickname'];
|
||||||
|
if (!empty($post['nickname']) && $item['nickname'] !== $post['nickname']) {
|
||||||
|
if ($item['nickname_time'] > 0) {
|
||||||
|
return $this->json(4001, '每人仅先修改一次昵称,您已修改过了。');
|
||||||
|
}
|
||||||
|
$update['nickname_time'] = $item['nickname_time'] + 1;
|
||||||
|
}
|
||||||
|
$item->save($update);
|
||||||
|
return $this->json();
|
||||||
|
}
|
||||||
|
$this->data['item'] = $item;
|
||||||
|
return $this->view();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 我的订单
|
||||||
|
*
|
||||||
|
* @return View
|
||||||
|
*/
|
||||||
|
public function order(): View
|
||||||
|
{
|
||||||
|
$accountId = $this->auth['id'] ?? 0;
|
||||||
|
$tag = input('get.tag/s', 'waiting');
|
||||||
|
|
||||||
|
$this->data['items'] = OrderRepository::getInstance()->getOrderGoods($accountId, $tag);
|
||||||
|
$this->data['tag'] = $tag;
|
||||||
|
return $this->view();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 保证金
|
||||||
|
*
|
||||||
|
* @return View
|
||||||
|
* @throws RepositoryException
|
||||||
|
*/
|
||||||
|
public function deposit(): View
|
||||||
|
{
|
||||||
|
$accountId = $this->auth['id'] ?? 0;
|
||||||
|
if (!$accountId) {
|
||||||
|
$this->error('请先登录');
|
||||||
|
}
|
||||||
|
|
||||||
|
$item = AccountRepository::getInstance()->findById($accountId, ['quota', 'id', 'deposit']);
|
||||||
|
|
||||||
|
$this->data['item'] = $item;
|
||||||
|
return $this->view();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 实名认证
|
||||||
|
*
|
||||||
|
* @return View|Json
|
||||||
|
* @throws RepositoryException
|
||||||
|
*/
|
||||||
|
public function realName()
|
||||||
|
{
|
||||||
|
$accountId = $this->auth['id'] ?? 0;
|
||||||
|
$account = AccountRepository::getInstance()->findById($accountId);
|
||||||
|
if ($this->request->isPost()) {
|
||||||
|
if (!$account) {
|
||||||
|
return $this->json(4001, '请先登录');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($account['is_real_name']) {
|
||||||
|
return $this->json(4002, '您已通过认证');
|
||||||
|
}
|
||||||
|
|
||||||
|
$post = input('post.');
|
||||||
|
$validate = new VAccount();
|
||||||
|
if (!$validate->scene('real_name')->check($post)) {
|
||||||
|
return $this->json(4003, $validate->getError());
|
||||||
|
}
|
||||||
|
|
||||||
|
$post['is_real_name'] = 1;
|
||||||
|
$account->save($post);
|
||||||
|
return $this->json();
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->data['item'] = $account;
|
||||||
|
return $this->view();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 个人账户
|
||||||
|
*
|
||||||
|
* @return View
|
||||||
|
* @throws RepositoryException
|
||||||
|
*/
|
||||||
|
public function info(): View
|
||||||
|
{
|
||||||
|
$accountId = $this->auth['id'] ?? 0;
|
||||||
|
$item = AccountRepository::getInstance()->findById($accountId);
|
||||||
|
$rechargeList = AccountRepository::getInstance()->fetchRechargeList($accountId);
|
||||||
|
$withdrawalList = AccountRepository::getInstance()->fetchWithdrawalList($accountId);
|
||||||
|
|
||||||
|
$this->data['item'] = $item;
|
||||||
|
$this->data['rechargeList'] = $rechargeList['list'];
|
||||||
|
$this->data['withdrawalList'] = $withdrawalList['list'];
|
||||||
|
return $this->view();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 中标清单
|
||||||
|
*
|
||||||
|
* @return View
|
||||||
|
* @throws DbException
|
||||||
|
*/
|
||||||
|
public function biddingList(): View
|
||||||
|
{
|
||||||
|
$accountId = $this->auth['id'] ?? 0;
|
||||||
|
$pageParams['query'] = input('get.');
|
||||||
|
$list = OrderRepository::getInstance()->auctionMarkList('', [$accountId], $pageParams);
|
||||||
|
|
||||||
|
$this->data['list'] = $list;
|
||||||
|
return $this->view();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 竞价清单
|
||||||
|
*
|
||||||
|
* @return View
|
||||||
|
*/
|
||||||
|
public function biddingLog(): View
|
||||||
|
{
|
||||||
|
$list = GoodsRepository::getInstance()->auctionBiddingList($this->authId);
|
||||||
|
|
||||||
|
$this->data['items'] = $list;
|
||||||
|
return $this->view();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 关注的拍品
|
||||||
|
*
|
||||||
|
* @return View
|
||||||
|
* @throws DataNotFoundException
|
||||||
|
* @throws DbException
|
||||||
|
* @throws ModelNotFoundException
|
||||||
|
*/
|
||||||
|
public function auctionCollection(): View
|
||||||
|
{
|
||||||
|
$accountId = $this->auth['id'] ?? 0;
|
||||||
|
$items = AccountRepository::getInstance()->fetchCollection($accountId, GoodsRepository::TYPE_AUCTION);
|
||||||
|
$this->data['items'] = $items;
|
||||||
|
return $this->view();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 商品收藏
|
||||||
|
*
|
||||||
|
* @return View
|
||||||
|
* @throws DataNotFoundException
|
||||||
|
* @throws DbException
|
||||||
|
* @throws ModelNotFoundException
|
||||||
|
*/
|
||||||
|
public function goodsCollection(): View
|
||||||
|
{
|
||||||
|
$accountId = $this->auth['id'] ?? 0;
|
||||||
|
$items = AccountRepository::getInstance()->fetchCollection($accountId, GoodsRepository::TYPE_GOODS);
|
||||||
|
$this->data['items'] = $items;
|
||||||
|
return $this->view();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 地址管理
|
||||||
|
*
|
||||||
|
* @return View
|
||||||
|
* @throws DataNotFoundException
|
||||||
|
* @throws DbException
|
||||||
|
* @throws ModelNotFoundException
|
||||||
|
*/
|
||||||
|
public function address(): View
|
||||||
|
{
|
||||||
|
$accountId = $this->auth['id'] ?? 0;
|
||||||
|
//地址列表
|
||||||
|
$addressList = AccountRepository::getInstance()->findAddressByUid($accountId);
|
||||||
|
|
||||||
|
$this->data['addressList'] = $addressList;
|
||||||
|
return $this->view();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 地址详情
|
||||||
|
*
|
||||||
|
* @return Json|View
|
||||||
|
* @throws DataNotFoundException
|
||||||
|
* @throws DbException
|
||||||
|
* @throws ModelNotFoundException
|
||||||
|
*/
|
||||||
|
public function addressDetail()
|
||||||
|
{
|
||||||
|
$resp = AccountRepository::getInstance();
|
||||||
|
$accountId = $this->auth['id'] ?? 0;
|
||||||
|
$id = input('param.id/d', 0);
|
||||||
|
$item = $resp->findAddressById($id);
|
||||||
|
if ($this->request->isPost()) {
|
||||||
|
$postItem = input('post.');
|
||||||
|
$postItem['user_id'] = $postItem['user_id'] ?? $accountId;
|
||||||
|
$resp->saveAddress($postItem);
|
||||||
|
return $this->json();
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->data['item'] = $item;
|
||||||
|
return $this->view();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 地址删除
|
||||||
|
*
|
||||||
|
* @return Json
|
||||||
|
*/
|
||||||
|
public function addressDel(): Json
|
||||||
|
{
|
||||||
|
if ($this->request->isPost()) {
|
||||||
|
$id = input('post.id/d', 0);
|
||||||
|
AccountRepository::getInstance()->delAddress($id);
|
||||||
|
return $this->json();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->json(4002, '请求方式错误');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改密码
|
||||||
|
*
|
||||||
|
* @return Json
|
||||||
|
*/
|
||||||
|
public function editPwd(): Json
|
||||||
|
{
|
||||||
|
$post = input('post.');
|
||||||
|
$accountId = $this->auth['id'] ?? 0;
|
||||||
|
$validate = new VAccount();
|
||||||
|
if (!$validate->scene('edit_password')->check($post)) {
|
||||||
|
return $this->json(4002, $validate->getError());
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
AccountRepository::getInstance()->modifyPwd($accountId, $post['old_password'], $post['password']);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
$this->json(4003, $e->getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->json();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 取消收藏|关注
|
||||||
|
*
|
||||||
|
* @return Json
|
||||||
|
* @throws DataNotFoundException
|
||||||
|
* @throws DbException
|
||||||
|
* @throws ModelNotFoundException
|
||||||
|
*/
|
||||||
|
public function unCollect(): Json
|
||||||
|
{
|
||||||
|
$accountId = $this->auth['id'] ?? 0;
|
||||||
|
$goodsId = input('post.id/d');
|
||||||
|
AccountRepository::getInstance()->unCollectGoods($accountId, $goodsId);
|
||||||
|
return $this->json();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 操作保证金 充值|退回 相应改变额度
|
||||||
|
*
|
||||||
|
* @return Json
|
||||||
|
* @throws RepositoryException
|
||||||
|
*/
|
||||||
|
public function operateDeposit(): Json
|
||||||
|
{
|
||||||
|
if ($this->request->isPost()) {
|
||||||
|
$accountId = $this->auth['id'] ?? 0;
|
||||||
|
$amount = input('post.value', 0);
|
||||||
|
$type = input('post.type/s', 'recharge');
|
||||||
|
if (!AccountRepository::getInstance()->isEnough($accountId, $amount, 'deposit')) {
|
||||||
|
return $this->json(4000, '余额不足');
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
AccountRepository::getInstance()->operateDeposit($accountId, $amount, $type);
|
||||||
|
} catch (RepositoryException $e) {
|
||||||
|
return $this->json(4002, $e->getMessage());
|
||||||
|
} catch (Exception $e) {
|
||||||
|
CommonRepository::log('保证金充值失败', $e);
|
||||||
|
return $this->json(5001, '充值失败');
|
||||||
|
}
|
||||||
|
return $this->json();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->json(4002, '请求方式错误');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 充值
|
||||||
|
*
|
||||||
|
* @return Json
|
||||||
|
* @throws GuzzleException
|
||||||
|
*/
|
||||||
|
public function rechargeAmount(): Json
|
||||||
|
{
|
||||||
|
if ($this->request->isPost()) {
|
||||||
|
$accountId = $this->auth['id'] ?? 0;
|
||||||
|
$amount = input('post.amount', 0);
|
||||||
|
$type = input('post.type/s');
|
||||||
|
if (!$accountId) {
|
||||||
|
return $this->json(4001, '请先登录');
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$qr = AccountRepository::getInstance()->recharge($accountId, (float) $amount, $type);
|
||||||
|
return $this->json(0, 'success', ['payment_order_number' => $qr['order_id'], 'code_url' => $qr['qr']]);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
CommonRepository::log('充值失败', $e);
|
||||||
|
return $this->json(5001, '充值失败:'.$e->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->json(4002, '请求方式错误');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 重新充值
|
||||||
|
*
|
||||||
|
* @return Json
|
||||||
|
* @throws GuzzleException
|
||||||
|
*/
|
||||||
|
public function rechargeAgain(): Json
|
||||||
|
{
|
||||||
|
if ($this->request->isPost()) {
|
||||||
|
$accountId = $this->auth['id'] ?? 0;
|
||||||
|
$orderId = input('post.order_id', 0);
|
||||||
|
$type = input('post.type/s');
|
||||||
|
if (!$accountId) {
|
||||||
|
return $this->json(4001, '请先登录');
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$qr = AccountRepository::getInstance()->rechargeAgain($accountId, $orderId, $type);
|
||||||
|
return $this->json(0, 'success', ['payment_order_number' => $qr['order_id'], 'code_url' => $qr['qr']]);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
CommonRepository::log('充值失败', $e);
|
||||||
|
return $this->json(5001, '充值失败:'.$e->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->json(4002, '请求方式错误');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询订单
|
||||||
|
*
|
||||||
|
* @return array|Json
|
||||||
|
* @throws DataNotFoundException
|
||||||
|
* @throws DbException
|
||||||
|
* @throws ModelNotFoundException
|
||||||
|
*/
|
||||||
|
public function checkPayment()
|
||||||
|
{
|
||||||
|
if ($this->request->isPost()) {
|
||||||
|
$res['code'] = 0;
|
||||||
|
$res['msg'] = 'success';
|
||||||
|
$res['data']['paid'] = true;
|
||||||
|
$orderId = input('post.order_id/s', ''); //订单ID
|
||||||
|
$type = input('post.type/s', 'all'); //支付方式
|
||||||
|
|
||||||
|
if (!$orderId || !$type) {
|
||||||
|
$res['code'] = 1;
|
||||||
|
$res['msg'] = '参数错误';
|
||||||
|
return $res;
|
||||||
|
}
|
||||||
|
|
||||||
|
//根据支付类型 请求接口查询订单
|
||||||
|
$hasPaid = AccountRepository::getInstance()->hasPaid($orderId, $type);
|
||||||
|
if ($hasPaid) {
|
||||||
|
AccountRepository::getInstance()->paymentLogPaid($orderId, $type);
|
||||||
|
}
|
||||||
|
$res['data']['paid'] = $hasPaid;
|
||||||
|
return $res;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->json(1, '非法请求!');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 提现
|
||||||
|
*
|
||||||
|
* @return Json
|
||||||
|
*/
|
||||||
|
public function withdrawal(): Json
|
||||||
|
{
|
||||||
|
if ($this->request->isPost()) {
|
||||||
|
$amount = input('post.amount', '');
|
||||||
|
$accountId = $this->auth['id'] ?? 0;
|
||||||
|
|
||||||
|
try {
|
||||||
|
AccountRepository::getInstance()->withdrawal($accountId, $amount);
|
||||||
|
return $this->json();
|
||||||
|
} catch (Exception $e) {
|
||||||
|
CommonRepository::log('提现失败', $e);
|
||||||
|
return $this->json(5001, '提现失败');
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->json(1, '非法请求!');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取已有订单号的支付二维码
|
||||||
|
*
|
||||||
|
* @return Json
|
||||||
|
* @throws GuzzleException
|
||||||
|
*/
|
||||||
|
public function getPaymentQr(): Json
|
||||||
|
{
|
||||||
|
if ($this->request->isPost()) {
|
||||||
|
$type = input('post.type', '');
|
||||||
|
$orderId = input('post.order_id', '');
|
||||||
|
|
||||||
|
try {
|
||||||
|
$codeQr = OrderRepository::getInstance()->generatePaymentQrCode($type, $orderId);
|
||||||
|
return $this->json(0, 'success', ['payment_order_number' => $orderId, 'code_url' => $codeQr]);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
CommonRepository::log('获取支付二维码', $e);
|
||||||
|
return $this->json(5001, '获取支付二维码');
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 物流查询
|
||||||
|
*
|
||||||
|
* @return Json
|
||||||
|
* @throws DataNotFoundException
|
||||||
|
* @throws DbException
|
||||||
|
* @throws ModelNotFoundException
|
||||||
|
*/
|
||||||
|
public function logistics(): Json
|
||||||
|
{
|
||||||
|
$orderId = input('post.order_id');
|
||||||
|
$type = input('post.type', 'goods');
|
||||||
|
|
||||||
|
// $com = 'shunfeng';
|
||||||
|
// $num = 'SF1980860132707';
|
||||||
|
|
||||||
|
if ($type == 'goods') {
|
||||||
|
if (!$delivery = OrderRepository::getInstance()->findExpressByOrder($orderId)) {
|
||||||
|
return $this->json(4001, '物流信息不存在');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!$delivery = OrderRepository::getInstance()->findExpressByAuction($orderId)) {
|
||||||
|
return $this->json(4001, '物流信息不存在');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$com = $delivery['express_code'];
|
||||||
|
$num = $delivery['express_number'];
|
||||||
|
|
||||||
|
return $this->json(0, 'success', ['res' => Kd100::query($com, $num)]);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,99 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace app\controller;
|
||||||
|
|
||||||
|
use app\model\{Archives as MArticle, Category};
|
||||||
|
use think\facade\View;
|
||||||
|
|
||||||
|
class Article extends Base
|
||||||
|
{
|
||||||
|
//详情
|
||||||
|
public function detail($id = 0)
|
||||||
|
{
|
||||||
|
|
||||||
|
if ($id <= 0) {
|
||||||
|
return $this->error('错误页面');
|
||||||
|
}
|
||||||
|
$article = MArticle::getById($id);
|
||||||
|
if (empty($article)) {
|
||||||
|
return $this->error('无此文章');
|
||||||
|
}
|
||||||
|
MArticle::updateById($id, ['views' => $article['views'] + 1]);
|
||||||
|
$category = Category::getById($article['category_id']);
|
||||||
|
$prev = MArticle::getPrevArticleByIdAndCategoryId($id, $article['category_id']);
|
||||||
|
$next = MArticle::getNextArticleByIdAndCategoryId($id, $article['category_id']);
|
||||||
|
|
||||||
|
$keywords = $article['seo_keywords'] ?: $this->system['seo_keywords'];
|
||||||
|
$description = $article['seo_description'] ?: $this->system['seo_description'];
|
||||||
|
$this->setSeo($article['title'], $keywords, $description);
|
||||||
|
$this->data['article'] = $article;
|
||||||
|
$this->data['category'] = $category;
|
||||||
|
$this->data['categoryId'] = $category['id'];
|
||||||
|
$this->data['prev'] = $prev;
|
||||||
|
$this->data['next'] = $next;
|
||||||
|
return $this->view($category['template_detail'] ?? '');
|
||||||
|
}
|
||||||
|
|
||||||
|
//列表页
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
$categoryId = input('category_id/d', 0);
|
||||||
|
if ($categoryId <= 0) {
|
||||||
|
return $this->error('错误页面');
|
||||||
|
}
|
||||||
|
$category = Category::getById($categoryId);
|
||||||
|
$page_size = 20;
|
||||||
|
if( $category['number'])$page_size= $category['number'];
|
||||||
|
|
||||||
|
if( $this->request->param("page_size/d")){
|
||||||
|
$page_size= $this->request->param("page_size/d");
|
||||||
|
cookie("article_page_size",$this->request->param("page_size/d"));
|
||||||
|
}else{
|
||||||
|
if( cookie("?article_page_size"))$page_size= cookie("article_page_size");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($category)) {
|
||||||
|
return $this->error('错误页面');
|
||||||
|
}
|
||||||
|
$description = $category['description'] ?: $this->system['seo_description'];
|
||||||
|
$this->setSeo($category['title'], $this->system['seo_keywords'], $description);
|
||||||
|
$this->data['items'] = MArticle::getListPageByCategory($categoryId, $page_size);
|
||||||
|
$this->data['category'] = $category;
|
||||||
|
$this->data['categoryId'] = $categoryId;
|
||||||
|
$this->data['page_size'] = $page_size;
|
||||||
|
$this->data['article_count'] = MArticle::getListCount($categoryId);
|
||||||
|
|
||||||
|
return $this->view($category['template_list'] ?? '');
|
||||||
|
}
|
||||||
|
|
||||||
|
//查询
|
||||||
|
public function query(): \think\response\View
|
||||||
|
{
|
||||||
|
$keyword = $this->request->param("keyword/s");
|
||||||
|
//无key值跳转到产品
|
||||||
|
if (!$keyword) $this->redirect((string)url('/articles/12.html'));
|
||||||
|
|
||||||
|
$where = [
|
||||||
|
['category_id', 'in', [5, 12, 13, 14, 15]],
|
||||||
|
['status', '=', 1],
|
||||||
|
];
|
||||||
|
|
||||||
|
$where[] = ['title', 'like', '%' . $keyword . '%'];
|
||||||
|
$param['keyword'] = $keyword;
|
||||||
|
|
||||||
|
$paginate = [
|
||||||
|
'list_rows' => 20,
|
||||||
|
'query' => $param
|
||||||
|
];
|
||||||
|
$data = MArticle::where($where)
|
||||||
|
->order("sort desc")
|
||||||
|
->paginate($paginate, false);
|
||||||
|
|
||||||
|
View::assign("items", $data);
|
||||||
|
View::assign("keyword", $keyword);
|
||||||
|
$this->data['category'] = Category::getById(5);
|
||||||
|
$this->data['categoryId'] = 5;
|
||||||
|
return $this->view("/article/product_query");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace app\controller;
|
||||||
|
|
||||||
|
use app\model\Category;
|
||||||
|
use app\model\Link;
|
||||||
|
use app\model\System;
|
||||||
|
use app\repository\BlockRepository;
|
||||||
|
use app\repository\CmsRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 控制器基础类
|
||||||
|
*/
|
||||||
|
class Base extends BaseController
|
||||||
|
{
|
||||||
|
//需要向模板传递的值
|
||||||
|
protected $data = [];
|
||||||
|
//系统配置信息
|
||||||
|
protected $system = [];
|
||||||
|
|
||||||
|
protected $auth = [];
|
||||||
|
|
||||||
|
protected $authId = 0;
|
||||||
|
|
||||||
|
protected $aboutCategory = [];
|
||||||
|
|
||||||
|
// 初始化
|
||||||
|
protected function initialize()
|
||||||
|
{
|
||||||
|
$this->auth = session('frontend_auth') ?? [];
|
||||||
|
$this->data['auth'] = $this->auth;
|
||||||
|
$this->authId = $this->auth['id'] ?? 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//设置SEO信息
|
||||||
|
protected function setSeo($title = '', $keywords = '', $description = '')
|
||||||
|
{
|
||||||
|
$this->data['seoTitle'] = $title ?: $this->system['seo_title'] ?? '';
|
||||||
|
$this->data['seoKeywords'] = $keywords ?: $this->system['seo_keywords'] ?? '';
|
||||||
|
$this->data['seoDescription'] = $description ?: $this->system['seo_description'] ?? '';
|
||||||
|
}
|
||||||
|
|
||||||
|
//模板
|
||||||
|
protected function view($template = '')
|
||||||
|
{
|
||||||
|
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,26 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace app\controller;
|
||||||
|
|
||||||
|
use app\repository\BlockRepository;
|
||||||
|
use Exception;
|
||||||
|
use think\response\View;
|
||||||
|
use app\repository\OperationRepository;
|
||||||
|
|
||||||
|
class Contact extends Base
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @return View
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public function index(): View
|
||||||
|
{
|
||||||
|
$position = ['contact_banner'];
|
||||||
|
$slides = OperationRepository::getInstance()->slideListByPosition($position);
|
||||||
|
|
||||||
|
$this->data['blocks'] = BlockRepository::getInstance()->getByCateName(BlockRepository::CATEGORY_CONTACT);
|
||||||
|
$this->data['slide'] = $slides;
|
||||||
|
$this->setSeo();
|
||||||
|
return $this->view();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
|
||||||
|
namespace app\controller;
|
||||||
|
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,101 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace app\controller;
|
||||||
|
|
||||||
|
use app\repository\OrderRepository;
|
||||||
|
use app\service\wx\WechatPay;
|
||||||
|
use Exception;
|
||||||
|
use think\facade\Log;
|
||||||
|
use think\response\Redirect;
|
||||||
|
|
||||||
|
class Index extends Base
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @return Redirect
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public function index(): Redirect
|
||||||
|
{
|
||||||
|
return $this->redirect('/manager');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 退出
|
||||||
|
*
|
||||||
|
* @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,283 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace app\controller;
|
||||||
|
|
||||||
|
use app\exception\RepositoryException;
|
||||||
|
use app\repository\CommonRepository;
|
||||||
|
use app\validate\Account as VAccount;
|
||||||
|
use app\repository\AccountRepository;
|
||||||
|
use Exception;
|
||||||
|
use Overtrue\Socialite\SocialiteManager;
|
||||||
|
use think\db\exception\DataNotFoundException;
|
||||||
|
use think\db\exception\DbException;
|
||||||
|
use think\db\exception\ModelNotFoundException;
|
||||||
|
use think\facade\Config;
|
||||||
|
use think\facade\Log;
|
||||||
|
use think\response\Json;
|
||||||
|
use think\response\Redirect;
|
||||||
|
use think\response\View;
|
||||||
|
|
||||||
|
class Login extends Base
|
||||||
|
{
|
||||||
|
protected $middleware = ['csrf'];
|
||||||
|
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
$referer = input('param.url/s', '/');
|
||||||
|
$referer = urldecode($referer);
|
||||||
|
$auth = session('frontend_auth');
|
||||||
|
if ($auth) {
|
||||||
|
return $this->redirect($referer);
|
||||||
|
}
|
||||||
|
session('login_return', $referer);
|
||||||
|
if ($this->request->isPost()) {
|
||||||
|
$username = input('post.username/s');
|
||||||
|
$password = input('post.password/s');
|
||||||
|
if (empty($username) || empty($password)) {
|
||||||
|
return $this->json(4001, '参数错误');
|
||||||
|
}
|
||||||
|
|
||||||
|
$user = AccountRepository::getInstance()->infoByPhone($username);
|
||||||
|
if (!$user) {
|
||||||
|
if (!$user = AccountRepository::getInstance()->infoByUsername($username)) {
|
||||||
|
return $this->json(4002, '账号或密码错误');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($user['password'] !== md5($password)) {
|
||||||
|
return $this->json(4003, '密码错误!若手机验证码方式注册,初始密码为手机号后6位!');
|
||||||
|
}
|
||||||
|
|
||||||
|
unset($user['password']);
|
||||||
|
session('frontend_auth', $user->toArray());
|
||||||
|
$referer = session('login_return') ?? '/';
|
||||||
|
return $this->json(0, 'success', ['login_return' => $referer]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->view();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function phone()
|
||||||
|
{
|
||||||
|
$referer = input('param.url/s', '/');
|
||||||
|
$referer = urldecode($referer);
|
||||||
|
$auth = session('frontend_auth');
|
||||||
|
if ($auth) {
|
||||||
|
return $this->redirect($referer);
|
||||||
|
}
|
||||||
|
session('login_return', $referer);
|
||||||
|
if ($this->request->isPost()) {
|
||||||
|
$phone = input('post.phone/s');
|
||||||
|
$code = input('post.code/s');
|
||||||
|
if (empty($phone) || empty($code)) {
|
||||||
|
return $this->json(4001, '参数错误');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!CommonRepository::getInstance()->checkSms($phone, $code, CommonRepository::SMS_TYPE_LOGIN)) {
|
||||||
|
return $this->json(4002, '短信验证码错误');
|
||||||
|
}
|
||||||
|
|
||||||
|
$user = AccountRepository::getInstance()->infoByPhone($phone);
|
||||||
|
if (!$user) {
|
||||||
|
$password = substr(trim($phone), -6);
|
||||||
|
$data['mobile'] = $phone;
|
||||||
|
$data['password'] = md5($password);
|
||||||
|
$data['nickname'] = trim($phone);
|
||||||
|
$data['status'] = 'normal';
|
||||||
|
$data['created_at'] = date('Y-m-d H:i:s');
|
||||||
|
$user = AccountRepository::getInstance()->create($data);
|
||||||
|
}
|
||||||
|
|
||||||
|
session('frontend_auth', $user);
|
||||||
|
$referer = session('login_return') ?? '/';
|
||||||
|
return $this->json(0, 'success', ['login_return' => $referer]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->view();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 微信登录
|
||||||
|
*
|
||||||
|
* @return Redirect|View
|
||||||
|
* @throws DataNotFoundException
|
||||||
|
* @throws DbException
|
||||||
|
* @throws ModelNotFoundException
|
||||||
|
* @throws RepositoryException
|
||||||
|
*/
|
||||||
|
public function wechat()
|
||||||
|
{
|
||||||
|
$code = input('code/s');
|
||||||
|
Config::load('extra/wechat', 'wechat');
|
||||||
|
$wechatConfig = config('wechat');
|
||||||
|
|
||||||
|
$referer = session('login_return') ?? '/';
|
||||||
|
if ($this->auth) {
|
||||||
|
return $this->redirect($referer);
|
||||||
|
} else {
|
||||||
|
if ($code) {
|
||||||
|
$config = [
|
||||||
|
'wechat' => [
|
||||||
|
'client_id' => $wechatConfig['openAppId'],
|
||||||
|
'client_secret' => $wechatConfig['openAppSecret'],
|
||||||
|
'redirect' => $wechatConfig['open_notify_url'],
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
$socialite = new SocialiteManager($config);
|
||||||
|
|
||||||
|
$user = $socialite->driver('wechat')->user();
|
||||||
|
|
||||||
|
$wechatUser = $user->getOriginal();
|
||||||
|
// $wechatUser = [
|
||||||
|
// 'openid' => 'o05Qy6rt1l7NOjrZsViC2bvS75j0',
|
||||||
|
// 'nickname' => '拙言',
|
||||||
|
// 'sex' => '1',
|
||||||
|
// 'language' => 'language',
|
||||||
|
// 'city' => 'chengdu ',
|
||||||
|
// 'province' => '四川',
|
||||||
|
// 'country' => '中国',
|
||||||
|
// 'headimgurl' => 'https://thirdwx.qlogo.cn/mmopen/vi_32/Q0j4TwGTfTIZib13lH3Sicc1BO189ibaqohRtXr3OuHw3xSHibn611kaGmmLvppOD5hHyE5IJmicTDpdwCEDw4LF9Xw/132',
|
||||||
|
// 'unionid' => 'oIrzJv6Vk8s8Hg_rJuNB8muquziw',
|
||||||
|
// ];
|
||||||
|
if (empty($wechatUser)) {
|
||||||
|
|
||||||
|
}
|
||||||
|
$account = AccountRepository::getInstance()->findOneByWhere(['unionid' => $wechatUser['unionid']]);
|
||||||
|
$data = [];
|
||||||
|
$now = date('Y-m-d H:i:s');
|
||||||
|
if (!$account) {
|
||||||
|
//无账号 新建账号
|
||||||
|
$data = $wechatUser;
|
||||||
|
$data['created_at'] = $now;
|
||||||
|
$data['status'] = AccountRepository::STATUS_NORMAL;
|
||||||
|
$account = AccountRepository::getInstance()->create($wechatUser);
|
||||||
|
}
|
||||||
|
|
||||||
|
$data['login_ip'] = $this->request->ip();
|
||||||
|
$data['last_login'] = $now;
|
||||||
|
session('frontend_auth', $account->toArray());
|
||||||
|
$account->save($data);
|
||||||
|
if (empty($account['mobile'])) {
|
||||||
|
//没有手机号 跳转绑定
|
||||||
|
return $this->redirect('/login/binding');
|
||||||
|
}
|
||||||
|
return $this->redirect($referer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$openAppId = $wechatConfig['openAppId'] ?? '';
|
||||||
|
$redirect = $wechatConfig['open_notify_url'] ?? '';
|
||||||
|
|
||||||
|
$this->data['redirect'] = urlencode($redirect);
|
||||||
|
$this->data['openAppId'] = $openAppId;
|
||||||
|
return $this->view();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 常规注册
|
||||||
|
*
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public function register(): Json
|
||||||
|
{
|
||||||
|
if ($this->request->isPost()) {
|
||||||
|
$post = input('post.');
|
||||||
|
$validate = new VAccount();
|
||||||
|
if (!$validate->scene('register')->check($post)) {
|
||||||
|
return $this->json(4001, $validate->getError());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!CommonRepository::getInstance()->checkSms($post['phone'], $post['code'], CommonRepository::SMS_TYPE_REGISTER)) {
|
||||||
|
return $this->json(4002, '验证码错误');
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
AccountRepository::getInstance()->registerByNormal($post);
|
||||||
|
} catch (RepositoryException $e) {
|
||||||
|
return $this->json(4003, $e->getMessage());
|
||||||
|
} catch (Exception $e) {
|
||||||
|
Log::error(sprintf("[注册失败]%s:%s %s", $e->getFile(), $e->getLine(), $e->getMessage()));
|
||||||
|
return $this->json(5001, '注册失败');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->json();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送注册验证码
|
||||||
|
*
|
||||||
|
* @return Json
|
||||||
|
*/
|
||||||
|
public function sms(): Json
|
||||||
|
{
|
||||||
|
$post = input('post.');
|
||||||
|
$validate = new VAccount();
|
||||||
|
if (!$validate->scene('send_sms')->check($post)) {
|
||||||
|
return $this->json(4001, $validate->getError());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CommonRepository::getInstance()->sendSms($post['phone'], $post['type'])) {
|
||||||
|
return $this->json();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->json(4002, '验证码发送失败');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 绑定手机号
|
||||||
|
*
|
||||||
|
* @return Redirect|Json|View
|
||||||
|
* @throws DataNotFoundException
|
||||||
|
* @throws DbException
|
||||||
|
* @throws ModelNotFoundException
|
||||||
|
* @throws RepositoryException
|
||||||
|
*/
|
||||||
|
public function binding()
|
||||||
|
{
|
||||||
|
if ($this->request->isPost()) {
|
||||||
|
$post = input('post.');
|
||||||
|
$validate = new VAccount();
|
||||||
|
if (!$validate->scene('binding')->check($post)) {
|
||||||
|
return $this->json(4001, $validate->getError());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$account = AccountRepository::getInstance()->info($this->auth['id'] ?? 0)) {
|
||||||
|
return $this->json(4006, '请先登录');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($account['mobile'])) {
|
||||||
|
return $this->json(4007, '您已绑定手机号,无需重复绑定!');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (AccountRepository::getInstance()->infoByPhone($post['phone'])) {
|
||||||
|
return $this->json(4005, '该手机已绑定账号');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!CommonRepository::getInstance()->checkSms($post['phone'], $post['code'], CommonRepository::SMS_TYPE_BINDING)) {
|
||||||
|
return $this->json(4002, '验证码错误');
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$account->save(['mobile' => $post['phone']]);
|
||||||
|
} catch (RepositoryException $e) {
|
||||||
|
return $this->json(4003, $e->getMessage());
|
||||||
|
} catch (Exception $e) {
|
||||||
|
CommonRepository::log('绑定手机号失败', $e, 'error');
|
||||||
|
return $this->json(5001, '绑定手机号失败');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->json();
|
||||||
|
} else {
|
||||||
|
if (!$account = AccountRepository::getInstance()->info($this->auth['id'] ?? 0)) {
|
||||||
|
return $this->redirect('/login');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($account['mobile'])) {
|
||||||
|
return $this->redirect('/');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $this->view();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?php
|
||||||
|
namespace app\controller;
|
||||||
|
|
||||||
|
use app\model\{Category, Block};
|
||||||
|
|
||||||
|
class Page extends Base
|
||||||
|
{
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
|
||||||
|
$categoryId=$this->request->param("category_id");
|
||||||
|
$category = Category::getById($this->request->param("category_id"));
|
||||||
|
|
||||||
|
if ($category) {
|
||||||
|
$description = $category['description'] ?: $this->system['seo_description'];
|
||||||
|
$this->setSeo($category['title'], $this->system['seo_keywords'], $description);
|
||||||
|
} else {
|
||||||
|
return $this->error('错误页面');
|
||||||
|
}
|
||||||
|
$childCategory = Category::getChildrenByParentId($categoryId);
|
||||||
|
|
||||||
|
$this->data['categoryId'] = $categoryId;
|
||||||
|
$this->data['category'] = $category;
|
||||||
|
$this->data['childCategory'] = $childCategory;
|
||||||
|
$this->data['blocks'] = Block::getByCategoryId($categoryId);
|
||||||
|
return $this->view($category['template_detail']);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace app\controller;
|
||||||
|
|
||||||
|
use app\repository\AccountRepository;
|
||||||
|
use app\repository\GoodsRepository;
|
||||||
|
use app\repository\OperationRepository;
|
||||||
|
use Exception;
|
||||||
|
use think\response\View;
|
||||||
|
|
||||||
|
class Search extends Base
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 搜索
|
||||||
|
*
|
||||||
|
* @return View
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public function index(): View
|
||||||
|
{
|
||||||
|
$tag = input('get.tag/s', 'goods');
|
||||||
|
$keyword = input('get.keyword/s', '');
|
||||||
|
$pageParams['query'][] = input('get.');
|
||||||
|
$where['size'] = 50;
|
||||||
|
$where['where'][] = ['type', '=', $tag];
|
||||||
|
$where['where'][] = ['status', '=', GoodsRepository::STATUS_ON];
|
||||||
|
$where['where'][] = ['stock', '>', 0];
|
||||||
|
$where['where'][] = ['title', 'like', '%'.$keyword.'%'];
|
||||||
|
$items = GoodsRepository::getInstance()->findListWithPaginate($where, $pageParams);
|
||||||
|
|
||||||
|
$position = ['search_banner'];
|
||||||
|
$slides = OperationRepository::getInstance()->slideListByPosition($position);
|
||||||
|
$collectedIds = $this->authId ? AccountRepository::getInstance()->getCollectedIds($this->authId, $tag) : [];
|
||||||
|
|
||||||
|
$this->data['items'] = $items;
|
||||||
|
$this->data['collectedIds'] = $collectedIds;
|
||||||
|
$this->data['slide'] = $slides;
|
||||||
|
return $this->view();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,272 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace app\controller\api;
|
||||||
|
|
||||||
|
use app\model\AccountRecord;
|
||||||
|
use app\model\Disease;
|
||||||
|
use app\repository\ArchivesRepository;
|
||||||
|
use Exception;
|
||||||
|
use think\db\exception\DataNotFoundException;
|
||||||
|
use think\db\exception\DbException;
|
||||||
|
use think\db\exception\ModelNotFoundException;
|
||||||
|
use think\response\Json;
|
||||||
|
use app\exception\RepositoryException;
|
||||||
|
|
||||||
|
class Archives extends Base
|
||||||
|
{
|
||||||
|
protected $noNeedLogin = ['course', 'detail'];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 病种列表
|
||||||
|
*
|
||||||
|
* @return Json
|
||||||
|
* @throws DataNotFoundException
|
||||||
|
* @throws DbException
|
||||||
|
* @throws ModelNotFoundException
|
||||||
|
*/
|
||||||
|
public function disease(): Json
|
||||||
|
{
|
||||||
|
$data = Disease::getListByPid();
|
||||||
|
|
||||||
|
return $this->json(0, 'success', $data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 病种问题文章列表 分类问题
|
||||||
|
*
|
||||||
|
* @return Json
|
||||||
|
*/
|
||||||
|
public function diseaseQuestion(): Json
|
||||||
|
{
|
||||||
|
$diseaseId = input('disease_id/d', 0);
|
||||||
|
|
||||||
|
try {
|
||||||
|
$data = ArchivesRepository::getInstance()->diseaseQuestion($diseaseId);
|
||||||
|
|
||||||
|
return $this->json(0, 'success', $data);
|
||||||
|
} catch (RepositoryException $e) {
|
||||||
|
return $this->json(4001, $e->getMessage());
|
||||||
|
} catch (Exception $e) {
|
||||||
|
ArchivesRepository::log($e->getMessage(), $e);
|
||||||
|
return $this->json(5000, '操作失败');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 恒美小课堂
|
||||||
|
*
|
||||||
|
* @return Json
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public function course(): Json
|
||||||
|
{
|
||||||
|
$accountId = $this->request->user['user_id'] ?? 0;
|
||||||
|
$courseId = input('course_id/d', 0);
|
||||||
|
$page = input('page/d', 1);
|
||||||
|
$size = input('size/d', 20);
|
||||||
|
|
||||||
|
try {
|
||||||
|
$data = ArchivesRepository::getInstance()->course($accountId, $courseId, $page, $size);
|
||||||
|
|
||||||
|
return $this->json(0, 'success', $data);
|
||||||
|
} catch (RepositoryException $e) {
|
||||||
|
return $this->json(4001, $e->getMessage());
|
||||||
|
} catch (Exception $e) {
|
||||||
|
ArchivesRepository::log($e->getMessage(), $e);
|
||||||
|
return $this->json(5000, '操作失败');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 热门推荐
|
||||||
|
*
|
||||||
|
* @return Json
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public function hot(): Json
|
||||||
|
{
|
||||||
|
$categoryId = input('category_id/d', 0);
|
||||||
|
$page = input('page/d', 1);
|
||||||
|
$size = input('size/d', 20);
|
||||||
|
$keyword = input('keyword/s', '');
|
||||||
|
$accountId = $this->request->user['user_id'] ?? 0;
|
||||||
|
|
||||||
|
try {
|
||||||
|
$where[] = ['hot', '=', 1];
|
||||||
|
if (!empty($keyword)) {
|
||||||
|
|
||||||
|
$keyword = trim($keyword);
|
||||||
|
$where[] = ['title|subtitle|disease_name|doctor_name', 'like', '%'.$keyword.'%'];
|
||||||
|
AccountRecord::saveSearch($accountId, $keyword);
|
||||||
|
}
|
||||||
|
$data = ArchivesRepository::getInstance()->category($accountId, $categoryId, $where, $page, $size);
|
||||||
|
|
||||||
|
return $this->json(0, 'success', $data);
|
||||||
|
} catch (RepositoryException $e) {
|
||||||
|
return $this->json(4001, $e->getMessage());
|
||||||
|
} catch (Exception $e) {
|
||||||
|
ArchivesRepository::log($e->getMessage(), $e);
|
||||||
|
return $this->json(5000, '操作失败');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取指定栏目内容列表
|
||||||
|
*
|
||||||
|
* @return Json
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public function category(): Json
|
||||||
|
{
|
||||||
|
$categoryId = input('category_id/d', 0);
|
||||||
|
$page = input('page/d', 1);
|
||||||
|
$size = input('size/d', 20);
|
||||||
|
$keyword = input('keyword/s', '');
|
||||||
|
$diseaseIds = input('disease_id/s', '');//病种 多个用逗号分隔
|
||||||
|
$accountId = $this->request->user['user_id'] ?? 0;
|
||||||
|
|
||||||
|
try {
|
||||||
|
$where = [];
|
||||||
|
if (!empty($keyword)) {
|
||||||
|
$keyword = trim($keyword);
|
||||||
|
$where[] = ['title|subtitle|disease_name|doctor_name', 'like', '%'.$keyword.'%'];
|
||||||
|
AccountRecord::saveSearch($accountId, $keyword);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($diseaseIds)) {
|
||||||
|
$where[] = ['disease_id', 'in', explode(',', $diseaseIds)];
|
||||||
|
}
|
||||||
|
|
||||||
|
$data = ArchivesRepository::getInstance()->category($accountId, $categoryId, $where, $page, $size);
|
||||||
|
return $this->json(0, 'success', $data);
|
||||||
|
} catch (RepositoryException $e) {
|
||||||
|
return $this->json(4001, $e->getMessage());
|
||||||
|
} catch (Exception $e) {
|
||||||
|
ArchivesRepository::log($e->getMessage(), $e);
|
||||||
|
return $this->json(5000, '操作失败');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取关于我们栏目内容列表
|
||||||
|
*
|
||||||
|
* @return Json
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public function about(): Json
|
||||||
|
{
|
||||||
|
$categoryId = input('category_id/d', 0);
|
||||||
|
$page = input('page/d', 1);
|
||||||
|
$size = input('size/d', 20);
|
||||||
|
$exceptId = input('except_id/d', 0);
|
||||||
|
$keyword = input('keyword/s', '');
|
||||||
|
$accountId = $this->request->user['user_id'] ?? 0;
|
||||||
|
|
||||||
|
try {
|
||||||
|
$where = [];
|
||||||
|
if (!empty($keyword)) {
|
||||||
|
$keyword = trim($keyword);
|
||||||
|
$where[] = ['title|subtitle|disease_name|doctor_name', 'like', '%'.$keyword.'%'];
|
||||||
|
AccountRecord::saveSearch($accountId, $keyword);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($exceptId > 0) {
|
||||||
|
$where[] = ['id', '<>', $exceptId];
|
||||||
|
}
|
||||||
|
|
||||||
|
$order = ['published_at' => 'desc'];
|
||||||
|
|
||||||
|
$data = ArchivesRepository::getInstance()->about($accountId, $categoryId, $where, $page, $size, $order);
|
||||||
|
return $this->json(0, 'success', $data);
|
||||||
|
} catch (RepositoryException $e) {
|
||||||
|
return $this->json(4001, $e->getMessage());
|
||||||
|
} catch (Exception $e) {
|
||||||
|
ArchivesRepository::log($e->getMessage(), $e);
|
||||||
|
return $this->json(5000, '操作失败');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 内容详情
|
||||||
|
*
|
||||||
|
* @return Json
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public function detail(): Json
|
||||||
|
{
|
||||||
|
$id = input('id/d', 0);
|
||||||
|
$shareId = input('share_id/d', 0);//分享人ID
|
||||||
|
$accountId = $this->request->user['user_id'] ?? 0;
|
||||||
|
|
||||||
|
try {
|
||||||
|
$data = ArchivesRepository::getInstance()->detail($id, $accountId, $shareId);
|
||||||
|
return $this->json(0, 'success', $data);
|
||||||
|
} catch (RepositoryException $e) {
|
||||||
|
return $this->json(4001, $e->getMessage());
|
||||||
|
} catch (Exception $e) {
|
||||||
|
ArchivesRepository::log($e->getMessage(), $e);
|
||||||
|
return $this->json(5000, '获取详情失败');
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 点赞、收藏
|
||||||
|
*/
|
||||||
|
public function record(): Json
|
||||||
|
{
|
||||||
|
if (!$this->request->isPost()) {
|
||||||
|
return $this->json(4000, '无效请求');
|
||||||
|
}
|
||||||
|
|
||||||
|
$accountId = $this->request->user['user_id'] ?? 0;
|
||||||
|
$archiveId = $this->request->param('archive_id/d', 0);
|
||||||
|
$action = $this->request->param('action/s', '');
|
||||||
|
|
||||||
|
try {
|
||||||
|
ArchivesRepository::getInstance()->record($accountId, $archiveId, $action);
|
||||||
|
} catch (RepositoryException $e) {
|
||||||
|
return $this->json(4001, $e->getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->json();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 取消 点赞、收藏
|
||||||
|
*/
|
||||||
|
public function unRecord(): Json
|
||||||
|
{
|
||||||
|
if (!$this->request->isPost()) {
|
||||||
|
return $this->json(4000, '无效请求');
|
||||||
|
}
|
||||||
|
|
||||||
|
$accountId = $this->request->user['user_id'] ?? 0;
|
||||||
|
$archiveId = $this->request->param('archive_id/d', 0);
|
||||||
|
$action = $this->request->param('action/s', '');
|
||||||
|
|
||||||
|
try {
|
||||||
|
ArchivesRepository::getInstance()->unRecord($accountId, $archiveId, $action);
|
||||||
|
} catch (RepositoryException $e) {
|
||||||
|
return $this->json(4001, $e->getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->json();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户内容收藏列表
|
||||||
|
*/
|
||||||
|
public function collects(): Json
|
||||||
|
{
|
||||||
|
$accountId = $this->request->user['user_id'] ?? 0;
|
||||||
|
$categoryId = $this->request->param('category_id/d', 0);
|
||||||
|
$page = $this->request->param('page/d', 1);
|
||||||
|
$size = $this->request->param('size/d', 10);
|
||||||
|
|
||||||
|
$page = $page <= 0 ? 1 : $page;
|
||||||
|
$size = $size <= 0 ? 10 : $size;
|
||||||
|
$data = ArchivesRepository::getInstance()->accountCollects($accountId, $categoryId, $page, $size);
|
||||||
|
return $this->json(0, 'success', $data);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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,94 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace app\controller\api;
|
||||||
|
|
||||||
|
use app\exception\RepositoryException;
|
||||||
|
use app\repository\AccountRepository;
|
||||||
|
use app\repository\CommonRepository;
|
||||||
|
use app\repository\OperationRepository;
|
||||||
|
use app\repository\OrderRepository;
|
||||||
|
use app\service\Sms;
|
||||||
|
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',
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送短信验证码
|
||||||
|
*
|
||||||
|
* @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);
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
$list = new Collection();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->json(0, 'success', $list);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取快递公司列表
|
||||||
|
*
|
||||||
|
* @throws ModelNotFoundException
|
||||||
|
* @throws DbException
|
||||||
|
* @throws DataNotFoundException
|
||||||
|
*/
|
||||||
|
public function expressList(): Json
|
||||||
|
{
|
||||||
|
$list = OrderRepository::getInstance()->allExpress();
|
||||||
|
return $this->json(0, 'success', $list);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,63 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace app\controller\api;
|
||||||
|
|
||||||
|
use app\exception\RepositoryException;
|
||||||
|
use app\repository\GoodsRepository;
|
||||||
|
use app\validate\Goods as GoodsValidate;
|
||||||
|
use Exception;
|
||||||
|
use think\response\Json;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 测试用
|
||||||
|
*
|
||||||
|
* Class DepartmentGoodsListLog
|
||||||
|
* @package app\controller\api
|
||||||
|
*/
|
||||||
|
class DepartmentGoodsListLog extends Base
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @return Json
|
||||||
|
* @throws RepositoryException
|
||||||
|
*/
|
||||||
|
public function list()
|
||||||
|
{
|
||||||
|
$params = $this->request->param();
|
||||||
|
$validate = new GoodsValidate();
|
||||||
|
if (!$validate->scene('base')->check($params)) {
|
||||||
|
return $this->json(4001, $validate->getError());
|
||||||
|
}
|
||||||
|
|
||||||
|
$data = GoodsRepository::getInstance()->list();
|
||||||
|
|
||||||
|
return $this->json(0, 'success', $data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取分类列表
|
||||||
|
*
|
||||||
|
* @return Json
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public function category()
|
||||||
|
{
|
||||||
|
$params = $this->request->param();
|
||||||
|
$validate = new GoodsValidate();
|
||||||
|
if (!$validate->scene('base')->check($params)) {
|
||||||
|
return $this->json(4001, $validate->getError());
|
||||||
|
}
|
||||||
|
|
||||||
|
$data = GoodsRepository::getInstance()->categoryList();
|
||||||
|
|
||||||
|
return $this->json(0, 'success', $data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testApiClassMethod()
|
||||||
|
{
|
||||||
|
$header = $this->request->header();
|
||||||
|
$all = $this->request->param();
|
||||||
|
$get = input('get.');
|
||||||
|
$post = input('post.');
|
||||||
|
return $this->json(0, 'success', ['cost'=>$cost ?? 0]);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,100 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace app\controller\api;
|
||||||
|
|
||||||
|
use app\exception\RepositoryException;
|
||||||
|
use app\job\NotifySms;
|
||||||
|
use app\model\AccountFootmarks;
|
||||||
|
use app\model\HotKeyword;
|
||||||
|
use app\repository\AccountRepository;
|
||||||
|
use app\service\ExtraConfig;
|
||||||
|
use think\Collection;
|
||||||
|
use think\facade\Queue;
|
||||||
|
use think\response\Json;
|
||||||
|
|
||||||
|
class Index extends Base
|
||||||
|
{
|
||||||
|
protected $noNeedLogin = [
|
||||||
|
'miniProgramSetting',
|
||||||
|
'clearFootmarks',
|
||||||
|
'hotKeywords'
|
||||||
|
];
|
||||||
|
|
||||||
|
public function index(): Json
|
||||||
|
{
|
||||||
|
return json(['code' => 0, 'msg' => 'I am index']);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 测试用
|
||||||
|
*
|
||||||
|
* @return Json
|
||||||
|
* @throws RepositoryException
|
||||||
|
*/
|
||||||
|
public function test(): Json
|
||||||
|
{
|
||||||
|
$userId = $this->request->middleware('userInfo')['user_id'] ?? 0;
|
||||||
|
$user = AccountRepository::getInstance()->info($userId, []);
|
||||||
|
|
||||||
|
return json(['code' => 0, 'msg' => 'I am test ', 'data' => $user]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function login(): Json
|
||||||
|
{
|
||||||
|
$userId = $this->request->middleware('userInfo')['user_id'] ?? 0;
|
||||||
|
return json(['code' => 0, 'msg' => 'I am login '.$userId]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function notify()
|
||||||
|
{
|
||||||
|
$beginNotifyList = AccountRepository::getInstance()->getBeginNotifyList();
|
||||||
|
// $res = Queue::later(3, NotifySms::class, $beginNotifyList);
|
||||||
|
// $getSuccessList = AccountRepository::getInstance()->getSuccessList();
|
||||||
|
return $this->json(0, 'success', $beginNotifyList);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 小程序个性装修配置
|
||||||
|
*/
|
||||||
|
public function miniProgramSetting(): Json
|
||||||
|
{
|
||||||
|
$conf = ExtraConfig::miniProgram();
|
||||||
|
return $this->json(0, 'success', $conf);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 推荐显示的热搜词
|
||||||
|
*/
|
||||||
|
public function hotKeywords(): Json
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$type = input('type/s',"");
|
||||||
|
$list = HotKeyword::allRecommends($type);
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
$list = new Collection();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->json(0, 'success', $list);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清理过期足迹
|
||||||
|
*
|
||||||
|
* @return Json
|
||||||
|
*/
|
||||||
|
public function clearFootmarks(): Json
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
//清理N天以前的数据
|
||||||
|
$day = 30;
|
||||||
|
$time = date('Y-m-d H:i:s', time() - $day * 86400);
|
||||||
|
$count = AccountFootmarks::where('created_at', '<', $time)->count();
|
||||||
|
AccountFootmarks::where('created_at', '<', $time)->delete();
|
||||||
|
return $this->json(0, '成功清理足迹(条):'.$count);
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
return $this->json(5000, '清理足迹失败');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace app\controller\api;
|
||||||
|
|
||||||
|
|
||||||
|
use app\model\Account;
|
||||||
|
use app\model\AccountLevel;
|
||||||
|
use app\repository\AccountRepository;
|
||||||
|
use think\response\Json;
|
||||||
|
|
||||||
|
class Level extends Base
|
||||||
|
{
|
||||||
|
protected $noNeedLogin = [
|
||||||
|
|
||||||
|
];
|
||||||
|
|
||||||
|
public function index(): Json
|
||||||
|
{
|
||||||
|
$userId = $this->request->user['user_id'] ?? 0;
|
||||||
|
$user = Account::findById($userId);
|
||||||
|
if (empty($user)) {
|
||||||
|
return json(['code' => 6001, 'msg' => '未登录']);
|
||||||
|
}
|
||||||
|
$level = AccountRepository::getInstance()->getUserLevel($user["coin_total"]);
|
||||||
|
$nextLevel = AccountRepository::getInstance()->getUserNextLevel($level["value"]);
|
||||||
|
|
||||||
|
if (!empty($nextLevel)) {
|
||||||
|
$nextLevel["disparity"] = ( $nextLevel["value"] - $user['coin_total']);
|
||||||
|
}
|
||||||
|
return $this->json(0, "ok", [
|
||||||
|
"level" => $level,
|
||||||
|
"nextLevel" => $nextLevel,
|
||||||
|
"nickname" => $user['nickname'],
|
||||||
|
"headimgurl" => $user['headimgurl'],
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,406 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace app\controller\api;
|
||||||
|
|
||||||
|
use app\exception\RepositoryException;
|
||||||
|
use app\repository\OrderRepository;
|
||||||
|
use app\validate\OrderValidate;
|
||||||
|
use app\model\Order as OrderModel;
|
||||||
|
use Exception;
|
||||||
|
use GuzzleHttp\Exception\GuzzleException;
|
||||||
|
use think\db\exception\DataNotFoundException;
|
||||||
|
use think\db\exception\DbException;
|
||||||
|
use think\db\exception\ModelNotFoundException;
|
||||||
|
use think\response\Json;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订单
|
||||||
|
*
|
||||||
|
* Class Order
|
||||||
|
* @package app\controller\api
|
||||||
|
*/
|
||||||
|
class Order extends Base
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 创建订单
|
||||||
|
*
|
||||||
|
* @return Json
|
||||||
|
* @throws GuzzleException
|
||||||
|
*/
|
||||||
|
public function create(): Json
|
||||||
|
{
|
||||||
|
if ($this->request->isPost()) {
|
||||||
|
$params = $this->request->param();
|
||||||
|
$accountId = $this->request->user['user_id'] ?? 0;
|
||||||
|
|
||||||
|
try {
|
||||||
|
$data = OrderRepository::getInstance()->createOrder($accountId, $params);
|
||||||
|
OrderRepository::getInstance()->updateSpuStock([]);
|
||||||
|
return $this->json(0, 'success', $data);
|
||||||
|
} catch (RepositoryException $e) {
|
||||||
|
return $this->json(4000, $e->getMessage());
|
||||||
|
} catch (Exception $e) {
|
||||||
|
OrderRepository::log('订单创建失败', $e, 'error', 'order');
|
||||||
|
return $this->json(5000, '订单创建失败');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $this->json(4002, '请求错误');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 购物车列表
|
||||||
|
*
|
||||||
|
* @return Json
|
||||||
|
* @throws DataNotFoundException
|
||||||
|
* @throws DbException
|
||||||
|
* @throws ModelNotFoundException
|
||||||
|
*/
|
||||||
|
public function shoppingCart(): Json
|
||||||
|
{
|
||||||
|
$params = $this->request->param();
|
||||||
|
$accountId = $this->request->user['user_id'] ?? 0;
|
||||||
|
$type = $params['type'] ?? '';
|
||||||
|
$page = $params['page'] ?? 1;
|
||||||
|
$size = $params['size'] ?? 20;
|
||||||
|
|
||||||
|
$data = OrderRepository::getInstance()->shoppingCart($accountId, $type, $page, $size);
|
||||||
|
|
||||||
|
return $this->json(0, 'success', $data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加购物车
|
||||||
|
*
|
||||||
|
* @return Json
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public function shoppingCartAdd(): Json
|
||||||
|
{
|
||||||
|
if ($this->request->isPost()) {
|
||||||
|
$params = $this->request->param();
|
||||||
|
$accountId = $this->request->user['user_id'] ?? 0;
|
||||||
|
$rules = [
|
||||||
|
'sku_id|商品' => 'require|number',
|
||||||
|
'num|数量' => 'require|number',
|
||||||
|
];
|
||||||
|
|
||||||
|
$validate = $this->validateByApi($params, $rules);
|
||||||
|
if ($validate !== true) {
|
||||||
|
return $validate;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
OrderRepository::getInstance()->shoppingCartAdd($accountId, $params['sku_id'], $params['num'] ?? 1);
|
||||||
|
return $this->json();
|
||||||
|
} catch (RepositoryException $e) {
|
||||||
|
return $this->json(4000, $e->getMessage());
|
||||||
|
} catch (Exception $e) {
|
||||||
|
OrderRepository::log('购物车添加失败', $e);
|
||||||
|
return $this->json(5000, '购物车添加失败');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $this->json(4002, '请求错误');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 购物车商品数量变更
|
||||||
|
*
|
||||||
|
* @return Json
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public function shoppingCartChangeNum(): Json
|
||||||
|
{
|
||||||
|
if ($this->request->isPost()) {
|
||||||
|
$params = $this->request->param();
|
||||||
|
$rules = [
|
||||||
|
'id|ID' => 'require|number',
|
||||||
|
'num|数量' => 'require|number',
|
||||||
|
];
|
||||||
|
|
||||||
|
$validate = $this->validateByApi($params, $rules);
|
||||||
|
if ($validate !== true) {
|
||||||
|
return $validate;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
OrderRepository::getInstance()->shoppingCartChangeNum($params['id'], $params['num']);
|
||||||
|
} catch (RepositoryException $e) {
|
||||||
|
return $this->json(4000, $e->getMessage());
|
||||||
|
} catch (Exception $e) {
|
||||||
|
OrderRepository::log('购物车数量加减失败', $e);
|
||||||
|
return $this->json(5000, '操作失败');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->json();
|
||||||
|
}
|
||||||
|
return $this->json(4002, '请求错误');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 购物车商品删除
|
||||||
|
*
|
||||||
|
* @return Json
|
||||||
|
*/
|
||||||
|
public function shoppingCartDel(): Json
|
||||||
|
{
|
||||||
|
if ($this->request->isPost()) {
|
||||||
|
$id = input('post.id/d', 0);
|
||||||
|
$accountId = $this->request->user['user_id'] ?? 0;
|
||||||
|
if (!$id) {
|
||||||
|
return $this->json(4001, '参数错误');
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
OrderRepository::getInstance()->shoppingCartDel($accountId, $id);
|
||||||
|
} catch (RepositoryException $e) {
|
||||||
|
return $this->json(4000, $e->getMessage());
|
||||||
|
} catch (Exception $e) {
|
||||||
|
OrderRepository::log('购物车数量加减失败', $e);
|
||||||
|
return $this->json(5000, '操作失败');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->json();
|
||||||
|
}
|
||||||
|
return $this->json(4002, '请求错误');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订单准备信息
|
||||||
|
* 结算页面 获取商品数据及汇总金额
|
||||||
|
* @return Json
|
||||||
|
*/
|
||||||
|
public function prepareInfo(): Json
|
||||||
|
{
|
||||||
|
if ($this->request->isPost()) {
|
||||||
|
$params = $this->request->param();
|
||||||
|
$accountId = $this->request->user['user_id'] ?? 0;
|
||||||
|
|
||||||
|
try {
|
||||||
|
$data = OrderRepository::getInstance()->prepareInfo($accountId, $params);
|
||||||
|
} catch (RepositoryException $e) {
|
||||||
|
return $this->json(4000, $e->getMessage());
|
||||||
|
} catch (Exception $e) {
|
||||||
|
OrderRepository::log('获取订单前置信息失败', $e, 'error', 'order');
|
||||||
|
return $this->json(5000, '订单信息获取失败');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->json(0, 'success', $data);
|
||||||
|
}
|
||||||
|
return $this->json(4002, '请求错误');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 支付成功通知
|
||||||
|
* 结算页面 获取商品数据及汇总金额
|
||||||
|
*
|
||||||
|
* @return Json
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public function paid(): Json
|
||||||
|
{
|
||||||
|
if ($this->request->isPost()) {
|
||||||
|
$params = $this->request->param();
|
||||||
|
$accountId = $this->request->user['user_id'] ?? 0;
|
||||||
|
$rules = [
|
||||||
|
'order_coding|订单编号' => 'require',
|
||||||
|
];
|
||||||
|
|
||||||
|
$validate = $this->validateByApi($params, $rules);
|
||||||
|
if ($validate !== true) {
|
||||||
|
return $validate;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (OrderRepository::getInstance()->setPaid($params['order_coding'])) {
|
||||||
|
return $this->json();
|
||||||
|
}
|
||||||
|
return $this->json(4003, '支付失败');
|
||||||
|
} catch (RepositoryException $e) {
|
||||||
|
return $this->json(4000, $e->getMessage());
|
||||||
|
} catch (Exception $e) {
|
||||||
|
OrderRepository::log('支付成功通知操作失败', $e);
|
||||||
|
return $this->json(5000, '操作失败');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $this->json(4002, '请求错误');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订单验收 - 确认收货
|
||||||
|
*
|
||||||
|
* @return Json
|
||||||
|
*/
|
||||||
|
public function accepted(): Json
|
||||||
|
{
|
||||||
|
if (!$this->request->isPost()) {
|
||||||
|
return $this->json(4002, '请求错误');
|
||||||
|
}
|
||||||
|
|
||||||
|
$accountId = $this->request->user['user_id'] ?? 0;
|
||||||
|
$orderId = $this->request->param('order_id', 0);
|
||||||
|
|
||||||
|
try {
|
||||||
|
OrderRepository::getInstance()->orderAccepted($orderId, $accountId);
|
||||||
|
|
||||||
|
} catch (RepositoryException $e) {
|
||||||
|
return $this->json(4000, $e->getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->json();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发货
|
||||||
|
*
|
||||||
|
* @return Json
|
||||||
|
*/
|
||||||
|
public function ship(): Json
|
||||||
|
{
|
||||||
|
if (!$this->request->isPost()) {
|
||||||
|
return $this->json(4002, '请求错误');
|
||||||
|
}
|
||||||
|
|
||||||
|
$orderId = $this->request->param('order_id', 0);
|
||||||
|
$expressId = $this->request->param('express_id', 0);
|
||||||
|
$expressNumber = $this->request->param('express_number', 0);
|
||||||
|
|
||||||
|
try {
|
||||||
|
OrderRepository::getInstance()->orderShipping($orderId, $expressId, $expressNumber);
|
||||||
|
|
||||||
|
} catch (RepositoryException $e) {
|
||||||
|
return $this->json(4000, $e->getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->json();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询订单物流
|
||||||
|
*
|
||||||
|
* @return Json
|
||||||
|
*/
|
||||||
|
public function logistics(): Json
|
||||||
|
{
|
||||||
|
$orderCoding = input('order_coding');
|
||||||
|
|
||||||
|
try {
|
||||||
|
$res = OrderRepository::getInstance()->logistics($orderCoding);
|
||||||
|
return $this->json(0, 'success', $res);
|
||||||
|
} catch (RepositoryException $e) {
|
||||||
|
return $this->json(4000, $e->getMessage());
|
||||||
|
} catch (Exception $e) {
|
||||||
|
OrderRepository::log('物流查询失败', $e);
|
||||||
|
return $this->json(5000, '获取物流信息失败');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 取消订单
|
||||||
|
*
|
||||||
|
* @return Json
|
||||||
|
* @throws DataNotFoundException
|
||||||
|
* @throws DbException
|
||||||
|
* @throws ModelNotFoundException
|
||||||
|
*/
|
||||||
|
public function cancel(): Json
|
||||||
|
{
|
||||||
|
if (!$this->request->isPost()) {
|
||||||
|
return $this->json(4002, '请求错误');
|
||||||
|
}
|
||||||
|
|
||||||
|
$orderCoding = $this->request->param('order_coding', 0);
|
||||||
|
$reason = $this->request->param('remarks', '');
|
||||||
|
|
||||||
|
try {
|
||||||
|
OrderRepository::getInstance()->setClosed($orderCoding, OrderModel::STATUS_CLOSED, $reason);
|
||||||
|
} catch (RepositoryException $e) {
|
||||||
|
return $this->json(4000, $e->getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->json();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订单付款
|
||||||
|
*
|
||||||
|
* @return Json
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public function pay(): Json
|
||||||
|
{
|
||||||
|
if (!$this->request->isPost()) {
|
||||||
|
return $this->json(4002, '请求错误');
|
||||||
|
}
|
||||||
|
|
||||||
|
$accountId = $this->request->user['user_id'] ?? 0;
|
||||||
|
$orderCoding = $this->request->param('order_coding', 0);
|
||||||
|
|
||||||
|
try {
|
||||||
|
$res = OrderRepository::getInstance()->pay($orderCoding, $accountId);
|
||||||
|
return $this->json(0, 'success', $res);
|
||||||
|
} catch (RepositoryException $e) {
|
||||||
|
return $this->json(4000, $e->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 购物车数量
|
||||||
|
*
|
||||||
|
* @return Json
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public function shoppingCartCount(): Json
|
||||||
|
{
|
||||||
|
$accountId = $this->request->user['user_id'] ?? 0;
|
||||||
|
$type = $this->request->param('type/s', 'spu');
|
||||||
|
|
||||||
|
try {
|
||||||
|
$count = OrderRepository::getInstance()->shoppingCartCount($accountId, $type);
|
||||||
|
return $this->json(0, 'success', ['count' => $count]);
|
||||||
|
} catch (RepositoryException $e) {
|
||||||
|
return $this->json(4000, $e->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 商品sku核验
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public function check(): Json
|
||||||
|
{
|
||||||
|
$orderCoding = input('order_coding/s', '');
|
||||||
|
$id = input('id/d', 0);
|
||||||
|
$checkBy = input('check_user/d', 0);
|
||||||
|
$num = input('num/d', 1);
|
||||||
|
|
||||||
|
try {
|
||||||
|
OrderRepository::getInstance()->check($orderCoding, $id, $num, $checkBy);
|
||||||
|
} catch (RepositoryException $e) {
|
||||||
|
return $this->json(4000, $e->getMessage());
|
||||||
|
} catch (Exception $e) {
|
||||||
|
OrderRepository::log('订单商品核验失败', $e);
|
||||||
|
return $this->json(5000, '订单商品核验失败');
|
||||||
|
}
|
||||||
|
return $this->json();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 商品sku核验结果
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public function checkResult(): Json
|
||||||
|
{
|
||||||
|
$orderCoding = input('order_coding/s', '');
|
||||||
|
$id = input('id/d', 0);
|
||||||
|
$notCheckNum = input('not_check_num/d', 0);
|
||||||
|
|
||||||
|
try {
|
||||||
|
$res = OrderRepository::getInstance()->checkResult($orderCoding, $id, $notCheckNum);
|
||||||
|
return $this->json(0, 'success', ['result' => (int) $res]);
|
||||||
|
} catch (RepositoryException $e) {
|
||||||
|
return $this->json(4000, $e->getMessage());
|
||||||
|
} catch (Exception $e) {
|
||||||
|
OrderRepository::log('订单商品核验结果获取失败', $e);
|
||||||
|
return $this->json(5000, '订单商品核验结果获取失败');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,152 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace app\controller\api;
|
||||||
|
|
||||||
|
use app\exception\RepositoryException;
|
||||||
|
use app\repository\BusinessRepository;
|
||||||
|
use app\repository\RechargeRepository;
|
||||||
|
use app\service\wx\WechatPay;
|
||||||
|
use app\model\Recharge as RechargeModel;
|
||||||
|
use think\facade\Db;
|
||||||
|
use think\facade\Log;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 充值
|
||||||
|
*
|
||||||
|
* Class Recharge
|
||||||
|
* @package app\controller\api
|
||||||
|
*/
|
||||||
|
class Recharge extends Base
|
||||||
|
{
|
||||||
|
protected $noNeedLogin = ['query'];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询是否支付成功
|
||||||
|
* */
|
||||||
|
public function query()
|
||||||
|
{
|
||||||
|
$orderNum = input("order_num/s");
|
||||||
|
if (empty($orderNum)) {
|
||||||
|
return $this->json("4001", "参数错误");
|
||||||
|
}
|
||||||
|
$recharge = RechargeRepository::getInstance()->getModel()->where(["order_num" => $orderNum])->lock(true)->find();
|
||||||
|
if (empty($recharge)) {
|
||||||
|
return $this->json("4001", "订单不存在");
|
||||||
|
}
|
||||||
|
if ($recharge['state'] == RechargeModel::state_on) {
|
||||||
|
return $this->json();
|
||||||
|
}
|
||||||
|
$business = BusinessRepository::getInstance()->getModel()->where(["code" => $recharge['business_code']])->lock(true)->find();
|
||||||
|
if (empty($business)) {
|
||||||
|
return $this->json("4001", "商家不存在");
|
||||||
|
}
|
||||||
|
//查询 交易成功判断条件: return_code、result_code和trade_state都为SUCCESS
|
||||||
|
$res = WechatPay::getInstance()->order->queryByOutTradeNumber($orderNum);
|
||||||
|
if ($res['return_code'] == 'SUCCESS') { // return_code 表示通信状态,不代表支付状态
|
||||||
|
if (isset($res['result_code']) && $res['result_code'] == 'SUCCESS') {
|
||||||
|
if (isset($res['trade_state']) && $res['trade_state'] == 'SUCCESS') {
|
||||||
|
Db::startTrans();
|
||||||
|
try {
|
||||||
|
//这里确定支付成功
|
||||||
|
$total_fee = $res['total_fee'] / 100;
|
||||||
|
//加余额
|
||||||
|
$business->save(["balance" => ($business["balance"] + $total_fee)]);
|
||||||
|
//修改支付状态
|
||||||
|
$recharge->save([
|
||||||
|
"money" => $total_fee,
|
||||||
|
"state" => RechargeModel::state_on,
|
||||||
|
"update_time" => date("Y-m-d H:i:s"),
|
||||||
|
"balance" => $business->balance
|
||||||
|
]);
|
||||||
|
Db::commit();
|
||||||
|
return $this->json();
|
||||||
|
} catch (RepositoryException $e) {
|
||||||
|
Db::rollback();
|
||||||
|
return $this->json("5001", $e->getMessage());
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
Db::rollback();
|
||||||
|
return $this->json("5001", "充值失败");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $this->json("4001", "未支付成功");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 微信的回调
|
||||||
|
*
|
||||||
|
* @throws \EasyWeChat\Kernel\Exceptions\Exception
|
||||||
|
*/
|
||||||
|
public function notify(){
|
||||||
|
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);
|
||||||
|
|
||||||
|
$recharge = RechargeRepository::getInstance()->getModel()->where(["order_num" => $message['out_trade_no']])->lock(true)->find();
|
||||||
|
if (empty($recharge)) {
|
||||||
|
$this->log(sprintf("[微信支付回调][%s][%s]订单支付成功,但系统查无此订单 info:%s", date('Y-m-d H:i:s'), $message['out_trade_no'], $m), 'error');
|
||||||
|
return true;//订单不存在
|
||||||
|
}
|
||||||
|
if ($recharge['state'] == RechargeModel::state_on) {
|
||||||
|
return true;//订单已经支付
|
||||||
|
}
|
||||||
|
$business = BusinessRepository::getInstance()->getModel()->where(["code" => $recharge['business_code']])->lock(true)->find();
|
||||||
|
if (empty($business)) {
|
||||||
|
$this->log(sprintf("[微信支付回调][%s][%s]订单支付成功,但商家不存在 info:%s", date('Y-m-d H:i:s'), $message['out_trade_no'], $m), 'error');
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if ($message['return_code'] == 'SUCCESS') { // return_code 表示通信状态,不代表支付状态
|
||||||
|
if (isset($message['result_code']) && $message['result_code'] == 'SUCCESS') {
|
||||||
|
if (isset($message['trade_state']) && $message['trade_state'] == 'SUCCESS') {
|
||||||
|
Db::startTrans();
|
||||||
|
try {
|
||||||
|
//这里确定支付成功
|
||||||
|
$total_fee = $message['total_fee'] / 100;
|
||||||
|
//加余额
|
||||||
|
$business->save(["balance" => ($business["balance"] + $total_fee)]);
|
||||||
|
//修改支付状态
|
||||||
|
$recharge->save([
|
||||||
|
"money" => $total_fee,
|
||||||
|
"state" => RechargeModel::state_on,
|
||||||
|
"update_time" => date("Y-m-d H:i:s"),
|
||||||
|
"balance" => $business->balance
|
||||||
|
]);
|
||||||
|
Db::commit();
|
||||||
|
//记录日志
|
||||||
|
$this->log(sprintf("[微信支付回调][%s][%s]订单支付成功 info:%s", date('Y-m-d H:i:s'), $message['out_trade_no'], $m), 'info');
|
||||||
|
return true;
|
||||||
|
} catch (RepositoryException $e) {
|
||||||
|
Db::rollback();
|
||||||
|
$this->log(sprintf("[微信支付回调][%s][%s]订单支付成功-修改订单状态失败-RepositoryException info:%s", date('Y-m-d H:i:s'), $message['out_trade_no'], $m), 'info');
|
||||||
|
return $fail('Order status edit failed.');
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
Db::rollback();
|
||||||
|
$this->log(sprintf("[微信支付回调][%s][%s]订单支付成功-修改订单状态失败-Exception info:%s", date('Y-m-d H:i:s'), $message['out_trade_no'], $m), 'info');
|
||||||
|
return $fail('Order status edit failed.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $fail('通信失败,请稍后再通知我');
|
||||||
|
});
|
||||||
|
|
||||||
|
$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,181 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace app\controller\api;
|
||||||
|
|
||||||
|
use app\exception\RepositoryException;
|
||||||
|
use app\model\Account;
|
||||||
|
use app\model\AccountSignOnline;
|
||||||
|
use app\repository\AccountRepository;
|
||||||
|
use think\Exception;
|
||||||
|
use think\facade\Config;
|
||||||
|
use think\facade\Db;
|
||||||
|
use think\response\Json;
|
||||||
|
|
||||||
|
class Sign extends Base
|
||||||
|
{
|
||||||
|
protected $noNeedLogin = [];
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 签到页面加载
|
||||||
|
* */
|
||||||
|
public function miniLoad()
|
||||||
|
{
|
||||||
|
Config::load('extra/base', 'base');
|
||||||
|
$baseConfig = config('base');
|
||||||
|
$score = isset($baseConfig['sign_score']) ? abs($baseConfig['sign_score']) : 1;
|
||||||
|
|
||||||
|
$userId = $this->request->user['user_id'] ?? 0;
|
||||||
|
if ($userId == 0) {
|
||||||
|
return $this->json(6001, "请先登录");
|
||||||
|
}
|
||||||
|
|
||||||
|
$account = Account::findOne(["id" => $userId], []);
|
||||||
|
if (empty($account)) {
|
||||||
|
return $this->json(6001, "请先登录");
|
||||||
|
}
|
||||||
|
|
||||||
|
//更新连续签到次数
|
||||||
|
AccountRepository::getInstance()->checkContinuitySign($account);
|
||||||
|
|
||||||
|
$weekDate = getLatelyWeekDate();
|
||||||
|
|
||||||
|
$weedSignInOnlineRecord = AccountRepository::getInstance()->weedSignInOnlineRecord($userId, $weekDate["1"]["date"], strtotime($weekDate["7"]["date"]) + 86399);
|
||||||
|
|
||||||
|
foreach ($weedSignInOnlineRecord as $item) {
|
||||||
|
$w = date("w", strtotime($item['created_at']));
|
||||||
|
if ($w == 0) {
|
||||||
|
$weekDate["1"]["record"] = $item["score"];
|
||||||
|
} else {
|
||||||
|
$weekDate[$w]["record"] = $item["score"];
|
||||||
|
}
|
||||||
|
$weekDate[$w]['is_sign'] = AccountSignOnline::COMMON_ON;//当天是否签到
|
||||||
|
}
|
||||||
|
$todaySignIn = AccountSignOnline::COMMON_OFF;
|
||||||
|
foreach ($weekDate as &$item) {
|
||||||
|
|
||||||
|
$key = date("m.d", strtotime($item['date']));
|
||||||
|
if (!isset($item['record'])) {
|
||||||
|
$item['record'] = $score;
|
||||||
|
$item['is_sign'] = AccountSignOnline::COMMON_OFF;//当天是否签到
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($key == date("m.d")) {
|
||||||
|
$key = "今天";
|
||||||
|
|
||||||
|
if ($item['is_sign'] == AccountSignOnline::COMMON_ON) {
|
||||||
|
$todaySignIn = AccountSignOnline::COMMON_ON;
|
||||||
|
}
|
||||||
|
} elseif ($key == (date("m.d", strtotime("+1 day")))) {
|
||||||
|
$key = "明天";
|
||||||
|
}
|
||||||
|
$item["key"] = $key;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->json(0, "操作成功", [
|
||||||
|
"sign_record" => $weekDate,
|
||||||
|
"reward_score" => $score,
|
||||||
|
"user_score" => $account['score'],
|
||||||
|
"today_sign_in" => $todaySignIn,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 签到记录
|
||||||
|
* */
|
||||||
|
|
||||||
|
public function onlineSignRecord()
|
||||||
|
{
|
||||||
|
$userId = $this->request->user['user_id'] ?? 0;
|
||||||
|
if ($userId == 0) {
|
||||||
|
return $this->json(6001, "请先登录");
|
||||||
|
}
|
||||||
|
|
||||||
|
$page = input("page/d", 1);
|
||||||
|
$size = input("size/d", 10);
|
||||||
|
|
||||||
|
$record = AccountRepository::getInstance()->onlineSignRecordList($userId, $page, $size);
|
||||||
|
if ($record->isEmpty()) {
|
||||||
|
return $this->json(4001, "没有更多");
|
||||||
|
}
|
||||||
|
return $this->json(0, "ok", $record);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 线上签到
|
||||||
|
* */
|
||||||
|
public function onlineSingIn(): Json
|
||||||
|
{
|
||||||
|
//检查是否已经签到
|
||||||
|
$userId = $this->request->user['user_id'] ?? 0;
|
||||||
|
if ($userId == 0) {
|
||||||
|
return $this->json(6001, "请先登录");
|
||||||
|
}
|
||||||
|
|
||||||
|
$check = AccountRepository::getInstance()->checkSignInOnline($userId);
|
||||||
|
if ($check) {
|
||||||
|
return $this->json(4003, "今天已经签到了,请明天再来");
|
||||||
|
}
|
||||||
|
$account = Account::findOne(["id" => $userId], [], function ($q) {
|
||||||
|
return $q->lock(true);
|
||||||
|
});
|
||||||
|
if (empty($account)) {
|
||||||
|
return $this->json(6001, "请先登录");
|
||||||
|
}
|
||||||
|
|
||||||
|
//更新连续签到次数
|
||||||
|
AccountRepository::getInstance()->checkContinuitySign($account);
|
||||||
|
|
||||||
|
Config::load('extra/base', 'base');
|
||||||
|
$baseConfig = config('base');
|
||||||
|
$score = isset($baseConfig['sign_score']) ? abs($baseConfig['sign_score']) : 1;
|
||||||
|
|
||||||
|
Db::startTrans();
|
||||||
|
try {
|
||||||
|
AccountRepository::getInstance()->SignInOnline($account, $score);
|
||||||
|
Db::commit();
|
||||||
|
return $this->json();
|
||||||
|
} catch (Exception $e) {
|
||||||
|
Db::rollback();
|
||||||
|
$this->json(4003, "签到失败");
|
||||||
|
} catch (RepositoryException $e) {
|
||||||
|
Db::rollback();
|
||||||
|
$this->json(4003, "签到失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 线下签到
|
||||||
|
* */
|
||||||
|
public function SingIn(): Json
|
||||||
|
{
|
||||||
|
//检查是否已经签到
|
||||||
|
$userId = $this->request->user['user_id'] ?? 0;
|
||||||
|
if ($userId == 0) {
|
||||||
|
return $this->json(6001, "请先登录");
|
||||||
|
}
|
||||||
|
|
||||||
|
$check = AccountRepository::getInstance()->checkSignIn($userId);
|
||||||
|
if ($check) {
|
||||||
|
return $this->json(4003, "今天已经签到了,请明天再来");
|
||||||
|
}
|
||||||
|
Db::startTrans();
|
||||||
|
try {
|
||||||
|
AccountRepository::getInstance()->SignIn($userId);
|
||||||
|
Db::commit();
|
||||||
|
return $this->json();
|
||||||
|
} catch (Exception $e) {
|
||||||
|
Db::rollback();
|
||||||
|
$this->json(4003, "签到失败");
|
||||||
|
} catch (RepositoryException $e) {
|
||||||
|
Db::rollback();
|
||||||
|
$this->json(4003, "签到失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,335 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace app\controller\api;
|
||||||
|
|
||||||
|
use app\controller\api\Base;
|
||||||
|
use app\exception\RepositoryException;
|
||||||
|
use app\model\AccountLevel;
|
||||||
|
use app\model\AccountRecord;
|
||||||
|
use app\model\AccountRole;
|
||||||
|
use app\model\Spu as SpuModel;
|
||||||
|
use app\model\Disease;
|
||||||
|
use app\model\SpuActivity;
|
||||||
|
use app\model\Staff;
|
||||||
|
use app\repository\OrderRepository;
|
||||||
|
use app\repository\SpuRepository;
|
||||||
|
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 Spu extends Base
|
||||||
|
{
|
||||||
|
protected $exceptExtra = ['list', 'category', 'detail'];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 商品列表筛选条件
|
||||||
|
*
|
||||||
|
* @throws ModelNotFoundException
|
||||||
|
* @throws DbException
|
||||||
|
* @throws DataNotFoundException
|
||||||
|
*/
|
||||||
|
public function condition(): Json
|
||||||
|
{
|
||||||
|
$list = [
|
||||||
|
'disease' => Disease::getListByPid(0, ['pid', 'name', 'id', 'sort']),
|
||||||
|
'doctor_roles' => AccountRole::findAccountRolesByGroupName(AccountRole::ROLE_GROUP_DOCTOR),
|
||||||
|
'activity' => SpuModel::activity(),
|
||||||
|
];
|
||||||
|
|
||||||
|
return $this->json(0, 'success', $list);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取已发布的商品列表
|
||||||
|
*
|
||||||
|
* @return Json
|
||||||
|
* @throws RepositoryException
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public function list(): Json
|
||||||
|
{
|
||||||
|
$repo = SpuRepository::getInstance();
|
||||||
|
|
||||||
|
$fields = SpuModel::spuListFields();
|
||||||
|
|
||||||
|
$params = input();
|
||||||
|
$params['fields'] = $fields;
|
||||||
|
$params['is_score'] = SpuModel::COMMON_OFF;//排除积分商品
|
||||||
|
|
||||||
|
$list = $repo->listForFront($params, function ($q) {
|
||||||
|
return $q->with([
|
||||||
|
'activity_info' => function ($query) {
|
||||||
|
$query->withoutField('content');
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
return $this->json(0, 'success', $list);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取已发布的积分商品列表
|
||||||
|
*
|
||||||
|
* @return Json
|
||||||
|
* @throws RepositoryException
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public function score(): Json
|
||||||
|
{
|
||||||
|
$repo = SpuRepository::getInstance();
|
||||||
|
|
||||||
|
$type = input('type/s', SpuModel::TYPE_NORMAL);//normal=综合 newest=最新
|
||||||
|
$sortField = input('sort_field/s', '');// score=积分 num=兑换量
|
||||||
|
$sortValue = input('sort_value/s', '');//desc=降序 asc=升序
|
||||||
|
|
||||||
|
$rules = [
|
||||||
|
'page|页数' => 'integer|gt:0',
|
||||||
|
'size|每页数量' => 'integer|gt:0',
|
||||||
|
'type|类型' => 'in:newest,'.SpuModel::TYPE_NORMAL,
|
||||||
|
'sort_field|排序字段' => 'in:score,amount',
|
||||||
|
'sort_value|排序值' => 'in:asc,desc',
|
||||||
|
];
|
||||||
|
|
||||||
|
$message = [
|
||||||
|
'type.in' => '类型错误',
|
||||||
|
'$sortField.in' => '排序字段错误',
|
||||||
|
'sort_value.in' => '排序值错误',
|
||||||
|
];
|
||||||
|
|
||||||
|
$params = input();
|
||||||
|
|
||||||
|
$validate = $this->validateByApi($params, $rules, $message);
|
||||||
|
if ($validate !== true) {
|
||||||
|
return $validate;
|
||||||
|
}
|
||||||
|
|
||||||
|
$order = [];//排序
|
||||||
|
|
||||||
|
// 综合排序
|
||||||
|
if ($type === SpuModel::TYPE_NORMAL) {
|
||||||
|
$order = [
|
||||||
|
'sort' => 'desc',
|
||||||
|
'id' => 'desc',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 最新排序
|
||||||
|
if ($type === 'newest') {
|
||||||
|
$order = ['published_at' => 'desc'];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 兑换量排序
|
||||||
|
if (!empty($sortField)) {
|
||||||
|
if (empty($sortValue)) {
|
||||||
|
return $this->json(4003, '排序参数错误');
|
||||||
|
}
|
||||||
|
$order = [
|
||||||
|
$sortField => $sortValue
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
$params['is_score'] = SpuModel::COMMON_ON;
|
||||||
|
$params['fields'] = SpuModel::scoreListFields();
|
||||||
|
|
||||||
|
$list = $repo->listForFront($params, function ($q) {
|
||||||
|
return $q->with([
|
||||||
|
'activity_info' => function ($query) {
|
||||||
|
$query->withoutField('content');
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
}, $order);
|
||||||
|
|
||||||
|
return $this->json(0, 'success', $list);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 收藏列表
|
||||||
|
*
|
||||||
|
* @return Json
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public function collection(): Json
|
||||||
|
{
|
||||||
|
$rules = [
|
||||||
|
'page|页数' => 'integer',
|
||||||
|
'size|每页数量' => 'integer',
|
||||||
|
];
|
||||||
|
|
||||||
|
$params = input();
|
||||||
|
$page = $params['page'] ?? 1;
|
||||||
|
$size = $params['size'] ?? 10;
|
||||||
|
$accountId = $this->request->user['user_id'] ?? 0;
|
||||||
|
|
||||||
|
|
||||||
|
$params['page'] = 1;
|
||||||
|
$params['size'] = 0;
|
||||||
|
|
||||||
|
$validate = $this->validateByApi($params, $rules);
|
||||||
|
if ($validate !== true) {
|
||||||
|
return $validate;
|
||||||
|
}
|
||||||
|
|
||||||
|
//获取收藏相关
|
||||||
|
$collection = AccountRecord::where('type', AccountRecord::TYPE_SPU)
|
||||||
|
->where('action', AccountRecord::ACTION_COLLECT)
|
||||||
|
->where('account_id', $accountId)
|
||||||
|
->where('is_record', AccountRecord::COMMON_ON)
|
||||||
|
->order('recorded_at', 'desc');
|
||||||
|
|
||||||
|
$total = $collection->count();
|
||||||
|
if ($total <= 0) {
|
||||||
|
return $this->json(0, 'success', [
|
||||||
|
'total' => 0,
|
||||||
|
'current' => $page,
|
||||||
|
'size' => $size,
|
||||||
|
'list' => new Collection(),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$recordList = $collection->page($page)->limit($size)->field('relation_id,recorded_at')->select();
|
||||||
|
|
||||||
|
$where = [];
|
||||||
|
$where[] = ['id', 'in', $recordList->column('relation_id')];
|
||||||
|
|
||||||
|
$list = SpuRepository::getInstance()->listForFront($params, function ($q) {
|
||||||
|
return $q->with([
|
||||||
|
'activity_info' => function ($query) {
|
||||||
|
$query->withoutField('content');
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
}, [], $where);
|
||||||
|
|
||||||
|
$data = [];
|
||||||
|
$spuList = $list['list']->toArray();
|
||||||
|
foreach ($recordList as $record) {
|
||||||
|
foreach ($spuList as $key => $spu) {
|
||||||
|
if ($record['relation_id'] == $spu['id']) {
|
||||||
|
$data[] = $spu;
|
||||||
|
unset($spuList[$key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$list['total'] = $total;
|
||||||
|
$list['current'] = $page;
|
||||||
|
$list['size'] = $size;
|
||||||
|
$list['list'] = $data;
|
||||||
|
|
||||||
|
return $this->json(0, 'success', $list);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SPU 详情
|
||||||
|
*/
|
||||||
|
public function detail(): Json
|
||||||
|
{
|
||||||
|
$repo = SpuRepository::getInstance();
|
||||||
|
$id = input('id/d', 0);
|
||||||
|
$shareId = input('share_id/d', 0);//分享人ID
|
||||||
|
$isActivity = input('is_activity/d', 0);//分享人ID
|
||||||
|
$accountId = $this->request->user['user_id'] ?? 0;
|
||||||
|
|
||||||
|
try {
|
||||||
|
$data = $repo->detail($id, $accountId, $shareId, (bool) $isActivity);
|
||||||
|
return $this->json(0, 'success', $data);
|
||||||
|
} catch (RepositoryException $e) {
|
||||||
|
return $this->json(4001, $e->getMessage());
|
||||||
|
} catch (Exception $e) {
|
||||||
|
$repo->log($e->getMessage(), $e);
|
||||||
|
return $this->json(5000, '获取详情失败');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取指定活动商品的拼团列表 仅限拼团活动商品
|
||||||
|
*/
|
||||||
|
public function groupList(): Json
|
||||||
|
{
|
||||||
|
$id = input('id/d', 0);
|
||||||
|
|
||||||
|
try {
|
||||||
|
$data = OrderRepository::getInstance()->getGroupList($id);
|
||||||
|
return $this->json(0, 'success', $data);
|
||||||
|
} catch (RepositoryException $e) {
|
||||||
|
return $this->json(4001, $e->getMessage());
|
||||||
|
} catch (Exception $e) {
|
||||||
|
SpuRepository::log($e->getMessage(), $e);
|
||||||
|
return $this->json(5000, '获取拼团列表失败');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 收藏
|
||||||
|
*/
|
||||||
|
public function record(): Json
|
||||||
|
{
|
||||||
|
if (!$this->request->isPost()) {
|
||||||
|
return $this->json(4000, '无效请求');
|
||||||
|
}
|
||||||
|
|
||||||
|
$accountId = $this->request->user['user_id'] ?? 0;
|
||||||
|
$id = $this->request->param('id/d', 0);
|
||||||
|
$action = $this->request->param('action/s', '');
|
||||||
|
|
||||||
|
try {
|
||||||
|
if ($accountId <= 0 || $id <= 0) {
|
||||||
|
return $this->json(4001, '无效请求');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!in_array($action, AccountRecord::allowActions())) {
|
||||||
|
return $this->json(4001, '操作类型参数错误');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!SpuModel::findById($id)) {
|
||||||
|
return $this->json(4001, '商品不存在');
|
||||||
|
}
|
||||||
|
|
||||||
|
AccountRecord::record($accountId, AccountRecord::TYPE_SPU, $action, $id);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
Log::error('[商品记录失败]'.$e->getMessage());
|
||||||
|
return $this->json(5000, '操作失败');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->json();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 取消 收藏
|
||||||
|
*/
|
||||||
|
public function unRecord(): Json
|
||||||
|
{
|
||||||
|
if (!$this->request->isPost()) {
|
||||||
|
return $this->json(4000, '无效请求');
|
||||||
|
}
|
||||||
|
|
||||||
|
$accountId = $this->request->user['user_id'] ?? 0;
|
||||||
|
$id = $this->request->param('id/d', 0);
|
||||||
|
$action = $this->request->param('action/s', '');
|
||||||
|
|
||||||
|
try {
|
||||||
|
if ($accountId <= 0 || $id <= 0) {
|
||||||
|
return $this->json(4001, '无效请求');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!in_array($action, AccountRecord::allowActions())) {
|
||||||
|
return $this->json(4001, '操作类型参数错误');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!SpuModel::findById($id)) {
|
||||||
|
return $this->json(4001, '商品不存在');
|
||||||
|
}
|
||||||
|
|
||||||
|
AccountRecord::unRecord($accountId, $id, AccountRecord::TYPE_SPU, $action);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
Log::error('[取消商品记录失败]'.$e->getMessage());
|
||||||
|
return $this->json(5000, '操作失败');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->json();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,77 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace app\controller\api;
|
||||||
|
|
||||||
|
use app\model\AccountFootmarks;
|
||||||
|
use app\model\Event;
|
||||||
|
use Exception;
|
||||||
|
use think\db\exception\DataNotFoundException;
|
||||||
|
use think\db\exception\DbException;
|
||||||
|
use think\db\exception\ModelNotFoundException;
|
||||||
|
use think\response\Json;
|
||||||
|
|
||||||
|
class Statistics extends Base
|
||||||
|
{
|
||||||
|
protected $noNeedLogin = ['event'];
|
||||||
|
/**
|
||||||
|
* 事件列表
|
||||||
|
*
|
||||||
|
* @return Json
|
||||||
|
* @throws DataNotFoundException
|
||||||
|
* @throws DbException
|
||||||
|
* @throws ModelNotFoundException
|
||||||
|
*/
|
||||||
|
public function event(): Json
|
||||||
|
{
|
||||||
|
$data = Event::field('id, name')->select()->toArray();
|
||||||
|
|
||||||
|
return $this->json(0, 'success', $data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上报
|
||||||
|
*
|
||||||
|
* @return Json
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public function report(): Json
|
||||||
|
{
|
||||||
|
$data = input();
|
||||||
|
$accountId = $this->request->user['user_id'] ?? 0;
|
||||||
|
|
||||||
|
if (empty($data)) {
|
||||||
|
return $this->json();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_array($data)) {
|
||||||
|
$data = json_decode($data, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
$insert = [];
|
||||||
|
if (count($data) > 1000) {
|
||||||
|
//TODO 太大就分片处理
|
||||||
|
|
||||||
|
} else {
|
||||||
|
foreach ($data as $d) {
|
||||||
|
if (!isset($d['e']) || !isset($d['t'])) {
|
||||||
|
return $this->json(4001, '参数错误');
|
||||||
|
}
|
||||||
|
$arr = [];
|
||||||
|
$arr['event_id'] = (int) ($d['e'] ?? 0);
|
||||||
|
$arr['account_id'] = $accountId;
|
||||||
|
$arr['content_id'] = (int) ($d['c'] ?? 0);
|
||||||
|
$t = (strlen($d['t']) == 13) ? $d['t'] / 1000 : $d['t'];
|
||||||
|
$arr['created_at'] = date('Y-m-d H:i:s', $t);
|
||||||
|
|
||||||
|
$insert[] = $arr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 若量大 时间长 可丢入队列操作
|
||||||
|
if (count($insert) > 0) {
|
||||||
|
(new AccountFootmarks())->saveAll($insert);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->json();
|
||||||
|
}
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,132 @@
|
||||||
|
<?php
|
||||||
|
namespace app\controller\api\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 bool $uploadPathIsWritable = false;
|
||||||
|
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');
|
||||||
|
if(is_writable(app()->getRootPath() . 'public' . $this->uploadPath)){
|
||||||
|
$this->uploadPathIsWritable = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
$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(date('Ymd'), $file, 'uniqid');
|
||||||
|
$src = $this->uploadPath . '/' . $src;
|
||||||
|
$return['src'] = $src;
|
||||||
|
$return['name'] = $file->getOriginalName();
|
||||||
|
|
||||||
|
//加入上传文件表
|
||||||
|
File::add($file, $src, 'file');
|
||||||
|
} 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(date('Ymd'), $image, 'uniqid');
|
||||||
|
$src = $this->uploadPath . '/' . $src;
|
||||||
|
$return['src'] = $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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 同步到OOS服务器存储
|
||||||
|
* @param string $src
|
||||||
|
*/
|
||||||
|
private function syncToOos(string $src)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @OA\Info(
|
||||||
|
* description="商城接口",
|
||||||
|
* version="1.0.0",
|
||||||
|
* title="大头商城",
|
||||||
|
* )
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @OA\Tag(
|
||||||
|
* name="common",
|
||||||
|
* description="通用",
|
||||||
|
* )
|
||||||
|
*
|
||||||
|
* @OA\Tag(
|
||||||
|
* name="home",
|
||||||
|
* description="首页",
|
||||||
|
* )
|
||||||
|
*
|
||||||
|
* @OA\Tag(
|
||||||
|
* name="goods",
|
||||||
|
* description="商品相关",
|
||||||
|
* )
|
||||||
|
* @OA\Tag(
|
||||||
|
* name="order",
|
||||||
|
* description="订单相关",
|
||||||
|
* )
|
||||||
|
* @OA\Tag(
|
||||||
|
* name="user",
|
||||||
|
* description="用户相关",
|
||||||
|
* )
|
||||||
|
*
|
||||||
|
*/
|
|
@ -0,0 +1,488 @@
|
||||||
|
<?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/alioss', 'alioss');
|
||||||
|
$config = config('alioss');
|
||||||
|
$oss = $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();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 视频列表
|
||||||
|
*
|
||||||
|
* @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/alioss', 'alioss');
|
||||||
|
$config = config('alioss');
|
||||||
|
$oss = $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()
|
||||||
|
{
|
||||||
|
Config::load('extra/alioss', 'alioss');
|
||||||
|
$config = config('alioss');
|
||||||
|
$oss = $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 = config('alioss');
|
||||||
|
|
||||||
|
$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,153 @@
|
||||||
|
<?php
|
||||||
|
namespace app\controller\manager;
|
||||||
|
|
||||||
|
use think\facade\{Db, Config, Env};
|
||||||
|
use app\model\{Log as MLog};
|
||||||
|
use app\service\Tool;
|
||||||
|
|
||||||
|
class Backup extends Base
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 因受mysql 配置参数net_buffer_length和max_allowed_packet大小的限制,因此insert语句改为单条插入
|
||||||
|
* show VARIABLES like "%net_buffer_length%" 默认单条sql语句长度16k
|
||||||
|
* show VARIABLES like "%max_allowed_packet%" 默认单个sql文件最大容量
|
||||||
|
* sql 文件注释 -- + 空格之后填写注释内容
|
||||||
|
* 因根目录文件夹权限限制,因此需要手动创建backup/data目录并赋予权限(www用户组)
|
||||||
|
*/
|
||||||
|
public function back()
|
||||||
|
{
|
||||||
|
ini_set('max_execution_time', 0);
|
||||||
|
ini_set("memory_limit",-1);
|
||||||
|
set_time_limit(0);
|
||||||
|
|
||||||
|
$path = Config::get('filesystem.disks.backup.root') . '/';
|
||||||
|
$dataBase = Env::get('database.database');
|
||||||
|
// 不要使用单引号,双引号中的变量可以解析,单引号就是绝对的字符串
|
||||||
|
$eol = "\r\n";
|
||||||
|
$eolB = "\r\n\r\n";
|
||||||
|
$info = '-- ------------------------------'.$eol;
|
||||||
|
$info .= '-- 日期: '.date('Y-m-d H:i:s',time()).$eol;
|
||||||
|
$info .= '-- MySQL --Database - '.$dataBase.$eol;
|
||||||
|
$info .= '-- ------------------------------'.$eol;
|
||||||
|
|
||||||
|
$info .= 'CREATE DATABASE IF NOT EXISTS `'.$dataBase.'` DEFAULT CHARACTER SET "utf8mb4" COLLATE "utf8mb4_general_ci";'.$eolB;
|
||||||
|
$info .= 'USE `'.$dataBase.'`;'.$eol;
|
||||||
|
|
||||||
|
if(is_dir($path)) {
|
||||||
|
if(!is_writable($path)) {
|
||||||
|
chmod($path, 0755);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
mkdir($path, 0755, true);
|
||||||
|
}
|
||||||
|
$fileName = $path.$dataBase.'_'.date('YmdHis',time()).'.sql';
|
||||||
|
if(file_exists($fileName)) {
|
||||||
|
@unlink($fileName);
|
||||||
|
}
|
||||||
|
// 以追加的方式写入
|
||||||
|
file_put_contents($fileName, $info, FILE_APPEND);
|
||||||
|
$tables = Db::query('show tables');
|
||||||
|
foreach ($tables as $table) {
|
||||||
|
// 表结构
|
||||||
|
$tableName = $table['Tables_in_'.$dataBase];
|
||||||
|
$sqlTable = 'SHOW CREATE TABLE '.$tableName;
|
||||||
|
$res = Db::query($sqlTable);
|
||||||
|
$infoTable = '-- ------------------------------'.$eol;
|
||||||
|
$infoTable .= '-- Table structure for `'.$tableName.'`'.$eol;
|
||||||
|
$infoTable .= '-- ------------------------------'.$eolB;
|
||||||
|
$infoTable .= 'DROP TABLE IF EXISTS `'.$tableName.'`;'.$eolB;
|
||||||
|
$infoTable .= $res[0]['Create Table'].';'.$eolB;
|
||||||
|
// 表数据
|
||||||
|
$infoTable .= '-- ------------------------------'.$eol;
|
||||||
|
$infoTable .= '-- Data for the table `'.$tableName.'`'.$eol;
|
||||||
|
$infoTable .= '-- ------------------------------'.$eolB;
|
||||||
|
file_put_contents($fileName, $infoTable, FILE_APPEND);
|
||||||
|
|
||||||
|
$sqlData = 'select * from '.$tableName;
|
||||||
|
$data = Db::query($sqlData);
|
||||||
|
$count = count($data);
|
||||||
|
if ($count > 0) {
|
||||||
|
$dataStr = 'INSERT INTO `'.$tableName.'` VALUE ';
|
||||||
|
foreach ($data as $k => $item) {
|
||||||
|
$valStr = '(';
|
||||||
|
foreach ($item as $val) {
|
||||||
|
// 字符串转义
|
||||||
|
$val = addslashes($val);
|
||||||
|
$valStr .= '"'.$val.'", ';
|
||||||
|
}
|
||||||
|
// 去除最后的逗号和空格
|
||||||
|
$valStr = substr($valStr,0,strlen($valStr)-2);
|
||||||
|
// 限制单条sql语句在16K以内(可根据mysql配置条件进行调整)
|
||||||
|
$sqlLength = strlen($dataStr) + strlen($valStr);
|
||||||
|
if($sqlLength >= (1024 * 16 - 10)) {
|
||||||
|
$dataStr .= $valStr.');'.$eol;
|
||||||
|
file_put_contents($fileName, $dataStr, FILE_APPEND);
|
||||||
|
// 提前分段写入后需重置数据语句
|
||||||
|
if ($k <= ($count-1)) {
|
||||||
|
$dataStr = 'INSERT INTO `'.$tableName.'` VALUE ';
|
||||||
|
} else {
|
||||||
|
$dataStr = '';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if ($k < ($count-1)) {
|
||||||
|
$dataStr .= $valStr.'),'.$eol;
|
||||||
|
} else {
|
||||||
|
$dataStr .= $valStr.');'.$eolB;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
file_put_contents($fileName, $dataStr, FILE_APPEND);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
clearstatcache();
|
||||||
|
|
||||||
|
$backups = explode('/', $fileName);
|
||||||
|
$backupName = $backups[count($backups)-1];
|
||||||
|
$src = Config::get('filesystem.disks.backup.url') . '/';
|
||||||
|
return $this->json(0, '备份成功:' . $src . $backupName);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
$path = Config::get('filesystem.disks.backup.root') . '/';
|
||||||
|
$src = Config::get('filesystem.disks.backup.url') . '/';
|
||||||
|
$items = [];
|
||||||
|
if(is_dir($path)) {
|
||||||
|
if(!is_readable($path)) {
|
||||||
|
chmod($path,0755);
|
||||||
|
}
|
||||||
|
$files = scandir($path);
|
||||||
|
foreach ($files as $file) {
|
||||||
|
if($file != '.' && $file != '..') {
|
||||||
|
$ext = substr($file, -4);
|
||||||
|
if ($ext == '.sql') {
|
||||||
|
$creatTime = substr($file, -18, 14);
|
||||||
|
$items[] = [
|
||||||
|
'file' => $file,
|
||||||
|
'path' => $src . $file,
|
||||||
|
'time' =>is_numeric($creatTime) ? date('Y-m-d H:i:s', strtotime($creatTime)) : '',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
clearstatcache();
|
||||||
|
|
||||||
|
$this->data['items'] = $items;
|
||||||
|
$this->data['backupPath'] = str_replace('\\','/', $path);
|
||||||
|
return $this->view();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function del()
|
||||||
|
{
|
||||||
|
if (request()->isPost()) {
|
||||||
|
$filePath = input('post.id');
|
||||||
|
Tool::delFile($filePath);
|
||||||
|
MLog::write('backup', 'del', '删除了备份数据文件,文件路径为:' . $filePath);
|
||||||
|
return $this->json();
|
||||||
|
} else {
|
||||||
|
return $this->json(1, '非法请求');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,104 @@
|
||||||
|
<?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)],
|
||||||
|
// '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,364 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace app\controller\manager;
|
||||||
|
|
||||||
|
use app\exception\RepositoryException;
|
||||||
|
use app\model\BusinessFlow;
|
||||||
|
use app\model\Coupon;
|
||||||
|
use app\model\CouponMain;
|
||||||
|
use app\model\Recharge;
|
||||||
|
use app\model\Business as BusinessModel;
|
||||||
|
use app\model\Member;
|
||||||
|
use app\repository\BusinessRepository;
|
||||||
|
use app\repository\CouponRepository;
|
||||||
|
use app\repository\RechargeRepository;
|
||||||
|
use app\service\wx\WechatPay;
|
||||||
|
use Exception;
|
||||||
|
|
||||||
|
use think\facade\Db;
|
||||||
|
use think\response\Json;
|
||||||
|
use think\response\View;
|
||||||
|
|
||||||
|
/*商家*/
|
||||||
|
|
||||||
|
class Business extends Base
|
||||||
|
{
|
||||||
|
protected $noNeedLogin = ['queryManagerRecharge'];
|
||||||
|
/**
|
||||||
|
* 商家列表列表
|
||||||
|
*
|
||||||
|
* @return Json|View
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
if ($this->request->isPost()) {
|
||||||
|
$model = new BusinessFlow();
|
||||||
|
$repo = BusinessRepository::getInstance($model);
|
||||||
|
$keyword = $this->request->param('keyword/s', '');
|
||||||
|
$page = $this->request->param('page/d', 1);
|
||||||
|
$size = $this->request->param('size/d', 30);
|
||||||
|
|
||||||
|
$whereMap = [["business.state", "=", BusinessModel::state_on]];
|
||||||
|
$orders = ['business.id' => 'desc'];
|
||||||
|
if (!empty($keyword)) {
|
||||||
|
$whereMap[] = ['account.nick_name|business.business_name', 'like', "%$keyword%"];
|
||||||
|
}
|
||||||
|
|
||||||
|
$list = $repo->businessList($whereMap, $page, $size, $orders);
|
||||||
|
$list["list"]->each(function ($item) {
|
||||||
|
//得到当前商家的所有优惠券
|
||||||
|
$date = date("Y-m-d H:i:s");
|
||||||
|
//优惠券总数
|
||||||
|
$item->coupon_total_count = CouponMain::where(["business_code" => $item->business->code])->sum("count");
|
||||||
|
|
||||||
|
//进行中优惠券总数
|
||||||
|
$item->coupon_doing_count = CouponMain::where(["business_code" => $item->business->code])
|
||||||
|
->whereTime("start_time", "<", $date)
|
||||||
|
->whereTime("end_time", ">", $date)
|
||||||
|
->where("status", CouponMain::status_on)
|
||||||
|
->where("on_shelf", CouponMain::on_shelf_on)
|
||||||
|
->sum("count");
|
||||||
|
|
||||||
|
//进行中优惠券总数
|
||||||
|
$item->coupon_receive_count = CouponMain::where(["business_code" => $item->business->code])->sum("received_count");
|
||||||
|
|
||||||
|
//过期未使用优惠券总数
|
||||||
|
$item->coupon_be_overdue_count = Coupon::where(["business_code" => $item->business->code])
|
||||||
|
->where("is_verificated", "=", Coupon::is_verificated_off)
|
||||||
|
->whereTime("end_time", "<", $date)
|
||||||
|
->count();
|
||||||
|
|
||||||
|
//已使用优惠券总数
|
||||||
|
$item->coupon_used_count = Coupon::where(["business_code" => $item->business->code])
|
||||||
|
->where("is_verificated", "=", Coupon::is_verificated_on)
|
||||||
|
->count();
|
||||||
|
|
||||||
|
//商家充值总额
|
||||||
|
$item->recharge_total_money = Recharge::where(["business_code" => $item->business->code])
|
||||||
|
->where("state", "=", Recharge::state_on)
|
||||||
|
->sum("money");
|
||||||
|
});
|
||||||
|
|
||||||
|
return $this->json(0, 'success', $list);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->view();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 商家优惠券列表
|
||||||
|
*
|
||||||
|
* @return Json|View
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public function businessCouponList()
|
||||||
|
{
|
||||||
|
$businessCode = input("business_code/s", "");
|
||||||
|
if ($this->request->isPost()) {
|
||||||
|
|
||||||
|
event('CouponStatusCheck');
|
||||||
|
|
||||||
|
$repo = BusinessRepository::getInstance();
|
||||||
|
$keyword = $this->request->param('keyword/s', '');
|
||||||
|
$page = $this->request->param('page/d', 1);
|
||||||
|
$size = $this->request->param('size/d', 30);
|
||||||
|
|
||||||
|
$whereMap = ["business_code" => $businessCode];
|
||||||
|
|
||||||
|
if (!empty($keyword)) {
|
||||||
|
$whereMap[] = ['name', 'like', "%$keyword%"];
|
||||||
|
}
|
||||||
|
|
||||||
|
$list = $repo->businessCouponList($whereMap, $page, $size, ["create_time" => "desc", "id" => "desc"]);
|
||||||
|
|
||||||
|
return $this->json(0, 'success', $list);
|
||||||
|
}
|
||||||
|
$this->data["businessCode"] = $businessCode;
|
||||||
|
return $this->view();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 商家扣费记录列表
|
||||||
|
*
|
||||||
|
* @return Json|View
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public function businessDeductionList()
|
||||||
|
{
|
||||||
|
$businessCode = input("business_code/s", "");
|
||||||
|
if ($this->request->isPost()) {
|
||||||
|
$repo = BusinessRepository::getInstance();
|
||||||
|
$keyword = $this->request->param('keyword/s', '');
|
||||||
|
$page = $this->request->param('page/d', 1);
|
||||||
|
$size = $this->request->param('size/d', 30);
|
||||||
|
|
||||||
|
$whereMap = ["business_code" => $businessCode];
|
||||||
|
|
||||||
|
if (!empty($keyword)) {
|
||||||
|
$whereMap[] = ['reason|business_name', 'like', "%$keyword%"];
|
||||||
|
}
|
||||||
|
|
||||||
|
$list = $repo->businessDeductionList($whereMap, $page, $size, ["create_time" => "desc", "id" => "desc"]);
|
||||||
|
|
||||||
|
return $this->json(0, 'success', $list);
|
||||||
|
}
|
||||||
|
$this->data["businessCode"] = $businessCode;
|
||||||
|
return $this->view();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 商家充值记录列表
|
||||||
|
*
|
||||||
|
* @return Json|View
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public function businessRechargeList()
|
||||||
|
{
|
||||||
|
$businessCode = input("business_code/s", "");
|
||||||
|
if ($this->request->isPost()) {
|
||||||
|
$repo = BusinessRepository::getInstance();
|
||||||
|
$keyword = $this->request->param('keyword/s', '');
|
||||||
|
$page = $this->request->param('page/d', 1);
|
||||||
|
$size = $this->request->param('size/d', 30);
|
||||||
|
|
||||||
|
$whereMap = ["business_code" => $businessCode];
|
||||||
|
|
||||||
|
if (!empty($keyword)) {
|
||||||
|
$whereMap[] = ['order_num', 'like', "%$keyword%"];
|
||||||
|
}
|
||||||
|
|
||||||
|
$list = $repo->businessRechargeList($whereMap, $page, $size, ["create_time" => "desc", "id" => "desc"]);
|
||||||
|
|
||||||
|
return $this->json(0, 'success', $list);
|
||||||
|
}
|
||||||
|
$this->data["businessCode"] = $businessCode;
|
||||||
|
return $this->view();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 商家详情
|
||||||
|
*
|
||||||
|
* @return Json|View
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public function businessDetail()
|
||||||
|
{
|
||||||
|
$businessCode = input("business_code/s", "");
|
||||||
|
if ($this->request->isPost()) {
|
||||||
|
|
||||||
|
}
|
||||||
|
$business = $repo = BusinessRepository::getInstance()->findOneByWhere(['code' => $businessCode]);
|
||||||
|
if (empty($business)) {
|
||||||
|
return $this->error("商家不存在");
|
||||||
|
}
|
||||||
|
$this->data["item"] = $business;
|
||||||
|
return $this->view();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 商家认证列表
|
||||||
|
*
|
||||||
|
* @return Json|View
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public function businessWaitList()
|
||||||
|
{
|
||||||
|
if ($this->request->isPost()) {
|
||||||
|
$model = new BusinessFlow();
|
||||||
|
$repo = BusinessRepository::getInstance($model);
|
||||||
|
$keyword = $this->request->param('keyword/s', '');
|
||||||
|
$page = $this->request->param('page/d', 1);
|
||||||
|
$size = $this->request->param('size/d', 30);
|
||||||
|
|
||||||
|
$whereMap = [["business.state", "in", [BusinessModel::state_reviewing, BusinessModel::state_off]]];
|
||||||
|
$orders = ['business.id' => 'desc'];
|
||||||
|
if (!empty($keyword)) {
|
||||||
|
$whereMap[] = ['account.nick_name|business.business_name', 'like', "%$keyword%"];
|
||||||
|
}
|
||||||
|
|
||||||
|
$list = $repo->businessList($whereMap, $page, $size, $orders);
|
||||||
|
|
||||||
|
return $this->json(0, 'success', $list);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->view();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行商家认证
|
||||||
|
*
|
||||||
|
* @return Json|View
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public function businessWait()
|
||||||
|
{
|
||||||
|
if ($this->request->isPost()) {
|
||||||
|
$businessCode = input("business_code/s", "");
|
||||||
|
$state = input("state/d", 0);
|
||||||
|
$business = BusinessRepository::getInstance()->findOneByWhere(["code" => $businessCode]);
|
||||||
|
if (empty($business)) {
|
||||||
|
return $this->json(4001, "商家不存在");
|
||||||
|
}
|
||||||
|
if ($business['state'] != BusinessModel::state_reviewing) {
|
||||||
|
return $this->json(4001, "商家当前状态不可审核");
|
||||||
|
}
|
||||||
|
if (!in_array($state, [BusinessModel::state_off, BusinessModel::state_on])) {
|
||||||
|
return $this->json(4001, "错误的审核状态");
|
||||||
|
}
|
||||||
|
Db::startTrans();
|
||||||
|
try {
|
||||||
|
$business->save(["state"=>$state]);
|
||||||
|
Db::commit();
|
||||||
|
return $this->json();
|
||||||
|
}catch (RepositoryException $e){
|
||||||
|
Db::rollback();
|
||||||
|
return $this->json("5001","审核失败");
|
||||||
|
}catch (\think\Exception $e){
|
||||||
|
Db::rollback();
|
||||||
|
return $this->json("5002","审核失败");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 给商家指派代理商
|
||||||
|
*
|
||||||
|
* @return Json|View
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public function assign()
|
||||||
|
{
|
||||||
|
$businessCode = input("business_code/s", "");
|
||||||
|
$business = BusinessRepository::getInstance()->findOneByWhere(["code" => $businessCode]);
|
||||||
|
|
||||||
|
if ($this->request->isPost()) {
|
||||||
|
$anent_code = input("agency_code/s", "");
|
||||||
|
if(empty($business)){
|
||||||
|
return $this->json(4001,"商家不存在");
|
||||||
|
}
|
||||||
|
Db::startTrans();
|
||||||
|
try {
|
||||||
|
$business->save(["agency_code"=>$anent_code]);
|
||||||
|
Db::commit();
|
||||||
|
return $this->json();
|
||||||
|
}catch (RepositoryException $e){
|
||||||
|
Db::rollback();
|
||||||
|
return $this->json("5001","指派失败");
|
||||||
|
}catch (\think\Exception $e){
|
||||||
|
Db::rollback();
|
||||||
|
return $this->json("5002","指派失败");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(empty($business)){
|
||||||
|
return $this->error("商家不存在");
|
||||||
|
}
|
||||||
|
$this->data["agent"] = Member::getAgentAll();
|
||||||
|
$this->data["businessCode"] = $businessCode;
|
||||||
|
$this->data["business"] = $business;
|
||||||
|
return $this->view();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 代为充值
|
||||||
|
*
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public function rechargeBehalf()
|
||||||
|
{
|
||||||
|
$businessCode = input("business_code/s", "");
|
||||||
|
$business = BusinessRepository::getInstance()->findOneByWhere(["code" => $businessCode]);
|
||||||
|
|
||||||
|
if ($this->request->isPost()) {
|
||||||
|
$money = input("money/f", 0,"abs");
|
||||||
|
if($money<=0){
|
||||||
|
return $this->json(4001,"金额错误");
|
||||||
|
}
|
||||||
|
$money = floor($money * 100) / 100;
|
||||||
|
if(empty($business)){
|
||||||
|
return $this->json(4001,"商家不存在");
|
||||||
|
}
|
||||||
|
Db::startTrans();
|
||||||
|
try {
|
||||||
|
//创建充值订单
|
||||||
|
if (!$order = RechargeRepository::getInstance()->createOrder($businessCode,$money)) {
|
||||||
|
throw new RepositoryException('订单创建失败,请稍后重试');
|
||||||
|
}
|
||||||
|
//生成支付
|
||||||
|
$res = WechatPay::getInstance()->order->unify([
|
||||||
|
'body' => '商家充值',
|
||||||
|
'out_trade_no' => $order->order_num,
|
||||||
|
'total_fee' => $money * 100,
|
||||||
|
'trade_type' => 'NATIVE',
|
||||||
|
'product_id' => $order->id,
|
||||||
|
'notify_url' => $this->request->domain()."/api/recharge/notify.html",
|
||||||
|
]);
|
||||||
|
|
||||||
|
if(!isset($res['code_url'])){
|
||||||
|
throw new RepositoryException('订单创建失败,请稍后重试');
|
||||||
|
}
|
||||||
|
|
||||||
|
Db::commit();
|
||||||
|
return $this->json(0,"success",["order_num"=>$order->order_num,"code_url"=>$res['code_url']]);
|
||||||
|
}catch (RepositoryException $e){
|
||||||
|
Db::rollback();
|
||||||
|
return $this->json("5001",$e->getMessage());
|
||||||
|
}catch (Exception $e){
|
||||||
|
Db::rollback();
|
||||||
|
return $this->json("5001",$e->getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
if(empty($business)){
|
||||||
|
return $this->error("商家不存在");
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->data["businessCode"] = $businessCode;
|
||||||
|
|
||||||
|
return $this->view();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,215 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace app\controller\manager;
|
||||||
|
|
||||||
|
use app\repository\CmsRepository;
|
||||||
|
use app\model\Log;
|
||||||
|
use app\model\Category as CategoryModel;
|
||||||
|
|
||||||
|
use Exception;
|
||||||
|
use think\facade\Db;
|
||||||
|
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 Category
|
||||||
|
* @package app\controller\manager
|
||||||
|
*/
|
||||||
|
class Category extends Base
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 编辑
|
||||||
|
*
|
||||||
|
* @return Json|View
|
||||||
|
* @throws DataNotFoundException
|
||||||
|
* @throws DbException
|
||||||
|
* @throws ModelNotFoundException
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public function edit()
|
||||||
|
{
|
||||||
|
$id = input('id/d', 0);
|
||||||
|
|
||||||
|
if (!$info = CategoryModel::findById($id)) {
|
||||||
|
return $this->json(4001, '记录不存在');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->request->isPost()) {
|
||||||
|
$item = input('post.');
|
||||||
|
$validate = $this->validateByApi($item, [
|
||||||
|
'pid|父级分类' => 'require|number',
|
||||||
|
'name|标题' => 'require|max:100|unique:disease,name,'.$id,
|
||||||
|
]);
|
||||||
|
|
||||||
|
if ($validate !== true) {
|
||||||
|
return $validate;
|
||||||
|
}
|
||||||
|
|
||||||
|
Db::startTrans();
|
||||||
|
try {
|
||||||
|
$oldPath = $info['path'] ?? '';
|
||||||
|
$item['path'] = CategoryModel::getPath($item['pid']);
|
||||||
|
$info->save($item);
|
||||||
|
|
||||||
|
//刷新所有路径
|
||||||
|
$oldPath = $oldPath.','.$id;
|
||||||
|
$newPath = $item['path'].','.$id;
|
||||||
|
if ($oldPath != $newPath) {
|
||||||
|
CategoryModel::refreshPath();
|
||||||
|
}
|
||||||
|
Db::commit();
|
||||||
|
return $this->json();
|
||||||
|
} catch (ValidateException $e) {
|
||||||
|
Db::rollback();
|
||||||
|
return $this->json(4001, $e->getError());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$disabled = CategoryModel::getAllChildrenIds($id);
|
||||||
|
$disabled[] = $id;
|
||||||
|
$this->data['jsonList'] = $this->categoryJson([$info['pid']], $disabled);
|
||||||
|
$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, [
|
||||||
|
'id|ID' => 'require|number',
|
||||||
|
'field|字段名' => 'require',
|
||||||
|
'value|值' => 'require',
|
||||||
|
]);
|
||||||
|
|
||||||
|
if ($validate !== true) {
|
||||||
|
return $validate;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$info = CategoryModel::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, [
|
||||||
|
'pid|父级分类' => 'require|number',
|
||||||
|
'name|标题' => 'require|max:100',
|
||||||
|
]);
|
||||||
|
|
||||||
|
if ($validate !== true) {
|
||||||
|
return $validate;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
CategoryModel::create($item);
|
||||||
|
return $this->json();
|
||||||
|
} catch (ValidateException $e) {
|
||||||
|
return $this->json(4001, $e->getError());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->data['jsonList'] = $this->categoryJson();
|
||||||
|
|
||||||
|
return $this->view();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除
|
||||||
|
* @return Json
|
||||||
|
*/
|
||||||
|
public function del()
|
||||||
|
{
|
||||||
|
if (!$this->request->isPost()) {
|
||||||
|
return $this->json(4000, '非法请求');
|
||||||
|
}
|
||||||
|
|
||||||
|
$ids = $this->request->param('ids/a', []);
|
||||||
|
if(!empty(CategoryModel::findOne([["pid","in",$ids]]))){
|
||||||
|
return $this->json(5001,"该栏目还有下级 不能删除");
|
||||||
|
}
|
||||||
|
CategoryModel::destroy($ids);
|
||||||
|
return $this->json();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 列表
|
||||||
|
*
|
||||||
|
* @return Json|View
|
||||||
|
* @throws DataNotFoundException
|
||||||
|
* @throws DbException
|
||||||
|
* @throws ModelNotFoundException
|
||||||
|
*/
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
if ($this->request->isPost()) {
|
||||||
|
$menus = CategoryModel::getList();
|
||||||
|
$res = [
|
||||||
|
'code' => 0,
|
||||||
|
'msg' => 'success',
|
||||||
|
'count' => $menus->count(),
|
||||||
|
'data' => $menus->toArray(),
|
||||||
|
];
|
||||||
|
return json($res);
|
||||||
|
}
|
||||||
|
return $this->view();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $selected
|
||||||
|
* @param array $disabled
|
||||||
|
* @return false|string
|
||||||
|
* @throws DataNotFoundException
|
||||||
|
* @throws DbException
|
||||||
|
* @throws ModelNotFoundException
|
||||||
|
*/
|
||||||
|
private function categoryJson(array $selected = [], array $disabled = [])
|
||||||
|
{
|
||||||
|
$categoryList[] = ['name' => '顶级分类', 'id' => 0, 'disabled' => false, 'selected' => in_array(0, $selected)];
|
||||||
|
$list = CategoryModel::getListByPid();
|
||||||
|
$list = $list->toArray();
|
||||||
|
foreach ($list as $k => $m) {
|
||||||
|
$list[$k]['selected'] = in_array($m['id'], $selected);
|
||||||
|
$list[$k]['disabled'] = in_array($m['id'], $disabled);
|
||||||
|
}
|
||||||
|
$list = CmsRepository::getInstance()->buildMenuChild(0, $list);
|
||||||
|
$categoryList = array_merge($categoryList, CmsRepository::getInstance()->handleSelectedList($list));
|
||||||
|
return json_encode($categoryList, JSON_UNESCAPED_UNICODE);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,185 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
|
||||||
|
namespace app\controller\manager;
|
||||||
|
|
||||||
|
use app\model\CommentRule;
|
||||||
|
use Exception;
|
||||||
|
use think\exception\ValidateException;
|
||||||
|
use think\facade\Config as CConfig;
|
||||||
|
use think\response\Json;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 额外配置
|
||||||
|
* 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 commentRule()
|
||||||
|
{
|
||||||
|
if ($this->request->isPost()) {
|
||||||
|
$page = input('param.page/d', 1);
|
||||||
|
$size = input('param.size/d', 10);
|
||||||
|
$items = CommentRule::findList([],[], $page, $size);
|
||||||
|
return $this->json(0, 'ok', $items);
|
||||||
|
}
|
||||||
|
return $this->view();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function delCommentRule()
|
||||||
|
{
|
||||||
|
if ($this->request->isPost()) {
|
||||||
|
$ids = input('post.ids/a', []);
|
||||||
|
if (empty($ids)) {
|
||||||
|
$ids[] = input('post.id/d');
|
||||||
|
}
|
||||||
|
CommentRule::deleteByIds($ids);
|
||||||
|
return $this->json();
|
||||||
|
}
|
||||||
|
return $this->json(4001, '非法请求!');
|
||||||
|
}
|
||||||
|
public function addCommentRule()
|
||||||
|
{
|
||||||
|
if ($this->request->isPost()) {
|
||||||
|
$item = input('post.item');
|
||||||
|
|
||||||
|
$validate = $this->validateByApi($item, [
|
||||||
|
'rule|规则' => 'require',
|
||||||
|
'state|状态' => 'require',
|
||||||
|
]);
|
||||||
|
|
||||||
|
if ($validate !== true) {
|
||||||
|
return $validate;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$item['create_time'] = date('Y-m-d H:i:s');
|
||||||
|
CommentRule::create($item);
|
||||||
|
return $this->json();
|
||||||
|
} catch (ValidateException $e) {
|
||||||
|
return $this->json(4001, $e->getError());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $this->view();
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 单个字段编辑
|
||||||
|
*
|
||||||
|
* @return Json
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public function modifyCommentRule(): Json
|
||||||
|
{
|
||||||
|
if ($this->request->isPost()) {
|
||||||
|
$item = input('post.');
|
||||||
|
$validate = $this->validateByApi($item, [
|
||||||
|
'field' => 'require',
|
||||||
|
'value' => 'require',
|
||||||
|
]);
|
||||||
|
|
||||||
|
if ($validate !== true) {
|
||||||
|
return $validate;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$info = CommentRule::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, '非法请求');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
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/'.$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,141 @@
|
||||||
|
<?php
|
||||||
|
namespace app\controller\manager;
|
||||||
|
|
||||||
|
use app\model\{AuthGroup, AuthRule, Log};
|
||||||
|
use app\validate\AuthGroup as VAuthGroup;
|
||||||
|
use think\exception\ValidateException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 角色管理控制器
|
||||||
|
*/
|
||||||
|
class Group extends Base
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 角色、分组删除
|
||||||
|
*/
|
||||||
|
public function del()
|
||||||
|
{
|
||||||
|
if ($this->request->isPost()) {
|
||||||
|
$id = input('post.id/d');
|
||||||
|
if (is_numeric($id) === true && $id > 0) {
|
||||||
|
$item = AuthGroup::getById($id);
|
||||||
|
if(!empty($item)){
|
||||||
|
AuthGroup::destroy($id);
|
||||||
|
Log::write('group', 'del', '删除角色,ID:' . $id . ',名称:' . $item['title']);
|
||||||
|
return $this->json();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $this->json(2, '传入参数错误,请核对之后再操作!');
|
||||||
|
}
|
||||||
|
return $this->json(1, '非法请求!');
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 角色、分组权限分配
|
||||||
|
*/
|
||||||
|
public function rule()
|
||||||
|
{
|
||||||
|
if($this->request->isPost()){
|
||||||
|
$rules = input('post.rules/a');
|
||||||
|
$groupId = input('post.group_id/d');
|
||||||
|
if (is_array($rules) && (is_numeric($groupId) === true && $groupId > 0)) {
|
||||||
|
$group = AuthGroup::getById($groupId);
|
||||||
|
if(empty($group)){
|
||||||
|
return $this->json(2, '无此角色信息,请核对之后再操作!');
|
||||||
|
}
|
||||||
|
AuthGroup::updateRules($groupId, $rules);
|
||||||
|
// 重置该角色对应的权限缓存
|
||||||
|
AuthGroup::resetGroupRulesCache($groupId);
|
||||||
|
Log::write('group', 'rule', '角色分配权限,ID:' . $groupId . ',名称:' . $group['title']);
|
||||||
|
return $this->json();
|
||||||
|
}else{
|
||||||
|
return $this->json(3, '传入参数错误,请核对之后再操作!');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$groupId = input('param.group_id/d');
|
||||||
|
$group = AuthGroup::getById($groupId);
|
||||||
|
if(!empty($group)){
|
||||||
|
$rules = AuthRule::getListTree();
|
||||||
|
$this->data['group_id'] = $groupId;
|
||||||
|
$this->data['group'] = $group;
|
||||||
|
$this->data['rules'] = $rules;
|
||||||
|
return $this->view();
|
||||||
|
}else{
|
||||||
|
return $this->json(1, '无此角色信息,请核对之后再操作!');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 角色、分组添加
|
||||||
|
* @param int $status 1:正常;0:禁止
|
||||||
|
*/
|
||||||
|
public function add()
|
||||||
|
{
|
||||||
|
if($this->request->isPost()){
|
||||||
|
$title = trim(input('post.title'));
|
||||||
|
$status = input('post.status/d');
|
||||||
|
if (!empty($title) && (is_numeric($status) === true) && ($status == 1 || $status == 0)) {
|
||||||
|
$item = [
|
||||||
|
'title' => $title,
|
||||||
|
'status' => $status
|
||||||
|
];
|
||||||
|
try {
|
||||||
|
validate(VAuthGroup::class)->check($item);
|
||||||
|
$group = AuthGroup::create($item);
|
||||||
|
Log::write('group', 'add', "角色新增,ID:{$group->id} ,标题:{$group->title}");
|
||||||
|
return $this->json();
|
||||||
|
} catch (ValidateException $e) {
|
||||||
|
return $this->json(2, $e->getError());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $this->json(1, '传入参数错误,请核对之后再操作!');
|
||||||
|
}else{
|
||||||
|
return $this->view();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 角色、分组编辑
|
||||||
|
*/
|
||||||
|
public function edit()
|
||||||
|
{
|
||||||
|
if($this->request->isPost()){
|
||||||
|
$title = trim(input('post.title'));
|
||||||
|
$status = input('post.status/d');
|
||||||
|
$id = input('post.id/d');
|
||||||
|
if (!empty($title) && ($status == 1 || $status == 0) && (is_numeric($id) === true && $id > 0)) {
|
||||||
|
$item = [
|
||||||
|
'title' => $title,
|
||||||
|
'status' => $status
|
||||||
|
];
|
||||||
|
try {
|
||||||
|
validate(VAuthGroup::class)->check($item);
|
||||||
|
AuthGroup::updateById($id, $item);
|
||||||
|
Log::write('group', 'edit', "角色编辑,ID:{$id} ,标题:{$item['title']}");
|
||||||
|
return $this->json();
|
||||||
|
} catch (ValidateException $e) {
|
||||||
|
return $this->json(2, $e->getError());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $this->json(1, '传入参数错误,请核对之后再操作!');
|
||||||
|
}else{
|
||||||
|
$id = input('param.id/d');
|
||||||
|
if (is_numeric($id) === true && $id > 0) {
|
||||||
|
$item = AuthGroup::getById($id);
|
||||||
|
$this->data['item'] = $item;
|
||||||
|
return $this->view();
|
||||||
|
}
|
||||||
|
return $this->json(1, '传入参数错误,请核对之后再操作!');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 所有角色分组信息
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
$list = AuthGroup::select()->toArray();
|
||||||
|
$this->data['list'] = $list;
|
||||||
|
return $this->view();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,86 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace app\controller\manager;
|
||||||
|
|
||||||
|
use app\model\AccountRecord;
|
||||||
|
use app\model\Overview;
|
||||||
|
use app\model\AccountRole;
|
||||||
|
use app\model\Appointment;
|
||||||
|
use app\model\Account;
|
||||||
|
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
|
||||||
|
{
|
||||||
|
//TODO 权限未完善
|
||||||
|
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()
|
||||||
|
{
|
||||||
|
return $this->view();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 菜单初始化
|
||||||
|
*
|
||||||
|
* @return Json
|
||||||
|
*/
|
||||||
|
public function init(): Json
|
||||||
|
{
|
||||||
|
$res = [];
|
||||||
|
$res['homeInfo'] = ['title' => '控制台', 'href' => "manager/index/dashboard"];
|
||||||
|
$res['logoInfo'] = ['title' => '恒美植发', 'href' => "", 'image' => '/static/manager/image/logo.png'];
|
||||||
|
|
||||||
|
$menus = CmsRepository::getInstance()->getMenuList(Menu::TYPE_MENU, Menu::SHOW_YES)->toArray();
|
||||||
|
foreach ($menus as $k => $m) {
|
||||||
|
$menus[$k]['icon'] = !empty($m['icon']) ? 'fa '.$m['icon'] : '';
|
||||||
|
$menus[$k]['href'] = ltrim($m['href'], '/');
|
||||||
|
}
|
||||||
|
$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,76 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace app\controller\manager;
|
||||||
|
|
||||||
|
use app\service\Jwt;
|
||||||
|
use Exception;
|
||||||
|
use app\model\{Member, AuthRule, 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'],
|
||||||
|
'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 = [];
|
||||||
|
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,411 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace app\controller\manager;
|
||||||
|
|
||||||
|
use app\model\Log;
|
||||||
|
use app\model\Member as MemberModel;
|
||||||
|
use app\model\Role as RoleModel;
|
||||||
|
use app\model\Business as BusinessModel;
|
||||||
|
use app\repository\BusinessRepository;
|
||||||
|
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 {
|
||||||
|
//之前关联的商家不为空 并且已经改变 吧之前的商家 从代理商变成普通商家
|
||||||
|
if ($info['business_code'] != $item['business_code']) {
|
||||||
|
if(!empty($info['business_code']) ){
|
||||||
|
$oldBusiness = BusinessRepository::getInstance()->findOneByWhere(["code" => $info['business_code']]);
|
||||||
|
if (!empty($oldBusiness)) {
|
||||||
|
$oldBusiness->save(["is_agency" => BusinessModel::COMMON_OFF]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//如果改变了关联商家
|
||||||
|
if(!empty($item['business_code'])){
|
||||||
|
$Business = BusinessRepository::getInstance()->findOneByWhere(["code" => $item['business_code']]);
|
||||||
|
if (empty($Business)) {
|
||||||
|
Db::rollback();
|
||||||
|
return $this->json(4001, "指定商家不存在");
|
||||||
|
}
|
||||||
|
$Business->save(["is_agency" => BusinessModel::COMMON_ON]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$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']));
|
||||||
|
|
||||||
|
$this->data['business'] = BusinessRepository::getInstance()->getBusinessAll();
|
||||||
|
|
||||||
|
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.'%'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$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,165 @@
|
||||||
|
<?php
|
||||||
|
namespace app\controller\manager;
|
||||||
|
|
||||||
|
use app\model\{Model as MModel, Log};
|
||||||
|
use app\validate\Model as VModel;
|
||||||
|
use think\exception\ValidateException;
|
||||||
|
|
||||||
|
class Model extends Base
|
||||||
|
{
|
||||||
|
//删除模型
|
||||||
|
public function del()
|
||||||
|
{
|
||||||
|
if($this->request->isPost()){
|
||||||
|
$ids = input('post.ids/a');
|
||||||
|
if(is_array($ids)) {
|
||||||
|
$idsArr = $ids;
|
||||||
|
} else {
|
||||||
|
$idsArr = array_filter(explode(',', $ids));
|
||||||
|
}
|
||||||
|
if(count($idsArr) == 0) {
|
||||||
|
return $this->json(1, '无效请求,参数错误!');
|
||||||
|
}
|
||||||
|
$items = MModel::getListByIds($idsArr);
|
||||||
|
if(!empty($items)){
|
||||||
|
$delIds = [];
|
||||||
|
foreach($items as $item){
|
||||||
|
$delIds[] = $item['id'];
|
||||||
|
}
|
||||||
|
MModel::destroy($delIds);
|
||||||
|
Log::write('model', 'del', "模型删除,ID:" . implode(',', $ids));
|
||||||
|
return $this->json();
|
||||||
|
}
|
||||||
|
return $this->json(2, '无效请求,参数错误!');
|
||||||
|
}
|
||||||
|
return $this->json(1, '非法请求!');
|
||||||
|
}
|
||||||
|
|
||||||
|
//编辑模型
|
||||||
|
public function edit()
|
||||||
|
{
|
||||||
|
if($this->request->isPost()){
|
||||||
|
$item = [];
|
||||||
|
$item['name'] = input('post.name');
|
||||||
|
$item['template'] = input('post.template');
|
||||||
|
$item['manager'] = input('post.manager');
|
||||||
|
$id = input('post.id/d');
|
||||||
|
if(is_numeric($id) && $id > 0) {
|
||||||
|
$model = MModel::getById($id);
|
||||||
|
if(empty($model)){
|
||||||
|
return $this->json(2, '无此模型数据!');
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
validate(VModel::class)->check($item);
|
||||||
|
MModel::updateById($id, $item);
|
||||||
|
Log::write('model', 'edit', "模型编辑,ID:{$id}, 标题:{$item['name']}");
|
||||||
|
return $this->json();
|
||||||
|
} catch (ValidateException $e) {
|
||||||
|
return $this->json(3, $e->getError());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $this->json(1, '无效请求,参数错误!');
|
||||||
|
}else{
|
||||||
|
$id = input('param.id/d');
|
||||||
|
if (is_numeric($id) && $id > 0) {
|
||||||
|
$item = MModel::getById($id);
|
||||||
|
$this->data['item'] = $item;
|
||||||
|
return $this->view();
|
||||||
|
}
|
||||||
|
return $this->json(1,'传入参数错误,请核对之后再操作!');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加模型
|
||||||
|
*/
|
||||||
|
public function add()
|
||||||
|
{
|
||||||
|
if($this->request->isPost()){
|
||||||
|
$item = [];
|
||||||
|
$item['name'] = input('post.name');
|
||||||
|
$item['template'] = input('post.template');
|
||||||
|
$item['manager'] = input('post.manager');
|
||||||
|
try {
|
||||||
|
validate(VModel::class)->check($item);
|
||||||
|
$model = MModel::create($item);
|
||||||
|
Log::write('model', 'add', "模型新增,ID:{$model->id}, 标题:{$item['name']}");
|
||||||
|
return $this->json();
|
||||||
|
} catch (ValidateException $e) {
|
||||||
|
return $this->json(2, $e->getError());
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
return $this->view();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 模型列表
|
||||||
|
*/
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
$items = MModel::getList();
|
||||||
|
$this->data['items'] = $items;
|
||||||
|
return $this->view();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 排序
|
||||||
|
*/
|
||||||
|
public function sort()
|
||||||
|
{
|
||||||
|
if($this->request->isPost()){
|
||||||
|
$id = input('post.id/d');
|
||||||
|
$sort = input('post.sort');
|
||||||
|
$num = input('post.num/d', 1);
|
||||||
|
if($num <= 0){
|
||||||
|
$num = 1;
|
||||||
|
}
|
||||||
|
if(!in_array($sort, ['up', 'down'], true)){
|
||||||
|
return $this->json(2, '参数错误');
|
||||||
|
}
|
||||||
|
$item = MModel::getById($id);
|
||||||
|
if(empty($item)) {
|
||||||
|
return $this->json(3, '无此模型!');
|
||||||
|
}
|
||||||
|
if($sort == 'up'){
|
||||||
|
$where = "sort < {$item['sort']}";
|
||||||
|
$order = "sort desc";
|
||||||
|
}else{
|
||||||
|
$where = "sort > {$item['sort']}";
|
||||||
|
$order = "sort asc";
|
||||||
|
}
|
||||||
|
$forSortItems = MModel::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)){
|
||||||
|
$model = new MModel();
|
||||||
|
$model->saveAll($updateData);
|
||||||
|
$sortStr = $sort == 'up' ? '上移' : '下调';
|
||||||
|
Log::write('model', 'sort', "模型排序,ID:{$id} ,标题:{$item['name']},{$sortStr}了{$num}位");
|
||||||
|
return $this->json();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $this->json(4, '无须调整排序!');
|
||||||
|
}
|
||||||
|
return $this->json(1, '非法请求!');
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,467 @@
|
||||||
|
<?php
|
||||||
|
namespace app\controller\manager;
|
||||||
|
|
||||||
|
use app\model\{Category, Block, Log};
|
||||||
|
use app\validate\Block as VBlock;
|
||||||
|
use think\exception\ValidateException;
|
||||||
|
use app\service\Tool;
|
||||||
|
|
||||||
|
class Page extends Base
|
||||||
|
{
|
||||||
|
//源码,代码
|
||||||
|
public function code()
|
||||||
|
{
|
||||||
|
if($this->request->isPost()){
|
||||||
|
$item = input('post.item/a');
|
||||||
|
$categoryId = input('post.category_id/d');
|
||||||
|
$id = input('post.id/d');
|
||||||
|
$item['keyword'] = Tool::trimSpace($item['keyword']);
|
||||||
|
try{
|
||||||
|
validate(VBlock::class)->check($item);
|
||||||
|
if(empty($item['value'])){
|
||||||
|
return $this->json(2, '内容不可为空!');
|
||||||
|
}
|
||||||
|
$block = Block::getByKeyword($item['keyword'], $categoryId);
|
||||||
|
if($id){
|
||||||
|
if(!empty($block) && $block['id'] != $id){
|
||||||
|
return $this->json(3, '键值已存在,请更改键值');
|
||||||
|
}
|
||||||
|
Block::updateById($id, $item);
|
||||||
|
Log::write('page', 'code', "单页代码编辑,ID:{$id}, 键值:{$item['keyword']}");
|
||||||
|
}else{
|
||||||
|
if($categoryId <= 0){
|
||||||
|
return $this->json(4, '栏目参数错误!');
|
||||||
|
}
|
||||||
|
if(!empty($block)){
|
||||||
|
return $this->json(3, '键值已存在,请更改键值');
|
||||||
|
}
|
||||||
|
$item['category_id'] = $categoryId;
|
||||||
|
$item['type'] = Block::CODE;
|
||||||
|
$block = Block::create($item);
|
||||||
|
Log::write('page', 'code', "单页代码新增,ID:{$block->id}, 键值:{$item['keyword']}");
|
||||||
|
}
|
||||||
|
return $this->json();
|
||||||
|
} catch (ValidateException $e){
|
||||||
|
return $this->json(1, $e->getError());
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
$id = input('param.id/d');
|
||||||
|
if($id <= 0){ //添加
|
||||||
|
$categoryId = input('param.category_id/d');
|
||||||
|
$category = Category::getById($categoryId);
|
||||||
|
if(empty($category)){
|
||||||
|
$url = url('manager.content/index')->__toString();
|
||||||
|
return $this->error('无此栏目', $url);
|
||||||
|
}
|
||||||
|
}else{ //修改
|
||||||
|
$item = Block::getById($id);
|
||||||
|
if(empty($item)){
|
||||||
|
return $this->error('无此代码块!');
|
||||||
|
}
|
||||||
|
$categoryId = $item['category_id'];
|
||||||
|
$this->data['item'] = $item;
|
||||||
|
}
|
||||||
|
$this->data['categoryId'] = $categoryId;
|
||||||
|
return $this->view();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//排序
|
||||||
|
public function sort()
|
||||||
|
{
|
||||||
|
if($this->request->isPost()){
|
||||||
|
$id = input('post.id/d');
|
||||||
|
$sort = input('post.sort');
|
||||||
|
$num = input('post.num/d', 1);
|
||||||
|
if($num <= 0){
|
||||||
|
$num = 1;
|
||||||
|
}
|
||||||
|
if(!in_array($sort, ['up', 'down'], true)){
|
||||||
|
return $this->json(2, '参数错误');
|
||||||
|
}
|
||||||
|
$item = Block::getById($id);
|
||||||
|
if(empty($item)){
|
||||||
|
return $this->json(3, '无此块信息');
|
||||||
|
}
|
||||||
|
if($sort == 'up'){
|
||||||
|
$where = "category_id='{$item['category_id']}' and sort < {$item['sort']}";
|
||||||
|
$order = "sort desc";
|
||||||
|
}else{
|
||||||
|
$where = "category_id='{$item['category_id']}' and sort > {$item['sort']}";
|
||||||
|
$order = "sort asc";
|
||||||
|
}
|
||||||
|
$forSortItems = Block::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)){
|
||||||
|
$model = new Block();
|
||||||
|
$model->saveAll($updateData);
|
||||||
|
$sortStr = $sort == 'up' ? '上移' : '下调';
|
||||||
|
Log::write('page', 'sort', "单页区块排序,ID:{$id} ,键值:{$item['keyword']},{$sortStr}了{$num}位");
|
||||||
|
return $this->json();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $this->json(4, '无须调整排序!');
|
||||||
|
}
|
||||||
|
return $this->error('无此操作');
|
||||||
|
}
|
||||||
|
|
||||||
|
//删除
|
||||||
|
public function del()
|
||||||
|
{
|
||||||
|
if ($this->request->isAjax()) {
|
||||||
|
$id = input('post.id/d');
|
||||||
|
$item = Block::getById($id);
|
||||||
|
if(!empty($item)){
|
||||||
|
Block::destroy($id);
|
||||||
|
Log::write('page', 'del', "单页区块删除,ID:{$id} ,键值:{$item['keyword']}");
|
||||||
|
return $this->json();
|
||||||
|
}
|
||||||
|
return $this->json(1, 'fail');
|
||||||
|
}
|
||||||
|
return $this->error('无此操作');
|
||||||
|
}
|
||||||
|
//图片
|
||||||
|
public function img()
|
||||||
|
{
|
||||||
|
if($this->request->isPost()){
|
||||||
|
$item = input('post.item/a');
|
||||||
|
$img = trim(input('post.img'));
|
||||||
|
$categoryId = input('post.category_id/d');
|
||||||
|
if (!empty($img) && $img == 'null') {
|
||||||
|
$img = '';
|
||||||
|
}
|
||||||
|
$id = input('post.id/d');
|
||||||
|
$item['keyword'] = Tool::trimSpace($item['keyword']);
|
||||||
|
try{
|
||||||
|
validate(VBlock::class)->check($item);
|
||||||
|
$block = Block::getByKeyword($item['keyword'], $categoryId);
|
||||||
|
if($id){
|
||||||
|
if(!empty($block) && $block['id'] != $id){
|
||||||
|
return $this->json(4, '键值已存在,请更改键值');
|
||||||
|
}
|
||||||
|
if(!empty($img)){
|
||||||
|
$item['value'] = $img;
|
||||||
|
}
|
||||||
|
Block::updateById($id, $item);
|
||||||
|
Log::write('page', 'img', "单页图片编辑,ID:{$id} ,键值:{$item['keyword']}");
|
||||||
|
}else{
|
||||||
|
if(!empty($block)){
|
||||||
|
return $this->json(4, '键值已存在,请更改键值');
|
||||||
|
}
|
||||||
|
if($categoryId <= 0){
|
||||||
|
return $this->json(2, '栏目参数错误!!');
|
||||||
|
}
|
||||||
|
if(empty($img)){
|
||||||
|
return $this->json(3, '图片不可为空');
|
||||||
|
}
|
||||||
|
$item['value'] = $img;
|
||||||
|
$item['type'] = Block::IMG;
|
||||||
|
$item['category_id'] = $categoryId;
|
||||||
|
$block = Block::create($item);
|
||||||
|
Log::write('page', 'img', "单页图片新增,ID:{$block->id} ,键值:{$item['keyword']}");
|
||||||
|
}
|
||||||
|
return $this->json();
|
||||||
|
} catch (ValidateException $e){
|
||||||
|
return $this->json(1, $e->getError());
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
$id = input('param.id/d');
|
||||||
|
if($id <= 0){ //添加
|
||||||
|
$categoryId = input('param.category_id/d');
|
||||||
|
$category = Category::getById($categoryId);
|
||||||
|
if(empty($category)){
|
||||||
|
$url = url('manager.content/index')->__toString();
|
||||||
|
return $this->error('无此栏目', $url);
|
||||||
|
}
|
||||||
|
}else{ //修改
|
||||||
|
$item = Block::getById($id);
|
||||||
|
if(empty($item)){
|
||||||
|
return $this->error('无此图片!');
|
||||||
|
}
|
||||||
|
$categoryId = $item['category_id'];
|
||||||
|
$this->data['item'] = $item;
|
||||||
|
}
|
||||||
|
if(isset($item) && $item['width'] && $item['height']){
|
||||||
|
$imgSize = $item['width'].'px X '.$item['height'].'px';
|
||||||
|
}else{
|
||||||
|
$imgSize = '';
|
||||||
|
}
|
||||||
|
$this->data['categoryId'] = $categoryId;
|
||||||
|
$this->data['imgSize'] = $imgSize;
|
||||||
|
$this->data['groupId'] = session('auth.groupId');
|
||||||
|
return $this->view();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//文字块
|
||||||
|
public function block()
|
||||||
|
{
|
||||||
|
if($this->request->isPost()){
|
||||||
|
$item = input('post.item/a');
|
||||||
|
$categoryId = input('post.category_id/d');
|
||||||
|
$id = input('post.id/d');
|
||||||
|
$item['keyword'] = Tool::trimSpace($item['keyword']);
|
||||||
|
try{
|
||||||
|
validate(VBlock::class)->check($item);
|
||||||
|
if(empty($item['value'])){
|
||||||
|
return $this->json(1, '内容不可为空!');
|
||||||
|
}
|
||||||
|
$block = Block::getByKeyword($item['keyword'], $categoryId);
|
||||||
|
if($id){
|
||||||
|
if(!empty($block) && $block['id'] != $id){
|
||||||
|
return $this->json(4, '键值已存在,请更改键值');
|
||||||
|
}
|
||||||
|
Block::updateById($id, $item);
|
||||||
|
Log::write('page', 'block', "单页文字块编辑,ID:{$id} ,键值:{$item['keyword']}");
|
||||||
|
}else{
|
||||||
|
if($categoryId <= 0){
|
||||||
|
return $this->json(2, '栏目参数错误!');
|
||||||
|
}
|
||||||
|
if(!empty($block)){
|
||||||
|
return $this->json(4, '键值已存在,请更改键值');
|
||||||
|
}
|
||||||
|
$item['category_id'] = $categoryId;
|
||||||
|
$block = Block::create($item);
|
||||||
|
Log::write('page', 'block', "单页文字块新增,ID:{$block->id} ,键值:{$item['keyword']}");
|
||||||
|
}
|
||||||
|
return $this->json();
|
||||||
|
} catch (ValidateException $e){
|
||||||
|
return $this->json(1, $e->getError());
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
$id = input('param.id/d');
|
||||||
|
if($id <= 0){ //添加
|
||||||
|
$categoryId = input('param.category_id/d');
|
||||||
|
$category = Category::getById($categoryId);
|
||||||
|
if(empty($category)){
|
||||||
|
$url = url('manager.content/index')->__toString();
|
||||||
|
return $this->error('无此栏目', $url);
|
||||||
|
}
|
||||||
|
}else{ //修改
|
||||||
|
$item = Block::getById($id);
|
||||||
|
if(empty($item)){
|
||||||
|
return $this->error('无此文字块!');
|
||||||
|
}
|
||||||
|
$categoryId = $item['category_id'];
|
||||||
|
$this->data['item'] = $item;
|
||||||
|
}
|
||||||
|
$this->data['categoryId'] = $categoryId;
|
||||||
|
return $this->view();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//富文本内容
|
||||||
|
public function text()
|
||||||
|
{
|
||||||
|
if($this->request->isPost()){
|
||||||
|
$item = input('post.item/a');
|
||||||
|
$categoryId = input('post.category_id/d');
|
||||||
|
$item['keyword'] = Tool::trimSpace($item['keyword']);
|
||||||
|
try{
|
||||||
|
validate(VBlock::class)->check($item);
|
||||||
|
if(empty($item['value'])){
|
||||||
|
return $this->json(1, '内容不可为空!');
|
||||||
|
}
|
||||||
|
$block = Block::getByKeyword($item['keyword'], $categoryId);
|
||||||
|
$id = input('post.id/d');
|
||||||
|
if($id){
|
||||||
|
if(!empty($block) && $block['id'] != $id){
|
||||||
|
return $this->json(4, '键值已存在,请更改');
|
||||||
|
}
|
||||||
|
Block::updateById($id, $item);
|
||||||
|
Log::write('page', 'text', "单页富文本编辑,ID:{$id} ,键值:{$item['keyword']}");
|
||||||
|
}else{
|
||||||
|
if($categoryId <= 0){
|
||||||
|
return $this->json(2, '栏目参数错误!');
|
||||||
|
}
|
||||||
|
if(!empty($block)){
|
||||||
|
return $this->json(4, '键值已存在,请更改键值');
|
||||||
|
}
|
||||||
|
$item['category_id'] = $categoryId;
|
||||||
|
$item['type'] = Block::TEXT;
|
||||||
|
$block = Block::create($item);
|
||||||
|
Log::write('page', 'text', "单页富文本新增,ID:{$block->id} ,键值:{$item['keyword']}");
|
||||||
|
}
|
||||||
|
return $this->json();
|
||||||
|
} catch (ValidateException $e){
|
||||||
|
return $this->json(1, $e->getError());
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
$id = input('param.id/d');
|
||||||
|
if($id <= 0){ //添加
|
||||||
|
$categoryId = input('param.category_id/d');
|
||||||
|
$category = Category::getById($categoryId);
|
||||||
|
if(empty($category)){
|
||||||
|
$url = url('manager.content/index')->__toString();
|
||||||
|
return $this->error('无此栏目', $url);
|
||||||
|
}
|
||||||
|
}else{ //修改
|
||||||
|
$item = Block::getById($id);
|
||||||
|
if(empty($item)){
|
||||||
|
return $this->error('无此富文本!');
|
||||||
|
}
|
||||||
|
$categoryId = $item['category_id'];
|
||||||
|
$this->data['item'] = $item;
|
||||||
|
}
|
||||||
|
$this->data['categoryId'] = $categoryId;
|
||||||
|
return $this->view();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//组图
|
||||||
|
public function group()
|
||||||
|
{
|
||||||
|
if($this->request->isPost()){
|
||||||
|
$item = input('post.item/a');
|
||||||
|
$imgs = input('post.img/a');
|
||||||
|
$categoryId = input('post.category_id/d');
|
||||||
|
if (!empty($imgs) && is_array($imgs)) {
|
||||||
|
$item['value'] = json_encode($imgs);
|
||||||
|
} else {
|
||||||
|
$item['value'] = '';
|
||||||
|
}
|
||||||
|
$item['keyword'] = Tool::trimSpace($item['keyword']);
|
||||||
|
try{
|
||||||
|
validate(VBlock::class)->check($item);
|
||||||
|
$block = Block::getByKeyword($item['keyword'], $categoryId);
|
||||||
|
$id = input('post.id/d');
|
||||||
|
if($id){
|
||||||
|
if(!empty($block) && $block['id'] != $id){
|
||||||
|
return $this->json(4, '键值已存在,请更改');
|
||||||
|
}
|
||||||
|
Block::updateById($id, $item);
|
||||||
|
Log::write('page', 'group', "单页组图编辑,ID:{$id} ,键值:{$item['keyword']}");
|
||||||
|
}else{
|
||||||
|
if($categoryId <= 0){
|
||||||
|
return $this->json(2, '栏目参数错误!');
|
||||||
|
}
|
||||||
|
if(!empty($block)){
|
||||||
|
return $this->json(4, '键值已存在,请更改键值');
|
||||||
|
}
|
||||||
|
$item['category_id'] = $categoryId;
|
||||||
|
$item['type'] = Block::GROUP;
|
||||||
|
$block = Block::create($item);
|
||||||
|
Log::write('page', 'group', "单页组图新增,ID:{$block->id} ,键值:{$item['keyword']}");
|
||||||
|
}
|
||||||
|
return $this->json();
|
||||||
|
} catch (ValidateException $e){
|
||||||
|
return $this->json(1, $e->getError());
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
$id = input('param.id/d');
|
||||||
|
if($id <= 0){ //添加
|
||||||
|
$categoryId = input('param.category_id/d');
|
||||||
|
$category = Category::getById($categoryId);
|
||||||
|
if(empty($category)){
|
||||||
|
$url = url('manager.content/index')->__toString();
|
||||||
|
return $this->error('无此栏目', $url);
|
||||||
|
}
|
||||||
|
}else{ //修改
|
||||||
|
$item = Block::getById($id);
|
||||||
|
if(empty($item)){
|
||||||
|
return $this->error('无此组图!');
|
||||||
|
}
|
||||||
|
$categoryId = $item['category_id'];
|
||||||
|
$this->data['item'] = $item;
|
||||||
|
}
|
||||||
|
$this->data['categoryId'] = $categoryId;
|
||||||
|
if(isset($item) && $item['width'] && $item['height']){
|
||||||
|
$imgSize = $item['width'].'px X '.$item['height'].'px';
|
||||||
|
}else{
|
||||||
|
$imgSize = '';
|
||||||
|
}
|
||||||
|
$this->data['imgSize'] = $imgSize;
|
||||||
|
$this->data['groupId'] = session('auth.groupId');
|
||||||
|
return $this->view();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//视频
|
||||||
|
public function video()
|
||||||
|
{
|
||||||
|
if($this->request->isPost()){
|
||||||
|
$item = input('post.item/a');
|
||||||
|
$img = trim(input('post.img'));
|
||||||
|
$video = trim(input('post.video'));
|
||||||
|
$categoryId = input('post.category_id/d');
|
||||||
|
$item['keyword'] = Tool::trimSpace($item['keyword']);
|
||||||
|
try{
|
||||||
|
validate(VBlock::class)->check($item);
|
||||||
|
$block = Block::getByKeyword($item['keyword'], $categoryId);
|
||||||
|
$id = input('post.id/d');
|
||||||
|
if($id){
|
||||||
|
if(!empty($block) && $block['id'] != $id){
|
||||||
|
return $this->json(4, '键值已存在,请更改');
|
||||||
|
}
|
||||||
|
if(!empty($img)){
|
||||||
|
$item['img'] = $img;
|
||||||
|
}
|
||||||
|
if(!empty($video)){
|
||||||
|
$item['value'] = $video;
|
||||||
|
}
|
||||||
|
Block::updateById($id, $item);
|
||||||
|
Log::write('page', 'video', "单页视频编辑,ID:{$id} ,键值:{$item['keyword']}");
|
||||||
|
}else{
|
||||||
|
if($categoryId <= 0){
|
||||||
|
return $this->json(2, '栏目参数错误!');
|
||||||
|
}
|
||||||
|
if(!empty($block)){
|
||||||
|
return $this->json(3, '键值已存在,请更改键值');
|
||||||
|
}
|
||||||
|
if(empty($video)){
|
||||||
|
return $this->json(3, '视频不可为空');
|
||||||
|
}
|
||||||
|
$item['category_id'] = $categoryId;
|
||||||
|
$item['type'] = Block::VIDEO;
|
||||||
|
$item['value'] = $video;
|
||||||
|
$item['img'] = $img;
|
||||||
|
$block = Block::create($item);
|
||||||
|
Log::write('page', 'video', "单页视频新增,ID:{$block->id} ,键值:{$item['keyword']}");
|
||||||
|
}
|
||||||
|
return $this->json();
|
||||||
|
} catch (ValidateException $e){
|
||||||
|
return $this->json(1, $e->getError());
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
$id = input('param.id/d');
|
||||||
|
if($id <= 0){ //添加
|
||||||
|
$categoryId = input('param.category_id/d');
|
||||||
|
$category = Category::getById($categoryId);
|
||||||
|
if(empty($category)){
|
||||||
|
$url = url('manager.content/index')->__toString();
|
||||||
|
return $this->error('无此栏目', $url);
|
||||||
|
}
|
||||||
|
}else{ //修改
|
||||||
|
$item = Block::getById($id);
|
||||||
|
if(empty($item)){
|
||||||
|
return $this->error('无此视频!');
|
||||||
|
}
|
||||||
|
$categoryId = $item['category_id'];
|
||||||
|
$this->data['item'] = $item;
|
||||||
|
}
|
||||||
|
$this->data['categoryId'] = $categoryId;
|
||||||
|
if(isset($item) && $item['width'] && $item['height']){
|
||||||
|
$imgSize = $item['width'].'px X '.$item['height'].'px';
|
||||||
|
}else{
|
||||||
|
$imgSize = '';
|
||||||
|
}
|
||||||
|
$this->data['imgSize'] = $imgSize;
|
||||||
|
$this->data['groupId'] = session('auth.groupId');
|
||||||
|
return $this->view();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,270 @@
|
||||||
|
<?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 = [])
|
||||||
|
{
|
||||||
|
$menus = Menu::field("id,pid,title,sort")
|
||||||
|
->where('status', Menu::STATUS_NORMAL)
|
||||||
|
->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);
|
||||||
|
}
|
||||||
|
return $this->view();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,183 @@
|
||||||
|
<?php
|
||||||
|
namespace app\controller\manager;
|
||||||
|
|
||||||
|
use app\model\{AuthRule, AuthGroup, Log};
|
||||||
|
use app\validate\AuthRule as VAuthRule;
|
||||||
|
use Exception;
|
||||||
|
use think\exception\ValidateException;
|
||||||
|
use think\response\Json;
|
||||||
|
|
||||||
|
class Rule extends Base
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 权限排序
|
||||||
|
* 暂不允许父级变更
|
||||||
|
*
|
||||||
|
* @return Json
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public function sort()
|
||||||
|
{
|
||||||
|
if ($this->request->isAjax()) {
|
||||||
|
$id = input('post.id');
|
||||||
|
$sort = input('post.sort');
|
||||||
|
$num = input('post.num/d', 1);
|
||||||
|
if($num <= 0){
|
||||||
|
$num = 1;
|
||||||
|
}
|
||||||
|
if(!in_array($sort, ['up', 'down'], true)){
|
||||||
|
return $this->json(2, '参数错误');
|
||||||
|
}
|
||||||
|
$item = AuthRule::getById($id);
|
||||||
|
if(empty($item)){
|
||||||
|
return $this->json(3, '权限不存在');
|
||||||
|
}
|
||||||
|
if($sort == 'up'){
|
||||||
|
$where = "parent_id = {$item['parent_id']} and sort < {$item['sort']}";
|
||||||
|
$order = "sort desc";
|
||||||
|
}else{
|
||||||
|
$where = "parent_id = {$item['parent_id']} and sort > {$item['sort']}";
|
||||||
|
$order = "sort asc";
|
||||||
|
}
|
||||||
|
$forSortItems = AuthRule::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)){
|
||||||
|
$model = new AuthRule();
|
||||||
|
$model->saveAll($updateData);
|
||||||
|
$sortStr = $sort == 'up' ? '上移' : '下调';
|
||||||
|
Log::write('rule', 'sort', "权限排序,ID:{$id} ,标题:{$item['title']},{$sortStr}了{$num}位");
|
||||||
|
return $this->json();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $this->json(4, '无须调整排序!');
|
||||||
|
}
|
||||||
|
return $this->json(1, '非法请求!');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 权限删除
|
||||||
|
*/
|
||||||
|
public function del()
|
||||||
|
{
|
||||||
|
if ($this->request->isAjax()) {
|
||||||
|
$ids = input('post.ids/a');
|
||||||
|
$items = AuthRule::where('id', 'in', $ids)->select();
|
||||||
|
if(!$items){
|
||||||
|
return $this->json(1, '无此权限');
|
||||||
|
}
|
||||||
|
if(AuthRule::where('parent_id', 'in', $ids)->count()){
|
||||||
|
return $this->json(2, '当前权限有下级权限,不可删除');
|
||||||
|
}
|
||||||
|
AuthRule::destroy($ids);
|
||||||
|
AuthGroup::resetGroupRulesCache();
|
||||||
|
$ids = implode(',', $ids);
|
||||||
|
Log::write('rule', 'del', "权限删除,ID:{$ids}");
|
||||||
|
return $this->json();
|
||||||
|
}
|
||||||
|
return $this->json(1, '非法请求!');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 权限修改
|
||||||
|
*/
|
||||||
|
public function edit()
|
||||||
|
{
|
||||||
|
if($this->request->isPost()){
|
||||||
|
$item = input('post.item/a');
|
||||||
|
$id = input('post.id');
|
||||||
|
$rule = AuthRule::getById($id);
|
||||||
|
if(empty($rule)){
|
||||||
|
return $this->json(1, '请选择正确的权限');
|
||||||
|
}
|
||||||
|
$rule2 = AuthRule::getByName($item['name']);
|
||||||
|
if(!empty($rule2) && $rule2['id'] != $id){
|
||||||
|
return $this->json(2, '已存在相同权限['.$item['name'].']');
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
validate(VAuthRule::class)->check($item);
|
||||||
|
AuthRule::updateById($id, $item);
|
||||||
|
AuthGroup::resetGroupRulesCache();
|
||||||
|
Log::write('rule', 'edit', "权限编辑,ID:{$id}, 标题:{$item['title']}");
|
||||||
|
return $this->json();
|
||||||
|
} catch (ValidateException $e) {
|
||||||
|
return $this->json(3, $e->getError());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$id = input('param.id/d');
|
||||||
|
$rule = AuthRule::getById($id);
|
||||||
|
if(empty($rule)){
|
||||||
|
return $this->json(1,'无此权限信息,请核对之后再操作!');
|
||||||
|
}else{
|
||||||
|
$this->data['item'] = $rule;
|
||||||
|
if($rule['parent_id'] > 0){
|
||||||
|
$parent = AuthRule::getById($rule['parent_id']);
|
||||||
|
$this->data['parent'] = $parent;
|
||||||
|
}
|
||||||
|
return $this->view();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 权限添加
|
||||||
|
*/
|
||||||
|
public function add()
|
||||||
|
{
|
||||||
|
if($this->request->isPost()){
|
||||||
|
$item = input('post.item/a');
|
||||||
|
try {
|
||||||
|
validate(VAuthRule::class)->check($item);
|
||||||
|
$rule = AuthRule::getByName($item['name']);
|
||||||
|
if(!empty($rule)){
|
||||||
|
return $this->json(1, '已存在相同权限');
|
||||||
|
}
|
||||||
|
$rule = AuthRule::create($item);
|
||||||
|
//基本权限的话需要重置所有已有角色权限缓存
|
||||||
|
if ($item['is_base'] > 0) {
|
||||||
|
AuthGroup::resetGroupRulesCache();
|
||||||
|
} else {
|
||||||
|
AuthGroup::resetGroupRulesCache(1);
|
||||||
|
}
|
||||||
|
Log::write('rule', 'add', "权限新增,ID:{$rule->id}, 标题:{$item['title']}");
|
||||||
|
return $this->json();
|
||||||
|
} catch (ValidateException $e) {
|
||||||
|
return $this->json(2, $e->getError());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$parentId = input('param.parent_id/d',0);
|
||||||
|
if($parentId > 0){
|
||||||
|
$parent = AuthRule::getById($parentId);
|
||||||
|
$this->data['parent'] = $parent;
|
||||||
|
}
|
||||||
|
$this->data['parentId'] = $parentId;
|
||||||
|
return $this->view();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 权限列表(全部)
|
||||||
|
*/
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
$list = AuthRule::getListTree();
|
||||||
|
$this->data['items'] = $list;
|
||||||
|
return $this->view();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,277 @@
|
||||||
|
<?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);
|
||||||
|
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);
|
||||||
|
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);
|
||||||
|
} 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);
|
||||||
|
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,221 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace app\controller\manager;
|
||||||
|
|
||||||
|
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 __construct()
|
||||||
|
{
|
||||||
|
$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)) {
|
||||||
|
$this->uploadPathIsWritable = 1;
|
||||||
|
}
|
||||||
|
if (is_writable(app()->getRootPath().'public'.$this->videoUploadPath)) {
|
||||||
|
$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');
|
||||||
|
if (!$this->videoUploadPathIsWritable) {
|
||||||
|
return $this->json(1, '上传文件夹需要写入权限');
|
||||||
|
}
|
||||||
|
if ($this->validate->checkVideo($video)) {
|
||||||
|
$md5 = $video->md5();//文件md5
|
||||||
|
if ($fileItem = File::where('md5', $md5)->find()) {
|
||||||
|
$return['src'] = $fileItem['src'];
|
||||||
|
$fileItem['updated_at'] = date('Y-m-d H:i:s');
|
||||||
|
$fileItem->save();
|
||||||
|
return $this->json(200, '该文件已存在 路径为:'.$fileItem['path'], $return);
|
||||||
|
}
|
||||||
|
|
||||||
|
$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('Ymd');//自定义目录
|
||||||
|
$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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//文件上传(通用)
|
||||||
|
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(date('Ymd'), $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');
|
||||||
|
$md5 = $image->md5();//文件md5
|
||||||
|
$type = request()->param('type/s', '');
|
||||||
|
$path = request()->param('path/s', '');//指定路径 基于public下 若为空则默认
|
||||||
|
$hasPath = !empty($path);
|
||||||
|
|
||||||
|
if ($this->validate->checkImage($image)) {
|
||||||
|
$info = @getimagesize($image->getPathname());
|
||||||
|
$width = $info[0] ?? 0;
|
||||||
|
$height = $info[1] ?? 0;
|
||||||
|
|
||||||
|
// 海报限制大小 750 * 1334
|
||||||
|
switch ($type) {
|
||||||
|
case 'porter':
|
||||||
|
if ($width != 750 || $height != 1334) {
|
||||||
|
return $this->json(1, '海报背景图尺寸大小固定为:750 * 1334');
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 : date('Ymd');//自定义目录
|
||||||
|
$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) {
|
||||||
|
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 wangImage()
|
||||||
|
{
|
||||||
|
|
||||||
|
$imageArr = request()->file('wang_img'); // 该方式,前端js上传方法中字段名称必须以数组形式传参 如 wang_img[] = 值
|
||||||
|
$errno = 0;
|
||||||
|
$data = [];
|
||||||
|
|
||||||
|
if (!$this->uploadPathIsWritable) {
|
||||||
|
$errno = 1;
|
||||||
|
$data[] = '上传文件夹需要写入权限';
|
||||||
|
} else {
|
||||||
|
foreach ($imageArr as $image) {
|
||||||
|
$md5 = $image->md5();//文件md5
|
||||||
|
if ($fileItem = File::where('md5', $md5)->find()) {
|
||||||
|
$return['src'] = $fileItem['src'];
|
||||||
|
$fileItem['updated_at'] = date('Y-m-d H:i:s');
|
||||||
|
|
||||||
|
$data[] = $fileItem['src'];
|
||||||
|
$fileItem->save();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->validate->checkImage($image)) {
|
||||||
|
$src = Filesystem::putFile(date('Ymd'), $image, 'uniqid');
|
||||||
|
$src = $this->uploadPath.$this->DIRECTORY_SEPARATOR.$src;
|
||||||
|
$data[] = $src;
|
||||||
|
if ($this->isCompress) {
|
||||||
|
Image::resize($src);
|
||||||
|
}
|
||||||
|
File::add($image, $src, $md5); //加入上传文件表
|
||||||
|
} else {
|
||||||
|
$errno = 1;
|
||||||
|
$data = [];
|
||||||
|
$data[] = Lang::get($this->validate->getError());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$return['errno'] = $errno;
|
||||||
|
$return['data'] = $data;
|
||||||
|
return json($return);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
<?php
|
||||||
|
// 事件定义文件
|
||||||
|
return [
|
||||||
|
//事件标识
|
||||||
|
'bind' => [
|
||||||
|
// 'UserLogin' => 'app\event\UserLogin',
|
||||||
|
],
|
||||||
|
|
||||||
|
//监听事件
|
||||||
|
'listen' => [
|
||||||
|
'AppInit' => [],
|
||||||
|
'HttpRun' => [],
|
||||||
|
'HttpEnd' => [],
|
||||||
|
'LogLevel' => [],
|
||||||
|
'LogWrite' => [],
|
||||||
|
],
|
||||||
|
|
||||||
|
//订阅事件
|
||||||
|
'subscribe' => [
|
||||||
|
'app\subscribe\Spu',
|
||||||
|
'app\subscribe\Order',
|
||||||
|
'app\subscribe\Coupon',
|
||||||
|
],
|
||||||
|
];
|
|
@ -0,0 +1,10 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace app\exception;
|
||||||
|
|
||||||
|
use Exception;
|
||||||
|
|
||||||
|
class ApiRedirectException extends Exception
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace app\exception;
|
||||||
|
|
||||||
|
class RepositoryException 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,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,11 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace app\model;
|
||||||
|
|
||||||
|
use Exception;
|
||||||
|
use think\exception\ValidateException;
|
||||||
|
|
||||||
|
class Account extends Base
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
|
@ -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,388 @@
|
||||||
|
<?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 ($limit) {
|
||||||
|
if ($page) {
|
||||||
|
$q = $q->page($page);
|
||||||
|
}
|
||||||
|
$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,11 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace app\model;
|
||||||
|
|
||||||
|
class Business extends Base
|
||||||
|
{
|
||||||
|
const state_reviewing = 0;
|
||||||
|
const state_on = 1;
|
||||||
|
const state_off = 2;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace app\model;
|
||||||
|
|
||||||
|
//商家和用户的链接表
|
||||||
|
class BusinessFlow extends Base
|
||||||
|
{
|
||||||
|
public function account()
|
||||||
|
{
|
||||||
|
return $this->hasOne(Account::class,"user_code","user_code");
|
||||||
|
}
|
||||||
|
public function business()
|
||||||
|
{
|
||||||
|
return $this->hasOne(Business::class,"code","business_code");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,66 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace app\model;
|
||||||
|
|
||||||
|
use think\Collection;
|
||||||
|
use think\db\exception\DataNotFoundException;
|
||||||
|
use think\db\exception\DbException;
|
||||||
|
use think\db\exception\ModelNotFoundException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 商家分类
|
||||||
|
* Class Disease
|
||||||
|
* @package app\model
|
||||||
|
*/
|
||||||
|
class Category extends Base
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 根据父级ID 获取病种列表
|
||||||
|
*
|
||||||
|
* @param int $pid
|
||||||
|
* @param string[] $fields
|
||||||
|
* @return Disease[]|array|Collection
|
||||||
|
* @throws DataNotFoundException
|
||||||
|
* @throws DbException
|
||||||
|
* @throws ModelNotFoundException
|
||||||
|
*/
|
||||||
|
public static function getListByPid(int $pid = 0, array $fields = ['pid', 'name', 'id'])
|
||||||
|
{
|
||||||
|
return self::where('pid', $pid)->order('id', 'desc')->field($fields)->select();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取全部病种列表
|
||||||
|
*
|
||||||
|
* @return Disease[]|array|Collection
|
||||||
|
* @throws DataNotFoundException
|
||||||
|
* @throws DbException
|
||||||
|
* @throws ModelNotFoundException
|
||||||
|
*/
|
||||||
|
public static function getList()
|
||||||
|
{
|
||||||
|
return self::field('id,pid,name,commision')->order('id', 'desc')->order('id')->select();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 病种 xmSelect json数据
|
||||||
|
*
|
||||||
|
* @param int $pid
|
||||||
|
* @param array $selected
|
||||||
|
* @param array $disabled
|
||||||
|
* @return array|Disease[]|Collection
|
||||||
|
* @throws DataNotFoundException
|
||||||
|
* @throws DbException
|
||||||
|
* @throws ModelNotFoundException
|
||||||
|
*/
|
||||||
|
public static function diseaseXmJson(int $pid = 0, array $selected = [], array $disabled = [])
|
||||||
|
{
|
||||||
|
$list = self::getListByPid($pid);
|
||||||
|
foreach ($list as $k => $m) {
|
||||||
|
$list[$k]['selected'] = in_array($m['id'], $selected);
|
||||||
|
$list[$k]['disabled'] = in_array($m['id'], $disabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $list;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
<?php
|
||||||
|
namespace app\model;
|
||||||
|
|
||||||
|
class Comment extends Base
|
||||||
|
{
|
||||||
|
//评论表
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
<?php
|
||||||
|
namespace app\model;
|
||||||
|
|
||||||
|
class CommentRule extends Base
|
||||||
|
{
|
||||||
|
//评论规则表
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace app\model;
|
||||||
|
|
||||||
|
use think\Collection;
|
||||||
|
use think\db\exception\DataNotFoundException;
|
||||||
|
use think\db\exception\DbException;
|
||||||
|
use think\db\exception\ModelNotFoundException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 优惠券
|
||||||
|
* Class Coupon
|
||||||
|
* @package app\model
|
||||||
|
*/
|
||||||
|
class Coupon extends Base
|
||||||
|
{
|
||||||
|
//是否验证
|
||||||
|
const is_verificated_on = 1;//1已验证
|
||||||
|
const is_verificated_off = 0;//0未验证
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace app\model;
|
||||||
|
|
||||||
|
use think\Collection;
|
||||||
|
use think\db\exception\DataNotFoundException;
|
||||||
|
use think\db\exception\DbException;
|
||||||
|
use think\db\exception\ModelNotFoundException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 优惠券主表
|
||||||
|
* Class CouponMain
|
||||||
|
* @package app\model
|
||||||
|
*/
|
||||||
|
class CouponMain extends Base
|
||||||
|
{
|
||||||
|
const status_on = 0;//进行中
|
||||||
|
const status_off = 1;//停止
|
||||||
|
const on_shelf_on = 0;//上架状态
|
||||||
|
const on_shelf_off = 1;//下架状态
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace app\model;
|
||||||
|
|
||||||
|
use think\Collection;
|
||||||
|
use think\db\exception\DataNotFoundException;
|
||||||
|
use think\db\exception\DbException;
|
||||||
|
use think\db\exception\ModelNotFoundException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 优惠券类型
|
||||||
|
* Class CouponType
|
||||||
|
* @package app\model
|
||||||
|
*/
|
||||||
|
class CouponType extends Base
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace app\model;
|
||||||
|
|
||||||
|
use think\Collection;
|
||||||
|
use think\db\exception\DataNotFoundException;
|
||||||
|
use think\db\exception\DbException;
|
||||||
|
use think\db\exception\ModelNotFoundException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 扣费记录
|
||||||
|
* Class Deduction
|
||||||
|
* @package app\model
|
||||||
|
*/
|
||||||
|
class Deduction extends Base
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,129 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace app\model;
|
||||||
|
|
||||||
|
use app\service\AliOss;
|
||||||
|
use Exception;
|
||||||
|
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']!= "false" && $baseConfig['oss']!== false) {
|
||||||
|
$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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 将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,20 @@
|
||||||
|
<?php
|
||||||
|
namespace app\model;
|
||||||
|
|
||||||
|
class Log extends Base
|
||||||
|
{
|
||||||
|
//记录操作日志
|
||||||
|
public static function write($controller, $action, $content)
|
||||||
|
{
|
||||||
|
$auth = session('auth');
|
||||||
|
return self::create([
|
||||||
|
'member_id' => $auth['user_id'],
|
||||||
|
'name' => $auth['username'],
|
||||||
|
'ip' => request()->ip(),
|
||||||
|
'create_time' => time(),
|
||||||
|
'controller' => $controller,
|
||||||
|
'action' => $action,
|
||||||
|
'content' => $content
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
<?php
|
||||||
|
namespace app\model;
|
||||||
|
|
||||||
|
class LoginLog extends Base
|
||||||
|
{
|
||||||
|
}
|
|
@ -0,0 +1,81 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace app\model;
|
||||||
|
|
||||||
|
use think\facade\Db;
|
||||||
|
|
||||||
|
class Member extends Base
|
||||||
|
{
|
||||||
|
public const STATUS_NORMAL = 1;//正常
|
||||||
|
public const STATUS_DISABLE = 0;//禁用
|
||||||
|
|
||||||
|
public const ANENT_role_id = 2;//角色id 2 为代理商
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
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 getAgentAll(){
|
||||||
|
|
||||||
|
$subQuery = Db::name('member')
|
||||||
|
->field('id,business_code,nickname')
|
||||||
|
->whereRaw('(find_in_set("'.Member::ANENT_role_id.'", roles))')
|
||||||
|
->buildSql();
|
||||||
|
|
||||||
|
return Db::table($subQuery . ' a')
|
||||||
|
->join("business b" ,"a.business_code = b.code")
|
||||||
|
->field("a.*")
|
||||||
|
->order('a.id', 'desc')
|
||||||
|
->select();
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 根据角色分组返回用户
|
||||||
|
* @param int $groupId 角色分组ID
|
||||||
|
* @param int $limit 每页数量
|
||||||
|
*/
|
||||||
|
public static function getListByGroup($groupId, $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')
|
||||||
|
->where('m.group_id', '=', $groupId)
|
||||||
|
->order('m.id', 'asc')
|
||||||
|
->paginate($limit);
|
||||||
|
}
|
||||||
|
|
||||||
|
//根据用户名获取管理账号
|
||||||
|
public static function getByUserName($username)
|
||||||
|
{
|
||||||
|
return self::where('username', trim($username))
|
||||||
|
->findOrEmpty()
|
||||||
|
->toArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
//根据ID获取管理账户和相关权限
|
||||||
|
public static function getMemberAndRulesByID($memberId)
|
||||||
|
{
|
||||||
|
return self::alias('m')
|
||||||
|
->join('auth_group g', 'm.group_id = g.id', 'LEFT')
|
||||||
|
->field('m.group_id,g.rules')
|
||||||
|
->where('m.id', $memberId)
|
||||||
|
->findOrEmpty()
|
||||||
|
->toArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function updateCates($id, $cates)
|
||||||
|
{
|
||||||
|
$cates = implode(',', $cates);
|
||||||
|
$data = ['cates' => $cates];
|
||||||
|
self::updateById($id, $data);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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,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,8 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace app\model;
|
||||||
|
|
||||||
|
class PaymentLog extends Base
|
||||||
|
{
|
||||||
|
public const TYPE_ORDER = 'order';//订单支付
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace app\model;
|
||||||
|
|
||||||
|
use think\Collection;
|
||||||
|
use think\db\exception\DataNotFoundException;
|
||||||
|
use think\db\exception\DbException;
|
||||||
|
use think\db\exception\ModelNotFoundException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 充值记录
|
||||||
|
* Class Recharge
|
||||||
|
* @package app\model
|
||||||
|
*/
|
||||||
|
class Recharge extends Base
|
||||||
|
{
|
||||||
|
const state_off = 0;//未支付
|
||||||
|
const state_on = 1;//已支付
|
||||||
|
|
||||||
|
public function business()
|
||||||
|
{
|
||||||
|
return $this->hasOne(Business::class,"code","business_code")->bind(["business_name"]);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
<?php
|
||||||
|
namespace app\model;
|
||||||
|
|
||||||
|
class Role extends Base
|
||||||
|
{
|
||||||
|
public const STATUS_NORMAL = 1; //正常
|
||||||
|
public const STATUS_DISABLE = 0;//禁用
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
<?php
|
||||||
|
namespace app\model;
|
||||||
|
|
||||||
|
class Rules extends Base
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace app\model;
|
||||||
|
|
||||||
|
class Slide extends Base
|
||||||
|
{
|
||||||
|
public static function delByIds($ids)
|
||||||
|
{
|
||||||
|
return self::whereIn('id', $ids)->delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
//获取幻灯片列表
|
||||||
|
public static function getList()
|
||||||
|
{
|
||||||
|
return self::order("sort asc")
|
||||||
|
->select()
|
||||||
|
->toArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function onAfterInsert($slide)
|
||||||
|
{
|
||||||
|
$slide->sort = $slide->id;
|
||||||
|
$slide->save();
|
||||||
|
}
|
||||||
|
|
||||||
|
//获取轮播图涉及到的文件
|
||||||
|
public static function getFilesInUse()
|
||||||
|
{
|
||||||
|
$items = self::select()->toArray();
|
||||||
|
$data = [];
|
||||||
|
foreach ($items as $item) {
|
||||||
|
$src = trim($item['src']);
|
||||||
|
if (!empty($src)) {
|
||||||
|
$key = getKeyByPath($src);
|
||||||
|
$data[$key] = $src;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
<?php
|
||||||
|
namespace app\model;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 轮播图显示位置
|
||||||
|
*
|
||||||
|
* Class SlidePosition
|
||||||
|
* @package app\model
|
||||||
|
*/
|
||||||
|
class SlidePosition extends Base
|
||||||
|
{
|
||||||
|
public static function allPosition()
|
||||||
|
{
|
||||||
|
return self::select();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,54 @@
|
||||||
|
<?php
|
||||||
|
namespace app\model;
|
||||||
|
|
||||||
|
class System extends Base
|
||||||
|
{
|
||||||
|
//获取友情链接上传图片尺寸
|
||||||
|
public static function getLinkImageSize()
|
||||||
|
{
|
||||||
|
$system = self::getSystem();
|
||||||
|
if(!empty($system['link_w']) && !empty($system['link_h'])){
|
||||||
|
$linkSize = $system['link_w'] . '像素 X ' . $system['link_h'] . '像素';
|
||||||
|
}else{
|
||||||
|
$linkSize = '';
|
||||||
|
}
|
||||||
|
return $linkSize;
|
||||||
|
}
|
||||||
|
//获取幻灯片上传尺寸
|
||||||
|
public static function getSlideImageSize()
|
||||||
|
{
|
||||||
|
$system = self::getSystem();
|
||||||
|
if(!empty($system['slide_w']) && !empty($system['slide_h'])){
|
||||||
|
$slideSize = $system['slide_w'] . '像素 X ' . $system['slide_h'] . '像素';
|
||||||
|
}else{
|
||||||
|
$slideSize = '';
|
||||||
|
}
|
||||||
|
if(!empty($system['slide_mobile_w']) && !empty($system['slide_mobile_h'])){
|
||||||
|
$slideMobileSize = $system['slide_mobile_w'] . '像素 X ' . $system['slide_mobile_h'] . '像素';
|
||||||
|
}else{
|
||||||
|
$slideMobileSize = '';
|
||||||
|
}
|
||||||
|
return [
|
||||||
|
'slide_size' => $slideSize,
|
||||||
|
'slide_mobile_size' => $slideMobileSize
|
||||||
|
];
|
||||||
|
}
|
||||||
|
//获取文章图片尺寸
|
||||||
|
public static function getArticleImageSize()
|
||||||
|
{
|
||||||
|
$system = self::getSystem();
|
||||||
|
if(!empty($system['article_w']) && !empty($system['article_h'])){
|
||||||
|
$articleSize = $system['article_w'] . '像素 X ' . $system['article_h'] . '像素';
|
||||||
|
}else{
|
||||||
|
$articleSize = '';
|
||||||
|
}
|
||||||
|
return $articleSize;
|
||||||
|
}
|
||||||
|
//获取系统配置信息
|
||||||
|
public static function getSystem()
|
||||||
|
{
|
||||||
|
return self::order('id asc')
|
||||||
|
->findOrEmpty()
|
||||||
|
->toArray();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,107 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace app\repository;
|
||||||
|
|
||||||
|
use app\exception\RepositoryException;
|
||||||
|
|
||||||
|
use app\service\Repository;
|
||||||
|
use think\db\exception\DataNotFoundException;
|
||||||
|
use think\db\exception\DbException;
|
||||||
|
use think\db\exception\ModelNotFoundException;
|
||||||
|
use think\Model;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 账户域 相关操作(客户账号)
|
||||||
|
*
|
||||||
|
* Class AccountRepository
|
||||||
|
* @package app\repository
|
||||||
|
* @method self getInstance(Model $model = null) static
|
||||||
|
*/
|
||||||
|
class AccountRepository extends Repository
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 获取用户列表
|
||||||
|
*
|
||||||
|
* @throws RepositoryException
|
||||||
|
*/
|
||||||
|
public function list(): ?array
|
||||||
|
{
|
||||||
|
return $this->findList();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取指定账户记录By手机号
|
||||||
|
*
|
||||||
|
* @param string $phone
|
||||||
|
* @param array $fields
|
||||||
|
* @return Model|null
|
||||||
|
* @throws DataNotFoundException
|
||||||
|
* @throws DbException
|
||||||
|
* @throws ModelNotFoundException
|
||||||
|
*/
|
||||||
|
public function infoByPhone(string $phone, array $fields = []): ?Model
|
||||||
|
{
|
||||||
|
$where[] = ['mobile', '=', $phone];
|
||||||
|
return $this->findOneByWhere($where, $fields);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取指定账户记录By用户名
|
||||||
|
*
|
||||||
|
* @param string $username
|
||||||
|
* @param array $fields
|
||||||
|
* @return Model|null
|
||||||
|
* @throws DataNotFoundException
|
||||||
|
* @throws DbException
|
||||||
|
* @throws ModelNotFoundException
|
||||||
|
*/
|
||||||
|
public function infoByUsername(string $username, array $fields = []): ?Model
|
||||||
|
{
|
||||||
|
$where[] = ['username', '=', $username];
|
||||||
|
return $this->findOneByWhere($where, $fields);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过微信小程序的openID查询
|
||||||
|
*
|
||||||
|
* @param string $openID
|
||||||
|
* @return array|Model|null
|
||||||
|
* @throws DataNotFoundException
|
||||||
|
* @throws DbException
|
||||||
|
* @throws ModelNotFoundException
|
||||||
|
*/
|
||||||
|
public function findByOpenID(string $openID)
|
||||||
|
{
|
||||||
|
return $this->model->where('openid', $openID)->find();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改密码
|
||||||
|
*
|
||||||
|
* @param int $accountId
|
||||||
|
* @param string $oldPwd
|
||||||
|
* @param string $newPwd
|
||||||
|
* @return bool
|
||||||
|
* @throws RepositoryException
|
||||||
|
*/
|
||||||
|
public function modifyPwd(int $accountId, string $oldPwd, string $newPwd): bool
|
||||||
|
{
|
||||||
|
if (!$user = $this->findById($accountId)) {
|
||||||
|
throw new RepositoryException('用户不存在');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($user['password'] != md5($oldPwd)) {
|
||||||
|
throw new RepositoryException('原密码错误');
|
||||||
|
}
|
||||||
|
|
||||||
|
$user->password = md5($newPwd);
|
||||||
|
|
||||||
|
return $user->save();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,115 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace app\repository;
|
||||||
|
|
||||||
|
use app\exception\RepositoryException;
|
||||||
|
use app\model\Business;
|
||||||
|
use app\model\CouponMain;
|
||||||
|
use app\model\Deduction;
|
||||||
|
use app\model\Recharge;
|
||||||
|
use app\service\Repository;
|
||||||
|
use think\Collection;
|
||||||
|
use think\Model;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 商家域 相关操作
|
||||||
|
*
|
||||||
|
* Class BusinessRepository
|
||||||
|
* @package app\repository
|
||||||
|
* @method self getInstance(Model $model = null) static
|
||||||
|
*/
|
||||||
|
class BusinessRepository extends Repository
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 根据条件查询列表
|
||||||
|
*
|
||||||
|
* @param array $where 查询条件
|
||||||
|
* @param int $page 默认第一页 0不限制
|
||||||
|
* @param int $limit 限制条数 0不限制
|
||||||
|
* @param array $order
|
||||||
|
* @return array
|
||||||
|
* @throws RepositoryException
|
||||||
|
*/
|
||||||
|
public function businessList(array $where = [], int $page = 1, int $limit = 0, array $order = [])
|
||||||
|
{
|
||||||
|
$q = $this->model->alias("a")->field("id")->withJoin(["account" => ["avatar_url", "nick_name"], "business"]);
|
||||||
|
$data = [
|
||||||
|
'total' => 0,
|
||||||
|
'current' => $page,
|
||||||
|
'size' => $limit,
|
||||||
|
'list' => new Collection(),
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
|
if (count($where)) {
|
||||||
|
$q = $q->where($where);
|
||||||
|
}
|
||||||
|
if (count($order)) {
|
||||||
|
$q = $q->order($order);
|
||||||
|
}
|
||||||
|
$data['total'] = $q->count();
|
||||||
|
if ($data['total']) {
|
||||||
|
if ($limit) {
|
||||||
|
if ($page) {
|
||||||
|
$q = $q->page($page);
|
||||||
|
}
|
||||||
|
$q = $q->limit($limit);
|
||||||
|
}
|
||||||
|
|
||||||
|
$data['list'] = $q->select();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 优惠券列表
|
||||||
|
*
|
||||||
|
* @param string $businessCode 商家code
|
||||||
|
* @param int $page 默认第一页 0不限制
|
||||||
|
* @param int $limit 限制条数 0不限制
|
||||||
|
* @param array $order
|
||||||
|
* @return array
|
||||||
|
* @throws RepositoryException
|
||||||
|
*/
|
||||||
|
public function businessCouponList($where, int $page = 1, int $limit = 0, array $order = ["create_time" => "desc", "id" => "desc"])
|
||||||
|
{
|
||||||
|
return CouponMain::findList($where, [], $page, $limit, null, $order);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 扣费记录
|
||||||
|
*
|
||||||
|
* @param string $businessCode 商家code
|
||||||
|
* @param int $page 默认第一页 0不限制
|
||||||
|
* @param int $limit 限制条数 0不限制
|
||||||
|
* @param array $order
|
||||||
|
* @return array
|
||||||
|
* @throws RepositoryException
|
||||||
|
*/
|
||||||
|
public function businessDeductionList($where, int $page = 1, int $limit = 0, array $order = ["create_time" => "desc", "id" => "desc"])
|
||||||
|
{
|
||||||
|
return Deduction::findList($where, [], $page, $limit, null, $order);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 充值记录
|
||||||
|
*
|
||||||
|
* @param string $businessCode 商家code
|
||||||
|
* @param int $page 默认第一页 0不限制
|
||||||
|
* @param int $limit 限制条数 0不限制
|
||||||
|
* @param array $order
|
||||||
|
* @return array
|
||||||
|
* @throws RepositoryException
|
||||||
|
*/
|
||||||
|
public function businessRechargeList($where, int $page = 1, int $limit = 0, array $order = ["create_time" => "desc", "id" => "desc"])
|
||||||
|
{
|
||||||
|
return Recharge::findList($where, [], $page, $limit, function ($q){
|
||||||
|
return $q->withJoin(["business"=>["business_name"]]);
|
||||||
|
}, $order);
|
||||||
|
}
|
||||||
|
/* 获取所有不是代理商的商家*/
|
||||||
|
public function getBusinessAll(){
|
||||||
|
return Business:: where("state", Business::state_on)->select();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,49 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace app\repository;
|
||||||
|
|
||||||
|
use app\traits\cms\ArticleTrait;
|
||||||
|
use app\traits\cms\MenuTrait;
|
||||||
|
use app\traits\CmsCategoryTrait;
|
||||||
|
use think\db\exception\DataNotFoundException;
|
||||||
|
use think\db\exception\DbException;
|
||||||
|
use think\db\exception\ModelNotFoundException;
|
||||||
|
use think\Model;
|
||||||
|
use app\service\Repository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CMS 基础功能仓储
|
||||||
|
*
|
||||||
|
* Class CmsRepository
|
||||||
|
* @package app\repository
|
||||||
|
* @method self getInstance(Model $model = null) static
|
||||||
|
*/
|
||||||
|
class CmsRepository extends Repository
|
||||||
|
{
|
||||||
|
use CmsCategoryTrait;
|
||||||
|
use MenuTrait;
|
||||||
|
use ArticleTrait;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xmSelect下拉列表格式处理
|
||||||
|
* 如 [['title' => 'aa', 'value' => 1, 'selected' => true, 'prefix' => ' ']]
|
||||||
|
*
|
||||||
|
* @param array $data 待处理的数据
|
||||||
|
* @param string $symbol 分隔符号 默认
|
||||||
|
* @param int $repeatNum 重复次数 默认4
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function handleSelectedList(array $data, string $symbol = ' ', int $repeatNum = 4): array
|
||||||
|
{
|
||||||
|
$list = [];
|
||||||
|
foreach ($data as $item) {
|
||||||
|
$level = $item['level'] ?? 0;
|
||||||
|
$arr = $item;
|
||||||
|
$arr['children'] = $arr['children'] ?? [];
|
||||||
|
$arr['prefix'] = str_repeat($symbol, $level * $repeatNum);
|
||||||
|
$list[] = $arr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $list;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace app\repository;
|
||||||
|
|
||||||
|
use app\exception\RepositoryException;
|
||||||
|
use app\model\CouponMain;
|
||||||
|
use app\service\Repository;
|
||||||
|
use think\Model;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 优惠券 相关操作
|
||||||
|
*
|
||||||
|
* Class CouponRepository
|
||||||
|
* @package app\repository
|
||||||
|
* @method self getInstance(Model $model = null) static
|
||||||
|
*/
|
||||||
|
class CouponRepository extends Repository
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 优惠券列表
|
||||||
|
*
|
||||||
|
* @param string $businessCode 商家code
|
||||||
|
* @param array $order
|
||||||
|
* @return array
|
||||||
|
* @throws RepositoryException
|
||||||
|
*/
|
||||||
|
public function businessCouponModel($where)
|
||||||
|
{
|
||||||
|
return CouponMain::where($where);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,212 @@
|
||||||
|
<?php
|
||||||
|
namespace app\repository;
|
||||||
|
|
||||||
|
use app\model\SlidePosition;
|
||||||
|
use Exception;
|
||||||
|
use think\Model;
|
||||||
|
use app\model\Slide;
|
||||||
|
use think\Collection;
|
||||||
|
use app\service\Repository;
|
||||||
|
use think\db\exception\DbException;
|
||||||
|
use think\db\exception\DataNotFoundException;
|
||||||
|
use think\db\exception\ModelNotFoundException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 运营领域 相关
|
||||||
|
*
|
||||||
|
* Class OperationRepository
|
||||||
|
* @package app\repository
|
||||||
|
* @method self getInstance(Model $model = null) static
|
||||||
|
*/
|
||||||
|
class OperationRepository extends Repository
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 轮播位置
|
||||||
|
*
|
||||||
|
* @return string[][]
|
||||||
|
*/
|
||||||
|
public function slidePositions(): array
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
return SlidePosition::allPosition()->toArray();
|
||||||
|
} catch (Exception $e) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取轮播
|
||||||
|
*
|
||||||
|
* @param int $id
|
||||||
|
* @return array|Model|null
|
||||||
|
* @throws DataNotFoundException
|
||||||
|
* @throws DbException
|
||||||
|
* @throws ModelNotFoundException
|
||||||
|
*/
|
||||||
|
public function findSlideById(int $id)
|
||||||
|
{
|
||||||
|
return Slide::findById($id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 轮播列表
|
||||||
|
*
|
||||||
|
* @param array $where
|
||||||
|
* @param array $fields
|
||||||
|
* @param int $page
|
||||||
|
* @param int $size
|
||||||
|
* @param callable|null $call
|
||||||
|
* @param array $orders
|
||||||
|
* @return array
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public function slideList(array $where=[], array $fields=[], int $page=1, int $size=20, callable $call=null, array $orders=[]): array
|
||||||
|
{
|
||||||
|
return Slide::findList($where, $fields, $page, $size, $call, $orders);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新轮播
|
||||||
|
*
|
||||||
|
* @param array $data
|
||||||
|
* @param int $id
|
||||||
|
* @return bool
|
||||||
|
* @throws DataNotFoundException
|
||||||
|
* @throws DbException
|
||||||
|
* @throws ModelNotFoundException
|
||||||
|
*/
|
||||||
|
public function updateSlide(array $data, int $id): bool
|
||||||
|
{
|
||||||
|
$item = (new Slide())->where('id', $id)->find();
|
||||||
|
if ($item) {
|
||||||
|
return $item->save($data);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建轮播
|
||||||
|
*
|
||||||
|
* @param array $data
|
||||||
|
* @return Slide
|
||||||
|
*/
|
||||||
|
public function createSlide(array $data): Slide
|
||||||
|
{
|
||||||
|
$data['created_at'] = date('y-m-d H:i:s');
|
||||||
|
return Slide::create($data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除轮播图
|
||||||
|
*
|
||||||
|
* @param array $ids
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function deleteSlides(array $ids): bool
|
||||||
|
{
|
||||||
|
return Slide::deleteByIds($ids);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 轮播位置是否存在
|
||||||
|
*
|
||||||
|
* @param string $position
|
||||||
|
* @param int $exceptId 需要排除的显示位置ID
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function slidePositionExists(string $position, int $exceptId = 0): bool
|
||||||
|
{
|
||||||
|
return (new SlidePosition())->when($exceptId > 0, function ($q) use ($exceptId) {
|
||||||
|
$q->where('id', '<>', $exceptId);
|
||||||
|
})->where('key', $position)->count() > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据显示位置查询相关的轮播图信息
|
||||||
|
*
|
||||||
|
* @param string $position 轮播图位置标识
|
||||||
|
* @param int $size 限制查询数量
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public function slideListByPosition(string $position, int $size=0): ?Collection
|
||||||
|
{
|
||||||
|
$where[] = ['position', '=', $position];
|
||||||
|
$orders = ['sort'=>'asc'];
|
||||||
|
return Slide::findList($where, [], 1, $size, null, $orders)['list'];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 轮播显示位置列表
|
||||||
|
*
|
||||||
|
* @param array $where
|
||||||
|
* @param array $fields
|
||||||
|
* @param int $page
|
||||||
|
* @param int $size
|
||||||
|
* @param callable|null $call
|
||||||
|
* @param array $orders
|
||||||
|
* @return array
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public function slidePositionList(array $where=[], array $fields=[], int $page=1, int $size=20, callable $call=null, array $orders=[]): array
|
||||||
|
{
|
||||||
|
return SlidePosition::findList($where, $fields, $page, $size, $call, $orders);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新轮播位置
|
||||||
|
*
|
||||||
|
* @param array $data
|
||||||
|
* @param int $id
|
||||||
|
* @return bool
|
||||||
|
* @throws DataNotFoundException
|
||||||
|
* @throws DbException
|
||||||
|
* @throws ModelNotFoundException
|
||||||
|
*/
|
||||||
|
public function updateSlidePosition(array $data, int $id): bool
|
||||||
|
{
|
||||||
|
$item = (new SlidePosition())->where('id', $id)->find();
|
||||||
|
if ($item) {
|
||||||
|
$item->save($data);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建轮播位置
|
||||||
|
*
|
||||||
|
* @param array $data
|
||||||
|
* @return SlidePosition
|
||||||
|
*/
|
||||||
|
public function createSlidePosition(array $data): SlidePosition
|
||||||
|
{
|
||||||
|
$data['created_at'] = date('y-m-d H:i:s');
|
||||||
|
return SlidePosition::create($data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除轮播位置
|
||||||
|
*
|
||||||
|
* @param array $ids
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function deleteSlidePositions(array $ids): bool
|
||||||
|
{
|
||||||
|
return SlidePosition::deleteByIds($ids);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取轮播位置
|
||||||
|
*
|
||||||
|
* @param int $id
|
||||||
|
* @return array|Model|null
|
||||||
|
* @throws DataNotFoundException
|
||||||
|
* @throws DbException
|
||||||
|
* @throws ModelNotFoundException
|
||||||
|
*/
|
||||||
|
public function findSlidePositionById(int $id)
|
||||||
|
{
|
||||||
|
return SlidePosition::findById($id);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace app\repository;
|
||||||
|
|
||||||
|
use app\exception\RepositoryException;
|
||||||
|
|
||||||
|
use app\model\Recharge;
|
||||||
|
use app\service\Repository;
|
||||||
|
use think\db\exception\DataNotFoundException;
|
||||||
|
use think\db\exception\DbException;
|
||||||
|
use think\db\exception\ModelNotFoundException;
|
||||||
|
use think\Model;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 充值户域 相关操作
|
||||||
|
* Class RechargeRepository
|
||||||
|
* @package app\repository
|
||||||
|
* @method self getInstance(Model $model = null) static
|
||||||
|
*/
|
||||||
|
class RechargeRepository extends Repository
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 创建一个支付订单
|
||||||
|
* */
|
||||||
|
public function createOrder($businessCode, $money)
|
||||||
|
{
|
||||||
|
$data = [
|
||||||
|
"order_num" => createUuid(),
|
||||||
|
"business_code" => $businessCode,
|
||||||
|
"money" => $money,
|
||||||
|
"state" => Recharge::state_off,
|
||||||
|
"create_time" => date("Y-m-d H:i:s"),
|
||||||
|
"balance" => 0,
|
||||||
|
];
|
||||||
|
return Recharge::create($data);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use tauthz\TauthzService;
|
||||||
|
|
||||||
|
// 系统服务定义文件
|
||||||
|
// 服务在完成全局初始化之后执行
|
||||||
|
return [
|
||||||
|
TauthzService::class,
|
||||||
|
];
|
|
@ -0,0 +1,46 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace app\service;
|
||||||
|
|
||||||
|
use OSS\Core\OssException;
|
||||||
|
use OSS\OssClient;
|
||||||
|
use think\facade\Config;
|
||||||
|
use think\facade\Log;
|
||||||
|
|
||||||
|
class AliOss
|
||||||
|
{
|
||||||
|
private static $oss = null;
|
||||||
|
|
||||||
|
private function __construct()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
private function __clone()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 阿里云OSS
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public static function config()
|
||||||
|
{
|
||||||
|
Config::load('extra/alioss', 'alioss');
|
||||||
|
return config('alioss');
|
||||||
|
}
|
||||||
|
|
||||||
|
// 阿里云OSS实例 单例模式
|
||||||
|
public static function instance(): ?OssClient
|
||||||
|
{
|
||||||
|
if (self::$oss == null) {
|
||||||
|
try {
|
||||||
|
$conf = self::config();
|
||||||
|
self::$oss = new OssClient($conf['accessKeyId'], $conf['accessKeySecret'], $conf['endpoint']);
|
||||||
|
} catch (OssException $e) {
|
||||||
|
Log::error('实例化阿里云OSS失败: ' . $e->getMessage());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return self::$oss;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,64 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace app\service;
|
||||||
|
|
||||||
|
use Yansongda\Pay\Pay;
|
||||||
|
use Yansongda\Pay\Log;
|
||||||
|
use think\facade\Config;
|
||||||
|
|
||||||
|
class Alipay
|
||||||
|
{
|
||||||
|
private static $app = null;
|
||||||
|
|
||||||
|
private function __construct()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
private function __clone()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 支付宝配置
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public static function config(): array
|
||||||
|
{
|
||||||
|
Config::load('extra/alipay', 'alipay');
|
||||||
|
$conf = config('alipay');
|
||||||
|
return [
|
||||||
|
'app_id' => trim($conf['appId']),
|
||||||
|
'notify_url' => trim($conf['notify_url']),
|
||||||
|
'return_url' => trim($conf['return_url']) ?? trim($conf['notify_url']),
|
||||||
|
'ali_public_key' => trim($conf['aliPubKey']),//注意 这里的是支付宝的公钥
|
||||||
|
// 加密方式: **RSA2**
|
||||||
|
'private_key' => trim($conf['priKey']),
|
||||||
|
// 使用公钥证书模式,请配置下面两个参数,同时修改ali_public_key为以.crt结尾的支付宝公钥证书路径,
|
||||||
|
// 如(./cert/alipayCertPublicKey_RSA2.crt)
|
||||||
|
// 'app_cert_public_key' => './cert/appCertPublicKey.crt', //应用公钥证书路径
|
||||||
|
// 'alipay_root_cert' => './cert/alipayRootCert.crt', //支付宝根证书路径
|
||||||
|
'log' => [ // optional
|
||||||
|
'file' => './logs/alipay.log',
|
||||||
|
'level' => 'debug', // 建议生产环境等级调整为 info,开发环境为 debug
|
||||||
|
'type' => 'single', // optional, 可选 daily.
|
||||||
|
'max_file' => 30, // optional, 当 type 为 daily 时有效,默认 30 天
|
||||||
|
],
|
||||||
|
'http' => [ // optional
|
||||||
|
'timeout' => 5.0,
|
||||||
|
'connect_timeout' => 5.0,
|
||||||
|
// 更多配置项请参考 [Guzzle](https://guzzle-cn.readthedocs.io/zh_CN/latest/request-options.html)
|
||||||
|
],
|
||||||
|
// 'mode' => 'dev', // optional,设置此参数,将进入沙箱模式
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
//支付宝支付实例 单例模式
|
||||||
|
public static function getInstance(): ?\Yansongda\Pay\Gateways\Alipay
|
||||||
|
{
|
||||||
|
if (self::$app == null) {
|
||||||
|
self::$app = Pay::alipay(self::config());
|
||||||
|
}
|
||||||
|
return self::$app;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,201 @@
|
||||||
|
<?php
|
||||||
|
namespace app\service;
|
||||||
|
|
||||||
|
use PhpOffice\PhpSpreadsheet\Shared\Date as EDate;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Style\Alignment;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Style\Border;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
|
||||||
|
use think\file\UploadedFile;
|
||||||
|
|
||||||
|
class Excel
|
||||||
|
{
|
||||||
|
// 导出excel默认样式
|
||||||
|
public static array $excelStyle = [
|
||||||
|
'font' => [
|
||||||
|
'name' => '宋体',
|
||||||
|
],
|
||||||
|
'alignment' => [
|
||||||
|
'horizontal' => Alignment::HORIZONTAL_CENTER, // 水平居中
|
||||||
|
'vertical' => Alignment::VERTICAL_CENTER, // 垂直居中
|
||||||
|
'wrapText' => true,
|
||||||
|
],
|
||||||
|
'borders' => [
|
||||||
|
'allBorders' => [
|
||||||
|
'borderStyle' => Border::BORDER_THIN,
|
||||||
|
'color' => ['rgb' => 'eeeeee'],
|
||||||
|
]
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
public static array $defaultSetting = [
|
||||||
|
'cell_width' => 30, // 默认列宽
|
||||||
|
'font_size' => 12, // 默认excel内容字体大小
|
||||||
|
];
|
||||||
|
|
||||||
|
//导出
|
||||||
|
static public function export($spreadsheet,$filename)
|
||||||
|
{
|
||||||
|
$writer = new Xlsx($spreadsheet);
|
||||||
|
header("Content-Type: application/force-download");
|
||||||
|
header("Content-Type: application/octet-stream");
|
||||||
|
header("Content-Type: application/download");
|
||||||
|
header('Content-Disposition:inline;filename="'.$filename.'"');
|
||||||
|
header("Content-Transfer-Encoding: binary");
|
||||||
|
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
|
||||||
|
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
|
||||||
|
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
|
||||||
|
header("Pragma: no-cache");
|
||||||
|
$writer->save('php://output');
|
||||||
|
$spreadsheet->disconnectWorksheets();
|
||||||
|
unset($spreadsheet);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function cancelTimeLimit()
|
||||||
|
{
|
||||||
|
ini_set('max_execution_time', '0');
|
||||||
|
ini_set("memory_limit", '-1');
|
||||||
|
set_time_limit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据header字段获取可配置列的cellId列表
|
||||||
|
* 默认前26列为可配置列A~Z, $headerLength不能超过26 * 27 = 702
|
||||||
|
*
|
||||||
|
* @param int $headerLength
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public static function getCellIds(int $headerLength): array
|
||||||
|
{
|
||||||
|
$defaultCellIds = range('A', 'Z', 1);
|
||||||
|
$cellIds = $defaultCellIds;
|
||||||
|
$loop = ceil($headerLength / 26);
|
||||||
|
if($loop>1) {
|
||||||
|
$maxPrefixIndex = ($loop - 2) >= 25 ? 25 : ($loop - 2);
|
||||||
|
for ($prefixIndex = 0; $prefixIndex<= $maxPrefixIndex; $prefixIndex++) {
|
||||||
|
$prefix = $defaultCellIds[$prefixIndex];
|
||||||
|
$cellIds = array_merge($cellIds, array_map(function ($val) use($prefix) {
|
||||||
|
return $prefix.$val;
|
||||||
|
}, $defaultCellIds));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $cellIds;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置导出表数据
|
||||||
|
*
|
||||||
|
* @param Worksheet $sheet 工作表对象
|
||||||
|
* @param array $cellValues 数据信息,二维数组(ps:若字段值需要指定样式以数组格式传递,如[$val, DataType::TYPE_STRING])。第二行开始填充
|
||||||
|
* @param array $header 表头信息, 第一行为表头
|
||||||
|
* @param string $sheetTitle 工作表标题
|
||||||
|
* @param array $cellWidthList 列宽样式,键值对,键名为列序号(从0开始计算)
|
||||||
|
* @param array $excelStyle 表数据样式
|
||||||
|
* @param array $defaultList 默认设置样式
|
||||||
|
* @param array $cellWrapList 列换行样式
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public static function setExcelCells(Worksheet $sheet, array $cellValues, array $header, string $sheetTitle = '数据列表', $cellWidthList = [], $excelStyle = [], $defaultList = [], $cellWrapList = []): bool
|
||||||
|
{
|
||||||
|
$defaultStyle = [
|
||||||
|
'font' => [
|
||||||
|
'name' => '宋体',
|
||||||
|
],
|
||||||
|
'alignment' => [
|
||||||
|
'horizontal' => Alignment::HORIZONTAL_CENTER, // 水平居中
|
||||||
|
'vertical' => Alignment::VERTICAL_CENTER, // 垂直居中
|
||||||
|
'wrapText' => false,
|
||||||
|
],
|
||||||
|
'borders' => [
|
||||||
|
'allBorders' => [
|
||||||
|
'borderStyle' => Border::BORDER_THIN,
|
||||||
|
'color' => ['rgb'=>'eeeeee'],
|
||||||
|
]
|
||||||
|
],
|
||||||
|
];
|
||||||
|
$headerLength = count($header);
|
||||||
|
|
||||||
|
if($headerLength === 0) return false;
|
||||||
|
$cellIds = self::getCellIds($headerLength);
|
||||||
|
$lastCellId = $cellIds[$headerLength-1];
|
||||||
|
$contentIndex = 2;
|
||||||
|
foreach ($cellValues as $n => $itemCell) {
|
||||||
|
foreach ($itemCell as $i => $cellValue) {
|
||||||
|
if(is_array($cellValue)) {
|
||||||
|
$sheet->setCellValueExplicit($cellIds[$i] . $contentIndex, ...$cellValue);
|
||||||
|
} else {
|
||||||
|
$sheet->setCellValue($cellIds[$i] . $contentIndex, $cellValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$contentIndex++;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$headerStr = 'A1:' . $lastCellId.'1';
|
||||||
|
$bodyStr = 'A2:' . $lastCellId . ($contentIndex - 1);
|
||||||
|
|
||||||
|
$defaultWidth = 24; // 默认列宽24个字符
|
||||||
|
$fontSize = 12; // 默认字体大小为12号
|
||||||
|
if(!empty($defaultList)) {
|
||||||
|
if(isset($defaultList['cell_width']) && is_numeric($defaultList['cell_width']) && $defaultList['cell_width'] > 0) {
|
||||||
|
$defaultWidth = $defaultList['cell_width'];
|
||||||
|
}
|
||||||
|
if(isset($defaultList['font_size']) && is_numeric($defaultList['font_size']) && $defaultList['font_size'] > 0) {
|
||||||
|
$fontSize = $defaultList['font_size'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$sheet->setTitle(empty($sheetTitle) ? '数据列表': $sheetTitle);
|
||||||
|
$sheet->getDefaultColumnDimension()->setAutoSize($fontSize);
|
||||||
|
$sheet->getStyle($headerStr)->getFont()->setBold(false)->setSize($fontSize+2);
|
||||||
|
$sheet->getDefaultColumnDimension()->setWidth($defaultWidth);
|
||||||
|
$sheet->fromArray($header, null, 'A1');
|
||||||
|
$sheet->getStyle($headerStr)->applyFromArray($defaultStyle);
|
||||||
|
$sheet->getStyle($bodyStr)->applyFromArray(empty($excelStyle) ? $defaultStyle : $excelStyle);
|
||||||
|
|
||||||
|
// 自定义列宽
|
||||||
|
if(!empty($cellWidthList)) {
|
||||||
|
foreach ($cellWidthList as $cellId => $widthVal) {
|
||||||
|
if(isset($cellIds[$cellId]) && is_numeric($widthVal) && $widthVal > 0) {
|
||||||
|
$sheet->getColumnDimension($cellIds[$cellId])->setWidth($widthVal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//自定义列是否换行
|
||||||
|
if(!empty($cellWrapList)) {
|
||||||
|
foreach ($cellWrapList as $cellId => $boolVal) {
|
||||||
|
if(isset($cellIds[$cellId])) {
|
||||||
|
$wrap = $boolVal ? true : false;
|
||||||
|
$sheet->getStyle($cellIds[$cellId])->getAlignment()->setWrapText($wrap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// excel导入时间转换
|
||||||
|
public static function getExcelTime($timeStr, $format = 'Y-m-d')
|
||||||
|
{
|
||||||
|
$timezone = ini_get('date.timezone');
|
||||||
|
$timeStr = trim($timeStr);
|
||||||
|
if (!empty($timeStr)) {
|
||||||
|
if (is_numeric($timeStr)) {
|
||||||
|
$toTimestamp = EDate::excelToTimestamp($timeStr, $timezone);
|
||||||
|
$timeStr = date($format, $toTimestamp);
|
||||||
|
} else {
|
||||||
|
$toTimestamp = strtotime($timeStr);
|
||||||
|
$timeStr = ($toTimestamp === false) ? '' : date($format, $toTimestamp);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$timeStr = '';
|
||||||
|
}
|
||||||
|
return $timeStr;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,62 @@
|
||||||
|
<?php
|
||||||
|
namespace app\service;
|
||||||
|
|
||||||
|
use think\facade\Config as CConfig;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 扩展配置项工具类
|
||||||
|
* Class ExtraConfig
|
||||||
|
* @package app\service
|
||||||
|
*/
|
||||||
|
class ExtraConfig
|
||||||
|
{
|
||||||
|
private static string $extraDir = 'extra/';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 比率设置
|
||||||
|
* @return array|mixed
|
||||||
|
*/
|
||||||
|
public static function ratio()
|
||||||
|
{
|
||||||
|
CConfig::load(self::$extraDir.'ratio', 'ratio');
|
||||||
|
return config('ratio') ?? [];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 微信相关设置
|
||||||
|
* @return array|mixed
|
||||||
|
*/
|
||||||
|
public static function wechat()
|
||||||
|
{
|
||||||
|
CConfig::load(self::$extraDir.'wechat', 'wechat');
|
||||||
|
return config('wechat') ?? [];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 小程序个性装修配置
|
||||||
|
* @return array|mixed
|
||||||
|
*/
|
||||||
|
public static function miniProgram()
|
||||||
|
{
|
||||||
|
CConfig::load('extra/mini_program', 'mini_program');
|
||||||
|
return config('mini_program') ?? [];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 基础配置
|
||||||
|
*/
|
||||||
|
public static function base()
|
||||||
|
{
|
||||||
|
CConfig::load('extra/base', 'base');
|
||||||
|
return config('base') ?? [];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 阿里OSS配置
|
||||||
|
*/
|
||||||
|
public static function aliOss()
|
||||||
|
{
|
||||||
|
CConfig::load('extra/alioss', 'alioss');
|
||||||
|
return config('alioss') ?? [];
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,65 @@
|
||||||
|
<?php
|
||||||
|
namespace app\service;
|
||||||
|
|
||||||
|
use think\file\UploadedFile;
|
||||||
|
|
||||||
|
class File
|
||||||
|
{
|
||||||
|
//上传文件移动到上传文件夹
|
||||||
|
public static function move(UploadedFile $file)
|
||||||
|
{
|
||||||
|
$upload_path = 'storage/uploads/' . date('Ymd');
|
||||||
|
$path = app()->getRootPath() . $upload_path;
|
||||||
|
$filename = uniqid() . '.' . $file->extension();
|
||||||
|
$upload_filename = '/' . $upload_path . '/' . $filename;
|
||||||
|
return [$file->move($path, $filename), $file, $upload_filename];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件访问路径转换为完整的url
|
||||||
|
* @param string|null $fileUrl
|
||||||
|
* @param bool $ossAnalysis 是否进行OSS解析
|
||||||
|
* @return string
|
||||||
|
* @todo 若启用OOS存储,需根据业务配置调整$fileDomain
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public static function convertCompleteFileUrl(?string $fileUrl, bool $ossAnalysis=true): string
|
||||||
|
{
|
||||||
|
if (empty($fileUrl)) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
if ($ossAnalysis) {
|
||||||
|
$fileDomain = self::getFileDomain();
|
||||||
|
} else {
|
||||||
|
$fileDomain = request()->domain();
|
||||||
|
}
|
||||||
|
$prefix = substr($fileUrl, 0, 4);
|
||||||
|
if (!($prefix == 'http')) {
|
||||||
|
$fileUrl = $fileDomain.'/'.ltrim($fileUrl, '/');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $fileUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件访问域名前缀
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public static function getFileDomain(): string
|
||||||
|
{
|
||||||
|
$confBase = ExtraConfig::base();
|
||||||
|
$confOss = ExtraConfig::aliOss();
|
||||||
|
$isOss = $confBase['oss'] ?? 'false';
|
||||||
|
$ossDomain = $confOss['customDomain'] ?? '';
|
||||||
|
|
||||||
|
// 默认为当前域名
|
||||||
|
$fileDomain = request()->domain();
|
||||||
|
if ($isOss == 'true' && !empty($ossDomain)) {
|
||||||
|
$fileDomain = $ossDomain;
|
||||||
|
}
|
||||||
|
|
||||||
|
$fileDomain = trim($fileDomain);
|
||||||
|
return rtrim($fileDomain, '/');
|
||||||
|
}
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue