""" API v1 通用模型 """ import os import uuid from django.db import models from django.contrib.auth import get_user_model from flower.common import ModelBase User = get_user_model() def upload_file_path(instance, filename): """ 生成随机化的文件上传路径 格式: uploads/YYYY/MM/DD/uuid.ext """ # 获取文件扩展名 ext = os.path.splitext(filename)[1].lower() # 生成随机文件名 random_filename = f"{uuid.uuid4().hex}{ext}" # 返回完整路径 from datetime import datetime now = datetime.now() return f"uploads/{now.year}/{now.month:02d}/{now.day:02d}/{random_filename}" class UploadedFile(ModelBase): """ 通用文件上传记录 用于存储无法归类到具体业务的文件上传记录 """ path = models.FileField( upload_to=upload_file_path, max_length=500, verbose_name='文件路径', help_text='文件存储路径,包含前缀、随机文件名和后缀' ) owner = models.ForeignKey( User, on_delete=models.CASCADE, related_name='uploaded_files', verbose_name='上传者' ) is_deleted = models.BooleanField( default=False, verbose_name='是否已删除', help_text='软删除标记' ) original_filename = models.CharField( max_length=255, blank=True, verbose_name='原始文件名', help_text='用户上传时的原始文件名' ) file_size = models.BigIntegerField( null=True, blank=True, verbose_name='文件大小(字节)' ) content_type = models.CharField( max_length=100, blank=True, verbose_name='文件类型', help_text='MIME类型,如 image/jpeg' ) class Meta: db_table = 'api_uploaded_file' verbose_name = '上传文件' verbose_name_plural = '上传文件' ordering = ['-created_at'] def __str__(self): return f"{self.original_filename or self.path.name} (by {self.owner.username})" @property def file_url(self): """获取文件访问URL""" if self.path: return self.path.url return None class DataSync(ModelBase): """记录外部数据同步的执行情况""" class TableName(models.TextChoices): PRODUCT = 'product', '产品' CUSTOMER = 'customer', '客户' table_name = models.CharField(max_length=50, choices=TableName.choices, verbose_name='同步目标') page_index = models.PositiveIntegerField(default=1, verbose_name='页码') page_size = models.PositiveIntegerField(default=100, verbose_name='每页数量') total_count = models.PositiveIntegerField(default=0, verbose_name='远端总数') synced_rows = models.PositiveIntegerField(default=0, verbose_name='本次同步数量') last_ctime = models.DateTimeField(null=True, blank=True, verbose_name='最新数据时间') last_rowid = models.CharField(max_length=64, blank=True, verbose_name='最新 RowID') note = models.CharField(max_length=255, blank=True, verbose_name='备注') class Meta: db_table = 'api_data_sync' verbose_name = '数据同步记录' verbose_name_plural = '数据同步记录' ordering = ['-created_at'] def __str__(self): return f'{self.table_name} @ {self.created_at:%Y-%m-%d %H:%M:%S}' class MDYPlateOrderStaging(ModelBase): """明道云“开版数据表”同步暂存表(不影响 printing.PlateOrder)。 设计目标: - 与现有业务模型完全隔离,避免影响业务数据与流程 - 仅保留 rowid 便于检索排查,其余信息全部落在 raw(JSON) 中 - 随着同步深入再逐步“属性化”字段(从 raw 实时提取/映射) """ mdy_rowid = models.CharField( max_length=64, unique=True, db_index=True, verbose_name='明道云 RowID', help_text='明道云行记录的 rowid(全局唯一)', ) raw = models.JSONField( default=dict, blank=True, verbose_name='原始行数据', help_text='getFilterRows 返回的整行原始数据(包含各 controlId 字段)', ) class Meta: db_table = 'api_mdy_plate_order_staging' verbose_name = '明道云开版暂存' verbose_name_plural = '明道云开版暂存' ordering = ['-created_at'] def __str__(self): return f'{self.mdy_rowid}'