diff --git a/client/src/api/qualificationInfo.js b/client/src/api/qualificationInfo.js index 72506ec..2ebcc11 100644 --- a/client/src/api/qualificationInfo.js +++ b/client/src/api/qualificationInfo.js @@ -1,17 +1,25 @@ import request from '@/utils/request' -export function getMyQi(query) { +export function getAllQi(query) { return request({ url: '/info/faq/', method: 'get', params: query }) } + +export function getMyQi(query) { + return request({ + url: '/info/faqch/', + method: 'get', + params: query + }) +} export function getQi(id) { return request({ - url: `/info/faqch/?instance_id=${id}`, + url: `/info/ad/?instance_id=${id}`, method: 'get' }) } @@ -19,8 +27,8 @@ export function getQi(id) { export function updateQi(id, data) { return request({ - url: `/info/faq/${id}/`, - method: 'patch', + url: `/info/faqch/${id}/`, + method: 'put', data }) } diff --git a/client/src/router/index.js b/client/src/router/index.js index 4a3a82d..70b1879 100644 --- a/client/src/router/index.js +++ b/client/src/router/index.js @@ -457,6 +457,12 @@ export const asyncRoutes = [ component: () => import('@/views/informatiomCollect/externalAuditor.vue'), meta: { title: '外审员情况', perms: ['infoCollect_EA'] } }, + { + path: 'smsMessage', + name: 'smsMessage', + component: () => import('@/views/informatiomCollect/smsMessage.vue'), + meta: { title: '发送邮件', perms: ['infoCollect_SM']} + }, // { // path: 'inspectionStats', // name: 'inspectionStats', diff --git a/client/src/views/informatiomCollect/qualiChange copy.vue b/client/src/views/informatiomCollect/qualiChange copy.vue new file mode 100644 index 0000000..fe89d46 --- /dev/null +++ b/client/src/views/informatiomCollect/qualiChange copy.vue @@ -0,0 +1,104 @@ + + + \ No newline at end of file diff --git a/client/src/views/informatiomCollect/qualiChange.vue b/client/src/views/informatiomCollect/qualiChange.vue index fe89d46..aafe372 100644 --- a/client/src/views/informatiomCollect/qualiChange.vue +++ b/client/src/views/informatiomCollect/qualiChange.vue @@ -1,32 +1,139 @@ + \ No newline at end of file diff --git a/server/apps/information/migrations/0031_qualification_change_date.py b/server/apps/information/migrations/0031_qualification_change_date.py new file mode 100644 index 0000000..5f6c9d3 --- /dev/null +++ b/server/apps/information/migrations/0031_qualification_change_date.py @@ -0,0 +1,18 @@ +# Generated by Django 3.2.12 on 2024-04-24 04:21 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('information', '0030_alter_externalauditors_review_types'), + ] + + operations = [ + migrations.AddField( + model_name='qualification', + name='change_date', + field=models.DateField(blank=True, null=True, verbose_name='变更日期'), + ), + ] diff --git a/server/apps/information/models.py b/server/apps/information/models.py index fd04d55..f996c58 100644 --- a/server/apps/information/models.py +++ b/server/apps/information/models.py @@ -15,7 +15,7 @@ class Qualification(CommonBDModel): 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) - + change_date = models.DateField(verbose_name='变更日期', null=True, blank=True) class Meta: verbose_name = '资质情况' diff --git a/server/apps/information/serializers.py b/server/apps/information/serializers.py index a54c4f3..00ea47b 100644 --- a/server/apps/information/serializers.py +++ b/server/apps/information/serializers.py @@ -1,6 +1,8 @@ from rest_framework import serializers from apps.system.serializers import OrganizationSimpleSerializer +from apps.system.models import Organization from .models import AbilityReview, QualityCommendation, QualityActivities, Contact, ExternalAuditors, AuditLog, Qualification +from django.utils import timezone class BaseMeta: fields = '__all__' @@ -36,9 +38,16 @@ class ExternalAuditorsSerializer(serializers.ModelSerializer): class QualificationSerializer(serializers.ModelSerializer): class Meta(BaseMeta): model = Qualification - fields = ["id","name","company_name","quali_type","org","org_date","expiration_date","number","scope"] - + fields = ["id","name","company_name","quali_type","org","org_date","expiration_date","number","scope", "change_date"] + def create(self, validated_data): + validated_data["belong_dept_id"] = Organization.objects.filter(name = validated_data.get("company_name")).first().id + return super().create(validated_data) + + def update(self, instance, validated_data): + validated_data["change_date"] = timezone.now().date() + return super().update(instance, validated_data) + class AbilityReviewSerializer(serializers.ModelSerializer): quali_name = serializers.CharField(source='quali.name', read_only=True) diff --git a/server/apps/information/urls.py b/server/apps/information/urls.py index d4a9c2d..120530f 100644 --- a/server/apps/information/urls.py +++ b/server/apps/information/urls.py @@ -1,6 +1,6 @@ from django.urls import path, include from rest_framework import routers -from .views import AbilityReviewViewSet, QualityCommendationViewSet, QualityActivitiesViewSet, QualiChangeViewSet, ContactViewSet, ExternalAuditorsViewSet, QualificationViewSet +from .views import AbilityReviewViewSet, AuditLogViewSet, QualityCommendationViewSet, QualityActivitiesViewSet, QualiChangeViewSet, ContactViewSet, ExternalAuditorsViewSet, QualificationViewSet router = routers.DefaultRouter() router.register('ar', AbilityReviewViewSet, basename='abilityreviews') @@ -10,6 +10,7 @@ router.register('contact', ContactViewSet, basename='contact') router.register('ea', ExternalAuditorsViewSet, basename='externalauditors') router.register('faq', QualificationViewSet, basename='faq') router.register('faqch', QualiChangeViewSet, basename='faqch') +router.register('ad', AuditLogViewSet, basename='ad') urlpatterns = [ path('', include(router.urls)) diff --git a/server/apps/information/views.py b/server/apps/information/views.py index b57ba12..c5bc50c 100644 --- a/server/apps/information/views.py +++ b/server/apps/information/views.py @@ -276,6 +276,7 @@ class QualityActivitiesViewSet(ImpMixin, RbacFilterSet, CreateUpdateCustomMixin, data_list = [] for row in sheet.iter_rows(min_row=start, values_only=True): # 假设第一行是表头,从第二行开始读取数据 if row[0] is not None: + department_id = Organization.objects.filter(name=row[4]).first().id activate_time = row[6].strftime("%Y-%m-%d") role_dict = {"组织方":0, "参与方":1} serializer_data = { @@ -287,7 +288,8 @@ class QualityActivitiesViewSet(ImpMixin, RbacFilterSet, CreateUpdateCustomMixin, 'activate_time':activate_time, 'participations':row[7], 'function':row[8], - 'earnings':row[9] + 'earnings':row[9], + 'belong_dept':department_id, } data_list.append(serializer_data) return data_list @@ -300,7 +302,7 @@ class QualityActivitiesViewSet(ImpMixin, RbacFilterSet, CreateUpdateCustomMixin, return self.gen_imp_view(request, 2, QualityActivitiesSerializer) -class ContactViewSet(RbacFilterSet, CreateUpdateCustomMixin, ModelViewSet): +class ContactViewSet(CreateUpdateCustomMixin, ModelViewSet): queryset = Contact.objects.all() serializer_class = ContactSerializer @@ -377,6 +379,7 @@ class ExternalAuditorsViewSet(ImpMixin, RbacFilterSet, CreateUpdateCustomMixin, data_list = [] for row in sheet.iter_rows(min_row=start, values_only=True): # 假设第一行是表头,从第二行开始读取数据 if row[0] is not None: + department_id = Organization.objects.filter(name=row[1]).first().id activate_time = row[4].strftime("%Y-%m-%d") serializer_data = { 'name_company': row[1], # 第一列是名字 @@ -386,6 +389,7 @@ class ExternalAuditorsViewSet(ImpMixin, RbacFilterSet, CreateUpdateCustomMixin, 'contact':row[5], 'judging_areas':row[6], 'remark':row[7], + 'belong_dept':department_id, } data_list.append(serializer_data) return data_list @@ -398,43 +402,26 @@ class ExternalAuditorsViewSet(ImpMixin, RbacFilterSet, CreateUpdateCustomMixin, return self.gen_imp_view(request, 2, ExternalAuditorsSerializer) -class QualificationViewSet(CreateUpdateCustomMixin, ModelViewSet): +class QualificationViewSet(ModelViewSet): queryset = Qualification.objects.all() serializer_class = QualificationSerializer - - # # 重写更新的方法 - # 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({'old':origin_value, 'new':v, 'name':k}) - # 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=instance, - # change_time = datetime.now(), - # change_user=request.user, - # val_new=serializers.data, - # difference=diff - # ) - # return Response(serializers.data, status = status.HTTP_204_NO_CONTENT) + perms_map = {'get': '*', 'post': 'qa_create', + 'put': 'qa_update', 'delete': 'qa_delete'} -class QualiChangeViewSet(RbacFilterSet, ModelViewSet): +class AuditLogViewSet(RbacFilterSet, CreateUpdateCustomMixin, ModelViewSet): queryset = AuditLog.objects.select_related('instance').all() serializer_class = AuditLogSerializer filterset_fields = ['instance_id'] + +class QualiChangeViewSet(RbacFilterSet, CreateUpdateCustomMixin, ModelViewSet): + queryset = Qualification.objects.all() + serializer_class = QualificationSerializer + perms_map = {'get': '*', 'post': 'qchange_create', + 'put': 'qchange_update', 'patch': 'qchange_update', 'delete': 'qchange_delete'} + + # 重写更新的方法 def partial_update(self, request, pk=None): #获取需要更新的实列 diff --git a/server/apps/system/views.py b/server/apps/system/views.py index 8057ae8..1921ecd 100644 --- a/server/apps/system/views.py +++ b/server/apps/system/views.py @@ -105,32 +105,41 @@ class sendMsg(APIView): def post(self, request): code = random.randint(10000,99999) my_sender = 'gxpt@ctc.ac.cn' - my_user = request.data['mail'] + # 材料报送二级单位和三级单位 + names = request.data['names'] + role_ids = [role.id for role in Role.objects.filter(name__in=names)] + reci_users = [] + for i in role_ids: + role = Role.objects.get(id=i) + users = role.user_set.all() + username = users.values_list('username', flat=True) + reci_users.extend(username) my_pass = 'Pintai123' - if not User.objects.filter(username=my_user).exists(): - return Response('该账户不存在', status=status.HTTP_400_BAD_REQUEST) + # if not User.objects.filter(username=my_user).exists(): + # return Response('该账户不存在', status=status.HTTP_400_BAD_REQUEST) try: - # 邮件内容 - msg=MIMEText('您好,共享平台本次登陆验证码为' + str(code),'plain','utf-8') - # 括号里的对应发件人邮箱昵称、发件人邮箱账号 - msg['From']=formataddr(["国检集团检验检测能力共享平台",my_sender]) - # 括号里的对应收件人邮箱昵称、收件人邮箱账号 - msg['To']=formataddr(["",my_user]) - # 邮件的主题 - msg['Subject'] = Header(str(code), 'utf-8').encode() - - # SMTP服务器,腾讯企业邮箱端口是465,腾讯邮箱支持SSL(不强制), 不支持TLS - # qq邮箱smtp服务器地址:smtp.qq.com,端口号:456 - # 163邮箱smtp服务器地址:smtp.163.com,端口号:25 - server=smtplib.SMTP_SSL("smtp.exmail.qq.com", 465) - # 登录服务器,括号中对应的是发件人邮箱账号、邮箱密码 - server.login(my_sender, my_pass) - # 发送邮件,括号中对应的是发件人邮箱账号、收件人邮箱账号、发送邮件 - server.sendmail(my_sender,[my_user,],msg.as_string()) + for u in reci_users: + # 邮件内容 + msg=MIMEText('您好,共享平台本次登陆验证码为' + str(code),'plain','utf-8') + # 括号里的对应发件人邮箱昵称、发件人邮箱账号 + msg['From']=formataddr(["国检集团检验检测能力共享平台",my_sender]) + # 括号里的对应收件人邮箱昵称、收件人邮箱账号 + msg['To']=formataddr(["",u]) + # 邮件的主题 + msg['Subject'] = Header(str(code), 'utf-8').encode() + + # SMTP服务器,腾讯企业邮箱端口是465,腾讯邮箱支持SSL(不强制), 不支持TLS + # qq邮箱smtp服务器地址:smtp.qq.com,端口号:456 + # 163邮箱smtp服务器地址:smtp.163.com,端口号:25 + server=smtplib.SMTP_SSL("smtp.exmail.qq.com", 465) + # 登录服务器,括号中对应的是发件人邮箱账号、邮箱密码 + server.login(my_sender, my_pass) + # 发送邮件,括号中对应的是发件人邮箱账号、收件人邮箱账号、发送邮件 + server.sendmail(my_sender,[u,],msg.as_string()) + Message.objects.filter(mail=u).delete() + Message.objects.create(mail=u, msg=code) # 关闭连接 - server.quit() - Message.objects.filter(mail=my_user).delete() - Message.objects.create(mail=my_user, msg=code) + server.quit() except: return Response('验证码发送失败', status=status.HTTP_400_BAD_REQUEST) return Response(status=status.HTTP_200_OK)