mock平台

group.js 15KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548
  1. const groupModel = require('../models/group.js');
  2. const yapi = require('../yapi.js');
  3. const baseController = require('./base.js');
  4. const projectModel = require('../models/project.js');
  5. const userModel = require('../models/user.js');
  6. const interfaceModel = require('../models/interface.js');
  7. const interfaceColModel = require('../models/interfaceCol.js');
  8. const interfaceCaseModel = require('../models/interfaceCase.js');
  9. const _ = require('underscore')
  10. const rolename = {
  11. owner: '组长',
  12. dev: '开发者',
  13. guest: '访客'
  14. };
  15. class groupController extends baseController {
  16. constructor(ctx) {
  17. super(ctx);
  18. const id = 'number';
  19. const group_name = {
  20. type: 'string',
  21. minLength: 1
  22. };
  23. const group_desc = 'string';
  24. const role = {
  25. type: 'string',
  26. enum: ['owner', 'dev', 'guest']
  27. };
  28. const member_uids = {
  29. type: 'array',
  30. items: 'number',
  31. minItems: 1
  32. };
  33. this.schemaMap = {
  34. get: {
  35. '*id': id
  36. },
  37. add: {
  38. '*group_name': group_name,
  39. group_desc: group_desc,
  40. owner_uids: ['number']
  41. },
  42. addMember: {
  43. '*id': id,
  44. role: role,
  45. '*member_uids': member_uids
  46. },
  47. changeMemberRole: {
  48. '*member_uid': 'number',
  49. '*id': id,
  50. role: role
  51. },
  52. getMemberList: {
  53. '*id': id
  54. },
  55. delMember: {
  56. '*id': id,
  57. '*member_uid': 'number'
  58. },
  59. del: {
  60. '*id': id
  61. },
  62. up: {
  63. '*id': id,
  64. '*group_name': group_name,
  65. group_desc: group_desc,
  66. custom_field1: {
  67. name: 'string',
  68. enable: 'boolen'
  69. },
  70. custom_field2: {
  71. name: 'string',
  72. enable: 'boolen'
  73. },
  74. custom_field3: {
  75. name: 'string',
  76. enable: 'boolen'
  77. }
  78. }
  79. };
  80. }
  81. /**
  82. * 查询项目分组
  83. * @interface /group/get
  84. * @method GET
  85. * @category group
  86. * @foldnumber 10
  87. * @param {String} id 项目分组ID
  88. * @returns {Object}
  89. * @example
  90. */
  91. async get(ctx) {
  92. let params = ctx.params;
  93. let groupInst = yapi.getInst(groupModel);
  94. let result = await groupInst.getGroupById(params.id);
  95. if (result) {
  96. result = result.toObject();
  97. let role = await this.getProjectRole(params.id, 'group');
  98. result.role = role;
  99. if (result.type === 'private') {
  100. result.group_name = '个人空间';
  101. }
  102. ctx.body = yapi.commons.resReturn(result);
  103. }
  104. }
  105. /**
  106. * 添加项目分组
  107. * @interface /group/add
  108. * @method POST
  109. * @category group
  110. * @foldnumber 10
  111. * @param {String} group_name 项目分组名称,不能为空
  112. * @param {String} [group_desc] 项目分组描述
  113. * @param {String} [owner_uids] 组长[uid]
  114. * @returns {Object}
  115. * @example ./api/group/add.json
  116. */
  117. async add(ctx) {
  118. let params = ctx.params;
  119. // 新版每个人都有权限添加分组
  120. // if (this.getRole() !== 'admin') {
  121. // return (ctx.body = yapi.commons.resReturn(null, 401, '没有权限'));
  122. // }
  123. let owners = [];
  124. if(params.owner_uids.length === 0){
  125. params.owner_uids.push(
  126. this.getUid()
  127. )
  128. }
  129. if (params.owner_uids) {
  130. for (let i = 0, len = params.owner_uids.length; i < len; i++) {
  131. let id = params.owner_uids[i];
  132. let groupUserdata = await this.getUserdata(id, 'owner');
  133. if (groupUserdata) {
  134. owners.push(groupUserdata);
  135. }
  136. }
  137. }
  138. let groupInst = yapi.getInst(groupModel);
  139. let checkRepeat = await groupInst.checkRepeat(params.group_name);
  140. if (checkRepeat > 0) {
  141. return (ctx.body = yapi.commons.resReturn(null, 401, '项目分组名已存在'));
  142. }
  143. let data = {
  144. group_name: params.group_name,
  145. group_desc: params.group_desc,
  146. uid: this.getUid(),
  147. add_time: yapi.commons.time(),
  148. up_time: yapi.commons.time(),
  149. members: owners
  150. };
  151. let result = await groupInst.save(data);
  152. result = yapi.commons.fieldSelect(result, [
  153. '_id',
  154. 'group_name',
  155. 'group_desc',
  156. 'uid',
  157. 'members',
  158. 'type'
  159. ]);
  160. let username = this.getUsername();
  161. yapi.commons.saveLog({
  162. content: `<a href="/user/profile/${this.getUid()}">${username}</a> 新增了分组 <a href="/group/${
  163. result._id
  164. }">${params.group_name}</a>`,
  165. type: 'group',
  166. uid: this.getUid(),
  167. username: username,
  168. typeid: result._id
  169. });
  170. ctx.body = yapi.commons.resReturn(result);
  171. }
  172. /**
  173. * 获取用户数据
  174. * @param uid
  175. * @param role
  176. * @returns {Promise.<*>}
  177. */
  178. async getUserdata(uid, role) {
  179. role = role || 'dev';
  180. let userInst = yapi.getInst(userModel);
  181. let userData = await userInst.findById(uid);
  182. if (!userData) {
  183. return null;
  184. }
  185. return {
  186. _role: userData.role,
  187. role: role,
  188. uid: userData._id,
  189. username: userData.username,
  190. email: userData.email
  191. };
  192. }
  193. async getMyGroup(ctx){
  194. var groupInst = yapi.getInst(groupModel);
  195. let privateGroup = await groupInst.getByPrivateUid(this.getUid());
  196. if (!privateGroup) {
  197. privateGroup = await groupInst.save({
  198. uid: this.getUid(),
  199. group_name: 'User-' + this.getUid(),
  200. add_time: yapi.commons.time(),
  201. up_time: yapi.commons.time(),
  202. type: 'private'
  203. });
  204. }
  205. if(privateGroup){
  206. ctx.body = yapi.commons.resReturn(privateGroup)
  207. }else{
  208. ctx.body = yapi.commons.resReturn(null)
  209. }
  210. }
  211. /**
  212. * 添加项目分组成员
  213. * @interface /group/add_member
  214. * @method POST
  215. * @category group
  216. * @foldnumber 10
  217. * @param {String} id 项目分组id
  218. * @param {String} member_uids 项目分组成员[uid]
  219. * @param {String} role 成员角色,owner or dev or guest
  220. * @returns {Object}
  221. * @example
  222. */
  223. async addMember(ctx) {
  224. let params = ctx.params;
  225. let groupInst = yapi.getInst(groupModel);
  226. params.role = ['owner', 'dev', 'guest'].find(v => v === params.role) || 'dev';
  227. let add_members = [];
  228. let exist_members = [];
  229. let no_members = [];
  230. for (let i = 0, len = params.member_uids.length; i < len; i++) {
  231. let id = params.member_uids[i];
  232. let check = await groupInst.checkMemberRepeat(params.id, id);
  233. let userdata = await this.getUserdata(id, params.role);
  234. if (check > 0) {
  235. exist_members.push(userdata);
  236. } else if (!userdata) {
  237. no_members.push(id);
  238. } else {
  239. userdata.role !== 'admin' && add_members.push(userdata);
  240. delete userdata._role;
  241. }
  242. }
  243. let result = await groupInst.addMember(params.id, add_members);
  244. let username = this.getUsername();
  245. if (add_members.length) {
  246. let members = add_members.map(item => {
  247. return `<a href = "/user/profile/${item.uid}">${item.username}</a>`;
  248. });
  249. members = members.join('、');
  250. yapi.commons.saveLog({
  251. content: `<a href="/user/profile/${this.getUid()}">${username}</a> 新增了分组成员 ${members} 为 ${
  252. rolename[params.role]
  253. }`,
  254. type: 'group',
  255. uid: this.getUid(),
  256. username: username,
  257. typeid: params.id
  258. });
  259. }
  260. ctx.body = yapi.commons.resReturn({
  261. result,
  262. add_members,
  263. exist_members,
  264. no_members
  265. });
  266. }
  267. /**
  268. * 修改项目分组成员角色
  269. * @interface /group/change_member_role
  270. * @method POST
  271. * @category group
  272. * @foldnumber 10
  273. * @param {String} id 项目分组id
  274. * @param {String} member_uid 项目分组成员uid
  275. * @param {String} role 权限 ['owner'|'dev']
  276. * @returns {Object}
  277. * @example
  278. */
  279. async changeMemberRole(ctx) {
  280. let params = ctx.request.body;
  281. let groupInst = yapi.getInst(groupModel);
  282. var check = await groupInst.checkMemberRepeat(params.id, params.member_uid);
  283. if (check === 0) {
  284. return (ctx.body = yapi.commons.resReturn(null, 400, '分组成员不存在'));
  285. }
  286. if ((await this.checkAuth(params.id, 'group', 'danger')) !== true) {
  287. return (ctx.body = yapi.commons.resReturn(null, 405, '没有权限'));
  288. }
  289. params.role = ['owner', 'dev', 'guest'].find(v => v === params.role) || 'dev';
  290. let result = await groupInst.changeMemberRole(params.id, params.member_uid, params.role);
  291. let username = this.getUsername();
  292. let groupUserdata = await this.getUserdata(params.member_uid, params.role);
  293. yapi.commons.saveLog({
  294. content: `<a href="/user/profile/${this.getUid()}">${username}</a> 更改了分组成员 <a href="/user/profile/${
  295. params.member_uid
  296. }">${groupUserdata ? groupUserdata.username : ''}</a> 的权限为 "${rolename[params.role]}"`,
  297. type: 'group',
  298. uid: this.getUid(),
  299. username: username,
  300. typeid: params.id
  301. });
  302. ctx.body = yapi.commons.resReturn(result);
  303. }
  304. /**
  305. * 获取所有项目成员
  306. * @interface /group/get_member_list
  307. * @method GET
  308. * @category group
  309. * @foldnumber 10
  310. * @param {String} id 项目分组id
  311. * @returns {Object}
  312. * @example
  313. */
  314. async getMemberList(ctx) {
  315. let params = ctx.params;
  316. let groupInst = yapi.getInst(groupModel);
  317. let group = await groupInst.get(params.id);
  318. ctx.body = yapi.commons.resReturn(group.members);
  319. }
  320. /**
  321. * 删除项目成员
  322. * @interface /group/del_member
  323. * @method POST
  324. * @category group
  325. * @foldnumber 10
  326. * @param {String} id 项目分组id
  327. * @param {String} member_uid 项目分组成员uid
  328. * @returns {Object}
  329. * @example
  330. */
  331. async delMember(ctx) {
  332. let params = ctx.params;
  333. let groupInst = yapi.getInst(groupModel);
  334. var check = await groupInst.checkMemberRepeat(params.id, params.member_uid);
  335. if (check === 0) {
  336. return (ctx.body = yapi.commons.resReturn(null, 400, '分组成员不存在'));
  337. }
  338. if ((await this.checkAuth(params.id, 'group', 'danger')) !== true) {
  339. return (ctx.body = yapi.commons.resReturn(null, 405, '没有权限'));
  340. }
  341. let result = await groupInst.delMember(params.id, params.member_uid);
  342. let username = this.getUsername();
  343. let groupUserdata = await this.getUserdata(params.member_uid, params.role);
  344. yapi.commons.saveLog({
  345. content: `<a href="/user/profile/${this.getUid()}">${username}</a> 删除了分组成员 <a href="/user/profile/${
  346. params.member_uid
  347. }">${groupUserdata ? groupUserdata.username : ''}</a>`,
  348. type: 'group',
  349. uid: this.getUid(),
  350. username: username,
  351. typeid: params.id
  352. });
  353. ctx.body = yapi.commons.resReturn(result);
  354. }
  355. /**
  356. * 获取项目分组列表
  357. * @interface /group/list
  358. * @method get
  359. * @category group
  360. * @foldnumber 10
  361. * @returns {Object}
  362. * @example ./api/group/list.json
  363. */
  364. async list(ctx) {
  365. var groupInst = yapi.getInst(groupModel);
  366. let projectInst = yapi.getInst(projectModel);
  367. let result = await groupInst.getAuthList(this.getUid());
  368. let privateGroup = await groupInst.getByPrivateUid(this.getUid());
  369. let newResult = [];
  370. if (!privateGroup) {
  371. privateGroup = await groupInst.save({
  372. uid: this.getUid(),
  373. group_name: 'User-' + this.getUid(),
  374. add_time: yapi.commons.time(),
  375. up_time: yapi.commons.time(),
  376. type: 'private'
  377. });
  378. }
  379. if(result && result.length > 0 ){
  380. for (let i = 0; i < result.length; i++){
  381. result[i] = result[i].toObject();
  382. newResult.unshift(result[i])
  383. }
  384. }
  385. const groupIds = newResult.map(item=> item._id);
  386. const newGroupIds = [];
  387. let groupByProject = await projectInst.getAuthList(this.getUid());
  388. if(groupByProject && groupByProject.length > 0){
  389. groupByProject.forEach( _data=>{
  390. const _temp = [...groupIds, ...newGroupIds];
  391. if(!_.find(_temp, id=> id === _data.group_id)){
  392. newGroupIds.push(_data.group_id)
  393. }
  394. })
  395. }
  396. let newData = await groupInst.findByGroups(newGroupIds)
  397. newData.forEach(_data=>{
  398. _data = _data.toObject();
  399. newResult.push(_data);
  400. })
  401. // if (result && result.length > 0) {
  402. // for (let i = 0; i < result.length; i++) {
  403. // result[i] = result[i].toObject();
  404. // result[i].role = await this.getProjectRole(result[i]._id, 'group');
  405. // if (result[i].role !== 'member') {
  406. // newResult.unshift(result[i]);
  407. // } else {
  408. // let publicCount = await projectInst.countWithPublic(result[i]._id);
  409. // if (publicCount > 0) {
  410. // newResult.push(result[i]);
  411. // } else {
  412. // let projectCountWithAuth = await projectInst.getProjectWithAuth(
  413. // result[i]._id,
  414. // this.getUid()
  415. // );
  416. // if (projectCountWithAuth > 0) {
  417. // newResult.push(result[i]);
  418. // }
  419. // }
  420. // }
  421. // }
  422. // }
  423. if (privateGroup) {
  424. privateGroup = privateGroup.toObject();
  425. privateGroup.group_name = '个人空间';
  426. privateGroup.role = 'owner';
  427. newResult.unshift(privateGroup);
  428. }
  429. ctx.body = yapi.commons.resReturn(newResult);
  430. }
  431. /**
  432. * 删除项目分组
  433. * @interface /group/del
  434. * @method post
  435. * @param {String} id 项目分组id
  436. * @category group
  437. * @foldnumber 10
  438. * @returns {Object}
  439. * @example ./api/group/del.json
  440. */
  441. async del(ctx) {
  442. if (this.getRole() !== 'admin') {
  443. return (ctx.body = yapi.commons.resReturn(null, 401, '没有权限'));
  444. }
  445. let groupInst = yapi.getInst(groupModel);
  446. let projectInst = yapi.getInst(projectModel);
  447. let interfaceInst = yapi.getInst(interfaceModel);
  448. let interfaceColInst = yapi.getInst(interfaceColModel);
  449. let interfaceCaseInst = yapi.getInst(interfaceCaseModel);
  450. let id = ctx.params.id;
  451. let projectList = await projectInst.list(id, true);
  452. projectList.forEach(async p => {
  453. await interfaceInst.delByProjectId(p._id);
  454. await interfaceCaseInst.delByProjectId(p._id);
  455. await interfaceColInst.delByProjectId(p._id);
  456. });
  457. if (projectList.length > 0) {
  458. await projectInst.delByGroupid(id);
  459. }
  460. let result = await groupInst.del(id);
  461. ctx.body = yapi.commons.resReturn(result);
  462. }
  463. /**
  464. * 更新项目分组
  465. * @interface /group/up
  466. * @method post
  467. * @param {String} id 项目分组id
  468. * @param {String} group_name 项目分组名称
  469. * @param {String} group_desc 项目分组描述
  470. * @category group
  471. * @foldnumber 10
  472. * @returns {Object}
  473. * @example ./api/group/up.json
  474. */
  475. async up(ctx) {
  476. let groupInst = yapi.getInst(groupModel);
  477. let params = ctx.params;
  478. if ((await this.checkAuth(params.id, 'group', 'danger')) !== true) {
  479. return (ctx.body = yapi.commons.resReturn(null, 405, '没有权限'));
  480. }
  481. let result = await groupInst.up(params.id, params);
  482. let username = this.getUsername();
  483. yapi.commons.saveLog({
  484. content: `<a href="/user/profile/${this.getUid()}">${username}</a> 更新了 <a href="/group/${
  485. params.id
  486. }">${params.group_name}</a> 分组`,
  487. type: 'group',
  488. uid: this.getUid(),
  489. username: username,
  490. typeid: params.id
  491. });
  492. ctx.body = yapi.commons.resReturn(result);
  493. }
  494. }
  495. module.exports = groupController;