Merge branch 'dev' of fanxb/bookmark into master

This commit is contained in:
fanxb 2022-04-15 15:49:08 +08:00 committed by Gogs
commit e8a646dbe8
29 changed files with 1055 additions and 529 deletions

View File

@ -0,0 +1,16 @@
package com.fanxb.bookmark.business.bookmark.constant;
import java.nio.file.Paths;
/**
* TODO
*
* @author fanxb
*/
public class FileConstant {
/**
* 网站icon存储路径
*/
public static final String FAVICON_PATH = Paths.get("files", "public", "favicon").toString();
}

View File

@ -0,0 +1,33 @@
package com.fanxb.bookmark.business.bookmark.dao;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
/**
* @author fanxb
*/
@Mapper
public interface HostIconDao {
/**
* 插入一条数据
*
* @param host host
* @param iconPath path
* @author fanxb
*/
@Insert("insert into host_icon(host,iconPath) value(#{host},#{iconPath})")
void insert(@Param("host") String host, @Param("iconPath") String iconPath);
/**
* 根据host获取iconPath
*
* @param host host
* @return {@link String}
* @author fanxb
*/
@Select("select iconPath from host_icon where host=#{host}")
String selectByHost(String host);
}

View File

@ -1,21 +1,29 @@
package com.fanxb.bookmark.business.bookmark.service.impl; package com.fanxb.bookmark.business.bookmark.service.impl;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.fanxb.bookmark.business.api.UserApi; import com.fanxb.bookmark.business.api.UserApi;
import com.fanxb.bookmark.business.bookmark.constant.FileConstant;
import com.fanxb.bookmark.business.bookmark.dao.BookmarkDao; import com.fanxb.bookmark.business.bookmark.dao.BookmarkDao;
import com.fanxb.bookmark.business.bookmark.dao.HostIconDao;
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.BookmarkDeleteMessage; import com.fanxb.bookmark.business.bookmark.entity.redis.BookmarkDeleteMessage;
import com.fanxb.bookmark.business.bookmark.entity.redis.VisitNumPlus; 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.CommonConstant;
import com.fanxb.bookmark.common.constant.EsConstant; import com.fanxb.bookmark.common.constant.EsConstant;
import com.fanxb.bookmark.common.constant.RedisConstant; import com.fanxb.bookmark.common.constant.RedisConstant;
import com.fanxb.bookmark.common.entity.po.Bookmark; import com.fanxb.bookmark.common.entity.po.Bookmark;
import com.fanxb.bookmark.common.exception.CustomException;
import com.fanxb.bookmark.common.util.*; import com.fanxb.bookmark.common.util.*;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import okhttp3.Request;
import okhttp3.Response;
import org.elasticsearch.index.query.BoolQueryBuilder; import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders; import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.builder.SearchSourceBuilder; import org.elasticsearch.search.builder.SearchSourceBuilder;
@ -28,9 +36,15 @@ import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import java.io.File;
import java.io.InputStream; import java.io.InputStream;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URL; import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*; import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -51,13 +65,15 @@ public class BookmarkServiceImpl implements BookmarkService {
private final PinYinService pinYinService; private final PinYinService pinYinService;
private final UserApi userApi; private final UserApi userApi;
private final EsUtil esUtil; private final EsUtil esUtil;
private final HostIconDao hostIconDao;
@Autowired @Autowired
public BookmarkServiceImpl(BookmarkDao bookmarkDao, PinYinService pinYinService, UserApi userApi, EsUtil esUtil) { public BookmarkServiceImpl(BookmarkDao bookmarkDao, PinYinService pinYinService, UserApi userApi, EsUtil esUtil, HostIconDao hostIconDao) {
this.bookmarkDao = bookmarkDao; this.bookmarkDao = bookmarkDao;
this.pinYinService = pinYinService; this.pinYinService = pinYinService;
this.userApi = userApi; this.userApi = userApi;
this.esUtil = esUtil; this.esUtil = esUtil;
this.hostIconDao = hostIconDao;
} }
@Override @Override
@ -201,7 +217,7 @@ public class BookmarkServiceImpl implements BookmarkService {
bookmark.setUserId(userId); bookmark.setUserId(userId);
bookmark.setCreateTime(System.currentTimeMillis()); bookmark.setCreateTime(System.currentTimeMillis());
bookmark.setAddTime(bookmark.getCreateTime()); bookmark.setAddTime(bookmark.getCreateTime());
bookmark.setIcon(getIconBase64(bookmark.getUrl())); bookmark.setIcon(getIconPath(bookmark.getUrl()));
//文件夹和书签都建立搜索key //文件夹和书签都建立搜索key
pinYinService.changeBookmark(bookmark); pinYinService.changeBookmark(bookmark);
bookmarkDao.insertOne(bookmark); bookmarkDao.insertOne(bookmark);
@ -215,7 +231,7 @@ public class BookmarkServiceImpl implements BookmarkService {
bookmark.setUserId(userId); bookmark.setUserId(userId);
if (bookmark.getType() == 0) { if (bookmark.getType() == 0) {
pinYinService.changeBookmark(bookmark); pinYinService.changeBookmark(bookmark);
bookmark.setIcon(getIconBase64(bookmark.getUrl())); bookmark.setIcon(getIconPath(bookmark.getUrl()));
} }
bookmarkDao.editBookmark(bookmark); bookmarkDao.editBookmark(bookmark);
userApi.versionPlus(userId); userApi.versionPlus(userId);
@ -274,7 +290,7 @@ public class BookmarkServiceImpl implements BookmarkService {
while ((deal = bookmarkDao.selectUserNoIcon(userId, start, size)).size() > 0) { while ((deal = bookmarkDao.selectUserNoIcon(userId, start, size)).size() > 0) {
start += size; start += size;
deal.forEach(item -> { deal.forEach(item -> {
String icon = getIconBase64(item.getUrl()); String icon = getIconPath(item.getUrl());
if (StrUtil.isNotEmpty(icon)) { if (StrUtil.isNotEmpty(icon)) {
bookmarkDao.updateIcon(item.getBookmarkId(), icon); bookmarkDao.updateIcon(item.getBookmarkId(), icon);
} }
@ -305,21 +321,56 @@ public class BookmarkServiceImpl implements BookmarkService {
return resPath; return resPath;
} }
private String getIconBase64(String url) { /**
* 获取icon
*
* @param url url
* @return {@link String}
* @author fanxb
*/
private String getIconPath(String url) {
if (StrUtil.isEmpty(url)) { if (StrUtil.isEmpty(url)) {
return ""; return "";
} }
String host;
try { try {
URL urlObj = new URL(url); URL urlObj = new URL(url);
byte[] data = HttpUtil.download(urlIconAddress + "/icon?url=" + urlObj.getHost() + "&size=8..16..64", false); host = urlObj.getHost();
String base64 = new String(Base64.getEncoder().encode(data)); } catch (Exception e) {
if (StrUtil.isNotEmpty(base64)) {
return "data:image/png;base64," + base64;
} else {
log.warn("url无法获取icon:{}", url);
}
} catch (MalformedURLException e) {
log.warn("url无法解析出domain:{}", url); log.warn("url无法解析出domain:{}", url);
return "";
}
String iconPath = hostIconDao.selectByHost(host);
if (iconPath != null) {
return iconPath;
}
iconPath = saveFile(host, urlIconAddress + "/icon?url=" + host + "&size=16..64..256");
if (StrUtil.isNotEmpty(iconPath)) {
hostIconDao.insert(host, iconPath);
}
return iconPath;
}
private String saveFile(String host, String url) {
try {
try (Response res = HttpUtil.getClient(false).newCall(new Request.Builder().url(url)
.header("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.75 Safari/537.36 Edg/100.0.1185.36")
.get().build()).execute()) {
assert res.body() != null;
if (!HttpUtil.checkIsOk(res.code())) {
throw new CustomException("请求错误:" + res.code());
}
byte[] data = res.body().byteStream().readAllBytes();
if (data.length > 0) {
String iconUrl = res.request().url().toString();
String fileName = URLEncoder.encode(host, StandardCharsets.UTF_8) + iconUrl.substring(iconUrl.lastIndexOf("."));
String filePath = Paths.get(FileConstant.FAVICON_PATH, host.substring(0, 2), fileName).toString();
FileUtil.writeBytes(data, Paths.get(CommonConstant.fileSavePath, filePath).toString());
return File.separator + filePath;
} else {
log.info("未获取到icon:{}", url);
}
}
} catch (Exception e) { } catch (Exception e) {
log.error("url获取icon故障:{}", url, e); log.error("url获取icon故障:{}", url, e);
} }

View File

@ -1,5 +1,6 @@
package com.fanxb.bookmark.business.user.constant; package com.fanxb.bookmark.business.user.constant;
import com.fanxb.bookmark.common.constant.CommonConstant;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.nio.file.Paths; import java.nio.file.Paths;
@ -17,6 +18,6 @@ public class FileConstant {
/** /**
* 用户头像目录 * 用户头像目录
*/ */
public static String iconPath = Paths.get("files", "public", "icon").toString(); public static String iconPath = Paths.get(CommonConstant.fileSavePath, "files", "public", "icon").toString();
} }

View File

@ -12,8 +12,6 @@ import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct; import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.net.Proxy; import java.net.Proxy;
import java.util.Map; import java.util.Map;
@ -51,42 +49,33 @@ public class HttpUtil {
/** /**
* 无代理环境 * 无代理环境
*/ */
private static final OkHttpClient CLIENT = new OkHttpClient.Builder().connectTimeout(2, TimeUnit.SECONDS) private static final OkHttpClient CLIENT = new OkHttpClient.Builder().connectTimeout(1, TimeUnit.SECONDS)
.readTimeout(60, TimeUnit.SECONDS) .readTimeout(60, TimeUnit.SECONDS)
.build(); .build();
/**
* 获取客户端
*
* @param proxy 是否代理
* @return {@link OkHttpClient}
* @author fanxb
*/
public static OkHttpClient getClient(boolean proxy) {
return proxy ? PROXY_CLIENT : CLIENT;
}
public static final MediaType JSON = MediaType.get("application/json; charset=utf-8"); public static final MediaType JSON = MediaType.get("application/json; charset=utf-8");
@PostConstruct @PostConstruct
public void init() { public void init() {
OkHttpClient.Builder builder = new OkHttpClient.Builder(); OkHttpClient.Builder builder = new OkHttpClient.Builder().connectTimeout(1, TimeUnit.SECONDS).readTimeout(60, TimeUnit.SECONDS);
log.info("代理配置ip:{},port:{}", proxyIp, proxyPort); log.info("代理配置ip:{},port:{}", proxyIp, proxyPort);
if (StrUtil.isNotBlank(proxyIp) && StrUtil.isNotBlank(proxyPort)) { if (StrUtil.isNotBlank(proxyIp) && StrUtil.isNotBlank(proxyPort)) {
builder.proxy(new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyIp, Integer.parseInt(proxyPort)))); builder.proxy(new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyIp, Integer.parseInt(proxyPort))));
proxyExist = true; proxyExist = true;
} PROXY_CLIENT = builder.build();
PROXY_CLIENT = builder.connectTimeout(10, TimeUnit.SECONDS)
.readTimeout(60, TimeUnit.SECONDS)
.build();
}
/***
* 下载文件
* @author fanxb
* @param url 下载链接
* @param proxy 是否使用代理
* @return java.io.InputStream
* @date 2021/3/12
**/
public static byte[] download(String url, boolean proxy) {
try (Response res = (proxy ? PROXY_CLIENT : CLIENT).newCall(new Request.Builder().url(url).build()).execute()) {
assert res.body() != null;
if (checkIsOk(res.code())) {
return res.body().byteStream().readAllBytes();
} else { } else {
throw new CustomException("下载出现问题:" + res.body().string()); PROXY_CLIENT = CLIENT;
}
} catch (Exception e) {
throw new CustomException(e);
} }
} }
@ -270,6 +259,8 @@ public class HttpUtil {
} }
return ipAddress; return ipAddress;
} }
} }

View File

@ -1,17 +0,0 @@
<!DOCTYPE NETSCAPE-Bookmark-file-1>
<!-- This is an automatically generated file.
It will be read and overwritten.
DO NOT EDIT! -->
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8">
<TITLE>Bookmarks</TITLE>
<H1>Bookmarks Menu</H1>
<DL><p>
<DT><A HREF="http://0.0.0.1/" ADD_DATE="1614837460" LAST_MODIFIED="1614837465">1</A>
<DT><A HREF="http://0.0.0.2/" ADD_DATE="1614837471" LAST_MODIFIED="1614837474">2</A>
<DT><H3 ADD_DATE="1614837478" LAST_MODIFIED="1614837497">f1</H3>
<DL><p>
<DT><A HREF="http://asdf/" ADD_DATE="1614837485" LAST_MODIFIED="1614837493" TAGS="ww">f11</A>
<DT><A HREF="http://f12/" ADD_DATE="1614837497" LAST_MODIFIED="1614837502">f12</A>
</DL><p>
</DL>

View File

@ -1,17 +0,0 @@
<!DOCTYPE NETSCAPE-Bookmark-file-1>
<!-- This is an automatically generated file.
It will be read and overwritten.
DO NOT EDIT! -->
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8">
<TITLE>Bookmarks</TITLE>
<H1>Bookmarks Menu</H1>
<DL><p>
<DT><A HREF="http://0.0.0.1/" ADD_DATE="1614837460" LAST_MODIFIED="1614837465">1</A>
<DT><A HREF="http://0.0.0.2/" ADD_DATE="1614837471" LAST_MODIFIED="1614837474">2</A>
<DT><H3 ADD_DATE="1614837478" LAST_MODIFIED="1614837497">f1</H3>
<DL><p>
<DT><A HREF="http://asdf/" ADD_DATE="1614837485" LAST_MODIFIED="1614837493" TAGS="ww">f11</A>
<DT><A HREF="http://f12/" ADD_DATE="1614837497" LAST_MODIFIED="1614837502">f12</A>
</DL><p>
</DL>

View File

@ -0,0 +1,10 @@
CREATE TABLE bookmark.host_icon (
id INT UNSIGNED auto_increment NOT NULL,
host varchar(300) NOT NULL COMMENT 'host',
iconPath varchar(330) NOT NULL,
CONSTRAINT host_icon_pk PRIMARY KEY (id)
)
ENGINE=InnoDB
DEFAULT CHARSET=utf8mb4
COLLATE=utf8mb4_0900_ai_ci;
CREATE INDEX host_icon_host_IDX USING BTREE ON bookmark.host_icon (host(20));

View File

@ -3,6 +3,7 @@ node_modules
/dist /dist
package-lock.json package-lock.json
yarn.lock yarn.lock
public/files
# local env files # local env files
.env.local .env.local

Binary file not shown.

View File

@ -6,7 +6,7 @@
<script> <script>
export default { export default {
name: "App", name: "App"
}; };
</script> </script>

View File

@ -1,13 +1,14 @@
import Vue from "vue"; import Vue from "vue";
import VueRouter from "vue-router"; import VueRouter from "vue-router";
import * as vuex from "../store/index.js"; import * as vuex from "../store/index.js";
import { GLOBAL_CONFIG, SUPPORT_NO_LOGIN, TOKEN } from "@/store/modules/globalConfig"; import { GLOBAL_CONFIG, SUPPORT_NO_LOGIN, TOKEN, setToken } from "@/store/modules/globalConfig";
import { checkJwtValid } from "@/util/UserUtil"; import { checkJwtValid } from "@/util/UserUtil";
Vue.use(VueRouter); Vue.use(VueRouter);
const routes = [ const routes = [
{ path: "/", component: () => import("@/views/home/index") }, { path: "/", component: () => import("@/views/home/index") },
{ path: "/noHead/addBookmark", component: () => import("@/views/noHead/addBookmark/index") },
{ {
path: "/manage", path: "/manage",
component: () => import("@/views/manage/index"), component: () => import("@/views/manage/index"),
@ -15,6 +16,7 @@ const routes = [
{ path: "", redirect: "/manage/bookmarkTree" }, { path: "", redirect: "/manage/bookmarkTree" },
{ path: "bookmarkTree", component: () => import("@/views/manage/bookmarkTree/index") }, { path: "bookmarkTree", component: () => import("@/views/manage/bookmarkTree/index") },
{ path: "personSpace/userInfo", component: () => import("@/views/manage/personSpace/index") }, { path: "personSpace/userInfo", component: () => import("@/views/manage/personSpace/index") },
{ path: "sso/auth", component: () => import("@/views/manage/sso/auth/index") }
] ]
}, },
{ {
@ -26,7 +28,7 @@ const routes = [
{ path: "resetPassword", component: () => import("@/views/public/passwordReset/index") }, { path: "resetPassword", component: () => import("@/views/public/passwordReset/index") },
{ path: "oauth/github", component: () => import("@/views/public/oauth/github/index") }, { path: "oauth/github", component: () => import("@/views/public/oauth/github/index") },
{ path: "about", component: () => import("@/views/public/about/index") }, { path: "about", component: () => import("@/views/public/about/index") },
{ path: "404", component: () => import("@/views/public/notFound/index") }, { path: "404", component: () => import("@/views/public/notFound/index") }
] ]
}, },
{ path: "*", redirect: "/public/404" } { path: "*", redirect: "/public/404" }
@ -41,11 +43,15 @@ const router = new VueRouter({
* 在此进行登录信息判断以及重定向到登录页面 * 在此进行登录信息判断以及重定向到登录页面
*/ */
router.beforeEach(async (to, from, next) => { router.beforeEach(async (to, from, next) => {
//进入主页面/管理页面时,确认已经进行初始化操作 if (to.query.token && checkJwtValid(to.query.token)) {
if (to.path === '/' || to.path.startsWith("/manage")) { console.log("获取到页面token", to.query.token);
await vuex.default.dispatch(GLOBAL_CONFIG + "/" + setToken, to.query.token);
}
//进入除/public以外的路由确认已经进行初始化操作
if (!to.path.startsWith("/public")) {
await vuex.loginInit(); await vuex.loginInit();
} }
let supportNoLogin = to.path === '/' || to.path.startsWith("/public"); let supportNoLogin = to.path === "/" || to.path.startsWith("/public");
vuex.default.commit(GLOBAL_CONFIG + "/" + SUPPORT_NO_LOGIN, supportNoLogin); vuex.default.commit(GLOBAL_CONFIG + "/" + SUPPORT_NO_LOGIN, supportNoLogin);
if (!supportNoLogin && !checkJwtValid(vuex.default.state[GLOBAL_CONFIG][TOKEN])) { if (!supportNoLogin && !checkJwtValid(vuex.default.state[GLOBAL_CONFIG][TOKEN])) {
//如不支持未登录进入切jwt已过期直接跳转到登录页面,并清理缓存 //如不支持未登录进入切jwt已过期直接跳转到登录页面,并清理缓存
@ -58,8 +64,6 @@ router.beforeEach(async (to, from, next) => {
} else { } else {
next(); next();
} }
}) });
export default router; export default router;

View File

@ -11,7 +11,14 @@ export const IS_PHONE = "isPhone";
export const noLoginInit = "noLoginInit"; export const noLoginInit = "noLoginInit";
export const loginInit = "loginInit"; export const loginInit = "loginInit";
/**
* 登出清除数据
*/
export const clear = "clear"; export const clear = "clear";
/**
* 设置token
*/
export const setToken = "setToken";
/** /**
* 存储全局配置 * 存储全局配置
*/ */
@ -46,7 +53,7 @@ const getters = {};
const actions = { const actions = {
//未登录需要进行的初始化 //未登录需要进行的初始化
async [noLoginInit] ({ commit }) { async [noLoginInit]({ commit }) {
commit(SERVER_CONFIG, await HttpUtil.get("/common/config/global")); commit(SERVER_CONFIG, await HttpUtil.get("/common/config/global"));
let token = await localforage.getItem(TOKEN); let token = await localforage.getItem(TOKEN);
if (token) { if (token) {
@ -55,7 +62,7 @@ const actions = {
} }
}, },
//登陆后的,初始化数据 //登陆后的,初始化数据
async [loginInit] (context) { async [loginInit](context) {
if (context.state.isInit) { if (context.state.isInit) {
return; return;
} }
@ -63,38 +70,36 @@ const actions = {
context.commit(USER_INFO, userInfo); context.commit(USER_INFO, userInfo);
context.commit(IS_INIT, true); context.commit(IS_INIT, true);
}, },
async setToken ({ commit }, token) { async [setToken]({ commit }, token) {
await localforage.setItem(TOKEN, token); await localforage.setItem(TOKEN, token);
window.jwtToken = token; window.jwtToken = token;
commit(TOKEN, token); commit(TOKEN, token);
}, },
//登出清除数据 async [clear](context) {
async [clear] (context) {
await localforage.removeItem(TOKEN); await localforage.removeItem(TOKEN);
context.commit(USER_INFO, null); context.commit(USER_INFO, null);
context.commit(TOKEN, null); context.commit(TOKEN, null);
context.commit(IS_INIT, false); context.commit(IS_INIT, false);
},
};
const mutations = {
[USER_INFO] (state, userInfo) {
state[USER_INFO] = userInfo;
},
[TOKEN] (state, token) {
state[TOKEN] = token;
},
[IS_INIT] (state, isInit) {
state[IS_INIT] = isInit;
},
[SERVER_CONFIG] (state, serverConfig) {
state[SERVER_CONFIG] = serverConfig;
},
[SUPPORT_NO_LOGIN] (state, val) {
state[SUPPORT_NO_LOGIN] = val;
} }
}; };
const mutations = {
[USER_INFO](state, userInfo) {
state[USER_INFO] = userInfo;
},
[TOKEN](state, token) {
state[TOKEN] = token;
},
[IS_INIT](state, isInit) {
state[IS_INIT] = isInit;
},
[SERVER_CONFIG](state, serverConfig) {
state[SERVER_CONFIG] = serverConfig;
},
[SUPPORT_NO_LOGIN](state, val) {
state[SUPPORT_NO_LOGIN] = val;
}
};
export const store = { export const store = {
namespaced: true, namespaced: true,

View File

@ -30,6 +30,10 @@ export const clear = "clear";
* 删除书签数据 * 删除书签数据
*/ */
export const deleteData = "deleteData"; export const deleteData = "deleteData";
/**
* 新增节点
*/
export const addNode = "addNode";
/** /**
* 版本检查定时调度 * 版本检查定时调度
@ -72,10 +76,8 @@ const getters = {
}; };
const actions = { const actions = {
async [noLoginInit] () { async [noLoginInit]() {},
async [loginInit](context) {
},
async [loginInit] (context) {
if (context.state.isInit || context.state.isIniting) { if (context.state.isInit || context.state.isIniting) {
return; return;
} }
@ -91,7 +93,7 @@ const actions = {
/** /**
* 确保数据加载完毕 * 确保数据加载完毕
*/ */
ensureDataOk (context) { ensureDataOk(context) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
let timer = setInterval(() => { let timer = setInterval(() => {
try { try {
@ -106,7 +108,7 @@ const actions = {
}); });
}, },
//刷新缓存数据 //刷新缓存数据
async [refresh] (context) { async [refresh](context) {
let treeData = await HttpUtil.get("/bookmark/currentUser"); let treeData = await HttpUtil.get("/bookmark/currentUser");
if (!treeData[""]) { if (!treeData[""]) {
treeData[""] = []; treeData[""] = [];
@ -125,7 +127,7 @@ const actions = {
await localforage.setItem(TOTAL_TREE_DATA, treeData); await localforage.setItem(TOTAL_TREE_DATA, treeData);
}, },
//清除缓存数据 //清除缓存数据
async [clear] (context) { async [clear](context) {
context.commit(TOTAL_TREE_DATA, null); context.commit(TOTAL_TREE_DATA, null);
context.commit(VERSION, null); context.commit(VERSION, null);
context.commit(SHOW_REFRESH_TOAST, false); context.commit(SHOW_REFRESH_TOAST, false);
@ -141,7 +143,7 @@ const actions = {
/** /**
* 移动节点 * 移动节点
*/ */
async moveNode (context, info) { async moveNode(context, info) {
let data = context.state[TOTAL_TREE_DATA]; let data = context.state[TOTAL_TREE_DATA];
const target = info.node.dataRef; const target = info.node.dataRef;
const current = info.dragNode.dataRef; const current = info.dragNode.dataRef;
@ -209,25 +211,24 @@ const actions = {
await localforage.setItem(TOTAL_TREE_DATA, state[TOTAL_TREE_DATA]); await localforage.setItem(TOTAL_TREE_DATA, state[TOTAL_TREE_DATA]);
return body; return body;
}, },
async [refreshHomePinList] ({ commit }) { async [refreshHomePinList]({ commit }) {
let list = await HttpUtil.get("/home/pin"); let list = await HttpUtil.get("/home/pin");
commit(HOME_PIN_LIST, list); commit(HOME_PIN_LIST, list);
let map = {}; let map = {};
list.filter(item => item.id).forEach(item => map[item.bookmarkId] = true); list.filter(item => item.id).forEach(item => (map[item.bookmarkId] = true));
commit(HOME_PIN_BOOKMARK_ID_MAP, map); commit(HOME_PIN_BOOKMARK_ID_MAP, map);
}, },
/** /**
* 更新版本数据 * 更新版本数据
*/ */
async updateVersion ({ commit, state }, version) { async updateVersion({ commit, state }, version) {
commit(VERSION, version == null ? state[VERSION] + 1 : version); commit(VERSION, version == null ? state[VERSION] + 1 : version);
await localforage.setItem(VERSION, state[VERSION]); await localforage.setItem(VERSION, state[VERSION]);
}, },
/** /**
* 新增书签文件夹 * 新增书签文件夹
*/ */
async addNode (context, { sourceNode, targetNode }) { async [addNode](context, { sourceNode, targetNode }) {
if (sourceNode === null) { if (sourceNode === null) {
if (context.state[TOTAL_TREE_DATA][""] === undefined) { if (context.state[TOTAL_TREE_DATA][""] === undefined) {
context.state[TOTAL_TREE_DATA][""] = []; context.state[TOTAL_TREE_DATA][""] = [];
@ -252,7 +253,7 @@ const actions = {
/** /**
* 删除节点数据 * 删除节点数据
*/ */
async [deleteData] (context, { pathList, bookmarkIdList }) { async [deleteData](context, { pathList, bookmarkIdList }) {
//待删除的书签 //待删除的书签
let bookmarkIdSet = new Set(); let bookmarkIdSet = new Set();
bookmarkIdList.forEach(item => bookmarkIdSet.add(item)); bookmarkIdList.forEach(item => bookmarkIdSet.add(item));
@ -280,7 +281,7 @@ const actions = {
/** /**
* 编辑书签节点 * 编辑书签节点
*/ */
async editNode ({ dispatch, state, commit }, { node, newName, newUrl, newIcon }) { async editNode({ dispatch, state, commit }, { node, newName, newUrl, newIcon }) {
node.name = newName; node.name = newName;
node.url = newUrl; node.url = newUrl;
node.icon = newIcon; node.icon = newIcon;
@ -294,10 +295,10 @@ const mutations = {
[TOTAL_TREE_DATA]: (state, totalTreeData) => { [TOTAL_TREE_DATA]: (state, totalTreeData) => {
state.totalTreeData = totalTreeData; state.totalTreeData = totalTreeData;
}, },
[IS_INIT] (state, isInit) { [IS_INIT](state, isInit) {
state.isInit = isInit; state.isInit = isInit;
}, },
[IS_INITING] (state, isIniting) { [IS_INITING](state, isIniting) {
state.isIniting = isIniting; state.isIniting = isIniting;
}, },
[VERSION]: (state, version) => { [VERSION]: (state, version) => {
@ -314,7 +315,6 @@ const mutations = {
} }
}; };
/** /**
* 检查书签缓存是否最新 * 检查书签缓存是否最新
* *
@ -322,7 +322,7 @@ const mutations = {
* @param {*} isFirst * @param {*} isFirst
* @returns * @returns
*/ */
async function treeDataCheck (context, isFirst) { async function treeDataCheck(context, isFirst) {
if (toastShow || !checkJwtValid(context.rootState.globalConfig.token)) { if (toastShow || !checkJwtValid(context.rootState.globalConfig.token)) {
return; return;
} }
@ -336,14 +336,14 @@ async function treeDataCheck (context, isFirst) {
closable: false, closable: false,
keyboard: false, keyboard: false,
maskClosable: false, maskClosable: false,
onOk () { onOk() {
toastShow = false; toastShow = false;
return new Promise(async (resolve) => { return new Promise(async resolve => {
await context.dispatch(refresh); await context.dispatch(refresh);
resolve(); resolve();
}); });
}, },
onCancel () { onCancel() {
toastShow = false; toastShow = false;
} }
}); });
@ -361,4 +361,3 @@ export const store = {
actions, actions,
mutations mutations
}; };

View File

@ -77,7 +77,7 @@
<a-menu-item v-if="!rec.dataRef.isLeaf" key="add">新增</a-menu-item> <a-menu-item v-if="!rec.dataRef.isLeaf" key="add">新增</a-menu-item>
<a-menu-item v-else key="copy" class="copy-to-board" :data="rec.dataRef.url">复制URL</a-menu-item> <a-menu-item v-else key="copy" class="copy-to-board" :data="rec.dataRef.url">复制URL</a-menu-item>
<a-menu-item v-if="rec.dataRef.isLeaf" key="pin"> <a-menu-item v-if="rec.dataRef.isLeaf" key="pin">
{{ homePinList.filter((item) => item.id && item.bookmarkId == rec.dataRef.bookmarkId).length > 0 ? "从首页移除" : "固定到首页" }} {{ homePinList.filter(item => item.id && item.bookmarkId == rec.dataRef.bookmarkId).length > 0 ? "从首页移除" : "固定到首页" }}
</a-menu-item> </a-menu-item>
<a-menu-item key="edit">编辑</a-menu-item> <a-menu-item key="edit">编辑</a-menu-item>
<a-menu-item key="delete">删除</a-menu-item> <a-menu-item key="delete">删除</a-menu-item>
@ -114,7 +114,7 @@ export default {
loadedKeys: [], // loadedKeys: [], //
replaceFields: { replaceFields: {
title: "name", title: "name",
key: "bookmarkId", key: "bookmarkId"
}, },
mulSelect: false, // mulSelect: false, //
currentSelect: null, // currentSelect: null, //
@ -126,19 +126,19 @@ export default {
// null // null
targetNode: null, targetNode: null,
// //
isAdd: false, isAdd: false
}, },
copyBoard: null, // copyBoard: null //
}; };
}, },
computed: { computed: {
...mapState("treeData", ["totalTreeData", HOME_PIN_LIST]), ...mapState("treeData", ["totalTreeData", HOME_PIN_LIST]),
...mapState("globalConfig", ["isPhone"]), ...mapState("globalConfig", ["isPhone"])
}, },
watch: { watch: {
totalTreeData(newVal, oldVal) { totalTreeData(newVal, oldVal) {
this.resetData(); this.resetData();
}, }
}, },
async mounted() { async mounted() {
this.$store.commit(TREE_DATA + "/" + SHOW_REFRESH_TOAST, true); this.$store.commit(TREE_DATA + "/" + SHOW_REFRESH_TOAST, true);
@ -147,14 +147,21 @@ export default {
this.loading = false; this.loading = false;
//clipboard //clipboard
this.copyBoard = new ClipboardJS(".copy-to-board", { this.copyBoard = new ClipboardJS(".copy-to-board", {
text: function (trigger) { text: function(trigger) {
return trigger.attributes.data.nodeValue; return trigger.attributes.data.nodeValue;
}, }
}); });
this.copyBoard.on("success", (e) => { this.copyBoard.on("success", e => {
this.$message.success("复制成功"); this.$message.success("复制成功");
e.clearSelection(); e.clearSelection();
}); });
window.onblur = e => {
console.log("窗口非激活");
};
window.onfocus = e => {
console.log("窗口激活");
};
}, },
beforeDestroy() { beforeDestroy() {
this.$store.commit(TREE_DATA + "/" + SHOW_REFRESH_TOAST, false); this.$store.commit(TREE_DATA + "/" + SHOW_REFRESH_TOAST, false);
@ -168,7 +175,7 @@ export default {
*/ */
loadData(treeNode) { loadData(treeNode) {
console.log("加载数据", treeNode); console.log("加载数据", treeNode);
return new Promise((resolve) => { return new Promise(resolve => {
const data = typeof treeNode === "number" ? this.$store.getters["treeData/getById"](treeNode) : treeNode.dataRef; const data = typeof treeNode === "number" ? this.$store.getters["treeData/getById"](treeNode) : treeNode.dataRef;
let newPath = data.path + "." + data.bookmarkId; let newPath = data.path + "." + data.bookmarkId;
if (!this.totalTreeData[newPath]) { if (!this.totalTreeData[newPath]) {
@ -212,9 +219,9 @@ export default {
this.expandedKeys = [ this.expandedKeys = [
...item.path ...item.path
.split(".") .split(".")
.filter((item) => item.length > 0) .filter(item => item.length > 0)
.map((item) => parseInt(item)), .map(item => parseInt(item)),
item.bookmarkId, item.bookmarkId
]; ];
} else { } else {
this.expandedKeys.pop(); this.expandedKeys.pop();
@ -228,7 +235,7 @@ export default {
} else { } else {
this.checkedKeys.splice(this.checkedKeys.indexOf(item.bookmarkId), 1); this.checkedKeys.splice(this.checkedKeys.indexOf(item.bookmarkId), 1);
this.checkedNodes.splice( this.checkedNodes.splice(
this.checkedNodes.findIndex((item1) => item1.bookmarkId === item.bookmarkId), this.checkedNodes.findIndex(item1 => item1.bookmarkId === item.bookmarkId),
1 1
); );
} }
@ -248,9 +255,9 @@ export default {
this.expandedKeys = [ this.expandedKeys = [
...item.path ...item.path
.split(".") .split(".")
.filter((item) => item.length > 0) .filter(item => item.length > 0)
.map((item) => parseInt(item)), .map(item => parseInt(item)),
item.bookmarkId, item.bookmarkId
]; ];
} }
} else { } else {
@ -273,7 +280,7 @@ export default {
const bookmarkIdList = []; const bookmarkIdList = [];
const pathList = []; const pathList = [];
if (this.checkedNodes) { if (this.checkedNodes) {
this.checkedNodes.forEach((item) => this.checkedNodes.forEach(item =>
item.type === 1 ? pathList.push(item.path + "." + item.bookmarkId) : bookmarkIdList.push(item.bookmarkId) item.type === 1 ? pathList.push(item.path + "." + item.bookmarkId) : bookmarkIdList.push(item.bookmarkId)
); );
} }
@ -290,7 +297,7 @@ export default {
await HttpUtil.post("/bookmark/batchDelete", null, { pathList, bookmarkIdList }); await HttpUtil.post("/bookmark/batchDelete", null, { pathList, bookmarkIdList });
await this.$store.dispatch(TREE_DATA + "/" + deleteData, { pathList, bookmarkIdList }); await this.$store.dispatch(TREE_DATA + "/" + deleteData, { pathList, bookmarkIdList });
// //
pathList.forEach((item) => { pathList.forEach(item => {
const id = parseInt(item.split(".").reverse()[0]); const id = parseInt(item.split(".").reverse()[0]);
let index = this.loadedKeys.indexOf(id); let index = this.loadedKeys.indexOf(id);
if (index > -1) { if (index > -1) {
@ -322,13 +329,13 @@ export default {
this.refresh(false); this.refresh(false);
this.expandedKeys = item.path this.expandedKeys = item.path
.split(".") .split(".")
.filter((one) => one.length > 0) .filter(one => one.length > 0)
.map((one) => parseInt(one)); .map(one => parseInt(one));
this.loadedKeys = item.path this.loadedKeys = item.path
.split(".") .split(".")
.filter((one) => one.length > 0) .filter(one => one.length > 0)
.map((one) => parseInt(one)); .map(one => parseInt(one));
this.expandedKeys.forEach(async (one) => await this.loadData(one)); this.expandedKeys.forEach(async one => await this.loadData(one));
this.currentSelect = item; this.currentSelect = item;
}, },
/** /**
@ -344,7 +351,7 @@ export default {
this.addModal = { this.addModal = {
show: false, show: false,
targetNode: null, targetNode: null,
isAdd: false, isAdd: false
}; };
}, },
async onDrop(info) { async onDrop(info) {
@ -388,12 +395,12 @@ export default {
await this.deleteBookmarks(); await this.deleteBookmarks();
resolve(); resolve();
}); });
}, }
}); });
} else if (key === "edit") { } else if (key === "edit") {
this.editData(); this.editData();
} else if (key === "pin") { } else if (key === "pin") {
let pin = this.homePinList.filter((one) => one.id && one.bookmarkId == item.bookmarkId); let pin = this.homePinList.filter(one => one.id && one.bookmarkId == item.bookmarkId);
if (pin.length > 0) { if (pin.length > 0) {
await HttpUtil.delete("/home/pin", { id: pin[0].id }); await HttpUtil.delete("/home/pin", { id: pin[0].id });
} else { } else {
@ -411,8 +418,8 @@ export default {
dealList(root, map[""], map); dealList(root, map[""], map);
let content = exportFileHead + root.outerHTML; let content = exportFileHead + root.outerHTML;
downloadFile(moment().format("YYYY-MM-DD") + "导出书签.html", content); downloadFile(moment().format("YYYY-MM-DD") + "导出书签.html", content);
}, }
}, }
}; };
</script> </script>

View File

@ -0,0 +1,39 @@
<template>
<div class="ssoMain">{{ message }}</div>
</template>
<script>
import { GLOBAL_CONFIG, TOKEN } from "@/store/modules/globalConfig";
export default {
name: "ssoPage",
data() {
return {
message: "loading"
};
},
mounted() {
window.addEventListener("message", event => {
if (!event.data.code) {
return;
}
console.log("收到content消息", event);
if (event.data.code == "setTokenOk") {
this.message = "登陆成功3s后关闭本页面";
setTimeout(() => window.close(), 3000);
}
});
let token = this.$store.state[GLOBAL_CONFIG][TOKEN];
window.postMessage({ code: "setToken", data: token }, "*");
},
beforeDestroy() {
window.removeEventListener("message");
}
};
</script>
<style lang="less" scoped>
.ssoMain {
text-align: center;
}
</style>

View File

@ -0,0 +1,63 @@
<template>
<div class="ssoAddBookmark">
正在添加请稍后
<!-- <button @click="closeIframe">关闭</button> -->
</div>
</template>
<script>
import HttpUtil from "@/util/HttpUtil";
import { TREE_DATA, addNode } from "@/store/modules/treeData";
export default {
data() {
return {
form: {
name: null,
url: null,
type: 0,
path: ""
}
};
},
mounted() {
//
window.addEventListener("message", event => {
if (!event.data.code) {
return;
}
console.log("收到content消息", event);
if (event.data.code == "addBookmarkAction") {
console.log("新增书签");
this.form.name = event.data.data.name;
this.form.url = event.data.data.url;
this.addBookmark();
}
});
console.log("向父节点获取数据");
window.parent.postMessage({ code: "getBookmarkData", receiver: "content" }, "*");
},
methods: {
closeIframe() {
window.parent.postMessage({ code: "closeIframe", receiver: "content" }, "*");
},
//
async addBookmark() {
let res = await HttpUtil.put("/bookmark", null, this.form);
this.$message.success("添加成功");
await this.$store.dispatch(TREE_DATA + "/" + addNode, { sourceNode: null, targetNode: res });
setTimeout(this.closeIframe, 500);
}
}
};
</script>
<style lang="less" scoped>
.ssoAddBookmark {
display: flex;
justify-content: center;
align-items: center;
background: white;
width: 100%;
height: 100vh;
}
</style>

View File

@ -9,6 +9,11 @@
使用教程 使用教程
<a href="https://blog.fleyx.com/blog/detail/20220329" target="_blank">点击跳转</a> <a href="https://blog.fleyx.com/blog/detail/20220329" target="_blank">点击跳转</a>
</div> </div>
<div>
浏览器插件
<a href="/static/bookmarkBrowserPlugin.7z" download="浏览器插件.7z" target="_blank">点击下载</a>
,使用详情请参考使用教程
</div>
<div>交流反馈qq群150056494,邮箱fleyx20@outlook.com</div> <div>交流反馈qq群150056494,邮箱fleyx20@outlook.com</div>
<div> <div>
统计 统计
@ -38,7 +43,7 @@ export default {
script.defer = true; script.defer = true;
script.src = "https://qiezi.fleyx.com/qiezijs/1.0/qiezi_statistic.min.js"; script.src = "https://qiezi.fleyx.com/qiezijs/1.0/qiezi_statistic.min.js";
document.getElementsByTagName("head")[0].appendChild(script); document.getElementsByTagName("head")[0].appendChild(script);
}, }
}; };
</script> </script>

View File

@ -0,0 +1,100 @@
chrome.runtime.onInstalled.addListener(() => {
chrome.contextMenus.create(
{
title: '添加到书签',
id: "addBookmark",
},
() => console.log("创建右键菜单成功")
);
});
chrome.contextMenus.onClicked.addListener(async function (info, tab) {
console.log(info, tab);
let body = {
name: tab.title,
url: tab.url,
};
sendToContent(tab.id, { code: "addBookmark", data: body, token: await getVal("token") });
});
// 接收content/popup发送的消息
chrome.runtime.onMessage.addListener(async (data, sender, sendResponse) => {
if (!data.code || !data.receiver == 'background') {
return;
}
sendResponse("ok");
console.log("收到消息:", data, sender);
if (data.code == 'setToken') {
await setVal("token", data.data);
// sendToContent
await sendToContent(sender.tab.id, { code: "setTokenOk" });
} else if (data.code == 'getToken') {
let token = await getVal("token");
sendToPopup({ code: "setToken", data: await getVal("token") });
} else if (data.code == "clearToken") {
await clearVal("token");
}
})
/**
* 向content发送消息
* @param {*} tabId
* @param {*} data
*/
function sendToContent (tabId, data) {
console.log(tabId, data);
data.receiver = "content";
chrome.tabs.sendMessage(tabId, data, res => {
console.log("接受响应", res);
})
}
/**
* 向popup发送消息
* @param {*} data
*/
function sendToPopup (data) {
data.receiver = "popup";
chrome.runtime.sendMessage(data, res => console.log(res));
}
/**
* 设置值
* @param {*} key
* @param {*} val
* @returns
*/
function setVal (key, val) {
return new Promise((resolve, reject) => {
chrome.storage.local.set({ [key]: val }, function () {
console.log("设置值成功:", key, val)
resolve();
})
})
}
/**
* 获取值
* @param {*} key
* @returns
*/
function getVal (key) {
return new Promise((resolve, reject) => {
chrome.storage.local.get([key], function (res) {
console.log("取值成功", res);
resolve(res[key]);
})
})
}
function clearVal (key) {
return new Promise((resolve, reject) => {
chrome.storage.local.remove(key, function () {
console.log("remove成功", key);
resolve();
})
})
}

View File

@ -0,0 +1,26 @@
{
"name": "签签世界",
"description": "云书签管理平台",
"version": "1.0",
"manifest_version": 3,
"permissions": ["contextMenus", "storage"],
"action": {
"default_popup": "popup/index.html"
},
"icons": {
"48": "static/icons/favicon.png",
"128": "static/icons/favicon.png"
},
"background": {
"service_worker": "background.js"
},
"options_ui": {
"page": "options/index.html"
},
"content_scripts": [
{
"matches": ["*://*/*"],
"js": ["static/js/axios.min.js", "static/js/config.js", "static/js/content.js"]
}
]
}

View File

@ -0,0 +1,16 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
#content {
color: red;
}
</style>
</head>
<body>
<h1>option.html</h1>
</body>
</html>

View File

@ -0,0 +1,31 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
html,
body {
padding: 0.2em;
width: 8em;
}
#content {
color: red;
}
</style>
</head>
<body>
<a id="login" href="https://fleyx.com/userSpace/ssoAuth" target="_blank">点击登录</a>
<div id="action" style="display: none">
<button id="logout">退出登陆</button>
<!-- <button title="同步云端书签到浏览器(覆盖本地)">同步云端书签</button> -->
<!-- <button title="同步浏览器书签到云端(覆盖云端)">同步浏览器</button> -->
</div>
<p id="content"></p>
<div class="bottom">插件版本:<span id="version"></span></div>
<script type="text/javascript" src="/static/js/axios.min.js"></script>
<script type="text/javascript" src="/static/js/config.js"></script>
<script type="text/javascript" src="/popup/index.js"></script>
</body>
</html>

View File

@ -0,0 +1,50 @@
console.log("asdf");
console.log(bookmarkHost);
var token;
var login = document.getElementById("login");
var action = document.getElementById("action");
(async () => {
//初始化
login.href = bookmarkHost + "/manage/sso/auth";
document.getElementById("version").innerText = version;
sendToBg("getToken", null);
})();
/**
* 退出登陆
*/
document.getElementById("logout").addEventListener("click", () => {
console.log("click");
sendToBg("clearToken", null);
action.style.display = "none";
login.style.display = "block";
});
/**
* 发送消息到后台
* @param {*} data
*/
function sendToBg (code, data) {
chrome.runtime.sendMessage({ code, data, receiver: "background" }, res => console.log(res));
}
// 接收content/background发送的消息
chrome.runtime.onMessage.addListener(async (data, sender, sendResponse) => {
if (!data.code || !data.receiver == 'popup') {
return;
}
sendResponse("ok");
console.log("popup收到消息", data);
if (data.code == 'setToken') {
token = data.data;
if (token) {
action.style.display = "block";
login.style.display = "none";
} else {
login.style.display = "block";
}
}
})

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,10 @@
var bookmarkHost = "https://fleyx.com";
// var bookmarkHost = "http://localhost:8080";
var version = "0.1";
window.token = localStorage.getItem('token');
axios.defaults.baseURL = bookmarkHost + '/bookmark/api';
axios.defaults.headers.common['jwt-token'] = window.token;
axios.defaults.headers.post['Content-Type'] = 'application/json';
axios.defaults.headers.put['Content-Type'] = 'application/json';

View File

@ -0,0 +1,98 @@
console.log('注入了页面');
var bookmarkInfo = null;
var addBlockDiv = null;
var iframe = null;
/**
* 接收当前注入页面传来的消息
*/
window.addEventListener('message', function (event) {
console.log(event);
if (event.data.code === undefined) {
return;
}
console.log('接受到网页消息:', event.data);
if (event.data.code === 'getBookmarkData') {
iframe.contentWindow.postMessage({ code: "addBookmarkAction", data: bookmarkInfo }, "*");
} else if (event.data.code === 'setToken') {
sendToBg(event.data);
} else if (event.data.code == 'closeIframe') {
addBlockDiv.remove();
}
});
/**
* 接收content/background发送的消息
*/
chrome.runtime.onMessage.addListener(async (data, sender, sendResponse) => {
if (!data || !data.code || data.receiver != "content") {
return;
}
sendResponse("ok");
console.log('收到消息:', data);
if (data.code == 'setTokenOk') {
sendToPage(data);
} else if (data.code == 'addBookmark') {
await addBookmark(data);
}
});
async function addBookmark (data) {
if (!checkTokenValid(data.token)) {
alert("登陆失效,请登陆后,重试");
window.open(bookmarkHost + "/manage/sso/auth");
return;
}
//新增书签
console.log("新增书签", data.data);
bookmarkInfo = data.data;
addBlockDiv = document.createElement("div");
addBlockDiv.setAttribute("style", "position:fixed;width:100%;height:100vh;z-index:100000;left:0;top:0;background:rgba(211, 211, 205, 0.8)");
document.getElementsByTagName("body")[0].appendChild(addBlockDiv);
iframe = document.createElement("iframe");
iframe.src = bookmarkHost + "/noHead/addBookmark?token=" + data.token;
iframe.setAttribute("style", "width:70%;min-height:60vh;margin-left:15%;margin-top:10vh;padding:0;border:0;border-radius:10px");
addBlockDiv.appendChild(iframe);
}
/**
* 发送消息给bg
* @param {*} data
*/
function sendToBg (data) {
data.receiver = "background";
chrome.runtime.sendMessage(data, response => {
console.log(response);
});
}
/**
* 发消息到页面
* @param {*} data
*/
function sendToPage (data) {
data.receiver = "page";
window.postMessage(data, "*");
}
/**
* 检查token是否有效
* @param {*} token
* @returns
*/
function checkTokenValid (token) {
try {
if (token && token.trim().length > 0) {
//检查token是否还有效
let content = JSON.parse(window.atob(token.split(".")[1]));
if (content.exp > Date.now() / 1000) {
return true;
}
}
} catch (err) {
console.error(err);
}
return false;
}

File diff suppressed because one or more lines are too long