diff --git a/CHANGELOG.md b/CHANGELOG.md
index 351ce85b..b6b11434 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,8 @@
+### v1.3.19
+
+* 增加项目文档记录wiki
+
+
### v1.3.18
* 增加全局接口搜索功能
diff --git a/client/components/TimeLine/TimeLine.js b/client/components/TimeLine/TimeLine.js
index 53081f89..4e8e1463 100644
--- a/client/components/TimeLine/TimeLine.js
+++ b/client/components/TimeLine/TimeLine.js
@@ -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
-}
+ return (
+
+ );
+};
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 ;
+ return (
+
+ );
});
children.unshift(
-
- )
+
+ );
+
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 (} key={i}>
-
- {timeago(item.add_time)}
- {/*{item.username}*/}
- {logType[item.type]}动态
- {formatTime(item.add_time)}
-
-
- {interfaceDiff &&
-
- }
- );
+ return (
+
+
+
+ }
+ key={i}
+ >
+
+ {timeago(item.add_time)}
+ {/*{item.username}*/}
+ {logType[item.type]}动态
+ {formatTime(item.add_time)}
+
+
+
+ {interfaceDiff && }
+
+
+ );
});
} else {
- data = "";
+ data = '';
}
- let pending = this.props.newsData.total <= this.props.curpage ? 以上为全部内容 : 查看更多;
+ let pending =
+ this.props.newsData.total <= this.props.curpage ? (
+ 以上为全部内容
+ ) : (
+
+ 查看更多
+
+ );
if (this.state.loading) {
- pending =
+ pending = ;
}
let diffView = showDiffMsg(jsondiffpatch, formattersHtml, curDiffData);
-
-
return (
@@ -243,14 +273,19 @@ class TimeTree extends Component {
注: 绿色代表新增内容,红色代表删除内容
{diffView.map((item, index) => {
- return
+ return (
+
+ );
})}
- {diffView.length === 0 &&
-
- }
+ {diffView.length === 0 &&
}
- {this.props.type === 'project' &&
+ {this.props.type === 'project' && (
选择查询的 Api:
@@ -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}
-
- }
- {data ? {data} : }
+ )}
+ {data ? (
+
+ {data}
+
+ ) : (
+
+ )}
- )
+ );
}
}
-export default TimeTree
+export default TimeTree;
diff --git a/common/diff-view.js b/common/diff-view.js
index e6ca138f..d95898c3 100644
--- a/common/diff-view.js
+++ b/common/diff-view.js
@@ -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 路径',
diff --git a/common/utils.js b/common/utils.js
index bd9b23ca..5407b054 100644
--- a/common/utils.js
+++ b/common/utils.js
@@ -169,4 +169,5 @@ exports.json_format= function(json){
}catch(e){
return json;
}
-}
\ No newline at end of file
+}
+
diff --git a/exts/yapi-plugin-advanced-mock/server.js b/exts/yapi-plugin-advanced-mock/server.js
index 733c8708..d8a357fa 100644
--- a/exts/yapi-plugin-advanced-mock/server.js
+++ b/exts/yapi-plugin-advanced-mock/server.js
@@ -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;
diff --git a/exts/yapi-plugin-wiki/WikiPage/index.js b/exts/yapi-plugin-wiki/WikiPage/index.js
index a90c8ae7..ca992e33 100644
--- a/exts/yapi-plugin-wiki/WikiPage/index.js
+++ b/exts/yapi-plugin-wiki/WikiPage/index.js
@@ -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 (
@@ -124,15 +128,24 @@ class WikiPage extends Component {
-
- 通知相关人员
+
+
+ 通知相关人员
+
)}
{!isEditor &&
username && (
- 由{username}修改于{editorTime}
+ {/* 由 {username} */}
+
+ {/*

*/}
+ {username}
+
+ 修改于 {editorTime}
)}
diff --git a/exts/yapi-plugin-wiki/client.js b/exts/yapi-plugin-wiki/client.js
index 4a01abf8..48d0bda9 100644
--- a/exts/yapi-plugin-wiki/client.js
+++ b/exts/yapi-plugin-wiki/client.js
@@ -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
}
diff --git a/exts/yapi-plugin-wiki/controller.js b/exts/yapi-plugin-wiki/controller.js
index 4324dd47..46490a62 100644
--- a/exts/yapi-plugin-wiki/controller.js
+++ b/exts/yapi-plugin-wiki/controller.js
@@ -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: `
+
- ${this.getUsername()}更新了wiki
-
修改用户: ${this.getUsername()}
+
${username}更新了wiki说明
+
修改用户: ${username}
修改项目: ${project.name}
详细改动日志: ${this.diffHTML(diffView)}
`
})
}
+
+ // 保存修改日志信息
+ yapi.commons.saveLog({
+ content: `
${username} 更新了
wiki 的信息`,
+ type: 'project',
+ uid,
+ username: username,
+ typeid: params.project_id,
+ data: logData
+ });
// let upRes = await this.Model.get(result._id)
return 1;
} catch (err) {
diff --git a/exts/yapi-plugin-wiki/server.js b/exts/yapi-plugin-wiki/server.js
index 63463134..6c7bdcc7 100644
--- a/exts/yapi-plugin-wiki/server.js
+++ b/exts/yapi-plugin-wiki/server.js
@@ -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'
- // })
-
})
};
\ No newline at end of file
diff --git a/exts/yapi-plugin-wiki/util.js b/exts/yapi-plugin-wiki/util.js
index 82912640..5e8b34d5 100644
--- a/exts/yapi-plugin-wiki/util.js
+++ b/exts/yapi-plugin-wiki/util.js
@@ -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 "刚刚";
+ }
}
+
+
diff --git a/exts/yapi-plugin-wiki/wikiModel.js b/exts/yapi-plugin-wiki/wikiModel.js
index 6c39a181..965043b4 100644
--- a/exts/yapi-plugin-wiki/wikiModel.js
+++ b/exts/yapi-plugin-wiki/wikiModel.js
@@ -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,
diff --git a/server/controllers/interfaceCol.js b/server/controllers/interfaceCol.js
index 87bd8094..6ef696ba 100755
--- a/server/controllers/interfaceCol.js
+++ b/server/controllers/interfaceCol.js
@@ -672,7 +672,7 @@ class interfaceColController extends baseController {
let result = await this.colModel.up(id, params);
let username = this.getUsername();
yapi.commons.saveLog({
- content: `
${username} 更新了接口集
${colData.name} 的信息`,
+ content: `
${username} 更新了测试集合
${colData.name} 的信息`,
type: 'project',
uid: this.getUid(),
username: username,
diff --git a/server/controllers/project.js b/server/controllers/project.js
index 37cdfd1c..31734c83 100755
--- a/server/controllers/project.js
+++ b/server/controllers/project.js
@@ -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)