mirror of
https://github.com/YMFE/yapi.git
synced 2025-03-13 14:26:50 +08:00
fix: wiki 增加动态
This commit is contained in:
parent
8577935975
commit
215ee2fa02
@ -1,3 +1,8 @@
|
||||
### v1.3.19
|
||||
|
||||
* 增加项目文档记录wiki
|
||||
|
||||
|
||||
### v1.3.18
|
||||
|
||||
* 增加全局接口搜索功能
|
||||
|
@ -1,41 +1,41 @@
|
||||
import React, { PureComponent as Component } from 'react'
|
||||
import { Timeline, Spin, Row, Col, Tag, Avatar, Button, Modal, AutoComplete } from 'antd'
|
||||
import PropTypes from 'prop-types'
|
||||
import { connect } from 'react-redux'
|
||||
import React, { PureComponent as Component } from 'react';
|
||||
import { Timeline, Spin, Row, Col, Tag, Avatar, Button, Modal, AutoComplete } from 'antd';
|
||||
import PropTypes from 'prop-types';
|
||||
import { connect } from 'react-redux';
|
||||
import { formatTime } from '../../common.js';
|
||||
import showDiffMsg from '../../../common/diff-view.js'
|
||||
import showDiffMsg from '../../../common/diff-view.js';
|
||||
import variable from '../../constants/variable';
|
||||
import { Link } from 'react-router-dom'
|
||||
import { fetchNewsData, fetchMoreNews } from '../../reducer/modules/news.js'
|
||||
import { fetchInterfaceList } from '../../reducer/modules/interface.js'
|
||||
import { Link } from 'react-router-dom';
|
||||
import { fetchNewsData, fetchMoreNews } from '../../reducer/modules/news.js';
|
||||
import { fetchInterfaceList } from '../../reducer/modules/interface.js';
|
||||
import ErrMsg from '../ErrMsg/ErrMsg.js';
|
||||
const jsondiffpatch = require('jsondiffpatch/public/build/jsondiffpatch-full.js')
|
||||
const jsondiffpatch = require('jsondiffpatch/public/build/jsondiffpatch-full.js');
|
||||
const formattersHtml = require('jsondiffpatch/public/build/jsondiffpatch-formatters.js').html;
|
||||
import 'jsondiffpatch/public/formatters-styles/annotated.css'
|
||||
import 'jsondiffpatch/public/formatters-styles/html.css'
|
||||
import 'jsondiffpatch/public/formatters-styles/annotated.css';
|
||||
import 'jsondiffpatch/public/formatters-styles/html.css';
|
||||
|
||||
import './TimeLine.scss'
|
||||
import './TimeLine.scss';
|
||||
|
||||
const Option = AutoComplete.Option;
|
||||
|
||||
const AddDiffView = (props) => {
|
||||
const AddDiffView = props => {
|
||||
const { title, content, className } = props;
|
||||
if (!content) {
|
||||
return null;
|
||||
}
|
||||
return <div className={className}>
|
||||
<h3 className="title">{title}</h3>
|
||||
<div dangerouslySetInnerHTML={{ __html: content }}></div>
|
||||
</div>
|
||||
}
|
||||
return (
|
||||
<div className={className}>
|
||||
<h3 className="title">{title}</h3>
|
||||
<div dangerouslySetInnerHTML={{ __html: content }} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
AddDiffView.propTypes = {
|
||||
title: PropTypes.string,
|
||||
content: PropTypes.string,
|
||||
className: PropTypes.string
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
function timeago(timestamp) {
|
||||
let minutes, hours, days, seconds, mouth, year;
|
||||
@ -52,47 +52,45 @@ function timeago(timestamp) {
|
||||
mouth = 0;
|
||||
}
|
||||
if (seconds > 86400) {
|
||||
days = parseInt(seconds / (86400));
|
||||
days = parseInt(seconds / 86400);
|
||||
} else {
|
||||
days = 0;
|
||||
}
|
||||
if (seconds > 3600) {
|
||||
hours = parseInt(seconds / (3600));
|
||||
hours = parseInt(seconds / 3600);
|
||||
} else {
|
||||
hours = 0;
|
||||
}
|
||||
minutes = parseInt(seconds / 60);
|
||||
if (year > 0) {
|
||||
return year + "年前";
|
||||
return year + '年前';
|
||||
} else if (mouth > 0 && year <= 0) {
|
||||
return mouth + "月前";
|
||||
return mouth + '月前';
|
||||
} else if (days > 0 && mouth <= 0) {
|
||||
return days + "天前";
|
||||
return days + '天前';
|
||||
} else if (days <= 0 && hours > 0) {
|
||||
return hours + "小时前";
|
||||
return hours + '小时前';
|
||||
} else if (hours <= 0 && minutes > 0) {
|
||||
return minutes + "分钟前";
|
||||
return minutes + '分钟前';
|
||||
} else if (minutes <= 0 && seconds > 0) {
|
||||
if (seconds < 30) {
|
||||
return "刚刚";
|
||||
return '刚刚';
|
||||
} else {
|
||||
return seconds + "秒前";
|
||||
return seconds + '秒前';
|
||||
}
|
||||
|
||||
} else {
|
||||
return "刚刚";
|
||||
return '刚刚';
|
||||
}
|
||||
}
|
||||
// timeago(new Date().getTime() - 40);
|
||||
|
||||
@connect(
|
||||
|
||||
state => {
|
||||
return {
|
||||
newsData: state.news.newsData,
|
||||
curpage: state.news.curpage,
|
||||
curUid: state.user.uid
|
||||
}
|
||||
};
|
||||
},
|
||||
{
|
||||
fetchNewsData: fetchNewsData,
|
||||
@ -100,7 +98,6 @@ function timeago(timestamp) {
|
||||
fetchInterfaceList
|
||||
}
|
||||
)
|
||||
|
||||
class TimeTree extends Component {
|
||||
static propTypes = {
|
||||
newsData: PropTypes.object,
|
||||
@ -113,33 +110,39 @@ class TimeTree extends Component {
|
||||
curUid: PropTypes.number,
|
||||
type: PropTypes.string,
|
||||
fetchInterfaceList: PropTypes.func
|
||||
}
|
||||
};
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
bidden: "",
|
||||
bidden: '',
|
||||
loading: false,
|
||||
visible: false,
|
||||
curDiffData: {},
|
||||
apiList: []
|
||||
}
|
||||
};
|
||||
this.curInterfaceId = '';
|
||||
}
|
||||
|
||||
|
||||
getMore() {
|
||||
const that = this;
|
||||
|
||||
if (this.props.curpage <= this.props.newsData.total) {
|
||||
|
||||
this.setState({ loading: true });
|
||||
this.props.fetchMoreNews(this.props.typeid, this.props.type, this.props.curpage + 1, 10, this.curInterfaceId).then(function () {
|
||||
that.setState({ loading: false });
|
||||
if (that.props.newsData.total === that.props.curpage) {
|
||||
that.setState({ bidden: "logbidden" })
|
||||
}
|
||||
})
|
||||
this.props
|
||||
.fetchMoreNews(
|
||||
this.props.typeid,
|
||||
this.props.type,
|
||||
this.props.curpage + 1,
|
||||
10,
|
||||
this.curInterfaceId
|
||||
)
|
||||
.then(function() {
|
||||
that.setState({ loading: false });
|
||||
if (that.props.newsData.total === that.props.curpage) {
|
||||
that.setState({ bidden: 'logbidden' });
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -147,89 +150,116 @@ class TimeTree extends Component {
|
||||
this.setState({
|
||||
visible: false
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
componentWillMount() {
|
||||
this.props.fetchNewsData(this.props.typeid, this.props.type, 1, 10)
|
||||
this.props.fetchNewsData(this.props.typeid, this.props.type, 1, 10);
|
||||
if (this.props.type === 'project') {
|
||||
this.getApiList()
|
||||
this.getApiList();
|
||||
}
|
||||
}
|
||||
|
||||
openDiff = (data) => {
|
||||
openDiff = data => {
|
||||
this.setState({
|
||||
curDiffData: data,
|
||||
visible: true
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
async getApiList() {
|
||||
let result = await this.props.fetchInterfaceList({project_id: this.props.typeid, limit: 'all'});
|
||||
let result = await this.props.fetchInterfaceList({
|
||||
project_id: this.props.typeid,
|
||||
limit: 'all'
|
||||
});
|
||||
this.setState({
|
||||
apiList: result.payload.data.data.list
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
handleSelectApi = (interfaceId) => {
|
||||
handleSelectApi = interfaceId => {
|
||||
this.curInterfaceId = interfaceId;
|
||||
this.props.fetchNewsData(this.props.typeid, this.props.type, 1, 10, interfaceId)
|
||||
}
|
||||
this.props.fetchNewsData(this.props.typeid, this.props.type, 1, 10, interfaceId);
|
||||
};
|
||||
|
||||
render() {
|
||||
let data = this.props.newsData ? this.props.newsData.list : [];
|
||||
|
||||
const curDiffData = this.state.curDiffData;
|
||||
let logType = {
|
||||
project: "项目",
|
||||
group: "分组",
|
||||
interface: "接口",
|
||||
interface_col: "接口集",
|
||||
user: "用户",
|
||||
other: "其他"
|
||||
project: '项目',
|
||||
group: '分组',
|
||||
interface: '接口',
|
||||
interface_col: '接口集',
|
||||
user: '用户',
|
||||
other: '其他'
|
||||
};
|
||||
|
||||
|
||||
|
||||
const children = this.state.apiList.map((item) => {
|
||||
const children = this.state.apiList.map(item => {
|
||||
let methodColor = variable.METHOD_COLOR[item.method ? item.method.toLowerCase() : 'get'];
|
||||
return <Option title={item.title} value={item._id + ''} path={item.path} key={item._id}>{item.path} <Tag style={{ color: methodColor.color, backgroundColor: methodColor.bac, border: 'unset' }} >{item.method}</Tag></Option>;
|
||||
return (
|
||||
<Option title={item.title} value={item._id + ''} path={item.path} key={item._id}>
|
||||
{item.title}{' '}
|
||||
<Tag
|
||||
style={{ color: methodColor.color, backgroundColor: methodColor.bac, border: 'unset' }}
|
||||
>
|
||||
{item.method}
|
||||
</Tag>
|
||||
</Option>
|
||||
);
|
||||
});
|
||||
|
||||
children.unshift(
|
||||
<Option value='' key='all' >选择全部</Option>
|
||||
)
|
||||
<Option value="" key="all">
|
||||
选择全部
|
||||
</Option>
|
||||
);
|
||||
|
||||
|
||||
|
||||
if (data && data.length) {
|
||||
data = data.map((item, i) => {
|
||||
let interfaceDiff = false;
|
||||
if (item.data && typeof item.data === 'object' && item.data.interface_id) {
|
||||
// 去掉了 && item.data.interface_id
|
||||
if (item.data && typeof item.data === 'object') {
|
||||
interfaceDiff = true;
|
||||
|
||||
}
|
||||
return (<Timeline.Item dot={<Link to={`/user/profile/${item.uid}`}><Avatar src={`/api/user/avatar?uid=${item.uid}`} /></Link>} key={i}>
|
||||
<div className="logMesHeade">
|
||||
<span className="logoTimeago">{timeago(item.add_time)}</span>
|
||||
{/*<span className="logusername"><Link to={`/user/profile/${item.uid}`}><Icon type="user" />{item.username}</Link></span>*/}
|
||||
<span className="logtype">{logType[item.type]}动态</span>
|
||||
<span className="logtime">{formatTime(item.add_time)}</span>
|
||||
</div>
|
||||
<span className="logcontent" dangerouslySetInnerHTML={{ __html: item.content }}></span>
|
||||
<div style={{ padding: "10px 0 0 10px" }}>{interfaceDiff &&
|
||||
<Button onClick={() => this.openDiff(item.data)}>改动详情</Button>
|
||||
}</div>
|
||||
</Timeline.Item>);
|
||||
return (
|
||||
<Timeline.Item
|
||||
dot={
|
||||
<Link to={`/user/profile/${item.uid}`}>
|
||||
<Avatar src={`/api/user/avatar?uid=${item.uid}`} />
|
||||
</Link>
|
||||
}
|
||||
key={i}
|
||||
>
|
||||
<div className="logMesHeade">
|
||||
<span className="logoTimeago">{timeago(item.add_time)}</span>
|
||||
{/*<span className="logusername"><Link to={`/user/profile/${item.uid}`}><Icon type="user" />{item.username}</Link></span>*/}
|
||||
<span className="logtype">{logType[item.type]}动态</span>
|
||||
<span className="logtime">{formatTime(item.add_time)}</span>
|
||||
</div>
|
||||
<span className="logcontent" dangerouslySetInnerHTML={{ __html: item.content }} />
|
||||
<div style={{ padding: '10px 0 0 10px' }}>
|
||||
{interfaceDiff && <Button onClick={() => this.openDiff(item.data)}>改动详情</Button>}
|
||||
</div>
|
||||
</Timeline.Item>
|
||||
);
|
||||
});
|
||||
} else {
|
||||
data = "";
|
||||
data = '';
|
||||
}
|
||||
let pending = this.props.newsData.total <= this.props.curpage ? <a className="logbidden">以上为全部内容</a> : <a className="loggetMore" onClick={this.getMore.bind(this)}>查看更多</a>;
|
||||
let pending =
|
||||
this.props.newsData.total <= this.props.curpage ? (
|
||||
<a className="logbidden">以上为全部内容</a>
|
||||
) : (
|
||||
<a className="loggetMore" onClick={this.getMore.bind(this)}>
|
||||
查看更多
|
||||
</a>
|
||||
);
|
||||
if (this.state.loading) {
|
||||
pending = <Spin />
|
||||
pending = <Spin />;
|
||||
}
|
||||
let diffView = showDiffMsg(jsondiffpatch, formattersHtml, curDiffData);
|
||||
|
||||
|
||||
|
||||
return (
|
||||
<section className="news-timeline">
|
||||
@ -243,14 +273,19 @@ class TimeTree extends Component {
|
||||
<i>注: 绿色代表新增内容,红色代表删除内容</i>
|
||||
<div className="project-interface-change-content">
|
||||
{diffView.map((item, index) => {
|
||||
return <AddDiffView className="item-content" title={item.title} key={index} content={item.content} />
|
||||
return (
|
||||
<AddDiffView
|
||||
className="item-content"
|
||||
title={item.title}
|
||||
key={index}
|
||||
content={item.content}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
{diffView.length === 0 &&
|
||||
<ErrMsg type="noChange" />
|
||||
}
|
||||
{diffView.length === 0 && <ErrMsg type="noChange" />}
|
||||
</div>
|
||||
</Modal>
|
||||
{this.props.type === 'project' &&
|
||||
{this.props.type === 'project' && (
|
||||
<Row className="news-search">
|
||||
<Col span="3">选择查询的 Api:</Col>
|
||||
<Col span="10">
|
||||
@ -258,10 +293,14 @@ class TimeTree extends Component {
|
||||
onSelect={this.handleSelectApi}
|
||||
style={{ width: '100%' }}
|
||||
placeholder="Select Api"
|
||||
optionLabelProp="path"
|
||||
optionLabelProp="title"
|
||||
filterOption={(inputValue, options) => {
|
||||
console.log(options);
|
||||
if (options.props.value == '') return true;
|
||||
if (options.props.path.indexOf(inputValue) !== -1 || options.props.title.indexOf(inputValue) !== -1) {
|
||||
if (
|
||||
options.props.path.indexOf(inputValue) !== -1 ||
|
||||
options.props.title.indexOf(inputValue) !== -1
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -270,13 +309,18 @@ class TimeTree extends Component {
|
||||
{children}
|
||||
</AutoComplete>
|
||||
</Col>
|
||||
|
||||
</Row>
|
||||
}
|
||||
{data ? <Timeline className="news-content" pending={pending}>{data}</Timeline> : <ErrMsg type="noData" />}
|
||||
)}
|
||||
{data ? (
|
||||
<Timeline className="news-content" pending={pending}>
|
||||
{data}
|
||||
</Timeline>
|
||||
) : (
|
||||
<ErrMsg type="noData" />
|
||||
)}
|
||||
</section>
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default TimeTree
|
||||
export default TimeTree;
|
||||
|
@ -66,7 +66,17 @@ module.exports = function (jsondiffpatch, formattersHtml, curDiffData) {
|
||||
|
||||
|
||||
if (curDiffData && typeof curDiffData === 'object' && curDiffData.current) {
|
||||
const { current, old } = curDiffData;
|
||||
const { current, old, type } = curDiffData;
|
||||
// wiki 信息的diff 输出
|
||||
if(type === 'wiki') {
|
||||
if (current != old) {
|
||||
diffView.push({
|
||||
title: 'wiki更新',
|
||||
content: diffText(old, current)
|
||||
})
|
||||
}
|
||||
return diffView = diffView.filter(item => item.content)
|
||||
}
|
||||
if (current.path != old.path) {
|
||||
diffView.push({
|
||||
title: 'Api 路径',
|
||||
|
@ -169,4 +169,5 @@ exports.json_format= function(json){
|
||||
}catch(e){
|
||||
return json;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -49,7 +49,7 @@ module.exports = function(){
|
||||
interface_id: interfaceId,
|
||||
ip_enable: true,
|
||||
ip: ip
|
||||
}).select('_id params');
|
||||
}).select('_id params');
|
||||
let matchList = [];
|
||||
listWithIp.forEach(item=>{
|
||||
let params = item.params;
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React, { Component } from 'react';
|
||||
import { Button, message, Checkbox } from 'antd';
|
||||
import { connect } from 'react-redux'
|
||||
import { connect } from 'react-redux';
|
||||
import axios from 'axios';
|
||||
import PropTypes from 'prop-types';
|
||||
import './index.scss';
|
||||
@ -11,7 +11,8 @@ require('tui-editor/dist/tui-editor-contents.css'); // editor content
|
||||
require('highlight.js/styles/github.css'); // code block highlight
|
||||
// require('./editor.css');
|
||||
var Editor = require('tui-editor');
|
||||
import { formatDate } from '../util.js';
|
||||
import { timeago } from '../util.js';
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
@connect(
|
||||
state => {
|
||||
@ -69,7 +70,8 @@ class WikiPage extends Component {
|
||||
desc: data.desc,
|
||||
markdown: data.markdown,
|
||||
username: data.username,
|
||||
editorTime: formatDate(data.up_time * 1000)
|
||||
uid: data.uid,
|
||||
editorTime: timeago(data.up_time)
|
||||
});
|
||||
}
|
||||
} else {
|
||||
@ -101,16 +103,18 @@ class WikiPage extends Component {
|
||||
};
|
||||
|
||||
// 邮件通知
|
||||
onEmailNotice = (e) => {
|
||||
onEmailNotice = e => {
|
||||
this.setState({
|
||||
notice: e.target.checked
|
||||
})
|
||||
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
render() {
|
||||
const { isEditor, username, editorTime, notice } = this.state;
|
||||
const editorEable = this.props.projectMsg.role === 'admin' || this.props.projectMsg.role === 'owner' || this.props.projectMsg.role === 'dev'
|
||||
const { isEditor, username, editorTime, notice, uid } = this.state;
|
||||
const editorEable =
|
||||
this.props.projectMsg.role === 'admin' ||
|
||||
this.props.projectMsg.role === 'owner' ||
|
||||
this.props.projectMsg.role === 'dev';
|
||||
return (
|
||||
<div className="g-row">
|
||||
<div className="m-panel wiki-content">
|
||||
@ -124,15 +128,24 @@ class WikiPage extends Component {
|
||||
<Button icon="upload" type="primary" className="upload-btn" onClick={this.onUpload}>
|
||||
更新
|
||||
</Button>
|
||||
<Button onClick={this.onCancel} className="upload-btn">取消</Button>
|
||||
<Checkbox checked={notice} onChange={this.onEmailNotice}>通知相关人员</Checkbox>
|
||||
<Button onClick={this.onCancel} className="upload-btn">
|
||||
取消
|
||||
</Button>
|
||||
<Checkbox checked={notice} onChange={this.onEmailNotice}>
|
||||
通知相关人员
|
||||
</Checkbox>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
{!isEditor &&
|
||||
username && (
|
||||
<div className="wiki-user">
|
||||
由{username}修改于{editorTime}
|
||||
{/* 由 {username} */}
|
||||
<Link className="user-name" to={`/user/profile/${uid || 11}`}>
|
||||
{/* <img src={'/api/user/avatar?uid=' + this.props.curData.uid} className="user-img" /> */}
|
||||
{username}
|
||||
</Link>
|
||||
修改于 {editorTime}
|
||||
</div>
|
||||
)}
|
||||
<div id="desc" className="wiki-editor" style={{ display: isEditor ? 'block' : 'none' }} />
|
||||
|
@ -3,7 +3,7 @@ import WikiPage from './WikiPage/index'
|
||||
module.exports = function(){
|
||||
this.bindHook('sub_nav', function(app){
|
||||
app.wiki = {
|
||||
name: 'wiki',
|
||||
name: 'Wiki',
|
||||
path: '/project/:id/wiki',
|
||||
component: WikiPage
|
||||
}
|
||||
|
@ -5,10 +5,10 @@ const projectModel = require('models/project.js');
|
||||
const jsondiffpatch = require('jsondiffpatch');
|
||||
const formattersHtml = jsondiffpatch.formatters.html;
|
||||
const yapi = require('yapi.js');
|
||||
const util = require('./util.js');
|
||||
const fs = require('fs-extra')
|
||||
// const util = require('./util.js');
|
||||
const fs = require('fs-extra');
|
||||
const path = require('path');
|
||||
|
||||
const showDiffMsg = require('../../common/diff-view.js');
|
||||
class wikiController extends baseController {
|
||||
constructor(ctx) {
|
||||
super(ctx);
|
||||
@ -68,12 +68,15 @@ class wikiController extends baseController {
|
||||
|
||||
let notice = params.email_notice;
|
||||
delete params.email_notice;
|
||||
const username = this.getUsername();
|
||||
const uid = this.getUid();
|
||||
|
||||
// 如果当前数据库里面没有数据
|
||||
let result = await this.Model.get(params.project_id)
|
||||
if(!result) {
|
||||
let data = Object.assign(params, {
|
||||
username: this.getUsername(),
|
||||
username,
|
||||
uid,
|
||||
add_time: yapi.commons.time(),
|
||||
up_time: yapi.commons.time()
|
||||
});
|
||||
@ -84,42 +87,57 @@ class wikiController extends baseController {
|
||||
|
||||
// console.log('result', result);
|
||||
let data = Object.assign(params, {
|
||||
username: this.getUsername(),
|
||||
username,
|
||||
uid,
|
||||
up_time: yapi.commons.time()
|
||||
});
|
||||
let upRes = await this.Model.up(result._id, data);
|
||||
ctx.body = yapi.commons.resReturn(upRes)
|
||||
|
||||
let logData = {
|
||||
type: 'wiki',
|
||||
project_id: params.project_id,
|
||||
current: params.desc,
|
||||
old: result ? result.toObject().desc : ''
|
||||
}
|
||||
let wikiUrl = `http://${ctx.request.host}/project/${params.project_id}/wiki`
|
||||
|
||||
if(notice) {
|
||||
let logData = {
|
||||
project_id: params.project_id,
|
||||
current: params.desc,
|
||||
old: result ? result.toObject().desc : ''
|
||||
}
|
||||
let diffView = util.showDiffMsg(jsondiffpatch, formattersHtml, logData);
|
||||
let diffView = showDiffMsg(jsondiffpatch, formattersHtml, logData);
|
||||
|
||||
let annotatedCss = fs.readFileSync(path.resolve(yapi.WEBROOT, 'node_modules/jsondiffpatch/public/formatters-styles/annotated.css'), 'utf8');
|
||||
let htmlCss = fs.readFileSync(path.resolve(yapi.WEBROOT, 'node_modules/jsondiffpatch/public/formatters-styles/html.css'), 'utf8');
|
||||
let project = await this.projectModel.getBaseInfo(params.project_id);
|
||||
let wikiUrl = `http://${ctx.request.host}/project/${params.project_id}/wiki`
|
||||
|
||||
yapi.commons.sendNotice(params.project_id, {
|
||||
title: `${this.getUsername()} 更新了wiki说明`,
|
||||
title: `${username} 更新了wiki说明`,
|
||||
content: `<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<style>
|
||||
${annotatedCss}
|
||||
${htmlCss}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div><h3>${this.getUsername()}更新了wiki</h3>
|
||||
<p>修改用户: ${this.getUsername()}</p>
|
||||
<div><h3>${username}更新了wiki说明</h3>
|
||||
<p>修改用户: ${username}</p>
|
||||
<p>修改项目: <a href="${wikiUrl}">${project.name}</a></p>
|
||||
<p>详细改动日志: ${this.diffHTML(diffView)}</p></div>
|
||||
</body>
|
||||
</html>`
|
||||
})
|
||||
}
|
||||
|
||||
// 保存修改日志信息
|
||||
yapi.commons.saveLog({
|
||||
content: `<a href="/user/profile/${uid}">${username}</a> 更新了 <a href="${wikiUrl}">wiki</a> 的信息`,
|
||||
type: 'project',
|
||||
uid,
|
||||
username: username,
|
||||
typeid: params.project_id,
|
||||
data: logData
|
||||
});
|
||||
// let upRes = await this.Model.get(result._id)
|
||||
return 1;
|
||||
} catch (err) {
|
||||
|
@ -16,6 +16,7 @@ module.exports = function () {
|
||||
|
||||
this.bindHook('add_router', function (addRouter) {
|
||||
addRouter({
|
||||
// 获取wiki信息
|
||||
controller: controller,
|
||||
method: 'get',
|
||||
path: 'wiki_desc/get',
|
||||
@ -23,24 +24,12 @@ module.exports = function () {
|
||||
})
|
||||
|
||||
addRouter({
|
||||
// 更新wiki信息
|
||||
controller: controller,
|
||||
method: 'post',
|
||||
path: 'wiki_desc/up',
|
||||
action: 'uplodaWikiDesc'
|
||||
})
|
||||
// addRouter({
|
||||
// controller: controller,
|
||||
// method: 'get',
|
||||
// path: 'statismock/get_system_status',
|
||||
// action: 'getSystemStatus'
|
||||
// })
|
||||
// addRouter({
|
||||
// controller: controller,
|
||||
// method: 'get',
|
||||
// path: 'statismock/group_data_statis',
|
||||
// action: 'groupDataStatis'
|
||||
// })
|
||||
|
||||
|
||||
})
|
||||
};
|
@ -28,37 +28,51 @@ const convert2Decimal = num => (num > 9 ? num : `0${num}`)
|
||||
|
||||
// const json5_parse = require('../client/common.js').json5_parse;
|
||||
|
||||
|
||||
|
||||
exports.showDiffMsg = (jsondiffpatch, formattersHtml, curDiffData) => {
|
||||
|
||||
const diffText = (left, right) => {
|
||||
left = left || '';
|
||||
right = right || '';
|
||||
if (left == right) {
|
||||
return null;
|
||||
}
|
||||
var delta = jsondiffpatch.diff(left, right);
|
||||
return formattersHtml.format(delta, left)
|
||||
exports.timeago =(timestamp) => {
|
||||
let minutes, hours, days, seconds, mouth, year;
|
||||
const timeNow = parseInt(new Date().getTime() / 1000);
|
||||
seconds = timeNow - timestamp;
|
||||
if (seconds > 86400 * 30 * 12) {
|
||||
year = parseInt(seconds / (86400 * 30 * 12));
|
||||
} else {
|
||||
year = 0;
|
||||
}
|
||||
|
||||
|
||||
let diffView = [];
|
||||
|
||||
|
||||
if (curDiffData && typeof curDiffData === 'object' && curDiffData.current) {
|
||||
const { current, old } = curDiffData;
|
||||
if (current != old) {
|
||||
diffView.push({
|
||||
title: 'wiki更新',
|
||||
content: diffText(old, current)
|
||||
})
|
||||
}
|
||||
|
||||
if (seconds > 86400 * 30) {
|
||||
mouth = parseInt(seconds / (86400 * 30));
|
||||
} else {
|
||||
mouth = 0;
|
||||
}
|
||||
|
||||
|
||||
return diffView = diffView.filter(item => item.content)
|
||||
|
||||
if (seconds > 86400) {
|
||||
days = parseInt(seconds / (86400));
|
||||
} else {
|
||||
days = 0;
|
||||
}
|
||||
if (seconds > 3600) {
|
||||
hours = parseInt(seconds / (3600));
|
||||
} else {
|
||||
hours = 0;
|
||||
}
|
||||
minutes = parseInt(seconds / 60);
|
||||
if (year > 0) {
|
||||
return year + "年前";
|
||||
} else if (mouth > 0 && year <= 0) {
|
||||
return mouth + "月前";
|
||||
} else if (days > 0 && mouth <= 0) {
|
||||
return days + "天前";
|
||||
} else if (days <= 0 && hours > 0) {
|
||||
return hours + "小时前";
|
||||
} else if (hours <= 0 && minutes > 0) {
|
||||
return minutes + "分钟前";
|
||||
} else if (minutes <= 0 && seconds > 0) {
|
||||
if (seconds < 30) {
|
||||
return "刚刚";
|
||||
} else {
|
||||
return seconds + "秒前";
|
||||
}
|
||||
|
||||
} else {
|
||||
return "刚刚";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -10,6 +10,7 @@ class statisMockModel extends baseModel {
|
||||
return {
|
||||
project_id: { type: Number, required: true },
|
||||
username: String,
|
||||
uid: Number,
|
||||
desc: String,
|
||||
markdown: String,
|
||||
add_time: Number,
|
||||
|
@ -672,7 +672,7 @@ class interfaceColController extends baseController {
|
||||
let result = await this.colModel.up(id, params);
|
||||
let username = this.getUsername();
|
||||
yapi.commons.saveLog({
|
||||
content: `<a href="/user/profile/${this.getUid()}">${username}</a> 更新了接口集 <a href="/project/${colData.project_id}/interface/col/${id}">${colData.name}</a> 的信息`,
|
||||
content: `<a href="/user/profile/${this.getUid()}">${username}</a> 更新了测试集合 <a href="/project/${colData.project_id}/interface/col/${id}">${colData.name}</a> 的信息`,
|
||||
type: 'project',
|
||||
uid: this.getUid(),
|
||||
username: username,
|
||||
|
@ -908,9 +908,10 @@ class projectController extends baseController {
|
||||
return (ctx.body = yapi.commons.resReturn(null, 405, '项目id不能为空'));
|
||||
}
|
||||
|
||||
if ((await this.checkAuth(project_id, 'project', 'edit')) !== true) {
|
||||
return (ctx.body = yapi.commons.resReturn(null, 405, '没有权限'));
|
||||
}
|
||||
// 去掉权限判断
|
||||
// if ((await this.checkAuth(project_id, 'project', 'edit')) !== true) {
|
||||
// return (ctx.body = yapi.commons.resReturn(null, 405, '没有权限'));
|
||||
// }
|
||||
|
||||
let env = await this.Model.getByEnv(project_id);
|
||||
// console.log('project', projectData)
|
||||
|
Loading…
x
Reference in New Issue
Block a user