cmdb增加一个功能界面(机房和机型管理)
目录:
介绍
以增删查改主机资产进行展示
后端代码
django增加app
python manage.py startapp inventory
修改setting
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'account',
'inventory',
]
将inventory的url指向inventory
path('inventory/', include('inventory.urls')),
后端代码
涉及到机房,机型和主机
models
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models
# Create your models here.
class Tags(models.Model):
# 标签
tag = models.CharField(max_length=100, unique=True, null=False)
class Idc(models.Model):
# 机房
name = models.CharField(max_length=50)
# 代码
code = models.CharField(max_length=20, unique=True)
# 地址
location = models.CharField(max_length=150)
class Meta:
permissions = (
("view_idc", ("查看机房")),
("add_idc", ("添加机房")),
("change_idc", ("编辑机房")),
("delete_idc", ("删除机房")),
)
default_permissions = ()
def __str__(self):
return '%s(%s)' % (self.name, self.code)
class Specification(models.Model):
# 机房
idc = models.ForeignKey(Idc, on_delete=models.PROTECT)
# 机型
name = models.CharField(max_length=100)
# cpu单位核数
cpu = models.IntegerField()
# 内存单位G
mem = models.IntegerField()
class Meta:
unique_together = (("idc", "name"),)
permissions = (
("view_specification", ("查看类型")),
("add_specification", ("添加类型")),
("change_specification", ("编辑类型")),
("delete_specification", ("删除类型")),
)
default_permissions = ()
def __str__(self):
return '%s %s' % (str(self.idc), self.name)
class Storage(models.Model):
media_choices = (
(0, 'SSD'),
(1, 'HDD'),
)
# n对1 主机
machine = models.ForeignKey('Machine', on_delete=models.CASCADE)
# 介质
media = models.IntegerField(choices=media_choices)
# 大小
volume = models.IntegerField()
class Meta:
permissions = ()
default_permissions = ()
def __str__(self):
return '%s : %d GB' % (self.get_media_display(), self.volume)
class Machine(models.Model):
# 主机名
hostname = models.CharField(max_length=50)
# 主机型号
specification = models.ForeignKey('Specification', null=True, on_delete=models.PROTECT)
# ip
ip = models.GenericIPAddressField(null=False)
# 主机标签
tags = models.ManyToManyField(Tags)
# 创建时间
created = models.DateTimeField(auto_now_add=True)
# 修改时间
last_modified = models.DateTimeField(auto_now=True)
class Meta:
permissions = (
("view_machine", ("查看服务器")),
("add_machine", ("添加服务器")),
("change_machine", ("编辑服务器")),
("delete_machine", ("删除服务器")),
("connect_machine", ("连接服务器")),
)
default_permissions = ()
url
from django.urls import path
from inventory import views
urlpatterns = [
# 根据条件查找主机
path('machineFilterOptions/', views.machine_filter_options),
# 添加主机
path('machineAdd/', views.machine_add),
# 修改主机 machineAdd和machineChange都是调用了machine_edit用于编辑和创建主机
path('machineChange/<int:id>/', views.machine_change),
path('getMachines/', views.get_machines),
# 添加主机 get方法用于获取需要添加主机的其他信息
path('addMachine/', views.add_machine),
# 修改主机 get方法用于获取需要修改主机的信息
path('changeMachine/', views.change_machine),
path('deleteMachine/', views.delete_machine),
path('getIdcs/', views.get_idcs),
path('addIdc/', views.add_idc),
path('changeIdc/', views.change_idc),
path('deleteIdc/', views.delete_idc),
path('getSpecifications/', views.get_specifications),
path('addSpecification/', views.add_specification),
path('changeSpecification/', views.change_specification),
path('deleteSpecification/', views.delete_specification),
]
view
# -*- coding: utf-8 -*-
from django.contrib.auth.decorators import login_required, permission_required
from inventory import machine, idc, specification
@login_required
@permission_required('inventory.view_machine', raise_exception=True)
def machine_filter_options(request):
return machine.machine_filter_options(request)
@login_required
@permission_required('inventory.add_machine', raise_exception=True)
def machine_add(request):
return machine.machine_edit(request, None)
@login_required
@permission_required('inventory.change_machine', raise_exception=True)
def machine_change(request, id):
return machine.machine_edit(request, id)
@login_required
@permission_required('inventory.view_machine', raise_exception=True)
def get_machines(request):
return machine.get_machines(request)
@login_required
@permission_required('inventory.add_machine', raise_exception=True)
def add_machine(request):
return machine.add_machine(request)
@login_required
@permission_required('inventory.change_machine', raise_exception=True)
def change_machine(request):
return machine.change_machine(request)
@login_required
@permission_required('inventory.delete_machine', raise_exception=True)
def delete_machine(request):
return machine.delete_machine(request)
@login_required
@permission_required('inventory.view_idc', raise_exception=True)
def get_idcs(request):
return idc.get_idcs(request)
@login_required
@permission_required('inventory.add_idc', raise_exception=True)
def add_idc(request):
return idc.add_idc(request)
@login_required
@permission_required('inventory.change_idc', raise_exception=True)
def change_idc(request):
return idc.change_idc(request)
@login_required
@permission_required('inventory.delete_idc', raise_exception=True)
def delete_idc(request):
return idc.delete_idc(request)
@login_required
@permission_required('inventory.view_specification', raise_exception=True)
def get_specifications(request):
return specification.get_specifications(request)
@login_required
@permission_required('inventory.add_specification', raise_exception=True)
def add_specification(request):
return specification.add_specification(request)
@login_required
@permission_required('inventory.change_specification', raise_exception=True)
def change_specification(request):
return specification.change_specification(request)
@login_required
@permission_required('inventory.delete_specification', raise_exception=True)
def delete_specification(request):
return specification.delete_specification(request)
json序列化时间
python的json.dumps()序列化默认只支持以下类型
python | Json |
---|---|
dict | object |
list, tuple | array |
str | string |
int, float | number |
True | true |
False | false |
None | null |
如果需要支持其他的类型
from datetime import datetime, date
import json
# 用于json格式化data和datatime类型
class DateEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, datetime):
return obj.strftime('%Y-%m-%d %H:%M:%S')
if isinstance(obj, date):
return obj.strftime('%Y-%m-%d')
return json.JSONEncoder.default(self, obj)
在json.dumps()的时候加上cls=DateEncoder的参数即可
idc
from django.http import HttpResponse, HttpResponseBadRequest
from django.db import transaction
from django.db.models import Q
from inventory.models import Idc
import json
def get_idcs(request):
search = request.GET.get('search')
order_by = request.GET.get('orderBy')
order = request.GET.get('order')
size = int(request.GET.get('size'))
page = int(request.GET.get('page'))
idcs = Idc.objects
if search:
idcs = idcs.filter(Q(name__icontains=search) | Q(code__icontains=search) | Q(location__icontains=search))
if order_by and order:
if order == 'ascending':
idcs = idcs.order_by(order_by)
if order == 'descending':
idcs = idcs.order_by('-' + order_by)
else:
idcs = idcs.order_by('id')
start = (page - 1) * size
end = size * page
total = idcs.count()
idcs = idcs[start : end].values('id', 'name', 'code', 'location')
return HttpResponse(json.dumps({'tableData': list(idcs), 'total': total}))
def add_idc(request):
idc_data = json.loads(request.body.decode())
name = idc_data.get('name')
code = idc_data.get('code')
location = idc_data.get('location')
idc, status = Idc.objects.get_or_create(code=code, defaults={
'name': name, 'location': location})
if status:
return HttpResponse(status=201)
else:
return HttpResponseBadRequest()
def change_idc(request):
idc_data = json.loads(request.body.decode())
id = idc_data.get('id')
name = idc_data.get('name')
code = idc_data.get('code')
location = idc_data.get('location')
count = Idc.objects.filter(id=id).update(name=name, code=code, location=location)
if count > 0:
return HttpResponse(status=202)
else:
return HttpResponseBadRequest()
@transaction.atomic
def delete_idc(request):
id_list = json.loads(request.body.decode()).get('idList')
print(id_list)
result = Idc.objects.filter(id__in=id_list).delete()
if result[0] > 0:
return HttpResponse(status=204)
else:
return HttpResponseBadRequest()
specification
from django.http import HttpResponse, HttpResponseBadRequest
from django.db import transaction
from django.db.models import F
from django.db.models import Q
from inventory.models import Idc, Specification
import json
def get_specifications(request):
search = request.GET.get('search')
order_by = request.GET.get('orderBy')
order = request.GET.get('order')
size = int(request.GET.get('size'))
page = int(request.GET.get('page'))
specifications = Specification.objects.annotate(idcId=F('idc__id'), idcName=F('idc__name'), idcCode=F('idc__code'))
if search:
specifications = specifications.filter( Q(idc__name__icontains=search) | Q(idc__code__icontains=search))
if order_by and order:
if order == 'ascending':
specifications = specifications.order_by(order_by)
if order == 'descending':
specifications = specifications.order_by('-' + order_by)
else:
specifications = specifications.order_by('id')
start = (page - 1) * size
end = size * page
total = specifications.count()
specifications = specifications[start : end].values('id', 'idcId', 'idcName', 'idcCode', 'name', 'cpu', 'mem')
idc_options = list(Idc.objects.all().values('id', 'name', 'code'))
return HttpResponse(json.dumps({'idcOptions': idc_options,'tableData': list(specifications),
'total': total}))
def add_specification(request):
specification_data = json.loads(request.body.decode())
name = specification_data.get('name')
cpu = specification_data.get('cpu')
mem = specification_data.get('mem')
idc_id = specification_data.get('idc')
specification, status = Specification.objects.get_or_create(idc=Idc.objects.get(id=idc_id), name=name, cpu=cpu, mem=mem)
if status:
return HttpResponse(status=201)
else:
return HttpResponseBadRequest()
def change_specification(request):
specification_data = json.loads(request.body.decode())
id = specification_data.get('id')
idc = specification_data.get('idc')
name = specification_data.get('name')
cpu = specification_data.get('cpu')
mem = specification_data.get('mem')
count = Specification.objects.filter(id=id).update(idc=idc, name=name, cpu=cpu, mem=mem)
if count > 0:
return HttpResponse(status=202)
else:
return HttpResponseBadRequest()
@transaction.atomic
def delete_specification(request):
id_list = json.loads(request.body.decode()).get('idList')
result = Specification.objects.filter(id__in=id_list).delete()
if result[0] > 0:
return HttpResponse(status=204)
else:
return HttpResponseBadRequest()
同步数据库
python manage.py makemigrations
python manage.py migrate
前端
添加路由
src/store.js的path增加页面和权限对应关系
在main中会判断这些组件是否存在对应的权限,在请求url或者在显示的时候也会进行判断
const state = {
...
paths: {
...,
'MachineAdd': 'inventory.add_machine',
'MachineChange': 'inventory.change_machine',
'MachineManagement': 'inventory.view_machine',
'IdcManagement': 'inventory.view_idc',
'SpecificationManagement': 'inventory.view_specification'
},
src/components/Navigation.vue增加对应的跳转按钮
<el-menu>
...
<el-submenu index="inventory">
<template slot="title">
<i class="fas fa-sitemap fa-lg"></i>
<span slot="title">资产管理</span>
</template>
<el-submenu index="machine">
<span slot="title"><i class="fas fa-server fa-lg"></i> 机器</span>
<el-menu-item index="/machineAdd">
<i class="fas fa-plus-circle fa-lg"></i>
<span slot="title">添加服务器</span>
</el-menu-item>
<el-menu-item index="/machineManagement">
<i class="fas fa-list-alt fa-lg"></i>
<span slot="title">服务器管理</span>
</el-menu-item>
</el-submenu>
<el-submenu index="idc">
<span slot="title"><i class="fas fa-building fa-lg"></i> 机房</span>
<el-menu-item index="/idcManagement">
<i class="fas fa-cubes fa-lg"></i>
<span slot="title">机房管理</span>
</el-menu-item>
<el-menu-item index="/specificationManagement">
<i class="fas fa-cube fa-lg"></i>
<span slot="title">机架位管理</span>
</el-menu-item>
</el-submenu>
</el-submenu>
</el-menu>
src/router/index.js添加router关系
...
import MachineManagement from '@/components/MachineManagement'
import MachineEdit from '@/components/MachineEdit'
import IdcManagement from '@/components/IdcManagement'
import SpecificationManagement from '@/components/SpecificationManagement'
...
export default new Router({
mode: 'history',
routes: [
...,
{
path: '/machineManagement',
name: 'MachineManagement',
component: MachineManagement
},
{
path: '/machineAdd',
name: 'MachineAdd',
component: MachineEdit
},
{
path: '/machineChange/:id',
name: 'MachineChange',
component: MachineEdit
},
{
path: '/idcManagement',
name: 'IdcManagement',
component: IdcManagement
},
{
path: 'specificationManagement',
name: 'SpecificationManagement',
component: SpecificationManagement
}
]
})
package.json更新依赖
{
...
"dependencies": {
...,
"file-saver": "^1.3.8",
},
...
}
更新了依赖需要npm install
src/components/添加新的组件
IdcManagement管理idc组件
src/components/IdcManagement.vue
通过changemode参数控制一个编辑页面,可以用来编译和添加
<template>
<div>
<div class="div-header">
<el-row>
<el-col :span="3">
<el-button type="primary" size="mini" icon="el-icon-plus"
:disabled="$store.state.permissions.indexOf('inventory.add_idc') < 0"
@click="handleAdd">
添加机房
</el-button>
</el-col>
<el-col :span="3">
<el-badge :value="multipleSelection.length"
:hidden="$store.state.permissions.indexOf('inventory.delete_idc') < 0 ||
!multipleSelection.length > 0"
:max="100" class="item">
<el-button type="danger" size="mini" icon="el-icon-delete"
:disabled="$store.state.permissions.indexOf('inventory.delete_idc') < 0 ||
!multipleSelection.length > 0" @click="deleteMutiple">
批量删除
</el-button>
</el-badge>
</el-col>
<el-col :offset="13" :span="4">
<el-input placeholder="请输入搜索内容" clearable size="mini" suffix-icon="el-icon-search"
v-model="search" @input="handleSearch">
</el-input>
</el-col>
</el-row>
</div>
<el-table stripe border :data="tableData" style="width: 100%" v-loading="loading" element-loading-text="拼命加载中" @selection-change="handleSelectionChange"
@sort-change="sortChange">
<el-table-column type="selection"></el-table-column>
<el-table-column prop="id" sortable="custom" label="ID"></el-table-column>
<el-table-column prop="name" sortable="custom" label="IDC名称"></el-table-column>
<el-table-column prop="code" sortable="custom" label="IDC代码"></el-table-column>
<el-table-column prop="location" sortable="custom" label="地址"></el-table-column>
<el-table-column label="操作" width="210">
<template slot-scope="scope">
<el-button size="mini" icon="el-icon-edit"
:disabled="$store.state.permissions.indexOf('inventory.change_idc') < 0"
@click="handleEdit(scope.$index, scope.row)">
编辑
</el-button>
<el-button size="mini" icon="el-icon-delete" type="danger"
:disabled="$store.state.permissions.indexOf('inventory.delete_idc') < 0"
@click="handleDelete(scope.$index, scope.row)">
删除
</el-button>
</template>
</el-table-column>
</el-table>
<idcEdit :title="title" :idcFormVisible.sync="idcFormVisible"
:changeMode="changeMode" :idcForm="idcForm" @reloadTable="reloadTable">
</idcEdit>
<pagination :total="total" :pageSizes="[20, 50, 100]" :pageSize.sync="size"
:currentPage.sync="page" @reloadTable="reloadTable">
</pagination>
</div>
</template>
<script>
import idcEdit from '@/components/IdcEdit.vue';
import pagination from '@/components/Pagination.vue';
export default {
components: {
'idcEdit': idcEdit,
'pagination': pagination
},
data: function () {
return {
loading: false,
multipleSelection: [],
tableData: [],
total: 0,
title: '',
idcFormVisible: false,
changeMode: false,
idcForm: {
id: '',
name: '',
code: '',
location: ''
},
size: 20,
page: 1,
search: '',
orderBy: '',
order: '',
};
},
methods: {
handleSelectionChange: function (val) {
this.multipleSelection = val;
},
reloadTable: function () {
var _this = this;
var url = '/api/inventory/getIdcs/' + '?search=' + this.search + '&orderBy=' + this.orderBy + '&order=' + this.order + '&size=' + this.size + '&page=' + this.page;
this.loading = true;
this.$http.get(url).then(function (response) {
_this.tableData = response.data.tableData;
_this.total = response.data.total;
_this.loading = false;
}).catch(function (error) {
_this.$message.error('获取NIC列表失败');
_this.loading = false;
});
},
handleSearch: function () {
setTimeout(this.reloadTable, 500);
},
handleEdit: function (index, row) {
this.idcForm.id = row.id;
this.idcForm.name = row.name;
this.idcForm.code = row.code;
this.idcForm.location = row.location;
this.title = '编辑IDC信息';
this.changeMode = true;
this.idcFormVisible = true;
},
handleDelete: function (index, row) {
var idList = [row.id];
this.deleteSubmit(idList);
},
deleteMutiple: function () {
var idList = []
this.multipleSelection.forEach(v => {idList.push(v.id)});
this.deleteSubmit(idList);
},
handleAdd: function () {
this.title = '添加IDC信息';
this.idcForm.name = '';
this.idcForm.code = '';
this.idcForm.location = '';
this.changeMode = false;
this.idcFormVisible = true;
},
deleteSubmit: function (idList) {
var _this = this;
this.$confirm('删除IDC信息: [' + idList.toString() + '], 是否继续?', '确认', {
confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning'}).then(() => {
this.$http.post('/api/inventory/deleteIdc/', {'idList': idList}).then(
function (response) {
_this.$notify({ title: '成功', message: '删除IDC信息成功', type: 'success'});
_this.reloadTable();
}
).catch(function (error) {
if (error.response.status === 403) {
_this.$message.warning('没有权限操作');
} else {
_this.$message.error('删除IDC信息失败');
}
}
);
}).catch(() => {
this.$message({type: 'info', message: '已取消删除'});
});
},
sortChange: function (sort) {
this.orderBy = sort.prop;
this.order = sort.order;
this.reloadTable();
}
},
mounted: function () {
this.reloadTable();
}
}
</script>
IdcEdit编辑idc
src/components/IdcEdit.vue
使用el-dialog用于弹出
<template>
<el-dialog :title="title" :visible="idcFormVisible" @close="handleClose">
<el-form label-position="left" status-icon ref="idcForm" :model="idcForm" :rules="rules"
label-width="100px">
<el-form-item v-if="changeMode" label="ID" prop="id">
<el-input :disabled="changeMode" v-model="idcForm.id"></el-input>
</el-form-item>
<el-form-item label="IDC名称" prop="name">
<el-input v-model.trim="idcForm.name"></el-input>
</el-form-item>
<el-form-item label="IDC代码" prop="code">
<el-input v-model.trim="idcForm.code">
</el-input>
</el-form-item>
<el-form-item label="地址" prop="location">
<el-input v-model.trim="idcForm.location">
</el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="handleClose">取消</el-button>
<el-button type="primary" @click="saveSubmit('idcForm')">保存</el-button>
</div>
</el-dialog>
</template>
<script>
export default {
props: ['title', 'idcFormVisible', 'changeMode', 'idcForm'],
data: function () {
return {
rules: {
name: [
{ required: true, message: '请输入IDC名称', trigger: 'blur' },
{ max: 50, message: '长度不得超过50个字符', trigger: 'blur' }
],
code: [
{ required: true, message: '请输入IDC代码', trigger: 'blur' },
{ max: 20, message: '长度不得超过20个字符', trigger: 'blur' }
],
location: [
{ max: 150, message: '长度不得超过150个字符', trigger: 'blur' }
]
}
}
},
methods: {
saveSubmit: function (formName) {
var _this = this;
this.$refs[formName].validate((valid) => {
if (valid) {
var url = '';
this.changeMode ? url = '/api/inventory/changeIdc/' : url = '/api/inventory/addIdc/';
this.$http.post(url, this.idcForm).then(function (response) {
_this.$notify({ title: '成功', message: '保存IDC信息成功', type: 'success'});
_this.handleClose();
_this.$emit('reloadTable');
}).catch(function (error) {
if (error.response.status === 403) {
_this.$message.warning('没有权限操作');
} else {
_this.$message.error('保存IDC信息失败');
}
});
} else {
_this.$message.error('未通过表单验证');
return false;
}
});
},
handleClose: function () {
this.$emit('update:idcFormVisible', false);
}
}
}
</script>
SpecificationManagement管理界面
src/components/SpecificationManagement.vue
<template>
<div>
<div class="div-header">
<el-row>
<el-col :span="3">
<el-button type="primary" size="mini" icon="el-icon-plus"
:disabled="$store.state.permissions.indexOf('inventory.add_specification') < 0"
@click="handleAdd">
添加机型
</el-button>
</el-col>
<el-col :span="3">
<el-badge :value="multipleSelection.length"
:hidden="$store.state.permissions.indexOf('inventory.delete_specification') < 0 ||
!multipleSelection.length > 0"
:max="100" class="item">
<el-button type="danger" size="mini" icon="el-icon-delete"
:disabled="$store.state.permissions.indexOf('inventory.delete_specification') < 0 ||
!multipleSelection.length > 0" @click="deleteMutiple">
批量删除
</el-button>
</el-badge>
</el-col>
<el-col :offset="13" :span="4">
<el-input placeholder="请输入搜索内容" clearable size="mini" suffix-icon="el-icon-search" v-model="search" @input="handleSearch">
</el-input>
</el-col>
</el-row>
</div>
<el-table stripe border :data="tableData" style="width: 100%" v-loading="loading" element-loading-text="拼命加载中" @selection-change="handleSelectionChange" @sort-change="sortChange">
<el-table-column type="selection"></el-table-column>
<el-table-column prop="id" sortable="custom" label="ID"></el-table-column>
<el-table-column prop="idcName" sortable="custom" label="IDC" :formatter="formatter"></el-table-column>
<el-table-column prop="name" sortable="custom" label="机型"></el-table-column>
<el-table-column prop="cpu" sortable="custom" label="CPU核数"></el-table-column>
<el-table-column prop="mem" sortable="custom" label="内存大小"></el-table-column>
<el-table-column label="操作" width="210">
<template slot-scope="scope">
<el-button size="mini" icon="el-icon-edit"
:disabled="$store.state.permissions.indexOf('inventory.change_specification') < 0"
@click="handleEdit(scope.$index, scope.row)">
编辑
</el-button>
<el-button size="mini" icon="el-icon-delete" type="danger"
:disabled="$store.state.permissions.indexOf('inventory.delete_specification') < 0"
@click="handleDelete(scope.$index, scope.row)">
删除
</el-button>
</template>
</el-table-column>
</el-table>
<specificationEdit :title="title" :specificationFormVisible.sync="specificationFormVisible"
:changeMode="changeMode" :idcOptions="idcOptions" :specificationForm="specificationForm"
@reloadTable="reloadTable">
</specificationEdit>
<pagination :total="total" :pageSizes="[20, 50, 100]" :pageSize.sync="size"
:currentPage.sync="page" @reloadTable="reloadTable">
</pagination>
</div>
</template>
<script>
import specificationEdit from '@/components/SpecificationEdit.vue';
import pagination from '@/components/Pagination.vue';
export default {
components: {
'specificationEdit': specificationEdit,
'pagination': pagination
},
data: function () {
return {
loading: false,
multipleSelection: [],
tableData: [],
total: 0,
specificationFormVisible: false,
changeMode: false,
title: '',
idcOptions: [],
specificationForm: {
id: '',
idc: '',
name: '',
cpu: '',
mem: ''
},
size: 20,
page: 1,
search: '',
orderBy: '',
order: ''
};
},
methods: {
handleSelectionChange: function (val) {
this.multipleSelection = val;
},
formatter: function (row, column) {
return row.idcName + '(' + row.idcCode + ')';
},
reloadTable: function () {
var _this = this;
var url = '/api/inventory/getSpecifications/' + '?search=' + this.search + '&orderBy=' + this.orderBy + '&order=' + this.order + '&size=' + this.size + '&page=' + this.page;
this.loading = true;
this.$http.get(url).then(function (response) {
_this.idcOptions = response.data.idcOptions;
_this.tableData = response.data.tableData;
_this.total = response.data.total;
_this.loading = false;
}).catch(function (error) {
_this.$message.error('获取机型列表失败');
_this.loading = false;
});
},
handleSearch: function () {
setTimeout(this.reloadTable, 500);
},
handleEdit: function (index, row) {
this.specificationForm.id = row.id;
this.specificationForm.idc = row.idcId;
this.specificationForm.name = row.name;
this.specificationForm.cpu = row.cpu;
this.specificationForm.mem = row.mem;
this.title = '编辑机型信息';
this.changeMode = true;
this.specificationFormVisible = true;
},
handleDelete: function (index, row) {
var idList = [row.id];
this.deleteSubmit(idList);
},
deleteMutiple: function () {
var idList = []
this.multipleSelection.forEach(v => {idList.push(v.id)});
this.deleteSubmit(idList);
},
handleAdd: function () {
this.title = '添加机型信息';
this.changeMode = false;
this.specificationForm.idc = '';
this.specificationForm.name = '';
this.specificationForm.cpu = '';
this.specificationForm.mem = '';
this.specificationFormVisible = true;
},
deleteSubmit: function (idList) {
var _this = this;
this.$confirm('删除机型信息: [' + idList.toString() + '], 是否继续?', '确认', {
confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning'}).then(() => {
this.$http.post('/api/inventory/deleteSpecification/', {'idList': idList}).then(
function (response) {
_this.$notify({ title: '成功', message: '删除机型信息成功', type: 'success'});
_this.reloadTable();
}
).catch(function (error) {
if (error.response.status === 403) {
_this.$message.warning('没有权限操作');
} else {
_this.$message.error('删除机型信息失败');
}
}
);
}).catch(() => {
this.$message({type: 'info', message: '已取消删除'});
});
},
sortChange: function (sort) {
this.orderBy = sort.prop;
this.order = sort.order;
this.reloadTable();
}
},
mounted: function () {
this.reloadTable();
}
}
</script>
SpecificationEdit机型编辑
<template>
<el-dialog :title="title" :visible="specificationFormVisible" @close="handleClose">
<el-form label-position="left" status-icon ref="specificationForm" :model="specificationForm" :rules="rules"
label-width="100px">
<el-form-item v-if="changeMode" label="ID" prop="id">
<el-input :disabled="changeMode" v-model="specificationForm.id"></el-input>
</el-form-item>
<el-form-item label="IDC" prop="idc">
<el-select v-model="specificationForm.idc" placeholder="请选择IDC">
<el-option v-for="(item, index) in idcOptions" :key="index"
:label="item.name+'('+item.code+')'" :value="item.id">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="机型" prop="name">
<el-input v-model.trim="specificationForm.name"></el-input>
</el-form-item>
<el-form-item label="CPU数量" prop="cpu">
<el-input v-model.trim="specificationForm.cpu"></el-input>
</el-form-item>
<el-form-item label="内存大小" prop="mem">
<el-input v-model.trim="specificationForm.mem"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="handleClose">取消</el-button>
<el-button type="primary" @click="saveSubmit('specificationForm')">保存</el-button>
</div>
</el-dialog>
</template>
<script>
export default {
props: ['title', 'specificationFormVisible', 'changeMode', 'specificationForm', 'idcOptions'],
data: function () {
return {
rules: {
idc: [
{ required: true, message: '请选择IDC', trigger: 'change' }
],
name: [
{ required: true, message: '请输入机型名称', trigger: 'blur' },
{max: 100, message: '长度不得超过100个字符', trigger: 'blur'}
],
cpu: [
{ required: true, message: '请输入CPU核数', trigger: 'blur' }
],
mem: [
{ required: true, message: '请输入内存大小', trigger: 'blur' }
]
}
}
},
methods: {
saveSubmit: function (formName) {
var _this = this;
this.$refs[formName].validate((valid) => {
if (valid) {
var url = '';
this.changeMode ? url = '/api/inventory/changeSpecification/' : url = '/api/inventory/addSpecification/';
this.$http.post(url, this.specificationForm).then(function (response) {
_this.$notify({ title: '成功', message: '保存机型信息成功', type: 'success'});
_this.handleClose();
_this.$emit('reloadTable');
}).catch(function (error) {
if (error.response.status === 403) {
_this.$message.warning('没有权限操作');
} else {
_this.$message.error('保存机型信息失败');
}
});
} else {
_this.$message.error('未通过表单验证');
return false;
}
});
},
handleClose: function () {
this.$emit('update:specificationFormVisible', false);
}
}
}
</script>
<style scoped>
.el-select {
width: 100%;
}
</style>
测试
机房管理界面
机型管理界面