Merge branch 'master' of https://e.coding.net/ctcdevteam/cma_search
This commit is contained in:
commit
f5e237b635
|
@ -2,4 +2,4 @@ from django.apps import AppConfig
|
|||
|
||||
|
||||
class AbilityConfig(AppConfig):
|
||||
name = 'ability'
|
||||
name = 'apps.ability'
|
||||
|
|
|
@ -2,4 +2,4 @@ from django.apps import AppConfig
|
|||
|
||||
|
||||
class QualityConfig(AppConfig):
|
||||
name = 'consulting'
|
||||
name = 'apps.consulting'
|
||||
|
|
|
@ -2,4 +2,4 @@ from django.apps import AppConfig
|
|||
|
||||
|
||||
class CrmConfig(AppConfig):
|
||||
name = 'crm'
|
||||
name = 'apps.crm'
|
||||
|
|
|
@ -2,4 +2,4 @@ from django.apps import AppConfig
|
|||
|
||||
|
||||
class ExamConfig(AppConfig):
|
||||
name = 'exam'
|
||||
name = 'apps.exam'
|
||||
|
|
|
@ -2,5 +2,5 @@ from django.apps import AppConfig
|
|||
|
||||
|
||||
class OpsConfig(AppConfig):
|
||||
name = 'ops'
|
||||
name = 'apps.ops'
|
||||
verbose_name = '系统监控'
|
||||
|
|
|
@ -2,4 +2,4 @@ from django.apps import AppConfig
|
|||
|
||||
|
||||
class QualityConfig(AppConfig):
|
||||
name = 'quality'
|
||||
name = 'apps.quality'
|
||||
|
|
|
@ -2,4 +2,4 @@ from django.apps import AppConfig
|
|||
|
||||
|
||||
class SupervisionConfig(AppConfig):
|
||||
name = 'supervision'
|
||||
name = 'apps.supervision'
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
# Generated by Django 3.0.5 on 2023-05-22 07:15
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('supervision', '0039_auto_20230517_1419'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='task2',
|
||||
name='state',
|
||||
field=models.PositiveSmallIntegerField(choices=[(10, '创建中'), (20, '进行中'), (30, '已关闭')], default=10, verbose_name='任务状态'),
|
||||
),
|
||||
]
|
|
@ -0,0 +1,18 @@
|
|||
# Generated by Django 3.0.5 on 2023-05-22 07:18
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('supervision', '0040_auto_20230522_1515'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='task2',
|
||||
name='cycle',
|
||||
field=models.PositiveSmallIntegerField(blank=True, default=0, help_text='1-6个周期', verbose_name='所属周期'),
|
||||
),
|
||||
]
|
|
@ -0,0 +1,18 @@
|
|||
# Generated by Django 3.2.12 on 2023-05-23 06:52
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('supervision', '0041_auto_20230522_1518'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='pgoaldept',
|
||||
name='goal_value_b',
|
||||
field=models.FloatField(blank=True, null=True, verbose_name='设定值'),
|
||||
),
|
||||
]
|
|
@ -0,0 +1,18 @@
|
|||
# Generated by Django 3.2.12 on 2023-05-26 08:46
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('supervision', '0042_alter_pgoaldept_goal_value_b'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='pgoaldept',
|
||||
name='goal_value_a',
|
||||
field=models.FloatField(blank=True, null=True, verbose_name='基础值'),
|
||||
),
|
||||
]
|
|
@ -0,0 +1,18 @@
|
|||
# Generated by Django 3.2.12 on 2023-05-29 00:38
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('supervision', '0043_alter_pgoaldept_goal_value_a'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RenameField(
|
||||
model_name='task2do',
|
||||
old_name='num_ocheck',
|
||||
new_name='num_oinspect',
|
||||
),
|
||||
]
|
|
@ -0,0 +1,18 @@
|
|||
# Generated by Django 3.2.12 on 2023-05-29 01:39
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('supervision', '0044_rename_num_ocheck_task2do_num_oinspect'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='rc',
|
||||
name='remark',
|
||||
field=models.TextField(blank=True, null=True, verbose_name='备注'),
|
||||
),
|
||||
]
|
|
@ -0,0 +1,38 @@
|
|||
# Generated by Django 3.2.12 on 2023-05-29 04:06
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('supervision', '0045_rc_remark'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='pt',
|
||||
name='handle_result',
|
||||
field=models.PositiveSmallIntegerField(choices=[(0, '/'), (10, '已整改'), (20, '被暂停'), (30, '已被撤销认可资格')], default=0, help_text="((0, '/'), (10, '已整改'), (20, '被暂停'), (30, '已被撤销认可资格'))", verbose_name='处理结果'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='oinspect',
|
||||
name='cate',
|
||||
field=models.PositiveSmallIntegerField(choices=[(10, '市场监管部门检查'), (20, '行业主管部门检查'), (30, '其他检查')], default=30, help_text="((10, '市场监管部门检查'), (20, '行业主管部门检查'), (30, '其他检查'))", verbose_name='检查分类'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='pt',
|
||||
name='result',
|
||||
field=models.PositiveSmallIntegerField(choices=[(10, '满意'), (20, '有问题'), (30, '不满意')], default=10, help_text="((10, '满意'), (20, '有问题'), (30, '不满意'))", verbose_name='结果'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='risk',
|
||||
name='level',
|
||||
field=models.PositiveSmallIntegerField(choices=[(10, '主要风险'), (20, '严重风险'), (30, '重大风险')], default=10, help_text="((10, '主要风险'), (20, '严重风险'), (30, '重大风险'))", verbose_name='风险等级'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='risk',
|
||||
name='state',
|
||||
field=models.PositiveSmallIntegerField(choices=[(10, '未整改'), (20, '整改中'), (30, '整改完成')], default=10, help_text="((10, '未整改'), (20, '整改中'), (30, '整改完成'))", verbose_name='整改状态'),
|
||||
),
|
||||
]
|
|
@ -0,0 +1,28 @@
|
|||
# Generated by Django 3.2.12 on 2023-05-31 08:29
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('supervision', '0046_auto_20230529_1206'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='task2do',
|
||||
name='num_acc',
|
||||
field=models.PositiveSmallIntegerField(blank=True, null=True, verbose_name='重大质量事故'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='task2do',
|
||||
name='num_complaint_10',
|
||||
field=models.PositiveSmallIntegerField(blank=True, null=True, verbose_name='满意客户投诉数'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='task2do',
|
||||
name='num_pt_10',
|
||||
field=models.PositiveSmallIntegerField(blank=True, null=True, verbose_name='满意能力验证数'),
|
||||
),
|
||||
]
|
|
@ -1,6 +1,6 @@
|
|||
from django.db import models
|
||||
from utils.model import BaseModel
|
||||
from apps.system.models import CommonAModel, CommonBModel, Organization, User, Dict, File
|
||||
from apps.system.models import CommonAModel, CommonBModel, Organization, User, Dict, File, CommonADModel, CommonBDModel
|
||||
from django.contrib.postgres.fields import JSONField
|
||||
# Create your models here.
|
||||
|
||||
|
@ -114,7 +114,7 @@ class TAction(CommonAModel):
|
|||
value_old = JSONField('原值', null=True, blank=True, default=dict)
|
||||
value_new = JSONField('新值', null=True, blank=True, default=dict)
|
||||
|
||||
class Pgoal(CommonAModel):
|
||||
class Pgoal(CommonADModel):
|
||||
"""
|
||||
基础目标
|
||||
"""
|
||||
|
@ -137,7 +137,7 @@ class Pgoal(CommonAModel):
|
|||
pgoal_4_file = models.ForeignKey(File, related_name='pgoal_4_file', on_delete=models.SET_NULL, null=True, blank=True)
|
||||
pgoal_5_file = models.ForeignKey(File, related_name='pgoal_5_file', on_delete=models.SET_NULL, null=True, blank=True)
|
||||
|
||||
class Task2(CommonAModel):
|
||||
class Task2(CommonADModel):
|
||||
"""
|
||||
报送任务2
|
||||
"""
|
||||
|
@ -157,46 +157,49 @@ class Task2(CommonAModel):
|
|||
)
|
||||
|
||||
year = models.PositiveSmallIntegerField('年份', default=2023)
|
||||
cycle = models.PositiveSmallIntegerField('所属周期', default=0, help_text='1-6个周期')
|
||||
cycle = models.PositiveSmallIntegerField('所属周期', default=0, help_text='1-6个周期', blank=True)
|
||||
type = models.PositiveSmallIntegerField('任务类型', choices=TASK2_TYPES, default=20)
|
||||
state = models.PositiveSmallIntegerField('任务状态', choices=TASK2_STATES, default=20)
|
||||
state = models.PositiveSmallIntegerField('任务状态', choices=TASK2_STATES, default=10)
|
||||
depts = models.ManyToManyField(Organization, verbose_name='执行公司', through='supervision.task2do', blank=True)
|
||||
|
||||
|
||||
class Task2Do(CommonBModel):
|
||||
class Task2Do(CommonBDModel):
|
||||
"""任务执行情况
|
||||
"""
|
||||
task2 = models.ForeignKey(Task2, verbose_name='关联任务', on_delete=models.CASCADE, related_name='task2dept_task2')
|
||||
count_up = models.PositiveSmallIntegerField('完成上报内容数', default=0)
|
||||
count_all = models.PositiveSmallIntegerField('需上报内容数', default=8)
|
||||
count_all = models.PositiveSmallIntegerField('需上报内容数', default=9)
|
||||
|
||||
num_issue = models.PositiveSmallIntegerField('已发放报告数量', null=True, blank=True)
|
||||
num_expect = models.PositiveSmallIntegerField('应发报告数', null=True, blank=True)
|
||||
num_acc = models.PositiveSmallIntegerField('重大质量事故', null=True, blank=True)
|
||||
|
||||
num_error = models.PositiveSmallIntegerField('不准确报告数', null=True, blank=True)
|
||||
num_overdue = models.PositiveSmallIntegerField('超期报告数', null=True, blank=True)
|
||||
num_complaint = models.PositiveSmallIntegerField('客户投诉数', null=True, blank=True)
|
||||
num_complaint_10 = models.PositiveSmallIntegerField('满意客户投诉数', null=True, blank=True)
|
||||
num_pt = models.PositiveSmallIntegerField('能力验证数', null=True, blank=True)
|
||||
num_pt_10 = models.PositiveSmallIntegerField('满意能力验证数', null=True, blank=True)
|
||||
num_risk = models.PositiveSmallIntegerField('风险识别数', null=True, blank=True)
|
||||
num_ocheck = models.PositiveSmallIntegerField('外部检查数', null=True, blank=True)
|
||||
num_oinspect = models.PositiveSmallIntegerField('外部检查数', null=True, blank=True)
|
||||
|
||||
|
||||
class PgoalDept(CommonBModel):
|
||||
class PgoalDept(CommonBDModel):
|
||||
"""企业年度目标值
|
||||
"""
|
||||
year = models.PositiveSmallIntegerField('年份')
|
||||
goal_name = models.CharField('目标名称', max_length=100)
|
||||
goal_key = models.CharField('目标key值', max_length=100, default='other', blank=True)
|
||||
goal_value_a = models.FloatField('基础值')
|
||||
goal_value_a = models.FloatField('基础值', null=True, blank=True)
|
||||
goal_o_file = models.ForeignKey(File, related_name='goal_o_file', verbose_name='原文件ID', on_delete=models.SET_NULL, null=True, blank=True)
|
||||
goal_value_b = models.FloatField('设定值')
|
||||
goal_value_b = models.FloatField('设定值', null=True, blank=True)
|
||||
goal_value_c = models.FloatField('实际值', null=True, blank=True)
|
||||
goal_file = models.ForeignKey(File, related_name='goal_file', verbose_name='当前文件ID', on_delete=models.SET_NULL, null=True, blank=True)
|
||||
goal_files = models.ManyToManyField(File, related_name='goal_files', verbose_name='历史文件', blank=True)
|
||||
task2do = models.ForeignKey('supervision.task2do', verbose_name= '关联任务执行', on_delete=models.SET_NULL, null=True, blank=True)
|
||||
|
||||
|
||||
class Rc(CommonBModel):
|
||||
class Rc(CommonBDModel):
|
||||
"""报告或证书
|
||||
"""
|
||||
etype_choices = (
|
||||
|
@ -211,9 +214,10 @@ class Rc(CommonBModel):
|
|||
date_expect = models.DateField('预计发放日期', null=True, blank=True)
|
||||
date_issue = models.DateField('实际发放日期', null=True, blank=True)
|
||||
task2do = models.ForeignKey('supervision.task2do', verbose_name= '关联任务执行', on_delete=models.SET_NULL, null=True, blank=True)
|
||||
remark = models.TextField('备注', null=True, blank=True)
|
||||
|
||||
|
||||
class Complaint(CommonBModel):
|
||||
class Complaint(CommonBDModel):
|
||||
"""客户投诉
|
||||
"""
|
||||
complainant = models.CharField('投诉人', max_length=100)
|
||||
|
@ -224,7 +228,7 @@ class Complaint(CommonBModel):
|
|||
task2do = models.ForeignKey('supervision.task2do', verbose_name= '关联任务执行', on_delete=models.SET_NULL, null=True, blank=True)
|
||||
|
||||
|
||||
class Pt(CommonBModel):
|
||||
class Pt(CommonBDModel):
|
||||
"""能力验证
|
||||
"""
|
||||
pt_result_choices = (
|
||||
|
@ -232,15 +236,22 @@ class Pt(CommonBModel):
|
|||
(20, '有问题'),
|
||||
(30, '不满意')
|
||||
)
|
||||
pt_hresult_choices = (
|
||||
(0, '/'),
|
||||
(10, '已整改'),
|
||||
(20, '被暂停'),
|
||||
(30, '已被撤销认可资格')
|
||||
)
|
||||
name = models.CharField('名称', max_length=100)
|
||||
number = models.CharField('编号', max_length=100)
|
||||
organizer = models.CharField('组织方', max_length=100)
|
||||
params = models.TextField('参加参数名称')
|
||||
result = models.PositiveSmallIntegerField('结果', choices=pt_result_choices, default=10)
|
||||
result = models.PositiveSmallIntegerField('结果', choices=pt_result_choices, default=10, help_text=str(pt_result_choices))
|
||||
handle_result = models.PositiveSmallIntegerField('处理结果', choices = pt_hresult_choices, default=0, help_text=str(pt_hresult_choices))
|
||||
task2do = models.ForeignKey('supervision.task2do', verbose_name= '关联任务执行', on_delete=models.SET_NULL, null=True, blank=True)
|
||||
|
||||
|
||||
class Risk(CommonBModel):
|
||||
class Risk(CommonBDModel):
|
||||
"""风险识别
|
||||
"""
|
||||
risk_level_choices = (
|
||||
|
@ -254,13 +265,13 @@ class Risk(CommonBModel):
|
|||
(30, '整改完成')
|
||||
)
|
||||
content = models.TextField('内容')
|
||||
level = models.PositiveSmallIntegerField('风险等级', choices=risk_level_choices, default=10)
|
||||
level = models.PositiveSmallIntegerField('风险等级', choices=risk_level_choices, default=10, help_text=str(risk_level_choices))
|
||||
code = models.CharField('风险代码', max_length=100)
|
||||
state = models.PositiveSmallIntegerField('整改状态', choices=risk_state_choices, default=10)
|
||||
state = models.PositiveSmallIntegerField('整改状态', choices=risk_state_choices, default=10, help_text=str(risk_state_choices))
|
||||
task2do = models.ForeignKey('supervision.task2do', verbose_name= '关联任务执行', on_delete=models.SET_NULL, null=True, blank=True)
|
||||
|
||||
|
||||
class Oinspect(CommonBModel):
|
||||
class Oinspect(CommonBDModel):
|
||||
"""外部检查
|
||||
"""
|
||||
oinspect_cate_choices = (
|
||||
|
@ -268,7 +279,7 @@ class Oinspect(CommonBModel):
|
|||
(20, '行业主管部门检查'),
|
||||
(30, '其他检查')
|
||||
)
|
||||
cate = models.PositiveSmallIntegerField('检查分类', choices=oinspect_cate_choices, default=30)
|
||||
cate = models.PositiveSmallIntegerField('检查分类', choices=oinspect_cate_choices, default=30, help_text=str(oinspect_cate_choices))
|
||||
checker = models.CharField('检查方', max_length=100)
|
||||
date_inspect = models.DateField('检查日期')
|
||||
result = models.TextField('检查结果')
|
||||
|
|
|
@ -112,7 +112,7 @@ class Task2Serializer(serializers.ModelSerializer):
|
|||
read_only_fields = ['create_time', 'update_time', 'create_by', 'update_by', 'belong_dept', 'state', 'is_deleted', 'depts']
|
||||
|
||||
def update(self, instance, validated_data):
|
||||
validated_data.pop('type') # type不可编辑
|
||||
validated_data.pop('type', None) # type不可编辑
|
||||
if instance.state != Task2.TASK2_CLOSE:
|
||||
raise ParseError('非创建状态不可编辑')
|
||||
return super().update(instance, validated_data)
|
||||
|
@ -131,23 +131,35 @@ class Task2DoSerializer(serializers.ModelSerializer):
|
|||
class ValidateMixin:
|
||||
def validate(self, attrs):
|
||||
task2do = attrs.get('task2do', None)
|
||||
attrs['create_by'] = self.context['request'].user
|
||||
attrs['belong_dept'] = self.context['request'].user.dept
|
||||
if task2do:
|
||||
if task2do.task2.state == Task2.TASK2_CLOSE:
|
||||
raise ParseError('任务已关闭不可处理')
|
||||
attrs['year'] = task2do.task2.year
|
||||
attrs['belong_dept'] = task2do.task2.belong_dept
|
||||
attrs['belong_dept'] = task2do.belong_dept
|
||||
return attrs
|
||||
|
||||
class BaseMeta:
|
||||
fields = '__all__'
|
||||
read_only_fields = ['create_time', 'update_time', 'create_by', 'update_by', 'is_deleted']
|
||||
read_only_fields = ['create_time', 'update_time', 'create_by', 'update_by', 'is_deleted', 'belong_dept']
|
||||
|
||||
class PgoalDeptSerializer(ValidateMixin, serializers.ModelSerializer):
|
||||
class PgoalDeptSerializer(serializers.ModelSerializer):
|
||||
goal_file_ = FileSimpleSerializer(source='goal_file', read_only=True)
|
||||
goal_o_file_ = FileSimpleSerializer(source='goal_o_file', read_only=True)
|
||||
class Meta(BaseMeta):
|
||||
model = PgoalDept
|
||||
read_only_fields = BaseMeta.read_only_fields + ['goal_value_a', 'goal_value_c', 'goal_files', 'goal_key']
|
||||
read_only_fields = BaseMeta.read_only_fields + ['goal_value_a', 'goal_value_c', 'goal_files', 'goal_key', 'goal_file_', 'goal_o_file', 'goal_o_file_']
|
||||
|
||||
def validate(self, attrs):
|
||||
task2do = attrs.get('task2do', None)
|
||||
attrs['create_by'] = self.context['request'].user
|
||||
attrs['belong_dept'] = self.context['request'].user.dept
|
||||
if task2do:
|
||||
if task2do.task2.state == Task2.TASK2_CLOSE:
|
||||
raise ParseError('任务已关闭不可处理')
|
||||
attrs['year'] = task2do.task2.year
|
||||
attrs['belong_dept'] = task2do.belong_dept
|
||||
return attrs
|
||||
|
||||
class RcSerializer(ValidateMixin, serializers.ModelSerializer):
|
||||
|
||||
|
@ -177,3 +189,17 @@ class OinspectSerializer(ValidateMixin, serializers.ModelSerializer):
|
|||
|
||||
class NoRecordSerializer(serializers.Serializer):
|
||||
key = serializers.ChoiceField(label='字段key', choices=['num_error', 'num_overdue', 'num_complaint', 'num_pt', 'num_risk', 'num_oinspect'])
|
||||
|
||||
|
||||
class UpdateFieldSerializer(serializers.ModelSerializer):
|
||||
|
||||
class Meta:
|
||||
model = Task2Do
|
||||
fields = ['num_issue', 'num_expect', 'num_acc']
|
||||
extra_kwargs = {'num_issue': {'required': True}, 'num_expect': {'required': True}, 'num_acc': {'required': True}}
|
||||
|
||||
|
||||
|
||||
class ImpSerializer(serializers.Serializer):
|
||||
path = serializers.CharField(label='文件地址')
|
||||
task2do = serializers.PrimaryKeyRelatedField(label='关联task2do的ID值', queryset = Task2Do.objects.all())
|
|
@ -11,6 +11,7 @@ from rest_framework.mixins import ListModelMixin, CreateModelMixin, UpdateModelM
|
|||
from rest_framework.response import Response
|
||||
from rest_framework.viewsets import GenericViewSet, ModelViewSet
|
||||
from utils.pagination import PageOrNot
|
||||
from openpyxl import load_workbook
|
||||
|
||||
from apps.system.mixins import CreateUpdateCustomMixin
|
||||
from apps.system.models import Organization
|
||||
|
@ -410,6 +411,7 @@ class PogalViewSet(CreateUpdateCustomMixin, ModelViewSet):
|
|||
return PgoalCreateUpdateSerializer
|
||||
return super().get_serializer_class()
|
||||
|
||||
|
||||
class Task2ViewSet(CreateUpdateCustomMixin, ModelViewSet):
|
||||
perms_map = {'get': '*', 'post': 'task2',
|
||||
'put': 'task2', 'delete': 'task2'}
|
||||
|
@ -434,7 +436,7 @@ class Task2ViewSet(CreateUpdateCustomMixin, ModelViewSet):
|
|||
return Response()
|
||||
|
||||
@transaction.atomic
|
||||
@action(methods=['put'], detail=True, perms_map = {'put':'task2'})
|
||||
@action(methods=['put'], detail=True, perms_map = {'put':'task2'}, serializer_class=serializers.Serializer)
|
||||
def start(self, request, *args, **kwargs):
|
||||
"""
|
||||
开始执行
|
||||
|
@ -450,13 +452,13 @@ class Task2ViewSet(CreateUpdateCustomMixin, ModelViewSet):
|
|||
except:
|
||||
raise ParseError('未配置年度基础目标')
|
||||
for i in tds:
|
||||
for k, v in enumerate(Pgoal.basedict):
|
||||
pds = PgoalDept.objects.filter(year=i.year, task2do=i, goal_key=k)
|
||||
for key in Pgoal.basedict:
|
||||
pds = PgoalDept.objects.filter(task2do=i, goal_key=key)
|
||||
if pds.exists():
|
||||
pds.update(**{'goal_name': v, 'goal_value_a': getattr(pg, k), 'goal_o_file': getattr(pg, k+'_file')})
|
||||
pds.update(**{'goal_name': Pgoal.basedict[key], 'goal_value_a': getattr(pg, key), 'goal_o_file': getattr(pg, key+'_file')})
|
||||
else:
|
||||
PgoalDept.objects.create(**{'year': i.year, 'task2do': i, 'belong_dept': i.belong_dept,
|
||||
'goal_name': v, 'goal_key': k, 'goal_value_a': getattr(pg, k), 'goal_o_file': getattr(pg, k+'_file')})
|
||||
PgoalDept.objects.create(**{'year': i.task2.year, 'task2do': i, 'belong_dept': i.belong_dept,
|
||||
'goal_name': Pgoal.basedict[key], 'goal_key': key, 'goal_value_a': getattr(pg, key), 'goal_o_file': getattr(pg, key+'_file')})
|
||||
obj.state = Task2.TASK2_DOING
|
||||
obj.save()
|
||||
return Response()
|
||||
|
@ -471,11 +473,11 @@ class Task2ViewSet(CreateUpdateCustomMixin, ModelViewSet):
|
|||
sr = Task2DeptsSerializer(data=request.data)
|
||||
sr.is_valid(raise_exception=True)
|
||||
vdata = sr.validated_data
|
||||
count_all = 8
|
||||
count_all = 9
|
||||
if task2.type == Task2.TASK2_F:
|
||||
count_all = 5
|
||||
for i in vdata['ids']:
|
||||
Task2Do.objects.get_or_create(task2=task2, belong_dept=i, defaults={'task2': task2, 'belong_dept': i, 'count_all': count_all})
|
||||
Task2Do.objects.get_or_create(task2=task2, belong_dept=i, defaults={'task2': task2, 'belong_dept': i, 'count_all': count_all, 'create_by': self.request.user})
|
||||
return Response()
|
||||
|
||||
|
||||
|
@ -484,7 +486,7 @@ class Task2DoViewSet(ListModelMixin, GenericViewSet):
|
|||
queryset = Task2Do.objects.select_related('belong_dept', 'task2').all()
|
||||
serializer_class = Task2DoSerializer
|
||||
ordering = ['belong_dept__sort']
|
||||
|
||||
filterset_fields = ['task2', 'belong_dept', 'task2__year', 'task2__cycle']
|
||||
cfields = ['num_issue', 'num_expect', 'num_error', 'num_overdue', 'num_complaint', 'num_pt', 'num_risk', 'num_oinspect']
|
||||
|
||||
@classmethod
|
||||
|
@ -498,19 +500,38 @@ class Task2DoViewSet(ListModelMixin, GenericViewSet):
|
|||
instance.count_up = count_up
|
||||
instance.save()
|
||||
|
||||
@action(methods=['put'], detail=True, perms_map = {'post':'task2do'}, serializer_class=NoRecordSerializer)
|
||||
@action(methods=['put'], detail=True, perms_map = {'put':'task2do'}, serializer_class=UpdateFieldSerializer)
|
||||
def save_num(self, request, *args, **kwargs):
|
||||
"""保存数值
|
||||
|
||||
保存数值
|
||||
"""
|
||||
obj = self.get_object()
|
||||
obj.num_issue = request.data.get('num_issue', 0)
|
||||
obj.num_expect = request.data.get('num_expect', 0)
|
||||
obj.num_acc = request.data.get('num_acc', 0)
|
||||
obj.update_by = request.user
|
||||
obj.save()
|
||||
self.countup_task2do(obj)
|
||||
return Response()
|
||||
|
||||
@action(methods=['put'], detail=True, perms_map = {'put':'task2do'}, serializer_class=NoRecordSerializer)
|
||||
def no_record(self, request, *args, **kwargs):
|
||||
"""没有记录
|
||||
|
||||
没有记录
|
||||
"""
|
||||
obj = self.get_object()
|
||||
setattr(obj, request.data.get('key'), 0)
|
||||
theattr = getattr(obj, request.data.get('key'), None)
|
||||
if theattr is None:
|
||||
theattr = 0
|
||||
else:
|
||||
raise ParseError('已有记录')
|
||||
obj.save()
|
||||
self.countup_task2do(obj)
|
||||
return Response()
|
||||
|
||||
@action(methods=['get'], detail=False, perms_map = {'post':'task2do'})
|
||||
@action(methods=['get'], detail=False, perms_map = {'get':'task2do'})
|
||||
def my(self, request, *args, **kwargs):
|
||||
"""我的任务
|
||||
|
||||
|
@ -523,7 +544,7 @@ class Task2DoViewSet(ListModelMixin, GenericViewSet):
|
|||
else:
|
||||
mydept = request.user.dept
|
||||
belong_depts = get_child_queryset2(mydept)
|
||||
queryset = queryset.filter(belong_dept = belong_depts)
|
||||
queryset = queryset.filter(belong_dept__in = belong_depts)
|
||||
serializer = Task2DoSerializer(queryset, many=True)
|
||||
return Response(serializer.data)
|
||||
|
||||
|
@ -532,80 +553,233 @@ class Domixin:
|
|||
perms_map = {'get': '*', 'put': 'task2do', 'post': 'task2do', 'delete': 'task2do'}
|
||||
ordering = ['create_time']
|
||||
ordering_fields = ['create_time', 'belong_dept__sort']
|
||||
filterset_fields = ['task2do', 'task2do__task2', 'task2do__belong_dept']
|
||||
|
||||
def countnum_task2do_field(self, task2do):
|
||||
for k, v in self.count_dict:
|
||||
setattr(task2do, k, self.queryset.model.objects.filter({**{'task2do': task2do}, **v}).count())
|
||||
for k, v in self.count_dict.items():
|
||||
setattr(task2do, k, self.queryset.model.objects.filter(**{**{'task2do': task2do}, **v}).count())
|
||||
task2do.save()
|
||||
# 更新count_up字段
|
||||
Task2DoViewSet.countup_task2do(task2do)
|
||||
|
||||
def countup_task2do(self, task2do):
|
||||
if task2do.task2.type == Task2.TASK2_F:
|
||||
task2do.count_up = PgoalDept.objects.filter(task2do=task2do).count()
|
||||
task2do.count_up = PgoalDept.objects.filter(task2do=task2do).exclude(goal_value_b=None).count()
|
||||
task2do.save()
|
||||
elif task2do.task2.type == Task2.TASK2_S:
|
||||
self.countnum_task2do_field(task2do)
|
||||
|
||||
@transaction.atomic
|
||||
def perform_create(self, serializer):
|
||||
instance = super().perform_create(serializer)
|
||||
instance = serializer.save()
|
||||
self.countup_task2do(instance.task2do)
|
||||
|
||||
@transaction.atomic
|
||||
def perform_destroy(self, instance):
|
||||
task2do = instance.task2do
|
||||
instance.delete(soft=False)
|
||||
instance.delete()
|
||||
self.countup_task2do(task2do)
|
||||
|
||||
|
||||
class PgoalDeptViewSet(Domixin, CreateUpdateCustomMixin, ModelViewSet):
|
||||
queryset = PgoalDept.objects.all()
|
||||
serializer_class = PgoalDeptSerializer
|
||||
filterset_fields = ['goal_key', 'belong_dept', 'year', 'task2do']
|
||||
|
||||
def perform_update(self, serializer):
|
||||
instance = super().perform_update(serializer)
|
||||
instance = serializer.save()
|
||||
goal_file = instance.goal_file
|
||||
if goal_file:
|
||||
instance.goal_files.add(goal_file)
|
||||
|
||||
class ImpMixin:
|
||||
def get_enum(self, val, atuple, ind):
|
||||
for i in atuple:
|
||||
if i[1] == val:
|
||||
return i[0]
|
||||
raise ParseError('第{}: 请选择固定选项值'.format(ind))
|
||||
|
||||
class RcViewSet(Domixin, CreateUpdateCustomMixin, ModelViewSet):
|
||||
def make_data(self, data, sheet, i, etype):
|
||||
raise NotImplementedError()
|
||||
|
||||
def gen_imp_view(self, request, start: int, mySerializer, etype=0):
|
||||
sr = ImpSerializer(data=request.data)
|
||||
sr.is_valid(raise_exception=True)
|
||||
vdata = sr.validated_data
|
||||
path = vdata['path']
|
||||
if not path.endswith('.xlsx'):
|
||||
raise ParseError('请提供xlsx格式文件')
|
||||
task2do = vdata['task2do']
|
||||
fullpath = settings.BASE_DIR + path
|
||||
wb = load_workbook(fullpath,data_only=True)
|
||||
sheet = wb.worksheets[0]
|
||||
datalist = []
|
||||
i = start
|
||||
while sheet['b'+str(i)].value:
|
||||
data = {}
|
||||
data['task2do'] = task2do.id
|
||||
data = self.make_data(data, sheet, i, etype)
|
||||
datalist.append(data)
|
||||
i = i + 1
|
||||
sr = mySerializer(data=datalist, many=True)
|
||||
sr.is_valid()
|
||||
err_msg = ''
|
||||
for ind, val in enumerate(sr.errors):
|
||||
if val:
|
||||
for i in val:
|
||||
err_msg = '第{}行: {}'.format(5+ind, i + str(val[i][0]))
|
||||
if err_msg != '':
|
||||
raise ParseError(err_msg)
|
||||
else:
|
||||
sr.save(create_by=request.user)
|
||||
return Response()
|
||||
|
||||
class RcViewSet(ImpMixin, Domixin, CreateUpdateCustomMixin, ModelViewSet):
|
||||
queryset = Rc.objects.all()
|
||||
serializer_class = RcSerializer
|
||||
count_dict = {
|
||||
"num_error": {'etype': 10},
|
||||
"num_overdue": {'etype': 20}
|
||||
}
|
||||
filterset_fields = ['etype', 'task2do', 'task2do__belong_dept', 'task2do__task2__year']
|
||||
|
||||
|
||||
class ComplaintViewSet(Domixin, CreateUpdateCustomMixin, ModelViewSet):
|
||||
def make_data(self, data, sheet, i, etype):
|
||||
data['etype'] = etype
|
||||
if etype == 10:
|
||||
data['number'] = sheet['b'+str(i)].value
|
||||
data['number_correct'] = sheet['c'+str(i)].value
|
||||
data['reason_error'] = sheet['d'+str(i)].value
|
||||
data['date_issue'] = sheet['e'+str(i)].value
|
||||
else:
|
||||
data['number'] = sheet['b'+str(i)].value
|
||||
data['date_accept'] = sheet['c'+str(i)].value
|
||||
data['date_expect'] = sheet['d'+str(i)].value
|
||||
data['date_issue'] = sheet['e'+str(i)].value
|
||||
data['remark'] = sheet['f'+str(i)].value
|
||||
return data
|
||||
|
||||
@action(methods=['post'], detail=False, perms_map = {'post':'task2do'}, serializer_class=ImpSerializer)
|
||||
@transaction.atomic
|
||||
def imp_error(self, request, *args, **kwargs):
|
||||
"""导入表格
|
||||
|
||||
导入表格
|
||||
"""
|
||||
return self.gen_imp_view(request, 5, RcSerializer, 10)
|
||||
|
||||
|
||||
@action(methods=['post'], detail=False, perms_map = {'post':'task2do'}, serializer_class=ImpSerializer)
|
||||
@transaction.atomic
|
||||
def imp_overdue(self, request, *args, **kwargs):
|
||||
"""导入表格
|
||||
|
||||
导入表格
|
||||
"""
|
||||
return self.gen_imp_view(request, 5, RcSerializer, 20)
|
||||
|
||||
|
||||
|
||||
class ComplaintViewSet(ImpMixin, Domixin, CreateUpdateCustomMixin, ModelViewSet):
|
||||
queryset = Complaint.objects.all()
|
||||
serializer_class = ComplaintSerializer
|
||||
count_dict = {
|
||||
"num_complaint": {}
|
||||
"num_complaint": {},
|
||||
"num_complaint_10": {'is_satisfied': True}
|
||||
}
|
||||
filterset_fields = ['task2do', 'task2do__belong_dept', 'task2do__task2__year']
|
||||
|
||||
def make_data(self, data, sheet, i, etype):
|
||||
data['complainant'] = sheet['b'+str(i)].value
|
||||
data['date_occurrence'] = sheet['c'+str(i)].value
|
||||
data['content'] = sheet['d'+str(i)].value
|
||||
data['date_feedback'] = sheet['e'+str(i)].value
|
||||
data['is_satisfied'] = True if sheet['f'+str(i)].value == '是' else False
|
||||
return data
|
||||
|
||||
@action(methods=['post'], detail=False, perms_map = {'post':'task2do'}, serializer_class=ImpSerializer)
|
||||
@transaction.atomic
|
||||
def imp(self, request, *args, **kwargs):
|
||||
"""导入表格
|
||||
|
||||
导入表格
|
||||
"""
|
||||
return self.gen_imp_view(request, 5, ComplaintSerializer)
|
||||
|
||||
|
||||
class PtViewSet(Domixin, CreateUpdateCustomMixin, ModelViewSet):
|
||||
class PtViewSet(ImpMixin, Domixin, CreateUpdateCustomMixin, ModelViewSet):
|
||||
queryset = Pt.objects.all()
|
||||
serializer_class = PtSerializer
|
||||
count_dict = {
|
||||
"num_pt": {}
|
||||
"num_pt": {},
|
||||
"num_pt_10": {'result': 10}
|
||||
}
|
||||
filterset_fields = ['task2do', 'task2do__belong_dept', 'task2do__task2__year']
|
||||
|
||||
def make_data(self, data, sheet, i, etype):
|
||||
data['name'] = sheet['b'+str(i)].value
|
||||
data['number'] = sheet['c'+str(i)].value
|
||||
data['organizer'] = sheet['d'+str(i)].value
|
||||
data['params'] = sheet['e'+str(i)].value
|
||||
data['result'] = self.get_enum(sheet['f'+str(i)].value, Pt.pt_result_choices, i)
|
||||
data['handle_result'] = self.get_enum(sheet['g'+str(i)].value, Pt.pt_hresult_choices, i)
|
||||
return data
|
||||
|
||||
@action(methods=['post'], detail=False, perms_map = {'post':'task2do'}, serializer_class=ImpSerializer)
|
||||
@transaction.atomic
|
||||
def imp(self, request, *args, **kwargs):
|
||||
"""导入表格
|
||||
|
||||
导入表格
|
||||
"""
|
||||
return self.gen_imp_view(request, 5, PtSerializer)
|
||||
|
||||
|
||||
class RiskViewSet(Domixin, CreateUpdateCustomMixin, ModelViewSet):
|
||||
class RiskViewSet(ImpMixin, Domixin, CreateUpdateCustomMixin, ModelViewSet):
|
||||
queryset = Risk.objects.all()
|
||||
serializer_class = RiskSerializer
|
||||
count_dict = {
|
||||
"num_risk": {}
|
||||
}
|
||||
filterset_fields = ['task2do', 'task2do__belong_dept', 'task2do__task2__year']
|
||||
|
||||
def make_data(self, data, sheet, i, etype):
|
||||
data['content'] = sheet['b'+str(i)].value
|
||||
data['level'] = self.get_enum(sheet['c'+str(i)].value, Risk.risk_level_choices, i)
|
||||
data['code'] = sheet['d'+str(i)].value
|
||||
data['state'] = self.get_enum(sheet['e'+str(i)].value, Risk.risk_state_choices, i)
|
||||
return data
|
||||
|
||||
@action(methods=['post'], detail=False, perms_map = {'post':'task2do'}, serializer_class=ImpSerializer)
|
||||
@transaction.atomic
|
||||
def imp(self, request, *args, **kwargs):
|
||||
"""导入表格
|
||||
|
||||
导入表格
|
||||
"""
|
||||
return self.gen_imp_view(request, 5, RiskSerializer)
|
||||
|
||||
|
||||
class OinspectViewSet(Domixin, CreateUpdateCustomMixin, ModelViewSet):
|
||||
class OinspectViewSet(ImpMixin, Domixin, CreateUpdateCustomMixin, ModelViewSet):
|
||||
queryset = Oinspect.objects.all()
|
||||
serializer_class = OinspectSerializer
|
||||
count_dict = {
|
||||
"num_oinspect": {}
|
||||
}
|
||||
filterset_fields = ['task2do', 'task2do__belong_dept', 'task2do__task2__year']
|
||||
|
||||
def make_data(self, data, sheet, i, etype):
|
||||
data['cate'] = self.get_enum(sheet['b'+str(i)].value, Oinspect.oinspect_cate_choices, i)
|
||||
data['checker'] = sheet['c'+str(i)].value
|
||||
data['date_inspect'] = sheet['d'+str(i)].value
|
||||
data['result'] = sheet['e'+str(i)].value
|
||||
return data
|
||||
|
||||
@action(methods=['post'], detail=False, perms_map = {'post':'task2do'}, serializer_class=ImpSerializer)
|
||||
@transaction.atomic
|
||||
def imp(self, request, *args, **kwargs):
|
||||
"""导入表格
|
||||
|
||||
导入表格
|
||||
"""
|
||||
return self.gen_imp_view(request, 5, OinspectSerializer)
|
|
@ -2,5 +2,5 @@ from django.apps import AppConfig
|
|||
|
||||
|
||||
class RbacConfig(AppConfig):
|
||||
name = 'system'
|
||||
name = 'apps.system'
|
||||
verbose_name = '系统管理'
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
# Generated by Django 3.2.12 on 2023-05-23 06:52
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('system', '0022_delete_historicaldict'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='user',
|
||||
name='first_name',
|
||||
field=models.CharField(blank=True, max_length=150, verbose_name='first name'),
|
||||
),
|
||||
]
|
|
@ -167,6 +167,17 @@ class Dict(SoftModel):
|
|||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
class CommonADModel(BaseModel):
|
||||
"""
|
||||
业务用基本表A,包含create_by, update_by字段,物理删除
|
||||
"""
|
||||
create_by = models.ForeignKey(
|
||||
User, null=True, blank=True, on_delete=models.SET_NULL, verbose_name='创建人', related_name='%(class)s_create_by')
|
||||
update_by = models.ForeignKey(
|
||||
User, null=True, blank=True, on_delete=models.SET_NULL, verbose_name='最后编辑人', related_name='%(class)s_update_by')
|
||||
|
||||
class Meta:
|
||||
abstract = True
|
||||
|
||||
class CommonAModel(SoftModel):
|
||||
"""
|
||||
|
@ -194,6 +205,19 @@ class CommonBModel(SoftModel):
|
|||
class Meta:
|
||||
abstract = True
|
||||
|
||||
class CommonBDModel(BaseModel):
|
||||
"""
|
||||
业务用基本表B,包含create_by, update_by, belong_dept字段,物理删除
|
||||
"""
|
||||
create_by = models.ForeignKey(
|
||||
User, null=True, blank=True, on_delete=models.SET_NULL, verbose_name='创建人', related_name='%(class)s_create_by')
|
||||
update_by = models.ForeignKey(
|
||||
User, null=True, blank=True, on_delete=models.SET_NULL, verbose_name='最后编辑人', related_name='%(class)s_update_by')
|
||||
belong_dept = models.ForeignKey(
|
||||
Organization, null=True, blank=True, on_delete=models.SET_NULL, verbose_name='所属部门', related_name='%(class)s_belong_dept')
|
||||
|
||||
class Meta:
|
||||
abstract = True
|
||||
|
||||
class File(CommonAModel):
|
||||
"""
|
||||
|
|
|
@ -2,4 +2,4 @@ from django.apps import AppConfig
|
|||
|
||||
|
||||
class VodConfig(AppConfig):
|
||||
name = 'vod'
|
||||
name = 'apps.vod'
|
||||
|
|
Binary file not shown.
|
@ -126,6 +126,9 @@ USE_TZ = True
|
|||
CORS_ALLOW_CREDENTIALS = True
|
||||
CORS_ORIGIN_ALLOW_ALL = True
|
||||
|
||||
# 默认主键
|
||||
DEFAULT_AUTO_FIELD = 'django.db.models.AutoField'
|
||||
|
||||
|
||||
# Static files (CSS, JavaScript, Images)
|
||||
# https://docs.djangoproject.com/en/3.0/howto/static-files/
|
||||
|
|
Loading…
Reference in New Issue