Merge branch 'dev'

This commit is contained in:
fanxb 2020-05-12 13:48:56 +08:00
commit 41311e9385
14 changed files with 149 additions and 54 deletions

View File

@ -21,6 +21,7 @@ import java.util.stream.Collectors;
* Created By Fxb * Created By Fxb
* Date: 2020/3/29 * Date: 2020/3/29
* Time: 11:34 * Time: 11:34
* @author fanxb
*/ */
@MqConsumer(RedisConstant.BOOKMARK_INSERT_ES) @MqConsumer(RedisConstant.BOOKMARK_INSERT_ES)
public class BookmarkInsertEsConsumer implements RedisConsumer { public class BookmarkInsertEsConsumer implements RedisConsumer {

View File

@ -0,0 +1,41 @@
package com.fanxb.bookmark.business.bookmark.consumer;
import com.alibaba.fastjson.JSON;
import com.fanxb.bookmark.business.bookmark.dao.BookmarkDao;
import com.fanxb.bookmark.business.bookmark.entity.redis.VisitNumPlus;
import com.fanxb.bookmark.common.annotation.MqConsumer;
import com.fanxb.bookmark.common.constant.RedisConstant;
import com.fanxb.bookmark.common.entity.redis.RedisConsumer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
/**
* 更新书签时间
* Created with IntelliJ IDEA
* Created By Fxb
* Date: 2020/5/12
* Time: 10:33
*
* @author fanxb
*/
@MqConsumer(RedisConstant.BOOKMARK_VISIT_NUM_PLUS)
@Slf4j
public class BookmarkVisitNumPlusConsumer implements RedisConsumer {
private final BookmarkDao bookmarkDao;
@Autowired
public BookmarkVisitNumPlusConsumer(BookmarkDao bookmarkDao) {
this.bookmarkDao = bookmarkDao;
}
@Override
public void deal(String message) {
VisitNumPlus item = JSON.parseObject(message, VisitNumPlus.class);
try {
bookmarkDao.updateVisitNum(item);
} catch (Exception e) {
log.error("书签访问次数增加失败:{}", e.getMessage());
}
}
}

View File

@ -161,4 +161,18 @@ public class BookmarkController {
return Result.success(null); return Result.success(null);
} }
/**
* 功能描述: 书签增加1
*
* @param id id
* @return com.fanxb.bookmark.common.entity.Result
* @author fanxb
* @date 2020/5/12 10:44
*/
@PostMapping("/visitNum")
public Result visitNum(int id) {
bookmarkService.visitNumPlus(id);
return Result.success(null);
}
} }

View File

@ -2,6 +2,7 @@ package com.fanxb.bookmark.business.bookmark.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.fanxb.bookmark.business.bookmark.entity.BookmarkEs; import com.fanxb.bookmark.business.bookmark.entity.BookmarkEs;
import com.fanxb.bookmark.business.bookmark.entity.redis.VisitNumPlus;
import com.fanxb.bookmark.common.entity.Bookmark; import com.fanxb.bookmark.common.entity.Bookmark;
import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select; import org.apache.ibatis.annotations.Select;
@ -24,7 +25,6 @@ public interface BookmarkDao extends BaseMapper<Bookmark> {
* Description: 插入一条书签记录 * Description: 插入一条书签记录
* *
* @param node node * @param node node
* @return void
* @author fanxb * @author fanxb
* @date 2019/7/8 16:49 * @date 2019/7/8 16:49
*/ */
@ -189,9 +189,20 @@ public interface BookmarkDao extends BaseMapper<Bookmark> {
* *
* @param size 大小 * @param size 大小
* @param startIndex 开始下标 * @param startIndex 开始下标
* @return * @return bookmark List
* @author fanxb
*/ */
@Select("select * from bookmark order by bookmarkId limit ${startIndex},${size}") @Select("select * from bookmark order by bookmarkId limit ${startIndex},${size}")
List<Bookmark> getBookmarkListPage(@Param("size") int size, @Param("startIndex") int startIndex); List<Bookmark> getBookmarkListPage(@Param("size") int size, @Param("startIndex") int startIndex);
/**
* 功能描述: 书签访问次数+1
*
* @param item 信息
* @author fanxb
* @date 2020/5/12 10:40
*/
@Update("update bookmark set visitNum=visitNum+1 where userId=#{userId} and bookmarkId=#{bookmarkId}")
void updateVisitNum(VisitNumPlus item);
} }

