帖子相关

This commit is contained in:
taoser 2024-04-01 10:22:13 +08:00
parent 38ac88505b
commit a5acd6cb6e
23 changed files with 909 additions and 739 deletions

View File

@ -45,6 +45,13 @@ abstract class BaseController
*/
protected $middleware = [];
/**
* article content
*
* @var string
*/
protected $content = '';
/**
* 构造方法
* @access public
@ -221,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);
@ -265,8 +272,9 @@ 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.非带有?号等参数的图片
@ -275,13 +283,13 @@ abstract class BaseController
//下载远程图片(可下载)
$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;
}
/**

View File

@ -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]);
}
}

View File

@ -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]);
}
}
/**
* 上传接口
*

View File

@ -58,6 +58,9 @@
<i class="layui-icon layui-icon-delete"></i>
删除
</button>
<button class="pear-btn layui-bg-orange pear-btn-md" lay-event="checkSelect">
批量审核
</button>
</script>
@ -125,6 +128,8 @@
window.refresh();
} else if (obj.event === 'batchRemove') {
window.batchRemove(obj);
} else if (obj.event === 'checkSelect') {
window.checkSelect(obj);
}
});
@ -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');
}

View File

@ -77,6 +77,9 @@
<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">
@ -176,6 +179,7 @@
});
});
}
getSelectCate();
table.on('tool(forum-table)', function(obj) {
@ -193,6 +197,8 @@
window.refresh();
} else if (obj.event === 'batchRemove') {
window.batchRemove(obj);
} else if (obj.event === 'checkSelect') {
window.checkSelect(obj);
}
});
@ -239,8 +245,8 @@
});
});
// 添加
window.add = function() {
layer.open({
type: 2,
title: '新增',
@ -261,7 +267,6 @@
}
window.remove = function(obj) {
layer.confirm('确定要删除?', {
icon: 3,
title: '提示'
@ -292,6 +297,7 @@
});
}
// 批量删除
window.batchRemove = function(obj) {
var checkIds = common.checkField(obj,'id');
if (checkIds === "") {
@ -333,6 +339,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.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');
}

View File

@ -81,7 +81,7 @@
</button>
</script>
<script type="text/html" id="imgTpl">
<a href="{:url('user.user/goUserHome')}?id={{ d.id }}" target="_blank"><img src= {{=d.avatar}} style="width: 100px; height: 100px; border-radius: 6px;" /></a>
<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>

View File

@ -29,10 +29,9 @@
<option value="3">L3</option>
<option value="4">L4</option>
<option value="5">L5</option>
</select>
</div>
<div class="layui-input-block">
<div class="layui-input-inline">
<input type="text" name="score" lay-verify="required" placeholder="积分区间:0-99" autocomplete="off" class="layui-input">
</div>
@ -54,7 +53,7 @@
<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>
</div>

View File

@ -99,6 +99,8 @@ class BaseController extends BaseCtrl
if(!$user){
//1.查询用户
$user = Db::name('user')->field('id,name,nickname,user_img,sex,area_id,auth,city,phone,email,active,sign,point,vip,create_time')->find($id);
$vipNick = Db::name('user_viprule')->field('nick')->where('vip', $user['vip'] ?? 0)->value('nick');
$user['nick'] = $vipNick;
Cache::tag('user')->set('user'.$id, $user, 600);
}
return $user;

View File

@ -275,6 +275,7 @@ class Article extends Model
->where(['user_id' => $id,'status' => 1])
->order(['create_time'=>'desc'])
->append(['url'])
->limit(25)
->cache(3600)
->select()
->toArray();
@ -298,6 +299,7 @@ class Article extends Model
->order('create_time','desc')
->append(['url'])
->paginate(10);
return $res;
}
}

View File

@ -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
{

View File

@ -262,14 +262,19 @@ class Article extends BaseController
$cateName = Db::name('cate')->field('ename,appname')->find($data['cate_id']);
// vip每天可免费发帖数
$user = Db::name('user')->field('id,vip,point')->find($this->uid);
$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) {
//额度已用完需要扣积分
@ -281,6 +286,7 @@ class Article extends BaseController
// 2.扣除积分
Db::name('user')->where('id', $this->uid)->update(['point' => $point]);
}
}
$result = $this->model->add($data);
if ($result['code'] == 1) {

View File

@ -127,7 +127,8 @@ class User extends BaseController
$count = count($idArr);
// vip每天可刷新数
$user = Db::name('user')->field('id,vip,point')->find($this->uid);
$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();
@ -135,6 +136,8 @@ class User extends BaseController
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.免费额已用完 后面需要积分
@ -160,6 +163,7 @@ class User extends BaseController
}
}
}
}
// 刷新数据
$res = Db::name('article')->where('id', 'in', $idArr)->update(['update_time' => time()]);
@ -302,6 +306,7 @@ class User extends BaseController
->where(['a.delete_time'=>0,'c.delete_time'=>0,'c.status'=>1])
->where('c.user_id',$id)
->order(['c.create_time'=>'desc'])
->limit(10)
->cache(3600)->select();
View::assign(['u'=>$u,'arts'=>$arts,'reys'=>$reys,'jspage'=>'']);

View File

@ -16,7 +16,7 @@ return [
// 应用名,此项不可更改
'appname' => 'TaoLer',
// 版本配置
'version' => '2.5.0',
'version' => '2.5.2',
// 加盐
'salt' => 'taoler',
// 数据库备份目录

View File

@ -191,7 +191,7 @@ 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 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;}
@ -601,6 +601,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)}
}
@ -618,7 +622,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}

View File

@ -18,7 +18,7 @@
<div class="layui-container">
<div class="layui-row layui-col-space15">
<div class="layui-col-md8 content detail">
<div class="fly-panel detail-box">
<section class="fly-panel detail-box">
{//标题}
<h1>{article:title /}</h1>
@ -28,7 +28,7 @@
<img src="{article:user name='user_img' /}" alt="{article:user name='name' /}" />
<cite>{article:auther} </cite>
</a>
<span class="user-post-time" data="{$article.create_time}" style="padding-top: 5px">{$article.create_time|date="Y-h-d H:i"}</span>
<span class="user-post-time" data="{$article.create_time}" style="padding-top: 5px">{$article.update_time|date="Y-h-d H:i"}</span>
<i class="iconfont" title="{:lang('reply')}">&#xe60c;</i>
{$article:comments_count}
<i class="iconfont" title="浏览">&#xe60b;</i>
@ -47,7 +47,7 @@
<div style="margin: 10px 0; font-size: 16px; font-weight: bold; color: rgb(161, 155, 155)">问题描述:</div>
{:hook('taoplayerdiv')}
<div class="detail-body photos" id="content">{article:content}</div>
<article class="detail-body photos" id="content">{article:content}</article>
{notempty name="$article.upzip"}
{if (session('?user_name'))}
<button type="button" class="layui-btn layui-btn-xs" id="zip-download"><i class="layui-icon layui-icon-download-circle"></i>{:lang('download files')}: {$article.downloads}次</button>
@ -79,10 +79,10 @@
{$Request.domain}/{$Request.url}
</a>
</div>
</div>
</section>
{//评论内容}
<div class="fly-panel detail-box" id="flyReply">
<section class="fly-panel detail-box" id="flyReply">
<span style="font-size:18px;">评论 {$article.comments_count}</span>
<ul class="jieda" id="jieda">
@ -199,7 +199,7 @@
{/article:comment}
</ul>
<div style="text-align: center" id="pages"></div>
</div>
</section>
{//评论区}
{if session('?user_id') AND ( config('taoler.config.is_reply') == 1 ) AND ( $article.is_reply == 1 )}

View File

@ -41,7 +41,7 @@
<div class="d-inline-block" itemprop="author" itemscope="" itemtype="">
<a href="{$Request.domain}" target="_blank" class="text-muted" itemprop="url"><span itemprop="name">{article:auther}</span></a>
<a href="{article:cate name='link'}" target="_blank" class="text-muted" rel="category">{article:cate name="name"}</a>
<time class="d-inline-block" datetime="{$article.create_time|date='Y-m-d h:m:s'}" itemprop="datePublished">{article:time}</time>
<time class="d-inline-block" datetime="{$article.create_time|date='Y-m-d h:m:s'}" itemprop="datePublished">{article:uptime}</time>
</div>
<div class="ml-auto text-sm yincang">
<span class="mx-1"><small>阅读 {article:pv /} 次</small></span>

View File

@ -25,7 +25,7 @@
<div class="detail-hits" style="left:-30px;">
<span>{$article.cate.catename}</span>
<span>{$article.user.name}</span>
<span class="post-time" style="padding-top: 5px;" data="{$article.create_time}">{$article.create_time} </span>
<span class="post-time" style="padding-top: 5px;" data="{$article.update_time}">{article:uptime} </span>
<span><i class="iconfont" title="浏览">&#xe60b;</i> {article:pv}</span>
</div>
</div>

View File

@ -19,7 +19,7 @@
<div class="layui-container">
<div class="layui-row layui-col-space15">
<div class="layui-col-md8 content detail">
<div class="fly-panel detail-box">
<section class="fly-panel detail-box">
{//标题}
<h1>{article:title /}</h1>
@ -60,7 +60,7 @@
<a href="{article:user name='link' /}" class="fly-link"><cite>{article:auther}</cite></a>
</div>
<div class="detail-hits">
<span class="post-time" data="{$article.create_time}" style="padding-top: 5px;">{$article.create_time}</span>
<span class="post-time" data="{$article.update_time}" style="padding-top: 5px;">{article:uptime}</span>
{:hook('ipShow',$article.user.city)}
</div>
</div>
@ -68,7 +68,7 @@
{//内容}
{:hook('taoplayerdiv')}
<div class="detail-body photos" id="content">{article:content}</div>
<article class="detail-body photos" id="content">{article:content}</article>
{//下载}
{notempty name="$article.upzip"}
{if(session('?user_name'))}
@ -107,10 +107,10 @@
<span><img src="{$vo.userImg}"></span>
{/volist}
</div>
</div>
</section>
{//评论}
<div class="fly-panel">
<section class="fly-panel">
{if session('?user_id') AND ( config('taoler.config.is_reply') == 1 ) AND ( $article.is_reply == 1 )}
<div class="layui-form layui-form-pane">
<div class="layui-form-item layui-form-text">
@ -125,7 +125,7 @@
</div>
</div>
{/if}
</div>
</section>
{//评论内容}
<div class="fly-panel detail-box" id="flyReply">

View File

@ -1,6 +1,6 @@
<div class="fly-header layui-bg-black">
<div class="layui-container">
<a class="fly-logo layui-hide-xs" href="{$Request.domain}"><img src="{$Request.domain}{$sysInfo.logo}" alt="{system:webname}logo"></a>
<a class="fly-logo layui-hide-xs" href="{$Request.domain}"><img src="{$Request.domain}/{$sysInfo.logo}" alt="{system:webname}logo"></a>
<!--头部伸缩侧边栏-->
<div class="site-tree-mobile-top layui-hide"><i class="layui-icon layui-icon-spread-left"></i></div>
<div class="site-mobile-shade-top"></div>
@ -37,7 +37,7 @@
<li class="layui-nav-item"><a href="{$Request.domain}">{:lang('home page')}</a></li>
{/if}
<li class="layui-nav-item">
<a class="fly-nav-avatar" ><cite class="layui-hide-xs">{$user.name}</cite><img src="{$Request.domain}{$user.user_img}"></a>
<a class="fly-nav-avatar" ><cite class="layui-hide-xs">{$user.name}</cite><img src="{$Request.domain}/{$user.user_img}"></a>
<dl class="layui-nav-child">
<dd><a href="{:url('user/index')}"><i class="layui-icon layui-icon-username"></i>{:lang('user center')}</a></dd>
<dd><a href="{:url('user/set')}"><i class="layui-icon layui-icon-set"></i>{:lang('set info')}</a></dd>

View File

@ -1,3 +1,4 @@
{if $Request.isMobile}
<div class="layui-panel site-menu layui-hide-md">
<ul class="layui-menu layui-menu-lg">
<li class="search" style="padding-left:5px;padding-top:2px;padding-right:5px;">
@ -69,6 +70,6 @@
</li>
</ul>
</div>
{/if}

View File

@ -33,6 +33,7 @@
</div>
{include file="public/footer" /}
<script>
var $ = layui.jquery;
var notify = layui.notify;
layui.cache.page = 'user';
layui.cache.user = {
@ -48,7 +49,6 @@
}).extend({
fly: 'index'
}).use('fly');
var $ = layui.jquery;
var articleUrl = "{:url('user/article')}";
artListUrl = "{:url('User/artList')}",
collListUrl = "{:url('User/collList')}",

View File

@ -14,14 +14,14 @@
{block name="column"}{/block}
{block name="content"}
<div class="fly-home fly-panel" >
<img src="{$Request.domain}{$u.user_img}" alt="{$u.name}">
<img src="{$Request.domain}/{$u.user_img}" alt="{$u.name}">
{if($u.vip > 0)}<i class="iconfont icon-renzheng" title="Fly社区认证"></i>{/if}
<h1>
{$u.nickname ?: $u.name}
{if($u.sex==0)}<i class="iconfont icon-nan"></i>
{else}<i class="iconfont icon-nv"></i> {/if}
{if($u.vip > 0)}
<i class="layui-badge fly-badge-vip">VIP{$u.vip}</i>
<i class="layui-badge fly-badge-vip">{$u.vip}</i>
{/if}
<!--
<span style="color:#c00;">(管理员)</span>
@ -82,17 +82,4 @@
{/block}
{block name="script"}
<script>
layui.use(['fly','face'], function(){
var $ = layui.$;
var fly = layui.fly;
var face = layui.face;
//如果你是采用模版自带的编辑器,你需要开启以下语句来解析。
$('.detail-body').each(function(){
var othis = $(this), html = othis.html();
othis.html(fly.content(html));
});
});
</script>
{/block}

View File

@ -22,7 +22,7 @@
<div class="layui-col-md6">
<div class="fly-panel fly-panel-border"> <div class="fly-panel-title"> 我的会员信息 </div>
<div class="fly-panel-main layui-text" style="padding: 18px 15px; height: 50px; line-height: 26px;">
<p>您的财富经验值:<span style="color: red">{$user.point}</span> 金币</p> <p>您当前为:<span style="color: red">VIP{$user.vip}</span></p> </div> </div> </div>
<p>您的财富经验值:<span style="color: red">{$user.point}</span> 金币</p> <p>您当前为:<span style="color: red">{$user.nick}</span></p> </div> </div> </div>
<div class="layui-col-md12" style="margin-top: -20px;">
<div class="fly-panel fly-panel-border"> <div class="fly-panel-title"> 快捷方式 </div>
<div class="fly-panel-main">