823 lines
28 KiB
Python
Executable File
823 lines
28 KiB
Python
Executable File
import importlib
|
||
import json
|
||
from drf_yasg import openapi
|
||
from django.contrib.auth.hashers import check_password, make_password
|
||
from django.db import transaction
|
||
from django_celery_beat.models import (CrontabSchedule, IntervalSchedule,
|
||
PeriodicTask)
|
||
from django_celery_results.models import TaskResult
|
||
from rest_framework.decorators import action
|
||
from rest_framework.exceptions import ParseError, ValidationError, PermissionDenied
|
||
from rest_framework.mixins import RetrieveModelMixin
|
||
from rest_framework.parsers import (JSONParser,
|
||
MultiPartParser)
|
||
from rest_framework.serializers import Serializer
|
||
from rest_framework.permissions import IsAuthenticated, AllowAny
|
||
from rest_framework.response import Response
|
||
from rest_framework.views import APIView
|
||
from apps.hrm.models import Employee
|
||
from apps.system.errors import OLD_PASSWORD_WRONG, PASSWORD_NOT_SAME, SCHEDULE_WRONG
|
||
from apps.system.filters import DeptFilterSet, UserFilterSet
|
||
# from django_q.models import Task as QTask, Schedule as QSchedule
|
||
from apps.utils.mixins import (MyLoggingMixin, BulkCreateModelMixin, BulkDestroyModelMixin, CustomListModelMixin)
|
||
from django.conf import settings
|
||
from apps.utils.permission import ALL_PERMS
|
||
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, MySchedule)
|
||
from .serializers import (ApkSerializer, DeptCreateUpdateSerializer, DeptSerializer, DictCreateUpdateSerializer,
|
||
DictSerializer, DictTypeCreateUpdateSerializer, DictTypeSerializer,
|
||
FileSerializer, PasswordChangeSerializer, PermissionCreateUpdateSerializer,
|
||
PermissionSerializer, PostCreateUpdateSerializer, PostRoleCreateSerializer,
|
||
PostRoleSerializer, PostSerializer,
|
||
PTaskSerializer, PTaskCreateUpdateSerializer, PTaskResultSerializer,
|
||
RoleCreateUpdateSerializer, RoleSerializer, TaskRunSerializer,
|
||
UserCreateSerializer, UserListSerializer, UserPostCreateSerializer,
|
||
UserPostSerializer, UserUpdateSerializer, UserFullInfoSerializer,
|
||
MyScheduleCreateSerializer, MyScheduleSerializer)
|
||
from rest_framework.viewsets import GenericViewSet
|
||
from cron_descriptor import get_description
|
||
import locale
|
||
from drf_yasg.utils import swagger_auto_schema
|
||
from server.settings import get_sysconfig, update_sysconfig, update_dict
|
||
from django.core.cache import cache
|
||
from apps.utils.permission import get_user_route
|
||
|
||
# logger.info('请求成功! response_code:{};response_headers:{};
|
||
# response_body:{}'.format(response_code, response_headers, response_body[:251]))
|
||
# logger.error('请求出错-{}'.format(error))
|
||
|
||
|
||
class TaskList(APIView):
|
||
permission_classes = [IsAuthenticated]
|
||
|
||
def get(self, request):
|
||
"""获取注册任务列表
|
||
|
||
获取注册任务列表
|
||
"""
|
||
tasks = list(
|
||
sorted(name for name in celery_app.tasks if not name.startswith('celery.')))
|
||
return Response(tasks)
|
||
|
||
|
||
# class QScheduleViewSet(CustomModelViewSet):
|
||
# """
|
||
# list:定时任务列表
|
||
|
||
# 定时任务列表
|
||
|
||
# retrieve:定时任务详情
|
||
|
||
# 定时任务详情
|
||
# """
|
||
# queryset = QSchedule.objects.all()
|
||
# serializer_class = QScheduleSerializer
|
||
# search_fields = ['name', 'func']
|
||
# filterset_fields = ['schedule_type']
|
||
# ordering = ['-pk']
|
||
|
||
# @action(methods=['get'], detail=True, perms_map={'post': 'qschedule:run_once'})
|
||
# def run_once(self, request, pk=None):
|
||
# """同步执行一次
|
||
|
||
# 同步执行一次
|
||
# """
|
||
# obj = self.get_object()
|
||
# module, func = obj.func.rsplit(".", 1)
|
||
# m = importlib.import_module(module)
|
||
# f = getattr(m, func)
|
||
# f(*obj.args.split(','), **eval(f"dict({obj.kwargs})"))
|
||
# return Response()
|
||
|
||
|
||
# class QTaskResultViewSet(ListModelMixin, RetrieveModelMixin, CustomGenericViewSet):
|
||
# """
|
||
# list:任务执行结果列表
|
||
|
||
# 任务执行结果列表
|
||
|
||
# retrieve:任务执行结果详情
|
||
|
||
# 任务执行结果详情
|
||
# """
|
||
# perms_map = {'get': '*'}
|
||
# filterset_fields = ['func']
|
||
# queryset = QTask.objects.all()
|
||
# serializer_class = QTaskResultSerializer
|
||
# ordering = ['-started']
|
||
# lookup_field = 'id'
|
||
|
||
class PTaskViewSet(CustomModelViewSet):
|
||
"""
|
||
list:定时任务列表
|
||
|
||
定时任务列表
|
||
|
||
retrieve:定时任务详情
|
||
|
||
定时任务详情
|
||
"""
|
||
queryset = PeriodicTask.objects.exclude(name__contains='celery.')
|
||
serializer_class = PTaskSerializer
|
||
create_serializer_class = PTaskCreateUpdateSerializer
|
||
update_serializer_class = PTaskCreateUpdateSerializer
|
||
partial_update_serializer_class = PTaskCreateUpdateSerializer
|
||
search_fields = ['name', 'task']
|
||
filterset_fields = ['enabled']
|
||
select_related_fields = ['interval', 'crontab']
|
||
ordering = ['-id']
|
||
|
||
@action(methods=['post'], detail=True, perms_map={'get': 'qtask.run_once'},
|
||
serializer_class=TaskRunSerializer)
|
||
def run_once(self, request, pk=None):
|
||
"""执行一次
|
||
|
||
执行一次
|
||
"""
|
||
obj = self.get_object()
|
||
module, func = obj.task.rsplit(".", 1)
|
||
m = importlib.import_module(module)
|
||
f = getattr(m, func)
|
||
if request.data.get('sync', True):
|
||
f(*json.loads(obj.args), **json.loads(obj.kwargs))
|
||
return Response()
|
||
else:
|
||
task_obj = f.delay(*json.loads(obj.args), **json.loads(obj.kwargs))
|
||
return Response({'task_id': task_obj.id})
|
||
|
||
@action(methods=['put'], detail=True, perms_map={'put': 'ptask.update'})
|
||
def toggle(self, request, pk=None):
|
||
"""修改启用禁用状态
|
||
|
||
修改启用禁用状态
|
||
"""
|
||
obj = self.get_object()
|
||
obj.enabled = False if obj.enabled else True
|
||
obj.save()
|
||
return Response()
|
||
|
||
@transaction.atomic
|
||
def create(self, request, *args, **kwargs):
|
||
"""创建定时任务
|
||
|
||
创建定时任务
|
||
"""
|
||
data = request.data
|
||
timetype = data.get('timetype', None)
|
||
interval_ = data.get('interval_', None)
|
||
crontab_ = data.get('crontab_', None)
|
||
if timetype == 'interval' and interval_:
|
||
data['crontab'] = None
|
||
try:
|
||
interval, _ = IntervalSchedule.objects.get_or_create(
|
||
**interval_, defaults=interval_)
|
||
data['interval'] = interval.id
|
||
except Exception:
|
||
raise ParseError(**SCHEDULE_WRONG)
|
||
if timetype == 'crontab' and crontab_:
|
||
data['interval'] = None
|
||
try:
|
||
crontab_['timezone'] = 'Asia/Shanghai'
|
||
crontab, _ = CrontabSchedule.objects.get_or_create(
|
||
**crontab_, defaults=crontab_)
|
||
data['crontab'] = crontab.id
|
||
except Exception:
|
||
raise ParseError(**SCHEDULE_WRONG)
|
||
serializer = self.get_serializer(data=data)
|
||
serializer.is_valid(raise_exception=True)
|
||
serializer.save()
|
||
return Response()
|
||
|
||
@transaction.atomic
|
||
def update(self, request, *args, **kwargs):
|
||
"""更新定时任务
|
||
|
||
更新定时任务
|
||
"""
|
||
data = request.data
|
||
timetype = data.get('timetype', None)
|
||
interval_ = data.get('interval_', None)
|
||
crontab_ = data.get('crontab_', None)
|
||
if timetype == 'interval' and interval_:
|
||
data['crontab'] = None
|
||
try:
|
||
if 'id' in interval_:
|
||
del interval_['id']
|
||
interval, _ = IntervalSchedule.objects.get_or_create(
|
||
**interval_, defaults=interval_)
|
||
data['interval'] = interval.id
|
||
except Exception:
|
||
raise ParseError(**SCHEDULE_WRONG)
|
||
if timetype == 'crontab' and crontab_:
|
||
data['interval'] = None
|
||
try:
|
||
crontab_['timezone'] = 'Asia/Shanghai'
|
||
if 'id' in crontab_:
|
||
del crontab_['id']
|
||
crontab, _ = CrontabSchedule.objects.get_or_create(
|
||
**crontab_, defaults=crontab_)
|
||
data['crontab'] = crontab.id
|
||
except Exception:
|
||
raise ParseError(**SCHEDULE_WRONG)
|
||
instance = self.get_object()
|
||
serializer = self.get_serializer(instance, data=data)
|
||
serializer.is_valid(raise_exception=True)
|
||
serializer.save()
|
||
return Response()
|
||
|
||
|
||
class PTaskResultViewSet(CustomListModelMixin, RetrieveModelMixin, CustomGenericViewSet):
|
||
"""
|
||
list:任务执行结果列表
|
||
|
||
任务执行结果列表
|
||
|
||
retrieve:任务执行结果详情
|
||
|
||
任务执行结果详情
|
||
"""
|
||
perms_map = {'get': '*'}
|
||
filterset_fields = {
|
||
"task_name": ["exact", "in"],
|
||
"periodic_task_name": ["exact"],
|
||
"status": ["exact"],
|
||
"date_created": ["gte", "lte"]
|
||
}
|
||
queryset = TaskResult.objects.all()
|
||
serializer_class = PTaskResultSerializer
|
||
ordering = ['-date_created']
|
||
lookup_field = 'task_id'
|
||
|
||
|
||
class DictTypeViewSet(CustomModelViewSet):
|
||
"""数据字典类型-增删改查
|
||
|
||
数据字典类型-增删改查
|
||
"""
|
||
queryset = DictType.objects.all()
|
||
serializer_class = DictTypeSerializer
|
||
create_serializer_class = DictTypeCreateUpdateSerializer
|
||
update_serializer_class = DictTypeCreateUpdateSerializer
|
||
partial_update_serializer_class = DictTypeCreateUpdateSerializer
|
||
search_fields = ['name']
|
||
|
||
|
||
class DictViewSet(CustomModelViewSet):
|
||
"""数据字典-增删改查
|
||
|
||
数据字典-增删改查
|
||
"""
|
||
# queryset = Dictionary.objects.get_queryset(all=True) # 获取全部的,包括软删除的
|
||
queryset = Dictionary.objects.all()
|
||
filterset_fields = ['type', 'is_used', 'type__code']
|
||
serializer_class = DictSerializer
|
||
create_serializer_class = DictCreateUpdateSerializer
|
||
update_serializer_class = DictCreateUpdateSerializer
|
||
partial_update_serializer_class = DictCreateUpdateSerializer
|
||
search_fields = ['name']
|
||
ordering = ['sort', 'create_time']
|
||
|
||
|
||
class PostViewSet(CustomModelViewSet):
|
||
"""岗位-增删改查
|
||
|
||
岗位-增删改查
|
||
"""
|
||
queryset = Post.objects.all()
|
||
serializer_class = PostSerializer
|
||
create_serializer_class = PostCreateUpdateSerializer
|
||
update_serializer_class = PostCreateUpdateSerializer
|
||
partial_update_serializer_class = PostCreateUpdateSerializer
|
||
search_fields = ['name', 'code', 'description']
|
||
ordering = ['create_time']
|
||
|
||
|
||
class PermissionViewSet(CustomModelViewSet):
|
||
"""菜单权限-增删改查
|
||
|
||
菜单权限-增删改查
|
||
"""
|
||
queryset = Permission.objects.all()
|
||
filterset_fields = ['type']
|
||
serializer_class = PermissionSerializer
|
||
create_serializer_class = PermissionCreateUpdateSerializer
|
||
update_serializer_class = PermissionCreateUpdateSerializer
|
||
partial_update_serializer_class = PermissionCreateUpdateSerializer
|
||
search_fields = ['name', 'codes']
|
||
ordering = ['sort', 'create_time']
|
||
|
||
@action(methods=['get'], detail=False, permission_classes=[IsAuthenticated])
|
||
def codes(self, request, pk=None):
|
||
"""获取全部权限标识
|
||
|
||
需要先请求一次swagger
|
||
"""
|
||
ALL_PERMS.sort()
|
||
return Response(ALL_PERMS)
|
||
|
||
def perform_create(self, serializer):
|
||
super().perform_create(serializer)
|
||
cache.delete('perms_alld_list')
|
||
|
||
def perform_update(self, serializer):
|
||
super().perform_update(serializer)
|
||
cache.delete('perms_alld_list')
|
||
|
||
def perform_destroy(self, instance):
|
||
super().perform_destroy(instance)
|
||
cache.delete('perms_alld_list')
|
||
|
||
class DeptViewSet(CustomModelViewSet):
|
||
"""部门-增删改查
|
||
|
||
部门-增删改查
|
||
"""
|
||
queryset = Dept.objects.all()
|
||
serializer_class = DeptSerializer
|
||
create_serializer_class = DeptCreateUpdateSerializer
|
||
update_serializer_class = DeptCreateUpdateSerializer
|
||
partial_update_serializer_class = DeptCreateUpdateSerializer
|
||
filterset_class = DeptFilterSet
|
||
search_fields = ['name']
|
||
ordering = ['type', 'sort', 'create_time']
|
||
|
||
# def filter_queryset(self, queryset):
|
||
# if not self.detail:
|
||
# self.request.query_params._mutable = True
|
||
# self.request.query_params.setdefault('type', 'dept')
|
||
# return super().filter_queryset(queryset)
|
||
|
||
# def get_queryset(self):
|
||
# type = self.request.query_params.get('type', None)
|
||
# if type:
|
||
# queryset = Dept.objects.filter(type='rparty')
|
||
# else:
|
||
# queryset = Dept.objects.filter(type__in=['dept', 'company'])
|
||
# return queryset
|
||
|
||
|
||
class RoleViewSet(CustomModelViewSet):
|
||
"""角色-增删改查
|
||
|
||
角色-增删改查
|
||
"""
|
||
queryset = Role.objects.all()
|
||
serializer_class = RoleSerializer
|
||
create_serializer_class = RoleCreateUpdateSerializer
|
||
update_serializer_class = RoleCreateUpdateSerializer
|
||
partial_update_serializer_class = RoleCreateUpdateSerializer
|
||
search_fields = ['name', 'code']
|
||
ordering = ['create_time']
|
||
|
||
|
||
class PostRoleViewSet(BulkCreateModelMixin, BulkDestroyModelMixin, CustomListModelMixin, CustomGenericViewSet):
|
||
"""岗位/角色关系
|
||
|
||
岗位/角色关系
|
||
"""
|
||
perms_map = {'get': '*', 'post': 'post.update', 'delete': 'post.update'}
|
||
queryset = PostRole.objects.select_related('post', 'role').all()
|
||
serializer_class = PostRoleSerializer
|
||
create_serializer_class = PostRoleCreateSerializer
|
||
filterset_fields = ['post', 'role']
|
||
|
||
|
||
class UserPostViewSet(BulkCreateModelMixin, BulkDestroyModelMixin, CustomListModelMixin, CustomGenericViewSet):
|
||
"""用户/岗位关系
|
||
|
||
用户/岗位关系
|
||
"""
|
||
perms_map = {'get': '*', 'post': 'user.update', 'delete': 'user.update'}
|
||
queryset = UserPost.objects.select_related('user', 'post', 'dept').all()
|
||
serializer_class = UserPostSerializer
|
||
create_serializer_class = UserPostCreateSerializer
|
||
filterset_fields = ['user', 'post', 'dept']
|
||
ordering = ['sort', 'create_time']
|
||
|
||
def perform_create(self, serializer):
|
||
instance = serializer.save()
|
||
user = instance.user
|
||
up = UserPost.objects.filter(user=user).order_by(
|
||
'sort', 'create_time').first()
|
||
if up:
|
||
user.belong_dept = up.dept
|
||
user.post = up.post
|
||
user.update_by = self.request.user
|
||
user.save()
|
||
# 更新人员表
|
||
ep = Employee.objects.get_queryset(
|
||
all=True).filter(user=user).first()
|
||
if ep:
|
||
ep.belong_dept = user.belong_dept
|
||
ep.post = user.post
|
||
ep.is_deleted = False
|
||
ep.save()
|
||
|
||
def perform_destroy(self, instance):
|
||
user = instance.user
|
||
instance.delete()
|
||
up = UserPost.objects.filter(user=user).order_by(
|
||
'sort', 'create_time').first()
|
||
if up:
|
||
user.belong_dept = up.dept
|
||
user.post = up.post
|
||
else:
|
||
user.belong_dept = None
|
||
user.post = None
|
||
user.update_by = self.request.user
|
||
user.save()
|
||
# 更新人员表
|
||
ep = Employee.objects.get_queryset(
|
||
all=True).filter(user=user).first()
|
||
if ep:
|
||
ep.belong_dept = user.belong_dept
|
||
ep.post = user.post
|
||
ep.is_deleted = False
|
||
ep.save()
|
||
|
||
|
||
class UserViewSet(CustomModelViewSet):
|
||
queryset = User.objects.get_queryset(all=True)
|
||
serializer_class = UserListSerializer
|
||
create_serializer_class = UserCreateSerializer
|
||
update_serializer_class = UserUpdateSerializer
|
||
filterset_class = UserFilterSet
|
||
search_fields = ['username', 'name', 'phone', 'email', 'id']
|
||
select_related_fields = ['superior', 'belong_dept', 'post']
|
||
prefetch_related_fields = ['posts', 'roles', 'depts']
|
||
ordering = ['create_time', 'type']
|
||
|
||
def get_queryset(self):
|
||
if self.request.method == 'GET' and (not self.request.query_params.get('is_deleted', None)):
|
||
self.queryset = User.objects.all()
|
||
return super().get_queryset()
|
||
|
||
def perform_update(self, serializer):
|
||
instance = serializer.save()
|
||
ep = Employee.objects.get_queryset(
|
||
all=True).filter(user=instance).first()
|
||
# ep2 = Employee.objects.get_queryset(all=True).filter(phone=instance.phone).first()
|
||
if ep:
|
||
pass
|
||
# elif ep2:
|
||
# ep = ep2
|
||
else:
|
||
ep = Employee()
|
||
ep.user = instance
|
||
ep.name = instance.name
|
||
ep.phone = instance.phone
|
||
ep.type = instance.type
|
||
ep.is_deleted = False
|
||
ep.save()
|
||
|
||
def create(self, request, *args, **kwargs):
|
||
"""创建用户
|
||
|
||
创建用户
|
||
"""
|
||
password = make_password(get_sysconfig("default_pwd", "abc!0000"))
|
||
serializer = self.get_serializer(data=request.data)
|
||
serializer.is_valid(raise_exception=True)
|
||
instance = serializer.save(password=password, belong_dept=None)
|
||
ep = Employee.objects.get_queryset(
|
||
all=True).filter(user=instance).first()
|
||
# ep2 = Employee.objects.get_queryset(all=True).filter(phone=instance.phone).first()
|
||
if ep:
|
||
pass
|
||
# elif ep2:
|
||
# ep = ep2
|
||
else:
|
||
ep = Employee()
|
||
ep.user = instance
|
||
ep.name = instance.name
|
||
ep.phone = instance.phone
|
||
ep.type = instance.type
|
||
ep.is_deleted = False
|
||
ep.save()
|
||
return Response(data=serializer.data)
|
||
|
||
@action(methods=['put'], detail=False,
|
||
permission_classes=[IsAuthenticated],
|
||
serializer_class=PasswordChangeSerializer)
|
||
def password(self, request, pk=None):
|
||
"""修改密码
|
||
|
||
修改密码
|
||
"""
|
||
user = request.user
|
||
old_password = request.data['old_password']
|
||
if check_password(old_password, user.password):
|
||
new_password1 = request.data['new_password1']
|
||
new_password2 = request.data['new_password2']
|
||
if new_password1 == new_password2:
|
||
if new_password1 == old_password:
|
||
raise ParseError('新密码不得与旧密码相同')
|
||
user.set_password(new_password2)
|
||
user.save()
|
||
return Response()
|
||
else:
|
||
raise ParseError(**PASSWORD_NOT_SAME)
|
||
else:
|
||
raise ValidationError(**OLD_PASSWORD_WRONG)
|
||
|
||
@action(methods=['post'], detail=True, perms_map={'post': '*'}, serializer_class=Serializer)
|
||
def reset_password(self, request, pk=None):
|
||
user = self.get_object()
|
||
if request.user.is_superuser:
|
||
user.set_password(get_sysconfig("default_pwd", "abc!0000"))
|
||
user.save()
|
||
else:
|
||
raise PermissionDenied()
|
||
return Response()
|
||
|
||
@action(methods=['get'], detail=False, permission_classes=[IsAuthenticated])
|
||
def info(self, request, pk=None):
|
||
"""登录用户信息
|
||
|
||
获取登录用户信息
|
||
"""
|
||
user = request.user
|
||
return Response(UserFullInfoSerializer(user).data)
|
||
|
||
@action(methods=['get'], detail=False, permission_classes=[IsAuthenticated])
|
||
def route(self, request, pk=None):
|
||
"""登录用户路由
|
||
|
||
获取登录用户路由
|
||
"""
|
||
return Response(get_user_route(request.user))
|
||
|
||
@action(methods=['post'], detail=False, permission_classes=[IsAuthenticated])
|
||
def bind_wxmp(self, request, pk=None):
|
||
"""
|
||
绑定微信小程序
|
||
|
||
绑定微信小程序
|
||
"""
|
||
openid = request.data['openid']
|
||
if openid:
|
||
user = request.user
|
||
if user.wxmp_openid != openid:
|
||
User.objects.filter(wxmp_openid=openid).update(
|
||
wxmp_openid=None)
|
||
user.wxmp_openid = openid
|
||
user.save()
|
||
return Response({'wxmp_openid': openid})
|
||
|
||
@action(methods=['post'], detail=False, permission_classes=[IsAuthenticated])
|
||
def unbind_wxmp(self, request, pk=None):
|
||
"""
|
||
解绑微信小程序
|
||
|
||
解绑微信小程序
|
||
"""
|
||
user = request.user
|
||
user.wxmp_openid = None
|
||
user.save()
|
||
return Response()
|
||
|
||
@action(methods=['post'], detail=False, permission_classes=[IsAuthenticated])
|
||
def bind_wx(self, request, pk=None):
|
||
"""绑定微信公众号
|
||
|
||
绑定微信公众号, 用于发送通知
|
||
"""
|
||
openid = request.data['openid']
|
||
if openid:
|
||
user = request.user
|
||
if user.wx_openid != openid:
|
||
User.objects.filter(wx_openid=openid).update(wx_openid=None)
|
||
user.wx_openid = openid
|
||
user.save()
|
||
return Response({'wx_openid': openid})
|
||
|
||
@action(methods=['post'], detail=False, permission_classes=[IsAuthenticated])
|
||
def bind_secret(self, request, pk=None):
|
||
"""创建密钥
|
||
|
||
创建密钥
|
||
"""
|
||
secret = request.data['secret']
|
||
if secret:
|
||
user = request.user
|
||
user.secret = secret
|
||
user.save()
|
||
return Response()
|
||
|
||
|
||
class FileViewSet(BulkCreateModelMixin, RetrieveModelMixin, CustomListModelMixin, CustomGenericViewSet):
|
||
"""文件上传
|
||
|
||
list:
|
||
文件列表
|
||
|
||
文件列表
|
||
|
||
create:
|
||
文件上传
|
||
|
||
文件上传
|
||
"""
|
||
permission_classes = [IsAuthenticated]
|
||
parser_classes = [MultiPartParser, JSONParser]
|
||
queryset = File.objects.all()
|
||
serializer_class = FileSerializer
|
||
filterset_fields = ['type']
|
||
search_fields = ['name']
|
||
cache_seconds = 0
|
||
|
||
def perform_create(self, serializer):
|
||
file_obj = self.request.data.get('file')
|
||
name = file_obj._name
|
||
size = file_obj.size
|
||
mime = file_obj.content_type
|
||
file_type = File.FILE_TYPE_OTHER
|
||
if 'image' in mime:
|
||
file_type = File.FILE_TYPE_PIC
|
||
elif 'video' in mime:
|
||
file_type = File.FILE_TYPE_VIDEO
|
||
elif 'audio' in mime:
|
||
file_type = File.FILE_TYPE_AUDIO
|
||
elif 'application' or 'text' in mime:
|
||
file_type = File.FILE_TYPE_DOC
|
||
instance = serializer.save(
|
||
create_by=self.request.user, name=name, size=size, type=file_type, mime=mime)
|
||
instance.path = settings.MEDIA_URL + instance.file.name
|
||
instance.save()
|
||
|
||
|
||
class ApkViewSet(MyLoggingMixin, CustomListModelMixin, BulkCreateModelMixin, GenericViewSet):
|
||
perms_map = {'get': '*', 'post': 'apk.upload'}
|
||
serializer_class = ApkSerializer
|
||
|
||
def get_authenticators(self):
|
||
if self.request.method == 'GET':
|
||
return []
|
||
return super().get_authenticators()
|
||
|
||
def get_permissions(self):
|
||
if self.request.method == 'GET':
|
||
return [AllowAny()]
|
||
return super().get_permissions()
|
||
|
||
def list(self, request, *args, **kwargs):
|
||
"""
|
||
获取apk信息
|
||
|
||
获取apk信息
|
||
"""
|
||
config = get_sysconfig()
|
||
return Response({'version': config['apk']['apk_version'], 'file': config['apk']['apk_file']})
|
||
|
||
def create(self, request, *args, **kwargs):
|
||
"""
|
||
上传apk
|
||
|
||
上传apk
|
||
"""
|
||
sr = ApkSerializer(data=request.data)
|
||
sr.is_valid(raise_exception=True)
|
||
vdata = sr.validated_data
|
||
update_sysconfig({
|
||
"apk": {
|
||
"apk_version": vdata['version'],
|
||
"apk_file": vdata['file']
|
||
}
|
||
})
|
||
return Response()
|
||
|
||
|
||
class MyScheduleViewSet(CustomListModelMixin, BulkCreateModelMixin, BulkDestroyModelMixin, CustomGenericViewSet):
|
||
perms_map = {'get': '*', 'post': '*',
|
||
'delete': 'myschedule.delete'}
|
||
serializer_class = MyScheduleSerializer
|
||
create_serializer_class = MyScheduleCreateSerializer
|
||
queryset = MySchedule.objects.all()
|
||
select_related_fields = ['interval', 'crontab']
|
||
period_dict = {
|
||
"days": "天",
|
||
"hours": "小时",
|
||
"minutes": "分钟",
|
||
"seconds": "秒",
|
||
"microseconds": "微秒"
|
||
}
|
||
|
||
def get_chinese_description(self, type: str = 'interval', data: dict = {}):
|
||
"""转换为汉语描述
|
||
"""
|
||
if type == 'interval':
|
||
return f"每隔{data['every']}{self.period_dict[data['period']]}"
|
||
elif type == 'crontab':
|
||
locale.setlocale(locale.LC_ALL, 'zh_CN.UTF-8')
|
||
return get_description(f"{data['minute']} {data['hour']} {data['day_of_month']} {data['month_of_year']} {data['day_of_week']}")
|
||
return ''
|
||
|
||
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.name = self.get_chinese_description('interval', interval_data)
|
||
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.name = self.get_chinese_description('crontab', crontab_data)
|
||
obj.crontab = crontab
|
||
obj.save()
|
||
|
||
|
||
class SysBaseConfigView(APIView):
|
||
authentication_classes = []
|
||
permission_classes = []
|
||
read_keys = ['base', 'apk']
|
||
|
||
@swagger_auto_schema(manual_parameters=[
|
||
openapi.Parameter(name="project_code", in_=openapi.IN_QUERY,
|
||
type=openapi.TYPE_STRING, required=False)
|
||
])
|
||
def get(self, request, format=None):
|
||
"""
|
||
获取系统基本信息
|
||
|
||
获取系统基本信息
|
||
"""
|
||
project_code = request.query_params.get('project_code', '')
|
||
if project_code:
|
||
from apps.develop.models import Project
|
||
try:
|
||
project = Project.objects.get(code=project_code)
|
||
config = project.config_json
|
||
except Project.DoesNotExist:
|
||
raise ParseError('项目不存在')
|
||
else:
|
||
config = get_sysconfig()
|
||
base_dict = {key: config[key]
|
||
for key in self.read_keys if key in config}
|
||
base_dict.get("base", {})["sys_version"] = settings.SYS_VERSION
|
||
base_dict.get("base", {})["sys_name"] = settings.SYS_NAME
|
||
return Response(base_dict)
|
||
|
||
|
||
class SysConfigView(MyLoggingMixin, APIView):
|
||
perms_map = {'get': 'sysconfig.view', 'put': 'sysconfig.update'}
|
||
|
||
@swagger_auto_schema(manual_parameters=[
|
||
openapi.Parameter(name="project_code", in_=openapi.IN_QUERY,
|
||
type=openapi.TYPE_STRING, required=False),
|
||
openapi.Parameter(name="reload", in_=openapi.IN_QUERY,
|
||
type=openapi.TYPE_BOOLEAN, required=False),
|
||
])
|
||
def get(self, request, format=None):
|
||
"""
|
||
获取config json
|
||
|
||
获取config json
|
||
"""
|
||
reload = False
|
||
if request.query_params.get('reload', None):
|
||
reload = True
|
||
project_code = request.query_params.get('project_code', '')
|
||
if project_code:
|
||
from apps.develop.models import Project
|
||
try:
|
||
project = Project.objects.get(code=project_code)
|
||
config = project.config_json
|
||
except Project.DoesNotExist:
|
||
raise ParseError('项目不存在')
|
||
else:
|
||
config = get_sysconfig(reload=reload)
|
||
return Response(config)
|
||
|
||
@swagger_auto_schema(request_body=Serializer)
|
||
def put(self, request, format=None):
|
||
"""
|
||
修改config json
|
||
|
||
修改config json
|
||
"""
|
||
data = request.data
|
||
project_code = data.get('project_code', '')
|
||
if project_code:
|
||
from apps.develop.models import Project
|
||
try:
|
||
project = Project.objects.get(code=project_code)
|
||
config = project.config_json
|
||
update_dict(config, data)
|
||
project.config_json = config
|
||
project.save()
|
||
except Project.DoesNotExist:
|
||
raise ParseError('项目不存在')
|
||
else:
|
||
update_sysconfig(data)
|
||
return Response()
|