88 lines
7.1 KiB
Python
88 lines
7.1 KiB
Python
from django.db import models
|
||
from django.db.models.base import Model
|
||
import django.utils.timezone as timezone
|
||
from django.db.models.query import QuerySet
|
||
from apps.system.models import CommonAModel, CommonBModel, Organization, User, Dict, File
|
||
from utils.model import SoftModel, BaseModel
|
||
from simple_history.models import HistoricalRecords
|
||
|
||
|
||
class Workflow(CommonAModel):
|
||
"""
|
||
工作流
|
||
"""
|
||
name = models.CharField('名称', max_length=50)
|
||
description = models.CharField('描述', max_length=200)
|
||
view_permission_check = models.BooleanField('查看权限校验', default=True, help_text='开启后,只允许工单的关联人(创建人、曾经的处理人)有权限查看工单')
|
||
title_template = models.CharField('标题模板', max_length=50, default='你有一个待办工单:{title}', null=True, blank=True, help_text='工单字段的值可以作为参数写到模板中,格式如:你有一个待办工单:{title}')
|
||
|
||
class State(BaseModel):
|
||
"""
|
||
状态记录
|
||
"""
|
||
type_choices = (
|
||
(0, '普通类型'),
|
||
(1, '初始状态'),
|
||
(2, '结束状态')
|
||
)
|
||
name = models.CharField('名称', max_length=50)
|
||
workflow = models.ForeignKey(Workflow, on_delete=models.CASCADE, verbose_name='所属工作流')
|
||
is_hidden = models.BooleanField('是否隐藏', default=False, help_text='设置为True时,获取工单步骤api中不显示此状态(当前处于此状态时除外)')
|
||
sort = models.IntegerField('状态顺序', default=0, help_text='用于工单步骤接口时,step上状态的顺序(因为存在网状情况,所以需要人为设定顺序),值越小越靠前')
|
||
type = models.IntegerField('状态类型', default=0, choices=type_choices, help_text='0.普通类型 1.初始状态(用于新建工单时,获取对应的字段必填及transition信息) 2.结束状态(此状态下的工单不得再处理,即没有对应的transition)')
|
||
enable_retreat = models.BooleanField('允许撤回', default=False, help_text='开启后允许工单创建人在此状态直接撤回工单到初始状态')
|
||
|
||
participant_type = models.IntegerField('参与者类型', default=1, blank=True, help_text='0.无处理人,1.个人,2.多人,3.部门,4.角色,5.变量(支持工单创建人,创建人的leader),6.脚本,7.工单的字段内容(如表单中的"测试负责人",需要为用户名或者逗号隔开的多个用户名),8.父工单的字段内容。 初始状态请选择类型5,参与人填creator')
|
||
|
||
|
||
class Transition(BaseModel):
|
||
"""
|
||
工作流流转,定时器,条件(允许跳过), 条件流转与定时器不可同时存在
|
||
"""
|
||
attribute_type_choices = (
|
||
(1, '同意'),
|
||
(2, '拒绝'),
|
||
(3, '其他')
|
||
)
|
||
name = models.CharField('操作', max_length=50)
|
||
workflow = models.ForeignKey(Workflow, on_delete=models.CASCADE, verbose_name='所属工作流')
|
||
timer = models.IntegerField('定时器(单位秒)', default=0, help_text='单位秒。处于源状态X秒后如果状态都没有过变化则自动流转到目标状态。设置时间有效')
|
||
source_state = models.ForeignKey(State, on_delete=models.CASCADE, verbose_name='源状态', related_name='sstate_transition')
|
||
destination_state = models.ForeignKey(State, on_delete=models.CASCADE, verbose_name='目的状态', related_name='dstate_transition')
|
||
condition_expression = models.JSONField('条件表达式', max_length=1000, default='[]', help_text='流转条件表达式,根据表达式中的条件来确定流转的下个状态,格式为[{"expression":"{days} > 3 and {days}<10", "target_state":11}] 其中{}用于填充工单的字段key,运算时会换算成实际的值,当符合条件下个状态将变为target_state_id中的值,表达式只支持简单的运算或datetime/time运算.loonflow会以首次匹配成功的条件为准,所以多个条件不要有冲突' )
|
||
attribute_type = models.IntegerField('属性类型', default=1, choices=attribute_type_choices, help_text='属性类型,1.同意,2.拒绝,3.其他')
|
||
field_require_check = models.BooleanField('是否校验必填项', default=True, help_text='默认在用户点击操作的时候需要校验工单表单的必填项,如果设置为否则不检查。用于如"退回"属性的操作,不需要填写表单内容')
|
||
|
||
|
||
class CustomField(BaseModel):
|
||
"""自定义字段, 设定某个工作流有哪些自定义字段"""
|
||
field_type_choices = (
|
||
('string', '字符串'),
|
||
('int', '整型'),
|
||
('float', '浮点'),
|
||
('bol', '布尔'),
|
||
('date', '日期'),
|
||
('datetime', '日期时间'),
|
||
('radio', '单选'),
|
||
('checkbox', '多选'),
|
||
('select', '单选下拉'),
|
||
('mutiselect', '多选下拉'),
|
||
('textarea', '文本域'),
|
||
('selectuser', '单选用户'),
|
||
('selectusers', '多选用户'),
|
||
('file', '附件')
|
||
)
|
||
workflow = models.ForeignKey(Workflow, on_delete=models.CASCADE, verbose_name='所属工作流')
|
||
field_type = 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)
|
||
sort = 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 = models.CharField('占位符', max_length=100, blank=True, default='', help_text='用户工单详情表单中作为字段的占位符显示')
|
||
field_template = models.TextField('文本域模板', default='', blank=True, help_text='文本域类型字段前端显示时可以将此内容作为字段的placeholder')
|
||
boolean_field_display = models.JSONField('布尔类型显示名', default='{}', blank=True,
|
||
help_text='当为布尔类型时候,可以支持自定义显示形式。{"1":"是","0":"否"}或{"1":"需要","0":"不需要"},注意数字也需要引号')
|
||
field_choice = models.JSONField('radio、checkbox、select的选项', default='{}', blank=True,
|
||
help_text='radio,checkbox,select,multiselect类型可供选择的选项,格式为json如:{"1":"中国", "2":"美国"},注意数字也需要引号')
|
||
label = models.JSONField('标签', blank=True, default='{}', help_text='自定义标签,json格式,调用方可根据标签自行处理特殊场景逻辑,loonflow只保存文本内容') |