1
0
forked from erp-dev/erp

feat: backend api

This commit is contained in:
2025-11-06 13:24:02 +08:00
parent 999fdfb136
commit 37c2e7d723
11 changed files with 264 additions and 45 deletions

0
api_man/__init__.py Normal file
View File

6
api_man/apps.py Normal file
View File

@@ -0,0 +1,6 @@
from django.apps import AppConfig
class ApiManConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'api_man'

View File

66
api_man/serializers.py Normal file
View File

@@ -0,0 +1,66 @@
from rest_framework import serializers
from basic_info import models as basic_models
class ProductCategorySerializer(serializers.ModelSerializer):
class Meta:
model = basic_models.ProductCategory
fields = '__all__'
class ProductSerializer(serializers.ModelSerializer):
class Meta:
model = basic_models.Product
fields = '__all__'
depth = 1 # 展开外键关系
class WareHouseSerializer(serializers.ModelSerializer):
class Meta:
model = basic_models.WareHouse
fields = '__all__'
class SupplierSerializer(serializers.ModelSerializer):
class Meta:
model = basic_models.Supplier
fields = '__all__'
class EmployeeSerializer(serializers.ModelSerializer):
class Meta:
model = basic_models.Employee
fields = '__all__'
class CustomerSerializer(serializers.ModelSerializer):
class Meta:
model = basic_models.Customer
fields = '__all__'
class VehicleTypeSerializer(serializers.ModelSerializer):
class Meta:
model = basic_models.VehicleType
fields = '__all__'
class BankAccountSerializer(serializers.ModelSerializer):
class Meta:
model = basic_models.BankAccount
fields = '__all__'
class DeviceInfoSerializer(serializers.ModelSerializer):
class Meta:
model = basic_models.DeviceInfo
fields = '__all__'
class VehicleTransportRecordSerializer(serializers.ModelSerializer):
vehicle_type_name = serializers.CharField(source='vehicle_type.name', read_only=True)
class Meta:
model = basic_models.VehicleTransportRecord
fields = '__all__'
depth = 1 # 展开外键关系

3
api_man/tests.py Normal file
View File

@@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.

48
api_man/urls.py Normal file
View File

@@ -0,0 +1,48 @@
from django.urls import path, include
from rest_framework import routers
from . import views
product_router = routers.DefaultRouter()
product_router.register(prefix='', viewset=views.ProductViewSet)
warehouse_router = routers.DefaultRouter()
warehouse_router.register(prefix='', viewset=views.WareHouseViewSet)
product_category_router = routers.DefaultRouter()
product_category_router.register(prefix='', viewset=views.ProductCategoryViewSet)
supplier_router = routers.DefaultRouter()
supplier_router.register(prefix='', viewset=views.SupplierViewSet)
employee_router = routers.DefaultRouter()
employee_router.register(prefix='', viewset=views.EmployeeViewSet)
customer_router = routers.DefaultRouter()
customer_router.register(prefix='', viewset=views.CustomerViewSet)
vehicle_type_router = routers.DefaultRouter()
vehicle_type_router.register(prefix='', viewset=views.VehicleTypeViewSet)
bank_account_router = routers.DefaultRouter()
bank_account_router.register(prefix='', viewset=views.BankAccountViewSet)
device_info_router = routers.DefaultRouter()
device_info_router.register(prefix='', viewset=views.DeviceInfoViewSet)
vehicle_transport_record_router = routers.DefaultRouter()
vehicle_transport_record_router.register(prefix='', viewset=views.VehicleTransportRecordViewSet)
urlpatterns = [
path('products/', include(product_router.urls)),
path('warehouses/', include(warehouse_router.urls)),
path('product-categories/', include(product_category_router.urls)),
path('suppliers/', include(supplier_router.urls)),
path('employees/', include(employee_router.urls)),
path('customers/', include(customer_router.urls)),
path('vehicle-types/', include(vehicle_type_router.urls)),
path('bank-accounts/', include(bank_account_router.urls)),
path('device-info/', include(device_info_router.urls)),
path('vehicle-transport-records/', include(vehicle_transport_record_router.urls)),
]

56
api_man/views.py Normal file
View File

