Files
SMANAGE/gvsds/apps/doc/manager.py
T
TermiNexus 9cb0d8e186 refactor(core): 文档系列目录查询收敛进 DocManager
core/views.py 的 GetSerieDirectory 分支改用 DocManager.GetSerie / 新增的 ListDocumentsBySerie,移除视图内局部 import 与裸 ORM;doc/manager.py 新增 ListDocumentsBySerie(DocSerieUUID) 查询集方法。

注:core/views.py 同时携带此前工作区已有的 Viper/Venom 子域登记(SUBDOMAIN_CONFIG 两条),随本文件一并提交。
2026-09-14 06:47:38 +08:00

190 lines
6.3 KiB
Python
Raw 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.
"""模块:doc 服务层
社区文档与系列的统一操作入口——供 GERP 文档视图与 doc app 自身复用,
消除视图层裸 ORM。所有方法遵循帕斯卡命名法。
"""
import uuid
from gvsdsdk.model_utils import UUIDObj
from gvsds.apps.doc.models import CommunityDocument, CommunitySeries
class DocManager:
"""文档/系列管理器——社区文档的增删改查与系列管理"""
# ========== 文档 ==========
@staticmethod
def ListDocuments(Keyword=''):
"""获取文档列表(不含 DocContent 全文,仅标题/系列/创建时间/格式)"""
qs = CommunityDocument.objects.all()
if Keyword:
qs = qs.filter(DocTitle__icontains=Keyword)
data = []
for d in qs:
data.append({
'DocUUID': UUIDObj(d.DocUUID).str,
'DocSerieUUID': UUIDObj(d.DocSerieUUID).str if d.DocSerieUUID else None,
'DocTitle': d.DocTitle,
'DocFormat': d.DocFormat,
'DocCreateTime': d.DocCreateTime.isoformat() if d.DocCreateTime else None,
})
return data
@staticmethod
def GetDocument(DocUUID):
"""获取文档实例(不存在返回 None)"""
try:
return CommunityDocument.objects.get(DocUUID=UUIDObj(DocUUID).bytes)
except (CommunityDocument.DoesNotExist, ValueError, AttributeError):
return None
@staticmethod
def AddDocument(Title, Content='', SerieUUID=None, Format='markdown'):
"""新建文档(可选绑定系列;DocSerieUUID 为可空 UUID 列,直接存 bytes)
Format: 'markdown' 或 'html'(DocFormat 字段)。
"""
create_data = {
'DocUUID': uuid.uuid4().bytes,
'DocTitle': Title,
'DocContent': Content,
'DocFormat': Format if Format in ('markdown', 'html') else 'markdown',
}
if SerieUUID and DocManager.GetSerie(SerieUUID) is not None:
create_data['DocSerieUUID'] = UUIDObj(SerieUUID).bytes
return CommunityDocument.objects.create(**create_data)
@staticmethod
def ModifyDocument(DocUUID, Data):
"""修改文档标题/内容/格式
Returns:
(成功?, 错误消息 or None)
"""
doc = DocManager.GetDocument(DocUUID)
if doc is None:
return False, '文档不存在'
for field in ('DocTitle', 'DocContent', 'DocFormat'):
if field in Data:
setattr(doc, field, Data[field])
doc.save()
return True, None
@staticmethod
def DeleteDocument(DocUUID):
"""删除文档
Returns:
(成功?, 错误消息 or None)
"""
doc = DocManager.GetDocument(DocUUID)
if doc is None:
return False, '文档不存在'
doc.delete()
return True, None
# ========== 系列 ==========
@staticmethod
def ListSeries():
"""获取系列列表(统一 DocSerie 前缀字段名)"""
data = []
for s in CommunitySeries.objects.all():
data.append({
'DocSerieUUID': UUIDObj(s.DocSerieUUID).str,
'DocSerieName': s.DocSerieName,
})
return data
@staticmethod
def AddSeries(Data):
"""新建系列(Data 为已验证字段 dict)"""
return CommunitySeries.objects.create(
DocSerieUUID=uuid.uuid4().bytes,
**Data,
)
@staticmethod
def ModifySerie(DocSerieUUID, Data):
"""修改系列名称
Returns:
(成功?, 错误消息 or None)
"""
try:
serie = CommunitySeries.objects.get(DocSerieUUID=UUIDObj(DocSerieUUID).bytes)
except (CommunitySeries.DoesNotExist, ValueError, AttributeError):
return False, '系列不存在'
for field in ('DocSerieName',):
if field in Data:
setattr(serie, field, Data[field])
serie.save()
return True, None
@staticmethod
def DeleteSerie(DocSerieUUID):
"""删除系列
Returns:
(成功?, 错误消息 or None)
"""
try:
serie = CommunitySeries.objects.get(DocSerieUUID=UUIDObj(DocSerieUUID).bytes)
except (CommunitySeries.DoesNotExist, ValueError, AttributeError):
return False, '系列不存在'
serie.delete()
return True, None
# ========== 查询集(供视图 get_queryset 复用) ==========
@staticmethod
def QueryDocuments(Keyword='', DocSerieUUID=None):
"""文档查询集——按标题模糊 / 所属系列过滤(空值表示不过滤)"""
qs = CommunityDocument.objects.all()
if Keyword:
qs = qs.filter(DocTitle__icontains=Keyword)
if DocSerieUUID:
qs = qs.filter(DocSerieUUID=UUIDObj(DocSerieUUID).bytes)
return qs
@staticmethod
def ListDocumentsBySerie(DocSerieUUID):
"""系列下的文档查询集(DocSerieUUID 支持 bytes/UUIDObj/str)"""
return CommunityDocument.objects.filter(DocSerieUUID=UUIDObj(DocSerieUUID).bytes)
@staticmethod
def QuerySeries(Keyword=''):
"""系列查询集——按名称模糊过滤"""
qs = CommunitySeries.objects.all()
if Keyword:
qs = qs.filter(DocSerieName__icontains=Keyword)
return qs
# ========== 系列附加查询(供视图收敛裸 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):
"""判断系列下是否还有文档(防删除)"""
try:
serie_bytes = UUIDObj(DocSerieUUID).bytes
except (ValueError, AttributeError):
return False
if DocManager.GetSerie(DocSerieUUID) is None:
return False
return CommunityDocument.objects.filter(DocSerieUUID=serie_bytes).exists()