View File

@ -0,0 +1,23 @@
package com.fanxb.bookmark.business.bookmark.entity.redis;
import lombok.AllArgsConstructor;
import lombok.Data;
/**
* Created with IntelliJ IDEA
*
* @author fanxb
* Date: 2020/5/12 11:47
*/
@Data
@AllArgsConstructor
public class VisitNumPlus {
/**
* 用户id
*/
private int userId;
/**
* 书签id
*/
private int bookmarkId;
}

View File

@ -98,8 +98,18 @@ public interface BookmarkService {
* *
* @param userId userId * @param userId userId
* @param context context * @param context context
* @return es搜索结果
* @author fanxb * @author fanxb
* @date 2019/7/25 10:45 * @date 2019/7/25 10:45
*/ */
List<BookmarkEs> searchUserBookmark(int userId, String context); List<BookmarkEs> searchUserBookmark(int userId, String context);
/**
* 功能描述: 当前用户书签访问次数+1
*
* @param id 书签id
* @author fanxb
* @date 2020/5/12 10:21
*/
void visitNumPlus(int id);
} }

View File

@ -1,8 +1,10 @@
package com.fanxb.bookmark.business.bookmark.service.impl; package com.fanxb.bookmark.business.bookmark.service.impl;
import com.alibaba.fastjson.JSON;
import com.fanxb.bookmark.business.bookmark.dao.BookmarkDao; import com.fanxb.bookmark.business.bookmark.dao.BookmarkDao;
import com.fanxb.bookmark.business.bookmark.entity.BookmarkEs; import com.fanxb.bookmark.business.bookmark.entity.BookmarkEs;
import com.fanxb.bookmark.business.bookmark.entity.MoveNodeBody; import com.fanxb.bookmark.business.bookmark.entity.MoveNodeBody;
import com.fanxb.bookmark.business.bookmark.entity.redis.VisitNumPlus;
import com.fanxb.bookmark.business.bookmark.service.BookmarkService; import com.fanxb.bookmark.business.bookmark.service.BookmarkService;
import com.fanxb.bookmark.business.bookmark.service.PinYinService; import com.fanxb.bookmark.business.bookmark.service.PinYinService;
import com.fanxb.bookmark.common.constant.EsConstant; import com.fanxb.bookmark.common.constant.EsConstant;
@ -239,6 +241,12 @@ public class BookmarkServiceImpl implements BookmarkService {
return esUtil.search(EsConstant.BOOKMARK_INDEX, builder, BookmarkEs.class); return esUtil.search(EsConstant.BOOKMARK_INDEX, builder, BookmarkEs.class);
} }
@Override
public void visitNumPlus(int id) {
VisitNumPlus item = new VisitNumPlus(UserContextHolder.get().getUserId(), id);
RedisUtil.addToMq(RedisConstant.BOOKMARK_VISIT_NUM_PLUS, JSON.toJSONString(item));
}
/** /**
* 功能描述: 向mq发送消息通知数据更新 * 功能描述: 向mq发送消息通知数据更新
* *

View File

@ -75,9 +75,9 @@ public class MqConfiguration implements ApplicationRunner {
} }
}); });
if (count.get() == topicMap.keySet().size()) { if (count.get() == topicMap.keySet().size()) {
//当所有的队列都为空时休眠1s //当所有的队列都为空时休眠3s
try { try {
TimeUnit.SECONDS.sleep(1); TimeUnit.SECONDS.sleep(3);
} catch (Exception e) { } catch (Exception e) {
log.error("休眠出错", e); log.error("休眠出错", e);
} }

View File

@ -27,4 +27,8 @@ public class RedisConstant {
* 从es中删除数据 * 从es中删除数据
*/ */
public static final String BOOKMARK_DELETE_ES = "bookmark_DELETE_es"; public static final String BOOKMARK_DELETE_ES = "bookmark_DELETE_es";
/**
* 书签访问次数+1
*/
public static final String BOOKMARK_VISIT_NUM_PLUS = "bookmark_visit_num_plus";
} }

