mirror of
https://github.com/YMFE/yapi.git
synced 2024-12-09 05:00:30 +08:00
1030 lines
30 KiB
JavaScript
Executable File
1030 lines
30 KiB
JavaScript
Executable File
const projectModel = require('../models/project.js');
|
||
const yapi = require('../yapi.js');
|
||
const _ = require('underscore');
|
||
const baseController = require('./base.js');
|
||
const interfaceModel = require('../models/interface.js');
|
||
const interfaceColModel = require('../models/interfaceCol.js');
|
||
const interfaceCaseModel = require('../models/interfaceCase.js');
|
||
const interfaceCatModel = require('../models/interfaceCat.js');
|
||
const groupModel = require('../models/group');
|
||
const commons = require('../utils/commons.js');
|
||
const userModel = require('../models/user.js');
|
||
const logModel = require('../models/log.js');
|
||
const followModel = require('../models/follow.js');
|
||
const tokenModel = require('../models/token.js');
|
||
|
||
const sha = require('sha.js');
|
||
|
||
class projectController extends baseController {
|
||
constructor(ctx) {
|
||
super(ctx);
|
||
this.Model = yapi.getInst(projectModel);
|
||
this.groupModel = yapi.getInst(groupModel);
|
||
this.logModel = yapi.getInst(logModel);
|
||
this.followModel = yapi.getInst(followModel);
|
||
this.tokenModel = yapi.getInst(tokenModel);
|
||
this.interfaceModel = yapi.getInst(interfaceModel);
|
||
|
||
const id = 'number';
|
||
const member_uid = ['number'];
|
||
const name = {
|
||
type: 'string',
|
||
minLength: 1
|
||
};
|
||
const role = {
|
||
type: 'string',
|
||
enum: ['owner', 'dev', 'guest']
|
||
};
|
||
const basepath = {
|
||
type: 'string',
|
||
default: ''
|
||
};
|
||
const group_id = 'number';
|
||
const group_name = 'string';
|
||
const project_type = {
|
||
type: 'string',
|
||
enum: ['private', 'public'],
|
||
default: 'private'
|
||
};
|
||
const desc = 'string';
|
||
const icon = 'string';
|
||
const color = 'string';
|
||
const env = 'array';
|
||
|
||
const cat = 'array';
|
||
this.schemaMap = {
|
||
add: {
|
||
'*name': name,
|
||
basepath: basepath,
|
||
'*group_id': group_id,
|
||
group_name,
|
||
desc: desc,
|
||
color,
|
||
icon,
|
||
project_type
|
||
},
|
||
copy: {
|
||
'*name': name,
|
||
preName: name,
|
||
basepath: basepath,
|
||
'*group_id': group_id,
|
||
_id: id,
|
||
cat,
|
||
pre_script: desc,
|
||
after_script: desc,
|
||
env,
|
||
group_name,
|
||
desc,
|
||
color,
|
||
icon,
|
||
project_type
|
||
},
|
||
addMember: {
|
||
'*id': id,
|
||
'*member_uids': member_uid,
|
||
role: role
|
||
},
|
||
delMember: {
|
||
'*id': id,
|
||
'*member_uid': id
|
||
},
|
||
getMemberList: {
|
||
'*id': id
|
||
},
|
||
get: {
|
||
'*id': id
|
||
},
|
||
list: {
|
||
'*group_id': group_id
|
||
},
|
||
del: {
|
||
'*id': id
|
||
},
|
||
changeMemberRole: {
|
||
'*id': id,
|
||
'*member_uid': id,
|
||
role
|
||
},
|
||
token: {
|
||
'*project_id': id
|
||
},
|
||
updateToken: {
|
||
'*project_id': id
|
||
}
|
||
};
|
||
}
|
||
|
||
handleBasepath(basepath) {
|
||
if (!basepath) return '';
|
||
if (basepath === '/') return '';
|
||
if (basepath[0] !== '/') basepath = '/' + basepath;
|
||
if (basepath[basepath.length - 1] === '/') basepath = basepath.substr(0, basepath.length - 1);
|
||
if (!/^\/[a-zA-Z0-9\-\/_]+$/.test(basepath)) {
|
||
return false;
|
||
}
|
||
return basepath;
|
||
}
|
||
|
||
verifyDomain(domain) {
|
||
if (!domain) return false;
|
||
if (/^[a-zA-Z0-9\-_\.]+?\.[a-zA-Z0-9\-_\.]*?[a-zA-Z]{2,6}$/.test(domain)) {
|
||
return true;
|
||
}
|
||
return false;
|
||
}
|
||
|
||
/**
|
||
* 判断分组名称是否重复
|
||
* @interface /project/check_project_name
|
||
* @method get
|
||
*/
|
||
|
||
async checkProjectName(ctx) {
|
||
try {
|
||
let name = ctx.request.query.name;
|
||
let group_id = ctx.request.query.group_id;
|
||
|
||
if (!name) {
|
||
return (ctx.body = yapi.commons.resReturn(null, 401, '项目名不能为空'));
|
||
}
|
||
let checkRepeat = await this.Model.checkNameRepeat(name, group_id);
|
||
|
||
if (checkRepeat > 0) {
|
||
return (ctx.body = yapi.commons.resReturn(null, 401, '已存在的项目名'));
|
||
}
|
||
|
||
ctx.body = yapi.commons.resReturn({});
|
||
} catch (err) {
|
||
ctx.body = yapi.commons.resReturn(null, 402, err.message);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 添加项目分组
|
||
* @interface /project/add
|
||
* @method POST
|
||
* @category project
|
||
* @foldnumber 10
|
||
* @param {String} name 项目名称,不能为空
|
||
* @param {String} basepath 项目基本路径,不能为空
|
||
* @param {Number} group_id 项目分组id,不能为空
|
||
* @param {Number} group_name 项目分组名称,不能为空
|
||
* @param {String} project_type private public
|
||
* @param {String} [desc] 项目描述
|
||
* @returns {Object}
|
||
* @example ./api/project/add.json
|
||
*/
|
||
async add(ctx) {
|
||
let params = ctx.params;
|
||
|
||
if ((await this.checkAuth(params.group_id, 'group', 'edit')) !== true) {
|
||
return (ctx.body = yapi.commons.resReturn(null, 405, '没有权限'));
|
||
}
|
||
|
||
let checkRepeat = await this.Model.checkNameRepeat(params.name, params.group_id);
|
||
|
||
if (checkRepeat > 0) {
|
||
return (ctx.body = yapi.commons.resReturn(null, 401, '已存在的项目名'));
|
||
}
|
||
|
||
params.basepath = params.basepath || '';
|
||
|
||
if ((params.basepath = this.handleBasepath(params.basepath)) === false) {
|
||
return (ctx.body = yapi.commons.resReturn(null, 401, 'basepath格式有误'));
|
||
}
|
||
|
||
let data = {
|
||
name: params.name,
|
||
desc: params.desc,
|
||
basepath: params.basepath,
|
||
members: [],
|
||
project_type: params.project_type || 'private',
|
||
uid: this.getUid(),
|
||
group_id: params.group_id,
|
||
group_name: params.group_name,
|
||
icon: params.icon,
|
||
color: params.color,
|
||
add_time: yapi.commons.time(),
|
||
up_time: yapi.commons.time(),
|
||
env: [{ name: 'local', domain: 'http://127.0.0.1' }]
|
||
};
|
||
|
||
let result = await this.Model.save(data);
|
||
let colInst = yapi.getInst(interfaceColModel);
|
||
let catInst = yapi.getInst(interfaceCatModel);
|
||
if (result._id) {
|
||
await colInst.save({
|
||
name: '公共测试集',
|
||
project_id: result._id,
|
||
desc: '公共测试集',
|
||
uid: this.getUid(),
|
||
add_time: yapi.commons.time(),
|
||
up_time: yapi.commons.time()
|
||
});
|
||
await catInst.save({
|
||
name: '公共分类',
|
||
project_id: result._id,
|
||
desc: '公共分类',
|
||
uid: this.getUid(),
|
||
add_time: yapi.commons.time(),
|
||
up_time: yapi.commons.time()
|
||
});
|
||
}
|
||
let uid = this.getUid();
|
||
// 将项目添加者变成项目组长,除admin以外
|
||
if (this.getRole() !== 'admin') {
|
||
let userdata = await this.getUserdata(uid, 'owner');
|
||
await this.Model.addMember(result._id, [userdata]);
|
||
}
|
||
let username = this.getUsername();
|
||
yapi.commons.saveLog({
|
||
content: `<a href="/user/profile/${this.getUid()}">${username}</a> 添加了项目 <a href="/project/${
|
||
result._id
|
||
}">${params.name}</a>`,
|
||
type: 'project',
|
||
uid,
|
||
username: username,
|
||
typeid: result._id
|
||
});
|
||
ctx.body = yapi.commons.resReturn(result);
|
||
}
|
||
|
||
/**
|
||
* 拷贝项目分组
|
||
* @interface /project/copy
|
||
* @method POST
|
||
* @category project
|
||
* @foldnumber 10
|
||
* @param {String} name 项目名称,不能为空
|
||
* @param {String} basepath 项目基本路径,不能为空
|
||
* @param {Number} group_id 项目分组id,不能为空
|
||
* @param {Number} group_name 项目分组名称,不能为空
|
||
* @param {String} project_type private public
|
||
* @param {String} [desc] 项目描述
|
||
* @returns {Object}
|
||
* @example ./api/project/add.json
|
||
*/
|
||
async copy(ctx) {
|
||
try {
|
||
let params = ctx.params;
|
||
|
||
// 拷贝项目的ID
|
||
let copyId = params._id;
|
||
if ((await this.checkAuth(params.group_id, 'group', 'edit')) !== true) {
|
||
return (ctx.body = yapi.commons.resReturn(null, 405, '没有权限'));
|
||
}
|
||
|
||
params.basepath = params.basepath || '';
|
||
|
||
let data = Object.assign(params, {
|
||
project_type: params.project_type || 'private',
|
||
uid: this.getUid(),
|
||
add_time: yapi.commons.time(),
|
||
up_time: yapi.commons.time(),
|
||
env: params.env || [{ name: 'local', domain: 'http://127.0.0.1' }]
|
||
});
|
||
|
||
delete data._id;
|
||
let result = await this.Model.save(data);
|
||
let colInst = yapi.getInst(interfaceColModel);
|
||
let catInst = yapi.getInst(interfaceCatModel);
|
||
|
||
// 增加集合
|
||
if (result._id) {
|
||
await colInst.save({
|
||
name: '公共测试集',
|
||
project_id: result._id,
|
||
desc: '公共测试集',
|
||
uid: this.getUid(),
|
||
add_time: yapi.commons.time(),
|
||
up_time: yapi.commons.time()
|
||
});
|
||
|
||
// 拷贝接口列表
|
||
let cat = params.cat;
|
||
for (let i = 0; i < cat.length; i++) {
|
||
let item = cat[i];
|
||
let catDate = {
|
||
name: item.name,
|
||
project_id: result._id,
|
||
desc: item.desc,
|
||
uid: this.getUid(),
|
||
add_time: yapi.commons.time(),
|
||
up_time: yapi.commons.time()
|
||
};
|
||
let catResult = await catInst.save(catDate);
|
||
|
||
// 获取每个集合中的interface
|
||
let interfaceData = await this.interfaceModel.listByInterStatus(item._id);
|
||
|
||
// 将interfaceData存到新的catID中
|
||
for (let key = 0; key < interfaceData.length; key++) {
|
||
let interfaceItem = interfaceData[key].toObject();
|
||
let data = Object.assign(interfaceItem, {
|
||
uid: this.getUid(),
|
||
catid: catResult._id,
|
||
project_id: result._id,
|
||
add_time: yapi.commons.time(),
|
||
up_time: yapi.commons.time()
|
||
});
|
||
delete data._id;
|
||
|
||
await this.interfaceModel.save(data);
|
||
}
|
||
}
|
||
}
|
||
|
||
// 增加member
|
||
let copyProject = await this.Model.get(copyId);
|
||
let copyProjectMembers = copyProject.members;
|
||
|
||
let uid = this.getUid();
|
||
// 将项目添加者变成项目组长,除admin以外
|
||
if (this.getRole() !== 'admin') {
|
||
let userdata = await this.getUserdata(uid, 'owner');
|
||
copyProjectMembers.push(userdata);
|
||
}
|
||
await this.Model.addMember(result._id, copyProjectMembers);
|
||
|
||
// 在每个测试结合下添加interface
|
||
|
||
let username = this.getUsername();
|
||
yapi.commons.saveLog({
|
||
content: `<a href="/user/profile/${this.getUid()}">${username}</a> 复制了项目 ${
|
||
params.preName
|
||
} 为 <a href="/project/${result._id}">${params.name}</a>`,
|
||
type: 'project',
|
||
uid,
|
||
username: username,
|
||
typeid: result._id
|
||
});
|
||
ctx.body = yapi.commons.resReturn(result);
|
||
} catch (err) {
|
||
ctx.body = yapi.commons.resReturn(null, 402, err.message);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 添加项目成员
|
||
* @interface /project/add_member
|
||
* @method POST
|
||
* @category project
|
||
* @foldnumber 10
|
||
* @param {Number} id 项目id,不能为空
|
||
* @param {Array} member_uid 项目成员uid,不能为空
|
||
* @returns {Object}
|
||
* @example ./api/project/add_member.json
|
||
*/
|
||
async addMember(ctx) {
|
||
let params = ctx.params;
|
||
if ((await this.checkAuth(params.id, 'project', 'edit')) !== true) {
|
||
return (ctx.body = yapi.commons.resReturn(null, 405, '没有权限'));
|
||
}
|
||
|
||
params.role = ['owner', 'dev', 'guest'].find(v => v === params.role) || 'dev';
|
||
let add_members = [];
|
||
let exist_members = [];
|
||
let no_members = [];
|
||
for (let i = 0, len = params.member_uids.length; i < len; i++) {
|
||
let id = params.member_uids[i];
|
||
let check = await this.Model.checkMemberRepeat(params.id, id);
|
||
let userdata = await this.getUserdata(id, params.role);
|
||
if (check > 0) {
|
||
exist_members.push(userdata);
|
||
} else if (!userdata) {
|
||
no_members.push(id);
|
||
} else {
|
||
add_members.push(userdata);
|
||
}
|
||
}
|
||
|
||
let result = await this.Model.addMember(params.id, add_members);
|
||
if (add_members.length) {
|
||
let members = add_members.map(item => {
|
||
return `<a href = "/user/profile/${item.uid}">${item.username}</a>`;
|
||
});
|
||
members = members.join('、');
|
||
let username = this.getUsername();
|
||
yapi.commons.saveLog({
|
||
content: `<a href="/user/profile/${this.getUid()}">${username}</a> 添加了项目成员 ${members}`,
|
||
type: 'project',
|
||
uid: this.getUid(),
|
||
username: username,
|
||
typeid: params.id
|
||
});
|
||
}
|
||
ctx.body = yapi.commons.resReturn({
|
||
result,
|
||
add_members,
|
||
exist_members,
|
||
no_members
|
||
});
|
||
}
|
||
/**
|
||
* 删除项目成员
|
||
* @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
|
||
*/
|
||
|
||
async delMember(ctx) {
|
||
let params = ctx.params;
|
||
|
||
var check = await this.Model.checkMemberRepeat(params.id, params.member_uid);
|
||
if (check === 0) {
|
||
return (ctx.body = yapi.commons.resReturn(null, 400, '项目成员不存在'));
|
||
}
|
||
|
||
if ((await this.checkAuth(params.id, 'project', 'danger')) !== true) {
|
||
return (ctx.body = yapi.commons.resReturn(null, 405, '没有权限'));
|
||
}
|
||
|
||
let result = await this.Model.delMember(params.id, params.member_uid);
|
||
let username = this.getUsername();
|
||
yapi
|
||
.getInst(userModel)
|
||
.findById(params.member_uid)
|
||
.then(member => {
|
||
yapi.commons.saveLog({
|
||
content: `<a href="/user/profile/${this.getUid()}">${username}</a> 删除了项目中的成员 <a href="/user/profile/${
|
||
params.member_uid
|
||
}">${member.username}</a>`,
|
||
type: 'project',
|
||
uid: this.getUid(),
|
||
username: username,
|
||
typeid: params.id
|
||
});
|
||
});
|
||
ctx.body = yapi.commons.resReturn(result);
|
||
}
|
||
|
||
async getUserdata(uid, role) {
|
||
role = role || 'dev';
|
||
let userInst = yapi.getInst(userModel);
|
||
let userData = await userInst.findById(uid);
|
||
if (!userData) {
|
||
return null;
|
||
}
|
||
return {
|
||
role: role,
|
||
uid: userData._id,
|
||
username: userData.username,
|
||
email: userData.email
|
||
};
|
||
}
|
||
|
||
/**
|
||
* 获取项目成员列表
|
||
* @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.params;
|
||
if (!params.id) {
|
||
return (ctx.body = yapi.commons.resReturn(null, 400, '项目id不能为空'));
|
||
}
|
||
|
||
let project = await this.Model.get(params.id);
|
||
ctx.body = yapi.commons.resReturn(project.members);
|
||
}
|
||
|
||
/**
|
||
* 获取项目信息
|
||
* @interface /project/get
|
||
* @method GET
|
||
* @category project
|
||
* @foldnumber 10
|
||
* @param {Number} id 项目id,不能为空
|
||
* @returns {Object}
|
||
* @example ./api/project/get.json
|
||
*/
|
||
|
||
async get(ctx) {
|
||
let params = ctx.params;
|
||
let result = await this.Model.getBaseInfo(params.id);
|
||
|
||
if (!result) {
|
||
return (ctx.body = yapi.commons.resReturn(null, 400, '不存在的项目'));
|
||
}
|
||
if (result.project_type === 'private') {
|
||
if ((await this.checkAuth(result._id, 'project', 'view')) !== true) {
|
||
return (ctx.body = yapi.commons.resReturn(null, 406, '没有权限'));
|
||
}
|
||
}
|
||
result = result.toObject();
|
||
let catInst = yapi.getInst(interfaceCatModel);
|
||
let cat = await catInst.list(params.id);
|
||
result.cat = cat;
|
||
if (result.env.length === 0) {
|
||
result.env.push({ name: 'local', domain: 'http://127.0.0.1' });
|
||
}
|
||
result.role = await this.getProjectRole(params.id, 'project');
|
||
|
||
yapi.emitHook('project_add', params.id).then();
|
||
ctx.body = yapi.commons.resReturn(result);
|
||
}
|
||
|
||
/**
|
||
* 获取项目列表
|
||
* @interface /project/list
|
||
* @method GET
|
||
* @category project
|
||
* @foldnumber 10
|
||
* @param {Number} group_id 项目group_id,不能为空
|
||
* @returns {Object}
|
||
* @example ./api/project/list.json
|
||
*/
|
||
|
||
async list(ctx) {
|
||
let group_id = ctx.params.group_id,
|
||
project_list = [];
|
||
|
||
let groupData = await this.groupModel.get(group_id);
|
||
let isPrivateGroup = false;
|
||
if (groupData.type === 'private' && this.getUid() === groupData.uid) {
|
||
isPrivateGroup = true;
|
||
}
|
||
let auth = await this.checkAuth(group_id, 'group', 'view');
|
||
let result = await this.Model.list(group_id);
|
||
let follow = await this.followModel.list(this.getUid());
|
||
if (isPrivateGroup === false) {
|
||
for (let index = 0, item, r = 1; index < result.length; index++) {
|
||
item = result[index].toObject();
|
||
if (item.project_type === 'private' && auth === false) {
|
||
r = await this.Model.checkMemberRepeat(item._id, this.getUid());
|
||
if (r === 0) {
|
||
continue;
|
||
}
|
||
}
|
||
|
||
let f = _.find(follow, fol => {
|
||
return fol.projectid === item._id;
|
||
});
|
||
// 排序:收藏的项目放前面
|
||
if (f) {
|
||
item.follow = true;
|
||
project_list.unshift(item);
|
||
} else {
|
||
item.follow = false;
|
||
project_list.push(item);
|
||
}
|
||
}
|
||
} else {
|
||
follow = follow.map(item => {
|
||
item = item.toObject();
|
||
item.follow = true;
|
||
return item;
|
||
});
|
||
project_list = _.uniq(follow.concat(result), item => item._id);
|
||
}
|
||
|
||
ctx.body = yapi.commons.resReturn({
|
||
list: project_list
|
||
});
|
||
}
|
||
|
||
/**
|
||
* 删除项目
|
||
* @interface /project/del
|
||
* @method POST
|
||
* @category project
|
||
* @foldnumber 10
|
||
* @param {Number} id 项目id,不能为空
|
||
* @returns {Object}
|
||
* @example ./api/project/del.json
|
||
*/
|
||
|
||
async del(ctx) {
|
||
let id = ctx.params.id;
|
||
|
||
if ((await this.checkAuth(id, 'project', 'danger')) !== true) {
|
||
return (ctx.body = yapi.commons.resReturn(null, 405, '没有权限'));
|
||
}
|
||
|
||
let interfaceInst = yapi.getInst(interfaceModel);
|
||
let interfaceColInst = yapi.getInst(interfaceColModel);
|
||
let interfaceCaseInst = yapi.getInst(interfaceCaseModel);
|
||
await interfaceInst.delByProjectId(id);
|
||
await interfaceCaseInst.delByProjectId(id);
|
||
await interfaceColInst.delByProjectId(id);
|
||
yapi.emitHook('project_del', id).then();
|
||
let result = await this.Model.del(id);
|
||
ctx.body = yapi.commons.resReturn(result);
|
||
}
|
||
|
||
/**
|
||
* 修改项目成员角色
|
||
* @interface /project/change_member_role
|
||
* @method POST
|
||
* @category project
|
||
* @foldnumber 10
|
||
* @param {String} id 项目id
|
||
* @param {String} member_uid 项目成员uid
|
||
* @param {String} role 权限 ['owner'|'dev']
|
||
* @returns {Object}
|
||
* @example
|
||
*/
|
||
async changeMemberRole(ctx) {
|
||
let params = ctx.request.body;
|
||
let projectInst = yapi.getInst(projectModel);
|
||
|
||
var check = await projectInst.checkMemberRepeat(params.id, params.member_uid);
|
||
if (check === 0) {
|
||
return (ctx.body = yapi.commons.resReturn(null, 400, '项目成员不存在'));
|
||
}
|
||
if ((await this.checkAuth(params.id, 'project', 'danger')) !== true) {
|
||
return (ctx.body = yapi.commons.resReturn(null, 405, '没有权限'));
|
||
}
|
||
|
||
params.role = ['owner', 'dev', 'guest'].find(v => v === params.role) || 'dev';
|
||
let rolename = {
|
||
owner: '组长',
|
||
dev: '开发者',
|
||
guest: '访客'
|
||
};
|
||
|
||
let result = await projectInst.changeMemberRole(params.id, params.member_uid, params.role);
|
||
|
||
let username = this.getUsername();
|
||
yapi
|
||
.getInst(userModel)
|
||
.findById(params.member_uid)
|
||
.then(member => {
|
||
yapi.commons.saveLog({
|
||
content: `<a href="/user/profile/${this.getUid()}">${username}</a> 修改了项目中的成员 <a href="/user/profile/${
|
||
params.member_uid
|
||
}">${member.username}</a> 的角色为 "${rolename[params.role]}"`,
|
||
type: 'project',
|
||
uid: this.getUid(),
|
||
username: username,
|
||
typeid: params.id
|
||
});
|
||
});
|
||
ctx.body = yapi.commons.resReturn(result);
|
||
}
|
||
|
||
/**
|
||
* 项目头像设置
|
||
* @interface /project/upset
|
||
* @method POST
|
||
* @category project
|
||
* @foldnumber 10
|
||
* @param {Number} id 项目id,不能为空
|
||
* @param {String} icon 项目icon
|
||
* @param {Array} color 项目color
|
||
* @returns {Object}
|
||
* @example ./api/project/upset
|
||
*/
|
||
async upSet(ctx) {
|
||
let id = ctx.request.body.id;
|
||
let data = {};
|
||
if ((await this.checkAuth(id, 'project', 'danger')) !== true) {
|
||
return (ctx.body = yapi.commons.resReturn(null, 405, '没有权限'));
|
||
}
|
||
data.color = ctx.request.body.color;
|
||
data.icon = ctx.request.body.icon;
|
||
if (!id) {
|
||
return (ctx.body = yapi.commons.resReturn(null, 405, '项目id不能为空'));
|
||
}
|
||
try {
|
||
let result = await this.Model.up(id, data);
|
||
ctx.body = yapi.commons.resReturn(result);
|
||
} catch (e) {
|
||
ctx.body = yapi.commons.resReturn(null, 402, e.message);
|
||
}
|
||
try {
|
||
this.followModel.updateById(this.getUid(), id, data).then(() => {
|
||
let username = this.getUsername();
|
||
yapi.commons.saveLog({
|
||
content: `<a href="/user/profile/${this.getUid()}">${username}</a> 修改了项目图标、颜色`,
|
||
type: 'project',
|
||
uid: this.getUid(),
|
||
username: username,
|
||
typeid: id
|
||
});
|
||
});
|
||
} catch (e) {
|
||
yapi.commons.log(e, 'error'); // eslint-disable-line
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 编辑项目
|
||
* @interface /project/up
|
||
* @method POST
|
||
* @category project
|
||
* @foldnumber 10
|
||
* @param {Number} id 项目id,不能为空
|
||
* @param {String} name 项目名称,不能为空
|
||
* @param {String} basepath 项目基本路径,不能为空
|
||
* @param {String} [desc] 项目描述
|
||
* @returns {Object}
|
||
* @example ./api/project/up.json
|
||
*/
|
||
async up(ctx) {
|
||
try {
|
||
let id = ctx.request.body.id;
|
||
let params = ctx.request.body;
|
||
|
||
params = yapi.commons.handleParams(params, {
|
||
name: 'string',
|
||
basepath: 'string',
|
||
group_id: 'number',
|
||
desc: 'string',
|
||
pre_script: 'string',
|
||
after_script: 'string'
|
||
});
|
||
|
||
if (!id) {
|
||
return (ctx.body = yapi.commons.resReturn(null, 405, '项目id不能为空'));
|
||
}
|
||
|
||
if ((await this.checkAuth(id, 'project', 'danger')) !== true) {
|
||
return (ctx.body = yapi.commons.resReturn(null, 405, '没有权限'));
|
||
}
|
||
|
||
let projectData = await this.Model.get(id);
|
||
|
||
if (params.basepath) {
|
||
if ((params.basepath = this.handleBasepath(params.basepath)) === false) {
|
||
return (ctx.body = yapi.commons.resReturn(null, 401, 'basepath格式有误'));
|
||
}
|
||
}
|
||
|
||
if (projectData.name === params.name) {
|
||
delete params.name;
|
||
}
|
||
|
||
if (params.name) {
|
||
let checkRepeat = await this.Model.checkNameRepeat(params.name, params.group_id);
|
||
if (checkRepeat > 0) {
|
||
return (ctx.body = yapi.commons.resReturn(null, 401, '已存在的项目名'));
|
||
}
|
||
}
|
||
|
||
let data = {
|
||
up_time: yapi.commons.time()
|
||
};
|
||
if (params.project_type) {
|
||
data.project_type = params.project_type;
|
||
}
|
||
|
||
if (!_.isUndefined(params.name)) data.name = params.name;
|
||
if (!_.isUndefined(params.desc)) data.desc = params.desc;
|
||
if (!_.isUndefined(params.group_id)) data.group_id = params.group_id;
|
||
if (!_.isUndefined(params.basepath)) data.basepath = params.basepath;
|
||
if (!_.isUndefined(params.switch_notice)) data.switch_notice = params.switch_notice;
|
||
if (!_.isUndefined(params.color)) data.color = params.color;
|
||
if (!_.isUndefined(params.icon)) data.icon = params.icon;
|
||
if (!_.isUndefined(params.pre_script)) data.pre_script = params.pre_script;
|
||
if (!_.isUndefined(params.after_script)) data.after_script = params.after_script;
|
||
|
||
let result = await this.Model.up(id, data);
|
||
let username = this.getUsername();
|
||
yapi.commons.saveLog({
|
||
content: `<a href="/user/profile/${this.getUid()}">${username}</a> 更新了项目 <a href="/project/${id}/interface/api}">${
|
||
projectData.name
|
||
}</a>`,
|
||
type: 'project',
|
||
uid: this.getUid(),
|
||
username: username,
|
||
typeid: id
|
||
});
|
||
ctx.body = yapi.commons.resReturn(result);
|
||
} catch (e) {
|
||
ctx.body = yapi.commons.resReturn(null, 402, e.message);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 编辑项目
|
||
* @interface /project/up_env
|
||
* @method POST
|
||
* @category project
|
||
* @foldnumber 10
|
||
* @param {Number} id 项目id,不能为空
|
||
* @param {Array} [env] 项目环境配置
|
||
* @param {String} [env[].name] 环境名称
|
||
* @param {String} [env[].domain] 环境域名
|
||
* @param {Array} [env[].header] header
|
||
* @returns {Object}
|
||
* @example
|
||
*/
|
||
async upEnv(ctx) {
|
||
try {
|
||
let id = ctx.request.body.id;
|
||
let params = ctx.request.body;
|
||
if (!id) {
|
||
return (ctx.body = yapi.commons.resReturn(null, 405, '项目id不能为空'));
|
||
}
|
||
|
||
if ((await this.checkAuth(id, 'project', 'edit')) !== true) {
|
||
return (ctx.body = yapi.commons.resReturn(null, 405, '没有权限'));
|
||
}
|
||
|
||
if (!params.env || !Array.isArray(params.env)) {
|
||
return (ctx.body = yapi.commons.resReturn(null, 405, 'env参数格式有误'));
|
||
}
|
||
|
||
let projectData = await this.Model.get(id);
|
||
let data = {
|
||
up_time: yapi.commons.time()
|
||
};
|
||
|
||
data.env = params.env;
|
||
let isRepeat = this.arrRepeat(data.env, 'name');
|
||
if (isRepeat) {
|
||
return (ctx.body = yapi.commons.resReturn(null, 405, '环境变量名重复'));
|
||
}
|
||
let result = await this.Model.up(id, data);
|
||
let username = this.getUsername();
|
||
yapi.commons.saveLog({
|
||
content: `<a href="/user/profile/${this.getUid()}">${username}</a> 更新了项目 <a href="/project/${id}/interface/api">${
|
||
projectData.name
|
||
}</a> 的环境`,
|
||
type: 'project',
|
||
uid: this.getUid(),
|
||
username: username,
|
||
typeid: id
|
||
});
|
||
ctx.body = yapi.commons.resReturn(result);
|
||
} catch (e) {
|
||
ctx.body = yapi.commons.resReturn(null, 402, e.message);
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* 获取项目的环境变量值
|
||
* @interface /project/get_env
|
||
* @method GET
|
||
* @category project
|
||
* @foldnumber 10
|
||
* @param {Number} id 项目id,不能为空
|
||
|
||
* @returns {Object}
|
||
* @example
|
||
*/
|
||
async getEnv(ctx) {
|
||
try {
|
||
// console.log(ctx.request.query.project_id)
|
||
let project_id = ctx.request.query.project_id;
|
||
// let params = ctx.request.body;
|
||
if (!project_id) {
|
||
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, '没有权限'));
|
||
}
|
||
|
||
let env = await this.Model.getByEnv(project_id);
|
||
// console.log('project', projectData)
|
||
|
||
ctx.body = yapi.commons.resReturn(env);
|
||
} catch (e) {
|
||
ctx.body = yapi.commons.resReturn(null, 402, e.message);
|
||
}
|
||
}
|
||
|
||
|
||
|
||
arrRepeat(arr, key) {
|
||
const s = new Set();
|
||
arr.forEach(item => s.add(item[key]));
|
||
return s.size !== arr.length;
|
||
}
|
||
|
||
/**
|
||
* 获取token数据
|
||
* @interface /project/token
|
||
* @method GET
|
||
* @category project
|
||
* @foldnumber 10
|
||
* @param {Number} id 项目id,不能为空
|
||
* @param {String} q
|
||
* @return {Object}
|
||
*/
|
||
async token(ctx) {
|
||
try {
|
||
let project_id = ctx.params.project_id;
|
||
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;
|
||
}
|
||
|
||
ctx.body = yapi.commons.resReturn(token);
|
||
} catch (err) {
|
||
ctx.body = yapi.commons.resReturn(null, 402, err.message);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 更新token数据
|
||
* @interface /project/update_token
|
||
* @method GET
|
||
* @category project
|
||
* @foldnumber 10
|
||
* @param {Number} id 项目id,不能为空
|
||
* @param {String} q
|
||
* @return {Object}
|
||
*/
|
||
async updateToken(ctx) {
|
||
try {
|
||
let project_id = ctx.params.project_id;
|
||
let data = await this.tokenModel.get(project_id);
|
||
let token, result;
|
||
if (data && data.token) {
|
||
let passsalt = yapi.commons.randStr();
|
||
token = sha('sha1')
|
||
.update(passsalt)
|
||
.digest('hex')
|
||
.substr(0, 20);
|
||
result = await this.tokenModel.up(project_id, token);
|
||
result.token = token;
|
||
} else {
|
||
ctx.body = yapi.commons.resReturn(null, 402, '没有查到token信息');
|
||
}
|
||
|
||
ctx.body = yapi.commons.resReturn(result);
|
||
} catch (err) {
|
||
ctx.body = yapi.commons.resReturn(null, 402, err.message);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 模糊搜索项目名称或者组名称
|
||
* @interface /project/search
|
||
* @method GET
|
||
* @category project
|
||
* @foldnumber 10
|
||
* @param {String} q
|
||
* @return {Object}
|
||
* @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: '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
|
||
};
|
||
|
||
return (ctx.body = yapi.commons.resReturn(queryList, 0, 'ok'));
|
||
}
|
||
}
|
||
|
||
module.exports = projectController;
|