yapi-next/vendors/exts/yapi-plugin-wiki/wikiPage/index.js
2023-06-25 19:08:56 +08:00

256 lines
6.5 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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;