Compare commits

...

13 Commits

81 changed files with 9794 additions and 6389 deletions

View File

@ -1,8 +1,8 @@
###
# @Author: Do not edit
# @Date: 2023-08-29 09:40:39
# @LastEditTime: 2024-09-02 09:07:05
# @LastEditors: zhp
# @LastEditTime: 2024-11-07 09:29:23
# @LastEditors: zwq
# @Description:
###
# 开发环境配置
@ -12,17 +12,8 @@ ENV = 'development'
VUE_APP_TITLE = MES系统
# 芋道管理系统/开发环境
# 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.4.173:48080'
# VUE_APP_BASE_API = 'http://192.168.2.173:48080'
# VUE_APP_BASE_API = 'http://192.168.1.81: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.1.56:48082'
# VUE_APP_BASE_API = 'http://192.168.4.159:48080'
# VUE_APP_BASE_API = 'http://192.168.1.64:48082'
VUE_APP_BASE_API = 'http://192.168.1.20:48082'
# VUE_APP_BASE_API = 'http://172.16.21.222:48082'
VUE_APP_BASE_API = 'http://mes2.kszny.picaiba.com'

View File

@ -1,8 +1,8 @@
###
# @Author: zhp
# @Date: 2023-11-07 19:11:40
# @LastEditTime: 2023-11-16 16:40:59
# @LastEditors: zhp
# @LastEditTime: 2024-10-17 09:09:05
# @LastEditors: zwq
# @Description:
###
# 生产环境配置
@ -12,15 +12,18 @@ ENV = 'production'
VUE_APP_TITLE = MES系统
# 芋道管理系统/生产环境
VUE_APP_BASE_API = '/prod-api'
# VUE_APP_BASE_API = '/prod-api'
VUE_APP_BASE_API = ''
# 积木报表指向地址
VUE_APP_JIMU_API = 'http://192.168.0.33:48082'
# VUE_APP_JIMU_API = 'http://192.168.0.33:48082'
VUE_APP_JIMU_API = ''
# 根据服务器或域名修改
# PUBLIC_PATH = 'http://my-pi.com:8888/yudao-admin/'
PUBLIC_PATH = 'http://192.168.0.33:8889/'
# PUBLIC_PATH = 'http://192.168.0.33:8889/'
PUBLIC_PATH = ''
# 二级部署路径
VUE_APP_APP_NAME ='yudao-admin'

View File

@ -6,7 +6,7 @@
"license": "MIT",
"scripts": {
"local": "vue-cli-service serve --mode local",
"dev": "vue-cli-service serve --mode dev",
"dev": "set NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service serve --mode dev",
"front": "vue-cli-service serve --mode front",
"build:prod": "vue-cli-service build --mode prod",
"build:stage": "vue-cli-service build --mode stage",

View File

@ -1,3 +1,10 @@
/*
* @Author: zwq
* @Date: 2024-06-28 17:03:29
* @LastEditors: zwq
* @LastEditTime: 2024-09-27 09:24:09
* @Description:
*/
import request from '@/utils/request'
// 获取走势分析数据
@ -8,7 +15,24 @@ export function getEnergyTrend(data) {
data: data
})
}
// 导出走势分析数据
export function exportTrend(data) {
return request({
url: '/analysis/energy-analysis/exportTrend',
method: 'post',
data: data,
responseType: 'blob'
})
}
// 导出对比分析数据
export function exportCompare(data) {
return request({
url: '/analysis/energy-analysis/exportCompare',
method: 'post',
data: data,
responseType: 'blob'
})
}
// 获取对比分析数据
export function getCompare(data) {
return request({
@ -27,6 +51,24 @@ export function getYoy(data) {
})
}
// 导出同比分析数据
export function exportYoy(data) {
return request({
url: '/analysis/energy-analysis/exportYoy',
method: 'post',
data: data,
responseType: 'blob'
})
}
// 导出环比分析数据
export function exportChain(data) {
return request({
url: '/analysis/energy-analysis/exportChain',
method: 'post',
data: data,
responseType: 'blob'
})
}
// 获取环比分析数据(1:月,2:周,3:日)
export function getQoq(data) {
return request({
@ -34,4 +76,4 @@ export function getQoq(data) {
method: 'post',
data: data
})
}
}

View File

@ -3,7 +3,7 @@
* @Date: 2023-10-21 11:50:46
* @LastEditTime: 2023-10-30 14:37:28
* @LastEditors: DY
* @Description:
* @Description:
*/
import request from '@/utils/request'
@ -65,4 +65,11 @@ export function getCoreDepartmentList(query) {
method: 'get',
params: query
})
}
}
export function getDepartmentList(query) {
return request({
url: '/system/dept/list',
method: 'get',
params: query
})
}

View File

