repair-agent 88b8f023f4
Some checks failed
Build and Deploy Backend / build-and-deploy (push) Failing after 1m36s
Fix app api
2026-02-09 15:35:33 +08:00

181 lines
7.2 KiB
Python

"""
设备模块模型
"""
from django.db import models
from apps.users.models import User
from apps.spirits.models import Spirit
class DeviceType(models.Model):
"""设备类型表"""
id = models.BigAutoField(primary_key=True)
brand = models.CharField('品牌', max_length=50)
product_code = models.CharField('产品代号', max_length=50, unique=True)
name = models.CharField('名称', max_length=100)
is_network_required = models.BooleanField('是否需要联网', default=True)
is_active = models.BooleanField('是否启用', default=True)
created_at = models.DateTimeField('创建时间', auto_now_add=True)
updated_at = models.DateTimeField('更新时间', auto_now=True)
class Meta:
db_table = 'device_type'
verbose_name = '设备类型'
verbose_name_plural = '设备类型'
def save(self, *args, **kwargs):
# 根据产品代号后缀自动判断是否需要联网
if self.product_code:
self.is_network_required = not self.product_code.endswith('-OFF')
super().save(*args, **kwargs)
def __str__(self):
return f"{self.brand} - {self.name}"
class DeviceBatch(models.Model):
"""设备批次表"""
STATUS_CHOICES = [
('pending', '待生成'),
('generated', '已生成'),
]
id = models.BigAutoField(primary_key=True)
device_type = models.ForeignKey(DeviceType, on_delete=models.PROTECT, related_name='batches', verbose_name='设备类型')
batch_no = models.CharField('批次号', max_length=50)
production_date = models.DateField('生产日期')
production_week = models.CharField('生产周', max_length=10, blank=True) # 格式: 25W45
quantity = models.IntegerField('数量')
remark = models.TextField('备注', blank=True, default='')
status = models.CharField('状态', max_length=20, choices=STATUS_CHOICES, default='pending')
created_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, verbose_name='创建人')
created_at = models.DateTimeField('创建时间', auto_now_add=True)
updated_at = models.DateTimeField('更新时间', auto_now=True)
class Meta:
db_table = 'device_batch'
verbose_name = '设备批次'
verbose_name_plural = '设备批次'
unique_together = ['device_type', 'batch_no', 'production_date']
def save(self, *args, **kwargs):
# 计算生产周
if self.production_date and not self.production_week:
year = self.production_date.year
week = self.production_date.isocalendar()[1]
self.production_week = f"{year % 100}W{week:02d}"
super().save(*args, **kwargs)
def __str__(self):
return f"{self.device_type.brand}-{self.batch_no}"
class Device(models.Model):
"""设备表"""
STATUS_CHOICES = [
('in_stock', '库存中'),
('out_stock', '已出库'),
('bound', '已绑定'),
]
id = models.BigAutoField(primary_key=True)
sn = models.CharField('SN码', max_length=50, unique=True)
device_type = models.ForeignKey(DeviceType, on_delete=models.PROTECT, null=True, related_name='devices', verbose_name='设备类型')
batch = models.ForeignKey(DeviceBatch, on_delete=models.SET_NULL, null=True, related_name='devices', verbose_name='所属批次')
mac_address = models.CharField('MAC地址', max_length=20, blank=True, null=True, unique=True)
name = models.CharField('自定义名称', max_length=100, blank=True, default='')
status = models.CharField('状态', max_length=20, choices=STATUS_CHOICES, default='in_stock')
battery = models.IntegerField('电量百分比', default=0) # 0-100
is_online = models.BooleanField('是否在线', default=False)
is_ai = models.BooleanField('是否AI设备', default=True)
icon = models.CharField('设备图标', max_length=100, null=True, blank=True)
firmware_version = models.CharField('固件版本', max_length=20, blank=True, default='')
last_online_at = models.DateTimeField('最后在线时间', null=True, blank=True)
created_at = models.DateTimeField('创建时间', auto_now_add=True)
updated_at = models.DateTimeField('更新时间', auto_now=True)
class Meta:
db_table = 'device'
verbose_name = '设备'
verbose_name_plural = '设备'
indexes = [
models.Index(fields=['mac_address']),
models.Index(fields=['status']),
]
def __str__(self):
return self.sn
class UserDevice(models.Model):
"""用户设备绑定表"""
BIND_TYPE_CHOICES = [
('owner', '所有者'),
('share', '分享'),
]
id = models.BigAutoField(primary_key=True)
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='user_devices', verbose_name='用户')
device = models.ForeignKey(Device, on_delete=models.CASCADE, related_name='user_devices', verbose_name='设备')
spirit = models.ForeignKey(Spirit, on_delete=models.SET_NULL, null=True, blank=True, related_name='user_devices', verbose_name='绑定的智能体')
bind_type = models.CharField('绑定类型', max_length=20, choices=BIND_TYPE_CHOICES, default='owner')
bind_time = models.DateTimeField('绑定时间', auto_now_add=True)
is_active = models.BooleanField('是否有效', default=True)
class Meta:
db_table = 'user_device'
verbose_name = '用户设备绑定'
verbose_name_plural = '用户设备绑定'
unique_together = ['user', 'device']
def __str__(self):
return f"{self.user.phone} - {self.device.sn}"
class DeviceSettings(models.Model):
"""设备设置"""
device = models.OneToOneField(
Device, on_delete=models.CASCADE,
related_name='settings', verbose_name='设备'
)
nickname = models.CharField('设备昵称', max_length=50, null=True, blank=True)
user_name = models.CharField('用户称呼', max_length=50, null=True, blank=True)
volume = models.IntegerField('音量', default=50) # 0-100
brightness = models.IntegerField('亮度', default=50) # 0-100
allow_interrupt = models.BooleanField('允许打断', default=True)
privacy_mode = models.BooleanField('隐私模式', default=False)
created_at = models.DateTimeField('创建时间', auto_now_add=True)
updated_at = models.DateTimeField('更新时间', auto_now=True)
class Meta:
db_table = 'device_settings'
verbose_name = '设备设置'
verbose_name_plural = verbose_name
def __str__(self):
return f"设置 - {self.device.sn}"
class DeviceWifi(models.Model):
"""设备 WiFi 配置"""
device = models.ForeignKey(
Device, on_delete=models.CASCADE,
related_name='wifi_list', verbose_name='设备'
)
ssid = models.CharField('WiFi名称', max_length=100)
is_connected = models.BooleanField('是否已连接', default=False)
created_at = models.DateTimeField('创建时间', auto_now_add=True)
updated_at = models.DateTimeField('更新时间', auto_now=True)
class Meta:
db_table = 'device_wifi'
verbose_name = '设备WiFi'
verbose_name_plural = verbose_name
unique_together = ['device', 'ssid']
def __str__(self):
return f"{self.device.sn} - {self.ssid}"