feat:支持搜索引擎自定义

This commit is contained in:
fleyx 2023-08-13 15:05:40 +08:00
parent 383450ebe4
commit c56ca2809c
16 changed files with 519 additions and 90 deletions

View File

@ -0,0 +1,47 @@
package com.fanxb.bookmark.business.user.controller;
import com.fanxb.bookmark.business.user.dao.SearchEngineDao;
import com.fanxb.bookmark.business.user.entity.SearchEngine;
import com.fanxb.bookmark.business.user.service.SearchEngineService;
import com.fanxb.bookmark.common.entity.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/searchEngine")
public class SearchEngineController {
@Autowired
private SearchEngineService searchEngineService;
/**
* 列表查询
*/
@GetMapping("/list")
public Result list() {
return Result.success(searchEngineService.list());
}
@PostMapping("/insert")
public Result insert(@RequestBody SearchEngine body){
searchEngineService.insertOne(body);
return Result.success();
}
@PostMapping("/edit")
public Result edit(@RequestBody SearchEngine body){
searchEngineService.editOne(body);
return Result.success();
}
@PostMapping("/delete")
public Result delete(@RequestBody SearchEngine body){
searchEngineService.deleteOne(body.getId());
return Result.success();
}
@PostMapping("/setChecked")
public Result setChecked(@RequestBody SearchEngine body){
searchEngineService.setChecked(body.getId());
return Result.success();
}
}

View File

@ -0,0 +1,8 @@
package com.fanxb.bookmark.business.user.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.fanxb.bookmark.business.user.entity.SearchEngine;
public interface SearchEngineDao extends BaseMapper<SearchEngine> {
}

View File

@ -1,5 +1,6 @@
package com.fanxb.bookmark.business.user.dao; package com.fanxb.bookmark.business.user.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.fanxb.bookmark.common.entity.po.User; import com.fanxb.bookmark.common.entity.po.User;
import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select; import org.apache.ibatis.annotations.Select;
@ -16,7 +17,7 @@ import java.util.List;
* @date 2019/7/6 11:36 * @date 2019/7/6 11:36
*/ */
@Component @Component
public interface UserDao { public interface UserDao extends BaseMapper<User> {
/** /**
* Description: 新增一个用户 * Description: 新增一个用户
@ -182,16 +183,6 @@ public interface UserDao {
@Select("select userId from user order by userId limit #{start},#{size}") @Select("select userId from user order by userId limit #{start},#{size}")
List<Integer> selectUserIdPage(@Param("start") int start, @Param("size") int size); List<Integer> selectUserIdPage(@Param("start") int start, @Param("size") int size);
/**
* 更新用户搜索引擎
*
* @param userId userId
* @param engine engine
* @author fanxb
* @date 2021/3/14
**/
@Update("update user set defaultSearchEngine=#{engine} where userId=#{userId}")
void updateSearchEngine(@Param("userId") int userId, @Param("engine") String engine);
/** /**
* 更新一个字段-一个条件 * 更新一个字段-一个条件

View File

@ -0,0 +1,29 @@
package com.fanxb.bookmark.business.user.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.experimental.Accessors;
@Data
@Accessors(chain = true)
@TableName("search_engine")
public class SearchEngine {
@TableId(type = IdType.AUTO)
private Integer id;
private Integer userId;
private Integer checked;
/**
* 名称
*/
private String name;
/**
* url
*/
private String url;
/**
* 图标
*/
private String icon;
}

View File

@ -0,0 +1,49 @@
package com.fanxb.bookmark.business.user.service;
import com.fanxb.bookmark.business.user.entity.SearchEngine;
import java.util.List;
public interface SearchEngineService {
/**
* 列表查询
*/
List<SearchEngine> list();
/**
* delete one by id
*
* @param id id
*/
void deleteOne(int id);
/**
* insert one
*
* @param body body
*/
void insertOne(SearchEngine body);
/**
* edit one
*
* @param body body
*/
void editOne(SearchEngine body);
/**
* 设为默认搜索项
*
* @param id
*/
void setChecked(Integer id);
/**
* 新用户初始化
*
* @param userId userId
*/
void newUserInit(int userId);
}

View File

@ -87,6 +87,6 @@ public class BaseInfoServiceImpl implements BaseInfoService {
@Override @Override
public void changeDefaultSearchEngine(User user) { public void changeDefaultSearchEngine(User user) {
userDao.updateSearchEngine(user.getUserId(), user.getDefaultSearchEngine()); userDao.updateById(user);
} }
} }

