<template>
|
<div class="autoTest viewWrap">
|
<h2>自动化测试</h2>
|
<ProductList ref="productList"></ProductList>
|
<div class="mainWrap">
|
<div class="leftWrap">
|
<!-- 搜索功能区 -->
|
<div class="wrap">
|
<div class="searchWrap">
|
<div class="searchItem">
|
<span class="searchTitle">产品</span>
|
<el-select v-model="proId" placeholder="请选择" style="width:220px;" @focus="onShowProductList1"
|
ref="productList1">
|
<el-option v-for="(item, index) in selectData" :key="index" :label="`${item.name} / ${item.type}`"
|
:value="item.id">
|
</el-option>
|
</el-select>
|
</div>
|
<div class="searchButton">
|
<el-button type="primary" @click="onGetSearchData">查询</el-button>
|
<el-button @click="onClearSearchData">清空</el-button>
|
<span v-if="!connStatus" class="closed conn">串口通信未连接</span>
|
<span v-if="connStatus" class="connected conn">串口通信已连接</span>
|
</div>
|
</div>
|
</div>
|
<!-- 指令分类及功能区域 -->
|
<div class="tabs">
|
<el-tabs v-model="activeListIndex" type="card" style="margin-top: 20px;">
|
<el-tab-pane label="测试指令" name="1"></el-tab-pane>
|
<el-tab-pane label="设置指令" name="2"></el-tab-pane>
|
</el-tabs>
|
<div class="tabsBtn">
|
<el-button size="mini" @click="handleFormDataAdd"><i class="iconfont icon-zidonghuaceshi"
|
style="font-size: 12px;"></i>
|
新建指令</el-button>
|
<el-button size="mini"><i class="iconfont icon-duilie" style="font-size: 12px;"></i> 全部添加到队列</el-button>
|
</div>
|
</div>
|
<!-- 数据表格区 -->
|
<el-table stripe :data="tableData" height="0">
|
<el-table-column type="index" label="序号"> </el-table-column>
|
<el-table-column prop="name" label="名称" width="120px" show-overflow-tooltip> </el-table-column>
|
<el-table-column prop="value" label="指令" show-overflow-tooltip> </el-table-column>
|
<el-table-column prop="item" label="操作" width="271px">
|
<template slot-scope="scope">
|
<el-button icon="el-icon-edit" type="text" size="mini"
|
@click.native.prevent="handleFormDataEdit(scope.row)">编辑</el-button>
|
<el-button icon="el-icon-delete" type="text" size="mini"
|
@click.native.prevent="handleFormDataDel(scope.row)">删除</el-button>
|
<el-button type="text" size="mini" @click="inputValue = scope.row.value"><i class="iconfont icon-shuru"
|
style="font-size: 12px;"></i>
|
输入</el-button>
|
<el-button type="text" size="mini" :disabled="!connStatus" @click="sendMessage(scope.row.value)"><i
|
class="iconfont icon-fasong" style="font-size: 12px;"></i>
|
发送</el-button>
|
<el-button type="text" size="mini"><i class="iconfont icon-duilie" style="font-size: 12px;"></i>
|
队列</el-button>
|
</template>
|
</el-table-column>
|
</el-table>
|
<!-- 分页组件 -->
|
<el-pagination style="margin-top: 20px;" @size-change="onGetTableData" @current-change="onGetTableData"
|
:current-page.sync="pageCurr" :page-size.sync="pageSize" :page-sizes="[10, 20, 50, 100]"
|
layout="total, sizes, prev, pager, next, jumper" :total="total">
|
</el-pagination>
|
<!-- 表单 -->
|
<el-dialog title="指令详情" :visible.sync="showFromData" width="600px" :before-close="handleFormDataClose">
|
<el-form :model="formData" :rules="formRules" ref="formData" label-width="140px">
|
<el-form-item label="ID" prop="id" style="display: none;">
|
<el-input style="width:320px" v-model="formData.id" disabled></el-input>
|
</el-form-item>
|
<el-form-item label="产品" prop="proId">
|
<el-select v-model="formData.proId" @focus="onShowProductList2" placeholder="请选择" style="width:320px;"
|
clearable ref="productList2">
|
<el-option v-for="(item, index) in selectData" :key="index" :label="`${item.name} / ${item.type}`"
|
:value="item.id">
|
</el-option>
|
</el-select>
|
</el-form-item>
|
<el-form-item label="指令类型" prop="type">
|
<el-radio-group v-model="formData.type">
|
<el-radio label="1">测试指令</el-radio>
|
<el-radio label="2">设置指令</el-radio>
|
</el-radio-group>
|
</el-form-item>
|
<el-form-item label="指令名称" prop="name">
|
<el-input style="width:320px" v-model="formData.name" clearable></el-input>
|
</el-form-item>
|
<el-form-item label="指令内容" prop="value">
|
<el-input style="width:320px" v-model="formData.value" clearable></el-input>
|
</el-form-item>
|
</el-form>
|
<span slot="footer" class="dialog-footer">
|
<el-button @click="handleFormDataClose">取 消</el-button>
|
<el-button type="primary" @click="handleFormDataSubmit">确 定</el-button>
|
</span>
|
</el-dialog>
|
</div>
|
<div class="rightWrap">
|
<!-- 模块标题及功能按钮 -->
|
<div class="title">
|
<span class="titleName">串口通信日志</span>
|
<div style="margin-bottom: 10px;">
|
<el-button size="mini" plain type="success" v-if="!connStatus" @click="setWebSocketConn"><i
|
class="iconfont icon-lianjie" style="font-size: 12px;"></i> 连接串口通信</el-button>
|
<el-button size="mini" plain type="danger" v-if="connStatus" @click="closeWebSocketConn"><i
|
class="iconfont icon-duankai" style="font-size: 12px;"></i> 断开串口通信</el-button>
|
<el-button size="mini" @click="clearMessageList"><i class="iconfont icon-qingkong"
|
style="font-size: 12px;"></i>
|
清空通信记录</el-button>
|
</div>
|
</div>
|
<!-- 消息列表 -->
|
<div class="messages">
|
<div v-for="item, index in messageList" :key="index" :class="`messageItem ${item.type}`">
|
<span class="name" v-if="item.type == 'receive'">接收</span>
|
<span :class="`content ${item.type}`">{{ item.content }}</span>
|
<span class="name" v-if="item.type == 'send'">发送</span>
|
</div>
|
</div>
|
<!-- 输入区域 -->
|
<div class="input">
|
<input v-model="inputValue" placeholder="请输入指令"></input>
|
<button @click="sendInputMessage" :disabled="!connStatus"><i class="iconfont icon-fasong"
|
style="font-size: 12px;"></i> 发送</button>
|
<button @click="inputValue = null" class="clearButton"><i class="iconfont icon-qingkong"
|
style="font-size: 12px;"></i> 清除</button>
|
</div>
|
<!-- 模块标题及功能按钮 -->
|
<div class="title" style="padding-top: 20px;">
|
<span class="titleName">待发送消息队列</span>
|
<div style="margin-bottom: 10px;">
|
<span style="font-size: 12px; font-weight: normal; margin-right: 5px;">指令间隔</span>
|
<el-input-number size="mini" v-model="timeOutNum" style="margin-right: 5px;"></el-input-number>
|
<span style="font-size: 12px; font-weight: normal; margin-right: 20px;">秒</span>
|
<el-button size="mini" :disabled="!connStatus"><i class="iconfont icon-kaishi" style="font-size: 12px;"></i>
|
开始发送</el-button>
|
<el-button size="mini"><i class="iconfont icon-qingkong" style="font-size: 12px;"></i> 清空队列</el-button>
|
<el-button size="mini" v-if="showSendList" @click="showSendList = false"><i class="iconfont icon-zuixiaohua"
|
style="font-size: 12px;"></i> 列表缩小</el-button>
|
<el-button size="mini" v-if="!showSendList" @click="showSendList = true"><i class="iconfont icon-zuidahua"
|
style="font-size: 12px;"></i> 列表展开</el-button>
|
</div>
|
</div>
|
<!-- 队列 -->
|
<div class="sendList" v-show="showSendList"></div>
|
</div>
|
</div>
|
</div>
|
</template>
|
|
<style lang="less" scoped>
|
.autoTest {
|
padding: 20px;
|
|
.mainWrap {
|
height: 100%;
|
display: flex;
|
|
.leftWrap {
|
width: 600px;
|
height: calc(100vh - 187px);
|
display: flex;
|
flex-direction: column;
|
|
.conn {
|
margin-left: 20px;
|
font-weight: 700;
|
}
|
|
.connected {
|
color: #67c23a;
|
}
|
|
.closed {
|
color: #f56c6c;
|
}
|
|
.tabs {
|
position: relative;
|
|
.tabsBtn {
|
position: absolute;
|
right: 0;
|
bottom: 5px;
|
display: flex;
|
align-items: center;
|
}
|
}
|
}
|
|
.rightWrap {
|
margin-left: 20px;
|
flex-grow: 1;
|
background-color: #fff;
|
height: calc(100vh - 187px);
|
display: flex;
|
flex-direction: column;
|
|
.title {
|
height: 32px;
|
line-height: 32px;
|
font-size: 16px;
|
font-weight: 700;
|
color: #333;
|
background-color: #f5f5f5;
|
display: flex;
|
justify-content: space-between;
|
align-items: center;
|
|
.titleName {
|
background-color: #fff;
|
padding: 0 20px;
|
}
|
}
|
|
.messages {
|
flex-grow: 1;
|
height: 0;
|
overflow: auto;
|
|
.messageItem:first-child {
|
margin-top: 10px;
|
}
|
|
.messageItem {
|
display: flex;
|
align-items: flex-start;
|
margin-bottom: 10px;
|
|
.content {
|
min-height: 40px;
|
display: flex;
|
align-items: center;
|
justify-content: center;
|
border-radius: 5px;
|
max-width: 400px;
|
word-break: break-all;
|
overflow: hidden;
|
padding: 10px;
|
box-sizing: border-box;
|
}
|
|
.name {
|
display: inline-block;
|
width: 40px;
|
height: 40px;
|
line-height: 40px;
|
text-align: center;
|
margin: 0 10px;
|
font-size: 12px;
|
color: #fff;
|
border-radius: 5px;
|
background-color: #409eff;
|
}
|
|
.send {
|
background-color: #d0e7ff;
|
}
|
|
.receive {
|
background-color: #eeeeee;
|
}
|
}
|
|
.system {
|
justify-content: center;
|
color: #aaaaaa;
|
font-size: 12px;
|
}
|
|
.send {
|
justify-content: flex-end;
|
}
|
|
.receive {
|
justify-content: flex-start;
|
}
|
}
|
|
.sendList {
|
height: 220px;
|
}
|
|
.input {
|
border-top: 2px solid #f5f5f5;
|
border-bottom: 2px solid #f5f5f5;
|
height: 40px;
|
display: flex;
|
|
input {
|
padding-left: 10px;
|
border: none;
|
outline: none;
|
border-right: 2px solid #f5f5f5;
|
flex-grow: 1;
|
}
|
|
button {
|
width: 80px;
|
border: none;
|
outline: none;
|
background-color: #fff;
|
cursor: pointer;
|
}
|
|
.clearButton {
|
border-left: 2px solid #f5f5f5;
|
}
|
}
|
}
|
}
|
}
|
|
::v-deep .el-tabs__header {
|
margin: 0;
|
}
|
|
::v-deep .el-tabs__nav {
|
border: 0 !important;
|
}
|
|
::v-deep .el-tabs__item.is-active {
|
background-color: #fff !important;
|
border-color: #fff !important;
|
}
|
</style>
|
|
<script>
|
import ProductList from '@/components/ProductList'
|
export default {
|
name: "autoTest",
|
components: { ProductList },
|
data() {
|
return {
|
proId: null,
|
pageSize: 10,
|
pageCurr: 1,
|
total: 0,
|
webSocketConn: null, // 连接对象
|
connStatus: false, // 连接状态
|
tableData: [],
|
showFromData: false,
|
selectData: [],
|
activeListIndex: '1',
|
timeOutNum: 1, // 时间间隔
|
showSendList: true,
|
inputValue: null,
|
showFromData: false,
|
formData: {
|
id: null,
|
proId: null,
|
type: null,
|
name: null,
|
value: null,
|
},
|
formRules: {
|
proId: [{ required: true, message: "必填项", trigger: "blur" }],
|
type: [{ required: true, message: "必填项", trigger: "blur" }],
|
name: [{ required: true, message: "必填项", trigger: "blur" }],
|
value: [{ required: true, message: "必填项", trigger: "blur" }],
|
},
|
messageList: [
|
{
|
type: 'system',
|
content: '1234567890'
|
},
|
{
|
type: 'send',
|
content: '1234567890'
|
},
|
{
|
type: 'receive',
|
content: '1234567890'
|
},
|
],
|
};
|
},
|
computed: {},
|
watch: {
|
proId: function () {
|
this.onGetTableData();
|
},
|
activeListIndex: function () {
|
this.onGetTableData();
|
},
|
},
|
mounted() {
|
this.onGetSelectData()
|
this.onGetTableData()
|
this.setWebSocketConn()
|
},
|
methods: {
|
// 显示产品列表
|
onShowProductList1: function () {
|
this.$refs.productList1.blur()
|
this.$refs.productList.show((res) => {
|
if (!res) return;
|
this.proId = res.id
|
})
|
},
|
// 执行条件查询
|
onGetSearchData: function () {
|
this.pageCurr = 1;
|
this.onGetTableData();
|
},
|
// 清空查询条件
|
onClearSearchData: function () {
|
this.proId = null;
|
this.pageCurr = 1;
|
this.onGetTableData();
|
},
|
// 获取产品数据
|
onGetSelectData: function () {
|
var that = this;
|
that
|
.$axiosAdmin({
|
method: "get",
|
url: "platform/product/all",
|
})
|
.then((res) => {
|
if (res.success == true) {
|
this.selectData = res.content;
|
} else {
|
that.$alert(res.content, "提示", {
|
confirmButtonText: "确定",
|
});
|
}
|
})
|
.catch((err) => {
|
console.log(err);
|
});
|
},
|
// 获取表格数据
|
onGetTableData: function () {
|
var that = this;
|
this.tableData = [];
|
this.total = 0;
|
// if (!this.proId) return;
|
var data = {
|
type: this.activeListIndex,
|
proId: this.proId,
|
pageSize: this.pageSize,
|
pageCurr: this.pageCurr,
|
};
|
that
|
.$axiosAdmin({
|
method: "post",
|
url: "platform/command/some",
|
data: JSON.stringify(data),
|
})
|
.then((res) => {
|
if (res.success == true) {
|
that.tableData = res.content.obj;
|
that.total = res.content.itemTotal;
|
} else {
|
that.$alert(res.content, "提示", {
|
confirmButtonText: "确定",
|
});
|
}
|
})
|
.catch((err) => {
|
console.log(err);
|
});
|
},
|
onShowProductList2: function () {
|
this.$refs.productList2.blur()
|
this.$refs.productList.show((res) => {
|
if (!res) return;
|
this.formData.proId = res.id
|
})
|
},
|
// 添加
|
handleFormDataAdd: function () {
|
this.onGetSelectData();
|
this.formData.id = null;
|
this.formData.proId = this.proId;
|
this.formData.type = this.activeListIndex;
|
this.formData.name = null;
|
this.formData.value = null;
|
this.showFromData = true;
|
},
|
// 关闭
|
handleFormDataClose: function () {
|
this.formData.id = null;
|
this.formData.proId = null;
|
this.formData.type = null;
|
this.formData.name = null;
|
this.formData.value = null;
|
this.showFromData = false;
|
this.$refs['formData'].resetFields();
|
},
|
// 编辑
|
handleFormDataEdit: function (row) {
|
this.onGetSelectData();
|
this.formData.id = row.id;
|
this.formData.proId = row.proId;
|
this.formData.type = row.type + "";
|
this.formData.name = row.name;
|
this.formData.value = row.value;
|
this.showFromData = true;
|
},
|
// 提交数据确认
|
handleFormDataSubmit: function () {
|
this.$confirm(`此操作将保存并更新数据, 是否继续?`, "提示", {
|
confirmButtonText: "确定",
|
cancelButtonText: "取消",
|
type: "warning",
|
})
|
.then(() => {
|
this.onFormDataSubmit();
|
})
|
.catch(() => {
|
this.$message({
|
type: "info",
|
message: "已取消",
|
});
|
});
|
},
|
// 提交数据
|
onFormDataSubmit: function () {
|
var that = this;
|
var url, data;
|
if (this.formData.id) {
|
url = "platform/command/update";
|
data = {
|
id: this.formData.id,
|
proId: this.formData.proId,
|
type: this.formData.type,
|
name: this.formData.name,
|
value: this.formData.value,
|
};
|
} else {
|
url = "platform/command/save";
|
data = {
|
proId: this.formData.proId,
|
type: this.formData.type,
|
name: this.formData.name,
|
value: this.formData.value,
|
};
|
}
|
that
|
.$axiosAdmin({
|
method: "post",
|
url: url,
|
data: JSON.stringify(data),
|
})
|
.then((res) => {
|
if (res.success == true) {
|
that.$message({
|
type: "success",
|
message: "已成功",
|
});
|
that.handleFormDataClose();
|
that.onGetTableData();
|
} else {
|
that.$alert(res.content, "提示", {
|
confirmButtonText: "确定",
|
});
|
}
|
})
|
.catch((err) => {
|
console.log(err);
|
});
|
},
|
// 删除数据确认
|
handleFormDataDel: function (row) {
|
this.$confirm(`此操作将删除数据, 是否继续?`, "提示", {
|
confirmButtonText: "确定",
|
cancelButtonText: "取消",
|
type: "warning",
|
})
|
.then(() => {
|
this.onFormDataDel(row.id);
|
})
|
.catch((err) => {
|
this.$message({
|
type: "info",
|
message: "已取消",
|
});
|
});
|
},
|
// 删除数据
|
onFormDataDel: function (id) {
|
var that = this;
|
that
|
.$axiosAdmin({
|
method: "get",
|
url: `platform/command/delete?id=${id}`,
|
})
|
.then((res) => {
|
if (res.success == true) {
|
that.$message({
|
type: "success",
|
message: "已成功",
|
});
|
that.onGetTableData();
|
} else {
|
that.$alert(res.content, "提示", {
|
confirmButtonText: "确定",
|
});
|
}
|
})
|
.catch((err) => {
|
console.log(err);
|
});
|
},
|
// 创建网串中间件连接
|
setWebSocketConn: function () {
|
var that = this;
|
if ('WebSocket' in window) {
|
this.webSocketConn = new WebSocket('ws://localhost:65532')
|
this.webSocketConn.onopen = function () {
|
that.connStatus = true
|
that.messageList.push({
|
type: 'system',
|
content: '网串中间件已连接'
|
},)
|
}
|
this.webSocketConn.onmessage = function (evt) {
|
that.messageList.push({
|
type: 'receive',
|
content: evt.data
|
},)
|
}
|
this.webSocketConn.onclose = function () {
|
that.connStatus = false
|
that.messageList.push({
|
type: 'system',
|
content: '网串中间件已断开'
|
},)
|
}
|
this.webSocketConn.onerror = function () {
|
that.messageList.push({
|
type: 'system',
|
content: '中间件连接异常'
|
},)
|
}
|
} else {
|
this.$alert('当前浏览器不支持websocket连接', "提示", {
|
confirmButtonText: "确定",
|
});
|
}
|
},
|
// 断开网串中间件连接
|
closeWebSocketConn: function () {
|
this.webSocketConn.close()
|
},
|
// 清空通信记录
|
clearMessageList: function () {
|
this.messageList.splice(0, this.messageList.length)
|
},
|
// 发送指令输入框内容并清空
|
sendInputMessage: function () {
|
var that = this;
|
if (this.inputValue) {
|
this.webSocketConn.send(this.inputValue)
|
this.messageList.push({
|
type: 'send',
|
content: this.inputValue
|
},)
|
this.inputValue = null
|
} else {
|
this.$alert('请输入指令内容', "提示", {
|
confirmButtonText: "确定",
|
})
|
}
|
},
|
// 发送指令
|
sendMessage: function (message) {
|
var that = this;
|
this.webSocketConn.send(message)
|
this.messageList.push({
|
type: 'send',
|
content: message
|
},)
|
},
|
},
|
destroyed() {
|
this.closeWebSocketConn()
|
}
|
};
|
</script>
|