1
0
forked from erp-dev/erp

feat: sse && multi_merchant completed

This commit is contained in:
2025-11-11 10:56:20 +08:00
parent b2078dfa46
commit 2aafb93aad
43 changed files with 2445 additions and 244 deletions

View File

@@ -0,0 +1,90 @@
"""
库存变动视图的公共 Mixin
提供通用的权限检查、数据构建、错误响应等方法
"""
from rest_framework import status
from rest_framework.response import Response
from basic_info.services import DataVisibilityService
import logging
logger = logging.getLogger(__name__)
class StockChangeViewMixin:
"""库存变动视图基类,提供公共方法"""
def get_merchant_id(self, request):
"""获取当前用户的商户ID"""
try:
return request.user.employee.merchant_id
except AttributeError:
return None
def check_employee_permission(self, request):
"""检查用户是否有员工信息"""
if not hasattr(request.user, 'employee'):
logger.error(f"用户 {request.user.username} 无员工信息")
return False
return True
def validate_warehouse_visibility(self, warehouse_id, request):
"""验证仓库对当前用户是否可见"""
return DataVisibilityService.is_warehouse_visible_to_employee(warehouse_id, request.user)
def validate_product_visibility(self, product_id, request):
"""验证产品对当前用户是否可见"""
return DataVisibilityService.is_product_visible_to_employee(product_id, request.user)
def filter_visible_details(self, details, request):
"""过滤出用户可见的产品明细"""
visible_details = []
for detail in details:
if self.validate_product_visibility(detail.product_id, request):
visible_details.append(detail)
return visible_details
def build_record_data(self, record):
"""构建库存变动记录数据"""
return {
'id': record.id,
'type': record.type,
'type_display': record.get_type_display(),
'warehouse': record.warehouse_id,
'warehouse_name': record.warehouse.name,
'source_type': record.source_type,
'source_type_display': record.get_source_type_display(),
'source_id': record.source_id,
'is_finished': record.is_finished,
'finished_at': record.finished_at,
'created_at': record.created_at,
'created_by': record.created_by.username if record.created_by else None,
'remarks': record.remarks,
}
def build_detail_data(self, detail):
"""构建明细数据"""
return {
'id': detail.id,
'product': detail.product_id,
'product_name': detail.product.name,
'quantity': float(detail.quantity),
'unit': detail.unit,
'unit_display': detail.get_unit_display(),
}
def error_response(self, error_msg, details=None, status_code=status.HTTP_400_BAD_REQUEST):
"""统一的错误响应"""
response_data = {'error': error_msg}
if details:
response_data['details'] = details
return Response(response_data, status=status_code)
def permission_error_response(self, message='无权限访问'):
"""权限错误响应"""
return Response({'error': message}, status=status.HTTP_403_FORBIDDEN)
def not_found_response(self, message):
"""未找到资源响应"""
return Response({'error': message}, status=status.HTTP_404_NOT_FOUND)