From 7e491ab10ec28a7e79db8a6dce0c839f6ea90432 Mon Sep 17 00:00:00 2001 From: fanxb Date: Wed, 17 Jul 2019 17:33:00 +0800 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20Feat:=20[=E5=89=8D=E5=8F=B0]:?= =?UTF-8?q?=E5=AE=8C=E6=88=90=E7=BC=96=E8=BE=91=E5=8A=9F=E8=83=BD=E3=80=82?= =?UTF-8?q?=E6=8B=96=E6=8B=BD=E5=8A=9F=E8=83=BD=E9=83=A8=E5=88=86=E5=AE=8C?= =?UTF-8?q?=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- front/src/pages/manage/OverView/AddModal.jsx | 61 +++- front/src/pages/manage/OverView/function.js | 87 ++++- front/src/pages/manage/OverView/index.jsx | 311 +++++++++--------- .../pages/public/RegisterOrReset/index.jsx | 306 ++++++++--------- front/src/util/httpUtil.js | 120 +++---- 5 files changed, 506 insertions(+), 379 deletions(-) diff --git a/front/src/pages/manage/OverView/AddModal.jsx b/front/src/pages/manage/OverView/AddModal.jsx index ccfa831..e98b061 100644 --- a/front/src/pages/manage/OverView/AddModal.jsx +++ b/front/src/pages/manage/OverView/AddModal.jsx @@ -13,7 +13,37 @@ export default class AddModal extends React.Component { }; } - addOne = () => { + submit = () => { + const { currentEditNode } = this.props; + if (currentEditNode == null) { + this.addOne(); + } else { + this.editOne(currentEditNode); + } + }; + + /** + * 编辑一个节点 + * @param {*} node + */ + editOne(node) { + const { addName, addValue } = this.state; + const body = { + name: addName, + url: addValue + }; + httpUtil.post("/bookmark/updateOne", body).then(() => { + message.success("编辑成功"); + node.name = addName; + node.url = addValue; + this.close(); + }); + } + + /** + * 新增一个节点 + */ + addOne() { const { currentAddFolder, addToTree, closeModal } = this.props; const path = currentAddFolder == null ? "" : currentAddFolder.path + "." + currentAddFolder.bookmarkId; if (this.state.addType === 2) { @@ -40,7 +70,7 @@ export default class AddModal extends React.Component { closeModal(); }); } - }; + } close = () => { const { closeModal } = this.props; @@ -49,8 +79,9 @@ export default class AddModal extends React.Component { }; render() { - const { isShowModal } = this.props; + const { isShowModal, currentEditNode } = this.props; const { addType, addName, addValue } = this.state; + const type = currentEditNode == null ? "add" : "edit"; const formItemLayout = { labelCol: { xs: { span: 4 }, @@ -72,21 +103,23 @@ export default class AddModal extends React.Component { fileList: [] }; return ( - +
- - this.setState({ addType: e.target.value })}> - 书签 - 文件夹 - 上传书签html - - - {addType < 2 ? ( + {type === "add" ? ( + + this.setState({ addType: e.target.value })}> + 书签 + 文件夹 + 上传书签html + + + ) : null} + {addType < 2 || type === "edit" ? ( this.setState({ addName: e.target.value })} value={addName} /> ) : null} - {addType === 0 ? ( + {(addType === 0 && type === "add") || (type === "edit" && currentEditNode.type === 0) ? ( this.setState({ addValue: e.target.value })} /> @@ -100,7 +133,7 @@ export default class AddModal extends React.Component { ) : null}
-
diff --git a/front/src/pages/manage/OverView/function.js b/front/src/pages/manage/OverView/function.js index 6f1b8bc..b3a1b15 100644 --- a/front/src/pages/manage/OverView/function.js +++ b/front/src/pages/manage/OverView/function.js @@ -1,6 +1,6 @@ import httpUtil from "../../../util/httpUtil"; import React from "react"; -import { Modal, Button, Tooltip, Tree } from "antd"; +import { Modal, Button, Tooltip, Tree, message } from "antd"; import styles from "./index.module.less"; import IconFont from "../../../components/IconFont"; const { TreeNode } = Tree; @@ -44,6 +44,16 @@ export function onCheck(keys, data) { }); } +/** + * 编辑一个节点 + * @param {*} node 节点对象 + * @param {*} e + */ +function editNode(node, e) { + e.stopPropagation(); + this.setState({ isShowModal: true, currentEditNode: node }); +} + /** * 渲染树节点中节点内容 * @param {*} item @@ -66,6 +76,7 @@ export function renderNodeContent(item) { /> ) : null} {item.type === 1 ? - ) : null} - -
- {isEdit ? ( - - - - ) : null} - -
- - - {renderTreeNodes.call(this, treeData)} - - {isLoading === false && treeData.length === 0 ? : null} - - - - ); - } -} +import React from "react"; +import { Tree, Empty, Button } from "antd"; +import MainLayout from "../../../layout/MainLayout"; +import httpUtil from "../../../util/httpUtil"; +import styles from "./index.module.less"; +import { batchDelete, renderTreeNodes, onExpand, closeAll, onCheck, onDragEnter, onDrop } from "./function.js"; +import AddModal from "./AddModal"; + +export default class OverView extends React.Component { + constructor(props) { + super(props); + this.state = { + treeData: [], + isEdit: false, + isLoading: true, + checkedKeys: [], + expandKeys: [], + //是否显示新增/编辑书签弹窗 + isShowModal: false, + currentAddFolder: null, + currentEditNode: null + }; + } + + /** + * 初始化第一级书签 + */ + componentDidMount() { + httpUtil + .get("/bookmark/currentUser/path?path=") + .then(res => { + this.setState({ treeData: res, isLoading: false }); + }) + .catch(() => this.setState({ isLoading: false })); + } + + /** + * 异步加载 + */ + loadData = e => + new Promise(resolve => { + const item = e.props.dataRef; + const newPath = item.path + "." + item.bookmarkId; + httpUtil.get("/bookmark/currentUser/path?path=" + newPath).then(res => { + item.children = res; + this.setState({ treeData: [...this.state.treeData] }); + resolve(); + }); + }); + + /** + * 节点选择 + * @param {*} key + * @param {*} e + */ + treeNodeSelect(key, e) { + if (e.nativeEvent.delegateTarget && e.nativeEvent.delegateTarget.name === "copy") { + return; + } + const { expandKeys } = this.state; + const item = e.node.props.dataRef; + if (item.type === 0) { + window.open(item.url); + } else { + const id = item.bookmarkId.toString(); + const index = expandKeys.indexOf(id); + index === -1 ? expandKeys.push(id) : expandKeys.splice(index, 1); + this.setState({ expandKeys: [...expandKeys] }); + } + } + + /** + * 将新增的数据加入到state中 + */ + addToTree = node => { + const { currentAddFolder, treeData } = this.state; + if (currentAddFolder === null) { + treeData.push(node); + } else { + //存在children说明该子节点的孩子数据已经加载,需要重新将新的子书签加入进去 + if (currentAddFolder.children) { + currentAddFolder.children.push(node); + this.setState({ treeData: [...treeData] }); + } + this.setState({ currentAddFolder: null }); + } + }; + + /** + * 关闭新增书签弹窗 + */ + closeAddModal = () => { + this.setState({ isShowModal: false, currentAddFolder: null, currentEditNode: null }); + }; + + /** + * 新增书签 + */ + addOne = (item, e) => { + e.stopPropagation(); + this.setState({ currentAddFolder: item, isShowModal: true }); + }; + + render() { + const { isLoading, isEdit, treeData, expandKeys, checkedKeys, isShowModal, currentAddFolder, currentEditNode } = this.state; + return ( + +
+
+
+ 我的书签树 + {isEdit ? + ) : null} +
+
+ {isEdit ? ( + + + + ) : null} + +
+
+ + {renderTreeNodes.call(this, treeData)} + + {isLoading === false && treeData.length === 0 ? : null} + +
+
+ ); + } +} diff --git a/front/src/pages/public/RegisterOrReset/index.jsx b/front/src/pages/public/RegisterOrReset/index.jsx index f7cdc4b..d51ebca 100644 --- a/front/src/pages/public/RegisterOrReset/index.jsx +++ b/front/src/pages/public/RegisterOrReset/index.jsx @@ -1,153 +1,153 @@ -import React from "react"; -import IconFont from "../../../components/IconFont"; -import { Button, Input, message } from "antd"; -import { LoginLayout, REGISTER_TYPE, RESET_PASSWORD_TYPE } from "../../../layout/LoginLayout"; -import styles from "./index.module.less"; -import axios from "../../../util/httpUtil"; - -export default class Register extends React.Component { - constructor(props) { - super(props); - console.log(props); - let type = props.location.pathname.split("/").reverse()[0]; - this.state = { - current: type === "register" ? REGISTER_TYPE : RESET_PASSWORD_TYPE, - username: "", - email: "", - password: "", - repassword: "", - authCode: "", - authCodeText: "获取验证码", - isCountDown: false - }; - } - - componentWillUnmount() { - if (this.timer != null) { - clearInterval(this.timer); - } - } - - /** - * 获取验证码 - */ - getCode = () => { - if (this.state.isCountDown) { - return; - } - axios.get("/user/authCode?email=" + this.state.email).then(() => { - message.success("发送成功,请注意查收(检查垃圾箱)"); - let count = 60; - this.setState({ authCodeText: `${count}s后重试`, isCountDown: true }); - this.timer = setInterval(() => { - count--; - if (count === 0) { - this.setState({ isCountDown: false, authCodeText: "获取验证码" }); - clearInterval(this.timer); - return; - } - this.setState({ authCodeText: `${count}s后重试` }); - }, 1000); - }); - }; - - changeData = e => { - this.setState({ [e.target.name]: e.target.value }); - }; - - /** - * 提交表单 - */ - submit = () => { - const { current, username, email, password, repassword, authCode } = this.state; - if (password !== repassword) { - message.error("两次密码不一致"); - return; - } - let form = { username, email, password, authCode }; - if (current === REGISTER_TYPE) { - axios - .put("/user", form) - .then(() => { - message.success("注册成功"); - setTimeout(() => this.props.history.replace("/public/login"), 500); - }) - .catch(error => message.error(error)); - } else { - delete form.username; - axios - .post("/user/resetPassword", form) - .then(() => { - message.success("操作成功"); - console.log(this.location); - setTimeout(() => this.props.history.replace("/public/login"), 500); - }) - .catch(error => message.error(error)); - } - }; - - render() { - const { current, username, email, password, repassword, authCode, authCodeText, isCountDown } = this.state; - return ( - -
- {current === REGISTER_TYPE ? ( - } - placeholder="用户名" - /> - ) : null} - } - placeholder="邮箱" - /> - } - placeholder="密码" - /> - } - placeholder="重复密码" - /> - } - addonAfter={ - - {authCodeText} - - } - placeholder="验证码" - /> - -
-
- ); - } -} +import React from "react"; +import IconFont from "../../../components/IconFont"; +import { Button, Input, message } from "antd"; +import { LoginLayout, REGISTER_TYPE, RESET_PASSWORD_TYPE } from "../../../layout/LoginLayout"; +import styles from "./index.module.less"; +import axios from "../../../util/httpUtil"; + +export default class Register extends React.Component { + constructor(props) { + super(props); + console.log(props); + let type = props.location.pathname.split("/").reverse()[0]; + this.state = { + current: type === "register" ? REGISTER_TYPE : RESET_PASSWORD_TYPE, + username: "", + email: "", + password: "", + repassword: "", + authCode: "", + authCodeText: "获取验证码", + isCountDown: false + }; + } + + componentWillUnmount() { + if (this.timer != null) { + clearInterval(this.timer); + } + } + + /** + * 获取验证码 + */ + getCode = () => { + if (this.state.isCountDown) { + return; + } + let count = 60; + this.setState({ authCodeText: `${count}s后重试`, isCountDown: true }); + axios.get("/user/authCode?email=" + this.state.email).then(() => { + message.success("发送成功,请注意查收(检查垃圾箱)"); + this.timer = setInterval(() => { + count--; + if (count === 0) { + this.setState({ isCountDown: false, authCodeText: "获取验证码" }); + clearInterval(this.timer); + return; + } + this.setState({ authCodeText: `${count}s后重试` }); + }, 1000); + }); + }; + + changeData = e => { + this.setState({ [e.target.name]: e.target.value }); + }; + + /** + * 提交表单 + */ + submit = () => { + const { current, username, email, password, repassword, authCode } = this.state; + if (password !== repassword) { + message.error("两次密码不一致"); + return; + } + let form = { username, email, password, authCode }; + if (current === REGISTER_TYPE) { + axios + .put("/user", form) + .then(() => { + message.success("注册成功"); + setTimeout(() => this.props.history.replace("/public/login"), 500); + }) + .catch(error => message.error(error)); + } else { + delete form.username; + axios + .post("/user/resetPassword", form) + .then(() => { + message.success("操作成功"); + console.log(this.location); + setTimeout(() => this.props.history.replace("/public/login"), 500); + }) + .catch(error => message.error(error)); + } + }; + + render() { + const { current, username, email, password, repassword, authCode, authCodeText, isCountDown } = this.state; + return ( + +
+ {current === REGISTER_TYPE ? ( + } + placeholder="用户名" + /> + ) : null} + } + placeholder="邮箱" + /> + } + placeholder="密码" + /> + } + placeholder="重复密码" + /> + } + addonAfter={ + + {authCodeText} + + } + placeholder="验证码" + /> + +
+
+ ); + } +} diff --git a/front/src/util/httpUtil.js b/front/src/util/httpUtil.js index b903fe8..7532c9c 100644 --- a/front/src/util/httpUtil.js +++ b/front/src/util/httpUtil.js @@ -1,60 +1,60 @@ -import { notification } from "antd"; -import axios from "axios"; - -//定义http实例 -const instance = axios.create({ - baseURL: "/bookmark/api", - timeout: 15000 -}); - -//实例添加请求拦截器 -instance.interceptors.request.use( - req => { - req.headers["jwt-token"] = window.token; - return req; - }, - error => { - console.log(error); - } -); - -//实例添加响应拦截器 -instance.interceptors.response.use( - function(res) { - const data = res.data; - if (data.code === 1) { - return data.data; - } else if (data.code === -2) { - return Promise.reject(data.message); - } else { - showError(data); - return Promise.reject(data.message); - } - }, - function(error) { - console.log(error); - showError(error.response); - return Promise.reject(JSON.stringify(error)); - } -); - -function showError(response) { - let description, - message = "出问题啦"; - if (response) { - description = response.message; - if (response.code === -1) { - let redirect = encodeURIComponent(window.location.pathname + window.location.search); - window.reactHistory.replace("/public/login?redirect=" + redirect); - } - } else { - description = "无网络连接"; - } - notification.open({ - message, - description, - duration: 2 - }); -} - -export default instance; +import { notification } from "antd"; +import axios from "axios"; + +//定义http实例 +const instance = axios.create({ + baseURL: "/bookmark/api", + timeout: 15000 +}); + +//实例添加请求拦截器 +instance.interceptors.request.use( + req => { + req.headers["jwt-token"] = window.token; + return req; + }, + error => { + console.log(error); + } +); + +//实例添加响应拦截器 +instance.interceptors.response.use( + function(res) { + const data = res.data; + if (data.code === 1) { + return data.data; + } else if (data.code === -2) { + return Promise.reject(data.message); + } else { + showError(data); + return Promise.reject(data.message); + } + }, + function(error) { + console.log(error); + showError(error.response); + return Promise.reject(JSON.stringify(error)); + } +); + +function showError(response) { + let description, + message = "出问题啦"; + if (response) { + description = response.message; + if (response.code === -1) { + let redirect = encodeURIComponent(window.location.pathname + window.location.search); + window.reactHistory.replace("/public/login?redirect=" + redirect); + } + } else { + description = "无网络连接"; + } + notification.open({ + message, + description, + duration: 2 + }); +} + +export default instance;