From d7f017d396fbff7b33535125ce287ce4c8e00cfa Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Fri, 7 Aug 2026 23:52:30 +0800 Subject: [PATCH] =?UTF-8?q?refactor(gerp):=20=E6=94=B6=E6=95=9B=20SAAS=20?= =?UTF-8?q?=E6=AE=8B=E7=95=99=E8=A3=B8=20ORM=EF=BC=88doc=20=E8=A7=86?= =?UTF-8?q?=E5=9B=BE/=E7=BB=9F=E8=AE=A1=E4=BB=BB=E5=8A=A1/=E5=AE=A1?= =?UTF-8?q?=E8=AE=A1=E6=B8=85=E7=90=86/=E5=B7=A5=E5=8D=95=E9=80=9A?= =?UTF-8?q?=E7=9F=A5/viewsets=20=E6=8D=A2=E6=BA=90=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- gvsds/apps/doc/manager.py | 43 +++++++++-- gvsds/apps/doc/views.py | 77 +++++++------------ gvsds/apps/gerp/form_service.py | 6 +- .../management/commands/CleanAuditLogs.py | 2 +- gvsds/apps/gerp/views/viewsets.py | 15 ++-- gvsds/apps/stats/tasks.py | 2 +- 6 files changed, 73 insertions(+), 72 deletions(-) diff --git a/gvsds/apps/doc/manager.py b/gvsds/apps/doc/manager.py index 5184d508..242f36cb 100644 --- a/gvsds/apps/doc/manager.py +++ b/gvsds/apps/doc/manager.py @@ -39,13 +39,19 @@ class DocManager: return None @staticmethod - def AddDocument(Title, Content=''): - """新建文档""" - return CommunityDocument.objects.create( - DocUUID=uuid.uuid4().bytes, - DocTitle=Title, - DocContent=Content, - ) + def AddDocument(Title, Content='', SerieUUID=None): + """新建文档(可选绑定系列)""" + create_data = { + 'DocUUID': uuid.uuid4().bytes, + 'DocTitle': Title, + 'DocContent': Content, + } + if SerieUUID: + serie = DocManager.GetSerie(SerieUUID) + if serie is not None: + # DocSerieUUID 为 ForeignKey:传实例 + create_data['DocSerieUUID'] = serie + return CommunityDocument.objects.create(**create_data) @staticmethod def ModifyDocument(DocUUID, Data): @@ -127,3 +133,26 @@ class DocManager: return False, '系列不存在' serie.delete() return True, None + + # ========== 系列附加查询(供视图收敛裸 ORM) ========== + + @staticmethod + def GetSerie(DocSerieUUID): + """获取系列实例(不存在返回 None)""" + try: + return CommunitySeries.objects.get(DocSerieUUID=UUIDObj(DocSerieUUID).bytes) + except (CommunitySeries.DoesNotExist, ValueError, AttributeError): + return None + + @staticmethod + def SerieNameExists(DocSerieName): + """判断系列名是否已存在""" + return CommunitySeries.objects.filter(DocSerieName=DocSerieName).exists() + + @staticmethod + def SerieHasDocuments(DocSerieUUID): + """判断系列下是否还有文档(防删除)""" + serie = DocManager.GetSerie(DocSerieUUID) + if serie is None: + return False + return CommunityDocument.objects.filter(DocSerieUUID=serie).exists() diff --git a/gvsds/apps/doc/views.py b/gvsds/apps/doc/views.py index ab1f5eec..03a142db 100644 --- a/gvsds/apps/doc/views.py +++ b/gvsds/apps/doc/views.py @@ -1,7 +1,6 @@ """模块:Doc 社区文档视图 提供社区文档与系列的增删改查与访问控制。""" -import uuid import datetime from rest_framework import viewsets from rest_framework.decorators import action @@ -14,6 +13,7 @@ from .serializers import ( DocAddSerializer, DocModifySerializer, SerieAddSerializer, SerieDeleteSerializer, ) +from .manager import DocManager from gvsdsdk.model_utils import UUIDObj @@ -54,9 +54,8 @@ class CommunityDocumentViewSet(viewsets.ModelViewSet): doc_bytes = UUIDObj(doc_uuid).bytes if not doc_bytes: return Response({'code': 1, 'msg': 'DocUUID格式错误'}, status=400) - try: - doc = CommunityDocument.objects.get(DocUUID=doc_bytes) - except CommunityDocument.DoesNotExist: + doc = DocManager.GetDocument(doc_uuid) + if doc is None: return Response({'code': 1, 'msg': '文档不存在'}, status=404) return Response({ 'code': 0, @@ -74,22 +73,13 @@ class CommunityDocumentViewSet(viewsets.ModelViewSet): user_uuid = request.user.UserUUID serie_uuid_str = data.get('DocSerieUUID') - serie = None if serie_uuid_str: - serie_bytes = UUIDObj(serie_uuid_str).bytes - if not serie_bytes: + if not UUIDObj(serie_uuid_str).bytes: return Response({'code': 1, 'msg': 'DocSerieUUID格式错误'}, status=400) - try: - serie = CommunitySeries.objects.get(DocSerieUUID=serie_bytes) - except CommunitySeries.DoesNotExist: + if DocManager.GetSerie(serie_uuid_str) is None: return Response({'code': 1, 'msg': '系列不存在'}, status=400) - doc = CommunityDocument.objects.create( - DocUUID=uuid.uuid4().bytes, - DocTitle=data['DocTitle'], - DocContent='', - DocSerieUUID=serie, - ) + doc = DocManager.AddDocument(Title=data['DocTitle'], Content='', SerieUUID=serie_uuid_str) return Response({ 'code': 0, 'msg': '添加成功', @@ -102,23 +92,11 @@ class CommunityDocumentViewSet(viewsets.ModelViewSet): ser.IsValid(raise_exception=True) data = ser.ValidatedData doc_uuid_str = data.get('DocUUID') - doc_bytes = UUIDObj(doc_uuid_str).bytes - if not doc_bytes: + if not UUIDObj(doc_uuid_str).bytes: return Response({'code': 1, 'msg': 'DocUUID格式错误'}, status=400) - try: - doc = CommunityDocument.objects.get(DocUUID=doc_bytes) - except CommunityDocument.DoesNotExist: - return Response({'code': 1, 'msg': '文档不存在'}, status=404) - - update_fields = [] - if 'DocTitle' in data: - doc.DocTitle = data['DocTitle'] - update_fields.append('DocTitle') - if 'DocContent' in data: - doc.DocContent = data['DocContent'] - update_fields.append('DocContent') - if update_fields: - doc.save(update_fields=update_fields) + ok, err = DocManager.ModifyDocument(doc_uuid_str, data) + if not ok: + return Response({'code': 1, 'msg': err or '修改失败'}, status=404) return Response({'code': 0, 'msg': '修改成功'}) @action(detail=False, methods=['post']) @@ -129,11 +107,12 @@ class CommunityDocumentViewSet(viewsets.ModelViewSet): doc_bytes = UUIDObj(doc_uuid).bytes if not doc_bytes: return Response({'code': 1, 'msg': 'DocUUID格式错误'}, status=400) - try: - doc = CommunityDocument.objects.get(DocUUID=doc_bytes) - except CommunityDocument.DoesNotExist: + doc = DocManager.GetDocument(doc_uuid) + if doc is None: return Response({'code': 1, 'msg': '文档不存在'}, status=404) - doc.delete() + ok, err = DocManager.DeleteDocument(doc_uuid) + if not ok: + return Response({'code': 1, 'msg': err or '删除失败'}, status=404) return Response({'code': 0, 'msg': '删除成功'}) @@ -167,14 +146,13 @@ class CommunitySeriesViewSet(viewsets.ModelViewSet): data = ser.ValidatedData user_uuid = request.user.UserUUID - if CommunitySeries.objects.filter(DocSerieName=data['DocSerieName']).exists(): + if DocManager.SerieNameExists(data['DocSerieName']): return Response({'code': 1, 'msg': '系列名称已存在'}, status=409) - serie = CommunitySeries.objects.create( - DocSerieUUID=uuid.uuid4().bytes, - DocSerieName=data['DocSerieName'], - DocAuthorUserUUID=user_uuid, - ) + serie = DocManager.AddSeries({ + 'DocSerieName': data['DocSerieName'], + 'DocAuthorUserUUID': user_uuid, + }) return Response({ 'code': 0, 'msg': '添加成功', @@ -187,16 +165,13 @@ class CommunitySeriesViewSet(viewsets.ModelViewSet): ser.IsValid(raise_exception=True) data = ser.ValidatedData serie_uuid_str = data.get('DocSerieUUID') - serie_bytes = UUIDObj(serie_uuid_str).bytes - if not serie_bytes: + if not UUIDObj(serie_uuid_str).bytes: return Response({'code': 1, 'msg': 'DocSerieUUID格式错误'}, status=400) - try: - serie = CommunitySeries.objects.get(DocSerieUUID=serie_bytes) - except CommunitySeries.DoesNotExist: + if DocManager.GetSerie(serie_uuid_str) is None: return Response({'code': 1, 'msg': '系列不存在'}, status=404) - - if CommunityDocument.objects.filter(DocSerieUUID=serie).exists(): + if DocManager.SerieHasDocuments(serie_uuid_str): return Response({'code': 1, 'msg': '该系列下还有文档,无法删除'}, status=400) - - serie.delete() + ok, err = DocManager.DeleteSerie(serie_uuid_str) + if not ok: + return Response({'code': 1, 'msg': err or '删除失败'}, status=404) return Response({'code': 0, 'msg': '删除成功'}) diff --git a/gvsds/apps/gerp/form_service.py b/gvsds/apps/gerp/form_service.py index 758a2d61..dadb588c 100644 --- a/gvsds/apps/gerp/form_service.py +++ b/gvsds/apps/gerp/form_service.py @@ -1334,11 +1334,11 @@ class FormService(FormServiceBase): def _send_workorder_notify(self, order, receiver_uuid, title, content): """工单指派/状态流转时向用户发送站内信通知(MsgType=2 工单通知)""" try: - from gvsds.apps.gerp.models import Message as _WoMsg + from gvsdsdk.models import Message as _WoMsg _WoMsg.objects.create( MessageUUID=uuid.uuid4().bytes, - SenderUUID_id=self._current_user_uuid_bytes(), - ReceiverUUID_id=receiver_uuid, + SenderUUID=self._current_user_uuid_bytes(), + ReceiverUUID=receiver_uuid, Title=title, Content=content, MsgType=2, diff --git a/gvsds/apps/gerp/management/commands/CleanAuditLogs.py b/gvsds/apps/gerp/management/commands/CleanAuditLogs.py index d276fc33..cbb34f12 100644 --- a/gvsds/apps/gerp/management/commands/CleanAuditLogs.py +++ b/gvsds/apps/gerp/management/commands/CleanAuditLogs.py @@ -11,7 +11,7 @@ import logging from django.core.management.base import BaseCommand from django.utils import timezone -from gvsds.apps.gerp.models import AuditLog +from gvsdsdk.models import AuditLog logger = logging.getLogger(__name__) diff --git a/gvsds/apps/gerp/views/viewsets.py b/gvsds/apps/gerp/views/viewsets.py index ff43b95d..43673a39 100644 --- a/gvsds/apps/gerp/views/viewsets.py +++ b/gvsds/apps/gerp/views/viewsets.py @@ -15,6 +15,7 @@ from gvsdsdk.models import ( PositionTemplatePermission as SdkPositionTemplatePermission, CompanyInfo as SdkCompanyInfo, DepartmentSMTM as SdkDepartmentSMTM, + UserRoleDepartment as SdkUserRoleDepartment, Workgroup as SdkWorkgroup, SimulatedTrigger as SdkSimulatedTrigger, CashReceiptsPaymentsLedger as SdkCashReceiptsPaymentsLedger, @@ -37,10 +38,6 @@ from gvsdsdk.models import ( Position as SdkPosition, ) from . import ELTAuthenticatedAPIView -from ..models import ( - UserRoleDepartment, - DepartmentSMTM, -) from ..serializers import ( TenantSerializer, CompanyInfoSerializer, CompanySerializer, DepartmentSerializer, RoleSerializer, UserRoleSerializer, @@ -180,7 +177,7 @@ class DepartmentViewSet(CompanyScopedMixin, viewsets.ModelViewSet): dept = DepartmentManager.GetDepartmentByUUID(dept_bytes) if dept and UUIDObj(dept.CompanyUUID).bytes != current_company: return Response({'code': 403, 'msg': '无权操作:目标部门不属于当前公司'}, status=403) - smtm, created = DepartmentSMTM.objects.update_or_create( + smtm, created = SdkDepartmentSMTM.objects.update_or_create( DepartmentUUID=dept_bytes, UserUUID=user_bytes, defaults={'PersonInChargeStatus': status_val} @@ -338,7 +335,7 @@ class UserRoleViewSet(CompanyScopedMixin, viewsets.ModelViewSet): # 批量取"用户-角色对 → 首个部门",供部门树浏览面板分组 urd_dept_map = {} try: - urd_rows = UserRoleDepartment.objects.filter(UserRoleUUID__in=[ + urd_rows = SdkUserRoleDepartment.objects.filter(UserRoleUUID__in=[ ur.UserRoleUUID for ur in page if ur.UserRoleUUID ]) for u in urd_rows: @@ -347,11 +344,11 @@ class UserRoleViewSet(CompanyScopedMixin, viewsets.ModelViewSet): except Exception: _key = str(u.UserRoleUUID) if _key not in urd_dept_map: - # DeptUUID 为 ForeignKey:用 _id 取原始列值(BINARY(16)) + # SDK UserRoleDepartment.DeptUUID 为 UUIDField:取字段值转字符串 try: - urd_dept_map[_key] = str(UUIDObj(u.DeptUUID_id)) + urd_dept_map[_key] = str(UUIDObj(u.DeptUUID)) except Exception: - urd_dept_map[_key] = str(u.DeptUUID_id) + urd_dept_map[_key] = str(u.DeptUUID) except Exception: urd_dept_map = {} data = [] diff --git a/gvsds/apps/stats/tasks.py b/gvsds/apps/stats/tasks.py index 5e35d4ac..52206b54 100644 --- a/gvsds/apps/stats/tasks.py +++ b/gvsds/apps/stats/tasks.py @@ -94,7 +94,7 @@ def BuildDailyRankings(self): def _GetActiveTenants(): """获取所有活跃租户的 UUID 列表(bytes 形式)。""" try: - from gvsds.apps.gerp.models import Tenant + from gvsdsdk.models import Tenant return [t.TenantUUID.bytes for t in Tenant.objects.filter(TenantStatus=1)] except Exception: logger.warning('[StatsTasks] 获取租户列表失败,返回空列表', exc_info=True)