先展示一下效果
以上为该系统的部分功能
主要使用语言为前端—vue 后端—python flask
先来看一下前端,看到页面大部分熟悉前端vue的同学会很熟悉,对,用的就是element-ui,给不了解的同学贴一下地址element-ui
接下来挑几个代码讲一下吧
这是首页的代码,可以看到直接使用的element-ui的模板来创建,各种目录的划分
<template><div>
<div class="line"></div>
<el-menu
router
:default-active="this.$router.path"
class="el-menu-demo"
mode="horizontal"
@select="handleSelect"
background-color="#545c64"
text-color="#fff"
active-text-color="#ffd04b">
<el-menu-item index="1" disabled>暂无</el-menu-item>
<el-submenu index="2">
<template slot="title">流程查询与CMDB跳转</template>
<el-menu-item index=""> <a href="http://xxx" target="_blank">交易区流程查询跳转</a></el-menu-item>
<el-menu-item index="" text-color="#fff"><a href="http:/xxx" target="_blank" >交易区CMDB跳转</a></el-menu-item>
<el-menu-item index="" disabled></el-menu-item>
<el-submenu index="" disabled>
<!-- 运维信息查询运维信息查询v非交&交tomcat信息查询服务架构图查看-->
<template slot="title">暂无</template>
<el-menu-item index="" disabled>暂无</el-menu-item>
<el-menu-item index="" disabled>暂无</el-menu-item>
<el-menu-item index="" disabled>暂无</el-menu-item>
</el-submenu>
</el-submenu>
<el-submenu index="..">
<template slot="title">事务登记</template>
<el-menu-item index="fbsb" >发布上报</el-menu-item>
<el-menu-item index="gzdj"> 故障登记</el-menu-item>
<el-menu-item index="zyyw" >重要运维事件</el-menu-item>
<el-menu-item index="zbyl" >灾备演练</el-menu-item>
</el-submenu>
<el-menu-item index="test" >交易区VIP查询</el-menu-item>
<el-menu-item index="test2" >非交&交tomcat信息查询</el-menu-item>
<el-menu-item index="jiagou" >服务架构图查看</el-menu-item>
<el-menu-item index="chatgpt" >chatgpt</el-menu-item>
<el-submenu index="">
<template slot="title">服务概览</template>
<el-menu-item index="chriden1"> 条件单&&反手信息查询</el-menu-item>
<el-menu-item index="/test5" >交易区CMDB跳转</el-menu-item>
<el-menu-item index="/test6" disabled></el-menu-item>
</el-submenu>
<el-submenu index=".">
<template slot="title">学习文档下载</template>
<el-menu-item index="/test6"> 复用前置机运维文档下载</el-menu-item>
<el-menu-item index="/test5" >时间服务运维文档下载</el-menu-item>
<el-menu-item index="/test6" disabled></el-menu-item>
</el-submenu>
</el-menu><router-view></router-view>
<!-- <el-carousel :interval="4000" type="card" height="380px">
<el-carousel-item v-for="item in imgList" :key="item.id">
<img :src="item.idView" class="image" style="width:100%">
</el-carousel-item>
</el-carousel> -->
<div id="chartBox" >
<div v-show="showgroup" id="myChart" style="width: 600px;height:400px;"></div>
</div>
</div>
</template>
<style>
.el-carousel__item h3 {
color: #475669;
font-size: 14px;
opacity: 0.75;
line-height: 200px;
margin: 0;
}
.el-carousel__item:nth-child(2n) {
background-color: #99a9bf;
}
.el-carousel__item:nth-child(2n+1) {
background-color: #d3dce6;
}
</style>
<script>
export default {
data() {
return {
activeIndex: '1',
activeIndex2: '1',
showgroup:true,
imgList: [
{id:0,idView:'./static/images/1.jpg'},
{id:1,idView:'./static/images/1.jpg'},
{id:2,idView:'./static/images/1.jpg'},
{id:3,idView:'./static/images/1.jpg'}
]
};
},
methods: {
handleSelect(key, keyPath) {
this.showgroup=false
console.log(key, keyPath);
},
再是发布登记的页面前端
<!-- Table -->
<template><div>
<button @click="downloadFile">下载文件</button>
<el-button type="text" @click="dialogFormVisible = true">新增上报</el-button>
<router-link to="/dashboard2">数据统计</router-link>
<!-- <a id="download" href="javascript:void(0);" @click="download">下载报告</a> -->
<el-dialog title="发布上报" :visible.sync="dialogFormVisible">
<el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm">
<el-form-item label="系统分类" prop="xtflsb">
<el-select v-model="ruleForm.xtflsb" placeholder="请选择系统">
<el-option label="交易组" value="交易组"></el-option>
<el-option label="java组" value="java"></el-option>
<el-option label="h5" value="h5"></el-option>
</el-select>
</el-form-item>
<el-form-item label="发布名称" prop="fwmcsb">
<el-input v-model="ruleForm.fwmcsb"></el-input>
</el-form-item>
<el-form-item label="发布目的" prop="fbmdsb">
<el-input v-model="ruleForm.fbmdsb"></el-input>
</el-form-item>
<el-form-item label="发布ip" prop="ipsb">
<el-input v-model="ruleForm.ipsb"></el-input>
</el-form-item>
<el-form-item label="开发人员" prop="kfrysb">
<el-input v-model="ruleForm.kfrysb"></el-input>
</el-form-item>
<el-form-item label="测试人员" prop="csrysb">
<el-input v-model="ruleForm.csrysb"></el-input>
</el-form-item>
<el-form-item label="运维人员" prop="ywrysb">
<el-input v-model="ruleForm.ywrysb"></el-input>
</el-form-item>
<el-form-item label="发布时间" required>
<el-col :span="11">
<el-form-item prop="fbsjsb">
<el-date-picker type="date" placeholder="选择日期" value-format="yyyy-MM-dd" v-model="ruleForm.fbsjsb" style="width: 100%;"></el-date-picker>
</el-form-item>
</el-col>
<el-col class="line" :span="2">-</el-col>
<!-- <el-col :span="11">
<el-form-item prop="date2">
<el-time-picker placeholder="选择时间" v-model="ruleForm.date2" style="width: 100%;"></el-time-picker>
</el-form-item>
</el-col> -->
</el-form-item>
<el-form-item label="测试结果" prop="csjgsb">
<el-radio-group v-model="ruleForm.csjgsb">
<el-radio label="成功"></el-radio>
<el-radio label="失败"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="发布结果" prop="fbjgsb">
<el-radio-group v-model="ruleForm.fbjgsb">
<el-radio label="一次成功"></el-radio>
<el-radio label="二次成功"></el-radio>
<el-radio label="三次及以上成功"></el-radio>
<el-radio label="失败"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="备注" prop="bzsb">
<el-input type="textarea" v-model="ruleForm.bzsb"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submitForm('ruleForm')">立即创建</el-button>
<el-button @click="resetForm('ruleForm')">重置</el-button>
</el-form-item>
</el-form>
</el-dialog>
<el-table
height=600
:data="tableData.filter(data => !search || data.fwmc.toLowerCase().includes(search.toLowerCase()))"
style="width: 100%"
@cell-click="tabClick"
>
<el-table-column
fixed
sortable
prop="fbsj"
label="日期"
width="150">
<template slot-scope="scope">
<span v-if="scope.row.index === tabClickIndex && tabClickLabel === '日期'">
<el-input v-model="scope.row.fbsj" maxlength="300" placeholder="请输入日期" size="mini" @blur="inputBlur"/>
</span>
<span v-else>{{ scope.row.fbsj }}</span>
</template>
</el-table-column>
<el-table-column
prop="xtfl"
label="系统分类"
width="150">
<template slot-scope="scope">
<span v-if="scope.row.index === tabClickIndex && tabClickLabel === '系统分类'">
<el-input v-model="scope.row.xtfl" maxlength="300" placeholder="请输入系统分类" size="mini" @blur="inputBlur"/>
</span>
<span v-else>{{ scope.row.xtfl }}</span>
</template>
</el-table-column>
<el-table-column
prop="xtfl"
label="标签"
width="100"
:filters="[{ text: '交易组', value: '交易组' }, { text: 'java', value: 'java' }, { text: 'h5', value: 'h5' }]"
:filter-method="filterTag"
filter-placement="bottom-end">
<template slot-scope="scope">
<el-tag
:type="scope.row.xtfl === '交易组' ? 'primary' : 'success'"
disable-transitions>{{scope.row.xtfl}}</el-tag></template>
</el-table-column>
<!-- <el-table-column
prop="xtfl"
label="系统分类"
width="120">
</el-table-column> -->
<el-table-column
:show-overflow-tooltip="true"
prop="fwmc"
label="服务名称"
width="120">
<template slot-scope="scope">
<span v-if="scope.row.index === tabClickIndex && tabClickLabel === '服务名称'">
<el-input v-model="scope.row.fwmc" maxlength="300" placeholder="请输入服务名称" size="mini" @blur="inputBlur"/>
</span>
<span v-else>{{ scope.row.fwmc }}</span>
</template>
</el-table-column>
<el-table-column
prop="fbmd"
label="发布目的"
width="120"
:show-overflow-tooltip="true">
<template slot-scope="scope">
<span v-if="scope.row.index === tabClickIndex && tabClickLabel === '发布目的'">
<el-input v-model="scope.row.fbmd" maxlength="300" placeholder="请输入服发布目的" size="mini" @blur="inputBlur"/>
</span>
<span v-else>{{ scope.row.fbmd }}</span>
</template>
</el-table-column>
<el-table-column
prop="ip"
label="ip"
width="120"
:show-overflow-tooltip="true">
<template slot-scope="scope">
<span v-if="scope.row.index === tabClickIndex && tabClickLabel === 'ip'">
<el-input v-model="scope.row.ip" maxlength="300" placeholder="请输入ip" size="mini" @blur="inputBlur"/>
</span>
<span v-else>{{ scope.row.ip }}</span>
</template>
</el-table-column>
<el-table-column
prop="kfry"
label="开发人员"
width="120">
<template slot-scope="scope">
<span v-if="scope.row.index === tabClickIndex && tabClickLabel === '开发人员'">
<el-input v-model="scope.row.kfry" maxlength="300" placeholder="请输入开发人员" size="mini" @blur="inputBlur"/>
</span>
<span v-else>{{ scope.row.kfry }}</span>
</template>
</el-table-column>
<el-table-column
prop="csry"
label="测试人员"
width="120">
<template slot-scope="scope">
<span v-if="scope.row.index === tabClickIndex && tabClickLabel === '测试人员'">
<el-input v-model="scope.row.csry" maxlength="300" placeholder="请输入测试人员" size="mini" @blur="inputBlur"/>
</span>
<span v-else>{{ scope.row.csry }}</span>
</template>
</el-table-column>
<el-table-column
prop="ywry"
label="运维人员"
width="120">
<template slot-scope="scope">
<span v-if="scope.row.index === tabClickIndex && tabClickLabel === '运维人员'">
<el-input v-model="scope.row.ywry" maxlength="300" placeholder="请输入运维人员" size="mini" @blur="inputBlur"/>
</span>
<span v-else>{{ scope.row.ywry }}</span>
</template>
</el-table-column>
<el-table-column
prop="csjg"
label="测试结果"
width="120">
<template slot-scope="scope">
<span v-if="scope.row.index === tabClickIndex && tabClickLabel === '测试结果'">
<el-input v-model="scope.row.csjg" maxlength="300" placeholder="请输入测试结果" size="mini" @blur="inputBlur"/>
</span>
<span v-else>{{ scope.row.csjg }}</span>
</template>
</el-table-column>
<el-table-column
prop="fbjg"
label="发布结果"
width="120">
<template slot-scope="scope">
<span v-if="scope.row.index === tabClickIndex && tabClickLabel === '发布结果'">
<el-input v-model="scope.row.fbjg" maxlength="300" placeholder="请输入发布结果" size="mini" @blur="inputBlur"/>
</span>
<span v-else>{{ scope.row.fbjg }}</span>
</template>
</el-table-column>
<el-table-column
prop="bz"
label="备注"
width="120">
<template slot-scope="scope">
<span v-if="scope.row.index === tabClickIndex && tabClickLabel === '备注'">
<el-input v-model="scope.row.bz" maxlength="300" placeholder="请输入备注" size="mini" @blur="inputBlur"/>
</span>
<span v-else>{{ scope.row.bz }}</span>
</template>
</el-table-column>
<el-table-column
prop="id"
label="id"
width="120"
v-if="operation1">
</el-table-column>
<el-table-column label="操作">
<template slot="header" slot-scope="scope">
<el-input
v-model="search"
size="mini"
placeholder="输入服务名称关键字搜索"/>
</template>
<!-- <template slot-scope="scope">
<el-button type="text" @click="dialogVisible = true">删除</el-button>
<el-dialog
title="提示"
:visible.sync="dialogVisible"
width="30%" append-to-body
>
<span>是否确定删除</span>
<span slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false">取 消</el-button>
<el-button type="primary" @click="handleDelete(scope.$index, scope.row)">确 定</el-button>
</span>
</el-dialog>
</template> -->
</el-table-column>
</el-table>
<div class="block">
<span class="demonstration">完整功能</span>
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="pageNo"
:page-sizes="[1, 6, 300, 400]"
:page-size="pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total=totalcount>
</el-pagination>
</div>
<!-- Form -->
</div>
</template>
<style lang="css">
.el-tooltip__popper{font-size: 14px; max-width:50% } /*设置显示隐藏部分内容,按50%显示*/
</style>
<script>
import axios from 'axios'
export default {
data() {
return {
totalcount:0,
pageSize:1,
pageNo: 1,
tabClickIndex: null, // 点击的单元格
tabClickLabel: '', // 当前点击的列名
search: '',
centerDialogVisible: false,
dialogVisible: false,
operation1: false,
tableData: [],
ruleForm: {
xtflsb: '',
fwmcsb: '',
fbmdsb: '',
ipsb: '',
kfrysb: '',
csrysb: '',
ywrysb: '',
fbsjsb:'',
csjgsb: '',
fbjgsb: '',
bzsb: ''
},
rules: {
name: [
{ required: true, message: '请输入', trigger: 'blur' },
// { min: 3, max: 5, message: '长度在 3 到 5 个字符', trigger: 'blur' }
],
fwmcsb: [
{ required: true, message: '请输入服务发布名称', trigger: 'blur' },
],
kfrysb: [
{ required: true, message: '请输入开发人员名称', trigger: 'blur' },
],
csrysb: [
{ required: true, message: '请输入测试人员名称', trigger: 'blur' },
],
ywrysb: [
{ required: true, message: '请输入运维人员名称', trigger: 'blur' },
],
xtflsb: [
{ required: true, message: '请选择发布系统', trigger: 'change' }
],
fbmdsb:
[
{ type: 'string', required: true, message: '请输入发布目的', trigger: 'change' }
],
ipsb:
[
{ type: 'string', required: true, message: '请输入发布ip', trigger: 'change' }
],
fbsjsb: [
{ type: 'string', required: true, message: '请选择日期', trigger: 'change' }
],
// date2: [
// { type: 'date', required: true, message: '请选择时间', trigger: 'change' }
// ],
csjgsb: [
{ required: true, message: '请选择测试结果', trigger: 'change' }
],
fbjgsb: [
{ required: true, message: '请选择发布结果', trigger: 'change' }
],
bzsb: [
{ required: false, message: '1', trigger: 'blur' }
]
},
rowidd: '',
currentPage1: 1,
currentPage2: 5,
currentPage3: 5,
currentPage4: 4,
dialogTableVisible: false,
dialogFormVisible: false,
form: {
name: '',
region: '',
date1: '',
date2: '',
delivery: false,
type: [],
resource: '',
desc: ''
},
formLabelWidth: '120px'
};
},
methods: {
tableRowClassName({ row, rowIndex }) {
// 把每一行的索引放进row
row.index = rowIndex
},
handleSizeChange(val) {
console.log(`每页 ${val} 条`);
},
handleCurrentChange(val) {
console.log(`当前页: ${val}`);
}
,
tabClick(row, column, cell, event) {
switch (column.label) {
case '服务名称':
this.tabClickIndex = row.index
this.tabClickLabel = column.label
this.rowidd = row
break
case '发布目的':
this.tabClickIndex = row.index
this.tabClickLabel = column.label
this.rowidd = row
break
case '日期':
this.tabClickIndex = row.index
this.tabClickLabel = column.label
this.rowidd = row
break
case '系统分类':
this.tabClickIndex = row.index
this.tabClickLabel = column.label
this.rowidd = row
break
case 'ip':
this.tabClickIndex = row.index
this.tabClickLabel = column.label
this.rowidd = row
break
case '开发人员':
this.tabClickIndex = row.index
this.tabClickLabel = column.label
this.rowidd = row
break
case '测试人员':
this.tabClickIndex = row.index
this.tabClickLabel = column.label
this.rowidd = row
break
case '运维人员':
this.tabClickIndex = row.index
this.tabClickLabel = column.label
this.rowidd = row
break
case '测试结果':
this.tabClickIndex = row.index
this.tabClickLabel = column.label
this.rowidd = row
break
case '发布结果':
this.tabClickIndex = row.index
this.tabClickLabel = column.label
this.rowidd = row
break
case '备注':
this.tabClickIndex = row.index
this.tabClickLabel = column.label
this.rowidd = row
break
default: return
}
console.log('添加明细原因', row.id,row.fwmc)
},
inputBlur(row, event, column) {
console.log('shiqu', this.rowidd.id,this.rowidd.fwmc)
axios.post('http://xxxx:5000/updatefabu',{
idsb: this.rowidd.id,
xtflsb: this.rowidd.xtfl,
fwmcsb: this.rowidd.fwmc,
fbmdsb: this.rowidd.fbmd,
ipsb: this.rowidd.ip,
kfrysb: this.rowidd.kfry,
csrysb: this.rowidd.csry,
ywrysb: this.rowidd.ywry,
fbsjsb: this.rowidd.fbsj,
csjgsb: this.rowidd.csjg,
fbjgsb: this.rowidd.fbjg,
bzsb: this.rowidd.bz,
},)
.then(res=>{
console.log(row.id);
})
this.tabClickIndex = null
this.tabClickLabel = ''
},
downloadFile() {
const baseUrl = 'http://xxxx:5000/download-file'
const fileName = `filename_${new Date().toLocaleString().replace(/\D/g, '')}.xlsx` // 根据当前时间生成文件名
const url = `${baseUrl}?filename=${fileName}`
const link = document.createElement('a')
link.href = url
link.download = fileName
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
},
download () {
var a = document.createElement('a') // 创建一个<a></a>标签
a.href = 'static\\fbsb.xlsx'
a.download = 'fbsb.xlsx' // 设置下载文件文件名
a.style.display = 'none' // 隐藏a标签
document.body.appendChild(a) // 将a标签追加到文档对象中
a.click() // 模拟点击了a标签,会触发a标签的href的读取,浏览器就会自动下载了
a.remove() // 一次性的,用完就删除a标签
},
filterTag(value, row) {
return row.xtfl === value;
},
filterHandler(value, row, column) {
const property = column['property'];
return row[property] === value;
},
getfabu(){
// console.log(this.input1);
axios.post('http://xxxx:5000/getfabu',{
source: 'this.input1'
})
.then(res=>{
// 将返回的数据显示到demo中
//this.demo = res.data;
//this.showList = [{'池':'123','VIP及服务':'123','节点':'12345','域名':'asdasdasd'}]
this.tableData =res.data.data
// 向控制台打印获取到的数据
console.log(res.data.data);
})
},
handleEdit(index, row) {
console.log(index, row);
},
handleDelete(index, row) {
console.log(index, row);
axios.post('http://xxxx:5000/delfabu',{
id: row.id,
},)
.then(res=>{
// 将返回的数据显示到demo中
//this.demo = res.data;
//this.showList = [{'池':'123','VIP及服务':'123','节点':'12345','域名':'asdasdasd'}]
// this.showList1 =res.data.data
// 向控制台打印获取到的数据
console.log(row.id);
window.location.reload();
})
},
submitForm(formName) {
this.$refs[formName].validate((valid) => {
if (valid) {
// alert('submit!');
console.log(this.ruleForm.ywrysb);
console.log(this.ruleForm.fabu);
console.log(this.ruleForm.fbsjsb);
axios.post('http://xxxx:5000/fabu',{
xtflsb: this.ruleForm.xtflsb,
fwmcsb: this.ruleForm.fwmcsb,
fbmdsb: this.ruleForm.fbmdsb,
ipsb: this.ruleForm.ipsb,
kfrysb: this.ruleForm.kfrysb,
csrysb: this.ruleForm.csrysb,
ywrysb: this.ruleForm.ywrysb,
fbsjsb: this.ruleForm.fbsjsb,
csjgsb: this.ruleForm.csjgsb,
fbjgsb: this.ruleForm.fbjgsb,
bzsb: this.ruleForm.bzsb,
},)
.then(res=>{
// 将返回的数据显示到demo中
//this.demo = res.data;
//this.showList = [{'池':'123','VIP及服务':'123','节点':'12345','域名':'asdasdasd'}]
// this.showList1 =res.data.data
// 向控制台打印获取到的数据
console.log(res.data);
window.location.reload();
})
} else {
console.log('error submit!!');
return false;
}
});
},
resetForm(formName) {
this.$refs[formName].resetFields();
},
gettotal(){
// console.log(this.input1);
axios.post('http://xxxx:5000/gettotal',{
source: 'this.input1'
})
.then(res=>{
// 将返回的数据显示到demo中
//this.demo = res.data;
//this.showList = [{'池':'123','VIP及服务':'123','节点':'12345','域名':'asdasdasd'}]
this.totalcount =res.data.data
// 向控制台打印获取到的数据
console.log(this.totalcount);
})
},
getList(){
let params = new FormData();
params.append("pageNo",this.currentPage1);
params.append("pageSize",this.pageSize);
this.axios.post("http://xxxx:5000/getList",{
pageNo: this.pageNo,
pageSize:this.pageSize
}).then(res=>{
this.tableData = res.data.data;
console.log(this.tableData);
})
},
handleSizeChange(val) { // 修改每页所存数据量的值所触发的函数
this.pageSize = val; // 修改页的大小
this.getList(); // 按新的pageNo和pageSize进行查询
},
handleCurrentChange(val) { // 修改当前页所触发的函数
this.pageNo = val; // 更新当前的页
console.log(this.pageNo)
this.getList(); // 按新的pageNo和pageSize进行查询
}
},
mounted(){
// this.getfabu();
console.log(localStorage.getItem('username'))
this.getList(),
this.gettotal()
},
};
</script>
代码也是直接通过element-ui 的模板来进行的页面创建,这里使用的就是例如table dialog等的一些内容,页面加载时重新向后端发起数据请求来显示页面,数据提交时重新刷新页面获取数据展示。
由于代码比较多,本次第一章主要演示功能部分,具体实现的代码后续再继续展开,有需要源码学习的小伙伴也可以联系哦。