首次上传
|
@ -0,0 +1,19 @@
|
||||||
|
APP_DEBUG = true
|
||||||
|
APP_TRACE = true
|
||||||
|
|
||||||
|
[APP]
|
||||||
|
DEFAULT_TIMEZONE = Asia/Shanghai
|
||||||
|
|
||||||
|
[DATABASE]
|
||||||
|
TYPE = mysql
|
||||||
|
HOSTNAME = 211.149.245.223
|
||||||
|
DATABASE = dev_bee_cms
|
||||||
|
USERNAME = dev_bee_cms
|
||||||
|
PASSWORD = dT7yH5fmd28JG6ER
|
||||||
|
HOSTPORT = 3306
|
||||||
|
CHARSET = utf8mb4
|
||||||
|
DEBUG = true
|
||||||
|
PREFIX = bee_
|
||||||
|
|
||||||
|
[LANG]
|
||||||
|
default_lang = zh-cn
|
|
@ -0,0 +1,13 @@
|
||||||
|
.env
|
||||||
|
/.idea
|
||||||
|
/.vscode
|
||||||
|
backup/data/*
|
||||||
|
/config
|
||||||
|
*.log
|
||||||
|
runtime/*
|
||||||
|
storage/*
|
||||||
|
public/storage/*
|
||||||
|
.DS_Store
|
||||||
|
Test.php
|
||||||
|
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 @@
|
||||||
|
deny from all
|
|
@ -0,0 +1,367 @@
|
||||||
|
<?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;
|
||||||
|
|
||||||
|
// 应用公共文件
|
||||||
|
|
||||||
|
if (!function_exists('widget')) {
|
||||||
|
/**
|
||||||
|
* 渲染输出Widget
|
||||||
|
* @param string $name Widget名称
|
||||||
|
* @param array $data 传入的参数
|
||||||
|
* @return mixed
|
||||||
|
* milo 2019-05-08 从TP5.1代码中拿来修改的
|
||||||
|
*/
|
||||||
|
function widget($name, $data = [])
|
||||||
|
{
|
||||||
|
return action($name, $data, 'widget');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!function_exists('action')) {
|
||||||
|
/**
|
||||||
|
* 调用模块的操作方法 参数格式 [模块/控制器/]操作
|
||||||
|
* @param string $url 调用地址
|
||||||
|
* @param string|array $vars 调用参数 支持字符串和数组
|
||||||
|
* @param string $layer 要调用的控制层名称
|
||||||
|
* @param bool $appendSuffix 是否添加类名后缀
|
||||||
|
* @return mixed
|
||||||
|
* milo 2019-05-08 从TP5.1代码中拿来修改的
|
||||||
|
*/
|
||||||
|
function action($url, $vars = [], $layer = 'controller', $appendSuffix = false)
|
||||||
|
{
|
||||||
|
$info = pathinfo($url);
|
||||||
|
$action = $info['basename'];
|
||||||
|
$module = '.' != $info['dirname'] ? $info['dirname'] : request()->controller();
|
||||||
|
$class = controller($module, $layer);
|
||||||
|
if (is_scalar($vars)) {
|
||||||
|
if (strpos($vars, '=')) {
|
||||||
|
parse_str($vars, $vars);
|
||||||
|
} else {
|
||||||
|
$vars = [$vars];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return app()->invokeMethod([$class, $action . config('route.action_suffix')], $vars);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!function_exists('controller')) {
|
||||||
|
/**
|
||||||
|
* 实例化(分层)控制器 格式:[模块名/]控制器名
|
||||||
|
* @access public
|
||||||
|
* @param string $name 资源地址
|
||||||
|
* @param string $layer 控制层名称
|
||||||
|
* @param bool $appendSuffix 是否添加类名后缀
|
||||||
|
* @param string $empty 空控制器名称
|
||||||
|
* @return object
|
||||||
|
* @throws ClassNotFoundException
|
||||||
|
*
|
||||||
|
* milo 2019-05-08 从TP5.1代码中拿来修改的
|
||||||
|
*/
|
||||||
|
function controller($name, $layer = 'controller', $empty = '')
|
||||||
|
{
|
||||||
|
$class = parseClass($name, $layer);
|
||||||
|
if (class_exists($class)) {
|
||||||
|
return app()->make($class);
|
||||||
|
} elseif ($empty && class_exists($emptyClass = app()->parseClass($layer, $empty))) {
|
||||||
|
return app()->make($emptyClass);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new ClassNotFoundException('class not exists:' . $class, $class);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!function_exists('parseClass')) {
|
||||||
|
/**
|
||||||
|
* 解析模块和类名
|
||||||
|
* @access protected
|
||||||
|
* @param string $name 资源地址
|
||||||
|
* @param string $layer 验证层名称
|
||||||
|
* @param bool $appendSuffix 是否添加类名后缀
|
||||||
|
* @return array
|
||||||
|
*
|
||||||
|
* milo 2019-05-08 从TP5.1代码中拿来修改的
|
||||||
|
*/
|
||||||
|
function parseClass($name, $layer)
|
||||||
|
{
|
||||||
|
if (false !== strpos($name, '\\')) {
|
||||||
|
$class = $name;
|
||||||
|
} else {
|
||||||
|
if (strpos($name, '/')) {
|
||||||
|
$names = explode('/', $name, 2);
|
||||||
|
$name = $names[1];
|
||||||
|
}
|
||||||
|
$class = app()->parseClass($layer,$name);
|
||||||
|
}
|
||||||
|
return $class;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (!function_exists('randomStr')) {
|
||||||
|
/**
|
||||||
|
* 获取随机字符串
|
||||||
|
* @param int $type 0:数字(默认);1:全部;2:小写字母;3:大写字母;4:字母;
|
||||||
|
* @param int $len 字符串长度
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
function randomStr($type = 0,$len = 5)
|
||||||
|
{
|
||||||
|
$strPol = "0123456789";
|
||||||
|
if($type == 1) {
|
||||||
|
$strPol = "ABCDEFGHIJKLMOPQRSTUVWYZ0123456789abcdefghijklmopqrstuvwyz";
|
||||||
|
} elseif ($type == 2) {
|
||||||
|
$strPol = "abcdefghijklmopqrstuvwyz";
|
||||||
|
} elseif ($type == 3) {
|
||||||
|
$strPol = "ABCDEFGHIJKLMOPQRSTUVWYZ";
|
||||||
|
} elseif ($type == 4) {
|
||||||
|
$strPol = "ABCDEFGHIJKLMOPQRSTUVWYZabcdefghijklmopqrstuvwyz";
|
||||||
|
}
|
||||||
|
$max = strlen($strPol) - 1;
|
||||||
|
$str = '';
|
||||||
|
for ($i=0;$i<$len;$i++) {
|
||||||
|
$str .= $strPol[rand(0,$max)];
|
||||||
|
}
|
||||||
|
return $str;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!function_exists('isMobile')){
|
||||||
|
//判断访问终端是否为移动端
|
||||||
|
function isMobile()
|
||||||
|
{
|
||||||
|
// 如果有HTTP_X_WAP_PROFILE则一定是移动设备
|
||||||
|
if (isset($_SERVER['HTTP_X_WAP_PROFILE'])) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// 如果via信息含有wap则一定是移动设备,部分服务商会屏蔽该信息
|
||||||
|
if (isset($_SERVER['HTTP_VIA'])) {
|
||||||
|
// 找不到为flase,否则为true
|
||||||
|
return stristr($_SERVER['HTTP_VIA'], "wap") ? true : false;
|
||||||
|
}
|
||||||
|
// 脑残法,判断手机发送的客户端标志,兼容性有待提高。其中'MicroMessenger'是电脑微信
|
||||||
|
if (isset($_SERVER['HTTP_USER_AGENT'])) {
|
||||||
|
$clientkeywords = ['nokia','sony','ericsson','mot','samsung','htc','sgh','lg','sharp','sie-','philips','panasonic','alcatel','lenovo','iphone','ipod','blackberry','meizu','android','netfront','symbian','ucweb','windowsce','palm','operamini','operamobi','openwave','nexusone','cldc','midp','wap','mobile','MicroMessenger'];
|
||||||
|
// 从HTTP_USER_AGENT中查找手机浏览器的关键字
|
||||||
|
if (preg_match("/(" . implode('|', $clientkeywords) . ")/i", strtolower($_SERVER['HTTP_USER_AGENT']))) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 协议法,因为有可能不准确,放到最后判断
|
||||||
|
if (isset ($_SERVER['HTTP_ACCEPT'])) {
|
||||||
|
// 如果只支持wml并且不支持html那一定是移动设备
|
||||||
|
// 如果支持wml和html但是wml在html之前则是移动设备
|
||||||
|
if ((strpos($_SERVER['HTTP_ACCEPT'], 'vnd.wap.wml') !== false) && (strpos($_SERVER['HTTP_ACCEPT'], 'text/html') === false || (strpos($_SERVER['HTTP_ACCEPT'], 'vnd.wap.wml') < strpos($_SERVER['HTTP_ACCEPT'], 'text/html')))) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//根据栏目获取路径
|
||||||
|
if(!function_exists('getUri')){
|
||||||
|
function getUri($cate)
|
||||||
|
{
|
||||||
|
$url = '';
|
||||||
|
if(!empty($cate)){
|
||||||
|
if($cate['is_index']){
|
||||||
|
$url = '/';
|
||||||
|
}elseif(!empty($cate['url'])){
|
||||||
|
$url = $cate['url'];
|
||||||
|
}else{
|
||||||
|
$url = url($cate['template'].'/index', ['category_id' => $cate['id']]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $url;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//根据文件大小转换为文字
|
||||||
|
if(!function_exists('sizeToStr')){
|
||||||
|
function sizeToStr($size)
|
||||||
|
{
|
||||||
|
if(!is_numeric($size) || $size <= 0){
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
$size = $size / 1024;
|
||||||
|
if($size < 1024){
|
||||||
|
return sprintf("%.2fK", $size);
|
||||||
|
}
|
||||||
|
$size = $size / 1024;
|
||||||
|
if($size < 1024){
|
||||||
|
return sprintf("%.2fM", $size);
|
||||||
|
}
|
||||||
|
$size = $size / 1024;
|
||||||
|
return sprintf("%.2fG", $size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//根据路径获取文件名
|
||||||
|
if(!function_exists('getKeyByPath')){
|
||||||
|
function getKeyByPath($path)
|
||||||
|
{
|
||||||
|
return substr($path, strrpos($path, '/')+1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//富文本中提取图片路径
|
||||||
|
if(!function_exists('getImageUrlFromText')){
|
||||||
|
function getImageUrlFromText($content)
|
||||||
|
{
|
||||||
|
preg_match_all('/<img.*?src="(.*?)".*?>/is', $content, $imgs);
|
||||||
|
$data = [];
|
||||||
|
if(!empty($imgs) && !empty($imgs[1])){
|
||||||
|
foreach($imgs[1] as $img){
|
||||||
|
if(substr($img, 0, 4) != 'http'){
|
||||||
|
$key = getKeyByPath($img);
|
||||||
|
$data[$key] = $img;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//富文本中提取视频路径
|
||||||
|
if(!function_exists('getVideoUrlFromText')){
|
||||||
|
function getVideoUrlFromText($content)
|
||||||
|
{
|
||||||
|
preg_match_all('/<video.*?src="(.*?)".*?>/is', $content, $videos);
|
||||||
|
$data = [];
|
||||||
|
if(!empty($videos) && !empty($videos[1])){
|
||||||
|
foreach($videos[1] as $video){
|
||||||
|
if(substr($video, 0, 4) != 'http'){
|
||||||
|
$key = getKeyByPath($video);
|
||||||
|
$data[$key] = $video;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//获取目录下的所有文件
|
||||||
|
if(!function_exists('getAllFilesByPath')){
|
||||||
|
function getAllFilesByPath($path, $rootPath)
|
||||||
|
{
|
||||||
|
if(is_dir($path) && file_exists($path)){
|
||||||
|
$items = scandir($path);
|
||||||
|
$files = [];
|
||||||
|
foreach($items as $item){
|
||||||
|
if(substr($item, 0, 1) != '.' && strpos($item, '_') == false){
|
||||||
|
$itemPath = $path . '/' . $item;
|
||||||
|
if(is_file($itemPath)){
|
||||||
|
$size = filesize($itemPath);
|
||||||
|
$files[$item] = [
|
||||||
|
'path' => str_replace($rootPath, '/', $itemPath),
|
||||||
|
'realPath' => $itemPath,
|
||||||
|
'size' => $size,
|
||||||
|
'sizeStr' => sizeToStr($size),
|
||||||
|
'suffix' => strtolower(substr($item, strrpos($item, '.')+1)) //后缀
|
||||||
|
];
|
||||||
|
}elseif(is_dir($itemPath)){
|
||||||
|
$childFiles = getAllFilesByPath($itemPath, $rootPath);
|
||||||
|
if(!empty($childFiles)){
|
||||||
|
$files = array_merge($files, $childFiles);
|
||||||
|
}else{
|
||||||
|
rmdir($itemPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $files;
|
||||||
|
}
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//过滤get输入
|
||||||
|
if(!function_exists('getFilter')){
|
||||||
|
function getFilter($value){
|
||||||
|
$getFilter = "'|(and|or)\b.+?(>|<|=|in|like)|\/\*.+?\*\/|<\s*script\b|\bEXEC\b|UNION.+?SELECT|UPDATE.+?SET|INSERT\s+INTO.+?VALUES|(SELECT|DELETE).+?FROM|(CREATE|ALTER|DROP|TRUNCATE)\s+(TABLE|DATABASE)";
|
||||||
|
$forArray = false;
|
||||||
|
if(is_array($value)){
|
||||||
|
$forFilter = implode($value);
|
||||||
|
$forArray = true;
|
||||||
|
}else{
|
||||||
|
$forFilter = $value;
|
||||||
|
}
|
||||||
|
if (preg_match("/".$getFilter."/is", $forFilter) == 1){
|
||||||
|
$value = $forArray ? [] : '';
|
||||||
|
}
|
||||||
|
return filterExp($value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//过滤post录入
|
||||||
|
if(!function_exists($postFilter)){
|
||||||
|
function postFilter($value){
|
||||||
|
$postFilter = "\b(and|or)\b.{1,6}?(=|>|<|\bin\b|\blike\b)|\/\*.+?\*\/|<\s*script\b|\bEXEC\b|UNION.+?SELECT|UPDATE.+?SET|INSERT\s+INTO.+?VALUES|(SELECT|DELETE).+?FROM|(CREATE|ALTER|DROP|TRUNCATE)\s+(TABLE|DATABASE)";
|
||||||
|
$forArray = false;
|
||||||
|
if(is_array($value)){
|
||||||
|
$forFilter = implode($value);
|
||||||
|
$forArray = true;
|
||||||
|
}else{
|
||||||
|
$forFilter = $value;
|
||||||
|
}
|
||||||
|
if (preg_match("/".$postFilter."/is", $forFilter) == 1){
|
||||||
|
$value = $forArray ? [] : '';
|
||||||
|
}
|
||||||
|
return filterExp($value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//过滤cookie数据
|
||||||
|
if(!function_exists('cookieFilter')){
|
||||||
|
function cookieFilter($value){
|
||||||
|
$cookieFilter = "\b(and|or)\b.{1,6}?(=|>|<|\bin\b|\blike\b)|\/\*.+?\*\/|<\s*script\b|\bEXEC\b|UNION.+?SELECT|UPDATE.+?SET|INSERT\s+INTO.+?VALUES|(SELECT|DELETE).+?FROM|(CREATE|ALTER|DROP|TRUNCATE)\s+(TABLE|DATABASE)";
|
||||||
|
$forArray = false;
|
||||||
|
if(is_array($value)){
|
||||||
|
$forFilter = implode($value);
|
||||||
|
$forArray = true;
|
||||||
|
}else{
|
||||||
|
$forFilter = $value;
|
||||||
|
}
|
||||||
|
if (preg_match("/".$cookieFilter."/is", $forFilter) == 1){
|
||||||
|
$value = $forArray ? [] : '';
|
||||||
|
}
|
||||||
|
return filterExp($value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!function_exists('filterExp')){
|
||||||
|
function filterExp($value){
|
||||||
|
$filter = '/^EXP|NEQ|GT|EGT|LT|ELT|OR|XOR|LIKE|NOTLIKE|NOT LIKE|NOT BETWEEN|NOTBETWEEN|BETWEEN|NOTIN|NOT IN|IN$/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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,100 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace app\controller;
|
||||||
|
|
||||||
|
use app\model\{Article as MArticle, Category};
|
||||||
|
use think\facade\View;
|
||||||
|
|
||||||
|
class Article extends Base
|
||||||
|
{
|
||||||
|
//详情
|
||||||
|
public function detail($id = 0)
|
||||||
|
{
|
||||||
|
|
||||||
|
if ($id <= 0) {
|
||||||
|
return $this->error('错误页面');
|
||||||
|
}
|
||||||
|
$article = MArticle::getById($id);
|
||||||
|
if (empty($article)) {
|
||||||
|
return $this->error('无此文章');
|
||||||
|
}
|
||||||
|
MArticle::updateById($id, ['views' => $article['views'] + 1]);
|
||||||
|
$category = Category::getById($article['category_id']);
|
||||||
|
$prev = MArticle::getPrevArticleByIdAndCategoryId($id, $article['category_id']);
|
||||||
|
$next = MArticle::getNextArticleByIdAndCategoryId($id, $article['category_id']);
|
||||||
|
|
||||||
|
$keywords = $article['seo_keywords'] ? $article['seo_keywords'] : $this->system['seo_keywords'];
|
||||||
|
$description = $article['seo_description'] ? $article['seo_description'] : $this->system['seo_description'];
|
||||||
|
$this->setSeo($article['title'], $keywords, $description);
|
||||||
|
$this->data['article'] = $article;
|
||||||
|
$this->data['category'] = $category;
|
||||||
|
$this->data['categoryId'] = $category['id'];
|
||||||
|
$this->data['prev'] = $prev;
|
||||||
|
$this->data['next'] = $next;
|
||||||
|
return $this->view($category['template_detail'] ?? '');
|
||||||
|
}
|
||||||
|
|
||||||
|
//列表页
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
$categoryId = input('category_id/d', 0);
|
||||||
|
if ($categoryId <= 0) {
|
||||||
|
return $this->error('错误页面');
|
||||||
|
}
|
||||||
|
$category = Category::getById($categoryId);
|
||||||
|
$page_size = 20;
|
||||||
|
if( $category['number'])$page_size= $category['number'];
|
||||||
|
|
||||||
|
if( $this->request->param("page_size/d")){
|
||||||
|
$page_size= $this->request->param("page_size/d");
|
||||||
|
cookie("article_page_size",$this->request->param("page_size/d"));
|
||||||
|
}else{
|
||||||
|
if( cookie("?article_page_size"))$page_size= cookie("article_page_size");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($category)) {
|
||||||
|
return $this->error('错误页面');
|
||||||
|
}
|
||||||
|
$childCategory = Category::getChildrenByParentId($categoryId);
|
||||||
|
$description = $category['description'] ? $category['description'] : $this->system['seo_description'];
|
||||||
|
$this->setSeo($category['title'], $this->system['seo_keywords'], $description);
|
||||||
|
$this->data['items'] = MArticle::getListPageByCategory($categoryId, $page_size);
|
||||||
|
$this->data['category'] = $category;
|
||||||
|
$this->data['categoryId'] = $categoryId;
|
||||||
|
$this->data['page_size'] = $page_size;
|
||||||
|
$this->data['article_count'] = MArticle::getListCount($categoryId);
|
||||||
|
|
||||||
|
return $this->view($category['template_list'] ?? '');
|
||||||
|
}
|
||||||
|
|
||||||
|
//查询
|
||||||
|
public function query()
|
||||||
|
{
|
||||||
|
$keyword = $this->request->param("keyword/s");
|
||||||
|
//无key值跳转到产品
|
||||||
|
if (!$keyword) $this->redirect((string)url('/articles/12.html'));
|
||||||
|
|
||||||
|
$where = [
|
||||||
|
['category_id', 'in', [5, 12, 13, 14, 15]],
|
||||||
|
['status', '=', 1],
|
||||||
|
];
|
||||||
|
|
||||||
|
$where[] = ['title', 'like', '%' . $keyword . '%'];
|
||||||
|
$param['keyword'] = $keyword;
|
||||||
|
|
||||||
|
$paginate = [
|
||||||
|
'list_rows' => 20,
|
||||||
|
'query' => $param
|
||||||
|
];
|
||||||
|
$data = MArticle::where($where)
|
||||||
|
->order("sort desc")
|
||||||
|
->paginate($paginate, false);
|
||||||
|
|
||||||
|
View::assign("items", $data);
|
||||||
|
View::assign("keyword", $keyword);
|
||||||
|
$this->data['category'] = Category::getById(5);
|
||||||
|
$this->data['categoryId'] = 5;
|
||||||
|
return $this->view("/article/product _query");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
<?php
|
||||||
|
namespace app\controller;
|
||||||
|
|
||||||
|
use app\controller\BaseController;
|
||||||
|
use app\model\System;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 控制器基础类
|
||||||
|
*/
|
||||||
|
class Base extends BaseController
|
||||||
|
{
|
||||||
|
//需要向模板传递的值
|
||||||
|
protected $data = [];
|
||||||
|
//系统配置信息
|
||||||
|
protected $system = [];
|
||||||
|
|
||||||
|
// 初始化
|
||||||
|
protected function initialize()
|
||||||
|
{
|
||||||
|
$this->system = System::getSystem();
|
||||||
|
$this->data['system'] = $this->system;
|
||||||
|
}
|
||||||
|
|
||||||
|
//设置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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,193 @@
|
||||||
|
<?php
|
||||||
|
declare (strict_types = 1);
|
||||||
|
|
||||||
|
namespace app\controller;
|
||||||
|
|
||||||
|
use think\{App, Validate};
|
||||||
|
use think\exception\ValidateException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 控制器基础类
|
||||||
|
*/
|
||||||
|
abstract class BaseController
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Request实例
|
||||||
|
* @var \think\Request
|
||||||
|
*/
|
||||||
|
protected $request;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 应用实例
|
||||||
|
* @var \think\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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 操作成功跳转的快捷方法
|
||||||
|
* @access protected
|
||||||
|
* @param mixed $msg 提示信息
|
||||||
|
* @param string $url 跳转的URL地址
|
||||||
|
* @param mixed $data 返回的数据
|
||||||
|
* @param integer $wait 跳转等待时间
|
||||||
|
* @param array $header 发送的Header信息
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
protected function success($msg = '', string $url = null, $data = '', int $wait = 3, array $header = [])
|
||||||
|
{
|
||||||
|
if (is_null($url) && isset($_SERVER["HTTP_REFERER"])) {
|
||||||
|
$url = $_SERVER["HTTP_REFERER"];
|
||||||
|
} elseif ($url) {
|
||||||
|
$url = (strpos($url, '://') || 0 === strpos($url, '/')) ? $url : $this->app->route->buildUrl($url);
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = [
|
||||||
|
'code' => 1,
|
||||||
|
'msg' => $msg,
|
||||||
|
'data' => $data,
|
||||||
|
'url' => $url,
|
||||||
|
'wait' => $wait,
|
||||||
|
];
|
||||||
|
return $this->redirect(url('error/jump',$result));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 操作错误跳转的快捷方法
|
||||||
|
* @access protected
|
||||||
|
* @param mixed $msg 提示信息
|
||||||
|
* @param string $url 跳转的URL地址
|
||||||
|
* @param mixed $data 返回的数据
|
||||||
|
* @param integer $wait 跳转等待时间
|
||||||
|
* @param array $header 发送的Header信息
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
protected function error($msg = '', string $url = null, $data = '', int $wait = 3)
|
||||||
|
{
|
||||||
|
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 $data 要返回的数据
|
||||||
|
* @param integer $code 返回的code
|
||||||
|
* @param mixed $msg 提示信息
|
||||||
|
* @param string $type 返回数据格式
|
||||||
|
* @param array $header 发送的Header信息
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
protected function json($code = 0, $msg = 'ok', $data= [])
|
||||||
|
{
|
||||||
|
$result = [
|
||||||
|
'code' => $code,
|
||||||
|
'msg' => $msg,
|
||||||
|
'time' => time(),
|
||||||
|
'data' => $data
|
||||||
|
];
|
||||||
|
return json($result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* URL重定向
|
||||||
|
* @access protected
|
||||||
|
* @param string $url 跳转的URL表达式
|
||||||
|
* @param array|integer $params 其它URL参数
|
||||||
|
* @param integer $code http code
|
||||||
|
* @param array $with 隐式传参
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
protected function redirect($url)
|
||||||
|
{
|
||||||
|
if(!is_string($url)){
|
||||||
|
$url = $url->__toString();
|
||||||
|
}
|
||||||
|
return redirect($url);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,49 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
|
||||||
|
namespace app\controller;
|
||||||
|
|
||||||
|
|
||||||
|
class Error extends BaseController
|
||||||
|
{
|
||||||
|
public function __call($method, $args)
|
||||||
|
{
|
||||||
|
|
||||||
|
if(request()->isAjax()) {
|
||||||
|
return $this->json(404, 'error request!');
|
||||||
|
} else {
|
||||||
|
$referer = $_SERVER['HTTP_REFERER'] ?? null;
|
||||||
|
if (empty($referer)) {
|
||||||
|
$url = '/';
|
||||||
|
} else {
|
||||||
|
$domain = $this->request->domain();
|
||||||
|
$urlInfo = parse_url($referer);
|
||||||
|
$scheme = $urlInfo['scheme'] ?? '';
|
||||||
|
$requestSrc = '';
|
||||||
|
if (!empty($scheme)) {
|
||||||
|
$requestSrc = $scheme.'://'.($urlInfo['host'] ?? '');
|
||||||
|
}
|
||||||
|
if($domain != $requestSrc) {
|
||||||
|
$url = '/';
|
||||||
|
} else {
|
||||||
|
$url = 'javascript:history.back(-1);';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$result = [
|
||||||
|
'code' => 404,
|
||||||
|
'msg' => '无效请求! 没有找到相关资源',
|
||||||
|
'data' => [],
|
||||||
|
'url' => $url,
|
||||||
|
'wait' => 5,
|
||||||
|
];
|
||||||
|
return view('error/400')->assign($result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function jump()
|
||||||
|
{
|
||||||
|
$param = request()->param();
|
||||||
|
return view()->assign($param);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
<?php
|
||||||
|
namespace app\controller;
|
||||||
|
|
||||||
|
use app\model\{Category, Block};
|
||||||
|
use think\facade\View;
|
||||||
|
|
||||||
|
|
||||||
|
class Home extends Base
|
||||||
|
{
|
||||||
|
protected $category_id;
|
||||||
|
protected function initialize()
|
||||||
|
{
|
||||||
|
parent::initialize(); // TODO: Change the autogenerated stub
|
||||||
|
$category = Category::getIndex();
|
||||||
|
$categoryId = $category['id'] ?? 0;
|
||||||
|
$this->data['categoryId'] = $categoryId;
|
||||||
|
$this->setSeo($this->system['seo_title'], $this->system['seo_keywords'], $this->system['seo_description']);
|
||||||
|
$this->data['blocks'] = Block::getByCategoryId($categoryId);
|
||||||
|
$this->category_id=$this->request->param("category_id/d");
|
||||||
|
}
|
||||||
|
//关于我们
|
||||||
|
public function aboutUs(){
|
||||||
|
$Block=["key1"=>"","key2"=>""];
|
||||||
|
$Block["key1"]=Block::getByKeyword(1,$this->category_id);
|
||||||
|
$Block["key2"]=Block::getByKeyword(2,$this->category_id);
|
||||||
|
dump($Block);
|
||||||
|
View::assign($Block);
|
||||||
|
return $this->view();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
<?php
|
||||||
|
namespace app\controller;
|
||||||
|
|
||||||
|
use app\model\{Category, Block};
|
||||||
|
use think\facade\View;
|
||||||
|
|
||||||
|
class Index extends Base
|
||||||
|
{
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
|
||||||
|
$category = Category::getIndex();
|
||||||
|
$categoryId = $category['id'] ?? 0;
|
||||||
|
$this->data['categoryId'] = $categoryId;
|
||||||
|
$this->setSeo($this->system['seo_title'], $this->system['seo_keywords'], $this->system['seo_description']);
|
||||||
|
$this->data['blocks'] = Block::getByCategoryId($categoryId);
|
||||||
|
$category = Category::getById(1);
|
||||||
|
View::assign("category",$category);
|
||||||
|
return $this->view();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?php
|
||||||
|
namespace app\controller;
|
||||||
|
|
||||||
|
use app\model\{Category, Block};
|
||||||
|
|
||||||
|
class Page extends Base
|
||||||
|
{
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
|
||||||
|
$categoryId=$this->request->param("category_id");
|
||||||
|
$category = Category::getById($this->request->param("category_id"));
|
||||||
|
|
||||||
|
if ($category) {
|
||||||
|
$description = $category['description'] ? $category['description'] : $this->system['seo_description'];
|
||||||
|
$this->setSeo($category['title'], $this->system['seo_keywords'], $description);
|
||||||
|
} else {
|
||||||
|
return $this->error('错误页面');
|
||||||
|
}
|
||||||
|
$childCategory = Category::getChildrenByParentId($categoryId);
|
||||||
|
|
||||||
|
$this->data['categoryId'] = $categoryId;
|
||||||
|
$this->data['category'] = $category;
|
||||||
|
$this->data['childCategory'] = $childCategory;
|
||||||
|
$this->data['blocks'] = Block::getByCategoryId($categoryId);
|
||||||
|
return $this->view($category['template_detail']);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,217 @@
|
||||||
|
<?php
|
||||||
|
namespace app\controller\manager;
|
||||||
|
|
||||||
|
use app\model\{Article as MArticle, Category, System, Log};
|
||||||
|
use app\validate\Article as VArticle;
|
||||||
|
use think\exception\ValidateException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 内容管理 - 文章管理
|
||||||
|
*/
|
||||||
|
class Article extends Base
|
||||||
|
{
|
||||||
|
//批量修改属性
|
||||||
|
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)){
|
||||||
|
$delIds = [];
|
||||||
|
foreach($items as $item){
|
||||||
|
$delIds[] = $item['id'];
|
||||||
|
}
|
||||||
|
MArticle::destroy($delIds);
|
||||||
|
Log::write('article', '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 = MArticle::getById($id);
|
||||||
|
if(!empty($item)){
|
||||||
|
MArticle::destroy($id);
|
||||||
|
Log::write('article', '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 = MArticle::getById($id);
|
||||||
|
if(empty($item)){
|
||||||
|
return $this->json(3, '该文章信息不存在');
|
||||||
|
}
|
||||||
|
if($sort == 'up'){
|
||||||
|
$where = "category_id='{$item['category_id']}' and sort > {$item['sort']}";
|
||||||
|
$order = "sort asc";
|
||||||
|
}else{
|
||||||
|
$where = "category_id='{$item['category_id']}' and sort < {$item['sort']}";
|
||||||
|
$order = "sort desc";
|
||||||
|
}
|
||||||
|
$forSortItems = MArticle::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 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');
|
||||||
|
$id = input('post.id/d');
|
||||||
|
$article = MArticle::getById($id);
|
||||||
|
if (empty($article)) {
|
||||||
|
return $this->json(1, '该文章不存在!');
|
||||||
|
}
|
||||||
|
if(!empty($img)){
|
||||||
|
$item['src'] = $img;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
validate(VArticle::class)->check($item);
|
||||||
|
$auth = session('auth');
|
||||||
|
$item['update_time'] = time();
|
||||||
|
$item['updated'] = $auth['userName'];
|
||||||
|
MArticle::updateById($id, $item);
|
||||||
|
Log::write('article', 'edit', "文章编辑,ID:{$id} ,标题:{$item['title']}");
|
||||||
|
return $this->json();
|
||||||
|
} catch (ValidateException $e) {
|
||||||
|
return $this->json(2, $e->getError());
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
$id = input('param.id');
|
||||||
|
$article = MArticle::getById($id);
|
||||||
|
$category = Category::getById($article['category_id']);
|
||||||
|
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;
|
||||||
|
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(VArticle::class)->check($item);
|
||||||
|
$content = $item['content'] ?? '';
|
||||||
|
if(isset($item['content'])){
|
||||||
|
unset($item['content']);
|
||||||
|
}
|
||||||
|
$item['content'] = $content;
|
||||||
|
$article = MArticle::create($item);
|
||||||
|
Log::write('article', 'add', "文章新增,ID:{$article->id} ,标题:{$item['title']}");
|
||||||
|
return $this->json();
|
||||||
|
} catch (ValidateException $e) {
|
||||||
|
return $this->json(2, $e->getError());
|
||||||
|
}
|
||||||
|
}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;
|
||||||
|
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,53 @@
|
||||||
|
<?php
|
||||||
|
namespace app\controller\manager;
|
||||||
|
|
||||||
|
use app\controller\BaseController;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 控制器基础类
|
||||||
|
*/
|
||||||
|
class Base extends BaseController
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function error($msg = '', string $url = null, $data = '', int $wait = 3)
|
||||||
|
{
|
||||||
|
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,235 @@
|
||||||
|
<?php
|
||||||
|
namespace app\controller\manager;
|
||||||
|
|
||||||
|
use app\model\{Category as MCategory, Model as MCModel, Log};
|
||||||
|
use app\validate\Category as VCategory;
|
||||||
|
use think\exception\ValidateException;
|
||||||
|
use think\facade\Cache;
|
||||||
|
|
||||||
|
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);
|
||||||
|
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);
|
||||||
|
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');
|
||||||
|
if (count($item) > 0 && (is_numeric($id) === true && $id > 0)) {
|
||||||
|
try {
|
||||||
|
validate(VCategory::class)->check($item);
|
||||||
|
if(!empty($img)){
|
||||||
|
$item['src'] = $img;
|
||||||
|
}
|
||||||
|
MCategory::updateById($id, $item);
|
||||||
|
Log::write('category', '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');
|
||||||
|
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();
|
||||||
|
return $this->view();
|
||||||
|
}
|
||||||
|
return $this->json(1,'参数错误,请核对之后再操作!');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 栏目添加
|
||||||
|
*/
|
||||||
|
public function add()
|
||||||
|
{
|
||||||
|
if($this->request->isPost()){
|
||||||
|
$item = input('post.item/a');
|
||||||
|
$img = input('post.img');
|
||||||
|
if (is_array($item) === true && count($item) > 0) {
|
||||||
|
if (!empty($img)) {
|
||||||
|
$item['src'] = $img;
|
||||||
|
}
|
||||||
|
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'] . ',';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$category = MCategory::create($item);
|
||||||
|
Log::write('category', 'add', "栏目新增,ID:{$category->id} ,标题:{$item['title']}");
|
||||||
|
return $this->json();
|
||||||
|
} catch (ValidateException $e) {
|
||||||
|
return $this->json(2,$e->getError());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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();
|
||||||
|
return $this->view();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,173 @@
|
||||||
|
<?php
|
||||||
|
namespace app\controller\manager;
|
||||||
|
|
||||||
|
use app\model\{Category, Article, Block, Log, History};
|
||||||
|
|
||||||
|
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('无此栏目');
|
||||||
|
}
|
||||||
|
$list = Article::getList($categoryId, 20, $keyword, $param);
|
||||||
|
$this->data['list'] = $list;
|
||||||
|
$this->data['category'] = $category;
|
||||||
|
$this->data['keyword'] = $keyword;
|
||||||
|
$this->data['param'] = $param;
|
||||||
|
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', []);
|
||||||
|
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] == '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)
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$block = new Block;
|
||||||
|
$block->saveAll($data);
|
||||||
|
Log::write('content', 'page', "单页编辑,栏目ID:{$category['id']} ,标题:{$category['title']}");
|
||||||
|
return $this->json();
|
||||||
|
}else{
|
||||||
|
$categoryId = input('param.category_id');
|
||||||
|
$children = Category::getChildrenByParentId($categoryId);
|
||||||
|
if(empty($children)){
|
||||||
|
$category = Category::getById($categoryId);
|
||||||
|
}else{
|
||||||
|
$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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
<?php
|
||||||
|
namespace app\controller\manager;
|
||||||
|
|
||||||
|
class Error
|
||||||
|
{
|
||||||
|
public function jump()
|
||||||
|
{
|
||||||
|
$param = request()->param();
|
||||||
|
return view()->assign($param);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,142 @@
|
||||||
|
<?php
|
||||||
|
namespace app\controller\manager;
|
||||||
|
|
||||||
|
use app\model\{File as MFile, Article, Block, Category, Link, 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);
|
||||||
|
}
|
||||||
|
$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 ajaxList()
|
||||||
|
{
|
||||||
|
if($this->request->isAjax()){
|
||||||
|
$page = input('param.page/d', 1);
|
||||||
|
$size = input('param.size/d', 20);
|
||||||
|
if(!is_integer($page) || $page < 1){
|
||||||
|
$page = 1;
|
||||||
|
}
|
||||||
|
if (!is_integer($size) || $size < 1) {
|
||||||
|
$size = 20;
|
||||||
|
}
|
||||||
|
$type = input('param.type', '');
|
||||||
|
if(!in_array($type, array_keys(MFile::getTypes()))){
|
||||||
|
$type = '';
|
||||||
|
}
|
||||||
|
$items = MFile::getList($type, $page, $size);
|
||||||
|
return $this->json(0, 'ok', $items);
|
||||||
|
}
|
||||||
|
return $this->json(1, '无此操作');
|
||||||
|
}
|
||||||
|
//列表
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
$items = MFile::getListPage();
|
||||||
|
$this->data['items'] = $items;
|
||||||
|
$this->data['types'] = MFile::getTypes();
|
||||||
|
return $this->view();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,141 @@
|
||||||
|
<?php
|
||||||
|
namespace app\controller\manager;
|
||||||
|
|
||||||
|
use app\model\{AuthGroup, AuthRule, Log};
|
||||||
|
use app\validate\AuthGroup as VAuthGroup;
|
||||||
|
use think\exception\ValidateException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 角色管理控制器
|
||||||
|
*/
|
||||||
|
class Group extends Base
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 角色、分组删除
|
||||||
|
*/
|
||||||
|
public function del()
|
||||||
|
{
|
||||||
|
if ($this->request->isPost()) {
|
||||||
|
$id = input('post.id/d');
|
||||||
|
if (is_numeric($id) === true && $id > 0) {
|
||||||
|
$item = AuthGroup::getById($id);
|
||||||
|
if(!empty($item)){
|
||||||
|
AuthGroup::destroy($id);
|
||||||
|
Log::write('group', 'del', '删除角色,ID:' . $id . ',名称:' . $item['title']);
|
||||||
|
return $this->json();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $this->json(2, '传入参数错误,请核对之后再操作!');
|
||||||
|
}
|
||||||
|
return $this->json(1, '非法请求!');
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 角色、分组权限分配
|
||||||
|
*/
|
||||||
|
public function rule()
|
||||||
|
{
|
||||||
|
if($this->request->isPost()){
|
||||||
|
$rules = input('post.rules/a');
|
||||||
|
$groupId = input('post.group_id/d');
|
||||||
|
if (is_array($rules) && (is_numeric($groupId) === true && $groupId > 0)) {
|
||||||
|
$group = AuthGroup::getById($groupId);
|
||||||
|
if(empty($group)){
|
||||||
|
return $this->json(2, '无此角色信息,请核对之后再操作!');
|
||||||
|
}
|
||||||
|
AuthGroup::updateRules($groupId, $rules);
|
||||||
|
// 重置该角色对应的权限缓存
|
||||||
|
AuthGroup::resetGroupRulesCache($groupId);
|
||||||
|
Log::write('group', 'rule', '角色分配权限,ID:' . $groupId . ',名称:' . $group['title']);
|
||||||
|
return $this->json();
|
||||||
|
}else{
|
||||||
|
return $this->json(3, '传入参数错误,请核对之后再操作!');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$groupId = input('param.group_id/d');
|
||||||
|
$group = AuthGroup::getById($groupId);
|
||||||
|
if(!empty($group)){
|
||||||
|
$rules = AuthRule::getListTree();
|
||||||
|
$this->data['group_id'] = $groupId;
|
||||||
|
$this->data['group'] = $group;
|
||||||
|
$this->data['rules'] = $rules;
|
||||||
|
return $this->view();
|
||||||
|
}else{
|
||||||
|
return $this->json(1, '无此角色信息,请核对之后再操作!');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 角色、分组添加
|
||||||
|
* @param int $status 1:正常;0:禁止
|
||||||
|
*/
|
||||||
|
public function add()
|
||||||
|
{
|
||||||
|
if($this->request->isPost()){
|
||||||
|
$title = trim(input('post.title'));
|
||||||
|
$status = input('post.status/d');
|
||||||
|
if (!empty($title) && (is_numeric($status) === true) && ($status == 1 || $status == 0)) {
|
||||||
|
$item = [
|
||||||
|
'title' => $title,
|
||||||
|
'status' => $status
|
||||||
|
];
|
||||||
|
try {
|
||||||
|
validate(VAuthGroup::class)->check($item);
|
||||||
|
$group = AuthGroup::create($item);
|
||||||
|
Log::write('group', 'add', "角色新增,ID:{$group->id} ,标题:{$group->title}");
|
||||||
|
return $this->json();
|
||||||
|
} catch (ValidateException $e) {
|
||||||
|
return $this->json(2, $e->getError());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $this->json(1, '传入参数错误,请核对之后再操作!');
|
||||||
|
}else{
|
||||||
|
return $this->view();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 角色、分组编辑
|
||||||
|
*/
|
||||||
|
public function edit()
|
||||||
|
{
|
||||||
|
if($this->request->isPost()){
|
||||||
|
$title = trim(input('post.title'));
|
||||||
|
$status = input('post.status/d');
|
||||||
|
$id = input('post.id/d');
|
||||||
|
if (!empty($title) && ($status == 1 || $status == 0) && (is_numeric($id) === true && $id > 0)) {
|
||||||
|
$item = [
|
||||||
|
'title' => $title,
|
||||||
|
'status' => $status
|
||||||
|
];
|
||||||
|
try {
|
||||||
|
validate(VAuthGroup::class)->check($item);
|
||||||
|
AuthGroup::updateById($id, $item);
|
||||||
|
Log::write('group', 'edit', "角色编辑,ID:{$id} ,标题:{$item['title']}");
|
||||||
|
return $this->json();
|
||||||
|
} catch (ValidateException $e) {
|
||||||
|
return $this->json(2, $e->getError());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $this->json(1, '传入参数错误,请核对之后再操作!');
|
||||||
|
}else{
|
||||||
|
$id = input('param.id/d');
|
||||||
|
if (is_numeric($id) === true && $id > 0) {
|
||||||
|
$item = AuthGroup::getById($id);
|
||||||
|
$this->data['item'] = $item;
|
||||||
|
return $this->view();
|
||||||
|
}
|
||||||
|
return $this->json(1, '传入参数错误,请核对之后再操作!');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 所有角色分组信息
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
$list = AuthGroup::select()->toArray();
|
||||||
|
$this->data['list'] = $list;
|
||||||
|
return $this->view();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,345 @@
|
||||||
|
<?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'],
|
||||||
|
];
|
||||||
|
$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'],
|
||||||
|
];
|
||||||
|
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,11 @@
|
||||||
|
<?php
|
||||||
|
namespace app\controller\manager;
|
||||||
|
|
||||||
|
class Index extends Base
|
||||||
|
{
|
||||||
|
//后台首页
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
return $this->redirect(url('manager.safe/index'));
|
||||||
|
}
|
||||||
|
}
|
|
@ -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::getList();
|
||||||
|
$this->data['items'] = $items;
|
||||||
|
return $this->view();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,75 @@
|
||||||
|
<?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');
|
||||||
|
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::getListByGroup($auth['groupId'], 40);
|
||||||
|
}
|
||||||
|
$this->data['items'] = $items;
|
||||||
|
return $this->view();
|
||||||
|
}
|
||||||
|
}
|
|
@ -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,467 @@
|
||||||
|
<?php
|
||||||
|
namespace app\controller\manager;
|
||||||
|
|
||||||
|
use app\model\{Category, Block, Log};
|
||||||
|
use app\validate\Block as VBlock;
|
||||||
|
use think\exception\ValidateException;
|
||||||
|
use app\service\Tool;
|
||||||
|
|
||||||
|
class Page extends Base
|
||||||
|
{
|
||||||
|
//源码,代码
|
||||||
|
public function code()
|
||||||
|
{
|
||||||
|
if($this->request->isPost()){
|
||||||
|
$item = input('post.item/a');
|
||||||
|
$categoryId = input('post.category_id/d');
|
||||||
|
$id = input('post.id/d');
|
||||||
|
$item['keyword'] = Tool::trimSpace($item['keyword']);
|
||||||
|
try{
|
||||||
|
validate(VBlock::class)->check($item);
|
||||||
|
if(empty($item['value'])){
|
||||||
|
return $this->json(2, '内容不可为空!');
|
||||||
|
}
|
||||||
|
$block = Block::getByKeyword($item['keyword'], $categoryId);
|
||||||
|
if($id){
|
||||||
|
if(!empty($block) && $block['id'] != $id){
|
||||||
|
return $this->json(3, '键值已存在,请更改键值');
|
||||||
|
}
|
||||||
|
Block::updateById($id, $item);
|
||||||
|
Log::write('page', 'code', "单页代码编辑,ID:{$id}, 键值:{$item['keyword']}");
|
||||||
|
}else{
|
||||||
|
if($categoryId <= 0){
|
||||||
|
return $this->json(4, '栏目参数错误!');
|
||||||
|
}
|
||||||
|
if(!empty($block)){
|
||||||
|
return $this->json(3, '键值已存在,请更改键值');
|
||||||
|
}
|
||||||
|
$item['category_id'] = $categoryId;
|
||||||
|
$item['type'] = Block::CODE;
|
||||||
|
$block = Block::create($item);
|
||||||
|
Log::write('page', 'code', "单页代码新增,ID:{$block->id}, 键值:{$item['keyword']}");
|
||||||
|
}
|
||||||
|
return $this->json();
|
||||||
|
} catch (ValidateException $e){
|
||||||
|
return $this->json(1, $e->getError());
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
$id = input('param.id/d');
|
||||||
|
if($id <= 0){ //添加
|
||||||
|
$categoryId = input('param.category_id/d');
|
||||||
|
$category = Category::getById($categoryId);
|
||||||
|
if(empty($category)){
|
||||||
|
$url = url('manager.content/index')->__toString();
|
||||||
|
return $this->error('无此栏目', $url);
|
||||||
|
}
|
||||||
|
}else{ //修改
|
||||||
|
$item = Block::getById($id);
|
||||||
|
if(empty($item)){
|
||||||
|
return $this->error('无此代码块!');
|
||||||
|
}
|
||||||
|
$categoryId = $item['category_id'];
|
||||||
|
$this->data['item'] = $item;
|
||||||
|
}
|
||||||
|
$this->data['categoryId'] = $categoryId;
|
||||||
|
return $this->view();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//排序
|
||||||
|
public function sort()
|
||||||
|
{
|
||||||
|
if($this->request->isPost()){
|
||||||
|
$id = input('post.id/d');
|
||||||
|
$sort = input('post.sort');
|
||||||
|
$num = input('post.num/d', 1);
|
||||||
|
if($num <= 0){
|
||||||
|
$num = 1;
|
||||||
|
}
|
||||||
|
if(!in_array($sort, ['up', 'down'], true)){
|
||||||
|
return $this->json(2, '参数错误');
|
||||||
|
}
|
||||||
|
$item = Block::getById($id);
|
||||||
|
if(empty($item)){
|
||||||
|
return $this->json(3, '无此块信息');
|
||||||
|
}
|
||||||
|
if($sort == 'up'){
|
||||||
|
$where = "category_id='{$item['category_id']}' and sort < {$item['sort']}";
|
||||||
|
$order = "sort desc";
|
||||||
|
}else{
|
||||||
|
$where = "category_id='{$item['category_id']}' and sort > {$item['sort']}";
|
||||||
|
$order = "sort asc";
|
||||||
|
}
|
||||||
|
$forSortItems = Block::getListByWhereAndOrder($where, $order, $num);
|
||||||
|
if(!empty($forSortItems)){
|
||||||
|
$updateData = [];
|
||||||
|
$forSortCount = count($forSortItems);
|
||||||
|
for($i = 0; $i < $forSortCount; $i++){
|
||||||
|
if($i == 0){
|
||||||
|
$updateData[] = [
|
||||||
|
'id' => $forSortItems[$i]['id'],
|
||||||
|
'sort' => $item['sort']
|
||||||
|
];
|
||||||
|
}else{
|
||||||
|
$updateData[] = [
|
||||||
|
'id' => $forSortItems[$i]['id'],
|
||||||
|
'sort' => $forSortItems[$i - 1]['sort']
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$updateData[] = [
|
||||||
|
'id' => $item['id'],
|
||||||
|
'sort' => $forSortItems[$i - 1]['sort']
|
||||||
|
];
|
||||||
|
if(!empty($updateData)){
|
||||||
|
$model = new Block();
|
||||||
|
$model->saveAll($updateData);
|
||||||
|
$sortStr = $sort == 'up' ? '上移' : '下调';
|
||||||
|
Log::write('page', 'sort', "单页区块排序,ID:{$id} ,键值:{$item['keyword']},{$sortStr}了{$num}位");
|
||||||
|
return $this->json();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $this->json(4, '无须调整排序!');
|
||||||
|
}
|
||||||
|
return $this->error('无此操作');
|
||||||
|
}
|
||||||
|
|
||||||
|
//删除
|
||||||
|
public function del()
|
||||||
|
{
|
||||||
|
if ($this->request->isAjax()) {
|
||||||
|
$id = input('post.id/d');
|
||||||
|
$item = Block::getById($id);
|
||||||
|
if(!empty($item)){
|
||||||
|
Block::destroy($id);
|
||||||
|
Log::write('page', 'del', "单页区块删除,ID:{$id} ,键值:{$item['keyword']}");
|
||||||
|
return $this->json();
|
||||||
|
}
|
||||||
|
return $this->json(1, 'fail');
|
||||||
|
}
|
||||||
|
return $this->error('无此操作');
|
||||||
|
}
|
||||||
|
//图片
|
||||||
|
public function img()
|
||||||
|
{
|
||||||
|
if($this->request->isPost()){
|
||||||
|
$item = input('post.item/a');
|
||||||
|
$img = trim(input('post.img'));
|
||||||
|
$categoryId = input('post.category_id/d');
|
||||||
|
if (!empty($img) && $img == 'null') {
|
||||||
|
$img = '';
|
||||||
|
}
|
||||||
|
$id = input('post.id/d');
|
||||||
|
$item['keyword'] = Tool::trimSpace($item['keyword']);
|
||||||
|
try{
|
||||||
|
validate(VBlock::class)->check($item);
|
||||||
|
$block = Block::getByKeyword($item['keyword'], $categoryId);
|
||||||
|
if($id){
|
||||||
|
if(!empty($block) && $block['id'] != $id){
|
||||||
|
return $this->json(4, '键值已存在,请更改键值');
|
||||||
|
}
|
||||||
|
if(!empty($img)){
|
||||||
|
$item['value'] = $img;
|
||||||
|
}
|
||||||
|
Block::updateById($id, $item);
|
||||||
|
Log::write('page', 'img', "单页图片编辑,ID:{$id} ,键值:{$item['keyword']}");
|
||||||
|
}else{
|
||||||
|
if(!empty($block)){
|
||||||
|
return $this->json(4, '键值已存在,请更改键值');
|
||||||
|
}
|
||||||
|
if($categoryId <= 0){
|
||||||
|
return $this->json(2, '栏目参数错误!!');
|
||||||
|
}
|
||||||
|
if(empty($img)){
|
||||||
|
return $this->json(3, '图片不可为空');
|
||||||
|
}
|
||||||
|
$item['value'] = $img;
|
||||||
|
$item['type'] = Block::IMG;
|
||||||
|
$item['category_id'] = $categoryId;
|
||||||
|
$block = Block::create($item);
|
||||||
|
Log::write('page', 'img', "单页图片新增,ID:{$block->id} ,键值:{$item['keyword']}");
|
||||||
|
}
|
||||||
|
return $this->json();
|
||||||
|
} catch (ValidateException $e){
|
||||||
|
return $this->json(1, $e->getError());
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
$id = input('param.id/d');
|
||||||
|
if($id <= 0){ //添加
|
||||||
|
$categoryId = input('param.category_id/d');
|
||||||
|
$category = Category::getById($categoryId);
|
||||||
|
if(empty($category)){
|
||||||
|
$url = url('manager.content/index')->__toString();
|
||||||
|
return $this->error('无此栏目', $url);
|
||||||
|
}
|
||||||
|
}else{ //修改
|
||||||
|
$item = Block::getById($id);
|
||||||
|
if(empty($item)){
|
||||||
|
return $this->error('无此图片!');
|
||||||
|
}
|
||||||
|
$categoryId = $item['category_id'];
|
||||||
|
$this->data['item'] = $item;
|
||||||
|
}
|
||||||
|
if(isset($item) && $item['width'] && $item['height']){
|
||||||
|
$imgSize = $item['width'].'px X '.$item['height'].'px';
|
||||||
|
}else{
|
||||||
|
$imgSize = '';
|
||||||
|
}
|
||||||
|
$this->data['categoryId'] = $categoryId;
|
||||||
|
$this->data['imgSize'] = $imgSize;
|
||||||
|
$this->data['groupId'] = session('auth.groupId');
|
||||||
|
return $this->view();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//文字块
|
||||||
|
public function block()
|
||||||
|
{
|
||||||
|
if($this->request->isPost()){
|
||||||
|
$item = input('post.item/a');
|
||||||
|
$categoryId = input('post.category_id/d');
|
||||||
|
$id = input('post.id/d');
|
||||||
|
$item['keyword'] = Tool::trimSpace($item['keyword']);
|
||||||
|
try{
|
||||||
|
validate(VBlock::class)->check($item);
|
||||||
|
if(empty($item['value'])){
|
||||||
|
return $this->json(1, '内容不可为空!');
|
||||||
|
}
|
||||||
|
$block = Block::getByKeyword($item['keyword'], $categoryId);
|
||||||
|
if($id){
|
||||||
|
if(!empty($block) && $block['id'] != $id){
|
||||||
|
return $this->json(4, '键值已存在,请更改键值');
|
||||||
|
}
|
||||||
|
Block::updateById($id, $item);
|
||||||
|
Log::write('page', 'block', "单页文字块编辑,ID:{$id} ,键值:{$item['keyword']}");
|
||||||
|
}else{
|
||||||
|
if($categoryId <= 0){
|
||||||
|
return $this->json(2, '栏目参数错误!');
|
||||||
|
}
|
||||||
|
if(!empty($block)){
|
||||||
|
return $this->json(4, '键值已存在,请更改键值');
|
||||||
|
}
|
||||||
|
$item['category_id'] = $categoryId;
|
||||||
|
$block = Block::create($item);
|
||||||
|
Log::write('page', 'block', "单页文字块新增,ID:{$block->id} ,键值:{$item['keyword']}");
|
||||||
|
}
|
||||||
|
return $this->json();
|
||||||
|
} catch (ValidateException $e){
|
||||||
|
return $this->json(1, $e->getError());
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
$id = input('param.id/d');
|
||||||
|
if($id <= 0){ //添加
|
||||||
|
$categoryId = input('param.category_id/d');
|
||||||
|
$category = Category::getById($categoryId);
|
||||||
|
if(empty($category)){
|
||||||
|
$url = url('manager.content/index')->__toString();
|
||||||
|
return $this->error('无此栏目', $url);
|
||||||
|
}
|
||||||
|
}else{ //修改
|
||||||
|
$item = Block::getById($id);
|
||||||
|
if(empty($item)){
|
||||||
|
return $this->error('无此文字块!');
|
||||||
|
}
|
||||||
|
$categoryId = $item['category_id'];
|
||||||
|
$this->data['item'] = $item;
|
||||||
|
}
|
||||||
|
$this->data['categoryId'] = $categoryId;
|
||||||
|
return $this->view();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//富文本内容
|
||||||
|
public function text()
|
||||||
|
{
|
||||||
|
if($this->request->isPost()){
|
||||||
|
$item = input('post.item/a');
|
||||||
|
$categoryId = input('post.category_id/d');
|
||||||
|
$item['keyword'] = Tool::trimSpace($item['keyword']);
|
||||||
|
try{
|
||||||
|
validate(VBlock::class)->check($item);
|
||||||
|
if(empty($item['value'])){
|
||||||
|
return $this->json(1, '内容不可为空!');
|
||||||
|
}
|
||||||
|
$block = Block::getByKeyword($item['keyword'], $categoryId);
|
||||||
|
$id = input('post.id/d');
|
||||||
|
if($id){
|
||||||
|
if(!empty($block) && $block['id'] != $id){
|
||||||
|
return $this->json(4, '键值已存在,请更改');
|
||||||
|
}
|
||||||
|
Block::updateById($id, $item);
|
||||||
|
Log::write('page', 'text', "单页富文本编辑,ID:{$id} ,键值:{$item['keyword']}");
|
||||||
|
}else{
|
||||||
|
if($categoryId <= 0){
|
||||||
|
return $this->json(2, '栏目参数错误!');
|
||||||
|
}
|
||||||
|
if(!empty($block)){
|
||||||
|
return $this->json(4, '键值已存在,请更改键值');
|
||||||
|
}
|
||||||
|
$item['category_id'] = $categoryId;
|
||||||
|
$item['type'] = Block::TEXT;
|
||||||
|
$block = Block::create($item);
|
||||||
|
Log::write('page', 'text', "单页富文本新增,ID:{$block->id} ,键值:{$item['keyword']}");
|
||||||
|
}
|
||||||
|
return $this->json();
|
||||||
|
} catch (ValidateException $e){
|
||||||
|
return $this->json(1, $e->getError());
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
$id = input('param.id/d');
|
||||||
|
if($id <= 0){ //添加
|
||||||
|
$categoryId = input('param.category_id/d');
|
||||||
|
$category = Category::getById($categoryId);
|
||||||
|
if(empty($category)){
|
||||||
|
$url = url('manager.content/index')->__toString();
|
||||||
|
return $this->error('无此栏目', $url);
|
||||||
|
}
|
||||||
|
}else{ //修改
|
||||||
|
$item = Block::getById($id);
|
||||||
|
if(empty($item)){
|
||||||
|
return $this->error('无此富文本!');
|
||||||
|
}
|
||||||
|
$categoryId = $item['category_id'];
|
||||||
|
$this->data['item'] = $item;
|
||||||
|
}
|
||||||
|
$this->data['categoryId'] = $categoryId;
|
||||||
|
return $this->view();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//组图
|
||||||
|
public function group()
|
||||||
|
{
|
||||||
|
if($this->request->isPost()){
|
||||||
|
$item = input('post.item/a');
|
||||||
|
$imgs = input('post.img/a');
|
||||||
|
$categoryId = input('post.category_id/d');
|
||||||
|
if (!empty($imgs) && is_array($imgs)) {
|
||||||
|
$item['value'] = json_encode($imgs);
|
||||||
|
} else {
|
||||||
|
$item['value'] = '';
|
||||||
|
}
|
||||||
|
$item['keyword'] = Tool::trimSpace($item['keyword']);
|
||||||
|
try{
|
||||||
|
validate(VBlock::class)->check($item);
|
||||||
|
$block = Block::getByKeyword($item['keyword'], $categoryId);
|
||||||
|
$id = input('post.id/d');
|
||||||
|
if($id){
|
||||||
|
if(!empty($block) && $block['id'] != $id){
|
||||||
|
return $this->json(4, '键值已存在,请更改');
|
||||||
|
}
|
||||||
|
Block::updateById($id, $item);
|
||||||
|
Log::write('page', 'group', "单页组图编辑,ID:{$id} ,键值:{$item['keyword']}");
|
||||||
|
}else{
|
||||||
|
if($categoryId <= 0){
|
||||||
|
return $this->json(2, '栏目参数错误!');
|
||||||
|
}
|
||||||
|
if(!empty($block)){
|
||||||
|
return $this->json(4, '键值已存在,请更改键值');
|
||||||
|
}
|
||||||
|
$item['category_id'] = $categoryId;
|
||||||
|
$item['type'] = Block::GROUP;
|
||||||
|
$block = Block::create($item);
|
||||||
|
Log::write('page', 'group', "单页组图新增,ID:{$block->id} ,键值:{$item['keyword']}");
|
||||||
|
}
|
||||||
|
return $this->json();
|
||||||
|
} catch (ValidateException $e){
|
||||||
|
return $this->json(1, $e->getError());
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
$id = input('param.id/d');
|
||||||
|
if($id <= 0){ //添加
|
||||||
|
$categoryId = input('param.category_id/d');
|
||||||
|
$category = Category::getById($categoryId);
|
||||||
|
if(empty($category)){
|
||||||
|
$url = url('manager.content/index')->__toString();
|
||||||
|
return $this->error('无此栏目', $url);
|
||||||
|
}
|
||||||
|
}else{ //修改
|
||||||
|
$item = Block::getById($id);
|
||||||
|
if(empty($item)){
|
||||||
|
return $this->error('无此组图!');
|
||||||
|
}
|
||||||
|
$categoryId = $item['category_id'];
|
||||||
|
$this->data['item'] = $item;
|
||||||
|
}
|
||||||
|
$this->data['categoryId'] = $categoryId;
|
||||||
|
if(isset($item) && $item['width'] && $item['height']){
|
||||||
|
$imgSize = $item['width'].'px X '.$item['height'].'px';
|
||||||
|
}else{
|
||||||
|
$imgSize = '';
|
||||||
|
}
|
||||||
|
$this->data['imgSize'] = $imgSize;
|
||||||
|
$this->data['groupId'] = session('auth.groupId');
|
||||||
|
return $this->view();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//视频
|
||||||
|
public function video()
|
||||||
|
{
|
||||||
|
if($this->request->isPost()){
|
||||||
|
$item = input('post.item/a');
|
||||||
|
$img = trim(input('post.img'));
|
||||||
|
$video = trim(input('post.video'));
|
||||||
|
$categoryId = input('post.category_id/d');
|
||||||
|
$item['keyword'] = Tool::trimSpace($item['keyword']);
|
||||||
|
try{
|
||||||
|
validate(VBlock::class)->check($item);
|
||||||
|
$block = Block::getByKeyword($item['keyword'], $categoryId);
|
||||||
|
$id = input('post.id/d');
|
||||||
|
if($id){
|
||||||
|
if(!empty($block) && $block['id'] != $id){
|
||||||
|
return $this->json(4, '键值已存在,请更改');
|
||||||
|
}
|
||||||
|
if(!empty($img)){
|
||||||
|
$item['img'] = $img;
|
||||||
|
}
|
||||||
|
if(!empty($video)){
|
||||||
|
$item['value'] = $video;
|
||||||
|
}
|
||||||
|
Block::updateById($id, $item);
|
||||||
|
Log::write('page', 'video', "单页视频编辑,ID:{$id} ,键值:{$item['keyword']}");
|
||||||
|
}else{
|
||||||
|
if($categoryId <= 0){
|
||||||
|
return $this->json(2, '栏目参数错误!');
|
||||||
|
}
|
||||||
|
if(!empty($block)){
|
||||||
|
return $this->json(3, '键值已存在,请更改键值');
|
||||||
|
}
|
||||||
|
if(empty($video)){
|
||||||
|
return $this->json(3, '视频不可为空');
|
||||||
|
}
|
||||||
|
$item['category_id'] = $categoryId;
|
||||||
|
$item['type'] = Block::VIDEO;
|
||||||
|
$item['value'] = $video;
|
||||||
|
$item['img'] = $img;
|
||||||
|
$block = Block::create($item);
|
||||||
|
Log::write('page', 'video', "单页视频新增,ID:{$block->id} ,键值:{$item['keyword']}");
|
||||||
|
}
|
||||||
|
return $this->json();
|
||||||
|
} catch (ValidateException $e){
|
||||||
|
return $this->json(1, $e->getError());
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
$id = input('param.id/d');
|
||||||
|
if($id <= 0){ //添加
|
||||||
|
$categoryId = input('param.category_id/d');
|
||||||
|
$category = Category::getById($categoryId);
|
||||||
|
if(empty($category)){
|
||||||
|
$url = url('manager.content/index')->__toString();
|
||||||
|
return $this->error('无此栏目', $url);
|
||||||
|
}
|
||||||
|
}else{ //修改
|
||||||
|
$item = Block::getById($id);
|
||||||
|
if(empty($item)){
|
||||||
|
return $this->error('无此视频!');
|
||||||
|
}
|
||||||
|
$categoryId = $item['category_id'];
|
||||||
|
$this->data['item'] = $item;
|
||||||
|
}
|
||||||
|
$this->data['categoryId'] = $categoryId;
|
||||||
|
if(isset($item) && $item['width'] && $item['height']){
|
||||||
|
$imgSize = $item['width'].'px X '.$item['height'].'px';
|
||||||
|
}else{
|
||||||
|
$imgSize = '';
|
||||||
|
}
|
||||||
|
$this->data['imgSize'] = $imgSize;
|
||||||
|
$this->data['groupId'] = session('auth.groupId');
|
||||||
|
return $this->view();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,180 @@
|
||||||
|
<?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' ? '上移' : '下调';
|
||||||
|
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,63 @@
|
||||||
|
<?php
|
||||||
|
namespace app\controller\manager;
|
||||||
|
|
||||||
|
use app\model\{Member, Log};
|
||||||
|
|
||||||
|
class Safe extends Base
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 安全设置
|
||||||
|
* @return Safe
|
||||||
|
*/
|
||||||
|
|
||||||
|
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;
|
||||||
|
return $this->view();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,191 @@
|
||||||
|
<?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_pc');
|
||||||
|
$imgMobile = 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($imgMobile)){
|
||||||
|
$item['src_mobile'] = $imgMobile;
|
||||||
|
}
|
||||||
|
if(!empty($img)){
|
||||||
|
$item['src'] = $img;
|
||||||
|
}
|
||||||
|
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_pc');
|
||||||
|
$imgMobile = input('post.img_mobile');
|
||||||
|
|
||||||
|
if (empty($item)) {
|
||||||
|
return $this->json(1, '参数错误,请核对之后再操作!');
|
||||||
|
}
|
||||||
|
if(!empty($img)){
|
||||||
|
$item['src'] = $img;
|
||||||
|
}
|
||||||
|
if(!empty($imgMobile)){
|
||||||
|
$item['src_mobile'] = $imgMobile;
|
||||||
|
}
|
||||||
|
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,139 @@
|
||||||
|
<?php
|
||||||
|
namespace app\controller\manager;
|
||||||
|
|
||||||
|
use app\service\Image;
|
||||||
|
use app\model\{System, File};
|
||||||
|
use app\validate\Upload as VUpload;
|
||||||
|
use think\facade\{Filesystem, Config, Lang};
|
||||||
|
use think\Image as TImage;
|
||||||
|
use app\controller\BaseController;
|
||||||
|
|
||||||
|
class Upload extends BaseController
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
File::add($video, $src, 'video'); //加入上传文件表
|
||||||
|
return $this->json(0, 'ok', $return);
|
||||||
|
}else{
|
||||||
|
$errorMsg = Lang::get($this->validate->getError());
|
||||||
|
return $this->json(1, $errorMsg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//文件上传(通用)
|
||||||
|
public function file()
|
||||||
|
{
|
||||||
|
$file = request()->file('file');
|
||||||
|
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');
|
||||||
|
if($this->validate->checkImage($image)){
|
||||||
|
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, 100, 100, TImage::THUMB_SCALING); //上传返回缩略图宽度为100
|
||||||
|
}
|
||||||
|
$return['src'] = $src;
|
||||||
|
if($this->isCompress){
|
||||||
|
Image::resize($src);
|
||||||
|
}
|
||||||
|
File::add($image, $src); //加入上传文件表
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
return $this->json(1, $e->getMessage());
|
||||||
|
}
|
||||||
|
return $this->json(0, 'ok', $return);
|
||||||
|
}else{
|
||||||
|
$errorMsg = Lang::get($this->validate->getError());
|
||||||
|
return $this->json(1, $errorMsg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//富文本编辑器商城图片
|
||||||
|
public function wangImage()
|
||||||
|
{
|
||||||
|
|
||||||
|
$imageArr = request()->file('wang_img'); // 该方式,前端js上传方法中字段名称必须以数组形式传参 如 wang_img[] = 值
|
||||||
|
$errno = 0;
|
||||||
|
$data = [];
|
||||||
|
if(!$this->uploadPathIsWritable){
|
||||||
|
$errno = 1;
|
||||||
|
$data[] = '上传文件夹需要写入权限';
|
||||||
|
}else{
|
||||||
|
foreach ($imageArr as $image) {
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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,168 @@
|
||||||
|
<?php
|
||||||
|
namespace app\model;
|
||||||
|
|
||||||
|
class Article extends Base
|
||||||
|
{
|
||||||
|
//获取最高访问的文章列表
|
||||||
|
public static function getMostVisited($limit = 5)
|
||||||
|
{
|
||||||
|
if($limit <= 0){
|
||||||
|
$limit = 5;
|
||||||
|
}
|
||||||
|
return self::order('views', 'desc')
|
||||||
|
->limit($limit)
|
||||||
|
->select()
|
||||||
|
->toArray();
|
||||||
|
}
|
||||||
|
//获取栏目下最新记录
|
||||||
|
public static function getLatestByCategory($categoryId, $limit = 5)
|
||||||
|
{
|
||||||
|
if(empty($categoryId)){
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
if($limit <= 0){
|
||||||
|
$limit = 5;
|
||||||
|
}
|
||||||
|
return self::where('category_id', $categoryId)
|
||||||
|
->order('create_time', 'desc')
|
||||||
|
->limit($limit)
|
||||||
|
->select()
|
||||||
|
->toArray();
|
||||||
|
}
|
||||||
|
//根据文章ID和栏目ID获取下一篇文章
|
||||||
|
public static function getNextArticleByIdAndCategoryId($id, $categoryId)
|
||||||
|
{
|
||||||
|
return self::where('id','<',$id)
|
||||||
|
->where('category_id', $categoryId)
|
||||||
|
->where('status', 1)
|
||||||
|
->order('sort desc')
|
||||||
|
->findOrEmpty()
|
||||||
|
->toArray();
|
||||||
|
}
|
||||||
|
//根据文章ID和栏目ID获取上一篇文章
|
||||||
|
public static function getPrevArticleByIdAndCategoryId($id, $categoryId)
|
||||||
|
{
|
||||||
|
return self::where('id','>',$id)
|
||||||
|
->where('category_id',$categoryId)
|
||||||
|
->where('status', 1)
|
||||||
|
->order('sort asc')
|
||||||
|
->findOrEmpty()
|
||||||
|
->toArray();
|
||||||
|
}
|
||||||
|
//根据栏目ID获取文章列表
|
||||||
|
public static function getListByCategory($categoryId, $limit = 10)
|
||||||
|
{
|
||||||
|
return self::where('category_id', $categoryId)
|
||||||
|
->where('status', 1)
|
||||||
|
->order("sort desc")
|
||||||
|
->limit($limit)
|
||||||
|
->select()
|
||||||
|
->toArray();
|
||||||
|
}
|
||||||
|
//根据栏目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::where($where)
|
||||||
|
->order("sort desc")
|
||||||
|
->paginate($paginate,false);
|
||||||
|
}
|
||||||
|
//根据栏目ID获取文章分页列表
|
||||||
|
public static function getListCount($categoryId)
|
||||||
|
{
|
||||||
|
$where = [
|
||||||
|
['category_id', '=', $categoryId],
|
||||||
|
['status', '=', 1],
|
||||||
|
];
|
||||||
|
$param['category_id'] = $categoryId;
|
||||||
|
|
||||||
|
return self::where($where)
|
||||||
|
->order("sort desc")
|
||||||
|
->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 $categoryId 分类ID
|
||||||
|
* @param int $per 每页数量
|
||||||
|
* @param string $keyword 关键词
|
||||||
|
* @param array $param 文章类型:置顶、热门、推荐 ['top','hot','recommend']
|
||||||
|
* @param int $status 文章状态,-1表示不限制
|
||||||
|
* @return \think\Paginator
|
||||||
|
* @throws \think\db\exception\DbException
|
||||||
|
*/
|
||||||
|
public static function getList($categoryId, $per = 20, $keyword = '', $param = [], $status = -1)
|
||||||
|
{
|
||||||
|
$whereMap = [];
|
||||||
|
$pageParam = [];
|
||||||
|
if(is_numeric($categoryId) && $categoryId > 0) {
|
||||||
|
$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::when(count($whereMap) > 0, function($query) use ($whereMap) {
|
||||||
|
$query->where($whereMap);
|
||||||
|
})
|
||||||
|
->order("sort desc")
|
||||||
|
->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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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,41 @@
|
||||||
|
<?php
|
||||||
|
namespace app\model;
|
||||||
|
|
||||||
|
use think\Model;
|
||||||
|
|
||||||
|
class Base extends Model
|
||||||
|
{
|
||||||
|
protected $autoWriteTimestamp = false;
|
||||||
|
//根据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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,113 @@
|
||||||
|
<?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;
|
||||||
|
|
||||||
|
//获取类型键值对
|
||||||
|
public static function getTypes()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'1' => 'block',
|
||||||
|
'2' => 'img',
|
||||||
|
'3' => 'text',
|
||||||
|
'4' => 'group',
|
||||||
|
'5' => 'video',
|
||||||
|
'6' => 'code'
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
//根据键值和类目获取数据
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,189 @@
|
||||||
|
<?php
|
||||||
|
namespace app\model;
|
||||||
|
|
||||||
|
class Category extends Base
|
||||||
|
{
|
||||||
|
//获取首页栏目ID
|
||||||
|
public static function getIndex()
|
||||||
|
{
|
||||||
|
return self::where('is_index', 1)->findOrEmpty()->toArray();
|
||||||
|
}
|
||||||
|
//根据上级ID和语言获取下级栏目
|
||||||
|
public static function getChildrenByParentId($parentId)
|
||||||
|
{
|
||||||
|
if($parentId <= 0){
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
$category = self::getById($parentId);
|
||||||
|
if(empty($category)){
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
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)
|
||||||
|
->order('c.sort','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)
|
||||||
|
->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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,93 @@
|
||||||
|
<?php
|
||||||
|
namespace app\model;
|
||||||
|
|
||||||
|
use think\Image;
|
||||||
|
|
||||||
|
class File extends Base
|
||||||
|
{
|
||||||
|
const IMG = 'img';
|
||||||
|
const VIDEO = 'video';
|
||||||
|
const FILE = 'file';
|
||||||
|
|
||||||
|
//获取文件类型
|
||||||
|
public static function getTypes()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'img' => '图片',
|
||||||
|
'video' => '视频',
|
||||||
|
'file' => '文件'
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
//获取文件列表
|
||||||
|
public static function getList($type = '', $page = 1, $per = 20)
|
||||||
|
{
|
||||||
|
$limit = ($page - 1) * $per;
|
||||||
|
if($type != ''){
|
||||||
|
if(!in_array($type, array_keys(self::getTypes()))){
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
$items = self::where('type', $type)
|
||||||
|
->order('id desc');
|
||||||
|
}else{
|
||||||
|
$items = self::order('id desc');
|
||||||
|
}
|
||||||
|
$items = $items->limit($limit, $per)->select()->toArray();
|
||||||
|
foreach($items as &$item){
|
||||||
|
$item['sizeStr'] = sizeToStr($item['size']);
|
||||||
|
}
|
||||||
|
return $items;
|
||||||
|
}
|
||||||
|
|
||||||
|
//获取分页列表
|
||||||
|
public static function getListPage($type = '', $per = 20)
|
||||||
|
{
|
||||||
|
if($type != ''){
|
||||||
|
if(!in_array($type, array_keys(self::getTypes()))){
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
return self::where('type', $type)
|
||||||
|
->order('id desc')
|
||||||
|
->paginate([
|
||||||
|
'list_rows' => $per,
|
||||||
|
'query' => [
|
||||||
|
'type' => $type
|
||||||
|
]
|
||||||
|
], false);
|
||||||
|
}else{
|
||||||
|
return self::order('id desc')
|
||||||
|
->paginate([
|
||||||
|
'list_rows' => $per
|
||||||
|
], false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//添加,$w_h图片尺寸大小,单位像素,只对type=img时有效
|
||||||
|
public static function add($file, $src, $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
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
//获取所有记录
|
||||||
|
public static function getAll()
|
||||||
|
{
|
||||||
|
return self::select()->toArray();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
<?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
|
||||||
|
];
|
||||||
|
$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)
|
||||||
|
{
|
||||||
|
$items = self::where('category_id', $categoryId)
|
||||||
|
->when($onlyVisible, function($query){
|
||||||
|
$query->where('visible', 1);
|
||||||
|
})
|
||||||
|
->order('sort', 'asc')
|
||||||
|
->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,39 @@
|
||||||
|
<?php
|
||||||
|
namespace app\model;
|
||||||
|
|
||||||
|
class Link 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($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,57 @@
|
||||||
|
<?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;
|
||||||
|
}
|
||||||
|
|
||||||
|
//根据用户名获取管理账号
|
||||||
|
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,14 @@
|
||||||
|
<?php
|
||||||
|
namespace app\model;
|
||||||
|
|
||||||
|
class Message extends Base
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 获取留言列表
|
||||||
|
*/
|
||||||
|
public static function getList($per = 20)
|
||||||
|
{
|
||||||
|
return self::order("create_time desc")
|
||||||
|
->paginate($per);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
<?php
|
||||||
|
namespace app\model;
|
||||||
|
|
||||||
|
class Model extends Base
|
||||||
|
{
|
||||||
|
//获取模型列表
|
||||||
|
public static function getList()
|
||||||
|
{
|
||||||
|
return self::order('sort asc')
|
||||||
|
->select()
|
||||||
|
->toArray();
|
||||||
|
}
|
||||||
|
public static function onAfterInsert($model)
|
||||||
|
{
|
||||||
|
$model->sort = $model->id;
|
||||||
|
$model->save();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,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,54 @@
|
||||||
|
<?php
|
||||||
|
namespace app\model;
|
||||||
|
|
||||||
|
class System extends Base
|
||||||
|
{
|
||||||
|
//获取友情链接上传图片尺寸
|
||||||
|
public static function getLinkImageSize()
|
||||||
|
{
|
||||||
|
$system = self::getSystem();
|
||||||
|
if(!empty($system['link_w']) && !empty($system['link_h'])){
|
||||||
|
$linkSize = $system['link_w'] . '像素 X ' . $system['link_h'] . '像素';
|
||||||
|
}else{
|
||||||
|
$linkSize = '';
|
||||||
|
}
|
||||||
|
return $linkSize;
|
||||||
|
}
|
||||||
|
//获取幻灯片上传尺寸
|
||||||
|
public static function getSlideImageSize()
|
||||||
|
{
|
||||||
|
$system = self::getSystem();
|
||||||
|
if(!empty($system['slide_w']) && !empty($system['slide_h'])){
|
||||||
|
$slideSize = $system['slide_w'] . '像素 X ' . $system['slide_h'] . '像素';
|
||||||
|
}else{
|
||||||
|
$slideSize = '';
|
||||||
|
}
|
||||||
|
if(!empty($system['slide_mobile_w']) && !empty($system['slide_mobile_h'])){
|
||||||
|
$slideMobileSize = $system['slide_mobile_w'] . '像素 X ' . $system['slide_mobile_h'] . '像素';
|
||||||
|
}else{
|
||||||
|
$slideMobileSize = '';
|
||||||
|
}
|
||||||
|
return [
|
||||||
|
'slide_size' => $slideSize,
|
||||||
|
'slide_mobile_size' => $slideMobileSize
|
||||||
|
];
|
||||||
|
}
|
||||||
|
//获取文章图片尺寸
|
||||||
|
public static function getArticleImageSize()
|
||||||
|
{
|
||||||
|
$system = self::getSystem();
|
||||||
|
if(!empty($system['article_w']) && !empty($system['article_h'])){
|
||||||
|
$articleSize = $system['article_w'] . '像素 X ' . $system['article_h'] . '像素';
|
||||||
|
}else{
|
||||||
|
$articleSize = '';
|
||||||
|
}
|
||||||
|
return $articleSize;
|
||||||
|
}
|
||||||
|
//获取系统配置信息
|
||||||
|
public static function getSystem()
|
||||||
|
{
|
||||||
|
return self::order('id asc')
|
||||||
|
->findOrEmpty()
|
||||||
|
->toArray();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
<?php
|
||||||
|
namespace app\service;
|
||||||
|
|
||||||
|
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];
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,131 @@
|
||||||
|
<?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 = app()->getRootPath() . 'public/' . ltrim($src,'/');
|
||||||
|
if(is_file($realPath)){
|
||||||
|
$img = TImage::open($realPath);
|
||||||
|
list($img_w,$img_h) = $img->size();
|
||||||
|
if($max > 0 && $img_w > $max){
|
||||||
|
$img->thumb($max, $max * ($img_h / $img_w))->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 '';
|
||||||
|
}
|
||||||
|
$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,53 @@
|
||||||
|
<?php
|
||||||
|
namespace app\service;
|
||||||
|
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
<?php
|
||||||
|
namespace app\validate;
|
||||||
|
|
||||||
|
use think\Validate;
|
||||||
|
|
||||||
|
class Article extends Validate
|
||||||
|
{
|
||||||
|
protected $rule = [
|
||||||
|
'title' => 'require',
|
||||||
|
'link' => 'url'
|
||||||
|
];
|
||||||
|
protected $message = [
|
||||||
|
'title.require' => '标题必须',
|
||||||
|
'link.url' => '请填写有效的网址'
|
||||||
|
];
|
||||||
|
}
|
|
@ -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,18 @@
|
||||||
|
<?php
|
||||||
|
namespace app\validate;
|
||||||
|
|
||||||
|
use think\Validate;
|
||||||
|
|
||||||
|
class Category extends Validate
|
||||||
|
{
|
||||||
|
protected $rule = [
|
||||||
|
'title' => 'require',
|
||||||
|
'model_id' => 'require|number|min:1',
|
||||||
|
];
|
||||||
|
protected $message = [
|
||||||
|
'title.require' => '栏目名称必须',
|
||||||
|
'model_id.require' => '栏目模型必须',
|
||||||
|
'model_id.number' => '栏目模型格式要正确',
|
||||||
|
'model_id.min' => '请选择正确的栏目模型'
|
||||||
|
];
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
<?php
|
||||||
|
namespace app\validate;
|
||||||
|
|
||||||
|
use think\Validate;
|
||||||
|
|
||||||
|
class History extends Validate
|
||||||
|
{
|
||||||
|
protected $rule = [
|
||||||
|
'title' => 'require|length:1,60',
|
||||||
|
'visible' => 'require|in:0,1',
|
||||||
|
];
|
||||||
|
protected $message = [
|
||||||
|
'title.require' => '标题不能为空',
|
||||||
|
'name.length' => '标题长度限制为60个字符以内',
|
||||||
|
'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,200',
|
||||||
|
'visible' => 'require|in:0,1',
|
||||||
|
];
|
||||||
|
protected $message = [
|
||||||
|
'title.require' => '标题不能为空',
|
||||||
|
'name.length' => '标题长度限制为200个字符以内',
|
||||||
|
'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 Member extends Validate
|
||||||
|
{
|
||||||
|
protected $rule = [
|
||||||
|
'group_id' => 'require|number',
|
||||||
|
'username' => 'require',
|
||||||
|
];
|
||||||
|
protected $message = [
|
||||||
|
'group_id.require' => '所属角色不能为空!',
|
||||||
|
'group_id.number' => '用户角色信息数据格式不正确!',
|
||||||
|
'username.require' => '用户姓名不能为空!',
|
||||||
|
];
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
<?php
|
||||||
|
namespace app\validate;
|
||||||
|
|
||||||
|
use think\Validate;
|
||||||
|
|
||||||
|
class Model extends Validate
|
||||||
|
{
|
||||||
|
protected $rule = [
|
||||||
|
'name' => 'require',
|
||||||
|
'manager' => 'require',
|
||||||
|
];
|
||||||
|
protected $message = [
|
||||||
|
'name.require' => '名称必须',
|
||||||
|
'manager.require' => '后台管理必须'
|
||||||
|
];
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
<?php
|
||||||
|
namespace app\validate;
|
||||||
|
|
||||||
|
use think\Validate;
|
||||||
|
|
||||||
|
class Slide extends Validate
|
||||||
|
{
|
||||||
|
protected $rule = [
|
||||||
|
'title' => 'require',
|
||||||
|
'url' => 'url',
|
||||||
|
];
|
||||||
|
protected $message = [
|
||||||
|
'title.require' => '标题必须',
|
||||||
|
'url.url' => '请填写有效的网址,以http://或https://开头'
|
||||||
|
];
|
||||||
|
}
|
|
@ -0,0 +1,60 @@
|
||||||
|
<?php
|
||||||
|
namespace app\validate;
|
||||||
|
|
||||||
|
use think\Validate;
|
||||||
|
use app\model\System;
|
||||||
|
use think\Lang;
|
||||||
|
|
||||||
|
class Upload extends Validate
|
||||||
|
{
|
||||||
|
protected $rule = [];
|
||||||
|
protected $message = [];
|
||||||
|
protected $system;
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->system = System::getSystem();
|
||||||
|
$this->lang = new Lang;
|
||||||
|
}
|
||||||
|
|
||||||
|
//验证图片上传
|
||||||
|
public function checkImage($image)
|
||||||
|
{
|
||||||
|
$ext = str_replace(',', ',', $this->system['img_type']);
|
||||||
|
$size = $this->system['img_size'] * 1024 * 1024;
|
||||||
|
$this->rule = [
|
||||||
|
'image' => [
|
||||||
|
'fileExt' => $ext,
|
||||||
|
'fileSize' => (int)$size
|
||||||
|
]
|
||||||
|
];
|
||||||
|
return $this->check(['image' => $image]);
|
||||||
|
}
|
||||||
|
|
||||||
|
//验证视频上传
|
||||||
|
public function checkVideo($video)
|
||||||
|
{
|
||||||
|
$ext = str_replace(',', ',', $this->system['video_type']);
|
||||||
|
$size = $this->system['video_size'] * 1024 * 1024;
|
||||||
|
$this->rule = [
|
||||||
|
'video' => [
|
||||||
|
'fileExt' => $ext,
|
||||||
|
'fileSize' => (int)$size
|
||||||
|
]
|
||||||
|
];
|
||||||
|
return $this->check(['video' => $video]);
|
||||||
|
}
|
||||||
|
|
||||||
|
//验证文件上传
|
||||||
|
public function checkFile($file)
|
||||||
|
{
|
||||||
|
$ext = str_replace(',', ',', $this->system['file_type']);
|
||||||
|
$size = $this->system['file_size'] * 1024 * 1024;
|
||||||
|
$this->rule = [
|
||||||
|
'file' => [
|
||||||
|
'fileExt' => $ext,
|
||||||
|
'fileSize' => (int)$size
|
||||||
|
]
|
||||||
|
];
|
||||||
|
return $this->check(['file' => $file]);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
<?php
|
||||||
|
namespace app\widget;
|
||||||
|
|
||||||
|
use app\model\Category;
|
||||||
|
use think\facade\View;
|
||||||
|
|
||||||
|
class Crumbs
|
||||||
|
{
|
||||||
|
public function index($categoryId)
|
||||||
|
{
|
||||||
|
$data = [
|
||||||
|
'crumbs' => Category::getCatesCrumbs($categoryId)
|
||||||
|
];
|
||||||
|
return View::assign($data)->fetch('public/crumbs');
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,49 @@
|
||||||
|
<?php
|
||||||
|
namespace app\widget;
|
||||||
|
|
||||||
|
|
||||||
|
use app\model\Category;
|
||||||
|
use think\facade\{Db,View, Cache};
|
||||||
|
|
||||||
|
class Menu
|
||||||
|
{
|
||||||
|
public function index($categoryId)
|
||||||
|
{
|
||||||
|
$menus = Cache::get('rules');
|
||||||
|
if(empty($menus)){
|
||||||
|
$menus = Category::getListForFrontMenu();
|
||||||
|
}
|
||||||
|
$currentFirstId = 0;
|
||||||
|
if (is_numeric($categoryId) && $categoryId > 0) {
|
||||||
|
$currentFirstId = Category::firstGradeById($categoryId);
|
||||||
|
}
|
||||||
|
|
||||||
|
//产品菜单
|
||||||
|
|
||||||
|
$product_children=Category::alias('c')
|
||||||
|
->leftJoin('model m', 'c.model_id=m.id')
|
||||||
|
->field('c.*, m.manager, m.template, m.name as modelName')
|
||||||
|
->where('c.parent_id', 5)
|
||||||
|
->order('c.sort','asc')
|
||||||
|
->select()
|
||||||
|
->toArray();
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
'categoryId' => $categoryId,
|
||||||
|
'menus' => $menus,
|
||||||
|
'product_children' => $product_children?$product_children:[],
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
|
$this_menu= \app\model\Category::alias('c')
|
||||||
|
->leftJoin('model m', 'c.model_id=m.id')
|
||||||
|
->field('c.*, m.manager, m.name as modelName')
|
||||||
|
->when(3, function($query) {
|
||||||
|
$query->whereIn('c.id', []);
|
||||||
|
})
|
||||||
|
->order('sort','asc')
|
||||||
|
->select()
|
||||||
|
->toArray();
|
||||||
|
return View::assign($data)->fetch('public/menu');
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
<?php
|
||||||
|
namespace app\widget;
|
||||||
|
|
||||||
|
use think\facade\View;
|
||||||
|
use app\model\Slide as WSlide;
|
||||||
|
|
||||||
|
class Slide
|
||||||
|
{
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
$data = [
|
||||||
|
'slides' => WSlide::getList(),
|
||||||
|
];
|
||||||
|
return View::assign($data)->fetch('public/slide');
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
<?php
|
||||||
|
namespace app\widget\manager;
|
||||||
|
|
||||||
|
use app\model\{Category, AuthRule};
|
||||||
|
use think\facade\View;
|
||||||
|
|
||||||
|
class Crumbs
|
||||||
|
{
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
$request = request();
|
||||||
|
$controller = strtolower($request->controller());
|
||||||
|
$action = strtolower($request->action());
|
||||||
|
$controller = str_replace('manager.', '', $controller);
|
||||||
|
$name = $controller . '/' . $action;
|
||||||
|
if($action == 'index'){
|
||||||
|
$rule = AuthRule::getByTwoName($name, $controller);
|
||||||
|
}else{
|
||||||
|
$rule = AuthRule::getByName($name);
|
||||||
|
}
|
||||||
|
$parent = [];
|
||||||
|
if(!empty($rule) && $rule['parent_id']){
|
||||||
|
$parent = AuthRule::getById($rule['parent_id']);
|
||||||
|
}
|
||||||
|
$cateCrumbs = [];
|
||||||
|
$isContent = false;
|
||||||
|
if($controller == 'content') {
|
||||||
|
$isContent = true;
|
||||||
|
$categoryId = $request->param('category_id', 0);
|
||||||
|
if (is_numeric($categoryId) && $categoryId > 0) {
|
||||||
|
$cateCrumbs = Category::getCatesCrumbs($categoryId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
'rule' => $rule,
|
||||||
|
'parent' => $parent,
|
||||||
|
'isContent' => $isContent,
|
||||||
|
'cateCrumbs' => $cateCrumbs
|
||||||
|
];
|
||||||
|
return View::assign($data)->fetch('manager/widget/crumbs');
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,90 @@
|
||||||
|
<?php
|
||||||
|
namespace app\widget\manager;
|
||||||
|
|
||||||
|
use think\facade\{View, Cache};
|
||||||
|
use app\model\Category;
|
||||||
|
|
||||||
|
class Menu
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 左侧菜单
|
||||||
|
* milo
|
||||||
|
* 2018-01-06
|
||||||
|
*/
|
||||||
|
public function left($categoryId = 0)
|
||||||
|
{
|
||||||
|
$auth = session('auth');
|
||||||
|
$authCates = array_filter(explode(',', $auth['cates']));
|
||||||
|
$rules = Cache::get('group_rules_'.$auth['groupId']);
|
||||||
|
$menuRules = $this->getMenuRules($rules);
|
||||||
|
|
||||||
|
$current = strtolower(request()->controller());
|
||||||
|
$current = str_replace('manager.', '', $current);
|
||||||
|
$currentAction = strtolower($current.'/'.request()->action());
|
||||||
|
// message 留言管理是否集成在内容管理中,后期开发中根据情况调整
|
||||||
|
if(in_array($current, ['article', 'product', 'page'], true)){
|
||||||
|
$current = 'content';
|
||||||
|
}
|
||||||
|
if($auth['groupId'] == 1) {
|
||||||
|
$menus = $this->getMenus(Category::getList(false));
|
||||||
|
} else {
|
||||||
|
$menus = $this->getMenus(Category::getList(true, $authCates));
|
||||||
|
}
|
||||||
|
$data = [
|
||||||
|
'rules' => $menuRules,
|
||||||
|
'categoryId' => $categoryId,
|
||||||
|
'menus' => $menus,
|
||||||
|
'current' => $current,
|
||||||
|
'currentAction' => $currentAction
|
||||||
|
];
|
||||||
|
return View::assign($data)->fetch('manager/widget/left');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 过滤出权限菜单
|
||||||
|
* @param $rules
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
private function getMenuRules($rules)
|
||||||
|
{
|
||||||
|
$menuRules = [];
|
||||||
|
if (!empty($rules)) {
|
||||||
|
foreach ($rules as $rule) {
|
||||||
|
$hasChildren = $rule['hasChildren'] ?? false;
|
||||||
|
if ($hasChildren) {
|
||||||
|
$rule['children'] = $this->getMenuRules($rule['children']);
|
||||||
|
if(count($rule['children']) > 0) {
|
||||||
|
$rule['status'] = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if($rule['status'] > 0) {
|
||||||
|
$menuRules[] = $rule;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $menuRules;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 内容栏目菜单
|
||||||
|
* @param $cates
|
||||||
|
* @param int $parent_id
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
private function getMenus($cates,$parentId=0)
|
||||||
|
{
|
||||||
|
$menus = [];
|
||||||
|
foreach($cates as $cate){
|
||||||
|
if($cate['parent_id'] == $parentId && $cate['state'] == 1){
|
||||||
|
$children = $this->getMenus($cates,$cate['id']);
|
||||||
|
if(!empty($children)){
|
||||||
|
$cate['children'] = $children;
|
||||||
|
}
|
||||||
|
if(!empty($cate['children']) || !empty($cate['manager'])){
|
||||||
|
$menus[] = $cate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $menus;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,71 @@
|
||||||
|
<?php
|
||||||
|
namespace app\widget\manager;
|
||||||
|
|
||||||
|
use think\facade\View;
|
||||||
|
|
||||||
|
class Upload
|
||||||
|
{
|
||||||
|
//视频
|
||||||
|
public function video($src = '', $append = '')
|
||||||
|
{
|
||||||
|
$data = [
|
||||||
|
'src' => $src,
|
||||||
|
'append' => $append
|
||||||
|
];
|
||||||
|
return View::assign($data)->fetch('manager/widget/video');
|
||||||
|
}
|
||||||
|
|
||||||
|
//图片(layui自带上传控件),若同一页面内徐亚加载多层本上传控件则需要传不同的$append来区分控件ID
|
||||||
|
public function image($src = '', $append = '', $imgSize = 0, $thumb = 0)
|
||||||
|
{
|
||||||
|
$data = [
|
||||||
|
'src' => $src,
|
||||||
|
'append' => $append,
|
||||||
|
'imgSize' => $imgSize,
|
||||||
|
'thumb' => $thumb,
|
||||||
|
];
|
||||||
|
return View::assign($data)->fetch('manager/widget/image');
|
||||||
|
}
|
||||||
|
|
||||||
|
//上传文件,目前在文章中添加附件
|
||||||
|
public function files($files = [], $num = 10, $append = '')
|
||||||
|
{
|
||||||
|
if(!empty($files) && $files == 'null') {
|
||||||
|
$files = [];
|
||||||
|
}
|
||||||
|
$data = [
|
||||||
|
'files' => $files,
|
||||||
|
'append' => $append,
|
||||||
|
'num' => $num,
|
||||||
|
];
|
||||||
|
return View::assign($data)->fetch('manager/widget/files');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 水印图片上传
|
||||||
|
* milo
|
||||||
|
* 2018-01-13
|
||||||
|
*/
|
||||||
|
public function mark($src = '')
|
||||||
|
{
|
||||||
|
return View::assign(['src' => $src])->fetch('manager/widget/mark');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* layui组图上传
|
||||||
|
* milo
|
||||||
|
*/
|
||||||
|
public function multi($imgs = [], $num = 10, $append = '', $imgSize = '')
|
||||||
|
{
|
||||||
|
if(!empty($imgs) && $imgs == 'null') {
|
||||||
|
$imgs = [];
|
||||||
|
}
|
||||||
|
$data = [
|
||||||
|
'imgs' => $imgs,
|
||||||
|
'append' => $append,
|
||||||
|
'imgSize' => $imgSize,
|
||||||
|
'num' => $num
|
||||||
|
];
|
||||||
|
return View::assign($data)->fetch('manager/widget/multi');
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
<?php
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | Author: liu21st <liu21st@gmail.com>
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* php think build 自动生成应用的目录结构的定义示例
|
||||||
|
*/
|
||||||
|
return [
|
||||||
|
// 需要自动创建的文件
|
||||||
|
'__file__' => [],
|
||||||
|
// 需要自动创建的目录
|
||||||
|
'__dir__' => ['controller', 'model', 'view'],
|
||||||
|
// 需要自动创建的控制器
|
||||||
|
'controller' => ['Index'],
|
||||||
|
// 需要自动创建的模型
|
||||||
|
'model' => ['User'],
|
||||||
|
// 需要自动创建的模板
|
||||||
|
'view' => ['index/index'],
|
||||||
|
];
|
|
@ -0,0 +1,46 @@
|
||||||
|
{
|
||||||
|
"name": "topthink/think",
|
||||||
|
"description": "the new thinkphp framework",
|
||||||
|
"type": "project",
|
||||||
|
"keywords": [
|
||||||
|
"framework",
|
||||||
|
"thinkphp",
|
||||||
|
"ORM"
|
||||||
|
],
|
||||||
|
"homepage": "http://thinkphp.cn/",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "liu21st",
|
||||||
|
"email": "liu21st@gmail.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"require": {
|
||||||
|
"php": ">=7.1.0",
|
||||||
|
"topthink/framework": "^6.0.0",
|
||||||
|
"topthink/think-orm": "^2.0",
|
||||||
|
"topthink/think-view": "^1.0",
|
||||||
|
"topthink/think-image": "^1.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"symfony/var-dumper": "^4.2",
|
||||||
|
"topthink/think-trace":"^1.0"
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"app\\": "app"
|
||||||
|
},
|
||||||
|
"psr-0": {
|
||||||
|
"": "extend/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"config": {
|
||||||
|
"preferred-install": "dist"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"post-autoload-dump": [
|
||||||
|
"@php think service:discover",
|
||||||
|
"@php think vendor:publish"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
After Width: | Height: | Size: 4.2 KiB |
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"name": "cms",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"lockfileVersion": 1
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
{
|
||||||
|
"name": "cms",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "本CMS基于ThinkPHP 6.0开发",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://gitee.com/dxtc/cms.git"
|
||||||
|
},
|
||||||
|
"keywords": [],
|
||||||
|
"author": "",
|
||||||
|
"license": "ISC"
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
<IfModule mod_rewrite.c>
|
||||||
|
Options +FollowSymlinks -Multiviews
|
||||||
|
RewriteEngine On
|
||||||
|
|
||||||
|
RewriteCond %{REQUEST_FILENAME} !-d
|
||||||
|
RewriteCond %{REQUEST_FILENAME} !-f
|
||||||
|
RewriteCond %{REQUEST_URI} !^(.*)\.(gif|jpg|jpeg|png|swf|mp4)$ [NC]
|
||||||
|
RewriteRule ^(.*)$ index.php?s=/$1 [QSA,PT,L]
|
||||||
|
</IfModule>
|
|
@ -0,0 +1,24 @@
|
||||||
|
<?php
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | Copyright (c) 2006-2018 http://thinkphp.cn All rights reserved.
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | Author: liu21st <liu21st@gmail.com>
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
|
||||||
|
// [ 应用入口文件 ]
|
||||||
|
namespace think;
|
||||||
|
|
||||||
|
header("Access-Control-Allow-Origin:*");
|
||||||
|
header('Access-Control-Allow-Methods:POST');
|
||||||
|
header('Access-Control-Allow-Headers:x-requested-with, content-type');
|
||||||
|
require dirname(__DIR__) . '/vendor/autoload.php';
|
||||||
|
|
||||||
|
// 执行HTTP应用并响应
|
||||||
|
$http = (new App())->http;
|
||||||
|
$response = $http->run();
|
||||||
|
$response->send();
|
||||||
|
$http->end($response);
|
|
@ -0,0 +1,599 @@
|
||||||
|
@charset "utf-8";
|
||||||
|
/* CSS Document */
|
||||||
|
/*公用代码*/
|
||||||
|
body,html{background:none repeat scroll 0 0;font:100% "Microsoft YaHei New","Microsoft Yahei","微软雅黑","Hiragino Sans GB","冬青黑体","Arial","Helvetica","SimHei","黑体","STXihei","华文细黑",sans-serif;}
|
||||||
|
body{overflow-x:hidden;color:#333;}
|
||||||
|
blockquote,body,button,dd,div,dl,dt,fieldset,form,h1,h2,h3,h4,h5,h6,input,li,ol,p,pre,td,textarea,th,ul{margin:0;padding:0;text-shadow:none;}
|
||||||
|
label input{vertical-align:middle;text-shadow:none;}
|
||||||
|
*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;}
|
||||||
|
a{-webkit-transition:all .5s;-moz-transition:all .5s;transition:all .5s;}
|
||||||
|
a:hover{ color: #578df3;}
|
||||||
|
:hover,a:active,a:focus,a:hover,a:link,a:visited{text-decoration:none;text-shadow:none;}
|
||||||
|
img{max-width:100%;border:0;}
|
||||||
|
i{ font-style: initial;}
|
||||||
|
table{border-collapse:collapse;}
|
||||||
|
ul li{list-style:none outside none;}
|
||||||
|
input,select,textarea{outline:medium none; resize: none;}
|
||||||
|
.f-l{float:left;}
|
||||||
|
.f-l,.f-r{display:inline-block;}
|
||||||
|
.f-r{float:right;}
|
||||||
|
.t-l{text-align:left;}
|
||||||
|
.t-c{text-align:center;}
|
||||||
|
.t-r{text-align:right;}
|
||||||
|
.top10{margin-top:10px;}
|
||||||
|
.top20{margin-top:20px;}
|
||||||
|
.top30,.top40{margin-top:30px;}
|
||||||
|
.top50{margin-top:50px;}
|
||||||
|
.top60{margin-top:60px;}
|
||||||
|
.top70{margin-top:70px;}
|
||||||
|
.top80{margin-top:80px;}
|
||||||
|
.bg-w{background:#fff;}
|
||||||
|
.w-90{ width: 94%; margin: auto;}
|
||||||
|
.w-100{width:100%; float: left;}
|
||||||
|
.w-1200{margin:auto;width:75rem;}
|
||||||
|
.w-1500{margin: auto; width: 1500px;}
|
||||||
|
.div-pc{ display: block;}
|
||||||
|
.div-phone{ display: none;}
|
||||||
|
|
||||||
|
|
||||||
|
/* 布局样式 */
|
||||||
|
.between-top{ display: flex; display: -webkit-flex; justify-content: space-between; -webkit-justify-content: space-between; }
|
||||||
|
.between-center{ display: flex; display: -webkit-flex; justify-content: space-between; align-items: center; -webkit-justify-content: space-between; -webkit-align-items: center; }
|
||||||
|
.between-bottom{ display: flex; display: -webkit-flex; justify-content: space-between; align-items: flex-end; -webkit-justify-content: space-between; -webkit-align-items: flex-end; }
|
||||||
|
.center-center{ display: -webkit-box; display: -ms-flexbox; display: flex; -webkit-box-align: center; -ms-flex-align: center; align-items: center; -webkit-box-pack: center; -ms-flex-pack: center; justify-content: center; -webkit-box-orient: vertical; -webkit-box-direction: normal; -ms-flex-direction: column; flex-direction: column; }
|
||||||
|
.around-center{ display: flex; display: -webkit-flex; justify-content: space-around; align-items: center; -webkit-justify-content: space-around; -webkit-align-items: center; }
|
||||||
|
.column-between{ display: flex; display: -webkit-flex; flex-direction: column; -webkit-flex-direction: column; justify-content: space-between; -webkit-justify-content: space-between; }
|
||||||
|
.column-around{ display: flex; display: -webkit-flex; flex-direction: column; -webkit-flex-direction: column; justify-content: space-around; -webkit-justify-content: space-around; }
|
||||||
|
|
||||||
|
/* 文字超出隐藏省略号 */
|
||||||
|
.text-one-hide{ overflow: hidden; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 1;}
|
||||||
|
.text-two-hide{ overflow: hidden; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2;}
|
||||||
|
.text-three-hide{ overflow: hidden; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3;}
|
||||||
|
|
||||||
|
/*nav*/
|
||||||
|
/**/
|
||||||
|
.nav ul li{ float: left; position: relative; margin-left: 4.6875rem; transition: all .6s;}
|
||||||
|
.nav ul li span a{ float: left; font-size: 1.125rem; line-height: 6.25rem; position: relative; text-decoration: none;}
|
||||||
|
.nav ul li span a::before{ content: ''; width: 0; height: 2px; position: absolute; left: 0; bottom: 0; background: #f54123; transition: all .6s; opacity: 0;}
|
||||||
|
/*二级控制*/
|
||||||
|
.nav ul li .nav-second{ width: auto; min-width: 5.625rem; position: absolute; left: 50%; top: 100%; background: #fff; opacity: 0; transform: translate(-50%,0); transition: all .6s;}
|
||||||
|
.nav ul li .nav-second a{ width: 100%; float: left; color: #333; text-align: center; height: 0; font-size: 0.875rem; white-space: nowrap;}
|
||||||
|
.nav ul li .nav-second a:hover,.nav ul li .nav-second a.active{ color: #f54123;}
|
||||||
|
/*三级级控制*/
|
||||||
|
.nav ul li .nav-second .nav-three{ width: 100%; position: relative; display: block; float: left;}
|
||||||
|
.nav ul li .nav-second .nav-three:hover p a{ background: #fff; color: #0c253b;}
|
||||||
|
.nav ul li .nav-second .nav-three div{ position: absolute; left: 100%; top: -10px; background: #f75c9a; padding: 10px 0; display: none;}
|
||||||
|
.nav ul li .nav-second .nav-three div::before{ content: ''; width: 10px; height: 50px; position: absolute; left: -10px; top: 0;}
|
||||||
|
.nav ul li .nav-second .nav-three div a{ display: block; white-space: nowrap;}
|
||||||
|
.nav ul li .nav-second .nav-three:hover div{ display: block;}
|
||||||
|
/*hover*/
|
||||||
|
.nav ul li:hover .nav-second{ padding: 0.625rem; opacity: 1;}
|
||||||
|
.nav ul li:hover .nav-second a{ height: 2rem; line-height: 2rem;}
|
||||||
|
.nav ul li:hover span a,.nav ul li.active span a{ color: #f54123 !important; font-weight: bold;}
|
||||||
|
.nav ul li:hover span a::before,.nav ul li.active span a::before{ opacity: 1; width: 100%;}
|
||||||
|
/*icon*/
|
||||||
|
.nav_btn{ width: 24px; float: right; position: relative; cursor: pointer; display: none;}
|
||||||
|
.nav_btn i{ display: block; width: 100%; height: 2px; float: left; background-color: #f54123; border-radius: 50px;
|
||||||
|
transition: all .5s ease 0s;
|
||||||
|
-webkit-transition: all .5s ease 0s;
|
||||||
|
-moz-transition: all .5s ease 0s;
|
||||||
|
}
|
||||||
|
.nav_btn i.bar-top{ margin-top: 0;}
|
||||||
|
.nav_btn i.bar-cen{ margin-top: 6px;}
|
||||||
|
.nav_btn i.bar-bom{ margin-top: 6px;}
|
||||||
|
.nav_btn.cur i.bar-cen{ opacity: 0;}
|
||||||
|
.nav_btn.cur i.bar-top{ -webkit-transform:rotate(45deg) translate(6px, 6px);transform:rotate(45deg) translate(6px, 6px);}
|
||||||
|
.nav_btn.cur i.bar-bom{ -webkit-transform: rotate(-45deg) translate(5.5px, -5px);transform: rotate(-45deg) translate(5.5px, -5px);}
|
||||||
|
/*隐藏*/
|
||||||
|
.overHide{ overflow: hidden;}
|
||||||
|
|
||||||
|
|
||||||
|
.all-center-box{ width: 100%; float: left; margin-top: 6.25rem;}
|
||||||
|
|
||||||
|
.head-box{ position: fixed; left: 0; top: 0; z-index: 99; background: #fff; transition: all .6s; padding-bottom: 1px; box-shadow: 0 0 10px rgba(0,0,0,0.1);}
|
||||||
|
.head-box .pull-left img{ height: 3.75rem;}
|
||||||
|
|
||||||
|
.head-two{ position: fixed; left: 0; top: 6.25rem; z-index: 98; background: rgba(0,0,0,0.4); display: none;}
|
||||||
|
.head-two ul{ display: flex;}
|
||||||
|
.head-two ul li{ width: 100%; float: left; text-align: center; padding: 1.875rem 10px;}
|
||||||
|
.head-two ul li i{ display: block; height: 8.125rem; overflow: hidden;}
|
||||||
|
.head-two ul li i img{ height: 100%; object-fit: cover;}
|
||||||
|
.head-two ul li p{ color: #fff; margin-top: 10px; font-size: 1rem; transition: all .6s;}
|
||||||
|
.head-two ul li:hover p{ color: #f54123;}
|
||||||
|
|
||||||
|
|
||||||
|
.banner-box{ height: auto;}
|
||||||
|
.banner-box .swiper-container{ height: 100%;}
|
||||||
|
.banner-box .swiper-container .swiper-slide{ background-position: center; background-size: cover; background-color: #ccc;}
|
||||||
|
.banner-box .swiper-container .swiper-slide .pull-left{ color: #fff;}
|
||||||
|
.banner-box .swiper-container .swiper-slide .pull-left p{ font-size: 4.375rem; transform: translate(3.125rem,0); opacity: 0; transition: all .6s;}
|
||||||
|
.banner-box .swiper-container .swiper-slide .pull-left i{ font-size: 1.25rem; line-height: 1.6; display: block; margin-top: 1.25rem; transform: translate(3.125rem,0); opacity: 0; transition: all .6s ease .1s;}
|
||||||
|
.banner-box .swiper-container .swiper-slide .w-1500.active .pull-left p{ opacity: 1; transform: translate(0,0);}
|
||||||
|
.banner-box .swiper-container .swiper-slide .w-1500.active .pull-left i{ opacity: 1; transform: translate(0,0);}
|
||||||
|
.banner-box .swiper-container .swiper-slide .w-1500.active .pull-left a{ opacity: 1; transform: translate(0,0);}
|
||||||
|
|
||||||
|
.banner-box .swiper-page{ width: 100%; position: absolute; left: 0; bottom: 4rem;}
|
||||||
|
.banner-box .swiper-container .swiper-pagination{ position: relative;}
|
||||||
|
.banner-box .swiper-container .swiper-pagination .swiper-pagination-bullet{ width: 0.75rem; height: 0.75rem; outline: none; margin: 0 0.3125rem; border-radius: 4px; background: #d8d8d8; transition: all .6s; opacity: 1;}
|
||||||
|
.banner-box .swiper-container .swiper-pagination .swiper-pagination-bullet.swiper-pagination-bullet-active{ width: 3.125rem; background: #f54123;}
|
||||||
|
|
||||||
|
.online{ position: fixed; left: 0; top: 50%; z-index: 99; margin-top: -3.125rem;}
|
||||||
|
.online img{ height: 5.0625rem; float: left;}
|
||||||
|
|
||||||
|
.home-box1 .top-box{ position: relative; overflow: hidden;}
|
||||||
|
.home-box1 .top-box::after{ content: ''; width: 40%; height: 100%; position: absolute; right: 0; bottom: 0; background: #0071ec;}
|
||||||
|
.home-box1 .top-box .pull-left{ width: 29%; line-height: 5.5rem; font-size: 1.25rem; color: #444; position: relative; z-index: 2;}
|
||||||
|
.home-box1 .top-box .pull-left span{ color: #f54123;}
|
||||||
|
.home-box1 .top-box .pull-right{ width: 71%; background: #0071ec; padding: 0 3.125rem; position: relative; z-index: 2;}
|
||||||
|
.home-box1 .top-box .pull-right .text{ width: 23.75rem; height: 5.5rem; float: left; background: none; border:none; font-size: 0.875rem; color: #fff;}
|
||||||
|
.home-box1 .top-box .pull-right .text::-webkit-input-placeholder{ color: rgba(255,255,255,0.8);}
|
||||||
|
.home-box1 .top-box .pull-right .btns{ width: 2.5rem; height: 5.5rem; float: left; background: url(../image/icon_1.png) no-repeat center; background-size: 1.25rem; border:none;}
|
||||||
|
.home-box1 .lower-box{ padding: 4.0625rem 0;}
|
||||||
|
.home-box1 .lower-box .pull-left{ width: 38%;}
|
||||||
|
.home-box1 .lower-box .pull-left .box1{ font-size: 1.875rem;}
|
||||||
|
.home-box1 .lower-box .pull-left .box2{ font-size: 14px; line-height: 1.5rem; color: #666; margin: 1.5625rem 0; text-align: justify;}
|
||||||
|
.home-box1 .lower-box .pull-right .center-center{ width: 20rem; height: 20rem; border: 1px solid #D5D5D5; float: left; border-radius: 100%; padding: 0 3.75rem;}
|
||||||
|
.home-box1 .lower-box .pull-right .center-center em img{ height: 32px;}
|
||||||
|
.home-box1 .lower-box .pull-right .center-center span{ font-size: 1.25rem; margin: 1rem 0 0;}
|
||||||
|
.home-box1 .lower-box .pull-right .center-center:nth-child(1) span{ font-size: 2.25rem;}
|
||||||
|
.home-box1 .lower-box .pull-right .center-center span i{ font-size: 3rem;}
|
||||||
|
.home-box1 .lower-box .pull-right .center-center p{ font-size: 12px; color: #888; text-align: center; height: 96px;}
|
||||||
|
|
||||||
|
.all-more{ border: 1px solid; padding: 0 0.75rem; line-height: 1.875rem; font-size: 12px; display: inline-block;}
|
||||||
|
.all-more i{ display: inline-block; padding-right: 1.875rem; background-position: right; background-repeat: no-repeat; background-size: 1rem;}
|
||||||
|
.all-more.orange{ color: #f54123;}
|
||||||
|
.all-more.orange i{ background-image: url(../image/icon_jt1.png);}
|
||||||
|
.all-more.white{ color: #fff;}
|
||||||
|
.all-more.white i{ background-image: url(../image/icon_jt2.png);}
|
||||||
|
.all-more.noBor{ color: #be0d27; padding: 0; border: none;}
|
||||||
|
.all-more.noBor i{ background-image: url(../image/icon_jt3.png); padding-right: 1.5625rem;}
|
||||||
|
|
||||||
|
.home-box2 ul li{ width: 25%; height: 600px; float: left; transition: all .6s; color: #fff; position: relative; overflow: hidden;}
|
||||||
|
.home-box2 ul li:nth-child(1){ background: #f54123;}
|
||||||
|
.home-box2 ul li:nth-child(2){ background: url(../image/ho2_bg2.jpg) no-repeat center; background-size: cover;}
|
||||||
|
.home-box2 ul li:nth-child(3){ background: url(../image/ho2_bg3.png) no-repeat right bottom #0071ec; background-size: 18.75rem;}
|
||||||
|
.home-box2 ul li .box-info1 .center-block{ width: 12.25rem;}
|
||||||
|
.home-box2 ul li .box-info2 .center-block{ width: 23.75rem;}
|
||||||
|
.home-box2 ul li .box-info1{ width: 100%; height: 100%; position: absolute; left: 0; top: 0; z-index: 2; font-size: 12px; padding: 0 3.25rem; transition: all .6s;}
|
||||||
|
.home-box2 ul li .box-info1 .box1{ text-align: center;}
|
||||||
|
.home-box2 ul li .box-info1 .box1 i img{ width: 2.5rem;}
|
||||||
|
.home-box2 ul li .box-info1 .box1 p{ margin-top: 0.75rem;}
|
||||||
|
.home-box2 ul li .box-info1 .box2{ padding: 30px 0;}
|
||||||
|
.home-box2 ul li .box-info1 .box3{ text-align: center;}
|
||||||
|
.home-box2 ul li .box-info1 .box3 img{ height: 2.125rem;}
|
||||||
|
.home-box2 ul li .box-info2{ width: 100%; height: 100%; position: absolute; left: 0; top: 0; z-index: 2; padding: 0 6.875rem; opacity: 0; transition: all .6s;}
|
||||||
|
.home-box2 ul li .box-info2 .box1 i{ font-size: 12px; display: block;}
|
||||||
|
.home-box2 ul li .box-info2 .box1 span{ display: block; font-size: 1.5rem; padding: 26px 0 15px;}
|
||||||
|
.home-box2 ul li .box-info2 .box1 p{ font-size: 0.875rem; text-align: justify;}
|
||||||
|
.home-box2 ul li .box-info2 .box2{ font-size: 0.875rem; margin: 29px 0 19px;}
|
||||||
|
.home-box2 ul li .box-info2 .box3 div{ float: left; text-align: center;}
|
||||||
|
.home-box2 ul li .box-info2 .box3 div+div{ margin-left: 3.75rem;}
|
||||||
|
.home-box2 ul li .box-info2 .box3 div i{ display: block; height: 28px;}
|
||||||
|
.home-box2 ul li .box-info2 .box3 div i img{ height: 28px;}
|
||||||
|
.home-box2 ul li .box-info2 .box3 div p{ display: block; font-size: 0.75rem; margin-top: 3px;}
|
||||||
|
.home-box2 ul li .box-info2 .box4{ margin-top: 28px;}
|
||||||
|
|
||||||
|
|
||||||
|
.home-box2 ul li.active{ width: 50%;}
|
||||||
|
.home-box2 ul li.active .box-info1{ opacity: 0;}
|
||||||
|
.home-box2 ul li.active .box-info2{ opacity: 1;}
|
||||||
|
|
||||||
|
.all-title1{}
|
||||||
|
.all-title1 .pull-left{ width: 23.75rem; border-top: 1px solid #be0d27; padding-top: 1.0625rem;}
|
||||||
|
.all-title1 .pull-left span{ font-size: 1.875rem; float: left; line-height: 2.5rem;}
|
||||||
|
.all-title1 .pull-left a{ width: 2.5rem; height: 2.5rem; float: right; background: url(../image/icon_jt2.png) no-repeat center #f54123; background-size: 1rem;}
|
||||||
|
|
||||||
|
|
||||||
|
.home-box3{ position: relative; padding: 4.0625rem 3.75rem 0 0;}
|
||||||
|
.home-box3::after{ content: ''; width: 75%; height: 94%; background: #F0F0F0; position: absolute; right: 0; top: 0;}
|
||||||
|
.home-box3 .center-block{ background: #fff; box-shadow: 0 0 10px rgba(0,0,0,0.2); position: relative; z-index: 2; padding: 0 3.125rem 0.9375rem 6.875rem;}
|
||||||
|
.home-box3 .center-block .box-info1{ width: 68%; float: left; margin-top: 1rem;}
|
||||||
|
.home-box3 .center-block .box-info1 ul li{ width: 100%; float: left; border-top: 1px solid #eee; padding: 1.75rem 0;}
|
||||||
|
.home-box3 .center-block .box-info1 ul li:first-child{ border:none;}
|
||||||
|
.home-box3 .center-block .imgs{ width: 33%; height: 7.8125rem; float: left; overflow: hidden;}
|
||||||
|
.home-box3 .center-block .imgs img{ width: 100%; height: 100%; float: left; object-fit: cover; transition: all .6s;}
|
||||||
|
.home-box3 .center-block .info{ width: 67%; float: left; padding-left: 3.0625rem;}
|
||||||
|
.home-box3 .center-block .info .box1 i{ display: block; font-size: 12px; color: #666; margin-top: 0.375rem;}
|
||||||
|
.home-box3 .center-block .info .box1 span{ display: block; font-size: 1rem; color: #262626; overflow: hidden; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 1;}
|
||||||
|
.home-box3 .center-block .info .box1 p{ font-size: 12px; color: #4c4c4c; overflow: hidden; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; margin: 0.75rem 0;}
|
||||||
|
.home-box3 .center-block .info .all-more{ line-height: 1.1;}
|
||||||
|
.home-box3 .center-block .box-info2{ width: 28%; float: right; margin-top: 2.75rem;}
|
||||||
|
.home-box3 .center-block .box-info2 .imgs{ width: 100%; height: 9.6875rem;}
|
||||||
|
.home-box3 .center-block .box-info2 .info{ width: 100%; padding: 1.75rem 0 0;}
|
||||||
|
.home-box3 .center-block .box-info1 ul li:hover .imgs img,.home-box3 .center-block .box-info2:hover .imgs img{ transform: scale(1.1);}
|
||||||
|
|
||||||
|
.home-box4 .top-box{ padding: 2.5rem 6.875rem;}
|
||||||
|
.home-box4 .lower-box{ background: #34312C; color: #fff; position: relative; overflow: hidden;}
|
||||||
|
.home-box4 .lower-box .pull-left{ width: 78%; height: 28.125rem; background: url(../image/ho4_bg.jpg) no-repeat center; padding: 6.875rem 6.875rem 0;}
|
||||||
|
.home-box4 .lower-box .pull-left .center-block{ padding-right: 42%; display: none;}
|
||||||
|
.home-box4 .lower-box .pull-left .center-block .box1{ font-size: 1.5rem; font-weight: bold;}
|
||||||
|
.home-box4 .lower-box .pull-left .center-block .box2{ font-size: 0.75rem; margin: 0.9375rem 0; text-align: justify; min-height: 12.5rem;}
|
||||||
|
.home-box4 .lower-box .pull-right{ width: 22%; height: 100%; position: absolute; right: 0; top: 0;}
|
||||||
|
.home-box4 .lower-box .pull-right ul{ width: 100%;}
|
||||||
|
.home-box4 .lower-box .pull-right ul li{ width: 100%; float: left;}
|
||||||
|
.home-box4 .lower-box .pull-right ul li a{ width: 100%; float: left; line-height: 2.5rem; padding: 0 1.5625rem; color: #fff; font-size: 0.875rem; border-left: 2px solid #fff;}
|
||||||
|
.home-box4 .lower-box .pull-right ul li a:hover,.home-box4 .lower-box .pull-right ul li.active a{ color: #f54123; border-color: #f54123;}
|
||||||
|
|
||||||
|
.home-box4 .lower-box .swiper-pagination-bullet{ background: rgba(255,255,255,0.5); opacity: 1;}
|
||||||
|
.home-box4 .lower-box .swiper-pagination-bullet-active{ background: #f54123;}
|
||||||
|
.home-box4 .lower-box .swiper-pagination{ bottom: 0;}
|
||||||
|
|
||||||
|
.home-box5 .center-block{ background: url(../image/ho5_bg.png) no-repeat center; background-size: cover; height: 36.25rem; padding: 2.5rem 6.875rem;}
|
||||||
|
.home-box5 .center-block .box-info{ width: 230px; background: #fff; float: left; border-radius: 5px; box-shadow: 0 0 0.625rem rgba(0,0,0,0.1); position: relative; margin: 72px 0 0 280px;}
|
||||||
|
.home-box5 .center-block .box-info .info{ padding: 1.375rem 1rem 3.125rem;}
|
||||||
|
.home-box5 .center-block .box-info .info span{ font-size: 0.875rem; color: #f54123;}
|
||||||
|
.home-box5 .center-block .box-info .info p{ font-size: 12px; color: #7f7f7f; background-position: 0 3px; background-repeat: no-repeat; padding-left: 22px; margin-top: 10px;}
|
||||||
|
.home-box5 .center-block .box-info .info p.icon1{ background-image: url(../image/icon_4.png);}
|
||||||
|
.home-box5 .center-block .box-info .info p.icon2{ background-image: url(../image/icon_5.png);}
|
||||||
|
.home-box5 .center-block .box-info::before{ content: ''; width: 14px; height: 14px; background: url(../image/icon_3.png) no-repeat center; background-size: 100%; position: absolute; left: -44px; top: 50%; margin-top: -7px;}
|
||||||
|
.home-box5 .center-block .box-info::after{ content: ''; width: 0; height: 0; border-top: 6px solid transparent; border-bottom: 6px solid transparent; border-right: 6px solid #fff; position: absolute; right: 100%; top: 50%; z-index: 2; margin-top: -6px;}
|
||||||
|
|
||||||
|
.home-box6{ background: #0071ec;}
|
||||||
|
|
||||||
|
.foot-box{ background: #111; color: #fff;}
|
||||||
|
.foot-box .top-box{ display: flex; padding: 1.875rem 2.5rem 3.125rem; letter-spacing: 2px;}
|
||||||
|
.foot-box .top-box ul{ float: left; font-size: 12px;}
|
||||||
|
.foot-box .top-box ul+ul{ margin-left: 3.125rem;}
|
||||||
|
.foot-box .top-box ul span{ display: block; font-size: 14px; white-space: nowrap;}
|
||||||
|
.foot-box .top-box ul li{ display: block; color: #999; margin-top: 1rem;}
|
||||||
|
.foot-box .top-box ul li img{ width: 70px;}
|
||||||
|
.foot-box .top-box ul li a{ color: #999;}
|
||||||
|
.foot-box .top-box ul li a:hover{ color: #fff;}
|
||||||
|
.foot-box .top-box ul:last-child li{ white-space: nowrap;}
|
||||||
|
.foot-box .lower-box{ padding: 24px 2.5rem; font-size: 14px;}
|
||||||
|
|
||||||
|
.all-title2{ text-align: center;}
|
||||||
|
.all-title2 span{ display: block; font-size: 2.5rem;}
|
||||||
|
.all-title2 p{ font-size: 12px; color: #999; display: inline-block; padding: 0 6.25rem; position: relative;}
|
||||||
|
.all-title2 p i{ display: inline-block; position: relative; z-index: 2; padding: 0 0.375rem; background: #fff;}
|
||||||
|
.all-title2 p::after{ content: ''; width: 100%; height: 1px; background: #999; position: absolute; left: 0; top: 50%;}
|
||||||
|
|
||||||
|
.about-box1{ padding: 2.5rem 0;}
|
||||||
|
.about-box1:nth-child(2){ padding-top: 5rem;}
|
||||||
|
.about-box1 .box-info{ padding-top: 3.75rem;}
|
||||||
|
.about-box1 .box-info .pull-left{ width: 48.4%; position: relative; padding-left: 9%;}
|
||||||
|
.about-box1 .box-info .pull-left::after{ content: ''; width: 100%; height: 48%; background: #f0f0f0; position: absolute; left: 0; bottom: 0;}
|
||||||
|
.about-box1 .box-info .pull-left img{ width: 100%; float: left; position: relative; z-index: 2;}
|
||||||
|
.about-box1 .box-info .pull-right{ width: 51.6%; padding-left: 3.25rem;}
|
||||||
|
.about-box1 .box-info .pull-right .box1{ font-size: 1.875rem;}
|
||||||
|
.about-box1 .box-info .pull-right .box2{ height: 350px; overflow: auto; font-size: 14px; line-height: 24px; margin-top: 1.875rem; text-align: justify; padding-right: 1.5rem;}
|
||||||
|
.about-box1 .box-info .pull-right .box2::-webkit-scrollbar{ width: 5px; background: #fff;}
|
||||||
|
.about-box1 .box-info .pull-right .box2::-webkit-scrollbar-thumb{ background: #eee;}
|
||||||
|
.about-box1 .box-info .pull-right .box2::-webkit-scrollbar-button:hover{ background-color: #ddd !important;}
|
||||||
|
.about-box1 .box-info .pull-right .box2::-webkit-scrollbar-button:active{ background-color: #d2d2d2 !important;}
|
||||||
|
|
||||||
|
.about-box1 .list-box1,.about-box1 .list-box2{ margin-top: 2rem;}
|
||||||
|
|
||||||
|
.list-box1 ul li{ width: 49.2%; float: left; margin-top: 2.1875rem; text-align: center; background: #fff; box-shadow: 0 0 10px rgba(0,0,0,0.2);}
|
||||||
|
.list-box1 ul li:nth-child(2n){ float: right;}
|
||||||
|
.list-box1 ul li span{ width: 100%; float: left; height: 16.1875rem; overflow: hidden;}
|
||||||
|
.list-box1 ul li span img{ width: 100%; height: 100%; object-fit: cover; transition: all .6s;}
|
||||||
|
.list-box1 ul li p{ width: 100%; float: left; line-height: 40px; font-size: 1rem;}
|
||||||
|
.list-box1 ul li:hover span img{ transform: scale(1.1);}
|
||||||
|
|
||||||
|
.list-box2 ul{ margin: 0 -0.75rem;}
|
||||||
|
.list-box2 ul li{ width: 33.33%; float: left; padding: 0 0.75rem; margin-top: 1.25rem;}
|
||||||
|
.list-box2 ul li a{ width: 100%; float: left; background: #fff; box-shadow: 0 0 10px rgba(0,0,0,0.2); text-align: center;}
|
||||||
|
.list-box2 ul li a span{ width: 100%; float: left; height: 19.6875rem; overflow: hidden;}
|
||||||
|
.list-box2 ul li a span img{ width: 100%; height: 100%; float: left; object-fit: cover; transition: all .6s;}
|
||||||
|
.list-box2 ul li a p{ width: 100%; height: 6.5625rem; float: left; display: flex; align-items: center; justify-content: center; padding: 0 1rem; font-size: 1rem;}
|
||||||
|
.list-box2 ul li a:hover{ background: #0071ec; color: rgba(255,255,255,0.85);}
|
||||||
|
.list-box2 ul li a:hover span img{ transform: scale(1.1);}
|
||||||
|
|
||||||
|
.page-menu{ margin-top: 3.125rem;}
|
||||||
|
.page-menu a{ line-height: 3rem; font-size: 1rem; min-width: 9.375rem; border: 1px solid #979797; text-align: center;}
|
||||||
|
.page-menu a+a{ border-left-width: 0;}
|
||||||
|
.page-menu a:hover,.page-menu a.active{ background: #0071ec; color: #fff;}
|
||||||
|
|
||||||
|
.product-box1{ padding: 5rem 0;}
|
||||||
|
.product-box1 .center-block{ margin-top: 2.5rem;}
|
||||||
|
.product-box1 .center-block ul{ margin: 0 -0.625rem;}
|
||||||
|
.product-box1 .center-block ul li{ width: 25%; float: left; padding: 0 0.625rem; margin-top: 1.25rem;}
|
||||||
|
.product-box1 .center-block ul li a{ width: 100%; float: left; position: relative; overflow: hidden; box-shadow: 0 0 10px rgba(0,0,0,0.1); background: #fff;}
|
||||||
|
.product-box1 .center-block ul li a .box-info1 .box1{ height: 12.5rem; overflow: hidden;}
|
||||||
|
.product-box1 .center-block ul li a .box-info1 .box1 img{ width: 100%; height: 100%; float: left; object-fit: cover;}
|
||||||
|
.product-box1 .center-block ul li a .box-info1 .box2{ padding: 0.875rem 0.875rem 0.9rem;}
|
||||||
|
.product-box1 .center-block ul li a .box-info1 .box2 span{ display: block; font-size: 1rem; overflow: hidden; white-space: nowrap; text-overflow: ellipsis;}
|
||||||
|
.product-box1 .center-block ul li a .box-info1 .box2 p{ font-size: 12px; height: 32px; overflow: hidden; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; margin-top: 0.625rem;}
|
||||||
|
.product-box1 .center-block ul li a .box-info2{ width: 100%; height: 100%; position: absolute; left: 0; top: 0; background: rgba(0,113,236,0.8); color: #fff; padding: 0 14px; opacity: 0; transition: all .6s;}
|
||||||
|
.product-box1 .center-block ul li a .box-info2 span{ width: 100%; font-size: 1rem;}
|
||||||
|
.product-box1 .center-block ul li a .box-info2 p{ font-size: 12px; margin-top: 0.8rem;}
|
||||||
|
.product-box1 .center-block ul li a:hover .box-info2{ opacity: 1;}
|
||||||
|
|
||||||
|
.pager{ margin: 5rem 0 0;}
|
||||||
|
.pager li>a,.pager li>span{ border-radius: 2px !important; margin: 0 0.3125rem; padding: 0.35rem 0.65rem; color: #333; font-size: 12px;}
|
||||||
|
.pagination>.active>span{ background: #578DF3;}
|
||||||
|
.pagination>li:last-child>a, .pagination>li:last-child>span{ margin-right: 0;}
|
||||||
|
|
||||||
|
.page-info{ padding: 3.125rem 0;}
|
||||||
|
.page-info .box1{ font-size: 2.25rem; font-weight: bold;}
|
||||||
|
.page-info .box2{ margin-top: 1.875rem; font-size: 12px; color: #333;}
|
||||||
|
.page-info .box3{ font-size: 14px; margin-top: 1.875rem; line-height: 1.6;}
|
||||||
|
|
||||||
|
.service-box1{ padding: 5rem 0 3.75rem;}
|
||||||
|
.service-box1 .box-info{ margin-top: 1.25rem;}
|
||||||
|
.service-box1 .box-info ul{ margin: 0 -0.625rem;}
|
||||||
|
.service-box1 .box-info ul li{ float: left; padding: 0.625rem; position: relative;}
|
||||||
|
.service-box1 .box-info ul li img{ width: 100%; height: 100%; float: left; object-fit: cover; transition: all .6s;}
|
||||||
|
.service-box1 .box-info ul li a{ width: 100%; height: 100%; float: left; position: relative; overflow: hidden;}
|
||||||
|
.service-box1 .box-info ul li .center-block{ position: absolute; left: 2.25rem; bottom: 2.5rem; color: #fff;}
|
||||||
|
.service-box1 .box-info ul li .center-block strong{ display: block; font-size: 1.5rem; font-weight: bold;}
|
||||||
|
.service-box1 .box-info ul li .center-block p{ font-size: 0.875rem; margin: 0.875rem 0;}
|
||||||
|
.service-box1 .box-info ul li:hover img{ transform: scale(1.1);}
|
||||||
|
.service-box1 .box-info .pull-left{ width: 43.5%;}
|
||||||
|
.service-box1 .box-info .pull-right{ width: 56.5%; padding-left: 1.25rem;}
|
||||||
|
.service-box1 .box-info .pull-left ul li{ width: 100%;}
|
||||||
|
.service-box1 .box-info .pull-left ul li:nth-child(1){ height: 17.5rem;}
|
||||||
|
.service-box1 .box-info .pull-left ul li:nth-child(2){ height: 22.5rem;}
|
||||||
|
.service-box1 .box-info .pull-right ul li:nth-child(1){ width: 100%; height: 25.625rem;}
|
||||||
|
.service-box1 .box-info .pull-right ul li:nth-child(1) .center-block{ left: 3.6875rem; bottom: 50%; margin-bottom: -3.125rem;}
|
||||||
|
.service-box1 .box-info .pull-right ul li:nth-child(2){ width: 50%; height: 14.375rem;}
|
||||||
|
.service-box1 .box-info .pull-right ul li:nth-child(2) a{ background: #f54123;}
|
||||||
|
.service-box1 .box-info .pull-right ul li:nth-child(3){ width: 50%; height: 14.375rem;}
|
||||||
|
.service-box1 .box-info .pull-right ul li:nth-child(3) a{ background: #0071ec;}
|
||||||
|
|
||||||
|
.service-box2 .box-info{ padding: 3.4375rem 0 6.25rem;}
|
||||||
|
.service-box2 .box-info ul{ margin: 0 -0.625rem;}
|
||||||
|
.service-box2 .box-info ul li{ width: 16.66%; float: left; padding: 0 0.625rem; margin-top: 1.25rem;}
|
||||||
|
.service-box2 .box-info ul li a{ width: 100%; height: 13.4375rem; float: left; background: #fff; box-shadow: 0 0 10px rgba(0,0,0,0.2); text-align: center; padding: 1.875rem 0 0;}
|
||||||
|
.service-box2 .box-info ul li a i{ display: block;}
|
||||||
|
.service-box2 .box-info ul li a i img{ height: 5.8125rem;}
|
||||||
|
.service-box2 .box-info ul li a span{ display: block; font-size: 1.5rem;}
|
||||||
|
.service-box2 .box-info ul li a p{ font-size: 12px; margin-top: 6px;}
|
||||||
|
.service-box2 .box-info ul li a:hover{ background: #4C85F9; color: #fff;}
|
||||||
|
|
||||||
|
.contact-box{ padding: 5rem 0 0;}
|
||||||
|
.contact-box .top-box{ padding: 1.5625rem 0 2.8125rem;}
|
||||||
|
.contact-box .top-box ul{ margin: 0 -0.75rem;}
|
||||||
|
.contact-box .top-box ul li{ width: 33.33%; float: left; padding: 0 0.75rem; margin-top: 1.25rem;}
|
||||||
|
.contact-box .top-box ul li .between-center{ width: 100%; height: 6.25rem; float: left; background: #fff; box-shadow: 0 0 10px rgba(0,0,0,0.1); padding: 0 1rem 0 1.875rem; position: relative;}
|
||||||
|
.contact-box .top-box ul li .between-center div{ width: 82%;}
|
||||||
|
.contact-box .top-box ul li .between-center div span{ font-size: 1.125rem;}
|
||||||
|
.contact-box .top-box ul li .between-center div p{ font-size: 0.875rem; margin-top: 0.5rem;}
|
||||||
|
.contact-box .top-box ul li .between-center .ewm{ width: 4.625rem; height: 4.625rem; position: absolute; right: 3.4375rem; top: 50%; margin-top: -2.3125rem;}
|
||||||
|
.contact-box .lower-box{ height: 47.5rem; background: #F2F1ED;}
|
||||||
|
.contact-box .lower-box img,.contact-box .lower-box label{ max-width: initial;}
|
||||||
|
|
||||||
|
.contact-map{ width: 230px; height: 255px; background: #fff; float: left; border-radius: 5px; box-shadow: 0 0 0.625rem rgba(0,0,0,0.1); position: relative; padding: 18px 0 0;}
|
||||||
|
.contact-map .imgs{ height: 132px; overflow: hidden;}
|
||||||
|
.contact-map .imgs img{ width: 100%; height: 100%; object-fit: cover;}
|
||||||
|
.contact-map .info{ padding:10px 0 0;}
|
||||||
|
.contact-map .info span{ font-size: 14px; color: #f54123;}
|
||||||
|
.contact-map .info p{ font-size: 12px; color: #7f7f7f; background-position: 0 3px; background-repeat: no-repeat; padding-left: 22px; margin-top: 10px;}
|
||||||
|
.contact-map .info p.icon1{ background-image: url(../image/icon_4.png);}
|
||||||
|
.contact-map .info p.icon2{ background-image: url(../image/icon_5.png);}
|
||||||
|
|
||||||
|
.xmcx_box .top-box{ background: #317dff; padding: 25px 20px 95px; text-align: center;}
|
||||||
|
.xmcx_box .lower-box{ position: relative; z-index: 2; padding: 0 30px; margin-top: -75px;}
|
||||||
|
.xmcx_box .lower-box .center-block{ background: #fff; border-radius: 10px; box-shadow: 0 5px 10px rgba(231,239,253,0.5); padding: 0 30px 30px; position: relative;}
|
||||||
|
.xmcx_box .lower-box .center-block p{ font-size: 20px; font-weight: bold; margin-top: 24px;}
|
||||||
|
.xmcx_box .lower-box .center-block input{ font-size: 14px; width: 100%; height: 20px; border: none; background: none; margin-top: 6px;}
|
||||||
|
.xmcx_box .lower-box .btns{ width: 100%; height: 45px; background: #317DFF; color: #fff; font-size: 20px; border-radius: 50px; margin: 50px 0 0; border:none;}
|
||||||
|
|
||||||
|
.xmjd-box .top-box{ background: #317dff; text-align: center; padding: 60px 30px 20px;}
|
||||||
|
.xmjd-box .lower-box{ padding: 5px 30px 30px;}
|
||||||
|
.xmjd-box .lower-box .box1{ font-size: 20px; font-weight: bold; margin-top: 17px;}
|
||||||
|
.xmjd-box .lower-box .box2{ font-size: 14px; color: #999; margin-top: 6px;}
|
||||||
|
.xmjd-box .lower-box .box3 ul{ margin: 0 -8px;}
|
||||||
|
.xmjd-box .lower-box .box3 ul li{ width: 33.33%; float: left; margin-top: 0.9375rem; text-align: center; padding: 0 8px;}
|
||||||
|
.xmjd-box .lower-box .box3 ul li span{ width: 100%; height: 120px; float: left; background: #EAF2FF; overflow: hidden;}
|
||||||
|
.xmjd-box .lower-box .box3 ul li p{ width: 100%; float: left; font-size: 14px; margin-top: 10px;}
|
||||||
|
.xmjd-box .lower-box .box3.style2 ul li span{ height: 80px;}
|
||||||
|
.xmjd-box .lower-box .box3.style2 ul li span img{ width: 100%; height: 100%; object-fit: cover;}
|
||||||
|
.xmjd-box .lower-box .box4{ background: #f7faff; padding: 15px; border-radius: 10px; margin-top: 15px; font-size: 14px;}
|
||||||
|
.xmjd-box .lower-box .box4 span{ display: block; color: #95A6C1;}
|
||||||
|
.xmjd-box .lower-box .box4 p{ margin-top: 6px; text-align: justify;}
|
||||||
|
|
||||||
|
.news-list{ padding: 5rem 0;}
|
||||||
|
.news-list .top-box{ padding: 2.1875rem 0;}
|
||||||
|
.news-list .top-box ul{ margin: 0 -0.6875rem;}
|
||||||
|
.news-list .top-box ul li{ width: 33.33%; float: left; padding: 0 0.6875rem; margin-top: 1.375rem;}
|
||||||
|
.news-list .top-box ul li a{ width: 100%; float: left; height: 16.875rem; position: relative; overflow: hidden; box-shadow: 0 0 10px rgba(0,0,0,0.2);}
|
||||||
|
.news-list .top-box ul li a img{ width: 100%; height: 100%; float: left; object-fit: cover; transition: all .6s;}
|
||||||
|
.news-list .top-box ul li a div{ width: 100%; position: absolute; left: 0; bottom: 0; color: #fff; background: rgba(0,0,0,0.2); padding: 0.9375rem; font-size: 12px;}
|
||||||
|
.news-list .top-box ul li a div span{ display: block; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; font-size: 1rem; margin-bottom: 0.375rem;}
|
||||||
|
.news-list .top-box ul li a:hover img{ transform: scale(1.1);}
|
||||||
|
.news-list .lower-box ul li{ width: 100%; float: left; border-bottom: 1px solid #EAEAEA; padding: 3rem 0;}
|
||||||
|
.news-list .lower-box ul li a{ width: 100%; float: left;}
|
||||||
|
.news-list .lower-box ul li .pull-left{ width: 33%; height: 14.6875rem; overflow: hidden;}
|
||||||
|
.news-list .lower-box ul li .pull-left img{ width: 100%; height: 100%; float: left; object-fit: cover; transition: all .6s;}
|
||||||
|
.news-list .lower-box ul li .pull-right{ width: 67%; padding:0 5.625rem 0 2.125rem;}
|
||||||
|
.news-list .lower-box ul li .pull-right span{ display: block; font-size: 1rem; font-weight: bold; margin-top: 0.3125rem;}
|
||||||
|
.news-list .lower-box ul li .pull-right p{ font-size: 12px; line-height: 1.5rem; overflow: hidden; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 5; height: 7.5rem; margin: 0.9375rem 0 1.875rem; color: #222;}
|
||||||
|
.news-list .lower-box ul li .pull-right i{ font-size: 12px; color: #222;}
|
||||||
|
.news-list .lower-box ul li:hover .pull-left img{ transform: scale(1.1);}
|
||||||
|
|
||||||
|
|
||||||
|
.page-search{}
|
||||||
|
.page-search .between-center{ width: 500px;}
|
||||||
|
.page-search .between-center .layui-input{ width: 80%; font-size: 1rem; line-height: 3.125rem; height: 3.125rem;}
|
||||||
|
.page-search .between-center .layui-btn{ width: 20%; font-size: 1rem; margin-left: 10px; line-height: 3.125rem; height: 3.125rem;}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* 小于等于多少高度的样式 */
|
||||||
|
@media screen and (max-height:880px){
|
||||||
|
}
|
||||||
|
@media screen and (max-height:600px){
|
||||||
|
}
|
||||||
|
/* 小于等于多少宽度的样式 */
|
||||||
|
@media screen and (max-width:1660px){
|
||||||
|
html,body{ font-size: 94%;}
|
||||||
|
.w-1500{ width: 94%;}
|
||||||
|
.home-box5 .center-block .box-info{ margin: 62px 0 0 265px;}
|
||||||
|
}
|
||||||
|
@media screen and (max-width:1440px){
|
||||||
|
html,body{ font-size: 80%;}
|
||||||
|
.w-1500{ width: 1200px;}
|
||||||
|
.home-box1 .lower-box .pull-right .center-center{ width: 22rem; height: 22rem;}
|
||||||
|
.home-box5 .center-block .box-info{ margin: 37px 0 0 230px;}
|
||||||
|
.home-box4 .lower-box .pull-left{ padding-top: 5rem;}
|
||||||
|
.home-box4 .lower-box .pull-left .center-block{ padding-right: 30%;}
|
||||||
|
}
|
||||||
|
@media screen and (max-width:1366px){
|
||||||
|
}
|
||||||
|
@media screen and (max-width:1200px){
|
||||||
|
.w-1200{ width: 94%;}
|
||||||
|
.w-1500{ width: 94%;}
|
||||||
|
}
|
||||||
|
@media screen and (max-width:1100px){
|
||||||
|
|
||||||
|
}
|
||||||
|
@media screen and (max-width:1024px){
|
||||||
|
html,body{ font-size: 70%;}
|
||||||
|
.div-pc{ display: none;}
|
||||||
|
.div-phone{ display: block;}
|
||||||
|
/*nav*/
|
||||||
|
.nav_btn{ display: block;}
|
||||||
|
.nav_btn.cur i{ background: #f54123;}
|
||||||
|
.nav{ width: 100%; position: absolute; right: 0; top: 0; background: rgba(255,255,255,0.9); padding: 10vh 0 10px; height: 100vh; transition: all .6s; transform: translate(100%,0); display: block;}
|
||||||
|
.nav ul li{ width: 100%; margin-left: 0;}
|
||||||
|
.nav ul li span{ width: 100%; float: left; text-align: center;}
|
||||||
|
.nav ul li span a{ display: inline-block; line-height: 35px; float: none; margin: auto; font-size: 14px; padding: 0; color: #333;}
|
||||||
|
.nav ul li span a::before{ display: none;}
|
||||||
|
.nav ul li span.active a::after{ content: ''; width: 13px; height: 97%; background: url(../image/icon_jt5.png) no-repeat center; background-size: 100%; position: absolute; right: -20px; top: 1px; pointer-events: none;}
|
||||||
|
.nav ul li span.active:hover a::after,.nav ul li.active span.active a::after{ background-image: url(../image/icon_jt5_h.png);}
|
||||||
|
.nav ul li .nav-second{ position: relative; top: 0; width: 100%; overflow: initial; display: block; float: left; background: none;}
|
||||||
|
.nav ul li .nav-second a{ min-width: 100%; margin: 0; font-size: 12px;}
|
||||||
|
.nav ul li:hover span a{ color: #f54123 !important;}
|
||||||
|
.nav ul li:hover span a::after{}
|
||||||
|
.nav ul li:hover .nav-second a{ height: 2.0625rem; line-height: 2.0625rem;}
|
||||||
|
.nav ul li:hover .nav-second{ padding: 5px 10px;}
|
||||||
|
.nav.active{ transform: translate(0,0);}
|
||||||
|
/*nav end*/
|
||||||
|
|
||||||
|
.head-box{ padding: 10px 0; position: fixed;}
|
||||||
|
.head-box .pull-left img{ height: 40px;}
|
||||||
|
|
||||||
|
.all-center-box{ margin-top: 60px;}
|
||||||
|
.online{ top: 25vh; margin-top: 0;}
|
||||||
|
.online img{ height: 3rem;}
|
||||||
|
.banner-box .swiper-container .swiper-slide .w-1500 .pull-left p{ font-size: 1.5rem;}
|
||||||
|
.banner-box .swiper-container .swiper-slide .w-1500 .pull-left i{ font-size: 0.75rem; line-height: 1.4; margin-top: 0.9375rem;}
|
||||||
|
.banner-box .swiper-page{ bottom: 1rem;}
|
||||||
|
.home-box1 .top-box .pull-left{ width: 100%; text-align: center; line-height: 4rem;}
|
||||||
|
.home-box1 .top-box::after{ width: 100%; height: 3.5rem; display: none;}
|
||||||
|
.home-box1 .top-box .pull-right{ width: 100%; padding: 0;}
|
||||||
|
.home-box1 .top-box .pull-right .text{ width: 85%; height: 3.5rem; padding-left: 6%;}
|
||||||
|
.home-box1 .top-box .pull-right .btns{ width: 15%; height: 3.5rem;}
|
||||||
|
.home-box1 .lower-box{ padding: 1.5rem 0 0;}
|
||||||
|
.home-box1 .lower-box .w-1200{ display: block;}
|
||||||
|
.home-box1 .lower-box .pull-left{ width: 100%;}
|
||||||
|
.home-box1 .lower-box .pull-left .box2{ margin: 1rem 0;}
|
||||||
|
.home-box1 .lower-box .pull-right{ width: 100%; margin-top: 0.5rem;}
|
||||||
|
.home-box1 .lower-box .pull-right .center-center{ width: 100%; height: auto; border-radius: 0; padding: 2rem; margin-top: 1rem;}
|
||||||
|
.home-box1 .lower-box .pull-right .center-center p{ height: auto;}
|
||||||
|
.home-box1 .lower-box .pull-right .center-center span{ margin: 1rem 0;}
|
||||||
|
|
||||||
|
.home-box2 ul li{ width: 100% !important; height: auto; margin-top: 1.5rem;}
|
||||||
|
.home-box2 ul li .box-info1{ display: none;}
|
||||||
|
.home-box2 ul li .box-info2{ position: relative; padding: 2rem 1.5rem; opacity: 1;}
|
||||||
|
.home-box2 ul li .box-info2 .box1 span{ padding: 16px 0 10px;}
|
||||||
|
.home-box2 ul li .box-info2 .box2{ margin: 16px 0 10px;}
|
||||||
|
.home-box2 ul li .box-info2 .box4{ margin-top: 18px;}
|
||||||
|
.home-box2 ul li .box-info1 .center-block{ width: 100%;}
|
||||||
|
.home-box2 ul li .box-info2 .center-block{ width: 100%;}
|
||||||
|
|
||||||
|
.home-box3{ padding: 1.5rem 1.5rem 0 0;}
|
||||||
|
.home-box3::after{ height: 96%;}
|
||||||
|
.home-box3 .center-block{ width: 100%; padding: 0 1.5rem 1rem;}
|
||||||
|
.home-box3 .center-block .box-info1,.home-box3 .center-block .box-info2{ width: 100%;}
|
||||||
|
.home-box3 .center-block .box-info1 ul li{ padding: 1rem 0;}
|
||||||
|
.home-box3 .center-block .imgs{ width: 35%; height: 9rem;}
|
||||||
|
.home-box3 .center-block .info{ width: 65%; padding-left: 1rem;}
|
||||||
|
.home-box3 .center-block .info .box1 i{ margin-top: 0.2rem;}
|
||||||
|
.home-box3 .center-block .box-info2{ margin: 0.5rem 0;}
|
||||||
|
.home-box3 .center-block .box-info2 .imgs{ height: 16rem;}
|
||||||
|
.home-box3 .center-block .box-info2 .info{ padding: 1rem 0 0;}
|
||||||
|
|
||||||
|
.all-title1 .pull-left{ width: 20rem;}
|
||||||
|
.all-title1 .pull-left span{ font-size: 1.7rem;}
|
||||||
|
|
||||||
|
.home-box4 .top-box{ padding: 2rem 1.5rem;}
|
||||||
|
.home-box4 .lower-box .pull-left{ width: 100%; padding: 1.5rem; height: auto;}
|
||||||
|
.home-box4 .lower-box .pull-left .center-block{ display: block !important; padding: 0;}
|
||||||
|
|
||||||
|
.home-box5 .center-block{ padding: 2rem 1.5rem 1.5rem; height: auto;}
|
||||||
|
.home-box5 .center-block .box-info{ margin: 1rem 0 0;}
|
||||||
|
|
||||||
|
.foot-box .top-box{ display: none;}
|
||||||
|
.foot-box .lower-box{ font-size: 12px; padding: 12px 0; text-align: center;}
|
||||||
|
|
||||||
|
.about-box1{ padding: 1rem 0;}
|
||||||
|
.about-box1:nth-child(2){ padding-top: 2rem;}
|
||||||
|
.about-box1 .box-info{ padding: 0;}
|
||||||
|
.about-box1 .box-info .pull-left{ width: 100%; padding: 0; height: 250px; overflow: hidden; margin-top: 1rem;}
|
||||||
|
.about-box1 .box-info .pull-right{ width: 100%; padding: 0; margin-top: 1.5rem;}
|
||||||
|
.about-box1 .box-info .pull-right .box2{ height: 200px; margin-top: 0.5rem;}
|
||||||
|
|
||||||
|
.list-box1 ul li{ width: 100%; margin-top: 1rem;}
|
||||||
|
.list-box1 ul li span{ height: 14rem;}
|
||||||
|
|
||||||
|
.about-box1 .list-box1,.about-box1 .list-box2{ margin-top: 1rem;}
|
||||||
|
|
||||||
|
.list-box2 ul li{ width: 100%;}
|
||||||
|
.list-box2 ul li a span{ height: 26rem;}
|
||||||
|
|
||||||
|
.product-box1{ padding: 2rem 0;}
|
||||||
|
.page-menu{ margin-top: 2rem; padding-left: 5px;}
|
||||||
|
.page-menu .between-center{ display: block; width: 100%;}
|
||||||
|
.page-menu a{ min-width: 25%; float: left; margin-top: -1px; margin-left: -1px; }
|
||||||
|
.page-menu a+a{ border-left-width: 1px;}
|
||||||
|
.product-box1 .center-block{ margin-top: 1rem;}
|
||||||
|
.product-box1 .center-block ul li{ width: 50%;}
|
||||||
|
.pager{ margin-top: 2rem;}
|
||||||
|
|
||||||
|
.page-info{ padding: 2rem 0;}
|
||||||
|
.page-info .box1{ font-size: 1.875rem;}
|
||||||
|
.page-info .box2,.page-info .box3{ margin-top: 1rem;}
|
||||||
|
|
||||||
|
.service-box1{ padding: 2rem 0;}
|
||||||
|
.service-box1 .box-info .pull-left,.service-box1 .box-info .pull-right{ width: 100%; padding: 0;}
|
||||||
|
.service-box1 .box-info ul li{ width: 100% !important; height: 18rem !important;}
|
||||||
|
.service-box1 .box-info ul li .center-block{ left: 1.5rem !important; bottom: 1.5rem !important; margin: auto !important;}
|
||||||
|
.service-box1 .box-info .pull-right ul li:nth-child(2),.service-box1 .box-info .pull-right ul li:nth-child(3){ width: 50% !important; height: 12rem !important;}
|
||||||
|
|
||||||
|
.service-box2 .box-info{ padding: 1rem 0 3rem;}
|
||||||
|
.service-box2 .box-info ul li{ width: 50%;}
|
||||||
|
.service-box2 .box-info ul li a{ padding-top: 1.5rem;}
|
||||||
|
|
||||||
|
.contact-box{ padding: 2rem 0 0;}
|
||||||
|
.contact-box .top-box{ padding: 0.5rem 0 2rem;}
|
||||||
|
.contact-box .top-box ul{ margin: auto;}
|
||||||
|
.contact-box .top-box ul li{ width: 100%; padding: 0;}
|
||||||
|
|
||||||
|
.contact-box .lower-box{ height: 370px;}
|
||||||
|
|
||||||
|
.all-title2 span{ font-size: 2rem;}
|
||||||
|
.all-title2 p{ margin-top: 0.2rem;}
|
||||||
|
|
||||||
|
.news-list{ padding: 2rem 0;}
|
||||||
|
.news-list .top-box{ padding: 1rem 0 0;}
|
||||||
|
.news-list .top-box ul{ margin: 0;}
|
||||||
|
.news-list .top-box ul li{ width: 100%; padding: 0; margin-top: 1rem;}
|
||||||
|
.news-list .top-box ul li a{ height: 20rem;}
|
||||||
|
.news-list .lower-box{ margin-top: 1rem;}
|
||||||
|
.news-list .lower-box ul li{ padding: 1rem 0;}
|
||||||
|
.news-list .lower-box ul li .pull-left{ width: 100%; height: 18rem;}
|
||||||
|
.news-list .lower-box ul li .pull-right{ width: 100%; padding: 1rem 0 0;}
|
||||||
|
.news-list .lower-box ul li .pull-right span{ font-size: 14px;}
|
||||||
|
.news-list .lower-box ul li .pull-right p{ height: auto; margin: 0.8rem 0;}
|
||||||
|
|
||||||
|
.page-search{}
|
||||||
|
.page-search .between-center{ width: 100%; padding: 0 5px;}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
@media screen and (max-width:768px){
|
||||||
|
}
|
||||||
|
@media screen and (max-width:480px){
|
||||||
|
}
|
||||||
|
@media screen and (max-width:365px){
|
||||||
|
}
|
After Width: | Height: | Size: 263 KiB |
After Width: | Height: | Size: 6.1 KiB |
After Width: | Height: | Size: 5.8 KiB |
After Width: | Height: | Size: 6.4 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 992 B |
After Width: | Height: | Size: 694 B |
After Width: | Height: | Size: 759 B |
After Width: | Height: | Size: 4.8 KiB |