feature<master> feat:新增资质情况和更新记录功能

This commit is contained in:
zty 2024-04-09 17:29:41 +08:00
parent 94ef5e3121
commit 4a06a9d68a
5 changed files with 176 additions and 19 deletions

View File

@ -0,0 +1,57 @@
# Generated by Django 3.2.12 on 2024-04-09 06:02
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import uuid
class Migration(migrations.Migration):
dependencies = [
('system', '0023_alter_user_first_name'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('information', '0018_auto_20240407_1622'),
]
operations = [
migrations.CreateModel(
name='Qualification',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('company_name', models.CharField(blank=True, max_length=20, null=True, verbose_name='公司名称')),
('name', models.CharField(blank=True, max_length=20, null=True, verbose_name='资质名称')),
('quali_type', models.CharField(choices=[('国家级', '国家级'), ('省级', '省级')], max_length=20, verbose_name='资质类型')),
('org', models.CharField(blank=True, max_length=20, null=True, verbose_name='发证单位')),
('org_date', models.DateField(blank=True, null=True, verbose_name='发证日期')),
('expiration_date', models.DateField(blank=True, null=True, verbose_name='截至日期')),
('scope', models.TextField(blank=True, null=True, verbose_name='资质范围')),
('number', models.IntegerField(blank=True, null=True, verbose_name='参数数量')),
('cie_path', models.CharField(blank=True, max_length=100, null=True, verbose_name='证书路径')),
('create_date', models.DateTimeField(auto_now_add=True, null=True)),
('update_date', models.DateTimeField(auto_now=True, null=True)),
('department', models.ForeignKey(null=True, on_delete=django.db.models.deletion.PROTECT, to='system.organization', verbose_name='所属单位')),
],
options={
'verbose_name': '资质情况',
'db_table': 'qfn_info',
},
),
migrations.CreateModel(
name='AuditLog',
fields=[
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
('action', models.CharField(max_length=20, verbose_name='动作')),
('instance_id', models.CharField(editable=False, max_length=20, verbose_name='记录ID')),
('change_reason', models.CharField(default='', max_length=50, verbose_name='变更原因')),
('change_time', models.DateTimeField(verbose_name='变更时间')),
('val_new', models.JSONField(default=dict, verbose_name='变更后完整数据')),
('difference', models.JSONField(default=list, verbose_name='变更情况')),
('change_user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL, verbose_name='操作人')),
],
options={
'verbose_name': '资质变更情况',
'db_table': 'qfn_change_info',
},
),
]

View File

@ -1,6 +1,47 @@
from django.db import models
from django.utils import timezone
from apps.system.models import Organization
import uuid
class Qualification(models.Model):
quali_options = (('国家级','国家级'),('省级','省级'))
company_name = models.CharField(max_length=20, verbose_name='公司名称', null=True, blank=True)
name = models.CharField(max_length=20, verbose_name='资质名称',null=True, blank=True)
quali_type = models.CharField(max_length=20, choices=quali_options, verbose_name='资质类型')
org = models.CharField(max_length=20, verbose_name='发证单位', null=True, blank=True)
org_date = models.DateField(verbose_name='发证日期', null=True, blank=True)
expiration_date = models.DateField(verbose_name='截至日期', null=True, blank=True)
scope = models.TextField(verbose_name='资质范围', null=True, blank=True)
number = models.IntegerField(verbose_name='参数数量', null=True, blank=True)
cie_path = models.CharField(max_length=100, verbose_name='证书路径', null=True, blank=True)
create_date = models.DateTimeField(auto_now_add=True, null=True)
update_date = models.DateTimeField(auto_now=True, null=True)
department = models.ForeignKey(Organization, on_delete=models.PROTECT, null=True, verbose_name='所属单位')
def save(self, *args, **kwargs):
if not self.id:
self.create_date = timezone.now()
# update_date将自动设置为当前时间因为auto_now=True
super(Qualification, self).save(*args, **kwargs)
class Meta:
verbose_name = '资质情况'
db_table = 'qfn_info'
class AuditLog(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
action = models.CharField('动作', max_length=20)
instance_id = models.CharField('记录ID', max_length=20, editable=False)
change_reason = models.CharField('变更原因', default='', max_length=50)
change_user = models.ForeignKey('system.user', on_delete=models.SET_NULL, verbose_name='操作人', null=True, blank=True)
change_time = models.DateTimeField('变更时间')
val_new = models.JSONField('变更后完整数据', default=dict)
difference = models.JSONField('变更情况', default=list)
class Meta:
verbose_name = '资质变更情况'
db_table = 'qfn_change_info'
class AbilityReview(models.Model):

View File

@ -1,6 +1,6 @@
from rest_framework import serializers
from apps.system.serializers import OrganizationSimpleSerializer
from .models import AbilityReview, QualityCommendation, QualityActivities, Contact, ExternalAuditors
from .models import AbilityReview, QualityCommendation, QualityActivities, Contact, ExternalAuditors, AuditLog, Qualification
class AbilityReviewSerializer(serializers.ModelSerializer):
@ -35,4 +35,15 @@ class ExternalAuditorsSerializer(serializers.ModelSerializer):
fields = '__all__'
class QualificationSerializer(serializers.ModelSerializer):
class Meta:
model = Qualification
fields = '__all__'
class AuditLogSerializer(serializers.ModelSerializer):
class Meta:
model = AuditLog
fields = '__all__'

View File

@ -1,6 +1,6 @@
from django.urls import path, include
from rest_framework import routers
from .views import AbilityReviewViewSet, QualityCommendationViewSet, QualityActivitiesViewSet, ContactViewSet, ExternalAuditorsViewSet
from .views import AbilityReviewViewSet, QualityCommendationViewSet, QualityActivitiesViewSet, ContactViewSet, ExternalAuditorsViewSet, QualificationViewSet
router = routers.DefaultRouter()
router.register('ar', AbilityReviewViewSet, basename='abilityreviews')
@ -8,6 +8,7 @@ router.register('qc', QualityCommendationViewSet, basename='qualitycommendation'
router.register('qa', QualityActivitiesViewSet, basename='qualityactivities')
router.register('contact', ContactViewSet, basename='contact')
router.register('ea', ExternalAuditorsViewSet, basename='externalauditors')
router.register('faq', QualificationViewSet, basename='faq')
urlpatterns = [
path('', include(router.urls))
]

View File

@ -1,11 +1,6 @@
from rest_framework import viewsets, mixins
from rest_framework.viewsets import ViewSet
from rest_framework import status
from django.conf import settings
from rest_framework.decorators import action
from rest_framework.views import APIView
from rest_framework.viewsets import ModelViewSet
from utils.queryset import get_child_queryset2
from rest_framework.response import Response
@ -47,6 +42,7 @@ class AbilityReviewViewSet(ModelViewSet):
#根据日期过滤数据
@action(detail=False, methods=['post'])
@transaction.atomic
def filter_by_date(self, request, *args, **kwargs):
father_dept = request.user.dept
child_dept = get_child_queryset2(father_dept)
@ -137,6 +133,7 @@ class ImpMixin:
return Response({'uploaded': 'File uploaded successfully'}, status=status.HTTP_201_CREATED)
class QualityCommendationViewSet(ModelViewSet):
queryset = QualityCommendation.objects.all()
serializer_class = QualityCommendationSerializer
@ -153,13 +150,6 @@ class QualityCommendationViewSet(ModelViewSet):
else:
raise ParseError("获奖单位不存在")
# # 导入表格
# @action(methods=['post'], detail=False)
# @transaction.atomic
# def imp(self, request, *args, **kwargs):
# return self.gen_imp_view(request, 5, QualityCommendationSerializer, 'qt')
#构造导入的数据格式
def build_qt_data(self, sheet):
data_list = []
for row in sheet.iter_rows(min_row=2, values_only=True): # 假设第一行是表头,从第二行开始读取数据
@ -186,7 +176,6 @@ class QualityCommendationViewSet(ModelViewSet):
data_list.append(serializer_data)
return data_list
# 查询子以及已经本公司的质量表彰
@action(detail=False, methods=['get'])
def commentdation_info(self, request, *args, **kwargs):
@ -199,6 +188,7 @@ class QualityCommendationViewSet(ModelViewSet):
#根据日期过滤数据
@action(detail=False, methods=['post'])
@transaction.atomic
def filter_by_date(self, request, *args, **kwargs):
father_dept = request.user.dept
child_dept = get_child_queryset2(father_dept)
@ -249,6 +239,7 @@ class QualityActivitiesViewSet(ModelViewSet):
#根据日期过滤数据
@action(detail=False, methods=['post'])
@transaction.atomic
def filter_by_date(self, request, *args, **kwargs):
father_dept = request.user.dept
child_dept = get_child_queryset2(father_dept)
@ -281,6 +272,7 @@ class ContactViewSet(ModelViewSet):
queryset = Contact.objects.all()
serializer_class = ContactSerializer
class ExternalAuditorsViewSet(ModelViewSet):
queryset = ExternalAuditors.objects.all()
serializer_class = ExternalAuditorsSerializer
@ -294,7 +286,7 @@ class ExternalAuditorsViewSet(ModelViewSet):
serializer.save()
return Response(serializer.data, status = status.HTTP_201_CREATED)
else:
raise ParseError("组织单位不存在")
raise ParseError("公司名称不存在")
# 查询子以及已经本公司的质量活动
@action(detail=False, methods=['get'])
@ -307,6 +299,7 @@ class ExternalAuditorsViewSet(ModelViewSet):
#根据日期过滤数据
@action(detail=False, methods=['post'])
@transaction.atomic
def filter_by_date(self, request, *args, **kwargs):
father_dept = request.user.dept
child_dept = get_child_queryset2(father_dept)
@ -331,3 +324,57 @@ class ExternalAuditorsViewSet(ModelViewSet):
new_data_list.append(new_dict)
data = {'count':len(serializer.data), 'results':new_data_list}
return Response(data, status = status.HTTP_200_OK)
class QualificationViewSet(ModelViewSet):
queryset = Qualification.objects.all()
serializer_class = QualificationSerializer
#重写保存方法
def create(self, request):
if Organization.objects.filter(name=request.data['company_name']).exists():
department_id = Organization.objects.filter(name=request.data['company_name']).first().id
request.data['department'] = department_id
serializer = self.get_serializer(data=request.data)
if serializer.is_valid(raise_exception=True):
serializer.save()
return Response(serializer.data, status = status.HTTP_201_CREATED)
else:
raise ParseError("公司名称不存在")
# 重写更新的方法
def partial_update(self, request, pk=None):
#获取需要更新的实列
instance = self.get_object()
# 数据比较
ignore_fields = ['create_by', 'create_date', 'update_date', 'id']
origin_dict = QualificationSerializer(instance=instance).data
diff = []
for k, v in request.data.items():
if k not in ignore_fields:
origin_value = origin_dict.get(k)
if origin_value != v:
diff.append({k:{'old':origin_value, 'new':v}})
serializers = self.get_serializer(instance, data=request.data, partial=True)
serializers.is_valid(raise_exception=True)
self.perform_update(serializers)
if diff:
AuditLog.objects.create(
action='update',
instance_id=instance.id,
change_time = datetime.now(),
change_user=request.user,
val_new=serializers.data,
difference=diff
)
return Response(serializers.data, status = status.HTTP_204_NO_CONTENT)
# 查询子以及已经本公司的资质情况
@action(detail=False, methods=['get'])
def activate_info(self, request, *args, **kwargs):
child_dept = get_child_queryset2(request.user.dept)
query = Qualification.objects.filter(department__in=child_dept)
serializer = QualificationSerializer(query, many=True)
data = {'count':len(serializer.data), 'results':serializer.data}
return Response(data, status = status.HTTP_200_OK)