"feat(gvsdsdk): 新增 PositionManager 服务层并接入职务系统 API
- PositionManager 提供职务/岗位模板/模板权限共 11 个服务方法 - position.py 11 处裸 ORM 操作全部改用服务层 - 消除职务系统跨表裸查询,统一走 gvsdsdk"
This commit is contained in:
1 parent
62b6ae08ed
commit
e27f3d3dd6
2 files changed
+191
-61
No files matched your search
@@ -11,6 +11,7 @@ from gvsds.apps.gerp.serializers import (
|
||||
PositionTemplateSerializer, PositionTemplateCreateSerializer, PositionTemplateUpdateSerializer,
|
||||
PositionTemplatePermissionSerializer, PositionTemplatePermAssignSerializer, PositionTemplatePermRemoveSerializer,
|
||||
)
|
||||
from gvsdsdk.auth.managers import PositionManager
|
||||
|
||||
|
||||
class PositionListView(ELTAuthenticatedAPIView):
|
||||
@@ -21,7 +22,7 @@ class PositionListView(ELTAuthenticatedAPIView):
|
||||
if not tenant_uuid:
|
||||
return Response({'Code': 400, 'Msg': 'TenantUUID 必填', 'Data': None}, status=400)
|
||||
|
||||
positions = Position.objects.filter(TenantUUID=tenant_uuid, PositionStatus=1)
|
||||
positions = PositionManager.GetPositionsForTenant(tenant_uuid)
|
||||
serializer = PositionSerializer(positions, many=True)
|
||||
return Response({'Code': 200, 'Msg': 'OK', 'Data': serializer.data})
|
||||
|
||||
@@ -62,17 +63,14 @@ class PositionUpdateView(ELTAuthenticatedAPIView):
|
||||
return Response({'Code': 400, 'Msg': serializer.errors, 'Data': None}, status=400)
|
||||
|
||||
data = serializer.validated_data
|
||||
try:
|
||||
position = Position.objects.get(PositionUUID=data['PositionUUID'])
|
||||
except Position.DoesNotExist:
|
||||
position = PositionManager.GetPositionByUUID(data['PositionUUID'])
|
||||
if position is None:
|
||||
return Response({'Code': 404, 'Msg': '职务不存在', 'Data': None}, status=404)
|
||||
|
||||
for field in ('PositionName', 'PositionCode', 'PositionLevel', 'PositionStatus', 'PositionDesc'):
|
||||
if field in data:
|
||||
setattr(position, field, data[field])
|
||||
import datetime
|
||||
position.UpdateTime = datetime.datetime.utcnow()
|
||||
position.save(update_fields=[f for f in data if f != 'PositionUUID'] + ['UpdateTime'])
|
||||
position = PositionManager.UpdatePosition(
|
||||
data['PositionUUID'],
|
||||
**{f: data[f] for f in ('PositionName', 'PositionCode', 'PositionLevel', 'PositionStatus', 'PositionDesc') if f in data},
|
||||
)
|
||||
return Response({'Code': 200, 'Msg': '更新成功', 'Data': PositionSerializer(position).data})
|
||||
|
||||
|
||||
@@ -84,15 +82,8 @@ class PositionDeleteView(ELTAuthenticatedAPIView):
|
||||
if not position_uuid:
|
||||
return Response({'Code': 400, 'Msg': 'PositionUUID 必填', 'Data': None}, status=400)
|
||||
|
||||
try:
|
||||
position = Position.objects.get(PositionUUID=position_uuid)
|
||||
except Position.DoesNotExist:
|
||||
if not PositionManager.DeletePosition(position_uuid):
|
||||
return Response({'Code': 404, 'Msg': '职务不存在', 'Data': None}, status=404)
|
||||
|
||||
position.PositionStatus = 0
|
||||
import datetime
|
||||
position.UpdateTime = datetime.datetime.utcnow()
|
||||
position.save(update_fields=['PositionStatus', 'UpdateTime'])
|
||||
return Response({'Code': 200, 'Msg': '删除成功', 'Data': None})
|
||||
|
||||
|
||||
@@ -106,7 +97,7 @@ class PositionTemplateListView(ELTAuthenticatedAPIView):
|
||||
if not tenant_uuid:
|
||||
return Response({'Code': 400, 'Msg': 'TenantUUID 必填', 'Data': None}, status=400)
|
||||
|
||||
templates = PositionTemplate.objects.filter(TenantUUID=tenant_uuid, TemplateStatus=1)
|
||||
templates = PositionManager.GetTemplatesForTenant(tenant_uuid)
|
||||
serializer = PositionTemplateSerializer(templates, many=True)
|
||||
return Response({'Code': 200, 'Msg': 'OK', 'Data': serializer.data})
|
||||
|
||||
@@ -125,15 +116,12 @@ class PositionTemplateCreateView(ELTAuthenticatedAPIView):
|
||||
except Tenant.DoesNotExist:
|
||||
return Response({'Code': 404, 'Msg': '租户不存在', 'Data': None}, status=404)
|
||||
|
||||
template = PositionTemplate(
|
||||
PositionTemplateUUID=uuid.uuid4().bytes,
|
||||
TenantUUID=tenant,
|
||||
TemplateName=data['TemplateName'],
|
||||
TemplateCode=data.get('TemplateCode', ''),
|
||||
TemplateStatus=1,
|
||||
template = PositionManager.CreatePositionTemplate(
|
||||
data['TemplateName'],
|
||||
tenant.TenantUUID,
|
||||
Code=data.get('TemplateCode', ''),
|
||||
TemplateDesc=data.get('TemplateDesc', ''),
|
||||
)
|
||||
template.save()
|
||||
return Response({'Code': 200, 'Msg': '创建成功', 'Data': PositionTemplateSerializer(template).data})
|
||||
|
||||
|
||||
@@ -146,17 +134,14 @@ class PositionTemplateUpdateView(ELTAuthenticatedAPIView):
|
||||
return Response({'Code': 400, 'Msg': serializer.errors, 'Data': None}, status=400)
|
||||
|
||||
data = serializer.validated_data
|
||||
try:
|
||||
template = PositionTemplate.objects.get(PositionTemplateUUID=data['PositionTemplateUUID'])
|
||||
except PositionTemplate.DoesNotExist:
|
||||
template = PositionManager.GetPositionTemplateByUUID(data['PositionTemplateUUID'])
|
||||
if template is None:
|
||||
return Response({'Code': 404, 'Msg': '岗位模板不存在', 'Data': None}, status=404)
|
||||
|
||||
for field in ('TemplateName', 'TemplateCode', 'TemplateStatus', 'TemplateDesc'):
|
||||
if field in data:
|
||||
setattr(template, field, data[field])
|
||||
import datetime
|
||||
template.UpdateTime = datetime.datetime.utcnow()
|
||||
template.save(update_fields=[f for f in data if f != 'PositionTemplateUUID'] + ['UpdateTime'])
|
||||
template = PositionManager.UpdatePositionTemplate(
|
||||
data['PositionTemplateUUID'],
|
||||
**{f: data[f] for f in ('TemplateName', 'TemplateCode', 'TemplateStatus', 'TemplateDesc') if f in data},
|
||||
)
|
||||
return Response({'Code': 200, 'Msg': '更新成功', 'Data': PositionTemplateSerializer(template).data})
|
||||
|
||||
|
||||
@@ -168,15 +153,8 @@ class PositionTemplateDeleteView(ELTAuthenticatedAPIView):
|
||||
if not template_uuid:
|
||||
return Response({'Code': 400, 'Msg': 'PositionTemplateUUID 必填', 'Data': None}, status=400)
|
||||
|
||||
try:
|
||||
template = PositionTemplate.objects.get(PositionTemplateUUID=template_uuid)
|
||||
except PositionTemplate.DoesNotExist:
|
||||
if not PositionManager.DeletePositionTemplate(template_uuid):
|
||||
return Response({'Code': 404, 'Msg': '岗位模板不存在', 'Data': None}, status=404)
|
||||
|
||||
template.TemplateStatus = 0
|
||||
import datetime
|
||||
template.UpdateTime = datetime.datetime.utcnow()
|
||||
template.save(update_fields=['TemplateStatus', 'UpdateTime'])
|
||||
return Response({'Code': 200, 'Msg': '删除成功', 'Data': None})
|
||||
|
||||
|
||||
@@ -198,12 +176,7 @@ class PositionTemplatePermAssignView(ELTAuthenticatedAPIView):
|
||||
if existing:
|
||||
return Response({'Code': 409, 'Msg': '关联已存在', 'Data': PositionTemplatePermissionSerializer(existing).data})
|
||||
|
||||
ptp = PositionTemplatePermission(
|
||||
PTPermUUID=uuid.uuid4().bytes,
|
||||
PositionTemplateUUID=data['PositionTemplateUUID'],
|
||||
PermUUID=data['PermUUID'],
|
||||
)
|
||||
ptp.save()
|
||||
ptp = PositionManager.AssignPermToTemplate(data['PositionTemplateUUID'], data['PermUUID'])
|
||||
return Response({'Code': 200, 'Msg': '关联成功', 'Data': PositionTemplatePermissionSerializer(ptp).data})
|
||||
|
||||
|
||||
@@ -216,11 +189,7 @@ class PositionTemplatePermRemoveView(ELTAuthenticatedAPIView):
|
||||
return Response({'Code': 400, 'Msg': serializer.errors, 'Data': None}, status=400)
|
||||
|
||||
data = serializer.validated_data
|
||||
deleted, _ = PositionTemplatePermission.objects.filter(
|
||||
PositionTemplateUUID=data['PositionTemplateUUID'],
|
||||
PermUUID=data['PermUUID'],
|
||||
).delete()
|
||||
if deleted > 0:
|
||||
if PositionManager.RemovePermFromTemplate(data['PositionTemplateUUID'], data['PermUUID']):
|
||||
return Response({'Code': 200, 'Msg': '移除成功', 'Data': None})
|
||||
return Response({'Code': 404, 'Msg': '关联不存在', 'Data': None})
|
||||
|
||||
@@ -233,11 +202,7 @@ class PositionTemplatePermsView(ELTAuthenticatedAPIView):
|
||||
if not template_uuid:
|
||||
return Response({'Code': 400, 'Msg': 'PositionTemplateUUID 必填', 'Data': None}, status=400)
|
||||
|
||||
from gvsds.apps.gerp.models import Permission
|
||||
ptp_uuids = PositionTemplatePermission.objects.filter(
|
||||
PositionTemplateUUID=template_uuid
|
||||
).values_list('PermUUID', flat=True)
|
||||
perms = Permission.objects.filter(PermUUID__in=ptp_uuids)
|
||||
from gvsds.apps.gerp.serializers import PermissionSerializer
|
||||
perms = PositionManager.GetPermsForTemplate(template_uuid)
|
||||
serializer = PermissionSerializer(perms, many=True)
|
||||
return Response({'Code': 200, 'Msg': 'OK', 'Data': serializer.data})
|
||||
+167
-2
@@ -1,10 +1,10 @@
|
||||
import uuid
|
||||
from django.utils import timezone as _timezone
|
||||
|
||||
from gvsdsdk.models import Role, UserRole, RolePermission, Permission
|
||||
from gvsdsdk.models import Role, UserRole, RolePermission, Permission, Position, PositionTemplate, PositionTemplatePermission
|
||||
from gvsdsdk.model_utils import _GetUserModel
|
||||
|
||||
# NOTE: 类型注解暂缓——RoleManager 静态方法较多,全量补充注解工作量较大且易引入回归,后续单独迭代处理。
|
||||
# NOTE: 类型注解暂缓——RoleManager/PositionManager 静态方法较多,全量补充注解工作量较大且易引入回归,后续单独迭代处理。
|
||||
|
||||
|
||||
class RoleManager:
|
||||
@@ -167,3 +167,168 @@ class RoleManager:
|
||||
qs = qs.filter(CompanyUUID=CompanyUUID)
|
||||
return qs.exists()
|
||||
|
||||
|
||||
class PositionManager:
|
||||
"""职务管理器——提供人事职务标签创建、岗位模板管理"""
|
||||
|
||||
# ── 人事职务标签 ──
|
||||
|
||||
@staticmethod
|
||||
def CreatePosition(Name, TenantUUID, Code='', Level=0, **Kwargs):
|
||||
"""创建人事职务标签(TenantUUID 传 UUIDObj/str/bytes)"""
|
||||
position = Position(
|
||||
PositionUUID=uuid.uuid4().bytes,
|
||||
TenantUUID=TenantUUID,
|
||||
PositionName=Name,
|
||||
PositionCode=Code,
|
||||
PositionLevel=Level,
|
||||
PositionStatus=1,
|
||||
PositionDesc=Kwargs.get('PositionDesc', ''),
|
||||
CreateTime=_timezone.now(),
|
||||
UpdateTime=_timezone.now(),
|
||||
)
|
||||
position.save()
|
||||
return position
|
||||
|
||||
@staticmethod
|
||||
def GetPositionsForTenant(TenantUUID):
|
||||
"""获取租户下的所有启用职务"""
|
||||
return Position.objects.filter(TenantUUID=TenantUUID, PositionStatus=1)
|
||||
|
||||
@staticmethod
|
||||
def GetPositionByUUID(PositionUUID):
|
||||
"""按 UUID 查询职务(不存在返回 None)"""
|
||||
return Position.objects.filter(PositionUUID=PositionUUID).first()
|
||||
|
||||
@staticmethod
|
||||
def UpdatePosition(PositionUUID, **Fields):
|
||||
"""更新职务字段(自动刷新 UpdateTime)
|
||||
|
||||
Args:
|
||||
PositionUUID: 职务 UUID
|
||||
**Fields: 允许字段 PositionName/PositionCode/PositionLevel/PositionStatus/PositionDesc
|
||||
|
||||
Returns:
|
||||
更新后的 Position 实例;职务不存在返回 None
|
||||
"""
|
||||
position = Position.objects.filter(PositionUUID=PositionUUID).first()
|
||||
if not position:
|
||||
return None
|
||||
allowed = ('PositionName', 'PositionCode', 'PositionLevel', 'PositionStatus', 'PositionDesc')
|
||||
update_fields = []
|
||||
for key, value in Fields.items():
|
||||
if key in allowed:
|
||||
setattr(position, key, value)
|
||||
update_fields.append(key)
|
||||
position.UpdateTime = _timezone.now()
|
||||
update_fields.append('UpdateTime')
|
||||
if update_fields:
|
||||
position.save(update_fields=update_fields)
|
||||
return position
|
||||
|
||||
@staticmethod
|
||||
def DeletePosition(PositionUUID):
|
||||
"""软删除职务(PositionStatus=0);返回是否命中"""
|
||||
position = Position.objects.filter(PositionUUID=PositionUUID).first()
|
||||
if not position:
|
||||
return False
|
||||
position.PositionStatus = 0
|
||||
position.UpdateTime = _timezone.now()
|
||||
position.save(update_fields=['PositionStatus', 'UpdateTime'])
|
||||
return True
|
||||
|
||||
# ── 岗位模板 ──
|
||||
|
||||
@staticmethod
|
||||
def CreatePositionTemplate(Name, TenantUUID, Code='', **Kwargs):
|
||||
"""创建岗位模板(TenantUUID 传 UUIDObj/str/bytes)"""
|
||||
template = PositionTemplate(
|
||||
PositionTemplateUUID=uuid.uuid4().bytes,
|
||||
TenantUUID=TenantUUID,
|
||||
TemplateName=Name,
|
||||
TemplateCode=Code,
|
||||
TemplateStatus=1,
|
||||
TemplateDesc=Kwargs.get('TemplateDesc', ''),
|
||||
CreateTime=_timezone.now(),
|
||||
UpdateTime=_timezone.now(),
|
||||
)
|
||||
template.save()
|
||||
return template
|
||||
|
||||
@staticmethod
|
||||
def GetTemplatesForTenant(TenantUUID):
|
||||
"""获取租户下的所有启用岗位模板"""
|
||||
return PositionTemplate.objects.filter(TenantUUID=TenantUUID, TemplateStatus=1)
|
||||
|
||||
@staticmethod
|
||||
def GetPositionTemplateByUUID(PositionTemplateUUID):
|
||||
"""按 UUID 查询岗位模板(不存在返回 None)"""
|
||||
return PositionTemplate.objects.filter(PositionTemplateUUID=PositionTemplateUUID).first()
|
||||
|
||||
@staticmethod
|
||||
def UpdatePositionTemplate(PositionTemplateUUID, **Fields):
|
||||
"""更新岗位模板字段(自动刷新 UpdateTime)
|
||||
|
||||
Args:
|
||||
PositionTemplateUUID: 岗位模板 UUID
|
||||
**Fields: 允许字段 TemplateName/TemplateCode/TemplateStatus/TemplateDesc
|
||||
|
||||
Returns:
|
||||
更新后的 PositionTemplate 实例;模板不存在返回 None
|
||||
"""
|
||||
template = PositionTemplate.objects.filter(PositionTemplateUUID=PositionTemplateUUID).first()
|
||||
if not template:
|
||||
return None
|
||||
allowed = ('TemplateName', 'TemplateCode', 'TemplateStatus', 'TemplateDesc')
|
||||
update_fields = []
|
||||
for key, value in Fields.items():
|
||||
if key in allowed:
|
||||
setattr(template, key, value)
|
||||
update_fields.append(key)
|
||||
template.UpdateTime = _timezone.now()
|
||||
update_fields.append('UpdateTime')
|
||||
if update_fields:
|
||||
template.save(update_fields=update_fields)
|
||||
return template
|
||||
|
||||
@staticmethod
|
||||
def DeletePositionTemplate(PositionTemplateUUID):
|
||||
"""软删除岗位模板(TemplateStatus=0);返回是否命中"""
|
||||
template = PositionTemplate.objects.filter(PositionTemplateUUID=PositionTemplateUUID).first()
|
||||
if not template:
|
||||
return False
|
||||
template.TemplateStatus = 0
|
||||
template.UpdateTime = _timezone.now()
|
||||
template.save(update_fields=['TemplateStatus', 'UpdateTime'])
|
||||
return True
|
||||
|
||||
# ── 岗位模板权限关联 ──
|
||||
|
||||
@staticmethod
|
||||
def AssignPermToTemplate(TemplateUUID, PermUUID):
|
||||
"""为岗位模板关联权限"""
|
||||
ptp = PositionTemplatePermission(
|
||||
PTPermUUID=uuid.uuid4().bytes,
|
||||
PositionTemplateUUID=TemplateUUID,
|
||||
PermUUID=PermUUID,
|
||||
CreateTime=_timezone.now(),
|
||||
)
|
||||
ptp.save()
|
||||
return ptp
|
||||
|
||||
@staticmethod
|
||||
def RemovePermFromTemplate(TemplateUUID, PermUUID):
|
||||
"""移除岗位模板与权限的关联;返回是否命中"""
|
||||
deleted, _ = PositionTemplatePermission.objects.filter(
|
||||
PositionTemplateUUID=TemplateUUID, PermUUID=PermUUID
|
||||
).delete()
|
||||
return deleted > 0
|
||||
|
||||
@staticmethod
|
||||
def GetPermsForTemplate(TemplateUUID):
|
||||
"""获取岗位模板关联的所有启用权限"""
|
||||
perm_uuids = PositionTemplatePermission.objects.filter(
|
||||
PositionTemplateUUID=TemplateUUID
|
||||
).values_list('PermUUID', flat=True)
|
||||
return Permission.objects.filter(PermUUID__in=perm_uuids, PermStatus=1)
|
||||
|
||||
Reference in new issue
Block a user