提交 3bd4af3d 编写于 作者: 街头小贩's avatar 街头小贩

增加版块话题未读数量推送

上级 7f63b250
......@@ -574,7 +574,16 @@ public class TopicDaoImpl implements TopicDao{
.setParameter(3, LocalDateTime.now())
.getResultStream();
}
@Override
public long findAllRecentByBoardSize(long boardId, LocalDateTime prevDate) {
return entityManager.createQuery("SELECT COUNT(t) FROM Topic t WHERE t.boardId = ?1 AND t.entryDateTime BETWEEN ?2 AND ?3", Long.class)
.setParameter(1, boardId)
.setParameter(2, prevDate)
.setParameter(3, LocalDateTime.now())
.getSingleResult();
}
@Override
public Stream<Topic> findAllByBoardOfTop(long boardId) {
return entityManager.createQuery("SELECT t FROM Topic t WHERE t.boardId = ?1 AND t.tops = ?2 AND t.status != ?3 ORDER BY t.id DESC", Topic.class)
......
......@@ -711,7 +711,13 @@ public class TopicServiceImpl implements TopicService{
logger.info(String.format("[TS]calc localdate:%s", DateTimeUtils.getRFC3339(prevDate)));
return associationTopicStatsAsync(topicDao.findAllRecentByBoard(boardId, prevDate).collect(Collectors.toList())).collect(Collectors.toList());
}
@Override
public long getRecentByUnixStampSize(long boardId, int prevUnixStamp) {
LocalDateTime prevDate = DateTimeUtils.getDateTimeByUnixTimestamp(prevUnixStamp);
return topicDao.findAllRecentByBoardSize(boardId, prevDate);
}
@Override
public Optional<TopicReplica> getTopicContentAndStats(final long id, final ImageIOMeta imageIO){
CompletableFuture<PostsReplica> oneFloor = CompletableFuture.supplyAsync(()->postsDao.findOneByTopicId(id).map(PostsReplica.copyPosts).orElse(null))
......
......@@ -203,7 +203,16 @@ public interface TopicDao extends PagingAndSortingRepository<Topic, Long> {
* @return
*/
Stream<Topic> findAllRecentByBoard(long boardId, LocalDateTime prevDate);
/**
* 自参考日期以后版块最近话题的数量
*
* @param boardId 版块ID
* @param prevDate 参考日期
* @return
*/
long findAllRecentByBoardSize(long boardId, LocalDateTime prevDate);
/**
* 查看指定版块置顶的话题,不包括删除的
*
......
......@@ -528,7 +528,16 @@ public interface TopicService {
* @return
*/
List<TopicReplica> getRecentByUnixStamp(long boardId, int prevUnixStamp);
/**
* 自参考日期以后版块最近的话题数量
*
* @param boardId 版块ID
* @param prevUnixStamp 参考日期
* @return
*/
long getRecentByUnixStampSize(long boardId, int prevUnixStamp);
/**
* [Cacheable]查看指定的话题
*
......
......@@ -10,6 +10,7 @@ import com.apobates.forum.core.entity.ForumEntityStatusEnum;
import com.apobates.forum.core.entity.Topic;
import com.apobates.forum.core.entity.TopicCategory;
import com.apobates.forum.core.entity.proxy.BoardGroupReplica;
import com.apobates.forum.core.entity.proxy.TopicReplica;
import com.apobates.forum.core.service.AlbumPictureService;
import com.apobates.forum.core.service.AlbumService;
import com.apobates.forum.core.service.BoardGroupService;
......@@ -316,4 +317,25 @@ public class LazyLoadController {
Map<Long, String> result = albumService.getAll(topicIdSet, imageIOMeta, scale, "/static/img/140x140.png").collect(Collectors.toMap(Album::getTopicId, Album::getCoverLink));
return callBackFun + "(" + new Gson().toJson(result) + ");";
}
//查看指定参考日期以来的新话题
@GetMapping(path = "/board/topic/recent.json", produces = "application/json;charset=UTF-8")
@ResponseBody
public String getRecentByPrevStamp(
@RequestParam("id") String boardIdString,
@RequestParam("stamp") String refDateStamp,
HttpServletRequest request,
Model model){
long boardId = Commons.stringToLong(boardIdString, 0L);
int previousUx = Commons.stringToInteger(refDateStamp, 0);
if(boardId == 0 || previousUx == 0){
return "{}";
}
List<TopicReplica> rs = topicService.getRecentByUnixStamp(boardId, previousUx);
if (null == rs || rs.isEmpty()) {
return "{}";
}
List<ForumThreads> data = rs.stream().map(ForumThreads::new).collect(Collectors.toList());
return new Gson().toJson(data);
}
}
\ No newline at end of file
package com.apobates.forum.thrones.controller.helper;
import com.apobates.forum.core.entity.proxy.TopicReplica;
import com.apobates.forum.core.service.PostsService;
import com.apobates.forum.core.service.TopicService;
import com.apobates.forum.thrones.vo.ForumThreads;
import com.apobates.forum.utils.Commons;
......@@ -26,15 +25,11 @@ import org.springframework.web.socket.handler.TextWebSocketHandler;
public class TopicSocketUpdatedHandler extends TextWebSocketHandler {
@Autowired
private TopicService topicService;
@Autowired
private PostsService postsService;
private final static Logger logger = LoggerFactory.getLogger(TopicSocketUpdatedHandler.class);
//周期性的?步进式的
@Override
protected void handleTextMessage(WebSocketSession session, TextMessage message) {
//{"id":"boardId", "ux":"previousUx","cmd":"topic_list"}//1
//{"id":"topicId", "ux":"previousUx","cmd":"posts_list"}//2
String cmdMsg = message.getPayload();
logger.info("[TopicUpdated]sock.js cmd: " + cmdMsg);
......@@ -45,13 +40,15 @@ public class TopicSocketUpdatedHandler extends TextWebSocketHandler {
cmdSybol = jsonData.get("cmd");
} catch (NullPointerException e) {
}
if (cmdSybol == 1) {
//{"id":"boardId", "ux":"previousUx","cmd":"topic_list"}
if (cmdSybol == 1) { //推消息
responseData = boardUpdatedTopic(jsonData.get("id"), jsonData.get("ux").intValue());
}
//if (cmdSybol == 2) {
// responseData = topicUpdatedPostes(jsonData.get("id"), jsonData.get("ux").intValue());
//}
if (cmdSybol == 2) { //推消息数量
long unknown = topicService.getRecentByUnixStampSize(jsonData.get("id"), jsonData.get("ux").intValue());
Map<String,String> data = Map.of("id", jsonData.get("id")+"", "ux", jsonData.get("ux")+"", "size", unknown+"");
responseData = Commons.toJson(data);
}
//
if (null == responseData) {
return;
......
......@@ -99,6 +99,9 @@
</ul>
</div>
<!-- 置顶话题结束 -->
<!-- 未读话题数量提示开始 -->
<div id="unknow_topic_tip" style="display: none;">&nbsp;</div>
<!-- 未读话题数量提示结束 -->
<div role="separator" class="divider" style="height:1px;">&nbsp;</div>
<!-- 话题列表开始 -->
<ul class="board_list_header mb20" data-board="${board.id}" id="board_topic_collect" data-socket-uri="${BASE}/sock/updated"></ul>
......
......@@ -75,6 +75,21 @@
</div>
</div>
<!-- 顶部功能区结束 -->
<!-- 置顶的滚动层开始 -->
<div class="row m-0">
<nav id="scroll-top-section" class="navbar-fixed-top" style="display:none">
<div id="scroll-top-section-bar" style="display:flex;flex-wrap:wrap;width:1110px">
<div class="col-md-9" style="overflow:hidden;text-overflow: ellipsis;height:50px;"><h5 style="line-height: 50px;">${topic.title}</h5></div>
<div class="col-md-3">
<div class="float-right" style="margin-top:5px">
<a class="btn btn-danger action-cmd favorite-topic" role="button" href="javascript:;" data-handler="${BASE}/topic/favorite?id=${topic.id}"><i class="ico-sm mdi mdi-favorite" aria-hidden="true"></i> 收藏</a> &nbsp;
<a class="btn btn-primary" role="button" href="${BASE}/posts/create?volumes=${topic.volumesId}&board=${topic.boardId}&topic=${topic.id}">回复 <i class="ico-sm mdi mdi-mail-reply"></i></a>
</div>
</div>
</div>
</nav>
</div>
<!-- 置顶的滚动层结束 -->
<!-- 回复区段开始 -->
<div id="topic_posts_collect" class="mb20">
<div class="topic_posts">
......
......@@ -68,7 +68,7 @@ dt{font-weight:500}
.posts-buttons a {display: block;float: right;height: 33px;line-height: 33px;position: relative;text-align: center;width: 33px;transition: color 0.1s ease-in-out, background-color 0.1s ease-in-out;}
.posts-buttons span {height: 33px;opacity: 0;padding: 0 10px;pointer-events: none;position: absolute;right: 33px;top: 0;transition: opacity 0.1s ease-in-out 0s;white-space: nowrap;}
.posts-buttons a:hover span {opacity: 1;}
.posts-member{height:50px;padding-top: 30px;}#scroll-top-section-bar{-moz-box-shadow:0px 5px 3px rgba(26,26,26,.1); -webkit-box-shadow: 0 5px 3px rgba(26,26,26,.1);box-shadow: 0 5px 3px rgba(26,26,26,.1);}
.posts-member{height:50px;padding-top: 30px;}.navbar-fixed-top{position:fixed;top:0;z-index:9999;}#scroll-top-section-bar{-moz-box-shadow:0px 5px 3px rgba(26,26,26,.1); -webkit-box-shadow: 0 5px 3px rgba(26,26,26,.1);box-shadow: 0 5px 3px rgba(26,26,26,.1);}
.relate_topic p{line-height:45px;margin:0;padding:0;text-indent:20px}
.relate_topic li{list-style:none;margin:0;padding:0;line-height:35px;height:35px;width:49.888%;display:inline-block;text-indent:20px;text-overflow:ellipsis;overflow:hidden;white-space:nowrap;}
#topic_tages{margin-bottom:15px}
......@@ -77,6 +77,8 @@ dt{font-weight:500}
#topic_tages a, #topic_tages label{border-radius: 2px;}
.mood-action span {text-indent: 5px;display: inline-block;}
.div-select{border-width: 1px;border-style:solid;padding: 5px 8px;margin-bottom: 0;border-radius: .2rem;margin-top: 0;text-indent:.5rem;cursor:pointer;}
#unknow_topic_tip{margin:0;border:0;border-radius:0;text-align:center;line-height:50px;position:relative}
/*底部统计*/
#footer{color: #fff;width: 100%;height:100px;position: relative;clear:both}.social-tooltip{width:50px;height:50px;line-height:50px;text-align:center;display:inline-block;color:#666;}.social-tooltip:hover{background-color:#000;color:#fff}
.stat-block {box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05), 0 1px 0 rgba(0, 0, 0, 0.05);}
......@@ -359,6 +361,7 @@ body.jetblack{background-color:#272b30}
.jetblack .fav-board-item{border: 1px solid #666;}
.jetblack .fav-board-stats {border-top: 1px solid #666;color:#999}
.jetblack .div-select{border-color:#666;background-color:#272b2e;color: #999;}
.jetblack #unknow_topic_tip{background-color:#32383e!important;color:#e1e1e1!important}
/*推送|置顶的样式*/
.jetblack .fadeout-anim {
background:#1c1e22;
......@@ -451,6 +454,7 @@ body.snowhite{background-color:#f2f2f2!important}
.snowhite .fav-board-item{border: 1px solid #ddd;}
.snowhite .fav-board-stats {border-top: 1px solid #ddd;color:#333}
.snowhite .div-select{border-color:#ddd;background-color:#fff;color: #666;}
.snowhite #unknow_topic_tip{background-color:#e1e1e1!important}
/*推送|置顶的样式*/
.snowhite .fadeout-anim {
background:#fff;
......
......@@ -259,7 +259,8 @@ define('jForum', [
// 版块最新的话题
$('#board_topic_collect').on('loadDataEvent', function (e) {
var _k = $(e.target);
threadsPushHandler(_k);
//threadsPushHandler(_k);
threadSizePushHandler(_k);
}).trigger('loadDataEvent');
//提示
$('[data-toggle="tooltip"]').tooltip();
......@@ -284,6 +285,31 @@ define('jForum', [
event.preventDefault();
$(this).ekkoLightbox({ alwaysShowClose: true });
});
//查看未知的新话题@20201015
$('#unknow_topic_tip').on('click', 'a', function(event){
event.preventDefault();
var _tt = $(this);
var reqData = {};
reqData.id = _tt.attr('data-board');
reqData.stamp = _tt.attr('data-stamp');
console.log(reqData);
xhr.jsonGet(BASE+'/loader/board/topic/recent.json', {data: reqData}).done(function (data) {
//?
if ($.isEmptyObject(data)) {
return;
}
//?
_tt.parent().slideDown(1000, 'linear', function(){
$(this).html('');
});
//?
$('#board_topic_collect').attr('data-ux', util.getUnixStamp());
var _l = template;
$.each(data, function (index, item) {
_l.drawUpdatedTopics(item, 'board_topic_collect', true);
});
});
});
//侧边栏的工具按钮
$('#sideTool').sideToolBar();
//加载今天的公告
......@@ -349,6 +375,7 @@ define('jForum', [
}
});
};
//未知的新话题
function threadsPushHandler(_k) {
_k.attr('data-ux', util.getUnixStamp()); //一开始的时间戳
try {
......@@ -368,6 +395,44 @@ define('jForum', [
}
} catch (e) { console.log('thread socket file lost'); }
}
//未知的新话题数量@20201015
function threadSizePushHandler(_k) {
_k.attr('data-ux', util.getUnixStamp()); //一开始的时间戳
try {
if (_k.attr('data-socket-uri') && _k.attr('data-board')) {
var _st = new socket(_k.attr('data-socket-uri'), _k, {
sendDataFun: function (jqEle) {
var data = {};
data.id = jqEle.attr('data-board');
data.cmd = 2;
data.ux = jqEle.attr('data-ux');
return data;
},
callbackFun: updateunKnowThreadSize
});
_st.init('ThreadsNotice');
_st.start(60000);
}
} catch (e) { console.log('thread socket file lost'); }
}
//新话题数量推送回调
function updateunKnowThreadSize(sockplaindata){
var jsonObj = $.parseJSON(sockplaindata);
if ($.isEmptyObject(jsonObj)) {
return;
}
if(!jsonObj.size || parseInt(jsonObj.size) == 0){
return;
}
if($('#unknow_topic_tip').find('span').length == 1){ //已经有提示消息了
return;
}
$('#unknow_topic_tip').html('<span>新话题已经赶来了, <a href="javascript:;" data-stamp="%STAMP%" data-board="%ID%">点击查看</a></span>'
.replace('%STAMP%', jsonObj.ux)
.replace('%ID%', jsonObj.id)).slideDown(1000, 'linear', function(){
$(this).show();
});
}
//新话题列表推送回调
function updateNewsTopices(sockplaindata) {
var jsonArray = $.parseJSON(sockplaindata);
......@@ -424,6 +489,7 @@ define('jForum', [
_self.append(eleBox);
return this;
};
//右侧边栏的工具栏
$(window).on('scroll', function (e) {
if ($(this).scrollTop() > 200) {
$('#topTopBar').fadeIn(500);
......
......@@ -369,6 +369,16 @@ define('jForumThreads', [
//
xhr.action(rawdata.uri, rawdata.callFun, rawdata.data, false, _j);
});
//话题内容页中顶部的固定
$(document).scroll(function() {
var scroH = $(document).scrollTop(); //滚动高度
if(scroH < 300){
$('#scroll-top-section').hide();
}
if(scroH > 300){
$('#scroll-top-section').show();
}
});
}
return { init: init };
})();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册