init
commit
198397f325
|
@ -0,0 +1,12 @@
|
|||
.env
|
||||
/.idea
|
||||
/.vscode
|
||||
.vs
|
||||
backup/data/*
|
||||
/public/html/*
|
||||
*.log
|
||||
runtime/*
|
||||
public/storage/*
|
||||
.DS_Store
|
||||
nginx.htaccess
|
||||
dump.rdb
|
|
@ -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,18 @@
|
|||
# 四川大向天诚CMS管理系统
|
||||
|
||||
## 部署说明
|
||||
- 项目目录下是否存在`runtime`文件夹,不存在则创建,存在需要开启都写权限。
|
||||
```shell
|
||||
chmod -R 777 runtime
|
||||
```
|
||||
- public/storage文件夹同上
|
||||
|
||||
## PHP 扩展
|
||||
- fileinfo 文件操作通用扩展
|
||||
- exif 图片文件基础信息通用扩展,依赖于mbstring扩展,需要安装在mbstring扩展之后
|
||||
|
||||
## 使用技术栈
|
||||
- [Thinkphp6](https://www.kancloud.cn/manual/thinkphp6_0/1037479)
|
||||
- php7.1+ ~ 7.4
|
||||
- mysql 5.7+
|
||||
- 富文本:tinymce5+
|
|
@ -0,0 +1 @@
|
|||
deny from all
|
|
@ -0,0 +1,497 @@
|
|||
<?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\exception\ClassNotFoundException;
|
||||
use app\model\Model as ModelModel ;
|
||||
// 应用公共文件
|
||||
|
||||
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']){
|
||||
return '/';
|
||||
}
|
||||
if(!empty($cate['url'])){
|
||||
return $cate['url'];
|
||||
}
|
||||
if(!empty($cate['route'])){
|
||||
return $cate['route'].".html";
|
||||
}
|
||||
switch ($cate["model_id"]){
|
||||
case ModelModel::MODEL_ARTICLE:
|
||||
return url('/articles/'. $cate['id']);
|
||||
break;
|
||||
case ModelModel::MODEL_PAGE:
|
||||
return url('/page/index', ['categoryId' => $cate['id']]);
|
||||
break;
|
||||
case ModelModel::MODEL_PRODUCT:
|
||||
return url('/product/index', ['categoryId' => $cate['id']]);
|
||||
break;
|
||||
default:
|
||||
return url('/article/index', ['categoryId' => $cate['id']]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $url;
|
||||
}
|
||||
}
|
||||
|
||||
//根据栏目获取文章路径
|
||||
if (!function_exists('archiveGetUri')) {
|
||||
function archiveGetUri($archive)
|
||||
{
|
||||
if (!empty($archive) &&isset($archive["id"])&& isset($archive->archivesCategory)&&!empty($archive->archivesCategory)) {
|
||||
|
||||
if (empty($archive->archivesCategory->route)) {
|
||||
switch ($archive->archivesCategory["model_id"]){
|
||||
case ModelModel::MODEL_PRODUCT:
|
||||
return '/product/detail/'.$archive['id'].".html";
|
||||
break;
|
||||
default:
|
||||
return '/article/detail/'.$archive['id'].".html";
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
return $archive->archivesCategory->route."/".$archive['id'] .".html";
|
||||
}
|
||||
}
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//根据文件大小转换为文字
|
||||
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('getTextareaText')){
|
||||
function getTextareaText($content) {
|
||||
$content = trim($content);
|
||||
if(!empty($content)) {
|
||||
$content = str_replace("\r\n", "\n", $content);
|
||||
$content = str_replace("\r", "\n", $content);
|
||||
}
|
||||
return $content;
|
||||
}
|
||||
}
|
||||
|
||||
if(!function_exists('getTextNlToList')){
|
||||
function getTextNlToList($content) {
|
||||
$list = [];
|
||||
$content = getTextareaText($content);
|
||||
if(!empty($content)) {
|
||||
$list = explode("\n", $content);
|
||||
}
|
||||
return $list;
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('checkPathExistWithMake')) {
|
||||
/**
|
||||
* 检测文件夹是否存在,不存在时自动创建(需要有写入权限)
|
||||
* 支持递归创建
|
||||
*
|
||||
* @param string $absolutePath
|
||||
* @return bool
|
||||
*/
|
||||
function checkPathExistWithMake(string $absolutePath): bool
|
||||
{
|
||||
try {
|
||||
$absolutePath = rtrim($absolutePath, '/');
|
||||
if (empty($absolutePath)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!is_dir($absolutePath)) {
|
||||
return mkdir($absolutePath, 0777, true);
|
||||
}
|
||||
|
||||
return true;
|
||||
} catch (\Exception $e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('dateToFormat')) {
|
||||
/**
|
||||
* 时间日期格式化
|
||||
*
|
||||
* @param null|string $dateStr
|
||||
* @param string $format
|
||||
* @return string
|
||||
*/
|
||||
function dateToFormat(?string $dateStr, string $format='Y-m-d'): string
|
||||
{
|
||||
if (empty($dateStr)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$time = strtotime($dateStr);
|
||||
if (!$time) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return date($format, $time);
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('timeToFormat')) {
|
||||
/**
|
||||
* 时间日期格式化
|
||||
*
|
||||
* @param int $time
|
||||
* @param string $format
|
||||
* @return string
|
||||
*/
|
||||
function timeToFormat(int $time, string $format='Y-m-d'): string
|
||||
{
|
||||
if ($time <= 0) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return date($format, $time);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
<?php
|
||||
|
||||
namespace app\controller;
|
||||
|
||||
use app\model\AuthRule;
|
||||
use app\model\LoginLog;
|
||||
use app\model\Member;
|
||||
use app\service\Jwt;
|
||||
|
||||
class ApiManager extends Base
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
// $jwtData = [
|
||||
// 'member_id' => "11",
|
||||
// ];
|
||||
// $token = Jwt::generate($jwtData);
|
||||
|
||||
$token = input("token/s","");
|
||||
$userInfo = Jwt::parse($token);//token中携带的简易用户信息
|
||||
if(empty($userInfo)||!array_key_exists("member_id",$userInfo)){
|
||||
return $this->json(4001,"无效请求");
|
||||
}
|
||||
$member = Member::getById($userInfo["member_id"]);
|
||||
if(empty($member)){
|
||||
return $this->json(4001,"用户不存在");
|
||||
}
|
||||
|
||||
//执行登录
|
||||
$rulesList = AuthRule::userRolesList($member['group_id']);
|
||||
$rulesIdStr = '';
|
||||
if (!empty($rulesList)) {
|
||||
$rulesId = $rulesList['allRulesId'];
|
||||
$rulesIdStr = implode(',', $rulesId);
|
||||
}
|
||||
$authSession = [
|
||||
'userId' => $member['id'],
|
||||
'userName' => $member['username'],
|
||||
'groupId' => $member['group_id'],
|
||||
'rules' => $rulesIdStr,
|
||||
'cates' => $member['cates']
|
||||
];
|
||||
|
||||
//记录最后登陆时间
|
||||
$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', $authSession);
|
||||
|
||||
return $this->redirect("/manager");
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,158 @@
|
|||
<?php
|
||||
|
||||
namespace app\controller;
|
||||
|
||||
use app\model\{Article as MArticle,
|
||||
Category,
|
||||
Model
|
||||
};
|
||||
use page\DxtcPageA;
|
||||
use think\Collection;
|
||||
use think\Paginator;
|
||||
|
||||
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']);
|
||||
|
||||
$description = $article['seo_description'] ?: $this->system['seo_description'];
|
||||
$keywords = $article['seo_keywords'] ?: $this->system['seo_keywords'];
|
||||
$title = $article['seo_title'] ?: $article['title'].' | '.$this->system['seo_title'];
|
||||
|
||||
$pathArr = explode(',', $category['path']);
|
||||
$secondCategoryId = isset($pathArr[3]) && !empty($pathArr[3]) ? $pathArr[3] : $article['category_id'];
|
||||
$secondCategory = Category::getById($secondCategoryId);
|
||||
|
||||
$this->data['images'] = json_decode($article['imgs'], true);
|
||||
|
||||
$this->setSeo($title, $keywords, $description);
|
||||
$this->data['item'] = MArticle::parseInfo($article);
|
||||
$this->data['category'] = $category;
|
||||
$this->data['secondInfo'] = $secondCategory;
|
||||
$this->data['categoryId'] = $category['id'];
|
||||
$this->data['topCategoryId'] = Category::firstGradeById($category['id']) ;
|
||||
$this->detailPrevAndNext($article);
|
||||
$this->detailRecommendList($article, $category['recommend_num']);
|
||||
return $this->view($category['template_detail'] ?? 'news_detail');
|
||||
}
|
||||
|
||||
// 上下篇
|
||||
private function detailPrevAndNext($article)
|
||||
{
|
||||
$prev = [];
|
||||
$next = [];
|
||||
|
||||
if ($article) {
|
||||
$sortCategoryIds = [];
|
||||
|
||||
/*
|
||||
$caseCategoryIds = Category::getCategoryWithChildrenIds(Category::CATEGORY_COMMUNITY);
|
||||
if(in_array($article['category_id'], $caseCategoryIds)) {
|
||||
$sortCategoryIds = $caseCategoryIds;
|
||||
}
|
||||
*/
|
||||
|
||||
if (!empty($sortCategoryIds)) {
|
||||
$prevWhere = [
|
||||
['sort', '>', $article['sort']],
|
||||
['category_id', 'in', $sortCategoryIds]
|
||||
];
|
||||
$prevOrder = ['a.sort' => 'asc'];
|
||||
$prev = MArticle::getPrevArticleByTimeAndCategoryIds($prevWhere, $prevOrder);
|
||||
$nextWhere = [
|
||||
['sort', '<', $article['sort']],
|
||||
['category_id', 'in', $sortCategoryIds]
|
||||
];
|
||||
$nextOrder = ['sort' => 'desc'];
|
||||
$next = MArticle::getNextArticleByTimeAndCategoryIds($nextWhere, $nextOrder);
|
||||
} else {
|
||||
$prev = MArticle::getPrevArticleBySortAndCategoryId($article['sort'], $article['category_id']);
|
||||
|
||||
$next = MArticle::getNextArticleBySortAndCategoryId($article['sort'], $article['category_id']);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$this->data['prev'] = $prev;
|
||||
$this->data['next'] = $next;
|
||||
}
|
||||
|
||||
// 相关推荐
|
||||
private function detailRecommendList($article, $num = 8)
|
||||
{
|
||||
// 目前规则为:除当前以外的同栏目下最新8个
|
||||
$orderList = ['top' => 'desc', 'recommend' => 'desc', 'id' => 'desc'];
|
||||
$list = MArticle::getLastTopList($article['category_id'], $num, [$article['id']], $orderList);
|
||||
|
||||
$this->data['recommendList'] = $list;
|
||||
}
|
||||
|
||||
//列表页
|
||||
public function index($categoryId = 0)
|
||||
{
|
||||
$categoryId = empty($categoryId) ? $this->request->param("category_id") : $categoryId;
|
||||
$category = Category::getById($categoryId);
|
||||
if (!$category || $category['model_id'] != Model::MODEL_ARTICLE) {
|
||||
return $this->error('错误页面');
|
||||
}
|
||||
|
||||
$description = $category['seo_description'] ?: $this->system['seo_description'];
|
||||
$keywords = $category['seo_keywords'] ?: $this->system['seo_keywords'];
|
||||
$title = $category['seo_title'] ?: $category['title'].' | '.$this->system['seo_title'];
|
||||
$this->setSeo($title, $keywords, $description);
|
||||
|
||||
// 自定义分页驱动
|
||||
app('think\App')->bind(Paginator::class, DxtcPageA::class);
|
||||
|
||||
|
||||
$this->data['items'] = MArticle::getList($categoryId,$category['number']??10);
|
||||
$this->data['category'] = $category;
|
||||
|
||||
$this->data['categoryId'] = $categoryId;
|
||||
$this->data['topCategoryId'] = Category::firstGradeById($category['id']) ;
|
||||
$this->data['bodyClass'] = 'main';
|
||||
|
||||
return $this->view($category['template_list'] ?? '/news_list');
|
||||
}
|
||||
|
||||
//文章列表接口,获取栏目下文章列表
|
||||
public function ajaxList()
|
||||
{
|
||||
$categoryId = input('category_id/d', 0);
|
||||
$keyword = input('keyword/s', '');
|
||||
$page = input('page/s', 1);
|
||||
|
||||
if ($categoryId <= 0) {
|
||||
return $this->json(1, '参数错误');
|
||||
}
|
||||
$category = Category::getById($categoryId);
|
||||
if (empty($category)) {
|
||||
return $this->json(2, '栏目不存在');
|
||||
}
|
||||
|
||||
$items = MArticle::findListByWhere(["category_id"=>$categoryId],$page, $category['number']);
|
||||
|
||||
foreach ($items as $item) {
|
||||
$item['uri'] = archiveGetUri($item);
|
||||
$item['create_date_d'] = date('d', $item['create_time']);
|
||||
$item['create_date_y_m'] = date('Y-m', $item['create_time']);
|
||||
}
|
||||
|
||||
return $this->json(0, 'ok', $items);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,122 @@
|
|||
<?php
|
||||
|
||||
namespace app\controller;
|
||||
|
||||
use app\model\Category;
|
||||
use app\model\ConfigSetting;
|
||||
use app\model\Link;
|
||||
use app\model\System;
|
||||
use app\model\VisitLogoModel;
|
||||
use think\response\Redirect;
|
||||
|
||||
/**
|
||||
* 控制器基础类
|
||||
*/
|
||||
class Base extends BaseController
|
||||
{
|
||||
//需要向模板传递的值
|
||||
protected $data = [];
|
||||
//系统配置信息
|
||||
protected $system = [];
|
||||
|
||||
// 初始化
|
||||
protected function initialize()
|
||||
{
|
||||
$this->system = System::getSystem();
|
||||
$this->data['system'] = $this->system;
|
||||
$this->data['links'] = Link::getList();
|
||||
if (session('?__token__')) {
|
||||
$this->data['_token'] = session('__token__');
|
||||
} else {
|
||||
$this->data['_token'] = $this->request->buildToken();
|
||||
}
|
||||
|
||||
$this->data['config'] = ConfigSetting::getConfigContentsByName('extraBase');
|
||||
|
||||
$this->nav();
|
||||
$this->logVisit();
|
||||
$this->setNofollowATagNames();
|
||||
}
|
||||
|
||||
//设置SEO信息
|
||||
protected function setSeo($title, $keywords = '', $description = '')
|
||||
{
|
||||
$this->data['seoTitle'] = $title;
|
||||
$this->data['seoKeywords'] = $keywords;
|
||||
$this->data['seoDescription'] = $description;
|
||||
}
|
||||
|
||||
//模板
|
||||
protected function view($template = '')
|
||||
{
|
||||
return view($template)->assign($this->data);
|
||||
}
|
||||
|
||||
public function setExtraBaseConfig()
|
||||
{
|
||||
$this->data['extraBase'] = ConfigSetting::getConfigContentsByName('extraBase');
|
||||
}
|
||||
|
||||
/*
|
||||
* 重构异常提示页面
|
||||
*/
|
||||
protected function error($msg = '', string $url = null, $data = [], int $code = 404): Redirect
|
||||
{
|
||||
switch ($code) {
|
||||
case 500:
|
||||
return $this->redirect('/500.html');
|
||||
default:
|
||||
return $this->redirect('/404.html');
|
||||
}
|
||||
}
|
||||
|
||||
// 记录访问日志
|
||||
protected function logVisit()
|
||||
{
|
||||
$referer = $_SERVER["HTTP_REFERER"] ?? '';
|
||||
$domain = $this->request->domain();
|
||||
$checkDomain = substr($referer, 0, strlen($domain));
|
||||
if (!empty($referer) && $domain !== $checkDomain) {
|
||||
// session('first_landing_page', $this->request->url(true));
|
||||
VisitLogoModel::create([
|
||||
'ip' => request()->ip(),
|
||||
'referer' => $referer,
|
||||
'visit' => $this->request->url(true),
|
||||
'create_time' => time(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
// HTML a标签设置 rel="nofollow" 属性,禁止搜索引擎追踪
|
||||
protected function setNofollowATagNames()
|
||||
{
|
||||
$this->data['nofollowList'] = [
|
||||
|
||||
];
|
||||
$this->data['footerAllowFollowList'] = [
|
||||
'客户案例', '公司新闻',
|
||||
];
|
||||
}
|
||||
|
||||
protected function nav()
|
||||
{
|
||||
$this->data['menus'] = Category::navList()['menus'];
|
||||
}
|
||||
|
||||
// 所有下级栏目ID
|
||||
private function getAllSubordinateIds($items, $curId = 0)
|
||||
{
|
||||
$list = [];
|
||||
foreach ($items as $k => $item) {
|
||||
if ($item['parent_id'] == $curId) {
|
||||
$list[] = $item['id'];
|
||||
unset($items[$k]);
|
||||
$childrenIds = $this->getAllSubordinateIds($items, $item['id']);
|
||||
if ($childrenIds) {
|
||||
$list = array_merge($list, $childrenIds);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $list;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,241 @@
|
|||
<?php
|
||||
declare (strict_types=1);
|
||||
|
||||
namespace app\controller;
|
||||
|
||||
use think\{App, Request, response\Json, response\Redirect, Validate};
|
||||
use Exception;
|
||||
use think\exception\ValidateException;
|
||||
|
||||
/**
|
||||
* 控制器基础类
|
||||
*/
|
||||
abstract class BaseController
|
||||
{
|
||||
/**
|
||||
* 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((string) url('error/jump', $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/jump', $result));
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回封装后的API数据到客户端
|
||||
* 以json格式抛出异常
|
||||
* @access protected
|
||||
* @param mixed $code 返回的code
|
||||
* @param mixed $msg 提示信息
|
||||
* @param mixed $data 要返回的数据
|
||||
* @return Json
|
||||
*/
|
||||
protected function json($code = 0, $msg = 'ok', $data = []): Json
|
||||
{
|
||||
$result = [
|
||||
'code' => $code,
|
||||
'msg' => $msg,
|
||||
'time' => time(),
|
||||
'data' => $data
|
||||
];
|
||||
return json($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* URL重定向
|
||||
* @access protected
|
||||
* @param mixed $url 跳转的URL表达式
|
||||
* @return Redirect
|
||||
*/
|
||||
protected function redirect($url): Redirect
|
||||
{
|
||||
if (!is_string($url)) {
|
||||
$url = $url->__toString();
|
||||
}
|
||||
return redirect($url);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
<?php
|
||||
|
||||
namespace app\controller;
|
||||
|
||||
use app\model\{DownloadModel, Category};
|
||||
use page\DxtcPageA;
|
||||
use think\Paginator;
|
||||
|
||||
class Download extends Base
|
||||
{
|
||||
//列表页
|
||||
public function index($categoryId = 0)
|
||||
{
|
||||
$rule = Category::RULE_DOWNLOAD;
|
||||
$categoryId = empty($categoryId) ? $this->request->param("category_id") : $categoryId;
|
||||
|
||||
$category = Category::getById($categoryId);
|
||||
|
||||
//没有category_id 则通过路由查询
|
||||
$category = $category ?: Category::getByRuleAlias($rule);
|
||||
|
||||
$description = $category['seo_description'] ?: $category['title'];
|
||||
$keywords = $category['seo_keywords'] ?: $category['title'];
|
||||
$title = $category['seo_title'] ?: $category['title'].' | '.$this->system['seo_title'];
|
||||
$this->setSeo($title, $keywords, $description);
|
||||
$listSort = ['a.sort' => 'desc'];
|
||||
|
||||
// 自定义分页驱动
|
||||
app('think\App')->bind(Paginator::class, DxtcPageA::class);
|
||||
|
||||
$items = DownloadModel::getList($category['id'], $category['number'], '', [], 1, $listSort, false);
|
||||
$items->each(function ($item) {
|
||||
$item->size_text = sizeToStr($item->size);
|
||||
});
|
||||
$this->data['items'] = $items;
|
||||
$this->data['category'] = $category;
|
||||
$this->data['categoryId'] = $category['id'];
|
||||
$this->data['bodyClass'] = 'main';
|
||||
|
||||
return $this->view();
|
||||
}
|
||||
|
||||
public function file()
|
||||
{
|
||||
$id = input('id');
|
||||
if (!$file = DownloadModel::getById($id)) {
|
||||
return $this->error('文件不存在');
|
||||
}
|
||||
|
||||
if (!file_exists(public_path().$file['file'])) {
|
||||
return $this->error('文件不存在');
|
||||
}
|
||||
return download(public_path().$file['file'], $file['title'].'.'.$file['suffix']);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
<?php
|
||||
namespace app\controller;
|
||||
|
||||
|
||||
use app\model\Category;
|
||||
use app\model\Model;
|
||||
use app\model\SpecialRoute;
|
||||
|
||||
class Error extends BaseController
|
||||
{
|
||||
protected $data = [];
|
||||
|
||||
public function __call($method, $args)
|
||||
{
|
||||
//特殊路径处理
|
||||
$specialRoute = SpecialRoute::findOneByUrl($this->request->baseUrl());
|
||||
if(!empty($specialRoute)){
|
||||
switch ($specialRoute["type"]){
|
||||
case SpecialRoute::type_archives:
|
||||
return action("article/detail",["id"=>$specialRoute->relation_id]);
|
||||
break;
|
||||
case SpecialRoute::type_archives_category:
|
||||
$category = Category::findInfoById($specialRoute->relation_id);
|
||||
if(empty($category)){
|
||||
break;
|
||||
}
|
||||
switch ($category->model_id){
|
||||
case Model::MODEL_PRODUCT:
|
||||
return action("product/index",["id"=>$specialRoute->relation_id]);
|
||||
break;
|
||||
case Model::MODEL_ARTICLE:
|
||||
return action("article/index",["categoryId"=>$specialRoute->relation_id]);
|
||||
break;
|
||||
case Model::MODEL_PAGE:
|
||||
return action("page/index",["categoryId"=>$specialRoute->relation_id]);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
$this->data['seoTitle'] = '404';
|
||||
return $this->redirect('/404.html');
|
||||
}
|
||||
|
||||
public function jump()
|
||||
{
|
||||
$param = request()->param();
|
||||
return view()->assign($param);
|
||||
}
|
||||
|
||||
// 404
|
||||
public function notFind()
|
||||
{
|
||||
$this->data['seoTitle'] = '404';
|
||||
return view('error/404')->assign($this->data);
|
||||
}
|
||||
|
||||
// 500
|
||||
public function serviceFail()
|
||||
{
|
||||
$this->data['seoTitle'] = '500';
|
||||
return view('error/500')->assign($this->data);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
<?php
|
||||
|
||||
namespace app\controller;
|
||||
|
||||
use app\model\{Article as MArticle, Category, Block, Message, Article, Slide};
|
||||
use Exception;
|
||||
use think\exception\ValidateException;
|
||||
use think\facade\View;
|
||||
use app\service\Tool;
|
||||
|
||||
class Index extends Base
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
$category = Category::getIndex();
|
||||
$categoryId = $category['id'] ?? 0;
|
||||
$blocks = Block::getByCategoryId($categoryId);
|
||||
|
||||
$this->news(5);
|
||||
$this->data['categoryId'] = $categoryId;
|
||||
$this->data['blocks'] = Block::convertValue($blocks);
|
||||
$this->data['category'] = $category;
|
||||
$this->data['topCategoryId'] = Category::firstGradeById($category['id']) ;
|
||||
$this->data['isIndex'] = true;
|
||||
$this->data['slide'] = Slide::getList();
|
||||
$this->setSeo($this->system['seo_title'], $this->system['seo_keywords'], $this->system['seo_description']);
|
||||
return $this->view();
|
||||
}
|
||||
|
||||
// 新闻动态
|
||||
private function news($num)
|
||||
{
|
||||
$this->data['newsList'] = MArticle::getIndexList(Category::CATEGORY_NEWS, $num);
|
||||
$topNews = MArticle::getIndexTop(Category::CATEGORY_NEWS);
|
||||
$this->data['topNews'] = $topNews;
|
||||
}
|
||||
|
||||
/**
|
||||
* 留言
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public function message()
|
||||
{
|
||||
if ($this->request->isPost()) {
|
||||
$item = input('item/a', [], 'strip_tags');
|
||||
$validate = $this->validateByApi($item, [
|
||||
'code|验证码' => 'require',
|
||||
'name|姓名' => 'require',
|
||||
'email|邮箱' => 'email',
|
||||
'tel|联系方式' => 'require|mobile',
|
||||
'content|留言内容' => 'require',
|
||||
]);
|
||||
if ($validate !== true) {
|
||||
return $validate;
|
||||
}
|
||||
|
||||
if (!captcha_check($item['code'])) {
|
||||
return $this->json(4001, '验证码错误');
|
||||
}
|
||||
|
||||
Message::create([
|
||||
'name' => $item['name'],
|
||||
'tel' => $item['tel'],
|
||||
'email' => $item['email'],
|
||||
'content' => $item['content'],
|
||||
'ip' => request()->ip(),
|
||||
'create_time' => time(),
|
||||
]);
|
||||
return $this->json();
|
||||
} else {
|
||||
return $this->json('请求错误');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
namespace app\controller;
|
||||
|
||||
use app\model\Link;
|
||||
use page\DxtcPageA;
|
||||
use think\Paginator;
|
||||
|
||||
/**
|
||||
* 友情链接
|
||||
*
|
||||
* Class Links
|
||||
* @package app\controller
|
||||
*/
|
||||
class Links extends Base
|
||||
{
|
||||
|
||||
public function index()
|
||||
{
|
||||
// 自定义分页驱动
|
||||
app('think\App')->bind(Paginator::class, DxtcPageA::class);
|
||||
$items = Link::getListWithPaginate([], 15);
|
||||
|
||||
$this->data['items'] = $items;
|
||||
|
||||
$this->setSeo('友情链接');
|
||||
return $this->view();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
<?php
|
||||
namespace app\controller;
|
||||
|
||||
|
||||
class Msg extends Base
|
||||
{
|
||||
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
<?php
|
||||
|
||||
namespace app\controller;
|
||||
|
||||
use app\model\{Category, Block, History, Honour, Model as MModel, Article as MArticle, PositionModel};
|
||||
use think\response\View;
|
||||
|
||||
class Page extends Base
|
||||
{
|
||||
/**
|
||||
* @return View|void
|
||||
*/
|
||||
public function index($categoryId=0)
|
||||
{
|
||||
$category = Category::getById($categoryId);
|
||||
if (!empty($category)) {
|
||||
$description = $category['seo_description'] ?: $this->system['seo_description'];
|
||||
$keywords = $category['seo_keywords'] ?: $this->system['seo_keywords'];
|
||||
$title = $category['seo_title'] ?: $category['title'].' | '.$this->system['seo_title'];
|
||||
$this->setSeo($title, $keywords, $description);
|
||||
} else {
|
||||
$this->redirect('/404.html');
|
||||
}
|
||||
$childCategory = Category::getChildrenByParentId($category['id']);
|
||||
$parentCategory = Category::getById($category['parent_id']);
|
||||
$brotherCategory = Category::getChildrenByParentId($category['parent_id']);
|
||||
$blocks = Block::getByCategoryId($category['id']);
|
||||
$blocks = Block::convertValue($blocks);
|
||||
|
||||
// 父级单页配置的公共信息
|
||||
$parentBlocks = [];
|
||||
if (!empty($parentCategory) && $parentCategory['model_id'] == MModel::MODEL_PAGE) {
|
||||
$parentBlocks = Block::getByCategoryId($parentCategory['id']);
|
||||
$parentBlocks = Block::convertValue($parentBlocks);
|
||||
}
|
||||
|
||||
$this->data['topCategoryId'] = Category::firstGradeById($category['id']) ;
|
||||
|
||||
$this->data['categoryId'] = $category['id'];
|
||||
$this->data['category'] = $category;
|
||||
$this->data['childCategory'] = $childCategory;
|
||||
$this->data['blocks'] = $blocks;
|
||||
$this->data['parentBlocks'] = $parentBlocks;
|
||||
$this->data['parentCategory'] = $parentCategory;
|
||||
$this->data['brotherCategory'] = $brotherCategory;
|
||||
$this->data['bodyClass'] = 'main';
|
||||
$this->setExtraBaseConfig();
|
||||
|
||||
return $this->view($category['template_detail']);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
<?php
|
||||
|
||||
namespace app\controller;
|
||||
|
||||
use app\model\{Block, Category, PositionModel};
|
||||
|
||||
use think\Paginator;
|
||||
|
||||
class Position extends Base
|
||||
{
|
||||
|
||||
//详情
|
||||
public function detail($id = 0)
|
||||
{
|
||||
if ($id <= 0) {
|
||||
return $this->error('错误页面');
|
||||
}
|
||||
$article = PositionModel::getById($id);
|
||||
if (empty($article)) {
|
||||
return $this->error('无此内容');
|
||||
}
|
||||
|
||||
|
||||
$category = Category::getById($article['category_id']);
|
||||
|
||||
$description = $category['seo_description'] ?: $this->system['seo_description'];
|
||||
$keywords = $category['seo_keywords'] ?: $this->system['seo_keywords'];
|
||||
$title = $category['seo_title'] ?: $category['title'].' | '.$this->system['seo_title'];
|
||||
|
||||
$this->setSeo($title, $keywords, $description);
|
||||
|
||||
$this->data['item'] = $article;
|
||||
$this->data['category'] = $category;
|
||||
$blocks = Block::getByCategoryId($category['id']);
|
||||
$blocks = Block::convertValue($blocks);
|
||||
$this->data['blocks'] = $blocks;
|
||||
$this->data['categoryId'] = $category['id'];
|
||||
$this->data['topCategoryId'] = Category::firstGradeById($category['id']) ;
|
||||
return $this->view('/article/joindata');
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,131 @@
|
|||
<?php
|
||||
|
||||
namespace app\controller;
|
||||
|
||||
use app\model\{ProductModel,
|
||||
Category,
|
||||
Model
|
||||
};
|
||||
use page\DxtcPageA;
|
||||
use think\db\exception\DataNotFoundException;
|
||||
use think\db\exception\DbException;
|
||||
use think\db\exception\ModelNotFoundException;
|
||||
use think\Paginator;
|
||||
|
||||
class Product extends Base
|
||||
{
|
||||
//详情
|
||||
public function detail($id = 0)
|
||||
{
|
||||
if ($id <= 0) {
|
||||
return $this->error('错误页面');
|
||||
}
|
||||
$article = ProductModel::getById($id);
|
||||
if (empty($article)) {
|
||||
return $this->error('无此产品');
|
||||
}
|
||||
|
||||
$category = Category::getById($article['category_id']);
|
||||
|
||||
$description = $article['seo_description'] ?: $this->system['seo_description'];
|
||||
$keywords = $article['seo_keywords'] ?: $this->system['seo_keywords'];
|
||||
$title = $article['seo_title'] ?: $article['title'].' | '.$this->system['seo_title'];
|
||||
|
||||
$pathArr = explode(',', $category['path']);
|
||||
$secondCategoryId = $pathArr[3] ?: $article['category_id'];
|
||||
$secondCategory = Category::getById($secondCategoryId);
|
||||
|
||||
$this->data['images'] = json_decode($article['images'], true);
|
||||
|
||||
// 相关推荐
|
||||
$recommendList = $this->recommendList($article, 3);
|
||||
|
||||
$this->data['recommendList'] = $recommendList;
|
||||
$this->setSeo($title, $keywords, $description);
|
||||
$this->data['item'] = $article;
|
||||
$this->data['category'] = $category;
|
||||
$this->data['secondInfo'] = $secondCategory;
|
||||
$this->data['categoryId'] = $category['id'];
|
||||
$this->data['topCategoryId'] = Category::firstGradeById($category['id']) ;
|
||||
return $this->view($category['template_detail'] ?? '');
|
||||
}
|
||||
|
||||
/**
|
||||
* 相关推荐
|
||||
*
|
||||
* @param $article
|
||||
* @param $num
|
||||
* @return array
|
||||
* @throws DataNotFoundException
|
||||
* @throws DbException
|
||||
* @throws ModelNotFoundException
|
||||
*/
|
||||
private function recommendList($article, $num)
|
||||
{
|
||||
return ProductModel::where('category_id', $article['category_id'])
|
||||
->where('visible', 1)
|
||||
->order('sort', 'desc')
|
||||
->order('id', 'desc')
|
||||
->limit($num)
|
||||
->select()->toArray();
|
||||
}
|
||||
|
||||
//列表页
|
||||
public function index()
|
||||
{
|
||||
$second = input('second/d', 0);
|
||||
$third = input('third/d', 0);
|
||||
|
||||
$first = Category::getByRuleAlias(Category::RULE_PRODUCT);//产品顶级分类
|
||||
$categoryList = Category::getChildrenByParentId($first['id'], false);
|
||||
$secondMenus = [];
|
||||
$secondChildren = [];
|
||||
foreach ($categoryList as $k => $cate) {
|
||||
if ($cate['parent_id'] == $first['id']) {
|
||||
$secondMenus[$cate['id']] = $cate;
|
||||
unset($categoryList[$k]);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($categoryList as $thirdCate) {
|
||||
foreach ($secondMenus as $secondCate) {
|
||||
if (!isset($secondChildren[$secondCate['id']])) {
|
||||
$secondChildren[$secondCate['id']] = [];
|
||||
}
|
||||
if ($thirdCate['parent_id'] == $secondCate['id']) {
|
||||
$secondChildren[$secondCate['id']][] = $thirdCate;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$secondInfo = $second == 0 ? array_values($secondMenus)[0] : $secondMenus[$second];
|
||||
$thirdMenus = $secondChildren[$secondInfo['id']];
|
||||
|
||||
$this->data['thirdId'] = $third;
|
||||
|
||||
|
||||
$description = $first['seo_description'] ?: $this->system['seo_description'];
|
||||
$keywords = $first['seo_keywords'] ?: $this->system['seo_keywords'];
|
||||
$title = $first['seo_title'] ?: $first['title'].' | '.$this->system['seo_title'];
|
||||
$this->setSeo($title, $keywords, $description);
|
||||
$listSort = ['a.sort' => 'desc'];
|
||||
|
||||
$this->data['secondInfo'] = $secondInfo;
|
||||
$this->data['secondMenus'] = $secondMenus;
|
||||
$this->data['thirdMenus'] = $thirdMenus;
|
||||
|
||||
// 自定义分页驱动
|
||||
app('think\App')->bind(Paginator::class, DxtcPageA::class);
|
||||
|
||||
$cateId = $third > 0 ? $third : $secondInfo['id'];
|
||||
$queryParam = ['second' => $secondInfo['id'], 'third' => $third];
|
||||
$items = ProductModel::getList($cateId, $first['number'], '', [], 1, $listSort, false, $queryParam);
|
||||
|
||||
$this->data['items'] = $items;
|
||||
$this->data['category'] = $first;
|
||||
$this->data['categoryId'] = $first['id'];
|
||||
$this->data['bodyClass'] = 'main';
|
||||
$this->data['topCategoryId'] = Category::firstGradeById($first['id']) ;
|
||||
return $this->view();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
<?php
|
||||
|
||||
namespace app\controller;
|
||||
|
||||
use app\model\{Category, ProductModel};
|
||||
use page\DxtcPageA;
|
||||
use think\Paginator;
|
||||
|
||||
class Search extends Base
|
||||
{
|
||||
//列表页
|
||||
public function index()
|
||||
{
|
||||
$type = input('type/s', 'product');
|
||||
if (!in_array($type, ['product', 'news', 'scheme'])) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$keyword = input('keyword/s', '');
|
||||
|
||||
if (empty($keyword)) {
|
||||
return $this->error('请输入搜索关键词');
|
||||
}
|
||||
|
||||
// 自定义分页驱动
|
||||
app('think\App')->bind(Paginator::class, DxtcPageA::class);
|
||||
|
||||
$items = [];
|
||||
$paginate = [
|
||||
'list_rows' => 20,
|
||||
'query' => ['keyword' => $keyword, 'type' => $type]
|
||||
];
|
||||
$orderList = ['sort' => 'desc', 'id' => 'desc'];
|
||||
$path = '';
|
||||
switch ($type) {
|
||||
case 'product':
|
||||
$items = ProductModel::where('title|description|content|params', 'like', '%'.$keyword.'%')
|
||||
->where('visible', 1)
|
||||
->order($orderList)
|
||||
->paginate($paginate);
|
||||
$path = '/product/detail.html';
|
||||
break;
|
||||
case 'news':
|
||||
$categoryIds = Category::where('template_list', Category::TEMPLATE_NEWS)->column('id');
|
||||
$items = \app\model\Article::where('title|summary|content', 'like', '%'.$keyword.'%')
|
||||
->whereIn('category_id', $categoryIds)
|
||||
->where('status', 1)
|
||||
->order($orderList)
|
||||
->paginate($paginate);
|
||||
$path = '/news/detail.html';
|
||||
break;
|
||||
case 'scheme':
|
||||
$categoryIds = Category::where('template_list', Category::TEMPLATE_SCHEME)->column('id');
|
||||
$items = \app\model\Article::where('title|summary|content', 'like', '%'.$keyword.'%')
|
||||
->whereIn('category_id', $categoryIds)
|
||||
->where('status', 1)
|
||||
->order($orderList)
|
||||
->paginate($paginate);
|
||||
$path = '/scheme/detail.html';
|
||||
break;
|
||||
}
|
||||
|
||||
$this->data['items'] = $items;
|
||||
$this->data['bodyClass'] = 'main';
|
||||
$this->data['type'] = $type;
|
||||
$this->data['keyword'] = $keyword;
|
||||
$this->data['path'] = $path;
|
||||
|
||||
return $this->view();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
namespace app\controller;
|
||||
|
||||
use app\controller\manager\Upload as MUpload;
|
||||
|
||||
class Upload extends MUpload
|
||||
{
|
||||
|
||||
}
|
|
@ -0,0 +1,506 @@
|
|||
<?php
|
||||
|
||||
namespace app\controller\manager;
|
||||
|
||||
use app\model\{Article as MArticle, ArticleTags, Category, SpecialRoute, System, Log};
|
||||
use app\validate\Article as VArticle;
|
||||
use think\exception\ValidateException;
|
||||
use app\service\Tool;
|
||||
use think\facade\Db;
|
||||
|
||||
/**
|
||||
* 内容管理 - 文章管理
|
||||
*/
|
||||
class Article extends Base
|
||||
{
|
||||
// 允许设置组图的模版列表
|
||||
protected $allowImgTemplate = [
|
||||
Category::TEMPLATE_CASES,
|
||||
];
|
||||
|
||||
|
||||
//批量修改属性
|
||||
public function attribute()
|
||||
{
|
||||
if ($this->request->isPost()) {
|
||||
$ids = input('post.id/a');
|
||||
if (empty($ids) || !is_array($ids)) {
|
||||
return $this->json(2, '参数错误,请核对之后再操作!');
|
||||
}
|
||||
$data = [];
|
||||
foreach (['top', 'hot', 'recommend'] as $key) {
|
||||
$val = input('post.'.$key, 0);
|
||||
if (in_array($val, [1, 2])) {
|
||||
if ($val == 1) {
|
||||
$data[$key] = 1;
|
||||
} else {
|
||||
$data[$key] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!empty($data)) {
|
||||
MArticle::whereIn('id', $ids)->update($data);
|
||||
Log::write('article', 'attribute', '批量修改了文章属性,涉及到的文章ID为:'.implode(',', $ids));
|
||||
}
|
||||
return $this->json();
|
||||
}
|
||||
return $this->json(1, '非法请求!');
|
||||
}
|
||||
|
||||
//批量删除
|
||||
public function batchDel()
|
||||
{
|
||||
if ($this->request->isPost()) {
|
||||
$ids = input('post.ids/a');
|
||||
if (empty($ids) || !is_array($ids)) {
|
||||
return $this->json(2, '参数错误,请核对之后再操作!');
|
||||
}
|
||||
$items = MArticle::getListByIds($ids);
|
||||
if (empty($items)) {
|
||||
return $this->json(3, '待删除文章列表为空');
|
||||
}
|
||||
|
||||
Db::startTrans();
|
||||
try {
|
||||
$delIds = [];
|
||||
$cateId = $items[0]['category_id'];
|
||||
foreach ($items as $item) {
|
||||
$delIds[] = $item['id'];
|
||||
}
|
||||
|
||||
MArticle::destroy($delIds);
|
||||
SpecialRoute::deleteByTypeIds($delIds ,SpecialRoute::type_archives);
|
||||
Log::write('article', 'betchDel', '批量删除了文章,涉及到的文章ID为:'.implode(',', $delIds));
|
||||
Db::commit();
|
||||
} catch (\Exception $e) {
|
||||
Db::rollback();
|
||||
return $this->json(5000, '文章删除失败!');
|
||||
}
|
||||
|
||||
return $this->json();
|
||||
}
|
||||
return $this->json(1, '非法请求!');
|
||||
}
|
||||
|
||||
//删除
|
||||
public function del()
|
||||
{
|
||||
if ($this->request->isPost()) {
|
||||
$id = input('post.id/d');
|
||||
if (is_numeric($id) && $id > 0) {
|
||||
$item = MArticle::getById($id);
|
||||
if (empty($item)) {
|
||||
return $this->json(3, '待删除文章不存在');
|
||||
}
|
||||
|
||||
Db::startTrans();
|
||||
try {
|
||||
MArticle::destroy($id);
|
||||
Log::write('article', 'del', '删除文章,ID:'.$id.',标题:'.$item['title']);
|
||||
SpecialRoute::deleteByTypeIds([$id] ,SpecialRoute::type_archives);
|
||||
Db::commit();
|
||||
} catch (\Exception $e) {
|
||||
Db::rollback();
|
||||
return $this->json(5000, '文章删除失败!');
|
||||
}
|
||||
return $this->json();
|
||||
}
|
||||
|
||||
return $this->json(2, '参数错误,请核对之后再操作!');
|
||||
}
|
||||
return $this->json(1, '非法请求!');
|
||||
}
|
||||
|
||||
//排序
|
||||
public function sort()
|
||||
{
|
||||
if ($this->request->isPost()) {
|
||||
$id = input('post.id/d');
|
||||
$sort = input('post.sort');
|
||||
$num = input('post.num/d', 1);
|
||||
$categoryId = $this->request->param('category_id/d', 0); // get | post
|
||||
if ($num <= 0) {
|
||||
$num = 1;
|
||||
}
|
||||
if (!in_array($sort, ['up', 'down'], true)) {
|
||||
return $this->json(2, '参数错误');
|
||||
}
|
||||
$item = MArticle::getById($id);
|
||||
if (empty($item)) {
|
||||
return $this->json(3, '该文章信息不存在');
|
||||
}
|
||||
$whereMap = [];
|
||||
if (is_numeric($categoryId) && $categoryId > 0) {
|
||||
$children = Category::getChildrenByParentId($categoryId);
|
||||
if (!empty($children)) {
|
||||
$childrenIds = [];
|
||||
foreach ($children as $child) {
|
||||
if ($child['model_id'] == 31) {
|
||||
$childrenIds[] = $child['id'];
|
||||
}
|
||||
}
|
||||
$whereMap[] = ['category_id', 'in', $childrenIds];
|
||||
} else {
|
||||
$whereMap[] = ['category_id', '=', $categoryId];
|
||||
}
|
||||
} else {
|
||||
$whereMap[] = ['category_id', '=', $item['category_id']];
|
||||
}
|
||||
|
||||
if ($sort == 'up') {
|
||||
$whereMap[] = ['sort', '>', $item['sort']];
|
||||
$order = "sort asc";
|
||||
} else {
|
||||
$whereMap[] = ['sort', '<', $item['sort']];
|
||||
$order = "sort desc";
|
||||
}
|
||||
$forSortItems = MArticle::getListByWhereAndOrder($whereMap, $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 MArticle();
|
||||
$model->saveAll($updateData);
|
||||
$sortStr = $sort == 'up' ? '上移' : '下调';
|
||||
Log::write('article', 'sort', "文章排序,ID:{$id} ,标题:{$item['title']},{$sortStr}了{$num}位");
|
||||
return $this->json();
|
||||
}
|
||||
}
|
||||
return $this->json(4, '无须调整排序!');
|
||||
}
|
||||
return $this->json(1, '非法请求!');
|
||||
}
|
||||
|
||||
//编辑
|
||||
public function edit()
|
||||
{
|
||||
if ($this->request->isPost()) {
|
||||
$item = input('post.item/a');
|
||||
$img = input('post.img', '');
|
||||
$logo = input('post.img_logo', '');
|
||||
$banner = input('post.img_banner', '');
|
||||
$video = input('post.video', '');
|
||||
$id = input('post.id/d');
|
||||
$article = MArticle::getById($id);
|
||||
if (empty($article)) {
|
||||
return $this->json(1, '该文章不存在!');
|
||||
}
|
||||
$item['src'] = $img;
|
||||
if (!empty($logo)) {
|
||||
$item['logo'] = $logo;
|
||||
}
|
||||
if (!empty($banner)) {
|
||||
$item['banner'] = $banner;
|
||||
}
|
||||
$item['video'] = $video;
|
||||
|
||||
try {
|
||||
validate(VArticle::class)->scene("edit")->check($item);
|
||||
$auth = session('auth');
|
||||
$item['update_time'] = time();
|
||||
$item['updated'] = $auth['userName'];
|
||||
|
||||
cache('articlesForRoute', null); //清理缓存
|
||||
|
||||
// 默认属性
|
||||
$defaultAttributes = ['recommend', 'top', 'hot'];
|
||||
$item['recommend'] = $item['recommend'] ?? 0;
|
||||
$item['top'] = $item['top'] ?? 0;
|
||||
$item['hot'] = $item['hot'] ?? 0;
|
||||
|
||||
// 自定义属性配置(包含默认属性)
|
||||
$recommendOtherNameStr = input('post.recommend_other_str/s', '');
|
||||
$recommendOtherList = [];
|
||||
if (!empty($recommendOtherNameStr)) {
|
||||
$recommendOtherNameList = explode(',', $recommendOtherNameStr);
|
||||
$attributeList = MArticle::getAttributeList([$article['category_id']]);
|
||||
$attributeKeyList = array_flip($attributeList);
|
||||
|
||||
foreach ($recommendOtherNameList as $recommendOtherName) {
|
||||
$attributeKey = $attributeKeyList[$recommendOtherName] ?? '';
|
||||
if (!empty($attributeKey)) {
|
||||
$recommendOtherList[] = $attributeKey;
|
||||
|
||||
// 默认属性配置,适用于排序
|
||||
if (in_array($attributeKey, $defaultAttributes)) {
|
||||
$item[$attributeKey] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$item['recommend_other'] = empty($recommendOtherList) ? '' : implode(',', $recommendOtherList);
|
||||
|
||||
// 标签
|
||||
$item['tag'] = trim($item['tag'] ?? '');
|
||||
$item['tag'] = str_replace(',', ',', $item['tag']);
|
||||
if (!empty($tagSaveCheck) && ($article['status'] == MArticle::STATUS_NORMAL || $item['status'] == MArticle::STATUS_NORMAL)) {
|
||||
$oldTagList = empty($article['tag']) ? [] : explode(',', $article['tag']);
|
||||
$curTagList = empty($item['tag']) ? [] : explode(',', $item['tag']);
|
||||
/**
|
||||
* $oldTagList 差集:total - 1
|
||||
* $curTagList 差集:不存在则新增,存在则total + 1
|
||||
* [normal->disable] total - 1
|
||||
* [disable->normal] total + 1
|
||||
*/
|
||||
if ($article['status'] != $item['status']) {
|
||||
if ($article['status'] == MArticle::STATUS_NORMAL) {
|
||||
$curTagList = [];
|
||||
} else {
|
||||
$oldTagList = [];
|
||||
}
|
||||
}
|
||||
|
||||
$oldTagsDiff = array_diff($oldTagList, $curTagList);
|
||||
$curTagsDiff = array_diff($curTagList, $oldTagList);
|
||||
if (count($oldTagsDiff) > 0) {
|
||||
ArticleTags::whereIn('name', $oldTagsDiff)
|
||||
->where($tagSaveCheck, '>', 0)
|
||||
->dec($tagSaveCheck, 1)
|
||||
->update();
|
||||
}
|
||||
if (count($curTagsDiff) > 0) {
|
||||
$hadTagItems = ArticleTags::findByNames($curTagsDiff);
|
||||
$hadTags = $hadTagItems->column('name');
|
||||
$newTags = array_diff($curTagsDiff, $hadTags);
|
||||
|
||||
$tagsInsert = [];
|
||||
$tagsUpdate = [];
|
||||
foreach ($newTags as $tagName) {
|
||||
$tagsInsert[] = [
|
||||
'name' => $tagName,
|
||||
$tagSaveCheck => 1
|
||||
];
|
||||
}
|
||||
foreach ($hadTagItems as $tagItem) {
|
||||
$tagsUpdate[] = [
|
||||
'id' => $tagItem['id'],
|
||||
$tagSaveCheck => $tagItem[$tagSaveCheck] + 1
|
||||
];
|
||||
}
|
||||
|
||||
if (count($tagsInsert) > 0) {
|
||||
ArticleTags::insertAll($tagsInsert);
|
||||
}
|
||||
if (count($tagsUpdate) > 0) {
|
||||
(new ArticleTags())->saveAll($tagsUpdate);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
MArticle::updateById($id, $item);
|
||||
|
||||
//处理特殊路由
|
||||
if (array_key_exists("route", $item) && !empty($item['route'])) {
|
||||
$specialRoute = SpecialRoute::findByTypeRelaTioneId($id,SpecialRoute::type_archives);
|
||||
if(empty($specialRoute)){
|
||||
$specialRouteData = [
|
||||
"route" =>$item["route"]??'',
|
||||
"type" =>SpecialRoute::type_archives,
|
||||
"relation_id" =>$id,
|
||||
];
|
||||
SpecialRoute::create($specialRouteData);
|
||||
}else{
|
||||
$specialRoute->save(["route"=>$item["route"]??'']);
|
||||
}
|
||||
}else{
|
||||
SpecialRoute::deleteByTypeIds([$id],SpecialRoute::type_archives);
|
||||
}
|
||||
|
||||
Db::commit();
|
||||
Log::write('article', 'edit', "文章编辑,ID:{$id} ,标题:{$item['title']}");
|
||||
return $this->json();
|
||||
}
|
||||
catch (ValidateException $e) {
|
||||
Db::rollback();
|
||||
return $this->json(2, $e->getError());
|
||||
}catch (\Exception $e) {
|
||||
Db::rollback();
|
||||
return $this->json(3, $e->getMessage());
|
||||
}
|
||||
} else {
|
||||
$id = input('param.id');
|
||||
$article = MArticle::getById($id);
|
||||
$category = [];
|
||||
$categoryId = $article['category_id'] ?? 0;
|
||||
$imgSize = '';
|
||||
$attributeList = [];
|
||||
|
||||
if ($article) {
|
||||
$article = MArticle::convertRecommendOther([$categoryId], $article, false);
|
||||
$attributeList = MArticle::getAttributeList([$categoryId]);
|
||||
|
||||
$category = Category::getById($categoryId);
|
||||
if ($category['img_width'] && $category['img_height']) {
|
||||
$imgSize = $category['img_width'].'像素 X '.$category['img_height'].'像素';
|
||||
} else {
|
||||
$imgSize = System::getArticleImageSize();
|
||||
}
|
||||
}
|
||||
|
||||
$this->data['item'] = $article;
|
||||
$this->data['category'] = $category;
|
||||
$this->data['imgSize'] = $imgSize;
|
||||
$this->data['attributeList'] = $attributeList;
|
||||
$this->data['contentRaw'] = in_array($categoryId, Category::$contentRawCategoryList);
|
||||
$this->data['allowTag'] = in_array($categoryId, Category::$allowTagCategoryList);
|
||||
$this->data['allowImgs'] = in_array($category['template_list'], $this->allowImgTemplate);
|
||||
|
||||
return $this->view();
|
||||
}
|
||||
}
|
||||
|
||||
//添加
|
||||
public function add()
|
||||
{
|
||||
if ($this->request->isPost()) {
|
||||
$item = input('post.item/a');
|
||||
$img = input('post.img', '');
|
||||
$logo = input('post.img_logo', '');
|
||||
$banner = input('post.img_banner', '');
|
||||
$video = input('post.video', '');
|
||||
|
||||
$item['src'] = $img;
|
||||
if (!empty($logo)) {
|
||||
$item['logo'] = $logo;
|
||||
}
|
||||
|
||||
if (!empty($banner)) {
|
||||
$item['banner'] = $banner;
|
||||
}
|
||||
$item['video'] = $video;
|
||||
Db::startTrans();
|
||||
try {
|
||||
validate(VArticle::class)->scene("add")->check($item);
|
||||
$content = $item['content'] ?? '';
|
||||
if (isset($item['content'])) {
|
||||
unset($item['content']);
|
||||
}
|
||||
$item['content'] = $content;
|
||||
if (!empty($item['alias'])) {
|
||||
if (Tool::hasAlias($item['alias'])) {
|
||||
throw new ValidateException('别名已存在');
|
||||
}
|
||||
cache('articlesForRoute', null); //有别名时,清理缓存
|
||||
}
|
||||
|
||||
// 默认属性
|
||||
$defaultAttributes = ['recommend', 'top', 'hot'];
|
||||
$item['recommend'] = $item['recommend'] ?? 0;
|
||||
$item['top'] = $item['top'] ?? 0;
|
||||
$item['hot'] = $item['hot'] ?? 0;
|
||||
|
||||
// 自定义属性配置
|
||||
$recommendOtherNameStr = input('post.recommend_other_str', '');
|
||||
$recommendOtherList = [];
|
||||
if (!empty($recommendOtherNameStr)) {
|
||||
$recommendOtherNameList = explode(',', $recommendOtherNameStr);
|
||||
$attributeList = MArticle::getAttributeList([$item['category_id']]);
|
||||
$attributeKeyList = array_flip($attributeList);
|
||||
|
||||
foreach ($recommendOtherNameList as $recommendOtherName) {
|
||||
$attributeKey = $attributeKeyList[$recommendOtherName] ?? '';
|
||||
if (!empty($attributeKey)) {
|
||||
$recommendOtherList[] = $attributeKey;
|
||||
|
||||
// 默认属性配置,适用于排序
|
||||
if (in_array($attributeKey, $defaultAttributes)) {
|
||||
$item[$attributeKey] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$item['recommend_other'] = empty($recommendOtherList) ? '' : implode(',', $recommendOtherList);
|
||||
|
||||
// 标签
|
||||
$item['tag'] = trim($item['tag'] ?? '');
|
||||
$item['tag'] = str_replace(',', ',', $item['tag']);
|
||||
if (!empty($item['tag']) && !empty($tagSaveCheck) && $item['status'] == MArticle::STATUS_NORMAL) {
|
||||
$curTags = explode(',', $item['tag']);
|
||||
$tagItems = ArticleTags::findByNames($curTags);
|
||||
$hadTags = $tagItems->column('name');
|
||||
$newTags = array_diff($curTags, $hadTags);
|
||||
if (count($newTags) > 0) {
|
||||
$tagsInsert = [];
|
||||
$tagsUpdate = [];
|
||||
foreach ($newTags as $tag) {
|
||||
$tagsInsert[] = [
|
||||
'name' => $tag,
|
||||
$tagSaveCheck => 1
|
||||
];
|
||||
}
|
||||
foreach ($tagItems as $tagItem) {
|
||||
$tagsUpdate[] = [
|
||||
'id' => $tagItem['id'],
|
||||
$tagSaveCheck => $tagItem[$tagSaveCheck] + 1,
|
||||
];
|
||||
}
|
||||
|
||||
if (count($tagsInsert) > 0) {
|
||||
ArticleTags::insertAll($tagsInsert);
|
||||
}
|
||||
if (count($tagsUpdate)) {
|
||||
(new ArticleTags())->saveAll($tagsUpdate);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$article = MArticle::create($item);
|
||||
//处理特殊路由
|
||||
if (array_key_exists("route", $item) && !empty($item['route'])) {
|
||||
$specialRouteData = [
|
||||
"route" =>$item["route"]??'',
|
||||
"type" =>SpecialRoute::type_archives,
|
||||
"relation_id" =>$article->id,
|
||||
];
|
||||
SpecialRoute::create($specialRouteData);
|
||||
}
|
||||
Log::write('article', 'add', "文章新增,ID:{$article->id} ,标题:{$item['title']}");
|
||||
Db::commit();
|
||||
return $this->json();
|
||||
} catch (ValidateException $e) {
|
||||
Db::rollback();
|
||||
return $this->json(2, $e->getError());
|
||||
} catch (\Exception $e) {
|
||||
Db::rollback();
|
||||
return $this->json(2, 'request fail! '.$e->getMessage());
|
||||
}
|
||||
} else {
|
||||
$categoryId = input('param.category_id');
|
||||
$category = Category::getById($categoryId);
|
||||
if (count($category) > 0 && $category['img_width'] && $category['img_height']) {
|
||||
$imgSize = $category['img_width'].'像素 X '.$category['img_height'].'像素';
|
||||
} else {
|
||||
$imgSize = System::getArticleImageSize();
|
||||
}
|
||||
|
||||
$this->data['category'] = $category;
|
||||
$this->data['imgSize'] = $imgSize;
|
||||
$this->data['attributeList'] = MArticle::getAttributeList([$categoryId]);
|
||||
$this->data['contentRaw'] = in_array($categoryId, Category::$contentRawCategoryList);
|
||||
$this->data['allowTag'] = in_array($categoryId, Category::$allowTagCategoryList);
|
||||
$this->data['allowImgs'] = in_array($category['template_list'], $this->allowImgTemplate);
|
||||
|
||||
return $this->view();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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,89 @@
|
|||
<?php
|
||||
|
||||
namespace app\controller\manager;
|
||||
|
||||
use app\controller\BaseController;
|
||||
use PhpOffice\PhpSpreadsheet\Style\Alignment;
|
||||
use PhpOffice\PhpSpreadsheet\Style\Border;
|
||||
use think\response\Redirect;
|
||||
|
||||
/**
|
||||
* 控制器基础类
|
||||
*/
|
||||
class Base extends BaseController
|
||||
{
|
||||
// excel 导出格式配置
|
||||
protected $excelStyle = [
|
||||
'font' => [
|
||||
'name' => '宋体',
|
||||
],
|
||||
'alignment' => [
|
||||
'horizontal' => Alignment::HORIZONTAL_CENTER, // 水平居中
|
||||
'vertical' => Alignment::VERTICAL_CENTER, // 垂直居中
|
||||
'wrapText' => true,
|
||||
],
|
||||
'borders' => [
|
||||
'allBorders' => [
|
||||
'borderStyle' => Border::BORDER_THIN,
|
||||
'color' => ['rgb' => 'eeeeee'],
|
||||
]
|
||||
],
|
||||
];
|
||||
|
||||
protected $defaultSetting = [
|
||||
'cell_width' => 30,
|
||||
'font_size' => 12
|
||||
];
|
||||
|
||||
protected $data = [];
|
||||
|
||||
|
||||
protected function initialize()
|
||||
{
|
||||
$this->middleware = [
|
||||
//'csrf',
|
||||
'auth' => [
|
||||
'except' => ['manager.login/index']
|
||||
]
|
||||
];
|
||||
$auth = session('auth');
|
||||
$this->data['member'] = $auth;
|
||||
if (session('?__token__')) {
|
||||
$this->data['_token'] = session('__token__');
|
||||
} else {
|
||||
$this->data['_token'] = $this->request->buildToken();
|
||||
}
|
||||
$this->data['groupId'] = $auth['groupId'] ?? 0;
|
||||
}
|
||||
|
||||
//变量赋值到模板
|
||||
protected function view()
|
||||
{
|
||||
return view()->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));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,327 @@
|
|||
<?php
|
||||
namespace app\controller\manager;
|
||||
|
||||
use app\model\{Category as MCategory, Model as MCModel, Log, SpecialRoute};
|
||||
use app\validate\Category as VCategory;
|
||||
use think\facade\Db;
|
||||
use think\Exception;
|
||||
use think\exception\ValidateException;
|
||||
use think\facade\Cache;
|
||||
use app\service\Tool;
|
||||
|
||||
class Category extends Base
|
||||
{
|
||||
//栏目列表
|
||||
public function index()
|
||||
{
|
||||
$auth = session('auth');
|
||||
$authCates = array_filter(explode(',', $auth['cates']));
|
||||
if ($auth['groupId'] == 1) {
|
||||
$cates = MCategory::getList();
|
||||
} else {
|
||||
$cates = MCategory::getList(true, $authCates);
|
||||
}
|
||||
$items = MCategory::getCates($cates);
|
||||
|
||||
$powerAdd = false;
|
||||
$ruleNames = Cache::get('rule_names_'.$auth['groupId']);
|
||||
if (is_array($ruleNames) && in_array('category/add', $ruleNames, true)) {
|
||||
$powerAdd = true;
|
||||
}
|
||||
|
||||
$this->data['items'] = $items;
|
||||
$this->data['power_add'] = $powerAdd;
|
||||
return $this->view();
|
||||
}
|
||||
|
||||
//批量删除
|
||||
public function batchDel()
|
||||
{
|
||||
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, '无效请求,参数错误!');
|
||||
}
|
||||
if (MCategory::hasChildren($idsArr)) {
|
||||
return $this->json(2, '需删除的栏目下存在下级栏目,不可删除。请检查核实后再操作!');
|
||||
}
|
||||
$categories = MCategory::getListByIds($idsArr);
|
||||
if(!empty($categories)){
|
||||
$hasIds = [];
|
||||
foreach($categories as $cate){
|
||||
$hasIds[] = $cate['id'];
|
||||
}
|
||||
MCategory::destroy($hasIds);
|
||||
Cache::delete("categoryNames");
|
||||
SpecialRoute::deleteByTypeIds($hasIds ,SpecialRoute::type_archives_category);
|
||||
Log::write('category', 'betchDel', '批量删除了栏目,涉及到的ID为:' . implode(',', $hasIds));
|
||||
return $this->json();
|
||||
}
|
||||
return $this->json(3, '删除失败!栏目不存在,请刷新页面后再试!');
|
||||
}
|
||||
return $this->json(1, '非法请求!');
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除
|
||||
*/
|
||||
public function del()
|
||||
{
|
||||
if($this->request->isPost()){
|
||||
$id = input('post.id/d');
|
||||
if(is_numeric($id) && $id > 0) {
|
||||
if(MCategory::hasChildren($id)){
|
||||
return $this->json(4, '此栏目有下级栏目,不可删除。请检查核实后再操作!');
|
||||
}
|
||||
$cate = MCategory::getById($id);
|
||||
if(!empty($cate)){
|
||||
MCategory::destroy($id);
|
||||
Cache::delete("categoryNames");
|
||||
SpecialRoute::deleteByTypeIds([$id] ,SpecialRoute::type_archives_category);
|
||||
Log::write('category', 'del', '删除栏目,ID:' . $id . ',标题:' . $cate['title']);
|
||||
return $this->json();
|
||||
}
|
||||
return $this->json(3, '删除失败!栏目不存在,请刷新页面后再试!');
|
||||
} else {
|
||||
return $this->json(2, '无效请求,参数错误!');
|
||||
}
|
||||
}
|
||||
return $this->json(1, '非法请求!');
|
||||
}
|
||||
|
||||
//排序
|
||||
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 = MCategory::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 = MCategory::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 MCategory();
|
||||
$model->saveAll($updateData);
|
||||
$sortStr = $sort == 'up' ? '上移' : '下调';
|
||||
Log::write('category', 'sort', "栏目排序,ID:{$id} ,标题:{$item['title']},{$sortStr}了{$num}位");
|
||||
return $this->json();
|
||||
}
|
||||
}
|
||||
return $this->json(4, '无须调整排序!');
|
||||
}
|
||||
return $this->json(1, '非法请求!');
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新栏目数据
|
||||
*/
|
||||
public function edit()
|
||||
{
|
||||
if($this->request->isPost()){
|
||||
$item = input('post.item/a');
|
||||
$id = input('post.id');
|
||||
$img = input('post.img');
|
||||
$img_mobile = input('post.img_mobile');
|
||||
$icon = input('post.imgicon');
|
||||
if (count($item) > 0 && (is_numeric($id) === true && $id > 0)) {
|
||||
Db::startTrans();
|
||||
try {
|
||||
validate(VCategory::class)->scene("edit")->check($item);
|
||||
$item['src'] = empty($img) ? '' : $img;
|
||||
$item['src_mobile'] = empty($img_mobile) ? '' : $img_mobile;
|
||||
$item['icon_img'] = empty($icon) ? '' : $icon;
|
||||
|
||||
// 只允许文章类栏目可以设置汇总查看
|
||||
if ($item['model_id'] != MCModel::MODEL_ARTICLE) {
|
||||
$item['parent_show'] = 0;
|
||||
}
|
||||
if (isset($item['category_key']) && strlen($item['category_key']) > 0) {
|
||||
$hadCate = MCategory::findByCategoryKey($item['category_key']);
|
||||
if (!empty($hadCate) && $hadCate['id'] != $id) {
|
||||
throw new ValidateException('栏目标识已存在');
|
||||
}
|
||||
}
|
||||
|
||||
MCategory::updateById($id, $item);
|
||||
|
||||
//处理特殊路由
|
||||
if (array_key_exists("route", $item) && !empty($item['route'])) {
|
||||
$specialRoute = SpecialRoute::findByTypeRelaTioneId($id,SpecialRoute::type_archives_category);
|
||||
if(empty($specialRoute)){
|
||||
$specialRouteData = [
|
||||
"route" =>$item["route"]??'',
|
||||
"type" =>SpecialRoute::type_archives_category,
|
||||
"relation_id" =>$id,
|
||||
];
|
||||
SpecialRoute::create($specialRouteData);
|
||||
}else{
|
||||
$specialRoute->save(["route"=>$item["route"]??'']);
|
||||
}
|
||||
}else{
|
||||
SpecialRoute::deleteByTypeIds($id,SpecialRoute::type_archives_category);
|
||||
}
|
||||
Db::commit();
|
||||
Cache::delete("categoryNames");
|
||||
Log::write('category', 'edit', "栏目编辑,ID:{$id} ,标题:{$item['title']}");
|
||||
return $this->json();
|
||||
} catch (ValidateException $e) {
|
||||
Db::rollback();
|
||||
return $this->json(2, $e->getError());
|
||||
}catch (\Exception $e) {
|
||||
return $this->json(2, $e->getMessage());
|
||||
}
|
||||
}
|
||||
return $this->json(1,'传入参数错误,请核对之后再操作!');
|
||||
} else {
|
||||
$id = input('param.id');
|
||||
if (is_numeric($id) === true && $id > 0) {
|
||||
$item = MCategory::getById($id);
|
||||
if(empty($item)){
|
||||
return $this->json(1,'参数错误,无此栏目!');
|
||||
}
|
||||
|
||||
$this->data['item'] = $item;
|
||||
$this->data['parent'] = MCategory::getById($item['parent_id']);
|
||||
$this->data['models'] = MCModel::getList();
|
||||
$this->data['iconImgSize'] = '64px * 64px';
|
||||
return $this->view();
|
||||
}
|
||||
return $this->json(1,'参数错误,请核对之后再操作!');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 栏目添加
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
if($this->request->isPost()){
|
||||
$item = input('post.item/a');
|
||||
$img = input('post.img');
|
||||
$img_mobile = input('post.img_mobile');
|
||||
$icon = input('post.imgicon');
|
||||
if (is_array($item) === true && count($item) > 0) {
|
||||
if (!empty($img)) {
|
||||
$item['src'] = $img;
|
||||
}if (!empty($img_mobile)) {
|
||||
$item['src_mobile'] = $img_mobile;
|
||||
}
|
||||
if(!empty($icon)){
|
||||
$item['icon_img'] = $icon;
|
||||
}
|
||||
Db::starttrans();
|
||||
try {
|
||||
validate(VCategory::class)->check($item);
|
||||
if(!isset($item['number']) || $item['number'] <= 0){
|
||||
$item['number'] = 20;
|
||||
}
|
||||
if($item['parent_id'] == 0){
|
||||
$item['path'] = ',0,';
|
||||
}else{
|
||||
$parent = MCategory::getById($item['parent_id']);
|
||||
if(empty($parent)){
|
||||
$item['path'] = ',0,';
|
||||
}else{
|
||||
$item['path'] = $parent['path'] . $parent['id'] . ',';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 只允许文章类栏目可以设置汇总查看
|
||||
if ($item['model_id'] != MCModel::MODEL_ARTICLE) {
|
||||
$item['parent_show'] = 0;
|
||||
}
|
||||
|
||||
if (isset($item['category_key']) && strlen($item['category_key']) > 0) {
|
||||
$hadCate = MCategory::findByCategoryKey($item['category_key']);
|
||||
if (!empty($hadCate)) {
|
||||
throw new ValidateException('栏目标识已存在');
|
||||
}
|
||||
}
|
||||
|
||||
$category = MCategory::create($item);
|
||||
|
||||
// 更新session
|
||||
$member = \app\model\Member::getById(session('auth')['userId']);
|
||||
$newCates = $member['cates'].','.$category['id'];
|
||||
(new \app\model\Member())->where('id', $member['id'])->save([
|
||||
'cates' => $newCates
|
||||
]);
|
||||
$auth = session('auth');
|
||||
$auth['cates'] = $newCates;
|
||||
session('auth', $auth);
|
||||
|
||||
//处理特殊路由
|
||||
if (array_key_exists("route", $item) && !empty($item['route'])) {
|
||||
$specialRouteData = [
|
||||
"route" =>$item["route"]??'',
|
||||
"type" =>SpecialRoute::type_archives_category,
|
||||
"relation_id" =>$category['id'],
|
||||
];
|
||||
SpecialRoute::create($specialRouteData);
|
||||
}
|
||||
Cache::delete("categoryNames");
|
||||
Db::commit();
|
||||
Log::write('category', 'add', "栏目新增,ID:{$category->id} ,标题:{$item['title']}");
|
||||
return $this->json();
|
||||
} catch (ValidateException $e) {
|
||||
return $this->json(2,$e->getError());
|
||||
} catch (\Exception $e) {
|
||||
return $this->json(2,$e->getMessage());
|
||||
}
|
||||
}
|
||||
return $this->json(1, '传入值错误,请核对之后再操作!');
|
||||
} else {
|
||||
$parentId = input('param.id')??input('param.parent_id');
|
||||
if(empty($parentId)){
|
||||
$parent = [];
|
||||
}else{
|
||||
$parent = MCategory::getById($parentId);
|
||||
}
|
||||
$this->data['parent'] = $parent;
|
||||
$this->data['models'] = MCModel::getList();
|
||||
$this->data['iconImgSize'] = '64px * 64px';
|
||||
return $this->view();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,95 @@
|
|||
<?php
|
||||
namespace app\controller\manager;
|
||||
|
||||
use app\model\ConfigSetting;
|
||||
use think\facade\Config as CConfig;
|
||||
|
||||
/**
|
||||
* 基础配置
|
||||
* Class Config
|
||||
* @package app\controller\manager
|
||||
*/
|
||||
class Config extends Base
|
||||
{
|
||||
public function base()
|
||||
{
|
||||
$configName = 'extraBase';
|
||||
|
||||
if ($this->request->isPost()) {
|
||||
$data = input("post.");
|
||||
if(isset($data['_token'])) {
|
||||
unset($data['_token']);
|
||||
}
|
||||
ConfigSetting::setConfigByName($configName, $data);
|
||||
return $this->json(0);
|
||||
|
||||
} else {
|
||||
|
||||
// 兼容写法,把原配置文件中的配置信息写入到数据库
|
||||
$conf = ConfigSetting::getConfigContentsByName($configName);
|
||||
if (empty($conf)) {
|
||||
CConfig::load('extra/base', $configName);
|
||||
$conf = config($configName);
|
||||
if (!empty($conf)) {
|
||||
ConfigSetting::setConfigByName($configName, $conf);
|
||||
}
|
||||
}
|
||||
|
||||
$this->data['item'] = $conf;
|
||||
return $this->view();
|
||||
}
|
||||
}
|
||||
|
||||
//法律制度
|
||||
public function statute()
|
||||
{
|
||||
$configName = 'extraStatute';
|
||||
|
||||
if ($this->request->isPost()) {
|
||||
$data = input("post.");
|
||||
if(isset($data['_token'])) {
|
||||
unset($data['_token']);
|
||||
}
|
||||
ConfigSetting::setConfigByName($configName, $data);
|
||||
return $this->json();
|
||||
|
||||
} else {
|
||||
|
||||
$conf = ConfigSetting::getConfigContentsByName($configName);
|
||||
if (empty($conf)) {
|
||||
CConfig::load('extra/statute', $configName);
|
||||
$conf = config($configName);
|
||||
if (!empty($conf)) {
|
||||
ConfigSetting::setConfigByName($configName, $conf);
|
||||
}
|
||||
}
|
||||
|
||||
$this->data['item'] = $conf;
|
||||
return $this->view();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 侧边栏配置
|
||||
* @date 2021-11
|
||||
*/
|
||||
public function slide()
|
||||
{
|
||||
$configName = 'extraSlide';
|
||||
|
||||
if ($this->request->isPost()) {
|
||||
$data = input("post.");
|
||||
if(isset($data['_token'])) {
|
||||
unset($data['_token']);
|
||||
}
|
||||
ConfigSetting::setConfigByName($configName, $data);
|
||||
return $this->json();
|
||||
|
||||
} else {
|
||||
|
||||
$conf = ConfigSetting::getConfigContentsByName($configName);
|
||||
$this->data['item'] = $conf;
|
||||
return $this->view();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,258 @@
|
|||
<?php
|
||||
|
||||
namespace app\controller\manager;
|
||||
|
||||
use app\model\{Category, Article, Block, DownloadModel, Log, History, Honour, PositionModel, ProductModel};
|
||||
|
||||
class Content extends Base
|
||||
{
|
||||
//文章
|
||||
public function article()
|
||||
{
|
||||
$categoryId = input('param.category_id');
|
||||
$keyword = input('param.keyword');
|
||||
$param = input('param.param/a', []);
|
||||
$category = Category::getById($categoryId);
|
||||
if (empty($category)) {
|
||||
return $this->error('无此栏目');
|
||||
}
|
||||
|
||||
$order = ['top' => 'desc', 'sort' => 'desc'];
|
||||
$list = Article::getList($categoryId, 20, $keyword, $param, -1, $order);
|
||||
$list = Article::convertRecommendOther([$categoryId], $list, true);
|
||||
|
||||
$this->data['list'] = $list;
|
||||
$this->data['category'] = $category;
|
||||
$this->data['keyword'] = $keyword;
|
||||
$this->data['param'] = $param;
|
||||
$this->data['attributeList'] = Article::getAttributeList([$categoryId]);
|
||||
return $this->view();
|
||||
}
|
||||
|
||||
//做页面跳转
|
||||
public function index()
|
||||
{
|
||||
$items = Category::getList();
|
||||
if (!empty($items)) {
|
||||
$items = Category::getCates($items);
|
||||
}
|
||||
|
||||
if (!empty($items)) {
|
||||
$first = array_shift($items);
|
||||
if (isset($first['children'])) {
|
||||
$childrenFirst = array_shift($first['children']);
|
||||
$url = url('manager.content/'.$childrenFirst['manager'], ['category_id' => $childrenFirst['id']]);
|
||||
} else {
|
||||
$url = url('manager.content/'.$first['manager'], ['category_id' => $first['id']]);
|
||||
}
|
||||
if (!empty($url)) {
|
||||
return $this->redirect($url);
|
||||
}
|
||||
} else {
|
||||
return $this->redirect(url('manager.category/add'));
|
||||
}
|
||||
}
|
||||
|
||||
//单页
|
||||
public function page()
|
||||
{
|
||||
if ($this->request->isAjax()) {
|
||||
$blocks = input('post.block/a'); //所有文本信息
|
||||
$texts = input('post.text/a'); //所有富文本信息
|
||||
$codes = input('post.code/a'); //所有代码信息
|
||||
$categoryId = input('post.category_id/d');
|
||||
$category = Category::getById($categoryId);
|
||||
unset($_POST['block']);
|
||||
unset($_POST['text']);
|
||||
unset($_POST['file']);
|
||||
unset($_POST['code']);
|
||||
$imgs = []; //图片信息
|
||||
$videos = []; //视频信息
|
||||
$groups = []; //组图信息
|
||||
$groupIds = input('post.groupIds/a', []);
|
||||
|
||||
$videoGroup = []; //视频组信息
|
||||
$videoGroupIds = input('post.videoGroupIds/a', []);
|
||||
foreach ($_POST as $key => $val) {
|
||||
if (strpos($key, '_') !== false) {
|
||||
$keys = explode('_', $key);
|
||||
if ($keys[1] == 'img') { //图片
|
||||
$imgs[$keys[2]] = $val;
|
||||
} elseif ($keys[1] == 'video') { //视频
|
||||
$videos[$keys[2]][$keys[0]] = $val;
|
||||
} elseif ($keys[1] == 'videos') { //视频组
|
||||
$videoGroup[$keys[2]] = $val;
|
||||
} elseif ($keys[1] == 'group') { //组图
|
||||
$groups[$keys[2]] = $val;
|
||||
}
|
||||
}
|
||||
}
|
||||
$data = [];
|
||||
if (!empty($blocks)) {
|
||||
foreach ($blocks as $key => $block) {
|
||||
$data[] = [
|
||||
'id' => $key,
|
||||
'value' => $block
|
||||
];
|
||||
}
|
||||
}
|
||||
if (!empty($texts)) {
|
||||
foreach ($texts as $key => $text) {
|
||||
$data[] = [
|
||||
'id' => $key,
|
||||
'value' => $text
|
||||
];
|
||||
}
|
||||
}
|
||||
if (!empty($codes)) {
|
||||
foreach ($codes as $key => $code) {
|
||||
$data[] = [
|
||||
'id' => $key,
|
||||
'value' => $code
|
||||
];
|
||||
}
|
||||
}
|
||||
if (!empty($imgs)) {
|
||||
foreach ($imgs as $key => $img) {
|
||||
$data[] = [
|
||||
'id' => $key,
|
||||
'value' => $img
|
||||
];
|
||||
}
|
||||
}
|
||||
if (!empty($videos)) {
|
||||
foreach ($videos as $key => $video) {
|
||||
$data[] = [
|
||||
'id' => $key,
|
||||
'img' => $video['img'],
|
||||
'value' => $video['video']
|
||||
];
|
||||
}
|
||||
}
|
||||
if (!empty($groupIds)) {
|
||||
foreach ($groupIds as $key => $groupId) {
|
||||
$group = $groups[$groupId] ?? [];
|
||||
$data[] = [
|
||||
'id' => $groupId,
|
||||
'value' => json_encode($group)
|
||||
];
|
||||
}
|
||||
}
|
||||
if (!empty($videoGroupIds)) {
|
||||
foreach ($videoGroupIds as $key => $groupId) {
|
||||
$group = $videoGroup[$groupId] ?? [];
|
||||
$data[] = [
|
||||
'id' => $groupId,
|
||||
'value' => json_encode($group)
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
$block = new Block;
|
||||
$block->saveAll($data);
|
||||
Log::write('content', 'page', "单页编辑,栏目ID:{$category['id']} ,标题:{$category['title']}");
|
||||
return $this->json();
|
||||
} else {
|
||||
$categoryId = input('param.category_id');
|
||||
$category = Category::getById($categoryId);
|
||||
/*
|
||||
* 单页栏目允许父级栏目配置,不自动跳转到第一个子栏目
|
||||
$children = Category::getChildrenByParentId($categoryId);
|
||||
if(!empty($children)){
|
||||
$child = Category::getChildrenByParentId($children[0]['id']);
|
||||
if(empty($child)){
|
||||
$category = $children[0];
|
||||
}else{
|
||||
$category = $child[0];
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
if (empty($category)) {
|
||||
return $this->redirect(url('manager.content/index'));
|
||||
}
|
||||
$blocks = Block::getByCategoryId($category['id']);
|
||||
$this->data['categoryId'] = $categoryId;
|
||||
$this->data['category'] = $category;
|
||||
$this->data['blocks'] = $blocks;
|
||||
$this->data['groupId'] = session('auth.groupId');
|
||||
$this->data['types'] = Block::getTypes();
|
||||
return $this->view();
|
||||
}
|
||||
}
|
||||
|
||||
// 发展历程
|
||||
public function history()
|
||||
{
|
||||
$categoryId = input('param.category_id/d', 0);
|
||||
$category = Category::getById($categoryId);
|
||||
if (empty($category)) {
|
||||
return $this->redirect(url('manager.content/index'));
|
||||
}
|
||||
|
||||
$this->data['categoryId'] = $categoryId;
|
||||
$this->data['category'] = $category;
|
||||
$this->data['items'] = History::getPaginateList($categoryId, 20, false);
|
||||
return $this->view();
|
||||
}
|
||||
|
||||
// 荣誉资质
|
||||
public function honour()
|
||||
{
|
||||
$categoryId = input('param.category_id/d', 0);
|
||||
$category = Category::getById($categoryId);
|
||||
if (empty($category)) {
|
||||
return $this->redirect(url('manager.content/index'));
|
||||
}
|
||||
|
||||
$this->data['categoryId'] = $categoryId;
|
||||
$this->data['category'] = $category;
|
||||
$this->data['items'] = Honour::getPaginateList($categoryId, 20, false);
|
||||
return $this->view();
|
||||
}
|
||||
|
||||
// 产品
|
||||
public function product()
|
||||
{
|
||||
$categoryId = input('param.category_id/d', 0);
|
||||
$category = Category::getById($categoryId);
|
||||
if (empty($category)) {
|
||||
return $this->redirect(url('manager.content/index'));
|
||||
}
|
||||
|
||||
$this->data['categoryId'] = $categoryId;
|
||||
$this->data['category'] = $category;
|
||||
$this->data['items'] = ProductModel::getPaginateList($categoryId, 20, false);
|
||||
return $this->view();
|
||||
}
|
||||
|
||||
// 下载中心
|
||||
public function download()
|
||||
{
|
||||
$categoryId = input('param.category_id/d', 0);
|
||||
$category = Category::getById($categoryId);
|
||||
if (empty($category)) {
|
||||
return $this->redirect(url('manager.content/index'));
|
||||
}
|
||||
|
||||
$this->data['categoryId'] = $categoryId;
|
||||
$this->data['category'] = $category;
|
||||
$this->data['items'] = DownloadModel::getPaginateList($categoryId, 20, false);
|
||||
return $this->view();
|
||||
}
|
||||
|
||||
// 招聘职位
|
||||
public function position()
|
||||
{
|
||||
$categoryId = input('param.category_id/d', 0);
|
||||
$category = Category::getById($categoryId);
|
||||
if (empty($category)) {
|
||||
return $this->redirect(url('manager.content/index'));
|
||||
}
|
||||
|
||||
$this->data['categoryId'] = $categoryId;
|
||||
$this->data['category'] = $category;
|
||||
$this->data['items'] = PositionModel::getPaginateList($categoryId, 20, false);
|
||||
return $this->view();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,164 @@
|
|||
<?php
|
||||
|
||||
namespace app\controller\manager;
|
||||
|
||||
use app\model\{DownloadModel, Category as MCategory, Log as MLog, System};
|
||||
use think\exception\ValidateException;
|
||||
use app\validate\{DownloadValidate};
|
||||
use think\facade\Db;
|
||||
|
||||
/**
|
||||
* 下载中心
|
||||
* Class Download
|
||||
* @package app\controller\manager
|
||||
*/
|
||||
class Download extends Base
|
||||
{
|
||||
public function add()
|
||||
{
|
||||
if (request()->isPost()) {
|
||||
$params = input('post.item/a', []);
|
||||
$file = input('file');
|
||||
$params = arrayHtmlFilter($params);
|
||||
try {
|
||||
$fileInfo = \app\model\File::where('src', $file)->order('id', 'desc')->find();
|
||||
if (!$fileInfo) {
|
||||
return $this->json(1, '文件不存在,请重新上传');
|
||||
}
|
||||
$params['size'] = $fileInfo['size'];
|
||||
$params['mime_type'] = $fileInfo['mime_type'];
|
||||
$params['suffix'] = $fileInfo['suffix'];
|
||||
$params['file'] = $fileInfo['src'];
|
||||
|
||||
validate(DownloadValidate::class)->check($params);
|
||||
$newItem = DownloadModel::create($params);
|
||||
MLog::write('download', 'add', '新增下载中心,ID:'.$newItem->id);
|
||||
} catch (ValidateException $e) {
|
||||
return $this->json(1, $e->getError());
|
||||
}
|
||||
return $this->json();
|
||||
} else {
|
||||
$categoryId = input('param.category_id/d', 0);
|
||||
$category = MCategory::getById($categoryId);
|
||||
$this->data['category'] = $category;
|
||||
return $this->view();
|
||||
}
|
||||
}
|
||||
|
||||
public function edit()
|
||||
{
|
||||
$id = input('param.id/d', 0);
|
||||
$item = DownloadModel::getById($id);
|
||||
if (count($item) == 0) {
|
||||
return $this->json(1, '该记录不存在');
|
||||
}
|
||||
if (request()->isPost()) {
|
||||
$params = input('post.item/a', []);
|
||||
$file = input('file');
|
||||
$params = arrayHtmlFilter($params);
|
||||
try {
|
||||
if (!empty($file)) {
|
||||
$fileInfo = \app\model\File::where('src', $file)->order('id', 'desc')->find();
|
||||
if (!$fileInfo) {
|
||||
return $this->json(1, '文件不存在,请重新上传');
|
||||
}
|
||||
$params['size'] = $fileInfo['size'];
|
||||
$params['mime_type'] = $fileInfo['mime_type'];
|
||||
$params['suffix'] = $fileInfo['suffix'];
|
||||
$params['file'] = $fileInfo['src'];
|
||||
}
|
||||
|
||||
validate(DownloadValidate::class)->check($params);
|
||||
DownloadModel::updateById($id, $params);
|
||||
MLog::write('download', 'edit', '修改下载中心,ID:'.$id);
|
||||
} catch (ValidateException $e) {
|
||||
return $this->json(2, $e->getError());
|
||||
}
|
||||
return $this->json();
|
||||
} else {
|
||||
$this->data['item'] = $item;
|
||||
return $this->view();
|
||||
}
|
||||
}
|
||||
|
||||
public function sort()
|
||||
{
|
||||
if (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 = DownloadModel::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 = DownloadModel::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 DownloadModel();
|
||||
$model->saveAll($updateData);
|
||||
$sortStr = $sort == 'up' ? '上移' : '下调';
|
||||
MLog::write('download', 'sort', "下载中心排序,ID:{$id} ,{$sortStr}了{$num}位");
|
||||
return $this->json();
|
||||
}
|
||||
}
|
||||
return $this->json(4, '无须调整排序!');
|
||||
}
|
||||
return $this->json(1, '无此操作');
|
||||
}
|
||||
|
||||
// 删除
|
||||
public function del()
|
||||
{
|
||||
if (request()->isPost()) {
|
||||
$downloadId = input('param.id/d', 0);
|
||||
$item = DownloadModel::getById($downloadId);
|
||||
if (count($item) == 0) {
|
||||
return $this->json(2, '该记录不存在');
|
||||
}
|
||||
Db::startTrans();
|
||||
try {
|
||||
@unlink(public_path().$item['file'] ?? '');
|
||||
DownloadModel::destroy($downloadId);
|
||||
MLog::write('download', 'del', '删除历程,ID:'.$downloadId);
|
||||
Db::commit();
|
||||
} catch (\Exception $e) {
|
||||
Db::rollback();
|
||||
return $this->json(3, '删除失败,'.$e->getMessage());
|
||||
}
|
||||
return $this->json();
|
||||
}
|
||||
return $this->json(1, '无此操作');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
namespace app\controller\manager;
|
||||
|
||||
class Error
|
||||
{
|
||||
protected $data = [];
|
||||
|
||||
public function __call($method, $args)
|
||||
{
|
||||
$this->data['seoTitle'] = '404';
|
||||
return view('error/404')->assign($this->data);
|
||||
}
|
||||
|
||||
public function jump()
|
||||
{
|
||||
$param = request()->param();
|
||||
return view()->assign($param);
|
||||
}
|
||||
|
||||
// 404
|
||||
public function notFind()
|
||||
{
|
||||
$this->data['seoTitle'] = '404';
|
||||
return view('error/404')->assign($this->data);
|
||||
}
|
||||
|
||||
// 500
|
||||
public function serviceFail()
|
||||
{
|
||||
$this->data['seoTitle'] = '500';
|
||||
return view('error/500')->assign($this->data);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,146 @@
|
|||
<?php
|
||||
namespace app\controller\manager;
|
||||
|
||||
use app\model\{File as MFile, Article, Block, Category, Link, LinkProduct, Slide, Log};
|
||||
use app\service\Tool;
|
||||
|
||||
class File extends Base
|
||||
{
|
||||
//删除磁盘上的文件
|
||||
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);
|
||||
}
|
||||
$linkProductFiles = LinkProduct::getFilesInUse();
|
||||
if(!empty($linkProductFiles)){
|
||||
$files = array_merge($files, $linkProductFiles);
|
||||
}
|
||||
$categoryFiles = Category::getFilesInUse();
|
||||
if(!empty($categoryFiles)){
|
||||
$files = array_merge($files, $categoryFiles);
|
||||
}
|
||||
$articleFiles = Article::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,146 @@
|
|||
<?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()
|
||||
{
|
||||
$auth = session('auth');
|
||||
if ($auth['groupId'] == 1) {
|
||||
$list = AuthGroup::select()->toArray();
|
||||
} else {
|
||||
$list = AuthGroup::where('id', '<>', 1)->select()->toArray();
|
||||
}
|
||||
$this->data['list'] = $list;
|
||||
return $this->view();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,346 @@
|
|||
<?php
|
||||
|
||||
namespace app\controller\manager;
|
||||
|
||||
use app\model\{HistoryInfo as MHistoryInfo, History as MHistory, Category as MCategory, Log as MLog, System};
|
||||
use think\exception\ValidateException;
|
||||
use app\validate\{History as VHistory, HistoryInfo as VHistoryInfo};
|
||||
use think\facade\Db;
|
||||
|
||||
/**
|
||||
* 发展历程
|
||||
* Class History
|
||||
* @package app\controller\manager
|
||||
*/
|
||||
class History extends Base
|
||||
{
|
||||
public function add()
|
||||
{
|
||||
if (request()->isPost()) {
|
||||
$params = input('post.item/a', []);
|
||||
$params = arrayHtmlFilter($params);
|
||||
try {
|
||||
validate(VHistory::class)->check($params);
|
||||
$data = [
|
||||
'title' => $params['title'],
|
||||
'visible' => $params['visible'],
|
||||
'category_id' => $params['category_id'],
|
||||
'event' => $params['event'],
|
||||
];
|
||||
$newItem = MHistory::create($data);
|
||||
MLog::write('history', 'add', '新增发展历程,ID:'.$newItem->id);
|
||||
} catch (ValidateException $e) {
|
||||
return $this->json(1, $e->getError());
|
||||
}
|
||||
return $this->json();
|
||||
} else {
|
||||
$categoryId = input('param.category_id/d', 0);
|
||||
$category = MCategory::getById($categoryId);
|
||||
$this->data['category'] = $category;
|
||||
return $this->view();
|
||||
}
|
||||
}
|
||||
|
||||
public function edit()
|
||||
{
|
||||
$id = input('param.id/d', 0);
|
||||
$item = MHistory::getById($id);
|
||||
if (count($item) == 0) {
|
||||
return $this->json(1, '该历程信息不存在');
|
||||
}
|
||||
if (request()->isPost()) {
|
||||
$params = input('post.item/a', []);
|
||||
$params = arrayHtmlFilter($params);
|
||||
try {
|
||||
validate(VHistory::class)->check($params);
|
||||
$data = [
|
||||
'title' => $params['title'],
|
||||
'visible' => $params['visible'],
|
||||
'event' => $params['event'],
|
||||
];
|
||||
MHistory::updateById($id, $data);
|
||||
MLog::write('history', 'edit', '修改发展历程,ID:'.$id);
|
||||
} catch (ValidateException $e) {
|
||||
return $this->json(2, $e->getError());
|
||||
}
|
||||
return $this->json();
|
||||
} else {
|
||||
$this->data['item'] = $item;
|
||||
return $this->view();
|
||||
}
|
||||
}
|
||||
|
||||
public function sort()
|
||||
{
|
||||
if (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 = MHistory::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 = MHistory::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 MHistory();
|
||||
$model->saveAll($updateData);
|
||||
$sortStr = $sort == 'up' ? '上移' : '下调';
|
||||
MLog::write('history', 'sort', "发展历程排序,ID:{$id} ,{$sortStr}了{$num}位");
|
||||
return $this->json();
|
||||
}
|
||||
}
|
||||
return $this->json(4, '无须调整排序!');
|
||||
}
|
||||
return $this->json(1, '无此操作');
|
||||
}
|
||||
|
||||
// 删除历程和历程相关的事例
|
||||
public function del()
|
||||
{
|
||||
if (request()->isPost()) {
|
||||
$historyId = input('param.id/d', 0);
|
||||
$item = MHistory::getById($historyId);
|
||||
if (count($item) == 0) {
|
||||
return $this->json(2, '该历程信息不存在');
|
||||
}
|
||||
Db::startTrans();
|
||||
try {
|
||||
MHistory::destroy($historyId);
|
||||
$hasInfo = MHistoryInfo::countByHistoryId($historyId);
|
||||
if ($hasInfo > 0) {
|
||||
MHistoryInfo::delByHistoryId($historyId);
|
||||
}
|
||||
MLog::write('history', 'del', '删除历程,ID:'.$historyId);
|
||||
Db::commit();
|
||||
} catch (\Exception $e) {
|
||||
Db::rollback();
|
||||
return $this->json(3, '删除失败,'.$e->getMessage());
|
||||
}
|
||||
return $this->json();
|
||||
}
|
||||
return $this->json(1, '无此操作');
|
||||
}
|
||||
|
||||
|
||||
public function info()
|
||||
{
|
||||
$historyId = input('param.history_id/d', 0);
|
||||
$history = MHistory::getById($historyId);
|
||||
$infoItems = [];
|
||||
$categoryId = $history['category_id'] ?? 0;
|
||||
if (count($history) > 0) {
|
||||
$infoItems = MHistoryInfo::getByHistoryId($historyId);
|
||||
}
|
||||
$this->data['history'] = $history;
|
||||
$this->data['categoryId'] = $categoryId;
|
||||
$this->data['items'] = $infoItems;
|
||||
return $this->view();
|
||||
}
|
||||
|
||||
// 新增发展历程详情
|
||||
public function addInfo()
|
||||
{
|
||||
$historyId = input('param.history_id/d', 0);
|
||||
$history = MHistory::getById($historyId);
|
||||
if (count($history) == 0) {
|
||||
return $this->json(1, '该历程信息不存在');
|
||||
}
|
||||
if (request()->isPost()) {
|
||||
$params = input('post.item/a', []);
|
||||
$params = arrayHtmlFilter($params);
|
||||
$imgs = input('post.img/a');
|
||||
if (!empty($imgs) && is_array($imgs)) {
|
||||
$imgs = json_encode($imgs);
|
||||
} else {
|
||||
$imgs = '';
|
||||
}
|
||||
try {
|
||||
validate(VHistoryInfo::class)->check($params);
|
||||
$data = [
|
||||
'title' => $params['title'],
|
||||
'visible' => $params['visible'],
|
||||
'history_id' => $historyId,
|
||||
'imgs' => $imgs,
|
||||
];
|
||||
$newItem = MHistoryInfo::create($data);
|
||||
MLog::write('history', 'addInfo', '新增发展历程事例,ID:'.$newItem->id);
|
||||
} catch (ValidateException $e) {
|
||||
return $this->json(2, $e->getError());
|
||||
}
|
||||
return $this->json();
|
||||
} else {
|
||||
$imgSize = '';
|
||||
$category = MCategory::getById($history['category_id']);
|
||||
if (count($category) > 0 && $category['img_width'] && $category['img_height']) {
|
||||
$imgSize = $category['img_width'].'像素 X '.$category['img_height'].'像素';
|
||||
}
|
||||
|
||||
$this->data['historyId'] = $historyId;
|
||||
$this->data['history'] = $history;
|
||||
$this->data['imgSize'] = $imgSize;
|
||||
return $this->view();
|
||||
}
|
||||
}
|
||||
|
||||
// 编辑发展历程详情
|
||||
public function editInfo()
|
||||
{
|
||||
$id = input('param.id/d', 0);
|
||||
$item = MHistoryInfo::getById($id);
|
||||
if (count($item) == 0) {
|
||||
return $this->json(1, '该历程事例信息不存在');
|
||||
}
|
||||
|
||||
if (request()->isPost()) {
|
||||
$params = input('post.item/a', []);
|
||||
$params = arrayHtmlFilter($params);
|
||||
$imgs = input('post.img/a');
|
||||
if (!empty($imgs) && is_array($imgs)) {
|
||||
$imgs = json_encode($imgs);
|
||||
} else {
|
||||
$imgs = '';
|
||||
}
|
||||
try {
|
||||
validate(VHistoryInfo::class)->check($params);
|
||||
$data = [
|
||||
'title' => $params['title'],
|
||||
'visible' => $params['visible'],
|
||||
'imgs' => $imgs,
|
||||
];
|
||||
MHistoryInfo::updateById($id, $data);
|
||||
MLog::write('history', 'editInfo', '修改发展历程事例,ID:'.$id);
|
||||
} catch (ValidateException $e) {
|
||||
return $this->json(2, $e->getError());
|
||||
}
|
||||
return $this->json();
|
||||
} else {
|
||||
$history = MHistory::getById($item['history_id']);
|
||||
$imgSize = '';
|
||||
if (count($history) > 0) {
|
||||
$category = MCategory::getById($history['category_id']);
|
||||
if (count($category) > 0 && $category['img_width'] && $category['img_height']) {
|
||||
$imgSize = $category['img_width'].'像素 X '.$category['img_height'].'像素';
|
||||
}
|
||||
}
|
||||
|
||||
$this->data['item'] = $item;
|
||||
$this->data['imgSize'] = $imgSize;
|
||||
return $this->view();
|
||||
}
|
||||
}
|
||||
|
||||
public function sortInfo()
|
||||
{
|
||||
if (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 = MHistoryInfo::getById($id);
|
||||
if (empty($item)) {
|
||||
return $this->json(3, '该历程事例信息不存在');
|
||||
}
|
||||
if ($sort == 'up') {
|
||||
$where = "history_id='{$item['history_id']}' and sort < {$item['sort']}";
|
||||
$order = "sort desc";
|
||||
} else {
|
||||
$where = "history_id='{$item['history_id']}' and sort > {$item['sort']}";
|
||||
$order = "sort asc";
|
||||
}
|
||||
$forSortItems = MHistoryInfo::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 MHistoryInfo();
|
||||
$model->saveAll($updateData);
|
||||
$sortStr = $sort == 'up' ? '上移' : '下调';
|
||||
MLog::write('history', 'sortInfo', "发展历程事例排序,ID:{$id} ,{$sortStr}了{$num}位");
|
||||
return $this->json();
|
||||
}
|
||||
}
|
||||
return $this->json(4, '无须调整排序!');
|
||||
}
|
||||
return $this->json(1, '无此操作');
|
||||
}
|
||||
|
||||
public function delInfo()
|
||||
{
|
||||
if (request()->isPost()) {
|
||||
$infoIds = [];
|
||||
$ids = input('post.ids', []);
|
||||
$id = input('post.id', 0);
|
||||
if (!empty($ids)) {
|
||||
if (is_array($ids)) {
|
||||
$infoIds = $ids;
|
||||
} else {
|
||||
$infoIds = explode(',', $ids);
|
||||
}
|
||||
} elseif ($id > 0) {
|
||||
$infoIds[] = $id;
|
||||
}
|
||||
if (count($infoIds) > 0) {
|
||||
MHistoryInfo::destroy($infoIds);
|
||||
MLog::write('history', 'delInfo', '删除历程事例,IDs:'.implode(',', $infoIds));
|
||||
return $this->json();
|
||||
}
|
||||
return $this->json(2, '参数错误');
|
||||
}
|
||||
return $this->json(1, '无此操作');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,164 @@
|
|||
<?php
|
||||
|
||||
namespace app\controller\manager;
|
||||
|
||||
use app\validate\HonourValidate;
|
||||
use app\model\{Honour as MHonour, Category as MCategory, Log as MLog, System};
|
||||
use think\exception\ValidateException;
|
||||
use think\response\Json;
|
||||
use think\response\View;
|
||||
|
||||
/**
|
||||
* 荣誉资质
|
||||
* Class Honour
|
||||
* @package app\controller\manager
|
||||
*/
|
||||
class Honour extends Base
|
||||
{
|
||||
/**
|
||||
* @return Json|View
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
if (request()->isPost()) {
|
||||
$params = input('post.item/a', []);
|
||||
$params = arrayHtmlFilter($params);
|
||||
$params['image'] = input('img');
|
||||
try {
|
||||
validate(HonourValidate::class)->check($params);
|
||||
$newItem = MHonour::create($params);
|
||||
MLog::write('honour', 'add', '新增荣誉资质,ID:'.$newItem->id);
|
||||
} catch (ValidateException $e) {
|
||||
return $this->json(1, $e->getError());
|
||||
}
|
||||
return $this->json();
|
||||
} else {
|
||||
$categoryId = input('param.category_id/d', 0);
|
||||
$category = MCategory::getById($categoryId);
|
||||
|
||||
if (count($category) > 0 && $category['img_width'] && $category['img_height']) {
|
||||
$imgSize = $category['img_width'].'像素 X '.$category['img_height'].'像素';
|
||||
} else {
|
||||
$imgSize = System::getArticleImageSize();
|
||||
}
|
||||
|
||||
$this->data['imgSize'] = $imgSize;
|
||||
$this->data['category'] = $category;
|
||||
return $this->view();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Json|View
|
||||
*/
|
||||
public function edit()
|
||||
{
|
||||
$id = input('param.id/d', 0);
|
||||
$item = MHonour::getById($id);
|
||||
if (count($item) == 0) {
|
||||
return $this->json(1, '该荣誉资质不存在');
|
||||
}
|
||||
if (request()->isPost()) {
|
||||
$params = input('post.item/a', []);
|
||||
$params = arrayHtmlFilter($params);
|
||||
$params['image'] = input('img');
|
||||
try {
|
||||
validate(HonourValidate::class)->check($params);
|
||||
MHonour::updateById($id, $params);
|
||||
MLog::write('honour', 'edit', '修改荣誉资质,ID:'.$id);
|
||||
} catch (ValidateException $e) {
|
||||
return $this->json(2, $e->getError());
|
||||
}
|
||||
return $this->json();
|
||||
} else {
|
||||
$category = MCategory::getById($item['category_id']);
|
||||
|
||||
if (count($category) > 0 && $category['img_width'] && $category['img_height']) {
|
||||
$imgSize = $category['img_width'].'像素 X '.$category['img_height'].'像素';
|
||||
} else {
|
||||
$imgSize = System::getArticleImageSize();
|
||||
}
|
||||
|
||||
$this->data['imgSize'] = $imgSize;
|
||||
$this->data['item'] = $item;
|
||||
return $this->view();
|
||||
}
|
||||
}
|
||||
|
||||
public function sort()
|
||||
{
|
||||
if (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 = MHonour::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 = MHonour::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 MHonour();
|
||||
$model->saveAll($updateData);
|
||||
$sortStr = $sort == 'up' ? '上移' : '下调';
|
||||
MLog::write('history', 'sort', "荣誉资质排序,ID:{$id} ,{$sortStr}了{$num}位");
|
||||
return $this->json();
|
||||
}
|
||||
}
|
||||
return $this->json(4, '无须调整排序!');
|
||||
}
|
||||
return $this->json(1, '无此操作');
|
||||
}
|
||||
|
||||
// 删除历程和历程相关的事例
|
||||
public function del()
|
||||
{
|
||||
if (request()->isPost()) {
|
||||
$historyId = input('param.id/d', 0);
|
||||
$item = MHonour::getById($historyId);
|
||||
if (count($item) == 0) {
|
||||
return $this->json(2, '该荣誉资质不存在');
|
||||
}
|
||||
try {
|
||||
MHonour::destroy($historyId);
|
||||
MLog::write('honour', 'del', '删除荣誉资质,ID:'.$historyId);
|
||||
} catch (\Exception $e) {
|
||||
return $this->json(3, '删除失败,'.$e->getMessage());
|
||||
}
|
||||
return $this->json();
|
||||
}
|
||||
return $this->json(1, '无此操作');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
<?php
|
||||
|
||||
namespace app\controller\manager;
|
||||
|
||||
use app\model\VisitLogoModel;
|
||||
use think\response\View;
|
||||
|
||||
class Index extends Base
|
||||
{
|
||||
//后台首页
|
||||
public function index(): View
|
||||
{
|
||||
$today = [];
|
||||
|
||||
$today[] = ['create_time', '>', strtotime(date('Y-m-d 00:00:00'))];
|
||||
$today[] = ['create_time', '<', strtotime(date('Y-m-d 23:59:59'))];
|
||||
|
||||
// 全部
|
||||
$data['total'] = VisitLogoModel::field('id')->count();
|
||||
// 今日全部
|
||||
$data['todayTotal'] = VisitLogoModel::where($today)->field('id')->count();
|
||||
|
||||
// 百度全部
|
||||
$data['totalBaidu'] = VisitLogoModel::where('referer', 'like', '%baidu.com%')->field('id')->count();
|
||||
// 360全部
|
||||
$data['total360'] = VisitLogoModel::where('referer', 'like', '%so.com%')->field('id')->count();
|
||||
|
||||
// 百度今日
|
||||
$data['todayBaidu'] = VisitLogoModel::where($today)->where('referer', 'like', '%baidu.com%')->field('id')->count();
|
||||
// 360今日
|
||||
$data['today360'] = VisitLogoModel::where($today)->where('referer', 'like', '%so.com%')->field('id')->count();
|
||||
|
||||
// 今日留言
|
||||
$data['todayMessage'] = \app\model\Message::where($today)->count();
|
||||
// 总留言
|
||||
$data['totalMessage'] = \app\model\Message::count();
|
||||
|
||||
$this->data['data'] = $data;
|
||||
|
||||
return $this->view();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,177 @@
|
|||
<?php
|
||||
namespace app\controller\manager;
|
||||
|
||||
use app\model\{Link as MLink, System, Log};
|
||||
use app\validate\Link as VLink;
|
||||
use think\exception\ValidateException;
|
||||
|
||||
class Link extends Base
|
||||
{
|
||||
//批量删除
|
||||
public function batchDel()
|
||||
{
|
||||
if ($this->request->isPost()) {
|
||||
$ids = input('post.ids/a');
|
||||
if(empty($ids) || !is_array($ids)) {
|
||||
return $this->json(2, '参数错误,请核对之后再操作!');
|
||||
}
|
||||
$items = MLink::getListByIds($ids);
|
||||
if(!empty($items)){
|
||||
$delIds = [];
|
||||
foreach($items as $item){
|
||||
$delIds[] = $item['id'];
|
||||
}
|
||||
MLink::destroy($delIds);
|
||||
Log::write('link', 'betchDel', '批量删除了友情链接,涉及到的ID为:' . implode(',', $delIds));
|
||||
return $this->json();
|
||||
}else{
|
||||
return $this->json(3, '待删除友情链接为空');
|
||||
}
|
||||
}
|
||||
return $this->json(1, '非法请求!');
|
||||
}
|
||||
//删除
|
||||
public function del()
|
||||
{
|
||||
if ($this->request->isPost()) {
|
||||
$id = input('post.id/d');
|
||||
if(is_numeric($id) && $id > 0) {
|
||||
$item = MLink::getById($id);
|
||||
if(!empty($item)){
|
||||
MLink::destroy($id);
|
||||
Log::write('link', 'del', '删除友情链接,ID:' . $id . ',标题:' . $item['title']);
|
||||
return $this->json();
|
||||
}
|
||||
return $this->json(3, '待删除友情链接不存在');
|
||||
}
|
||||
return $this->json(2, '参数错误,请核对之后再操作!');
|
||||
}
|
||||
return $this->json(1, '非法请求!');
|
||||
}
|
||||
|
||||
//排序
|
||||
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 = MLink::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 = MLink::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 MLink();
|
||||
$model->saveAll($updateData);
|
||||
$sortStr = $sort == 'up' ? '上移' : '下调';
|
||||
Log::write('link', 'sort', "友情链接排序,ID:{$id} ,标题:{$item['title']},{$sortStr}了{$num}位");
|
||||
return $this->json();
|
||||
}
|
||||
}
|
||||
return $this->json(4, '无须调整排序!');
|
||||
}
|
||||
return $this->json(1, '非法请求!');
|
||||
}
|
||||
|
||||
//编辑
|
||||
public function edit()
|
||||
{
|
||||
if($this->request->isPost()){
|
||||
$item = input('post.item/a');
|
||||
$id = input('post.id/d');
|
||||
$img = input('post.img');
|
||||
if(is_numeric($id) && $id > 0) {
|
||||
$link = MLink::getById($id);
|
||||
if(empty($link)) {
|
||||
return $this->json(2, '该友情链接信息不存在!');
|
||||
}
|
||||
if(!empty($img)){
|
||||
$item['src'] = $img;
|
||||
}
|
||||
try {
|
||||
validate(VLink::class)->check($item);
|
||||
MLink::updateById($id, $item);
|
||||
Log::write('link', 'edit', "友情链接编辑,ID:{$id} ,标题:{$item['title']}");
|
||||
return $this->json();
|
||||
} catch (ValidateException $e) {
|
||||
return $this->json(3, $e->getError());
|
||||
}
|
||||
}
|
||||
return $this->json(1, '参数错误,请核对之后再操作!');
|
||||
} else {
|
||||
$id = input('param.id/d');
|
||||
$item = MLink::getById($id);
|
||||
$imgSize = System::getLinkImageSize();
|
||||
|
||||
$this->data['item'] = $item;
|
||||
$this->data['img_size'] = $imgSize;
|
||||
return $this->view();
|
||||
}
|
||||
}
|
||||
|
||||
//添加
|
||||
public function add()
|
||||
{
|
||||
if($this->request->isPost()){
|
||||
$item = input('post.item/a');
|
||||
$img = input('post.img');
|
||||
|
||||
if(!empty($img)){
|
||||
$item['src'] = $img;
|
||||
}
|
||||
try {
|
||||
validate(VLink::class)->check($item);
|
||||
$link = MLink::create($item);
|
||||
Log::write('link', 'add', "友情链接新增,ID:{$link->id} ,标题:{$item['title']}");
|
||||
return $this->json();
|
||||
} catch (ValidateException $e) {
|
||||
return $this->json(2, $e->getError());
|
||||
}
|
||||
} else {
|
||||
$imgSize = System::getLinkImageSize();
|
||||
$this->data['img_size'] = $imgSize;
|
||||
return $this->view();
|
||||
}
|
||||
}
|
||||
|
||||
public function index()
|
||||
{
|
||||
$items = MLink::getListWithPaginate([], 50);
|
||||
$this->data['items'] = $items;
|
||||
return $this->view();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,179 @@
|
|||
<?php
|
||||
namespace app\controller\manager;
|
||||
|
||||
use app\model\{LinkProduct as MLinkProduct, System, Log};
|
||||
use app\validate\LinkProduct as VLinkProduct;
|
||||
use think\exception\ValidateException;
|
||||
|
||||
class LinkProduct extends Base
|
||||
{
|
||||
// 封面图推荐尺寸
|
||||
protected $imgSize = '210像素 x 190像素';
|
||||
|
||||
//批量删除
|
||||
public function batchDel()
|
||||
{
|
||||
if ($this->request->isPost()) {
|
||||
$ids = input('post.ids/a');
|
||||
if(empty($ids) || !is_array($ids)) {
|
||||
return $this->json(2, '参数错误,请核对之后再操作!');
|
||||
}
|
||||
$items = MLinkProduct::getListByIds($ids);
|
||||
if(!empty($items)){
|
||||
$delIds = [];
|
||||
foreach($items as $item){
|
||||
$delIds[] = $item['id'];
|
||||
}
|
||||
MLinkProduct::destroy($delIds);
|
||||
Log::write('LinkProduct', 'betchDel', '批量删除了合作伙伴,涉及到的ID为:' . implode(',', $delIds));
|
||||
return $this->json();
|
||||
}else{
|
||||
return $this->json(3, '待删除合作伙伴为空');
|
||||
}
|
||||
}
|
||||
return $this->json(1, '非法请求!');
|
||||
}
|
||||
//删除
|
||||
public function del()
|
||||
{
|
||||
if ($this->request->isPost()) {
|
||||
$id = input('post.id/d');
|
||||
if(is_numeric($id) && $id > 0) {
|
||||
$item = MLinkProduct::getById($id);
|
||||
if(!empty($item)){
|
||||
MLinkProduct::destroy($id);
|
||||
Log::write('LinkProduct', 'del', '删除合作伙伴,ID:' . $id . ',标题:' . $item['title']);
|
||||
return $this->json();
|
||||
}
|
||||
return $this->json(3, '待删除合作伙伴不存在');
|
||||
}
|
||||
return $this->json(2, '参数错误,请核对之后再操作!');
|
||||
}
|
||||
return $this->json(1, '非法请求!');
|
||||
}
|
||||
|
||||
//排序 (数字小的在前)
|
||||
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 = MLinkProduct::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 = MLinkProduct::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 MLinkProduct();
|
||||
$model->saveAll($updateData);
|
||||
$sortStr = $sort == 'up' ? '上移' : '下调';
|
||||
Log::write('LinkProduct', 'sort', "合作伙伴排序,ID:{$id} ,标题:{$item['title']},{$sortStr}了{$num}位");
|
||||
return $this->json();
|
||||
}
|
||||
}
|
||||
return $this->json(4, '无须调整排序!');
|
||||
}
|
||||
return $this->json(1, '非法请求!');
|
||||
}
|
||||
|
||||
//编辑
|
||||
public function edit()
|
||||
{
|
||||
if($this->request->isPost()){
|
||||
$item = input('post.item/a');
|
||||
$id = input('post.id/d');
|
||||
$img = input('post.img');
|
||||
if(is_numeric($id) && $id > 0) {
|
||||
$link = MLinkProduct::getById($id);
|
||||
if(empty($link)) {
|
||||
return $this->json(2, '该合作伙伴信息不存在!');
|
||||
}
|
||||
if(!empty($img)){
|
||||
$item['src'] = $img;
|
||||
}
|
||||
try {
|
||||
validate(VLinkProduct::class)->check($item);
|
||||
MLinkProduct::updateById($id, $item);
|
||||
Log::write('LinkProduct', 'edit', "合作伙伴编辑,ID:{$id} ,标题:{$item['title']}");
|
||||
return $this->json();
|
||||
} catch (ValidateException $e) {
|
||||
return $this->json(3, $e->getError());
|
||||
}
|
||||
}
|
||||
return $this->json(1, '参数错误,请核对之后再操作!');
|
||||
} else {
|
||||
$id = input('param.id/d');
|
||||
$item = MLinkProduct::getById($id);
|
||||
|
||||
$this->data['item'] = $item;
|
||||
$this->data['img_size'] = $this->imgSize;
|
||||
return $this->view();
|
||||
}
|
||||
}
|
||||
|
||||
//添加
|
||||
public function add()
|
||||
{
|
||||
if($this->request->isPost()){
|
||||
$item = input('post.item/a');
|
||||
$img = input('post.img');
|
||||
|
||||
if(!empty($img)){
|
||||
$item['src'] = $img;
|
||||
}
|
||||
try {
|
||||
validate(VLinkProduct::class)->check($item);
|
||||
$link = MLinkProduct::create($item);
|
||||
Log::write('LinkProduct', 'add', "合作伙伴新增,ID:{$link->id} ,标题:{$item['title']}");
|
||||
return $this->json();
|
||||
} catch (ValidateException $e) {
|
||||
return $this->json(2, $e->getError());
|
||||
}
|
||||
} else {
|
||||
|
||||
$this->data['img_size'] = $this->imgSize;
|
||||
return $this->view();
|
||||
}
|
||||
}
|
||||
|
||||
public function index()
|
||||
{
|
||||
$items = MLinkProduct::getList();
|
||||
$this->data['items'] = $items;
|
||||
return $this->view();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,82 @@
|
|||
<?php
|
||||
namespace app\controller\manager;
|
||||
|
||||
use app\model\{Member, AuthRule, LoginLog};
|
||||
use app\controller\BaseController;
|
||||
|
||||
class Login extends BaseController
|
||||
{
|
||||
/**
|
||||
* user lgoin
|
||||
* use ajax post push
|
||||
*
|
||||
* @return void | JSON
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
if(request()->isPost()){
|
||||
$username = trim(input('param.username'));
|
||||
$password = trim(input('param.password'));
|
||||
$loginUrl = url('manager.login/index');
|
||||
|
||||
$captcha = trim(input('param.captcha', ''));
|
||||
if (!captcha_check($captcha)) {
|
||||
session('loginError','验证码错误');
|
||||
return $this->redirect($loginUrl);
|
||||
}
|
||||
|
||||
if(empty($username) || empty($password)){
|
||||
session('loginError','用户名和密码不能为空');
|
||||
return $this->redirect($loginUrl);
|
||||
}
|
||||
|
||||
$member = Member::getByUserName($username);
|
||||
if(empty($member)){
|
||||
session('loginError','用户名错误');
|
||||
return $this->redirect($loginUrl);
|
||||
}
|
||||
if($member['password'] != md5($password)){
|
||||
session('loginError','用户密码错误');
|
||||
return $this->redirect($loginUrl);
|
||||
|
||||
}
|
||||
$rulesList = AuthRule::userRolesList($member['group_id']);
|
||||
$rulesIdStr = '';
|
||||
if (!empty($rulesList)) {
|
||||
$rulesId = $rulesList['allRulesId'];
|
||||
$rulesIdStr = implode(',', $rulesId);
|
||||
}
|
||||
|
||||
$authSession = [
|
||||
'userId' => $member['id'],
|
||||
'userName' => $member['username'],
|
||||
'groupId' => $member['group_id'],
|
||||
'rules' => $rulesIdStr,
|
||||
'cates' => $member['cates']
|
||||
];
|
||||
|
||||
//记录最后登陆时间
|
||||
$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', $authSession);
|
||||
return redirect(url('manager.index/index'));
|
||||
}
|
||||
|
||||
$viewData = [];
|
||||
if(session('?loginError')) {
|
||||
$viewData['error'] = session('loginError');
|
||||
}
|
||||
session('loginError', null);
|
||||
return view()->assign($viewData);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
namespace app\controller\manager;
|
||||
|
||||
use app\controller\BaseController;
|
||||
|
||||
class Logout extends BaseController
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
session(null);
|
||||
return redirect(url('manager.login/index'));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,181 @@
|
|||
<?php
|
||||
namespace app\controller\manager;
|
||||
|
||||
use app\model\{Category, AuthGroup, Member as MMember, Log};
|
||||
use Exception;
|
||||
use think\facade\Db;
|
||||
|
||||
class Member extends Base
|
||||
{
|
||||
/**
|
||||
* 删除管理用户
|
||||
*/
|
||||
public function del()
|
||||
{
|
||||
if ($this->request->isPost()) {
|
||||
$id = input('post.id/d');
|
||||
if (is_numeric($id) === true && $id > 0) {
|
||||
$item = MMember::getByID($id);
|
||||
if(!empty($item)){
|
||||
MMember::destroy($id);
|
||||
Log::write('member', 'del', "管理员删除,ID:{$id}, 管理员:{$item['username']}");
|
||||
return $this->json();
|
||||
}
|
||||
}
|
||||
return $this->json(2, '参数错误,请核对之后再操作!');
|
||||
}
|
||||
return $this->json(1, '非法请求!');
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改管理用户信息
|
||||
* 由于try语法中抛出的异常类型与$this->json()抛出的异常类型不一致,因此需要利用$errorMsg 来判断返回情况
|
||||
*/
|
||||
public function edit()
|
||||
{
|
||||
if($this->request->isPost()){
|
||||
$id = input('post.id/d');
|
||||
$username = trim(input('post.username'));
|
||||
$password = trim(input('post.password'));
|
||||
$groupId = input('post.group_id/d');
|
||||
if ((is_numeric($id) === true && $id > 0) && ((is_numeric($groupId) === true && $groupId > 0) && !empty($username))) {
|
||||
$member = MMember::getByUserName($username);
|
||||
if(!empty($member) && $member['id'] != $id){
|
||||
return $this->json(2, '该用户名已被使用!');
|
||||
}
|
||||
$errorMsg = '';
|
||||
Db::startTrans();
|
||||
try {
|
||||
$member = MMember::getById($id);
|
||||
$item = [
|
||||
'username' => $username,
|
||||
'group_id' => $groupId
|
||||
];
|
||||
//角色权限重新赋值
|
||||
$group = AuthGroup::getById($groupId);
|
||||
$item['rules'] = $group['rules'];
|
||||
|
||||
if(!empty($password)){
|
||||
$item['password'] = md5($password);
|
||||
}
|
||||
MMember::updateById($id, $item);
|
||||
Log::write('member', 'edit', "管理员编辑,ID:{$id}, 管理员:{$item['username']}");
|
||||
Db::commit();
|
||||
} catch (Exception $e) {
|
||||
Db::rollback();
|
||||
$errorMsg = '用户信息修改失败!'.$e->getMessage();
|
||||
}
|
||||
if (empty($errorMsg)) {
|
||||
return $this->json();
|
||||
}
|
||||
return $this->json(3, $errorMsg);
|
||||
}
|
||||
return $this->json(1, '参数错误,请核对之后再操作!');
|
||||
}else{
|
||||
$id = input('param.id/d');
|
||||
if (is_numeric($id) === true && $id > 0) {
|
||||
$member = MMember::getByID($id);
|
||||
$item = [
|
||||
'id' => $member['id'],
|
||||
'username' => $member['username'],
|
||||
'group_id' => $member['group_id']
|
||||
];
|
||||
$auth = session('auth');
|
||||
$groups = AuthGroup::getListById($auth['groupId']);
|
||||
$this->data['groups'] = $groups;
|
||||
$this->data['item'] = $item;
|
||||
return $this->view();
|
||||
}
|
||||
return $this->json(1, '参数错误,请核对之后再操作!');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增管理用户
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
if($this->request->isPost()){
|
||||
$groupId = input('post.group_id/d');
|
||||
$username = trim(input('post.username'));
|
||||
$password = trim(input('post.password'));
|
||||
if ((is_numeric($groupId) === true && $groupId > 0) && ($username != "" && $password != "")) {
|
||||
$member = MMember::getByUserName($username);
|
||||
if(!empty($member)){
|
||||
return $this->json(2, '该用户名已被使用!');
|
||||
}
|
||||
$group = AuthGroup::getById($groupId);
|
||||
$newMember = MMember::create([
|
||||
'username' => $username,
|
||||
'group_id' => $groupId,
|
||||
'password' => md5($password),
|
||||
'rules' => $group['rules'] ?? '',
|
||||
'cates' => '',
|
||||
'login_time' => 0,
|
||||
]);
|
||||
Log::write('member', 'add', "管理员新增,ID:{$newMember->id}, 管理员:{$newMember['username']}");
|
||||
return $this->json();
|
||||
}
|
||||
return $this->json(1, '参数错误,请核对之后再操作!');
|
||||
}
|
||||
|
||||
$auth = session('auth');
|
||||
$groups = AuthGroup::getListById($auth['groupId']);
|
||||
$this->data['groups'] = $groups;
|
||||
return $this->view();
|
||||
}
|
||||
|
||||
/**
|
||||
* 栏目菜单分配
|
||||
*/
|
||||
public function menuAlloter()
|
||||
{
|
||||
if(request()->isPost()) {
|
||||
$cates = input('post.cates/a');
|
||||
$id = input('post.id/d');
|
||||
if (is_array($cates) && (is_numeric($id) === true && $id > 0)) {
|
||||
$member = MMember::getById($id);
|
||||
if(empty($member)){
|
||||
return $this->json(2, '无此用户信息,请核对之后再操作!');
|
||||
}
|
||||
MMember::updateCates($id, $cates);
|
||||
Log::write('member', 'menuAlloter', "管理员栏目分配,ID:{$id}, 管理员:{$member['username']}");
|
||||
return $this->json();
|
||||
}else{
|
||||
return $this->json(3, '传入参数错误,请核对之后再操作!');
|
||||
}
|
||||
} else {
|
||||
$id = input('param.id/d');
|
||||
if (is_numeric($id) && $id > 0) {
|
||||
$member = MMember::getById($id);
|
||||
if (empty($member)) {
|
||||
return $this->json(2, '该管理员信息不存在,请核对之后再操作!');
|
||||
}
|
||||
$cates = Category::getListTree(false);
|
||||
$memberCates = array_filter(explode(',', $member['cates']));
|
||||
|
||||
$this->data['id'] = $id;
|
||||
$this->data['member'] = $member;
|
||||
$this->data['memberCates'] = $memberCates;
|
||||
$this->data['cates'] = $cates;
|
||||
return $this->view();
|
||||
}
|
||||
return $this->json(1, '参数错误,请核对之后再操作!',$id);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 所有用户列表
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$auth = session('auth');
|
||||
if ($auth['groupId'] == 1) {
|
||||
$items = MMember::getList(40);
|
||||
} else {
|
||||
$items = MMember::getListNotAdmin(40);
|
||||
}
|
||||
$this->data['items'] = $items;
|
||||
return $this->view();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,141 @@
|
|||
<?php
|
||||
namespace app\controller\manager;
|
||||
|
||||
use app\model\{Message as MMessage, Log};
|
||||
use app\service\Tool;
|
||||
use app\service\File;
|
||||
use PhpOffice\PhpSpreadsheet\Cell\DataType;
|
||||
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||||
use PhpOffice\PhpSpreadsheet\Style\Alignment;
|
||||
use PhpOffice\PhpSpreadsheet\Style\Border;
|
||||
|
||||
class Message extends Base
|
||||
{
|
||||
protected $excelStyle = [
|
||||
'font' => [
|
||||
'name' => '宋体',
|
||||
],
|
||||
'alignment' => [
|
||||
'horizontal' => Alignment::HORIZONTAL_CENTER, // 水平居中
|
||||
'vertical' => Alignment::VERTICAL_CENTER, // 垂直居中
|
||||
'wrapText' => true,
|
||||
],
|
||||
'borders' => [
|
||||
'allBorders' => [
|
||||
'borderStyle' => Border::BORDER_THIN,
|
||||
'color' => ['rgb' => 'eeeeee'],
|
||||
]
|
||||
],
|
||||
];
|
||||
|
||||
protected $defaultSetting = [
|
||||
'cell_width' => 30,
|
||||
'font_size' => 12
|
||||
];
|
||||
|
||||
//下载文件
|
||||
public function file()
|
||||
{
|
||||
$id = input('param.id/d');
|
||||
if(is_numeric($id) && $id > 0) {
|
||||
$item = MMessage::getById($id);
|
||||
if(empty($item)){
|
||||
return $this->error('留言不存在');
|
||||
}
|
||||
if(empty($item['file'])){
|
||||
return $this->error('无文件需要下载');
|
||||
}
|
||||
$file = app()->getRootPath() . 'public' . $item['file'];
|
||||
if(!file_exists($file)){
|
||||
return $this->error('无文件需要下载');
|
||||
}
|
||||
$fileInfo = pathinfo($file);
|
||||
$fileName = $item['name'] . '上传文件.' . $fileInfo['extension'];
|
||||
$fileSize = filesize($file);
|
||||
|
||||
//以只读和二进制模式打开文件
|
||||
$file = fopen ( $file, "rb" );
|
||||
|
||||
//告诉浏览器这是一个文件流格式的文件
|
||||
Header ( "Content-type: application/octet-stream" );
|
||||
//请求范围的度量单位
|
||||
Header ( "Accept-Ranges: bytes" );
|
||||
//Content-Length是指定包含于请求或响应中数据的字节长度
|
||||
Header ( "Accept-Length: " . $fileSize );
|
||||
//用来告诉浏览器,文件是可以当做附件被下载,下载后的文件名称为$file_name该变量的值。
|
||||
Header ( "Content-Disposition: attachment; filename=" . $fileName );
|
||||
|
||||
//读取文件内容并直接输出到浏览器
|
||||
echo fread ( $file, $fileSize );
|
||||
fclose ( $file );
|
||||
exit ();
|
||||
}
|
||||
return $this->error('参数错误,请核对之后再操作!');
|
||||
}
|
||||
//可以删除一个
|
||||
public function del()
|
||||
{
|
||||
if ($this->request->isPost()) {
|
||||
$id = input('post.id/d');
|
||||
if(is_numeric($id) && $id > 0) {
|
||||
$item = MMessage::getById($id);
|
||||
if(!empty($item)){
|
||||
MMessage::destroy($id);
|
||||
if(!empty($item['file'])){
|
||||
Tool::delFile($item['file']);
|
||||
}
|
||||
Log::write('link', 'del', '删除留言,ID:' . $id . ',姓名:' . $item['name']);
|
||||
return $this->json();
|
||||
}
|
||||
return $this->json(3, '待删除留言不存在');
|
||||
}
|
||||
return $this->json(2, '参数错误,请核对之后再操作!');
|
||||
}
|
||||
return $this->json(1, '非法请求!');
|
||||
}
|
||||
|
||||
//列表
|
||||
public function index()
|
||||
{
|
||||
$startDate = input('param.startDate', '');
|
||||
$endDate = input('param.endDate', '');
|
||||
|
||||
$items = MMessage::getList(20, $startDate, $endDate);
|
||||
$this->data['items'] = $items;
|
||||
$this->data['startDate'] = $startDate;
|
||||
$this->data['endDate'] = $endDate;
|
||||
return $this->view();
|
||||
}
|
||||
|
||||
// 导出留言
|
||||
public function export()
|
||||
{
|
||||
File::cancelTimeLimit();
|
||||
|
||||
$startDate = input('param.startDate', '');
|
||||
$endDate = input('param.endDate', '');
|
||||
$list = MMessage::getExportList($startDate, $endDate, 10000);
|
||||
|
||||
$spreadsheet = new Spreadsheet();
|
||||
$header = ['序号', '姓名', '电话', '公司/团队名称', '申请日期'];
|
||||
|
||||
$sheet = $spreadsheet->getActiveSheet();
|
||||
$sheetTitle = '预约记录';
|
||||
$cellValues = [];
|
||||
$cellWidthList = [];
|
||||
|
||||
foreach ($list as $item) {
|
||||
$cellValues[] = [
|
||||
[$item['id'], DataType::TYPE_STRING],
|
||||
$item['name'],
|
||||
$item['tel'],
|
||||
$item['company'],
|
||||
date('Y-m-d H:i', $item['create_time']),
|
||||
];
|
||||
}
|
||||
|
||||
File::setExcelCells($sheet, $cellValues, $header, $sheetTitle, $cellWidthList, $this->excelStyle, $this->defaultSetting);
|
||||
File::export($spreadsheet, '预约记录导出_' . date('YmdHis') . '.xlsx');
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,184 @@
|
|||
<?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 batchDel()
|
||||
{
|
||||
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', 'batchDel', "模型批量删除,ID:" . implode(',', $ids));
|
||||
return $this->json();
|
||||
}
|
||||
return $this->json(2, '无效请求,参数错误!');
|
||||
}
|
||||
return $this->json(1, '非法请求!');
|
||||
}
|
||||
|
||||
//删除单个模型
|
||||
public function del()
|
||||
{
|
||||
if($this->request->isPost()){
|
||||
$id = input('post.id/d');
|
||||
if(is_numeric($id) && $id > 0) {
|
||||
$item = MModel::getById($id);
|
||||
if(!empty($item)) {
|
||||
MModel::destroy($id);
|
||||
Log::write('model', 'del', "模型删除,ID:{$id}, 标题:{$item['name']}");
|
||||
return $this->json();
|
||||
}
|
||||
return $this->json(3, '删除失败!该模型不存在,请刷新页面后再试!');
|
||||
}
|
||||
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,672 @@
|
|||
<?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(strip_tags($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(array_values($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();
|
||||
}
|
||||
}
|
||||
|
||||
//音频组
|
||||
public function audios()
|
||||
{
|
||||
if ($this->request->isPost()) {
|
||||
$item = input('post.item/a');
|
||||
$audios = input('post.audios/a');
|
||||
$categoryId = input('post.category_id/d');
|
||||
if (!empty($audios) && is_array($audios)) {
|
||||
$item['value'] = json_encode(array_values($audios));
|
||||
} 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::AUDIOS;
|
||||
$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;
|
||||
$this->data['groupId'] = session('auth.groupId');
|
||||
return $this->view();
|
||||
}
|
||||
}
|
||||
|
||||
//视频组
|
||||
public function videos()
|
||||
{
|
||||
if ($this->request->isPost()) {
|
||||
$item = input('post.item/a');
|
||||
$videos = input('post.videos/a');
|
||||
$categoryId = input('post.category_id/d');
|
||||
if (!empty($videos) && is_array($videos)) {
|
||||
$item['value'] = json_encode(array_values($videos));
|
||||
} 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::VIDEOS;
|
||||
$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;
|
||||
$this->data['groupId'] = session('auth.groupId');
|
||||
return $this->view();
|
||||
}
|
||||
}
|
||||
|
||||
//地图
|
||||
public function map()
|
||||
{
|
||||
if ($this->request->isPost()) {
|
||||
$item = input('post.item/a');
|
||||
$item["value"] = json_encode(input('post.value/a'), JSON_UNESCAPED_UNICODE);
|
||||
$item["type"] = Block::MAP;
|
||||
$categoryId = input('post.category_id/d');
|
||||
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::MAP;
|
||||
$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'];
|
||||
$item["value"] = json_decode($item["value"], true);
|
||||
$this->data['item'] = $item;
|
||||
}
|
||||
$this->data['categoryId'] = $categoryId;
|
||||
$this->data['groupId'] = session('auth.groupId');
|
||||
$this->data['mapType'] = Block::$mapType;
|
||||
return $this->view();
|
||||
}
|
||||
}
|
||||
|
||||
public function mapPlugin()
|
||||
{
|
||||
$data= [
|
||||
"lng"=>input("lng",""),
|
||||
"lat"=>input("lat",""),
|
||||
];
|
||||
return view("/manager/map_plugin/" . input("template", "gaode"))->assign($data);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,145 @@
|
|||
<?php
|
||||
|
||||
namespace app\controller\manager;
|
||||
|
||||
use app\validate\PositionValidate;
|
||||
use app\model\{PositionModel, Category as MCategory, Log as MLog, System};
|
||||
use think\exception\ValidateException;
|
||||
use think\response\Json;
|
||||
use think\response\View;
|
||||
|
||||
/**
|
||||
* 招聘职位
|
||||
* Class Position
|
||||
* @package app\controller\manager
|
||||
*/
|
||||
class Position extends Base
|
||||
{
|
||||
/**
|
||||
* @return Json|View
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
if (request()->isPost()) {
|
||||
$params = input('post.item/a', []);
|
||||
$params['create_time'] = time();
|
||||
try {
|
||||
validate(PositionValidate::class)->check($params);
|
||||
$newItem = PositionModel::create($params);
|
||||
MLog::write('position', 'add', '新增职位,ID:'.$newItem->id);
|
||||
} catch (ValidateException $e) {
|
||||
return $this->json(1, $e->getError());
|
||||
}
|
||||
return $this->json();
|
||||
} else {
|
||||
$categoryId = input('param.category_id/d', 0);
|
||||
$category = MCategory::getById($categoryId);
|
||||
|
||||
$this->data['category'] = $category;
|
||||
return $this->view();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Json|View
|
||||
*/
|
||||
public function edit()
|
||||
{
|
||||
$id = input('param.id/d', 0);
|
||||
$item = PositionModel::getById($id);
|
||||
if (count($item) == 0) {
|
||||
return $this->json(1, '该职位不存在');
|
||||
}
|
||||
if (request()->isPost()) {
|
||||
$params = input('post.item/a', []);
|
||||
try {
|
||||
validate(PositionValidate::class)->check($params);
|
||||
PositionModel::updateById($id, $params);
|
||||
MLog::write('position', 'edit', '修改职位,ID:'.$id);
|
||||
} catch (ValidateException $e) {
|
||||
return $this->json(2, $e->getError());
|
||||
}
|
||||
return $this->json();
|
||||
} else {
|
||||
$this->data['item'] = $item;
|
||||
return $this->view();
|
||||
}
|
||||
}
|
||||
|
||||
public function sort()
|
||||
{
|
||||
if (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 = PositionModel::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 = PositionModel::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 PositionModel();
|
||||
$model->saveAll($updateData);
|
||||
$sortStr = $sort == 'up' ? '上移' : '下调';
|
||||
MLog::write('position', 'sort', "职位排序,ID:{$id} ,{$sortStr}了{$num}位");
|
||||
return $this->json();
|
||||
}
|
||||
}
|
||||
return $this->json(4, '无须调整排序!');
|
||||
}
|
||||
return $this->json(1, '无此操作');
|
||||
}
|
||||
|
||||
// 删除
|
||||
public function del()
|
||||
{
|
||||
if (request()->isPost()) {
|
||||
$historyId = input('param.id/d', 0);
|
||||
$item = PositionModel::getById($historyId);
|
||||
if (count($item) == 0) {
|
||||
return $this->json(2, '该职位不存在');
|
||||
}
|
||||
try {
|
||||
PositionModel::destroy($historyId);
|
||||
MLog::write('position', 'del', '删除职位,ID:'.$historyId);
|
||||
} catch (\Exception $e) {
|
||||
return $this->json(3, '删除失败,'.$e->getMessage());
|
||||
}
|
||||
return $this->json();
|
||||
}
|
||||
return $this->json(1, '无此操作');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,167 @@
|
|||
<?php
|
||||
|
||||
namespace app\controller\manager;
|
||||
|
||||
use app\validate\ProductValidate;
|
||||
use app\model\{ProductModel, Category as MCategory, Log as MLog, System};
|
||||
use think\exception\ValidateException;
|
||||
use think\response\Json;
|
||||
use think\response\View;
|
||||
|
||||
/**
|
||||
* 产品
|
||||
* Class Honour
|
||||
* @package app\controller\manager
|
||||
*/
|
||||
class Product extends Base
|
||||
{
|
||||
/**
|
||||
* @return Json|View
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
if (request()->isPost()) {
|
||||
$images = input('img_images/a');
|
||||
$params = input('post.item/a', []);
|
||||
$params['image'] = input('img');
|
||||
$params['images'] = json_encode($images, JSON_UNESCAPED_UNICODE);
|
||||
$params['qr'] = input('img_qr');
|
||||
try {
|
||||
validate(ProductValidate::class)->check($params);
|
||||
$newItem = ProductModel::create($params);
|
||||
MLog::write('honour', 'add', '新增产品,ID:'.$newItem->id);
|
||||
} catch (ValidateException $e) {
|
||||
return $this->json(1, $e->getError());
|
||||
}
|
||||
return $this->json();
|
||||
} else {
|
||||
$categoryId = input('param.category_id/d', 0);
|
||||
$category = MCategory::getById($categoryId);
|
||||
|
||||
if (count($category) > 0 && $category['img_width'] && $category['img_height']) {
|
||||
$imgSize = $category['img_width'].'像素 X '.$category['img_height'].'像素';
|
||||
} else {
|
||||
$imgSize = System::getArticleImageSize();
|
||||
}
|
||||
|
||||
$this->data['imgSize'] = $imgSize;
|
||||
$this->data['category'] = $category;
|
||||
return $this->view();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Json|View
|
||||
*/
|
||||
public function edit()
|
||||
{
|
||||
$id = input('param.id/d', 0);
|
||||
$item = ProductModel::getById($id);
|
||||
if (count($item) == 0) {
|
||||
return $this->json(1, '该产品不存在');
|
||||
}
|
||||
if (request()->isPost()) {
|
||||
$params = input('post.item/a', []);
|
||||
$params['image'] = input('img');
|
||||
$params['qr'] = input('img_qr');
|
||||
$params['images'] = json_encode(array_values(input('img_images/a')), JSON_UNESCAPED_UNICODE);
|
||||
try {
|
||||
validate(ProductValidate::class)->check($params);
|
||||
ProductModel::updateById($id, $params);
|
||||
MLog::write('honour', 'edit', '修改产品,ID:'.$id);
|
||||
} catch (ValidateException $e) {
|
||||
return $this->json(2, $e->getError());
|
||||
}
|
||||
return $this->json();
|
||||
} else {
|
||||
$category = MCategory::getById($item['category_id']);
|
||||
|
||||
if (count($category) > 0 && $category['img_width'] && $category['img_height']) {
|
||||
$imgSize = $category['img_width'].'像素 X '.$category['img_height'].'像素';
|
||||
} else {
|
||||
$imgSize = System::getArticleImageSize();
|
||||
}
|
||||
|
||||
$this->data['imgSize'] = $imgSize;
|
||||
$this->data['item'] = $item;
|
||||
return $this->view();
|
||||
}
|
||||
}
|
||||
|
||||
public function sort()
|
||||
{
|
||||
if (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 = ProductModel::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 = ProductModel::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 ProductModel();
|
||||
$model->saveAll($updateData);
|
||||
$sortStr = $sort == 'up' ? '上移' : '下调';
|
||||
MLog::write('history', 'sort', "产品排序,ID:{$id} ,{$sortStr}了{$num}位");
|
||||
return $this->json();
|
||||
}
|
||||
}
|
||||
return $this->json(4, '无须调整排序!');
|
||||
}
|
||||
return $this->json(1, '无此操作');
|
||||
}
|
||||
|
||||
// 删除
|
||||
public function del()
|
||||
{
|
||||
if (request()->isPost()) {
|
||||
$historyId = input('param.id/d', 0);
|
||||
$item = ProductModel::getById($historyId);
|
||||
if (count($item) == 0) {
|
||||
return $this->json(2, '该产品不存在');
|
||||
}
|
||||
try {
|
||||
ProductModel::destroy($historyId);
|
||||
MLog::write('honour', 'del', '删除产品,ID:'.$historyId);
|
||||
} catch (\Exception $e) {
|
||||
return $this->json(3, '删除失败,'.$e->getMessage());
|
||||
}
|
||||
return $this->json();
|
||||
}
|
||||
return $this->json(1, '无此操作');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,181 @@
|
|||
<?php
|
||||
namespace app\controller\manager;
|
||||
|
||||
use app\model\{AuthRule, AuthGroup, Log};
|
||||
use app\validate\AuthRule as VAuthRule;
|
||||
use think\exception\ValidateException;
|
||||
|
||||
class Rule extends Base
|
||||
{
|
||||
/**
|
||||
* 权限排序
|
||||
* 暂不允许父级变更
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
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' ? '上移' : '下调';
|
||||
AuthGroup::resetGroupRulesCache();
|
||||
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()) {
|
||||
$id = input('post.id/d');
|
||||
$item = AuthRule::getById($id);
|
||||
if(empty($item)){
|
||||
return $this->json(1, '无此权限');
|
||||
}
|
||||
$children = AuthRule::getListByParentId($id);
|
||||
if(!empty($children)){
|
||||
return $this->json(2, '当前权限有下级权限,不可删除');
|
||||
}
|
||||
AuthRule::destroy($id);
|
||||
AuthGroup::resetGroupRulesCache();
|
||||
Log::write('rule', 'del', "权限删除,ID:{$id}, 标题:{$item['title']}");
|
||||
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,70 @@
|
|||
<?php
|
||||
namespace app\controller\manager;
|
||||
|
||||
use app\service\Jwt;
|
||||
use app\model\{Member, Log};
|
||||
use think\response\Json;
|
||||
use think\response\View;
|
||||
|
||||
class Safe extends Base
|
||||
{
|
||||
/**
|
||||
* 安全设置
|
||||
* @return View|Json
|
||||
*/
|
||||
|
||||
public function index()
|
||||
{
|
||||
$auth = session('auth');
|
||||
if($this->request->isPost()){
|
||||
if ($auth) {
|
||||
$authId = $auth['userId'];
|
||||
$oldPassword = trim(input('post.password_old'));
|
||||
$password = trim(input('post.password'));
|
||||
$passwordAgain = trim(input('post.password_again'));
|
||||
$name = trim(input('post.name'));
|
||||
|
||||
$user = Member::getByID($authId);
|
||||
if (empty($user)) {
|
||||
return $this->json(1, '登录失效,请重新登录后再试!');
|
||||
}
|
||||
if (empty($name)) {
|
||||
return $this->json(2, '用户名不能为空!');
|
||||
}
|
||||
$hasUser = Member::getByUserName($name);
|
||||
if (!empty($hasUser) && $hasUser['id'] != $authId) {
|
||||
return $this->json(3, '该用户名已被其他用户使用,请更换!');
|
||||
}
|
||||
if (empty($password) || empty($oldPassword)) {
|
||||
return $this->json(4, '用户密码不能为空!');
|
||||
}
|
||||
if ($password != $passwordAgain) {
|
||||
return $this->json(5, '新密码两次输入不一致!');
|
||||
}
|
||||
if (mb_strlen($password) < 6 || mb_strlen($password) > 30) {
|
||||
return $this->json(6, '新密码长度格式不正确,请输入6~30位密码!');
|
||||
}
|
||||
if ($user['password'] != md5($oldPassword)) {
|
||||
return $this->json(7,'原密码不正确');
|
||||
}
|
||||
$data['password'] = md5($password);
|
||||
Member::updateById($authId, $data);
|
||||
Log::write('safe', 'index', "安全设置,ID:{$authId}, 管理员:{$name}");
|
||||
session('auth', null);
|
||||
//cache('rules_'.$authId, null); //当前看代码,这个是无用代码;先注释掉,如果在使用过程中不会用到,再删除。
|
||||
cache('group_rules_'.$authId, null);
|
||||
cache('rule_names_'.$authId, null);
|
||||
return $this->json(0, '修改成功,请重新登录!');
|
||||
} else {
|
||||
return $this->json(1, '登录失效,请重新登录后再试!');
|
||||
}
|
||||
}else{
|
||||
$this->data['item'] = $auth;
|
||||
$jwtData = [
|
||||
'member_id' => $auth["userId"],
|
||||
];
|
||||
$this->data["token"] = Jwt::generate($jwtData);
|
||||
return $this->view();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,190 @@
|
|||
<?php
|
||||
namespace app\controller\manager;
|
||||
|
||||
use app\model\{Slide as MSlide, System, Log};
|
||||
use app\validate\Slide as VSlide;
|
||||
use think\exception\ValidateException;
|
||||
|
||||
class Slide extends Base
|
||||
{
|
||||
//批量删除
|
||||
public function batchDel()
|
||||
{
|
||||
if ($this->request->isPost()) {
|
||||
$ids = input('post.ids/a');
|
||||
if(empty($ids) || !is_array($ids)) {
|
||||
return $this->json(2, '参数错误,请核对之后再操作!');
|
||||
}
|
||||
$items = MSlide::getListByIds($ids);
|
||||
if(!empty($items)){
|
||||
$delIds = [];
|
||||
foreach($items as $item){
|
||||
$delIds[] = $item['id'];
|
||||
}
|
||||
MSlide::destroy($delIds);
|
||||
Log::write('link', 'betchDel', '批量删除了友情链接,涉及到的ID为:' . implode(',', $delIds));
|
||||
return $this->json();
|
||||
}else{
|
||||
return $this->json(3, '待删除友情链接为空');
|
||||
}
|
||||
}
|
||||
return $this->json(1, '非法请求!');
|
||||
}
|
||||
//可以删除一个,可以批量删除,TODO 需要调整
|
||||
public function del()
|
||||
{
|
||||
if ($this->request->isPost()) {
|
||||
$id = input('post.id/d');
|
||||
if(is_numeric($id) && $id > 0) {
|
||||
$item = MSlide::getById($id);
|
||||
if(!empty($item)){
|
||||
MSlide::destroy($id);
|
||||
Log::write('link', 'del', '删除轮播图,ID:' . $id . ',标题:' . $item['title']);
|
||||
return $this->json();
|
||||
}
|
||||
return $this->json(3, '待删除轮播图不存在');
|
||||
}
|
||||
return $this->json(2, '参数错误,请核对之后再操作!');
|
||||
}
|
||||
return $this->json(1, '非法请求!');
|
||||
}
|
||||
//排序
|
||||
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 = MSlide::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 = MSlide::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 MSlide();
|
||||
$model->saveAll($updateData);
|
||||
$sortStr = $sort == 'up' ? '上移' : '下调';
|
||||
Log::write('slide', 'sort', "轮播图排序,ID:{$id} ,标题:{$item['title']},{$sortStr}了{$num}位");
|
||||
return $this->json();
|
||||
}
|
||||
}
|
||||
return $this->json(4, '无须调整排序!');
|
||||
}
|
||||
return $this->json(1, '非法请求!');
|
||||
}
|
||||
|
||||
//编辑
|
||||
public function edit()
|
||||
{
|
||||
if($this->request->isPost()){
|
||||
$item = input('post.item');
|
||||
$img = input('post.img');
|
||||
$img_mobile = input('post.img_mobile');
|
||||
$id = input('post.id/d');
|
||||
|
||||
if(is_numeric($id) && $id > 0) {
|
||||
$slide = MSlide::getById($id);
|
||||
if(empty($slide)) {
|
||||
return $this->json(2, 'id参数错误,没有相关轮播图信息记录!');
|
||||
}
|
||||
if(!empty($img)){
|
||||
$item['src'] = $img;
|
||||
}
|
||||
if(!empty($img_mobile)){
|
||||
$item['src_mobile'] = $img_mobile;
|
||||
}
|
||||
try {
|
||||
validate(VSlide::class)->check($item);
|
||||
MSlide::updateById($id, $item);
|
||||
Log::write('slide', 'edit', "轮播图编辑,ID:{$id} ,标题:{$item['title']}");
|
||||
return $this->json();
|
||||
} catch (ValidateException $e) {
|
||||
return $this->json(3, $e->getError());
|
||||
}
|
||||
}
|
||||
return $this->json(1, '参数错误,请核对之后再操作!');
|
||||
}else{
|
||||
$id = input('param.id/d');
|
||||
$item = MSlide::getById($id);
|
||||
$imgSize = System::getSlideImageSize();
|
||||
$this->data['item'] = $item;
|
||||
$this->data['img_size'] = $imgSize;
|
||||
return $this->view();
|
||||
}
|
||||
}
|
||||
|
||||
//添加
|
||||
public function add()
|
||||
{
|
||||
if($this->request->isPost()){
|
||||
$item = input('post.item');
|
||||
$img = input('post.img');
|
||||
$img_mobile = input('post.img_mobile');
|
||||
if (empty($item)) {
|
||||
return $this->json(1, '参数错误,请核对之后再操作!');
|
||||
}
|
||||
if(!empty($img)){
|
||||
$item['src'] = $img;
|
||||
}
|
||||
if(!empty($img_mobile)){
|
||||
$item['src_mobile'] = $img_mobile;
|
||||
}
|
||||
try {
|
||||
validate(VSlide::class)->check($item);
|
||||
$slide = MSlide::create($item);
|
||||
Log::write('slide', 'add', "轮播图新增,ID:{$slide->id} ,标题:{$item['title']}");
|
||||
return $this->json();
|
||||
} catch (ValidateException $e) {
|
||||
return $this->json(2,$e->getError());
|
||||
}
|
||||
}else{
|
||||
$this->data['img_size'] = System::getSlideImageSize();
|
||||
return $this->view();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 列表
|
||||
* 暂定只有首页轮播图,后期可以根据需求进行分组管理
|
||||
* @return Slide
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$items = MSlide::getList();
|
||||
$this->data['items'] = $items;
|
||||
return $this->view();
|
||||
}
|
||||
}
|
|
@ -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,64 @@
|
|||
<?php
|
||||
namespace app\controller\manager;
|
||||
|
||||
use app\model\ArticleTags;
|
||||
use think\Exception;
|
||||
use think\exception\ValidateException;
|
||||
|
||||
/**
|
||||
* 标签管理
|
||||
*
|
||||
* Class Tag
|
||||
* @package app\controller\manager
|
||||
*/
|
||||
class Tag extends Base
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
$whereMap = [];
|
||||
$paginateRows = [
|
||||
'list_rows' => 30,
|
||||
'query' => [],
|
||||
];
|
||||
|
||||
$this->data['items'] = ArticleTags::getListWithPaginate($whereMap, $paginateRows, false);
|
||||
return $this->view();
|
||||
}
|
||||
|
||||
|
||||
public function edit()
|
||||
{
|
||||
$id = $this->request->param('id/d', 0);
|
||||
$tagInfo = ArticleTags::findInfoById($id);
|
||||
if (empty($tagInfo)) {
|
||||
return $this->json(4004, '没有相关的记录');
|
||||
}
|
||||
|
||||
if ($this->request->isPost()) {
|
||||
$itemData = $this->request->param('item/a', []);
|
||||
if (isset($itemData['id'])) {
|
||||
unset($itemData['id']);
|
||||
}
|
||||
|
||||
try {
|
||||
$this->validate($itemData, [
|
||||
'seo_title|SEO标题' => 'max:100',
|
||||
'seo_keyword|SEO关键词' => 'max:200',
|
||||
'seo_description|SEO描述' => 'max:200',
|
||||
]);
|
||||
$tagInfo->save($itemData);
|
||||
} catch (ValidateException $e) {
|
||||
return $this->json(4001, $e->getError());
|
||||
} catch (Exception $e) {
|
||||
return $this->json(5001, '系统繁忙,修改失败!');
|
||||
}
|
||||
|
||||
return $this->json(0, '修改成功!');
|
||||
}
|
||||
|
||||
$this->data['id'] = $id;
|
||||
$this->data['item'] = $tagInfo;
|
||||
return $this->view();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,211 @@
|
|||
<?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;
|
||||
use think\image\Exception as ImageException;
|
||||
|
||||
class Upload extends BaseController
|
||||
{
|
||||
private $isCompress = true;
|
||||
private $validate;
|
||||
private $uploadPath;
|
||||
private $uploadPathIsWritable = 0;
|
||||
|
||||
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');
|
||||
if(is_writable(app()->getRootPath() . 'public' . $this->uploadPath)){
|
||||
$this->uploadPathIsWritable = 1;
|
||||
}
|
||||
}
|
||||
|
||||
//视频上传
|
||||
public function video()
|
||||
{
|
||||
if(!$this->uploadPathIsWritable){
|
||||
return $this->json(1, '上传文件夹需要写入权限');
|
||||
}
|
||||
$video = request()->file('video');
|
||||
if($this->validate->checkVideo($video)){
|
||||
$src = Filesystem::disk('video')->putFile(date('Ymd'), $video, 'uniqid');
|
||||
$src = $this->uploadPath . '/' . $src;
|
||||
$return['src'] = $src;
|
||||
//加入上传文件表
|
||||
$newFile = File::add($video, $src, 'video');
|
||||
$return['fid'] = $newFile->id;
|
||||
return $this->json(0, 'ok', $return);
|
||||
}else{
|
||||
$errorMsg = Lang::get($this->validate->getError());
|
||||
return $this->json(1, $errorMsg);
|
||||
}
|
||||
}
|
||||
|
||||
//音频上传
|
||||
public function audio()
|
||||
{
|
||||
if(!$this->uploadPathIsWritable){
|
||||
return $this->json(1, '上传文件夹需要写入权限');
|
||||
}
|
||||
$audio = request()->file('audio');
|
||||
if($this->validate->checkFile($audio)){
|
||||
$src = Filesystem::disk('audio')->putFile(date('Ymd'), $audio, 'uniqid');
|
||||
$src = $this->uploadPath . '/' . $src;
|
||||
$return['src'] = $src;
|
||||
File::add($audio, $src, 'audio'); //加入上传文件表
|
||||
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');
|
||||
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(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 = request()->file('image');
|
||||
// $md5 = $image->md5();//文件md5
|
||||
|
||||
if($this->validate->checkImage($image)){
|
||||
// if ($fileItem = File::where('md5', $md5)->find()) {
|
||||
// $return['src'] = $fileItem['src'];
|
||||
// $fileItem['updated_at'] = date('Y-m-d H:i:s');
|
||||
// return $this->json(0, '该文件已存在 路径为:'.$fileItem['src'], $return);
|
||||
// }
|
||||
try{
|
||||
if(!$this->uploadPathIsWritable){
|
||||
throw new \Exception('上传文件夹需要写入权限');
|
||||
}
|
||||
$src = Filesystem::putFile(date('Ymd'), $image, 'uniqid');
|
||||
|
||||
$src = $this->uploadPath . '/' . $src;
|
||||
// $suffix = strtolower($image->getOriginalExtension());
|
||||
// if($suffix == 'gif'){
|
||||
// $return['thumb_src'] = $src; //TODO获取GIF缩略图
|
||||
// }else{
|
||||
// $return['thumb_src'] = Image::getThumb($src, 300, 300, TImage::THUMB_SCALING); //上传返回缩略图宽度为300
|
||||
// }
|
||||
|
||||
$return['src'] = $src;
|
||||
// if($this->isCompress){
|
||||
// Image::resize($src);
|
||||
// }
|
||||
File::add($image, $src); //加入上传文件表
|
||||
} catch (\Exception|ImageException $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) {
|
||||
if($this->validate->checkImage($image)){
|
||||
$src = Filesystem::putFile(date('Ymd'), $image, 'uniqid');
|
||||
$src = $this->uploadPath . '/' . $src;
|
||||
$data[] = $src;
|
||||
if($this->isCompress){
|
||||
Image::resize($src);
|
||||
}
|
||||
File::add($image, $src); //加入上传文件表
|
||||
}else{
|
||||
$errno = 1;
|
||||
$data = [];
|
||||
$data[] = Lang::get($this->validate->getError());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$return['errno'] = $errno;
|
||||
$return['data'] = $data;
|
||||
return json($return);
|
||||
}
|
||||
|
||||
//富文本编辑器上传图片
|
||||
public function tinyImage()
|
||||
{
|
||||
$image = request()->file('file');
|
||||
|
||||
if (!$image) {
|
||||
// 字段名不对
|
||||
header("HTTP/1.1 404 config field error");
|
||||
exit;
|
||||
}
|
||||
|
||||
if (!$this->uploadPathIsWritable) {
|
||||
header("HTTP/1.1 403 Insufficient folder permissions");
|
||||
exit;
|
||||
} else {
|
||||
if (!in_array(strtolower($image->getMime()), ['image/png','image/jpeg','image/jpg','image/gif'])) {
|
||||
header("HTTP/1.1 400 MIME TYPE ERROR");
|
||||
exit;
|
||||
}
|
||||
|
||||
checkPathExistWithMake(public_path().$this->uploadPath.'/images/'.date('Ym'));
|
||||
|
||||
// tinymce富文本对图片进行操作后(xuan)上传的是blob文件。
|
||||
// 针对blob文件未读取到后缀名 自动生成后缀 默认用mimetype后缀 如image/jpeg =》jpeg
|
||||
$newFileName = $image->hashName('uniqid');
|
||||
if (isset(explode('.',$newFileName)[1]) && empty(explode('.',$newFileName)[1])) {
|
||||
$ext = explode('/', $image->getOriginalMime());
|
||||
$newFileName .= $ext[1];
|
||||
}
|
||||
|
||||
$src = Filesystem::putFileAs('images/'.date('Ym'), $image, $newFileName);
|
||||
$src = $this->uploadPath.'/'.$src;
|
||||
if ($this->isCompress) {
|
||||
// 剪切
|
||||
Image::resize($src);
|
||||
}
|
||||
File::add($image, $src); //加入上传文件表
|
||||
$res['location'] = $src;
|
||||
return json($res);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,147 @@
|
|||
<?php
|
||||
|
||||
namespace app\controller\manager;
|
||||
|
||||
use app\model\{Message as MMessage, Log, VisitLogoModel};
|
||||
use app\service\Tool;
|
||||
use app\service\File;
|
||||
use PhpOffice\PhpSpreadsheet\Cell\DataType;
|
||||
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||||
use PhpOffice\PhpSpreadsheet\Style\Alignment;
|
||||
use PhpOffice\PhpSpreadsheet\Style\Border;
|
||||
use think\response\View;
|
||||
|
||||
class VisitLog extends Base
|
||||
{
|
||||
protected $excelStyle = [
|
||||
'font' => [
|
||||
'name' => '宋体',
|
||||
],
|
||||
'alignment' => [
|
||||
'horizontal' => Alignment::HORIZONTAL_CENTER, // 水平居中
|
||||
'vertical' => Alignment::VERTICAL_CENTER, // 垂直居中
|
||||
'wrapText' => true,
|
||||
],
|
||||
'borders' => [
|
||||
'allBorders' => [
|
||||
'borderStyle' => Border::BORDER_THIN,
|
||||
'color' => ['rgb' => 'eeeeee'],
|
||||
]
|
||||
],
|
||||
];
|
||||
|
||||
protected $defaultSetting = [
|
||||
'cell_width' => 30,
|
||||
'font_size' => 12
|
||||
];
|
||||
|
||||
//可以删除一个
|
||||
public function del()
|
||||
{
|
||||
if ($this->request->isPost()) {
|
||||
$id = input('post.id/d');
|
||||
if (is_numeric($id) && $id > 0) {
|
||||
$item = VisitLogoModel::getById($id);
|
||||
if (!empty($item)) {
|
||||
VisitLogoModel::destroy($id);
|
||||
if (!empty($item['file'])) {
|
||||
Tool::delFile($item['file']);
|
||||
}
|
||||
Log::write('visit_log', 'del', '删除访问记录,ID:'.$id);
|
||||
return $this->json();
|
||||
}
|
||||
return $this->json(3, '待删除记录不存在');
|
||||
}
|
||||
return $this->json(2, '参数错误,请核对之后再操作!');
|
||||
}
|
||||
return $this->json(1, '非法请求!');
|
||||
}
|
||||
|
||||
//列表
|
||||
public function index(): View
|
||||
{
|
||||
$startDate = input('param.startDate', '');
|
||||
$endDate = input('param.endDate', '');
|
||||
$keyword = input('param.keyword', '');
|
||||
|
||||
$param = [];
|
||||
if (!empty($startDate)) {
|
||||
$param['startDate'] = $startDate;
|
||||
}
|
||||
if (!empty($endDate)) {
|
||||
$param['endDate'] = $endDate;
|
||||
}
|
||||
|
||||
if (!empty($keyword)) {
|
||||
$param['keyword'] = $keyword;
|
||||
}
|
||||
|
||||
$paginate = [
|
||||
'list_rows' => 20,
|
||||
'query' => $param
|
||||
];
|
||||
|
||||
$items = VisitLogoModel::when(!empty($startDate) && strtotime($startDate), function ($query) use ($startDate) {
|
||||
$startTime = strtotime(date('Y-m-d 00:00:00', strtotime($startDate)));
|
||||
$query->where('create_time', '>=', $startTime);
|
||||
})
|
||||
->when(!empty($endDate) && strtotime($endDate), function ($query) use ($endDate) {
|
||||
$endTime = strtotime(date('Y-m-d 23:59:59', strtotime($endDate)));
|
||||
$query->where('create_time', '<=', $endTime);
|
||||
})
|
||||
->when(!empty($keyword), function ($query) use ($keyword) {
|
||||
$query->where('referer|visit', 'like', '%'.$keyword.'%');
|
||||
})
|
||||
->order("create_time", 'desc')
|
||||
->paginate($paginate);
|
||||
|
||||
$items->each(function ($item) {
|
||||
$item->source_title = '其他';
|
||||
if (str_contains($item->referer, 'baidu.com')) {
|
||||
$item->source_title = '百度';
|
||||
}
|
||||
|
||||
if (str_contains($item->referer, 'so.com')) {
|
||||
$item->source_title = '360';
|
||||
}
|
||||
});
|
||||
|
||||
$this->data['items'] = $items;
|
||||
$this->data['startDate'] = $startDate;
|
||||
$this->data['endDate'] = $endDate;
|
||||
$this->data['keyword'] = $keyword;
|
||||
return $this->view();
|
||||
}
|
||||
|
||||
// 导出留言
|
||||
public function export()
|
||||
{
|
||||
File::cancelTimeLimit();
|
||||
|
||||
$startDate = input('param.startDate', '');
|
||||
$endDate = input('param.endDate', '');
|
||||
$list = MMessage::getExportList($startDate, $endDate, 10000);
|
||||
|
||||
$spreadsheet = new Spreadsheet();
|
||||
$header = ['序号', '姓名', '电话', '公司/团队名称', '申请日期'];
|
||||
|
||||
$sheet = $spreadsheet->getActiveSheet();
|
||||
$sheetTitle = '预约记录';
|
||||
$cellValues = [];
|
||||
$cellWidthList = [];
|
||||
|
||||
foreach ($list as $item) {
|
||||
$cellValues[] = [
|
||||
[$item['id'], DataType::TYPE_STRING],
|
||||
$item['name'],
|
||||
$item['tel'],
|
||||
$item['company'],
|
||||
date('Y-m-d H:i', $item['create_time']),
|
||||
];
|
||||
}
|
||||
|
||||
File::setExcelCells($sheet, $cellValues, $header, $sheetTitle, $cellWidthList, $this->excelStyle, $this->defaultSetting);
|
||||
File::export($spreadsheet, '预约记录导出_'.date('YmdHis').'.xlsx');
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
|
||||
|
||||
namespace app\controller\manager;
|
||||
|
||||
|
||||
/**
|
||||
* 微信公众号配置
|
||||
* Class Wechat
|
||||
* @package app\controller\manager
|
||||
*/
|
||||
class Wechat extends Base
|
||||
{
|
||||
// 公众号设置
|
||||
public function base()
|
||||
{
|
||||
// TODO
|
||||
return 'TODO ...';
|
||||
}
|
||||
|
||||
// 公众号设置
|
||||
public function menu()
|
||||
{
|
||||
// TODO
|
||||
return 'TODO ...';
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
// 事件定义文件
|
||||
return [
|
||||
'bind' => [
|
||||
],
|
||||
|
||||
'listen' => [
|
||||
'AppInit' => [],
|
||||
'HttpRun' => [],
|
||||
'HttpEnd' => [],
|
||||
'LogLevel' => [],
|
||||
'LogWrite' => [],
|
||||
],
|
||||
|
||||
'subscribe' => [
|
||||
],
|
||||
];
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
// 全局中间件定义文件
|
||||
return [
|
||||
// 全局请求缓存
|
||||
// \think\middleware\CheckRequestCache::class,
|
||||
// 多语言加载
|
||||
//\think\middleware\LoadLangPack::class,
|
||||
// Session初始化
|
||||
\think\middleware\SessionInit::class,
|
||||
];
|
|
@ -0,0 +1,65 @@
|
|||
<?php
|
||||
namespace app\middleware;
|
||||
|
||||
use Closure;
|
||||
use app\model\AuthRule;
|
||||
use think\facade\Cache;
|
||||
|
||||
class Auth
|
||||
{
|
||||
public function handle($request, Closure $next)
|
||||
{
|
||||
$auth = session('auth');
|
||||
if(!$auth){
|
||||
return redirect(url('manager.login/index'));
|
||||
}
|
||||
// 角色权限
|
||||
$rules = Cache::get('group_rules_'.$auth['groupId']);
|
||||
$ruleNames = Cache::get('rule_names_'.$auth['groupId']);
|
||||
//如果是超级管理员,不用验证权限,给予所有权限
|
||||
if(empty($rules)){
|
||||
$ruleNames = [];
|
||||
if($auth['groupId'] == 1){
|
||||
$rules = AuthRule::getListTree(0);
|
||||
}else{
|
||||
// 角色权限 + 基本权限
|
||||
$rules = AuthRule::getAuthListByRuleIDs($auth['groupId']);
|
||||
}
|
||||
foreach($rules as &$rule){
|
||||
if(!stripos($rule['name'],'/')){
|
||||
$rule['name'] = $rule['name'].'/index';
|
||||
}
|
||||
$ruleNames[] = strtolower($rule['name']);
|
||||
if(isset($rule['children']) && !empty($rule['children'])){
|
||||
foreach($rule['children'] as &$child){
|
||||
if(!stripos($child['name'],'/')){
|
||||
$child['name'] = $child['name'].'/index';
|
||||
}
|
||||
$ruleNames[] = strtolower($child['name']);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
// 对角色赋予权限缓存,角色权限更新时需要同步更新缓存
|
||||
Cache::set('group_rules_'.$auth['groupId'], $rules);
|
||||
Cache::set('rule_names_'.$auth['groupId'], $ruleNames);
|
||||
}
|
||||
if($auth['groupId'] == 1){
|
||||
return $next($request);
|
||||
}
|
||||
|
||||
$controller = strtolower(request()->controller());
|
||||
$controller = str_replace('manager.', '', $controller);
|
||||
$action = request()->action();
|
||||
$name = strtolower($controller.'/'.$action);
|
||||
if(!empty($ruleNames) && in_array($name, $ruleNames, true)){
|
||||
return $next($request);
|
||||
}
|
||||
if(request()->isAjax()){
|
||||
return json(['code' => 1,'msg' => '没有权限']);
|
||||
}else{
|
||||
exit('无操作权限') ;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
<?php
|
||||
namespace app\middleware;
|
||||
|
||||
use Closure;
|
||||
|
||||
/**
|
||||
* CSRF校验
|
||||
*/
|
||||
class Csrf
|
||||
{
|
||||
public function handle($request, Closure $next)
|
||||
{
|
||||
if($request->isPost()){
|
||||
$check = $request->checkToken('__token__');
|
||||
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,555 @@
|
|||
<?php
|
||||
|
||||
namespace app\model;
|
||||
|
||||
use think\model\relation\HasOne;
|
||||
use think\Paginator;
|
||||
|
||||
class Article extends Base
|
||||
{
|
||||
public const STATUS_NORMAL = 1; // 正常
|
||||
public const STATUS_DISABLE = 0; // 禁用
|
||||
|
||||
// 文章属性(默认)
|
||||
protected static $defaultAttributeList = [
|
||||
'top' => '置顶',
|
||||
'hot' => '热门',
|
||||
'recommend' => '推荐',
|
||||
];
|
||||
|
||||
/**
|
||||
* 栏目
|
||||
* @return HasOne
|
||||
*/
|
||||
public function archivesCategory(): HasOne
|
||||
{
|
||||
return $this->hasOne(Category::class, 'id', 'category_id');
|
||||
}
|
||||
|
||||
|
||||
public static function getAttributeList(array $categoryIds = [])
|
||||
{
|
||||
$data = [];
|
||||
$recommendCategoryList = [];
|
||||
if(count(array_intersect($categoryIds, $recommendCategoryList)) > 0) {
|
||||
$data['recommend'] = '推荐';
|
||||
}
|
||||
|
||||
// 新闻动态
|
||||
$communityCategoryIds = Category::getCategoryWithChildrenIds(Category::CATEGORY_NEWS);
|
||||
if(count(array_intersect($categoryIds, $communityCategoryIds)) > 0) {
|
||||
$data['top'] = '置顶';
|
||||
$data['hot'] = '热门';
|
||||
$data['recommend'] = '推荐';
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/*********************************************
|
||||
* 分割线
|
||||
*********************************************/
|
||||
|
||||
|
||||
|
||||
//获取最高访问的文章列表
|
||||
public static function getMostVisited($limit = 5)
|
||||
{
|
||||
if ($limit <= 0) {
|
||||
$limit = 5;
|
||||
}
|
||||
return self::with(["archivesCategory"])
|
||||
->order('views', 'desc')
|
||||
->limit($limit)
|
||||
->select();
|
||||
}
|
||||
|
||||
//获取栏目下最新记录
|
||||
public static function getLatestByCategory($categoryId, $limit = 5)
|
||||
{
|
||||
if (empty($categoryId)) {
|
||||
return [];
|
||||
}
|
||||
if ($limit <= 0) {
|
||||
$limit = 5;
|
||||
}
|
||||
return self::with(["archivesCategory"])
|
||||
->where('category_id', $categoryId)
|
||||
->order('id', 'desc')
|
||||
->limit($limit)
|
||||
->select();
|
||||
}
|
||||
|
||||
//根据文章ID和栏目ID获取下一篇文章
|
||||
public static function getNextArticleBySortAndCategoryId($sort, $categoryId)
|
||||
{
|
||||
return self::with(["archivesCategory"])
|
||||
->where('sort', '<', $sort)
|
||||
->where('category_id', $categoryId)
|
||||
->where('status', 1)
|
||||
->order('sort', 'desc')
|
||||
->find();
|
||||
}
|
||||
|
||||
//根据文章ID和栏目ID获取上一篇文章
|
||||
public static function getPrevArticleBySortAndCategoryId($sort, $categoryId)
|
||||
{
|
||||
return self::with(["archivesCategory"])
|
||||
->where('sort', '>', $sort)
|
||||
->where('category_id', $categoryId)
|
||||
->where('status', 1)
|
||||
->order('sort', 'asc')
|
||||
->find();
|
||||
}
|
||||
|
||||
//根据栏目ID获取文章列表
|
||||
public static function getListByCategory($categoryId, $limit = 10)
|
||||
{
|
||||
return self::with(["archivesCategory"])
|
||||
->where('category_id', $categoryId)
|
||||
->where('status', 1)
|
||||
->order("sort", 'desc')
|
||||
->limit($limit)
|
||||
->select();
|
||||
}
|
||||
|
||||
//根据栏目ID获取文章分页列表
|
||||
public static function getListPageByCategory($categoryId, $per = 20, $keyword = '')
|
||||
{
|
||||
$where = [
|
||||
['category_id', '=', $categoryId],
|
||||
['status', '=', 1],
|
||||
];
|
||||
$param['category_id'] = $categoryId;
|
||||
if ($keyword != '') {
|
||||
$where[] = ['title', 'like', '%'.$keyword.'%'];
|
||||
$param['keyword'] = $keyword;
|
||||
}
|
||||
$paginate = [
|
||||
'list_rows' => $per,
|
||||
'query' => $param
|
||||
];
|
||||
return self::with(["archivesCategory"])
|
||||
->where($where)
|
||||
->order("sort", 'desc')
|
||||
->paginate($paginate, false);
|
||||
}
|
||||
|
||||
//根据栏目ID获取文章数量(状态:正常)
|
||||
public static function getNormalListCount($categoryId)
|
||||
{
|
||||
$where = [
|
||||
['category_id', '=', $categoryId],
|
||||
['status', '=', 1],
|
||||
];
|
||||
|
||||
return self::where($where)
|
||||
->count();
|
||||
}
|
||||
|
||||
public static function onAfterInsert($article)
|
||||
{
|
||||
$article->sort = $article->id;
|
||||
$article->create_time = $article->update_time = time();
|
||||
$auth = session('auth');
|
||||
$article->created = $article->updated = $auth['userName'];
|
||||
$article->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文章列表
|
||||
* @param int $categoryId 分类ID
|
||||
* @param int $per 每页数量
|
||||
* @param string $keyword 关键词
|
||||
* @param array $param 文章类型:置顶、热门、推荐 ['top','hot','recommend']
|
||||
* @param int $status 文章状态,-1表示不限制
|
||||
* @param array $orderList 排序
|
||||
* @param bool $onlyChild 仅获取下级 默认true false=获取所有后代分类
|
||||
* @return Paginator
|
||||
*/
|
||||
public static function getList($categoryId, $per = 20, $keyword = '', $param = [], $status = -1, $orderList = ['sort' => 'desc'], bool $onlyChild = true)
|
||||
{
|
||||
$whereMap = [];
|
||||
$pageParam = [];
|
||||
if (is_numeric($categoryId) && $categoryId > 0) {
|
||||
$children = Category::getChildrenByParentId($categoryId, $onlyChild);
|
||||
if (!empty($children)) {
|
||||
$categoryIds = [$categoryId];
|
||||
foreach ($children as $child) {
|
||||
if ($child['model_id'] == Model::MODEL_ARTICLE) {
|
||||
$categoryIds[] = $child['id'];
|
||||
}
|
||||
}
|
||||
$whereMap[] = ['category_id', 'in', $categoryIds];
|
||||
} else {
|
||||
$whereMap[] = ['category_id', '=', $categoryId];
|
||||
}
|
||||
$pageParam['category_id'] = $categoryId;
|
||||
}
|
||||
if (!empty($keyword)) {
|
||||
$whereMap[] = ['title', 'like', '%'.$keyword.'%'];
|
||||
$pageParam['keyword'] = $keyword;
|
||||
}
|
||||
if (is_array($param) && count($param) > 0) {
|
||||
$pageParam['param'] = $param;
|
||||
foreach ($param as $vo) {
|
||||
if (in_array($vo, ['top', 'hot', 'recommend'], true)) {
|
||||
$whereMap[] = ["{$vo}", '=', 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
$paginate = [
|
||||
'list_rows' => $per,
|
||||
'query' => $pageParam
|
||||
];
|
||||
|
||||
return self::with(["archivesCategory"])
|
||||
->when(count($whereMap) > 0, function ($query) use ($whereMap) {
|
||||
$query->where($whereMap);
|
||||
})
|
||||
->when($status != -1, function ($query) use ($status) {
|
||||
$query->where('status', $status);
|
||||
})
|
||||
->order($orderList)
|
||||
->paginate($paginate, false);
|
||||
}
|
||||
|
||||
//获取文章涉及到的图片
|
||||
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;
|
||||
}
|
||||
$imgs = getImageUrlFromText($item['content']);
|
||||
if (!empty($imgs)) {
|
||||
$data = array_merge($data, $imgs);
|
||||
}
|
||||
$videos = getVideoUrlFromText($item['content']);
|
||||
if (!empty($videos)) {
|
||||
$data = array_merge($data, $videos);
|
||||
}
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
//推荐列表(其他推荐类)
|
||||
public static function getRecommendList($categoryId, $recommend = '', $limit = 3, $excludeIds = [], $orderList = ['a.id' => 'desc'])
|
||||
{
|
||||
if (empty($categoryId) || empty($recommend)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$whereMap = [];
|
||||
if (is_numeric($categoryId) && $categoryId > 0) {
|
||||
$children = Category::getChildrenByParentId($categoryId);
|
||||
if (!empty($children)) {
|
||||
$categoryIds = [$categoryId];
|
||||
foreach ($children as $child) {
|
||||
if ($child['model_id'] == Model::MODEL_ARTICLE) {
|
||||
$categoryIds[] = $child['id'];
|
||||
}
|
||||
}
|
||||
$whereMap[] = ['category_id', 'in', $categoryIds];
|
||||
} else {
|
||||
$whereMap[] = ['category_id', '=', $categoryId];
|
||||
}
|
||||
}
|
||||
if (!empty($excludeIds)) {
|
||||
$whereMap[] = ['id', 'not in', $excludeIds];
|
||||
}
|
||||
|
||||
return self::with(["archivesCategory"])
|
||||
->when(count($whereMap) > 0, function ($query) use ($whereMap) {
|
||||
$query->where($whereMap);
|
||||
})
|
||||
->whereRaw("FIND_IN_SET(:recommend, `recommend_other`)", ['recommend' => $recommend])
|
||||
->where('status', 1)
|
||||
->order($orderList)
|
||||
->limit($limit)
|
||||
->select();
|
||||
}
|
||||
|
||||
// 转换文章的推荐设置
|
||||
public static function convertRecommendOther($categoryIds = [], $articles, $isMulti = true)
|
||||
{
|
||||
if (empty($articles) || count($articles) == 0) {
|
||||
return $articles;
|
||||
}
|
||||
|
||||
$attributeList = self::getAttributeList($categoryIds);
|
||||
|
||||
if ($isMulti) {
|
||||
foreach ($articles as &$article) {
|
||||
$recommendOtherList = [];
|
||||
$recommendOtherStrList = [];
|
||||
if (isset($article['recommend_other']) && !empty($article['recommend_other'])) {
|
||||
$recommendOtherList = explode(',', $article['recommend_other']);
|
||||
foreach ($recommendOtherList as $recommendKey) {
|
||||
if (isset($attributeList[$recommendKey]) && !empty($attributeList[$recommendKey])) {
|
||||
$recommendOtherStrList[] = $attributeList[$recommendKey];
|
||||
}
|
||||
}
|
||||
}
|
||||
$article['recommend_other_list'] = $recommendOtherList;
|
||||
$article['recommend_other_str'] = implode(',', $recommendOtherStrList);
|
||||
}
|
||||
unset($article);
|
||||
|
||||
} else {
|
||||
$recommendOtherList = [];
|
||||
$recommendOtherStrList = [];
|
||||
if (isset($articles['recommend_other']) && !empty($articles['recommend_other'])) {
|
||||
$recommendOtherList = explode(',', $articles['recommend_other']);
|
||||
foreach ($recommendOtherList as $recommendKey) {
|
||||
if (isset($attributeList[$recommendKey]) && !empty($attributeList[$recommendKey])) {
|
||||
$recommendOtherStrList[] = $attributeList[$recommendKey];
|
||||
}
|
||||
}
|
||||
}
|
||||
$articles['recommend_other_list'] = $recommendOtherList;
|
||||
$articles['recommend_other_str'] = implode(',', $recommendOtherStrList);
|
||||
}
|
||||
|
||||
return $articles;
|
||||
}
|
||||
|
||||
// 获取最新动态
|
||||
public static function getLastDynamicsList($categoryId, $withChild = false, $limit = 10)
|
||||
{
|
||||
$categoryIds = [$categoryId];
|
||||
if ($withChild) {
|
||||
$childCategories = Category::getChildrenByParentId($categoryId);
|
||||
if (!empty($childCategories)) {
|
||||
foreach ($childCategories as $category) {
|
||||
if ($category['model_id'] == Model::MODEL_ARTICLE) {
|
||||
$categoryIds[] = $category['id'];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return self::with(["archivesCategory"])
|
||||
->whereIn('category_id', $categoryIds)
|
||||
->where('status', 1)
|
||||
->order('id', 'desc')
|
||||
->limit($limit)
|
||||
->select();
|
||||
|
||||
}
|
||||
|
||||
|
||||
//根据文章ID和栏目IDs,默认按创建时间获取下一篇文章
|
||||
public static function getNextArticleByTimeAndCategoryIds(array $where, $sortOrder = ['id' => 'desc'])
|
||||
{
|
||||
return self::with(["archivesCategory"])
|
||||
->where($where)
|
||||
->where('status', 1)
|
||||
->order($sortOrder)
|
||||
->find();
|
||||
}
|
||||
|
||||
//根据文章ID和栏目IDs,默认按创建时间获取上一篇文章
|
||||
public static function getPrevArticleByTimeAndCategoryIds(array $where, $sortOrder = ['id' => 'asc'])
|
||||
{
|
||||
return self::with(["archivesCategory"])
|
||||
// ->where('a.id','>',$curId)
|
||||
// ->whereIn('a.category_id', $categoryIds)
|
||||
->where($where)
|
||||
->where('status', 1)
|
||||
->order($sortOrder)
|
||||
->find();
|
||||
}
|
||||
|
||||
public static function getLastTopList($categoryId, $limit = 3, $excludeIds = [], $orderList = ['recommend_other' => 'desc', 'id' => 'desc'])
|
||||
{
|
||||
if (empty($categoryId)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$whereMap = [];
|
||||
if (is_numeric($categoryId) && $categoryId > 0) {
|
||||
$children = Category::getChildrenByParentId($categoryId);
|
||||
if (!empty($children)) {
|
||||
$categoryIds = [$categoryId];
|
||||
foreach ($children as $child) {
|
||||
if ($child['model_id'] == Model::MODEL_ARTICLE) {
|
||||
$categoryIds[] = $child['id'];
|
||||
}
|
||||
}
|
||||
$whereMap[] = ['category_id', 'in', $categoryIds];
|
||||
} else {
|
||||
$whereMap[] = ['category_id', '=', $categoryId];
|
||||
}
|
||||
}
|
||||
if (!empty($excludeIds)) {
|
||||
$whereMap[] = ['id', 'not in', $excludeIds];
|
||||
}
|
||||
|
||||
$items = self::with(["archivesCategory"])
|
||||
->when(count($whereMap) > 0, function ($query) use ($whereMap) {
|
||||
$query->where($whereMap);
|
||||
})
|
||||
->where('status', 1)
|
||||
->order($orderList);
|
||||
if ($limit > 0) {
|
||||
$items = $items->limit($limit);
|
||||
}
|
||||
$items = $items->limit($limit)
|
||||
->select();
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
// 分页获取最新动态
|
||||
public static function getLastDynamicsPageList($categoryId, $withChild = true, $per = 20)
|
||||
{
|
||||
$categoryIds = [$categoryId];
|
||||
if ($withChild) {
|
||||
$childCategories = Category::getChildrenByParentId($categoryId);
|
||||
if (!empty($childCategories)) {
|
||||
foreach ($childCategories as $category) {
|
||||
if ($category['model_id'] == Model::MODEL_ARTICLE) {
|
||||
$categoryIds[] = $category['id'];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$paginate = [
|
||||
'list_rows' => $per,
|
||||
'query' => [
|
||||
'category_id' => $categoryId
|
||||
]
|
||||
];
|
||||
|
||||
return self::with(["archivesCategory"])
|
||||
->whereIn('category_id', $categoryIds)
|
||||
->where('status', 1)
|
||||
->order('id', 'desc')
|
||||
->paginate($paginate, false);
|
||||
}
|
||||
|
||||
// 根据栏目ID进行分组,按sort倒序排列,每组最多获取n条(默认10条)数据
|
||||
public static function getGroupListByCategoryIds(array $categoryIds, int $size = 10)
|
||||
{
|
||||
return self::alias('ca')
|
||||
->where($size, '>', function ($q) {
|
||||
$q->table('bee_article cb')
|
||||
->whereRaw('ca.category_id = cb.category_id and ca.sort < cb.sort')->field('count(*)');
|
||||
})
|
||||
->whereIn('ca.category_id', $categoryIds)
|
||||
->field('ca.*')
|
||||
->order(['ca.sort' => 'desc'])
|
||||
->select();
|
||||
}
|
||||
|
||||
public static function parseList($items)
|
||||
{
|
||||
try {
|
||||
$tagNameList = [];
|
||||
foreach ($items as $ki => $item) {
|
||||
$tagStr = trim($item['tag'] ?? '');
|
||||
$tagNames = empty($tagStr) ? [] : explode(',', $tagStr);
|
||||
$tagNameList = array_merge($tagNameList, $tagNames);
|
||||
}
|
||||
$tagNameList = array_unique($tagNameList);
|
||||
$tagKVs = ArticleTags::findByNames($tagNameList)->column('id', 'name');
|
||||
|
||||
foreach ($items as $ki => $item) {
|
||||
$tagStr = trim($item['tag'] ?? '');
|
||||
$tagNames = empty($tagStr) ? [] : explode(',', $tagStr);
|
||||
$tagList = [];
|
||||
foreach ($tagNames as $tagName) {
|
||||
$tagList[] = [
|
||||
'name' => $tagName,
|
||||
'id' => $tagKVs[$tagName] ?? 0
|
||||
];
|
||||
}
|
||||
$items[$ki]['tag_list'] = $tagList;
|
||||
$createTime = is_numeric($item['create_time']) ? $item['create_time'] : strtotime($item['create_time']);
|
||||
$items[$ki]['create_date'] = date('Y-m-d', $createTime);
|
||||
$item['create_dateTime'] = date('Y-m-d H:i:s', $createTime);
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
|
||||
}
|
||||
return $items;
|
||||
}
|
||||
|
||||
public static function parseInfo($item)
|
||||
{
|
||||
if ($item) {
|
||||
$tagStr = trim($item['tag'] ?? '');
|
||||
$tagNameList = empty($tagStr) ? [] : explode(',', $tagStr);
|
||||
$tagKVs = ArticleTags::findByNames($tagNameList)->column('id', 'name');
|
||||
$tagList = [];
|
||||
foreach ($tagNameList as $tagName) {
|
||||
$tagList[] = [
|
||||
'name' => $tagName,
|
||||
'id' => $tagKVs[$tagName] ?? 0
|
||||
];
|
||||
}
|
||||
$item['tag_list'] = $tagList;
|
||||
$createTime = is_numeric($item['create_time']) ? $item['create_time'] : strtotime($item['create_time']);
|
||||
$item['create_date'] = date('Y-m-d', $createTime);
|
||||
$item['create_dateTime'] = date('Y-m-d H:i:s', $createTime);
|
||||
}
|
||||
return $item;
|
||||
}
|
||||
|
||||
public static function countList(array $where, callable $call = null)
|
||||
{
|
||||
$q = new static();
|
||||
$q = $q->where($where);
|
||||
if ($call) {
|
||||
$q = $call($q);
|
||||
}
|
||||
return $q->count();
|
||||
}
|
||||
|
||||
public static function findListByWhere(array $where, int $page = 1, int $size = 10, callable $call = null, array $sortList = ['sort' => 'desc'])
|
||||
{
|
||||
$q = new static();
|
||||
$q = $q->with(["archivesCategory"])->where($where);
|
||||
if ($call) {
|
||||
$q = $call($q);
|
||||
}
|
||||
if ($size > 0) {
|
||||
$q = $q->page($page, $size);
|
||||
}
|
||||
if (count($sortList)) {
|
||||
$q = $q->order($sortList);
|
||||
}
|
||||
return $q->select();
|
||||
}
|
||||
|
||||
public static function getTeam()
|
||||
{
|
||||
return self::with(["archivesCategory"])
|
||||
->where("category_id",Category::CATEGORY_TEAM)
|
||||
->order(["sort"=>"desc","id"=>"desc"])
|
||||
->select();
|
||||
}
|
||||
public static function getIndexTop($categoryId)
|
||||
{
|
||||
return self::with(["archivesCategory"])
|
||||
->where("category_id",$categoryId)
|
||||
->where("top",1)
|
||||
->order(["sort"=>"desc"])
|
||||
->find();
|
||||
}
|
||||
|
||||
public static function getIndexList($categoryId,$num)
|
||||
{
|
||||
return self::with(["archivesCategory"])
|
||||
->where("category_id",$categoryId)
|
||||
->where("top","<>",1)
|
||||
->order([ 'sort' => 'desc',"id"=>"desc"])
|
||||
->limit($num)
|
||||
->select();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
<?php
|
||||
namespace app\model;
|
||||
|
||||
use think\Collection;
|
||||
use think\db\exception\DataNotFoundException;
|
||||
use think\db\exception\DbException;
|
||||
use think\db\exception\ModelNotFoundException;
|
||||
use think\Paginator;
|
||||
|
||||
/**
|
||||
* 文章标签记录
|
||||
* 当前只收录【客户案例】和【得助社区】的标签
|
||||
*
|
||||
* Class ArticleTags
|
||||
* @package app\model
|
||||
*/
|
||||
class ArticleTags extends Base
|
||||
{
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @return array|\think\Model|null
|
||||
* @throws DataNotFoundException
|
||||
* @throws DbException
|
||||
* @throws ModelNotFoundException
|
||||
*/
|
||||
public static function findByName(string $name)
|
||||
{
|
||||
return self::where('name', $name)->find();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $nameList
|
||||
* @return Collection
|
||||
* @throws DataNotFoundException
|
||||
* @throws DbException
|
||||
* @throws ModelNotFoundException
|
||||
*/
|
||||
public static function findByNames(array $nameList)
|
||||
{
|
||||
return self::whereIn('name', $nameList)->select();
|
||||
}
|
||||
|
||||
// 获取推荐标签
|
||||
public static function getRecommendTags(int $size = 12, int $type = -1)
|
||||
{
|
||||
$where = [];
|
||||
$sortOrder = [];
|
||||
switch ($type) {
|
||||
case 1: // 限制查询 case_total
|
||||
$where[] = ['case_total', '>', 0];
|
||||
$sortOrder['case_total'] = 'desc';
|
||||
break;
|
||||
case 2: // 限制查询 news_total
|
||||
$where[] = ['news_total', '>', 0];
|
||||
$sortOrder['news_total'] = 'desc';
|
||||
break;
|
||||
}
|
||||
|
||||
$q = new static();
|
||||
if (count($where) > 0) {
|
||||
$q = $q->where($where);
|
||||
}
|
||||
if (count($sortOrder) > 0) {
|
||||
$q = $q->order($sortOrder);
|
||||
}
|
||||
|
||||
return $q->limit($size)->select();
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页器:分页数据查询
|
||||
*
|
||||
* @param array $where 查询条件,二维数组
|
||||
* @param array $paginateRows 分页参数 [list_rows 每页数量 | page 当前页 | path url路径 | query url额外参数| fragment url锚点 | var_page 分页变量]
|
||||
* @param bool $paginateSimple 是否为简单分页
|
||||
* @return Paginator
|
||||
* @throws DbException
|
||||
*/
|
||||
public static function getListWithPaginate(array $where, array $paginateRows, bool $paginateSimple = false): Paginator
|
||||
{
|
||||
return self::where($where)->paginate($paginateRows, $paginateSimple);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
<?php
|
||||
namespace app\model;
|
||||
|
||||
use think\facade\Cache;
|
||||
|
||||
class AuthGroup extends Base
|
||||
{
|
||||
public static function updateRules($groupId, $rules)
|
||||
{
|
||||
$rules = implode(',', $rules);
|
||||
$data = ['rules' => $rules];
|
||||
self::updateById($groupId, $data);
|
||||
Member::where('group_id', $groupId)
|
||||
->update($data);
|
||||
}
|
||||
|
||||
//根据ID获取角色列表,ID为1是超级管理员
|
||||
public static function getListById($groupId = 1)
|
||||
{
|
||||
if($groupId < 1){
|
||||
return [];
|
||||
}
|
||||
$group = self::getById($groupId);
|
||||
if(empty($group)){
|
||||
return [];
|
||||
}
|
||||
if($groupId == 1){
|
||||
return self::select()
|
||||
->toArray();
|
||||
}else{
|
||||
return self::where('id','<>','1')
|
||||
->select()
|
||||
->toArray();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 重置角色权限缓存
|
||||
* @param int $groupId 指定重置的角色ID,若不指定则重置所有角色
|
||||
*/
|
||||
public static function resetGroupRulesCache($groupId = 0)
|
||||
{
|
||||
if(is_numeric($groupId) && $groupId > 0) {
|
||||
Cache::set('group_rules_'.$groupId, null);
|
||||
Cache::set('rule_names_'.$groupId, null);
|
||||
} else {
|
||||
$groupIds = self::column('id');
|
||||
foreach ($groupIds as $id){
|
||||
Cache::set('group_rules_'.$id, null);
|
||||
Cache::set('rule_names_'.$id, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,271 @@
|
|||
<?php
|
||||
namespace app\model;
|
||||
|
||||
class AuthRule extends Base
|
||||
{
|
||||
//根据权限IDs获取权限列表
|
||||
public static function getListByRuleIDs($ruleIds)
|
||||
{
|
||||
$items = self::wherein('id',$ruleIds)
|
||||
//->where('status', 1)
|
||||
->order('sort', 'asc')
|
||||
->select()
|
||||
->toArray();
|
||||
return self::getChildren($items);
|
||||
}
|
||||
|
||||
//角色权限 + 基本权限
|
||||
public static function getAuthListByRuleIDs($groupId)
|
||||
{
|
||||
$order = ['sort'=>'asc'];
|
||||
if ($groupId == 1) {
|
||||
$items = self::order($order)->select()->toArray();
|
||||
} else {
|
||||
$group = AuthGroup::getById($groupId);
|
||||
$rulesArr = [];
|
||||
if ($group && !empty($group['rules'])) {
|
||||
$rulesArr = array_filter(explode(',', $group['rules']));
|
||||
}
|
||||
if (count($rulesArr) >0) {
|
||||
$items = self::wherein('id', $rulesArr)->whereOr('is_base', 1)->order($order)->select()->toArray();
|
||||
} else {
|
||||
$items = self::where('is_base', 1)->order($order)->select()->toArray();
|
||||
}
|
||||
}
|
||||
$levelItems = self::getChildren($items);
|
||||
$levelIds = self::getChildrenIds($items);
|
||||
// 独立写入不在连续分层中的权限,连续分层权限可用于菜单显示
|
||||
foreach ($items as $item) {
|
||||
if(!in_array($item['id'], $levelIds)) {
|
||||
$levelItems[] = $item;
|
||||
}
|
||||
}
|
||||
return $levelItems;
|
||||
}
|
||||
|
||||
//根据上级ID获取下级权限列表
|
||||
public static function getListTree($forMenu = 0)
|
||||
{
|
||||
$items = self::getList($forMenu);
|
||||
return self::getChildren($items);
|
||||
}
|
||||
|
||||
//根据上级ID获取下级权限列表
|
||||
public static function getListByParentId($parentId)
|
||||
{
|
||||
return self::where('parent_id', $parentId)
|
||||
->order('sort', 'asc')
|
||||
->select()
|
||||
->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $items
|
||||
* @param integer $parent_id
|
||||
* @return array
|
||||
*/
|
||||
public static function getChildren($items, $parentId = 0)
|
||||
{
|
||||
$data = [];
|
||||
foreach($items as $item){
|
||||
if($item['parent_id'] == $parentId){
|
||||
$childern = self::getChildren($items, $item['id']);
|
||||
if(!empty($childern)){
|
||||
$item['hasChildren'] = true;
|
||||
$item['children'] = $childern;
|
||||
}
|
||||
$data[] = $item;
|
||||
}
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
public static function getChildrenIds($items, $parentId = 0)
|
||||
{
|
||||
$data = [];
|
||||
foreach($items as $item){
|
||||
if($item['parent_id'] == $parentId){
|
||||
$childrenIds = self::getChildrenIds($items, $item['id']);
|
||||
if(!empty($childrenIds)){
|
||||
$data = array_merge($data, $childrenIds);
|
||||
}
|
||||
$data[] = $item['id'];
|
||||
}
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param integer $forMenu 大于0表示获取可显示的权限
|
||||
* @return void
|
||||
*/
|
||||
private static function getList($forMenu = 0)
|
||||
{
|
||||
if($forMenu){
|
||||
return self::where('status', 1)->order('sort', 'asc')->select()->toArray();
|
||||
}else{
|
||||
return self::order('sort', 'asc')->select()->toArray();
|
||||
}
|
||||
}
|
||||
|
||||
//获取可显示权限
|
||||
public static function getTopListForDisplay()
|
||||
{
|
||||
return self::where('status', 1)
|
||||
->where('parent_id', 0)
|
||||
->order('sort', 'asc')
|
||||
->select()
|
||||
->toArray();
|
||||
}
|
||||
|
||||
//根据两个名字获取权限
|
||||
public static function getByTwoName($name, $otherName)
|
||||
{
|
||||
return self::whereOr('name',$name)
|
||||
->whereOr('name',$otherName)
|
||||
->findOrEmpty()
|
||||
->toArray();
|
||||
}
|
||||
|
||||
//根据name获取权限
|
||||
public static function getByName($name)
|
||||
{
|
||||
return self::where('name', $name)
|
||||
->findOrEmpty()
|
||||
->toArray();
|
||||
}
|
||||
|
||||
public static function onAfterInsert($rule)
|
||||
{
|
||||
$rule->sort = $rule->id;
|
||||
$rule->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* 该情况适合无限级菜单分组显示 (当前系统仅支持2级权限,因此推荐使用getListTree 方法)
|
||||
* @param int $forMenu 是否只获取可显示菜单权限
|
||||
*/
|
||||
public static function getListTreeSort($forMenu = 0)
|
||||
{
|
||||
$items = self::getList($forMenu);
|
||||
return self::groupSort($items, 0, 1, true, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 分组排序(不拆分为子集)
|
||||
*
|
||||
* @param $items 数据源
|
||||
* @param integer $pid
|
||||
* @param integer $level
|
||||
* @param bool $clear 是否释放局部变量(外部调用时必须先释放,避免数据被累加;内部不用,需要累加)
|
||||
* @param bool $isArr 传入的$items是否为数组,默认否(数据集)
|
||||
* @param string $levelSpare 分层符
|
||||
* @return void
|
||||
*/
|
||||
public static function groupSort($items,$pid = 0, $level = 1, $clear = true, $isArr = false, $levelSpare = '_')
|
||||
{
|
||||
static $data = [];
|
||||
if ($clear) {
|
||||
$data = [];
|
||||
static $data = [];
|
||||
}
|
||||
if(!empty($levelSpare) && $level > 1) {
|
||||
$levelSpare = str_repeat($levelSpare, $level-1);
|
||||
}
|
||||
if (count($items) > 0) {
|
||||
if ($isArr) {
|
||||
foreach ($items as $key => $item) {
|
||||
if ($item['parent_id'] == $pid) {
|
||||
$item['level'] = $level;
|
||||
$item['title'] = $levelSpare.$item['title'];
|
||||
$data[] = $item;
|
||||
self::groupSort($items, $item['id'], $level+1, false, $isArr);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
foreach ($items as $key => $item) {
|
||||
if ($item->parent_id == $pid) {
|
||||
$item->level = $level;
|
||||
$item->title = $levelSpare.$item->title;
|
||||
$data[] = $item;
|
||||
self::groupSort($items, $item->id, $level+1, false, $isArr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 树形排序 (拆分子集)
|
||||
*
|
||||
* @param Collection $items 数据集(非数组)
|
||||
* @param integer $pid
|
||||
* @param integer $level
|
||||
* @return void
|
||||
*/
|
||||
public static function treeSort($items,$pid = 0, $level = 1)
|
||||
{
|
||||
$data = [];
|
||||
if (count($items) > 0) {
|
||||
foreach ($items as $key => $item) {
|
||||
if ($item->parent_id == $pid) {
|
||||
$item->level = $level;
|
||||
$children = self::treeSort($items, $item->id, $level+1);
|
||||
$item->children = $children;
|
||||
$data[] = $item;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询用户权限(登陆时更具角色更新为最新权限)
|
||||
* 可显示权限和所有权限 角色权限 + 基本权限
|
||||
*
|
||||
* @param boolean $groupId 角色ID,超级管理员(对应group_id = 1)
|
||||
* @return void
|
||||
*/
|
||||
public static function userRolesList($groupId = 1)
|
||||
{
|
||||
$userRoles = [];
|
||||
$items = null;
|
||||
$order = ['sort'=>'asc'];
|
||||
if ($groupId == 1) {
|
||||
$items = self::order($order)->select();
|
||||
} else {
|
||||
$group = AuthGroup::getById($groupId);
|
||||
$rulesArr = [];
|
||||
if ($group && !empty($group['rules'])) {
|
||||
$rulesArr = array_filter(explode(',', $group['rules']));
|
||||
}
|
||||
if (count($rulesArr) >0) {
|
||||
$items = self::wherein('id', $rulesArr)->whereOr('is_base', 1)->order($order)->select();
|
||||
} else {
|
||||
$items = self::where('is_base', 1)->order($order)->select();
|
||||
}
|
||||
}
|
||||
if (empty($items) || $items->isEmpty()) {
|
||||
return $userRoles;
|
||||
}
|
||||
|
||||
$allRulesId = [];
|
||||
$displayRules = [];
|
||||
$displayRulesId = [];
|
||||
foreach ($items as $key => $item) {
|
||||
$allRulesId[] = $item->id;
|
||||
if ($item->status > 0) {
|
||||
$displayRules[] = $item;
|
||||
$displayRulesId[] = $item->id;
|
||||
}
|
||||
}
|
||||
|
||||
$userRoles['allRules'] = $items;
|
||||
$userRoles['allRulesId'] = $allRulesId;
|
||||
$userRoles['displayRules'] = $displayRules;
|
||||
$userRoles['displayRulesId'] = $displayRulesId;
|
||||
return $userRoles;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
<?php
|
||||
namespace app\model;
|
||||
|
||||
use think\Model;
|
||||
|
||||
class Base extends Model
|
||||
{
|
||||
protected $autoWriteTimestamp = false;
|
||||
|
||||
public const BOOL_TRUE = 1;
|
||||
public const BOOL_FALSE = 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更新数据
|
||||
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查询记录详情
|
||||
public static function findInfoById($id)
|
||||
{
|
||||
return self::where('id', $id)->find();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,170 @@
|
|||
<?php
|
||||
namespace app\model;
|
||||
|
||||
class Block extends Base
|
||||
{
|
||||
const BLOCK = 1;
|
||||
const IMG = 2;
|
||||
const TEXT = 3;
|
||||
const GROUP = 4;
|
||||
const VIDEO = 5;
|
||||
const CODE = 6;
|
||||
const AUDIOS = 7;
|
||||
const VIDEOS = 8;
|
||||
const MAP = 9;
|
||||
|
||||
// json化存储的区块类型
|
||||
public static $jsonValueTypes = [self::GROUP,self::AUDIOS,self::MAP];
|
||||
public static $mapType = [
|
||||
"gaode"=>"高德",
|
||||
"baidu"=>"百度",
|
||||
"tengxun"=>"腾讯",
|
||||
];
|
||||
|
||||
//获取类型键值对
|
||||
public static function getTypes()
|
||||
{
|
||||
return [
|
||||
'1' => 'block',
|
||||
'2' => 'img',
|
||||
'3' => 'text',
|
||||
'4' => 'group',
|
||||
'5' => 'video',
|
||||
'6' => 'code',
|
||||
'7' => 'audios',
|
||||
'8' => 'videos',
|
||||
'9' => 'map',
|
||||
];
|
||||
}
|
||||
|
||||
//根据键值和类目获取数据
|
||||
public static function getByKeyword($keyword, $categoryId)
|
||||
{
|
||||
return self::where('keyword', $keyword)->where('category_id', $categoryId)->findOrEmpty()->toArray();
|
||||
}
|
||||
|
||||
//根据栏目ID获取块列表
|
||||
public static function getByCategoryId($categoryId)
|
||||
{
|
||||
|
||||
if($categoryId <= 0){
|
||||
return [];
|
||||
}
|
||||
$category = Category::getById($categoryId);
|
||||
if(empty($category)){
|
||||
return [];
|
||||
}
|
||||
$items = self::where('category_id', $categoryId)
|
||||
->order('sort asc')
|
||||
->select()
|
||||
->toArray();
|
||||
if(empty($items)){
|
||||
return [];
|
||||
}
|
||||
$data = [];
|
||||
foreach($items as $item){
|
||||
$data[$item['keyword']] = $item;
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
//根据栏目ID获取块列表
|
||||
public static function getChildrenByCategoryId($categoryId)
|
||||
{
|
||||
|
||||
if($categoryId <= 0){
|
||||
return [];
|
||||
}
|
||||
$category = Category::getById($categoryId);
|
||||
if(empty($category)){
|
||||
return [];
|
||||
}
|
||||
$categoryIds = Category::where('path', 'like', $category['path'].$category['id'].',%')->column('id');
|
||||
if(empty($categoryIds)){
|
||||
return [];
|
||||
}
|
||||
$items = self::whereIn('category_id', $categoryIds)
|
||||
->order('sort asc')
|
||||
->select()
|
||||
->toArray();
|
||||
if(empty($items)){
|
||||
return [];
|
||||
}
|
||||
$data = [];
|
||||
foreach($items as $item){
|
||||
$data[$item['keyword']] = $item;
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
public static function onAfterInsert($item)
|
||||
{
|
||||
$item->sort = $item->id;
|
||||
$item->save();
|
||||
}
|
||||
|
||||
//获取在使用中的文件
|
||||
public static function getFilesInUse()
|
||||
{
|
||||
$items = self::whereIn('type', [self::IMG, self::GROUP, self::VIDEO, self::TEXT])
|
||||
->select()
|
||||
->toArray();
|
||||
$data = [];
|
||||
foreach($items as $item){
|
||||
if($item['type'] == self::IMG){
|
||||
$file = trim($item['value']);
|
||||
if(!empty($file)){
|
||||
$key = getKeyByPath($file);
|
||||
$data[$key] = $file;
|
||||
}
|
||||
}elseif($item['type'] == self::GROUP){
|
||||
$val = trim($item['value']);
|
||||
if (!empty($val) && $val != '[]' && $val != 'null') {
|
||||
$files = json_decode($val, true);
|
||||
foreach($files as $file){
|
||||
$src = trim($file['src']);
|
||||
if(!empty($src)){
|
||||
$key = getKeyByPath($src);
|
||||
$data[$key] = $src;
|
||||
}
|
||||
}
|
||||
}
|
||||
}elseif($item['type'] == self::VIDEO){
|
||||
$video = trim($item['value']);
|
||||
if(!empty($video)){
|
||||
$key = getKeyByPath($video);
|
||||
$data[$key] = $video;
|
||||
}
|
||||
$img = trim($item['img']);
|
||||
if(!empty($img)){
|
||||
$key = getKeyByPath($img);
|
||||
$data[$key] = $img;
|
||||
}
|
||||
}elseif($item['type'] == self::TEXT){
|
||||
$imgs = getImageUrlFromText($item['value']);
|
||||
if(!empty($imgs)){
|
||||
$data = array_merge($data, $imgs);
|
||||
}
|
||||
$videos = getVideoUrlFromText($item['value']);
|
||||
if(!empty($videos)){
|
||||
$data = array_merge($data, $videos);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
// 转化json化存储的数据
|
||||
public static function convertValue($items)
|
||||
{
|
||||
foreach ($items as &$item) {
|
||||
$item['json_value_list'] = [];
|
||||
if(in_array($item['type'], self::$jsonValueTypes) && !empty($item['value'])) {
|
||||
$item['json_value_list'] = json_decode($item['value'], true);
|
||||
}
|
||||
}
|
||||
unset($item);
|
||||
|
||||
return $items;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,471 @@
|
|||
<?php
|
||||
|
||||
namespace app\model;
|
||||
|
||||
use think\Collection;
|
||||
use think\db\exception\DataNotFoundException;
|
||||
use think\db\exception\DbException;
|
||||
use think\db\exception\ModelNotFoundException;
|
||||
|
||||
class Category extends Base
|
||||
{
|
||||
// 文章类
|
||||
// 新闻动态
|
||||
public const CATEGORY_NEWS = 7;
|
||||
//团队管理
|
||||
public const CATEGORY_TEAM = 6;
|
||||
//企业介绍
|
||||
public const CATEGORY_COMPANY = 2;
|
||||
//物业服务
|
||||
public const CATEGORY_SERVICE = 8;
|
||||
//新闻碎片
|
||||
public const CATEGORY_NEWS_BLOCK = 14;
|
||||
//新闻碎片
|
||||
public const CATEGORY_JOIN_BLOCK = 15;
|
||||
//新闻碎片
|
||||
public const CATEGORY_SERVE_BLOCK = 16;
|
||||
|
||||
|
||||
// 案例模版
|
||||
public const TEMPLATE_NEWS = 'news_list';
|
||||
// 案例模版
|
||||
public const TEMPLATE_CASES = 'cases_list';
|
||||
// 解决方案模版
|
||||
public const TEMPLATE_SCHEME = 'scheme_list';
|
||||
|
||||
// 路由
|
||||
public const RULE_PRODUCT = 'product';
|
||||
public const RULE_DOWNLOAD = 'download';
|
||||
|
||||
// 内容以文本域形式录入配置,默认内容为富文本形式录入
|
||||
public static $contentRawCategoryList = [
|
||||
|
||||
];
|
||||
|
||||
// 允许设置标签的栏目
|
||||
public static $allowTagCategoryList = [
|
||||
|
||||
];
|
||||
|
||||
/*
|
||||
* ====================================================
|
||||
* 分割线
|
||||
* ====================================================
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
//获取首页栏目ID
|
||||
public static function getIndex()
|
||||
{
|
||||
return self::where('is_index', 1)->findOrEmpty()->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据上级ID和语言获取下级栏目
|
||||
*
|
||||
* @param $parentId
|
||||
* @param bool $onlyChild 仅获取下级 默认true false=获取所有后代
|
||||
* @return array
|
||||
*/
|
||||
public static function getChildrenByParentId($parentId, bool $onlyChild = true)
|
||||
{
|
||||
if ($parentId <= 0) {
|
||||
return [];
|
||||
}
|
||||
$category = self::getById($parentId);
|
||||
if (empty($category)) {
|
||||
return [];
|
||||
}
|
||||
if ($onlyChild) {
|
||||
$where[] = ['c.parent_id', '=', $parentId];
|
||||
} else {
|
||||
$where[] = ['c.path', 'like', $category['path'].$parentId.',%'];
|
||||
}
|
||||
return self::alias('c')
|
||||
->leftJoin('model m', 'c.model_id=m.id')
|
||||
->field('c.*, m.manager, m.template, m.name as modelName')
|
||||
// ->where('c.parent_id', $parentId)
|
||||
->where($where)
|
||||
->order('c.sort', 'asc')
|
||||
->order('c.id', 'asc')
|
||||
->select()
|
||||
->toArray();
|
||||
}
|
||||
|
||||
//重写方法
|
||||
public static function getById($categoryId)
|
||||
{
|
||||
return self::alias('c')
|
||||
->leftJoin('model m', 'c.model_id = m.id')
|
||||
->where('c.id', $categoryId)
|
||||
->field('c.*, m.template')
|
||||
->findOrEmpty()
|
||||
->toArray();
|
||||
}
|
||||
|
||||
//查看是否有下级栏目
|
||||
public static function hasChildren($categoryId)
|
||||
{
|
||||
if (is_array($categoryId)) {
|
||||
$count = self::where('parent_id', 'in', $categoryId)->count();
|
||||
} else {
|
||||
$count = self::where(['parent_id' => $categoryId])->count();
|
||||
}
|
||||
return $count ? true : false;
|
||||
}
|
||||
|
||||
//获取前台菜单
|
||||
public static function getListForFrontMenu()
|
||||
{
|
||||
$items = self::alias('c')
|
||||
->leftJoin('model m', 'c.model_id=m.id')
|
||||
->field('c.*, m.manager, m.template')
|
||||
->where('c.state', 1)
|
||||
->where('c.frontend_show', 1)
|
||||
->order('is_index desc, sort asc')
|
||||
->select()
|
||||
->toArray();
|
||||
return self::getCates($items);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取栏目
|
||||
* @param bool $limit 是否限制查询
|
||||
* @param array $cates 需要限制查询的栏目IDs
|
||||
*/
|
||||
public static function getList($limit = false, $cates = [])
|
||||
{
|
||||
if ($limit && empty($cates)) {
|
||||
return [];
|
||||
}
|
||||
return self::alias('c')
|
||||
->leftJoin('model m', 'c.model_id=m.id')
|
||||
->field('c.*, m.manager, m.name as modelName')
|
||||
->when($limit, function ($query) use ($cates) {
|
||||
$query->whereIn('c.id', $cates);
|
||||
})
|
||||
->order('sort', 'asc')
|
||||
->select()
|
||||
->toArray();
|
||||
}
|
||||
|
||||
//获取栏目分级列表
|
||||
public static function getListTree($isMenu = false)
|
||||
{
|
||||
if ($isMenu) {
|
||||
$items = self::where('c.state', 1)->order('sort', 'asc')->select()->toArray();
|
||||
} else {
|
||||
$items = self::order('sort', 'asc')->select()->toArray();
|
||||
}
|
||||
return self::getCates($items);
|
||||
}
|
||||
|
||||
//获取递归栏目
|
||||
public static function getCates($cates, $parentId = 0)
|
||||
{
|
||||
$menus = [];
|
||||
foreach ($cates as $cate) {
|
||||
if ($cate['parent_id'] == $parentId) {
|
||||
$children = self::getCates($cates, $cate['id']);
|
||||
if (!empty($children)) {
|
||||
$cate['children'] = $children;
|
||||
}
|
||||
$menus[] = $cate;
|
||||
}
|
||||
}
|
||||
return $menus;
|
||||
}
|
||||
|
||||
public static function onAfterInsert($category)
|
||||
{
|
||||
$category->sort = $category->id;
|
||||
$category->save();
|
||||
}
|
||||
|
||||
//递归获取栏目名称面包屑
|
||||
public static function getCatesCrumbs($currentId = 0)
|
||||
{
|
||||
$crumbs = [];
|
||||
$category = self::getById($currentId);
|
||||
if ($category) {
|
||||
if ($category['parent_id'] != 0) {
|
||||
$categoryIds = explode(',', trim($category['path'], ','));
|
||||
$categories = self::where('id', 'in', $categoryIds)->column('*', 'id');
|
||||
foreach ($categoryIds as $id) {
|
||||
if (isset($categories[$id])) {
|
||||
$crumbs[] = $categories[$id]['title'];
|
||||
}
|
||||
}
|
||||
}
|
||||
$crumbs[] = $category['title'];
|
||||
}
|
||||
return $crumbs;
|
||||
}
|
||||
|
||||
//获取栏目中涉及到的文件
|
||||
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;
|
||||
}
|
||||
|
||||
//当前分类的最高级分类Id
|
||||
public static function firstGradeById($id)
|
||||
{
|
||||
$res = 0;
|
||||
$item = self::getById($id);
|
||||
if ($item) {
|
||||
$res = $id;
|
||||
if ($item['parent_id'] > 0) {
|
||||
$items = self::select()->toArray();
|
||||
$first = self::getFirstGrade($items, $item['parent_id']);
|
||||
if (!empty($first)) {
|
||||
$res = $first['id'];
|
||||
}
|
||||
}
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
public static function getFirstGrade($items, $parentId)
|
||||
{
|
||||
$data = [];
|
||||
foreach ($items as $key => $item) {
|
||||
if ($item['id'] == $parentId) {
|
||||
if ($item['parent_id'] > 0) {
|
||||
unset($items[$key]);
|
||||
$parent = self::getFirstGrade($items, $item['parent_id']);
|
||||
if (!empty($parent)) {
|
||||
$data = $parent;
|
||||
} else {
|
||||
$data = $item;
|
||||
}
|
||||
} else {
|
||||
$data = $item;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 当前分类和子分类
|
||||
*
|
||||
* @param int $parentId
|
||||
* @return array
|
||||
*/
|
||||
public static function getCategoryWithChildren(int $parentId)
|
||||
{
|
||||
$item = self::getById($parentId);
|
||||
if ($item) {
|
||||
$childList = self::getChildrenByParentId($parentId);
|
||||
$childIds = [];
|
||||
foreach ($childList as $child) {
|
||||
$childIds[] = $child['id'];
|
||||
}
|
||||
$item['children'] = $childList;
|
||||
$item['children_ids'] = $childIds;
|
||||
}
|
||||
|
||||
return $item;
|
||||
}
|
||||
|
||||
/**
|
||||
* 当前分类和子分类的ID集
|
||||
* @param int $parentId
|
||||
* @return array|int[]
|
||||
*/
|
||||
public static function getCategoryWithChildrenIds(int $parentId)
|
||||
{
|
||||
$categoryIds = [$parentId];
|
||||
$item = self::getCategoryWithChildren($parentId);
|
||||
if ($item) {
|
||||
$categoryIds = array_merge($categoryIds, $item['children_ids']);
|
||||
}
|
||||
return $categoryIds;
|
||||
}
|
||||
|
||||
public static function getByRuleAlias($alias)
|
||||
{
|
||||
return self::where('route', $alias)->findOrEmpty()->toArray();
|
||||
}
|
||||
|
||||
/*
|
||||
* 设置了路由别名的栏目
|
||||
* 路由别名长度大的优先排序,路由匹配优先规则
|
||||
*/
|
||||
public static function getRouteList()
|
||||
{
|
||||
return self::whereRaw('char_length(route) > 0')
|
||||
->field('id,route,model_id, char_length(route) as alias_len')
|
||||
->order('alias_len', 'desc')
|
||||
->select()
|
||||
->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有下级分类
|
||||
*
|
||||
* @param int $parentId
|
||||
* @return Collection
|
||||
* @throws DataNotFoundException
|
||||
* @throws DbException
|
||||
* @throws ModelNotFoundException
|
||||
*/
|
||||
public static function findAllChildren(int $parentId)
|
||||
{
|
||||
return self::whereFindInSet('path', $parentId)->select();
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据栏目分组ID获取该分组所有的栏目ID集
|
||||
*
|
||||
* @param int $groupId
|
||||
* @return array|int[]
|
||||
* @throws DataNotFoundException
|
||||
* @throws DbException
|
||||
* @throws ModelNotFoundException
|
||||
*/
|
||||
public static function getGroupCategoryIds(int $groupId)
|
||||
{
|
||||
$list = [$groupId];
|
||||
$items = self::findAllChildren($groupId);
|
||||
$childrenIds = $items->column('id');
|
||||
|
||||
return array_merge($list, $childrenIds);
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断当前分类是否为文章类
|
||||
*
|
||||
* @param int $cateId
|
||||
*/
|
||||
public static function isArticle(int $cateId)
|
||||
{
|
||||
$item = self::getById($cateId);
|
||||
$res = false;
|
||||
if (!empty($item) && $item['model_id'] == Model::MODEL_ARTICLE) {
|
||||
$res = true;
|
||||
}
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据栏目标识获取栏目信息
|
||||
*
|
||||
* @param string $categoryKey
|
||||
* @return array|\think\Model|null
|
||||
* @throws DataNotFoundException
|
||||
* @throws DbException
|
||||
* @throws ModelNotFoundException
|
||||
*/
|
||||
public static function findByCategoryKey(string $categoryKey)
|
||||
{
|
||||
if (strlen($categoryKey) == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return self::where('category_key', $categoryKey)->find();
|
||||
}
|
||||
|
||||
|
||||
public static function navList($categoryId = 0)
|
||||
{
|
||||
$menus = self::getListForFrontMenu();
|
||||
$allCategories = Category::getList(false);
|
||||
foreach ($menus as &$menu) {
|
||||
$menu['children_ids'] = [];
|
||||
// $menusGroup = [];
|
||||
if (isset($menu['children'])) {
|
||||
$menu['children_ids'] = array_column($menu['children'], 'id');
|
||||
// foreach ($menu['children'] as $child) {
|
||||
// $menusGroup[$child['group_name']][] = $child;
|
||||
// }
|
||||
}
|
||||
|
||||
// $menu['menus_group'] = $menusGroup;
|
||||
$menu['all_subordinate_ids'] = self::getAllSubordinateIds($allCategories, $menu['id'], true);
|
||||
$menu['isActive'] = 0;
|
||||
if ($categoryId == $menu['id'] || in_array($categoryId, $menu['all_subordinate_ids'])) {
|
||||
$menu['isActive'] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
$data = [
|
||||
// 'categoryId' => $categoryId,
|
||||
'menus' => $menus,
|
||||
];
|
||||
// var_dump($menus);exit;
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
// 所有下级栏目ID 包含当前栏目ID
|
||||
private static function getAllSubordinateIds($items, $curId = 0, $containCurrent = false)
|
||||
{
|
||||
$list = [];
|
||||
foreach ($items as $k => $item) {
|
||||
if ($item['parent_id'] == $curId) {
|
||||
$list[] = $item['id'];
|
||||
unset($items[$k]);
|
||||
$childrenIds = self::getAllSubordinateIds($items, $item['id']);
|
||||
if ($childrenIds) {
|
||||
$list = array_merge($list, $childrenIds);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($containCurrent) {
|
||||
$list = array_merge([$curId], $list);
|
||||
}
|
||||
return $list;
|
||||
}
|
||||
|
||||
|
||||
//当前分类的最高级分类Id
|
||||
public static function getPosition($id)
|
||||
{
|
||||
$position = "";
|
||||
$item = self::getById($id);
|
||||
if ($item) {
|
||||
$position= "<a href=\"".getUri($item)."\">{$item['title']}</a>";
|
||||
if ($item['parent_id'] > 0) {
|
||||
$items = self::select()->toArray();
|
||||
$first = self::getPositionGrade($items, $item['parent_id']);
|
||||
|
||||
if (!empty($first)) {
|
||||
$position = $first.$position;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $position;
|
||||
}
|
||||
|
||||
public static function getPositionGrade($items, $parentId)
|
||||
{
|
||||
$data="";
|
||||
foreach ($items as $key => $item) {
|
||||
if ($item['id'] == $parentId) {
|
||||
$data = "<a href=\"".getUri($item)."\">{$item['title']}</a>";
|
||||
if ($item['parent_id'] > 0) {
|
||||
unset($items[$key]);
|
||||
$parent = self::getFirstGrade($items, $item['parent_id']);
|
||||
if (!empty($parent)) {
|
||||
$data = "<a href=\"".getUri($parent)."\">{$parent['title']}</a>".$data;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,115 @@
|
|||
<?php
|
||||
namespace app\model;
|
||||
|
||||
use think\facade\Config as CConfig;
|
||||
|
||||
class ConfigSetting extends Base
|
||||
{
|
||||
// 是否开启同步生成扩展配置文件
|
||||
const with_write_config = true;
|
||||
|
||||
public static function setConfigByName(string $name, array $content)
|
||||
{
|
||||
$config = self::getConfigByName($name);
|
||||
|
||||
if(empty($config)) {
|
||||
self::create([
|
||||
'name' => $name,
|
||||
'contents' => json_encode($content, JSON_UNESCAPED_UNICODE)
|
||||
]);
|
||||
} else {
|
||||
self::updateById($config['id'], [
|
||||
'contents' => json_encode($content, JSON_UNESCAPED_UNICODE)
|
||||
]);
|
||||
}
|
||||
|
||||
// 同步写入与生成配置文件
|
||||
if (self::with_write_config) {
|
||||
self::setWithExtraConfigFile($name, $content);
|
||||
}
|
||||
}
|
||||
|
||||
public static function getConfigByName(string $name)
|
||||
{
|
||||
$item = self::where('name', $name)
|
||||
->findOrEmpty()
|
||||
->toArray();
|
||||
|
||||
return self::convertContents($item);
|
||||
}
|
||||
|
||||
// 通过数据库查询配置信息
|
||||
public static function getConfigContentsByName(string $name)
|
||||
{
|
||||
$item = self::getConfigByName($name);
|
||||
return $item['contents'] ?? [];
|
||||
}
|
||||
|
||||
public static function convertContents(array $item)
|
||||
{
|
||||
if(empty($item)) {
|
||||
return [];
|
||||
}
|
||||
$item['contents'] = empty($item['contents']) ? [] : json_decode($item['contents'], true);
|
||||
return $item;
|
||||
}
|
||||
|
||||
|
||||
// 优先通过扩展配置文件查询配置信息,没有查询到再从数据库中查询
|
||||
public static function getConfigContentsWithFileByName(string $name)
|
||||
{
|
||||
$conf = [];
|
||||
if (self::with_write_config) {
|
||||
$extraFileName = self::parseExtraConfigFileNameByName($name);
|
||||
CConfig::load('extra/'.$extraFileName, $name);
|
||||
$conf = config($name);
|
||||
}
|
||||
|
||||
if (!empty($conf)) {
|
||||
return $conf;
|
||||
|
||||
} else {
|
||||
$item = self::getConfigByName($name);
|
||||
return $item['contents'] ?? [];
|
||||
}
|
||||
}
|
||||
|
||||
// 通过配置名称解析扩展配置文件名称
|
||||
public static function parseExtraConfigFileNameByName(string $name)
|
||||
{
|
||||
// extra开头
|
||||
if (substr($name, 0, 5) == 'extra') {
|
||||
$configFileName = substr($name, 5);
|
||||
// 字符串首字母转小写
|
||||
$configFileName = lcfirst($configFileName);
|
||||
} else {
|
||||
$configFileName = $name;
|
||||
}
|
||||
|
||||
return $configFileName;
|
||||
}
|
||||
|
||||
// 扩展配置信息写入扩展配置文件
|
||||
public static function setWithExtraConfigFile(string $name, array $content = [])
|
||||
{
|
||||
try {
|
||||
$configFileName = self::parseExtraConfigFileNameByName($name);
|
||||
if (!is_numeric($configFileName) && empty($configFileName)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$extraPath = config_path().'extra/';
|
||||
checkPathExistWithMake($extraPath);
|
||||
$configFil = $extraPath.$configFileName.'.php';
|
||||
$configData = var_export($content, true);
|
||||
|
||||
file_put_contents($configFil, '<?php' . PHP_EOL . 'return ' . $configData . ';');
|
||||
|
||||
return true;
|
||||
} catch (\Exception $e) {
|
||||
\think\facade\Log::write('请检查扩展配置文件目录config/extra是否拥有可读写权限', 'error');
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,96 @@
|
|||
<?php
|
||||
namespace app\model;
|
||||
|
||||
use think\Paginator;
|
||||
|
||||
class DownloadModel extends Base
|
||||
{
|
||||
protected $name = 'download';
|
||||
|
||||
public static function onAfterInsert($item)
|
||||
{
|
||||
$item->sort = $item->id;
|
||||
$item->save();
|
||||
}
|
||||
|
||||
public static function getPaginateList($categoryId, $per = 20, $isSample = false)
|
||||
{
|
||||
$paginate = [
|
||||
'list_rows' => $per,
|
||||
'query' => ['category_id' => $categoryId]
|
||||
];
|
||||
return self::where('category_id', $categoryId)->order('sort', 'desc')->paginate($paginate, $isSample);
|
||||
}
|
||||
|
||||
public static function getByCategoryId($categoryId, $onlyVisible = false, $pre = 50)
|
||||
{
|
||||
$items = self::where('category_id', $categoryId)
|
||||
->when($onlyVisible, function($query){
|
||||
$query->where('visible', 1);
|
||||
})
|
||||
->order('sort', 'desc')
|
||||
->limit($pre)
|
||||
->select();
|
||||
return $items->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取列表
|
||||
* @param int $categoryId 分类ID
|
||||
* @param int $per 每页数量
|
||||
* @param string $keyword 关键词
|
||||
* @param array $param 类型:置顶、热门、推荐 ['top','hot','recommend']
|
||||
* @param int $status 状态,-1表示不限制
|
||||
* @param array $orderList 排序
|
||||
* @param bool $onlyChild 仅获取下级 默认true false=获取所有后代分类
|
||||
* @return Paginator
|
||||
*/
|
||||
public static function getList(int $categoryId, int $per = 20, string $keyword = '', array $param = [], int $status = -1, array $orderList = ['a.sort' => 'desc'], bool $onlyChild = true)
|
||||
{
|
||||
$whereMap = [];
|
||||
$pageParam = [];
|
||||
if (is_numeric($categoryId) && $categoryId > 0) {
|
||||
$children = Category::getChildrenByParentId($categoryId, $onlyChild);
|
||||
if (!empty($children)) {
|
||||
$categoryIds = [$categoryId];
|
||||
foreach ($children as $child) {
|
||||
if ($child['model_id'] == Model::MODEL_DOWNLOAD) {
|
||||
$categoryIds[] = $child['id'];
|
||||
}
|
||||
}
|
||||
$whereMap[] = ['a.category_id', 'in', $categoryIds];
|
||||
} else {
|
||||
$whereMap[] = ['a.category_id', '=', $categoryId];
|
||||
}
|
||||
$pageParam['category_id'] = $categoryId;
|
||||
}
|
||||
if (!empty($keyword)) {
|
||||
$whereMap[] = ['a.title', 'like', '%'.$keyword.'%'];
|
||||
$pageParam['keyword'] = $keyword;
|
||||
}
|
||||
if (is_array($param) && count($param) > 0) {
|
||||
$pageParam['param'] = $param;
|
||||
foreach ($param as $vo) {
|
||||
if (in_array($vo, ['top', 'hot', 'recommend'], true)) {
|
||||
$whereMap[] = ["a.{$vo}", '=', 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
$paginate = [
|
||||
'list_rows' => $per,
|
||||
'query' => $pageParam
|
||||
];
|
||||
|
||||
return self::alias('a')
|
||||
->leftJoin('category c', 'c.id = a.category_id')
|
||||
->when(count($whereMap) > 0, function ($query) use ($whereMap) {
|
||||
$query->where($whereMap);
|
||||
})
|
||||
->when($status != -1, function ($query) use ($status) {
|
||||
$query->where('a.visible', $status);
|
||||
})
|
||||
->order($orderList)
|
||||
->field('a.*, c.title as category_title')
|
||||
->paginate($paginate, false);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,96 @@
|
|||
<?php
|
||||
namespace app\model;
|
||||
|
||||
use think\Image;
|
||||
|
||||
class File extends Base
|
||||
{
|
||||
const IMG = 'img';
|
||||
const VIDEO = 'video';
|
||||
const FILE = 'file';
|
||||
const AUDIO = 'audio';
|
||||
|
||||
//获取文件类型
|
||||
public static function getTypes()
|
||||
{
|
||||
return [
|
||||
'img' => '图片',
|
||||
'video' => '视频',
|
||||
'file' => '文件',
|
||||
'audio' => '音频',
|
||||
];
|
||||
}
|
||||
|
||||
//获取文件列表
|
||||
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, $type = 'img')
|
||||
{
|
||||
$realPath = app()->getRootPath() . ltrim($src,'/');
|
||||
if(is_file($realPath) && $type == 'img'){
|
||||
$img = Image::open($realPath);
|
||||
list($w,$h) = $img->size();
|
||||
$w_h = $w . 'px * ' . $h . 'px';
|
||||
}else{
|
||||
$w_h = '';
|
||||
}
|
||||
return self::create([
|
||||
'type' => $type,
|
||||
'name' => $file->getOriginalName(),
|
||||
'src' => $src,
|
||||
'size' => $file->getSize(),
|
||||
'suffix' => $file->getOriginalExtension(),
|
||||
'mime_type' => $file->getOriginalMime(),
|
||||
'create_time' => time(),
|
||||
'w_h' => $w_h,
|
||||
'md5' => $file->md5()
|
||||
]);
|
||||
}
|
||||
|
||||
//获取所有记录
|
||||
public static function getAll()
|
||||
{
|
||||
return self::select()->toArray();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
<?php
|
||||
namespace app\model;
|
||||
|
||||
class History extends Base
|
||||
{
|
||||
public static function onAfterInsert($item)
|
||||
{
|
||||
$item->sort = $item->id;
|
||||
$item->save();
|
||||
}
|
||||
|
||||
public static function getPaginateList($categoryId, $per = 20, $isSample = false)
|
||||
{
|
||||
$paginate = [
|
||||
'list_rows' => $per,
|
||||
'query' => ['category_id' => $categoryId]
|
||||
];
|
||||
$items = self::where('category_id', $categoryId)->order('sort', 'asc')->paginate($paginate, $isSample);
|
||||
if(!$items->isEmpty()) {
|
||||
$ids = $items->column('id');
|
||||
$infoList = HistoryInfo::getByHistoryIds($ids);
|
||||
foreach ($items as $k => $item) {
|
||||
$items[$k]['info'] = $infoList[$item['id']] ?? [];
|
||||
}
|
||||
}
|
||||
return $items;
|
||||
}
|
||||
|
||||
public static function getByCategoryId($categoryId, $onlyVisible = false, $pre = 50)
|
||||
{
|
||||
$items = self::where('category_id', $categoryId)
|
||||
->when($onlyVisible, function($query){
|
||||
$query->where('visible', 1);
|
||||
})
|
||||
->order('sort', 'asc')
|
||||
->limit($pre)
|
||||
->select();
|
||||
if(!$items->isEmpty()) {
|
||||
$ids = $items->column('id');
|
||||
$infoList = HistoryInfo::getByHistoryIds($ids, $onlyVisible);
|
||||
foreach ($items as $k => $item) {
|
||||
$items[$k]['info'] = $infoList[$item['id']] ?? [];
|
||||
}
|
||||
}
|
||||
return $items->toArray();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
<?php
|
||||
namespace app\model;
|
||||
|
||||
class HistoryInfo extends Base
|
||||
{
|
||||
public static function onAfterInsert($item)
|
||||
{
|
||||
$item->sort = $item->id;
|
||||
$item->save();
|
||||
}
|
||||
|
||||
public static function getByHistoryIds($historyIds = [], $onlyVisible = false)
|
||||
{
|
||||
if(!is_array($historyIds) || count($historyIds) == 0) {
|
||||
return [];
|
||||
}
|
||||
$list = self::whereIn('history_id', $historyIds)
|
||||
->when($onlyVisible, function ($query) {
|
||||
$query->where('visible', 1);
|
||||
})
|
||||
->order(['history_id'=>'asc','sort'=>'asc'])
|
||||
->select()
|
||||
->toArray();
|
||||
$data = [];
|
||||
foreach ($list as $item) {
|
||||
$item['img_list'] = [];
|
||||
if(!empty($item['imgs'])) {
|
||||
$item['img_list'] = array_filter(explode(',', $item['imgs']));
|
||||
}
|
||||
$data[$item['history_id']][] = $item;
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
public static function countByHistoryId($historyId)
|
||||
{
|
||||
return self::where('history_id', $historyId)->count();
|
||||
}
|
||||
|
||||
public static function delByHistoryId($historyId)
|
||||
{
|
||||
return self::where('history_id', $historyId)->delete();
|
||||
}
|
||||
|
||||
public static function getByHistoryId($historyId)
|
||||
{
|
||||
if($historyId <= 0) {
|
||||
return [];
|
||||
}
|
||||
return self::where('history_id', $historyId)->order(['sort'=>'asc'])->select()->toArray();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
namespace app\model;
|
||||
|
||||
class Honour extends Base
|
||||
{
|
||||
public static function onAfterInsert($item)
|
||||
{
|
||||
$item->sort = $item->id;
|
||||
$item->save();
|
||||
}
|
||||
|
||||
public static function getPaginateList($categoryId, $per = 20, $isSample = false)
|
||||
{
|
||||
$paginate = [
|
||||
'list_rows' => $per,
|
||||
'query' => ['category_id' => $categoryId]
|
||||
];
|
||||
return self::where('category_id', $categoryId)->order('sort', 'asc')->paginate($paginate, $isSample);
|
||||
}
|
||||
|
||||
public static function getByCategoryId($categoryId, $onlyVisible = false, $pre = 50)
|
||||
{
|
||||
$items = self::where('category_id', $categoryId)
|
||||
->when($onlyVisible, function($query){
|
||||
$query->where('visible', 1);
|
||||
})
|
||||
->order('sort', 'asc')
|
||||
->limit($pre)
|
||||
->select();
|
||||
return $items->toArray();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
<?php
|
||||
namespace app\model;
|
||||
|
||||
class Link extends Base
|
||||
{
|
||||
public static function delByIds($ids)
|
||||
{
|
||||
return self::whereIn('id', $ids)->delete();
|
||||
}
|
||||
|
||||
//获取友情链接
|
||||
public static function getList($limit=0)
|
||||
{
|
||||
return self::order('sort asc')
|
||||
->when($limit > 0, function($q) use ($limit) {
|
||||
$q->limit($limit);
|
||||
})
|
||||
->select()
|
||||
->toArray();
|
||||
}
|
||||
|
||||
public static function onAfterInsert($item)
|
||||
{
|
||||
$item->sort = $item->id;
|
||||
$item->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;
|
||||
}
|
||||
|
||||
// 分页查询
|
||||
public static function getListWithPaginate($where=[], $limit=10, $simplePage = false)
|
||||
{
|
||||
return self::where($where)
|
||||
->order('sort asc')
|
||||
->paginate([
|
||||
'list_rows' => $limit
|
||||
], $simplePage);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
<?php
|
||||
namespace app\model;
|
||||
|
||||
/**
|
||||
* 产品快链管理
|
||||
*
|
||||
* Class LinkProduct
|
||||
* @package app\model
|
||||
*/
|
||||
class LinkProduct extends Base
|
||||
{
|
||||
public static function delByIds($ids)
|
||||
{
|
||||
return self::whereIn('id', $ids)->delete();
|
||||
}
|
||||
|
||||
//获取列表
|
||||
public static function getList($limit = 10, $where = [], $orders = ['sort'=>'asc'])
|
||||
{
|
||||
return self::order($orders)
|
||||
->when(!empty($where), function ($q) use ($where) {
|
||||
$q->where($where);
|
||||
})
|
||||
->when($limit > 0, function ($q) use ($limit) {
|
||||
$q->limit($limit);
|
||||
})
|
||||
->select()
|
||||
->toArray();
|
||||
}
|
||||
|
||||
public static function onAfterInsert($item)
|
||||
{
|
||||
$item->sort = $item->id;
|
||||
$item->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,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['userId'],
|
||||
'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,72 @@
|
|||
<?php
|
||||
namespace app\model;
|
||||
|
||||
class Member extends Base
|
||||
{
|
||||
public static function getList($limit = 40)
|
||||
{
|
||||
$items = 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);
|
||||
return $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据角色分组返回用户
|
||||
* @param int $groupId 角色分组ID
|
||||
* @param int $limit 每页数量
|
||||
*/
|
||||
public static function getListByGroup($groupId, $limit = 40)
|
||||
{
|
||||
$items = 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);
|
||||
return $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据角色分组返回用户
|
||||
* @param int $limit 每页数量
|
||||
* @return mixed
|
||||
*/
|
||||
public static function getListNotAdmin(int $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', '<>', 1)
|
||||
->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,60 @@
|
|||
<?php
|
||||
namespace app\model;
|
||||
|
||||
class Message extends Base
|
||||
{
|
||||
/**
|
||||
* 获取留言列表
|
||||
*/
|
||||
public static function getList($per = 20, $startDate='', $endDate='')
|
||||
{
|
||||
$param = [];
|
||||
if(!empty($startDate)) {
|
||||
$param['startDate'] = $startDate;
|
||||
}
|
||||
if(!empty($endDate)) {
|
||||
$param['endDate'] = $endDate;
|
||||
}
|
||||
|
||||
$paginate = [
|
||||
'list_rows' => $per,
|
||||
'query' => $param
|
||||
];
|
||||
|
||||
$items = self::when(!empty($startDate) && strtotime($startDate), function ($query) use($startDate) {
|
||||
$startTime = strtotime(date('Y-m-d 00:00:00', strtotime($startDate)));
|
||||
$query->where('create_time', '>=', $startTime);
|
||||
})
|
||||
->when(!empty($endDate) && strtotime($endDate), function ($query) use($endDate) {
|
||||
$endTime = strtotime(date('Y-m-d 23:59:59', strtotime($endDate)));
|
||||
$query->where('create_time', '<=', $endTime);
|
||||
})
|
||||
->order("create_time", 'desc')
|
||||
->paginate($paginate);
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
public static function onAfterInsert($item)
|
||||
{
|
||||
$item->create_time = time();
|
||||
$item->save();
|
||||
}
|
||||
|
||||
public static function getExportList($startDate='', $endDate='', $limit = 10000)
|
||||
{
|
||||
return self::when(!empty($startDate) && strtotime($startDate), function ($query) use($startDate) {
|
||||
$startTime = strtotime(date('Y-m-d 00:00:00', strtotime($startDate)));
|
||||
$query->where('create_time', '>=', $startTime);
|
||||
})
|
||||
->when(!empty($endDate) && strtotime($endDate), function ($query) use($endDate) {
|
||||
$endTime = strtotime(date('Y-m-d 23:59:59', strtotime($endDate)));
|
||||
$query->where('create_time', '<=', $endTime);
|
||||
})
|
||||
->order('create_time', 'desc')
|
||||
->limit($limit)
|
||||
->select()
|
||||
->toArray();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
namespace app\model;
|
||||
|
||||
class Model extends Base
|
||||
{
|
||||
// 文章模型ID
|
||||
const MODEL_ARTICLE = 31;
|
||||
// 单页模型
|
||||
const MODEL_PAGE = 33;
|
||||
// 产品模型
|
||||
const MODEL_PRODUCT = 36;
|
||||
// 下载中心
|
||||
const MODEL_DOWNLOAD = 37;
|
||||
|
||||
//获取模型列表
|
||||
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,96 @@
|
|||
<?php
|
||||
namespace app\model;
|
||||
|
||||
use think\Paginator;
|
||||
|
||||
class PositionModel extends Base
|
||||
{
|
||||
protected $name = 'position';
|
||||
|
||||
public static function onAfterInsert($item)
|
||||
{
|
||||
$item->sort = $item->id;
|
||||
$item->save();
|
||||
}
|
||||
|
||||
public static function getPaginateList($categoryId, $per = 20, $isSample = false)
|
||||
{
|
||||
$paginate = [
|
||||
'list_rows' => $per,
|
||||
'query' => ['category_id' => $categoryId]
|
||||
];
|
||||
return self::where('category_id', $categoryId)->order('sort', 'desc')->paginate($paginate, $isSample);
|
||||
}
|
||||
|
||||
public static function getByCategoryId($categoryId, $onlyVisible = false, $pre = 50)
|
||||
{
|
||||
$items = self::where('category_id', $categoryId)
|
||||
->when($onlyVisible, function($query){
|
||||
$query->where('visible', 1);
|
||||
})
|
||||
->order('sort', 'asc')
|
||||
->limit($pre)
|
||||
->select();
|
||||
return $items->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取列表
|
||||
* @param int $categoryId 分类ID
|
||||
* @param int $per 每页数量
|
||||
* @param string $keyword 关键词
|
||||
* @param array $param 类型:置顶、热门、推荐 ['top','hot','recommend']
|
||||
* @param int $status 状态,-1表示不限制
|
||||
* @param array $orderList 排序
|
||||
* @param bool $onlyChild 仅获取下级 默认true false=获取所有后代分类
|
||||
* @return Paginator
|
||||
*/
|
||||
public static function getList(int $categoryId, int $per = 20, string $keyword = '', array $param = [], int $status = -1, array $orderList = ['a.sort' => 'desc'], bool $onlyChild = true)
|
||||
{
|
||||
$whereMap = [];
|
||||
$pageParam = [];
|
||||
if (is_numeric($categoryId) && $categoryId > 0) {
|
||||
$children = Category::getChildrenByParentId($categoryId, $onlyChild);
|
||||
if (!empty($children)) {
|
||||
$categoryIds = [$categoryId];
|
||||
foreach ($children as $child) {
|
||||
if ($child['model_id'] == Model::MODEL_PRODUCT) {
|
||||
$categoryIds[] = $child['id'];
|
||||
}
|
||||
}
|
||||
$whereMap[] = ['a.category_id', 'in', $categoryIds];
|
||||
} else {
|
||||
$whereMap[] = ['a.category_id', '=', $categoryId];
|
||||
}
|
||||
$pageParam['category_id'] = $categoryId;
|
||||
}
|
||||
if (!empty($keyword)) {
|
||||
$whereMap[] = ['a.title', 'like', '%'.$keyword.'%'];
|
||||
$pageParam['keyword'] = $keyword;
|
||||
}
|
||||
if (is_array($param) && count($param) > 0) {
|
||||
$pageParam['param'] = $param;
|
||||
foreach ($param as $vo) {
|
||||
if (in_array($vo, ['top', 'hot', 'recommend'], true)) {
|
||||
$whereMap[] = ["a.{$vo}", '=', 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
$paginate = [
|
||||
'list_rows' => $per,
|
||||
'query' => $pageParam
|
||||
];
|
||||
|
||||
return self::alias('a')
|
||||
->leftJoin('category c', 'c.id = a.category_id')
|
||||
->when(count($whereMap) > 0, function ($query) use ($whereMap) {
|
||||
$query->where($whereMap);
|
||||
})
|
||||
->when($status != -1, function ($query) use ($status) {
|
||||
$query->where('a.visible', $status);
|
||||
})
|
||||
->order($orderList)
|
||||
->field('a.*, c.title as category_title')
|
||||
->paginate($paginate, false);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,94 @@
|
|||
<?php
|
||||
namespace app\model;
|
||||
|
||||
use think\Paginator;
|
||||
|
||||
class ProductModel extends Base
|
||||
{
|
||||
protected $name = 'product';
|
||||
|
||||
public static function onAfterInsert($item)
|
||||
{
|
||||
$item->sort = $item->id;
|
||||
$item->save();
|
||||
}
|
||||
|
||||
public static function getPaginateList($categoryId, $per = 20, $isSample = false)
|
||||
{
|
||||
$paginate = [
|
||||
'list_rows' => $per,
|
||||
'query' => ['category_id' => $categoryId]
|
||||
];
|
||||
return self::where('category_id', $categoryId)->order('sort', 'desc')->paginate($paginate, $isSample);
|
||||
}
|
||||
|
||||
public static function getByCategoryId($categoryId, $onlyVisible = false, $pre = 50)
|
||||
{
|
||||
$items = self::where('category_id', $categoryId)
|
||||
->when($onlyVisible, function($query){
|
||||
$query->where('visible', 1);
|
||||
})
|
||||
->order('sort', 'asc')
|
||||
->limit($pre)
|
||||
->select();
|
||||
return $items->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取列表
|
||||
* @param int $categoryId 分类ID
|
||||
* @param int $per 每页数量
|
||||
* @param string $keyword 关键词
|
||||
* @param array $param 类型:置顶、热门、推荐 ['top','hot','recommend']
|
||||
* @param int $status 状态,-1表示不限制
|
||||
* @param array $orderList 排序
|
||||
* @param bool $onlyChild 仅获取下级 默认true false=获取所有后代分类
|
||||
* @return Paginator
|
||||
*/
|
||||
public static function getList(int $categoryId, int $per = 20, string $keyword = '', array $param = [], int $status = -1, array $orderList = ['a.sort' => 'desc'], bool $onlyChild = true, array $queryParam = [])
|
||||
{
|
||||
$whereMap = [];
|
||||
if (is_numeric($categoryId) && $categoryId > 0) {
|
||||
$children = Category::getChildrenByParentId($categoryId, $onlyChild);
|
||||
if (!empty($children)) {
|
||||
$categoryIds = [$categoryId];
|
||||
foreach ($children as $child) {
|
||||
if ($child['model_id'] == Model::MODEL_PRODUCT) {
|
||||
$categoryIds[] = $child['id'];
|
||||
}
|
||||
}
|
||||
$whereMap[] = ['a.category_id', 'in', $categoryIds];
|
||||
} else {
|
||||
$whereMap[] = ['a.category_id', '=', $categoryId];
|
||||
}
|
||||
}
|
||||
if (!empty($keyword)) {
|
||||
$whereMap[] = ['a.title', 'like', '%'.$keyword.'%'];
|
||||
$pageParam['keyword'] = $keyword;
|
||||
}
|
||||
if (is_array($param) && count($param) > 0) {
|
||||
$pageParam['param'] = $param;
|
||||
foreach ($param as $vo) {
|
||||
if (in_array($vo, ['top', 'hot', 'recommend'], true)) {
|
||||
$whereMap[] = ["a.{$vo}", '=', 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
$paginate = [
|
||||
'list_rows' => $per,
|
||||
'query' => $queryParam
|
||||
];
|
||||
|
||||
return self::alias('a')
|
||||
->leftJoin('category c', 'c.id = a.category_id')
|
||||
->when(count($whereMap) > 0, function ($query) use ($whereMap) {
|
||||
$query->where($whereMap);
|
||||
})
|
||||
->when($status != -1, function ($query) use ($status) {
|
||||
$query->where('a.visible', $status);
|
||||
})
|
||||
->order($orderList)
|
||||
->field('a.*, c.title as category_title')
|
||||
->paginate($paginate, false);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
<?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;
|
||||
}
|
||||
$mobileSrc = trim($item['src_mobile']);
|
||||
if(!empty($mobileSrc)){
|
||||
$key = getKeyByPath($mobileSrc);
|
||||
$data[$key] = $mobileSrc;
|
||||
}
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
namespace app\model;
|
||||
|
||||
/**
|
||||
* 短信记录
|
||||
* Class SmsLog
|
||||
* @package app\model
|
||||
*/
|
||||
class SmsLog extends Base
|
||||
{
|
||||
public static $typeList = [
|
||||
'resister' => 'reg',
|
||||
'appointment' => 'appoint',
|
||||
];
|
||||
|
||||
public static function countByPhone($phone, $starTime=0,$endTime=0, $type='')
|
||||
{
|
||||
return self::where('phone', $phone)
|
||||
->when($starTime > 0, function ($query) use($starTime) {
|
||||
$query->where('create_time', '>=', $starTime);
|
||||
})
|
||||
->when($endTime > 0, function ($query) use($endTime) {
|
||||
$query->where('create_time', '<=', $endTime);
|
||||
})
|
||||
->when(!empty($type) && in_array($type, self::$typeList), function ($query) use($type) {
|
||||
$query->where('type', $type);
|
||||
})
|
||||
->count();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
<?php
|
||||
namespace app\model;
|
||||
|
||||
//特殊路由表
|
||||
class SpecialRoute extends Base
|
||||
{
|
||||
|
||||
const type_archives = "archives";
|
||||
const type_archives_category = "archives_category";
|
||||
public static function findOneByUrl(string $url="")
|
||||
{
|
||||
return self::where('route', $url)->find();
|
||||
}
|
||||
|
||||
public static function deleteByTypeIds($ids,$type)
|
||||
{
|
||||
return self::where([['relation_id', "in",$ids],["type","=",$type]])->delete();
|
||||
}
|
||||
public static function findByTypeRelaTioneId($relationId,$type)
|
||||
{
|
||||
return self::where([['relation_id', "=",$relationId],["type","=",$type]])->find();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
<?php
|
||||
namespace app\model;
|
||||
|
||||
use think\facade\Config as CConfig;
|
||||
|
||||
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()
|
||||
{
|
||||
$system = self::order('id asc')
|
||||
->findOrEmpty()
|
||||
->toArray();
|
||||
CConfig::load('extra/base', "extraBase");
|
||||
$extraBase = config("extraBase");
|
||||
return array_merge($extraBase,$system);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
<?php
|
||||
|
||||
namespace app\model;
|
||||
|
||||
use think\Paginator;
|
||||
|
||||
class VisitLogoModel extends Base
|
||||
{
|
||||
protected $name = 'visit_log';
|
||||
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
<?php
|
||||
// 容器Provider定义文件
|
||||
return [
|
||||
'think\Paginator' => 'dxtc\Bootstrap'
|
||||
];
|
|
@ -0,0 +1,188 @@
|
|||
<?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 File
|
||||
{
|
||||
//上传文件移动到上传文件夹
|
||||
public static function move(UploadedFile $file)
|
||||
{
|
||||
$upload_path = '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];
|
||||
}
|
||||
|
||||
//导出
|
||||
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,168 @@
|
|||
<?php
|
||||
namespace app\service;
|
||||
|
||||
class Http
|
||||
{
|
||||
public static function curlGet($url,$apiFields = null, $header = [])
|
||||
{
|
||||
$ch = curl_init();
|
||||
if(!empty($apiFields)){
|
||||
$i = 1;
|
||||
foreach ($apiFields as $key => $value){
|
||||
if($i == 1) {
|
||||
if(mb_stripos($url, '?') !== FALSE) {
|
||||
$url .= "&" ."$key=" . urlencode($value);
|
||||
} else {
|
||||
$url .= "?" ."$key=" . urlencode($value);
|
||||
}
|
||||
} else {
|
||||
$url .= "&" ."$key=" . urlencode($value);
|
||||
}
|
||||
$i ++;
|
||||
}
|
||||
}
|
||||
|
||||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_FAILONERROR, false);
|
||||
if(empty($header)){
|
||||
curl_setopt($ch, CURLOPT_HEADER, false);
|
||||
}else{
|
||||
curl_setopt($ch,CURLOPT_HTTPHEADER, $header);
|
||||
}
|
||||
|
||||
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
|
||||
|
||||
//https ignore ssl check ?
|
||||
if(strlen($url) > 5 && strtolower(substr($url,0,5)) == "https" ){
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
|
||||
}
|
||||
|
||||
$reponse = curl_exec($ch);
|
||||
|
||||
if (curl_errno($ch)){
|
||||
throw new \Exception(curl_error($ch),0);
|
||||
}else{
|
||||
$httpStatusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
if (200 !== $httpStatusCode){
|
||||
throw new \Exception($reponse,$httpStatusCode);
|
||||
}
|
||||
}
|
||||
curl_close($ch);
|
||||
return $reponse;
|
||||
}
|
||||
|
||||
public static function curlPost($url, $postFields = null, $header = [], $hasFile = false)
|
||||
{
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
curl_setopt($ch, CURLOPT_FAILONERROR, false);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
//https 请求
|
||||
if(strlen($url) > 5 && strtolower(substr($url,0,5)) == "https" ) {
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
|
||||
}
|
||||
curl_setopt($ch, CURLOPT_POST, true);
|
||||
|
||||
if (is_array($postFields) && 0 < count($postFields))
|
||||
{
|
||||
if($hasFile) {
|
||||
// CURLOPT_POSTFIELDS 值为数组则以multipart/form-data形式提交
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $postFields);
|
||||
} else {
|
||||
$jsonHeader = array("Content-Type: application/json; charset=utf-8", "Content-Length:".strlen(json_encode($postFields)));
|
||||
$header = array_merge($header, $jsonHeader);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($postFields));
|
||||
}
|
||||
|
||||
if(!empty($header)) {
|
||||
curl_setopt($ch,CURLOPT_HTTPHEADER, $header);
|
||||
}
|
||||
}
|
||||
|
||||
$reponse = curl_exec($ch);
|
||||
if (curl_errno($ch))
|
||||
{
|
||||
throw new \Exception(curl_error($ch),0);
|
||||
}
|
||||
else
|
||||
{
|
||||
$httpStatusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
if (200 !== $httpStatusCode)
|
||||
{
|
||||
throw new \Exception($reponse,$httpStatusCode);
|
||||
}
|
||||
}
|
||||
curl_close($ch);
|
||||
return $reponse;
|
||||
}
|
||||
|
||||
public static function curlDelete($url, $postFields = null)
|
||||
{
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE');
|
||||
|
||||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
curl_setopt($ch, CURLOPT_FAILONERROR, false);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
//https 请求
|
||||
if(strlen($url) > 5 && strtolower(substr($url,0,5)) == "https" ) {
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
|
||||
}
|
||||
|
||||
if (is_array($postFields) && 0 < count($postFields))
|
||||
{
|
||||
$header = array("Content-Type: application/json; charset=utf-8", "Content-Length:".strlen(json_encode($postFields)));
|
||||
curl_setopt($ch,CURLOPT_HTTPHEADER,$header);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($postFields));
|
||||
}
|
||||
$reponse = curl_exec($ch);
|
||||
if (curl_errno($ch))
|
||||
{
|
||||
throw new \Exception(curl_error($ch),0);
|
||||
}
|
||||
else
|
||||
{
|
||||
$httpStatusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
if (200 !== $httpStatusCode)
|
||||
{
|
||||
throw new \Exception($reponse,$httpStatusCode);
|
||||
}
|
||||
}
|
||||
curl_close($ch);
|
||||
return $reponse;
|
||||
}
|
||||
|
||||
//POST请求的结果解析
|
||||
public static function decodePostResult($url, $param, $header = [], $hasFile = false)
|
||||
{
|
||||
$resp = [];
|
||||
try {
|
||||
$resp = json_decode(self::curlPost($url, $param, $header, $hasFile), true);
|
||||
$resp['resp_status'] = empty($resp) ? false :true;
|
||||
} catch (\Exception $e) {
|
||||
$resp = json_decode($e->getMessage(), true);
|
||||
$resp['resp_status'] = false;
|
||||
}
|
||||
|
||||
return $resp;
|
||||
}
|
||||
|
||||
//GET请求结果解析
|
||||
public static function decodeGetResult($url, $header=[], $param = [])
|
||||
{
|
||||
$resp = [];
|
||||
try {
|
||||
$resp = json_decode(self::curlGet($url, $param, $header), true);
|
||||
$resp['resp_status'] = empty($resp) ? false :true;
|
||||
} catch (\Exception $e) {
|
||||
$resp = json_decode($e->getMessage(), true);
|
||||
$resp['resp_status'] = false;
|
||||
}
|
||||
|
||||
return $resp;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,140 @@
|
|||
<?php
|
||||
namespace app\service;
|
||||
|
||||
use think\Image as TImage;
|
||||
use app\model\System;
|
||||
|
||||
class Image extends File
|
||||
{
|
||||
/**
|
||||
* 对图片进行重置大小,并对宽度大于max宽度的等比缩放为宽度为1920
|
||||
* milo
|
||||
* 2019-10-24修改
|
||||
*/
|
||||
public static function resize($src)
|
||||
{
|
||||
$max = 1920;
|
||||
$realPath = public_path() . ltrim($src,'/');
|
||||
if(is_file($realPath)){
|
||||
$img = TImage::open($realPath);
|
||||
list($img_w,$img_h) = $img->size();
|
||||
if($max > 0 && $img_w > $max){
|
||||
$height = floor($max * ($img_h / $img_w));
|
||||
$img->thumb($max, $height)->save($realPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加水印
|
||||
* milo
|
||||
* 2018-01-17
|
||||
*/
|
||||
public static function mark($src)
|
||||
{
|
||||
$rootPath = app()->getRootPath();
|
||||
if(!empty($src)){
|
||||
$system = System::getSystem();
|
||||
$realPath = $rootPath . 'public/' . ltrim($src, '/');
|
||||
if(is_file($realPath)){
|
||||
if($system['is_mark']){
|
||||
$mark = $rootPath . ltrim($system['mark_img'], '/');
|
||||
if(is_file($mark)){
|
||||
$mark_position = $system['mark_position']??5;
|
||||
$mark_opacity = $system['mark_opacity']??50;
|
||||
$img = TImage::Open($realPath);
|
||||
$img->water($mark,$mark_position,$mark_opacity)->save($realPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//获取水印位置键值对
|
||||
public static function getMarkPosition()
|
||||
{
|
||||
return [
|
||||
"1" => '上左',
|
||||
"2" => '上中',
|
||||
"3" => '上右',
|
||||
"4" => '中左',
|
||||
"5" => '正中',
|
||||
"6" => '中右',
|
||||
"7" => '下左',
|
||||
"8" => '下中',
|
||||
"9" => '下右'
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除图片
|
||||
* milo
|
||||
* 2018-01-15
|
||||
*/
|
||||
public static function delImg($src)
|
||||
{
|
||||
if(!empty(trim($src))){
|
||||
$realPath = app()->getRootPath() . 'public/' . ltrim($src, '/');
|
||||
if (file_exists($realPath)) {
|
||||
$info = pathinfo($realPath);
|
||||
$source = $info['dirname'] . DIRECTORY_SEPARATOR . $info['filename'] . '*.' . $info['extension'];
|
||||
foreach(glob($source) as $filename){
|
||||
if(is_file($filename)){
|
||||
unlink($filename);
|
||||
}
|
||||
}
|
||||
clearstatcache();// 清除缓存
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 获取缩略图
|
||||
* milo
|
||||
* 2019-10-24修改
|
||||
* 避免跨平台出错,目录分隔符全部转换为'/'
|
||||
* app()->getRuntimePath() = app()->getRootPath().'runtime/当前应用模块(api)/'
|
||||
*/
|
||||
public static function getThumb($src,$width=0,$height=0,$type = TImage::THUMB_CENTER)
|
||||
{
|
||||
if(empty($src)){
|
||||
return '';
|
||||
}
|
||||
//文件存在 就不用切割了
|
||||
$suffix = explode(".",$src);
|
||||
if(count($suffix)==2){
|
||||
$cuttingUrl = $suffix[0]."_".$width."_".$height.".".$suffix[1];
|
||||
if(file_exists(public_path().$cuttingUrl)){
|
||||
return $cuttingUrl;
|
||||
}
|
||||
}
|
||||
$rootPath = app()->getRootPath();
|
||||
$realPath = $rootPath . 'public/' . ltrim($src, '/');
|
||||
$realPath = str_replace('\\', '/', $realPath);
|
||||
if(!file_exists($realPath)){
|
||||
return '';
|
||||
}
|
||||
$info = pathinfo($src);
|
||||
if($width <= 0 && $height <= 0){ //高宽都小于或等于0,则返回原图片
|
||||
return $src;
|
||||
}
|
||||
$image = TImage::open($realPath);
|
||||
list($imageWidth, $imageHeight) = $image->size();
|
||||
if($width <= 0){
|
||||
$width = floor($height * ($imageWidth / $imageHeight));
|
||||
}elseif($height <= 0){
|
||||
$height = floor($width * ($imageHeight / $imageWidth));
|
||||
}
|
||||
if($width >= $imageWidth || $height >= $imageHeight){
|
||||
return $src;
|
||||
}
|
||||
$thumbName = $info['dirname']. DIRECTORY_SEPARATOR .$info['filename'].'_'.$width.'_'.$height.'.'.$info['extension'];
|
||||
$realThumbName = $rootPath . 'public/' . ltrim($thumbName, '/');
|
||||
$realThumbName = str_replace('\\', '/', $realThumbName);
|
||||
if(!file_exists($realThumbName)){
|
||||
$image = TImage::open($realPath);
|
||||
$image->thumb($width, $height, $type)->save($realThumbName);
|
||||
}
|
||||
return str_replace('\\', '/', $thumbName);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,133 @@
|
|||
<?php
|
||||
|
||||
namespace app\service;
|
||||
|
||||
use DateTimeImmutable;
|
||||
use DateTimeZone;
|
||||
use Exception;
|
||||
use Lcobucci\Clock\SystemClock;
|
||||
use Lcobucci\JWT\Configuration;
|
||||
use Lcobucci\JWT\Signer\Hmac\Sha256;
|
||||
use Lcobucci\JWT\Signer\Key\InMemory;
|
||||
use Lcobucci\JWT\UnencryptedToken;
|
||||
use Lcobucci\JWT\Validation\Constraint\IssuedBy;
|
||||
use Lcobucci\JWT\Validation\Constraint\LooseValidAt;
|
||||
use Lcobucci\JWT\Validation\Constraint\PermittedFor;
|
||||
use Lcobucci\JWT\Validation\Constraint\ValidAt;
|
||||
|
||||
class Jwt
|
||||
{
|
||||
private static $secret = 'lF9XkOMfpsR0ODVfbasY2HtDrIps8GIX';
|
||||
private static $expire = 86400 * 3;//秒
|
||||
private static $iss = 'dxtc';//jwt签发者
|
||||
private static $sub = 'dxtc-customer';//jwt所面向的用户
|
||||
private static $aud = 'dxtc-customer';//接受jwt的一方
|
||||
|
||||
private static function config(): Configuration
|
||||
{
|
||||
return Configuration::forSymmetricSigner(
|
||||
// You may use any HMAC variations (256, 384, and 512)
|
||||
new Sha256(),
|
||||
// replace the value below with a key of your own!
|
||||
InMemory::base64Encoded(self::$secret)
|
||||
// You may also override the JOSE encoder/decoder if needed by providing extra arguments here
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取token有效期 单位秒
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public static function expire(): int
|
||||
{
|
||||
return self::$expire;
|
||||
}
|
||||
|
||||
/**
|
||||
* 编码
|
||||
*
|
||||
* @param $data
|
||||
* @param int $expire
|
||||
* @return string
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function generate($data, int $expire = 0): string
|
||||
{
|
||||
$expire = $expire <= 0 ? self::$expire : $expire;
|
||||
$now = new DateTimeImmutable('now', new DateTimeZone('Asia/ShangHai'));
|
||||
|
||||
$token = self::config()->builder()
|
||||
// Configures the issuer (iss claim)
|
||||
->issuedBy(self::$iss)
|
||||
// Configures the audience (aud claim)
|
||||
->permittedFor(self::$aud)
|
||||
// Configures the id (jti claim)
|
||||
// ->identifiedBy($this->jti)
|
||||
// Configures the time that the token was issue (iat claim)
|
||||
->issuedAt($now)
|
||||
// Configures the expiration time of the token (exp claim)
|
||||
->expiresAt($now->modify(sprintf('+%d seconds', $expire)))
|
||||
// Configures a new claim, called "uid"
|
||||
->withClaim('data', $data)
|
||||
// Configures a new header, called "foo"
|
||||
// ->withHeader('foo', 'bar')
|
||||
// Builds a new token
|
||||
->getToken(self::config()->signer(), self::config()->signingKey());
|
||||
|
||||
return $token->toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析
|
||||
*
|
||||
* @param string $tokenStr
|
||||
* @return array|mixed
|
||||
*/
|
||||
public static function parse(string $tokenStr)
|
||||
{
|
||||
$config = self::config();
|
||||
|
||||
try {
|
||||
$token = $config->parser()->parse($tokenStr);
|
||||
assert($token instanceof UnencryptedToken);
|
||||
return $token->claims()->all()['data'] ?? [];
|
||||
} catch (Exception $e) {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证token
|
||||
*
|
||||
* @param string $tokenStr
|
||||
* @return bool
|
||||
*/
|
||||
public static function validate(string $tokenStr): bool
|
||||
{
|
||||
$config = self::config();
|
||||
try {
|
||||
$token = $config->parser()->parse($tokenStr);
|
||||
assert($token instanceof UnencryptedToken);
|
||||
|
||||
//验证签发人iss是否正确
|
||||
$validateIssued = new IssuedBy(self::$iss);
|
||||
$config->setValidationConstraints($validateIssued);
|
||||
//验证客户端aud是否匹配
|
||||
$validateAud = new PermittedFor(self::$aud);
|
||||
$config->setValidationConstraints($validateAud);
|
||||
|
||||
//验证是否过期 exp
|
||||
$timezone = new DateTimeZone('Asia/Shanghai');
|
||||
$now = new SystemClock($timezone);
|
||||
$validateExpired = new LooseValidAt($now);
|
||||
$config->setValidationConstraints($validateExpired);
|
||||
|
||||
$constraints = $config->validationConstraints();
|
||||
|
||||
return $config->validator()->validate($token, ...$constraints);
|
||||
} catch (Exception $e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,102 @@
|
|||
<?php
|
||||
namespace app\service;
|
||||
|
||||
use app\model\Category;
|
||||
use app\model\Article;
|
||||
|
||||
class Tool
|
||||
{
|
||||
//删除文件
|
||||
public static function delFile($path)
|
||||
{
|
||||
if(!empty(trim($path))){
|
||||
$realPath = app()->getRootPath() . ltrim($path, '/');
|
||||
if (file_exists($realPath)) {
|
||||
$info = pathinfo($realPath);
|
||||
$source = $info['dirname'] . DIRECTORY_SEPARATOR . $info['filename'] . '*.' . $info['extension'];
|
||||
foreach(glob($source) as $filename){
|
||||
if(is_file($filename)){
|
||||
unlink($filename);
|
||||
}
|
||||
}
|
||||
clearstatcache();// 清除缓存
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除目录下的所有文件和子目录
|
||||
* 调用完毕后请用clearstatcache()清理缓存
|
||||
*/
|
||||
public static function removeByPath($path)
|
||||
{
|
||||
if(is_dir($path)) {
|
||||
if($handle = @opendir($path)) {
|
||||
while (($file = readdir($handle)) !== false){
|
||||
if($file != '.' && $file != '..') {
|
||||
$child = $path.'/'.$file;
|
||||
is_dir($child) ? self::removeByPath($child) : @unlink($child);
|
||||
}
|
||||
}
|
||||
}
|
||||
closedir($handle);
|
||||
} elseif (is_file($path)) {
|
||||
@unlink($path);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//去除字符串空格
|
||||
public static function trimSpace($str)
|
||||
{
|
||||
return str_replace(' ', '', trim($str));
|
||||
}
|
||||
|
||||
|
||||
//获取文章链接
|
||||
public static function getArticleUrl($article)
|
||||
{
|
||||
if(empty($article)){
|
||||
return '';
|
||||
}
|
||||
// if(!empty($article['link'])){
|
||||
// return $article['link'];
|
||||
// }
|
||||
if(empty($article['route'])){
|
||||
return url('article/detail', ['id' => $article['id']]);
|
||||
}
|
||||
$category = Category::getById($article['category_id']);
|
||||
$categoryRoute = '';
|
||||
if(isset($category['route']) && !empty($category['route'])){
|
||||
$categoryRoute = $category['route'];
|
||||
}
|
||||
$url = '/';
|
||||
if(!empty($categoryRoute)){
|
||||
$url .= $categoryRoute . '/';
|
||||
}
|
||||
return $url . $article['route'] . '.html';
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化金钱字段
|
||||
* @param $money
|
||||
* @return float
|
||||
*/
|
||||
public static function moneyFormat($money)
|
||||
{
|
||||
$money = is_string($money) ? trim($money) : $money;
|
||||
return is_numeric($money) ? number_format($money, 2, '.', '') : 0;
|
||||
}
|
||||
// 获取客户端IP
|
||||
public static function get_client_ip() {
|
||||
$forwarded = request()->header("x-forwarded-for");
|
||||
if($forwarded){
|
||||
$ip = explode(',',$forwarded)[0];
|
||||
}else{
|
||||
$ip = request()->ip();
|
||||
}
|
||||
return $ip;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
<?php
|
||||
namespace app\service\driver;
|
||||
|
||||
|
||||
|
||||
use think\App;
|
||||
use think\session\driver\File;
|
||||
|
||||
/**
|
||||
* 自定义session file 驱动器
|
||||
*
|
||||
* 用于修复TP 自带file驱动器bug
|
||||
*
|
||||
* Class sessionFile
|
||||
* @package app\service\driver
|
||||
*/
|
||||
class SessionFile extends File
|
||||
{
|
||||
|
||||
public function __construct(App $app, array $config = [])
|
||||
{
|
||||
parent::__construct($app, $config);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* bug v20220302 error: SplFileInfo::getMTime(): stat failed for filePath(xxx)
|
||||
* 修复此函数
|
||||
*
|
||||
* Session 垃圾回收
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function gc(): void
|
||||
{
|
||||
$lifetime = $this->config['expire'];
|
||||
$now = time();
|
||||
|
||||
$files = $this->findFiles($this->config['path'], function (\SplFileInfo $item) use ($lifetime, $now) {
|
||||
// 添加文件是否存在判断
|
||||
if (!$item->isFile()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $now - $lifetime > $item->getMTime();
|
||||
});
|
||||
|
||||
foreach ($files as $file) {
|
||||
$this->unlink($file->getPathname());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 重构unlink方法
|
||||
*
|
||||
* 判断文件是否存在后,删除
|
||||
*
|
||||
* @access private
|
||||
* @param string $file
|
||||
* @return bool
|
||||
*/
|
||||
protected function unlink(string $file): bool
|
||||
{
|
||||
return is_file($file) && unlink($file);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
<?php
|
||||
namespace app\validate;
|
||||
|
||||
use think\Validate;
|
||||
|
||||
class Article extends Validate
|
||||
{
|
||||
protected $rule = [
|
||||
'category_id|栏目' => 'require|>:0',
|
||||
'title|标题' => 'require|max:255',
|
||||
'summary|摘要' => 'max:255',
|
||||
'route|路由' => "routeValidate"
|
||||
];
|
||||
|
||||
protected $message = [
|
||||
'model_id' => '所属模型必需选择',
|
||||
'route.routeValidate' => '路由不符合指定规范',
|
||||
'route.unique' => '路由已存在',
|
||||
];
|
||||
|
||||
protected function routeValidate($value)
|
||||
{
|
||||
$chars =preg_replace('/\s+/','',
|
||||
"/^(
|
||||
|
||||
[\/]{1}
|
||||
|
||||
(
|
||||
|
||||
|
||||
(
|
||||
|
||||
([A-Za-z0-9_-]*[A-Za-z_-]+)
|
||||
|
|
||||
([A-Za-z_-]+[A-Za-z0-9_-]*)
|
||||
)
|
||||
|
||||
|
|
||||
|
||||
(
|
||||
([A-Za-z0-9_-]+[A-Za-z_-]+[A-Za-z0-9_-]+)
|
||||
|
|
||||
([A-Za-z_-]+[A-Za-z0-9_-]+[A-Za-z_-]+)
|
||||
)
|
||||
|
||||
)
|
||||
|
||||
|
||||
)+
|
||||
|
||||
$/");
|
||||
|
||||
if ( preg_match($chars, $value)){
|
||||
return true;
|
||||
|
||||
}else{
|
||||
|
||||
return "路由不符合指定规范";
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// edit 验证场景定义
|
||||
public function sceneEdit()
|
||||
{
|
||||
$id = input('id/d', 0);
|
||||
return $this->append('route', 'unique:article,route,' .$id . '|unique:category,route' . '|unique:special_route,route' );
|
||||
}
|
||||
public function sceneAdd()
|
||||
{
|
||||
return $this->append('route', 'unique:category,route|unique:article,route|unique:special_route,route');
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
namespace app\validate;
|
||||
|
||||
use think\Validate;
|
||||
|
||||
class AuthGroup extends Validate
|
||||
{
|
||||
protected $rule = [
|
||||
'title' => 'require',
|
||||
'status' => 'require|number',
|
||||
];
|
||||
protected $message = [
|
||||
'title.require' => '角色名称不能为空',
|
||||
'status.require' => '角色状态必须设置',
|
||||
'status.number' => '角色状态参数值只能为数字类型',
|
||||
];
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
<?php
|
||||
namespace app\validate;
|
||||
|
||||
use think\Validate;
|
||||
|
||||
class AuthRule extends Validate
|
||||
{
|
||||
protected $rule = [
|
||||
'title' => 'require',
|
||||
'name' => 'require',
|
||||
'status' =>'require|number',
|
||||
];
|
||||
protected $message = [
|
||||
'title.require' => '名称必须',
|
||||
'name.require'=> '标识必须',
|
||||
'status.require'=> '显示状态必须传值',
|
||||
'status.number'=> '显示状态传值只能为数字表示',
|
||||
];
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
<?php
|
||||
namespace app\validate;
|
||||
|
||||
use think\Validate;
|
||||
|
||||
class Block extends Validate
|
||||
{
|
||||
protected $rule = [
|
||||
'title' => 'require',
|
||||
'keyword' => 'require',
|
||||
];
|
||||
protected $message = [
|
||||
'title.require' => '名称必须',
|
||||
'keyword.require' => '键值必须'
|
||||
];
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
<?php
|
||||
|
||||
namespace app\validate;
|
||||
|
||||
use think\Validate;
|
||||
|
||||
class Category extends Validate
|
||||
{
|
||||
protected $rule = [
|
||||
'parent_id|父级分类' => 'require|number',
|
||||
'model_id|所属模型' => 'require|number|gt:0',
|
||||
'title|标题' => 'require|max:100',
|
||||
'description|描述' => 'max:255',
|
||||
'route|路由' =>"routeValidate",
|
||||
'category_key|标识' =>"alphaDash",
|
||||
];
|
||||
|
||||
protected $message = [
|
||||
'model_id' => '所属模型必需选择',
|
||||
'route.routeValidate' => '路由不符合指定规范',
|
||||
'route.unique' => '路由已存在',
|
||||
];
|
||||
|
||||
protected function routeValidate($value)
|
||||
{
|
||||
$chars =preg_replace('/\s+/','',
|
||||
"/^(
|
||||
|
||||
[\/]{1}
|
||||
|
||||
(
|
||||
|
||||
|
||||
(
|
||||
|
||||
([A-Za-z0-9_-]*[A-Za-z_-]+)
|
||||
|
|
||||
([A-Za-z_-]+[A-Za-z0-9_-]*)
|
||||
)
|
||||
|
||||
|
|
||||
|
||||
(
|
||||
([A-Za-z0-9_-]+[A-Za-z_-]+[A-Za-z0-9_-]+)
|
||||
|
|
||||
([A-Za-z_-]+[A-Za-z0-9_-]+[A-Za-z_-]+)
|
||||
)
|
||||
|
||||
)
|
||||
|
||||
|
||||
)+
|
||||
|
||||
$/");
|
||||
|
||||
if ( preg_match($chars, $value)){
|
||||
return true;
|
||||
|
||||
}else{
|
||||
|
||||
return "路由不符合指定规范";
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// edit 验证场景定义
|
||||
public function sceneEdit()
|
||||
{
|
||||
$id = input('id/d', 0);
|
||||
return $this->append('route', 'unique:category,route,' .$id . '|unique:article,route' )
|
||||
->append("category_key",'unique:category,category_key,' .$id );
|
||||
}
|
||||
public function sceneAdd()
|
||||
{
|
||||
return $this->append('route', 'unique:category,route|unique:article,route|unique:special_route,route')
|
||||
->append("category_key",'unique:category,category_key' );
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
<?php
|
||||
namespace app\validate;
|
||||
|
||||
use think\Validate;
|
||||
|
||||
class DownloadValidate extends Validate
|
||||
{
|
||||
protected $rule = [
|
||||
'title' => 'require|length:1,60',
|
||||
'file' => 'require',
|
||||
'visible' => 'require|in:0,1',
|
||||
];
|
||||
protected $message = [
|
||||
'title.require' => '标题不能为空',
|
||||
'file.require' => '文件必传',
|
||||
'visible.require' => '状态必须设置',
|
||||
'visible.in' => '状态参数错误',
|
||||
];
|
||||
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
namespace app\validate;
|
||||
|
||||
use think\Validate;
|
||||
|
||||
class History extends Validate
|
||||
{
|
||||
protected $rule = [
|
||||
'title' => 'require|length:1,60',
|
||||
'visible' => 'require|in:0,1',
|
||||
'event' => 'require',
|
||||
];
|
||||
protected $message = [
|
||||
'title.require' => '标题不能为空',
|
||||
'name.length' => '标题长度限制为60个字符以内',
|
||||
'event.require' => '事件不能为空',
|
||||
'visible.require' => '历程状态必须设置',
|
||||
'visible.in' => '状态参数错误',
|
||||
];
|
||||
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
<?php
|
||||
namespace app\validate;
|
||||
|
||||
use think\Validate;
|
||||
|
||||
class HistoryInfo extends Validate
|
||||
{
|
||||
protected $rule = [
|
||||
'title' => 'require|length:1,2000',
|
||||
'visible' => 'require|in:0,1',
|
||||
];
|
||||
protected $message = [
|
||||
'title.require' => '事例概述内容不能为空',
|
||||
'name.length' => '事例概述内容长度限制为2000个字符以内',
|
||||
'visible.require' => '历程事例状态必须设置',
|
||||
'visible.in' => '状态参数错误',
|
||||
];
|
||||
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
<?php
|
||||
namespace app\validate;
|
||||
|
||||
use think\Validate;
|
||||
|
||||
class HonourValidate extends Validate
|
||||
{
|
||||
protected $rule = [
|
||||
'title' => 'require|length:1,60',
|
||||
'visible' => 'require|in:0,1',
|
||||
'image' => 'require',
|
||||
];
|
||||
protected $message = [
|
||||
'title.require' => '标题不能为空',
|
||||
'image.require' => '图片不能为空',
|
||||
'visible.require' => '状态必须设置',
|
||||
'visible.in' => '状态参数错误',
|
||||
];
|
||||
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
<?php
|
||||
namespace app\validate;
|
||||
|
||||
use think\Validate;
|
||||
|
||||
class Link extends Validate
|
||||
{
|
||||
protected $rule = [
|
||||
'title' => 'require',
|
||||
'url' => 'url',
|
||||
];
|
||||
protected $message = [
|
||||
'title.require' => '名称必须',
|
||||
'url.url' => '请填写有效的网址,以http://或https://开头'
|
||||
];
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
namespace app\validate;
|
||||
|
||||
use think\Validate;
|
||||
|
||||
class LinkProduct extends Validate
|
||||
{
|
||||
protected $rule = [
|
||||
'title' => 'require',
|
||||
'url' => 'url',
|
||||
];
|
||||
protected $message = [
|
||||
'title.require' => '名称必须',
|
||||
'url.require' => '链接网址不能为空,以http://或https://开头',
|
||||
'url.url' => '请填写有效的网址,以http://或https://开头'
|
||||
];
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue