From 2aad51811cf0875e2bf83e24e8c2bdab7b6c02a3 Mon Sep 17 00:00:00 2001 From: caoqianming Date: Fri, 3 Mar 2023 10:01:37 +0800 Subject: [PATCH 1/5] =?UTF-8?q?=E5=A2=9E=E5=8A=A0dpm=20=E5=8F=8C=E6=8E=A7a?= =?UTF-8?q?pp?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/dpm/__init__.py | 0 apps/dpm/admin.py | 3 + apps/dpm/apps.py | 7 ++ apps/dpm/migrations/__init__.py | 0 apps/dpm/models.py | 155 ++++++++++++++++++++++++++++++++ apps/dpm/serializers.py | 128 ++++++++++++++++++++++++++ apps/dpm/tasks.py | 30 +++++++ apps/dpm/tests.py | 3 + apps/dpm/urls.py | 13 +++ apps/dpm/views.py | 71 +++++++++++++++ 10 files changed, 410 insertions(+) create mode 100644 apps/dpm/__init__.py create mode 100644 apps/dpm/admin.py create mode 100644 apps/dpm/apps.py create mode 100644 apps/dpm/migrations/__init__.py create mode 100644 apps/dpm/models.py create mode 100644 apps/dpm/serializers.py create mode 100644 apps/dpm/tasks.py create mode 100644 apps/dpm/tests.py create mode 100644 apps/dpm/urls.py create mode 100644 apps/dpm/views.py diff --git a/apps/dpm/__init__.py b/apps/dpm/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/apps/dpm/admin.py b/apps/dpm/admin.py new file mode 100644 index 00000000..8c38f3f3 --- /dev/null +++ b/apps/dpm/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/apps/dpm/apps.py b/apps/dpm/apps.py new file mode 100644 index 00000000..456386e9 --- /dev/null +++ b/apps/dpm/apps.py @@ -0,0 +1,7 @@ +from django.apps import AppConfig + + +class DpmConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'dpm' + verbose_name = '双重预防' \ No newline at end of file diff --git a/apps/dpm/migrations/__init__.py b/apps/dpm/migrations/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/apps/dpm/models.py b/apps/dpm/models.py new file mode 100644 index 00000000..6ae90017 --- /dev/null +++ b/apps/dpm/models.py @@ -0,0 +1,155 @@ +from django.db import models +from apps.utils.models import CommonBModel, CommonAModel +from django_celery_beat.models import PeriodicTask + +# Create your models here. +class RiskPoint(CommonBModel): + """ + 风险点表 + """ + R_LEVEL = ( + (10, '低风险'), + (20, '一般风险'), + (30, '较大风险'), + (40, '重大风险') + ) + R_TYPE = ( + (10, '作业活动类'), + (20, '设备设施类') + ) + R_M_LEVEL = ( + (10, '岗位级'), + (20, '班组级'), + (30, '部门级'), + (40, '公司级') + ) + name = models.CharField('名称', max_length=40) + area = models.ForeignKey('am.area', on_delete=models.CASCADE, verbose_name='所在区域', related_name='riskpoint_area', null=True, blank=True) + place = models.CharField('具体地点', max_length=100, null=True, blank=True) + level = models.PositiveSmallIntegerField('风险点等级', default=10, choices=R_LEVEL) + type = models.PositiveSmallIntegerField('风险点类型', default=10, choices=R_TYPE) + manage_level = models.PositiveSmallIntegerField('管控层级', default=10, choices=R_M_LEVEL) + dept_res = models.ForeignKey('system.dept', on_delete=models.SET_NULL, verbose_name='责任部门', related_name='riskpoint_dept_res', null=True, blank=True) + user_res = models.ForeignKey('system.user', on_delete=models.CASCADE, verbose_name='责任人', related_name='hazard_user_discover', null=True, blank=True) + +class Risk(CommonBModel): + """ + 风险表 + """ + name = models.TextField('项目/步骤') + level = models.PositiveSmallIntegerField('风险等级', default=10, choices=RiskPoint.R_LEVEL) + standard = models.TextField('检查标准', null=True, blank=True) + hazard = models.TextField('危害因素', null=True, blank=True) + results = models.ManyToManyField('system.dictionary', verbose_name='可能后果', related_name='risk_results', null=True) + sort = models.PositiveSmallIntegerField('排序', default=1) + measure_tech = models.TextField('工程技术措施', null=True, blank=True) + measure_manage = models.TextField('管理措施', null=True, blank=True) + measure_edu = models.TextField('培训教育措施', null=True, blank=True) + measure_protect = models.TextField('个体防护措施', null=True, blank=True) + measure_emer = models.TextField('应急处置措施', null=True, blank=True) + riskl = models.DecimalField(max_digits=6, decimal_places=1, null=True, blank=True) + riske = models.DecimalField(max_digits=6, decimal_places=1, null=True, blank=True) + riskc = models.DecimalField(max_digits=6, decimal_places=1, null=True, blank=True) + riskd = models.DecimalField(max_digits=6, decimal_places=1, null=True, blank=True) + riskpoint = models.ForeignKey(RiskPoint, on_delete=models.CASCADE, verbose_name='所属风险点') + + +class CheckTaskSet(CommonBModel): + """ + 检查任务派发设置 + """ + riskpoint = models.ForeignKey(RiskPoint, verbose_name='关联风险点', related_name='ctask_riskpoint', on_delete=models.SET_NULL, null=True, blank=True) + note = models.TextField('派发备注', null=True, blank=True) + expire = models.PositiveSmallIntegerField('执行有效期(h)', default=0, help_text='0代表不设限制直到下个任务派发') + user_duty = models.ForeignKey('system.user', verbose_name='指派人', on_delete=models.SET_NULL, null=True, blank=True) + myschedule = models.ForeignKey('system.myschedule', verbose_name='周期', on_delete=models.SET_NULL, null=True, blank=True) + periodictask = models.ForeignKey(PeriodicTask, verbose_name='关联定时任务', on_delete=models.CASCADE, related_name='checktask_periodictask') + + +class CheckWork(CommonBModel): + """ + 检查工作 + """ + CW_TYPE = ( + (10, '手动'), + (20, '派发') + ) + name = models.CharField('名称', max_length=40) + description = models.TextField('工作描述', null=True, blank=True) + type = models.PositiveSmallIntegerField('任务类型', default=10, choices=CW_TYPE) + category = models.ForeignKey('system.dictionary', on_delete=models.CASCADE, verbose_name='工作分类', null=True, blank=True) + time_start = models.DateTimeField('开启时间') + time_end = models.DateTimeField('关闭时间') + enabled = models.BooleanField('是否可用', default=True) + user_duty = models.ForeignKey('system.user', verbose_name='指派人', on_delete=models.SET_NULL, null=True, blank=True) + riskpoint = models.ForeignKey(RiskPoint, verbose_name='关联风险点', related_name='cwork_riskpoint', on_delete=models.SET_NULL, null=True, blank=True) + note = models.TextField('检查备注', null=True, blank=True) + time_check = models.BooleanField('最后检查时间', default=True) + checktaskset = models.ForeignKey(CheckTaskSet, verbose_name='关联派发任务', on_delete=models.CASCADE, null=True, blank=True) + + +class Hazard(CommonBModel): + """ + 事故隐患表 + """ + H_HARM = ( + (10, '无伤害'), + (20, '轻微伤'), + (30, '轻伤'), + (40, '重伤'), + (50, '死亡') + ) + H_LEVEL = ( + (10, '无隐患'), + (20, '一般隐患'), + (30, '重大隐患') + ) + H_STATE = ( + (10, '待提交'), + (20, '流程中'), + (30, '已结束') + ) + number = models.CharField('编号', max_length=20, null=True, blank=True) + checkwork = models.ForeignKey(CheckWork, verbose_name='关联检查工作', null=True, blank=True) + state = models.PositiveSmallIntegerField('隐患流程状态', default=10, choices=H_STATE) + time_discover = models.DateTimeField('发现时间') + dept_res = models.ForeignKey('system.dept', on_delete=models.SET_NULL, verbose_name='责任部门', related_name='hazard_dept_res', null=True, blank=True) + user_discover = models.ForeignKey('system.user', on_delete=models.CASCADE, verbose_name='发现人', related_name='hazard_user_discover') + area = models.ForeignKey('am.area', on_delete=models.CASCADE, verbose_name='所在区域', null=True, blank=True) + place = models.CharField('具体地点', max_length=100, null=True, blank=True) + level = models.PositiveSmallIntegerField('隐患等级', default=10, choices=H_LEVEL) + harm_access = models.PositiveSmallIntegerField('伤害评估', default=10, choices=H_HARM) + category = models.ForeignKey('system.dictionary', on_delete=models.CASCADE, verbose_name='隐患类别', null=True, blank=True) + description = models.TextField('隐患描述', null=True, blank=True) + reason = models.TextField('原因分析', null=True, blank=True) + correct_measure = models.TextField('整改措施', null=True, blank=True) + correct_solution = models.ForeignKey('system.file', verbose_name='整改方案', null=True, blank=True) + correct_deadline = models.DateTimeField('整改期限', null=True, blank=True) + photos = models.ManyToManyField('system.file', verbose_name='现场照片', related_name='hazard_photos', null=True) + correct_description = models.TextField('整改描述', null=True, blank=True) + photos_done = models.ManyToManyField('system.file', verbose_name='整改后照片', related_name='hazard_photos_done', null=True) + dept_correct = models.ForeignKey('system.dept', on_delete=models.CASCADE, verbose_name='整改部门', related_name='hazard_dept_correct', null=True, blank=True) + user_correct = models.ForeignKey('system.user', on_delete=models.SET_NULL, verbose_name='整改责任人', related_name='hazard_user_correct', null=True, blank=True) + correct_time = models.DateTimeField('整改完成时间', null=True, blank=True) + user_access = models.ForeignKey('system.user', on_delete=models.CASCADE, verbose_name='评估人', related_name='hazard_user_access') + opinion_access = models.TextField('评估意见', null=True, blank=True) + user_check = models.ForeignKey('system.user', on_delete=models.CASCADE, verbose_name='复查人', related_name='hazard_user_check') + opinion_check = models.TextField('复查意见', null=True, blank=True) + user_audit = models.ForeignKey('system.user', on_delete=models.CASCADE, verbose_name='审核人', related_name='hazard_user_audit') + opinion_audit = models.TextField('审核意见', null=True, blank=True) + ticket = models.ForeignKey('wf.ticket', on_delete=models.SET_NULL, verbose_name='关联工单', related_name='hazard_ticket', null=True, blank=True) + + +class CheckItem(CommonAModel): + """ + 检查工作-隐患关联表 + """ + CITEM_RESULT = ( + (10, '未检查'), + (20, '合格'), + (30, '不合格') + ) + checkwork = models.ForeignKey(CheckWork, verbose_name='关联检查工作', related_name='citem_checkwork', on_delete=models.CASCADE) + risk = models.ForeignKey(Risk, verbose_name='关联风险', related_name='citem_risk', on_delete=models.SET_NULL, null=True, blank=True) + hazard = models.ForeignKey(Hazard, verbose_name='关联隐患', related_name='citem_hazard', on_delete=models.SET_NULL, null=True, blank=True) + result = models.PositiveSmallIntegerField('检查结果', default=10) diff --git a/apps/dpm/serializers.py b/apps/dpm/serializers.py new file mode 100644 index 00000000..ab85d9bc --- /dev/null +++ b/apps/dpm/serializers.py @@ -0,0 +1,128 @@ +import json +from apps.dpm.models import CheckTaskSet, CheckWork, RiskPoint, Risk +from rest_framework import serializers +from apps.utils.serializers import CustomModelSerializer +from apps.utils.constants import EXCLUDE_FIELDS +from apps.system.models import Dictionary +from django_celery_beat.models import PeriodicTask +import time + + +class RiskPointCreateUpdateSerializer(CustomModelSerializer): + class Meta: + model = RiskPoint + exclude = EXCLUDE_FIELDS + + +class RiskPointSerializer(CustomModelSerializer): + class Meta: + model = RiskPoint + fields = '__all__' + + +class RiskCreateUpdateSerializer(CustomModelSerializer): + class Meta: + model = Risk + exclude = EXCLUDE_FIELDS + ['riskd'] + + def save(self, **kwargs): + obj = super().save(**kwargs) + if obj.riskl and obj.riske and obj.riskc: + obj.riskd = obj.riskl * obj.riske * obj.riskc + if obj.riskd >= 320: + obj.level = 40 + elif 320 > obj.riskd >= 160: + obj.level = 30 + elif 160 > obj.riskd >= 70: + obj.level = 20 + else: + obj.level = 10 + obj.save() + self.cal_riskpoint_level(obj) + return obj + + @staticmethod + def cal_riskpoint_level(risk): + """ + 计算风险点风险等级 + """ + riskpoint = risk.riskpoint + levels = Risk.objects.filter(riskpoint=riskpoint).values_list('level', flat=True) + riskpoint.level = max(levels) + riskpoint.save() + RiskCreateUpdateSerializer.cal_area_level(riskpoint) + + @staticmethod + def cal_area_level(riskpoint): + """ + 计算区域风险等级 + """ + area = riskpoint.area + if area: + levels = RiskPoint.objects.filter(area=area).values_list('level', flat=True) + area.level = max(levels) + area.save() + + +class RiskSerializer(CustomModelSerializer): + class Meta: + model = Risk + fields = '__all__' + + +class CheckTaskSetCreateUpdateSerializer(CustomModelSerializer): + class Meta: + model = CheckTaskSet + exclude = EXCLUDE_FIELDS + ['periodictask'] + + def save(self, **kwargs): + ins = super().save(**kwargs) + if ins.periodictask: + pobj = ins.periodictask + pobj.name = 'checktask_' + time.strftime('%Y%m%d%H%M%S') + pobj.task = 'apps.dpm.dispath_checkwork_task' + pobj.kwargs = json.dumps({'checktaskset': ins.id}) + else: + pobj = PeriodicTask() + sch = ins.myschedule + if sch.crontab: + pobj.crontab = sch.crontab + elif sch.interval: + pobj.interval = sch.interval + pobj.save() + ins.periodictask = pobj + ins.save() + return ins + + +class CheckTaskSetSerializer(CustomModelSerializer): + enabled = serializers.BooleanField(source='periodictask.enabled', read_only=True) + last_run_at = serializers.DateTimeField(source='periodictask.last_run_at', read_only=True) + total_run_count = serializers.IntegerField(source='periodictask.total_run_count', read_only=True) + + class Meta: + model = CheckTaskSet + fields = '__all__' + + +class CheckWork_10_CreateUpdateSerializer(CustomModelSerializer): + category = serializers.PrimaryKeyRelatedField( + label='检查分类', queryset=Dictionary.objects.filter(type__code='checkwork_category')) + + class Meta: + model = CheckWork + fields = ['name', 'description', 'category', 'time_start', 'time_end', 'enabled'] + + def save(self, **kwargs): + kwargs['type'] = 10 # 创建/编辑只有手动类型 + return super().save(**kwargs) + + +class CheckWorkSerializer(CustomModelSerializer): + category_name = serializers.CharField(source='category.name', read_only=True) + user_duty_name = serializers.CharField(source='user_duty.name', read_only=True) + riskpoint_name = serializers.CharField(source='riskpoint.name', read_only=True) + + class Meta: + model = CheckWork + fields = '__all__' diff --git a/apps/dpm/tasks.py b/apps/dpm/tasks.py new file mode 100644 index 00000000..12f7a7a9 --- /dev/null +++ b/apps/dpm/tasks.py @@ -0,0 +1,30 @@ +from apps.utils.tasks import CustomTask +from celery import shared_task +from apps.dpm.models import CheckTaskSet, CheckWork +from django.utils import timezone +from datetime import timedelta + + +@shared_task(base=CustomTask) +def dispath_checkwork_task(checktaskset: str): + cts = CheckTaskSet.objects.get(id=checktaskset) + cw = CheckWork() + cw.type = 20 + cw.checktaskset = cts + cw.name = '风险点检查(自动派发)' + now = timezone.now() + cw.time_start = now + if cts.expire: + cw.time_end = now + timedelta(hours=cts.expire) + cw.user_duty = cts.user_duty + cw.riskpoint = cts.riskpoint + cw.note = cts.note + cw.save() + # 发送通知 + pass + + +@shared_task(base=CustomTask) +def expire_checkwork(): + now = timezone.now() + CheckWork.objects.filter(expire__gte=now).update(enabled=False) diff --git a/apps/dpm/tests.py b/apps/dpm/tests.py new file mode 100644 index 00000000..7ce503c2 --- /dev/null +++ b/apps/dpm/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/apps/dpm/urls.py b/apps/dpm/urls.py new file mode 100644 index 00000000..ee1ca829 --- /dev/null +++ b/apps/dpm/urls.py @@ -0,0 +1,13 @@ +from apps.dpm.views import RiskPointViewSet, RiskViewSet +from django.urls import path, include +from rest_framework.routers import DefaultRouter + +API_BASE_URL = 'api/dpm/' +HTML_BASE_URL = 'dpm/' +# cache_areas_info() +router = DefaultRouter() +router.register('riskpoint', RiskPointViewSet, basename='riskpoint') +router.register('risk', RiskViewSet, basename='risk') +urlpatterns = [ + path(API_BASE_URL, include(router.urls)), +] diff --git a/apps/dpm/views.py b/apps/dpm/views.py new file mode 100644 index 00000000..51c0fa30 --- /dev/null +++ b/apps/dpm/views.py @@ -0,0 +1,71 @@ +from apps.dpm.serializers import RiskPointCreateUpdateSerializer, RiskPointSerializer, RiskCreateUpdateSerializer, RiskSerializer, CheckTaskSetCreateUpdateSerializer, CheckTaskSetSerializer, CheckWork_10_CreateUpdateSerializer, CheckWorkSerializer +from apps.utils.viewsets import CustomModelViewSet +from apps.dpm.models import CheckTaskSet, CheckWork, RiskPoint, Risk +from rest_framework.decorators import action +from rest_framework.response import Response +from django.db import transaction + + +# Create your views here. +class RiskPointViewSet(CustomModelViewSet): + queryset = RiskPoint.objects.all() + create_serializer_class = RiskPointCreateUpdateSerializer + update_serializer_class = RiskPointCreateUpdateSerializer + serializer_class = RiskPointSerializer + select_related_fields = ['area', 'dept_res', 'user_res'] + search_fields = ['name'] + filterset_fields = ['area', 'type', 'level', 'manage_level'] + + +class RiskViewSet(CustomModelViewSet): + queryset = Risk.objects.all() + create_serializer_class = RiskCreateUpdateSerializer + update_serializer_class = RiskCreateUpdateSerializer + serializer_class = RiskSerializer + select_related_fields = ['riskpoint'] + prefetch_related_fields = ['results'] + search_fields = ['name'] + filterset_fields = ['results'] + + +class CheckTaskSetViewSet(CustomModelViewSet): + queryset = CheckTaskSet.objects.all() + create_serializer_class = CheckTaskSetCreateUpdateSerializer + update_serializer_class = CheckTaskSetCreateUpdateSerializer + serializer_class = CheckTaskSetSerializer + select_related_fields = ['periodictask'] + search_fields = ['note'] + filterset_fields = ['periodictask__enabled'] + + @action(methods=['put'], detail=True, perms_map={'put': 'checktaskset.update'}) + def toggle(self, request, pk=None): + """修改启用禁用状态 + + 修改启用禁用状态 + """ + obj = self.get_object() + periodictask = obj.periodictask + periodictask.enabled = False if periodictask.enabled else True + periodictask.save() + return Response() + + def perform_destroy(self, instance): + with transaction.atomic(): + periodictask = instance.periodictask + instance.delete() + periodictask.enabled = False + periodictask.save() + + +class CheckWorkViewSet(CustomModelViewSet): + queryset = CheckWork.objects.all() + create_serializer_class = CheckWork_10_CreateUpdateSerializer + update_serializer_class = CheckWork_10_CreateUpdateSerializer + serializer_class = CheckWorkSerializer + search_fields = ['name', 'description'] + select_related_fields = ['category', 'user_duty', 'riskpoint'] + filterset_fields = ['type', 'category', 'riskpoint'] + + +class HazardViewSet(CustomModelViewSet): + pass From 0a59af9c656f2ea0a3457f43136c97b71101058d Mon Sep 17 00:00:00 2001 From: caoqianming Date: Fri, 3 Mar 2023 10:02:09 +0800 Subject: [PATCH 2/5] =?UTF-8?q?=E5=A2=9E=E5=8A=A0edu=20app?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/edu/migrations/__init__.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 apps/edu/migrations/__init__.py diff --git a/apps/edu/migrations/__init__.py b/apps/edu/migrations/__init__.py new file mode 100644 index 00000000..e69de29b From 0bb4595ee62efb7462a8e2f5487871cf1edfafd0 Mon Sep 17 00:00:00 2001 From: caoqianming Date: Fri, 3 Mar 2023 10:02:41 +0800 Subject: [PATCH 3/5] =?UTF-8?q?=E5=A2=9E=E5=8A=A0myschedule?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/system/serializers.py | 43 +++++++++++++++++++++++++++++++++++--- apps/system/views.py | 32 +++++++++++++++++++++++++--- 2 files changed, 69 insertions(+), 6 deletions(-) diff --git a/apps/system/serializers.py b/apps/system/serializers.py index a9913c12..618c84dc 100755 --- a/apps/system/serializers.py +++ b/apps/system/serializers.py @@ -9,7 +9,7 @@ from apps.utils.fields import MyFilePathField from apps.utils.serializers import CustomModelSerializer from apps.utils.constants import EXCLUDE_FIELDS, EXCLUDE_FIELDS_BASE from apps.utils.tools import check_phone_e -from .models import (Dictionary, DictType, File, Dept, Permission, Post, PostRole, +from .models import (Dictionary, DictType, File, Dept, MySchedule, Permission, Post, PostRole, Role, User, UserPost) from rest_framework.exceptions import ParseError, ValidationError from django.db import transaction @@ -385,7 +385,6 @@ class PostRoleCreateSerializer(CustomModelSerializer): class UserInfoSerializer(CustomModelSerializer): - class Meta: model = User fields = ['id', 'username', 'name', 'post', 'avatar', 'belong_dept', 'type'] @@ -394,4 +393,42 @@ class UserInfoSerializer(CustomModelSerializer): class ApkSerializer(serializers.Serializer): version = serializers.CharField(label='版本号') file = serializers.CharField(label='文件地址') - \ No newline at end of file + + +class IntervalScheduleSerializer(serializers.ModelSerializer): + class Meta: + model = IntervalSchedule + fields = '__all__' + + +class CrontabScheduleSerializer(serializers.ModelSerializer): + class Meta: + model = CrontabSchedule + exclude = ['timezone'] + + +class MyScheduleCreateSerializer(CustomModelSerializer): + interval_ = IntervalScheduleSerializer(allow_null=True, required=False) + crontab_ = CrontabScheduleSerializer(allow_null=True, required=False) + + class Meta: + model = MySchedule + fields = ['name', 'type', 'interval_', 'crontab_'] + + def validate(self, attrs): + if attrs['type'] == 10 and attrs.get('interval_', None): + pass + elif attrs['type'] == 20 and attrs.get('crontab_', None): + pass + else: + raise ValidationError('信息有误') + return super().validate(attrs) + + +class MyScheduleSerializer(CustomModelSerializer): + interval_ = IntervalScheduleSerializer(source='interval', read_only=True) + crontab = CrontabScheduleSerializer(source='crontab', read_only=True) + + class Meta: + model = MySchedule + fields = '__all__' diff --git a/apps/system/views.py b/apps/system/views.py index c7ad694b..3f11301c 100755 --- a/apps/system/views.py +++ b/apps/system/views.py @@ -26,7 +26,7 @@ from apps.utils.permission import ALL_PERMS, get_user_perms_map from apps.utils.viewsets import CustomGenericViewSet, CustomModelViewSet from server.celery import app as celery_app from .models import (Dept, Dictionary, DictType, File, Permission, Post, PostRole, Role, User, - UserPost) + UserPost, MySchedule) from .serializers import (ApkSerializer, DeptCreateUpdateSerializer, DeptSerializer, DictCreateUpdateSerializer, DictSerializer, DictTypeCreateUpdateSerializer, DictTypeSerializer, FileSerializer, PasswordChangeSerializer, PermissionCreateUpdateSerializer, @@ -35,7 +35,7 @@ from .serializers import (ApkSerializer, DeptCreateUpdateSerializer, DeptSeriali PTaskSerializer, PTaskCreateUpdateSerializer, PTaskResultSerializer, RoleCreateUpdateSerializer, RoleSerializer, TaskRunSerializer, UserCreateSerializer, UserListSerializer, UserPostCreateSerializer, - UserPostSerializer, UserUpdateSerializer) + UserPostSerializer, UserUpdateSerializer, MyScheduleCreateSerializer, MyScheduleSerializer) from rest_framework.viewsets import GenericViewSet @@ -663,4 +663,30 @@ class ApkViewSet(MyLoggingMixin, ListModelMixin, CreateModelMixin, GenericViewSe config.write(f) from shutil import copyfile copyfile(settings.BASE_DIR + vdata['file'], settings.BASE_DIR + '/media/zc_ehs.apk') - return Response() \ No newline at end of file + return Response() + + +class MyScheduleViewSet(ListModelMixin, CreateModelMixin, DestroyModelMixin, CustomGenericViewSet): + perms_map = {'get': '*', 'post': 'myschedule.create', 'delete': 'myschedule.delete'} + serializer_class = MyScheduleSerializer + create_serializer_class = MyScheduleCreateSerializer + queryset = MySchedule.objects.all() + select_related_fields = ['interval', 'crontab'] + + @transaction.atomic + def perform_create(self, serializer): + vdata = serializer.validated_data + vdata['create_by'] = self.request.user #不可少 + interval_data = vdata.pop('interval_', None) + crontab_data = vdata.pop('crontab_', None) + if vdata['type'] == 10: + interval, _ = IntervalSchedule.objects.get_or_create(**interval_data, defaults=interval_data) + obj = MySchedule(**vdata) + obj.interval = interval + obj.save() + elif vdata['type'] == 20: + crontab_data['timezone'] = 'Asia/Shanghai' + crontab, _ = CrontabSchedule.objects.get_or_create(**crontab_data, defaults=crontab_data) + obj = MySchedule(**vdata) + obj.crontab = crontab + obj.save() From f96a62d5e94dd670a980f03d0f743fb9d12c88da Mon Sep 17 00:00:00 2001 From: caoqianming Date: Fri, 3 Mar 2023 10:03:10 +0800 Subject: [PATCH 4/5] =?UTF-8?q?=E5=A2=9E=E5=8A=A0myschedule=20model?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/system/models.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/apps/system/models.py b/apps/system/models.py index a9cb2dba..e7e34e6e 100755 --- a/apps/system/models.py +++ b/apps/system/models.py @@ -2,6 +2,7 @@ from django.contrib.auth.models import UserManager from django.db import models from django.contrib.auth.models import AbstractUser from apps.utils.models import CommonADModel, CommonAModel, CommonBModel, BaseModel, SoftDeletableManagerMixin +from django_celery_beat.models import IntervalSchedule, CrontabSchedule class DataFilter(models.IntegerChoices): @@ -237,3 +238,17 @@ class File(CommonAModel): def __str__(self): return self.name + + +class MySchedule(CommonAModel): + """ + 常用周期 + """ + MS_TYPE = ( + (10, '间隔'), + (20, '定时') + ) + name = models.CharField('名称', max_length=200) + type = models.PositiveSmallIntegerField('周期类型', default=10) + interval = models.ForeignKey(IntervalSchedule, on_delete=models.PROTECT, null=True, blank=True) + crontab = models.ForeignKey(CrontabSchedule, on_delete=models.PROTECT, null=True, blank=True) \ No newline at end of file From 6f25ebdd42aaac2348ddd8b6ff4e83773cb08463 Mon Sep 17 00:00:00 2001 From: caoqianming Date: Fri, 3 Mar 2023 10:03:41 +0800 Subject: [PATCH 5/5] =?UTF-8?q?ecm=20algochannel=20=E5=8F=98=E6=9B=B4?= =?UTF-8?q?=E4=B8=BAalways=5Fon=20=E4=B8=BAfalse?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/ecm/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/ecm/models.py b/apps/ecm/models.py index 755a9c53..c5abca5f 100644 --- a/apps/ecm/models.py +++ b/apps/ecm/models.py @@ -40,7 +40,7 @@ class AlgoChannel(BaseModel): algo = models.ForeignKey(EventCate, verbose_name='关联算法', on_delete=models.CASCADE) vchannel = models.ForeignKey(TDevice, verbose_name='视频通道', on_delete=models.CASCADE) - always_on = models.BooleanField("始终开启", default=True) + always_on = models.BooleanField("实时开启", default=False) class Meta: unique_together = ('algo', 'vchannel')