2025-03-18 08:46:50 +08:00

153 lines
6.6 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from apps.lyautocode.models.models_autocode import *
from utils.jsonResponse import SuccessResponse,DetailResponse,ErrorResponse
from utils.common import get_parameter_dic, ast_convert,starts_with_digit
from utils.models import is_table_exists
from rest_framework import serializers
from utils.serializers import CustomModelSerializer
from utils.viewset import CustomModelViewSet
from utils.autocode.lygeneratecode import GenerateCode
from django.db.models import Q
from django.db import transaction
from django.utils.autoreload import restart_with_reloader
import logging
logger = logging.getLogger(__name__)
class LyAutoCodeSerializer(CustomModelSerializer):
"""
代码生成 -序列化器
"""
def to_representation(self, instance): # 序列化
ret = super().to_representation(instance)
ret['column'] = ast_convert(ret['column']) # 可以保存的修改字段值的方法
ret['other_config'] = ast_convert(ret['other_config']) # 可以保存的修改字段值的方法
return ret
class Meta:
model = LyAutoCode
read_only_fields = ["id"]
fields = '__all__'
class LyAutoCodeCreateUpdateSerializer(CustomModelSerializer):
"""
代码生成 -序列化器
"""
column = serializers.JSONField()
other_config = serializers.JSONField()
class Meta:
model = LyAutoCode
read_only_fields = ["id"]
fields = '__all__'
class LyAutoCodeViewSet(CustomModelViewSet):
"""
后台代码生成 接口:
"""
queryset = LyAutoCode.objects.filter(is_delete=False).order_by('-create_datetime')
serializer_class = LyAutoCodeSerializer
create_serializer_class = LyAutoCodeCreateUpdateSerializer
update_serializer_class = LyAutoCodeCreateUpdateSerializer
search_fields = ('class_name','verbose_name','db_table')
# 重写delete方法并改为逻辑删除
def destroy(self, request, *args, **kwargs):
real_delete = get_parameter_dic(request).get('real_delete',None)
instance = self.get_object_list()
if not real_delete:
for i in range(len(instance)):
instance[i].is_delete = True
model = self.get_serializer().Meta.model
model.objects.bulk_update(instance, fields=['is_delete'])
return DetailResponse(msg="删除成功")
else:
for i in range(len(instance)):
serializer = self.get_serializer(instance[i])
object = serializer.data
if instance[i].is_mount:
menu_instance = None
if instance[i].menu:
menu_instance = instance[i].menu
GenerateCode().generate(object, True, menu_instance,True)
self.perform_destroy(instance)
return DetailResponse(msg="删除成功")
def create(self, request, *args, **kwargs):
params = request.data
class_name = params.get('class_name',None)
if starts_with_digit(class_name):
return ErrorResponse(msg="类名【%s】不能以数字开头!!!"%class_name)
db_table = params.get('db_table', None)
if self.filter_queryset(self.get_queryset()).filter(Q(class_name=class_name)|Q(db_table=db_table)).exists():
return ErrorResponse(msg="存在同名的类名或表名")
if is_table_exists(db_table):
return ErrorResponse(msg="存在同名的表名,请更改后再试")
params['file_name_old'] = class_name
serializer = self.get_serializer(data=params, request=request)
serializer.is_valid(raise_exception=True)
self.perform_create(serializer)
return DetailResponse(data=serializer.data, msg="新增成功")
def previewCode(self,request):
id = get_parameter_dic(request).get('id',None)
instance = self.filter_queryset(self.get_queryset()).filter(id=id).first()
serializer = self.get_serializer(instance)
data = GenerateCode().generate(serializer.data)
return SuccessResponse(data=data,total=len(data))
def generateMount(self,request):
id = get_parameter_dic(request).get('id',None)
isReload = get_parameter_dic(request).get('isReload',False)
instance = self.filter_queryset(self.get_queryset()).filter(id=id).first()
if not instance:
return ErrorResponse(msg="id error")
serializer = self.get_serializer(instance)
object = serializer.data
# vue的route name
VueIndexName = 'lyAutoCode%s' % object['class_name']
try:
# 在事务开始前创建保存点
save_id = transaction.savepoint()
# 以下代码会在事务中执行
# 配置路由菜单
parent_menu = object['parent_menu'] if object['parent_menu'] else None
if instance.menu:
menu_instance = instance.menu
Menu.objects.filter(id=menu_instance.id).update(name=object['verbose_name'], web_path=VueIndexName,sort=object['menu_sort'],parent_id=parent_menu)
else:
menu_instance,created = Menu.objects.get_or_create(name=object['verbose_name'], sort=object['menu_sort'],web_path=VueIndexName, isautopm=1)
if parent_menu:
menu_instance.parent_id = parent_menu
menu_instance.save()
instance.menu = menu_instance
instance.save()
data = GenerateCode().generate(object, True, menu_instance)
if not data:
# 回滚到保存点
transaction.savepoint_rollback(save_id)
return ErrorResponse(msg="生成文件错误")
instance.file_name_old = object['class_name']
instance.is_mount = True
instance.save()
# 提交从保存点到当前状态的所有数据库事务操作
transaction.savepoint_commit(save_id)
if isReload:
restart_with_reloader()
return DetailResponse(msg="操作成功")
except Exception as e:
# 回滚到保存点
transaction.savepoint_rollback(save_id)
# 处理代码
raise e
def syncdb(self,request):
result = GenerateCode().syncdb()
if result:
return DetailResponse(msg="数据库同步成功")
return ErrorResponse(msg="数据库同步失败请查看后端IDE报错内容或重启后端项目重试同步")