diff --git a/src/assets/images/factory-icon.png b/src/assets/images/factory-icon.png new file mode 100644 index 00000000..0f90ed82 Binary files /dev/null and b/src/assets/images/factory-icon.png differ diff --git a/src/assets/images/no-data-bg.png b/src/assets/images/no-data-bg.png new file mode 100644 index 00000000..8f4f7ee2 Binary files /dev/null and b/src/assets/images/no-data-bg.png differ diff --git a/src/assets/images/tree-icon-1.png b/src/assets/images/tree-icon-1.png new file mode 100644 index 00000000..5b05daea Binary files /dev/null and b/src/assets/images/tree-icon-1.png differ diff --git a/src/assets/images/tree-icon-2.png b/src/assets/images/tree-icon-2.png new file mode 100644 index 00000000..e9e58018 Binary files /dev/null and b/src/assets/images/tree-icon-2.png differ diff --git a/src/assets/styles/index.scss b/src/assets/styles/index.scss index ca85a160..3180e79f 100644 --- a/src/assets/styles/index.scss +++ b/src/assets/styles/index.scss @@ -6,11 +6,12 @@ @import './btn.scss'; body { - height: 100%; - -moz-osx-font-smoothing: grayscale; - -webkit-font-smoothing: antialiased; - text-rendering: optimizeLegibility; - font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, Arial, sans-serif; + height: 100%; + -moz-osx-font-smoothing: grayscale; + -webkit-font-smoothing: antialiased; + text-rendering: optimizeLegibility; + font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, + Microsoft YaHei, Arial, sans-serif; } // label { @@ -27,170 +28,195 @@ body { } html { - height: 100%; - box-sizing: border-box; + height: 100%; + box-sizing: border-box; } #app { - height: 100%; + height: 100%; } *, *:before, *:after { - box-sizing: inherit; + box-sizing: inherit; } .no-padding { - padding: 0px !important; + padding: 0px !important; } .padding-content { - padding: 4px 0; + padding: 4px 0; } a:focus, a:active { - outline: none; + outline: none; } a, a:focus, a:hover { - cursor: pointer; - color: inherit; - text-decoration: none; + cursor: pointer; + color: inherit; + text-decoration: none; } div:focus { - outline: none; + outline: none; } .fr { - float: right; + float: right; } .fl { - float: left; + float: left; } .pr-5 { - padding-right: 5px; + padding-right: 5px; } .pl-5 { - padding-left: 5px; + padding-left: 5px; } .block { - display: block; + display: block; } .pointer { - cursor: pointer; + cursor: pointer; } .inlineBlock { - display: block; + display: block; } .clearfix { - &:after { - visibility: hidden; - display: block; - font-size: 0; - content: " "; - clear: both; - height: 0; - } + &:after { + visibility: hidden; + display: block; + font-size: 0; + content: ' '; + clear: both; + height: 0; + } } aside { - background: #eef1f6; - padding: 8px 24px; - margin-bottom: 20px; - border-radius: 2px; - display: block; - line-height: 32px; - font-size: 16px; - font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; - color: #2c3e50; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; + background: #eef1f6; + padding: 8px 24px; + margin-bottom: 20px; + border-radius: 2px; + display: block; + line-height: 32px; + font-size: 16px; + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, + Ubuntu, Cantarell, 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif; + color: #2c3e50; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; - a { - color: #337ab7; - cursor: pointer; + a { + color: #337ab7; + cursor: pointer; - &:hover { - color: rgb(32, 160, 255); - } - } + &:hover { + color: rgb(32, 160, 255); + } + } } //main-container全局样式 .app-container { - padding: 16px; + padding: 16px; } .components-container { - margin: 30px 50px; - position: relative; + margin: 30px 50px; + position: relative; } .text-center { - text-align: center + text-align: center; } .sub-navbar { - height: 50px; - line-height: 50px; - position: relative; - width: 100%; - text-align: right; - padding-right: 20px; - transition: 600ms ease position; - background: linear-gradient(90deg, rgba(32, 182, 249, 1) 0%, rgba(32, 182, 249, 1) 0%, rgba(33, 120, 241, 1) 100%, rgba(33, 120, 241, 1) 100%); + height: 50px; + line-height: 50px; + position: relative; + width: 100%; + text-align: right; + padding-right: 20px; + transition: 600ms ease position; + background: linear-gradient( + 90deg, + rgba(32, 182, 249, 1) 0%, + rgba(32, 182, 249, 1) 0%, + rgba(33, 120, 241, 1) 100%, + rgba(33, 120, 241, 1) 100% + ); - .subtitle { - font-size: 20px; - color: #fff; - } + .subtitle { + font-size: 20px; + color: #fff; + } - &.draft { - background: #d0d0d0; - } + &.draft { + background: #d0d0d0; + } - &.deleted { - background: #d0d0d0; - } + &.deleted { + background: #d0d0d0; + } } .link-type, .link-type:focus { - color: #337ab7; - cursor: pointer; + color: #337ab7; + cursor: pointer; - &:hover { - color: rgb(32, 160, 255); - } + &:hover { + color: rgb(32, 160, 255); + } } .filter-container { - padding-bottom: 10px; + padding-bottom: 10px; - .filter-item { - display: inline-block; - vertical-align: middle; - margin-bottom: 10px; - } + .filter-item { + display: inline-block; + vertical-align: middle; + margin-bottom: 10px; + } } //refine vue-multiselect plugin .multiselect { - line-height: 16px; + line-height: 16px; } .multiselect--active { - z-index: 1000 !important; + z-index: 1000 !important; +} + +.no-data-bg { + height: 240px; + background: url(../images/no-data-bg.png) 50% 100% / contain + no-repeat; + position: relative; + + &::after { + content: '暂无数据'; + position: absolute; + bottom: 12px; + left: 50%; + transform: translateX(-50%); + color: #ccc; + font-size: 18px; + letter-spacing: 1px; + } } diff --git a/src/assets/styles/ruoyi.scss b/src/assets/styles/ruoyi.scss index 0b790e54..17ef2e4f 100644 --- a/src/assets/styles/ruoyi.scss +++ b/src/assets/styles/ruoyi.scss @@ -5,110 +5,123 @@ /** 基础通用 **/ .pt5 { - padding-top: 5px; + padding-top: 5px; } .pr5 { - padding-right: 5px; + padding-right: 5px; } .pb5 { - padding-bottom: 5px; + padding-bottom: 5px; } .mt5 { - margin-top: 5px; + margin-top: 5px; } .mr5 { - margin-right: 5px; + margin-right: 5px; } .mb5 { - margin-bottom: 5px; + margin-bottom: 5px; } .mb8 { - margin-bottom: 8px; + margin-bottom: 8px; } .ml5 { - margin-left: 5px; + margin-left: 5px; } .mt10 { - margin-top: 10px; + margin-top: 10px; } .mr10 { - margin-right: 10px; + margin-right: 10px; } .mb10 { - margin-bottom: 10px; + margin-bottom: 10px; } .ml10 { - margin-left: 10px; + margin-left: 10px; } .mt20 { - margin-top: 20px; + margin-top: 20px; } .mr20 { - margin-right: 20px; + margin-right: 20px; } .mb20 { - margin-bottom: 20px; + margin-bottom: 20px; } .ml20 { - margin-left: 20px; + margin-left: 20px; } -.h1, .h2, .h3, .h4, .h5, .h6, h1, h2, h3, h4, h5, h6 { - font-family: inherit; - font-weight: 500; - line-height: 1.1; - color: inherit; +.h1, +.h2, +.h3, +.h4, +.h5, +.h6, +h1, +h2, +h3, +h4, +h5, +h6 { + font-family: inherit; + font-weight: 500; + line-height: 1.1; + color: inherit; } -.el-message-box__status + .el-message-box__message{ - word-break: break-word; +.el-message-box__status + .el-message-box__message { + word-break: break-word; } .el-dialog:not(.is-fullscreen) { - margin-top: 6vh !important; + // margin-top: 6vh !important; + margin-top: 12vh !important; } .el-dialog__wrapper.scrollbar .el-dialog .el-dialog__body { - overflow: auto; - overflow-x: hidden; - max-height: 70vh; - padding: 10px 20px 0; + overflow: auto; + overflow-x: hidden; + max-height: 70vh; + padding: 10px 20px 0; } -.el-dialog{ - display: flex; - flex-direction: column; - max-width: calc(100% - 30px); - max-height: calc(100% - 70px); - .el-dialog__body { - overflow: auto; - } +.el-dialog { + display: flex; + flex-direction: column; + max-width: calc(100% - 30px); + max-height: calc(100% - 70px); + .el-dialog__body { + overflow: auto; + } } .el-table { - .el-table__header-wrapper, .el-table__fixed-header-wrapper { - th { - word-break: break-word; - background-color: #f8f8f9; - color: #515a6e; - height: 40px; - font-size: 13px; - } - } - .el-table__body-wrapper { - .el-button [class*="el-icon-"] + span { - margin-left: 1px; - } - } + .el-table__header-wrapper, + .el-table__fixed-header-wrapper { + th { + word-break: break-word; + background-color: #f8f8f9; + color: #515a6e; + height: 40px; + font-size: 13px; + } + } + .el-table__body-wrapper { + .el-button [class*='el-icon-'] + span { + margin-left: 1px; + } + } } /** 表单布局 **/ .form-header { - font-size:15px; - color:#6379bb; - border-bottom:1px solid #ddd; - margin:8px 10px 25px 10px; - padding-bottom:5px + font-size: 15px; + color: #6379bb; + border-bottom: 1px solid #ddd; + margin: 8px 10px 25px 10px; + padding-bottom: 5px; } /** 表格布局 **/ @@ -122,169 +135,171 @@ /* tree border */ .tree-border { - margin-top: 5px; - border: 1px solid #e5e6e7; - background: #FFFFFF none; - border-radius:4px; + margin-top: 5px; + border: 1px solid #e5e6e7; + background: #ffffff none; + border-radius: 4px; } .pagination-container .el-pagination { - right: 0; - position: absolute; + right: 0; + position: absolute; } -@media ( max-width : 768px) { - .pagination-container .el-pagination > .el-pagination__jump { - display: none !important; - } - .pagination-container .el-pagination > .el-pagination__sizes { - display: none !important; - } +@media (max-width: 768px) { + .pagination-container .el-pagination > .el-pagination__jump { + display: none !important; + } + .pagination-container .el-pagination > .el-pagination__sizes { + display: none !important; + } } .el-table .fixed-width .el-button--mini { - padding-left: 0; - padding-right: 0; - width: inherit; + padding-left: 0; + padding-right: 0; + width: inherit; } /** 表格更多操作下拉样式 */ -.el-table .el-dropdown-link,.el-table .el-dropdown-selfdefine { - cursor: pointer; - margin-left: 5px; +.el-table .el-dropdown-link, +.el-table .el-dropdown-selfdefine { + cursor: pointer; + margin-left: 5px; } -.el-table .el-dropdown, .el-icon-arrow-down { - font-size: 12px; +.el-table .el-dropdown, +.el-icon-arrow-down { + font-size: 12px; } .el-tree-node__content > .el-checkbox { - margin-right: 8px; + margin-right: 8px; } .list-group-striped > .list-group-item { - border-left: 0; - border-right: 0; - border-radius: 0; - padding-left: 0; - padding-right: 0; + border-left: 0; + border-right: 0; + border-radius: 0; + padding-left: 0; + padding-right: 0; - &:not(:last-child) { - border-bottom: 1px solid #e7eaec; - } + &:not(:last-child) { + border-bottom: 1px solid #e7eaec; + } } .list-group { - padding-left: 0px; - list-style: none; + padding-left: 0px; + list-style: none; } .list-group-item { - // border-bottom: 1px solid #e7eaec; - // border-top: 1px solid #e7eaec; - margin-bottom: -1px; - padding: 11px 0px; - font-size: 13px; + // border-bottom: 1px solid #e7eaec; + // border-top: 1px solid #e7eaec; + margin-bottom: -1px; + padding: 11px 0px; + font-size: 13px; } .pull-right { - float: right !important; + float: right !important; } .el-card__header { - padding: 14px 15px 7px; - min-height: 40px; + padding: 14px 15px 7px; + min-height: 40px; } .el-card__body { - padding: 15px 20px 20px 20px; + padding: 15px 20px 20px 20px; } .card-box { - padding-right: 15px; - padding-left: 15px; - margin-bottom: 10px; + padding-right: 15px; + padding-left: 15px; + margin-bottom: 10px; } /* button color */ .el-button--cyan.is-active, .el-button--cyan:active { - background: #20B2AA; - border-color: #20B2AA; - color: #FFFFFF; + background: #20b2aa; + border-color: #20b2aa; + color: #ffffff; } .el-button--cyan:focus, .el-button--cyan:hover { - background: #48D1CC; - border-color: #48D1CC; - color: #FFFFFF; + background: #48d1cc; + border-color: #48d1cc; + color: #ffffff; } .el-button--cyan { - background-color: #20B2AA; - border-color: #20B2AA; - color: #FFFFFF; + background-color: #20b2aa; + border-color: #20b2aa; + color: #ffffff; } /* text color */ .text-navy { - color: #1ab394; + color: #1ab394; } .text-primary { - color: inherit; + color: inherit; } .text-success { - color: #1c84c6; + color: #1c84c6; } .text-info { - color: #23c6c8; + color: #23c6c8; } .text-warning { - color: #f8ac59; + color: #f8ac59; } .text-danger { - color: #ed5565; + color: #ed5565; } .text-muted { - color: #888888; + color: #888888; } /* image */ .img-circle { - border-radius: 50%; + border-radius: 50%; } .img-lg { - width: 120px; - height: 120px; + width: 120px; + height: 120px; } .avatar-upload-preview { - position: absolute; - top: 50%; - transform: translate(50%, -50%); - width: 200px; - height: 200px; - border-radius: 50%; - box-shadow: 0 0 4px #ccc; - overflow: hidden; + position: absolute; + top: 50%; + transform: translate(50%, -50%); + width: 200px; + height: 200px; + border-radius: 50%; + box-shadow: 0 0 4px #ccc; + overflow: hidden; } /* 拖拽列样式 */ -.sortable-ghost{ - opacity: .8; - color: #fff!important; - background: #42b983!important; +.sortable-ghost { + opacity: 0.8; + color: #fff !important; + background: #42b983 !important; } .top-right-btn { - position: relative; - float: right; + position: relative; + float: right; } diff --git a/src/utils/dynamicProps.js b/src/utils/dynamicProps.js index b0a9e643..147f82fb 100644 --- a/src/utils/dynamicProps.js +++ b/src/utils/dynamicProps.js @@ -1,3 +1,5 @@ +import moment from 'moment'; + /** * 用于动态表结构的 tableProps 生成 * @param {*} nameData @@ -16,10 +18,9 @@ export function handleNameData(nameData) { function step1(tree1) { return Array.from(new Set(tree1.map((item) => item.name))) .sort() - .map((item) => ({ - prop: item, - label: item, - align: 'center', + .map((time) => ({ + prop: time, + label: moment(time).format('YYYY-MM-DD HH:mm:ss'), children: [], })); } @@ -33,7 +34,6 @@ function step2(firstTierProps, tree2) { parent.children.push({ label: nd.name, prop: `${parent.prop}-${nd.name}`, - align: 'center', }); } }); diff --git a/src/views/base/equipmentBindGroup/index.vue b/src/views/base/equipmentBindGroup/index.vue index c67c66eb..33477279 100644 --- a/src/views/base/equipmentBindGroup/index.vue +++ b/src/views/base/equipmentBindGroup/index.vue @@ -17,6 +17,7 @@ v-if="tableBtn.length" slot="handleBtn" label="操作" + :width="120" :method-list="tableBtn" @clickBtn="handleTableBtnClick" /> @@ -85,12 +86,11 @@ export default { width: 180, filter: (val) => moment(val).format('yyyy-MM-DD HH:mm:ss'), }, - { prop: 'equipmentName', label: '设备', align: 'center' }, - { prop: 'groupName', label: '分组', align: 'center' }, + { prop: 'equipmentName', label: '设备' }, + { prop: 'groupName', label: '分组' }, { _action: 'equipment-bind-group-show-alert', label: '分组报警', - align: 'center', subcomponent: { props: ['injectData'], render: function (h) { @@ -98,7 +98,7 @@ export default { return h( 'el-button', { - props: { type: 'text', size: 'mini' }, + props: { type: 'text' }, on: { click: function () { console.log('inejctdata', _this.injectData); @@ -162,6 +162,9 @@ export default { label: '设备', url: '/base/equipment/page?pageNo=1&pageSize=100', prop: 'equipmentId', + bind: { + filterable: true, + }, rules: [{ required: true, message: '不能为空', trigger: 'blur' }], }, ], @@ -173,6 +176,9 @@ export default { // depends: '__product_line', // 依赖产线获取数据 // depends: 'productionLineId', prop: 'groupId', + bind: { + filterable: true, + }, rules: [{ required: true, message: '不能为空', trigger: 'blur' }], }, ], @@ -223,7 +229,7 @@ export default { /** 查询列表 */ getList() { this.loading = true; - _// 执行查询 + _; // 执行查询 getEquipmentBindGroupPage(this.queryParams).then((response) => { this.list = response.data.list; this.total = response.data.total; diff --git a/src/views/base/equipmentBindSection/index.vue b/src/views/base/equipmentBindSection/index.vue index cb46db05..405c7393 100644 --- a/src/views/base/equipmentBindSection/index.vue +++ b/src/views/base/equipmentBindSection/index.vue @@ -17,6 +17,7 @@ v-if="tableBtn.length" slot="handleBtn" label="操作" + :width="120" :method-list="tableBtn" @clickBtn="handleTableBtnClick" /> @@ -83,28 +84,26 @@ export default { width: 180, filter: (val) => moment(val).format('yyyy-MM-DD HH:mm:ss'), }, - { prop: 'productionLine', label: '产线名称', align: 'center' }, - { prop: 'workshopSection', label: '工段名称', align: 'center' }, - { prop: 'equipment', label: '设备名称', align: 'center' }, - { prop: 'sort', label: '工段中排序', align: 'center' }, + { prop: 'productionLine', label: '产线名称' }, + { prop: 'workshopSection', label: '工段名称' }, + { prop: 'equipment', label: '设备名称' }, + { prop: 'sort', label: '工段中排序' }, { prop: 'lineDataType', label: '产线数据类型', - align: 'center', filter: (val) => val != null ? ['无类型', '进口计数', '出口计数'][val] : '-', }, { prop: 'sectionDataType', label: '工段数据类型', - align: 'center', filter: (val) => val != null ? ['无类型', '进口计数', '出口计数'][val] : '-', }, // { // action: 'show-alert', // label: '报警', - // align: 'center', + // , // subcomponent: { // props: ['injectData'], // render: function (h) { diff --git a/src/views/base/equipmentGroup/index.vue b/src/views/base/equipmentGroup/index.vue index ae10d52a..24d248fe 100644 --- a/src/views/base/equipmentGroup/index.vue +++ b/src/views/base/equipmentGroup/index.vue @@ -17,6 +17,7 @@ v-if="tableBtn.length" slot="handleBtn" label="操作" + :width="120" :method-list="tableBtn" @clickBtn="handleTableBtnClick" /> @@ -84,13 +85,12 @@ export default { width: 180, filter: (val) => moment(val).format('yyyy-MM-DD HH:mm:ss'), }, - { prop: 'name', label: '设备分组名称', align: 'center' }, - { prop: 'code', label: '检测分组编码', align: 'center' }, - { prop: 'remark', label: '备注', align: 'center' }, + { prop: 'name', label: '设备分组名称' }, + { prop: 'code', label: '设备分组编码' }, + { prop: 'remark', label: '备注' }, { _action: 'equipment-group-show-alert', label: '报警', - align: 'center', subcomponent: { props: ['injectData'], render: function (h) { @@ -98,7 +98,7 @@ export default { return h( 'el-button', { - props: { type: 'text', size: 'mini' }, + props: { type: 'text' }, on: { click: function () { console.log('inejctdata', _this.injectData); @@ -127,7 +127,7 @@ export default { type: 'input', label: '分组编码', placeholder: '请输入设备分组编码', - param: 'codes', + param: 'code', }, { type: 'button', @@ -172,6 +172,7 @@ export default { label: '分组编码', prop: 'code', url: '/base/equipment-group/getCode', + rules: [{ required: true, message: '不能为空', trigger: 'blur' }], }, ], [ @@ -302,11 +303,7 @@ export default { handleDelete(row) { const id = row.id; this.$modal - .confirm( - '是否确认删除设备分组(用于同类型不同厂家的设备区分)编号为"' + - id + - '"的数据项?' - ) + .confirm('是否确认删除设备分组 "' + row.name + '"?') .then(function () { return deleteEquipmentGroup(id); }) diff --git a/src/views/base/equipmentGroupAlarm/dialogForm.vue b/src/views/base/equipmentGroupAlarm/dialogForm.vue new file mode 100644 index 00000000..a0b9f55e --- /dev/null +++ b/src/views/base/equipmentGroupAlarm/dialogForm.vue @@ -0,0 +1,177 @@ + + + + + + + diff --git a/src/views/base/equipmentGroupAlarm/index.vue b/src/views/base/equipmentGroupAlarm/index.vue index 01fd0821..dda58f82 100644 --- a/src/views/base/equipmentGroupAlarm/index.vue +++ b/src/views/base/equipmentGroupAlarm/index.vue @@ -17,6 +17,7 @@ v-if="tableBtn.length" slot="handleBtn" label="操作" + :width="120" :method-list="tableBtn" @clickBtn="handleTableBtnClick" /> @@ -37,7 +38,7 @@ @close="cancel" @cancel="cancel" @confirm="submitForm"> - + @@ -54,10 +55,11 @@ import { import basicPageMixin from '@/mixins/lb/basicPageMixin'; import moment from 'moment'; import { publicFormatter } from '@/utils/dict'; +import DialogForm from './dialogForm.vue'; export default { name: 'EquipmentGroupAlarm', - components: {}, + components: { DialogForm }, mixins: [basicPageMixin], data() { return { @@ -84,22 +86,27 @@ export default { width: 180, filter: (val) => moment(val).format('yyyy-MM-DD HH:mm:ss'), }, - { prop: 'code', label: '报警编码', align: 'center' }, - { prop: 'type', label: '报警类型', align: 'center' }, + { width: 240, prop: 'code', label: '报警编码' }, + { + prop: 'type', + label: '报警类型', + filter: (val) => + val != null ? ['-', '字符型', '布尔型', '-'][val] : '-', + }, { prop: 'grade', label: '报警级别', - align: 'center', filter: publicFormatter(this.DICT_TYPE.EQU_ALARM_LEVEL), }, - { prop: 'alarmCode', label: '设备报警编码', align: 'center' }, - { prop: 'plcParamName', label: '参数列名', align: 'center' }, - { prop: 'alarmContent', label: '报警内容', align: 'center' }, + { prop: 'alarmCode', label: '设备报警编码' }, + { prop: 'plcParamName', label: '参数列名' }, + { prop: 'alarmContent', label: '报警内容' }, ], searchBarFormConfig: [ { type: 'input', label: '设备分组编码', + width: '220', placeholder: '/', param: 'equipmentGroupCode', defaultSelect: null, @@ -181,14 +188,14 @@ export default { }, // 表单参数 form: { - id: undefined, - equipmentGroupId: undefined, - code: undefined, - type: undefined, - grade: undefined, - alarmCode: undefined, - alarmContent: undefined, - plcParamName: undefined, + id: null, + equipmentGroupId: null, + code: null, + type: null, + grade: null, + alarmCode: null, + alarmContent: null, + plcParamName: null, }, // // 表单校验 // rules: { @@ -249,14 +256,14 @@ export default { /** 表单重置 */ reset() { this.form = { - id: undefined, - equipmentGroupId: undefined, - code: undefined, - type: undefined, - grade: undefined, - alarmCode: undefined, - alarmContent: undefined, - plcParamName: undefined, + id: null, + equipmentGroupId: null, + code: null, + type: null, + grade: null, + alarmCode: null, + alarmContent: null, + plcParamName: null, }; this.resetForm('form'); }, @@ -321,7 +328,7 @@ export default { handleDelete(row) { const id = row.id; this.$modal - .confirm('是否确认删除设备分组报警明细编号为"' + id + '"的数据项?') + .confirm('是否确认删除该报警?') .then(function () { return deleteEquipmentGroupAlarm(id); }) diff --git a/src/views/base/equipmentPlc/index.vue b/src/views/base/equipmentPlc/index.vue index c8327042..59c6fa71 100644 --- a/src/views/base/equipmentPlc/index.vue +++ b/src/views/base/equipmentPlc/index.vue @@ -12,6 +12,7 @@ :page="queryParams.pageNo" :limit="queryParams.pageSize" :table-data="list" + ref="pageTable" @emitFun="handleEmitFun"> { - this.active = !this.active; - console.log('changed emit', newVal); this.$emit('emitData', { action: 'update-collect', payload: { @@ -95,6 +97,7 @@ export default { components: {}, data() { return { + tableKey: Math.random(), searchBarKeys: ['name', 'plcTableName'], tableBtn: [ this.$auth.hasPermi('base:equipment-plc:update') @@ -118,17 +121,16 @@ export default { // width: 180, // filter: (val) => moment(val).format('yyyy-MM-DD HH:mm:ss'), // }, - { prop: 'code', label: '编码', align: 'center' }, - { prop: 'plcTableName', label: '关联表名', align: 'center' }, - { prop: 'name', label: '标识名称', align: 'center' }, - { prop: 'enName', label: '英文名称', align: 'center' }, + { prop: 'code', label: '编码' }, + { prop: 'plcTableName', label: '关联表名' }, + { prop: 'name', label: '标识名称' }, + { prop: 'enName', label: '英文名称' }, { prop: 'collection', label: '是否采集', - align: 'center', subcomponent: switchBtn, }, - { prop: 'description', label: '描述', align: 'center' }, + { prop: 'description', label: '描述' }, ], searchBarFormConfig: [ { @@ -185,6 +187,7 @@ export default { label: '编码', prop: 'code', url: '/base/equipment-group/getCode', + rules: [{ required: true, message: '不能为空', trigger: 'blur' }], }, ], [ @@ -192,7 +195,7 @@ export default { input: true, label: '标识', prop: 'name', - // rules: [{ required: true, message: '不能为空', trigger: 'blur' }], + rules: [{ required: true, message: '不能为空', trigger: 'blur' }], // bind: { // disabled: true, // some condition, like detail mode... // } @@ -246,7 +249,7 @@ export default { handleEmitFun({ action, payload }) { switch (action) { case 'update-collect': - this.reset(); + this.reset(); const tempForm = {}; Object.keys(this.form).forEach((key) => { tempForm[key] = payload[key]; @@ -267,6 +270,7 @@ export default { this.list = response.data.list; this.total = response.data.total; this.loading = false; + // this.tableKey = Math.random(); // method 1 }); }, /** 取消按钮 */ diff --git a/src/views/base/equipmentPlcConnect/index.vue b/src/views/base/equipmentPlcConnect/index.vue index 7554b9af..e6022379 100644 --- a/src/views/base/equipmentPlcConnect/index.vue +++ b/src/views/base/equipmentPlcConnect/index.vue @@ -17,6 +17,7 @@ v-if="tableBtn.length" slot="handleBtn" label="操作" + :width="120" :method-list="tableBtn" @clickBtn="handleTableBtnClick" /> @@ -61,7 +62,7 @@ export default { components: {}, data() { return { - searchBarKeys: ['name', 'plcTableName'], + searchBarKeys: ['equipmentId', 'plcId'], // tableBtn: [ // this.$auth.hasPermi('base:equipment-plc:update') // ? { @@ -98,18 +99,17 @@ export default { // width: 180, // filter: (val) => moment(val).format('yyyy-MM-DD HH:mm:ss'), // }, - { prop: 'productionLine', label: '产线', align: 'center' }, - { prop: 'workshopSection', label: '工段', align: 'center' }, - { prop: 'equipmentName', label: '设备名', align: 'center' }, - { prop: 'equipmentCode', label: '设备编码', align: 'center' }, - { prop: 'plcCode', label: '关联表编码', align: 'center' }, - { prop: 'plcTableName', label: '关联表名', align: 'center' }, - { prop: 'plcName', label: '标识名称', align: 'center' }, - { prop: 'bindingParameters', label: '绑定参数数量', align: 'center' }, + { prop: 'productionLine', label: '产线' }, + { prop: 'workshopSection', label: '工段' }, + { prop: 'equipmentName', label: '设备名' }, + { prop: 'equipmentCode', label: '设备编码' }, + { prop: 'plcCode', label: '关联表编码' }, + { prop: 'plcTableName', label: '关联表名' }, + { prop: 'plcName', label: '标识名称' }, + { prop: 'bindingParameters', label: '绑定参数数量' }, { _action: 'params-bind', label: '查看绑定', - align: 'center', subcomponent: { props: ['injectData'], render: function (h) { @@ -136,16 +136,18 @@ export default { ], searchBarFormConfig: [ { - type: 'input', + type: 'select', label: '设备名', - placeholder: '请输入设备名', + placeholder: '请选择设备', param: 'equipmentId', + selectOptions: [], }, { - type: 'input', - label: '编码', - placeholder: '请输入编码', + type: 'select', + label: 'PLC编码', + placeholder: '请选择编码', param: 'plcId', + selectOptions: [], }, { type: 'button', @@ -179,6 +181,7 @@ export default { select: true, label: '关联表名', prop: 'plcId', + labelKey: `plcTableName`, url: '/base/equipment-plc/listAll', rules: [{ required: true, message: '不能为空', trigger: 'blur' }], }, @@ -207,8 +210,44 @@ export default { }, created() { this.getList(); + this.initSearchOptions(); }, methods: { + async getEquipmentOptions() { + const res = await this.$axios({ + url: '/base/equipment/listAll', + method: 'get', + }); + return res.data; + }, + + async getPlcOptions() { + const res = await this.$axios({ + url: '/base/equipment-plc/listAll', + method: 'get', + }); + return res.data; + }, + + /** 初始化查询条件 */ + async initSearchOptions() { + Promise.all([this.getEquipmentOptions(), this.getPlcOptions()]).then( + ([eqList, plcList]) => { + this.searchBarFormConfig[0].selectOptions = eqList.map((item) => { + return { + name: item.name, + id: item.id, + }; + }); + this.searchBarFormConfig[1].selectOptions = plcList.map((item) => { + return { + name: item.name, + id: item.id, + }; + }); + } + ); + }, /** 覆盖 handleEmitFun 的默认实现 */ handleEmitFun({ action, payload }) { switch (action) { diff --git a/src/views/base/equipmentPlcParam/index.vue b/src/views/base/equipmentPlcParam/index.vue index 161b1b76..6d932706 100644 --- a/src/views/base/equipmentPlcParam/index.vue +++ b/src/views/base/equipmentPlcParam/index.vue @@ -17,6 +17,7 @@ v-if="tableBtn.length" slot="handleBtn" label="操作" + :width="120" :method-list="tableBtn" @clickBtn="handleTableBtnClick" /> @@ -68,29 +69,27 @@ export default { // width: 180, // filter: (val) => moment(val).format('yyyy-MM-DD HH:mm:ss'), // }, - { prop: 'plcParamName', label: '参数列名', align: 'center' }, - { prop: 'name', label: '参数名称', align: 'center' }, + { prop: 'plcParamName', label: '参数列名' }, + { prop: 'name', label: '参数名称' }, { prop: 'unit', label: '单位', - align: 'center', filter: publicFormatter('unit_dict'), }, { prop: 'collection', label: '是否采集', - align: 'center', filter: (val) => (val != null ? ['否', '是'][val] : '-'), }, - { prop: 'minValue', label: '最小值', align: 'center' }, - { prop: 'maxValue', label: '最大值', align: 'center' }, - { prop: 'defaultValue', label: '标准值', align: 'center' }, - { prop: 'description', label: '描述', align: 'center' }, - { prop: 'remark', label: '备注', align: 'center' }, + { prop: 'minValue', label: '最小值' }, + { prop: 'maxValue', label: '最大值' }, + { prop: 'defaultValue', label: '标准值' }, + { prop: 'description', label: '描述' }, + { prop: 'remark', label: '备注' }, // { // _action: 'params-bind', // label: '查看绑定', - // align: 'center', + // , // subcomponent: { // props: ['injectData'], // render: function (h) { @@ -157,7 +156,7 @@ export default { { type: 'number', message: '请输入正确的数字', - trigger: 'blur', + trigger: 'change', transform: (val) => Number(val), }, ], @@ -167,10 +166,13 @@ export default { label: '最大值', prop: 'maxValue', rules: [ + { + required: false, + }, { type: 'number', message: '请输入正确的数字', - trigger: 'blur', + trigger: 'change', transform: (val) => Number(val), }, ], @@ -349,8 +351,8 @@ export default { plcParamName: undefined, name: undefined, unit: undefined, - minValue: undefined, - maxValue: undefined, + minValue: null, + maxValue: null, defaultValue: undefined, collection: undefined, description: undefined, diff --git a/src/views/core/base/equipment/index.vue b/src/views/core/base/equipment/index.vue index b031cd65..1e428def 100644 --- a/src/views/core/base/equipment/index.vue +++ b/src/views/core/base/equipment/index.vue @@ -16,6 +16,7 @@ @@ -147,15 +148,14 @@ export default { width: 180, filter: (val) => moment(val).format('yyyy-MM-DD HH:mm:ss'), }, - { prop: 'name', label: '设备名称', align: 'center' }, - { prop: 'code', label: '检测编码', align: 'center' }, - { prop: 'equipmentType', label: '设备类型', align: 'center' }, - { prop: 'enName', label: '英文名称', align: 'center' }, - { prop: 'abbr', label: '缩写', align: 'center' }, + { prop: 'name', label: '设备名称' }, + { width: 256, prop: 'code', label: '检测编码' }, + { prop: 'equipmentType', label: '设备类型' }, + { prop: 'enName', label: '英文名称' }, + { prop: 'abbr', label: '缩写' }, { action: 'show-detail', label: '详情', - align: 'center', subcomponent: { props: ['injectData'], render: function (h) { @@ -377,8 +377,8 @@ export default { width: 180, filter: (val) => moment(val).format('yyyy-MM-DD HH:mm:ss'), }, - { prop: 'name', label: '属性名称', align: 'center' }, - { prop: 'value', label: '属性值', align: 'center' }, + { prop: 'name', label: '属性名称' }, + { prop: 'value', label: '属性值' }, ], // 是否显示弹出层 open: false, diff --git a/src/views/core/base/equipmentType/index.vue b/src/views/core/base/equipmentType/index.vue index 8790f426..70633ce6 100644 --- a/src/views/core/base/equipmentType/index.vue +++ b/src/views/core/base/equipmentType/index.vue @@ -17,6 +17,7 @@ v-if="tableBtn.length" slot="handleBtn" label="操作" + :width="120" :method-list="tableBtn" @clickBtn="handleTableBtnClick" /> @@ -85,9 +86,9 @@ export default { width: 180, filter: (val) => moment(val).format('yyyy-MM-DD HH:mm:ss'), }, - { prop: 'name', label: '设备类型名称', align: 'center' }, - { prop: 'code', label: '检测类型编码', align: 'center' }, - { prop: 'remark', label: '备注', align: 'center' }, + { prop: 'name', label: '设备类型名称', }, + { prop: 'code', label: '检测类型编码', }, + { prop: 'remark', label: '备注', }, ], searchBarFormConfig: [ { diff --git a/src/views/equipment/analysis/efficiency/components/pieChart.vue b/src/views/equipment/analysis/efficiency/components/pieChart.vue index 74db4ada..e051f341 100644 --- a/src/views/equipment/analysis/efficiency/components/pieChart.vue +++ b/src/views/equipment/analysis/efficiency/components/pieChart.vue @@ -6,7 +6,34 @@ --> diff --git a/src/views/equipment/analysis/efficiency/index.vue b/src/views/equipment/analysis/efficiency/index.vue index 23ebb70c..3f2e2853 100644 --- a/src/views/equipment/analysis/efficiency/index.vue +++ b/src/views/equipment/analysis/efficiency/index.vue @@ -13,46 +13,64 @@ ref="search-bar" @headBtnClick="handleSearchBarBtnClick" /> - - - - - + + + + + + + + +
+
各设备加工数量
+
+
+ + 工作时长 +
+
+ + 停机时长 +
+
+ + 故障时长 +
+
+ + 速度开动率 +
+
+
+
+
+
- - - - - -
- -
-
-