View File

@ -40,6 +40,10 @@ public class Bookmark {
private String searchKey = ""; private String searchKey = "";
private Long addTime; private Long addTime;
private Long createTime; private Long createTime;
/**
* 访问次数
*/
private int visitNum;
private List<Bookmark> children; private List<Bookmark> children;
public Bookmark() { public Bookmark() {

View File

@ -0,0 +1 @@
ALTER TABLE `bookmark`.`bookmark` ADD COLUMN `visitNum` int(0) UNSIGNED NOT NULL DEFAULT 0 COMMENT '访问次数' AFTER `createTime`;

View File

@ -0,0 +1,2 @@
ALTER TABLE `bookmark`.`bookmark`
ADD INDEX `userId_bookmarkId_index`(`userId`, `bookmarkId`) USING BTREE;

View File

@ -1,17 +1,18 @@
import React from "react"; import React from 'react';
import { Input, Select, Empty } from "antd"; import { Input, Select, Empty } from 'antd';
import styles from "./index.module.less"; import styles from './index.module.less';
import { keySearch } from "../../util/cacheUtil"; import { keySearch } from '../../util/cacheUtil';
import httpUtil from '../../util/httpUtil';
class Search extends React.Component { class Search extends React.Component {
constructor(props) { constructor(props) {
super(props); super(props);
this.state = { this.state = {
content: "", content: '',
currentIndex: 0, currentIndex: 0,
isFocus: false, isFocus: false,
resultList: [], resultList: [],
options: ["书签", "百度", "谷歌"], options: ['书签', '百度', '谷歌'],
currentOptionIndex: 0 currentOptionIndex: 0
}; };
} }
@ -63,28 +64,25 @@ class Search extends React.Component {
this.setState({ resultList, currentIndex: 0 }); this.setState({ resultList, currentIndex: 0 });
} }
goTo(item) {
window.open(item.url.startsWith('http') ? item.url : 'http://' + item.url);
httpUtil.post('/bookmark/visitNum?id=' + item.bookmarkId);
}
/** /**
* 处理跳转到搜索引擎或者对应的书签 * 处理跳转到搜索引擎或者对应的书签
*/ */
enter() { enter() {
const { const { currentIndex, currentOptionIndex, resultList, content } = this.state;
currentIndex,
currentOptionIndex,
resultList,
content
} = this.state;
if (currentOptionIndex === 0 && resultList.length > 0) { if (currentOptionIndex === 0 && resultList.length > 0) {
let url = resultList[currentIndex].url; let url = resultList[currentIndex].url;
window.open(url.startsWith("http") ? url : "http://" + url); window.open(url.startsWith('http') ? url : 'http://' + url);
httpUtil.post('/bookmark/visitNum?id=' + resultList[currentIndex].bookmarkId);
} }
if (currentOptionIndex === 1) { if (currentOptionIndex === 1) {
window.open( window.open('https://www.baidu.com/s?ie=UTF-8&wd=' + encodeURIComponent(content));
"https://www.baidu.com/s?ie=UTF-8&wd=" + encodeURIComponent(content)
);
} else if (currentOptionIndex === 2) { } else if (currentOptionIndex === 2) {
window.open( window.open('https://www.google.com/search?q=' + encodeURIComponent(content));
"https://www.google.com/search?q=" + encodeURIComponent(content)
);
} }
} }
@ -130,12 +128,7 @@ class Search extends React.Component {
* 渲染结果列表 * 渲染结果列表
*/ */
renderResults() { renderResults() {
const { const { resultList, currentIndex, currentOptionIndex, isFocus } = this.state;
resultList,
currentIndex,
currentOptionIndex,
isFocus
} = this.state;
if (currentOptionIndex !== 0 || !isFocus) { if (currentOptionIndex !== 0 || !isFocus) {
return; return;
} }
@ -143,38 +136,22 @@ class Search extends React.Component {
return ( return (
<div className={styles.resultList}> <div className={styles.resultList}>
{resultList.map((item, index) => ( {resultList.map((item, index) => (
<div <div className={`${styles.item} ${index === currentIndex ? styles.checked : ''}`} key={item.bookmarkId} onClick={() => this.goTo(item)}>
className={`${styles.item} ${
index === currentIndex ? styles.checked : ""
}`}
key={item.bookmarkId}
onClick={() => window.open(item.url)}
>
<span style={{ fontWeight: 600 }}>{item.name}&emsp;</span> <span style={{ fontWeight: 600 }}>{item.name}&emsp;</span>
<span style={{ fontSize: "0.8em", fontWeight: 400 }}> <span style={{ fontSize: '0.8em', fontWeight: 400 }}>{item.url}</span>
{item.url}
</span>
</div> </div>
))} ))}
</div> </div>
); );
} else { } else {
return ( return <Empty className={styles.resultList} image={Empty.PRESENTED_IMAGE_SIMPLE} />;
<Empty
className={styles.resultList}
image={Empty.PRESENTED_IMAGE_SIMPLE}
/>
);
} }
} }
render() { render() {
const { content, options, currentOptionIndex } = this.state; const { content, options, currentOptionIndex } = this.state;
const prefix = ( const prefix = (
<Select <Select value={options[currentOptionIndex]} onChange={this.valueIndexChange.bind(this)}>
value={options[currentOptionIndex]}
onChange={this.valueIndexChange.bind(this)}
>
{options.map((item, index) => ( {options.map((item, index) => (
<Select.Option key={index} value={index}> <Select.Option key={index} value={index}>
{item} {item}
@ -188,15 +165,13 @@ class Search extends React.Component {
addonBefore={prefix} addonBefore={prefix}
ref="searchInput" ref="searchInput"
value={content} value={content}
placeholder={currentOptionIndex === 0 ? "检索我的书签" : "搜索"} placeholder={currentOptionIndex === 0 ? '检索我的书签' : '搜索'}
enterButton enterButton
onSearch={this.enter.bind(this)} onSearch={this.enter.bind(this)}
onChange={this.contentChange.bind(this)} onChange={this.contentChange.bind(this)}
onKeyDown={this.keyUp.bind(this)} onKeyDown={this.keyUp.bind(this)}
onFocus={() => this.setState({ isFocus: true })} onFocus={() => this.setState({ isFocus: true })}
onBlur={() => onBlur={() => setTimeout(() => this.setState({ isFocus: false }), 600)}
setTimeout(() => this.setState({ isFocus: false }), 600)
}
/> />
{this.renderResults()} {this.renderResults()}
</div> </div>

View File

@ -105,6 +105,7 @@ class OverView extends React.Component {
const item = e.node.props.dataRef; const item = e.node.props.dataRef;
if (item.type === 0) { if (item.type === 0) {
window.open(item.url.startsWith('http') ? item.url : 'http://' + item.url); window.open(item.url.startsWith('http') ? item.url : 'http://' + item.url);
httpUtil.post('/bookmark/visitNum?id=' + item.bookmarkId);
} else { } else {
const id = item.bookmarkId.toString(); const id = item.bookmarkId.toString();
const index = expandedKeys.indexOf(id); const index = expandedKeys.indexOf(id);