models.py 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. from django.db import models
  2. from django.contrib.auth.models import User
  3. from datetime import date
  4. class Category(models.Model):
  5. """设备分类"""
  6. name = models.CharField('分类名称', max_length=50, unique=True)
  7. description = models.CharField('描述', max_length=200, blank=True, default='')
  8. created_at = models.DateTimeField('创建时间', auto_now_add=True)
  9. class Meta:
  10. verbose_name = '设备分类'
  11. verbose_name_plural = verbose_name
  12. ordering = ['name']
  13. def __str__(self):
  14. return self.name
  15. class Asset(models.Model):
  16. """硬件资产"""
  17. # 基本信息
  18. asset_number = models.CharField('资产编号', max_length=50, db_index=True)
  19. name = models.CharField('设备名称', max_length=100)
  20. category = models.ForeignKey(Category, on_delete=models.PROTECT, verbose_name='设备分类', related_name='assets')
  21. # 硬件信息
  22. brand = models.CharField('品牌', max_length=200, blank=True, default='')
  23. model = models.CharField('型号', max_length=200, blank=True, default='')
  24. asset_value = models.CharField('资产面值', max_length=50, blank=True, default='')
  25. serial_number = models.CharField('序列号', max_length=200, blank=True, default='', db_index=True)
  26. # 位置信息
  27. location = models.CharField('机房', max_length=200, blank=True, default='', help_text='楼层/房间/区域')
  28. cabinet = models.CharField('机柜', max_length=200, blank=True, default='')
  29. cabinet_position = models.CharField('机柜位置', max_length=200, blank=True, default='', help_text='U位')
  30. # 网络信息
  31. bmc_address = models.CharField('BMC地址', max_length=200, blank=True, default='')
  32. ip_address = models.CharField('IP地址', max_length=200, blank=True, default='')
  33. # 显卡信息
  34. has_gpu = models.CharField('是否带卡', max_length=50, blank=True, default='')
  35. gpu_type = models.CharField('显卡类型', max_length=200, blank=True, default='')
  36. gpu_count = models.CharField('卡数', max_length=50, blank=True, default='')
  37. # 采购与质保
  38. purchase_date = models.CharField('采购日期', max_length=50, blank=True, default='')
  39. warranty_expire = models.CharField('质保到期', max_length=50, blank=True, default='')
  40. supplier = models.CharField('供应商', max_length=200, blank=True, default='')
  41. # 管理信息
  42. responsible_person = models.CharField('负责人', max_length=200, blank=True, default='')
  43. department = models.CharField('使用部门', max_length=200, blank=True, default='')
  44. user = models.CharField('维护人', max_length=200, blank=True, default='')
  45. business_type = models.CharField('业务类型', max_length=200, blank=True, default='')
  46. STATUS_CHOICES = [
  47. ('in_use', '在用'),
  48. ('idle', '闲置'),
  49. ('maintenance', '维修中'),
  50. ('scrapped', '已报废'),
  51. ]
  52. status = models.CharField('状态', max_length=50, choices=STATUS_CHOICES, default='in_use')
  53. remark = models.CharField('备注', max_length=500, blank=True, default='')
  54. # 系统字段
  55. created_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True, verbose_name='创建人')
  56. created_at = models.DateTimeField('创建时间', auto_now_add=True)
  57. updated_at = models.DateTimeField('更新时间', auto_now=True)
  58. class Meta:
  59. verbose_name = '硬件资产'
  60. verbose_name_plural = verbose_name
  61. ordering = ['id']
  62. def __str__(self):
  63. return f'{self.asset_number} - {self.name}'
  64. @property
  65. def is_expired(self):
  66. if self.warranty_expire:
  67. try:
  68. from datetime import datetime
  69. expire_date = datetime.strptime(self.warranty_expire, '%Y-%m-%d').date()
  70. return expire_date < date.today()
  71. except (ValueError, TypeError):
  72. return False
  73. return False
  74. @property
  75. def is_expiring_soon(self):
  76. if self.warranty_expire:
  77. try:
  78. from datetime import datetime, timedelta
  79. expire_date = datetime.strptime(self.warranty_expire, '%Y-%m-%d').date()
  80. return date.today() <= expire_date <= date.today() + timedelta(days=30)
  81. except (ValueError, TypeError):
  82. return False
  83. return False
  84. class AssetChangeLog(models.Model):
  85. """资产变更记录"""
  86. ACTION_CHOICES = [
  87. ('create', '创建'),
  88. ('update', '更新'),
  89. ('delete', '删除'),
  90. ('import', '导入'),
  91. ('export', '导出'),
  92. ('status_change', '状态变更'),
  93. ]
  94. asset = models.ForeignKey(Asset, on_delete=models.SET_NULL, null=True, blank=True,
  95. verbose_name='资产', related_name='change_logs')
  96. asset_number = models.CharField('资产编号', max_length=50, db_index=True)
  97. action = models.CharField('操作类型', max_length=20, choices=ACTION_CHOICES)
  98. field_name = models.CharField('变更字段', max_length=50, blank=True, default='')
  99. old_value = models.TextField('旧值', blank=True, default='')
  100. new_value = models.TextField('新值', blank=True, default='')
  101. description = models.TextField('描述', blank=True, default='')
  102. operator = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True, verbose_name='操作人')
  103. created_at = models.DateTimeField('操作时间', auto_now_add=True)
  104. class Meta:
  105. verbose_name = '变更记录'
  106. verbose_name_plural = verbose_name
  107. ordering = ['-created_at']
  108. def __str__(self):
  109. return f'{self.asset_number} - {self.get_action_display()}'