1
0

feat: 新增业务类型、显卡信息字段;优化列表列宽和字符截断;删除是否带卡列

Cette révision appartient à :
cnbugs
2026-04-28 12:51:36 +08:00
Parent f0f802d637
révision bbbec77c63
8 fichiers modifiés avec 188 ajouts et 46 suppressions
+93 -33
Voir le fichier
@@ -8,6 +8,7 @@ from .models import Category
# Excel列定义
EXPORT_COLUMNS = [
('id', 'ID', 8),
('asset_number', '资产编号', 18),
('name', '设备名称', 20),
('category', '设备分类', 12),
@@ -20,12 +21,15 @@ EXPORT_COLUMNS = [
('cabinet_position', '机柜位置', 10),
('bmc_address', 'BMC地址', 16),
('ip_address', 'IP地址', 16),
('gpu_type', '显卡类型', 15),
('gpu_count', '卡数', 6),
('purchase_date', '采购日期', 12),
('warranty_expire', '质保到期', 12),
('supplier', '供应商', 15),
('responsible_person', '负责人', 10),
('department', '使用部门', 15),
('user', '使用人', 10),
('business_type', '业务类型', 15),
('status', '状态', 8),
('remark', '备注', 30),
]
@@ -65,7 +69,9 @@ def export_assets_to_excel(queryset):
# 写数据
for row_idx, asset in enumerate(queryset, 2):
for col_idx, (field, _, _) in enumerate(EXPORT_COLUMNS, 1):
if field == 'category':
if field == 'id':
value = asset.id
elif field == 'category':
value = str(asset.category) if asset.category else ''
elif field == 'status':
value = STATUS_MAP.get(asset.status, asset.status)
@@ -102,9 +108,10 @@ def generate_import_template():
# 示例数据行
example_data = [
'IT-2024-0001', '测试服务器', '服务器', 'Dell', 'PowerEdge R740',
'1', 'IT-2024-0001', '测试服务器', '服务器', 'Dell', 'PowerEdge R740',
'50000.00', 'ABC123456', '3楼机房A区', 'A01', 'U10-U15', '192.168.1.200',
'192.168.1.100', '2024-01-15', '2027-01-15', '戴尔科技', '张三', '研发部', '李四', '在用', '测试备注'
'192.168.1.100', 'NVIDIA A100', '8', '2024-01-15', '2027-01-15', '戴尔科技',
'张三', '研发部', '李四', 'AI训练', '在用', '测试备注'
]
for col_idx, value in enumerate(example_data, 1):
cell = ws.cell(row=2, column=col_idx, value=value)
@@ -193,37 +200,90 @@ def import_assets_from_excel(ws, category_map, operator=None):
except (InvalidOperation, ValueError):
pass
asset = Asset.objects.create(
asset_number=asset_number,
name=data.get('name', ''),
category=category,
brand=data.get('brand', ''),
model=data.get('model', ''),
asset_value=asset_value,
serial_number=data.get('serial_number', ''),
location=data.get('location', ''),
cabinet=data.get('cabinet', ''),
cabinet_position=data.get('cabinet_position', ''),
bmc_address=bmc_address,
ip_address=ip_address,
purchase_date=purchase_date,
warranty_expire=warranty_expire,
supplier=data.get('supplier', ''),
responsible_person=data.get('responsible_person', ''),
department=data.get('department', ''),
user=data.get('user', ''),
status=status,
remark=data.get('remark', ''),
created_by=operator,
)
# 处理ID - 如果提供了ID且已存在,则更新该记录
import_id = data.get('id', '').strip()
asset = None
is_update = False
if import_id:
try:
asset = Asset.objects.get(id=int(import_id))
is_update = True
except (Asset.DoesNotExist, ValueError):
asset = None
AssetChangeLog.objects.create(
asset=asset,
asset_number=asset.asset_number,
action='import',
description=f'通过Excel导入创建',
operator=operator,
)
if asset:
# 更新已有记录
asset.asset_number = asset_number
asset.name = data.get('name', '')
asset.category = category
asset.brand = data.get('brand', '')
asset.model = data.get('model', '')
asset.asset_value = asset_value
asset.serial_number = data.get('serial_number', '')
asset.location = data.get('location', '')
asset.cabinet = data.get('cabinet', '')
asset.cabinet_position = data.get('cabinet_position', '')
asset.bmc_address = bmc_address
asset.ip_address = ip_address
asset.gpu_type = data.get('gpu_type', '')
gpu_count_str = data.get('gpu_count', '').strip()
asset.gpu_count = int(gpu_count_str) if gpu_count_str else None
asset.purchase_date = purchase_date
asset.warranty_expire = warranty_expire
asset.supplier = data.get('supplier', '')
asset.responsible_person = data.get('responsible_person', '')
asset.department = data.get('department', '')
asset.user = data.get('user', '')
asset.business_type = data.get('business_type', '')
asset.status = status
asset.remark = data.get('remark', '')
asset.save()
AssetChangeLog.objects.create(
asset=asset,
asset_number=asset.asset_number,
action='import',
description=f'通过Excel导入更新(ID:{asset.id})',
operator=operator,
)
else:
# 创建新记录
gpu_count_str = data.get('gpu_count', '').strip()
gpu_count = int(gpu_count_str) if gpu_count_str else None
asset = Asset.objects.create(
asset_number=asset_number,
name=data.get('name', ''),
category=category,
brand=data.get('brand', ''),
model=data.get('model', ''),
asset_value=asset_value,
serial_number=data.get('serial_number', ''),
location=data.get('location', ''),
cabinet=data.get('cabinet', ''),
cabinet_position=data.get('cabinet_position', ''),
bmc_address=bmc_address,
ip_address=ip_address,
gpu_type=data.get('gpu_type', ''),
gpu_count=gpu_count,
purchase_date=purchase_date,
warranty_expire=warranty_expire,
supplier=data.get('supplier', ''),
responsible_person=data.get('responsible_person', ''),
department=data.get('department', ''),
user=data.get('user', ''),
business_type=data.get('business_type', ''),
status=status,
remark=data.get('remark', ''),
created_by=operator,
)
AssetChangeLog.objects.create(
asset=asset,
asset_number=asset.asset_number,
action='import',
description=f'通过Excel导入创建',
operator=operator,
)
results['success'] += 1
+2 -1
Voir le fichier
@@ -8,8 +8,9 @@ class AssetForm(forms.ModelForm):
fields = [
'asset_number', 'name', 'category', 'brand', 'model', 'asset_value', 'serial_number',
'location', 'cabinet', 'cabinet_position', 'bmc_address', 'ip_address',
'has_gpu', 'gpu_type', 'gpu_count',
'purchase_date', 'warranty_expire', 'supplier',
'responsible_person', 'department', 'user', 'status', 'remark',
'responsible_person', 'department', 'user', 'business_type', 'status', 'remark',
]
widgets = {
'purchase_date': forms.DateInput(attrs={'type': 'date'}),
+16
Voir le fichier
@@ -0,0 +1,16 @@
# Generated manually to update ordering from ['-created_at'] to ['id']
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('assetapp', '0005_asset_asset_value'),
]
operations = [
migrations.AlterModelOptions(
name='asset',
options={'ordering': ['id'], 'verbose_name': '硬件资产', 'verbose_name_plural': '硬件资产'},
),
]
@@ -0,0 +1,33 @@
# Generated by Django 5.2.13 on 2026-04-28 04:35
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('assetapp', '0006_alter_asset_ordering'),
]
operations = [
migrations.AddField(
model_name='asset',
name='business_type',
field=models.CharField(blank=True, default='', max_length=100, verbose_name='业务类型'),
),
migrations.AddField(
model_name='asset',
name='gpu_count',
field=models.IntegerField(blank=True, null=True, verbose_name='卡数'),
),
migrations.AddField(
model_name='asset',
name='gpu_type',
field=models.CharField(blank=True, default='', max_length=100, verbose_name='显卡类型'),
),
migrations.AddField(
model_name='asset',
name='has_gpu',
field=models.CharField(blank=True, default='', max_length=20, verbose_name='是否带卡'),
),
]
+6
Voir le fichier
@@ -48,6 +48,11 @@ class Asset(models.Model):
bmc_address = models.GenericIPAddressField('BMC地址', blank=True, null=True)
ip_address = models.GenericIPAddressField('IP地址', blank=True, null=True)
# 显卡信息
has_gpu = models.CharField('是否带卡', max_length=20, blank=True, default='')
gpu_type = models.CharField('显卡类型', max_length=100, blank=True, default='')
gpu_count = models.IntegerField('卡数', blank=True, null=True)
# 采购与质保
purchase_date = models.DateField('采购日期', blank=True, null=True)
warranty_expire = models.DateField('质保到期', blank=True, null=True)
@@ -57,6 +62,7 @@ class Asset(models.Model):
responsible_person = models.CharField('负责人', max_length=50, blank=True, default='')
department = models.CharField('使用部门', max_length=100, blank=True, default='')
user = models.CharField('使用人', max_length=50, blank=True, default='')
business_type = models.CharField('业务类型', max_length=100, blank=True, default='')
status = models.CharField('状态', max_length=20, choices=STATUS_CHOICES, default='in_use')
remark = models.TextField('备注', blank=True, default='')