判定规则

This commit is contained in:
caoqianming 2021-10-18 11:00:38 +08:00
parent 5ac4ef9985
commit 7dc91b5a86
6 changed files with 88 additions and 8 deletions

View File

@ -0,0 +1,49 @@
# Generated by Django 3.2.6 on 2021-10-18 02:57
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('mtm', '0022_auto_20211014_0944'),
]
operations = [
migrations.AddField(
model_name='recordformfield',
name='high_limit',
field=models.FloatField(blank=True, null=True, verbose_name='上限值'),
),
migrations.AddField(
model_name='recordformfield',
name='high_rule',
field=models.IntegerField(blank=True, choices=[(1, '小于'), (2, '小于等于')], null=True, verbose_name='上限规则'),
),
migrations.AddField(
model_name='recordformfield',
name='low_limit',
field=models.FloatField(blank=True, null=True, verbose_name='下限值'),
),
migrations.AddField(
model_name='recordformfield',
name='low_rule',
field=models.IntegerField(blank=True, choices=[(1, '大于'), (2, '大于等于')], null=True, verbose_name='下限规则'),
),
migrations.AddField(
model_name='recordformfield',
name='need_judge',
field=models.BooleanField(default=False, verbose_name='需要判定'),
),
migrations.AddField(
model_name='recordformfield',
name='rule_expression',
field=models.JSONField(default=list, help_text='判定表达式, 格式为[{"expression":"{value} > 3 and {value}<10"}] 其中{}用于填充工单的字段key,运算时会换算成实际的值符合条件返回true,表达式只支持简单的运算或datetime/time运算.以首次匹配成功的条件为准,所以多个条件不要有冲突', verbose_name='判定表达式'),
),
migrations.AlterField(
model_name='usedstep',
name='step',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='usedstep', to='mtm.step', verbose_name='子工序'),
),
]

View File

@ -110,6 +110,14 @@ class RecordFormField(CommonAModel):
('selects', '多选下拉'),
('textarea', '文本域'),
)
high_rule_choices = (
(1, '小于'),
(2, '小于等于'),
)
low_rule_choices = (
(1, '大于'),
(2, '大于等于'),
)
form = models.ForeignKey(RecordForm, on_delete=models.CASCADE, verbose_name='关联表格')
field_type = models.CharField('类型', max_length=50, choices=field_type_choices)
field_key = models.CharField('字段标识', max_length=50, help_text='字段类型请尽量特殊,避免与系统中关键字冲突')
@ -119,6 +127,13 @@ class RecordFormField(CommonAModel):
field_choice = models.JSONField('radio、checkbox、select的选项', default=dict, blank=True, null=True,
help_text='radio,checkbox,select,multiselect类型可供选择的选项格式为json如:{"1":"中国", "2":"美国"},注意数字也需要引号')
sort = models.IntegerField('排序号', default=1)
need_judge = models.BooleanField('需要判定', default=False)
high_limit = models.FloatField('上限值', null=True, blank=True)
high_rule = models.IntegerField('上限规则', choices=high_rule_choices, null=True, blank=True)
low_limit = models.FloatField('下限值', null=True, blank=True)
low_rule = models.IntegerField('下限规则', choices=low_rule_choices, null=True, blank=True)
rule_expression = models.JSONField('判定表达式', default=list, help_text='判定表达式, 格式为[{"expression":"{value} > 3 and {value}<10"}] 其中{}用于填充的字段key,运算时会换算成实际的值符合条件返回true,表达式只支持简单的运算或datetime/time运算.以首次匹配成功的条件为准,所以多个条件不要有冲突' )
class Meta:
verbose_name = '记录表格字段'
verbose_name_plural = verbose_name

View File

@ -175,7 +175,7 @@ class RecordFormFieldSerializer(serializers.ModelSerializer):
class RecordFormFieldCreateSerializer(serializers.ModelSerializer):
class Meta:
model = RecordFormField
fields = ['form', 'field_type', 'field_key', 'field_name', 'boolean_field_display', 'field_choice', 'sort']
fields = ['form', 'field_type', 'field_key', 'field_name', 'boolean_field_display', 'field_choice', 'sort', 'need_judge', 'high_limit', 'high_rule', 'low_limit', 'low_rule', 'rule_expression']
def validate(self, data):
if RecordFormField.objects.filter(field_key=data['field_key'], form=data['form'], is_deleted=False).exists():
@ -185,7 +185,7 @@ class RecordFormFieldCreateSerializer(serializers.ModelSerializer):
class RecordFormFieldUpdateSerializer(serializers.ModelSerializer):
class Meta:
model = RecordFormField
fields = ['field_type', 'field_name', 'boolean_field_display', 'field_choice', 'sort']
fields = ['field_type', 'field_name', 'boolean_field_display', 'field_choice', 'sort', 'need_judge', 'high_limit', 'high_rule', 'low_limit', 'low_rule', 'rule_expression']
class RecordFormFieldSimpleSerializer(serializers.ModelSerializer):
class Meta:

