Merge branch 'projects/mesxc-test' into projects/mesxc-dy

This commit is contained in:
helloDy 2023-12-22 16:41:28 +08:00
commit f617597f38
107 changed files with 11851 additions and 455 deletions

View File

@ -1,8 +1,8 @@
### ###
# @Author: Do not edit # @Author: Do not edit
# @Date: 2023-08-29 09:40:39 # @Date: 2023-08-29 09:40:39
# @LastEditTime: 2023-12-14 14:02:40 # @LastEditTime: 2023-12-18 13:35:00
# @LastEditors: DY # @LastEditors: zhp
# @Description: # @Description:
### ###
# 开发环境配置 # 开发环境配置
@ -14,13 +14,14 @@ VUE_APP_TITLE = MES系统
# 芋道管理系统/开发环境 # 芋道管理系统/开发环境
# VUE_APP_BASE_API = 'http://100.64.0.26:48082' # VUE_APP_BASE_API = 'http://100.64.0.26:48082'
VUE_APP_BASE_API = 'http://192.168.0.33:48082' VUE_APP_BASE_API = 'http://192.168.0.33:48082'
# VUE_APP_BASE_API = 'http://192.168.1.78:48082' # VUE_APP_BASE_API = 'http://192.168.4.173:48080'
# VUE_APP_BASE_API = 'http://192.168.2.173:48080' # VUE_APP_BASE_API = 'http://192.168.2.173:48080'
# VUE_APP_BASE_API = 'http://192.168.1.49:48082' # VUE_APP_BASE_API = 'http://192.168.1.49:48082'
# VUE_APP_BASE_API = 'http://192.168.1.8:48082' # VUE_APP_BASE_API = 'http://192.168.1.8:48082'
# VUE_APP_BASE_API = 'http://192.168.4.159:48080' # VUE_APP_BASE_API = 'http://192.168.4.159:48080'
# VUE_APP_BASE_API = 'http://192.168.1.56:48082' # VUE_APP_BASE_API = 'http://192.168.1.56:48082'
# VUE_APP_BASE_API = 'http://192.168.1.62:48082' # VUE_APP_BASE_API = 'http://192.168.1.62:48082'
# VUE_APP_BASE_API = 'http://192.168.1.78:48082'
# 积木报表指向地址 # 积木报表指向地址
VUE_APP_JIMU_API = 'http://192.168.0.33:48082' VUE_APP_JIMU_API = 'http://192.168.0.33:48082'

View File

@ -15,7 +15,7 @@ VUE_APP_TITLE = MES系统
VUE_APP_BASE_API = '/prod-api' VUE_APP_BASE_API = '/prod-api'
# 积木报表指向地址 # 积木报表指向地址
VUE_APP_JIMU_API = 'http://10.70.2.2:8080' VUE_APP_JIMU_API = 'http://10.70.2.22:8080'
# 根据服务器或域名修改 # 根据服务器或域名修改

View File

@ -2,7 +2,7 @@
/* /*
* @Author: zhp * @Author: zhp
* @Date: 2023-11-06 15:38:12 * @Date: 2023-11-06 15:38:12
* @LastEditTime: 2023-12-08 16:08:35 * @LastEditTime: 2023-12-15 15:29:16
* @LastEditors: zhp * @LastEditors: zhp
* @Description: * @Description:
*/ */
@ -99,3 +99,27 @@ export function getMaterialCheckList(query) {
params: query params: query
}) })
} }
export function createQualityHotMaterialDet(query){
return request({
url: '/base/quality-hot-material-det/create',
method: 'post',
data: query
})
}
export function updateQualityHotMaterialDet(query){
return request({
url: '/base/quality-hot-material-det/listbyfilter',
method: 'put',
data: query
})
}
export function getQualityHotMaterialDetList(query){
return request({
url: '/base/quality-hot-material-det/listbyfilter',
method: 'get',
params: query
})
}

View File

