fix:修复页面书签数据缓存问题
This commit is contained in:
parent
2be78755f4
commit
6e91e49404
@ -40,6 +40,6 @@ public class PinyinUpdateConsumer implements RedisConsumer {
|
|||||||
bookmarkDao.updateSearchKey(bookmarks.get(i).getBookmarkId(), resList.get(i));
|
bookmarkDao.updateSearchKey(bookmarks.get(i).getBookmarkId(), resList.get(i));
|
||||||
}
|
}
|
||||||
//更新本用户书签更新时间
|
//更新本用户书签更新时间
|
||||||
RedisUtil.addToMq(RedisConstant.BOOKMARK_UPDATE_TIME, new UserBookmarkUpdate(bookmarks.get(0).getUserId()));
|
RedisUtil.addToMq(RedisConstant.BOOKMARK_UPDATE_VERSION, new UserBookmarkUpdate(bookmarks.get(0).getUserId()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -74,7 +74,7 @@ public class BookmarkServiceImpl implements BookmarkService {
|
|||||||
dealBookmark(userId, elements.get(i), path, sortBase + count + i - 1, bookmarks);
|
dealBookmark(userId, elements.get(i), path, sortBase + count + i - 1, bookmarks);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RedisUtil.addToMq(RedisConstant.BOOKMARK_UPDATE_TIME, new UserBookmarkUpdate(userId, System.currentTimeMillis()));
|
updateVersion(userId);
|
||||||
RedisUtil.addToMq(RedisConstant.BOOKMARK_INSERT_ES, bookmarks);
|
RedisUtil.addToMq(RedisConstant.BOOKMARK_INSERT_ES, bookmarks);
|
||||||
RedisUtil.addToMq(RedisConstant.BOOKMARK_PINYIN_CHANGE, bookmarks);
|
RedisUtil.addToMq(RedisConstant.BOOKMARK_PINYIN_CHANGE, bookmarks);
|
||||||
|
|
||||||
@ -172,8 +172,8 @@ public class BookmarkServiceImpl implements BookmarkService {
|
|||||||
bookmarkDao.deleteUserBookmark(userId, bookmarkIdList);
|
bookmarkDao.deleteUserBookmark(userId, bookmarkIdList);
|
||||||
}
|
}
|
||||||
set.addAll(bookmarkIdList.stream().map(String::valueOf).collect(Collectors.toSet()));
|
set.addAll(bookmarkIdList.stream().map(String::valueOf).collect(Collectors.toSet()));
|
||||||
RedisUtil.addToMq(RedisConstant.BOOKMARK_UPDATE_TIME, new UserBookmarkUpdate(userId, System.currentTimeMillis()));
|
|
||||||
RedisUtil.addToMq(RedisConstant.BOOKMARK_DELETE_ES, set);
|
RedisUtil.addToMq(RedisConstant.BOOKMARK_DELETE_ES, set);
|
||||||
|
updateVersion(userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -191,7 +191,7 @@ public class BookmarkServiceImpl implements BookmarkService {
|
|||||||
if (bookmark.getType() == 0) {
|
if (bookmark.getType() == 0) {
|
||||||
RedisUtil.addToMq(RedisConstant.BOOKMARK_INSERT_ES, Collections.singleton(bookmark));
|
RedisUtil.addToMq(RedisConstant.BOOKMARK_INSERT_ES, Collections.singleton(bookmark));
|
||||||
}
|
}
|
||||||
RedisUtil.addToMq(RedisConstant.BOOKMARK_UPDATE_TIME, new UserBookmarkUpdate(userId, System.currentTimeMillis()));
|
updateVersion(userId);
|
||||||
return bookmark;
|
return bookmark;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -204,7 +204,7 @@ public class BookmarkServiceImpl implements BookmarkService {
|
|||||||
if (bookmark.getType() == 0) {
|
if (bookmark.getType() == 0) {
|
||||||
RedisUtil.addToMq(RedisConstant.BOOKMARK_INSERT_ES, Collections.singleton(bookmark));
|
RedisUtil.addToMq(RedisConstant.BOOKMARK_INSERT_ES, Collections.singleton(bookmark));
|
||||||
}
|
}
|
||||||
RedisUtil.addToMq(RedisConstant.BOOKMARK_UPDATE_TIME, new UserBookmarkUpdate(userId, System.currentTimeMillis()));
|
updateVersion(userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -225,7 +225,7 @@ public class BookmarkServiceImpl implements BookmarkService {
|
|||||||
}
|
}
|
||||||
//更新被移动节点的path和sort
|
//更新被移动节点的path和sort
|
||||||
bookmarkDao.updatePathAndSort(userId, body.getBookmarkId(), body.getTargetPath(), body.getSort());
|
bookmarkDao.updatePathAndSort(userId, body.getBookmarkId(), body.getTargetPath(), body.getSort());
|
||||||
RedisUtil.addToMq(RedisConstant.BOOKMARK_UPDATE_TIME, new UserBookmarkUpdate(userId, System.currentTimeMillis()));
|
updateVersion(userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -239,5 +239,16 @@ public class BookmarkServiceImpl implements BookmarkService {
|
|||||||
return esUtil.search(EsConstant.BOOKMARK_INDEX, builder, BookmarkEs.class);
|
return esUtil.search(EsConstant.BOOKMARK_INDEX, builder, BookmarkEs.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 功能描述: 向mq发送消息通知,数据更新
|
||||||
|
*
|
||||||
|
* @param userId userId
|
||||||
|
* @author fanxb
|
||||||
|
* @date 2020/5/10 12:07
|
||||||
|
*/
|
||||||
|
private void updateVersion(int userId) {
|
||||||
|
RedisUtil.addToMq(RedisConstant.BOOKMARK_UPDATE_VERSION, userId);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -61,7 +61,7 @@ public class PinYinServiceImpl implements PinYinService {
|
|||||||
i = bookmarks.get(SIZE - 1).getBookmarkId();
|
i = bookmarks.get(SIZE - 1).getBookmarkId();
|
||||||
}
|
}
|
||||||
//更新所有用户的上次刷新时间
|
//更新所有用户的上次刷新时间
|
||||||
RedisUtil.addToMq(RedisConstant.BOOKMARK_UPDATE_TIME, new UserBookmarkUpdate(-1, System.currentTimeMillis()));
|
RedisUtil.addToMq(RedisConstant.BOOKMARK_UPDATE_VERSION, new UserBookmarkUpdate(-1, System.currentTimeMillis()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -12,7 +12,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|||||||
* @author fanxb
|
* @author fanxb
|
||||||
* @date 2020/1/26 上午11:54
|
* @date 2020/1/26 上午11:54
|
||||||
*/
|
*/
|
||||||
@MqConsumer(RedisConstant.BOOKMARK_UPDATE_TIME)
|
@MqConsumer(RedisConstant.BOOKMARK_UPDATE_VERSION)
|
||||||
public class UserInfoUpdateConsumer implements RedisConsumer {
|
public class UserInfoUpdateConsumer implements RedisConsumer {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
@ -20,11 +20,11 @@ public class UserInfoUpdateConsumer implements RedisConsumer {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void deal(String message) {
|
public void deal(String message) {
|
||||||
UserBookmarkUpdate item = JSON.parseObject(message, UserBookmarkUpdate.class);
|
int userId = Integer.parseInt(message);
|
||||||
if (item.getUserId() == -1) {
|
if (userId == -1) {
|
||||||
userDao.updateAllBookmarkUpdateTime(item.getUpdateTime());
|
userDao.updateAllBookmarkUpdateVersion();
|
||||||
} else {
|
} else {
|
||||||
userDao.updateLastBookmarkUpdateTime(item);
|
userDao.updateLastBookmarkUpdateTime(userId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -123,8 +123,8 @@ public interface UserDao {
|
|||||||
* @author fanxb
|
* @author fanxb
|
||||||
* @date 2020/1/26 下午3:47
|
* @date 2020/1/26 下午3:47
|
||||||
*/
|
*/
|
||||||
@Update("update user set bookmarkChangeTime=#{updateTime} where userId=#{userId}")
|
@Update("update user set version=version+1 where userId=#{userId}")
|
||||||
void updateLastBookmarkUpdateTime(UserBookmarkUpdate item);
|
void updateLastBookmarkUpdateTime(int userId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 功能描述: 更新所有用户的更新时间
|
* 功能描述: 更新所有用户的更新时间
|
||||||
@ -133,6 +133,6 @@ public interface UserDao {
|
|||||||
* @author 123
|
* @author 123
|
||||||
* @date 2020/3/29 18:18
|
* @date 2020/3/29 18:18
|
||||||
*/
|
*/
|
||||||
@Update("update user set bookmarkChangeTime=#{time}")
|
@Update("update user set version=version+1")
|
||||||
void updateAllBookmarkUpdateTime(long time);
|
void updateAllBookmarkUpdateVersion();
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@ public class RedisConstant {
|
|||||||
/**
|
/**
|
||||||
* 某用户书签数据更新时间,该队列左进右出
|
* 某用户书签数据更新时间,该队列左进右出
|
||||||
*/
|
*/
|
||||||
public static final String BOOKMARK_UPDATE_TIME = "bookmark_update_time";
|
public static final String BOOKMARK_UPDATE_VERSION = "bookmark_update_version";
|
||||||
/**
|
/**
|
||||||
* 某个用户上传了文件夹,需要进行书签转化
|
* 某个用户上传了文件夹,需要进行书签转化
|
||||||
*/
|
*/
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package com.fanxb.bookmark.common.entity;
|
package com.fanxb.bookmark.common.entity;
|
||||||
|
|
||||||
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import com.alibaba.fastjson.annotation.JSONField;
|
||||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
@ -22,28 +23,12 @@ public class User {
|
|||||||
private String email;
|
private String email;
|
||||||
private String newEmail;
|
private String newEmail;
|
||||||
private String icon;
|
private String icon;
|
||||||
@JsonIgnore
|
@JSONField(serialize = false)
|
||||||
private String password;
|
private String password;
|
||||||
private long createTime;
|
private long createTime;
|
||||||
private long lastLoginTime;
|
private long lastLoginTime;
|
||||||
/**
|
/**
|
||||||
* 上次更新书签时间
|
* 书签同步版本
|
||||||
*/
|
*/
|
||||||
private long bookmarkChangeTime;
|
private int version;
|
||||||
|
|
||||||
public static void main(String[] args) {
|
|
||||||
User user1 = new User();
|
|
||||||
User user2 = new User();
|
|
||||||
Map<User, User> map = new HashMap<>();
|
|
||||||
map.put(user1, user2);
|
|
||||||
NewUserObj obj = new NewUserObj();
|
|
||||||
obj.setMap(map);
|
|
||||||
NewUserObj newObj = JSON.parseObject(JSON.toJSONString(obj), NewUserObj.class);
|
|
||||||
System.out.println(newObj.getMap().get(user1));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Data
|
|
||||||
public static class NewUserObj {
|
|
||||||
private Map<User, User> map;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -133,7 +133,7 @@ public class LoginFilter implements Filter {
|
|||||||
UserContextHolder.set(context);
|
UserContextHolder.set(context);
|
||||||
return true;
|
return true;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("jwt解密失败:{}", jwt, e);
|
log.error("jwt解密失败:{},原因:{}", jwt, e.getMessage());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,15 @@
|
|||||||
package com.fanxb.bookmark.web;
|
package com.fanxb.bookmark.web;
|
||||||
|
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.serializer.SerializerFeature;
|
||||||
|
import com.alibaba.fastjson.support.config.FastJsonConfig;
|
||||||
|
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
|
||||||
import org.mybatis.spring.annotation.MapperScan;
|
import org.mybatis.spring.annotation.MapperScan;
|
||||||
import org.springframework.boot.SpringApplication;
|
import org.springframework.boot.SpringApplication;
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.http.converter.HttpMessageConverter;
|
||||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||||
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
||||||
|
|
||||||
@ -22,4 +28,17 @@ public class Application {
|
|||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
SpringApplication.run(Application.class, args);
|
SpringApplication.run(Application.class, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public HttpMessageConverters fastJsonHttpMessageConverters() {
|
||||||
|
// 1.定义一个converters转换消息的对象
|
||||||
|
FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter();
|
||||||
|
// 2.添加fastjson的配置信息,比如: 是否需要格式化返回的json数据
|
||||||
|
FastJsonConfig fastJsonConfig = new FastJsonConfig();
|
||||||
|
fastJsonConfig.setSerializerFeatures(SerializerFeature.DisableCircularReferenceDetect);
|
||||||
|
// 3.在converter中添加配置信息
|
||||||
|
fastConverter.setFastJsonConfig(fastJsonConfig);
|
||||||
|
// 5.返回HttpMessageConverters对象
|
||||||
|
return new HttpMessageConverters(fastConverter);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,4 @@
|
|||||||
|
update bookmark.user
|
||||||
|
set bookmarkChangeTime=0;
|
||||||
|
ALTER TABLE `bookmark`.`user`
|
||||||
|
CHANGE COLUMN `bookmarkChangeTime` `version` int(10) UNSIGNED NOT NULL DEFAULT 0 AFTER `lastLoginTime`;
|
@ -1,8 +1,8 @@
|
|||||||
import React from "react";
|
import React from 'react';
|
||||||
import { Input, Select, Button, message } from "antd";
|
import { Input, Select, Button, message } from 'antd';
|
||||||
import styles from "./index.module.less";
|
import styles from './index.module.less';
|
||||||
import MainLayout from "../../../layout/MainLayout";
|
import MainLayout from '../../../layout/MainLayout';
|
||||||
import httpUtil from "../../../util/httpUtil";
|
import httpUtil from '../../../util/httpUtil';
|
||||||
|
|
||||||
const { TextArea } = Input;
|
const { TextArea } = Input;
|
||||||
const { Option } = Select;
|
const { Option } = Select;
|
||||||
@ -11,15 +11,15 @@ class Feedback extends React.Component {
|
|||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.state = {
|
this.state = {
|
||||||
content: "",
|
content: '',
|
||||||
//1:bug反馈,2:功能建议
|
//1:bug反馈,2:功能建议
|
||||||
type: "bug"
|
type: 'bug'
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async submit() {
|
async submit() {
|
||||||
await httpUtil.put("/feedback", this.state);
|
await httpUtil.put('/feedback', this.state);
|
||||||
message.success("创建成功");
|
message.success('创建成功');
|
||||||
this.props.history.goBack();
|
this.props.history.goBack();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -30,29 +30,19 @@ class Feedback extends React.Component {
|
|||||||
<div>反馈页面</div>
|
<div>反馈页面</div>
|
||||||
<div className={styles.main}>
|
<div className={styles.main}>
|
||||||
<div>
|
<div>
|
||||||
<Select
|
<Select defaultValue={type} style={{ width: 140 }} onChange={value => this.setState({ type: value })}>
|
||||||
defaultValue={type}
|
|
||||||
style={{ width: 140 }}
|
|
||||||
onChange={value => this.setState({ type: value })}
|
|
||||||
>
|
|
||||||
<Option value="bug">BUG反馈</Option>
|
<Option value="bug">BUG反馈</Option>
|
||||||
<Option value="advice">功能建议</Option>
|
<Option value="advice">功能建议</Option>
|
||||||
</Select>
|
</Select>
|
||||||
<span className={styles.tips}>
|
<span className={styles.tips}>
|
||||||
建议通过
|
建议通过
|
||||||
<a
|
<a href="https://github.com/FleyX/bookmark/issues" target="github">
|
||||||
href="https://github.com/FleyX/bookmark/issues"
|
|
||||||
target="github"
|
|
||||||
>
|
|
||||||
github
|
github
|
||||||
</a>
|
</a>
|
||||||
反馈
|
反馈
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<TextArea
|
<TextArea rows="8" onChange={e => this.setState({ content: e.target.value })}></TextArea>
|
||||||
rows="8"
|
|
||||||
onChange={e => this.setState({ content: e.target.value })}
|
|
||||||
></TextArea>
|
|
||||||
<div>
|
<div>
|
||||||
<Button type="primary" onClick={this.submit.bind(this)}>
|
<Button type="primary" onClick={this.submit.bind(this)}>
|
||||||
确认
|
确认
|
||||||
|
@ -1,20 +1,15 @@
|
|||||||
import React from "react";
|
import React from 'react';
|
||||||
import { Tree, Empty, Button, Spin, Modal } from "antd";
|
import { Tree, Empty, Button, Spin, Modal } from 'antd';
|
||||||
import MainLayout from "../../../layout/MainLayout";
|
import MainLayout from '../../../layout/MainLayout';
|
||||||
import styles from "./index.module.less";
|
import styles from './index.module.less';
|
||||||
import { batchDelete, renderTreeNodes, onDrop } from "./function.js";
|
import { batchDelete, renderTreeNodes, onDrop } from './function.js';
|
||||||
import {
|
import { cacheBookmarkData, getBookmarkList, checkCacheStatus, clearCache } from '../../../util/cacheUtil';
|
||||||
cacheBookmarkData,
|
import httpUtil from '../../../util/httpUtil';
|
||||||
getBookmarkList,
|
import AddModal from './AddModal';
|
||||||
checkCacheStatus,
|
import Search from '../../../components/Search';
|
||||||
clearCache
|
|
||||||
} from "../../../util/cacheUtil";
|
|
||||||
import httpUtil from "../../../util/httpUtil";
|
|
||||||
import AddModal from "./AddModal";
|
|
||||||
import Search from "../../../components/Search";
|
|
||||||
|
|
||||||
import * as action from "../../../redux/action/BookmarkTreeOverview";
|
import * as action from '../../../redux/action/BookmarkTreeOverview';
|
||||||
import { connect } from "react-redux";
|
import { connect } from 'react-redux';
|
||||||
|
|
||||||
const { confirm } = Modal;
|
const { confirm } = Modal;
|
||||||
|
|
||||||
@ -30,11 +25,9 @@ function mapDispatchToProps(dispatch) {
|
|||||||
addNode: (item, e) => dispatch(action.addNode(item, e)),
|
addNode: (item, e) => dispatch(action.addNode(item, e)),
|
||||||
editNode: (item, e) => dispatch(action.editNode(item, e)),
|
editNode: (item, e) => dispatch(action.editNode(item, e)),
|
||||||
changeIsInit: value => dispatch(action.changeIsInit(value)),
|
changeIsInit: value => dispatch(action.changeIsInit(value)),
|
||||||
changeCheckedKeys: (keys, nodes) =>
|
changeCheckedKeys: (keys, nodes) => dispatch(action.changeCheckedKeys(keys, nodes)),
|
||||||
dispatch(action.changeCheckedKeys(keys, nodes)),
|
|
||||||
changeExpandedKeys: keys => dispatch(action.changeExpandedKeys(keys)),
|
changeExpandedKeys: keys => dispatch(action.changeExpandedKeys(keys)),
|
||||||
changeCurrentClickItem: item =>
|
changeCurrentClickItem: item => dispatch(action.changeCurrentClickItem(item)),
|
||||||
dispatch(action.changeCurrentClickItem(item)),
|
|
||||||
changeLoadedKeys: keys => dispatch(action.changeLoadedKeys(keys))
|
changeLoadedKeys: keys => dispatch(action.changeLoadedKeys(keys))
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -55,12 +48,12 @@ class OverView extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async componentWillMount() {
|
async componentWillMount() {
|
||||||
await httpUtil.get("/user/loginStatus");
|
await httpUtil.get('/user/loginStatus');
|
||||||
this.state.timer = setInterval(this.checkCache.bind(this), 10000);
|
this.state.timer = setInterval(this.checkCache.bind(this), 30000);
|
||||||
setTimeout(this.checkCache.bind(this), 5000);
|
setTimeout(this.checkCache.bind(this), 5000);
|
||||||
this.props.refresh();
|
this.props.refresh();
|
||||||
await cacheBookmarkData();
|
await cacheBookmarkData();
|
||||||
this.props.updateTreeData(getBookmarkList(""));
|
this.props.updateTreeData(getBookmarkList(''));
|
||||||
this.props.changeIsInit(true);
|
this.props.changeIsInit(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,8 +66,8 @@ class OverView extends React.Component {
|
|||||||
if (!(await checkCacheStatus())) {
|
if (!(await checkCacheStatus())) {
|
||||||
this.state.showDialog = true;
|
this.state.showDialog = true;
|
||||||
confirm({
|
confirm({
|
||||||
title: "缓存过期",
|
title: '缓存过期',
|
||||||
content: "书签数据有更新,是否立即刷新?",
|
content: '书签数据有更新,是否立即刷新?',
|
||||||
async onOk() {
|
async onOk() {
|
||||||
_this.state.showDialog = false;
|
_this.state.showDialog = false;
|
||||||
await clearCache();
|
await clearCache();
|
||||||
@ -94,9 +87,9 @@ class OverView extends React.Component {
|
|||||||
const { loadedKeys } = this.props;
|
const { loadedKeys } = this.props;
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
const item = e.props.dataRef;
|
const item = e.props.dataRef;
|
||||||
const newPath = item.path + "." + item.bookmarkId;
|
const newPath = item.path + '.' + item.bookmarkId;
|
||||||
item.children = getBookmarkList(newPath);
|
item.children = getBookmarkList(newPath);
|
||||||
this.props.updateTreeData([...getBookmarkList("")]);
|
this.props.updateTreeData([...getBookmarkList('')]);
|
||||||
loadedKeys.push(item.bookmarkId.toString());
|
loadedKeys.push(item.bookmarkId.toString());
|
||||||
this.props.changeLoadedKeys(loadedKeys);
|
this.props.changeLoadedKeys(loadedKeys);
|
||||||
resolve();
|
resolve();
|
||||||
@ -111,9 +104,7 @@ class OverView extends React.Component {
|
|||||||
const { expandedKeys, changeExpandedKeys } = this.props;
|
const { expandedKeys, changeExpandedKeys } = this.props;
|
||||||
const item = e.node.props.dataRef;
|
const item = e.node.props.dataRef;
|
||||||
if (item.type === 0) {
|
if (item.type === 0) {
|
||||||
window.open(
|
window.open(item.url.startsWith('http') ? item.url : 'http://' + item.url);
|
||||||
item.url.startsWith("http") ? item.url : "http://" + item.url
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
const id = item.bookmarkId.toString();
|
const id = item.bookmarkId.toString();
|
||||||
const index = expandedKeys.indexOf(id);
|
const index = expandedKeys.indexOf(id);
|
||||||
@ -131,16 +122,7 @@ class OverView extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {
|
const { isEdit, setIsEdit, treeData, addNode, isInit, expandedKeys, checkedKeys, loadedKeys } = this.props;
|
||||||
isEdit,
|
|
||||||
setIsEdit,
|
|
||||||
treeData,
|
|
||||||
addNode,
|
|
||||||
isInit,
|
|
||||||
expandedKeys,
|
|
||||||
checkedKeys,
|
|
||||||
loadedKeys
|
|
||||||
} = this.props;
|
|
||||||
const { isLoading } = this.state;
|
const { isLoading } = this.state;
|
||||||
const { changeExpandedKeys } = this.props;
|
const { changeExpandedKeys } = this.props;
|
||||||
return (
|
return (
|
||||||
@ -150,54 +132,27 @@ class OverView extends React.Component {
|
|||||||
<div className={styles.header}>
|
<div className={styles.header}>
|
||||||
<div className={styles.left}>
|
<div className={styles.left}>
|
||||||
<span className={styles.myTree}>我的书签树</span>
|
<span className={styles.myTree}>我的书签树</span>
|
||||||
<Button
|
<Button size="small" type="primary" icon="sync" shape="circle" onClick={this.refreshTree.bind(this, null)} />
|
||||||
size="small"
|
<Button size="small" type="primary" icon="plus" shape="circle" onClick={addNode.bind(this, null)} />
|
||||||
type="primary"
|
|
||||||
icon="sync"
|
|
||||||
shape="circle"
|
|
||||||
onClick={this.refreshTree.bind(this, null)}
|
|
||||||
/>
|
|
||||||
<Button
|
|
||||||
size="small"
|
|
||||||
type="primary"
|
|
||||||
icon="plus"
|
|
||||||
shape="circle"
|
|
||||||
onClick={addNode.bind(this, null)}
|
|
||||||
/>
|
|
||||||
{expandedKeys.length > 0 ? (
|
{expandedKeys.length > 0 ? (
|
||||||
<Button
|
<Button type="primary" size="small" onClick={changeExpandedKeys.bind(this, [])}>
|
||||||
type="primary"
|
|
||||||
size="small"
|
|
||||||
onClick={changeExpandedKeys.bind(this, [])}
|
|
||||||
>
|
|
||||||
收起
|
收起
|
||||||
</Button>
|
</Button>
|
||||||
) : null}
|
) : null}
|
||||||
<a
|
<a className={styles.help} href="https://github.com/FleyX/bookmark/blob/master/README.md">
|
||||||
className={styles.help}
|
|
||||||
href="https://github.com/FleyX/bookmark/blob/master/README.md"
|
|
||||||
>
|
|
||||||
使用帮助
|
使用帮助
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div className={styles.right}>
|
<div className={styles.right}>
|
||||||
{isEdit ? (
|
{isEdit ? (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
<Button
|
<Button size="small" type="danger" onClick={batchDelete.bind(this)}>
|
||||||
size="small"
|
|
||||||
type="danger"
|
|
||||||
onClick={batchDelete.bind(this)}
|
|
||||||
>
|
|
||||||
删除选中
|
删除选中
|
||||||
</Button>
|
</Button>
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
) : null}
|
) : null}
|
||||||
<Button
|
<Button size="small" type="primary" onClick={setIsEdit.bind(this, !isEdit)}>
|
||||||
size="small"
|
{isEdit ? '完成' : '编辑'}
|
||||||
type="primary"
|
|
||||||
onClick={setIsEdit.bind(this, !isEdit)}
|
|
||||||
>
|
|
||||||
{isEdit ? "完成" : "编辑"}
|
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -218,9 +173,7 @@ class OverView extends React.Component {
|
|||||||
>
|
>
|
||||||
{renderTreeNodes.call(this, treeData)}
|
{renderTreeNodes.call(this, treeData)}
|
||||||
</Tree>
|
</Tree>
|
||||||
{isInit && treeData.length === 0 ? (
|
{isInit && treeData.length === 0 ? <Empty description="还没有数据" /> : null}
|
||||||
<Empty description="还没有数据" />
|
|
||||||
) : null}
|
|
||||||
</Spin>
|
</Spin>
|
||||||
<AddModal />
|
<AddModal />
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,44 +1,29 @@
|
|||||||
/* eslint-disable no-undef */
|
/* eslint-disable no-undef */
|
||||||
import httpUtil from "./httpUtil";
|
import httpUtil from './httpUtil';
|
||||||
import config from "./config";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* web版本
|
|
||||||
*/
|
|
||||||
export const WEB_VERSION = "webVersion";
|
|
||||||
/**
|
/**
|
||||||
* 全部书签数据key
|
* 全部书签数据key
|
||||||
*/
|
*/
|
||||||
export const TREE_LIST_KEY = "treeListData";
|
export const TREE_LIST_KEY = 'treeListData';
|
||||||
/**
|
/**
|
||||||
* 获取全部书签时间
|
* 当前用户书签版本
|
||||||
*/
|
*/
|
||||||
export const TREE_LIST_TIME_KEY = "treeListDataTime";
|
export const TREE_LIST_VERSION_KEY = 'treeDataVersion';
|
||||||
/**
|
|
||||||
* 书签数据所属用户
|
|
||||||
*/
|
|
||||||
export const TREE_LIST_USER_ID = "treeListDataUserId";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 缓存书签数据
|
* 缓存书签数据
|
||||||
*/
|
*/
|
||||||
export async function cacheBookmarkData() {
|
export async function cacheBookmarkData() {
|
||||||
let currentId = JSON.parse(window.atob(window.token.split(".")[1])).userId;
|
let key = getCacheKey();
|
||||||
let cacheId = await localforage.getItem(TREE_LIST_USER_ID);
|
let res = await localforage.getItem(key);
|
||||||
let webVersion = await localforage.getItem(WEB_VERSION);
|
//如果没有缓存
|
||||||
if ((currentId && currentId !== cacheId) || config.version !== webVersion) {
|
|
||||||
await localforage.setItem(WEB_VERSION, config.version);
|
|
||||||
await clearCache();
|
|
||||||
}
|
|
||||||
let res = await localforage.getItem(TREE_LIST_KEY);
|
|
||||||
if (!res) {
|
if (!res) {
|
||||||
res = await httpUtil.get("/bookmark/currentUser");
|
res = await httpUtil.get('/bookmark/currentUser');
|
||||||
if (!res[""]) {
|
if (!res['']) {
|
||||||
res[""] = [];
|
res[''] = [];
|
||||||
}
|
}
|
||||||
await localforage.setItem(TREE_LIST_KEY, res);
|
let version = (await httpUtil.get('/user/currentUserInfo')).version;
|
||||||
await localforage.setItem(TREE_LIST_TIME_KEY, Date.now());
|
await localforage.setItem(key, res);
|
||||||
await localforage.setItem(TREE_LIST_USER_ID, currentId);
|
await localforage.setItem(TREE_LIST_VERSION_KEY, version);
|
||||||
}
|
}
|
||||||
window[TREE_LIST_KEY] = res;
|
window[TREE_LIST_KEY] = res;
|
||||||
}
|
}
|
||||||
@ -59,27 +44,26 @@ export function getBookmarkList(path) {
|
|||||||
* @return 返回true说明未过期,否则说明过期了
|
* @return 返回true说明未过期,否则说明过期了
|
||||||
*/
|
*/
|
||||||
export async function checkCacheStatus() {
|
export async function checkCacheStatus() {
|
||||||
let date = await localforage.getItem(TREE_LIST_TIME_KEY, Date.now());
|
let version = await localforage.getItem(TREE_LIST_VERSION_KEY);
|
||||||
let userInfo = await httpUtil.get("/user/currentUserInfo");
|
let realVersion = (await httpUtil.get('/user/currentUserInfo')).version;
|
||||||
return !date || date > userInfo.bookmarkChangeTime;
|
return version >= realVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 清楚缓存数据
|
* 清楚缓存数据
|
||||||
*/
|
*/
|
||||||
export async function clearCache() {
|
export async function clearCache() {
|
||||||
await localforage.removeItem(TREE_LIST_KEY);
|
await localforage.removeItem(getCacheKey());
|
||||||
await localforage.removeItem(TREE_LIST_TIME_KEY);
|
await localforage.removeItem(TREE_LIST_VERSION_KEY);
|
||||||
await localforage.removeItem(TREE_LIST_USER_ID);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 更新本地缓存数据的时间
|
* 更新本地缓存
|
||||||
*/
|
*/
|
||||||
export async function updateCurrentChangeTime() {
|
export async function updateCurrentChangeTime() {
|
||||||
await localforage.setItem(TREE_LIST_TIME_KEY, Date.now());
|
let version = await localforage.getItem(TREE_LIST_VERSION_KEY);
|
||||||
await localforage.setItem(TREE_LIST_TIME_KEY, Date.now());
|
await localforage.setItem(TREE_LIST_VERSION_KEY, version + 1);
|
||||||
await localforage.setItem(TREE_LIST_KEY, window[TREE_LIST_KEY]);
|
await localforage.setItem(getCacheKey(), window[TREE_LIST_KEY]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -91,13 +75,13 @@ export async function addNode(currentNode, node) {
|
|||||||
debugger;
|
debugger;
|
||||||
let treeDataMap = window[TREE_LIST_KEY];
|
let treeDataMap = window[TREE_LIST_KEY];
|
||||||
if (currentNode) {
|
if (currentNode) {
|
||||||
let key = currentNode.path + "." + currentNode.bookmarkId;
|
let key = currentNode.path + '.' + currentNode.bookmarkId;
|
||||||
if (!treeDataMap[key]) {
|
if (!treeDataMap[key]) {
|
||||||
treeDataMap[key] = [];
|
treeDataMap[key] = [];
|
||||||
}
|
}
|
||||||
treeDataMap[key].push(node);
|
treeDataMap[key].push(node);
|
||||||
} else {
|
} else {
|
||||||
treeDataMap[""].push(node);
|
treeDataMap[''].push(node);
|
||||||
}
|
}
|
||||||
await updateCurrentChangeTime();
|
await updateCurrentChangeTime();
|
||||||
}
|
}
|
||||||
@ -117,7 +101,7 @@ export async function deleteNodes(nodeList) {
|
|||||||
}
|
}
|
||||||
//如果是文件夹还是把他的子节点删除
|
//如果是文件夹还是把他的子节点删除
|
||||||
if (item.type === 1) {
|
if (item.type === 1) {
|
||||||
let key = item.path + "." + item.bookmarkId;
|
let key = item.path + '.' + item.bookmarkId;
|
||||||
Object.keys(data).forEach(one => {
|
Object.keys(data).forEach(one => {
|
||||||
if (one.startsWith(key)) {
|
if (one.startsWith(key)) {
|
||||||
delete data[one];
|
delete data[one];
|
||||||
@ -147,7 +131,7 @@ export async function moveNode(info) {
|
|||||||
const body = {
|
const body = {
|
||||||
bookmarkId: current.bookmarkId,
|
bookmarkId: current.bookmarkId,
|
||||||
sourcePath: current.path,
|
sourcePath: current.path,
|
||||||
targetPath: "",
|
targetPath: '',
|
||||||
//-1 表示排在最后
|
//-1 表示排在最后
|
||||||
sort: -1
|
sort: -1
|
||||||
};
|
};
|
||||||
@ -166,14 +150,13 @@ export async function moveNode(info) {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
//移动到一个文件夹下面
|
//移动到一个文件夹下面
|
||||||
body.targetPath = target.path + "." + target.bookmarkId;
|
body.targetPath = target.path + '.' + target.bookmarkId;
|
||||||
let targetList = data[body.targetPath];
|
let targetList = data[body.targetPath];
|
||||||
if (!targetList) {
|
if (!targetList) {
|
||||||
targetList = [];
|
targetList = [];
|
||||||
data[body.targetPath] = targetList;
|
data[body.targetPath] = targetList;
|
||||||
}
|
}
|
||||||
body.sort =
|
body.sort = targetList.length > 0 ? targetList[targetList.length - 1].sort + 1 : 1;
|
||||||
targetList.length > 0 ? targetList[targetList.length - 1].sort + 1 : 1;
|
|
||||||
targetList.push(current);
|
targetList.push(current);
|
||||||
}
|
}
|
||||||
//更新节点的path和对应子节点path
|
//更新节点的path和对应子节点path
|
||||||
@ -183,9 +166,9 @@ export async function moveNode(info) {
|
|||||||
if (body.sourcePath !== body.targetPath) {
|
if (body.sourcePath !== body.targetPath) {
|
||||||
let keys = Object.keys(data);
|
let keys = Object.keys(data);
|
||||||
//旧路径
|
//旧路径
|
||||||
let oldPath = body.sourcePath + "." + current.bookmarkId;
|
let oldPath = body.sourcePath + '.' + current.bookmarkId;
|
||||||
//新路径
|
//新路径
|
||||||
let newPath = body.targetPath + "." + current.bookmarkId;
|
let newPath = body.targetPath + '.' + current.bookmarkId;
|
||||||
keys.forEach(item => {
|
keys.forEach(item => {
|
||||||
if (!item.startsWith(oldPath)) {
|
if (!item.startsWith(oldPath)) {
|
||||||
return;
|
return;
|
||||||
@ -219,12 +202,20 @@ export async function keySearch(content) {
|
|||||||
if (item.searchKey.indexOf(content) > -1) {
|
if (item.searchKey.indexOf(content) > -1) {
|
||||||
res.push(item);
|
res.push(item);
|
||||||
if (res.length >= 12) {
|
if (res.length >= 12) {
|
||||||
console.info("搜索耗时:" + (Date.now() - time1));
|
console.info('搜索耗时:' + (Date.now() - time1));
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
console.info("搜索耗时:" + (Date.now() - time1));
|
console.info('搜索耗时:' + (Date.now() - time1));
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取localstore缓存的key
|
||||||
|
*/
|
||||||
|
export function getCacheKey() {
|
||||||
|
let currentId = JSON.parse(window.atob(window.token.split('.')[1])).userId;
|
||||||
|
return currentId + TREE_LIST_KEY;
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user