This commit is contained in:
shijing 2023-05-31 17:20:50 +08:00
commit f5e237b635
24 changed files with 493 additions and 63 deletions

View File

@ -2,4 +2,4 @@ from django.apps import AppConfig
class AbilityConfig(AppConfig):
name = 'ability'
name = 'apps.ability'

View File

@ -2,4 +2,4 @@ from django.apps import AppConfig
class QualityConfig(AppConfig):
name = 'consulting'
name = 'apps.consulting'

View File

@ -2,4 +2,4 @@ from django.apps import AppConfig
class CrmConfig(AppConfig):
name = 'crm'
name = 'apps.crm'

View File

@ -2,4 +2,4 @@ from django.apps import AppConfig
class ExamConfig(AppConfig):
name = 'exam'
name = 'apps.exam'

View File

@ -2,5 +2,5 @@ from django.apps import AppConfig
class OpsConfig(AppConfig):
name = 'ops'
name = 'apps.ops'
verbose_name = '系统监控'

View File

@ -2,4 +2,4 @@ from django.apps import AppConfig
class QualityConfig(AppConfig):
name = 'quality'
name = 'apps.quality'

View File

@ -2,4 +2,4 @@ from django.apps import AppConfig
class SupervisionConfig(AppConfig):
name = 'supervision'
name = 'apps.supervision'

View File

@ -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='任务状态'),
),
]

View File

@ -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='所属周期'),
),
]

View File

@ -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='设定值'),
),
]

View File

@ -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='基础值'),
),
]

View File

@ -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',
),
]

View File

@ -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='备注'),
),
]

View File

@ -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='整改状态'),
),
]

View File

@ -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='满意能力验证数'),
),
]

View File

@ -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('检查结果')

View File

@ -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())

View File

@ -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)

View File

@ -2,5 +2,5 @@ from django.apps import AppConfig
class RbacConfig(AppConfig):
name = 'system'
name = 'apps.system'
verbose_name = '系统管理'

View File

@ -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'),
),
]

View File

@ -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):
"""

View File

@ -2,4 +2,4 @@ from django.apps import AppConfig
class VodConfig(AppConfig):
name = 'vod'
name = 'apps.vod'

Binary file not shown.

View File

@ -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/