@@ -0,0 +1,54 @@ | |||
import request from '@/utils/request' | |||
// 创建设备报警日志 | |||
export function createEquipmentAlarmLog(data) { | |||
return request({ | |||
url: '/monitoring/equipment-alarm-log/create', | |||
method: 'post', | |||
data: data | |||
}) | |||
} | |||
// 更新设备报警日志 | |||
export function updateEquipmentAlarmLog(data) { | |||
return request({ | |||
url: '/monitoring/equipment-alarm-log/update', | |||
method: 'put', | |||
data: data | |||
}) | |||
} | |||
// 删除设备报警日志 | |||
export function deleteEquipmentAlarmLog(id) { | |||
return request({ | |||
url: '/monitoring/equipment-alarm-log/delete?id=' + id, | |||
method: 'delete' | |||
}) | |||
} | |||
// 获得设备报警日志 | |||
export function getEquipmentAlarmLog(id) { | |||
return request({ | |||
url: '/monitoring/equipment-alarm-log/get?id=' + id, | |||
method: 'get' | |||
}) | |||
} | |||
// 获得设备报警日志分页 | |||
export function getEquipmentAlarmLogPage(query) { | |||
return request({ | |||
url: '/monitoring/equipment-alarm-log/page', | |||
method: 'get', | |||
params: query | |||
}) | |||
} | |||
// 导出设备报警日志 Excel | |||
export function exportEquipmentAlarmLogExcel(query) { | |||
return request({ | |||
url: '/monitoring/equipment-alarm-log/export-excel', | |||
method: 'get', | |||
params: query, | |||
responseType: 'blob' | |||
}) | |||
} |
@@ -0,0 +1,54 @@ | |||
import request from '@/utils/request' | |||
// 创建设备报警实时信息 | |||
export function createEquipmentAlarmRealtime(data) { | |||
return request({ | |||
url: '/monitoring/equipment-alarm-realtime/create', | |||
method: 'post', | |||
data: data | |||
}) | |||
} | |||
// 更新设备报警实时信息 | |||
export function updateEquipmentAlarmRealtime(data) { | |||
return request({ | |||
url: '/monitoring/equipment-alarm-realtime/update', | |||
method: 'put', | |||
data: data | |||
}) | |||
} | |||
// 删除设备报警实时信息 | |||
export function deleteEquipmentAlarmRealtime(id) { | |||
return request({ | |||
url: '/monitoring/equipment-alarm-realtime/delete?id=' + id, | |||
method: 'delete' | |||
}) | |||
} | |||
// 获得设备报警实时信息 | |||
export function getEquipmentAlarmRealtime(id) { | |||
return request({ | |||
url: '/monitoring/equipment-alarm-realtime/get?id=' + id, | |||
method: 'get' | |||
}) | |||
} | |||
// 获得设备报警实时信息分页 | |||
export function getEquipmentAlarmRealtimePage(query) { | |||
return request({ | |||
url: '/monitoring/equipment-alarm-realtime/page', | |||
method: 'get', | |||
params: query | |||
}) | |||
} | |||
// 导出设备报警实时信息 Excel | |||
export function exportEquipmentAlarmRealtimeExcel(query) { | |||
return request({ | |||
url: '/monitoring/equipment-alarm-realtime/export-excel', | |||
method: 'get', | |||
params: query, | |||
responseType: 'blob' | |||
}) | |||
} |
@@ -0,0 +1,89 @@ | |||
<!-- | |||
filename: index.vue | |||
author: liubin | |||
date: 2023-08-29 14:39:40 | |||
description: 状态时序图 | |||
--> | |||
<template> | |||
<div class="sequence-graph"> | |||
<SequenceGraphItem v-for="eq in Object.keys(list)" :key="eq" /> | |||
</div> | |||
</template> | |||
<script> | |||
import SequenceGraphItem from './sequenceGraphItem.vue'; | |||
export default { | |||
name: 'SequenceGraph', | |||
components: { SequenceGraphItem }, | |||
props: { | |||
colors: { | |||
type: Array, | |||
default: () => ['', '', '', '', '', ''], // 默认颜色 | |||
}, | |||
}, | |||
data() { | |||
return { | |||
list: { | |||
打孔机: { | |||
equipmentId: 1, | |||
equipmentName: 'EQ1', | |||
status: '', | |||
startTime: '', | |||
duration: '', | |||
startPos: '', | |||
relativeDuring: '', | |||
}, | |||
磨边机: { | |||
equipmentId: 12, | |||
equipmentName: 'EQ2', | |||
status: '', | |||
startTime: '', | |||
duration: '', | |||
startPos: '', | |||
relativeDuring: '', | |||
}, | |||
清洗机: { | |||
equipmentId: 13, | |||
equipmentName: 'EQ3', | |||
status: '', | |||
startTime: '', | |||
duration: '', | |||
startPos: '', | |||
relativeDuring: '', | |||
}, | |||
窑炉: { | |||
equipmentId: 14, | |||
equipmentName: 'EQ4', | |||
status: '', | |||
startTime: '', | |||
duration: '', | |||
startPos: '', | |||
relativeDuring: '', | |||
}, | |||
AGV: { | |||
equipmentId: 15, | |||
equipmentName: 'EQ5', | |||
status: '', | |||
startTime: '', | |||
duration: '', | |||
startPos: '', | |||
relativeDuring: '', | |||
}, | |||
}, | |||
}; | |||
}, | |||
computed: {}, | |||
methods: {}, | |||
}; | |||
</script> | |||
<style scoped lang="scss"> | |||
.sequence-graph { | |||
padding: 24px; | |||
background: #fff; | |||
border-radius: 6px; | |||
margin: 12px; | |||
box-shadow: 0 0 32px 8px rgba($color: #000000, $alpha: 0.2); | |||
} | |||
</style> |
@@ -0,0 +1,51 @@ | |||
<!-- | |||
filename: sequenceGraphItem.vue | |||
author: liubin | |||
date: 2023-08-29 14:40:51 | |||
description: 时序图最小单元 | |||
--> | |||
<template> | |||
<div class="sequence-graph-item" :style="styles"> | |||
<span v-if="time != null">{{ time }}</span> | |||
</div> | |||
</template> | |||
<script> | |||
export default { | |||
name: 'SequenceGraphItem', | |||
components: {}, | |||
props: { | |||
color: { | |||
type: String, | |||
default: 'black', | |||
}, | |||
time: { | |||
type: String, | |||
default: null | |||
} | |||
}, | |||
computed: { | |||
styles() { | |||
return { | |||
color: this.color | |||
} | |||
} | |||
}, | |||
data() { | |||
return {}; | |||
}, | |||
computed: {}, | |||
methods: {}, | |||
}; | |||
</script> | |||
<style scoped lang="scss"> | |||
.sequence-graph-item { | |||
background: #fff; | |||
padding: 12px; | |||
width: 40px; | |||
height: 32px; | |||
display: inline-block; | |||
} | |||
</style> |
@@ -46,6 +46,8 @@ export default { | |||
.app-main { | |||
/* 84 = navbar + tags-view = 50 + 34 */ | |||
min-height: calc(100vh - 120px - 8px); | |||
display: flex; | |||
flex-direction: column; | |||
} | |||
.fixed-header + .app-main { | |||
@@ -0,0 +1,285 @@ | |||
<template> | |||
<div class="app-container"> | |||
<!-- 搜索工作栏 --> | |||
<SearchBar | |||
:formConfigs="searchBarFormConfig" | |||
ref="search-bar" | |||
@headBtnClick="handleSearchBarBtnClick" /> | |||
<!-- 列表 --> | |||
<base-table | |||
:table-props="tableProps" | |||
:page="queryParams.pageNo" | |||
:limit="queryParams.pageSize" | |||
:table-data="list" | |||
@emitFun="handleEmitFun"> | |||
<method-btn | |||
v-if="tableBtn.length" | |||
slot="handleBtn" | |||
label="操作" | |||
:method-list="tableBtn" | |||
@clickBtn="handleTableBtnClick" /> | |||
</base-table> | |||
<!-- 分页组件 --> | |||
<pagination | |||
v-show="total > 0" | |||
:total="total" | |||
:page.sync="queryParams.pageNo" | |||
:limit.sync="queryParams.pageSize" | |||
@pagination="getList" /> | |||
<!-- 对话框(添加 / 修改) --> | |||
<!-- <base-dialog | |||
:dialogTitle="title" | |||
:dialogVisible="open" | |||
width="500px" | |||
@close="cancel" | |||
@cancel="cancel" | |||
@confirm="submitForm"> | |||
<DialogForm v-if="open" ref="form" :dataForm="form" :rows="rows" /> | |||
</base-dialog> --> | |||
</div> | |||
</template> | |||
<script> | |||
import { | |||
createEquipmentAlarmLog, | |||
updateEquipmentAlarmLog, | |||
deleteEquipmentAlarmLog, | |||
getEquipmentAlarmLog, | |||
getEquipmentAlarmLogPage, | |||
exportEquipmentAlarmLogExcel, | |||
} from '@/api/monitoring/equipmentAlarmLog'; | |||
import Editor from '@/components/Editor'; | |||
import moment from 'moment'; | |||
import basicPageMixin from '@/mixins/lb/basicPageMixin'; | |||
import { getAccessToken } from '@/utils/auth'; | |||
import { publicFormatter } from '@/utils/dict'; | |||
export default { | |||
name: 'EquipmentAlarmLog', | |||
components: { | |||
Editor, | |||
}, | |||
mixins: [basicPageMixin], | |||
data() { | |||
return { | |||
searchBarKeys: ['checkTime'], | |||
tableBtn: [ | |||
this.$auth.hasPermi('base:equipment-alarm-log:update') | |||
? { | |||
type: 'edit', | |||
btnName: '修改', | |||
} | |||
: undefined, | |||
this.$auth.hasPermi('base:equipment-alarm-log:delete') | |||
? { | |||
type: 'delete', | |||
btnName: '删除', | |||
} | |||
: undefined, | |||
].filter((v) => v), | |||
tableProps: [ | |||
{ width: 128, prop: 'productionLine', label: '产线', align: 'center' }, | |||
{ width: 128, prop: 'workshopSection', label: '工段', align: 'center' }, | |||
{ width: 128, prop: 'equipment', label: '设备名称', align: 'center' }, | |||
{ | |||
prop: 'alarmGrade', | |||
label: '报警级别', | |||
align: 'center', | |||
filter: publicFormatter(this.DICT_TYPE.EQU_ALARM_LEVEL), | |||
}, | |||
{ | |||
prop: 'createTime', | |||
label: '报警时间', | |||
width: 180, | |||
filter: (val) => moment(val).format('yyyy-MM-DD HH:mm:ss'), | |||
}, | |||
{ prop: 'alarmContent', label: '报警内容', align: 'center' }, | |||
// { | |||
// _action: 'equipment-group-show-alert', | |||
// label: '报警', | |||
// align: 'center', | |||
// subcomponent: { | |||
// props: ['injectData'], | |||
// render: function (h) { | |||
// const _this = this; | |||
// return h( | |||
// 'el-button', | |||
// { | |||
// props: { type: 'text', size: 'mini' }, | |||
// on: { | |||
// click: function () { | |||
// console.log('inejctdata', _this.injectData); | |||
// _this.$emit('emitData', { | |||
// action: _this.injectData._action, | |||
// // value: _this.injectData.id, | |||
// value: _this.injectData, | |||
// }); | |||
// }, | |||
// }, | |||
// }, | |||
// '查看报警' | |||
// ); | |||
// }, | |||
// }, | |||
// }, | |||
], | |||
searchBarFormConfig: [ | |||
{ | |||
type: 'datePicker', | |||
label: '时间段', | |||
dateType: 'daterange', // datetimerange | |||
// format: 'yyyy-MM-dd HH:mm:ss', | |||
format: 'yyyy-MM-dd', | |||
valueFormat: 'yyyy-MM-dd HH:mm:ss', | |||
rangeSeparator: '-', | |||
startPlaceholder: '开始日期', | |||
endPlaceholder: '结束日期', | |||
defaultTime: ['00:00:00', '23:59:59'], | |||
param: 'createTime', | |||
// width: 350, | |||
}, | |||
{ | |||
type: 'button', | |||
btnName: '查询', | |||
name: 'search', | |||
color: 'primary', | |||
}, | |||
], | |||
// 是否显示弹出层 | |||
open: false, | |||
// 查询参数 | |||
queryParams: { | |||
pageNo: 1, | |||
pageSize: 10, | |||
createTime: [], | |||
}, | |||
// 表单参数 | |||
form: {}, | |||
// 表单校验 | |||
rules: {}, | |||
}; | |||
}, | |||
created() { | |||
this.getList(); | |||
}, | |||
methods: { | |||
/** 重写 basicPageMixin 里的 handleSearchBarBtnClick */ | |||
handleSearchBarBtnClick(btn) { | |||
// 仅查询一种情况 | |||
this.queryParams.createTime = btn.createTime; | |||
this.handleQuery(); | |||
}, | |||
/** 查询列表 */ | |||
getList() { | |||
this.loading = true; | |||
// 执行查询 | |||
getEquipmentAlarmLogPage(this.queryParams).then((response) => { | |||
this.list = response.data.list; | |||
this.total = response.data.total; | |||
this.loading = false; | |||
}); | |||
}, | |||
/** 取消按钮 */ | |||
cancel() { | |||
this.open = false; | |||
this.reset(); | |||
}, | |||
/** 表单重置 */ | |||
reset() { | |||
this.form = { | |||
id: undefined, | |||
alarmId: undefined, | |||
alarmContent: undefined, | |||
alarmValue: undefined, | |||
alarmEquipmentId: undefined, | |||
remark: undefined, | |||
}; | |||
this.resetForm('form'); | |||
}, | |||
/** 搜索按钮操作 */ | |||
handleQuery() { | |||
this.queryParams.pageNo = 1; | |||
this.getList(); | |||
}, | |||
/** 重置按钮操作 */ | |||
resetQuery() { | |||
this.resetForm('queryForm'); | |||
this.handleQuery(); | |||
}, | |||
/** 新增按钮操作 */ | |||
handleAdd() { | |||
this.reset(); | |||
this.open = true; | |||
this.title = '添加设备报警日志'; | |||
}, | |||
/** 修改按钮操作 */ | |||
handleUpdate(row) { | |||
this.reset(); | |||
const id = row.id; | |||
getEquipmentAlarmLog(id).then((response) => { | |||
this.form = response.data; | |||
this.open = true; | |||
this.title = '修改设备报警日志'; | |||
}); | |||
}, | |||
/** 提交按钮 */ | |||
submitForm() { | |||
this.$refs['form'].validate((valid) => { | |||
if (!valid) { | |||
return; | |||
} | |||
// 修改的提交 | |||
if (this.form.id != null) { | |||
updateEquipmentAlarmLog(this.form).then((response) => { | |||
this.$modal.msgSuccess('修改成功'); | |||
this.open = false; | |||
this.getList(); | |||
}); | |||
return; | |||
} | |||
// 添加的提交 | |||
createEquipmentAlarmLog(this.form).then((response) => { | |||
this.$modal.msgSuccess('新增成功'); | |||
this.open = false; | |||
this.getList(); | |||
}); | |||
}); | |||
}, | |||
/** 删除按钮操作 */ | |||
handleDelete(row) { | |||
const id = row.id; | |||
this.$modal | |||
.confirm('是否确认删除设备报警日志编号为"' + id + '"的数据项?') | |||
.then(function () { | |||
return deleteEquipmentAlarmLog(id); | |||
}) | |||
.then(() => { | |||
this.getList(); | |||
this.$modal.msgSuccess('删除成功'); | |||
}) | |||
.catch(() => {}); | |||
}, | |||
/** 导出按钮操作 */ | |||
handleExport() { | |||
// 处理查询参数 | |||
let params = { ...this.queryParams }; | |||
params.pageNo = undefined; | |||
params.pageSize = undefined; | |||
this.$modal | |||
.confirm('是否确认导出所有设备报警日志数据项?') | |||
.then(() => { | |||
this.exportLoading = true; | |||
return exportEquipmentAlarmLogExcel(params); | |||
}) | |||
.then((response) => { | |||
this.$download.excel(response, '设备报警日志.xls'); | |||
this.exportLoading = false; | |||
}) | |||
.catch(() => {}); | |||
}, | |||
}, | |||
}; | |||
</script> |
@@ -0,0 +1,326 @@ | |||
<template> | |||
<div class="app-container"> | |||
<!-- 搜索工作栏 --> | |||
<el-form | |||
:model="queryParams" | |||
ref="queryForm" | |||
size="small" | |||
:inline="true" | |||
v-show="showSearch" | |||
label-width="68px"> | |||
<el-form-item label="创建时间" prop="createTime"> | |||
<el-date-picker | |||
v-model="queryParams.createTime" | |||
style="width: 240px" | |||
value-format="yyyy-MM-dd HH:mm:ss" | |||
type="daterange" | |||
range-separator="-" | |||
start-placeholder="开始日期" | |||
end-placeholder="结束日期" | |||
:default-time="['00:00:00', '23:59:59']" /> | |||
</el-form-item> | |||
<el-form-item> | |||
<el-button type="primary" icon="el-icon-search" @click="handleQuery"> | |||
搜索 | |||
</el-button> | |||
<el-button icon="el-icon-refresh" @click="resetQuery">重置</el-button> | |||
</el-form-item> | |||
</el-form> | |||
<!-- 操作工具栏 --> | |||
<el-row :gutter="10" class="mb8"> | |||
<el-col :span="1.5"> | |||
<el-button | |||
type="primary" | |||
plain | |||
icon="el-icon-plus" | |||
size="mini" | |||
@click="handleAdd" | |||
v-hasPermi="['monitoring:equipment-alarm-realtime:create']"> | |||
新增 | |||
</el-button> | |||
</el-col> | |||
<el-col :span="1.5"> | |||
<el-button | |||
type="warning" | |||
plain | |||
icon="el-icon-download" | |||
size="mini" | |||
@click="handleExport" | |||
:loading="exportLoading" | |||
v-hasPermi="['monitoring:equipment-alarm-realtime:export']"> | |||
导出 | |||
</el-button> | |||
</el-col> | |||
<right-toolbar | |||
:showSearch.sync="showSearch" | |||
@queryTable="getList"></right-toolbar> | |||
</el-row> | |||
<!-- 列表 --> | |||
<el-table v-loading="loading" :data="list"> | |||
<el-table-column label="id" align="center" prop="id" /> | |||
<el-table-column | |||
label="报警信息ID,关联base_equipment_group_alarm表" | |||
align="center" | |||
prop="alarmId" /> | |||
<el-table-column | |||
label="字符型报警编码" | |||
align="center" | |||
prop="alarmContent" /> | |||
<el-table-column label="报警详细描述" align="center" prop="description" /> | |||
<el-table-column | |||
label="报警设备id 关联equipment表" | |||
align="center" | |||
prop="alarmEquipmentId" /> | |||
<el-table-column label="实时报警值" align="center" prop="alarmValue" /> | |||
<el-table-column | |||
label="状态,0 正常 1 报警中" | |||
align="center" | |||
prop="alarmStatus" /> | |||
<el-table-column | |||
label="创建时间" | |||
align="center" | |||
prop="createTime" | |||
width="180"> | |||
<template v-slot="scope"> | |||
<span>{{ parseTime(scope.row.createTime) }}</span> | |||
</template> | |||
</el-table-column> | |||
<el-table-column | |||
label="操作" | |||
align="center" | |||
class-name="small-padding fixed-width"> | |||
<template v-slot="scope"> | |||
<el-button | |||
size="mini" | |||
type="text" | |||
icon="el-icon-edit" | |||
@click="handleUpdate(scope.row)" | |||
v-hasPermi="['monitoring:equipment-alarm-realtime:update']"> | |||
修改 | |||
</el-button> | |||
<el-button | |||
size="mini" | |||
type="text" | |||
icon="el-icon-delete" | |||
@click="handleDelete(scope.row)" | |||
v-hasPermi="['monitoring:equipment-alarm-realtime:delete']"> | |||
删除 | |||
</el-button> | |||
</template> | |||
</el-table-column> | |||
</el-table> | |||
<!-- 分页组件 --> | |||
<pagination | |||
v-show="total > 0" | |||
:total="total" | |||
:page.sync="queryParams.pageNo" | |||
:limit.sync="queryParams.pageSize" | |||
@pagination="getList" /> | |||
<!-- 对话框(添加 / 修改) --> | |||
<el-dialog | |||
:title="title" | |||
:visible.sync="open" | |||
width="500px" | |||
v-dialogDrag | |||
append-to-body> | |||
<el-form ref="form" :model="form" :rules="rules" label-width="80px"> | |||
<el-form-item | |||
label="报警信息ID,关联base_equipment_group_alarm表" | |||
prop="alarmId"> | |||
<el-input | |||
v-model="form.alarmId" | |||
placeholder="请输入报警信息ID,关联base_equipment_group_alarm表" /> | |||
</el-form-item> | |||
<el-form-item label="字符型报警编码"> | |||
<editor v-model="form.alarmContent" :min-height="192" /> | |||
</el-form-item> | |||
<el-form-item label="报警详细描述"> | |||
<editor v-model="form.description" :min-height="192" /> | |||
</el-form-item> | |||
<el-form-item | |||
label="报警设备id 关联equipment表" | |||
prop="alarmEquipmentId"> | |||
<el-input | |||
v-model="form.alarmEquipmentId" | |||
placeholder="请输入报警设备id 关联equipment表" /> | |||
</el-form-item> | |||
<el-form-item label="实时报警值" prop="alarmValue"> | |||
<el-input v-model="form.alarmValue" placeholder="请输入实时报警值" /> | |||
</el-form-item> | |||
<el-form-item label="状态,0 正常 1 报警中" prop="alarmStatus"> | |||
<el-radio-group v-model="form.alarmStatus"> | |||
<el-radio label="1">请选择字典生成</el-radio> | |||
</el-radio-group> | |||
</el-form-item> | |||
</el-form> | |||
<div slot="footer" class="dialog-footer"> | |||
<el-button type="primary" @click="submitForm">确 定</el-button> | |||
<el-button @click="cancel">取 消</el-button> | |||
</div> | |||
</el-dialog> | |||
</div> | |||
</template> | |||
<script> | |||
import { | |||
createEquipmentAlarmRealtime, | |||
updateEquipmentAlarmRealtime, | |||
deleteEquipmentAlarmRealtime, | |||
getEquipmentAlarmRealtime, | |||
getEquipmentAlarmRealtimePage, | |||
exportEquipmentAlarmRealtimeExcel, | |||
} from '@/api/monitoring/equipmentAlarmRealtime'; | |||
import Editor from '@/components/Editor'; | |||
export default { | |||
name: 'EquipmentAlarmRealtime', | |||
components: { | |||
Editor, | |||
}, | |||
data() { | |||
return { | |||
// 遮罩层 | |||
loading: true, | |||
// 导出遮罩层 | |||
exportLoading: false, | |||
// 显示搜索条件 | |||
showSearch: true, | |||
// 总条数 | |||
total: 0, | |||
// 设备报警实时信息列表 | |||
list: [], | |||
// 弹出层标题 | |||
title: '', | |||
// 是否显示弹出层 | |||
open: false, | |||
// 查询参数 | |||
queryParams: { | |||
pageNo: 1, | |||
pageSize: 10, | |||
createTime: [], | |||
}, | |||
// 表单参数 | |||
form: {}, | |||
// 表单校验 | |||
rules: {}, | |||
}; | |||
}, | |||
created() { | |||
this.getList(); | |||
}, | |||
methods: { | |||
/** 查询列表 */ | |||
getList() { | |||
this.loading = true; | |||
// 执行查询 | |||
getEquipmentAlarmRealtimePage(this.queryParams).then((response) => { | |||
this.list = response.data.list; | |||
this.total = response.data.total; | |||
this.loading = false; | |||
}); | |||
}, | |||
/** 取消按钮 */ | |||
cancel() { | |||
this.open = false; | |||
this.reset(); | |||
}, | |||
/** 表单重置 */ | |||
reset() { | |||
this.form = { | |||
id: undefined, | |||
alarmId: undefined, | |||
alarmContent: undefined, | |||
description: undefined, | |||
alarmEquipmentId: undefined, | |||
alarmValue: undefined, | |||
alarmStatus: undefined, | |||
}; | |||
this.resetForm('form'); | |||
}, | |||
/** 搜索按钮操作 */ | |||
handleQuery() { | |||
this.queryParams.pageNo = 1; | |||
this.getList(); | |||
}, | |||
/** 重置按钮操作 */ | |||
resetQuery() { | |||
this.resetForm('queryForm'); | |||
this.handleQuery(); | |||
}, | |||
/** 新增按钮操作 */ | |||
handleAdd() { | |||
this.reset(); | |||
this.open = true; | |||
this.title = '添加设备报警实时信息'; | |||
}, | |||
/** 修改按钮操作 */ | |||
handleUpdate(row) { | |||
this.reset(); | |||
const id = row.id; | |||
getEquipmentAlarmRealtime(id).then((response) => { | |||
this.form = response.data; | |||
this.open = true; | |||
this.title = '修改设备报警实时信息'; | |||
}); | |||
}, | |||
/** 提交按钮 */ | |||
submitForm() { | |||
this.$refs['form'].validate((valid) => { | |||
if (!valid) { | |||
return; | |||
} | |||
// 修改的提交 | |||
if (this.form.id != null) { | |||
updateEquipmentAlarmRealtime(this.form).then((response) => { | |||
this.$modal.msgSuccess('修改成功'); | |||
this.open = false; | |||
this.getList(); | |||
}); | |||
return; | |||
} | |||
// 添加的提交 | |||
createEquipmentAlarmRealtime(this.form).then((response) => { | |||
this.$modal.msgSuccess('新增成功'); | |||
this.open = false; | |||
this.getList(); | |||
}); | |||
}); | |||
}, | |||
/** 删除按钮操作 */ | |||
handleDelete(row) { | |||
const id = row.id; | |||
this.$modal | |||
.confirm('是否确认删除设备报警实时信息编号为"' + id + '"的数据项?') | |||
.then(function () { | |||
return deleteEquipmentAlarmRealtime(id); | |||
}) | |||
.then(() => { | |||
this.getList(); | |||
this.$modal.msgSuccess('删除成功'); | |||
}) | |||
.catch(() => {}); | |||
}, | |||
/** 导出按钮操作 */ | |||
handleExport() { | |||
// 处理查询参数 | |||
let params = { ...this.queryParams }; | |||
params.pageNo = undefined; | |||
params.pageSize = undefined; | |||
this.$modal | |||
.confirm('是否确认导出所有设备报警实时信息数据项?') | |||
.then(() => { | |||
this.exportLoading = true; | |||
return exportEquipmentAlarmRealtimeExcel(params); | |||
}) | |||
.then((response) => { | |||
this.$download.excel(response, '设备报警实时信息.xls'); | |||
this.exportLoading = false; | |||
}) | |||
.catch(() => {}); | |||
}, | |||
}, | |||
}; | |||
</script> |
@@ -0,0 +1,497 @@ | |||
<!-- | |||
filename: index.vue | |||
author: liubin | |||
date: 2023-08-31 09:14:19 | |||
description: 设备全参数查询 | |||
--> | |||
<template> | |||
<div class="app-container full-param-page"> | |||
<SearchBar | |||
:formConfigs="searchBarFormConfig" | |||
ref="search-bar" | |||
@headBtnClick="handleSearchBarBtnClick" /> | |||
<div class="tables"> | |||
<base-table | |||
:key="1 + '__basetable'" | |||
:table-props="table1.tableProps" | |||
:page="1" | |||
:limit="999" | |||
:table-data="table1.data" | |||
@emitFun="(val) => handleEmitFun(table1, val)"></base-table> | |||
<base-table | |||
:key="2 + '__basetable'" | |||
:table-props="table2.tableProps" | |||
:page="1" | |||
:limit="999" | |||
:table-data="table2.data" | |||
@emitFun="(val) => handleEmitFun(table2, val)"></base-table> | |||
<base-table | |||
:key="3 + '__basetable'" | |||
:table-props="table3.tableProps" | |||
:page="1" | |||
:limit="999" | |||
:table-data="table3.data" | |||
@emitFun="(val) => handleEmitFun(table3, val)"></base-table> | |||
<base-table | |||
:key="4 + '__basetable'" | |||
:table-props="table4.tableProps" | |||
:page="1" | |||
:limit="999" | |||
:table-data="table4.data" | |||
@emitFun="(val) => handleEmitFun(table4, val)"></base-table> | |||
<base-table | |||
:key="5 + '__basetable'" | |||
:table-props="table5.tableProps" | |||
:page="1" | |||
:limit="999" | |||
:table-data="table5.data" | |||
@emitFun="(val) => handleEmitFun(table5, val)"></base-table> | |||
<base-table | |||
:key="6 + '__basetable'" | |||
:table-props="table6.tableProps" | |||
:page="1" | |||
:limit="999" | |||
:table-data="table6.data" | |||
@emitFun="(val) => handleEmitFun(table6, val)"></base-table> | |||
<base-table | |||
:key="7 + '__basetable'" | |||
:table-props="table7.tableProps" | |||
:page="1" | |||
:limit="999" | |||
:table-data="table7.data" | |||
@emitFun="(val) => handleEmitFun(table7, val)"></base-table> | |||
</div> | |||
<!-- <div class="tables"> | |||
<div class="table-wrapper" v-for="table in tableList" :key="table.key"> | |||
<div class="table-title">PLC 1</div> | |||
<base-table | |||
:key="table.key + '__basetable'" | |||
:table-props="table.tableProps" | |||
:page="1" | |||
:limit="999" | |||
:table-data="table.data" | |||
@emitFun="(val) => handleEmitFun(table, val)"> | |||
</base-table> | |||
<pagination | |||
v-show="table.total > 0" | |||
:total="table.total" | |||
:page.sync="table.queryParams.pageNo" | |||
:limit.sync="table.queryParams.pageSize" | |||
@pagination="(val) => getListFor(table, val)" /> | |||
</div> | |||
</div> --> | |||
</div> | |||
</template> | |||
<script> | |||
export default { | |||
name: 'EquipmentFullParams', | |||
components: {}, | |||
props: {}, | |||
data() { | |||
const now = new Date(); | |||
const [y, m, d] = [now.getFullYear(), now.getMonth(), now.getDate()]; | |||
const today = new Date(y, m, d, 0, 0, 0, 0).getTime(); | |||
const aWeekAgo = today - 3600 * 1000 * 24 * 7; | |||
return { | |||
tableList: [], | |||
searchBarFormConfig: [ | |||
{ | |||
type: 'input', | |||
label: '设备名称', | |||
placeholder: '请输入设备名称', | |||
param: 'name', | |||
disabled: true, | |||
}, | |||
{ | |||
type: 'input', | |||
label: '设备编码', | |||
placeholder: '请输入设备编码', | |||
param: 'code', | |||
disabled: true, | |||
}, | |||
{ | |||
type: 'datePicker', | |||
label: '时间段', | |||
dateType: 'daterange', // datetimerange | |||
format: 'yyyy-MM-dd HH:mm:ss', | |||
// valueFormat: 'yyyy-MM-dd HH:mm:ss', | |||
valueFormat: 'timestamp', | |||
rangeSeparator: '-', | |||
startPlaceholder: '开始时间', | |||
endPlaceholder: '结束时间', | |||
defaultTime: ['00:00:00', '23:59:59'], | |||
param: 'timeVal', | |||
width: 350, | |||
// defaultSelect: [new Date(aWeekAgo), new Date(today)], | |||
}, | |||
{ | |||
type: 'button', | |||
btnName: '查询', | |||
name: 'search', | |||
color: 'primary', | |||
}, | |||
], | |||
queryParams: { | |||
id: null, | |||
time: [new Date(aWeekAgo), new Date(today)], | |||
}, | |||
table1: { | |||
tableProps: [ | |||
{ | |||
prop: 'time', | |||
label: '时间', | |||
}, | |||
{ | |||
prop: 'plcCode', | |||
label: 'PLC编码', | |||
}, | |||
{ | |||
prop: 'val1', | |||
label: '数值1', | |||
}, | |||
{ | |||
prop: 'bol1', | |||
label: '布尔1', | |||
}, | |||
{ | |||
prop: 'val2', | |||
label: '数值2', | |||
}, | |||
{ | |||
prop: 'bol2', | |||
label: '布尔2', | |||
}, | |||
{ | |||
prop: 'val3', | |||
label: '数值3', | |||
}, | |||
{ | |||
prop: 'bol3', | |||
label: '布尔3', | |||
}, | |||
{ | |||
prop: 'val4', | |||
label: '数值4', | |||
}, | |||
{ | |||
prop: 'bol4', | |||
label: '布尔4', | |||
}, | |||
], | |||
data: [ | |||
{ | |||
time: 1111111111111111, | |||
plcCode: 2, | |||
val1: 3, | |||
bol1: 4, | |||
val2: 5, | |||
bol2: 6, | |||
}, | |||
{ | |||
time: 1, | |||
plcCode: 22222222222222, | |||
val1: 3, | |||
bol1: 4, | |||
val2: 5, | |||
bol2: 6, | |||
}, | |||
{ | |||
time: 1, | |||
plcCode: 2, | |||
val1: 33333333333333, | |||
bol1: 4, | |||
val2: 5, | |||
bol2: 6, | |||
}, | |||
{ | |||
time: 1, | |||
plcCode: 2, | |||
val1: 3, | |||
bol1: 44444444444444, | |||
val2: 5, | |||
bol2: 6, | |||
}, | |||
{ | |||
time: 1, | |||
plcCode: 2, | |||
val1: 3, | |||
bol1: 4, | |||
val2: 5555555555555, | |||
bol2: 6, | |||
}, | |||
{ | |||
time: 1, | |||
plcCode: 2, | |||
val1: 3, | |||
bol1: 4, | |||
val2: 5, | |||
bol2: 6666666666666666666, | |||
}, | |||
{ time: 1, plcCode: 2, val1: 3, bol1: 4, val2: 5, bol2: 6 }, | |||
{ time: 1, plcCode: 2, val1: 3, bol1: 4, val2: 5, bol2: 6 }, | |||
{ time: 1, plcCode: 2, val1: 3, bol1: 4, val2: 5, bol2: 6 }, | |||
{ time: 1, plcCode: 2, val1: 3, bol1: 4, val2: 5, bol2: 6 }, | |||
{ time: 1, plcCode: 2, val1: 3, bol1: 4, val2: 5, bol2: 6 }, | |||
{ time: 1, plcCode: 2, val1: 3, bol1: 4, val2: 5, bol2: 6 }, | |||
{ time: 1, plcCode: 2, val1: 3, bol1: 4, val2: 5, bol2: 6 }, | |||
{ time: 1, plcCode: 2, val1: 3, bol1: 4, val2: 5, bol2: 6 }, | |||
{ time: 1, plcCode: 2, val1: 3, bol1: 4, val2: 5, bol2: 6 }, | |||
{ time: 1, plcCode: 2, val1: 3, bol1: 4, val2: 5, bol2: 6 }, | |||
{ time: 1, plcCode: 2, val1: 3, bol1: 4, val2: 5, bol2: 6 }, | |||
], | |||
}, | |||
table2: { | |||
tableProps: [ | |||
{ | |||
prop: 'time', | |||
label: '时间', | |||
}, | |||
{ | |||
prop: 'plcCode', | |||
label: 'PLC编码', | |||
}, | |||
{ | |||
prop: 'val1', | |||
label: '数值1', | |||
}, | |||
{ | |||
prop: 'bol1', | |||
label: '布尔1', | |||
}, | |||
{ | |||
prop: 'val2', | |||
label: '数值2', | |||
}, | |||
{ | |||
prop: 'bol2', | |||
label: '布尔2', | |||
}, | |||
], | |||
data: [], | |||
}, | |||
table3: { | |||
tableProps: [ | |||
{ | |||
prop: 'time', | |||
label: '时间', | |||
}, | |||
{ | |||
prop: 'plcCode', | |||
label: 'PLC编码', | |||
}, | |||
{ | |||
prop: 'val1', | |||
label: '数值1', | |||
}, | |||
{ | |||
prop: 'bol1', | |||
label: '布尔1', | |||
}, | |||
{ | |||
prop: 'val2', | |||
label: '数值2', | |||
}, | |||
{ | |||
prop: 'bol2', | |||
label: '布尔2', | |||
}, | |||
], | |||
data: [], | |||
}, | |||
table4: { | |||
tableProps: [ | |||
{ | |||
prop: 'time', | |||
label: '时间', | |||
}, | |||
{ | |||
prop: 'plcCode', | |||
label: 'PLC编码', | |||
}, | |||
{ | |||
prop: 'val1', | |||
label: '数值1', | |||
}, | |||
{ | |||
prop: 'bol1', | |||
label: '布尔1', | |||
}, | |||
{ | |||
prop: 'val2', | |||
label: '数值2', | |||
}, | |||
{ | |||
prop: 'bol2', | |||
label: '布尔2', | |||
}, | |||
], | |||
data: [], | |||
}, | |||
table5: { | |||
tableProps: [ | |||
{ | |||
prop: 'time', | |||
label: '时间', | |||
}, | |||
{ | |||
prop: 'plcCode', | |||
label: 'PLC编码', | |||
}, | |||
{ | |||
prop: 'val1', | |||
label: '数值1', | |||
}, | |||
{ | |||
prop: 'bol1', | |||
label: '布尔1', | |||
}, | |||
{ | |||
prop: 'val2', | |||
label: '数值2', | |||
}, | |||
{ | |||
prop: 'bol2', | |||
label: '布尔2', | |||
}, | |||
], | |||
data: [], | |||
}, | |||
table6: { | |||
tableProps: [ | |||
{ | |||
prop: 'time', | |||
label: '时间', | |||
}, | |||
{ | |||
prop: 'plcCode', | |||
label: 'PLC编码', | |||
}, | |||
{ | |||
prop: 'val1', | |||
label: '数值1', | |||
}, | |||
{ | |||
prop: 'bol1', | |||
label: '布尔1', | |||
}, | |||
{ | |||
prop: 'val2', | |||
label: '数值2', | |||
}, | |||
{ | |||
prop: 'bol2', | |||
label: '布尔2', | |||
}, | |||
], | |||
data: [], | |||
}, | |||
table7: { | |||
tableProps: [ | |||
{ | |||
prop: 'time', | |||
label: '时间', | |||
}, | |||
{ | |||
prop: 'plcCode', | |||
label: 'PLC编码', | |||
}, | |||
{ | |||
prop: 'val1', | |||
label: '数值1', | |||
}, | |||
{ | |||
prop: 'bol1', | |||
label: '布尔1', | |||
}, | |||
{ | |||
prop: 'val2', | |||
label: '数值2', | |||
}, | |||
{ | |||
prop: 'bol2', | |||
label: '布尔2', | |||
}, | |||
], | |||
data: [], | |||
}, | |||
}; | |||
}, | |||
computed: { | |||
id() { | |||
return this.$route.params.equipmentId; | |||
}, | |||
code() { | |||
return this.$route.params.equipmentCode; | |||
}, | |||
name() { | |||
return this.$route.params.equipmentName; | |||
}, | |||
}, | |||
mounted() { | |||
if (this.id) this.$set(this.queryParams, 'id', this.id); | |||
if (this.code) | |||
this.$set(this.searchBarFormConfig[0], 'defaultSelect', this.code); | |||
if (this.name) | |||
this.$set(this.searchBarFormConfig[1], 'defaultSelect', this.name); | |||
}, | |||
methods: { | |||
/** 查询 */ | |||
async handleQuery() { | |||
const { data } = this.$axios({ | |||
url: '/monitoring/equipment-monitor/runLog', | |||
method: 'get', | |||
params: this.queryParams, | |||
}); | |||
console.log('data', data); | |||
}, | |||
async handleSearchBarBtnClick({ btnName, timeVal }) { | |||
if (timeVal && timeVal.length > 0) { | |||
this.queryParams.time = timeVal; | |||
} else { | |||
this.queryParams.time = []; | |||
} | |||
await this.handleQuery(); | |||
}, | |||
handleEmitFun(table, val) { | |||
console.log('table val', table, val); | |||
}, | |||
/** 构造 props */ | |||
buildProps() { | |||
this.tableList.forEach((table) => { | |||
this.buildTableProp(table); | |||
}); | |||
}, | |||
/** 构造一个 tableProps - 根据动态结构 */ | |||
buildTableProp(table) {}, | |||
/** 为某个 table 获取 list 数据 */ | |||
getListFor(table, val) { | |||
console.log('get list for', table, val); | |||
}, | |||
}, | |||
}; | |||
</script> | |||
<style scoped> | |||
.full-param-page { | |||
position: relative; | |||
} | |||
.tables { | |||
display: grid; | |||
grid-template-columns: 1fr 1fr; | |||
gap: 18px; | |||
} | |||
.tables >>> .baseTable { | |||
overflow-x: hidden; | |||
} | |||
</style> |
@@ -0,0 +1,69 @@ | |||
<!-- | |||
filename: graph.vue | |||
author: liubin | |||
date: 2023-08-31 14:00:02 | |||
description: | |||
--> | |||
<template> | |||
<div class="chart-wrapper"> | |||
<h4>line graph</h4> | |||
<div class="chart" ref="chart"></div> | |||
</div> | |||
</template> | |||
<script> | |||
import * as echarts from 'echarts'; | |||
export default { | |||
name: 'LineChartInEquipmentProcessAmount', | |||
components: {}, | |||
props: {}, | |||
data() { | |||
return { | |||
chart: null, | |||
option: { | |||
xAxis: { | |||
type: 'category', | |||
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'], | |||
}, | |||
yAxis: { | |||
type: 'value', | |||
}, | |||
series: [ | |||
{ | |||
data: [120, 200, 150, 80, 70, 110, 130], | |||
type: 'bar', | |||
showBackground: true, | |||
backgroundStyle: { | |||
color: 'rgba(180, 180, 180, 0.2)', | |||
}, | |||
}, | |||
], | |||
}, | |||
}; | |||
}, | |||
mounted() { | |||
if (!this.chart) this.chart = echarts.init(this.$refs.chart); | |||
this.chart.setOption(this.option); | |||
}, | |||
beforeDestroy() { | |||
this.chart.dispose(); | |||
}, | |||
methods: {}, | |||
}; | |||
</script> | |||
<style scoped lang="scss"> | |||
.chart-wrapper { | |||
height: 100%; | |||
flex: 1; | |||
background: #f1f1f1; | |||
padding: 12px; | |||
} | |||
.chart { | |||
height: 100%; | |||
width: 100%; | |||
} | |||
</style> |
@@ -0,0 +1,340 @@ | |||
<!-- | |||
filename: index.vue | |||
author: liubin | |||
date: 2023-08-30 14:02:49 | |||
description: 设备加工数量 | |||
--> | |||
<template> | |||
<div style="flex: 1; display: flex; background: #f2f4f9"> | |||
<div | |||
class="app-container" | |||
style="margin-right: 12px; border-radius: 8px; background: #fff"> | |||
<!-- side bar --> | |||
<div | |||
class="side-bar__left" | |||
style="width: 240px; padding: 12px; height: 100%"> | |||
<el-tree | |||
:data="sidebarContent" | |||
:props="treeProps" | |||
@node-click="handleSidebarItemClick" /> | |||
</div> | |||
</div> | |||
<div | |||
class="app-container equipment-process-amount" | |||
style="flex: 1; border-radius: 8px; background: #fff"> | |||
<!-- main area --> | |||
<div class="main-content" style="display: flex; flex-direction: column"> | |||
<SearchBar | |||
:formConfigs="searchBarFormConfig" | |||
ref="search-bar" | |||
@headBtnClick="handleSearchBarBtnClick" /> | |||
<transition appear name="vvv" mode="out-in"> | |||
<base-table | |||
v-if="mode == 'table'" | |||
:table-props="tableProps" | |||
:page="1" | |||
:limit="999" | |||
:table-data="list" | |||
@emitFun="handleEmitFun"> | |||
<!-- <method-btn | |||
v-if="tableBtn.length" | |||
slot="handleBtn" | |||
label="操作" | |||
:method-list="tableBtn" | |||
@clickBtn="handleTableBtnClick" /> --> | |||
</base-table> | |||
<div class="graph" style="height: 56vh;" v-else> | |||
<!-- graph --> | |||
<Graph /> | |||
</div> | |||
</transition> | |||
</div> | |||
</div> | |||
</div> | |||
</template> | |||
<script> | |||
import Graph from './graph.vue'; | |||
export default { | |||
name: 'EquipmentProcessAmount', | |||
components: { Graph }, | |||
props: {}, | |||
data() { | |||
return { | |||
sidebarContent: [ | |||
// { | |||
// id: 'fc1', | |||
// name: '工厂', | |||
// lines: [ | |||
// { | |||
// name: '产线1', | |||
// id: 'pl1', | |||
// sections: [ | |||
// { | |||
// name: '工段1', | |||
// id: 'pl1ws1', | |||
// equipments: [ | |||
// { | |||
// name: '设备1', | |||
// id: 'pl1ws1--eq1', | |||
// }, | |||
// { | |||
// name: '设备2', | |||
// id: 'pl1ws1--eq2', | |||
// }, | |||
// { | |||
// name: '设备3', | |||
// id: 'pl1ws1--eq3', | |||
// }, | |||
// ], | |||
// }, | |||
// { | |||
// name: '工段2', | |||
// id: 'pl1ws2', | |||
// equipments: [ | |||
// { | |||
// name: '设备1', | |||
// id: 'pl2ws1--eq1', | |||
// }, | |||
// { | |||
// name: '设备2', | |||
// id: 'pl2ws1--eq2', | |||
// }, | |||
// { | |||
// name: '设备3', | |||
// id: 'pl2ws1--eq3', | |||
// }, | |||
// ], | |||
// }, | |||
// { | |||
// name: '工段3', | |||
// id: 'pl1ws3', | |||
// equipments: [ | |||
// { | |||
// name: '设备1', | |||
// id: 'pl3ws1--eq1', | |||
// }, | |||
// { | |||
// name: '设备2', | |||
// id: 'pl3ws1--eq2', | |||
// }, | |||
// { | |||
// name: '设备3', | |||
// id: 'pl3ws1--eq3', | |||
// }, | |||
// ], | |||
// }, | |||
// ], | |||
// }, | |||
// { | |||
// name: '产线2', | |||
// id: 'pl2', | |||
// sections: [ | |||
// { | |||
// name: '工段1', | |||
// id: 'pl2ws1', | |||
// }, | |||
// { | |||
// name: '工段2', | |||
// id: 'pl2ws2', | |||
// }, | |||
// { | |||
// name: '工段3', | |||
// id: 'pl2ws3', | |||
// }, | |||
// ], | |||
// }, | |||
// ], | |||
// }, | |||
], | |||
searchBarFormConfig: [ | |||
{ | |||
type: 'datePicker', | |||
label: '时间段', | |||
dateType: 'daterange', // datetimerange | |||
format: 'yyyy-MM-dd', | |||
valueFormat: 'yyyy-MM-dd HH:mm:ss', | |||
rangeSeparator: '-', | |||
startPlaceholder: '开始日期', | |||
endPlaceholder: '结束日期', | |||
defaultTime: ['00:00:00', '23:59:59'], | |||
param: 'timeVal', | |||
width: 350, | |||
}, | |||
{ | |||
type: 'button', | |||
btnName: '查询', | |||
name: 'search', | |||
color: 'primary', | |||
}, | |||
{ | |||
type: 'separate', | |||
}, | |||
{ | |||
type: 'button', | |||
btnName: '表格', | |||
name: 'table', | |||
plain: true, | |||
color: 'success', | |||
}, | |||
{ | |||
type: 'button', | |||
btnName: '图表', | |||
name: 'graph', | |||
plain: true, | |||
color: 'warning', | |||
}, | |||
// { | |||
// type: this.$auth.hasPermi('base:equipment-group:export') ? 'button' : '', | |||
// btnName: '导出', | |||
// name: 'export', | |||
// color: 'warning', | |||
// }, | |||
], | |||
tableProps: [ | |||
{ prop: 'lineName', label: '产线', align: 'center' }, | |||
{ prop: 'sectionName', label: '工段', align: 'center' }, | |||
{ prop: 'externalCode', label: '设备编码', align: 'center' }, | |||
{ prop: 'equipmentName', label: '设备名称', align: 'center' }, | |||
{ prop: 'totalQuantity', label: '加工数量', align: 'center' }, | |||
], | |||
mode: 'table', // table | graph | |||
queryParams: { | |||
// pageNo: 1, | |||
// pageSize: 999, | |||
recordTime: [], | |||
equipmentId: null, | |||
lineId: null, | |||
sectionId: null, | |||
productId: null, | |||
}, | |||
list: [], | |||
treeProps: { | |||
children: 'children', | |||
label: 'label', | |||
}, | |||
}; | |||
}, | |||
mounted() { | |||
this.getTree(); | |||
}, | |||
methods: { | |||
/** build side bar tree */ | |||
buildTree(data) { | |||
data.forEach((factory) => { | |||
this.$set(factory, 'label', factory.name); | |||
this.$set(factory, 'type', '工厂'); | |||
delete factory.name; | |||
factory.children = factory.lines; | |||
delete factory.lines; | |||
factory.children?.forEach((line) => { | |||
this.$set(line, 'label', line.name); | |||
this.$set(line, 'type', '产线'); | |||
delete line.name; | |||
line.children = line.sections; | |||
delete line.sections; | |||
line.children?.forEach((ws) => { | |||
this.$set(ws, 'label', ws.name); | |||
this.$set(ws, 'type', '工段'); | |||
delete ws.name; | |||
ws.children = ws.equipments; | |||
delete ws.equipments; | |||
ws.children?.forEach((eq) => { | |||
this.$set(eq, 'label', eq.name); | |||
this.$set(eq, 'type', '设备'); | |||
delete eq.name; | |||
}); | |||
}); | |||
}); | |||
}); | |||
}, | |||
async getTree() { | |||
const { data } = await this.$axios('/base/factory/getTree'); | |||
this.sidebarContent = data; | |||
this.buildTree(data); | |||
}, | |||
handleSidebarItemClick({ label, id, type }) { | |||
console.log('lable clicked!', label, id, type); | |||
switch (type) { | |||
case '设备': | |||
this.queryParams.equipmentId = id; | |||
break; | |||
case '工段': | |||
this.queryParams.equipmentId = null; | |||
this.queryParams.sectionId = id; | |||
break; | |||
case '产线': | |||
this.queryParams.equipmentId = null; | |||
this.queryParams.sectionId = null; | |||
this.queryParams.lineId = id; | |||
break; | |||
case '工厂': | |||
this.queryParams.equipmentId = null; | |||
this.queryParams.sectionId = null; | |||
this.queryParams.lineId = null; | |||
break; | |||
} | |||
}, | |||
handleEmitFun() {}, | |||
handleSearchBarBtnClick(btn) { | |||
switch (btn.btnName) { | |||
case 'table': | |||
this.mode = 'table'; | |||
break; | |||
case 'graph': | |||
this.mode = 'graph'; | |||
break; | |||
case 'search': | |||
if (btn.timeVal != null && btn.timeVal.length > 0) | |||
this.queryParams.recordTime = btn.timeVal; | |||
else this.queryParams.recordTime = null; | |||
this.handleQuery(); | |||
break; | |||
} | |||
}, | |||
async handleQuery() { | |||
console.log('queryParams', this.queryParams); | |||
const { data } = await this.$axios({ | |||
url: '/monitoring/equipment-monitor/quantity-det-list', | |||
method: 'get', | |||
params: this.queryParams, | |||
}); | |||
this.list = data; | |||
}, | |||
}, | |||
}; | |||
</script> | |||
<style scoped> | |||
.side-bar__left >>> .is-current { | |||
color: #111; | |||
background: #f2f4f7; | |||
} | |||
.vvv-enter, | |||
.vvv-leave-to { | |||
/* transform: translateY(24px) scaleY(0); */ | |||
transform: translateY(24px); | |||
opacity: 0; | |||
} | |||
.vvv-enter-active, | |||
.vvv-leave-active { | |||
transition: all 0.3s ease-out; | |||
} | |||
.vvv-enter-to, | |||
.vvv-leave { | |||
/* transform: translateY(0) scaleY(1); */ | |||
transform: translateY(0); | |||
} | |||
</style> |
@@ -0,0 +1,181 @@ | |||
<!-- | |||
filename: index.vue | |||
author: liubin | |||
date: 2023-08-04 14:44:58 | |||
description: 设备24小时生产记录 | |||
--> | |||
<template> | |||
<div class="app-container"> | |||
<SearchBar | |||
:formConfigs="[{ label: '设备近24小时生产记录', type: 'title' }]" | |||
ref="search-bar" /> | |||
<el-skeleton v-if="initing" :rows="6" animated /> | |||
<base-table | |||
v-else | |||
:span-method="mergeColumnHandler" | |||
:table-props="tableProps" | |||
:table-data="list" | |||
@emitFun="handleEmitFun"></base-table> | |||
<!-- :page="queryParams.pageNo" | |||
:limit="queryParams.pageSize" --> | |||
</div> | |||
</template> | |||
<script> | |||
export default { | |||
name: 'QualityRecentHours', | |||
components: {}, | |||
props: {}, | |||
data() { | |||
return { | |||
initing: false, | |||
queryParams: { | |||
pageNo: 1, | |||
pageSize: 10, | |||
}, | |||
list: [], | |||
tableProps: [], | |||
spanInfo: {}, | |||
}; | |||
}, | |||
computed: {}, | |||
mounted() { | |||
this.getList(); | |||
}, | |||
methods: { | |||
/** 构建tableProps - 依据第一个元素所提供的信息 */ | |||
buildProps(item) { | |||
const { | |||
data: [{ hourData }], | |||
} = item; | |||
const props = [ | |||
{ prop: 'productLine', label: '产线', align: 'center' }, | |||
{ prop: 'specification', label: '规格', align: 'center' }, | |||
{ prop: 'equipmentName', label: '设备', align: 'center' }, | |||
{ prop: 'totalQuantity', label: '生产总数', align: 'center' }, | |||
]; | |||
for (const key of Object.keys(hourData).sort()) { | |||
const subprop = { | |||
label: key, | |||
align: 'center', | |||
children: [ | |||
{ prop: key + '__in', label: '进数据', align: 'center' }, | |||
{ prop: key + '__out', label: '出数据', align: 'center' }, | |||
{ prop: key + '__nok', label: '报废数据', align: 'center' }, | |||
{ | |||
prop: key + '__ratio', | |||
label: '报废率', | |||
align: 'center', | |||
filter: (val) => (val != null ? val + ' %' : '-'), | |||
}, | |||
], | |||
}; | |||
props.push(subprop); | |||
} | |||
this.tableProps = props; | |||
}, | |||
/** 把 list 里的数据转换成 tableProps 对应的格式 */ | |||
convertList(list) { | |||
this.list.splice(0); | |||
let rowIndex = 0; | |||
for (const line of list) { | |||
const { productLine, specification, data } = line; | |||
// 设置span的行数 | |||
this.spanInfo[rowIndex] = data.length; | |||
for (const equipment of data) { | |||
const { equipmentName, totalQuantity } = equipment; | |||
let row = { | |||
productLine, | |||
specification: specification.join('、'), | |||
equipmentName, | |||
totalQuantity, | |||
}; | |||
rowIndex += 1; | |||
for (const [key, hourData] of Object.entries(equipment.hourData)) { | |||
const { inQuantity, outQuantity, nokQuantity, scrapRatio } = | |||
hourData; | |||
row[key + '__in'] = inQuantity; | |||
row[key + '__out'] = outQuantity; | |||
row[key + '__nok'] = nokQuantity; | |||
row[key + '__ratio'] = scrapRatio; | |||
} | |||
this.list.push(row); | |||
} | |||
} | |||
}, | |||
buildData(data) { | |||
this.convertList(data); | |||
}, | |||
/** 合并table列的规则 */ | |||
mergeColumnHandler({ row, column, rowIndex, columnIndex }) { | |||
if (columnIndex == 0 || columnIndex == 1) { | |||
if (this.spanInfo[rowIndex]) { | |||
return [ | |||
this.spanInfo[rowIndex], // row span | |||
1, // col span | |||
]; | |||
} else { | |||
return [0, 0]; | |||
} | |||
} | |||
}, | |||
async getList() { | |||
const { data } = await this.$axios({ | |||
url: '/monitoring/equipment-monitor/recent-24-hours', | |||
method: 'get', | |||
}); | |||
// const data = this.res.data; | |||
// console.log('recent-24', data); | |||
this.initing = true; | |||
this.buildProps(data[0]); | |||
this.buildData(data); | |||
this.queryParams.pageSize = this.list.length; | |||
setTimeout(() => { | |||
this.initing = false; | |||
}, 1000); | |||
}, | |||
handleEmitFun(payload) { | |||
console.log('payload', payload); | |||
}, | |||
}, | |||
}; | |||
</script> | |||
<style scoped lang="scss"> | |||
::-webkit-scrollbar { | |||
display: none; | |||
} | |||
pre { | |||
margin: 10px; | |||
background: #f6f8faf6; | |||
border: 1px solid #e1e4e8; | |||
padding: 12px; | |||
border-radius: 12px; | |||
position: fixed; | |||
// top: 15vh; | |||
top: 10vh; | |||
left: 0; | |||
max-height: 80vh; | |||
overflow-y: auto; | |||
z-index: 100000; | |||
box-shadow: 0 0 32px 12px #0001; | |||
} | |||
code { | |||
font-family: 'IntelOne Mono', 'Ubuntu', 'Courier New', Courier, monospace; | |||
} | |||
</style> |
@@ -0,0 +1,283 @@ | |||
<template> | |||
<div class="app-container"> | |||
<!-- 搜索工作栏 --> | |||
<SearchBar | |||
:formConfigs="searchBarFormConfig" | |||
ref="search-bar" | |||
@headBtnClick="handleSearchBarBtnClick" | |||
@select-changed="handleSearchBarItemChange" /> | |||
<!-- 列表 --> | |||
<base-table | |||
:table-props="tableProps" | |||
:page="queryParams.pageNo" | |||
:limit="queryParams.pageSize" | |||
:table-data="list" | |||
@emitFun="handleEmitFun"> | |||
<method-btn | |||
v-if="tableBtn.length" | |||
slot="handleBtn" | |||
label="操作" | |||
:method-list="tableBtn" | |||
@clickBtn="handleTableBtnClick" /> | |||
</base-table> | |||
<!-- 分页组件 --> | |||
<pagination | |||
v-show="total > 0" | |||
:total="total" | |||
:page.sync="queryParams.pageNo" | |||
:limit.sync="queryParams.pageSize" | |||
@pagination="getList" /> | |||
<!-- 对话框(添加 / 修改) --> | |||
<!-- <base-dialog | |||
:dialogTitle="title" | |||
:dialogVisible="open" | |||
width="500px" | |||
@close="cancel" | |||
@cancel="cancel" | |||
@confirm="submitForm"> | |||
<DialogForm v-if="open" ref="form" :dataForm="form" :rows="rows" /> | |||
</base-dialog> --> | |||
</div> | |||
</template> | |||
<script> | |||
import moment from 'moment'; | |||
import basicPageMixin from '@/mixins/lb/basicPageMixin'; | |||
import { publicFormatter } from '@/utils/dict'; | |||
export default { | |||
name: 'EquipmentStatusAndParams', | |||
mixins: [basicPageMixin], | |||
data() { | |||
return { | |||
searchBarKeys: ['equipmentId', 'productionLineId'], | |||
tableBtn: [ | |||
this.$auth.hasPermi('base:equipment-alarm-log:update') | |||
? { | |||
type: 'edit', | |||
btnName: '修改', | |||
} | |||
: undefined, | |||
this.$auth.hasPermi('base:equipment-alarm-log:delete') | |||
? { | |||
type: 'delete', | |||
btnName: '删除', | |||
} | |||
: undefined, | |||
].filter((v) => v), | |||
tableProps: [ | |||
{ | |||
width: 128, | |||
prop: 'equipmentName', | |||
label: '设备名称', | |||
align: 'center', | |||
}, | |||
{ | |||
width: 128, | |||
prop: 'equipmentCode', | |||
label: '设备编码', | |||
align: 'center', | |||
}, | |||
{ width: 128, prop: 'inQuantity', label: '投入数', align: 'center' }, | |||
{ width: 128, prop: 'outQuantity', label: '产出数', align: 'center' }, | |||
{ | |||
width: 128, | |||
prop: 'run', | |||
label: '是否运行', | |||
align: 'center', | |||
filter: (val) => (val != null ? (val ? '是' : '否') : '-'), | |||
}, | |||
{ | |||
width: 128, | |||
prop: 'status', | |||
label: '状态', | |||
align: 'center', | |||
filter: (val) => | |||
val != null ? ['正常', '计划停机', '故障'][val] : '-', | |||
}, | |||
{ | |||
width: 128, | |||
prop: 'error', | |||
label: '是否故障', | |||
align: 'center', | |||
filter: (val) => (val != null ? (val ? '是' : '否') : '-'), | |||
}, | |||
{ | |||
prop: 'quantityRecordTime', | |||
label: '生产量记录时间', | |||
width: 180, | |||
filter: (val) => moment(val).format('yyyy-MM-DD HH:mm:ss'), | |||
}, | |||
{ | |||
prop: 'statusRecordTime', | |||
label: '状态量记录时间', | |||
width: 180, | |||
filter: (val) => moment(val).format('yyyy-MM-DD HH:mm:ss'), | |||
}, | |||
{ | |||
_action: 'params-monitor', | |||
label: '参数监控', | |||
align: 'center', | |||
subcomponent: { | |||
props: ['injectData'], | |||
render: function (h) { | |||
const _this = this; | |||
return h( | |||
'el-button', | |||
{ | |||
props: { type: 'text', size: 'mini' }, | |||
on: { | |||
click: function () { | |||
console.log('inejctdata', _this.injectData); | |||
_this.$emit('emitData', { | |||
action: _this.injectData._action, | |||
// value: _this.injectData.id, | |||
value: _this.injectData, | |||
}); | |||
}, | |||
}, | |||
}, | |||
'查看监控' | |||
); | |||
}, | |||
}, | |||
}, | |||
], | |||
searchBarFormConfig: [ | |||
// { | |||
// type: 'datePicker', | |||
// label: '时间段', | |||
// dateType: 'daterange', // datetimerange | |||
// // format: 'yyyy-MM-dd HH:mm:ss', | |||
// format: 'yyyy-MM-dd', | |||
// valueFormat: 'yyyy-MM-dd HH:mm:ss', | |||
// rangeSeparator: '-', | |||
// startPlaceholder: '开始日期', | |||
// endPlaceholder: '结束日期', | |||
// defaultTime: ['00:00:00', '23:59:59'], | |||
// param: 'createTime', | |||
// // width: 350, | |||
// }, | |||
{ | |||
type: 'select', | |||
label: '产线', | |||
onchange: true, | |||
placeholder: '请选择产线', | |||
selectOptions: [], | |||
param: 'productionLineId', | |||
}, | |||
{ | |||
type: 'select', | |||
label: '设备', | |||
placeholder: '请选择设备', | |||
param: 'equipmentId', | |||
selectOptions: [], | |||
}, | |||
{ | |||
type: 'button', | |||
btnName: '查询', | |||
name: 'search', | |||
color: 'primary', | |||
}, | |||
], | |||
// 是否显示弹出层 | |||
open: false, | |||
// 查询参数 | |||
queryParams: { | |||
pageNo: 1, | |||
pageSize: 10, | |||
productionLineId: null, | |||
equipmentId: null, | |||
}, | |||
total: 0, | |||
// 表单参数 | |||
form: {}, | |||
// 表单校验 | |||
rules: {}, | |||
}; | |||
}, | |||
created() { | |||
this.getLineList(); | |||
this.getList(); | |||
}, | |||
methods: { | |||
/** 获取产线 */ | |||
async getLineList() { | |||
const { data } = await this.$axios({ | |||
url: '/base/production-line/listAll', | |||
method: 'get', | |||
}); | |||
this.searchBarFormConfig[0].selectOptions = data.map((line) => ({ | |||
name: line.name, | |||
id: line.id, | |||
})); | |||
}, | |||
/** 根据产线获取设备 */ | |||
async getEquipmentList(id) { | |||
const { data } = await this.$axios({ | |||
url: '/base/equipment/listByLine', | |||
method: 'get', | |||
query: { id }, | |||
}); | |||
return data; | |||
}, | |||
/** 监听 search bar 的产线下拉框改变 */ | |||
async handleSearchBarItemChange({ param, value: id }) { | |||
if (param == 'productionLineId') { | |||
if (id == '') { | |||
// 清除设备选框里的选项 | |||
this.searchBarFormConfig[1].selectOptions = []; | |||
return; | |||
} | |||
const list = await this.getEquipmentList(id); | |||
this.searchBarFormConfig[1].selectOptions = list.map((eq) => ({ | |||
name: eq.name, | |||
id: eq.id, | |||
})); | |||
} | |||
}, | |||
handleSearchBarBtnClick(btn) { | |||
const { equipmentId, productionLineId } = btn; | |||
if (equipmentId) this.queryParams.equipmentId = equipmentId; | |||
else this.queryParams.equipmentId = null; | |||
if (productionLineId) | |||
this.queryParams.productionLineId = productionLineId; | |||
else this.queryParams.productionLineId = null; | |||
this.getList(); | |||
}, | |||
/** 查询列表 */ | |||
async getList() { | |||
this.loading = true; | |||
const { data } = await this.$axios({ | |||
url: '/monitoring/equipment-monitor/realtime-page', | |||
method: 'get', | |||
params: this.queryParams, | |||
}); | |||
this.list = data.list; | |||
this.total = data.total; | |||
}, | |||
handleEmitFun({ action, value }) { | |||
if (action == 'params-monitor') { | |||
const { equipmentId, equipmentName, equipmentCode } = value; | |||
this.$router.push({ | |||
name: 'equipmentFullParams', | |||
params: { | |||
equipmentId, | |||
equipmentCode, | |||
equipmentName, | |||
}, | |||
}); | |||
} | |||
}, | |||
}, | |||
}; | |||
</script> |