@@ -0,0 +1,12 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<svg width="16px" height="16px" viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> | |||
<title>选择</title> | |||
<g id="设备管理" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> | |||
<g id="设备监控-设备加工数量" transform="translate(-496.000000, -187.000000)" fill-rule="nonzero"> | |||
<g id="选择" transform="translate(496.000000, 187.000000)"> | |||
<rect id="矩形" fill="#000000" opacity="0" x="0" y="0" width="16" height="16"></rect> | |||
<path d="M13.8735116,4.65950813 C13.6725171,4.47101195 13.3555167,4.48001613 13.1670206,4.6815213 L6.49899208,11.7809972 L2.85649778,8.19199033 C2.65950812,7.99798414 2.34299153,8 2.14898534,8.19698966 C1.95497916,8.3934955 1.95747883,8.71049591 2.15449536,8.90399141 L6.16199434,12.8519823 C6.16349952,12.8534874 6.1654885,12.8539712 6.16699367,12.8554764 C6.16849884,12.8569816 6.16898266,12.8589706 6.17048783,12.8604757 C6.20198897,12.8904717 6.23999461,12.9074856 6.27649508,12.9274829 C6.29450341,12.9379922 6.3099852,12.953474 6.32898802,12.960973 C6.38798547,12.9839807 6.45047706,12.9959683 6.51248486,12.9959683 C6.57798681,12.9959683 6.64348875,12.9829593 6.70447519,12.9569682 C6.72498319,12.9484747 6.74097566,12.930977 6.75997848,12.919957 C6.79747344,12.8979438 6.83647358,12.8794517 6.86848541,12.8469561 C6.86999058,12.8454509 6.87047439,12.8429512 6.87197956,12.841446 C6.87297405,12.8399409 6.87498991,12.8394571 6.8764682,12.8379519 L13.8949604,5.36594544 C14.0849886,5.16548852 14.0745061,4.8489988 13.8735116,4.65950813 Z" id="路径" fill="#0B58FF"></path> | |||
</g> | |||
</g> | |||
</g> | |||
</svg> |
@@ -0,0 +1,14 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<svg width="16px" height="16px" viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> | |||
<title>菜单</title> | |||
<g id="设备管理" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> | |||
<g id="设备监控-设备加工数量" transform="translate(-284.000000, -164.000000)" fill-rule="nonzero"> | |||
<g id="编组-7" transform="translate(284.000000, 162.000000)"> | |||
<g id="菜单" transform="translate(0.000000, 2.000000)"> | |||
<rect id="矩形" fill="#000000" opacity="0" x="0" y="0" width="16" height="16"></rect> | |||
<path d="M3.00057813,4.49926562 L13.0025156,4.49926562 C13.2786563,4.49926562 13.5025156,4.27540625 13.5025156,3.99926563 C13.5025156,3.723125 13.2786563,3.49926563 13.0025156,3.49926563 L3.00057813,3.49926563 C2.7244375,3.49926563 2.50057813,3.723125 2.50057813,3.99926563 C2.50057813,4.27540625 2.7244375,4.49926562 3.00057813,4.49926562 Z M3.0004375,8.48703125 L12.9786875,8.48703125 C13.2548281,8.48703125 13.4786875,8.26317187 13.4786875,7.98703125 C13.4786875,7.71089062 13.2548281,7.48703125 12.9786875,7.48703125 L3.0004375,7.48703125 C2.72429687,7.48703125 2.5004375,7.71089062 2.5004375,7.98703125 C2.5004375,8.26317187 2.72429687,8.48703125 3.0004375,8.48703125 Z M13.0025156,11.4969063 L3.00057813,11.4969063 C2.7244375,11.4969063 2.50057813,11.7207656 2.50057813,11.9969063 C2.50057813,12.2730469 2.7244375,12.4969063 3.00057813,12.4969063 L13.0025156,12.4969063 C13.2786563,12.4969063 13.5025156,12.2730469 13.5025156,11.9969063 C13.5025156,11.7207656 13.2786563,11.4969063 13.0025156,11.4969063 L13.0025156,11.4969063 Z" id="形状" fill="#373738"></path> | |||
</g> | |||
</g> | |||
</g> | |||
</g> | |||
</svg> |
@@ -32,7 +32,7 @@ export default { | |||
min-height: calc(100vh - 56px); | |||
min-width: calc(100vh - 280px); | |||
position: relative; | |||
overflow: hidden; | |||
overflow: visible; | |||
margin: 8px 14px 0px 16px; | |||
border-radius: 8px; | |||
background-color: #fff; | |||
@@ -0,0 +1,531 @@ | |||
<!-- | |||
filename: EquipmentDrawer.vue | |||
author: liubin | |||
date: 2023-08-22 14:38:56 | |||
description: | |||
--> | |||
<template> | |||
<el-drawer | |||
:visible="visible" | |||
:show-close="false" | |||
:wrapper-closable="false" | |||
class="drawer" | |||
custom-class="mes-drawer" | |||
size="60%" | |||
@closed="$emit('destroy')"> | |||
<SmallTitle slot="title"> | |||
{{ | |||
mode.includes('detail') | |||
? '详情' | |||
: mode.includes('edit') | |||
? '编辑' | |||
: '新增' | |||
}} | |||
</SmallTitle> | |||
<div class="drawer-body flex"> | |||
<div class="drawer-body__content"> | |||
<section v-for="(section, index) in sections" :key="section.key"> | |||
<SmallTitle v-if="index != 0">{{ section.name }}</SmallTitle> | |||
<div class="form-part" v-if="section.key == 'base'"> | |||
<el-skeleton v-if="!showForm" animated /> | |||
<BaseInfoForm | |||
key="drawer-dialog-form" | |||
v-if="showForm" | |||
ref="form" | |||
:disabled="mode.includes('detail')" | |||
:dataForm="form" | |||
:rows="formRows" /> | |||
</div> | |||
<div v-if="section.key == 'attrs'" style="margin-top: 12px"> | |||
<base-table | |||
v-loading="attrListLoading" | |||
:table-props="section.props" | |||
:page="attrQuery?.params.pageNo || 1" | |||
:limit="attrQuery?.params.pageSize || 10" | |||
:table-data="list" | |||
:add-button-show="mode.includes('detail') ? null : '添加属性'" | |||
@emitButtonClick="handleAddAttr" | |||
@emitFun="handleEmitFun"> | |||
<method-btn | |||
v-if="section.tableBtn" | |||
slot="handleBtn" | |||
label="操作" | |||
:method-list="tableBtn" | |||
@clickBtn="handleTableBtnClick" /> | |||
</base-table> | |||
<!-- 分页组件 --> | |||
<pagination | |||
v-show="total > 0" | |||
:total="total" | |||
:page.sync="attrQuery.params.pageNo" | |||
:limit.sync="attrQuery.params.pageSize" | |||
@pagination="getAttrList" /> | |||
</div> | |||
</section> | |||
</div> | |||
<div class="drawer-body__footer"> | |||
<el-button style="" @click="handleCancel">取消</el-button> | |||
<el-button v-if="mode == 'detail'" type="primary" @click="toggleEdit"> | |||
编辑 | |||
</el-button> | |||
<el-button v-else type="primary" @click="handleCancel">确定</el-button> | |||
<!-- sections的第二项必须是 属性列表 --> | |||
<!-- <el-button | |||
v-if="sections[1].allowAdd" | |||
type="primary" | |||
@click="handleAddAttr"> | |||
添加属性 | |||
</el-button> --> | |||
</div> | |||
</div> | |||
<!-- 属性对话框 --> | |||
<base-dialog | |||
v-if="sections[1].allowAdd" | |||
:dialogTitle="attrTitle" | |||
:dialogVisible="attrFormVisible" | |||
width="45%" | |||
:append-to-body="true" | |||
custom-class="baseDialog" | |||
@close="closeAttrForm" | |||
@cancel="closeAttrForm" | |||
@confirm="submitAttrForm"> | |||
<DialogForm | |||
v-if="attrFormVisible" | |||
ref="attrForm" | |||
:disabled="mode.includes('detail')" | |||
v-model="attrForm" | |||
:rows="attrRows" /> | |||
</base-dialog> | |||
</el-drawer> | |||
</template> | |||
<script> | |||
import BaseInfoForm from '@/components/DialogForm'; | |||
const SmallTitle = { | |||
name: 'SmallTitle', | |||
props: ['size'], | |||
data() { | |||
return {}; | |||
}, | |||
methods: {}, | |||
render: function (h) { | |||
return h( | |||
'span', | |||
{ | |||
class: 'small-title', | |||
style: { | |||
fontSize: '18px', | |||
lineHeight: | |||
this.size == 'lg' ? '24px' : this.size == 'sm' ? '18px' : '20px', | |||
fontWeight: 500, | |||
fontFamily: '微软雅黑, Microsoft YaHei, Arial, Helvetica, sans-serif', | |||
}, | |||
}, | |||
this.$slots.default | |||
); | |||
}, | |||
}; | |||
export default { | |||
components: { SmallTitle, DialogForm: BaseInfoForm, BaseInfoForm }, | |||
props: ['sections', 'defaultMode', 'infoData'], | |||
data() { | |||
return { | |||
mode: '', | |||
visible: false, | |||
showForm: false, | |||
total: 0, | |||
form: {}, | |||
list: [], | |||
attrTitle: '', | |||
attrForm: { | |||
id: null, | |||
name: '', | |||
plcParamName: '', | |||
unit: '', | |||
collection: '', | |||
minValue: '', | |||
maxValue: '', | |||
defaultValue: '', | |||
description: '', | |||
remark: '', | |||
alarmContent: '', | |||
}, | |||
attrFormVisible: false, | |||
attrRows: [ | |||
[ | |||
{ | |||
input: true, | |||
label: '参数列名', | |||
prop: 'plcParamName', | |||
rules: [{ required: true, message: '不能为空', trigger: 'blur' }], | |||
}, | |||
{ | |||
input: true, | |||
label: '参数名称', | |||
prop: 'name', | |||
rules: [{ required: true, message: '不能为空', trigger: 'blur' }], | |||
}, | |||
], | |||
[ | |||
{ | |||
select: true, | |||
label: '单位', | |||
prop: 'unit', | |||
options: this.getDictDatas(this.DICT_TYPE.UNIT_DICT), | |||
// rules: [{ required: true, message: '不能为空', trigger: 'blur' }], | |||
}, | |||
{ | |||
switch: true, | |||
label: '是否采集', | |||
prop: 'collection', | |||
bind: { | |||
'active-value': 1, | |||
'inactive-value': 0, | |||
}, | |||
}, | |||
], | |||
[ | |||
{ | |||
input: true, | |||
label: '最小值', | |||
prop: 'minValue', | |||
rules: [ | |||
{ | |||
type: 'number', | |||
message: '请输入正确的数字', | |||
trigger: 'change', | |||
transform: (val) => Number(val), | |||
}, | |||
], | |||
}, | |||
{ | |||
input: true, | |||
label: '最大值', | |||
prop: 'maxValue', | |||
rules: [ | |||
{ | |||
required: false, | |||
}, | |||
{ | |||
type: 'number', | |||
message: '请输入正确的数字', | |||
trigger: 'change', | |||
transform: (val) => Number(val), | |||
}, | |||
], | |||
// rules: [{ required: true, message: '不能为空', trigger: 'blur' }], | |||
}, | |||
], | |||
[ | |||
{ | |||
input: true, | |||
label: '标准值', | |||
prop: 'defaultValue', | |||
// rules: [{ required: true, message: '不能为空', trigger: 'blur' }], | |||
}, | |||
{ | |||
input: true, | |||
label: '描述', | |||
prop: 'description', | |||
// rules: [{ required: true, message: '不能为空', trigger: 'blur' }], | |||
}, | |||
], | |||
[ | |||
{ | |||
input: true, | |||
label: '备注', | |||
prop: 'remark', | |||
// rules: [{ required: true, message: '不能为空', trigger: 'blur' }], | |||
}, | |||
], | |||
], | |||
attrQuery: { | |||
params: { | |||
pageNo: 1, | |||
pageSize: 10, | |||
}, | |||
}, // 属性列表的请求 | |||
infoQuery: null, // 基本信息的请求 | |||
attrFormSubmitting: false, | |||
attrListLoading: false, | |||
}; | |||
}, | |||
computed: { | |||
formRows() { | |||
return this.sections[0].rows.map((row) => { | |||
return row.map((col) => { | |||
return { | |||
...col, | |||
bind: { | |||
// 详情 模式下,禁用各种输入 | |||
// disabled: this.mode == 'detail', | |||
disabled: true, | |||
}, | |||
}; | |||
}); | |||
}); | |||
}, | |||
tableBtn() { | |||
return this.mode == 'detail' ? [] : this.sections[1].tableBtn; | |||
}, | |||
}, | |||
mounted() { | |||
this.mode = this.defaultMode || 'detail'; | |||
for (const section of this.sections) { | |||
// 请求具体信息 | |||
if ('url' in section) { | |||
const query = { | |||
url: section.url, | |||
method: section.method || 'get', | |||
params: section.queryParams || null, | |||
data: section.data || null, | |||
}; | |||
// debugger; | |||
this.$axios(query).then(({ data }) => { | |||
if (section.key == 'base') { | |||
this.form = data; | |||
this.showForm = true; | |||
this.infoQuery = query; | |||
} else if (section.key == 'attrs') { | |||
this.attrQuery = query; | |||
this.list = data.list; | |||
this.total = data.total; | |||
} | |||
}); | |||
} else if (section.key == 'base') { | |||
this.form = this.infoData; | |||
this.showForm = true; | |||
} | |||
} | |||
}, | |||
methods: { | |||
handleTableBtnClick({ type, data }) { | |||
switch (type) { | |||
case 'edit': | |||
this.handleEditAttr(data.id); | |||
break; | |||
case 'delete': | |||
this.handleDeleteAttr(data.id); | |||
break; | |||
} | |||
}, | |||
handleEmitFun(val) { | |||
console.log('handleEmitFun', val); | |||
}, | |||
init() { | |||
this.visible = true; | |||
}, | |||
async getAttrList() { | |||
this.attrListLoading = true; | |||
const res = await this.$axios(this.attrQuery); | |||
if (res.code == 0) { | |||
this.list = res.data.list; | |||
this.total = res.data.total; | |||
} | |||
this.attrListLoading = false; | |||
}, | |||
// 保存表单 | |||
handleSave() { | |||
this.$refs['form'][0].validate(async (valid) => { | |||
if (valid) { | |||
const isEdit = this.mode == 'edit'; | |||
await this.$axios({ | |||
url: this.sections[0][isEdit ? 'urlUpdate' : 'urlCreate'], | |||
method: isEdit ? 'put' : 'post', | |||
data: this.form, | |||
}); | |||
this.$modal.msgSuccess(`${isEdit ? '更新' : '创建'}成功`); | |||
this.visible = false; | |||
this.$emit('refreshDataList'); | |||
} | |||
}); | |||
}, | |||
handleCancel() { | |||
this.visible = false; | |||
}, | |||
// 开启编辑 | |||
toggleEdit() { | |||
this.mode = 'edit'; | |||
}, | |||
// 新增属性 | |||
handleAddAttr() { | |||
this.attrForm = { | |||
id: null, | |||
name: '', | |||
plcParamName: '', | |||
unit: '', | |||
collection: '', | |||
minValue: '', | |||
maxValue: '', | |||
defaultValue: '', | |||
description: '', | |||
remark: '', | |||
alarmContent: '', | |||
}; | |||
this.attrTitle = '添加设备绑定信息'; | |||
this.attrFormVisible = true; | |||
}, | |||
// 编辑属性 | |||
async handleEditAttr(attrId) { | |||
const res = await this.$axios({ | |||
url: this.sections[1].urlDetail, | |||
method: 'get', | |||
params: { id: attrId }, | |||
}); | |||
if (res.code == 0) { | |||
this.attrForm = res.data; | |||
this.attrTitle = '编辑设备绑定信息'; | |||
this.attrFormVisible = true; | |||
} | |||
}, | |||
// 删除属性 | |||
handleDeleteAttr(attrId) { | |||
this.$confirm('确定删除该分组报警?', '提示', { | |||
confirmButtonText: '确定', | |||
cancelButtonText: '取消', | |||
type: 'warning', | |||
}) | |||
.then(async () => { | |||
const res = await this.$axios({ | |||
url: this.sections[1].urlDelete, | |||
method: 'delete', | |||
params: { id: attrId }, | |||
}); | |||
if (res.code == 0) { | |||
this.$message({ | |||
message: '删除成功', | |||
type: 'success', | |||
duration: 1500, | |||
onClose: () => { | |||
this.getAttrList(); | |||
}, | |||
}); | |||
} | |||
}) | |||
.catch(() => {}); | |||
}, | |||
// 提交属性表 | |||
async submitAttrForm() { | |||
this.$refs['attrForm'].validate((valid) => { | |||
if (!valid) { | |||
return; | |||
} | |||
}); | |||
const isEdit = this.attrForm.id != null; | |||
this.attrFormSubmitting = true; | |||
const res = await this.$axios({ | |||
url: isEdit ? this.sections[1].urlUpdate : this.sections[1].urlCreate, | |||
method: isEdit ? 'put' : 'post', | |||
data: { | |||
...this.attrForm, | |||
connectId: this.infoData.id | |||
}, | |||
}); | |||
if (res.code == 0) { | |||
this.closeAttrForm(); | |||
this.$message({ | |||
message: `${isEdit ? '更新' : '创建'}成功`, | |||
type: 'success', | |||
duration: 1500, | |||
onClose: () => { | |||
this.getAttrList(); | |||
}, | |||
}); | |||
} | |||
this.attrFormSubmitting = false; | |||
}, | |||
closeAttrForm() { | |||
this.attrFormVisible = false; | |||
}, | |||
handleClick(raw) { | |||
if (raw.type === 'delete') { | |||
this.$confirm(`确定删除该报警?`, '提示', { | |||
confirmButtonText: '确定', | |||
cancelButtonText: '取消', | |||
type: 'warning', | |||
}) | |||
.then(() => { | |||
deleteProductAttr(raw.data.id).then(({ data }) => { | |||
this.$message({ | |||
message: '操作成功', | |||
type: 'success', | |||
duration: 1500, | |||
onClose: () => { | |||
this.getList(); | |||
}, | |||
}); | |||
}); | |||
}) | |||
.catch(() => {}); | |||
} else { | |||
this.addNew(raw.data.id); | |||
} | |||
}, | |||
}, | |||
}; | |||
</script> | |||
<style scoped> | |||
.drawer >>> .el-drawer { | |||
border-radius: 8px 0 0 8px; | |||
} | |||
.drawer >>> .el-drawer__header { | |||
margin: 0; | |||
padding: 32px 32px 24px; | |||
border-bottom: 1px solid #dcdfe6; | |||
margin-bottom: 0px; | |||
} | |||
.small-title::before { | |||
content: ''; | |||
display: inline-block; | |||
vertical-align: top; | |||
width: 4px; | |||
height: 22px; | |||
border-radius: 1px; | |||
margin-right: 8px; | |||
background-color: #0b58ff; | |||
} | |||
.drawer-body { | |||
display: flex; | |||
flex-direction: column; | |||
height: 100%; | |||
} | |||
.drawer-body__content { | |||
flex: 1; | |||
/* background: #eee; */ | |||
padding: 20px 30px; | |||
overflow-y: auto; | |||
} | |||
.drawer-body__footer { | |||
display: flex; | |||
justify-content: flex-end; | |||
padding: 18px; | |||
} | |||
</style> |
@@ -40,6 +40,53 @@ | |||
@confirm="submitForm"> | |||
<DialogForm v-if="open" ref="form" :dataForm="form" :rows="rows" /> | |||
</base-dialog> | |||
<!-- 抽屉 详情 --> | |||
<BasicDrawer | |||
v-if="editVisible" | |||
ref="drawer" | |||
:default-mode="editMode" | |||
:info-data="alarmForm" | |||
:sections="[ | |||
{ | |||
name: '基本信息', | |||
key: 'base', | |||
rows: drawerBaseInfoRows, | |||
}, | |||
{ | |||
name: '属性列表', | |||
key: 'attrs', | |||
props: drawerListProps, | |||
url: '/base/equipment-plc-param/page', | |||
urlCreate: '/base/equipment-plc-param/create', | |||
urlUpdate: '/base/equipment-plc-param/update', | |||
urlDelete: '/base/equipment-plc-param/delete', | |||
urlDetail: '/base/equipment-plc-param/get', | |||
queryParams: { | |||
connectId: alarmForm.id, | |||
pageNo: 1, | |||
pageSize: 10, | |||
}, | |||
tableBtn: [ | |||
this.$auth.hasPermi('base:equipment-plc-param:update') | |||
? { | |||
type: 'edit', | |||
btnName: '修改', | |||
} | |||
: undefined, | |||
this.$auth.hasPermi('base:equipment-plc-param:delete') | |||
? { | |||
type: 'delete', | |||
btnName: '删除', | |||
} | |||
: undefined, | |||
].filter((v) => v), | |||
allowAdd: true, | |||
}, | |||
]" | |||
@refreshDataList="getList" | |||
@cancel="editVisible = false" | |||
@destroy="editVisible = false" /> | |||
</div> | |||
</template> | |||
@@ -55,11 +102,13 @@ import { | |||
import moment from 'moment'; | |||
import basicPageMixin from '@/mixins/lb/basicPageMixin'; | |||
// import './http'; | |||
import BasicDrawer from './components/BasicDrawer.vue'; | |||
import { publicFormatter } from '@/utils/dict'; | |||
export default { | |||
name: 'EquipmentPlcConnect', | |||
mixins: [basicPageMixin], | |||
components: {}, | |||
components: { BasicDrawer }, | |||
data() { | |||
return { | |||
searchBarKeys: ['equipmentId', 'plcId'], | |||
@@ -78,6 +127,10 @@ export default { | |||
// : undefined, | |||
// ].filter((v) => v), | |||
tableBtn: [ | |||
{ | |||
type: 'detail', | |||
btnName: '参数绑定', | |||
}, | |||
{ | |||
type: 'edit', | |||
btnName: '修改', | |||
@@ -107,32 +160,32 @@ export default { | |||
{ prop: 'plcTableName', label: '关联表名' }, | |||
{ prop: 'plcName', label: '标识名称' }, | |||
{ prop: 'bindingParameters', label: '绑定参数数量' }, | |||
{ | |||
_action: 'params-bind', | |||
label: '查看绑定', | |||
subcomponent: { | |||
props: ['injectData'], | |||
render: function (h) { | |||
const _this = this; | |||
return h( | |||
'el-button', | |||
{ | |||
props: { type: 'text' }, | |||
on: { | |||
click: function () { | |||
console.log('inejctdata', _this.injectData); | |||
_this.$emit('emitData', { | |||
action: _this.injectData._action, | |||
payload: _this.injectData, | |||
}); | |||
}, | |||
}, | |||
}, | |||
'查看绑定' | |||
); | |||
}, | |||
}, | |||
}, | |||
// { | |||
// _action: 'params-bind', | |||
// label: '查看绑定', | |||
// subcomponent: { | |||
// props: ['injectData'], | |||
// render: function (h) { | |||
// const _this = this; | |||
// return h( | |||
// 'el-button', | |||
// { | |||
// props: { type: 'text' }, | |||
// on: { | |||
// click: function () { | |||
// console.log('inejctdata', _this.injectData); | |||
// _this.$emit('emitData', { | |||
// action: _this.injectData._action, | |||
// payload: _this.injectData, | |||
// }); | |||
// }, | |||
// }, | |||
// }, | |||
// '查看绑定' | |||
// ); | |||
// }, | |||
// }, | |||
// }, | |||
], | |||
searchBarFormConfig: [ | |||
{ | |||
@@ -185,8 +238,8 @@ export default { | |||
url: '/base/equipment-plc/listAll', | |||
rules: [{ required: true, message: '不能为空', trigger: 'blur' }], | |||
bind: { | |||
filterable: true | |||
} | |||
filterable: true, | |||
}, | |||
}, | |||
], | |||
[ | |||
@@ -197,8 +250,8 @@ export default { | |||
url: '/base/equipment/page?pageNo=1&pageSize=99', | |||
rules: [{ required: true, message: '不能为空', trigger: 'blur' }], | |||
bind: { | |||
filterable: true | |||
} | |||
filterable: true, | |||
}, | |||
}, | |||
], | |||
], | |||
@@ -212,6 +265,52 @@ export default { | |||
}, | |||
// 表单参数 | |||
form: {}, | |||
// 查看绑定配置 | |||
editVisible: false, | |||
editMode: '', | |||
drawerBaseInfoRows: [ | |||
[ | |||
{ | |||
input: true, | |||
label: '设备名', | |||
prop: 'equipmentName', | |||
rules: [{ required: true, message: '不能为空', trigger: 'blur' }], | |||
// bind: { | |||
// disabled: this.editMode == 'detail', // some condition, like detail mode... | |||
// } | |||
}, | |||
{ | |||
input: true, | |||
label: '关联表名', | |||
prop: 'plcTableName', | |||
// url: '/base/equipment/getCode', | |||
}, | |||
], | |||
], | |||
drawerListProps: [ | |||
{ prop: 'plcParamName', label: '参数列名' }, | |||
{ prop: 'name', label: '参数名称' }, | |||
{ | |||
prop: 'unit', | |||
label: '单位', | |||
filter: publicFormatter('unit_dict'), | |||
}, | |||
{ | |||
prop: 'collection', | |||
label: '是否采集', | |||
filter: (val) => (val != null ? ['否', '是'][val] : '-'), | |||
}, | |||
{ prop: 'minValue', label: '最小值' }, | |||
{ prop: 'maxValue', label: '最大值' }, | |||
{ prop: 'defaultValue', label: '标准值' }, | |||
{ prop: 'description', label: '描述' }, | |||
{ prop: 'remark', label: '备注' }, | |||
], | |||
alarmForm: { | |||
id: undefined, | |||
equipmentName: undefined, | |||
plcTableName: undefined, | |||
}, | |||
}; | |||
}, | |||
created() { | |||
@@ -353,6 +452,34 @@ export default { | |||
}); | |||
}); | |||
}, | |||
// 查看报警 | |||
handleDetail(row) { | |||
// debugger; | |||
const { | |||
id, | |||
bindingParameters, | |||
equipmentCode, | |||
equipmentId, | |||
equipmentName, | |||
plcCode, | |||
plcId, | |||
plcName, | |||
plcTableName, | |||
productionLine, | |||
workshopSection, | |||
} = row; | |||
// 打开抽屉 | |||
this.editMode = 'detail'; | |||
this.alarmForm.id = id; | |||
this.alarmForm.plcTableName = plcTableName; // 关联表名 | |||
this.alarmForm.equipmentName = equipmentName; | |||
this.editVisible = true; | |||
this.$nextTick(() => { | |||
this.$refs['drawer'].init(); | |||
}); | |||
}, | |||
/** 删除按钮操作 */ | |||
handleDelete(row) { | |||
const id = row.id; | |||
@@ -367,6 +494,7 @@ export default { | |||
}) | |||
.catch(() => {}); | |||
}, | |||
/** 导出按钮操作 */ | |||
handleExport() { | |||
// 处理查询参数 | |||
@@ -6,10 +6,11 @@ | |||
--> | |||
<template> | |||
<div class="chart-grid-item" style=""> | |||
<div class="chart-grid-item" style="overflow: inherit"> | |||
<div | |||
class="pie-chart" | |||
ref="pieChart" | |||
style="overflow: inherit;" | |||
:data-eqname="value.equipmentName || 'Default'"></div> | |||
<div class="data-view"> | |||
<div class="data-view__item"> | |||
@@ -93,7 +94,7 @@ export default { | |||
name: '', | |||
type: 'pie', | |||
radius: ['75%', '90%'], | |||
center: ['50%', '45%'], | |||
center: ['50%', '48%'], | |||
label: { | |||
show: false, | |||
}, | |||
@@ -108,7 +109,7 @@ export default { | |||
// 内环 | |||
name: '', | |||
type: 'pie', | |||
center: ['50%', '45%'], | |||
center: ['50%', '48%'], | |||
radius: ['60%', '75%'], | |||
itemStyle: { | |||
borderRadius: 10, | |||
@@ -6,7 +6,7 @@ | |||
--> | |||
<template> | |||
<div class="app-container"> | |||
<div class="app-container allow-overflow"> | |||
<!-- 搜索工作栏 --> | |||
<SearchBar | |||
:formConfigs="searchBarFormConfig" | |||
@@ -29,11 +29,19 @@ | |||
:table-data="list" | |||
@emitFun="handleEmitFun"></base-table> | |||
</el-tab-pane> | |||
<el-tab-pane :label="'\u3000可视化\u3000'" name="graph"> | |||
<el-tab-pane | |||
:label="'\u3000可视化\u3000'" | |||
name="graph" | |||
style="overflow: inherit"> | |||
<div | |||
v-if="activeName == 'graph'" | |||
class="graph" | |||
style="display: flex; flex-direction: column; position: relative"> | |||
style=" | |||
overflow: inherit; | |||
display: flex; | |||
flex-direction: column; | |||
position: relative; | |||
"> | |||
<div class="blue-title">各设备加工数量</div> | |||
<div class="legend"> | |||
<div class="legend-item"> | |||
@@ -429,6 +437,10 @@ export default { | |||
transform: translateY(-12px); | |||
} | |||
.el-tabs__content { | |||
overflow: visible; | |||
} | |||
.el-tabs__item { | |||
padding-left: 0 !important; | |||
padding-right: 0 !important; | |||
@@ -462,6 +474,7 @@ export default { | |||
border-radius: 12px; | |||
border: 1px solid #ccc; | |||
// background: #0003; | |||
overflow: inherit; | |||
} | |||
.bg-grid { | |||
display: grid; | |||
@@ -469,7 +482,7 @@ export default { | |||
grid-template-columns: repeat(4, minmax(280px, 1fr)); | |||
grid-auto-columns: 280px; | |||
grid-auto-rows: 290px; | |||
overflow: hidden; | |||
overflow: inherit; | |||
position: relative; | |||
} | |||
@@ -76,13 +76,18 @@ export default class GanttGraph { | |||
type: 'none', | |||
}, | |||
formatter: (params) => { | |||
// debugger; | |||
return ` | |||
<div style="display: flex; align-items: center; justify-content: space-between"> | |||
<h1 style="font-size: 18px; font-weight: 600;">${params.seriesName}</h1> | |||
<h2 style="font-size: 18px; font-weight: 400; letter-spacing: 1px;">${params.name} <span style="display: inline-block; margin-left: 8px; width: 12px; height: 12px; border-radius: 50%; background: ${params.color} "></span></h2> | |||
</div> | |||
<div>${new Date(params.value[1]).toLocaleString()} ~ ${new Date(params.value[2]).toLocaleString()}</div> | |||
` | |||
<div style="display: flex; flex-direction: column;"> | |||
<span>${new Date(params.value[1]).toLocaleTimeString()} ~ ${new Date(params.value[2]).toLocaleTimeString()}</span> | |||
<div style="display: flex; align-items: center; justify-content: space-between;"> | |||
<div style="display: flex; align-items: center;"> | |||
<span class="icon" style="width: 8px; height: 8px; border-radius: 2px; background: ${params.color}"></span> | |||
<span class="eq-name" style="margin-left: 4px;">${params.seriesName}</span> | |||
</div> | |||
<span class="run-status" style="margin-left: 8px; opacity: 0.6">${params.name}</span> | |||
</div> | |||
` | |||
} | |||
} | |||
grid = [] | |||
@@ -137,6 +142,11 @@ export default class GanttGraph { | |||
.join(':'); | |||
}, | |||
}, | |||
axisLine: { | |||
lineStyle: { | |||
color: '#0005', | |||
}, | |||
}, | |||
boundaryGap: false, | |||
// data: getXaxisRange(getTodayStart(new Date())), | |||
}, | |||
@@ -166,10 +176,13 @@ export default class GanttGraph { | |||
nameRotate: 0, | |||
nameTextStyle: { | |||
fontSize: 16, | |||
color: '#000A' | |||
}, | |||
axisLine: { | |||
show: true, | |||
lineStyle: {}, | |||
lineStyle: { | |||
color: '#0005', | |||
}, | |||
}, | |||
axisLabel: { show: false }, | |||
axisTick: { show: false }, | |||
@@ -180,6 +193,12 @@ export default class GanttGraph { | |||
gridIndex: this.gridIndex, | |||
type: 'value', | |||
splitLine: { show: false }, | |||
axisLine: { | |||
show: true, | |||
lineStyle: { | |||
color: '#0005', | |||
}, | |||
}, | |||
axisLabel: { show: false }, | |||
axisTick: { show: false }, | |||
}, | |||
@@ -213,7 +232,7 @@ export default class GanttGraph { | |||
tooltip: { show: false }, | |||
itemStyle: { | |||
color: '#F2F4F9', | |||
// opacity: 0.3, | |||
opacity: 0.3, | |||
} | |||
}, | |||
] | |||
@@ -33,7 +33,13 @@ | |||
:data-value="fc.id" | |||
class="factory-list__item" | |||
:class="{ 'is-current': fc.id == currentFactory?.id }"> | |||
{{ fc.label }} | |||
<span> | |||
{{ fc.label }} | |||
</span> | |||
<svg-icon | |||
v-if="fc.id == currentFactory?.id" | |||
icon-class="Confirm" | |||
style="height: 14px; width: 14px" /> | |||
</li> | |||
</ul> | |||
<div v-else style="color: #0008; width: 128px; text-align: center"> | |||
@@ -499,9 +505,12 @@ li { | |||
.factory-list__item { | |||
font-size: 16px; | |||
line-height: 1; | |||
padding: 8px 64px 8px 16px; | |||
/* min-width: 64px; */ | |||
padding: 8px 16px 8px 16px; | |||
min-width: 128px; | |||
position: relative; | |||
display: flex; | |||
align-items: center; | |||
justify-content: space-between; | |||
} | |||
.factory-list__item:hover, | |||
@@ -510,13 +519,13 @@ li { | |||
color: #0b58ff; | |||
} | |||
.factory-list__item.is-current::after { | |||
/* .factory-list__item.is-current::after { | |||
content: '√'; | |||
position: absolute; | |||
top: 8px; | |||
right: 16px; | |||
font-weight: bold; | |||
} | |||
} */ | |||
.custom-tree-class >>> .el-tree-node__content { | |||
width: 100%; | |||
@@ -543,8 +552,8 @@ li { | |||
.custom-icon-class { | |||
margin-right: 8px; | |||
width: 20px; | |||
height: 24px; | |||
background: url('../../../assets/images/tree-icon-1.png') 100% / contain | |||
height: 20px; | |||
background: url('../../../assets/images/Qian.png') center center / contain | |||
no-repeat; | |||
} | |||
@@ -9,10 +9,10 @@ | |||
<el-form | |||
ref="form" | |||
:model="dataForm" | |||
label-width="100px" | |||
label-width="120px" | |||
v-loading="formLoading"> | |||
<el-row :gutter="20"> | |||
<el-col> | |||
<el-col :span="12"> | |||
<el-form-item | |||
label="产线" | |||
prop="productionId" | |||
@@ -30,7 +30,7 @@ | |||
</el-select> | |||
</el-form-item> | |||
</el-col> | |||
<el-col> | |||
<el-col :span="12"> | |||
<el-form-item | |||
label="工段" | |||
prop="sectionId" | |||
@@ -49,7 +49,7 @@ | |||
</el-form-item> | |||
</el-col> | |||
<el-col> | |||
<el-col :span="12"> | |||
<el-form-item | |||
label="按钮盒识别码" | |||
prop="buttonId" | |||
@@ -85,7 +85,7 @@ | |||
</el-form-item> --> | |||
</el-col> | |||
<el-col> | |||
<el-col :span="12"> | |||
<el-form-item label="按钮盒模式" prop="model"> | |||
<el-input | |||
v-model="dataForm.model" | |||
@@ -94,7 +94,7 @@ | |||
</el-form-item> | |||
</el-col> | |||
<el-col> | |||
<el-col :span="12"> | |||
<el-form-item | |||
label="按钮值" | |||
prop="keyValue" | |||
@@ -121,7 +121,7 @@ | |||
</el-form-item> | |||
</el-col> | |||
<el-col> | |||
<el-col :span="12"> | |||
<el-form-item label="检测内容" prop="inspectionDetContent"> | |||
<el-input | |||
type="textarea" | |||
@@ -75,8 +75,6 @@ export default { | |||
filterable: true, | |||
}, | |||
}, | |||
], | |||
[ | |||
{ | |||
select: true, | |||
label: '工段', | |||
@@ -103,8 +101,8 @@ export default { | |||
}, | |||
], | |||
}, | |||
{ input: true, label: '按钮盒模式', prop: 'model' }, | |||
], | |||
[{ input: true, label: '按钮盒模式', prop: 'model' }], | |||
[ | |||
{ | |||
input: true, | |||
@@ -121,8 +119,6 @@ export default { | |||
], | |||
bind: { type: 'number', min: 0, max: 100 }, | |||
}, | |||
], | |||
[ | |||
{ | |||
textarea: true, | |||
label: '检测内容', | |||