This commit is contained in:
2024-03-01 20:28:14 +08:00
commit 076c21dc36
491 changed files with 84482 additions and 0 deletions

View File

@@ -0,0 +1,255 @@
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 (
<div className="g-row">
<div className="m-panel wiki-content">
<div className="wiki-content">
{isConflict && (
<div className="wiki-conflict">
<Link to={`/user/profile/${editUid || uid}`}>
<b>{editName || username}</b>
</Link>
<span>正在编辑该wiki请稍后再试...</span>
</div>
)}
</div>
{!isEditor ? (
<WikiView
editorEable={editorEable}
onEditor={this.onEditor}
uid={uid}
username={username}
editorTime={editorTime}
desc={this.state.desc}
/>
) : (
<WikiEditor
isConflict={isConflict}
onUpload={this.onUpload}
onCancel={this.onCancel}
notice={notice}
onEmailNotice={this.onEmailNotice}
desc={this.state.desc}
/>
)}
</div>
</div>
);
}
}
export default WikiPage;