feature:<master> feat:后端

增加质量表彰功能
This commit is contained in:
zty 2024-03-28 14:15:15 +08:00
parent eb1d9da790
commit a216e17904
11 changed files with 295 additions and 69 deletions

View File

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

View File

@ -0,0 +1,58 @@
# Generated by Django 3.2.12 on 2024-03-27 05:15
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone
class Migration(migrations.Migration):
dependencies = [
('system', '0023_alter_user_first_name'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('information', '0002_auto_20240326_0932'),
]
operations = [
migrations.AddField(
model_name='qualitycommendation',
name='awardee_people',
field=models.CharField(max_length=20, null=True, verbose_name='获奖人'),
),
migrations.AddField(
model_name='qualitycommendation',
name='belong_dept',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='qualitycommendation_belong_dept', to='system.organization', verbose_name='所属部门'),
),
migrations.AddField(
model_name='qualitycommendation',
name='create_by',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='qualitycommendation_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人'),
),
migrations.AddField(
model_name='qualitycommendation',
name='create_time',
field=models.DateTimeField(default=django.utils.timezone.now, help_text='创建时间', verbose_name='创建时间'),
),
migrations.AddField(
model_name='qualitycommendation',
name='is_deleted',
field=models.BooleanField(default=False, help_text='删除标记', verbose_name='删除标记'),
),
migrations.AddField(
model_name='qualitycommendation',
name='update_by',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='qualitycommendation_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人'),
),
migrations.AddField(
model_name='qualitycommendation',
name='update_time',
field=models.DateTimeField(auto_now=True, help_text='修改时间', verbose_name='修改时间'),
),
migrations.AlterField(
model_name='qualitycommendation',
name='awardee_company',
field=models.CharField(max_length=20, null=True, verbose_name='获奖单位'),
),
]

View File

@ -0,0 +1,37 @@
# Generated by Django 3.2.12 on 2024-03-27 09:41
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('information', '0003_auto_20240327_1315'),
]
operations = [
migrations.RemoveField(
model_name='qualitycommendation',
name='belong_dept',
),
migrations.RemoveField(
model_name='qualitycommendation',
name='create_by',
),
migrations.RemoveField(
model_name='qualitycommendation',
name='create_time',
),
migrations.RemoveField(
model_name='qualitycommendation',
name='is_deleted',
),
migrations.RemoveField(
model_name='qualitycommendation',
name='update_by',
),
migrations.RemoveField(
model_name='qualitycommendation',
name='update_time',
),
]

View File

@ -0,0 +1,20 @@
# Generated by Django 3.2.12 on 2024-03-27 11:25
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('system', '0023_alter_user_first_name'),
('information', '0004_auto_20240327_1741'),
]
operations = [
migrations.AddField(
model_name='qualitycommendation',
name='department',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='system.organization', verbose_name='所属单位'),
),
]

View File