@ -3,7 +3,7 @@
* @Date: 2023-10-21 11:50:46
* @LastEditTime: 2023-11-15 17:19:19
* @LastEditors: DY
* @Description:
* @Description:
*/
import request from '@/utils/request'
@ -16,6 +16,14 @@ export function createCoreWO(data) {
})
}
// 获取工艺模式工单预计消耗物料
export function getMaterialCostWorkOrder(data) {
return request({
url: '/extend/process-retrospect/getMaterialCostWorkOrder',
method: 'post',
data: data
})
}
// 更新工单
export function updateCoreWO(data) {
return request({

View File

@ -50,6 +50,22 @@ export function getOrderById(query) {
params: query
})
}
// 订单进度-获取普通模式订单剩余数量
export function getOrderRemainNum(id) {
return request({
url: '/base/order/getOrderRemainNum?id=' + id,
method: 'get'
})
}
// 订单进度-获取工艺模式订单预计消耗物料(计算后)
export function getMaterialCostOrder(data) {
return request({
url: '/extend/process-retrospect/getMaterialCostOrder',
method: 'post',
data: data
})
}
// 获得工艺流程列表
export function getProcessFlowList() {
@ -59,6 +75,16 @@ export function getProcessFlowList() {
})
}
// 获得工艺流程列表
export function getProcessFlowPage(query) {
return request({
url: '/extend/process-flow/page',
method: 'get',
params: query
})
}
// 创建订单
export function orderCreate(data) {
return request({
@ -181,11 +207,11 @@ export function getDetailTree(data) {
params: data
})
}
export function getDetailTreeInfo(data) {
export function getDetailTreeInfo(query) {
return request({
url: 'base/order/getDetailTreeInfoById',
url: 'base/order/getDetailTreeInfoByIdNew',
method: 'get',
params: data
params: query
})
}

View File

@ -5,13 +5,6 @@
* @LastEditors: zhp
* @Description:
*/
/*
* @Author: zhp
* @Date: 2024-07-12 15:31:41
* @LastEditTime: 2024-07-22 09:33:20
* @LastEditors: zhp
* @Description:
*/
import request from '@/utils/request'
@ -26,7 +19,7 @@ export function getItemPageData(data) {
return request({
url: '/base/equipment-check-program/page',
method: 'get',
data
params: data
})
}

54
src/api/home.js Normal file
View File

@ -0,0 +1,54 @@
/*
* @Author: zwq
* @Date: 2024-09-12 13:38:33
* @LastEditors: zwq
* @LastEditTime: 2024-09-13 15:25:07
* @Description:
*/
import request from '@/utils/request'
// 获得首页生产总览以及工单监控
export function getHomeOrder(data) {
return request({
url: '/base/core-work-order/homeOrder',
method: 'post',
data: data
})
}
// 获得首页生产总览-完成订单数量
export function getHomeOrderNum(data) {
return request({
url: '/base/order/homeOrder',
method: 'post',
data: data
})
}
// 首页设备总览
export function getHomeEquipment() {
return request({
url: '/monitoring/equipment-monitor/homeEquipment',
method: 'get'
})
}
// 首页设备报警信息
export function getHomeEquipmentAlarmList() {
return request({
url: '/base/equipment-alarm-realtime/homeEquipmentAlarmList',
method: 'get'
})
}
// 获取是否存在报警(右上角红点)
export function getHomeGetAlarm() {
return request({
url: '/base/core-alarm-log/homeGetAlarm',
method: 'get'
})
}
// 条件查询获得异常警告列表
export function getHomeAlarmList(query) {
return request({
url: '/base/core-alarm-log/listbyfilter',
method: 'get',
params: query
})
}

View File

@ -0,0 +1,15 @@
<?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(-1713.000000, -32.000000)">
<g id="icon/banner/消息" transform="translate(1713.000000, 32.000000)">
<g id="编组">
<rect id="矩形" x="0" y="0" width="24" height="24"></rect>
<path d="M13.875,20.6585751 L13.9796526,20.6647179 C14.3523487,20.7094224 14.6,20.9943408 14.6,21.3949387 C14.6,21.793137 14.3546839,22.079785 13.9805499,22.1250542 L13.8720425,22.1313899 L10.125,22.1313023 L10.0203474,22.1251595 C9.64765132,22.080455 9.4,21.7955365 9.4,21.3949387 C9.4,20.9967404 9.64531608,20.7100924 10.0194501,20.6648232 L10.1279575,20.6584875 L13.875,20.6585751 Z M12,0.930991914 L12.114202,0.938656892 C12.4461465,0.982430206 12.6786924,1.21840343 12.7188472,1.56053658 L12.7250824,1.6705356 L12.724,2.83025932 L12.975759,2.90430031 L13.2244725,2.9413468 C16.687784,3.51732717 19.3536312,6.48703662 19.5838508,10.0724929 L19.5959741,10.3244915 L19.6000064,10.5775585 L19.6,18.0623023 L20.7499628,18.1131205 L20.8641749,18.1204751 C21.1961465,18.1642484 21.4286924,18.4002216 21.4688472,18.7423548 L21.4750824,18.8523538 L21.4678171,18.9675593 C21.4246486,19.3025982 21.1922705,19.5388574 20.8555499,19.5795997 L20.7470425,19.5859353 L3.25,19.5859353 L3.14534744,19.5797049 C2.77265132,19.5350005 2.525,19.250082 2.525,18.8494841 C2.525,18.4512975 2.77030543,18.1646386 3.1443756,18.1193685 L3.25285992,18.113033 L4.35003719,18.1123023 L4.4,10.5767569 L4.40403631,10.3246942 C4.524824,6.55675169 7.34298069,3.38911146 11.0266305,2.90405757 L11.229889,2.87995432 L11.275,1.66770897 L11.2823355,1.55103724 C11.3211556,1.24947788 11.5116242,1.02739927 11.7956288,0.955808301 L11.897531,0.937079811 L12,0.930991914 Z M12,4.31312051 C8.70150639,4.31312051 5.97362451,6.99932148 5.85407645,10.3480678 L5.85000794,10.5758657 L5.849,18.0622956 L18.099,18.1123023 L18.15,10.5767635 L18.1459233,10.3480647 C18.0266869,7.00812062 15.3071214,4.31312051 12,4.31312051 Z" id="形状结合" fill="#FFFFFF" fill-rule="nonzero"></path>
</g>
<circle id="Oval-1-Copy-2" fill="#F5222D" cx="18" cy="6" r="3"></circle>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

@ -8,8 +8,7 @@
<rect id="矩形" x="0" y="0" width="24" height="24"></rect>
<path d="M13.875,20.6585751 L13.9796526,20.6647179 C14.3523487,20.7094224 14.6,20.9943408 14.6,21.3949387 C14.6,21.793137 14.3546839,22.079785 13.9805499,22.1250542 L13.8720425,22.1313899 L10.125,22.1313023 L10.0203474,22.1251595 C9.64765132,22.080455 9.4,21.7955365 9.4,21.3949387 C9.4,20.9967404 9.64531608,20.7100924 10.0194501,20.6648232 L10.1279575,20.6584875 L13.875,20.6585751 Z M12,0.930991914 L12.114202,0.938656892 C12.4461465,0.982430206 12.6786924,1.21840343 12.7188472,1.56053658 L12.7250824,1.6705356 L12.724,2.83025932 L12.975759,2.90430031 L13.2244725,2.9413468 C16.687784,3.51732717 19.3536312,6.48703662 19.5838508,10.0724929 L19.5959741,10.3244915 L19.6000064,10.5775585 L19.6,18.0623023 L20.7499628,18.1131205 L20.8641749,18.1204751 C21.1961465,18.1642484 21.4286924,18.4002216 21.4688472,18.7423548 L21.4750824,18.8523538 L21.4678171,18.9675593 C21.4246486,19.3025982 21.1922705,19.5388574 20.8555499,19.5795997 L20.7470425,19.5859353 L3.25,19.5859353 L3.14534744,19.5797049 C2.77265132,19.5350005 2.525,19.250082 2.525,18.8494841 C2.525,18.4512975 2.77030543,18.1646386 3.1443756,18.1193685 L3.25285992,18.113033 L4.35003719,18.1123023 L4.4,10.5767569 L4.40403631,10.3246942 C4.524824,6.55675169 7.34298069,3.38911146 11.0266305,2.90405757 L11.229889,2.87995432 L11.275,1.66770897 L11.2823355,1.55103724 C11.3211556,1.24947788 11.5116242,1.02739927 11.7956288,0.955808301 L11.897531,0.937079811 L12,0.930991914 Z M12,4.31312051 C8.70150639,4.31312051 5.97362451,6.99932148 5.85407645,10.3480678 L5.85000794,10.5758657 L5.849,18.0622956 L18.099,18.1123023 L18.15,10.5767635 L18.1459233,10.3480647 C18.0266869,7.00812062 15.3071214,4.31312051 12,4.31312051 Z" id="形状结合" fill="#FFFFFF" fill-rule="nonzero"></path>
</g>
<circle id="Oval-1-Copy-2" fill="#F5222D" cx="18" cy="6" r="3"></circle>
</g>
</g>
</g>
</svg>
</svg>

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@ -0,0 +1,132 @@
<!--
filename: index.vue
author: liubin
date: 2024-04-02 09:49:36
description:
-->
<template>
<!-- 按钮切换 -->
<div v-if="buttonMode" class="button-nav">
<button
v-for="m in menus"
:key="m"
@click="currentMenu = m"
:data-text="m"
:class="[m === currentMenu ? 'active' : '']"
></button>
</div>
<!-- 标签切换 -->
<div v-else class="custom-tabs" style="height: 100%; width: 100%">
<el-tabs class="tag-nav" v-model="currentMenu" style="height: 100%">
<el-tab-pane
v-for="(m, idx) in menus"
:key="m"
:label="idx == 0 ? `\u2002${m}\u2002` : `\u3000${m}\u3000`"
:name="m"
>
<slot :name="`tab${idx + 1}`"></slot>
</el-tab-pane>
</el-tabs>
</div>
</template>
<script>
export default {
name: "ButtonNav",
props: {
menus: {
type: Array,
required: true,
default: () => [],
validator: (val) => {
return val.length > 0;
},
},
buttonMode: {
type: Boolean,
default: true,
},
},
data() {
return {
currentMenu: "",
};
},
created() {
this.currentMenu = this.menus[0];
},
watch: {
currentMenu(val) {
this.$emit("change", val);
},
},
};
</script>
<style scoped lang="scss">
.button-nav {
width: 100%;
display: flex;
gap: 12px;
* {
user-select: none;
}
button {
cursor: pointer;
appearance: none;
outline: none;
border: none;
background: #fff;
border-radius: 8px;
padding: 15px;
color: #888;
letter-spacing: 2px;
flex: 1;
box-sizing: padding-box;
position: relative;
&::after {
content: attr(data-text);
position: absolute;
top: 5px;
left: 50%;
font-size: 16px;
font-weight: 500;
transform: translate(-50%);
}
&.active {
color: #111;
//border-bottom: 2px solid #0b58ff;
box-shadow: 0px 2px 1px 1px #0b58ff;
}
}
}
</style>
<style scoped>
.custom-tabs >>> .el-tabs__header {
margin-bottom: 8px;
display: inline-block;
/* transform: translateY(-12px); */
}
.custom-tabs >>> .el-tabs__item {
padding-left: 0px !important;
padding-right: 0px !important;
line-height: 36px !important;
height: 36px;
}
.custom-tabs >>> .el-tabs__content {
height: calc(100% - 42px);
}
.custom-tabs >>> .el-tab-pane {
box-sizing: border-box;
height: 100%;
padding: 20px;
border: 10px solid #f002;
}
</style>

View File

@ -0,0 +1,22 @@
<!--
* @Author: zwq
* @Date: 2024-09-12 14:55:26
* @LastEditors: zwq
* @LastEditTime: 2024-09-12 15:00:14
* @Description:
-->
<template>
<dict-tag
:type="DICT_TYPE.EQU_ALARM_LEVEL"
:value="injectData.alarmGrade" />
</template>
<script>
export default {
props: {
injectData: {
type: Object,
default: () => ({}),
},
},
};
</script>

View File

@ -34,6 +34,12 @@
import Navbar from './components/Navbar';
import moment from 'moment';
import tableHeightMixin from '@/mixins/tableHeightMixin';
import { listData } from '@/api/system/dict/data';
import alarmGrade from './alarmGrade.vue'
import {
getHomeAlarmList
} from '@/api/home';
export default {
name: 'AbnormalWarning',
mixins: [tableHeightMixin],
@ -45,25 +51,28 @@ export default {
type: 'input',
label: '报警来源',
placeholder: '报警来源',
param: 'content',
param: 'alarmSource',
},
{
type: 'select',
type: 'datePicker',
label: '时间段',
selectOptions: [],
labelField: 'name',
valueField: 'id',
param: 'typeId',
filterable: true,
dateType: 'daterange',
format: 'yyyy-MM-dd',
valueFormat: 'timestamp',
rangeSeparator: '-',
startPlaceholder: '开始时间',
endPlaceholder: '结束时间',
param: 'alarmTime',
},
{
type: 'select',
label: '报警级别',
selectOptions: [],
labelField: 'name',
valueField: 'id',
param: 'typeId',
param: 'alarmGrade',
defaultSelect: '',
filterable: true,
labelField: 'label',
valueField: 'value',
},
{
type: 'button',
@ -75,60 +84,79 @@ export default {
heightNum: 280,
tableProps: [
{
prop: 'createTime',
prop: 'alarmTime',
label: '报警时间',
width: 180,
filter: (val) => moment(val).format('yyyy-MM-DD HH:mm:ss'),
},
{
prop: 'productionLineName1',
prop: 'alarmSource',
label: '报警来源',
showOverflowtooltip: true,
},
{
prop: 'productionLineName2',
prop: 'alarmType',
label: '报警类型',
showOverflowtooltip: true,
},
{
prop: 'productionLineName3',
prop: 'alarmGrade',
label: '报警级别',
showOverflowtooltip: true,
subcomponent: alarmGrade
},
{
prop: 'productionLineName4',
prop: 'alarmReason',
label: '报警原因',
showOverflowtooltip: true,
},
{
prop: 'sectionName5',
prop: 'alarmContent',
label: '报警详情',
showOverflowtooltip: true,
},
],
list: [
{ productionLineName: 1 },
{ productionLineName: 1 },
{ productionLineName: 1 },
{ productionLineName: 1 },
{ productionLineName: 1 },
{ productionLineName: 1 },
{ productionLineName: 1 },
{ productionLineName: 1 },
{ productionLineName: 1 },
{ productionLineName: 1 },
{ productionLineName: 1 },
{ productionLineName: 1 },
{ productionLineName: 1 },
{ productionLineName: 1 },
{ productionLineName: 1 },
{ productionLineName: 1 },
],
list: [],
listQuery: {
alarmSource: undefined,
alarmTime: undefined,
alarmGrade: undefined,
}
};
},
created() {},
created() {
const queryParams = {
pageNo: 1,
pageSize: 99,
dictType: 'equ_alarm_level',
};
listData(queryParams).then((response) => {
this.formConfig[2].selectOptions = response.data.list;
});
this.getDataList()
},
methods: {
buttonClick(val) {},
buttonClick(val) {
switch (val.btnName) {
case 'search':
this.listQuery.alarmSource = val.alarmSource;
this.listQuery.alarmGrade = val.alarmGrade;
this.listQuery.alarmTime = val.alarmTime ? val.alarmTime : null;
this.getDataList();
break;
default:
console.log(val);
}
},
getDataList(){
getHomeAlarmList(this.listQuery).then(response => {
if(response.hasOwnProperty('data')){
this.list = response.data;
}else{
this.list = []
}
});
},
toHome() {
this.$router.push({ path: '/' });
},

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,689 @@
<template>
<div class="app-container">
<!-- 搜索工作栏 -->
<SearchBar
:formConfigs="searchBarFormConfig"
ref="search-bar"
@headBtnClick="handleSearchBarBtnClick" />
<!-- 列表 -->
<base-table
:table-props="tableProps"
:page="queryParams.pageNo"
:limit="queryParams.pageSize"
:table-data="list"
@emitFun="handleEmitFun">
<method-btn
v-if="tableBtn.length"
slot="handleBtn"
: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="60%"
@confirm="submitForm">
<DialogForm
v-if="open"
key="index-dialog-form"
ref="form"
label-position="top"
size="small"
v-model="form"
:has-files="['files', 'files2']"
:rows="computedRows" />
</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: 'Equipment',
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: 'equipmentTypeName', label: '设备类型' },
{ prop: 'enName', label: '英文名称' },
{ prop: 'abbr', label: '缩写' },
// {
// action: 'show-detail',
// label: '',
// subcomponent: {
// props: ['injectData'],
// render: function (h) {
// const _this = this;
// return h(
// 'el-button',
// {
// props: { type: 'text', size: 'mini' },
// on: {
// click: function () {
// console.log('inejctdata', _this.injectData);
// _this.$emit('emitData', {
// action: _this.injectData.action,
// value: _this.injectData.id,
// });
// },
// },
// },
// ''
// );
// },
// },
// },
],
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' },
],
// bind: {
// disabled: this.editMode == 'detail', // some condition, like detail mode...
// }
},
{
input: true,
label: '设备编码',
prop: 'code',
url: '/base/core-equipment/getCode',
},
{
input: true,
label: '英文名称',
prop: 'enName',
},
],
[
{
input: true,
label: '缩写',
prop: 'abbr',
},
{
select: true,
label: '设备类型',
prop: 'equipmentTypeId',
url: '/base/core-equipment-type/page?pageNo=1&pageSize=100',
rules: [
{ required: true, message: '设备类型不能为空', trigger: 'blur' },
],
bind: {
filterable: true,
},
},
{
input: true,
label: '预计生产时间(min/天)',
prop: 'workTime',
rules: [
{
required: true,
message: '预计生产时间不能为空',
trigger: 'blur',
},
{
type: 'number',
message: '请输入正确的数字值',
trigger: 'blur',
transform: (val) => Number(val),
},
],
},
// {
// select: true,
// label: '',
// prop: 'groupId',
// url: '/base/core-equipment-group/page?pageNo=1&pageSize=100',
// },
],
[
{
datetime: true,
label: '生产日期',
prop: 'productionTime',
bind: {
format: 'yyyy-MM-dd',
clearable: true,
},
},
{
datetime: true,
label: '进厂日期',
prop: 'enterTime',
bind: {
format: 'yyyy-MM-dd',
clearable: true,
},
},
{
input: true,
prop: 'tvalue',
label: '设备TT值',
rules: [
{ required: true, message: '设备TT值不能为空', trigger: 'blur' },
{
type: 'number',
message: '请输入正确的数字值',
trigger: 'blur',
transform: (val) => Number(val),
},
],
},
],
[
{
input: true,
label: '单件产品加工时间(s)',
prop: 'processingTime',
rules: [
{
required: true,
message: '单件产品加工时间不能为空',
trigger: 'blur',
},
{
type: 'number',
message: '请输入正确的数字值',
trigger: 'blur',
transform: (val) => Number(val),
},
],
},
{
input: true,
label: '制造商',
prop: 'manufacturer',
},
{
input: true,
label: '规格描述',
prop: 'spec',
},
],
[
{
textarea: true,
label: '功能描述',
prop: 'description',
},
],
[
{
upload: true,
label: '设备资料',
prop: 'files',
},
],
[
{
upload: true,
label: '设备图片',
prop: 'files2',
fileType: 1,
},
],
[{ input: true, label: '备注', prop: 'remark' }],
// [
// {
// assetUpload: true,
// label: '',
// fieldName: 'assets',
// subcomponent: AssetsUpload
// },
// ],
// [
// {
// assetUpload: true,
// label: '',
// fieldName: 'images',
// subcomponent: AssetsUpload
// },
// ],
// [
// {
// upload: true,
// label: '',
// prop: 'uploadFiles',
// url: process.env.VUE_APP_BASE_API + '/admin-api/infra/file/upload', //
// uploadFnName: 'assetsUpload', //
// bind: {
// headers: { Authorization: 'Bearer ' + getAccessToken() },
// 'show-file-list': false,
// },
// },
// {
// diy: true,
// key: 'eq-assets',
// label: '',
// prop: 'fileNames',
// subcomponent: EquipmentAssets,
// },
// ],
// [
// {
// upload: true,
// label: '',
// prop: 'uploadImages',
// url: process.env.VUE_APP_BASE_API + '/admin-api/infra/file/upload', //
// uploadFnName: 'imagesUpload', //
// bind: {
// headers: { Authorization: 'Bearer ' + getAccessToken() },
// 'show-file-list': false,
// },
// },
// {
// diy: true,
// key: 'eq-pics',
// label: '',
// prop: 'fileUrls',
// subcomponent: EquipmentPics,
// pictures: async () => {
// // some async request
// return [];
// },
// },
// ],
// [
// {
// diy: true,
// key: 'eq-pics',
// label: '',
// prop: 'fileUrls',
// subcomponent: EquipmentPics,
// pictures: async () => {
// // some async request
// return [];
// },
// },
// ],
],
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, //
};
},
created() {
this.getList();
},
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;
},
},
methods: {
/** 查询列表 */
getList() {
this.loading = true;
//
getEquipmentPage(this.queryParams).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 = '添加设备';
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
this.showUploadComponents = true;
const id = row.id;
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({}, 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
.delConfirm(row.name)
.then(function () {
return deleteEquipment(id);
})
.then(() => {
this.getList();
this.$modal.msgSuccess('删除成功');
})
.catch(() => {});
},
/** 导出按钮操作 */
handleExport() {
//
let params = { ...this.queryParams };
params.pageNo = undefined;
params.pageSize = undefined;
this.$modal
.confirm('是否确认导出所有设备数据项?')
.then(() => {
this.exportLoading = true;
return 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>

View File

@ -0,0 +1,370 @@
<template>
<div class="app-container">
<!-- 搜索工作栏 -->
<SearchBar
:formConfigs="searchBarFormConfig"
ref="search-bar"
@headBtnClick="handleSearchBarBtnClick" />
<!-- 列表 -->
<base-table
:table-props="tableProps"
:page="queryParams.pageNo"
:limit="queryParams.pageSize"
:table-data="list"
@emitFun="handleEmitFun">
<method-btn
v-if="tableBtn.length"
slot="handleBtn"
label="操作"
:width="100"
: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 moment from 'moment';
import basicPageMixin from '@/mixins/lb/basicPageMixin';
// import { getAccessToken } from '@/utils/auth';
export default {
name: 'EquipmentLineBind',
components: {},
mixins: [basicPageMixin],
data() {
return {
basePath: '/base/core-equipment-bind-section',
searchBarKeys: ['equipmentName', 'productionLineId'],
tableBtn: [
this.$auth.hasPermi('base:core-equipment-bind-section:update')
? {
type: 'edit',
btnName: '修改',
}
: undefined,
this.$auth.hasPermi('base:core-equipment-bind-section:delete')
? {
type: 'delete',
btnName: '删除',
}
: undefined,
].filter((v) => v),
tableProps: [
{
prop: 'createTime',
label: '添加时间',
fixed: true,
width: 150,
filter: (val) => moment(val).format('yyyy-MM-DD HH:mm:ss'),
},
{ prop: 'productionLineName', label: '产线名称' },
{ prop: 'workshopSectionName', label: '工段名称' },
{ prop: 'equipmentName', label: '设备名称' },
{ prop: 'sort', label: '工段中排序' },
{
prop: 'lineDataType',
label: '产线统计类型',
width:120,
filter: (val) =>
val != null ? ['无类型', '进片数量统计', '出片数量统计'][val] : '',
},
{
prop: 'sectionDataType',
label: '工段统计类型',
width:120,
filter: (val) =>
val != null ? ['无类型', '进片数量统计', '出片数量统计'][val] : '',
},
// { prop: 'remark', label: '' },
],
searchBarFormConfig: [
{
type: 'select',
label: '产线',
placeholder: '请选择产线',
param: 'productionLineId',
selectOptions: [],
filterable: true,
},
{
type: 'input',
label: '设备名',
placeholder: '请输入设备名称',
param: 'equipmentName',
},
{
type: 'button',
btnName: '查询',
name: 'search',
color: 'primary',
},
{
type: 'separate',
},
{
type: this.$auth.hasPermi('base:core-equipment-bind-section: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: [
[
{
select: true,
label: '产线',
prop: 'productionLineId',
rules: [{ required: true, message: '产线名不能为空', trigger: 'blur' }],
url: '/base/core-production-line/listAll',
bind: { clearable: true, filterable: true },
// watch: 'workshopSectionId'
},
{
select: true,
label: '工段',
prop: 'workshopSectionId',
depends: 'productionLineId',
rules: [{ required: true, message: '工段不能为空', trigger: 'blur' }],
bind: { clearable: true, filterable: true },
url: '/base/core-workshop-section/listByParentId',
},
],
[
{
select: true,
label: '设备',
prop: 'equipmentId',
rules: [{ required: true, message: '设备名不能为空', trigger: 'blur' }],
bind: { clearable: true, filterable: true },
url: '/base/core-equipment/listAll',
},
{
input: true,
label: '工段排序',
prop: 'sort',
},
],
[
{
select: true,
options: [
{ label: '无类型', value: 0 },
{ label: '进片数量统计', value: 1 },
{ label: '出片数量统计', value: 2 },
],
label: '产线统计类型',
prop: 'lineDataType',
bind: {
clearable: true, filterable: true
},
rules: [{ required: true, message: '产线统计类型不能为空', trigger: 'change' }],
},
{
select: true,
options: [
{ label: '无类型', value: 0 },
{ label: '进片数量统计', value: 1 },
{ label: '出片数量统计', value: 2 },
],
label: '工段统计类型',
prop: 'sectionDataType',
bind: {
clearable: true, filterable: true
},
rules: [{ required: true, message: '工段统计类型不能为空', trigger: 'change' }],
},
],
],
//
open: false,
//
queryParams: {
pageNo: 1,
pageSize: 10,
equipmentName: null,
productionLineId: null,
},
//
form: {},
};
},
created() {
this.initSearchOptions();
this.getList();
},
methods: {
/** 初始化查询条件 */
async initSearchOptions() {
this.http('/base/core-production-line/listAll', 'get').then(
({ code, data }) => {
if (code == 0) {
this.searchBarFormConfig[0].selectOptions = data.map((item) => {
return {
name: item.name,
id: item.id,
};
});
}
}
);
},
/** 查询列表 */
getList() {
this.loading = true;
//
this.recv(this.queryParams).then(({ code, data }) => {
// if (code == 0) {
this.list = data.list;
this.total = data.total;
this.loading = false;
// }
});
// .catch(err => {
// this.list = [];
// this.total = 0;
// this.loading = false;
// })
},
/** 取消按钮 */
cancel() {
this.open = false;
this.reset();
},
/** 表单重置 */
reset() {
this.form = {
id: undefined,
productionLineId: undefined,
//
workshopSectionId: undefined,
//
equipmentId: undefined,
//
sort: undefined,
// 线
lineDataType: undefined,
//
sectionDataType: undefined,
};
this.resetForm('form');
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNo = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm('queryForm');
this.handleQuery();
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.open = true;
this.title = '添加设备工段绑定';
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
const id = row.id;
this.info({ id }).then(({ code, data }) => {
this.form = 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(({ code, data }) => {
this.$modal.msgSuccess('修改成功');
this.open = false;
this.getList();
});
return;
}
this.post(this.form).then(({ code, data }) => {
this.$modal.msgSuccess('修改成功');
this.open = false;
this.getList();
});
});
},
/** 删除按钮操作 */
handleDelete(row) {
const id = row.id;
this.$modal
.delConfirm(row.equipmentName)
.then(function () {
return deleteEquipmentType(id);
})
.then(() => {
this.getList();
this.$modal.msgSuccess('删除成功');
})
.catch(() => {});
},
/** 导出按钮操作 */
handleExport() {
//
let params = { ...this.queryParams };
params.pageNo = undefined;
params.pageSize = undefined;
this.$modal
.confirm('是否确认导出所有设备工段绑定?')
.then(() => {
this.exportLoading = true;
// return exportEquipmentTypeExcel(params);
})
.then((response) => {
this.$download.excel(response, '设备工段绑定.xls');
this.exportLoading = false;
})
.catch(() => {});
},
},
};
</script>

View File

@ -0,0 +1,312 @@
<template>
<div class="app-container">
<!-- 搜索工作栏 -->
<SearchBar
:formConfigs="searchBarFormConfig"
ref="search-bar"
@headBtnClick="handleSearchBarBtnClick" />
<!-- 列表 -->
<base-table
:table-props="tableProps"
:page="queryParams.pageNo"
:limit="queryParams.pageSize"
:table-data="list"
@emitFun="handleEmitFun">
<method-btn
v-if="tableBtn.length"
slot="handleBtn"
label="操作"
: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="true"
:rows="rows" />
</base-dialog>
</div>
</template>
<script>
import moment from 'moment';
import basicPageMixin from '@/mixins/lb/basicPageMixin';
import {
createEquipmentType,
updateEquipmentType,
deleteEquipmentType,
getEquipmentType,
getEquipmentTypePage,
exportEquipmentTypeExcel,
} from '@/api/base/equipmentType';
// import { getAccessToken } from '@/utils/auth';
export default {
name: 'EquipmentType',
components: {},
mixins: [basicPageMixin],
data() {
return {
searchBarKeys: ['name'],
tableBtn: [
this.$auth.hasPermi('base:core-equipment-type:update')
? {
type: 'edit',
btnName: '修改',
}
: undefined,
this.$auth.hasPermi('base:core-equipment-type:delete')
? {
type: 'delete',
btnName: '删除',
}
: undefined,
].filter((v) => v),
tableProps: [
{
prop: 'createTime',
label: '添加时间',
fixed: true,
width: 150,
filter: (val) => moment(val).format('yyyy-MM-DD HH:mm:ss'),
},
{ prop: 'name', label: '类型名称' },
{ prop: 'code', label: '类型编号', width: 210 },
{ prop: 'remark', label: '备注' },
],
searchBarFormConfig: [
{
type: 'input',
label: '设备类型',
placeholder: '设备类型',
param: 'name',
},
{
type: 'button',
btnName: '查询',
name: 'search',
color: 'primary',
},
{
type: 'separate',
},
{
type: this.$auth.hasPermi('base:core-equipment-type: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' },
],
// bind: {
// disabled: true, // some condition, like detail mode...
// }
},
{
input: true,
label: '类型编号',
prop: 'code',
url: '/base/core-equipment-type/getCode',
rules: [
{ required: true, message: '类型编号不能为空', trigger: 'blur' },
],
},
],
[
{
select: true,
label: '父类',
prop: 'parentId',
url: '/base/core-equipment-type/page?pageNo=1&pageSize=100',
},
{},
],
[
{
upload: true,
label: '上传资料',
prop: 'files',
},
],
[{ input: true, label: '备注', prop: 'remark' }],
],
//
open: false,
//
queryParams: {
pageNo: 1,
pageSize: 10,
name: '',
},
//
form: {
code: undefined,
name: undefined,
id: undefined,
parentId: undefined,
remark: undefined,
},
};
},
watch: {
// form: {
// handler: function (val, oldVal) {
// console.log('[watch:form]', val, oldVal);
// },
// deep: true,
// },
},
created() {
this.getList();
},
methods: {
/** 查询列表 */
getList() {
this.loading = true;
//
getEquipmentTypePage(this.queryParams).then((response) => {
this.list = response.data.list;
this.total = response.data.total;
this.loading = false;
});
},
/** 取消按钮 */
cancel() {
this.open = false;
this.reset();
},
/** 表单重置 */
reset() {
this.form = {
id: undefined,
code: undefined,
name: undefined,
parentId: undefined,
remark: undefined,
};
this.resetForm('form');
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNo = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm('queryForm');
this.handleQuery();
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.open = true;
this.title = '添加设备类型';
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
const id = row.id;
getEquipmentType(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) {
updateEquipmentType(this.form).then((response) => {
this.$modal.msgSuccess('修改成功');
this.open = false;
this.getList();
});
return;
}
//
createEquipmentType(this.form).then((response) => {
this.$modal.msgSuccess('新增成功');
this.open = false;
this.getList();
});
});
},
/** 删除按钮操作 */
handleDelete(row) {
const id = row.id;
this.$modal
.delConfirm(row.name)
.then(function () {
return deleteEquipmentType(id);
})
.then(() => {
this.getList();
this.$modal.msgSuccess('删除成功');
})
.catch(() => {});
},
/** 导出按钮操作 */
handleExport() {
//
let params = { ...this.queryParams };
params.pageNo = undefined;
params.pageSize = undefined;
this.$modal
.confirm('是否确认导出所有设备类型数据项?')
.then(() => {
this.exportLoading = true;
return exportEquipmentTypeExcel(params);
})
.then((response) => {
this.$download.excel(response, '设备类型.xls');
this.exportLoading = false;
})
.catch(() => {});
},
},
};
</script>

View File

@ -0,0 +1,163 @@
<!--
* @Author: zwq
* @Date: 2021-11-18 14:16:25
* @LastEditors: zwq
* @LastEditTime: 2024-09-25 10:24:33
* @Description:
-->
<template>
<el-form
:model="dataForm"
:rules="dataRule"
ref="dataForm"
@keyup.enter.native="dataFormSubmit()"
label-width="100px">
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="产线名称" prop="name">
<el-input
v-model="dataForm.name"
clearable
placeholder="请输入产线名称" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="产线编号" prop="code">
<el-input
v-model="dataForm.code"
clearable
placeholder="请输入产线编号" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="工厂名称" prop="factoryId">
<el-select
v-model="dataForm.factoryId"
filterable
placeholder="请选择工厂"
style="width: 100%">
<el-option
v-for="dict in factoryList"
:key="dict.id"
:label="dict.name"
:value="dict.id" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="归属部门" prop="deptId">
<treeselect
v-model="dataForm.deptId"
:options="deptOptions"
:show-count="true"
:clearable="false"
placeholder="请选择归属部门"
:normalizer="normalizer" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="产线TT值(h)" prop="tvalue">
<el-input
v-model.number="dataForm.tvalue"
type="number"
placeholder="TT值" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="描述信息" prop="description">
<el-input
v-model="dataForm.description"
placeholder="请输入描述信息" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="备注" prop="remark">
<el-input v-model="dataForm.remark" placeholder="请输入备注" />
</el-form-item>
</el-col>
</el-row>
</el-form>
</template>
<script>
import basicAdd from '@/mixins/basic-add';
import {
createCorePL,
updateCorePL,
getCorePL,
getCode,
} from '@/api/base/coreProductionLine';
import { getFactoryList } from '@/api/core/base/factory';
import { listSimpleDepts } from '@/api/system/dept';
import Treeselect from '@riophae/vue-treeselect';
import '@riophae/vue-treeselect/dist/vue-treeselect.css';
export default {
mixins: [basicAdd],
components: { Treeselect },
data() {
return {
urlOptions: {
isGetCode: true,
codeURL: getCode,
createURL: createCorePL,
updateURL: updateCorePL,
infoURL: getCorePL,
},
//
deptOptions: undefined,
dataForm: {
id: undefined,
code: undefined,
name: undefined,
description: undefined,
tvalue: 0,
factoryId: undefined,
deptId: undefined,
remark: undefined,
},
factoryList: [],
dataRule: {
code: [
{ required: true, message: '产线编号不能为空', trigger: 'blur' },
],
name: [
{ required: true, message: '产线名称不能为空', trigger: 'blur' },
],
factoryId: [
{ required: true, message: '工厂不能为空', trigger: 'blur' },
],
},
};
},
mounted() {
this.getDict();
this.getTreeselect()
},
methods: {
async getDict() {
//
const factoryRes = await getFactoryList();
this.factoryList = factoryRes.data;
},
/** 查询部门下拉树结构 */
getTreeselect() {
listSimpleDepts().then((response) => {
// deptOptions
this.deptOptions = [];
this.deptOptions.push(...this.handleTree(response.data, 'id'));
});
},
//
normalizer(node) {
return {
id: node.id,
label: node.name,
children: node.children,
};
},
},
};
</script>

View File

@ -0,0 +1,204 @@
<template>
<div class="app-container">
<search-bar
:formConfigs="formConfig"
ref="searchBarForm"
@headBtnClick="buttonClick" />
<base-table
v-loading="dataListLoading"
:table-props="tableProps"
:page="listQuery.pageNo"
:limit="listQuery.pageSize"
:table-data="tableData">
<method-btn
v-if="tableBtn.length"
slot="handleBtn"
:width="120"
label="操作"
:method-list="tableBtn"
@clickBtn="handleClick" />
</base-table>
<pagination
:limit.sync="listQuery.pageSize"
:page.sync="listQuery.pageNo"
:total="listQuery.total"
@pagination="getDataList" />
<base-dialog
:dialogTitle="addOrEditTitle"
:dialogVisible="addOrUpdateVisible"
@cancel="handleCancel"
@confirm="handleConfirm"
:before-close="handleCancel"
width="50%">
<add-or-update
ref="addOrUpdate"
@refreshDataList="successSubmit"></add-or-update>
</base-dialog>
</div>
</template>
<script>
import AddOrUpdate from './add-or-updata';
import basicPage from '@/mixins/basic-page';
import { parseTime } from '@/mixins/code-filter';
import codeFilter from '@/mixins/code-filter';
import { getCorePLPage, deleteCorePL } from '@/api/base/coreProductionLine';
import { getStatus } from '@/api/core/base/productionLine';
const tableProps = [
{
prop: 'createTime',
label: '添加时间',
filter: parseTime,
width: 150,
},
{
prop: 'factoryName',
label: '工厂',
},
{
prop: 'departmentName',
label: '归属部门',
},
{
prop: 'name',
label: '产线名称',
},
{
prop: 'code',
label: '产线编码',
width: 150,
},
{
prop: 'enabled',
label: '当前状态',
filter: codeFilter('lineStatus'),
},
{
prop: 'tvalue',
label: '产线TT值(h)',
width: 100,
},
{
prop: 'description',
label: '描述',
},
{
prop: 'remark',
label: '备注',
},
];
export default {
mixins: [basicPage],
data() {
return {
urlOptions: {
getDataListURL: getCorePLPage,
deleteURL: deleteCorePL,
},
tableProps,
tableBtn: [
this.$auth.hasPermi(`base:core-production-line:update`)
? {
type: 'edit',
btnName: '编辑',
}
: undefined,
this.$auth.hasPermi(`base:core-production-line:delete`)
? {
type: 'delete',
btnName: '删除',
}
: undefined,
].filter((v) => v),
tableData: [],
formConfig: [
{
type: 'input',
label: '产线名称',
placeholder: '产线名称',
param: 'name',
},
{
type: 'button',
btnName: '查询',
name: 'search',
color: 'primary',
},
{
type: 'separate',
},
{
type: this.$auth.hasPermi('base:core-production-line:create')
? 'button'
: '',
btnName: '新增',
name: 'add',
color: 'success',
plain: true,
},
],
};
},
components: {
AddOrUpdate,
},
created() {},
methods: {
//
getDataList() {
this.dataListLoading = true;
this.urlOptions.getDataListURL(this.listQuery).then((response) => {
// this.tableData = response.data.list;
this.getStatus(response.data.list);
this.listQuery.total = response.data.total;
this.dataListLoading = false;
});
},
getStatus(list) {
const ids = list.map((i) => {
return i.id;
});
console.log('111', ids);
getStatus(ids).then((response) => {
response.forEach((a) => {
list.forEach((b) => {
if (b.id === a.id) b.enabled = a.status;
});
});
this.tableData = list;
});
},
buttonClick(val) {
switch (val.btnName) {
case 'search':
this.listQuery.pageNo = 1;
this.listQuery.pageSize = 10;
this.listQuery.name = val.name ? val.name : undefined;
this.getDataList();
break;
case 'reset':
this.$refs.searchBarForm.resetForm();
this.listQuery = {
pageSize: 10,
pageNo: 1,
total: 1,
};
this.getDataList();
break;
case 'add':
this.addOrEditTitle = '新增';
this.addOrUpdateVisible = true;
this.addOrUpdateHandle();
break;
case 'export':
this.handleExport();
break;
default:
console.log(val);
}
},
},
};
</script>

View File

@ -0,0 +1,105 @@
<!--
* @Author: zwq
* @Date: 2021-11-18 14:16:25
* @LastEditors: zwq
* @LastEditTime: 2024-09-24 14:49:25
* @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" clearable placeholder="请输入工段名称" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="工段编号" prop="code">
<el-input v-model="dataForm.code" clearable placeholder="请输入工段编号" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="产线" prop="productionLineId">
<el-select
v-model="dataForm.productionLineId"
filterable
placeholder="请选择产线">
<el-option
v-for="dict in proLineList"
:key="dict.id"
:label="dict.name"
:value="dict.id" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="排序" prop="sort">
<el-input-number
v-model="dataForm.sort"
controls-position="right"
placeholder="排序"
style="width: 100%" />
</el-form-item>
</el-col>
</el-row>
<el-form-item label="备注" prop="remark">
<el-input
v-model="dataForm.remark"
placeholder="请输入备注" />
</el-form-item>
</el-form>
</template>
<script>
import basicAdd from '@/mixins/basic-add';
import { createCWSection, updateCWSection, getCWSection, getCode } from "@/api/base/coreWorkshopSection";
import { getCorePLList } from '@/api/base/coreProductionLine';
export default {
mixins: [basicAdd],
data() {
return {
urlOptions: {
isGetCode: true,
codeURL: getCode,
createURL: createCWSection,
updateURL: updateCWSection,
infoURL: getCWSection
},
dataForm: {
id: undefined,
code: undefined,
name: undefined,
description: undefined,
sort: 0,
productionLineId: undefined,
remark: undefined,
},
proLineList: [],
dataRule: {
code: [{ required: true, message: "工段编号不能为空", trigger: "blur" }],
name: [{ required: true, message: "工段名称不能为空", trigger: "blur" }],
productionLineId: [{ required: true, message: "产线不能为空", trigger: "blur" }],
sort: [{ required: true, message: "排序不能为空", trigger: "blur" }]
}
};
},
mounted() {
this.getDict()
},
methods: {
async getDict() {
// 线
const res = await getCorePLList();
this.proLineList = res.data;
},
}
};
</script>

View File

@ -0,0 +1,165 @@
<template>
<div class="app-container">
<search-bar
:formConfigs="formConfig"
ref="searchBarForm"
@headBtnClick="buttonClick" />
<base-table
v-loading="dataListLoading"
:table-props="tableProps"
:page="listQuery.pageNo"
:limit="listQuery.pageSize"
:table-data="tableData">
<method-btn
v-if="tableBtn.length"
slot="handleBtn"
:width="120"
label="操作"
:method-list="tableBtn"
@clickBtn="handleClick" />
</base-table>
<pagination
:limit.sync="listQuery.pageSize"
:page.sync="listQuery.pageNo"
:total="listQuery.total"
@pagination="getDataList" />
<base-dialog
:dialogTitle="addOrEditTitle"
:dialogVisible="addOrUpdateVisible"
@cancel="handleCancel"
@confirm="handleConfirm"
:before-close="handleCancel"
width="40%">
<add-or-update
ref="addOrUpdate"
@refreshDataList="successSubmit"></add-or-update>
</base-dialog>
</div>
</template>
<script>
import AddOrUpdate from './add-or-updata';
import basicPage from '@/mixins/basic-page';
import { parseTime } from '@/mixins/code-filter';
import {
getCWSectionPage,
deleteCWSection
} from '@/api/base/coreWorkshopSection';
const tableProps = [
{
prop: 'createTime',
label: '添加时间',
filter: parseTime,
width:150
},
{
prop: 'code',
label: '工段编码',
width:150
},
{
prop: 'name',
label: '工段名称'
},
{
prop: 'productionLineName',
label: '产线名'
},
{
prop: 'sort',
label: '排序'
},
{
prop: 'remark',
label: '备注'
},
];
export default {
mixins: [basicPage],
data() {
return {
urlOptions: {
getDataListURL: getCWSectionPage,
deleteURL: deleteCWSection
},
tableProps,
tableBtn: [
this.$auth.hasPermi(`base:core-workshop-section:update`)
? {
type: 'edit',
btnName: '编辑',
}
: undefined,
this.$auth.hasPermi(`base:core-workshop-section:delete`)
? {
type: 'delete',
btnName: '删除',
}
: undefined,
].filter((v)=>v),
tableData: [],
formConfig: [
{
type: 'input',
label: '工段名称',
placeholder: '工段名称',
param: 'name'
},
{
type: 'button',
btnName: '查询',
name: 'search',
color: 'primary',
},
{
type: 'separate',
},
{
type: this.$auth.hasPermi('base:core-workshop-section:create') ? 'button' : '',
btnName: '新增',
name: 'add',
color: 'success',
plain: true
},
],
};
},
components: {
AddOrUpdate,
},
created() {},
methods: {
buttonClick(val) {
switch (val.btnName) {
case 'search':
this.listQuery.pageNo = 1;
this.listQuery.pageSize = 10;
this.listQuery.name = val.name ? val.name : undefined;
this.getDataList();
break;
case 'reset':
this.$refs.searchBarForm.resetForm();
this.listQuery = {
pageSize: 10,
pageNo: 1,
total: 1,
};
this.getDataList();
break;
case 'add':
this.addOrEditTitle = '新增';
this.addOrUpdateVisible = true;
this.addOrUpdateHandle();
break;
case 'export':
this.handleExport();
break;
default:
console.log(val);
}
},
},
};
</script>

View File

@ -0,0 +1,90 @@
<!--
* @Author: zwq
* @Date: 2021-11-18 14:16:25
* @LastEditors: DY
* @LastEditTime: 2023-11-03 16:32:52
* @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"
clearable
placeholder="请输入工厂名称" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="工厂编码" prop="code">
<el-input
v-model="dataForm.code"
clearable
placeholder="请输入工厂编码" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="地址" prop="address">
<el-input v-model="dataForm.address" clearable placeholder="请输入地址" />
</el-form-item>
</el-col>
<!-- <el-form-item label="启用状态" prop="enabled">
<el-select
v-model="dataForm.enabled"
placeholder="请选择启用状态">
<el-option
v-for="dict in this.getDictDatas(DICT_TYPE.INFRA_BOOLEAN_STRING)"
:key="dict.value"
:label="dict.label"
:value="dict.value" />
</el-select>
</el-form-item> -->
<el-col :span="12">
<el-form-item label="备注" prop="remark">
<el-input v-model="dataForm.remark" clearable placeholder="请输入备注" />
</el-form-item>
</el-col>
</el-row>
</el-form>
</template>
<script>
import basicAdd from '@/mixins/basic-add';
import { createFactory, updateFactory, getFactory, getCode } from "@/api/core/base/factory";
export default {
mixins: [basicAdd],
data() {
return {
urlOptions: {
isGetCode: true,
codeURL: getCode,
createURL: createFactory,
updateURL: updateFactory,
infoURL: getFactory,
},
dataForm: {
id: undefined,
code: undefined,
name: undefined,
address: undefined,
remark: undefined,
},
dataRule: {
code: [{ required: true, message: "工厂编码不能为空", trigger: "blur" }],
name: [{ required: true, message: "工厂名称不能为空", trigger: "blur" }],
}
};
},
methods: {
},
};
</script>

View File

@ -0,0 +1,184 @@
<template>
<div class="app-container">
<search-bar
:formConfigs="formConfig"
ref="searchBarForm"
@headBtnClick="buttonClick" />
<base-table
v-loading="dataListLoading"
:table-props="tableProps"
:page="listQuery.pageNo"
:limit="listQuery.pageSize"
:table-data="tableData">
<method-btn
v-if="tableBtn.length"
slot="handleBtn"
:width="120"
label="操作"
:method-list="tableBtn"
@clickBtn="handleClick" />
</base-table>
<pagination
:limit.sync="listQuery.pageSize"
:page.sync="listQuery.pageNo"
:total="listQuery.total"
@pagination="getDataList" />
<base-dialog
:dialogTitle="addOrEditTitle"
:dialogVisible="addOrUpdateVisible"
@cancel="handleCancel"
@confirm="handleConfirm"
:before-close="handleCancel"
width="50%">
<add-or-update
ref="addOrUpdate"
@refreshDataList="successSubmit"></add-or-update>
</base-dialog>
</div>
</template>
<script>
import AddOrUpdate from './add-or-updata';
import basicPage from '@/mixins/basic-page';
import { parseTime } from '@/mixins/code-filter';
import {
deleteFactory,
getFactoryPage
} from '@/api/core/base/factory';
const tableProps = [
{
prop: 'createTime',
label: '添加时间',
filter: parseTime
},
{
prop: 'name',
label: '工厂名称'
},
{
prop: 'code',
label: '工厂编码'
},
{
prop: 'address',
label: '地址'
},
{
prop: 'remark',
label: '备注'
}
];
export default {
mixins: [basicPage],
data() {
return {
urlOptions: {
getDataListURL: getFactoryPage,
deleteURL: deleteFactory,
// exportURL: exportFactoryExcel,
},
tableProps,
tableBtn: [
this.$auth.hasPermi(`base:core-factory:update`)
? {
type: 'edit',
btnName: '编辑',
}
: undefined,
this.$auth.hasPermi(`base:core-factory:delete`)
? {
type: 'delete',
btnName: '删除',
}
: undefined,
].filter((v)=>v),
tableData: [],
formConfig: [
{
type: 'input',
label: '工厂名称',
placeholder: '工厂名称',
param: 'name',
},
{
type: 'input',
label: '工厂编码',
placeholder: '工厂编码',
param: 'code',
},
{
type: 'button',
btnName: '查询',
name: 'search',
color: 'primary',
},
// {
// type: 'separate',
// },
// {
// type: 'button',
// btnName: '',
// name: 'reset',
// },
{
type: 'separate',
},
{
type: this.$auth.hasPermi('base:core-factory:create') ? 'button' : '',
btnName: '新增',
name: 'add',
color: 'success',
plain: true,
},
// {
// type: this.$auth.hasPermi('base:factory:create') ? 'separate' : '',
// },
// {
// type: this.$auth.hasPermi('base:factory:export') ? 'button' : '',
// btnName: '',
// name: 'export',
// color: 'warning',
// },
],
};
},
components: {
AddOrUpdate,
},
created() {},
methods: {
buttonClick(val) {
switch (val.btnName) {
case 'search':
this.listQuery.pageNo = 1;
this.listQuery.pageSize = 10;
this.listQuery.name = val.name;
this.listQuery.code = val.code;
this.getDataList();
break;
case 'reset':
this.$refs.searchBarForm.resetForm();
this.listQuery = {
pageSize: 10,
pageNo: 1,
total: 1,
};
this.getDataList();
break;
case 'add':
this.addOrEditTitle = '新增';
this.addOrUpdateVisible = true;
this.addOrUpdateHandle();
break;
case 'export':
this.handleExport();
break;
default:
console.log(val);
}
},
},
};
</script>

View File

@ -241,7 +241,9 @@ export default {
},
/** 删除按钮操作 */
handleDelete(row) {
this.$modal.confirm('是否确认删除监控对象为"' + row.objName + '"的数据项?').then(function() {
this.$modal
.delConfirm(row.objName)
.then(function() {
return deleteEnergyLimit(row.id);
}).then(() => {
this.queryParams.pageNo = 1;

View File

@ -63,7 +63,7 @@ const tableProps = [
label: '对象编码'
},
{
prop: 'plcTableName',
prop: 'plcTableName',
label: '关联表名'
},
{
@ -230,7 +230,9 @@ export default {
},
/** 删除按钮操作 */
handleDelete(row) {
this.$modal.confirm('是否确认删除对象为"' + row.objName + '"的数据项?').then(function() {
this.$modal
.delConfirm(row.objName)
.then(function() {
return deleteEnergyPlcConnect(row.id);
}).then(() => {
this.queryParams.pageNo = 1;

View File

@ -63,7 +63,7 @@ const tableProps = [
showOverflowtooltip: true
},
{
prop: 'type',
prop: 'type',
label: '统计类型',
filter: publicFormatter('statistic_type')
},
@ -224,7 +224,9 @@ export default {
},
/** 删除按钮操作 */
handleDelete(row) {
this.$modal.confirm('是否确认删除方案名称为"' + row.name + '"的数据项?').then(function() {
this.$modal
.delConfirm(row.name)
.then(function() {
return deleteEnergyStatistics(row.id);
}).then(() => {
this.queryParams.pageNo = 1;

View File

@ -205,7 +205,9 @@ export default {
},
/** 删除按钮操作 */
handleDelete(row) {
this.$modal.confirm('是否确认删除能源类型为"' + row.name + '"的数据项?').then(function() {
this.$modal
.delConfirm(row.name)
.then(function() {
return deleteEnergyType(row.id);
}).then(() => {
this.queryParams.pageNo = 1;

View File

@ -150,6 +150,10 @@
<el-button type="primary" size="small" @click="search">查询</el-button>
<span class="separateStyle"></span>
<el-button size="small" @click="resetBtn">重置</el-button>
<span class="separateStyle"></span>
<el-button type="primary" size="small" @click="exportData" plain>
导出
</el-button>
</el-form-item>
</el-form>
<span v-if="isFold" class="foldClass" @click='switchMode'>
@ -326,8 +330,16 @@ export default {
})
}
},
//
search() {
if (this.validateData()) {
this.queryParams.startTime = this.queryParams.startTime + '';
this.queryParams.endTime = this.queryParams.endTime + '';
this.$emit('submit', this.queryParams);
}
},
//
search() {
validateData() {
if (!this.queryParams.energyTypeId) {
this.$modal.msgError('请选择能源类型')
return false
@ -397,10 +409,7 @@ export default {
this.$modal.msgError('请选择对象')
return false
}
this.queryParams.startTime = this.queryParams.startTime + ''
this.queryParams.endTime = this.queryParams.endTime + ''
console.log(this.queryParams)
this.$emit('submit', this.queryParams)
return true;
},
resetBtn() {
this.queryParams.energyTypeId = null
@ -436,7 +445,14 @@ export default {
} else {
element.classList.add('divHeight')
}
}
},
exportData() {
if (this.validateData()) {
this.queryParams.startTime = this.queryParams.startTime + '';
this.queryParams.endTime = this.queryParams.endTime + '';
this.$emit('exportD', this.queryParams);
}
},
}
}
</script>
@ -494,4 +510,4 @@ export default {
vertical-align: middle;
margin: 0 10px;
}
</style>
</style>

View File

@ -1,66 +1,100 @@
<template>
<div class="app-container contrastAnalysisBox" id="contrastAnalysisBox">
<!-- 搜索工作栏 -->
<search-area :isFold="isFold" @submit="getList"/>
<el-tabs v-model="activeName" @tab-click="switchChart" v-show='chartData.length'>
<el-tab-pane label="柱状图" name="bar">
<bar-chart ref="analysisBarChart" :chartData="chartData" :timeDim="timeDim" />
</el-tab-pane>
<el-tab-pane label="折线图" name="line">
<line-chart ref="analysisLineChart" :chartData="chartData" :timeDim="timeDim"/>
</el-tab-pane>
</el-tabs>
<search-area :isFold="isFold" @submit="getList" @exportD="exportData"/>
<div v-show="chartData.length">
<bar-chart
ref="analysisBarChart"
:chartData="chartData"
:timeDim="timeDim" />
<base-table
:table-props="tableProps"
:table-data="list"
:max-height="tableH"
class="contrast-out-table" />
</div>
<!-- 没有数据 -->
<div class="no-data-bg" v-show='!chartData.length'></div>
</div>
</template>
<script>
import { getCompare } from "@/api/analysis/energyAnalysis"
import { getCompare ,exportCompare} from "@/api/analysis/energyAnalysis"
import SearchArea from "./components/searchArea"
import BarChart from "./components/barChart"
import LineChart from "./components/lineChart"
import tableHeightMixin from '@/mixins/tableHeightMixin';
import FileSaver from 'file-saver';
import * as XLSX from 'xlsx/xlsx.mjs';
// import moment from 'moment'
export default {
name: 'ContrastAnalysis',
components: { SearchArea, BarChart, LineChart },
components: { SearchArea, BarChart },
mixins: [tableHeightMixin],
data() {
return {
isFold: false,
activeName: 'bar',
chartData: [],
timeDim: ''
chartData: [],
timeDim: '',
tableProps: [],
list: [],
tableH: this.tableHeight(250) / 2,
}
},
mounted() {
window.addEventListener('resize', () => {
this.tableH = this.tableHeight(260)
this.isFold = this.searchBarWidth('contrastAnalysisBox', 1437)
this.isFold = this.searchBarWidth('contrastAnalysisBox', 1310)
// console.log(document.getElementById("contrastAnalysisBox").offsetWidth)
})
this.isFold = this.searchBarWidth('contrastAnalysisBox', 1437)
this.isFold = this.searchBarWidth('contrastAnalysisBox', 1310)
},
methods: {
_setTableHeight() {
this.tableH = this.tableHeight(250) / 2;
},
getList(params) {
this.timeDim = params.timeDim
getCompare({ ...params }).then((res) => {
console.log(res)
if (res.code === 0) {
this.chartData = res.data || []
if (res.code === 0) {
this.getTableList(res.data || []);
this.chartData = res.data || [];
} else {
this.chartData = []
}
})
},
switchChart() {
if (this.activeName === 'bar') {
this.$nextTick((res) => {
this.$refs.analysisBarChart.getChart()
})
} else {
this.$nextTick((res) => {
this.$refs.analysisLineChart.getChart()
})
}
getTableList(arr) {
this.tableProps = [];
this.list = [];
let tempX = [];
let timeArr = arr[0].trendRespVOList || [];
this.list = timeArr.map((item) => {
return { time: item.time };
});
for (let i = 0; i < arr.length; i++) {
let obj = {};
obj.prop = arr[i].objId;
obj.label = arr[i].objName;
obj.minWidth = 100;
tempX.push(obj);
let tiemList = arr[i].trendRespVOList;
for (let j = 0; j < tiemList.length; j++) {
this.list[j][arr[i].objId] = tiemList[j].useNum
? tiemList[j].useNum.toFixed(2)
: null;
}
}
this.tableProps = [{ prop: 'time', label: '时间' }].concat(tempX);
},
/** 导出按钮操作 */
exportData(val) {
//
this.$modal.confirm('是否确认导出对比分析数据?').then(() => {
this.exportLoading = true;
return exportCompare(val);
}).then(response => {
this.$download.excel(response, '对比分析数据.xlsx');
this.exportLoading = false;
}).catch(() => {});
}
}
}
@ -93,4 +127,4 @@ export default {
color: rgba(0, 0, 0, 0.45);
}
}
</style>
</style>

View File

@ -0,0 +1,74 @@
<!--
* @Author: zwq
* @Date: 2024-09-23 14:35:30
* @LastEditors: zwq
* @LastEditTime: 2024-09-23 14:48:08
* @Description:
-->
<template>
<div>
<div style="background: #f2f4f9; height: 40px; width: 100%">
<ButtonNav
:menus="['走势分析', '对比分析', '同比分析', '环比分析']"
@change="currentMenu">
<template v-slot:tab1>
<div>走势分析</div>
</template>
<template v-slot:tab2>
<div>对比分析</div>
</template>
<template v-slot:tab3>
<div>同比分析</div>
</template>
<template v-slot:tab4>
<div>环比分析</div>
</template>
</ButtonNav>
</div>
<div class="app-container">
<div v-if="activeName === '走势分析'">
<trendAnalysis />
</div>
<div v-else-if="activeName === '对比分析'">
<contrastAnalysis />
</div>
<div v-else-if="activeName === '同比分析'">
<yoyAnalysis />
</div>
<div v-else-if="activeName === '环比分析'">
<qoqAnalysis />
</div>
</div>
</div>
</template>
<script>
import ButtonNav from '@/components/ButtonNav';
import trendAnalysis from './trendAnalysis';
import contrastAnalysis from './contrastAnalysis';
import yoyAnalysis from './yoyAnalysis';
import qoqAnalysis from './qoqAnalysis';
export default {
name: '',
data() {
return {
activeName: '走势分析',
};
},
components: {
ButtonNav,
trendAnalysis,
contrastAnalysis,
yoyAnalysis,
qoqAnalysis,
},
created() {},
methods: {
currentMenu(val) {
this.activeName = val;
},
},
};
</script>
<style lang="scss"></style>

View File

@ -158,14 +158,33 @@ export default {
this.$emit('submit', this.queryParams)
},
exportData() {
let name
if (this.queryParams.objId) {
name = this.getObjName(this.objList, this.queryParams.objId)
if (this.objArr.length === 0) {
this.$modal.msgError('请选择对象')
return false
} else {
this.$modal.msgWarning("对象不能为空")
this.queryParams.objId = this.objArr[this.objArr.length-1]
}
if (!this.queryParams.type) {
this.$modal.msgError('请选择时间维度')
return false
}
this.$emit('exportD', {name: name})
if (!this.queryParams.searchTime) {
this.$modal.msgError('请选择时间')
return false
}
switch (this.queryParams.type) {
case 1:
this.queryParams.searchTime = this.transformTime(this.monthValue)
break;
case 2:
let value = moment(this.weekValue).day(6).format('YYYY-MM-DD') + ' 23:59:59'
this.queryParams.searchTime = new Date(value).getTime()
break;
default:
let value2 = moment(this.dateValue).format('YYYY-MM-DD') + ' 23:59:59'
this.queryParams.searchTime = new Date(value2).getTime()
}
this.$emit('exportD', this.queryParams)
},
// name
getObjName(list, id) {
@ -229,4 +248,4 @@ export default {
margin-top: 10px;
}
}
</style>
</style>

View File

@ -19,7 +19,7 @@
</div>
</template>
<script>
import { getQoq } from "@/api/analysis/energyAnalysis"
import { getQoq,exportChain } from "@/api/analysis/energyAnalysis"
import SearchArea from "./components/searchArea"
import LineChart from "./components/lineChart"
import FileSaver from "file-saver"
@ -89,26 +89,14 @@ export default {
this.chartData = this.list
},
exportData(val) {
if (this.list.length > 0) {
var wb = XLSX.utils.table_to_book(document.querySelector(".qoq-out-table"))
let fileName = val.name + "环比分析.xlsx"
var wbout = XLSX.write(wb, {
bookType: "xlsx",
bookSST: true,
type: "array"
})
try {
FileSaver.saveAs(
new Blob([wbout], { type: "application/octet-stream" }),
fileName
)
} catch (e) {
if (typeof console !== "undefined") console.log(e, wbout);
}
return wbout
} else {
this.$modal.msgWarning("暂无数据导出")
}
//
this.$modal.confirm('是否确认导出环比分析数据?').then(() => {
this.exportLoading = true;
return exportChain(val);
}).then(response => {
this.$download.excel(response, '环比分析数据.xlsx');
this.exportLoading = false;
}).catch(() => {});
}
}
}
@ -129,4 +117,4 @@ export default {
margin-right: 8px;
vertical-align: bottom;
}
</style>
</style>

View File

@ -1,456 +1,489 @@
<template>
<div class="searchBarBox divHeight" ref="searchBarRef" :style="{ paddingRight: isFold ? '55px' : '0px' }">
<el-form :inline="true" class="demo-form-inline">
<span class="blue-block"></span>
<el-form-item label="能源类型" required>
<el-select v-model="queryParams.energyTypeId" placeholder="请选择" style="width: 100px;" size="small">
<el-option
v-for="item in energyTypeList"
:key="item.id"
:label="item.name"
:value="item.id">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="对象选择" required>
<el-cascader
v-model="objArr"
:options="objList"
:props="{ checkStrictly: true, value: 'id', label: 'name' }"
popper-class="cascaderParent"
size="small"
clearable></el-cascader>
</el-form-item>
<el-form-item label="时间维度" required>
<el-select v-model="queryParams.timeDim" placeholder="请选择" style="width: 80px;" size="small">
<el-option
v-for="item in getDictDatas(this.DICT_TYPE.TIME_DIM)"
:key="item.value"
:label="item.label"
:value="item.value"
size="small">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="时间范围" required>
<div v-show="queryParams.timeDim === '1'">
<el-date-picker
v-model="timeValue"
type="datetimerange"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期"
format="yyyy-MM-dd HH:mm"
value-format="timestamp"
:picker-options="pickerOptions"
popper-class="noneMinute"
@change="timeSelect"
size="small"
style='width:350px;'
>
</el-date-picker>
</div>
<div v-show="queryParams.timeDim === '2'">
<el-date-picker
v-model="dateValue"
type="daterange"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期"
value-format="timestamp"
:picker-options="pickerOptions"
@change="timeSelect"
size="small"
style='width:350px;'
>
</el-date-picker>
</div>
<div v-show="queryParams.timeDim === '3'">
<el-date-picker
v-model="weekValue1"
type="week"
format="yyyy 第 WW 周"
style='width:170px;'
:picker-options="pickerOptionsWeek"
@change="startWeek"
size="small"
placeholder="选择周">
</el-date-picker>-
<el-date-picker
v-model="weekValue2"
type="week"
format="yyyy 第 WW 周"
:picker-options="pickerOptionsWeek"
style='width:170px;'
@change="endWeek"
size="small"
placeholder="选择周">
</el-date-picker>
</div>
<div v-show="queryParams.timeDim === '4'">
<el-date-picker
v-model="monthValue"
type="monthrange"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期"
value-format="timestamp"
:picker-options="pickerOptions"
size="small"
style='width:350px;'
@change="timeSelect"
>
</el-date-picker>
</div>
<div v-show="queryParams.timeDim === '5'">
<el-date-picker
style='width:170px;'
v-model="yearValue1"
type="year"
:picker-options="pickerOptions"
value-format="timestamp"
placeholder="选择年"
size="small"
@change="startYear"
>
</el-date-picker>-
<el-date-picker
style='width:170px;'
v-model="yearValue2"
type="year"
:picker-options="pickerOptions"
value-format="timestamp"
placeholder="选择年"
size="small"
@change="endYear"
>
</el-date-picker>
</div>
</el-form-item>
<el-form-item>
<el-button type="primary" size="small" @click="search">查询</el-button>
<span class="separateStyle"></span>
<el-button size="small" @click="resetBtn">重置</el-button>
</el-form-item>
</el-form>
<span v-if="isFold" class="foldClass" @click='switchMode'>
{{ isExpand ? '收起' : '展开' }}
<svg-icon :icon-class="isExpand ? 'upward' : 'downward'" />
</span>
</div>
<div
class="searchBarBox divHeight"
ref="searchBarRef"
:style="{ paddingRight: isFold ? '55px' : '0px' }">
<el-form :inline="true" class="demo-form-inline">
<span class="blue-block"></span>
<el-form-item label="能源类型" required>
<el-select
v-model="queryParams.energyTypeId"
placeholder="请选择"
style="width: 100px"
size="small">
<el-option
v-for="item in energyTypeList"
:key="item.id"
:label="item.name"
:value="item.id"></el-option>
</el-select>
</el-form-item>
<el-form-item label="对象选择" required>
<el-cascader
v-model="objArr"
:options="objList"
:props="{ checkStrictly: true, value: 'id', label: 'name' }"
popper-class="cascaderParent"
size="small"
clearable></el-cascader>
</el-form-item>
<el-form-item label="时间维度" required>
<el-select
v-model="queryParams.timeDim"
placeholder="请选择"
style="width: 80px"
size="small">
<el-option
v-for="item in getDictDatas(this.DICT_TYPE.TIME_DIM)"
:key="item.value"
:label="item.label"
:value="item.value"
size="small"></el-option>
</el-select>
</el-form-item>
<el-form-item label="时间范围" required>
<div v-show="queryParams.timeDim === '1'">
<el-date-picker
v-model="timeValue"
type="datetimerange"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期"
format="yyyy-MM-dd HH:mm"
value-format="timestamp"
:picker-options="pickerOptions"
popper-class="noneMinute"
@change="timeSelect"
size="small"
style="width: 350px"></el-date-picker>
</div>
<div v-show="queryParams.timeDim === '2'">
<el-date-picker
v-model="dateValue"
type="daterange"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期"
value-format="timestamp"
:picker-options="pickerOptions"
@change="timeSelect"
size="small"
style="width: 350px"></el-date-picker>
</div>
<div v-show="queryParams.timeDim === '3'">
<el-date-picker
v-model="weekValue1"
type="week"
format="yyyy 第 WW 周"
style="width: 170px"
:picker-options="pickerOptionsWeek"
@change="startWeek"
size="small"
placeholder="选择周"></el-date-picker>
-
<el-date-picker
v-model="weekValue2"
type="week"
format="yyyy 第 WW 周"
:picker-options="pickerOptionsWeek"
style="width: 170px"
@change="endWeek"
size="small"
placeholder="选择周"></el-date-picker>
</div>
<div v-show="queryParams.timeDim === '4'">
<el-date-picker
v-model="monthValue"
type="monthrange"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期"
value-format="timestamp"
:picker-options="pickerOptions"
size="small"
style="width: 350px"
@change="timeSelect"></el-date-picker>
</div>
<div v-show="queryParams.timeDim === '5'">
<el-date-picker
style="width: 170px"
v-model="yearValue1"
type="year"
:picker-options="pickerOptions"
value-format="timestamp"
placeholder="选择年"
size="small"
@change="startYear"></el-date-picker>
-
<el-date-picker
style="width: 170px"
v-model="yearValue2"
type="year"
:picker-options="pickerOptions"
value-format="timestamp"
placeholder="选择年"
size="small"
@change="endYear"></el-date-picker>
</div>
</el-form-item>
<el-form-item>
<el-button type="primary" size="small" @click="search">查询</el-button>
<span class="separateStyle"></span>
<el-button size="small" @click="resetBtn">重置</el-button>
<span class="separateStyle"></span>
<el-button type="primary" size="small" @click="exportData" plain>
导出
</el-button>
</el-form-item>
</el-form>
<span v-if="isFold" class="foldClass" @click="switchMode">
{{ isExpand ? '收起' : '展开' }}
<svg-icon :icon-class="isExpand ? 'upward' : 'downward'" />
</span>
</div>
</template>
<script>
import { getEnergyTypeListAll } from "@/api/base/energyType"
import { getTree } from '@/api/base/factory'
import moment from 'moment'
import { getEnergyTypeListAll } from '@/api/base/energyType';
import { getTree } from '@/api/base/factory';
import moment from 'moment';
export default {
name: 'searchArea',
props: {
isFold: {//
type: Boolean,
default: false
}
},
data() {
return {
isExpand: false, //
//
queryParams: {
energyTypeId: null,
objId: null,
timeDim: null,
startTime: null,
endTime: null
},
objArr: [],
timeValue: [],// 7
dateValue: [],// 30
weekValue1: null,//24
weekValue2: null,
monthValue: [],//24
yearValue1: null,//10
yearValue2: null,
energyTypeList: [],
objList: [],
pickerOptions: {
disabledDate(date) {
return date.getTime() > Date.now()
}
},
pickerOptionsWeek: {
disabledDate(time) {
let day = Date.now()
let limitTime = moment(day).day(-1)
return time.getTime() > new Date(limitTime).getTime()
}
}
}
},
mounted() {
this.getTypeList()
this.getObjTree()
this.queryParams.timeDim = this.getDictDatas(this.DICT_TYPE.TIME_DIM)[0].value //
this.timeValue = [moment().startOf('day'), moment().endOf('day')-59*61*1000]
},
methods: {
getTypeList() {
getEnergyTypeListAll().then((res) => {
this.energyTypeList = res.data || []
})
},
getObjTree() {
getTree().then(res => {
this.objList = res.data || []
})
},
//
timeSelect() {
switch (this.queryParams.timeDim) {
case '1':
if (this.timeValue[1] - this.timeValue[0] > 7*24*3600000) {
this.$modal.msgError('最大时间范围为7天请重新选择')
this.timeValue = []
}
break
case '2':
if (this.dateValue[1] - this.dateValue[0] > 29*24*3600000) {
this.$modal.msgError('最大时间范围为30天请重新选择') // 0:00:0023:59:59
this.dateValue = []
}
break
case '4':
if (this.monthValue[1] - this.monthValue[0] > 729*24*3600000) {
this.$modal.msgError('最大时间范围为24个月请重新选择')//
this.monthValue = []
}
break
default:
}
},
//
startYear() {
if (this.yearValue2 && this.yearValue2 < this.yearValue1) {
this.$modal.msgError('开始时间不能晚于结束时间,请重新选择')
this.yearValue1 = null
return false
}
if (this.yearValue1 && this.yearValue2) {
if (this.yearValue2 - this.yearValue1 > 10*365*24*3600000) {
this.$modal.msgError('最大时间范围为10年请重新选择')
this.yearValue1 = null
return false
}
}
},
endYear() {
if (this.yearValue2 && this.yearValue2 < this.yearValue1) {
this.$modal.msgError('结束时间不能早于开始时间,请重新选择')
this.yearValue2 = null
return false
}
if (this.yearValue1 && this.yearValue2) {
if (this.yearValue2 - this.yearValue1 > 10*365*24*3600000) {
this.$modal.msgError('最大时间范围为10年请重新选择')
this.yearValue2 = null
return false
}
}
},
//
startWeek() {
if (this.weekValue1 && this.weekValue2) {
let a = new Date(this.weekValue1).getTime()
let b = new Date(this.weekValue2).getTime()
if (a > b) {
this.$modal.msgError('开始时间不能晚于结束时间,请重新选择')
this.weekValue1 = null
return false
}
if (b - a > 167*24*3600000) {
this.$modal.msgError('最大时间范围为24周请重新选择')
this.weekValue1 = null
return false
}
}
},
endWeek() {
if (this.weekValue1 && this.weekValue2) {
let a = new Date(this.weekValue1).getTime()
let b = new Date(this.weekValue2).getTime()
if (a > b) {
this.$modal.msgError('结束时间不能早于开始时间,请重新选择')
this.weekValue2 = null
return false
}
if (b - a > 167*24*3600000) {
this.$modal.msgError('最大时间范围为24周请重新选择')
this.weekValue2 = null
return false
}
}
},
//
search() {
if (!this.queryParams.energyTypeId) {
this.$modal.msgError('请选择能源类型')
return false
}
if (this.objArr.length === 0) {
this.$modal.msgError('请选择对象')
return false
} else {
this.queryParams.objId = this.objArr[this.objArr.length-1]
}
if (!this.queryParams.timeDim) {
this.$modal.msgError('请选择时间维度')
return false
}
switch (this.queryParams.timeDim) {
case '1':
if (this.timeValue.length > 0) {
this.queryParams.startTime = this.timeValue[0]
this.queryParams.endTime = this.timeValue[1] //
} else {
this.$modal.msgError('时间范围不能为空')
return false
}
break
case '2':
if (this.dateValue.length > 0) {
this.queryParams.startTime = this.dateValue[0]
this.queryParams.endTime = this.dateValue[1] + 86399000 // 23:59:59
} else {
this.$modal.msgError('日范围不能为空')
return false
}
break
case '3':
if (this.weekValue1 && this.weekValue2) {
let a = moment(this.weekValue1).day(0).format('YYYY-MM-DD') + ' 00:00:00'
let b = moment(this.weekValue2).day(6).format('YYYY-MM-DD') + ' 23:59:59'
this.queryParams.startTime = new Date(a).getTime()
this.queryParams.endTime = new Date(b).getTime()
} else {
this.$modal.msgError('周范围不能为空')
return false
}
break
case '4'://
if (this.monthValue.length > 0) {
this.queryParams.startTime = this.monthValue[0]
this.queryParams.endTime = this.transformTime(this.monthValue[1])
} else {
this.$modal.msgError('月范围不能为空')
return false
}
break
default://
if (this.yearValue1 && this.yearValue2) {
if (this.yearValue2 < this.yearValue1) {
this.$modal.msgError('结束时间不能早于开始时间')
return false
} else {
this.queryParams.startTime = this.yearValue1
this.queryParams.endTime = this.transformYear(this.yearValue2)
}
} else {
this.$modal.msgError('年范围不能为空')
return false
}
}
this.queryParams.startTime = this.queryParams.startTime + ''
this.queryParams.endTime = this.queryParams.endTime + ''
this.$emit('submit', this.queryParams)
},
//
resetBtn() {
this.queryParams.energyTypeId = null
this.queryParams.objId = null
this.objArr = []
this.queryParams.timeDim = this.getDictDatas(this.DICT_TYPE.TIME_DIM)[0].value //
this.timeValue = [moment().startOf('day'), moment().endOf('day')-59*61*1000]
},
transformTime(timeStamp) {//
let year = moment(timeStamp).format('YYYY')
let month = moment(timeStamp).format('MM')
let newData = moment(new Date(year,month,0)).format('YYYY-MM-DD') + ' 23:59:59'
let value = new Date(newData).getTime()
return value
},
transformYear(timeStamp) {//
let year = moment(timeStamp).format('YYYY')
let newData = year+'-12-31 23:59:59'
let value = new Date(newData).getTime()
return value
},
switchMode() {//
this.isExpand = !this.isExpand
const element = this.$refs.searchBarRef
if (this.isExpand) {
element.classList.remove('divHeight')
} else {
element.classList.add('divHeight')
}
}
}
}
name: 'searchArea',
props: {
isFold: {
//
type: Boolean,
default: false,
},
},
data() {
return {
isExpand: false, //
//
queryParams: {
energyTypeId: null,
objId: null,
timeDim: null,
startTime: null,
endTime: null,
},
objArr: [],
timeValue: [], // 7
dateValue: [], // 30
weekValue1: null, //24
weekValue2: null,
monthValue: [], //24
yearValue1: null, //10
yearValue2: null,
energyTypeList: [],
objList: [],
pickerOptions: {
disabledDate(date) {
return date.getTime() > Date.now();
},
},
pickerOptionsWeek: {
disabledDate(time) {
let day = Date.now();
let limitTime = moment(day).day(-1);
return time.getTime() > new Date(limitTime).getTime();
},
},
};
},
mounted() {
this.getTypeList();
this.getObjTree();
this.queryParams.timeDim = this.getDictDatas(
this.DICT_TYPE.TIME_DIM
)[0].value; //
this.timeValue = [
moment().startOf('day'),
moment().endOf('day') - 59 * 61 * 1000,
];
},
methods: {
getTypeList() {
getEnergyTypeListAll().then((res) => {
this.energyTypeList = res.data || [];
});
},
getObjTree() {
getTree().then((res) => {
this.objList = res.data || [];
});
},
//
timeSelect() {
switch (this.queryParams.timeDim) {
case '1':
if (this.timeValue[1] - this.timeValue[0] > 7 * 24 * 3600000) {
this.$modal.msgError('最大时间范围为7天请重新选择');
this.timeValue = [];
}
break;
case '2':
if (this.dateValue[1] - this.dateValue[0] > 29 * 24 * 3600000) {
this.$modal.msgError('最大时间范围为30天请重新选择'); // 0:00:0023:59:59
this.dateValue = [];
}
break;
case '4':
if (this.monthValue[1] - this.monthValue[0] > 729 * 24 * 3600000) {
this.$modal.msgError('最大时间范围为24个月请重新选择'); //
this.monthValue = [];
}
break;
default:
}
},
//
startYear() {
if (this.yearValue2 && this.yearValue2 < this.yearValue1) {
this.$modal.msgError('开始时间不能晚于结束时间,请重新选择');
this.yearValue1 = null;
return false;
}
if (this.yearValue1 && this.yearValue2) {
if (this.yearValue2 - this.yearValue1 > 10 * 365 * 24 * 3600000) {
this.$modal.msgError('最大时间范围为10年请重新选择');
this.yearValue1 = null;
return false;
}
}
},
endYear() {
if (this.yearValue2 && this.yearValue2 < this.yearValue1) {
this.$modal.msgError('结束时间不能早于开始时间,请重新选择');
this.yearValue2 = null;
return false;
}
if (this.yearValue1 && this.yearValue2) {
if (this.yearValue2 - this.yearValue1 > 10 * 365 * 24 * 3600000) {
this.$modal.msgError('最大时间范围为10年请重新选择');
this.yearValue2 = null;
return false;
}
}
},
//
startWeek() {
if (this.weekValue1 && this.weekValue2) {
let a = new Date(this.weekValue1).getTime();
let b = new Date(this.weekValue2).getTime();
if (a > b) {
this.$modal.msgError('开始时间不能晚于结束时间,请重新选择');
this.weekValue1 = null;
return false;
}
if (b - a > 167 * 24 * 3600000) {
this.$modal.msgError('最大时间范围为24周请重新选择');
this.weekValue1 = null;
return false;
}
}
},
endWeek() {
if (this.weekValue1 && this.weekValue2) {
let a = new Date(this.weekValue1).getTime();
let b = new Date(this.weekValue2).getTime();
if (a > b) {
this.$modal.msgError('结束时间不能早于开始时间,请重新选择');
this.weekValue2 = null;
return false;
}
if (b - a > 167 * 24 * 3600000) {
this.$modal.msgError('最大时间范围为24周请重新选择');
this.weekValue2 = null;
return false;
}
}
},
//
validateData() {
if (!this.queryParams.energyTypeId) {
this.$modal.msgError('请选择能源类型');
return false;
}
if (this.objArr.length === 0) {
this.$modal.msgError('请选择对象');
return false;
} else {
this.queryParams.objId = this.objArr[this.objArr.length - 1];
}
if (!this.queryParams.timeDim) {
this.$modal.msgError('请选择时间维度');
return false;
}
switch (this.queryParams.timeDim) {
case '1':
if (this.timeValue.length > 0) {
this.queryParams.startTime = this.timeValue[0];
this.queryParams.endTime = this.timeValue[1]; //
} else {
this.$modal.msgError('时间范围不能为空');
return false;
}
break;
case '2':
if (this.dateValue.length > 0) {
this.queryParams.startTime = this.dateValue[0];
this.queryParams.endTime = this.dateValue[1] + 86399000; // 23:59:59
} else {
this.$modal.msgError('日范围不能为空');
return false;
}
break;
case '3':
if (this.weekValue1 && this.weekValue2) {
let a =
moment(this.weekValue1).day(0).format('YYYY-MM-DD') + ' 00:00:00';
let b =
moment(this.weekValue2).day(6).format('YYYY-MM-DD') + ' 23:59:59';
this.queryParams.startTime = new Date(a).getTime();
this.queryParams.endTime = new Date(b).getTime();
} else {
this.$modal.msgError('周范围不能为空');
return false;
}
break;
case '4': //
if (this.monthValue.length > 0) {
this.queryParams.startTime = this.monthValue[0];
this.queryParams.endTime = this.transformTime(this.monthValue[1]);
} else {
this.$modal.msgError('月范围不能为空');
return false;
}
break;
default: //
if (this.yearValue1 && this.yearValue2) {
if (this.yearValue2 < this.yearValue1) {
this.$modal.msgError('结束时间不能早于开始时间');
return false;
} else {
this.queryParams.startTime = this.yearValue1;
this.queryParams.endTime = this.transformYear(this.yearValue2);
}
} else {
this.$modal.msgError('年范围不能为空');
return false;
}
}
return true;
},
//
search() {
if (this.validateData()) {
this.queryParams.startTime = this.queryParams.startTime + '';
this.queryParams.endTime = this.queryParams.endTime + '';
this.$emit('submit', this.queryParams);
}
},
//
resetBtn() {
this.queryParams.energyTypeId = null;
this.queryParams.objId = null;
this.objArr = [];
this.queryParams.timeDim = this.getDictDatas(
this.DICT_TYPE.TIME_DIM
)[0].value; //
this.timeValue = [
moment().startOf('day'),
moment().endOf('day') - 59 * 61 * 1000,
];
},
transformTime(timeStamp) {
//
let year = moment(timeStamp).format('YYYY');
let month = moment(timeStamp).format('MM');
let newData =
moment(new Date(year, month, 0)).format('YYYY-MM-DD') + ' 23:59:59';
let value = new Date(newData).getTime();
return value;
},
transformYear(timeStamp) {
//
let year = moment(timeStamp).format('YYYY');
let newData = year + '-12-31 23:59:59';
let value = new Date(newData).getTime();
return value;
},
switchMode() {
//
this.isExpand = !this.isExpand;
const element = this.$refs.searchBarRef;
if (this.isExpand) {
element.classList.remove('divHeight');
} else {
element.classList.add('divHeight');
}
},
exportData() {
if (this.validateData()) {
this.queryParams.startTime = this.queryParams.startTime + '';
this.queryParams.endTime = this.queryParams.endTime + '';
this.$emit('exportD', this.queryParams);
}
},
},
};
</script>
<style lang='scss'>
<style lang="scss">
/* 级联选择器 */
.cascaderParent .el-cascader-panel .el-scrollbar:first-child .el-radio {
display: none;
display: none;
}
/* 时间整点 */
.noneMinute .el-time-spinner__wrapper {
width: 100%;
width: 100%;
}
.noneMinute .el-scrollbar:nth-of-type(2) {
display: none;
display: none;
}
.demo-form-inline {
.el-date-editor .el-range__icon {
font-size: 16px;
color: #0B58FF;
}
.el-input__prefix .el-icon-date {
font-size: 16px;
color: #0B58FF;
}
.el-date-editor .el-range__icon {
font-size: 16px;
color: #0b58ff;
}
.el-input__prefix .el-icon-date {
font-size: 16px;
color: #0b58ff;
}
}
</style>
<style lang="scss" scoped>
.demo-form-inline {
.blue-block {
display: inline-block;
width: 4px;
height: 16px;
background-color: #0B58FF;
border-radius: 1px;
margin-right: 8px;
margin-top: 12px;
}
.blue-block {
display: inline-block;
width: 4px;
height: 16px;
background-color: #0b58ff;
border-radius: 1px;
margin-right: 8px;
margin-top: 12px;
}
}
.searchBarBox .foldClass {
position: absolute;
top: 14px;
right: 0;
cursor: pointer;
font-size: 12px;
color:#0B58FF;
position: absolute;
top: 14px;
right: 0;
cursor: pointer;
font-size: 12px;
color: #0b58ff;
}
.searchBarBox .foldClass .iconfont {
font-size: 14px;
font-size: 14px;
}
.divHeight {
height: 45px;
overflow: hidden;
height: 45px;
overflow: hidden;
}
.separateStyle {
display: inline-block;
width: 1px;
height: 24px;
background: #E8E8E8;
vertical-align: middle;
margin: 0 10px;
display: inline-block;
width: 1px;
height: 24px;
background: #e8e8e8;
vertical-align: middle;
margin: 0 10px;
}
</style>
</style>

View File

@ -1,94 +1,104 @@
<!--
* @Author: zwq
* @Date: 2024-07-01 14:53:55
* @LastEditors: zwq
* @LastEditTime: 2024-09-26 10:47:36
* @Description:
-->
<template>
<div class="app-container trendAnalysisBox" id="trendAnalysisBox">
<!-- 搜索工作栏 -->
<search-area :isFold="isFold" @submit="getList"/>
<el-tabs v-model="activeName" @tab-click="switchChart" v-show='chartData.length'>
<el-tab-pane label="柱状图" name="bar">
<bar-chart ref="analysisBarChart" :chartData="chartData" :timeDim="timeDim"/>
</el-tab-pane>
<el-tab-pane label="折线图" name="line">
<line-chart ref="analysisLineChart" :chartData="chartData" :timeDim="timeDim"/>
</el-tab-pane>
</el-tabs>
<search-area :isFold="isFold" @submit="getList" @exportD="exportData"/>
<div v-show="chartData.length">
<base-table
:table-props="tableProps"
:table-data="list"
class="trend-out-table" />
<line-chart
ref="analysisLineChart"
:chartData="chartData"
:timeDim="timeDim" />
</div>
<!-- 没有数据 -->
<div class="no-data-bg" v-show='!chartData.length'></div>
</div>
</template>
<script>
import { getEnergyTrend } from "@/api/analysis/energyAnalysis"
import { getEnergyTrend, exportTrend } from "@/api/analysis/energyAnalysis"
import SearchArea from "./components/searchArea"
import BarChart from "./components/barChart"
import LineChart from "./components/lineChart"
// import moment from 'moment'
export default {
name: 'TrendAnalysis',
components: { SearchArea, BarChart, LineChart },
components: { SearchArea, LineChart },
data() {
return {
isFold: false,
activeName: 'bar',
chartData: [],
timeDim: ''
timeDim: '',
tableProps: [],
list: [],
}
},
mounted() {
window.addEventListener('resize', () => {
this.tableH = this.tableHeight(260)
this.isFold = this.searchBarWidth('trendAnalysisBox', 1263)
this.isFold = this.searchBarWidth('trendAnalysisBox', 1146)
})
this.isFold = this.searchBarWidth('trendAnalysisBox', 1263)
this.isFold = this.searchBarWidth('trendAnalysisBox', 1146)
},
methods: {
getList(params) {
this.timeDim = params.timeDim
getEnergyTrend({ ...params }).then((res) => {
if (res.code === 0) {
this.chartData = res.data
this.getTableList(res.data || []);
this.chartData = res.data || [];
} else {
this.chartData = []
}
})
},
switchChart() {
if (this.activeName === 'bar') {
this.$nextTick((res) => {
this.$refs.analysisBarChart.getChart()
})
} else {
this.$nextTick((res) => {
this.$refs.analysisLineChart.getChart()
})
}
getTableList(arr) {
this.tableProps = [];
this.list = [];
let tempX = [];
let listObj = { useNum: '消耗量' }; //
for (let i = 0; i < arr.length; i++) {
let obj = {};
if (this.timeDim === '3') {
let fName = arr[i].time.slice(0, 4);
let lName = arr[i].time.slice(4, 6);
obj.label = fName + ' 第 ' + lName + ' 周';
} else {
obj.label = arr[i].time;
}
obj.prop = arr[i].time;
obj.minWidth = 100;
tempX.push(obj);
listObj[arr[i].time] = arr[i].useNum || null;
}
this.tableProps = [{ prop: 'useNum', label: '时间' }].concat(tempX);
this.list.push(listObj);
},
/** 导出按钮操作 */
exportData(val) {
//
this.$modal.confirm('是否确认导出走势分析数据?').then(() => {
this.exportLoading = true;
return exportTrend(val);
}).then(response => {
this.$download.excel(response, '走势分析数据.xlsx');
this.exportLoading = false;
}).catch(() => {});
}
}
}
</script>
<style lang='scss'>
.trendAnalysisBox {
.el-tabs__nav::after {
content: "";
position: absolute;
left: 0;
bottom: 0;
width: 100%;
height: 2px;
background-color: #e4e7ed;
/* z-index: 1; */
}
.el-tabs__nav-wrap::after {
width: 0;
}
.el-tabs__item {
padding: 0 10px;
}
.el-tabs__item:hover {
color: rgba(0, 0, 0, 0.85);
}
.el-tabs__item.is-active {
color: rgba(0, 0, 0, 0.85);
}
.el-tabs__item {
color: rgba(0, 0, 0, 0.45);
}
.trend-out-table {
margin-bottom: 15px;
}
}
</style>
</style>

View File

@ -125,14 +125,26 @@ export default {
this.$emit('submit', this.queryParams)
},
exportData() {
let name
if (this.queryParams.objId) {
name = this.getObjName(this.objList, this.queryParams.objId)
if (this.objArr.length === 0) {
this.$modal.msgError('请选择对象')
return false
} else {
this.$modal.msgWarning("对象不能为空")
this.queryParams.objId = this.objArr[this.objArr.length-1]
}
if (!this.queryParams.type) {
this.$modal.msgError('请选择时间维度')
return false
}
this.$emit('exportD', {name: name})
if (!this.queryParams.searchTime) {
this.$modal.msgError('请选择时间')
return false
}
if (this.queryParams.type === 3) {
this.queryParams.searchTime = this.transformTime(this.yearMonth) + ''
} else {
this.queryParams.searchTime = this.transformYear(this.yearValue) + ''
}
this.$emit('exportD', this.queryParams)
},
// name
getObjName(list, id) {
@ -202,4 +214,4 @@ export default {
background: #E8E8E8;
vertical-align: middle;
}
</style>
</style>

View File

@ -20,7 +20,7 @@
</div>
</template>
<script>
import { getYoy } from "@/api/analysis/energyAnalysis"
import { getYoy,exportYoy } from "@/api/analysis/energyAnalysis"
import subRate from "./components/subRate.vue"
import SearchArea from "./components/searchArea"
import LineChart from "./components/lineChart"
@ -101,26 +101,14 @@ export default {
this.chartData = this.list
},
exportData(val) {
if (this.list.length > 0) {
var wb = XLSX.utils.table_to_book(document.querySelector(".yoy-out-table"))
let fileName = val.name + "同比分析.xlsx"
var wbout = XLSX.write(wb, {
bookType: "xlsx",
bookSST: true,
type: "array"
})
try {
FileSaver.saveAs(
new Blob([wbout], { type: "application/octet-stream" }),
fileName
)
} catch (e) {
if (typeof console !== "undefined") console.log(e, wbout);
}
return wbout
} else {
this.$modal.msgWarning("暂无数据导出")
}
//
this.$modal.confirm('是否确认导出同比分析数据?').then(() => {
this.exportLoading = true;
return exportYoy(val);
}).then(response => {
this.$download.excel(response, '同比分析数据.xlsx');
this.exportLoading = false;
}).catch(() => {});
}
}
}
@ -140,4 +128,4 @@ export default {
margin-right: 8px;
vertical-align: bottom;
}
</style>
</style>

View File

@ -0,0 +1,430 @@
<!--
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]" :disabled="disabled"
@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('selectupdate', 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"
:disabled="col.disabled ? col.disabled : disabled" :placeholder="`请选择${col.label}`" value-format="timestamp"
@change="$emit('update', form)" v-bind="col.bind">
</el-date-picker>
<el-switch v-if="col.switch" v-model="form[col.prop]" :disabled="disabled" active-color="#0b58ff"
inactive-color="#e1e1e1" @change="$emit('update', form)" v-bind="col.bind"></el-switch>
<component v-if="col.subcomponent" :key="col.key" :disabled="disabled" :read-only="disabled"
:is="col.subcomponent" v-model="form[col.prop]" :inlineStyle="col.style" @on-change="$emit('update', form)"
v-bind="col.bind"></component>
<div class="upload-area" :class="uploadOpen ? '' : 'height-48'" ref="uploadArea" :key="col.prop"
v-if="col.upload">
<span class="close-icon" :class="uploadOpen ? 'open' : ''">
<el-button type="text" icon="el-icon-arrow-right" @click="handleFilesOpen" />
</span>
<!-- :file-list="uploadedFileList" -->
<el-upload class="upload-in-dialog" v-if="col.upload" :key="col.prop + '__el-upload'" :action="uploadUrl"
:headers="uploadHeaders" :show-file-list="false" icon="el-icon-upload2" :disabled="disabled"
:before-upload="beforeUpload" :on-success="
(response, file, fileList) => {
handleUploadSuccess(response, file, col.prop);
}
" v-bind="col.bind">
<el-button size="mini" :disabled="col.bind?.disabled || false">
<svg-icon icon-class="icon-upload" style="color: inherit"></svg-icon>
上传文件
</el-button>
<div class="el-upload__tip" slot="tip" v-if="col.uploadTips">
{{ col.uploadTips || '只能上传jpg/png文件, 大小不超过2MB' }}
</div>
</el-upload>
<uploadedFile class="file" v-for="file in form[col.prop]" :file="file" :key="file.fileUrl"
@delete="!disabled && handleDeleteFile(file, col.prop)" />
</div>
</el-form-item>
</el-col>
</el-row>
</el-form>
</template>
<script>
import { getAccessToken } from '@/utils/auth';
import tupleImg from '@/assets/images/tuple.png';
import cache from '@/utils/cache';
/**
* 找到最长的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;
if (opt.label.includes('(')) {
max = max - 3
}
}
});
});
return max;
}
const uploadedFile = {
name: 'UploadedFile',
props: ['file'],
data() {
return {};
},
methods: {
handleDelete() {
this.$emit('delete', this.file);
},
async handleDownload() {
const data = await this.$axios({
url: this.file.fileUrl,
method: 'get',
responseType: 'blob',
});
await this.$message.success('开始下载');
// create download link
const url = window.URL.createObjectURL(data);
const link = document.createElement('a');
link.href = url;
link.download = this.file.fileName;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
},
},
mounted() {},
render: function (h) {
return (
<div
title={this.file.fileName}
onClick={this.handleDownload}
style={{
background: `url(${tupleImg}) no-repeat`,
backgroundSize: '14px',
backgroundPosition: '0 55%',
paddingLeft: '20px',
paddingRight: '24px',
textOverflow: 'ellipsis',
whiteSpace: 'nowrap',
overflow: 'hidden',
cursor: 'pointer',
display: 'inline-block',
}}>
{this.file.fileName}
<el-button
type="text"
icon="el-icon-close"
style="float: right; position: relative; top: 2px; left: 8px; z-index: 100"
class="dialog__upload_component__close"
onClick={this.handleDelete}
/>
</div>
);
},
};
export default {
name: 'DialogForm',
model: {
prop: 'dataForm',
event: 'update',
},
emits: ['update'],
components: { uploadedFile },
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 {
uploadOpen: false,
form: {},
formLoading: true,
optionListOf: {},
uploadedFileList: [],
dataLoaded: false,
uploadHeaders: { Authorization: 'Bearer ' + getAccessToken() },
uploadUrl: process.env.VUE_APP_BASE_API + '/admin-api/infra/file/upload', // headersurl
};
},
computed: {
labelWidth() {
let max = findMaxLabelWidth(this.rows);
// 20px
return max * 20;
// return max * 20 + 'px';
},
},
watch: {
rows: {
handler() {
this.$nextTick(() => {
this.handleOptions('watch');
});
},
deep: true,
immediate: false,
},
dataForm: {
handler(val) {
this.form = JSON.parse(JSON.stringify(val));
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() {
// 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) {
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: false,
}
);
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;
if (opt.cache) {
cache.store(opt.cache, list);
}
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;
// dataFormcodebug
this.$emit('update', this.form);
}
});
}
}
});
});
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, prop) {
console.log('[handleUploadSuccess]', response, file, prop);
this.form[prop].push({
fileName: file.name,
fileUrl: response.data,
fileType: prop == 'files' ? 2 : 1,
});
this.$modal.msgSuccess('上传成功');
this.$emit('update', this.form);
},
getFileName(fileUrl) {
return fileUrl.split('/').pop();
},
handleFilesOpen() {
this.uploadOpen = !this.uploadOpen;
},
handleDeleteFile(file, prop) {
this.form[prop] = this.form[prop].filter(
(item) => item.fileUrl != file.fileUrl
);
this.$emit('update', this.form);
},
},
};
</script>
<style scoped lang="scss">
.el-date-editor,
.el-select {
width: 100%;
}
.upload-area {
// background: #ccc;
// display: grid;
// grid-auto-rows: 34px;
// grid-template-columns: repeat(6, minmax(32px, max-content));
// gap: 8px;
// align-items: center;
position: relative;
overflow: hidden;
transition: height 0.3s ease-out;
}
.upload-in-dialog {
// display: inline-block;
margin-right: 24px;
// background: #ccc;
position: relative;
// top: -13px;
float: left;
}
.close-icon {
// background: #ccc;
position: absolute;
top: 0;
right: 12px;
z-index: 100;
transition: transform 0.3s ease-out;
}
.close-icon.open {
transform: rotateZ(90deg);
}
</style>
<style>
.dialog__upload_component__close {
color: #ccc;
}
.dialog__upload_component__close:hover {
/* color: #777; */
color: red;
}
.height-48 {
height: 35px !important;
}
</style>

View File

@ -252,7 +252,7 @@ export default {
computed: {},
created() {
this.fillLineOptions();
this.fillProductOptions();
// this.fillProductOptions();
},
mounted() {
// window.addEventListener('resize', () => {
@ -284,23 +284,23 @@ export default {
);
},
async fillProductOptions() {
const { data } = await this.$axios({
url: '/base/core-product/listAll',
method: 'get',
});
const cfg = this.searchBarFormConfig.find(
(item) => item.__index == 'product'
);
this.$set(
cfg,
'selectOptions',
data.map((item) => ({
id: item.id,
name: item.name,
}))
);
},
// async fillProductOptions() {
// const { data } = await this.$axios({
// url: '/base/core-product/listAll',
// method: 'get',
// });
// const cfg = this.searchBarFormConfig.find(
// (item) => item.__index == 'product'
// );
// this.$set(
// cfg,
// 'selectOptions',
// data.map((item) => ({
// id: item.id,
// name: item.name,
// }))
// );
// },
async getList() {
const { data } = await this.$axios({

View File

@ -6,84 +6,60 @@
* @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-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-row :gutter="20">
<el-col :span="8">
<div class="blodTip">巡检单名称</div>
<div class="lightTip">{{ dataForm.name }}</div>
</el-col>
<el-col :span="8">
<el-col :span="8">
<div class="blodTip">部门</div>
<div class="lightTip">{{ dataForm.department }}</div>
</el-col>
<el-col :span="8">
<div class="blodTip">巡检时间</div>
<el-col :span="8">
<div class="blodTip">计划巡检时间</div>
<div class="lightTip">{{ parseTime(dataForm.planCheckTime) }}</div>
</el-col>
</el-row>
</div>
</div>
<el-divider />
<el-divider />
<div class="attr-list">
<small-title
style="margin: 16px 0; padding-left: 8px"
:no-padding="true">
巡检内容
</small-title>
<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>
<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>
<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">
<!-- <div class="drawer-body__footer">
<el-button type="primary" @click="goback()">关闭</el-button>
</div> -->
</div>
</div>
</div>
</div>
<attr-add
v-if="addOrUpdateVisible"
ref="addOrUpdate"
:order-id="dataForm.id"
@refreshDataList="getList" />
</el-drawer>
<attr-add v-if="addOrUpdateVisible" ref="addOrUpdate" :order-id="dataForm.id" @refreshDataList="getList" />
</el-drawer>
</template>
<script>
@ -111,8 +87,13 @@ const tableProps = [
},
{
prop: 'program',
label: '检查项目',
}
label: '巡检项目',
},
{
prop: 'checkResult',
label: '巡检结果',
},
];
export default {

View File

@ -36,7 +36,7 @@ const tableProps = [
align:'center',
},
{
prop: 'maintainResult',
prop: 'checkResult',
label: '默认巡检结果',
align: 'center',
},
@ -102,7 +102,8 @@ export default {
getDataList(id) {
this.dataListLoading = true;
this.queryParams.equipmentTypeId = id
this.urlOptions.getDataListURL(this.listQuery).then(response => {
console.log(id);
this.urlOptions.getDataListURL(this.queryParams).then(response => {
this.tableData = response.data.list;
this.listQuery.total = response.data.total;
this.dataListLoading = false

View File

@ -6,55 +6,32 @@
-->
<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="maintainOrderNumber"
:rules="[
<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="maintainOrderNumber" :rules="[
{ required: true, message: '请输入设备保养单号', trigger: 'blur' },
]">
<el-input
v-model="form.maintainOrderNumber"
@change="$emit('update', form)"
:placeholder="`请输入保养计划单号`"
:disabled="disabled" />
</el-form-item>
</el-col>
<el-input v-model="form.maintainOrderNumber" @change="$emit('update', form)" :placeholder="`请输入保养计划单号`"
:disabled="disabled" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="保养计划名称" prop="name">
<el-input value="---" disabled />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="保养计划名称" prop="name">
<el-input value="---" disabled />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item
label="部门"
prop="departmentId"
:rules="[{ required: true, message: '请选择部门', trigger: 'blur' }]">
<el-select
v-model="form.departmentId"
:placeholder="`请选择部门`"
:disabled="disabled"
clearable
filterable
@change="$emit('update', form)">
<el-option
v-for="opt in departmentOptions"
:key="opt.value"
:label="opt.label"
:value="opt.value" />
</el-select>
</el-form-item>
<el-col :span="12">
<el-form-item label="部门" prop="departmentId" :rules="[{ required: true, message: '请选择部门', trigger: 'blur' }]">
<el-select v-model="form.departmentId" :placeholder="`请选择部门`" :disabled="disabled" clearable filterable
@change="$emit('update', form)">
<el-option v-for="opt in departmentOptions" :key="opt.value" :label="opt.label" :value="opt.value" />
</el-select>
</el-form-item>
<!-- <el-form-item
<!-- <el-form-item
label="设备大类"
prop="equipmentCategory"
:rules="[
@ -72,89 +49,59 @@
:value="opt.value" />
</el-select>
</el-form-item> -->
</el-col>
</el-col>
<el-col :span="12">
<el-form-item
label="产线"
prop="lineId"
:rules="[{ required: true, message: '请选择产线', trigger: 'blur' }]">
<el-select
v-model="form.lineId"
:placeholder="`请选择产线`"
:disabled="disabled"
clearable
filterable
@change="$emit('update', form)">
<el-option
v-for="opt in lineOptions"
: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="lineId" :rules="[{ required: true, message: '请选择产线', trigger: 'blur' }]">
<el-select v-model="form.lineId" :placeholder="`请选择产线`" :disabled="disabled" clearable filterable
@change="$emit('update', form)">
<el-option v-for="opt in lineOptions" :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="maintainer">
<el-input value="---" disabled />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="计划保养人员" prop="maintainer">
<el-input value="---" disabled />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="计划开始时间" prop="planStartTime">
<el-input value="---" disabled />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="计划开始时间" prop="planStartTime">
<el-input value="---" disabled />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="计划结束时间" prop="planEndTime">
<el-input value="---" disabled />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="计划结束时间" prop="planEndTime">
<el-input value="---" disabled />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item
label="实际开始时间"
prop="startTime"
:rules="[
<el-col :span="12">
<el-form-item label="实际开始时间" prop="startTime" :rules="[
{ required: true, message: '请选择实际开始时间', trigger: 'blur' },
]">
<el-date-picker
v-model="form.startTime"
type="datetime"
:disabled="edit"
placeholder="请选择实际开始时间"
@change="$emit('update', form)"
value-format="timestamp"></el-date-picker>
</el-form-item>
</el-col>
<el-date-picker v-model="form.startTime" type="datetime" :disabled="edit" placeholder="请选择实际开始时间"
@change="$emit('update', form)" value-format="timestamp"></el-date-picker>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item
label="实际结束时间"
prop="endTime"
:rules="[
<el-col :span="12">
<el-form-item label="实际结束时间" prop="endTime" :rules="[
{ required: true, message: '请选择实际结束时间', trigger: 'blur' },
]">
<el-date-picker
v-model="form.endTime"
type="datetime"
:disabled="edit"
placeholder="请选择实际结束时间"
@change="$emit('update', form)"
value-format="timestamp"></el-date-picker>
</el-form-item>
</el-col>
<el-date-picker v-model="form.endTime" type="datetime" :disabled="edit" placeholder="请选择实际结束时间"
@change="$emit('update', form)" value-format="timestamp"></el-date-picker>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item
label="实际保养人员"
prop="maintainWorker"
:rules="[
{ required: false, message: '请选择实际保养人员', trigger: 'blur' },
<el-col :span="12">
<el-form-item label="实际保养人员" prop="maintainWorker" :rules="[
{ required: false, message: '请输入实际保养人员', trigger: 'blur' },
]">
<el-select
<el-input v-model="form.maintainWorker" @change="$emit('update', form)" :placeholder="`请输入实际保养人员`" :disabled="disabled" />
<!-- <el-select
v-model="form.maintainWorker"
:placeholder="`请选择实际保养人员`"
:disabled="disabled"
@ -167,21 +114,17 @@
:key="opt.value"
:label="opt.label"
:value="opt.value" />
</el-select>
</el-form-item>
</el-col>
</el-select> -->
</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>
<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>
@ -321,7 +264,6 @@ export default {
const urls = [
'/base/core-production-line/listAll',
'/system/dept/list-all-simple',
'/base/core-worker/listAll',
];
let res;
switch (source) {
@ -329,10 +271,6 @@ export default {
res = await this.$axios(urls[1]);
this.departmentList = res.data || [];
break;
case 'maintainer':
res = await this.$axios(urls[2]);
this.maintainerList = res.data || [];
break;
case 'line':
res = await this.$axios(urls[0]);
this.lineList = res.data || [];

View File

@ -6,177 +6,116 @@
-->
<template>
<el-drawer
:visible.sync="visible"
:show-close="false"
:wrapper-closable="true"
class="drawer"
custom-class="mes-drawer"
size="60%"
:before-close="beforeClose"
@closed="$emit('destroy')">
<SmallTitle slot="title">编辑</SmallTitle>
<el-drawer :visible.sync="visible" :show-close="false" :wrapper-closable="true" class="drawer"
custom-class="mes-drawer" size="60%" :before-close="beforeClose" @closed="$emit('destroy')">
<SmallTitle slot="title">编辑</SmallTitle>
<div class="drawer-body flex">
<div class="drawer-body__content">
<div class="form-part" style="margin-bottom: 32px">
<!-- <el-skeleton v-if="!showForm" animated /> -->
<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="maintainOrderNumber">
<!-- :rules="[
<div class="drawer-body flex">
<div class="drawer-body__content">
<div class="form-part" style="margin-bottom: 32px">
<!-- <el-skeleton v-if="!showForm" animated /> -->
<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="maintainOrderNumber">
<!-- :rules="[
{
required: true,
message: '请输入保养计划单号',
trigger: 'blur',
},
]" -->
<el-input
v-model="form.maintainOrderNumber"
disabled
:placeholder="`请输入保养计划单号`" />
</el-form-item>
</el-col>
<el-input v-model="form.maintainOrderNumber" disabled :placeholder="`请输入保养计划单号`" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="保养计划名称" prop="planName">
<el-input
v-model="form.planName"
placeholder="请输入保养计划名称"
disabled />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="保养计划名称" prop="planName">
<el-input v-model="form.planName" placeholder="请输入保养计划名称" disabled />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="部门" prop="departmentId">
<!-- :rules="[
<el-col :span="8">
<el-form-item label="部门" prop="departmentId">
<!-- :rules="[
{ required: true, message: '请选择部门', trigger: 'blur' },
]" -->
<el-select
v-model="form.departmentId"
:placeholder="`请选择部门`"
clearable
disabled
filterable>
<el-option
v-for="opt in departmentOptions"
:key="opt.value"
:label="opt.label"
:value="opt.value" />
</el-select>
</el-form-item>
</el-col>
<el-select v-model="form.departmentId" :placeholder="`请选择部门`" clearable disabled filterable>
<el-option v-for="opt in departmentOptions" :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="lineId">
<!-- :rules="[
<el-col :span="8">
<el-form-item label="产线" prop="lineId">
<!-- :rules="[
{ required: true, message: '请选择产线', trigger: 'blur' },
]" -->
<el-select
v-model="form.lineId"
:placeholder="`请选择产线`"
disabled
clearable
filterable>
<el-option
v-for="opt in lineOptions"
:key="opt.value"
:label="opt.label"
:value="opt.value" />
</el-select>
</el-form-item>
</el-col>
<el-select v-model="form.lineId" :placeholder="`请选择产线`" disabled clearable filterable>
<el-option v-for="opt in lineOptions" :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="maintainer">
<el-select
v-model="form.planMaintainWorker"
placeholder="请选择计划保养人员"
disabled
clearable
filterable />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="计划保养人员" prop="maintainer">
<el-select v-model="form.planMaintainWorker" placeholder="请选择计划保养人员" disabled clearable filterable />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="计划开始时间" prop="planStartTime">
<el-date-picker
v-model="form.planStartTime"
type="datetime"
disabled
placeholder="请选择计划开始时间"
value-format="timestamp"></el-date-picker>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="计划开始时间" prop="planStartTime">
<el-date-picker v-model="form.planStartTime" type="datetime" disabled placeholder="请选择计划开始时间"
value-format="timestamp"></el-date-picker>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="计划结束时间" prop="planEndTime">
<el-date-picker
v-model="form.planEndTime"
type="datetime"
disabled
placeholder="请选择计划结束时间"
value-format="timestamp"></el-date-picker>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="计划结束时间" prop="planEndTime">
<el-date-picker v-model="form.planEndTime" type="datetime" disabled placeholder="请选择计划结束时间"
value-format="timestamp"></el-date-picker>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item
label="实际开始时间"
prop="startTime"
:rules="[
<el-col :span="8">
<el-form-item label="实际开始时间" prop="startTime" :rules="[
{
required: true,
message: '请选择实际开始时间',
trigger: 'blur',
},
]">
<el-date-picker
v-model="form.startTime"
type="datetime"
placeholder="请选择实际开始时间"
value-format="timestamp"></el-date-picker>
</el-form-item>
</el-col>
<el-date-picker v-model="form.startTime" type="datetime" placeholder="请选择实际开始时间"
value-format="timestamp"></el-date-picker>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item
label="实际结束时间"
prop="endTime"
:rules="[
<el-col :span="8">
<el-form-item label="实际结束时间" prop="endTime" :rules="[
{
required: true,
message: '请选择实际结束时间',
trigger: 'blur',
},
]">
<el-date-picker
v-model="form.endTime"
type="datetime"
placeholder="请选择实际结束时间"
value-format="timestamp"></el-date-picker>
</el-form-item>
</el-col>
<el-date-picker v-model="form.endTime" type="datetime" placeholder="请选择实际结束时间"
value-format="timestamp"></el-date-picker>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item
label="实际保养人员"
prop="maintainWorker"
:rules="[
<el-col :span="8">
<el-form-item label="实际保养人员" prop="maintainWorker" :rules="[
{
required: false,
message: '请选择实际保养人员',
message: '请输入实际保养人员',
trigger: 'blur',
},
]">
<el-select
<el-input v-model="form.maintainWorker" :placeholder="`请输入实际保养人员`" />
<!-- <el-select
v-model="form.maintainWorker"
:placeholder="`请选择实际保养人员`"
multiple
@ -187,89 +126,62 @@
:key="opt.value"
:label="opt.label"
:value="opt.value" />
</el-select>
</el-form-item>
</el-col>
</el-select> -->
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" :placeholder="`请输入备注`" />
</el-form-item>
</el-col>
</el-row>
</el-form>
</div>
<el-col :span="24">
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" :placeholder="`请输入备注`" />
</el-form-item>
</el-col>
</el-row>
</el-form>
</div>
<SmallTitle>保养内容</SmallTitle>
<SmallTitle>保养内容</SmallTitle>
<div style="margin-top: 12px; position: relative">
<SearchBar
:formConfigs="searchBarFormConfig"
ref="attr-search-bar"
@headBtnClick="handleSearchBarBtnClick" />
</div>
<div style="margin-top: 12px; position: relative">
<SearchBar :formConfigs="searchBarFormConfig" ref="attr-search-bar" @headBtnClick="handleSearchBarBtnClick" />
</div>
<div style="margin-top: 12px; position: relative">
<div 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="attrTableProps"
:page="attrQuery?.params.pageNo || 1"
:limit="attrQuery?.params.pageSize || 10"
:table-data="attrList"
@emitFun="handleEmitFun">
<method-btn
slot="handleBtn"
label="操作"
:method-list="tableBtn"
@clickBtn="handleTableBtnClick" />
</base-table>
<div style="margin-top: 12px; position: relative">
<div 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="attrTableProps" :page="attrQuery?.params.pageNo || 1"
:limit="attrQuery?.params.pageSize || 10" :table-data="attrList" @emitFun="handleEmitFun">
<method-btn slot="handleBtn" label="操作" :method-list="tableBtn" @clickBtn="handleTableBtnClick" />
</base-table>
<!-- 分页组件 -->
<pagination
v-show="attrTotal > 0"
:total="attrTotal"
:page.sync="attrQuery.params.pageNo"
:limit.sync="attrQuery.params.pageSize"
@pagination="getAttrList" />
</div>
</div>
<!-- 分页组件 -->
<pagination v-show="attrTotal > 0" :total="attrTotal" :page.sync="attrQuery.params.pageNo"
:limit.sync="attrQuery.params.pageSize" @pagination="getAttrList" />
</div>
</div>
<div class="drawer-body__footer">
<el-button style="" @click="handleCancel">取消</el-button>
<el-button type="primary" @click="handleConfirm">保存</el-button>
<!-- sections的第二项必须是 属性列表 -->
<!-- <el-button
<div class="drawer-body__footer">
<el-button style="" @click="handleCancel">取消</el-button>
<el-button type="primary" @click="handleConfirm">保存</el-button>
<!-- sections的第二项必须是 属性列表 -->
<!-- <el-button
v-if="sections[1].allowAdd"
type="primary"
@click="handleAddAttr">
添加属性
</el-button> -->
</div>
</div>
</div>
</div>
<!-- 属性对话框 -->
<base-dialog
: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"
v-model="attrForm"
:rows="attrRows" />
</base-dialog>
</el-drawer>
<!-- 属性对话框 -->
<base-dialog :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" v-model="attrForm" :rows="attrRows" />
</base-dialog>
</el-drawer>
</template>
<script>
@ -541,7 +453,7 @@ export default {
const urls = [
'/base/core-production-line/listAll',
'system/dept/list-all-simple',
'/base/core-worker/listAll',
// '/base/core-worker/listAll',
];
let res;
switch (source) {
@ -549,10 +461,10 @@ export default {
res = await this.$axios(urls[1]);
this.departmentList = res.data || [];
break;
case 'maintainer':
res = await this.$axios(urls[2]);
this.maintainerList = res.data || [];
break;
// case 'maintainer':
// res = await this.$axios(urls[2]);
// this.maintainerList = res.data || [];
// break;
case 'line':
res = await this.$axios(urls[0]);
this.lineList = res.data || [];

View File

@ -105,14 +105,16 @@
<el-form-item label="实际保养人员" prop="maintainWorker" :rules="[
{
required: false,
message: '请选择实际保养人员',
message: '请输入实际保养人员',
trigger: 'blur',
},
]">
<el-select v-model="form.maintainWorker" :placeholder="`请选择实际保养人员`" multiple clearable filterable>
<el-input v-model="form.maintainWorker" :placeholder="`请输入实际保养人员`" />
<!-- <el-select v-model="form.maintainWorker" :placeholder="`请选择实际保养人员`" multiple clearable filterable>
<el-option v-for="opt in maintainerOptions" :key="opt.value" :label="opt.label"
:value="opt.value" />
</el-select>
</el-select> -->
</el-form-item>
</el-col>
@ -445,7 +447,7 @@ export default {
method: 'put',
data: {
...this.form,
maintainWorker: this.form.maintainWorker.join(','),
maintainWorker: this.form.maintainWorker ? this.form.maintainWorker.join(',') :null,
special: false,
relatePlan: 2
}
@ -463,8 +465,8 @@ export default {
url: '/base/equipment-maintain-log/create',
method: 'post',
data: {
...this.form,
maintainWorker: this.form.maintainWorker.join(','),
...this.form,
maintainWorker: this.form.maintainWorker ? this.form.maintainWorker.join(',') : null,
special: false,
relatePlan: 2,
confirmed: false,
@ -536,7 +538,7 @@ export default {
const urls = [
'/base/core-production-line/listAll',
'/system/dept/list-all-simple',
'/base/core-worker/listAll',
// '/base/core-worker/listAll',
];
let res;
switch (source) {
@ -544,10 +546,10 @@ export default {
res = await this.$axios(urls[1]);
this.departmentList = res.data || [];
break;
case 'maintainer':
res = await this.$axios(urls[2]);
this.maintainerList = res.data || [];
break;
// case 'maintainer':
// res = await this.$axios(urls[2]);
// this.maintainerList = res.data || [];
// break;
case 'line':
res = await this.$axios(urls[0]);
this.lineList = res.data || [];

View File

@ -135,7 +135,7 @@ export default {
maintainDuration: undefined,
remark: undefined,
firstMaintenanceTime: undefined,
maintainer: undefined
maintainer: null
},
menuOptions: [],
proLineList: [],
@ -175,8 +175,8 @@ export default {
const resline = await getCorePLList();
this.proLineList = resline.data;
//
const personres = await getWorkerList()
this.personList = personres.data || []
// const personres = await getWorkerList()
// this.personList = personres.data || []
},
getList() {
//
@ -259,7 +259,8 @@ export default {
if (this.dataForm.id) {
this.urlOptions.updateURL({
...this.dataForm,
maintainer: this.dataForm.maintainer.join(',')
maintainer: this.dataForm.maintainer ? this.dataForm.maintainer.join(',') : null,
}).then(response => {
this.$modal.msgSuccess("修改成功");
this.visible = false;
@ -270,7 +271,7 @@ export default {
//
this.urlOptions.createURL({
...this.dataForm,
maintainer: this.dataForm.maintainer.join(',')
maintainer: this.dataForm.maintainer ? this.dataForm.maintainer.join(',') : null,
}).then(response => {
this.$modal.msgSuccess("新增成功");
// this.idAttrShow = true

View File

@ -17,7 +17,7 @@
<el-row :gutter="24">
<el-col :span="24">
<el-form-item label="默认保养结果" prop="resultType">
<el-select v-model="dataForm.resultType" placeholder="请选择默认保养结果">
<el-select v-model="dataForm.resultType" placeholder="请选择默认保养结果" @change="handleClear">
<el-option v-for="dict in resultList" :key="dict.id" :label="dict.name" :value="dict.id" />
</el-select>
</el-form-item>
@ -39,13 +39,16 @@
</el-col>
</el-row>
<el-row v-else-if="dataForm.resultType === 2" :gutter="24">
<el-col :span="12">
<el-col :span="11">
<el-form-item prop="minValue">
<el-input oninput="value=value.replace(/[^\-\d.]/g, '')" v-model="dataForm.minValue" placeholder="请输入最小值" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="maxValue">
<el-col :span="4">
</el-col>
<el-col :span="9">
<el-form-item prop="maxValue" label-width="20">
<el-input @change="handleChange" oninput="value=value.replace(/[^\-\d.]/g, '')" v-model="dataForm.maxValue"
placeholder="请输入最大值" />
</el-form-item>
@ -102,7 +105,9 @@ export default {
dataRule: {
// materialId: [{ required: true, message: "", trigger: "blur" }],
program: [{ required: true, message: "保养项目不能为空", trigger: "blur" }],
maintainResult: [{ required: true, message: "默认保养结果不能为空", trigger: "blur" }],
maintainResult: [{ required: true, message: "文本或数值不能为空不能为空", trigger: "blur" }],
resultType: [{ required: true, message: "默认保养结果不能为空", trigger: "blur" }],
minValue: [{ required: true, message: "最小值不能为空", trigger: "blur" }],
maxValue: [{ required: true, message: "最大值不能为空", trigger: "blur" }],
@ -114,7 +119,12 @@ export default {
this.getDict()
console.log('我看看', this.dataForm)
},
methods: {
methods: {
handleClear() {
this.dataForm.minValue = undefined
this.dataForm.maxValue = undefined
this.dataForm.maintainResult = undefined
},
async getDict() {
//
const res = await getList();

View File

@ -223,15 +223,13 @@ export default {
},
methods: {
initSearchBar() {
this.http('/base/core-equipment/page', 'get', {
special: false,
pageNo: 1,
pageSize: 999,
}).then(({ data }) => {
this.http('/base/core-equipment/listAll', 'get').then(({ data }) => {
console.log('data', data);
this.$set(
this.searchBarFormConfig[0],
'selectOptions',
(data?.list || []).map((item) => ({
(data || []).map((item) => ({
name: item.name,
id: item.id,
}))

View File

@ -184,16 +184,17 @@ export default {
],
[
{
select: true, // TODO: or INPUT instead of SELECT
input: true, // TODO: or INPUT instead of SELECT
label: '负责人',
prop: 'responsible',
url: '/base/core-worker/listAll', // TODO:
valueKey: 'name',
bind: {
filterable: true,
clearable: true,
multiple: true
},
// url: 'system/user/page', // TODO:
// valueKey: 'id',
// labelKey:'username',
// bind: {
// filterable: true,
// clearable: true,
// multiple: true
// },
},
],
[

View File

@ -37,12 +37,14 @@
@close="cancel"
@cancel="cancel"
@confirm="submitForm">
<DialogForm
<DialogFormZ
v-if="open"
ref="form"
v-model="form"
label-position="top"
:disabled="mode == 'detail'"
:has-files="false"
@selectupdate="updateDialogFormZ"
:rows="rows" />
</base-dialog>
</div>
@ -51,14 +53,16 @@
<script>
import moment from 'moment';
import basicPageMixin from '@/mixins/lb/basicPageMixin';
import DialogFormZ from '../../../DialogFormZ.vue';
import { publicFormatter } from '@/utils/dict';
import { deleteSparePart } from '@/api/equipment/base/spare-parts/list';
import { getMaterialTree, getMaterialList } from '@/api/base/material';
const timeFilter = (val) => moment(val).format('yyyy-MM-DD HH:mm:ss');
export default {
name: 'EquipmentSparePartsList',
components: {},
components: { DialogFormZ },
mixins: [basicPageMixin],
data() {
return {
@ -129,33 +133,45 @@ export default {
rows: [
[
{
input: true,
select: true,
label: '备件名称',
prop: 'name',
prop: 'productMaterialId',
url: '/base/core-product-material/listAll', // TODO:
// options: [],
bind: {
filterable: true,
clearable: false,
},
rules: [
{ required: true, message: '备件名称不能为空', trigger: 'blur' },
{
required: true,
message: '备件名称不能为空',
trigger: 'change',
},
],
},
{
input: true,
label: '备件编码',
prop: 'code',
url: '/base/equipment-spare-part/getCode',
rules: [
{ required: true, message: '备件编码不能为空', trigger: 'blur' },
],
},
],
[
{
input: true,
label: '备件型号',
prop: 'model',
},
],
[
{
input: true,
label: '备件编码',
prop: 'code',
bind: {
disabled: true,
},
},
{
input: true,
label: '规格',
prop: 'specifications',
bind: {
disabled: true,
},
},
],
[
@ -165,27 +181,32 @@ export default {
prop: 'supplierId',
url: '/base/core-supplier/listAll', // TODO:
bind: {
filterable: true,
clearable: true,
disabled: true,
},
rules: [
{ required: true, message: '供应商不能为空', trigger: 'blur' },
],
},
{
select: true,
label: '物料类型',
prop: 'type',
options: this.getDictDatas('material_type'),
// url: '/base/core-equipment/listAll', // TODO:
label: '单位',
prop: 'unit', //
bind: {
filterable: true,
clearable: true,
disabled: true,
},
rules: [
{ required: true, message: '物料类型不能为空', trigger: 'blur' },
],
options: this.getDictDatas(this.DICT_TYPE.UNIT_DICT),
},
// {
// select: true,
// label: '',
// prop: 'type',
// options: this.getDictDatas('material_type'),
// // url: '/base/core-equipment/listAll', // TODO:
// bind: {
// filterable: true,
// clearable: true,
// },
// rules: [
// { required: true, message: '', trigger: 'blur' },
// ],
// },
],
[
{
@ -201,14 +222,6 @@ export default {
},
],
},
{
select: true,
label: '单位',
prop: 'unit', //
options: this.getDictDatas(this.DICT_TYPE.UNIT_DICT),
},
],
[
{
input: true,
label: '备注',
@ -225,11 +238,23 @@ export default {
name: null,
},
//
form: {},
form: {
id: null,
code: null,
name: null,
model: null,
specifications: null,
life: null,
type: null,
supplierId: null,
unit: null,
remark: null,
},
basePath: '/base/equipment-spare-part',
mode: null,
};
},
mounted() {},
created() {
// this.initSearchBar();
this.getList();
@ -267,8 +292,8 @@ export default {
reset() {
this.form = {
id: null,
productMaterialId: null,
code: null,
name: null,
model: null,
specifications: null,
life: null,
@ -294,6 +319,7 @@ export default {
this.reset();
this.open = true;
this.title = '添加备品备件';
this.getDict();
},
/** 修改按钮操作 */
handleUpdate(row) {
@ -302,13 +328,14 @@ export default {
this.info({ id }).then((response) => {
this.form = response.data;
if (this.form.unit !== undefined) {
this.form.unit = String(this.form.unit)
this.form.unit = String(this.form.unit);
}
if (this.form.type !== undefined) {
this.form.type = String(this.form.type)
this.form.type = String(this.form.type);
}
this.open = true;
this.title = '修改备品备件';
this.getDict();
});
},
/** 提交按钮 */
@ -355,6 +382,7 @@ export default {
this.form = response.data;
this.open = true;
this.title = '修改备品备件';
this.getDict();
});
},
/** 导出按钮操作 */
@ -375,6 +403,30 @@ export default {
})
.catch(() => {});
},
async getDict() {
const materRes = await getMaterialTree(); //
let typeId = materRes.data.find((item) => item.product === 2).id;
const listQuery = {
typeId: typeId,
};
const materData = await getMaterialList(listQuery);
this.rows[0][0].options = (materData.data || []).map((item) => ({
label: item.name,
value: item.id,
...item
}));
},
updateDialogFormZ(val) {
const selectData = this.rows[0][0].options.find(
(item) => item.id === val.productMaterialId
);
this.form.productMaterialId = selectData.id;
this.form.name = selectData.name;
this.form.code = selectData.code;
this.form.specifications = selectData.specifications;
this.form.supplierId = selectData.supplierId;
this.form.unit = selectData.unit;
},
},
};
</script>

View File

@ -1,8 +1,8 @@
<!--
* @Author: zwq
* @Date: 2023-08-01 14:55:51
* @LastEditors: zhp
* @LastEditTime: 2023-11-28 10:34:24
* @LastEditors: zwq
* @LastEditTime: 2024-10-15 15:59:48
* @Description:
-->
<template>
@ -26,9 +26,11 @@ import { parseTime } from '../../core/mixins/code-filter';
import {
getProcessTraceabilityPage,
getWorkOrderList,
getCoreProduct
// exportEnergyPlcExcel
} from '@/api/quality/processTraceability';
import {
getProductMaterial,
} from '@/api/base/material';
import { publicFormatter } from '@/utils/dict';
const tableProps = [
{
@ -62,6 +64,14 @@ const tableProps = [
prop: 'actualQuantity',
label: '生产数量'
},
{
prop: 'lineName',
label: '产线名称'
},
{
prop: 'lineNum',
label: '产线预计产量'
},
{
prop: 'planProductUnit',
label: '单位',
@ -187,7 +197,7 @@ export default {
if (val.type === "processDetail") {
console.log(val);
let specificationsData =''
getCoreProduct(val.data.planProductId).then((res) => {
getProductMaterial(val.data.planProductId).then((res) => {
console.log(res)
this.$router.push({
@ -199,6 +209,7 @@ export default {
specifications: res.data.specifications,
productName: val.data.planProductName,
processFlowName: val.data.processFlowName,
lineId: val.data.lineId,
// planProductId: val.data.planProductId
// equipmentName,
},

View File

@ -185,6 +185,7 @@ export default {
pageNo: 1,
pageSize: 10,
orderId: this.$route.query.orderId,
lineId: this.$route.query.lineId,
flowDetId: [this.detId],
// orderId: this.$route.query.orderId,
@ -232,6 +233,7 @@ export default {
pageNo: 1,
pageSize: 10,
orderId: this.$route.query.orderId,
lineId: this.$route.query.lineId,
flowDetId: [this.detId],
// orderId: this.$route.query.orderId,
@ -263,6 +265,7 @@ export default {
pageNo: 1,
pageSize: 10,
orderId: this.$route.query.orderId,
lineId: this.$route.query.lineId,
flowDetId: [this.detId],
}).then((res) => {
console.log(res);

View File

@ -6,7 +6,7 @@
style="font-size: 24px; cursor: pointer"
@click="toHome" /> -->
<svg-icon
icon-class="home-alarm-white"
:icon-class="isAlarm ? 'home-alarm-white-circle' : 'home-alarm-white'"
style="font-size: 24px; cursor: pointer"
@click="toAlarm" />
</div>
@ -46,16 +46,15 @@
import moment from 'moment';
import { getUser } from '@/api/system/user.js';
import { getPath } from '@/utils/ruoyi';
import { getHomeGetAlarm } from '@/api/home';
export default {
name: 'navRight',
data() {
return {
// topDate: '',
// topTime: '',
// timeZone: '',
timer: '',
dept: ' ',
nickname: this.$store.getters.nickname,
isAlarm: false,
};
},
props: {
@ -68,21 +67,18 @@ export default {
},
created() {
this.getUserMsg();
// this.getTime();
this.getHomeGetAlarm();
this.timer = setInterval(this.getHomeGetAlarm(), 3600000);
},
beforeDestroy() {
clearInterval(this.timer);
},
// beforeDestroy() {
// clearInterval(this.timer);
// },
methods: {
// getTime() {
// let _this = this;
// this.timer = setInterval(function () {
// _this.topDate = moment().format('YYYY/MM/DD');
// let temp = moment().format('A-hh:mm').split('-');
// _this.timeZone = temp[0];
// _this.topTime = temp[1];
// }, 1000);
// },
getHomeGetAlarm() {
getHomeGetAlarm().then((response) => {
this.isAlarm = response.data || false;
});
},
getUserMsg() {
let id = this.$store.getters.userId;
getUser(id).then((res) => {

View File

@ -3,50 +3,47 @@
<div>
<navbar />
</div>
<div class="date-tabs">
<el-tabs v-model="activeName" :stretch="true">
<el-tab-pane
:label="'\u2002\u2002日\u2002\u2002'"
name="日"></el-tab-pane>
<el-tab-pane
:label="'\u2002\u2002周\u2002\u2002'"
name="周"></el-tab-pane>
<el-tab-pane
:label="'\u2002\u2002月\u2002\u2002'"
name="月"></el-tab-pane>
<el-tab-pane
:label="'\u2002\u2002年\u2002\u2002'"
name="年"></el-tab-pane>
</el-tabs>
<div class="current-date">(6.13-6.20)</div>
<div class="current-time">
<span style="display: inline-block; margin-right: 16px">
{{ topTime + timeZone }}
</span>
<span>{{ topDate }}</span>
</div>
</div>
<el-row class="main-top" :gutter="16">
<el-col :span="12" style="position: relative">
<div class="title">
<svg-icon icon-class="home-produce" />
<span class="title-inner">生产总览</span>
<div class="date-tabs">
<el-tabs
v-model="activeName"
@tab-click="handleClick"
:stretch="true">
<el-tab-pane
:label="'\u2002\u2002日\u2002\u2002'"
name="日"></el-tab-pane>
<el-tab-pane
:label="'\u2002\u2002周\u2002\u2002'"
name="周"></el-tab-pane>
<el-tab-pane
:label="'\u2002\u2002月\u2002\u2002'"
name="月"></el-tab-pane>
<el-tab-pane
:label="'\u2002\u2002年\u2002\u2002'"
name="年"></el-tab-pane>
</el-tabs>
</div>
<div class="current-date">( {{ showTime }} )</div>
</div>
<el-row class="box">
<el-col :span="6" class="num-box shadow">
<div class="num-style">9,301.01</div>
<div class="num-style">{{ homeProduce.quantity }}</div>
<div class="unit-style">产量/千片</div>
</el-col>
<el-col :span="4" class="num-box shadow">
<div class="num-style">94.34</div>
<div class="num-style">{{ homeProduce.yieldRate }}</div>
<div class="unit-style">良品率/%</div>
</el-col>
<el-col :span="8" class="num-box shadow">
<div class="num-style">29,301.01</div>
<div class="num-style">{{ homeProduce.endWorkOrderQuantity }}</div>
<div class="unit-style">完成工单数量/千片</div>
</el-col>
<el-col :span="6" class="num-box">
<div class="num-style">1,340</div>
<div class="num-style">{{ homeProduce.endOrderQuantity }}</div>
<div class="unit-style">完成订单数量/</div>
</el-col>
</el-row>
@ -55,22 +52,29 @@
<div class="title">
<svg-icon icon-class="home-device" />
<span class="title-inner">设备总览</span>
<!-- <div class="date-tabs">
<div class="current-time">
<span>
{{ topTime + timeZone + ' '+ topDate }}
</span>
</div>
</div> -->
</div>
<el-row class="box">
<el-col :span="6" class="num-box shadow">
<div class="num-style">2,931</div>
<div class="num-style">{{ homeDevice.allEquipment }}</div>
<div class="unit-style">设备总数/</div>
</el-col>
<el-col :span="6" class="num-box shadow">
<div class="num-style">931</div>
<div class="num-style">{{ homeDevice.onlineEquipment }}</div>
<div class="unit-style">在线设备总数/</div>
</el-col>
<el-col :span="6" class="num-box shadow">
<div class="num-style">7</div>
<div class="num-style">{{ homeDevice.errorEquipment }}</div>
<div class="unit-style">故障设备总数/</div>
</el-col>
<el-col :span="6" class="num-box">
<div class="num-style">0</div>
<div class="num-style">{{ homeDevice.stopEquipment }}</div>
<div class="unit-style">停机设备总数/</div>
</el-col>
</el-row>
@ -81,6 +85,7 @@
class="item"
:class="{ shadow: index !== middleMenu.length - 1 }"
v-for="(item, index) in middleMenu"
@click="goPage(item)"
:key="index">
<div style="width: 160px; margin: 0 auto; padding-top: 20px">
<svg-icon :icon-class="item.icon" style="font-size: 56px" />
@ -105,14 +110,14 @@
<div class="order-box">
<div
class="order-item"
v-for="(item, index) in orderList"
v-for="(item, index) in homeProduce.orderList"
:key="index">
<div>
<span class="order-name">{{ item.name }}</span>
<span class="order-value">{{ item.value }}%</span>
<span class="order-name">{{ item.orderName }}</span>
<span class="order-value">{{ item.completeRate * 100 }}%</span>
</div>
<el-progress
:percentage="item.value"
:percentage="item.completeRate * 100"
:text-inside="false"
:stroke-width="15"
:show-text="false"></el-progress>
@ -130,7 +135,7 @@
:page="1"
:limit="100000"
:table-props="tableProps"
:table-data="list"
:table-data="homeDevice.list"
:max-height="tableH" />
</div>
</el-col>
@ -155,6 +160,13 @@
import Navbar from './components/Navbar';
import moment from 'moment';
import tableHeightMixin from '@/mixins/tableHeightMixin';
import {
getHomeOrder,
getHomeOrderNum,
getHomeEquipment,
getHomeEquipmentAlarmList,
} from '@/api/home';
export default {
name: 'Home',
mixins: [tableHeightMixin],
@ -175,69 +187,107 @@ export default {
topTime: '',
timeZone: '',
middleMenu: [
{ name: '工单管理', url: '', icon: 'home-work-menu' },
{ name: '订单管理', url: '', icon: 'home-order-menu' },
{ name: '设备管理', url: '', icon: 'home-device-menu' },
{ name: '质量管理', url: '', icon: 'home-quality-menu' },
{ name: '仓库管理', url: '', icon: 'home-store-menu' },
],
orderList: [
{ name: '工单1', value: 50 },
{ name: '工单2', value: 60 },
{ name: '工单3', value: 30 },
{ name: '工单4', value: 60 },
{ name: '工单5', value: 10 },
{ name: '工单6', value: 60 },
{ name: '工单7', value: 40 },
{ name: '工单8', value: 70 },
{ name: '工单9', value: 90 },
{ name: '生产管理', url: 'productLine24h', icon: 'home-work-menu' },
{
name: '能源管理',
url: 'EnergyQuantityRealtime',
icon: 'home-order-menu',
},
{ name: '设备管理', url: 'PlanConfig', icon: 'home-device-menu' },
{ name: '质量管理', url: 'qualityScrapLog', icon: 'home-quality-menu' },
{ name: '仓库管理', url: 'warehouse-info', icon: 'home-store-menu' },
],
heightNum: 640,
tableProps: [
{
prop: 'productionLineName',
prop: 'equipmentName',
label: '设备名称',
showOverflowtooltip: true,
},
{
prop: 'sectionName',
prop: 'alarmContent',
label: '告警内容',
showOverflowtooltip: true,
},
{
prop: 'createTime',
prop: 'updateTime',
label: '告警时间',
width: 180,
filter: (val) => moment(val).format('yyyy-MM-DD HH:mm:ss'),
},
],
list: [
{ productionLineName: 1 },
{ productionLineName: 1 },
{ productionLineName: 1 },
{ productionLineName: 1 },
{ productionLineName: 1 },
{ productionLineName: 1 },
{ productionLineName: 1 },
{ productionLineName: 1 },
{ productionLineName: 1 },
{ productionLineName: 1 },
{ productionLineName: 1 },
{ productionLineName: 1 },
{ productionLineName: 1 },
{ productionLineName: 1 },
{ productionLineName: 1 },
{ productionLineName: 1 },
],
homeProduce: {
quantity: undefined,
yieldRate: undefined,
endWorkOrderQuantity: undefined,
endOrderQuantity: undefined,
orderList: [],
},
homeDevice: {
allEquipment: undefined,
onlineEquipment: undefined,
errorEquipment: undefined,
stopEquipment: undefined,
list: [],
},
times: [],
showTime: '',
};
},
created() {
this.getTime();
this.handleClick();
this.getHomeEquipment();
this.showTime = moment(new Date()).subtract(0, 'days').format('YYYY-MM-DD');
},
beforeDestroy() {
clearInterval(this.timer);
},
methods: {
handleClick() {
let start =
Date.parse(new Date())
let end =
Date.parse(new Date())
switch (this.activeName) {
case '日':
this.showTime = moment(new Date())
.subtract(0, 'days')
.format('YYYY-MM-DD');
this.times = [start, end];
break;
case '周':
start =
moment(new Date()).subtract(6, 'days').format('x')
this.showTime =
moment(new Date()).subtract(6, 'days').format('MM-DD') +
' ~ ' +
moment(new Date()).subtract(0, 'days').format('MM-DD');
this.times = [start, end];
break;
case '月':
start =
moment(new Date()).subtract(1, 'month').format('x')
this.showTime =
moment(new Date()).subtract(1, 'month').format('MM-DD') +
' ~ ' +
moment(new Date()).subtract(0, 'days').format('MM-DD');
this.times = [start, end];
break;
case '年':
start =
moment(new Date()).subtract(1, 'year').format('x')
this.showTime =
moment(new Date()).subtract(1, 'year').format('YYYY') +
' ~ ' +
moment(new Date()).subtract(0, 'days').format('YYYY');
this.times = [start, end];
break;
default:
console.log(val);
}
this.getHomeOrder();
},
getTime() {
let _this = this;
this.timer = setInterval(function () {
@ -247,6 +297,59 @@ export default {
_this.topTime = temp[1];
}, 1000);
},
getHomeOrder() {
getHomeOrder(this.times).then((response) => {
if (response.hasOwnProperty('data')) {
this.homeProduce.quantity = response.data.quantity;
this.homeProduce.yieldRate = response.data.yieldRate * 100;
this.homeProduce.endWorkOrderQuantity =
response.data.endWorkOrderQuantity;
this.homeProduce.orderList = response.data.orderMonitorVO;
} else {
this.homeProduce = {
quantity: undefined,
yieldRate: undefined,
endWorkOrderQuantity: undefined,
endOrderQuantity: undefined,
orderList: [],
};
}
});
getHomeOrderNum(this.times).then((response) => {
if (response.hasOwnProperty('data')) {
this.homeProduce.endOrderQuantity = response.data.endOrderQuantity;
} else {
this.homeProduce.endOrderQuantity = '-';
}
});
},
getHomeEquipment() {
getHomeEquipment().then((response) => {
if (response.hasOwnProperty('data')) {
this.homeDevice.allEquipment = response.data.allEquipment;
this.homeDevice.onlineEquipment = response.data.onlineEquipment;
this.homeDevice.errorEquipment = response.data.errorEquipment;
this.homeDevice.stopEquipment = response.data.stopEquipment;
} else {
this.homeDevice = {
allEquipment: undefined,
onlineEquipment: undefined,
errorEquipment: undefined,
stopEquipment: undefined,
};
}
});
getHomeEquipmentAlarmList().then((response) => {
if (response.hasOwnProperty('data')) {
this.homeDevice.list = response.data;
} else {
this.homeDevice.list = [];
}
});
},
goPage(val) {
this.$router.push({ name: val.url });
},
},
};
</script>
@ -260,56 +363,14 @@ export default {
height: 300px;
width: 100%;
}
.date-tabs {
padding-left: 40px;
padding-top: 20px;
position: relative;
}
:deep(.date-tabs) {
.el-tabs__header {
margin-bottom: 8px;
display: inline-block;
transform: translateY(-12px);
}
.el-tabs__content {
overflow: visible;
}
.el-tabs__item {
font-size: 18px;
color: #fff;
padding-left: 0 !important;
padding-right: 0 !important;
line-height: 36px !important;
height: 36px;
}
.el-tabs__item.is-active {
color: #0b58ff;
}
}
.current-date {
color: #fff;
font-size: 18px;
position: absolute;
left: 260px;
top: 14px;
}
.current-time {
color: #fff;
font-size: 18px;
position: absolute;
right: 38px;
top: 14px;
}
.main-top {
width: 100%;
padding: 0 20px 0 40px;
padding: 10px 20px 0 40px;
.title {
position: absolute;
left: 34px;
top: 20px;
width: 180px;
width: 90%;
font-size: 32px;
z-index: 10;
.title-inner {
@ -318,12 +379,53 @@ export default {
top: 5px;
font-size: 24px;
}
.date-tabs {
position: absolute;
right: 100px;
top: 5px;
font-size: 18px;
}
:deep(.date-tabs) {
.el-tabs__header {
margin-bottom: 8px;
display: inline-block;
}
.el-tabs__content {
overflow: visible;
}
.el-tabs__item {
font-size: 18px;
padding-left: 0 !important;
padding-right: 0 !important;
line-height: 20px !important;
height: 24px;
}
.el-tabs__item.is-active {
color: #0b58ff;
}
}
.current-date {
font-size: 15px;
font-weight: 500;
position: absolute;
right: 0px;
top: 5px;
}
// .current-time {
// width: 160px;
// font-size: 18px;
// position: absolute;
// right: -20px;
// top: 5px;
// }
}
.box {
background-color: #fff;
border-radius: 24px;
height: 192px;
padding: 40px 24px 32px 24px;
height: 232px;
padding: 60px 24px 32px 24px;
.num-box {
height: 120px;
padding-top: 26px;

View File

@ -2,7 +2,7 @@
* @Author: zwq
* @Date: 2021-11-18 14:16:25
* @LastEditors: zwq
* @LastEditTime: 2024-08-14 15:26:32
* @LastEditTime: 2024-10-14 09:26:29
* @Description:
-->
<template>
@ -252,10 +252,8 @@ export default {
});
},
async getDict() {
const materRes = await getMaterialTree();
let typeId = materRes.data[0].product
? materRes.data[0].id
: materRes.data[1].id;
const materRes = await getMaterialTree();//
let typeId = materRes.data.find(item=>item.product === 1).id
const listQuery = {
typeId: typeId,
};

View File

@ -117,8 +117,8 @@ export default {
methods: {
async getDict() {
//
const materRes = await getMaterialTree();
let typeId = materRes.data[0].product?materRes.data[1].id:materRes.data[0].id
const materRes = await getMaterialTree(); //
let typeId = materRes.data.find(item=>item.product === 1).id
const listQuery= {
typeId:typeId
}

View File

@ -2,7 +2,7 @@
* @Author: zwq
* @Date: 2021-11-18 14:16:25
* @LastEditors: zwq
* @LastEditTime: 2024-08-14 15:27:50
* @LastEditTime: 2024-10-14 09:26:53
* @Description:
-->
<template>
@ -207,8 +207,8 @@ export default {
},
methods: {
async getDictData() {
const materRes = await getMaterialTree();
let typeId = materRes.data[0].product?materRes.data[1].id:materRes.data[0].id
const materRes = await getMaterialTree(); //
let typeId = materRes.data.find(item=>item.product === 0).id
const listQuery= {
typeId:typeId
}

View File

@ -1,4 +1,4 @@
<!--
<!--
filename: index.vue
author: liubin
date: 2023-08-31 09:14:19
@ -44,16 +44,17 @@ import { Message } from 'element-ui';
import LocalDataManager from './utils/local-data-manager';
// import response from './response';
import moment from 'moment';
import { parseTime } from '@/utils/ruoyi'
export default {
name: 'EquipmentFullParams',
components: {},
props: {},
data() {
const now = new Date();
const [y, m, d] = [now.getFullYear(), now.getMonth(), now.getDate()];
const today = new Date(y, m, d, 0, 0, 0, 0).getTime();
const aWeekAgo = today - 3600 * 1000 * 24 * 7;
// const now = new Date().getTime();
// const [y, m, d] = [now.getFullYear(), now.getMonth(), now.getDate()];
const today = new Date().getTime();
const tenminAgo = new Date(today - (10 * 60 * 1000)).getTime();
return {
searchBarFormConfig: [
{
@ -73,10 +74,10 @@ export default {
{
type: 'datePicker',
label: '时间段',
dateType: 'daterange', // datetimerange
dateType: 'datetimerange', // datetimerange
format: 'yyyy-MM-dd HH:mm:ss',
// valueFormat: 'yyyy-MM-dd HH:mm:ss',
valueFormat: 'timestamp',
valueFormat: 'yyyy-MM-dd HH:mm:ss',
rangeSeparator: '-',
startPlaceholder: '开始时间',
endPlaceholder: '结束时间',
@ -93,14 +94,20 @@ export default {
},
],
queryParams: {
id: null,
time: [new Date(aWeekAgo), new Date(today)],
equipmentId: null,
recordTime: [parseTime(tenminAgo), parseTime(today)],
},
tableList: [
// {
// key: 'base-table__key__1',
// tableProps: [],
// list: [],
// tableProps: [{
// prop: 'name',
// label: 'name'
// }],
// dataManager: {dataList: [{name: '1'}]},
// list: [{
// name: '11'
// }],
// pageNo: 1,
// pageSize: 3,
// total: 0,
@ -111,7 +118,7 @@ export default {
beforeRouteEnter(to, from, next) {
if (Object.keys(to.params).length > 0) {
next((vm) => {
vm.$set(vm.queryParams, 'id', to.params.equipmentId);
vm.$set(vm.queryParams, 'equipmentId', to.params.equipmentId);
vm.$set(
vm.searchBarFormConfig[0],
'defaultSelect',
@ -122,6 +129,11 @@ export default {
'defaultSelect',
to.params.equipmentCode
);
vm.$set(
vm.searchBarFormConfig[2],
'defaultSelect',
vm.queryParams.recordTime
);
vm.handleQuery();
});
} else {
@ -155,7 +167,7 @@ export default {
},
beforeRouteLeave(to, from, next) {
// clean job
this.$set(this.queryParams, 'id', null);
this.$set(this.queryParams, 'equipmentId', null);
this.$set(this.searchBarFormConfig[0], 'defaultSelect', null);
this.$set(this.searchBarFormConfig[1], 'defaultSelect', null);
this.tableList = [];
@ -192,7 +204,7 @@ export default {
props.push({
label: item.name,
prop: item.name,
width: 128,
// width: 128,
});
firstLineData[item.name] = `${item.minValue ?? ''}-${
item.maxValue ?? ''
@ -268,11 +280,18 @@ export default {
async handleSearchBarBtnClick({ btnName, timeVal }) {
if (timeVal && timeVal.length > 0) {
this.queryParams.time = timeVal;
console.log('nihc ', timeVal)
if (new Date(timeVal[1]).getTime() - new Date(timeVal[0]).getTime() <= 30 * 60 * 1000) {
this.queryParams.recordTime = timeVal;
await this.handleQuery();
} else {
this.$message.warning('时间范围最大30分钟限制')
}
} else {
this.queryParams.time = [];
this.queryParams.recordTime = [];
this.$message.warning('时间段必选!')
}
await this.handleQuery();
},
handleEmitFun(table, val) {
@ -295,9 +314,12 @@ export default {
}
.tables {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 18px;
/* display: grid; */
/* grid-template-columns: 1fr 1fr; */
/* gap: 18px; */
display: flex;
flex-direction: column;
width: 100%;
}
.tables >>> .baseTable {
@ -306,5 +328,6 @@ export default {
.custom-table {
overflow-x: hidden;
margin-bottom: 10px;
}
</style>

View File

@ -283,7 +283,7 @@ export default {
},
//
returnOrderManage() {
this.$router.push({path: '/order/base/order-manage'})
this.$router.go(-1);
}
}
}
@ -340,4 +340,4 @@ export default {
vertical-align: bottom;
}
}
</style>
</style>

View File

@ -1,290 +1,417 @@
<template>
<el-form ref="addWorkOrder" :rules="rules" label-width="130px" :model="form" label-position='top'>
<el-row :gutter="20">
<el-col :span='6'>
<el-form-item label="工单名称" prop="name" v-if='!isBind'>
<el-input v-model="form.name"></el-input>
</el-form-item>
<el-form-item label="工单名称" prop="workOrderId" v-if='isBind'>
<el-select v-model="form.workOrderId" placeholder="请选择" style="width: 100%;" filterable
@change="getWorkOrderMsg">
<el-option v-for="item in workOrderList" :key="item.id" :label="item.name" :value="item.id">
</el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span='6'>
<el-form-item label="工单编码" prop="code">
<el-input v-model="form.code" disabled></el-input>
</el-form-item>
</el-col>
<el-col :span='6'>
<el-form-item label="产品名称" prop="planProductId">
<el-select v-model="form.planProductId" placeholder="请选择" disabled style="width: 100%;">
<el-option v-for="item in productList" :key="item.id" :label="item.name+' | '+item.specifications"
:value="item.id">
<span style="float: left">{{ item.name }}</span>
<span style="float: right; color: #8492a6; font-size: 13px">{{ item.specifications }}</span>
</el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span='6'>
<el-form-item label="计划开始时间">
<el-date-picker v-model="planStartTime" type="datetime" value-format="yyyy-MM-dd HH:mm:ss"
style="width: 100%;" placeholder="选择日期" :disabled="isBind">
</el-date-picker>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span='6'>
<el-form-item label="计划完成时间">
<el-date-picker v-model="planFinishTime" type="datetime" value-format="yyyy-MM-dd HH:mm:ss"
style="width: 100%;" placeholder="选择日期" :disabled="isBind">
</el-date-picker>
</el-form-item>
</el-col>
<el-col :span='6'>
<el-form-item label="计划投入数量" prop="planAssignQuantity">
<el-input-number v-model="form.planAssignQuantity" :min="0" :max="9999999999999" :disabled="isBind"
style="width: 100%;"></el-input-number>
</el-form-item>
</el-col>
<el-col :span='6'>
<el-form-item label="计划生产数量" prop="planQuantity">
<el-input-number v-model="form.planQuantity" :min="0" :max="9999999999999" :disabled="isBind"
style="width: 100%;"></el-input-number>
</el-form-item>
</el-col>
<el-col :span='6'>
<el-form-item label="关联工艺" prop="processFlowId">
<el-select v-model="form.processFlowId" placeholder="请选择" disabled style="width: 100%;">
<el-option v-for="item in processFlowList" :key="item.id" :label="item.name" :value="item.id">
</el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span='6'>
<el-form-item label="物料计算方式" prop="materialMethod">
<el-select v-model="form.materialMethod" placeholder="请选择" style="width: 100%;" disabled>
<el-option label="产品基础BOM" :value="1"></el-option>
<el-option label="工艺扩展BOM" :value="2"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span='6'>
<el-form-item label="优先级" prop="priority">
<el-select v-model="form.priority" placeholder="请选择" style="width: 100%;" :disabled="isBind">
<el-option v-for="item in getDictDatas(DICT_TYPE.ORDER_PRIORITY)" :key="item.value" :label="item.label"
:value="item.value">
</el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span='6'>
<el-form-item label="工单类型" prop="type">
<el-select v-model="form.type" placeholder="请选择" style="width: 100%;" :disabled="isBind">
<el-option v-for="item in workOrderTypeList" :key="item.id" :label="item.name" :value="item.id">
</el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span='6'>
<el-form-item label="关联产线" prop="productLineId">
<el-select v-model="form.productLineId" placeholder="请选择" multiple style="width: 100%;" :disabled="isBind">
<el-option v-for="item in productLineList" :key="item.id" :label="item.name" :value="item.id">
</el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span='6'>
<el-form-item label="负责人" prop="workers">
<el-input v-model="form.workers" :disabled="isBind"></el-input>
</el-form-item>
</el-col>
<el-col :span='6'>
<el-form-item label="负责部门" prop="deptId">
<el-select v-model="form.deptId" placeholder="请选择关联产线" style="width: 100%;">
<el-option v-for="item in deptList" :key="item.id" :label="item.name" :value="item.id">
</el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span='6'>
<el-form-item label="计划分配订单量" prop="planAssignmentQuantity">
<el-input-number v-model="form.planAssignmentQuantity" :min="0" :max="9999999999999" style="width: 100%;">
</el-input-number>
</el-form-item>
</el-col>
</el-row>
</el-form>
<el-form
ref="addWorkOrder"
:rules="rules"
label-width="130px"
:model="form"
label-position="top">
<el-row :gutter="20">
<el-col :span="6">
<el-form-item label="工单模式">
<el-radio-group v-model="isBind">
<el-radio :label="true">绑定工单</el-radio>
<el-radio :label="false">新增工单</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="工单名称" prop="name" v-if="!isBind">
<el-input v-model="form.name"></el-input>
</el-form-item>
<el-form-item label="工单名称" prop="workOrderId" v-if="isBind">
<el-select
v-model="form.workOrderId"
placeholder="请选择"
style="width: 100%"
filterable
@change="getWorkOrderMsg">
<el-option
v-for="item in workOrderList"
:key="item.id"
:label="item.name"
:value="item.id"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="工单编码" prop="code">
<el-input v-model="form.code" disabled></el-input>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="产品名称" prop="planProductId">
<el-select
v-model="form.planProductId"
placeholder="请选择"
disabled
style="width: 100%">
<el-option
v-for="item in productList"
:key="item.id"
:label="item.name + ' | ' + item.specifications"
:value="item.id">
<span style="float: left">{{ item.name }}</span>
<span style="float: right; color: #8492a6; font-size: 13px">
{{ item.specifications }}
</span>
</el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="计划开始时间">
<el-date-picker
v-model="planStartTime"
type="datetime"
value-format="yyyy-MM-dd HH:mm:ss"
style="width: 100%"
placeholder="选择日期"
:disabled="isBind"></el-date-picker>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="计划完成时间">
<el-date-picker
v-model="planFinishTime"
type="datetime"
value-format="yyyy-MM-dd HH:mm:ss"
style="width: 100%"
placeholder="选择日期"
:disabled="isBind"></el-date-picker>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="计划投入数量" prop="planAssignQuantity">
<el-input-number
v-model="form.planAssignQuantity"
:min="0"
:max="9999999999999"
:disabled="isBind"
style="width: 100%"></el-input-number>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="计划生产数量" prop="planQuantity">
<el-input-number
v-model="form.planQuantity"
:min="0"
:max="9999999999999"
:disabled="isBind"
style="width: 100%"></el-input-number>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="关联工艺" prop="processFlowId">
<el-select
v-model="form.processFlowId"
placeholder="请选择"
disabled
style="width: 100%">
<el-option
v-for="item in processFlowList"
:key="item.id"
:label="item.name"
:value="item.id"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="物料计算方式" prop="materialMethod">
<el-select
v-model="form.materialMethod"
placeholder="请选择"
style="width: 100%"
disabled>
<el-option label="产品基础BOM" :value="1"></el-option>
<el-option label="工艺扩展BOM" :value="2"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="优先级" prop="priority">
<el-select
v-model="form.priority"
placeholder="请选择"
style="width: 100%"
:disabled="isBind">
<el-option
v-for="item in getDictDatas(DICT_TYPE.ORDER_PRIORITY)"
:key="item.value"
:label="item.label"
:value="item.value"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="工单类型" prop="type">
<el-select
v-model="form.type"
placeholder="请选择"
style="width: 100%"
:disabled="isBind">
<el-option
v-for="item in workOrderTypeList"
:key="item.id"
:label="item.name"
:value="item.id"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="关联产线" prop="productLineId">
<el-select
v-model="form.productLineId"
placeholder="请选择"
multiple
style="width: 100%"
:disabled="isBind">
<el-option
v-for="item in productLineList"
:key="item.id"
:label="item.name"
:value="item.id"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="负责人" prop="workers">
<el-input v-model="form.workers" :disabled="isBind"></el-input>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="负责部门" prop="deptId">
<el-select
v-model="form.deptId"
placeholder="请选择关联产线"
style="width: 100%">
<el-option
v-for="item in deptList"
:key="item.id"
:label="item.name"
:value="item.id"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="计划分配订单量" prop="planAssignmentQuantity">
<el-input-number
v-model="form.planAssignmentQuantity"
:min="0"
:max="9999999999999"
style="width: 100%"></el-input-number>
</el-form-item>
</el-col>
</el-row>
</el-form>
</template>
<script>
import { getProductAll } from '@/api/base/product'
import { getProcessFlowList, getWorkOrderCode, orderIssue, workOrderList, getWorkOrderById } from '@/api/base/orderManage'
import { getLineAll } from '@/api/base/productionLine'
import { getProductAll } from '@/api/base/product';
import {
getProcessFlowList,
getWorkOrderCode,
orderIssue,
workOrderList,
getWorkOrderById,
} from '@/api/base/orderManage';
import { getLineAll } from '@/api/base/productionLine';
import { listDept } from '@/api/system/dept';
import moment from 'moment'
import moment from 'moment';
export default {
name: 'AddWorkOrder',
data() {
return {
form: {
workOrderId: '',
orderId: '',
name: '',
code: '',
planProductId: '',
planStartTime: '',
planFinishTime: '',
planAssignQuantity: 0,
deptId:undefined,
planQuantity: 0,
processFlowId: '',
materialMethod: 1,
priority: '',
productLineId: [],
type: '',
workers: '',
planAssignmentQuantity: ''
},
deptList:[],
rules: {
name: [{ required: true, message: "工单名称不能为空", trigger: "blur" }],
planProductId: [{ required: true, message: "产品名称不能为空", trigger: "change" }],
planAssignQuantity: [{ required: true, message: "计划投入数量不能为空", trigger: "blur" }],
planQuantity: [{ required: true, message: "计划生产数量不能为空", trigger: "blur" }],
productLineId: [{ required: true, message: "产线不能为空", trigger: "change" }],
planAssignmentQuantity: [{ required: true, message: "计划分配订单量不能为空", trigger: "blur" }]
},
productList: [],
processFlowList: [],
productLineList: [],
workOrderTypeList: [
{id: 1,name:'标准工单'},
{id: 2, name:'特殊工单'}
],
planStartTime: '',
planFinishTime: '',
isBind: false,
workOrderList: []
}
},
methods: {
init(data, param) {
this.form.orderId = data.id
this.getList()
if (param === 'add') {
this.isBind = false
getWorkOrderCode().then(res => {
this.form.code = res.data || ''
})
this.form.planProductId = data.planProductId
this.form.processFlowId = data.processFlowId
this.form.materialMethod = data.materialMethod
}else{//
this.isBind = true
}
},
getList() {
listDept().then(res => {
this.deptList = res.data || []
})
//
getProductAll().then(res => {
this.productList = res.data || []
})
// 线
getLineAll().then(res => {
this.productLineList = res.data || []
})
//
getProcessFlowList().then(res => {
this.processFlowList = res.data || []
})
// list
workOrderList({
status: 1
}).then(res => {
this.workOrderList = res.data || []
})
},
addWorkOrderSubmit() {
this.$refs['addWorkOrder'].validate((valid) => {
if (valid) {
if (this.isBind) {
//
orderIssue({
workOrderId: this.form.workOrderId,
orderId: this.form.orderId,
planAssignmentQuantity: this.form.planAssignmentQuantity
}).then((res) => {
if (res.code === 0) {
this.$modal.msgSuccess("操作成功")
this.$emit('addWorkOrderSubmit')
}
})
} else {
//
let _this = this
_this.form.planStartTime = _this.planStartTime ? new Date(_this.planStartTime).valueOf() : ''
_this.form.planFinishTime = _this.planFinishTime ? new Date(_this.planFinishTime).valueOf() : ''
orderIssue({ ..._this.form }).then(res => {
if (res.code === 0) {
_this.$modal.msgSuccess("操作成功")
let name = this.form.name
_this.$emit('addWorkOrderSubmit')
// 使
// _this.$modal.confirm('使?').then(function() {
// _this.$router.push({
// path: '/core/core-work-order?workOrderName='+encodeURI(name)
// })
// })
}
})
}
} else {
return false
}
})
},
formClear() {
this.$refs.addWorkOrder.resetFields()
this.form.materialMethod = 1
this.form.planAssignQuantity = 0
this.form.planQuantity = 0
this.planFinishTime = ''
this.planStartTime = ''
this.form.planFinishTime = ''
this.form.planStartTime = ''
this.isBind = false
},
//
getWorkOrderMsg() {
if (this.form.workOrderId) {
getWorkOrderById({id:this.form.workOrderId}).then(res => {
if (res.code === 0) {
this.form.code = res.data.code
this.form.planProductId = res.data.planProductId
this.planStartTime = res.data.planStartTime ? moment.unix(res.data.planStartTime).format('YYYY-MM-DD HH:mm:ss') : null
this.planFinishTime = res.data.planFinishTime ? moment.unix(res.data.planFinishTime).format('YYYY-MM-DD HH:mm:ss') : null
this.form.planAssignQuantity = res.data.planAssignQuantity
this.form.planQuantity = res.data.planQuantity
this.form.processFlowId = res.data.processFlowId
this.form.materialMethod = res.data.materialMethod
this.form.priority = res.data.priority ? res.data.priority + '' : ''
this.form.productLineId = res.data.productLineIds
this.form.type = res.data.type
this.form.workers = res.data.workers
}
})
}
}
}
}
name: 'AddWorkOrder',
data() {
return {
form: {
workOrderId: '',
orderId: '',
name: '',
code: '',
planProductId: '',
planStartTime: '',
planFinishTime: '',
planAssignQuantity: 0,
deptId: undefined,
planQuantity: 0,
processFlowId: '',
materialMethod: 1,
priority: '',
productLineId: [],
type: '',
workers: '',
planAssignmentQuantity: '',
},
deptList: [],
rules: {
name: [
{ required: true, message: '工单名称不能为空', trigger: 'blur' },
],
planProductId: [
{ required: true, message: '产品名称不能为空', trigger: 'change' },
],
planAssignQuantity: [
{ required: true, message: '计划投入数量不能为空', trigger: 'blur' },
],
planQuantity: [
{ required: true, message: '计划生产数量不能为空', trigger: 'blur' },
],
productLineId: [
{ required: true, message: '产线不能为空', trigger: 'change' },
],
planAssignmentQuantity: [
{
required: true,
message: '计划分配订单量不能为空',
trigger: 'blur',
},
],
},
productList: [],
processFlowList: [],
productLineList: [],
workOrderTypeList: [
{ id: 1, name: '标准工单' },
{ id: 2, name: '特殊工单' },
],
planStartTime: '',
planFinishTime: '',
isBind: false,
workOrderList: [],
orderData: {},
};
},
methods: {
init(data, param) {
this.isBind = true;
this.orderData = data;
this.form.orderId = data.id;
this.getList();
},
changeAdd() {
if (this.isBind) {
this.isBind = false;
getWorkOrderCode().then((res) => {
this.form.code = res.data || '';
});
this.form.orderId = null;
this.form.planProductId = this.orderData.planProductId;
this.form.processFlowId = this.orderData.processFlowId;
this.form.materialMethod = this.orderData.materialMethod;
} else {
this.isBind = true;
this.form.orderId = this.orderData.id;
this.form.planProductId = null;
this.form.processFlowId = null;
this.form.materialMethod = null;
this.form.code = null;
}
},
getList() {
listDept().then((res) => {
this.deptList = res.data || [];
});
//
getProductAll().then((res) => {
this.productList = res.data || [];
});
// 线
getLineAll().then((res) => {
this.productLineList = res.data || [];
});
//
getProcessFlowList().then((res) => {
this.processFlowList = res.data || [];
});
// list
workOrderList({
status: 1,
}).then((res) => {
this.workOrderList = res.data || [];
});
},
addWorkOrderSubmit() {
this.$refs['addWorkOrder'].validate((valid) => {
if (valid) {
if (this.isBind) {
//
orderIssue({
workOrderId: this.form.workOrderId,
orderId: this.form.orderId,
planAssignmentQuantity: this.form.planAssignmentQuantity,
}).then((res) => {
if (res.code === 0) {
this.$modal.msgSuccess('操作成功');
this.$emit('addWorkOrderSubmit');
}
});
} else {
//
let _this = this;
_this.form.planStartTime = _this.planStartTime
? new Date(_this.planStartTime).valueOf()
: '';
_this.form.planFinishTime = _this.planFinishTime
? new Date(_this.planFinishTime).valueOf()
: '';
orderIssue({ ..._this.form }).then((res) => {
if (res.code === 0) {
_this.$modal.msgSuccess('操作成功');
let name = this.form.name;
_this.$emit('addWorkOrderSubmit');
// 使
// _this.$modal.confirm('使?').then(function() {
// _this.$router.push({
// path: '/core/core-work-order?workOrderName='+encodeURI(name)
// })
// })
}
});
}
} else {
return false;
}
});
},
formClear() {
this.$refs.addWorkOrder.resetFields();
this.form.materialMethod = 1;
this.form.planAssignQuantity = 0;
this.form.planQuantity = 0;
this.planFinishTime = '';
this.planStartTime = '';
this.form.planFinishTime = '';
this.form.planStartTime = '';
this.isBind = false;
},
//
getWorkOrderMsg() {
if (this.form.workOrderId) {
getWorkOrderById({ id: this.form.workOrderId }).then((res) => {
if (res.code === 0) {
this.form.code = res.data.code;
this.form.planProductId = res.data.planProductId;
this.planStartTime = res.data.planStartTime
? moment
.unix(res.data.planStartTime)
.format('YYYY-MM-DD HH:mm:ss')
: null;
this.planFinishTime = res.data.planFinishTime
? moment
.unix(res.data.planFinishTime)
.format('YYYY-MM-DD HH:mm:ss')
: null;
this.form.planAssignQuantity = res.data.planAssignQuantity;
this.form.planQuantity = res.data.planQuantity;
this.form.processFlowId = res.data.processFlowId;
this.form.materialMethod = res.data.materialMethod;
this.form.priority = res.data.priority
? res.data.priority + ''
: '';
this.form.productLineId = res.data.productLineIds;
this.form.type = res.data.type;
this.form.workers = res.data.workers;
}
});
}
},
},
};
</script>

View File

@ -22,7 +22,7 @@ export default {
},
methods: {
changeInput() {
console.log(this.list)
this.list.sType = 1
this.$emit('emitData', this.list)
}
}

View File

@ -31,9 +31,15 @@
</el-row>
<el-row :gutter="20">
<el-col :span='6'>
<el-form-item label="单价" prop="price">
<el-input-number v-model="form.price" :min="0" :max="9999999999999" :precision='2' style="width: 100%;">
</el-input-number>
<el-form-item label="产品规格" prop="specifications">
<el-input v-model="form.specifications"></el-input>
</el-form-item>
</el-col>
<el-col :span='6'>
<el-form-item label="交货日期" prop="deliveTime">
<el-date-picker v-model="form.deliveTime" type="datetime" style="width: 100%;" value-format="timestamp"
@change="timeChange" placeholder="选择日期">
</el-date-picker>
</el-form-item>
</el-col>
<el-col :span='6'>
@ -44,6 +50,16 @@
</el-select>
</el-form-item>
</el-col>
<el-col :span='6'>
<el-form-item label="单价" prop="price">
<el-input-number v-model="form.price" :min="0" :max="9999999999999" :precision='2' style="width: 100%;">
</el-input-number>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
</el-row>
<el-row :gutter="20">
<el-col :span='6'>
<el-form-item label="包装规格" prop="packSpec">
<el-select v-model="form.packSpec" placeholder="请选择" style="width: 100%;" clearable>
@ -53,22 +69,6 @@
</el-select>
</el-form-item>
</el-col>
<el-col :span='6'>
<el-form-item label="交货日期" prop="deliveTime">
<el-date-picker v-model="form.deliveTime" type="datetime" style="width: 100%;" value-format="timestamp"
@change="timeChange" placeholder="选择日期">
</el-date-picker>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
</el-row>
<el-row :gutter="20">
<el-col :span='6'>
<el-form-item label="产品规格" prop="specifications">
<el-input v-model="form.specifications"></el-input>
</el-form-item>
</el-col>
<el-col :span='12'>
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark"></el-input>

View File

@ -1,257 +1,313 @@
<!--
* @Author: zhp
* @Date: 2024-08-01 16:27:30
* @LastEditTime: 2024-09-04 15:56:53
* @LastEditors: zhp
* @Author: zwq
* @Date: 2024-09-26 14:08:58
* @LastEditors: zwq
* @LastEditTime: 2024-11-06 09:52:59
* @Description:
-->
<template>
<el-form ref="orderAddForm" :rules="rules" :model="form" :inline="true" class="demo-form-inline">
<!-- <el-row :gutter="20"> -->
<!-- <el-col :span='6'> -->
<el-form-item label="拆分数量" prop="attr3">
<el-input v-model.number="form.attr3" oninput="value=value.replace(/[^\d]/g,'')"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="handleSplit">确定</el-button>
</el-form-item>
<!-- </el-col> -->
<!-- </el-row> -->
<base-table :table-props="tableProps" :table-data="list" :max-height="tableH">
<!-- <method-btn v-if="tableBtn.length" slot="handleBtn" :width="240" label="操作" :method-list="tableBtn"
<el-form
ref="orderAddForm"
:rules="rules"
:model="form"
:inline="true"
class="demo-form-inline">
<!-- <el-row :gutter="20"> -->
<!-- <el-col :span='6'> -->
<el-form-item label="拆分数量" prop="attr3">
<el-input
v-model.number="form.attr3"
oninput="value=value.replace(/[^\d]/g,'')"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="handleSplit">确定</el-button>
</el-form-item>
<!-- </el-col> -->
<!-- </el-row> -->
<base-table
:table-props="tableProps"
:table-data="list"
@emitFun="inputChange"
:max-height="tableH">
<!-- <method-btn v-if="tableBtn.length" slot="handleBtn" :width="240" label="操作" :method-list="tableBtn"
@clickBtn="handleClick" /> -->
</base-table>
</el-form>
</base-table>
</el-form>
</template>
<script>
import { getOrderCode, getOrderById, getProcessFlowList, orderUpdate, orderCreate, orderSplit } from '@/api/base/orderManage'
import { parseTime } from '@/utils/ruoyi'
import inputArea from './inputArea.vue'
const tableProps = [
{
prop: 'name',
label: '订单名称',
minWidth: 120,
showOverflowtooltip: true,
subcomponent: inputArea
},
{
prop: 'code',
label: '订单编码',
minWidth: 180,
subcomponent: inputArea
},
{
prop: 'productName',
label: '产品',
showOverflowtooltip: true,
subcomponent: inputArea
},
// {
// prop: 'priority',
// label: '',
// filter: publicFormatter('order_priority')
// },
{
prop: 'planQuantity',
label: '计划加工量',
width: 100,
subcomponent: inputArea
},
{
prop: 'deliveTime',
label: '交货日期',
filter: parseTime,
minWidth: 160,
subcomponent: inputArea
},
{
prop: 'customerId',
label: '客户',
showOverflowtooltip: true,
subcomponent: inputArea
},
{
prop: 'price',
label: '单价',
width: 100,
subcomponent: inputArea
},
{
prop: 'packSpec',
label: '包装规格',
width: 100,
subcomponent: inputArea
},
{
prop: 'remark',
label: '备注',
width: 100,
subcomponent: inputArea
},
]
export default {
name: 'OrderAdd',
data() {
return {
tableProps,
list: [],
tableH: this.tableHeight(260),
form: {
id: '',
name: '',
code: '',
planQuantity: '',
planProductId: '',
price: '',
customerId: '',
attr3:undefined,
priority: '',
packSpec: '',
workers: '',
materialMethod: 1,
remark: '',
deliveTime:undefined,
// description: '',
planStartTime: '',
},
rules: {
attr3: [{ required: true, message: "拆分数量不能为空", trigger: "blur" }],
},
productList: [],
customerList: [],
processFlowList: [],
isEdit: false //
}
},
created () {
window.addEventListener('resize', () => {
this.tableH = this.tableHeight(260)
})
},
methods: {
handleSplit() {
let obj = {
attr3: this.form.attr3,
id:this.form.id
}
orderSplit(obj).then((res) => {
this.list = res.data
})
},
init(obj) {
// this.getList()
// if (obj) {
this.isEdit = true
this.form = {}
this.list = []
this.form.id = obj.id
// getOrderById({id: this.form.id}).then(res => {
// if (res.code === 0) {
// this.form.name = res.data.name
// this.form.code = res.data.code
// this.form.planQuantity = res.data.planQuantity
// this.form.planProductId = res.data.planProductId
// this.form.price = res.data.price
// this.form.customerId = res.data.customerId
// this.form.priority = res.data.priority ? res.data.priority + '' : ''
// this.form.planStartTime = res.data.planStartTime ? res.data.planStartTime : null
// this.form.packSpec = res.data.packSpec ? res.data.packSpec+'' : ''
// this.form.workers = res.data.workers
// this.form.processFlowId = res.data.processFlowId
// this.form.materialMethod = res.data.materialMethod
// this.form.planFinishTime = res.data.planFinishTime ? res.data.planFinishTime : null
// this.form.remark = res.data.remark
// // this.form.description = res.data.description
// }
// })
// } else {
// this.isEdit = false
// this.form.id = ''
// //
// getOrderCode().then(res => {
// this.form.code = res.data || ''
// })
// }
},
// getList() {
// //
// getProductAll().then(res => {
// this.productList = res.data || []
// })
// //
// getCustomerList().then(res => {
// this.customerList = res.data || []
// })
// //
// getProcessFlowList().then(res => {
// this.processFlowList = res.data || []
// })
// },
// timeChange() {
// if (this.form.planStartTime && this.form.planFinishTime) {
// if (this.form.planStartTime > this.form.planFinishTime) {
// this.$modal.msgError('')
// }
// }
// },
// //
// materialMethodChange(val) {
// if (val === 2 && !this.form.processFlowId) {
// this.form.materialMethod = 1
// this.$modal.msgError("");
// }
// },
// //
// processFlowIdChange(val) {
// console.log(val)
// if (!val) {
// this.form.materialMethod = 1
// }
// },
submitForm() {
Promise.all(this.list.map((ele) => {
return orderCreate(ele);
})).then((res) => {
this.$modal.msgSuccess("操作成功");
this.$emit('splitWorkOrderSubmit');
});
import {
getOrderCode,
getOrderById,
getProcessFlowList,
orderUpdate,
orderCreate,
orderSplit,
} from '@/api/base/orderManage';
// this.$refs['orderAddForm'].validate((valid) => {
// if (valid) {
// if (this.form.planStartTime && this.form.planFinishTime) {
// if (this.form.planStartTime > this.form.planFinishTime) {
// this.$modal.msgError('')
// return false
// }
// }
// // console.log(this.form)
// if (this.isEdit) {
// //
// orderUpdate({ ...this.form }).then((res) => {
// if (res.code === 0) {
// this.$modal.msgSuccess("");
// this.$emit('successSubmit')
// }
// })
// } else {
// this.form.status = 1
// this.form.triggerOrigin = 1
// orderCreate({ ...this.form }).then((res) => {
// if (res.code === 0) {
// this.$modal.msgSuccess("");
// this.$emit('successSubmit')
// }
// })
// }
// } else {
// return false
// }
// })
},
formClear() {
this.$refs.orderAddForm.resetFields()
}
}
}
import { getCustomerList } from '@/api/base/customer';
import { parseTime } from '@/utils/ruoyi';
import inputArea from './inputArea.vue';
import selectMember from './selectMember';
import selectTime from './selectTime';
import { publicFormatter } from '@/utils/dict'
const tableProps = [
{
prop: 'name',
label: '订单名称',
minWidth: 120,
showOverflowtooltip: true,
subcomponent: inputArea,
},
{
prop: 'code',
label: '订单编码',
minWidth: 180,
},
{
prop: 'productName',
label: '产品',
showOverflowtooltip: true,
},
{
prop: 'specifications',
label: '产品规格',
showOverflowtooltip: true,
},
// {
// prop: 'priority',
// label: '',
// filter: publicFormatter('order_priority')
// },
{
prop: 'planQuantity',
label: '计划加工量',
width: 100,
subcomponent: inputArea,
},
{
prop: 'deliveTime',
label: '交货日期',
filter: parseTime,
minWidth: 160,
subcomponent: selectTime,
},
{
prop: 'customerId',
label: '客户',
showOverflowtooltip: true,
// subcomponent: selectMember,
},
{
prop: 'price',
label: '单价',
width: 100,
// subcomponent: inputArea,
},
{
prop: 'packSpec',
label: '包装规格',
width: 100,
filter: publicFormatter('pack_spec')
// subcomponent: selectMember,
},
{
prop: 'remark',
label: '备注',
width: 100,
subcomponent: inputArea,
},
];
export default {
name: 'OrderAdd',
data() {
return {
tableProps,
list: [],
tableH: this.tableHeight(260),
form: {
id: '',
name: '',
code: '',
planQuantity: '',
planProductId: '',
price: '',
customerId: '',
attr3: undefined,
priority: '',
packSpec: '',
workers: '',
materialMethod: 1,
remark: '',
deliveTime: undefined,
// description: '',
planStartTime: '',
},
rules: {
attr3: [
{ required: true, message: '拆分数量不能为空', trigger: 'blur' },
],
},
productList: [],
customerList: [],
processFlowList: [],
isEdit: false, //
};
},
created() {
window.addEventListener('resize', () => {
this.tableH = this.tableHeight(260);
});
},
methods: {
handleSplit() {
if (this.form.attr3) {
this.list = [];
let obj = {
attr3: this.form.attr3,
id: this.form.id,
};
orderSplit(obj).then((res) => {
this.list = res.data;
this.list.forEach((item, index) => {
item.name = item.name + '-' + (index + 1);
item.code = item.code + '-' + (index + 1);
});
});
} else {
this.$message('拆分数量不能为空');
}
},
init(obj) {
this.getList();
// if (obj) {
this.isEdit = true;
this.form = {};
this.list = [];
this.form.id = obj.id;
// getOrderById({id: this.form.id}).then(res => {
// if (res.code === 0) {
// this.form.name = res.data.name
// this.form.code = res.data.code
// this.form.planQuantity = res.data.planQuantity
// this.form.planProductId = res.data.planProductId
// this.form.price = res.data.price
// this.form.customerId = res.data.customerId
// this.form.priority = res.data.priority ? res.data.priority + '' : ''
// this.form.planStartTime = res.data.planStartTime ? res.data.planStartTime : null
// this.form.packSpec = res.data.packSpec ? res.data.packSpec+'' : ''
// this.form.workers = res.data.workers
// this.form.processFlowId = res.data.processFlowId
// this.form.materialMethod = res.data.materialMethod
// this.form.planFinishTime = res.data.planFinishTime ? res.data.planFinishTime : null
// this.form.remark = res.data.remark
// // this.form.description = res.data.description
// }
// })
// } else {
// this.isEdit = false
// this.form.id = ''
// //
// getOrderCode().then(res => {
// this.form.code = res.data || ''
// })
// }
},
getList() {
//
// getProductAll().then(res => {
// this.productList = res.data || []
// })
//
getCustomerList().then((res) => {
this.customerList = res.data || [];
this.$set(this.tableProps[6], 'customerList', this.customerList);
});
//
// getProcessFlowList().then(res => {
// this.processFlowList = res.data || []
// })
},
// timeChange() {
// if (this.form.planStartTime && this.form.planFinishTime) {
// if (this.form.planStartTime > this.form.planFinishTime) {
// this.$modal.msgError('')
// }
// }
// },
// //
// materialMethodChange(val) {
// if (val === 2 && !this.form.processFlowId) {
// this.form.materialMethod = 1
// this.$modal.msgError("");
// }
// },
// //
// processFlowIdChange(val) {
// console.log(val)
// if (!val) {
// this.form.materialMethod = 1
// }
// },
inputChange(data) {
switch (data.sType) {
case 1:
this.list[data._pageIndex - 1][data.prop] = data[data.prop];
break;
case 2:
this.list[data._pageIndex - 1][data.prop] = data[data.prop];
break;
case 3:
this.list[data._pageIndex - 1][data.prop] = data.deliveTime;
break;
default:
console.log(val);
}
},
submitForm() {
Promise.all(
this.list.map((ele) => {
return orderCreate(ele);
})
).then((res) => {
this.$modal.msgSuccess('操作成功');
this.$emit('splitWorkOrderSubmit');
});
// this.$refs['orderAddForm'].validate((valid) => {
// if (valid) {
// if (this.form.planStartTime && this.form.planFinishTime) {
// if (this.form.planStartTime > this.form.planFinishTime) {
// this.$modal.msgError('')
// return false
// }
// }
// // console.log(this.form)
// if (this.isEdit) {
// //
// orderUpdate({ ...this.form }).then((res) => {
// if (res.code === 0) {
// this.$modal.msgSuccess("");
// this.$emit('successSubmit')
// }
// })
// } else {
// this.form.status = 1
// this.form.triggerOrigin = 1
// orderCreate({ ...this.form }).then((res) => {
// if (res.code === 0) {
// this.$modal.msgSuccess("");
// this.$emit('successSubmit')
// }
// })
// }
// } else {
// return false
// }
// })
},
formClear() {
this.$refs.orderAddForm.resetFields();
},
},
};
</script>

View File

@ -0,0 +1,51 @@
<template>
<div class="tableInner">
<el-select
v-model="list[list.prop]"
@change="changeInput">
<el-option
v-for="item in list.prop === 'packSpec'
? getDictDatas(DICT_TYPE.PACK_SPEC)
: list.customerList"
:key="list.prop === 'packSpec' ? item.value : item.id"
:label="list.prop === 'packSpec' ? item.label : item.name"
:value="
list.prop === 'packSpec' ? parseInt(item.value) : item.id
"></el-option>
</el-select>
</div>
</template>
<script>
export default {
name: 'InputArea',
props: {
injectData: {
type: Object,
default: () => ({}),
},
itemProp: {
type: String,
},
},
data() {
return {
list: this.injectData,
};
},
created() {
},
methods: {
changeInput() {
this.list.sType = 2;
this.$emit('emitData', this.list);
},
},
};
</script>
<style scoped>
.tableInner .el-input__inner {
border: none;
padding: 0;
height: 33px;
}
</style>

View File

@ -0,0 +1,47 @@
<template>
<div class="tableInner">
<el-date-picker
@change="changeInput"
v-model="list.deliveTime"
type="datetime"
size="mini"
:style="{width:'100%'}"
format='yyyy-MM-dd'
value-format="timestamp"
prefix-icon="none"
placeholder="选择日期">
</el-date-picker>
</div>
</template>
<script>
export default {
name: "InputArea",
props: {
injectData: {
type: Object,
default: () => ({}),
},
itemProp: {
type: String,
},
},
data() {
return {
list: this.injectData,
};
},
methods: {
changeInput() {
this.list.sType = 3
this.$emit("emitData", this.list);
},
},
};
</script>
<style scoped>
.tableInner .el-input__inner {
border: none;
padding: 0;
height: 33px;
}
</style>

File diff suppressed because it is too large Load Diff

View File

@ -1,357 +1,440 @@
<template>
<div class="orderDetailData">
<div class="box1">
<div class="boxTitle">
<span class="blueTitle"></span>
<span>订单编码: {{orderMsg.code}}</span>
</div>
<el-button type="primary" plain size="small" style="float: right;" @click="returnOrderManage">
<svg-icon icon-class="return" /> 返回
</el-button>
<div style="padding-left: 14px;">
<el-row>
<el-col :span='3'>
<div class="blodTip">订单名</div>
<div class="lightTip">{{orderMsg.name}}</div>
</el-col>
<el-col :span='3'>
<div class="blodTip">产品信息</div>
<div class="lightTip">{{orderMsg.productName}}</div>
</el-col>
<el-col :span='3'>
<div class="blodTip">产品规格</div>
<div class="lightTip">{{orderMsg.specifications}}</div>
</el-col>
<el-col :span='3'>
<div class="blodTip">客户</div>
<div class="lightTip">{{orderMsg.customerName}}</div>
</el-col>
<el-col :span='3'>
<div class="blodTip">包装规格</div>
<div class="lightTip">{{ getDictDataLabel(DICT_TYPE.PACK_SPEC, orderMsg.packSpec)}}</div>
</el-col>
<!-- <el-col :span='3'>
<div class="blodTip">物料计算方式</div>
<div class="lightTip">{{orderMsg.materialMethod ? (orderMsg.materialMethod === 1 ? '产品基础' : '工艺扩展') : ''}}
</div>
</el-col> -->
<el-col :span='3'>
<div class="blodTip">创建时间</div>
<div class="lightTip">{{ parseTime(orderMsg.createTime) }}</div>
</el-col>
<el-col :span='3'>
<div class="blodTip">计划开始时间</div>
<div class="lightTip">{{ parseTime(orderMsg.planStartTime) }}</div>
</el-col>
</el-row>
<el-row>
<el-col :span='3'>
<div class="blodTip">计划完成时间</div>
<div class="lightTip">{{ parseTime(orderMsg.planFinishTime) }}</div>
</el-col>
<el-col :span='3'>
<div class="blodTip">计划加工数量</div>
<div class="lightTip">{{orderMsg.planQuantity}}</div>
</el-col>
<el-col :span='3'>
<div class="blodTip">加工平方数(平方米)</div>
<div class="lightTip">{{orderMsg.planArea}}</div>
</el-col>
<el-col :span='3'>
<div class="blodTip">预计用时()</div>
<div class="lightTip">{{ orderMsg.expectTime }}</div>
</el-col>
<el-col :span='3'>
<div class="blodTip">状态</div>
<div class="lightTip">{{getDictDataLabel(DICT_TYPE.ORDER_STATUS, orderMsg.status)}}</div>
</el-col>
<el-col :span='3'>
<div class="blodTip">实际开始时间</div>
<div class="lightTip">{{ parseTime(orderMsg.startProduceTime) }}</div>
</el-col>
<el-col :span='3'>
<div class="blodTip">实际完成时间</div>
<div class="lightTip">{{ parseTime(orderMsg.finishProduceTime) }}</div>
</el-col>
<el-col :span='3'>
<div class="blodTip">实际生产数量</div>
<div class="lightTip">{{orderMsg.actualQuantity }}</div>
</el-col>
</el-row>
<el-row>
<el-col :span='3'>
<div class="blodTip">完成比%</div>
<div class="lightTip">{{orderMsg.completeProp}}</div>
</el-col>
<el-col :span='3'>
<div class="blodTip">废片数量</div>
<div class="lightTip">{{orderMsg.nokQuantity}}</div>
</el-col>
<el-col :span='3'>
<div class="blodTip">负责人</div>
<div class="lightTip">{{orderMsg.workers}}</div>
</el-col>
<!-- <el-col :span='3'>
<div class="orderDetailData">
<div class="box1">
<div class="boxTitle">
<span class="blueTitle"></span>
<span>订单编码: {{ orderMsg.code }}</span>
</div>
<el-button
type="primary"
plain
size="small"
style="float: right; margin-top: -10px"
@click="returnOrderManage">
<svg-icon icon-class="return" />
返回
</el-button>
<div style="padding-left: 14px; margin-top: 20px">
<el-row>
<el-col :span="3">
<div class="blodTip">订单名</div>
<div class="lightTip">{{ orderMsg.name }}</div>
</el-col>
<el-col :span="3">
<div class="blodTip">产品名称</div>
<div class="lightTip">{{ orderMsg.productName }}</div>
</el-col>
<el-col :span="3">
<div class="blodTip">产品规格</div>
<div class="lightTip">{{ orderMsg.specifications }}</div>
</el-col>
<el-col :span="3">
<div class="blodTip">客户</div>
<div class="lightTip">{{ orderMsg.customerName }}</div>
</el-col>
<el-col :span="3">
<div class="blodTip">包装规格</div>
<div class="lightTip">
{{ getDictDataLabel(DICT_TYPE.PACK_SPEC, orderMsg.packSpec) }}
</div>
</el-col>
<el-col :span="3">
<div class="blodTip">物料计算方式</div>
<div class="lightTip">
{{
orderMsg.materialMethod
? orderMsg.materialMethod === 1
? '产品基础'
: '工艺扩展'
: ''
}}
</div>
</el-col>
<!-- <el-col :span="3">
<div class="blodTip">计划开始时间</div>
<div class="lightTip">{{ parseTime(orderMsg.planStartTime) }}</div>
</el-col> -->
</el-row>
<el-row>
<el-col :span="3">
<div class="blodTip">创建时间</div>
<div class="lightTip">{{ parseTime(orderMsg.createTime) }}</div>
</el-col>
<el-col :span="3">
<div class="blodTip">交货时间</div>
<div class="lightTip">{{ parseTime(orderMsg.deliveTime) }}</div>
</el-col>
<!-- <el-col :span="3">
<div class="blodTip">计划完成时间</div>
<div class="lightTip">{{ parseTime(orderMsg.planFinishTime) }}</div>
</el-col> -->
<el-col :span="3">
<div class="blodTip">计划加工数量</div>
<div class="lightTip">{{ orderMsg.planQuantity }}</div>
</el-col>
<!-- <el-col :span="3">
<div class="blodTip">加工平方数(平方米)</div>
<div class="lightTip">{{ orderMsg.planArea }}</div>
</el-col>
<el-col :span="3">
<div class="blodTip">预计用时()</div>
<div class="lightTip">{{ orderMsg.expectTime }}</div>
</el-col> -->
<el-col :span="3">
<div class="blodTip">状态</div>
<div class="lightTip">
{{ getDictDataLabel(DICT_TYPE.ORDER_STATUS, orderMsg.status) }}
</div>
</el-col>
<el-col :span="3">
<div class="blodTip">实际开始时间</div>
<div class="lightTip">
{{ parseTime(orderMsg.startProduceTime) }}
</div>
</el-col>
<el-col :span="3">
<div class="blodTip">实际完成时间</div>
<div class="lightTip">
{{ parseTime(orderMsg.finishProduceTime) }}
</div>
</el-col>
</el-row>
<el-row>
<el-col :span="3">
<div class="blodTip">实际生产数量</div>
<div class="lightTip">{{ orderMsg.actualQuantity }}</div>
</el-col>
<el-col :span="3">
<div class="blodTip">完成比%</div>
<div class="lightTip">{{ orderMsg.completeProp }}</div>
</el-col>
<el-col :span="3">
<div class="blodTip">废片数量</div>
<div class="lightTip">{{ orderMsg.nokQuantity }}</div>
</el-col>
<el-col :span="3">
<div class="blodTip">备注</div>
<div class="lightTip">{{ orderMsg.remark }}</div>
</el-col>
<!-- <el-col :span="3">
<div class="blodTip">负责人</div>
<div class="lightTip">{{ orderMsg.workers }}</div>
</el-col> -->
<!-- <el-col :span='3'>
<div class="blodTip">关联工艺</div>
<div class="lightTip">{{processFlowName}}</div>
</el-col> -->
</el-row>
</div>
</div>
<div class="box2">
<!-- <div class="boxTitle">
</el-row>
</div>
</div>
<div class="box2">
<!-- <div class="boxTitle">
<span class="blueTitle"></span>
<span>工单信息</span>
</div> -->
<div class="toggleTabBox">
<div :class="{ active: activeModule === 'orderInfo' }" @click="toggleTab('orderInfo')">子订单信息</div>
<!-- <div :class="{ active: activeModule === 'useInfo' }" @click="toggleTab('useInfo')">用料信息</div> -->
</div>
<!-- 列表 -->
<el-row v-show="activeModule === 'orderInfo'">
<el-col :span="6">
<el-tree :data="treeData" :props="defaultProps" @node-click="handleNodeClick"></el-tree>
</el-col>
<el-col :span="18">
<base-table :page="queryParams.pageNo" :limit="queryParams.pageSize" :table-props="tableProps1"
:table-data="list1" :max-height="tableH" />
</el-col>
</el-row>
<!-- <base-table v-show="activeModule === 'useInfo'" :page="queryParams.pageNo" :limit="queryParams.pageSize"
:table-props="tableProps2" :table-data="list2" :max-height="tableH" /> -->
</div>
</div>
<div class="toggleTabBox">
<div
:class="{ active: activeModule === 'orderInfo' }"
@click="toggleTab('orderInfo')">
子订单信息
</div>
<div
:class="{ active: activeModule === 'useInfo' }"
@click="toggleTab('useInfo')">
用料信息
</div>
</div>
<!-- 列表 -->
<el-row v-show="activeModule === 'orderInfo'">
<el-col :span="6">
<el-tree
:data="treeData"
:props="defaultProps"
default-expand-all
@node-click="handleNodeClick"></el-tree>
</el-col>
<el-col :span="18">
<base-table
:page="queryParams.pageNo"
:limit="queryParams.pageSize"
:table-props="tableProps1"
:table-data="list1"
:max-height="tableH" />
</el-col>
</el-row>
<base-table
v-show="activeModule === 'useInfo'"
:page="queryParams.pageNo"
:limit="queryParams.pageSize"
:table-props="tableProps2"
:table-data="list2"
:max-height="tableH" />
</div>
</div>
</template>
<script>
import { parseTime } from '@/utils/ruoyi'
import { publicFormatter } from '@/utils/dict'
import { getProcessFlowList } from '@/api/base/orderManage'
import { orderDetail, bomUseNum, getDetailTree, getDetailTreeInfo } from '@/api/base/orderManage'
import { parseTime } from '@/utils/ruoyi';
import { publicFormatter } from '@/utils/dict';
import {
getProcessFlowList,
getOrderRemainNum,
getMaterialCostOrder,
} from '@/api/base/orderManage';
import {
orderDetail,
bomUseNum,
getDetailTree,
getDetailTreeInfo,
} from '@/api/base/orderManage';
const tableProps1 = [
{
prop: 'issueTime',
label: '下发时间',
filter: parseTime,
minWidth: 160
},
{
prop: 'name',
label: '工单名',
minWidth: 100,
showOverflowtooltip: true
},
{
prop: 'code',
label: '工单编码',
minWidth: 150
},
{
prop: 'planAssignmentQuantity',
label: '计划加工量',
width: 100
},
{
prop: 'actualQuantity',
label: '实际加工量',
width: 100
},
{
prop: 'actualArea',
label: '加工平方数',
width: 100
},
{
prop: 'status',
label: '状态',
filter: publicFormatter('order_status')
},
{
prop: 'startProduceTime',
label: '开始时间',
filter: parseTime,
minWidth: 160
},
{
prop: 'finishProduceTime',
label: '结束时间',
filter: parseTime,
minWidth: 160
},
{
prop: 'productLineNames',
label: '关联产线',
filter: (val) => val ? val.join(',') : '',
showOverflowtooltip: true
},
{
prop: 'workers',
label: '负责人'
},
{
prop: 'remark',
label: '备注'
}
]
{
prop: 'issueTime',
label: '下发时间',
filter: parseTime,
minWidth: 160,
},
{
prop: 'type',
label: '订单/工单类型',
minWidth: 140,
showOverflowtooltip: true,
sortable:true
},
{
prop: 'name',
label: '订单/工单名',
minWidth: 100,
showOverflowtooltip: true,
},
{
prop: 'code',
label: '订单/工单编码',
minWidth: 165,
},
{
prop: 'planAssignmentQuantity',
label: '计划加工量',
width: 100,
},
{
prop: 'actualQuantity',
label: '实际加工量',
width: 100,
},
// {
// prop: 'actualArea',
// label: '',
// width: 100,
// },
{
prop: 'status',
label: '状态',
filter: publicFormatter('order_status'),
},
{
prop: 'startProduceTime',
label: '开始时间',
filter: parseTime,
minWidth: 160,
},
{
prop: 'finishProduceTime',
label: '结束时间',
filter: parseTime,
minWidth: 160,
},
{
prop: 'productLineNames',
label: '关联产线',
filter: (val) => (val ? val.join(',') : ''),
showOverflowtooltip: true,
},
{
prop: 'workers',
label: '负责人',
},
{
prop: 'remark',
label: '备注',
},
];
const tableProps2 = [
{
prop: 'materialName',
label: '物料名称'
},
{
prop: 'unit',
label: '单位',
filter: publicFormatter('unit_dict')
},
{
prop: 'num',
label: '剩余生产预计消耗'
}
]
{
prop: 'materialName',
label: '物料名称',
},
{
prop: 'unit',
label: '单位',
filter: publicFormatter('unit_dict'),
},
{
prop: 'num',
label: '剩余生产预计消耗',
},
];
export default {
name: 'OrderDetailData',
data() {
return {
orderId: '',
tableProps1,
treeData:undefined,
activeModule:'orderInfo',
tableProps2,
list1: [],
list2: [],
tableH: this.tableHeight(510) / 2,
//
queryParams: {
pageNo: 1,
pageSize: 500
},
defaultProps: {
children: 'children',
label: 'name'
},
orderMsg: {},
processFlowName: ''
}
},
mounted() {
window.addEventListener('resize', () => {
this.tableH = this.tableHeight(510) / 2
})
this.orderId = location.href.split('?')[1].split('=')[1]
this.getMsg()
},
watch: {
$route: 'initData'
},
methods: {
toggleTab(val) {
this.activeModule = val
},
handleNodeClick(val) {
console.log(val)
getDetailTreeInfo({
id: val.id
}).then(res => {
this.list1 = res.data.order
console.log(res)
})
},
initData(to) {
if (to.name === 'OrderDetailData') {
this.orderId = location.href.split('?')[1].split('=')[1]
this.getMsg()
}
},
getMsg() {
orderDetail({
id: this.orderId
}).then(res => {
this.orderMsg = res.data
this.list1 = res.data.coreWorkOrderRespVOS
bomUseNum({
productId: this.orderMsg.planProductId
}).then(res2 => {
if (res2.data && res2.data.length > 0) {
let arr = res2.data
arr.map(item => {
if (item) {
let a = item.num * this.orderMsg.remainingQuantity
item.num = !isNaN(parseFloat(a)) && isFinite(a) ? a : ''
}
})
this.list2 = arr
}else {
this.list2 = []
}
})
getDetailTree({
id: this.orderId
}).then(res => {
console.log(res)
this.treeData =res.data
name: 'OrderDetailData',
data() {
return {
orderId: '',
tableProps1,
treeData: undefined,
activeModule: 'orderInfo',
tableProps2,
list1: [],
list2: [],
tableH: this.tableHeight(510) / 2,
//
queryParams: {
pageNo: 1,
pageSize: 500,
},
defaultProps: {
children: 'children',
label: 'name',
},
orderMsg: {},
processFlowName: '',
};
},
activated() {
window.addEventListener('resize', () => {
this.tableH = this.tableHeight(510) / 2;
});
this.orderId = location.href.split('=')[1];
this.getMsg();
},
watch: {
$route: 'initData',
},
methods: {
toggleTab(val) {
this.activeModule = val;
},
handleNodeClick(val) {
getDetailTreeInfo({
id: val.id,
}).then((res) => {
this.list1 = res.data;
});
},
initData(to) {
if (to.name === 'OrderDetailData') {
this.orderId = location.href.split('=')[1];
this.getMsg();
}
},
getMsg() {
orderDetail({
id: this.orderId,
}).then((res) => {
this.orderMsg = res.data;
getOrderRemainNum(this.orderId).then((resNum) => {
bomUseNum({
productId: this.orderMsg.planProductId,
}).then((res2) => {
if (res2.data && res2.data.length > 0) {
let arr = res2.data;
arr.map((item) => {
if (item) {
let a = item.num * resNum.data;
item.num = !isNaN(parseFloat(a)) && isFinite(a) ? a : '';
}
});
this.list2 = arr;
this.getMaterialCostOrder(this.orderId);
} else {
this.list2 = [];
}
});
});
getDetailTreeInfo({
id: this.orderId,
}).then((res) => {
this.list1 = res.data;
});
getDetailTree({
id: this.orderId,
}).then((res) => {
this.treeData = res.data;
this.treeData.unshift({
id:this.orderId,
name:'全部'
})
//
getProcessFlowList().then(res => {
let arr = res.data || []
if (arr.length > 0) {
arr.map(item => {
if (item.id === this.orderMsg.processFlowId) {
this.processFlowName = item.name
}
})
}
})
})
},
//
returnOrderManage() {
this.$router.go(-1);
}
}
}
});
//
getProcessFlowList().then((res) => {
let arr = res.data || [];
if (arr.length > 0) {
arr.map((item) => {
if (item.id === this.orderMsg.processFlowId) {
this.processFlowName = item.name;
}
});
}
});
});
},
getMaterialCostOrder(id) {
getMaterialCostOrder({ id }).then((res) => {
this.list2.push(...res.data);
});
},
//
returnOrderManage() {
this.$router.go(-1);
},
},
};
</script>
<style lang='scss' scoped>
<style lang="scss" scoped>
.orderDetailData {
background-color: rgb(242, 244, 249);
.box1, .box2, .box3 {
background-color: #fff;
border-radius: 9px;
}
.box2 {
height: calc((100vh - 360px));
padding: 12px 16px 0;
margin: 8px 0;
.toggleTabBox {
display: inline-block;
div {
display: inline-block;
padding: 0 8px 4px;
color: rgba(102, 102, 102, 0.5);
border-bottom: 2px solid rgba(242, 244, 249, 1);
cursor: pointer;
}
.active {
color: rgba(0, 0, 0, 0.85);
border-bottom-color: #0B58FF;
}
}
}
.box1 {
height: 215px;
padding: 16px 16px 0 16px;
.blodTip {
height: 16px;
font-size: 14px;
font-weight: 600;
color: rgba(0,0,0,0.85);
margin-bottom: 8px;
}
.lightTip {
height: 16px;
font-size: 14px;
font-weight: 400;
color: rgba(102,102,102,0.75);
margin-bottom: 12px;
}
}
background-color: rgb(242, 244, 249);
.box1,
.box2,
.box3 {
background-color: #fff;
border-radius: 9px;
}
.box2 {
height: calc((100vh - 360px));
padding: 12px 16px 0;
margin: 8px 0;
.toggleTabBox {
display: inline-block;
div {
display: inline-block;
padding: 0 8px 4px;
color: rgba(102, 102, 102, 0.5);
border-bottom: 2px solid rgba(242, 244, 249, 1);
cursor: pointer;
}
.active {
color: rgba(0, 0, 0, 0.85);
border-bottom-color: #0b58ff;
}
}
}
.box1 {
height: 215px;
padding: 16px 16px 0 16px;
.blodTip {
height: 16px;
font-size: 14px;
font-weight: 600;
color: rgba(0, 0, 0, 0.85);
margin-bottom: 8px;
}
.lightTip {
height: 16px;
font-size: 14px;
font-weight: 400;
color: rgba(102, 102, 102, 0.75);
margin-bottom: 12px;
}
}
}
</style>

View File

@ -1,315 +1,496 @@
<template>
<el-form ref="dataForm" :rules="rules" label-width="130px" :model="dataForm" label-position="top">
<el-row :gutter="20">
<el-col :span='8'>
<el-form-item label="工单名称" prop="name">
<el-input v-model="dataForm.name" placeholder="请输入工单名称"></el-input>
</el-form-item>
</el-col>
<el-col :span='8'>
<el-form-item label="工单编码" prop="code">
<el-input v-model="dataForm.code" disabled placeholder="请输入工单编码"></el-input>
</el-form-item>
</el-col>
<el-col :span='8'>
<el-form-item label="产品名称" prop="planProductId">
<el-select v-model="dataForm.planProductId" placeholder="请选择产品" style="width: 100%;" filterable
@change="selectProduct">
<el-option v-for="item in productList" :key="item.id" :label="item.name" :value="item.id">
</el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span='8'>
<el-form-item label="产品规格" prop="specifications">
<el-input v-model="dataForm.specifications" placeholder="请输入产品规格" />
</el-form-item>
</el-col>
<el-col :span='8'>
<el-form-item label="计划开始时间">
<el-date-picker v-model="dataForm.planStartTime" type="datetime" value-format="timestamp" style="width: 100%;"
placeholder="请选择计划开始时间">
</el-date-picker>
</el-form-item>
</el-col>
<el-col :span='8'>
<el-form-item label="计划完成时间">
<el-date-picker v-model="dataForm.planFinishTime" type="datetime" value-format="timestamp"
style="width: 100%;" placeholder="请选择计划完成时间">
</el-date-picker>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span='8'>
<el-form-item label="计划投入数量" prop="planAssignQuantity">
<el-input-number v-model="dataForm.planAssignQuantity" :min="0" :max="9999999999999" style="width: 100%;"
placeholder="请输入计划投入数量"></el-input-number>
</el-form-item>
</el-col>
<el-col :span='8'>
<el-form-item label="计划生产数量" prop="planQuantity">
<el-input-number v-model="dataForm.planQuantity" :min="0" :max="9999999999999" style="width: 100%;"
placeholder="请输入计划生产数量"></el-input-number>
</el-form-item>
</el-col>
<el-col :span='8'>
<el-form-item label="关联工艺" prop="processFlowId">
<el-select v-model="dataForm.processFlowId" placeholder="请选择关联工艺" clearable filterable style="width: 100%;"
@change="processFlowIdChange">
<el-option v-for="item in processFlowList" :key="item.id" :label="item.name" :value="item.id">
</el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span='8'>
<el-form-item label="物料计算方式" prop="materialMethod">
<!-- <el-radio-group v-model="dataForm.materialMethod" @change="materialMethodChange">
<el-radio :label="1">产品基础BOM</el-radio>
<el-radio :label="2">工艺扩展BOM</el-radio>
</el-radio-group> -->
<el-select v-model="dataForm.materialMethod" placeholder="请选择物料计算方式" style="width: 100%;"
<el-form
ref="dataForm"
:rules="rules"
label-width="130px"
:model="dataForm"
label-position="top">
<el-row :gutter="20">
<el-col :span="8">
<el-form-item label="工单名称" prop="name">
<el-input
v-model="dataForm.name"
placeholder="请输入工单名称"></el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="工单编码" prop="code">
<el-input
v-model="dataForm.code"
disabled
placeholder="请输入工单编码"></el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="产品名称" prop="planProductId">
<el-select
v-model="dataForm.planProductId"
placeholder="请选择产品"
style="width: 100%"
filterable
@change="selectProduct">
<el-option
v-for="item in productList"
:key="item.id"
:label="item.name"
:value="item.id"></el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="8">
<el-form-item label="产品规格" prop="specifications">
<el-input
v-model="dataForm.specifications"
placeholder="请输入产品规格" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="计划开始时间">
<el-date-picker
v-model="dataForm.planStartTime"
type="datetime"
value-format="timestamp"
style="width: 100%"
placeholder="请选择计划开始时间"></el-date-picker>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="计划完成时间">
<el-date-picker
v-model="dataForm.planFinishTime"
type="datetime"
value-format="timestamp"
style="width: 100%"
placeholder="请选择计划完成时间"></el-date-picker>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="8">
<el-form-item label="计划投入数量" prop="planAssignQuantity">
<el-input-number
v-model="dataForm.planAssignQuantity"
:min="0"
:max="9999999999999"
style="width: 100%"
placeholder="请输入计划投入数量"></el-input-number>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="计划生产数量" prop="planQuantity">
<el-input-number
v-model="dataForm.planQuantity"
:min="0"
:max="9999999999999"
style="width: 100%"
placeholder="请输入计划生产数量"></el-input-number>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="优先级" prop="priority">
<el-select
v-model="dataForm.priority"
placeholder="请选择优先级"
style="width: 100%">
<el-option
v-for="item in getDictDatas(DICT_TYPE.ORDER_PRIORITY)"
:key="item.value"
:label="item.label"
:value="item.value"></el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="8">
<el-form-item label="工单类型" prop="type">
<el-select
v-model="dataForm.type"
placeholder="请选择工单类型"
style="width: 100%">
<el-option
v-for="item in workOrderTypeList"
: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="deptId">
<el-select
v-model="dataForm.deptId"
placeholder="请选择负责部门"
style="width: 100%">
<el-option
v-for="item in deptList"
: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="workers">
<el-input
v-model="dataForm.workers"
placeholder="请输入负责人"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<span class="add-type">物料计算方式</span>
<el-radio-group
v-model="dataForm.materialMethod"
@change="materialMethodChange">
<el-radio :label="1">产品基础BOM</el-radio>
<el-radio :label="2">工艺扩展BOM</el-radio>
</el-radio-group>
<!-- <el-select v-model="dataForm.materialMethod" placeholder="请选择物料计算方式" style="width: 100%;"
@change="materialMethodChange">
<el-option key="1" label="产品基础BOM" :value="1" />
<el-option key="2" label="工艺扩展BOM" :value="2" />
</el-select>
</el-form-item>
</el-col>
<el-col :span='8'>
<el-form-item label="优先级" prop="priority">
<el-select v-model="dataForm.priority" placeholder="请选择优先级" style="width: 100%;">
<el-option v-for="item in getDictDatas(DICT_TYPE.ORDER_PRIORITY)" :key="item.value" :label="item.label"
:value="item.value">
</el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span='8'>
<el-form-item label="工单类型" prop="type">
<el-select v-model="dataForm.type" placeholder="请选择工单类型" style="width: 100%;">
<el-option v-for="item in workOrderTypeList" :key="item.id" :label="item.name" :value="item.id">
</el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span='8'>
<el-form-item label="关联产线" prop="productLineIds">
<el-select v-model="dataForm.productLineIds" placeholder="请选择关联产线" multiple style="width: 100%;">
<el-option v-for="item in productLineList" :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="deptId">
<el-select v-model="dataForm.deptId" placeholder="请选择关联产线" style="width: 100%;">
<el-option v-for="item in deptList" :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="workers">
<el-input v-model="dataForm.workers" placeholder="请输入负责人"></el-input>
</el-form-item>
</el-col>
</el-row>
<!-- <el-row>
</el-select> -->
</el-col>
</el-row>
<div v-if="dataForm.materialMethod === 1">
<el-row :gutter="20">
<el-col :span="24">
<span style="margin: 8px 0;" class="add-type">关联产线</span>
<el-button style="margin-left: 20px" type="text" @click="addBind">
新增
</el-button>
</el-col>
</el-row>
<el-row
:gutter="20"
v-for="(item, index) in dataForm.productLineIds"
:key="index + 'line'"
style="margin-bottom: 8px">
<el-col :span="8">
<el-select
v-model="item.lineId"
placeholder="请选择产线"
style="width: 100%">
<el-option
v-for="item in productLineList"
:key="item.id"
:label="item.name"
:value="item.id"></el-option>
</el-select>
</el-col>
<el-col :span="8">
<el-input-number
style="width: 100%"
v-model="item.num"
placeholder="请输入数量"
:step="1"
:min="0"
step-strictly />
</el-col>
</el-row>
</div>
<div v-else>
<el-row :gutter="20">
<el-col :span="24">
<span style="margin: 8px 0; display: inline-block">
关联产线及工艺
</span>
<el-button style="margin-left: 20px" type="text" @click="addBind">
新增
</el-button>
</el-col>
</el-row>
<el-row
:gutter="20"
v-for="(item, index) in dataForm.productLineIds"
:key="index + 'process'"
style="margin-bottom: 8px">
<el-col :span="8">
<el-select
v-model="item.lineId"
placeholder="请选择产线"
style="width: 100%"
@change="processLineIdChange">
<el-option
v-for="item in productLineList"
:key="item.id"
:label="item.name"
:value="item.id"></el-option>
</el-select>
</el-col>
<el-col :span="8">
<el-select
v-model="item.processId"
placeholder="请选择工艺"
filterable
style="width: 100%">
<el-option
v-for="item in processFlowList"
:key="item.id"
:label="item.name"
:value="item.id"></el-option>
</el-select>
</el-col>
<el-col :span="8">
<el-input-number
style="width: 100%"
v-model="item.num"
:step="1"
:min="0"
step-strictly />
</el-col>
</el-row>
</div>
<!-- <el-row>
<el-col :span='12'>
<el-form-item label="计划分配订单量" prop="planAssignmentQuantity">
<el-input-number v-model="form.planAssignmentQuantity" :min="0" :max="9999999999999" style="width: 100%;"></el-input-number>
</el-form-item>
</el-col>
</el-row> -->
</el-form>
</el-form>
</template>
<script>
import { getProductAll } from '@/api/base/product'
import { getProcessFlowList, workOrderList } from '@/api/base/orderManage'
import { createCoreWO, updateCoreWO, getCode, getCoreWO } from '@/api/base/coreWorkOrder'
import { getLineAll } from '@/api/base/productionLine'
import { getProductAll } from '@/api/base/product';
import { getProcessFlowPage, workOrderList } from '@/api/base/orderManage';
import {
createCoreWO,
updateCoreWO,
getCode,
getCoreWO,
} from '@/api/base/coreWorkOrder';
import { getLineAll } from '@/api/base/productionLine';
import basicAdd from '../../core/mixins/basic-add';
import { listDept } from '@/api/system/dept';
export default {
name: 'AddWorkOrder',
mixins: [basicAdd],
data() {
return {
urlOptions: {
isGetCode: true,
codeURL: getCode,
name: 'AddWorkOrder',
mixins: [basicAdd],
data() {
return {
urlOptions: {
isGetCode: true,
codeURL: getCode,
createURL: createCoreWO,
updateURL: updateCoreWO,
infoURL: getCoreWO
infoURL: getCoreWO,
},
dataForm: {
id: undefined,
workOrderId: '',
name: '',
code: '',
deptId:undefined,
planProductId: '',
specifications: '',
planStartTime: '',
planFinishTime: '',
planAssignQuantity: 0,
planQuantity: 0,
processFlowId: '',
materialMethod: 1,
triggerOrigin: 1,
priority: '',
productLineIds: [],
type: '',
workers: '',
status: 1
},
rules: {
name: [{ required: true, message: "工单名称不能为空", trigger: "blur" }],
planProductId: [{ required: true, message: "产品名称不能为空", trigger: "change" }],
planAssignQuantity: [{ required: true, message: "计划投入数量不能为空", trigger: "blur" }],
planQuantity: [{ required: true, message: "计划生产数量不能为空", trigger: "blur" }],
productLineIds: [{ required: true, message: "关联产线不能为空", trigger: "change" }]
},
productList: [],
processFlowList: [],
productLineList: [],
deptList:[],
workOrderTypeList: [
{id: 1,name:'普通'},
{id: 2, name:'特殊'}
],
planStartTime: '',
planFinishTime: '',
isBind: false,
workOrderList: []
}
},
mounted() {
this.getDict()
},
methods: {
//
materialMethodChange(val) {
if (val === 2 && !this.dataForm.processFlowId) {
this.dataForm.materialMethod = 1
this.$modal.msgError("请先选择关联工艺");
}
},
//
processFlowIdChange(val) {
console.log(val)
if (!val) {
this.dataForm.materialMethod = 1
}
},
init(id) {
this.dataForm.id = id || "";
this.visible = true;
if (this.urlOptions.getOption) {
this.getArr()
}
this.$nextTick(() => {
this.$refs["dataForm"].resetFields();
this.planStartTime = ''
this.planFinishTime = ''
if (this.dataForm.id) {
getCoreWO(id).then(response => {
this.dataForm = response.data;
if (this.dataForm.priority !== undefined) {
this.dataForm.priority = String(this.dataForm.priority)
}
this.dataForm.priority
});
} else {
if (this.urlOptions.isGetCode) {
this.getCode()
}
dataForm: {
id: undefined,
workOrderId: '',
name: '',
code: '',
deptId: undefined,
planProductId: '',
specifications: '',
planStartTime: '',
planFinishTime: '',
planAssignQuantity: 0,
planQuantity: 0,
materialMethod: 1,
triggerOrigin: 1,
priority: '',
productLineIds: [{ lineId: null, processId: null, num: null }],
type: '',
workers: '',
status: 1,
},
rules: {
name: [
{ required: true, message: '工单名称不能为空', trigger: 'blur' },
],
planProductId: [
{ required: true, message: '产品名称不能为空', trigger: 'change' },
],
planAssignQuantity: [
{ required: true, message: '计划投入数量不能为空', trigger: 'blur' },
],
planQuantity: [
{ required: true, message: '计划生产数量不能为空', trigger: 'blur' },
],
deptId: [
{ required: true, message: '负责部门不能为空', trigger: 'change' },
],
},
productList: [],
processFlowList: [],
productLineList: [],
deptList: [],
workOrderTypeList: [
{ id: 1, name: '普通' },
{ id: 2, name: '特殊' },
],
planStartTime: '',
planFinishTime: '',
isBind: false,
workOrderList: [],
};
},
mounted() {
this.getDict();
},
methods: {
//
materialMethodChange(val) {
console.log(val);
this.processFlowList = [];
this.dataForm.productLineIds = [];
const obj = { lineId: null, processId: null, num: null };
this.dataForm.productLineIds.push(obj);
// if (val === 2 && !this.dataForm.processFlowId) {
// this.dataForm.materialMethod = 1;
// this.$modal.msgError('');
// }
},
// 线
processLineIdChange(val) {
const params = {
pageNo: 1,
pageSize: 100,
lineId: val,
};
//
getProcessFlowPage(params).then((res) => {
this.processFlowList = res.data.list || [];
});
},
init(id) {
this.dataForm.id = id || '';
this.visible = true;
if (this.urlOptions.getOption) {
this.getArr();
}
this.$nextTick(() => {
this.$refs['dataForm'].resetFields();
this.planStartTime = '';
this.planFinishTime = '';
if (this.dataForm.id) {
getCoreWO(id).then((response) => {
this.dataForm = response.data;
if (this.dataForm.priority !== undefined) {
this.dataForm.priority = String(this.dataForm.priority);
}
this.dataForm.priority;
});
} else {
if (this.urlOptions.isGetCode) {
this.getCode();
}
}
});
},
//
dataFormSubmit() {
this.$refs["dataForm"].validate((valid) => {
if (!valid) {
return false;
}
//
if (this.dataForm.id) {
this.urlOptions.updateURL(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.$confirm('是否添加预使用主原料信息?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
console.log('121', this.dataForm.name)
this.$emit("refreshDataList", {
id: response.data,
name: this.dataForm.name
});
}).catch(() => {
this.$emit("refreshDataList");
});
});
});
},
getCode() {
this.urlOptions.codeURL()
});
},
//
dataFormSubmit() {
this.$refs['dataForm'].validate((valid) => {
if (!valid) {
return false;
}
let isContinue = true;
if (this.dataForm.materialMethod === 1) {
this.dataForm.productLineIds.forEach((item) => {
if (!item.lineId) {
this.$message('关联产线不能为空');
isContinue = false;
}
});
} else {
this.dataForm.productLineIds.forEach((item) => {
if (!item.lineId || !item.processId) {
this.$message('关联产线及工艺不能为空');
isContinue = false;
}
});
}
//
if (this.dataForm.id && isContinue) {
this.urlOptions.updateURL(this.dataForm).then((response) => {
this.$modal.msgSuccess('修改成功');
this.visible = false;
this.$emit('refreshDataList');
});
return;
}
//
if (isContinue) {
this.urlOptions.createURL(this.dataForm).then((response) => {
this.$modal.msgSuccess('新增成功');
this.visible = false;
this.$confirm('是否添加预使用主原料信息?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
})
.then(() => {
console.log('121', this.dataForm.name);
this.$emit('refreshDataList', {
id: response.data,
name: this.dataForm.name,
});
})
.catch(() => {
this.$emit('refreshDataList');
});
});
}
});
},
getCode() {
this.urlOptions
.codeURL()
.then(({ data: res }) => {
this.dataForm.code = res;
})
.catch(() => {});
},
getDict() {
//
getProductAll().then(res => {
this.productList = res.data || []
})
// 线
getLineAll().then(res => {
this.productLineList = res.data || []
})
listDept().then(res => {
this.deptList = res.data || []
})
//
getProcessFlowList().then(res => {
this.processFlowList = res.data || []
})
// list
workOrderList({
status: 1
}).then(res => {
this.workOrderList = res.data || []
})
},
//
selectProduct(val) {
if (val) {
this.productList.map(item => {
if (val === item.id) {
this.dataForm.specifications = item.specifications
}
})
} else {
this.dataForm.specifications = ''
}
}
}
}
getDict() {
//
getProductAll().then((res) => {
this.productList = res.data || [];
});
// 线
getLineAll().then((res) => {
this.productLineList = res.data || [];
});
listDept().then((res) => {
this.deptList = res.data || [];
});
// list
workOrderList({
status: 1,
}).then((res) => {
this.workOrderList = res.data || [];
});
},
//
selectProduct(val) {
if (val) {
this.productList.map((item) => {
if (val === item.id) {
this.dataForm.specifications = item.specifications;
}
});
} else {
this.dataForm.specifications = '';
}
},
addBind() {
const obj = { lineId: null, processId: null, num: null };
this.dataForm.productLineIds.push(obj);
},
},
};
</script>
<style scoped>
.add-type {
margin: 0 20px 15px 0;
display: inline-block;
}
.add-type::before {
content: '*';
color: #ff4949;
margin-right: 4px;
}
</style>

View File

@ -1,8 +1,8 @@
<!--
* @Author: zwq
* @Date: 2021-11-18 14:16:25
* @LastEditors: zhp
* @LastEditTime: 2024-09-11 10:27:13
* @LastEditors: zwq
* @LastEditTime: 2024-10-15 16:16:22
* @Description:
-->
<template>
@ -157,7 +157,7 @@
<script>
// import basicAdd from '../../core/mixins/basic-add';
import { getCoreWO, getMaterialBomPage, getConOrderList, getCoreWOListById } from "@/api/base/coreWorkOrder";
import { getCoreWO, getMaterialBomPage, getConOrderList, getCoreWOListById,getMaterialCostWorkOrder } from "@/api/base/coreWorkOrder";
import tableHeightMixin from '@/mixins/tableHeightMixin';
import { getOrderEnergyData } from "@/api/monitoring/orderEnergy";
// import { orderList } from "@/api/base/orderManage";
@ -215,7 +215,7 @@ const tableProps1 = [
filter: publicFormatter('unit_dict')
},
{
prop: 'num',
prop: 'remainingNum',
label: '剩余生产预计消耗'
},
];
@ -390,8 +390,8 @@ export default {
// this.listQuery.total = response.data.total;
});
}else if (this.activeName === 'material') {
getConOrderList({
workOrderId: this.dataForm.id,
getMaterialCostWorkOrder({
id: this.dataForm.id,
}).then((response) => {
this.materialList = response.data;
// this.listQuery.total = response.data.total;

View File

@ -1,66 +1,17 @@
<template>
<div class="app-container">
<el-form
:model="queryParams"
ref="queryForm"
size="small"
:inline="true"
v-show="showSearch">
<el-form-item label="部门名称" prop="name">
<el-input
v-model="queryParams.name"
placeholder="请输入部门名称"
clearable
@keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="状态" prop="status">
<el-select
v-model="queryParams.status"
placeholder="菜单状态"
clearable>
<el-option
v-for="dict in statusDictDatas"
:key="parseInt(dict.value)"
:label="dict.label"
:value="parseInt(dict.value)" />
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" @click="handleQuery">
搜索
</el-button>
<el-button icon="el-icon-refresh" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleAdd"
v-hasPermi="['system:dept:create']">
新增
</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="info"
plain
icon="el-icon-sort"
size="mini"
@click="toggleExpandAll">
展开/折叠
</el-button>
</el-col>
<right-toolbar
:showSearch.sync="showSearch"
@queryTable="getList"></right-toolbar>
</el-row>
<search-bar
:formConfigs="formConfig"
ref="searchBarForm"
@headBtnClick="buttonClick" />
<el-table
:header-cell-style="{
background: '#F2F4F9',
color: '#606266',
}"
border
style="width: 100%"
v-if="refreshTable"
v-loading="loading"
:data="deptList"
@ -125,8 +76,14 @@
</el-table-column>
</el-table>
<!-- 添加或修改部门对话框 -->
<el-dialog :title="title" :visible.sync="open" width="600px" append-to-body>
<!-- 添加或修改菜单对话框 -->
<el-dialog :visible.sync="open" width="800px" append-to-body class="dialog">
<template #title>
<slot name="title">
<div class="titleStyle">{{ title }}</div>
</slot>
</template>
<slot />
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-row>
<el-col :span="24">
@ -197,8 +154,8 @@
</el-row>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
<el-button class="btnTextStyle" @click="cancel"> </el-button>
<el-button type="primary" class="btnTextStyle" @click="submitForm"> </el-button>
</div>
</el-dialog>
</div>
@ -276,6 +233,40 @@ export default {
],
status: [{ required: true, message: '状态不能为空', trigger: 'blur' }],
},
formConfig: [
{
type: 'input',
label: '部门名称',
placeholder: '部门名称',
param: 'name',
},
{
type: 'select',
label: '状态',
selectOptions: getDictDatas(DICT_TYPE.COMMON_STATUS),
param: 'status',
defaultSelect: '',
valueField: 'value',
labelField: 'label',
filterable: true,
},
{
type: 'button',
btnName: '查询',
name: 'search',
color: 'primary',
},
{
type: this.$auth.hasPermi('system:dept:create') ? 'separate' : '',
},
{
type: this.$auth.hasPermi('system:dept:create') ? 'button' : '',
btnName: '新增',
name: 'add',
color: 'success',
plain: true,
},
],
//
CommonStatusEnum: CommonStatusEnum,
@ -291,6 +282,15 @@ export default {
});
},
methods: {
buttonClick(val) {
if (val.btnName === 'search') {
this.queryParams.name = val.name;
this.queryParams.status = val.status;
this.getList();
} else {
this.handleAdd();
}
},
/** 查询部门列表 */
getList() {
this.loading = true;
@ -422,3 +422,36 @@ export default {
},
};
</script>
<style scoped>
.app-container >>> .el-table .el-table__cell {
padding: 0;
height: 35px;
}
.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;
}
.dialog >>> .btnTextStyle {
letter-spacing: 6px;
padding: 9px 10px 9px 16px;
font-size: 14px;
}
</style>

View File

@ -1,38 +1,18 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="字典名称" prop="dictType">
<el-select v-model="queryParams.dictType">
<el-option v-for="item in typeOptions" :key="item.id" :label="item.name" :value="item.type"/>
</el-select>
</el-form-item>
<el-form-item label="字典标签" prop="label">
<el-input v-model="queryParams.label" placeholder="请输入字典标签" clearable @keyup.enter.native="handleQuery"/>
</el-form-item>
<el-form-item label="状态" prop="status">
<el-select v-model="queryParams.status" placeholder="数据状态" clearable>
<el-option v-for="dict in statusDictDatas" :key="dict.value" :label="dict.label" :value="dict.value"/>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<search-bar
:formConfigs="formConfig"
ref="searchBarForm"
@headBtnClick="buttonClick" />
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd"
v-hasPermi="['system:dict:create']">新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="warning" icon="el-icon-download" size="mini" @click="handleExport" :loading="exportLoading"
v-hasPermi="['system:dict:export']">导出</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="dataList" >
<el-table
:header-cell-style="{
background: '#F2F4F9',
color: '#606266',
}"
border
style="width: 100%"
v-loading="loading" :data="dataList" >
<el-table-column label="字典编码" align="center" prop="id" />
<el-table-column label="字典标签" align="center" prop="label" />
<el-table-column label="字典键值" align="center" prop="value" />
@ -64,7 +44,13 @@
@pagination="getList"/>
<!-- 添加或修改参数配置对话框 -->
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
<el-dialog :visible.sync="open" width="800px" append-to-body class="dialog">
<template #title>
<slot name="title">
<div class="titleStyle">{{ title }}</div>
</slot>
</template>
<slot />
<el-form ref="form" :model="form" :rules="rules" label-width="90px">
<el-form-item label="字典类型">
<el-input v-model="form.dictType" :disabled="true" />
@ -96,8 +82,8 @@
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
<el-button class="btnTextStyle" @click="cancel"> </el-button>
<el-button type="primary" class="btnTextStyle" @click="submitForm"> </el-button>
</div>
</el-dialog>
</div>
@ -130,8 +116,6 @@ export default {
title: "",
//
open: false,
//
typeOptions: [],
//
queryParams: {
pageNo: 1,
@ -176,6 +160,60 @@ export default {
}
],
formConfig: [
{
type: 'select',
label: '字典名称',
selectOptions: [],
param: 'dictType',
defaultSelect: '',
valueField: 'type',
labelField: 'name',
filterable: true,
},
{
type: 'input',
label: '字典标签',
placeholder: '字典标签',
param: 'label',
},
{
type: 'select',
label: '状态',
selectOptions: getDictDatas(DICT_TYPE.COMMON_STATUS),
param: 'status',
defaultSelect: '',
valueField: 'value',
labelField: 'label',
filterable: true,
},
{
type: 'button',
btnName: '查询',
name: 'search',
color: 'primary',
},
{
type: this.$auth.hasPermi('system:dict:create') ? 'separate' : '',
},
{
type: this.$auth.hasPermi('system:dict:create') ? 'button' : '',
btnName: '新增',
name: 'add',
color: 'success',
plain: true,
},
{
type: this.$auth.hasPermi('system:dict:export') ? 'separate' : '',
},
{
type: this.$auth.hasPermi('system:dict:export') ? 'button' : '',
btnName: '导出',
name: 'export',
color: 'primary',
plain: true,
},
],
//
CommonStatusEnum: CommonStatusEnum,
//
@ -188,6 +226,19 @@ export default {
this.getTypeList();
},
methods: {
buttonClick(val) {
if (val.btnName === 'search') {
this.queryParams.dictType = val.dictType;
this.queryParams.label = val.label;
this.queryParams.status = val.status;
this.getList();
} else if (val.btnName === 'export'){
this.handleExport()
}
else {
this.handleAdd();
}
},
/** 查询字典类型详细 */
getType(dictId) {
getType(dictId).then(response => {
@ -199,7 +250,7 @@ export default {
/** 查询字典类型列表 */
getTypeList() {
listAllSimple().then(response => {
this.typeOptions = response.data;
this.formConfig[0].selectOptions = response.data;
});
},
/** 查询字典数据列表 */
@ -281,7 +332,8 @@ export default {
/** 删除按钮操作 */
handleDelete(row) {
const ids = row.id;
this.$modal.confirm('是否确认删除字典编码为"' + ids + '"的数据项?').then(function() {
this.$modal
.delConfirm(row.label).then(function() {
return delData(ids);
}).then(() => {
this.getList();
@ -302,3 +354,36 @@ export default {
}
};
</script>
<style scoped>
.app-container >>> .el-table .el-table__cell {
padding: 0;
height: 35px;
}
.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;
}
.dialog >>> .btnTextStyle {
letter-spacing: 6px;
padding: 9px 10px 9px 16px;
font-size: 14px;
}
</style>

View File

@ -1,40 +1,18 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="字典名称" prop="name">
<el-input v-model="queryParams.name" placeholder="请输入字典名称" clearable style="width: 240px" @keyup.enter.native="handleQuery"/>
</el-form-item>
<el-form-item label="字典类型" prop="type">
<el-input v-model="queryParams.type" placeholder="请输入字典类型" clearable style="width: 240px" @keyup.enter.native="handleQuery"/>
</el-form-item>
<el-form-item label="状态" prop="status">
<el-select v-model="queryParams.status" placeholder="字典状态" clearable style="width: 240px">
<el-option v-for="dict in statusDictDatas" :key="parseInt(dict.value)" :label="dict.label" :value="parseInt(dict.value)"/>
</el-select>
</el-form-item>
<el-form-item label="创建时间" prop="createTime">
<el-date-picker v-model="queryParams.createTime" style="width: 240px" value-format="yyyy-MM-dd HH:mm:ss" type="daterange"
range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期" :default-time="['00:00:00', '23:59:59']" />
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<search-bar
:formConfigs="formConfig"
ref="searchBarForm"
@headBtnClick="buttonClick" />
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd"
v-hasPermi="['system:dict:create']">新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="warning" icon="el-icon-download" size="mini" @click="handleExport" :loading="exportLoading"
v-hasPermi="['system:dict:export']">导出</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="typeList">
<el-table
:header-cell-style="{
background: '#F2F4F9',
color: '#606266',
}"
border
style="width: 100%"
v-loading="loading" :data="typeList">
<el-table-column label="字典编号" align="center" prop="id" />
<el-table-column label="字典名称" align="center" prop="name" :show-overflow-tooltip="true" />
<el-table-column label="字典类型" align="center" :show-overflow-tooltip="true">
@ -69,7 +47,13 @@
@pagination="getList"/>
<!-- 添加或修改参数配置对话框 -->
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
<el-dialog :visible.sync="open" width="800px" append-to-body class="dialog">
<template #title>
<slot name="title">
<div class="titleStyle">{{ title }}</div>
</slot>
</template>
<slot />
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="字典名称" prop="name">
<el-input v-model="form.name" placeholder="请输入字典名称" />
@ -87,8 +71,8 @@
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
<el-button class="btnTextStyle" @click="cancel"> </el-button>
<el-button type="primary" class="btnTextStyle" @click="submitForm"> </el-button>
</div>
</el-dialog>
</div>
@ -139,6 +123,70 @@ export default {
]
},
formConfig: [
{
type: 'input',
label: '字典名称',
placeholder: '字典名称',
param: 'name',
},
{
type: 'input',
label: '字典类型',
placeholder: '字典类型',
param: 'type',
},
{
type: 'select',
label: '状态',
selectOptions: getDictDatas(DICT_TYPE.COMMON_STATUS),
param: 'status',
defaultSelect: '',
valueField: 'value',
labelField: 'label',
filterable: true,
},
{
type: 'datePicker',
label: '创建时间',
dateType: 'daterange',
format: 'yyyy-MM-dd',
valueFormat: 'yyyy-MM-dd HH:mm:ss',
rangeSeparator: '-',
startPlaceholder: '开始日期',
endPlaceholder: '结束日期',
param: 'createTime',
defaultSelect: [],
defaultTime: ['00:00:00', '23:59:59'],
width: 250,
},
{
type: 'button',
btnName: '查询',
name: 'search',
color: 'primary',
},
{
type: this.$auth.hasPermi('system:dict:create') ? 'separate' : '',
},
{
type: this.$auth.hasPermi('system:dict:create') ? 'button' : '',
btnName: '新增',
name: 'add',
color: 'success',
plain: true,
},
{
type: this.$auth.hasPermi('system:dict:export') ? 'separate' : '',
},
{
type: this.$auth.hasPermi('system:dict:export') ? 'button' : '',
btnName: '导出',
name: 'export',
color: 'primary',
plain: true,
},
],
//
CommonStatusEnum: CommonStatusEnum,
//
@ -149,6 +197,20 @@ export default {
this.getList();
},
methods: {
buttonClick(val) {
if (val.btnName === 'search') {
this.queryParams.name = val.name;
this.queryParams.type = val.type;
this.queryParams.createTime = val.createTime;
this.queryParams.status = val.status;
this.getList();
} else if (val.btnName === 'export'){
this.handleExport()
}
else {
this.handleAdd();
}
},
/** 查询字典类型列表 */
getList() {
this.loading = true;
@ -224,7 +286,8 @@ export default {
/** 删除按钮操作 */
handleDelete(row) {
const ids = row.id || this.ids;
this.$modal.confirm('是否确认删除字典编号为"' + ids + '"的数据项?').then(function() {
this.$modal
.delConfirm(row.name).then(function() {
return delType(ids);
}).then(() => {
this.getList();
@ -249,3 +312,36 @@ export default {
}
};
</script>
<style scoped>
.app-container >>> .el-table .el-table__cell {
padding: 0;
height: 35px;
}
.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;
}
.dialog >>> .btnTextStyle {
letter-spacing: 6px;
padding: 9px 10px 9px 16px;
font-size: 14px;
}
</style>

View File

@ -1,406 +1,572 @@
<template>
<div class="app-container">
<!-- <doc-alert title="功能权限" url="https://doc.iocoder.cn/resource-permission" />
<div class="app-container">
<!-- <doc-alert title="功能权限" url="https://doc.iocoder.cn/resource-permission" />
<doc-alert title="菜单路由" url="https://doc.iocoder.cn/vue2/route/" /> -->
<!-- 搜索工作栏 -->
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch">
<el-form-item label="菜单名称" prop="name">
<el-input v-model="queryParams.name" placeholder="请输入菜单名称" clearable @keyup.enter.native="handleQuery"/>
</el-form-item>
<el-form-item label="状态" prop="status">
<el-select v-model="queryParams.status" placeholder="菜单状态" clearable>
<el-option v-for="dict in statusDictDatas" :key="parseInt(dict.value)" :label="dict.label" :value="parseInt(dict.value)"/>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<!-- 搜索工作栏 -->
<search-bar
:formConfigs="formConfig"
ref="searchBarForm"
@headBtnClick="buttonClick" />
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd"
v-hasPermi="['system:menu:create']">新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="info" plain icon="el-icon-sort" size="mini" @click="toggleExpandAll">展开/折叠</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table
:header-cell-style="{
background: '#F2F4F9',
color: '#606266',
}"
border
style="width: 100%"
v-if="refreshTable"
v-loading="loading"
:data="menuList"
row-key="id"
:default-expand-all="isExpandAll"
:tree-props="{ children: 'children', hasChildren: 'hasChildren' }">
<el-table-column
prop="name"
label="菜单名称"
:show-overflow-tooltip="true"
width="250"></el-table-column>
<el-table-column prop="icon" label="图标" align="center" width="100">
<template v-slot="scope">
<svg-icon :icon-class="scope.row.icon" />
</template>
</el-table-column>
<el-table-column prop="sort" label="排序" width="60"></el-table-column>
<el-table-column
prop="permission"
label="权限标识"
:show-overflow-tooltip="true" />
<el-table-column
prop="component"
label="组件路径"
:show-overflow-tooltip="true" />
<el-table-column
prop="componentName"
label="组件名称"
:show-overflow-tooltip="true" />
<el-table-column prop="status" label="状态" width="80">
<template v-slot="scope">
<dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="scope.row.status" />
</template>
</el-table-column>
<el-table-column
label="操作"
align="center"
class-name="small-padding fixed-width">
<template v-slot="scope">
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
v-hasPermi="['system:menu:update']">
修改
</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-plus"
@click="handleAdd(scope.row)"
v-hasPermi="['system:menu:create']">
新增
</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['system:menu:delete']">
删除
</el-button>
</template>
</el-table-column>
</el-table>
<el-table v-if="refreshTable" v-loading="loading" :data="menuList" row-key="id" :default-expand-all="isExpandAll"
:tree-props="{children: 'children', hasChildren: 'hasChildren'}">
<el-table-column prop="name" label="菜单名称" :show-overflow-tooltip="true" width="250"></el-table-column>
<el-table-column prop="icon" label="图标" align="center" width="100">
<template v-slot="scope">
<svg-icon :icon-class="scope.row.icon" />
</template>
</el-table-column>
<el-table-column prop="sort" label="排序" width="60"></el-table-column>
<el-table-column prop="permission" label="权限标识" :show-overflow-tooltip="true" />
<el-table-column prop="component" label="组件路径" :show-overflow-tooltip="true" />
<el-table-column prop="componentName" label="组件名称" :show-overflow-tooltip="true" />
<el-table-column prop="status" label="状态" width="80">
<template v-slot="scope">
<dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="scope.row.status"/>
</template>
</el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template v-slot="scope">
<el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)"
v-hasPermi="['system:menu:update']">修改</el-button>
<el-button size="mini" type="text" icon="el-icon-plus" @click="handleAdd(scope.row)"
v-hasPermi="['system:menu:create']">新增</el-button>
<el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)"
v-hasPermi="['system:menu:delete']">删除</el-button>
</template>
</el-table-column>
</el-table>
<!-- 添加或修改菜单对话框 -->
<el-dialog :title="title" :visible.sync="open" width="800px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="100px">
<el-row>
<el-col :span="24">
<el-form-item label="上级菜单">
<treeselect v-model="form.parentId" :options="menuOptions" :normalizer="normalizer" :show-count="true"
placeholder="选择上级菜单"/>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="菜单类型" prop="type">
<el-radio-group v-model="form.type">
<el-radio v-for="dict in menuTypeDictDatas" :key="parseInt(dict.value)" :label="parseInt(dict.value)">
{{dict.label}}</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item v-if="form.type !== 3" label="菜单图标">
<el-popover placement="bottom-start" width="460" trigger="click" @show="$refs['iconSelect'].reset()">
<IconSelect ref="iconSelect" @selected="selected" />
<el-input slot="reference" clearable v-model="form.icon" placeholder="点击选择图标">
<svg-icon v-if="form.icon" slot="prefix" :icon-class="form.icon" class="el-input__icon"
style="height: 32px;width: 16px;"/>
<i v-else slot="prefix" class="el-icon-search el-input__icon" />
</el-input>
</el-popover>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="菜单名称" prop="name">
<el-input v-model="form.name" placeholder="请输入菜单名称" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="显示排序" prop="sort">
<el-input-number v-model="form.sort" controls-position="right" :min="0" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item v-if="form.type !== 3" label="路由地址" prop="path">
<span slot="label">
<el-tooltip content="访问的路由地址,如:`user`。如需外网地址时,则以 `http(s)://` 开头" placement="top">
<i class="el-icon-question" />
</el-tooltip>
路由地址
</span>
<el-input v-model="form.path" placeholder="请输入路由地址" />
</el-form-item>
</el-col>
<!-- 添加或修改菜单对话框 -->
<el-dialog :visible.sync="open" width="800px" append-to-body class="dialog">
<template #title>
<slot name="title">
<div class="titleStyle">{{ title }}</div>
</slot>
</template>
<slot />
<el-form ref="form" :model="form" :rules="rules" label-width="100px">
<el-row>
<el-col :span="24">
<el-form-item label="上级菜单">
<treeselect
v-model="form.parentId"
:options="menuOptions"
:normalizer="normalizer"
:show-count="true"
placeholder="选择上级菜单" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="菜单类型" prop="type">
<el-radio-group v-model="form.type">
<el-radio
v-for="dict in menuTypeDictDatas"
:key="parseInt(dict.value)"
:label="parseInt(dict.value)">
{{ dict.label }}
</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item v-if="form.type !== 3" label="菜单图标">
<el-popover
placement="bottom-start"
width="460"
trigger="click"
@show="$refs['iconSelect'].reset()">
<IconSelect ref="iconSelect" @selected="selected" />
<el-input
slot="reference"
clearable
v-model="form.icon"
placeholder="点击选择图标">
<svg-icon
v-if="form.icon"
slot="prefix"
:icon-class="form.icon"
class="el-input__icon"
style="height: 32px; width: 16px" />
<i
v-else
slot="prefix"
class="el-icon-search el-input__icon" />
</el-input>
</el-popover>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="菜单名称" prop="name">
<el-input v-model="form.name" placeholder="请输入菜单名称" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="显示排序" prop="sort">
<el-input-number
v-model="form.sort"
controls-position="right"
:min="0" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item v-if="form.type !== 3" label="路由地址" prop="path">
<span slot="label">
<el-tooltip
content="访问的路由地址,如:`user`。如需外网地址时,则以 `http(s)://` 开头"
placement="top">
<i class="el-icon-question" />
</el-tooltip>
路由地址
</span>
<el-input v-model="form.path" placeholder="请输入路由地址" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item v-if="form.type !== 1" label="权限标识">
<span slot="label">
<el-tooltip content="Controller 方法上的权限字符,如:@PreAuthorize(`@ss.hasPermission('system:user:list')`)" placement="top">
<i class="el-icon-question" />
</el-tooltip>
权限字符
</span>
<el-input v-model="form.permission" placeholder="请权限标识" maxlength="50" />
<span slot="label">
<el-tooltip
content="Controller 方法上的权限字符,如:@PreAuthorize(`@ss.hasPermission('system:user:list')`)"
placement="top">
<i class="el-icon-question" />
</el-tooltip>
权限字符
</span>
<el-input
v-model="form.permission"
placeholder="请权限标识"
maxlength="50" />
</el-form-item>
</el-col>
<el-col :span="12" v-if="form.type === 2">
<el-form-item label="组件路径" prop="component">
<el-input
v-model="form.component"
placeholder="例如说system/user/index" />
</el-form-item>
</el-col>
<el-col :span="12" v-if="form.type === 2">
<el-form-item label="组件路径" prop="component">
<el-input v-model="form.component" placeholder="例如说system/user/index" />
</el-form-item>
</el-col>
<el-col :span="12" v-if="form.type === 2">
<el-form-item label="组件名称" prop="componentName">
<el-input v-model="form.componentName" placeholder="例如说SystemUser" />
<el-input
v-model="form.componentName"
placeholder="例如说SystemUser" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="菜单状态" prop="status">
<span slot="label">
<el-tooltip
content="选择停用时,路由将不会出现在侧边栏,也不能被访问"
placement="top">
<i class="el-icon-question" />
</el-tooltip>
菜单状态
</span>
<el-radio-group v-model="form.status">
<el-radio
v-for="dict in this.getDictDatas(DICT_TYPE.COMMON_STATUS)"
:key="dict.value"
:label="parseInt(dict.value)">
{{ dict.label }}
</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item v-if="form.type !== 3" label="显示状态">
<span slot="label">
<el-tooltip
content="选择隐藏时,路由将不会出现在侧边栏,但仍然可以访问"
placement="top">
<i class="el-icon-question" />
</el-tooltip>
是否显示
</span>
<el-radio-group v-model="form.visible">
<el-radio :key="true" :label="true">显示</el-radio>
<el-radio :key="false" :label="false">隐藏</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item v-if="form.type !== 3" label="总是显示">
<span slot="label">
<el-tooltip
content="选择不是时,当该菜单只有一个子菜单时,不展示自己,直接展示子菜单"
placement="top">
<i class="el-icon-question" />
</el-tooltip>
总是显示
</span>
<el-radio-group v-model="form.alwaysShow">
<el-radio :key="true" :label="true">总是</el-radio>
<el-radio :key="false" :label="false">不是</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="菜单状态" prop="status">
<span slot="label">
<el-tooltip content="选择停用时,路由将不会出现在侧边栏,也不能被访问" placement="top">
<i class="el-icon-question" />
</el-tooltip>
菜单状态
</span>
<el-radio-group v-model="form.status">
<el-radio v-for="dict in this.getDictDatas(DICT_TYPE.COMMON_STATUS)"
:key="dict.value" :label="parseInt(dict.value)">{{dict.label}}</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item v-if="form.type !== 3" label="显示状态">
<span slot="label">
<el-tooltip content="选择隐藏时,路由将不会出现在侧边栏,但仍然可以访问" placement="top">
<i class="el-icon-question" />
</el-tooltip>
是否显示
</span>
<el-radio-group v-model="form.visible">
<el-radio :key="true" :label="true">显示</el-radio>
<el-radio :key="false" :label="false">隐藏</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item v-if="form.type !== 3" label="总是显示">
<span slot="label">
<el-tooltip content="选择不是时,当该菜单只有一个子菜单时,不展示自己,直接展示子菜单" placement="top">
<i class="el-icon-question" />
</el-tooltip>
总是显示
</span>
<el-radio-group v-model="form.alwaysShow">
<el-radio :key="true" :label="true">总是</el-radio>
<el-radio :key="false" :label="false">不是</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item v-if="form.type === 2" label="是否缓存">
<span slot="label">
<el-tooltip content="选择缓存时,则会被 `keep-alive` 缓存,必须填写「组件名称」字段" placement="top">
<i class="el-icon-question" />
</el-tooltip>
是否缓存
</span>
<span slot="label">
<el-tooltip
content="选择缓存时,则会被 `keep-alive` 缓存,必须填写「组件名称」字段"
placement="top">
<i class="el-icon-question" />
</el-tooltip>
是否缓存
</span>
<el-radio-group v-model="form.keepAlive">
<el-radio :key="true" :label="true">缓存</el-radio>
<el-radio :key="false" :label="false">不缓存</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
</el-row>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
</div>
</el-row>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button class="btnTextStyle" @click="cancel"> </el-button>
<el-button type="primary" class="btnTextStyle" @click="submitForm"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { listMenu, getMenu, delMenu, addMenu, updateMenu } from "@/api/system/menu";
import Treeselect from "@riophae/vue-treeselect";
import "@riophae/vue-treeselect/dist/vue-treeselect.css";
import IconSelect from "@/components/IconSelect";
import {
listMenu,
getMenu,
delMenu,
addMenu,
updateMenu,
} from '@/api/system/menu';
import Treeselect from '@riophae/vue-treeselect';
import '@riophae/vue-treeselect/dist/vue-treeselect.css';
import IconSelect from '@/components/IconSelect';
import { SystemMenuTypeEnum, CommonStatusEnum } from '@/utils/constants'
import { getDictDatas, DICT_TYPE } from '@/utils/dict'
import {isExternal} from "@/utils/validate";
import { SystemMenuTypeEnum, CommonStatusEnum } from '@/utils/constants';
import { getDictDatas, DICT_TYPE } from '@/utils/dict';
import { isExternal } from '@/utils/validate';
export default {
name: "SystemMenu",
components: { Treeselect, IconSelect },
data() {
return {
//
loading: true,
//
showSearch: true,
//
menuList: [],
//
menuOptions: [],
//
title: "",
//
open: false,
//
isExpandAll: false,
//
refreshTable: true,
//
queryParams: {
name: undefined,
visible: undefined
},
//
form: {},
//
rules: {
name: [
{ required: true, message: "菜单名称不能为空", trigger: "blur" }
],
sort: [
{ required: true, message: "菜单顺序不能为空", trigger: "blur" }
],
path: [
{ required: true, message: "路由地址不能为空", trigger: "blur" }
],
status: [
{ required: true, message: "状态不能为空", trigger: "blur" }
]
},
name: 'SystemMenu',
components: { Treeselect, IconSelect },
data() {
return {
//
loading: true,
//
showSearch: true,
//
menuList: [],
//
menuOptions: [],
//
title: '',
//
open: false,
//
isExpandAll: false,
//
refreshTable: true,
//
queryParams: {
name: undefined,
visible: undefined,
},
//
form: {},
//
rules: {
name: [
{ required: true, message: '菜单名称不能为空', trigger: 'blur' },
],
sort: [
{ required: true, message: '菜单顺序不能为空', trigger: 'blur' },
],
path: [
{ required: true, message: '路由地址不能为空', trigger: 'blur' },
],
status: [{ required: true, message: '状态不能为空', trigger: 'blur' }],
},
//
MenuTypeEnum: SystemMenuTypeEnum,
CommonStatusEnum: CommonStatusEnum,
//
menuTypeDictDatas: getDictDatas(DICT_TYPE.SYSTEM_MENU_TYPE),
statusDictDatas: getDictDatas(DICT_TYPE.COMMON_STATUS)
};
},
created() {
this.getList();
},
methods: {
//
selected(name) {
this.form.icon = name;
},
/** 查询菜单列表 */
getList() {
this.loading = true;
listMenu(this.queryParams).then(response => {
this.menuList = this.handleTree(response.data, "id");
this.loading = false;
});
},
/** 转换菜单数据结构 */
normalizer(node) {
if (node.children && !node.children.length) {
delete node.children;
}
return {
id: node.id,
label: node.name,
children: node.children
};
},
/** 查询菜单下拉树结构 */
getTreeselect() {
listMenu().then(response => {
this.menuOptions = [];
const menu = { id: 0, name: '主类目', children: [] };
menu.children = this.handleTree(response.data, "id");
this.menuOptions.push(menu);
});
},
//
cancel() {
this.open = false;
this.reset();
},
//
reset() {
this.form = {
id: undefined,
parentId: 0,
name: undefined,
icon: undefined,
type: SystemMenuTypeEnum.DIR,
sort: undefined,
status: CommonStatusEnum.ENABLE,
visible: true,
keepAlive: true,
alwaysShow: true,
};
this.resetForm("form");
},
/** 搜索按钮操作 */
handleQuery() {
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.handleQuery();
},
/** 展开/折叠操作 */
toggleExpandAll() {
this.refreshTable = false;
this.isExpandAll = !this.isExpandAll;
this.$nextTick(() => {
this.refreshTable = true;
});
},
/** 新增按钮操作 */
handleAdd(row) {
this.reset();
this.getTreeselect();
if (row != null && row.id) {
this.form.parentId = row.id;
} else {
this.form.parentId = 0;
}
this.open = true;
this.title = "添加菜单";
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
this.getTreeselect();
getMenu(row.id).then(response => {
this.form = response.data;
this.open = true;
this.title = "修改菜单";
});
},
/** 提交按钮 */
submitForm: function() {
this.$refs["form"].validate(valid => {
if (valid) {
// path
if (this.form.type === SystemMenuTypeEnum.DIR
|| this.form.type === SystemMenuTypeEnum.MENU) {
//
const path = this.form.path
if (!isExternal(path)) {
// path /
if (this.form.parentId === 0 && path.charAt(0) !== '/') {
this.$modal.msgSuccess('前端必须以 / 开头')
return
} else if (this.form.parentId !== 0 && path.charAt(0) === '/') {
this.$modal.msgSuccess('前端不能以 / 开头')
return
}
}
}
formConfig: [
{
type: 'input',
label: '菜单名称',
placeholder: '菜单名称',
param: 'name',
},
{
type: 'select',
label: '状态',
selectOptions: getDictDatas(DICT_TYPE.COMMON_STATUS),
param: 'status',
defaultSelect: '',
valueField: 'value',
labelField: 'label',
filterable: true,
},
{
type: 'button',
btnName: '查询',
name: 'search',
color: 'primary',
},
{
type: this.$auth.hasPermi('system:menu:create') ? 'separate' : '',
},
{
type: this.$auth.hasPermi('system:menu:create') ? 'button' : '',
btnName: '新增',
name: 'add',
color: 'success',
plain: true,
},
],
//
if (this.form.id !== undefined) {
updateMenu(this.form).then(response => {
this.$modal.msgSuccess("修改成功");
this.open = false;
this.getList();
});
} else {
addMenu(this.form).then(response => {
this.$modal.msgSuccess("新增成功");
this.open = false;
this.getList();
});
}
}
});
},
/** 删除按钮操作 */
handleDelete(row) {
this.$modal.confirm('是否确认删除名称为"' + row.name + '"的数据项?').then(function() {
return delMenu(row.id);
}).then(() => {
this.getList();
this.$modal.msgSuccess("删除成功");
}).catch(() => {});
}
}
//
MenuTypeEnum: SystemMenuTypeEnum,
CommonStatusEnum: CommonStatusEnum,
//
menuTypeDictDatas: getDictDatas(DICT_TYPE.SYSTEM_MENU_TYPE),
statusDictDatas: getDictDatas(DICT_TYPE.COMMON_STATUS),
};
},
created() {
this.getList();
},
methods: {
buttonClick(val) {
if (val.btnName === 'search') {
this.queryParams.name = val.name;
this.queryParams.status = val.status;
this.getList();
} else {
this.handleAdd();
}
},
//
selected(name) {
this.form.icon = name;
},
/** 查询菜单列表 */
getList() {
this.loading = true;
listMenu(this.queryParams).then((response) => {
this.menuList = this.handleTree(response.data, 'id');
this.loading = false;
});
},
/** 转换菜单数据结构 */
normalizer(node) {
if (node.children && !node.children.length) {
delete node.children;
}
return {
id: node.id,
label: node.name,
children: node.children,
};
},
/** 查询菜单下拉树结构 */
getTreeselect() {
listMenu().then((response) => {
this.menuOptions = [];
const menu = { id: 0, name: '主类目', children: [] };
menu.children = this.handleTree(response.data, 'id');
this.menuOptions.push(menu);
});
},
//
cancel() {
this.open = false;
this.reset();
},
//
reset() {
this.form = {
id: undefined,
parentId: 0,
name: undefined,
icon: undefined,
type: SystemMenuTypeEnum.DIR,
sort: undefined,
status: CommonStatusEnum.ENABLE,
visible: true,
keepAlive: true,
alwaysShow: true,
};
this.resetForm('form');
},
/** 搜索按钮操作 */
handleQuery() {
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm('queryForm');
this.handleQuery();
},
/** 展开/折叠操作 */
toggleExpandAll() {
this.refreshTable = false;
this.isExpandAll = !this.isExpandAll;
this.$nextTick(() => {
this.refreshTable = true;
});
},
/** 新增按钮操作 */
handleAdd(row) {
this.reset();
this.getTreeselect();
if (row != null && row.id) {
this.form.parentId = row.id;
} else {
this.form.parentId = 0;
}
this.open = true;
this.title = '添加菜单';
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
this.getTreeselect();
getMenu(row.id).then((response) => {
this.form = response.data;
this.open = true;
this.title = '修改菜单';
});
},
/** 提交按钮 */
submitForm: function () {
this.$refs['form'].validate((valid) => {
if (valid) {
// path
if (
this.form.type === SystemMenuTypeEnum.DIR ||
this.form.type === SystemMenuTypeEnum.MENU
) {
//
const path = this.form.path;
if (!isExternal(path)) {
// path /
if (this.form.parentId === 0 && path.charAt(0) !== '/') {
this.$modal.msgSuccess('前端必须以 / 开头');
return;
} else if (this.form.parentId !== 0 && path.charAt(0) === '/') {
this.$modal.msgSuccess('前端不能以 / 开头');
return;
}
}
}
//
if (this.form.id !== undefined) {
updateMenu(this.form).then((response) => {
this.$modal.msgSuccess('修改成功');
this.open = false;
this.getList();
});
} else {
addMenu(this.form).then((response) => {
this.$modal.msgSuccess('新增成功');
this.open = false;
this.getList();
});
}
}
});
},
/** 删除按钮操作 */
handleDelete(row) {
this.$modal
.delConfirm(row.name)
.then(function () {
return delMenu(row.id);
})
.then(() => {
this.getList();
this.$modal.msgSuccess('删除成功');
})
.catch(() => {});
},
},
};
</script>
<style scoped>
.app-container >>> .el-table .el-table__cell {
padding: 0;
height: 35px;
}
.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;
}
.dialog >>> .btnTextStyle {
letter-spacing: 6px;
padding: 9px 10px 9px 16px;
font-size: 14px;
}
</style>

View File

@ -1,36 +1,18 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="岗位编码" prop="code">
<el-input v-model="queryParams.code" placeholder="请输入岗位编码" clearable @keyup.enter.native="handleQuery"/>
</el-form-item>
<el-form-item label="岗位名称" prop="name">
<el-input v-model="queryParams.name" placeholder="请输入岗位名称" clearable @keyup.enter.native="handleQuery"/>
</el-form-item>
<el-form-item label="状态" prop="status">
<el-select v-model="queryParams.status" placeholder="岗位状态" clearable>
<el-option v-for="dict in statusDictDatas" :key="parseInt(dict.value)" :label="dict.label" :value="parseInt(dict.value)"/>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<search-bar
:formConfigs="formConfig"
ref="searchBarForm"
@headBtnClick="buttonClick" />
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd"
v-hasPermi="['system:post:create']">新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="warning" icon="el-icon-download" size="mini" @click="handleExport" :loading="exportLoading"
v-hasPermi="['system:post:export']">导出</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="postList">
<el-table
:header-cell-style="{
background: '#F2F4F9',
color: '#606266',
}"
border
style="width: 100%"
v-loading="loading" :data="postList">
<el-table-column label="岗位编号" align="center" prop="id" />
<el-table-column label="岗位编码" align="center" prop="code" />
<el-table-column label="岗位名称" align="center" prop="name" />
@ -59,7 +41,13 @@
@pagination="getList"/>
<!-- 添加或修改岗位对话框 -->
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
<el-dialog :visible.sync="open" width="800px" append-to-body class="dialog">
<template #title>
<slot name="title">
<div class="titleStyle">{{ title }}</div>
</slot>
</template>
<slot />
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="岗位名称" prop="name">
<el-input v-model="form.name" placeholder="请输入岗位名称" />
@ -81,8 +69,8 @@
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
<el-button class="btnTextStyle" @click="cancel"> </el-button>
<el-button type="primary" class="btnTextStyle" @click="submitForm"> </el-button>
</div>
</el-dialog>
</div>
@ -135,6 +123,56 @@ export default {
]
},
formConfig: [
{
type: 'input',
label: '岗位编码',
placeholder: '岗位编码',
param: 'code',
},
{
type: 'input',
label: '岗位名称',
placeholder: '岗位名称',
param: 'name',
},
{
type: 'select',
label: '状态',
selectOptions: getDictDatas(DICT_TYPE.COMMON_STATUS),
param: 'status',
defaultSelect: '',
valueField: 'value',
labelField: 'label',
filterable: true,
},
{
type: 'button',
btnName: '查询',
name: 'search',
color: 'primary',
},
{
type: this.$auth.hasPermi('system:post:create') ? 'separate' : '',
},
{
type: this.$auth.hasPermi('system:post:create') ? 'button' : '',
btnName: '新增',
name: 'add',
color: 'success',
plain: true,
},
{
type: this.$auth.hasPermi('system:post:export') ? 'separate' : '',
},
{
type: this.$auth.hasPermi('system:post:export') ? 'button' : '',
btnName: '导出',
name: 'export',
color: 'primary',
plain: true,
},
],
//
CommonStatusEnum: CommonStatusEnum,
//
@ -145,6 +183,19 @@ export default {
this.getList();
},
methods: {
buttonClick(val) {
if (val.btnName === 'search') {
this.queryParams.name = val.name;
this.queryParams.code = val.code;
this.queryParams.status = val.status;
this.getList();
} else if (val.btnName === 'export'){
this.handleExport()
}
else {
this.handleAdd();
}
},
/** 查询岗位列表 */
getList() {
this.loading = true;
@ -220,7 +271,8 @@ export default {
/** 删除按钮操作 */
handleDelete(row) {
const ids = row.id;
this.$modal.confirm('是否确认删除岗位编号为"' + ids + '"的数据项?').then(function() {
this.$modal
.delConfirm(row.name).then(function() {
return delPost(ids);
}).then(() => {
this.getList();
@ -241,3 +293,36 @@ export default {
}
};
</script>
<style scoped>
.app-container >>> .el-table .el-table__cell {
padding: 0;
height: 35px;
}
.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;
}
.dialog >>> .btnTextStyle {
letter-spacing: 6px;
padding: 9px 10px 9px 16px;
font-size: 14px;
}
</style>

View File

@ -102,14 +102,14 @@ export default {
bottom: '3%',
bottom: '55%',
},
{
containLabel: true,
top: 40,
left: '4%',
right: '2%',
bottom: '3%',
top: '55%',
},
// {
// containLabel: true,
// top: 40,
// left: '4%',
// right: '2%',
// bottom: '3%',
// top: '55%',
// },
],
xAxis: [
{
@ -128,22 +128,22 @@ export default {
},
},
},
{
type: 'category',
data: nameArr,
gridIndex: 1,
axisTick: {
alignWithLabel: true,
},
axisLabel: {
color: '#979797',
},
axisLine: {
lineStyle: {
color: '#979797',
},
},
},
// {
// type: 'category',
// data: nameArr,
// gridIndex: 1,
// axisTick: {
// alignWithLabel: true,
// },
// axisLabel: {
// color: '#979797',
// },
// axisLine: {
// lineStyle: {
// color: '#979797',
// },
// },
// },
],
yAxis: [
{
@ -159,19 +159,19 @@ export default {
color: '#979797',
},
},
{
gridIndex: 1,
name: '剩余使用天数',
axisTick: {
show: false,
},
splitArea: {
show: false,
},
axisLabel: {
color: '#979797',
},
},
// {
// gridIndex: 1,
// name: '使',
// axisTick: {
// show: false,
// },
// splitArea: {
// show: false,
// },
// axisLabel: {
// color: '#979797',
// },
// },
],
series: [
{
@ -181,15 +181,15 @@ export default {
data: valueArr,
animationDuration,
},
{
name: '天数',
type: 'bar',
barWidth: '20',
data: dayArr,
animationDuration,
xAxisIndex: 1,
yAxisIndex: 1,
},
// {
// name: '',
// type: 'bar',
// barWidth: '20',
// data: dayArr,
// animationDuration,
// xAxisIndex: 1,
// yAxisIndex: 1,
// },
],
});
},

View File

@ -144,21 +144,24 @@ export default {
this.chart.getZr().off('click');
this.chart.getZr().on('click', function () {
if (_this.targetId !== '') {
switch (_this.targetId) {
case 1:
_this.$router.push({
path: 'warehouse-manage1/InventoryOverview/' + _this.targetId,
});
break;
case '1818175999715164161':
_this.$router.push({
path: 'warehouse-manage2/InventoryOverview/' + _this.targetId,
});
break;
default:
console.log(_this.targetId);
break;
}
_this.$router.push({
path: `warehouse-manage${_this.targetId}/InventoryOverview/` + _this.targetId,
});
// switch (_this.targetId) {
// case 1:
// _this.$router.push({
// path: 'warehouse-manage1/InventoryOverview/' + _this.targetId,
// });
// break;
// case '1818175999715164161':
// _this.$router.push({
// path: 'warehouse-manage2/InventoryOverview/' + _this.targetId,
// });
// break;
// default:
// console.log(_this.targetId);
// break;
// }
}
});
},

View File

@ -2,7 +2,7 @@
* @Author: zwq
* @Date: 2024-07-02 15:56:48
* @LastEditors: zwq
* @LastEditTime: 2024-08-02 14:57:52
* @LastEditTime: 2024-09-23 09:15:30
* @Description:
-->
<template>
@ -59,21 +59,24 @@ export default {
},
methods: {
toPage(i) {
switch (i.id) {
case 1:
this.$router.push({
path: 'warehouse-manage1/InventoryOverview/' + i.id,
this.$router.push({
path: `warehouse-manage${i.id}/InventoryOverview/` + i.id,
});
break;
case '1818175999715164161':
this.$router.push({
path: 'warehouse-manage2/InventoryOverview/' + i.id,
});
break;
default:
console.log(i.id);
break;
}
// switch (i.id) {
// case 1:
// this.$router.push({
// path: 'warehouse-manage1/InventoryOverview/' + i.id,
// });
// break;
// case '1818175999715164161':
// this.$router.push({
// path: 'warehouse-manage2/InventoryOverview/' + i.id,
// });
// break;
// default:
// console.log(i.id);
// break;
// }
},
},
};

68
sync_mes2.bat Normal file
View File

@ -0,0 +1,68 @@
@echo off
setlocal enabledelayedexpansion
set cmdstr=rsync
set zipfile=cwrsync.zip
set downurl=https://itefix.net/download/free/cwrsync_6.3.0_x64_free.zip
set currpath=%~dp0
set "rsynchome=%ProgramFiles%\%zipfile:~0,-4%"
set passfile=%temp%\.password
set syncdir=dist/
:: 以下需要配置同步服务器
set accountwithost=kszny@47.96.93.140::mes2
set "password=kszny@123"
set "runcommand=%cmdstr% --port=873 -rlptvz --progress --password-file=%passfile% --exclude=google.exe --exclude=Lodap.zip %syncdir% %accountwithost%"
where %cmdstr% >nul 2>nul
::有错误输出,说明不存在该命令
if %errorlevel% neq 0 (
::还未下载安装包或未正常解压到安装目录
if not exist "%rsynchome%" (
:: 请求提升管理员权限
echo Set UAC = CreateObject^("Shell.Application"^) > "%temp%\runAsAdmin.vbs"
echo UAC.ShellExecute "%~s0", "", "", "runas", 1 >> "%temp%\runAsAdmin.vbs"
"%temp%\runAsAdmin.vbs"
:: 需要提升管理员权限才能创建此目录
mkdir "%rsynchome%"
del "%temp%\runAsAdmin.vbs"
exit /B
)
:: 使用powershell的curl下载软件包
powershell curl -o %temp%\%zipfile% %downurl%
:: 解压
tar -xf "%temp%\%zipfile%" -C "%rsynchome%"
echo "%cmdstr%已经安装到了%rsynchome%目录下"
:: 检查路径是否存在于 PATH 中
set "found=false"
for %%I in ("%PATH:;=";"%") do (
if /I "%%~I"=="%rsynchome%\bin" (
set "found=true"
)
)
:: 未设置到path变量中添加到path变量
if "!found!"=="false" (
:: 更新注册表中的 PATH 变量通过setx方式变量值长度超过1024个字符就会被截断
reg add "HKCU\Environment" /v PATH /t REG_EXPAND_SZ /d "%PATH%;%rsynchome%\bin" /f
)
)
::当前目录下没有dist目录
if not exist "%currpath%%syncdir%" (
echo 当前目录下没有需要同步的%syncdir%目录,请把需要同步的%syncdir%目录拷贝到当前目录下!
) else (
echo !password!>%passfile%
echo 数据同步开始,请稍后...
!runcommand! && (
echo 数据同步完成!
) || (
echo !runcommand!
echo 数据同步失败请确认是否开启了VPN
)
del %passfile%
)
endlocal
pause

2925
yarn.lock

File diff suppressed because it is too large Load Diff