From 7dc91b5a86051424213aa0370abb8ee7ccafe052 Mon Sep 17 00:00:00 2001 From: caoqianming Date: Mon, 18 Oct 2021 11:00:38 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=A4=E5=AE=9A=E8=A7=84=E5=88=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mtm/migrations/0023_auto_20211018_1057.py | 49 +++++++++++++++++++ hb_server/apps/mtm/models.py | 15 ++++++ hb_server/apps/mtm/serializers.py | 4 +- hb_server/apps/wf/models.py | 18 ++++++- hb_server/apps/wf/services.py | 4 +- hb_server/apps/wf/views.py | 6 +-- 6 files changed, 88 insertions(+), 8 deletions(-) create mode 100644 hb_server/apps/mtm/migrations/0023_auto_20211018_1057.py diff --git a/hb_server/apps/mtm/migrations/0023_auto_20211018_1057.py b/hb_server/apps/mtm/migrations/0023_auto_20211018_1057.py new file mode 100644 index 0000000..9cf0179 --- /dev/null +++ b/hb_server/apps/mtm/migrations/0023_auto_20211018_1057.py @@ -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='子工序'), + ), + ] diff --git a/hb_server/apps/mtm/models.py b/hb_server/apps/mtm/models.py index 7675957..6ebe98a 100644 --- a/hb_server/apps/mtm/models.py +++ b/hb_server/apps/mtm/models.py @@ -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 diff --git a/hb_server/apps/mtm/serializers.py b/hb_server/apps/mtm/serializers.py index 5da68a4..315e464 100644 --- a/hb_server/apps/mtm/serializers.py +++ b/hb_server/apps/mtm/serializers.py @@ -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: diff --git a/hb_server/apps/wf/models.py b/hb_server/apps/wf/models.py index 4540eb0..5427ed2 100644 --- a/hb_server/apps/wf/models.py +++ b/hb_server/apps/wf/models.py @@ -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) \ No newline at end of file + 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('脚本内容') + diff --git a/hb_server/apps/wf/services.py b/hb_server/apps/wf/services.py index a6ec576..0ddfec3 100644 --- a/hb_server/apps/wf/services.py +++ b/hb_server/apps/wf/services.py @@ -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)) diff --git a/hb_server/apps/wf/views.py b/hb_server/apps/wf/views.py index eab077e..3d3f439 100644 --- a/hb_server/apps/wf/views.py +++ b/hb_server/apps/wf/views.py @@ -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字段 需要下个处理人是部门、角色等的情况