task.py 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. # -*- coding: utf-8 -*-
  2. """
  3. walle-web
  4. :copyright: © 2015-2019 walle-web.io
  5. :created time: 2018-11-24 06:22:04
  6. :author: wushuiyong@walle-web.io
  7. """
  8. from datetime import datetime
  9. from sqlalchemy import String, Integer, DateTime, Text
  10. from walle import model
  11. from walle.model.database import db, Model, SurrogatePK
  12. from walle.service.extensions import permission
  13. from walle.service.rbac.role import *
  14. # 上线单
  15. class TaskModel(SurrogatePK, Model):
  16. __tablename__ = 'tasks'
  17. current_time = datetime.now()
  18. # 状态:0新建提交,1审核通过,2审核拒绝,3上线中,4上线完成,5上线失败
  19. status_new = 0
  20. status_pass = 1
  21. status_reject = 2
  22. status_doing = 3
  23. status_success = 4
  24. status_fail = 5
  25. status_memo = {
  26. status_new: '新建提交',
  27. status_pass: '审核通过',
  28. status_reject: '审核拒绝',
  29. status_doing: '上线中',
  30. status_success: '上线完成',
  31. status_fail: '上线失败',
  32. }
  33. rollback_count = {}
  34. keep_version_num = 3
  35. # 表的结构:
  36. id = db.Column(Integer, primary_key=True, autoincrement=True)
  37. name = db.Column(String(100))
  38. user_id = db.Column(Integer)
  39. user_name = db.Column(String(10))
  40. project_id = db.Column(Integer)
  41. action = db.Column(Integer)
  42. status = db.Column(Integer)
  43. link_id = db.Column(String(100))
  44. ex_link_id = db.Column(String(100))
  45. servers = db.Column(Text)
  46. commit_id = db.Column(String(40))
  47. branch = db.Column(String(100))
  48. tag = db.Column(String(100))
  49. file_transmission_mode = db.Column(Integer)
  50. file_list = db.Column(Text)
  51. is_rollback = db.Column(Integer)
  52. created_at = db.Column(DateTime, default=current_time)
  53. updated_at = db.Column(DateTime, default=current_time, onupdate=current_time)
  54. taskMdl = None
  55. def table_name(self):
  56. return self.__tablename__
  57. #
  58. # def list(self, page=0, size=10, kw=''):
  59. # data = Task.query.order_by('id').offset(int(size) * int(page)).limit(size).all()
  60. # return [p.to_json() for p in data]
  61. #
  62. # def one(self):
  63. # project_info = Project.query.filter_by(id=self.taskMdl.get('project_id')).one().to_json()
  64. # return dict(project_info, **self.taskMdl)
  65. #
  66. def list(self, page=0, size=10, space_id=None, kw=None):
  67. """
  68. 获取分页列表
  69. :param page:
  70. :param size:
  71. :param kw:
  72. :return:
  73. """
  74. self.rollback_count.clear()
  75. query = TaskModel.query.filter(TaskModel.status.notin_([self.status_remove]))
  76. if kw:
  77. query = query.filter(TaskModel.name.like('%' + kw + '%'))
  78. # 关联 projects
  79. ProjectModel = model.project.ProjectModel
  80. query = query.join(ProjectModel, TaskModel.project_id == ProjectModel.id)
  81. query = query.filter(ProjectModel.status.notin_([self.status_remove]))
  82. # 关联 environments
  83. EnvironmentModel = model.environment.EnvironmentModel
  84. query = query.join(EnvironmentModel, EnvironmentModel.id == ProjectModel.environment_id)
  85. query = query.filter(EnvironmentModel.status.notin_([self.status_remove]))
  86. if space_id:
  87. query = query.filter(ProjectModel.space_id == space_id)
  88. query = query.add_columns(ProjectModel.name, EnvironmentModel.name, ProjectModel.keep_version_num)
  89. count = query.count()
  90. data = query.order_by(TaskModel.id.desc()) \
  91. .offset(int(size) * int(page)).limit(size) \
  92. .all()
  93. task_list = []
  94. for p in data:
  95. p[0].keep_version_num = p[3]
  96. item = p[0].to_json()
  97. item['project_name'] = p[1]
  98. item['environment_name'] = p[2]
  99. # self.keep_version_num = p[3]
  100. task_list.append(item)
  101. return task_list, count
  102. def item(self, id=None):
  103. """
  104. 获取单条记录
  105. :param role_id:
  106. :return:
  107. """
  108. id = id if id else self.id
  109. data = self.query.filter(TaskModel.status.notin_([self.status_remove])).filter_by(id=id).first()
  110. if not data:
  111. return []
  112. task = data.to_json()
  113. ProjectModel = model.project.ProjectModel
  114. project = ProjectModel().item(task['project_id'])
  115. task['project_name'] = project['name'] if project else '未知项目'
  116. task['project_info'] = project
  117. return task
  118. def add(self, *args, **kwargs):
  119. data = dict(*args)
  120. project = TaskModel(**data)
  121. db.session.add(project)
  122. db.session.commit()
  123. if project.id:
  124. self.id = project.id
  125. return project.to_json()
  126. def update(self, *args, **kwargs):
  127. update_data = dict(*args)
  128. return super(TaskModel, self).update(**update_data)
  129. def remove(self, id=None):
  130. """
  131. :param role_id:
  132. :return:
  133. """
  134. id = id if id else self.id
  135. self.query.filter_by(id=id).update({'status': self.status_remove})
  136. ret = db.session.commit()
  137. return ret
  138. def to_json(self):
  139. ServerModel = model.server.ServerModel
  140. item = {
  141. 'id': self.id,
  142. 'name': self.name,
  143. 'user_id': int(self.user_id),
  144. 'user_name': self.user_name,
  145. 'project_id': int(self.project_id),
  146. 'project_name': self.project_id if self.project_id else '',
  147. 'action': self.action,
  148. 'status': self.status,
  149. 'link_id': self.link_id,
  150. 'ex_link_id': self.ex_link_id,
  151. 'servers': self.servers,
  152. 'servers_info': ServerModel.fetch_by_id(self.servers.split(',')) if self.servers else '',
  153. 'commit_id': self.commit_id,
  154. 'branch': self.branch,
  155. 'tag': self.tag,
  156. 'file_transmission_mode': self.file_transmission_mode,
  157. 'file_list': self.file_list,
  158. 'is_rollback': self.is_rollback,
  159. 'created_at': self.created_at.strftime('%Y-%m-%d %H:%M:%S'),
  160. 'updated_at': self.updated_at.strftime('%Y-%m-%d %H:%M:%S'),
  161. }
  162. item.update(self.enable())
  163. return item
  164. def enable(self):
  165. is_project_master = self.project_id in session['project_master']
  166. if self.project_id not in self.rollback_count:
  167. self.rollback_count[self.project_id] = 0
  168. if self.status in [self.status_doing, self.status_fail, self.status_success]:
  169. self.rollback_count[self.project_id] += 1
  170. current_app.logger.error(self.rollback_count[self.project_id])
  171. current_app.logger.error(self.keep_version_num)
  172. if self.rollback_count[self.project_id] <= self.keep_version_num \
  173. and self.status in [self.status_doing, self.status_fail, self.status_success] \
  174. and self.ex_link_id:
  175. enable_rollback = True
  176. else:
  177. enable_rollback = False
  178. return {
  179. 'enable_view': True if self.status in [self.status_doing, self.status_fail, self.status_success] else False,
  180. 'enable_update': (permission.enable_uid(self.user_id) or permission.role_upper_developer() or is_project_master) and (self.status in [self.status_new, self.status_reject]),
  181. 'enable_delete': (permission.enable_uid(self.user_id) or permission.role_upper_developer() or is_project_master) and (self.status in [self.status_new, self.status_pass, self.status_reject]),
  182. 'enable_create': False,
  183. 'enable_online': (permission.enable_uid(self.user_id) or permission.role_upper_developer() or is_project_master) and (self.status in [self.status_pass, self.status_fail, self.status_doing]),
  184. 'enable_audit': (permission.role_upper_developer() or is_project_master) and (self.status in [self.status_new]),
  185. 'enable_rollback': enable_rollback
  186. }
  187. @classmethod
  188. def task_default_status(cls, project_id):
  189. ProjectModel = model.project.ProjectModel
  190. project_info = ProjectModel.query.filter_by(id=project_id).first()
  191. if project_info.task_audit == ProjectModel.task_audit_true:
  192. return TaskModel.status_new
  193. else:
  194. return TaskModel.status_pass