master #3
10
README.md
10
README.md
@ -22,6 +22,16 @@
|
|||||||
|
|
||||||
帮助文档:[点击跳转](https://blog.fleyx.com/blog/detail/20220329/)
|
帮助文档:[点击跳转](https://blog.fleyx.com/blog/detail/20220329/)
|
||||||
|
|
||||||
|
# 更新日志
|
||||||
|
|
||||||
|
## 2023-08-13
|
||||||
|
|
||||||
|
![pic](https://s3.fleyx.com/picbed/2023/08/Snipaste_2023-08-13_15-01-20.png)
|
||||||
|
|
||||||
|
搜索引擎支持自定义[#43](https://github.com/FleyX/bookmark/issues/43)
|
||||||
|
|
||||||
|
位置:右上角个人中心-管理搜索引擎
|
||||||
|
|
||||||
# TODO
|
# TODO
|
||||||
|
|
||||||
- [x] 主页功能
|
- [x] 主页功能
|
||||||
|
@ -1,16 +1,16 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="search">
|
<div class="search">
|
||||||
<div :class="{ listShow: focused && list.length > 0 }" class="newSearch">
|
<div :class="{ listShow: focused && list.length > 0 }" class="newSearch">
|
||||||
<input ref="searchInput" class="input" type="text" v-model="value" @keydown="keyPress" @focus="inputFocus" @blur="inputBlur" />
|
<input ref="searchInput" class="input" type="text" v-model="value" @keydown="keyPress" @focus="inputFocus"
|
||||||
|
@blur="inputBlur" />
|
||||||
<div class="action">
|
<div class="action">
|
||||||
<a-dropdown :trigger="['click']">
|
<a-dropdown :trigger="['click']">
|
||||||
<a-tooltip title="点击切换网页搜索">
|
<a-tooltip title="点击切换网页搜索">
|
||||||
<my-icon class="icon" style="margin-right: 0.5em" :type="searchIcon" />
|
<my-icon class="icon" style="margin-right: 0.5em" :type="checkedSearchEngine.icon"
|
||||||
|
@click="searchIconClick" />
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
<a-menu slot="overlay" @click="searchEngineChange">
|
<a-menu slot="overlay" @click="searchEngineChange">
|
||||||
<a-menu-item key="google">谷歌</a-menu-item>
|
<a-menu-item v-for="item in searchEngineList" :key="item.id">{{ item.name }}</a-menu-item>
|
||||||
<a-menu-item key="bing">bing</a-menu-item>
|
|
||||||
<a-menu-item key="baidu">baidu</a-menu-item>
|
|
||||||
</a-menu>
|
</a-menu>
|
||||||
</a-dropdown>
|
</a-dropdown>
|
||||||
<a-icon class="icon" type="search" @click="submit(true)" />
|
<a-icon class="icon" type="search" @click="submit(true)" />
|
||||||
@ -30,7 +30,8 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="icons">
|
<div class="icons">
|
||||||
<a-tooltip title="定位到书签树中" v-if="showLocation">
|
<a-tooltip title="定位到书签树中" v-if="showLocation">
|
||||||
<my-icon style="color: white; font-size: 1.3em" type="icon-et-location" @mousedown="location($event, item)" />
|
<my-icon style="color: white; font-size: 1.3em" type="icon-et-location"
|
||||||
|
@mousedown="location($event, item)" />
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
<a-tooltip title="复制链接">
|
<a-tooltip title="复制链接">
|
||||||
<a-icon
|
<a-icon
|
||||||
@ -61,10 +62,11 @@ import { mapState } from "vuex";
|
|||||||
import ClipboardJS from "clipboard";
|
import ClipboardJS from "clipboard";
|
||||||
import { GLOBAL_CONFIG, USER_INFO } from "@/store/modules/globalConfig";
|
import { GLOBAL_CONFIG, USER_INFO } from "@/store/modules/globalConfig";
|
||||||
import { TREE_DATA, refreshHomePinList, HOME_PIN_BOOKMARK_ID_MAP } from "@/store/modules/treeData";
|
import { TREE_DATA, refreshHomePinList, HOME_PIN_BOOKMARK_ID_MAP } from "@/store/modules/treeData";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "Search",
|
name: "Search",
|
||||||
props: {
|
props: {
|
||||||
showLocation: Boolean, //是否显示定位等按钮
|
showLocation: Boolean //是否显示定位等按钮
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
@ -74,19 +76,25 @@ export default {
|
|||||||
//上下选中
|
//上下选中
|
||||||
selectIndex: null,
|
selectIndex: null,
|
||||||
copyBoard: null, //剪贴板对象
|
copyBoard: null, //剪贴板对象
|
||||||
|
searchEngineList: [],
|
||||||
|
checkedSearchEngine: { icon: "icon-baidu", name: "百度", url: "https://www.baidu.com/s?ie=UTF-8&wd=%s" }
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
mounted() {
|
async mounted() {
|
||||||
//初始化clipboard
|
//初始化clipboard
|
||||||
this.copyBoard = new ClipboardJS(".search-copy-to-board", {
|
this.copyBoard = new ClipboardJS(".search-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();
|
||||||
});
|
});
|
||||||
|
if (this.$store.state.globalConfig.token != null) {
|
||||||
|
this.searchEngineList = await HttpUtil.get("/searchEngine/list");
|
||||||
|
this.checkedSearchEngine = this.searchEngineList.find(item => item.checked === 1);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
destroyed() {
|
destroyed() {
|
||||||
if (this.copyBoard != null) {
|
if (this.copyBoard != null) {
|
||||||
@ -95,26 +103,20 @@ export default {
|
|||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapState("treeData", ["totalTreeData", HOME_PIN_BOOKMARK_ID_MAP]),
|
...mapState("treeData", ["totalTreeData", HOME_PIN_BOOKMARK_ID_MAP]),
|
||||||
...mapState("globalConfig", ["userInfo"]),
|
...mapState("globalConfig", ["userInfo"])
|
||||||
searchIcon() {
|
|
||||||
let search = this.userInfo != null ? this.userInfo.defaultSearchEngine : "baidu";
|
|
||||||
return search === "baidu" ? "icon-baidu" : search === "bing" ? "icon-bing" : "icon-google";
|
|
||||||
},
|
|
||||||
searchUrl() {
|
|
||||||
let search = this.userInfo && this.userInfo.defaultSearchEngine ? this.userInfo.defaultSearchEngine : "baidu";
|
|
||||||
return search === "baidu"
|
|
||||||
? "https://www.baidu.com/s?ie=UTF-8&wd="
|
|
||||||
: search === "bing"
|
|
||||||
? "https://www.bing.com/search?q="
|
|
||||||
: "https://www.google.com/search?q=";
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
value(newVal, oldVal) {
|
value(newVal, oldVal) {
|
||||||
this.search(newVal);
|
this.search(newVal);
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
searchIconClick() {
|
||||||
|
if (this.userInfo == null) {
|
||||||
|
this.searchEngineList = [];
|
||||||
|
this.$message.warning("未登录,请登录后操作");
|
||||||
|
}
|
||||||
|
},
|
||||||
search(content) {
|
search(content) {
|
||||||
console.log(content);
|
console.log(content);
|
||||||
let val = content.toLocaleLowerCase().trim();
|
let val = content.toLocaleLowerCase().trim();
|
||||||
@ -135,7 +137,7 @@ export default {
|
|||||||
let url;
|
let url;
|
||||||
if (forceSearch || this.selectIndex == null) {
|
if (forceSearch || this.selectIndex == null) {
|
||||||
//说明使用网页搜索
|
//说明使用网页搜索
|
||||||
url = this.searchUrl + encodeURIComponent(this.value);
|
url = this.checkedSearchEngine.url.replace("%s", encodeURIComponent(this.value));
|
||||||
} else {
|
} else {
|
||||||
//说明跳转到书签
|
//说明跳转到书签
|
||||||
let bookmark = this.list[this.selectIndex];
|
let bookmark = this.list[this.selectIndex];
|
||||||
@ -176,15 +178,10 @@ export default {
|
|||||||
},
|
},
|
||||||
//修改默认搜索引擎
|
//修改默认搜索引擎
|
||||||
async searchEngineChange(item) {
|
async searchEngineChange(item) {
|
||||||
if (this.userInfo == null) {
|
|
||||||
this.$message.warning("未登录,请登录后操作");
|
let target = this.searchEngineList.find(one => one.id === item.key);
|
||||||
return;
|
await HttpUtil.post("/searchEngine/setChecked", null, { id: item.key });
|
||||||
}
|
this.checkedSearchEngine = target;
|
||||||
if (item.key !== this.userInfo.defaultSearchEngine) {
|
|
||||||
await HttpUtil.post("/baseInfo/updateSearchEngine", null, { defaultSearchEngine: item.key });
|
|
||||||
this.userInfo.defaultSearchEngine = item.key;
|
|
||||||
this.$store.commit(GLOBAL_CONFIG + "/" + USER_INFO, this.userInfo);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
//固定书签到首页
|
//固定书签到首页
|
||||||
async pinBookmark(event, { bookmarkId }) {
|
async pinBookmark(event, { bookmarkId }) {
|
||||||
@ -228,8 +225,8 @@ export default {
|
|||||||
}
|
}
|
||||||
console.log("阻止成功");
|
console.log("阻止成功");
|
||||||
return false;
|
return false;
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@ -240,10 +237,12 @@ export default {
|
|||||||
@listActiveBgColor: #454545;
|
@listActiveBgColor: #454545;
|
||||||
.search {
|
.search {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
.listShow {
|
.listShow {
|
||||||
border-bottom-left-radius: 0 !important;
|
border-bottom-left-radius: 0 !important;
|
||||||
border-bottom-right-radius: 0 !important;
|
border-bottom-right-radius: 0 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.newSearch {
|
.newSearch {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@ -252,6 +251,7 @@ export default {
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
font-size: 1.2em;
|
font-size: 1.2em;
|
||||||
color: @textColor;
|
color: @textColor;
|
||||||
|
|
||||||
.input {
|
.input {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
border: 0;
|
border: 0;
|
||||||
@ -260,11 +260,13 @@ export default {
|
|||||||
padding-left: 0.19rem;
|
padding-left: 0.19rem;
|
||||||
outline: none;
|
outline: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.action {
|
.action {
|
||||||
padding: 0.1rem;
|
padding: 0.1rem;
|
||||||
padding-right: 0.19rem;
|
padding-right: 0.19rem;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
||||||
.icon {
|
.icon {
|
||||||
color: @textColor;
|
color: @textColor;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
@ -282,6 +284,7 @@ export default {
|
|||||||
border-bottom-left-radius: 0.18rem;
|
border-bottom-left-radius: 0.18rem;
|
||||||
border-bottom-right-radius: 0.18rem;
|
border-bottom-right-radius: 0.18rem;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
||||||
.listItem {
|
.listItem {
|
||||||
font-size: 0.16rem;
|
font-size: 0.16rem;
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -292,6 +295,7 @@ export default {
|
|||||||
margin: 0.05rem 0 0.05rem 0;
|
margin: 0.05rem 0 0.05rem 0;
|
||||||
padding: 0 0.19rem 0 0.19rem;
|
padding: 0 0.19rem 0 0.19rem;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
.name {
|
.name {
|
||||||
padding-right: 1em;
|
padding-right: 1em;
|
||||||
max-width: calc(100% - 2em);
|
max-width: calc(100% - 2em);
|
||||||
@ -299,17 +303,21 @@ export default {
|
|||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.icons {
|
.icons {
|
||||||
display: none;
|
display: none;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.listItem:hover {
|
.listItem:hover {
|
||||||
background-color: @listActiveBgColor;
|
background-color: @listActiveBgColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
.itemActive {
|
.itemActive {
|
||||||
background-color: @listActiveBgColor;
|
background-color: @listActiveBgColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
.listItem:hover .icons {
|
.listItem:hover .icons {
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,7 @@ let noLoginFinish = false;
|
|||||||
/**
|
/**
|
||||||
* 执行各模块的登陆后初始化
|
* 执行各模块的登陆后初始化
|
||||||
*/
|
*/
|
||||||
export async function loginInit () {
|
export async function loginInit() {
|
||||||
if (!noLoginFinish) {
|
if (!noLoginFinish) {
|
||||||
await finishNoLogin();
|
await finishNoLogin();
|
||||||
}
|
}
|
||||||
@ -40,12 +40,13 @@ export async function loginInit () {
|
|||||||
store.dispatch(globalConfig.GLOBAL_CONFIG + "/" + globalConfig.loginInit);
|
store.dispatch(globalConfig.GLOBAL_CONFIG + "/" + globalConfig.loginInit);
|
||||||
store.dispatch(treeData.TREE_DATA + "/" + treeData.loginInit);
|
store.dispatch(treeData.TREE_DATA + "/" + treeData.loginInit);
|
||||||
}
|
}
|
||||||
|
console.log("初始化完成");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 推出登陆时需要清理的
|
* 推出登陆时需要清理的
|
||||||
*/
|
*/
|
||||||
export async function logoutClear () {
|
export async function logoutClear() {
|
||||||
await store.dispatch(globalConfig.GLOBAL_CONFIG + "/" + globalConfig.clear);
|
await store.dispatch(globalConfig.GLOBAL_CONFIG + "/" + globalConfig.clear);
|
||||||
await store.dispatch(treeData.TREE_DATA + "/" + treeData.clear);
|
await store.dispatch(treeData.TREE_DATA + "/" + treeData.clear);
|
||||||
}
|
}
|
||||||
@ -53,7 +54,7 @@ export async function logoutClear () {
|
|||||||
/**
|
/**
|
||||||
* 确保未登录前要初始化的初始化完了
|
* 确保未登录前要初始化的初始化完了
|
||||||
*/
|
*/
|
||||||
async function finishNoLogin () {
|
async function finishNoLogin() {
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
let timer = setInterval(() => {
|
let timer = setInterval(() => {
|
||||||
if (noLoginFinish) {
|
if (noLoginFinish) {
|
||||||
@ -61,7 +62,7 @@ async function finishNoLogin () {
|
|||||||
resolve();
|
resolve();
|
||||||
}
|
}
|
||||||
}, 100);
|
}, 100);
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export default store;
|
export default store;
|
||||||
|
@ -69,6 +69,7 @@ const actions = {
|
|||||||
let userInfo = await HttpUtil.get("/user/currentUserInfo");
|
let userInfo = await HttpUtil.get("/user/currentUserInfo");
|
||||||
context.commit(USER_INFO, userInfo);
|
context.commit(USER_INFO, userInfo);
|
||||||
context.commit(IS_INIT, true);
|
context.commit(IS_INIT, true);
|
||||||
|
console.log("用户完了");
|
||||||
},
|
},
|
||||||
async [setToken]({ commit }, token) {
|
async [setToken]({ commit }, token) {
|
||||||
await localforage.setItem(TOKEN, token);
|
await localforage.setItem(TOKEN, token);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user