@ -1,7 +1,5 @@
from django.db import models from django.db import models
from apps.system.models import Organization
# Create your models here.
class AbilityReview(models.Model): class AbilityReview(models.Model):
type_method = ( type_method = (
(0, '文审'), (0, '文审'),
@ -25,26 +23,21 @@ class AbilityReview(models.Model):
verbose_name = '评审情况' verbose_name = '评审情况'
db_table = 'ability_review' db_table = 'ability_review'
def __str__(self):
return self.name
class QualityCommendation(models.Model): class QualityCommendation(models.Model):
name = models.CharField(max_length=20, unique=True, verbose_name='项目名称') name = models.CharField(max_length=20, unique=True, verbose_name='项目名称')
commendation_name = models.CharField(max_length=20, verbose_name='表彰名称') commendation_name = models.CharField(max_length=20, verbose_name='表彰名称')
Awards_level = models.CharField(max_length=20, verbose_name='获奖等级') Awards_level = models.CharField(max_length=20, verbose_name='获奖等级')
awardee_company = models.CharField(max_length=20, verbose_name='获奖单位') awardee_company = models.CharField(max_length=20, verbose_name='获奖单位', null=True)
awardee_people = models.CharField(max_length=20, verbose_name='获奖人', null=True)
awarded_by = models.CharField(max_length=20, verbose_name='颁奖单位') awarded_by = models.CharField(max_length=20, verbose_name='颁奖单位')
awarded_date = models.DateField(verbose_name='获奖日期', null=True) awarded_date = models.DateField(verbose_name='获奖日期', null=True)
department = models.ForeignKey(Organization, on_delete=models.CASCADE, null=True, verbose_name='所属单位')
class Meta: class Meta:
verbose_name = '质量表彰' verbose_name = '质量表彰'
db_table = 'quality_commendation' db_table = 'quality_commendation'
def __str__(self):
return self.name
class QualityActivities(models.Model): class QualityActivities(models.Model):
role = (('组织方','组织方'),('活动方','活动方')) role = (('组织方','组织方'),('活动方','活动方'))
name = models.CharField(max_length=20, unique=True, verbose_name='活动名称') name = models.CharField(max_length=20, unique=True, verbose_name='活动名称')
@ -61,9 +54,6 @@ class QualityActivities(models.Model):
verbose_name = '质量活动' verbose_name = '质量活动'
db_table = 'quality_activities' db_table = 'quality_activities'
def __str__(self):
return self.name
class Contact(models.Model): class Contact(models.Model):
name = models.CharField(max_length=20, unique=True, verbose_name='姓名') name = models.CharField(max_length=20, unique=True, verbose_name='姓名')
@ -82,10 +72,6 @@ class Contact(models.Model):
verbose_name = '实验室联系方式' verbose_name = '实验室联系方式'
db_table = 'contact' db_table = 'contact'
def __str__(self):
return self.name
class ExternalAuditors(models.Model): class ExternalAuditors(models.Model):
review_type = ( ('CNAS', 'CNAS'), review_type = ( ('CNAS', 'CNAS'),
('CMA', 'CMA'), ('CMA', 'CMA'),
@ -101,6 +87,3 @@ class ExternalAuditors(models.Model):
class Meta: class Meta:
verbose_name = '外审员情况' verbose_name = '外审员情况'
db_table = 'externalauditors' db_table = 'externalauditors'
def __str__(self):
return self.name

View File

@ -1,28 +1,38 @@
from rest_framework import serializers from rest_framework import serializers
from apps.information.models import AbilityReview, QualityCommendation, QualityActivities, Contact, ExternalAuditors from apps.system.serializers import OrganizationSimpleSerializer
from .models import AbilityReview, QualityCommendation, QualityActivities, Contact, ExternalAuditors
class AbilityReviewSerializer(serializers.ModelSerializer): class AbilityReviewSerializer(serializers.ModelSerializer):
model = AbilityReview class Meta:
fields = '__all__' model = AbilityReview
fields = '__all__'
class QualityCommendationSerializer(serializers.ModelSerializer): class QualityCommendationSerializer(serializers.ModelSerializer):
model = QualityCommendation class Meta:
fields = '__all__' model = QualityCommendation
fields = '__all__'
read_only_fields = ['id']
class QualityActivitiesSerializer(serializers.ModelSerializer): class QualityActivitiesSerializer(serializers.ModelSerializer):
model = QualityActivities
fields = '__all __' class Meta:
model = QualityActivities
fields = '__all __'
class ContactSerializer(serializers.ModelSerializer): class ContactSerializer(serializers.ModelSerializer):
model = Contact
fields = '__all__' class Meta:
model = Contact
fields = '__all__'
class ExternalAuditorsSerializer(serializers.ModelSerializer): class ExternalAuditorsSerializer(serializers.ModelSerializer):
model = ExternalAuditors class Meta:
fields = '__all__' model = ExternalAuditors
fields = '__all__'
class ImpSerializer(serializers.Serializer):
path = serializers.FileField(label='文件地址')

View File

@ -1,19 +0,0 @@
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from .views import AbilityReviewViewSet, \
QualityCommendationBViewSet, \
QualityActivitiesViewSet,\
ContactViewSet, \
ExternalAuditorsViewSet
API_BASE_URL = 'api/information/'
router = DefaultRouter()
router.register(r'abilityreviews', AbilityReviewViewSet, basename='评审情况')
router.register(r'qualitycommendation', QualityCommendationBViewSet, basename='质量表彰')
router.register(r'qualityactivities', QualityActivitiesViewSet, basename='质量活动')
router.register(r'contact', ContactViewSet, basename='实验室联系方式')
router.register(r'externalauditors', ExternalAuditorsViewSet, basename='外审员情况')
urlpatterns = [path(API_BASE_URL, include(router.urls)),]

View File

@ -0,0 +1,13 @@
from django.urls import path, include
from rest_framework import routers
from .views import AbilityReviewViewSet, QualityCommendationViewSet, QualityActivitiesViewSet, ContactViewSet, ExternalAuditorsViewSet
router = routers.DefaultRouter()
router.register('abilityreviews', AbilityReviewViewSet, basename='abilityreviews')
router.register('qualitycommendation', QualityCommendationViewSet, basename='qualitycommendation')
router.register('qualityactivities', QualityActivitiesViewSet, basename='qualityactivities')
router.register('contact', ContactViewSet, basename='contact')
router.register('externalauditors', ExternalAuditorsViewSet, basename='externalauditors')
urlpatterns = [
path('', include(router.urls))
]

View File

@ -1,11 +1,26 @@
from rest_framework import viewsets, mixins
from .models import AbilityReview, QualityCommendation, QualityActivities, Contact, ExternalAuditors
from .serializers import AbilityReviewSerializer, \
QualityCommendationSerializer, \
QualityActivitiesSerializer,\
ContactSerializer, \
ExternalAuditorsSerializer
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 .models import AbilityReview, QualityCommendation, QualityActivities, Contact, ExternalAuditors
# from .serializers import AbilityReviewSerializer, QualityCommendationSerializer, QualityActivitiesSerializer,ContactSerializer, ExternalAuditorsSerializer
from utils.queryset import get_child_queryset2
from rest_framework.response import Response
from apps.system.permission import has_permission
from openpyxl import load_workbook
from django.db import transaction
from rest_framework.exceptions import ParseError
from apps.system.models import Organization
from .models import *
from .serializers import *
from datetime import datetime
import os
class AbilityReviewViewSet( mixins.CreateModelMixin, class AbilityReviewViewSet( mixins.CreateModelMixin,
mixins.ListModelMixin, mixins.ListModelMixin,
@ -19,15 +34,123 @@ class AbilityReviewViewSet( mixins.CreateModelMixin,
def get_queryset(self): def get_queryset(self):
pass pass
class ImpMixin:
def get_queryset(self):
mydept = self.request.user.dept
qs = super().get_queryset()
if has_permission('task2', self.request.user):
return qs
return qs.filter(belong_dept=mydept)
class QualityCommendationBViewSet(mixins.CreateModelMixin, def format_date(self, ind, val):
mixins.ListModelMixin, new_val = val
mixins.DestroyModelMixin, if isinstance(val, datetime.datetime):
mixins.UpdateModelMixin, new_val = val.date()
viewsets.GenericViewSet): elif isinstance(val, datetime.date):
new_val = val
elif isinstance(val, str):
try:
new_val = datetime.datetime.strptime(val, '%Y-%m-%d').date()
except ValueError:
raise ParseError(f'{ind}行, 日期时间格式错误')
elif val is None:
pass
else:
raise ParseError(f'{ind}行, 日期时间格式错误')
return new_val
def get_enum(self, val, atuple, ind):
for i in atuple:
if i[1] == val:
return i[0]
raise ParseError('{}: 请选择固定选项值'.format(ind))
def F(self, data, sheet, i, etype):
raise NotImplementedError()
def gen_imp_view(self, request, start: int, mySerializer, types = None):
if 'file' not in request.data:
raise ParseError('请提供文件')
path = request.data['file']
if not str(path).endswith('.xlsx'):
raise ParseError('请提供xlsx格式文件')
fullpath = os.path.join(settings.BASE_DIR, str(path))
wb = load_workbook(fullpath,data_only=True)
sheet = wb.active
# 遍历Excel文件中的数据
if types.lower() == "qt":
data_list = self.build_qt_data(sheet)
else:
pass
serializer = mySerializer(data=data_list, many=True, context={'request': request})
if serializer.is_valid():
serializer.save()
else:
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
return Response({'uploaded': 'File uploaded successfully'}, status=status.HTTP_201_CREATED)
class QualityCommendationViewSet(ImpMixin, ModelViewSet):
queryset = QualityCommendation.objects.all() queryset = QualityCommendation.objects.all()
serializer_class = QualityCommendationSerializer serializer_class = QualityCommendationSerializer
perms_map = {"get": "*", "post": "*", "put": "*", "delete": "*"}
def create(self):
if Organization.objects.filter(name=self.request.data['awardee_company']).exists():
department_id = Organization.objects.filter(name=self.request.data['awardee_company']).first().id
self.request.data['department'] = department_id
serializer = self.get_serializer(data=self.request.data)
if serializer.is_valid(raise_exception=True):
serializer.save()
return Response(serializer.data, status = status.HTTP_201_CREATED)
# 人名存在重复
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): # 假设第一行是表头,从第二行开始读取数据
if row[0] is not None:
awarded_date = row[6].strftime("%Y-%m-%d")
# 判断获奖的是人还是公司
department_id = Organization.objects.filter(name=row[4]).first().id
if department_id:
awardee_people = None
awardee_company = row[4]
else:
awardee_company = None
awardee_people = row[4]
serializer_data = {
'name': row[1], # 第一列是名字
'commendation_name':row[2],
'Awards_level':row[3],
'awardee_company':awardee_company,
'awardee_people':awardee_people,
'awarded_by':row[5],
'awarded_date':awarded_date,
'department':department_id,
}
data_list.append(serializer_data)
return data_list
# 查询子以及已经本公司的质量表彰
@action(detail=False, methods=['get'])
def commentdation_info(self, *args, **kwargs):
father_dept = self.request.user.dept
child_dept = get_child_queryset2(father_dept)
query = QualityCommendation.objects.filter(department__in=child_dept)
serializer = QualityCommendationSerializer(query, many=True)
return Response(serializer.data)
class QualityActivitiesViewSet(mixins.CreateModelMixin, class QualityActivitiesViewSet(mixins.CreateModelMixin,
mixins.ListModelMixin, mixins.ListModelMixin,

View File

@ -49,13 +49,13 @@ INSTALLED_APPS = [
'apps.crm', 'apps.crm',
'apps.ability', 'apps.ability',
'apps.supervision', 'apps.supervision',
'apps.information',
'apps.quality', 'apps.quality',
'apps.vod', 'apps.vod',
'apps.consulting', 'apps.consulting',
'apps.exam', 'apps.exam',
'apps.ops', 'apps.ops',
'apps.edu', 'apps.edu',
'apps.information'
] ]
MIDDLEWARE = [ MIDDLEWARE = [

View File

@ -59,6 +59,7 @@ urlpatterns = [
path('api/supervision/', include('apps.supervision.urls')), path('api/supervision/', include('apps.supervision.urls')),
path('api/quality/', include('apps.quality.urls')), path('api/quality/', include('apps.quality.urls')),
path('api/vod/', include('apps.vod.urls')), path('api/vod/', include('apps.vod.urls')),
path('api/info/', include('apps.information.urls')),
path('api/consulting/', include('apps.consulting.urls')), path('api/consulting/', include('apps.consulting.urls')),
path('', include('apps.ops.urls')), path('', include('apps.ops.urls')),
path('', include('apps.exam.urls')), path('', include('apps.exam.urls')),