View File

@ -4,6 +4,7 @@ import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.fanxb.bookmark.business.user.dao.UserDao; import com.fanxb.bookmark.business.user.dao.UserDao;
import com.fanxb.bookmark.business.user.service.OauthService; import com.fanxb.bookmark.business.user.service.OauthService;
import com.fanxb.bookmark.business.user.service.SearchEngineService;
import com.fanxb.bookmark.business.user.service.UserService; import com.fanxb.bookmark.business.user.service.UserService;
import com.fanxb.bookmark.business.user.vo.OauthBody; import com.fanxb.bookmark.business.user.vo.OauthBody;
import com.fanxb.bookmark.common.constant.CommonConstant; import com.fanxb.bookmark.common.constant.CommonConstant;
@ -38,6 +39,8 @@ public class OauthServiceImpl implements OauthService {
private String githubClientId; private String githubClientId;
@Value("${OAuth.github.secret}") @Value("${OAuth.github.secret}")
private String githubSecret; private String githubSecret;
@Autowired
private SearchEngineService searchEngineService;
private final UserDao userDao; private final UserDao userDao;
private final UserService userService; private final UserService userService;
@ -105,6 +108,7 @@ public class OauthServiceImpl implements OauthService {
other.setLastLoginTime(System.currentTimeMillis()); other.setLastLoginTime(System.currentTimeMillis());
other.setVersion(0); other.setVersion(0);
userDao.addOne(other); userDao.addOne(other);
searchEngineService.newUserInit(other.getUserId());
return other; return other;
} else { } else {
if (!current.getEmail().equals(other.getEmail()) || !current.getGithubId().equals(other.getGithubId())) { if (!current.getEmail().equals(other.getEmail()) || !current.getGithubId().equals(other.getGithubId())) {

View File

@ -0,0 +1,88 @@
package com.fanxb.bookmark.business.user.service.impl;
import cn.hutool.core.util.StrUtil;
import com.alibaba.druid.support.ibatis.SpringIbatisBeanNameAutoProxyCreator;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.fanxb.bookmark.business.user.dao.SearchEngineDao;
import com.fanxb.bookmark.business.user.dao.UserDao;
import com.fanxb.bookmark.business.user.entity.SearchEngine;
import com.fanxb.bookmark.business.user.service.SearchEngineService;
import com.fanxb.bookmark.common.entity.UserContext;
import com.fanxb.bookmark.common.entity.po.User;
import com.fanxb.bookmark.common.exception.CustomException;
import com.fanxb.bookmark.common.util.UserContextHolder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Service
public class SearchEngineServiceImpl implements SearchEngineService {
@Autowired
private SearchEngineDao searchEngineDao;
@Autowired
private UserDao userDao;
@Override
public List<SearchEngine> list() {
return searchEngineDao.selectList(new LambdaQueryWrapper<SearchEngine>().eq(SearchEngine::getUserId, UserContextHolder.get().getUserId()));
}
@Override
public void deleteOne(int id) {
SearchEngine engine = searchEngineDao.selectById(id);
if (engine.getUserId() != UserContextHolder.get().getUserId()) {
throw new CustomException("无法操作其他人数据");
}
if (engine.getChecked() == 1) {
throw new CustomException("默认搜索引擎无法删除");
}
searchEngineDao.deleteById(id);
}
@Override
public void insertOne(SearchEngine body) {
checkOne(body);
body.setId(null).setChecked(0).setUserId(UserContextHolder.get().getUserId());
searchEngineDao.insert(body);
}
private void checkOne(SearchEngine body) {
if (StrUtil.hasBlank(body.getIcon(), body.getUrl(), body.getName())) {
throw new CustomException("请填写完整");
}
if (!body.getUrl().contains("%s")) {
throw new CustomException("路径中必须包含%s");
}
}
@Override
public void editOne(SearchEngine body) {
SearchEngine engine = searchEngineDao.selectById(body.getId());
if (engine.getUserId() != UserContextHolder.get().getUserId()) {
throw new CustomException("无法操作其他人数据");
}
checkOne(body);
searchEngineDao.updateById(body);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void setChecked(Integer id) {
int userId = UserContextHolder.get().getUserId();
LambdaUpdateWrapper<SearchEngine> update = new LambdaUpdateWrapper<SearchEngine>().set(SearchEngine::getChecked, 0).eq(SearchEngine::getUserId, userId).eq(SearchEngine::getChecked, 1);
searchEngineDao.update(null, update);
update = new LambdaUpdateWrapper<SearchEngine>().set(SearchEngine::getChecked, 1).eq(SearchEngine::getId, id).eq(SearchEngine::getUserId, userId);
searchEngineDao.update(null, update);
}
@Override
public void newUserInit(int userId) {
searchEngineDao.insert(new SearchEngine().setUserId(userId).setIcon("icon-baidu").setName("百度").setUrl("https://www.baidu.com/s?ie=UTF-8&wd=%s").setChecked(1));
searchEngineDao.insert(new SearchEngine().setUserId(userId).setIcon("icon-bing").setName("必应").setUrl("https://www.bing.com/search?q=%s").setChecked(0));
searchEngineDao.insert(new SearchEngine().setUserId(userId).setIcon("icon-google").setName("谷歌").setUrl("https://www.google.com/search?q=%s").setChecked(0));
}
}

View File

@ -5,6 +5,7 @@ import cn.hutool.core.util.StrUtil;
import com.fanxb.bookmark.business.api.BookmarkApi; import com.fanxb.bookmark.business.api.BookmarkApi;
import com.fanxb.bookmark.business.user.constant.FileConstant; import com.fanxb.bookmark.business.user.constant.FileConstant;
import com.fanxb.bookmark.business.user.dao.UserDao; import com.fanxb.bookmark.business.user.dao.UserDao;
import com.fanxb.bookmark.business.user.service.SearchEngineService;
import com.fanxb.bookmark.business.user.service.UserService; import com.fanxb.bookmark.business.user.service.UserService;
import com.fanxb.bookmark.business.user.vo.LoginBody; import com.fanxb.bookmark.business.user.vo.LoginBody;
import com.fanxb.bookmark.business.user.vo.RegisterBody; import com.fanxb.bookmark.business.user.vo.RegisterBody;
@ -20,6 +21,7 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import java.io.File; import java.io.File;
@ -42,6 +44,8 @@ public class UserServiceImpl implements UserService {
* 登陆最大重试次数 * 登陆最大重试次数
*/ */
private static final int LOGIN_COUNT = 5; private static final int LOGIN_COUNT = 5;
@Autowired
private SearchEngineService searchEngineService;
private final UserDao userDao; private final UserDao userDao;
private final StringRedisTemplate redisTemplate; private final StringRedisTemplate redisTemplate;
@ -83,6 +87,7 @@ public class UserServiceImpl implements UserService {
* @author fanxb * @author fanxb
* @date 2019/7/6 11:30 * @date 2019/7/6 11:30
*/ */
@Transactional(rollbackFor = Exception.class)
public String register(RegisterBody body) { public String register(RegisterBody body) {
User user = userDao.selectByUsernameOrEmail(body.getUsername(), body.getEmail()); User user = userDao.selectByUsernameOrEmail(body.getUsername(), body.getEmail());
if (user != null) { if (user != null) {
@ -102,6 +107,7 @@ public class UserServiceImpl implements UserService {
user.setLastLoginTime(System.currentTimeMillis()); user.setLastLoginTime(System.currentTimeMillis());
user.setVersion(0); user.setVersion(0);
userDao.addOne(user); userDao.addOne(user);
searchEngineService.newUserInit(user.getUserId());
Map<String, String> data = new HashMap<>(1); Map<String, String> data = new HashMap<>(1);
data.put("userId", String.valueOf(user.getUserId())); data.put("userId", String.valueOf(user.getUserId()));
return JwtUtil.encode(data, CommonConstant.jwtSecret, LONG_EXPIRE_TIME); return JwtUtil.encode(data, CommonConstant.jwtSecret, LONG_EXPIRE_TIME);

View File

@ -37,16 +37,10 @@
<artifactId>commons-pool2</artifactId> <artifactId>commons-pool2</artifactId>
</dependency> </dependency>
<!--mybatis依赖-->
<!-- <dependency>-->
<!-- <groupId>org.mybatis.spring.boot</groupId>-->
<!-- <artifactId>mybatis-spring-boot-starter</artifactId>-->
<!-- <version>2.0.1</version>-->
<!-- </dependency>-->
<dependency> <dependency>
<groupId>com.baomidou</groupId> <groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId> <artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.1</version> <version>3.5.3.2</version>
</dependency> </dependency>
<dependency> <dependency>
@ -59,19 +53,25 @@
<dependency> <dependency>
<groupId>com.alibaba</groupId> <groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId> <artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.18</version> <version>1.2.18</version>
</dependency> </dependency>
<!--数据库版本管理--> <!--数据库版本管理-->
<dependency> <dependency>
<groupId>org.flywaydb</groupId> <groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId> <artifactId>flyway-core</artifactId>
<version>5.2.4</version> <version>9.21.1</version>
</dependency>
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-mysql</artifactId>
<version>9.21.1</version>
</dependency> </dependency>
<!--mysql jdbc依赖--> <!--mysql jdbc依赖-->
<dependency> <dependency>
<groupId>mysql</groupId> <groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId> <artifactId>mysql-connector-java</artifactId>
<version>8.0.33</version>
</dependency> </dependency>
<!--邮件依赖--> <!--邮件依赖-->
@ -101,7 +101,46 @@
<dependency> <dependency>
<groupId>cn.hutool</groupId> <groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId> <artifactId>hutool-all</artifactId>
<version>5.8.12</version> <version>5.8.21</version>
</dependency>
<!--单元测试-->
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-test -->
<!--mysql jdbc依赖-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.33</version>
</dependency>
<!--邮件依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<!--减负依赖-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!--json工具依赖-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.83</version>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.21</version>
</dependency> </dependency>
<!--单元测试--> <!--单元测试-->

View File

@ -2,6 +2,10 @@ package com.fanxb.bookmark.common.entity.po;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.annotation.JSONField; import com.alibaba.fastjson.annotation.JSONField;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data; import lombok.Data;
@ -16,9 +20,11 @@ import java.util.Map;
* @date 2019/7/4 20:14 * @date 2019/7/4 20:14
*/ */
@Data @Data
@TableName("user")
public class User { public class User {
private int userId; @TableId(type = IdType.AUTO)
private Integer userId;
/** /**
* 第三方github登陆id,-1说明非github登陆 * 第三方github登陆id,-1说明非github登陆
*/ */
@ -30,6 +36,7 @@ public class User {
/** /**
* 是否未设置密码 * 是否未设置密码
*/ */
@TableField(exist = false)
private Boolean noPassword; private Boolean noPassword;
@JSONField(serialize = false) @JSONField(serialize = false)
private String password; private String password;
@ -42,9 +49,10 @@ public class User {
* 书签同步版本 * 书签同步版本
*/ */
private int version; private int version;
/** /**
* 默认搜索引擎 * 默认搜索引擎
*/ */
private String defaultSearchEngine; private Integer searchEngineId;
} }

View File

@ -22,7 +22,7 @@
<parent> <parent>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId> <artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.12.RELEASE</version> <version>2.7.14</version>
<relativePath/> <relativePath/>
</parent> </parent>

View File

@ -2,15 +2,21 @@ create table search_engine
( (
id int auto_increment id int auto_increment
primary key, primary key,
userId int not null,
checked tinyint not null default 0,
name varchar(20) null, name varchar(20) null,
url varchar(500) null, url varchar(500) null,
icon varchar(20) null icon varchar(20) null
); ) auto_increment=1001;
INSERT INTO bookmark.search_engine (name, url, icon) create index search_engine_userId_index
VALUES ('谷歌', 'https://www.google.com/search?q=%s', 'icon-google'); on search_engine (userId);
INSERT INTO bookmark.search_engine (name, url, icon) insert into search_engine(userId, checked, name, url, icon)
VALUES ('必应', 'https://www.bing.com/search?q=%s', 'icon-bing'); select userId, if(defaultSearchEngine = 'baidu', 1, 0), '百度', 'https://www.baidu.com/s?ie=UTF-8&wd=%s', 'icon-baidu'
from user;
INSERT INTO bookmark.search_engine (name, url, icon) insert into search_engine(userId, checked, name, url, icon)
VALUES ('百度', 'https://www.bing.com/search?q=%s', 'icon-baidu'); select userId, if(defaultSearchEngine = 'bing', 1, 0), '必应', 'https://www.bing.com/search?q=%s', 'icon-bing'
from user;
insert into search_engine(userId, checked, name, url, icon)
select userId, if(defaultSearchEngine = 'google', 1, 0), '谷歌', 'https://www.google.com/search?q=%s', 'icon-google'
from user;

View File

@ -20,14 +20,15 @@ import {
AutoComplete, AutoComplete,
Select, Select,
Popover, Popover,
Breadcrumb Breadcrumb,
Table
} from "ant-design-vue"; } from "ant-design-vue";
import App from "./App.vue"; import App from "./App.vue";
import router from "./router"; import router from "./router";
import store from "./store"; import store from "./store";
const IconFont = Icon.createFromIconfontCN({ const IconFont = Icon.createFromIconfontCN({
scriptUrl: "//at.alicdn.com/t/font_1261825_1cgngjf5r4f.js" scriptUrl: "//at.alicdn.com/t/c/font_1261825_v7m0rilm4hm.js"
}); });
Vue.use(Button); Vue.use(Button);
Vue.use(FormModel); Vue.use(FormModel);
@ -48,6 +49,7 @@ Vue.use(AutoComplete);
Vue.use(Select); Vue.use(Select);
Vue.use(Popover); Vue.use(Popover);
Vue.use(Breadcrumb); Vue.use(Breadcrumb);
Vue.use(Table);
Vue.component("my-icon", IconFont); Vue.component("my-icon", IconFont);
Vue.prototype.$message = message; Vue.prototype.$message = message;

View File

@ -0,0 +1,164 @@
<template>
<div>
<a-button type="primary" @click="addOne">新增</a-button>
<a-table :columns="columns" :data-source="list" :pagination="false">
<template v-for="col in ['name', 'url']" :slot="col" slot-scope="text, record, index">
<div :key="col">
<a-input v-if="record.isEdit" style="margin: -5px 0" :value="text"
@change="e => handleChange(e.target.value, record.id, col)" />
<template v-else>{{ text }}</template>
</div>
</template>
<template slot="icon" slot-scope="text, record, index">
<div key="icon">
<a-select v-if="record.isEdit" :default-value="text" style="width: 120px"
@change="e => handleChange(e, record.id, 'icon')">
<a-select-option v-for="item in iconList" :key="item.icon" :value="item.icon">
<my-icon :type="item.icon" />
{{ item.label }}
</a-select-option>
</a-select>
<template v-else>
<my-icon style="font-size: 1.2em" :type="text" />
</template>
</div>
</template>
<template slot="checked" slot-scope="text">
<span>{{ text === 1 ? "是" : "否" }}</span>
</template>
<template slot="operation" slot-scope="text, record, index">
<div class="editable-row-operations">
<span v-if="record.isEdit">
<a @click="() => save(record.id)">保存</a>
&nbsp;<a @click="() => cancel(record.id)">取消</a>
</span>
<div v-else>
<a :disabled="currentEditCache" @click="() => edit(record.id)">编辑</a>&nbsp;
<a-popconfirm title="确认删除吗?" ok-text="" cancel-text="" @confirm="() => deleteOne(record.id)">
<a :disabled="currentEditCache">删除</a>
</a-popconfirm>&nbsp;
<a :disabled="currentEditCache || record.checked===1" @click="() => setDefault(record.id)">设为默认</a>
</div>
</div>
</template>
</a-table>
</div>
</template>
<script>
import HttpUtil from "@/util/HttpUtil";
export default {
name: "manageSearchEngine",
data() {
return {
list: [],
currentEditCache: null,
iconList: [
{ icon: "icon-baidu", label: "百度" },
{ icon: "icon-bing", label: "必应" },
{ icon: "icon-google", label: "谷歌" },
{ icon: "icon-yandex", label: "yandex" },
{ icon: "icon-sogou", label: "搜狗" },
{ icon: "icon-yahoo", label: "雅虎" },
{ icon: "icon-qita", label: "其他" }
],
columns: [
{
title: "名称",
dataIndex: "name",
width: "10em",
scopedSlots: { customRender: "name" }
}, {
title: "图标",
dataIndex: "icon",
width: "8em",
scopedSlots: { customRender: "icon" }
}, {
title: "路径(%s 会被替换为搜索内容)",
dataIndex: "url",
scopedSlots: { customRender: "url" }
}, {
title: "默认",
dataIndex: "checked",
width: "10em",
scopedSlots: { customRender: "checked" }
}, {
title: "操作",
width: "15em",
dataIndex: "operation",
scopedSlots: { customRender: "operation" }
}]
};
},
async created() {
await this.getData();
},
computed: {
//
deleteOk() {
return this.list.filter(item => item.isEdit).length === 0;
}
},
methods: {
addOne() {
let body = { id: -1, icon: "", name: "", url: "", checked: 0, isEdit: true };
this.list = [body, ...this.list];
this.currentEditCache = body;
},
handleChange(value, id, column) {
console.log(value, id, column);
const target = this.list.find(item => item.id === id);
target[column] = value;
this.list = [...this.list];
},
async edit(id) {
let target = this.list.find(item => item.id === id);
this.currentEditCache = { ...target };
target.isEdit = true;
this.list = [...this.list];
},
async save(id) {
let target = this.list.find(item => item.id === id);
if (target.id > 0) {
await HttpUtil.post("/searchEngine/edit", null, target);
} else {
await HttpUtil.post("/searchEngine/insert", null, target);
}
target.isEdit = false;
this.currentEditCache = null;
await this.getData();
},
cancel(id) {
let target = this.list.find(item => item.id === id);
Object.assign(target, this.currentEditCache);
target.isEdit = false;
this.list = [...this.list];
this.currentEditCache = null;
},
async deleteOne(id) {
await HttpUtil.post("/searchEngine/delete", null, { id });
this.list = await HttpUtil.get("/searchEngine/list");
},
async setDefault(id) {
await HttpUtil.post("/searchEngine/setChecked", null, { id });
this.list = await HttpUtil.get("/searchEngine/list");
},
async getData() {
this.list = await HttpUtil.get("/searchEngine/list");
}
}
};
</script>
<style lang="less" scoped>
.icon {
color: black;
cursor: pointer;
font-size: 1.3em;
}
</style>

View File

@ -1,5 +1,5 @@
<template> <template>
<div class="userInfo"> <div v-if="userInfo" class="userInfo">
<div class="icon"> <div class="icon">
<img :src="userInfo.icon" class="full" /> <img :src="userInfo.icon" class="full" />
<label class="full"> <label class="full">
@ -12,7 +12,8 @@
<div class="baseInfo"> <div class="baseInfo">
<div class="item"> <div class="item">
<a-tooltip title="点击修改" v-if="currentAction != 'name'"> <a-tooltip title="点击修改" v-if="currentAction != 'name'">
<span style="font-size: 2em; cursor: pointer" @click="() => (this.currentAction = 'name')">{{ userInfo.username }}</span> <span style="font-size: 2em; cursor: pointer"
@click="() => (this.currentAction = 'name')">{{ userInfo.username }}</span>
</a-tooltip> </a-tooltip>
<div class="inputGroup" v-else-if="currentAction === 'name'"> <div class="inputGroup" v-else-if="currentAction === 'name'">
<a-input type="text" v-model="name" placeholder="修改昵称" /> <a-input type="text" v-model="name" placeholder="修改昵称" />
@ -26,7 +27,9 @@
<div class="item"> <div class="item">
<span style="width: 5em">密码</span> <span style="width: 5em">密码</span>
<a-tooltip title="点击修改" v-if="currentAction != 'password'"> <a-tooltip title="点击修改" v-if="currentAction != 'password'">
<span style="cursor: pointer" @click="() => (this.currentAction = 'password')">{{ userInfo.noPassword ? "设置密码" : "**********" }}</span> <span style="cursor: pointer"
@click="() => (this.currentAction = 'password')">{{ userInfo.noPassword ? "设置密码" : "**********"
}}</span>
</a-tooltip> </a-tooltip>
<div class="inputGroup" v-else-if="currentAction === 'password'"> <div class="inputGroup" v-else-if="currentAction === 'password'">
<a-input type="password" v-model="oldPassword" placeholder="旧密码(如无置空)" /> <a-input type="password" v-model="oldPassword" placeholder="旧密码(如无置空)" />
@ -58,27 +61,24 @@
<a-tooltip title="搜索框默认搜索引擎"> <a-tooltip title="搜索框默认搜索引擎">
<span style="width: 5em">搜索</span> <span style="width: 5em">搜索</span>
</a-tooltip> </a-tooltip>
<a-tooltip title="点击修改" v-if="currentAction != 'defaultSearchEngine'"> <div @click="showSearchEngineManage=true" style=" cursor: pointer;color:blue">管理搜索引擎</div>
<span style="cursor: pointer" @click="() => (this.currentAction = 'defaultSearchEngine')">{{ defaultSearchEngine }}</span>
<span>管理搜索引擎</span>
</a-tooltip>
<div class="inputGroup" v-else-if="currentAction === 'defaultSearchEngine'">
<a-select :default-value="userInfo.defaultSearchEngine" style="width: 100%" @change="submit">
<a-select-option value="baidu">百度</a-select-option>
<a-select-option value="google">谷歌</a-select-option>
<a-select-option value="bing">Bing</a-select-option>
</a-select>
</div>
</div> </div>
</div> </div>
<a-modal v-model="showSearchEngineManage" title="管理搜索引擎" :footer="null" width="70%">
<manage-search-engine />
</a-modal>
</div> </div>
</template> </template>
<script> <script>
import manageSearchEngine from "./components/manageSearchEngine.vue";
import { mapState } from "vuex"; import { mapState } from "vuex";
import HttpUtil from "@/util/HttpUtil"; import HttpUtil from "@/util/HttpUtil";
export default { export default {
name: "UserInfo", name: "UserInfo",
components: { manageSearchEngine },
data() { data() {
return { return {
currentAction: null, //,name,password,email currentAction: null, //,name,password,email
@ -87,21 +87,11 @@ export default {
password: "", password: "",
rePassword: "", rePassword: "",
email: "", email: "",
showSearchEngineManage: false
}; };
}, },
computed: { computed: {
...mapState("globalConfig", ["userInfo"]), ...mapState("globalConfig", ["userInfo"])
defaultSearchEngine() {
switch (this.userInfo.defaultSearchEngine) {
case "baidu":
return "百度";
case "google":
return "谷歌";
case "bing":
return "Bing";
}
return "";
},
}, },
methods: { methods: {
async changeIcon(e) { async changeIcon(e) {
@ -128,21 +118,18 @@ export default {
url = "/baseInfo/password"; url = "/baseInfo/password";
body = { body = {
oldPassword: this.oldPassword, oldPassword: this.oldPassword,
password: this.password, password: this.password
}; };
} else if (this.currentAction === "email") { } else if (this.currentAction === "email") {
url = "/baseInfo/email"; url = "/baseInfo/email";
body = { oldPassword: this.oldPassword, email: this.email }; body = { oldPassword: this.oldPassword, email: this.email };
} else if (this.currentAction === "defaultSearchEngine") {
url = "/baseInfo/updateSearchEngine";
body = { defaultSearchEngine: e };
} }
await HttpUtil.post(url, null, body); await HttpUtil.post(url, null, body);
await this.$store.dispatch("globalConfig/refreshUserInfo"); await this.$store.dispatch("globalConfig/refreshUserInfo");
this.$message.success("操作成功"); this.$message.success("操作成功");
this.currentAction = null; this.currentAction = null;
}, }
}, }
}; };
</script> </script>
@ -196,6 +183,7 @@ export default {
border-bottom: 1px solid #ebebeb; border-bottom: 1px solid #ebebeb;
display: flex; display: flex;
.inputGroup { .inputGroup {
flex: 1; flex: 1;
} }