import React, { Component } from 'react'; import { message } from 'antd'; import { connect } from 'react-redux'; import axios from 'axios'; import PropTypes from 'prop-types'; import './index.scss'; import { timeago } from '../../../common/utils'; import { Link } from 'react-router-dom'; import WikiView from './View.js'; import WikiEditor from './Editor.js'; @connect( state => { return { projectMsg: state.project.currProject }; }, {} ) class WikiPage extends Component { constructor(props) { super(props); this.state = { isEditor: false, isUpload: true, desc: '', markdown: '', notice: props.projectMsg.switch_notice, status: 'INIT', editUid: '', editName: '', curdata: null }; } static propTypes = { match: PropTypes.object, projectMsg: PropTypes.object }; async componentDidMount() { const currProjectId = this.props.match.params.id; await this.handleData({ project_id: currProjectId }); this.handleConflict(); } componentWillUnmount() { // willUnmount try { if (this.state.status === 'CLOSE') { this.WebSocket.send('end'); this.WebSocket.close(); } } catch (e) { return null; } } // 结束编辑websocket endWebSocket = () => { try { if (this.state.status === 'CLOSE') { const sendEnd = () => { this.WebSocket.send('end'); }; this.handleWebsocketAccidentClose(sendEnd); } } catch (e) { return null; } }; // 处理多人编辑冲突问题 handleConflict = () => { // console.log(location) let domain = location.hostname + (location.port !== '' ? ':' + location.port : ''); let s; //因后端 node 仅支持 ws, 暂不支持 wss let wsProtocol = location.protocol === 'https:' ? 'wss' : 'ws'; s = new WebSocket( wsProtocol + '://' + domain + '/api/ws_plugin/wiki_desc/solve_conflict?id=' + this.props.match.params.id ); s.onopen = () => { this.WebSocket = s; s.send('start'); }; s.onmessage = e => { let result = JSON.parse(e.data); if (result.errno === 0) { // 更新 if (result.data) { this.setState({ // curdata: result.data, desc: result.data.desc, username: result.data.username, uid: result.data.uid, editorTime: timeago(result.data.up_time) }); } // 新建 this.setState({ isEditor: !this.state.isEditor, status: 'CLOSE' }); } else { this.setState({ editUid: result.data.uid, editName: result.data.username, status: 'EDITOR' }); } }; s.onerror = () => { this.setState({ status: 'CLOSE' }); console.warn('websocket 连接失败,将导致多人编辑同一个接口冲突。'); }; }; // 点击编辑按钮 发送 websocket 获取数据 onEditor = () => { // this.WebSocket.send('editor'); const sendEditor = () => { this.WebSocket.send('editor'); }; this.handleWebsocketAccidentClose(sendEditor, status => { // 如果websocket 启动不成功用户依旧可以对wiki 进行编辑 if (!status) { this.setState({ isEditor: !this.state.isEditor }); } }); }; // 处理websocket 意外断开问题 handleWebsocketAccidentClose = (fn, callback) => { // websocket 是否启动 if (this.WebSocket) { // websocket 断开 if (this.WebSocket.readyState !== 1) { message.error('websocket 链接失败,请重新刷新页面'); } else { fn(); } callback(true); } else { callback(false); } }; // 获取数据 handleData = async params => { let result = await axios.get('/api/plugin/wiki_desc/get', { params }); if (result.data.errcode === 0) { const data = result.data.data; if (data) { this.setState({ desc: data.desc, markdown: data.markdown, username: data.username, uid: data.uid, editorTime: timeago(data.up_time) }); } } else { message.error(`请求数据失败: ${result.data.errmsg}`); } }; // 数据上传 onUpload = async (desc, markdown) => { const currProjectId = this.props.match.params.id; let option = { project_id: currProjectId, desc, markdown, email_notice: this.state.notice }; let result = await axios.post('/api/plugin/wiki_desc/up', option); if (result.data.errcode === 0) { await this.handleData({ project_id: currProjectId }); this.setState({ isEditor: false }); } else { message.error(`更新失败: ${result.data.errmsg}`); } this.endWebSocket(); // this.WebSocket.send('end'); }; // 取消编辑 onCancel = () => { this.setState({ isEditor: false }); this.endWebSocket(); }; // 邮件通知 onEmailNotice = e => { this.setState({ notice: e.target.checked }); }; render() { const { isEditor, username, editorTime, notice, uid, status, editUid, editName } = this.state; const editorEable = this.props.projectMsg.role === 'admin' || this.props.projectMsg.role === 'owner' || this.props.projectMsg.role === 'dev'; const isConflict = status === 'EDITOR'; return (
{isConflict && (
{editName || username} 正在编辑该wiki,请稍后再试...
)}
{!isEditor ? ( ) : ( )}
); } } export default WikiPage;