member.py 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. # -*- coding: utf-8 -*-
  2. """
  3. walle-web
  4. :copyright: © 2015-2019 walle-web.io
  5. :created time: 2018-11-26 16:29:58
  6. :author: wushuiyong@walle-web.io
  7. """
  8. from datetime import datetime
  9. from flask import current_app
  10. from sqlalchemy import String, Integer, DateTime
  11. from walle import model
  12. from walle.model.database import SurrogatePK
  13. from walle.model.database import db, Model, or_
  14. from walle.model.user import UserModel
  15. from walle.service.rbac.role import *
  16. # 项目配置表
  17. class MemberModel(SurrogatePK, Model):
  18. __tablename__ = 'members'
  19. current_time = datetime.now()
  20. group_id = None
  21. project_id = None
  22. source_type_project = 'project'
  23. source_type_group = 'group'
  24. # 表的结构:
  25. id = db.Column(Integer, primary_key=True, autoincrement=True)
  26. user_id = db.Column(Integer, db.ForeignKey('users.id'))
  27. source_id = db.Column(Integer)
  28. source_type = db.Column(String(10))
  29. access_level = db.Column(String(10))
  30. status = db.Column(Integer)
  31. created_at = db.Column(DateTime, default=current_time)
  32. updated_at = db.Column(DateTime, default=current_time, onupdate=current_time)
  33. group_name = None
  34. def spaces(self, user_id=None):
  35. """
  36. 获取分页列表
  37. :param page:
  38. :param size:
  39. :return:
  40. """
  41. SpaceModel = model.space.SpaceModel
  42. filters = {
  43. MemberModel.status.notin_([self.status_remove]),
  44. MemberModel.source_type == self.source_type_group,
  45. SpaceModel.status.notin_([self.status_remove]),
  46. }
  47. query = self.query.filter(*filters).with_labels()\
  48. .with_entities(MemberModel.source_id, MemberModel.access_level, SpaceModel.name)
  49. if user_id:
  50. query = query.filter_by(user_id=user_id)
  51. query = query.join(SpaceModel, SpaceModel.id == MemberModel.source_id)
  52. spaces = query.all()
  53. current_app.logger.info(spaces)
  54. return {space[0]: {'id': space[0], 'role': space[1], 'name': space[2]} for space in spaces}
  55. def projects(self, user_id=None, space_id=None):
  56. """
  57. 获取分页列表
  58. :param page:
  59. :param size:
  60. :return:
  61. """
  62. filters = {
  63. MemberModel.status.notin_([self.status_remove]),
  64. MemberModel.source_type == self.source_type_project
  65. }
  66. query = self.query.filter(*filters)
  67. if user_id:
  68. query = query.filter_by(user_id=user_id)
  69. projects = query.all()
  70. current_app.logger.info(projects)
  71. return projects
  72. def project_master(self):
  73. filters = {
  74. MemberModel.status.notin_([self.status_remove]),
  75. MemberModel.source_type == self.source_type_project,
  76. MemberModel.user_id == current_user.id,
  77. MemberModel.access_level == MASTER,
  78. }
  79. query = self.query.filter(*filters)
  80. projects = query.with_entities(MemberModel.source_id).all()
  81. return [project[0] for project in projects]
  82. def update_group(self, members, group_name=None):
  83. SpaceModel = model.space.SpaceModel
  84. # 修复空间名称
  85. if group_name:
  86. SpaceModel(id=self.group_id).update({'name': group_name})
  87. # # 修改tag信息
  88. # if group_name:
  89. # tag_model = TagModel.query.filter_by(label='user_group').filter_by(id=self.group_id).first()
  90. # if tag_model.name != group_name:
  91. # tag_model.name = group_name
  92. # 修改用户组成员
  93. # clean up
  94. filters = {
  95. MemberModel.source_id == self.group_id,
  96. MemberModel.source_type == self.source_type_group,
  97. }
  98. MemberModel.query.filter(*filters).delete()
  99. current_app.logger.info(members)
  100. # insert all
  101. for member in members:
  102. current_app.logger.info(member)
  103. current_app.logger.info(member['role'])
  104. update = {
  105. 'user_id': member['user_id'],
  106. 'source_id': self.group_id,
  107. 'source_type': self.source_type_group,
  108. 'access_level': member['role'].upper(),
  109. 'status': self.status_available,
  110. }
  111. m = MemberModel(**update)
  112. db.session.add(m)
  113. ret = db.session.commit()
  114. return ret
  115. def update_project(self, project_id, members, group_name=None):
  116. space_info = model.project.ProjectModel.query.filter_by(id=project_id).first().to_json()
  117. space_members, count, user_ids = self.members(group_id=space_info['space_id'], size=-1)
  118. update_uids = []
  119. for member in members:
  120. update_uids.append(member['user_id'])
  121. current_app.logger.info(user_ids)
  122. current_app.logger.info(update_uids)
  123. # project新增用户是否在space's group中,无则抛出
  124. if list(set(update_uids).difference(set(user_ids))):
  125. raise WalleError(Code.user_not_in_space)
  126. # 修改用户组成员
  127. # clean up
  128. filters = {
  129. MemberModel.source_id == project_id,
  130. MemberModel.source_type == self.source_type_project,
  131. }
  132. MemberModel.query.filter(*filters).delete()
  133. # insert all
  134. for member in members:
  135. insert = {
  136. 'user_id': member['user_id'],
  137. 'source_id': project_id,
  138. 'source_type': self.source_type_project,
  139. 'access_level': member['role'].upper(),
  140. 'status': self.status_available,
  141. }
  142. group = MemberModel(**insert)
  143. db.session.add(group)
  144. ret = db.session.commit()
  145. return ret
  146. def members(self, group_id=None, project_id=None, page=0, size=10, kw=None):
  147. """
  148. 获取单条记录
  149. :param role_id:
  150. :return:
  151. """
  152. group_id = group_id if group_id else self.group_id
  153. project_id = project_id if project_id else self.project_id
  154. source_id = group_id if group_id else project_id
  155. source_type = self.source_type_group if group_id else self.source_type_project
  156. query = UserModel.query \
  157. .filter(UserModel.status.notin_([self.status_remove])) \
  158. .filter(MemberModel.source_id == source_id) \
  159. .filter(MemberModel.source_type == source_type)
  160. query = query.join(MemberModel, UserModel.id == MemberModel.user_id)
  161. if kw:
  162. query = query.filter(or_(UserModel.username.like('%' + kw + '%'), UserModel.email.like('%' + kw + '%')))
  163. query = query.add_columns(MemberModel.access_level, UserModel.id)
  164. count = query.count()
  165. query = query.order_by(MemberModel.id.asc())
  166. if size > 0:
  167. query = query.offset(int(size) * int(page)).limit(size)
  168. data = query.all()
  169. current_app.logger.info(data)
  170. list = []
  171. user_ids = []
  172. for p in data:
  173. item = p[0].to_json()
  174. item['role'] = p[1]
  175. user_ids.append(p[2])
  176. list.append(item)
  177. current_app.logger.info(list)
  178. return list, count, user_ids
  179. def member(self, user_id, role, group_id=None, project_id=None):
  180. query = self.query
  181. if group_id:
  182. query = query.filter_by(source_id=group_id).filter_by(source_type=self.source_type_group)
  183. elif project_id:
  184. query = query.filter_by(project_id=project_id).filter_by(source_type=self.source_type_project)
  185. if user_id:
  186. query = query.filter_by(user_id=user_id)
  187. if query.count():
  188. query.update({'access_level': role})
  189. else:
  190. source_type = self.source_type_project if project_id else self.source_type_group
  191. source_id = project_id if project_id else group_id
  192. insert = {
  193. 'user_id': user_id,
  194. 'source_id': source_id,
  195. 'source_type': source_type,
  196. 'access_level': role.upper(),
  197. 'status': self.status_available,
  198. }
  199. current_app.logger.info(insert)
  200. group = MemberModel(**insert)
  201. db.session.add(group)
  202. db.session.commit()
  203. return self.members(group_id=group_id)
  204. def remove(self, group_id=None, user_id=None, project_id=None):
  205. """
  206. :param role_id:
  207. :return:
  208. """
  209. if group_id:
  210. MemberModel.query.filter_by(group_id=group_id).update({'status': self.status_remove})
  211. elif user_id:
  212. MemberModel.query.filter_by(user_id=user_id).update({'status': self.status_remove})
  213. elif self.group_id:
  214. MemberModel.query.filter_by(group_id=self.group_id).update({'status': self.status_remove})
  215. elif project_id:
  216. MemberModel.query.filter_by(project_id=project_id).update({'status': self.status_remove})
  217. ret = db.session.commit()
  218. return ret
  219. def to_json(self):
  220. return {
  221. 'id': self.id,
  222. 'user_id': self.user_id,
  223. 'group_id': self.group_id,
  224. 'group_name': self.group_name,
  225. 'created_at': self.created_at.strftime('%Y-%m-%d %H:%M:%S'),
  226. 'updated_at': self.updated_at.strftime('%Y-%m-%d %H:%M:%S'),
  227. }