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.db import models
from django.utils import timezone from django.utils import timezone
from apps.system.models import Organization 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): class AbilityReview(models.Model):

View File

@ -1,6 +1,6 @@
from rest_framework import serializers from rest_framework import serializers
from apps.system.serializers import OrganizationSimpleSerializer 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): class AbilityReviewSerializer(serializers.ModelSerializer):
@ -35,4 +35,15 @@ class ExternalAuditorsSerializer(serializers.ModelSerializer):
fields = '__all__' 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 django.urls import path, include
from rest_framework import routers 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 = routers.DefaultRouter()
router.register('ar', AbilityReviewViewSet, basename='abilityreviews') router.register('ar', AbilityReviewViewSet, basename='abilityreviews')
@ -8,6 +8,7 @@ router.register('qc', QualityCommendationViewSet, basename='qualitycommendation'
router.register('qa', QualityActivitiesViewSet, basename='qualityactivities') router.register('qa', QualityActivitiesViewSet, basename='qualityactivities')
router.register('contact', ContactViewSet, basename='contact') router.register('contact', ContactViewSet, basename='contact')
router.register('ea', ExternalAuditorsViewSet, basename='externalauditors') router.register('ea', ExternalAuditorsViewSet, basename='externalauditors')
router.register('faq', QualificationViewSet, basename='faq')
urlpatterns = [ urlpatterns = [
path('', include(router.urls)) 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 rest_framework import status
from django.conf import settings from django.conf import settings
from rest_framework.decorators import action from rest_framework.decorators import action
from rest_framework.views import APIView
from rest_framework.viewsets import ModelViewSet from rest_framework.viewsets import ModelViewSet
from utils.queryset import get_child_queryset2 from utils.queryset import get_child_queryset2
from rest_framework.response import Response from rest_framework.response import Response
@ -47,6 +42,7 @@ class AbilityReviewViewSet(ModelViewSet):
#根据日期过滤数据 #根据日期过滤数据
@action(detail=False, methods=['post']) @action(detail=False, methods=['post'])
@transaction.atomic
def filter_by_date(self, request, *args, **kwargs): def filter_by_date(self, request, *args, **kwargs):
father_dept = request.user.dept father_dept = request.user.dept
child_dept = get_child_queryset2(father_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) return Response({'uploaded': 'File uploaded successfully'}, status=status.HTTP_201_CREATED)
class QualityCommendationViewSet(ModelViewSet): class QualityCommendationViewSet(ModelViewSet):
queryset = QualityCommendation.objects.all() queryset = QualityCommendation.objects.all()
serializer_class = QualityCommendationSerializer serializer_class = QualityCommendationSerializer
@ -153,13 +150,6 @@ class QualityCommendationViewSet(ModelViewSet):
else: else:
raise ParseError("获奖单位不存在") 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): def build_qt_data(self, sheet):
data_list = [] data_list = []
for row in sheet.iter_rows(min_row=2, values_only=True): # 假设第一行是表头,从第二行开始读取数据 for row in sheet.iter_rows(min_row=2, values_only=True): # 假设第一行是表头,从第二行开始读取数据
@ -186,7 +176,6 @@ class QualityCommendationViewSet(ModelViewSet):
data_list.append(serializer_data) data_list.append(serializer_data)
return data_list return data_list
# 查询子以及已经本公司的质量表彰 # 查询子以及已经本公司的质量表彰
@action(detail=False, methods=['get']) @action(detail=False, methods=['get'])
def commentdation_info(self, request, *args, **kwargs): def commentdation_info(self, request, *args, **kwargs):
@ -199,6 +188,7 @@ class QualityCommendationViewSet(ModelViewSet):
#根据日期过滤数据 #根据日期过滤数据
@action(detail=False, methods=['post']) @action(detail=False, methods=['post'])
@transaction.atomic
def filter_by_date(self, request, *args, **kwargs): def filter_by_date(self, request, *args, **kwargs):
father_dept = request.user.dept father_dept = request.user.dept
child_dept = get_child_queryset2(father_dept) child_dept = get_child_queryset2(father_dept)
@ -249,6 +239,7 @@ class QualityActivitiesViewSet(ModelViewSet):
#根据日期过滤数据 #根据日期过滤数据
@action(detail=False, methods=['post']) @action(detail=False, methods=['post'])
@transaction.atomic
def filter_by_date(self, request, *args, **kwargs): def filter_by_date(self, request, *args, **kwargs):
father_dept = request.user.dept father_dept = request.user.dept
child_dept = get_child_queryset2(father_dept) child_dept = get_child_queryset2(father_dept)
@ -281,6 +272,7 @@ class ContactViewSet(ModelViewSet):
queryset = Contact.objects.all() queryset = Contact.objects.all()
serializer_class = ContactSerializer serializer_class = ContactSerializer
class ExternalAuditorsViewSet(ModelViewSet): class ExternalAuditorsViewSet(ModelViewSet):
queryset = ExternalAuditors.objects.all() queryset = ExternalAuditors.objects.all()
serializer_class = ExternalAuditorsSerializer serializer_class = ExternalAuditorsSerializer
@ -294,7 +286,7 @@ class ExternalAuditorsViewSet(ModelViewSet):
serializer.save() serializer.save()
return Response(serializer.data, status = status.HTTP_201_CREATED) return Response(serializer.data, status = status.HTTP_201_CREATED)
else: else:
raise ParseError("组织单位不存在") raise ParseError("公司名称不存在")
# 查询子以及已经本公司的质量活动 # 查询子以及已经本公司的质量活动
@action(detail=False, methods=['get']) @action(detail=False, methods=['get'])
@ -307,6 +299,7 @@ class ExternalAuditorsViewSet(ModelViewSet):
#根据日期过滤数据 #根据日期过滤数据
@action(detail=False, methods=['post']) @action(detail=False, methods=['post'])
@transaction.atomic
def filter_by_date(self, request, *args, **kwargs): def filter_by_date(self, request, *args, **kwargs):
father_dept = request.user.dept father_dept = request.user.dept
child_dept = get_child_queryset2(father_dept) child_dept = get_child_queryset2(father_dept)
@ -331,3 +324,57 @@ class ExternalAuditorsViewSet(ModelViewSet):
new_data_list.append(new_dict) new_data_list.append(new_dict)
data = {'count':len(serializer.data), 'results':new_data_list} data = {'count':len(serializer.data), 'results':new_data_list}
return Response(data, status = status.HTTP_200_OK) 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)