fork from bc4552c5a8
This commit is contained in:
12
exts/yapi-plugin-swagger-auto-sync/client.js
Normal file
12
exts/yapi-plugin-swagger-auto-sync/client.js
Normal file
@@ -0,0 +1,12 @@
|
||||
import swaggerAutoSync from './swaggerAutoSync/swaggerAutoSync.js'
|
||||
|
||||
function hander(routers) {
|
||||
routers.test = {
|
||||
name: 'Swagger自动同步',
|
||||
component: swaggerAutoSync
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = function() {
|
||||
this.bindHook('sub_setting_nav', hander);
|
||||
};
|
||||
@@ -0,0 +1,62 @@
|
||||
const baseController = require('controllers/base.js');
|
||||
const yapi = require('yapi.js');
|
||||
const syncModel = require('../syncModel.js');
|
||||
const projectModel = require('models/project.js');
|
||||
const interfaceSyncUtils = require('../interfaceSyncUtils.js')
|
||||
|
||||
class syncController extends baseController {
|
||||
constructor(ctx) {
|
||||
super(ctx);
|
||||
this.syncModel = yapi.getInst(syncModel);
|
||||
this.projectModel = yapi.getInst(projectModel);
|
||||
this.interfaceSyncUtils = yapi.getInst(interfaceSyncUtils);
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存定时任务
|
||||
* @param {*} ctx
|
||||
*/
|
||||
async upSync(ctx) {
|
||||
let requestBody = ctx.request.body;
|
||||
let projectId = requestBody.project_id;
|
||||
if (!projectId) {
|
||||
return (ctx.body = yapi.commons.resReturn(null, 408, '缺少项目Id'));
|
||||
}
|
||||
|
||||
if ((await this.checkAuth(projectId, 'project', 'edit')) !== true) {
|
||||
return (ctx.body = yapi.commons.resReturn(null, 405, '没有权限'));
|
||||
}
|
||||
|
||||
let result;
|
||||
if (requestBody.id) {
|
||||
result = await this.syncModel.up(requestBody);
|
||||
} else {
|
||||
result = await this.syncModel.save(requestBody);
|
||||
}
|
||||
|
||||
//操作定时任务
|
||||
if (requestBody.is_sync_open) {
|
||||
this.interfaceSyncUtils.addSyncJob(projectId, requestBody.sync_cron, requestBody.sync_json_url, requestBody.sync_mode, requestBody.uid);
|
||||
} else {
|
||||
this.interfaceSyncUtils.deleteSyncJob(projectId);
|
||||
}
|
||||
return (ctx.body = yapi.commons.resReturn(result));
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询定时任务
|
||||
* @param {*} ctx
|
||||
*/
|
||||
async getSync(ctx) {
|
||||
let projectId = ctx.query.project_id;
|
||||
if (!projectId) {
|
||||
return (ctx.body = yapi.commons.resReturn(null, 408, '缺少项目Id'));
|
||||
}
|
||||
let result = await this.syncModel.getByProjectId(projectId);
|
||||
return (ctx.body = yapi.commons.resReturn(result));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
module.exports = syncController;
|
||||
4
exts/yapi-plugin-swagger-auto-sync/index.js
Normal file
4
exts/yapi-plugin-swagger-auto-sync/index.js
Normal file
@@ -0,0 +1,4 @@
|
||||
module.exports = {
|
||||
server: true,
|
||||
client: true
|
||||
}
|
||||
221
exts/yapi-plugin-swagger-auto-sync/interfaceSyncUtils.js
Normal file
221
exts/yapi-plugin-swagger-auto-sync/interfaceSyncUtils.js
Normal file
@@ -0,0 +1,221 @@
|
||||
const schedule = require('node-schedule');
|
||||
const openController = require('controllers/open.js');
|
||||
const projectModel = require('models/project.js');
|
||||
const syncModel = require('./syncModel.js');
|
||||
const tokenModel = require('models/token.js');
|
||||
const yapi = require('yapi.js')
|
||||
const sha = require('sha.js');
|
||||
const md5 = require('md5');
|
||||
const { getToken } = require('utils/token');
|
||||
const jobMap = new Map();
|
||||
|
||||
class syncUtils {
|
||||
|
||||
constructor(ctx) {
|
||||
yapi.commons.log("-------------------------------------swaggerSyncUtils constructor-----------------------------------------------");
|
||||
this.ctx = ctx;
|
||||
this.openController = yapi.getInst(openController);
|
||||
this.syncModel = yapi.getInst(syncModel);
|
||||
this.tokenModel = yapi.getInst(tokenModel)
|
||||
this.projectModel = yapi.getInst(projectModel);
|
||||
this.init()
|
||||
}
|
||||
|
||||
//初始化定时任务
|
||||
async init() {
|
||||
let allSyncJob = await this.syncModel.listAll();
|
||||
for (let i = 0, len = allSyncJob.length; i < len; i++) {
|
||||
let syncItem = allSyncJob[i];
|
||||
if (syncItem.is_sync_open) {
|
||||
this.addSyncJob(syncItem.project_id, syncItem.sync_cron, syncItem.sync_json_url, syncItem.sync_mode, syncItem.uid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增同步任务.
|
||||
* @param {*} projectId 项目id
|
||||
* @param {*} cronExpression cron表达式,针对定时任务
|
||||
* @param {*} swaggerUrl 获取swagger的地址
|
||||
* @param {*} syncMode 同步模式
|
||||
* @param {*} uid 用户id
|
||||
*/
|
||||
async addSyncJob(projectId, cronExpression, swaggerUrl, syncMode, uid) {
|
||||
if(!swaggerUrl)return;
|
||||
let projectToken = await this.getProjectToken(projectId, uid);
|
||||
//立即执行一次
|
||||
this.syncInterface(projectId, swaggerUrl, syncMode, uid, projectToken);
|
||||
let scheduleItem = schedule.scheduleJob(cronExpression, async () => {
|
||||
this.syncInterface(projectId, swaggerUrl, syncMode, uid, projectToken);
|
||||
});
|
||||
|
||||
//判断是否已经存在这个任务
|
||||
let jobItem = jobMap.get(projectId);
|
||||
if (jobItem) {
|
||||
jobItem.cancel();
|
||||
}
|
||||
jobMap.set(projectId, scheduleItem);
|
||||
}
|
||||
|
||||
//同步接口
|
||||
async syncInterface(projectId, swaggerUrl, syncMode, uid, projectToken) {
|
||||
yapi.commons.log('定时器触发, syncJsonUrl:' + swaggerUrl + ",合并模式:" + syncMode);
|
||||
let oldPorjectData;
|
||||
try {
|
||||
oldPorjectData = await this.projectModel.get(projectId);
|
||||
} catch(e) {
|
||||
yapi.commons.log('获取项目:' + projectId + '失败');
|
||||
this.deleteSyncJob(projectId);
|
||||
//删除数据库定时任务
|
||||
await this.syncModel.delByProjectId(projectId);
|
||||
return;
|
||||
}
|
||||
//如果项目已经删除了
|
||||
if (!oldPorjectData) {
|
||||
yapi.commons.log('项目:' + projectId + '不存在');
|
||||
this.deleteSyncJob(projectId);
|
||||
//删除数据库定时任务
|
||||
await this.syncModel.delByProjectId(projectId);
|
||||
return;
|
||||
}
|
||||
let newSwaggerJsonData;
|
||||
try {
|
||||
newSwaggerJsonData = await this.getSwaggerContent(swaggerUrl)
|
||||
if (!newSwaggerJsonData || typeof newSwaggerJsonData !== 'object') {
|
||||
yapi.commons.log('数据格式出错,请检查')
|
||||
this.saveSyncLog(0, syncMode, "数据格式出错,请检查", uid, projectId);
|
||||
}
|
||||
newSwaggerJsonData = JSON.stringify(newSwaggerJsonData)
|
||||
} catch (e) {
|
||||
this.saveSyncLog(0, syncMode, "获取数据失败,请检查", uid, projectId);
|
||||
yapi.commons.log('获取数据失败' + e.message)
|
||||
}
|
||||
|
||||
let oldSyncJob = await this.syncModel.getByProjectId(projectId);
|
||||
|
||||
//更新之前判断本次swagger json数据是否跟上次的相同,相同则不更新
|
||||
if (newSwaggerJsonData && oldSyncJob.old_swagger_content && oldSyncJob.old_swagger_content == md5(newSwaggerJsonData)) {
|
||||
//记录日志
|
||||
// this.saveSyncLog(0, syncMode, "接口无更新", uid, projectId);
|
||||
oldSyncJob.last_sync_time = yapi.commons.time();
|
||||
await this.syncModel.upById(oldSyncJob._id, oldSyncJob);
|
||||
return;
|
||||
}
|
||||
|
||||
let _params = {
|
||||
type: 'swagger',
|
||||
json: newSwaggerJsonData,
|
||||
project_id: projectId,
|
||||
merge: syncMode,
|
||||
token: projectToken
|
||||
}
|
||||
let requestObj = {
|
||||
params: _params
|
||||
};
|
||||
await this.openController.importData(requestObj);
|
||||
|
||||
//同步成功就更新同步表的数据
|
||||
if (requestObj.body.errcode == 0) {
|
||||
//修改sync_model的属性
|
||||
oldSyncJob.last_sync_time = yapi.commons.time();
|
||||
oldSyncJob.old_swagger_content = md5(newSwaggerJsonData);
|
||||
await this.syncModel.upById(oldSyncJob._id, oldSyncJob);
|
||||
}
|
||||
//记录日志
|
||||
this.saveSyncLog(requestObj.body.errcode, syncMode, requestObj.body.errmsg, uid, projectId);
|
||||
}
|
||||
|
||||
getSyncJob(projectId) {
|
||||
return jobMap.get(projectId);
|
||||
}
|
||||
|
||||
deleteSyncJob(projectId) {
|
||||
let jobItem = jobMap.get(projectId);
|
||||
if (jobItem) {
|
||||
jobItem.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 记录同步日志
|
||||
* @param {*} errcode
|
||||
* @param {*} syncMode
|
||||
* @param {*} moremsg
|
||||
* @param {*} uid
|
||||
* @param {*} projectId
|
||||
*/
|
||||
saveSyncLog(errcode, syncMode, moremsg, uid, projectId) {
|
||||
yapi.commons.saveLog({
|
||||
content: '自动同步接口状态:' + (errcode == 0 ? '成功,' : '失败,') + "合并模式:" + this.getSyncModeName(syncMode) + ",更多信息:" + moremsg,
|
||||
type: 'project',
|
||||
uid: uid,
|
||||
username: "自动同步用户",
|
||||
typeid: projectId
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取项目token,因为导入接口需要鉴权.
|
||||
* @param {*} project_id 项目id
|
||||
* @param {*} uid 用户id
|
||||
*/
|
||||
async getProjectToken(project_id, uid) {
|
||||
try {
|
||||
let data = await this.tokenModel.get(project_id);
|
||||
let token;
|
||||
if (!data) {
|
||||
let passsalt = yapi.commons.randStr();
|
||||
token = sha('sha1')
|
||||
.update(passsalt)
|
||||
.digest('hex')
|
||||
.substr(0, 20);
|
||||
|
||||
await this.tokenModel.save({ project_id, token });
|
||||
} else {
|
||||
token = data.token;
|
||||
}
|
||||
|
||||
token = getToken(token, uid);
|
||||
|
||||
return token;
|
||||
} catch (err) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
getUid(uid) {
|
||||
return parseInt(uid, 10);
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换合并模式的值为中文.
|
||||
* @param {*} syncMode 合并模式
|
||||
*/
|
||||
getSyncModeName(syncMode) {
|
||||
if (syncMode == 'good') {
|
||||
return '智能合并';
|
||||
} else if (syncMode == 'normal') {
|
||||
return '普通模式';
|
||||
} else if (syncMode == 'merge') {
|
||||
return '完全覆盖';
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
async getSwaggerContent(swaggerUrl) {
|
||||
const axios = require('axios')
|
||||
try {
|
||||
let response = await axios.get(swaggerUrl);
|
||||
if (response.status > 400) {
|
||||
throw new Error(`http status "${response.status}"` + '获取数据失败,请确认 swaggerUrl 是否正确')
|
||||
}
|
||||
return response.data;
|
||||
} catch (e) {
|
||||
let response = e.response || {status: e.message || 'error'};
|
||||
throw new Error(`http status "${response.status}"` + '获取数据失败,请确认 swaggerUrl 是否正确')
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
module.exports = syncUtils;
|
||||
23
exts/yapi-plugin-swagger-auto-sync/server.js
Normal file
23
exts/yapi-plugin-swagger-auto-sync/server.js
Normal file
@@ -0,0 +1,23 @@
|
||||
const controller = require('./controller/syncController.js');
|
||||
const yapi =require('yapi.js');
|
||||
const interfaceSyncUtils = require('./interfaceSyncUtils.js');
|
||||
|
||||
module.exports = function () {
|
||||
yapi.getInst(interfaceSyncUtils);
|
||||
|
||||
this.bindHook('add_router', function (addRouter) {
|
||||
addRouter({
|
||||
controller: controller,
|
||||
method: 'get',
|
||||
path: 'autoSync/get',
|
||||
action: 'getSync'
|
||||
});
|
||||
addRouter({
|
||||
controller: controller,
|
||||
method: 'post',
|
||||
path: 'autoSync/save',
|
||||
action: 'upSync'
|
||||
});
|
||||
});
|
||||
|
||||
};
|
||||
@@ -0,0 +1,239 @@
|
||||
import React, { Component } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import PropTypes from 'prop-types';
|
||||
import { formatTime } from 'client/common.js';
|
||||
import { Form, Switch, Button, Icon, Tooltip, message, Input, Select } from 'antd';
|
||||
import {handleSwaggerUrlData} from 'client/reducer/modules/project';
|
||||
const FormItem = Form.Item;
|
||||
const Option = Select.Option;
|
||||
import axios from 'axios';
|
||||
|
||||
// layout
|
||||
const formItemLayout = {
|
||||
labelCol: {
|
||||
lg: { span: 5 },
|
||||
xs: { span: 24 },
|
||||
sm: { span: 10 }
|
||||
},
|
||||
wrapperCol: {
|
||||
lg: { span: 16 },
|
||||
xs: { span: 24 },
|
||||
sm: { span: 12 }
|
||||
},
|
||||
className: 'form-item'
|
||||
};
|
||||
const tailFormItemLayout = {
|
||||
wrapperCol: {
|
||||
sm: {
|
||||
span: 16,
|
||||
offset: 11
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@connect(
|
||||
state => {
|
||||
return {
|
||||
projectMsg: state.project.currProject
|
||||
};
|
||||
},
|
||||
{
|
||||
handleSwaggerUrlData
|
||||
}
|
||||
)
|
||||
@Form.create()
|
||||
export default class ProjectInterfaceSync extends Component {
|
||||
static propTypes = {
|
||||
form: PropTypes.object,
|
||||
match: PropTypes.object,
|
||||
projectId: PropTypes.number,
|
||||
projectMsg: PropTypes.object,
|
||||
handleSwaggerUrlData: PropTypes.func
|
||||
};
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
sync_data: { is_sync_open: false }
|
||||
};
|
||||
}
|
||||
|
||||
handleSubmit = async () => {
|
||||
const { form, projectId } = this.props;
|
||||
let params = {
|
||||
project_id: projectId,
|
||||
is_sync_open: this.state.sync_data.is_sync_open,
|
||||
uid: this.props.projectMsg.uid
|
||||
};
|
||||
if (this.state.sync_data._id) {
|
||||
params.id = this.state.sync_data._id;
|
||||
}
|
||||
form.validateFields(async (err, values) => {
|
||||
if (!err) {
|
||||
let assignValue = Object.assign(params, values);
|
||||
await axios.post('/api/plugin/autoSync/save', assignValue).then(res => {
|
||||
if (res.data.errcode === 0) {
|
||||
message.success('保存成功');
|
||||
} else {
|
||||
message.error(res.data.errmsg);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
validSwaggerUrl = async (rule, value, callback) => {
|
||||
if(!value)return;
|
||||
try{
|
||||
await this.props.handleSwaggerUrlData(value);
|
||||
} catch(e) {
|
||||
callback('swagger地址不正确');
|
||||
}
|
||||
callback()
|
||||
}
|
||||
|
||||
UNSAFE_componentWillMount() {
|
||||
//查询同步任务
|
||||
this.setState({
|
||||
sync_data: {}
|
||||
});
|
||||
//默认每份钟同步一次,取一个随机数
|
||||
this.setState({
|
||||
random_corn: '*/2 * * * *'
|
||||
});
|
||||
this.getSyncData();
|
||||
}
|
||||
|
||||
async getSyncData() {
|
||||
let projectId = this.props.projectMsg._id;
|
||||
let result = await axios.get('/api/plugin/autoSync/get?project_id=' + projectId);
|
||||
if (result.data.errcode === 0) {
|
||||
if (result.data.data) {
|
||||
this.setState({
|
||||
sync_data: result.data.data
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 是否开启
|
||||
onChange = v => {
|
||||
let sync_data = this.state.sync_data;
|
||||
sync_data.is_sync_open = v;
|
||||
this.setState({
|
||||
sync_data: sync_data
|
||||
});
|
||||
};
|
||||
|
||||
sync_cronCheck(rule, value, callback){
|
||||
if(!value)return;
|
||||
value = value.trim();
|
||||
if(value.split(/ +/).length > 5){
|
||||
callback('不支持秒级别的设置,建议使用 "*/10 * * * *" ,每隔10分钟更新')
|
||||
}
|
||||
callback()
|
||||
}
|
||||
|
||||
render() {
|
||||
const { getFieldDecorator } = this.props.form;
|
||||
return (
|
||||
<div className="m-panel">
|
||||
<Form>
|
||||
<FormItem
|
||||
label="是否开启自动同步"
|
||||
{...formItemLayout}
|
||||
>
|
||||
<Switch
|
||||
checked={this.state.sync_data.is_sync_open}
|
||||
onChange={this.onChange}
|
||||
checkedChildren="开"
|
||||
unCheckedChildren="关"
|
||||
/>
|
||||
{this.state.sync_data.last_sync_time != null ? (<div>上次更新时间:<span className="logtime">{formatTime(this.state.sync_data.last_sync_time)}</span></div>) : null}
|
||||
</FormItem>
|
||||
|
||||
<div>
|
||||
<FormItem {...formItemLayout} label={
|
||||
<span className="label">
|
||||
数据同步
|
||||
<Tooltip
|
||||
title={
|
||||
<div>
|
||||
<h3 style={{ color: 'white' }}>普通模式</h3>
|
||||
<p>不导入已存在的接口</p>
|
||||
<br />
|
||||
<h3 style={{ color: 'white' }}>智能合并</h3>
|
||||
<p>
|
||||
已存在的接口,将合并返回数据的 response,适用于导入了 swagger
|
||||
数据,保留对数据结构的改动
|
||||
</p>
|
||||
<br />
|
||||
<h3 style={{ color: 'white' }}>完全覆盖</h3>
|
||||
<p>不保留旧数据,完全使用新数据,适用于接口定义完全交给后端定义</p>
|
||||
</div>
|
||||
}
|
||||
>
|
||||
<Icon type="question-circle-o" />
|
||||
</Tooltip>{' '}
|
||||
</span>
|
||||
}>
|
||||
{getFieldDecorator('sync_mode', {
|
||||
initialValue: this.state.sync_data.sync_mode,
|
||||
rules: [
|
||||
{
|
||||
required: true,
|
||||
message: '请选择同步方式!'
|
||||
}
|
||||
]
|
||||
})(
|
||||
|
||||
<Select>
|
||||
<Option value="normal">普通模式</Option>
|
||||
<Option value="good">智能合并</Option>
|
||||
<Option value="merge">完全覆盖</Option>
|
||||
</Select>
|
||||
)}
|
||||
</FormItem>
|
||||
|
||||
<FormItem {...formItemLayout} label="项目的swagger json地址">
|
||||
{getFieldDecorator('sync_json_url', {
|
||||
rules: [
|
||||
{
|
||||
required: true,
|
||||
message: '输入swagger地址'
|
||||
},
|
||||
{
|
||||
validator: this.validSwaggerUrl
|
||||
}
|
||||
],
|
||||
validateTrigger: 'onBlur',
|
||||
initialValue: this.state.sync_data.sync_json_url
|
||||
})(<Input />)}
|
||||
</FormItem>
|
||||
|
||||
<FormItem {...formItemLayout} label={<span>类cron风格表达式(默认10分钟更新一次) <a href="https://blog.csdn.net/shouldnotappearcalm/article/details/89469047">参考</a></span>}>
|
||||
{getFieldDecorator('sync_cron', {
|
||||
rules: [
|
||||
{
|
||||
required: true,
|
||||
message: '输入node-schedule的类cron表达式!'
|
||||
},
|
||||
{
|
||||
validator: this.sync_cronCheck
|
||||
}
|
||||
],
|
||||
initialValue: this.state.sync_data.sync_cron ? this.state.sync_data.sync_cron : this.state.random_corn
|
||||
})(<Input />)}
|
||||
</FormItem>
|
||||
</div>
|
||||
<FormItem {...tailFormItemLayout}>
|
||||
<Button type="primary" htmlType="submit" icon="save" size="large" onClick={this.handleSubmit}>
|
||||
保存
|
||||
</Button>
|
||||
</FormItem>
|
||||
</Form>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
90
exts/yapi-plugin-swagger-auto-sync/syncModel.js
Normal file
90
exts/yapi-plugin-swagger-auto-sync/syncModel.js
Normal file
@@ -0,0 +1,90 @@
|
||||
const yapi = require('yapi.js');
|
||||
const baseModel = require('models/base.js');
|
||||
const mongoose = require('mongoose');
|
||||
|
||||
class syncModel extends baseModel {
|
||||
getName() {
|
||||
return 'interface_auto_sync';
|
||||
}
|
||||
|
||||
getSchema() {
|
||||
return {
|
||||
uid: { type: Number},
|
||||
project_id: { type: Number, required: true },
|
||||
//是否开启自动同步
|
||||
is_sync_open: { type: Boolean, default: false },
|
||||
//自动同步定时任务的cron表达式
|
||||
sync_cron: String,
|
||||
//自动同步获取json的url
|
||||
sync_json_url: String,
|
||||
//接口合并模式 good,nomarl等等 意思也就是智能合并,完全覆盖等
|
||||
sync_mode: String,
|
||||
//上次成功同步接口时间,
|
||||
last_sync_time: Number,
|
||||
//上次同步的swagger 文档内容
|
||||
old_swagger_content: String,
|
||||
add_time: Number,
|
||||
up_time: Number,
|
||||
};
|
||||
}
|
||||
|
||||
getByProjectId(id) {
|
||||
return this.model.findOne({
|
||||
project_id: id
|
||||
})
|
||||
}
|
||||
|
||||
delByProjectId(project_id){
|
||||
return this.model.remove({
|
||||
project_id: project_id
|
||||
})
|
||||
}
|
||||
|
||||
save(data) {
|
||||
data.up_time = yapi.commons.time();
|
||||
let m = new this.model(data);
|
||||
return m.save();
|
||||
}
|
||||
|
||||
listAll() {
|
||||
return this.model
|
||||
.find({})
|
||||
.select(
|
||||
'_id uid project_id add_time up_time is_sync_open sync_cron sync_json_url sync_mode old_swagger_content last_sync_time'
|
||||
)
|
||||
.sort({ _id: -1 })
|
||||
.exec();
|
||||
}
|
||||
|
||||
up(data) {
|
||||
let id = data.id;
|
||||
delete data.id;
|
||||
data.up_time = yapi.commons.time();
|
||||
return this.model.update({
|
||||
_id: id
|
||||
}, data)
|
||||
}
|
||||
|
||||
upById(id, data) {
|
||||
delete data.id;
|
||||
data.up_time = yapi.commons.time();
|
||||
return this.model.update({
|
||||
_id: id
|
||||
}, data)
|
||||
}
|
||||
|
||||
del(id){
|
||||
return this.model.remove({
|
||||
_id: id
|
||||
})
|
||||
}
|
||||
|
||||
delByProjectId(projectId){
|
||||
return this.model.remove({
|
||||
project_id: projectId
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
module.exports = syncModel;
|
||||
Reference in New Issue
Block a user