from django.db import models from django.contrib.auth.models import User from datetime import date class Category(models.Model): """设备分类""" name = models.CharField('分类名称', max_length=50, unique=True) description = models.CharField('描述', max_length=200, blank=True, default='') created_at = models.DateTimeField('创建时间', auto_now_add=True) class Meta: verbose_name = '设备分类' verbose_name_plural = verbose_name ordering = ['name'] def __str__(self): return self.name class Asset(models.Model): """硬件资产""" # 基本信息 asset_number = models.CharField('资产编号', max_length=50, db_index=True) name = models.CharField('设备名称', max_length=100) category = models.ForeignKey(Category, on_delete=models.PROTECT, verbose_name='设备分类', related_name='assets') # 硬件信息 brand = models.CharField('品牌', max_length=200, blank=True, default='') model = models.CharField('型号', max_length=200, blank=True, default='') asset_value = models.CharField('资产面值', max_length=50, blank=True, default='') serial_number = models.CharField('序列号', max_length=200, blank=True, default='', db_index=True) # 位置信息 location = models.CharField('机房', max_length=200, blank=True, default='', help_text='楼层/房间/区域') cabinet = models.CharField('机柜', max_length=200, blank=True, default='') cabinet_position = models.CharField('机柜位置', max_length=200, blank=True, default='', help_text='U位') # 网络信息 bmc_address = models.CharField('BMC地址', max_length=200, blank=True, default='') ip_address = models.CharField('IP地址', max_length=200, blank=True, default='') # 显卡信息 has_gpu = models.CharField('是否带卡', max_length=50, blank=True, default='') gpu_type = models.CharField('显卡类型', max_length=200, blank=True, default='') gpu_count = models.CharField('卡数', max_length=50, blank=True, default='') # 采购与质保 purchase_date = models.CharField('采购日期', max_length=50, blank=True, default='') warranty_expire = models.CharField('质保到期', max_length=50, blank=True, default='') supplier = models.CharField('供应商', max_length=200, blank=True, default='') # 管理信息 responsible_person = models.CharField('负责人', max_length=200, blank=True, default='') department = models.CharField('使用部门', max_length=200, blank=True, default='') user = models.CharField('维护人', max_length=200, blank=True, default='') business_type = models.CharField('业务类型', max_length=200, blank=True, default='') STATUS_CHOICES = [ ('in_use', '在用'), ('idle', '闲置'), ('maintenance', '维修中'), ('scrapped', '已报废'), ] status = models.CharField('状态', max_length=50, choices=STATUS_CHOICES, default='in_use') remark = models.CharField('备注', max_length=500, blank=True, default='') # 系统字段 created_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True, verbose_name='创建人') created_at = models.DateTimeField('创建时间', auto_now_add=True) updated_at = models.DateTimeField('更新时间', auto_now=True) class Meta: verbose_name = '硬件资产' verbose_name_plural = verbose_name ordering = ['id'] def __str__(self): return f'{self.asset_number} - {self.name}' @property def is_expired(self): if self.warranty_expire: try: from datetime import datetime expire_date = datetime.strptime(self.warranty_expire, '%Y-%m-%d').date() return expire_date < date.today() except (ValueError, TypeError): return False return False @property def is_expiring_soon(self): if self.warranty_expire: try: from datetime import datetime, timedelta expire_date = datetime.strptime(self.warranty_expire, '%Y-%m-%d').date() return date.today() <= expire_date <= date.today() + timedelta(days=30) except (ValueError, TypeError): return False return False class AssetChangeLog(models.Model): """资产变更记录""" ACTION_CHOICES = [ ('create', '创建'), ('update', '更新'), ('delete', '删除'), ('import', '导入'), ('export', '导出'), ('status_change', '状态变更'), ] asset = models.ForeignKey(Asset, on_delete=models.SET_NULL, null=True, blank=True, verbose_name='资产', related_name='change_logs') asset_number = models.CharField('资产编号', max_length=50, db_index=True) action = models.CharField('操作类型', max_length=20, choices=ACTION_CHOICES) field_name = models.CharField('变更字段', max_length=50, blank=True, default='') old_value = models.TextField('旧值', blank=True, default='') new_value = models.TextField('新值', blank=True, default='') description = models.TextField('描述', blank=True, default='') operator = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True, verbose_name='操作人') created_at = models.DateTimeField('操作时间', auto_now_add=True) class Meta: verbose_name = '变更记录' verbose_name_plural = verbose_name ordering = ['-created_at'] def __str__(self): return f'{self.asset_number} - {self.get_action_display()}'