yapi/server/controllers/project.js

451 lines
15 KiB
JavaScript
Raw Normal View History

2017-07-14 17:00:30 +08:00
import projectModel from '../models/project.js'
import yapi from '../yapi.js'
2017-07-06 19:21:54 +08:00
import baseController from './base.js'
2017-07-10 20:02:44 +08:00
import interfaceModel from '../models/interface.js'
import groupModel from '../models/group'
import commons from '../utils/commons.js'
import userModel from '../models/user.js'
2017-07-06 19:21:54 +08:00
class projectController extends baseController {
constructor(ctx){
super(ctx)
this.Model = yapi.getInst(projectModel);
this.groupModel = yapi.getInst(groupModel);
2017-07-06 19:21:54 +08:00
}
2017-07-20 16:14:20 +08:00
handleBasepath(basepath){
if(!basepath) return false;
if(basepath[0] !== '/') basepath = '/' + basepath;
if(basepath[basepath.length -1] === '/') basepath = basepath.substr(0, basepath.length -1)
if(!this.verifyPath(basepath)){
return false;
}
return basepath;
}
verifyPath(path){
if(/^[a-zA-Z0-9\-\/_:]+$/.test(path)){
2017-07-20 16:14:20 +08:00
return true;
}else{
return false;
}
}
verifyDomain(domain){
if(!domain) return false;
if(/^[a-zA-Z0-9\-_\.]+[a-zA-Z]{2,6}$/.test(domain)){
return true;
}
return false;
}
2017-07-10 11:56:53 +08:00
/**
* 添加项目分组
* @interface /project/add
* @method POST
* @category project
* @foldnumber 10
* @param {String} name 项目名称不能为空
* @param {String} basepath 项目基本路径不能为空
* @param {String} prd_host 项目线上域名不能为空可通过配置的域名访问到mock数据
* @param {String} protocol 线上域名协议不能为空
2017-07-10 11:56:53 +08:00
* @param {Number} group_id 项目分组id不能为空
* @param {String} [desc] 项目描述
* @returns {Object}
* @example ./api/project/add.json
*/
async add(ctx) {
let params = ctx.request.body;
2017-07-06 19:21:54 +08:00
if(!params.group_id){
return ctx.body = yapi.commons.resReturn(null, 400, '项目分组id不能为空');
}
if(!params.name){
return ctx.body = yapi.commons.resReturn(null, 400, '项目名不能为空');
}
2017-07-06 19:21:54 +08:00
let checkRepeat = await this.Model.checkNameRepeat(params.name);
if(checkRepeat > 0){
2017-07-06 19:21:54 +08:00
return ctx.body = yapi.commons.resReturn(null, 401, '已存在的项目名');
}
if(!params.basepath){
return ctx.body = yapi.commons.resReturn(null, 400, '项目basepath不能为空');
}
2017-07-06 19:21:54 +08:00
if(!params.prd_host){
return ctx.body = yapi.commons.resReturn(null, 400, '项目domain不能为空');
}
if((params.basepath = this.handleBasepath(params.basepath)) === false){
2017-07-20 16:14:20 +08:00
return ctx.body = yapi.commons.resReturn(null, 401, 'basepath格式有误')
}
if(!this.verifyDomain(params.prd_host)){
return ctx.body = yapi.commons.resReturn(null, 401, '线上域名格式有误')
}
2017-07-06 19:21:54 +08:00
let checkRepeatDomain = await this.Model.checkDomainRepeat(params.prd_host, params.basepath);
if(checkRepeatDomain > 0){
return ctx.body = yapi.commons.resReturn(null, 401, '已存在domain和basepath');
}
let data = {
2017-07-06 19:21:54 +08:00
name: params.name,
desc: params.desc,
prd_host: params.prd_host,
basepath: params.basepath,
protocol: params.protocol || 'http',
2017-07-06 19:21:54 +08:00
members: [this.getUid()],
uid: this.getUid(),
group_id: params.group_id,
add_time: yapi.commons.time(),
up_time: yapi.commons.time()
}
2017-07-06 19:21:54 +08:00
try{
2017-07-06 19:21:54 +08:00
let result = await this.Model.save(data);
ctx.body = yapi.commons.resReturn(result);
}catch(e){
ctx.body = yapi.commons.resReturn(null, 402, e.message)
}
2017-07-06 19:21:54 +08:00
}
2017-07-10 11:56:53 +08:00
/**
* 添加项目
2017-07-10 11:56:53 +08:00
* @interface /project/add_member
* @method POST
* @category project
* @foldnumber 10
* @param {Number} id 项目id不能为空
* @param {String} member_uid 项目成员uid,不能为空
2017-07-10 11:56:53 +08:00
* @returns {Object}
* @example ./api/project/add_member.json
*/
2017-07-06 19:21:54 +08:00
async addMember(ctx){
let params = ctx.request.body;
if(!params.member_uid){
return ctx.body = yapi.commons.resReturn(null, 400, '项目成员uid不能为空');
}
if(!params.id){
return ctx.body = yapi.commons.resReturn(null, 400, '项目id不能为空');
}
var check = await this.Model.checkMemberRepeat(params.id, params.member_uid);
if(check > 0){
return ctx.body = yapi.commons.resReturn(null, 400, '项目成员已存在');
}
try{
let result = await this.Model.addMember(params.id, params.member_uid);
ctx.body = yapi.commons.resReturn(result);
}catch(e){
ctx.body = yapi.commons.resReturn(null, 402, e.message)
}
}
2017-07-10 11:56:53 +08:00
/**
* 添加项目
2017-07-10 11:56:53 +08:00
* @interface /project/del_member
* @method POST
* @category project
* @foldnumber 10
* @param {Number} id 项目id不能为空
* @param {member_uid} uid 项目成员uid,不能为空
* @returns {Object}
* @example ./api/project/del_member.json
*/
2017-07-06 19:21:54 +08:00
async delMember(ctx){
let params = ctx.request.body;
if(!params.member_uid){
return ctx.body = yapi.commons.resReturn(null, 400, '项目成员uid不能为空');
}
if(!params.id){
return ctx.body = yapi.commons.resReturn(null, 400, '项目id不能为空');
}
var check = await this.Model.checkMemberRepeat(params.id, params.member_uid);
if(check === 0){
return ctx.body = yapi.commons.resReturn(null, 400, '项目成员不存在');
}
try{
let result = await this.Model.delMember(params.id, params.member_uid);
ctx.body = yapi.commons.resReturn(result);
}catch(e){
ctx.body = yapi.commons.resReturn(null, 402, e.message)
}
}
/**
* 获取项目成员列表
2017-07-18 15:13:47 +08:00
* @interface /project/get_member_list
* @method GET
* @category project
* @foldnumber 10
* @param {Number} id 项目id不能为空
* @return {Object}
* @example ./api/project/get_member_list.json
*/
async getMemberList(ctx) {
let params = ctx.request.query;
if(!params.id) {
return ctx.body = yapi.commons.resReturn(null, 400, '项目id不能为空');
}
try {
let project = await this.Model.get(params.id);
let userInst = yapi.getInst(userModel);
let result = await userInst.findByUids(project.members);
ctx.body = yapi.commons.resReturn(result);
} catch(e) {
ctx.body = yapi.commons.resReturn(null, 402, e.message);
}
}
2017-07-10 11:56:53 +08:00
/**
* 添加项目
* @interface /project/get
* @method GET
* @category project
* @foldnumber 10
* @param {Number} id 项目id不能为空
* @returns {Object}
* @example ./api/project/get.json
*/
2017-07-06 19:21:54 +08:00
async get(ctx){
let params = ctx.request.query;
if(!params.id){
return ctx.body = yapi.commons.resReturn(null, 400, '项目id不能为空');
}
try{
let result = await this.Model.get(params.id);
ctx.body = yapi.commons.resReturn(result);
}catch(e){
ctx.body = yapi.commons.resReturn(null, 402, e.message)
}
}
2017-07-10 11:56:53 +08:00
/**
* 获取项目列表
* @interface /project/list
* @method GET
* @category project
* @foldnumber 10
* @param {Number} group_id 项目group_id不能为空
2017-07-18 16:37:28 +08:00
* @param {Number} [page] 分页页码
* @param {Number} [limit] 每页数据条目默认为10
2017-07-10 11:56:53 +08:00
* @returns {Object}
* @example ./api/project/list.json
*/
async list(ctx) {
2017-07-18 15:13:47 +08:00
let group_id = ctx.request.query.group_id,
2017-07-18 16:37:28 +08:00
page = ctx.request.query.page || 1,
limit = ctx.request.query.limit || 10;
2017-07-18 15:13:47 +08:00
2017-07-06 20:53:26 +08:00
if(!group_id){
2017-07-06 19:21:54 +08:00
return ctx.body = yapi.commons.resReturn(null, 400, '项目分组id不能为空');
}
2017-07-18 15:13:47 +08:00
try{
2017-07-18 16:37:28 +08:00
let result = await this.Model.listWithPaging(group_id, page, limit);
let count = await this.Model.listCount(group_id);
let uids = [];
result.forEach( (item)=> {
if(uids.indexOf(item.uid) !== -1){
uids.push(item.uid)
}
} )
let _users = {}, users = await yapi.getInst(userModel).findByUids(uids);
users.forEach((item)=> {
_users[item._id] = item;
} )
2017-07-18 15:13:47 +08:00
ctx.body = yapi.commons.resReturn({
total: Math.ceil(count / limit),
list: result,
userinfo: _users
2017-07-18 15:13:47 +08:00
})
}catch(err){
ctx.body = yapi.commons.resReturn(null, 402, e.message)
}
2017-07-06 19:21:54 +08:00
}
2017-07-10 11:56:53 +08:00
/**
* 删除项目
* @interface /project/del
* @method POST
* @category project
* @foldnumber 10
* @param {Number} id 项目id不能为空
* @returns {Object}
* @example ./api/project/del.json
*/
async del(ctx){
try{
let id = ctx.request.body.id;
2017-07-10 11:56:53 +08:00
if(!id){
return ctx.body = yapi.commons.resReturn(null, 400, '项目id不能为空');
}
2017-07-10 20:02:44 +08:00
let interfaceInst = yapi.getInst(interfaceModel);
let count = await interfaceInst.countByProjectId(id);
if(count > 0){
return ctx.body = yapi.commons.resReturn(null, 400, '请先删除该项目下所有接口');
}
2017-07-10 11:56:53 +08:00
if(await this.jungeProjectAuth(id) !== true){
2017-07-06 19:21:54 +08:00
return ctx.body = yapi.commons.resReturn(null, 405, '没有权限');
}
let result = await this.Model.del(id);
2017-07-10 20:02:44 +08:00
ctx.body = yapi.commons.resReturn(result);
}catch(err){
ctx.body = yapi.commons.resReturn(null, 402, e.message)
}
2017-07-06 19:21:54 +08:00
}
2017-07-10 11:56:53 +08:00
/**
* 编辑项目
* @interface /project/up
2017-07-18 15:48:05 +08:00
* @method POST
2017-07-10 11:56:53 +08:00
* @category project
* @foldnumber 10
* @param {Number} id 项目id不能为空
* @param {String} name 项目名称不能为空
* @param {String} basepath 项目基本路径不能为空
* @param {String} prd_host 项目线上域名不能为空可通过配置的域名访问到mock数据
* @param {String} [desc] 项目描述
2017-07-10 20:02:44 +08:00
* @param {Array} [env] 项目环境配置
* @param {String} [env[].name] 环境名称
2017-07-21 11:46:44 +08:00
* @param {String} [env[].domain] 环境域名
2017-07-10 11:56:53 +08:00
* @returns {Object}
* @example ./api/project/up.json
*/
async up(ctx){
2017-07-06 19:21:54 +08:00
try{
let id = ctx.request.body.id;
2017-07-06 20:53:26 +08:00
let params = ctx.request.body;
if(!id){
return ctx.body = yapi.commons.resReturn(null, 405, '项目id不能为空');
}
2017-07-06 20:53:26 +08:00
2017-07-10 11:56:53 +08:00
if(await this.jungeMemberAuth(id, this.getUid()) !== true){
2017-07-06 19:21:54 +08:00
return ctx.body = yapi.commons.resReturn(null, 405, '没有权限');
}
let projectData = await this.Model.get(id);
2017-07-20 16:14:20 +08:00
if(params.basepath = (this.handleBasepath(params.basepath)) === false){
return ctx.body = yapi.commons.resReturn(null, 401, 'basepath格式有误')
}
if(!this.verifyDomain(params.prd_host)){
return ctx.body = yapi.commons.resReturn(null, 401, '线上域名格式有误')
}
if(projectData.name === params.name){
delete params.name;
}
if(projectData.basepath === params.basepath && projectData.prd_host === params.prd_host){
delete params.basepath
delete params.prd_host
}
2017-07-06 20:53:26 +08:00
2017-07-10 11:56:53 +08:00
if(params.name){
let checkRepeat = await this.Model.checkNameRepeat(params.name);
if(checkRepeat > 0){
return ctx.body = yapi.commons.resReturn(null, 401, '已存在的项目名');
}
2017-07-06 20:53:26 +08:00
}
2017-07-10 11:56:53 +08:00
if(params.basepath && params.prd_host){
let checkRepeatDomain = await this.Model.checkDomainRepeat(params.prd_host, params.basepath);
if(checkRepeatDomain > 0){
return ctx.body = yapi.commons.resReturn(null, 401, '已存在domain和basepath');
}
2017-07-06 20:53:26 +08:00
}
2017-07-10 11:56:53 +08:00
let data= {
uid: this.getUid(),
up_time: yapi.commons.time()
2017-07-06 20:53:26 +08:00
}
2017-07-10 11:56:53 +08:00
if(params.name) data.name = params.name;
if(params.desc) data.desc = params.desc;
if(params.prd_host && params.basepath){
data.prd_host = params.prd_host;
data.basepath = params.basepath;
2017-07-06 20:53:26 +08:00
}
if(params.protocol) data.protocol = params.protocol;
2017-07-10 11:56:53 +08:00
if(params.env) data.env = params.env;
2017-07-06 20:53:26 +08:00
2017-07-06 19:21:54 +08:00
let result = await this.Model.up(id, data);
ctx.body = yapi.commons.resReturn(result)
2017-07-10 11:56:53 +08:00
}catch(e){
ctx.body = yapi.commons.resReturn(null, 402, e.message)
}
}
/**
* 模糊搜索项目名称或者组名称
* @interface /project/search
* @method GET
* @category project
* @foldnumber 10
* @param {String} q
* @return {Object}
2017-07-14 17:00:30 +08:00
* @example ./api/project/search.json
*/
async search(ctx) {
const { q } = ctx.request.query;
if (!q) {
return ctx.body = yapi.commons.resReturn(void 0, 400, 'No keyword.')
}
if (!yapi.commons.validateSearchKeyword(q)) {
return ctx.body = yapi.commons.resReturn(void 0, 400, 'Bad query.')
}
let projectList = await this.Model.search(q);
let groupList = await this.groupModel.search(q);
let projectRules = [
'_id',
'name',
'basepath',
'uid',
'env',
'members',
{ key: 'group_id', alias: 'groupId' },
{ key: 'up_time', alias: 'upTime' },
{ key: 'prd_host', alias: 'prdHost' },
{ key: 'add_time', alias: 'addTime' }
];
let groupRules = [
'_id',
'uid',
{ key: 'group_name', alias: 'groupName'},
{ key: 'group_desc', alias: 'groupDesc' },
{ key: 'add_time', alias: 'addTime' },
{ key: 'up_time', alias: 'upTime' }
];
projectList = commons.filterRes(projectList, projectRules);
groupList = commons.filterRes(groupList, groupRules);
let queryList = {
project: projectList,
group: groupList
};
2017-07-19 13:58:12 +08:00
return ctx.body = yapi.commons.resReturn(queryList, 0, 'ok')
}
}
2017-07-06 19:21:54 +08:00
module.exports = projectController;