查看趋势

-
-
+
+ + +
+
+
+
+
+
+
@@ -68,6 +86,7 @@ export default { props: {}, data() { return { + activeName: 'table', open: false, visualizationOpen: false, trendOpen: false, @@ -86,84 +105,72 @@ export default { // : undefined, // ].filter((v) => v), tableProps: [ - { prop: 'factoryName', label: '工厂', align: 'center' }, - { prop: 'lineName', label: '产线', align: 'center' }, - { prop: 'sectionName', label: '工段', align: 'center' }, - { prop: 'equipmentName', label: '设备', align: 'center' }, + { prop: 'factoryName', label: '工厂' }, + { prop: 'lineName', label: '产线' }, + { prop: 'sectionName', label: '工段' }, + { prop: 'equipmentName', label: '设备' }, { label: '有效时间', - align: 'center', children: [ { width: 128, prop: 'workTime', label: '工作时长', - align: 'center', }, { width: 128, prop: 'workRate', label: '百分比', - align: 'center', filter: (val) => (val != null ? +val.toFixed(3) : '-'), }, ], }, { label: '关机时间', - align: 'center', children: [ { width: 128, prop: 'stopTime', label: '停机时长', - align: 'center', }, - { width: 128, prop: 'stopRate', label: '百分比', align: 'center' }, + { width: 128, prop: 'stopRate', label: '百分比' }, ], }, { label: '中断损失', - align: 'center', children: [ { width: 128, prop: 'downTime', label: '故障时长', - align: 'center', filter: (val) => (val != null ? +val.toFixed(3) : '-'), }, - { width: 128, prop: 'downRate', label: '百分比', align: 'center' }, + { width: 128, prop: 'downRate', label: '百分比' }, { width: 128, prop: 'timeEfficiency', label: '时间开动率', - align: 'center', filter: (val) => (val != null ? +val.toFixed(3) : '-'), }, ], }, { label: '速度损失', - align: 'center', children: [ { width: 128, prop: 'realProcSpeed', label: '实际加工速度', - align: 'center', }, { width: 128, prop: 'designProcSpeed', label: '理论加工速度', - align: 'center', }, { width: 128, prop: 'peEfficiency', label: '速度开动率', - align: 'center', filter: (val) => (val != null ? +val.toFixed(3) : '-'), }, ], @@ -171,19 +178,17 @@ export default { { prop: 'oee', label: 'OEE', - align: 'center', filter: (val) => (val != null ? +val.toFixed(3) : '-'), }, { prop: 'teep', label: 'TEEP', - align: 'center', filter: (val) => (val != null ? +val.toFixed(3) : '-'), }, // { // _action: 'view-trend', // label: '趋势', - // align: 'center', + // , // subcomponent: { // props: ['injectData'], // render: function (h) { @@ -240,7 +245,7 @@ export default { parent: 'dateFilterType', // 时间段选择 type: 'datePicker', - label: '时间段', + // label: '时间段', dateType: 'daterange', format: 'yyyy-MM-dd', valueFormat: 'yyyy-MM-dd HH:mm:ss', @@ -254,7 +259,7 @@ export default { parent: 'dateFilterType', // 日期选择 type: 'datePicker', - label: '日期', + // label: '日期', dateType: 'date', placeholder: '选择日期', format: 'yyyy-MM-dd', @@ -269,16 +274,16 @@ export default { name: 'search', color: 'primary', }, - { - type: 'separate', - }, - { - type: 'button', - btnName: '设备可视化', - name: 'visualization', - plain: true, - color: 'success', - }, + // { + // type: 'separate', + // }, + // { + // type: 'button', + // btnName: '设备可视化', + // name: 'visualization', + // plain: true, + // color: 'success', + // }, // { // type: 'button', // btnName: 'OEE', @@ -364,7 +369,6 @@ export default { params: this.queryParams, }); if (code == 0) { - console.log('data', data); this.list = data; } }, @@ -407,6 +411,8 @@ export default { }, submitForm() {}, + + handleTabClick() {}, }, }; @@ -416,4 +422,141 @@ export default { display: grid; grid-template-columns: repeat(3, minmax(240px, 1fr)); } + +:deep(.custom-tabs) { + .el-tabs__header { + margin-bottom: 8px; + display: inline-block; + transform: translateY(-12px); + } + + .el-tabs__item { + padding-left: 0 !important; + padding-right: 0 !important; + line-height: 36px !important; + height: 36px; + } +} + +.blue-title { + position: relative; + padding: 4px 0; + padding-left: 12px; + font-size: 14px; + + &::before { + content: ''; + position: absolute; + left: 0; + top: 6px; + height: 16px; + width: 4px; + border-radius: 1px; + background: #0b58ff; + } +} + +.graph-grid { + margin-top: 8px; + padding: 12px; + position: relative; + border-radius: 12px; + border: 1px solid #ccc; + // background: #0003; +} +.bg-grid { + display: grid; + place-content: center; + grid-template-columns: repeat(4, minmax(280px, 1fr)); + grid-auto-columns: 280px; + grid-auto-rows: 290px; + overflow: hidden; + position: relative; +} + +.grid-line::after { + content: ''; + position: absolute; + top: -1px; + left: -1px; + width: calc(100% + 2px); + height: calc(100% + 2px); + display: inline-block; + border: 8px solid #fff; +} + +.grid-charts { + position: absolute; + width: calc(100% - 24px); + top: 12px; + left: 12px; +} + +.grid-item { + border: 1px solid #ccc; +} + +.grid-item:not(:first-child) { + border-left: 0; + border-top: 0; +} + +.legend { + position: absolute; + top: 8px; + right: 12px; + display: flex; +} + +.legend .legend-item { + display: flex; + align-items: center; + margin-left: 12px; +} + +.legend .legend-item .icon { + width: 10px; + height: 10px; + border-radius: 1px; + margin-right: 4px; + margin-top: 1px; +} + +.legend .legend-item .text { + color: #8c8c8c; +} + +.blue { + background-color: #3da8fd; +} + +.green { + background-color: #8ef0ab; +} + +.purple { + background-color: #6b5cfd; +} + +.yellow { + background-color: #ffc72a; +} + +@media screen and (max-width: 1390px) { + .bg-grid { + grid-template-columns: repeat(3, minmax(280px, 1fr)); + } +} + +@media screen and (max-width: 1190px) { + .bg-grid { + grid-template-columns: repeat(2, minmax(280px, 1fr)); + } +} + +@media screen and (max-width: 640px) { + .bg-grid { + grid-template-columns: repeat(1, minmax(280px, 1fr)); + } +} diff --git a/src/views/equipment/analysis/exception/index.vue b/src/views/equipment/analysis/exception/index.vue index c8246cdb..a7afb2df 100644 --- a/src/views/equipment/analysis/exception/index.vue +++ b/src/views/equipment/analysis/exception/index.vue @@ -50,39 +50,47 @@ export default { data() { return { searchBarKeys: ['name', 'code'], + // tableBtn: [ + // this.$auth.hasPermi('base:equipment-group:update') + // ? { + // type: 'edit', + // btnName: '修改', + // } + // : undefined, + // this.$auth.hasPermi('base:equipment-group:delete') + // ? { + // type: 'delete', + // btnName: '删除', + // } + // : undefined, + // ].filter((v) => v), tableBtn: [ - this.$auth.hasPermi('base:equipment-group:update') - ? { - type: 'edit', - btnName: '修改', - } - : undefined, - this.$auth.hasPermi('base:equipment-group:delete') - ? { - type: 'delete', - btnName: '删除', - } - : undefined, - ].filter((v) => v), - tableProps: [ - { prop: 'lineName', label: '产线', align: 'center' }, - { prop: 'sectionName', label: '工段', align: 'center' }, - { prop: 'equipmentName', label: '设备', align: 'center' }, { - width: 188, + type: 'edit', + btnName: '修改', + }, + { + type: 'delete', + btnName: '删除', + }, + ], + tableProps: [ + { prop: 'lineName', label: '产线' }, + { prop: 'sectionName', label: '工段' }, + { prop: 'equipmentName', label: '设备' }, + { + width: 240, prop: 'mtbf', label: '平均故障间隔时间[MTBF](h)', - align: 'center', }, { - width: 180, + width: 240, prop: 'mttr', label: '平均维修时间[MTTR](h)', - align: 'center', }, - { prop: 'workTime', label: '工作时长(h)', align: 'center' }, - { prop: 'downTime', label: '故障时长(h)', align: 'center' }, - { prop: 'downCount', label: '故障次数', align: 'center' }, + { width: 128, prop: 'workTime', label: '工作时长(h)' }, + { width: 128, prop: 'downTime', label: '故障时长(h)' }, + { prop: 'downCount', label: '故障次数' }, ], searchBarFormConfig: [ { @@ -113,6 +121,8 @@ export default { ], // 查询参数 queryParams: { + pageNo: 1, + pageSize: 10, lineId: null, factoryId: null, recordTime: null, @@ -162,15 +172,13 @@ export default { this.queryParams.recordTime = [ moment() .month(btn.month - 1) - .format('YYYY-MM')+'-01 00:00:00', - moment() - .month(btn.month) - .format('YYYY-MM')+'-01 00:00:00', + .format('YYYY-MM') + '-01 00:00:00', + moment().month(btn.month).format('YYYY-MM') + '-01 00:00:00', ]; } else { this.queryParams.recordTime = null; } - this.queryParams.lineId = btn.lineId || null; + this.queryParams.lineId = btn.lineId || null; this.handleQuery(); break; } diff --git a/src/views/equipment/analysis/quality/components/lineChart.vue b/src/views/equipment/analysis/quality/components/lineChart.vue index f3a93bc8..b91b93f1 100644 --- a/src/views/equipment/analysis/quality/components/lineChart.vue +++ b/src/views/equipment/analysis/quality/components/lineChart.vue @@ -15,27 +15,143 @@ import * as echarts from 'echarts'; export default { name: 'LineChart', components: {}, - props: ['config'], + props: ['config', 'list'], data() { return { chart: null, }; }, - computed: {}, + // watch: { + // list: { + // handler(listdata) { + // if (listdata && listdata.length) { + // console.log('[linechart] list changed', listdata); + // const option = this.handleList(listdata); + // this.setOption(option); + // } + // }, + // immediate: true, + // }, + // }, + computed: { + option() { + const opt = []; + this.list.map((eq) => { + /** [设备名, ok数量, 不ok数量] */ + opt.push([eq.equipmentName, eq.okQuantity, eq.nokQuantity]); + }); + return { + color: ['#288AFF', '#8EF0AB'], + tooltip: { + trigger: 'axis', + axisPointer: { + type: 'shadow', + }, + }, + legend: { + itemWidth: 12, + itemHeight: 12, + right: 0 + }, + grid: { + left: '1%', + right: '1%', + top: '8%', + bottom: '3%', + containLabel: true, + }, + // xAxis: [ + // { + // type: 'category', + // data: ['设备1', '设备2', '设备3', '设备4', '设备5'], + // }, + // ], + // yAxis: [ + // { + // type: 'value', + // splitLine: { + // lineStyle: { + // color: '#0001', + // }, + // }, + // }, + // ], + xAxis: { + type: 'category', + axisTick: { show: false }, + data: opt.map((item) => item[0]), + }, + yAxis: { + type: 'value', + splitLine: { + lineStyle: { + color: '#0001', + }, + }, + }, + series: [ + { + name: '合格数量', + type: 'bar', + barWidth: 20, + stack: 's', + data: opt.map((item) => item[1]), + }, + { + name: '不合格数量', + type: 'bar', + barWidth: 20, + stack: 's', + data: opt.map((item) => item[2]), + }, + ], + }; + }, + }, mounted() { + console.log('[linechart] mounted'); this.init(); }, beforeDestroy() { if (this.chart) { this.chart.dispose(); } + console.log('[linechart] destroyed'); }, methods: { init() { - console.log('thsi el', this.$el); if (!this.chart) this.chart = echarts.init(this.$el); - this.chart.setOption(this.config); + console.log('[linechart] initialized', this.$el); + this.$nextTick(() => { + this.setOption(); + }); }, + + setOption() { + if (this.chart) this.chart.setOption(this.option); + console.log('[linechart] option settled'); + }, + + // handleList(list) { + // /** 清空数据 */ + // this.option.series[0].data.splice(0); + // this.option.series[1].data.splice(0); + // this.option.xAxis.data.splice(0); + + // list.map((eq) => { + // this.option.xAxis.data.push(eq.equipmentName); + // this.option.series[0].data.push(eq.nokQuantity); + // this.option.series[1].data.push(eq.okQuantity); + // }); + + // this.setOption(); + + // // const pureList = list.map((eq) => ({ + // // name: eq.equipmentName, + // // ok: eq.okQuantity, + // // nok: eq.nokQuantity, + // // })); + // }, }, }; @@ -43,7 +159,7 @@ export default { diff --git a/src/views/equipment/analysis/quality/index.vue b/src/views/equipment/analysis/quality/index.vue index 2f9dcae2..bec2ed0a 100644 --- a/src/views/equipment/analysis/quality/index.vue +++ b/src/views/equipment/analysis/quality/index.vue @@ -13,28 +13,35 @@ ref="search-bar" @headBtnClick="handleSearchBarBtnClick" /> - - - - - + + + + + + + + +
+
各设备加工数量
+ +
+
+
+
+
- + diff --git a/src/views/equipment/timing-diagram/status/index.vue b/src/views/equipment/timing-diagram/status/index.vue index 2aafc1c6..ac4769a9 100644 --- a/src/views/equipment/timing-diagram/status/index.vue +++ b/src/views/equipment/timing-diagram/status/index.vue @@ -6,29 +6,51 @@ --> @@ -139,19 +141,16 @@ export default { width: 48, prop: 'index', label: '序号', - align: 'center', }, { width: 160, prop: 'time', label: '时间', - align: 'center', }, { width: 200, prop: 'plcCode', label: 'PLC编码', - align: 'center', }, ]; const firstLineData = { @@ -162,7 +161,6 @@ export default { otherList.forEach((item) => { props.push({ label: item.name, - align: 'center', prop: item.name, width: 128, }); diff --git a/src/views/monitoring/equipmentProcessAmount/graph.vue b/src/views/monitoring/equipmentProcessAmount/graph.vue index 7d6843cb..907313d2 100644 --- a/src/views/monitoring/equipmentProcessAmount/graph.vue +++ b/src/views/monitoring/equipmentProcessAmount/graph.vue @@ -17,15 +17,16 @@ import * as echarts from 'echarts'; export default { name: 'LineChartInEquipmentProcessAmount', components: {}, - props: ['equipmentList'], + props: ['equipmentList', 'render'], data() { return { chart: null, option: { + color: ['#288AFF'], grid: { top: 64, left: 56, - right: 24, + right: 64, bottom: 56, }, title: { @@ -64,6 +65,10 @@ export default { color: '#ccc', }, }, + name: '数量', + nameTextStyle: { + fontSize: 14, + }, }, series: [ { @@ -85,16 +90,19 @@ export default { }, }; }, - mounted() { - // console.log('this.eq list', this.equipmentList); - if (!this.chart) this.chart = echarts.init(this.$refs.chart); - - this.$nextTick(() => { - this.chart.setOption(this.updateConfig(this.option)); - }); + watch: { + render: { + handler: function (newVal, oldVal) { + if (!this.chart) this.chart = echarts.init(this.$refs.chart); + this.$nextTick(() => { + if (this.chart) this.chart.setOption(this.updateConfig(this.option)); + }); + }, + deep: true, + }, }, beforeDestroy() { - this.chart.dispose(); + if (this.chart) this.chart.dispose(); }, methods: { updateConfig(config) { @@ -122,5 +130,6 @@ export default { .chart { height: 100%; width: 100%; + // background: lightcoral; } diff --git a/src/views/monitoring/equipmentProcessAmount/index.vue b/src/views/monitoring/equipmentProcessAmount/index.vue index 4119be8d..2acb6635 100644 --- a/src/views/monitoring/equipmentProcessAmount/index.vue +++ b/src/views/monitoring/equipmentProcessAmount/index.vue @@ -9,15 +9,52 @@
- + style=" + margin-right: 12px; + border-radius: 8px; + background: #fff; + padding: 0; + "> + +
- - - - + + + +
+ + +
+ 没有设备 +
+
+
+ + + -
- - -
没有设备
-
-
+
@@ -66,6 +123,17 @@ export default { props: {}, data() { return { + renderKey: Math.random(), + factoryListOpen: false, + currentFactory: null, + factoryList: [ + { name: '1', value: 1 }, + { name: '2', value: 2 }, + { name: '3', value: 3 }, + { name: '4', value: 4 }, + { name: '5', value: 5 }, + { name: '6', value: 6 }, + ], sidebarContent: [ // { // id: 'fc1', @@ -152,6 +220,7 @@ export default { // ], // }, ], + activeName: 'table', searchBarFormConfig: [ { type: 'datePicker', @@ -172,23 +241,23 @@ export default { 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: '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: '导出', @@ -197,11 +266,11 @@ export default { // }, ], 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' }, + { prop: 'lineName', label: '产线' }, + { prop: 'sectionName', label: '工段' }, + { prop: 'externalCode', label: '设备编码' }, + { prop: 'equipmentName', label: '设备名称' }, + { prop: 'totalQuantity', label: '加工数量' }, ], mode: 'table', // table | graph queryParams: { @@ -230,20 +299,20 @@ export default { this.$set(factory, 'label', factory.name); this.$set(factory, 'type', '工厂'); delete factory.name; - factory.children = factory.lines; - delete factory.lines; + // 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 = 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 = ws.equipments; + // delete ws.equipments; ws.children?.forEach((eq) => { this.$set(eq, 'label', eq.name); this.$set(eq, 'type', '设备'); @@ -258,10 +327,22 @@ export default { const { data } = await this.$axios('/base/factory/getTree'); this.sidebarContent = data; this.buildTree(data); + console.log('tree', this.sidebarContent); + }, + + handleTabClick(tab, event) { + if (tab.name == 'graph') this.renderKey = Math.random(); + }, + + factoryChangeHandler(event) { + this.factoryListOpen = false; + const fcId = event.target.dataset.value; + this.handleSidebarItemClick({ id: fcId, type: '工厂' }); + this.currentFactory = this.sidebarContent.find((item) => item.id == fcId); }, handleSidebarItemClick({ label, id, type }) { - console.log('lable clicked!', label, id, type); + console.log('label clicked!', label, id, type); switch (type) { case '设备': this.queryParams.equipmentId = id; @@ -317,8 +398,10 @@ export default { + + diff --git a/src/views/monitoring/equipmentRecentHours/index.vue b/src/views/monitoring/equipmentRecentHours/index.vue index c4cf6b6b..79ea99db 100644 --- a/src/views/monitoring/equipmentRecentHours/index.vue +++ b/src/views/monitoring/equipmentRecentHours/index.vue @@ -11,14 +11,16 @@ :formConfigs="[{ label: '设备近24小时生产记录', type: 'title' }]" ref="search-bar" /> - - +
+ + +
@@ -37,6 +39,7 @@ export default { list: [], tableProps: [], spanInfo: {}, + noData: true, }; }, computed: {}, @@ -51,24 +54,22 @@ export default { } = item; const props = [ - { prop: 'productLine', label: '产线', align: 'center' }, - { prop: 'specification', label: '规格', align: 'center' }, - { prop: 'equipmentName', label: '设备', align: 'center' }, - { prop: 'totalQuantity', label: '生产总数', align: 'center' }, + { prop: 'productLine', label: '产线' }, + { prop: 'specification', label: '规格' }, + { prop: 'equipmentName', label: '设备' }, + { prop: 'totalQuantity', label: '生产总数' }, ]; 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 + '__in', label: '进数据' }, + { prop: key + '__out', label: '出数据' }, + { prop: key + '__nok', label: '报废数据' }, { prop: key + '__ratio', label: '报废率', - align: 'center', filter: (val) => (val != null ? val + ' %' : '-'), }, ], @@ -138,6 +139,13 @@ export default { // console.log('recent-24', data); this.initing = true; + + if (!data || !data.length) { + this.initing = false; + this.noData = true; + return; + } + this.noData = false; this.buildProps(data[0]); this.buildData(data); this.queryParams.pageSize = this.list.length; diff --git a/src/views/monitoring/equipmentStatusAndParams/index.vue b/src/views/monitoring/equipmentStatusAndParams/index.vue index 2cacd5b6..63e7e6eb 100644 --- a/src/views/monitoring/equipmentStatusAndParams/index.vue +++ b/src/views/monitoring/equipmentStatusAndParams/index.vue @@ -18,6 +18,7 @@ v-if="tableBtn.length" slot="handleBtn" label="操作" + :width="120" :method-list="tableBtn" @clickBtn="handleTableBtnClick" /> @@ -74,28 +75,24 @@ export default { 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: 'inQuantity', label: '投入数' }, + { width: 128, prop: 'outQuantity', label: '产出数' }, { width: 128, prop: 'run', label: '是否运行', - align: 'center', filter: (val) => (val != null ? (val ? '是' : '否') : '-'), }, { width: 128, prop: 'status', label: '状态', - align: 'center', filter: (val) => val != null ? ['正常', '计划停机', '故障'][val] : '-', }, @@ -103,7 +100,6 @@ export default { width: 128, prop: 'error', label: '是否故障', - align: 'center', filter: (val) => (val != null ? (val ? '是' : '否') : '-'), }, { @@ -121,7 +117,6 @@ export default { { _action: 'params-monitor', label: '参数监控', - align: 'center', subcomponent: { props: ['injectData'], render: function (h) { @@ -129,7 +124,7 @@ export default { return h( 'el-button', { - props: { type: 'text', size: 'mini' }, + props: { type: 'text' }, on: { click: function () { console.log('inejctdata', _this.injectData); diff --git a/src/views/quality/base/qualityInspectionBoxBtn/dialogForm.vue b/src/views/quality/base/qualityInspectionBoxBtn/dialogForm.vue new file mode 100644 index 00000000..11653f55 --- /dev/null +++ b/src/views/quality/base/qualityInspectionBoxBtn/dialogForm.vue @@ -0,0 +1,238 @@ + + + + + + + diff --git a/src/views/quality/base/qualityInspectionBoxBtn/index.vue b/src/views/quality/base/qualityInspectionBoxBtn/index.vue index 2193b1a4..291f84dc 100644 --- a/src/views/quality/base/qualityInspectionBoxBtn/index.vue +++ b/src/views/quality/base/qualityInspectionBoxBtn/index.vue @@ -17,6 +17,7 @@ v-if="tableBtn.length" slot="handleBtn" label="操作" + :width="120" fixed="right" :method-list="tableBtn" @clickBtn="handleTableBtnClick" /> @@ -38,7 +39,7 @@ @close="cancel" @cancel="cancel" @confirm="submitForm"> - + @@ -54,11 +55,12 @@ import { } from '@/api/base/qualityInspectionBoxBtn'; import basicPageMixin from '@/mixins/lb/basicPageMixin'; import moment from 'moment'; +import DialogForm from './dialogForm.vue'; export default { name: 'QualityInspectionBoxBtn', mixins: [basicPageMixin], - components: {}, + components: { DialogForm }, data() { return { rows: [ @@ -81,6 +83,9 @@ export default { url: '/base/workshop-section/listAll', prop: 'sectionId', rules: [{ required: true, message: '不能为空', trigger: 'blur' }], + bind: { + filterable: true, + }, }, ], [ @@ -91,9 +96,10 @@ export default { rules: [ { type: 'number', - message: '请输入数字', + message: '请输入整数', trigger: 'blur', - transform: (val) => Number(val), + transform: (val) => + Number.isInteger(Number(val)) && Number(val), }, ], }, @@ -107,9 +113,10 @@ export default { rules: [ { type: 'number', - message: '请输入100以内的数字', + message: '请输入100以内的整数', trigger: 'blur', - transform: (val) => Number(val) <= 100 && Number(val), + transform: (val) => + Number(val) <= 100 && Number.isInteger(+val) && Number(val), }, ], bind: { type: 'number', min: 0, max: 100 }, @@ -120,7 +127,7 @@ export default { textarea: true, label: '检测内容', prop: 'inspectionDetContent', - rules: [{ required: true, message: '不能为空', trigger: 'blur' }], + // rules: [{ required: true, message: '不能为空', trigger: 'blur' }], }, ], ], @@ -173,43 +180,36 @@ export default { filter: (val) => moment(val).format('yyyy-MM-DD HH:mm:ss'), }, { - width: 128, prop: 'productionName', label: '产线', - align: 'center', }, { - width: 128, prop: 'sectionName', label: '工段', - align: 'center', }, { - width: 128, prop: 'inspectionDetContent', label: '检测内容', - align: 'center', }, { width: 160, prop: 'buttonId', label: '按钮盒识别码', - align: 'center', }, // { // width: 256, // prop: 'productionId', // label: '按钮盒所在产线ID', - // align: 'center', + // , // }, // { // width: 256, // prop: 'sectionId', // label: '按钮盒所在工段ID', - // align: 'center', + // , // }, - { width: 90, prop: 'keyValue', label: '按钮值', align: 'center' }, - { width: 128, prop: 'model', label: '按钮盒模式', align: 'center' }, + { width: 90, prop: 'keyValue', label: '按钮值' }, + { width: 128, prop: 'model', label: '按钮盒模式' }, ], // 查询参数 queryParams: { @@ -220,13 +220,13 @@ export default { // 搜索框需要的 keys, 与上面 queryParams 的除 pageNo, pageSize 之外的 key 一一对应 searchBarKeys: ['inspectionDetContent'], form: { - id: undefined, - inspectionDetId: undefined, - inspectionDetContent: undefined, - productionId: undefined, - sectionId: undefined, - model: undefined, - keyValue: undefined, + id: null, + buttonId: null, + inspectionDetContent: null, + productionId: null, + sectionId: null, + model: null, + keyValue: null, }, }; }, @@ -247,13 +247,13 @@ export default { /** 表单重置 */ reset() { this.form = { - id: undefined, - inspectionDetId: undefined, - inspectionDetContent: undefined, - productionId: undefined, - sectionId: undefined, - model: undefined, - keyValue: undefined, + id: null, + buttonId: null, + inspectionDetContent: null, + productionId: null, + sectionId: null, + model: null, + keyValue: null, }; this.resetForm('form'); }, @@ -300,7 +300,7 @@ export default { handleDelete(row) { const id = row.id; this.$modal - .confirm('是否确认删除安灯按钮16键对应编号为"' + id + '"的数据项?') + .confirm('是否确认删除"' + row.sectionName + '"?') .then(function () { return deleteQualityInspectionBoxBtn(id); }) diff --git a/src/views/quality/base/qualityInspectionDet/index.vue b/src/views/quality/base/qualityInspectionDet/index.vue index 4515b4d1..a5518679 100644 --- a/src/views/quality/base/qualityInspectionDet/index.vue +++ b/src/views/quality/base/qualityInspectionDet/index.vue @@ -17,6 +17,7 @@ v-if="tableBtn.length" slot="handleBtn" label="操作" + :width="120" fixed="right" :method-list="tableBtn" @clickBtn="handleTableBtnClick" /> @@ -172,10 +173,10 @@ export default { width: 180, filter: (val) => moment(val).format('yyyy-MM-DD HH:mm:ss'), }, - { prop: 'typeName', label: '类型名称', align: 'center' }, - { prop: 'content', label: '检测内容', align: 'center' }, - { prop: 'code', label: '检测编码', align: 'center' }, - { prop: 'remark', label: '备注', align: 'center' }, + { prop: 'typeName', label: '类型名称', }, + { prop: 'content', label: '检测内容', }, + { prop: 'code', label: '检测编码', }, + { prop: 'remark', label: '备注', }, ], // 查询参数 queryParams: { @@ -275,7 +276,7 @@ export default { handleDelete(row) { const id = row.id; this.$modal - .confirm('是否确认删除质量检测信息基础编号为"' + id + '"的数据项?') + .confirm('是否确认删除检测信息"' + row.content + '"?') .then(function () { return deleteQualityInspectionDet(id); }) diff --git a/src/views/quality/base/qualityInspectionType/index.vue b/src/views/quality/base/qualityInspectionType/index.vue index f78db868..a66b9745 100644 --- a/src/views/quality/base/qualityInspectionType/index.vue +++ b/src/views/quality/base/qualityInspectionType/index.vue @@ -17,6 +17,7 @@ v-if="tableBtn.length" slot="handleBtn" label="操作" + :width="120" :method-list="tableBtn" @clickBtn="handleTableBtnClick" /> @@ -106,9 +107,9 @@ export default { width: 180, filter: (val) => moment(val).format('yyyy-MM-DD HH:mm:ss'), }, - { prop: 'name', label: '检测类型名称', align: 'center' }, - { prop: 'code', label: '检测类型编码', align: 'center' }, - { prop: 'remark', label: '备注', align: 'center' }, + { prop: 'name', label: '检测类型名称' }, + { prop: 'code', label: '检测类型编码' }, + { prop: 'remark', label: '备注' }, // { // label: '操作', // alignt: 'center', @@ -321,7 +322,7 @@ export default { handleDelete(row) { const id = row.id; this.$modal - .confirm('是否确认删除质量检测类型基础编号为"' + id + '"的数据项?') + .confirm('是否确认删除该质量检测类型?') .then(function () { return deleteQualityInspectionType(id); }) diff --git a/src/views/quality/monitoring/qualityInspectionRecord/index.vue b/src/views/quality/monitoring/qualityInspectionRecord/index.vue index 19e691f4..9aef665c 100644 --- a/src/views/quality/monitoring/qualityInspectionRecord/index.vue +++ b/src/views/quality/monitoring/qualityInspectionRecord/index.vue @@ -17,6 +17,7 @@ v-if="tableBtn.length" slot="handleBtn" label="操作" + :width="120" fixed="right" :method-list="tableBtn" @clickBtn="handleTableBtnClick" /> @@ -68,7 +69,7 @@ export default { [ { select: true, - label: '检测内容ID', + label: '检测内容', url: '/base/quality-inspection-det/listAll', prop: 'inspectionDetId', labelKey: 'content', @@ -97,6 +98,9 @@ export default { label: '产线', url: '/base/production-line/listAll', prop: 'productionLineId', + bind: { + filterable: true, + }, rules: [{ required: true, message: '不能为空', trigger: 'blur' }], }, { @@ -105,6 +109,9 @@ export default { url: '/base/workshop-section/listAll', // 这个 url 其实可加可不加,因为下面会更新 options options: [], // 这个options也可加可不加, 因为下面会更新 options prop: 'sectionId', + bind: { + filterable: true, + }, rules: [{ required: true, message: '不能为空', trigger: 'blur' }], }, ], @@ -118,6 +125,7 @@ export default { datetime: true, label: '检测时间', prop: 'checkTime', + rules: [{ required: true, message: '不能为空', trigger: 'blur' }], bind: { format: 'yyyy-MM-dd HH:mm:ss', 'value-format': 'timestamp', @@ -126,15 +134,15 @@ export default { }, }, ], - [ - { - textarea: true, - label: '检测内容', - prop: 'inspectionDetContent', - value: '', - rules: [{ required: true, message: '不能为空', trigger: 'blur' }], - }, - ], + // [ + // { + // textarea: true, + // label: '检测内容', + // prop: 'inspectionDetContent', + // value: '', + // rules: [{ required: true, message: '不能为空', trigger: 'blur' }], + // }, + // ], [{ textarea: true, label: '描述', prop: 'explainText' }], [{ input: true, label: '备注', prop: 'remark' }], ], @@ -213,32 +221,28 @@ export default { width: 128, prop: 'inspectionDetContent', label: '检测内容', - align: 'center', }, { // width: 128, prop: 'lineName', label: '产线', - align: 'center', }, { // width: 128, prop: 'checkPerson', label: '检测人员', - align: 'center', }, { // width: 160, prop: 'checkTime', label: '检测时间', - align: 'center', - filter: (val) => moment(val).format('yyyy-MM-DD HH:mm:ss'), + filter: (val) => + val != null ? moment(val).format('yyyy-MM-DD HH:mm:ss') : '-', }, { width: 90, prop: 'source', label: '来源', - align: 'center', filter: (val) => ['未知', '手动', '自动'][val], }, ], @@ -394,7 +398,7 @@ export default { handleDelete(row) { const id = row.id; this.$modal - .confirm('是否确认删除质量检查信息记录表编号为"' + id + '"的数据项?') + .confirm('是否确认删除"' + row.inspectionDetContent + '"?') .then(function () { return deleteQualityInspectionRecord(id); }) diff --git a/src/views/quality/monitoring/qualityRecentHours/index.vue b/src/views/quality/monitoring/qualityRecentHours/index.vue index 84b38a39..d7ec32e0 100644 --- a/src/views/quality/monitoring/qualityRecentHours/index.vue +++ b/src/views/quality/monitoring/qualityRecentHours/index.vue @@ -13,18 +13,20 @@ - +
+ +