View File

@ -207,4 +207,20 @@ class TicketFlow(BaseModel):
participant = models.ForeignKey(User, verbose_name='处理人', on_delete=models.SET_NULL, null=True, blank=True, related_name='ticketflow_participant')
state = models.ForeignKey(State, verbose_name='当前状态', default=0, blank=True, on_delete=models.CASCADE)
ticket_data = models.JSONField('工单数据', default=dict, blank=True, help_text='可以用于记录当前表单数据json格式')
intervene_type = models.IntegerField('干预类型', default=0, help_text='流转类型', choices=Transition.intervene_type_choices)
intervene_type = models.IntegerField('干预类型', default=0, help_text='流转类型', choices=Transition.intervene_type_choices)
class WfScript(CommonAModel):
"""
执行脚本
"""
usage_choices =(
(1, '获取处理人'),
(2, '执行操作'),
)
usage = models.IntegerField('脚本用途', default=1, choices=usage_choices)
wait = models.BooleanField('是否等待执行完成', default=True)
name = models.CharField('脚本名称', max_length=100)
workflow = models.ForeignKey(Workflow, verbose_name='关联工作流', null=True, blank=True, on_delete=models.SET_NULL)
content = models.TextField('脚本内容')

View File

@ -141,8 +141,8 @@ class WfService(object):
multi_all_person_dict = {}
destination_participant_type, destination_participant = state.participant_type, state.participant
if destination_participant_type == State.PARTICIPANT_TYPE_FIELD:
destination_participant = ticket_data.get(destination_participant, None) if destination_participant in ticket_data else Ticket.ticket_data.get(destination_participant, None)
destination_participant = ticket_data.get(destination_participant, 0) if destination_participant in ticket_data \
else Ticket.ticket_data.get(destination_participant, 0)
elif destination_participant_type == State.PARTICIPANT_TYPE_DEPT:#单部门
destination_participant = list(User.objects.filter(dept=destination_participant).values_list('id', flat=True))

View File

@ -136,7 +136,7 @@ class TicketViewSet(OptimizationMixin, CreateUpdateCustomMixin, CreateModelMixin
next_state = WfService.get_next_state_by_transition_and_ticket_info(ticket=ticket, transition=transition)
participant_info = WfService.get_ticket_state_participant_info(state=next_state, ticket=ticket, ticket_data=ticket.ticket_data)
destination_participant_type = participant_info.get('destination_participant_type', 0)
destination_participant = participant_info.get('destination_participant', None)
destination_participant = participant_info.get('destination_participant', 0)
multi_all_person = participant_info.get('multi_all_person', {}) # 多人需要全部处理情况
sn = WfService.get_ticket_sn(ticket.workflow) # 流水号
if next_state.type == State.STATE_TYPE_END:
@ -197,7 +197,7 @@ class TicketViewSet(OptimizationMixin, CreateUpdateCustomMixin, CreateModelMixin
if WfService.check_dict_has_all_same_value(multi_all_person):
participant_info = WfService.get_ticket_state_participant_info(destination_state, ticket, data['ticket_data'])
destination_participant_type = participant_info.get('destination_participant_type', 0)
destination_participant = participant_info.get('destination_participant', None)
destination_participant = participant_info.get('destination_participant', 0)
multi_all_person = {}
else:
# 处理人没有没有全部处理完成或者处理动作不一致
@ -211,7 +211,7 @@ class TicketViewSet(OptimizationMixin, CreateUpdateCustomMixin, CreateModelMixin
# 当前处理人类型非全部处理
participant_info = WfService.get_ticket_state_participant_info(destination_state, ticket, data['ticket_data'])
destination_participant_type = participant_info.get('destination_participant_type', 0)
destination_participant = participant_info.get('destination_participant', None)
destination_participant = participant_info.get('destination_participant', 0)
multi_all_person = participant_info.get('multi_all_person', {})
# 更新工单信息:基础字段及自定义字段, add_relation字段 需要下个处理人是部门、角色等的情况