From 2c6d6b859946933bb44649cefd91da4b03421905 Mon Sep 17 00:00:00 2001 From: shilixia <2309368887@qq.com> Date: Wed, 21 Oct 2020 10:56:36 +0800 Subject: [PATCH] =?UTF-8?q?=E6=A3=80=E9=AA=8C=E8=83=BD=E5=8A=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/api/inspection.js | 54 +++ client/src/router/index.js | 16 +- client/src/views/ability/inspection.vue | 360 ++++++++++++++++++ client/src/views/dashboard/index.vue | 4 +- .../ability/migrations/0013_inspection.py | 35 ++ .../migrations/0014_auto_20201020_1601.py | 23 ++ server/apps/ability/models.py | 21 + server/apps/ability/serializers.py | 8 +- server/apps/ability/urls.py | 3 +- server/apps/ability/views.py | 173 ++++++++- 10 files changed, 691 insertions(+), 6 deletions(-) create mode 100644 client/src/api/inspection.js create mode 100644 client/src/views/ability/inspection.vue create mode 100644 server/apps/ability/migrations/0013_inspection.py create mode 100644 server/apps/ability/migrations/0014_auto_20201020_1601.py diff --git a/client/src/api/inspection.js b/client/src/api/inspection.js new file mode 100644 index 0000000..71d6611 --- /dev/null +++ b/client/src/api/inspection.js @@ -0,0 +1,54 @@ +import request from '@/utils/request' + +export function getInspectionList(query) { + return request({ + url: '/ability/inspection/', + method: 'get', + params: query + }) +} + + + +export function createInspection(data) { + return request({ + url: '/ability/inspection/', + method: 'post', + data + }) +} +export function updateInspection(id, data) { + return request({ + url: `/ability/inspection/${id}/`, + method: 'put', + data + }) +} +export function deleteInspection(id) { + return request({ + url: `/ability/inspection/${id}/`, + method: 'delete' + }) +} +export function inspectionimport(data) { + return request({ + url: `/ability/inspection/inspection2/`, + method: 'post', + data + }) +} +export function getInspectionGroup(query) { + return request({ + url: '/ability/inspection/group/', + method: 'get', + params: query + }) +} +export function deletes(data) +{ + return request({ + url: `/ability/inspection/deletes/`, + method: 'post', + data + }) +} diff --git a/client/src/router/index.js b/client/src/router/index.js index 1b8481d..67504b2 100644 --- a/client/src/router/index.js +++ b/client/src/router/index.js @@ -81,6 +81,7 @@ export const asyncRoutes = [ meta: { title: '检测能力(总部CMA+CNAS)', icon: 'table', perms: ['cma_view'] } }] }, + { path: '/cma2', component: Layout, @@ -92,7 +93,20 @@ export const asyncRoutes = [ meta: { title: '检测能力(分子公司CMA)', icon: 'table', perms: ['cma2_view'] } } ] - }, + } +, +{ + path: '/inspection', + component: Layout, + redirect: '/inspection', + children: [{ + path: '', + name: 'inspection', + component: () => import('@/views/ability/inspection'), + meta: { title: '检验能力', icon: 'table', perms: ['inspection_view'] } + }] +}, + { path: '/system', component: Layout, diff --git a/client/src/views/ability/inspection.vue b/client/src/views/ability/inspection.vue new file mode 100644 index 0000000..9790c9e --- /dev/null +++ b/client/src/views/ability/inspection.vue @@ -0,0 +1,360 @@ + + + diff --git a/client/src/views/dashboard/index.vue b/client/src/views/dashboard/index.vue index 7922e2e..54a1ba8 100644 --- a/client/src/views/dashboard/index.vue +++ b/client/src/views/dashboard/index.vue @@ -41,13 +41,13 @@ -
+
- 检验能力-建设中 + 检验能力
diff --git a/server/apps/ability/migrations/0013_inspection.py b/server/apps/ability/migrations/0013_inspection.py new file mode 100644 index 0000000..65901f0 --- /dev/null +++ b/server/apps/ability/migrations/0013_inspection.py @@ -0,0 +1,35 @@ +# Generated by Django 3.0.5 on 2020-10-20 06:57 + +from django.db import migrations, models +import django.utils.timezone + + +class Migration(migrations.Migration): + + dependencies = [ + ('ability', '0012_auto_20201020_0920'), + ] + + operations = [ + migrations.CreateModel( + name='Inspection', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('create_time', models.DateTimeField(default=django.utils.timezone.now, help_text='创建时间', verbose_name='创建时间')), + ('update_time', models.DateTimeField(auto_now=True, help_text='修改时间', verbose_name='修改时间')), + ('is_deleted', models.BooleanField(default=False, help_text='删除标记', verbose_name='删除标记')), + ('dlxh', models.TextField(blank=True, null=True, verbose_name='大类序号')), + ('dlmc', models.TextField(blank=True, null=True, verbose_name='大类名称')), + ('dxxh', models.TextField(blank=True, null=True, verbose_name='对象序号')), + ('jydx', models.TextField(blank=True, null=True, verbose_name='检验对象')), + ('jyxmxh', models.TextField(blank=True, null=True, verbose_name='检验项目序号')), + ('jyxmmc', models.TextField(blank=True, null=True, verbose_name='检验项目名称')), + ('jybz', models.TextField(blank=True, null=True, verbose_name='检验标准')), + ('sm', models.TextField(blank=True, null=True, verbose_name='说明')), + ('sxrq', models.TextField(blank=True, null=True, verbose_name='生效日期')), + ], + options={ + 'abstract': False, + }, + ), + ] diff --git a/server/apps/ability/migrations/0014_auto_20201020_1601.py b/server/apps/ability/migrations/0014_auto_20201020_1601.py new file mode 100644 index 0000000..6dddfaa --- /dev/null +++ b/server/apps/ability/migrations/0014_auto_20201020_1601.py @@ -0,0 +1,23 @@ +# Generated by Django 3.0.5 on 2020-10-20 08:01 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('ability', '0013_inspection'), + ] + + operations = [ + migrations.AddField( + model_name='inspection', + name='sszx', + field=models.TextField(blank=True, null=True, verbose_name='所属中心'), + ), + migrations.AddField( + model_name='inspection', + name='type', + field=models.CharField(choices=[('center', '总部'), ('sub', '分子公司')], default='center', max_length=50, verbose_name='所属类型'), + ), + ] diff --git a/server/apps/ability/models.py b/server/apps/ability/models.py index 52830d6..f142712 100644 --- a/server/apps/ability/models.py +++ b/server/apps/ability/models.py @@ -25,6 +25,27 @@ class CMA(BaseModel): choices=type_choices, default='center') glzz = models.TextField('关联资质', null=True, blank=True) +class Inspection(BaseModel): + """ + 检验能力表 + """ + type_choices = ( + ('center', '总部'), + ('sub', '分子公司') + ) + dlxh = models.TextField('大类序号', null=True,blank=True) + dlmc = models.TextField('大类名称', null=True,blank=True) + dxxh = models.TextField('对象序号', null=True,blank=True) + jydx = models.TextField('检验对象', null=True,blank=True) + jyxmxh = models.TextField('检验项目序号', null=True,blank=True) + jyxmmc = models.TextField('检验项目名称', null=True,blank=True) + jybz = models.TextField('检验标准', null=True,blank=True) + sm = models.TextField('说明', null=True,blank=True) + sxrq = models.TextField('生效日期', null=True,blank=True) + sszx = models.TextField('所属中心',null=True,blank=True) + type = models.CharField('所属类型', max_length=50, + choices=type_choices, default='center') + class CNAS(BaseModel): """ CNAS检测能力表 diff --git a/server/apps/ability/serializers.py b/server/apps/ability/serializers.py index b552d98..b515e24 100644 --- a/server/apps/ability/serializers.py +++ b/server/apps/ability/serializers.py @@ -16,7 +16,13 @@ class CNASSerializer(serializers.ModelSerializer): class Meta: model = CNAS fields = '__all__' - +class InspectionSerializer(serializers.ModelSerializer): + """ + 检验能力反馈 + """ + class Meta: + model = Inspection + fields = '__all__' class QualificationotherSerializer(serializers.ModelSerializer): class Meta: model = Qualificationother diff --git a/server/apps/ability/urls.py b/server/apps/ability/urls.py index 2fbd263..adc0958 100644 --- a/server/apps/ability/urls.py +++ b/server/apps/ability/urls.py @@ -1,11 +1,12 @@ from django.urls import path, include from rest_framework import routers -from .views import CMAViewSet, CNASViewSet, QualificationViewSet +from .views import CMAViewSet, CNASViewSet, QualificationViewSet,InspectionViewSet router = routers.DefaultRouter() router.register('cma', CMAViewSet, basename="cma") router.register('cnas', CNASViewSet, basename="cnas") router.register('qualification', QualificationViewSet, basename="qualification") +router.register('inspection', InspectionViewSet, basename="inspection") urlpatterns = [ path('', include(router.urls)) ] \ No newline at end of file diff --git a/server/apps/ability/views.py b/server/apps/ability/views.py index bec7630..b6ad3a7 100644 --- a/server/apps/ability/views.py +++ b/server/apps/ability/views.py @@ -170,6 +170,78 @@ class QualificationViewSet(ModelViewSet): return Response(status = status.HTTP_200_OK) else: return Response('不支持非xlsx格式', status = status.HTTP_400_BAD_REQUEST) +class InspectionViewSet(ModelViewSet): + """ + CNAS检测能力:增删改查 + """ + perms_map = {'get': '*', 'post': 'inspection_create', + 'put': 'inspection_update', 'delete': 'inspection_delete'} + queryset = Inspection.objects.all() + serializer_class = InspectionSerializer + search_fields = ['dlmc', 'jydx', 'dxxh'] + ordering_fields = ['dlmc'] + ordering = 'dlmc' + filterset_fields = ['sszx'] + @action(methods=['post'], detail=False, url_path='deletes', url_name='inspection_deletes', perms_map = {'post':'inspection_deletes'}) + def deletes(self, request): + + array = request.data['ids'] + Inspection.objects.filter(pk__in=array).delete() + + return Response(status = status.HTTP_200_OK) + @action(methods=['get'], detail=False,url_name='inspection_group_by', perms_map = {'*':'*'}) + def group(self, request, pk=None): + """ + 聚合查询列 + """ + queryset = self.filter_queryset(self.get_queryset()) + ret = [] + if request.query_params.get('group_by', None): + group_by = request.query_params.get('group_by') + group_by_data = list(queryset.values(group_by).annotate(count=Count(group_by)).order_by(group_by)) + for i in group_by_data: + if i[group_by] and i['count']: + ret.append({'text':i[group_by]+'('+ str(i['count']) +')','value':i[group_by]}) + return Response(ret) + + @action(methods=['post'], detail=False, url_path='inspection2', url_name='inspection_inspection2', perms_map = {'post':'inspection_inspection2'}) + def inspection_import2(self, request, pk=None): + """ + 导入能力2 + """ + filepath = request.data['path'] + fullpath = settings.BASE_DIR + filepath + import os + if fullpath.endswith('.rar'): + rar = rarfile.RarFile(fullpath) + fulldir = fullpath.replace('.rar','') + os.mkdir(fulldir) + os.chdir(fulldir) + rar.extractall() + rar.close() + # CMA.objects.filter(type='sub').delete() + for root, dirs, files in os.walk(fulldir): + for f in files: + if f.endswith('.xlsx'): + import_inspection(f, os.path.join(root,f)) + else: + return Response('不支持非xlsx格式', status = status.HTTP_400_BAD_REQUEST) + elif fullpath.endswith('.zip'): + fulldir = fullpath.replace('.zip','') + os.mkdir(fulldir) + os.chdir(fulldir) + # CMA.objects.filter(type='sub').delete() + with zipfile.ZipFile(fullpath,'r') as zzz: + zzz.extractall(fulldir) + for root, dirs, files in os.walk(fulldir): + for f in files: + if f.endswith('.xlsx'): + import_inspection(f.encode('cp437').decode('gbk'), os.path.join(root,f)) + else: + return Response('不支持非xlsx格式', status = status.HTTP_400_BAD_REQUEST) + return Response(status = status.HTTP_200_OK) + + class CNASViewSet(ModelViewSet): """ CNAS检测能力:增删改查 @@ -401,4 +473,103 @@ def import_cma2(filename, path): data['type'] = 'sub' datalist.append(CMA(**data)) i = i + 1 - CMA.objects.bulk_create(datalist) \ No newline at end of file + CMA.objects.bulk_create(datalist) +def import_inspection(filename, path): + wb = load_workbook(path,data_only=True) + sheet = wb.worksheets[0] + datalist = [] + sszx = filename.split('-')[0] + if Inspection.objects.filter(sszx=sszx).exists(): + Inspection.objects.filter(sszx=sszx).delete() + i = 3 + max_row = sheet.max_row + while i