123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149 |
- import os
- import uuid
- from django.db import models
- from apps.loon_base_model import BaseModel
- class Workflow(BaseModel):
- """
- 工作流
- """
- name = models.CharField('名称', max_length=50)
- description = models.CharField('描述', max_length=50)
- flowchart = models.FileField('流程图', upload_to='flowchart', blank=True, help_text='工作流的流程图,为了方便别人')
- notices = models.CharField('通知', default='', blank=True, max_length=50, help_text='CustomNotice中的id.逗号隔开多个通知方式')
- view_permission_check = models.BooleanField('查看权限校验', default=True, help_text='开启后,只允许工单的关联人(创建人、曾经的处理人)有权限查看工单')
- limit_expression = models.CharField('限制表达式', max_length=1000, default='{}', blank=True, help_text='限制周期({"period":24} 24小时), 限制次数({"count":1}在限制周期内只允许提交1次), 限制级别({"level":1} 针对(1单个用户 2全局)限制周期限制次数,默认特定用户);允许特定人员提交({"allow_persons":"zhangsan,lisi"}只允许张三提交工单,{"allow_depts":"1,2"}只允许部门id为1和2的用户提交工单,{"allow_roles":"1,2"}只允许角色id为1和2的用户提交工单)')
- display_form_str = models.CharField('展现表单字段', max_length=10000, default='[]', blank=True, help_text='默认"[]",用于用户只有对应工单查看权限时显示哪些字段,field_key的list的json,如["days","sn"],内置特殊字段participant_info.participant_name:当前处理人信息(部门名称、角色名称),state.state_name:当前状态的状态名,workflow.workflow_name:工作流名称')
- # default_notice_to = models.CharField('默认通知人', max_length=50, default='', blank=True, help_text='表单创建及结束时会发送相应通知信息')
- class Meta:
- verbose_name = '工作流'
- verbose_name_plural = '工作流'
- class State(BaseModel):
- """
- 状态记录, 变量支持通过脚本获取
- """
- name = models.CharField('名称', max_length=50)
- workflow_id = models.IntegerField('工作流')
- sub_workflow_id = models.IntegerField('子工作流id', default=0, blank=True, help_text='如果需要在此状态启用子工单,请填写对应的工作流id')
- is_hidden = models.BooleanField('是否隐藏', default=False, help_text='设置为True时,获取工单步骤api中不显示此状态(当前处于此状态时除外)')
- order_id = models.IntegerField('状态顺序', default=0, help_text='用于工单步骤接口时,step上状态的顺序(因为存在网状情况,所以需要人为设定顺序),值越小越靠前')
- type_id = models.IntegerField('状态类型id', default=0, help_text='0.普通类型 1.初始状态(用于新建工单时,获取对应的字段必填及transition信息) 2.结束状态(此状态下的工单不得再处理,即没有对应的transition)')
- remember_last_man_enable = models.BooleanField('记忆最后处理人', default=False, help_text='开启后,到达此状态时会先检查之前是否有人在此状态处理过,如果有则处理人为最后一次处理的人')
- participant_type_id = models.IntegerField('参与者类型id', default=1, blank=True, help_text='0.无处理人,1.个人,2.多人,3.部门,4.角色,5.变量(支持工单创建人,创建人的leader),6.脚本,7.工单的字段内容(如表单中的"测试负责人",需要为用户名或者逗号隔开的多个用户名),8.父工单的字段内容。 初始状态请选择类型5,参与人填creator')
- participant = models.CharField('参与者', default='', blank=True, max_length=100, help_text='可以为空(无处理人的情况,如结束状态)、username\多个username(以,隔开)\部门id\角色id\变量(creator,creator_tl)\脚本记录的id等,包含子工作流的需要设置处理人为loonrobot')
- distribute_type_id = models.IntegerField('分配方式', default=1, help_text='1.主动接单(如果当前处理人实际为多人的时候,需要先接单才能处理) 2.直接处理(即使当前处理人实际为多人,也可以直接处理) 3.随机分配(如果实际为多人,则系统会随机分配给其中一个人) 4.全部处理(要求所有参与人都要处理一遍,才能进入下一步)')
- state_field_str = models.TextField('表单字段', default='{}', help_text='json格式字典存储,包括读写属性1:只读,2:必填,3:可选. 示例:{"created_at":1,"title":2, "sn":1}, 内置特殊字段participant_info.participant_name:当前处理人信息(部门名称、角色名称),state.state_name:当前状态的状态名,workflow.workflow_name:工作流名称') # json格式存储,包括读写属性1:只读,2:必填,3:可选,4:不显示, 字典的字典
- label = models.CharField('状态标签', max_length=1000, default='{}', help_text='json格式,由调用方根据实际定制需求自行确定,如状态下需要显示哪些前端组件:{"components":[{"AppList":1, "ProjectList":7}]}')
- class Meta:
- verbose_name = '工作流状态'
- verbose_name_plural = '工作流状态'
- class Transition(BaseModel):
- """
- 工作流流转,定时器,条件(允许跳过), 条件流转与定时器不可同时存在
- """
- name = models.CharField('操作', max_length=50)
- workflow_id = models.IntegerField('工作流id')
- transition_type_id = models.IntegerField('流转类型', default=1, help_text='1.常规流转,2.定时器流转,需要设置定时器时间')
- timer = models.IntegerField('定时器(单位秒)', default=0, help_text='流转类型设置为定时器流转时生效,单位秒。处于源状态X秒后如果状态都没有过变化则自动流转到目标状态')
- source_state_id = models.IntegerField('源状态id')
- destination_state_id = models.IntegerField('目的状态id')
- condition_expression = models.CharField('条件表达式', max_length=1000, default='[]', help_text='流转条件表达式,根据表达式中的条件来确定流转的下个状态,格式为[{"expression":"{days} > 3 and {days}<10", "target_state_id":11}] 其中{}用于填充工单的字段key,运算时会换算成实际的值,当符合条件下个状态将变为target_state_id中的值,表达式只支持简单的运算或datetime/time运算.loonflow会以首次匹配成功的条件为准,所以多个条件不要有冲突' )
- attribute_type_id = models.IntegerField('属性类型', default=1, help_text='属性类型,1.同意,2.拒绝,3.其他')
- field_require_check = models.BooleanField('是否校验必填项', default=True, help_text='默认在用户点击操作的时候需要校验工单表单的必填项,如果设置为否则不检查。用于如"退回"属性的操作,不需要填写表单内容')
- alert_enable = models.BooleanField('点击弹窗提示', default=False)
- alert_text = models.CharField('弹窗内容', max_length=100, default='', blank=True)
- class Meta:
- verbose_name = '工作流流转'
- verbose_name_plural = '工作流流转'
- class CustomField(BaseModel):
- """自定义字段, 设定某个工作流有哪些自定义字段"""
- workflow_id = models.IntegerField('工作流id')
- field_type_id = models.IntegerField('类型', help_text='5.字符串,10.整形,15.浮点型,20.布尔,25.日期,30.日期时间,35.单选框,40.多选框,45.下拉列表,50.多选下拉列表,55.文本域,60.用户名, 70.多选的用户名, 80.附件(只保存路径,多个使用逗号隔开)')
- field_key = models.CharField('字段标识', max_length=50, help_text='字段类型请尽量特殊,避免与系统中关键字冲突')
- field_name = models.CharField('字段名称', max_length=50)
- order_id = models.IntegerField('排序', default=0, help_text='工单基础字段在表单中排序为:流水号0,标题20,状态id40,状态名41,创建人80,创建时间100,更新时间120.前端展示工单信息的表单可以根据这个id顺序排列')
- default_value = models.CharField('默认值', null=True, blank=True, max_length=100, help_text='前端展示时,可以将此内容作为表单中的该字段的默认值')
- description = models.CharField('描述', max_length=100, blank=True, default='', help_text='字段的描述信息,对于非文本域字段可以将此内容作为placeholder')
- field_template = models.TextField('文本域模板', default='', blank=True, help_text='文本域类型字段前端显示时可以将此内容作为字段的placeholder')
- boolean_field_display = models.CharField('布尔类型显示名', max_length=100, default='{}', blank=True,
- help_text='当为布尔类型时候,可以支持自定义显示形式。{"1":"是","0":"否"}或{"1":"需要","0":"不需要"},注意数字也需要引号')
- field_choice = models.CharField('radio、checkbox、select的选项', max_length=1000, default='{}', blank=True,
- help_text='radio,checkbox,select,multiselect类型可供选择的选项,格式为json如:{"1":"中国", "2":"美国"},注意数字也需要引号')
- label = models.CharField('标签', max_length=100, blank=True, default='{}', help_text='自定义标签,json格式,调用方可根据标签自行处理特殊场景逻辑,loonflow只保存文本内容')
-
- class Meta:
- verbose_name = '工作流自定义字段'
- verbose_name_plural = '工作流自定义字段'
- def upload_workflow_script(instance, filename):
- """
- 因为脚本中可能会存在一些私密信息,如账号密码等,所以重命名文件,避免可以直接下载此文件
- :param instance:
- :param filename:
- :return:
- """
- upload_to = 'workflow_script'
- ext = filename.split('.')[-1]
- if ext != 'py':
- raise Exception('只支持python脚本')
- filename = '{}.{}'.format(uuid.uuid1(), ext)
- return os.path.join(upload_to, filename)
- class WorkflowScript(BaseModel):
- """
- 流程中执行的脚本
- """
- name = models.CharField('名称', max_length=50)
- saved_name = models.FileField('存储的文件名', upload_to=upload_workflow_script, help_text='请上传python脚本,media/workflow_script/demo_script.py为示例脚本,请参考编写')
- description = models.CharField('描述', max_length=100, null=True, blank=True)
- is_active = models.BooleanField('可用', default=True, help_text='此处可用时,才允许实际执行')
-
- class Meta:
- verbose_name = '工作流脚本'
- verbose_name_plural = '工作流脚本'
- def upload_notice_script(instance, filename):
- """
- 因为通知脚本中可能会存在一些私密信息,如账号密码等,所以重命名文件,避免可以直接下载此文件
- :param instance:
- :param filename:
- :return:
- """
- upload_to = 'notice_script'
- ext = filename.split('.')[-1]
- if ext != 'py':
- raise Exception('只支持python脚本')
- filename = '{}.{}'.format(uuid.uuid1(), ext)
- return os.path.join(upload_to, filename)
- class CustomNotice(BaseModel):
- """
- 自定义通知方式
- """
- name = models.CharField('名称', max_length=50)
- description = models.CharField('描述', max_length=100, null=True, blank=True)
- script = models.FileField('通知脚本', upload_to=upload_notice_script, null=True, blank=True)
- title_template = models.CharField('标题模板', max_length=50, default='你有一个待办工单:{title}', null=True, blank=True, help_text='工单字段的值可以作为参数写到模板中,格式如:你有一个待办工单:{title}')
- content_template = models.CharField('内容模板', max_length=1000, default='标题:{title}, 创建时间:{gmt_created}', null=True, blank=True, help_text='工单字段的值可以作为参数写到模板中,格式如:标题:{title}, 创建时间:{gmt_created}')
-
- class Meta:
- verbose_name = '自定义通知脚本'
- verbose_name_plural = '自定义通知脚本'
|