@@ -0,0 +1,56 @@
from rest_framework import viewsets
from . import serializers
class BaseViewSet(viewsets.ModelViewSet):
permission_classes = [] # 允许所有访问
class ProductViewSet(BaseViewSet):
queryset = serializers.basic_models.Product.objects
serializer_class = serializers.ProductSerializer
class WareHouseViewSet(BaseViewSet):
queryset = serializers.basic_models.WareHouse.objects
serializer_class = serializers.WareHouseSerializer
class ProductCategoryViewSet(BaseViewSet):
queryset = serializers.basic_models.ProductCategory.objects
serializer_class = serializers.ProductCategorySerializer
class SupplierViewSet(BaseViewSet):
queryset = serializers.basic_models.Supplier.objects
serializer_class = serializers.SupplierSerializer
class EmployeeViewSet(BaseViewSet):
queryset = serializers.basic_models.Employee.objects
serializer_class = serializers.EmployeeSerializer
class CustomerViewSet(BaseViewSet):
queryset = serializers.basic_models.Customer.objects
serializer_class = serializers.CustomerSerializer
class VehicleTypeViewSet(BaseViewSet):
queryset = serializers.basic_models.VehicleType.objects
serializer_class = serializers.VehicleTypeSerializer
class BankAccountViewSet(BaseViewSet):
queryset = serializers.basic_models.BankAccount.objects
serializer_class = serializers.BankAccountSerializer
class DeviceInfoViewSet(BaseViewSet):
queryset = serializers.basic_models.DeviceInfo.objects
serializer_class = serializers.DeviceInfoSerializer
class VehicleTransportRecordViewSet(BaseViewSet):
queryset = serializers.basic_models.VehicleTransportRecord.objects
serializer_class = serializers.VehicleTransportRecordSerializer

View File

