Compare commits
11 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
fd06749715 | ||
|
06cc3caf77 | ||
|
a8943fa6aa | ||
|
fe2d08ca8e | ||
|
27daa029f4 | ||
|
91bd9d28c2 | ||
|
a5acd6cb6e | ||
|
38ac88505b | ||
|
59db926938 | ||
|
d9bd397475 | ||
|
d82f29fbe5 |
@ -45,6 +45,13 @@ abstract class BaseController
|
||||
*/
|
||||
protected $middleware = [];
|
||||
|
||||
/**
|
||||
* article content
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $content = '';
|
||||
|
||||
/**
|
||||
* 构造方法
|
||||
* @access public
|
||||
@ -202,16 +209,15 @@ abstract class BaseController
|
||||
protected function getArticleAllpic($str)
|
||||
{
|
||||
//正则匹配<img src="http://img.com" />
|
||||
$pattern = "/<[img|IMG].*?src=[\'|\"](.*?(?:[\.gif|\.jpg|\.png]))[\'|\"].*?[\/]?>/";
|
||||
$pattern = "/<[img|IMG].*?src=[\'|\"](.*?(?:[\.gif|\.jpg|\.png|\.jpeg]))[\'|\"].*?[\/]?>/";
|
||||
preg_match_all($pattern,$str,$matchContent);
|
||||
if(isset($matchContent[1])){
|
||||
$img = $matchContent[1];
|
||||
$imgArr = $matchContent[1];
|
||||
}else{
|
||||
$temp = "./images/no-image.jpg";//在相应位置放置一张命名为no-image的jpg图片
|
||||
}
|
||||
|
||||
return $img;
|
||||
|
||||
|
||||
return $imgArr;
|
||||
}
|
||||
|
||||
//下载远程图片
|
||||
@ -222,7 +228,7 @@ abstract class BaseController
|
||||
curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, false );
|
||||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
|
||||
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 60);
|
||||
$file = curl_exec($ch);
|
||||
curl_close($ch);
|
||||
return $this->saveAsImage($url, $file);
|
||||
@ -234,9 +240,9 @@ abstract class BaseController
|
||||
{
|
||||
$filename = pathinfo($url, PATHINFO_BASENAME);
|
||||
//$dirname = pathinfo(parse_url($url, PHP_URL_PATH), PATHINFO_DIRNAME);
|
||||
$dirname = date('Ymd',time());
|
||||
|
||||
//路径
|
||||
$path = 'storage/download/article_pic/' . $dirname . '/';
|
||||
$path = 'storage/download/article_pic/' . date('Ymd',time()) . '/';
|
||||
//绝对文件夹
|
||||
$fileDir = public_path() . $path;
|
||||
//文件绝对路径
|
||||
@ -266,23 +272,24 @@ abstract class BaseController
|
||||
//下载网络图片到本地并替换
|
||||
public function downUrlPicsReaplace($content)
|
||||
{
|
||||
$this->content = $content;
|
||||
// 批量下载网络图片并替换
|
||||
$images = $this->getArticleAllpic($content);
|
||||
$images = $this->getArticleAllpic($this->content);
|
||||
if(count($images)) {
|
||||
foreach($images as $image){
|
||||
//1.带http地址的图片,2.非本站的网络图片 3.非带有?号等参数的图片
|
||||
if((stripos($image,'http') !== false) && (stripos($image, Request::domain()) === false) && (stripos($image, '?') === false)) {
|
||||
if((stripos($image,'http') !== false) && (stripos($image, Request::domain()) === false) && (stripos($image, '?') == false)) {
|
||||
// 如果图片中没有带参数或者加密可下载
|
||||
//下载远程图片(可下载)
|
||||
$newImageUrl = $this->downloadImage($image);
|
||||
//替换图片链接
|
||||
$content = str_replace($image,Request::domain().$newImageUrl,$content);
|
||||
$this->content = str_replace($image, Request::domain().$newImageUrl, $this->content);
|
||||
}
|
||||
}
|
||||
//不可下载的图片,如加密或者带有参数的图片如?type=jpeg,直接返回content
|
||||
}
|
||||
|
||||
return $content;
|
||||
return $this->content;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -21,6 +21,7 @@ use app\admin\model\Cunsult;
|
||||
use think\facade\Config;
|
||||
use taoler\com\Api;
|
||||
use app\common\lib\facade\HttpHelper;
|
||||
use app\common\model\Comment;
|
||||
|
||||
class Index extends AdminController
|
||||
{
|
||||
@ -61,15 +62,28 @@ class Index extends AdminController
|
||||
public function console2()
|
||||
{
|
||||
// 评论、帖子状态
|
||||
$comm = Db::name('comment')->field('id')->where(['delete_time'=>0,'status'=>0])->select();
|
||||
$comm = Db::name('comment')->field('id,content,create_time')->where(['delete_time'=>0,'status'=>0])->select();
|
||||
$forum = Db::name('article')->field('id')->where(['delete_time'=>0,'status'=>0])->select();
|
||||
$user = Db::name('user')->field('id')->where(['delete_time'=>0,'status'=>0])->select();
|
||||
// 回复评论
|
||||
$comments = Comment::field('id,article_id,content,create_time,delete_time')->where(['delete_time'=>0])->order('create_time desc')->limit(10)->select();
|
||||
$commData = [];
|
||||
foreach($comments as $v) {
|
||||
$commData[] = [
|
||||
'id' => $v->id,
|
||||
'content' => strip_tags($v['content']),
|
||||
'create_time' => $v['create_time'],
|
||||
'url' => $this->getArticleUrl($v['article_id'], 'index', $v->article->cate->ename)
|
||||
];
|
||||
}
|
||||
|
||||
View::assign([
|
||||
'pendComms' => count($comm),
|
||||
'pendForums' => count($forum),
|
||||
'pendUser' => count($user),
|
||||
'comments' => $commData,
|
||||
]);
|
||||
|
||||
return View::fetch('console2');
|
||||
}
|
||||
|
||||
|
@ -341,11 +341,11 @@ class Addons extends AdminController
|
||||
{
|
||||
$name = input('name');
|
||||
$config = get_addons_config($name);
|
||||
// halt($config);
|
||||
|
||||
if(empty($config)) return json(['code'=>-1,'msg'=>'无配置项!无需操作']);
|
||||
if(Request::isAjax()){
|
||||
$params = Request::param('params/a',[],'trim');
|
||||
// halt($params);
|
||||
|
||||
if ($params) {
|
||||
foreach ($config as $k => &$v) {
|
||||
if (isset($params[$k])) {
|
||||
@ -359,6 +359,9 @@ class Addons extends AdminController
|
||||
$value = $params[$k];
|
||||
$v['content'] = $value;
|
||||
$v['value'] = $value;
|
||||
} elseif ($v['type'] == 'select'){
|
||||
$value = [(int)$params[$k]];
|
||||
$v['value'] = $value;
|
||||
} else {
|
||||
$value = $params[$k];
|
||||
}
|
||||
@ -371,7 +374,7 @@ class Addons extends AdminController
|
||||
}
|
||||
return json(['code'=>0,'msg'=>'配置成功!']);
|
||||
}
|
||||
//halt($config);
|
||||
|
||||
//模板引擎初始化
|
||||
$view = ['formData'=>$config,'title'=>'title'];
|
||||
View::assign($view);
|
||||
|
@ -166,7 +166,29 @@ class Comment extends AdminController
|
||||
return json(['code'=>0,'msg'=>'评论被禁止','icon'=>5]);
|
||||
}
|
||||
return json(['code'=>-1,'msg'=>'审核出错']);
|
||||
}
|
||||
|
||||
/**
|
||||
* 多选批量审核
|
||||
*
|
||||
* @return Json
|
||||
*/
|
||||
public function checkSelect()
|
||||
{
|
||||
$param = Request::param('data');
|
||||
$data = [];
|
||||
foreach($param as $v) {
|
||||
$data[] = ['id' => (int)$v['id'], 'status' => $v['check'] == '1' ? '-1' : '1'];
|
||||
}
|
||||
|
||||
//获取状态
|
||||
$res = $this->model->saveAll($data);
|
||||
|
||||
if($res){
|
||||
return json(['code'=>0,'msg'=>'审核成功','icon'=>6]);
|
||||
}else {
|
||||
return json(['code'=>-1,'msg'=>'失败啦','icon'=>6]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -87,7 +87,7 @@ class Forum extends AdminController
|
||||
$where[] = ['title', 'like', '%'.$data['title'].'%'];
|
||||
}
|
||||
|
||||
$list = $this->model->getList($where, input('limit'), input('page'));
|
||||
$list = $this->model->getAllStatusList($where, input('limit'), input('page'));
|
||||
$res = [];
|
||||
if($list['total']){
|
||||
foreach($list['data'] as $v) {
|
||||
@ -277,6 +277,29 @@ class Forum extends AdminController
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 多选批量审核
|
||||
*
|
||||
* @return Json
|
||||
*/
|
||||
public function checkSelect()
|
||||
{
|
||||
$param = Request::param('data');
|
||||
$data = [];
|
||||
foreach($param as $v) {
|
||||
$data[] = ['id' => (int)$v['id'], 'status' => $v['check'] == '1' ? '-1' : '1'];
|
||||
}
|
||||
|
||||
//获取状态
|
||||
$res = $this->model->saveAll($data);
|
||||
|
||||
if($res){
|
||||
return json(['code'=>0,'msg'=>'审核成功','icon'=>6]);
|
||||
}else {
|
||||
return json(['code'=>-1,'msg'=>'失败啦','icon'=>6]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传接口
|
||||
*
|
||||
|
@ -19,7 +19,6 @@ use app\common\lib\Uploads;
|
||||
use app\common\validate\User as userValidate;
|
||||
use think\exception\ValidateException;
|
||||
|
||||
|
||||
class User extends AdminController
|
||||
{
|
||||
|
||||
@ -39,40 +38,53 @@ class User extends AdminController
|
||||
if(Request::isAjax()){
|
||||
$datas = Request::only(['id','name','email','sex','status']);
|
||||
$map = array_filter($datas,[$this,'filtrArr']);
|
||||
if(!empty($map['id'])) {
|
||||
$map['id'] = (int) $map['id'];
|
||||
}
|
||||
|
||||
$user = Db::name('user')->where(['delete_time'=>0])->where($map)->order('id desc')->paginate([
|
||||
'list_rows' => input('limit'),
|
||||
'page' => input('page')
|
||||
]);
|
||||
$count = $user->total();
|
||||
$res = [];
|
||||
$data = [];
|
||||
if($count){
|
||||
$res = ['code'=>0,'msg'=>'ok','count'=>$count];
|
||||
foreach($user as $k => $v){
|
||||
$data = [
|
||||
'id' => $v['id'],
|
||||
'username' => $v['name'],
|
||||
'nick' => $v['nickname'],
|
||||
'avatar' => $v['user_img'],
|
||||
'phone' => $v['phone'],
|
||||
'email' => $v['email'],
|
||||
'sex' => $v['sex'],
|
||||
'ip' => $v['last_login_ip'],
|
||||
'city' => $v['city'],
|
||||
'logintime' => date("Y-m-d H:i",$v['last_login_time']),
|
||||
'jointime' => date("Y-m-d",$v['create_time']),
|
||||
'check' => $v['status'],
|
||||
'auth' => $v['auth']
|
||||
];
|
||||
$res['data'][] = $data;
|
||||
$vipList = [];
|
||||
$vipRule = Db::name('user_viprule')->field('id,vip,nick')->select();
|
||||
foreach($vipRule as $v) {
|
||||
$vipList[] = ['id' => $v['id'], 'vip' => $v['vip'], 'title' => $v['nick']];
|
||||
}
|
||||
} else {
|
||||
$res = ['code'=>-1,'msg'=>'没有查询结果!'];
|
||||
|
||||
foreach($user as $k => $v){
|
||||
$data[] = [
|
||||
'id' => $v['id'],
|
||||
'username' => $v['name'],
|
||||
'nick' => $v['nickname'],
|
||||
'avatar' => $v['user_img'],
|
||||
'phone' => $v['phone'],
|
||||
'email' => $v['email'],
|
||||
'sex' => $v['sex'],
|
||||
'ip' => $v['last_login_ip'],
|
||||
'city' => $v['city'],
|
||||
'point' => $v['point'],
|
||||
'logintime' => date("Y-m-d H:i:s",$v['last_login_time']),
|
||||
'jointime' => date("Y-m-d H:i",$v['create_time']),
|
||||
'check' => $v['status'],
|
||||
'auth' => $v['auth'],
|
||||
'vip' => $vipList[$v['vip']]['title']
|
||||
];
|
||||
}
|
||||
|
||||
return json(['code'=>0,'msg'=>'ok','count'=>$count, 'data' => $data, 'viplist' => $vipList]);
|
||||
}
|
||||
return json($res);
|
||||
return json(['code'=>-1,'msg'=>'没有查询结果!']);
|
||||
}
|
||||
return View::fetch();
|
||||
}
|
||||
|
||||
protected function getUserVipNick($vip) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
//添加用户
|
||||
@ -204,5 +216,40 @@ class User extends AdminController
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//登录用户中心
|
||||
public function goUserHome() {
|
||||
$id = (int)input('id');
|
||||
$user_home_url = $this->getUserHome($id);
|
||||
|
||||
return redirect($user_home_url);
|
||||
}
|
||||
|
||||
// 编辑用户积分
|
||||
public function editPoint()
|
||||
{
|
||||
if(Request::isAjax()) {
|
||||
$param = Request::param(['id','point']);
|
||||
|
||||
$res = Db::name('user')->where('id',(int)$param['id'])->update(['point' => (int)$param['point']]);
|
||||
if($res > 0) {
|
||||
return json(['code' => 0, 'msg' => '修改成功']);
|
||||
}
|
||||
return json(['code' => -1, 'msg' => '修改失败']);
|
||||
}
|
||||
}
|
||||
|
||||
// 编辑用户会员等级
|
||||
public function editVipLevel()
|
||||
{
|
||||
if(Request::isAjax()) {
|
||||
$param = Request::param(['id','vip']);
|
||||
$vipRule = Db::name('user_viprule')->field('vip,nick')->where('nick', $param['vip'])->find();
|
||||
$res = Db::name('user')->where('id',(int)$param['id'])->update(['vip' => (int)$vipRule['vip']]);
|
||||
if($res > 0) {
|
||||
return json(['code' => 0, 'msg' => '修改成功']);
|
||||
}
|
||||
return json(['code' => -1, 'msg' => '修改失败']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -29,22 +29,30 @@ class Vip extends AdminController
|
||||
{
|
||||
$keys = UserViprule::select();
|
||||
$count = $keys->count();
|
||||
$res = [];
|
||||
$data = [];
|
||||
if($count){
|
||||
$res = ['code'=>0,'msg'=>'','count'=>$count];
|
||||
foreach($keys as $k=>$v){
|
||||
$res['data'][] = ['id'=>$v['id'],'score'=>$v['score'],'nick'=>$v['nick'],'vip'=>$v['vip'],'ctime'=>$v['create_time']];
|
||||
}
|
||||
} else {
|
||||
$res = ['code'=>-1,'msg'=>'还没有任何vip等级设置!'];
|
||||
}
|
||||
return json($res);
|
||||
$data[] = [
|
||||
'id'=>$v['id'],
|
||||
'vip'=>$v['vip'],
|
||||
'score'=>$v['score'],
|
||||
'nick'=>$v['nick'],
|
||||
'postnum'=>$v['postnum'],
|
||||
'postpoint'=>$v['postpoint'],
|
||||
'refreshnum'=>$v['refreshnum'],
|
||||
'refreshpoint'=>$v['refreshpoint'],
|
||||
'ctime'=>$v['create_time']
|
||||
];
|
||||
}
|
||||
return json(['code'=>0,'msg'=>'ok','count'=>$count, 'data' => $data]);
|
||||
}
|
||||
return json(['code'=>-1,'msg'=>'还没有任何vip等级设置!']);
|
||||
}
|
||||
|
||||
//添加VIP积分规则
|
||||
public function add()
|
||||
{
|
||||
$data = Request::only(['score','vip','nick']);
|
||||
$data = Request::only(['score','vip','nick','postnum','refreshnum']);
|
||||
$vip = UserViprule::where('vip',$data['vip'])->find();
|
||||
if($vip){
|
||||
$res = ['code'=>-1,'msg'=>'vip等级不能重复设置'];
|
||||
|
@ -4,5 +4,5 @@ return [
|
||||
// 检测安装
|
||||
\app\middleware\Install::class,
|
||||
// 权限检测
|
||||
app\middleware\Auth::class,
|
||||
app\middleware\AdminAuth::class,
|
||||
];
|
@ -38,6 +38,9 @@
|
||||
{{# } }}
|
||||
{{# } }}
|
||||
</script>
|
||||
<script type="text/html" id="ver-tpl">
|
||||
<div>{{d.version}} {{# if(d.have_newversion == 1) { }} <span class="layui-badge-dot"></span> {{# } }}</div>
|
||||
</script>
|
||||
|
||||
<script type="text/html" id="buttonStatus">
|
||||
<input type="checkbox" name="{{d.name}}" lay-skin="switch" lay-filter="addonsStatus" lay-text="启动|禁用" {{# if(d.status == 1){ }} checked {{# } }} data-url="{:url('addon.addons/check')}">
|
||||
@ -51,7 +54,7 @@
|
||||
|
||||
{include file="public/user_login" /}
|
||||
<script src="/static/component/layui/layui.js"></script>
|
||||
<script src="/static/component/pear/pear.js"></script>
|
||||
<script src="/static/component/pear/pear.js"></script>
|
||||
|
||||
<script>
|
||||
var addonList = "{:url('addon.addons/getList')}";
|
||||
@ -65,7 +68,7 @@
|
||||
var toast = layui.toast;
|
||||
|
||||
let LIST_URL = "{:url('addon.addons/list')}";
|
||||
|
||||
|
||||
let cols = [[
|
||||
{type: 'checkbox'},
|
||||
{title: '序号', type: 'numbers'},
|
||||
@ -74,7 +77,7 @@
|
||||
{field: 'author', title: '作者', width: 100},
|
||||
{field: 'price', title: '价格(元)', width: 85},
|
||||
{field: 'downloads', title: '下载', width: 70},
|
||||
{field: 'version', title: '版本', templet: '<div>{{d.version}} {{# if(d.have_newversion == 1){ }}<span class="layui-badge-dot"></span>{{# } }}</div>', width: 75},
|
||||
{field: 'version', title: '版本', templet: '#ver-tpl', width: 75},
|
||||
{field: 'status', title: '在线', width: 70},
|
||||
{title: '操作', width: 165, align: 'center', toolbar: '#addons-bar'}
|
||||
]];
|
||||
|
@ -5,74 +5,77 @@
|
||||
<title>管理员管理</title>
|
||||
<link rel="stylesheet" href="/static/component/pear/css/pear.css" />
|
||||
</head>
|
||||
<body class="pear-container">
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-body">
|
||||
<form class="layui-form" action="">
|
||||
<div class="layui-form-item">
|
||||
<div class="layui-inline layuiadmin-input-useradmin">
|
||||
<label class="layui-form-label">回帖人</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="name" placeholder="请输入" autocomplete="off" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-inline">
|
||||
<label class="layui-form-label">内容</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="content" placeholder="请输入" autocomplete="off" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-inline">
|
||||
<label class="layui-form-label">状态</label>
|
||||
<div class="layui-input-block">
|
||||
<select name="status" lay-filter="fourm-check">
|
||||
<option value="">全部</option>
|
||||
<option value="0">待审</option>
|
||||
<option value="-1">禁止</option>
|
||||
<option value="1">通过</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item layui-inline">
|
||||
<button class="pear-btn pear-btn-md pear-btn-primary" lay-submit lay-filter="comment-query">
|
||||
<i class="layui-icon layui-icon-search"></i>
|
||||
查询
|
||||
</button>
|
||||
<button type="reset" class="pear-btn pear-btn-md">
|
||||
<i class="layui-icon layui-icon-refresh"></i>
|
||||
重置
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-body">
|
||||
<table id="comment-table" lay-filter="comment-table"></table>
|
||||
</div>
|
||||
</div>
|
||||
<body class="pear-container">
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-body">
|
||||
<form class="layui-form" action="">
|
||||
<div class="layui-form-item">
|
||||
<div class="layui-inline layuiadmin-input-useradmin">
|
||||
<label class="layui-form-label">回帖人</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="name" placeholder="请输入" autocomplete="off" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-inline">
|
||||
<label class="layui-form-label">内容</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="content" placeholder="请输入" autocomplete="off" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-inline">
|
||||
<label class="layui-form-label">状态</label>
|
||||
<div class="layui-input-block">
|
||||
<select name="status" lay-filter="fourm-check">
|
||||
<option value="">全部</option>
|
||||
<option value="0">待审</option>
|
||||
<option value="-1">禁止</option>
|
||||
<option value="1">通过</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item layui-inline">
|
||||
<button class="pear-btn pear-btn-md pear-btn-primary" lay-submit lay-filter="comment-query">
|
||||
<i class="layui-icon layui-icon-search"></i>
|
||||
查询
|
||||
</button>
|
||||
<button type="reset" class="pear-btn pear-btn-md">
|
||||
<i class="layui-icon layui-icon-refresh"></i>
|
||||
重置
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-body">
|
||||
<table id="comment-table" lay-filter="comment-table"></table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script type="text/html" id="comment-toolbar">
|
||||
<button class="pear-btn pear-btn-danger pear-btn-md" lay-event="batchRemove">
|
||||
<i class="layui-icon layui-icon-delete"></i>
|
||||
删除
|
||||
</button>
|
||||
</script>
|
||||
<script type="text/html" id="comment-toolbar">
|
||||
<button class="pear-btn pear-btn-danger pear-btn-md" lay-event="batchRemove">
|
||||
<i class="layui-icon layui-icon-delete"></i>
|
||||
删除
|
||||
</button>
|
||||
<button class="pear-btn layui-bg-orange pear-btn-md" lay-event="checkSelect">
|
||||
批量审核
|
||||
</button>
|
||||
</script>
|
||||
|
||||
|
||||
<script type="text/html" id="imgTpl">
|
||||
<img style="width: 25px; height: 25px;" src= {{ d.avatar }}>
|
||||
</script>
|
||||
<script type="text/html" id="buttonCheck">
|
||||
<input type="checkbox" name="check" lay-skin="switch" lay-filter="check" lay-text="通过|{{ d.check == 0 ? '待审' : '禁止' }}" {{ d.check == 1 ? 'checked' : '' }} id="{{d.id}}" >
|
||||
<script type="text/html" id="imgTpl">
|
||||
<img style="width: 25px; height: 25px;" src= {{ d.avatar }}>
|
||||
</script>
|
||||
<script type="text/html" id="buttonCheck">
|
||||
<input type="checkbox" name="check" lay-skin="switch" lay-filter="check" lay-text="通过|{{ d.check == 0 ? '待审' : '禁止' }}" {{ d.check == 1 ? 'checked' : '' }} id="{{d.id}}" >
|
||||
|
||||
</script>
|
||||
</script>
|
||||
|
||||
<script type="text/html" id="comment-bar">
|
||||
<!--<button class="pear-btn pear-btn-primary pear-btn-sm" lay-event="edit"><i class="layui-icon layui-icon-edit"></i></button>-->
|
||||
<button class="pear-btn pear-btn-danger pear-btn-sm" lay-event="remove"><i class="layui-icon layui-icon-delete"></i></button>
|
||||
</script>
|
||||
<script type="text/html" id="comment-bar">
|
||||
<!--<button class="pear-btn pear-btn-primary pear-btn-sm" lay-event="edit"><i class="layui-icon layui-icon-edit"></i></button>-->
|
||||
<button class="pear-btn pear-btn-danger pear-btn-sm" lay-event="remove"><i class="layui-icon layui-icon-delete"></i></button>
|
||||
</script>
|
||||
|
||||
</div>
|
||||
|
||||
@ -125,7 +128,9 @@
|
||||
window.refresh();
|
||||
} else if (obj.event === 'batchRemove') {
|
||||
window.batchRemove(obj);
|
||||
}
|
||||
} else if (obj.event === 'checkSelect') {
|
||||
window.checkSelect(obj);
|
||||
}
|
||||
});
|
||||
|
||||
form.on('submit(comment-query)', function(data) {
|
||||
@ -246,6 +251,53 @@
|
||||
});
|
||||
}
|
||||
|
||||
// 全选审核
|
||||
window.checkSelect = function(obj) {
|
||||
var id = obj.config.id;
|
||||
var checkStatus = table.checkStatus(id);
|
||||
var data = checkStatus.data;
|
||||
|
||||
if (data.length === 0) {
|
||||
layer.msg("未选中数据", {
|
||||
icon: 3,
|
||||
time: 1000
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
layer.confirm('确定要审核?', {
|
||||
icon: 3,
|
||||
title: '提示'
|
||||
}, function(index) {
|
||||
layer.close(index);
|
||||
let loading = layer.load();
|
||||
console.log(data)
|
||||
$.ajax({
|
||||
type: "post",
|
||||
url: "{:url('content.comment/checkSelect')}",
|
||||
dataType: 'json',
|
||||
data: {data},
|
||||
success: function(result) {
|
||||
layer.close(loading);
|
||||
if (result.code === 0) {
|
||||
layer.msg(result.msg, {
|
||||
icon: 1,
|
||||
time: 1000
|
||||
}, function() {
|
||||
table.reload('comment-table');
|
||||
});
|
||||
} else {
|
||||
layer.msg(result.msg, {
|
||||
icon: 2,
|
||||
time: 1000
|
||||
});
|
||||
}
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
window.refresh = function(param) {
|
||||
table.reload('comment-table');
|
||||
}
|
||||
|
@ -113,7 +113,7 @@
|
||||
show: true,
|
||||
indent: 15,
|
||||
strict: false,
|
||||
expandedKeys: true
|
||||
expandedKeys: false
|
||||
},
|
||||
tips: '请选择'
|
||||
});
|
||||
@ -203,6 +203,8 @@
|
||||
|
||||
});
|
||||
</script>
|
||||
{// 编辑器}
|
||||
{:hook('ueditor')}
|
||||
{:hook('taonyeditor')}
|
||||
{// 百度标题词条}
|
||||
{:hook('seoBaiduTitle')}
|
||||
|
@ -154,7 +154,7 @@
|
||||
show: true,
|
||||
indent: 15,
|
||||
strict: false,
|
||||
expandedKeys: true
|
||||
expandedKeys: false
|
||||
},
|
||||
tips: '请选择'
|
||||
});
|
||||
@ -222,6 +222,8 @@
|
||||
|
||||
});
|
||||
</script>
|
||||
{// 编辑器}
|
||||
{:hook('ueditor')}
|
||||
{:hook('taonyeditor')}
|
||||
{// 百度标题词条}
|
||||
{:hook('seoBaiduTitle')}
|
||||
|
@ -5,358 +5,392 @@
|
||||
<title>用户管理</title>
|
||||
<link rel="stylesheet" href="/static/component/pear/css/pear.css" />
|
||||
</head>
|
||||
<body class="pear-container">
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-body">
|
||||
<form class="layui-form" action="">
|
||||
<div class="layui-row layui-col-space15 ">
|
||||
<div class="layui-col-md3">
|
||||
<label class="layui-form-label">选择类目</label>
|
||||
<div class="layui-input-block">
|
||||
<div id="CateId" class="xm-select-demo"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-col-md3">
|
||||
<label class="layui-form-label">帖子ID</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="id" placeholder="请输入" autocomplete="off" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-col-md3">
|
||||
<label class="layui-form-label">发帖人</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="name" placeholder="请输入" autocomplete="off" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-col-md3">
|
||||
<label class="layui-form-label">标题</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="title" placeholder="请输入" autocomplete="off" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-col-md3">
|
||||
<label class="layui-form-label">状态</label>
|
||||
<div class="layui-input-block">
|
||||
<select name="sec">
|
||||
<option value="">选择状态</option>
|
||||
<option value="1">正常</option>
|
||||
<option value="5">禁止</option>
|
||||
<option value="6">待审</option>
|
||||
<option value="2">置顶</option>
|
||||
<option value="3">加精</option>
|
||||
<option value="4">禁评</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-col-md3">
|
||||
<button class="pear-btn pear-btn-md pear-btn-primary" lay-submit lay-filter="forum-query">
|
||||
<i class="layui-icon layui-icon-search"></i>
|
||||
查询
|
||||
</button>
|
||||
<button type="reset" class="pear-btn pear-btn-md">
|
||||
<i class="layui-icon layui-icon-refresh"></i>
|
||||
重置
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-body">
|
||||
<table id="forum-table" lay-filter="forum-table" ></table>
|
||||
</div>
|
||||
</div>
|
||||
<body class="pear-container">
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-body">
|
||||
<form class="layui-form" action="">
|
||||
<div class="layui-row layui-col-space15 ">
|
||||
<div class="layui-col-md3">
|
||||
<label class="layui-form-label">选择类目</label>
|
||||
<div class="layui-input-block">
|
||||
<div id="CateId" class="xm-select-demo"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-col-md3">
|
||||
<label class="layui-form-label">帖子ID</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="id" placeholder="请输入" autocomplete="off" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-col-md3">
|
||||
<label class="layui-form-label">发帖人</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="name" placeholder="请输入" autocomplete="off" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-col-md3">
|
||||
<label class="layui-form-label">标题</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="title" placeholder="请输入" autocomplete="off" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-col-md3">
|
||||
<label class="layui-form-label">状态</label>
|
||||
<div class="layui-input-block">
|
||||
<select name="sec">
|
||||
<option value="">选择状态</option>
|
||||
<option value="1">正常</option>
|
||||
<option value="5">禁止</option>
|
||||
<option value="6">待审</option>
|
||||
<option value="2">置顶</option>
|
||||
<option value="3">加精</option>
|
||||
<option value="4">禁评</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-col-md3">
|
||||
<button class="pear-btn pear-btn-md pear-btn-primary" lay-submit lay-filter="forum-query">
|
||||
<i class="layui-icon layui-icon-search"></i>
|
||||
查询
|
||||
</button>
|
||||
<button type="reset" class="pear-btn pear-btn-md">
|
||||
<i class="layui-icon layui-icon-refresh"></i>
|
||||
重置
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-body">
|
||||
<table id="forum-table" lay-filter="forum-table" ></table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script type="text/html" id="forum-toolbar">
|
||||
<button class="pear-btn pear-btn-primary pear-btn-md" lay-event="add">
|
||||
<i class="layui-icon layui-icon-add-1"></i>
|
||||
新增
|
||||
</button>
|
||||
<button class="pear-btn pear-btn-danger pear-btn-md" lay-event="batchRemove">
|
||||
<i class="layui-icon layui-icon-delete"></i>
|
||||
删除
|
||||
</button>
|
||||
</script>
|
||||
<script type="text/html" id="forum-toolbar">
|
||||
<button class="pear-btn pear-btn-primary pear-btn-md" lay-event="add">
|
||||
<i class="layui-icon layui-icon-add-1"></i>
|
||||
新增
|
||||
</button>
|
||||
<button class="pear-btn pear-btn-danger pear-btn-md" lay-event="batchRemove">
|
||||
<i class="layui-icon layui-icon-delete"></i>
|
||||
删除
|
||||
</button>
|
||||
<button class="pear-btn layui-bg-orange pear-btn-md" lay-event="checkSelect">
|
||||
批量审核
|
||||
</button>
|
||||
</script>
|
||||
|
||||
<script type="text/html" id="avatarTpl">
|
||||
<div><img style="width: 25px; height: 25px;" src= "{{ d.avatar }}"></div>
|
||||
</script>
|
||||
<script type="text/html" id="forum-istop">
|
||||
<input type="checkbox" name="is_top" value="{{d.id}}" lay-skin="switch" lay-text="是|否" lay-filter="isTop" {{ d.top == 1 ? 'checked' : '' }}>
|
||||
</script>
|
||||
<script type="text/html" id="buttonHot">
|
||||
<input type="checkbox" name="is_hot" value="{{d.id}}" lay-skin="switch" lay-text="是|否" lay-filter="isHot" {{ d.hot == 1 ? 'checked' : '' }}>
|
||||
</script>
|
||||
<script type="text/html" id="buttonReply">
|
||||
<input type="checkbox" name="is_reply" value="{{d.id}}" lay-skin="switch" lay-text="是|否" lay-filter="isReply" {{ d.reply == 0 ? 'checked' : '' }}>
|
||||
</script>
|
||||
<script type="text/html" id="buttonCheck">
|
||||
<input type="checkbox" name="status" value="{{d.id}}" lay-skin="switch" lay-filter="artStatus" lay-text="通过|{{ d.check == 0 ? '待审' : '禁止' }}" {{ d.check == 1 ? 'checked' : '' }}>
|
||||
</script>
|
||||
<script type="text/html" id="avatarTpl">
|
||||
<div><img style="width: 25px; height: 25px;" src= "{{ d.avatar }}"></div>
|
||||
</script>
|
||||
<script type="text/html" id="forum-istop">
|
||||
<input type="checkbox" name="is_top" value="{{d.id}}" lay-skin="switch" lay-text="是|否" lay-filter="isTop" {{ d.top == 1 ? 'checked' : '' }}>
|
||||
</script>
|
||||
<script type="text/html" id="buttonHot">
|
||||
<input type="checkbox" name="is_hot" value="{{d.id}}" lay-skin="switch" lay-text="是|否" lay-filter="isHot" {{ d.hot == 1 ? 'checked' : '' }}>
|
||||
</script>
|
||||
<script type="text/html" id="buttonReply">
|
||||
<input type="checkbox" name="is_reply" value="{{d.id}}" lay-skin="switch" lay-text="是|否" lay-filter="isReply" {{ d.reply == 0 ? 'checked' : '' }}>
|
||||
</script>
|
||||
<script type="text/html" id="buttonCheck">
|
||||
<input type="checkbox" name="status" value="{{d.id}}" lay-skin="switch" lay-filter="artStatus" lay-text="通过|{{ d.check == 0 ? '待审' : '禁止' }}" {{ d.check == 1 ? 'checked' : '' }}>
|
||||
</script>
|
||||
|
||||
<script type="text/html" id="forum-table-bar">
|
||||
<button class="pear-btn pear-btn-primary pear-btn-sm" lay-event="edit"><i class="layui-icon layui-icon-edit"></i></button>
|
||||
<button class="pear-btn pear-btn-danger pear-btn-sm" lay-event="remove"><i class="layui-icon layui-icon-delete"></i></button>
|
||||
</script>
|
||||
<script type="text/html" id="forum-table-bar">
|
||||
<button class="pear-btn pear-btn-primary pear-btn-sm" lay-event="edit"><i class="layui-icon layui-icon-edit"></i></button>
|
||||
<button class="pear-btn pear-btn-danger pear-btn-sm" lay-event="remove"><i class="layui-icon layui-icon-delete"></i></button>
|
||||
</script>
|
||||
|
||||
<script src="/static/component/layui/layui.js"></script>
|
||||
<script src="/static/component/pear/pear.js"></script>
|
||||
<script src="/static/component/layui/layui.js"></script>
|
||||
<script src="/static/component/pear/pear.js"></script>
|
||||
|
||||
<script>
|
||||
const FORUM_List = "{:url('content.forum/list')}";
|
||||
<script>
|
||||
const FORUM_List = "{:url('content.forum/list')}";
|
||||
|
||||
layui.use(['toast','jquery','form', 'table','common','xmSelect'], function(){
|
||||
var $ = layui.jquery
|
||||
,form = layui.form
|
||||
,table = layui.table;
|
||||
let common = layui.common;
|
||||
var toast = layui.toast;
|
||||
var xmSelect = layui.xmSelect;
|
||||
layui.use(['toast','jquery','form', 'table','common','xmSelect'], function(){
|
||||
var $ = layui.jquery
|
||||
,form = layui.form
|
||||
,table = layui.table;
|
||||
let common = layui.common;
|
||||
var toast = layui.toast;
|
||||
var xmSelect = layui.xmSelect;
|
||||
|
||||
//如果你是采用模版自带的编辑器,你需要开启以下语句来解析。
|
||||
var taonystatus = "{:hook('taonystatus')}";
|
||||
// 编辑器插件启用状态
|
||||
var isShow = taonystatus ? false : true;
|
||||
let cols = [
|
||||
[
|
||||
{type: 'checkbox'}
|
||||
,{field: 'id', width: 60, title: 'ID', sort: true}
|
||||
,{field: 'avatar', title: '头像', width: 60, templet: '#avatarTpl'}
|
||||
,{field: 'poster', title: '账号',width: 80}
|
||||
,{field: 'title', title: '标题', minWidth: 180, templet: '<div><a href="{{- d.url }}" target="_blank">{{- d.title }}</a></div>'}
|
||||
,{field: 'cate', title: '类别', width: 120}
|
||||
,{field: 'content', title: '内容', 'escape':false, minWidth: 200}
|
||||
,{field: 'posttime', title: '时间',width: 120, sort: true}
|
||||
,{field: 'top', title: '置顶', templet: '#forum-istop', width: 80, align: 'center'}
|
||||
,{field: 'hot', title: '加精', templet: '#buttonHot', width: 80, align: 'center'}
|
||||
,{field: 'reply', title: '禁评', templet: '#buttonReply', width: 80, align: 'center'}
|
||||
,{field: 'check', title: '审帖', templet: '#buttonCheck', width: 95, align: 'center'}
|
||||
,{title: '操作', width: 110, align: 'center', toolbar: '#forum-table-bar'}
|
||||
]
|
||||
];
|
||||
|
||||
table.render({
|
||||
elem: '#forum-table',
|
||||
url: FORUM_List,
|
||||
page: true,
|
||||
cols: cols,
|
||||
skin: 'line',
|
||||
toolbar: '#forum-toolbar',
|
||||
defaultToolbar: [{
|
||||
title: '刷新',
|
||||
layEvent: 'refresh',
|
||||
icon: 'layui-icon-refresh',
|
||||
}, 'filter', 'print', 'exports']
|
||||
});
|
||||
|
||||
let cols = [
|
||||
[
|
||||
{type: 'checkbox'}
|
||||
,{field: 'id', width: 60, title: 'ID', sort: true}
|
||||
,{field: 'avatar', title: '头像', width: 60, templet: '#avatarTpl'}
|
||||
,{field: 'poster', title: '账号',width: 80}
|
||||
,{field: 'title', title: '标题', minWidth: 180,templet: '<div><a href="{{- d.url }}" target="_blank">{{- d.title }}</a></div>'}
|
||||
,{field: 'cate', title: '类别', width: 120}
|
||||
,{field: 'content', title: '内容', 'escape':false, minWidth: 200}
|
||||
,{field: 'posttime', title: '时间',width: 120, sort: true}
|
||||
,{field: 'top', title: '置顶', templet: '#forum-istop', width: 80, align: 'center'}
|
||||
,{field: 'hot', title: '加精', templet: '#buttonHot', width: 80, align: 'center'}
|
||||
,{field: 'reply', title: '禁评', templet: '#buttonReply', width: 80, align: 'center'}
|
||||
,{field: 'check', title: '审帖', templet: '#buttonCheck', width: 95, align: 'center'}
|
||||
,{title: '操作', width: 110, align: 'center', toolbar: '#forum-table-bar'}
|
||||
]
|
||||
];
|
||||
// 动态分类
|
||||
function getSelectCate() {
|
||||
// 分类选择
|
||||
$.get("{:url('content.forum/getCateList')}", function(res){
|
||||
// 渲染下拉树
|
||||
xmSelect.render({
|
||||
el: '#CateId',
|
||||
name: 'cate_id',
|
||||
height: '250px',
|
||||
layVerify: '',
|
||||
layVerType: 'tips',
|
||||
data: res.data,
|
||||
initValue: [],
|
||||
model: {label: {type: 'text'}},
|
||||
prop: {
|
||||
name: 'catename',
|
||||
value: 'id'
|
||||
},
|
||||
radio: true,
|
||||
clickClose: true,
|
||||
tree: {
|
||||
show: true,
|
||||
indent: 15,
|
||||
strict: false,
|
||||
expandedKeys: true
|
||||
},
|
||||
tips: '请选择'
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
table.render({
|
||||
elem: '#forum-table',
|
||||
url: FORUM_List,
|
||||
page: true,
|
||||
cols: cols,
|
||||
skin: 'line',
|
||||
toolbar: '#forum-toolbar',
|
||||
defaultToolbar: [{
|
||||
title: '刷新',
|
||||
layEvent: 'refresh',
|
||||
icon: 'layui-icon-refresh',
|
||||
}, 'filter', 'print', 'exports']
|
||||
});
|
||||
getSelectCate();
|
||||
|
||||
// 动态分类
|
||||
function getSelectCate() {
|
||||
// 分类选择
|
||||
$.get("{:url('content.forum/getCateList')}", function(res){
|
||||
// 渲染下拉树
|
||||
xmSelect.render({
|
||||
el: '#CateId',
|
||||
name: 'cate_id',
|
||||
height: '250px',
|
||||
layVerify: '',
|
||||
layVerType: 'tips',
|
||||
data: res.data,
|
||||
initValue: [],
|
||||
model: {label: {type: 'text'}},
|
||||
prop: {
|
||||
name: 'catename',
|
||||
value: 'id'
|
||||
},
|
||||
radio: true,
|
||||
clickClose: true,
|
||||
tree: {
|
||||
show: true,
|
||||
indent: 15,
|
||||
strict: false,
|
||||
expandedKeys: true
|
||||
},
|
||||
tips: '请选择'
|
||||
});
|
||||
});
|
||||
}
|
||||
getSelectCate();
|
||||
table.on('tool(forum-table)', function(obj) {
|
||||
if (obj.event === 'remove') {
|
||||
window.remove(obj);
|
||||
} else if (obj.event === 'edit') {
|
||||
window.edit(obj);
|
||||
}
|
||||
});
|
||||
|
||||
table.on('tool(forum-table)', function(obj) {
|
||||
if (obj.event === 'remove') {
|
||||
window.remove(obj);
|
||||
} else if (obj.event === 'edit') {
|
||||
window.edit(obj);
|
||||
}
|
||||
});
|
||||
table.on('toolbar(forum-table)', function(obj) {
|
||||
if (obj.event === 'add') {
|
||||
window.add();
|
||||
} else if (obj.event === 'refresh') {
|
||||
window.refresh();
|
||||
} else if (obj.event === 'batchRemove') {
|
||||
window.batchRemove(obj);
|
||||
} else if (obj.event === 'checkSelect') {
|
||||
window.checkSelect(obj);
|
||||
}
|
||||
});
|
||||
|
||||
table.on('toolbar(forum-table)', function(obj) {
|
||||
if (obj.event === 'add') {
|
||||
window.add();
|
||||
} else if (obj.event === 'refresh') {
|
||||
window.refresh();
|
||||
} else if (obj.event === 'batchRemove') {
|
||||
window.batchRemove(obj);
|
||||
}
|
||||
});
|
||||
form.on('submit(forum-query)', function(data) {
|
||||
table.reload('forum-table', {
|
||||
where: data.field,
|
||||
page: {
|
||||
curr: 1 //重新从第 1 页开始
|
||||
}
|
||||
})
|
||||
return false;
|
||||
});
|
||||
|
||||
form.on('submit(forum-query)', function(data) {
|
||||
table.reload('forum-table', {
|
||||
where: data.field,
|
||||
page: {
|
||||
curr: 1 //重新从第 1 页开始
|
||||
}
|
||||
})
|
||||
return false;
|
||||
});
|
||||
// 监听置顶
|
||||
form.on('switch(isTop)', function(obj){
|
||||
$.post("{:url('content.forum/check')}",{id:obj.value, name:obj.elem.name,value:obj.elem.checked ? 1 : 0},function(res){
|
||||
layer.tips(obj.value + ' ' + obj.elem.name + ':'+ obj.elem.checked, obj.othis);
|
||||
});
|
||||
});
|
||||
|
||||
// 监听置顶
|
||||
form.on('switch(isTop)', function(obj){
|
||||
$.post("{:url('content.forum/check')}",{id:obj.value, name:obj.elem.name,value:obj.elem.checked ? 1 : 0},function(res){
|
||||
layer.tips(obj.value + ' ' + obj.elem.name + ':'+ obj.elem.checked, obj.othis);
|
||||
});
|
||||
});
|
||||
// 监听加精
|
||||
form.on('switch(isHot)', function(obj){
|
||||
$.post("{:url('content.forum/check')}",{id:obj.value, name:obj.elem.name,value: obj.elem.checked ? 1 : 0},function(res){
|
||||
layer.tips(obj.value + ' ' + obj.elem.name + ':'+ obj.elem.checked, obj.othis);
|
||||
});
|
||||
});
|
||||
|
||||
// 监听加精
|
||||
form.on('switch(isHot)', function(obj){
|
||||
$.post("{:url('content.forum/check')}",{id:obj.value, name:obj.elem.name,value: obj.elem.checked ? 1 : 0},function(res){
|
||||
layer.tips(obj.value + ' ' + obj.elem.name + ':'+ obj.elem.checked, obj.othis);
|
||||
});
|
||||
});
|
||||
// 监听回复
|
||||
form.on('switch(isReply)', function(obj){
|
||||
$.post("{:url('content.forum/check')}",{id:obj.value, name:obj.elem.name,value: obj.elem.checked ? 0 : 1},function(res){
|
||||
layer.tips(obj.value + ' ' + obj.elem.name + ':'+ obj.elem.checked, obj.othis);
|
||||
});
|
||||
});
|
||||
|
||||
// 监听回复
|
||||
form.on('switch(isReply)', function(obj){
|
||||
$.post("{:url('content.forum/check')}",{id:obj.value, name:obj.elem.name,value: obj.elem.checked ? 0 : 1},function(res){
|
||||
layer.tips(obj.value + ' ' + obj.elem.name + ':'+ obj.elem.checked, obj.othis);
|
||||
});
|
||||
});
|
||||
// 监听审贴
|
||||
form.on('switch(artStatus)', function(obj){
|
||||
//layer.tips(obj.value + ' ' + obj.elem.name + ':'+ obj.elem.checked, obj.othis);
|
||||
$.post("{:url('content.forum/check')}",{id:obj.value, name:obj.elem.name,value: obj.elem.checked ? 1 : -1},function(res){
|
||||
if(res.code === 0){
|
||||
layer.msg(res.msg,{icon:res.icon,time:2000})
|
||||
} else {
|
||||
layer.open({title:'审核失败',content:res.msg,icon:5,adim:6})
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// 监听审贴
|
||||
form.on('switch(artStatus)', function(obj){
|
||||
//layer.tips(obj.value + ' ' + obj.elem.name + ':'+ obj.elem.checked, obj.othis);
|
||||
$.post("{:url('content.forum/check')}",{id:obj.value, name:obj.elem.name,value: obj.elem.checked ? 1 : -1},function(res){
|
||||
if(res.code === 0){
|
||||
layer.msg(res.msg,{icon:res.icon,time:2000})
|
||||
} else {
|
||||
layer.open({title:'审核失败',content:res.msg,icon:5,adim:6})
|
||||
}
|
||||
});
|
||||
});
|
||||
// 添加
|
||||
window.add = function() {
|
||||
layer.open({
|
||||
type: 2,
|
||||
title: '新增',
|
||||
shade: 0.1,
|
||||
area: [common.isModile()?'100%':'100%', common.isModile()?'100%':'100%'],
|
||||
content: 'add.html'
|
||||
});
|
||||
}
|
||||
|
||||
window.add = function() {
|
||||
if(isShow) {
|
||||
toast.info({title: '信息',message: '编辑器插件未开启或未安装',position: 'topRight'});
|
||||
return false;
|
||||
}
|
||||
layer.open({
|
||||
type: 2,
|
||||
title: '新增',
|
||||
shade: 0.1,
|
||||
area: [common.isModile()?'100%':'100%', common.isModile()?'100%':'100%'],
|
||||
content: 'add.html'
|
||||
});
|
||||
}
|
||||
window.edit = function(obj) {
|
||||
layer.open({
|
||||
type: 2,
|
||||
title: '修改',
|
||||
shade: 0.1,
|
||||
area: ['100%', '100%'],
|
||||
content: 'edit.html?id=' + obj.data.id
|
||||
});
|
||||
}
|
||||
|
||||
window.edit = function(obj) {
|
||||
if(isShow) {
|
||||
toast.info({title: '信息',message: '编辑器插件未开启或未安装',position: 'topRight'});
|
||||
return false;
|
||||
}
|
||||
layer.open({
|
||||
type: 2,
|
||||
title: '修改',
|
||||
shade: 0.1,
|
||||
area: ['100%', '100%'],
|
||||
content: 'edit.html?id=' + obj.data.id
|
||||
});
|
||||
}
|
||||
window.remove = function(obj) {
|
||||
layer.confirm('确定要删除?', {
|
||||
icon: 3,
|
||||
title: '提示'
|
||||
}, function(index) {
|
||||
layer.close(index);
|
||||
let loading = layer.load();
|
||||
$.ajax({
|
||||
url: "{:url('content.forum/delete')}?id=" + obj.data['id'],
|
||||
dataType: 'json',
|
||||
type: 'delete',
|
||||
success: function(result) {
|
||||
layer.close(loading);
|
||||
if (result.code === 0) {
|
||||
layer.msg(result.msg, {
|
||||
icon: 1,
|
||||
time: 1000
|
||||
}, function() {
|
||||
obj.del();
|
||||
});
|
||||
} else {
|
||||
layer.msg(result.msg, {
|
||||
icon: 2,
|
||||
time: 1000
|
||||
});
|
||||
}
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// $(document).on('focusin', function(e) {
|
||||
// if ($(e.target).closest(".tox-tinymce, .tox-tinymce-aux, .moxman-window, .tam-assetmanager-root").length) {
|
||||
// e.stopImmediatePropagation();
|
||||
// }
|
||||
// });
|
||||
// 批量删除
|
||||
window.batchRemove = function(obj) {
|
||||
var checkIds = common.checkField(obj,'id');
|
||||
if (checkIds === "") {
|
||||
layer.msg("未选中数据", {
|
||||
icon: 3,
|
||||
time: 1000
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
window.remove = function(obj) {
|
||||
layer.confirm('确定要删除?', {
|
||||
icon: 3,
|
||||
title: '提示'
|
||||
}, function(index) {
|
||||
layer.close(index);
|
||||
let loading = layer.load();
|
||||
$.ajax({
|
||||
url: "{:url('content.forum/delete')}?id=" + checkIds,
|
||||
dataType: 'json',
|
||||
type: 'delete',
|
||||
data:{"id":checkIds},
|
||||
success: function(result) {
|
||||
layer.close(loading);
|
||||
if (result.code === 0) {
|
||||
layer.msg(result.msg, {
|
||||
icon: 1,
|
||||
time: 1000
|
||||
}, function() {
|
||||
table.reload('forum-table');
|
||||
});
|
||||
} else {
|
||||
layer.msg(result.msg, {
|
||||
icon: 2,
|
||||
time: 1000
|
||||
});
|
||||
}
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
layer.confirm('确定要删除?', {
|
||||
icon: 3,
|
||||
title: '提示'
|
||||
}, function(index) {
|
||||
layer.close(index);
|
||||
let loading = layer.load();
|
||||
$.ajax({
|
||||
url: "{:url('content.forum/delete')}?id=" + obj.data['id'],
|
||||
dataType: 'json',
|
||||
type: 'delete',
|
||||
success: function(result) {
|
||||
layer.close(loading);
|
||||
if (result.code === 0) {
|
||||
layer.msg(result.msg, {
|
||||
icon: 1,
|
||||
time: 1000
|
||||
}, function() {
|
||||
obj.del();
|
||||
});
|
||||
} else {
|
||||
layer.msg(result.msg, {
|
||||
icon: 2,
|
||||
time: 1000
|
||||
});
|
||||
}
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
// 全选审核
|
||||
window.checkSelect = function(obj) {
|
||||
var id = obj.config.id;
|
||||
var checkStatus = table.checkStatus(id);
|
||||
var data = checkStatus.data;
|
||||
|
||||
window.batchRemove = function(obj) {
|
||||
var checkIds = common.checkField(obj,'id');
|
||||
if (checkIds === "") {
|
||||
layer.msg("未选中数据", {
|
||||
icon: 3,
|
||||
time: 1000
|
||||
});
|
||||
return false;
|
||||
}
|
||||
if (data.length === 0) {
|
||||
layer.msg("未选中数据", {
|
||||
icon: 3,
|
||||
time: 1000
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
layer.confirm('确定要删除?', {
|
||||
icon: 3,
|
||||
title: '提示'
|
||||
}, function(index) {
|
||||
layer.close(index);
|
||||
let loading = layer.load();
|
||||
$.ajax({
|
||||
url: "{:url('content.forum/delete')}?id=" + checkIds,
|
||||
dataType: 'json',
|
||||
type: 'delete',
|
||||
data:{"id":checkIds},
|
||||
success: function(result) {
|
||||
layer.close(loading);
|
||||
if (result.code === 0) {
|
||||
layer.msg(result.msg, {
|
||||
icon: 1,
|
||||
time: 1000
|
||||
}, function() {
|
||||
table.reload('forum-table');
|
||||
});
|
||||
} else {
|
||||
layer.msg(result.msg, {
|
||||
icon: 2,
|
||||
time: 1000
|
||||
});
|
||||
}
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
layer.confirm('确定要审核?', {
|
||||
icon: 3,
|
||||
title: '提示'
|
||||
}, function(index) {
|
||||
layer.close(index);
|
||||
let loading = layer.load();
|
||||
console.log(data)
|
||||
$.ajax({
|
||||
type: "post",
|
||||
url: "{:url('content.forum/checkSelect')}",
|
||||
dataType: 'json',
|
||||
data: {data},
|
||||
success: function(result) {
|
||||
layer.close(loading);
|
||||
if (result.code === 0) {
|
||||
layer.msg(result.msg, {
|
||||
icon: 1,
|
||||
time: 1000
|
||||
}, function() {
|
||||
table.reload('forum-table');
|
||||
});
|
||||
} else {
|
||||
layer.msg(result.msg, {
|
||||
icon: 2,
|
||||
time: 1000
|
||||
});
|
||||
}
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
window.refresh = function(param) {
|
||||
table.reload('forum-table');
|
||||
}
|
||||
// 刷新
|
||||
window.refresh = function(param) {
|
||||
table.reload('forum-table');
|
||||
}
|
||||
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -327,7 +327,7 @@
|
||||
const v = layui.v;
|
||||
|
||||
|
||||
layui.use(['form','layer', 'echarts', 'element', 'count','toast'], function() {
|
||||
layui.use(['form','layer', 'echarts', 'carousel', 'element', 'count','toast'], function() {
|
||||
let $ = layui.jquery, form = layui.form,
|
||||
layer = layui.layer,
|
||||
element = layui.element,
|
||||
@ -335,37 +335,37 @@
|
||||
echarts = layui.echarts;
|
||||
let toast = layui.toast;
|
||||
let table = layui.table;
|
||||
let carousel = layui.carousel;
|
||||
|
||||
$('.UI').append(v);
|
||||
|
||||
|
||||
count.up("value1", {
|
||||
time: 4000,
|
||||
num: {:hook('seoBaiduTongji',['name'=>'tpv']) ?: 0},
|
||||
bit: 0,
|
||||
regulator: 50
|
||||
})
|
||||
bit: 0,
|
||||
regulator: 50
|
||||
})
|
||||
|
||||
count.up("value2", {
|
||||
time: 4000,
|
||||
num: {:hook('seoBaiduTongji',['name'=>'tuv']) ?: 0},
|
||||
bit: 0,
|
||||
regulator: 50
|
||||
})
|
||||
bit: 0,
|
||||
regulator: 50
|
||||
})
|
||||
|
||||
count.up("value3", {
|
||||
time: 4000,
|
||||
num: {:hook('seoBaiduTongji',['name'=>'tip']) ?: 0},
|
||||
bit: 0,
|
||||
regulator: 50
|
||||
})
|
||||
bit: 0,
|
||||
regulator: 50
|
||||
})
|
||||
|
||||
count.up("value4", {
|
||||
time: 4000,
|
||||
bit: 2,
|
||||
num: {:hook('seoBaiduTongji',['name'=>'tvt']) ?: 0},
|
||||
regulator: 50
|
||||
})
|
||||
regulator: 50
|
||||
})
|
||||
|
||||
var echartsRecords = echarts.init(document.getElementById('echarts-records'), 'walden');
|
||||
|
||||
@ -610,20 +610,20 @@
|
||||
$.get("{:url('system.upgrade/check')}",function (data){
|
||||
if (data.code === 1) {
|
||||
//可升级
|
||||
layer.confirm('发现新版本V' + data.data.version + ',确定升级?',{icon: 3, title:'系统检测'}, function(index){
|
||||
layer.confirm('发现新版本V' + data.data.version + ',确定升级?', {icon: 3, title:'系统检测'}, function(index){
|
||||
var loadIndex = layer.load(0);
|
||||
//更新
|
||||
$.get("{:url('system.upgrade/upload')}",function (res){
|
||||
layer.close(loadIndex)
|
||||
if (res.code === 0) {
|
||||
layer.close(index);
|
||||
toast.info({title:"通知消息", message: res.msg ,position: 'topRight'})
|
||||
} else {
|
||||
layer.close(index);
|
||||
toast.error({title:"服务器错误", message:res.msg})
|
||||
}
|
||||
return false;
|
||||
});
|
||||
//关闭load加载层
|
||||
layer.close(index);
|
||||
});
|
||||
|
||||
}
|
||||
});
|
||||
});
|
||||
|
@ -129,14 +129,14 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-card">
|
||||
<!-- <div class="layui-card">
|
||||
<div class="layui-card-header">
|
||||
使用记录
|
||||
</div>
|
||||
<div class="layui-card-body">
|
||||
<table id="role-table" lay-filter="role-table"></table>
|
||||
</div>
|
||||
</div>
|
||||
</div> -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -145,81 +145,13 @@
|
||||
<div class="layui-card-header">留言板</div>
|
||||
<div class="layui-card-body">
|
||||
<ul class="pear-card-status">
|
||||
{volist name="comments" id="vo"}
|
||||
<li>
|
||||
<p>要不要作为我的家人,搬来我家。</p>
|
||||
<span>12月25日 19:92</span>
|
||||
<a href="javascript:;" data-id="1"
|
||||
class="pear-btn pear-btn-primary pear-btn-xs pear-reply">回复</a>
|
||||
</li>
|
||||
<li>
|
||||
<p>快乐的时候不敢尽兴,频繁警戒自己保持清醒。</p>
|
||||
<span>4月30日 22:43</span>
|
||||
<a href="javascript:;" data-id="1"
|
||||
class="pear-btn pear-btn-primary pear-btn-xs pear-reply">回复</a>
|
||||
</li>
|
||||
<li>
|
||||
<p>夏天真的来了,尽管它还有些犹豫。</p>
|
||||
<span>4月30日 22:43</span>
|
||||
<a href="javascript:;" data-id="1"
|
||||
class="pear-btn pear-btn-primary pear-btn-xs pear-reply">回复</a>
|
||||
</li>
|
||||
<li>
|
||||
<p>看似不可达到的高度,只要坚持不懈就可能到达。</p>
|
||||
<span>4月30日 22:43</span>
|
||||
<a href="javascript:;" data-id="1"
|
||||
class="pear-btn pear-btn-primary pear-btn-xs pear-reply">回复</a>
|
||||
</li>
|
||||
<li>
|
||||
<p>当浑浊变成了一种常态,那么清白就成了一种罪过。</p>
|
||||
<span>4月30日 22:43</span>
|
||||
<a href="javascript:;" data-id="1"
|
||||
class="pear-btn pear-btn-primary pear-btn-xs pear-reply">回复</a>
|
||||
</li>
|
||||
<li>
|
||||
<p>那是一种内在的东西,他们到达不了,也无法触及!</p>
|
||||
<span>5月12日 01:25</span>
|
||||
<a href="javascript:;" data-id="1"
|
||||
class="pear-btn pear-btn-primary pear-btn-xs pear-reply">回复</a>
|
||||
</li>
|
||||
</li>
|
||||
<li>
|
||||
<p>希望是一个好东西,也许是最好的,好东西是不会消亡的!</p>
|
||||
<span>6月11日 15:33</span>
|
||||
<a href="javascript:;" data-id="1"
|
||||
class="pear-btn pear-btn-primary pear-btn-xs pear-reply">回复</a>
|
||||
</li>
|
||||
<li>
|
||||
<p>一切都在不可避免的走向庸俗。</p>
|
||||
<span>2月09日 13:40</span>
|
||||
<a href="javascript:;" data-id="1"
|
||||
class="pear-btn pear-btn-primary pear-btn-xs pear-reply">回复</a>
|
||||
</li>
|
||||
<li>
|
||||
<p>路上没有灯火的时候,就点亮自己的头颅。</p>
|
||||
<span>3月11日 12:30</span>
|
||||
<a href="javascript:;" data-id="1"
|
||||
class="pear-btn pear-btn-primary pear-btn-xs pear-reply">回复</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<p>我们应该不虚度一生,应该能够说:"我已经做了我能做的事。"</p>
|
||||
<span>4月30日 22:43</span>
|
||||
<a href="javascript:;" data-id="1"
|
||||
class="pear-btn pear-btn-primary pear-btn-xs pear-reply">回复</a>
|
||||
</li>
|
||||
</li>
|
||||
<li>
|
||||
<p>接近,是我对一切的态度,是我对一切态度的距离</p>
|
||||
<span>6月11日 15:33</span>
|
||||
<a href="javascript:;" data-id="1"
|
||||
class="pear-btn pear-btn-primary pear-btn-xs pear-reply">回复</a>
|
||||
</li>
|
||||
<li>
|
||||
<p>没有锚的船当然也可以航行,只是紧张充满你的一生。</p>
|
||||
<span>2月09日 13:40</span>
|
||||
<a href="javascript:;" data-id="1"
|
||||
class="pear-btn pear-btn-primary pear-btn-xs pear-reply">回复</a>
|
||||
<p>{$vo.content|raw}</p>
|
||||
<span>{$vo.create_time}</span>
|
||||
<a href="{$vo.url}" data-id="{$vo.id}" target="_blank" class="pear-btn pear-btn-primary pear-btn-xs pear-reply">回复</a>
|
||||
</li>
|
||||
{/volist}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -12,6 +12,7 @@
|
||||
<meta charset="utf-8">
|
||||
<title>{block name="title"}TaoLerCMS后台管理系统{/block}</title>
|
||||
<link rel="stylesheet" href="/static/component/pear/css/pear.css" />
|
||||
{block name="head"}内容{/block}
|
||||
</head>
|
||||
<body class="pear-container">
|
||||
{block name="body"}内容{/block}
|
||||
|
@ -4,6 +4,7 @@
|
||||
<meta charset="utf-8">
|
||||
<title>{block name="title"}TaoLerCMS后台管理系统{/block}</title>
|
||||
<link rel="stylesheet" href="/static/component/pear/css/pear.css" />
|
||||
{block name="link"}{/block}
|
||||
</head>
|
||||
<body>
|
||||
{block name="body"}内容{/block}
|
||||
|
@ -29,21 +29,16 @@
|
||||
归档
|
||||
</div>
|
||||
<div class="layui-card-body">
|
||||
<ul class="list">
|
||||
<!-- <ul class="list">
|
||||
<li class="list-item"><span class="title">优化代码格式</span><span class="footer">2020-06-04 11:28</span></li>
|
||||
<li class="list-item"><span class="title">新增消息组件</span><span class="footer">2020-06-01 04:23</span></li>
|
||||
<li class="list-item"><span class="title">移动端兼容</span><span class="footer">2020-05-22 21:38</span></li>
|
||||
<li class="list-item"><span class="title">系统布局优化</span><span class="footer">2020-05-15 14:26</span></li>
|
||||
<li class="list-item"><span class="title">兼容多系统菜单模式</span><span class="footer">2020-05-13 16:32</span></li>
|
||||
<li class="list-item"><span class="title">兼容多标签页切换</span><span class="footer">2019-12-9 14:58</span></li>
|
||||
<li class="list-item"><span class="title">扩展下拉组件</span><span class="footer">2019-12-7 9:06</span></li>
|
||||
<li class="list-item"><span class="title">扩展卡片样式</span><span class="footer">2019-12-1 10:26</span></li>
|
||||
</ul>
|
||||
</ul> -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-col-md9">
|
||||
<div class="layui-card">
|
||||
<!-- <div class="layui-card">
|
||||
<div class="layui-card-header">
|
||||
我的文章
|
||||
</div>
|
||||
@ -51,6 +46,7 @@
|
||||
<div class="layui-tab layui-tab-brief" lay-filter="docDemoTabBrief">
|
||||
<div class="layui-tab-content">
|
||||
<div class="layui-tab-item layui-show">
|
||||
|
||||
<div class="layui-row layui-col-space10" style="margin: 15px;">
|
||||
<div class="layui-col-md1">
|
||||
<img src="/static/admin/images/act.jpg" style="width: 100%;height: 100%;border-radius: 5px;" />
|
||||
@ -63,83 +59,13 @@
|
||||
<div class="comment">2020-06-12 评论 5 点赞 12 转发 4</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-row layui-col-space10" style="margin: 15px;">
|
||||
<div class="layui-col-md1">
|
||||
<img src="/static/admin/images/act.jpg" style="width: 100%;height: 100%;border-radius: 5px;" />
|
||||
</div>
|
||||
<div class="layui-col-md11" style="height: 80px;">
|
||||
<div class="title">为什么程序员们愿意在GitHub上开源自己的成果给别人免费使用和学习?</div>
|
||||
<div class="content">
|
||||
“Git的精髓在于让所有人的贡献无缝合并。而GitHub的天才之处,在于理解了Git的精髓。”来一句我们程序员们接地气的话:分享是一种快乐~
|
||||
</div>
|
||||
<div class="comment">2020-06-12 评论 5 点赞 12 转发 4</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-row layui-col-space10" style="margin: 15px;">
|
||||
<div class="layui-col-md1">
|
||||
<img src="/static/admin/images/act.jpg" style="width: 100%;height: 100%;border-radius: 5px;" />
|
||||
</div>
|
||||
<div class="layui-col-md11" style="height: 80px;">
|
||||
<div class="title">为什么程序员们愿意在GitHub上开源自己的成果给别人免费使用和学习?</div>
|
||||
<div class="content">
|
||||
“Git的精髓在于让所有人的贡献无缝合并。而GitHub的天才之处,在于理解了Git的精髓。”来一句我们程序员们接地气的话:分享是一种快乐~
|
||||
</div>
|
||||
<div class="comment">2020-06-12 评论 5 点赞 12 转发 4</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-row layui-col-space10" style="margin: 15px;">
|
||||
<div class="layui-col-md1">
|
||||
<img src="/static/admin/images/act.jpg" style="width: 100%;height: 100%;border-radius: 5px;" />
|
||||
</div>
|
||||
<div class="layui-col-md11" style="height: 80px;">
|
||||
<div class="title">为什么程序员们愿意在GitHub上开源自己的成果给别人免费使用和学习?</div>
|
||||
<div class="content">
|
||||
“Git的精髓在于让所有人的贡献无缝合并。而GitHub的天才之处,在于理解了Git的精髓。”来一句我们程序员们接地气的话:分享是一种快乐~
|
||||
</div>
|
||||
<div class="comment">2020-06-12 评论 5 点赞 12 转发 4</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-row layui-col-space10" style="margin: 15px;">
|
||||
<div class="layui-col-md1">
|
||||
<img src="/static/admin/images/act.jpg" style="width: 100%;height: 100%;border-radius: 5px;" />
|
||||
</div>
|
||||
<div class="layui-col-md11" style="height: 80px;">
|
||||
<div class="title">为什么程序员们愿意在GitHub上开源自己的成果给别人免费使用和学习?</div>
|
||||
<div class="content">
|
||||
“Git的精髓在于让所有人的贡献无缝合并。而GitHub的天才之处,在于理解了Git的精髓。”来一句我们程序员们接地气的话:分享是一种快乐~
|
||||
</div>
|
||||
<div class="comment">2020-06-12 评论 5 点赞 12 转发 4</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-row layui-col-space10" style="margin: 15px;">
|
||||
<div class="layui-col-md1">
|
||||
<img src="/static/admin/images/act.jpg" style="width: 100%;height: 100%;border-radius: 5px;" />
|
||||
</div>
|
||||
<div class="layui-col-md11" style="height: 80px;">
|
||||
<div class="title">为什么程序员们愿意在GitHub上开源自己的成果给别人免费使用和学习?</div>
|
||||
<div class="content">
|
||||
“Git的精髓在于让所有人的贡献无缝合并。而GitHub的天才之处,在于理解了Git的精髓。”来一句我们程序员们接地气的话:分享是一种快乐~
|
||||
</div>
|
||||
<div class="comment">2020-06-12 评论 5 点赞 12 转发 4</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-row layui-col-space10" style="margin: 15px;">
|
||||
<div class="layui-col-md1">
|
||||
<img src="/static/admin/images/act.jpg" style="width: 100%;height: 100%;border-radius: 5px;" />
|
||||
</div>
|
||||
<div class="layui-col-md11" style="height: 80px;">
|
||||
<div class="title">为什么程序员们愿意在GitHub上开源自己的成果给别人免费使用和学习?</div>
|
||||
<div class="content">
|
||||
“Git的精髓在于让所有人的贡献无缝合并。而GitHub的天才之处,在于理解了Git的精髓。”来一句我们程序员们接地气的话:分享是一种快乐~
|
||||
</div>
|
||||
<div class="comment">2020-06-12 评论 5 点赞 12 转发 4</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div> -->
|
||||
</div>
|
||||
</div>
|
||||
<script src="/static/component/layui/layui.js"></script>
|
||||
|
@ -23,21 +23,21 @@
|
||||
<label class="layui-form-label">邮箱</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="email" value="{$user.email}" lay-verify="title"
|
||||
autocomplete="off" placeholder="请输入标题" class="layui-input">
|
||||
autocomplete="off" placeholder="请输入邮箱" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">密码</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="password" value="" lay-verify="title" autocomplete="off"
|
||||
placeholder="请输入标题" class="layui-input">
|
||||
placeholder="请输入密码" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">电话</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="phone" value="{$user.phone}" lay-verify="title" autocomplete="off"
|
||||
placeholder="请输入标题" class="layui-input">
|
||||
placeholder="请输入电话" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
|
@ -63,6 +63,7 @@
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-body">
|
||||
<table id="user-table" lay-filter="user-table"></table>
|
||||
@ -80,7 +81,15 @@
|
||||
</button>
|
||||
</script>
|
||||
<script type="text/html" id="imgTpl">
|
||||
<img src= {{=d.avatar}} style="width: 30px; height: 30px;" />
|
||||
<a href="{:url('user.user/goUserHome')}?id={{ d.id }}" target="_blank"><img src= {{=d.avatar}} style="width: 100px; height: 100px; border-radius: 6px; object-fit: cover;"/></a>
|
||||
</script>
|
||||
<script type="text/html" id="userInfoTpl">
|
||||
<ul>
|
||||
<li>ID: {{d.id}} 用户名:{{d.username }}</li>
|
||||
<li>性别:{{#if (d.sex == 0) { }} <span>男</span> {{# }else if(d.sex == 1){ }} <span>女</span> {{# } }} 昵称:{{d.nickname}}</li>
|
||||
<li>电话:{{d.phone}}</li>
|
||||
<li>邮箱:{{d.email}}</li>
|
||||
</ul>
|
||||
</script>
|
||||
<script type="text/html" id="user-bar">
|
||||
<button class="pear-btn pear-btn-primary pear-btn-sm" lay-event="edit"><i class="layui-icon layui-icon-edit"></i></button>
|
||||
@ -98,27 +107,25 @@
|
||||
{if condition="checkRuleButton('user.user/auth')"}<input type="checkbox" name="auth" lay-skin="primary" lay-filter="auth" {{# if(d.auth ==1){ }}checked value="0"{{# } else { }}value="1"{{# } }} id="{{d.id}}" >{else}<button class="layui-btn layui-btn-xs layui-btn-disabled">无权限</button>{/if}
|
||||
{{# } }}
|
||||
</script>
|
||||
|
||||
<script type="text/html" id="user-sex">
|
||||
{{#if (d.sex == 0) { }}
|
||||
<span>男</span>
|
||||
{{# }else if(d.sex == 1){ }}
|
||||
<span>女</span>
|
||||
{{# } }}
|
||||
</script>
|
||||
|
||||
<script type="text/html" id="user-login">
|
||||
{{#if (d.login == 0) { }}
|
||||
<span>在线</span>
|
||||
{{# }else if(d.sex == 1){ }}
|
||||
<span>离线</span>
|
||||
{{# } }}
|
||||
<script type="text/html" id="userLoginTpl">
|
||||
<url>
|
||||
<li>ip:{{d.ip}}</li>
|
||||
<li>归属地:{{d.city}}</li>
|
||||
<li>{{d.logintime}}</li>
|
||||
</url>
|
||||
</script>
|
||||
|
||||
<script type="text/html" id="user-createTime">
|
||||
{{layui.util.toDateString(d.createTime, 'yyyy-MM-dd')}}
|
||||
</script>
|
||||
|
||||
<script type="text/html" id="TPL-dropdpwn-vip">
|
||||
<button class="layui-btn layui-btn-primary dropdpwn-demo">
|
||||
<span>{{= d.vip}}</span>
|
||||
<i class="layui-icon layui-icon-down layui-font-12"></i>
|
||||
</button>
|
||||
</script>
|
||||
|
||||
<script src="/static/component/layui/layui.js"></script>
|
||||
<script src="/static/component/pear/pear.js"></script>
|
||||
<script>
|
||||
@ -127,68 +134,48 @@
|
||||
let form = layui.form;
|
||||
let $ = layui.jquery;
|
||||
let common = layui.common;
|
||||
var dropdown = layui.dropdown;
|
||||
|
||||
let MODULE_PATH = "operate/";
|
||||
let MODULE_PATH = "operate/";
|
||||
|
||||
let cols = [
|
||||
[{
|
||||
[ {
|
||||
type: 'checkbox'
|
||||
},
|
||||
{
|
||||
title: 'id',
|
||||
field: 'id',
|
||||
align: 'center',
|
||||
width: 60
|
||||
},
|
||||
{
|
||||
title: '头像',
|
||||
field: 'avatar',
|
||||
align: 'center',
|
||||
width: 80,
|
||||
width: 150,
|
||||
templet: '#imgTpl'
|
||||
},
|
||||
{
|
||||
title: '用户',
|
||||
field: 'username',
|
||||
align: 'center',
|
||||
width: 100
|
||||
minWidth: 200,
|
||||
templet: '#userInfoTpl'
|
||||
},
|
||||
{
|
||||
title: '昵称',
|
||||
field: 'nick',
|
||||
align: 'center'
|
||||
},
|
||||
{
|
||||
title: '性别',
|
||||
field: 'sex',
|
||||
align: 'center',
|
||||
width: 80,
|
||||
templet: '#user-sex'
|
||||
},
|
||||
{
|
||||
title: '电话',
|
||||
field: 'phone',
|
||||
align: 'center'
|
||||
},
|
||||
{
|
||||
title: '邮箱',
|
||||
field: 'email',
|
||||
align: 'center'
|
||||
},
|
||||
{
|
||||
title: 'IP',
|
||||
title: '登录',
|
||||
field: 'ip',
|
||||
align: 'center'
|
||||
minWidth: 180,
|
||||
templet: '#userLoginTpl'
|
||||
},
|
||||
{
|
||||
title: '城市',
|
||||
field: 'city',
|
||||
align: 'center'
|
||||
title: '积分/金币',
|
||||
field: 'point',
|
||||
align: 'center',
|
||||
width: 120,
|
||||
edit: 'text'
|
||||
},
|
||||
{
|
||||
title: '登录时间',
|
||||
field: 'logintime',
|
||||
align: 'center'
|
||||
title: '会员等级/L',
|
||||
field: 'vip',
|
||||
align: 'center',
|
||||
width:180,
|
||||
unresize: true,
|
||||
align: 'center',
|
||||
templet: '#TPL-dropdpwn-vip'
|
||||
},
|
||||
{
|
||||
title: '状态',
|
||||
@ -197,12 +184,6 @@
|
||||
width: 95,
|
||||
templet: '#user-enable'
|
||||
},
|
||||
{
|
||||
title: '登录',
|
||||
field: 'login',
|
||||
align: 'center',
|
||||
templet: '#user-login'
|
||||
},
|
||||
{
|
||||
title: '超级管理',
|
||||
field: 'auth',
|
||||
@ -230,12 +211,54 @@
|
||||
cols: cols,
|
||||
skin: 'line',
|
||||
toolbar: '#user-toolbar',
|
||||
lineStyle: 'height: 160px;', // 定义表格的多行样式
|
||||
defaultToolbar: [{
|
||||
title: '刷新',
|
||||
layEvent: 'refresh',
|
||||
icon: 'layui-icon-refresh',
|
||||
}, 'filter', 'print', 'exports'],
|
||||
limit: 10
|
||||
limit: 10,
|
||||
done: function(res, curr, count){
|
||||
var options = this;
|
||||
|
||||
// 获取当前行数据
|
||||
table.getRowData = function(elem){
|
||||
var index = $(elem).closest('tr').data('index');
|
||||
return table.cache[options.id][index] || {};
|
||||
};
|
||||
|
||||
// dropdown 方式的下拉选择
|
||||
dropdown.render({
|
||||
elem: '.dropdpwn-demo',
|
||||
// trigger: 'hover',
|
||||
// 此处的 data 值,可根据 done 返回的 res 遍历来赋值
|
||||
data: res.viplist,
|
||||
click: function(obj){
|
||||
var data = table.getRowData(this.elem); // 获取当前行数据(如 id 等字段,以作为数据修改的索引)
|
||||
|
||||
this.elem.find('span').html(obj.title);
|
||||
// 更新数据中对应的字段
|
||||
data.vip = obj.title;
|
||||
console.log(data)
|
||||
$.ajax({
|
||||
type: "post",
|
||||
url: "{:url('user.user/editVipLevel')}",
|
||||
data: data,
|
||||
dataType: 'json',
|
||||
success: (res) => {
|
||||
if(res.code === 0) {
|
||||
layer.msg(res.msg, {icon: 1});
|
||||
} else {
|
||||
layer.msg(res.msg, {icon: 2});
|
||||
return false;
|
||||
}
|
||||
}
|
||||
})
|
||||
// 显示 - 仅用于演示
|
||||
//layer.msg('选中值: '+ obj.title +'<br>当前行数据:'+ JSON.stringify(data));
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
table.on('tool(user-table)', function(obj) {
|
||||
@ -256,6 +279,44 @@
|
||||
}
|
||||
});
|
||||
|
||||
// 单元格编辑后的事件
|
||||
table.on('edit(user-table)', function(obj){
|
||||
//var field = obj.field; // 得到修改的字段
|
||||
var value = obj.value // 得到修改后的值
|
||||
//var oldValue = obj.oldValue // 得到修改前的值 -- v2.8.0 新增
|
||||
var data = obj.data // 得到所在行所有键值
|
||||
//var col = obj.getCol(); // 得到当前列的表头配置属性 -- v2.8.0 新增
|
||||
|
||||
// 值的校验
|
||||
if(value.replace(/\s/g, '') === ''){
|
||||
layer.tips('值不能为空', this, {tips: 1});
|
||||
return obj.reedit(); // 重新编辑 -- v2.8.0 新增
|
||||
}
|
||||
// 只能为数值型
|
||||
if(isNaN(value)) {
|
||||
layer.tips('只能为数值', this, {tips: 1});
|
||||
return obj.reedit();
|
||||
}
|
||||
|
||||
// 编辑后续操作,如提交更新请求,以完成真实的数据更新
|
||||
$.ajax({
|
||||
type: "post",
|
||||
url: "{:url('user.user/editPoint')}",
|
||||
data: data,
|
||||
dataType: 'json',
|
||||
success: (res) => {
|
||||
if(res.code === 0) {
|
||||
layer.msg(res.msg, {icon: 1});
|
||||
} else {
|
||||
layer.msg(res.msg, {icon: 2});
|
||||
return false;
|
||||
}
|
||||
}
|
||||
})
|
||||
// …
|
||||
});
|
||||
|
||||
|
||||
form.on('submit(user-query)', function(data) {
|
||||
table.reload('user-table', {
|
||||
where: data.field
|
||||
|
@ -13,11 +13,11 @@
|
||||
<input type="text" name="id" class="layui-input" value="{$vip.id}">
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">Vip级别</label>
|
||||
<label class="layui-form-label">会员等级</label>
|
||||
<div class="layui-input-inline" >
|
||||
<select name="vip">
|
||||
{volist name="level" id="vo"}
|
||||
<option {if condition="$vip.vip eq $vo"} selected {/if} value="{$vo}">{if condition="$vo eq 0"}普通{else /}VIP{$vo}{/if}</option>
|
||||
<option {if condition="$vip.vip eq $vo"} selected {/if} value="{$vo}">{if condition="$vo eq 0"}普通{else /}L{$vo}{/if}</option>
|
||||
{/volist}
|
||||
</select>
|
||||
</div>
|
||||
@ -29,15 +29,33 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">认证</label>
|
||||
<label class="layui-form-label">认证昵称</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="text" name="nick" lay-verify="required" placeholder="等级昵称" autocomplete="off" class="layui-input" value="{$vip.nick}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">权限</label>
|
||||
<label class="layui-form-label">免费发帖/日</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="text" name="rules" lay-verify="" placeholder="请选择" autocomplete="off" class="layui-input" value="{$vip.rules}">
|
||||
<input type="text" name="postnum" lay-verify="number" placeholder="10" autocomplete="off" class="layui-input" value="{$vip.postnum}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">免费刷新/日</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="text" name="refreshnum" lay-verify="number" placeholder="10" autocomplete="off" class="layui-input" value="{$vip.refreshnum}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">发贴扣积分</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="text" name="postpoint" lay-verify="number" placeholder="10" autocomplete="off" class="layui-input" value="{$vip.postpoint}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">刷贴扣积分</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="text" name="refreshpoint" lay-verify="number" placeholder="10" autocomplete="off" class="layui-input" value="{$vip.refreshpoint}">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -77,9 +95,8 @@
|
||||
icon: 1,
|
||||
time: 1000
|
||||
}, function() {
|
||||
parent.layer.close(parent.layer.getFrameIndex(window
|
||||
.name)); //关闭当前页
|
||||
parent.layui.table.reload("vip-table");
|
||||
parent.layer.close(parent.layer.getFrameIndex(window.name)); //关闭当前页
|
||||
parent.layui.table.reload("vip-rule");
|
||||
});
|
||||
} else {
|
||||
layer.msg(result.msg, {
|
||||
|
@ -8,20 +8,14 @@
|
||||
</head>
|
||||
<body class="pear-container">
|
||||
<div class="layui-fluid" id="component-tabs">
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-body">
|
||||
<div class="layui-tab layui-tab-brief" lay-filter="server-tabs-brief">
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-body">
|
||||
<div class="layui-tab layui-tab-brief" lay-filter="server-tabs-brief" lay-allowclose="true">
|
||||
<ul class="layui-tab-title">
|
||||
{if hook('signstatushook') == 1}
|
||||
<li class="layui-this" lay-id="score">签到规则</li>
|
||||
{/if}
|
||||
<li lay-id="vip" class="{if hook('signstatushook') == 0} layui-this {/if}">用户等级</li>
|
||||
<li lay-id="vip" class="layui-this">用户等级</li>
|
||||
</ul>
|
||||
<div class="layui-tab-content">
|
||||
|
||||
{:hook('signadminhook')}
|
||||
|
||||
<div class="layui-tab-item {if hook('signstatushook') == 0}layui-show{/if}">
|
||||
<div class="layui-tab-item layui-show">
|
||||
<div class="layui-tab-content" style="padding: 20px 0;">
|
||||
<div class="layui-form">
|
||||
<div class="layui-form-item">
|
||||
@ -29,24 +23,37 @@
|
||||
<label class="layui-form-label">用户积分</label>
|
||||
<div class="layui-input-inline" style="width: 120px;">
|
||||
<select name="vip">
|
||||
<option value="0">普通</option>
|
||||
<option value="1">VIP1</option>
|
||||
<option value="2">VIP2</option>
|
||||
<option value="3">VIP3</option>
|
||||
<option value="4">VIP4</option>
|
||||
<option value="5">VIP5</option>
|
||||
|
||||
<option value="0">普通</option>
|
||||
<option value="1">L1</option>
|
||||
<option value="2">L2</option>
|
||||
<option value="3">L3</option>
|
||||
<option value="4">L4</option>
|
||||
<option value="5">L5</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="layui-input-inline">
|
||||
<input type="tel" name="score" lay-verify="required" placeholder="积分区间:0-99" autocomplete="off" class="layui-input">
|
||||
<input type="text" name="score" lay-verify="required" placeholder="积分区间:0-99" autocomplete="off" class="layui-input">
|
||||
</div>
|
||||
<div class="layui-input-inline">
|
||||
<input type="tel" name="nick" lay-verify="required" placeholder="认证名称" autocomplete="off" class="layui-input">
|
||||
<input type="text" name="nick" lay-verify="required" placeholder="认证名称" autocomplete="off" class="layui-input">
|
||||
</div>
|
||||
<div class="layui-input-inline">
|
||||
<input type="text" name="postnum" lay-verify="required|number" placeholder="免费发帖日限额" autocomplete="off" class="layui-input">
|
||||
</div>
|
||||
<div class="layui-input-inline">
|
||||
<input type="text" name="refreshnum" lay-verify="required|number" placeholder="免费刷新日限额" autocomplete="off" class="layui-input">
|
||||
</div>
|
||||
<div class="layui-input-inline">
|
||||
<input type="text" name="postpoint" lay-verify="required|number" placeholder="发帖扣积分" autocomplete="off" class="layui-input">
|
||||
</div>
|
||||
<div class="layui-input-inline">
|
||||
<input type="text" name="refreshpoint" lay-verify="required|number" placeholder="刷贴扣积分" autocomplete="off" class="layui-input">
|
||||
</div>
|
||||
<div class="layui-input-inline">
|
||||
<input type="submit" class="pear-btn pear-btn-primary" lay-submit lay-filter="vip-rule-submit" id="vip-rule-submit" value="立即提交">
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -59,6 +66,9 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{:hook('signadminhook')}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -75,6 +85,9 @@
|
||||
|
||||
let VIP_RULE = "{:url('user.vip/list')}";
|
||||
|
||||
// 渲染 tab 组件
|
||||
element.render('tab', 'server-tabs-brief');
|
||||
|
||||
//Vip规则
|
||||
table.render({
|
||||
elem: '#vip-rule',
|
||||
@ -84,7 +97,10 @@
|
||||
{field: 'vip',title: '等级'},
|
||||
{field: 'score',title: '积分'},
|
||||
{field: 'nick',title: '认证'},
|
||||
{field: 'rules',title: '权限'},
|
||||
{field: 'postnum',title: '免费发帖/日'},
|
||||
{field: 'refreshnum',title: '免费刷新/日'},
|
||||
{field: 'postpoint',title: '发帖扣积分'},
|
||||
{field: 'refreshpoint',title: '刷新扣积分'},
|
||||
{field: 'ctime',title: '时间'},
|
||||
{title: '操作', width: 150, align:'center', toolbar: '#vip-rule-bar'}
|
||||
|
||||
@ -111,23 +127,23 @@
|
||||
url:"{:url('user.vip/add')}",
|
||||
data:field,
|
||||
daType:"json",
|
||||
success:function (data){
|
||||
if (data.code == 0) {
|
||||
layer.msg(data.msg,{
|
||||
icon:6,
|
||||
time:2000
|
||||
}, function(){
|
||||
table.reload('vip-rule'); //数据刷新
|
||||
});
|
||||
} else {
|
||||
layer.open({
|
||||
title:'添加失败',
|
||||
content:data.msg,
|
||||
icon:5,
|
||||
anim:6
|
||||
});
|
||||
}
|
||||
success:function (res){
|
||||
if (res.code == 0) {
|
||||
layer.msg(res.msg,{
|
||||
icon:6,
|
||||
time:2000
|
||||
}, function(){
|
||||
table.reload('vip-rule'); //数据刷新
|
||||
});
|
||||
} else {
|
||||
layer.open({
|
||||
title:'添加失败',
|
||||
content:res.msg,
|
||||
icon:5,
|
||||
anim:6
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
return false;
|
||||
});
|
||||
@ -139,7 +155,7 @@
|
||||
type: 2,
|
||||
title: '修改',
|
||||
shade: 0.1,
|
||||
area: ['450px', '400px'],
|
||||
area: ['450px', '580px'],
|
||||
content: 'edit.html?id=' + obj.data.id
|
||||
});
|
||||
}
|
||||
|
@ -18,6 +18,8 @@ use think\facade\Db;
|
||||
use taoser\think\Auth;
|
||||
use taoler\com\Files;
|
||||
use think\facade\Lang;
|
||||
use think\facade\Cookie;
|
||||
use think\facade\Config;
|
||||
|
||||
/**
|
||||
* 控制器基础类
|
||||
@ -165,6 +167,31 @@ class AdminController extends \app\BaseController
|
||||
$articleUrl = (string) url('article_detail', ['id' => (int) $aid, 'ename'=> $ename]);
|
||||
}
|
||||
|
||||
return $this->appConver($appName, $articleUrl);
|
||||
|
||||
}
|
||||
|
||||
//后台管理用户的路由转换为前台用户中心的路由
|
||||
//直接登录用户中心
|
||||
protected function getUserHome($uid) {
|
||||
$user = Db::name('user')->field('id,name')->find($uid);
|
||||
$salt = Config::get('taoler.salt');
|
||||
$auth = md5($user['name'].$salt).":".$user['id'];
|
||||
Cookie::set('auth',$auth,604800);
|
||||
$url = (string) url('user/index');
|
||||
return $this->appConver('index', $url);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* APP应用转换,在后台admin应用转换为在其它app应用的路径
|
||||
* /admin/user/info转换为 /index/user/info
|
||||
* @param string $appName 要转换为哪个应用
|
||||
* @param string $url 路由地址
|
||||
* @return string
|
||||
*/
|
||||
public function appConver(string $appName, string $url) :string
|
||||
{
|
||||
// 判断应用是否绑定域名
|
||||
$app_bind = array_search($appName, config('app.domain_bind'));
|
||||
// 判断应用是否域名映射
|
||||
@ -179,43 +206,40 @@ class AdminController extends \app\BaseController
|
||||
if($bind_admin) {
|
||||
// 1.应用绑定了域名
|
||||
if($app_bind) {
|
||||
return $this->getDomain() . $articleUrl;
|
||||
return $this->getDomain() . $url;
|
||||
}
|
||||
// 2.应用进行了映射
|
||||
if($app_map){
|
||||
return $this->getDomain() . '/' . $appName . $articleUrl;
|
||||
return $this->getDomain() . '/' . $appName . $url;
|
||||
}
|
||||
// 3.应用未绑定域名也未进行映射
|
||||
return $this->getDomain() . '/' . $appName . $articleUrl;
|
||||
return $this->getDomain() . '/' . $appName . $url;
|
||||
}
|
||||
|
||||
//2.admin进行了映射
|
||||
if($map_admin) {
|
||||
// 1.应用绑定了域名
|
||||
if($app_bind) {
|
||||
return $this->getDomain() . str_replace($map_admin, '', $articleUrl);;
|
||||
return $this->getDomain() . str_replace($map_admin, '', $url);;
|
||||
}
|
||||
// 2.应用进行了映射
|
||||
if($app_map){
|
||||
return $this->getDomain() . str_replace($map_admin, $app_map, $articleUrl);
|
||||
return $this->getDomain() . str_replace($map_admin, $app_map, $url);
|
||||
}
|
||||
// 3.应用未绑定域名也未进行映射
|
||||
return $this->getDomain() . str_replace($map_admin, $appName, $articleUrl);
|
||||
return $this->getDomain() . str_replace($map_admin, $appName, $url);
|
||||
}
|
||||
//3.admin未绑定域名也未映射
|
||||
// 1.应用绑定了域名
|
||||
if($app_bind) {
|
||||
return $this->getDomain() . $articleUrl;
|
||||
return $this->getDomain() . $url;
|
||||
}
|
||||
// 2.应用进行了映射
|
||||
if($app_map){
|
||||
return $this->getDomain() . str_replace('admin', $app_map, $articleUrl);
|
||||
return $this->getDomain() . str_replace('admin', $app_map, $url);
|
||||
}
|
||||
return str_replace('admin', $appName, $articleUrl);
|
||||
return str_replace('admin', $appName, $url);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
@ -16,7 +16,6 @@ use think\facade\Request;
|
||||
use think\facade\View;
|
||||
use think\facade\Db;
|
||||
use think\facade\Session;
|
||||
use think\facade\Cache;
|
||||
use app\BaseController as BaseCtrl;
|
||||
|
||||
/**
|
||||
@ -25,14 +24,26 @@ use app\BaseController as BaseCtrl;
|
||||
class BaseController extends BaseCtrl
|
||||
{
|
||||
|
||||
protected $uid = '';
|
||||
/**
|
||||
* 登录用户uid
|
||||
*
|
||||
* @var int|null
|
||||
*/
|
||||
protected $uid;
|
||||
|
||||
/**
|
||||
* 登录用户信息
|
||||
*
|
||||
* @var array|object
|
||||
*/
|
||||
protected $user;
|
||||
|
||||
/**
|
||||
* 初始化系统,导航,用户
|
||||
*/
|
||||
protected function initialize()
|
||||
{
|
||||
$this->uid = Session::get('user_id');
|
||||
$this->setUid();
|
||||
//系统配置
|
||||
$this->showSystem();
|
||||
|
||||
@ -46,33 +57,32 @@ class BaseController extends BaseCtrl
|
||||
|
||||
}
|
||||
|
||||
//判断是否已登录?
|
||||
protected function isLogged()
|
||||
// 用户登录
|
||||
private function setUid()
|
||||
{
|
||||
if(Session::has('user_id')){
|
||||
$this->success('您已登录','/index/index/index');
|
||||
if(Session::has('user_id')) {
|
||||
$this->uid = Session::get('user_id') ?? -1;
|
||||
}
|
||||
}
|
||||
|
||||
//判断是否需要登录?
|
||||
protected function isLogin()
|
||||
{
|
||||
if(!Session::has('user_id')){
|
||||
$this->error('请登录','/index/user/login');
|
||||
}
|
||||
}
|
||||
private function setUser()
|
||||
{
|
||||
if(Session::has('user_id')) {
|
||||
$this->uid = Session::get('user_id') ?? -1;
|
||||
}
|
||||
}
|
||||
|
||||
// 显示子导航subnav
|
||||
protected function showSubnav()
|
||||
{
|
||||
$subCateList = []; // 没有点击任何分类,点击首页获取全部分类信息
|
||||
//1.查询父分类id
|
||||
$pCate = Db::name('cate')->field('id,pid,ename,catename,is_hot')->where(['ename'=>input('ename'),'status'=>1,'delete_time'=>0])->find();
|
||||
|
||||
if(empty($pCate)) { // 没有点击任何分类,点击首页获取全部分类信息
|
||||
$subCateList = [];
|
||||
} else { // 点击分类,获取子分类信息
|
||||
if(!is_null($pCate)) { // 点击分类,获取子分类信息
|
||||
$parentId = $pCate['id'];
|
||||
$subCate = Db::name('cate')->field('id,ename,catename,is_hot,pid')->where(['pid'=>$parentId,'status'=>1,'delete_time'=>0])->select()->toArray();
|
||||
|
||||
if(!empty($subCate)) { // 有子分类
|
||||
$subCateList = array2tree($subCate);
|
||||
} else { //无子分类
|
||||
@ -95,12 +105,13 @@ class BaseController extends BaseCtrl
|
||||
//显示当前登录用户
|
||||
protected function showUser($id)
|
||||
{
|
||||
$user = Cache::get('user'.$id);
|
||||
if(!$user){
|
||||
//1.查询用户
|
||||
$user = Db::name('user')->field('id,name,nickname,user_img,sex,area_id,auth,city,email,active,sign,point,vip,create_time')->find($id);
|
||||
Cache::tag('user')->set('user'.$id,$user,600);
|
||||
}
|
||||
if($id == -1) return [];
|
||||
//1.查询用户
|
||||
$user = Db::name('user')
|
||||
->alias('u')
|
||||
->join('user_viprule v','v.vip = u.vip')
|
||||
->field('u.id as id,v.id as vid,name,nickname,user_img,sex,area_id,auth,city,phone,email,active,sign,point,u.vip as vip,nick,u.create_time as create_time')
|
||||
->find((int)$id);
|
||||
return $user;
|
||||
}
|
||||
|
||||
|
@ -10,6 +10,14 @@ use think\response\Json;
|
||||
|
||||
class Arts
|
||||
{
|
||||
|
||||
/**
|
||||
* 数据内容
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $content = '';
|
||||
|
||||
//显示网站设置
|
||||
protected function getSystem()
|
||||
{
|
||||
@ -19,11 +27,17 @@ class Arts
|
||||
}
|
||||
|
||||
//域名协议转换 把数据库中的带HTTP或不带协议的域名转换为当前协议的域名前缀
|
||||
protected function getHttpUrl($url)
|
||||
{
|
||||
//域名转换为无http协议
|
||||
protected function getHttpUrl($url)
|
||||
{
|
||||
//域名转换为无http协议
|
||||
$www = stripos($url,'://') ? substr(stristr($url,'://'),3) : $url;
|
||||
return Request::scheme().'://'. $www;
|
||||
$htpw = Request::scheme().'://'. $www;
|
||||
return $htpw;
|
||||
}
|
||||
|
||||
protected function getDomain()
|
||||
{
|
||||
return $this->getHttpUrl($this->getSystem()['domain']);
|
||||
}
|
||||
|
||||
//得到当前系统安装前台域名
|
||||
@ -305,10 +319,10 @@ class Arts
|
||||
{
|
||||
$filename = pathinfo($url, PATHINFO_BASENAME);
|
||||
//$dirname = pathinfo(parse_url($url, PHP_URL_PATH), PATHINFO_DIRNAME);
|
||||
$dirname = date('Ymd',time());
|
||||
|
||||
$uid = session('user_id') ?: $userId;
|
||||
//路径
|
||||
$path = 'storage/' . $uid . '/article_pic/' . $dirname . '/';
|
||||
$path = 'storage/' . $uid . '/article_pic/' . date('Ymd',time()) . '/';
|
||||
//绝对文件夹
|
||||
$fileDir = public_path() . $path;
|
||||
//文件绝对路径
|
||||
@ -338,8 +352,9 @@ class Arts
|
||||
//下载网络图片到本地并替换
|
||||
public function downUrlPicsReaplace($content, $userId = 1)
|
||||
{
|
||||
$this->content = $content;
|
||||
// 批量下载网络图片并替换
|
||||
$images = $this->getArticleAllpic($content);
|
||||
$images = $this->getArticleAllpic($this->content);
|
||||
if(count($images)) {
|
||||
foreach($images as $image){
|
||||
//1.带http地址的图片,2.非本站的网络图片 3.非带有?号等参数的图片
|
||||
@ -348,13 +363,13 @@ class Arts
|
||||
//下载远程图片(可下载)
|
||||
$newImageUrl = $this->downloadImage($image, $userId);
|
||||
//替换图片链接
|
||||
$content = str_replace($image,Request::domain().$newImageUrl,$content);
|
||||
$this->content = str_replace($image,Request::domain().$newImageUrl,$this->content);
|
||||
}
|
||||
}
|
||||
//不可下载的图片,如加密或者带有参数的图片如?type=jpeg,直接返回content
|
||||
}
|
||||
|
||||
return $content;
|
||||
return $this->content;
|
||||
}
|
||||
|
||||
}
|
66
app/common/lib/JwtAuth.php
Normal file
66
app/common/lib/JwtAuth.php
Normal file
@ -0,0 +1,66 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\common\lib;
|
||||
|
||||
use Firebase\JWT\JWT;
|
||||
use Firebase\JWT\Key;
|
||||
|
||||
class JwtAuth
|
||||
{
|
||||
// 访问密钥
|
||||
const KEY = 'adsfhgkjl1324675809';
|
||||
// 签发者
|
||||
const ISS = 'www.aieok.com';
|
||||
// 接收者
|
||||
const AUD = 'www.aieok.com';
|
||||
// 加密算法
|
||||
const ALG = 'HS256';
|
||||
|
||||
/** 对数据进行编码
|
||||
* @param array $data
|
||||
*/
|
||||
|
||||
public static function encode(array $data)
|
||||
{
|
||||
$time = time();
|
||||
$payload = [
|
||||
"iss" => self::ISS,
|
||||
"aud" => self::AUD,
|
||||
"iat" => $time,
|
||||
"nbf" => $time,
|
||||
'exp' => $time + 86400 * 30,
|
||||
'data' => $data,
|
||||
];
|
||||
$token = JWT::encode($payload, self::KEY, self::ALG);
|
||||
return $token;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* 对 token 进行编码验证
|
||||
* @param string $token
|
||||
* @param integer $user_id
|
||||
*/
|
||||
public static function decode(string $token)
|
||||
{
|
||||
try {
|
||||
// 对 token 进行编码
|
||||
$decoded = JWT::decode($token, new Key(self::KEY, self::ALG));
|
||||
// 检测 token 附加数据中是否存在用户id
|
||||
if (!empty($decoded->data->uid)) {
|
||||
$data = $decoded->data;
|
||||
} else {
|
||||
throw new \Exception('token 中没有用户信息');
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
throw new \Exception($e->getMessage(), 201);
|
||||
}
|
||||
return $data; // 用户信息
|
||||
}
|
||||
|
||||
public static function getHeaderToken(array $header)
|
||||
{
|
||||
return str_replace('Bearer ', '', $header['authorization']);
|
||||
}
|
||||
}
|
@ -2,11 +2,11 @@
|
||||
/*
|
||||
* @Author: TaoLer <317927823@qq.com>
|
||||
* @Date: 2021-12-06 16:04:50
|
||||
* @LastEditTime: 2022-08-16 14:16:40
|
||||
* @LastEditTime: 2024-04-12 19:32:40
|
||||
* @LastEditors: TaoLer
|
||||
* @Description: 优化版
|
||||
* @FilePath: \TaoLer\app\common\lib\SqlFile.php
|
||||
* Copyright (c) 2020~2022 https://www.aieok.com All rights reserved.
|
||||
* Copyright (c) 2020~2024 https://www.aieok.com All rights reserved.
|
||||
*/
|
||||
declare (strict_types = 1);
|
||||
|
||||
@ -84,6 +84,9 @@ class SqlFile
|
||||
if (file_exists($sqlFile)) {
|
||||
$sqlArr = self::loadSqlFile($sqlFile);
|
||||
if(!empty($sqlArr)) {
|
||||
$orginal = 'tao_'; //sql默认表前缀
|
||||
$prefix = config('database.connections.mysql.prefix'); // 现在表前缀
|
||||
($orginal == $prefix) ? true : $sqlArr = str_replace(" `{$orginal}", " `{$prefix}", $sqlArr); //替换数组中表前缀
|
||||
foreach($sqlArr as $v){
|
||||
try {
|
||||
Db::execute($v);
|
||||
|
@ -155,6 +155,7 @@ class Uploads
|
||||
->check(['file'=>$file]);
|
||||
|
||||
} catch (ValidateException $e) {
|
||||
halt($e->getMessage());
|
||||
return json(['status'=>-1,'msg'=>$e->getMessage()]);
|
||||
}
|
||||
|
||||
@ -200,4 +201,75 @@ class Uploads
|
||||
return json(['status'=>0,'msg'=>'上传成功','url'=> $name_path, 'location'=>$name_path]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传文件
|
||||
* @param string $fileName 文件名
|
||||
* @param string $dirName 目录名
|
||||
* @param int $fileSize 文件大小
|
||||
* @param string $fileType 文件类型
|
||||
* @param string $rule 文件命名规则 默认md5,uniqid,date,sha1,_self为上传文件名称作为文件名,或者自定义如a.jpg文件名
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function put_api(string $fileName, string $dirName, int $fileSize, string $fileType, int $uid, string $rule = '' )
|
||||
{
|
||||
if(stripos($fileName,'http') !== false) {
|
||||
$file = $fileName;
|
||||
} else {
|
||||
$file = request()->file($fileName);
|
||||
}
|
||||
|
||||
$fileExt = $this->getFileInfo($fileType,'ext');
|
||||
$fileMime = $this->getFileInfo($fileType,'mime');
|
||||
|
||||
try {
|
||||
validate([$fileName=>['fileSize'=>$fileSize * 1024,'fileExt'=>$fileExt,'fileMime'=>$fileMime]])
|
||||
->check(['file'=>$file]);
|
||||
|
||||
} catch (ValidateException $e) {
|
||||
halt($e->getMessage());
|
||||
return json(['status'=>-1,'msg'=>$e->getMessage()]);
|
||||
}
|
||||
|
||||
// 解析存储位置 SYS_开头为系统位置
|
||||
$isSys = stripos($dirName, 'SYS_');
|
||||
if($isSys) {
|
||||
$disk = 'sys';
|
||||
$dirName = substr($dirName,4);
|
||||
$uploadDir = Config::get('filesystem.disks.sys.url');
|
||||
$path = DIRECTORY_SEPARATOR . $disk . DIRECTORY_SEPARATOR . $dirName . DIRECTORY_SEPARATOR . date('Ymd');
|
||||
} else {
|
||||
$disk = 'public';
|
||||
$dirName = $uid . DIRECTORY_SEPARATOR . $dirName;
|
||||
$uploadDir = Config::get('filesystem.disks.public.url');
|
||||
$path = DIRECTORY_SEPARATOR . 'storage' . DIRECTORY_SEPARATOR . $dirName . DIRECTORY_SEPARATOR . date('Ymd');
|
||||
}
|
||||
|
||||
$realPath = app()->getRootPath() . 'public' . $path;
|
||||
|
||||
$rules = ['md5','date','sha1','uniqid'];
|
||||
|
||||
try{
|
||||
// 解析是否自定义文件名
|
||||
if(in_array($rule, $rules)) {
|
||||
// rule命名
|
||||
$info = $file->move($realPath, $file->hashName($rule));
|
||||
} elseif(!empty($rule)) {
|
||||
// 自定义文件名
|
||||
if(stripos($rule, '_self')) {
|
||||
$info = $file->move($realPath, $file->getOriginalName());
|
||||
}
|
||||
$info = $file->move($realPath, $rule);
|
||||
} else {
|
||||
// 默认
|
||||
$info = $file->move($realPath, $file->hashName());
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
return json(['code' => -1, 'msg' => $e->getMessage()]);
|
||||
}
|
||||
|
||||
$name_path = str_replace('\\',"/", $path . '/' . $info->getBasename());
|
||||
|
||||
return json(['code' => 1,'msg'=>'上传成功', 'data' => ['url'=> $name_path]]);
|
||||
}
|
||||
|
||||
}
|
@ -7,6 +7,7 @@ use think\Model;
|
||||
use think\model\concern\SoftDelete;
|
||||
use think\facade\Cache;
|
||||
use think\facade\Config;
|
||||
use think\db\Query;
|
||||
|
||||
class Article extends Model
|
||||
{
|
||||
@ -109,20 +110,19 @@ class Article extends Model
|
||||
*/
|
||||
public function getArtTop(int $num)
|
||||
{
|
||||
|
||||
return Cache::remember('topArticle', function() use($num){
|
||||
return $this::field('id,title,title_color,cate_id,user_id,content,create_time,is_top,pv,upzip,has_img,has_video,has_audio,read_type,art_pass')
|
||||
->where([['is_top', '=', 1], ['status', '=', 1]])
|
||||
$topIdArr = $this::where(['is_top' => 1, 'status' => 1])->limit($num)->column('id');
|
||||
return $this::field('id,title,title_color,cate_id,user_id,create_time,is_top,pv,upzip,has_img,has_video,has_audio,read_type')
|
||||
->where('id', 'in', $topIdArr)
|
||||
->with([
|
||||
'cate' => function ($query) {
|
||||
$query->where('delete_time', 0)->field('id,catename,ename');
|
||||
'cate' => function (Query $query) {
|
||||
$query->field('id,catename,ename');
|
||||
},
|
||||
'user' => function ($query) {
|
||||
'user' => function (Query $query) {
|
||||
$query->field('id,name,nickname,user_img');
|
||||
}
|
||||
])->withCount(['comments'])
|
||||
->order('create_time', 'desc')
|
||||
->limit($num)
|
||||
->order('id', 'desc')
|
||||
->append(['url'])
|
||||
->select()
|
||||
->toArray();
|
||||
@ -140,28 +140,30 @@ class Article extends Model
|
||||
public function getArtList(int $num)
|
||||
{
|
||||
return Cache::remember('indexArticle', function() use($num){
|
||||
return $this::field('id,title,title_color,cate_id,user_id,content,create_time,is_hot,pv,jie,upzip,has_img,has_video,has_audio,read_type,art_pass')
|
||||
$data = $this::field('id,title,title_color,cate_id,user_id,content,create_time,is_hot,pv,jie,upzip,has_img,has_video,has_audio,read_type,art_pass')
|
||||
->with([
|
||||
'cate' => function($query){
|
||||
$query->where('delete_time',0)->field('id,catename,ename,detpl');
|
||||
'cate' => function(Query $query){
|
||||
$query->field('id,catename,ename,detpl');
|
||||
},
|
||||
'user' => function($query){
|
||||
'user' => function(Query $query){
|
||||
$query->field('id,name,nickname,user_img');
|
||||
} ])
|
||||
->withCount(['comments'])
|
||||
->where('status', '=', 1)
|
||||
->order('create_time','desc')
|
||||
->order('id','desc')
|
||||
->limit($num)
|
||||
->hidden(['art_pass'])
|
||||
->append(['url'])
|
||||
->select()
|
||||
->toArray();
|
||||
->select();
|
||||
|
||||
return $data->hidden(['art_pass'])->toArray();
|
||||
},30);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 热点文章
|
||||
* @param int $num 热点列表数量
|
||||
* @param int $num 热点列表数量 评论或者pv排序
|
||||
* @return \think\Collection
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
@ -169,20 +171,47 @@ class Article extends Model
|
||||
*/
|
||||
public function getArtHot(int $num)
|
||||
{
|
||||
$artHot = $this::field('id,cate_id,title,create_time')
|
||||
->with(['cate' => function($query){
|
||||
$query->where('delete_time',0)->field('id,ename');
|
||||
}])
|
||||
->withCount('comments')
|
||||
->where(['status'=>1,'delete_time'=>0])
|
||||
->whereTime('create_time', 'year')
|
||||
->order('comments_count','desc')
|
||||
return Cache::remember('article_hot', function() use($num){
|
||||
$comments = Comment::field('article_id,count(*) as count')
|
||||
->hasWhere('article',['status' => 1])
|
||||
->group('article_id')
|
||||
->order('count','desc')
|
||||
->limit($num)
|
||||
->withCache(120)
|
||||
->append(['url'])
|
||||
->select();
|
||||
$idArr = [];
|
||||
foreach($comments as $v) {
|
||||
$idArr[] = $v->article_id;
|
||||
}
|
||||
$where = [];
|
||||
if(count($idArr)) {
|
||||
// 评论数
|
||||
$where = [
|
||||
['id', 'in', $idArr]
|
||||
];
|
||||
|
||||
return $artHot;
|
||||
$artHot = $this::field('id,cate_id,title,create_time')
|
||||
->withCount('comments')
|
||||
->where($where)
|
||||
//->whereYear('create_time')
|
||||
// ->order('comments_count','desc')
|
||||
->append(['url'])
|
||||
->select();
|
||||
} else {
|
||||
// pv数
|
||||
$where = [
|
||||
['status', '=', 1]
|
||||
];
|
||||
$artHot = $this::field('id,cate_id,title,create_time')
|
||||
->withCount('comments')
|
||||
->where($where)
|
||||
->whereMonth('create_time')
|
||||
->order('pv','desc')
|
||||
->limit($num)
|
||||
->append(['url'])
|
||||
->select();
|
||||
}
|
||||
return $artHot;
|
||||
}, 3600);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -198,14 +227,15 @@ class Article extends Model
|
||||
return $this::field('id,title,content,status,cate_id,user_id,goods_detail_id,is_top,is_hot,is_reply,pv,jie,upzip,downloads,keywords,description,read_type,art_pass,title_color,create_time,update_time')
|
||||
->where(['status'=>1])
|
||||
->with([
|
||||
'cate' => function($query){
|
||||
$query->where('delete_time',0)->field('id,catename,ename');
|
||||
'cate' => function(Query $query){
|
||||
$query->field('id,catename,ename');
|
||||
},
|
||||
'user' => function($query){
|
||||
'user' => function(Query $query){
|
||||
$query->field('id,name,nickname,user_img,area_id,vip,city')->withCount(['article','comments']);
|
||||
}
|
||||
])
|
||||
->withCount(['comments'])
|
||||
->hidden(['art_pass'])
|
||||
->append(['url'])
|
||||
->find($id);
|
||||
|
||||
@ -223,12 +253,6 @@ class Article extends Model
|
||||
*/
|
||||
public function getCateList(string $ename, string $type, int $page = 1)
|
||||
{
|
||||
$where = [];
|
||||
$cateId = Cate::where('ename',$ename)->value('id');
|
||||
if($cateId){
|
||||
$where[] = ['cate_id' ,'=', $cateId];
|
||||
}
|
||||
|
||||
switch ($type) {
|
||||
//查询文章,15个分1页
|
||||
case 'jie':
|
||||
@ -244,10 +268,28 @@ class Article extends Model
|
||||
$where[] = ['jie','=', 0];
|
||||
break;
|
||||
}
|
||||
|
||||
$where[] = ['status', '=', 1];
|
||||
|
||||
return Cache::remember('cate_list_'.$ename.$type.$page, function() use($where,$page){
|
||||
return $this::field('id,cate_id,user_id,title,content,title_color,create_time,is_top,is_hot,pv,jie,upzip,has_img,has_video,has_audio,read_type,art_pass')
|
||||
return Cache::remember('cate_list_'.$ename.$type.$page, function() use($where,$ename,$page){
|
||||
$cateId = Cate::where('ename',$ename)->value('id');
|
||||
if($cateId){
|
||||
$where[] = ['cate_id' ,'=', $cateId];
|
||||
}
|
||||
|
||||
$list = $this::field('id')->where($where)->order(['id'=>'desc'])->paginate([
|
||||
'list_rows' => 15,
|
||||
'page' => $page
|
||||
])->toArray();
|
||||
|
||||
$idArr = [];
|
||||
if($list['total'] > 0) {
|
||||
foreach($list['data'] as $v) {
|
||||
$idArr[] = $v['id'];
|
||||
}
|
||||
}
|
||||
|
||||
$data = $this::field('id,cate_id,user_id,title,content,title_color,create_time,is_top,is_hot,pv,jie,upzip,has_img,has_video,has_audio,read_type,art_pass')
|
||||
->with([
|
||||
'cate' => function($query) {
|
||||
$query->field('id,catename,ename');
|
||||
@ -256,13 +298,19 @@ class Article extends Model
|
||||
$query->field('id,name,nickname,user_img,vip');
|
||||
}
|
||||
])->withCount(['comments'])
|
||||
->where($where)
|
||||
->limit(15)
|
||||
->order(['create_time'=>'desc'])
|
||||
->paginate([
|
||||
'list_rows' => 15,
|
||||
'page' => $page
|
||||
])->append(['url'])->toArray();
|
||||
->where('id','in',$idArr)
|
||||
->order(['id'=>'desc'])
|
||||
->append(['url'])
|
||||
->hidden(['art_pass'])
|
||||
->select()
|
||||
->toArray();
|
||||
return [
|
||||
'total' => $list['total'],
|
||||
'per_page' => $list['per_page'],
|
||||
'current_page' => $list['current_page'],
|
||||
'last_page' => $list['last_page'],
|
||||
'data' => $data
|
||||
];
|
||||
}, 600);
|
||||
}
|
||||
|
||||
@ -270,11 +318,12 @@ class Article extends Model
|
||||
public function getUserArtList(int $id) {
|
||||
$userArtList = $this::field('id,cate_id,title,create_time,pv,is_hot')
|
||||
->with(['cate' => function($query){
|
||||
$query->where(['delete_time'=>0,'status'=>1])->field('id,ename');
|
||||
$query->where(['status'=>1])->field('id,ename');
|
||||
}])
|
||||
->where(['user_id' => $id,'status' => 1])
|
||||
->order(['create_time'=>'desc'])
|
||||
->order('id','desc')
|
||||
->append(['url'])
|
||||
->limit(25)
|
||||
->cache(3600)
|
||||
->select()
|
||||
->toArray();
|
||||
@ -295,10 +344,11 @@ class Article extends Model
|
||||
$map[] = ['title','like','%'.$keywords.'%'];
|
||||
$res = Article::where($map)
|
||||
->withCount('comments')
|
||||
->order('create_time','desc')
|
||||
->order('id','desc')
|
||||
->append(['url'])
|
||||
->paginate(10);
|
||||
return $res;
|
||||
|
||||
return $res;
|
||||
}
|
||||
}
|
||||
|
||||
@ -311,14 +361,17 @@ class Article extends Model
|
||||
*/
|
||||
public function getAllTags($tagId)
|
||||
{
|
||||
$allTags = $this::hasWhere('taglist',['tag_id'=>$tagId])
|
||||
$arrId = Taglist::where('tag_id', $tagId)->column('article_id');
|
||||
|
||||
$allTags = $this::field('id,user_id,cate_id,title,create_time,is_hot')->where('id','in', $arrId)
|
||||
->with(['user' => function($query){
|
||||
$query->field('id,name,nickname,user_img,area_id,vip');
|
||||
},'cate' => function($query){
|
||||
$query->where('delete_time',0)->field('id,catename,ename');
|
||||
$query->field('id,catename,ename');
|
||||
}])
|
||||
->where(['status'=>1])
|
||||
->order('pv desc')
|
||||
->order('id desc')
|
||||
->limit(20)
|
||||
->append(['url'])
|
||||
->select()
|
||||
->toArray();
|
||||
@ -335,14 +388,13 @@ class Article extends Model
|
||||
*/
|
||||
public function getRelationTags($tagId,$id,$limit)
|
||||
{
|
||||
$allTags = $this::hasWhere('taglist',['tag_id'=>$tagId])
|
||||
->with(['user' => function($query){
|
||||
$query->field('id,name,nickname,user_img,area_id,vip');
|
||||
},'cate' => function($query){
|
||||
$query->where('delete_time',0)->field('id,catename,ename');
|
||||
}])
|
||||
$arrId = Taglist::where([
|
||||
['tag_id', '=', $tagId],
|
||||
['article_id','<>',$id]
|
||||
])->column('article_id');
|
||||
|
||||
$allTags = $this::field('id,cate_id,title')->where('id', 'in', $arrId)
|
||||
->where(['status'=>1])
|
||||
// ->where('article.id', '<>', $id)
|
||||
->order('pv desc')
|
||||
->limit($limit)
|
||||
->append(['url'])
|
||||
@ -359,23 +411,33 @@ class Article extends Model
|
||||
* @param [type] $cid 当前分类ID
|
||||
* @return void|array
|
||||
*/
|
||||
public function getPrevNextArticle($id,$cid)
|
||||
public function getPrevNextArticle($id, $cid)
|
||||
{
|
||||
//上一篇
|
||||
$previous = $this::field('id,title,cate_id')
|
||||
->where([
|
||||
['id', '<', $id],
|
||||
$pIds = $this::where([
|
||||
['id', '>=', $id], // >= <= 条件可以使用索引
|
||||
['cate_id', '=', $cid],
|
||||
['status', '=',1]
|
||||
])->order('id desc')->limit(1)->append(['url'])->select()->toArray();
|
||||
])->order('id asc')->limit(2)->column('id');
|
||||
|
||||
if(count($pIds) === 2) {
|
||||
$previous = $this::field('id,title,cate_id')->append(['url'])->find($pIds[1])->toArray();
|
||||
} else {
|
||||
$previous = [];
|
||||
}
|
||||
|
||||
//下一篇
|
||||
$next = $this::field('id,title,cate_id')
|
||||
->where([
|
||||
['id', '>', $id],
|
||||
$nids = $this::where([
|
||||
['id', '<=', $id],
|
||||
['cate_id', '=', $cid],
|
||||
['status', '=',1]
|
||||
])->limit(1)->append(['url'])->select()->toArray();
|
||||
])->order('id desc')->limit(2)->column('id');
|
||||
|
||||
if(count($nids) === 2) {
|
||||
$next = $this::field('id,title,cate_id')->append(['url'])->find($nids[1])->toArray();
|
||||
} else {
|
||||
$next = [];
|
||||
}
|
||||
|
||||
return ['previous' => $previous, 'next' => $next];
|
||||
}
|
||||
@ -394,13 +456,33 @@ class Article extends Model
|
||||
])
|
||||
->where(['status' => 1])
|
||||
->where($where)
|
||||
->order('create_time', 'desc')
|
||||
->order('id', 'desc')
|
||||
->paginate([
|
||||
'list_rows' => $limit,
|
||||
'page' => $page
|
||||
])->toArray();
|
||||
}
|
||||
|
||||
// 获取admin应用所有帖子状态内容
|
||||
public function getAllStatusList(array $where, int $limit, int $page)
|
||||
{
|
||||
return $this::field('id,user_id,cate_id,title,content,is_top,is_hot,is_reply,status,update_time,read_type,art_pass')
|
||||
->with([
|
||||
'user' => function($query){
|
||||
$query->field('id,name,user_img');
|
||||
},
|
||||
'cate' => function($query){
|
||||
$query->field('id,ename,catename');
|
||||
}
|
||||
])
|
||||
->where($where)
|
||||
->order('id', 'desc')
|
||||
->paginate([
|
||||
'list_rows' => $limit,
|
||||
'page' => $page
|
||||
])->toArray();
|
||||
}
|
||||
|
||||
// 获取url
|
||||
public function getUrlAttr($value,$data)
|
||||
{
|
||||
|
@ -63,12 +63,12 @@ class Cate extends Model
|
||||
public function del($id)
|
||||
{
|
||||
$cates = $this->field('id,pid')->with('article')->find($id);
|
||||
$sonCate = $this->field('id,pid')->where('pid',$cates['id'])->find();
|
||||
if(empty($sonCate)) {
|
||||
$res = $cates->together(['article'])->delete();
|
||||
return $res ? 1 : '删除失败';
|
||||
$sonCate = $this::where('pid',$cates['id'])->count();
|
||||
if($sonCate > 0) {
|
||||
return '存在子分类,无法删除';
|
||||
}
|
||||
return '存在子分类,无法删除';
|
||||
$res = $cates->together(['article'])->delete();
|
||||
return $res ? 1 : '删除失败';
|
||||
}
|
||||
|
||||
// 分类表
|
||||
@ -89,7 +89,7 @@ class Cate extends Model
|
||||
{
|
||||
try {
|
||||
return $this->where(['status' => 1])
|
||||
->cache('catename', 3600)
|
||||
->cache(3600)
|
||||
->append(['url'])
|
||||
->select()
|
||||
->toArray();
|
||||
@ -104,7 +104,7 @@ class Cate extends Model
|
||||
{
|
||||
try {
|
||||
$cateList = $this->where(['status' => 1])
|
||||
->cache('catename', 3600)
|
||||
->cache(3600)
|
||||
->append(['url'])
|
||||
->select()
|
||||
->toArray();
|
||||
@ -121,11 +121,11 @@ class Cate extends Model
|
||||
public function getUrlAttr($value,$data)
|
||||
{
|
||||
// 栏目下存在帖子,则返回正常url,否则为死链
|
||||
$articleArr = Article::field('id')->where('cate_id', $data['id'])->find();
|
||||
if(empty($articleArr)) {
|
||||
return 'javascript:void(0);';
|
||||
$articleCount = Article::where('cate_id', $data['id'])->count();
|
||||
if($articleCount > 0) {
|
||||
return (string) url('cate',['ename' => $data['ename']]);
|
||||
}
|
||||
return (string) url('cate',['ename' => $data['ename']]);;
|
||||
return 'javascript:void(0);';
|
||||
}
|
||||
|
||||
|
||||
|
@ -97,7 +97,7 @@ class Comment extends Model
|
||||
$res['data'][] = $u;
|
||||
}
|
||||
} else {
|
||||
$res = ['status' => 0, 'msg' =>'no reply'];
|
||||
$res = ['status' => -1, 'msg' =>'no reply'];
|
||||
}
|
||||
return json($res);
|
||||
}
|
||||
|
@ -33,12 +33,11 @@ class MessageTo extends Model
|
||||
//得到消息数
|
||||
public function getMsgNum($id)
|
||||
{
|
||||
$msg = $this::where(['receve_id'=>$id,'is_read'=>0])->column('id');
|
||||
if($num = count($msg)) {
|
||||
return $num;
|
||||
} else {
|
||||
return 0;
|
||||
$msgNum = $this::where(['receve_id'=>$id,'is_read'=>0])->count('id');
|
||||
if($msgNum) {
|
||||
return $msgNum;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -127,6 +127,7 @@ class User extends Model
|
||||
$salt = substr(md5($data['create_time']),-6);
|
||||
$data['password'] = substr_replace(md5($data['password']),$salt,0,6);
|
||||
$data['status'] = Config::get('taoler.config.regist_check');
|
||||
$data['nickname'] = $data['name'];
|
||||
$msg = $data['status'] ? '注册成功请登录' : '注册成功,请等待审核';
|
||||
$result = $this->save($data);
|
||||
if ($result) {
|
||||
|
@ -24,7 +24,7 @@ class UserViprule extends Model
|
||||
//获取等级名
|
||||
public function getVipAttr($value)
|
||||
{
|
||||
$vip = [0=>'普通',1=>'VIP1',2=>'VIP2',3=>'VIP3',4=>'VIP4',5=>'VIP5'];
|
||||
$vip = [0=>'普通',1=>'L1',2=>'L2',3=>'L3',4=>'L4',5=>'L5'];
|
||||
return $vip[$value];
|
||||
}
|
||||
|
||||
|
@ -30,6 +30,7 @@ class Article extends TagLib
|
||||
'description' => ['attr' => '', 'close' => 0],
|
||||
'link' => ['attr' => '', 'close' => 0],
|
||||
'time' => ['attr' => '', 'close' => 0],
|
||||
'uptime' => ['attr' => '', 'close' => 0],
|
||||
|
||||
'cate' => ['attr' => 'name', 'close' => 0],
|
||||
'user' => ['attr' => 'name', 'close' => 0],
|
||||
@ -102,6 +103,11 @@ class Article extends TagLib
|
||||
return '{$article.create_time}';
|
||||
}
|
||||
|
||||
public function tagUptime(): string
|
||||
{
|
||||
return '{$article.update_time}';
|
||||
}
|
||||
|
||||
// 详情分类
|
||||
public function tagCate($tag): string
|
||||
{
|
||||
|
3
app/index/controller/.gitignore
vendored
3
app/index/controller/.gitignore
vendored
@ -1,2 +1,3 @@
|
||||
Api.php
|
||||
Works.php
|
||||
Works.php
|
||||
Shop.php
|
@ -50,18 +50,19 @@ class Article extends BaseController
|
||||
|
||||
//分类列表
|
||||
$artList = $this->model->getCateList($ename,$type,$page);
|
||||
// halt($artList);
|
||||
// 热议文章
|
||||
$artHot = $this->model->getArtHot(10);
|
||||
|
||||
|
||||
$assignArr = [
|
||||
'ename'=>$ename,
|
||||
'cateinfo'=> $cateInfo,
|
||||
'type'=>$type,
|
||||
'artList'=>$artList,
|
||||
'artHot'=>$artHot,
|
||||
'path'=>$path,
|
||||
'jspage'=>'jie'
|
||||
'ename' => $ename,
|
||||
'cateinfo' => $cateInfo,
|
||||
'type' => $type,
|
||||
'artList' => $artList,
|
||||
'artHot' => $artHot,
|
||||
'path' => $path,
|
||||
'jspage' => 'jie'
|
||||
];
|
||||
View::assign($assignArr);
|
||||
|
||||
@ -96,8 +97,8 @@ class Article extends BaseController
|
||||
|
||||
// 标签
|
||||
$tags = [];
|
||||
$relationArticle = [];
|
||||
$artTags = Db::name('taglist')->where('article_id',$id)->select();
|
||||
$relationArticle = []; //相关帖子
|
||||
$artTags = Db::name('taglist')->where('article_id', $id)->select();
|
||||
if(count($artTags)) {
|
||||
foreach($artTags as $v) {
|
||||
$tag = Db::name('tag')->find($v['tag_id']);
|
||||
@ -118,15 +119,15 @@ class Article extends BaseController
|
||||
|
||||
//上一篇下一篇
|
||||
$upDownArt = $this->model->getPrevNextArticle($id,$artDetail['cate_id']);
|
||||
if(empty($upDownArt['previous'][0])) {
|
||||
if(empty($upDownArt['previous'])) {
|
||||
$previous = '前面已经没有了!';
|
||||
} else {
|
||||
$previous = '<a href="' . $upDownArt['previous'][0]['url'] . '" rel="prev">' . $upDownArt['previous'][0]['title'] . '</a>';
|
||||
$previous = '<a href="' . $upDownArt['previous']['url'] . '" rel="prev">' . $upDownArt['previous']['title'] . '</a>';
|
||||
}
|
||||
if(empty($upDownArt['next'][0])) {
|
||||
if(empty($upDownArt['next'])) {
|
||||
$next = '已经是最新的内容了!';
|
||||
} else {
|
||||
$next = '<a href="' . $upDownArt['next'][0]['url'] . '" rel="prev">' . $upDownArt['next'][0]['title'] . '</a>';
|
||||
$next = '<a href="' . $upDownArt['next']['url'] . '" rel="prev">' . $upDownArt['next']['title'] . '</a>';
|
||||
}
|
||||
|
||||
//评论
|
||||
@ -139,22 +140,22 @@ class Article extends BaseController
|
||||
$push_js = Db::name('push_jscode')->where(['delete_time'=>0,'type'=>1])->cache(true)->select();
|
||||
|
||||
View::assign([
|
||||
'article' => $artDetail,
|
||||
'pv' => $pv,
|
||||
'artHot' => $artHot,
|
||||
'tags' => $tags,
|
||||
'article' => $artDetail,
|
||||
'pv' => $pv,
|
||||
'artHot' => $artHot,
|
||||
'tags' => $tags,
|
||||
'relationArticle' => $relationArticle,
|
||||
'previous' => $previous,
|
||||
'next' => $next,
|
||||
'page' => $page,
|
||||
'comments' => $comments,
|
||||
'push_js' => $push_js,
|
||||
'cid' => $id,
|
||||
'lrDate_time' => $lrDate_time,
|
||||
'userZanList' => $userZanList,
|
||||
'zanCount' => $zanCount,
|
||||
'jspage' => 'jie',
|
||||
'passJieMi' => session('art_pass_'.$id),
|
||||
'previous' => $previous,
|
||||
'next' => $next,
|
||||
'page' => $page,
|
||||
'comments' => $comments,
|
||||
'push_js' => $push_js,
|
||||
'cid' => $id,
|
||||
'lrDate_time' => $lrDate_time,
|
||||
'userZanList' => $userZanList,
|
||||
'zanCount' => $zanCount,
|
||||
'jspage' => 'jie',
|
||||
'passJieMi' => session('art_pass_'.$id),
|
||||
$download,
|
||||
]);
|
||||
|
||||
@ -179,7 +180,7 @@ class Article extends BaseController
|
||||
$data = Request::only(['content','article_id','pid','to_user_id']);
|
||||
$data['user_id'] = $this->uid;
|
||||
$sendId = $data['user_id'];
|
||||
// halt($data);
|
||||
|
||||
$art = Db::name('article')->field('id,status,is_reply,delete_time')->find($data['article_id']);
|
||||
|
||||
if($art['delete_time'] != 0 || $art['status'] != 1 || $art['is_reply'] != 1){
|
||||
@ -229,6 +230,7 @@ class Article extends BaseController
|
||||
if (Request::isAjax()) {
|
||||
// 检验发帖是否开放
|
||||
if(config('taoler.config.is_post') == 0 ) return json(['code'=>-1,'msg'=>'抱歉,系统维护中,暂时禁止发帖!']);
|
||||
|
||||
// 数据
|
||||
$data = Request::only(['cate_id', 'title', 'title_color','read_type','art_pass', 'content', 'upzip', 'keywords', 'description', 'captcha']);
|
||||
$data['user_id'] = $this->uid;
|
||||
@ -252,7 +254,7 @@ class Article extends BaseController
|
||||
$iva= $this->hasIva($data['content']);
|
||||
$data = array_merge($data,$iva);
|
||||
|
||||
// 处理内容
|
||||
// 处理图片内容
|
||||
$data['content'] = $this->downUrlPicsReaplace($data['content']);
|
||||
// 把中文,转换为英文,并去空格->转为数组->去掉空数组->再转化为带,号的字符串
|
||||
$data['keywords'] = implode(',',array_filter(explode(',',trim(str_replace(',',',',$data['keywords'])))));
|
||||
@ -260,30 +262,61 @@ class Article extends BaseController
|
||||
// 获取分类ename,appname
|
||||
$cateName = Db::name('cate')->field('ename,appname')->find($data['cate_id']);
|
||||
|
||||
// vip每天可免费发帖数
|
||||
$user = Db::name('user')->field('id,vip,point,auth')->find($this->uid);
|
||||
|
||||
$postRule = Db::name('user_viprule')->field('postnum,postpoint')->where('vip', $user['vip'])->find();
|
||||
// 检测可发帖子剩余量
|
||||
$postLog = Db::name('user_article_log')->field('id,user_postnum')->where(['user_id' => $this->uid])->whereDay('create_time')->find();
|
||||
if(is_null($postLog)) {
|
||||
//没有记录创建
|
||||
Db::name('user_article_log')->save(['user_id' => $this->uid, 'create_time' => time()]);
|
||||
$postLog = Db::name('user_article_log')->field('id,user_postnum')->where(['user_id' => $this->uid])->whereDay('create_time')->find();
|
||||
}
|
||||
|
||||
// 超级管理员排外
|
||||
if($user['auth'] === '0') {
|
||||
$cannum = $postRule['postnum'] - $postLog['user_postnum']; // 可用免费额
|
||||
if($cannum <= 0) {
|
||||
//额度已用完需要扣积分
|
||||
$canpoint = 1 * $postRule['postpoint'];
|
||||
$point = $user['point'] - $canpoint;
|
||||
if($point < 0) { // 1.积分不足
|
||||
return json(['code' => -1, 'msg' => "免额已使用,本次需{$canpoint}积分,请充值!"]);
|
||||
}
|
||||
// 2.扣除积分
|
||||
Db::name('user')->where('id', $this->uid)->update(['point' => $point]);
|
||||
}
|
||||
}
|
||||
|
||||
$result = $this->model->add($data);
|
||||
if ($result['code'] == 1) {
|
||||
// 记录每天发帖量
|
||||
Db::name('user_article_log')->where('id', $postLog['id'])->inc('user_postnum')->update();
|
||||
// 获取到的最新ID
|
||||
$aid = $result['data']['id'];
|
||||
|
||||
//写入taglist表
|
||||
$tagArr = [];
|
||||
if(isset($tagId)) {
|
||||
$tagIdArr = explode(',',$tagId);
|
||||
if(!empty($tagId)) {
|
||||
$tagArr = [];
|
||||
$tagIdArr = explode(',', $tagId);
|
||||
foreach($tagIdArr as $tid) {
|
||||
$tagArr[] = ['article_id'=>$aid,'tag_id'=>$tid,'create_time'=>time()];
|
||||
$tagArr[] = [ 'article_id' => $aid, 'tag_id' => $tid, 'create_time'=>time()];
|
||||
}
|
||||
}
|
||||
Db::name('taglist')->insertAll($tagArr);
|
||||
Db::name('taglist')->insertAll($tagArr);
|
||||
}
|
||||
|
||||
// 清除文章tag缓存
|
||||
Cache::tag('tagArtDetail')->clear();
|
||||
// 发提醒邮件
|
||||
if(Config::get('taoler.config.email_notice')) hook('mailtohook',[$this->showUser(1)['email'],'发帖审核通知','Hi亲爱的管理员:</br>用户'.$this->showUser($this->uid)['name'].'刚刚发表了 <b>'.$data['title'].'</b> 新的帖子,请尽快处理。']);
|
||||
hook('mailtohook',[$this->showUser(1)['email'],'发帖审核通知','Hi亲爱的管理员:</br>用户'.$this->showUser($this->uid)['name'].'刚刚发表了 <b>'.$data['title'].'</b> 新的帖子,请尽快处理。']);
|
||||
|
||||
$link = $this->getRouteUrl((int)$aid, $cateName['ename']);
|
||||
$link = $this->getRouteUrl((int) $aid, $cateName['ename']);
|
||||
$url = $result['data']['status'] ? $link : (string)url('index/');
|
||||
|
||||
hook('SeoBaiduPush', ['link'=>$link]); // 推送给百度收录接口
|
||||
|
||||
$url = $result['data']['status'] ? $link : (string)url('index/');
|
||||
hook('callme_add', ['article_id' => (int) $aid]); // 添加文章的联系方式
|
||||
|
||||
return Msgres::success($result['msg'], $url);
|
||||
}
|
||||
return Msgres::error('add_error');
|
||||
@ -354,11 +387,11 @@ class Article extends BaseController
|
||||
$result = $article->edit($data);
|
||||
if($result == 1) {
|
||||
//处理标签
|
||||
$artTags = Db::name('taglist')->where('article_id',$id)->column('tag_id','id');
|
||||
if(isset($tagId)) {
|
||||
if(!empty($tagId)) {
|
||||
$tagIdArr = explode(',',$tagId);
|
||||
$artTags = Db::name('taglist')->where('article_id',$id)->column('tag_id','id');
|
||||
foreach($artTags as $aid => $tid) {
|
||||
if(!in_array($tid,$tagIdArr)){
|
||||
if(!in_array($tid, $tagIdArr)){
|
||||
//删除被取消的tag
|
||||
Db::name('taglist')->delete($aid);
|
||||
}
|
||||
@ -408,7 +441,7 @@ class Article extends BaseController
|
||||
*/
|
||||
public function delete()
|
||||
{
|
||||
$article = $this->model->find(input('id'));
|
||||
$article = $this->model->find((int)input('id'));
|
||||
$result = $article->together(['comments'])->delete();
|
||||
if($result) {
|
||||
return Msgres::success('delete_success');
|
||||
@ -436,11 +469,14 @@ class Article extends BaseController
|
||||
public function download($id)
|
||||
{
|
||||
$zipdir = Db::name('article')->where('id',$id)->value('upzip');
|
||||
$zip = substr($zipdir,1);
|
||||
Db::name('article')->cache(true)->where('id',$id)->inc('downloads')->update();
|
||||
//删除缓存显示下载后数据
|
||||
Cache::delete('article_'.$id);
|
||||
return download($zip,'my');
|
||||
if(!empty($zipdir)) {
|
||||
$zip = substr($zipdir,1);
|
||||
Db::name('article')->cache(true)->where('id',$id)->inc('downloads')->update();
|
||||
//删除缓存显示下载后数据
|
||||
Cache::delete('article_'.$id);
|
||||
return download($zip,'my');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 文章置顶、加精、评论状态
|
||||
|
@ -11,13 +11,15 @@
|
||||
namespace app\index\controller;
|
||||
|
||||
use app\common\controller\BaseController;
|
||||
use app\common\lib\facade\HttpHelper;
|
||||
use think\facade\View;
|
||||
use think\facade\Request;
|
||||
use think\facade\Db;
|
||||
use app\facade\Article;
|
||||
use app\common\lib\Msgres;
|
||||
|
||||
use addons\pay\controller\AlipayFactory;
|
||||
use addons\pay\controller\WeixinFactory;
|
||||
|
||||
class Index extends BaseController
|
||||
{
|
||||
/**
|
||||
@ -29,18 +31,31 @@ class Index extends BaseController
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
|
||||
// $res = get_addons_info('callme1');
|
||||
// halt($res);
|
||||
// $htmlString = "<p>这是一个<a href='http://example.com'>链接</a>和其他文本。</p>";
|
||||
// $cleanString = preg_replace("/<a\b[^>]*>(.*?)<\/a>/is", "", $htmlString);
|
||||
// //$cleanString = preg_replace("(<a [^>]*>|</a>)","",$htmlString);
|
||||
// echo $cleanString;
|
||||
|
||||
// $ip = file_get_contents('https://myip.ipip.net');
|
||||
// echo "My public IP address is: " . $ip;
|
||||
// $alipay = AlipayFactory::createPayMethod();
|
||||
// $weixin = WeixinFactory::createPayMethod();
|
||||
// $a = $alipay->index();
|
||||
// $b= $weixin->index();
|
||||
// var_dump($a,$b);
|
||||
|
||||
$types = input('type');
|
||||
//置顶文章
|
||||
$artTop = Article::getArtTop(5);
|
||||
//首页文章列表,显示10个
|
||||
$artList = Article::getArtList(15);
|
||||
//热议文章
|
||||
$artHot = Article::getArtHot(10);
|
||||
$artList = Article::getArtList(10);
|
||||
|
||||
$vs = [
|
||||
'artTop' => $artTop,
|
||||
'artList' => $artList,
|
||||
'artHot' => $artHot,
|
||||
'type' => $types,
|
||||
'jspage' => '',
|
||||
];
|
||||
@ -48,13 +63,6 @@ class Index extends BaseController
|
||||
|
||||
return View::fetch();
|
||||
}
|
||||
|
||||
//回帖榜
|
||||
public function reply()
|
||||
{
|
||||
$comment = new \app\common\model\Comment();
|
||||
return $comment->reply(20);
|
||||
}
|
||||
|
||||
public function jump()
|
||||
{
|
||||
|
@ -42,9 +42,8 @@ class Login extends BaseController
|
||||
// 检验登录是否开放
|
||||
if(config('taoler.config.is_login') == 0 ) return json(['code'=>-1,'msg'=>'抱歉,网站维护中,暂时不能登录哦!']);
|
||||
//登陆前数据校验
|
||||
$data = Request::param();
|
||||
if(Config::get('taoler.config.login_captcha') == 1)
|
||||
{
|
||||
$data = Request::only(['name','email','phone','password','captcha','remember']);
|
||||
if(Config::get('taoler.config.login_captcha') == 1) {
|
||||
//先校验验证码
|
||||
if(!captcha_check($data['captcha'])){
|
||||
// 验证失败
|
||||
@ -55,8 +54,7 @@ class Login extends BaseController
|
||||
//邮箱正则表达式
|
||||
$pattern = "/^([0-9A-Za-z\\-_\\.]+)@([0-9a-z]+\\.[a-z]{2,3}(\\.[a-z]{2})?)$/i";
|
||||
|
||||
if(preg_match("/^1[34578]\d{9}$/",$data['name']))
|
||||
{
|
||||
if(preg_match("/^1[34578]\d{9}$/",$data['name'])) {
|
||||
//手机验证登录
|
||||
$data['phone'] = $data['name'];
|
||||
unset($data['name']);
|
||||
|
@ -11,7 +11,6 @@
|
||||
namespace app\index\controller;
|
||||
|
||||
use app\common\controller\BaseController;
|
||||
use think\facade\Session;
|
||||
use think\facade\Request;
|
||||
use think\facade\Db;
|
||||
use app\common\model\Message as MessageModel;
|
||||
@ -25,12 +24,8 @@ class Message extends BaseController
|
||||
{
|
||||
$messgeto = new MessageTo();
|
||||
$num = $messgeto->getMsgNum($this->uid);
|
||||
if($num){
|
||||
$res = ['status' =>0,'count' => $num, 'msg' => 'ok'];
|
||||
} else {
|
||||
$res = ['status' =>0,'count' => 0, 'msg' => 'no message'];
|
||||
}
|
||||
return json($res);
|
||||
if($num) return json(['status' =>0,'count' => $num, 'msg' => 'ok']);
|
||||
return json(['status' =>0,'count' => 0, 'msg' => 'no message']);
|
||||
}
|
||||
|
||||
//消息查询
|
||||
@ -82,18 +77,20 @@ class Message extends BaseController
|
||||
$uid = $this->uid;
|
||||
|
||||
$id = Request::only(['id']);
|
||||
|
||||
if($id['id'] == 'true'){
|
||||
//删除所有此用户消息
|
||||
$msg = Db::name('message_to')->where(['receve_id'=>$uid,'delete_time'=>0])->useSoftDelete('delete_time',time())->delete();
|
||||
// id为'true' 删除所有此用户消息
|
||||
$msg = Db::name('message_to')->where(['receve_id' => $uid])->delete();
|
||||
} else {
|
||||
//删除单条消息
|
||||
$msg = Db::name('message_to')->where('id',$id['id'])->useSoftDelete('delete_time',time())->delete();
|
||||
$msg = Db::name('message_to')->where('id', $id['id'])->delete();
|
||||
}
|
||||
|
||||
if($msg){
|
||||
$res = ['status'=>0];
|
||||
return $res;
|
||||
}
|
||||
return $res;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
@ -15,7 +15,6 @@ use app\facade\Article;
|
||||
use think\facade\View;
|
||||
use think\facade\Request;
|
||||
use think\facade\Db;
|
||||
use app\common\model\Slider;
|
||||
use app\common\model\Tag as TagModel;
|
||||
|
||||
class Tag extends BaseController
|
||||
@ -31,22 +30,20 @@ class Tag extends BaseController
|
||||
{
|
||||
//
|
||||
$tagEname = Request::param('ename');
|
||||
$tag = Db::name('tag')->where('ename',$tagEname)->find();
|
||||
$tag = Db::name('tag')->where('ename', $tagEname)->find();
|
||||
|
||||
$artList = Article::getAllTags($tag['id']);
|
||||
$slider = new Slider();
|
||||
//首页右栏
|
||||
$ad_comm = $slider->getSliderList(2);
|
||||
|
||||
// 查询热议
|
||||
$artHot = Article::getArtHot(10);
|
||||
|
||||
$assign = [
|
||||
'tag'=>$tag,
|
||||
'artList'=>$artList,
|
||||
'ad_comm'=>$ad_comm,
|
||||
'artHot'=>$artHot,
|
||||
'jspage'=>''
|
||||
'tag' => $tag,
|
||||
'artList' => $artList,
|
||||
'artHot' => $artHot,
|
||||
'jspage' => ''
|
||||
];
|
||||
|
||||
View::assign($assign);
|
||||
return View::fetch('index');
|
||||
}
|
||||
|
@ -3,7 +3,6 @@ namespace app\index\controller;
|
||||
|
||||
use app\common\controller\BaseController;
|
||||
use app\common\validate\User as userValidate;
|
||||
use think\exception\ValidateException;
|
||||
use think\facade\Db;
|
||||
use think\facade\Request;
|
||||
use think\facade\Session;
|
||||
@ -13,7 +12,6 @@ use think\facade\View;
|
||||
use app\common\model\Article;
|
||||
use app\common\model\Collection;
|
||||
use app\common\model\User as userModel;
|
||||
use app\common\model\Comment;
|
||||
use taoler\com\Message;
|
||||
|
||||
class User extends BaseController
|
||||
@ -33,13 +31,13 @@ class User extends BaseController
|
||||
public function artList()
|
||||
{
|
||||
$param = Request::only(['page','limit']);
|
||||
$myArticle = Article::field('id,cate_id,title,status,pv,create_time')
|
||||
$myArticle = Article::field('id,cate_id,title,status,pv,create_time,update_time')
|
||||
->withCount(['comments'])
|
||||
->where(['user_id'=>$this->uid])
|
||||
->order('update_time','desc')
|
||||
->paginate([
|
||||
'list_rows' => $param['limit'],
|
||||
'page' => $param['page']
|
||||
'page' => $param['page']
|
||||
]);
|
||||
$count = $myArticle->total();
|
||||
$res = [];
|
||||
@ -50,16 +48,34 @@ class User extends BaseController
|
||||
$res['data'][] = ['id'=>$v['id'],
|
||||
'title' => htmlspecialchars($v['title']),
|
||||
'url' => $this->getRouteUrl($v['id'], $v->cate->ename, $v->cate->appname),
|
||||
'status' => $v['status'] ? '正常':'待审',
|
||||
'status' => $this->artStatus($v['status']),
|
||||
'ctime' => $v['create_time'],
|
||||
'datas' => $v['pv'].'阅/'.$v['comments_count'].'答'
|
||||
'utime' => $v['update_time'],
|
||||
'pv' => $v['pv'],
|
||||
'datas' => $v['comments_count'].'答'
|
||||
];
|
||||
}
|
||||
|
||||
} else {
|
||||
return json(['code'=>-1,'msg'=>'无数据']);
|
||||
return json($res);
|
||||
}
|
||||
return json($res);
|
||||
|
||||
return json(['code'=>-1,'msg'=>'无数据']);
|
||||
}
|
||||
|
||||
// 文章状态
|
||||
private function artStatus($status)
|
||||
{
|
||||
switch ($status) {
|
||||
case 1:
|
||||
$res = '正常';
|
||||
break;
|
||||
case -1:
|
||||
$res = '禁止';
|
||||
break;
|
||||
default:
|
||||
$res = '待审';
|
||||
break;
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
// 收藏list
|
||||
@ -99,6 +115,82 @@ class User extends BaseController
|
||||
{
|
||||
return View::fetch();
|
||||
}
|
||||
|
||||
// 编辑pv
|
||||
public function edtiPv()
|
||||
{
|
||||
if(Request::isAjax()){
|
||||
$param = Request::param(['id','pv']);
|
||||
$res = Db::name('article')->save(['id' => $param['id'], 'pv' => $param['pv']]);
|
||||
if($res) {
|
||||
return json(['code' => 0, 'msg' => '修改成功!']);
|
||||
}
|
||||
}
|
||||
return json(['code' => -1, 'msg' => '修改失败!']);
|
||||
}
|
||||
|
||||
// 刷新
|
||||
public function updateTime()
|
||||
{
|
||||
if(Request::isAjax()){
|
||||
$param = Request::param(['data']);
|
||||
if(count($param) == 0) return json(['code' => -1, 'msg' => '未选中任何数据!']);
|
||||
$idArr = [];
|
||||
foreach($param['data'] as $v) {
|
||||
$idArr[] = $v['id'];
|
||||
}
|
||||
$count = count($idArr);
|
||||
|
||||
// vip每天可刷新数
|
||||
$user = Db::name('user')->field('id,vip,point,auth')->find($this->uid);
|
||||
|
||||
$refreshRule = Db::name('user_viprule')->field('refreshnum,refreshpoint')->where('vip', $user['vip'])->find();
|
||||
// 检测刷新帖子剩余量
|
||||
$refreshLog = Db::name('user_article_log')->field('id,user_refreshnum')->where(['user_id' => $this->uid])->whereDay('create_time')->find();
|
||||
if(is_null($refreshLog)) {// 新增
|
||||
Db::name('user_article_log')->save(['user_id' => $this->uid, 'create_time' => time()]);
|
||||
$refreshLog = Db::name('user_article_log')->field('id,user_refreshnum')->where(['user_id' => $this->uid])->whereDay('create_time')->find();
|
||||
}
|
||||
// 超级管理员排外
|
||||
if($user['auth'] === '0') {
|
||||
$cannum = $refreshRule['refreshnum'] - $refreshLog['user_refreshnum']; // 可用免费数
|
||||
// 刷帖先扣积分
|
||||
if($cannum <= 0) { // a.免费额已用完 后面需要积分
|
||||
$canpoint = $count * $refreshRule['refreshpoint'];
|
||||
$point = $user['point'] - $canpoint;
|
||||
if($point < 0) {
|
||||
// 1.积分不足
|
||||
return json(['code' => -1, 'msg' => "免额已使用,本次需{$canpoint}积分,请充值!"]);
|
||||
} else {
|
||||
// 2.扣除积分
|
||||
Db::name('user')->where('id', $this->uid)->update(['point' => $point]);
|
||||
}
|
||||
} else { // b.未超限 有剩余条数
|
||||
if($count > $cannum) { // 本次刷新数量大于剩余免费数量,需要支付积分
|
||||
$canpoint = ($count - $cannum) * $refreshRule['refreshpoint'];
|
||||
$point = $user['point'] - $canpoint;
|
||||
if($point < 0) {
|
||||
// 1.积分不足
|
||||
return json(['code' => -1, 'msg' => "免额已使用,本次需{$canpoint}积分,额度不足请充值!"]);
|
||||
} else {
|
||||
// 2.扣除积分
|
||||
Db::name('user')->where('id', $this->uid)->update(['point' => $point]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 刷新数据
|
||||
$res = Db::name('article')->where('id', 'in', $idArr)->update(['update_time' => time()]);
|
||||
if($res > 0) {
|
||||
// 记录刷帖日志
|
||||
Db::name('user_article_log')->where('id', $refreshLog['id'])->inc('user_refreshnum', $count)->update();
|
||||
|
||||
return json(['code' => 0, 'msg' => '刷新成功!']);
|
||||
}
|
||||
}
|
||||
return json(['code' => -1, 'msg' => '刷新失败!']);
|
||||
}
|
||||
|
||||
//取消文章收藏
|
||||
public function colltDel()
|
||||
@ -119,7 +211,7 @@ class User extends BaseController
|
||||
public function set()
|
||||
{
|
||||
if(Request::isAjax()){
|
||||
$data = Request::only(['email','nickname','sex','city','area_id','sign']);
|
||||
$data = Request::only(['email','phone','nickname','sex','city','area_id','sign']);
|
||||
$data['user_id'] = $this->uid;
|
||||
// 过滤
|
||||
$sign = strtolower($data['sign']);
|
||||
@ -209,11 +301,8 @@ class User extends BaseController
|
||||
public function home($id)
|
||||
{
|
||||
//用户
|
||||
$u = Cache::get('user'.$id);
|
||||
if(!$u){
|
||||
$u = Db::name('user')->field('name,nickname,city,sex,sign,user_img,point,vip,create_time')->cache(3600)->find($id);
|
||||
}
|
||||
|
||||
$u = Db::name('user')->field('name,nickname,city,sex,sign,user_img,point,vip,create_time')->find($id);
|
||||
|
||||
$article = new Article();
|
||||
$arts = $article->getUserArtList((int) $id);
|
||||
|
||||
@ -228,7 +317,8 @@ class User extends BaseController
|
||||
->field('a.id,a.title,t.ename,c.content,c.create_time,c.delete_time,c.status')
|
||||
->where(['a.delete_time'=>0,'c.delete_time'=>0,'c.status'=>1])
|
||||
->where('c.user_id',$id)
|
||||
->order(['c.create_time'=>'desc'])
|
||||
->order(['c.id'=>'desc'])
|
||||
->limit(10)
|
||||
->cache(3600)->select();
|
||||
|
||||
View::assign(['u'=>$u,'arts'=>$arts,'reys'=>$reys,'jspage'=>'']);
|
||||
@ -278,15 +368,15 @@ class User extends BaseController
|
||||
return json(['code'=>-1,'msg' =>$validate->getError()]);
|
||||
|
||||
}
|
||||
$user = new userModel;
|
||||
$result = $user->setpass($data);
|
||||
$user = new userModel;
|
||||
$result = $user->setpass($data);
|
||||
if($result == 1) {
|
||||
Session::clear();
|
||||
Cookie::delete('auth');
|
||||
return $this->success('密码修改成功 请登录', (string) url('login/index'));
|
||||
} else {
|
||||
return json(['code'=>-1,'msg' =>$result]);
|
||||
return json(['code' => 1, 'msg' => '密码修改成功', 'data' => ['url' => (string) url('login/index')]]);
|
||||
}
|
||||
|
||||
return json(['code' => -1,'msg' =>$result]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -31,6 +31,8 @@ Route::group(function () {
|
||||
Route::get('user/message$', 'user/message');
|
||||
Route::get('user/post', 'user/post');
|
||||
Route::get('user/article','user/artList');
|
||||
Route::post('user/editpv','user/editPv');
|
||||
Route::post('user/updatetime','user/updateTime');
|
||||
Route::get('user/coll','user/collList');
|
||||
Route::get('user/colldel','user/collDel');
|
||||
Route::get('user/setpass','user/setPass');
|
||||
|
@ -74,7 +74,8 @@ CREATE TABLE `tao_article` (
|
||||
`delete_time` int NOT NULL DEFAULT 0 COMMENT '删除时间',
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
INDEX `user_id`(`user_id`) USING BTREE COMMENT '文章的用户索引',
|
||||
INDEX `cate_id`(`cate_id`) USING BTREE COMMENT '文章分类索引'
|
||||
INDEX `cate_id`(`cate_id`) USING BTREE COMMENT '文章分类索引',
|
||||
INDEX `idx_article_create_time`(`create_time` DESC) USING BTREE COMMENT '创建时间'
|
||||
) ENGINE = MyISAM AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '文章表' ROW_FORMAT = Dynamic;
|
||||
|
||||
-- ----------------------------
|
||||
@ -213,7 +214,7 @@ INSERT INTO `tao_auth_rule` VALUES (64, 'user.user/edit', 'Edit user', 1, 1, 60,
|
||||
INSERT INTO `tao_auth_rule` VALUES (65, 'user.user/delete', 'Delete user', 1, 1, 60, 2, '', 2, 54, '', 0, 0, 0);
|
||||
INSERT INTO `tao_auth_rule` VALUES (66, 'user.user/check', 'Check user', 1, 1, 60, 2, '', 2, 55, '', 0, 0, 0);
|
||||
INSERT INTO `tao_auth_rule` VALUES (67, 'user.user/auth', 'Superuser', 1, 1, 60, 2, '', 2, 56, '', 0, 0, 0);
|
||||
INSERT INTO `tao_auth_rule` VALUES (68, 'user.vip/index', '用户vip', 1, 1, 2, 1, '', 1, 2, '', 0, 0, 0);
|
||||
INSERT INTO `tao_auth_rule` VALUES (68, 'user.vip/index', '会员等级', 1, 1, 2, 1, '', 1, 2, '', 0, 0, 0);
|
||||
INSERT INTO `tao_auth_rule` VALUES (69, 'user.vip/list', 'vip列表', 1, 1, 68, 2, '', 2, 50, '', 0, 0, 0);
|
||||
INSERT INTO `tao_auth_rule` VALUES (70, 'user.vip/add', '添加vip', 1, 1, 68, 2, '', 2, 51, '', 0, 0, 0);
|
||||
INSERT INTO `tao_auth_rule` VALUES (71, 'user.vip/edit', '编辑vip', 1, 1, 68, 2, '', 2, 52, '', 0, 0, 0);
|
||||
@ -429,7 +430,8 @@ CREATE TABLE `tao_message_to` (
|
||||
`create_time` int NOT NULL DEFAULT 0 COMMENT '创建时间',
|
||||
`update_time` int NOT NULL DEFAULT 0 COMMENT '更新时间',
|
||||
`delete_time` int NOT NULL DEFAULT 0 COMMENT '删除时间',
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
INDEX `idx_mesto_receveid`(`receve_id`) USING BTREE COMMENT '收件人ID'
|
||||
) ENGINE = MyISAM AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '消息详细表' ROW_FORMAT = Dynamic;
|
||||
|
||||
-- ----------------------------
|
||||
@ -606,6 +608,20 @@ INSERT INTO `tao_user_area` VALUES (2, '上海', '沪', 0, 0, 0);
|
||||
INSERT INTO `tao_user_area` VALUES (3, '广州', '广', 0, 0, 0);
|
||||
INSERT INTO `tao_user_area` VALUES (4, '深圳', '深', 0, 0, 0);
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for tao_user_article_log
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `tao_user_article_log`;
|
||||
CREATE TABLE `tao_user_article_log` (
|
||||
`id` int NOT NULL AUTO_INCREMENT COMMENT 'ID',
|
||||
`user_id` int NOT NULL COMMENT '用户ID',
|
||||
`user_postnum` int NOT NULL DEFAULT 0 COMMENT '用户发帖数量',
|
||||
`user_refreshnum` int NOT NULL DEFAULT 0 COMMENT '用户刷新数量',
|
||||
`create_time` int NOT NULL DEFAULT 0 COMMENT '记录时间',
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
INDEX `uid`(`user_id` ASC) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '用户发文刷新日志记录' ROW_FORMAT = Dynamic;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for tao_user_sign
|
||||
-- ----------------------------
|
||||
@ -649,10 +665,14 @@ INSERT INTO `tao_user_signrule` VALUES (4, 7, 10, 1677824262, 1677824262, 0);
|
||||
DROP TABLE IF EXISTS `tao_user_viprule`;
|
||||
CREATE TABLE `tao_user_viprule` (
|
||||
`id` int NOT NULL AUTO_INCREMENT COMMENT '用户等级ID',
|
||||
`score` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '0' COMMENT '积分区间',
|
||||
`vip` tinyint(1) NOT NULL DEFAULT 0 COMMENT 'vip等级',
|
||||
`score` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '0' COMMENT '积分区间',
|
||||
`nick` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '认证昵称',
|
||||
`rules` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '0' COMMENT '权限',
|
||||
`postnum` int NOT NULL DEFAULT 10 COMMENT '日发帖数量',
|
||||
`postpoint` int NOT NULL DEFAULT 0 COMMENT '发文扣积分',
|
||||
`refreshnum` int NOT NULL DEFAULT 10 COMMENT '日刷贴数量',
|
||||
`refreshpoint` int NOT NULL DEFAULT 0 COMMENT '刷帖扣积分',
|
||||
`create_time` int NOT NULL DEFAULT 0 COMMENT '创建时间',
|
||||
`update_time` int NOT NULL DEFAULT 0 COMMENT '升级时间',
|
||||
`delete_time` int NOT NULL DEFAULT 0 COMMENT '删除时间',
|
||||
@ -662,12 +682,12 @@ CREATE TABLE `tao_user_viprule` (
|
||||
-- ----------------------------
|
||||
-- Records of tao_user_viprule
|
||||
-- ----------------------------
|
||||
INSERT INTO `tao_user_viprule` VALUES (1, '0-99', 0, '游民', '0', 1585476523, 1585544577, 0);
|
||||
INSERT INTO `tao_user_viprule` VALUES (2, '100-299', 1, '富农', '1', 1585476551, 1677823895, 0);
|
||||
INSERT INTO `tao_user_viprule` VALUES (3, '300-500', 2, '地主', '0', 1585545450, 1585546241, 0);
|
||||
INSERT INTO `tao_user_viprule` VALUES (4, '501-699', 3, '土豪', '0', 1585545542, 1585569657, 0);
|
||||
INSERT INTO `tao_user_viprule` VALUES (5, '700-899', 4, '霸主', '0', 1677824242, 1677824242, 0);
|
||||
INSERT INTO `tao_user_viprule` VALUES (6, '900-1000', 5, '王爷', '0', 1677824859, 1677824859, 0);
|
||||
INSERT INTO `tao_user_viprule` VALUES (1, 0, '0-99', '游民', '0', 2, 2, 10, 1, 1585476523, 1698763623, 0);
|
||||
INSERT INTO `tao_user_viprule` VALUES (2, 1, '100-299', '富农', '1', 50, 0, 10, 0, 1585476551, 1698740135, 0);
|
||||
INSERT INTO `tao_user_viprule` VALUES (3, 2, '300-500', '地主', '0', 100, 0, 0, 0, 1585545450, 1698733320, 0);
|
||||
INSERT INTO `tao_user_viprule` VALUES (4, 3, '501-699', '土豪', '0', 10, 0, 100, 0, 1585545542, 1698746583, 0);
|
||||
INSERT INTO `tao_user_viprule` VALUES (5, 4, '700-899', '霸主', '0', 10, 0, 0, 0, 1677824242, 1677824242, 0);
|
||||
INSERT INTO `tao_user_viprule` VALUES (6, 5, '900-1000', '王爷', '0', 10, 0, 0, 0, 1677824859, 1677824859, 0);
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for tao_user_zan
|
||||
|
@ -33,52 +33,36 @@ class UserLogin
|
||||
$url = 'http://ip-api.com/json/' . $ip . '?lang=zh-CN&fields=57361';
|
||||
$city = 'earth';
|
||||
|
||||
// 登录日志
|
||||
Log::channel('login')->info('login:{user} {ip}',['user'=>$u->name,'ip'=>$ip]);
|
||||
|
||||
//日志
|
||||
if($type == 'log'){
|
||||
//$name = $user->user['name'];
|
||||
|
||||
try{
|
||||
$ipInfo = HttpHelper::get($url)->toJson();
|
||||
if($ipInfo->status == 'success')
|
||||
{
|
||||
if($ipInfo->status == 'success') {
|
||||
$city = $ipInfo->city;
|
||||
}
|
||||
|
||||
$data = [
|
||||
'city' => $city,
|
||||
'last_login_ip' => $ip,
|
||||
'last_login_time' => time(),
|
||||
'login_error_num' => 0
|
||||
];
|
||||
} catch (\Exception $e) {
|
||||
// echo $e->getMessage();
|
||||
}
|
||||
|
||||
//国内查询,接口已失效
|
||||
// $url = 'http://freeapi.ipip.net/' . $ip;
|
||||
// $ipJson = Api::urlGetRespond($url);
|
||||
// $respond = $ipJson->getData();
|
||||
// if($respond['code'] == 0){
|
||||
// //字符串数组["中国","北京","北京"]
|
||||
// $data = $respond['data'];
|
||||
// //正则去掉[''],保留字符串
|
||||
// $str = preg_replace('/(\"|\[|\])/','',$data);
|
||||
// //地址数组
|
||||
// $arr = explode(',', $str);
|
||||
// $city = 'earth';
|
||||
// if($arr[0] !== '本机地址') {
|
||||
// $city = $arr[2];
|
||||
// }
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
if($type == 'logError'){
|
||||
$u->allowField(['login_error_num','login_error_time'])->save(['login_error_num'=>$u->login_error_num + 1,'login_error_time'=>time()]);
|
||||
// 登录失败 失败次数加1
|
||||
if($type == 'logError') {
|
||||
$data = [
|
||||
'login_error_num' => $u->login_error_num + 1,
|
||||
'login_error_time' => time()
|
||||
];
|
||||
}
|
||||
|
||||
$u->allowField(['city','last_login_ip','last_login_time','login_error_num'])->save(
|
||||
[
|
||||
'city' => $city,
|
||||
'last_login_ip' => $ip,
|
||||
'last_login_time' => time(),
|
||||
'login_error_num' => 0
|
||||
]
|
||||
);
|
||||
Log::channel('login')->info('login:{user} {ip}',['user'=>$u->name,'ip'=>$ip]);
|
||||
|
||||
$u->allowField(['city','last_login_ip','last_login_time','login_error_num'])->save($data);
|
||||
}
|
||||
}
|
||||
|
117
app/middleware/AdminAuth.php
Normal file
117
app/middleware/AdminAuth.php
Normal file
@ -0,0 +1,117 @@
|
||||
<?php
|
||||
/*
|
||||
* @Author: TaoLer <alipey_tao@qq.com>
|
||||
* @Date: 2021-12-06 16:04:50
|
||||
* @LastEditTime: 2022-04-22 06:24:03
|
||||
* @LastEditors: TaoLer
|
||||
* @Description: 搜索引擎SEO优化设置
|
||||
* @FilePath: \TaoLer\app\middleware\Auth.php
|
||||
* Copyright (c) 2020~2022 http://www.aieok.com All rights reserved.
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\middleware;
|
||||
|
||||
use taoser\think\Auth as UserAuth;
|
||||
use think\facade\Session;
|
||||
use think\facade\Cookie;
|
||||
use think\facade\Db;
|
||||
use think\facade\Config;
|
||||
use think\facade\Request;
|
||||
|
||||
class AdminAuth
|
||||
{
|
||||
/**
|
||||
* 处理请求
|
||||
*
|
||||
* @param Request $request
|
||||
* @param \Closure $next
|
||||
* @return Response
|
||||
*/
|
||||
public function handle($request, \Closure $next)
|
||||
{
|
||||
// var_dump(Request::url(),Request::pathinfo(),$request->baseUrl(),$request->controller());
|
||||
//访问路径
|
||||
// $path = app('http')->getName().'/'.stristr($request->pathinfo(),".html",true);
|
||||
$path = stristr($request->pathinfo(),".html",true) ?: Request::pathinfo();
|
||||
// var_dump($path);
|
||||
//登陆前获取加密的Cookie
|
||||
$cooAuth = Cookie::get('adminAuth');
|
||||
|
||||
if(!empty($cooAuth)){
|
||||
$resArr = explode(':',$cooAuth);
|
||||
$userId = end($resArr);
|
||||
//检验用户
|
||||
$user = Db::name('admin')->where('id',$userId)->find();
|
||||
if(!empty($user)){
|
||||
//验证cookie
|
||||
$salt = Config::get('taoler.salt');
|
||||
$auth = md5($user['username'].$salt).":".$userId;
|
||||
if($auth == $cooAuth){
|
||||
Session::set('admin_name',$user['username']);
|
||||
Session::set('admin_id',$userId);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// //没有登录及当前非登录页重定向登录页
|
||||
// if(!Session::has('admin_id') && $path !== 'admin/login/index' && !(stristr($request->pathinfo(),"captcha.html") || stristr($request->pathinfo(),"addons")) )
|
||||
// {
|
||||
// return redirect((string) url('login/index'));
|
||||
// }
|
||||
// //登陆后无法访问登录页
|
||||
// if(Session::has('admin_id') && $path == 'admin/login/index'){
|
||||
// return redirect((string) url('index/index'));
|
||||
// }
|
||||
// // 排除公共权限
|
||||
// $not_check = ['admin/','index/index', 'admin/menu/getMenuNavbar','admin/login/index','admin/index/index','admin/index/home','admin/Admin/info','admin/Admin/repass','admin/Admin/logout','admin/Index/news','admin/Index/cunsult','admin/Index/replys','admin/Index/reply','admin/captcha','addons/socail/','admin/addons/social/oauth/login','admin/addons/bacimg/index/getImages'];
|
||||
|
||||
|
||||
//没有登录及当前非登录页重定向登录页
|
||||
if(!Session::has('admin_id') && $path !== 'login/index' && !(stristr($request->pathinfo(),"captcha.html") || stristr($request->pathinfo(),"addons")) )
|
||||
{
|
||||
return redirect((string) url('login/index'));
|
||||
}
|
||||
//登陆后无法访问登录页
|
||||
if(Session::has('admin_id') && $path == 'login/index' || $path == ''){
|
||||
return redirect((string) url('index/index'));
|
||||
}
|
||||
|
||||
// 排除公共权限
|
||||
$not_check = [
|
||||
'captcha',
|
||||
'login/index',
|
||||
'admin/index',
|
||||
'system.menu/getnav',
|
||||
'index/index',
|
||||
'index/console1',
|
||||
'index/console2',
|
||||
'index/news',
|
||||
'menu/getMenuNavbar',
|
||||
'index/home',
|
||||
'Admin/info',
|
||||
'system.admin/repass',
|
||||
'system.admin/logout',
|
||||
'Index/cunsult',
|
||||
'Index/replys',
|
||||
'Index/reply',
|
||||
'admin/captcha',
|
||||
'addons/socail/',
|
||||
'addons/social/oauth/login',
|
||||
'addons/bacimg/index/getImages'
|
||||
];
|
||||
|
||||
if (!in_array($path, $not_check)) {
|
||||
$auth = new UserAuth();
|
||||
$admin_id = Session::get('admin_id'); //登录用户的id
|
||||
|
||||
if (!$auth->check($path, $admin_id) && $admin_id != 1) {
|
||||
//return view('public/auth');
|
||||
//return response("<script>alert('没有操作权限')</script>");
|
||||
return json(['code'=>-1,'msg'=>'无权限']);
|
||||
}
|
||||
}
|
||||
return $next($request);
|
||||
}
|
||||
}
|
@ -1,117 +1,31 @@
|
||||
<?php
|
||||
/*
|
||||
* @Author: TaoLer <alipey_tao@qq.com>
|
||||
* @Date: 2021-12-06 16:04:50
|
||||
* @LastEditTime: 2022-04-22 06:24:03
|
||||
* @LastEditors: TaoLer
|
||||
* @Description: 搜索引擎SEO优化设置
|
||||
* @FilePath: \TaoLer\app\middleware\Auth.php
|
||||
* Copyright (c) 2020~2022 http://www.aieok.com All rights reserved.
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\middleware;
|
||||
|
||||
use taoser\think\Auth as UserAuth;
|
||||
use think\facade\Session;
|
||||
use think\facade\Cookie;
|
||||
use think\facade\Db;
|
||||
use think\facade\Config;
|
||||
use think\facade\Request;
|
||||
use app\common\lib\JwtAuth;
|
||||
|
||||
class Auth
|
||||
{
|
||||
/**
|
||||
* 处理请求
|
||||
*
|
||||
* @param Request $request
|
||||
* @param \Closure $next
|
||||
* @return Response
|
||||
*/
|
||||
public function handle($request, \Closure $next)
|
||||
{
|
||||
// var_dump(Request::url(),Request::pathinfo(),$request->baseUrl(),$request->controller());
|
||||
//访问路径
|
||||
// $path = app('http')->getName().'/'.stristr($request->pathinfo(),".html",true);
|
||||
$path = stristr($request->pathinfo(),".html",true) ?: Request::pathinfo();
|
||||
// var_dump($path);
|
||||
//登陆前获取加密的Cookie
|
||||
$cooAuth = Cookie::get('adminAuth');
|
||||
$header = $request->header();
|
||||
|
||||
if(!empty($cooAuth)){
|
||||
$resArr = explode(':',$cooAuth);
|
||||
$userId = end($resArr);
|
||||
//检验用户
|
||||
$user = Db::name('admin')->where('id',$userId)->find();
|
||||
if(!empty($user)){
|
||||
//验证cookie
|
||||
$salt = Config::get('taoler.salt');
|
||||
$auth = md5($user['username'].$salt).":".$userId;
|
||||
if($auth == $cooAuth){
|
||||
Session::set('admin_name',$user['username']);
|
||||
Session::set('admin_id',$userId);
|
||||
}
|
||||
if(isset($header['authorization'])) {
|
||||
$token = trim(ltrim($request->header('authorization'), 'Bearer'));
|
||||
|
||||
try{
|
||||
$data = JwtAuth::decode($token);
|
||||
|
||||
$request->uid = $data->uid;
|
||||
|
||||
} catch(\Exception $e) {
|
||||
return json(['code' => -1, 'msg' => $e->getMessage()]);
|
||||
}
|
||||
|
||||
} else {
|
||||
return json(['code' => -1, 'msg' => 'no auth']);
|
||||
}
|
||||
|
||||
// //没有登录及当前非登录页重定向登录页
|
||||
// if(!Session::has('admin_id') && $path !== 'admin/login/index' && !(stristr($request->pathinfo(),"captcha.html") || stristr($request->pathinfo(),"addons")) )
|
||||
// {
|
||||
// return redirect((string) url('login/index'));
|
||||
// }
|
||||
// //登陆后无法访问登录页
|
||||
// if(Session::has('admin_id') && $path == 'admin/login/index'){
|
||||
// return redirect((string) url('index/index'));
|
||||
// }
|
||||
// // 排除公共权限
|
||||
// $not_check = ['admin/','index/index', 'admin/menu/getMenuNavbar','admin/login/index','admin/index/index','admin/index/home','admin/Admin/info','admin/Admin/repass','admin/Admin/logout','admin/Index/news','admin/Index/cunsult','admin/Index/replys','admin/Index/reply','admin/captcha','addons/socail/','admin/addons/social/oauth/login','admin/addons/bacimg/index/getImages'];
|
||||
|
||||
|
||||
//没有登录及当前非登录页重定向登录页
|
||||
if(!Session::has('admin_id') && $path !== 'login/index' && !(stristr($request->pathinfo(),"captcha.html") || stristr($request->pathinfo(),"addons")) )
|
||||
{
|
||||
return redirect((string) url('login/index'));
|
||||
}
|
||||
//登陆后无法访问登录页
|
||||
if(Session::has('admin_id') && $path == 'login/index' || $path == ''){
|
||||
return redirect((string) url('index/index'));
|
||||
}
|
||||
|
||||
// 排除公共权限
|
||||
$not_check = [
|
||||
'captcha',
|
||||
'login/index',
|
||||
'admin/index',
|
||||
'system.menu/getnav',
|
||||
'index/index',
|
||||
'index/console1',
|
||||
'index/console2',
|
||||
'index/news',
|
||||
'menu/getMenuNavbar',
|
||||
'index/home',
|
||||
'Admin/info',
|
||||
'system.admin/repass',
|
||||
'system.admin/logout',
|
||||
'Index/cunsult',
|
||||
'Index/replys',
|
||||
'Index/reply',
|
||||
'admin/captcha',
|
||||
'addons/socail/',
|
||||
'addons/social/oauth/login',
|
||||
'addons/bacimg/index/getImages'
|
||||
];
|
||||
|
||||
if (!in_array($path, $not_check)) {
|
||||
$auth = new UserAuth();
|
||||
$admin_id = Session::get('admin_id'); //登录用户的id
|
||||
|
||||
if (!$auth->check($path, $admin_id) && $admin_id != 1) {
|
||||
//return view('public/auth');
|
||||
//return response("<script>alert('没有操作权限')</script>");
|
||||
return json(['code'=>-1,'msg'=>'无权限']);
|
||||
}
|
||||
}
|
||||
return $next($request);
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
}
|
||||
|
33
app/middleware/Auths.php
Normal file
33
app/middleware/Auths.php
Normal file
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace app\middleware;
|
||||
|
||||
use app\common\lib\JwtAuth;
|
||||
|
||||
class Auths
|
||||
{
|
||||
public function handle($request, \Closure $next)
|
||||
{
|
||||
$header = $request->header();
|
||||
|
||||
if(isset($header['authorization'])) {
|
||||
$token = trim(ltrim($request->header('authorization'), 'Bearer'));
|
||||
|
||||
try{
|
||||
$data = JwtAuth::decode($token);
|
||||
|
||||
$request->uid = $data->uid;
|
||||
|
||||
} catch(\Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
return json(['code' => -1, 'msg' => 'no auth']);
|
||||
}
|
||||
//登陆前获取加密的Cookie
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
}
|
@ -1,17 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace app\middleware;
|
||||
use think\facade\Request;
|
||||
|
||||
use think\facade\Log;
|
||||
|
||||
/**
|
||||
* 浏览记录日志中间件
|
||||
*/
|
||||
class Browse
|
||||
{
|
||||
public function handle($request, \Closure $next)
|
||||
{
|
||||
$agent = $_SERVER['HTTP_USER_AGENT'];
|
||||
$ip = $_SERVER['REMOTE_ADDR'];
|
||||
$url = Request::url(true);
|
||||
$agent = $request->header('user-agent');
|
||||
$ip = $request->ip();
|
||||
$url = $request->url(true);
|
||||
Log::channel('browse')->info('browse:{agent} {ip} {url}',['agent'=>$agent,'url'=>$url,'ip'=>$ip]);
|
||||
return $next($request);
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
}
|
||||
|
@ -24,8 +24,6 @@
|
||||
"topthink/think-view": "^1.0",
|
||||
"topthink/think-captcha": "^3.0",
|
||||
"phpmailer/phpmailer": "^6.1",
|
||||
"lotofbadcode/phpspirit_databackup": "^1.1",
|
||||
"wamkj/thinkphp6.0-databackup": "^1.0",
|
||||
"taoser/think-addons": "^1.0",
|
||||
"liliuwei/thinkphp-social": "^1.3",
|
||||
"taoser/think-setarr": "^0.0.3",
|
||||
@ -38,7 +36,9 @@
|
||||
"workerman/phpsocket.io": "^1.1",
|
||||
"jaeger/querylist": "^4.2",
|
||||
"symfony/var-exporter": "^5.4",
|
||||
"yzh52521/easyhttp": "^1.0"
|
||||
"yzh52521/easyhttp": "^1.0",
|
||||
"firebase/php-jwt": "^6.8",
|
||||
"overtrue/easy-sms": "^2.5"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/var-dumper": "^4.2",
|
||||
|
438
composer.lock
generated
438
composer.lock
generated
@ -4,7 +4,7 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "20dad4ba0451f20b1191711c63ad21c7",
|
||||
"content-hash": "6be3b456c215d7ae6d3ba8a28f6697b4",
|
||||
"packages": [
|
||||
{
|
||||
"name": "bacon/bacon-qr-code",
|
||||
@ -257,16 +257,16 @@
|
||||
},
|
||||
{
|
||||
"name": "dasprid/enum",
|
||||
"version": "1.0.4",
|
||||
"version": "1.0.5",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/DASPRiD/Enum.git",
|
||||
"reference": "8e6b6ea76eabbf19ea2bf5b67b98e1860474012f"
|
||||
"reference": "6faf451159fb8ba4126b925ed2d78acfce0dc016"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/DASPRiD/Enum/zipball/8e6b6ea76eabbf19ea2bf5b67b98e1860474012f",
|
||||
"reference": "8e6b6ea76eabbf19ea2bf5b67b98e1860474012f",
|
||||
"url": "https://api.github.com/repos/DASPRiD/Enum/zipball/6faf451159fb8ba4126b925ed2d78acfce0dc016",
|
||||
"reference": "6faf451159fb8ba4126b925ed2d78acfce0dc016",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -301,9 +301,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/DASPRiD/Enum/issues",
|
||||
"source": "https://github.com/DASPRiD/Enum/tree/1.0.4"
|
||||
"source": "https://github.com/DASPRiD/Enum/tree/1.0.5"
|
||||
},
|
||||
"time": "2023-03-01T18:44:03+00:00"
|
||||
"time": "2023-08-25T16:18:39+00:00"
|
||||
},
|
||||
{
|
||||
"name": "endroid/qr-code",
|
||||
@ -377,6 +377,69 @@
|
||||
],
|
||||
"time": "2022-10-26T08:48:17+00:00"
|
||||
},
|
||||
{
|
||||
"name": "firebase/php-jwt",
|
||||
"version": "v6.10.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/firebase/php-jwt.git",
|
||||
"reference": "a49db6f0a5033aef5143295342f1c95521b075ff"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/firebase/php-jwt/zipball/a49db6f0a5033aef5143295342f1c95521b075ff",
|
||||
"reference": "a49db6f0a5033aef5143295342f1c95521b075ff",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.4||^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"guzzlehttp/guzzle": "^6.5||^7.4",
|
||||
"phpspec/prophecy-phpunit": "^2.0",
|
||||
"phpunit/phpunit": "^9.5",
|
||||
"psr/cache": "^1.0||^2.0",
|
||||
"psr/http-client": "^1.0",
|
||||
"psr/http-factory": "^1.0"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-sodium": "Support EdDSA (Ed25519) signatures",
|
||||
"paragonie/sodium_compat": "Support EdDSA (Ed25519) signatures when libsodium is not present"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Firebase\\JWT\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD-3-Clause"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Neuman Vong",
|
||||
"email": "neuman+pear@twilio.com",
|
||||
"role": "Developer"
|
||||
},
|
||||
{
|
||||
"name": "Anant Narayanan",
|
||||
"email": "anant@php.net",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"description": "A simple library to encode and decode JSON Web Tokens (JWT) in PHP. Should conform to the current spec.",
|
||||
"homepage": "https://github.com/firebase/php-jwt",
|
||||
"keywords": [
|
||||
"jwt",
|
||||
"php"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/firebase/php-jwt/issues",
|
||||
"source": "https://github.com/firebase/php-jwt/tree/v6.10.0"
|
||||
},
|
||||
"time": "2023-12-01T16:26:39+00:00"
|
||||
},
|
||||
{
|
||||
"name": "guzzlehttp/guzzle",
|
||||
"version": "7.0.0",
|
||||
@ -648,21 +711,21 @@
|
||||
},
|
||||
{
|
||||
"name": "jaeger/g-http",
|
||||
"version": "V1.7.2",
|
||||
"version": "V1.7.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/jae-jae/GHttp.git",
|
||||
"reference": "82585ddd5e2c6651e37ab1d8166efcdbb6b293d4"
|
||||
"reference": "035fe0ff6e3e0390769647ce14694875bf02cf22"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/jae-jae/GHttp/zipball/82585ddd5e2c6651e37ab1d8166efcdbb6b293d4",
|
||||
"reference": "82585ddd5e2c6651e37ab1d8166efcdbb6b293d4",
|
||||
"url": "https://api.github.com/repos/jae-jae/GHttp/zipball/035fe0ff6e3e0390769647ce14694875bf02cf22",
|
||||
"reference": "035fe0ff6e3e0390769647ce14694875bf02cf22",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"cache/filesystem-adapter": "^1",
|
||||
"guzzlehttp/guzzle": "^6.0 | ^7.0"
|
||||
"guzzlehttp/guzzle": "^6.0 || ^7.0"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
@ -683,9 +746,9 @@
|
||||
"description": "Simple Http client base on GuzzleHttp",
|
||||
"support": {
|
||||
"issues": "https://github.com/jae-jae/GHttp/issues",
|
||||
"source": "https://github.com/jae-jae/GHttp/tree/V1.7.2"
|
||||
"source": "https://github.com/jae-jae/GHttp/tree/V1.7.3"
|
||||
},
|
||||
"time": "2021-08-08T04:59:44+00:00"
|
||||
"time": "2024-03-24T14:55:49+00:00"
|
||||
},
|
||||
{
|
||||
"name": "jaeger/phpquery-single",
|
||||
@ -736,16 +799,16 @@
|
||||
},
|
||||
{
|
||||
"name": "jaeger/querylist",
|
||||
"version": "V4.2.8",
|
||||
"version": "V4.2.9",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/jae-jae/QueryList.git",
|
||||
"reference": "39dc0ca9c668bec7a793e20472ccd7d26ef89ea4"
|
||||
"reference": "7aae3aed38214d3d7096174faf49f6c41b2dd550"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/jae-jae/QueryList/zipball/39dc0ca9c668bec7a793e20472ccd7d26ef89ea4",
|
||||
"reference": "39dc0ca9c668bec7a793e20472ccd7d26ef89ea4",
|
||||
"url": "https://api.github.com/repos/jae-jae/QueryList/zipball/7aae3aed38214d3d7096174faf49f6c41b2dd550",
|
||||
"reference": "7aae3aed38214d3d7096174faf49f6c41b2dd550",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -753,11 +816,10 @@
|
||||
"jaeger/g-http": "^1.1",
|
||||
"jaeger/phpquery-single": "^1",
|
||||
"php": ">=7.1",
|
||||
"tightenco/collect": ">5.0"
|
||||
"symfony/var-dumper": ">3.4"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^8.5",
|
||||
"symfony/var-dumper": "^3.3"
|
||||
"phpunit/phpunit": "^8.5"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
@ -784,7 +846,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/jae-jae/QueryList/issues",
|
||||
"source": "https://github.com/jae-jae/QueryList/tree/V4.2.8"
|
||||
"source": "https://github.com/jae-jae/QueryList/tree/V4.2.9"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -792,20 +854,20 @@
|
||||
"type": "open_collective"
|
||||
}
|
||||
],
|
||||
"time": "2021-07-05T06:07:58+00:00"
|
||||
"time": "2024-04-12T06:29:50+00:00"
|
||||
},
|
||||
{
|
||||
"name": "laravel/serializable-closure",
|
||||
"version": "v1.3.1",
|
||||
"version": "v1.3.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/laravel/serializable-closure.git",
|
||||
"reference": "e5a3057a5591e1cfe8183034b0203921abe2c902"
|
||||
"reference": "3dbf8a8e914634c48d389c1234552666b3d43754"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/laravel/serializable-closure/zipball/e5a3057a5591e1cfe8183034b0203921abe2c902",
|
||||
"reference": "e5a3057a5591e1cfe8183034b0203921abe2c902",
|
||||
"url": "https://api.github.com/repos/laravel/serializable-closure/zipball/3dbf8a8e914634c48d389c1234552666b3d43754",
|
||||
"reference": "3dbf8a8e914634c48d389c1234552666b3d43754",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -852,7 +914,7 @@
|
||||
"issues": "https://github.com/laravel/serializable-closure/issues",
|
||||
"source": "https://github.com/laravel/serializable-closure"
|
||||
},
|
||||
"time": "2023-07-14T13:56:28+00:00"
|
||||
"time": "2023-11-08T14:08:06+00:00"
|
||||
},
|
||||
{
|
||||
"name": "league/flysystem",
|
||||
@ -950,26 +1012,26 @@
|
||||
},
|
||||
{
|
||||
"name": "league/mime-type-detection",
|
||||
"version": "1.11.0",
|
||||
"version": "1.15.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/thephpleague/mime-type-detection.git",
|
||||
"reference": "ff6248ea87a9f116e78edd6002e39e5128a0d4dd"
|
||||
"reference": "ce0f4d1e8a6f4eb0ddff33f57c69c50fd09f4301"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/thephpleague/mime-type-detection/zipball/ff6248ea87a9f116e78edd6002e39e5128a0d4dd",
|
||||
"reference": "ff6248ea87a9f116e78edd6002e39e5128a0d4dd",
|
||||
"url": "https://api.github.com/repos/thephpleague/mime-type-detection/zipball/ce0f4d1e8a6f4eb0ddff33f57c69c50fd09f4301",
|
||||
"reference": "ce0f4d1e8a6f4eb0ddff33f57c69c50fd09f4301",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-fileinfo": "*",
|
||||
"php": "^7.2 || ^8.0"
|
||||
"php": "^7.4 || ^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"friendsofphp/php-cs-fixer": "^3.2",
|
||||
"phpstan/phpstan": "^0.12.68",
|
||||
"phpunit/phpunit": "^8.5.8 || ^9.3"
|
||||
"phpunit/phpunit": "^8.5.8 || ^9.3 || ^10.0"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
@ -990,7 +1052,7 @@
|
||||
"description": "Mime-type detection for Flysystem",
|
||||
"support": {
|
||||
"issues": "https://github.com/thephpleague/mime-type-detection/issues",
|
||||
"source": "https://github.com/thephpleague/mime-type-detection/tree/1.11.0"
|
||||
"source": "https://github.com/thephpleague/mime-type-detection/tree/1.15.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -1002,7 +1064,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2022-04-17T13:12:02+00:00"
|
||||
"time": "2024-01-28T23:22:08+00:00"
|
||||
},
|
||||
{
|
||||
"name": "liliuwei/thinkphp-social",
|
||||
@ -1080,61 +1142,83 @@
|
||||
"time": "2021-01-13T05:11:12+00:00"
|
||||
},
|
||||
{
|
||||
"name": "lotofbadcode/phpspirit_databackup",
|
||||
"version": "v1.2",
|
||||
"name": "overtrue/easy-sms",
|
||||
"version": "2.6.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/lotofbadcode/phpspirit_databackup.git",
|
||||
"reference": "77c2421f8461392c044cf8c29918f495c22a5612"
|
||||
"url": "https://github.com/overtrue/easy-sms.git",
|
||||
"reference": "bb88b244f0de8d1f74bc50c4c08414f4c5f30281"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/lotofbadcode/phpspirit_databackup/zipball/77c2421f8461392c044cf8c29918f495c22a5612",
|
||||
"reference": "77c2421f8461392c044cf8c29918f495c22a5612",
|
||||
"url": "https://api.github.com/repos/overtrue/easy-sms/zipball/bb88b244f0de8d1f74bc50c4c08414f4c5f30281",
|
||||
"reference": "bb88b244f0de8d1f74bc50c4c08414f4c5f30281",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.0"
|
||||
"ext-json": "*",
|
||||
"guzzlehttp/guzzle": "^6.2 || ^7.0",
|
||||
"php": ">=5.6"
|
||||
},
|
||||
"require-dev": {
|
||||
"brainmaestro/composer-git-hooks": "^2.8",
|
||||
"jetbrains/phpstorm-attributes": "^1.0",
|
||||
"mockery/mockery": "~1.3.3 || ^1.4.2",
|
||||
"phpunit/phpunit": "^5.7 || ^7.5 || ^8.5.19 || ^9.5.8"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"hooks": {
|
||||
"pre-commit": [
|
||||
"composer check-style",
|
||||
"composer psalm",
|
||||
"composer test"
|
||||
],
|
||||
"pre-push": [
|
||||
"composer check-style"
|
||||
]
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"phpspirit\\databackup\\": "src/"
|
||||
"Overtrue\\EasySms\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"Apache-2.0"
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "代码庸医",
|
||||
"email": "3359964266@qq.com"
|
||||
"name": "overtrue",
|
||||
"email": "i@overtrue.me"
|
||||
}
|
||||
],
|
||||
"description": "一个PHP数据库备份恢复的插件",
|
||||
"keywords": [
|
||||
"library",
|
||||
"php"
|
||||
],
|
||||
"description": "The easiest way to send short message.",
|
||||
"support": {
|
||||
"issues": "https://github.com/lotofbadcode/phpspirit_databackup/issues",
|
||||
"source": "https://github.com/lotofbadcode/phpspirit_databackup/tree/v1.2"
|
||||
"issues": "https://github.com/overtrue/easy-sms/issues",
|
||||
"source": "https://github.com/overtrue/easy-sms/tree/2.6.0"
|
||||
},
|
||||
"time": "2023-05-12T12:02:05+00:00"
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://github.com/overtrue",
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2024-03-08T06:36:45+00:00"
|
||||
},
|
||||
{
|
||||
"name": "php-di/invoker",
|
||||
"version": "2.3.3",
|
||||
"version": "2.3.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/PHP-DI/Invoker.git",
|
||||
"reference": "cd6d9f267d1a3474bdddf1be1da079f01b942786"
|
||||
"reference": "33234b32dafa8eb69202f950a1fc92055ed76a86"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/PHP-DI/Invoker/zipball/cd6d9f267d1a3474bdddf1be1da079f01b942786",
|
||||
"reference": "cd6d9f267d1a3474bdddf1be1da079f01b942786",
|
||||
"url": "https://api.github.com/repos/PHP-DI/Invoker/zipball/33234b32dafa8eb69202f950a1fc92055ed76a86",
|
||||
"reference": "33234b32dafa8eb69202f950a1fc92055ed76a86",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -1168,7 +1252,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/PHP-DI/Invoker/issues",
|
||||
"source": "https://github.com/PHP-DI/Invoker/tree/2.3.3"
|
||||
"source": "https://github.com/PHP-DI/Invoker/tree/2.3.4"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -1176,7 +1260,7 @@
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2021-12-13T09:22:56+00:00"
|
||||
"time": "2023-09-08T09:24:21+00:00"
|
||||
},
|
||||
{
|
||||
"name": "php-di/php-di",
|
||||
@ -1298,16 +1382,16 @@
|
||||
},
|
||||
{
|
||||
"name": "phpmailer/phpmailer",
|
||||
"version": "v6.8.0",
|
||||
"version": "v6.9.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/PHPMailer/PHPMailer.git",
|
||||
"reference": "df16b615e371d81fb79e506277faea67a1be18f1"
|
||||
"reference": "039de174cd9c17a8389754d3b877a2ed22743e18"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/df16b615e371d81fb79e506277faea67a1be18f1",
|
||||
"reference": "df16b615e371d81fb79e506277faea67a1be18f1",
|
||||
"url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/039de174cd9c17a8389754d3b877a2ed22743e18",
|
||||
"reference": "039de174cd9c17a8389754d3b877a2ed22743e18",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -1317,16 +1401,17 @@
|
||||
"php": ">=5.5.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"dealerdirect/phpcodesniffer-composer-installer": "^0.7.2",
|
||||
"dealerdirect/phpcodesniffer-composer-installer": "^1.0",
|
||||
"doctrine/annotations": "^1.2.6 || ^1.13.3",
|
||||
"php-parallel-lint/php-console-highlighter": "^1.0.0",
|
||||
"php-parallel-lint/php-parallel-lint": "^1.3.2",
|
||||
"phpcompatibility/php-compatibility": "^9.3.5",
|
||||
"roave/security-advisories": "dev-latest",
|
||||
"squizlabs/php_codesniffer": "^3.7.1",
|
||||
"squizlabs/php_codesniffer": "^3.7.2",
|
||||
"yoast/phpunit-polyfills": "^1.0.4"
|
||||
},
|
||||
"suggest": {
|
||||
"decomplexity/SendOauth2": "Adapter for using XOAUTH2 authentication",
|
||||
"ext-mbstring": "Needed to send email in multibyte encoding charset or decode encoded addresses",
|
||||
"ext-openssl": "Needed for secure SMTP sending and DKIM signing",
|
||||
"greew/oauth2-azure-provider": "Needed for Microsoft Azure XOAUTH2 authentication",
|
||||
@ -1366,7 +1451,7 @@
|
||||
"description": "PHPMailer is a full-featured email creation and transfer class for PHP",
|
||||
"support": {
|
||||
"issues": "https://github.com/PHPMailer/PHPMailer/issues",
|
||||
"source": "https://github.com/PHPMailer/PHPMailer/tree/v6.8.0"
|
||||
"source": "https://github.com/PHPMailer/PHPMailer/tree/v6.9.1"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -1374,7 +1459,7 @@
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2023-03-06T14:43:22+00:00"
|
||||
"time": "2023-11-25T22:23:28+00:00"
|
||||
},
|
||||
{
|
||||
"name": "psr/cache",
|
||||
@ -1525,16 +1610,16 @@
|
||||
},
|
||||
{
|
||||
"name": "psr/http-client",
|
||||
"version": "1.0.2",
|
||||
"version": "1.0.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/php-fig/http-client.git",
|
||||
"reference": "0955afe48220520692d2d09f7ab7e0f93ffd6a31"
|
||||
"reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/php-fig/http-client/zipball/0955afe48220520692d2d09f7ab7e0f93ffd6a31",
|
||||
"reference": "0955afe48220520692d2d09f7ab7e0f93ffd6a31",
|
||||
"url": "https://api.github.com/repos/php-fig/http-client/zipball/bb5906edc1c324c9a05aa0873d40117941e5fa90",
|
||||
"reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -1571,9 +1656,9 @@
|
||||
"psr-18"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/php-fig/http-client/tree/1.0.2"
|
||||
"source": "https://github.com/php-fig/http-client"
|
||||
},
|
||||
"time": "2023-04-10T20:12:12+00:00"
|
||||
"time": "2023-09-23T14:17:50+00:00"
|
||||
},
|
||||
{
|
||||
"name": "psr/http-message",
|
||||
@ -1775,16 +1860,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-mbstring",
|
||||
"version": "v1.27.0",
|
||||
"version": "v1.29.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-mbstring.git",
|
||||
"reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534"
|
||||
"reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/8ad114f6b39e2c98a8b0e3bd907732c207c2b534",
|
||||
"reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9773676c8a1bb1f8d4340a62efe641cf76eda7ec",
|
||||
"reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -1798,9 +1883,6 @@
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "1.27-dev"
|
||||
},
|
||||
"thanks": {
|
||||
"name": "symfony/polyfill",
|
||||
"url": "https://github.com/symfony/polyfill"
|
||||
@ -1838,7 +1920,7 @@
|
||||
"shim"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.27.0"
|
||||
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.29.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -1854,20 +1936,20 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2022-11-03T14:55:06+00:00"
|
||||
"time": "2024-01-29T20:11:03+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-php72",
|
||||
"version": "v1.27.0",
|
||||
"version": "v1.29.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-php72.git",
|
||||
"reference": "869329b1e9894268a8a61dabb69153029b7a8c97"
|
||||
"reference": "861391a8da9a04cbad2d232ddd9e4893220d6e25"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/869329b1e9894268a8a61dabb69153029b7a8c97",
|
||||
"reference": "869329b1e9894268a8a61dabb69153029b7a8c97",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/861391a8da9a04cbad2d232ddd9e4893220d6e25",
|
||||
"reference": "861391a8da9a04cbad2d232ddd9e4893220d6e25",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -1875,9 +1957,6 @@
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "1.27-dev"
|
||||
},
|
||||
"thanks": {
|
||||
"name": "symfony/polyfill",
|
||||
"url": "https://github.com/symfony/polyfill"
|
||||
@ -1914,7 +1993,7 @@
|
||||
"shim"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/polyfill-php72/tree/v1.27.0"
|
||||
"source": "https://github.com/symfony/polyfill-php72/tree/v1.29.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -1930,20 +2009,20 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2022-11-03T14:55:06+00:00"
|
||||
"time": "2024-01-29T20:11:03+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-php80",
|
||||
"version": "v1.27.0",
|
||||
"version": "v1.29.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-php80.git",
|
||||
"reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936"
|
||||
"reference": "87b68208d5c1188808dd7839ee1e6c8ec3b02f1b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936",
|
||||
"reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/87b68208d5c1188808dd7839ee1e6c8ec3b02f1b",
|
||||
"reference": "87b68208d5c1188808dd7839ee1e6c8ec3b02f1b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -1951,9 +2030,6 @@
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "1.27-dev"
|
||||
},
|
||||
"thanks": {
|
||||
"name": "symfony/polyfill",
|
||||
"url": "https://github.com/symfony/polyfill"
|
||||
@ -1997,7 +2073,7 @@
|
||||
"shim"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/polyfill-php80/tree/v1.27.0"
|
||||
"source": "https://github.com/symfony/polyfill-php80/tree/v1.29.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -2013,7 +2089,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2022-11-03T14:55:06+00:00"
|
||||
"time": "2024-01-29T20:11:03+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/var-dumper",
|
||||
@ -2106,16 +2182,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/var-exporter",
|
||||
"version": "v5.4.26",
|
||||
"version": "v5.4.35",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/var-exporter.git",
|
||||
"reference": "11401fe94f960249b3c63a488c63ba73091c1e4a"
|
||||
"reference": "abb0a151b62d6b07e816487e20040464af96cae7"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/var-exporter/zipball/11401fe94f960249b3c63a488c63ba73091c1e4a",
|
||||
"reference": "11401fe94f960249b3c63a488c63ba73091c1e4a",
|
||||
"url": "https://api.github.com/repos/symfony/var-exporter/zipball/abb0a151b62d6b07e816487e20040464af96cae7",
|
||||
"reference": "abb0a151b62d6b07e816487e20040464af96cae7",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -2159,7 +2235,7 @@
|
||||
"serialize"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/var-exporter/tree/v5.4.26"
|
||||
"source": "https://github.com/symfony/var-exporter/tree/v5.4.35"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -2175,7 +2251,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2023-07-20T07:21:16+00:00"
|
||||
"time": "2024-01-23T13:51:25+00:00"
|
||||
},
|
||||
{
|
||||
"name": "taoser/think-addons",
|
||||
@ -2327,60 +2403,6 @@
|
||||
},
|
||||
"time": "2022-04-16T23:08:43+00:00"
|
||||
},
|
||||
{
|
||||
"name": "tightenco/collect",
|
||||
"version": "v8.83.27",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/tighten/collect.git",
|
||||
"reference": "07eed6cf7441c7a69c379fdcb118eec1a1fdd0e6"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/tighten/collect/zipball/07eed6cf7441c7a69c379fdcb118eec1a1fdd0e6",
|
||||
"reference": "07eed6cf7441c7a69c379fdcb118eec1a1fdd0e6",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.3|^8.0",
|
||||
"symfony/var-dumper": "^3.4 || ^4.0 || ^5.0 || ^6.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"mockery/mockery": "^1.0",
|
||||
"nesbot/carbon": "^2.23.0",
|
||||
"phpunit/phpunit": "^8.3"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"files": [
|
||||
"src/Collect/Support/helpers.php",
|
||||
"src/Collect/Support/alias.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Tightenco\\Collect\\": "src/Collect"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Taylor Otwell",
|
||||
"email": "taylorotwell@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "Collect - Illuminate Collections as a separate package.",
|
||||
"keywords": [
|
||||
"collection",
|
||||
"laravel"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/tighten/collect/issues",
|
||||
"source": "https://github.com/tighten/collect/tree/v8.83.27"
|
||||
},
|
||||
"time": "2023-01-13T18:05:42+00:00"
|
||||
},
|
||||
{
|
||||
"name": "topthink/framework",
|
||||
"version": "v6.1.4",
|
||||
@ -2592,24 +2614,27 @@
|
||||
},
|
||||
{
|
||||
"name": "topthink/think-migration",
|
||||
"version": "v3.0.6",
|
||||
"version": "v3.1.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/top-think/think-migration.git",
|
||||
"reference": "82c4226cb14f973b9377c7fc6e89c525cbb8b030"
|
||||
"reference": "22c44058e1454f3af1d346e7f6524fbe654de7fb"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/top-think/think-migration/zipball/82c4226cb14f973b9377c7fc6e89c525cbb8b030",
|
||||
"reference": "82c4226cb14f973b9377c7fc6e89c525cbb8b030",
|
||||
"url": "https://api.github.com/repos/top-think/think-migration/zipball/22c44058e1454f3af1d346e7f6524fbe654de7fb",
|
||||
"reference": "22c44058e1454f3af1d346e7f6524fbe654de7fb",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.2",
|
||||
"topthink/framework": "^6.0 || ^8.0",
|
||||
"topthink/think-helper": "^3.0.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"fzaninotto/faker": "^1.8"
|
||||
"composer/composer": "^2.5.8",
|
||||
"fzaninotto/faker": "^1.8",
|
||||
"robmorgan/phinx": "^0.13.4"
|
||||
},
|
||||
"suggest": {
|
||||
"fzaninotto/faker": "Required to use the factory builder (^1.8)."
|
||||
@ -2624,7 +2649,7 @@
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Phinx\\": "phinx/src/Phinx",
|
||||
"Phinx\\": "phinx",
|
||||
"think\\migration\\": "src"
|
||||
}
|
||||
},
|
||||
@ -2640,9 +2665,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/top-think/think-migration/issues",
|
||||
"source": "https://github.com/top-think/think-migration/tree/v3.0.6"
|
||||
"source": "https://github.com/top-think/think-migration/tree/v3.1.1"
|
||||
},
|
||||
"time": "2023-07-01T11:01:52+00:00"
|
||||
"time": "2023-09-14T05:51:31+00:00"
|
||||
},
|
||||
{
|
||||
"name": "topthink/think-multi-app",
|
||||
@ -2829,51 +2854,6 @@
|
||||
},
|
||||
"time": "2019-11-06T11:40:13+00:00"
|
||||
},
|
||||
{
|
||||
"name": "wamkj/thinkphp6.0-databackup",
|
||||
"version": "v1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/wamkj/thinkphp6.0-databackup.git",
|
||||
"reference": "28a0e406d827132942723a3c9f69bb20c98e652f"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/wamkj/thinkphp6.0-databackup/zipball/28a0e406d827132942723a3c9f69bb20c98e652f",
|
||||
"reference": "28a0e406d827132942723a3c9f69bb20c98e652f",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.1.0",
|
||||
"topthink/framework": "^6.0"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"wamkj\\thinkphp\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"Apache-2.0"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "wamkj",
|
||||
"email": "1149183529@qq.com"
|
||||
}
|
||||
],
|
||||
"description": "thinkphp6.0的数据库自动备份扩展",
|
||||
"keywords": [
|
||||
"think-databackup",
|
||||
"thinkphp"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/wamkj/thinkphp6.0-databackup/issues",
|
||||
"source": "https://github.com/wamkj/thinkphp6.0-databackup/tree/v1.0"
|
||||
},
|
||||
"time": "2020-02-15T13:04:16+00:00"
|
||||
},
|
||||
{
|
||||
"name": "workerman/channel",
|
||||
"version": "v1.2.0",
|
||||
@ -2958,16 +2938,16 @@
|
||||
},
|
||||
{
|
||||
"name": "workerman/workerman",
|
||||
"version": "v4.1.13",
|
||||
"version": "v4.1.15",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/walkor/workerman.git",
|
||||
"reference": "807780ff672775fcd08f89e573a2824e939021ce"
|
||||
"reference": "afc8242fc769ab7cf22eb4ac22b97cb59d465e4e"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/walkor/workerman/zipball/807780ff672775fcd08f89e573a2824e939021ce",
|
||||
"reference": "807780ff672775fcd08f89e573a2824e939021ce",
|
||||
"url": "https://api.github.com/repos/walkor/workerman/zipball/afc8242fc769ab7cf22eb4ac22b97cb59d465e4e",
|
||||
"reference": "afc8242fc769ab7cf22eb4ac22b97cb59d465e4e",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -3017,7 +2997,7 @@
|
||||
"type": "patreon"
|
||||
}
|
||||
],
|
||||
"time": "2023-07-31T05:57:25+00:00"
|
||||
"time": "2024-02-19T02:10:39+00:00"
|
||||
},
|
||||
{
|
||||
"name": "yansongda/pay",
|
||||
@ -3159,21 +3139,21 @@
|
||||
},
|
||||
{
|
||||
"name": "yzh52521/easyhttp",
|
||||
"version": "v1.0.7",
|
||||
"version": "v1.1.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/yzh52521/easyhttp.git",
|
||||
"reference": "52cb9aba60a725bef77acd9c4c48ecc78931af9e"
|
||||
"url": "https://github.com/yuanzhihai/easyhttp.git",
|
||||
"reference": "02bcf47eaf723520fa3905d0e6f1852168fe646c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/yzh52521/easyhttp/zipball/52cb9aba60a725bef77acd9c4c48ecc78931af9e",
|
||||
"reference": "52cb9aba60a725bef77acd9c4c48ecc78931af9e",
|
||||
"url": "https://api.github.com/repos/yuanzhihai/easyhttp/zipball/02bcf47eaf723520fa3905d0e6f1852168fe646c",
|
||||
"reference": "02bcf47eaf723520fa3905d0e6f1852168fe646c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"guzzlehttp/guzzle": "^6.0|^7.0",
|
||||
"php": "^7.2.5|^8.0",
|
||||
"php": ">=7.2.5",
|
||||
"psr/log": "^1.0|^2.0|^3.0"
|
||||
},
|
||||
"type": "library",
|
||||
@ -3204,10 +3184,10 @@
|
||||
"phphttp"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/yzh52521/easyhttp/issues",
|
||||
"source": "https://github.com/yzh52521/easyhttp/tree/v1.0.7"
|
||||
"issues": "https://github.com/yuanzhihai/easyhttp/issues",
|
||||
"source": "https://github.com/yuanzhihai/easyhttp/tree/v1.1.3"
|
||||
},
|
||||
"time": "2023-02-16T03:04:02+00:00"
|
||||
"time": "2023-11-14T05:49:02+00:00"
|
||||
}
|
||||
],
|
||||
"packages-dev": [
|
||||
|
@ -16,7 +16,7 @@ return [
|
||||
// 应用名,此项不可更改
|
||||
'appname' => 'TaoLer',
|
||||
// 版本配置
|
||||
'version' => '2.3.9',
|
||||
'version' => '2.5.8',
|
||||
// 加盐
|
||||
'salt' => 'taoler',
|
||||
// 数据库备份目录
|
||||
|
@ -172,6 +172,15 @@ body,
|
||||
display: none;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 768px) {
|
||||
.pear-admin.banner-layout .layui-header .layui-logo {
|
||||
display: none;
|
||||
}
|
||||
.pear-admin.banner-layout .layui-header .layui-layout-left {
|
||||
left: 0px;
|
||||
}
|
||||
}
|
||||
|
||||
/** 收缩布局 */
|
||||
.pear-mini .layui-side .layui-logo .title {
|
||||
display: none;
|
||||
@ -465,7 +474,13 @@ body,
|
||||
-webkit-transition: all .3s;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 450px) {
|
||||
.pearone-color .layui-form-item .layui-input-inline {
|
||||
float: left !important;
|
||||
width: 190px !important;
|
||||
margin: 0 10px 0 0!important;
|
||||
}
|
||||
}
|
||||
.select-color {
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
327
public/static/admin/css/admin.dark.css
Normal file
327
public/static/admin/css/admin.dark.css
Normal file
@ -0,0 +1,327 @@
|
||||
/** loader */
|
||||
.pear-admin-dark .loader-wrapper,
|
||||
.pear-admin-dark .loader-wrapper .loader {
|
||||
background-color: #141414;
|
||||
}
|
||||
|
||||
/** layout */
|
||||
.pear-admin-dark .layui-layout {
|
||||
background-color: #141414;
|
||||
}
|
||||
|
||||
/** header */
|
||||
.pear-admin-dark .layui-header,
|
||||
.pear-admin-dark .layui-header .layui-logo {
|
||||
background-color: #141414 !important;
|
||||
box-shadow: none !important;
|
||||
border: none !important;
|
||||
}
|
||||
.pear-admin-dark .layui-header.auto-theme,
|
||||
.pear-admin-dark .layui-header.auto-theme .layui-logo {
|
||||
background-color: var(--global-primary-color) !important;
|
||||
}
|
||||
|
||||
.pear-admin-dark .layui-header.auto-theme .layui-logo .title {
|
||||
color: #ffffff !important;
|
||||
}
|
||||
|
||||
.pear-admin-dark .layui-header {
|
||||
border: 1px solid rgba(0, 0, 0, .40) !important;
|
||||
}
|
||||
|
||||
.pear-admin-dark .layui-header .layui-nav * {
|
||||
color: #ffffff !important;
|
||||
}
|
||||
|
||||
.pear-admin-dark .layui-header .layui-nav .layui-nav-child {
|
||||
box-shadow: 0 3px 4px rgba(0, 0, 0, .6) !important;
|
||||
background-color: #141414;
|
||||
border-color: #141414;
|
||||
}
|
||||
|
||||
.pear-admin-dark .layui-header .layui-nav .layui-nav-child dd > a:hover {
|
||||
background-color: #141414 !important;
|
||||
}
|
||||
|
||||
.pear-admin-dark .layui-header .pear-nav-control .layui-this a{
|
||||
background-color: #0c0c0c !important;
|
||||
}
|
||||
|
||||
.pear-admin-dark .auto-theme .layui-logo .title{
|
||||
color: var(--global-primary-color) !important;
|
||||
}
|
||||
|
||||
/** side */
|
||||
.pear-admin-dark .layui-side {
|
||||
box-shadow: 0 3px 4px rgba(0, 0, 0, .6) !important;
|
||||
}
|
||||
|
||||
.pear-admin-dark .layui-logo {
|
||||
border-color: rgba(0, 0, 0, .30) !important;
|
||||
}
|
||||
|
||||
.pear-admin-dark .layui-side .layui-logo,
|
||||
.pear-admin-dark .layui-side .layui-side-scroll,
|
||||
.pear-admin-dark .layui-side .layui-side-scroll .layui-nav-tree{
|
||||
background-color: #141414 !important;
|
||||
}
|
||||
|
||||
.pear-admin-dark .layui-side .layui-side-scroll .layui-nav-tree .layui-nav-child {
|
||||
background-color: rgba(0,0,0,.3)!important;
|
||||
}
|
||||
|
||||
.pear-admin-dark .layui-side .layui-side-scroll .layui-nav .layui-nav-item a,
|
||||
.pear-admin-dark .layui-side .layui-side-scroll .layui-nav .layui-nav-item a > .layui-nav-more {
|
||||
color: rgba(255,255,255,.7) !important;
|
||||
}
|
||||
|
||||
.pear-admin-dark .layui-side .layui-side-scroll .layui-nav .layui-nav-child dd.layui-this a,
|
||||
.pear-admin-dark .layui-side .layui-side-scroll .layui-nav .layui-nav-itemed > a,
|
||||
.pear-admin-dark .layui-side .layui-side-scroll .layui-nav .layui-nav-itemed > a > .layui-nav-more,
|
||||
.pear-admin-dark .layui-side .layui-side-scroll .layui-nav .layui-nav-item > a:hover {
|
||||
color: #ffffff !important;
|
||||
}
|
||||
|
||||
/** body */
|
||||
.pear-admin-dark .layui-body,
|
||||
.pear-admin-dark .layui-body .pear-tab-page-loading,
|
||||
.pear-admin-dark .layui-body .pear-page-loading {
|
||||
background-color: #0a0a0a !important;
|
||||
}
|
||||
|
||||
.pear-admin-dark .layui-body .layui-tab .layui-tab-title,
|
||||
.pear-admin-dark .layui-body .layui-tab .layui-tab-title li,
|
||||
.pear-admin-dark .layui-body .layui-tab .layui-tab-control li {
|
||||
background-color: #141414 !important;
|
||||
border-color:rgba(0, 0, 0, .30) !important;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.pear-admin-dark .layui-body .layui-tab .layui-tab-title li > span:first-child {
|
||||
background-color: #434343;
|
||||
}
|
||||
|
||||
.pear-admin-dark .layui-body .layui-tab .layui-nav-child.layui-anim {
|
||||
border-color: #141414;
|
||||
background-color: #141414 !important;
|
||||
}
|
||||
|
||||
.pear-admin-dark .layui-body .layui-tab .layui-nav-child.layui-anim a {
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.pear-admin-dark .layui-body .layui-tab .layui-nav-child.layui-anim a:hover {
|
||||
background-color: #0a0a0a;
|
||||
}
|
||||
|
||||
.pear-admin-dark .layui-body .layui-tab .layui-tab-close:hover {
|
||||
border-radius: 50%;
|
||||
background-color: #0a0a0a !important;
|
||||
}
|
||||
|
||||
.pear-admin-dark .pear-tab-page-menu ul li {
|
||||
color: #ffffff !important;
|
||||
}
|
||||
|
||||
.pear-admin-dark .layui-footer {
|
||||
background-color: #141414;
|
||||
border-top: 1px solid #141414;
|
||||
}
|
||||
|
||||
/** theme */
|
||||
.pear-admin-dark .set-text,
|
||||
.pear-admin-dark .select-color-title,
|
||||
.pear-admin-dark .color-title {
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
/** search */
|
||||
.pear-admin-dark .menu-search-no-data {
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.pear-admin-dark .menu-search-tips * {
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.pear-admin-dark .menu-search-tips kbd {
|
||||
border-color: rgba(0, 0, 0, .30) !important;
|
||||
}
|
||||
|
||||
|
||||
/** message center */
|
||||
.pear-admin-dark .pear-message-center .layui-tab-title,
|
||||
.pear-admin-dark .pear-message-center .message-item {
|
||||
border-color: rgba(0, 0, 0, .30) !important;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
/** button */
|
||||
.pear-admin-dark .layui-btn {
|
||||
color: #ffffff;
|
||||
border-color: #4C4D4F;
|
||||
}
|
||||
|
||||
/** layer */
|
||||
.pear-admin-dark .layui-layer {
|
||||
background-color: #141414;
|
||||
}
|
||||
|
||||
.pear-admin-dark .layui-layer-msg {
|
||||
border-color: #141414;
|
||||
}
|
||||
|
||||
.pear-admin-dark .layui-layer-msg .layui-layer-content {
|
||||
color: #E5EAF3;
|
||||
}
|
||||
|
||||
.pear-admin-dark .layui-layer .layui-layer-setwin > span,
|
||||
.pear-admin-dark .layui-layer .layui-layer-title {
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
/** card */
|
||||
.pear-admin-dark .layui-card {
|
||||
background-color: #1d1e1f !important;
|
||||
}
|
||||
|
||||
.pear-admin-dark .layui-card .layui-card-header {
|
||||
border-bottom-color: #414243;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.pear-admin-dark .layui-card .layui-card-body {
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
/** input */
|
||||
.pear-admin-dark .layui-input {
|
||||
background-color: transparent;
|
||||
color: #ffffff;
|
||||
border-color: rgba(0, 0, 0, .30) !important;
|
||||
}
|
||||
|
||||
/** switch */
|
||||
.pear-admin-dark .layui-form-switch {
|
||||
border-color: #484849;
|
||||
background-color: rgba(255,255,255,.08);
|
||||
}
|
||||
|
||||
/** table */
|
||||
.pear-admin-dark .layui-table {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.pear-admin-dark .layui-table tr:hover {
|
||||
background-color: #141414 !important;
|
||||
}
|
||||
|
||||
.pear-admin-dark .layui-table td,
|
||||
.pear-admin-dark .layui-table th,
|
||||
.pear-admin-dark .layui-table-view,
|
||||
.pear-admin-dark .layui-table-page,
|
||||
.pear-admin-dark .layui-table-tool,
|
||||
.pear-admin-dark .layui-table-header {
|
||||
border-color: rgba(0, 0, 0, .40) !important;
|
||||
}
|
||||
|
||||
.pear-admin-dark .layui-laypage select,
|
||||
.pear-admin-dark .layui-laypage button {
|
||||
border-color: rgba(0, 0, 0, .40) !important;
|
||||
color: #ffffff !important;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.pear-admin-dark .layui-table-tool-self > div {
|
||||
border-color: rgba(0, 0, 0, .40) !important;
|
||||
color: #ffffff !important;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
/** panel */
|
||||
.pear-admin-dark .layui-panel {
|
||||
background-color: #1d1e1f !important;
|
||||
border-color: #1d1e1f !important;
|
||||
}
|
||||
|
||||
/** menu */
|
||||
.pear-admin-dark .layui-menu {
|
||||
background-color: #1d1e1f !important;
|
||||
}
|
||||
|
||||
.pear-admin-dark .layui-menu .layui-menu-body-title,
|
||||
.pear-admin-dark .layui-menu .layui-menu-body-title:hover {
|
||||
color: #ffffff;
|
||||
background-color: #1d1e1f !important;
|
||||
}
|
||||
|
||||
/** timeline */
|
||||
.pear-admin-dark .layui-timeline-axis {
|
||||
background-color: rgb(29, 30, 31) !important;
|
||||
}
|
||||
|
||||
.pear-admin-dark .layui-timeline-item:before {
|
||||
background-color: #414243 !important;
|
||||
}
|
||||
|
||||
|
||||
/** toast */
|
||||
.pear-admin-dark .iziToast {
|
||||
background-color: #1f1f1f !important;
|
||||
}
|
||||
|
||||
/** console */
|
||||
|
||||
.pear-admin-dark .deputy,
|
||||
.pear-admin-dark .shortcut-menu {
|
||||
background-color: #141414 !important;
|
||||
}
|
||||
|
||||
.pear-admin-dark .deputy:hover,
|
||||
.pear-admin-dark .shortcut-menu:hover {
|
||||
box-shadow: 0 3px 4px rgba(0, 0, 0, .6) !important;
|
||||
}
|
||||
|
||||
.pear-admin-dark .message-board li {
|
||||
border-bottom: 1px solid rgba(0, 0, 0, .40) !important;
|
||||
}
|
||||
|
||||
/** analysis */
|
||||
.pear-admin-dark .top-panel-number {
|
||||
color: #ffffff !important;
|
||||
border-color: #414243;
|
||||
}
|
||||
|
||||
|
||||
.pear-admin-dark .dynamic-status dd {
|
||||
border-color: #414243;
|
||||
}
|
||||
|
||||
/** success failure */
|
||||
.pear-admin-dark .pear-result .content {
|
||||
background-color: rgba(153, 153, 153, 0.12);
|
||||
color: #E5EAF3;
|
||||
}
|
||||
|
||||
.pear-admin-dark .pear-result .title{
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.pear-admin-dark .pear-result .description{
|
||||
color: #8D9095;
|
||||
}
|
||||
|
||||
/** 403 404 500*/
|
||||
.pear-admin-dark .pear-exception .title p{
|
||||
color: #E5EAF3 !important;
|
||||
}
|
||||
|
||||
/** scroll */
|
||||
.pear-admin-dark *::-webkit-scrollbar-thumb {
|
||||
background: #141414;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.pear-admin-dark *::-webkit-scrollbar-thumb:hover {
|
||||
background: #0a0a0a;
|
||||
}
|
65
public/static/admin/css/other/analysis.css
Normal file
65
public/static/admin/css/other/analysis.css
Normal file
@ -0,0 +1,65 @@
|
||||
.top-panel {
|
||||
border-radius: 4px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.top-panel>.layui-card-body {
|
||||
height: 60px;
|
||||
}
|
||||
|
||||
.top-panel-number {
|
||||
line-height: 60px;
|
||||
font-size: 29px;
|
||||
border-right: 1px solid #eceff9;
|
||||
}
|
||||
|
||||
.top-panel-tips {
|
||||
padding-left: 8px;
|
||||
padding-top: 16px;
|
||||
line-height: 30px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.top-panel-tips i {
|
||||
font-size: 33px;
|
||||
}
|
||||
|
||||
.top-panel-tips svg {
|
||||
margin-top: -12px;
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
}
|
||||
|
||||
.dynamic-status {
|
||||
padding: 0 10px 10px;
|
||||
}
|
||||
|
||||
.dynamic-status dd {
|
||||
padding: 15px 0;
|
||||
border-bottom: 1px solid #EEE;
|
||||
display: -webkit-flex;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.dynamic-status dd div.dynamic-status-img {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border-radius: 50%;
|
||||
margin-right: 15px;
|
||||
}
|
||||
|
||||
.dynamic-status dd div.dynamic-status-img a {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: inline-block;
|
||||
text-align: center;
|
||||
line-height: 32px;
|
||||
}
|
||||
|
||||
.dynamic-status dd div span {
|
||||
color: #BBB;
|
||||
}
|
||||
|
||||
.dynamic-status dd div a {
|
||||
color: #01AAED;
|
||||
}
|
81
public/static/admin/css/other/console.css
Normal file
81
public/static/admin/css/other/console.css
Normal file
@ -0,0 +1,81 @@
|
||||
|
||||
.shortcut-menu {
|
||||
width: 100%;
|
||||
height: 66px;
|
||||
background-color: #F8F8F8;
|
||||
display: inline-block;
|
||||
border-radius: 5px;
|
||||
text-align: center;
|
||||
margin-bottom: 3px;
|
||||
}
|
||||
|
||||
.shortcut-menu i {
|
||||
font-size: 30px;
|
||||
height: 66px;
|
||||
line-height: 66px;
|
||||
}
|
||||
|
||||
.shortcut-menu:hover {
|
||||
box-shadow: 2px 0 8px 0 lightgray !important;
|
||||
}
|
||||
|
||||
.shortcut-menu-label {
|
||||
width: 100%;
|
||||
display: inline-block;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.deputy {
|
||||
width: 100%;
|
||||
height: 90px;
|
||||
background-color: #F8F8F8;
|
||||
display: inline-block;
|
||||
border-radius: 5px;
|
||||
text-align: center;
|
||||
margin-bottom: 3px;
|
||||
}
|
||||
|
||||
.deputy:hover {
|
||||
box-shadow: 2px 0 8px 0 lightgray !important;
|
||||
}
|
||||
|
||||
.deputy .deputy-label {
|
||||
color: gray;
|
||||
margin-top: 14px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.deputy .deputy-count {
|
||||
margin-top: 12px;
|
||||
color: var(--global-primary-color);
|
||||
font-size: 30px;
|
||||
}
|
||||
|
||||
.message-board {
|
||||
padding: 0 10px 10px;
|
||||
}
|
||||
|
||||
.message-board li {
|
||||
position: relative;
|
||||
padding: 10px 0;
|
||||
border-bottom: 1px solid #EEE;
|
||||
}
|
||||
|
||||
.message-board li p {
|
||||
padding-bottom: 10px;
|
||||
padding-top: 3px;
|
||||
}
|
||||
|
||||
.message-board li>span {
|
||||
color: #999;
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
.message-board .message-board-reply {
|
||||
position: absolute;
|
||||
right: 20px;
|
||||
bottom: 12px;
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
}
|
28
public/static/admin/css/other/exception.css
Normal file
28
public/static/admin/css/other/exception.css
Normal file
@ -0,0 +1,28 @@
|
||||
.pear-exception {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
text-align: center;
|
||||
box-sizing: border-box;
|
||||
padding: 70px 40px
|
||||
}
|
||||
|
||||
.pear-exception .title {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.pear-exception .title p {
|
||||
color: rgb(0, 0, 0);
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.pear-exception .description {
|
||||
margin-top: 10px;
|
||||
color: #8D9095;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.pear-exception .extra {
|
||||
margin: 30px;
|
||||
}
|
80
public/static/admin/css/other/profile.css
Normal file
80
public/static/admin/css/other/profile.css
Normal file
@ -0,0 +1,80 @@
|
||||
.text-center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.user-info-head {
|
||||
width: 110px;
|
||||
height: 110px;
|
||||
line-height: 110px;
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
border-radius: 50%;
|
||||
overflow: hidden;
|
||||
cursor: pointer;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.layui-line-dash {
|
||||
border-bottom: 1px dashed #ccc;
|
||||
margin: 15px 0;
|
||||
}
|
||||
|
||||
|
||||
.blog-title {
|
||||
padding-left: 13.5px;
|
||||
}
|
||||
|
||||
.blog-content {
|
||||
padding-left: 13px;
|
||||
font-size: 13px;
|
||||
color: dimgray;
|
||||
}
|
||||
|
||||
.layui-tab-title {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.fl-item {
|
||||
height: 30px;
|
||||
font-size: 13.5;
|
||||
}
|
||||
|
||||
.dot {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
border-radius: 50px;
|
||||
background-color: gray;
|
||||
display: inline-block;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.message-board {
|
||||
padding: 0 10px 10px;
|
||||
}
|
||||
|
||||
.message-board li {
|
||||
position: relative;
|
||||
padding: 10px 0;
|
||||
border-bottom: 1px solid #EEE;
|
||||
}
|
||||
|
||||
.message-board li p {
|
||||
padding-bottom: 10px;
|
||||
padding-top: 3px;
|
||||
}
|
||||
|
||||
.message-board li>span {
|
||||
color: #999;
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
.message-board .message-board-reply {
|
||||
position: absolute;
|
||||
right: 20px;
|
||||
bottom: 12px;
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
}
|
44
public/static/admin/css/reset.css
Normal file
44
public/static/admin/css/reset.css
Normal file
@ -0,0 +1,44 @@
|
||||
.layui-dropdown {
|
||||
border-radius: var(--global-border-radius);
|
||||
}
|
||||
|
||||
.layui-input {
|
||||
border-radius: var(--global-border-radius);
|
||||
}
|
||||
|
||||
.layui-form-onswitch {
|
||||
background-color: var(--global-primary-color) !important;
|
||||
}
|
||||
|
||||
.layui-form-onswitch {
|
||||
border-color: var(--global-primary-color);
|
||||
}
|
||||
|
||||
.layui-btn {
|
||||
background-color: var(--global-primary-color);
|
||||
}
|
||||
|
||||
.layui-btn.layui-btn-normal {
|
||||
background-color: #1e9fff !important;
|
||||
}
|
||||
|
||||
.layui-btn.layui-btn-danger {
|
||||
background-color: #ff5722 !important;
|
||||
}
|
||||
|
||||
.layui-btn.layui-btn-warm {
|
||||
background-color: #ffb800 !important;
|
||||
}
|
||||
|
||||
.layui-btn.layui-btn-primary {
|
||||
background-color: transparent !important;
|
||||
color: #5f5f5f !important;
|
||||
}
|
||||
|
||||
.layui-card {
|
||||
border-radius: var(--global-border-radius);
|
||||
}
|
||||
|
||||
.layui-timeline-axis {
|
||||
color: var(--global-primary-color);
|
||||
}
|
7
public/static/admin/css/variables.css
Normal file
7
public/static/admin/css/variables.css
Normal file
@ -0,0 +1,7 @@
|
||||
:root {
|
||||
|
||||
--global-primary-color: #16baaa;
|
||||
|
||||
--global-border-radius: 4px;
|
||||
|
||||
}
|
BIN
public/static/admin/images/banner.png
Normal file
BIN
public/static/admin/images/banner.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 9.9 MiB |
BIN
public/static/admin/images/blog.jpg
Normal file
BIN
public/static/admin/images/blog.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 197 KiB |
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
977
public/static/component/pear/css/module/global.css
Normal file
977
public/static/component/pear/css/module/global.css
Normal file
@ -0,0 +1,977 @@
|
||||
.pear-container {
|
||||
padding: 10px;
|
||||
margin: 0px;
|
||||
box-sizing: border-box;
|
||||
background-color: transparent;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
*::-webkit-scrollbar {
|
||||
width: 0px;
|
||||
height: 0px;
|
||||
}
|
||||
|
||||
*::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
}
|
||||
|
||||
*::-webkit-scrollbar-track {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
*::-webkit-scrollbar-thumb {
|
||||
background: #E6E6E6;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
*::-webkit-scrollbar-thumb:hover {
|
||||
background: #E6E6E6;
|
||||
}
|
||||
|
||||
*::-webkit-scrollbar-corner {
|
||||
background: #f6f6f6;
|
||||
}
|
||||
|
||||
.pear-row::after,
|
||||
.pear-row::before {
|
||||
content: "";
|
||||
display: table;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.pear-col {
|
||||
float: left;
|
||||
min-height: 1px;
|
||||
}
|
||||
|
||||
.pear-row * {
|
||||
box-sizing: border-box
|
||||
}
|
||||
|
||||
.pear-col-md1 {
|
||||
width: 4.16%;
|
||||
}
|
||||
|
||||
.pear-col-md2 {
|
||||
width: 8.33%;
|
||||
}
|
||||
|
||||
.pear-col-md3 {
|
||||
width: 12.5%;
|
||||
}
|
||||
|
||||
.pear-col-md4 {
|
||||
width: 16.66%;
|
||||
}
|
||||
|
||||
.pear-col-md5 {
|
||||
width: 20.83%;
|
||||
}
|
||||
|
||||
.pear-col-md6 {
|
||||
width: 25%;
|
||||
}
|
||||
|
||||
.pear-col-md7 {
|
||||
width: 29.16%;
|
||||
}
|
||||
|
||||
.pear-col-md8 {
|
||||
width: 33.33%;
|
||||
}
|
||||
|
||||
.pear-col-md9 {
|
||||
width: 37.5%;
|
||||
}
|
||||
|
||||
.pear-col-md10 {
|
||||
width: 41.66%;
|
||||
}
|
||||
|
||||
.pear-col-md11 {
|
||||
width: 45.83%;
|
||||
}
|
||||
|
||||
.pear-col-md12 {
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.pear-col-md13 {
|
||||
width: 54.16%;
|
||||
}
|
||||
|
||||
.pear-col-md14 {
|
||||
width: 58.33%;
|
||||
}
|
||||
|
||||
.pear-col-md15 {
|
||||
width: 62.5%;
|
||||
}
|
||||
|
||||
.pear-col-md16 {
|
||||
width: 66.66%;
|
||||
}
|
||||
|
||||
.pear-col-md17 {
|
||||
width: 70.83%;
|
||||
}
|
||||
|
||||
.pear-col-md18 {
|
||||
width: 75%;
|
||||
}
|
||||
|
||||
.pear-col-md19 {
|
||||
width: 79.16%;
|
||||
}
|
||||
|
||||
.pear-col-md20 {
|
||||
width: 83.33%;
|
||||
}
|
||||
|
||||
.pear-col-md21 {
|
||||
width: 87.5%;
|
||||
}
|
||||
|
||||
.pear-col-md22 {
|
||||
width: 91.66%;
|
||||
}
|
||||
|
||||
.pear-col-md23 {
|
||||
width: 95.83%;
|
||||
}
|
||||
|
||||
.pear-col-md24 {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.pear-col-md-offset1 {
|
||||
margin-left: 4.16%;
|
||||
}
|
||||
|
||||
.pear-col-md-offset2 {
|
||||
margin-left: 8.33%;
|
||||
}
|
||||
|
||||
.pear-col-md-offset3 {
|
||||
margin-left: 12.5%;
|
||||
}
|
||||
|
||||
.pear-col-md-offset4 {
|
||||
margin-left: 16.66%;
|
||||
}
|
||||
|
||||
.pear-col-md-offset5 {
|
||||
margin-left: 20.83%;
|
||||
}
|
||||
|
||||
.pear-col-md-offset6 {
|
||||
margin-left: 25%;
|
||||
}
|
||||
|
||||
.pear-col-md-offset7 {
|
||||
margin-left: 29.16%;
|
||||
}
|
||||
|
||||
.pear-col-md-offset8 {
|
||||
margin-left: 33.33%;
|
||||
}
|
||||
|
||||
.pear-col-md-offset9 {
|
||||
margin-left: 37.5%;
|
||||
}
|
||||
|
||||
.pear-col-md-offset10 {
|
||||
margin-left: 41.66%;
|
||||
}
|
||||
|
||||
.pear-col-md-offset11 {
|
||||
margin-left: 45.83%;
|
||||
}
|
||||
|
||||
.pear-col-md-offset12 {
|
||||
margin-left: 50%;
|
||||
}
|
||||
|
||||
.pear-col-md-offset13 {
|
||||
margin-left: 54.16%;
|
||||
}
|
||||
|
||||
.pear-col-md-offset14 {
|
||||
margin-left: 58.33%;
|
||||
}
|
||||
|
||||
.pear-col-md-offset15 {
|
||||
margin-left: 62.5%;
|
||||
}
|
||||
|
||||
.pear-col-md-offset16 {
|
||||
margin-left: 66.66%;
|
||||
}
|
||||
|
||||
.pear-col-md-offset17 {
|
||||
margin-left: 70.83%;
|
||||
}
|
||||
|
||||
.pear-col-md-offset18 {
|
||||
margin-left: 75%;
|
||||
}
|
||||
|
||||
.pear-col-md-offset19 {
|
||||
margin-left: 79.16%;
|
||||
}
|
||||
|
||||
.pear-col-md-offset20 {
|
||||
margin-left: 83.33%;
|
||||
}
|
||||
|
||||
.pear-col-md-offset21 {
|
||||
margin-left: 87.5%;
|
||||
}
|
||||
|
||||
.pear-col-md-offset22 {
|
||||
margin-left: 91.66%;
|
||||
}
|
||||
|
||||
.pear-col-md-offset23 {
|
||||
margin-left: 95.83%;
|
||||
}
|
||||
|
||||
.pear-col-md-offset24 {
|
||||
margin-left: 100%;
|
||||
}
|
||||
|
||||
|
||||
@media all and (max-width:768px) {
|
||||
.pear-col-xs1 {
|
||||
width: 4.16%;
|
||||
}
|
||||
|
||||
.pear-col-xs2 {
|
||||
width: 8.33%;
|
||||
}
|
||||
|
||||
.pear-col-xs3 {
|
||||
width: 12.5%;
|
||||
}
|
||||
|
||||
.pear-col-xs4 {
|
||||
width: 16.66%;
|
||||
}
|
||||
|
||||
.pear-col-xs5 {
|
||||
width: 20.83%;
|
||||
}
|
||||
|
||||
.pear-col-xs6 {
|
||||
width: 25%;
|
||||
}
|
||||
|
||||
.pear-col-xs7 {
|
||||
width: 29.16%;
|
||||
}
|
||||
|
||||
.pear-col-xs8 {
|
||||
width: 33.33%;
|
||||
}
|
||||
|
||||
.pear-col-xs9 {
|
||||
width: 37.5%;
|
||||
}
|
||||
|
||||
.pear-col-xs10 {
|
||||
width: 41.66%;
|
||||
}
|
||||
|
||||
.pear-col-xs11 {
|
||||
width: 45.83%;
|
||||
}
|
||||
|
||||
.pear-col-xs12 {
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.pear-col-xs13 {
|
||||
width: 54.16%;
|
||||
}
|
||||
|
||||
.pear-col-xs14 {
|
||||
width: 58.33%;
|
||||
}
|
||||
|
||||
.pear-col-xs15 {
|
||||
width: 62.5%;
|
||||
}
|
||||
|
||||
.pear-col-xs16 {
|
||||
width: 66.66%;
|
||||
}
|
||||
|
||||
.pear-col-xs17 {
|
||||
width: 70.83%;
|
||||
}
|
||||
|
||||
.pear-col-xs18 {
|
||||
width: 75%;
|
||||
}
|
||||
|
||||
.pear-col-xs19 {
|
||||
width: 79.16%;
|
||||
}
|
||||
|
||||
.pear-col-xs20 {
|
||||
width: 83.33%;
|
||||
}
|
||||
|
||||
.pear-col-xs21 {
|
||||
width: 87.5%;
|
||||
}
|
||||
|
||||
.pear-col-xs22 {
|
||||
width: 91.66%;
|
||||
}
|
||||
|
||||
.pear-col-xs23 {
|
||||
width: 95.83%;
|
||||
}
|
||||
|
||||
.pear-col-xs24 {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.pear-col-xs-offset1 {
|
||||
margin-left: 4.16%;
|
||||
}
|
||||
|
||||
.pear-col-xs-offset2 {
|
||||
margin-left: 8.33%;
|
||||
}
|
||||
|
||||
.pear-col-xs-offset3 {
|
||||
margin-left: 12.5%;
|
||||
}
|
||||
|
||||
.pear-col-xs-offset4 {
|
||||
margin-left: 16.66%;
|
||||
}
|
||||
|
||||
.pear-col-xs-offset5 {
|
||||
margin-left: 20.83%;
|
||||
}
|
||||
|
||||
.pear-col-xs-offset6 {
|
||||
margin-left: 25%;
|
||||
}
|
||||
|
||||
.pear-col-xs-offset7 {
|
||||
margin-left: 29.16%;
|
||||
}
|
||||
|
||||
.pear-col-xs-offset8 {
|
||||
margin-left: 33.33%;
|
||||
}
|
||||
|
||||
.pear-col-xs-offset9 {
|
||||
margin-left: 37.5%;
|
||||
}
|
||||
|
||||
.pear-col-xs-offset10 {
|
||||
margin-left: 41.66%;
|
||||
}
|
||||
|
||||
.pear-col-xs-offset11 {
|
||||
margin-left: 45.83%;
|
||||
}
|
||||
|
||||
.pear-col-xs-offset12 {
|
||||
margin-left: 50%;
|
||||
}
|
||||
|
||||
.pear-col-xs-offset13 {
|
||||
margin-left: 54.16%;
|
||||
}
|
||||
|
||||
.pear-col-xs-offset14 {
|
||||
margin-left: 58.33%;
|
||||
}
|
||||
|
||||
.pear-col-xs-offset15 {
|
||||
margin-left: 62.5%;
|
||||
}
|
||||
|
||||
.pear-col-xs-offset16 {
|
||||
margin-left: 66.66%;
|
||||
}
|
||||
|
||||
.pear-col-xs-offset17 {
|
||||
margin-left: 70.83%;
|
||||
}
|
||||
|
||||
.pear-col-xs-offset18 {
|
||||
margin-left: 75%;
|
||||
}
|
||||
|
||||
.pear-col-xs-offset19 {
|
||||
margin-left: 79.16%;
|
||||
}
|
||||
|
||||
.pear-col-xs-offset20 {
|
||||
margin-left: 83.33%;
|
||||
}
|
||||
|
||||
.pear-col-xs-offset21 {
|
||||
margin-left: 87.5%;
|
||||
}
|
||||
|
||||
.pear-col-xs-offset22 {
|
||||
margin-left: 91.66%;
|
||||
}
|
||||
|
||||
.pear-col-xs-offset23 {
|
||||
margin-left: 95.83%;
|
||||
}
|
||||
|
||||
.pear-col-xs-offset24 {
|
||||
margin-left: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
@media all and (min-width:768px) and (max-width:992px) {
|
||||
.pear-col-sm1 {
|
||||
width: 4.16%;
|
||||
}
|
||||
|
||||
.pear-col-sm2 {
|
||||
width: 8.33%;
|
||||
}
|
||||
|
||||
.pear-col-sm3 {
|
||||
width: 12.5%;
|
||||
}
|
||||
|
||||
.pear-col-sm4 {
|
||||
width: 16.66%;
|
||||
}
|
||||
|
||||
.pear-col-sm5 {
|
||||
width: 20.83%;
|
||||
}
|
||||
|
||||
.pear-col-sm6 {
|
||||
width: 25%;
|
||||
}
|
||||
|
||||
.pear-col-sm7 {
|
||||
width: 29.16%;
|
||||
}
|
||||
|
||||
.pear-col-sm8 {
|
||||
width: 33.33%;
|
||||
}
|
||||
|
||||
.pear-col-sm9 {
|
||||
width: 37.5%;
|
||||
}
|
||||
|
||||
.pear-col-sm10 {
|
||||
width: 41.66%;
|
||||
}
|
||||
|
||||
.pear-col-sm11 {
|
||||
width: 45.83%;
|
||||
}
|
||||
|
||||
.pear-col-sm12 {
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.pear-col-sm13 {
|
||||
width: 54.16%;
|
||||
}
|
||||
|
||||
.pear-col-sm14 {
|
||||
width: 58.33%;
|
||||
}
|
||||
|
||||
.pear-col-sm15 {
|
||||
width: 62.5%;
|
||||
}
|
||||
|
||||
.pear-col-sm16 {
|
||||
width: 66.66%;
|
||||
}
|
||||
|
||||
.pear-col-sm17 {
|
||||
width: 70.83%;
|
||||
}
|
||||
|
||||
.pear-col-sm18 {
|
||||
width: 75%;
|
||||
}
|
||||
|
||||
.pear-col-sm19 {
|
||||
width: 79.16%;
|
||||
}
|
||||
|
||||
.pear-col-sm20 {
|
||||
width: 83.33%;
|
||||
}
|
||||
|
||||
.pear-col-sm21 {
|
||||
width: 87.5%;
|
||||
}
|
||||
|
||||
.pear-col-sm22 {
|
||||
width: 91.66%;
|
||||
}
|
||||
|
||||
.pear-col-sm23 {
|
||||
width: 95.83%;
|
||||
}
|
||||
|
||||
.pear-col-sm24 {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.pear-col-sm-offset1 {
|
||||
margin-left: 4.16%;
|
||||
}
|
||||
|
||||
.pear-col-sm-offset2 {
|
||||
margin-left: 8.33%;
|
||||
}
|
||||
|
||||
.pear-col-sm-offset3 {
|
||||
margin-left: 12.5%;
|
||||
}
|
||||
|
||||
.pear-col-sm-offset4 {
|
||||
margin-left: 16.66%;
|
||||
}
|
||||
|
||||
.pear-col-sm-offset5 {
|
||||
margin-left: 20.83%;
|
||||
}
|
||||
|
||||
.pear-col-sm-offset6 {
|
||||
margin-left: 25%;
|
||||
}
|
||||
|
||||
.pear-col-sm-offset7 {
|
||||
margin-left: 29.16%;
|
||||
}
|
||||
|
||||
.pear-col-sm-offset8 {
|
||||
margin-left: 33.33%;
|
||||
}
|
||||
|
||||
.pear-col-sm-offset9 {
|
||||
margin-left: 37.5%;
|
||||
}
|
||||
|
||||
.pear-col-sm-offset10 {
|
||||
margin-left: 41.66%;
|
||||
}
|
||||
|
||||
.pear-col-sm-offset11 {
|
||||
margin-left: 45.83%;
|
||||
}
|
||||
|
||||
.pear-col-sm-offset12 {
|
||||
margin-left: 50%;
|
||||
}
|
||||
|
||||
.pear-col-sm-offset13 {
|
||||
margin-left: 54.16%;
|
||||
}
|
||||
|
||||
.pear-col-sm-offset14 {
|
||||
margin-left: 58.33%;
|
||||
}
|
||||
|
||||
.pear-col-sm-offset15 {
|
||||
margin-left: 62.5%;
|
||||
}
|
||||
|
||||
.pear-col-sm-offset16 {
|
||||
margin-left: 66.66%;
|
||||
}
|
||||
|
||||
.pear-col-sm-offset17 {
|
||||
margin-left: 70.83%;
|
||||
}
|
||||
|
||||
.pear-col-sm-offset18 {
|
||||
margin-left: 75%;
|
||||
}
|
||||
|
||||
.pear-col-sm-offset19 {
|
||||
margin-left: 79.16%;
|
||||
}
|
||||
|
||||
.pear-col-sm-offset20 {
|
||||
margin-left: 83.33%;
|
||||
}
|
||||
|
||||
.pear-col-sm-offset21 {
|
||||
margin-left: 87.5%;
|
||||
}
|
||||
|
||||
.pear-col-sm-offset22 {
|
||||
margin-left: 91.66%;
|
||||
}
|
||||
|
||||
.pear-col-sm-offset23 {
|
||||
margin-left: 95.83%;
|
||||
}
|
||||
|
||||
.pear-col-sm-offset24 {
|
||||
margin-left: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
@media all and (min-width:1200px) {
|
||||
.pear-col-lg1 {
|
||||
width: 4.16%;
|
||||
}
|
||||
|
||||
.pear-col-lg2 {
|
||||
width: 8.33%;
|
||||
}
|
||||
|
||||
.pear-col-lg3 {
|
||||
width: 12.5%;
|
||||
}
|
||||
|
||||
.pear-col-lg4 {
|
||||
width: 16.66%;
|
||||
}
|
||||
|
||||
.pear-col-lg5 {
|
||||
width: 20.83%;
|
||||
}
|
||||
|
||||
.pear-col-lg6 {
|
||||
width: 25%;
|
||||
}
|
||||
|
||||
.pear-col-lg7 {
|
||||
width: 29.16%;
|
||||
}
|
||||
|
||||
.pear-col-lg8 {
|
||||
width: 33.33%;
|
||||
}
|
||||
|
||||
.pear-col-lg9 {
|
||||
width: 37.5%;
|
||||
}
|
||||
|
||||
.pear-col-lg10 {
|
||||
width: 41.66%;
|
||||
}
|
||||
|
||||
.pear-col-lg11 {
|
||||
width: 45.83%;
|
||||
}
|
||||
|
||||
.pear-col-lg12 {
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.pear-col-lg13 {
|
||||
width: 54.16%;
|
||||
}
|
||||
|
||||
.pear-col-lg14 {
|
||||
width: 58.33%;
|
||||
}
|
||||
|
||||
.pear-col-lg15 {
|
||||
width: 62.5%;
|
||||
}
|
||||
|
||||
.pear-col-lg16 {
|
||||
width: 66.66%;
|
||||
}
|
||||
|
||||
.pear-col-lg17 {
|
||||
width: 70.83%;
|
||||
}
|
||||
|
||||
.pear-col-lg18 {
|
||||
width: 75%;
|
||||
}
|
||||
|
||||
.pear-col-lg19 {
|
||||
width: 79.16%;
|
||||
}
|
||||
|
||||
.pear-col-lg20 {
|
||||
width: 83.33%;
|
||||
}
|
||||
|
||||
.pear-col-lg21 {
|
||||
width: 87.5%;
|
||||
}
|
||||
|
||||
.pear-col-lg22 {
|
||||
width: 91.66%;
|
||||
}
|
||||
|
||||
.pear-col-lg23 {
|
||||
width: 95.83%;
|
||||
}
|
||||
|
||||
.pear-col-lg24 {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.pear-col-lg-offset1 {
|
||||
margin-left: 4.16%;
|
||||
}
|
||||
|
||||
.pear-col-lg-offset2 {
|
||||
margin-left: 8.33%;
|
||||
}
|
||||
|
||||
.pear-col-lg-offset3 {
|
||||
margin-left: 12.5%;
|
||||
}
|
||||
|
||||
.pear-col-lg-offset4 {
|
||||
margin-left: 16.66%;
|
||||
}
|
||||
|
||||
.pear-col-lg-offset5 {
|
||||
margin-left: 20.83%;
|
||||
}
|
||||
|
||||
.pear-col-lg-offset6 {
|
||||
margin-left: 25%;
|
||||
}
|
||||
|
||||
.pear-col-lg-offset7 {
|
||||
margin-left: 29.16%;
|
||||
}
|
||||
|
||||
.pear-col-lg-offset8 {
|
||||
margin-left: 33.33%;
|
||||
}
|
||||
|
||||
.pear-col-lg-offset9 {
|
||||
margin-left: 37.5%;
|
||||
}
|
||||
|
||||
.pear-col-lg-offset10 {
|
||||
margin-left: 41.66%;
|
||||
}
|
||||
|
||||
.pear-col-lg-offset11 {
|
||||
margin-left: 45.83%;
|
||||
}
|
||||
|
||||
.pear-col-lg-offset12 {
|
||||
margin-left: 50%;
|
||||
}
|
||||
|
||||
.pear-col-lg-offset13 {
|
||||
margin-left: 54.16%;
|
||||
}
|
||||
|
||||
.pear-col-lg-offset14 {
|
||||
margin-left: 58.33%;
|
||||
}
|
||||
|
||||
.pear-col-lg-offset15 {
|
||||
margin-left: 62.5%;
|
||||
}
|
||||
|
||||
.pear-col-lg-offset16 {
|
||||
margin-left: 66.66%;
|
||||
}
|
||||
|
||||
.pear-col-lg-offset17 {
|
||||
margin-left: 70.83%;
|
||||
}
|
||||
|
||||
.pear-col-lg-offset18 {
|
||||
margin-left: 75%;
|
||||
}
|
||||
|
||||
.pear-col-lg-offset19 {
|
||||
margin-left: 79.16%;
|
||||
}
|
||||
|
||||
.pear-col-lg-offset20 {
|
||||
margin-left: 83.33%;
|
||||
}
|
||||
|
||||
.pear-col-lg-offset21 {
|
||||
margin-left: 87.5%;
|
||||
}
|
||||
|
||||
.pear-col-lg-offset22 {
|
||||
margin-left: 91.66%;
|
||||
}
|
||||
|
||||
.pear-col-lg-offset23 {
|
||||
margin-left: 95.83%;
|
||||
}
|
||||
|
||||
.pear-col-lg-offset24 {
|
||||
margin-left: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.pear-col-space1 {
|
||||
margin: -.5px
|
||||
}
|
||||
|
||||
.pear-col-space1>* {
|
||||
padding: .5px
|
||||
}
|
||||
|
||||
.pear-col-space2 {
|
||||
margin: -1px
|
||||
}
|
||||
|
||||
.pear-col-space2>* {
|
||||
padding: 1px
|
||||
}
|
||||
|
||||
.pear-col-space4 {
|
||||
margin: -2px
|
||||
}
|
||||
|
||||
.pear-col-space4>* {
|
||||
padding: 2px
|
||||
}
|
||||
|
||||
.pear-col-space5 {
|
||||
margin: -2.5px
|
||||
}
|
||||
|
||||
.pear-col-space5>* {
|
||||
padding: 2.5px
|
||||
}
|
||||
|
||||
.pear-col-space6 {
|
||||
margin: -3px
|
||||
}
|
||||
|
||||
.pear-col-space6>* {
|
||||
padding: 3px
|
||||
}
|
||||
|
||||
.pear-col-space8 {
|
||||
margin: -4px
|
||||
}
|
||||
|
||||
.pear-col-space8>* {
|
||||
padding: 4px
|
||||
}
|
||||
|
||||
.pear-col-space10 {
|
||||
margin: -5px
|
||||
}
|
||||
|
||||
.pear-col-space10>* {
|
||||
padding: 5px
|
||||
}
|
||||
|
||||
.pear-col-space12 {
|
||||
margin: -6px
|
||||
}
|
||||
|
||||
.pear-col-space12>* {
|
||||
padding: 6px
|
||||
}
|
||||
|
||||
.pear-col-space14 {
|
||||
margin: -7px
|
||||
}
|
||||
|
||||
.pear-col-space14>* {
|
||||
padding: 7px
|
||||
}
|
||||
|
||||
.pear-col-space15 {
|
||||
margin: -7.5px
|
||||
}
|
||||
|
||||
.pear-col-space15>* {
|
||||
padding: 7.5px
|
||||
}
|
||||
|
||||
.pear-col-space16 {
|
||||
margin: -8px
|
||||
}
|
||||
|
||||
.pear-col-space16>* {
|
||||
padding: 8px
|
||||
}
|
||||
|
||||
.pear-col-space18 {
|
||||
margin: -9px
|
||||
}
|
||||
|
||||
.pear-col-space18>* {
|
||||
padding: 9px
|
||||
}
|
||||
|
||||
.pear-col-space20 {
|
||||
margin: -10px
|
||||
}
|
||||
|
||||
.pear-col-space20>* {
|
||||
padding: 10px
|
||||
}
|
||||
|
||||
.pear-col-space22 {
|
||||
margin: -11px
|
||||
}
|
||||
|
||||
.pear-col-space22>* {
|
||||
padding: 11px
|
||||
}
|
||||
|
||||
.pear-col-space24 {
|
||||
margin: -12px
|
||||
}
|
||||
|
||||
.pear-col-space24>* {
|
||||
padding: 12px
|
||||
}
|
||||
|
||||
.pear-col-space25 {
|
||||
margin: -12.5px
|
||||
}
|
||||
|
||||
.pear-col-space25>* {
|
||||
padding: 12.5px
|
||||
}
|
||||
|
||||
.pear-col-space26 {
|
||||
margin: -13px
|
||||
}
|
||||
|
||||
.pear-col-space26>* {
|
||||
padding: 13px
|
||||
}
|
||||
|
||||
.pear-col-space28 {
|
||||
margin: -14px
|
||||
}
|
||||
|
||||
.pear-col-space28>* {
|
||||
padding: 14px
|
||||
}
|
||||
|
||||
.pear-col-space30 {
|
||||
margin: -15px
|
||||
}
|
||||
|
||||
.pear-col-space30>* {
|
||||
padding: 15px
|
||||
}
|
90
public/static/component/pear/css/module/menuSearch.css
Normal file
90
public/static/component/pear/css/module/menuSearch.css
Normal file
@ -0,0 +1,90 @@
|
||||
/* 搜索面板 */
|
||||
.menu-search-content .layui-input {
|
||||
padding-left: 30px;
|
||||
}
|
||||
|
||||
.menu-search-content .layui-input:focus {
|
||||
border: 1px solid var(--global-primary-color)!important;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.menu-search-content {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.menu-search-input-wrapper {
|
||||
width: 100%;
|
||||
padding: 15px 15px;
|
||||
}
|
||||
|
||||
.menu-search-no-data {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
height: 122px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.menu-search-list {
|
||||
width: 100%;
|
||||
padding: 5px 15px;
|
||||
}
|
||||
|
||||
.menu-search-list li {
|
||||
position: relative;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
flex-wrap: nowrap;
|
||||
height: 50px;
|
||||
margin-bottom: 8px;
|
||||
padding: 0px 10px;
|
||||
color: currentColor;
|
||||
font-size: 14px;
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 1px 3px #d4d9e1;
|
||||
cursor: pointer;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.menu-search-list li.this,
|
||||
.menu-search-list li:hover {
|
||||
background-color: var(--global-primary-color);
|
||||
color: white;
|
||||
}
|
||||
.menu-search-tips {
|
||||
margin-bottom: 15px;
|
||||
padding: 0 15px;
|
||||
width: 100%
|
||||
}
|
||||
|
||||
.menu-search-tips>div {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.menu-search-tips .mr-1 {
|
||||
margin-right: 4px;
|
||||
}
|
||||
|
||||
.menu-search-tips .mr-5 {
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
.menu-search-tips .w-5 {
|
||||
width: 14px;
|
||||
}
|
||||
|
||||
.menu-search-tips kbd {
|
||||
line-height: 1.5;
|
||||
border: 1px solid #e5e7eb;
|
||||
font-size: 10px;
|
||||
text-align: center;
|
||||
padding: 2px 6px;
|
||||
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, Liberation Mono, Courier New, monospace;
|
||||
border-radius: 5px;
|
||||
}
|
39
public/static/component/pear/css/module/messageCenter.css
Normal file
39
public/static/component/pear/css/module/messageCenter.css
Normal file
@ -0,0 +1,39 @@
|
||||
.pear-message-center {
|
||||
width: 360px;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.pear-message-center .layui-tab .layui-tab-title{
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.pear-message-center .layui-tab .layui-tab-title .layui-this::after {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.pear-message-center .layui-tab .layui-tab-title li {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.pear-message-center .message-item img {
|
||||
margin-left: 8px;
|
||||
width: 33px !important;
|
||||
height: 33px !important;
|
||||
border-radius: 50px;
|
||||
margin-right: 15px;
|
||||
}
|
||||
|
||||
.pear-message-center .message-item {
|
||||
height: 64px !important;
|
||||
line-height: 45px !important;
|
||||
padding-right: 20px;
|
||||
padding-left: 20px;
|
||||
border-bottom: 1px solid whitesmoke;
|
||||
padding-top: 10px;
|
||||
padding-bottom: 15px;
|
||||
}
|
||||
|
||||
.pear-message-center .message-item .extra {
|
||||
float: right;
|
||||
right: 10px;
|
||||
}
|
154
public/static/component/pear/css/module/page.css
Normal file
154
public/static/component/pear/css/module/page.css
Normal file
@ -0,0 +1,154 @@
|
||||
.pear-page {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
overflow-y: auto;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.pear-page .dot {
|
||||
width: 5px;
|
||||
height: 24px;
|
||||
background-color: #5FB878;
|
||||
margin-top: 8px;
|
||||
margin-left: 15px;
|
||||
border-radius: 2px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.pear-page .pear-page-title {
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
background-color: white;
|
||||
border: whitesmoke 1px solid;
|
||||
}
|
||||
|
||||
.pear-page .pear-page-content,
|
||||
.pear-page .pear-page-content iframe {
|
||||
width: 100%;
|
||||
height: calc(100% - 0px) !important;
|
||||
}
|
||||
|
||||
.pear-page .pear-page-content iframe {
|
||||
height: calc(100% - 4px) !important;
|
||||
}
|
||||
|
||||
.pear-page-loading {
|
||||
position: absolute;
|
||||
display: none;
|
||||
width: 100%;
|
||||
height: calc(100% - 0px) !important;
|
||||
background-color: #fff;
|
||||
top: 0px;
|
||||
z-index: 19;
|
||||
}
|
||||
|
||||
.pear-page-loading.close {
|
||||
animation: close 1s;
|
||||
-webkit-animation: close 1s;
|
||||
animation-fill-mode: forwards;
|
||||
}
|
||||
|
||||
.ball-loader {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
-ms-transform: translate(-50%, -50%);
|
||||
-webkit-transform: translate(-50%, -50%)
|
||||
}
|
||||
|
||||
.ball-loader>span,
|
||||
.signal-loader>span {
|
||||
background-color: #4aca85;
|
||||
display: inline-block
|
||||
}
|
||||
|
||||
.ball-loader>span:nth-child(1),
|
||||
.ball-loader.sm>span:nth-child(1),
|
||||
.signal-loader>span:nth-child(1),
|
||||
.signal-loader.sm>span:nth-child(1) {
|
||||
-webkit-animation-delay: 0s;
|
||||
animation-delay: 0s
|
||||
}
|
||||
|
||||
.ball-loader>span:nth-child(2),
|
||||
.ball-loader.sm>span:nth-child(2),
|
||||
.signal-loader>span:nth-child(2),
|
||||
.signal-loader.sm>span:nth-child(2) {
|
||||
-webkit-animation-delay: .1s;
|
||||
animation-delay: .1s
|
||||
}
|
||||
|
||||
.ball-loader>span:nth-child(3),
|
||||
.ball-loader.sm>span:nth-child(3),
|
||||
.signal-loader>span:nth-child(3),
|
||||
.signal-loader.sm>span:nth-child(3) {
|
||||
-webkit-animation-delay: .15s;
|
||||
animation-delay: .15s
|
||||
}
|
||||
|
||||
.ball-loader>span:nth-child(4),
|
||||
.ball-loader.sm>span:nth-child(4),
|
||||
.signal-loader>span:nth-child(4),
|
||||
.signal-loader.sm>span:nth-child(4) {
|
||||
-webkit-animation-delay: .2s;
|
||||
animation-delay: .2s
|
||||
}
|
||||
|
||||
.ball-loader>span {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
margin: 0 3px;
|
||||
border-radius: 50%;
|
||||
transform: scale(0);
|
||||
-ms-transform: scale(0);
|
||||
-webkit-transform: scale(0);
|
||||
animation: ball-load 1s ease-in-out infinite;
|
||||
-webkit-animation: 1s ball-load ease-in-out infinite
|
||||
}
|
||||
|
||||
@-webkit-keyframes ball-load {
|
||||
0% {
|
||||
transform: scale(0);
|
||||
-webkit-transform: scale(0)
|
||||
}
|
||||
|
||||
50% {
|
||||
transform: scale(1);
|
||||
-webkit-transform: scale(1)
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: scale(0);
|
||||
-webkit-transform: scale(0)
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes ball-load {
|
||||
0% {
|
||||
transform: scale(0);
|
||||
-webkit-transform: scale(0)
|
||||
}
|
||||
|
||||
50% {
|
||||
transform: scale(1);
|
||||
-webkit-transform: scale(1)
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: scale(0);
|
||||
-webkit-transform: scale(0)
|
||||
}
|
||||
}
|
||||
|
||||
@-webkit-keyframes close {
|
||||
0% {
|
||||
opacity: 1;
|
||||
/*display: block;*/
|
||||
}
|
||||
|
||||
100% {
|
||||
opacity: 0;
|
||||
/*display: none;*/
|
||||
}
|
||||
}
|
314
public/static/component/pear/css/module/tabPage.css
Normal file
314
public/static/component/pear/css/module/tabPage.css
Normal file
@ -0,0 +1,314 @@
|
||||
.pear-tab-page {
|
||||
margin: 0px;
|
||||
overflow: hidden;
|
||||
height: 100% !important;
|
||||
}
|
||||
|
||||
.pear-tab-page .layui-tab-content {
|
||||
height: calc(100% - 42px) !important;
|
||||
}
|
||||
|
||||
.pear-tab-page .layui-tab-content .layui-tab-item {
|
||||
overflow-y: auto;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.pear-tab-page-menu{
|
||||
box-shadow: none;
|
||||
border-radius: 4px!important;
|
||||
overflow: hidden;
|
||||
box-shadow: 2px 0 6px rgba(0, 21, 41, .10);
|
||||
}
|
||||
|
||||
.pear-tab-page-menu .item{
|
||||
height: 20px;
|
||||
padding-left: 18px;
|
||||
padding-top: 7px;
|
||||
padding-bottom: 7px;
|
||||
color: #333;
|
||||
font-size: 13.5px;
|
||||
line-height: 20px;
|
||||
cursor:pointer;
|
||||
}
|
||||
.pear-tab-page-menu .item:hover{
|
||||
background: var(--global-primary-color);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.pear-tab-page .layui-tab-content {
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
.pear-tab-page > .layui-tab-title {
|
||||
border: none;
|
||||
border: 1px solid whitesmoke;
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
.pear-tab-page > .layui-tab-title li {
|
||||
border-right: 1px solid whitesmoke;
|
||||
color: dimgray;
|
||||
font-size: 13.5px;
|
||||
}
|
||||
|
||||
.pear-tab-page > .layui-tab-title .layui-tab-bar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.pear-tab-page .layui-nav-more {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.pear-tab-page > .layui-tab-title .layui-this:after {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.pear-tab-page > .layui-tab-title .pear-tab-page-active {
|
||||
display: inline-block;
|
||||
background-color: lightgray;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 30px;
|
||||
margin-right: 12px;
|
||||
}
|
||||
|
||||
.pear-tab-page > .layui-tab-title .layui-this .pear-tab-page-active {
|
||||
background-color: var(--global-primary-color) !important;
|
||||
}
|
||||
|
||||
.pear-tab-page > .layui-tab-title .layui-tab-close:hover {
|
||||
background-color: white;
|
||||
line-height: 19px;
|
||||
color: gray;
|
||||
}
|
||||
|
||||
.pear-tab-page > .layui-tab-title .disable-close+.layui-tab-close {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.pear-tab-page > .layui-tab-title .able-close+.layui-tab-close {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.pear-tab-page .layui-tab-close{
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.pear-tab-page .layui-tab-control>li {
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
width: 40px;
|
||||
background-color: white;
|
||||
border-top: whitesmoke 1px solid;
|
||||
border-bottom: whitesmoke 1px solid;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.pear-tab-page .layui-tab-prev {
|
||||
left: 0px;
|
||||
border-right: whitesmoke 1px solid;
|
||||
}
|
||||
|
||||
.pear-tab-page .layui-tab-next {
|
||||
right: 40px;
|
||||
border-left: 1px solid whitesmoke;
|
||||
}
|
||||
|
||||
.pear-tab-page .layui-tab-tool {
|
||||
right: 0px;
|
||||
border-left: 1px solid whitesmoke;
|
||||
}
|
||||
|
||||
.pear-tab-page .layui-tab-control .layui-tab-tool,
|
||||
.pear-tab-page .layui-tab-control .layui-tab-prev,
|
||||
.pear-tab-page .layui-tab-control .layui-tab-next {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.pear-tab-page.layui-tab-roll .layui-tab-control .layui-tab-prev,
|
||||
.pear-tab-page.layui-tab-roll .layui-tab-control .layui-tab-next {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.pear-tab-page.layui-tab-roll .layui-tab-control .layui-tab-next {
|
||||
right: 0px;
|
||||
border-right: 1px solid whitesmoke;
|
||||
}
|
||||
|
||||
.pear-tab-page.layui-tab-roll .layui-tab-title {
|
||||
padding-left: 40px;
|
||||
padding-right: 40px;
|
||||
}
|
||||
|
||||
.pear-tab-page.layui-tab-tool .layui-tab-control .layui-tab-tool {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.pear-tab-page.layui-tab-tool .layui-tab-title {
|
||||
padding-left: 0px;
|
||||
padding-right: 40px;
|
||||
}
|
||||
|
||||
.pear-tab-page.layui-tab-rollTool > .layui-tab-title {
|
||||
padding-left: 40px;
|
||||
padding-right: 80px;
|
||||
}
|
||||
|
||||
.pear-tab-page.layui-tab-rollTool .layui-tab-control .layui-tab-prev,
|
||||
.pear-tab-page.layui-tab-rollTool .layui-tab-control .layui-tab-next,
|
||||
.pear-tab-page.layui-tab-rollTool .layui-tab-control .layui-tab-tool {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.pear-tab-page .layui-tab-tool .layui-nav {
|
||||
position: absolute;
|
||||
height: 43px !important;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 0;
|
||||
background: 0 0;
|
||||
}
|
||||
|
||||
.pear-tab-page .layui-tab-tool .layui-nav-item {
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.pear-tab-page .layui-tab-tool .layui-nav-bar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.pear-tab-page .layui-tab-tool .layui-nav-child {
|
||||
left: auto;
|
||||
top: 45px;
|
||||
right: 3px;
|
||||
width: 120px;
|
||||
border: 1px solid whitesmoke;
|
||||
}
|
||||
|
||||
.pear-tab-page .layui-tab-tool .layui-this a {
|
||||
background-color: #009688;
|
||||
}
|
||||
|
||||
.pear-tab-page-loading {
|
||||
position: absolute;
|
||||
display: none;
|
||||
width: 100%;
|
||||
height: calc(100% - 42px);
|
||||
top: 42px;
|
||||
z-index: 19;
|
||||
background-color: #fff
|
||||
}
|
||||
|
||||
.pear-tab-page-loading.close {
|
||||
animation: close 1s;
|
||||
-webkit-animation: close 1s;
|
||||
animation-fill-mode: forwards;
|
||||
}
|
||||
|
||||
.ball-loader {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
-ms-transform: translate(-50%, -50%);
|
||||
-webkit-transform: translate(-50%, -50%)
|
||||
}
|
||||
|
||||
.ball-loader>span,
|
||||
.signal-loader>span {
|
||||
background-color: var(--global-primary-color) !important;
|
||||
display: inline-block
|
||||
}
|
||||
|
||||
.ball-loader>span:nth-child(1),
|
||||
.ball-loader.sm>span:nth-child(1),
|
||||
.signal-loader>span:nth-child(1),
|
||||
.signal-loader.sm>span:nth-child(1) {
|
||||
-webkit-animation-delay: 0s;
|
||||
animation-delay: 0s
|
||||
}
|
||||
|
||||
.ball-loader>span:nth-child(2),
|
||||
.ball-loader.sm>span:nth-child(2),
|
||||
.signal-loader>span:nth-child(2),
|
||||
.signal-loader.sm>span:nth-child(2) {
|
||||
-webkit-animation-delay: .1s;
|
||||
animation-delay: .1s
|
||||
}
|
||||
|
||||
.ball-loader>span:nth-child(3),
|
||||
.ball-loader.sm>span:nth-child(3),
|
||||
.signal-loader>span:nth-child(3),
|
||||
.signal-loader.sm>span:nth-child(3) {
|
||||
-webkit-animation-delay: .15s;
|
||||
animation-delay: .15s
|
||||
}
|
||||
|
||||
.ball-loader>span:nth-child(4),
|
||||
.ball-loader.sm>span:nth-child(4),
|
||||
.signal-loader>span:nth-child(4),
|
||||
.signal-loader.sm>span:nth-child(4) {
|
||||
-webkit-animation-delay: .2s;
|
||||
animation-delay: .2s
|
||||
}
|
||||
|
||||
.ball-loader>span {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
margin: 0 3px;
|
||||
border-radius: 50%;
|
||||
transform: scale(0);
|
||||
-ms-transform: scale(0);
|
||||
-webkit-transform: scale(0);
|
||||
animation: ball-load 1s ease-in-out infinite;
|
||||
-webkit-animation: 1s ball-load ease-in-out infinite
|
||||
}
|
||||
|
||||
@-webkit-keyframes ball-load {
|
||||
0% {
|
||||
transform: scale(0);
|
||||
-webkit-transform: scale(0)
|
||||
}
|
||||
|
||||
50% {
|
||||
transform: scale(1);
|
||||
-webkit-transform: scale(1)
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: scale(0);
|
||||
-webkit-transform: scale(0)
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes ball-load {
|
||||
0% {
|
||||
transform: scale(0);
|
||||
-webkit-transform: scale(0)
|
||||
}
|
||||
|
||||
50% {
|
||||
transform: scale(1);
|
||||
-webkit-transform: scale(1)
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: scale(0);
|
||||
-webkit-transform: scale(0)
|
||||
}
|
||||
}
|
||||
|
||||
@-webkit-keyframes close {
|
||||
0% {
|
||||
opacity: 1;
|
||||
/*display: block;*/
|
||||
}
|
||||
|
||||
100% {
|
||||
opacity: 0;
|
||||
/*display: none;*/
|
||||
}
|
||||
}
|
@ -2,7 +2,7 @@ layui.define(['message', 'table', 'jquery', 'element', 'yaml', 'form', 'tab', 'm
|
||||
function(exports) {
|
||||
"use strict";
|
||||
|
||||
var $ = layui.jquery,
|
||||
const $ = layui.jquery,
|
||||
form = layui.form,
|
||||
element = layui.element,
|
||||
yaml = layui.yaml,
|
||||
@ -12,30 +12,31 @@ layui.define(['message', 'table', 'jquery', 'element', 'yaml', 'form', 'tab', 'm
|
||||
pearFrame = layui.frame,
|
||||
pearTheme = layui.theme,
|
||||
message = layui.message,
|
||||
fullscreen=layui.fullscreen;
|
||||
fullscreen = layui.fullscreen;
|
||||
|
||||
var bodyFrame;
|
||||
var sideMenu;
|
||||
var bodyTab;
|
||||
var config;
|
||||
var logout = function() {};
|
||||
var msgInstance;
|
||||
var body = $('body');
|
||||
let bodyFrame;
|
||||
let sideMenu;
|
||||
let bodyTab;
|
||||
let config;
|
||||
let logout = function () {
|
||||
};
|
||||
let msgInstance;
|
||||
const body = $('body');
|
||||
|
||||
var pearAdmin = new function() {
|
||||
const pearAdmin = new function () {
|
||||
|
||||
var configType = 'yml';
|
||||
var configPath = 'pear.config.yml';
|
||||
let configType = 'yml';
|
||||
let configPath = 'pear.config.yml';
|
||||
|
||||
this.setConfigPath = function(path) {
|
||||
this.setConfigPath = function (path) {
|
||||
configPath = path;
|
||||
}
|
||||
|
||||
this.setConfigType = function(type) {
|
||||
this.setConfigType = function (type) {
|
||||
configType = type;
|
||||
}
|
||||
|
||||
this.render = function(initConfig) {
|
||||
this.render = function (initConfig) {
|
||||
if (initConfig !== undefined) {
|
||||
applyConfig(initConfig);
|
||||
} else {
|
||||
@ -43,11 +44,11 @@ layui.define(['message', 'table', 'jquery', 'element', 'yaml', 'form', 'tab', 'm
|
||||
}
|
||||
}
|
||||
|
||||
this.readConfig = function() {
|
||||
this.readConfig = function () {
|
||||
if (configType === "yml") {
|
||||
return yaml.load(configPath);
|
||||
} else {
|
||||
var data;
|
||||
let data;
|
||||
$.ajax({
|
||||
url: configPath,
|
||||
type: 'get',
|
||||
@ -61,8 +62,8 @@ layui.define(['message', 'table', 'jquery', 'element', 'yaml', 'form', 'tab', 'm
|
||||
}
|
||||
}
|
||||
|
||||
this.messageRender = function(option) {
|
||||
var option = {
|
||||
this.messageRender = function (option) {
|
||||
option = {
|
||||
elem: '.message',
|
||||
url: option.header.message,
|
||||
height: '250px'
|
||||
@ -70,12 +71,12 @@ layui.define(['message', 'table', 'jquery', 'element', 'yaml', 'form', 'tab', 'm
|
||||
msgInstance = message.render(option);
|
||||
}
|
||||
|
||||
this.logoRender = function(param) {
|
||||
this.logoRender = function (param) {
|
||||
$(".layui-logo .logo").attr("src", param.logo.image);
|
||||
$(".layui-logo .title").html(param.logo.title);
|
||||
}
|
||||
|
||||
this.menuRender = function(param) {
|
||||
this.menuRender = function (param) {
|
||||
sideMenu = pearMenu.render({
|
||||
elem: 'sideMenu',
|
||||
async: param.menu.async !== undefined ? param.menu.async : true,
|
||||
@ -83,16 +84,15 @@ layui.define(['message', 'table', 'jquery', 'element', 'yaml', 'form', 'tab', 'm
|
||||
height: '100%',
|
||||
method: param.menu.method,
|
||||
control: isControl(param) === 'true' || isControl(param) === true ? 'control' : false, // control
|
||||
controlWidth: param.menu.controlWidth,
|
||||
defaultMenu: 0,
|
||||
accordion: param.menu.accordion,
|
||||
url: param.menu.data,
|
||||
data: param.menu.data,
|
||||
parseData: false,
|
||||
change: function() {
|
||||
change: function () {
|
||||
compatible();
|
||||
},
|
||||
done: function() {
|
||||
done: function () {
|
||||
sideMenu.isCollapse = param.menu.collapse;
|
||||
sideMenu.selectItem(param.menu.select);
|
||||
pearAdmin.collapse(param);
|
||||
@ -100,9 +100,9 @@ layui.define(['message', 'table', 'jquery', 'element', 'yaml', 'form', 'tab', 'm
|
||||
});
|
||||
}
|
||||
|
||||
this.bodyRender = function(param) {
|
||||
this.bodyRender = function (param) {
|
||||
|
||||
body.on("click", ".refresh", function() {
|
||||
body.on("click", ".refresh", function () {
|
||||
refresh();
|
||||
})
|
||||
|
||||
@ -117,7 +117,7 @@ layui.define(['message', 'table', 'jquery', 'element', 'yaml', 'form', 'tab', 'm
|
||||
index: 0,
|
||||
tabMax: param.tab.max,
|
||||
preload: param.tab.preload,
|
||||
closeEvent: function(id) {
|
||||
closeEvent: function (id) {
|
||||
sideMenu.selectItem(id);
|
||||
},
|
||||
data: [{
|
||||
@ -126,9 +126,9 @@ layui.define(['message', 'table', 'jquery', 'element', 'yaml', 'form', 'tab', 'm
|
||||
title: param.tab.index.title,
|
||||
close: false
|
||||
}],
|
||||
success: function(id) {
|
||||
success: function (id) {
|
||||
if (param.tab.session) {
|
||||
setTimeout(function() {
|
||||
setTimeout(function () {
|
||||
sideMenu.selectItem(id);
|
||||
bodyTab.positionTab();
|
||||
}, 500)
|
||||
@ -136,7 +136,7 @@ layui.define(['message', 'table', 'jquery', 'element', 'yaml', 'form', 'tab', 'm
|
||||
}
|
||||
});
|
||||
|
||||
bodyTab.click(function(id) {
|
||||
bodyTab.click(function (id) {
|
||||
if (!param.tab.keepState) {
|
||||
bodyTab.refresh(false);
|
||||
}
|
||||
@ -144,7 +144,7 @@ layui.define(['message', 'table', 'jquery', 'element', 'yaml', 'form', 'tab', 'm
|
||||
sideMenu.selectItem(id);
|
||||
})
|
||||
|
||||
sideMenu.click(function(dom, data) {
|
||||
sideMenu.click(function (dom, data) {
|
||||
bodyTab.addTabOnly({
|
||||
id: data.menuId,
|
||||
title: data.menuTitle,
|
||||
@ -163,32 +163,32 @@ layui.define(['message', 'table', 'jquery', 'element', 'yaml', 'form', 'tab', 'm
|
||||
height: '100%'
|
||||
});
|
||||
|
||||
sideMenu.click(function(dom, data) {
|
||||
sideMenu.click(function (dom, data) {
|
||||
bodyFrame.changePage(data.menuUrl, true);
|
||||
compatible()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
this.keepLoad = function(param) {
|
||||
this.keepLoad = function (param) {
|
||||
compatible()
|
||||
setTimeout(function() {
|
||||
setTimeout(function () {
|
||||
$(".loader-main").fadeOut(200);
|
||||
}, param.other.keepLoad)
|
||||
}
|
||||
|
||||
this.themeRender = function(option) {
|
||||
this.themeRender = function (option) {
|
||||
if (option.theme.allowCustom === false) {
|
||||
$(".setting").remove();
|
||||
}
|
||||
var colorId = localStorage.getItem("theme-color");
|
||||
var currentColor = getColorById(colorId);
|
||||
const colorId = localStorage.getItem("theme-color");
|
||||
const currentColor = getColorById(colorId);
|
||||
localStorage.setItem("theme-color", currentColor.id);
|
||||
localStorage.setItem("theme-color-color", currentColor.color);
|
||||
localStorage.setItem("theme-color-second", currentColor.second);
|
||||
pearTheme.changeTheme(window, isAutoHead(config));
|
||||
|
||||
var menu = localStorage.getItem("theme-menu");
|
||||
let menu = localStorage.getItem("theme-menu");
|
||||
if (menu === null) {
|
||||
menu = option.theme.defaultMenu;
|
||||
} else {
|
||||
@ -197,7 +197,7 @@ layui.define(['message', 'table', 'jquery', 'element', 'yaml', 'form', 'tab', 'm
|
||||
}
|
||||
}
|
||||
|
||||
var header = localStorage.getItem("theme-header");
|
||||
let header = localStorage.getItem("theme-header");
|
||||
if (header === null) {
|
||||
header = option.theme.defaultHeader;
|
||||
} else {
|
||||
@ -206,7 +206,7 @@ layui.define(['message', 'table', 'jquery', 'element', 'yaml', 'form', 'tab', 'm
|
||||
}
|
||||
}
|
||||
|
||||
var banner = localStorage.getItem("theme-banner");
|
||||
let banner = localStorage.getItem("theme-banner");
|
||||
if (banner === null) {
|
||||
banner = option.theme.banner;
|
||||
} else {
|
||||
@ -215,7 +215,7 @@ layui.define(['message', 'table', 'jquery', 'element', 'yaml', 'form', 'tab', 'm
|
||||
}
|
||||
}
|
||||
|
||||
var autoHead = localStorage.getItem("auto-head");
|
||||
let autoHead = localStorage.getItem("auto-head");
|
||||
if (autoHead === null) {
|
||||
autoHead = option.other.autoHead;
|
||||
} else {
|
||||
@ -224,7 +224,7 @@ layui.define(['message', 'table', 'jquery', 'element', 'yaml', 'form', 'tab', 'm
|
||||
}
|
||||
}
|
||||
|
||||
var muiltTab = localStorage.getItem("muilt-tab");
|
||||
let muiltTab = localStorage.getItem("muilt-tab");
|
||||
if (muiltTab === null) {
|
||||
muiltTab = option.tab.enable;
|
||||
} else {
|
||||
@ -233,7 +233,7 @@ layui.define(['message', 'table', 'jquery', 'element', 'yaml', 'form', 'tab', 'm
|
||||
}
|
||||
}
|
||||
|
||||
var control = localStorage.getItem("control");
|
||||
let control = localStorage.getItem("control");
|
||||
if (control === null) {
|
||||
control = option.menu.control;
|
||||
} else {
|
||||
@ -242,10 +242,10 @@ layui.define(['message', 'table', 'jquery', 'element', 'yaml', 'form', 'tab', 'm
|
||||
}
|
||||
}
|
||||
|
||||
var footer = localStorage.getItem("footer");
|
||||
if( footer === null) {
|
||||
let footer = localStorage.getItem("footer");
|
||||
if (footer === null) {
|
||||
footer = option.other.footer;
|
||||
}else{
|
||||
} else {
|
||||
if (option.theme.allowCustom === false) {
|
||||
footer = option.other.footer;
|
||||
}
|
||||
@ -264,9 +264,9 @@ layui.define(['message', 'table', 'jquery', 'element', 'yaml', 'form', 'tab', 'm
|
||||
this.footer(footer);
|
||||
}
|
||||
|
||||
this.footer = function(footer){
|
||||
var bodyDOM = $(".pear-admin .layui-body");
|
||||
var footerDOM = $(".pear-admin .layui-footer");
|
||||
this.footer = function (footer) {
|
||||
const bodyDOM = $(".pear-admin .layui-body");
|
||||
const footerDOM = $(".pear-admin .layui-footer");
|
||||
if (footer === true || footer === "true") {
|
||||
footerDOM.removeClass("close");
|
||||
bodyDOM.css("bottom", footerDOM.outerHeight());
|
||||
@ -276,15 +276,15 @@ layui.define(['message', 'table', 'jquery', 'element', 'yaml', 'form', 'tab', 'm
|
||||
}
|
||||
}
|
||||
|
||||
this.bannerSkin = function(theme) {
|
||||
var pearAdmin = $(".pear-admin");
|
||||
this.bannerSkin = function (theme) {
|
||||
const pearAdmin = $(".pear-admin");
|
||||
pearAdmin.removeClass("banner-layout");
|
||||
if (theme === true || theme === "true") {
|
||||
pearAdmin.addClass("banner-layout");
|
||||
}
|
||||
}
|
||||
|
||||
this.collapse = function(param) {
|
||||
this.collapse = function (param) {
|
||||
if (param.menu.collapse) {
|
||||
if ($(window).width() >= 768) {
|
||||
collapse()
|
||||
@ -292,43 +292,44 @@ layui.define(['message', 'table', 'jquery', 'element', 'yaml', 'form', 'tab', 'm
|
||||
}
|
||||
}
|
||||
|
||||
this.menuSkin = function(theme) {
|
||||
var pearAdmin = $(".pear-admin .layui-side");
|
||||
this.menuSkin = function (theme) {
|
||||
const pearAdmin = $(".pear-admin .layui-side");
|
||||
pearAdmin.removeClass("light-theme");
|
||||
pearAdmin.removeClass("dark-theme");
|
||||
pearAdmin.addClass(theme);
|
||||
}
|
||||
|
||||
this.headerSkin = function(theme) {
|
||||
var pearAdmin = $(".pear-admin .layui-header");
|
||||
this.headerSkin = function (theme) {
|
||||
const pearAdmin = $(".pear-admin .layui-header");
|
||||
pearAdmin.removeClass("light-theme");
|
||||
pearAdmin.removeClass("dark-theme");
|
||||
pearAdmin.addClass(theme);
|
||||
}
|
||||
|
||||
this.logout = function(callback) {
|
||||
this.logout = function (callback) {
|
||||
logout = callback;
|
||||
}
|
||||
|
||||
this.message = function(callback) {
|
||||
this.message = function (callback) {
|
||||
if (callback != null) {
|
||||
msgInstance.click(callback);
|
||||
}
|
||||
}
|
||||
|
||||
this.collapseSide = function() {
|
||||
this.collapseSide = function () {
|
||||
collapse()
|
||||
}
|
||||
|
||||
this.refreshThis = function() {
|
||||
this.refreshThis = function () {
|
||||
refresh()
|
||||
}
|
||||
|
||||
this.refresh = function(id) {
|
||||
$("iframe[id='"+ id +"']").attr('src', $("iframe[id='"+ id +"']").attr('src'));
|
||||
this.refresh = function (id) {
|
||||
const iframe = $("iframe[id='" + id + "']");
|
||||
iframe.attr('src', iframe.attr('src'));
|
||||
}
|
||||
|
||||
this.addTab = function(id, title, url) {
|
||||
this.addTab = function (id, title, url) {
|
||||
if (isMuiltTab(config) === "true" || isMuiltTab(config) === true) {
|
||||
bodyTab.addTabOnly({
|
||||
id: id,
|
||||
@ -337,79 +338,67 @@ layui.define(['message', 'table', 'jquery', 'element', 'yaml', 'form', 'tab', 'm
|
||||
icon: null,
|
||||
close: true
|
||||
}, 400);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
this.closeTab = function(id) {
|
||||
this.closeTab = function (id) {
|
||||
if (isMuiltTab(config) === "true" || isMuiltTab(config) === true) {
|
||||
pearTab.delTabByElem('content', id, function(currentId){
|
||||
pearTab.delTabByElem('content', id, function (currentId) {
|
||||
sideMenu.selectItem(currentId);
|
||||
});
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
this.closeCurrentTab = function() {
|
||||
this.closeCurrentTab = function () {
|
||||
if (isMuiltTab(config) === "true" || isMuiltTab(config) === true) {
|
||||
pearTab.delCurrentTabByElem('content', function(id){
|
||||
pearTab.delCurrentTabByElem('content', function (id) {
|
||||
sideMenu.selectItem(id);
|
||||
});
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
this.closeOtherTab = function() {
|
||||
if (isMuiltTab(config) === "true" || isMuiltTab(config) === true) {
|
||||
pearTab.delOtherTabByElem('content', function(id){
|
||||
sideMenu.selectItem(id);
|
||||
});
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
this.closeAllTab = function() {
|
||||
if (isMuiltTab(config) === "true" || isMuiltTab(config) === true) {
|
||||
pearTab.delAllTabByElem('content', function(id){
|
||||
sideMenu.selectItem(id);
|
||||
});
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
this.changeTabTitle = function(id, title) {
|
||||
pearTab.changeTabTitleById('content', id ,title);
|
||||
}
|
||||
|
||||
this.changeIframe = function(id, title, url) {
|
||||
this.closeOtherTab = function () {
|
||||
if (isMuiltTab(config) === "true" || isMuiltTab(config) === true) {
|
||||
return;
|
||||
} else {
|
||||
pearTab.delOtherTabByElem('content', function (id) {
|
||||
sideMenu.selectItem(id);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
this.closeAllTab = function () {
|
||||
if (isMuiltTab(config) === "true" || isMuiltTab(config) === true) {
|
||||
pearTab.delAllTabByElem('content', function (id) {
|
||||
sideMenu.selectItem(id);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
this.changeTabTitle = function (id, title) {
|
||||
pearTab.changeTabTitleById('content', id, title);
|
||||
}
|
||||
|
||||
this.changeIframe = function (id, title, url) {
|
||||
if (isMuiltTab(config) !== "true" && isMuiltTab(config) !== true) {
|
||||
sideMenu.selectItem(id);
|
||||
bodyFrame.changePage(url, true);
|
||||
}
|
||||
}
|
||||
|
||||
this.jump = function(id, title, url) {
|
||||
this.jump = function (id, title, url) {
|
||||
if (isMuiltTab(config) === "true" || isMuiltTab(config) === true) {
|
||||
pearAdmin.addTab(id, title, url)
|
||||
} else {
|
||||
pearAdmin.changeIframe(id, title, url)
|
||||
}
|
||||
}
|
||||
|
||||
this.fullScreen = function() {
|
||||
|
||||
this.fullScreen = function () {
|
||||
if ($(".fullScreen").hasClass("layui-icon-screen-restore")) {
|
||||
screenFun(2).then(function() {
|
||||
screenFun(2).then(function () {
|
||||
$(".fullScreen").eq(0).removeClass("layui-icon-screen-restore");
|
||||
});
|
||||
} else {
|
||||
screenFun(1).then(function() {
|
||||
screenFun(1).then(function () {
|
||||
$(".fullScreen").eq(0).addClass("layui-icon-screen-restore");
|
||||
});
|
||||
}
|
||||
@ -417,7 +406,7 @@ layui.define(['message', 'table', 'jquery', 'element', 'yaml', 'form', 'tab', 'm
|
||||
};
|
||||
|
||||
function refresh() {
|
||||
var refreshA = $(".refresh a");
|
||||
const refreshA = $(".refresh a");
|
||||
refreshA.removeClass("layui-icon-refresh-1");
|
||||
refreshA.addClass("layui-anim");
|
||||
refreshA.addClass("layui-anim-rotate");
|
||||
@ -436,9 +425,9 @@ layui.define(['message', 'table', 'jquery', 'element', 'yaml', 'form', 'tab', 'm
|
||||
|
||||
function collapse() {
|
||||
sideMenu.collapse();
|
||||
var admin = $(".pear-admin");
|
||||
var left = $(".layui-icon-spread-left")
|
||||
var right = $(".layui-icon-shrink-right")
|
||||
const admin = $(".pear-admin");
|
||||
const left = $(".layui-icon-spread-left");
|
||||
const right = $(".layui-icon-shrink-right");
|
||||
if (admin.is(".pear-mini")) {
|
||||
left.addClass("layui-icon-shrink-right")
|
||||
left.removeClass("layui-icon-spread-left")
|
||||
@ -464,14 +453,14 @@ layui.define(['message', 'table', 'jquery', 'element', 'yaml', 'form', 'tab', 'm
|
||||
|
||||
body.on("click", ".menuSearch", function () {
|
||||
// 过滤菜单
|
||||
var filterHandle = function (filterData, val) {
|
||||
const filterHandle = function (filterData, val) {
|
||||
if (!val) return [];
|
||||
var filteredMenus = [];
|
||||
const filteredMenus = [];
|
||||
filterData = $.extend(true, {}, filterData);
|
||||
$.each(filterData, function (index, item) {
|
||||
if (item.children && item.children.length) {
|
||||
var children = filterHandle(item.children, val)
|
||||
var obj = $.extend({}, item, { children: children });
|
||||
var obj = $.extend({}, item, {children: children});
|
||||
if (children && children.length) {
|
||||
filteredMenus.push(obj);
|
||||
} else if (item.title.indexOf(val) >= 0) {
|
||||
@ -483,25 +472,25 @@ layui.define(['message', 'table', 'jquery', 'element', 'yaml', 'form', 'tab', 'm
|
||||
}
|
||||
})
|
||||
return filteredMenus;
|
||||
}
|
||||
};
|
||||
|
||||
// 树转路径
|
||||
var tiledHandle = function (data) {
|
||||
var tiledMenus = [];
|
||||
var treeTiled = function (data, content) {
|
||||
var path = "";
|
||||
var separator = " / ";
|
||||
const tiledHandle = function (data) {
|
||||
const tiledMenus = [];
|
||||
const treeTiled = function (data, content) {
|
||||
let path = "";
|
||||
const separator = " / ";
|
||||
// 上级路径
|
||||
if (!content) content = "";
|
||||
$.each(data, function (index, item) {
|
||||
if (item.children && item.children.length) {
|
||||
path += content + item.title + separator;
|
||||
var childPath = treeTiled(item.children, path);
|
||||
const childPath = treeTiled(item.children, path);
|
||||
path += childPath;
|
||||
if (!childPath) path = ""; // 重置路径
|
||||
} else {
|
||||
path += content + item.title
|
||||
tiledMenus.push({ path: path, info: item });
|
||||
tiledMenus.push({path: path, info: item});
|
||||
path = ""; //重置路径
|
||||
}
|
||||
})
|
||||
@ -510,11 +499,11 @@ layui.define(['message', 'table', 'jquery', 'element', 'yaml', 'form', 'tab', 'm
|
||||
treeTiled(data);
|
||||
|
||||
return tiledMenus;
|
||||
}
|
||||
};
|
||||
|
||||
// 创建搜索列表
|
||||
var createList = function (data) {
|
||||
var _listHtml = '';
|
||||
const createList = function (data) {
|
||||
let _listHtml = '';
|
||||
$.each(data, function (index, item) {
|
||||
_listHtml += '<li smenu-id="' + item.info.id + '" smenu-icon="' + item.info.icon + '" smenu-url="' + item.info.href + '" smenu-title="' + item.info.title + '" smenu-type="' + item.info.type + '">';
|
||||
_listHtml += ' <span><i style="margin-right:10px" class=" ' + item.info.icon + '"></i>' + item.path + '</span>';
|
||||
@ -522,9 +511,9 @@ layui.define(['message', 'table', 'jquery', 'element', 'yaml', 'form', 'tab', 'm
|
||||
_listHtml += '</li>'
|
||||
})
|
||||
return _listHtml;
|
||||
}
|
||||
};
|
||||
|
||||
var _html = [
|
||||
const _html = [
|
||||
'<div class="menu-search-content">',
|
||||
' <div class="layui-form menu-search-input-wrapper">',
|
||||
' <div class=" layui-input-wrap layui-input-wrap-prefix">',
|
||||
@ -551,43 +540,43 @@ layui.define(['message', 'table', 'jquery', 'element', 'yaml', 'form', 'tab', 'm
|
||||
move: false,
|
||||
content: _html,
|
||||
success: function(layero,layeridx){
|
||||
var $layer = layero;
|
||||
var $content = $(layero).children('.layui-layer-content');
|
||||
var $input = $(".menu-search-input-wrapper input");
|
||||
var $noData = $(".menu-search-no-data");
|
||||
var $list = $(".menu-search-list");
|
||||
var menuData = sideMenu.option.data;
|
||||
const $layer = layero;
|
||||
const $content = $(layero).children('.layui-layer-content');
|
||||
const $input = $(".menu-search-input-wrapper input");
|
||||
const $noData = $(".menu-search-no-data");
|
||||
const $list = $(".menu-search-list");
|
||||
const menuData = sideMenu.option.data;
|
||||
|
||||
|
||||
$layer.css("border-radius", "6px");
|
||||
$input.off("focus").focus();
|
||||
// 搜索菜单
|
||||
$input.off("input").on("input", debounce(function(){
|
||||
var keywords = $input.val().trim();
|
||||
var filteredMenus = filterHandle(menuData, keywords);
|
||||
const keywords = $input.val().trim();
|
||||
const filteredMenus = filterHandle(menuData, keywords);
|
||||
|
||||
if(filteredMenus.length){
|
||||
var tiledMenus = tiledHandle(filteredMenus);
|
||||
var listHtml = createList(tiledMenus);
|
||||
$noData.css("display", "none");
|
||||
$list.html("").append(listHtml).children(":first").addClass("this")
|
||||
if(filteredMenus.length){
|
||||
const tiledMenus = tiledHandle(filteredMenus);
|
||||
const listHtml = createList(tiledMenus);
|
||||
$noData.css("display", "none");
|
||||
$list.html("").append(listHtml).children(":first").addClass("this")
|
||||
}else{
|
||||
$list.html("");
|
||||
$noData.css("display", "flex");
|
||||
}
|
||||
var currentHeight = $(".menu-search-content").outerHeight()
|
||||
$layer.css("height", currentHeight);
|
||||
$content.css("height", currentHeight);
|
||||
}, 500)
|
||||
const currentHeight = $(".menu-search-content").outerHeight();
|
||||
$layer.css("height", currentHeight);
|
||||
$content.css("height", currentHeight);
|
||||
}, 500)
|
||||
)
|
||||
// 搜索列表点击事件
|
||||
$list.off("click").on("click", "li", function () {
|
||||
var menuId = $(this).attr("smenu-id");
|
||||
var menuUrl = $(this).attr("smenu-url");
|
||||
var menuIcon = $(this).attr("smenu-icon");
|
||||
var menuTitle = $(this).attr("smenu-title");
|
||||
var menuType = $(this).attr("smenu-type");
|
||||
var openableWindow = menuType === "1" || menuType === 1;
|
||||
const menuId = $(this).attr("smenu-id");
|
||||
const menuUrl = $(this).attr("smenu-url");
|
||||
const menuIcon = $(this).attr("smenu-icon");
|
||||
const menuTitle = $(this).attr("smenu-title");
|
||||
const menuType = $(this).attr("smenu-type");
|
||||
const openableWindow = menuType === "1" || menuType === 1;
|
||||
|
||||
if(sideMenu.isCollapse){
|
||||
collapse();
|
||||
@ -611,13 +600,14 @@ layui.define(['message', 'table', 'jquery', 'element', 'yaml', 'form', 'tab', 'm
|
||||
// 监听键盘事件
|
||||
// Enter:13 Spacebar:32 UpArrow:38 DownArrow:40 Esc:27
|
||||
$(document).off("keydown").keydown(function (e) {
|
||||
const $menuSearchList = $(".menu-search-list li.this");
|
||||
if (e.keyCode === 13 || e.keyCode === 32) {
|
||||
e.preventDefault();
|
||||
var menuId = $(".menu-search-list li.this").attr("smenu-id");
|
||||
var menuUrl = $(".menu-search-list li.this").attr("smenu-url");
|
||||
var menuTitle = $(".menu-search-list li.this").attr("smenu-title");
|
||||
var menuType = $(".menu-search-list li.this").attr("smenu-type");
|
||||
var openableWindow = menuType === "1" || menuType === 1;
|
||||
const menuId = $menuSearchList.attr("smenu-id");
|
||||
const menuUrl = $menuSearchList.attr("smenu-url");
|
||||
const menuTitle = $menuSearchList.attr("smenu-title");
|
||||
const menuType = $menuSearchList.attr("smenu-type");
|
||||
const openableWindow = menuType === "1" || menuType === 1;
|
||||
if (sideMenu.isCollapse) {
|
||||
collapse();
|
||||
}
|
||||
@ -630,8 +620,8 @@ layui.define(['message', 'table', 'jquery', 'element', 'yaml', 'form', 'tab', 'm
|
||||
layer.close(layeridx);
|
||||
}else if(e.keyCode === 38){
|
||||
e.preventDefault();
|
||||
var prevEl = $(".menu-search-list li.this").prev();
|
||||
$(".menu-search-list li.this").removeClass("this");
|
||||
const prevEl = $menuSearchList.prev();
|
||||
$menuSearchList.removeClass("this");
|
||||
if(prevEl.length !== 0){
|
||||
prevEl.addClass("this");
|
||||
}else{
|
||||
@ -639,8 +629,8 @@ layui.define(['message', 'table', 'jquery', 'element', 'yaml', 'form', 'tab', 'm
|
||||
}
|
||||
}else if(e.keyCode === 40){
|
||||
e.preventDefault();
|
||||
var nextEl = $(".menu-search-list li.this").next();
|
||||
$(".menu-search-list li.this").removeClass("this");
|
||||
const nextEl = $menuSearchList.next();
|
||||
$menuSearchList.removeClass("this");
|
||||
if(nextEl.length !== 0){
|
||||
nextEl.addClass("this");
|
||||
}else{
|
||||
@ -684,7 +674,7 @@ layui.define(['message', 'table', 'jquery', 'element', 'yaml', 'form', 'tab', 'm
|
||||
|
||||
body.on("click", ".setting", function() {
|
||||
|
||||
var menuItem =
|
||||
let menuItem =
|
||||
'<li class="layui-this" data-select-bgcolor="dark-theme" >' +
|
||||
'<a href="javascript:;" data-skin="skin-blue" style="" class="clearfix full-opacity-hover">' +
|
||||
'<div><span style="display:block; width: 20%; float: left; height: 12px; background: #28333E;"></span><span style="display:block; width: 80%; float: left; height: 12px; background: white;"></span></div>' +
|
||||
@ -700,7 +690,7 @@ layui.define(['message', 'table', 'jquery', 'element', 'yaml', 'form', 'tab', 'm
|
||||
'</a>' +
|
||||
'</li>';
|
||||
|
||||
var menuHtml =
|
||||
const menuHtml =
|
||||
'<div class="pearone-color">\n' +
|
||||
'<div class="color-title">菜单风格</div>\n' +
|
||||
'<div class="color-content">\n' +
|
||||
@ -708,7 +698,7 @@ layui.define(['message', 'table', 'jquery', 'element', 'yaml', 'form', 'tab', 'm
|
||||
'</div>\n' +
|
||||
'</div>';
|
||||
|
||||
var headItem =
|
||||
let headItem =
|
||||
'<li class="layui-this" data-select-header="light-theme" >' +
|
||||
'<a href="javascript:;" data-skin="skin-blue" style="" class="clearfix full-opacity-hover">' +
|
||||
'<div><span style="display:block; width: 20%; float: left; height: 12px; background: #28333E;"></span><span style="display:block; width: 80%; float: left; height: 12px; background: white;"></span></div>' +
|
||||
@ -724,7 +714,7 @@ layui.define(['message', 'table', 'jquery', 'element', 'yaml', 'form', 'tab', 'm
|
||||
'</a>' +
|
||||
'</li>';
|
||||
|
||||
var headHtml =
|
||||
const headHtml =
|
||||
'<div class="pearone-color">\n' +
|
||||
'<div class="color-title">顶部风格</div>\n' +
|
||||
'<div class="color-content">\n' +
|
||||
@ -732,7 +722,7 @@ layui.define(['message', 'table', 'jquery', 'element', 'yaml', 'form', 'tab', 'm
|
||||
'</div>\n' +
|
||||
'</div>';
|
||||
|
||||
var moreItem =
|
||||
let moreItem =
|
||||
'<div class="layui-form-item"><div class="layui-input-inline"><input type="checkbox" name="control" lay-filter="control" lay-skin="switch" lay-text="开|关"></div><span class="set-text">菜单</span></div>';
|
||||
|
||||
moreItem +=
|
||||
@ -747,7 +737,7 @@ layui.define(['message', 'table', 'jquery', 'element', 'yaml', 'form', 'tab', 'm
|
||||
moreItem +=
|
||||
'<div class="layui-form-item"><div class="layui-input-inline"><input type="checkbox" name="footer" lay-filter="footer" lay-skin="switch" lay-text="开|关"></div><span class="set-text">页脚</span></div>';
|
||||
|
||||
var moreHtml = '<br><div class="pearone-color">\n' +
|
||||
const moreHtml = '<br><div class="pearone-color">\n' +
|
||||
'<div class="color-title">更多设置</div>\n' +
|
||||
'<div class="color-content">\n' +
|
||||
'<form class="layui-form">\n' + moreItem + '</form>\n' +
|
||||
@ -770,9 +760,9 @@ layui.define(['message', 'table', 'jquery', 'element', 'yaml', 'form', 'tab', 'm
|
||||
|
||||
form.render();
|
||||
|
||||
var color = localStorage.getItem("theme-color");
|
||||
var menu = localStorage.getItem("theme-menu");
|
||||
var header = localStorage.getItem("theme-header");
|
||||
const color = localStorage.getItem("theme-color");
|
||||
const menu = localStorage.getItem("theme-menu");
|
||||
const header = localStorage.getItem("theme-header");
|
||||
|
||||
if (color !== "null") {
|
||||
$(".select-color-item").removeClass("layui-icon").removeClass("layui-icon-ok");
|
||||
@ -790,7 +780,7 @@ layui.define(['message', 'table', 'jquery', 'element', 'yaml', 'form', 'tab', 'm
|
||||
}
|
||||
|
||||
$('#layui-layer-shade' + index).click(function() {
|
||||
var $layero = $('#layui-layer' + index);
|
||||
const $layero = $('#layui-layer' + index);
|
||||
$layero.animate({
|
||||
left: $layero.offset().left + $layero.width()
|
||||
}, 200, function() {
|
||||
@ -859,7 +849,7 @@ layui.define(['message', 'table', 'jquery', 'element', 'yaml', 'form', 'tab', 'm
|
||||
});
|
||||
|
||||
body.on('click', '[data-select-bgcolor]', function() {
|
||||
var theme = $(this).attr('data-select-bgcolor');
|
||||
const theme = $(this).attr('data-select-bgcolor');
|
||||
$('[data-select-bgcolor]').removeClass("layui-this");
|
||||
$(this).addClass("layui-this");
|
||||
localStorage.setItem("theme-menu", theme);
|
||||
@ -867,7 +857,7 @@ layui.define(['message', 'table', 'jquery', 'element', 'yaml', 'form', 'tab', 'm
|
||||
});
|
||||
|
||||
body.on('click', '[data-select-header]', function() {
|
||||
var theme = $(this).attr('data-select-header');
|
||||
const theme = $(this).attr('data-select-header');
|
||||
$('[data-select-header]').removeClass("layui-this");
|
||||
$(this).addClass("layui-this");
|
||||
localStorage.setItem("theme-header", theme);
|
||||
@ -877,8 +867,8 @@ layui.define(['message', 'table', 'jquery', 'element', 'yaml', 'form', 'tab', 'm
|
||||
body.on('click', '.select-color-item', function() {
|
||||
$(".select-color-item").removeClass("layui-icon").removeClass("layui-icon-ok");
|
||||
$(this).addClass("layui-icon").addClass("layui-icon-ok");
|
||||
var colorId = $(".select-color-item.layui-icon-ok").attr("color-id");
|
||||
var currentColor = getColorById(colorId);
|
||||
const colorId = $(".select-color-item.layui-icon-ok").attr("color-id");
|
||||
const currentColor = getColorById(colorId);
|
||||
localStorage.setItem("theme-color", currentColor.id);
|
||||
localStorage.setItem("theme-color-color", currentColor.color);
|
||||
localStorage.setItem("theme-color-second", currentColor.second);
|
||||
@ -892,14 +882,14 @@ layui.define(['message', 'table', 'jquery', 'element', 'yaml', 'form', 'tab', 'm
|
||||
pearAdmin.bodyRender(param);
|
||||
pearAdmin.themeRender(param);
|
||||
pearAdmin.keepLoad(param);
|
||||
if (param.header.message != false) {
|
||||
if (param.header.message !== false) {
|
||||
pearAdmin.messageRender(param);
|
||||
}
|
||||
}
|
||||
|
||||
function getColorById(id) {
|
||||
var color;
|
||||
var flag = false;
|
||||
let color;
|
||||
let flag = false;
|
||||
$.each(config.colors, function(i, value) {
|
||||
if (value.id === id) {
|
||||
color = value;
|
||||
@ -917,7 +907,7 @@ layui.define(['message', 'table', 'jquery', 'element', 'yaml', 'form', 'tab', 'm
|
||||
}
|
||||
|
||||
function buildColorHtml() {
|
||||
var colors = "";
|
||||
let colors = "";
|
||||
$.each(config.colors, function(i, value) {
|
||||
colors += "<span class='select-color-item' color-id='" + value.id + "' style='background-color:" + value.color +
|
||||
";'></span>";
|
||||
@ -981,9 +971,9 @@ layui.define(['message', 'table', 'jquery', 'element', 'yaml', 'form', 'tab', 'm
|
||||
},50));
|
||||
|
||||
function debounce(fn, awaitTime) {
|
||||
var timerID = null
|
||||
let timerID = null;
|
||||
return function () {
|
||||
var arg = arguments[0]
|
||||
const arg = arguments[0];
|
||||
if (timerID) {
|
||||
clearTimeout(timerID)
|
||||
}
|
||||
|
@ -95,7 +95,11 @@ layui.define(['table', 'laypage','jquery', 'element'], function(exports) {
|
||||
html += "<div id='cardpage'></div>";
|
||||
}
|
||||
else {
|
||||
html = "<p>没有数据</p>";
|
||||
if (data.code != option.response.statusCode) {
|
||||
html = "<p>" + data.msg + "</p>";
|
||||
} else {
|
||||
html = "<p>没有数据</p>";
|
||||
}
|
||||
}
|
||||
$(option.elem).html(html);
|
||||
if (option.page) {
|
||||
@ -187,6 +191,9 @@ layui.define(['table', 'laypage','jquery', 'element'], function(exports) {
|
||||
data.msg = tempData[option.response.msgName];
|
||||
data.count = tempData[option.response.countName];
|
||||
var dataList = tempData[option.response.dataName];
|
||||
if(!dataList){
|
||||
return data;
|
||||
}
|
||||
data.data = [];
|
||||
for (var i = 0; i < dataList.length; i++) {
|
||||
var item = dataList[i];
|
||||
|
37
public/static/component/pear/module/extends/count.js
Normal file
37
public/static/component/pear/module/extends/count.js
Normal file
@ -0,0 +1,37 @@
|
||||
layui.define(['jquery', 'element'], function(exports) {
|
||||
"use strict";
|
||||
|
||||
var MOD_NAME = 'count',
|
||||
$ = layui.jquery,
|
||||
element = layui.element;
|
||||
|
||||
var count = new function() {
|
||||
|
||||
this.up = function(targetEle, options) {
|
||||
|
||||
options = options || {};
|
||||
|
||||
var $this = document.getElementById(targetEle),
|
||||
time = options.time,
|
||||
finalNum = options.num,
|
||||
regulator = options.regulator,
|
||||
step = finalNum / (time / regulator),
|
||||
count = 0.00,
|
||||
initial = 0;
|
||||
|
||||
var timer = setInterval(function() {
|
||||
count = count + step;
|
||||
if (count >= finalNum) {
|
||||
clearInterval(timer);
|
||||
count = finalNum;
|
||||
}
|
||||
var t = count.toFixed(options.bit?options.bit:0);;
|
||||
if (t == initial) return;
|
||||
initial = t;
|
||||
$this.innerHTML = initial;
|
||||
}, 30);
|
||||
}
|
||||
|
||||
}
|
||||
exports(MOD_NAME, count);
|
||||
});
|
95172
public/static/component/pear/module/extends/echarts.js
Normal file
95172
public/static/component/pear/module/extends/echarts.js
Normal file
File diff suppressed because it is too large
Load Diff
450
public/static/component/pear/module/extends/echartsTheme.js
Normal file
450
public/static/component/pear/module/extends/echartsTheme.js
Normal file
@ -0,0 +1,450 @@
|
||||
layui.define(function (exports) {
|
||||
exports('echartsTheme',
|
||||
{
|
||||
"color": [
|
||||
"#3fb1e3",
|
||||
"#6be6c1",
|
||||
"#626c91",
|
||||
"#a0a7e6",
|
||||
"#c4ebad",
|
||||
"#96dee8"
|
||||
],
|
||||
"backgroundColor": "rgba(252,252,252,0)",
|
||||
"textStyle": {},
|
||||
"title": {
|
||||
"textStyle": {
|
||||
"color": "#666666"
|
||||
},
|
||||
"subtextStyle": {
|
||||
"color": "#999999"
|
||||
}
|
||||
},
|
||||
"line": {
|
||||
"itemStyle": {
|
||||
"borderWidth": "3"
|
||||
},
|
||||
"lineStyle": {
|
||||
"width": "4"
|
||||
},
|
||||
"symbolSize": "10",
|
||||
"symbol": "emptyCircle",
|
||||
"smooth": true
|
||||
},
|
||||
"radar": {
|
||||
"itemStyle": {
|
||||
"borderWidth": "3"
|
||||
},
|
||||
"lineStyle": {
|
||||
"width": "4"
|
||||
},
|
||||
"symbolSize": "10",
|
||||
"symbol": "emptyCircle",
|
||||
"smooth": true
|
||||
},
|
||||
"bar": {
|
||||
"itemStyle": {
|
||||
"barBorderWidth": 0,
|
||||
"barBorderColor": "#ccc"
|
||||
},
|
||||
"emphasis": {
|
||||
"itemStyle": {
|
||||
"barBorderWidth": 0,
|
||||
"barBorderColor": "#ccc"
|
||||
}
|
||||
}
|
||||
},
|
||||
"pie": {
|
||||
"itemStyle": {
|
||||
"borderWidth": 0,
|
||||
"borderColor": "#ccc"
|
||||
},
|
||||
"emphasis": {
|
||||
"itemStyle": {
|
||||
"borderWidth": 0,
|
||||
"borderColor": "#ccc"
|
||||
}
|
||||
}
|
||||
},
|
||||
"scatter": {
|
||||
"itemStyle": {
|
||||
"borderWidth": 0,
|
||||
"borderColor": "#ccc"
|
||||
},
|
||||
"emphasis": {
|
||||
"itemStyle": {
|
||||
"borderWidth": 0,
|
||||
"borderColor": "#ccc"
|
||||
}
|
||||
}
|
||||
},
|
||||
"boxplot": {
|
||||
"itemStyle": {
|
||||
"borderWidth": 0,
|
||||
"borderColor": "#ccc"
|
||||
|
||||
},
|
||||
"emphasis": {
|
||||
"itemStyle": {
|
||||
"borderWidth": 0,
|
||||
"borderColor": "#ccc"
|
||||
}
|
||||
}
|
||||
},
|
||||
"parallel": {
|
||||
"itemStyle": {
|
||||
"borderWidth": 0,
|
||||
"borderColor": "#ccc"
|
||||
},
|
||||
"emphasis": {
|
||||
"itemStyle": {
|
||||
"borderWidth": 0,
|
||||
"borderColor": "#ccc"
|
||||
}
|
||||
}
|
||||
},
|
||||
"sankey": {
|
||||
"itemStyle": {
|
||||
"borderWidth": 0,
|
||||
"borderColor": "#ccc"
|
||||
},
|
||||
"emphasis": {
|
||||
"itemStyle": {
|
||||
"borderWidth": 0,
|
||||
"borderColor": "#ccc"
|
||||
}
|
||||
}
|
||||
},
|
||||
"funnel": {
|
||||
"itemStyle": {
|
||||
"borderWidth": 0,
|
||||
"borderColor": "#ccc"
|
||||
},
|
||||
"emphasis": {
|
||||
"itemStyle": {
|
||||
"borderWidth": 0,
|
||||
"borderColor": "#ccc"
|
||||
}
|
||||
}
|
||||
},
|
||||
"gauge": {
|
||||
"itemStyle": {
|
||||
"borderWidth": 0,
|
||||
"borderColor": "#ccc"
|
||||
},
|
||||
"emphasis": {
|
||||
"itemStyle": {
|
||||
"borderWidth": 0,
|
||||
"borderColor": "#ccc"
|
||||
}
|
||||
}
|
||||
},
|
||||
"candlestick": {
|
||||
"itemStyle": {
|
||||
"color": "#e6a0d2",
|
||||
"color0": "transparent",
|
||||
"borderColor": "#e6a0d2",
|
||||
"borderColor0": "#3fb1e3",
|
||||
"borderWidth": "2"
|
||||
}
|
||||
},
|
||||
"graph": {
|
||||
"itemStyle": {
|
||||
"borderWidth": 0,
|
||||
"borderColor": "#ccc"
|
||||
},
|
||||
"lineStyle": {
|
||||
"width": "1",
|
||||
"color": "#cccccc"
|
||||
},
|
||||
"symbolSize": "10",
|
||||
"symbol": "emptyCircle",
|
||||
"smooth": true,
|
||||
"color": [
|
||||
"#3fb1e3",
|
||||
"#6be6c1",
|
||||
"#626c91",
|
||||
"#a0a7e6",
|
||||
"#c4ebad",
|
||||
"#96dee8"
|
||||
],
|
||||
"label": {
|
||||
"color": "#ffffff"
|
||||
}
|
||||
},
|
||||
"map": {
|
||||
"itemStyle": {
|
||||
"areaColor": "#eeeeee",
|
||||
"borderColor": "#aaaaaa",
|
||||
"borderWidth": 0.5
|
||||
},
|
||||
"label": {
|
||||
"color": "#ffffff"
|
||||
},
|
||||
"emphasis": {
|
||||
"itemStyle": {
|
||||
"areaColor": "rgba(63,177,227,0.25)",
|
||||
"borderColor": "#3fb1e3",
|
||||
"borderWidth": 1
|
||||
},
|
||||
"label": {
|
||||
"color": "rgb(63,177,227)"
|
||||
}
|
||||
}
|
||||
},
|
||||
"geo": {
|
||||
"itemStyle": {
|
||||
"areaColor": "#eeeeee",
|
||||
"borderColor": "#aaaaaa",
|
||||
"borderWidth": 0.5
|
||||
},
|
||||
"label": {
|
||||
"color": "#ffffff"
|
||||
},
|
||||
"emphasis": {
|
||||
"itemStyle": {
|
||||
"areaColor": "rgba(63,177,227,0.25)",
|
||||
"borderColor": "#3fb1e3",
|
||||
"borderWidth": 1
|
||||
},
|
||||
"label": {
|
||||
"color": "rgb(63,177,227)"
|
||||
}
|
||||
}
|
||||
},
|
||||
"categoryAxis": {
|
||||
"axisLine": {
|
||||
"show": true,
|
||||
"lineStyle": {
|
||||
"color": "#cccccc"
|
||||
}
|
||||
},
|
||||
"axisTick": {
|
||||
"show": false,
|
||||
"lineStyle": {
|
||||
"color": "#333"
|
||||
}
|
||||
},
|
||||
"axisLabel": {
|
||||
"show": true,
|
||||
|
||||
"color": "#999999"
|
||||
|
||||
},
|
||||
"splitLine": {
|
||||
"show": true,
|
||||
"lineStyle": {
|
||||
"color": [
|
||||
"#eeeeee"
|
||||
]
|
||||
}
|
||||
},
|
||||
"splitArea": {
|
||||
"show": false,
|
||||
"areaStyle": {
|
||||
"color": [
|
||||
"rgba(250,250,250,0.05)",
|
||||
"rgba(200,200,200,0.02)"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"valueAxis": {
|
||||
"axisLine": {
|
||||
"show": true,
|
||||
"lineStyle": {
|
||||
"color": "#cccccc"
|
||||
}
|
||||
},
|
||||
"axisTick": {
|
||||
"show": false,
|
||||
"lineStyle": {
|
||||
"color": "#333"
|
||||
}
|
||||
},
|
||||
"axisLabel": {
|
||||
"show": true,
|
||||
"color": "#999999"
|
||||
|
||||
},
|
||||
"splitLine": {
|
||||
"show": true,
|
||||
"lineStyle": {
|
||||
"color": [
|
||||
"#eeeeee"
|
||||
]
|
||||
}
|
||||
},
|
||||
"splitArea": {
|
||||
"show": false,
|
||||
"areaStyle": {
|
||||
"color": [
|
||||
"rgba(250,250,250,0.05)",
|
||||
"rgba(200,200,200,0.02)"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"logAxis": {
|
||||
"axisLine": {
|
||||
"show": true,
|
||||
"lineStyle": {
|
||||
"color": "#cccccc"
|
||||
}
|
||||
},
|
||||
"axisTick": {
|
||||
"show": false,
|
||||
"lineStyle": {
|
||||
"color": "#333"
|
||||
}
|
||||
},
|
||||
"axisLabel": {
|
||||
"show": true,
|
||||
"color": "#999999"
|
||||
|
||||
},
|
||||
"splitLine": {
|
||||
"show": true,
|
||||
"lineStyle": {
|
||||
"color": [
|
||||
"#eeeeee"
|
||||
]
|
||||
}
|
||||
},
|
||||
"splitArea": {
|
||||
"show": false,
|
||||
"areaStyle": {
|
||||
"color": [
|
||||
"rgba(250,250,250,0.05)",
|
||||
"rgba(200,200,200,0.02)"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"timeAxis": {
|
||||
"axisLine": {
|
||||
"show": true,
|
||||
"lineStyle": {
|
||||
"color": "#cccccc"
|
||||
}
|
||||
},
|
||||
"axisTick": {
|
||||
"show": false,
|
||||
"lineStyle": {
|
||||
"color": "#333"
|
||||
}
|
||||
},
|
||||
"axisLabel": {
|
||||
"show": true,
|
||||
|
||||
"color": "#999999"
|
||||
|
||||
},
|
||||
"splitLine": {
|
||||
"show": true,
|
||||
"lineStyle": {
|
||||
"color": [
|
||||
"#eeeeee"
|
||||
]
|
||||
}
|
||||
},
|
||||
"splitArea": {
|
||||
"show": false,
|
||||
"areaStyle": {
|
||||
"color": [
|
||||
"rgba(250,250,250,0.05)",
|
||||
"rgba(200,200,200,0.02)"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"toolbox": {
|
||||
"iconStyle": {
|
||||
"borderColor": "#999999"
|
||||
},
|
||||
"emphasis": {
|
||||
"iconStyle": {
|
||||
"borderColor": "#666666"
|
||||
}
|
||||
}
|
||||
},
|
||||
"legend": {
|
||||
"textStyle": {
|
||||
"color": "#999999"
|
||||
}
|
||||
},
|
||||
"tooltip": {
|
||||
"axisPointer": {
|
||||
"lineStyle": {
|
||||
"color": "#cccccc",
|
||||
"width": 1
|
||||
},
|
||||
"crossStyle": {
|
||||
"color": "#cccccc",
|
||||
"width": 1
|
||||
}
|
||||
}
|
||||
},
|
||||
"timeline": {
|
||||
"lineStyle": {
|
||||
"color": "#626c91",
|
||||
"width": 1
|
||||
},
|
||||
"itemStyle": {
|
||||
"color": "#626c91",
|
||||
"borderWidth": 1
|
||||
|
||||
},
|
||||
"controlStyle": {
|
||||
"color": "#626c91",
|
||||
"borderColor": "#626c91",
|
||||
"borderWidth": 0.5
|
||||
},
|
||||
"checkpointStyle": {
|
||||
"color": "#3fb1e3",
|
||||
"borderColor": "rgba(63,177,227,0.15)"
|
||||
},
|
||||
"label": {
|
||||
"color": "#626c91"
|
||||
},
|
||||
"emphasis": {
|
||||
"itemStyle": {
|
||||
"color": "#626c91"
|
||||
},
|
||||
"controlStyle": {
|
||||
"color": "#626c91",
|
||||
"borderColor": "#626c91",
|
||||
"borderWidth": 0.5
|
||||
},
|
||||
"label": {
|
||||
"color": "#626c91"
|
||||
}
|
||||
}
|
||||
},
|
||||
"visualMap": {
|
||||
"color": [
|
||||
"#2a99c9",
|
||||
"#afe8ff"
|
||||
]
|
||||
},
|
||||
"dataZoom": {
|
||||
"backgroundColor": "rgba(255,255,255,0)",
|
||||
"dataBackgroundColor": "rgba(222,222,222,1)",
|
||||
"fillerColor": "rgba(114,230,212,0.25)",
|
||||
"handleColor": "#cccccc",
|
||||
"handleSize": "100%",
|
||||
"textStyle": {
|
||||
"color": "#999999"
|
||||
}
|
||||
},
|
||||
"markPoint": {
|
||||
"label": {
|
||||
"color": "#ffffff"
|
||||
},
|
||||
"emphasis": {
|
||||
"label": {
|
||||
"color": "#ffffff"
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
503
public/static/component/pear/module/extends/nprogress.js
Normal file
503
public/static/component/pear/module/extends/nprogress.js
Normal file
@ -0,0 +1,503 @@
|
||||
/* NProgress, (c) 2013, 2014 Rico Sta. Cruz - http://ricostacruz.com/nprogress
|
||||
* @license MIT */
|
||||
|
||||
;(function(root, factory) {
|
||||
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
define(factory);
|
||||
} else if (typeof exports === 'object') {
|
||||
module.exports = factory();
|
||||
} else {
|
||||
root.NProgress = factory();
|
||||
}
|
||||
|
||||
})(this, function() {
|
||||
var NProgress = {};
|
||||
|
||||
NProgress.version = '0.2.0';
|
||||
|
||||
var Settings = NProgress.settings = {
|
||||
minimum: 0.08,
|
||||
easing: 'linear',
|
||||
positionUsing: '',
|
||||
speed: 200,
|
||||
trickle: true,
|
||||
trickleSpeed: 200,
|
||||
showSpinner: true,
|
||||
barSelector: '[role="bar"]',
|
||||
spinnerSelector: '[role="spinner"]',
|
||||
parent: 'body',
|
||||
template: '<div class="bar" role="bar"><div class="peg"></div></div><div class="spinner" role="spinner"><div class="spinner-icon"></div></div>'
|
||||
};
|
||||
|
||||
/**
|
||||
* Updates configuration.
|
||||
*
|
||||
* NProgress.configure({
|
||||
* minimum: 0.1
|
||||
* });
|
||||
*/
|
||||
NProgress.configure = function(options) {
|
||||
var key, value;
|
||||
for (key in options) {
|
||||
value = options[key];
|
||||
if (value !== undefined && options.hasOwnProperty(key)) Settings[key] = value;
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Last number.
|
||||
*/
|
||||
|
||||
NProgress.status = null;
|
||||
|
||||
/**
|
||||
* Sets the progress bar status, where `n` is a number from `0.0` to `1.0`.
|
||||
*
|
||||
* NProgress.set(0.4);
|
||||
* NProgress.set(1.0);
|
||||
*/
|
||||
|
||||
NProgress.set = function(n) {
|
||||
var started = NProgress.isStarted();
|
||||
|
||||
n = clamp(n, Settings.minimum, 1);
|
||||
NProgress.status = (n === 1 ? null : n);
|
||||
|
||||
var progress = NProgress.render(!started),
|
||||
bar = progress.querySelector(Settings.barSelector),
|
||||
speed = Settings.speed,
|
||||
ease = Settings.easing;
|
||||
|
||||
progress.offsetWidth; /* Repaint */
|
||||
|
||||
queue(function(next) {
|
||||
// Set positionUsing if it hasn't already been set
|
||||
if (Settings.positionUsing === '') Settings.positionUsing = NProgress.getPositioningCSS();
|
||||
|
||||
// Add transition
|
||||
css(bar, barPositionCSS(n, speed, ease));
|
||||
|
||||
if (n === 1) {
|
||||
// Fade out
|
||||
css(progress, {
|
||||
transition: 'none',
|
||||
opacity: 1
|
||||
});
|
||||
progress.offsetWidth; /* Repaint */
|
||||
|
||||
setTimeout(function() {
|
||||
css(progress, {
|
||||
transition: 'all ' + speed + 'ms linear',
|
||||
opacity: 0
|
||||
});
|
||||
setTimeout(function() {
|
||||
NProgress.remove();
|
||||
next();
|
||||
}, speed);
|
||||
}, speed);
|
||||
} else {
|
||||
setTimeout(next, speed);
|
||||
}
|
||||
});
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
NProgress.isStarted = function() {
|
||||
return typeof NProgress.status === 'number';
|
||||
};
|
||||
|
||||
/**
|
||||
* Shows the progress bar.
|
||||
* This is the same as setting the status to 0%, except that it doesn't go backwards.
|
||||
*
|
||||
* NProgress.start();
|
||||
*
|
||||
*/
|
||||
NProgress.start = function() {
|
||||
if (!NProgress.status) NProgress.set(0);
|
||||
|
||||
var work = function() {
|
||||
setTimeout(function() {
|
||||
if (!NProgress.status) return;
|
||||
NProgress.trickle();
|
||||
work();
|
||||
}, Settings.trickleSpeed);
|
||||
};
|
||||
|
||||
if (Settings.trickle) work();
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Hides the progress bar.
|
||||
* This is the *sort of* the same as setting the status to 100%, with the
|
||||
* difference being `done()` makes some placebo effect of some realistic motion.
|
||||
*
|
||||
* NProgress.done();
|
||||
*
|
||||
* If `true` is passed, it will show the progress bar even if its hidden.
|
||||
*
|
||||
* NProgress.done(true);
|
||||
*/
|
||||
|
||||
NProgress.done = function(force) {
|
||||
if (!force && !NProgress.status) return this;
|
||||
|
||||
return NProgress.inc(0.3 + 0.5 * Math.random()).set(1);
|
||||
};
|
||||
|
||||
/**
|
||||
* Increments by a random amount.
|
||||
*/
|
||||
|
||||
NProgress.inc = function(amount) {
|
||||
var n = NProgress.status;
|
||||
|
||||
if (!n) {
|
||||
return NProgress.start();
|
||||
} else if(n > 1) {
|
||||
return;
|
||||
} else {
|
||||
if (typeof amount !== 'number') {
|
||||
if (n >= 0 && n < 0.2) { amount = 0.1; }
|
||||
else if (n >= 0.2 && n < 0.5) { amount = 0.04; }
|
||||
else if (n >= 0.5 && n < 0.8) { amount = 0.02; }
|
||||
else if (n >= 0.8 && n < 0.99) { amount = 0.005; }
|
||||
else { amount = 0; }
|
||||
}
|
||||
|
||||
n = clamp(n + amount, 0, 0.994);
|
||||
return NProgress.set(n);
|
||||
}
|
||||
};
|
||||
|
||||
NProgress.trickle = function() {
|
||||
return NProgress.inc();
|
||||
};
|
||||
|
||||
/**
|
||||
* Waits for all supplied jQuery promises and
|
||||
* increases the progress as the promises resolve.
|
||||
*
|
||||
* @param $promise jQUery Promise
|
||||
*/
|
||||
(function() {
|
||||
var initial = 0, current = 0;
|
||||
|
||||
NProgress.promise = function($promise) {
|
||||
if (!$promise || $promise.state() === "resolved") {
|
||||
return this;
|
||||
}
|
||||
|
||||
if (current === 0) {
|
||||
NProgress.start();
|
||||
}
|
||||
|
||||
initial++;
|
||||
current++;
|
||||
|
||||
$promise.always(function() {
|
||||
current--;
|
||||
if (current === 0) {
|
||||
initial = 0;
|
||||
NProgress.done();
|
||||
} else {
|
||||
NProgress.set((initial - current) / initial);
|
||||
}
|
||||
});
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
})();
|
||||
|
||||
/**
|
||||
* (Internal) renders the progress bar markup based on the `template`
|
||||
* setting.
|
||||
*/
|
||||
|
||||
NProgress.render = function(fromStart) {
|
||||
if (NProgress.isRendered()) return document.getElementById('nprogress');
|
||||
|
||||
addClass(document.documentElement, 'nprogress-busy');
|
||||
|
||||
var progress = document.createElement('div');
|
||||
progress.id = 'nprogress';
|
||||
progress.innerHTML = Settings.template;
|
||||
|
||||
|
||||
|
||||
var bar = progress.querySelector(Settings.barSelector),
|
||||
perc = fromStart ? '-100' : toBarPerc(NProgress.status || 0),
|
||||
parent = isDOM(Settings.parent)
|
||||
? Settings.parent
|
||||
: document.querySelector(Settings.parent),
|
||||
spinner
|
||||
|
||||
css(bar, {
|
||||
transition: 'all 0 linear',
|
||||
transform: 'translate3d(' + perc + '%,0,0)'
|
||||
});
|
||||
|
||||
if (!Settings.showSpinner) {
|
||||
spinner = progress.querySelector(Settings.spinnerSelector);
|
||||
spinner && removeElement(spinner);
|
||||
}
|
||||
|
||||
if (parent != document.body) {
|
||||
addClass(parent, 'nprogress-custom-parent');
|
||||
}
|
||||
|
||||
parent.appendChild(progress);
|
||||
return progress;
|
||||
};
|
||||
|
||||
/**
|
||||
* Removes the element. Opposite of render().
|
||||
*/
|
||||
|
||||
NProgress.remove = function() {
|
||||
removeClass(document.documentElement, 'nprogress-busy');
|
||||
var parent = isDOM(Settings.parent)
|
||||
? Settings.parent
|
||||
: document.querySelector(Settings.parent)
|
||||
removeClass(parent, 'nprogress-custom-parent')
|
||||
var progress = document.getElementById('nprogress');
|
||||
progress && removeElement(progress);
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks if the progress bar is rendered.
|
||||
*/
|
||||
|
||||
NProgress.isRendered = function() {
|
||||
return !!document.getElementById('nprogress');
|
||||
};
|
||||
|
||||
/**
|
||||
* Determine which positioning CSS rule to use.
|
||||
*/
|
||||
|
||||
NProgress.getPositioningCSS = function() {
|
||||
// Sniff on document.body.style
|
||||
var bodyStyle = document.body.style;
|
||||
|
||||
// Sniff prefixes
|
||||
var vendorPrefix = ('WebkitTransform' in bodyStyle) ? 'Webkit' :
|
||||
('MozTransform' in bodyStyle) ? 'Moz' :
|
||||
('msTransform' in bodyStyle) ? 'ms' :
|
||||
('OTransform' in bodyStyle) ? 'O' : '';
|
||||
|
||||
if (vendorPrefix + 'Perspective' in bodyStyle) {
|
||||
// Modern browsers with 3D support, e.g. Webkit, IE10
|
||||
return 'translate3d';
|
||||
} else if (vendorPrefix + 'Transform' in bodyStyle) {
|
||||
// Browsers without 3D support, e.g. IE9
|
||||
return 'translate';
|
||||
} else {
|
||||
// Browsers without translate() support, e.g. IE7-8
|
||||
return 'margin';
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Helpers
|
||||
*/
|
||||
|
||||
function isDOM (obj) {
|
||||
if (typeof HTMLElement === 'object') {
|
||||
return obj instanceof HTMLElement
|
||||
}
|
||||
return (
|
||||
obj &&
|
||||
typeof obj === 'object' &&
|
||||
obj.nodeType === 1 &&
|
||||
typeof obj.nodeName === 'string'
|
||||
)
|
||||
}
|
||||
|
||||
function clamp(n, min, max) {
|
||||
if (n < min) return min;
|
||||
if (n > max) return max;
|
||||
return n;
|
||||
}
|
||||
|
||||
/**
|
||||
* (Internal) converts a percentage (`0..1`) to a bar translateX
|
||||
* percentage (`-100%..0%`).
|
||||
*/
|
||||
|
||||
function toBarPerc(n) {
|
||||
return (-1 + n) * 100;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* (Internal) returns the correct CSS for changing the bar's
|
||||
* position given an n percentage, and speed and ease from Settings
|
||||
*/
|
||||
|
||||
function barPositionCSS(n, speed, ease) {
|
||||
var barCSS;
|
||||
|
||||
if (Settings.positionUsing === 'translate3d') {
|
||||
barCSS = { transform: 'translate3d('+toBarPerc(n)+'%,0,0)' };
|
||||
} else if (Settings.positionUsing === 'translate') {
|
||||
barCSS = { transform: 'translate('+toBarPerc(n)+'%,0)' };
|
||||
} else {
|
||||
barCSS = { 'margin-left': toBarPerc(n)+'%' };
|
||||
}
|
||||
|
||||
barCSS.transition = 'all '+speed+'ms '+ease;
|
||||
|
||||
return barCSS;
|
||||
}
|
||||
|
||||
/**
|
||||
* (Internal) Queues a function to be executed.
|
||||
*/
|
||||
|
||||
var queue = (function() {
|
||||
var pending = [];
|
||||
|
||||
function next() {
|
||||
var fn = pending.shift();
|
||||
if (fn) {
|
||||
fn(next);
|
||||
}
|
||||
}
|
||||
|
||||
return function(fn) {
|
||||
pending.push(fn);
|
||||
if (pending.length == 1) next();
|
||||
};
|
||||
})();
|
||||
|
||||
/**
|
||||
* (Internal) Applies css properties to an element, similar to the jQuery
|
||||
* css method.
|
||||
*
|
||||
* While this helper does assist with vendor prefixed property names, it
|
||||
* does not perform any manipulation of values prior to setting styles.
|
||||
*/
|
||||
|
||||
var css = (function() {
|
||||
var cssPrefixes = [ 'Webkit', 'O', 'Moz', 'ms' ],
|
||||
cssProps = {};
|
||||
|
||||
function camelCase(string) {
|
||||
return string.replace(/^-ms-/, 'ms-').replace(/-([\da-z])/gi, function(match, letter) {
|
||||
return letter.toUpperCase();
|
||||
});
|
||||
}
|
||||
|
||||
function getVendorProp(name) {
|
||||
var style = document.body.style;
|
||||
if (name in style) return name;
|
||||
|
||||
var i = cssPrefixes.length,
|
||||
capName = name.charAt(0).toUpperCase() + name.slice(1),
|
||||
vendorName;
|
||||
while (i--) {
|
||||
vendorName = cssPrefixes[i] + capName;
|
||||
if (vendorName in style) return vendorName;
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
function getStyleProp(name) {
|
||||
name = camelCase(name);
|
||||
return cssProps[name] || (cssProps[name] = getVendorProp(name));
|
||||
}
|
||||
|
||||
function applyCss(element, prop, value) {
|
||||
prop = getStyleProp(prop);
|
||||
element.style[prop] = value;
|
||||
}
|
||||
|
||||
return function(element, properties) {
|
||||
var args = arguments,
|
||||
prop,
|
||||
value;
|
||||
|
||||
if (args.length == 2) {
|
||||
for (prop in properties) {
|
||||
value = properties[prop];
|
||||
if (value !== undefined && properties.hasOwnProperty(prop)) applyCss(element, prop, value);
|
||||
}
|
||||
} else {
|
||||
applyCss(element, args[1], args[2]);
|
||||
}
|
||||
}
|
||||
})();
|
||||
|
||||
/**
|
||||
* (Internal) Determines if an element or space separated list of class names contains a class name.
|
||||
*/
|
||||
|
||||
function hasClass(element, name) {
|
||||
var list = typeof element == 'string' ? element : classList(element);
|
||||
return list.indexOf(' ' + name + ' ') >= 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* (Internal) Adds a class to an element.
|
||||
*/
|
||||
|
||||
function addClass(element, name) {
|
||||
var oldList = classList(element),
|
||||
newList = oldList + name;
|
||||
|
||||
if (hasClass(oldList, name)) return;
|
||||
|
||||
// Trim the opening space.
|
||||
element.className = newList.substring(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* (Internal) Removes a class from an element.
|
||||
*/
|
||||
|
||||
function removeClass(element, name) {
|
||||
var oldList = classList(element),
|
||||
newList;
|
||||
|
||||
if (!hasClass(element, name)) return;
|
||||
|
||||
// Replace the class name.
|
||||
newList = oldList.replace(' ' + name + ' ', ' ');
|
||||
|
||||
// Trim the opening and closing spaces.
|
||||
element.className = newList.substring(1, newList.length - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* (Internal) Gets a space separated list of the class names on the element.
|
||||
* The list is wrapped with a single space on each end to facilitate finding
|
||||
* matches within the list.
|
||||
*/
|
||||
|
||||
function classList(element) {
|
||||
return (' ' + (element && element.className || '') + ' ').replace(/\s+/gi, ' ');
|
||||
}
|
||||
|
||||
/**
|
||||
* (Internal) Removes an element from the DOM.
|
||||
*/
|
||||
|
||||
function removeElement(element) {
|
||||
element && element.parentNode && element.parentNode.removeChild(element);
|
||||
}
|
||||
|
||||
return NProgress;
|
||||
});
|
||||
|
||||
layui.define([], function(exports) {
|
||||
exports('nprogress', NProgress);
|
||||
});
|
47
public/static/component/pear/module/extends/popup.js
Normal file
47
public/static/component/pear/module/extends/popup.js
Normal file
@ -0,0 +1,47 @@
|
||||
layui.define(['layer'], function(exports) {
|
||||
"use strict";
|
||||
|
||||
var MOD_NAME = 'popup',
|
||||
layer = layui.layer;
|
||||
|
||||
var popup = new function() {
|
||||
|
||||
this.success = function(msg) {
|
||||
layer.msg(msg, {
|
||||
icon: 1,
|
||||
time: 1000
|
||||
})
|
||||
},
|
||||
this.failure = function(msg) {
|
||||
layer.msg(msg, {
|
||||
icon: 2,
|
||||
time: 1000
|
||||
})
|
||||
},
|
||||
this.warning = function(msg) {
|
||||
layer.msg(msg, {
|
||||
icon: 3,
|
||||
time: 1000
|
||||
})
|
||||
},
|
||||
this.success = function(msg, callback) {
|
||||
layer.msg(msg, {
|
||||
icon: 1,
|
||||
time: 1000
|
||||
}, callback);
|
||||
},
|
||||
this.failure = function(msg, callback) {
|
||||
layer.msg(msg, {
|
||||
icon: 2,
|
||||
time: 1000
|
||||
}, callback);
|
||||
},
|
||||
this.warming = function(msg, callback) {
|
||||
layer.msg(msg, {
|
||||
icon: 3,
|
||||
time: 1000
|
||||
}, callback);
|
||||
}
|
||||
};
|
||||
exports(MOD_NAME, popup);
|
||||
})
|
1225
public/static/component/pear/module/extends/toast.js
Normal file
1225
public/static/component/pear/module/extends/toast.js
Normal file
File diff suppressed because it is too large
Load Diff
2059
public/static/component/pear/module/extends/yaml.js
Normal file
2059
public/static/component/pear/module/extends/yaml.js
Normal file
File diff suppressed because it is too large
Load Diff
105
public/static/component/pear/module/imagecut.js
Normal file
105
public/static/component/pear/module/imagecut.js
Normal file
@ -0,0 +1,105 @@
|
||||
/**
|
||||
images压缩扩展模块
|
||||
changlin_zhao@qq.com
|
||||
2023.5.23
|
||||
**/
|
||||
layui.define(['upload','layer'],function(exports){
|
||||
|
||||
var layer = layui.layer;
|
||||
|
||||
var Compressor = {
|
||||
upload: function (obj) {
|
||||
// opthions = {
|
||||
// width: option[0],
|
||||
// height: option[1],
|
||||
// quality: option[2]
|
||||
// }
|
||||
obj.preview(function(index, file, result){
|
||||
canvasDataURL(result, {quality: 0.7}, function(base64Codes){
|
||||
obj.upload(index, convertBase64UrlTo(base64Codes, file.name));
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 已知 base64
|
||||
// canvasDataURL(base64, {quality: 0.7}, function(base64Codes){
|
||||
// // base64Codes 为压缩后的
|
||||
// // 其中 convertBase64UrlTo(base64Codes, file.name) 可返回 File 对象和 Blob
|
||||
// obj.upload(index, convertBase64UrlTo(base64Codes, file.name));
|
||||
// });
|
||||
|
||||
// 未知 base64
|
||||
// imageCompress(file, {quality: 0.7}, function(base64Codes){
|
||||
// // base64Codes 为压缩后的
|
||||
// obj.upload(index, convertBase64UrlTo(base64Codes, file.name));
|
||||
// });
|
||||
|
||||
/**
|
||||
* 读取文件
|
||||
* @param {file or Blob} file 上传文件
|
||||
* @param {object} config 压缩配置 可配置压缩长宽、质量等
|
||||
* @param {function} callback
|
||||
*/
|
||||
function imageCompress(file, config, callback){
|
||||
var ready = new FileReader();
|
||||
ready.readAsDataURL(file);
|
||||
|
||||
ready.onload=function(){
|
||||
canvasDataURL(this.result, config, callback)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string} path
|
||||
* @param {object} config -- {width: '', height: '', quality: 0.7}
|
||||
* @param {function} callback
|
||||
*/
|
||||
function canvasDataURL(path, config, callback){
|
||||
var img = new Image();
|
||||
img.src = path;
|
||||
|
||||
img.onload = function(){
|
||||
var that = this, quality = 0.6;
|
||||
var w = that.width, h = that.height, scale = w / h;
|
||||
w = config.width || w;
|
||||
h = config.height || (w / scale);
|
||||
|
||||
//生成canvas
|
||||
var canvas = document.createElement('canvas');
|
||||
var ctx = canvas.getContext('2d');
|
||||
var anw = document.createAttribute("width");
|
||||
anw.nodeValue = w;
|
||||
var anh = document.createAttribute("height");
|
||||
anh.nodeValue = h;
|
||||
canvas.setAttributeNode(anw);
|
||||
canvas.setAttributeNode(anh);
|
||||
ctx.drawImage(that, 0, 0, w, h);
|
||||
|
||||
if(config.quality && config.quality <= 1 && config.quality > 0){
|
||||
quality = config.quality;
|
||||
}
|
||||
callback(canvas.toDataURL('image/jpeg', quality));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将图片 base64 转为 File 对象或者 Blob
|
||||
* @param {*} urlData 图片 base64
|
||||
* @param {*} filename 图片名 没有图片名将转为 Blob
|
||||
*/
|
||||
function convertBase64UrlTo(urlData, filename = null){
|
||||
var base64Arr = urlData.split(','), mime = base64Arr[0].match(/:(.*?);/)[1],
|
||||
bstr = atob(base64Arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
|
||||
while(n--){
|
||||
u8arr[n] = bstr.charCodeAt(n);
|
||||
}
|
||||
|
||||
return filename ? new File([u8arr], filename, {type:mime}) : new Blob([u8arr], {type:mime});
|
||||
}
|
||||
|
||||
//输出 imagecut接口
|
||||
exports('imagecut', Compressor);
|
||||
|
||||
});
|
@ -20,7 +20,6 @@ layui.define(['table', 'jquery', 'element'], function (exports) {
|
||||
defaultOpen: opt.defaultOpen,
|
||||
defaultSelect: opt.defaultSelect,
|
||||
control: opt.control,
|
||||
controlWidth: opt.controlWidth ? opt.controlWidth : "auto",
|
||||
defaultMenu: opt.defaultMenu,
|
||||
accordion: opt.accordion,
|
||||
height: opt.height,
|
||||
@ -57,31 +56,6 @@ layui.define(['table', 'jquery', 'element'], function (exports) {
|
||||
// 处理高度
|
||||
$("#" + opt.elem).height(option.height)
|
||||
|
||||
setTimeout(function () {
|
||||
$("#" + opt.control + " .control").on("mousewheel DOMMouseScroll", function (event) {
|
||||
|
||||
var delta = (event.originalEvent.wheelDelta && (event.originalEvent.wheelDelta > 0 ? 1 : -1)) || // chrome & ie
|
||||
(event.originalEvent.detail && (event.originalEvent.detail > 0 ? -1 : 1)); // firefox
|
||||
|
||||
if (delta > 0) {
|
||||
for (var num = 1; num < 20; num++) {
|
||||
setTimeout(function () {
|
||||
if ($("#" + opt.control + " .control ul").css('left').replace("px", "") < 0) {
|
||||
$("#" + opt.control + " .control ul").css("left", "+=2px");
|
||||
}
|
||||
}, 10)
|
||||
}
|
||||
} else if (delta < 0) {
|
||||
if (((Number)($("#" + opt.control + " .control ul").css("left").replace("px", "")) + ($("#" + opt.control + " .control ul").width() - $("#" + opt.control + " .control").width())) > 0) {
|
||||
for (var num = 1; num < 20; num++) {
|
||||
setTimeout(function () {
|
||||
$("#" + opt.control + " .control ul").css("left", "-=2px");
|
||||
}, 10)
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}, 1000)
|
||||
|
||||
return new pearMenu(option);
|
||||
}
|
||||
@ -322,7 +296,8 @@ layui.define(['table', 'jquery', 'element'], function (exports) {
|
||||
}
|
||||
|
||||
function createMenuAndControl(option) {
|
||||
var control = '<div style="width: ' + option.controlWidth + 'px;white-space: nowrap;overflow-x: scroll;overflow: hidden;" class="control"><ul class="layui-nav pear-nav-control pc layui-hide-xs" style="width: fit-content;">';
|
||||
var control = '<div class="control"><ul class="layui-nav pear-nav-control pc layui-hide-xs" style="width: fit-content;">';
|
||||
control+= '<li class="layui-nav-item tabdrop layui-hide" style="float:right !important;"><a href="javascript:;"><i class="layui-icon layui-icon-more layui-font-20"></i></a><dl class="layui-nav-child"></dl></li>';
|
||||
var controlPe = '<ul class="layui-nav pear-nav-control layui-hide-sm">';
|
||||
// 声 明 头 部
|
||||
var menu = '<div class="layui-side-scroll ' + option.theme + '">'
|
||||
@ -479,7 +454,6 @@ layui.define(['table', 'jquery', 'element'], function (exports) {
|
||||
});
|
||||
});
|
||||
} else {
|
||||
$(this).parent().addClass("layui-nav-itemed");
|
||||
ele.animate({
|
||||
height: "0px"
|
||||
}, 240, function () {
|
||||
@ -551,10 +525,57 @@ layui.define(['table', 'jquery', 'element'], function (exports) {
|
||||
rationalizeWidth = $headerControl.parent().innerWidth() - $headerControl.position().left;
|
||||
}
|
||||
|
||||
if (option.controlWidth && rationalizeWidth >= option.controlWidth) {
|
||||
rationalizeWidth = option.controlWidth;
|
||||
}
|
||||
$("#" + option.control + " .control").css({ "width": rationalizeWidth, "transition": "width .15s" });
|
||||
$("#" + option.control + " .control").css({"width": rationalizeWidth});
|
||||
|
||||
var navobj = $("#" + option.control+' ul.pear-nav-control.pc');
|
||||
var dropdown = $(".tabdrop", navobj);
|
||||
|
||||
var collection = 0;
|
||||
var maxwidth = rationalizeWidth - 60;
|
||||
|
||||
var liwidth = 0;
|
||||
//检查超过一行的标签页
|
||||
$('.tabdrop').find('dd').each(function(){
|
||||
var newLI = $('<li></li>').html($(this).html());
|
||||
newLI.addClass('layui-nav-item');
|
||||
newLI.attr('pear-href', $(this).attr('pear-href'));
|
||||
newLI.attr('pear-title', $(this).attr('pear-title'));
|
||||
newLI.attr('pear-id', $(this).attr('pear-id'));
|
||||
navobj.append(newLI);
|
||||
$(this).remove();
|
||||
|
||||
})
|
||||
var litabs = navobj.find('>li').not('.tabdrop');
|
||||
|
||||
var totalwidth = 0;
|
||||
litabs.each(function () {
|
||||
totalwidth += $(this).outerWidth(true);
|
||||
});
|
||||
|
||||
if (rationalizeWidth < totalwidth) {
|
||||
litabs.each(function () {
|
||||
liwidth += $(this).outerWidth(true);
|
||||
if (liwidth > maxwidth) {
|
||||
var newDD = $('<dd></dd>').html($(this).html());
|
||||
newDD.attr('pear-href', $(this).attr('pear-href'));
|
||||
newDD.attr('pear-title', $(this).attr('pear-title'));
|
||||
newDD.attr('pear-id', $(this).attr('pear-id'));
|
||||
dropdown.find('dl').append(newDD);
|
||||
collection++;
|
||||
$(this).remove();
|
||||
}
|
||||
});
|
||||
if (collection > 0) {
|
||||
dropdown.removeClass('layui-hide');
|
||||
if (dropdown.find('.active').length === 1) {
|
||||
dropdown.addClass('active');
|
||||
} else {
|
||||
dropdown.removeClass('active');
|
||||
}
|
||||
}
|
||||
}else {
|
||||
dropdown.addClass('layui-hide');
|
||||
}
|
||||
}
|
||||
|
||||
function rationalizeHeaderControlWidthAuto(option){
|
||||
|
233
public/static/component/pear/module/menuSearch.js
Normal file
233
public/static/component/pear/module/menuSearch.js
Normal file
@ -0,0 +1,233 @@
|
||||
layui.define(['jquery', 'tools'], function (exports) {
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* @since Pear Admin 4.0
|
||||
*
|
||||
* Button component
|
||||
* */
|
||||
var MOD_NAME = 'menuSearch',
|
||||
tools = layui.tools,
|
||||
$ = layui.jquery;
|
||||
|
||||
var menuSearch = function (opt) {
|
||||
this.option = opt;
|
||||
};
|
||||
|
||||
/**
|
||||
* @since Pear Admin 4.0
|
||||
*
|
||||
* Button start loading
|
||||
* */
|
||||
menuSearch.prototype.render = function (opt) {
|
||||
|
||||
var options = {
|
||||
select: opt.select,
|
||||
elem: opt.elem,
|
||||
dataProvider: opt.dataProvider,
|
||||
}
|
||||
|
||||
$('body').on("click", options.elem, function () {
|
||||
|
||||
var _html = [
|
||||
`<div class="menu-search-content">
|
||||
<div class="layui-form menu-search-input-wrapper">
|
||||
<div class=" layui-input-wrap layui-input-wrap-prefix">
|
||||
<div class="layui-input-prefix">
|
||||
<i class="layui-icon layui-icon-search"></i>
|
||||
</div>
|
||||
<input type="text" name="menuSearch" value="" placeholder="搜索菜单" autocomplete="off" class="layui-input" lay-affix="clear">
|
||||
</div>
|
||||
</div>
|
||||
<div class="menu-search-no-data">暂 无 信 息</div>
|
||||
<ul class="menu-search-list">
|
||||
</ul>
|
||||
<div class="menu-search-tips">
|
||||
<div>
|
||||
<span class="mr-1">选择</span><kbd class="mr-1 w-5"> ↑ </kbd><kbd class="mr-5 w-5"> ↓ </kbd>
|
||||
<span class="mr-1">确定</span><kbd class="mr-5"> Enter </kbd><span class="mr-1">关闭</span><kbd class="mr-1"> Esc </kbd>
|
||||
</div>
|
||||
</div>
|
||||
</div>`
|
||||
].join('');
|
||||
|
||||
layer.open({
|
||||
type: 1,
|
||||
offset: "10%",
|
||||
area: ['600px'],
|
||||
title: false,
|
||||
closeBtn: 0,
|
||||
shadeClose: true,
|
||||
anim: 0,
|
||||
move: false,
|
||||
content: _html,
|
||||
success: function (layero, layeridx) {
|
||||
|
||||
var $layer = layero;
|
||||
var $content = $(layero).children('.layui-layer-content');
|
||||
var $input = $(".menu-search-input-wrapper input");
|
||||
var $noData = $(".menu-search-no-data");
|
||||
var $list = $(".menu-search-list");
|
||||
var menuData = options.dataProvider();
|
||||
|
||||
$layer.css("border-radius", "6px");
|
||||
$input.off("focus").focus();
|
||||
|
||||
// 搜索输入事件
|
||||
$input.off("input").on("input", tools.debounce(function () {
|
||||
var keywords = $input.val().trim();
|
||||
var filteredMenus = filterHandle(menuData, keywords);
|
||||
|
||||
if (filteredMenus.length) {
|
||||
var tiledMenus = tiledHandle(filteredMenus);
|
||||
var listHtml = createList(tiledMenus);
|
||||
$noData.css("display", "none");
|
||||
$list.html("").append(listHtml).children(":first").addClass("this")
|
||||
} else {
|
||||
$list.html("");
|
||||
$noData.css("display", "flex");
|
||||
}
|
||||
var currentHeight = $(".menu-search-content").outerHeight()
|
||||
$layer.css("height", currentHeight);
|
||||
$content.css("height", currentHeight);
|
||||
}, 500)
|
||||
)
|
||||
|
||||
// 列表点击事件
|
||||
$list.off("click").on("click", "li", function () {
|
||||
var id = $(this).attr("smenu-id");
|
||||
var title = $(this).attr("smenu-title");
|
||||
var url = $(this).attr("smenu-url");
|
||||
var type = $(this).attr("smenu-type");
|
||||
var openType = $(this).attr("smenu-open-type");
|
||||
|
||||
options.select({ id, title, url, type, openType });
|
||||
|
||||
layer.close(layeridx);
|
||||
})
|
||||
|
||||
$list.off('mouseenter').on("mouseenter", "li", function () {
|
||||
$(".menu-search-list li.this").removeClass("this");
|
||||
$(this).addClass("this");
|
||||
}).off("mouseleave").on("mouseleave", "li", function () {
|
||||
$(this).removeClass("this");
|
||||
})
|
||||
|
||||
// 监听键盘事件
|
||||
$('.menu-search-content').off("keydown").keydown(function (e) {
|
||||
if (e.keyCode === 13 || e.keyCode === 32) {
|
||||
e.preventDefault();
|
||||
var that = $(".menu-search-list li.this");
|
||||
var id = that.attr("smenu-id");
|
||||
var title = that.attr("smenu-title");
|
||||
var url = that.attr("smenu-url");
|
||||
var type = that.attr("smenu-type");
|
||||
var openType = that.attr("smenu-open-type");
|
||||
|
||||
options.select({ id, title, url, type, openType });
|
||||
|
||||
layer.close(layeridx);
|
||||
} else if (e.keyCode === 38) {
|
||||
e.preventDefault();
|
||||
var prevEl = $(".menu-search-list li.this").prev();
|
||||
$(".menu-search-list li.this").removeClass("this");
|
||||
if (prevEl.length !== 0) {
|
||||
prevEl.addClass("this");
|
||||
} else {
|
||||
$list.children().last().addClass("this");
|
||||
}
|
||||
} else if (e.keyCode === 40) {
|
||||
e.preventDefault();
|
||||
var nextEl = $(".menu-search-list li.this").next();
|
||||
$(".menu-search-list li.this").removeClass("this");
|
||||
if (nextEl.length !== 0) {
|
||||
nextEl.addClass("this");
|
||||
} else {
|
||||
$list.children().first().addClass("this");
|
||||
}
|
||||
} else if (e.keyCode === 27) {
|
||||
e.preventDefault();
|
||||
layer.close(layeridx);
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
return new menuSearch(options);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since Pear Admin 4.0
|
||||
*
|
||||
* 创建结果列表
|
||||
*/
|
||||
var createList = function (data) {
|
||||
var listHtml = '';
|
||||
$.each(data, function (index, item) {
|
||||
listHtml += `<li smenu-open-type="${item.info.openType}" smenu-id="${item.info.id}" smenu-icon="'${item.info.icon}" smenu-url="${item.info.href}" smenu-title="${item.info.title}" smenu-type="${item.info.type}">
|
||||
<span><i style="margin-right:10px" class="${item.info.icon}"></i>${item.path}</span>
|
||||
<i class="layui-icon layui-icon-right"></i>
|
||||
</li>`
|
||||
})
|
||||
return listHtml;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since Pear Admin 4.0
|
||||
*
|
||||
* Tree 转 path 列表
|
||||
*/
|
||||
var tiledHandle = function (data) {
|
||||
var tiledMenus = [];
|
||||
var treeTiled = function (data, content) {
|
||||
var path = "";
|
||||
var separator = " / ";
|
||||
if (!content) content = "";
|
||||
$.each(data, function (index, item) {
|
||||
if (item.children && item.children.length) {
|
||||
path += content + item.title + separator;
|
||||
var childPath = treeTiled(item.children, path);
|
||||
path += childPath;
|
||||
if (!childPath) path = ""; // 重置路径
|
||||
} else {
|
||||
path += content + item.title
|
||||
tiledMenus.push({ path: path, info: item });
|
||||
path = ""; //重置路径
|
||||
}
|
||||
})
|
||||
return path;
|
||||
};
|
||||
treeTiled(data);
|
||||
|
||||
return tiledMenus;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since Pear Admin 4.0
|
||||
*
|
||||
* 查询匹配算法
|
||||
*/
|
||||
var filterHandle = function (filterData, val) {
|
||||
if (!val) return [];
|
||||
var filteredMenus = [];
|
||||
filterData = $.extend(true, {}, filterData);
|
||||
$.each(filterData, function (index, item) {
|
||||
if (item.children && item.children.length) {
|
||||
var children = filterHandle(item.children, val)
|
||||
var obj = $.extend({}, item, { children: children });
|
||||
if (children && children.length) {
|
||||
filteredMenus.push(obj);
|
||||
} else if (item.title.indexOf(val) >= 0) {
|
||||
item.children = []; // 父级匹配但子级不匹配,就去除子级
|
||||
filteredMenus.push($.extend({}, item));
|
||||
}
|
||||
} else if (item.title.indexOf(val) >= 0) {
|
||||
filteredMenus.push(item);
|
||||
}
|
||||
})
|
||||
return filteredMenus;
|
||||
}
|
||||
|
||||
exports(MOD_NAME, new menuSearch());
|
||||
});
|
85
public/static/component/pear/module/messageCenter.js
Normal file
85
public/static/component/pear/module/messageCenter.js
Normal file
@ -0,0 +1,85 @@
|
||||
layui.define(['table', 'jquery', 'element', 'dropdown'], function (exports) {
|
||||
"use strict";
|
||||
|
||||
var MOD_NAME = 'messageCenter',
|
||||
$ = layui.jquery,
|
||||
dropdown = layui.dropdown;
|
||||
|
||||
var message = function (opt) {
|
||||
this.option = opt;
|
||||
};
|
||||
|
||||
message.prototype.render = function (opt) {
|
||||
var option = {
|
||||
elem: opt.elem,
|
||||
url: opt.url ? opt.url : false,
|
||||
height: opt.height,
|
||||
data: opt.data
|
||||
}
|
||||
if (option.url != false) {
|
||||
$.get(option.url, function (result) {
|
||||
const { code, success, data } = result;
|
||||
$(`${opt.elem}`).append(`<li class="layui-nav-item" lay-unselect="">
|
||||
<a href="#" class="notice layui-icon layui-icon-notice"></a>
|
||||
</li>`);
|
||||
if (code == 200 || success) {
|
||||
option.data = data;
|
||||
dropdown.render({
|
||||
elem: option.elem,
|
||||
align: "center",
|
||||
content: createHtml(option),
|
||||
})
|
||||
}
|
||||
});
|
||||
}
|
||||
return new message(option);
|
||||
}
|
||||
|
||||
message.prototype.click = function (callback) {
|
||||
$("*[notice-id]").click(function (event) {
|
||||
event.preventDefault();
|
||||
var id = $(this).attr("notice-id");
|
||||
var title = $(this).attr("notice-title");
|
||||
var context = $(this).attr("notice-context");
|
||||
var form = $(this).attr("notice-form");
|
||||
callback(id, title, context, form);
|
||||
})
|
||||
}
|
||||
|
||||
function createHtml(option) {
|
||||
|
||||
var count = 0;
|
||||
var notice = '<div class="pear-message-center"><div class="layui-tab layui-tab-brief">'
|
||||
var noticeTitle = '<ul class="layui-tab-title">';
|
||||
var noticeContent = '<div class="layui-tab-content" style="height:' + option.height + ';overflow-x: hidden;padding:0px;">';
|
||||
|
||||
$.each(option.data, function (i, item) {
|
||||
|
||||
noticeTitle += `<li class="${i === 0 ? 'layui-this' : ''}">${item.title}</li>`;
|
||||
noticeContent += '<div class="layui-tab-item layui-show">';
|
||||
|
||||
|
||||
$.each(item.children, function (i, note) {
|
||||
count++;
|
||||
noticeContent += '<div class="message-item" notice-form="' + note.form + '" notice-context="' + note.context +
|
||||
'" notice-title="' + note.title + '" notice-id="' + note.id + '">';
|
||||
|
||||
noticeContent += '<img src="' + note.avatar + '"/><div style="display:inline-block;">' + note.title + '</div>' +
|
||||
'<div class="extra">' + note.time + '</div>' +
|
||||
'</div>';
|
||||
})
|
||||
|
||||
noticeContent += '</div>';
|
||||
})
|
||||
|
||||
noticeTitle += '</ul>';
|
||||
noticeContent += '</div>';
|
||||
notice += noticeTitle;
|
||||
notice += noticeContent;
|
||||
notice += "</div></div>"
|
||||
|
||||
return notice;
|
||||
}
|
||||
|
||||
exports(MOD_NAME, new message());
|
||||
})
|
132
public/static/component/pear/module/page.js
Normal file
132
public/static/component/pear/module/page.js
Normal file
@ -0,0 +1,132 @@
|
||||
layui.define(['jquery', 'element'], function (exports) {
|
||||
"use strict";
|
||||
|
||||
var $ = layui.jquery;
|
||||
var element = layui.element;
|
||||
|
||||
var page = function (opt) {
|
||||
this.option = opt;
|
||||
};
|
||||
|
||||
/**
|
||||
* @since Pear Admin 4.0
|
||||
*
|
||||
* 创建 Page 页面
|
||||
*/
|
||||
page.prototype.render = function (opt) {
|
||||
var option = {
|
||||
elem: opt.elem,
|
||||
url: opt.url,
|
||||
width: opt.width || "100%",
|
||||
height: opt.height || "100%",
|
||||
title: opt.title
|
||||
}
|
||||
renderContent(option);
|
||||
return new page(option);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since Pear Admin 4.0
|
||||
*
|
||||
* 切换 Page 页面
|
||||
*/
|
||||
page.prototype.changePage = function (options) {
|
||||
|
||||
const $frame = $(`#${this.option.elem} .pear-page-content`);
|
||||
|
||||
if (options.type === "_iframe") {
|
||||
|
||||
$frame.html(`<iframe src='${options.href}' scrolling='auto' frameborder='0' allowfullscreen='true'></iframe>`);
|
||||
|
||||
} else {
|
||||
$.ajax({
|
||||
url: options.href,
|
||||
type: 'get',
|
||||
dataType: 'html',
|
||||
success: function (data) {
|
||||
$frame.html(data)
|
||||
},
|
||||
error: function (xhr) {
|
||||
return layer.msg('Status:' + xhr.status + ',' + xhr.statusText + ',请稍后再试!');
|
||||
}
|
||||
});
|
||||
}
|
||||
$frame.attr("type", options.type);
|
||||
$frame.attr("href", options.href);
|
||||
}
|
||||
|
||||
page.prototype.refresh = function (loading) {
|
||||
|
||||
var $frameLoad = $(`#${this.option.elem} .pear-page-loading`);
|
||||
var $frame = $(`#${this.option.elem} .pear-page-content`);
|
||||
|
||||
if (loading) {
|
||||
$frameLoad.css({
|
||||
display: 'block'
|
||||
});
|
||||
}
|
||||
|
||||
if ($frame.attr("type") === "_iframe") {
|
||||
|
||||
$frame.html(`<iframe src='${$frame.attr("href")}' scrolling='auto' frameborder='0' allowfullscreen='true'></iframe>`);
|
||||
|
||||
const $contentFrame = $frame.find("iframe");
|
||||
|
||||
$contentFrame.on("load", () => {
|
||||
$frameLoad.fadeOut(1000);
|
||||
})
|
||||
|
||||
} else {
|
||||
$.ajax({
|
||||
type: 'get',
|
||||
url: $frame.attr("href"),
|
||||
dataType: 'html',
|
||||
success: function (data) {
|
||||
$frame.html(data)
|
||||
$frameLoad.fadeOut(1000);
|
||||
element.init();
|
||||
},
|
||||
error: function (xhr) {
|
||||
return layer.msg('Status:' + xhr.status + ',' + xhr.statusText + ',请稍后再试!');
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function renderContent(option) {
|
||||
|
||||
$("#" + option.elem).html(`
|
||||
<div class='pear-page'>
|
||||
<div class='pear-page-content' type='${option.type}' href='${option.url}'></div>
|
||||
<div class="pear-page-loading">
|
||||
<div class="ball-loader">
|
||||
<span></span>
|
||||
<span></span>
|
||||
<span></span>
|
||||
<span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>`);
|
||||
|
||||
var $frame = $("#" + option.elem).find(".pear-page-content");
|
||||
|
||||
if (option.type === "_iframe") {
|
||||
|
||||
$frame.html(`<iframe src='${option.url}' scrolling='auto' frameborder='0' allowfullscreen='true'></iframe>`);
|
||||
} else {
|
||||
$.ajax({
|
||||
url: option.url,
|
||||
type: 'get',
|
||||
dataType: 'html',
|
||||
success: function (data) {
|
||||
$frame.html(data);
|
||||
},
|
||||
error: function (xhr) {
|
||||
return layer.msg('Status:' + xhr.status + ',' + xhr.statusText + ',请稍后再试!');
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
exports('page', new page());
|
||||
});
|
626
public/static/component/pear/module/tabPage.js
Normal file
626
public/static/component/pear/module/tabPage.js
Normal file
@ -0,0 +1,626 @@
|
||||
layui.define(['jquery', 'element', 'dropdown'], function (exports) {
|
||||
"use strict";
|
||||
|
||||
var MOD_NAME = 'tabPage',
|
||||
$ = layui.jquery,
|
||||
dropdown = layui.dropdown,
|
||||
element = layui.element;
|
||||
|
||||
var tabPage = function (opt) {
|
||||
this.option = opt;
|
||||
};
|
||||
|
||||
var tabData = new Array();
|
||||
var tabDataCurrent = 0;
|
||||
var contextTabDOM;
|
||||
|
||||
tabPage.prototype.render = function (opt) {
|
||||
|
||||
var option = {
|
||||
elem: opt.elem,
|
||||
data: opt.data,
|
||||
index: opt.index,
|
||||
tool: opt.tool || true,
|
||||
roll: opt.roll || true,
|
||||
success: opt.success ? opt.success : function (id) { },
|
||||
session: opt.session ? opt.session : false,
|
||||
preload: opt.preload ? opt.preload : false,
|
||||
height: opt.height || "100%",
|
||||
width: opt.width || "100%",
|
||||
closeEvent: opt.closeEvent,
|
||||
tabMax: opt.tabMax,
|
||||
}
|
||||
|
||||
if (option.session) {
|
||||
if (sessionStorage.getItem(option.elem + "-pear-tab-page-data") != null) {
|
||||
tabData = JSON.parse(sessionStorage.getItem(option.elem + "-pear-tab-page-data"));
|
||||
option.data = JSON.parse(sessionStorage.getItem(option.elem + "-pear-tab-page-data"));
|
||||
tabDataCurrent = sessionStorage.getItem(option.elem + "-pear-tab-page-data-current");
|
||||
tabData.forEach(function (item, index) {
|
||||
if (item.id == tabDataCurrent) {
|
||||
option.index = index;
|
||||
}
|
||||
})
|
||||
} else {
|
||||
tabData = opt.data;
|
||||
}
|
||||
}
|
||||
|
||||
var lastIndex;
|
||||
var tab = createTab(option);
|
||||
$("#" + option.elem).html(tab);
|
||||
$(".layui-tab[lay-filter='" + option.elem + "'] .layui-tab-prev").click(function () {
|
||||
rollPage("left", option);
|
||||
})
|
||||
$(".layui-tab[lay-filter='" + option.elem + "'] .layui-tab-next").click(function () {
|
||||
rollPage("right", option);
|
||||
})
|
||||
element.init();
|
||||
|
||||
$("#" + option.elem).width(opt.width);
|
||||
$("#" + option.elem).height(opt.height);
|
||||
$("#" + option.elem).css({
|
||||
position: "relative"
|
||||
});
|
||||
closeEvent(option);
|
||||
|
||||
option.success(sessionStorage.getItem(option.elem + "-pear-tab-page-data-current"));
|
||||
|
||||
dropdown.render({
|
||||
elem: `#${option.elem} .layui-tab-control > .layui-icon-down`,
|
||||
trigger: 'hover',
|
||||
data: [{
|
||||
title: '关 闭 当 前',
|
||||
id: 1
|
||||
}, {
|
||||
title: '关 闭 其 他',
|
||||
id: 2
|
||||
}, {
|
||||
title: '关 闭 全 部',
|
||||
id: 3
|
||||
}],
|
||||
click: function (obj) {
|
||||
|
||||
const id = obj.id;
|
||||
|
||||
if (id === 1) {
|
||||
var currentTab = $(".layui-tab[lay-filter='" + option.elem +
|
||||
"'] .layui-tab-title .layui-this");
|
||||
if (currentTab.find("span").is(".able-close")) {
|
||||
var currentId = currentTab.attr("lay-id");
|
||||
tabDelete(option.elem, currentId, option.closeEvent, option);
|
||||
} else {
|
||||
layer.msg("当前页面不允许关闭", {
|
||||
icon: 3,
|
||||
time: 1000
|
||||
})
|
||||
}
|
||||
} else if (id === 2) {
|
||||
var currentId = $(".layui-tab[lay-filter='" + option.elem +
|
||||
"'] .layui-tab-title .layui-this").attr("lay-id");
|
||||
var tabtitle = $(".layui-tab[lay-filter='" + option.elem + "'] .layui-tab-title li");
|
||||
$.each(tabtitle, function (i) {
|
||||
if ($(this).attr("lay-id") != currentId) {
|
||||
if ($(this).find("span").is(".able-close")) {
|
||||
tabDelete(option.elem, $(this).attr("lay-id"), option.closeEvent,
|
||||
option);
|
||||
}
|
||||
}
|
||||
})
|
||||
} else {
|
||||
var currentId = $(".layui-tab[lay-filter='" + option.elem +
|
||||
"'] .layui-tab-title .layui-this").attr("lay-id");
|
||||
var tabtitle = $(".layui-tab[lay-filter='" + option.elem + "'] .layui-tab-title li");
|
||||
$.each(tabtitle, function (i) {
|
||||
if ($(this).find("span").is(".able-close")) {
|
||||
tabDelete(option.elem, $(this).attr("lay-id"), option.closeEvent, option);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
})
|
||||
|
||||
$("body .layui-tab[lay-filter='" + option.elem + "'] .layui-tab-title").on("contextmenu", "li",
|
||||
function (e) {
|
||||
var top = e.clientY;
|
||||
var left = e.clientX;
|
||||
var menuWidth = 100;
|
||||
var currentId = $(this).attr("lay-id");
|
||||
var menu = `<ul>
|
||||
<li class='item' id='${option.elem}closeThis'>关闭当前</li>
|
||||
<li class='item' id='${option.elem}closeOther'>关闭其他</li>
|
||||
<li class='item' id='${option.elem}closeAll'>关闭所有</li>
|
||||
</ul>`;
|
||||
|
||||
contextTabDOM = $(this);
|
||||
var isOutsideBounds = (left + menuWidth) > $(window).width();
|
||||
if (isOutsideBounds) {
|
||||
left = $(window).width() - menuWidth;
|
||||
}
|
||||
|
||||
layer.open({
|
||||
type: 1,
|
||||
title: false,
|
||||
shade: false,
|
||||
skin: 'pear-tab-page-menu',
|
||||
closeBtn: false,
|
||||
area: [menuWidth + 'px', '108px'],
|
||||
fixed: true,
|
||||
anim: false,
|
||||
isOutAnim: false,
|
||||
offset: [top, left],
|
||||
content: menu,
|
||||
success: function (layero, index) {
|
||||
layer.close(lastIndex);
|
||||
lastIndex = index;
|
||||
menuEvent(option, index);
|
||||
var timer;
|
||||
$(layero).on('mouseout', function () {
|
||||
timer = setTimeout(function () {
|
||||
layer.close(index);
|
||||
}, 30)
|
||||
});
|
||||
|
||||
$(layero).on('mouseover', function () {
|
||||
clearTimeout(timer);
|
||||
});
|
||||
|
||||
$(layero).on('contextmenu', function () {
|
||||
return false;
|
||||
})
|
||||
}
|
||||
});
|
||||
return false;
|
||||
})
|
||||
|
||||
mousewheelAndTouchmoveHandler(option)
|
||||
return new tabPage(option);
|
||||
}
|
||||
|
||||
tabPage.prototype.click = function (callback) {
|
||||
var option = this.option;
|
||||
var elem = this.option.elem;
|
||||
element.on('tab(' + this.option.elem + ')', function (data) {
|
||||
var id = $("#" + elem + " .layui-tab-title .layui-this").attr("lay-id");
|
||||
sessionStorage.setItem(option.elem + "-pear-tab-page-data-current", id);
|
||||
callback(id);
|
||||
});
|
||||
}
|
||||
|
||||
tabPage.prototype.positionTab = function () {
|
||||
var $tabTitle = $('.layui-tab[lay-filter=' + this.option.elem + '] .layui-tab-title');
|
||||
var autoLeft = 0;
|
||||
$tabTitle.children("li").each(function () {
|
||||
if ($(this).hasClass('layui-this')) {
|
||||
return false;
|
||||
} else {
|
||||
autoLeft += $(this).outerWidth();
|
||||
}
|
||||
});
|
||||
$tabTitle.animate({
|
||||
scrollLeft: autoLeft - $tabTitle.width() / 3
|
||||
}, 200);
|
||||
}
|
||||
|
||||
tabPage.prototype.clear = function () {
|
||||
sessionStorage.removeItem(this.option.elem + "-pear-tab-page-data");
|
||||
sessionStorage.removeItem(this.option.elem + "-pear-tab-page-data-current");
|
||||
}
|
||||
|
||||
var index = 0;
|
||||
// 根据过滤 fliter 标识, 重置选项卡标题
|
||||
tabPage.prototype.changeTabTitleById = function (elem, id, title) {
|
||||
var currentTab = $(".layui-tab[lay-filter='" + elem + "'] .layui-tab-title [lay-id='" + id +
|
||||
"'] .title");
|
||||
currentTab.html(title);
|
||||
}
|
||||
|
||||
// 根据过滤 filter 标识, 删除指定选项卡
|
||||
tabPage.prototype.delTabByElem = function (elem, id, callback) {
|
||||
var currentTab = $(".layui-tab[lay-filter='" + elem + "'] .layui-tab-title [lay-id='" + id + "']");
|
||||
if (currentTab.find("span").is(".able-close")) {
|
||||
tabDelete(elem, id, callback);
|
||||
}
|
||||
}
|
||||
// 根据过滤 filter 标识, 删除其他选项卡
|
||||
tabPage.prototype.delOtherTabByElem = function (elem, callback) {
|
||||
var currentId = $(".layui-tab[lay-filter='" + elem + "'] .layui-tab-title .layui-this").attr(
|
||||
"lay-id");
|
||||
var tabtitle = $(".layui-tab[lay-filter='" + elem + "'] .layui-tab-title li");
|
||||
$.each(tabtitle, function (i) {
|
||||
if ($(this).attr("lay-id") != currentId) {
|
||||
if ($(this).find("span").is(".able-close")) {
|
||||
tabDelete(elem, $(this).attr("lay-id"), callback);
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 根据过滤 filter 标识, 删除全部选项卡
|
||||
tabPage.prototype.delAllTabByElem = function (elem, callback) {
|
||||
var currentId = $(".layui-tab[lay-filter='" + elem + "'] .layui-tab-title .layui-this").attr(
|
||||
"lay-id");
|
||||
var tabtitle = $(".layui-tab[lay-filter='" + elem + "'] .layui-tab-title li");
|
||||
$.each(tabtitle, function (i) {
|
||||
if ($(this).find("span").is(".able-close")) {
|
||||
tabDelete(elem, $(this).attr("lay-id"), callback);
|
||||
}
|
||||
})
|
||||
}
|
||||
// 根据过滤 filter 标识, 删除当前选项卡
|
||||
tabPage.prototype.delCurrentTabByElem = function (elem, callback) {
|
||||
var currentTab = $(".layui-tab[lay-filter='" + elem + "'] .layui-tab-title .layui-this");
|
||||
if (currentTab.find("span").is(".able-close")) {
|
||||
var currentId = currentTab.attr("lay-id");
|
||||
tabDelete(elem, currentId, callback);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @since Pear Admin 4.0
|
||||
*/
|
||||
tabPage.prototype.addTabOnly = function (opt, time) {
|
||||
|
||||
var title = `<span class="pear-tab-page-active"></span>
|
||||
<span class="${opt.close ? 'able-close' : 'disable-close'} title">${opt.title}</span>
|
||||
<i class="layui-icon layui-unselect layui-tab-close">ဆ</i>`;
|
||||
|
||||
if ($(".layui-tab[lay-filter='" + this.option.elem + "'] .layui-tab-title li[lay-id]").length <=
|
||||
0) {
|
||||
|
||||
var that = this;
|
||||
|
||||
if (opt.type === "_iframe") {
|
||||
|
||||
element.tabAdd(this.option.elem, {
|
||||
id: opt.id,
|
||||
title: title,
|
||||
content: `<iframe id="${opt.id}" type="${opt.type}" data-frameid="${opt.id}" scrolling="auto" frameborder="0" src="${opt.url}" style="width:100%;height:100%;" allowfullscreen="true"></iframe>`
|
||||
});
|
||||
|
||||
} else {
|
||||
|
||||
$.ajax({
|
||||
url: opt.url,
|
||||
type: 'get',
|
||||
dataType: 'html',
|
||||
async: false,
|
||||
success: function (data) {
|
||||
element.tabAdd(that.option.elem, {
|
||||
id: opt.id,
|
||||
title: title,
|
||||
content: `<div id="${opt.id}" type="${opt.type}" data-frameid="${opt.id}" src="${opt.url}">${data}</div>`,
|
||||
});
|
||||
},
|
||||
error: function (xhr, textstatus, thrown) {
|
||||
return layer.msg('Status:' + xhr.status + ',' + xhr.statusText + ',请稍后再试!');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
tabData.push(opt);
|
||||
sessionStorage.setItem(that.option.elem + "-pear-tab-page-data", JSON.stringify(tabData));
|
||||
sessionStorage.setItem(that.option.elem + "-pear-tab-page-data-current", opt.id);
|
||||
|
||||
} else {
|
||||
|
||||
var isData = false;
|
||||
$.each($(".layui-tab[lay-filter='" + this.option.elem + "'] .layui-tab-title li[lay-id]"),
|
||||
function () {
|
||||
if ($(this).attr("lay-id") == opt.id) {
|
||||
isData = true;
|
||||
}
|
||||
})
|
||||
|
||||
if (isData == false) {
|
||||
|
||||
if (this.option.tabMax != false) {
|
||||
if ($(".layui-tab[lay-filter='" + this.option.elem + "'] .layui-tab-title li[lay-id]")
|
||||
.length >= this.option.tabMax) {
|
||||
layer.msg("最多打开" + this.option.tabMax + "个标签页", {
|
||||
icon: 2,
|
||||
time: 1000,
|
||||
shift: 6
|
||||
});
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
var that = this;
|
||||
if (opt.type === "_iframe") {
|
||||
element.tabAdd(this.option.elem, {
|
||||
id: opt.id,
|
||||
title: title,
|
||||
content: `<iframe id="${opt.id}" type="${opt.type}" data-frameid="${opt.id}" scrolling="auto" frameborder="0" src="${opt.url}" style="width:100%;height:100%;" allowfullscreen="true"></iframe>`
|
||||
});
|
||||
} else {
|
||||
$.ajax({
|
||||
url: opt.url,
|
||||
type: 'get',
|
||||
dataType: 'html',
|
||||
async: false,
|
||||
success: function (data) {
|
||||
element.tabAdd(that.option.elem, {
|
||||
id: opt.id,
|
||||
title: title,
|
||||
content: `<div id="${opt.id}" type="${opt.type}" data-frameid="${opt.id}" src="${opt.url}">${data}</div>`,
|
||||
});
|
||||
},
|
||||
error: function (xhr, textstatus, thrown) {
|
||||
return layer.msg('Status:' + xhr.status + ',' + xhr.statusText + ',请稍后再试!');
|
||||
}
|
||||
});
|
||||
}
|
||||
tabData.push(opt);
|
||||
sessionStorage.setItem(that.option.elem + "-pear-tab-page-data", JSON.stringify(tabData));
|
||||
sessionStorage.setItem(that.option.elem + "-pear-tab-page-data-current", opt.id);
|
||||
}
|
||||
}
|
||||
element.tabChange(this.option.elem, opt.id);
|
||||
sessionStorage.setItem(this.option.elem + "-pear-tab-page-data-current", opt.id);
|
||||
}
|
||||
|
||||
// 刷 新 指 定 的 选 项 卡
|
||||
tabPage.prototype.refresh = function (time) {
|
||||
var $iframe = $(".layui-tab[lay-filter='" + this.option.elem + "'] .layui-tab-content .layui-show > *");
|
||||
var $iframeLoad;
|
||||
|
||||
if (time != false && time != 0) {
|
||||
$iframe.parent().append(`<div id="pear-tab-page-loading${index}" class="pear-tab-page-loading"><div class="ball-loader"><span></span><span></span><span></span><span></span></div></div>`);
|
||||
$iframeLoad = $("#" + this.option.elem).find("#pear-tab-page-loading" + index++);
|
||||
$iframeLoad.css({
|
||||
display: "block"
|
||||
});
|
||||
}
|
||||
|
||||
if($iframe.attr("type") === "_iframe") {
|
||||
$iframe.attr("src", $iframe.attr("src"));
|
||||
$iframe.on("load", function() {
|
||||
$iframeLoad.fadeOut(1000, function() {
|
||||
$iframeLoad.remove();
|
||||
});
|
||||
})
|
||||
} else {
|
||||
$.ajax({
|
||||
url: $iframe.attr("src"),
|
||||
type: 'get',
|
||||
dataType: 'html',
|
||||
success: function (data) {
|
||||
$iframe.html(data);
|
||||
if ($iframeLoad != undefined) {
|
||||
$iframeLoad.fadeOut(1000, function () {
|
||||
$iframeLoad.remove();
|
||||
});
|
||||
}
|
||||
},
|
||||
error: function (xhr) {
|
||||
return layer.msg('Status:' + xhr.status + ',' + xhr.statusText + ',请稍后再试!');
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function tabDelete(elem, id, callback, option) {
|
||||
var tabTitle = $(".layui-tab[lay-filter='" + elem + "']").find(".layui-tab-title");
|
||||
var removeTab = tabTitle.find("li[lay-id='" + id + "']");
|
||||
var nextNode = removeTab.next("li");
|
||||
if (!removeTab.hasClass("layui-this")) {
|
||||
removeTab.remove();
|
||||
var tabContent = $(".layui-tab[lay-filter='" + elem + "']").find("*[id='" + id + "']")
|
||||
.parent();
|
||||
tabContent.remove();
|
||||
|
||||
tabData = JSON.parse(sessionStorage.getItem(elem + "-pear-tab-page-data"));
|
||||
tabDataCurrent = sessionStorage.getItem(elem + "-pear-tab-page-data-current");
|
||||
tabData = tabData.filter(function (item) {
|
||||
return item.id != id;
|
||||
})
|
||||
sessionStorage.setItem(elem + "-pear-tab-page-data", JSON.stringify(tabData));
|
||||
return false;
|
||||
}
|
||||
|
||||
var currId;
|
||||
if (nextNode.length) {
|
||||
nextNode.addClass("layui-this");
|
||||
currId = nextNode.attr("lay-id");
|
||||
$("#" + elem + " [id='" + currId + "']").parent().addClass("layui-show");
|
||||
} else {
|
||||
var prevNode = removeTab.prev("li");
|
||||
prevNode.addClass("layui-this");
|
||||
currId = prevNode.attr("lay-id");
|
||||
$("#" + elem + " [id='" + currId + "']").parent().addClass("layui-show");
|
||||
}
|
||||
callback(currId);
|
||||
tabData = JSON.parse(sessionStorage.getItem(elem + "-pear-tab-page-data"));
|
||||
tabDataCurrent = sessionStorage.getItem(elem + "-pear-tab-page-data-current");
|
||||
tabData = tabData.filter(function (item) {
|
||||
return item.id != id;
|
||||
})
|
||||
sessionStorage.setItem(elem + "-pear-tab-page-data", JSON.stringify(tabData));
|
||||
sessionStorage.setItem(elem + "-pear-tab-page-data-current", currId);
|
||||
|
||||
removeTab.remove();
|
||||
// 删除 content
|
||||
var tabContent = $(".layui-tab[lay-filter='" + elem + "']").find("*[id='" + id + "']").parent();
|
||||
// 删除
|
||||
tabContent.remove();
|
||||
}
|
||||
|
||||
/**
|
||||
* @since Pear Admin 4.0
|
||||
*/
|
||||
function createTab(option) {
|
||||
|
||||
var type = "";
|
||||
if (option.roll == true) {
|
||||
type = "layui-tab-roll";
|
||||
}
|
||||
if (option.tool != false) {
|
||||
type = "layui-tab-tool";
|
||||
}
|
||||
if (option.roll == true && option.tool != false) {
|
||||
type = "layui-tab-rollTool";
|
||||
}
|
||||
var tab = '<div class="pear-tab-page ' + type + ' layui-tab" lay-filter="' + option.elem +
|
||||
'" lay-allowClose="true">';
|
||||
|
||||
var title = '<ul class="layui-tab-title">';
|
||||
var content = '<div class="layui-tab-content">';
|
||||
var control = `<div class="layui-tab-control">
|
||||
<li class="layui-tab-prev layui-icon layui-icon-left"></li>
|
||||
<li class="layui-tab-next layui-icon layui-icon-right"></li>
|
||||
<li class="layui-tab-tool layui-icon layui-icon-down"></li>
|
||||
</div>`;
|
||||
|
||||
// 处 理 选 项 卡 头 部
|
||||
var index = 0;
|
||||
$.each(option.data, function (i, item) {
|
||||
|
||||
var titleItem = `<li lay-id="${item.id}" class="${option.index == index ? 'layui-this' : ''}">
|
||||
<span class="pear-tab-page-active"></span>
|
||||
<span class="${item.close ? 'able-close' : 'disable-close'} title">
|
||||
${item.title}
|
||||
</span>
|
||||
<i class="layui-icon layui-unselect layui-tab-close">ဆ</i></li>
|
||||
</li>`;
|
||||
|
||||
title += titleItem;
|
||||
|
||||
if (item.type === "_iframe") {
|
||||
|
||||
content += `<div class="${option.index == index ? 'layui-show' : ''} layui-tab-item"><iframe id="${item.id}" type="${item.type}" data-frameid="${item.id}" scrolling="auto" frameborder="0" src="${item.url}" style="width:100%;height:100%;" allowfullscreen="true"></iframe></div>`
|
||||
|
||||
} else {
|
||||
|
||||
$.ajax({
|
||||
url: item.url,
|
||||
type: 'get',
|
||||
dataType: 'html',
|
||||
async: false,
|
||||
success: function (data) {
|
||||
content += `<div class="${option.index == index ? 'layui-show' : ''} layui-tab-item"><div id="${item.id}" type="${item.type}" data-frameid="${item.id}" src="${item.url}">${data}</div></div>`;
|
||||
},
|
||||
error: function (xhr) {
|
||||
return layer.msg('Status:' + xhr.status + ',' + xhr.statusText + ',请稍后再试!');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
index++;
|
||||
});
|
||||
|
||||
title += '</ul>';
|
||||
content += '</div>';
|
||||
|
||||
tab += title;
|
||||
tab += control;
|
||||
tab += content;
|
||||
tab += '</div>';
|
||||
tab += ''
|
||||
return tab;
|
||||
}
|
||||
|
||||
function rollPage(d, option) {
|
||||
var $tabTitle = $('#' + option.elem + ' .layui-tab-title');
|
||||
var left = $tabTitle.scrollLeft();
|
||||
if ('left' === d) {
|
||||
$tabTitle.animate({
|
||||
scrollLeft: left - 450
|
||||
}, 200);
|
||||
} else {
|
||||
$tabTitle.animate({
|
||||
scrollLeft: left + 450
|
||||
}, 200);
|
||||
}
|
||||
}
|
||||
|
||||
function closeEvent(option) {
|
||||
$(".layui-tab[lay-filter='" + option.elem + "']").on("click", ".layui-tab-close", function () {
|
||||
var layid = $(this).parent().attr("lay-id");
|
||||
tabDelete(option.elem, layid, option.closeEvent, option);
|
||||
})
|
||||
}
|
||||
|
||||
function menuEvent(option, index) {
|
||||
|
||||
$("#" + option.elem + "closeThis").click(function () {
|
||||
var currentTab = contextTabDOM;
|
||||
|
||||
if (currentTab.find("span").is(".able-close")) {
|
||||
var currentId = currentTab.attr("lay-id");
|
||||
tabDelete(option.elem, currentId, option.closeEvent, option);
|
||||
} else {
|
||||
layer.msg("当前页面不允许关闭", {
|
||||
icon: 3,
|
||||
time: 800
|
||||
})
|
||||
}
|
||||
layer.close(index);
|
||||
})
|
||||
|
||||
$("#" + option.elem + "closeOther").click(function () {
|
||||
var currentId = contextTabDOM.attr("lay-id");
|
||||
var tabtitle = $(".layui-tab[lay-filter='" + option.elem + "'] .layui-tab-title li");
|
||||
$.each(tabtitle, function (i) {
|
||||
if ($(this).attr("lay-id") != currentId) {
|
||||
if ($(this).find("span").is(".able-close")) {
|
||||
tabDelete(option.elem, $(this).attr("lay-id"), option.closeEvent,
|
||||
option);
|
||||
}
|
||||
}
|
||||
})
|
||||
layer.close(index);
|
||||
})
|
||||
|
||||
$("#" + option.elem + "closeAll").click(function () {
|
||||
var tabtitle = $(".layui-tab[lay-filter='" + option.elem + "'] .layui-tab-title li");
|
||||
$.each(tabtitle, function (i) {
|
||||
if ($(this).find("span").is(".able-close")) {
|
||||
tabDelete(option.elem, $(this).attr("lay-id"), option.closeEvent, option);
|
||||
}
|
||||
})
|
||||
layer.close(index);
|
||||
})
|
||||
}
|
||||
|
||||
function mousewheelAndTouchmoveHandler(option) {
|
||||
var $bodyTab = $("body .layui-tab[lay-filter='" + option.elem + "'] .layui-tab-title")
|
||||
var $tabTitle = $('#' + option.elem + ' .layui-tab-title');
|
||||
var mouseScrollStep = 100
|
||||
// 鼠标滚轮
|
||||
$bodyTab.on("mousewheel DOMMouseScroll", function (e) {
|
||||
e.originalEvent.preventDefault()
|
||||
var delta = (e.originalEvent.wheelDelta && (e.originalEvent.wheelDelta > 0 ? "top" :
|
||||
"down")) || // chrome & ie
|
||||
(e.originalEvent.detail && (e.originalEvent.detail > 0 ? "down" : "top")); // firefox
|
||||
var scrollLeft = $tabTitle.scrollLeft();
|
||||
|
||||
if (delta === "top") {
|
||||
scrollLeft -= mouseScrollStep
|
||||
} else if (delta === "down") {
|
||||
scrollLeft += mouseScrollStep
|
||||
}
|
||||
$tabTitle.scrollLeft(scrollLeft)
|
||||
});
|
||||
|
||||
// 触摸移动
|
||||
var touchX = 0;
|
||||
$bodyTab.on("touchstart", function (e) {
|
||||
var touch = e.originalEvent.targetTouches[0];
|
||||
touchX = touch.pageX
|
||||
})
|
||||
$bodyTab.on("touchmove", function (e) {
|
||||
var event = e.originalEvent;
|
||||
if (event.targetTouches.length > 1) return;
|
||||
event.preventDefault();
|
||||
var touch = event.targetTouches[0];
|
||||
var distanceX = touchX - touch.pageX
|
||||
var scrollLeft = $tabTitle.scrollLeft();
|
||||
touchX = touch.pageX
|
||||
$tabTitle.scrollLeft(scrollLeft += distanceX)
|
||||
});
|
||||
}
|
||||
|
||||
exports(MOD_NAME, new tabPage());
|
||||
})
|
40
public/static/component/pear/module/tools.js
Normal file
40
public/static/component/pear/module/tools.js
Normal file
@ -0,0 +1,40 @@
|
||||
layui.define(['jquery', 'element'],
|
||||
function (exports) {
|
||||
|
||||
var $ = layui.jquery;
|
||||
var tools = new function () {
|
||||
|
||||
/**
|
||||
* @since 防抖算法
|
||||
*
|
||||
* @param fn 要执行的方法
|
||||
* @param time 防抖时间参数
|
||||
*/
|
||||
this.debounce = function (fn, time) {
|
||||
var timer = null
|
||||
return function () {
|
||||
var arguments = arguments[0]
|
||||
if (timer) {
|
||||
clearTimeout(timer)
|
||||
}
|
||||
timer = setTimeout(function () {
|
||||
fn(arguments)
|
||||
}, time)
|
||||
}
|
||||
}
|
||||
|
||||
// image 转 base64
|
||||
this.imageToBase64 = function (img) {
|
||||
var canvas = document.createElement("canvas");
|
||||
canvas.width = img.width;
|
||||
canvas.height = img.height;
|
||||
var ctx = canvas.getContext("2d");
|
||||
ctx.drawImage(img, 0, 0, img.width, img.height);
|
||||
var ext = img.src.substring(img.src.lastIndexOf(".") + 1).toLowerCase();
|
||||
var dataURL = canvas.toDataURL("image/" + ext);
|
||||
return dataURL;
|
||||
}
|
||||
};
|
||||
|
||||
exports('tools', tools);
|
||||
})
|
@ -7,7 +7,7 @@ window.rootPath = (function (src) {
|
||||
|
||||
layui.config({
|
||||
base: rootPath + "module/",
|
||||
version: "3.30.0"
|
||||
version: "3.40.0"
|
||||
}).extend({
|
||||
admin: "admin", // 框架布局组件
|
||||
common: "common", // 公共方法封装
|
||||
|
@ -160,7 +160,7 @@ pre{overflow-y: auto;
|
||||
|
||||
/* 头像 */
|
||||
.fly-avatar{position: absolute; left: 15px; top: 10px;}
|
||||
.fly-avatar img{display: block; width: 45px; height: 45px; margin: 0; border-radius: 100%;}
|
||||
.fly-avatar img{display: block; width: 45px; height: 45px; margin: 0; border-radius: 100%; object-fit: cover;}
|
||||
.fly-avatar i{position: absolute; left: 35px; top: 25px; }
|
||||
|
||||
/* 徽章 */
|
||||
@ -191,8 +191,8 @@ pre{overflow-y: auto;
|
||||
|
||||
.fly-nav-user{position: absolute; top: 0; right: 0;}
|
||||
.fly-nav-user .iconfont{position: relative;}
|
||||
.fly-nav-avatar img{width: 36px; height: 36px; margin-left: 10px; border-radius: 100%;}
|
||||
.fly-nav-avatar .icon-renzheng{font-size: 16px; top: 1px;}
|
||||
.fly-nav-avatar img{width: 36px; height: 36px; margin-left: 10px; border-radius: 100%; object-fit: cover;}
|
||||
.fly-nav-avatar .icon-renzheng{font-size: 16px; top: 1px;}
|
||||
.fly-nav-avatar .fly-badge-vip{position: relative; margin-left: 10px;}
|
||||
.fly-nav-user .layui-nav-child a i{position: relative; top: 2px; margin-right: 10px; font-size: 26px;}
|
||||
|
||||
@ -409,13 +409,6 @@ body .layui-edit-face .layui-layer-content{padding:0; background-color:#fff; co
|
||||
.fly-signin-main span{padding-left: 10px;}
|
||||
|
||||
/* 榜单 */
|
||||
.fly-rank{padding-bottom: 10px;}
|
||||
.fly-rank dl{position: relative; overflow: hidden; margin-left: 10px; text-align: center; font-size: 0;}
|
||||
.fly-rank dd{position: relative; width: 55px; height: 75px; margin: 10px 15px 5px 0; display:inline-block; *display:inline; *zoom:1; vertical-align:top; font-size:12px;}
|
||||
.fly-rank dd a img{width: 55px; height: 55px; border-radius: 10px;}
|
||||
.fly-rank dd a cite{ position:absolute; bottom: 20px; left: 0; width: 100%; height:20px; line-height:20px; text-align:center; background-color:rgba(0,0,0,.2); color:#fff; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;}
|
||||
.fly-rank dd a:hover cite{display: block;}
|
||||
.fly-rank dd a i{position:absolute; bottom: 0; left: 0; width: 100%; text-align: center; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-style: normal;}
|
||||
|
||||
/* 温馨通道 */
|
||||
.fly-list-quick{border: 1px solid #f2f2f2; border-bottom: none; border-right: 0;}
|
||||
@ -441,7 +434,6 @@ body .layui-edit-face .layui-layer-content{padding:0; background-color:#fff; co
|
||||
.jie-row li i, .jie-row li em, .jie-row li cite{font-size:12px; color:#999; font-style: normal;}
|
||||
.jie-row li .mine-edit{margin-left:15px; padding:0 6px; background-color: #8FCDA0; color:#fff; font-size:12px;}
|
||||
.jie-row li em{position:absolute; right:0; top:0;}
|
||||
.jie-row li .jie-user{}
|
||||
.jie-row li .jie-title{max-width: 70%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;}
|
||||
.jie-row li .jie-user img{position:relative; top: 16px; width: 35px; height: 35px;}
|
||||
|
||||
@ -450,7 +442,7 @@ body .layui-edit-face .layui-layer-content{padding:0; background-color:#fff; co
|
||||
.detail .title>h1{float: left; font-size: 22px; line-height: 36px; padding-bottom:10px;}
|
||||
.detail-box .title span {float: right; padding-right: 5px;}
|
||||
.detail .fly-avatar{position: absolute; left: 15px; top: 10px;}
|
||||
.detail .fly-avatar img{display: block; width: 45px; height: 45px; margin: 0; border-radius: 100%;}
|
||||
.detail .fly-avatar img{display: block; width: 45px; height: 45px; margin: 0; border-radius: 100%; object-fit: cover;}
|
||||
.detail .fly-avatar .icon-renzheng{display: inline-block; width: 15px; height: 15px; line-height: 15px; top: 25px; left: 32px; background-color: #FFB800; color: #fff; border-radius: 50%; font-size: 14px;}
|
||||
|
||||
.fly-detail-info{position: relative; margin: 10px 0 15px;}
|
||||
@ -466,7 +458,6 @@ body .layui-edit-face .layui-layer-content{padding:0; background-color:#fff; co
|
||||
.detail-about .icon-renzheng{display: inline-block; width: 15px; height: 15px; line-height: 15px; top: 25px; left: 35px; background-color: #FFB800; color: #fff; border-radius: 50%; font-size: 10px;}
|
||||
.fly-detail-user{white-space: nowrap; overflow: hidden;}
|
||||
.fly-detail-user a{padding-right: 10px; font-size: 14px;}
|
||||
.fly-detail-user .guanzhu{position: absolute; right:10px; }
|
||||
|
||||
/*详情页管理工具条*/
|
||||
.detail-assist{
|
||||
@ -483,6 +474,32 @@ body .layui-edit-face .layui-layer-content{padding:0; background-color:#fff; co
|
||||
border-radius:5px;
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 750px) {
|
||||
.detail-assist {
|
||||
right:calc(50% - 500px);
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (min-width: 970px) {
|
||||
.detail-assist {
|
||||
right:calc(50% - 530px);
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (min-width: 1170px) {
|
||||
.detail-assist {
|
||||
right:calc(50% - 620px);
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (min-width: 1330px) {
|
||||
.detail-assist {
|
||||
right:calc(50% - 720px);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.detail-assist .fly-admin-box{text-align: center;}
|
||||
.detail-assist span{height: 30px;width:30px; line-height:30px;}
|
||||
.detail-assist .layui-btn{border-radius: 0;}
|
||||
@ -498,13 +515,6 @@ body .layui-edit-face .layui-layer-content{padding:0; background-color:#fff; co
|
||||
.detail-body p{margin-bottom: .6rem;font-size: .9375rem;line-height: 1.875;color: var(--color-secondary);word-wrap: break-word;}
|
||||
|
||||
.detail-body img{max-width: 100%; cursor: pointer;}
|
||||
/*
|
||||
.detail-body table{margin: 10px 0 15px;}
|
||||
.detail-body table thead{background-color:#f2f2f2;}
|
||||
.detail-body table th,
|
||||
.detail-body table td{padding: 10px 20px; line-height: 22px; border: 1px solid #DFDFDF; font-size: 14px; font-weight: 400;}
|
||||
*/
|
||||
|
||||
.detail-body .layui-btn{margin: 0 10px 10px 0;}
|
||||
.detail-body .layui-btn a{color: #fff;}
|
||||
.detail-body ul>li{margin-top: 0;}
|
||||
@ -512,25 +522,15 @@ body .layui-edit-face .layui-layer-content{padding:0; background-color:#fff; co
|
||||
|
||||
/*详情页-问答*/
|
||||
.user-questions{position:relative; margin: 5px 0 15px;}
|
||||
.user-questions .user-avatar img{width: 25px; height: 25px; margin-top: 10; border-radius: 100%;}
|
||||
|
||||
/*
|
||||
.detail-body-wenda{margin: 10px 0 5px; line-height: 26px; font-size: 16px; color: rgb(82, 80, 80); word-wrap: break-word;}
|
||||
.detail-body-wenda p{margin-bottom:15px;}
|
||||
.detail-body-wenda img{max-width: 100%; cursor: pointer;}
|
||||
.detail-body-wenda .layui-btn{margin: 0 10px 10px 0;}
|
||||
.detail-body-wenda .layui-btn a{color: #fff;}
|
||||
.detail-body-wenda ul>li{margin-top: 0;}
|
||||
.detail-body-wenda .layui-elem-quote{margin: 10px 0; font-size: 14px; line-height: 26px;}
|
||||
*/
|
||||
.user-questions .user-avatar img{width: 25px; height: 25px; border-radius: 100%;object-fit: cover;}
|
||||
|
||||
.layui-form-pane{position:relative; width:100%;}
|
||||
.que-comments{position:absolute; right:15px; bottom:15px;}
|
||||
|
||||
.wenda-user{height:200px; margin: 0,auto; text-align: center; pardding-top:20px;}
|
||||
.wenda-user .user-img{posation:relative; width:100%;}
|
||||
.wenda-user .user-img img{width:150px;height:150px; border-radius: 100%;}
|
||||
.wenda-user .user-img i{posation:absolute;right:20px;top:30px;width: 25px; height:25px; color:#fff; font-site:18px; border-radius: 100%;background-color:#FFB800;}
|
||||
.wenda-user{height:200px; margin: 0,auto; text-align: center; padding-top:20px;}
|
||||
.wenda-user .user-img{position:relative; width:100%;}
|
||||
.wenda-user .user-img img{width:150px; height:150px; border-radius: 100%; object-fit: cover;}
|
||||
.wenda-user .user-img i{position:absolute;right:20px;top:30px;width: 25px; height:25px; color:#fff; font-size:18px; border-radius: 100%;background-color:#FFB800;}
|
||||
.wenda-user .questions{height:30px;margin:20px 20px;}
|
||||
|
||||
/*详情页-文章post*/
|
||||
@ -600,6 +600,10 @@ body .fly-user-main{position: relative; min-height: 600px;}
|
||||
.fly-user-main .fly-none{min-height: 0;}
|
||||
.fly-panel-user[pad20]{padding-top: 5px;}
|
||||
|
||||
@media screen and (max-width: 768px) {
|
||||
.fly-user-main>.fly-panel{margin: 0 0 10px 0;}
|
||||
}
|
||||
|
||||
@media screen and (min-width: 768px) {
|
||||
.fly-panel-user{height: calc(100vh - 280px)}
|
||||
}
|
||||
@ -617,7 +621,7 @@ body .fly-user-main{position: relative; min-height: 600px;}
|
||||
|
||||
/* 个人主页 */
|
||||
.fly-home{position: relative; padding: 30px 0 30px; text-align: center;}
|
||||
.fly-home img{width:120px; height:120px; border-radius:100%;}
|
||||
.fly-home img{width:120px; height:120px; border-radius:100%; object-fit: cover;}
|
||||
.fly-home h1{font-size:26px; line-height:30px; margin-top:10px;}
|
||||
.fly-home h1 span{font-size:14px; color:#999;}
|
||||
.fly-home h1 .icon-nan{color:#4EBBF9}
|
||||
@ -787,7 +791,7 @@ p {
|
||||
margin: 0;
|
||||
white-space: normal;
|
||||
word-break: break-all;
|
||||
-webkit-user-select: none;
|
||||
/* -webkit-user-select: none; */
|
||||
}
|
||||
|
||||
code[class*="language-"], pre[class*="language-"] {
|
||||
|
@ -61,7 +61,7 @@ layui.define(['upload','layer'],function(exports){
|
||||
img.src = path;
|
||||
|
||||
img.onload = function(){
|
||||
var that = this, quality = 0.7;
|
||||
var that = this, quality = 0.6;
|
||||
var w = that.width, h = that.height, scale = w / h;
|
||||
w = config.width || w;
|
||||
h = config.height || (w / scale);
|
||||
|
@ -1,21 +1,16 @@
|
||||
/**
|
||||
TaoLer社区修改 www.aieok.com
|
||||
@Name: Fly社区主入口
|
||||
2021-5.21
|
||||
2024-4.7
|
||||
*/
|
||||
|
||||
layui.define(['layer', 'laytpl', 'form', 'element', 'upload', 'util', 'imgcom'], function(exports){
|
||||
layui.define(['layer', 'form', 'util'], function(exports){
|
||||
|
||||
var $ = layui.jquery
|
||||
,layer = layui.layer
|
||||
,laytpl = layui.laytpl
|
||||
,form = layui.form
|
||||
,element = layui.element
|
||||
,upload = layui.upload
|
||||
,util = layui.util
|
||||
,imgcom = layui.imgcom
|
||||
,device = layui.device()
|
||||
,DISABLED = 'layui-btn-disabled';
|
||||
var uid = layui.cache.user.uid;
|
||||
var login = $('.fly-nav-user').attr('userlogin');
|
||||
|
||||
@ -50,7 +45,7 @@ layui.define(['layer', 'laytpl', 'form', 'element', 'upload', 'util', 'imgcom'],
|
||||
};
|
||||
|
||||
var fly = {
|
||||
dir: layui.cache.host + 'static/res/mods/' //模块路径
|
||||
dir: layui.cache.host + 'static/res/mods/' //模块路径
|
||||
//Ajax
|
||||
,json: function(url, data, success, options){
|
||||
var that = this, type = typeof data === 'function';
|
||||
@ -93,522 +88,13 @@ layui.define(['layer', 'laytpl', 'form', 'element', 'upload', 'util', 'imgcom'],
|
||||
|
||||
,form: {}
|
||||
|
||||
//简易编辑器
|
||||
,layEditor: function(options){
|
||||
var html = ['<div class="layui-unselect fly-edit">'
|
||||
,'<span type="strong" title="加粗"><i class="layui-icon layedit-tool-b layedit-tool-active" title="加粗" lay-command="Bold" layedit-event="b" "=""></i></span>'
|
||||
,'<span type="face" title="表情"><i class="iconfont icon-yxj-expression" style="top: 1px;"></i></span>'
|
||||
,'<span type="picture" title="图片:img[src]"><i class="iconfont icon-tupian"></i></span>'
|
||||
,'<span type="video" title="视频"><i class="layui-icon layui-icon-video"></i></span>'
|
||||
,'<span type="audio" title="音频"><i class="layui-icon layui-icon-headset"></i></span>'
|
||||
,'<span type="href" title="超链接格式:a(href)[text]"><i class="iconfont icon-lianjie"></i></span>'
|
||||
,'<span type="quote" title="引用"><i class="iconfont icon-yinyong" style="top: 1px;"></i></span>'
|
||||
,'<span type="code" title="插入代码" class="layui-hide-xs"><i class="iconfont icon-emwdaima" style="top: 1px;"></i></span>'
|
||||
,'<span type="hr" title="水平线">hr</span>'
|
||||
,'<span type="preview" title="预览"><i class="iconfont icon-yulan1"></i></span>'
|
||||
,'</div>'].join('');
|
||||
//简易编辑器 -移除 -2024/4/7
|
||||
|
||||
var closeTips = function(){
|
||||
layer.close(mod.face.index);
|
||||
};
|
||||
|
||||
var log = {}, mod = {
|
||||
//加粗
|
||||
strong: function(editor){
|
||||
var str = window.getSelection().toString();
|
||||
if(!str == ''){
|
||||
//var strB = '<b>'+ str + '</b>';
|
||||
layui.focusInsert(editor[0], '[strong]'+ str + '[/strong]');
|
||||
//console.log(str);
|
||||
// console.log(strB);
|
||||
}
|
||||
},
|
||||
face: function(editor, self){ //插入表情
|
||||
var str = '', ul, face = fly.faces;
|
||||
for(var key in face){
|
||||
str += '<li title="'+ key +'"><img src="'+ face[key] +'"></li>';
|
||||
}
|
||||
str = '<ul id="LAY-editface" class="layui-clear" style="margin: -10px 0 0 -1px;">'+ str +'</ul>';
|
||||
|
||||
layer.close(mod.face.index);
|
||||
mod.face.index = layer.tips(str, self, {
|
||||
tips: 3
|
||||
,time: 0
|
||||
,skin: 'layui-edit-face'
|
||||
,tipsMore: true
|
||||
});
|
||||
|
||||
$(document).off('click', closeTips).on('click', closeTips);
|
||||
|
||||
$('#LAY-editface li').on('click', function(){
|
||||
var title = $(this).attr('title') + ' ';
|
||||
layui.focusInsert(editor[0], 'face' + title);
|
||||
editor.trigger('keyup');
|
||||
});
|
||||
}
|
||||
,picture: function(editor){ //插入图片
|
||||
//判断登陆
|
||||
if(uid == -1){
|
||||
layer.msg('请登录再发图', {icon: 6}, function(){
|
||||
location.href = login;
|
||||
})
|
||||
return false;
|
||||
}
|
||||
|
||||
layer.open({
|
||||
type: 1
|
||||
,id: 'fly-jie-upload'
|
||||
,title: '插入图片'
|
||||
,area: 'auto'
|
||||
,shade: false
|
||||
//,area: '465px'
|
||||
,fixed: false
|
||||
,offset: [
|
||||
editor.offset().top - $(window).scrollTop() + 'px'
|
||||
,editor.offset().left + 'px'
|
||||
]
|
||||
,skin: 'layui-layer-border'
|
||||
,content: ['<ul class="layui-form layui-form-pane" style="margin: 20px;">'
|
||||
,'<li class="layui-form-item">'
|
||||
,'<label class="layui-form-label">URL</label>'
|
||||
,'<div class="layui-input-inline">'
|
||||
,'<input required name="image" placeholder="支持粘贴远程图片地址" value="" class="layui-input">'
|
||||
,'</div>'
|
||||
,'<button type="button" class="layui-btn layui-btn-primary" id="uploadImg"><i class="layui-icon"></i>上传图片</button>'
|
||||
,'</li>'
|
||||
,'<li class="layui-form-item" style="text-align: center;">'
|
||||
,'<button type="button" lay-submit lay-filter="uploadImages" class="layui-btn" id="img-button">确认</button>'
|
||||
,'</li>'
|
||||
,'</ul>'].join('')
|
||||
,success: function(layero, index){
|
||||
var image = layero.find('input[name="image"]');
|
||||
|
||||
//执行上传实例
|
||||
upload.render({
|
||||
elem: '#uploadImg'
|
||||
,accept: 'images'
|
||||
,acceptMime: 'image/*'
|
||||
,exts: 'jpg|png|gif|bmp|jpeg'
|
||||
,url: uploads
|
||||
,data: {type:'image'}
|
||||
,auto: false
|
||||
//,bindAction: '#img-button' //指向一个按钮触发上传
|
||||
//,field: 'image'
|
||||
,size: 10240
|
||||
,choose: function (obj) { //选择文件后的回调
|
||||
imgcom.uploads(obj);
|
||||
}
|
||||
,done: function(res){
|
||||
if(res.status == 0){
|
||||
//console.log(res.url);
|
||||
image.val(res.url);
|
||||
} else {
|
||||
layer.msg(res.msg, {icon: 5});
|
||||
}
|
||||
}
|
||||
,error: function(){
|
||||
layer.msg('系统错误,请联系管理员');
|
||||
}
|
||||
});
|
||||
|
||||
form.on('submit(uploadImages)', function(data){
|
||||
var field = data.field;
|
||||
if(!field.image) return image.focus();
|
||||
layui.focusInsert(editor[0], 'img['+ field.image + '] ');
|
||||
layer.close(index);
|
||||
editor.trigger('keyup');
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
,href: function(editor){ //超链接
|
||||
layer.prompt({
|
||||
title: '请输入合法链接'
|
||||
,shade: false
|
||||
,fixed: false
|
||||
,id: 'LAY_flyedit_href'
|
||||
,offset: [
|
||||
editor.offset().top - $(window).scrollTop() + 1 + 'px'
|
||||
,editor.offset().left + 1 + 'px'
|
||||
]
|
||||
}, function(val, index, elem){
|
||||
if(!/^http(s*):\/\/[\S]/.test(val)){
|
||||
layer.tips('请务必 http 或 https 开头', elem, {tips:1})
|
||||
return;
|
||||
}
|
||||
layui.focusInsert(editor[0], ' a('+ val +')['+ val + '] ');
|
||||
layer.close(index);
|
||||
editor.trigger('keyup');
|
||||
});
|
||||
}
|
||||
,quote: function(editor){ //引用
|
||||
layer.prompt({
|
||||
title: '请输入引用内容'
|
||||
,formType: 2
|
||||
,maxlength: 10000
|
||||
,shade: false
|
||||
,id: 'LAY_flyedit_quote'
|
||||
,offset: [
|
||||
editor.offset().top - $(window).scrollTop() + 1 + 'px'
|
||||
,editor.offset().left + 1 + 'px'
|
||||
]
|
||||
,area: ['300px', '100px']
|
||||
}, function(val, index, elem){
|
||||
layui.focusInsert(editor[0], '[quote]\n '+ val + '\n[/quote]\n');
|
||||
layer.close(index);
|
||||
editor.trigger('keyup');
|
||||
});
|
||||
}
|
||||
,code: function(editor){ //插入代码
|
||||
layer.prompt({
|
||||
title: '请贴入代码'
|
||||
,formType: 2
|
||||
,maxlength: 10000
|
||||
,shade: false
|
||||
,id: 'LAY_flyedit_code'
|
||||
,area: ['800px', '360px']
|
||||
}, function(val, index, elem){
|
||||
layui.focusInsert(editor[0], '[pre]\n'+ val + '\n[/pre]\n');
|
||||
layer.close(index);
|
||||
editor.trigger('keyup');
|
||||
});
|
||||
}
|
||||
,hr: function(editor){ //插入水平分割线
|
||||
layui.focusInsert(editor[0], '[hr]\n');
|
||||
editor.trigger('keyup');
|
||||
}
|
||||
,video: function(editor){ //插入视频
|
||||
//判断登陆
|
||||
if(uid == -1){
|
||||
layer.msg('请登录再发视频', {icon: 6}, function(){
|
||||
location.href = login;
|
||||
})
|
||||
return false;
|
||||
}
|
||||
layer.open({
|
||||
type: 1
|
||||
,id: 'fly-jie-video-upload'
|
||||
,title: '插入视频'
|
||||
,area: 'auto'
|
||||
,shade: false
|
||||
//,area: '465px'
|
||||
,fixed: false
|
||||
,offset: [
|
||||
editor.offset().top - $(window).scrollTop() + 'px'
|
||||
,editor.offset().left + 'px'
|
||||
]
|
||||
,skin: 'layui-layer-border'
|
||||
,content: ['<ul class="layui-form layui-form-pane" style="margin: 20px;">'
|
||||
,'<li class="layui-form-item">'
|
||||
,'<label class="layui-form-label">封面</label>'
|
||||
,'<div class="layui-input-inline">'
|
||||
,'<input type="text" required name="cover" placeholder="支持粘贴远程图片地址" value="" class="layui-input">'
|
||||
,'</div>'
|
||||
,'<button type="button" lay-type="image" class="layui-btn" id="video-img"><i class="layui-icon"></i>上传封图</button>'
|
||||
,'</li>'
|
||||
,'<li class="layui-form-item">'
|
||||
,'<label class="layui-form-label">URL</label>'
|
||||
,'<div class="layui-input-inline">'
|
||||
,'<input type="text" required name="video" placeholder="支持粘贴远程视频地址" value="" class="layui-input">'
|
||||
,'</div>'
|
||||
,'<button type="button" lay-type="video" class="layui-btn" id="layedit-video"><i class="layui-icon layui-icon-video"></i>上传视频</button>'
|
||||
,'</li>'
|
||||
,'<li class="layui-form-item" style="text-align: center;">'
|
||||
,'<button type="button" lay-submit lay-filter="uploadImages" class="layui-btn">确认</button>'
|
||||
,'</li>'
|
||||
,'</ul>'].join('')
|
||||
,success: function(layero, index){
|
||||
var video = layero.find('input[name="video"]'), cover = layero.find('input[name="cover"]');
|
||||
|
||||
//上传视频
|
||||
upload.render({
|
||||
url: uploads
|
||||
,data: {type:'video'}
|
||||
,accept: 'video'
|
||||
,acceptMime: 'video/mp4'
|
||||
,exts: 'mp4'
|
||||
,elem: '#layedit-video'
|
||||
,before: function(obj){ //obj参数包含的信息,跟 choose回调完全一致,可参见上文。
|
||||
layer.load(2); //上传loading
|
||||
}
|
||||
,done: function(res){
|
||||
if(res.status == 0){
|
||||
video.val(res.url);
|
||||
} else {
|
||||
layer.msg(res.msg, {icon: 5});
|
||||
}
|
||||
layer.closeAll('loading');
|
||||
}
|
||||
});
|
||||
//上传图片
|
||||
upload.render({
|
||||
elem: '#video-img'
|
||||
,accept: 'images'
|
||||
,acceptMime: 'image/*'
|
||||
,exts: 'jpg|png|gif|bmp|jpeg'
|
||||
,url: uploads
|
||||
,data: {type:'image'}
|
||||
,auto: false
|
||||
//,bindAction: '#img-button' //指向一个按钮触发上传
|
||||
//,field: 'image'
|
||||
,size: 10240
|
||||
,choose: function (obj) { //选择文件后的回调
|
||||
imgcom.uploads(obj);
|
||||
}
|
||||
,done: function(res){
|
||||
if(res.status == 0){
|
||||
cover.val(res.url);
|
||||
} else {
|
||||
layer.msg(res.msg, {icon: 5});
|
||||
}
|
||||
}
|
||||
,error: function(){
|
||||
layer.msg('系统错误,请联系管理员');
|
||||
}
|
||||
});
|
||||
form.on('submit(uploadImages)', function(data){
|
||||
var field = data.field;
|
||||
if(!field.video) return video.focus();
|
||||
layui.focusInsert(editor[0], 'video('+field.cover+')['+ field.video + '] ');
|
||||
layer.close(index);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
,audio: function(editor){ //插入音频
|
||||
//判断登陆
|
||||
if(uid == -1){
|
||||
layer.msg('请登录再发布', {icon: 6}, function(){
|
||||
location.href = login;
|
||||
})
|
||||
return false;
|
||||
}
|
||||
layer.open({
|
||||
type: 1
|
||||
,id: 'fly-jie-audio-upload'
|
||||
,title: '插入音频'
|
||||
,area: 'auto'
|
||||
,shade: false
|
||||
//,area: '465px'
|
||||
,fixed: false
|
||||
,offset: [
|
||||
editor.offset().top - $(window).scrollTop() + 'px'
|
||||
,editor.offset().left + 'px'
|
||||
]
|
||||
,skin: 'layui-layer-border'
|
||||
,content: ['<ul class="layui-form layui-form-pane" style="margin: 20px;">'
|
||||
,'<li class="layui-form-item">'
|
||||
,'<label class="layui-form-label">URL</label>'
|
||||
,'<div class="layui-input-inline">'
|
||||
,'<input required name="audio" placeholder="支持直接粘贴远程音频地址" value="" class="layui-input">'
|
||||
,'</div>'
|
||||
,'<button required type="button" name="file" lay-type="audio" class="layui-btn upload-audio"><i class="layui-icon layui-icon-headset"></i>上传音频</button>'
|
||||
,'</li>'
|
||||
,'<li class="layui-form-item" style="text-align: center;">'
|
||||
,'<button type="button" lay-submit lay-filter="uploadImages" class="layui-btn">确认</button>'
|
||||
,'</li>'
|
||||
,'</ul>'].join('')
|
||||
,success: function(layero, index){
|
||||
var loding,audio = layero.find('input[name="audio"]');
|
||||
|
||||
upload.render({
|
||||
url: uploads
|
||||
,data: {type:'audio'}
|
||||
,elem: '#fly-jie-audio-upload .upload-audio'
|
||||
,accept: 'audio'
|
||||
,acceptMime: 'audio/*'
|
||||
,exts: 'mp3|m4a'
|
||||
,before: function(obj){
|
||||
//loding = layer.msg('文件上传中,请稍等哦', { icon: 16 ,shade:0.3,time:0 });
|
||||
layer.load(2); //上传loading
|
||||
}
|
||||
,done: function(res){
|
||||
|
||||
if(res.status == 0){
|
||||
audio.val(res.url);
|
||||
} else {
|
||||
layer.msg(res.msg, {icon: 5});
|
||||
}
|
||||
layer.closeAll('loading');
|
||||
}
|
||||
});
|
||||
form.on('submit(uploadImages)', function(data){
|
||||
var field = data.field;
|
||||
if(!field.audio) return audio.focus();
|
||||
layui.focusInsert(editor[0], 'audio['+ field.audio + '] ');
|
||||
layer.close(index);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
,preview: function(editor, span){ //预览
|
||||
var othis = $(span), getContent = function(){
|
||||
var content = editor.val();
|
||||
return /^\{html\}/.test(content) ? content.replace(/^\{html\}/, '') : fly.content(content)
|
||||
}, isMobile = device.ios || device.android;
|
||||
|
||||
if(mod.preview.isOpen) return layer.close(mod.preview.index);
|
||||
|
||||
mod.preview.index = layer.open({
|
||||
type: 1
|
||||
,title: '预览'
|
||||
,shade: false
|
||||
,offset: 'r'
|
||||
,id: 'LAY_flyedit_preview'
|
||||
,area: [
|
||||
isMobile ? '100%' : '775px'
|
||||
,'100%'
|
||||
]
|
||||
,scrollbar: isMobile ? false : true
|
||||
,anim: -1
|
||||
,isOutAnim: false
|
||||
,content: '<div class="detail-body layui-text" style="margin:20px;">'+ getContent() +'</div>'
|
||||
,success: function(layero){
|
||||
editor.on('keyup', function(val){
|
||||
layero.find('.detail-body').html(getContent());
|
||||
});
|
||||
mod.preview.isOpen = true;
|
||||
othis.addClass('layui-this');
|
||||
}
|
||||
,end: function(){
|
||||
delete mod.preview.isOpen;
|
||||
othis.removeClass('layui-this');
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
layui.use('face', function(face){
|
||||
options = options || {};
|
||||
fly.faces = face;
|
||||
$(options.elem).each(function(index){
|
||||
var that = this, othis = $(that), parent = othis.parent();
|
||||
parent.prepend(html);
|
||||
parent.find('.fly-edit span').on('click', function(event){
|
||||
var type = $(this).attr('type');
|
||||
mod[type].call(that, othis, this);
|
||||
if(type === 'face'){
|
||||
event.stopPropagation()
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
,escape: function(html){
|
||||
return String(html||'').replace(/&(?!#?[a-zA-Z0-9]+;)/g, '&')
|
||||
.replace(/</g, '<').replace(/>/g, '>').replace(/'/g, ''').replace(/"/g, '"');
|
||||
}
|
||||
|
||||
//内容转义
|
||||
,content: function(content){
|
||||
var util = fly
|
||||
,item = fly.faces;
|
||||
|
||||
//支持的html标签
|
||||
var html = function(end){
|
||||
return new RegExp('\\n*\\|\\-'+ (end||'') +'(div|span|p|button|table|thead|th|tbody|tr|td|ul|li|ol|li|dl|dt|dd|h2|h3|h4|h5)([\\s\\S]*?)\\-\\|\\n*', 'g');
|
||||
};
|
||||
|
||||
|
||||
//XSS
|
||||
content = util.escape(content||'')
|
||||
|
||||
//转义图片
|
||||
.replace(/img\[([^\s]+?)\]/g, function(img){
|
||||
return '<div><img src="' + img.replace(/(^img\[)|(\]$)/g, '') + '"></div>';
|
||||
})
|
||||
|
||||
//转义@
|
||||
.replace(/@(\S+)(\s+?|$)/g, '@<a href="javascript:;" class="fly-aite">$1</a>$2')
|
||||
|
||||
//转义表情
|
||||
.replace(/face\[([^\s\[\]]+?)\]/g, function(face){
|
||||
var alt = face.replace(/^face/g, '');
|
||||
return '<img alt="'+ alt +'" title="'+ alt +'" src="' + item[alt] + '">';
|
||||
})
|
||||
|
||||
//转义脚本
|
||||
.replace(/a(\(javascript:)(.+)(;*\))/g, 'a(javascript:layer.msg(\'非法脚本\');)')
|
||||
|
||||
//转义链接
|
||||
.replace(/a\([\s\S]+?\)\[[\s\S]*?\]/g, function(str){
|
||||
var href = (str.match(/a\(([\s\S]+?)\)\[/)||[])[1];
|
||||
var text = (str.match(/\)\[([\s\S]*?)\]/)||[])[1];
|
||||
if(!href) return str;
|
||||
var rel = /^(http(s)*:\/\/)\b(?!(\w+\.)*(sentsin.com|layui.com))\b/.test(href.replace(/\s/g, ''));
|
||||
return '<a href="'+ href +'" style="color: red;" target="_blank"'+ (rel ? ' rel="nofollow"' : '') +'>'+ (text||href) +'</a>';
|
||||
})
|
||||
|
||||
//转义横线
|
||||
.replace(/\[hr\]\n*/g, '<hr>')
|
||||
|
||||
//转义表格
|
||||
.replace(/\[table\]([\s\S]*)\[\/table\]\n*/g, function(str){
|
||||
return str.replace(/\[(thead|th|tbody|tr|td)\]\n*/g, '<$1>')
|
||||
.replace(/\n*\[\/(thead|th|tbody|tr|td)\]\n*/g, '</$1>')
|
||||
|
||||
.replace(/\[table\]\n*/g, '<table class="layui-table">')
|
||||
.replace(/\n*\[\/table\]\n*/g, '</table>');
|
||||
})
|
||||
|
||||
//转义 div/span
|
||||
.replace(/\n*\[(div|span)([\s\S]*?)\]([\s\S]*?)\[\/(div|span)\]\n*/g, function(str){
|
||||
return str.replace(/\[(div|span)([\s\S]*?)\]\n*/g, '<$1 $2>')
|
||||
.replace(/\n*\[\/(div|span)\]\n*/g, '</$1>');
|
||||
})
|
||||
|
||||
//转义列表
|
||||
.replace(/\[ul\]([\s\S]*)\[\/ul\]\n*/g, function(str){
|
||||
return str.replace(/\[li\]\n*/g, '<li>')
|
||||
.replace(/\n*\[\/li\]\n*/g, '</li>')
|
||||
|
||||
.replace(/\[ul\]\n*/g, '<ul>')
|
||||
.replace(/\n*\[\/ul\]\n*/g, '</ul>');
|
||||
})
|
||||
|
||||
//转义代码
|
||||
.replace(/\[pre\]([\s\S]*)\[\/pre\]\n*/g, function(str){
|
||||
return str.replace(/\[pre\]\n*/g, '<pre>')
|
||||
.replace(/\n*\[\/pre\]\n*/g, '</pre>');
|
||||
})
|
||||
|
||||
//转义引用
|
||||
.replace(/\[quote\]([\s\S]*)\[\/quote\]\n*/g, function(str){
|
||||
return str.replace(/\[quote\]\n*/g, '<div class="layui-elem-quote">')
|
||||
.replace(/\n*\[\/quote\]\n*/g, '</div>');
|
||||
})
|
||||
|
||||
//转义加粗
|
||||
.replace(/\[strong\]([\s\S]*)\[\/strong\]\n*/g, function(str){
|
||||
return str.replace(/\[strong\]\n*/g,'<b>')
|
||||
.replace(/\n*\[\/strong\]\n*/g, '</b>');
|
||||
})
|
||||
|
||||
//转义换行
|
||||
.replace(/\n/g, '<br>')
|
||||
|
||||
//转义视频
|
||||
.replace(/video\(.*?\)\[([^\s]+?)\]/g, function(str){
|
||||
var cover = (str.match(/video\(([\s\S]+?)\)\[/)||[])[1];
|
||||
var video = (str.match(/\)\[([^\s]+?)\]/)||[])[1];
|
||||
cover = cover ? cover : '/static/res/images/video_cover.jpg';
|
||||
return '<video poster="'+ cover + '" controls crossorigin><source src="'+ video + '" type="video/mp4"></video>';
|
||||
})
|
||||
//转义音频
|
||||
.replace(/audio\[([^\s]+?)\]/g, function(audio){
|
||||
return '<audio controls><source src="'+ audio.replace(/(^audio\[)|(\]$)/g, '')+ '" type="audio/mp3"></audio>';
|
||||
})
|
||||
|
||||
return content;
|
||||
}
|
||||
|
||||
//新消息通知
|
||||
,newmsg: function(){
|
||||
var elemUser = $('.fly-nav-user');
|
||||
var messageNums = elemUser.attr('msg-url'),
|
||||
messageRead = elemUser.attr('readMsg-url');
|
||||
var messageNums = elemUser.attr('msg-url');
|
||||
var messageRead = elemUser.attr('readMsg-url');
|
||||
if(uid != -1 && elemUser[0]){
|
||||
fly.json(messageNums, {
|
||||
_: new Date().getTime()
|
||||
@ -699,26 +185,6 @@ layui.define(['layer', 'laytpl', 'form', 'element', 'upload', 'util', 'imgcom'],
|
||||
//签到
|
||||
|
||||
//活跃榜
|
||||
var tplReply = ['{{# layui.each(d.data, function(index, item){ }}'
|
||||
,'<dd>'
|
||||
,'<a href="{{item.uid}}">'
|
||||
,'<img src="{{item.user.avatar}}">'
|
||||
,'<cite>{{item.user.username}}</cite>'
|
||||
,'<i>{{item["count"]}}' + replyNum + '</i>'
|
||||
,'</a>'
|
||||
,'</dd>'
|
||||
,'{{# }); }}'].join('')
|
||||
,elemReply = $('#LAY_replyRank');
|
||||
|
||||
var replyUrl = elemReply.attr('data-url');
|
||||
if(elemReply[0]){
|
||||
fly.json(replyUrl, {
|
||||
limit: 20
|
||||
}, function(res){
|
||||
var html = laytpl(tplReply).render(res);
|
||||
elemReply.find('dl').html(html);
|
||||
});
|
||||
};
|
||||
|
||||
//相册
|
||||
if($(window).width() > 750){
|
||||
@ -833,9 +299,7 @@ layui.define(['layer', 'laytpl', 'form', 'element', 'upload', 'util', 'imgcom'],
|
||||
}
|
||||
|
||||
//加载编辑器
|
||||
fly.layEditor({
|
||||
elem: '.fly-editor'
|
||||
});
|
||||
|
||||
|
||||
//手机设备的简单适配 用户中心底部左侧栏导航
|
||||
var treeMobile = $('.site-tree-mobile')
|
||||
|
@ -33,18 +33,53 @@ layui.define(['laypage', 'fly', 'element', 'flow', 'imgcom'], function(exports){
|
||||
var post = table.render({
|
||||
elem: '#art-post'
|
||||
,url: artListUrl
|
||||
,toolbar: '#toolbarPost'
|
||||
,title: ''
|
||||
,cols: [[
|
||||
{type: 'numbers', fixed: 'left'}
|
||||
{type: 'checkbox', fixed: 'left'},
|
||||
{type: 'numbers', fixed: 'left', title: '序号'}
|
||||
,{field: 'title', title: '标题',minWidth: 250 ,templet: '<div><a href="{{d.url}}" target="_blank">{{-d.title}}</a></div>'}
|
||||
,{field: 'pv', title:'浏览 <i class="layui-icon layui-icon-tips layui-font-14" lay-event="pv-tips" title="该字段开启了编辑功能" style="margin-left: 5px;"></i>', fieldTitle: 'pv', hide: 0, width:100, expandedMode: 'tips', edit: 'text'}
|
||||
,{field: 'status', title: '状态', width: 80}
|
||||
,{field: 'ctime', title: '时间', width: 120}
|
||||
,{field: 'datas', title: '数据', width: 120}
|
||||
,{field: 'ctime', title: '发布时间', width: 160}
|
||||
,{field: 'utime', title: '更新时间', width:160}
|
||||
,{field: 'datas', title: '数据', width: 80}
|
||||
,{title: '操作', width: 150, align: 'center', toolbar: '#artTool'}
|
||||
]]
|
||||
,text: '对不起,加载出现异常!'
|
||||
,page: true
|
||||
});
|
||||
|
||||
// 工具栏事件
|
||||
table.on('toolbar(art-post)', function(obj){
|
||||
var id = obj.config.id;
|
||||
var checkStatus = table.checkStatus(id);
|
||||
var othis = lay(this);
|
||||
switch(obj.event){
|
||||
case 'getCheckData':
|
||||
var data = checkStatus.data;
|
||||
// layer.alert(layui.util.escape(JSON.stringify(data)));
|
||||
$.post(updateTime,{"data":data},function(res){
|
||||
if(res.code === 0){
|
||||
layer.msg(res.msg,{icon:6,time:2000});
|
||||
table.reload('art-post')
|
||||
} else {
|
||||
layer.open({title:'刷新失败',content:res.msg,icon:5,adim:6})
|
||||
}
|
||||
}
|
||||
);
|
||||
break;
|
||||
case 'getData':
|
||||
var getData = table.getData(id);
|
||||
console.log(getData);
|
||||
layer.alert(layui.util.escape(JSON.stringify(getData)));
|
||||
break;
|
||||
case 'LAYTABLE_TIPS':
|
||||
layer.alert('自定义工具栏图标按钮');
|
||||
break;
|
||||
};
|
||||
return false
|
||||
});
|
||||
|
||||
//收藏list
|
||||
table.render({
|
||||
@ -62,6 +97,44 @@ layui.define(['laypage', 'fly', 'element', 'flow', 'imgcom'], function(exports){
|
||||
,text: '对不起,加载出现异常!'
|
||||
,page: true
|
||||
});
|
||||
|
||||
// 单元格编辑事件
|
||||
table.on('edit(art-post)', function(obj){
|
||||
var field = obj.field; // 得到字段
|
||||
var value = obj.value; // 得到修改后的值
|
||||
var data = obj.data; // 得到所在行所有键值
|
||||
|
||||
// 值的校验
|
||||
if(field === 'email'){
|
||||
if(!/^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/.test(obj.value)){
|
||||
layer.tips('输入的邮箱格式不正确,请重新编辑', this, {tips: 1});
|
||||
return obj.reedit(); // 重新编辑 -- v2.8.0 新增
|
||||
}
|
||||
}
|
||||
|
||||
// 编辑后续操作,如提交更新请求,以完成真实的数据更新
|
||||
$.ajax({
|
||||
type: "post",
|
||||
url: pvEdit,
|
||||
data: data,
|
||||
dataType: 'json',
|
||||
success: (res) => {
|
||||
if(res.code === 0) {
|
||||
layer.msg(res.msg, {icon: 1});
|
||||
} else {
|
||||
layer.msg(res.msg, {icon: 2});
|
||||
return false;
|
||||
}
|
||||
}
|
||||
})
|
||||
// …
|
||||
|
||||
// 其他更新操作
|
||||
var update = {};
|
||||
update[field] = value;
|
||||
obj.update(update);
|
||||
});
|
||||
|
||||
|
||||
//监听行工具事件
|
||||
table.on('tool(art-post)', function(obj){
|
||||
|
4
vendor/composer/autoload_files.php
vendored
4
vendor/composer/autoload_files.php
vendored
@ -9,15 +9,13 @@ return array(
|
||||
'9b552a3cc426e3287cc811caefa3cf53' => $vendorDir . '/topthink/think-helper/src/helper.php',
|
||||
'35fab96057f1bf5e7aba31a8a6d5fdde' => $vendorDir . '/topthink/think-orm/stubs/load_stubs.php',
|
||||
'7b11c4dc42b3b3023073cb14e519683c' => $vendorDir . '/ralouphie/getallheaders/src/getallheaders.php',
|
||||
'a4a119a56e50fbb293281d9a48007e0e' => $vendorDir . '/symfony/polyfill-php80/bootstrap.php',
|
||||
'c964ee0ededf28c96ebd9db5099ef910' => $vendorDir . '/guzzlehttp/promises/src/functions_include.php',
|
||||
'a0edc8309cc5e1d60e3047b5df6b7052' => $vendorDir . '/guzzlehttp/psr7/src/functions_include.php',
|
||||
'37a3dc5111fe8f707ab4c132ef1dbc62' => $vendorDir . '/guzzlehttp/guzzle/src/functions_include.php',
|
||||
'a4a119a56e50fbb293281d9a48007e0e' => $vendorDir . '/symfony/polyfill-php80/bootstrap.php',
|
||||
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php',
|
||||
'25072dd6e2470089de65ae7bf11d3109' => $vendorDir . '/symfony/polyfill-php72/bootstrap.php',
|
||||
'667aeda72477189d0494fecd327c3641' => $vendorDir . '/symfony/var-dumper/Resources/functions/dump.php',
|
||||
'fe62ba7e10580d903cc46d808b5961a4' => $vendorDir . '/tightenco/collect/src/Collect/Support/helpers.php',
|
||||
'caf31cc6ec7cf2241cb6f12c226c3846' => $vendorDir . '/tightenco/collect/src/Collect/Support/alias.php',
|
||||
'6b998e7ad3182c0d21d23780badfa07b' => $vendorDir . '/yansongda/supports/src/Functions.php',
|
||||
'b33e3d135e5d9e47d845c576147bda89' => $vendorDir . '/php-di/php-di/src/functions.php',
|
||||
'223fa6f9b46fbe5d6b44c5ff847bfceb' => $vendorDir . '/taoser/think-addons/src/helper.php',
|
||||
|
9
vendor/composer/autoload_psr4.php
vendored
9
vendor/composer/autoload_psr4.php
vendored
@ -7,23 +7,20 @@ $baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
'yzh52521\\EasyHttp\\' => array($vendorDir . '/yzh52521/easyhttp/src'),
|
||||
'wamkj\\thinkphp\\' => array($vendorDir . '/wamkj/thinkphp6.0-databackup/src'),
|
||||
'think\\view\\driver\\' => array($vendorDir . '/topthink/think-view/src'),
|
||||
'think\\trace\\' => array($vendorDir . '/topthink/think-trace/src'),
|
||||
'think\\migration\\' => array($vendorDir . '/topthink/think-migration/src'),
|
||||
'think\\composer\\' => array($vendorDir . '/topthink/think-installer/src'),
|
||||
'think\\captcha\\' => array($vendorDir . '/topthink/think-captcha/src'),
|
||||
'think\\app\\' => array($vendorDir . '/topthink/think-multi-app/src'),
|
||||
'think\\' => array($vendorDir . '/topthink/think-helper/src', $vendorDir . '/topthink/think-orm/src', $vendorDir . '/topthink/think-template/src', $vendorDir . '/topthink/framework/src/think'),
|
||||
'think\\' => array($vendorDir . '/topthink/framework/src/think', $vendorDir . '/topthink/think-helper/src', $vendorDir . '/topthink/think-orm/src', $vendorDir . '/topthink/think-template/src'),
|
||||
'taoser\\think\\' => array($vendorDir . '/taoser/think-auth/src'),
|
||||
'taoser\\' => array($vendorDir . '/taoser/think-addons/src', $vendorDir . '/taoser/think-setarr/src'),
|
||||
'phpspirit\\databackup\\' => array($vendorDir . '/lotofbadcode/phpspirit_databackup/src'),
|
||||
'liliuwei\\social\\' => array($vendorDir . '/liliuwei/thinkphp-social/src'),
|
||||
'app\\' => array($baseDir . '/app'),
|
||||
'Yansongda\\Supports\\' => array($vendorDir . '/yansongda/supports/src'),
|
||||
'Yansongda\\Pay\\' => array($vendorDir . '/yansongda/pay/src'),
|
||||
'Workerman\\' => array($vendorDir . '/workerman/workerman'),
|
||||
'Tightenco\\Collect\\' => array($vendorDir . '/tightenco/collect/src/Collect'),
|
||||
'Symfony\\Polyfill\\Php80\\' => array($vendorDir . '/symfony/polyfill-php80'),
|
||||
'Symfony\\Polyfill\\Php72\\' => array($vendorDir . '/symfony/polyfill-php72'),
|
||||
'Symfony\\Polyfill\\Mbstring\\' => array($vendorDir . '/symfony/polyfill-mbstring'),
|
||||
@ -38,9 +35,10 @@ return array(
|
||||
'Psr\\Container\\' => array($vendorDir . '/psr/container/src'),
|
||||
'Psr\\Cache\\' => array($vendorDir . '/psr/cache/src'),
|
||||
'PhpDocReader\\' => array($vendorDir . '/php-di/phpdoc-reader/src/PhpDocReader'),
|
||||
'Phinx\\' => array($vendorDir . '/topthink/think-migration/phinx/src/Phinx'),
|
||||
'Phinx\\' => array($vendorDir . '/topthink/think-migration/phinx'),
|
||||
'PHPSocketIO\\' => array($vendorDir . '/workerman/phpsocket.io/src'),
|
||||
'PHPMailer\\PHPMailer\\' => array($vendorDir . '/phpmailer/phpmailer/src'),
|
||||
'Overtrue\\EasySms\\' => array($vendorDir . '/overtrue/easy-sms/src'),
|
||||
'League\\MimeTypeDetection\\' => array($vendorDir . '/league/mime-type-detection/src'),
|
||||
'League\\Flysystem\\' => array($vendorDir . '/league/flysystem/src'),
|
||||
'Laravel\\SerializableClosure\\' => array($vendorDir . '/laravel/serializable-closure/src'),
|
||||
@ -49,6 +47,7 @@ return array(
|
||||
'GuzzleHttp\\Psr7\\' => array($vendorDir . '/guzzlehttp/psr7/src'),
|
||||
'GuzzleHttp\\Promise\\' => array($vendorDir . '/guzzlehttp/promises/src'),
|
||||
'GuzzleHttp\\' => array($vendorDir . '/guzzlehttp/guzzle/src'),
|
||||
'Firebase\\JWT\\' => array($vendorDir . '/firebase/php-jwt/src'),
|
||||
'Endroid\\QrCode\\' => array($vendorDir . '/endroid/qr-code/src'),
|
||||
'DI\\' => array($vendorDir . '/php-di/php-di/src'),
|
||||
'DASPRiD\\Enum\\' => array($vendorDir . '/dasprid/enum/src'),
|
||||
|
54
vendor/composer/autoload_static.php
vendored
54
vendor/composer/autoload_static.php
vendored
@ -10,15 +10,13 @@ class ComposerStaticInit1b32198725235c8d6500c87262ef30c2
|
||||
'9b552a3cc426e3287cc811caefa3cf53' => __DIR__ . '/..' . '/topthink/think-helper/src/helper.php',
|
||||
'35fab96057f1bf5e7aba31a8a6d5fdde' => __DIR__ . '/..' . '/topthink/think-orm/stubs/load_stubs.php',
|
||||
'7b11c4dc42b3b3023073cb14e519683c' => __DIR__ . '/..' . '/ralouphie/getallheaders/src/getallheaders.php',
|
||||
'a4a119a56e50fbb293281d9a48007e0e' => __DIR__ . '/..' . '/symfony/polyfill-php80/bootstrap.php',
|
||||
'c964ee0ededf28c96ebd9db5099ef910' => __DIR__ . '/..' . '/guzzlehttp/promises/src/functions_include.php',
|
||||
'a0edc8309cc5e1d60e3047b5df6b7052' => __DIR__ . '/..' . '/guzzlehttp/psr7/src/functions_include.php',
|
||||
'37a3dc5111fe8f707ab4c132ef1dbc62' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/functions_include.php',
|
||||
'a4a119a56e50fbb293281d9a48007e0e' => __DIR__ . '/..' . '/symfony/polyfill-php80/bootstrap.php',
|
||||
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php',
|
||||
'25072dd6e2470089de65ae7bf11d3109' => __DIR__ . '/..' . '/symfony/polyfill-php72/bootstrap.php',
|
||||
'667aeda72477189d0494fecd327c3641' => __DIR__ . '/..' . '/symfony/var-dumper/Resources/functions/dump.php',
|
||||
'fe62ba7e10580d903cc46d808b5961a4' => __DIR__ . '/..' . '/tightenco/collect/src/Collect/Support/helpers.php',
|
||||
'caf31cc6ec7cf2241cb6f12c226c3846' => __DIR__ . '/..' . '/tightenco/collect/src/Collect/Support/alias.php',
|
||||
'6b998e7ad3182c0d21d23780badfa07b' => __DIR__ . '/..' . '/yansongda/supports/src/Functions.php',
|
||||
'b33e3d135e5d9e47d845c576147bda89' => __DIR__ . '/..' . '/php-di/php-di/src/functions.php',
|
||||
'223fa6f9b46fbe5d6b44c5ff847bfceb' => __DIR__ . '/..' . '/taoser/think-addons/src/helper.php',
|
||||
@ -32,10 +30,6 @@ class ComposerStaticInit1b32198725235c8d6500c87262ef30c2
|
||||
array (
|
||||
'yzh52521\\EasyHttp\\' => 18,
|
||||
),
|
||||
'w' =>
|
||||
array (
|
||||
'wamkj\\thinkphp\\' => 15,
|
||||
),
|
||||
't' =>
|
||||
array (
|
||||
'think\\view\\driver\\' => 18,
|
||||
@ -48,10 +42,6 @@ class ComposerStaticInit1b32198725235c8d6500c87262ef30c2
|
||||
'taoser\\think\\' => 13,
|
||||
'taoser\\' => 7,
|
||||
),
|
||||
'p' =>
|
||||
array (
|
||||
'phpspirit\\databackup\\' => 21,
|
||||
),
|
||||
'l' =>
|
||||
array (
|
||||
'liliuwei\\social\\' => 16,
|
||||
@ -69,10 +59,6 @@ class ComposerStaticInit1b32198725235c8d6500c87262ef30c2
|
||||
array (
|
||||
'Workerman\\' => 10,
|
||||
),
|
||||
'T' =>
|
||||
array (
|
||||
'Tightenco\\Collect\\' => 18,
|
||||
),
|
||||
'S' =>
|
||||
array (
|
||||
'Symfony\\Polyfill\\Php80\\' => 23,
|
||||
@ -99,6 +85,10 @@ class ComposerStaticInit1b32198725235c8d6500c87262ef30c2
|
||||
'PHPSocketIO\\' => 12,
|
||||
'PHPMailer\\PHPMailer\\' => 20,
|
||||
),
|
||||
'O' =>
|
||||
array (
|
||||
'Overtrue\\EasySms\\' => 17,
|
||||
),
|
||||
'L' =>
|
||||
array (
|
||||
'League\\MimeTypeDetection\\' => 25,
|
||||
@ -119,6 +109,10 @@ class ComposerStaticInit1b32198725235c8d6500c87262ef30c2
|
||||
'GuzzleHttp\\Promise\\' => 19,
|
||||
'GuzzleHttp\\' => 11,
|
||||
),
|
||||
'F' =>
|
||||
array (
|
||||
'Firebase\\JWT\\' => 13,
|
||||
),
|
||||
'E' =>
|
||||
array (
|
||||
'Endroid\\QrCode\\' => 15,
|
||||
@ -146,10 +140,6 @@ class ComposerStaticInit1b32198725235c8d6500c87262ef30c2
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/yzh52521/easyhttp/src',
|
||||
),
|
||||
'wamkj\\thinkphp\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/wamkj/thinkphp6.0-databackup/src',
|
||||
),
|
||||
'think\\view\\driver\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/topthink/think-view/src',
|
||||
@ -176,10 +166,10 @@ class ComposerStaticInit1b32198725235c8d6500c87262ef30c2
|
||||
),
|
||||
'think\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/topthink/think-helper/src',
|
||||
1 => __DIR__ . '/..' . '/topthink/think-orm/src',
|
||||
2 => __DIR__ . '/..' . '/topthink/think-template/src',
|
||||
3 => __DIR__ . '/..' . '/topthink/framework/src/think',
|
||||
0 => __DIR__ . '/..' . '/topthink/framework/src/think',
|
||||
1 => __DIR__ . '/..' . '/topthink/think-helper/src',
|
||||
2 => __DIR__ . '/..' . '/topthink/think-orm/src',
|
||||
3 => __DIR__ . '/..' . '/topthink/think-template/src',
|
||||
),
|
||||
'taoser\\think\\' =>
|
||||
array (
|
||||
@ -190,10 +180,6 @@ class ComposerStaticInit1b32198725235c8d6500c87262ef30c2
|
||||
0 => __DIR__ . '/..' . '/taoser/think-addons/src',
|
||||
1 => __DIR__ . '/..' . '/taoser/think-setarr/src',
|
||||
),
|
||||
'phpspirit\\databackup\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/lotofbadcode/phpspirit_databackup/src',
|
||||
),
|
||||
'liliuwei\\social\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/liliuwei/thinkphp-social/src',
|
||||
@ -214,10 +200,6 @@ class ComposerStaticInit1b32198725235c8d6500c87262ef30c2
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/workerman/workerman',
|
||||
),
|
||||
'Tightenco\\Collect\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/tightenco/collect/src/Collect',
|
||||
),
|
||||
'Symfony\\Polyfill\\Php80\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/symfony/polyfill-php80',
|
||||
@ -276,7 +258,7 @@ class ComposerStaticInit1b32198725235c8d6500c87262ef30c2
|
||||
),
|
||||
'Phinx\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/topthink/think-migration/phinx/src/Phinx',
|
||||
0 => __DIR__ . '/..' . '/topthink/think-migration/phinx',
|
||||
),
|
||||
'PHPSocketIO\\' =>
|
||||
array (
|
||||
@ -286,6 +268,10 @@ class ComposerStaticInit1b32198725235c8d6500c87262ef30c2
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/phpmailer/phpmailer/src',
|
||||
),
|
||||
'Overtrue\\EasySms\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/overtrue/easy-sms/src',
|
||||
),
|
||||
'League\\MimeTypeDetection\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/league/mime-type-detection/src',
|
||||
@ -318,6 +304,10 @@ class ComposerStaticInit1b32198725235c8d6500c87262ef30c2
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/guzzlehttp/guzzle/src',
|
||||
),
|
||||
'Firebase\\JWT\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/firebase/php-jwt/src',
|
||||
),
|
||||
'Endroid\\QrCode\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/endroid/qr-code/src',
|
||||
|
539
vendor/composer/installed.json
vendored
539
vendor/composer/installed.json
vendored
@ -269,24 +269,18 @@
|
||||
},
|
||||
{
|
||||
"name": "dasprid/enum",
|
||||
"version": "1.0.4",
|
||||
"version_normalized": "1.0.4.0",
|
||||
"version": "1.0.5",
|
||||
"version_normalized": "1.0.5.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/DASPRiD/Enum.git",
|
||||
"reference": "8e6b6ea76eabbf19ea2bf5b67b98e1860474012f"
|
||||
"reference": "6faf451159fb8ba4126b925ed2d78acfce0dc016"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/DASPRiD/Enum/zipball/8e6b6ea76eabbf19ea2bf5b67b98e1860474012f",
|
||||
"reference": "8e6b6ea76eabbf19ea2bf5b67b98e1860474012f",
|
||||
"shasum": "",
|
||||
"mirrors": [
|
||||
{
|
||||
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
|
||||
"preferred": true
|
||||
}
|
||||
]
|
||||
"url": "https://api.github.com/repos/DASPRiD/Enum/zipball/6faf451159fb8ba4126b925ed2d78acfce0dc016",
|
||||
"reference": "6faf451159fb8ba4126b925ed2d78acfce0dc016",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.1 <9.0"
|
||||
@ -295,7 +289,7 @@
|
||||
"phpunit/phpunit": "^7 | ^8 | ^9",
|
||||
"squizlabs/php_codesniffer": "*"
|
||||
},
|
||||
"time": "2023-03-01T18:44:03+00:00",
|
||||
"time": "2023-08-25T16:18:39+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
@ -322,7 +316,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/DASPRiD/Enum/issues",
|
||||
"source": "https://github.com/DASPRiD/Enum/tree/1.0.4"
|
||||
"source": "https://github.com/DASPRiD/Enum/tree/1.0.5"
|
||||
},
|
||||
"install-path": "../dasprid/enum"
|
||||
},
|
||||
@ -401,6 +395,72 @@
|
||||
],
|
||||
"install-path": "../endroid/qr-code"
|
||||
},
|
||||
{
|
||||
"name": "firebase/php-jwt",
|
||||
"version": "v6.10.0",
|
||||
"version_normalized": "6.10.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/firebase/php-jwt.git",
|
||||
"reference": "a49db6f0a5033aef5143295342f1c95521b075ff"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/firebase/php-jwt/zipball/a49db6f0a5033aef5143295342f1c95521b075ff",
|
||||
"reference": "a49db6f0a5033aef5143295342f1c95521b075ff",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.4||^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"guzzlehttp/guzzle": "^6.5||^7.4",
|
||||
"phpspec/prophecy-phpunit": "^2.0",
|
||||
"phpunit/phpunit": "^9.5",
|
||||
"psr/cache": "^1.0||^2.0",
|
||||
"psr/http-client": "^1.0",
|
||||
"psr/http-factory": "^1.0"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-sodium": "Support EdDSA (Ed25519) signatures",
|
||||
"paragonie/sodium_compat": "Support EdDSA (Ed25519) signatures when libsodium is not present"
|
||||
},
|
||||
"time": "2023-12-01T16:26:39+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Firebase\\JWT\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD-3-Clause"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Neuman Vong",
|
||||
"email": "neuman+pear@twilio.com",
|
||||
"role": "Developer"
|
||||
},
|
||||
{
|
||||
"name": "Anant Narayanan",
|
||||
"email": "anant@php.net",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"description": "A simple library to encode and decode JSON Web Tokens (JWT) in PHP. Should conform to the current spec.",
|
||||
"homepage": "https://github.com/firebase/php-jwt",
|
||||
"keywords": [
|
||||
"jwt",
|
||||
"php"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/firebase/php-jwt/issues",
|
||||
"source": "https://github.com/firebase/php-jwt/tree/v6.10.0"
|
||||
},
|
||||
"install-path": "../firebase/php-jwt"
|
||||
},
|
||||
{
|
||||
"name": "guzzlehttp/guzzle",
|
||||
"version": "7.0.0",
|
||||
@ -693,24 +753,24 @@
|
||||
},
|
||||
{
|
||||
"name": "jaeger/g-http",
|
||||
"version": "V1.7.2",
|
||||
"version_normalized": "1.7.2.0",
|
||||
"version": "V1.7.3",
|
||||
"version_normalized": "1.7.3.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/jae-jae/GHttp.git",
|
||||
"reference": "82585ddd5e2c6651e37ab1d8166efcdbb6b293d4"
|
||||
"reference": "035fe0ff6e3e0390769647ce14694875bf02cf22"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/jae-jae/GHttp/zipball/82585ddd5e2c6651e37ab1d8166efcdbb6b293d4",
|
||||
"reference": "82585ddd5e2c6651e37ab1d8166efcdbb6b293d4",
|
||||
"url": "https://api.github.com/repos/jae-jae/GHttp/zipball/035fe0ff6e3e0390769647ce14694875bf02cf22",
|
||||
"reference": "035fe0ff6e3e0390769647ce14694875bf02cf22",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"cache/filesystem-adapter": "^1",
|
||||
"guzzlehttp/guzzle": "^6.0 | ^7.0"
|
||||
"guzzlehttp/guzzle": "^6.0 || ^7.0"
|
||||
},
|
||||
"time": "2021-08-08T04:59:44+00:00",
|
||||
"time": "2024-03-24T14:55:49+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
@ -731,7 +791,7 @@
|
||||
"description": "Simple Http client base on GuzzleHttp",
|
||||
"support": {
|
||||
"issues": "https://github.com/jae-jae/GHttp/issues",
|
||||
"source": "https://github.com/jae-jae/GHttp/tree/V1.7.2"
|
||||
"source": "https://github.com/jae-jae/GHttp/tree/V1.7.3"
|
||||
},
|
||||
"install-path": "../jaeger/g-http"
|
||||
},
|
||||
@ -787,17 +847,17 @@
|
||||
},
|
||||
{
|
||||
"name": "jaeger/querylist",
|
||||
"version": "V4.2.8",
|
||||
"version_normalized": "4.2.8.0",
|
||||
"version": "V4.2.9",
|
||||
"version_normalized": "4.2.9.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/jae-jae/QueryList.git",
|
||||
"reference": "39dc0ca9c668bec7a793e20472ccd7d26ef89ea4"
|
||||
"reference": "7aae3aed38214d3d7096174faf49f6c41b2dd550"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/jae-jae/QueryList/zipball/39dc0ca9c668bec7a793e20472ccd7d26ef89ea4",
|
||||
"reference": "39dc0ca9c668bec7a793e20472ccd7d26ef89ea4",
|
||||
"url": "https://api.github.com/repos/jae-jae/QueryList/zipball/7aae3aed38214d3d7096174faf49f6c41b2dd550",
|
||||
"reference": "7aae3aed38214d3d7096174faf49f6c41b2dd550",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -805,13 +865,12 @@
|
||||
"jaeger/g-http": "^1.1",
|
||||
"jaeger/phpquery-single": "^1",
|
||||
"php": ">=7.1",
|
||||
"tightenco/collect": ">5.0"
|
||||
"symfony/var-dumper": ">3.4"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^8.5",
|
||||
"symfony/var-dumper": "^3.3"
|
||||
"phpunit/phpunit": "^8.5"
|
||||
},
|
||||
"time": "2021-07-05T06:07:58+00:00",
|
||||
"time": "2024-04-12T06:29:50+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
@ -838,7 +897,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/jae-jae/QueryList/issues",
|
||||
"source": "https://github.com/jae-jae/QueryList/tree/V4.2.8"
|
||||
"source": "https://github.com/jae-jae/QueryList/tree/V4.2.9"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -850,17 +909,17 @@
|
||||
},
|
||||
{
|
||||
"name": "laravel/serializable-closure",
|
||||
"version": "v1.3.1",
|
||||
"version_normalized": "1.3.1.0",
|
||||
"version": "v1.3.3",
|
||||
"version_normalized": "1.3.3.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/laravel/serializable-closure.git",
|
||||
"reference": "e5a3057a5591e1cfe8183034b0203921abe2c902"
|
||||
"reference": "3dbf8a8e914634c48d389c1234552666b3d43754"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/laravel/serializable-closure/zipball/e5a3057a5591e1cfe8183034b0203921abe2c902",
|
||||
"reference": "e5a3057a5591e1cfe8183034b0203921abe2c902",
|
||||
"url": "https://api.github.com/repos/laravel/serializable-closure/zipball/3dbf8a8e914634c48d389c1234552666b3d43754",
|
||||
"reference": "3dbf8a8e914634c48d389c1234552666b3d43754",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -872,7 +931,7 @@
|
||||
"phpstan/phpstan": "^1.8.2",
|
||||
"symfony/var-dumper": "^5.4.11"
|
||||
},
|
||||
"time": "2023-07-14T13:56:28+00:00",
|
||||
"time": "2023-11-08T14:08:06+00:00",
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
@ -1016,29 +1075,29 @@
|
||||
},
|
||||
{
|
||||
"name": "league/mime-type-detection",
|
||||
"version": "1.11.0",
|
||||
"version_normalized": "1.11.0.0",
|
||||
"version": "1.15.0",
|
||||
"version_normalized": "1.15.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/thephpleague/mime-type-detection.git",
|
||||
"reference": "ff6248ea87a9f116e78edd6002e39e5128a0d4dd"
|
||||
"reference": "ce0f4d1e8a6f4eb0ddff33f57c69c50fd09f4301"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/thephpleague/mime-type-detection/zipball/ff6248ea87a9f116e78edd6002e39e5128a0d4dd",
|
||||
"reference": "ff6248ea87a9f116e78edd6002e39e5128a0d4dd",
|
||||
"url": "https://api.github.com/repos/thephpleague/mime-type-detection/zipball/ce0f4d1e8a6f4eb0ddff33f57c69c50fd09f4301",
|
||||
"reference": "ce0f4d1e8a6f4eb0ddff33f57c69c50fd09f4301",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-fileinfo": "*",
|
||||
"php": "^7.2 || ^8.0"
|
||||
"php": "^7.4 || ^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"friendsofphp/php-cs-fixer": "^3.2",
|
||||
"phpstan/phpstan": "^0.12.68",
|
||||
"phpunit/phpunit": "^8.5.8 || ^9.3"
|
||||
"phpunit/phpunit": "^8.5.8 || ^9.3 || ^10.0"
|
||||
},
|
||||
"time": "2022-04-17T13:12:02+00:00",
|
||||
"time": "2024-01-28T23:22:08+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
@ -1059,7 +1118,7 @@
|
||||
"description": "Mime-type detection for Flysystem",
|
||||
"support": {
|
||||
"issues": "https://github.com/thephpleague/mime-type-detection/issues",
|
||||
"source": "https://github.com/thephpleague/mime-type-detection/tree/1.11.0"
|
||||
"source": "https://github.com/thephpleague/mime-type-detection/tree/1.15.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -1158,71 +1217,87 @@
|
||||
"install-path": "../liliuwei/thinkphp-social"
|
||||
},
|
||||
{
|
||||
"name": "lotofbadcode/phpspirit_databackup",
|
||||
"version": "v1.2",
|
||||
"version_normalized": "1.2.0.0",
|
||||
"name": "overtrue/easy-sms",
|
||||
"version": "2.6.0",
|
||||
"version_normalized": "2.6.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/lotofbadcode/phpspirit_databackup.git",
|
||||
"reference": "77c2421f8461392c044cf8c29918f495c22a5612"
|
||||
"url": "https://github.com/overtrue/easy-sms.git",
|
||||
"reference": "bb88b244f0de8d1f74bc50c4c08414f4c5f30281"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/lotofbadcode/phpspirit_databackup/zipball/77c2421f8461392c044cf8c29918f495c22a5612",
|
||||
"reference": "77c2421f8461392c044cf8c29918f495c22a5612",
|
||||
"shasum": "",
|
||||
"mirrors": [
|
||||
{
|
||||
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
|
||||
"preferred": true
|
||||
}
|
||||
]
|
||||
"url": "https://api.github.com/repos/overtrue/easy-sms/zipball/bb88b244f0de8d1f74bc50c4c08414f4c5f30281",
|
||||
"reference": "bb88b244f0de8d1f74bc50c4c08414f4c5f30281",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.0"
|
||||
"ext-json": "*",
|
||||
"guzzlehttp/guzzle": "^6.2 || ^7.0",
|
||||
"php": ">=5.6"
|
||||
},
|
||||
"time": "2023-05-12T12:02:05+00:00",
|
||||
"require-dev": {
|
||||
"brainmaestro/composer-git-hooks": "^2.8",
|
||||
"jetbrains/phpstorm-attributes": "^1.0",
|
||||
"mockery/mockery": "~1.3.3 || ^1.4.2",
|
||||
"phpunit/phpunit": "^5.7 || ^7.5 || ^8.5.19 || ^9.5.8"
|
||||
},
|
||||
"time": "2024-03-08T06:36:45+00:00",
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"hooks": {
|
||||
"pre-commit": [
|
||||
"composer check-style",
|
||||
"composer psalm",
|
||||
"composer test"
|
||||
],
|
||||
"pre-push": [
|
||||
"composer check-style"
|
||||
]
|
||||
}
|
||||
},
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"phpspirit\\databackup\\": "src/"
|
||||
"Overtrue\\EasySms\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"Apache-2.0"
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "代码庸医",
|
||||
"email": "3359964266@qq.com"
|
||||
"name": "overtrue",
|
||||
"email": "i@overtrue.me"
|
||||
}
|
||||
],
|
||||
"description": "一个PHP数据库备份恢复的插件",
|
||||
"keywords": [
|
||||
"library",
|
||||
"php"
|
||||
],
|
||||
"description": "The easiest way to send short message.",
|
||||
"support": {
|
||||
"issues": "https://github.com/lotofbadcode/phpspirit_databackup/issues",
|
||||
"source": "https://github.com/lotofbadcode/phpspirit_databackup/tree/v1.2"
|
||||
"issues": "https://github.com/overtrue/easy-sms/issues",
|
||||
"source": "https://github.com/overtrue/easy-sms/tree/2.6.0"
|
||||
},
|
||||
"install-path": "../lotofbadcode/phpspirit_databackup"
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://github.com/overtrue",
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"install-path": "../overtrue/easy-sms"
|
||||
},
|
||||
{
|
||||
"name": "php-di/invoker",
|
||||
"version": "2.3.3",
|
||||
"version_normalized": "2.3.3.0",
|
||||
"version": "2.3.4",
|
||||
"version_normalized": "2.3.4.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/PHP-DI/Invoker.git",
|
||||
"reference": "cd6d9f267d1a3474bdddf1be1da079f01b942786"
|
||||
"reference": "33234b32dafa8eb69202f950a1fc92055ed76a86"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/PHP-DI/Invoker/zipball/cd6d9f267d1a3474bdddf1be1da079f01b942786",
|
||||
"reference": "cd6d9f267d1a3474bdddf1be1da079f01b942786",
|
||||
"url": "https://api.github.com/repos/PHP-DI/Invoker/zipball/33234b32dafa8eb69202f950a1fc92055ed76a86",
|
||||
"reference": "33234b32dafa8eb69202f950a1fc92055ed76a86",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -1234,7 +1309,7 @@
|
||||
"mnapoli/hard-mode": "~0.3.0",
|
||||
"phpunit/phpunit": "^9.0"
|
||||
},
|
||||
"time": "2021-12-13T09:22:56+00:00",
|
||||
"time": "2023-09-08T09:24:21+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
@ -1258,7 +1333,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/PHP-DI/Invoker/issues",
|
||||
"source": "https://github.com/PHP-DI/Invoker/tree/2.3.3"
|
||||
"source": "https://github.com/PHP-DI/Invoker/tree/2.3.4"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -1394,17 +1469,17 @@
|
||||
},
|
||||
{
|
||||
"name": "phpmailer/phpmailer",
|
||||
"version": "v6.8.0",
|
||||
"version_normalized": "6.8.0.0",
|
||||
"version": "v6.9.1",
|
||||
"version_normalized": "6.9.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/PHPMailer/PHPMailer.git",
|
||||
"reference": "df16b615e371d81fb79e506277faea67a1be18f1"
|
||||
"reference": "039de174cd9c17a8389754d3b877a2ed22743e18"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/df16b615e371d81fb79e506277faea67a1be18f1",
|
||||
"reference": "df16b615e371d81fb79e506277faea67a1be18f1",
|
||||
"url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/039de174cd9c17a8389754d3b877a2ed22743e18",
|
||||
"reference": "039de174cd9c17a8389754d3b877a2ed22743e18",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -1414,16 +1489,17 @@
|
||||
"php": ">=5.5.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"dealerdirect/phpcodesniffer-composer-installer": "^0.7.2",
|
||||
"dealerdirect/phpcodesniffer-composer-installer": "^1.0",
|
||||
"doctrine/annotations": "^1.2.6 || ^1.13.3",
|
||||
"php-parallel-lint/php-console-highlighter": "^1.0.0",
|
||||
"php-parallel-lint/php-parallel-lint": "^1.3.2",
|
||||
"phpcompatibility/php-compatibility": "^9.3.5",
|
||||
"roave/security-advisories": "dev-latest",
|
||||
"squizlabs/php_codesniffer": "^3.7.1",
|
||||
"squizlabs/php_codesniffer": "^3.7.2",
|
||||
"yoast/phpunit-polyfills": "^1.0.4"
|
||||
},
|
||||
"suggest": {
|
||||
"decomplexity/SendOauth2": "Adapter for using XOAUTH2 authentication",
|
||||
"ext-mbstring": "Needed to send email in multibyte encoding charset or decode encoded addresses",
|
||||
"ext-openssl": "Needed for secure SMTP sending and DKIM signing",
|
||||
"greew/oauth2-azure-provider": "Needed for Microsoft Azure XOAUTH2 authentication",
|
||||
@ -1433,7 +1509,7 @@
|
||||
"symfony/polyfill-mbstring": "To support UTF-8 if the Mbstring PHP extension is not enabled (^1.2)",
|
||||
"thenetworg/oauth2-azure": "Needed for Microsoft XOAUTH2 authentication"
|
||||
},
|
||||
"time": "2023-03-06T14:43:22+00:00",
|
||||
"time": "2023-11-25T22:23:28+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
@ -1465,7 +1541,7 @@
|
||||
"description": "PHPMailer is a full-featured email creation and transfer class for PHP",
|
||||
"support": {
|
||||
"issues": "https://github.com/PHPMailer/PHPMailer/issues",
|
||||
"source": "https://github.com/PHPMailer/PHPMailer/tree/v6.8.0"
|
||||
"source": "https://github.com/PHPMailer/PHPMailer/tree/v6.9.1"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -1642,24 +1718,24 @@
|
||||
},
|
||||
{
|
||||
"name": "psr/http-client",
|
||||
"version": "1.0.2",
|
||||
"version_normalized": "1.0.2.0",
|
||||
"version": "1.0.3",
|
||||
"version_normalized": "1.0.3.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/php-fig/http-client.git",
|
||||
"reference": "0955afe48220520692d2d09f7ab7e0f93ffd6a31"
|
||||
"reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/php-fig/http-client/zipball/0955afe48220520692d2d09f7ab7e0f93ffd6a31",
|
||||
"reference": "0955afe48220520692d2d09f7ab7e0f93ffd6a31",
|
||||
"url": "https://api.github.com/repos/php-fig/http-client/zipball/bb5906edc1c324c9a05aa0873d40117941e5fa90",
|
||||
"reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.0 || ^8.0",
|
||||
"psr/http-message": "^1.0 || ^2.0"
|
||||
},
|
||||
"time": "2023-04-10T20:12:12+00:00",
|
||||
"time": "2023-09-23T14:17:50+00:00",
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
@ -1691,7 +1767,7 @@
|
||||
"psr-18"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/php-fig/http-client/tree/1.0.2"
|
||||
"source": "https://github.com/php-fig/http-client"
|
||||
},
|
||||
"install-path": "../psr/http-client"
|
||||
},
|
||||
@ -1922,24 +1998,18 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-mbstring",
|
||||
"version": "v1.27.0",
|
||||
"version_normalized": "1.27.0.0",
|
||||
"version": "v1.29.0",
|
||||
"version_normalized": "1.29.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-mbstring.git",
|
||||
"reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534"
|
||||
"reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/8ad114f6b39e2c98a8b0e3bd907732c207c2b534",
|
||||
"reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534",
|
||||
"shasum": "",
|
||||
"mirrors": [
|
||||
{
|
||||
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
|
||||
"preferred": true
|
||||
}
|
||||
]
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9773676c8a1bb1f8d4340a62efe641cf76eda7ec",
|
||||
"reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.1"
|
||||
@ -1950,12 +2020,9 @@
|
||||
"suggest": {
|
||||
"ext-mbstring": "For best performance"
|
||||
},
|
||||
"time": "2022-11-03T14:55:06+00:00",
|
||||
"time": "2024-01-29T20:11:03+00:00",
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "1.27-dev"
|
||||
},
|
||||
"thanks": {
|
||||
"name": "symfony/polyfill",
|
||||
"url": "https://github.com/symfony/polyfill"
|
||||
@ -1994,7 +2061,7 @@
|
||||
"shim"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.27.0"
|
||||
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.29.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -2014,34 +2081,25 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-php72",
|
||||
"version": "v1.27.0",
|
||||
"version_normalized": "1.27.0.0",
|
||||
"version": "v1.29.0",
|
||||
"version_normalized": "1.29.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-php72.git",
|
||||
"reference": "869329b1e9894268a8a61dabb69153029b7a8c97"
|
||||
"reference": "861391a8da9a04cbad2d232ddd9e4893220d6e25"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/869329b1e9894268a8a61dabb69153029b7a8c97",
|
||||
"reference": "869329b1e9894268a8a61dabb69153029b7a8c97",
|
||||
"shasum": "",
|
||||
"mirrors": [
|
||||
{
|
||||
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
|
||||
"preferred": true
|
||||
}
|
||||
]
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/861391a8da9a04cbad2d232ddd9e4893220d6e25",
|
||||
"reference": "861391a8da9a04cbad2d232ddd9e4893220d6e25",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.1"
|
||||
},
|
||||
"time": "2022-11-03T14:55:06+00:00",
|
||||
"time": "2024-01-29T20:11:03+00:00",
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "1.27-dev"
|
||||
},
|
||||
"thanks": {
|
||||
"name": "symfony/polyfill",
|
||||
"url": "https://github.com/symfony/polyfill"
|
||||
@ -2079,7 +2137,7 @@
|
||||
"shim"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/polyfill-php72/tree/v1.27.0"
|
||||
"source": "https://github.com/symfony/polyfill-php72/tree/v1.29.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -2099,34 +2157,25 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-php80",
|
||||
"version": "v1.27.0",
|
||||
"version_normalized": "1.27.0.0",
|
||||
"version": "v1.29.0",
|
||||
"version_normalized": "1.29.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-php80.git",
|
||||
"reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936"
|
||||
"reference": "87b68208d5c1188808dd7839ee1e6c8ec3b02f1b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936",
|
||||
"reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936",
|
||||
"shasum": "",
|
||||
"mirrors": [
|
||||
{
|
||||
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
|
||||
"preferred": true
|
||||
}
|
||||
]
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/87b68208d5c1188808dd7839ee1e6c8ec3b02f1b",
|
||||
"reference": "87b68208d5c1188808dd7839ee1e6c8ec3b02f1b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.1"
|
||||
},
|
||||
"time": "2022-11-03T14:55:06+00:00",
|
||||
"time": "2024-01-29T20:11:03+00:00",
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "1.27-dev"
|
||||
},
|
||||
"thanks": {
|
||||
"name": "symfony/polyfill",
|
||||
"url": "https://github.com/symfony/polyfill"
|
||||
@ -2171,7 +2220,7 @@
|
||||
"shim"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/polyfill-php80/tree/v1.27.0"
|
||||
"source": "https://github.com/symfony/polyfill-php80/tree/v1.29.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -2289,17 +2338,17 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/var-exporter",
|
||||
"version": "v5.4.26",
|
||||
"version_normalized": "5.4.26.0",
|
||||
"version": "v5.4.35",
|
||||
"version_normalized": "5.4.35.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/var-exporter.git",
|
||||
"reference": "11401fe94f960249b3c63a488c63ba73091c1e4a"
|
||||
"reference": "abb0a151b62d6b07e816487e20040464af96cae7"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/var-exporter/zipball/11401fe94f960249b3c63a488c63ba73091c1e4a",
|
||||
"reference": "11401fe94f960249b3c63a488c63ba73091c1e4a",
|
||||
"url": "https://api.github.com/repos/symfony/var-exporter/zipball/abb0a151b62d6b07e816487e20040464af96cae7",
|
||||
"reference": "abb0a151b62d6b07e816487e20040464af96cae7",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -2309,7 +2358,7 @@
|
||||
"require-dev": {
|
||||
"symfony/var-dumper": "^4.4.9|^5.0.9|^6.0"
|
||||
},
|
||||
"time": "2023-07-20T07:21:16+00:00",
|
||||
"time": "2024-01-23T13:51:25+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
@ -2345,7 +2394,7 @@
|
||||
"serialize"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/var-exporter/tree/v5.4.26"
|
||||
"source": "https://github.com/symfony/var-exporter/tree/v5.4.35"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -2528,69 +2577,6 @@
|
||||
},
|
||||
"install-path": "../taoser/think-setarr"
|
||||
},
|
||||
{
|
||||
"name": "tightenco/collect",
|
||||
"version": "v8.83.27",
|
||||
"version_normalized": "8.83.27.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/tighten/collect.git",
|
||||
"reference": "07eed6cf7441c7a69c379fdcb118eec1a1fdd0e6"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/tighten/collect/zipball/07eed6cf7441c7a69c379fdcb118eec1a1fdd0e6",
|
||||
"reference": "07eed6cf7441c7a69c379fdcb118eec1a1fdd0e6",
|
||||
"shasum": "",
|
||||
"mirrors": [
|
||||
{
|
||||
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
|
||||
"preferred": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.3|^8.0",
|
||||
"symfony/var-dumper": "^3.4 || ^4.0 || ^5.0 || ^6.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"mockery/mockery": "^1.0",
|
||||
"nesbot/carbon": "^2.23.0",
|
||||
"phpunit/phpunit": "^8.3"
|
||||
},
|
||||
"time": "2023-01-13T18:05:42+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"files": [
|
||||
"src/Collect/Support/helpers.php",
|
||||
"src/Collect/Support/alias.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Tightenco\\Collect\\": "src/Collect"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Taylor Otwell",
|
||||
"email": "taylorotwell@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "Collect - Illuminate Collections as a separate package.",
|
||||
"keywords": [
|
||||
"collection",
|
||||
"laravel"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/tighten/collect/issues",
|
||||
"source": "https://github.com/tighten/collect/tree/v8.83.27"
|
||||
},
|
||||
"install-path": "../tightenco/collect"
|
||||
},
|
||||
{
|
||||
"name": "topthink/framework",
|
||||
"version": "v6.1.4",
|
||||
@ -2832,30 +2818,33 @@
|
||||
},
|
||||
{
|
||||
"name": "topthink/think-migration",
|
||||
"version": "v3.0.6",
|
||||
"version_normalized": "3.0.6.0",
|
||||
"version": "v3.1.1",
|
||||
"version_normalized": "3.1.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/top-think/think-migration.git",
|
||||
"reference": "82c4226cb14f973b9377c7fc6e89c525cbb8b030"
|
||||
"reference": "22c44058e1454f3af1d346e7f6524fbe654de7fb"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/top-think/think-migration/zipball/82c4226cb14f973b9377c7fc6e89c525cbb8b030",
|
||||
"reference": "82c4226cb14f973b9377c7fc6e89c525cbb8b030",
|
||||
"url": "https://api.github.com/repos/top-think/think-migration/zipball/22c44058e1454f3af1d346e7f6524fbe654de7fb",
|
||||
"reference": "22c44058e1454f3af1d346e7f6524fbe654de7fb",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.2",
|
||||
"topthink/framework": "^6.0 || ^8.0",
|
||||
"topthink/think-helper": "^3.0.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"fzaninotto/faker": "^1.8"
|
||||
"composer/composer": "^2.5.8",
|
||||
"fzaninotto/faker": "^1.8",
|
||||
"robmorgan/phinx": "^0.13.4"
|
||||
},
|
||||
"suggest": {
|
||||
"fzaninotto/faker": "Required to use the factory builder (^1.8)."
|
||||
},
|
||||
"time": "2023-07-01T11:01:52+00:00",
|
||||
"time": "2023-09-14T05:51:31+00:00",
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"think": {
|
||||
@ -2867,7 +2856,7 @@
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Phinx\\": "phinx/src/Phinx",
|
||||
"Phinx\\": "phinx",
|
||||
"think\\migration\\": "src"
|
||||
}
|
||||
},
|
||||
@ -2883,7 +2872,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/top-think/think-migration/issues",
|
||||
"source": "https://github.com/top-think/think-migration/tree/v3.0.6"
|
||||
"source": "https://github.com/top-think/think-migration/tree/v3.1.1"
|
||||
},
|
||||
"install-path": "../topthink/think-migration"
|
||||
},
|
||||
@ -3164,60 +3153,6 @@
|
||||
"description": "thinkphp template driver",
|
||||
"install-path": "../topthink/think-view"
|
||||
},
|
||||
{
|
||||
"name": "wamkj/thinkphp6.0-databackup",
|
||||
"version": "v1.0",
|
||||
"version_normalized": "1.0.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/wamkj/thinkphp6.0-databackup.git",
|
||||
"reference": "28a0e406d827132942723a3c9f69bb20c98e652f"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/wamkj/thinkphp6.0-databackup/zipball/28a0e406d827132942723a3c9f69bb20c98e652f",
|
||||
"reference": "28a0e406d827132942723a3c9f69bb20c98e652f",
|
||||
"shasum": "",
|
||||
"mirrors": [
|
||||
{
|
||||
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
|
||||
"preferred": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.1.0",
|
||||
"topthink/framework": "^6.0"
|
||||
},
|
||||
"time": "2020-02-15T13:04:16+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"wamkj\\thinkphp\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"Apache-2.0"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "wamkj",
|
||||
"email": "1149183529@qq.com"
|
||||
}
|
||||
],
|
||||
"description": "thinkphp6.0的数据库自动备份扩展",
|
||||
"keywords": [
|
||||
"think-databackup",
|
||||
"thinkphp"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/wamkj/thinkphp6.0-databackup/issues",
|
||||
"source": "https://github.com/wamkj/thinkphp6.0-databackup/tree/v1.0"
|
||||
},
|
||||
"install-path": "../wamkj/thinkphp6.0-databackup"
|
||||
},
|
||||
{
|
||||
"name": "workerman/channel",
|
||||
"version": "v1.2.0",
|
||||
@ -3314,17 +3249,17 @@
|
||||
},
|
||||
{
|
||||
"name": "workerman/workerman",
|
||||
"version": "v4.1.13",
|
||||
"version_normalized": "4.1.13.0",
|
||||
"version": "v4.1.15",
|
||||
"version_normalized": "4.1.15.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/walkor/workerman.git",
|
||||
"reference": "807780ff672775fcd08f89e573a2824e939021ce"
|
||||
"reference": "afc8242fc769ab7cf22eb4ac22b97cb59d465e4e"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/walkor/workerman/zipball/807780ff672775fcd08f89e573a2824e939021ce",
|
||||
"reference": "807780ff672775fcd08f89e573a2824e939021ce",
|
||||
"url": "https://api.github.com/repos/walkor/workerman/zipball/afc8242fc769ab7cf22eb4ac22b97cb59d465e4e",
|
||||
"reference": "afc8242fc769ab7cf22eb4ac22b97cb59d465e4e",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -3333,7 +3268,7 @@
|
||||
"suggest": {
|
||||
"ext-event": "For better performance. "
|
||||
},
|
||||
"time": "2023-07-31T05:57:25+00:00",
|
||||
"time": "2024-02-19T02:10:39+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
@ -3524,31 +3459,25 @@
|
||||
},
|
||||
{
|
||||
"name": "yzh52521/easyhttp",
|
||||
"version": "v1.0.7",
|
||||
"version_normalized": "1.0.7.0",
|
||||
"version": "v1.1.3",
|
||||
"version_normalized": "1.1.3.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/yzh52521/easyhttp.git",
|
||||
"reference": "52cb9aba60a725bef77acd9c4c48ecc78931af9e"
|
||||
"url": "https://github.com/yuanzhihai/easyhttp.git",
|
||||
"reference": "02bcf47eaf723520fa3905d0e6f1852168fe646c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/yzh52521/easyhttp/zipball/52cb9aba60a725bef77acd9c4c48ecc78931af9e",
|
||||
"reference": "52cb9aba60a725bef77acd9c4c48ecc78931af9e",
|
||||
"shasum": "",
|
||||
"mirrors": [
|
||||
{
|
||||
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
|
||||
"preferred": true
|
||||
}
|
||||
]
|
||||
"url": "https://api.github.com/repos/yuanzhihai/easyhttp/zipball/02bcf47eaf723520fa3905d0e6f1852168fe646c",
|
||||
"reference": "02bcf47eaf723520fa3905d0e6f1852168fe646c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"guzzlehttp/guzzle": "^6.0|^7.0",
|
||||
"php": "^7.2.5|^8.0",
|
||||
"php": ">=7.2.5",
|
||||
"psr/log": "^1.0|^2.0|^3.0"
|
||||
},
|
||||
"time": "2023-02-16T03:04:02+00:00",
|
||||
"time": "2023-11-14T05:49:02+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
@ -3578,8 +3507,8 @@
|
||||
"phphttp"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/yzh52521/easyhttp/issues",
|
||||
"source": "https://github.com/yzh52521/easyhttp/tree/v1.0.7"
|
||||
"issues": "https://github.com/yuanzhihai/easyhttp/issues",
|
||||
"source": "https://github.com/yuanzhihai/easyhttp/tree/v1.1.3"
|
||||
},
|
||||
"install-path": "../yzh52521/easyhttp"
|
||||
}
|
||||
|
131
vendor/composer/installed.php
vendored
131
vendor/composer/installed.php
vendored
@ -3,7 +3,7 @@
|
||||
'name' => 'taoser/taoler',
|
||||
'pretty_version' => '2.3.10.x-dev',
|
||||
'version' => '2.3.10.9999999-dev',
|
||||
'reference' => '0c2f0154a81dd0a6268da627982d1bf41c0ef231',
|
||||
'reference' => '158340e85a56ec3bd70563cef0bf1491468d7370',
|
||||
'type' => 'project',
|
||||
'install_path' => __DIR__ . '/../../',
|
||||
'aliases' => array(),
|
||||
@ -47,9 +47,9 @@
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'dasprid/enum' => array(
|
||||
'pretty_version' => '1.0.4',
|
||||
'version' => '1.0.4.0',
|
||||
'reference' => '8e6b6ea76eabbf19ea2bf5b67b98e1860474012f',
|
||||
'pretty_version' => '1.0.5',
|
||||
'version' => '1.0.5.0',
|
||||
'reference' => '6faf451159fb8ba4126b925ed2d78acfce0dc016',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../dasprid/enum',
|
||||
'aliases' => array(),
|
||||
@ -64,6 +64,15 @@
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'firebase/php-jwt' => array(
|
||||
'pretty_version' => 'v6.10.0',
|
||||
'version' => '6.10.0.0',
|
||||
'reference' => 'a49db6f0a5033aef5143295342f1c95521b075ff',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../firebase/php-jwt',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'guzzlehttp/guzzle' => array(
|
||||
'pretty_version' => '7.0.0',
|
||||
'version' => '7.0.0.0',
|
||||
@ -92,9 +101,9 @@
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'jaeger/g-http' => array(
|
||||
'pretty_version' => 'V1.7.2',
|
||||
'version' => '1.7.2.0',
|
||||
'reference' => '82585ddd5e2c6651e37ab1d8166efcdbb6b293d4',
|
||||
'pretty_version' => 'V1.7.3',
|
||||
'version' => '1.7.3.0',
|
||||
'reference' => '035fe0ff6e3e0390769647ce14694875bf02cf22',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../jaeger/g-http',
|
||||
'aliases' => array(),
|
||||
@ -110,18 +119,18 @@
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'jaeger/querylist' => array(
|
||||
'pretty_version' => 'V4.2.8',
|
||||
'version' => '4.2.8.0',
|
||||
'reference' => '39dc0ca9c668bec7a793e20472ccd7d26ef89ea4',
|
||||
'pretty_version' => 'V4.2.9',
|
||||
'version' => '4.2.9.0',
|
||||
'reference' => '7aae3aed38214d3d7096174faf49f6c41b2dd550',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../jaeger/querylist',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'laravel/serializable-closure' => array(
|
||||
'pretty_version' => 'v1.3.1',
|
||||
'version' => '1.3.1.0',
|
||||
'reference' => 'e5a3057a5591e1cfe8183034b0203921abe2c902',
|
||||
'pretty_version' => 'v1.3.3',
|
||||
'version' => '1.3.3.0',
|
||||
'reference' => '3dbf8a8e914634c48d389c1234552666b3d43754',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../laravel/serializable-closure',
|
||||
'aliases' => array(),
|
||||
@ -137,9 +146,9 @@
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'league/mime-type-detection' => array(
|
||||
'pretty_version' => '1.11.0',
|
||||
'version' => '1.11.0.0',
|
||||
'reference' => 'ff6248ea87a9f116e78edd6002e39e5128a0d4dd',
|
||||
'pretty_version' => '1.15.0',
|
||||
'version' => '1.15.0.0',
|
||||
'reference' => 'ce0f4d1e8a6f4eb0ddff33f57c69c50fd09f4301',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../league/mime-type-detection',
|
||||
'aliases' => array(),
|
||||
@ -154,19 +163,19 @@
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'lotofbadcode/phpspirit_databackup' => array(
|
||||
'pretty_version' => 'v1.2',
|
||||
'version' => '1.2.0.0',
|
||||
'reference' => '77c2421f8461392c044cf8c29918f495c22a5612',
|
||||
'overtrue/easy-sms' => array(
|
||||
'pretty_version' => '2.6.0',
|
||||
'version' => '2.6.0.0',
|
||||
'reference' => 'bb88b244f0de8d1f74bc50c4c08414f4c5f30281',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../lotofbadcode/phpspirit_databackup',
|
||||
'install_path' => __DIR__ . '/../overtrue/easy-sms',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'php-di/invoker' => array(
|
||||
'pretty_version' => '2.3.3',
|
||||
'version' => '2.3.3.0',
|
||||
'reference' => 'cd6d9f267d1a3474bdddf1be1da079f01b942786',
|
||||
'pretty_version' => '2.3.4',
|
||||
'version' => '2.3.4.0',
|
||||
'reference' => '33234b32dafa8eb69202f950a1fc92055ed76a86',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../php-di/invoker',
|
||||
'aliases' => array(),
|
||||
@ -191,9 +200,9 @@
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'phpmailer/phpmailer' => array(
|
||||
'pretty_version' => 'v6.8.0',
|
||||
'version' => '6.8.0.0',
|
||||
'reference' => 'df16b615e371d81fb79e506277faea67a1be18f1',
|
||||
'pretty_version' => 'v6.9.1',
|
||||
'version' => '6.9.1.0',
|
||||
'reference' => '039de174cd9c17a8389754d3b877a2ed22743e18',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../phpmailer/phpmailer',
|
||||
'aliases' => array(),
|
||||
@ -239,9 +248,9 @@
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'psr/http-client' => array(
|
||||
'pretty_version' => '1.0.2',
|
||||
'version' => '1.0.2.0',
|
||||
'reference' => '0955afe48220520692d2d09f7ab7e0f93ffd6a31',
|
||||
'pretty_version' => '1.0.3',
|
||||
'version' => '1.0.3.0',
|
||||
'reference' => 'bb5906edc1c324c9a05aa0873d40117941e5fa90',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../psr/http-client',
|
||||
'aliases' => array(),
|
||||
@ -302,27 +311,27 @@
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/polyfill-mbstring' => array(
|
||||
'pretty_version' => 'v1.27.0',
|
||||
'version' => '1.27.0.0',
|
||||
'reference' => '8ad114f6b39e2c98a8b0e3bd907732c207c2b534',
|
||||
'pretty_version' => 'v1.29.0',
|
||||
'version' => '1.29.0.0',
|
||||
'reference' => '9773676c8a1bb1f8d4340a62efe641cf76eda7ec',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/polyfill-mbstring',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/polyfill-php72' => array(
|
||||
'pretty_version' => 'v1.27.0',
|
||||
'version' => '1.27.0.0',
|
||||
'reference' => '869329b1e9894268a8a61dabb69153029b7a8c97',
|
||||
'pretty_version' => 'v1.29.0',
|
||||
'version' => '1.29.0.0',
|
||||
'reference' => '861391a8da9a04cbad2d232ddd9e4893220d6e25',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/polyfill-php72',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/polyfill-php80' => array(
|
||||
'pretty_version' => 'v1.27.0',
|
||||
'version' => '1.27.0.0',
|
||||
'reference' => '7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936',
|
||||
'pretty_version' => 'v1.29.0',
|
||||
'version' => '1.29.0.0',
|
||||
'reference' => '87b68208d5c1188808dd7839ee1e6c8ec3b02f1b',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/polyfill-php80',
|
||||
'aliases' => array(),
|
||||
@ -338,9 +347,9 @@
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/var-exporter' => array(
|
||||
'pretty_version' => 'v5.4.26',
|
||||
'version' => '5.4.26.0',
|
||||
'reference' => '11401fe94f960249b3c63a488c63ba73091c1e4a',
|
||||
'pretty_version' => 'v5.4.35',
|
||||
'version' => '5.4.35.0',
|
||||
'reference' => 'abb0a151b62d6b07e816487e20040464af96cae7',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/var-exporter',
|
||||
'aliases' => array(),
|
||||
@ -349,7 +358,7 @@
|
||||
'taoser/taoler' => array(
|
||||
'pretty_version' => '2.3.10.x-dev',
|
||||
'version' => '2.3.10.9999999-dev',
|
||||
'reference' => '0c2f0154a81dd0a6268da627982d1bf41c0ef231',
|
||||
'reference' => '158340e85a56ec3bd70563cef0bf1491468d7370',
|
||||
'type' => 'project',
|
||||
'install_path' => __DIR__ . '/../../',
|
||||
'aliases' => array(),
|
||||
@ -382,15 +391,6 @@
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'tightenco/collect' => array(
|
||||
'pretty_version' => 'v8.83.27',
|
||||
'version' => '8.83.27.0',
|
||||
'reference' => '07eed6cf7441c7a69c379fdcb118eec1a1fdd0e6',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../tightenco/collect',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'topthink/framework' => array(
|
||||
'pretty_version' => 'v6.1.4',
|
||||
'version' => '6.1.4.0',
|
||||
@ -428,9 +428,9 @@
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'topthink/think-migration' => array(
|
||||
'pretty_version' => 'v3.0.6',
|
||||
'version' => '3.0.6.0',
|
||||
'reference' => '82c4226cb14f973b9377c7fc6e89c525cbb8b030',
|
||||
'pretty_version' => 'v3.1.1',
|
||||
'version' => '3.1.1.0',
|
||||
'reference' => '22c44058e1454f3af1d346e7f6524fbe654de7fb',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../topthink/think-migration',
|
||||
'aliases' => array(),
|
||||
@ -481,15 +481,6 @@
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'wamkj/thinkphp6.0-databackup' => array(
|
||||
'pretty_version' => 'v1.0',
|
||||
'version' => '1.0.0.0',
|
||||
'reference' => '28a0e406d827132942723a3c9f69bb20c98e652f',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../wamkj/thinkphp6.0-databackup',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'workerman/channel' => array(
|
||||
'pretty_version' => 'v1.2.0',
|
||||
'version' => '1.2.0.0',
|
||||
@ -509,9 +500,9 @@
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'workerman/workerman' => array(
|
||||
'pretty_version' => 'v4.1.13',
|
||||
'version' => '4.1.13.0',
|
||||
'reference' => '807780ff672775fcd08f89e573a2824e939021ce',
|
||||
'pretty_version' => 'v4.1.15',
|
||||
'version' => '4.1.15.0',
|
||||
'reference' => 'afc8242fc769ab7cf22eb4ac22b97cb59d465e4e',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../workerman/workerman',
|
||||
'aliases' => array(),
|
||||
@ -536,9 +527,9 @@
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'yzh52521/easyhttp' => array(
|
||||
'pretty_version' => 'v1.0.7',
|
||||
'version' => '1.0.7.0',
|
||||
'reference' => '52cb9aba60a725bef77acd9c4c48ecc78931af9e',
|
||||
'pretty_version' => 'v1.1.3',
|
||||
'version' => '1.1.3.0',
|
||||
'reference' => '02bcf47eaf723520fa3905d0e6f1852168fe646c',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../yzh52521/easyhttp',
|
||||
'aliases' => array(),
|
||||
|
170
vendor/firebase/php-jwt/CHANGELOG.md
vendored
Normal file
170
vendor/firebase/php-jwt/CHANGELOG.md
vendored
Normal file
@ -0,0 +1,170 @@
|
||||
# Changelog
|
||||
|
||||
## [6.10.0](https://github.com/firebase/php-jwt/compare/v6.9.0...v6.10.0) (2023-11-28)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* allow typ header override ([#546](https://github.com/firebase/php-jwt/issues/546)) ([79cb30b](https://github.com/firebase/php-jwt/commit/79cb30b729a22931b2fbd6b53f20629a83031ba9))
|
||||
|
||||
## [6.9.0](https://github.com/firebase/php-jwt/compare/v6.8.1...v6.9.0) (2023-10-04)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* add payload to jwt exception ([#521](https://github.com/firebase/php-jwt/issues/521)) ([175edf9](https://github.com/firebase/php-jwt/commit/175edf958bb61922ec135b2333acf5622f2238a2))
|
||||
|
||||
## [6.8.1](https://github.com/firebase/php-jwt/compare/v6.8.0...v6.8.1) (2023-07-14)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* accept float claims but round down to ignore them ([#492](https://github.com/firebase/php-jwt/issues/492)) ([3936842](https://github.com/firebase/php-jwt/commit/39368423beeaacb3002afa7dcb75baebf204fe7e))
|
||||
* different BeforeValidException messages for nbf and iat ([#526](https://github.com/firebase/php-jwt/issues/526)) ([0a53cf2](https://github.com/firebase/php-jwt/commit/0a53cf2986e45c2bcbf1a269f313ebf56a154ee4))
|
||||
|
||||
## [6.8.0](https://github.com/firebase/php-jwt/compare/v6.7.0...v6.8.0) (2023-06-14)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* add support for P-384 curve ([#515](https://github.com/firebase/php-jwt/issues/515)) ([5de4323](https://github.com/firebase/php-jwt/commit/5de4323f4baf4d70bca8663bd87682a69c656c3d))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* handle invalid http responses ([#508](https://github.com/firebase/php-jwt/issues/508)) ([91c39c7](https://github.com/firebase/php-jwt/commit/91c39c72b22fc3e1191e574089552c1f2041c718))
|
||||
|
||||
## [6.7.0](https://github.com/firebase/php-jwt/compare/v6.6.0...v6.7.0) (2023-06-14)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* add ed25519 support to JWK (public keys) ([#452](https://github.com/firebase/php-jwt/issues/452)) ([e53979a](https://github.com/firebase/php-jwt/commit/e53979abae927de916a75b9d239cfda8ce32be2a))
|
||||
|
||||
## [6.6.0](https://github.com/firebase/php-jwt/compare/v6.5.0...v6.6.0) (2023-06-13)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* allow get headers when decoding token ([#442](https://github.com/firebase/php-jwt/issues/442)) ([fb85f47](https://github.com/firebase/php-jwt/commit/fb85f47cfaeffdd94faf8defdf07164abcdad6c3))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* only check iat if nbf is not used ([#493](https://github.com/firebase/php-jwt/issues/493)) ([398ccd2](https://github.com/firebase/php-jwt/commit/398ccd25ea12fa84b9e4f1085d5ff448c21ec797))
|
||||
|
||||
## [6.5.0](https://github.com/firebase/php-jwt/compare/v6.4.0...v6.5.0) (2023-05-12)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* allow KID of '0' ([#505](https://github.com/firebase/php-jwt/issues/505)) ([9dc46a9](https://github.com/firebase/php-jwt/commit/9dc46a9c3e5801294249cfd2554c5363c9f9326a))
|
||||
|
||||
|
||||
### Miscellaneous Chores
|
||||
|
||||
* drop support for PHP 7.3 ([#495](https://github.com/firebase/php-jwt/issues/495))
|
||||
|
||||
## [6.4.0](https://github.com/firebase/php-jwt/compare/v6.3.2...v6.4.0) (2023-02-08)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* add support for W3C ES256K ([#462](https://github.com/firebase/php-jwt/issues/462)) ([213924f](https://github.com/firebase/php-jwt/commit/213924f51936291fbbca99158b11bd4ae56c2c95))
|
||||
* improve caching by only decoding jwks when necessary ([#486](https://github.com/firebase/php-jwt/issues/486)) ([78d3ed1](https://github.com/firebase/php-jwt/commit/78d3ed1073553f7d0bbffa6c2010009a0d483d5c))
|
||||
|
||||
## [6.3.2](https://github.com/firebase/php-jwt/compare/v6.3.1...v6.3.2) (2022-11-01)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* check kid before using as array index ([bad1b04](https://github.com/firebase/php-jwt/commit/bad1b040d0c736bbf86814c6b5ae614f517cf7bd))
|
||||
|
||||
## [6.3.1](https://github.com/firebase/php-jwt/compare/v6.3.0...v6.3.1) (2022-11-01)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* casing of GET for PSR compat ([#451](https://github.com/firebase/php-jwt/issues/451)) ([60b52b7](https://github.com/firebase/php-jwt/commit/60b52b71978790eafcf3b95cfbd83db0439e8d22))
|
||||
* string interpolation format for php 8.2 ([#446](https://github.com/firebase/php-jwt/issues/446)) ([2e07d8a](https://github.com/firebase/php-jwt/commit/2e07d8a1524d12b69b110ad649f17461d068b8f2))
|
||||
|
||||
## 6.3.0 / 2022-07-15
|
||||
|
||||
- Added ES256 support to JWK parsing ([#399](https://github.com/firebase/php-jwt/pull/399))
|
||||
- Fixed potential caching error in `CachedKeySet` by caching jwks as strings ([#435](https://github.com/firebase/php-jwt/pull/435))
|
||||
|
||||
## 6.2.0 / 2022-05-14
|
||||
|
||||
- Added `CachedKeySet` ([#397](https://github.com/firebase/php-jwt/pull/397))
|
||||
- Added `$defaultAlg` parameter to `JWT::parseKey` and `JWT::parseKeySet` ([#426](https://github.com/firebase/php-jwt/pull/426)).
|
||||
|
||||
## 6.1.0 / 2022-03-23
|
||||
|
||||
- Drop support for PHP 5.3, 5.4, 5.5, 5.6, and 7.0
|
||||
- Add parameter typing and return types where possible
|
||||
|
||||
## 6.0.0 / 2022-01-24
|
||||
|
||||
- **Backwards-Compatibility Breaking Changes**: See the [Release Notes](https://github.com/firebase/php-jwt/releases/tag/v6.0.0) for more information.
|
||||
- New Key object to prevent key/algorithm type confusion (#365)
|
||||
- Add JWK support (#273)
|
||||
- Add ES256 support (#256)
|
||||
- Add ES384 support (#324)
|
||||
- Add Ed25519 support (#343)
|
||||
|
||||
## 5.0.0 / 2017-06-26
|
||||
- Support RS384 and RS512.
|
||||
See [#117](https://github.com/firebase/php-jwt/pull/117). Thanks [@joostfaassen](https://github.com/joostfaassen)!
|
||||
- Add an example for RS256 openssl.
|
||||
See [#125](https://github.com/firebase/php-jwt/pull/125). Thanks [@akeeman](https://github.com/akeeman)!
|
||||
- Detect invalid Base64 encoding in signature.
|
||||
See [#162](https://github.com/firebase/php-jwt/pull/162). Thanks [@psignoret](https://github.com/psignoret)!
|
||||
- Update `JWT::verify` to handle OpenSSL errors.
|
||||
See [#159](https://github.com/firebase/php-jwt/pull/159). Thanks [@bshaffer](https://github.com/bshaffer)!
|
||||
- Add `array` type hinting to `decode` method
|
||||
See [#101](https://github.com/firebase/php-jwt/pull/101). Thanks [@hywak](https://github.com/hywak)!
|
||||
- Add all JSON error types.
|
||||
See [#110](https://github.com/firebase/php-jwt/pull/110). Thanks [@gbalduzzi](https://github.com/gbalduzzi)!
|
||||
- Bugfix 'kid' not in given key list.
|
||||
See [#129](https://github.com/firebase/php-jwt/pull/129). Thanks [@stampycode](https://github.com/stampycode)!
|
||||
- Miscellaneous cleanup, documentation and test fixes.
|
||||
See [#107](https://github.com/firebase/php-jwt/pull/107), [#115](https://github.com/firebase/php-jwt/pull/115),
|
||||
[#160](https://github.com/firebase/php-jwt/pull/160), [#161](https://github.com/firebase/php-jwt/pull/161), and
|
||||
[#165](https://github.com/firebase/php-jwt/pull/165). Thanks [@akeeman](https://github.com/akeeman),
|
||||
[@chinedufn](https://github.com/chinedufn), and [@bshaffer](https://github.com/bshaffer)!
|
||||
|
||||
## 4.0.0 / 2016-07-17
|
||||
- Add support for late static binding. See [#88](https://github.com/firebase/php-jwt/pull/88) for details. Thanks to [@chappy84](https://github.com/chappy84)!
|
||||
- Use static `$timestamp` instead of `time()` to improve unit testing. See [#93](https://github.com/firebase/php-jwt/pull/93) for details. Thanks to [@josephmcdermott](https://github.com/josephmcdermott)!
|
||||
- Fixes to exceptions classes. See [#81](https://github.com/firebase/php-jwt/pull/81) for details. Thanks to [@Maks3w](https://github.com/Maks3w)!
|
||||
- Fixes to PHPDoc. See [#76](https://github.com/firebase/php-jwt/pull/76) for details. Thanks to [@akeeman](https://github.com/akeeman)!
|
||||
|
||||
## 3.0.0 / 2015-07-22
|
||||
- Minimum PHP version updated from `5.2.0` to `5.3.0`.
|
||||
- Add `\Firebase\JWT` namespace. See
|
||||
[#59](https://github.com/firebase/php-jwt/pull/59) for details. Thanks to
|
||||
[@Dashron](https://github.com/Dashron)!
|
||||
- Require a non-empty key to decode and verify a JWT. See
|
||||
[#60](https://github.com/firebase/php-jwt/pull/60) for details. Thanks to
|
||||
[@sjones608](https://github.com/sjones608)!
|
||||
- Cleaner documentation blocks in the code. See
|
||||
[#62](https://github.com/firebase/php-jwt/pull/62) for details. Thanks to
|
||||
[@johanderuijter](https://github.com/johanderuijter)!
|
||||
|
||||
## 2.2.0 / 2015-06-22
|
||||
- Add support for adding custom, optional JWT headers to `JWT::encode()`. See
|
||||
[#53](https://github.com/firebase/php-jwt/pull/53/files) for details. Thanks to
|
||||
[@mcocaro](https://github.com/mcocaro)!
|
||||
|
||||
## 2.1.0 / 2015-05-20
|
||||
- Add support for adding a leeway to `JWT:decode()` that accounts for clock skew
|
||||
between signing and verifying entities. Thanks to [@lcabral](https://github.com/lcabral)!
|
||||
- Add support for passing an object implementing the `ArrayAccess` interface for
|
||||
`$keys` argument in `JWT::decode()`. Thanks to [@aztech-dev](https://github.com/aztech-dev)!
|
||||
|
||||
## 2.0.0 / 2015-04-01
|
||||
- **Note**: It is strongly recommended that you update to > v2.0.0 to address
|
||||
known security vulnerabilities in prior versions when both symmetric and
|
||||
asymmetric keys are used together.
|
||||
- Update signature for `JWT::decode(...)` to require an array of supported
|
||||
algorithms to use when verifying token signatures.
|
337
vendor/firebase/php-jwt/README.md
vendored
337
vendor/firebase/php-jwt/README.md
vendored
@ -1,4 +1,4 @@
|
||||
[![Build Status](https://travis-ci.org/firebase/php-jwt.png?branch=master)](https://travis-ci.org/firebase/php-jwt)
|
||||
![Build Status](https://github.com/firebase/php-jwt/actions/workflows/tests.yml/badge.svg)
|
||||
[![Latest Stable Version](https://poser.pugx.org/firebase/php-jwt/v/stable)](https://packagist.org/packages/firebase/php-jwt)
|
||||
[![Total Downloads](https://poser.pugx.org/firebase/php-jwt/downloads)](https://packagist.org/packages/firebase/php-jwt)
|
||||
[![License](https://poser.pugx.org/firebase/php-jwt/license)](https://packagist.org/packages/firebase/php-jwt)
|
||||
@ -29,13 +29,13 @@ Example
|
||||
use Firebase\JWT\JWT;
|
||||
use Firebase\JWT\Key;
|
||||
|
||||
$key = "example_key";
|
||||
$payload = array(
|
||||
"iss" => "http://example.org",
|
||||
"aud" => "http://example.com",
|
||||
"iat" => 1356999524,
|
||||
"nbf" => 1357000000
|
||||
);
|
||||
$key = 'example_key';
|
||||
$payload = [
|
||||
'iss' => 'http://example.org',
|
||||
'aud' => 'http://example.com',
|
||||
'iat' => 1356999524,
|
||||
'nbf' => 1357000000
|
||||
];
|
||||
|
||||
/**
|
||||
* IMPORTANT:
|
||||
@ -45,9 +45,12 @@ $payload = array(
|
||||
*/
|
||||
$jwt = JWT::encode($payload, $key, 'HS256');
|
||||
$decoded = JWT::decode($jwt, new Key($key, 'HS256'));
|
||||
|
||||
print_r($decoded);
|
||||
|
||||
// Pass a stdClass in as the third parameter to get the decoded header values
|
||||
$decoded = JWT::decode($jwt, new Key($key, 'HS256'), $headers = new stdClass());
|
||||
print_r($headers);
|
||||
|
||||
/*
|
||||
NOTE: This will now be an object instead of an associative array. To get
|
||||
an associative array, you will need to cast it as such:
|
||||
@ -65,6 +68,40 @@ $decoded_array = (array) $decoded;
|
||||
JWT::$leeway = 60; // $leeway in seconds
|
||||
$decoded = JWT::decode($jwt, new Key($key, 'HS256'));
|
||||
```
|
||||
Example encode/decode headers
|
||||
-------
|
||||
Decoding the JWT headers without verifying the JWT first is NOT recommended, and is not supported by
|
||||
this library. This is because without verifying the JWT, the header values could have been tampered with.
|
||||
Any value pulled from an unverified header should be treated as if it could be any string sent in from an
|
||||
attacker. If this is something you still want to do in your application for whatever reason, it's possible to
|
||||
decode the header values manually simply by calling `json_decode` and `base64_decode` on the JWT
|
||||
header part:
|
||||
```php
|
||||
use Firebase\JWT\JWT;
|
||||
|
||||
$key = 'example_key';
|
||||
$payload = [
|
||||
'iss' => 'http://example.org',
|
||||
'aud' => 'http://example.com',
|
||||
'iat' => 1356999524,
|
||||
'nbf' => 1357000000
|
||||
];
|
||||
|
||||
$headers = [
|
||||
'x-forwarded-for' => 'www.google.com'
|
||||
];
|
||||
|
||||
// Encode headers in the JWT string
|
||||
$jwt = JWT::encode($payload, $key, 'HS256', null, $headers);
|
||||
|
||||
// Decode headers from the JWT string WITHOUT validation
|
||||
// **IMPORTANT**: This operation is vulnerable to attacks, as the JWT has not yet been verified.
|
||||
// These headers could be any value sent by an attacker.
|
||||
list($headersB64, $payloadB64, $sig) = explode('.', $jwt);
|
||||
$decoded = json_decode(base64_decode($headersB64), true);
|
||||
|
||||
print_r($decoded);
|
||||
```
|
||||
Example with RS256 (openssl)
|
||||
----------------------------
|
||||
```php
|
||||
@ -73,37 +110,52 @@ use Firebase\JWT\Key;
|
||||
|
||||
$privateKey = <<<EOD
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIICXAIBAAKBgQC8kGa1pSjbSYZVebtTRBLxBz5H4i2p/llLCrEeQhta5kaQu/Rn
|
||||
vuER4W8oDH3+3iuIYW4VQAzyqFpwuzjkDI+17t5t0tyazyZ8JXw+KgXTxldMPEL9
|
||||
5+qVhgXvwtihXC1c5oGbRlEDvDF6Sa53rcFVsYJ4ehde/zUxo6UvS7UrBQIDAQAB
|
||||
AoGAb/MXV46XxCFRxNuB8LyAtmLDgi/xRnTAlMHjSACddwkyKem8//8eZtw9fzxz
|
||||
bWZ/1/doQOuHBGYZU8aDzzj59FZ78dyzNFoF91hbvZKkg+6wGyd/LrGVEB+Xre0J
|
||||
Nil0GReM2AHDNZUYRv+HYJPIOrB0CRczLQsgFJ8K6aAD6F0CQQDzbpjYdx10qgK1
|
||||
cP59UHiHjPZYC0loEsk7s+hUmT3QHerAQJMZWC11Qrn2N+ybwwNblDKv+s5qgMQ5
|
||||
5tNoQ9IfAkEAxkyffU6ythpg/H0Ixe1I2rd0GbF05biIzO/i77Det3n4YsJVlDck
|
||||
ZkcvY3SK2iRIL4c9yY6hlIhs+K9wXTtGWwJBAO9Dskl48mO7woPR9uD22jDpNSwe
|
||||
k90OMepTjzSvlhjbfuPN1IdhqvSJTDychRwn1kIJ7LQZgQ8fVz9OCFZ/6qMCQGOb
|
||||
qaGwHmUK6xzpUbbacnYrIM6nLSkXgOAwv7XXCojvY614ILTK3iXiLBOxPu5Eu13k
|
||||
eUz9sHyD6vkgZzjtxXECQAkp4Xerf5TGfQXGXhxIX52yH+N2LtujCdkQZjXAsGdm
|
||||
B2zNzvrlgRmgBrklMTrMYgm1NPcW+bRLGcwgW2PTvNM=
|
||||
MIIEowIBAAKCAQEAuzWHNM5f+amCjQztc5QTfJfzCC5J4nuW+L/aOxZ4f8J3Frew
|
||||
M2c/dufrnmedsApb0By7WhaHlcqCh/ScAPyJhzkPYLae7bTVro3hok0zDITR8F6S
|
||||
JGL42JAEUk+ILkPI+DONM0+3vzk6Kvfe548tu4czCuqU8BGVOlnp6IqBHhAswNMM
|
||||
78pos/2z0CjPM4tbeXqSTTbNkXRboxjU29vSopcT51koWOgiTf3C7nJUoMWZHZI5
|
||||
HqnIhPAG9yv8HAgNk6CMk2CadVHDo4IxjxTzTTqo1SCSH2pooJl9O8at6kkRYsrZ
|
||||
WwsKlOFE2LUce7ObnXsYihStBUDoeBQlGG/BwQIDAQABAoIBAFtGaOqNKGwggn9k
|
||||
6yzr6GhZ6Wt2rh1Xpq8XUz514UBhPxD7dFRLpbzCrLVpzY80LbmVGJ9+1pJozyWc
|
||||
VKeCeUdNwbqkr240Oe7GTFmGjDoxU+5/HX/SJYPpC8JZ9oqgEA87iz+WQX9hVoP2
|
||||
oF6EB4ckDvXmk8FMwVZW2l2/kd5mrEVbDaXKxhvUDf52iVD+sGIlTif7mBgR99/b
|
||||
c3qiCnxCMmfYUnT2eh7Vv2LhCR/G9S6C3R4lA71rEyiU3KgsGfg0d82/XWXbegJW
|
||||
h3QbWNtQLxTuIvLq5aAryV3PfaHlPgdgK0ft6ocU2de2FagFka3nfVEyC7IUsNTK
|
||||
bq6nhAECgYEA7d/0DPOIaItl/8BWKyCuAHMss47j0wlGbBSHdJIiS55akMvnAG0M
|
||||
39y22Qqfzh1at9kBFeYeFIIU82ZLF3xOcE3z6pJZ4Dyvx4BYdXH77odo9uVK9s1l
|
||||
3T3BlMcqd1hvZLMS7dviyH79jZo4CXSHiKzc7pQ2YfK5eKxKqONeXuECgYEAyXlG
|
||||
vonaus/YTb1IBei9HwaccnQ/1HRn6MvfDjb7JJDIBhNClGPt6xRlzBbSZ73c2QEC
|
||||
6Fu9h36K/HZ2qcLd2bXiNyhIV7b6tVKk+0Psoj0dL9EbhsD1OsmE1nTPyAc9XZbb
|
||||
OPYxy+dpBCUA8/1U9+uiFoCa7mIbWcSQ+39gHuECgYAz82pQfct30aH4JiBrkNqP
|
||||
nJfRq05UY70uk5k1u0ikLTRoVS/hJu/d4E1Kv4hBMqYCavFSwAwnvHUo51lVCr/y
|
||||
xQOVYlsgnwBg2MX4+GjmIkqpSVCC8D7j/73MaWb746OIYZervQ8dbKahi2HbpsiG
|
||||
8AHcVSA/agxZr38qvWV54QKBgCD5TlDE8x18AuTGQ9FjxAAd7uD0kbXNz2vUYg9L
|
||||
hFL5tyL3aAAtUrUUw4xhd9IuysRhW/53dU+FsG2dXdJu6CxHjlyEpUJl2iZu/j15
|
||||
YnMzGWHIEX8+eWRDsw/+Ujtko/B7TinGcWPz3cYl4EAOiCeDUyXnqnO1btCEUU44
|
||||
DJ1BAoGBAJuPD27ErTSVtId90+M4zFPNibFP50KprVdc8CR37BE7r8vuGgNYXmnI
|
||||
RLnGP9p3pVgFCktORuYS2J/6t84I3+A17nEoB4xvhTLeAinAW/uTQOUmNicOP4Ek
|
||||
2MsLL2kHgL8bLTmvXV4FX+PXphrDKg1XxzOYn0otuoqdAQrkK4og
|
||||
-----END RSA PRIVATE KEY-----
|
||||
EOD;
|
||||
|
||||
$publicKey = <<<EOD
|
||||
-----BEGIN PUBLIC KEY-----
|
||||
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC8kGa1pSjbSYZVebtTRBLxBz5H
|
||||
4i2p/llLCrEeQhta5kaQu/RnvuER4W8oDH3+3iuIYW4VQAzyqFpwuzjkDI+17t5t
|
||||
0tyazyZ8JXw+KgXTxldMPEL95+qVhgXvwtihXC1c5oGbRlEDvDF6Sa53rcFVsYJ4
|
||||
ehde/zUxo6UvS7UrBQIDAQAB
|
||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzWHNM5f+amCjQztc5QT
|
||||
fJfzCC5J4nuW+L/aOxZ4f8J3FrewM2c/dufrnmedsApb0By7WhaHlcqCh/ScAPyJ
|
||||
hzkPYLae7bTVro3hok0zDITR8F6SJGL42JAEUk+ILkPI+DONM0+3vzk6Kvfe548t
|
||||
u4czCuqU8BGVOlnp6IqBHhAswNMM78pos/2z0CjPM4tbeXqSTTbNkXRboxjU29vS
|
||||
opcT51koWOgiTf3C7nJUoMWZHZI5HqnIhPAG9yv8HAgNk6CMk2CadVHDo4IxjxTz
|
||||
TTqo1SCSH2pooJl9O8at6kkRYsrZWwsKlOFE2LUce7ObnXsYihStBUDoeBQlGG/B
|
||||
wQIDAQAB
|
||||
-----END PUBLIC KEY-----
|
||||
EOD;
|
||||
|
||||
$payload = array(
|
||||
"iss" => "example.org",
|
||||
"aud" => "example.com",
|
||||
"iat" => 1356999524,
|
||||
"nbf" => 1357000000
|
||||
);
|
||||
$payload = [
|
||||
'iss' => 'example.org',
|
||||
'aud' => 'example.com',
|
||||
'iat' => 1356999524,
|
||||
'nbf' => 1357000000
|
||||
];
|
||||
|
||||
$jwt = JWT::encode($payload, $privateKey, 'RS256');
|
||||
echo "Encode:\n" . print_r($jwt, true) . "\n";
|
||||
@ -139,12 +191,12 @@ $privateKey = openssl_pkey_get_private(
|
||||
$passphrase
|
||||
);
|
||||
|
||||
$payload = array(
|
||||
"iss" => "example.org",
|
||||
"aud" => "example.com",
|
||||
"iat" => 1356999524,
|
||||
"nbf" => 1357000000
|
||||
);
|
||||
$payload = [
|
||||
'iss' => 'example.org',
|
||||
'aud' => 'example.com',
|
||||
'iat' => 1356999524,
|
||||
'nbf' => 1357000000
|
||||
];
|
||||
|
||||
$jwt = JWT::encode($payload, $privateKey, 'RS256');
|
||||
echo "Encode:\n" . print_r($jwt, true) . "\n";
|
||||
@ -173,12 +225,12 @@ $privateKey = base64_encode(sodium_crypto_sign_secretkey($keyPair));
|
||||
|
||||
$publicKey = base64_encode(sodium_crypto_sign_publickey($keyPair));
|
||||
|
||||
$payload = array(
|
||||
"iss" => "example.org",
|
||||
"aud" => "example.com",
|
||||
"iat" => 1356999524,
|
||||
"nbf" => 1357000000
|
||||
);
|
||||
$payload = [
|
||||
'iss' => 'example.org',
|
||||
'aud' => 'example.com',
|
||||
'iat' => 1356999524,
|
||||
'nbf' => 1357000000
|
||||
];
|
||||
|
||||
$jwt = JWT::encode($payload, $privateKey, 'EdDSA');
|
||||
echo "Encode:\n" . print_r($jwt, true) . "\n";
|
||||
@ -187,6 +239,44 @@ $decoded = JWT::decode($jwt, new Key($publicKey, 'EdDSA'));
|
||||
echo "Decode:\n" . print_r((array) $decoded, true) . "\n";
|
||||
````
|
||||
|
||||
Example with multiple keys
|
||||
--------------------------
|
||||
```php
|
||||
use Firebase\JWT\JWT;
|
||||
use Firebase\JWT\Key;
|
||||
|
||||
// Example RSA keys from previous example
|
||||
// $privateKey1 = '...';
|
||||
// $publicKey1 = '...';
|
||||
|
||||
// Example EdDSA keys from previous example
|
||||
// $privateKey2 = '...';
|
||||
// $publicKey2 = '...';
|
||||
|
||||
$payload = [
|
||||
'iss' => 'example.org',
|
||||
'aud' => 'example.com',
|
||||
'iat' => 1356999524,
|
||||
'nbf' => 1357000000
|
||||
];
|
||||
|
||||
$jwt1 = JWT::encode($payload, $privateKey1, 'RS256', 'kid1');
|
||||
$jwt2 = JWT::encode($payload, $privateKey2, 'EdDSA', 'kid2');
|
||||
echo "Encode 1:\n" . print_r($jwt1, true) . "\n";
|
||||
echo "Encode 2:\n" . print_r($jwt2, true) . "\n";
|
||||
|
||||
$keys = [
|
||||
'kid1' => new Key($publicKey1, 'RS256'),
|
||||
'kid2' => new Key($publicKey2, 'EdDSA'),
|
||||
];
|
||||
|
||||
$decoded1 = JWT::decode($jwt1, $keys);
|
||||
$decoded2 = JWT::decode($jwt2, $keys);
|
||||
|
||||
echo "Decode 1:\n" . print_r((array) $decoded1, true) . "\n";
|
||||
echo "Decode 2:\n" . print_r((array) $decoded2, true) . "\n";
|
||||
```
|
||||
|
||||
Using JWKs
|
||||
----------
|
||||
|
||||
@ -198,72 +288,117 @@ use Firebase\JWT\JWT;
|
||||
// this endpoint: https://www.gstatic.com/iap/verify/public_key-jwk
|
||||
$jwks = ['keys' => []];
|
||||
|
||||
// JWK::parseKeySet($jwks) returns an associative array of **kid** to private
|
||||
// key. Pass this as the second parameter to JWT::decode.
|
||||
// NOTE: The deprecated $supportedAlgorithm must be supplied when parsing from JWK.
|
||||
JWT::decode($payload, JWK::parseKeySet($jwks), $supportedAlgorithm);
|
||||
// JWK::parseKeySet($jwks) returns an associative array of **kid** to Firebase\JWT\Key
|
||||
// objects. Pass this as the second parameter to JWT::decode.
|
||||
JWT::decode($payload, JWK::parseKeySet($jwks));
|
||||
```
|
||||
|
||||
Changelog
|
||||
---------
|
||||
Using Cached Key Sets
|
||||
---------------------
|
||||
|
||||
#### 5.0.0 / 2017-06-26
|
||||
- Support RS384 and RS512.
|
||||
See [#117](https://github.com/firebase/php-jwt/pull/117). Thanks [@joostfaassen](https://github.com/joostfaassen)!
|
||||
- Add an example for RS256 openssl.
|
||||
See [#125](https://github.com/firebase/php-jwt/pull/125). Thanks [@akeeman](https://github.com/akeeman)!
|
||||
- Detect invalid Base64 encoding in signature.
|
||||
See [#162](https://github.com/firebase/php-jwt/pull/162). Thanks [@psignoret](https://github.com/psignoret)!
|
||||
- Update `JWT::verify` to handle OpenSSL errors.
|
||||
See [#159](https://github.com/firebase/php-jwt/pull/159). Thanks [@bshaffer](https://github.com/bshaffer)!
|
||||
- Add `array` type hinting to `decode` method
|
||||
See [#101](https://github.com/firebase/php-jwt/pull/101). Thanks [@hywak](https://github.com/hywak)!
|
||||
- Add all JSON error types.
|
||||
See [#110](https://github.com/firebase/php-jwt/pull/110). Thanks [@gbalduzzi](https://github.com/gbalduzzi)!
|
||||
- Bugfix 'kid' not in given key list.
|
||||
See [#129](https://github.com/firebase/php-jwt/pull/129). Thanks [@stampycode](https://github.com/stampycode)!
|
||||
- Miscellaneous cleanup, documentation and test fixes.
|
||||
See [#107](https://github.com/firebase/php-jwt/pull/107), [#115](https://github.com/firebase/php-jwt/pull/115),
|
||||
[#160](https://github.com/firebase/php-jwt/pull/160), [#161](https://github.com/firebase/php-jwt/pull/161), and
|
||||
[#165](https://github.com/firebase/php-jwt/pull/165). Thanks [@akeeman](https://github.com/akeeman),
|
||||
[@chinedufn](https://github.com/chinedufn), and [@bshaffer](https://github.com/bshaffer)!
|
||||
The `CachedKeySet` class can be used to fetch and cache JWKS (JSON Web Key Sets) from a public URI.
|
||||
This has the following advantages:
|
||||
|
||||
#### 4.0.0 / 2016-07-17
|
||||
- Add support for late static binding. See [#88](https://github.com/firebase/php-jwt/pull/88) for details. Thanks to [@chappy84](https://github.com/chappy84)!
|
||||
- Use static `$timestamp` instead of `time()` to improve unit testing. See [#93](https://github.com/firebase/php-jwt/pull/93) for details. Thanks to [@josephmcdermott](https://github.com/josephmcdermott)!
|
||||
- Fixes to exceptions classes. See [#81](https://github.com/firebase/php-jwt/pull/81) for details. Thanks to [@Maks3w](https://github.com/Maks3w)!
|
||||
- Fixes to PHPDoc. See [#76](https://github.com/firebase/php-jwt/pull/76) for details. Thanks to [@akeeman](https://github.com/akeeman)!
|
||||
1. The results are cached for performance.
|
||||
2. If an unrecognized key is requested, the cache is refreshed, to accomodate for key rotation.
|
||||
3. If rate limiting is enabled, the JWKS URI will not make more than 10 requests a second.
|
||||
|
||||
#### 3.0.0 / 2015-07-22
|
||||
- Minimum PHP version updated from `5.2.0` to `5.3.0`.
|
||||
- Add `\Firebase\JWT` namespace. See
|
||||
[#59](https://github.com/firebase/php-jwt/pull/59) for details. Thanks to
|
||||
[@Dashron](https://github.com/Dashron)!
|
||||
- Require a non-empty key to decode and verify a JWT. See
|
||||
[#60](https://github.com/firebase/php-jwt/pull/60) for details. Thanks to
|
||||
[@sjones608](https://github.com/sjones608)!
|
||||
- Cleaner documentation blocks in the code. See
|
||||
[#62](https://github.com/firebase/php-jwt/pull/62) for details. Thanks to
|
||||
[@johanderuijter](https://github.com/johanderuijter)!
|
||||
```php
|
||||
use Firebase\JWT\CachedKeySet;
|
||||
use Firebase\JWT\JWT;
|
||||
|
||||
#### 2.2.0 / 2015-06-22
|
||||
- Add support for adding custom, optional JWT headers to `JWT::encode()`. See
|
||||
[#53](https://github.com/firebase/php-jwt/pull/53/files) for details. Thanks to
|
||||
[@mcocaro](https://github.com/mcocaro)!
|
||||
// The URI for the JWKS you wish to cache the results from
|
||||
$jwksUri = 'https://www.gstatic.com/iap/verify/public_key-jwk';
|
||||
|
||||
#### 2.1.0 / 2015-05-20
|
||||
- Add support for adding a leeway to `JWT:decode()` that accounts for clock skew
|
||||
between signing and verifying entities. Thanks to [@lcabral](https://github.com/lcabral)!
|
||||
- Add support for passing an object implementing the `ArrayAccess` interface for
|
||||
`$keys` argument in `JWT::decode()`. Thanks to [@aztech-dev](https://github.com/aztech-dev)!
|
||||
// Create an HTTP client (can be any PSR-7 compatible HTTP client)
|
||||
$httpClient = new GuzzleHttp\Client();
|
||||
|
||||
#### 2.0.0 / 2015-04-01
|
||||
- **Note**: It is strongly recommended that you update to > v2.0.0 to address
|
||||
known security vulnerabilities in prior versions when both symmetric and
|
||||
asymmetric keys are used together.
|
||||
- Update signature for `JWT::decode(...)` to require an array of supported
|
||||
algorithms to use when verifying token signatures.
|
||||
// Create an HTTP request factory (can be any PSR-17 compatible HTTP request factory)
|
||||
$httpFactory = new GuzzleHttp\Psr\HttpFactory();
|
||||
|
||||
// Create a cache item pool (can be any PSR-6 compatible cache item pool)
|
||||
$cacheItemPool = Phpfastcache\CacheManager::getInstance('files');
|
||||
|
||||
$keySet = new CachedKeySet(
|
||||
$jwksUri,
|
||||
$httpClient,
|
||||
$httpFactory,
|
||||
$cacheItemPool,
|
||||
null, // $expiresAfter int seconds to set the JWKS to expire
|
||||
true // $rateLimit true to enable rate limit of 10 RPS on lookup of invalid keys
|
||||
);
|
||||
|
||||
$jwt = 'eyJhbGci...'; // Some JWT signed by a key from the $jwkUri above
|
||||
$decoded = JWT::decode($jwt, $keySet);
|
||||
```
|
||||
|
||||
Miscellaneous
|
||||
-------------
|
||||
|
||||
#### Exception Handling
|
||||
|
||||
When a call to `JWT::decode` is invalid, it will throw one of the following exceptions:
|
||||
|
||||
```php
|
||||
use Firebase\JWT\JWT;
|
||||
use Firebase\JWT\SignatureInvalidException;
|
||||
use Firebase\JWT\BeforeValidException;
|
||||
use Firebase\JWT\ExpiredException;
|
||||
use DomainException;
|
||||
use InvalidArgumentException;
|
||||
use UnexpectedValueException;
|
||||
|
||||
try {
|
||||
$decoded = JWT::decode($payload, $keys);
|
||||
} catch (InvalidArgumentException $e) {
|
||||
// provided key/key-array is empty or malformed.
|
||||
} catch (DomainException $e) {
|
||||
// provided algorithm is unsupported OR
|
||||
// provided key is invalid OR
|
||||
// unknown error thrown in openSSL or libsodium OR
|
||||
// libsodium is required but not available.
|
||||
} catch (SignatureInvalidException $e) {
|
||||
// provided JWT signature verification failed.
|
||||
} catch (BeforeValidException $e) {
|
||||
// provided JWT is trying to be used before "nbf" claim OR
|
||||
// provided JWT is trying to be used before "iat" claim.
|
||||
} catch (ExpiredException $e) {
|
||||
// provided JWT is trying to be used after "exp" claim.
|
||||
} catch (UnexpectedValueException $e) {
|
||||
// provided JWT is malformed OR
|
||||
// provided JWT is missing an algorithm / using an unsupported algorithm OR
|
||||
// provided JWT algorithm does not match provided key OR
|
||||
// provided key ID in key/key-array is empty or invalid.
|
||||
}
|
||||
```
|
||||
|
||||
All exceptions in the `Firebase\JWT` namespace extend `UnexpectedValueException`, and can be simplified
|
||||
like this:
|
||||
|
||||
```php
|
||||
use Firebase\JWT\JWT;
|
||||
use UnexpectedValueException;
|
||||
try {
|
||||
$decoded = JWT::decode($payload, $keys);
|
||||
} catch (LogicException $e) {
|
||||
// errors having to do with environmental setup or malformed JWT Keys
|
||||
} catch (UnexpectedValueException $e) {
|
||||
// errors having to do with JWT signature and claims
|
||||
}
|
||||
```
|
||||
|
||||
#### Casting to array
|
||||
|
||||
The return value of `JWT::decode` is the generic PHP object `stdClass`. If you'd like to handle with arrays
|
||||
instead, you can do the following:
|
||||
|
||||
```php
|
||||
// return type is stdClass
|
||||
$decoded = JWT::decode($payload, $keys);
|
||||
|
||||
// cast to array
|
||||
$decoded = json_decode(json_encode($decoded), true);
|
||||
```
|
||||
|
||||
Tests
|
||||
-----
|
||||
|
12
vendor/firebase/php-jwt/composer.json
vendored
12
vendor/firebase/php-jwt/composer.json
vendored
@ -20,10 +20,11 @@
|
||||
],
|
||||
"license": "BSD-3-Clause",
|
||||
"require": {
|
||||
"php": ">=5.3.0"
|
||||
"php": "^7.4||^8.0"
|
||||
},
|
||||
"suggest": {
|
||||
"paragonie/sodium_compat": "Support EdDSA (Ed25519) signatures when libsodium is not present"
|
||||
"paragonie/sodium_compat": "Support EdDSA (Ed25519) signatures when libsodium is not present",
|
||||
"ext-sodium": "Support EdDSA (Ed25519) signatures"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
@ -31,6 +32,11 @@
|
||||
}
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": ">=4.8 <=9"
|
||||
"guzzlehttp/guzzle": "^6.5||^7.4",
|
||||
"phpspec/prophecy-phpunit": "^2.0",
|
||||
"phpunit/phpunit": "^9.5",
|
||||
"psr/cache": "^1.0||^2.0",
|
||||
"psr/http-client": "^1.0",
|
||||
"psr/http-factory": "^1.0"
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,17 @@
|
||||
|
||||
namespace Firebase\JWT;
|
||||
|
||||
class BeforeValidException extends \UnexpectedValueException
|
||||
class BeforeValidException extends \UnexpectedValueException implements JWTExceptionWithPayloadInterface
|
||||
{
|
||||
private object $payload;
|
||||
|
||||
public function setPayload(object $payload): void
|
||||
{
|
||||
$this->payload = $payload;
|
||||
}
|
||||
|
||||
public function getPayload(): object
|
||||
{
|
||||
return $this->payload;
|
||||
}
|
||||
}
|
||||
|
268
vendor/firebase/php-jwt/src/CachedKeySet.php
vendored
Normal file
268
vendor/firebase/php-jwt/src/CachedKeySet.php
vendored
Normal file
@ -0,0 +1,268 @@
|
||||
<?php
|
||||
|
||||
namespace Firebase\JWT;
|
||||
|
||||
use ArrayAccess;
|
||||
use InvalidArgumentException;
|
||||
use LogicException;
|
||||
use OutOfBoundsException;
|
||||
use Psr\Cache\CacheItemInterface;
|
||||
use Psr\Cache\CacheItemPoolInterface;
|
||||
use Psr\Http\Client\ClientInterface;
|
||||
use Psr\Http\Message\RequestFactoryInterface;
|
||||
use RuntimeException;
|
||||
use UnexpectedValueException;
|
||||
|
||||
/**
|
||||
* @implements ArrayAccess<string, Key>
|
||||
*/
|
||||
class CachedKeySet implements ArrayAccess
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $jwksUri;
|
||||
/**
|
||||
* @var ClientInterface
|
||||
*/
|
||||
private $httpClient;
|
||||
/**
|
||||
* @var RequestFactoryInterface
|
||||
*/
|
||||
private $httpFactory;
|
||||
/**
|
||||
* @var CacheItemPoolInterface
|
||||
*/
|
||||
private $cache;
|
||||
/**
|
||||
* @var ?int
|
||||
*/
|
||||
private $expiresAfter;
|
||||
/**
|
||||
* @var ?CacheItemInterface
|
||||
*/
|
||||
private $cacheItem;
|
||||
/**
|
||||
* @var array<string, array<mixed>>
|
||||
*/
|
||||
private $keySet;
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $cacheKey;
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $cacheKeyPrefix = 'jwks';
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $maxKeyLength = 64;
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $rateLimit;
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $rateLimitCacheKey;
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $maxCallsPerMinute = 10;
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
private $defaultAlg;
|
||||
|
||||
public function __construct(
|
||||
string $jwksUri,
|
||||
ClientInterface $httpClient,
|
||||
RequestFactoryInterface $httpFactory,
|
||||
CacheItemPoolInterface $cache,
|
||||
int $expiresAfter = null,
|
||||
bool $rateLimit = false,
|
||||
string $defaultAlg = null
|
||||
) {
|
||||
$this->jwksUri = $jwksUri;
|
||||
$this->httpClient = $httpClient;
|
||||
$this->httpFactory = $httpFactory;
|
||||
$this->cache = $cache;
|
||||
$this->expiresAfter = $expiresAfter;
|
||||
$this->rateLimit = $rateLimit;
|
||||
$this->defaultAlg = $defaultAlg;
|
||||
$this->setCacheKeys();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $keyId
|
||||
* @return Key
|
||||
*/
|
||||
public function offsetGet($keyId): Key
|
||||
{
|
||||
if (!$this->keyIdExists($keyId)) {
|
||||
throw new OutOfBoundsException('Key ID not found');
|
||||
}
|
||||
return JWK::parseKey($this->keySet[$keyId], $this->defaultAlg);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $keyId
|
||||
* @return bool
|
||||
*/
|
||||
public function offsetExists($keyId): bool
|
||||
{
|
||||
return $this->keyIdExists($keyId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $offset
|
||||
* @param Key $value
|
||||
*/
|
||||
public function offsetSet($offset, $value): void
|
||||
{
|
||||
throw new LogicException('Method not implemented');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $offset
|
||||
*/
|
||||
public function offsetUnset($offset): void
|
||||
{
|
||||
throw new LogicException('Method not implemented');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<mixed>
|
||||
*/
|
||||
private function formatJwksForCache(string $jwks): array
|
||||
{
|
||||
$jwks = json_decode($jwks, true);
|
||||
|
||||
if (!isset($jwks['keys'])) {
|
||||
throw new UnexpectedValueException('"keys" member must exist in the JWK Set');
|
||||
}
|
||||
|
||||
if (empty($jwks['keys'])) {
|
||||
throw new InvalidArgumentException('JWK Set did not contain any keys');
|
||||
}
|
||||
|
||||
$keys = [];
|
||||
foreach ($jwks['keys'] as $k => $v) {
|
||||
$kid = isset($v['kid']) ? $v['kid'] : $k;
|
||||
$keys[(string) $kid] = $v;
|
||||
}
|
||||
|
||||
return $keys;
|
||||
}
|
||||
|
||||
private function keyIdExists(string $keyId): bool
|
||||
{
|
||||
if (null === $this->keySet) {
|
||||
$item = $this->getCacheItem();
|
||||
// Try to load keys from cache
|
||||
if ($item->isHit()) {
|
||||
// item found! retrieve it
|
||||
$this->keySet = $item->get();
|
||||
// If the cached item is a string, the JWKS response was cached (previous behavior).
|
||||
// Parse this into expected format array<kid, jwk> instead.
|
||||
if (\is_string($this->keySet)) {
|
||||
$this->keySet = $this->formatJwksForCache($this->keySet);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!isset($this->keySet[$keyId])) {
|
||||
if ($this->rateLimitExceeded()) {
|
||||
return false;
|
||||
}
|
||||
$request = $this->httpFactory->createRequest('GET', $this->jwksUri);
|
||||
$jwksResponse = $this->httpClient->sendRequest($request);
|
||||
if ($jwksResponse->getStatusCode() !== 200) {
|
||||
throw new UnexpectedValueException(
|
||||
sprintf('HTTP Error: %d %s for URI "%s"',
|
||||
$jwksResponse->getStatusCode(),
|
||||
$jwksResponse->getReasonPhrase(),
|
||||
$this->jwksUri,
|
||||
),
|
||||
$jwksResponse->getStatusCode()
|
||||
);
|
||||
}
|
||||
$this->keySet = $this->formatJwksForCache((string) $jwksResponse->getBody());
|
||||
|
||||
if (!isset($this->keySet[$keyId])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$item = $this->getCacheItem();
|
||||
$item->set($this->keySet);
|
||||
if ($this->expiresAfter) {
|
||||
$item->expiresAfter($this->expiresAfter);
|
||||
}
|
||||
$this->cache->save($item);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private function rateLimitExceeded(): bool
|
||||
{
|
||||
if (!$this->rateLimit) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$cacheItem = $this->cache->getItem($this->rateLimitCacheKey);
|
||||
if (!$cacheItem->isHit()) {
|
||||
$cacheItem->expiresAfter(1); // # of calls are cached each minute
|
||||
}
|
||||
|
||||
$callsPerMinute = (int) $cacheItem->get();
|
||||
if (++$callsPerMinute > $this->maxCallsPerMinute) {
|
||||
return true;
|
||||
}
|
||||
$cacheItem->set($callsPerMinute);
|
||||
$this->cache->save($cacheItem);
|
||||
return false;
|
||||
}
|
||||
|
||||
private function getCacheItem(): CacheItemInterface
|
||||
{
|
||||
if (\is_null($this->cacheItem)) {
|
||||
$this->cacheItem = $this->cache->getItem($this->cacheKey);
|
||||
}
|
||||
|
||||
return $this->cacheItem;
|
||||
}
|
||||
|
||||
private function setCacheKeys(): void
|
||||
{
|
||||
if (empty($this->jwksUri)) {
|
||||
throw new RuntimeException('JWKS URI is empty');
|
||||
}
|
||||
|
||||
// ensure we do not have illegal characters
|
||||
$key = preg_replace('|[^a-zA-Z0-9_\.!]|', '', $this->jwksUri);
|
||||
|
||||
// add prefix
|
||||
$key = $this->cacheKeyPrefix . $key;
|
||||
|
||||
// Hash keys if they exceed $maxKeyLength of 64
|
||||
if (\strlen($key) > $this->maxKeyLength) {
|
||||
$key = substr(hash('sha256', $key), 0, $this->maxKeyLength);
|
||||
}
|
||||
|
||||
$this->cacheKey = $key;
|
||||
|
||||
if ($this->rateLimit) {
|
||||
// add prefix
|
||||
$rateLimitKey = $this->cacheKeyPrefix . 'ratelimit' . $key;
|
||||
|
||||
// Hash keys if they exceed $maxKeyLength of 64
|
||||
if (\strlen($rateLimitKey) > $this->maxKeyLength) {
|
||||
$rateLimitKey = substr(hash('sha256', $rateLimitKey), 0, $this->maxKeyLength);
|
||||
}
|
||||
|
||||
$this->rateLimitCacheKey = $rateLimitKey;
|
||||
}
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user