diff --git a/client/src/api/task.js b/client/src/api/task.js
new file mode 100644
index 0000000..f96205d
--- /dev/null
+++ b/client/src/api/task.js
@@ -0,0 +1,9 @@
+import request from '@/utils/request'
+
+export function getTaskList(query) {
+ return request({
+ url: '/system/task/',
+ method: 'get',
+ params: query
+ })
+}
diff --git a/client/src/router/index.js b/client/src/router/index.js
index 85bf8c7..1a2c4d9 100644
--- a/client/src/router/index.js
+++ b/client/src/router/index.js
@@ -103,6 +103,12 @@ export const asyncRoutes = [
name: 'File',
component: () => import('@/views/system/file'),
meta: { title: '文件库', icon: 'documentation', perms: ['file_room'] }
+ },
+ {
+ path: 'task',
+ name: 'Task',
+ component: () => import('@/views/system/task'),
+ meta: { title: '定时任务', icon: 'list', perms: ['task_manage'] }
}
]
},
diff --git a/client/src/views/system/task.vue b/client/src/views/system/task.vue
new file mode 100644
index 0000000..4e1b908
--- /dev/null
+++ b/client/src/views/system/task.vue
@@ -0,0 +1,125 @@
+
+
+
+
+
+
+
+ 搜索
+ 刷新重置
+
+
+
+
+ {{ scope.row.name }}
+
+
+
+ {{ scope.row.description }}
+
+
+ {{ scope.row.total_run_count }}
+
+
+ {{ scope.row.last_run_at }}
+
+
+
+ {{ scope.row.enabled }}
+
+
+
+
+
+
+
+
diff --git a/docs/~$模块细分.docx b/docs/~$模块细分.docx
deleted file mode 100644
index 4a4b94b..0000000
Binary files a/docs/~$模块细分.docx and /dev/null differ
diff --git a/server/apps/system/models.py b/server/apps/system/models.py
index e96adc5..bc223c2 100644
--- a/server/apps/system/models.py
+++ b/server/apps/system/models.py
@@ -8,6 +8,7 @@ from simple_history.models import HistoricalRecords
+
class Position(BaseModel):
"""
职位/岗位
diff --git a/server/apps/system/serializers.py b/server/apps/system/serializers.py
index 7901e48..9d3b723 100644
--- a/server/apps/system/serializers.py
+++ b/server/apps/system/serializers.py
@@ -1,8 +1,16 @@
import re
+from django_celery_beat.models import PeriodicTask
from rest_framework import serializers
-from .models import Organization, Permission, Role, User, Position, DictType, Dict, File
+from .models import (Dict, DictType, File, Organization, Permission, Position,
+ Role, User)
+
+class TaskSerializer(serializers.ModelSerializer):
+ class Meta:
+ model = PeriodicTask
+ fields = '__all__'
+
class FileSerializer(serializers.ModelSerializer):
class Meta:
diff --git a/server/apps/system/tasks.py b/server/apps/system/tasks.py
new file mode 100644
index 0000000..95f1834
--- /dev/null
+++ b/server/apps/system/tasks.py
@@ -0,0 +1,9 @@
+# Create your tasks here
+from __future__ import absolute_import, unicode_literals
+
+from celery import shared_task
+
+
+@shared_task
+def add(x, y):
+ return x + y
\ No newline at end of file
diff --git a/server/apps/system/urls.py b/server/apps/system/urls.py
index 49aea89..3733f3d 100644
--- a/server/apps/system/urls.py
+++ b/server/apps/system/urls.py
@@ -1,5 +1,5 @@
from django.urls import path, include
-from .views import UserViewSet, OrganizationViewSet, PermissionViewSet, RoleViewSet, PositionViewSet, TestView, DictTypeViewSet, DictViewSet
+from .views import UserViewSet, OrganizationViewSet, PermissionViewSet, RoleViewSet, PositionViewSet, TestView, DictTypeViewSet, DictViewSet, TaskViewSet
from rest_framework import routers
@@ -11,6 +11,7 @@ router.register('role', RoleViewSet, basename="role")
router.register('position', PositionViewSet, basename="position")
router.register('dicttype', DictTypeViewSet, basename="dicttype")
router.register('dict', DictViewSet, basename="dict")
+router.register('task', TaskViewSet, basename="task")
urlpatterns = [
path('', include(router.urls)),
path('test/', TestView.as_view())
diff --git a/server/apps/system/views.py b/server/apps/system/views.py
index f0b153a..ba2e2d8 100644
--- a/server/apps/system/views.py
+++ b/server/apps/system/views.py
@@ -1,7 +1,9 @@
import logging
+from django.conf import settings
from django.contrib.auth.hashers import check_password, make_password
from django.core.cache import cache
+from django_celery_beat.models import PeriodicTask
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework import status
from rest_framework.decorators import action
@@ -10,6 +12,8 @@ from rest_framework.mixins import (CreateModelMixin, DestroyModelMixin,
ListModelMixin, RetrieveModelMixin,
UpdateModelMixin)
from rest_framework.pagination import PageNumberPagination
+from rest_framework.parsers import (FileUploadParser, JSONParser,
+ MultiPartParser)
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.views import APIView
@@ -19,15 +23,16 @@ from rest_framework_simplejwt.tokens import RefreshToken
from utils.queryset import get_child_queryset2
from .filters import UserFilter
-from .models import (Dict, DictType, Organization, Permission, Position, Role,
- User, File)
+from .mixins import CreateModelAMixin
+from .models import (Dict, DictType, File, Organization, Permission, Position,
+ Role, User)
from .permission import RbacPermission, get_permission_list
from .permission_data import RbacFilterSet
-from .serializers import (DictSerializer, DictTypeSerializer,
+from .serializers import (DictSerializer, DictTypeSerializer, FileSerializer,
OrganizationSerializer, PermissionSerializer,
- PositionSerializer, RoleSerializer,
+ PositionSerializer, RoleSerializer, TaskSerializer,
UserCreateSerializer, UserListSerializer,
- UserModifySerializer, FileSerializer)
+ UserModifySerializer)
logger = logging.getLogger('log')
# logger.info('请求成功! response_code:{};response_headers:{};response_body:{}'.format(response_code, response_headers, response_body[:251]))
@@ -40,6 +45,14 @@ class LogoutView(APIView):
def get(self, request, *args, **kwargs): # 可将token加入黑名单
return Response(status=status.HTTP_200_OK)
+class TaskViewSet(ModelViewSet):
+ queryset = PeriodicTask.objects.all()
+ serializer_class = TaskSerializer
+ search_fields = ['^name']
+ filterset_fields = ['enabled']
+ ordering = '-pk'
+
+
class DictTypeViewSet(ModelViewSet):
"""
@@ -211,9 +224,6 @@ class UserViewSet(ModelViewSet):
}
return Response(data)
-from rest_framework.parsers import MultiPartParser, JSONParser, FileUploadParser
-from .mixins import CreateModelAMixin
-from django.conf import settings
class FileViewSet(ModelViewSet):
"""
文件:增删改查
@@ -243,4 +253,3 @@ class FileViewSet(ModelViewSet):
instance = serializer.save(create_by = self.request.user, name=name, size=size, type=type, mime=mime)
instance.path = settings.MEDIA_URL + instance.file.name
instance.save()
-
\ No newline at end of file
diff --git a/server/requirements.txt b/server/requirements.txt
index bbd5da5..59640cf 100644
Binary files a/server/requirements.txt and b/server/requirements.txt differ
diff --git a/server/s_celerybeat.bat b/server/s_celerybeat.bat
new file mode 100644
index 0000000..45ca964
--- /dev/null
+++ b/server/s_celerybeat.bat
@@ -0,0 +1,4 @@
+@echo off
+call venv\scripts\activate.bat
+celery -A server beat -l info
+pause
\ No newline at end of file
diff --git a/server/s_celeryworker.bat b/server/s_celeryworker.bat
new file mode 100644
index 0000000..b1fa78e
--- /dev/null
+++ b/server/s_celeryworker.bat
@@ -0,0 +1,4 @@
+@echo off
+call venv\scripts\activate.bat
+celery -A server worker -l info -P eventlet
+pause
\ No newline at end of file
diff --git a/server/s_redis.bat b/server/s_redis.bat
deleted file mode 100644
index fafc7bb..0000000
--- a/server/s_redis.bat
+++ /dev/null
@@ -1,2 +0,0 @@
-c:\Basepackage\redis\redis-server.exe c:\Basepackage\redis\redis.windows.conf
-pause
\ No newline at end of file
diff --git a/server/s_server.bat b/server/s_server.bat
new file mode 100644
index 0000000..5f7e9df
--- /dev/null
+++ b/server/s_server.bat
@@ -0,0 +1,3 @@
+@echo off
+call venv\scripts\activate.bat
+python manage.py runserver
\ No newline at end of file
diff --git a/server/server/__init__.py b/server/server/__init__.py
index e69de29..d128d39 100644
--- a/server/server/__init__.py
+++ b/server/server/__init__.py
@@ -0,0 +1,7 @@
+from __future__ import absolute_import, unicode_literals
+
+# This will make sure the app is always imported when
+# Django starts so that shared_task will use this app.
+from .celery import app as celery_app
+
+__all__ = ('celery_app',)
\ No newline at end of file
diff --git a/server/server/celery.py b/server/server/celery.py
new file mode 100644
index 0000000..6b5bfab
--- /dev/null
+++ b/server/server/celery.py
@@ -0,0 +1,24 @@
+from __future__ import absolute_import, unicode_literals
+
+import os
+
+from celery import Celery
+
+# set the default Django settings module for the 'celery' program.
+os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'server.settings_dev')
+
+app = Celery('server')
+
+# Using a string here means the worker doesn't have to serialize
+# the configuration object to child processes.
+# - namespace='CELERY' means all celery-related configuration keys
+# should have a `CELERY_` prefix.
+app.config_from_object('django.conf:settings', namespace='CELERY')
+
+# Load task modules from all registered Django app configs.
+app.autodiscover_tasks()
+
+
+@app.task(bind=True)
+def debug_task(self):
+ print('Request: {0!r}'.format(self.request))
\ No newline at end of file
diff --git a/server/server/settings.py b/server/server/settings.py
index 9f8445b..a4357fe 100644
--- a/server/server/settings.py
+++ b/server/server/settings.py
@@ -38,6 +38,8 @@ INSTALLED_APPS = [
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
+ 'django_redis',
+ 'django_celery_beat',
'rest_framework',
'corsheaders',
"django_filters",
@@ -157,17 +159,15 @@ SIMPLE_JWT = {
'ACCESS_TOKEN_LIFETIME': timedelta(days=1),
}
+# 跨域配置
CORS_ORIGIN_ALLOW_ALL = True
+# Auth配置
AUTH_USER_MODEL = 'system.User'
-
-
-# 用户认证
AUTHENTICATION_BACKENDS = (
'apps.system.authentication.CustomBackend',
)
-
# 缓存配置
CACHES = {
"default": {
@@ -179,6 +179,8 @@ CACHES = {
}
}
}
+
+
# 日志配置
# 创建日志的路径
LOG_PATH = os.path.join(BASE_DIR, 'log')
diff --git a/server/server/settings_dev.py b/server/server/settings_dev.py
index 3f0ecdc..ee793c2 100644
--- a/server/server/settings_dev.py
+++ b/server/server/settings_dev.py
@@ -10,3 +10,10 @@ DATABASES = {
'PORT': '5432',
}
}
+# Celery配置
+CELERY_BEAT_SCHEDULER = 'django_celery_beat.schedulers:DatabaseScheduler'
+CELERY_BROKER_URL = 'redis://127.0.0.1:6379/0'
+CELERY_BROKER_TRANSPORT = 'redis'
+CELERYD_MAX_TASKS_PER_CHILD = 10
+CELERY_TIMEZONE = TIME_ZONE
+CELERY_ENABLE_UTC=True
diff --git a/server/server/settings_pro.py b/server/server/settings_pro.py
index 007e854..1908e9e 100644
--- a/server/server/settings_pro.py
+++ b/server/server/settings_pro.py
@@ -10,3 +10,10 @@ DATABASES = {
'PORT': '5432',
}
}
+# Celery配置
+CELERY_BEAT_SCHEDULER = 'django_celery_beat.schedulers:DatabaseScheduler'
+CELERY_BROKER_URL = 'redis://127.0.0.1:6379/0'
+CELERY_BROKER_TRANSPORT = 'redis'
+CELERYD_MAX_TASKS_PER_CHILD = 10
+CELERY_TIMEZONE = TIME_ZONE
+CELERY_ENABLE_UTC=True