@@ -5,10 +5,73 @@ from flower.common import ModelBase
from django.contrib.auth.models import User from django.contrib.auth.models import User
# ==================== 常量定义 ====================
METER_TO_YARD_RATE = 0.9144 METER_TO_YARD_RATE = 0.9144
YARD_TO_METER_RATE = 1.09361 YARD_TO_METER_RATE = 1.09361
# ==================== 枚举类定义 ====================
class MerchantTypeEnum(models.IntegerChoices):
"""商户类型枚举"""
STORE = 1, '布行'
FACTORY = 2, '印花厂'
class ProductUnitEnum(models.IntegerChoices):
"""产品单位枚举"""
METER = 1, ''
YARD = 2, ''
KG = 3, '公斤'
class EmployeeTypeEnum(models.TextChoices):
"""员工职位类型枚举"""
PRINTER = '打纸', '打纸'
ROLLING = '滚筒', '滚筒'
WARE = '仓库', '仓库'
DELIVERY = '送货', '送货'
class EmployeeStatusEnum(models.TextChoices):
"""员工状态枚举"""
ACTIVE = '在职', '在职'
INACTIVE = '离职', '离职'
class DeviceStatusEnum(models.TextChoices):
"""设备状态枚举"""
ACTIVE = '使用中', '使用中'
INACTIVE = '停用', '停用'
MAINTENANCE = '维修中', '维修中'
class DeviceTypeEnum(models.TextChoices):
"""设备类型枚举"""
ROLLING = '滚筒', '滚筒'
PRINTER = '打印', '打印'
# ==================== 模型定义 ====================
class Merchant(ModelBase):
id = models.BigAutoField(primary_key=True)
name = models.CharField(max_length=100, verbose_name='商户名称')
type = models.IntegerField(choices=MerchantTypeEnum.choices, verbose_name='商户类型')
area = models.CharField(max_length=100, blank=True, null=True, verbose_name='地区')
email = models.EmailField(blank=True, null=True, verbose_name='电子邮箱')
mobile = models.CharField(max_length=20, blank=True, null=True, verbose_name='手机')
contact = models.TextField(blank=True, null=True, verbose_name='联系人')
description = models.TextField(blank=True, null=True, verbose_name='备注描述')
def __str__(self):
return self.name
class Meta:
verbose_name = '商户资料'
verbose_name_plural = '商户资料'
class VehicleType(ModelBase): class VehicleType(ModelBase):
id = models.BigAutoField(primary_key=True) id = models.BigAutoField(primary_key=True)
name = models.CharField(max_length=50, verbose_name='车辆类型名称') name = models.CharField(max_length=50, verbose_name='车辆类型名称')
@@ -39,12 +102,6 @@ class WareHouse(ModelBase):
verbose_name_plural = '仓库资料' verbose_name_plural = '仓库资料'
class ProductUnitEnum(models.IntegerChoices):
METER = 1, ''
YARD = 2, ''
KG = 3, '公斤'
class Supplier(ModelBase): class Supplier(ModelBase):
id = models.BigAutoField(primary_key=True) id = models.BigAutoField(primary_key=True)
name = models.CharField(max_length=100, verbose_name='供应商名称') name = models.CharField(max_length=100, verbose_name='供应商名称')
@@ -189,18 +246,6 @@ class Customer(ModelBase):
verbose_name_plural = '客户资料' verbose_name_plural = '客户资料'
class EmployeeTypeEnum(models.TextChoices):
PRINTER = '打纸', '打纸'
ROLLING = '滚筒', '滚筒'
WARE = '仓库', '仓库'
DELIVERY = '送货', '送货'
class EmployeeStatusEnum(models.TextChoices):
ACTIVE = '在职', '在职'
INACTIVE = '离职', '离职'
class Employee(ModelBase): class Employee(ModelBase):
id = models.BigAutoField(primary_key=True) id = models.BigAutoField(primary_key=True)
sys_user = models.OneToOneField( sys_user = models.OneToOneField(
@@ -236,17 +281,6 @@ class Employee(ModelBase):
verbose_name_plural = '员工资料' verbose_name_plural = '员工资料'
class DeviceStatusEnum(models.TextChoices):
ACTIVE = '使用中', '使用中'
INACTIVE = '停用', '停用'
MAINTENANCE = '维修中', '维修中'
class DeviceTypeEnum(models.TextChoices):
ROLLING = '滚筒', '滚筒'
PRINTER = '打印', '打印'
class DeviceInfo(ModelBase): class DeviceInfo(ModelBase):
id = models.BigAutoField(primary_key=True) id = models.BigAutoField(primary_key=True)
name = models.CharField(max_length=100, verbose_name='设备名称') name = models.CharField(max_length=100, verbose_name='设备名称')

View File

@@ -64,6 +64,7 @@ INSTALLED_APPS = [
'basic_info', 'basic_info',
'stock', 'stock',
'api_v1', 'api_v1',
'api_man',
] ]
MIDDLEWARE = [ MIDDLEWARE = [

View File

@@ -36,4 +36,5 @@ urlpatterns = [
path('admin/', admin.site.urls), path('admin/', admin.site.urls),
path('stock/', router.urls), path('stock/', router.urls),
path('api/v1/', include('api_v1.urls')), path('api/v1/', include('api_v1.urls')),
path('api/backend/', include('api_man.urls')),
] ]

View File

@@ -6,22 +6,7 @@ from functools import reduce
import decimal import decimal
class PurchaseOrder(ModelBase): # ==================== 枚举类定义 ====================
"""采购单模型"""
id = models.BigAutoField(primary_key=True)
supplier = models.ForeignKey(basic_info_models.Supplier, on_delete=models.PROTECT, related_name='purchase_orders', verbose_name='供应商')
order_date = models.DateField(verbose_name='订单日期')
total_amount = models.DecimalField(max_digits=15, decimal_places=2, verbose_name='总金额')
remarks = models.TextField(blank=True, null=True, verbose_name='备注')
def __str__(self):
return f'采购订单 {self.id} - {self.supplier.name}'
class Meta:
verbose_name = '采购单'
verbose_name_plural = '采购单'
class StockChangeSourceEnum(models.IntegerChoices): class StockChangeSourceEnum(models.IntegerChoices):
"""库存变动来源类型""" """库存变动来源类型"""
@@ -44,6 +29,25 @@ class StockChangeTypeEnum(models.IntegerChoices):
REMOVE = 2, '出库' REMOVE = 2, '出库'
# ==================== 模型定义 ====================
class PurchaseOrder(ModelBase):
"""采购单模型"""
id = models.BigAutoField(primary_key=True)
supplier = models.ForeignKey(basic_info_models.Supplier, on_delete=models.PROTECT, related_name='purchase_orders', verbose_name='供应商')
order_date = models.DateField(verbose_name='订单日期')
total_amount = models.DecimalField(max_digits=15, decimal_places=2, verbose_name='总金额')
remarks = models.TextField(blank=True, null=True, verbose_name='备注')
def __str__(self):
return f'采购订单 {self.id} - {self.supplier.name}'
class Meta:
verbose_name = '采购单'
verbose_name_plural = '采购单'
class StockChangeRecord(ModelBase): class StockChangeRecord(ModelBase):
"""库存变动记录模型""" """库存变动记录模型"""