From 37c2e7d723c2df5bb5dd73ec7454c7c1bfdee5f9 Mon Sep 17 00:00:00 2001 From: colaftc Date: Thu, 6 Nov 2025 13:24:02 +0800 Subject: [PATCH] feat: backend api --- api_man/__init__.py | 0 api_man/apps.py | 6 +++ api_man/migrations/__init__.py | 0 api_man/serializers.py | 66 ++++++++++++++++++++++++ api_man/tests.py | 3 ++ api_man/urls.py | 48 ++++++++++++++++++ api_man/views.py | 56 +++++++++++++++++++++ basic_info/models.py | 92 +++++++++++++++++++++++----------- flower/settings.py | 1 + flower/urls.py | 1 + stock/models.py | 36 +++++++------ 11 files changed, 264 insertions(+), 45 deletions(-) create mode 100644 api_man/__init__.py create mode 100644 api_man/apps.py create mode 100644 api_man/migrations/__init__.py create mode 100644 api_man/serializers.py create mode 100644 api_man/tests.py create mode 100644 api_man/urls.py create mode 100644 api_man/views.py diff --git a/api_man/__init__.py b/api_man/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/api_man/apps.py b/api_man/apps.py new file mode 100644 index 0000000..a1b1385 --- /dev/null +++ b/api_man/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class ApiManConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'api_man' diff --git a/api_man/migrations/__init__.py b/api_man/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/api_man/serializers.py b/api_man/serializers.py new file mode 100644 index 0000000..fb7ff6c --- /dev/null +++ b/api_man/serializers.py @@ -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 # 展开外键关系 diff --git a/api_man/tests.py b/api_man/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/api_man/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/api_man/urls.py b/api_man/urls.py new file mode 100644 index 0000000..bc0b508 --- /dev/null +++ b/api_man/urls.py @@ -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)), +] diff --git a/api_man/views.py b/api_man/views.py new file mode 100644 index 0000000..93e6a3d --- /dev/null +++ b/api_man/views.py @@ -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 diff --git a/basic_info/models.py b/basic_info/models.py index 0feb0a3..d738af5 100644 --- a/basic_info/models.py +++ b/basic_info/models.py @@ -5,10 +5,73 @@ from flower.common import ModelBase from django.contrib.auth.models import User +# ==================== 常量定义 ==================== METER_TO_YARD_RATE = 0.9144 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): id = models.BigAutoField(primary_key=True) name = models.CharField(max_length=50, verbose_name='车辆类型名称') @@ -39,12 +102,6 @@ class WareHouse(ModelBase): verbose_name_plural = '仓库资料' -class ProductUnitEnum(models.IntegerChoices): - METER = 1, '米' - YARD = 2, '码' - KG = 3, '公斤' - - class Supplier(ModelBase): id = models.BigAutoField(primary_key=True) name = models.CharField(max_length=100, verbose_name='供应商名称') @@ -189,18 +246,6 @@ class Customer(ModelBase): verbose_name_plural = '客户资料' -class EmployeeTypeEnum(models.TextChoices): - PRINTER = '打纸', '打纸' - ROLLING = '滚筒', '滚筒' - WARE = '仓库', '仓库' - DELIVERY = '送货', '送货' - - -class EmployeeStatusEnum(models.TextChoices): - ACTIVE = '在职', '在职' - INACTIVE = '离职', '离职' - - class Employee(ModelBase): id = models.BigAutoField(primary_key=True) sys_user = models.OneToOneField( @@ -236,17 +281,6 @@ class Employee(ModelBase): verbose_name_plural = '员工资料' -class DeviceStatusEnum(models.TextChoices): - ACTIVE = '使用中', '使用中' - INACTIVE = '停用', '停用' - MAINTENANCE = '维修中', '维修中' - - -class DeviceTypeEnum(models.TextChoices): - ROLLING = '滚筒', '滚筒' - PRINTER = '打印', '打印' - - class DeviceInfo(ModelBase): id = models.BigAutoField(primary_key=True) name = models.CharField(max_length=100, verbose_name='设备名称') diff --git a/flower/settings.py b/flower/settings.py index ecd7b22..cd0caca 100644 --- a/flower/settings.py +++ b/flower/settings.py @@ -64,6 +64,7 @@ INSTALLED_APPS = [ 'basic_info', 'stock', 'api_v1', + 'api_man', ] MIDDLEWARE = [ diff --git a/flower/urls.py b/flower/urls.py index 33cbc91..8a16407 100644 --- a/flower/urls.py +++ b/flower/urls.py @@ -36,4 +36,5 @@ urlpatterns = [ path('admin/', admin.site.urls), path('stock/', router.urls), path('api/v1/', include('api_v1.urls')), + path('api/backend/', include('api_man.urls')), ] diff --git a/stock/models.py b/stock/models.py index f499555..36b437c 100644 --- a/stock/models.py +++ b/stock/models.py @@ -6,22 +6,7 @@ from functools import reduce 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): """库存变动来源类型""" @@ -44,6 +29,25 @@ class StockChangeTypeEnum(models.IntegerChoices): 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): """库存变动记录模型"""