@ -1,7 +1,7 @@
/* /*
* @Author: zhp * @Author: zhp
* @Date: 2023-12-04 14:10:37 * @Date: 2023-12-04 14:10:37
* @LastEditTime: 2023-12-13 16:03:46 * @LastEditTime: 2023-12-14 10:06:03
* @LastEditors: zhp * @LastEditors: zhp
* @Description: * @Description:
*/ */
@ -19,7 +19,7 @@ export function createQualityInspectionBoxBtn(data) {
// 更新安灯按钮16键对应 // 更新安灯按钮16键对应
export function updateQualityInspectionBoxBtn(data) { export function updateQualityInspectionBoxBtn(data) {
return request({ return request({
url: '/base/quality-inspection-box-btn/update', url: '/base/quality-inspection-box-btn/updateBatch',
method: 'put', method: 'put',
data: data data: data
}) })
@ -44,7 +44,7 @@ export function getQualityInspectionBoxBtn(id) {
// 获得安灯按钮16键对应分页 // 获得安灯按钮16键对应分页
export function getQualityInspectionBoxBtnPage(query) { export function getQualityInspectionBoxBtnPage(query) {
return request({ return request({
url: '/base/quality-inspection-box-btn/page', url: '/base/quality-inspection-box-btn/listGroupByLineSection',
method: 'get', method: 'get',
params: query params: query
}) })

View File

@ -1,7 +1,7 @@
/* /*
* @Author: zhp * @Author: zhp
* @Date: 2023-12-12 13:49:02 * @Date: 2023-12-12 13:49:02
* @LastEditTime: 2023-12-13 15:52:11 * @LastEditTime: 2023-12-14 14:21:43
* @LastEditors: zhp * @LastEditors: zhp
* @Description: * @Description:
*/ */
@ -39,3 +39,19 @@ export function getAutoDeliveDataList(query) {
data: query, data: query,
}) })
} }
export function updateAutoDeliveDataList(query) {
return request({
url: '/base/report-auto-delive/update',
method: 'put',
data: query,
})
}
export function updateSumAutoDeliveDataList(query) {
return request({
url: '/base/report-auto-delive/updatePlus',
method: 'put',
data: query,
})
}

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="24px" height="24px" viewBox="0 0 24 24" 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(-383.000000, -639.000000)" fill="#FFFFFF" fill-rule="nonzero">
<g id="制度流程" transform="translate(383.000000, 639.000000)">
<rect id="矩形" opacity="0" x="0" y="0" width="24" height="24"></rect>
<path d="M4.37117174,17.071929 L2.37885068,17.071929 C2.0028361,17.071929 1.69692899,17.3771995 1.69692899,17.7524526 L1.69692899,19.7475474 C1.69692899,20.1227781 2.00283612,20.428071 2.37885068,20.428071 L4.37117174,20.428071 C4.74718632,20.428071 5.05307101,20.1228005 5.05307101,19.7475474 L5.05307101,17.7524526 C5.05307101,17.3771996 4.74718632,17.071929 4.37117174,17.071929 Z M7.36536289,6.40073051 L21.8846371,6.40073051 C22.2245029,6.40073051 22.5,6.06492662 22.5,5.65073051 C22.5,5.2365344 22.2245029,4.90073051 21.8846371,4.90073051 L7.36536289,4.90073051 C7.02549709,4.90073051 6.75,5.23653442 6.75,5.65073054 C6.75,6.06492665 7.02549711,6.40073051 7.36536289,6.40073051 Z M3.14077284,5.95492436 L2.03265569,4.84248673 C1.8767502,4.68597337 1.62348469,4.6854806 1.46697133,4.84138609 C1.4665023,4.8418533 1.46603442,4.84232168 1.46556772,4.84279121 L1.18448184,5.12557972 C1.0295067,5.28149361 1.02939503,5.5332514 1.1842318,5.6893027 L2.85590574,7.37408916 C3.01150401,7.53090793 3.26476807,7.53189735 3.42158685,7.37629907 C3.42263304,7.37526103 3.42367349,7.3742172 3.42470814,7.37316765 L5.7220224,5.04277966 C5.87599957,4.88658572 5.87547971,4.63552909 5.72085699,4.47997417 L5.4403523,4.19777835 C5.28461275,4.04109986 5.0313479,4.04033871 4.87466942,4.19607825 C4.87370895,4.19703297 4.87275333,4.19799256 4.8718026,4.19895698 L3.14077284,5.95492436 L3.14077284,5.95492436 Z M21.8846371,11.25 L7.36536289,11.25 C7.02549709,11.25 6.75,11.5857972 6.75,11.999985 C6.75,12.4141729 7.02552167,12.75 7.36536289,12.75 L21.8846371,12.75 C22.2245029,12.75 22.5,12.4142028 22.5,11.999985 C22.5,11.5857672 22.2245029,11.25 21.8846371,11.25 Z M21.8846371,17.972656 L7.36536289,17.972656 C7.02549709,17.972656 6.75,18.30843 6.75,18.722656 C6.75,19.1368821 7.02552167,19.472656 7.36536289,19.472656 L21.8846371,19.472656 C22.2245029,19.472656 22.5,19.1368821 22.5,18.722656 C22.5,18.30843 22.2245029,17.972656 21.8846371,17.972656 Z M4.37117174,10.321929 L2.37885068,10.321929 C2.0028361,10.321929 1.69692899,10.6271975 1.69692899,11.0024481 L1.69692899,12.9975519 C1.69692899,13.3727801 2.00283612,13.678071 2.37885068,13.678071 L4.37117174,13.678071 C4.74718632,13.678071 5.05307101,13.3728025 5.05307101,12.9975519 L5.05307101,11.0024481 C5.05307101,10.6271975 4.74718632,10.321929 4.37117174,10.321929 Z" id="形状"></path>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1702606455297" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1590" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><path d="M614.4 59.136l238.592 137.728a204.8 204.8 0 0 1 102.4 177.3568v275.5584a204.8 204.8 0 0 1-102.4 177.3568L614.4 964.864a204.8 204.8 0 0 1-204.8 0l-238.592-137.728a204.8 204.8 0 0 1-102.4-177.3568V374.2208a204.8 204.8 0 0 1 102.4-177.3568L409.6 59.136a204.8 204.8 0 0 1 204.8 0z" fill="#EE1609" p-id="1591"></path><path d="M471.04 261.9904v315.392a40.96 40.96 0 1 0 81.92 0v-315.392a40.96 40.96 0 1 0-81.92 0z" fill="#FFFFFF" p-id="1592"></path><path d="M512 706.56m-51.2 0a51.2 51.2 0 1 0 102.4 0 51.2 51.2 0 1 0-102.4 0Z" fill="#FFFFFF" p-id="1593"></path></svg>

After

Width:  |  Height:  |  Size: 895 B

View File

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1702606467176" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1824" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><path d="M622.812817 29.238717l258.222014 146.7694A217.658893 217.658893 0 0 1 991.847648 365.004111v293.666761c0 77.991238-42.226593 150.032365-110.812817 188.995994l-258.222014 146.7694a224.568699 224.568699 0 0 1-221.625634 0l-258.222014-146.7694A217.658893 217.658893 0 0 1 32.152352 658.670872v-293.666761c0-77.991238 42.226593-150.032365 110.812817-188.995994L401.187183 29.238717a224.568699 224.568699 0 0 1 221.625634 0z" fill="#4AA468" p-id="1825"></path><path d="M448.852049 592.899754l-124.120591-140.883269a37.108218 37.108218 0 0 0-56.877941 1.087654 51.631607 51.631607 0 0 0-0.447858 65.067342l151.567877 172.105356c15.355125 17.466454 39.987304 18.042272 55.982226 1.407553l279.39929-290.403797a50.863851 50.863851 0 0 0 12.667978-44.529861 44.84976 44.84976 0 0 0-27.511265-34.67699 36.980259 36.980259 0 0 0-39.859345 10.17277l-250.800371 260.653242z" fill="#FFFFFF" p-id="1826"></path></svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 5.6 KiB

BIN
src/assets/logo/logo1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

BIN
src/assets/logo/xcac.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

View File

@ -139,7 +139,7 @@ $base1px: 0.15vh; // 1px / 1080px;
.title { .title {
margin: 0; margin: 0;
margin-left: calc(28 * 0.12vh); margin-left: calc(18px * 0.12vh);
font-weight: 400; font-weight: 400;
user-select: none; user-select: none;
color: #000; color: #000;
@ -148,8 +148,8 @@ $base1px: 0.15vh; // 1px / 1080px;
letter-spacing: calc(2 * 0.12vh); letter-spacing: calc(2 * 0.12vh);
.cnbm_logo { .cnbm_logo {
height: calc(40 * 0.12vh); height: calc(160 * 0.12vh);
width: calc(40 * 0.12vh); width: calc(182 * 0.12vh);
position: relative; position: relative;
top: calc(8 * 0.12vh); top: calc(8 * 0.12vh);
right: calc(8 * 0.12vh); right: calc(8 * 0.12vh);

View File

@ -86,8 +86,8 @@
</span> </span>
<!-- :file-list="uploadedFileList" --> <!-- :file-list="uploadedFileList" -->
<el-upload <el-upload
class="upload-in-dialog"
v-if="col.upload" v-if="col.upload"
class="upload-in-dialog"
:key="col.prop + '__el-upload'" :key="col.prop + '__el-upload'"
:action="uploadUrl" :action="uploadUrl"
:headers="uploadHeaders" :headers="uploadHeaders"
@ -101,7 +101,9 @@
} }
" "
v-bind="col.bind"> v-bind="col.bind">
<el-button size="mini" :disabled="col.bind?.disabled || false"> <el-button
size="mini"
:disabled="disabled || col.bind?.disabled || false">
<svg-icon <svg-icon
icon-class="icon-upload" icon-class="icon-upload"
style="color: inherit"></svg-icon> style="color: inherit"></svg-icon>
@ -117,6 +119,7 @@
v-for="file in form[col.prop]" v-for="file in form[col.prop]"
:file="file" :file="file"
:key="file.fileUrl" :key="file.fileUrl"
:disabled="disabled"
@delete="!disabled && handleDeleteFile(file, col.prop)" /> @delete="!disabled && handleDeleteFile(file, col.prop)" />
</div> </div>
</el-form-item> </el-form-item>
@ -142,6 +145,9 @@ function findMaxLabelWidth(rows) {
if (!opt.label) return 0; if (!opt.label) return 0;
if (opt.label.length > max) { if (opt.label.length > max) {
max = opt.label.length; max = opt.label.length;
if (opt.label.includes('(')) {
max = max - 3;
}
} }
}); });
}); });
@ -150,7 +156,7 @@ function findMaxLabelWidth(rows) {
const uploadedFile = { const uploadedFile = {
name: 'UploadedFile', name: 'UploadedFile',
props: ['file'], props: ['file', 'disabled'],
data() { data() {
return {}; return {};
}, },
@ -195,6 +201,7 @@ const uploadedFile = {
display: 'inline-block', display: 'inline-block',
}}> }}>
{this.file.fileName} {this.file.fileName}
{!this.disabled && (
<el-button <el-button
type="text" type="text"
icon="el-icon-close" icon="el-icon-close"
@ -202,6 +209,7 @@ const uploadedFile = {
class="dialog__upload_component__close" class="dialog__upload_component__close"
onClick={this.handleDelete} onClick={this.handleDelete}
/> />
)}
</div> </div>
); );
}, },
@ -404,8 +412,26 @@ export default {
} }
if (!promiseList.length) this.formLoading = false; if (!promiseList.length) this.formLoading = false;
}, },
// //
beforeUpload() {}, beforeUpload(file) {
const checkFileSize = () => {
const isLt2M = file.size / 1024 / 1024 < 2;
if (!isLt2M) {
this.$modal.msgError('上传文件大小不能超过 2MB!');
}
return isLt2M;
};
const checkFileType = () => {
const isJPG =
file.type === 'image/jpeg' ||
file.type === 'image/png' ||
file.type === 'image/jpg';
return isJPG;
};
return checkFileSize() && checkFileType();
},
// bind // bind
handleUploadSuccess(response, file, prop) { handleUploadSuccess(response, file, prop) {
console.log('[handleUploadSuccess]', response, file, prop); console.log('[handleUploadSuccess]', response, file, prop);

View File

@ -17,7 +17,9 @@ export default {
const vnodes = [] const vnodes = []
if (icon) { if (icon) {
vnodes.push(<svg-icon icon-class={icon}/>) vnodes.push(<svg-icon style="font-size: 18px;margin-right: 10px;vertical-align: middle;" icon-class={icon}/>)
} else {
vnodes.push(<span style="display: inline-block; width: 10px;"/>)
} }
if (title) { if (title) {

View File

@ -15,7 +15,7 @@
key="collapse" key="collapse"
class="sidebar-logo-link" class="sidebar-logo-link"
to="/"> to="/">
<img v-if="logo" :src="logo" class="sidebar-logo" /> <img v-if="logo" :src="logo" class="sidebar-logo-close" />
<h1 <h1
v-else v-else
class="sidebar-title" class="sidebar-title"
@ -67,7 +67,7 @@ export default {
}, },
data() { data() {
return { return {
title: '中建材智能化院', title: '许昌安彩新能科技有限公司',
logo: logoImg, logo: logoImg,
}; };
}, },
@ -98,8 +98,8 @@ export default {
width: 100%; width: 100%;
& .sidebar-logo { & .sidebar-logo {
width: 32px; width: 67px;
height: 40px; height: 24px;
vertical-align: middle; vertical-align: middle;
margin-right: 12px; margin-right: 12px;
} }
@ -108,17 +108,23 @@ export default {
display: inline-block; display: inline-block;
margin: 0; margin: 0;
color: #fff; color: #fff;
font-weight: 600; font-weight: 500;
line-height: 50px; width: 147px;
font-size: 18px; letter-spacing: 2px;
letter-spacing: 1px; font-size: 10px;
font-family: Avenir, Helvetica Neue, Arial, Helvetica, sans-serif; font-family: Avenir, Helvetica Neue, Arial, Helvetica, sans-serif;
vertical-align: middle; vertical-align: middle;
} }
} }
&.collapse { &.collapse {
.sidebar-logo { // .sidebar-logo {
// margin-right: 0px;
// }
.sidebar-logo-close {
width: 54px;
height: 19px;
vertical-align: middle;
margin-right: 0px; margin-right: 0px;
} }
} }

View File

@ -3,16 +3,16 @@
<template v-if="hasOneShowingChild(item.children,item) && (!onlyOneChild.children||onlyOneChild.noShowingChildren)&&!item.alwaysShow"> <template v-if="hasOneShowingChild(item.children,item) && (!onlyOneChild.children||onlyOneChild.noShowingChildren)&&!item.alwaysShow">
<app-link v-if="onlyOneChild.meta" :to="resolvePath(onlyOneChild.path)"> <app-link v-if="onlyOneChild.meta" :to="resolvePath(onlyOneChild.path)">
<el-menu-item :index="resolvePath(onlyOneChild.path)" :class="{'submenu-title-noDropdown':!isNest}"> <el-menu-item :index="resolvePath(onlyOneChild.path)" :class="{'submenu-title-noDropdown':!isNest}">
<item :icon="onlyOneChild.meta.icon||(item.meta&&item.meta.icon)" :title="onlyOneChild.meta.title" /> <item icon="menuIcon" :title="onlyOneChild.meta.title" />
</el-menu-item> </el-menu-item>
</app-link> </app-link>
</template> </template>
<el-submenu v-else ref="subMenu" :index="resolvePath(item.path)" popper-append-to-body> <el-submenu v-else ref="subMenu" :index="resolvePath(item.path)" popper-append-to-body>
<template slot="title"> <template slot="title">
<item v-if="item.meta" :icon="item.meta && item.meta.icon" :title="item.meta.title" /> <item v-if="item.meta" icon="menuIcon" :title="item.meta.title" />
</template> </template>
<sidebar-item <sidebar-item-sub
v-for="(child, index) in item.children" v-for="(child, index) in item.children"
:key="child.path + index" :key="child.path + index"
:is-nest="true" :is-nest="true"
@ -30,10 +30,11 @@ import { isExternal } from '@/utils/validate'
import Item from './Item' import Item from './Item'
import AppLink from './Link' import AppLink from './Link'
import FixiOSBug from './FixiOSBug' import FixiOSBug from './FixiOSBug'
import SidebarItemSub from './SidebarItemSub'
export default { export default {
name: 'SidebarItem', name: 'SidebarItem',
components: { Item, AppLink }, components: { Item, AppLink, SidebarItemSub },
mixins: [FixiOSBug], mixins: [FixiOSBug],
props: { props: {
// route object // route object

View File

@ -3,16 +3,16 @@
<template v-if="hasOneShowingChild(item.children,item) && (!onlyOneChild.children||onlyOneChild.noShowingChildren)&&!item.alwaysShow"> <template v-if="hasOneShowingChild(item.children,item) && (!onlyOneChild.children||onlyOneChild.noShowingChildren)&&!item.alwaysShow">
<app-link v-if="onlyOneChild.meta" :to="resolvePath(onlyOneChild.path)"> <app-link v-if="onlyOneChild.meta" :to="resolvePath(onlyOneChild.path)">
<el-menu-item :index="resolvePath(onlyOneChild.path)" :class="{'submenu-title-noDropdown':!isNest}"> <el-menu-item :index="resolvePath(onlyOneChild.path)" :class="{'submenu-title-noDropdown':!isNest}">
<item :icon="onlyOneChild.meta.icon||(item.meta&&item.meta.icon)" :title="onlyOneChild.meta.title" /> <item icon="" :title="onlyOneChild.meta.title" />
</el-menu-item> </el-menu-item>
</app-link> </app-link>
</template> </template>
<el-submenu v-else ref="subMenu" :index="resolvePath(item.path)" popper-append-to-body> <el-submenu v-else ref="subMenu" :index="resolvePath(item.path)" popper-append-to-body>
<template slot="title"> <template slot="title">
<item v-if="item.meta" :icon="item.meta && item.meta.icon" :title="item.meta.title" /> <item v-if="item.meta" icon="" :title="item.meta.title" />
</template> </template>
<sidebar-item <sidebar-item-sub
v-for="(child, index) in item.children" v-for="(child, index) in item.children"
:key="child.path + index" :key="child.path + index"
:is-nest="true" :is-nest="true"
@ -32,7 +32,7 @@ import AppLink from './Link'
import FixiOSBug from './FixiOSBug' import FixiOSBug from './FixiOSBug'
export default { export default {
name: 'SidebarItem', name: 'SidebarItemSub',
components: { Item, AppLink }, components: { Item, AppLink },
mixins: [FixiOSBug], mixins: [FixiOSBug],
props: { props: {

View File

@ -1,71 +0,0 @@
<template>
<div
:class="{ 'has-logo': showLogo }"
:style="{
backgroundColor:
settings.sideTheme === 'theme-dark'
? variables.menuBackground
: variables.menuLightBackground,
}">
<logo v-if="showLogo" :collapse="isCollapse" />
<el-scrollbar :class="settings.sideTheme" wrap-class="scrollbar-wrapper">
<el-menu
:default-active="activeMenu"
:collapse="isCollapse"
:background-color="
settings.sideTheme === 'theme-dark'
? variables.menuBackground
: variables.menuLightBackground
"
:text-color="
settings.sideTheme === 'theme-dark'
? variables.menuColor
: variables.menuLightColor
"
:unique-opened="true"
active-text-color="#fff"
:collapse-transition="false"
mode="vertical">
<!-- 根据 sidebarRouters 路由生成菜单 -->
<sidebar-item
v-for="(route, index) in sidebarRouters"
:key="route.path + index"
:item="route"
:base-path="route.path" />
</el-menu>
</el-scrollbar>
</div>
</template>
<script>
import { mapGetters, mapState } from 'vuex';
import Logo from './Logo';
import SidebarItem from './SidebarItem';
import variables from '@/assets/styles/variables.scss';
export default {
components: { SidebarItem, Logo },
computed: {
...mapState(['settings']),
...mapGetters(['sidebarRouters', 'sidebar']),
activeMenu() {
const route = this.$route;
const { meta, path } = route;
// if set path, the sidebar will highlight the path you set
if (meta.activeMenu) {
return meta.activeMenu;
}
return path;
},
showLogo() {
return this.$store.state.settings.sidebarLogo;
},
variables() {
return variables;
},
isCollapse() {
return !this.sidebar.opened;
},
},
};
</script>

View File

@ -28,10 +28,10 @@
mode="vertical"> mode="vertical">
<!-- 根据 sidebarRouters 路由生成菜单 --> <!-- 根据 sidebarRouters 路由生成菜单 -->
<sidebar-item <sidebar-item
v-for="(route, index) in routeList" v-for="(route, index) in routeList.children"
:key="route.path + index" :key="route.path + index"
:item="route" :item="route"
:base-path="route.path" /> :base-path="routeList.path+ '/'+ route.path" />
</el-menu> </el-menu>
</el-scrollbar> </el-scrollbar>
</div> </div>
@ -49,9 +49,7 @@ export default {
...mapState(['settings']), ...mapState(['settings']),
...mapGetters(['sidebarRouters', 'sidebar', 'choicepart']), ...mapGetters(['sidebarRouters', 'sidebar', 'choicepart']),
routeList() { routeList() {
// return [this.partList[this.choicepart]] return this.sidebarRouters[this.choicepart]
// return [this.sidebarRouters[29]]
return [this.sidebarRouters[this.choicepart]]
}, },
activeMenu() { activeMenu() {
const route = this.$route; const route = this.$route;

View File

@ -102,6 +102,7 @@ export const DICT_TYPE = {
ORDER_ORIGIN: 'order_Origin', ORDER_ORIGIN: 'order_Origin',
ORDER_PRIORITY: 'order_priority', ORDER_PRIORITY: 'order_priority',
PACK_SPEC: 'pack_spec', PACK_SPEC: 'pack_spec',
WORK_ORDER_STATUS: 'work_order_status',
// ============== EQUIPMENT - 设备模块 ============= // ============== EQUIPMENT - 设备模块 =============
MAINTAIN_TYPE: 'maintain_type', MAINTAIN_TYPE: 'maintain_type',

View File

@ -7,6 +7,8 @@
}"> }">
<img src="../../assets/img/logo.png" style="width:1.1em;position:relative;top:.4em" alt=""> <img src="../../assets/img/logo.png" style="width:1.1em;position:relative;top:.4em" alt="">
许昌安彩冷端看板 许昌安彩冷端看板
<h3 class="unit">单位河南汇融科技服务有限公司</h3>
<h3 class="time">{{ times }}</h3>
<!-- <el-button type="text" class="title-button" :style="{ right: 33 + 'px', top: 37 + 'px' }" <!-- <el-button type="text" class="title-button" :style="{ right: 33 + 'px', top: 37 + 'px' }"
@click="changeFullScreen"> @click="changeFullScreen">
<svg-icon v-if="isFullScreen" icon-class="unFullScreenView" /> <svg-icon v-if="isFullScreen" icon-class="unFullScreenView" />
@ -616,6 +618,7 @@ export default {
modelMonth: '', modelMonth: '',
cplNameList, cplNameList,
cplDataList, cplDataList,
times:'',
plInput: {}, plInput: {},
plOutput: {}, plOutput: {},
plRate: {}, plRate: {},
@ -658,7 +661,7 @@ export default {
this.windowWidth(document.documentElement.clientWidth) this.windowWidth(document.documentElement.clientWidth)
}, },
mounted() { mounted() {
console.log(1111); this.getTimes()
const _this = this; const _this = this;
_this.beilv2 = document.documentElement.clientWidth / 1920 _this.beilv2 = document.documentElement.clientWidth / 1920
window.onresize = () => { window.onresize = () => {
@ -685,6 +688,30 @@ export default {
// removeEventListener('resize', resizeFun) // removeEventListener('resize', resizeFun)
// }, // },
methods: { methods: {
getTimes() {
setInterval(this.getTimesInterval, 1000);
},
getTimesInterval: function () {
let _this = this;
let year = new Date().getFullYear(); //
let month = new Date().getMonth() + 1; //
let day = new Date().getDate(); //
let hours = new Date().getHours(); //
let minutes = new Date().getMinutes(); //
let seconds = new Date().getSeconds(); //
// 10 0
if (hours < 10) {
hours = "0" + hours;
}
if (minutes < 10) {
minutes = "0" + minutes;
}
if (seconds < 10) {
seconds = "0" + seconds;
}
//
this.times = year + "-" + month + "-" + day + " " + hours + ":" + minutes + ":" + seconds;
},
windowWidth(value) { windowWidth(value) {
this.clientWidth = value this.clientWidth = value
this.beilv2 = this.clientWidth / 1920 this.beilv2 = this.clientWidth / 1920
@ -1010,7 +1037,18 @@ export default {
background-size: 100% 100%; background-size: 100% 100%;
color: #00fff0; color: #00fff0;
text-align: center; text-align: center;
.unit {
position: absolute;
left: 260px;
top: 25px;
font-size: 20px;
}
.time {
position: absolute;
left: 1360px;
top: 25px;
font-size: 20px;
}
.title-button { .title-button {
color: #00fff0; color: #00fff0;
font-size: 20px; font-size: 20px;

View File

@ -2,21 +2,20 @@
* @Author: zwq * @Author: zwq
* @Date: 2021-07-19 15:18:30 * @Date: 2021-07-19 15:18:30
* @LastEditors: zhp * @LastEditors: zhp
* @LastEditTime: 2023-11-23 11:11:35 * @LastEditTime: 2023-12-19 14:25:07
* @Description: * @Description:
--> -->
<template> <template>
<div id="container" ref="container" class="visual-container" :style="styles"> <div id="container" ref="container" class="visual-container" :style="styles">
<el-row <el-row class="container-title" :style="{
class="container-title"
:style="{
height: 88 + 'px', height: 88 + 'px',
lineHeight: 88 + 'px', lineHeight: 88 + 'px',
fontSize: 31 + 'px' fontSize: 31 + 'px'
}" }">
>
<img src="../../assets/img/logo.png" style="width:1.1em;position:relative;top:.4em" alt=""> <img src="../../assets/img/logo.png" style="width:1.1em;position:relative;top:.4em" alt="">
许昌安彩深加工看板 许昌安彩深加工看板
<h3 class="unit">单位河南汇融科技服务有限公司</h3>
<h3 class="time">{{ times }}</h3>
<!-- <el-button <!-- <el-button
type="text" type="text"
class="title-button" class="title-button"
@ -31,13 +30,8 @@
<el-row :style="{ padding: '0 ' + 9 + 'px' }" :gutter="15" type="flex" class="flex-1"> <el-row :style="{ padding: '0 ' + 9 + 'px' }" :gutter="15" type="flex" class="flex-1">
<el-col :style="{ margin: 8 + 'px' + ' 0' }" :span="8"> <el-col :style="{ margin: 8 + 'px' + ' 0' }" :span="8">
<base-container :title="'设备报警'" :title-icon="'5_1'"> <base-container :title="'设备报警'" :title-icon="'5_1'">
<base-table1 <base-table1 :page="1" :limit="9" :show-index="false" :table-config="qualityYearTableProps"
:page="1" :table-data="qualityYearList" />
:limit="9"
:show-index="false"
:table-config="qualityYearTableProps"
:table-data="qualityYearList"
/>
</base-container> </base-container>
</el-col> </el-col>
@ -48,14 +42,8 @@
<el-option key="1" value="钢1线" label="钢1线" default /> <el-option key="1" value="钢1线" label="钢1线" default />
</el-select> </el-select>
</div> </div>
<base-table1 <base-table1 :page="1" :limit="9" :show-index="false" :table-config="qualityMonthTableProps"
:page="1" :table-data="qualityMonthList" />
:limit="9"
:show-index="false"
:table-config="qualityMonthTableProps"
:table-data="qualityMonthList"
/>
</base-container> </base-container>
</el-col> </el-col>
@ -116,13 +104,7 @@
</div> </div>
<el-row :gutter="9"> <el-row :gutter="9">
<el-col :style="{ margin: 8 + 'px' + ' 0' }" :span="24"> <el-col :style="{ margin: 8 + 'px' + ' 0' }" :span="24">
<linear-bar-chart <linear-bar-chart :name-list="cxNameList" :data-list="cxDataList" :height="359" :show-legend="true" />
:name-list="cxNameList"
:data-list="cxDataList"
:height="359"
:show-legend="true"
/>
</el-col> </el-col>
<!-- <el-col :style="{ margin: 8 + 'px' + ' 0' }" :span="12"> <!-- <el-col :style="{ margin: 8 + 'px' + ' 0' }" :span="12">
<base-table3 <base-table3
@ -142,14 +124,8 @@
<top-radio-group /> <top-radio-group />
</div> </div>
<!-- 像下面这样表格里的limit值也许可以用js动态计算出来 --> <!-- 像下面这样表格里的limit值也许可以用js动态计算出来 -->
<double-y-chart <double-y-chart :id=" 'doubleYChart' " :name-list="cxNameList" :data-list="cxDataList" :height="359"
:id=" 'doubleYChart' " :show-legend="true" />
:name-list="cxNameList"
:data-list="cxDataList"
:height="359"
:show-legend="true"
/>
</base-container> </base-container>
</el-col> </el-col>
</el-row> </el-row>
@ -685,6 +661,7 @@ export default {
beilv2: 1, beilv2: 1,
beilv: 1, beilv: 1,
value: 100, value: 100,
times:'',
// offsetWidth: null, // offsetWidth: null,
qualityYearTableProps, qualityYearTableProps,
cxNameList, cxNameList,
@ -742,6 +719,7 @@ export default {
this.init() this.init()
}, },
mounted() { mounted() {
this.getTimes()
this.windowWidth(document.documentElement.clientWidth) this.windowWidth(document.documentElement.clientWidth)
// const _this = this; // const _this = this;
// window.onresize = () => { // window.onresize = () => {
@ -768,6 +746,30 @@ export default {
// removeEventListener('resize', resizeFun) // removeEventListener('resize', resizeFun)
// }, // },
methods: { methods: {
getTimes() {
setInterval(this.getTimesInterval, 1000);
},
getTimesInterval: function () {
let _this = this;
let year = new Date().getFullYear(); //
let month = new Date().getMonth() + 1; //
let day = new Date().getDate(); //
let hours = new Date().getHours(); //
let minutes = new Date().getMinutes(); //
let seconds = new Date().getSeconds(); //
// 10 0
if (hours < 10) {
hours = "0" + hours;
}
if (minutes < 10) {
minutes = "0" + minutes;
}
if (seconds < 10) {
seconds = "0" + seconds;
}
//
this.times = year + "-" + month + "-" + day + " " + hours + ":" + minutes + ":" + seconds;
},
windowWidth(value) { windowWidth(value) {
this.clientWidth = value this.clientWidth = value
this.beilv2 = this.clientWidth / 1920 this.beilv2 = this.clientWidth / 1920
@ -838,7 +840,19 @@ export default {
background-size: 100% 100%; background-size: 100% 100%;
color: #00fff0; color: #00fff0;
text-align: center; text-align: center;
.unit {
position: absolute;
left: 260px;
top: 25px;
font-size: 20px;
}
.time {
position: absolute;
left: 1360px;
top: 25px;
font-size: 20px;
}
.title-button { .title-button {
color: #00fff0; color: #00fff0;
font-size: 20px; font-size: 20px;

View File

@ -268,7 +268,7 @@ export default {
// }) // })
// } else { // } else {
$('.hiprintEpContainer').empty() $('.hiprintEpContainer').empty()
console.log(this.modelData); console.log(this.modelData || {});
hiprint.PrintElementTypeManager.build('.hiprintEpContainer', provider.value) hiprint.PrintElementTypeManager.build('.hiprintEpContainer', provider.value)
$('.hiprint-printTemplate').empty() $('.hiprint-printTemplate').empty()
// const templates = this.$ls.get('KEY_TEMPLATES', {}) // const templates = this.$ls.get('KEY_TEMPLATES', {})

View File

@ -1,8 +1,8 @@
<template> <template>
<div class="navbar"> <div class="navbar">
<div style="color: #fff;font-size: 22px; float: left; letter-spacing: 1px; font-weight: 500; padding-left: 24px; marginTop: 13px"> <div style="color: #fff;font-size: 22px; float: left; letter-spacing: 2px; font-weight: 500; padding-left: 24px; marginTop: 13px">
<img src="../../../assets/images/cnbm.png" style="width: 26px; height: 26px; position: relative; top: 6px; marginRight: 14px" alt=""> <img src="../../../assets/logo/logo.png" style="width: 79px; height: 28px; position: relative; top: 6px; marginRight: 14px" alt="">
MES 许昌安彩新能科技有限公司
</div> </div>
<div style="padding-top: 15px; padding-right: 38px;"> <div style="padding-top: 15px; padding-right: 38px;">
<navbar-right /> <navbar-right />

View File

@ -30,6 +30,7 @@ import {
} from '@/api/cost/costEneryAutoReport'; } from '@/api/cost/costEneryAutoReport';
import { getEnergyTypeListAll } from '@/api/base/energyType'; import { getEnergyTypeListAll } from '@/api/base/energyType';
import { publicFormatter } from '@/utils/dict'; import { publicFormatter } from '@/utils/dict';
import moment from 'moment';
const tableProps = [ const tableProps = [
{ {
@ -79,9 +80,6 @@ export default {
tableData: [], tableData: [],
tableProps, tableProps,
drawerVisible: false, drawerVisible: false,
listQuery: {
reportType: 2,
},
formConfig: [ formConfig: [
{ {
type: 'select', type: 'select',
@ -94,7 +92,6 @@ export default {
], ],
param: 'reportType', param: 'reportType',
filterable: true, filterable: true,
defaultSelect: 2, //
clearable: false, clearable: false,
}, },
{ {
@ -109,7 +106,7 @@ export default {
label: '时间范围', label: '时间范围',
dateType: 'daterange', dateType: 'daterange',
format: 'yyyy-MM-dd', format: 'yyyy-MM-dd',
valueFormat: 'timestamp', valueFormat: 'yyyy-MM-dd',
rangeSeparator: '-', rangeSeparator: '-',
startPlaceholder: '开始时间', startPlaceholder: '开始时间',
endPlaceholder: '结束时间', endPlaceholder: '结束时间',
@ -147,15 +144,25 @@ export default {
this.listQuery.pageSize = 10; this.listQuery.pageSize = 10;
this.listQuery.reportType = val.reportType; this.listQuery.reportType = val.reportType;
this.listQuery.energyTypeId = val.energyTypeId; this.listQuery.energyTypeId = val.energyTypeId;
this.listQuery.reportTime = val.searchTime ? val.searchTime : null; this.listQuery.reportTime = val.searchTime
? [
moment(val.searchTime[0]).startOf('day').format('x'),
moment(val.searchTime[1]).endOf('day').format('x'),
]
: null;
this.getDataList(); this.getDataList();
break; break;
case 'export': case 'export':
const data = { const data = {
reportType: val.reportType, reportType: val.reportType,
energyTypeId: val.energyTypeId, energyTypeId: val.energyTypeId,
reportTime: val.searchTime ? val.searchTime : null reportTime: val.searchTime
} ? [
moment(val.searchTime[0]).startOf('day').format('x'),
moment(val.searchTime[1]).endOf('day').format('x'),
]
: null,
};
this.handleExport(data); this.handleExport(data);
break; break;
default: default:

View File

@ -70,7 +70,7 @@ const tableProps = [
}, },
{ {
prop: 'dailyUse', prop: 'dailyUse',
label: '单日消耗量(天)吨', label: '单日消耗量(吨)',
width: 130, width: 130,
}, },
{ {

View File

@ -30,6 +30,7 @@ import {
} from '@/api/cost/costMaterialAutoReport'; } from '@/api/cost/costMaterialAutoReport';
import { getHotMaterialList } from '@/api/base/coreHotMaterial'; import { getHotMaterialList } from '@/api/base/coreHotMaterial';
import { publicFormatter } from '@/utils/dict'; import { publicFormatter } from '@/utils/dict';
import moment from 'moment';
const tableProps = [ const tableProps = [
{ {
@ -87,7 +88,7 @@ export default {
label: '时间范围', label: '时间范围',
dateType: 'daterange', dateType: 'daterange',
format: 'yyyy-MM-dd', format: 'yyyy-MM-dd',
valueFormat: 'timestamp', valueFormat: 'yyyy-MM-dd',
rangeSeparator: '-', rangeSeparator: '-',
startPlaceholder: '开始时间', startPlaceholder: '开始时间',
endPlaceholder: '结束时间', endPlaceholder: '结束时间',
@ -140,8 +141,12 @@ export default {
this.listQuery.pageSize = 10; this.listQuery.pageSize = 10;
this.listQuery.materialId = val.materialId; this.listQuery.materialId = val.materialId;
this.listQuery.searchTime = val.searchTime ? val.searchTime[0] : null; this.listQuery.searchTime = val.searchTime ? val.searchTime[0] : null;
this.listQuery.startTime = val.searchTime ? val.searchTime[0] : null; this.listQuery.startTime = val.searchTime
this.listQuery.endTime = val.searchTime ? val.searchTime[1] : null; ? moment(val.searchTime[0]).startOf('day').format('x')
: null;
this.listQuery.endTime = val.searchTime
? moment(val.searchTime[1]).endOf('day').format('x')
: null;
this.getDataList(); this.getDataList();
break; break;
case 'export': case 'export':

View File

@ -30,6 +30,7 @@ import {
} from '@/api/cost/costMaterialAutoReport'; } from '@/api/cost/costMaterialAutoReport';
import { getHotMaterialList } from '@/api/base/coreHotMaterial'; import { getHotMaterialList } from '@/api/base/coreHotMaterial';
import { publicFormatter } from '@/utils/dict'; import { publicFormatter } from '@/utils/dict';
import moment from 'moment';
const tableProps = [ const tableProps = [
{ {
@ -73,14 +74,11 @@ export default {
return { return {
urlOptions: { urlOptions: {
getDataListURL: getCostMaterialAutoReportPage, getDataListURL: getCostMaterialAutoReportPage,
exportURL: exportCostMaterialAutoReportExcel exportURL: exportCostMaterialAutoReportExcel,
}, },
tableData: [], tableData: [],
tableProps, tableProps,
drawerVisible: false, drawerVisible: false,
listQuery: {
reportType: 2,
},
formConfig: [ formConfig: [
{ {
type: 'select', type: 'select',
@ -93,7 +91,6 @@ export default {
], ],
param: 'reportType', param: 'reportType',
filterable: true, filterable: true,
defaultSelect: 2, //
clearable: false, clearable: false,
}, },
{ {
@ -108,7 +105,7 @@ export default {
label: '时间范围', label: '时间范围',
dateType: 'daterange', dateType: 'daterange',
format: 'yyyy-MM-dd', format: 'yyyy-MM-dd',
valueFormat: 'timestamp', valueFormat: 'yyyy-MM-dd',
rangeSeparator: '-', rangeSeparator: '-',
startPlaceholder: '开始时间', startPlaceholder: '开始时间',
endPlaceholder: '结束时间', endPlaceholder: '结束时间',
@ -146,13 +143,23 @@ export default {
this.listQuery.pageSize = 10; this.listQuery.pageSize = 10;
this.listQuery.reportType = val.reportType; this.listQuery.reportType = val.reportType;
this.listQuery.materialId = val.materialId; this.listQuery.materialId = val.materialId;
this.listQuery.times = val.searchTime ? val.searchTime : null; this.listQuery.times = val.searchTime
? [
moment(val.searchTime[0]).startOf('day').format('x'),
moment(val.searchTime[1]).endOf('day').format('x'),
]
: null;
this.getDataList(); this.getDataList();
break; break;
case 'export': case 'export':
this.listQuery.reportType = val.reportType; this.listQuery.reportType = val.reportType;
this.listQuery.materialId = val.materialId; this.listQuery.materialId = val.materialId;
this.listQuery.times = val.searchTime ? val.searchTime : null; this.listQuery.times = val.searchTime
? [
moment(val.searchTime[0]).startOf('day').format('x'),
moment(val.searchTime[1]).endOf('day').format('x'),
]
: null;
this.handleExport(); this.handleExport();
break; break;
default: default:

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

View File

@ -0,0 +1,97 @@
<!--
filename: Container.vue
author: liubin
date: 2023-12-05 14:29:53
description: 窑炉容器
-->
<template>
<div class="kiln-container" :class="['kiln-container__' + size]">
<div class="container-hd" style="display: flex; align-items: center">
<i
class=""
style="display: inline-block; margin-left: 12px; padding-top: 4px">
<img :src="imgSrc" width="18" height="16" alt="" />
</i>
<span
style="
color: #fff;
font-size: 20px;
line-height: 2;
margin-left: 6px;
display: inline-block;
">
{{ name }}
</span>
</div>
<div class="container-body">
<slot>
<div class="test-body">something test....</div>
</slot>
</div>
</div>
</template>
<script>
export default {
name: 'KilnContainer',
components: {},
props: ['name', 'width', 'size'],
data() {
return {};
},
computed: {
imgSrc() {
switch (this.name) {
case '原料用量统计':
return require('../assets/move.png');
case '风机运行频率':
return require('../assets/flow.png');
case 'ISRA缺陷检测':
return require('../assets/gas.png');
case '能耗':
return require('../assets/gas.png');
case '窑炉信息':
return require('../assets/gas.png');
case '烟气处理':
return require('../assets/gas.png');
}
},
},
methods: {},
};
</script>
<style scoped lang="scss">
.kiln-container {
display: inline-block;
width: 100%;
height: 100%;
padding: 8px;
display: flex;
flex-direction: column;
position: relative;
&__small {
background: url(../assets/short.png) no-repeat;
background-size: 100% 100%;
background-position: 0 0;
}
&__middle {
background: url(../assets/middle.png) no-repeat;
background-size: 100% 100%;
background-position: 0 0;
}
&__large {
background: url(../assets/high.png) no-repeat;
background-size: 100% 100%;
background-position: 0 0;
}
}
.container-body {
flex: 1;
}
</style>

View File

@ -0,0 +1,84 @@
<!--
filename: DateBtnGroup.vue
author: liubin
date: 2023-12-05 14:35:14
description: 日期按钮组
-->
<template>
<div class="date-btn-group">
<button
class="btn"
:class="{ 'btn-active': active == '日' }"
@click="handleClick('日')">
</button>
<button
class="btn"
:class="{ 'btn-active': active == '周' }"
@click="handleClick('周')">
</button>
<button
class="btn"
:class="{ 'btn-active': active == '月' }"
@click="handleClick('月')">
</button>
</div>
</template>
<script>
export default {
name: 'DateBtnGroup',
data() {
return {
active: '日',
};
},
methods: {
handleClick(v) {
this.active = v;
this.$emit('change', v);
},
},
};
</script>
<style scoped lang="scss">
button {
appearance: none;
border: none;
outline: none;
background: none;
padding: 6px 8px;
}
.date-btn-group {
// position: absolute;
// top: 40px;
// right: 100px;
// border: 1px solid #ccc;
// padding: 12px;
display: flex;
align-items: center;
gap: 12px;
}
.btn {
cursor: pointer;
border: 1px solid #11e8e4;
border-radius: 4px;
color: #11e8e4;
transition: all 0.3s ease-in-out;
&:hover {
background: #11e8e4;
color: #013433;
}
}
.btn-active {
background: #11e8e4;
color: #013433;
}
</style>

View File

@ -0,0 +1,150 @@
<!--
filename: GasChart.vue
author: liubin
date: 2023-12-12 10:53:49
description:
-->
<template>
<div class="gas-chart"></div>
</template>
<script>
import * as echarts from 'echarts';
export default {
name: 'GasChart',
components: {},
props: {},
data() {
const colors = [
'#12FFF5',
'#2760FF',
'#FFD160',
'#E80091',
'#8064ff',
'#ff8a3b',
'#8cd26d',
'#2aa1ff',
];
return {
chart: null,
option: {
color: colors,
grid: { top: 32, right: 12, bottom: 20, left: 48 },
xAxis: {
type: 'category',
data: Array(7)
.fill(1)
.map((_, index) => {
const today = new Date();
const dtimestamp = today - index * 24 * 60 * 60 * 1000;
return `${new Date(dtimestamp).getMonth() + 1}.${new Date(
dtimestamp
).getDate()}`;
})
.reverse(),
axisLabel: {
color: '#fff',
fontSize: 12,
},
axisTick: { show: false },
axisLine: {
lineStyle: {
width: 1,
color: '#213259',
},
},
},
yAxis: {
name: '单位m³/h',
nameTextStyle: {
color: '#fff',
fontSize: 10,
align: 'right',
},
type: 'value',
axisLabel: {
color: '#fff',
fontSize: 12,
},
axisLine: {
show: true,
lineStyle: {
color: '#213259',
},
},
splitLine: {
lineStyle: {
color: '#213259a0',
},
},
},
series: [
Array(7)
.fill(1)
.map((_) => Math.ceil(Math.random() * 100)),
Array(7)
.fill(1)
.map((_) => Math.ceil(Math.random() * 100)),
Array(7)
.fill(1)
.map((_) => Math.ceil(Math.random() * 100)),
].map((v, i) => ({
name: ['总量', '白班', '夜班'][i],
data: v,
type: 'line',
symbol: 'circle',
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
// i % 8 8
{ offset: 0, color: colors[i % 8] + '40' },
{ offset: 0.5, color: colors[i % 8] + '20' },
{ offset: 1, color: colors[i % 8] + '00' },
]),
},
})),
tooltip: {
trigger: 'axis',
},
},
};
},
inject: ['resizeChart'],
computed: {
sidebarStatus() {
return this.$store.state.app.sidebar.opened;
},
},
watch: {
sidebarStatus(val) {
console.log('sidebarStatus', val);
this.chart && this.chart.dispose();
setTimeout(() => {
this.chart = echarts.init(this.$el);
this.chart.setOption(this.option);
}, 500);
},
// resizeChart(val) {
// console.log('resizeChart', val);
// val && this.chart && this.chart.resize();
// },
},
mounted() {
this.$el.addEventListener('resize', () => {
console.log('resziing.....');
});
this.chart = echarts.init(this.$el);
this.chart.setOption(this.option);
},
methods: {},
};
</script>
<style scoped lang="scss">
.gas-chart {
width: 100%;
height: 100%;
}
</style>

View File

@ -0,0 +1,75 @@
<!--
filename: Header.vue
author: liubin
date: 2023-12-05 14:30:46
description: 顶部标题
-->
<template>
<header class="kiln-header">
<h1
style="
font-size: 32px;
margin-bottom: 36px;
color: #0ee8e4;
letter-spacing: 5px;
">
窑炉生产运行驾驶舱
</h1>
<!-- left: 312px; -->
<div
class="firm"
style="
position: absolute;
bottom: 24px;
left: 16.5vw;
color: #fff;
font-size: 16px;
letter-spacing: 1px;
">
单位: 河南汇融科技服务有限公司
</div>
<div
class="datetime"
style="
position: absolute;
bottom: 18px;
right: 15.5vw;
color: #fff;
font-size: 16px;
letter-spacing: 1px;
display: flex;
align-items: center;
gap: 16px;
">
<DateBtnGroup />
{{ new Date().toLocaleString() }}
</div>
</header>
</template>
<script>
import DateBtnGroup from './DateBtnGroup.vue';
export default {
name: 'KilnHeader',
components: { DateBtnGroup },
props: {},
data() {
return {};
},
computed: {},
methods: {},
};
</script>
<style scoped lang="scss">
.kiln-header {
background: url('../assets/head.png') no-repeat;
height: 88px;
background-size: 100%;
background-position: 0 0;
display: grid;
place-content: center;
position: relative;
}
</style>

View File

@ -0,0 +1,235 @@
<!--
filename: ISRAChart.vue
author: liubin
date: 2023-12-12 09:05:25
description:
-->
<template>
<div class="isra-chart"></div>
</template>
<script>
import * as echarts from 'echarts';
export default {
name: 'ISRAChart',
components: {},
props: {},
data() {
return {
chart: null,
option: {
color: ['#2760ff', '#518eec', '#0ee8e4', '#ddb523'],
tooltip: {
trigger: 'item',
},
title: {
text: 11234,
subtext: '总数',
top: '43%',
left: '49%',
textAlign: 'center',
textStyle: {
fontSize: 32,
lineHeight: 16,
color: '#fff',
},
subtextStyle: {
fontSize: 16,
color: '#fff7',
},
},
series: [
{
name: 'Access From',
type: 'pie',
radius: ['60%', '85%'],
avoidLabelOverlap: true,
label: {
show: true,
position: 'outside',
formatter: ({ dataIndex, percent }) => {
// console.log(
// ['#2760ff', '#518eec', '#0ee8e4', '#ddb523'][dataIndex % 4],
// percent
// );
const styleName = ['a', 'b', 'c', 'd'][dataIndex % 4];
return `{${styleName}|${percent}%}`;
},
rich: {
a: {
color: '#2760ff',
fontSize: 18,
borderWidth: 0,
textBorderWidth: 0,
},
b: {
color: '#518eec',
fontSize: 18,
borderWidth: 0,
textBorderWidth: 0,
},
c: {
color: '#0ee8e4',
fontSize: 18,
borderWidth: 0,
textBorderWidth: 0,
},
d: {
color: '#ddb523',
fontSize: 18,
borderWidth: 0,
textBorderWidth: 0,
},
},
},
labelLine: {
show: true,
},
itemStyle: {
borderRadius: 12,
// borderColor: 'transparent',
// borderWidth: 20
},
data: [
{
value: 1048,
name: '缺陷1',
itemStyle: {
color: {
type: 'linear',
x: 1,
y: 1,
x2: 0,
y2: 0,
colorStops: [
{
offset: 0,
color: '#2760ff', // 0%
},
// {
// offset: 0.6,
// color: 'transparent', // 80%
// },
{
offset: 1,
color: '#2760ff33', // 100%
},
],
global: false, // false
},
},
},
{
value: 735,
name: '缺陷2',
itemStyle: {
color: {
type: 'linear',
x: 0,
y: 0,
x2: 1,
y2: 0,
colorStops: [
{
offset: 0,
color: '#518eec', // 0%
},
// {
// offset: 0.6,
// color: 'transparent', // 80%
// },
{
offset: 1,
color: '#518eec33', // 100%
},
],
global: false, // false
},
},
},
{
value: 580,
name: '缺陷3',
itemStyle: {
color: {
type: 'linear',
x: 0,
y: 0,
x2: 1,
y2: 1,
colorStops: [
{
offset: 0,
color: '#0ee8e4', // 0%
},
// {
// offset: 0.6,
// color: 'transparent', // 80%
// },
{
offset: 1,
color: '#0ee8e433', // 100%
},
],
global: false, // false
},
},
},
{
value: 484,
name: '缺陷4',
itemStyle: {
color: {
type: 'linear',
x: 1,
y: 0,
x2: 0,
y2: 0,
colorStops: [
{
offset: 0,
color: '#ddb523', // 0%
},
// {
// offset: 0.6,
// color: 'transparent', // 70%
// },
{
offset: 1,
color: '#ddb52333', // 100%
},
],
global: false, // false
},
},
},
],
},
],
},
};
},
mounted() {
this.initChart();
},
activated() {
// this.initChart();
},
computed: {},
methods: {
initChart() {
this.chart = echarts.init(this.$el);
this.chart.setOption(this.option);
},
},
};
</script>
<style scoped lang="scss">
.isra-chart {
width: 100%;
height: 100%;
}
</style>

View File

@ -0,0 +1,69 @@
<!--
filename: SelectorBtnGroup.vue
author: liubin
date: 2023-12-05 14:28:24
description: 选项按钮组
-->
<template>
<div class="selector-btn-group">
<button
class="btn"
v-for="opt in options"
:key="opt"
@click="active = opt"
:class="active == opt ? 'btn-active' : ''">
{{ opt }}
</button>
</div>
</template>
<script>
export default {
name: 'SelectorBtnGroup',
components: {},
props: ['options'],
data() {
return {
active: this.options[0] || 'default'
};
},
computed: {},
methods: {},
};
</script>
<style scoped lang="scss">
button {
border: none;
appearance: none;
outline: none;
color: red;
font-size: 14px;
padding: 8px 12px;
}
button:first-child {
border-top-left-radius: 8px;
border-bottom-left-radius: 8px;
}
button:last-child {
border-top-right-radius: 8px;
border-bottom-right-radius: 8px;
}
.selector-btn-group {
}
.btn {
background: #03233c;
color: #fff;
cursor: pointer;
transition: all 0.3s ease-out;
&.btn-active,
&:hover {
background: #0f3d5c;
}
}
</style>

View File

@ -0,0 +1,71 @@
<!--
filename: ShadowRect.vue
author: liubin
date: 2023-12-05 14:28:57
description: 阴影矩形
-->
<template>
<div class="shadow-rect" :style="{ borderRadius: rounded ? '8px' : '2px' }">
<slot>
<div
class="test-data"
style="flex: 1; display: flex; align-items: center">
<span
style="
flex: 7;
color: #fff;
text-align: right;
font-size: 18px;
line-height: 1.12;
letter-spacing: 1px;
padding-right: 12px;
">
窑炉压力碹顶加权
</span>
<span
style="
flex: 3;
color: #fff;
text-align: left;
font-size: 18px;
line-height: 1.12;
padding-right: 8px;
">
92Kpa
</span>
</div>
</slot>
</div>
</template>
<script>
export default {
name: '',
components: {},
props: ['rounded'],
data() {
return {};
},
watch: {
rounded(val) {
if (val) {
console.log('val', val);
}
},
},
computed: {},
methods: {},
};
</script>
<style scoped lang="scss">
.shadow-rect {
padding: 8px;
border-radius: 2px;
box-shadow: inset 0 0 8px 2px #ccc3;
color: white;
display: flex;
align-items: center;
}
</style>

View File

@ -0,0 +1,57 @@
<!--
filename: Switcher.vue
author: liubin
date: 2023-12-05 14:29:29
description: 开关
-->
<template>
<div class="switcher" style="display: flex; align-items: center; gap: 12px">
<el-switch v-model="value"></el-switch>
<span style="color: #fff; font-size: 16px">{{ mode }}</span>
;
</div>
</template>
<script>
export default {
name: 'Switcher',
components: {},
props: {},
data() {
return {
value: true,
};
},
computed: {
mode() {
return this.value ? '历史详情' : '实时数据';
},
},
methods: {},
};
</script>
<style scoped lang="scss">
.switcher {
:deep(.el-switch__core) {
border: none;
background-color: #213d566b;
&::after {
background-color: #02457e;
}
}
:deep(.is-checked) {
.el-switch__core {
border: none;
background-color: #b4fffc;
&::after {
background-color: #08d8cd;
}
}
}
}
</style>

View File

@ -0,0 +1,16 @@
export default {
name: 'KilnLine',
props: ['horizontal'],
render: function (h) {
return (
<div
class="line"
style={{
width: this.horizontal ? '100%' : '4px',
height: this.horizontal ? '4px' : '100%',
background:
'radial-gradient(ellipse at center, #3CE7FF, #3CE7FF66, transparent, transparent)',
}}></div>
);
},
};

View File

@ -0,0 +1,101 @@
<!--
filename: MaterialCost.vue
author: liubin
date: 2023-12-06 09:09:27
description:
-->
<template>
<Container name="能耗" size="middle" style="">
<EnergeTop />
<SplitLine :horizontal="true" />
<div class="" style="flex: 2; padding: 8px">
<div
class="header-line"
style="margin-bottom: 8px; display: flex; align-items: center">
<h2 class="" style="margin: 0; color: #0ee8fe; margin-right: 12px">
烟气趋势图
</h2>
<Switcher />
<div>
<span class="lgd lgd-total">总量</span>
<!-- <span class="lgd lgd-day">白班</span>
<span class="lgd lgd-night">夜班</span> -->
</div>
</div>
<div
class="select-line"
style="
display: flex;
align-items: center;
justify-content: space-between;
">
<SelectorBtnGroup
:options="['氧气含量', '二氧化硫', '一氧化氢', '二氧化氢']" />
<SelectorBtnGroup :options="['日', '周', '月', '年']" />
</div>
<div class="chart" style="height: 150px; margin-top: 8px;">
<GasChart />
</div>
</div>
</Container>
</template>
<script>
import Container from '../components/Container.vue';
import ShadowRect from '../components/ShadowRect.vue';
import SplitLine from '../components/line';
import Switcher from '../components/Switcher.vue';
import EnergeTop from './EnergeTop.vue';
import GasChart from '../components/GasChart.vue';
import SelectorBtnGroup from '../components/SelectorBtnGroup.vue';
export default {
name: 'EnergeCost',
components: {
Container,
ShadowRect,
SplitLine,
Switcher,
EnergeTop,
GasChart,
SelectorBtnGroup,
},
props: {},
data() {
return {};
},
computed: {},
methods: {},
};
</script>
<style scoped lang="scss">
.lgd {
color: #fff;
&:not(:last-child) {
margin-right: 12px;
}
}
.lgd::before {
content: '';
display: inline-block;
width: 8px;
height: 8px;
margin-right: 4px;
border-radius: 2px;
}
.lgd.lgd-total::before {
background-color: #ff9e00;
}
.lgd.lgd-day::before {
background-color: #08d8cd;
}
.lgd.lgd-night::before {
background-color: #0b58ff;
}
</style>

View File

@ -0,0 +1,123 @@
<!--
filename: EnergeTop.vue
author: liubin
date: 2023-12-11 09:31:41
description:
-->
<template>
<div
class="energe-top"
style="
flex: 1;
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-template-rows: auto;
gap: 8px;
padding: 4px;
">
<ShadowRect
style="grid-row: 1 / 3; flex-direction: column; justify-content: center">
<span
style="
font-size: 16px;
line-height: 1.55;
text-align: right;
padding-right: 8px;
letter-spacing: 1px;
">
余热发电
</span>
<span
style="
font-size: 16px;
line-height: 1.55;
text-align: right;
padding-right: 8px;
letter-spacing: 1px;
">
1023kWh
</span>
</ShadowRect>
<ShadowRect>
<div
style="
font-size: 16px;
line-height: 1.25;
flex: 1.2;
text-align: right;
padding-right: 8px;
letter-spacing: 3px;
">
<p style="margin: 0; line-height: inherit">水耗量</p>
</div>
<span style="font-size: 16px; line-height: 1.24; flex: 1">32Km³</span>
</ShadowRect>
<ShadowRect>
<div
style="
font-size: 16px;
line-height: 1.25;
flex: 1.2;
text-align: right;
padding-right: 8px;
letter-spacing: 3px;
">
<p style="margin: 0; line-height: inherit">天然气I</p>
</div>
<span style="font-size: 16px; line-height: 1.24; flex: 1">322Km³</span>
</ShadowRect>
<ShadowRect>
<div
style="
font-size: 16px;
line-height: 1.25;
flex: 1.2;
text-align: right;
padding-right: 8px;
letter-spacing: 3px;
">
<p style="margin: 0; line-height: inherit">电耗量</p>
</div>
<span style="font-size: 16px; line-height: 1.24; flex: 1">132kWh</span>
</ShadowRect>
<ShadowRect>
<div
style="
font-size: 16px;
line-height: 1.25;
flex: 1.2;
text-align: right;
padding-right: 8px;
letter-spacing: 3px;
">
<p style="margin: 0; line-height: inherit">天然气II</p>
</div>
<span style="font-size: 16px; line-height: 1.24; flex: 1">992Km³</span>
</ShadowRect>
</div>
</template>
<script>
import ShadowRect from '../components/ShadowRect.vue';
export default {
name: 'EnergeTop',
components: { ShadowRect },
props: {},
data() {
return {};
},
computed: {},
methods: {},
};
</script>
<style scoped lang="scss">
.energe-top {
}
</style>

View File

@ -0,0 +1,58 @@
<!--
filename: FanSequence.vue
author: liubin
date: 2023-12-06 09:40:51
description:
-->
<template>
<Container name="风机运行频率" size="middle" style="">
<div class="" style="position: absolute; top: 18px; left: 180px">
<Switcher />
</div>
<div
class="absolute"
style="
padding: 12px;
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-auto-rows: auto;
gap: 8px;
">
<ShadowRect v-for="n in 14" :key="n" :rounded="false">
<span
style="
font-size: 16px;
line-height: 1.24;
flex: 1.2;
text-align: right;
padding-right: 8px;
letter-spacing: 1px;
">
{{ n }}#风机
</span>
<span style="font-size: 16px; line-height: 1.24; flex: 1">
{{ Math.floor(Math.random() * 100) }}Hz
</span>
</ShadowRect>
</div>
</Container>
</template>
<script>
import Container from '../components/Container.vue';
import ShadowRect from '../components/ShadowRect.vue';
import Switcher from '../components/Switcher.vue';
export default {
name: 'FanSequence',
components: { Container, ShadowRect, Switcher },
props: {},
data() {
return {};
},
computed: {},
methods: {},
};
</script>
<style scoped lang="scss"></style>

View File

@ -0,0 +1,176 @@
<!--
filename: GasHandle.vue
author: liubin
date: 2023-12-11 09:02:40
description:
-->
<template>
<div class="gas-handle" style="flex: 2">
<Container name="烟气处理" size="large" style="">
<div
class=""
style="
flex: 1;
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: auto;
gap: 8px;
padding: 8px;
">
<ShadowRect>
<span
style="
font-size: 16px;
line-height: 1.24;
flex: 1.2;
text-align: right;
padding-right: 8px;
letter-spacing: 1px;
">
氧气含量
</span>
<span style="font-size: 16px; line-height: 1.24; flex: 1">82%</span>
</ShadowRect>
<ShadowRect>
<div
style="
font-size: 16px;
line-height: 1.5;
flex: 1.2;
text-align: right;
padding-right: 8px;
letter-spacing: 3px;
">
<p style="margin: 0; line-height: inherit">一氧化氮</p>
<p style="margin: 0; line-height: inherit">排放浓度</p>
</div>
<span style="font-size: 16px; line-height: 1.24; flex: 1">82%</span>
</ShadowRect>
<ShadowRect>
<div
style="
font-size: 16px;
line-height: 1.5;
flex: 1.2;
text-align: right;
padding-right: 8px;
letter-spacing: 3px;
">
<p style="margin: 0; line-height: inherit">二氧化硫</p>
<p style="margin: 0; line-height: inherit">排放浓度</p>
</div>
<span style="font-size: 16px; line-height: 1.24; flex: 1">82%</span>
</ShadowRect>
<ShadowRect>
<div
style="
font-size: 16px;
line-height: 1.5;
flex: 1.2;
text-align: right;
padding-right: 8px;
letter-spacing: 3px;
">
<p style="margin: 0; line-height: inherit">二氧化氮</p>
<p style="margin: 0; line-height: inherit">排放浓度</p>
</div>
<span style="font-size: 16px; line-height: 1.24; flex: 1">82%</span>
</ShadowRect>
</div>
<KilnLine :horizontal="true" />
<div class="" style="flex: 2; padding: 8px">
<div
class="header-line"
style="margin-bottom: 8px; display: flex; align-items: center">
<h2 class="" style="margin: 0; color: #0ee8fe; margin-right: 12px">
烟气趋势图
</h2>
<Switcher />
<div>
<span class="lgd lgd-total">总量</span>
<span class="lgd lgd-day">白班</span>
<span class="lgd lgd-night">夜班</span>
</div>
</div>
<div
class="select-line"
style="
display: flex;
align-items: center;
justify-content: space-between;
">
<SelectorBtnGroup
:options="['氧气含量', '二氧化硫', '一氧化氢', '二氧化氢']" />
<SelectorBtnGroup :options="['日', '周', '月', '年']" />
</div>
<div class="chart" style="height: 220px">
<GasChart />
</div>
</div>
</Container>
</div>
</template>
<script>
import Container from '../components/Container.vue';
import ShadowRect from '../components/ShadowRect.vue';
import KilnLine from '../components/line';
import Switcher from '../components/Switcher.vue';
import SelectorBtnGroup from '../components/SelectorBtnGroup.vue';
import GasChart from '../components/GasChart.vue';
export default {
name: 'GasHandle',
components: {
Container,
ShadowRect,
KilnLine,
Switcher,
SelectorBtnGroup,
GasChart,
},
props: {},
data() {
return {};
},
computed: {},
methods: {},
};
</script>
<style scoped lang="scss">
.gas-handle {
}
.lgd {
color: #fff;
&:not(:last-child) {
margin-right: 12px;
}
}
.lgd::before {
content: '';
display: inline-block;
width: 8px;
height: 8px;
margin-right: 4px;
border-radius: 2px;
}
.lgd.lgd-total::before {
background-color: #ff9e00;
}
.lgd.lgd-day::before {
background-color: #08d8cd;
}
.lgd.lgd-night::before {
background-color: #0b58ff;
}
</style>

View File

@ -0,0 +1,84 @@
<!--
filename: IsraCheck.vue
author: liubin
date: 2023-12-06 09:50:13
description:
-->
<template>
<Container name="ISRA缺陷检测" size="middle" style="">
<div style="padding: 12px; display: flex; flex-direction: column; gap: 8px; height: 100%;">
<div class="f" style="flex: 9;">
<ISRAChart />
</div>
<ul
class="legend"
style="
flex: 1;
padding: 8px;
display: flex;
justify-content: center;
gap: 20px;
color: #fff;
font-size: 14px;
">
<li class="fault-1">缺陷1</li>
<li class="fault-2">缺陷2</li>
<li class="fault-3">缺陷3</li>
<li class="fault-4">缺陷4</li>
</ul>
</div>
</Container>
</template>
<script>
import Container from '../components/Container.vue';
import ShadowRect from '../components/ShadowRect.vue';
import ISRAChart from '../components/ISRAChart.vue';
export default {
name: 'IsraCheck',
components: { Container, ShadowRect, ISRAChart },
props: {},
data() {
return {};
},
computed: {},
methods: {},
};
</script>
<style scoped lang="scss">
ul,
li {
margin: 0;
padding: 0;
list-style: none;
position: relative;
}
li::before {
content: '';
display: inline-block;
width: 8px;
height: 8px;
border-radius: 50%;
background: #ccc;
position: absolute;
top: 30%;
left: -12px;
}
li.fault-1::before {
background: #2760ff;
}
li.fault-2::before {
background: #518eec;
}
li.fault-3::before {
background: #0ee8e4;
}
li.fault-4::before {
background: #ddb523;
}
</style>

View File

@ -0,0 +1,71 @@
<!--
filename: KilnInfo.vue
author: liubin
date: 2023-12-11 09:01:15
description:
-->
<template>
<div class="kiln-info" style="flex: 1">
<Container name="窑炉信息" size="small" style="">
<div
class="absolute"
style="
padding: 12px;
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-auto-rows: auto;
gap: 8px;
">
<ShadowRect v-for="info in kilnInfo" :key="info.name" :rounded="false">
<span
style="
font-size: 16px;
line-height: 1.45;
flex: 1.2;
text-align: right;
padding-right: 8px;
letter-spacing: 1px;
">
{{ info.name }}
</span>
<span style="font-size: 16px; line-height: 1.45; flex: 1">
{{ info.value }}
<!-- {{ Math.floor(Math.random() * 100) }}Hz -->
</span>
</ShadowRect>
</div>
</Container>
</div>
</template>
<script>
import Container from '../components/Container.vue';
import ShadowRect from '../components/ShadowRect.vue';
export default {
name: 'KilnInfo',
components: { Container, ShadowRect },
props: {},
data() {
return {
kilnInfo: [
{ name: '窑炉压力', value: '83Kpa' },
{ name: '循环水温度', value: '53℃' },
{ name: '循环水流量', value: '23m³/h' },
{ name: '循环水压力', value: '33Kpa' },
{ name: '助燃风压力', value: '12Kpa' },
{ name: '碹顶加权温度', value: '32℃' },
{ name: '压缩气压力', value: '83Kpa' },
{ name: '融化加权温度', value: '123℃' },
],
};
},
computed: {},
methods: {},
};
</script>
<style scoped lang="scss">
.kiln-info {
}
</style>

View File

@ -0,0 +1,41 @@
<!--
filename: LeftFour.vue
author: liubin
date: 2023-12-06 09:35:30
description:
-->
<template>
<div
class="left-four"
style="
display: grid;
gap: 16px;
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr 1fr;
">
<MaterialCost />
<IsraCheck />
<EnergeCost />
<FanSequence />
</div>
</template>
<script>
import MaterialCost from './MaterialCost.vue';
import FanSequence from './FanSequence.vue';
import IsraCheck from './IsraCheck.vue';
import EnergeCost from './EnergeCost.vue';
export default {
name: 'LeftFour',
components: { MaterialCost, EnergeCost, IsraCheck, FanSequence },
props: {},
data() {
return {};
},
computed: {},
methods: {},
};
</script>
<style scoped lang="scss"></style>

View File

@ -0,0 +1,58 @@
<!--
filename: MaterialCost.vue
author: liubin
date: 2023-12-06 09:09:27
description:
-->
<template>
<Container name="原料用量统计" size="middle" style="">
<div
class="absolute"
style="
padding: 12px;
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-auto-rows: auto;
gap: 8px;
">
<ShadowRect v-for="n in 9" :key="n" :rounded="false">
<div
class="material"
style="
flex: 1;
padding: 6px;
display: flex;
flex-direction: column;
gap: 4px;
align-items: center;
justify-content: center;
">
<span style="color: #0ee8e4; font-weight: 500; font-size: 32px">
234
</span>
<span style="color: #fff; font-size: 14px; letter-spacing: 1px">
- 原料1/ -
</span>
</div>
</ShadowRect>
</div>
</Container>
</template>
<script>
import Container from '../components/Container.vue';
import ShadowRect from '../components/ShadowRect.vue';
export default {
name: 'MaterialCost',
components: { Container, ShadowRect },
props: {},
data() {
return {};
},
computed: {},
methods: {},
};
</script>
<style scoped lang="scss"></style>

View File

@ -0,0 +1,37 @@
<!--
filename: RightTwo.vue
author: liubin
date: 2023-12-06 10:19:00
description:
-->
<template>
<div
class="right-two"
style="display: flex; gap: 16px; flex-direction: column">
<KilnInfo />
<GasHandle />
</div>
</template>
<script>
import Container from '../components/Container.vue';
import ShadowRect from '../components/ShadowRect.vue';
import KilnLine from '../components/line';
import Switcher from '../components/Switcher.vue';
import SelectorBtnGroup from '../components/SelectorBtnGroup.vue';
import KilnInfo from './KilnInfo.vue';
import GasHandle from './GasHandle.vue';
export default {
name: 'RightTwo',
components: { Container, Switcher, SelectorBtnGroup, KilnLine, ShadowRect, KilnInfo, GasHandle },
props: {},
data() {
return {};
},
computed: {},
methods: {},
};
</script>
<style scoped lang="scss"></style>

View File

@ -0,0 +1,70 @@
<!--
filename: KilnDataBoard.vue
author: liubin
date: 2023-12-04 16:51:00
description:
-->
<template>
<div
class="KilnDataBoard"
style="
position: absolute;
top: -8px;
left: -16px;
width: calc(100% + 28px);
height: calc(100% + 38px);
display: flex;
flex-direction: column;
gap: 16px;
">
<KHeader />
<div
class="main-body"
style="flex: 1; display: flex; gap: 16px; padding: 8px 16px">
<div class="left-side" style="flex: 2">
<LeftFour />
</div>
<div class="right-side" style="flex: 1">
<RightTwo />
</div>
</div>
</div>
</template>
<script>
import KHeader from '../components/Header.vue';
import LeftFour from './LeftFour.vue';
import RightTwo from './RightTwo.vue';
export default {
name: 'KilnDataBoard',
components: {
KHeader,
LeftFour,
RightTwo,
},
// provide() {
// return {
// resizeChart: null,
// };
// },
mounted() {
// this.$el.addEventListener('resize', () => {
// console.log('resizzzze...')
// this.resizeChart = Math.random();
// });
},
data() {
return {};
},
};
</script>
<style scoped lang="scss">
.KilnDataBoard {
background: url(../assets/bg.png) no-repeat;
background-size: cover;
background-position: 0 0;
}
</style>

View File

@ -106,7 +106,7 @@ export default {
}, },
{ {
type: 'datePicker', type: 'datePicker',
label: '时间', label: '抄表日期',
dateType: 'daterange', dateType: 'daterange',
format: 'yyyy-MM-dd', format: 'yyyy-MM-dd',
valueFormat: "timestamp", valueFormat: "timestamp",

View File

@ -118,8 +118,8 @@ export default {
type: '', type: '',
plcParamId: '', plcParamId: '',
limitType: '', limitType: '',
minValue: null, minValue: 0,
maxValue: null maxValue: 0
}, },
objIds: [],// objIds: [],//
isEdit: false, // isEdit: false, //
@ -239,7 +239,8 @@ export default {
return false return false
} }
} }
// this.form.limitType = Number(this.form.limitType) this.form.minValue = this.form.minValue || 0
this.form.maxValue = this.form.maxValue || 0
if (this.isEdit) { if (this.isEdit) {
// //
updateEnergyLimit({...this.form}).then((res) => { updateEnergyLimit({...this.form}).then((res) => {

View File

@ -116,7 +116,7 @@
style="position: absolute; top: -40px; right: 0"> style="position: absolute; top: -40px; right: 0">
<el-button @click="handleAddAttr" type="text"> <el-button @click="handleAddAttr" type="text">
<i class="el-icon-plus"></i> <i class="el-icon-plus"></i>
添加属性 添加参数
</el-button> </el-button>
</div> </div>
<base-table <base-table

View File

@ -116,7 +116,16 @@ export default {
getGroupClasses(id).then((res) => { getGroupClasses(id).then((res) => {
if (res.code === 0) { if (res.code === 0) {
this.form = res.data this.form = res.data
this.form.disableTime = res.data.disableTime || '' this.form.name = res.data.name
this.form.code = res.data.code
this.form.enableTime = res.data.enableTime
// this.form.disableTime = res.data.disableTime || null
this.$set(this.form, 'disableTime', res.data.disableTime || null)
this.form.startTime = res.data.startTime
this.form.endTime = res.data.endTime
this.form.daySpan = res.data.daySpan
this.form.remark = res.data.remark
console.log(this.form)
} }
}) })
} else { } else {

View File

@ -44,7 +44,7 @@
border-radius: 100%; border-radius: 100%;
background: #26b9de; background: #26b9de;
"></span> "></span>
MES 向世界先进水平挑战为人类社会文明做贡献
</p> </p>
</div> </div>
<video <video
@ -64,18 +64,18 @@
<div class="field"> <div class="field">
<!-- [移动端]标题 --> <!-- [移动端]标题 -->
<h2 class="mobile-title"> <h2 class="mobile-title">
<h3 class="title">中建材智能自动化研究院有限公司</h3> <h3 class="title">许昌安彩新能科技有限公司</h3>
</h2> </h2>
<h2 class="pc-title" style=""> <h2 class="pc-title" style="">
<h3 class="title" style=""> <h3 class="title" style="display: flex; flex-direction: column; align-items: center;">
<img <img
src="../assets/logo/cnbm.png" src="../assets/logo/xcac.png"
alt="cnbm_logo" alt="cnbm_logo"
style="" style=""
class="cnbm_logo" /> class="cnbm_logo" />
<span>中建材智能自动化研究院有限公司</span> <span>许昌安彩新能科技有限公司</span>
</h3> </h3>
<h3 class="sub-title" style="">MES</h3> <!-- <h3 class="sub-title" style="">向世界先进水平挑战为人类社会文明做贡献</h3> -->
</h2> </h2>
<!-- 表单 --> <!-- 表单 -->
@ -166,7 +166,7 @@
<!-- footer --> <!-- footer -->
<div class="footer"> <div class="footer">
Copyright © 2023 中建材智能自动化All Rights Reserved. Copyright © 2023 中建材智能自动化研究有限公司 All Rights Reserved.
</div> </div>
</div> </div>
</div> </div>

View File

@ -165,7 +165,7 @@ const tableProps1 = [
{ {
prop: 'status', prop: 'status',
label: '状态', label: '状态',
filter: publicFormatter('order_status') filter: publicFormatter('work_order_status')
}, },
{ {
prop: 'startProduceTime', prop: 'startProduceTime',

View File

@ -22,7 +22,7 @@
<method-btn <method-btn
v-if="tableBtn.length" v-if="tableBtn.length"
slot="handleBtn" slot="handleBtn"
:width="140" :width="100"
label="操作" label="操作"
:method-list="tableBtn" :method-list="tableBtn"
@clickBtn="handleClick" @clickBtn="handleClick"
@ -190,24 +190,24 @@ export default {
] ]
} }
} }
: undefined,
this.$auth.hasPermi('base:order-completion-monitoring:sendOut')
? {
type: 'sendOutDetail',
btnName: '发货',
showTip: '发货详情',
showParam: {
type: '&',
data: [
{
type: 'more',
name: 'workOrderNum',
value: 1
}
]
}
}
: undefined : undefined
// this.$auth.hasPermi('base:order-completion-monitoring:sendOut')
// ? {
// type: 'sendOutDetail',
// btnName: '',
// showTip: '',
// showParam: {
// type: '&',
// data: [
// {
// type: 'more',
// name: 'workOrderNum',
// value: 1
// }
// ]
// }
// }
// : undefined
].filter((v) => v), ].filter((v) => v),
chartList: [] chartList: []
} }

View File

@ -142,7 +142,9 @@ export default {
console.log(obj); console.log(obj);
this.visible = true; this.visible = true;
// if(obj.id) // if(obj.id)
if (obj) {
this.dataForm.id = obj.id ? obj.id : "" this.dataForm.id = obj.id ? obj.id : ""
}
this.$nextTick(() => { this.$nextTick(() => {
this.$refs["dataForm"].resetFields() this.$refs["dataForm"].resetFields()
if (obj) { if (obj) {

View File

@ -10,8 +10,8 @@
</base-table> </base-table>
<!-- 分页组件 --> <!-- 分页组件 -->
<pagination :limit.sync="listQuery.pageSize" :page.sync="listQuery.pageNo" :total="listQuery.total" <!-- <pagination :limit.sync="listQuery.pageSize" :page.sync="listQuery.pageNo" :total="listQuery.total"
@pagination="getDataList" /> @pagination="getDataList" /> -->
<!-- 对话框(添加 / 修改) --> <!-- 对话框(添加 / 修改) -->
<base-dialog :dialogTitle="addOrEditTitle" :dialogVisible="addOrUpdateVisible" width="50%" @cancel="handleCancel" <base-dialog :dialogTitle="addOrEditTitle" :dialogVisible="addOrUpdateVisible" width="50%" @cancel="handleCancel"
@ -168,7 +168,10 @@ export default {
case 'add': case 'add':
this.addOrEditTitle = '新增'; this.addOrEditTitle = '新增';
this.addOrUpdateVisible = true; this.addOrUpdateVisible = true;
this.addOrUpdateHandle(); // this.addOrUpdateVisible = true;
this.$nextTick(() => {
this.$refs.addOrUpdate.init();
});
break; break;
case 'export': case 'export':
this.handleExport(); this.handleExport();

View File

@ -2,7 +2,7 @@
* @Author: zwq * @Author: zwq
* @Date: 2022-08-24 11:19:43 * @Date: 2022-08-24 11:19:43
* @LastEditors: zhp * @LastEditors: zhp
* @LastEditTime: 2023-12-13 16:19:04 * @LastEditTime: 2023-12-14 09:36:05
* @Description: * @Description:
*/ */
export default { export default {
@ -54,10 +54,10 @@ export default {
this.getDataList(); this.getDataList();
}, },
// 新增 / 修改 // 新增 / 修改
addOrUpdateHandle(id) { addOrUpdateHandle() {
this.addOrUpdateVisible = true; this.addOrUpdateVisible = true;
this.$nextTick(() => { this.$nextTick(() => {
this.$refs.addOrUpdate.init(id); this.$refs.addOrUpdate.init();
}); });
}, },
cancel(id) { cancel(id) {

View File

@ -1,7 +1,7 @@
<!-- <!--
* @Author: zhp * @Author: zhp
* @Date: 2023-12-08 13:46:17 * @Date: 2023-12-08 13:46:17
* @LastEditTime: 2023-12-08 16:09:13 * @LastEditTime: 2023-12-15 16:12:08
* @LastEditors: zhp * @LastEditors: zhp
* @Description: * @Description:
--> -->
@ -13,26 +13,28 @@
<div class="content"> <div class="content">
<!-- <div class="visual-part"> --> <!-- <div class="visual-part"> -->
<el-form :model="dataForm" :rules="dataRule" ref="dataForm" @keyup.enter.native="dataFormSubmit()" <el-form :model="dataForm" :rules="dataRule" ref="dataForm" @keyup.enter.native="dataFormSubmit()"
label-width="100px" label-position="top"> label-width="auto">
<el-row :gutter="24"> <el-row :gutter="24">
<el-col :span="8"> <el-col :span="8">
<el-form-item label="供应商" prop="supplierId"> <el-form-item label="供应商" prop="supplierId"
<el-select v-model="dataForm.supplierId" filterable :disabled="isdetail" style="width: 100%" :rules="[{ required: true, message: '供应商不能为空', trigger: 'change' }]">
placeholder="请选择供应商"> <el-select v-model="dataForm.supplierId" filterable :disabled="isdetail" placeholder="请选择供应商">
<el-option v-for="dict in supplierList" :key=" dict.id" :label="dict.name" :value="dict.id" /> <el-option v-for="dict in supplierList" :key=" dict.id" :label="dict.name" :value="dict.id" />
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="8"> <el-col :span="8">
<el-form-item label="原料" prop="materialId"> <el-form-item label="原料" prop="materialId"
<el-select v-model="dataForm.materialId" filterable :disabled="isdetail" style="width: 100%" :rules="[{ required: true, message: '原料不能为空', trigger: 'change' }]">
@change="getData" placeholder="请选择原料"> <el-select v-model="dataForm.materialId" filterable :disabled="isdetail" @change="getData"
placeholder="请选择原料">
<el-option v-for="dict in materialList" :key=" dict.id" :label="dict.name" :value="dict.id" /> <el-option v-for="dict in materialList" :key=" dict.id" :label="dict.name" :value="dict.id" />
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="8"> <el-col :span="8">
<el-form-item label="样品编码" prop="sampleCode"> <el-form-item label="样品编码" prop="sampleCode"
:rules="[{ required: true, message: '样品编号不能为空', trigger: 'blur' }]">
<el-input v-model="dataForm.sampleCode" clearable :disabled="isdetail" placeholder="请输入样品编码" /> <el-input v-model="dataForm.sampleCode" clearable :disabled="isdetail" placeholder="请输入样品编码" />
</el-form-item> </el-form-item>
</el-col> </el-col>
@ -40,28 +42,79 @@
<el-row :gutter="24"> <el-row :gutter="24">
<el-col :span="8"> <el-col :span="8">
<el-form-item label="取样人" prop="samplerId"> <el-form-item label="取样人" prop="samplerId">
<el-select v-model="dataForm.samplerId" filterable :disabled="isdetail" style="width: 100%" <el-select v-model="dataForm.samplerId" filterable :disabled="isdetail" placeholder="请选择取样人">
placeholder="请选择取样人">
<el-option v-for="dict in workerList" :key=" dict.id" :label="dict.name" :value="dict.id" /> <el-option v-for="dict in workerList" :key=" dict.id" :label="dict.name" :value="dict.id" />
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="8"> <el-col :span="8">
<el-form-item label="检测人" prop="checkerId"> <el-form-item label="检测人" prop="checkerId"
<el-select v-model="dataForm.checkerId" filterable :disabled="isdetail" style="width: 100%" :rules="[{ required: true, message: '检测人不能为空', trigger: 'change' }]">
placeholder="请选择检测人"> <el-select v-model="dataForm.checkerId" filterable :disabled="isdetail" placeholder="请选择检测人">
<el-option v-for="dict in workerList" :key=" dict.id" :label="dict.name" :value="dict.id" /> <el-option v-for="dict in workerList" :key=" dict.id" :label="dict.name" :value="dict.id" />
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="8"> <el-col :span="8">
<el-form-item label="检测时间" prop="checkTime"> <el-form-item label="检测时间" prop="checkTime"
:rules="[{ required: true, message: '检测时间不能为空', trigger: 'change' }]">
<el-date-picker v-model="dataForm.checkTime" type="datetime" placeholder="选择检测时间"> <el-date-picker v-model="dataForm.checkTime" type="datetime" placeholder="选择检测时间">
</el-date-picker> </el-date-picker>
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
<el-divider content-position="center">检测结果</el-divider>
<el-row :gutter="24">
<el-form-item label="外观合格" prop="appearance">
<el-radio :disabled="isdetail" v-model="dataForm.appearance" :label="true">合格</el-radio>
<el-radio :disabled="isdetail" v-model="dataForm.appearance" :label="false">不合格</el-radio>
</el-form-item>
</el-row>
<el-row :gutter="24" v-for="(item,index) in ingredientList" :key="item.id">
<el-col :span="8">
<el-form-item label="成分">
{{ item.name }}
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item :prop="'checkValueList.' + index + '.checkValue'" label="成分含量"
:rules="[{ required: true, message: '成分含量不能为空', trigger: 'blur' }]">
<el-input :disabled="isdetail" style="width: 90%;margin-right: 10px;" :max="item.maxValue"
:min='item.minValue' v-model="dataForm.checkValueList[index].checkValue"
@change="judgeValue(arguments[0],item.minValue,item.maxValue,index)"></el-input>
<span v-if="dataForm.checkValueList[index].showIcon">
<!-- <i class="el-icon-success"></i> -->
<svg-icon v-if="dataForm.checkValueList[index].isStandard" icon-class="standards" />
<svg-icon v-else icon-class="noStandards" />
</span>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="24">
<el-col :span="8">
<el-form-item label="判断结果" prop="checkResult">
<el-select :disabled="isdetail" v-model="dataForm.checkResult" placeholder="请选择">
<el-option v-for="item in checkResultList" :key="item.id" :label="item.name" :value="item.id">
</el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="原料等级" prop="materialGrade">
<el-select :disabled="isdetail" v-model="dataForm.materialGrade" placeholder="请选择" style="width: 100%;">
<el-option v-for="item in gradeList" :key="item.value" :label="item.label" :value="item.value">
</el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-form-item label="备注" prop="remark">
<el-input :disabled="isdetail" v-model="dataForm.remark" placeholder="请填写备注" style="width: 100%;">
</el-input>
</el-form-item>
</el-form> </el-form>
<!-- </div> --> <!-- </div> -->
<div class="attr-list" v-if="idAttrShow"> <div class="attr-list" v-if="idAttrShow">
<!-- <small-title style="margin: 16px 0; padding-left: 8px" :no-padding="true"> <!-- <small-title style="margin: 16px 0; padding-left: 8px" :no-padding="true">
@ -101,9 +154,15 @@ import {
getHotMaterialAllList, getHotMaterialAllList,
getSupplierList, getSupplierList,
getWorkerList, getWorkerList,
getMaterialCheckList getMaterialCheckList,
createQualityHotMaterialDet,
updateQualityHotMaterialDet,
getQualityHotMaterialDetList
} from '@/api/base/qualityHotMaterial'; } from '@/api/base/qualityHotMaterial';
import SmallTitle from './SmallTitle'; import SmallTitle from './SmallTitle';
import { DICT_TYPE, getDictDatas } from "@/utils/dict";
import { create } from 'domain';
// import { parseTime } from '../../core/mixins/code-filter'; // import { parseTime } from '../../core/mixins/code-filter';
// import attrAdd from './attr-add'; // import attrAdd from './attr-add';
// import {DICT_TYPE, getDictDatas} from "@/utils/dict"; // import {DICT_TYPE, getDictDatas} from "@/utils/dict";
@ -131,6 +190,16 @@ export default {
updateURL: updateQualityHotMaterial, updateURL: updateQualityHotMaterial,
infoURL: getQualityHotMaterial, infoURL: getQualityHotMaterial,
}, },
gradeList:[],
checkResultList: [{
id: true,
name:'合格',
},
{
id: false,
name: '不合格',
}
],
listQuery: { listQuery: {
pageSize: 10, pageSize: 10,
pageNo: 1, pageNo: 1,
@ -140,6 +209,8 @@ export default {
workerList: [], workerList: [],
supplierList:[], supplierList:[],
equipmentList: [], equipmentList: [],
ingredientFlag:false,
ingredientList:[],
dataForm: { dataForm: {
id: undefined, id: undefined,
materialId:null, materialId:null,
@ -151,6 +222,10 @@ export default {
appearance: null, appearance: null,
checkResult: null, checkResult: null,
materialGrade: null, materialGrade: null,
checkValueList: [],
checkResult: '',
materialGrade: undefined,
remark:null,
}, },
productAttrList: [], productAttrList: [],
visible: false, visible: false,
@ -168,6 +243,15 @@ export default {
mounted() { mounted() {
}, },
methods: { methods: {
judgeValue(val, minValue, maxValue, index) {
if (val >= minValue && val <= maxValue) {
this.dataForm.checkValueList[index].showIcon = true
this.dataForm.checkValueList[index].isStandard = true
} else {
this.dataForm.checkValueList[index].showIcon = true
this.dataForm.checkValueList[index].isStandard = false
}
},
dataFormSubmit() { dataFormSubmit() {
this.$refs["dataForm"].validate((valid) => { this.$refs["dataForm"].validate((valid) => {
if (!valid) { if (!valid) {
@ -175,28 +259,111 @@ export default {
} }
// //
if (this.dataForm.id) { if (this.dataForm.id) {
this.urlOptions.updateURL(this.dataForm).then(response => { let obj = {
this.$modal.msgSuccess("修改成功"); id: this.dataForm.id,
materialId: this.dataForm.materialId,
supplierId: this.dataForm.supplierId,
sampleCode: this.dataForm.sampleCode,
samplerId: this.dataForm.samplerId,
checkerId: this.dataForm.checkerId,
checkTime: this.dataForm.checkTime,
appearance: this.dataForm.appearance,
checkResult: this.dataForm.checkResult,
materialGrade: this.dataForm.materialGrade,
// checkValueList: [],
checkResult: this.dataForm.checkResult,
materialGrade: this.dataForm.materialGrade,
remark: this.dataForm.remark
}
this.urlOptions.updateURL(obj).then(response => {
let array = []
this.dataForm.checkValueList.forEach(ele => {
array.push(this.updateDet({
mainId: this.dataForm.id,
id:ele.id,
checkDetId: ele.checkDetId,
checkValue: ele.checkValue
}))
})
Promise.all(array).then(res => {
console.log(res)
this.visible = false; this.visible = false;
this.$emit("refreshDataList"); this.$emit("refreshDataList");
}).catch(error => {
// catch
console.log(error)
})
}); });
return; return;
} }
// //
this.urlOptions.createURL(this.dataForm).then(response => { let obj = {
// id: this.dataForm.id,
materialId: this.dataForm.materialId,
supplierId: this.dataForm.supplierId,
sampleCode: this.dataForm.sampleCode,
samplerId: this.dataForm.samplerId,
checkerId: this.dataForm.checkerId,
checkTime: this.dataForm.checkTime,
appearance: this.dataForm.appearance,
checkResult: this.dataForm.checkResult,
materialGrade: this.dataForm.materialGrade,
// checkValueList: [],
checkResult: this.dataForm.checkResult,
materialGrade: this.dataForm.materialGrade,
remark:this.dataForm.remark
}
this.urlOptions.createURL(obj).then(response => {
// this.idAttrShow = true;
let array = []
this.dataForm.checkValueList.forEach(ele => {
array.push(this.createDet({
mainId: response.data,
checkDetId: ele.checkDetId,
checkValue: ele.checkValue
}))
})
Promise.all(array).then(res => {
this.$modal.msgSuccess("新增成功"); this.$modal.msgSuccess("新增成功");
this.idAttrShow = true; this.visible = false;
this.dataForm.id = res.data
this.$emit("refreshDataList"); this.$emit("refreshDataList");
}).catch(error => {
// catch
console.log(error)
})
// this.dataForm.id = res.data
}); });
}); });
}, },
createDet(obj) {
return createQualityHotMaterialDet(obj).then((response) => {
return response.data
})
},
updateDet(obj) {
return updateQualityHotMaterialDet(obj).then((response) => {
return response.data
})
},
getData(val) { getData(val) {
console.log(val); console.log(val);
getMaterialCheckList({ getMaterialCheckList({
materialId:val materialId:val
}).then((res) => { }).then((res) => {
console.log(res); this.ingredientList = res.data
this.ingredientFlag = true
this.dataForm.checkValueList = res.data.map((ele) => {
return {
mainId: null,
checkDetId: ele.id,
checkValue: null,
isStandard: true,
showIcon:false,
}
})
// this.$set()
console.log(this.dataForm);
}) })
}, },
// clickTopBtn(val) { // clickTopBtn(val) {
@ -208,7 +375,7 @@ export default {
this.productAttrList.splice(0); this.productAttrList.splice(0);
this.listQuery.total = 0; this.listQuery.total = 0;
}, },
getDict() { async getDict() {
getHotMaterialAllList().then((res) => { getHotMaterialAllList().then((res) => {
this.materialList = res.data this.materialList = res.data
}) })
@ -218,49 +385,52 @@ export default {
getSupplierList().then(res => { getSupplierList().then(res => {
this.supplierList = res.data this.supplierList = res.data
}) })
const res = await getDictDatas(this.DICT_TYPE.EQU_ALARM_LEVEL)
console.log('111', res)
this.gradeList = res
}, },
handleClick(raw) { // handleClick(raw) {
if (raw.type === 'delete') { // if (raw.type === 'delete') {
this.$confirm( // this.$confirm(
`确定对${ // `${
raw.data.materialName // raw.data.materialName
? '[物料名称为' + raw.data.materialName + ']' // ? '[' + raw.data.materialName + ']'
: '[序号为' + raw.data.materialName + ']' // : '[' + raw.data.materialName + ']'
}进行删除操作?`, // }?`,
'提示', // '',
{ // {
confirmButtonText: '确定', // confirmButtonText: '',
cancelButtonText: '取消', // cancelButtonText: '',
type: 'warning', // type: 'warning',
} // }
) // )
.then(() => { // .then(() => {
deleteProcessEquMaterialBomDet(raw.data.id).then(({ data }) => { // deleteProcessEquMaterialBomDet(raw.data.id).then(({ data }) => {
this.$message({ // this.$message({
message: '操作成功', // message: '',
type: 'success', // type: 'success',
duration: 1500, // duration: 1500,
onClose: () => { // onClose: () => {
this.getList(); // this.getList();
}, // },
}); // });
}); // });
}) // })
.catch(() => {}); // .catch(() => {});
} else { // } else {
this.addNew(raw.data.id); // this.addNew(raw.data.id);
} // }
}, // },
getList() { // getList() {
// // //
processEquMaterialBomDetPage({ // processEquMaterialBomDetPage({
...this.listQuery, // ...this.listQuery,
bomId: this.dataForm.id, // bomId: this.dataForm.id,
}).then((response) => { // }).then((response) => {
this.productAttrList = response.data.list; // this.productAttrList = response.data.list;
this.listQuery.total = response.data.total; // this.listQuery.total = response.data.total;
}); // });
}, // },
init(id, isdetail) { init(id, isdetail) {
this.initData() this.initData()
this.getDict() this.getDict()
@ -278,18 +448,50 @@ export default {
if (this.dataForm.id) { if (this.dataForm.id) {
// //
this.urlOptions.infoURL({ let valueList = []
bomId: id, this.urlOptions.infoURL(id).then(response => {
pageNo: 1,
pageSize:10
}).then(response => {
this.dataForm = response.data this.dataForm = response.data
this.dataForm.unit = String(this.dataForm.unit) getMaterialCheckList({
this.dataForm.materialType = String(this.dataForm.materialType) materialId: response.data.materialId
this.dataForm.productType = String(this.dataForm.productType) }).then((res) => {
console.log(res.data);
this.ingredientList = res.data
valueList = this.ingredientList.map((ele) => {
// console.log(ele)
return {
maxValue: ele.maxValue,
minValue: ele.minValue
}
})
getQualityHotMaterialDetList({
mainId: response.data.id
}).then((result) => {
this.dataForm.checkValueList = result.data.map((ele) => {
return {
mainId: ele.mainId,
id: ele.id,
checkDetId: ele.id,
checkValue: ele.checkValue,
isStandard: true,
showIcon: false,
}
})
valueList.forEach((ele,index) => {
console.log(ele);
if (this.dataForm.checkValueList[index].checkValue >= ele.minValue && this.dataForm.checkValueList[index].checkValue <= ele.maxValue) {
this.dataForm.checkValueList[index].showIcon = true
this.dataForm.checkValueList[index].isStandard = true
} else {
this.dataForm.checkValueList[index].showIcon = true
this.dataForm.checkValueList[index].isStandard = false
}
// })
})
})
}); });
})
// //
this.getList(); // this.getList();
} else { } else {
if (this.urlOptions.isGetCode) { if (this.urlOptions.isGetCode) {
this.getCode() this.getCode()
@ -322,10 +524,6 @@ export default {
flex-direction: column; flex-direction: column;
} }
.drawer >>> .el-form-item__label {
padding: 0;
}
.drawer >>> .el-drawer__header { .drawer >>> .el-drawer__header {
margin: 0; margin: 0;
padding: 32px 32px 24px; padding: 32px 32px 24px;

View File

@ -77,13 +77,19 @@ export default {
}, },
tableProps, tableProps,
tableBtn: [ tableBtn: [
this.$auth.hasPermi(`base:quality-inspection-det:update`) this.$auth.hasPermi(`base:quality-hot-material:update`)
? { ? {
type: 'edit', type: 'edit',
btnName: '编辑', btnName: '编辑',
} }
: undefined, : undefined,
this.$auth.hasPermi(`base:quality-inspection-det:delete`) this.$auth.hasPermi(`base:quality-hot-material:detail`)
? {
type: 'detail',
btnName: '详情',
}
: undefined,
this.$auth.hasPermi(`base:quality-hot-material:delete`)
? { ? {
type: 'delete', type: 'delete',
btnName: '删除', btnName: '删除',
@ -133,6 +139,15 @@ export default {
this.getDict(); this.getDict();
}, },
methods: { methods: {
otherMethods(val) {
if (val.type === 'detail') {
this.addOrUpdateVisible = true;
this.addOrEditTitle = "详情";
this.$nextTick(() => {
this.$refs.addOrUpdate.init(val.data.id, true);
});
}
},
// //
getDataList() { getDataList() {
this.dataListLoading = true; this.dataListLoading = true;

View File

@ -100,6 +100,7 @@ export default {
startPlaceholder: '开始日期', startPlaceholder: '开始日期',
endPlaceholder: '结束日期', endPlaceholder: '结束日期',
defaultTime: ['00:00:00', '23:59:59'], defaultTime: ['00:00:00', '23:59:59'],
defaultSelect: [],
param: 'checkTime', param: 'checkTime',
// width: 350, // width: 350,
}, },
@ -263,6 +264,12 @@ export default {
this.searchBarFormConfig[0].defaultSelect = this.$route.query.woIdString.split(',') this.searchBarFormConfig[0].defaultSelect = this.$route.query.woIdString.split(',')
console.log(this.searchBarFormConfig[0].defaultSelect); console.log(this.searchBarFormConfig[0].defaultSelect);
} }
if (this.$route.query.startTime && this.$route.query.endTime) {
// console.log(this.$route.query.startTime);
this.searchBarFormConfig[2].defaultSelect = [moment(Number(this.$route.query.startTime)).format('yyyy-MM-DD HH:mm:ss'), moment(Number(this.$route.query.endTime)).format('yyyy-MM-DD HH:mm:ss'),]
this.queryParams.startTime = moment(Number(this.$route.query.startTime)).format('yyyy-MM-DD HH:mm:ss')
this.queryParams.endTime = moment(Number(this.$route.query.endTime)).format('yyyy-MM-DD HH:mm:ss')
}
// if (this.$route.params.startTime && this.$route.params.endTime) { // if (this.$route.params.startTime && this.$route.params.endTime) {
// this.searchBarFormConfig[0].defaultSelect = [ // this.searchBarFormConfig[0].defaultSelect = [
// this.$route.params.startTime, // this.$route.params.startTime,

View File

@ -1,7 +1,7 @@
<!-- <!--
* @Author: zhp * @Author: zhp
* @Date: 2023-12-12 13:45:25 * @Date: 2023-12-12 13:45:25
* @LastEditTime: 2023-12-13 15:17:53 * @LastEditTime: 2023-12-14 14:56:38
* @LastEditors: zhp * @LastEditors: zhp
* @Description: * @Description:
--> -->
@ -483,7 +483,7 @@ export default {
await updateProductionDataList(updateArr), await updateProductionDataList(updateArr),
]); ]);
if (result[0] == true && result[1] == true) { if (result[0] == true && result[1] == true) {
console.log(res) // console.log(res)
this.disabled = true this.disabled = true
this.isSave = false this.isSave = false
this.getDataList() this.getDataList()

View File

@ -1,7 +1,7 @@
<!-- <!--
* @Author: zhp * @Author: zhp
* @Date: 2023-12-12 13:45:25 * @Date: 2023-12-12 13:45:25
* @LastEditTime: 2023-12-13 16:55:27 * @LastEditTime: 2023-12-14 14:56:40
* @LastEditors: zhp * @LastEditors: zhp
* @Description: * @Description:
--> -->
@ -24,100 +24,132 @@
color: '#606266' color: '#606266'
}"> }">
<el-table-column :label="'许昌安彩月成品生产汇总' + timeTips" align="center"> <el-table-column :label="'许昌安彩月成品生产汇总' + timeTips" align="center">
<el-table-column prop="glassType" label="品种"> <el-table-column prop="glassType" label="品种" align="center">
<template slot-scope="scope"> <template slot-scope="scope">
<el-input v-if="scope.row.det === true" v-model="scope.row.glassType" :disabled="disabled"></el-input> <el-input v-if="scope.row.det === true" v-model="scope.row.glassType" :disabled="disabled"></el-input>
<span v-else>{{ scope.row.glassType }} </span> <span v-else>{{ scope.row.glassType }} </span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="规格"> <el-table-column label="规格" align="center">
<el-table-column prop="inputNow" label="本周"> <el-table-column label="成品" align="center">
<el-table-column :show-header="false">
<template slot-scope="scope"> <template slot-scope="scope">
<el-input v-if="scope.row.det === true" v-model="scope.row.inputNow" :disabled="disabled"></el-input> <el-input v-if="scope.row.det === true" v-model="scope.row.productionL" :disabled="disabled"></el-input>
<span v-else>{{ scope.row.inputNow }} </span> <span v-else>{{ scope.row.productionL }} </span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="inputHis" label="上周"> <el-table-column :show-header="false">
<template slot-scope="scope"> <template slot-scope="scope">
<el-input v-if="scope.row.det === true" v-model="scope.row.inputHis" :disabled="disabled"></el-input> <el-input v-if="scope.row.det === true" v-model="scope.row.productionW" :disabled="disabled"></el-input>
<span v-else>{{ scope.row.inputHis }} </span> <span v-else>{{ scope.row.productionW }} </span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="inputTrend" label="增减"> <el-table-column :show-header="false">
<template slot-scope="scope"> <template slot-scope="scope">
<el-input v-if="scope.row.det === true" v-model="scope.row.inputTrend" :disabled="disabled"></el-input> <el-input v-if="scope.row.det === true" v-model="scope.row.productionH" :disabled="disabled"></el-input>
<span v-else>{{ scope.row.inputTrend }} </span> <span v-else>{{ scope.row.productionH }} </span>
</template> </template>
</el-table-column> </el-table-column>
</el-table-column> </el-table-column>
<el-table-column label="完成良品产量"> <el-table-column label="原片">
<el-table-column prop="goodProductNow" label="本周"> <el-table-column prop="originalGlassSize">
<template slot-scope="scope"> <template slot-scope="scope">
<el-input v-if="scope.row.det === true" v-model="scope.row.goodProductNow" :disabled="disabled"> <el-input v-if="scope.row.det === true" v-model="scope.row.originalGlassSize" :disabled="disabled">
</el-input> </el-input>
<span v-else>{{ scope.row.goodProductNow }} </span> <span v-else>{{ scope.row.originalGlassSize }} </span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="goodProductHis" label="上周"> </el-table-column>
</el-table-column>
</el-table-column>
<!-- <el-table-column label="完成良品产量"> -->
<el-table-column prop="customerId" label="用户">
<template slot-scope="scope"> <template slot-scope="scope">
<el-input v-if="scope.row.det === true" v-model="scope.row.goodProductHis" :disabled="disabled"> <el-input v-if="scope.row.det === true" v-model="scope.row.customerId" :disabled="disabled">
</el-input> </el-input>
<span v-else>{{ scope.row.goodProductHis }} </span> <span v-else>{{ scope.row.customerId }} </span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="goodProductTrend" label="增减"> <el-table-column prop="packageType" label="包装形式">
<template slot-scope="scope"> <template slot-scope="scope">
<el-input v-if="scope.row.det === true" v-model="scope.row.goodProductTrend" :disabled="disabled"> <el-input v-if="scope.row.det === true" v-model="scope.row.packageType" :disabled="disabled">
</el-input> </el-input>
<span v-else>{{ scope.row.goodProductTrend }} </span> <span v-else>{{ scope.row.packageType }} </span>
</template> </template>
</el-table-column> </el-table-column>
</el-table-column> <el-table-column prop="orderNum" label="订单数量">
<el-table-column label="原片漏检率">
<el-table-column prop="missCheckNow" label="本周">
<template slot-scope="scope"> <template slot-scope="scope">
<el-input v-if="scope.row.det === true" v-model="scope.row.missCheckNow" :disabled="disabled"></el-input> <el-input v-if="scope.row.det === true" v-model="scope.row.orderNum" :disabled="disabled">
<span v-else>{{ scope.row.missCheckNow }} </span>
</template>
</el-table-column>
<el-table-column prop="missCheckHis" label="上周">
<template slot-scope="scope">
<el-input v-if="scope.row.det === true" v-model="scope.row.missCheckHis" :disabled="disabled"></el-input>
<span v-else>{{ scope.row.missCheckHis }} </span>
</template>
</el-table-column>
<el-table-column prop="missCheckTrend" label="增减">
<template slot-scope="scope">
<el-input v-if="scope.row.det === true" v-model="scope.row.missCheckTrend" :disabled="disabled">
</el-input> </el-input>
<span v-else>{{ scope.row.missCheckTrend }} </span> <span v-else>{{ scope.row.orderNum }} </span>
</template> </template>
</el-table-column> </el-table-column>
</el-table-column> <el-table-column prop="orderFinish" label="订单完成">
<el-table-column label="综合良品率">
<el-table-column prop="goodProductPassNow" label="本周">
<template slot-scope="scope"> <template slot-scope="scope">
<el-input v-if="scope.row.det === true" v-model="scope.row.goodProductPassNow" :disabled="disabled"> <el-input v-if="scope.row.det === true" v-model="scope.row.orderFinish" :disabled="disabled">
</el-input> </el-input>
<span v-else>{{ scope.row.goodProductPassNow }} </span> <span v-else>{{ scope.row.orderFinish }} </span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="goodProductPassHis" label="上周"> <el-table-column prop="orderRemaining" label="未完成订单">
<template slot-scope="scope"> <template slot-scope="scope">
<el-input v-if="scope.row.det === true" v-model="scope.row.goodProductPassHis" :disabled="disabled"> <el-input v-if="scope.row.det === true" v-model="scope.row.orderRemaining" :disabled="disabled">
</el-input> </el-input>
<span v-else>{{ scope.row.goodProductPassHis }} </span> <span v-else>{{ scope.row.orderRemaining }} </span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="goodProductPassTrend" label="增减"> <el-table-column prop="stockLastMonth" label="上月库存">
<template slot-scope="scope"> <template slot-scope="scope">
<el-input v-if="scope.row.det === true" v-model="scope.row.goodProductPassTrend" :disabled="disabled"> <el-input v-if="scope.row.det === true" v-model="scope.row.stockLastMonth" :disabled="disabled">
</el-input> </el-input>
<span v-else>{{ scope.row.goodProductPassTrend }} </span> <span v-else>{{ scope.row.stockLastMonth }} </span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="productNumThisMonth" label="本月生产成品">
<template slot-scope="scope">
<el-input v-if="scope.row.det === true" v-model="scope.row.productNumThisMonth" :disabled="disabled">
</el-input>
<span v-else>{{ scope.row.productNumThisMonth }} </span>
</template>
</el-table-column> </el-table-column>
<el-table-column prop="deliveNum" label="发货量">
<template slot-scope="scope">
<el-input v-if="scope.row.det === true" v-model="scope.row.deliveNum" :disabled="disabled">
</el-input>
<span v-else>{{ scope.row.deliveNum }} </span>
</template>
</el-table-column> </el-table-column>
<el-table-column prop="undeliveNum" label="未发货量">
<template slot-scope="scope">
<el-input v-if="scope.row.det === true" v-model="scope.row.undeliveNum" :disabled="disabled">
</el-input>
<span v-else>{{ scope.row.undeliveNum }} </span>
</template>
</el-table-column>
<el-table-column prop="undeliveArea" label="未发货面积">
<template slot-scope="scope">
<el-input v-if="scope.row.det === true" v-model="scope.row.undeliveArea" :disabled="disabled">
</el-input>
<span v-else>{{ scope.row.undeliveArea }} </span>
</template>
</el-table-column>
<el-table-column prop="deliveArea" label="发货面积">
<template slot-scope="scope">
<el-input v-if="scope.row.det === true" v-model="scope.row.deliveArea" :disabled="disabled">
</el-input>
<span v-else>{{ scope.row.deliveArea }} </span>
</template>
</el-table-column>
<el-table-column prop="productAreaThisMonth" label="本月生产面积">
<template slot-scope="scope">
<el-input v-if="scope.row.det === true" v-model="scope.row.productAreaThisMonth" :disabled="disabled">
</el-input>
<span v-else>{{ scope.row.productAreaThisMonth }} </span>
</template>
</el-table-column>
<!-- </el-table-column> -->
<div style="height: 50px;" class="remark" slot="append"> <div style="height: 50px;" class="remark" slot="append">
<h3 style="float: left;text-align: center;margin-left: 20px;">备注</h3> <h3 style="float: left;text-align: center;margin-left: 20px;">备注</h3>
<el-input :disabled="disabled" style="float:right;width: 96%;margin-top: 8px;" v-model="remark"></el-input> <el-input :disabled="disabled" style="float:right;width: 96%;margin-top: 8px;" v-model="remark"></el-input>
@ -143,8 +175,8 @@
<script> <script>
import { import {
getAutoDeliveDataList, getAutoDeliveDataList,
updateProductionDataList, updateSumAutoDeliveDataList,
updateSumProductionDataList updateAutoDeliveDataList
} from '@/api/report/production'; } from '@/api/report/production';
// import Editor from '@/components/Editor'; // import Editor from '@/components/Editor';
import moment from 'moment'; import moment from 'moment';
@ -482,10 +514,10 @@ export default {
// console.log(JSON.stringify(updateArr[1])) // console.log(JSON.stringify(updateArr[1]))
const result = await Promise.all([ const result = await Promise.all([
await updateSumProductionDataList(obj), await updateSumProductionDataList(obj),
await updateProductionDataList(updateArr), await updateAutoDeliveDataList(updateArr),
]); ]);
if (result[0] == true && result[1] == true) { if (result[0] == true && result[1] == true) {
console.log(res) // console.log(res)
this.disabled = true this.disabled = true
this.isSave = false this.isSave = false
this.getDataList() this.getDataList()
@ -519,12 +551,12 @@ export default {
// sum = res.data.list.splice(index, 1) // sum = res.data.list.splice(index, 1)
// } // }
// }) // })
// res.data.forEach((ele,index) => { res.data.forEach((ele,index) => {
// if (ele.det === false) { if (ele.det === false) {
// res.data.list[index].lineId = '' res.data[index].glassType = '合计'
// this.remark = res.data.list[index].remark this.remark = res.data[index].remark
// } }
// }); });
this.list = res.data this.list = res.data
}, },
}, },

View File

@ -1,7 +1,7 @@
<!-- <!--
* @Author: zhp * @Author: zhp
* @Date: 2023-12-12 13:45:25 * @Date: 2023-12-12 13:45:25
* @LastEditTime: 2023-12-13 15:17:39 * @LastEditTime: 2023-12-14 14:56:37
* @LastEditors: zhp * @LastEditors: zhp
* @Description: * @Description:
--> -->
@ -410,8 +410,8 @@ export default {
await updateSumProductionDataList(obj), await updateSumProductionDataList(obj),
await updateProductionDataList(updateArr), await updateProductionDataList(updateArr),
]); ]);
if (result[0] == true && result[1] == true) { if (result[0].data == true && result[1].data == true) {
console.log(res) // console.log(res)
this.disabled = true this.disabled = true
this.isSave = false this.isSave = false
this.getDataList() this.getDataList()

View File

@ -1,7 +1,7 @@
<!-- <!--
* @Author: zhp * @Author: zhp
* @Date: 2023-12-12 13:45:25 * @Date: 2023-12-12 13:45:25
* @LastEditTime: 2023-12-13 15:16:03 * @LastEditTime: 2023-12-14 14:56:45
* @LastEditors: zhp * @LastEditors: zhp
* @Description: * @Description:
--> -->
@ -405,8 +405,8 @@ export default {
await updateSumProductionDataList(obj), await updateSumProductionDataList(obj),
await updateProductionDataList(updateArr), await updateProductionDataList(updateArr),
]); ]);
if (result[0] == true && result[1] == true) { if (result[0].data == true && result[1].data == true) {
console.log(res) // console.log(res)
this.disabled = true this.disabled = true
this.isSave = false this.isSave = false
this.getDataList() this.getDataList()

View File

@ -68,7 +68,6 @@ export default {
} }
obj.name = item obj.name = item
obj.type = 'line' obj.type = 'line'
obj.stack = 'Total'
obj.symbol = 'none' obj.symbol = 'none'
obj.data = data obj.data = data
seriesData.push(obj) seriesData.push(obj)
@ -118,7 +117,7 @@ export default {
} }
}, },
grid: { grid: {
left: '3%', left: '4%',
right: '2%', right: '2%',
bottom: '3%', bottom: '3%',
containLabel: true containLabel: true

View File

@ -56,7 +56,7 @@ const tableProps = [
}, },
{ {
prop: 'code', prop: 'code',
label: '指编码', label: '指编码',
minWidth: 120 minWidth: 120
}, },
{ {

View File

@ -35,13 +35,14 @@
import { environmentalCheckRealtime, environmentalCheckRealtimeTrend } from '@/api/safetyEnvironmental/environmental' import { environmentalCheckRealtime, environmentalCheckRealtimeTrend } from '@/api/safetyEnvironmental/environmental'
import LineChart from './../../components/lineChart' import LineChart from './../../components/lineChart'
import SearchArea from './../../components/searchArea' import SearchArea from './../../components/searchArea'
import moment from 'moment'
export default { export default {
name: 'Voc', name: 'Voc',
data(){ data(){
return { return {
realtimeList:[], realtimeList:[],
queryParams:{ queryParams:{
checkType: 1, checkType: 3,
timeDim: null, timeDim: null,
timeRange: [] timeRange: []
}, },
@ -51,6 +52,9 @@ export default {
components: { LineChart, SearchArea }, components: { LineChart, SearchArea },
mounted() { mounted() {
this.getMsg() this.getMsg()
this.queryParams.timeDim = this.getDictDatas(this.DICT_TYPE.TIME_DIM)[0].value //
this.queryParams.timeRange = [moment().startOf('day')+0, moment().endOf('day')-59*61*1000]
this.getTrend()
}, },
methods: { methods: {
getMsg() { getMsg() {
@ -59,19 +63,21 @@ export default {
this.realtimeList = res.data || [] this.realtimeList = res.data || []
}) })
}, },
getTrend(params) { getTrend() {
console.log(params)
this.queryParams.timeDim = params.timeDim
this.queryParams.timeRange[0] = params.startTime
this.queryParams.timeRange[1] = params.endTime
environmentalCheckRealtimeTrend({...this.queryParams}).then(res => { environmentalCheckRealtimeTrend({...this.queryParams}).then(res => {
console.log(res)
if (res.code === 0) { if (res.code === 0) {
this.chartData = res.data this.chartData = res.data
} else { } else {
this.chartData = {} this.chartData = {}
} }
}) })
},
submitClick(params) {
console.log(params)
this.queryParams.timeDim = params.timeDim
this.queryParams.timeRange[0] = params.startTime
this.queryParams.timeRange[1] = params.endTime
this.getTrend()
} }
} }
} }

View File

@ -56,7 +56,7 @@ const tableProps = [
}, },
{ {
prop: 'code', prop: 'code',
label: '指编码', label: '指编码',
minWidth: 120 minWidth: 120
}, },
{ {

View File

@ -35,6 +35,7 @@
import { environmentalCheckRealtime, environmentalCheckRealtimeTrend } from '@/api/safetyEnvironmental/environmental' import { environmentalCheckRealtime, environmentalCheckRealtimeTrend } from '@/api/safetyEnvironmental/environmental'
import LineChart from './../../components/lineChart' import LineChart from './../../components/lineChart'
import SearchArea from './../../components/searchArea' import SearchArea from './../../components/searchArea'
import moment from 'moment'
export default { export default {
name: 'WasteGasManagement', name: 'WasteGasManagement',
data(){ data(){
@ -51,6 +52,9 @@ export default {
components: { LineChart, SearchArea }, components: { LineChart, SearchArea },
mounted() { mounted() {
this.getMsg() this.getMsg()
this.queryParams.timeDim = this.getDictDatas(this.DICT_TYPE.TIME_DIM)[0].value //
this.queryParams.timeRange = [moment().startOf('day')+0, moment().endOf('day')-59*61*1000]
this.getTrend()
}, },
methods: { methods: {
getMsg() { getMsg() {
@ -59,19 +63,21 @@ export default {
this.realtimeList = res.data || [] this.realtimeList = res.data || []
}) })
}, },
getTrend(params) { getTrend() {
console.log(params)
this.queryParams.timeDim = params.timeDim
this.queryParams.timeRange[0] = params.startTime
this.queryParams.timeRange[1] = params.endTime
environmentalCheckRealtimeTrend({...this.queryParams}).then(res => { environmentalCheckRealtimeTrend({...this.queryParams}).then(res => {
console.log(res)
if (res.code === 0) { if (res.code === 0) {
this.chartData = res.data this.chartData = res.data
} else { } else {
this.chartData = {} this.chartData = {}
} }
}) })
},
submitClick(params) {
console.log(params)
this.queryParams.timeDim = params.timeDim
this.queryParams.timeRange[0] = params.startTime
this.queryParams.timeRange[1] = params.endTime
this.getTrend()
} }
} }
} }

View File

@ -56,7 +56,7 @@ const tableProps = [
}, },
{ {
prop: 'code', prop: 'code',
label: '指编码', label: '指编码',
minWidth: 120 minWidth: 120
}, },
{ {

View File

@ -22,7 +22,7 @@
<span>检测指标趋势图</span> <span>检测指标趋势图</span>
</div> </div>
<!-- 搜索工作栏 --> <!-- 搜索工作栏 -->
<search-area @submit="getTrend"/> <search-area @submit="submitClick"/>
<line-chart :chartData="chartData" v-show='Object.keys(chartData).length !== 0' :timeDim="queryParams.timeDim"/> <line-chart :chartData="chartData" v-show='Object.keys(chartData).length !== 0' :timeDim="queryParams.timeDim"/>
<!-- 没有数据 --> <!-- 没有数据 -->
<div class="no-data-bg" v-show='Object.keys(chartData).length === 0'></div> <div class="no-data-bg" v-show='Object.keys(chartData).length === 0'></div>
@ -33,6 +33,7 @@
import { environmentalCheckRealtime, environmentalCheckRealtimeTrend } from '@/api/safetyEnvironmental/environmental' import { environmentalCheckRealtime, environmentalCheckRealtimeTrend } from '@/api/safetyEnvironmental/environmental'
import LineChart from './../../components/lineChart' import LineChart from './../../components/lineChart'
import SearchArea from './../../components/searchArea' import SearchArea from './../../components/searchArea'
import moment from 'moment'
export default { export default {
name: 'WasteWaterManagement', name: 'WasteWaterManagement',
data(){ data(){
@ -49,27 +50,31 @@ export default {
components: { LineChart, SearchArea }, components: { LineChart, SearchArea },
mounted() { mounted() {
this.getMsg() this.getMsg()
this.queryParams.timeDim = this.getDictDatas(this.DICT_TYPE.TIME_DIM)[0].value //
this.queryParams.timeRange = [moment().startOf('day')+0, moment().endOf('day')-59*61*1000]
this.getTrend()
}, },
methods: { methods: {
getMsg() { getMsg() {
environmentalCheckRealtime({checkType: 1}).then(res => { environmentalCheckRealtime({checkType: 1}).then(res => {
console.log(res)
this.realtimeList = res.data || [] this.realtimeList = res.data || []
}) })
}, },
getTrend(params) { getTrend() {
console.log(params)
this.queryParams.timeDim = params.timeDim
this.queryParams.timeRange[0] = params.startTime
this.queryParams.timeRange[1] = params.endTime
environmentalCheckRealtimeTrend({...this.queryParams}).then(res => { environmentalCheckRealtimeTrend({...this.queryParams}).then(res => {
console.log(res)
if (res.code === 0) { if (res.code === 0) {
this.chartData = res.data this.chartData = res.data
} else { } else {
this.chartData = {} this.chartData = {}
} }
}) })
},
submitClick(params) {
console.log(params)
this.queryParams.timeDim = params.timeDim
this.queryParams.timeRange[0] = params.startTime
this.queryParams.timeRange[1] = params.endTime
this.getTrend()
} }
} }
} }

View File

@ -0,0 +1,522 @@
<!--
filename: SpecialEquipmentForFireFighting.vue
author: liubin
date: 2023-12-12 13:51:23
description:
-->
<template>
<div class="app-container SpecialEquipmentForFireFighting">
<!-- 搜索工作栏 -->
<SearchBar
:formConfigs="searchBarFormConfig"
ref="search-bar"
@headBtnClick="handleSearchBarBtnClick" />
<!-- 列表 -->
<base-table
:table-props="tableProps"
:page="queryParams.pageNo"
:limit="queryParams.pageSize"
:table-data="list"
@emitFun="handleEmitFun">
<method-btn
v-if="tableBtn.length"
slot="handleBtn"
:width="120"
label="操作"
:method-list="tableBtn"
@clickBtn="handleTableBtnClick" />
</base-table>
<!-- 分页组件 -->
<pagination
v-show="total > 0"
:total="total"
:page.sync="queryParams.pageNo"
:limit.sync="queryParams.pageSize"
@pagination="getList" />
<!-- 对话框(添加) -->
<base-dialog
:dialogTitle="title"
:dialogVisible="open"
@close="cancel"
@cancel="cancel"
width="45%"
@confirm="submitForm">
<DialogForm
v-if="open"
key="index-dialog-form"
ref="form"
label-position="top"
size="small"
v-model="form"
:has-files="true"
:disabled="editMode === 'detail'"
:rows="computedRows" />
<!-- :has-files="['files', 'files2']" -->
</base-dialog>
<!-- 设备 详情 - 编辑 -->
<!-- <EquipmentDrawer
v-if="editVisible"
ref="drawer"
:mode="editMode"
@update-mode="editMode = $event"
:data-id="form.id"
:sections="[
{
name: '基本信息',
key: 'base',
rows: computedRows,
url: '/base/core-equipment/get',
urlUpdate: '/base/core-equipment/update',
urlCreate: '/base/core-equipment/create',
queryParams: { id: form.id },
},
{
name: '属性列表',
key: 'attrs',
props: drawerListProps,
url: '/base/core-equipment-attr/page',
urlCreate: '/base/core-equipment-attr/create',
urlUpdate: '/base/core-equipment-attr/update',
urlDelete: '/base/core-equipment-attr/delete',
urlDetail: '/base/core-equipment-attr/get',
queryParams: {
equipmentId: form.id,
pageNo: 1,
pageSize: 10,
},
tableBtn: [
this.$auth.hasPermi('base:core-equipment-attr:update')
? {
type: 'edit',
btnName: '修改',
}
: undefined,
this.$auth.hasPermi('base:core-equipment-attr:delete')
? {
type: 'delete',
btnName: '删除',
}
: undefined,
].filter((v) => v),
allowAdd: true,
},
]"
@refreshDataList="getList"
@cancel="cancelEdit"
@destroy="cancelEdit" /> -->
</div>
</template>
<script>
import moment from 'moment';
import basicPageMixin from '@/mixins/lb/basicPageMixin';
import EquipmentDrawer from '../components/EquipmentDrawer';
import {
createEquipment,
updateEquipment,
deleteEquipment,
getEquipment,
getEquipmentPage,
exportEquipmentExcel,
} from '@/api/base/equipment';
import Editor from '@/components/Editor';
import AssetsUpload from '../components/AssetsUpload.vue';
export default {
name: 'SpecialEquipmentForFireFighting',
components: {
Editor,
EquipmentDrawer,
},
mixins: [basicPageMixin],
data() {
return {
searchBarKeys: ['name', 'code'],
tableBtn: [
this.$auth.hasPermi(`base:core-equipment:update`)
? {
type: 'detail',
btnName: '详情',
}
: undefined,
this.$auth.hasPermi('base:core-equipment:update')
? {
type: 'edit',
btnName: '修改',
}
: undefined,
this.$auth.hasPermi('base:core-equipment:delete')
? {
type: 'delete',
btnName: '删除',
}
: undefined,
].filter((v) => v),
tableProps: [
// {
// prop: 'createTime',
// label: '',
// fixed: true,
// width: 180,
// filter: (val) => moment(val).format('yyyy-MM-DD HH:mm:ss'),
// },
{ prop: 'name', label: '设备名称' },
{ width: 256, prop: 'code', label: '设备编码' },
{ prop: 'location', label: '位置' },
{ prop: 'responsiblePeopleName', label: '负责人' },
{ prop: 'dueTime', label: '有效期至' },
{ prop: 'remark', label: '备注' },
],
searchBarFormConfig: [
{
type: 'input',
label: '设备名称',
placeholder: '请输入设备名称',
param: 'name',
},
{
type: 'input',
label: '设备编码',
placeholder: '请输入设备编码',
param: 'code',
},
{
type: 'button',
btnName: '查询',
name: 'search',
color: 'primary',
},
{
type: 'separate',
},
{
type: this.$auth.hasPermi('base:core-equipment:export')
? 'button'
: '',
btnName: '导出',
name: 'export',
plain: true,
color: 'primary',
},
{
type: this.$auth.hasPermi('base:core-equipment:create')
? 'button'
: '',
btnName: '新增',
name: 'add',
plain: true,
color: 'success',
},
],
rows: [
[
{
input: true,
label: '设备名称',
prop: 'name',
rules: [
{ required: true, message: '设备名称不能为空', trigger: 'blur' },
],
},
{
input: true,
label: '设备编码',
prop: 'code',
url: '/base/core-equipment/getCode',
rules: [
{ required: true, message: '设备编码不能为空', trigger: 'blur' },
],
},
],
[
{
input: true,
label: '所在区域',
prop: 'location',
},
{
select: true,
label: '负责人',
prop: 'responsiblePeopleId',
url: '/base/core-worker/listAll',
},
],
[
{
datetime: true,
label: '有效期至',
prop: 'dueTime',
bind: { clearable: true },
},
{},
],
[{ input: true, label: '备注', prop: 'remark' }],
[
{
upload: true,
label: '设备图片',
prop: 'files',
fileType: 1,
},
],
],
editVisible: false,
editMode: 'edit', // 'edit', 'detail'
// drawer
drawerListProps: [
{
prop: 'createTime',
label: '添加时间',
fixed: true,
width: 180,
filter: (val) => moment(val).format('yyyy-MM-DD HH:mm:ss'),
},
{ prop: 'name', label: '属性名称' },
{ prop: 'value', label: '属性值' },
],
//
open: false,
//
queryParams: {
pageNo: 1,
pageSize: 10,
code: '',
name: '',
},
//
form: {
id: null,
files: [],
},
showUploadComponents: false, //
};
},
computed: {
computedRows() {
return this.showUploadComponents
? [
...this.rows,
[
{
assetUpload: true,
key: 'eq-assets', //
label: '上传资料',
fieldName: 'assets',
subcomponent: AssetsUpload,
prop: 'uploadedAssets',
default: [],
bind: {
'is-pic-mode': false,
},
},
],
[
{
assetUpload: true,
key: 'eq-pics', //
label: '上传图片',
fieldName: 'images',
subcomponent: AssetsUpload,
// prop: '',
// default: [],
bind: {
'is-pic-mode': true,
},
},
],
]
: this.rows;
},
},
mounted() {
this.getList();
},
activated() {
this.getList();
},
methods: {
/** 查询列表 */
getList() {
this.loading = true;
//
getEquipmentPage({
...this.queryParams,
specialType: 2,
special: true,
}).then((response) => {
this.list = response.data.list;
this.total = response.data.total;
this.loading = false;
});
},
/** 取消按钮 */
cancel() {
this.open = false;
this.reset();
},
cancelEdit() {
this.showUploadComponents = false;
this.editVisible = false;
},
/** 表单重置 */
reset() {
this.form = {
id: undefined,
code: undefined,
name: undefined,
enName: undefined,
abbr: undefined,
enterTime: undefined,
productionTime: undefined,
equipmentTypeId: undefined,
groupId: undefined,
tvalue: undefined,
processingTime: undefined,
manufacturer: undefined,
spec: undefined,
description: undefined,
remark: undefined,
files: [],
files2: [],
};
this.resetForm('form');
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.open = true;
this.showUploadComponents = false;
this.title = '添加设备';
this.editMode = 'add';
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
this.showUploadComponents = false;
this.editMode = 'edit';
const id = row.id;
getEquipment(id).then((response) => {
this.form = response.data;
this.open = true;
this.title = '修改设备';
});
},
handleDetail(row) {
this.reset();
this.showUploadComponents = false;
const id = row.id;
this.editMode = 'detail';
getEquipment(id).then((response) => {
this.form = response.data;
this.open = true;
this.title = '查看详情';
});
},
/** 提交按钮 */
submitForm() {
this.$refs['form'].validate((valid) => {
if (!valid) {
return;
}
const payload = Object.assign(
{ special: true, specialType: 2 },
this.form
);
// payload.files = [...payload.files, ...payload.files2];
// delete payload.files2;
//
if (this.form.id != null) {
updateEquipment(payload).then((response) => {
this.$modal.msgSuccess('修改成功');
this.open = false;
this.getList();
});
return;
}
//
createEquipment(payload).then((response) => {
this.$modal.msgSuccess('新增成功');
this.open = false;
this.getList();
});
});
},
/** 删除按钮操作 */
handleDelete(row) {
const id = row.id;
this.$modal
.confirm('是否确认删除设备名称为"' + row.name + '"的数据项?')
.then(function () {
return deleteEquipment(id);
})
.then(() => {
this.getList();
this.$modal.msgSuccess('删除成功');
})
.catch(() => {});
},
/** 导出按钮操作 */
handleExport() {
//
let params = { ...this.queryParams, special: true, specialType: 2 };
params.pageNo = undefined;
params.pageSize = undefined;
this.$modal
.confirm('是否确认导出所有设备数据项?')
.then(() => {
this.exportLoading = true;
return exportEquipmentExcel(params);
})
.then((response) => {
this.$download.excel(response, '消防设备.xls');
this.exportLoading = false;
})
.catch(() => {});
},
//
viewDetail(id) {
this.reset();
this.editMode = 'detail';
this.showUploadComponents = true;
this.form.id = id;
this.editVisible = true;
this.$nextTick(() => {
this.$refs['drawer'].init();
});
},
// overwrite basicPageMixin
// handleTableBtnClick({ data, type }) {
// switch (type) {
// case 'edit':
// this.reset();
// this.editMode = 'edit';
// this.showUploadComponents = true;
// this.form.id = data.id;
// this.editVisible = true;
// this.$nextTick(() => {
// this.$refs['drawer'].init();
// });
// break;
// case 'delete':
// this.handleDelete(data);
// break;
// case 'detail':
// const { id } = data;
// this.viewDetail(id);
// break;
// }
// },
},
};
</script>
<style scoped lang="scss">
.SpecialEquipmentForFireFighting {
}
</style>

View File

@ -0,0 +1,512 @@
<!--
filename: SpecialEquipmentManagement.vue
author: liubin
date: 2023-12-12 13:51:23
description:
-->
<template>
<div class="app-container SpecialEquipmentManagement">
<!-- 搜索工作栏 -->
<SearchBar
:formConfigs="searchBarFormConfig"
ref="search-bar"
@headBtnClick="handleSearchBarBtnClick" />
<!-- 列表 -->
<base-table
:table-props="tableProps"
:page="queryParams.pageNo"
:limit="queryParams.pageSize"
:table-data="list"
@emitFun="handleEmitFun">
<method-btn
v-if="tableBtn.length"
slot="handleBtn"
:width="120"
label="操作"
:method-list="tableBtn"
@clickBtn="handleTableBtnClick" />
</base-table>
<!-- 分页组件 -->
<pagination
v-show="total > 0"
:total="total"
:page.sync="queryParams.pageNo"
:limit.sync="queryParams.pageSize"
@pagination="getList" />
<!-- 对话框(添加) -->
<base-dialog
:dialogTitle="title"
:dialogVisible="open"
@close="cancel"
@cancel="cancel"
width="45%"
@confirm="submitForm">
<DialogForm
v-if="open"
key="index-dialog-form"
ref="form"
label-position="top"
size="small"
v-model="form"
:has-files="true"
:disabled="editMode === 'detail'"
:rows="computedRows" />
<!-- :has-files="['files', 'files2']" -->
</base-dialog>
<!-- 设备 详情 - 编辑 -->
<!-- <EquipmentDrawer
v-if="editVisible"
ref="drawer"
:mode="editMode"
@update-mode="editMode = $event"
:data-id="form.id"
:sections="[
{
name: '基本信息',
key: 'base',
rows: computedRows,
url: '/base/core-equipment/get',
urlUpdate: '/base/core-equipment/update',
urlCreate: '/base/core-equipment/create',
queryParams: { id: form.id },
},
{
name: '属性列表',
key: 'attrs',
props: drawerListProps,
url: '/base/core-equipment-attr/page',
urlCreate: '/base/core-equipment-attr/create',
urlUpdate: '/base/core-equipment-attr/update',
urlDelete: '/base/core-equipment-attr/delete',
urlDetail: '/base/core-equipment-attr/get',
queryParams: {
equipmentId: form.id,
pageNo: 1,
pageSize: 10,
},
tableBtn: [
this.$auth.hasPermi('base:core-equipment-attr:update')
? {
type: 'edit',
btnName: '修改',
}
: undefined,
this.$auth.hasPermi('base:core-equipment-attr:delete')
? {
type: 'delete',
btnName: '删除',
}
: undefined,
].filter((v) => v),
allowAdd: true,
},
]"
@refreshDataList="getList"
@cancel="cancelEdit"
@destroy="cancelEdit" /> -->
</div>
</template>
<script>
import moment from 'moment';
import basicPageMixin from '@/mixins/lb/basicPageMixin';
import EquipmentDrawer from '../components/EquipmentDrawer';
import {
createEquipment,
updateEquipment,
deleteEquipment,
getEquipment,
getEquipmentPage,
exportEquipmentExcel,
} from '@/api/base/equipment';
import Editor from '@/components/Editor';
import AssetsUpload from '../components/AssetsUpload.vue';
export default {
name: 'SpecialEquipmentManagement',
components: {
Editor,
EquipmentDrawer,
},
mixins: [basicPageMixin],
data() {
return {
searchBarKeys: ['name', 'code'],
tableBtn: [
this.$auth.hasPermi(`base:core-equipment:update`)
? {
type: 'detail',
btnName: '详情',
}
: undefined,
this.$auth.hasPermi('base:core-equipment:update')
? {
type: 'edit',
btnName: '修改',
}
: undefined,
this.$auth.hasPermi('base:core-equipment:delete')
? {
type: 'delete',
btnName: '删除',
}
: undefined,
].filter((v) => v),
tableProps: [
// {
// prop: 'createTime',
// label: '',
// fixed: true,
// width: 180,
// filter: (val) => moment(val).format('yyyy-MM-DD HH:mm:ss'),
// },
{ prop: 'name', label: '设备名称' },
{ width: 256, prop: 'code', label: '设备编码' },
{ prop: 'location', label: '位置' },
{ prop: 'responsiblePeopleName', label: '负责人' },
{ prop: 'remark', label: '备注' },
],
searchBarFormConfig: [
{
type: 'input',
label: '名称',
placeholder: '请输入设备名称',
param: 'name',
},
{
type: 'input',
label: '编码',
placeholder: '请输入设备编码',
param: 'code',
},
{
type: 'button',
btnName: '查询',
name: 'search',
color: 'primary',
},
{
type: 'separate',
},
{
type: this.$auth.hasPermi('base:core-equipment:export')
? 'button'
: '',
btnName: '导出',
name: 'export',
plain: true,
color: 'primary',
},
{
type: this.$auth.hasPermi('base:core-equipment:create')
? 'button'
: '',
btnName: '新增',
name: 'add',
plain: true,
color: 'success',
},
],
rows: [
[
{
input: true,
label: '设备名称',
prop: 'name',
rules: [
{ required: true, message: '设备名称不能为空', trigger: 'blur' },
],
},
{
input: true,
label: '设备编码',
prop: 'code',
url: '/base/core-equipment/getCode',
rules: [
{ required: true, message: '设备编码不能为空', trigger: 'blur' },
],
},
],
[
{
input: true,
label: '所在区域',
prop: 'location',
},
{
select: true,
label: '负责人',
prop: 'responsiblePeopleId',
url: '/base/core-worker/listAll',
},
],
[{ input: true, label: '备注', prop: 'remark' }],
[
{
upload: true,
label: '设备图片',
prop: 'files',
fileType: 1,
},
],
],
editVisible: false,
editMode: 'edit', // 'edit', 'detail'
// drawer
drawerListProps: [
{
prop: 'createTime',
label: '添加时间',
fixed: true,
width: 180,
filter: (val) => moment(val).format('yyyy-MM-DD HH:mm:ss'),
},
{ prop: 'name', label: '属性名称' },
{ prop: 'value', label: '属性值' },
],
//
open: false,
//
queryParams: {
pageNo: 1,
pageSize: 10,
code: '',
name: '',
},
//
form: {
id: null,
files: [],
},
showUploadComponents: false, //
};
},
computed: {
computedRows() {
return this.showUploadComponents
? [
...this.rows,
[
{
assetUpload: true,
key: 'eq-assets', //
label: '上传资料',
fieldName: 'assets',
subcomponent: AssetsUpload,
prop: 'uploadedAssets',
default: [],
bind: {
'is-pic-mode': false,
},
},
],
[
{
assetUpload: true,
key: 'eq-pics', //
label: '上传图片',
fieldName: 'images',
subcomponent: AssetsUpload,
// prop: '',
// default: [],
bind: {
'is-pic-mode': true,
},
},
],
]
: this.rows;
},
},
mounted() {
this.getList();
},
activated() {
this.getList();
},
methods: {
/** 查询列表 */
getList() {
this.loading = true;
//
getEquipmentPage({
...this.queryParams,
specialType: 3,
special: true,
}).then((response) => {
this.list = response.data.list;
this.total = response.data.total;
this.loading = false;
});
},
/** 取消按钮 */
cancel() {
this.open = false;
this.reset();
},
cancelEdit() {
this.showUploadComponents = false;
this.editVisible = false;
},
/** 表单重置 */
reset() {
this.form = {
id: undefined,
code: undefined,
name: undefined,
enName: undefined,
abbr: undefined,
enterTime: undefined,
productionTime: undefined,
equipmentTypeId: undefined,
groupId: undefined,
tvalue: undefined,
processingTime: undefined,
manufacturer: undefined,
spec: undefined,
description: undefined,
remark: undefined,
files: [],
files2: [],
};
this.resetForm('form');
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.open = true;
this.showUploadComponents = false;
this.title = '添加设备';
this.editMode = 'add';
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
this.showUploadComponents = false;
this.editMode = 'edit';
const id = row.id;
getEquipment(id).then((response) => {
this.form = response.data;
this.open = true;
this.title = '修改设备';
});
},
handleDetail(row) {
this.reset();
this.showUploadComponents = false;
const id = row.id;
this.editMode = 'detail';
getEquipment(id).then((response) => {
this.form = response.data;
this.open = true;
this.title = '查看详情';
});
},
/** 提交按钮 */
submitForm() {
this.$refs['form'].validate((valid) => {
if (!valid) {
return;
}
const payload = Object.assign(
{ special: true, specialType: 3 },
this.form
);
// payload.files = [...payload.files, ...payload.files2];
// delete payload.files2;
//
if (this.form.id != null) {
updateEquipment(payload).then((response) => {
this.$modal.msgSuccess('修改成功');
this.open = false;
this.getList();
});
return;
}
//
createEquipment(payload).then((response) => {
this.$modal.msgSuccess('新增成功');
this.open = false;
this.getList();
});
});
},
/** 删除按钮操作 */
handleDelete(row) {
const id = row.id;
this.$modal
.confirm('是否确认删除设备名称为"' + row.name + '"的数据项?')
.then(function () {
return deleteEquipment(id);
})
.then(() => {
this.getList();
this.$modal.msgSuccess('删除成功');
})
.catch(() => {});
},
/** 导出按钮操作 */
handleExport() {
//
let params = { ...this.queryParams, special: true, specialType: 3 };
params.pageNo = undefined;
params.pageSize = undefined;
this.$modal
.confirm('是否确认导出所有设备数据项?')
.then(() => {
this.exportLoading = true;
return exportEquipmentExcel(params);
})
.then((response) => {
this.$download.excel(response, '特种设备.xls');
this.exportLoading = false;
})
.catch(() => {});
},
//
viewDetail(id) {
this.reset();
this.editMode = 'detail';
this.showUploadComponents = true;
this.form.id = id;
this.editVisible = true;
this.$nextTick(() => {
this.$refs['drawer'].init();
});
},
// overwrite basicPageMixin
// handleTableBtnClick({ data, type }) {
// switch (type) {
// case 'edit':
// this.reset();
// this.editMode = 'edit';
// this.showUploadComponents = true;
// this.form.id = data.id;
// this.editVisible = true;
// this.$nextTick(() => {
// this.$refs['drawer'].init();
// });
// break;
// case 'delete':
// this.handleDelete(data);
// break;
// case 'detail':
// const { id } = data;
// this.viewDetail(id);
// break;
// }
// },
},
};
</script>
<style scoped lang="scss">
.SpecialEquipmentManagement {
}
</style>

View File

@ -0,0 +1,512 @@
<!--
filename: Safety.vue
author: liubin
date: 2023-12-12 13:51:23
description:
-->
<template>
<div class="app-container SpecialEquipmentForSafety">
<!-- 搜索工作栏 -->
<SearchBar
:formConfigs="searchBarFormConfig"
ref="search-bar"
@headBtnClick="handleSearchBarBtnClick" />
<!-- 列表 -->
<base-table
:table-props="tableProps"
:page="queryParams.pageNo"
:limit="queryParams.pageSize"
:table-data="list"
@emitFun="handleEmitFun">
<method-btn
v-if="tableBtn.length"
slot="handleBtn"
:width="120"
label="操作"
:method-list="tableBtn"
@clickBtn="handleTableBtnClick" />
</base-table>
<!-- 分页组件 -->
<pagination
v-show="total > 0"
:total="total"
:page.sync="queryParams.pageNo"
:limit.sync="queryParams.pageSize"
@pagination="getList" />
<!-- 对话框(添加) -->
<base-dialog
:dialogTitle="title"
:dialogVisible="open"
@close="cancel"
@cancel="cancel"
width="45%"
@confirm="submitForm">
<DialogForm
v-if="open"
key="index-dialog-form"
ref="form"
label-position="top"
size="small"
v-model="form"
:has-files="true"
:disabled="editMode === 'detail'"
:rows="computedRows" />
<!-- :has-files="['files', 'files2']" -->
</base-dialog>
<!-- 设备 详情 - 编辑 -->
<!-- <EquipmentDrawer
v-if="editVisible"
ref="drawer"
:mode="editMode"
@update-mode="editMode = $event"
:data-id="form.id"
:sections="[
{
name: '基本信息',
key: 'base',
rows: computedRows,
url: '/base/core-equipment/get',
urlUpdate: '/base/core-equipment/update',
urlCreate: '/base/core-equipment/create',
queryParams: { id: form.id },
},
{
name: '属性列表',
key: 'attrs',
props: drawerListProps,
url: '/base/core-equipment-attr/page',
urlCreate: '/base/core-equipment-attr/create',
urlUpdate: '/base/core-equipment-attr/update',
urlDelete: '/base/core-equipment-attr/delete',
urlDetail: '/base/core-equipment-attr/get',
queryParams: {
equipmentId: form.id,
pageNo: 1,
pageSize: 10,
},
tableBtn: [
this.$auth.hasPermi('base:core-equipment-attr:update')
? {
type: 'edit',
btnName: '修改',
}
: undefined,
this.$auth.hasPermi('base:core-equipment-attr:delete')
? {
type: 'delete',
btnName: '删除',
}
: undefined,
].filter((v) => v),
allowAdd: true,
},
]"
@refreshDataList="getList"
@cancel="cancelEdit"
@destroy="cancelEdit" /> -->
</div>
</template>
<script>
import moment from 'moment';
import basicPageMixin from '@/mixins/lb/basicPageMixin';
import EquipmentDrawer from '../components/EquipmentDrawer';
import {
createEquipment,
updateEquipment,
deleteEquipment,
getEquipment,
getEquipmentPage,
exportEquipmentExcel,
} from '@/api/base/equipment';
import Editor from '@/components/Editor';
import AssetsUpload from '../components/AssetsUpload.vue';
export default {
name: 'SpecialEquipmentForSafety',
components: {
Editor,
EquipmentDrawer,
},
mixins: [basicPageMixin],
data() {
return {
searchBarKeys: ['name', 'code'],
tableBtn: [
this.$auth.hasPermi(`base:core-equipment:update`)
? {
type: 'detail',
btnName: '详情',
}
: undefined,
this.$auth.hasPermi('base:core-equipment:update')
? {
type: 'edit',
btnName: '修改',
}
: undefined,
this.$auth.hasPermi('base:core-equipment:delete')
? {
type: 'delete',
btnName: '删除',
}
: undefined,
].filter((v) => v),
tableProps: [
// {
// prop: 'createTime',
// label: '',
// fixed: true,
// width: 180,
// filter: (val) => moment(val).format('yyyy-MM-DD HH:mm:ss'),
// },
{ prop: 'name', label: '设备名称' },
{ width: 256, prop: 'code', label: '设备编码' },
{ prop: 'location', label: '位置' },
{ prop: 'responsiblePeopleName', label: '负责人' },
{ prop: 'remark', label: '备注' },
],
searchBarFormConfig: [
{
type: 'input',
label: '设备名称',
placeholder: '请输入设备名称',
param: 'name',
},
{
type: 'input',
label: '设备编码',
placeholder: '请输入设备编码',
param: 'code',
},
{
type: 'button',
btnName: '查询',
name: 'search',
color: 'primary',
},
{
type: 'separate',
},
{
type: this.$auth.hasPermi('base:core-equipment:export')
? 'button'
: '',
btnName: '导出',
name: 'export',
plain: true,
color: 'primary',
},
{
type: this.$auth.hasPermi('base:core-equipment:create')
? 'button'
: '',
btnName: '新增',
name: 'add',
plain: true,
color: 'success',
},
],
rows: [
[
{
input: true,
label: '设备名称',
prop: 'name',
rules: [
{ required: true, message: '设备名称不能为空', trigger: 'blur' },
],
},
{
input: true,
label: '设备编码',
prop: 'code',
url: '/base/core-equipment/getCode',
rules: [
{ required: true, message: '设备编码不能为空', trigger: 'blur' },
],
},
],
[
{
input: true,
label: '所在区域',
prop: 'location',
},
{
select: true,
label: '负责人',
prop: 'responsiblePeopleId',
url: '/base/core-worker/listAll',
},
],
[{ input: true, label: '备注', prop: 'remark' }],
[
{
upload: true,
label: '设备图片',
prop: 'files',
fileType: 1,
},
],
],
editVisible: false,
editMode: 'edit', // 'edit', 'detail'
// drawer
drawerListProps: [
{
prop: 'createTime',
label: '添加时间',
fixed: true,
width: 180,
filter: (val) => moment(val).format('yyyy-MM-DD HH:mm:ss'),
},
{ prop: 'name', label: '属性名称' },
{ prop: 'value', label: '属性值' },
],
//
open: false,
//
queryParams: {
pageNo: 1,
pageSize: 10,
code: '',
name: '',
},
//
form: {
id: null,
files: [],
},
showUploadComponents: false, //
};
},
computed: {
computedRows() {
return this.showUploadComponents
? [
...this.rows,
[
{
assetUpload: true,
key: 'eq-assets', //
label: '上传资料',
fieldName: 'assets',
subcomponent: AssetsUpload,
prop: 'uploadedAssets',
default: [],
bind: {
'is-pic-mode': false,
},
},
],
[
{
assetUpload: true,
key: 'eq-pics', //
label: '上传图片',
fieldName: 'images',
subcomponent: AssetsUpload,
// prop: '',
// default: [],
bind: {
'is-pic-mode': true,
},
},
],
]
: this.rows;
},
},
mounted() {
this.getList();
},
activated() {
this.getList();
},
methods: {
/** 查询列表 */
getList() {
this.loading = true;
//
getEquipmentPage({
...this.queryParams,
specialType: 1,
special: true,
}).then((response) => {
this.list = response.data.list;
this.total = response.data.total;
this.loading = false;
});
},
/** 取消按钮 */
cancel() {
this.open = false;
this.reset();
},
cancelEdit() {
this.showUploadComponents = false;
this.editVisible = false;
},
/** 表单重置 */
reset() {
this.form = {
id: undefined,
code: undefined,
name: undefined,
enName: undefined,
abbr: undefined,
enterTime: undefined,
productionTime: undefined,
equipmentTypeId: undefined,
groupId: undefined,
tvalue: undefined,
processingTime: undefined,
manufacturer: undefined,
spec: undefined,
description: undefined,
remark: undefined,
files: [],
files2: [],
};
this.resetForm('form');
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.open = true;
this.showUploadComponents = false;
this.title = '添加设备';
this.editMode = 'add';
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
this.showUploadComponents = false;
this.editMode = 'edit';
const id = row.id;
getEquipment(id).then((response) => {
this.form = response.data;
this.open = true;
this.title = '修改设备';
});
},
handleDetail(row) {
this.reset();
this.showUploadComponents = false;
const id = row.id;
this.editMode = 'detail';
getEquipment(id).then((response) => {
this.form = response.data;
this.open = true;
this.title = '查看详情';
});
},
/** 提交按钮 */
submitForm() {
this.$refs['form'].validate((valid) => {
if (!valid) {
return;
}
const payload = Object.assign(
{ special: true, specialType: 1 },
this.form
);
// payload.files = [...payload.files, ...payload.files2];
// delete payload.files2;
//
if (this.form.id != null) {
updateEquipment(payload).then((response) => {
this.$modal.msgSuccess('修改成功');
this.open = false;
this.getList();
});
return;
}
//
createEquipment(payload).then((response) => {
this.$modal.msgSuccess('新增成功');
this.open = false;
this.getList();
});
});
},
/** 删除按钮操作 */
handleDelete(row) {
const id = row.id;
this.$modal
.confirm('是否确认删除设备名称为"' + row.name + '"的数据项?')
.then(function () {
return deleteEquipment(id);
})
.then(() => {
this.getList();
this.$modal.msgSuccess('删除成功');
})
.catch(() => {});
},
/** 导出按钮操作 */
handleExport() {
//
let params = { ...this.queryParams, special: true, specialType: 1 };
params.pageNo = undefined;
params.pageSize = undefined;
this.$modal
.confirm('是否确认导出所有设备数据项?')
.then(() => {
this.exportLoading = true;
return exportEquipmentExcel(params);
})
.then((response) => {
this.$download.excel(response, '安全设备.xls');
this.exportLoading = false;
})
.catch(() => {});
},
//
viewDetail(id) {
this.reset();
this.editMode = 'detail';
this.showUploadComponents = true;
this.form.id = id;
this.editVisible = true;
this.$nextTick(() => {
this.$refs['drawer'].init();
});
},
// overwrite basicPageMixin
// handleTableBtnClick({ data, type }) {
// switch (type) {
// case 'edit':
// this.reset();
// this.editMode = 'edit';
// this.showUploadComponents = true;
// this.form.id = data.id;
// this.editVisible = true;
// this.$nextTick(() => {
// this.$refs['drawer'].init();
// });
// break;
// case 'delete':
// this.handleDelete(data);
// break;
// case 'detail':
// const { id } = data;
// this.viewDetail(id);
// break;
// }
// },
},
};
</script>
<style scoped lang="scss">
.SpecialEquipmentForSafety {
}
</style>

View File

@ -0,0 +1,436 @@
<!--
filename: Content.vue
author: liubin
date: 2023-12-12 13:53:22
description:
-->
<template>
<div class="app-container SpecialEquipmentCheckConfig">
<!-- 搜索工作栏 -->
<SearchBar
:formConfigs="searchBarFormConfig"
ref="search-bar"
@select-changed="handleSearchBarChange"
@headBtnClick="handleSearchBarBtnClick" />
<!-- 列表 -->
<base-table
:table-props="tableProps"
:page="queryParams.pageNo"
:limit="queryParams.pageSize"
:table-data="list"
@emitFun="handleEmitFun">
<method-btn
v-if="tableBtn.length"
slot="handleBtn"
label="操作"
:width="180"
:method-list="tableBtn"
@clickBtn="handleTableBtnClick" />
</base-table>
<!-- 分页组件 -->
<pagination
v-show="total > 0"
:total="total"
:page.sync="queryParams.pageNo"
:limit.sync="queryParams.pageSize"
@pagination="getList" />
<!-- 对话框(添加 / 修改) -->
<base-dialog
:dialogTitle="title"
:dialogVisible="open"
@close="cancel"
@cancel="cancel"
@confirm="handleConfirm">
<add ref="add" @refreshDataList="successSubmit" />
</base-dialog>
<!-- 添加巡检查看详情 -->
<addOrUpdata
v-if="addOrUpdateVisible"
ref="addOrUpdate"
@refreshDataList="getList" />
</div>
</template>
<script>
import basicPageMixin from '@/mixins/lb/basicPageMixin';
import addOrUpdata from './add-or-updata.vue';
import add from './add.vue';
export default {
name: 'SpecialEquipmentCheckConfig',
components: { addOrUpdata, add },
mixins: [basicPageMixin],
data() {
return {
addOrUpdateVisible: false,
addOrEditTitle: '',
searchBarKeys: ['equipmentId', 'name', 'specialType'],
tableBtn: [
this.$auth.hasPermi('equipment:check-setting:addInsp')
? {
type: 'add',
btnName: '添加',
showTip: '添加巡检',
}
: undefined,
this.$auth.hasPermi('equipment:check-setting:update')
? {
type: 'edit',
btnName: '修改',
}
: undefined,
this.$auth.hasPermi('equipment:check-setting:update')
? {
type: 'detail',
btnName: '查看详情',
}
: undefined,
this.$auth.hasPermi('equipment:check-setting:delete')
? {
type: 'delete',
btnName: '删除',
}
: undefined,
].filter((v) => v),
tableProps: [
{
prop: 'name',
label: '配置名',
width: 110,
showOverflowtooltip: true,
},
{ prop: 'lineName', label: '产线', showOverflowtooltip: true },
{
prop: 'equipmentCategory',
label: '设备大类',
filter: (val) =>
val != null ? ['-', '安全', '消防', '特种'][val] : '-',
},
{ prop: 'equipmentName', label: '设备', showOverflowtooltip: true },
{
prop: 'equipmentCode',
label: '设备编码',
minWidth: 150,
showOverflowtooltip: true,
},
{ prop: 'responsible', label: '负责人' },
{ prop: 'remark', label: '描述' },
{ prop: 'checkNumber', label: '巡检条数' }, // TODO:
],
searchBarFormConfig: [
{
type: 'input',
label: '配置名称',
placeholder: '请输入配置名称',
param: 'name',
},
{
type: 'select',
label: '设备大类',
placeholder: '请选择设备大类',
param: 'specialType',
onchange: true,
selectOptions: [
{ id: 1, name: '安全设备' },
{ id: 2, name: '消防设备' },
{ id: 3, name: '特种设备' },
],
filterable: true,
},
{
type: 'select',
label: '设备名称',
placeholder: '请选择设备',
param: 'equipmentId',
filterable: true,
},
{
type: 'button',
btnName: '查询',
name: 'search',
color: 'primary',
},
{
type: 'separate',
},
{
type: this.$auth.hasPermi('equipment:check-setting:create')
? 'button'
: '',
btnName: '新增',
name: 'add',
plain: true,
color: 'success',
},
// {
// type: this.$auth.hasPermi('equipment:check-setting:export')
// ? 'button'
// : '',
// btnName: '',
// name: 'export',
// color: 'warning',
// },
],
rows: [
[
{
input: true,
label: '配置名称',
prop: 'name',
rules: [
{ required: true, message: '配置名称不能为空', trigger: 'blur' },
],
},
{
input: true,
label: '配置编码',
prop: 'code',
url: '/base/equipment-check-config/getCode',
rules: [
{ required: true, message: '配置编码不能为空', trigger: 'blur' },
],
},
],
[
{
select: true,
label: '设备名称',
prop: 'equipmentId',
url: '/base/core-equipment/listAll',
bind: {
filterable: true,
clearable: true,
},
rules: [
{
required: true,
message: '设备名称不能为空',
trigger: 'change',
},
],
},
{
input: true,
label: '设备编码', // TODO:
prop: 'equipmentCode',
},
],
],
//
open: false,
//
queryParams: {
pageNo: 1,
pageSize: 10,
equipmentId: null,
name: null,
special: true,
specialType: null,
},
//
form: {},
basePath: '/base/equipment-check-config',
mode: null,
allSpecialEquipments: [],
};
},
created() {
this.initSearchBar();
this.getList();
},
methods: {
handleConfirm() {
this.$refs.add.dataFormSubmit();
},
successSubmit() {
this.cancel();
this.getList();
},
initSearchBar() {
this.http('/base/core-equipment/listAll', 'get').then(({ data }) => {
this.allSpecialEquipments = data.filter((item) => item.special);
this.setSearchBarEquipmentList(data.filter((item) => item.special));
});
},
//
handleSearchBarChange({ param, value }) {
if ('specialType' === param) {
if (!value) {
this.setSearchBarEquipmentList(this.allSpecialEquipments);
return;
}
this.setSearchBarEquipmentList(
this.allSpecialEquipments.filter((item) => item.specialType == value)
);
}
},
setSearchBarEquipmentList(eqList) {
this.$set(
this.searchBarFormConfig[2],
'selectOptions',
eqList.map((item) => ({
name: item.name,
id: item.id,
}))
);
},
/** 查询列表 */
getList() {
this.loading = true;
//
this.recv(this.queryParams).then((response) => {
this.list = response.data.list;
this.total = response.data.total;
this.loading = false;
});
},
/** 取消按钮 */
cancel() {
this.$refs.add.formClear();
this.open = false;
this.title = '';
// this.reset();
},
/** 表单重置 */
reset() {
this.form = {
id: null,
name: null,
content: null,
program: null,
remark: null,
};
this.resetForm('form');
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNo = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm('queryForm');
this.handleQuery();
},
/** 新增按钮操作 */
handleAdd() {
// this.reset();
this.open = true;
this.title = '添加巡检设置';
this.$nextTick(() => {
this.$refs.add.init();
});
},
/** 修改按钮操作 */
handleUpdate(row) {
// this.reset();
// const id = row.id;
// this.info({ id }).then((response) => {
// this.form = response.data;
// this.open = true;
// this.title = '';
// });
this.open = true;
this.title = '修改巡检设置';
this.$nextTick(() => {
this.$refs.add.init(row.id);
});
},
/** 提交按钮 */
submitForm() {
this.$refs['form'].validate((valid) => {
if (!valid) {
return;
}
//
if (this.form.id != null) {
this.put(this.form).then((response) => {
this.$modal.msgSuccess('修改成功');
this.open = false;
this.getList();
});
return;
}
//
this.post(this.form).then((response) => {
this.$modal.msgSuccess('新增成功');
this.open = false;
this.getList();
});
});
},
/** 删除按钮操作 */
handleDelete(row) {
const id = row.id;
this.$modal
.confirm('是否确认删除配置名为"' + row.name + '"的数据项?')
.then(() => {
return this.del({ id });
})
.then(() => {
this.getList();
this.$modal.msgSuccess('删除成功');
})
.catch(() => {});
},
//
handleTableBtnClick({ data, type }) {
switch (type) {
case 'edit':
this.handleUpdate(data);
break;
case 'delete':
this.handleDelete(data);
break;
case 'detail':
this.handleDetail(data);
break;
case 'add':
this.handleAddDetail(data);
break;
}
},
handleDetail({ id }) {
this.addOrUpdateVisible = true;
this.addOrEditTitle = '详情';
this.$nextTick(() => {
this.$refs.addOrUpdate.init(id, true);
});
},
handleAddDetail({ id }) {
this.addOrUpdateVisible = true;
this.addOrEditTitle = '添加巡检';
this.$nextTick(() => {
this.$refs.addOrUpdate.init(id);
});
},
/** 导出按钮操作 */
handleExport() {
//
let params = { ...this.queryParams };
params.pageNo = undefined;
params.pageSize = undefined;
this.$modal
.confirm('是否确认导出所有巡检设置?')
.then(() => {
this.exportLoading = true;
return exportEquipmentTypeExcel(params);
})
.then((response) => {
this.$download.excel(response, '巡检设置.xls');
this.exportLoading = false;
})
.catch(() => {});
},
},
};
</script>
<style scoped lang="scss">
.SpecialEquipmentCheckConfig {
}
</style>

View File

@ -0,0 +1,334 @@
<!--
filename: Content.vue
author: liubin
date: 2023-12-12 13:53:22
description:
-->
<template>
<div class="app-container SpecialEquipmentCheckContent">
<!-- 搜索工作栏 -->
<SearchBar
:formConfigs="searchBarFormConfig"
ref="search-bar"
@headBtnClick="handleSearchBarBtnClick" />
<!-- 列表 -->
<base-table
:table-props="tableProps"
:page="queryParams.pageNo"
:limit="queryParams.pageSize"
:table-data="list"
@emitFun="handleEmitFun">
<method-btn
v-if="tableBtn.length"
slot="handleBtn"
label="操作"
:width="120"
:method-list="tableBtn"
@clickBtn="handleTableBtnClick" />
</base-table>
<!-- 分页组件 -->
<pagination
v-show="total > 0"
:total="total"
:page.sync="queryParams.pageNo"
:limit.sync="queryParams.pageSize"
@pagination="getList" />
<!-- 对话框(添加 / 修改) -->
<base-dialog
:dialogTitle="title"
:dialogVisible="open"
@close="cancel"
@cancel="cancel"
@confirm="submitForm">
<DialogForm
v-if="open"
ref="form"
v-model="form"
:disabled="mode == 'detail'"
:has-files="false"
:rows="rows" />
</base-dialog>
</div>
</template>
<script>
import moment from 'moment';
import basicPageMixin from '@/mixins/lb/basicPageMixin';
import { deleteCheck } from '@/api/equipment/base/inspection/settings';
export default {
name: 'SpecialEquipmentCheckContent',
components: {},
mixins: [basicPageMixin],
data() {
return {
searchBarKeys: ['content'],
tableBtn: [
// this.$auth.hasPermi('equipment:check:update')
// ? {
// type: 'detail',
// btnName: '',
// }
// : undefined,
this.$auth.hasPermi('equipment:check:update')
? {
type: 'edit',
btnName: '修改',
}
: undefined,
this.$auth.hasPermi('equipment:check:delete')
? {
type: 'delete',
btnName: '删除',
}
: undefined,
].filter((v) => v),
tableProps: [
{ prop: 'program', label: '巡检项目', showOverflowtooltip: true },
{
prop: 'content',
label: '巡检内容',
minWidth: 150,
showOverflowtooltip: true,
},
{ prop: 'code', label: '巡检内容编码', showOverflowtooltip: true },
{ prop: 'remark', label: '备注', showOverflowtooltip: true },
],
searchBarFormConfig: [
{
type: 'input',
label: '巡检内容',
placeholder: '请输入巡检内容',
param: 'content',
},
{
type: 'button',
btnName: '查询',
name: 'search',
color: 'primary',
},
{
type: 'separate',
},
{
type: this.$auth.hasPermi('equipment:check:create') ? 'button' : '',
btnName: '新增',
name: 'add',
plain: true,
color: 'success',
},
// {
// type: this.$auth.hasPermi('equipment:check:export')
// ? 'button'
// : '',
// btnName: '',
// name: 'export',
// color: 'warning',
// },
],
rows: [
[
{
input: true,
label: '巡检内容编号',
prop: 'code',
url: '/base/equipment-check/getCode',
rules: [
{
required: true,
message: '巡检内容编号不能为空',
trigger: 'blur',
},
],
},
{
input: true,
label: '巡检项目',
prop: 'program',
rules: [
{ required: true, message: '巡检项目不能为空', trigger: 'blur' },
],
},
],
[
{
input: true,
label: '巡检内容',
prop: 'content',
rules: [
{ required: true, message: '巡检内容不能为空', trigger: 'blur' },
],
},
{
input: true,
label: '备注',
prop: 'remark',
},
],
],
//
open: false,
//
queryParams: {
pageNo: 1,
pageSize: 10,
content: null,
},
//
form: {
code: '',
program: '',
id: undefined,
content: '',
},
basePath: '/base/equipment-check',
mode: null,
};
},
created() {
// this.initSearchBar();
this.getList();
},
methods: {
// initSearchBar() {
// this.http('/base/core-equipment/listAll', 'get').then(({ data }) => {
// this.$set(
// this.searchBarFormConfig[0],
// 'selectOptions',
// data.map((item) => ({
// name: item.name,
// id: item.id,
// }))
// );
// });
// },
/** 查询列表 */
getList() {
this.loading = true;
//
this.recv(this.queryParams).then((response) => {
this.list = response.data.list;
this.total = response.data.total;
this.loading = false;
});
},
/** 取消按钮 */
cancel() {
this.open = false;
this.mode = null;
this.reset();
},
/** 表单重置 */
reset() {
this.form = {
id: null,
name: null,
content: null,
program: null,
remark: null,
};
this.resetForm('form');
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNo = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm('queryForm');
this.handleQuery();
},
/** 新增按钮操作 */
handleAdd() {
// this.reset();
this.open = true;
this.title = '添加巡检内容';
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
const id = row.id;
this.info({ id }).then((response) => {
this.form = response.data;
this.open = true;
this.title = '修改巡检内容';
});
},
/** 提交按钮 */
submitForm() {
this.$refs['form'].validate((valid) => {
if (!valid) {
return;
}
//
if (this.form.id != null) {
this.put(this.form).then((response) => {
this.$modal.msgSuccess('修改成功');
this.open = false;
this.getList();
});
return;
}
//
this.post(this.form).then((response) => {
this.$modal.msgSuccess('新增成功');
this.open = false;
this.getList();
});
});
},
/** 删除按钮操作 */
handleDelete(row) {
const id = row.id;
this.$modal
.confirm('是否确认删除该巡检项目?')
.then(function () {
// return this.del({ id });
return deleteCheck(id);
})
.then(() => {
this.getList();
this.$modal.msgSuccess('删除成功');
})
.catch(() => {});
},
handleDetail({ id }) {
this.reset();
this.mode = 'detail';
this.info({ id }).then((response) => {
this.form = response.data;
this.open = true;
this.title = '修改巡检内容';
});
},
/** 导出按钮操作 */
handleExport() {
//
let params = { ...this.queryParams };
params.pageNo = undefined;
params.pageSize = undefined;
this.$modal
.confirm('是否确认导出所有巡检内容?')
.then(() => {
this.exportLoading = true;
return exportEquipmentTypeExcel(params);
})
.then((response) => {
this.$download.excel(response, '巡检内容.xls');
this.exportLoading = false;
})
.catch(() => {});
},
},
};
</script>
<style scoped lang="scss">
.SpecialEquipmentCheckContent {
}
</style>

View File

@ -0,0 +1,504 @@
<!--
filename: dialogForm.vue
author: liubin
date: 2023-10-31 15:55:13
description:
-->
<template>
<el-drawer
ref="drawer"
:visible.sync="visible"
:show-close="false"
:wrapper-closable="isdetail"
class="drawer"
size="55%"
@closed="$emit('destroy')">
<small-title slot="title" :no-padding="true">
{{ isdetail ? '查看详情' : !dataForm.id ? '新增' : '编辑' }}
</small-title>
<el-form
ref="dataForm"
style="margin: 0 16px; padding: 0 16px"
:model="dataForm"
:rules="dataRule"
label-width="100px"
label-position="top"
v-loading="formLoading">
<el-row :gutter="20">
<el-col :span="8">
<el-form-item
label="设备大类"
prop="equipmentCategory"
:rules="[
{ required: true, message: '请选择设备大类', trigger: 'blur' },
]">
<el-select
v-model="dataForm.equipmentCategory"
:disabled="isdetail"
:placeholder="`请选择设备大类`"
filterable
@change="handleEqTypeChange">
<el-option
v-for="opt in equipmentTypeOptions"
:key="opt.value"
:label="opt.label"
:value="opt.value" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item
label="设备名称"
prop="equipmentId"
:rules="[
{ required: true, message: '设备不能为空', trigger: 'blur' },
]">
<el-select
v-model="dataForm.equipmentId"
filterable
clearable
:disabled="isdetail"
style="width: 100%"
placeholder="请选择设备名称"
@change="setConfig">
<el-option
v-for="dict in equipmentOptions"
:key="dict.value"
:label="dict.label"
:value="dict.value" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<!-- <el-form-item label="物料名称" prop="name">
<el-input v-model="dataForm.name" :disabled="isdetail" clearable placeholder="请输入物料名称" />
</el-form-item> -->
<el-form-item
label="巡检配置名称"
prop="configId"
:rules="[
{ required: true, message: '巡检配置不能为空', trigger: 'blur' },
]">
<el-select
v-model="dataForm.configId"
filterable
clearable
:disabled="isdetail"
style="width: 100%"
placeholder="请选择巡检配置"
@change="setInspectionContet">
<el-option
v-for="dict in configList"
:key="dict.id"
:label="dict.name"
:value="dict.id" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="设备编码" prop="equipmentCode">
<el-input
v-model="dataForm.equipmentCode"
disabled
clearable
placeholder="请输入设备编码" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="巡检人" prop="responsible">
<el-input
v-model="dataForm.responsible"
:disabled="isdetail"
clearable
placeholder="请输入巡检人" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="巡检时间" prop="actualTime">
<el-date-picker
v-model="dataForm.actualTime"
type="datetime"
:disabled="isdetail"
format="yyyy-MM-dd HH:mm:ss"
value-format="timestamp"
placeholder="选择巡检时间" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="数据来源" prop="origin">
<el-select
v-model="dataForm.origin"
filterable
clearable
:disabled="isdetail"
style="width: 100%"
placeholder="请选择数据来源">
<el-option key="1" label="手动" :value="1" />
<el-option key="2" label="PDA" :value="2" />
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-form-item label="巡检内容">
<base-table
:table-props="tableProps"
:page="listQuery.pageNo"
:limit="listQuery.pageSize"
:table-data="list" />
</el-form-item>
<el-form-item label="巡检详情" prop="description">
<editor
v-if="!isdetail"
v-model="dataForm.description"
:min-height="150" />
<div
v-else
v-html="dataForm.description"
style="padding: 5px; margin-left: 5px; border: 1px solid #dfdfdf" />
</el-form-item>
<el-form-item label="附件">
<FileUpload
v-model="file"
:limit="1"
:f-name="fileName"
:disabled="isdetail"
@name="setFileName" />
</el-form-item>
</el-form>
<div v-if="!isdetail" class="drawer-body__footer">
<el-button @click="goback()">取消</el-button>
<el-button type="primary" @click="dataFormSubmit()">确定</el-button>
</div>
</el-drawer>
</template>
<script>
import SmallTitle from './SmallTitle.vue';
import {
createCheckLog,
updateCheckLog,
getcheckConfigByEqList,
getEqCheckLog,
} from '@/api/equipment/base/inspection/record';
import { getEquipmentAll } from '@/api/base/equipment';
import Editor from '@/components/Editor';
import { getCheckDetPage } from '@/api/equipment/base/inspection/settings';
// import FileUpload from "@/components/FileUpload";
// import { parseTime } from '../../../../core/mixins/code-filter';
// import attrAdd from './attr-add';
import FileUpload from '@/components/FileUpload';
const tableBtn = [
{
type: 'delete',
btnName: '删除',
},
];
const tableProps = [
{
prop: 'program',
label: '巡检项目',
},
{
prop: 'content',
label: '巡检内容',
},
];
export default {
name: 'AddRecord',
model: {
prop: 'dataForm',
event: 'update',
},
emits: ['update'],
components: { SmallTitle, Editor, FileUpload },
props: {
// dataForm: {
// type: Object,
// default: () => ({}),
// },
// disabled: {
// type: Boolean,
// default: false
// },
},
data() {
return {
tableBtn,
tableProps,
addOrUpdateVisible: false,
formLoading: true,
visible: false,
isdetail: false,
dataForm: {
id: undefined,
configId: undefined,
equipmentId: undefined,
actualTime: undefined,
responsible: undefined,
description: undefined,
equipmentCode: undefined,
equipmentCategory: undefined,
origin: 1,
files: [],
},
equipmentTypeOptions: [
{ label: '安全设备', value: 1 },
{ label: '消防设备', value: 2 },
{ label: '特种设备', value: 3 },
],
list: [],
eqList: [],
configList: [],
listQuery: {
pageSize: 10,
pageNo: 1,
total: 0,
},
file: '',
fileName: '',
dataRule: {
responsible: [
{ required: true, message: '巡检人不能为空', trigger: 'blur' },
],
actualTime: [
{ required: true, message: '巡检时间不能为空', trigger: 'blur' },
],
},
};
},
mounted() {
this.getDict();
},
methods: {
setFileName(val) {
this.fileName = val;
},
async getDict() {
const res = await getEquipmentAll();
this.eqList = res.data;
this.handleEqTypeChange();
const configres = await getcheckConfigByEqList();
this.configList = configres.data;
},
async setConfig() {
const configres = await getcheckConfigByEqList({
equipmentId: this.dataForm.equipmentId,
});
this.configList = configres.data;
this.dataForm.configId =
this.configList.filter((it) => {
return it.id === this.dataForm.configId;
})[0]?.id ?? undefined;
this.dataForm.equipmentCode =
this.eqList.filter((item) => {
return item.id === this.dataForm.equipmentId;
})[0]?.code ?? undefined;
},
goback() {
this.$emit('refreshDataList');
this.visible = false;
},
goEdit() {
this.isdetail = false;
},
/** 模拟透传 ref */
validate(cb) {
return this.$refs.dataForm.validate(cb);
},
resetFields(args) {
return this.$refs.dataForm.resetFields(args);
},
initData() {
this.list = [];
this.file = '';
this.fileName = '';
},
init(id, isdetail) {
this.initData();
this.isdetail = isdetail || false;
this.dataForm.id = id || undefined;
this.visible = true;
// const scrollContainer = this.$refs.dataForm;
// const scrollPosition = scrollContainer.scrollTop;
// console.log('12', scrollPosition);
this.$nextTick(() => {
this.$refs['dataForm'].resetFields();
if (this.dataForm.id) {
//
getEqCheckLog(this.dataForm.id).then((response) => {
this.formLoading = false;
this.dataForm = response.data;
if (this.dataForm.files.length > 0) {
this.file = this.dataForm.files[0].fileUrl;
this.fileName = this.dataForm.files[0].fileName;
}
this.dataForm.description = this.dataForm.description || '无';
this.setConfig();
this.setInspectionContet();
});
} else {
// if (this.urlOptions.isGetCode) {
// this.getCode()
// }
}
});
this.formLoading = false;
},
setInspectionContet() {
//
getCheckDetPage({
pageNo: 1,
pageSize: 99,
configId: this.dataForm.configId,
}).then((response) => {
this.list = response.data.list;
this.listQuery.total = response.data.total;
});
},
// /
addNew(id) {
this.addOrUpdateVisible = true;
this.$nextTick(() => {
this.$refs.addOrUpdate.init(id);
});
},
handleEqTypeChange(type) {
this.dataForm.equipmentId = null;
this.dataForm.equipmentCode = null;
if (type) {
this.equipmentOptions = this.eqList
.filter((item) => item.special)
.filter((item) => item.specialType === type)
.map((item) => ({ label: item.name, value: item.id }));
} else
this.equipmentOptions = this.eqList
// .filter((item) => item.special)
.map((item) => ({
label: item.name,
value: item.id,
}));
// this.$emit('update', this.form)
},
//
dataFormSubmit() {
this.$refs['dataForm'].validate((valid) => {
if (!valid) {
return false;
}
if (this.file) {
const temp = this.file.split(','); //
let arry = [];
temp.forEach((item, index) => {
arry.push({
fileName: this.fileName,
fileType: 2,
fileUrl: item,
});
});
this.dataForm.files = arry;
} else {
this.dataForm.files = [];
}
//
if (this.dataForm.id) {
updateCheckLog(this.dataForm).then((response) => {
this.$modal.msgSuccess('修改成功');
this.visible = false;
this.$emit('refreshDataList');
});
return;
}
//
createCheckLog(this.dataForm).then((response) => {
this.$modal.msgSuccess('新增成功');
this.visible = false;
this.$emit('refreshDataList');
});
});
},
},
};
</script>
<style scoped>
.el-date-editor,
.el-select {
width: 100%;
}
.drawer-body__footer {
display: flex;
justify-content: flex-end;
padding: 18px;
}
.action_btn {
float: right;
margin: 5px 15px;
font-size: 14px;
}
.add {
color: #0b58ff;
}
.drawer >>> .el-drawer {
border-radius: 8px 0 0 8px;
display: flex;
flex-direction: column;
}
.drawer >>> .el-form-item__label {
padding: 0;
}
.drawer >>> .el-drawer__header {
margin: 0;
padding: 32px 32px 24px;
border-bottom: 1px solid #dcdfe6;
}
.drawer >>> .el-drawer__body {
flex: 1;
height: 1px;
margin: 10px 0;
display: flex;
flex-direction: column;
}
.drawer >>> .content {
padding: 30px 24px;
flex: 1;
display: flex;
flex-direction: column;
/* height: 100%; */
}
.drawer >>> .visual-part {
flex: 1 auto;
max-height: 76vh;
overflow: hidden;
overflow-y: scroll;
padding-right: 10px; /* 调整滚动条样式 */
}
.drawer >>> .el-form,
.drawer >>> .attr-list {
padding: 0 16px;
}
.drawer-body__footer {
display: flex;
justify-content: flex-end;
padding: 18px;
}
</style>

View File

@ -0,0 +1,449 @@
<!--
filename: Record.vue
author: liubin
date: 2023-12-12 13:53:22
description:
-->
<template>
<div class="app-container SpecialEquipmentCheckRecord">
<!-- 搜索工作栏 -->
<SearchBar
:formConfigs="searchBarFormConfig"
ref="search-bar"
@select-changed="handleSearchBarChange"
@headBtnClick="handleSearchBarBtnClick" />
<!-- 列表 -->
<base-table
:table-props="tableProps"
:page="queryParams.pageNo"
:limit="queryParams.pageSize"
:table-data="list"
@emitFun="handleEmitFun">
<method-btn
v-if="tableBtn.length"
slot="handleBtn"
label="操作"
:width="120"
:method-list="tableBtn"
@clickBtn="handleTableBtnClick" />
</base-table>
<!-- 分页组件 -->
<pagination
v-show="total > 0"
:total="total"
:page.sync="queryParams.pageNo"
:limit.sync="queryParams.pageSize"
@pagination="getList" />
<!-- 对话框(添加 / 修改) -->
<base-dialog
:dialogTitle="title"
:dialogVisible="open"
@close="cancel"
@cancel="cancel"
@confirm="submitForm">
<DialogForm
v-if="open"
ref="form"
v-model="form"
:disabled="mode == 'detail'"
:has-files="true"
:rows="rows" />
</base-dialog>
<addRecord
v-if="addOrUpdateVisible"
ref="addOrUpdate"
@refreshDataList="getList"
@destroy="addOrUpdateVisible = false" />
</div>
</template>
<script>
import moment from 'moment';
import basicPageMixin from '@/mixins/lb/basicPageMixin';
import addRecord from './Record-add.vue';
import {
exportCheckLogExcel,
deleteEqCheckLog,
} from '@/api/equipment/base/inspection/record';
import { parseTime } from '../../core/mixins/code-filter';
const timeFilter = (val) => moment(val).format('yyyy-MM-DD HH:mm:ss');
export default {
name: 'SpecialEquipmentCheckRecord',
components: { addRecord },
mixins: [basicPageMixin],
data() {
return {
addOrUpdateVisible: false,
searchBarKeys: ['equipmentId', 'actualTime', 'specialType'],
tableBtn: [
this.$auth.hasPermi('equipment:check-record:detail')
? {
type: 'detail',
btnName: '详情',
}
: undefined,
this.$auth.hasPermi('equipment:check-record:update')
? {
type: 'edit',
btnName: '修改',
}
: undefined,
this.$auth.hasPermi('equipment:check-record:delete')
? {
type: 'delete',
btnName: '删除',
}
: undefined,
].filter((v) => v),
tableProps: [
{ prop: 'configName', label: '配置名称' },
{ prop: 'equipmentName', label: '设备名称' },
{
prop: 'origin',
label: '数据来源',
filter: (val) => ['', '手动', 'PDA'][val],
},
// { prop: 'sectionName', label: '' },
{ prop: 'actualTime', label: '实际巡检时间', filter: parseTime },
// { prop: 'maintenanceDetail', label: '' },
{ prop: 'responsible', label: '巡检人' },
],
searchBarFormConfig: [
{
type: 'select',
label: '设备大类',
placeholder: '请选择设备大类',
param: 'specialType',
onchange: true,
selectOptions: [
{ id: 1, name: '安全设备' },
{ id: 2, name: '消防设备' },
{ id: 3, name: '特种设备' },
],
filterable: true,
},
{
type: 'select',
label: '设备',
placeholder: '请选择设备',
param: 'equipmentId',
filterable: true,
},
//
{
type: 'datePicker',
label: '时间段',
dateType: 'daterange', // datetimerange
format: 'yyyy-MM-dd',
valueFormat: 'yyyy-MM-dd HH:mm:ss',
rangeSeparator: '-',
startPlaceholder: '开始日期',
endPlaceholder: '结束日期',
defaultTime: ['00:00:00', '23:59:59'],
param: 'actualTime',
// width: 350,
},
{
type: 'button',
btnName: '查询',
name: 'search',
color: 'primary',
},
{
type: 'separate',
},
{
type: this.$auth.hasPermi('equipment:check-record:export')
? 'button'
: '',
btnName: '导出',
name: 'export',
plain: true,
color: 'primary',
},
{
type: this.$auth.hasPermi('equipment:check-record:create')
? 'button'
: '',
btnName: '新增',
name: 'add',
plain: true,
},
],
rows: [
[
{
input: true,
label: '维修单号',
prop: 'repairOrderNumber',
},
{
select: true,
label: '设备名称',
prop: 'equipmentId',
url: '/base/core-equipment/listAll',
bind: {
filterable: true,
clearable: true,
},
rules: [
{ required: true, message: '设备名称不能为空', trigger: 'blur' },
],
},
],
[
{
// TODO:
select: true,
label: '维修工',
prop: 'repairman',
// url: '/base/core-equipment/listAll',
bind: {
filterable: true,
clearable: true,
multiple: true,
},
rules: [
{ required: true, message: '维修工不能为空', trigger: 'blur' },
],
},
{
input: true,
label: '联系方式',
prop: 'repairmanPhone',
},
],
[
{
datetime: true,
label: '故障发生时间',
prop: 'faultTime',
rules: [
{
required: true,
message: '故障发生时间不能为空',
trigger: 'blur',
},
],
bind: {
format: 'yyyy-MM-dd HH:mm:ss',
'value-format': 'timestamp',
// 'value-format': 'yyyy-MM-dd HH:mm:ss',
clearable: true,
},
},
{
select: true,
label: '故障级别',
prop: 'faultLevel', //
options: this.getDictDatas(this.DICT_TYPE.FAULT_LEVEL),
},
],
],
//
open: false,
//
queryParams: {
pageNo: 1,
pageSize: 10,
maintenanceStatus: null,
createTime: null,
equipmentId: null,
special: true,
specialType: null,
},
//
form: {},
basePath: '/base/equipment-check-log',
mode: null,
allSpecialEquipments: [],
};
},
created() {
this.initSearchBar();
this.getList();
},
methods: {
initSearchBar() {
this.http('/base/core-equipment/listAll', 'get').then(({ data }) => {
this.allSpecialEquipments = data.filter((item) => item.special);
this.setSearchBarEquipmentList(data.filter((item) => item.special));
});
},
//
handleSearchBarChange({ param, value }) {
if ('specialType' === param) {
if (!value) {
this.setSearchBarEquipmentList(this.allSpecialEquipments);
return;
}
this.setSearchBarEquipmentList(
this.allSpecialEquipments.filter((item) => item.specialType == value)
);
}
},
setSearchBarEquipmentList(eqList) {
this.$set(
this.searchBarFormConfig[1],
'selectOptions',
eqList.map((item) => ({
name: item.name,
id: item.id,
}))
);
},
/** 查询列表 */
getList() {
this.loading = true;
//
this.recv(this.queryParams).then((response) => {
this.list = response.data.list;
this.total = response.data.total;
this.loading = false;
});
},
/** 取消按钮 */
cancel() {
this.open = false;
this.mode = null;
this.reset();
},
/** 表单重置 */
reset() {
this.form = {
id: null,
repairOrderNumber: null,
equipmentId: null,
repairman: null,
repairmanPhone: null,
faultTime: null,
faultLevel: null,
maintenanceStartTime: null,
maintenanceFinishTime: null,
faultType: null,
repairMode: null,
maintenanceStatus: null,
faultDetail: null,
maintenanceDetail: null,
remark: null,
files: [
// {
// fileName: '',
// fileType: '',
// fileUrl: '',
// },
],
};
this.resetForm('form');
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNo = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm('queryForm');
this.handleQuery();
},
/** 新增按钮操作 */
handleAdd() {
// this.reset();
// this.open = true;
// this.title = '';
this.addOrUpdateVisible = true;
this.$nextTick(() => {
this.$refs.addOrUpdate.init();
});
},
/** 修改按钮操作 */
handleUpdate(row) {
// this.reset();
// const id = row.id;
// this.info({ id }).then((response) => {
// this.form = response.data;
// this.open = true;
// this.title = '';
// });
this.addOrUpdateVisible = true;
this.$nextTick(() => {
this.$refs.addOrUpdate.init(row.id);
});
},
/** 提交按钮 */
submitForm() {
this.$refs['form'].validate((valid) => {
if (!valid) {
return;
}
//
if (this.form.id != null) {
this.put(this.form).then((response) => {
this.$modal.msgSuccess('修改成功');
this.open = false;
this.getList();
});
return;
}
//
this.post(this.form).then((response) => {
this.$modal.msgSuccess('新增成功');
this.open = false;
this.getList();
});
});
},
/** 删除按钮操作 */
handleDelete(row) {
const id = row.id;
this.$modal
.confirm(
'是否删除设备巡检记录配置名称为"' + row.configName + '"的数据项?'
)
.then(function () {
return deleteEqCheckLog(id);
})
.then(() => {
this.getList();
this.$modal.msgSuccess('删除成功');
})
.catch(() => {});
},
handleDetail({ id }) {
this.addOrUpdateVisible = true;
this.$nextTick(() => {
this.$refs.addOrUpdate.init(id, true);
});
},
/** 导出按钮操作 */
handleExport() {
//
let params = { ...this.queryParams };
params.pageNo = undefined;
params.pageSize = undefined;
this.$modal
.confirm('是否确认导出所有设备巡检记录?')
.then(() => {
this.exportLoading = true;
return exportCheckLogExcel(params);
})
.then((response) => {
this.$download.excel(response, '设备巡检记录.xls');
this.exportLoading = false;
})
.catch(() => {});
},
},
};
</script>
<style scoped lang="scss">
.SpecialEquipmentCheckRecord {
}
</style>

View File

@ -0,0 +1,65 @@
<!--
* @Author: zwq
* @Date: 2023-08-01 15:27:31
* @LastEditors: zwq
* @LastEditTime: 2023-08-01 16:25:54
* @Description:
-->
<template>
<div :class="[className, { 'p-0': noPadding }]">
<slot />
</div>
</template>
<script>
export default {
props: {
size: {
// : xl lg md sm
type: String,
default: 'de',
validator: function (val) {
return ['xl', 'lg', 'de', 'md', 'sm'].indexOf(val) !== -1;
},
},
noPadding: {
type: Boolean,
default: false,
},
},
computed: {
className: function () {
return `${this.size}-title`;
},
},
};
</script>
<style lang="scss" scoped>
$pxls: (xl, 28px) (lg, 24px) (de, 20px) (md, 18px) (sm, 16px);
$mgr: 8px;
@each $size, $height in $pxls {
.#{$size}-title {
font-size: 18px;
line-height: $height;
color: #000;
font-weight: 500;
font-family: '微软雅黑', 'Microsoft YaHei', Arial, Helvetica, sans-serif;
&::before {
content: '';
display: inline-block;
vertical-align: top;
width: 4px;
height: $height + 2px;
border-radius: 1px;
margin-right: $mgr;
background-color: #0b58ff;
}
}
}
.p-0 {
padding: 0;
}
</style>

View File

@ -0,0 +1,341 @@
<!--
* @Author: zwq
* @Date: 2021-11-18 14:16:25
* @LastEditors: DY
* @LastEditTime: 2023-12-01 11:02:43
* @Description:
-->
<template>
<el-drawer
:visible.sync="visible"
:show-close="false"
:wrapper-closable="true"
class="drawer"
size="50%">
<small-title slot="title" :no-padding="true">
{{ isdetail ? '详情' : '添加巡检' }}
</small-title>
<div class="content">
<div class="visual-part">
<el-form
:model="dataForm"
:rules="dataRule"
ref="dataForm"
@keyup.enter.native="dataFormSubmit()"
label-position="top">
<el-row :gutter="20">
<el-col :span="8">
<el-form-item label="设备大类" prop="equipmentCategory">
<span>
{{
['-', '安全设备', '消防设备', '特种设备'][
dataForm.equipmentCategory || 0
]
}}
</span>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="设备名称" prop="equipmentName">
{{ dataForm.equipmentName }}
<!-- <el-input v-model="dataForm.equipmentName" disabled clearable placeholder="请输入设备名称" /> -->
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="设备编码" prop="equipmentCode">
{{ dataForm.equipmentCode }}
<!-- <el-input
v-model="dataForm.equipmentCode"
clearable
disabled
placeholder="请输入设备编码" /> -->
</el-form-item>
</el-col>
</el-row>
</el-form>
</div>
<el-divider />
<div class="attr-list">
<small-title
style="margin: 16px 0; padding-left: 8px"
:no-padding="true">
巡检项目
</small-title>
<div v-if="!isdetail" class="action_btn">
<template>
<span style="display: inline-block">
<el-button type="text" @click="addNew()" icon="el-icon-plus">
添加
</el-button>
</span>
</template>
</div>
<base-table
:table-props="tableProps"
:page="listQuery.pageNo"
:limit="listQuery.pageSize"
:table-data="checkDetList">
<method-btn
v-if="!isdetail"
slot="handleBtn"
:width="120"
label="操作"
:method-list="tableBtn"
@clickBtn="handleClick" />
</base-table>
<pagination
v-show="listQuery.total > 0"
:total="listQuery.total"
:page.sync="listQuery.pageNo"
:limit.sync="listQuery.pageSize"
:page-sizes="[5, 10, 15]"
@pagination="getList" />
<!-- <div class="drawer-body__footer">
<el-button type="primary" @click="goback()">关闭</el-button>
</div> -->
</div>
</div>
<attr-add
v-if="addOrUpdateVisible"
ref="addOrUpdate"
:config-id="dataForm.id"
@refreshDataList="getList" />
</el-drawer>
</template>
<script>
import {
getEqCheck,
getCheckDetPage,
deleteCheckDet,
} from '@/api/equipment/base/inspection/settings';
import SmallTitle from './SmallTitle';
import attrAdd from './attr-add';
import { DICT_TYPE, getDictDatas } from '@/utils/dict';
const tableBtn = [
{
type: 'edit',
btnName: '编辑',
},
{
type: 'delete',
btnName: '删除',
},
];
const tableProps = [
{
prop: 'program',
label: '巡检项目',
},
{
prop: 'content',
label: '巡检内容',
},
{
prop: 'code',
label: '巡检内容编码',
},
{
prop: 'description',
label: '备注',
},
];
export default {
components: { SmallTitle, attrAdd },
data() {
return {
tableBtn,
tableProps,
addOrUpdateVisible: false,
urlOptions: {
infoURL: getEqCheck,
},
listQuery: {
pageSize: 10,
pageNo: 1,
total: 0,
},
dataForm: {
id: undefined,
code: undefined,
name: '',
materialType: undefined,
productType: undefined,
area: undefined,
specifications: undefined,
processTime: 0,
remark: undefined,
unit: undefined,
},
checkDetList: [],
visible: false,
isdetail: false,
dataRule: {
code: [
{ required: true, message: '物料编码不能为空', trigger: 'blur' },
],
name: [
{ required: true, message: '物料名称不能为空', trigger: 'blur' },
],
materialType: [
{ required: true, message: '物料类型不能为空', trigger: 'change' },
],
productType: [
{ required: true, message: '产品类型不能为空', trigger: 'change' },
],
processTime: [
{
required: true,
message: '产线生产单位用时不能为空',
trigger: 'blur',
},
],
},
};
},
mounted() {},
methods: {
initData() {
this.checkDetList.splice(0);
this.listQuery.total = 0;
},
handleClick(raw) {
if (raw.type === 'delete') {
this.$confirm(
`是否确认删除巡检项目名称为"${raw.data.program}"的数据项?`,
'提示',
{
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
}
)
.then(() => {
deleteCheckDet(raw.data.id).then(({ data }) => {
this.$message({
message: '操作成功',
type: 'success',
duration: 1500,
onClose: () => {
this.getList();
},
});
});
})
.catch(() => {});
} else {
this.addNew(raw.data.id);
}
},
getList() {
//
getCheckDetPage({
...this.listQuery,
configId: this.dataForm.id,
}).then((response) => {
this.checkDetList = response.data.list;
this.listQuery.total = response.data.total;
});
},
init(id, isdetail) {
this.initData();
this.isdetail = isdetail || false;
this.dataForm.id = id || undefined;
this.visible = true;
this.$nextTick(() => {
this.$refs['dataForm'].resetFields();
if (this.dataForm.id) {
//
this.urlOptions.infoURL(id).then((response) => {
this.dataForm = response.data;
});
//
this.getList();
} else {
if (this.urlOptions.isGetCode) {
this.getCode();
}
}
});
},
goback() {
this.$emit('refreshDataList');
this.visible = false;
// this.initData();
},
goEdit() {
this.isdetail = false;
},
// /
addNew(id) {
this.addOrUpdateVisible = true;
this.$nextTick(() => {
this.$refs.addOrUpdate.init(id);
});
},
},
};
</script>
<style scoped>
.drawer >>> .el-drawer {
border-radius: 8px 0 0 8px;
display: flex;
flex-direction: column;
}
.drawer >>> .el-form-item__label {
padding: 0;
}
.drawer >>> .el-drawer__header {
margin: 0;
padding: 32px 32px 24px;
border-bottom: 1px solid #dcdfe6;
}
.drawer >>> .el-drawer__body {
flex: 1;
height: 1px;
display: flex;
flex-direction: column;
}
.drawer >>> .content {
padding: 30px 24px;
flex: 1;
display: flex;
flex-direction: column;
/* height: 100%; */
}
.drawer >>> .visual-part {
/* flex: 1 auto; */
padding-right: 10px; /* 调整滚动条样式 */
}
.drawer >>> .el-form {
padding: 0 16px;
}
.drawer-body__footer {
display: flex;
justify-content: flex-end;
padding: 18px;
}
.action_btn {
float: right;
margin: -40px 15px;
font-size: 14px;
}
.add {
color: #0b58ff;
}
</style>

View File

@ -0,0 +1,167 @@
<!--
* @Author: zwq
* @Date: 2021-11-18 14:16:25
* @LastEditors: DY
* @LastEditTime: 2023-11-25 16:23:13
* @Description:
-->
<template>
<el-form
:model="dataForm"
:rules="dataRule"
ref="dataForm"
@keyup.enter.native="dataFormSubmit()"
label-width="80px">
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="配置名称" prop="name">
<el-input v-model="dataForm.name" placeholder="请输入配置名称" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="配置编码" prop="code">
<el-input v-model="dataForm.code" placeholder="请输入配置编码" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item
label="设备大类"
prop="equipmentCategory"
:rules="[
{ required: true, message: '请选择设备大类', trigger: 'blur' },
]">
<el-select
v-model="dataForm.equipmentCategory"
:placeholder="`请选择设备大类`"
@change="handleEqTypeChange">
<el-option
v-for="opt in equipmentTypeOptions"
:key="opt.value"
:label="opt.label"
:value="opt.value" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="设备名称" prop="equipmentId">
<el-select
v-model="dataForm.equipmentId"
filterable
style="width: 100%"
placeholder="请选择设备名称"
@change="setCode">
<el-option
v-for="d in equipmentOptions"
:key="d.value"
:label="d.label"
:value="d.value" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="设备编码" prop="equipmentCode">
<el-input
v-model="dataForm.equipmentCode"
disabled
placeholder="请输入设备编码" />
</el-form-item>
</el-col>
</el-row>
</el-form>
</template>
<script>
import basicAdd from '../../core/mixins/basic-add';
import {
getEqCheck,
getCode,
createCheckConfig,
updateCheckConfig,
} from '@/api/equipment/base/inspection/settings';
import { getEquipmentAll } from '@/api/base/equipment';
export default {
mixins: [basicAdd],
data() {
return {
urlOptions: {
isGetCode: true,
codeURL: getCode,
createURL: createCheckConfig,
updateURL: updateCheckConfig,
infoURL: getEqCheck,
},
dataForm: {
id: undefined,
code: undefined,
name: undefined,
equipmentId: undefined,
equipmentCode: undefined,
equipmentCategory: undefined,
},
eqList: [],
dataRule: {
equipmentId: [
{ required: true, message: '设备不能为空', trigger: 'blur' },
],
code: [
{ required: true, message: '配置编码不能为空', trigger: 'blur' },
],
name: [
{ required: true, message: '配置名称不能为空', trigger: 'blur' },
],
},
equipmentOptions: [],
equipmentTypeOptions: [
{ label: '安全设备', value: 1 },
{ label: '消防设备', value: 2 },
{ label: '特种设备', value: 3 },
],
};
},
mounted() {
this.getDict();
},
methods: {
async getDict() {
//
const res = await getEquipmentAll();
this.eqList = res.data;
this.$nextTick(() => {
this.handleEqTypeChange();
});
},
setCode() {
const chooseM = this.eqList.filter((item) => {
return item.id === this.dataForm.equipmentId;
});
this.dataForm.equipmentCode = chooseM[0].code;
},
// handlers
handleEqTypeChange(type) {
this.dataForm.equipmentId = null;
this.dataForm.equipmentCode = null;
if (type) {
this.equipmentOptions = this.eqList
.filter((item) => item.special)
.filter((item) => item.specialType === type)
.map((item) => ({ label: item.name, value: item.id }));
} else
this.equipmentOptions = this.eqList
.filter((item) => item.special)
.map((item) => ({
label: item.name,
value: item.id,
}));
// this.$emit('update', this.form)
},
},
};
</script>
<style scoped lang="scss">
.el-date-editor,
.el-select {
width: 100%;
}
</style>

View File

@ -0,0 +1,145 @@
<template>
<el-dialog
:visible.sync="visible"
:width="'30%'"
:append-to-body="true"
:close-on-click-modal="false"
class="dialog">
<template #title>
<slot name="title">
<div class="titleStyle">
{{ !dataForm.id ? '新增' : '编辑' }}
</div>
</slot>
</template>
<el-form
ref="dataForm"
:model="dataForm"
:rules="dataRule"
label-width="60px"
@keyup.enter.native="dataFormSubmit()">
<el-form-item label="巡检" prop="checkId">
<el-select v-model="dataForm.checkId" filterable placeholder="请选择巡检" style="width: 100%">
<el-option v-for="dict in checkList" :key="dict.id" :label="dict.content"
:value="dict.id" />
</el-select>
</el-form-item>
<el-form-item label="备注" prop="description">
<el-input
v-model="dataForm.description"
placeholder="请输入备注"
clearable />
</el-form-item>
</el-form>
<el-row style="text-align: right">
<el-button @click="visible = false">取消</el-button>
<el-button type="primary" @click="dataFormSubmit()">确定</el-button>
</el-row>
</el-dialog>
</template>
<script>
import { getCheckDet, createCheckDet, updateCheckDet, getcheckList } from "@/api/equipment/base/inspection/settings";
export default {
props: {
configId: {
type: String,
default: '',
},
},
data() {
return {
visible: false,
dataForm: {
id: undefined,
checkId: undefined,
configId: undefined,
description: ''
},
checkList: [],
dataRule: {
checkId: [{ required: true, message: '巡检不能为空', trigger: 'blur' }],
},
};
},
mounted() {
this.getDict()
},
methods: {
async getDict() {
const res = await getcheckList()
this.checkList = res.data
},
init(id) {
this.dataForm.id = id || '';
this.visible = true;
this.$nextTick(() => {
this.$refs['dataForm'].resetFields();
if (this.dataForm.id) {
getCheckDet(this.dataForm.id).then((res) => {
// const { name, value } = res.data;
// this.dataForm.name = name;
// this.dataForm.value = value;
this.dataForm = res.data
});
}
});
},
//
dataFormSubmit() {
this.$refs['dataForm'].validate((valid) => {
if (valid) {
//
if (this.dataForm.id) {
updateCheckDet({
...this.dataForm,
configId: this.configId
}).then((response) => {
this.$modal.msgSuccess('修改成功');
this.visible = false;
this.$emit('refreshDataList');
});
return;
}
//
createCheckDet({
...this.dataForm,
configId: this.configId,
}).then((response) => {
this.$modal.msgSuccess('新增成功');
this.visible = false;
this.$emit('refreshDataList');
});
}
});
},
},
};
</script>
<style scoped>
.dialog >>> .el-dialog__body {
padding: 30px 24px;
}
.dialog >>> .el-dialog__header {
font-size: 16px;
color: rgba(0, 0, 0, 0.85);
font-weight: 500;
padding: 13px 24px;
border-bottom: 1px solid #e9e9e9;
}
.dialog >>> .el-dialog__header .titleStyle::before {
content: '';
display: inline-block;
width: 4px;
height: 16px;
background-color: #0b58ff;
border-radius: 1px;
margin-right: 8px;
position: relative;
top: 2px;
}
</style>

View File

@ -0,0 +1,399 @@
<!--
filename: AssetsUpload.vue
author: liubin
date: 2023-10-12 16:40:14
description: 上传资料/图片 组件
-->
<template>
<div class="assets-upload">
<section class="operations">
<el-button type="text" class="expand-btn" @click="expand = !expand">
<i class="el-icon-folder-opened" v-if="expand"></i>
<i class="el-icon-folder" v-else></i>
展开
</el-button>
<!-- <div class="preview-btn">
<i class="el-icon-view"></i>
预览
</div> -->
</section>
<section
class="file-area"
:style="{
height: expand ? 'auto' : isPicMode ? '180px' : '152px',
gap: isPicMode ? '0 24px' : '24px',
gridAutoRows: isPicMode ? '180px' : '152px',
}">
<el-upload
class="equipment-upload"
:disabled="disabled"
drag
:action="uploadUrl"
:headers="headers"
multiple
:show-file-list="false"
:before-upload="beforeUpload"
:on-success="handleSuccess">
<i class="el-icon-upload"></i>
<div class="el-upload__text">
<span>将文件拖到此处或</span>
<em>点击上传</em>
</div>
<div class="el-upload__tip" slot="tip">
{{
isPicMode ? '仅支持上传 .jpg .png 格式文件, 且' : ''
}}文件大小不超过2MB
</div>
</el-upload>
<div
v-for="(file, index) in files"
:key="file.fileName"
style="width: 100%">
<div
class="file-list__item"
v-if="!isPicMode"
:style="{
background: isPicMode
? `url(${file.fileUrl}) no-repeat`
: `url(${defaultBg}) no-repeat`,
backgroundSize: isPicMode ? '100% 100%' : '64px',
backgroundPosition: isPicMode ? '0% 0%' : 'center',
}"
@click="handleDownload(file)"
:data-name="file.fileName">
<el-button
v-if="!disabled"
type="text"
class="el-icon-delete"
style="padding: 0"
@click="(e) => handleDelete(file)" />
</div>
<el-image
v-else
class="file-list__item"
style="width: 100%"
:src="file.fileUrl"
:preview-src-list="files.map((item) => item.fileUrl)"></el-image>
</div>
</section>
</div>
</template>
<script>
import { getAccessToken } from '@/utils/auth';
import defaultBg from '../../../assets/images/default-file-icon.png';
function checkSize(file, message) {
const isLt2M = file.size / 1024 / 1024 < 2;
if (!isLt2M) {
message.error('上传文件大小不能超过 2MB!');
}
return isLt2M;
}
function checkPic(file, message) {
const isJPG = file.type === 'image/jpeg';
const isPNG = file.type === 'image/png';
const isPic = isJPG || isPNG;
if (!isPic) {
message.error('上传图片只能是 JPG/PNG 格式!');
}
return isPic;
}
export default {
name: 'AssetsUpload',
components: {},
model: {
prop: 'dataSource',
event: 'update',
},
props: {
type: {
type: String,
default: 'image',
},
dataSource: {
type: Array,
default: () => [],
},
equipmentId: {
type: String,
default: '',
},
isPicMode: {
type: Boolean,
default: false,
},
disabled: {
type: Boolean,
default: false,
},
},
emits: ['update-filelist'],
data() {
return {
defaultBg,
expand: false,
headers: { Authorization: 'Bearer ' + getAccessToken() }, //
fileList: [],
uploadUrl: process.env.VUE_APP_BASE_API + '/admin-api/infra/file/upload',
files: [],
updateTimer: null,
};
},
watch: {
dataSource: {
handler(val) {
this.files = JSON.parse(JSON.stringify(val));
},
immediate: true,
deep: true,
},
},
mounted() {},
methods: {
// handle success, per file!
handleSuccess(response, file, fileList) {
this.$notify({
title: '成功',
message: '上传成功! 点击确认保存上传结果',
type: 'success',
});
if (
response == null ||
!('data' in response) ||
response.data == null ||
response.data.trim() == ''
) {
this.$message.error('上传出错了!');
return;
}
this.files.push({
fileName: file.name,
fileUrl: response.data,
fileType: this.isPicMode ? 1 : 2,
});
// debugger;
//
if (this.updateTimer) {
clearTimeout(this.updateTimer);
}
this.updateTimer = setTimeout(() => {
// console.log('[AssetsUpload] ');
this.emitFilelist();
clearTimeout(this.updateTimer);
this.updateTimer = null;
}, 500);
},
async handleDownload(file) {
if (this.isPicMode) {
// this.$emit('preview', file);
const link = document.createElement('a');
link.href = file.fileUrl;
link.target = '_blank';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
} else {
// this.$emit('download', file);
const data = await this.$axios({
url: file.fileUrl,
method: 'get',
responseType: 'blob',
});
const link = document.createElement('a');
link.href = window.URL.createObjectURL(new Blob([data]));
link.download = file.fileName;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
window.URL.revokeObjectURL(link.href);
}
},
emitFilelist() {
this.$emit('update', this.files);
},
handleRemove(file, fileList) {
debugger;
},
handleDelete(file) {
// fileName fileType fileUrl
this.files = this.files.filter((item) => item.fileUrl != file.fileUrl);
this.$notify({
title: '成功',
message: '删除成功! 需点击确认保存删除结果',
type: 'success',
});
this.emitFilelist();
},
beforeUpload(file) {
if (this.isPicMode) {
return checkPic(file, this.$message) && checkSize(file, this.$message);
}
return checkSize(file, this.$message);
},
handleUpload() {
switch (this.type) {
case 'image':
break;
case 'asset':
break;
}
},
updateFileList(appendFilelist) {
// Array
this.$emit('update-filelist', this.appendFilelist);
},
},
};
</script>
<style scoped lang="scss">
.assets-upload {
position: relative;
}
.operations {
position: absolute;
top: -36px;
right: 0;
display: flex;
align-items: center;
}
.expand-btn,
.preview-btn {
font-size: 14px;
line-height: 1.2;
display: inline-block;
padding-left: 20px;
cursor: pointer;
z-index: 1000;
}
.expand-btn {
margin-right: 12px;
}
.preview-btn {
color: #ccc;
}
.expand-btn,
.preview-btn:hover,
.preview-btn.active {
// color: #0042d0;
color: #0b58ff;
}
:deep(.equipment-upload) {
.el-upload-dragger {
width: 188px;
height: 128px;
}
.el-icon-upload {
margin: 12px 0;
font-size: 48px;
}
.el-upload__text {
font-size: 12px;
line-height: 2px;
display: flex;
flex-direction: column;
em {
margin-top: 12px;
}
}
.el-upload__tip {
font-size: 12px;
line-height: 1.5;
color: #d1d1d1;
margin: 0 0 12px;
transform: translateY(-12px);
user-select: none;
}
}
.equipment-upload {
margin-bottom: 24px;
}
.file-list {
padding: 12px;
border: 1px solid #ccc;
}
// custom
.file-area {
display: grid;
grid-template-columns: repeat(auto-fill, 188px);
grid-auto-rows: 152px;
gap: 48px 24px;
overflow: hidden;
}
.file-list__item {
height: 128px;
background-color: #fff;
border: 1px dashed #d9d9d9;
border-radius: 6px;
-webkit-box-sizing: border-box;
box-sizing: border-box;
text-align: center;
cursor: pointer;
position: relative;
// overflow: hidden;
&:hover {
.el-icon-delete {
display: block;
}
}
.el-icon-delete {
color: #ccc;
position: absolute;
top: 8px;
right: 8px;
display: none;
&:hover {
color: rgb(210, 41, 41);
}
}
}
.file-list__item:hover {
border-color: #0b58ff;
}
.file-list__item::after {
content: attr(data-name);
position: absolute;
left: 0;
bottom: -26px;
font-size: 14px;
line-height: 2;
color: #616161;
}
.default-icon {
background: url(../../../assets/images/default-file-icon.png) no-repeat;
background-position: center;
background-size: 64px;
}
</style>

View File

@ -0,0 +1,313 @@
<!--
filename: dialogForm.vue
author: liubin
date: 2023-08-15 10:32:36
description: 弹窗的表单组件
-->
<template>
<el-form
ref="form"
:model="form"
:label-width="`${labelWidth}px`"
:size="size"
:label-position="labelPosition"
v-loading="formLoading">
<el-row :gutter="20" v-for="(row, rindex) in rows" :key="rindex">
<el-col v-for="col in row" :key="col.label" :span="24 / row.length">
<el-form-item :label="col.label" :prop="col.prop" :rules="col.rules">
<el-input
v-if="col.input"
v-model="form[col.prop]"
@change="$emit('update', form)"
:placeholder="`请输入${col.label}`"
v-bind="col.bind" />
<el-input
v-if="col.textarea"
type="textarea"
v-model="form[col.prop]"
@change="$emit('update', form)"
:placeholder="`请输入${col.label}`"
v-bind="col.bind" />
<el-select
v-if="col.select"
v-model="form[col.prop]"
:placeholder="`请选择${col.label}`"
@change="$emit('update', form)"
v-bind="col.bind">
<el-option
v-for="opt in optionListOf[col.prop]"
:key="opt.value"
:label="opt.label"
:value="opt.value" />
</el-select>
<el-date-picker
v-if="col.datetime"
v-model="form[col.prop]"
type="datetime"
:placeholder="`请选择${col.label}`"
value-format="timestamp"
v-bind="col.bind"></el-date-picker>
<el-upload
class="upload-in-dialog"
v-if="col.upload"
:file-list="uploadedFileList"
:action="col.url"
:on-success="handleUploadSuccess"
v-bind="col.bind">
<el-button
size="small"
type="primary"
:disabled="col.bind?.disabled || false">
点击上传
</el-button>
<div class="el-upload__tip" slot="tip" v-if="col.uploadTips">
{{ col.uploadTips || '只能上传jpg/png文件大小不超过2MB' }}
</div>
</el-upload>
<el-switch
v-if="col.switch"
v-model="form[col.prop]"
active-color="#0b58ff"
inactive-color="#e1e1e1"
v-bind="col.bind"></el-switch>
<component
v-if="col.subcomponent"
:key="col.key"
:is="col.subcomponent"
v-bind="col.bind"
:inlineStyle="col.style"></component>
</el-form-item>
</el-col>
</el-row>
</el-form>
</template>
<script>
/**
* 找到最长的label
* @param {*} options
*/
function findMaxLabelWidth(rows) {
let max = 0;
rows.forEach((row) => {
row.forEach((opt) => {
// debugger;
if (!opt.label) return 0;
if (opt.label.length > max) {
max = opt.label.length;
}
});
});
return max;
}
export default {
name: 'DialogForm',
model: {
prop: 'dataForm',
event: 'update',
},
emits: ['update'],
components: {},
props: {
rows: {
type: Array,
default: () => [],
},
dataForm: {
type: Object,
default: () => ({}),
},
disabled: {
type: Boolean,
default: false,
},
labelPosition: {
type: String,
default: 'right',
},
size: {
type: String,
default: '',
},
},
data() {
return {
formLoading: true,
optionListOf: {},
uploadedFileList: [],
dataLoaded: false,
};
},
computed: {
labelWidth() {
let max = findMaxLabelWidth(this.rows);
// 20px
return max * 20;
// return max * 20 + 'px';
},
form: {
get() {
// if (this.dataLoaded) return this.dataForm;
// else return {}
return this.dataForm;
},
set(val) {
console.log('set form', val);
},
},
},
watch: {
rows: {
handler() {
console.log('watch triggered!');
this.$nextTick(() => {
this.handleOptions('watch');
});
},
deep: true,
immediate: false,
},
},
mounted() {
// options
this.handleOptions();
},
methods: {
/** 模拟透传 ref */
validate(cb) {
return this.$refs.form.validate(cb);
},
resetFields(args) {
return this.$refs.form.resetFields(args);
},
// getCode
async getCode(url) {
const response = await this.$axios(url);
return response.data;
},
async handleOptions(trigger = 'monuted') {
console.log('[dialogForm:handleOptions]');
const promiseList = [];
this.rows.forEach((cols) => {
cols.forEach((opt) => {
if (opt.value && !this.form[opt.prop]) {
//
this.form[opt.prop] = opt.value;
}
if (opt.options) {
this.$set(this.optionListOf, opt.prop, opt.options);
} else if (opt.url) {
// dependswatcher
if (opt.depends) {
console.log('[handleOptions] setting watch');
this.$watch(
() => this.form[opt.depends],
(id) => {
console.log('<', opt.depends, '>', 'changed', id);
if (id == null) return;
//
this.form[opt.prop] = null;
//
this.$axios({
url: `${opt.url}?id=${id}`,
}).then((res) => {
this.$set(
this.optionListOf,
opt.prop,
res.data.map((item) => ({
label: item[opt.labelKey ?? 'name'],
value: item[opt.valueKey ?? 'id'],
}))
);
});
},
{
immediate: true,
}
);
return;
}
//
if (opt.select || (opt.input && !this.form?.id)) {
promiseList.push(async () => {
const response = await this.$axios(opt.url, {
method: opt.method ?? 'get',
});
console.log('[dialogForm:handleOptions:response]', response);
if (opt.select) {
//
const list =
'list' in response.data
? response.data.list
: response.data;
this.$set(
this.optionListOf,
opt.prop,
list.map((item) => ({
label: item[opt.labelKey ?? 'name'],
value: item[opt.valueKey ?? 'id'],
}))
);
} else if (opt.input) {
console.log('setting code: ', response.data);
//
this.form[opt.prop] = response.data;
}
});
}
}
});
});
console.log('[dialogForm:handleOptions] done!');
// watch
if (trigger == 'watch') {
this.formLoading = false;
return;
}
try {
await Promise.all(promiseList.map((fn) => fn()));
this.formLoading = false;
this.dataLoaded = true;
// console.log("[dialogForm:handleOptions:optionListOf]", this.optionListOf)
} catch (error) {
console.log('[dialogForm:handleOptions:error]', error);
this.formLoading = false;
}
if (!promiseList.length) this.formLoading = false;
},
//
beforeUpload() {},
// bind
handleUploadSuccess(response, file, fileList) {
console.log(
'[dialogForm:handleUploadSuccess]',
response,
file,
fileList,
this.form
);
//
if ('fileNames' in this.form) this.form.fileNames.push(file.name);
//
if ('fileUrls' in this.form) this.form.fileUrls.push(response.data);
this.$modal.msgSuccess('上传成功');
},
getFileName(fileUrl) {
return fileUrl.split('/').pop();
},
},
};
</script>
<style scoped lang="scss">
.el-date-editor,
.el-select {
width: 100%;
}
</style>

View File

@ -0,0 +1,550 @@
<!--
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'"
style="margin-bottom: 32px">
<el-skeleton v-if="!showForm" animated />
<EquipmentInfoForm
key="drawer-dialog-form"
v-if="showForm"
:disabled="mode.includes('detail')"
:sync-filelist="syncFileListFlag"
v-model="form" />
</div>
<div
v-if="section.key == 'attrs'"
style="margin-top: 12px; position: relative">
<div
v-if="!mode.includes('detail')"
style="position: absolute; top: -40px; right: 0">
<el-button @click="handleAddAttr" type="text">
<i class="el-icon-plus"></i>
添加属性
</el-button>
</div>
<base-table
v-loading="attrListLoading"
:table-props="section.props"
:page="attrQuery?.params.pageNo || 1"
:limit="attrQuery?.params.pageSize || 10"
:table-data="list"
@emitFun="handleEmitFun">
<!-- :add-button-show="mode.includes('detail') ? null : '添加属性'"
@emitButtonClick="handleAddAttr" -->
<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="handleConfirm">保存</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="35%"
:append-to-body="true"
custom-class="baseDialog"
@close="closeAttrForm"
@cancel="closeAttrForm"
@confirm="submitAttrForm">
<DialogForm
v-if="attrFormVisible"
ref="attrForm"
:dataForm="attrForm"
:rows="attrRows" />
</base-dialog>
</el-drawer>
</template>
<script>
import DialogForm from './DialogForm';
import EquipmentInfoForm from './EquipmentInfoForm.vue';
const SmallTitle = {
name: 'SmallTitle',
props: ['size'],
components: {},
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, EquipmentInfoForm },
props: ['sections', 'mode', 'dataId'], // dataId id
data() {
return {
visible: false,
showForm: false,
btnLoading: false,
total: 0,
form: {},
list: [],
attrTitle: '',
attrForm: {
id: null,
equipmentId: null,
name: '',
value: '',
},
attrFormVisible: false,
attrRows: [
[
{
input: true,
label: '属性名称',
prop: 'name',
rules: [
{ required: true, message: '属性名称不能为空', trigger: 'blur' },
],
},
],
[
{
input: true,
label: '属性值',
prop: 'value',
},
],
],
attrQuery: {
params: {
pageNo: 1,
pageSize: 10,
},
}, //
infoQuery: null, //
attrFormSubmitting: false,
attrListLoading: false,
syncFileListFlag: null,
};
},
computed: {
formRows() {
return this.sections[0].rows.map((row) => {
return row.map((col) => {
if (col.key == 'eq-pics') {
//
return {
...col,
bind: {
...col.bind,
},
style: {
left: 0,
right: 'unset',
},
};
}
return {
...col,
bind: {
...col.bind,
//
disabled: this.mode == 'detail',
},
};
});
});
},
tableBtn() {
return this.mode == 'detail' ? [] : this.sections[1].tableBtn;
},
},
mounted() {
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,
};
this.$axios(query).then(({ data }) => {
if (section.key == 'base') {
this.form = data;
// this.form = {
// code: 'gj',
// name: '',
// enName: 'unload',
// abbr: '',
// equipmentTypeId: 21084,
// remark: '',
// id: '1712367395052384257',
// createTime: 1697095176000,
// enterTime: 0,
// productionTime: 0,
// files: [
// {
// fileName: '.xlsx',
// fileUrl: 'https://nimg.ws.126.net/?url=http%3A%2F%2Fdingyue.ws.126.net%2F2022%2F0108%2F0f0c6f30j00r5cle9000sc000hs00gtc.jpg&thumbnail=660x2147483647&quality=80&type=jpg',
// fileType: 1
// },
// {
// fileName: '2.xlsx',
// fileUrl: 'https://nimg.ws.126.net/?url=http%3A%2F%2Fdingyue.ws.126.net%2F2022%2F0415%2F2cd23619j00racb96000kc000hs00hsc.jpg&thumbnail=660x2147483647&quality=80&type=jpg',
// fileType: 1
// },
// {
// fileName: '3.xlsx',
// fileUrl: 'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fsafe-img.xhscdn.com%2Fbw1%2F1fea91a0-d088-409e-b145-e0e61254b28b%3FimageView2%2F2%2Fw%2F1080%2Fformat%2Fjpg&refer=http%3A%2F%2Fsafe-img.xhscdn.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1700031689&t=2e0fe7d1de7f54adff3007efe133d67c',
// fileType: 1
// },
// {
// fileName: '4.xlsx',
// fileUrl: 'https://pics5.baidu.com/feed/b7003af33a87e950cdfb4b4546eed044faf2b40d.jpeg?token=1d7484cfe4b014dd201f8c8725cab945',
// fileType: 2
// },
// {
// fileName: '5.xlsx',
// fileUrl: 'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fsafe-img.xhscdn.com%2Fbw1%2Fe3500876-9c46-4b70-8d37-4799520cdd13%3FimageView2%2F2%2Fw%2F1080%2Fformat%2Fjpg&refer=http%3A%2F%2Fsafe-img.xhscdn.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1700031689&t=4abc1df930e62730e5361a7d3765e0f2',
// fileType: 2
// },
// ],
// tvalue: 0,
// processingTime: 0,
// manufacturer: '',
// spec: '',
// description: '',
// };
this.showForm = true;
this.infoQuery = query;
} else if (section.key == 'attrs') {
this.attrQuery = query;
this.list = data.list;
this.total = data.total;
}
});
}
}
},
methods: {
handleTableBtnClick({ type, data }) {
switch (type) {
case 'edit':
this.handleEditAttr(data.id);
break;
case 'delete':
this.handleDeleteAttr(data.id);
break;
}
},
async handleConfirm() {
this.btnLoading = true;
this.syncFileListFlag = Math.random();
this.$nextTick(async () => {
const { code, data } = await this.$axios({
url: this.sections[0].urlUpdate,
method: 'put',
data: this.form,
});
if (code == 0) {
this.$modal.msgSuccess('更新成功');
}
this.btnLoading = false;
this.handleCancel();
});
},
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.$emit('update-mode', 'edit');
},
//
handleAddAttr() {
if (!this.dataId) return this.$message.error('请先创建设备信息');
this.attrForm = {
id: null,
equipmentId: this.dataId,
name: '',
value: '',
};
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(() => {});
},
//
submitAttrForm() {
this.$refs['attrForm'].validate(async (valid) => {
if (!valid) {
return;
}
try {
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,
});
if (res.code == 0) {
this.closeAttrForm();
this.$message({
message: `${isEdit ? '更新' : '创建'}成功`,
type: 'success',
duration: 1500,
onClose: () => {
this.getAttrList();
},
});
}
this.attrFormSubmitting = false;
} catch (err) {
this.$message({
message: err,
type: 'error',
duration: 1500,
});
this.attrFormSubmitting = false;
}
});
},
closeAttrForm() {
this.attrFormVisible = false;
},
handleClick(raw) {
if (raw.type === 'delete') {
this.$confirm(
`确定对${
raw.data.name
? '[名称=' + raw.data.name + ']'
: '[序号=' + raw.data._pageIndex + ']'
}进行删除操作?`,
'提示',
{
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>

View File

@ -0,0 +1,288 @@
<!--
filename: dialogForm.vue
author: liubin
date: 2023-08-15 10:32:36
description: 弹窗的表单组件
-->
<template>
<el-form class="equipment-info-form" ref="form" :model="form" label-width="200px" label-position="top"
v-loading="formLoading">
<el-row :gutter="20">
<el-col :span="8">
<el-form-item label="设备名称" prop="name" :rules="[{ required: true, message: '设备名称不能为空', trigger: 'blur' }]">
<el-input v-model="form.name" :disabled="disabled" placeholder="请输入设备名称"></el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="设备编码" prop="code" :rules="[]">
<el-input v-model="form.code" :disabled="disabled" placeholder="请输入设备编码"></el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="英文名称" prop="enName" :rules="[]">
<el-input v-model="form.enName" :disabled="disabled" placeholder="请输入英文名称"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="8">
<el-form-item label="缩写" prop="abbr" :rules="[]">
<el-input v-model="form.abbr" :disabled="disabled" placeholder="请输入名称缩写"></el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="设备类型" prop="equipmentTypeId"
:rules="[{ required: true, message: '设备类型不能为空', trigger: 'blur' }]">
<el-select v-model="form.equipmentTypeId" :disabled="disabled" filterable placeholder="请选择设备类型">
<el-option v-for="eqType in eqTypeList" :key="eqType.id" :label="eqType.name"
:value="eqType.id"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="预计生产时间(min/天)" prop="workTime" :rules="[
{ required: true, message: '预计生产时间不能为空', trigger: 'blur' },
{
type: 'number',
message: '请输入正确的数字值',
trigger: 'blur',
transform: (val) => Number(val),
},
]">
<el-input v-model="form.workTime" :disabled="disabled" placeholder="请输入预计生产时间"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="8">
<el-form-item label="生产日期" prop="productionTime" :rules="[]">
<el-date-picker v-model="form.enterTime" :disabled="disabled" type="datetime" placeholder="请选择生产日期"
value-format="timestamp"></el-date-picker>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="进场日期" prop="enterTime" :rules="[]">
<el-date-picker v-model="form.enterTime" :disabled="disabled" type="datetime" placeholder="请选择进场日期"
value-format="timestamp"></el-date-picker>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="设备TT值" prop="tvalue" :rules="[
{ required: true, message: '设备TT值不能为空', trigger: 'blur' },
{
type: 'number',
message: '请输入正确的数字值',
trigger: 'blur',
transform: (val) => Number(val),
},
]">
<el-input v-model="form.tvalue" :disabled="disabled" placeholder="请输入设备TT值"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="8">
<el-form-item label="产品加工时间(s)" prop="processingTime" :rules="[
{ required: true, message: '产品加工时间不能为空', trigger: 'blur' },
{
type: 'number',
message: '请输入正确的数字值',
trigger: 'blur',
transform: (val) => Number(val),
},
]">
<el-input v-model="form.processingTime" :disabled="disabled" placeholder="请输入产品加工时间"></el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="制造商" prop="manufacturer" :rules="[]">
<el-input v-model="form.manufacturer" :disabled="disabled" placeholder="请输入制造商"></el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="设备规格" prop="spec" :rules="[]">
<el-input v-model="form.spec" :disabled="disabled" placeholder="请输入设备规格"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<!-- 功能描述 -->
<el-col>
<el-form-item label="功能描述" prop="description" :rules="[]">
<el-input type="textarea" :disabled="disabled" v-model="form.description"
placeholder="请填写功能描述"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<!-- 功能描述 -->
<el-col>
<el-form-item label="备注" prop="remark" :rules="[]">
<el-input v-model="form.remark" :disabled="disabled" placeholder="请输入备注"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<!-- 上传资料 -->
<el-col>
<el-form-item label="上传资料" prop="assets" :rules="[]">
<AssetsUpload v-model="form.assets" :disabled="disabled" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<!-- 上传图片 -->
<el-col>
<el-form-item label="上传图片" prop="pics" :rules="[]">
<AssetsUpload :is-pic-mode="true" v-model="form.pics" :disabled="disabled" />
</el-form-item>
</el-col>
</el-row>
</el-form>
</template>
<script>
import AssetsUpload from './AssetsUpload.vue';
export default {
name: 'EquipmentInfoForm',
model: {
prop: 'dataForm',
event: 'update',
},
emits: ['update'],
components: { AssetsUpload },
props: {
dataForm: {
type: Object,
default: () => ({}),
},
disabled: {
type: Boolean,
default: false,
},
syncFilelist: {
type: Number,
default: null,
required: false,
},
},
data() {
return {
formLoading: false,
form: {
name: '',
code: '',
enName: '',
abbr: '',
equipmentTypeId: '',
remark: '',
productionTime: '',
workTime: '',
enterTime: '',
tvalue: '',
processingTime: '',
manufacturer: '',
spec: '',
description: '',
assets: [],
pics: [],
},
eqTypeList: [],
dataLoaded: false,
};
},
watch: {
dataForm: {
handler(val) {
// debugger;
this.form = JSON.parse(JSON.stringify(val));
this.form.assets =
this.form.files?.filter((item) => item.fileType == '2') || [];
this.form.pics =
this.form.files?.filter((item) => item.fileType == '1') || [];
delete this.form.files;
},
immediate: true,
deep: true,
},
syncFilelist: {
handler(val) {
if (val != null) {
this.updateForm();
}
},
immediate: true,
},
},
mounted() {
this.getEqTypeList();
},
methods: {
updateForm() {
console.log('update form ==> ');
this.form.files = [...this.form.assets, ...this.form.pics];
delete this.form.assets;
delete this.form.pics;
this.$emit('update', this.form);
},
async getEqTypeList() {
this.formLoading = true;
const { code, data } = await this.$axios(
'/base/core-equipment-type/page?pageNo=1&pageSize=100'
);
// debugger;
if (code == 0) {
this.eqTypeList = data.list;
}
this.formLoading = false;
},
/** 模拟透传 ref */
validate(cb) {
return this.$refs.form.validate(cb);
},
resetFields(args) {
return this.$refs.form.resetFields(args);
},
// getCode
async getCode(url) {
const response = await this.$axios(url);
return response.data;
},
//
beforeUpload() { },
// bind
handleUploadSuccess(response, file, fileList) {
//
if ('fileNames' in this.form) this.form.fileNames.push(file.name);
//
if ('fileUrls' in this.form) this.form.fileUrls.push(response.data);
this.$modal.msgSuccess('上传成功');
},
getFileName(fileUrl) {
return fileUrl.split('/').pop();
},
},
};
</script>
<style scoped lang="scss">
.el-date-editor,
.el-select {
width: 100%;
}
</style>

View File

@ -0,0 +1,399 @@
<template>
<el-drawer
:visible.sync="visible"
:show-close="false"
:wrapper-closable="disabled"
class="drawer"
custom-class="mes-drawer"
size="65%"
@closed="$emit('destroy')">
<small-title slot="title" :no-padding="true">
{{
disabled ? '查看详情' : !dataForm.maintenanceStatus ? '修改' : '完成'
}}
</small-title>
<div class="drawer-body flex">
<div class="drawer-body__content">
<el-form
ref="form"
:model="dataForm"
label-width="100px"
label-position="top"
v-loading="formLoading">
<el-row :gutter="20">
<el-col :span="8">
<el-form-item label="维修单号" prop="repairOrderNumber">
<span>{{ dataForm.repairOrderNumber }}</span>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="设备大类" prop="equipmentCategory">
<span>
{{
['-', '安全设备', '消防设备', '特种设备'][
dataForm.equipmentCategory || 0
]
}}
</span>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="设备名称" prop="equipmentName">
<span>{{ dataForm.equipmentName }}</span>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="维修工" prop="repairman">
<span>{{ dataForm.repairman }}</span>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="故障发生时间" prop="faultTime">
<span>{{ parseTime(dataForm.faultTime) }}</span>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="故障级别" prop="faultLevel">
<span>
{{ getDictDataLabel('fault-level', dataForm.faultLevel) }}
</span>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="联系方式" prop="repairmanPhone">
<span>{{ dataForm.repairmanPhone }}</span>
</el-form-item>
</el-col>
</el-row>
<el-divider />
<div
v-if="
disabled && dataForm.maintenanceStatus === 1
? true
: !disabled
? true
: false
">
<small-title
style="margin: 16px 0; padding-left: 8px"
:no-padding="true">
{{ '设备维修信息' }}
</small-title>
<el-row :gutter="20">
<el-col :span="6">
<el-form-item
label="维修开始时间"
prop="maintenanceStartTime"
:rules="[
{
required: true,
message: '维修开始时间不能为空',
trigger: 'blur',
},
]">
<el-date-picker
v-model="dataForm.maintenanceStartTime"
type="datetime"
:disabled="disabled"
placeholder="请选择维修开始时间"
value-format="timestamp" />
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item
label="维修结束时间"
prop="maintenanceFinishTime"
:rules="[
{
required: true,
message: '维修结束时间不能为空',
trigger: 'blur',
},
]">
<el-date-picker
v-model="dataForm.maintenanceFinishTime"
type="datetime"
:disabled="disabled"
placeholder="请选择维修开始时间"
value-format="timestamp" />
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item
label="维修方式"
prop="repairMode"
:rules="[
{
required: true,
message: '维修方式不能为空',
trigger: 'blur',
},
]">
<el-select
:disabled="disabled"
v-model="dataForm.repairMode"
placeholder="请选择维修方式">
<el-option
v-for="opt in getDictDatas('repair-mode')"
:key="opt.value"
:label="opt.label"
:value="opt.value" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="故障类型" prop="faultType">
<el-select
:disabled="disabled"
v-model="dataForm.faultType"
placeholder="请选择故障类型">
<el-option
v-for="opt in getDictDatas('fault-type')"
:key="opt.value"
:label="opt.label"
:value="opt.value" />
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col>
<el-form-item
label="故障明细"
prop="faultDetail"
:rules="[
{
required: true,
message: '故障明细不能为空',
trigger: 'blur',
},
]">
<!-- // -->
<editor
v-model="dataForm.faultDetail"
:read-only="disabled"
:min-height="150" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col>
<el-form-item label="维修记录" prop="maintenanceDetail">
<!-- // -->
<editor
v-model="dataForm.maintenanceDetail"
:read-only="disabled"
:min-height="150" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col>
<el-form-item label="维修附件" prop="file">
<FileUpload
v-model="file"
:limit="1"
:f-name="fileName"
:disabled="disabled"
@name="setFileName" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col>
<el-form-item label="备注" prop="remark">
<el-input
v-model="dataForm.remark"
:placeholder="`请输入备注`"
:disabled="disabled" />
</el-form-item>
</el-col>
</el-row>
</div>
</el-form>
<div v-if="!disabled" class="drawer-body__footer">
<el-button style="" @click="goback()">取消</el-button>
<el-button type="primary" @click="dataFormSubmit()">确定</el-button>
</div>
</div>
</div>
</el-drawer>
</template>
<script>
import SmallTitle from './SmallTitle.vue';
import { getEqRepair, updateEqRepair } from '@/api/equipment/base/repair';
import Editor from '@/components/Editor';
import FileUpload from '@/components/FileUpload';
import { getDictDatas } from '@/utils/dict';
import { parseTime } from '@/utils/ruoyi';
import { getDictDataLabel } from '@/utils/dict';
export default {
name: 'DialogForm',
model: {
prop: 'dataForm',
event: 'update',
},
emits: ['update'],
components: { SmallTitle, Editor, FileUpload },
props: {
// dataForm: {
// type: Object,
// default: () => ({}),
// },
// disabled: {
// type: Boolean,
// default: false
// },
},
data() {
return {
formLoading: true,
visible: false,
disabled: false,
dataForm: {},
file: '',
fileName: '',
};
},
mounted() {},
methods: {
setFileName(val) {
this.fileName = val;
},
goback() {
this.$emit('refreshDataList');
this.visible = false;
},
goEdit() {
this.disabled = false;
},
/** 模拟透传 ref */
validate(cb) {
return this.$refs.form.validate(cb);
},
resetFields(args) {
return this.$refs.form.resetFields(args);
},
initData() {
this.file = '';
this.fileName = '';
},
init(row, isdetail) {
this.initData();
this.disabled = isdetail || false;
this.dataForm.id = row.id || undefined;
this.visible = true;
this.$nextTick(() => {
this.$refs['form'].resetFields();
if (this.dataForm.id) {
//
getEqRepair(this.dataForm.id).then((response) => {
this.formLoading = false;
this.dataForm = response.data;
debugger;
this.dataForm.maintenanceStatus =
this.dataForm.maintenanceStatus || 0;
if (this.dataForm.files.length > 0) {
this.file = this.dataForm.files[0].fileUrl;
this.fileName = this.dataForm.files[0].fileName;
}
});
} else {
// if (this.urlOptions.isGetCode) {
// this.getCode()
// }
}
});
},
//
dataFormSubmit() {
this.$refs['form'].validate((valid) => {
if (!valid) {
return false;
}
//
if (this.file) {
const temp = this.file.split(','); //
let arry = [];
temp.forEach((item) => {
arry.push({
fileName: this.fileName,
fileType: 2,
fileUrl: item,
});
});
this.dataForm.files = arry;
}
if (this.dataForm.id) {
updateEqRepair(this.dataForm).then((response) => {
this.$modal.msgSuccess('修改成功');
this.visible = false;
this.$emit('refreshDataList');
});
return;
}
//
// this.urlOptions.createURL(this.dataForm).then(response => {
// this.$modal.msgSuccess("");
// this.visible = false;
// this.$emit("refreshDataList");
// });
});
},
},
};
</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>

View File

@ -0,0 +1,465 @@
<!--
filename: Monitor.vue
author: liubin
date: 2023-12-12 13:54:53
description:
-->
<template>
<div class="app-container SpecialEquipmentMaintainMonitor">
<!-- 搜索工作栏 -->
<SearchBar
:formConfigs="searchBarFormConfig"
ref="search-bar"
@select-changed="handleSearchBarChange"
@headBtnClick="handleSearchBarBtnClick" />
<!-- 列表 -->
<base-table
:table-props="tableProps"
:page="queryParams.pageNo"
:limit="queryParams.pageSize"
:table-data="list"
@emitFun="handleEmitFun">
<!-- <method-btn
v-if="tableBtn.length"
slot="handleBtn"
label="操作"
:width="120"
:method-list="tableBtn"
@clickBtn="handleTableBtnClick" /> -->
</base-table>
<!-- 分页组件 -->
<pagination
v-show="total > 0"
:total="total"
:page.sync="queryParams.pageNo"
:limit.sync="queryParams.pageSize"
@pagination="getList" />
<!-- 对话框(添加 / 修改) -->
<base-dialog
:dialogTitle="title"
:dialogVisible="open"
@close="cancel"
@cancel="cancel"
@confirm="submitForm">
<DialogForm
v-if="open"
ref="form"
v-model="form"
:has-files="false"
:rows="rows" />
</base-dialog>
</div>
</template>
<script>
import { publicFormatter } from '@/utils/dict';
// import moment from 'moment';
import basicPageMixin from '@/mixins/lb/basicPageMixin';
import { exportMaintainMonitorExcel } from '@/api/equipment/base/maintain/record';
import { parseTime } from '@/utils/ruoyi';
const remainBox = {
name: 'RemainBox',
props: ['injectData'],
data() {
return {};
},
computed: {
value() {
return this.injectData[this.injectData.prop] || null;
},
color() {
if (this.value) {
const v = +this.value;
return v < 0 ? '#FF5454' : v >= 0 && v < 2 ? '#FFD767' : '#37D97F';
}
return 'unset';
},
},
render: function (h) {
return (
<div
style={`background: ${
this.color
}; position:absolute; inset: 0; padding: 0 10px; display: flex; align-items: center; color: ${
// this.color == 'red' ? '#fff' : 'unset'
'#fff'
}`}>
{this.injectData[this.injectData.prop]?.toFixed(0) || ''}
</div>
);
},
};
const btn = {
name: 'tableBtn',
props: ['injectData'],
data() {
return {};
},
methods: {
handleClick() {
this.$emit('emitData', {
action: this.injectData.label,
value: this.injectData,
});
},
},
render: function (h) {
return (
<el-button type="text" onClick={this.handleClick}>
{this.injectData.name}
</el-button>
);
},
};
export default {
name: 'SpecialEquipmentMaintainMonitor',
components: {},
mixins: [basicPageMixin],
data() {
return {
searchBarKeys: ['planId', 'specialType', 'equipmentId'],
tableProps: [
// {
// prop: 'createTime',
// label: '',
// fixed: true,
// width: 180,
// filter: parseTime(createTime),
// },
{
prop: 'name',
label: '保养计划',
minWidth: 100,
showOverflowtooltip: true,
},
{
prop: 'lineName',
label: '产线名',
minWidth: 100,
showOverflowtooltip: true,
},
{
prop: 'equipmentCategory',
label: '设备大类',
minWidth: 100,
showOverflowtooltip: true,
filter: (val) =>
val != null ? ['-', '安全设备', '消防设备', '特种设备'][val] : '-',
},
{
prop: 'equipmentName',
label: '设备名称',
minWidth: 100,
showOverflowtooltip: true,
},
{ prop: 'maintenancePeriod', label: '保养频率' },
{
prop: 'maintainType',
label: '保养类型',
showOverflowtooltip: true,
filter: publicFormatter(this.DICT_TYPE.MAINTAIN_TYPE),
},
{
prop: 'lastMaintainTime',
label: '上次保养时间',
filter: parseTime,
minWidth: 150,
showOverflowtooltip: true,
},
{
prop: 'nextMaintainTime',
label: '计划下次保养时间',
filter: parseTime,
minWidth: 150,
showOverflowtooltip: true,
},
{
prop: 'remainDays',
label: '距离保养时间(天)',
subcomponent: remainBox,
minWidth: 150,
// showOverflowtooltip: true
},
{
prop: 'opt1',
label: '设备保养',
name: '操作',
subcomponent: btn,
width: 100,
},
{
prop: 'opt2',
label: '保养记录',
name: '查看详情',
subcomponent: btn,
width: 100,
},
],
searchBarFormConfig: [
{
type: 'select',
label: '保养计划',
placeholder: '请选择保养计划',
param: 'planId',
filterable: true,
},
{
type: 'select',
label: '设备大类',
placeholder: '请选择设备大类',
param: 'specialType',
onchange: true,
selectOptions: [
{ id: 1, name: '安全设备' },
{ id: 2, name: '消防设备' },
{ id: 3, name: '特种设备' },
],
filterable: true,
},
{
type: 'select',
label: '设备名',
placeholder: '请选择设备',
param: 'equipmentId',
filterable: true,
},
{
type: 'button',
btnName: '查询',
name: 'search',
color: 'primary',
},
{
type: 'separate',
},
{
type: this.$auth.hasPermi('base:quality-inspection-type:export')
? 'button'
: '',
btnName: '导出',
name: 'export',
plain: true,
color: 'primary',
},
],
//
open: false,
//
queryParams: {
pageNo: 1,
pageSize: 10,
equipmentName: null,
createTime: null,
special: true,
specialType: null,
},
//
form: {},
allSpecialEquipments: [],
};
},
created() {
this.initSearchBar();
this.getList();
},
methods: {
/** 导出按钮操作 */
handleExport() {
//
let params = { ...this.queryParams };
params.pageNo = undefined;
params.pageSize = undefined;
this.$modal
.confirm('是否确认导出所有设备保养监控数据项?')
.then(() => {
this.exportLoading = true;
return exportMaintainMonitorExcel(params);
})
.then((response) => {
this.$download.excel(response, '设备保养监控.xls');
this.exportLoading = false;
})
.catch(() => {});
},
handleSearchBarChange({ param, value }) {
if ('specialType' === param) {
if (!value) {
this.setSearchBarEquipmentList(this.allSpecialEquipments);
return;
}
this.setSearchBarEquipmentList(
this.allSpecialEquipments.filter((item) => item.specialType == value)
);
}
},
setSearchBarEquipmentList(eqList) {
this.$set(
this.searchBarFormConfig[2],
'selectOptions',
eqList.map((item) => ({
name: item.name,
id: item.id,
}))
);
},
initSearchBar() {
this.$watch('current', {});
this.http('/base/core-equipment/listAll', 'get').then(({ data }) => {
this.allSpecialEquipments = data.filter((item) => item.special);
this.setSearchBarEquipmentList(data.filter((item) => item.special));
});
this.http('/base/equipment-maintain-plan/page', 'get', {
pageNo: 1,
pageSize: 100,
special: true,
}).then(({ data }) => {
this.$set(
this.searchBarFormConfig[0],
'selectOptions',
(data?.list || []).map((item) => ({
name: item.name,
id: item.id,
}))
);
});
},
handleEmitFun({ action, value }) {
switch (action) {
//
case '设备保养':
this.$router.push({
path: '/equipment/base/maintain/record',
query: {
addRecord: 1,
row: value,
},
});
break;
case '保养记录':
const queryData = {
equipmentId: value.equipmentId,
maintainPlanId: value.id,
relatePlan: value.lastMaintainTime ? 1 : 2,
};
this.$router.push({
path: '/equipment/base/maintain/record',
query: queryData,
});
break;
}
},
/** 查询列表 */
getList() {
this.loading = true;
//
this.http(
'/base/equipment-maintain-plan/monitor',
'get',
this.queryParams
).then((response) => {
this.list = response.data.list;
this.total = response.data.total;
this.loading = false;
});
},
/** 取消按钮 */
cancel() {
this.open = false;
this.reset();
},
/** 表单重置 */
reset() {
this.form = {
code: null,
name: null,
equipmentId: null,
enabled: null,
maintenancePeriod: null,
maintainDuration: null,
maintainType: null,
remark: null,
enabled: 1,
};
this.resetForm('form');
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNo = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm('queryForm');
this.handleQuery();
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.open = true;
this.title = '添加保养计划';
},
handleDetail(id) {
alert('跳转到 保养记录');
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
const id = row.id;
this.info({ id }).then((response) => {
this.form = response.data;
this.open = true;
this.title = '修改保养计划';
});
},
/** 提交按钮 */
submitForm() {
this.$refs['form'].validate((valid) => {
if (!valid) {
return;
}
//
if (this.form.id != null) {
this.put(this.form).then((response) => {
this.$modal.msgSuccess('修改成功');
this.open = false;
this.getList();
});
return;
}
//
this.post(this.form).then((response) => {
this.$modal.msgSuccess('新增成功');
this.open = false;
this.getList();
});
});
},
/** 删除按钮操作 */
handleDelete(row) {
const id = row.id;
this.$modal
.confirm('是否确认删除设备类型"' + row.name + '"?')
.then(function () {
return this.del(id);
})
.then(() => {
this.getList();
this.$modal.msgSuccess('删除成功');
})
.catch(() => {});
},
},
};
</script>
<style scoped lang="scss">
.SpecialEquipmentMaintainMonitor {
}
</style>

View File

@ -0,0 +1,281 @@
<!--
filename: dialogForm.vue
author: liubin
date: 2023-08-15 10:32:36
description: 弹窗的表单组件
-->
<template>
<el-form
ref="form"
:model="form"
:size="size"
:label-position="labelPosition"
v-loading="formLoading">
<el-row :gutter="20">
<el-col :span="12">
<el-form-item
label="计划名称"
prop="name"
:rules="[
{ required: true, message: '请输入计划名称', trigger: 'blur' },
]">
<el-input
v-model="form.name"
@change="$emit('update', form)"
:placeholder="`请输入计划名称`"
:disabled="disabled" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item
label="计划编号"
prop="code"
:rules="[
{ required: true, message: '请输入计划编号', trigger: 'blur' },
]">
<el-input
v-model="form.code"
@change="$emit('update', form)"
:placeholder="`请输入计划编号`"
:disabled="disabled" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item
label="设备大类"
prop="equipmentCategory"
:rules="[
{ required: true, message: '请选择设备大类', trigger: 'blur' },
]">
<el-select
v-model="form.equipmentCategory"
:placeholder="`请选择设备大类`"
:disabled="disabled"
@change="handleEqTypeChange">
<el-option
v-for="opt in equipmentTypeOptions"
:key="opt.value"
:label="opt.label"
:value="opt.value" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item
label="设备"
prop="equipmentId"
:rules="[{ required: true, message: '请选择设备', trigger: 'blur' }]">
<el-select
v-model="form.equipmentId"
:placeholder="`请选择设备`"
:disabled="disabled"
@change="$emit('update', form)">
<el-option
v-for="opt in equipmentOptions"
:key="opt.value"
:label="opt.label"
:value="opt.value" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="保养类型" prop="maintainType">
<el-select
v-model="form.maintainType"
:placeholder="`请选择保养类型`"
:disabled="disabled"
@change="$emit('update', form)">
<el-option
v-for="opt in getDictDatas(DICT_TYPE.MAINTAIN_TYPE)"
:key="opt.value"
:label="opt.label"
:value="+opt.value" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item
label="保养时长(h)"
prop="maintainDuration"
:rules="[
{
type: 'number',
message: '请输入正确的数字',
trigger: 'blur',
transform: (val) => Number(val),
},
]">
<el-input
v-model="form.maintainDuration"
@change="$emit('update', form)"
:placeholder="`请输入保养时长`"
:disabled="disabled" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item
label="保养频率(天/次)"
prop="maintenancePeriod"
:rules="[
{
type: 'number',
message: '请输入正确的数字',
trigger: 'blur',
transform: (val) => Number(val),
},
{ required: true, message: '保养频率不能为空', trigger: 'blur' },
]">
<el-input
v-model="form.maintenancePeriod"
@change="$emit('update', form)"
:placeholder="`请输入保养频率`"
:disabled="disabled" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="备注" prop="remark">
<el-input
v-model="form.remark"
@change="$emit('update', form)"
:placeholder="`请输入备注`"
:disabled="disabled" />
</el-form-item>
</el-col>
</el-row>
</el-form>
</template>
<script>
export default {
name: 'DialogForm',
model: {
prop: 'dataForm',
event: 'update',
},
emits: ['update'],
components: {},
props: {
rows: {
type: Array,
default: () => [],
},
dataForm: {
type: Object,
default: () => ({}),
},
disabled: {
type: Boolean,
default: false,
},
hasFiles: {
type: Boolean | Array,
default: false,
},
labelPosition: {
type: String,
default: 'right',
},
size: {
type: String,
default: '',
},
},
data() {
return {
form: {},
formLoading: true,
dataLoaded: false,
equipmentList: [],
equipmentOptions: [],
equipmentTypeOptions: [
{ label: '安全设备', value: 1 },
{ label: '消防设备', value: 2 },
{ label: '特种设备', value: 3 },
],
};
},
watch: {
dataForm: {
handler(val) {
this.form = JSON.parse(JSON.stringify(val));
if (this.form.equipmentCategory != null) {
setTimeout(() => {
this.equipmentOptions = this.equipmentList
.filter((item) => item.special)
.filter(
(item) => item.specialType === this.form.equipmentCategory
)
.map((item) => ({ label: item.name, value: item.id }));
}, 1000);
}
if (this.hasFiles) {
if (typeof this.hasFiles == 'boolean' && this.hasFiles) {
this.form.files = this.form.files ?? [];
} else if (Array.isArray(this.hasFiles)) {
this.hasFiles.forEach((prop) => {
this.form[prop] = this.form[prop] ?? [];
});
}
}
},
deep: true,
immediate: true,
},
},
mounted() {
this.getEquipmentList();
this.getCode('/base/equipment-maintain-plan/getCode');
},
methods: {
/** 模拟透传 ref */
validate(cb) {
return this.$refs.form.validate(cb);
},
resetFields(args) {
return this.$refs.form.resetFields(args);
},
// getCode
async getCode(url) {
this.formLoading = true;
const response = await this.$axios(url);
this.formLoading = false;
this.form.code = response.data || '';
},
// initialize
async getEquipmentList() {
this.formLoading = true;
const response = await this.$axios('/base/core-equipment/listAll');
this.equipmentList = response.data || [];
this.equipmentOptions = (response.data || []).map((item) => ({
label: item.name,
value: item.id,
}));
this.formLoading = false;
},
// handlers
handleEqTypeChange(type) {
this.form.equipmentId = null;
if (type) {
this.equipmentOptions = this.equipmentList
.filter((item) => item.special)
.filter((item) => item.specialType === type)
.map((item) => ({ label: item.name, value: item.id }));
} else
this.equipmentOptions = this.equipmentList.map((item) => ({
label: item.name,
value: item.id,
}));
// this.$emit('update', this.form)
},
},
};
</script>
<style scoped lang="scss">
.el-date-editor,
.el-select {
width: 100%;
}
</style>

View File

@ -0,0 +1,416 @@
<!--
filename: PlanConfig.vue
author: liubin
date: 2023-12-12 13:54:53
description:
-->
<template>
<div class="app-container SpecialEquipmentPlanConfig">
<!-- 搜索工作栏 -->
<SearchBar
:formConfigs="searchBarFormConfig"
ref="search-bar"
@headBtnClick="handleSearchBarBtnClick" />
<!-- 列表 -->
<base-table
:table-props="tableProps"
:page="queryParams.pageNo"
:limit="queryParams.pageSize"
:table-data="list"
@emitFun="handleEmitFun">
<method-btn
v-if="tableBtn.length"
slot="handleBtn"
label="操作"
:width="120"
:method-list="tableBtn"
@clickBtn="handleTableBtnClick" />
</base-table>
<!-- 分页组件 -->
<pagination
v-show="total > 0"
:total="total"
:page.sync="queryParams.pageNo"
:limit.sync="queryParams.pageSize"
@pagination="getList" />
<!-- 对话框(添加 / 修改) -->
<base-dialog
:dialogTitle="title"
:dialogVisible="open"
@close="cancel"
@cancel="cancel"
@confirm="submitForm">
<DialogForm v-if="open" ref="form" v-model="form" :has-files="false" />
</base-dialog>
</div>
</template>
<script>
import moment from 'moment';
import basicPageMixin from '@/mixins/lb/basicPageMixin';
import { deleteEqMaintainPlan } from '@/api/equipment/base/maintain/record';
import { publicFormatter } from '@/utils/dict';
import PlanConfigAdd from './PlanConfig--add.vue';
export default {
name: 'SpecialEquipmentPlanConfig',
components: { DialogForm: PlanConfigAdd },
mixins: [basicPageMixin],
data() {
const t = new Date();
const [y, m, d] = [t.getFullYear(), t.getMonth(), t.getDate()];
return {
searchBarKeys: ['equipmentName', 'specialType', 'createTime'],
tableBtn: [
{
type: 'detail',
btnName: '保养记录',
},
this.$auth.hasPermi('equipment:plan-config:update')
? {
type: 'edit',
btnName: '修改',
}
: undefined,
this.$auth.hasPermi('equipment:plan-config:delete')
? {
type: 'delete',
btnName: '删除',
}
: undefined,
].filter((v) => v),
tableProps: [
// {
// prop: 'createTime',
// label: '',
// fixed: true,
// width: 180,
// filter: (val) => moment(val).format('yyyy-MM-DD HH:mm:ss'),
// },
{ prop: 'name', label: '计划名称' },
{ prop: 'code', label: '计划编号' },
{
prop: 'enabled',
label: '启用状态',
filter: (val) => ['停用', '启用'][val],
},
{ prop: 'lineName', label: '产线' },
{
prop: 'equipmentCategory',
label: '设备大类',
filter: (val) =>
val != null ? ['-', '安全', '消防', '特种'][val] : '-',
},
{ prop: 'equipmentName', label: '设备名称' },
{ width: 144, prop: 'maintainDuration', label: '计划保养用时(h)' },
{ width: 144, prop: 'maintenancePeriod', label: '保养频率(天/次)' },
{
prop: 'maintainType',
label: '保养类型',
filter: publicFormatter('maintain_type'),
},
{ prop: 'remark', label: '备注' },
],
searchBarFormConfig: [
{
type: 'select',
label: '设备大类',
selectOptions: [
{ id: 1, name: '安全设备' },
{ id: 2, name: '消防设备' },
{ id: 3, name: '特种设备' },
],
placeholder: '请选择设备大类',
param: 'specialType',
},
{
type: 'input',
label: '设备名',
placeholder: '请输入设备名称',
param: 'equipmentName',
},
{
type: 'datePicker',
label: '时间段',
dateType: 'daterange',
format: 'yyyy-MM-dd',
valueFormat: 'yyyy-MM-dd HH:mm:ss',
rangeSeparator: '-',
startPlaceholder: '开始时间',
endPlaceholder: '结束时间',
param: 'createTime',
},
{
type: 'button',
btnName: '查询',
name: 'search',
color: 'primary',
},
{
type: 'separate',
},
{
type: this.$auth.hasPermi('equipment:plan-config:create')
? 'button'
: '',
btnName: '新增',
name: 'add',
plain: true,
color: 'success',
},
// {
// type: this.$auth.hasPermi('base:quality-inspection-type:export')
// ? 'button'
// : '',
// btnName: '',
// name: 'export',
// color: 'warning',
// },
],
rows: [
[
{
input: true,
label: '计划名称',
prop: 'name',
rules: [
{ required: true, message: '计划名称不能为空', trigger: 'blur' },
],
},
{
input: true,
label: '计划编号',
prop: 'code',
url: '/base/equipment-maintain-plan/getCode',
rules: [
{ required: true, message: '计划编号不能为空', trigger: 'blur' },
],
},
],
[
{
select: true,
label: '设备大类',
prop: 'equipmentCategory',
options: [
{ value: 1, label: '安全设备' },
{ value: 2, label: '消防设备' },
{ value: 3, label: '特种设备' },
],
rules: [
{ required: true, message: '设备名称不能为空', trigger: 'blur' },
],
},
{
select: true,
label: '设备名称',
prop: 'equipmentId',
url: '/base/core-equipment/listAll',
rules: [
{ required: true, message: '设备名称不能为空', trigger: 'blur' },
],
},
{
select: true,
label: '保养类型',
prop: 'maintainType',
options: this.getDictDatas(this.DICT_TYPE.MAINTAIN_TYPE),
},
],
[
{
input: true,
label: '保养时长(h)',
prop: 'maintainDuration',
rules: [
{
type: 'number',
trigger: 'blur',
message: '请输入正确的数字',
transform: (val) => Number(val),
},
],
},
{
input: true,
label: '保养频率(天/次)',
prop: 'maintenancePeriod',
rules: [
{
type: 'number',
trigger: 'blur',
message: '请输入正确的数字',
transform: (val) => Number(val),
},
],
rules: [
{ required: true, message: '保养频率不能为空', trigger: 'blur' },
],
},
],
[
{
switch: true,
label: '启用状态',
prop: 'enabled',
bind: {
'active-value': 1,
'inactive-value': 0,
},
},
],
[{ input: true, label: '备注', prop: 'remark' }],
],
//
open: false,
//
queryParams: {
pageNo: 1,
pageSize: 10,
equipmentName: null,
createTime: null,
specialType: null,
},
//
form: {},
basePath: '/base/equipment-maintain-plan',
};
},
created() {
if (this.$route.query) {
this.queryParams.equipmentId =
this.$route.query?.equipmentId ?? undefined;
this.searchBarFormConfig[0].defaultSelect =
this.$route.query.equipmentName ?? undefined;
}
this.getList();
},
methods: {
/** 查询列表 */
getList() {
this.loading = true;
//
this.recv({
...this.queryParams,
special: true,
}).then((response) => {
this.list = response.data.list;
this.total = response.data.total;
this.loading = false;
});
},
/** 取消按钮 */
cancel() {
this.open = false;
this.reset();
},
/** 表单重置 */
reset() {
this.form = {
code: null,
name: null,
equipmentId: null,
enabled: null,
maintenancePeriod: null,
maintainDuration: null,
maintainType: null,
remark: null,
enabled: 1,
equipmentCategory: null,
};
this.resetForm('form');
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNo = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm('queryForm');
this.handleQuery();
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.open = true;
this.title = '添加保养计划';
},
handleDetail(row) {
// alert(' ')
// console.log(row)
const queryData = {
equipmentId: row.equipmentId,
maintainPlanId: row.id,
isAdd: 1,
// relatePlan: row.enabled
};
if (this.queryParams.createTime) {
queryData.createTime = this.queryParams.createTime;
}
this.$router.push({
path: '/safety-environmental/special-equipment/equipment-maintain/maintain-record',
query: queryData,
});
// this.$router.push({ path: '/equipment/base/maintain/record', query: { orderNo: row.orderNo }})
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
const id = row.id;
this.info({ id }).then((response) => {
this.form = response.data;
debugger;
this.open = true;
this.title = '修改保养计划';
});
},
/** 提交按钮 */
submitForm() {
this.$refs['form'].validate((valid) => {
if (!valid) {
return;
}
//
if (this.form.id != null) {
this.put(this.form).then((response) => {
this.$modal.msgSuccess('修改成功');
this.open = false;
this.getList();
});
return;
}
//
this.post(this.form).then((response) => {
this.$modal.msgSuccess('新增成功');
this.open = false;
this.getList();
});
});
},
/** 删除按钮操作 */
handleDelete(row) {
const id = row.id;
this.$modal
.confirm('是否确认删除计划名称为"' + row.name + '"的数据项?')
.then(function () {
return deleteEqMaintainPlan(id);
})
.then(() => {
this.getList();
this.$modal.msgSuccess('删除成功');
})
.catch(() => {});
},
},
};
</script>
<style scoped lang="scss">
.SpecialEquipmentPlanConfig {
}
</style>

Some files were not shown because too many files have changed in this diff Show More