Add all dashboard projects

This commit is contained in:
meswork764
2026-05-23 14:07:11 +08:00
commit ba82fbfc14
3550 changed files with 467904 additions and 0 deletions

View File

@@ -0,0 +1,254 @@
<template>
<div style="background:#f0f2f5;margin-top: -20px;">
<div class="wscn-http404">
<div class="pic-404">
<img :src="img_404" class="pic-404__parent" alt="404">
<img :src="img_404_cloud" class="pic-404__child left" alt="404">
<img :src="img_404_cloud" class="pic-404__child mid" alt="404">
<img :src="img_404_cloud" class="pic-404__child right" alt="404">
</div>
<div class="bullshit">
<div class="bullshit__oops">OOPS!</div>
<div class="bullshit__info">版权所有<a class="link-type" href="http://www.meswork.com/" target="_blank">迈思科技</a>
</div>
<div class="bullshit__headline">{{ message }}</div>
<div class="bullshit__info">请检查您输入的网址是否正确请点击以下按钮返回主页或者发送错误报告</div>
<a href="/" class="bullshit__return-home">返回首页</a>
</div>
</div>
</div>
</template>
<script>
import img_404 from '@/assets/404_images/404.png'
import img_404_cloud from '@/assets/404_images/404_cloud.png'
export default {
data() {
return {
img_404,
img_404_cloud
}
},
computed: {
message() {
return '这个页面你不能进......'
}
}
}
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
.wscn-http404 {
position: relative;
width: 1200px;
margin: 20px auto 60px;
padding: 0 100px;
overflow: hidden;
.pic-404 {
position: relative;
float: left;
width: 600px;
padding: 150px 0;
overflow: hidden;
&__parent {
width: 100%;
}
&__child {
position: absolute;
&.left {
width: 80px;
top: 17px;
left: 220px;
opacity: 0;
animation-name: cloudLeft;
animation-duration: 2s;
animation-timing-function: linear;
animation-fill-mode: forwards;
animation-delay: 1s;
}
&.mid {
width: 46px;
top: 10px;
left: 420px;
opacity: 0;
animation-name: cloudMid;
animation-duration: 2s;
animation-timing-function: linear;
animation-fill-mode: forwards;
animation-delay: 1.2s;
}
&.right {
width: 62px;
top: 100px;
left: 500px;
opacity: 0;
animation-name: cloudRight;
animation-duration: 2s;
animation-timing-function: linear;
animation-fill-mode: forwards;
animation-delay: 1s;
}
@keyframes cloudLeft {
0% {
top: 17px;
left: 220px;
opacity: 0;
}
20% {
top: 33px;
left: 188px;
opacity: 1;
}
80% {
top: 81px;
left: 92px;
opacity: 1;
}
100% {
top: 97px;
left: 60px;
opacity: 0;
}
}
@keyframes cloudMid {
0% {
top: 10px;
left: 420px;
opacity: 0;
}
20% {
top: 40px;
left: 360px;
opacity: 1;
}
70% {
top: 130px;
left: 180px;
opacity: 1;
}
100% {
top: 160px;
left: 120px;
opacity: 0;
}
}
@keyframes cloudRight {
0% {
top: 100px;
left: 500px;
opacity: 0;
}
20% {
top: 120px;
left: 460px;
opacity: 1;
}
80% {
top: 180px;
left: 340px;
opacity: 1;
}
100% {
top: 200px;
left: 300px;
opacity: 0;
}
}
}
}
.bullshit {
position: relative;
float: left;
width: 300px;
padding: 150px 0;
overflow: hidden;
&__oops {
font-size: 32px;
font-weight: bold;
line-height: 40px;
color: #1482f0;
opacity: 0;
margin-bottom: 20px;
animation-name: slideUp;
animation-duration: 0.5s;
animation-fill-mode: forwards;
}
&__headline {
font-size: 20px;
line-height: 24px;
color: #1482f0;
opacity: 0;
margin-bottom: 10px;
animation-name: slideUp;
animation-duration: 0.5s;
animation-delay: 0.1s;
animation-fill-mode: forwards;
}
&__info {
font-size: 13px;
line-height: 21px;
color: grey;
opacity: 0;
margin-bottom: 30px;
animation-name: slideUp;
animation-duration: 0.5s;
animation-delay: 0.2s;
animation-fill-mode: forwards;
}
&__return-home {
display: block;
float: left;
width: 110px;
height: 36px;
background: #1482f0;
border-radius: 100px;
text-align: center;
color: #ffffff;
opacity: 0;
font-size: 14px;
line-height: 36px;
cursor: pointer;
animation-name: slideUp;
animation-duration: 0.5s;
animation-delay: 0.3s;
animation-fill-mode: forwards;
}
@keyframes slideUp {
0% {
transform: translateY(60px);
opacity: 0;
}
100% {
transform: translateY(0);
opacity: 1;
}
}
}
}
</style>

View File

@@ -0,0 +1,301 @@
<template>
<el-card>
<el-radio-group v-model="PartType" style="margin: 30px 20px;">
<el-radio label="产品结构维护">产品结构维护</el-radio>
<el-radio label="产品材料维护">产品材料维护</el-radio>
<el-radio label="工艺参数维护">工艺参数维护</el-radio>
</el-radio-group>
<el-col>
<el-button
type="distribution"
icon="el-icon-circle-plus-outline"
size="small"
@click="handleAdd('department_Form')">新增</el-button>
<el-button type="warning" icon="el-icon-edit" size="small" plain @click="handleEdit()">编辑</el-button>
<el-button type="danger" icon="el-icon-delete" size="small" plain @click="deleteTable()">删除</el-button>
</el-col>
<el-card class="box-card" style="width: 600px;height: 720px">
<div slot="header" class="clearfix" style="position: relative;">
<span v-if="PartType == '产品结构维护'" style="color: black;line-height: 30px;">产品结构维护</span>
<span v-if="PartType == '产品材料维护'" style="color: darkgreen;line-height: 30px;">产品材料维护</span>
<span v-if="PartType == '工艺参数维护'" style="color: cornflowerblue;line-height: 30px;">工艺参数维护</span>
<el-button style="float: right; padding: 3px 0" type="text" @click="expandALL()">展开</el-button>
<div class="tList">
<div class="tItem">
<div :style="{ backgroundColor: getTypeColor('产品结构') }"/>
结构
</div>
<div class="tItem">
<div :style="{ backgroundColor: getTypeColor('产品材料') }"/>
材料
</div>
<div class="tItem">
<div :style="{ backgroundColor: getTypeColor('工艺参数') }"/>
工艺参数
</div>
</div>
</div>
<div style="height: 650px;overflow:auto;">
<el-tree
ref="treeForm"
:data="productTreeData"
:props="defaultProps"
:default-expanded-keys="expandedList"
:allow-drop="allowDrop"
draggable
show-checkbox
node-key="id"
check-strictly
@node-drag-end="sortDrag"
@node-expand="nodeExpand"
@node-collapse="nodeCollapse"
@check-change="handleClick">
<span slot-scope="{ node, data }" class="custom-tree-node">
<span :style="{ color: getTypeColor(data.type) }">{{ node.label }}</span>
</span>
</el-tree>
</div>
</el-card>
</el-card>
</template>
<script>
export default {
data() {
return {
PartType: '产品结构维护',
productTreeData: [],
defaultProps: {
children: 'children',
label: 'label'
},
expandedList: [],
productId: 0,
productType: '',
productName: '',
expandAll: true,
nodeName: ''
}
},
computed: {
},
created() {
this.getTreeData()
},
methods: {
handleAdd() {
this.$prompt('请输入分支名称', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
inputValue: ''
}).then(({ value }) => {
var param = []
param.push(['父节点', this.productId])
param.push(['节点名称', value])
param.push(['节点类型', this.PartType.substring(0, 4)])
var Data = this.CreateData('11', 'WEB_基本表_产品结构_新增', param)
this.ExecDatabase(Data).then(response => {
if (response.data[0].result == 1) {
this.$message.success('新增成功!')
this.getTreeData()
} else {
this.$message.error('信息增加失败')
}
})
})
},
getTreeData() {
var param = []
var Data = this.CreateData('11', 'WEB_基本表_产品结构_查询', param)
this.ExecDatabase(Data).then(response => {
const data = response.data
this.productTreeData = this.tree(data, 0)
})
},
deleteTable() {
if (this.productId) {
if (this.productType + '维护' != this.PartType) {
this.$message.warning(`请选择${this.productType + '维护'}`)
return
}
this.$confirm('此操作将永久删除该数据, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
var param = []
param[0] = ['子节点', this.productId]
var Data = this.CreateData('11', 'WEB_基本表_产品结构_删除', param)
this.ExecDatabase(Data).then(response => {
if (response.data[0].result == 1) {
this.getTreeData()
this.productId = 0
this.$message.success('删除成功')
} else {
this.$message.warning(response.data[0].msg)
}
})
})
} else {
this.$message.warning(`请选择产品`)
}
},
handleEdit() {
if (!this.productId) {
this.$message.warning('请先勾选产品!')
return
}
if (this.productType + '维护' != this.PartType) {
this.$message.warning(`请选择${this.productType + '维护'}`)
return
}
this.$prompt('请输入产品名称', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
inputValue: this.productName
}).then(({ value }) => {
var param = []
param.push(['子节点', this.productId])
param.push(['节点名称', value])
var Data = this.CreateData('11', 'WEB_基本表_产品结构_修改', param)
this.ExecDatabase(Data).then(response => {
if (response.data[0].result == 1) {
this.$message.success('修改成功!')
this.getTreeData()
} else {
this.$message.warning(response.data[0].msg)
}
})
})
},
expandALL() {
this.expandAll = !this.expandAll
for (let i = 0; i < this.$refs.treeForm.store._getAllNodes().length; i++) {
this.$refs.treeForm.store._getAllNodes()[i].expanded = this.expandAll
}
},
getTypeColor(type) {
switch (type) {
case '产品结构':
return 'black'
case '产品材料':
return 'darkgreen'
case '工艺参数':
return 'cornflowerblue'
default:
return 'black'
}
},
getBigTypeColor(type) {
switch (type) {
case '产品结构维护':
return 'black'
case '产品材料维护':
return 'darkgreen'
case '工艺参数维护':
return 'cornflowerblue'
default:
return 'black'
}
},
tree(data, pid) {
const result = []
let temp
for (let i = 0; i < data.length; i++) {
if (data[i].父节点 === pid) {
const obj = { label: data[i].节点名称, id: data[i].子节点, type: data[i].节点类型 }
temp = this.tree(data, data[i].子节点)
if (temp.length > 0) {
obj.children = temp
}
result.push(obj)
}
}
return result
},
allowDrop(draggingNode, dropNode, type) {
if (type === 'inner') {
return false
} else {
if (draggingNode.parent.id !== dropNode.parent.id) {
return false
} else {
return true
}
}
},
// 节点拖拽排序
sortDrag(Node, targetNode, type, event) {
// let PId = 0
// if (targetNode.parent.key) {
// PId = targetNode.parent.key
// }
// var param = []
// param[0] = ['原始位置', Node.data.id]
// param[1] = ['最终位置', targetNode.data.id]
// param[2] = ['父节点', PId]
// var Data = this.CreateData('12', '产品关系_变更节点排序', param)
// this.ExecDatabase(Data).then(response => {
// if (response.data[0].result === '1') {
// this.$message.success('更新成功')
// this.getTreeData()
// } else {
// this.$message.error('更新失败')
// }
// })
},
nodeExpand(data) {
// console.log(this.departmentData, 55555)
this.expandedList.push(data.id) // 在节点展开是添加到默认展开数组
},
nodeCollapse(data) {
this.expandedList.splice(this.expandedList.indexOf(data.id), 1) // 收起时删除数组里对应选项
},
handleClick(data, checked) {
if (!this.$refs.treeForm) return
if (checked) {
this.$refs.treeForm.setCheckedKeys([data.id])
setTimeout(() => {
this.productId = data.id
this.productName = data.label || '' // 防止undefined
this.productType = data.type || ''
console.log('当前选中:', this.productId, this.productName)
}, 50)
} else {
// this.$refs.treeForm.setCheckedKeys()
this.productId = 0
this.productName = ''
this.productType = ''
console.log('当前选中:', this.productId, this.productName)
}
}
}
}
</script>
<style scoped lang="scss">
::v-deep .el-card__body {
padding: 0px !important;
}
.tList {
text-align: right;
display: flex;
position: absolute;
right: 0px;
.tItem {
display: flex;
margin-left: 10px;
line-height: 15px;
font-size: 13px;
div {
width: 15px;
height: 15px;
margin-right: 5px;
}
}
}
</style>

View File

@@ -0,0 +1,430 @@
<template>
<div class="app-container">
<el-card style="height: 850px">
<div style="margin-top: 7px; margin-bottom: 7px">
<el-input v-model="equipmentName" placeholder="设备名称" size="small" clearable style="width:200px;margin-left: 0px"/>
<el-select v-model="equipmentType" placeholder="设备类型" filterable size="small" style="width:200px" clearable >
<el-option
v-for="item in basedatalx"
:key="item.id"
:label="item.name"
:value="item.id"/>
</el-select>
<!-- <el-input v-model="opName" placeholder="工位" size="small" clearable style="width:200px;margin-left: 0px"/> -->
<el-button type="primary" icon="el-icon-search" size="small" style="margin-left: 20px" plain @click="pageSize = 20;pageCurrent = 1;searchTable()">查询</el-button>
<el-tooltip effect="dark" content="添加新设备" placement="top">
<el-button type="distribution" icon="el-icon-circle-plus-outline" size="small" style="margin-left: 10px" @click="ADD()">设备</el-button>
</el-tooltip>
</div>
<div>
<el-table :data="tableData" border size="small" stripe highlight-current-row height="740px" style="width: 1048px">
<el-table-column label="设备名称" prop="设备名称" align="center" width="150px" >
<template slot-scope="scope">
{{ scope.row.设备名称 }}
</template>
</el-table-column>
<el-table-column label="设备型号" prop="设备型号" align="center" width="150px" >
<template slot-scope="scope">
{{ scope.row.设备型号 }}
</template>
</el-table-column>
<el-table-column label="设备类型" prop="设备类型名称" align="center" width="150px" >
<template slot-scope="scope">
{{ scope.row.设备类型名称 }}
</template>
</el-table-column>
<!-- <el-table-column label="加工工艺" align="center" width="150px">
<template slot-scope="scope">
{{ scope.row.加工工艺 }}
</template>
</el-table-column> -->
<!-- <el-table-column label="工位" align="center" width="80px">
<template slot-scope="scope">
{{ scope.row.工位号 }}
</template>
</el-table-column> -->
<!-- <el-table-column label="工时单价(元/小时)" align="center" width="140px">
<template slot-scope="scope">
{{ scope.row.工时单价 }}
</template>
</el-table-column>
<el-table-column label="月设备加工能力" align="center" width="140px">
<template slot-scope="scope">
{{ scope.row.月设备加工能力 }}
</template>
</el-table-column>
<el-table-column label="点检类型名称" align="center" width="137px">
<template slot-scope="scope">
{{ scope.row.点检表类型名称 }}
</template>
</el-table-column> -->
<el-table-column label="操作" align="center">
<template slot-scope="scope">
<el-button type="text" size="mini" icon="el-icon-edit" style="margin-right:10px" @click="handleEdit(scope.row)"/>
<el-button type="text" size="mini" icon="el-icon-delete" @click="handleDelete(scope.row)"/>
</template>
</el-table-column>
</el-table>
</div>
<div class="block" style="margin-top: 10px;">
<el-pagination
:current-page="pageCurrent"
:page-sizes="[10, 20, 30, 40, 100]"
:page-size="pageSize"
:total="total"
layout="total, sizes, prev, pager, next, jumper"
@size-change="handleSizeChanges"
@current-change="handleCurrentChanges"/>
</div>
</el-card>
<el-dialog :title="title" :visible.sync="dialogFormVisible" center style="min-height: 300px" width="700px">
<el-form ref="form" :model="form" :rules="rules" label-position="right" label-width="110px" class="demo-ruleForm">
<el-row>
<el-col :span = "12">
<el-form-item label="设备名称" prop="设备名称" >
<el-input v-model="form.设备名称" placeholder="设备名称" size="small" style="width:200px" clearable />
</el-form-item>
</el-col>
<el-col :span = "12">
<el-form-item label="设备型号" prop="设备型号" >
<el-input v-model="form.设备型号" placeholder="设备型号" size="small" style="width:200px" clearable />
</el-form-item>
</el-col>
<el-col :span = "12">
<el-form-item label="设备类型" prop="设备类型" >
<el-select v-model="form.设备类型" placeholder="设备类型" filterable size="small" style="width:200px" clearable >
<el-option
v-for="item in basedatalx"
:key="item.id"
:label="item.name"
:value="item.id"/>
</el-select>
</el-form-item>
</el-col>
</el-row>
<!-- <el-row>
<el-col :span = "12">
<el-form-item label="加工工艺" prop="加工工艺" >
<el-select v-model="form.加工工艺" placeholder="加工工艺" filterable size="small" style="width:200px" clearable >
<el-option
v-for="item in process"
:key="item.value"
:label="item.label"
:value="item.value"/>
</el-select>
</el-form-item>
</el-col>
<el-col :span = "12">
<el-form-item label="工位号" prop="工位号" >
<el-input v-model="form.工位号" placeholder="工位号" size="small" style="width:200px" clearable />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span = "12">
<el-form-item label="工时单价" prop="工时单价" >
<el-input v-positive="'float'" v-model="form.工时单价" class="工时单价" size="small" style="width:200px" placeholder="工时单价" type="number"/>
</el-form-item>
</el-col>
<el-col :span = "12">
<el-form-item label="月设备加工能力" prop="月设备加工能力" >
<el-input v-positive="'float'" v-model="form.月设备加工能力" class="工时单价" size="small" style="width:200px" placeholder="月设备加工能力" type="number"/>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span = "12">
<el-form-item label="点检类型" prop="点检类型" >
<el-select v-model="form.点检类型" placeholder="选择点检类型" filterable size="small" style="width:200px" clearable >
<el-option
v-for="item in routineCheckType"
:key="item.value"
:label="item.label"
:value="item.value"/>
</el-select>
</el-form-item>
</el-col>
</el-row> -->
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="callOff('form')">取消</el-button>
<el-button v-show="title==='新增设备'" type="primary" @click="submitAdd('form')">确定</el-button>
<el-button v-show="title==='编辑设备'" type="primary" @click="submitEdit('form')">确定</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { mapGetters } from 'vuex'
export default {
data() {
return {
routineCheckType: [],
dialogFormVisible: false,
title: '',
equipmentValue: '',
equipmentName: '',
equipmentType: '',
opName: '',
process: [],
form: {
设备名称: '',
设备型号: '',
设备类型: '',
// 加工工艺: '',
// 工位号: '',
// 点检类型: '',
// 工时单价: '',
// 月设备加工能力: ''
},
basedatalx:[],
rules: {
设备名称: [{ required: true, message: '请输入设备名称' }],
// 设备型号: [{ required: true, message: '请输入设备型号' }],
// 加工工艺: [{ required: true, message: '请选择加工工艺' }],
设备类型: [{ required: true, message: '请选择' }]
},
original: '',
total: 0, // 分页总数
tableData: [], // 设备信息表
pageCurrent: 1, // 分页当前页
pageSize: 20 // 分页每页显示条数
}
},
computed: {
...mapGetters([
'id',
'token'
])
},
created() {
this.searchTable()
this.getbasedata()
// this.getRoutineCheckType()
},
methods: {
// getRoutineCheckType() {
// var param = []
// var Data = this.CreateData('11', '点检类型_查询', param)
// this.ExecDatabase(Data).then(response => {
// for (let i = 0; i < response.data.length; i++) {
// this.routineCheckType.push({
// label: response.data[i].点检表类型名称,
// value: response.data[i].点检表类型流水号
// })
// }
// })
// },
// getProcess() {
// var param = []
// var Data = this.CreateData('11', '工艺名称_查询', param)
// this.ExecDatabase(Data).then(response => {
// for (let i = 0; i < response.data.length; i++) {
// this.process.push({
// label: response.data[i].工艺名称,
// value: response.data[i].工艺编号
// })
// }
// })
// },
getbasedata(){
var Data = this.CreateData('11', '查询字典')
this.ExecDatabase(Data).then(response => {
response.data.forEach(element => {
if(element.数据类别 == '设备类型'){
this.basedatalx.push({
name:element.词条名称,
id:element.AID,
})
}
});
})
},
searchTable() {
let equipmentName_check, equipmentType_check
this.equipmentName ? equipmentName_check = 1 : equipmentName_check = 0
this.equipmentType ? equipmentType_check = 1 : equipmentType_check = 0
// this.opName ? opName_check = 1 : opName_check = 0
var param = []
param[0] = ['设备名称_check', equipmentName_check]
param[1] = ['设备名称', this.equipmentName]
param[2] = ['设备类型', this.equipmentType]
param[3] = ['设备类型_check', equipmentType_check]
var Data = this.CreateData('11', '设备管理_设备信息_查询', param, this.pageSize, this.pageCurrent)
this.ExecDatabase(Data).then(response => {
this.tableData = response.data.rows
this.total = response.data.total
})
},
ADD() {
this.title = '新增设备'
if (this.$refs['form'] !== undefined) {
this.$refs['form'].resetFields()
}
this.form.设备名称 = ''
this.form.设备型号 = ''
this.form.设备类型 = ''
// this.form.加工工艺 = ''
// this.form.工位号 = ''
// this.form.月设备加工能力 = ''
// this.form.点检类型 = 1
// this.form.工时单价 = ''
this.dialogFormVisible = true
},
handleEdit(row) {
this.title = '编辑设备'
if (this.$refs['form'] !== undefined) {
this.$refs['form'].resetFields()
}
this.equipmentValue = row.设备流水号
this.form.设备名称 = row.设备名称
this.form.设备型号 = row.设备型号
console.log(this.basedatalx)
this.form.设备类型 = parseInt(row.设备类型)
// this.form.加工工艺 = Number(row.工艺编号)
// this.form.工位号 = row.工位号
// this.original = row.工位号
// this.form.点检类型 = Number(row.点检表类型)
// this.form.月设备加工能力 = row.月设备加工能力
// this.form.工时单价 = row.工时单价
this.dialogFormVisible = true
},
callOff(formName) {
this.dialogFormVisible = false
this.$refs[formName].resetFields()
},
submitAdd(formName) {
this.$refs[formName].validate((valid) => {
if (valid) {
// var param = []
// param[0] = ['工位', this.form.工位号]
// var Data = this.CreateData('11', '设备管理_设备信息_验证工位号是否重复', param)
// this.ExecDatabase(Data).then(response => {
// if (Number(response.data[0].Column1) === 0) {
var param = []
param[0] = ['设备名称', this.form.设备名称]
param[1] = ['设备型号', this.form.设备型号]
param[2] = ['设备类型', this.form.设备类型]
// param[2] = ['加工工艺', this.form.加工工艺]
// param[3] = ['工位', this.form.工位号]
// param[4] = ['工时单价', this.form.工时单价]
// param[5] = ['月设备加工能力', this.form.月设备加工能力]
// param[6] = ['点检类型', this.form.点检类型]
var Data = this.CreateData('12', '设备管理_设备信息_增加', param)
this.ExecDatabase(Data).then(response => {
if (response.data[0].result === '1') {
this.$message.success('添加成功')
this.searchTable()
this.dialogFormVisible = false
} else {
this.$message.error('添加失败')
}
})
// } else {
// // this.$message.warning('工位号重复')
// }
// })
}
})
},
submitEdit(formName) {
this.$refs[formName].validate((valid) => {
if (valid) {
if (this.form.工位号 === this.original) {
var param = []
param[0] = ['设备名称', this.form.设备名称]
param[1] = ['设备型号', this.form.设备型号]
param[2] = ['设备流水号', this.equipmentValue]
param[3] = ['设备类型', this.form.设备类型]
// param[2] = ['加工工艺', this.form.加工工艺]
// param[3] = ['工位', this.form.工位号]
// param[4] = ['工时单价', this.form.工时单价]
// param[5] = ['月设备加工能力', this.form.月设备加工能力]
// param[6] = ['设备流水号', this.equipmentValue]
// param[7] = ['原工位', this.original]
// param[8] = ['点检类型', this.form.点检类型]
var Data = this.CreateData('12', '设备管理_设备信息_编辑', param)
this.ExecDatabase(Data).then(response => {
if (response.data[0].result === '1') {
this.$message.success('编辑成功')
this.searchTable()
this.dialogFormVisible = false
} else {
this.$message.error('编辑失败')
}
})
} else {
// var param1 = []
// param1[0] = ['工位', this.form.工位号]
// var Data1 = this.CreateData('11', '设备管理_设备信息_验证工位号是否重复', param1)
// this.ExecDatabase(Data1).then(response => {
// if (Number(response.data[0].Column1) === 0) {
var param = []
param[0] = ['设备名称', this.form.设备名称]
param[1] = ['设备型号', this.form.设备型号]
param[2] = ['设备流水号', this.equipmentValue]
param[3] = ['设备类型', this.form.设备类型]
// param[2] = ['加工工艺', this.form.加工工艺]
// param[3] = ['工位', this.form.工位号]
// param[4] = ['工时单价', this.form.工时单价]
// param[5] = ['月设备加工能力', this.form.月设备加工能力]
// param[6] = ['设备流水号', this.equipmentValue]
// param[7] = ['原工位', this.original]
var Data = this.CreateData('12', '设备管理_设备信息_编辑', param)
this.ExecDatabase(Data).then(response => {
if (response.data[0].result === '1') {
this.$message.success('编辑成功')
this.searchTable()
this.dialogFormVisible = false
} else {
this.$message.error('编辑失败')
}
})
// } else {
// // this.$message.warning('工位号重复')
// }
// })
}
}
})
},
handleDelete(row) {
this.$confirm('是否删除?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
var param = []
param[0] = ['设备流水号', row.设备流水号]
var Data = this.CreateData('12', '设备管理_设备信息_删除', param)
this.ExecDatabase(Data).then(response => {
if (response.data[0].result === '1') {
this.$message.success('删除成功')
this.pageCurrent = 1
this.searchTable()
} else {
this.$message.error('删除失败')
}
})
}).catch(() => {
this.$message({
type: 'info',
message: '已取消删除'
})
})
},
handleSizeChanges(val) {
this.pageCurrent = 1
this.pageSize = val
this.searchTable()
},
handleCurrentChanges(val) {
this.pageCurrent = val
this.searchTable()
}
}
}
</script>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,109 @@
<template>
<div style="text-align: center; padding: 20px;">
<h3>扫码后自动关闭</h3>
<video
ref="video"
width="400"
height="300"
autoplay
playsinline
style="border: 1px solid #ccc; background: #000;"
></video>
<p v-if="result" style="color: green; margin: 10px 0;"> 扫码成功{{ result }}</p>
<p v-if="error" style="color: red;">{{ error }}</p>
<p v-if="isScanning" style="color: blue;">扫描中... 请将二维码对准摄像头</p>
<button @click="startScan" :disabled="isScanning">开始扫码</button>
<button @click="stopScan" :disabled="!isScanning">手动停止</button>
</div>
</template>
<script>
import { BrowserBarcodeReader } from '@zxing/library'
export default {
name: 'QrScannerAutoStop',
data() {
return {
isScanning: false,
result: '',
error: '',
codeReader: null
}
},
beforeDestroy() {
this.stopScan()
},
methods: {
async startScan() {
if (this.isScanning) return
this.result = ''
this.error = ''
this.isScanning = true
try {
// 创建读取器
this.codeReader = new BrowserBarcodeReader()
console.log('正在启动摄像头...')
// 直接使用连续解码模式
this.codeReader.decodeFromVideoDevice(
null, // 使用默认摄像头
this.$refs.video,
(result, err) => {
if (result) {
console.log('扫码成功:', result)
this.result = result.getText()
this.stopScan()
}
// 忽略 NotFoundException这是正常的未检测到二维码的情况
if (err && !this.isNotFoundException(err)) {
console.warn('解码错误:', err)
}
}
)
console.log('摄像头已启动,开始扫描...')
} catch (e) {
console.error('启动失败:', e)
this.error = `无法启动摄像头: ${e.message}`
this.isScanning = false
this.codeReader = null
}
},
isNotFoundException(err) {
// 检查是否是"未找到"异常(这是正常情况)
},
stopScan() {
if (this.codeReader) {
try {
// 停止解码过程
this.codeReader.reset()
// 停止所有媒体流
if (this.$refs.video && this.$refs.video.srcObject) {
const streams = this.$refs.video.srcObject.getTracks()
streams.forEach(stream => {
stream.stop()
})
this.$refs.video.srcObject = null
}
} catch (e) {
console.log('停止扫描时的小错误:', e)
}
this.codeReader = null
}
this.isScanning = false
}
}
}
</script>

View File

@@ -0,0 +1,446 @@
<template>
<div class="app-container">
<el-card class="topCard">
<div class="topDiv">
<span style="margin-left: 10px">物料名称:</span>
<el-select v-model="stationNumberValue" placeholder="请选择物料" filterable clearable remote :remote-method="getStationNumber" size="small" style="width: 250px" >
<el-option
v-for="item in stationNumber"
:key="item.物料编码"
:label="item.物料编码"
:value="item.物料编码"
size="mini">
</el-option>
</el-select>
<el-button type="primary" plain size="small" icon="el-icon-order" @click="getImgCheckDirectFileList">查询</el-button>
<el-button type="primary" icon="el-icon-circle-plus-outline" size="small" @click="uploadShowPDF(val = 2)" style="width: 100px;">零件图</el-button>
<el-button type="primary" icon="el-icon-circle-plus-outline" size="small" @click="uploadShowPDF(val = 0)" style="width: 155px;">选零件上传零件图</el-button>
<el-button type="primary" icon="el-icon-circle-plus-outline" size="small" @click="uploadShowPDF(val = 0)" style="width: 155px;">选订单上传零件图</el-button>
<el-button type="warning" icon="el-icon-document-delete" size="small" @click="showDeleteRecords" style="width: 140px;">查看删除记录</el-button>
</div>
<div class="main">
<el-table
ref="multipleTable"
:data="imgCheckDirectFileList"
:header-cell-style="{background:'#eef1f6',color:'#606266'}"
:cell-class-name="tableRowClassName"
element-loading-text="数据加载中"
element-loading-spinner="el-icon-loading"
element-loading-background="rgba(0, 0, 0, 0.2)"
class="main"
tooltip-effect="dark"
height="640px"
style="width: 90%"
border
size="mini"
@row-click="handleRowClick"
>
<el-table-column label="序号" type="index" align="center" width="80"/>
<el-table-column prop="num" label="物料编号" align="center" width="200"/>
<el-table-column prop="物料描述" label="物料名称" align="center" width="250"/>
<el-table-column prop="name" label="文件名称" align="center" width="100"/>
<el-table-column prop="worker" label="导入人" align="center" width="100"/>
<el-table-column prop="uploadTime" label="导入时间" align="center" width="150"/>
<el-table-column label="操作" align="center" width="250">
<template slot-scope="scope">
<el-button type="text" icon="el-icon-view" size="mini" @click="imgCheckDirectFile(scope.row)" >查看</el-button>
<el-button type="text" icon="el-icon-delete" size="mini" style="color: #ff0000" @click="deleteImgCheckDirectFileSubmit(scope.row)" >删除</el-button>
</template>
</el-table-column>
</el-table>
</div>
</el-card>
<!--上传文件-->
<el-dialog :visible.sync="imgDialogFormVisible" title="上传指导文件" center style="height: 800px" width="700px">
<span v-if="itemupload" style="margin-left: 10px">物料名称:</span>
<el-select v-if="itemupload" v-model="uploadValue" placeholder="请选择" filterable clearable remote :remote-method="getStationNumber" size="small" style="width: 500px; margin-bottom: 20px;" >
<el-option
v-for="item in tabledata2"
:key="item.物料编码"
:label="item.物料编码"
:value="item.物料编码"
size="mini"/>
</el-select>
<el-upload
ref="uploadPDF"
:multiple="true"
:auto-upload="false"
:on-success="uploadSuccessPDF"
:before-upload="beforeUploadPdf"
:on-exceed="warningExceedPdf"
:limit="limit"
:data="DataPDF"
:on-change="handleChange"
:action="uploadPDF"
accept=".pdf"
style="margin-left: 130px"
drag>
<i class="el-icon-upload"/>
<div class="el-upload__text">将文件拖到此处<em>点击上传</em></div>
<div slot="tip" class="el-upload__tip">只能上传一个pdf文件且不超过100mb</div>
</el-upload>
<div slot="footer" class="dialog-footer">
<el-button @click="imgDialogFormVisible=false">取消</el-button>
<el-button type="primary" style="width: 70px" @click="submitPicturePDF()">确定</el-button>
</div>
</el-dialog>
<el-dialog :visible.sync="deleteRecordsVisible" title="删除记录" center width="1200px">
<el-table
:data="deleteRecordsList"
:header-cell-style="{background:'#eef1f6',color:'#606266'}"
element-loading-text="数据加载中"
border
size="mini"
height="500px"
>
<el-table-column label="序号" type="index" align="center" width="80"/>
<el-table-column prop="物料编号" label="物料编号" align="center" width="200"/>
<el-table-column prop="文件名称" label="文件名称" align="center" width="250"/>
<el-table-column prop="操作人" label="操作人" align="center" width="150"/>
<el-table-column prop="删除时间" label="删除时间" align="center" width="200"/>
<el-table-column prop="备注" label="备注" align="center" />
</el-table>
<div slot="footer" class="dialog-footer">
<el-button @click="deleteRecordsVisible = false">关闭</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { MESUploadFile } from '@/utils/request'
import { MESDownFile } from '@/utils/request'
export default {
data() {
return {
imgDialogFormVisible: false,
imgDialogObj: '', // 点检类型对象
stationNumberValue: '', // 点检指导文件选择的工位号
engineType: [], // 点检机型类型
engineTypeValue: '', // 点检机型类型
imgCheckDialogFormVisible: false, // 查看点检文件
stationNumber: [],
stationName: '',
limit: 1,
DataPDF: {},
uploadPDF: MESUploadFile,
downPDF:MESDownFile,
imgCheckDirectFileList: [],
dialogFormVisible: false,
selectedRow:{},
itemupload:false,
tabledata2:[],
tabledata3:[],
uploadValue:'',
currentTime:'',
Uploaddirectly:false,
filename:'',
deleteRecordsVisible: false, // 删除记录弹窗显示状态
deleteRecordsList: [], // 删除记录列表
}
},
computed: {
},
watch: {
},
created() {
this.searchTable()
this.getStationNumber()
this.getCurrentTime()
this.getImgCheckDirectFileList()
},
methods: {
showDeleteRecords() {
this.deleteRecordsVisible = true
this.getDeleteRecords()
},
// 获取删除记录
getDeleteRecords() {
var Data = this.CreateData('11', '工艺管理_图纸维护_查询删除记录', [])
this.ExecDatabase(Data).then(response => {
if (response.data && response.data.length > 0) {
this.deleteRecordsList = response.data
} else {
this.deleteRecordsList = []
this.$message.info('暂无删除记录')
}
}).catch(error => {
console.error('获取删除记录失败:', error)
this.$message.error('获取删除记录失败')
})
},
getCurrentTime() {
const now = new Date();
const year = now.getFullYear();
const month = String(now.getMonth() + 1).padStart(2, '0'); // 月份从0开始需要加1
const day = String(now.getDate()).padStart(2, '0');
const hours = String(now.getHours()).padStart(2, '0');
const minutes = String(now.getMinutes()).padStart(2, '0');
const seconds = String(now.getSeconds()).padStart(2, '0');
this.currentTime = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
},
handleRowClick(row) {
this.selectedRow = row
},
searchTable(){
var param = []
this.imgCheckDirectFileList = []
param[0] = ['零件图号_check', 0]
param[1] = ['零件图号','']
var Data = this.CreateData('11', '工艺管理_图纸维护_零件图查询', param)
this.ExecDatabase(Data).then(response => {
if (response.data.length > 0) {
this.imgCheckDirectFileList = response.data
}
})
},
getStationNumber(query='') {
this.stationNumber = []
var param = []
param.push(["过滤",query])
var Data = this.CreateData('11', '工艺管理_图纸维护_物料查询',param)
this.ExecDatabase(Data).then(response => {
this.stationNumber = response.data
this.tabledata2 = response.data
this.tabledata3 = response.data
})
},
// 表格颜色变化
tableRowClassName({ row, rowIndex }) {
// console.log(row, rowIndex)
if (rowIndex % 2 === 0) {
return 'black'
} else {
return 'red'
}
},
// 上传成功回调
uploadSuccessPDF(res) {
this.dialogFormVisible = false
this.$refs.uploadPDF.clearFiles()
this.$message.success('指导文件上传成功!')
this.searchTable()
},
handleChange(file){
const filename = file.name
const lastIndex = filename.lastIndexOf('.');
const name = filename.substring(0, lastIndex); // 结果: "1.2.3"
const target = name
this.filename = target
if(this.Uploaddirectly){
var param = []
param[0] = ['零件图号',target]
var Data = this.CreateData('11', '工艺管理_图纸维护_验证名称', param)
this.ExecDatabase(Data).then(response => {
if (response.data.length == 0 ) {
this.imgDialogFormVisible = false
this.$message.error(`不存在物料编号'${target}'`)
this.$refs.uploadPDF.clearFiles()
}
})
}
const exists2 = this.imgCheckDirectFileList.some(item => item["num"] === target);
if(exists2){
this.imgDialogFormVisible = false
this.$message.error(`图纸上传重复,请先删除'${target}'`)
this.$refs.uploadPDF.clearFiles()
}
const exists3 = this.imgCheckDirectFileList.some(item => item["name"] === target);
if(exists3){
this.imgDialogFormVisible = false
this.$message.error(`图纸上传重复,请先删除'${target}'`)
this.$refs.uploadPDF.clearFiles()
}
},
// 上传前检测
beforeUploadPdf(file) {
let isJPG = /(\.|\/)(pdf)$/.test(file.type)
if (!isJPG) {
this.$message.error('只能上传PDF')
}
// if(!this.stationNumberValue){
// this.$message.error('请选择物料编号')
// isJPG = false
// }
return isJPG
},
warningExceedPdf() {
this.$message.error('仅可上传一份PDF指导文件')
},
// 预览指导文件按钮
imgCheckDirectFile(row) {
var param = []
console.log(row)
param[0] = ['物料编号',row.num]
var Data = this.CreateData('11', '工艺管理_图纸维护_查看图纸', param)
this.ExecDatabase(Data).then(response => {
console.log(response)
if (response.data.length > 0) {
var pdfSrc =""+this.downPDF+""+ response.data[0].uid+".pdf"
console.log(this.downPDF)
console.log(response.data[0].uid)
console.log(pdfSrc)
window.open(pdfSrc,'_blank')
}
})
},
// 删除指导文件
deleteImgCheckDirectFileSubmit(row) {
this.$confirm('此操作将永久删除该指导文件, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
var param = []
param[0] = ['物料编号', row.num]
param[1] = ['文件名称', row.name || '']
param[2] = ['操作人', this.$store.state.user.name]
var Data = this.CreateData('12', '工艺管理_图纸维护_删除图纸', param)
this.ExecDatabase(Data).then(response => {
if (response.data[0].result === '1') {
this.$message.success('删除指导文件成功!')
this.searchTable()
} else {
this.$message.error('删除指导文件失败!')
}
})
}).catch(() => {
})
},
// 添加指导文件
uploadShowPDF(val) {
if(val==1){
this.itemupload = false
this.Uploaddirectly = false
}else if(val==0){
this.itemupload = true
this.Uploaddirectly = false
}else if(val==2){
this.Uploaddirectly = true
this.itemupload = false
}
this.imgDialogFormVisible = true
},
// 保存文件
// submitPicturePDF() {
// if(!this.uploadValue & this.Uploaddirectly == false){
// return this.$message.error('请先选择物料')
// }
// if(this.Uploaddirectly == true){
// this.uploadValue = this.filename
// }
// var param = []
// param[0] = ['物料编号',this.uploadValue]
// var Data = this.CreateData('11', '工艺管理_图纸维护_查看图纸', param)
// this.ExecDatabase(Data).then(response => {
// if(response.data.length == 0){
// this.DataPDF = {
// num: this.uploadValue,
// // num:'a123',
// tableName: "物料基础数据_零件图纸",
// worker:this.$store.state.user.name,
// uploadTime:this.currentTime
// }
// console.log(JSON.stringify(this.DataPDF))
// this.$refs.uploadPDF.submit()
// this.imgDialogFormVisible = false
// }else{
// this.$refs.uploadPDF.clearFiles()
// this.imgDialogFormVisible = false
// this.$message.error('图纸上传重复,请先删除')
// }
// })
// },
// 保存文件
submitPicturePDF() {
if(!this.uploadValue & this.Uploaddirectly == false){
return this.$message.error('请先选择物料')
}
if(this.Uploaddirectly == true){
this.uploadValue = this.filename
}
var param = []
param[0] = ['物料编号',this.uploadValue]
var Data = this.CreateData('11', '工艺管理_图纸维护_查看图纸', param)
this.ExecDatabase(Data).then(response => {
if(response.data.length == 0){
// 修改这里:确保参数名与后台一致
this.DataPDF .params = JSON.stringify({
num: this.uploadValue, // 取消注释,使用实际值
tableName: '物料基础数据_零件图纸',
worker: this.$store.state.user.name, // 取消注释
uploadTime: this.currentTime // 取消注释
})
console.log('上传参数:', JSON.stringify(this.DataPDF))
this.$refs.uploadPDF.submit()
this.imgDialogFormVisible = false
this.searchTable()
}else{
this.$refs.uploadPDF.clearFiles()
this.imgDialogFormVisible = false
this.$message.error('图纸上传重复,请先删除')
}
})
},
// 查询指导文件列表
getImgCheckDirectFileList() {
var param = []
this.imgCheckDirectFileList = []
if (!this.stationNumberValue) {
param[0] = ['零件图号_check', 0]
param[1] = ['零件图号','']
var Data = this.CreateData('11', '工艺管理_图纸维护_零件图查询', param)
this.ExecDatabase(Data).then(response => {
if (response.data.length > 0) {
this.imgCheckDirectFileList = response.data
} else {
this.$message.error('该工位无此点检指导文件,请添加后查看')
}
})
}else{
param[0] = ['零件图号_check', 1]
param[1] = ['零件图号',this.stationNumberValue]
var Data = this.CreateData('11', '工艺管理_图纸维护_零件图查询', param)
this.ExecDatabase(Data).then(response => {
if (response.data.length > 0) {
this.imgCheckDirectFileList = response.data
} else {
this.$message.error('该工位无此点检指导文件,请添加后查看')
}
})
}
}
}
}
</script>
<style scoped lang="scss">
.NewlyAdded{
background:rgb(253,246,236);
border-color: #ff9759;
color: #ff9759;
&:hover{
background: #ff9759;
border-color: #ff9759;
color: white;
}
&:focus{
background: #ff9759;
border-color: #ff9759;
color: white;
}
}
.el-upload-dragger{
width: 210px;
//right: 30px;
}
</style>

View File

@@ -0,0 +1,267 @@
<template>
<div class="app-container">
<el-card style="height: 850px">
<el-row>
<el-col style="width: 400px;">
<div style="display: flex; align-items: center; margin: 10px 0 3px 0">
<el-input
v-model="searchName"
placeholder="请输入工艺名称"
size="small"
clearable
style="width: 200px; margin-right: 10px"
@input="handleSearch"
/>
<el-button type="primary" plain icon="el-icon-circle-plus-outline" size="small" style="width: 120px;" @click="addProcess">新增工艺</el-button>
</div>
<el-table :data="tableData2" :row-key="getRowKeys" size="mini" highlight-current-row stripe border height="780" width="100%">
<el-table-column label="序号" align="center" type="index" width="60"/>
<el-table-column label="工艺名称" align="center" width="200">
<template slot-scope="scope">
{{ scope.row.工艺名称 }}
</template>
</el-table-column>
<el-table-column align="center" label="操作">
<template slot-scope="scope">
<el-tooltip :open-delay="1200" effect="dark" content="编辑" placement="top">
<div style="display: inline-block">
<el-button type="text" size="mini" icon="el-icon-edit-outline" style="margin-left: 10px; width: 20px; padding: 0px;" @click="editProcess(scope.row)"/>
</div>
</el-tooltip>
<el-tooltip :open-delay="1200" effect="dark" content="删除" placement="top">
<div style="display: inline-block">
<el-button type="text" size="mini" icon="el-icon-delete" style="margin-left: 10px; width: 20px; padding: 0px;" @click="delProcess(scope.row)"/>
</div>
</el-tooltip>
</template>
</el-table-column>
</el-table>
</el-col>
</el-row>
</el-card>
<el-dialog :visible.sync="dialogFormVisible" :title="title" center style="min-height: 300px" width="400px">
<el-form ref="form1" :model="form1" :rules="rules1" label-position="left" label-width="110px" >
<el-form-item label="工艺名称" prop="ProcessClassification">
<el-input v-model="form1.ProcessClassification" size="small" clearable style="width:200px"/>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="calloff"> </el-button>
<el-button v-show="title==='新增工艺'" type="primary" @click="submitaddProcess('form1')"> </el-button>
<el-button v-show="title==='编辑工艺'" type="primary" @click="submiteditProcess('form1')"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { postB1 } from '@/api/b1s';
import { getB1 } from '@/api/b1s';
import { patchB1 } from '@/api/b1s';
export default {
data() {
return {
// 工艺分类所需变量
title: '',
expands: [],
tableData1: [],
ProcessNum: '',
loading: false,
dialogFormVisible: false,
temp: null,
ProcessClassificationNumS: '',
searchName: '', // 搜索框内容
form1: {
ProcessClassification: '',
TechnologicalRequirements: ''
},
rules1: {
ProcessClassification: [{ required: true, message: '请输入工艺分类名称', trigger: 'blur' }]
},
tableData2: [],
allTableData2: [], // 存储所有工艺数据
tableData3: [],
Num: [],
maxNum: '',
max: [],
code: '',
completionTime:''
}
},
created() {
this.getProcess()
var now = new Date();
var start = new Date(
Date.UTC(now.getFullYear() , now.getMonth(), now.getDate())
)
.toISOString()
.replace("T", " ")
.replace(".000Z", "");
var end = new Date(
Date.UTC(now.getFullYear(), now.getMonth(), now.getDate(), 23, 59, 59)
)
.toISOString()
.replace("T", " ")
.replace(".000Z", "");
this.completionTime= [start, end];
},
methods: {
getProcess() {
var param = []
// 参数数量与名称要与存储过程对应
var Data = this.CreateData('11', 'MES_ProcessManagement_ProcessGet', param)
this.ExecDatabase(Data).then(response => {
this.allTableData2 = response.data
this.tableData2 = response.data
})
},
// 处理搜索
handleSearch() {
if (this.searchName) {
this.tableData2 = this.allTableData2.filter(item => {
return item.工艺名称.includes(this.searchName)
})
} else {
this.tableData2 = this.allTableData2
}
},
calloff() {
if (this.$refs['form1'] !== undefined) {
this.$refs['form1'].resetFields()
}
this.dialogFormVisible = false
this.form1 = {
ProcessClassification: ''
}
},
addProcess() {
if (this.$refs['form1'] !== undefined) {
this.$refs['form1'].resetFields()
}
this.form1.ProcessClassification = ''
this.title = '新增工艺'
this.dialogFormVisible = true
},
submitaddProcess(formName) {
this.$refs[formName].validate((valid) => {
if (valid) {
var param = []
param[0] = ['工艺名称', this.form1.ProcessClassification]
// 参数数量与名称要与存储过程对应
var Data = this.CreateData('11', 'MES_ProcessManagement_ProcessAdd', param)
this.ExecDatabase(Data).then(response => {
if (response.data.length > 0 ) {
this.$message.success('增加成功')
postB1("/RouteStages",{
"Code": response.data[0].工艺编号,
"Description": this.form1.ProcessClassification,
"CreationDate": this.completionTime[0],
"DateOfUpdate": this.completionTime[0]
})
this.getProcess()
this.dialogFormVisible = false
} else {
this.$message.error('增加失败')
}
})
} else {
return false
}
})
},
editProcess(row) {
if (this.$refs['form1'] !== undefined) {
this.$refs['form1'].resetFields()
}
this.title = '编辑工艺'
this.dialogFormVisible = true
this.form1.ProcessClassification = row.工艺名称
this.ProcessNum = row.工艺编号
},
submiteditProcess(formName) {
this.$refs[formName].validate((valid) => {
if (valid) {
var param = []
param[0] = ['工艺名称', this.form1.ProcessClassification]
param[1] = ['工艺编号', this.ProcessNum]
// 参数数量与名称要与存储过程对应
var Data = this.CreateData('12', 'MES_ProcessManagement_ProcessEdit', param)
this.ExecDatabase(Data).then(async response => {
if (response.data[0].result === '1') {
var code = this.ProcessNum
var result = await getB1("/RouteStages",{
"$filter": "Code eq '"+ code+"'"
})
console.log(result)
var InternalNumber = result.data.value[0].InternalNumber
this.$message.success('编辑成功')
patchB1("/RouteStages("+InternalNumber+")",{
"Description": this.form1.ProcessClassification,
"DateOfUpdate": this.completionTime[0]
})
this.getProcess()
this.dialogFormVisible = false
} else {
this.$message.error('编辑失败')
}
})
} else {
return false
}
})
},
getRowKeys(row) {
return row.工艺编号
},
delProcess(row) {
this.$confirm('此操作将永久删除' + row.工艺名称 + '行, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
var param = []
param[0] = ['工艺编号', row.工艺编号]
// 参数数量与名称要与存储过程对应
var Data = this.CreateData('12', 'MES_ProcessManagement_Processdel', param)
this.ExecDatabase(Data).then(response => {
if (response.data[0].result === '1') {
this.$message.success('删除成功')
this.getProcess()
} else {
this.$message.error('删除失败')
}
})
})
}
}
}
</script>
<style scoped>
/*.el-card {*/
/* margin-top: 15px;*/
/* margin-left: 15px;*/
/* }!**!*/
</style>
<style lang="scss">
// .el-button{
// width: 20px;
// padding: 0px;
// }
.subTableHeader {
th {
background: #8ff4ea !important;
color: black;
}
tr.el-table__row td {
background-color: #d8e5f6 !important;
}
tr.el-table__row.el-table__row--striped td {
background: #e9f0f9 !important;
}
}
</style>

View File

@@ -0,0 +1,415 @@
<template>
<div class="app-container">
<el-card class="topCard">
<div class="topDiv">
<span style="margin-left: 10px">物料编号:</span>
<el-select v-model="stationNumberValue" placeholder="请选择物料" filterable clearable remote :remote-method="getStationNumber" size="small" style="width: 250px" @change="queryitem" >
<el-option
v-for="item in stationNumber"
:key="item.物料编码"
:label="item.物料编码"
:value="item.物料编码"
size="mini">
</el-option>
</el-select>
<el-button type="primary" plain size="small" icon="el-icon-order" @click="getImgCheckDirectFileList">查询</el-button>
<el-button type="primary" icon="el-icon-circle-plus-outline" size="small" @click="uploadShowPDF(val = 2)" style="width: 100px;">工艺图</el-button>
<el-button type="primary" icon="el-icon-circle-plus-outline" size="small" @click="uploadShowPDF(val = 0)" style="width: 155px;">选零件上传工艺图</el-button>
<el-button type="primary" icon="el-icon-circle-plus-outline" size="small" @click="uploadShowPDF(val = 0)" style="width: 155px;">选订单上传工艺图</el-button>
</div>
<div class="main">
<el-table
ref="multipleTable"
:data="imgCheckDirectFileList"
:header-cell-style="{background:'#eef1f6',color:'#606266'}"
:cell-class-name="tableRowClassName"
element-loading-text="数据加载中"
element-loading-spinner="el-icon-loading"
element-loading-background="rgba(0, 0, 0, 0.2)"
class="main"
tooltip-effect="dark"
height="640px"
style="width: 90%"
border
size="mini"
@row-click="handleRowClick"
>
<el-table-column label="序号" type="index" align="center" width="80"/>
<el-table-column prop="num" label="物料编号" align="center" width="200"/>
<el-table-column prop="物料描述" label="物料名称" align="center" width="250"/>
<el-table-column prop="name" label="文件名称" align="center" width="100"/>
<el-table-column prop="worker" label="导入人" align="center" width="100"/>
<el-table-column prop="uploadTime" label="导入时间" align="center" width="150"/>
<el-table-column label="操作" align="center" width="250">
<template slot-scope="scope">
<el-button type="text" icon="el-icon-view" size="mini" @click="imgCheckDirectFile(scope.row)" >查看</el-button>
<el-button type="text" icon="el-icon-delete" size="mini" style="color: #ff0000" @click="deleteImgCheckDirectFileSubmit(scope.row)" >删除</el-button>
</template>
</el-table-column>
</el-table>
</div>
</el-card>
<!--上传文件-->
<el-dialog :visible.sync="imgDialogFormVisible" title="上传指导文件" center style="height: 800px" width="460px">
<span v-if="itemupload" style="margin-left: 10px">物料编号:</span>
<span v-if="orderupload" style="margin-left: 10px">生产订单:</span>
<el-select v-if="itemupload" v-model="uploadValue" placeholder="请选择" filterable clearable remote :remote-method="getStationNumber" size="small" style="width: 250px; margin-bottom: 20px;" >
<el-option
v-for="item in tabledata2"
:key="item.物料编码"
:label="item.物料编码"
:value="item.物料编码"
size="mini"/>
</el-select>
<el-select v-if="orderupload" v-model="uploadValue" placeholder="请选择" filterable clearable remote :remote-method="getStationNumber" size="small" style="width: 250px; margin-bottom: 20px;" >
<el-option
v-for="item in tabledata3"
:key="item.物料编码"
:label="item.物料编码"
:value="item.物料编码"
size="mini">
<b style="float: left">{{ item.订单编号 }}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{{ item.物料描述 }}</b>
</el-option>
</el-select>
<el-upload
ref="uploadPDF"
:multiple="true"
:auto-upload="false"
:on-success="uploadSuccessPDF"
:before-upload="beforeUploadPdf"
:on-exceed="warningExceedPdf"
:limit="limit"
:data="DataPDF"
:on-change="handleChange"
:action="uploadPDF"
accept=".pdf"
style="margin-left: 30px"
drag>
<i class="el-icon-upload"/>
<div class="el-upload__text">将文件拖到此处<em>点击上传</em></div>
<div slot="tip" class="el-upload__tip">只能上传一个pdf文件且不超过100mb</div>
</el-upload>
<div slot="footer" class="dialog-footer">
<el-button @click="imgDialogFormVisible=false">取消</el-button>
<el-button type="primary" style="width: 70px" @click="submitPicturePDF()">确定</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { MESUploadFile } from '@/utils/request'
import { MESDownFile } from '@/utils/request'
export default {
data() {
return {
imgDialogFormVisible: false,
imgDialogObj: '', // 点检类型对象
stationNumberValue: '', // 点检指导文件选择的工位号
engineType: [], // 点检机型类型
engineTypeValue: '', // 点检机型类型
imgCheckDialogFormVisible: false, // 查看点检文件
stationNumber: [],
stationName: '',
limit: 1,
DataPDF: {},
uploadPDF: MESUploadFile,
downPDF:MESDownFile,
imgCheckDirectFileList: [],
dialogFormVisible: false,
selectedRow:{},
itemupload:false,
orderupload:false,
tabledata2:[],
tabledata3:[],
uploadValue:'',
currentTime:'',
Uploaddirectly:false,
filename:'',
}
},
computed: {
},
watch: {
},
created() {
// this.searchTable()
this.getStationNumber()
this.getCurrentTime()
this.getStationNumber()
this.getImgCheckDirectFileList()
},
methods: {
queryitem(){
console.log(this.stationNumberValue)
},
getCurrentTime() {
const now = new Date();
const year = now.getFullYear();
const month = String(now.getMonth() + 1).padStart(2, '0'); // 月份从0开始需要加1
const day = String(now.getDate()).padStart(2, '0');
const hours = String(now.getHours()).padStart(2, '0');
const minutes = String(now.getMinutes()).padStart(2, '0');
const seconds = String(now.getSeconds()).padStart(2, '0');
this.currentTime = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
},
handleRowClick(row) {
this.selectedRow = row
},
searchTable(){
var param = []
this.imgCheckDirectFileList = []
param[0] = ['零件图号_check', 0]
param[1] = ['零件图号','']
var Data = this.CreateData('11', '工艺管理_工艺维护_工艺图查询', param)
this.ExecDatabase(Data).then(response => {
if (response.data.length > 0) {
this.imgCheckDirectFileList = response.data
}
})
},
getStationNumber(query='') {
this.stationNumber = []
var param = []
param.push(["过滤",query])
var Data = this.CreateData('11', '工艺管理_图纸维护_物料查询',param)
this.ExecDatabase(Data).then(response => {
this.stationNumber = response.data
this.tabledata2 = response.data
this.tabledata3 = response.data
})
},
// 表格颜色变化
tableRowClassName({ row, rowIndex }) {
// console.log(row, rowIndex)
if (rowIndex % 2 === 0) {
return 'black'
} else {
return 'red'
}
},
// 上传成功回调
uploadSuccessPDF(res) {
this.dialogFormVisible = false
this.$refs.uploadPDF.clearFiles()
this.$message.success('指导文件上传成功!')
this.searchTable()
},
handleChange(file){
const filename = file.name
const lastIndex = filename.lastIndexOf('.');
const name = filename.substring(0, lastIndex); // 结果: "1.2.3"
const target = name
this.filename = target
if(this.Uploaddirectly){
var param = []
param[0] = ['零件图号',target]
var Data = this.CreateData('11', '工艺管理_工艺维护_验证名称', param)
this.ExecDatabase(Data).then(response => {
if (response.data.length == 0 ) {
this.imgDialogFormVisible = false
this.$message.error(`不存在物料编号'${target}'`)
this.$refs.uploadPDF.clearFiles()
}
})
}
const exists2 = this.imgCheckDirectFileList.some(item => item["num"] === target);
if(exists2){
this.imgDialogFormVisible = false
this.$message.error(`图纸上传重复,请先删除'${target}'`)
this.$refs.uploadPDF.clearFiles()
}
const exists3 = this.imgCheckDirectFileList.some(item => item["name"] === target);
if(exists3){
this.imgDialogFormVisible = false
this.$message.error(`图纸上传重复,请先删除'${target}'`)
this.$refs.uploadPDF.clearFiles()
}
},
// 上传前检测
beforeUploadPdf(file) {
let isJPG = /(\.|\/)(pdf)$/.test(file.type)
if (!isJPG) {
this.$message.error('只能上传PDF')
}
// if(!this.stationNumberValue){
// this.$message.error('请选择物料编号')
// isJPG = false
// }
return isJPG
},
warningExceedPdf() {
this.$message.error('仅可上传一份PDF指导文件')
},
// 预览指导文件按钮
imgCheckDirectFile(row) {
var param = []
console.log(row)
param[0] = ['物料编号',row.num]
var Data = this.CreateData('11', '工艺管理_工艺维护_查看图纸', param)
this.ExecDatabase(Data).then(response => {
console.log(response)
if (response.data.length > 0) {
var pdfSrc =""+this.downPDF+""+ response.data[0].uid+".pdf"
console.log(this.downPDF)
console.log(response.data[0].uid)
console.log(pdfSrc)
window.open(pdfSrc,'_blank')
}
})
},
// 删除指导文件
deleteImgCheckDirectFileSubmit(row) {
this.$confirm('此操作将永久删除该指导文件, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
var param = []
param[0] = ['物料编号', row.num]
var Data = this.CreateData('12', '工艺管理_工艺维护_删除图纸', param)
this.ExecDatabase(Data).then(response => {
if (response.data[0].result === '1') {
this.$message.success('删除指导文件成功!')
this.searchTable()
} else {
this.$message.error('删除指导文件失败!')
}
})
}).catch(() => {
})
},
// 添加指导文件
uploadShowPDF(val) {
if(val==1){
this.itemupload = false
this.Uploaddirectly = false
}else if(val==0){
this.itemupload = true
this.Uploaddirectly = false
}else if(val==2){
this.Uploaddirectly = true
this.itemupload = false
}
this.imgDialogFormVisible = true
},
// 保存文件
// submitPicturePDF() {
// if(!this.uploadValue & this.Uploaddirectly == false){
// return this.$message.error('请先选择物料')
// }
// if(this.Uploaddirectly == true){
// this.uploadValue = this.filename
// }
// var param = []
// param[0] = ['物料编号',this.uploadValue]
// var Data = this.CreateData('11', '工艺管理_图纸维护_查看图纸', param)
// this.ExecDatabase(Data).then(response => {
// if(response.data.length == 0){
// this.DataPDF = {
// num: this.uploadValue,
// // num:'a123',
// tableName: "物料基础数据_零件图纸",
// worker:this.$store.state.user.name,
// uploadTime:this.currentTime
// }
// console.log(JSON.stringify(this.DataPDF))
// this.$refs.uploadPDF.submit()
// this.imgDialogFormVisible = false
// }else{
// this.$refs.uploadPDF.clearFiles()
// this.imgDialogFormVisible = false
// this.$message.error('图纸上传重复,请先删除')
// }
// })
// },
// 保存文件
submitPicturePDF() {
if(!this.uploadValue & this.Uploaddirectly == false){
return this.$message.error('请先选择物料')
}
if(this.Uploaddirectly == true){
this.uploadValue = this.filename
}
var param = []
param[0] = ['物料编号',this.uploadValue]
var Data = this.CreateData('11', '工艺管理_工艺维护_查看图纸', param)
this.ExecDatabase(Data).then(response => {
if(response.data.length == 0){
// 修改这里:确保参数名与后台一致
this.DataPDF.params = JSON.stringify({
num: this.uploadValue, // 取消注释,使用实际值
tableName: '物料基础数据_工艺图纸',
worker: this.$store.state.user.name, // 取消注释
uploadTime: this.currentTime // 取消注释
})
console.log('上传参数:', JSON.stringify(this.DataPDF))
this.$refs.uploadPDF.submit()
this.imgDialogFormVisible = false
}else{
this.$refs.uploadPDF.clearFiles()
this.imgDialogFormVisible = false
this.$message.error('图纸上传重复,请先删除')
}
})
},
// 查询指导文件列表
getImgCheckDirectFileList() {
var param = []
this.imgCheckDirectFileList = []
if (!this.stationNumberValue) {
param[0] = ['零件图号_check', 0]
param[1] = ['零件图号','']
var Data = this.CreateData('11', '工艺管理_工艺维护_工艺图查询', param)
this.ExecDatabase(Data).then(response => {
if (response.data.length > 0) {
this.imgCheckDirectFileList = response.data
} else {
this.$message.error('该工位无此点检指导文件,请添加后查看')
}
})
}else{
param[0] = ['零件图号_check', 1]
param[1] = ['零件图号',this.stationNumberValue]
var Data = this.CreateData('11', '工艺管理_工艺维护_工艺图查询', param)
this.ExecDatabase(Data).then(response => {
if (response.data.length > 0) {
this.imgCheckDirectFileList = response.data
} else {
this.$message.error('该工位无此点检指导文件,请添加后查看')
}
})
}
}
}
}
</script>
<style scoped lang="scss">
.NewlyAdded{
background:rgb(253,246,236);
border-color: #ff9759;
color: #ff9759;
&:hover{
background: #ff9759;
border-color: #ff9759;
color: white;
}
&:focus{
background: #ff9759;
border-color: #ff9759;
color: white;
}
}
.el-upload-dragger{
width: 210px;
//right: 30px;
}
</style>

View File

@@ -0,0 +1,497 @@
<template>
<div class="app-container">
<el-card style="height: 850px">
<div style="margin-top: 7px; margin-bottom: 7px">
<span class="show-text">物料编码:</span>
<el-select v-if="processprodutc" v-model="partNameValue3" style="width:200px;margin-left: 10px" placeholder="生产工艺物料名称" size="small" filterable clearable remote :remote-method="searchTable" >
<el-option
v-for="item in tableData3"
:key="item.物料编码"
:label="item.物料描述"
:value="item.物料编码">
<b style="float: left">{{ item.物料描述 }}</b>
</el-option>
</el-select>
<el-select v-else v-model="partNameValue3" style="width:200px;margin-left: 10px" placeholder="物料名称" size="small" filterable clearable remote :remote-method="searchTable" >
<el-option
v-for="item in tableData3"
:key="item.物料编码"
:label="item.物料描述"
:value="item.物料编码">
<b style="float: left">{{ item.物料描述 }}</b>
</el-option>
</el-select>
<span class="show-text">生产订单:</span>
<el-input v-model="orderNo" placeholder="请输入生产订单" clearable style="width: 150px;margin-right: 10px" />
<span class="show-text">任务状态:</span>
<el-select v-model="taskstatus" placeholder="请选择">
<el-option
key='0'
label="全部"
value="0">
</el-option>
<el-option
key='1'
label="已打印"
value="1">
</el-option>
<el-option
key='2'
label="未打印"
value="2">
</el-option>
</el-select>
<el-button icon="el-icon-search" type="primary" plain size="small" style="margin-left: 10px;padding: 8px 15px;" @click="searchTable3">查询</el-button>
<el-button icon="el-icon-printer" type="primary" plain size="small" style="margin-left: 10px;padding: 8px 15px;" @click="handlePrint" :disabled="multipleSelection.length === 0">打印</el-button>
</div>
<el-table
v-show="!checked"
:data="tableData"
highlight-current-row
border
size="small"
style="margin-top: 10px"
height="740px"
@selection-change="handleSelectionChange"
@row-click="handleRowClick">
<el-table-column type="selection" width="55"></el-table-column>
<el-table-column label="序号" type="index" align="center" width="80"/>
<el-table-column label="生产订单" align="center" prop="订单编号" width="80" />
<el-table-column label="物料名称" align="center" prop="零件名称" width="250"/>
<el-table-column label="物料编码" align="center" prop="零件图号" width="200"/>
<el-table-column label="加工数量" align="center" prop="计划数量" width="80"/>
<el-table-column label="打印次数" align="center" prop="周转单打印次数" width="80"/>
<!-- <el-table-column label="操作" align="center" width="155px">
<template slot-scope="scope">
</template>
</el-table-column> -->
</el-table>
<div class="block" style="margin-top: 10px;">
<el-pagination
:current-page="pageCurrent"
:page-sizes="[20, 50, 100]"
:page-size="pageSize"
:total="total1"
layout="total, sizes, prev, pager, next, jumper"
@size-change="handleSizeChanges"
@current-change="handleCurrentChanges"/>
</div>
<!-- 打印内容区域 -->
<div v-for="(printData, index) in printDataList" :key="index" class="print-page" style="display: none; width: 9cm;height: 13cm;background-color: #fff; page-break-after: always;" >
<div style="margin-bottom: 10px;">
<div style="display: flex;">
<div style="width: 35%;
height: 20px;
background: url(/static/img/logo.1e81c84.png);
background-size: contain;
background-repeat: no-repeat;
"></div>
<div style="width: 65%;text-align: left;">大连元利流体</div>
</div>
<div style="text-align: center;">工序周转单</div>
</div>
<div style="display: flex;">
<div style="width: 50%;">
<span style="width: 35%;font-size: 10px;">生产订单</span>
<span style="font-size: 10px;">{{ printData.orderInfo.订单编号 }}</span>
</div>
<div style="width: 50%;">
<span style="width: 35%;font-size: 10px;">合同编号</span>
<span style="font-size: 10px;">{{ printData.orderInfo.合同号 }}</span>
</div>
</div>
<div style="display: flex;">
<div style="width: 50%;">
<span style="width: 35%;font-size: 10px;">重要程度</span>
<span style="font-size: 10px;">{{ printData.orderInfo.加急状态 }}</span>
</div>
<div style="width: 50%;">
<span style="width: 35%;font-size: 10px;">物料名称</span>
<span style="font-size: 10px;">{{ printData.orderInfo.零件名称 }}</span>
</div>
</div>
<div style="display: flex;">
<div style="width: 50%;">
<span style="width: 35%;font-size: 10px;">加工数量</span>
<span style="font-size: 10px;">{{ printData.orderInfo.计划数量 }}</span>
</div>
<div style="width: 50%;">
<span style="width: 35%;font-size: 10px;">要求日期</span>
<span style="font-size: 10px;">{{ formatDate(printData.orderInfo.计划完成) }}</span>
</div>
</div>
<div style="display: flex;">
<div>
<span style="width: 35%;font-size: 10px;">物料编码</span>
<span style="font-size: 10px;">{{ printData.orderInfo.零件图号 }}</span>
</div>
</div>
<div style="font-size: 10px ; text-align: center; line-height: 20px; border: 1px solid; border-bottom: 0; ">
<div style="display: flex; ">
<div style="width: 10%; border-right:1px solid; border-bottom: 1px solid;"></div>
<div style="width: 20%; border-right:1px solid; border-bottom: 1px solid;">工序名称</div>
<div style="width: 15%; border-right:1px solid; border-bottom: 1px solid;">工时</div>
<div style="width: 40%; border-right:1px solid; border-bottom: 1px solid;">条码</div>
<div style="width: 15%; border-bottom: 1px solid;">检验</div>
</div>
<div v-for="value in printData.processList" :key="value.id" style="display: flex; border-bottom: 1px solid;">
<div style="width: 10%; border-right:1px solid">{{ value.工艺顺序 }}</div>
<div style="width: 20%; border-right:1px solid">{{ value.工艺名称 }}</div>
<div style="width: 15%; border-right:1px solid">{{ value.标准工时 }}</div>
<div style="width: 40%; border-right:1px solid"></div>
<div style="width: 15%;"></div>
</div>
</div>
</div>
</el-card>
</div>
</template>
<script>
import { mapGetters } from 'vuex'
import $ from 'jquery'
import QRCode from 'qrcode'
export default {
data() {
return {
processprodutc: true,
dialogVisible1: false,
hadFile1: [],
processValue: '',
dialogName: true,
orderNumberTypeValue: '',
orderNumberType: [],
productpartNameValue: '',
productpartName: [],
partNameValue: '',
partName: '',
hadFile: [],
fileList: [],
tableData1: [],
dialogVisible: false,
dialogFormVisible1: false,
dialogFormVisible2: false,
checked: false,
loading: false,
total: 0,
total1: 0,
tableData: [],
tableData2: [],
pageCurrent: 1,
pageSize: 20,
orderName: '',
order: '',
partNameValue1: '',
tableData3: '',
materialarr: [],
partNameValue3: '',
selectedRow: '',
tableData4: '',
qrCodeUrl: '',
multipleSelection: [],
printDataList: [],
isPrinting: false,// 新增:打印状态标志
taskstatus:'2',
orderNo:''
}
},
computed: {
...mapGetters([
'id',
'token'
])
},
created() {
this.searchTable()
this.searchTable3()
},
methods: {
handleSelectionChange(val) {
this.multipleSelection = val;
},
async generateQRCode(text) {
try {
const url = await QRCode.toDataURL(String(text), {
width: 20,
margin: 1,
color: {
dark: '#000000',
light: '#ffffff'
}
})
this.qrCodeUrl = url
} catch (err) {
console.error('二维码生成失败:', err)
}
},
formatDate(date) {
if (!date) return ''
return date.split(' ').length > 1 ? date.split(' ')[0] : date
},
handleRowClick(row) {
this.selectedRow = row
},
searchTable(query = '') {
this.loading = true
var param = []
param.push(["过滤", query])
var Data = this.CreateData('11', 'MES_ProcessManagement_PartGet', param)
this.ExecDatabase(Data).then(response => {
this.tableData3 = response.data
this.loading = false
})
},
// 修改:整合打印流程
async handlePrint() {
if (this.multipleSelection.length === 0) {
this.$message.warning('请选择要打印的数据')
return
}
if (this.isPrinting) {
this.$message.warning('正在打印中,请稍候...')
return
}
this.isPrinting = true
this.loading = true
try {
// 1. 获取打印数据
await this.preparePrintData()
// 2. 执行打印
await this.executePrint()
// 3. 更新打印次数
await this.recordPrintCount()
this.$message.success('打印完成')
} catch (error) {
console.error('打印流程失败:', error)
this.$message.error('打印失败: ' + error.message)
} finally {
this.loading = false
this.isPrinting = false
}
},
// 准备打印数据
async preparePrintData() {
this.printDataList = []
for (const item of this.multipleSelection) {
const param = [
['物料编号', [item.零件图号]],
['订单编号', [item.订单编号]]
]
const Data = this.CreateData('11', '工艺管理_工艺查询_查询生产工艺', param)
const response = await this.ExecDatabase(Data)
if (response.data && response.data.length > 0) {
const orderInfo = response.data[0]
this.printDataList.push({
orderInfo: orderInfo,
processList: response.data
})
}
}
if (this.printDataList.length === 0) {
throw new Error('未找到对应的工艺数据')
}
},
// 执行打印
executePrint() {
return new Promise((resolve, reject) => {
try {
// 保存原始样式
const originalStyles = {}
$('.print-page').each(function(index) {
originalStyles[index] = $(this).attr('style')
})
const body = $('body')
// 隐藏原始内容
body.children().hide()
// 创建打印容器
const printContainer = $('<div class="print-container"></div>')
// 复制所有打印页面到打印容器
$('.print-page').each(function() {
const pageClone = $(this).clone()
pageClone.css({
display: 'block',
width: '9cm',
height: '13cm',
'background-color': '#fff',
'page-break-after': 'always',
margin: '0',
padding: '0'
})
printContainer.append(pageClone)
})
// 添加到body
body.append(printContainer)
// 打印后恢复
const restorePage = () => {
try {
printContainer.remove()
body.children().show()
// 恢复原始样式
$('.print-page').each(function(index) {
if (originalStyles[index]) {
$(this).attr('style', originalStyles[index])
} else {
$(this).css('display', 'none')
}
})
if (window.matchMedia) {
window.matchMedia('print').removeListener(handlePrintChange)
}
resolve()
} catch (error) {
reject(error)
}
}
const handlePrintChange = (mql) => {
if (!mql.matches) {
restorePage()
}
}
// 添加打印状态监听
if (window.matchMedia) {
window.matchMedia('print').addListener(handlePrintChange)
}
// 设置超时恢复(备用)
setTimeout(restorePage, 5000)
// 触发打印
window.print()
} catch (error) {
reject(error)
}
})
},
// 记录打印次数
async recordPrintCount() {
try {
const orderNumbers = this.multipleSelection.map(item => item.订单编号)
if (orderNumbers.length === 0) {
return
}
const param = [
['订单编号列表', orderNumbers.join(',')]
]
const Data = this.CreateData('11', '工艺管理_工艺查询_更新打印次数', param)
const response = await this.ExecDatabase(Data)
this.searchTable3()
if (response && response.success) {
console.log(`成功更新${orderNumbers.length}个订单的打印次数`)
// 刷新表格数据
} else {
console.warn('更新打印次数失败', response)
}
} catch (error) {
console.error('记录打印次数失败:', error)
// 这里不显示错误消息,避免影响用户体验
}
},
searchTable3() {
this.loading = true
var param = []
param.push(['物料编号', this.partNameValue3])
param.push(['PageCurrent', this.pageCurrent])
param.push(['PageSize', this.pageSize])
param.push(['PageCount', '1111', 'int', '1'])
param.push(['ItemCount', '1111', 'int', '1'])
param.push(['状态', this.taskstatus])
param.push(['生产订单', this.orderNo])
if (this.processprodutc) {
param.push(['生产工艺', 1])
var Data = this.CreateData('11', '工艺管理_工艺查询_生产工艺查询', param)
this.ExecDatabase(Data).then(response => {
this.tableData = response.data.result
this.total1 = parseInt(response.data.output[0].ItemCount)
this.loading = false
}).catch(() => {
this.loading = false
})
} else {
param.push(['生产工艺', 0])
var Data = this.CreateData('11', '工艺管理_工艺查询', param)
this.ExecDatabase(Data).then(response => {
this.tableData = response.data.result
this.total1 = parseInt(response.data.output[0].ItemCount)
this.loading = false
}).catch(() => {
this.loading = false
})
}
},
handleSizeChanges(val) {
this.pageCurrent = 1
this.pageSize = val
this.searchTable3()
},
handleCurrentChanges(val) {
this.pageCurrent = val
this.searchTable3()
}
}
}
</script>
<style scoped>
.el-form--label-left >>> .el-form-item__label {
text-align: right;
}
/* 打印样式 */
@media print {
body * {
visibility: hidden;
}
.print-container, .print-container * {
visibility: visible;
}
.print-container {
position: absolute;
left: 0;
top: 0;
width: 100%;
background: white;
}
.print-page {
display: block !important;
margin: 0 !important;
padding: 0 !important;
box-sizing: border-box;
}
}
</style>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,891 @@
<template>
<div class="app-container">
<el-card style="height: 950px">
<el-row>
<div style="margin-top: 7px; margin-bottom: 7px">
<el-select v-model="partNameValue3" style="width:400px;margin-left: 10px" placeholder="物料名称" size="small" filterable clearable remote :remote-method="searchTable" @change="searchTable1">
<el-option
v-for="item in tableData3"
:key="item.物料编码"
:label="item.物料编码"
:value="item.物料编码">
</el-option>
</el-select>
<el-button icon="el-icon-search" type="primary" plain size="small" style="margin-left: 10px;padding: 8px 15px;" @click="searchTable1()">查询</el-button>
<el-button icon="el-icon-document-copy" type="warning" plain size="small" style="margin-left: 10px;padding: 8px 15px;" @click="copyData()">拷贝</el-button>
<el-button icon="el-icon-search" type="primary" plain size="small" style="margin-left: 10px;padding: 8px 15px;" @click="getNum()">图纸</el-button>
<!-- <el-button icon="el-icon-document-copy" v-if="processStatus" type="success" plain size="small" style="margin-left: 10px;padding: 8px 15px;" >已保存</el-button> -->
<el-button icon="el-icon-document-copy" type="success" plain size="small" style="margin-left: 10px;padding: 8px 15px;" @click="saveProcess()">保存</el-button>
<!-- <el-button type="success" plain icon="el-icon-check" size="small" style="margin-left: 10px" @click="preservation1()">保存</el-button> -->
<!-- <el-button type="success" plain icon="el-icon-download" size="small" style="margin-left: 760px" @click="exportExcel()">导出</el-button>-->
</div>
<div style="margin: 7px;">
原料:<span v-for="(item, index) in itemdata" :key="index">{{ item.子件名称 }}({{ item.子件数量 }})</span>
</div>
<div style="display: flex;">
<el-col style="margin-left: 7px;width: 158px">
<div style="margin-top: 10px">
<el-input
v-model="processSearchName"
placeholder="请输入工序名称"
size="small"
clearable
style="width: 158px; margin-bottom: 10px"
@input="filterProcess"
/>
<el-table :data="filteredTableData4" :header-cell-style="{background: '#2283D4',color: 'white'}" highlight-current-row border size="mini" style="width: 158px;margin-top: 10px" height="780" @row-click="editProcedure">
<el-table-column :width="setColumnWidth('日期时间')" label="工序" align="center" prop="" show-overflow-tooltip>
<template slot-scope="scope">
{{ scope.row.工艺名称 }}
</template>
</el-table-column>
</el-table>
</div>
</el-col>
<el-col >
<div style="margin-top: 10px">
<el-table v-loading="loading" :data="tableData5" :header-cell-style="{background: '#19466E',color: 'white'}" highlight-current-row border size="mini" style="margin-top: 10px;width:90%" height="700" >
<el-table-column width="50px" label="序号" align="center" prop="工艺顺序" show-overflow-tooltip fixed>
<template slot-scope="scope">
{{ scope.row.工艺顺序 }}
</template>
</el-table-column>
<el-table-column width="130px" label="工序名称" align="center" prop="工艺名称" show-overflow-tooltip fixed>
<template slot-scope="scope">
{{ scope.row.工艺名称 }}
</template>
</el-table-column>
<el-table-column label="准备工时" align="center" prop="准备工时" show-overflow-tooltip>
<template slot-scope="scope">
<el-input v-model="scope.row.准备工时" size="mini" style="margin: 0;width: 100%" @change="updateProcess(scope.row)"/>
</template>
</el-table-column>
<el-table-column label="标准工时" align="center" prop="标准工时" show-overflow-tooltip>
<template slot-scope="scope">
<el-input v-model="scope.row.标准工时" size="mini" style="margin: 0;width: 100%" @change="updateProcess(scope.row)"/>
</template>
</el-table-column>
<el-table-column label="工时合计" align="center" prop="工时合计" show-overflow-tooltip>
<template slot-scope="scope">
<el-input v-model="scope.row.工时合计" size="mini" style="margin: 0;width: 100%" @change="updateProcess(scope.row)"/>
</template>
</el-table-column>
<el-table-column label="工装量具" align="center" width="150px">
<template slot-scope="scope">
<el-select v-model="scope.row.工卡量具" multiple placeholder="工装量具" size="small" filterable clearable @change="updateProcess(scope.row)">
<el-option
v-for="item in basedatagj"
:key="item.id"
:label="item.name"
:value="item.id">
</el-option>
</el-select>
</template>
</el-table-column>
<el-table-column label="指定机床" align="center" width="150px" >
<template slot-scope="scope">
<el-select v-model="scope.row.指定机床" multiple placeholder="指定机床" size="small" filterable clearable @change="updateProcess(scope.row)">
<el-option
v-for="item in basedatajc"
:key="item.id"
:label="item.name"
:value="item.id">
</el-option>
</el-select>
</template>
</el-table-column>
<el-table-column label="车间" align="center" width="150px">
<template slot-scope="scope">
<el-select v-model="scope.row.车间" placeholder="车间" size="small" filterable clearable @change="updateProcess(scope.row)">
<el-option
v-for="item in basedatacj"
:key="item.id"
:label="item.name"
:value="item.name">
</el-option>
</el-select>
</template>
</el-table-column>
<el-table-column width="330px" label="工序说明" align="center" prop="" show-overflow-tooltip>
<template slot-scope="scope">
<el-input v-model="scope.row.工艺要求" size="mini" style="margin: 0;width: 100%" @change="updateProcess(scope.row)"/>
</template>
</el-table-column>
<el-table-column width="200px" label="备注" align="center" prop="" show-overflow-tooltip>
<template slot-scope="scope">
<el-input v-model="scope.row.备注" size="mini" style="margin: 0;width: 100%" @change="updateProcess(scope.row)"/>
</template>
</el-table-column>
<el-table-column label="操作" align="center" width="200px" fixed="right">
<template slot-scope="scope">
<el-tooltip :open-delay="700" effect="dark" content="下移工序" placement="top">
<el-button type="text" icon="el-icon-bottom" size="mini" style="margin-right: 5px" @click="downOne(scope.row)"/>
</el-tooltip>
<el-tooltip :open-delay="700" effect="dark" content="上移工序" placement="top">
<el-button type="text" icon="el-icon-top" size="mini" style="margin-right: 5px" @click="upOne(scope.row)"/>
</el-tooltip>
<el-tooltip :open-delay="700" effect="dark" content="插入工序" placement="top">
<el-button type="text" icon="el-icon-plus" size="mini" style="margin-right: 5px" @click="insertOne(scope.row)"/>
</el-tooltip>
<el-tooltip :open-delay="700" effect="dark" content="删除工序" placement="top">
<el-button type="text" icon="el-icon-minus" size="mini" style="margin-right: 5px" @click="deleteOne(scope.row)"/>
</el-tooltip>
<!-- <el-tooltip :open-delay="700" effect="dark" content="上传工艺指导" placement="top">
<el-button :disabled="!scope.row.工艺名称" type="text" icon="el-icon-upload2" size="mini" style="margin-right: 5px" @click="ProcessTool(scope.row)"/>
</el-tooltip> -->
</template>
</el-table-column>
</el-table>
</div>
</el-col>
</div>
<el-dialog :visible.sync="dialogFormVisible" title="工艺拷贝" center style="min-height: 300px;" width="1100px">
<el-row style="margin-bottom: 10px">
<template>
<el-checkbox v-model="processprodutc" @change = 'copyData'>生产工艺</el-checkbox>
</template>
<el-select v-if ="processprodutc" v-model="partNameValue2" style="width:400px;margin-left: 10px" placeholder="生产工艺物料名称" size="small" filterable clearable clea @change="searchTable3" >
<el-option
v-for="item in tableData7"
:key="item.AID"
:label="item.物料编号"
:value="item.物料编号">
</el-option>
</el-select>
<el-select v-else v-model="partNameValue2" style="width:400px;margin-left: 10px" placeholder="物料名称" size="small" filterable clearable @change="searchTable2" >
<el-option
v-for="item in tableData7"
:key="item.id"
:label="item.零件图号"
:value="item.零件图号">
</el-option>
</el-select>
</el-row>
<el-table :data="tableData6" :header-cell-style="{background: '#383E4B',color: 'white'}" size="mini" style="width: 100%;margin-top:15px" height="500px" border highlight-current-row>
<el-table-column label="序号" align="center" prop="工艺顺序" show-overflow-tooltip>
</el-table-column>
<el-table-column label="工序名称" align="center" prop="工艺名称" show-overflow-tooltip>
</el-table-column>
<el-table-column label="工序说明" align="center" prop="工艺要求" show-overflow-tooltip>
</el-table-column>
<el-table-column label="准备工时" align="center" prop="准备工时" show-overflow-tooltip>
</el-table-column>
<el-table-column label="标准工时" align="center" prop="标准工时" show-overflow-tooltip>
</el-table-column>
<el-table-column label="工时合计" align="center" prop="工时合计" show-overflow-tooltip>
</el-table-column>
<el-table-column label="工装量具" align="center" width="150px">
<template slot-scope="scope">
<el-select v-model="scope.row.工卡量具" disabled multiple placeholder="工装量具" size="small" filterable clearable >
<el-option
v-for="item in basedatagj"
:key="item.id"
:label="item.name"
:value="Number(item.id)">
</el-option>
</el-select>
</template>
</el-table-column>
<el-table-column label="指定机床" align="center" width="150px" >
<template slot-scope="scope">
<el-select v-model="scope.row.指定机床" disabled multiple placeholder="指定机床" size="small" filterable clearable >
<el-option
v-for="item in basedatajc"
:key="item.id"
:label="item.name"
:value="Number(item.id)">
</el-option>
</el-select>
</template>
</el-table-column>
<el-table-column label="车间" align="center" prop="车间" width="150px">
<template slot-scope="scope">
<el-select v-model="scope.row.车间" placeholder="车间" size="small" disabled filterable clearable >
<el-option
v-for="item in basedatacj"
:key="item.id"
:label="item.name"
:value="item.name">
</el-option>
</el-select>
</template>
</el-table-column>
<el-table-column width="200px" label="备注" align="center" prop="备注" >
</el-table-column>
</el-table>
<div slot="footer" class="dialog-footer">
<el-button size="small" style="margin-left: 10px;padding: 8px 15px;" @click="dialogFormVisible=false">取消</el-button>
<el-button type="primary" size="small" style="margin-left: 10px;padding: 8px 15px;" @click="submitCopy">确定</el-button>
</div>
</el-dialog>
</el-row>
</el-card>
</div>
</template>
<script>
import { mapGetters } from 'vuex'
import { MESDownFile } from '@/utils/request'
export default {
data() {
return {
processprodutc:false,
partTool: '',
state: 1,
form:{
物料编号:'',
},
productNameValue: '', // 产品部件名称
productName: [], // 产品部件名称数组
partNameValue: '', // 零件名称
partNameLabel: '', // 零件名称
partName: [], // 零件名称数组
partNameValue1: '', // 零件名称
productValue1: '',
partName1: [], // 零件名称数组
partName2: [], // 零件名称数组
partNameValue2: '', // copy零件名称
partNameLabel2: '',
partNameValue3:'',// 零件名称
partNameValue4:'',// 计划数
dateRange: '', // 提交日期
dialogVisible: false,
dialogVisible1: false,
dialogFormVisible: false,
disabled: true,
checked: false,
hadFile: [],
fileList: [],
hadFile1: [],
processValue: '',
dialogName: true,
showFileList: false,
action: '',
product1: [], // 产品名称数组
loading: false, // 数据加载
total: 0, // 分页总数
tableData4: [], // 工艺列表
tableData3: [], // 零件列表
filteredTableData4: [], // 过滤后的工艺列表
processSearchName: '', // 工序搜索框内容
tableData5: [], // 工艺内容
tableData6: [],
tableData7: [],// 有工艺的物料组
pageCurrent: 1, // 分页当前页
pageSize: 100, // 分页每页显示条数
orderName: '', // 排序列名
order: '', // 排序方式
materialarr:[],
basedata:[],
basedatagj:[],
basedatajc:[],
basedatacj:[],
basedatavalue1:'',
basedatavalue2:'',
basedatavalue3:'',
downPDF:MESDownFile,
insertidx:0,
processStatus:0,
itemdata:[]
}
},
computed: {
...mapGetters([
'id',
'token'
])
},
watch: {
partNameValue(val) {
if (val) {
this.disabled = false
} else {
this.disabled = true
}
}
},
created() {
this.searchTable()
this.getProcess()
this.getbasedata()
},
methods: {
getitemdata(item){
var param = []
this.itemdata = []
param.push(["物料编号",item])
var Data = this.CreateData('11', '工艺管理_获取物料原料信息',param)
this.ExecDatabase(Data).then(response => {
response.data.forEach(element => {
if(element.ItmsGrpNam == '103.自制件-机加件'){
this.itemdata.push({
'子件名称':element.子件名称,
'子件数量':element.子件数量
})
}
console.log(response.data)
console.log(this.itemdata)
})
})
},
getbasedata(){
var Data = this.CreateData('11', '设备管理_设备信息_查询')
this.ExecDatabase(Data).then(response => {
response.data.forEach(element => {
if(element.设备类型名称 == '量具'){
this.basedatagj.push({
name:element.设备名称,
id:element.设备流水号
})
}
if(element.设备类型名称 == '机床'){
this.basedatajc.push({
name:element.设备名称,
id:element.设备流水号
})
}
if(element.设备类型名称 == '车间'){
this.basedatacj.push({
name:element.设备名称,
id:element.设备流水号
})
}
});
this.basedata = response.data
this.loading = false
console.log(this.basedatajc)
})
},
searchTable(query='') {
this.loading = true
var param = []
param.push(["过滤",query])
var Data = this.CreateData('11', '工艺管理_生产计划物料查询', param)
this.ExecDatabase(Data).then(response => {
this.tableData3 = response.data
this.loading = false
console.log(this.tableData3)
})
},
copyData() {
if(!this.partNameValue3){
this.$message.error('请先选择物料')
return
}
this.dialogFormVisible = true
this.loading = true
this.partNameValue2 = ''
if(this.processprodutc){
var Data = this.CreateData('11', '工艺管理_生产工艺_生产工艺拷贝')
this.ExecDatabase(Data).then(response => {
this.tableData7 = response.data
this.loading = false
console.log(this.tableData7)
})
}else{
var Data = this.CreateData('11', '工艺管理_生产工艺_标准工艺拷贝')
this.ExecDatabase(Data).then(response => {
this.tableData7 = response.data
this.loading = false
console.log(this.tableData7)
})
}
},
// ordernum(val){
// this.partNameValue3 = ''
// this.materialarr = []
// this.form = []
// this.tableData3.forEach(item => {
// console.log(item.订单编号,val)
// if (item.订单编号 == val){
// this.materialarr.push(item)
// this.form = {
// 物料编号:item.物料编号,
// 工序状态:'',
// 下达时间:item.下达日期,
// 要求完成时间:item.计划完成,
// 零件材质:'',
// 成活尺寸:'',
// 数量:item.计划数量,
// 备注:item.备注,
// }
// }
// });
// console.log(this.form)
// },
searchTable1(val) {
// this.materialarr.forEach(item => {
// if (item.物料编号 == val){
// this.partNameValue4 = item.计划数量
// }
// });
this.loading = true
var param = []
param[0] = ['物料编号',this.partNameValue3]
this.getitemdata(this.partNameValue3)
var Data = this.CreateData('11', 'MES_ProcessManagement_ProcessBindGet', param)
this.ExecDatabase(Data).then(response => {
// if(response.data[0].length>0){
// this.getPartProcess(response.data)
this.loading = false
this.tableData5 = response.data
this.processStatus = 0
this.fninsertidx()
console.log(response.data)
// }
})
},
searchTable2() {
this.loading = true
var param = []
param[0] = ['物料编号',this.partNameValue2]
var Data = this.CreateData('11', 'MES_ProcessManagement_ProcessBindGet', param)
this.ExecDatabase(Data).then(response => {
// if(response.data[0].length>0){
// this.getPartProcess(response.data)
this.loading = false
this.tableData6 = response.data
this.datadoing()
})
},
searchTable3() {
this.loading = true
var param = []
param[0] = ['物料编号',this.partNameValue2]
var Data = this.CreateData('11', '工艺管理_制定标准工艺_拷贝生产工艺', param)
this.ExecDatabase(Data).then(response => {
// if(response.data[0].length>0){
// this.getPartProcess(response.data)
this.loading = false
this.tableData6 = response.data
this.datadoing()
})
},
datadoing(){
this.tableData6.forEach(item => {
if(item.工卡量具){
item.工卡量具 = item.工卡量具.split(",").map(Number)
console.log(item.工卡量具)
}
if(item.指定机床){
item.指定机床 = item.指定机床.split(",").map(Number)
}
});
},
// getPartProcess(Processid) {
// var param = []
// var Processids = ''
// Processid.forEach(item => {
// if(item.工艺编号){
// Processids = Processids + item.工艺编号 +","
// }
// })
// console.log(Processids)
// param[0] = ['工艺编号',Processids]
// var Data = this.CreateData('11', 'MES_ProcessManagement_ProcessGet', param)
// this.ExecDatabase(Data).then(response => {
// const result1 = this.tableData5.map(item1 => {
// const matchedItem = response.data.find(item2 => item2.工艺编号 === item1.工艺编号);
// if(matchedItem){
// return {
// ...item1,
// 工艺名称: matchedItem.工艺名称
// };
// }else{
// return {
// ...item1,
// 工艺名称: ""
// };
// }
// });
// this.tableData5 = result1
// this.loading = false
// })
// },
getProcess() {
var param = []
// 参数数量与名称要与存储过程对应
param[0] = ['工艺编号','']
var Data = this.CreateData('11', 'MES_ProcessManagement_ProcessGet', param)
this.ExecDatabase(Data).then(response => {
this.tableData4 = response.data
this.filteredTableData4 = response.data
})
},
// 过滤工序
filterProcess() {
if (this.processSearchName) {
this.filteredTableData4 = this.tableData4.filter(item => {
return item.工艺名称.includes(this.processSearchName)
})
} else {
this.filteredTableData4 = this.tableData4
}
},
submitCopy() {
if (this.partNameValue2 == '') {
this.$message.warning('请先选择零件')
return
}
var processtype = 0
if(this.processprodutc){
processtype = 1
}
var param1 = []
param1[0] = ['物料编号', this.partNameValue3]
param1[1] = ['零件图号', this.partNameValue2]
param1[2] = ['工艺类型', processtype]
// 参数数量与名称要与存储过程对应
var Data1 = this.CreateData('12', '工艺管理_制定标准工艺_拷贝工艺保存', param1)
this.ExecDatabase(Data1).then(response => {
if (response.data[0].result === '1') {
this.$message.success('拷贝成功')
this.searchTable1()
this.dialogFormVisible = false
} else {
this.$message.error('拷贝失败')
}
})
},
getNum() {
var param = []
if(!this.partNameValue3){
this.$message.error('请先选择物料')
}
param[0] = ['物料编号',this.partNameValue3]
var Data = this.CreateData('11', '工艺管理_图纸维护_查看图纸', param)
this.ExecDatabase(Data).then(response => {
console.log(response)
if (response.data.length > 0) {
var pdfSrc =""+this.downPDF+""+ response.data[0].uid+".pdf"
console.log(this.downPDF)
console.log(response.data[0].uid)
console.log(pdfSrc)
window.open(pdfSrc,'_blank')
}else{
this.$message.error('未上传图纸')
}
})
},
fninsertidx(){
this.tableData5.forEach(item => {
if(!item.工艺名称){
this.insertidx = item.id
}
if(item.工卡量具){
item.工卡量具 = item.工卡量具.split(",").map(Number)
console.log(item.工卡量具)
}
if(item.指定机床){
item.指定机床 = item.指定机床.split(",").map(Number)
}
});
},
editProcedure(row) {
if(!this.partNameValue3){
this.$message.error('请先选择物料')
return
}
console.log(this.insertidx)
if(this.insertidx){
var param1 = []
param1[0] = ['工艺编号', row.工艺编号]
param1[1] = ['idd', this.insertidx]
param1[2] = ['物料编号', this.partNameValue3]
this.updateProcess2(param1)
}else{
var param1 = []
param1[0] = ['工艺编号', row.工艺编号]
param1[1] = ['物料编号', this.partNameValue3]
// param1[2] = ['计划数量', this.partNameValue4]
// 参数数量与名称要与存储过程对应
var Data1 = this.CreateData('11', '车间生产管理工艺_零件工序_修改数据_工艺库', param1)
this.ExecDatabase(Data1).then(response => {
var param = []
param[0] = ['物料编号', this.partNameValue3]
var Data = this.CreateData('11', '车间生产管理工艺_零件工序_查询工序信息_工艺库', param)
this.ExecDatabase(Data).then(response => {
this.tableData5 = response.data
this.fninsertidx()
this.processStatus = 0
})
})
}
},
updateProcess(row) {
var param1 = []
const 工卡量具 = Object.values(row.工卡量具);
const 指定机床 = Object.values(row.指定机床);
console.log(工卡量具)
param1[0] = ['idd', row.id]
param1[1] = ['工艺要求', row.工艺要求]
param1[2] = ['准备工时', row.准备工时]
param1[3] = ['标准工时', row.标准工时]
param1[4] = ['工时合计', row.工时合计]
param1[5] = ['工卡量具', 工卡量具]
param1[6] = ['指定机床', 指定机床]
param1[7] = ['车间', row.车间]
param1[8] = ['备注', row.备注]
console.log(param1[5])
var Data1 = this.CreateData('11', '车间生产管理工艺_零件工序_编辑_工艺库', param1)
this.ExecDatabase(Data1).then(response => {
})
},
updateProcess2(row) {
console.log(row)
var Data1 = this.CreateData('11', '车间生产管理工艺_零件工序_编辑插入行', row)
this.ExecDatabase(Data1).then(response => {
var param1 = []
param1[0] = ['物料编号', this.partNameValue3]
// 参数数量与名称要与存储过程对应
var Data1 = this.CreateData('11', '车间生产管理工艺_零件工序_查询工序信息_工艺库', param1)
this.ExecDatabase(Data1).then(response => {
this.tableData5 = response.data
this.fninsertidx()
this.insertidx = 0
this.processStatus = 0
})
})
},
deleteOne(row) { // 删除行
var param1 = []
param1[0] = ['物料编号', this.partNameValue3]
param1[1] = ['idd', row.id]
// 参数数量与名称要与存储过程对应
var Data1 = this.CreateData('11', '车间生产管理工艺_零件工序_删除工序_工艺库', param1)
this.ExecDatabase(Data1).then(response => {
var param1 = []
param1[0] = ['物料编号', this.partNameValue3]
// 参数数量与名称要与存储过程对应
var Data1 = this.CreateData('11', '车间生产管理工艺_零件工序_查询工序信息_工艺库', param1)
this.ExecDatabase(Data1).then(response => {
this.tableData5 = response.data
this.fninsertidx()
this.processStatus = 0
})
})
},
upOne(row) { // 上移
var param1 = []
param1[0] = ['物料编号', this.partNameValue3]
param1[1] = ['idd', row.id]
// 参数数量与名称要与存储过程对应
var Data1 = this.CreateData('11', '车间生产管理工艺_零件工序_上移工序_工艺库', param1)
this.ExecDatabase(Data1).then(response => {
var param1 = []
param1[0] = ['物料编号', this.partNameValue3]
// 参数数量与名称要与存储过程对应
var Data1 = this.CreateData('11', '车间生产管理工艺_零件工序_查询工序信息_工艺库', param1)
this.ExecDatabase(Data1).then(response => {
this.tableData5 = response.data
this.fninsertidx()
this.processStatus = 0
})
})
},
downOne(row) { // 下移
var param1 = []
param1[0] = ['物料编号', this.partNameValue3]
param1[1] = ['idd', row.id]
// 参数数量与名称要与存储过程对应
var Data1 = this.CreateData('11', '车间生产管理工艺_零件工序_下移工序_工艺库', param1)
this.ExecDatabase(Data1).then(response => {
var param1 = []
param1[0] = ['物料编号', this.partNameValue3]
// 参数数量与名称要与存储过程对应
var Data1 = this.CreateData('11', '车间生产管理工艺_零件工序_查询工序信息_工艺库', param1)
this.ExecDatabase(Data1).then(response => {
this.tableData5 = response.data
this.fninsertidx()
this.processStatus = 0
})
})
},
insertOne(row) { // 插入行
console.log(row)
var param1 = []
param1[0] = ['零件图号', this.partNameValue3]
param1[1] = ['idd', row.id]
var Data1 = this.CreateData('11', '车间生产管理工艺_零件工序_插入工序_工艺库', param1)
this.ExecDatabase(Data1).then(response => {
this.insertidx = response.data.Column1
var param3 = []
param3[0] = ['物料编号', this.partNameValue3]
// 参数数量与名称要与存储过程对应
var Data3 = this.CreateData('11', '车间生产管理工艺_零件工序_查询工序信息_工艺库', param3)
this.ExecDatabase(Data3).then(response => {
this.tableData5 = response.data
this.fninsertidx()
this.processStatus = 0
})
})
},
saveProcess(){
if(!this.partNameValue3){
this.$message.error('请先选择物料')
return
}
var param1 = []
param1[0] = ['物料编号', this.partNameValue3]
var Data1 = this.CreateData('11', '车间生产管理工艺_零件工序_启用', param1)
this.ExecDatabase(Data1).then(response => {
var param3 = []
param3[0] = ['物料编号', this.partNameValue3]
// 参数数量与名称要与存储过程对应
// var Data3 = this.CreateData('11', '车间生产管理工艺_零件工序_查询工序信息_工艺库', param3)
// this.ExecDatabase(Data3).then(response => {
// this.tableData5 = response.data
// this.fninsertidx()
// this.processStatus = 0
// })
})
}
}
}
</script>
<style scoped>
.topplanbox{
display: flex;
justify-content: left;
flex-wrap: wrap;
align-items: center;
}
.topplanbox .el-form-item{
display: inline-block;
width: 26%;
}
.el-form--label-left >>> .el-form-item__label {
text-align: right;
}
.el-button{
width: auto;
padding: 0px;
}
.el-col {
border-radius: 4px;
}
.bg-purple-dark {
background: #99a9bf;
}
.bg-purple {
background: #d3dce6;
}
.bg-purple-light {
background: #e5e9f2;
}
.grid-content {
border-radius: 4px;
min-height: 36px;
}
.row-bg {
padding: 10px 0;
background-color: #f9fafc;
}
/* >>>.el-dialog--center .el-dialog__body {
text-align: initial;
padding: 20px 30px 20px
}
>>>.el-dialog__header {
padding: 20px 20px 0px;
}
>>>.el-dialog__footer {
padding: 0px 20px 20px;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
>>>.el-form-item {
margin-bottom: 13px;
} */
.wrapper{
width: 90%;
height: 50px;
overflow: hidden;
border: 1px solid #b8c7d9;
/*float: left;*/
margin: 10px;
}
.content{
position: relative;
padding: 8px 8px 0 8px;
}
.action{
position: absolute;
top: 2px;
right: 8px;
}
.delete{
padding: 0 5px;
border-radius: 3px;
color: #0f84b0;
font-size: 12px;
}
.delete:hover{
background: -webkit-linear-gradient(top,#0ba9e3,#0099d3);
color: #fff;
}
a{
text-decoration: none;
}
.icon{
width: 30px;
height: 30px;
display: inline-block;
margin-right: 7px;
margin-top: 2px;
font-size: 26px;
}
.info{
width: 160px;
height: 50px;
position: absolute;
left: 44px;
line-height: 30px;
display: inline-block;
color: #999;
}
::v-deep .el-table__body-wrapper,::v-deep .el-table__footer-wrapper,::v-deep .el-table__header-wrapper {
width: 90%;
}
</style>

View File

@@ -0,0 +1,593 @@
<template>
<div>
<el-card>
<div class="search-container">
<span class="show-text">生产订单:</span>
<el-input v-model="orderNo" placeholder="请输入生产订单" clearable style="width: 150px;margin-right: 10px" />
<span class="show-text">销售订单:</span>
<el-input v-model="contractNo" placeholder="请输入销售订单" clearable style="width: 150px;margin-right: 10px" />
<span class="show-text">物料编码:</span>
<el-input v-model="productCode" placeholder="请输入物料编码" clearable style="width: 150px;margin-right: 10px" />
<span class="show-text">物料名称:</span>
<el-input v-model="productName" placeholder="请输入物料名称" clearable style="width: 150px;margin-right: 10px" />
<br>
<br>
<span class="show-text">任务状态:</span>
<el-select v-model="taskstatus" placeholder="请选择">
<el-option
key='0'
label="全部"
value="0">
</el-option>
<el-option
key='1'
label="未下发"
value="1">
</el-option>
<el-option
key='2'
label="已下发"
value="2">
</el-option>
</el-select>
<span class="show-text">属性:</span>
<el-select v-model="orderstatus" placeholder="请选择">
<el-option
key='0'
label="全部"
value="0">
</el-option>
<el-option
key='1'
label="机加件"
value="1">
</el-option>
<el-option
key='2'
label="装配件"
value="2">
</el-option>
</el-select>
<span class="show-text">要求完工日期:</span>
<el-date-picker
v-model="completionTime"
:clearable="false"
end-placeholder="结束时间"
format="yyyy-MM-dd"
popper-class="virtual-cell-time-picker"
range-separator="-"
start-placeholder="开始时间"
style="width: 280px;vertical-align: top"
type="datetimerange"
value-format="yyyy-MM-dd" />
<el-button :disabled="loading" icon="el-icon-search" plain type="primary" @click="searchTable()">查询</el-button>
<el-button type="warning" size="mini" style="width: 120px;" @click="AllworkTask">批量生成任务</el-button>
</div>
<el-table
v-loading="loading"
:data="tableData"
:height="'75vh'"
border
element-loading-background="rgba(0, 0, 0, 0.2)"
element-loading-spinner="el-icon-loading"
highlight-current-row
size="mini"
style="margin-top: 20px;"
tooltip-effect="dark"
ref="multipleTable"
@row-click="handleRowClick"
@selection-change="handleSelectionChange"
>
<el-table-column align="center" type="selection" width="50" fixed />
<el-table-column align="center" label="序号" type="index" width="50" />
<el-table-column align="center" prop="合同号" label="销售订单" width="70" />
<el-table-column align="center" prop="订单编号" label="生产订单" width="90" />
<el-table-column align="center" prop="物料编号" label="物料编码" width="220" />
<el-table-column align="center" prop="物料描述" label="物料名称" width="190" />
<el-table-column align="center" prop="自制件属性" label="属性" width="100" />
<el-table-column align="center" prop="计划数量" label="计划数" width="70" />
<el-table-column align="center" label="下达日期" width="170">
<template slot-scope="scope">
{{ scope.row.下达日期 }}
</template>
</el-table-column>
<el-table-column align="center" label="计划开始" width="170">
<template slot-scope="scope">
{{ scope.row.计划开始 }}
</template>
</el-table-column>
<el-table-column align="center" label="计划完成" width="170">
<template slot-scope="scope">
{{ scope.row.计划完成 }}
</template>
</el-table-column>
<el-table-column align="center" label="加急状态" width="80">
<template slot-scope="scope">
<div class="status-light" :class="scope.row.加急状态 == 1 ? 'status-light-green' : 'status-light-gray'" />
</template>
</el-table-column>
<el-table-column align="center" label="标准工艺" width="80">
<template slot-scope="scope">
<div class="status-light" :class="scope.row.标准工艺 == 1 ? 'status-light-green' : 'status-light-gray'" />
</template>
</el-table-column>
<el-table-column align="center" label="生产工艺" width="80">
<template slot-scope="scope">
<div class="status-light" :class="scope.row.生产工艺 == 1 ? 'status-light-green' : 'status-light-gray'" />
</template>
</el-table-column>
<el-table-column align="center" label="操作" width="220">
<template slot-scope="scope">
<el-button type="text" size="mini" @click="editProcess(scope.row)">查看生产工艺</el-button>
<el-button type="text" size="mini" @click="ViewProcess(scope.row)">查看标准工艺</el-button>
</template>
</el-table-column>
</el-table>
<el-dialog :visible.sync="dialogcasual" title="生产工艺详情" center style="min-height: 300px;" width="1300px" border>
<el-card style="height: 550px">
<el-row>
<div style="display: flex; height: 550px;">
<el-col >
<div style="margin-top: 10px">
<el-table v-loading="loading" :data="tableData5" :header-cell-style="{background: '#19466E',color: 'white'}" style="margin-top: 10px;width:100%" height="600">
<el-table-column width="50px" label="序号" align="center" prop="工艺顺序" show-overflow-tooltip/>
<el-table-column width="130px" label="工序名称" align="center" prop="工艺名称" show-overflow-tooltip/>
<el-table-column width="330px" label="工序说明" align="center" prop="工艺要求" show-overflow-tooltip/>
<el-table-column label="准备工时" align="center" prop="准备工时" show-overflow-tooltip/>
<el-table-column label="标准工时" align="center" prop="标准工时" show-overflow-tooltip/>
<el-table-column label="工时合计" align="center" prop="工时合计" show-overflow-tooltip/>
<el-table-column label="工装量具" align="center" width="150px">
<template slot-scope="scope">
<el-select v-model="scope.row.工卡量具" multiple placeholder="工装量具" size="small" disabled filterable clearable >
<el-option
v-for="item in basedatagj"
:key="item.id"
:label="item.name"
:value="item.id">
</el-option>
</el-select>
</template>
</el-table-column>
<el-table-column label="指定机床" align="center" width="150px" >
<template slot-scope="scope">
<el-select v-model="scope.row.指定机床" multiple placeholder="指定机床" size="small" disabled filterable clearable >
<el-option
v-for="item in basedatajc"
:key="item.id"
:label="item.name"
:value="item.id">
</el-option>
</el-select>
</template>
</el-table-column>
<el-table-column label="车间" align="center" width="150px">
<template slot-scope="scope">
<el-select v-model="scope.row.车间" placeholder="车间" size="small" disabled filterable clearable >
<el-option
v-for="item in basedatacj"
:key="item.id"
:label="item.name"
:value="item.name">
</el-option>
</el-select>
</template>
</el-table-column>
<el-table-column label="备注" align="center" prop="备注" width="200px"/>
</el-table>
</div>
</el-col>
</div>
</el-row>
</el-card>
</el-dialog>
<el-dialog :visible.sync="dialogprocess" title="标准工艺详情" center style="min-height: 300px;" width="1300px" border>
<el-card style="height: 550px">
<el-row>
<div style="display: flex; height: 550px;">
<el-col >
<div style="margin-top: 10px">
<el-table v-loading="loading" :data="tableData6" :header-cell-style="{background: '#19466E',color: 'white'}" style="margin-top: 10px;width:100%" height="600">
<el-table-column width="50px" label="序号" align="center" prop="工艺顺序" show-overflow-tooltip/>
<el-table-column width="130px" label="工序名称" align="center" prop="工艺名称" show-overflow-tooltip/>
<el-table-column width="330px" label="工序说明" align="center" prop="工艺要求" show-overflow-tooltip/>
<el-table-column label="准备工时" align="center" prop="准备工时" show-overflow-tooltip/>
<el-table-column label="标准工时" align="center" prop="标准工时" show-overflow-tooltip/>
<el-table-column label="工时合计" align="center" prop="工时合计" show-overflow-tooltip/>
<el-table-column label="工装量具" align="center" width="150px">
<template slot-scope="scope">
<el-select v-model="scope.row.工卡量具" multiple placeholder="工装量具" size="small" disabled filterable clearable >
<el-option
v-for="item in basedatagj"
:key="item.id"
:label="item.name"
:value="item.id">
</el-option>
</el-select>
</template>
</el-table-column>
<el-table-column label="指定机床" align="center" width="150px" >
<template slot-scope="scope">
<el-select v-model="scope.row.指定机床" multiple placeholder="指定机床" size="small" disabled filterable clearable >
<el-option
v-for="item in basedatajc"
:key="item.id"
:label="item.name"
:value="item.id">
</el-option>
</el-select>
</template>
</el-table-column>
<el-table-column label="车间" align="center" width="150px">
<template slot-scope="scope">
<el-select v-model="scope.row.车间" placeholder="车间" size="small" disabled filterable clearable >
<el-option
v-for="item in basedatacj"
:key="item.id"
:label="item.name"
:value="item.name">
</el-option>
</el-select>
</template>
</el-table-column>
<el-table-column label="备注" align="center" prop="备注" width="200px"/>
</el-table>
</div>
</el-col>
</div>
</el-row>
</el-card>
</el-dialog>
</el-card>
</div>
</template>
<script>
import { mapGetters } from 'vuex'
export default {
data() {
return {
partTool: '',
state: 1,
form:{
物料编号:'',
},
productNameValue: '', // 产品部件名称
productName: [], // 产品部件名称数组
partNameValue: '', // 零件名称
partNameLabel: '', // 零件名称
partName: [], // 零件名称数组
partNameValue1: '', // 零件名称
productValue1: '',
partName1: [], // 零件名称数组
partName2: [], // 零件名称数组
partNameValue2: '', // copy零件名称
partNameLabel2: '',
partNameValue3:'',// 零件名称
partNameValue4:'',// 计划数
dateRange: '', // 提交日期
dialogVisible: false,
dialogVisible1: false,
dialogFormVisible: false,
disabled: true,
checked: false,
hadFile: [],
fileList: [],
hadFile1: [],
processValue: '',
dialogName: true,
showFileList: false,
action: '',
product1: [], // 产品名称数组
loading: false, // 数据加载
total: 0, // 分页总数
tableData4: [], // 工艺列表
tableData3: [], // 零件列表
filteredTableData4: [], // 过滤后的工艺列表
processSearchName: '', // 工序搜索框内容
tableData5: [], // 工艺内容
tableData6: [],
pageCurrent: 1, // 分页当前页
pageSize: 100, // 分页每页显示条数
orderName: '', // 排序列名
order: '', // 排序方式
materialarr:[],
basedata:[],
basedatagj:[],
basedatajc:[],
basedatacj:[],
basedatavalue1:'',
basedatavalue2:'',
basedatavalue3:'',
dialogcasual:false,
dialogprocess:false,
orderNo: '',
contractNo: '',
productCode: '',
productName: '',
processName: '',
nature: '',
productionStatus: '未完成',
Doing:"",
Doingoptions:[],
completionTime: [],
loading: false,
tableData: [],
multipleSelection: [],
dialogVisible: false,
submitLoading: false,
currentRow: {},
stationOptions: [],
selectedRow: {},
editnumber:0,
submitstatus:0,
remarkDialogVisible: false,
remarkSubmitLoading: false,
tableData6:[],
taskstatus:'1',
orderstatus:'1'
}
},
computed: {
...mapGetters([
'id',
'token'
])
},
watch: {
partNameValue(val) {
if (val) {
this.disabled = false
} else {
this.disabled = true
}
}
},
created() {
this.searchTable()
this.getbasedata()
},
methods: {
getbasedata(){
var Data = this.CreateData('11', '设备管理_设备信息_查询')
this.ExecDatabase(Data).then(response => {
this.basedatagj = []
this.basedatajc = []
this.basedatacj = []
response.data.forEach(element => {
if(element.设备类型名称 == '量具'){
this.basedatagj.push({
name:element.设备名称,
id:element.设备流水号
})
}
if(element.设备类型名称 == '机床'){
this.basedatajc.push({
name:element.设备名称,
id:element.设备流水号
})
}
if(element.设备类型名称 == '车间'){
this.basedatacj.push({
name:element.设备名称,
id:element.设备流水号
})
}
});
this.basedata = response.data
this.loading = false
console.log(this.basedatagj)
})
},
editProcess(row){
this.dialogcasual = true
this.loading = true
this.editProcesssearch(row)
},
ViewProcess(row){
this.dialogprocess = true
this.loading = true
this.Processsearch(row)
},
editProcesssearch(row){
var param = []
param[0] = ['物料编号',row.物料编号]
param[1] = ['订单编号',row.订单编号]
var Data = this.CreateData('11', '工艺管理_生产工艺_查询生产工艺', param)
this.ExecDatabase(Data).then(response => {
this.loading = false
this.tableData5 = response.data
this.fninsertidx()
})
},
fninsertidx(){
this.tableData6.forEach(item => {
if(!item.工艺名称){
this.insertidx = item.id
}
if(item.工卡量具){
item.工卡量具 = item.工卡量具.split(",").map(Number)
}
if(item.指定机床){
item.指定机床 = item.指定机床.split(",").map(Number)
}
});
this.tableData5.forEach(item => {
if(!item.工艺名称){
this.insertidx = item.id
}
if(item.工卡量具){
item.工卡量具 = item.工卡量具.split(",").map(Number)
}
if(item.指定机床){
item.指定机床 = item.指定机床.split(",").map(Number)
}
});
},
Processsearch(row){
var param = []
param[0] = ['物料编号',row.物料编号]
var Data = this.CreateData('11', '工艺管理_生产工艺_查询标准工艺', param)
this.ExecDatabase(Data).then(response => {
this.loading = false
this.tableData6 = response.data
this.fninsertidx()
})
},
formatDate(date) {
if (!date) return ''
return date.split(' ').length > 1 ? date.split(' ')[0] : date
},
searchTable() {
this.loading = true
this.tableData = []
var param = []
param.push(['订单号', this.orderNo || 0])
param.push(['合同号', this.contractNo])
param.push(['产品编码', this.productCode])
param.push(['产品名称', this.productName])
param.push(['要求完工日期1', this.completionTime[0]])
param.push(['要求完工日期2', this.completionTime[1]])
param.push(['订单状态',this.orderstatus])
param.push(['任务状态',this.taskstatus])
var Data = this.CreateData('11', '工艺管理_工艺任务_订单查询', param)
this.ExecDatabase(Data).then(response => {
if(response.data.length>0){
this.loading = false
this.tableData = response.data
}
this.loading = false
}).catch(() => {
this.loading = false
})
},
handleSelectionChange(val) {
this.multipleSelection = val;
},
handleRowClick(row){
this.selectedRow = row
},
AllworkTask(){
console.log(this.multipleSelection)
const data = this.multipleSelection
const filtered = data.filter(item => item["任务状态"] == 2);
console.log(filtered);
if(filtered.length>0){
this.$message.error('请勾选未排产的数据')
return
}
if(this.multipleSelection.length>=1){
var multipleSelection = this.multipleSelection
var ordernums = []
var orderitems = []
multipleSelection.forEach(item => {
ordernums.push(item.订单编号)
});
ordernums = ordernums.join(',')
console.log(ordernums)
var param = []
param.push(['订单编号',ordernums])
console.log(param)
var Data = this.CreateData('12', '计划排产_生产订单_订单任务', param)
this.ExecDatabase(Data).then(response => {
this.searchTable()
this.$message.success('操作成功')
}).catch(() => {
this.$message.info('操作成功')
})
}else{
this.$message.error('请勾选数据')
}
},
// 过滤工序
filterProcess() {
if (this.processSearchName) {
this.filteredTableData4 = this.tableData4.filter(item => {
return item.工艺名称.includes(this.processSearchName)
})
} else {
this.filteredTableData4 = this.tableData4
}
},
}
}
</script>
<style scoped>
.status-light {
display: inline-block;
width: 12px;
height: 12px;
border-radius: 50%;
}
.status-light-green {
background-color: #67C23A;
}
.status-light-gray {
background-color: #909399;
}
::v-deep .el-input--suffix .el-input__inner{
padding-right: 0;
}
::v-deep .el-input__suffix{
display: none;
}
.show-text {
margin-right: 5px;
line-height: 32px;
}
.show-head {
margin-right: 5px;
line-height: 32px;
font-size: 15px;
}
.el-dialog__body {
padding: 20px;
}
.el-form-item {
margin-bottom: 15px;
}
.custom-tabs {
margin-top: 20px;
}
.schedule-container {
min-height: 67vh;
}
.schedule-container ::v-deep .fc-daygrid-day-frame {
padding: 2px;
min-height: auto;
}
.schedule-container ::v-deep .fc-event {
font-size: 12px;
padding: 1px 2px;
margin-bottom: 1px;
line-height: 1.4;
}
.schedule-container ::v-deep .fc-daygrid-event-harness {
margin-bottom: 1px;
}
.schedule-container ::v-deep .fc-daygrid-day-top {
padding: 2px;
}
.schedule-container ::v-deep .fc-daygrid-more-link {
font-size: 12px;
padding: 0 2px;
}
</style>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,383 @@
<template>
<div>
<el-card>
<div class="search-container">
<span class="show-text">生产订单:</span>
<el-input v-model="orderNo" placeholder="请输入生产订单" clearable style="width: 150px;margin-right: 10px" />
<span class="show-text">销售订单:</span>
<el-input v-model="contractNo" placeholder="请输入销售订单" clearable style="width: 150px;margin-right: 10px" />
<span class="show-text">产品编码:</span>
<el-input v-model="productCode" placeholder="请输入产品编码" clearable style="width: 150px;margin-right: 10px" />
<span class="show-text">产品名称:</span>
<el-input v-model="productName" placeholder="请输入产品名称" clearable style="width: 150px;margin-right: 10px" />
<span class="show-text">工序名称:</span>
<el-input v-model="processName" placeholder="请输入工序名称" clearable style="width: 150px;margin-right: 10px" />
<br>
<br>
<span class="show-text">性质:</span>
<el-input v-model="nature" placeholder="请输入性质" clearable style="width: 150px;margin-right: 10px" />
<span class="show-text">排产状态:</span>
<el-select v-model="productionStatus" clearable placeholder="请选择状态" style="width: 150px;margin-right: 10px">
<el-option label="全部" value="全部" />
<el-option label="已完成" value="已完成" />
<el-option label="未完成" value="未完成" />
</el-select>
<span class="show-text">要求完工日期:</span>
<el-date-picker v-model="completionTime" :clearable="false" end-placeholder="结束时间" format="yyyy-MM-dd"
range-separator="-" start-placeholder="开始时间" style="width: 280px;vertical-align: top" type="datetimerange"
value-format="yyyy-MM-dd" />
<el-button :disabled="loading" icon="el-icon-search" plain type="primary" @click="searchTable()">查询</el-button>
</div>
<el-table v-loading="loading" :data="tableData" :height="'67vh'" border
element-loading-background="rgba(0, 0, 0, 0.2)" element-loading-spinner="el-icon-loading" highlight-current-row
size="mini" style="width: 100%;margin-top: 20px;" tooltip-effect="dark" @row-click="handleRowClick">
<el-table-column align="center" label="序号" type="index" width="50" fixed />
<el-table-column align="center" prop="合同号" label="销售订单" width="120" fixed />
<el-table-column align="center" prop="订单号" label="生产订单" width="100" fixed />
<el-table-column align="center" prop="产品编码" label="产品编码" width="220" />
<el-table-column align="center" prop="产品名称" label="产品名称" width="190" />
<el-table-column align="center" prop="计划数量订单" label="计划数量" width="80" />
<el-table-column align="center" label="要求完工日" width="120">
<template slot-scope="scope">{{ formatDate(scope.row.要求完工日期) }}</template>
</el-table-column>
<el-table-column align="center" prop="当前序" label="当前序" width="80" />
<el-table-column align="center" label="排产" width="90">
<template slot-scope="scope">
<div class="status-light" :class="scope.row.排产状态 === 1 ? 'status-light-green' : 'status-light-gray'" />
</template>
</el-table-column>
<el-table-column align="center" label="开工" width="80">
<template slot-scope="scope">
<div class="status-light" :class="scope.row.开工时间 === 1 ? 'status-light-green' : 'status-light-gray'" />
</template>
</el-table-column>
<el-table-column align="center" label="终检" width="80">
<template slot-scope="scope">
<div class="status-light" :class="scope.row.序 === 1 ? 'status-light-green' : 'status-light-gray'" />
</template>
</el-table-column>
<el-table-column align="center" label="入库" width="80">
<template slot-scope="scope">
<div class="status-light" :class="scope.row.入库 === '是' ? 'status-light-green' : 'status-light-gray'" />
</template>
</el-table-column>
<el-table-column align="center" label="优先级" width="80">
<template slot-scope="scope">
<div class="status-light" :class="scope.row.优先级 === '是' ? 'status-light-green' : 'status-light-gray'" />
</template>
</el-table-column>
<el-table-column align="center" :label = "'工序1\n工序名称'" prop = "工序名称[0]" width="80"/>
<el-table-column align="center" :label = "'工序1\n指派对象'" prop = "指派对象[0]" width="80"/>
<el-table-column align="center" :label = "'工序1\n开始时间'" prop = "计划开始时间[0]" width="120"/>
<el-table-column align="center" :label = "'工序1\n结束时间'" prop = "计划完成时间[0]" width="120"/>
<el-table-column align="center" :label = "'工序1\n完成进度'" prop = "进度[0]" width="80"/>
<el-table-column align="center" :label = "'工序2\n工序名称'" prop = "工序名称[1]" width="80"/>
<el-table-column align="center" :label = "'工序2\n指派对象'" prop = "指派对象[1]" width="80"/>
<el-table-column align="center" :label = "'工序2\n开始时间'" prop = "计划开始时间[1]" width="120"/>
<el-table-column align="center" :label = "'工序2\n结束时间'" prop = "计划完成时间[1]" width="120"/>
<el-table-column align="center" :label = "'工序2\n完成进度'" prop = "进度[1]" width="80"/>
<el-table-column align="center" :label = "'工序3\n工序名称'" prop = "工序名称[2]" width="80"/>
<el-table-column align="center" :label = "'工序3\n指派对象'" prop = "指派对象[2]" width="80"/>
<el-table-column align="center" :label = "'工序3\n开始时间'" prop = "计划开始时间[2]" width="120"/>
<el-table-column align="center" :label = "'工序3\n结束时间'" prop = "计划完成时间[2]" width="120"/>
<el-table-column align="center" :label = "'工序3\n完成进度'" prop = "进度[2]" width="80"/>
<el-table-column align="center" :label = "'工序4\n工序名称'" prop = "工序名称[3]" width="80"/>
<el-table-column align="center" :label = "'工序4\n指派对象'" prop = "指派对象[3]" width="80"/>
<el-table-column align="center" :label = "'工序4\n开始时间'" prop = "计划开始时间[3]" width="120"/>
<el-table-column align="center" :label = "'工序4\n结束时间'" prop = "计划完成时间[3]" width="120"/>
<el-table-column align="center" :label = "'工序4\n完成进度'" prop = "进度[3]" width="80"/>
<el-table-column align="center" :label = "'工序5\n工序名称'" prop = "工序名称[4]" width="80"/>
<el-table-column align="center" :label = "'工序5\n指派对象'" prop = "指派对象[4]" width="80"/>
<el-table-column align="center" :label = "'工序5\n开始时间'" prop = "计划开始时间[4]" width="120"/>
<el-table-column align="center" :label = "'工序5\n结束时间'" prop = "计划完成时间[4]" width="120"/>
<el-table-column align="center" :label = "'工序5\n完成进度'" prop = "进度[4]" width="80"/>
</el-table>
</el-card>
</div>
</template>
<script>
export default {
data() {
return {
orderNo: '',
contractNo: '',
productCode: '',
productName: '',
processName: '',
nature: '',
productionStatus: '全部',
completionTime: [],
loading: false,
tableData: [],
selectedRow: null,
editDialogVisible: false,
editSubmitLoading: false,
currentRow: {},
editForm: {
优先级: '',
未完成说明: '',
派工特殊说明: ''
},
splitTaskDialogVisible: false,
splitTaskSubmitLoading: false,
stationOptions: [],
splitTaskForm: {
分配数量: 0,
指派对象: '',
指派对象编号: '',
派工特殊备注: '',
计划开始时间: '',
计划结束时间: '',
最晚开始时间: '',
任务概述: ''
}
}
},
created() {
var now = new Date()
var start = new Date(Date.UTC(now.getFullYear() - 2, now.getMonth(), now.getDate(), 0, 0, 0)).toISOString().replace('T', ' ').replace('.000Z', '')
var end = new Date(Date.UTC(now.getFullYear(), now.getMonth(), now.getDate(), 23, 59, 59)).toISOString().replace('T', ' ').replace('.000Z', '')
this.completionTime = [start, end]
this.searchTable()
},
methods: {
formatDate(date) {
if (!date) return ''
return date.split(' ').length > 1 ? date.split(' ')[0] : date
},
mergeOrderData(dataList) {
const orderMap = new Map();
const opMap = new Map();
dataList.forEach(item => {
const orderNumber = item.订单号;
if (!orderMap.has(orderNumber)) {
orderMap.set(orderNumber, {
...item,
// 需要累加的字段
指派数量: item.指派数量 || 0,
工序计划数量: item.工序计划数量 || 0,
计划数量: item.计划数量 || 0,
// 需要循环的字段
工序列表: [item.工序名称],
指派对象列表: [item.指派对象],
计划完成时间列表: [this.formatDate(item.计划完成时间)],
计划开始时间列表: [this.formatDate(item.计划开始时间)],
进度列表: [item.进度],
当前序:'',
开工时间:0,
序检:item.序检
});
} else {
// 合并到现有项
const existingItem = orderMap.get(orderNumber);
// 累加数值字段
existingItem.指派数量 += item.指派数量 || 0;
existingItem.工序计划数量 += item.工序计划数量 || 0;
existingItem.计划数量 += item.计划数量 || 0;
if (item.拆分内码 == 1) {
existingItem.工序列表.push(item.工序名称);
existingItem.指派对象列表.push(item.指派对象);
existingItem.计划完成时间列表.push(this.formatDate(item.计划完成时间));
existingItem.计划开始时间列表.push(this.formatDate(item.计划开始时间));
existingItem.进度列表.push(item.进度);
}
if(item.进度 < 100 & item.进度 > 0){
existingItem.当前序 = item.工序名称
}
if(new Date(item.开工时间) > new Date('1900-01-01 00:00:00')){
existingItem.开工时间 = 1
console.log(item.订单号)
}
}
});
this.tableData = Array.from(orderMap.values()).map(item => ({
// 基本信息
订单号: item.订单号,
合同号: item.合同号,
产品编码:item.产品编码,
产品名称:item.产品名称,
计划数量订单:item.计划数量订单,
要求完工日期:item.要求完工日期,
排产状态:item.排产状态,
优先级:item.优先级,
工序名称: item.工序列表,
指派对象: item.指派对象列表,
计划完成时间: item.计划完成时间列表,
计划开始时间: item.计划开始时间列表,
进度: item.进度列表,
当前序:item.当前序,
// 合并后的数值字段
指派数量: item.指派数量,
工序计划数量: item.工序计划数量,
计划数量: item.计划数量,
开工时间: item.开工时间,
序检:item.序检
}));
console.log(this.tableData)
console.log(dataList)
},
searchTable() {
this.loading = true
this.tableData = []
var param = []
param.push(['订单号', this.orderNo || 0])
param.push(['物料类型', '装配件'])
param.push(['合同号', this.contractNo])
param.push(['产品编码', this.productCode])
param.push(['产品名称', this.productName])
param.push(['工序名称', this.processName])
param.push(['性质', this.nature])
param.push(['要求完工日期1', this.completionTime ? this.completionTime[0] : ''])
param.push(['要求完工日期2', this.completionTime ? this.completionTime[1] : ''])
param.push(['排产状态', this.productionStatus])
var Data = this.CreateData('11', 'MES_OrderPlanned_Query', param)
this.ExecDatabase(Data).then(response => {
this.loading = false
if (response.data.length !== 0) {
this.mergeOrderData(response.data)
}
}).catch(() => {
this.loading = false
})
},
handleRowClick(row) {
this.selectedRow = row
},
editTask(row) {
this.currentRow = row
this.editForm = {
优先级: row.优先级 || '',
未完成说明: row.未完成说明 || '',
派工特殊说明: row.派工特殊说明 || ''
}
this.editDialogVisible = true
},
submitEditForm() {
this.editSubmitLoading = true
const params = []
params.push(['订单号', this.currentRow.订单号])
params.push(['订单行号', this.currentRow.订单行号])
params.push(['订单拆分内码', this.currentRow.拆分内码])
params.push(['优先级', this.editForm.优先级])
params.push(['未完成说明', this.editForm.未完成说明])
params.push(['派工特殊说明', this.editForm.派工特殊说明])
params.push(['最后编辑人', this.$store.state.user.name])
const Data = this.CreateData('12', 'MES_OrderPlanned_DescriptionEdit', params)
this.ExecDatabase(Data).then(() => {
this.$message.success('保存成功')
this.editDialogVisible = false
this.searchTable()
}).catch(() => {
this.$message.error('保存失败')
}).finally(() => {
this.editSubmitLoading = false
})
},
handleOutsourceNotify(row) {
this.$confirm('确认同计划发起外协通知吗?', '确认', {
confirmButtonText: '是',
cancelButtonText: '否',
type: 'warning',
center: true
}).then(() => {
this.$message.success('外协通知已发送')
}).catch(() => {
})
},
openSplitTask() {
if (!this.selectedRow) {
this.$message.warning('请先选择需要操作的行')
return
}
this.getStationList()
this.splitTaskForm = {
分配数量: this.selectedRow.计划数量 || 0,
指派对象: this.selectedRow.指派对象 || '',
指派对象编号: this.selectedRow.指派对象编号 || '',
派工特殊备注: this.selectedRow.派工特殊说明 || '',
计划开始时间: this.selectedRow.计划开始时间 || '',
计划结束时间: this.selectedRow.计划完成时间 || '',
最晚开始时间: this.selectedRow.最晚开始时间 || '',
任务概述: this.selectedRow.计划数量 || ''
}
this.splitTaskDialogVisible = true
},
submitSplitTaskForm() {
this.splitTaskSubmitLoading = true
this.$confirm('确认要拆分子任务吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
// 空逻辑
this.splitTaskSubmitLoading = false
this.splitTaskDialogVisible = false
this.$message.success('操作成功')
this.searchTable()
}).catch(() => {
this.splitTaskSubmitLoading = false
this.$message.info('已取消操作')
})
},
getStationList() {
const params = []
const Data = this.CreateData('11', 'Prog_MES_LoadStations', params)
this.ExecDatabase(Data).then(response => {
if (response.data && response.data.length > 0) {
this.stationOptions = response.data.map(item => ({
label: item.OPName,
value: item.OPName,
code: item.VisCode
}))
}
})
},
handleStationChange(value) {
const selected = this.stationOptions.find(item => item.value === value)
if (selected) {
this.splitTaskForm.指派对象编号 = selected.code
}
}
}
}
</script>
<style scoped>
::v-deep .el-table th.el-table__cell>.cell{
white-space: pre-wrap;
}
.search-container {
margin-bottom: 20px;
}
.show-text {
margin-right: 5px;
line-height: 32px;
}
.status-light {
display: inline-block;
width: 12px;
height: 12px;
border-radius: 50%;
}
.status-light-green {
background-color: #67C23A;
}
.status-light-gray {
background-color: #909399;
}
.dialog-footer {
text-align: right;
}
</style>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,532 @@
<template>
<div>
<el-card>
<div class="search-container">
<span class="show-text">销售订单:</span>
<el-input v-model="contractNo" placeholder="请输入销售订单" clearable style="width: 150px;margin-right: 10px" />
<span class="show-text">生产订单:</span>
<el-input v-model="orderNo" placeholder="请输入生产订单" clearable style="width: 150px;margin-right: 10px" />
<span class="show-text">产品编码:</span>
<el-input v-model="productCode" placeholder="请输入产品编码" clearable style="width: 150px;margin-right: 10px" />
<span class="show-text">产品名称:</span>
<el-input v-model="productName" placeholder="请输入产品名称" clearable style="width: 150px;margin-right: 10px" />
<span class="show-text">工序名称:</span>
<el-input v-model="processName" placeholder="请输入工序名称" clearable style="width: 150px;margin-right: 10px" />
<br>
<br>
<span class="show-text">性质:&nbsp;&nbsp;&nbsp;</span>
<el-input v-model="nature" placeholder="请输入性质" clearable style="width: 150px;margin-right: 10px" />
<span class="show-text">要求完工日期:</span>
<el-date-picker v-model="completionTime" :clearable="false" end-placeholder="结束时间" format="yyyy-MM-dd"
range-separator="-" start-placeholder="开始时间" style="width: 230px;"type="datetimerange" value-format="yyyy-MM-dd" />
<span class="show-text">指派对象:</span>
<el-select v-model="Doing" multiple @change = "Doingform">
<el-option v-for="item in Doingoptions"
:key="item.指南工位号"
:label="item.指南工位号"
:value="item.工位号" />
</el-select>
<el-button :disabled="loading" icon="el-icon-search" plain type="primary"
@click="searchTable()">查询</el-button>
</div>
<el-tabs v-model="activeTab" type="card" class="custom-tabs">
<el-tab-pane label="表单" name="form">
<div v-for=" (items,itemsname ) in tableData2" >
<h3>{{ itemsname }}</h3> <!-- 显示组名 -->
<el-table v-loading="loading" :data="items" border
element-loading-background="rgba(0, 0, 0, 0.2)" element-loading-spinner="el-icon-loading"
highlight-current-row size="mini" style="width: 100%;margin-top: 20px;" tooltip-effect="dark"
@row-click="handleRowClick">
<el-table-column align="center" label="序号" type="index" width="50" fixed />
<el-table-column align="center" prop="合同号" label="销售订单" width="120" fixed />
<el-table-column align="center" prop="生产订单" label="生产订单" width="100" fixed />
<el-table-column align="center" prop="产品编码" label="零件编码" width="220" />
<el-table-column align="center" prop="产品名称" label="产品名称" width="190" />
<el-table-column align="center" prop="计划数量" label="计划数" width="80" />
<el-table-column align="center" prop="工序名称" label="工序名称" width="120" />
<el-table-column align="center" prop="总工时" label="总工时" width="120" />
<el-table-column align="center" prop="占用情况" label="占用情况" width="120" />
<el-table-column align="center" prop="计划开始时间" label="计划开始时间" width="120" />
<el-table-column align="center" prop="计划完成时间" label="计划完成时间" width="120" />
<el-table-column align="center" prop="最晚开始时间" label="最晚开始时间" width="120" />
<el-table-column align="center" label="要求完工日期" width="120">
<template slot-scope="scope">
{{ formatDate(scope.row.要求完工日期) }}
</template>
</el-table-column>
<el-table-column align="center" label="收料" width="70">
<template slot-scope="scope">
<div v-if =" scope.row.收料数量 < scope.row.计划数量 & scope.row.收料 == 1 " class="status-light status-light-orange" />
<div v-if =" scope.row.收料数量 >= scope.row.计划数量 & scope.row.收料 == 1 "class="status-light status-light-green " />
<div v-if ="!scope.row.收料"class="status-light status-light-gray" />
</template>
</el-table-column>
<el-table-column align="center" label="进度" width="200">
<template slot-scope="scope">
<el-progress :percentage="scope.row.进度" />
</template>
</el-table-column>
<el-table-column align="center" label="序检" width="70">
<template slot-scope="scope">
<div v-if =" scope.row.进度 == 100 & scope.row.序检 == 0 " class="status-light status-light-orange" />
<div v-else class="status-light" :class="scope.row.序检 ? 'status-light-green' : 'status-light-gray'" />
</template>
</el-table-column>
<el-table-column align="center" label="优先级" width="80">
<template slot-scope="scope">
<div class="status-light"
:class="scope.row.优先级 === '是' ? 'status-light-green' : 'status-light-gray'" />
</template>
</el-table-column>
<el-table-column align="center" prop="未完成说明" label="未完成说明" width="120" />
<el-table-column align="center" prop="派工特殊说明" label="派工特殊备注" width="120" />
<el-table-column align="center" label="编辑" width="120">
<template slot-scope="scope">
<el-button type="text" size="mini" @click="editTask(scope.row)">编辑</el-button>
</template>
</el-table-column>
<el-table-column align="center" prop="最后编辑人" label="最后编辑人" width="100" />
<el-table-column align="center" label="最后编辑时间" width="170">
<template slot-scope="scope">
{{ scope.row.最后编辑时间 }}
</template>
</el-table-column>
</el-table>
</div>
</el-tab-pane>
<el-tab-pane label="日程" name="schedule">
<div class="schedule-container">
<FullCalendar ref="fullCalendar" :options="calendarOptions" />
</div>
</el-tab-pane>
</el-tabs>
</el-card>
<!-- 编辑备注弹窗 -->
<el-dialog :visible.sync="editDialogVisible" title="编辑任务信息" width="600px" center>
<el-form ref="editForm" :model="editForm" label-width="140px" size="mini">
<el-form-item label="优先级">
<el-select v-model="editForm.优先级" placeholder="请选择优先级" style="width: 100%">
<el-option label="" value="" />
<el-option label="" value="" />
</el-select>
</el-form-item>
<el-form-item label="未完成说明">
<el-input v-model="editForm.未完成说明" :rows="2" type="textarea" placeholder="请输入未完成说明" />
</el-form-item>
<el-form-item label="派工特殊备注">
<el-input v-model="editForm.派工特殊说明" :rows="3" type="textarea" placeholder="请输入派工特殊备注" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="editDialogVisible = false">取 消</el-button>
<el-button :loading="editSubmitLoading" type="primary" @click="submitEditForm">确 定</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
// 这三个组件用于绘制日历
import FullCalendar from '@fullcalendar/vue'
import dayGridPlugin from '@fullcalendar/daygrid'
import interactionPlugin from '@fullcalendar/interaction'
export default {
components: { FullCalendar },
data() {
return {
activeTab: 'form',
orderNo: '',
contractNo: '',
productCode: '',
productName: '',
processName: '',
nature: '',
station: '',
productionStatus: '全部',
completionTime: [],
loading: false,
tableData: [],
tableData2: [],
selectedRow: null,
editDialogVisible: false,
editSubmitLoading: false,
currentRow: {},
editForm: {
优先级: '',
未完成说明: '',
派工特殊说明: ''
},
taskAdjustVisible: false,
taskSubmitLoading: false,
stationOptions: [],
taskForm: {
指派对象: '',
指派对象编号: '',
指派数量: 0,
计划开始时间: '',
计划完成时间: '',
最晚开始时间: '',
派工特殊说明: ''
},
checkList: [],
Doingoptions:[],
Doing:"",
dialogadjust:false,
formData:[],
// FullCalendar 配置选项
calendarOptions: {
plugins: [dayGridPlugin, interactionPlugin], // 加载日视图和交互插件
initialView: 'dayGridMonth',
locale: 'zh-cn',
headerToolbar: {
left: 'prev,next today',
center: 'title',
right: 'today'
},
editable: true, // 允许通过拖拽或调整大小来修改事件
droppable: true,
events: [],
eventDrop: this.handleEventDrop, // 拖拽完成后回调
eventResize: this.handleEventResize, // 调整大小完成后回调
height: 'auto', // 设置高度为auto使其自适应内容
dayMaxEvents: true // 限制每天显示的事件数量
}
}
},
computed: {
calendarEvents() {
return this.tableData.map(item => ({
id: `${item.订单号}-${item.订单行号}-${item.拆分内码}`,
title: `${item.进度} | ${item.订单号} | ${item.产品名称} | ${item.产品编码} | 分配数量:${item.指派数量} | 序:${item.工序名称}`,
start: this.formatDateForCalendar(item.计划开始时间),
end: this.formatDateForCalendar(item.计划完成时间, true),
extendedProps: {
订单号: item.订单号,
订单行号: item.订单行号,
拆分内码: item.拆分内码,
}
}))
}
},
watch: {
activeTab(newVal) {
if (newVal === 'schedule') {
this.$nextTick(() => {
// 判断日历的HTML Dom 是否存在
const calendarApi = this.$refs.fullCalendar && this.$refs.fullCalendar.getApi()
if (calendarApi) {
// 重新绘制日历界面 避免出现未渲染问题
calendarApi.updateSize()
}
this.calendarOptions.events = this.calendarEvents
})
}
},
tableData: {
handler() {
this.calendarOptions.events = this.calendarEvents
if (this.activeTab === 'schedule') {
this.$nextTick(() => {
const calendarApi = this.$refs.fullCalendar && this.$refs.fullCalendar.getApi()
if (calendarApi) {
calendarApi.refetchEvents()
}
})
}
},
deep: true
}
},
created() {
var now = new Date()
var start = new Date(Date.UTC(now.getFullYear() - 1, now.getMonth(), now.getDate(), 0, 0, 0)).toISOString().replace('T', ' ').replace('.000Z', '')
var end = new Date(Date.UTC(now.getFullYear(), now.getMonth(), now.getDate(), 23, 59, 59)).toISOString().replace('T', ' ').replace('.000Z', '')
this.completionTime = [start, end]
this.searchTable()
this.getDoing()
},
methods: {
getDoing(){
var Data = this.CreateData('11', 'MES_登录_工位与名称_查询')
this.ExecDatabase(Data).then(response => {
this.loading = false
if (response.data.length !== 0) {
this.Doingoptions= response.data
}
})
},
Doingform(value){
console.log(value)
},
formatDate(date) {
if (!date) return ''
return date.split(' ').length > 1 ? date.split(' ')[0] : date
},
WorkTimeSum(tdata) {
var param = []
param.push(['计划开工_Start', this.completionTime ? this.completionTime[0] : ''])
param.push(['计划开工_End', this.completionTime ? this.completionTime[1] : ''])
var Data = this.CreateData('11', 'MES_ProductTask_WorkTimeSum', param)
this.ExecDatabase(Data).then(response => {
this.loading = false
tdata.forEach(item => {
response.data.forEach(itemtime => {
if (itemtime.TaskAID == item.TaskAID & itemtime.工序名称 == item.工序名称) {
item.总工时 = itemtime.总工时
}
})
})
var newtdata = tdata.reduce((acc, item) => {
const key = `${item.指派对象}【${item.计划开始时间}】`; // 创建一个唯一的键来区分不同的组
if(item.指派对象 ){
if (!acc[key]) {
acc[key] = []; // 如果键不存在,初始化一个空数组
}
acc[key].push(item); // 将当前项添加到对应的数组中
return acc
}
return acc
}, {}); // 初始值为一个空对象{}
this.tableData2 = newtdata
console.log(newtdata)
}).catch(() => {
this.loading = false
})
},
searchTable() {
this.loading = true
this.tableData = []
var param = []
param.push(['订单号', this.orderNo || 0])
param.push(['物料类型', '装配件'])
param.push(['合同号', this.contractNo])
param.push(['产品编码', this.productCode])
param.push(['产品名称', this.productName])
param.push(['工序名称', this.processName])
param.push(['性质', this.nature])
param.push(['要求完工日期1', this.completionTime ? this.completionTime[0] : ''])
param.push(['要求完工日期2', this.completionTime ? this.completionTime[1] : ''])
param.push(['排产状态', this.productionStatus])
param.push(['工位', this.Doing.toString()])
var Data = this.CreateData('11', 'MES_ProductAdmin_Query', param)
this.ExecDatabase(Data).then(response => {
this.loading = false
this.WorkTimeSum(response.data)
if (response.data.length !== 0) {
this.tableData = response.data
}
}).catch(() => {
this.loading = false
})
},
handleRowClick(row) {
this.selectedRow = row
console.log(row)
},
// 获取工位列表
getStationList() {
const params = []
const Data = this.CreateData('11', 'Prog_MES_LoadStations', params)
this.ExecDatabase(Data).then(response => {
if (response.data && response.data.length > 0) {
this.stationOptions = response.data.map(item => ({
label: item.OPName,
value: item.OPName,
code: item.VisCode
}))
}
})
},
// 处理工位选择
handleStationChange(value) {
const selected = this.stationOptions.find(item => item.value === value)
this.taskForm.指派对象编号 = selected ? selected.code : ''
},
// 提交派工调整
editTask(row) {
this.currentRow = row
this.editForm = {
优先级: row.优先级 || '',
未完成说明: row.未完成说明 || '',
派工特殊说明: row.派工特殊说明 || ''
}
this.editDialogVisible = true
},
submitEditForm() {
this.editSubmitLoading = true
const params = []
params.push(['订单号', this.currentRow.订单号])
params.push(['订单行号', this.currentRow.订单行号])
params.push(['订单拆分内码', this.currentRow.拆分内码])
params.push(['优先级', this.editForm.优先级])
params.push(['未完成说明', this.editForm.未完成说明])
params.push(['派工特殊说明', this.editForm.派工特殊说明])
params.push(['最后编辑人', this.$store.state.user.name])
const Data = this.CreateData('12', 'MES_OrderPlanned_DescriptionEdit', params)
this.ExecDatabase(Data).then(() => {
this.$message.success('保存成功')
this.editDialogVisible = false
this.searchTable()
}).catch(() => {
this.$message.error('保存失败')
}).finally(() => {
this.editSubmitLoading = false
})
},
// 格式化日期以适应 FullCalendar (需要 'yyyy-MM-dd')
formatDateForCalendar(date, isEnd = false) {
if (!date) return null
try {
let d
if (typeof date === 'string') {
// 如果是字符串,解析日期部分
const datePart = date.split(' ')[0]
const [year, month, day] = datePart.split('-').map(Number)
d = new Date(Date.UTC(year, month - 1, day))
} else if (date instanceof Date) {
d = new Date(date.getTime())
}
if (isEnd) {
d.setUTCDate(d.getUTCDate() + 1)
}
// 转换为 ISO 格式并取日期部分
const isoString = d.toISOString()
return isoString.split('T')[0]
} catch (error) {
console.error('Error formatting date for calendar:', date, error)
return null
}
},
// 处理日历事件拖拽完成后的逻辑
handleEventDrop(info) {
const event = info.event
const newStart = this.formatDateForCalendar(event.startStr)
const endDate = new Date(event.endStr)
endDate.setUTCDate(endDate.getUTCDate() - 1)
const newEnd = this.formatDateForCalendar(endDate)
this.updateTaskTime(event.extendedProps, newStart, newEnd, info.revert)
},
// 处理日历事件调整大小完成后
handleEventResize(info) {
const event = info.event
const newStart = this.formatDateForCalendar(event.startStr)
const endDate = new Date(event.endStr)
endDate.setUTCDate(endDate.getUTCDate() - 1)
const newEnd = this.formatDateForCalendar(endDate)
if (!newStart || !newEnd) {
this.$message.error('日期格式错误,无法更新')
info.revert()
return
}
this.updateTaskTime(event.extendedProps, newStart, newEnd, info.revert)
},
// 更新时间 传入 revert 回调用于失败时恢复事件位置
updateTaskTime(taskInfo, startTime, endTime, revertCallback) {
this.$confirm('确认修改计划时间?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
const params = []
var editstr = "[计划开始时间] = '"+ startTime+"' , [计划完成时间] = '"+ endTime+"'"
params.push(['editstr', editstr])
params.push(['订单号', taskInfo.订单号])
params.push(['订单行号', taskInfo.订单行号])
params.push(['订单拆分内码', taskInfo.拆分内码])
// params.push(['计划开始时间', startTime])
// params.push(['计划完成时间', endTime])
const Data = this.CreateData('12', 'MES_OrderPlanned_EditTaskPlanned', params)
this.ExecDatabase(Data).then(response => {
if (response.data[0].result !== '1') {
this.$message.error('计划时间更新失败')
if (revertCallback) revertCallback()
return
}
this.$message.success('计划时间更新成功')
this.searchTable()
this.donesearchTable()
})
}).catch(() => {
if (revertCallback) revertCallback()
})
}
}
}
</script>
<style scoped>
.search-container {
margin-bottom: 20px;
}
.show-text {
margin-right: 5px;
line-height: 32px;
}
.status-light {
display: inline-block;
width: 12px;
height: 12px;
border-radius: 50%;
}
.status-light-orange {
background-color: #e4a629;
}
.status-light-green {
background-color: #67C23A;
}
.status-light-gray {
background-color: #909399;
}
.dialog-footer {
text-align: right;
}
/* .schedule-container {
min-height: 67vh;
} */
.schedule-container ::v-deep .fc-daygrid-day-frame {
padding: 2px;
min-height: auto;
}
.schedule-container ::v-deep .fc-event {
font-size: 12px;
padding: 1px 2px;
margin-bottom: 1px;
line-height: 1.4;
}
.schedule-container ::v-deep .fc-daygrid-event-harness {
margin-bottom: 1px;
}
.schedule-container ::v-deep .fc-daygrid-day-top {
padding: 2px;
}
.schedule-container ::v-deep .fc-daygrid-more-link {
font-size: 12px;
padding: 0 2px;
}
</style>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,869 @@
<template>
<div class="app-container">
<el-card style="height: 850px">
<div style="margin-top: 7px; margin-bottom: 7px">
<span class="show-text">生产订单:</span>
<el-input
v-model="orderNo"
placeholder="请输入生产订单"
clearable
style="width: 150px; margin-right: 10px"
/>
<span class="show-text">物料编码:</span>
<el-input
v-model="productCode"
placeholder="请输入物料编码"
clearable
style="width: 150px; margin-right: 10px"
/>
<span class="show-text">物料名称:</span>
<el-input
v-model="itemName"
placeholder="请输入物料名称"
clearable
style="width: 150px; margin-right: 10px"
/>
<span class="show-text">工序名称:</span>
<el-input
v-model="processName"
placeholder="请输入工序名称"
clearable
style="width: 150px; margin-right: 10px"
/>
<br></br>
<span class="show-text">派工状态:</span>
<el-select v-model="workstate" placeholder="请选择">
<el-option
v-for="item in workstateoptions"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
<span class="show-text">状态:</span>
<el-select v-model="orderstate" placeholder="请选择">
<el-option
v-for="item in stateoptions"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
<el-button
icon="el-icon-search"
plain
type="primary"
@click="searchTable()"
>查询</el-button
>
<el-button icon="el-icon-printer" type="primary" plain size="small" style="margin-left: 10px;padding: 8px 15px;" @click="searchTable1" >打印</el-button>
</div>
<el-table
:data="mergedTableData"
highlight-current-row
border
size="small"
style="margin-top: 10px"
height="740px"
@selection-change="handleSelectionChange"
@row-click="handleRowClick">
<el-table-column type="selection" width="55"></el-table-column>
<el-table-column label="序号" type="index" align="center" width="50"/>
<el-table-column label="生产订单" align="center" prop="订单号" width="80" />
<el-table-column label="物料名称" align="center" prop="产品名称" width="200"/>
<el-table-column label="物料编码" align="center" prop="产品编码" width="200"/>
<el-table-column label="指派数量" align="center" prop="指派数量" width="80"/>
<el-table-column label="发料数量" align="center" prop="收料数量" width="80"/>
<el-table-column label="收料数量" align="center" prop="完成数量" width="80"/>
<el-table-column label="工序名称" align="center" prop="工序名称" width="120"/>
<el-table-column label="打印次数" align="center" prop="外协打印次数" width="120"/>
<el-table-column label="计划开始时间" align="center" prop="计划开始时间" width="120">
<template slot-scope="scope">
{{formatDate(scope.row.计划开始时间)}}
</template>
</el-table-column>
<el-table-column label="计划完成时间" align="center" prop="计划完成时间" width="120">
<template slot-scope="scope">
{{formatDate(scope.row.计划完成时间)}}
</template>
</el-table-column>
<el-table-column label="操作" align="center" width="200px">
<template slot-scope="scope">
<el-button
type="text"
size="mini"
style="margin-right: 5px; padding:0; width:auto"
@click="receive(scope.row)">发料
</el-button>
<el-button
type="text"
size="mini"
style="margin-right: 5px; padding:0; width:auto"
@click="doreceive(scope.row)">收料
</el-button>
<!-- <el-button
type="text"
size="mini"
style="margin-right: 5px; padding:0; width:auto"
@click="updateload2(scope.row)">上传ERP
</el-button> -->
</template>
</el-table-column>
</el-table>
</el-card>
<div v-for="(printData, index) in printDataList" :key="index" class="print-page" style="display: none; width: 20cm;height: 11.5cm;background-color: #fff; page-break-after: always;" >
<div style="margin-bottom: 10px;">
<div style="display: flex;">
<div style="width: 35%;
height: 40px;
background: url(/static/img/logo.1e81c84.png);
background-size: contain;
background-repeat: no-repeat;
"></div>
<div style="width: 65%;text-align: left;font-size: 25px;line-height: 40px;">大连元利流体生产工票</div>
</div>
</div>
<div class="field-container">
<div class="field-row">
<div class="field-group">
<span class="field-label">生产订单</span>
<span class="field-value">{{ printData.订单号 }}</span>
</div>
<div class="field-group">
<span class="field-label">工序名称</span>
<span class="field-value">{{ printData.工序名称 }}</span>
</div>
<div class="field-group">
<span class="field-label">指派数量</span>
<span class="field-value">{{ printData.指派数量 }}</span>
</div>
<div class="field-group">
<span class="field-label">销售订单</span>
<span class="field-value">{{ printData.合同号}}</span>
</div>
</div>
<div class="field-row">
<div class="field-group">
<span class="field-label">物料编码</span>
<span class="field-value">{{ printData.产品编码}}</span>
</div>
<div class="field-group">
<span class="field-label">物料名称</span>
<span class="field-value">{{ printData.产品名称}}</span>
</div>
<div class="field-group">
<span class="field-label">发料数量</span>
<span class="field-value">{{ printData.收料数量}}</span>
</div>
<div class="field-group">
<span class="field-label">打印次数</span>
<span class="field-value">{{ printData.外协打印次数}}</span>
</div>
</div>
<div class="field-row">
<div class="field-group">
<span class="field-label">制单人</span>
<span class="field-value">{{printData.最后编辑人}}</span>
</div>
<div class="field-group">
<span class="field-label">制单日期</span>
<span class="field-value">{{formatDate(printData.最后编辑时间) }}</span>
</div>
<div class="field-group">
<span class="field-label">操作者</span>
<span class="field-value">{{ numname }}</span>
</div>
<div class="field-group">
<span class="field-label">计划完工</span>
<span class="field-value">{{ formatDate(printData.计划完成时间) }}</span>
</div>
</div>
<div class="field-row">
<div class="field-group">
<span class="field-label">操作者</span>
<span class="field-value"></span>
</div>
<div class="field-group">
<span class="field-label">受单日期</span>
<span class="field-value"></span>
</div>
<div class="field-group">
<span class="field-label">检验员</span>
<span class="field-value"></span>
</div>
<div class="field-group">
<span class="field-label">检验日期</span>
<span class="field-value"></span>
</div>
</div>
</div>
</div>
<el-dialog :visible.sync="receiveVisible" title="发料" width="600px" center>
<el-form
ref="receiveForm"
:model="receiveData"
label-width="140px"
size="mini"
>
<el-form-item label="生产订单">
<el-input v-model="receiveData.订单编号" :rows="2" readonly />
</el-form-item>
<el-form-item label="销售订单">
<el-input v-model="receiveData.销售订单" :rows="2" readonly />
</el-form-item>
<el-form-item label="物料编号">
<el-input v-model="receiveData.物料编号" :rows="2" readonly />
</el-form-item>
<el-form-item label="分配数">
<el-input v-model="receiveData.指派数量" :rows="2" readonly />
</el-form-item>
<el-form-item label="已发料">
<el-input v-model="receiveData.收料数量" :rows="2" readonly />
</el-form-item>
<el-form-item label="发料工位">
<el-input v-model="receiveData.指派对象" :rows="2" readonly />
</el-form-item>
<el-form-item label="本次发料">
<el-input
v-model="receiveNum"
type="number"
@change="funreceiveNum"
/>
</el-form-item>
<el-form-item label="操作人">
<el-input v-model="this.$store.state.user.name" :rows="2" readonly />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="receiveVisible = false"> </el-button>
<el-button type="primary" @click="receiveForm()"> </el-button>
</div>
</el-dialog>
<el-dialog :visible.sync="doVisible" title="收料" width="600px" center>
<el-form
ref="doForm"
:model="doData"
label-width="140px"
size="mini"
>
<el-form-item label="生产订单">
<el-input v-model="doData.订单编号" :rows="2" readonly />
</el-form-item>
<el-form-item label="销售订单">
<el-input v-model="doData.销售订单" :rows="2" readonly />
</el-form-item>
<el-form-item label="物料编号">
<el-input v-model="doData.物料编号" :rows="2" readonly />
</el-form-item>
<el-form-item label="发料数">
<el-input v-model="doData.收料数量" :rows="2" readonly />
</el-form-item>
<el-form-item label="已收料">
<el-input v-model="doData.完成数量" :rows="2" readonly />
</el-form-item>
<el-form-item label="发料工位">
<el-input v-model="doData.指派对象" :rows="2" readonly />
</el-form-item>
<el-form-item label="本次收料">
<el-input
v-model="doNum"
type="number"
@change="fundoNum"
/>
</el-form-item>
<el-form-item label="操作人">
<el-input v-model="this.$store.state.user.name" :rows="2" readonly />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="doVisible = false"> </el-button>
<el-button type="primary" @click="doForm()"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { mapGetters } from 'vuex'
import { postB1 } from '@/api/b1s';
import $ from 'jquery'
export default {
data() {
return {
dialogFormVisible1: false,
tableData: [], // 原始数据
mergedTableData: [], // 合并后的数据
selectedRow:'',
productCode:'',
orderNo:'',
processName:'',
itemName:'',
sessionId:'',
currentTime:'',
receiveVisible:false,
receiveData: {},
receiveNum: 0,
doVisible:false,
doData: {},
doNum: 0,
// 新增:存储合并数据的原始信息
mergedDataMap: new Map(), // 用于存储合并数据对应的原始数据组
workstate:1,
orderstate:0,
workstateoptions:[{
value: 0,
label: '未派工'
}, {
value: 1,
label: '已派工',
disabled: true
}],
stateoptions:[{
value: 0,
label: '未完成',
disabled: true
}, {
value: 1,
label: '已完成',
}],
multipleSelection: [],
printDataList: [] ,// 新增:存储多个打印数据
numname:''
}
},
computed: {
...mapGetters([
'id',
'token'
]),
},
created() {
this.searchTable()
setInterval(this.getCurrentTime, 1000);
},
methods: {
async searchTable1() {
// var row = this.selectedRow
// if (row.length === 0) {
// this.$message.warning('请选择要打印的数据')
// return
// }
this.loading = true
// 清空之前的打印数据
this.printDataList = []
try {
this.$nextTick(() => {
setTimeout(() => {
this.handlePrint()
}, 500)
})
this.numname = this.$store.state.user.name
} catch (error) {
console.error('获取打印数据失败:', error)
this.$message.error('获取打印数据失败')
} finally {
this.loading = false
}
},
// 修改:整合打印流程
async handlePrint() {
if (this.multipleSelection.length === 0) {
this.$message.warning('请选择要打印的数据')
return
}
if (this.isPrinting) {
this.$message.warning('正在打印中,请稍候...')
return
}
this.isPrinting = true
this.loading = true
try {
// 1. 获取打印数据
await this.preparePrintData()
// 2. 执行打印
await this.executePrint()
// 3. 更新打印次数
await this.recordPrintCount()
this.$message.success('打印完成')
} catch (error) {
console.error('打印流程失败:', error)
this.$message.error('打印失败: ' + error.message)
} finally {
this.loading = false
this.isPrinting = false
}
},
// 准备打印数据
async preparePrintData() {
this.printDataList = []
for (const item of this.multipleSelection) {
this.printDataList.push(item)
}
console.log(this.printDataList)
},
// 执行打印
executePrint() {
return new Promise((resolve, reject) => {
try {
// 保存原始样式
const originalStyles = {}
$('.print-page').each(function(index) {
originalStyles[index] = $(this).attr('style')
})
const body = $('body')
// 隐藏原始内容
body.children().hide()
// 创建打印容器
const printContainer = $('<div class="print-container"></div>')
// 复制所有打印页面到打印容器
$('.print-page').each(function() {
const pageClone = $(this).clone()
pageClone.css({
display: 'block',
width: '20cm',
height: '11.5cm',
'background-color': '#fff',
'page-break-after': 'always',
margin: '0',
padding: '0'
})
printContainer.append(pageClone)
})
// 添加到body
body.append(printContainer)
// 打印后恢复
const restorePage = () => {
try {
printContainer.remove()
body.children().show()
// 恢复原始样式
$('.print-page').each(function(index) {
if (originalStyles[index]) {
$(this).attr('style', originalStyles[index])
} else {
$(this).css('display', 'none')
}
})
if (window.matchMedia) {
window.matchMedia('print').removeListener(handlePrintChange)
}
resolve()
} catch (error) {
reject(error)
}
}
const handlePrintChange = (mql) => {
if (!mql.matches) {
restorePage()
}
}
// 添加打印状态监听
if (window.matchMedia) {
window.matchMedia('print').addListener(handlePrintChange)
}
// 设置超时恢复(备用)
setTimeout(restorePage, 5000)
// 触发打印
window.print()
} catch (error) {
reject(error)
}
})
},
// 记录打印次数
async recordPrintCount() {
try {
const orderNumbers = this.multipleSelection.map(item => item.TaskAID)
if (orderNumbers.length === 0) {
return
}
const param = [
['订单编号列表', orderNumbers.join(',')]
]
const Data = this.CreateData('11', '生产管理_外协管理_更新打印次数', param)
const response = await this.ExecDatabase(Data)
this.searchTable()
if (response && response.success) {
console.log(`成功更新${orderNumbers.length}个订单的打印次数`)
// 刷新表格数据
} else {
console.warn('更新打印次数失败', response)
}
} catch (error) {
console.error('记录打印次数失败:', error)
// 这里不显示错误消息,避免影响用户体验
}
},
handleSelectionChange(val) {
this.multipleSelection = val;
},
getCurrentTime() {
const now = new Date();
const year = now.getFullYear();
const month = String(now.getMonth() + 1).padStart(2, "0");
const day = String(now.getDate()).padStart(2, "0");
const hours = String(now.getHours()).padStart(2, "0");
const minutes = String(now.getMinutes()).padStart(2, "0");
const seconds = String(now.getSeconds()).padStart(2, "0");
this.currentTime = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
},
handleRowClick(row) {
this.selectedRow = row
},
searchTable() {
this.loading = true
var param = []
param.push(["订单号",this.orderNo])
param.push(["产品编码",this.productCode])
param.push(["产品名称",this.itemName])
param.push(["工序名称",this.processName])
param.push(["派工状态",this.workstate])
param.push(["订单状态",this.orderstate])
var Data = this.CreateData('11', '生产管理_外协管理_查询外协',param)
this.ExecDatabase(Data).then(response => {
this.tableData = response.data
this.mergeTableData() // 处理数据合并
})
},
// 合并表格数据的方法
mergeTableData() {
if (!this.tableData || this.tableData.length === 0) {
this.mergedTableData = [];
this.mergedDataMap.clear();
return;
}
// 按订单号分组
const groupedByOrder = {};
this.tableData.forEach(item => {
const orderNo = item.订单号;
if (!groupedByOrder[orderNo]) {
groupedByOrder[orderNo] = [];
}
groupedByOrder[orderNo].push(item);
});
const mergedData = [];
this.mergedDataMap.clear();
// 处理每个订单组
Object.keys(groupedByOrder).forEach(orderNo => {
const orderItems = groupedByOrder[orderNo];
// 按订单行号排序
orderItems.sort((a, b) => a.订单行号 - b.订单行号);
let currentGroup = [orderItems[0]];
for (let i = 1; i < orderItems.length; i++) {
const currentItem = orderItems[i];
const lastItem = orderItems[i - 1];
// 检查订单行号是否连续
if (currentItem.订单行号 === lastItem.订单行号 + 1) {
currentGroup.push(currentItem);
} else {
// 不连续,处理当前组并开始新组
const mergedItem = this.mergeGroup(currentGroup);
mergedData.push(mergedItem);
// 存储合并数据对应的原始数据组
this.mergedDataMap.set(mergedItem.uniqueKey, currentGroup);
currentGroup = [currentItem];
}
}
// 处理最后一组
if (currentGroup.length > 0) {
const mergedItem = this.mergeGroup(currentGroup);
mergedData.push(mergedItem);
// 存储合并数据对应的原始数据组
this.mergedDataMap.set(mergedItem.uniqueKey, currentGroup);
}
});
this.mergedTableData = mergedData;
},
// 合并单个组的数据
mergeGroup(group) {
if (group.length === 1) {
const item = group[0];
item.uniqueKey = `${item.订单号}_${item.订单行号}_${item.TaskAID}`;
// 确保TaskAID是字符串类型便于后续处理
item.TaskAID = String(item.TaskAID);
return item;
}
const mergedItem = { ...group[0] };
// 生成唯一标识key
mergedItem.uniqueKey = group.map(item => `${item.订单号}_${item.订单行号}_${item.TaskAID}`).join('|');
// 拼接工序名称(逗号间隔)
const processNames = [...new Set(group.map(item => item.工序名称))];
mergedItem.工序名称 = processNames.join(',');
// 拼接TaskAID逗号间隔
const taskAIDs = [...new Set(group.map(item => String(item.TaskAID)))];
mergedItem.TaskAID = taskAIDs.join(',');
// 取计划开始时间的最小值
const startTimes = group.map(item => new Date(item.计划开始时间));
mergedItem.计划开始时间 = new Date(Math.min(...startTimes)).toISOString().slice(0, 19).replace('T', ' ');
// 取计划完成时间的最大值
const endTimes = group.map(item => new Date(item.计划完成时间));
mergedItem.计划完成时间 = new Date(Math.max(...endTimes)).toISOString().slice(0, 19).replace('T', ' ');
// 取最大值
const wcnum = group.map(item => item.完成数量);
mergedItem.完成数量 = Math.max(...wcnum)
const printnum = group.map(item => item.外协打印次数);
mergedItem.外协打印次数 = Math.max(...printnum)
// 取计划完成时间的最大值
const slnum = group.map(item => item.收料数量);
mergedItem.收料数量 = Math.max(...slnum)
// 存储原始组数据引用
mergedItem.originalGroup = group;
return mergedItem;
},
// 获取订单行号最大的TaskAID
getMaxOrderLineTaskAID(row) {
// 如果是单条数据直接返回TaskAID
if (typeof row.TaskAID === 'number' || !row.TaskAID.includes(',')) {
return String(row.TaskAID);
}
// 如果是合并数据从原始数据组中找订单行号最大的TaskAID
if (row.originalGroup) {
const maxOrderLineItem = row.originalGroup.reduce((max, item) => {
return item.订单行号 > max.订单行号 ? item : max;
}, row.originalGroup[0]);
return String(maxOrderLineItem.TaskAID);
}
// 如果没有原始组数据从TaskAID字符串中取最后一个
const taskAIDs = row.TaskAID.split(',');
return taskAIDs[taskAIDs.length - 1];
},
formatDate(date) {
if (!date) return ''
return date.split(' ').length > 1 ? date.split(' ')[0] : date
},
funreceiveNum(num) {
this.receiveNum = num;
},
fundoNum(num) {
this.doNum = num;
},
receive(row) {
if(!row){
this.$message.warning("请先选择一行数据");
return;
}
this.receiveVisible = true;
const param = [];
// 获取订单行号最大的TaskAID
const maxTaskAID = this.getMaxOrderLineTaskAID(row);
param.push(["TaskAID", maxTaskAID]);
var Data = this.CreateData("11", "生产管理_外协管理_外协发料查询", param);
this.ExecDatabase(Data)
.then((response) => {
this.loading = false;
if (response.data.length !== 0) {
this.receiveData = response.data[0];
}
})
.catch(() => {
this.loading = false;
});
},
doreceive(row) {
if(!row){
this.$message.warning("请先选择一行数据");
return;
}
this.doVisible = true;
const param = [];
// 获取订单行号最大的TaskAID
const maxTaskAID = this.getMaxOrderLineTaskAID(row);
param.push(["TaskAID", maxTaskAID]);
var Data = this.CreateData("11", "生产管理_外协管理_外协发料查询", param);
this.ExecDatabase(Data)
.then((response) => {
this.loading = false;
if (response.data.length !== 0) {
this.doData = response.data[0];
}
})
.catch(() => {
this.loading = false;
});
},
receiveForm() {
const params = [];
var row = this.selectedRow;
if (!this.receiveNum) {
this.$message.error('数量输入错误')
return
}
if (this.receiveNum > this.receiveData.指派数量 - this.receiveData.收料数量) {
this.$message.error('数量输入错误')
return
}
if (this.receiveNum > this.receiveData.上序合格数 & this.receiveData.订单行号>1) {
this.$message.error('数量输入错误')
return
}
// 获取订单行号最大的TaskAID
const maxTaskAID = this.getMaxOrderLineTaskAID(row);
params.push(["TaskAID", maxTaskAID]);
params.push(["optor", this.$store.state.user.name]);
params.push(["recievCount", this.receiveNum]);
const Data = this.CreateData(
"11",
"生产管理_外协管理_外协发料保存",
params
);
this.ExecDatabase(Data)
.then(() => {
this.$message.success("发料操作成功");
this.receiveVisible = false;
this.receiveNum = 0;
this.searchTable();
})
.catch(() => {
this.$message.error("保存失败");
})
.finally(() => {});
},
doForm() {
const params = [];
var row = this.selectedRow;
if (!this.doNum) {
this.$message.error('数量输入错误')
return
}
if (this.doNum > this.doData.收料数量 - this.doData.完成数量) {
this.$message.error('数量输入错误')
return
}
// 获取订单行号最大的TaskAID
const maxTaskAID = this.getMaxOrderLineTaskAID(row);
params.push(["TaskAID", maxTaskAID]);
params.push(["optor", this.$store.state.user.name]);
params.push(["recievCount", this.doNum]);
const Data = this.CreateData(
"11",
"生产管理_外协管理_外协收料保存",
params
);
this.ExecDatabase(Data)
.then(() => {
this.$message.success("收料操作成功");
this.doVisible = false;
this.doNum = 0;
this.searchTable();
})
},
async updateload2(data){
},
}
}
</script>
<style>
.field-container {
border: 1px solid #000;
border-bottom:0px
}
.field-row {
display: flex;
width: 100%;
border-bottom: 1px solid #000;
}
.field-group {
display: flex;
width: 25%;
align-items: stretch;
border-right: 1px solid #000;
}
.field-group:last-child {
border-right: none;
}
.field-label {
width: 40%;
color: #000;
text-align: right;
padding: 12px 5px;
border-right: 1px solid #000;
display: flex;
align-items: center;
justify-content: flex-end;
}
.field-value {
width: 60%;
color: #303133;
word-break: break-word;
overflow-wrap: break-word;
padding: 12px 10px;
display: flex;
align-items: center;
}
</style>

View File

@@ -0,0 +1,235 @@
<template>
<div class="app-container">
<el-card>
<!-- <span class="show-text">工位名称:</span>
<el-input
v-model="searchWorkstationName"
clearable
placeholder="请输入工位名称"
style="width: 280px;margin-right: 26px"/>
<el-button icon="el-icon-search" plain type="primary" @click="searchData()">查询</el-button> -->
<div style="margin-top: 10px">
<el-table
v-loading="loading"
:data="tableData"
border
element-loading-background="rgba(0, 0, 0, 0.2)"
element-loading-spinner="el-icon-loading"
element-loading-text="数据加载中"
height="694"
highlight-current-row
size="mini"
stripe
style="width: 100%"
tooltip-effect="dark">
<el-table-column align="center" label="序号" type="index" width="60"/>
<el-table-column align="center" label="工位名称" width="120">
<template slot-scope="scope">
{{ scope.row.指南工位号 }}
</template>
</el-table-column>
<el-table-column align="center" label="工位号" width="100">
<template slot-scope="scope">
{{ scope.row.工位号 }}
</template>
</el-table-column>
<el-table-column align="center" label="绑定人员" width="300">
<template slot-scope="scope">
<el-tag
v-for="person in scope.row.绑定人员列表"
:key="person.人员编号"
style="margin: 2px"
type="info">
{{ person.人员姓名 }}
</el-tag>
<span v-if="!scope.row.绑定人员列表 || scope.row.绑定人员列表.length === 0">未绑定人员</span>
</template>
</el-table-column>
<el-table-column align="center" label="操作" width="120">
<template slot-scope="scope">
<el-button
icon="el-icon-user"
style="font-family: MiSans Regular,serif;color: #67c23a"
type="text"
@click="handleBindPerson(scope.row)">绑定人员
</el-button>
</template>
</el-table-column>
</el-table>
</div>
</el-card>
<!-- 绑定人员对话框 -->
<el-dialog :visible.sync="dialogBindPersonVisible" center title="绑定人员" width="600px">
<el-divider style="margin: 0"/>
<div style="margin: 20px 0">
<span>当前工位: {{ currentWorkstation.指南工位号 }} ({{ currentWorkstation.工位号 }})</span>
</div>
<el-transfer
v-model="selectedPersonnel"
:data="personnelList"
:titles="['可选人员', '已选人员']"
filterable
style="text-align: left"
@change="handleTransferChange">
</el-transfer>
<div slot="footer" style="text-align: center; margin-top: 20px">
<el-button type="primary" @click="submitBindPerson"> </el-button>
<el-button @click="dialogBindPersonVisible = false"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
export default {
data() {
return {
searchWorkstationName: '',
loading: false,
tableData: [],
dialogBindPersonVisible: false,
currentWorkstation: {},
personnelList: [],
selectedPersonnel: [],
}
},
created() {
this.searchData()
this.loadPersonnelList()
},
methods: {
// 查询工位数据
searchData() {
this.loading = true
this.tableData = []
var param = []
var Data = this.CreateData('11', 'MES_登录_工位与名称_查询', param)
this.ExecDatabase(Data).then(response => {
if (response.data.length !== 0) {
this.tableData = response.data
this.loadBoundPersonnelForWorkstations()
} else {
this.loading = false
}
})
},
// 加载所有人员列表
loadPersonnelList() {
var param = []
var Data = this.CreateData('11', '系统管理_人员管理_所有有效人员查询', param)
this.ExecDatabase(Data).then(response => {
if (response.data && response.data.length > 0) {
this.personnelList = response.data.map(person => ({
key: person.人员编号,
label: `${person.人员姓名} (${person.账号})`,
disabled: false
}))
}
})
},
// 为所有工位加载绑定的人员信息
loadBoundPersonnelForWorkstations() {
console.log('开始加载绑定人员信息...')
const promises = this.tableData.map((workstation, index) => {
return new Promise((resolve) => {
var param = []
param[0] = ['工位号', workstation.工位号]
var Data = this.CreateData('11', '系统管理_工位管理_工位绑定人员查询', param)
this.ExecDatabase(Data).then(response => {
// 检查响应数据结构
let boundPersonnel = []
if (response.data && Array.isArray(response.data)) {
boundPersonnel = response.data
} else if (response.result && Array.isArray(response.result)) {
boundPersonnel = response.result
} else if (response.data && response.data.result && Array.isArray(response.data.result)) {
boundPersonnel = response.data.result
}
// 使用 Vue.set 确保响应式更新
this.$set(workstation, '绑定人员列表', boundPersonnel)
resolve()
}).catch((error) => {
console.error(`加载工位 ${workstation.工位号} 绑定人员失败:`, error)
this.$set(workstation, '绑定人员列表', [])
resolve()
})
})
})
Promise.all(promises).then(() => {
console.log('所有工位绑定人员加载完成,最终数据:', this.tableData)
this.loading = false
})
},
// 绑定人员
handleBindPerson(row) {
this.currentWorkstation = { ...row }
this.dialogBindPersonVisible = true
// 加载该工位已绑定的人员
var param = []
param[0] = ['工位号', row.工位号]
var Data = this.CreateData('11', '系统管理_工位管理_工位绑定人员查询', param)
this.ExecDatabase(Data).then(response => {
if (response.data && response.data.length > 0) {
this.selectedPersonnel = response.data.map(person => person.人员编号)
} else {
this.selectedPersonnel = []
}
})
},
// 提交人员绑定
submitBindPerson() {
if (!this.currentWorkstation.工位号) {
this.$message.error('工位信息错误')
return
}
var param = []
param[0] = ['工位号', this.currentWorkstation.工位号]
param[1] = ['人员编号列表', this.selectedPersonnel.join(',')]
var Data = this.CreateData('11', '系统管理_工位管理_工位绑定人员保存', param)
this.ExecDatabase(Data).then(response => {
if (response.data[0].执行结果 === 1) {
this.$message.success('人员绑定成功')
this.dialogBindPersonVisible = false
this.searchData() // 刷新数据
} else {
this.$message.error('人员绑定失败: ' + response.data[0].提示信息)
}
}).catch(() => {
this.$message.error('人员绑定失败')
})
},
// 传输框变化处理
handleTransferChange(value, direction, movedKeys) {
console.log('传输框变化:', value, direction, movedKeys)
}
}
}
</script>
<style scoped>
.el-card {
margin: 0px;
}
.el-transfer {
display: flex;
justify-content: center;
}
</style>

View File

@@ -0,0 +1,476 @@
<template>
<div>
<el-card>
<div class="search-container">
<span class="show-text">生产订单:</span>
<el-input v-model="orderNo" placeholder="请输入生产订单" clearable style="width: 150px;margin-right: 10px" />
<span class="show-text">销售订单:</span>
<el-input v-model="contractNo" placeholder="请输入销售订单" clearable style="width: 150px;margin-right: 10px" />
<span class="show-text">产品编码:</span>
<el-input v-model="productCode" placeholder="请输入产品编码" clearable style="width: 150px;margin-right: 10px" />
<span class="show-text">产品名称:</span>
<el-input v-model="productName" placeholder="请输入产品名称" clearable style="width: 150px;margin-right: 10px" />
<span class="show-text">工序名称:</span>
<el-input v-model="processName" placeholder="请输入工序名称" clearable style="width: 150px;margin-right: 10px" />
<br>
<br>
<span class="show-text">性质:</span>
<el-input v-model="nature" placeholder="请输入性质" clearable style="width: 150px;margin-right: 10px" />
<span class="show-text">排产状态:</span>
<el-select v-model="productionStatus" clearable placeholder="请选择状态" style="width: 150px;margin-right: 10px">
<el-option label="全部" value="全部" />
<el-option label="已完成" value="已完成" />
<el-option label="未完成" value="未完成" />
</el-select>
<span class="show-text">要求完工日期:</span>
<el-date-picker v-model="completionTime" :clearable="false" end-placeholder="结束时间" format="yyyy-MM-dd"
range-separator="-" start-placeholder="开始时间" style="width: 280px;vertical-align: top" type="datetimerange"
value-format="yyyy-MM-dd" />
<el-button :disabled="loading" icon="el-icon-search" plain type="primary" @click="searchTable()">查询</el-button>
</div>
<el-table v-loading="loading" :data="tableData" :height="'67vh'" border
element-loading-background="rgba(0, 0, 0, 0.2)" element-loading-spinner="el-icon-loading" highlight-current-row
size="mini" style="width: 100%;margin-top: 20px;" tooltip-effect="dark" @row-click="handleRowClick">
<el-table-column type="expand">
<template slot-scope="scope">
<el-form label-position="left" class="demo-table-expand">
<el-table :data="scope.row.子数据" :row-class-name="getHeaderClass" border >
<el-table-column align="center" label="序号" type="index" width="50" />
<el-table-column align="center" label="工序名称" prop="工序名称" width="100" />
<el-table-column align="center" label="计划数量" prop="计划数量" width="100" />
<el-table-column align="center" label="指派对象" prop="指派对象" width="100" />
<el-table-column align="center" label="开始时间" prop="计划开始时间" width="100">
<template slot-scope="scope">{{ formatDate(scope.row.计划开始时间) }}</template>
</el-table-column>
<el-table-column align="center" label="结束时间" prop="计划完成时间" width="100">
<template slot-scope="scope">{{ formatDate(scope.row.计划完成时间) }}</template>
</el-table-column>
<el-table-column align="center" label="完成进度" prop="进度" width="100" />
<!-- <el-table-column align="center" label="拆分内码" prop="拆分内码" width="100" /> -->
</el-table>
</el-form>
</template>
</el-table-column>
<el-table-column align="center" label="序号" type="index" width="50" />
<el-table-column align="center" prop="合同号" label="销售订单" width="120" />
<el-table-column align="center" prop="订单号" label="生产订单" width="100" />
<el-table-column align="center" prop="产品编码" label="产品编码" width="220" />
<el-table-column align="center" prop="产品名称" label="产品名称" width="190" />
<el-table-column align="center" prop="计划数量订单" label="计划数量" width="80" />
<el-table-column align="center" label="要求完工日" width="120">
<template slot-scope="scope">{{ formatDate(scope.row.要求完工日期) }}</template>
</el-table-column>
<el-table-column align="center" prop="当前序" label="当前序" width="80" />
<el-table-column align="center" label="排产" width="90">
<template slot-scope="scope">
<div class="status-light" :class="scope.row.排产状态 === 1 ? 'status-light-green' : 'status-light-gray'" />
</template>
</el-table-column>
<el-table-column align="center" label="开工" width="80">
<template slot-scope="scope">
<div class="status-light" :class="scope.row.开工时间 === 1 ? 'status-light-green' : 'status-light-gray'" />
</template>
</el-table-column>
<el-table-column align="center" label="终检" width="80">
<template slot-scope="scope">
<div class="status-light" :class="scope.row.序 === 1 ? 'status-light-green' : 'status-light-gray'" />
</template>
</el-table-column>
<el-table-column align="center" label="入库" width="80">
<template slot-scope="scope">
<div class="status-light" :class="scope.row.入库 === '是' ? 'status-light-green' : 'status-light-gray'" />
</template>
</el-table-column>
<el-table-column align="center" label="优先级" width="80">
<template slot-scope="scope">
<div class="status-light" :class="scope.row.优先级 === '是' ? 'status-light-green' : 'status-light-gray'" />
</template>
</el-table-column>
<!-- <el-table-column align="center" :label = "'工序1\n工序名称'" prop = "工序名称[0]" width="80"/>
<el-table-column align="center" :label = "'工序1\n指派对象'" prop = "指派对象[0]" width="80"/>
<el-table-column align="center" :label = "'工序1\n开始时间'" prop = "计划开始时间[0]" width="120"/>
<el-table-column align="center" :label = "'工序1\n结束时间'" prop = "计划完成时间[0]" width="120"/>
<el-table-column align="center" :label = "'工序1\n完成进度'" prop = "进度[0]" width="80"/>
<el-table-column align="center" :label = "'工序2\n工序名称'" prop = "工序名称[1]" width="80"/>
<el-table-column align="center" :label = "'工序2\n指派对象'" prop = "指派对象[1]" width="80"/>
<el-table-column align="center" :label = "'工序2\n开始时间'" prop = "计划开始时间[1]" width="120"/>
<el-table-column align="center" :label = "'工序2\n结束时间'" prop = "计划完成时间[1]" width="120"/>
<el-table-column align="center" :label = "'工序2\n完成进度'" prop = "进度[1]" width="80"/>
<el-table-column align="center" :label = "'工序3\n工序名称'" prop = "工序名称[2]" width="80"/>
<el-table-column align="center" :label = "'工序3\n指派对象'" prop = "指派对象[2]" width="80"/>
<el-table-column align="center" :label = "'工序3\n开始时间'" prop = "计划开始时间[2]" width="120"/>
<el-table-column align="center" :label = "'工序3\n结束时间'" prop = "计划完成时间[2]" width="120"/>
<el-table-column align="center" :label = "'工序3\n完成进度'" prop = "进度[2]" width="80"/>
<el-table-column align="center" :label = "'工序4\n工序名称'" prop = "工序名称[3]" width="80"/>
<el-table-column align="center" :label = "'工序4\n指派对象'" prop = "指派对象[3]" width="80"/>
<el-table-column align="center" :label = "'工序4\n开始时间'" prop = "计划开始时间[3]" width="120"/>
<el-table-column align="center" :label = "'工序4\n结束时间'" prop = "计划完成时间[3]" width="120"/>
<el-table-column align="center" :label = "'工序4\n完成进度'" prop = "进度[3]" width="80"/>
<el-table-column align="center" :label = "'工序5\n工序名称'" prop = "工序名称[4]" width="80"/>
<el-table-column align="center" :label = "'工序5\n指派对象'" prop = "指派对象[4]" width="80"/>
<el-table-column align="center" :label = "'工序5\n开始时间'" prop = "计划开始时间[4]" width="120"/>
<el-table-column align="center" :label = "'工序5\n结束时间'" prop = "计划完成时间[4]" width="120"/>
<el-table-column align="center" :label = "'工序5\n完成进度'" prop = "进度[4]" width="80"/> -->
</el-table>
</el-card>
</div>
</template>
<script>
export default {
data() {
return {
orderNo: '',
contractNo: '',
productCode: '',
productName: '',
processName: '',
nature: '',
productionStatus: '全部',
completionTime: [],
loading: false,
tableData: [],
selectedRow: null,
editDialogVisible: false,
editSubmitLoading: false,
currentRow: {},
editForm: {
优先级: '',
未完成说明: '',
派工特殊说明: ''
},
splitTaskDialogVisible: false,
splitTaskSubmitLoading: false,
stationOptions: [],
splitTaskForm: {
分配数量: 0,
指派对象: '',
指派对象编号: '',
派工特殊备注: '',
计划开始时间: '',
计划结束时间: '',
最晚开始时间: '',
任务概述: ''
}
}
},
created() {
var now = new Date()
var start = new Date(Date.UTC(now.getFullYear() - 2, now.getMonth(), now.getDate(), 0, 0, 0)).toISOString().replace('T', ' ').replace('.000Z', '')
var end = new Date(Date.UTC(now.getFullYear(), now.getMonth(), now.getDate(), 23, 59, 59)).toISOString().replace('T', ' ').replace('.000Z', '')
this.completionTime = [start, end]
this.searchTable()
},
methods: {
getHeaderClass({ row, rowIndex }) {
// row: 当前行的数据对象
// rowIndex: 当前行的索引从0开始
console.log(row)
if (row.绿 == 1) {
return 'warning-row'
}else if (row. === 1) {
return 'error-row';
}else if (row. === 1) {
return 'success-row';
}else{
return '';
}
},
formatDate(date) {
if (!date) return ''
return date.split(' ').length > 1 ? date.split(' ')[0] : date
},
mergeOrderData(dataList) {
const orderMap = new Map();
const opMap = new Map();
dataList.forEach(item => {
const orderNumber = item.订单号;
if (!orderMap.has(orderNumber) ) {
orderMap.set(orderNumber, {
...item,
// 需要累加的字段
// 指派数量: item.指派数量 || 0,
// 工序计划数量: item.工序计划数量 || 0,
// 计划数量: item.计划数量 || 0,
// 需要循环的字段
// 工序列表: [item.工序名称],
// 指派对象列表: [item.指派对象],
// 计划完成时间列表: [this.formatDate(item.计划完成时间)],
// 计划开始时间列表: [this.formatDate(item.计划开始时间)],
// 进度列表: [item.进度],
当前序:'',
开工时间:0,
序检:item.序检,
子数据:[{
工序名称:item.工序名称,
指派对象:item.指派对象,
计划完成时间:item.计划完成时间,
计划开始时间:item.计划开始时间,
进度:item.进度,
拆分内码:item.拆分内码,
计划数量:item.计划数量,
开工时间:item.开工时间,
绿:0,
:0,
:0,
}]
});
} else {
// 合并到现有项
// 累加数值字段
// existingItem.指派数量 += item.指派数量 || 0;
// existingItem.工序计划数量 += item.工序计划数量 || 0;
// existingItem.计划数量 += item.计划数量 || 0;
const existingItem = orderMap.get(orderNumber);
existingItem.子数据.push({
工序名称:item.工序名称,
指派对象:item.指派对象,
计划完成时间:item.计划完成时间,
计划开始时间:item.计划开始时间,
进度:item.进度,
拆分内码:item.拆分内码,
计划数量:item.计划数量,
开工时间:item.开工时间,
绿:0,
:0,
:0,
})
existingItem.子数据.forEach((element,index) => {
if(new Date(element.开工时间) > new Date('1900-01-01 00:00:00')){
element.绿 = 1
}else{
element.绿 = 0
}
if(element.进度 == 100){
element. = 1
element.绿 = 0
}else{
element. = 0
}
if(index>0){
if(new Date(element.开工时间) == new Date('1900-01-01 00:00:00') & existingItem.子数据[index-1].进度 == 100){
element. = 1
element.绿 = 0
}else{
element. = 0
}
}
});
if(item.进度 < 100 & item.进度 > 0){
existingItem.当前序 = item.工序名称
}
if(new Date(item.开工时间) > new Date('1900-01-01 00:00:00')){
existingItem.开工时间 = 1
}
}
});
this.tableData = Array.from(orderMap.values()).map(item => ({
// 基本信息
订单号: item.订单号,
合同号: item.合同号,
产品编码:item.产品编码,
产品名称:item.产品名称,
计划数量订单:item.计划数量订单,
要求完工日期:item.要求完工日期,
排产状态:item.排产状态,
优先级:item.优先级,
当前序:item.当前序,
计划数量: item.计划数量,
开工时间: item.开工时间,
序检:item.序检,
子数据:item.子数据,
}));
},
searchTable() {
this.loading = true
this.tableData = []
var param = []
param.push(['订单号', this.orderNo || 0])
param.push(['物料类型', '自制件'])
param.push(['合同号', this.contractNo])
param.push(['产品编码', this.productCode])
param.push(['产品名称', this.productName])
param.push(['工序名称', this.processName])
param.push(['性质', this.nature])
param.push(['要求完工日期1', this.completionTime ? this.completionTime[0] : ''])
param.push(['要求完工日期2', this.completionTime ? this.completionTime[1] : ''])
param.push(['排产状态', this.productionStatus])
var Data = this.CreateData('11', 'MES_OrderPlanned_Query', param)
this.ExecDatabase(Data).then(response => {
this.loading = false
if (response.data.length !== 0) {
this.mergeOrderData(response.data)
}
}).catch(() => {
this.loading = false
})
},
handleRowClick(row) {
this.selectedRow = row
},
editTask(row) {
this.currentRow = row
this.editForm = {
优先级: row.优先级 || '',
未完成说明: row.未完成说明 || '',
派工特殊说明: row.派工特殊说明 || ''
}
this.editDialogVisible = true
},
submitEditForm() {
this.editSubmitLoading = true
const params = []
params.push(['订单号', this.currentRow.订单号])
params.push(['订单行号', this.currentRow.订单行号])
params.push(['订单拆分内码', this.currentRow.拆分内码])
params.push(['优先级', this.editForm.优先级])
params.push(['未完成说明', this.editForm.未完成说明])
params.push(['派工特殊说明', this.editForm.派工特殊说明])
params.push(['最后编辑人', this.$store.state.user.name])
const Data = this.CreateData('12', 'MES_OrderPlanned_DescriptionEdit', params)
this.ExecDatabase(Data).then(() => {
this.$message.success('保存成功')
this.editDialogVisible = false
this.searchTable()
}).catch(() => {
this.$message.error('保存失败')
}).finally(() => {
this.editSubmitLoading = false
})
},
handleOutsourceNotify(row) {
this.$confirm('确认同计划发起外协通知吗?', '确认', {
confirmButtonText: '是',
cancelButtonText: '否',
type: 'warning',
center: true
}).then(() => {
this.$message.success('外协通知已发送')
}).catch(() => {
})
},
openSplitTask() {
if (!this.selectedRow) {
this.$message.warning('请先选择需要操作的行')
return
}
this.getStationList()
this.splitTaskForm = {
分配数量: this.selectedRow.计划数量 || 0,
指派对象: this.selectedRow.指派对象 || '',
指派对象编号: this.selectedRow.指派对象编号 || '',
派工特殊备注: this.selectedRow.派工特殊说明 || '',
计划开始时间: this.selectedRow.计划开始时间 || '',
计划结束时间: this.selectedRow.计划完成时间 || '',
最晚开始时间: this.selectedRow.最晚开始时间 || '',
任务概述: this.selectedRow.计划数量 || ''
}
this.splitTaskDialogVisible = true
},
submitSplitTaskForm() {
this.splitTaskSubmitLoading = true
this.$confirm('确认要拆分子任务吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
// 空逻辑
this.splitTaskSubmitLoading = false
this.splitTaskDialogVisible = false
this.$message.success('操作成功')
this.searchTable()
}).catch(() => {
this.splitTaskSubmitLoading = false
this.$message.info('已取消操作')
})
},
getStationList() {
const params = []
const Data = this.CreateData('11', 'Prog_MES_LoadStations', params)
this.ExecDatabase(Data).then(response => {
if (response.data && response.data.length > 0) {
this.stationOptions = response.data.map(item => ({
label: item.OPName,
value: item.OPName,
code: item.VisCode
}))
}
})
},
handleStationChange(value) {
const selected = this.stationOptions.find(item => item.value === value)
if (selected) {
this.splitTaskForm.指派对象编号 = selected.code
}
}
}
}
</script>
<style scoped>
::v-deep .el-table th.el-table__cell>.cell{
white-space: pre-wrap;
}
.process{
width: 120px;
display: inline-flex;
}
.search-container {
margin-bottom: 20px;
}
.show-text {
margin-right: 5px;
line-height: 32px;
}
.status-light {
display: inline-block;
width: 12px;
height: 12px;
border-radius: 50%;
}
.status-light-green {
background-color: #67C23A;
}
.status-light-gray {
background-color: #909399;
}
.dialog-footer {
text-align: right;
}
::v-deep .warning-row {
background-color: #67c23a !important;
}
::v-deep .error-row {
background-color: #409eff !important;
}
::v-deep .success-row {
background-color: #f2a201 !important;
}
::v-deep .el-table td.el-table__cell{
border: 0;
}
/* ::v-deep .el-table--enable-row-hover .el-table__body tr:hover > td {
background-color: initial !important;
} */
</style>

View File

@@ -0,0 +1,735 @@
<template>
<div>
<el-card>
<div class="search-container">
<span class="show-text">销售订单:</span>
<el-input v-model="contractNo" placeholder="请输入销售订单" clearable style="width: 150px;margin-right: 10px" />
<span class="show-text">生产订单:</span>
<el-input v-model="orderNo" placeholder="请输入生产订单" clearable style="width: 150px;margin-right: 10px" />
<span class="show-text">产品编码:</span>
<el-input v-model="productCode" placeholder="请输入产品编码" clearable style="width: 150px;margin-right: 10px" />
<span class="show-text">产品名称:</span>
<el-input v-model="productName" placeholder="请输入产品名称" clearable style="width: 150px;margin-right: 10px" />
<span class="show-text">工序名称:</span>
<el-input v-model="processName" placeholder="请输入工序名称" clearable style="width: 150px;margin-right: 10px" />
<br>
<br>
<span class="show-text">性质:&nbsp;&nbsp;&nbsp;</span>
<el-input v-model="nature" placeholder="请输入性质" clearable style="width: 150px;margin-right: 10px" />
<span class="show-text">要求完工日期:</span>
<el-date-picker v-model="completionTime" :clearable="false" end-placeholder="结束时间" format="yyyy-MM-dd"
range-separator="-" start-placeholder="开始时间" style="width: 230px;"type="datetimerange" value-format="yyyy-MM-dd" />
<span class="show-text">指派对象:</span>
<el-select v-model="Doing" multiple @change = "Doingform">
<el-option v-for="item in Doingoptions"
:key="item.指南工位号"
:label="item.指南工位号"
:value="item.工位号" />
</el-select>
<el-button :disabled="loading" icon="el-icon-search" plain type="primary"
@click="searchTable()">查询</el-button>
</div>
<!-- <div style="margin-top: 20px;">
<el-button :disabled="loading" plain type="primary" @click="openTaskAdjust()"
style="width: 100px;margin-left: 10px;">表单</el-button>
<el-button :disabled="loading" plain type="primary" @click="openTaskAdjust()"
style="width: 100px;">日程</el-button>
</div> -->
<el-tabs v-model="activeTab" type="card" class="custom-tabs">
<el-tab-pane label="表单" name="form">
<el-table v-loading="loading" :data="tableData" :height="'67vh'" border
element-loading-background="rgba(0, 0, 0, 0.2)" element-loading-spinner="el-icon-loading"
highlight-current-row size="mini" style="width: 100%;margin-top: 20px;" tooltip-effect="dark"
@row-click="handleRowClick">
<el-table-column align="center" label="序号" type="index" width="50" fixed />
<el-table-column align="center" prop="合同号" label="销售订单" width="120" fixed />
<el-table-column align="center" prop="订单号" label="生产订单" width="100" fixed />
<el-table-column align="center" prop="产品编码" label="零件编码" width="220" />
<el-table-column align="center" prop="产品名称" label="产品名称" width="190" />
<el-table-column align="center" prop="计划数量" label="计划数" width="80" />
<el-table-column align="center" prop="工序名称" label="工序名称" width="120" />
<el-table-column align="center" prop="性质" label="性质" width="100" />
<el-table-column align="center" prop="总工时" label="总工时" width="120" />
<el-table-column align="center" prop="占用情况" label="占用情况" width="120" />
<el-table-column align="center" prop="指派对象编号" label="指派对象编号" width="120" />
<el-table-column align="center" prop="指派对象" label="指派对象" width="120" />
<el-table-column align="center" prop="指派数量" label="指派数量" width="120" />
<el-table-column align="center" prop="计划开始时间" label="计划开始时间" width="120" />
<el-table-column align="center" prop="计划完成时间" label="计划完成时间" width="120" />
<el-table-column align="center" prop="最晚开始时间" label="最晚开始时间" width="120" />
<el-table-column align="center" label="要求完工日期" width="120">
<template slot-scope="scope">
{{ formatDate(scope.row.要求完工日期) }}
</template>
</el-table-column>
<el-table-column align="center" label="可执行" width="70">
<template slot-scope="scope">
<div class="status-light" :class="scope.row.可执行 ? 'status-light-green' : 'status-light-gray'" />
</template>
</el-table-column>
<el-table-column align="center" label="收料" width="70">
<template slot-scope="scope">
<div v-if =" scope.row.收料数量 < scope.row.计划数量 & scope.row.收料 == 1 " class="status-light status-light-orange" />
<div v-if =" scope.row.收料数量 >= scope.row.计划数量 & scope.row.收料 == 1 "class="status-light status-light-green " />
<div v-if ="!scope.row.收料"class="status-light status-light-gray" />
</template>
</el-table-column>
<el-table-column align="center" label="开工" width="70">
<template slot-scope="scope">
<div class="status-light" :class="scope.row.开工 ? 'status-light-green' : 'status-light-gray'" />
</template>
</el-table-column>
<el-table-column align="center" label="首检" width="70">
<template slot-scope="scope">
<div class="status-light" :class="scope.row.首检 ? 'status-light-green' : 'status-light-gray'" />
</template>
</el-table-column>
<el-table-column align="center" label="巡检" width="70">
<template slot-scope="scope">
<div class="status-light" :class="scope.row.巡检 ? 'status-light-green' : 'status-light-gray'" />
</template>
</el-table-column>
<el-table-column align="center" label="外协" width="70">
<template slot-scope="scope">
<div class="status-light" :class="scope.row.外协通知 ? 'status-light-orange' : 'status-light-gray'" />
</template>
</el-table-column>
<el-table-column align="center" label="派工调整" width="130">
<template slot-scope="scope">
<el-button type="primary" size="mini"
@click.stop="clickadjust(scope.row)">派工调整</el-button>
</template>
</el-table-column>
<el-table-column align="center" label="外协通知" width="130">
<template slot-scope="scope">
<el-button type="primary" size="mini" v-if="scope.row.外协通知==0"
@click.stop="handleOutsourceNotify(scope.row)">外协通知</el-button>
<el-button type="primary" size="mini" v-if="scope.row.外协通知==1">已发起</el-button>
</template>
</el-table-column>
<el-table-column align="center" label="进度" width="200">
<template slot-scope="scope">
<el-progress :percentage="scope.row.进度" />
</template>
</el-table-column>
<el-table-column align="center" prop="不合格数量" label="报废数" width="70" />
<el-table-column align="center" label="序检" width="70">
<template slot-scope="scope">
<div v-if =" scope.row.进度 == 100 & scope.row.序检 == 0 " class="status-light status-light-orange" />
<div v-else class="status-light" :class="scope.row.序检 ? 'status-light-green' : 'status-light-gray'" />
</template>
</el-table-column>
<el-table-column align="center" label="测试" width="70">
<template slot-scope="scope">
<div class="status-light" :class="scope.row.测试 ? 'status-light-green' : 'status-light-gray'" />
</template>
</el-table-column>
<el-table-column align="center" label="入库" width="70">
<template slot-scope="scope">
<div class="status-light" :class="scope.row.入库 ? 'status-light-green' : 'status-light-gray'" />
</template>
</el-table-column>
<el-table-column align="center" label="优先级" width="80">
<template slot-scope="scope">
<div class="status-light"
:class="scope.row.优先级 === '是' ? 'status-light-green' : 'status-light-gray'" />
</template>
</el-table-column>
<el-table-column align="center" prop="未完成说明" label="未完成说明" width="120" />
<el-table-column align="center" prop="派工特殊说明" label="派工特殊备注" width="120" />
<el-table-column align="center" label="编辑" width="120">
<template slot-scope="scope">
<el-button type="text" size="mini" @click="editTask(scope.row)">编辑</el-button>
</template>
</el-table-column>
<el-table-column align="center" prop="最后编辑人" label="最后编辑人" width="100" />
<el-table-column align="center" label="最后编辑时间" width="170">
<template slot-scope="scope">
{{ scope.row.最后编辑时间 }}
</template>
</el-table-column>
</el-table>
</el-tab-pane>
<el-tab-pane label="日程" name="schedule">
<div class="schedule-container">
<FullCalendar ref="fullCalendar" :options="calendarOptions" />
</div>
</el-tab-pane>
</el-tabs>
</el-card>
<!-- 派工调整 -->
<el-dialog :visible.sync="dialogadjust" :close-on-click-modal="false" :close-on-press-escape="false"
title="派工调整" center width="850px">
<el-form ref="formData" :model="formData" label-width="120px" size="mini">
<el-row>
<el-col :span="12">
<el-form-item label="指派对象" prop="指派对象">
<el-select v-model="formData.指派对象" placeholder="请选择" style="width: 100%" @change="handleStationChange">
<el-option v-for="item in stationOptions" :key="item.code" :label="item.label" :value="item.value" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="分配数量" prop="指派数量">
<el-input-number v-model="formData.指派数量" :min="1" :max="currentRow.计划数量" style="width: 100%" />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="计划开始时间" prop="计划开始时间">
<el-date-picker v-model="formData.计划开始时间" type="date" placeholder="选择日期" value-format="yyyy-MM-dd"
style="width: 100%" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="计划完成时间" prop="计划完成时间">
<el-date-picker v-model="formData.计划完成时间" type="date" placeholder="选择日期" value-format="yyyy-MM-dd"
style="width: 100%" />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="最晚开始时间" prop="最晚开始时间">
<el-date-picker v-model="formData.最晚开始时间" type="date" placeholder="选择日期" value-format="yyyy-MM-dd"
style="width: 100%" />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item label="派工特殊说明" prop="派工特殊说明">
<el-input v-model="formData.派工特殊说明" :rows="3" type="textarea" placeholder="请输入派工特殊说明" />
</el-form-item>
</el-col>
</el-row>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogadjust = false">取 消</el-button>
<el-button type="primary" @click="submitadjust">确 定</el-button>
</div>
</el-dialog>
<!-- 编辑备注弹窗 -->
<el-dialog :visible.sync="editDialogVisible" title="编辑任务信息" width="600px" center>
<el-form ref="editForm" :model="editForm" label-width="140px" size="mini">
<el-form-item label="优先级">
<el-select v-model="editForm.优先级" placeholder="请选择优先级" style="width: 100%">
<el-option label="" value="" />
<el-option label="" value="" />
</el-select>
</el-form-item>
<el-form-item label="未完成说明">
<el-input v-model="editForm.未完成说明" :rows="2" type="textarea" placeholder="请输入未完成说明" />
</el-form-item>
<el-form-item label="派工特殊备注">
<el-input v-model="editForm.派工特殊说明" :rows="3" type="textarea" placeholder="请输入派工特殊备注" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="editDialogVisible = false">取 消</el-button>
<el-button :loading="editSubmitLoading" type="primary" @click="submitEditForm">确 定</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
// 这三个组件用于绘制日历
import FullCalendar from '@fullcalendar/vue'
import dayGridPlugin from '@fullcalendar/daygrid'
import interactionPlugin from '@fullcalendar/interaction'
export default {
components: { FullCalendar },
data() {
return {
activeTab: 'form',
orderNo: '',
contractNo: '',
productCode: '',
productName: '',
processName: '',
nature: '',
station: '',
productionStatus: '全部',
completionTime: [],
loading: false,
tableData: [],
selectedRow: null,
editDialogVisible: false,
editSubmitLoading: false,
currentRow: {},
editForm: {
优先级: '',
未完成说明: '',
派工特殊说明: ''
},
taskAdjustVisible: false,
taskSubmitLoading: false,
stationOptions: [],
taskForm: {
指派对象: '',
指派对象编号: '',
指派数量: 0,
计划开始时间: '',
计划完成时间: '',
最晚开始时间: '',
派工特殊说明: ''
},
checkList: [],
Doingoptions:[],
Doing:"",
dialogadjust:false,
formData:[],
// FullCalendar 配置选项
calendarOptions: {
plugins: [dayGridPlugin, interactionPlugin], // 加载日视图和交互插件
initialView: 'dayGridMonth',
locale: 'zh-cn',
headerToolbar: {
left: 'prev,next today',
center: 'title',
right: 'today'
},
editable: true, // 允许通过拖拽或调整大小来修改事件
droppable: true,
events: [],
eventDrop: this.handleEventDrop, // 拖拽完成后回调
eventResize: this.handleEventResize, // 调整大小完成后回调
height: 'auto', // 设置高度为auto使其自适应内容
dayMaxEvents: true // 限制每天显示的事件数量
}
}
},
computed: {
calendarEvents() {
return this.tableData.map(item => ({
id: `${item.订单号}-${item.订单行号}-${item.拆分内码}`,
title: `${item.进度} | ${item.订单号} | ${item.产品名称} | ${item.产品编码} | 分配数量:${item.指派数量} | 序:${item.工序名称}`,
start: this.formatDateForCalendar(item.计划开始时间),
end: this.formatDateForCalendar(item.计划完成时间, true),
extendedProps: {
订单号: item.订单号,
订单行号: item.订单行号,
拆分内码: item.拆分内码,
}
}))
}
},
watch: {
activeTab(newVal) {
if (newVal === 'schedule') {
this.$nextTick(() => {
// 判断日历的HTML Dom 是否存在
const calendarApi = this.$refs.fullCalendar && this.$refs.fullCalendar.getApi()
if (calendarApi) {
// 重新绘制日历界面 避免出现未渲染问题
calendarApi.updateSize()
}
this.calendarOptions.events = this.calendarEvents
})
}
},
tableData: {
handler() {
this.calendarOptions.events = this.calendarEvents
if (this.activeTab === 'schedule') {
this.$nextTick(() => {
const calendarApi = this.$refs.fullCalendar && this.$refs.fullCalendar.getApi()
if (calendarApi) {
calendarApi.refetchEvents()
}
})
}
},
deep: true
}
},
created() {
var now = new Date()
var start = new Date(Date.UTC(now.getFullYear() - 1, now.getMonth(), now.getDate(), 0, 0, 0)).toISOString().replace('T', ' ').replace('.000Z', '')
var end = new Date(Date.UTC(now.getFullYear(), now.getMonth(), now.getDate(), 23, 59, 59)).toISOString().replace('T', ' ').replace('.000Z', '')
this.completionTime = [start, end]
this.searchTable()
this.getDoing()
},
methods: {
getDoing(){
var Data = this.CreateData('11', 'MES_登录_工位与名称_查询')
this.ExecDatabase(Data).then(response => {
this.loading = false
if (response.data.length !== 0) {
this.Doingoptions= response.data
}
})
},
Doingform(value){
console.log(value)
},
clickadjust(row){
this.dialogadjust = true
console.log(this)
this.formData = {
指派对象: row.指派对象,
指派对象编号: row.指派对象编号,
指派数量: row.计划数量,
计划开始时间: row.计划开始时间,
计划完成时间: row.计划完成时间,
最晚开始时间: row.最晚开始时间,
派工特殊说明: row.派工特殊说明
}
},
submitadjust(){
var row = this.selectedRow
const params = []
params.push(['订单号', row.订单号])
params.push(['订单行号', row.订单行号])
params.push(['订单拆分内码', row.拆分内码])
params.push(['指派对象编号', this.$refs.formData.model.指派对象编号])
params.push(['指派对象', this.$refs.formData.model.指派对象])
params.push(['指派数量', this.$refs.formData.model.指派数量])
params.push(['派工特殊说明', this.$refs.formData.model.派工特殊说明])
params.push(['计划开始时间', this.$refs.formData.model.计划开始时间])
params.push(['计划完成时间', this.$refs.formData.model.计划完成时间])
params.push(['最晚开始时间', this.$refs.formData.model.最晚开始时间])
params.push(['派工操作人', this.$store.state.user.name])
const Data = this.CreateData('12', 'MES_OrderPlanned_SingleTaskPlanned', params)
this.ExecDatabase(Data).then(response => {
this.dialogadjust = false
if (response.data[0].result !== '1') {
this.$message.error('派工失败')
return
}
this.$message.success('派工成功')
}).catch(() => {
})
},
formatDate(date) {
if (!date) return ''
return date.split(' ').length > 1 ? date.split(' ')[0] : date
},
WorkTimeSum(tdata) {
var param = []
param.push(['计划开工_Start', this.completionTime ? this.completionTime[0] : ''])
param.push(['计划开工_End', this.completionTime ? this.completionTime[1] : ''])
var Data = this.CreateData('11', 'MES_ProductTask_WorkTimeSum', param)
this.ExecDatabase(Data).then(response => {
this.loading = false
tdata.forEach(item => {
response.data.forEach(itemtime => {
if (itemtime.TaskAID == item.TaskAID & itemtime.工序名称 == item.工序名称) {
item.总工时 = itemtime.总工时
}
})
})
this.tableData = tdata
}).catch(() => {
this.loading = false
})
},
searchTable() {
this.loading = true
this.tableData = []
var param = []
console.log(this.Doing.toString())
param.push(['订单号', this.orderNo || 0])
param.push(['物料类型', '自制件'])
param.push(['合同号', this.contractNo])
param.push(['产品编码', this.productCode])
param.push(['产品名称', this.productName])
param.push(['工序名称', this.processName])
param.push(['性质', this.nature])
param.push(['要求完工日期1', this.completionTime ? this.completionTime[0] : ''])
param.push(['要求完工日期2', this.completionTime ? this.completionTime[1] : ''])
param.push(['排产状态', this.productionStatus])
param.push(['工位', this.Doing.toString()])
var Data = this.CreateData('11', 'MES_ProductAdmin_Query', param)
this.ExecDatabase(Data).then(response => {
this.loading = false
if (response.data.length !== 0) {
this.WorkTimeSum(response.data)
// this.tableData = response.data
}
}).catch(() => {
this.loading = false
})
},
handleRowClick(row) {
this.selectedRow = row
},
// 获取工位列表
getStationList() {
const params = []
const Data = this.CreateData('11', 'Prog_MES_LoadStations', params)
this.ExecDatabase(Data).then(response => {
if (response.data && response.data.length > 0) {
this.stationOptions = response.data.map(item => ({
label: item.OPName,
value: item.OPName,
code: item.VisCode
}))
}
})
},
// 处理工位选择
handleStationChange(value) {
const selected = this.stationOptions.find(item => item.value === value)
this.taskForm.指派对象编号 = selected ? selected.code : ''
},
// 提交派工调整
submitTaskForm() {
if (!this.selectedRow) {
this.$message.warning('未选择任务')
return
}
if (!this.taskForm.指派对象 || !this.taskForm.指派数量) {
this.$message.warning('请选择指派对象并设置指派数量')
return
}
this.taskSubmitLoading = true
const params = []
params.push(['订单号', this.selectedRow.订单号])
params.push(['订单行号', this.selectedRow.订单行号])
params.push(['订单拆分内码', this.selectedRow.拆分内码])
params.push(['指派对象编号', this.taskForm.指派对象编号])
params.push(['指派对象', this.taskForm.指派对象])
params.push(['指派数量', this.taskForm.指派数量])
params.push(['派工特殊说明', this.taskForm.派工特殊说明 || ''])
params.push(['计划开始时间', this.taskForm.计划开始时间 || ''])
params.push(['计划完成时间', this.taskForm.计划完成时间 || ''])
params.push(['最晚开始时间', this.taskForm.最晚开始时间 || ''])
params.push(['派工操作人', this.$store.state.user.name])
const Data = this.CreateData('12', 'Prog_MES_SingleTaskPlanned', params)
this.ExecDatabase(Data).then(response => {
if (response.data && response.data.length > 0 && response.data[0] && response.data[0].length > 0) {
this.$message.error('派工失败: ' + response.data[0])
return
}
this.$message.success('派工调整成功')
this.taskAdjustVisible = false
this.searchTable()
}).catch(() => {
this.$message.error('派工调整失败')
}).finally(() => {
this.taskSubmitLoading = false
})
},
editTask(row) {
this.currentRow = row
this.editForm = {
优先级: row.优先级 || '',
未完成说明: row.未完成说明 || '',
派工特殊说明: row.派工特殊说明 || ''
}
this.editDialogVisible = true
},
submitEditForm() {
this.editSubmitLoading = true
const params = []
params.push(['订单号', this.currentRow.订单号])
params.push(['订单行号', this.currentRow.订单行号])
params.push(['订单拆分内码', this.currentRow.拆分内码])
params.push(['优先级', this.editForm.优先级])
params.push(['未完成说明', this.editForm.未完成说明])
params.push(['派工特殊说明', this.editForm.派工特殊说明])
params.push(['最后编辑人', this.$store.state.user.name])
const Data = this.CreateData('12', 'MES_OrderPlanned_DescriptionEdit', params)
this.ExecDatabase(Data).then(() => {
this.$message.success('保存成功')
this.editDialogVisible = false
this.searchTable()
}).catch(() => {
this.$message.error('保存失败')
}).finally(() => {
this.editSubmitLoading = false
})
},
handleOutsourceNotify(row) {
this.$confirm('确认同计划发起外协通知吗?', '确认', {
confirmButtonText: '是',
cancelButtonText: '否',
type: 'warning',
center: true
}).then(() => {
const params = []
params.push(['TaskAID', row.TaskAID])
params.push(['外协通知', 1])
const Data = this.CreateData('12', 'MES_ProductTask_Notice', params)
this.ExecDatabase(Data).then(() => {
this.$message.success('外协通知已发送')
this.searchTable()
})
}).catch(() => {
})
},
openTaskAdjust() {
console.log('123')
},
// 格式化日期以适应 FullCalendar (需要 'yyyy-MM-dd')
formatDateForCalendar(date, isEnd = false) {
if (!date) return null
try {
let d
if (typeof date === 'string') {
// 如果是字符串,解析日期部分
const datePart = date.split(' ')[0]
const [year, month, day] = datePart.split('-').map(Number)
d = new Date(Date.UTC(year, month - 1, day))
} else if (date instanceof Date) {
d = new Date(date.getTime())
}
if (isEnd) {
d.setUTCDate(d.getUTCDate() + 1)
}
// 转换为 ISO 格式并取日期部分
const isoString = d.toISOString()
return isoString.split('T')[0]
} catch (error) {
console.error('Error formatting date for calendar:', date, error)
return null
}
},
// 处理日历事件拖拽完成后的逻辑
handleEventDrop(info) {
const event = info.event
const newStart = this.formatDateForCalendar(event.startStr)
const endDate = new Date(event.endStr)
endDate.setUTCDate(endDate.getUTCDate() - 1)
const newEnd = this.formatDateForCalendar(endDate)
this.updateTaskTime(event.extendedProps, newStart, newEnd, info.revert)
},
// 处理日历事件调整大小完成后
handleEventResize(info) {
const event = info.event
const newStart = this.formatDateForCalendar(event.startStr)
const endDate = new Date(event.endStr)
endDate.setUTCDate(endDate.getUTCDate() - 1)
const newEnd = this.formatDateForCalendar(endDate)
if (!newStart || !newEnd) {
this.$message.error('日期格式错误,无法更新')
info.revert()
return
}
this.updateTaskTime(event.extendedProps, newStart, newEnd, info.revert)
},
// 更新时间 传入 revert 回调用于失败时恢复事件位置
updateTaskTime(taskInfo, startTime, endTime, revertCallback) {
this.$confirm('确认修改计划时间?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
const params = []
var editstr = "[计划开始时间] = '"+ startTime+"' , [计划完成时间] = '"+ endTime+"'"
params.push(['editstr', editstr])
params.push(['订单号', taskInfo.订单号])
params.push(['订单行号', taskInfo.订单行号])
params.push(['订单拆分内码', taskInfo.拆分内码])
// params.push(['计划开始时间', startTime])
// params.push(['计划完成时间', endTime])
const Data = this.CreateData('12', 'MES_OrderPlanned_EditTaskPlanned', params)
this.ExecDatabase(Data).then(response => {
if (response.data[0].result !== '1') {
this.$message.error('计划时间更新失败')
if (revertCallback) revertCallback()
return
}
this.$message.success('计划时间更新成功')
this.searchTable()
this.donesearchTable()
})
}).catch(() => {
if (revertCallback) revertCallback()
})
}
}
}
</script>
<style scoped>
.search-container {
margin-bottom: 20px;
}
.show-text {
margin-right: 5px;
line-height: 32px;
}
.status-light {
display: inline-block;
width: 12px;
height: 12px;
border-radius: 50%;
}
.status-light-orange {
background-color: #e4a629;
}
.status-light-green {
background-color: #67C23A;
}
.status-light-gray {
background-color: #909399;
}
.dialog-footer {
text-align: right;
}
.schedule-container {
min-height: 67vh;
}
.schedule-container ::v-deep .fc-daygrid-day-frame {
padding: 2px;
min-height: auto;
}
.schedule-container ::v-deep .fc-event {
font-size: 12px;
padding: 1px 2px;
margin-bottom: 1px;
line-height: 1.4;
}
.schedule-container ::v-deep .fc-daygrid-event-harness {
margin-bottom: 1px;
}
.schedule-container ::v-deep .fc-daygrid-day-top {
padding: 2px;
}
.schedule-container ::v-deep .fc-daygrid-more-link {
font-size: 12px;
padding: 0 2px;
}
</style>

View File

@@ -0,0 +1,533 @@
<template>
<div>
<el-card>
<div class="search-container">
<span class="show-text">销售订单:</span>
<el-input v-model="contractNo" placeholder="请输入销售订单" clearable style="width: 150px;margin-right: 10px" />
<span class="show-text">生产订单:</span>
<el-input v-model="orderNo" placeholder="请输入生产订单" clearable style="width: 150px;margin-right: 10px" />
<span class="show-text">产品编码:</span>
<el-input v-model="productCode" placeholder="请输入产品编码" clearable style="width: 150px;margin-right: 10px" />
<span class="show-text">产品名称:</span>
<el-input v-model="productName" placeholder="请输入产品名称" clearable style="width: 150px;margin-right: 10px" />
<span class="show-text">工序名称:</span>
<el-input v-model="processName" placeholder="请输入工序名称" clearable style="width: 150px;margin-right: 10px" />
<br>
<br>
<span class="show-text">性质:&nbsp;&nbsp;&nbsp;</span>
<el-input v-model="nature" placeholder="请输入性质" clearable style="width: 150px;margin-right: 10px" />
<span class="show-text">要求完工日期:</span>
<el-date-picker v-model="completionTime" :clearable="false" end-placeholder="结束时间" format="yyyy-MM-dd"
range-separator="-" start-placeholder="开始时间" style="width: 230px;"type="datetimerange" value-format="yyyy-MM-dd" />
<span class="show-text">指派对象:</span>
<el-select v-model="Doing" multiple @change = "Doingform">
<el-option v-for="item in Doingoptions"
:key="item.指南工位号"
:label="item.指南工位号"
:value="item.工位号" />
</el-select>
<el-button :disabled="loading" icon="el-icon-search" plain type="primary"
@click="searchTable()">查询</el-button>
</div>
<el-tabs v-model="activeTab" type="card" class="custom-tabs">
<el-tab-pane label="表单" name="form">
<div v-for=" (items,itemsname ) in tableData2" >
<h3>{{ itemsname }}</h3> <!-- 显示组名 -->
<el-table v-loading="loading" :data="items" border
element-loading-background="rgba(0, 0, 0, 0.2)" element-loading-spinner="el-icon-loading"
highlight-current-row size="mini" style="width: 100%;margin-top: 20px;" tooltip-effect="dark"
@row-click="handleRowClick">
<el-table-column align="center" label="序号" type="index" width="50" fixed />
<el-table-column align="center" prop="合同号" label="销售订单" width="120" fixed />
<el-table-column align="center" prop="订单号" label="生产订单" width="100" fixed />
<el-table-column align="center" prop="产品编码" label="零件编码" width="220" />
<el-table-column align="center" prop="产品名称" label="产品名称" width="190" />
<el-table-column align="center" prop="计划数量" label="计划数" width="80" />
<el-table-column align="center" prop="工序名称" label="工序名称" width="120" />
<el-table-column align="center" prop="总工时" label="总工时" width="120" />
<el-table-column align="center" prop="占用情况" label="占用情况" width="120" />
<el-table-column align="center" prop="计划开始时间" label="计划开始时间" width="120" />
<el-table-column align="center" prop="计划完成时间" label="计划完成时间" width="120" />
<el-table-column align="center" prop="最晚开始时间" label="最晚开始时间" width="120" />
<el-table-column align="center" label="要求完工日期" width="120">
<template slot-scope="scope">
{{ formatDate(scope.row.要求完工日期) }}
</template>
</el-table-column>
<el-table-column align="center" label="收料" width="70">
<template slot-scope="scope">
<div v-if =" scope.row.收料数量 < scope.row.计划数量 & scope.row.收料 == 1 " class="status-light status-light-orange" />
<div v-if =" scope.row.收料数量 >= scope.row.计划数量 & scope.row.收料 == 1 "class="status-light status-light-green " />
<div v-if ="!scope.row.收料"class="status-light status-light-gray" />
</template>
</el-table-column>
<el-table-column align="center" label="进度" width="200">
<template slot-scope="scope">
<el-progress :percentage="scope.row.进度" />
</template>
</el-table-column>
<el-table-column align="center" label="序检" width="70">
<template slot-scope="scope">
<div v-if =" scope.row.进度 == 100 & scope.row.序检 == 0 " class="status-light status-light-orange" />
<div v-else class="status-light" :class="scope.row.序检 ? 'status-light-green' : 'status-light-gray'" />
</template>
</el-table-column>
<el-table-column align="center" label="优先级" width="80">
<template slot-scope="scope">
<div class="status-light"
:class="scope.row.优先级 === '是' ? 'status-light-green' : 'status-light-gray'" />
</template>
</el-table-column>
<el-table-column align="center" prop="未完成说明" label="未完成说明" width="120" />
<el-table-column align="center" prop="派工特殊说明" label="派工特殊备注" width="120" />
<el-table-column align="center" label="编辑" width="120">
<template slot-scope="scope">
<el-button type="text" size="mini" @click="editTask(scope.row)">编辑</el-button>
</template>
</el-table-column>
<el-table-column align="center" prop="最后编辑人" label="最后编辑人" width="100" />
<el-table-column align="center" label="最后编辑时间" width="170">
<template slot-scope="scope">
{{ scope.row.最后编辑时间 }}
</template>
</el-table-column>
</el-table>
</div>
</el-tab-pane>
<el-tab-pane label="日程" name="schedule">
<div class="schedule-container">
<FullCalendar ref="fullCalendar" :options="calendarOptions" />
</div>
</el-tab-pane>
</el-tabs>
</el-card>
<!-- 编辑备注弹窗 -->
<el-dialog :visible.sync="editDialogVisible" title="编辑任务信息" width="600px" center>
<el-form ref="editForm" :model="editForm" label-width="140px" size="mini">
<el-form-item label="优先级">
<el-select v-model="editForm.优先级" placeholder="请选择优先级" style="width: 100%">
<el-option label="" value="" />
<el-option label="" value="" />
</el-select>
</el-form-item>
<el-form-item label="未完成说明">
<el-input v-model="editForm.未完成说明" :rows="2" type="textarea" placeholder="请输入未完成说明" />
</el-form-item>
<el-form-item label="派工特殊备注">
<el-input v-model="editForm.派工特殊说明" :rows="3" type="textarea" placeholder="请输入派工特殊备注" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="editDialogVisible = false">取 消</el-button>
<el-button :loading="editSubmitLoading" type="primary" @click="submitEditForm">确 定</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
// 这三个组件用于绘制日历
import FullCalendar from '@fullcalendar/vue'
import dayGridPlugin from '@fullcalendar/daygrid'
import interactionPlugin from '@fullcalendar/interaction'
export default {
components: { FullCalendar },
data() {
return {
activeTab: 'form',
orderNo: '',
contractNo: '',
productCode: '',
productName: '',
processName: '',
nature: '',
station: '',
productionStatus: '全部',
completionTime: [],
loading: false,
tableData: [],
tableData2: [],
selectedRow: null,
editDialogVisible: false,
editSubmitLoading: false,
currentRow: {},
editForm: {
优先级: '',
未完成说明: '',
派工特殊说明: ''
},
taskAdjustVisible: false,
taskSubmitLoading: false,
stationOptions: [],
taskForm: {
指派对象: '',
指派对象编号: '',
指派数量: 0,
计划开始时间: '',
计划完成时间: '',
最晚开始时间: '',
派工特殊说明: ''
},
checkList: [],
Doingoptions:[],
Doing:"",
dialogadjust:false,
formData:[],
// FullCalendar 配置选项
calendarOptions: {
plugins: [dayGridPlugin, interactionPlugin], // 加载日视图和交互插件
initialView: 'dayGridMonth',
locale: 'zh-cn',
headerToolbar: {
left: 'prev,next today',
center: 'title',
right: 'today'
},
editable: true, // 允许通过拖拽或调整大小来修改事件
droppable: true,
events: [],
eventDrop: this.handleEventDrop, // 拖拽完成后回调
eventResize: this.handleEventResize, // 调整大小完成后回调
height: 'auto', // 设置高度为auto使其自适应内容
dayMaxEvents: true // 限制每天显示的事件数量
}
}
},
computed: {
calendarEvents() {
return this.tableData.map(item => ({
id: `${item.订单号}-${item.订单行号}-${item.拆分内码}`,
title: `${item.进度} | ${item.订单号} | ${item.产品名称} | ${item.产品编码} | 分配数量:${item.指派数量} | 序:${item.工序名称}`,
start: this.formatDateForCalendar(item.计划开始时间),
end: this.formatDateForCalendar(item.计划完成时间, true),
extendedProps: {
订单号: item.订单号,
订单行号: item.订单行号,
拆分内码: item.拆分内码,
}
}))
}
},
watch: {
activeTab(newVal) {
if (newVal === 'schedule') {
this.$nextTick(() => {
// 判断日历的HTML Dom 是否存在
const calendarApi = this.$refs.fullCalendar && this.$refs.fullCalendar.getApi()
if (calendarApi) {
// 重新绘制日历界面 避免出现未渲染问题
calendarApi.updateSize()
}
this.calendarOptions.events = this.calendarEvents
})
}
},
tableData: {
handler() {
this.calendarOptions.events = this.calendarEvents
if (this.activeTab === 'schedule') {
this.$nextTick(() => {
const calendarApi = this.$refs.fullCalendar && this.$refs.fullCalendar.getApi()
if (calendarApi) {
calendarApi.refetchEvents()
}
})
}
},
deep: true
}
},
created() {
var now = new Date()
var start = new Date(Date.UTC(now.getFullYear() - 1, now.getMonth(), now.getDate(), 0, 0, 0)).toISOString().replace('T', ' ').replace('.000Z', '')
var end = new Date(Date.UTC(now.getFullYear(), now.getMonth(), now.getDate(), 23, 59, 59)).toISOString().replace('T', ' ').replace('.000Z', '')
this.completionTime = [start, end]
this.searchTable()
this.getDoing()
},
methods: {
getDoing(){
var Data = this.CreateData('11', 'MES_登录_工位与名称_查询')
this.ExecDatabase(Data).then(response => {
this.loading = false
if (response.data.length !== 0) {
this.Doingoptions= response.data
}
})
},
Doingform(value){
console.log(value)
},
formatDate(date) {
if (!date) return ''
return date.split(' ').length > 1 ? date.split(' ')[0] : date
},
WorkTimeSum(tdata) {
var param = []
param.push(['计划开工_Start', this.completionTime ? this.completionTime[0] : ''])
param.push(['计划开工_End', this.completionTime ? this.completionTime[1] : ''])
var Data = this.CreateData('11', 'MES_ProductTask_WorkTimeSum', param)
this.ExecDatabase(Data).then(response => {
this.loading = false
tdata.forEach(item => {
response.data.forEach(itemtime => {
if (itemtime.TaskAID == item.TaskAID & itemtime.工序名称 == item.工序名称) {
item.总工时 = itemtime.总工时
}
})
})
var newtdata = tdata.reduce((acc, item) => {
const key = `${item.指派对象}【${item.计划开始时间}】`; // 创建一个唯一的键来区分不同的组
if(item.指派对象 ){
if (!acc[key]) {
acc[key] = []; // 如果键不存在,初始化一个空数组
}
acc[key].push(item); // 将当前项添加到对应的数组中
return acc
}
return acc
}, {}); // 初始值为一个空对象{}
this.tableData2 = newtdata
console.log(newtdata)
}).catch(() => {
this.loading = false
})
},
searchTable() {
this.loading = true
this.tableData = []
var param = []
param.push(['订单号', this.orderNo || 0])
param.push(['物料类型', '自制件'])
param.push(['合同号', this.contractNo])
param.push(['产品编码', this.productCode])
param.push(['产品名称', this.productName])
param.push(['工序名称', this.processName])
param.push(['性质', this.nature])
param.push(['要求完工日期1', this.completionTime ? this.completionTime[0] : ''])
param.push(['要求完工日期2', this.completionTime ? this.completionTime[1] : ''])
param.push(['排产状态', this.productionStatus])
param.push(['工位', this.Doing.toString()])
var Data = this.CreateData('11', 'MES_ProductAdmin_Query', param)
this.ExecDatabase(Data).then(response => {
this.loading = false
this.WorkTimeSum(response.data)
if (response.data.length !== 0) {
this.tableData = response.data
}
}).catch(() => {
this.loading = false
})
},
handleRowClick(row) {
this.selectedRow = row
console.log(row)
},
// 获取工位列表
getStationList() {
const params = []
const Data = this.CreateData('11', 'Prog_MES_LoadStations', params)
this.ExecDatabase(Data).then(response => {
if (response.data && response.data.length > 0) {
this.stationOptions = response.data.map(item => ({
label: item.OPName,
value: item.OPName,
code: item.VisCode
}))
}
})
},
// 处理工位选择
handleStationChange(value) {
const selected = this.stationOptions.find(item => item.value === value)
this.taskForm.指派对象编号 = selected ? selected.code : ''
},
// 提交派工调整
editTask(row) {
this.currentRow = row
this.editForm = {
优先级: row.优先级 || '',
未完成说明: row.未完成说明 || '',
派工特殊说明: row.派工特殊说明 || ''
}
this.editDialogVisible = true
},
submitEditForm() {
this.editSubmitLoading = true
const params = []
params.push(['订单号', this.currentRow.订单号])
params.push(['订单行号', this.currentRow.订单行号])
params.push(['订单拆分内码', this.currentRow.拆分内码])
params.push(['优先级', this.editForm.优先级])
params.push(['未完成说明', this.editForm.未完成说明])
params.push(['派工特殊说明', this.editForm.派工特殊说明])
params.push(['最后编辑人', this.$store.state.user.name])
const Data = this.CreateData('12', 'MES_OrderPlanned_DescriptionEdit', params)
this.ExecDatabase(Data).then(() => {
this.$message.success('保存成功')
this.editDialogVisible = false
this.searchTable()
}).catch(() => {
this.$message.error('保存失败')
}).finally(() => {
this.editSubmitLoading = false
})
},
// 格式化日期以适应 FullCalendar (需要 'yyyy-MM-dd')
formatDateForCalendar(date, isEnd = false) {
if (!date) return null
try {
let d
if (typeof date === 'string') {
// 如果是字符串,解析日期部分
const datePart = date.split(' ')[0]
const [year, month, day] = datePart.split('-').map(Number)
d = new Date(Date.UTC(year, month - 1, day))
} else if (date instanceof Date) {
d = new Date(date.getTime())
}
if (isEnd) {
d.setUTCDate(d.getUTCDate() + 1)
}
// 转换为 ISO 格式并取日期部分
const isoString = d.toISOString()
return isoString.split('T')[0]
} catch (error) {
console.error('Error formatting date for calendar:', date, error)
return null
}
},
// 处理日历事件拖拽完成后的逻辑
handleEventDrop(info) {
const event = info.event
const newStart = this.formatDateForCalendar(event.startStr)
const endDate = new Date(event.endStr)
endDate.setUTCDate(endDate.getUTCDate() - 1)
const newEnd = this.formatDateForCalendar(endDate)
this.updateTaskTime(event.extendedProps, newStart, newEnd, info.revert)
},
// 处理日历事件调整大小完成后
handleEventResize(info) {
const event = info.event
const newStart = this.formatDateForCalendar(event.startStr)
const endDate = new Date(event.endStr)
endDate.setUTCDate(endDate.getUTCDate() - 1)
const newEnd = this.formatDateForCalendar(endDate)
if (!newStart || !newEnd) {
this.$message.error('日期格式错误,无法更新')
info.revert()
return
}
this.updateTaskTime(event.extendedProps, newStart, newEnd, info.revert)
},
// 更新时间 传入 revert 回调用于失败时恢复事件位置
updateTaskTime(taskInfo, startTime, endTime, revertCallback) {
this.$confirm('确认修改计划时间?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
const params = []
var editstr = "[计划开始时间] = '"+ startTime+"' , [计划完成时间] = '"+ endTime+"'"
params.push(['editstr', editstr])
params.push(['订单号', taskInfo.订单号])
params.push(['订单行号', taskInfo.订单行号])
params.push(['订单拆分内码', taskInfo.拆分内码])
// params.push(['计划开始时间', startTime])
// params.push(['计划完成时间', endTime])
const Data = this.CreateData('12', 'MES_OrderPlanned_EditTaskPlanned', params)
this.ExecDatabase(Data).then(response => {
if (response.data[0].result !== '1') {
this.$message.error('计划时间更新失败')
if (revertCallback) revertCallback()
return
}
this.$message.success('计划时间更新成功')
this.searchTable()
this.donesearchTable()
})
}).catch(() => {
if (revertCallback) revertCallback()
})
}
}
}
</script>
<style scoped>
.search-container {
margin-bottom: 20px;
}
.show-text {
margin-right: 5px;
line-height: 32px;
}
.status-light {
display: inline-block;
width: 12px;
height: 12px;
border-radius: 50%;
}
.status-light-orange {
background-color: #e4a629;
}
.status-light-green {
background-color: #67C23A;
}
.status-light-gray {
background-color: #909399;
}
.dialog-footer {
text-align: right;
}
/* .schedule-container {
min-height: 67vh;
} */
.schedule-container ::v-deep .fc-daygrid-day-frame {
padding: 2px;
min-height: auto;
}
.schedule-container ::v-deep .fc-event {
font-size: 12px;
padding: 1px 2px;
margin-bottom: 1px;
line-height: 1.4;
}
.schedule-container ::v-deep .fc-daygrid-event-harness {
margin-bottom: 1px;
}
.schedule-container ::v-deep .fc-daygrid-day-top {
padding: 2px;
}
.schedule-container ::v-deep .fc-daygrid-more-link {
font-size: 12px;
padding: 0 2px;
}
</style>

View File

@@ -0,0 +1,390 @@
<template>
<div class="app-container">
<el-card>
<!-- 添加新班次按钮 -->
<div >
<el-button type="primary" icon="el-icon-plus" @click="handleAddShift" style="width: auto;">添加新班次</el-button>
</div>
<div style="margin-top: 10px">
<el-table
v-loading="loading"
:data="tableData"
border
element-loading-background="rgba(0, 0, 0, 0.2)"
element-loading-spinner="el-icon-loading"
element-loading-text="数据加载中"
height="694"
highlight-current-row
size="mini"
stripe
style="width: 100%"
tooltip-effect="dark">
<el-table-column align="center" label="序号" type="index" width="60"/>
<el-table-column align="center" label="班次" width="120">
<template slot-scope="scope">
<el-input
v-if="scope.row.isEditing"
v-model="scope.row.班次名称"
size="mini"
placeholder="请输入班次名称"
/>
<span v-else>{{ scope.row.班次名称 }}</span>
</template>
</el-table-column>
<el-table-column align="center" label="时间" width="300">
<template slot-scope="scope">
<div v-if="scope.row.isEditing" style="display: flex; align-items: center; gap: 5px">
<el-time-picker
v-model="scope.row.开始时间"
placeholder="开始时间"
format="HH:mm"
value-format="HH:mm"
size="mini"
style="width: 120px"
/>
<span>-</span>
<el-time-picker
v-model="scope.row.结束时间"
placeholder="结束时间"
format="HH:mm"
value-format="HH:mm"
size="mini"
style="width: 120px"
/>
</div>
<span v-else>{{ scope.row.开始时间 }} - {{ scope.row.结束时间 }}</span>
</template>
</el-table-column>
<el-table-column align="center" label="绑定人员" width="300">
<template slot-scope="scope">
<el-tag
v-for="person in scope.row.绑定人员列表"
:key="person.人员编号"
style="margin: 2px"
type="info">
{{ person.人员姓名 }}
</el-tag>
<span v-if="!scope.row.绑定人员列表 || scope.row.绑定人员列表.length === 0">未绑定人员</span>
</template>
</el-table-column>
<el-table-column align="center" label="操作" width="320">
<template slot-scope="scope">
<el-button
v-if="!scope.row.isEditing"
icon="el-icon-edit"
style="font-family: MiSans Regular,serif;color: #409EFF"
type="text"
@click="handleEditShift(scope.row)">编辑
</el-button>
<el-button
v-else
icon="el-icon-check"
style="font-family: MiSans Regular,serif;color: #67C23A"
type="text"
@click="handleSaveShift(scope.row)">保存
</el-button>
<el-button
v-if="scope.row.isEditing"
icon="el-icon-close"
style="font-family: MiSans Regular,serif;color: #F56C6C"
type="text"
@click="handleCancelEdit(scope.row)">取消
</el-button>
<el-button
icon="el-icon-user"
style="font-family: MiSans Regular,serif;color: #67c23a"
type="text"
@click="handleBindPerson(scope.row)">绑定
</el-button>
<el-button
icon="el-icon-delete"
style="font-family: MiSans Regular,serif;color: #F56C6C"
type="text"
@click="handleDeleteShift(scope.row)">删除
</el-button>
</template>
</el-table-column>
</el-table>
</div>
</el-card>
<!-- 绑定人员对话框 -->
<el-dialog :visible.sync="dialogBindPersonVisible" center title="绑定人员" width="600px">
<el-divider style="margin: 0"/>
<div style="margin: 20px 0">
<span>当前班次: {{ currentShift.班次名称 }} ({{ currentShift.开始时间 }} - {{ currentShift.结束时间 }})</span>
</div>
<el-transfer
v-model="selectedPersonnel"
:data="personnelList"
:titles="['可选人员', '已选人员']"
filterable
style="text-align: left"
@change="handleTransferChange">
</el-transfer>
<div slot="footer" style="text-align: center; margin-top: 20px">
<el-button type="primary" @click="submitBindPerson"> </el-button>
<el-button @click="dialogBindPersonVisible = false"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
export default {
data() {
return {
loading: false,
tableData: [],
dialogBindPersonVisible: false,
currentShift: {},
personnelList: [],
selectedPersonnel: [],
originalData: {} // 用于保存编辑前的数据
}
},
created() {
this.searchData()
this.loadPersonnelList()
},
methods: {
// 查询班次数据
searchData() {
this.loading = true
this.tableData = []
var param = []
var Data = this.CreateData('11', '生产管理_班次管理_班次列表查询', param)
this.ExecDatabase(Data).then(response => {
if (response.data && response.data.length !== 0) {
// 添加编辑状态字段
this.tableData = response.data.map(item => ({
...item,
isEditing: false
}))
this.loadBoundPersonnelForShifts()
} else {
this.loading = false
}
}).catch(() => {
this.loading = false
})
},
// 加载所有人员列表
loadPersonnelList() {
var param = []
var Data = this.CreateData('11', '系统管理_人员管理_所有有效人员查询', param)
this.ExecDatabase(Data).then(response => {
if (response.data && response.data.length > 0) {
this.personnelList = response.data.map(person => ({
key: person.人员编号,
label: `${person.人员姓名} (${person.账号})`,
disabled: false
}))
}
})
},
// 为所有班次加载绑定的人员信息
loadBoundPersonnelForShifts() {
console.log('开始加载班次绑定人员信息...')
const promises = this.tableData.map((shift, index) => {
return new Promise((resolve) => {
var param = []
param[0] = ['班次编号', shift.班次编号]
var Data = this.CreateData('11', '生产管理_班次管理_班次绑定人员查询', param)
this.ExecDatabase(Data).then(response => {
let boundPersonnel = []
if (response.data && Array.isArray(response.data)) {
boundPersonnel = response.data
} else if (response.result && Array.isArray(response.result)) {
boundPersonnel = response.result
} else if (response.data && response.data.result && Array.isArray(response.data.result)) {
boundPersonnel = response.data.result
}
this.$set(shift, '绑定人员列表', boundPersonnel)
resolve()
}).catch((error) => {
console.error(`加载班次 ${shift.班次名称} 绑定人员失败:`, error)
this.$set(shift, '绑定人员列表', [])
resolve()
})
})
})
Promise.all(promises).then(() => {
console.log('所有班次绑定人员加载完成')
this.loading = false
})
},
// 编辑班次
handleEditShift(row) {
this.originalData[row.班次编号] = { ...row }
row.isEditing = true
},
// 保存班次
handleSaveShift(row) {
if (!row.班次名称) {
this.$message.error('请输入班次名称')
return
}
if (!row.开始时间 || !row.结束时间) {
this.$message.error('请设置班次时间')
return
}
var param = []
param[0] = ['班次编号', row.班次编号]
param[1] = ['班次名称', row.班次名称]
param[2] = ['开始时间', row.开始时间]
param[3] = ['结束时间', row.结束时间]
param[4] = ['操作人', this.$store.state.user.name]
var Data = this.CreateData('11', '生产管理_班次管理_班次保存', param)
this.ExecDatabase(Data).then(response => {
if (response.data[0].执行结果 === 1) {
this.$message.success('班次保存成功')
row.isEditing = false
delete this.originalData[row.班次编号]
// 如果是新增的班次,重新加载数据获取正确的班次编号
if (row.班次编号.startsWith('NEW_')) {
this.searchData()
}
} else {
this.$message.error('班次保存失败: ' + response.data[0].提示信息)
}
}).catch(() => {
this.$message.error('班次保存失败')
})
},
// 取消编辑
handleCancelEdit(row) {
if (this.originalData[row.班次编号]) {
Object.assign(row, this.originalData[row.班次编号])
delete this.originalData[row.班次编号]
}
row.isEditing = false
// 如果是新增的班次且取消编辑,则从列表中移除
if (row.班次编号.startsWith('NEW_')) {
const index = this.tableData.findIndex(item => item.班次编号 === row.班次编号)
if (index !== -1) {
this.tableData.splice(index, 1)
}
}
},
// 添加新班次
handleAddShift() {
const newShift = {
班次编号: 'NEW_' + Date.now(),
班次名称: '',
开始时间: '08:00',
结束时间: '17:00',
绑定人员列表: [],
isEditing: true
}
this.tableData.unshift(newShift)
this.originalData[newShift.班次编号] = { ...newShift }
},
// 删除班次
handleDeleteShift(row) {
this.$confirm(`确定要删除班次"${row.班次名称}"吗?`, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
var param = []
param[0] = ['班次编号', row.班次编号]
var Data = this.CreateData('11', '生产管理_班次管理_班次删除', param)
this.ExecDatabase(Data).then(response => {
if (response.data[0].执行结果 === 1) {
this.$message.success('班次删除成功')
this.searchData() // 刷新数据
} else {
this.$message.error('班次删除失败: ' + response.data[0].提示信息)
}
}).catch(() => {
this.$message.error('班次删除失败')
})
}).catch(() => {
this.$message.info('已取消删除')
})
},
// 绑定人员
handleBindPerson(row) {
this.currentShift = { ...row }
this.dialogBindPersonVisible = true
var param = []
param[0] = ['班次编号', row.班次编号]
var Data = this.CreateData('11', '生产管理_班次管理_班次绑定人员查询', param)
this.ExecDatabase(Data).then(response => {
if (response.data && response.data.length > 0) {
this.selectedPersonnel = response.data.map(person => person.人员编号)
} else {
this.selectedPersonnel = []
}
})
},
// 提交人员绑定
submitBindPerson() {
if (!this.currentShift.班次编号) {
this.$message.error('班次信息错误')
return
}
var param = []
param[0] = ['班次编号', this.currentShift.班次编号]
param[1] = ['人员编号列表', this.selectedPersonnel.join(',')]
param[2] = ['操作人', this.$store.state.user.name]
var Data = this.CreateData('11', '生产管理_班次管理_班次绑定人员保存', param)
this.ExecDatabase(Data).then(response => {
if (response.data[0].执行结果 === 1) {
this.$message.success('人员绑定成功')
this.dialogBindPersonVisible = false
this.searchData() // 刷新数据
} else {
this.$message.error('人员绑定失败: ' + response.data[0].提示信息)
}
}).catch(() => {
this.$message.error('人员绑定失败')
})
},
// 传输框变化处理
handleTransferChange(value, direction, movedKeys) {
console.log('传输框变化:', value, direction, movedKeys)
}
}
}
</script>
<style scoped>
.el-card {
margin: 0px;
}
.el-transfer {
display: flex;
justify-content: center;
}
.el-input {
width: 100%;
}
</style>

View File

@@ -0,0 +1,708 @@
<template>
<div>
<el-card>
<div class="search-container">
<span class="show-text">开始时间范围:</span>
<el-date-picker
v-model="timeRange"
type="datetimerange"
range-separator=""
start-placeholder="开始时间"
end-placeholder="结束时间"
format="yyyy-MM-dd HH:mm:ss"
value-format="yyyy-MM-dd HH:mm:ss"
style="width: 360px; margin-right: 10px" />
<span class="show-text">校验状态:</span>
<el-select v-model="checkStatus" @change="searchTable" style="width: 120px; margin-right: 10px">
<el-option label="全部" value="2" />
<el-option label="已校验" value="1" />
<el-option label="未校验" value="0" />
</el-select>
<el-button :disabled="!!loading" icon="el-icon-search" plain type="primary" @click="searchTable()">查询</el-button>
<el-button :disabled="!!multipleSelection.length === 0 || loading" icon="el-icon-check" plain type="success" style="width: 100px;" @click="batchValidate">一键校验</el-button>
<el-button :disabled="!!loading" icon="el-icon-plus" plain type="warning" style="width: 130px;" @click="addWorkTimeRecord">新增工时记录</el-button>
</div>
<el-tabs v-model="activeTab" type="card" class="custom-tabs">
<el-table
v-loading="loading"
:data="tableData"
:height="'67vh'"
border
element-loading-background="rgba(0, 0, 0, 0.2)"
element-loading-spinner="el-icon-loading"
highlight-current-row
size="mini"
style="width: 100%;margin-top: 20px;"
tooltip-effect="dark"
@row-click="handleRowClick"
@selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column align="center" label="序号" type="index" width="50" fixed />
<el-table-column align="center" prop="指派对象" label="人员" width="120" fixed />
<el-table-column align="center" prop="订单号" label="生产订单" width="100" fixed />
<el-table-column align="center" prop="产品编码" label="物料编码" width="220" />
<el-table-column align="center" prop="产品名称" label="物料名称" width="190" />
<el-table-column align="center" prop="工序名称" label="工序名称" width="120" />
<el-table-column align="center" prop="工位名称" label="工位名称" width="120" />
<el-table-column align="center" prop="操作类别" label="报工类型" width="120" />
<el-table-column align="center" prop="操作数值" label="数量" width="120" />
<el-table-column align="center" label="开始时间" width="160">
<template slot-scope="scope">
{{ formatDateTime(scope.row.开始时间) }}
</template>
</el-table-column>
<el-table-column align="center" label="结束时间" width="160">
<template slot-scope="scope">
{{ formatDateTime(scope.row.结束时间) }}
</template>
</el-table-column>
<el-table-column align="center" label="加工工时" width="100">
<template slot-scope="scope">
{{ scope.row.加工工时 || 0 }}
</template>
</el-table-column>
<!-- <el-table-column align="center" label="要求完工日期" width="160">
<template slot-scope="scope">
{{ formatDateTime(scope.row.要求完工日期) }}
</template>
</el-table-column> -->
<el-table-column align="center" label="校验状态" width="80">
<template slot-scope="scope">
<el-tag :type="scope.row.已校验 ? 'success' : 'info'" size="mini">
{{ scope.row.已校验 ? '已校验' : '未校验' }}
</el-tag>
</template>
</el-table-column>
<el-table-column align="center" prop="最后编辑人" label="最后编辑人" width="100" />
<el-table-column align="center" label="最后编辑时间" width="160">
<template slot-scope="scope">
{{ formatDateTime(scope.row.最后编辑时间) }}
</template>
</el-table-column>
<el-table-column align="center" label="操作" width="120" fixed="right">
<template slot-scope="scope">
<el-button
type="text"
size="mini"
:disabled="!!scope.row.已校验"
@click="editTask(scope.row)">
{{ scope.row.已校验 ? '已校验' : '校验' }}
</el-button>
</template>
</el-table-column>
</el-table>
</el-tabs>
</el-card>
<!-- 编辑时间弹窗 -->
<el-dialog
:visible.sync="editDialogVisible"
:title="currentTask.已校验 ? '查看任务信息' : '编辑任务信息'"
width="700px"
center
:close-on-click-modal="false">
<el-form ref="editForm" :model="editForm" label-width="120px" size="mini" :disabled="!!currentTask.已校验">
<el-form-item label="生产订单">
<el-input v-model="editForm.订单编号" readonly />
</el-form-item>
<el-form-item label="物料编码">
<el-input v-model="editForm.产品编码" readonly />
</el-form-item>
<el-form-item label="物料名称">
<el-input v-model="editForm.产品名称" readonly />
</el-form-item>
<el-form-item label="工序名称">
<el-input v-model="editForm.工序名称" readonly />
</el-form-item>
<el-form-item label="指派对象">
<el-input v-model="editForm.指派对象" readonly />
</el-form-item>
<el-form-item label="开始时间" required>
<el-date-picker
v-model="editForm.开始时间"
type="datetime"
placeholder="选择开始时间"
value-format="yyyy-MM-dd HH:mm:ss"
style="width: 100%"
@change="calculateWorkTime" />
</el-form-item>
<el-form-item label="结束时间" required>
<el-date-picker
v-model="editForm.结束时间"
type="datetime"
placeholder="选择结束时间"
value-format="yyyy-MM-dd HH:mm:ss"
style="width: 100%"
@change="calculateWorkTime" />
</el-form-item>
<el-form-item label="加工工时">
<el-input v-model="editForm.加工工时" readonly>
<template slot="append"></template>
</el-input>
</el-form-item>
<!-- <el-form-item label="要求完工日期">
<el-date-picker
v-model="editForm.要求完工日期"
type="datetime"
placeholder="选择要求完工日期"
value-format="yyyy-MM-dd HH:mm:ss"
style="width: 100%"
readonly />
</el-form-item> -->
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="editDialogVisible = false">关闭</el-button>
<el-button
v-if="!currentTask.已校验"
:loading="editSubmitLoading"
type="primary"
@click="submitEditForm"
:disabled="!editForm.开始时间 || !editForm.结束时间">
</el-button>
</div>
</el-dialog>
<!-- 新增工时记录弹窗 -->
<el-dialog
:visible.sync="addRecordDialogVisible"
title="新增工时记录"
width="700px"
center
:close-on-click-modal="false">
<el-form ref="addRecordForm" :model="addRecordForm" label-width="120px" size="mini" :rules="addRecordRules">
<el-form-item label="操作类别" prop="操作类别">
<el-select v-model="addRecordForm.操作类别" placeholder="请选择操作类别" style="width: 100%">
<el-option label="收料" value="收料" />
<el-option label="辅助开始" value="辅助开始" />
<el-option label="辅助结束" value="辅助结束" />
<el-option label="开始加工" value="开始加工" />
<el-option label="暂停" value="暂停" />
<el-option label="报工" value="报工" />
</el-select>
</el-form-item>
<el-form-item label="生产订单" prop="订单编号">
<el-select
v-model="addRecordForm.订单编号"
placeholder="请选择订单编号"
style="width: 100%"
@change="handleOrderChange"
filterable>
<el-option
v-for="order in orderList"
:key="order.订单编号"
:label="order.订单编号"
:value="order.订单编号" />
</el-select>
</el-form-item>
<el-form-item label="物料编码">
<el-input v-model="addRecordForm.产品编码" readonly />
</el-form-item>
<el-form-item label="物料名称">
<el-input v-model="addRecordForm.产品名称" readonly />
</el-form-item>
<el-form-item label="工序名称" prop="工序名称">
<el-select
v-model="addRecordForm.工序名称"
placeholder="请选择工序名称"
style="width: 100%">
<el-option
v-for="process in processList"
:key="process.工序名称"
:label="process.工序名称"
:value="process.工序名称" />
</el-select>
</el-form-item>
<el-form-item label="指派对象" prop="指派对象">
<el-input v-model="addRecordForm.指派对象" placeholder="请输入操作人员" />
</el-form-item>
<el-form-item label="开始时间" prop="开始时间">
<el-date-picker
v-model="addRecordForm.开始时间"
type="datetime"
placeholder="选择开始时间"
value-format="yyyy-MM-dd HH:mm:ss"
style="width: 100%" />
</el-form-item>
<el-form-item label="结束时间" prop="结束时间">
<el-date-picker
v-model="addRecordForm.结束时间"
type="datetime"
placeholder="选择结束时间"
value-format="yyyy-MM-dd HH:mm:ss"
style="width: 100%" />
</el-form-item>
<el-form-item label="工作内容">
<el-input v-model="addRecordForm.操作内容" :rows="2" type="textarea" placeholder="请输入工作内容" />
</el-form-item>
<el-form-item label="备注说明">
<el-input v-model="addRecordForm.操作描述" :rows="3" type="textarea" placeholder="请输入备注说明" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="addRecordDialogVisible = false">取消</el-button>
<el-button :loading="addRecordLoading" type="primary" @click="submitAddRecord"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { postB1 } from '@/api/b1s';
import { getB1 } from '@/api/b1s';
import { patchB1 } from '@/api/b1s';
export default {
name: 'WorkTimeValidation',
data() {
return {
// 搜索条件
timeRange: [],
checkStatus: '',
// 表格数据
loading: false,
activeTab: 'first',
tableData: [],
multipleSelection: [],
// 编辑弹窗
editDialogVisible: false,
editSubmitLoading: false,
currentTask: {},
editForm: {
订单编号: '',
产品编码: '',
产品名称: '',
工位名称: '',
工序名称: '',
指派对象: '',
开始时间: '',
结束时间: '',
加工工时: 0,
要求完工日期: ''
},
// 新增相关数据
orderList: [], // 订单列表
processList: [], // 工序列表
// 新增工时记录
addRecordDialogVisible: false,
addRecordLoading: false,
addRecordForm: {
操作类别: '',
订单编号: '',
产品编码: '',
产品名称: '',
工序名称: '',
指派对象: '',
开始时间: '',
结束时间: '',
操作内容: '',
操作描述: ''
},
addRecordRules: {
操作类别: [{ required: true, message: '请选择操作类别', trigger: 'change' }],
订单编号: [{ required: true, message: '请选择订单编号', trigger: 'change' }],
工序名称: [{ required: true, message: '请选择工序名称', trigger: 'change' }],
指派对象: [{ required: true, message: '请输入操作人员', trigger: 'blur' }],
开始时间: [{ required: true, message: '请选择开始时间', trigger: 'change' }],
结束时间: [{ required: true, message: '请选择结束时间', trigger: 'change' }]
},
currentTime:'',
currentdate:''
}
},
mounted() {
this.searchTable()
this.loadOrderList()
},
methods: {
// 加载订单列表
loadOrderList() {
var Data = this.CreateData('11', '工时校验_获取订单列表', [])
this.ExecDatabase(Data).then(response => {
this.orderList = response.data || []
}).catch(error => {
console.error('加载订单列表失败:', error)
this.orderList = []
})
},
// 订单选择变化事件
handleOrderChange(orderId) {
if (orderId) {
// 自动填充零件编码和零件名称
const selectedOrder = this.orderList.find(order => order.订单编号 == orderId)
if (selectedOrder) {
this.addRecordForm.产品编码 = selectedOrder.零件编码
this.addRecordForm.产品名称 = selectedOrder.零件名称
}
// 加载该订单的工序列表
this.loadProcessList(orderId)
} else {
this.addRecordForm.产品编码 = ''
this.addRecordForm.产品名称 = ''
this.processList = []
}
},
// 加载工序列表
loadProcessList(orderId) {
var param = [['订单编号', orderId]]
var Data = this.CreateData('11', '工时校验_获取订单工序', param)
this.ExecDatabase(Data).then(response => {
this.processList = response.data || []
// 如果只有一个工序,自动选择
if (this.processList.length === 1) {
this.addRecordForm.工序名称 = this.processList[0].工序名称
}
}).catch(error => {
console.error('加载工序列表失败:', error)
this.processList = []
})
},
// 搜索表格
searchTable() {
this.loading = true;
var param = [];
if (this.timeRange && this.timeRange.length === 2) {
param[0] = ['开始时间', this.timeRange[0]];
param[1] = ['结束时间', this.timeRange[1]];
}
param[param.length] = ['校验状态', this.checkStatus];
var Data = this.CreateData('11', '工时校验_获取操作记录列表', param);
this.ExecDatabase(Data).then(response => {
this.tableData = response.data || [];
this.loading = false;
}).catch(error => {
this.$message.error('查询失败:' + error.message);
this.loading = false;
});
},
// 处理行点击
handleRowClick(row) {
this.currentTask = row
},
// 处理多选
handleSelectionChange(val) {
this.multipleSelection = val
},
// 编辑/查看任务
editTask(row) {
this.currentTask = row
this.editForm = {
订单编号: row.订单号,
产品编码: row.产品编码,
产品名称: row.产品名称,
工序名称: row.工序名称,
工位名称: row.工位名称,
指派对象: row.指派对象,
开始时间: row.开始时间,
结束时间: row.结束时间,
加工工时: row.加工工时 || 0,
要求完工日期: row.要求完工日期
}
this.editDialogVisible = true
},
// 计算加工工时(秒)
calculateWorkTime() {
if (this.editForm.开始时间 && this.editForm.结束时间) {
const start = new Date(this.editForm.开始时间)
const end = new Date(this.editForm.结束时间)
const diff = end.getTime() - start.getTime()
this.editForm.加工工时 = Math.round(diff / 1000) // 转换为秒
} else {
this.editForm.加工工时 = 0
}
},
// 提交编辑表单
submitEditForm() {
var param = [
['TaskAID', this.currentTask.AID],
['开始时间', this.editForm.开始时间],
['结束时间', this.editForm.结束时间],
['工时', this.editForm.加工工时],
['操作人', this.getCurrentUser()],
['最后编辑人', this.getCurrentUser()]
];
var Data = this.CreateData('11', '工时校验_保存校验记录', param);
this.ExecDatabase(Data).then(response => {
this.$message.success('校验成功');
this.editDialogVisible = false;
this.submitMaterialRequisition(this.editForm)
this.searchTable();
});
},
getCurrentTime() {
const now = new Date();
const year = now.getFullYear();
const month = String(now.getMonth() + 1).padStart(2, "0"); // 月份从0开始需要加1
const day = String(now.getDate()).padStart(2, "0");
const hours = String(now.getHours()).padStart(2, "0");
const minutes = String(now.getMinutes()).padStart(2, "0");
const seconds = String(now.getSeconds()).padStart(2, "0");
this.currentTime = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
this.currentdate = `${year}-${month}-${day}`;
},
async submitMaterialRequisition(data) {
console.log(data)
this.getCurrentTime()
var param = []
var result = await getB1("/ProductionOrders",{
"$filter":"AbsoluteEntry eq " +data.订单编号+""
})
console.log(result)
var LineNumberarr = result.data.value[0].ProductionOrderLines
var BaseLine = ''
console.log(this.editForm.工位名称)
LineNumberarr.forEach(element => {
if(element.ItemName == this.editForm.工位名称){
BaseLine = element.LineNumber
}
});
if(data.加工工时 != 0){
param.push({
"Quantity": Number(data.加工工时),
"BaseType": 202,
"BaseEntry": Number(data.订单编号),
"BaseLine":BaseLine,
"LineType": "dlt_Resource",
"WarehouseCode":'',
"AccountCode": "5001010100"
})
}
postB1("/InventoryGenExits",{
"DocDate": this.currentdate,
"DocDueDate": this.currentdate,
"Comments": '',
"DocumentLines": param
})
},
// 一键校验
batchValidate() {
if (this.multipleSelection.length === 0) {
this.$message.warning('请选择要校验的记录')
return
}
// 过滤出未校验的记录
const unvalidatedRecords = this.multipleSelection.filter(item => !item.已校验)
if (unvalidatedRecords.length === 0) {
this.$message.warning('选中的记录都已校验过')
return
}
this.$confirm(`确定要校验选中的 ${unvalidatedRecords.length} 条未校验记录吗?`, '提示', {
type: 'warning'
}).then(() => {
this.loading = true
const aidList = unvalidatedRecords.map(item => item.AID).join(',')
var param = [
['TaskAID列表', aidList],
['操作人', this.getCurrentUser()],
['最后编辑人', this.getCurrentUser()]
]
this.batchsap(unvalidatedRecords)
var Data = this.CreateData('11', '工时校验_批量保存校验记录', param)
this.ExecDatabase(Data).then(response => {
this.$message.success(`成功校验 ${unvalidatedRecords.length} 条记录`)
this.searchTable() // 刷新表格
this.multipleSelection = [] // 清空选择
}).catch(error => {
this.$message.error('批量校验失败:' + error.message)
}).finally(() => {
this.loading = false
})
})
},
async batchsap(batchdata){
this.getCurrentTime()
console.log(batchdata)
batchdata.forEach(async data => {
var result = await getB1("/ProductionOrders",{
"$filter":"AbsoluteEntry eq " +data.订单号+""
})
console.log(result)
var LineNumberarr = result.data.value[0].ProductionOrderLines
var BaseLine = ''
var param = []
LineNumberarr.forEach(element => {
if(element.ItemName == data.工位名称){
BaseLine = element.LineNumber
}
});
if(data.加工工时 != 0){
param.push({
"Quantity": Number(data.加工工时),
"BaseType": 202,
"BaseEntry": Number(data.订单号),
"BaseLine":BaseLine,
"LineType": "dlt_Resource",
"WarehouseCode":'',
"AccountCode": "5001010100"
})
}
console.log(param)
postB1("/InventoryGenExits",{
"DocDate": this.currentdate,
"DocDueDate": this.currentdate,
"Comments": '',
"DocumentLines": param
})
});
},
// 新增工时记录
addWorkTimeRecord() {
this.addRecordForm = {
操作类别: '',
订单编号: '',
产品编码: '',
产品名称: '',
工序名称: '',
指派对象: '',
开始时间: '',
结束时间: '',
操作内容: '',
操作描述: ''
}
this.processList = []
this.addRecordDialogVisible = true
this.$nextTick(() => {
this.$refs.addRecordForm.clearValidate()
})
},
// 提交新增记录
// 提交新增记录(修改后的)
submitAddRecord() {
this.$refs.addRecordForm.validate((valid) => {
if (valid) {
this.addRecordLoading = true
// 计算工时(秒)
let workTime = 0
if (this.addRecordForm.开始时间 && this.addRecordForm.结束时间) {
const start = new Date(this.addRecordForm.开始时间)
const end = new Date(this.addRecordForm.结束时间)
const diff = end.getTime() - start.getTime()
workTime = Math.round(diff / 1000)
}
const recordData = {
...this.addRecordForm,
工时: workTime,
操作人: this.getCurrentUser(),
报工日期: new Date().toISOString().split('T')[0]
}
// 调用新增API
var param = [
['操作类别', this.addRecordForm.操作类别],
['订单编号', this.addRecordForm.订单编号],
['物料编号', this.addRecordForm.产品编码],
['物料描述', this.addRecordForm.产品名称],
['工序名称', this.addRecordForm.工序名称],
['工位名称', this.addRecordForm.指派对象], // 使用指派对象作为工位名称
['操作人', this.getCurrentUser()],
['开始时间', this.addRecordForm.开始时间],
['结束时间', this.addRecordForm.结束时间],
['操作内容', this.addRecordForm.操作内容],
['操作描述', this.addRecordForm.操作描述]
]
var Data = this.CreateData('11', '工时校验_新增操作记录', param)
this.ExecDatabase(Data).then(response => {
this.$message.success('新增成功')
this.addRecordDialogVisible = false
this.searchTable() // 刷新表格
}).catch(error => {
this.$message.error('新增失败:' + error.message)
}).finally(() => {
this.addRecordLoading = false
})
}
})
},
// 获取当前用户
getCurrentUser() {
console.log(this)
return this.$store.state.user.name
},
// 日期时间格式化(精确到秒)
formatDateTime(dateTime) {
if (!dateTime) return ''
const date = new Date(dateTime)
return date.toLocaleString('zh-CN', {
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
hour12: false
}).replace(/\//g, '-')
}
}
}
</script>
<style scoped>
.search-container {
display: flex;
align-items: center;
flex-wrap: wrap;
gap: 10px;
}
.show-text {
white-space: nowrap;
}
.custom-tabs {
margin-top: 10px;
}
.dialog-footer {
text-align: center;
}
</style>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,298 @@
<template>
<div>
<el-card>
<div>
<el-menu mode="horizontal" :default-active="activeIndex" router>
<el-menu-item index="/QualityManagement/CheckTask/firstSpecial"
>首检专检</el-menu-item
>
<el-menu-item index="/QualityManagement/CheckTask/processSpecial"
>序检专检</el-menu-item
>
<el-menu-item index="/QualityManagement/CheckTask/final"
>终检</el-menu-item
>
<el-menu-item index="/QualityManagement/CheckTask/purchaseIncoming"
>采购入库检</el-menu-item
>
<el-menu-item index="/QualityManagement/CheckTask/salesReturn"
>销售退货检</el-menu-item
>
<el-menu-item index="/QualityManagement/CheckTask/materialReturn"
>原材料退库检</el-menu-item
>
<el-menu-item index="/QualityManagement/CheckTask/processReceive"
>序检收检</el-menu-item
>
</el-menu>
</div>
</el-card>
<el-card>
<div class="search-container">
<span class="show-text">工序:</span>
<el-select
v-model="process"
placeholder="请选择工序"
clearable
style="width: 150px; margin-right: 10px"
>
<el-option
v-for="item in processList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
<span class="show-text">工位:</span>
<el-select
v-model="station"
clearable
placeholder="请选择工位"
style="width: 150px; margin-right: 10px"
>
<el-option
v-for="item in StationList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
<span class="show-text">生产订单:</span>
<el-input
v-model="orderNo"
placeholder="请输入生产订单"
clearable
style="width: 150px; margin-right: 10px"
/>
<span class="show-text">零件编号:</span>
<el-input
v-model="partNo"
placeholder="请输入零件编号"
clearable
style="width: 150px; margin-right: 10px"
/>
<span class="show-text">操作时间:</span>
<el-date-picker
v-model="operationTime"
:clearable="false"
end-placeholder="结束时间"
format="yyyy-MM-dd"
popper-class="virtual-cell-time-picker"
range-separator="-"
start-placeholder="开始时间"
style="width: 280px; vertical-align: top"
type="datetimerange"
value-format="yyyy-MM-dd"
/>
<el-button
:disabled="loading"
icon="el-icon-search"
plain
type="primary"
@click="searchTable()"
>查询</el-button
>
</div>
<el-table
v-loading="loading"
:data="tableData"
:height="'67vh'"
border
element-loading-background="rgba(0, 0, 0, 0.2)"
element-loading-spinner="el-icon-loading"
highlight-current-row
size="mini"
style="width: 100%; margin-top: 20px"
tooltip-effect="dark"
>
<el-table-column
align="center"
label="序号"
type="index"
width="50"
fixed
/>
<el-table-column align="center" label="工位编号" width="100">
<template slot-scope="scope">
{{ scope.row.工位编号 }}
</template>
</el-table-column>
<el-table-column align="center" label="工序名称" width="100">
<template slot-scope="scope">
{{ scope.row.工序名称 }}
</template>
</el-table-column>
<el-table-column align="center" label="操作类别" width="100">
<template slot-scope="scope">
{{ scope.row.操作类别 }}
</template>
</el-table-column>
<el-table-column align="center" label="操作人" width="80">
<template slot-scope="scope">
{{ scope.row.操作人 }}
</template>
</el-table-column>
<el-table-column align="center" label="销售订单" width="80">
<template slot-scope="scope">
{{ scope.row.合同号 }}
</template>
</el-table-column>
<el-table-column align="center" label="生产订单" width="80">
<template slot-scope="scope">
{{ scope.row.订单编号 }}
</template>
</el-table-column>
<el-table-column align="center" label="物料编号" width="200">
<template slot-scope="scope">
{{ scope.row.物料编号 }}
</template>
</el-table-column>
<el-table-column align="center" label="物料名称" width="200">
<template slot-scope="scope">
{{ scope.row.物料描述 }}
</template>
</el-table-column>
<el-table-column align="center" label="操作数值" width="100">
<template slot-scope="scope">
{{ scope.row.操作数值 }}
</template>
</el-table-column>
<el-table-column align="center" label="开始时间" width="180">
<template slot-scope="scope">
{{ scope.row.开始时间 }}
</template>
</el-table-column>
<el-table-column align="center" label="结束时间" width="180">
<template slot-scope="scope">
{{ scope.row.结束时间 }}
</template>
</el-table-column>
<el-table-column align="center" label="工时(分)" width="80">
<template slot-scope="scope">
{{ scope.row.工时 }}
</template>
</el-table-column>
</el-table>
</el-card>
</div>
</template>
<script>
export default {
data() {
return {
activeTab: "form",
orderNo: "",
partNo: "",
productCode: "",
productName: "",
processName: "",
process: "",
processList: [],
station: "",
StationList: [],
operationTime: [],
loading: false,
tableData: [],
};
},
created() {
var now = new Date();
var start = new Date(
Date.UTC(now.getFullYear() - 1, now.getMonth(), now.getDate(), 0, 0, 0)
)
.toISOString()
.replace("T", " ")
.replace(".000Z", "");
var end = new Date(
Date.UTC(now.getFullYear(), now.getMonth(), now.getDate(), 23, 59, 59)
)
.toISOString()
.replace("T", " ")
.replace(".000Z", "");
this.operationTime = [start, end];
this.getProcessList();
this.getStationList();
this.searchTable();
},
computed: {
activeIndex() {
return this.$route.path;
},
},
methods: {
// 初始化获取工序信息
getProcessList() {
this.processList = [];
var Data = this.CreateData("11", "Prog_MES_LoadProcess");
this.ExecDatabase(Data).then((response) => {
for (let i = 0; i < response.data.length; i++) {
this.processList.push({
label: response.data[i].工序名称,
value: response.data[i].工艺编号,
});
}
});
},
// 初始化获取工位信息
getStationList() {
this.StationList = [];
var Data = this.CreateData("11", "Prog_MES_LoadStations");
this.ExecDatabase(Data).then((response) => {
for (let i = 0; i < response.data.length; i++) {
this.StationList.push({
label: response.data[i].OPName,
value: response.data[i].VisCode,
});
}
});
},
searchTable() {
this.loading = true;
this.tableData = [];
var param = [];
param.push(["ProcessID", this.process]);
param.push(["OPCode", this.station]);
param.push(["OrderNo", this.orderNo]);
param.push(["PartCode", this.partNo]);
param.push([
"PlanStart",
this.operationTime ? this.operationTime[0] : "",
]);
param.push(["PlanEnd", this.operationTime ? this.operationTime[1] : ""]);
param.push(["不装配", 1]);
var Data = this.CreateData(
"11",
"MES_QulityInspection_FirstCheckRecords",
param
);
this.ExecDatabase(Data)
.then((response) => {
this.loading = false;
console.log("查询结果:", response.data);
if (response.data && response.data.length !== 0) {
this.tableData = response.data;
} else {
console.log("查询结果为空");
}
})
.catch((error) => {
this.loading = false;
console.error("查询出错:", error);
});
},
},
};
</script>
<style scoped lang="scss">
.search-container {
margin-bottom: 20px;
}
</style>

View File

@@ -0,0 +1,772 @@
<template>
<div>
<el-card>
<div>
<el-menu mode="horizontal" :default-active="activeIndex" router>
<!-- <el-menu-item index="/QualityManagement/CheckTask/firstSpecial"
>首检专检</el-menu-item
>
<el-menu-item index="/QualityManagement/CheckTask/processSpecial"
>序检专检</el-menu-item
> -->
<el-menu-item index="/QualityManagement/CheckTask/final"
>终检</el-menu-item
>
<el-menu-item index="/QualityManagement/CheckTask/purchaseIncoming"
>采购入库检</el-menu-item
>
<el-menu-item index="/QualityManagement/CheckTask/salesReturn"
>销售退货检</el-menu-item
>
<el-menu-item index="/QualityManagement/CheckTask/materialReturn"
>原材料退库检</el-menu-item
>
<el-menu-item index="/QualityManagement/CheckTask/processReceive"
>序检收检</el-menu-item
>
</el-menu>
</div>
</el-card>
<el-card>
<div class="search-container">
<span class="show-text">生产订单:</span>
<el-input
v-model="orderNo"
placeholder="请输入生产订单"
clearable
style="width: 150px; margin-right: 10px"
/>
<span class="show-text">物料名称:</span>
<el-input
v-model="partName"
placeholder="请输入物料名称"
clearable
style="width: 150px; margin-right: 10px"
/>
<span class="show-text">物料编码:</span>
<el-input
v-model="partNo"
placeholder="请输入物料编号"
clearable
style="width: 150px; margin-right: 10px"
/>
<span class="show-text">检测日期:</span>
<el-date-picker
v-model="inspectionDate"
:clearable="false"
end-placeholder="结束时间"
format="yyyy-MM-dd"
range-separator="-"
start-placeholder="开始时间"
style="width: 280px; vertical-align: top"
type="datetimerange"
value-format="yyyy-MM-dd"
/>
<!-- <span class="show-text">计划完工日期:</span>
<el-date-picker
v-model="completionTime"
:clearable="false"
end-placeholder="结束时间"
format="yyyy-MM-dd"
range-separator="-"
start-placeholder="开始时间"
style="width: 280px; vertical-align: top"
type="datetimerange"
value-format="yyyy-MM-dd"
/> -->
<br />
<br />
<span class="show-text">检测结果</span>
<el-select
v-model="inspectionResult"
clearable
style="width: 150px; margin-right: 10px"
filterable
>
<el-option label="合格" value="1" />
<el-option label="不合格" value="0" />
</el-select>
<span class="show-text">检测人:</span>
<el-select
v-model="checker"
placeholder="请选择检测人"
clearable
style="width: 150px; margin-right: 10px"
filterable
>
<el-option
v-for="item in checkerList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
<!-- <span class="show-text">检测类别:</span>
<el-select
v-model="type"
placeholder="请选择检测类别"
clearable
style="width: 150px; margin-right: 10px"
filterable
>
<el-option
v-for="item in typeList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select> -->
<el-button
:disabled="loading"
icon="el-icon-search"
plain
type="primary"
@click="searchTable()"
>查询
</el-button>
<!-- <el-button
type="success"
icon="el-icon-download"
plain
:disabled="tableData.length === 0"
@click="exportToExcel"
>导出</el-button
> -->
</div>
<el-table
v-loading="loading"
:data="tableData"
:height="'67vh'"
border
element-loading-background="rgba(0, 0, 0, 0.2)"
element-loading-spinner="el-icon-loading"
highlight-current-row
size="mini"
style="width: 100%; margin-top: 20px"
tooltip-effect="dark"
>
<el-table-column
align="center"
label="序号"
type="index"
width="50"
fixed
/>
<el-table-column
align="center"
label="生产订单"
width="80"
prop="生产订单号"
/>
<el-table-column
align="center"
label="物料名称"
width="150"
prop="名称"
/>
<el-table-column
align="center"
label="物料编码"
width="150"
prop="编码"
/>
<el-table-column
align="center"
label="数量"
width="80"
prop="数量"
/>
<el-table-column
align="center"
label="批次"
width="80"
prop="批次信息"
/>
<el-table-column label="操作" align="center" width="250">
<template slot-scope="scope">
<el-button
class="operation-btn"
type="primary"
size="mini"
@click="receiveCheck(scope.row)"
>退库检</el-button
>
</template>
</el-table-column>
</el-table>
</el-card>
<!-- 收检对话框 -->
<el-dialog
title="入库检"
:visible.sync="receiveCheckVisible"
width="60%"
style="text-align: center"
>
<el-form
ref="receiveCheckForm"
:model="receiveCheckData"
label-position="right"
label-width="140px"
size="mini"
>
<div>
<div class="info-container">
<div class="info-item">
<span class="info-label">物料名称</span>
<span class="info-value">{{ receiveCheckData.零件名称 }}</span>
</div>
<div class="info-item">
<span class="info-label">物料编码</span>
<span class="info-value">{{ receiveCheckData.零件编码 }}</span>
</div>
</div>
</div>
<div>
<div class="info-container">
<div class="info-item">
<span class="info-label">生产订单</span>
<span class="info-value">{{ receiveCheckData.订单号 }}</span>
</div>
<div class="info-item">
<span class="info-label">数量</span>
<span class="info-value">{{ receiveCheckData.数量 }}</span>
</div>
</div>
</div>
<div>
<div class="info-container">
<div class="info-item">
<span class="info-label"> 检测数量</span>
<span class="info-value">{{ receiveCheckData.数量 }}</span>
</div>
<div class="info-item">
<span class="info-label"> 合格数</span>
<el-input-number
v-model="receiveCheckData.合格数"
size="mini"
:min="0"
:max="receiveCheckData.检测数量"
style="width: 200px"
@change="handleQualifiedChange"
/>
</div>
</div>
</div>
<div>
<div class="info-container">
<div class="info-item">
<span class="info-label"> 不合格数</span>
<el-input-number
v-model="receiveCheckData.不合格数"
size="mini"
:min="0"
:max="receiveCheckData.检测数量"
style="width: 200px"
/>
</div>
<div class="info-item">
<span class="info-label"> 检验人</span>
<el-select
v-model="receiveCheckData.检测人"
placeholder="请选择检验人"
clearable
style="width: 200px"
filterable
>
<el-option
v-for="item in checkerList"
:key="item.value"
:label="item.label"
:value="item.label"
/>
</el-select>
</div>
</div>
</div>
<div>
<div class="info-container">
<div class="info-item">
<span class="info-label"> 检验时间</span>
<el-date-picker
v-model="receiveCheckData.检测时间"
type="datetime"
placeholder="选择检验时间"
format="yyyy-MM-dd HH:mm:ss"
value-format="yyyy-MM-dd HH:mm:ss"
style="width: 120px"
class="info-value"
/>
</div>
<div class="info-item">
<span class="info-label"> 检测说明</span>
<el-input
v-model="receiveCheckData.检测说明"
type="textarea"
:rows="2"
placeholder="请输入检测说明"
style="width: 120px"
class="info-value"
/>
</div>
</div>
</div>
</el-form>
<div slot="footer">
<el-button type="primary" @click="confirmReceiveCheck"> </el-button>
<el-button @click="receiveCheckVisible = false"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
// 引入xlsx库
import * as XLSX from "xlsx";
import {posttm} from '@/api/tm'
import {getB1} from '@/api/b1s'
export default {
data() {
return {
contractNo: "",
orderNo: "",
partNo: "",
partName: "",
completionTime: "",
inspectionDate: "",
type: "",
typeList: [],
checker: "",
checkerLabel: "",
checkerList: [],
inspectionResult: "",
tableData: [],
loading: false,
selectedRow: null,
receiveCheckVisible: false,
receiveCheckData: {
// 基本信息(从行数据获取)
零件名称: "",
内部合同号: "",
零件编码: "",
计划号: "",
工序名称: "",
计划完成时间: "",
计划生产数: 0,
TaskAID: "",
// 收检数据(用户输入)
检测数量: 0,
合格数: 0,
不合格数: 0,
检测人: "",
检测时间: "",
检测说明: "",
},
};
},
created() {
this.getTypeList();
this.getCheckerList();
this.searchTable();
var now = new Date();
var start = new Date(
Date.UTC(now.getFullYear() , now.getMonth(), now.getDate())
)
.toISOString()
.replace("T", " ")
.replace(".000Z", "");
var end = new Date(
Date.UTC(now.getFullYear(), now.getMonth(), now.getDate(), 23, 59, 59)
)
.toISOString()
.replace("T", " ")
.replace(".000Z", "");
this.completionTime= [start, end];
},
computed: {
activeIndex() {
return this.$route.path;
},
},
methods: {
getTypeList() {
this.typeList = [];
var Data = this.CreateData("11", "查询字典");
this.ExecDatabase(Data).then((response) => {
for (let i = 0; i < response.data.length; i++) {
if (response.data[i].数据类别 === "检测类型") {
this.typeList.push({
label: response.data[i].词条名称,
value: response.data[i].词条编号,
});
}
}
});
},
getCheckerList() {
this.checkerList = [];
var Data = this.CreateData("11", "人员管理_人员信息查询_质检部门_查询");
this.ExecDatabase(Data).then((response) => {
for (let i = 0; i < response.data.length; i++) {
this.checkerList.push({
label: response.data[i].Personnel_Name,
value: response.data[i].Personnel_Number,
});
}
});
},
searchTable() {
// 开始加载状态,清空表格数据和选中行
this.loading = true;
this.tableData = [];
// 构建基础查询参数
var param = [];
// param.push(["合同号", this.contractNo]);
// param.push(["订单号", this.orderNo]);
// param.push(["零件编号", this.partNo]);
// param.push(["零件名称", this.partName]);
// // 添加完工日期范围参数
// param.push([
// "完工日期_Start",
// this.completionTime ? this.completionTime[0] : "",
// ]);
// param.push([
// "完工日期_End",
// this.completionTime ? this.completionTime[1] : "",
// ]);
// // 添加检测日期范围参数
// param.push([
// "检测日期_Start",
// this.inspectionDate ? this.inspectionDate[0] : "",
// ]);
// param.push([
// "检测日期_End",
// this.inspectionDate ? this.inspectionDate[1] : "",
// ]);
// param.push(["检测结果", this.inspectionResult]);
// const selectedChecker = this.checkerList.find(
// (item) => item.value === this.checker
// );
// param.push(["检测人", selectedChecker ? selectedChecker.label : ""]);
// param.push(["检测类别", this.type]);
// 调用封装方法生成请求数据 - 使用新的存储过程名称
var Data = this.CreateData(
"11",
"质量管理_原材料退库_查询",
param
);
// 执行数据库请求
this.ExecDatabase(Data)
.then((response) => {
this.loading = false;
console.log(response.data);
if (response.data && response.data.length !== 0) {
this.tableData = response.data;
} else {
this.tableData = [];
this.$message.info("未查询到相关数据");
}
})
.catch((error) => {
this.loading = false;
console.error("查询失败:", error);
this.$message.error("查询失败");
});
},
receiveCheck(row) {
// 打开收检对话框并填充数据
this.receiveCheckVisible = true;
// 从行数据填充基本信息
this.receiveCheckData = {
// 基本信息(从行数据获取)
零件编码: row.编码 || "",
零件名称: row.名称 || "",
订单号: row.生产订单号 || "",
数量:row.数量,
检测数量:row.数量,
id:row.id
};
console.log(this.receiveCheckData);
},
handleQualifiedChange(value) {
// 自动计算不合格数
console.log(this.receiveCheckData.检测数量)
this.receiveCheckData.不合格数 = this.receiveCheckData.检测数量 - value;
},
confirmReceiveCheck() {
// 验证表单
if (
!this.receiveCheckData.检测数量 ||
this.receiveCheckData.检测数量 <= 0
) {
this.$message.warning("请输入有效的检测数量");
return;
}
if (!this.receiveCheckData.检测人) {
this.$message.warning("请选择检验人");
return;
}
if (!this.receiveCheckData.检测时间) {
this.$message.warning("请选择检验时间");
return;
}
// 调用存储过程保存数据
this.saveReceiveCheck();
},
transformData(rawArray) {
// 先转成对象便于取值
const map = {};
for (const [key, value] of rawArray) {
map[key] = value;
}
const taskItemsArray = map.task_items;
const taskMap = {};
for (const [k, v] of taskItemsArray) {
taskMap[k] = v;
}
const materialsArray = taskMap.task_materials_items;
const materialsMap = {};
for (const [k, v] of materialsArray) {
materialsMap[k] = v;
}
return {
doc_date: map.doc_date, // 或 new Date().toISOString().split('T')[0]
doc_type: map.doc_type,
external_num: taskMap.external_num,
udf8:map.udf8,
task_items: [
{
base_line_num :taskMap.base_line_num,
base_entry :taskMap.base_entry,
base_type: taskMap.base_type,
external_num: taskMap.external_num,
item_code: taskMap.item_code,
item_name: taskMap.item_name,
whs_code: '', // 原值被清空
manage_type: taskMap.manage_type,
price: taskMap.price,
quantity: taskMap.quantity,
task_materials_items: [
{
item_code: taskMap.item_code, // 新增:继承 item_code
batch_number: '', // 原 null 改为空字符串
quantity: materialsMap.quantity
}
]
}
]
};
},
// 如果需要转成 JSON 字符串
async saveReceiveCheck() {
var param = [];
var param2 = [];
var param3 = [];
param.push(["doc_date", this.completionTime[0]]);
param.push(["doc_type", "202-60"]);
param.push(["udf8", this.receiveCheckData.id]);
param.push(["external_num", this.receiveCheckData.订单号.toString()]);
param.push(["task_items", param2]);
param2.push(["base_type", "202"]);
param2.push(["external_num", this.receiveCheckData.订单号.toString()])
param2.push(["item_code", this.receiveCheckData.零件编码]);
param2.push(["item_name", this.receiveCheckData.零件名称]);
param2.push(["whs_code", ""]);
param2.push(["manage_type", 'B']);
param2.push(["price", 0]);
param2.push(["quantity", this.receiveCheckData.合格数]);
param2.push(["task_materials_items", param3]);
param3.push(["item_code", this.receiveCheckData.零件编码]);
param3.push(["batch_number", ""]);
param3.push(["quantity", this.receiveCheckData.合格数]);
var LineNumber = ''
var result3 = await getB1("/ProductionOrders",{
"$filter":"AbsoluteEntry eq "+ this.receiveCheckData.订单号
})
result3.data.value[0].ProductionOrderLines.forEach(element => {
if (element.ItemNo == this.receiveCheckData.零件编码){
LineNumber = element.LineNumber
}
});
param2.push(["base_line_num", LineNumber]);
param2.push(["base_entry", this.receiveCheckData.订单号]);
const result = this.transformData(param);
// const jsonString = JSON.stringify(result, null, 2);
// console.log(jsonString);
const result2 = await posttm('/stocktask/task/receiptordertask',result)
console.log(result2)
this.receiveCheckVisible =false
},
formatDateTime(date) {
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, "0");
const day = String(date.getDate()).padStart(2, "0");
const hours = String(date.getHours()).padStart(2, "0");
const minutes = String(date.getMinutes()).padStart(2, "0");
const seconds = String(date.getSeconds()).padStart(2, "0");
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
},
// 导出Excel功能
exportToExcel() {
if (this.tableData.length === 0) {
this.$message.warning("没有数据可导出");
return;
}
try {
// 准备导出数据
const exportData = this.tableData.map((item, index) => {
return {
序号: index + 1,
合同号: item.内部合同号 || "",
订单编号: item.计划号 || "",
零件名称: item.零件名称 || "",
零件编码: item.零件编码 || "",
工序名称: item.工序名称 || "",
计划生产数: item.计划生产数 || 0,
检验数量: item.检验数量 || 0,
检验合格数量: item.合格数 || 0,
检验不合格数量: item.不合格数 || 0,
检验操作人: item.检测人 || "",
检验时间: item.检测时间 || "",
};
});
// 创建工作簿
const wb = XLSX.utils.book_new();
// 创建工作表
const ws = XLSX.utils.json_to_sheet(exportData);
// 设置列宽
const colWidth = [
{ wch: 8 }, // 序号
{ wch: 15 }, // 合同号
{ wch: 15 }, // 订单编号
{ wch: 20 }, // 零件名称
{ wch: 15 }, // 零件编码
{ wch: 12 }, // 工序名称
{ wch: 12 }, // 计划生产数
{ wch: 10 }, // 检验数量
{ wch: 15 }, // 检验合格数量
{ wch: 15 }, // 检验不合格数量
{ wch: 12 }, // 检验操作人
{ wch: 20 }, // 检验时间
];
ws["!cols"] = colWidth;
// 将工作表添加到工作簿
XLSX.utils.book_append_sheet(wb, ws, "序检收检记录");
// 生成文件名(包含当前时间)
const fileName = `序检收检记录_${this.formatDateForFileName(
new Date()
)}.xlsx`;
// 导出文件
XLSX.writeFile(wb, fileName);
this.$message.success("导出成功");
} catch (error) {
console.error("导出失败:", error);
this.$message.error("导出失败");
}
},
// 格式化日期用于文件名
formatDateForFileName(date) {
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, "0");
const day = String(date.getDate()).padStart(2, "0");
const hours = String(date.getHours()).padStart(2, "0");
const minutes = String(date.getMinutes()).padStart(2, "0");
const seconds = String(date.getSeconds()).padStart(2, "0");
return `${year}${month}${day}_${hours}${minutes}${seconds}`;
},
},
};
</script>
<style>
.search-container {
margin-bottom: 20px;
}
.show-text {
margin-right: 5px;
line-height: 32px;
}
.operation-cell {
display: flex;
justify-content: space-between;
width: 100%;
}
.operation-btn {
flex: 1;
margin: 0 5px;
padding: 0;
min-width: 0;
}
.active {
color: skyblue;
margin-left: 5px;
}
.info-container {
border: 1px solid #ccc;
display: flex;
}
.info-item {
display: flex;
flex: 1;
border-right: 1px solid #ccc;
}
.info-item:last-child {
border-right: none;
}
.info-label {
width: 30%;
padding: 8px;
background-color: #f5f7fa;
border-right: 1px solid #ccc;
}
.info-value {
flex: 1;
padding: 5px;
}
.info-label,
.info-value {
display: flex;
align-items: center;
}
</style>

View File

@@ -0,0 +1,770 @@
<template>
<div>
<el-card>
<div>
<el-menu mode="horizontal" :default-active="activeIndex" router>
<!-- <el-menu-item index="/QualityManagement/CheckTask/firstSpecial"
>首检专检</el-menu-item
>
<el-menu-item index="/QualityManagement/CheckTask/processSpecial"
>序检专检</el-menu-item
> -->
<el-menu-item index="/QualityManagement/CheckTask/final"
>终检</el-menu-item
>
<el-menu-item index="/QualityManagement/CheckTask/purchaseIncoming"
>采购入库检</el-menu-item
>
<el-menu-item index="/QualityManagement/CheckTask/salesReturn"
>销售退货检</el-menu-item
>
<el-menu-item index="/QualityManagement/CheckTask/materialReturn"
>原材料退库检</el-menu-item
>
<el-menu-item index="/QualityManagement/CheckTask/processReceive"
>序检收检</el-menu-item
>
</el-menu>
</div>
</el-card>
<el-card>
<div class="search-container">
<span class="show-text">生产订单:</span>
<el-input
v-model="orderNo"
placeholder="请输入生产订单"
clearable
style="width: 150px; margin-right: 10px"
/>
<span class="show-text">物料名称:</span>
<el-input
v-model="partName"
placeholder="请输入物料名称"
clearable
style="width: 150px; margin-right: 10px"
/>
<span class="show-text">物料编码:</span>
<el-input
v-model="partNo"
placeholder="请输入物料编号"
clearable
style="width: 150px; margin-right: 10px"
/>
<!-- <span class="show-text">检测日期:</span>
<el-date-picker
v-model="inspectionDate"
:clearable="false"
end-placeholder="结束时间"
format="yyyy-MM-dd"
range-separator="-"
start-placeholder="开始时间"
style="width: 280px; vertical-align: top"
type="datetimerange"
value-format="yyyy-MM-dd"
/> -->
<!-- <span class="show-text">计划完工日期:</span>
<el-date-picker
v-model="completionTime"
:clearable="false"
end-placeholder="结束时间"
format="yyyy-MM-dd"
range-separator="-"
start-placeholder="开始时间"
style="width: 280px; vertical-align: top"
type="datetimerange"
value-format="yyyy-MM-dd"
/> -->
<!-- <br />
<br /> -->
<!-- <span class="show-text">检测结果</span>
<el-select
v-model="inspectionResult"
clearable
style="width: 150px; margin-right: 10px"
filterable
>
<el-option label="合格" value="1" />
<el-option label="不合格" value="0" />
</el-select>
<span class="show-text">检测人:</span>
<el-select
v-model="checker"
placeholder="请选择检测人"
clearable
style="width: 150px; margin-right: 10px"
filterable
>
<el-option
v-for="item in checkerList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select> -->
<!-- <span class="show-text">检测类别:</span>
<el-select
v-model="type"
placeholder="请选择检测类别"
clearable
style="width: 150px; margin-right: 10px"
filterable
>
<el-option
v-for="item in typeList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select> -->
<el-button
:disabled="loading"
icon="el-icon-search"
plain
type="primary"
@click="searchTable()"
>查询
</el-button>
<!-- <el-button
type="success"
icon="el-icon-download"
plain
:disabled="tableData.length === 0"
@click="exportToExcel"
>导出</el-button
> -->
</div>
<el-table
v-loading="loading"
:data="tableData"
:height="'67vh'"
border
element-loading-background="rgba(0, 0, 0, 0.2)"
element-loading-spinner="el-icon-loading"
highlight-current-row
size="mini"
style="width: 100%; margin-top: 20px"
tooltip-effect="dark"
>
<el-table-column
align="center"
label="序号"
type="index"
width="50"
fixed
/>
<!-- <el-table-column
align="center"
label="销售订单"
width="100"
prop="内部合同号"
/> -->
<el-table-column
align="center"
label="生产订单"
width="100"
prop="计划号"
/>
<el-table-column
align="center"
label="物料名称"
width="100"
prop="零件名称"
/>
<el-table-column
align="center"
label="物料编码"
width="100"
prop="零件编码"
/>
<el-table-column
align="center"
label="工序名称"
width="120"
prop="工序名称"
/>
<el-table-column
align="center"
label="工位名称"
width="120"
prop="工位名称"
/>
<el-table-column
align="center"
label="完成数量"
width="100"
prop="完成数量"
/>
<el-table-column
align="center"
label="检验数量"
width="120"
prop="检验数量"
/>
<el-table-column
align="center"
label="检验合格数量"
width="110"
prop="合格数"
/>
<el-table-column
align="center"
label="检验不合格数量"
width="120"
prop="不合格数"
/>
<el-table-column
align="center"
label="检验操作人"
width="130"
prop="检测人"
/>
<el-table-column
align="center"
label="检验时间"
width="180"
prop="检测时间"
/>
<el-table-column
align="center"
label="检测说明"
width="180"
prop="检测说明"
/>
<el-table-column label="操作" align="center" width="250" fixed="right">
<template slot-scope="scope">
<el-button
class="operation-btn"
type="primary"
size="mini"
@click="receiveCheck(scope.row)"
>收检</el-button
>
</template>
</el-table-column>
</el-table>
</el-card>
<!-- 收检对话框 -->
<el-dialog
title="收检"
:visible.sync="receiveCheckVisible"
width="60%"
style="text-align: center"
>
<el-form
ref="receiveCheckForm"
:model="receiveCheckData"
label-position="right"
label-width="140px"
size="mini"
>
<div>
<div class="info-container">
<div class="info-item">
<span class="info-label">物料名称</span>
<span class="info-value">{{ receiveCheckData.零件名称 }}</span>
</div>
<div class="info-item">
<span class="info-label">销售订单</span>
<span class="info-value">{{ receiveCheckData.内部合同号 }}</span>
</div>
</div>
</div>
<div>
<div class="info-container">
<div class="info-item">
<span class="info-label">物料编码</span>
<span class="info-value">{{ receiveCheckData.零件编码 }}</span>
</div>
<div class="info-item">
<span class="info-label">生产订单</span>
<span class="info-value">{{ receiveCheckData.计划号 }}</span>
</div>
</div>
</div>
<div>
<div class="info-container">
<div class="info-item">
<span class="info-label">工序名称</span>
<span class="info-value">{{ receiveCheckData.工序名称 }}</span>
</div>
<div class="info-item">
<span class="info-label">完成数量</span>
<span class="info-value">{{ receiveCheckData.完成数量 }}</span>
</div>
</div>
</div>
<div>
<div class="info-container">
<div class="info-item">
<span class="info-label"> 未检测数量</span>
<span class="info-value">{{ receiveCheckData.完成数量 - receiveCheckData.检测数量 }}</span>
</div>
<div class="info-item">
<span class="info-label"> 合格数</span>
<el-input-number
v-model="receiveCheckData.合格数"
size="mini"
:min="0"
:max="receiveCheckData.完成数量 - receiveCheckData.检测数量"
style="width: 200px"
@change="handleQualifiedChange"
/>
</div>
</div>
</div>
<div>
<div class="info-container">
<div class="info-item">
<span class="info-label"> 不合格数</span>
<span class="info-value">{{ receiveCheckData.不合格数 }}</span>
</div>
<div class="info-item">
<span class="info-label"> 检验人</span>
<el-select
v-model="receiveCheckData.检测人"
placeholder="请选择检验人"
clearable
style="width: 200px"
filterable
>
<el-option
v-for="item in checkerList"
:key="item.value"
:label="item.label"
:value="item.label"
/>
</el-select>
</div>
</div>
</div>
<div>
<div class="info-container">
<div class="info-item">
<span class="info-label"> 检验时间</span>
<el-date-picker
v-model="receiveCheckData.检测时间"
type="datetime"
placeholder="选择检验时间"
format="yyyy-MM-dd HH:mm:ss"
value-format="yyyy-MM-dd HH:mm:ss"
style="width: 120px"
class="info-value"
/>
</div>
<div class="info-item">
<span class="info-label"> 检测说明</span>
<el-input
v-model="receiveCheckData.检测说明"
type="textarea"
:rows="2"
placeholder="请输入检测说明"
style="width: 120px"
class="info-value"
/>
</div>
</div>
</div>
</el-form>
<div slot="footer">
<el-button type="primary" @click="confirmReceiveCheck"> </el-button>
<el-button @click="receiveCheckVisible = false"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
// 引入xlsx库
import * as XLSX from "xlsx";
export default {
data() {
return {
contractNo: "",
orderNo: "",
partNo: "",
partName: "",
completionTime: "",
inspectionDate: "",
type: "",
typeList: [],
checker: "",
checkerLabel: "",
checkerList: [],
inspectionResult: "",
tableData: [],
loading: false,
selectedRow: null,
receiveCheckVisible: false,
receiveCheckData: {
// 基本信息(从行数据获取)
零件名称: "",
内部合同号: "",
零件编码: "",
计划号: "",
工序名称: "",
计划完成时间: "",
计划生产数: 0,
TaskAID: "",
// 收检数据(用户输入)
检测数量: 0,
合格数: 0,
不合格数: 0,
检测人: "",
检测时间: "",
检测说明: "",
},
};
},
created() {
this.getTypeList();
this.getCheckerList();
this.searchTable();
},
computed: {
activeIndex() {
return this.$route.path;
},
},
methods: {
getTypeList() {
this.typeList = [];
var Data = this.CreateData("11", "查询字典");
this.ExecDatabase(Data).then((response) => {
for (let i = 0; i < response.data.length; i++) {
if (response.data[i].数据类别 === "检测类型") {
this.typeList.push({
label: response.data[i].词条名称,
value: response.data[i].词条编号,
});
}
}
});
},
getCheckerList() {
this.checkerList = [];
var Data = this.CreateData("11", "人员管理_人员信息查询_质检部门_查询");
this.ExecDatabase(Data).then((response) => {
for (let i = 0; i < response.data.length; i++) {
this.checkerList.push({
label: response.data[i].Personnel_Name,
value: response.data[i].Personnel_Number,
});
}
});
},
searchTable() {
// 开始加载状态,清空表格数据和选中行
this.loading = true;
this.tableData = [];
// 构建基础查询参数
var param = [];
param.push(["合同号", this.contractNo]);
param.push(["订单号", this.orderNo]);
param.push(["零件编号", this.partNo]);
param.push(["零件名称", this.partName]);
// 添加完工日期范围参数
param.push([
"完工日期_Start",
this.completionTime ? this.completionTime[0] : "",
]);
param.push([
"完工日期_End",
this.completionTime ? this.completionTime[1] : "",
]);
// 添加检测日期范围参数
param.push([
"检测日期_Start",
this.inspectionDate ? this.inspectionDate[0] : "",
]);
param.push([
"检测日期_End",
this.inspectionDate ? this.inspectionDate[1] : "",
]);
param.push(["检测结果", this.inspectionResult]);
const selectedChecker = this.checkerList.find(
(item) => item.value === this.checker
);
param.push(["检测人", selectedChecker ? selectedChecker.label : ""]);
param.push(["检测类别", this.type]);
// 调用封装方法生成请求数据 - 使用新的存储过程名称
var Data = this.CreateData(
"11",
"质量管理_质量检验_收检记录_查询",
param
);
// 执行数据库请求
this.ExecDatabase(Data)
.then((response) => {
this.loading = false;
console.log(response.data);
if (response.data && response.data.length !== 0) {
this.tableData = response.data;
} else {
this.tableData = [];
this.$message.info("未查询到相关数据");
}
})
.catch((error) => {
this.loading = false;
console.error("查询失败:", error);
this.$message.error("查询失败");
});
},
receiveCheck(row) {
// 打开收检对话框并填充数据
this.receiveCheckVisible = true;
// 从行数据填充基本信息
this.receiveCheckData = {
// 基本信息(从行数据获取)
零件名称: row.零件名称 || "",
内部合同号: row.内部合同号 || "",
零件编码: row.零件编码 || "",
计划号: row.计划号 || "",
工序名称: row.工序名称 || "",
计划生产数: row.计划生产数 || 0,
TaskAID: row.TaskAID || "",
// 收检数据(用户输入)
检测数量: row.检验数量 || 0,
完成数量: row.完成数量 || 0,
合格数: 0,
不合格数: row.完成数量 - row.检验数量 || 0,
检测人: row.检测人 || "",
检测时间: this.formatDateTime(new Date()),
检测说明: "",
};
console.log(this.receiveCheckData);
},
handleQualifiedChange(value) {
// 自动计算不合格数
this.receiveCheckData.不合格数 = this.receiveCheckData.完成数量-this.receiveCheckData.检测数量 - value;
},
confirmReceiveCheck() {
// 验证表单
if (
this.receiveCheckData.完成数量-this.receiveCheckData.检测数量 <= 0
) {
this.$message.warning("请输入有效的检测数量");
return;
}
if (!this.receiveCheckData.检测人) {
this.$message.warning("请选择检验人");
return;
}
if (!this.receiveCheckData.检测时间) {
this.$message.warning("请选择检验时间");
return;
}
// 调用存储过程保存数据
this.saveReceiveCheck();
},
saveReceiveCheck() {
var param = [];
param.push(["TaskAID", this.receiveCheckData.TaskAID || ""]);
param.push(["检测类型编号", 6]);
param.push(["质检类型", "收检"]);
param.push(["零件名称", this.receiveCheckData.零件名称]);
param.push(["内部合同号", this.receiveCheckData.内部合同号]);
param.push(["零件编码", this.receiveCheckData.零件编码]);
param.push(["计划号", this.receiveCheckData.计划号]);
param.push(["工序名称", this.receiveCheckData.工序名称]);
param.push(["检测数量", this.receiveCheckData.完成数量-this.receiveCheckData.检测数量]);
param.push(["合格数", this.receiveCheckData.合格数]);
param.push(["不合格数", this.receiveCheckData.不合格数]);
param.push(["检测人", this.receiveCheckData.检测人]);
param.push(["检测时间", this.receiveCheckData.检测时间]);
param.push(["检测说明", this.receiveCheckData.检测说明]);
console.log(param);
var Data = this.CreateData("12", "质量管理_序检收检_新增", param);
this.ExecDatabase(Data)
.then((response) => {
if (
response.data &&
response.data[0] &&
response.data[0].result === "1"
) {
this.$message.success("收检操作成功");
this.receiveCheckVisible = false;
// 刷新表格数据
this.searchTable();
} else {
this.$message.error("收检操作失败");
}
})
.catch((error) => {
console.error("收检操作失败:", error);
this.$message.error("收检操作失败");
});
},
formatDateTime(date) {
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, "0");
const day = String(date.getDate()).padStart(2, "0");
const hours = String(date.getHours()).padStart(2, "0");
const minutes = String(date.getMinutes()).padStart(2, "0");
const seconds = String(date.getSeconds()).padStart(2, "0");
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
},
// 导出Excel功能
exportToExcel() {
if (this.tableData.length === 0) {
this.$message.warning("没有数据可导出");
return;
}
try {
// 准备导出数据
const exportData = this.tableData.map((item, index) => {
return {
序号: index + 1,
合同号: item.内部合同号 || "",
订单编号: item.计划号 || "",
零件名称: item.零件名称 || "",
零件编码: item.零件编码 || "",
工序名称: item.工序名称 || "",
计划生产数: item.计划生产数 || 0,
检验数量: item.检验数量 || 0,
检验合格数量: item.合格数 || 0,
检验不合格数量: item.不合格数 || 0,
检验操作人: item.检测人 || "",
检验时间: item.检测时间 || "",
};
});
// 创建工作簿
const wb = XLSX.utils.book_new();
// 创建工作表
const ws = XLSX.utils.json_to_sheet(exportData);
// 设置列宽
const colWidth = [
{ wch: 8 }, // 序号
{ wch: 15 }, // 合同号
{ wch: 15 }, // 订单编号
{ wch: 20 }, // 零件名称
{ wch: 15 }, // 零件编码
{ wch: 12 }, // 工序名称
{ wch: 12 }, // 计划生产数
{ wch: 10 }, // 检验数量
{ wch: 15 }, // 检验合格数量
{ wch: 15 }, // 检验不合格数量
{ wch: 12 }, // 检验操作人
{ wch: 20 }, // 检验时间
];
ws["!cols"] = colWidth;
// 将工作表添加到工作簿
XLSX.utils.book_append_sheet(wb, ws, "序检收检记录");
// 生成文件名(包含当前时间)
const fileName = `序检收检记录_${this.formatDateForFileName(
new Date()
)}.xlsx`;
// 导出文件
XLSX.writeFile(wb, fileName);
this.$message.success("导出成功");
} catch (error) {
console.error("导出失败:", error);
this.$message.error("导出失败");
}
},
// 格式化日期用于文件名
formatDateForFileName(date) {
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, "0");
const day = String(date.getDate()).padStart(2, "0");
const hours = String(date.getHours()).padStart(2, "0");
const minutes = String(date.getMinutes()).padStart(2, "0");
const seconds = String(date.getSeconds()).padStart(2, "0");
return `${year}${month}${day}_${hours}${minutes}${seconds}`;
},
},
};
</script>
<style>
.search-container {
margin-bottom: 20px;
}
.show-text {
margin-right: 5px;
line-height: 32px;
}
.operation-cell {
display: flex;
justify-content: space-between;
width: 100%;
}
.operation-btn {
flex: 1;
margin: 0 5px;
padding: 0;
min-width: 0;
}
.active {
color: skyblue;
margin-left: 5px;
}
.info-container {
border: 1px solid #ccc;
display: flex;
}
.info-item {
display: flex;
flex: 1;
border-right: 1px solid #ccc;
}
.info-item:last-child {
border-right: none;
}
.info-label {
width: 30%;
padding: 8px;
background-color: #f5f7fa;
border-right: 1px solid #ccc;
}
.info-value {
flex: 1;
padding: 5px;
}
.info-label,
.info-value {
display: flex;
align-items: center;
}
</style>

View File

@@ -0,0 +1,62 @@
<template>
<div>
<el-card>
<div>
<el-menu mode="horizontal" :default-active="activeIndex" router>
<el-menu-item index="/QualityManagement/CheckTask/firstSpecial"
>首检专检</el-menu-item
>
<el-menu-item index="/QualityManagement/CheckTask/processSpecial"
>序检专检</el-menu-item
>
<el-menu-item index="/QualityManagement/CheckTask/final"
>终检</el-menu-item
>
<el-menu-item index="/QualityManagement/CheckTask/purchaseIncoming"
>采购入库检</el-menu-item
>
<el-menu-item index="/QualityManagement/CheckTask/salesReturn"
>销售退货检</el-menu-item
>
<el-menu-item index="/QualityManagement/CheckTask/materialReturn"
>原材料退库检</el-menu-item
>
<el-menu-item index="/QualityManagement/CheckTask/processReceive"
>序检收检</el-menu-item
>
</el-menu>
</div>
</el-card>
</div>
</template>
</template>
<script>
export default {};
</script>
<style>
.search-container {
margin-bottom: 20px;
}
.show-text {
margin-right: 5px;
line-height: 32px;
}
.operation-cell {
display: flex;
justify-content: space-between;
width: 100%;
}
.operation-btn {
flex: 1;
margin: 0 5px;
padding: 0;
min-width: 0;
}
.active {
color: skyblue;
margin-left: 5px;
}
</style>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,726 @@
<template>
<div>
<el-card>
<div>
<el-menu mode="horizontal" :default-active="activeIndex" router>
<!-- <el-menu-item index="/QualityManagement/CheckTask/firstSpecial"
>首检专检</el-menu-item
>
<el-menu-item index="/QualityManagement/CheckTask/processSpecial"
>序检专检</el-menu-item
> -->
<el-menu-item index="/QualityManagement/CheckTask/final"
>终检</el-menu-item
>
<el-menu-item index="/QualityManagement/CheckTask/purchaseIncoming"
>采购入库检</el-menu-item
>
<el-menu-item index="/QualityManagement/CheckTask/salesReturn"
>销售退货检</el-menu-item
>
<el-menu-item index="/QualityManagement/CheckTask/materialReturn"
>原材料退库检</el-menu-item
>
<el-menu-item index="/QualityManagement/CheckTask/processReceive"
>序检收检</el-menu-item
>
</el-menu>
</div>
</el-card>
<el-card>
<div class="search-container">
<span class="show-text">生产订单:</span>
<el-input
v-model="orderNo"
placeholder="请输入生产订单"
clearable
style="width: 150px; margin-right: 10px"
/>
<span class="show-text">物料名称:</span>
<el-input
v-model="partName"
placeholder="请输入物料名称"
clearable
style="width: 150px; margin-right: 10px"
/>
<span class="show-text">物料编码:</span>
<el-input
v-model="partNo"
placeholder="请输入物料编号"
clearable
style="width: 150px; margin-right: 10px"
/>
<span class="show-text">检测日期:</span>
<el-date-picker
v-model="inspectionDate"
:clearable="false"
end-placeholder="结束时间"
format="yyyy-MM-dd"
range-separator="-"
start-placeholder="开始时间"
style="width: 280px; vertical-align: top"
type="datetimerange"
value-format="yyyy-MM-dd"
/>
<!-- <span class="show-text">计划完工日期:</span>
<el-date-picker
v-model="completionTime"
:clearable="false"
end-placeholder="结束时间"
format="yyyy-MM-dd"
range-separator="-"
start-placeholder="开始时间"
style="width: 280px; vertical-align: top"
type="datetimerange"
value-format="yyyy-MM-dd"
/> -->
<br />
<br />
<span class="show-text">检测结果</span>
<el-select
v-model="inspectionResult"
clearable
style="width: 150px; margin-right: 10px"
filterable
>
<el-option label="合格" value="1" />
<el-option label="不合格" value="0" />
</el-select>
<span class="show-text">检测人:</span>
<el-select
v-model="checker"
placeholder="请选择检测人"
clearable
style="width: 150px; margin-right: 10px"
filterable
>
<el-option
v-for="item in checkerList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
<!-- <span class="show-text">检测类别:</span>
<el-select
v-model="type"
placeholder="请选择检测类别"
clearable
style="width: 150px; margin-right: 10px"
filterable
>
<el-option
v-for="item in typeList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select> -->
<el-button
:disabled="loading"
icon="el-icon-search"
plain
type="primary"
@click="searchTable()"
>查询
</el-button>
<!-- <el-button
type="success"
icon="el-icon-download"
plain
:disabled="tableData.length === 0"
@click="exportToExcel"
>导出</el-button
> -->
</div>
<el-table
v-loading="loading"
:data="tableData"
:height="'67vh'"
border
element-loading-background="rgba(0, 0, 0, 0.2)"
element-loading-spinner="el-icon-loading"
highlight-current-row
size="mini"
style="width: 100%; margin-top: 20px"
tooltip-effect="dark"
>
<el-table-column
align="center"
label="序号"
type="index"
width="50"
fixed
/>
<el-table-column
align="center"
label="生产订单"
width="80"
prop="订单编号"
/>
<el-table-column
align="center"
label="物料名称"
width="150"
prop="物料名称"
/>
<el-table-column
align="center"
label="物料编码"
width="150"
prop="物料编码"
/>
<!-- <el-table-column
align="center"
label="采购数"
width="80"
prop="计划生产数"
/> -->
<el-table-column
align="center"
label="检验数量"
width="80"
prop="入库数量"
/>
<el-table-column
align="center"
label="合格数"
width="80"
prop="合格数"
/>
<el-table-column
align="center"
label="不合格数"
width="80"
prop="不合格数"
/>
<el-table-column
align="center"
label="检验人"
width="100"
prop="检测人"
/>
<el-table-column
align="center"
label="检验时间"
width="150"
prop="检验时间"
/>
<el-table-column label="操作" align="center" width="250">
<template slot-scope="scope">
<el-button
class="operation-btn"
type="primary"
size="mini"
@click="receiveCheck(scope.row)"
>入库检</el-button
>
</template>
</el-table-column>
</el-table>
</el-card>
<!-- 收检对话框 -->
<el-dialog
title="入库检"
:visible.sync="receiveCheckVisible"
width="60%"
style="text-align: center"
>
<el-form
ref="receiveCheckForm"
:model="receiveCheckData"
label-position="right"
label-width="140px"
size="mini"
>
<div>
<div class="info-container">
<div class="info-item">
<span class="info-label">物料名称</span>
<span class="info-value">{{ receiveCheckData.零件名称 }}</span>
</div>
<div class="info-item">
<span class="info-label">物料编码</span>
<span class="info-value">{{ receiveCheckData.零件编码 }}</span>
</div>
</div>
</div>
<div>
<div class="info-container">
<div class="info-item">
<span class="info-label">生产订单</span>
<span class="info-value">{{ receiveCheckData.计划号 }}</span>
</div>
<div class="info-item">
<span class="info-label">采购数</span>
<span class="info-value">{{ receiveCheckData.计划生产数 }}</span>
</div>
</div>
</div>
<div>
<div class="info-container">
<div class="info-item">
<span class="info-label"> 检测数量</span>
<span class="info-value">{{ receiveCheckData.检测数量 }}</span>
</div>
<div class="info-item">
<span class="info-label"> 合格数</span>
<el-input-number
v-model="receiveCheckData.合格数"
size="mini"
:min="0"
:max="receiveCheckData.检测数量"
style="width: 200px"
@change="handleQualifiedChange"
/>
</div>
</div>
</div>
<div>
<div class="info-container">
<div class="info-item">
<span class="info-label"> 不合格数</span>
<span class="info-value">{{ receiveCheckData.不合格数 }}</span>
</div>
<div class="info-item">
<span class="info-label"> 检验人</span>
<el-select
v-model="receiveCheckData.检测人"
placeholder="请选择检验人"
clearable
style="width: 200px"
filterable
>
<el-option
v-for="item in checkerList"
:key="item.value"
:label="item.label"
:value="item.label"
/>
</el-select>
</div>
</div>
</div>
<div>
<div class="info-container">
<div class="info-item">
<span class="info-label"> 检验时间</span>
<el-date-picker
v-model="receiveCheckData.检测时间"
type="datetime"
placeholder="选择检验时间"
format="yyyy-MM-dd HH:mm:ss"
value-format="yyyy-MM-dd HH:mm:ss"
style="width: 120px"
class="info-value"
/>
</div>
<div class="info-item">
<span class="info-label"> 检测说明</span>
<el-input
v-model="receiveCheckData.检测说明"
type="textarea"
:rows="2"
placeholder="请输入检测说明"
style="width: 120px"
class="info-value"
/>
</div>
</div>
</div>
</el-form>
<div slot="footer">
<el-button type="primary" @click="confirmReceiveCheck"> </el-button>
<el-button @click="receiveCheckVisible = false"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
// 引入xlsx库
import * as XLSX from "xlsx";
export default {
data() {
return {
contractNo: "",
orderNo: "",
partNo: "",
partName: "",
completionTime: "",
inspectionDate: "",
type: "",
typeList: [],
checker: "",
checkerLabel: "",
checkerList: [],
inspectionResult: "",
tableData: [],
loading: false,
selectedRow: null,
receiveCheckVisible: false,
receiveCheckData: {
// 基本信息(从行数据获取)
零件名称: "",
内部合同号: "",
零件编码: "",
计划号: "",
工序名称: "",
计划完成时间: "",
计划生产数: 0,
TaskAID: "",
// 收检数据(用户输入)
检测数量: 0,
合格数: 0,
不合格数: 0,
检测人: "",
检测时间: "",
检测说明: "",
},
};
},
created() {
this.getTypeList();
this.getCheckerList();
this.searchTable();
},
computed: {
activeIndex() {
return this.$route.path;
},
},
methods: {
getTypeList() {
this.typeList = [];
var Data = this.CreateData("11", "查询字典");
this.ExecDatabase(Data).then((response) => {
for (let i = 0; i < response.data.length; i++) {
if (response.data[i].数据类别 === "检测类型") {
this.typeList.push({
label: response.data[i].词条名称,
value: response.data[i].词条编号,
});
}
}
});
},
getCheckerList() {
this.checkerList = [];
var Data = this.CreateData("11", "人员管理_人员信息查询_质检部门_查询");
this.ExecDatabase(Data).then((response) => {
for (let i = 0; i < response.data.length; i++) {
this.checkerList.push({
label: response.data[i].Personnel_Name,
value: response.data[i].Personnel_Number,
});
}
});
},
searchTable() {
// 开始加载状态,清空表格数据和选中行
this.loading = true;
this.tableData = [];
// 构建基础查询参数
var param = [];
param.push(["订单号", this.orderNo]);
param.push(["零件编号", this.partNo]);
param.push(["零件名称", this.partName]);
// 添加检测日期范围参数
param.push([
"检测日期_Start",
this.inspectionDate ? this.inspectionDate[0] : "",
]);
param.push([
"检测日期_End",
this.inspectionDate ? this.inspectionDate[1] : "",
]);
param.push(["检测结果", this.inspectionResult]);
const selectedChecker = this.checkerList.find(
(item) => item.value === this.checker
);
param.push(["检测人", selectedChecker ? selectedChecker.label : ""]);
// 调用封装方法生成请求数据 - 使用新的存储过程名称
var Data = this.CreateData(
"11",
"质量管理_质量检验_退货质检任务_查询",
param
);
// 执行数据库请求
this.ExecDatabase(Data)
.then((response) => {
this.loading = false;
console.log(response.data);
if (response.data && response.data.length !== 0) {
this.tableData = response.data;
} else {
this.tableData = [];
this.$message.info("未查询到相关数据");
}
})
.catch((error) => {
this.loading = false;
console.error("查询失败:", error);
this.$message.error("查询失败");
});
},
receiveCheck(row) {
// 打开收检对话框并填充数据
this.receiveCheckVisible = true;
// 从行数据填充基本信息
this.receiveCheckData = {
// 基本信息(从行数据获取)
零件名称: row.物料名称 || "",
零件编码: row.物料编码 || "",
计划号: row.订单编号 || "",
行号: row.行号 || "",
订单类型: row.订单类型 || "",
// 收检数据(用户输入)
检测数量: row.入库数量 || 0,
合格数: row.合格数 || 0,
不合格数: row.不合格数 || 0,
检测人: row.检测人 || "",
检测时间: this.formatDateTime(new Date()),
检测说明: "",
};
console.log(this.receiveCheckData);
},
handleQualifiedChange(value) {
// 自动计算不合格数
this.receiveCheckData.不合格数 = this.receiveCheckData.检测数量 - value;
},
confirmReceiveCheck() {
// 验证表单
if (
!this.receiveCheckData.检测数量 ||
this.receiveCheckData.检测数量 <= 0
) {
this.$message.warning("请输入有效的检测数量");
return;
}
if (!this.receiveCheckData.检测人) {
this.$message.warning("请选择检验人");
return;
}
if (!this.receiveCheckData.检测时间) {
this.$message.warning("请选择检验时间");
return;
}
if (!this.receiveCheckData.检测数量 == this.receiveCheckData.合格数 + this.receiveCheckData.不合格数) {
this.$message.warning("合格数加不合格数必须等于检测数量");
return;
}
// 调用存储过程保存数据
this.saveReceiveCheck();
},
saveReceiveCheck() {
var param = [];
param.push(["检测类型编号", 5]);
param.push(["质检类型", "来料检验"]);
param.push(["零件名称", this.receiveCheckData.零件名称]);
param.push(["零件编码", this.receiveCheckData.零件编码]);
param.push(["计划号", this.receiveCheckData.计划号]);
param.push(["检测数量", this.receiveCheckData.检测数量]);
param.push(["合格数", this.receiveCheckData.合格数]);
param.push(["不合格数", this.receiveCheckData.不合格数]);
param.push(["检测人", this.receiveCheckData.检测人]);
param.push(["检测时间", this.receiveCheckData.检测时间]);
param.push(["检测说明", this.receiveCheckData.检测说明]);
param.push(["行号", this.receiveCheckData.行号]);
param.push(["订单类型", this.receiveCheckData.订单类型]);
console.log(param);
var Data = this.CreateData("12", "质量管理_来料检验_更新", param);
this.ExecDatabase(Data)
.then((response) => {
if (
response.data &&
response.data[0] &&
response.data[0].result === "1"
) {
this.$message.success("来料检验操作成功");
this.receiveCheckVisible = false;
// 刷新表格数据
this.searchTable();
} else {
this.$message.error("来料检验操作失败");
}
})
.catch((error) => {
console.error("来料检验操作失败:", error);
this.$message.error("来料检验操作失败");
});
},
formatDateTime(date) {
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, "0");
const day = String(date.getDate()).padStart(2, "0");
const hours = String(date.getHours()).padStart(2, "0");
const minutes = String(date.getMinutes()).padStart(2, "0");
const seconds = String(date.getSeconds()).padStart(2, "0");
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
},
// 导出Excel功能
exportToExcel() {
if (this.tableData.length === 0) {
this.$message.warning("没有数据可导出");
return;
}
try {
// 准备导出数据
const exportData = this.tableData.map((item, index) => {
return {
序号: index + 1,
合同号: item.内部合同号 || "",
订单编号: item.计划号 || "",
零件名称: item.零件名称 || "",
零件编码: item.零件编码 || "",
工序名称: item.工序名称 || "",
计划生产数: item.计划生产数 || 0,
检验数量: item.检验数量 || 0,
检验合格数量: item.合格数 || 0,
检验不合格数量: item.不合格数 || 0,
检验操作人: item.检测人 || "",
检验时间: item.检测时间 || "",
};
});
// 创建工作簿
const wb = XLSX.utils.book_new();
// 创建工作表
const ws = XLSX.utils.json_to_sheet(exportData);
// 设置列宽
const colWidth = [
{ wch: 8 }, // 序号
{ wch: 15 }, // 合同号
{ wch: 15 }, // 订单编号
{ wch: 20 }, // 零件名称
{ wch: 15 }, // 零件编码
{ wch: 12 }, // 工序名称
{ wch: 12 }, // 计划生产数
{ wch: 10 }, // 检验数量
{ wch: 15 }, // 检验合格数量
{ wch: 15 }, // 检验不合格数量
{ wch: 12 }, // 检验操作人
{ wch: 20 }, // 检验时间
];
ws["!cols"] = colWidth;
// 将工作表添加到工作簿
XLSX.utils.book_append_sheet(wb, ws, "序检收检记录");
// 生成文件名(包含当前时间)
const fileName = `序检收检记录_${this.formatDateForFileName(
new Date()
)}.xlsx`;
// 导出文件
XLSX.writeFile(wb, fileName);
this.$message.success("导出成功");
} catch (error) {
console.error("导出失败:", error);
this.$message.error("导出失败");
}
},
// 格式化日期用于文件名
formatDateForFileName(date) {
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, "0");
const day = String(date.getDate()).padStart(2, "0");
const hours = String(date.getHours()).padStart(2, "0");
const minutes = String(date.getMinutes()).padStart(2, "0");
const seconds = String(date.getSeconds()).padStart(2, "0");
return `${year}${month}${day}_${hours}${minutes}${seconds}`;
},
},
};
</script>
<style>
.search-container {
margin-bottom: 20px;
}
.show-text {
margin-right: 5px;
line-height: 32px;
}
.operation-cell {
display: flex;
justify-content: space-between;
width: 100%;
}
.operation-btn {
flex: 1;
margin: 0 5px;
padding: 0;
min-width: 0;
}
.active {
color: skyblue;
margin-left: 5px;
}
.info-container {
border: 1px solid #ccc;
display: flex;
}
.info-item {
display: flex;
flex: 1;
border-right: 1px solid #ccc;
}
.info-item:last-child {
border-right: none;
}
.info-label {
width: 30%;
padding: 8px;
background-color: #f5f7fa;
border-right: 1px solid #ccc;
}
.info-value {
flex: 1;
padding: 5px;
}
.info-label,
.info-value {
display: flex;
align-items: center;
}
</style>

View File

@@ -0,0 +1,817 @@
<template>
<div>
<el-card>
<div class="search-container">
<span class="show-text">零件号:</span>
<el-select
v-model="partNo"
placeholder="请选择零件号"
clearable
style="width: 150px; margin-right: 10px"
filterable
>
<el-option
v-for="item in partNoList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
<span class="show-text">工序名称:</span>
<el-select
v-model="process"
placeholder="请选择工序"
clearable
style="width: 150px; margin-right: 10px"
filterable
>
<el-option
v-for="item in processList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
<span class="show-text">类型:</span>
<el-select
v-model="type"
placeholder="请选择类型"
clearable
style="width: 150px; margin-right: 10px"
filterable
>
<el-option
v-for="item in typeList"
:key="item.value"
:label="item.label"
:value="item.value"
clearable
filterable
/>
</el-select>
<el-button
:disabled="loading"
plain
type="primary"
@click="searchTable()"
>查询</el-button
>
<el-button
:disabled="loading"
plain
type="primary"
@click="addCheckType()"
>新增标准</el-button
>
</div>
<el-table
v-loading="loading"
:data="tableData"
:height="'67vh'"
border
element-loading-background="rgba(0, 0, 0, 0.2)"
element-loading-spinner="el-icon-loading"
highlight-current-row
size="mini"
style="width: 100%; margin-top: 20px"
tooltip-effect="dark"
>
<el-table-column
align="center"
label="序号"
type="index"
width="50"
fixed
/>
<el-table-column align="center" label="零件号" width="120">
<template slot-scope="scope">
{{ scope.row.零件号 }}
</template>
</el-table-column>
<el-table-column align="center" label="工序" width="100">
<template slot-scope="scope">
{{ scope.row.工序 }}
</template>
</el-table-column>
<el-table-column align="center" label="类型" width="100">
<template slot-scope="scope">
{{ scope.row.类型 }}
</template>
</el-table-column>
<el-table-column align="center" label="检验项目" width="120">
<template slot-scope="scope">
{{ scope.row.检验项目 }}
</template>
</el-table-column>
<el-table-column align="center" label="检验内容" width="150">
<template slot-scope="scope">
{{ scope.row.检验内容 }}
</template>
</el-table-column>
<el-table-column align="center" label="上限值" width="80">
<template slot-scope="scope">
{{ scope.row.上限值 }}
</template>
</el-table-column>
<el-table-column align="center" label="下限值" width="80">
<template slot-scope="scope">
{{ scope.row.下限值 }}
</template>
</el-table-column>
<el-table-column align="center" label="单位" width="80">
<template slot-scope="scope">
{{ scope.row.单位 }}
</template>
</el-table-column>
<el-table-column align="center" label="检验比例" width="80">
<template slot-scope="scope">
{{ scope.row.检验比例 }}
</template>
</el-table-column>
<el-table-column align="center" label="检具" width="100">
<template slot-scope="scope">
{{ scope.row.检具 }}
</template>
</el-table-column>
<el-table-column align="center" label="备注" width="150">
<template slot-scope="scope">
{{ scope.row.备注 }}
</template>
</el-table-column>
<el-table-column label="操作" width="200" align="center">
<template slot-scope="scope">
<div class="operation-cell">
<el-button
type="text"
size="mini"
@click="editInspectionStandard(scope.row)"
>修改</el-button
>
<el-button
type="text"
size="mini"
@click="deleteInspectionStandard(scope.row)"
>删除</el-button
>
</div>
</template>
</el-table-column>
</el-table>
<el-dialog
:visible.sync="dialogVisibleAdd"
:title="dialogTitle"
center=""
width="850px"
style="text-align: center"
>
<el-form
ref="checkForm"
:model="checkForm"
label-position="right"
label-width="140px"
size="mini"
>
<el-row>
<el-col :span="12">
<el-form-item label="零件号">
<el-input
v-model="checkForm.零件号"
size="mini"
readonly=""
style="width: 200px"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="工序">
<el-input
v-model="checkForm.工序"
size="mini"
readonly=""
style="width: 200px"
/>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="类型">
<el-input
v-model="checkForm.类型"
size="mini"
readonly=""
style="width: 200px"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="检验比例">
<el-input
v-model="checkForm.检验比例"
size="mini"
style="width: 200px"
/>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="检验项目">
<el-input
v-model="checkForm.检验项目"
size="mini"
style="width: 200px"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="检验内容">
<el-input
v-model="checkForm.检验内容"
size="mini"
style="width: 200px"
/>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="上限值">
<el-input
v-model="checkForm.上限值"
size="mini"
style="width: 200px"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="下限值">
<el-input
v-model="checkForm.下限值"
size="mini"
style="width: 200px"
/>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="单位">
<el-input
v-model="checkForm.单位"
size="mini"
style="width: 200px"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="检具">
<el-input
v-model="checkForm.检具"
size="mini"
style="width: 200px"
/>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item label="备注">
<el-input
v-model="checkForm.备注"
type="textarea"
:rows="3"
resize="vertical"
size="mini"
style="width: 400px"
/>
</el-form-item>
</el-col>
</el-row>
<div class="dialog-footer">
<div style="margin-bottom: 20px">
<el-button
type="primary"
@click="submitInspection('checkForm', checkForm)"
>确定</el-button
>
<el-button @click="dialogVisibleAdd = false"> </el-button>
</div>
</div>
</el-form>
</el-dialog>
<el-dialog
:visible.sync="dialogVisibleChange"
:title="dialogTitle"
center=""
width="850px"
style="text-align: center"
>
<el-form
ref="checkForm"
:model="checkForm"
label-position="right"
label-width="140px"
size="mini"
>
<el-row>
<el-col :span="12">
<el-form-item label="零件号">
<el-input
v-model="checkForm.零件号"
size="mini"
readonly=""
style="width: 200px"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="工序">
<el-input
v-model="checkForm.工序"
size="mini"
readonly=""
style="width: 200px"
/>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="类型">
<el-input
v-model="checkForm.类型"
size="mini"
readonly=""
style="width: 200px"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="检验比例">
<el-input
v-model="checkForm.检验比例"
size="mini"
style="width: 200px"
/>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="检验项目">
<el-input
v-model="checkForm.检验项目"
size="mini"
style="width: 200px"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="检验内容">
<el-input
v-model="checkForm.检验内容"
size="mini"
style="width: 200px"
/>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="上限值">
<el-input
v-model="checkForm.上限值"
size="mini"
style="width: 200px"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="下限值">
<el-input
v-model="checkForm.下限值"
size="mini"
style="width: 200px"
/>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="单位">
<el-input
v-model="checkForm.单位"
size="mini"
style="width: 200px"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="检具">
<el-input
v-model="checkForm.检具"
size="mini"
style="width: 200px"
/>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item label="备注">
<el-input
v-model="checkForm.备注"
type="textarea"
:rows="3"
resize="vertical"
size="mini"
style="width: 400px"
/>
</el-form-item>
</el-col>
</el-row>
<div class="dialog-footer">
<div style="margin-bottom: 20px">
<el-button type="primary" @click="updateInspection('checkForm')"
>确定</el-button
>
<el-button @click="dialogVisibleChange = false"> </el-button>
</div>
</div>
</el-form>
</el-dialog>
</el-card>
</div>
</template>
<script>
export default {
data() {
return {
partNo: "",
partNoList: [],
process: "",
processList: [],
type: "",
typeList: [],
dialogVisibleAdd: false,
dialogVisibleChange: false,
dialogTitle: "新增检验标准",
checkForm: {
零件号: "",
工序: "",
类型: "",
检验比例: "",
检验项目: "",
检验内容: "",
上限值: "",
下限值: "",
单位: "",
检具: "",
备注: "",
},
currentEditRow: null,
loading: false,
};
},
created() {
this.getNoList();
this.getProcessList();
this.getTypeList();
this.searchTable();
},
methods: {
getNoList() {
// 模拟测试数据
this.partNoList = [
{ label: "零件A", value: "PART001" },
{ label: "零件B", value: "PART002" },
{ label: "零件C", value: "PART003" },
{ label: "零件D", value: "PART004" },
{ label: "零件E", value: "PART005" },
];
// 如果需要从接口获取真实数据,可以取消下面的注释并替换存储过程名
/*
this.partNoList = [];
var Data = this.CreateData("11", "查询零件号"); // 这里替换为实际的存储过程名
this.ExecDatabase(Data).then((response) => {
for (let i = 0; i < response.data.length; i++) {
// 根据实际返回的数据结构调整字段名
this.partNoList.push({
label: response.data[i].零件名称, // 根据实际字段名调整
value: response.data[i].零件编号, // 根据实际字段名调整
});
}
});
*/
},
getProcessList() {
this.processList = [];
var Data = this.CreateData("11", "Prog_MES_LoadProcess");
this.ExecDatabase(Data).then((response) => {
for (let i = 0; i < response.data.length; i++) {
this.processList.push({
label: response.data[i].StatgeName,
value: response.data[i].StageID,
});
}
});
},
getTypeList() {
this.typeList = [];
var Data = this.CreateData("11", "查询字典");
this.ExecDatabase(Data).then((response) => {
for (let i = 0; i < response.data.length; i++) {
// 假设 YL_基础表_数据字典 返回的字段是 DictName 和 DictID
if (response.data[i].数据类别 === "检测类型") {
this.typeList.push({
label: response.data[i].词条名称,
value: response.data[i].词条编号,
});
}
}
});
},
addCheckType() {
// 根据选中的值查找对应的标签文字
const partNoItem = this.partNoList.find(
(item) => item.value === this.partNo
);
const processItem = this.processList.find(
(item) => item.value === this.process
);
const typeItem = this.typeList.find((item) => item.value === this.type);
const partNoLabel = partNoItem ? partNoItem.label : this.partNo;
const processLabel = processItem ? processItem.label : this.process;
const typeLabel = typeItem ? typeItem.label : this.type;
this.checkForm = {
零件号: partNoLabel,
类型: typeLabel,
工序: processLabel,
检验比例: "",
检验项目: "",
检验内容: "",
上限值: "",
下限值: "",
单位: "",
检具: "",
备注: "",
};
this.dialogTitle = "新增检验标准";
this.dialogVisibleAdd = true;
},
submitInspection(formName, row) {
this.$refs[formName].validate((valid) => {
if (valid) {
// 获取选中项的编号
const partNoItem = this.partNoList.find(
(item) => item.label === this.checkForm.零件号
);
const processItem = this.processList.find(
(item) => item.label === this.checkForm.工序
);
const typeItem = this.typeList.find(
(item) => item.label === this.checkForm.类型
);
// 调用存储过程
const param = [];
param.push(["零件号", this.checkForm.零件号]);
param.push(["零件编号", partNoItem ? partNoItem.value : ""]);
param.push(["工序", this.checkForm.工序]);
param.push(["工序编号", processItem ? processItem.value : ""]);
param.push(["类型", this.checkForm.类型]);
param.push(["类型编号", typeItem ? typeItem.value : ""]);
param.push(["检验比例", this.checkForm.检验比例]);
param.push(["检验项目", this.checkForm.检验项目]);
param.push(["检验内容", this.checkForm.检验内容]);
param.push(["上限值", this.checkForm.上限值]);
param.push(["下限值", this.checkForm.下限值]);
param.push(["单位", this.checkForm.单位]);
param.push(["检具", this.checkForm.检具]);
param.push(["备注", this.checkForm.备注]);
const data = this.CreateData("12", "质量管理_检验标准表_新增", param);
this.ExecDatabase(data)
.then((response) => {
if (response.data[0].result !== "1") {
this.$message({
message: "检验标准提交失败!",
type: "error",
});
return;
}
this.$message({
message: "检验标准提交成功",
type: "success",
});
this.dialogVisibleAdd = false;
this.searchTable();
})
.catch((error) => {
this.$message({
message: "检验标准提交失败: " + error,
type: "error",
});
});
}
});
},
searchTable() {
this.loading = true;
this.tableData = [];
this.selectedRow = null;
console.log("查询条件:", {
零件编号: this.partNo,
工序编号: this.process,
类型编号: this.type,
});
var param = [];
if (this.partNo) {
param.push(["零件编号", this.partNo]);
}
if (this.process) {
param.push(["工序编号", this.process]);
}
if (this.type) {
param.push(["类型编号", this.type]);
}
var Data = this.CreateData("11", "质量管理_检验标准表_查询", param);
this.ExecDatabase(Data)
.then((response) => {
this.loading = false;
console.log("查询返回的数据:", response.data);
if (response.data.length !== 0) {
this.tableData = response.data;
console.log("表格数据:", this.tableData);
} else {
console.log("查询结果为空,参数:", param);
}
})
.catch((error) => {
this.loading = false;
console.error("查询出错:", error);
this.$message({
message: "查询失败",
type: "error",
});
});
},
editInspectionStandard(row) {
// 获取选中行的数据,并填充到表单中
this.checkForm = {
零件号: row.零件号,
工序: row.工序,
类型: row.类型,
检验比例: row.检验比例,
检验项目: row.检验项目,
检验内容: row.检验内容,
上限值: row.上限值,
下限值: row.下限值,
单位: row.单位,
检具: row.检具,
备注: row.备注,
};
// 保存当前编辑的行数据,用于后续更新操作
this.currentEditRow = row;
this.dialogTitle = "修改检验标准";
// 显示对话框
this.dialogVisibleChange = true;
},
updateInspection(formName) {
this.$refs[formName].validate((valid) => {
if (valid) {
// 获取编号信息
const partNoItem = this.partNoList.find(
(item) => item.label === this.checkForm.零件号
);
const processItem = this.processList.find(
(item) => item.label === this.checkForm.工序
);
const typeItem = this.typeList.find(
(item) => item.label === this.checkForm.类型
);
// 构建更新参数
const param = [];
param.push(["ID", this.currentEditRow.ID]);
param.push(["零件号", this.checkForm.零件号]);
param.push([
"零件编号",
this.currentEditRow.零件编号 ||
(partNoItem ? partNoItem.value : ""),
]);
param.push(["工序", this.checkForm.工序]);
param.push([
"工序编号",
this.currentEditRow.工序编号 ||
(processItem ? processItem.value : ""),
]);
param.push(["类型", this.checkForm.类型]);
param.push([
"类型编号",
this.currentEditRow.类型编号 || (typeItem ? typeItem.value : ""),
]);
param.push(["检验比例", this.checkForm.检验比例]);
param.push(["检验项目", this.checkForm.检验项目]);
param.push(["检验内容", this.checkForm.检验内容]);
param.push(["上限值", this.checkForm.上限值]);
param.push(["下限值", this.checkForm.下限值]);
param.push(["单位", this.checkForm.单位]);
param.push(["检具", this.checkForm.检具]);
param.push(["备注", this.checkForm.备注]);
// 调用更新存储过程
const data = this.CreateData("12", "质量管理_检验标准表_修改", param);
this.ExecDatabase(data)
.then((response) => {
if (response.data[0].result !== "1") {
this.$message({
message: "检验标准更新失败!",
type: "error",
});
return;
}
this.$message({
message: "检验标准更新成功",
type: "success",
});
this.dialogVisibleChange = false;
this.searchTable(); // 刷新表格数据
})
.catch((error) => {
this.$message({
message: "检验标准更新失败: " + error,
type: "error",
});
});
}
});
},
deleteInspectionStandard(row) {
this.$confirm("此操作将永久删除该检验标准, 是否继续?", "提示", {
cancelButtonText: "取消",
confirmButtonText: "确定",
type: "warning",
})
.then(() => {
// 构建删除参数
const param = [];
param.push(["ID", row.ID]);
// 调用删除存储过程
const data = this.CreateData("12", "质量管理_检验标准表_删除", param);
this.ExecDatabase(data)
.then((response) => {
if (response.data[0].result !== "1") {
this.$message({
message: "检验标准删除失败!",
type: "error",
});
return;
}
this.$message({
message: "检验标准删除成功",
type: "success",
});
this.searchTable(); // 刷新表格数据
})
.catch((error) => {
this.$message({
message: "检验标准删除失败: " + error,
type: "error",
});
});
})
.catch(() => {
this.$message({
type: "info",
message: "已取消删除",
});
});
},
},
};
</script>
<style scoped lang="scss">
.search-container {
margin-bottom: 20px;
}
.dialog-footer {
margin-top: 20px;
display: flex;
justify-content: center;
}
</style>

View File

@@ -0,0 +1,786 @@
<template>
<div>
<el-card>
<div class="search-container">
<span class="show-text">物料编号:</span>
<el-select
v-model="物料编号"
placeholder="请选择物料编号"
clearable
style="width: 150px; margin-right: 10px"
filterable
>
<el-option
v-for="item in partNoList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
<span class="show-text">工序名称:</span>
<el-select
v-model="工序名称编号"
placeholder="请选择工序"
clearable
style="width: 150px; margin-right: 10px"
filterable
>
<el-option
v-for="item in processList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
<span class="show-text">检测类别:</span>
<el-select
v-model="检测类别编号"
placeholder="请选择检测类别"
clearable
style="width: 150px; margin-right: 10px"
filterable
>
<el-option
v-for="item in typeList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
<el-button
:disabled="loading"
plain
type="primary"
@click="searchTable()"
>查询</el-button
>
<el-button
:disabled="loading"
plain
type="primary"
@click="addCheckType()"
>新增标准</el-button
>
</div>
<el-table
v-loading="loading"
:data="tableData"
:height="'67vh'"
border
element-loading-background="rgba(0, 0, 0, 0.2)"
element-loading-spinner="el-icon-loading"
highlight-current-row
size="mini"
style="width: 100%; margin-top: 20px"
tooltip-effect="dark"
>
<el-table-column
align="center"
label="序号"
type="index"
width="50"
fixed
/>
<el-table-column align="center" label="物料编号" width="240">
<template slot-scope="scope">
{{ scope.row.物料编号 }}
</template>
</el-table-column>
<el-table-column align="center" label="工序名称" width="100">
<template slot-scope="scope">
{{ getProcessLabel(scope.row.工序名称编号) }}
</template>
</el-table-column>
<el-table-column align="center" label="检测类别" width="100">
<template slot-scope="scope">
{{ getDetectionTypeLabel(scope.row.检测类别编号) }}
</template>
</el-table-column>
<el-table-column align="center" label="检测项目" width="120">
<template slot-scope="scope">
{{ scope.row.检测项目 }}
</template>
</el-table-column>
<el-table-column align="center" label="上限值" width="80">
<template slot-scope="scope">
{{ scope.row.上限值 }}
</template>
</el-table-column>
<el-table-column align="center" label="下限值" width="80">
<template slot-scope="scope">
{{ scope.row.下限值 }}
</template>
</el-table-column>
<el-table-column align="center" label="测量单位" width="80">
<template slot-scope="scope">
{{ scope.row.测量单位 }}
</template>
</el-table-column>
<el-table-column align="center" label="检验比例" width="80">
<template slot-scope="scope">
{{ scope.row.检验比例 }}
</template>
</el-table-column>
<el-table-column align="center" label="检具" width="100">
<template slot-scope="scope">
{{ scope.row.检具 }}
</template>
</el-table-column>
<el-table-column align="center" label="备注" width="150">
<template slot-scope="scope">
{{ scope.row.备注 }}
</template>
</el-table-column>
<el-table-column label="操作" width="200" align="center">
<template slot-scope="scope">
<div class="operation-cell">
<el-button
type="text"
size="mini"
@click="editInspectionStandard(scope.row)"
>修改</el-button
>
<el-button
type="text"
size="mini"
@click="deleteInspectionStandard(scope.row)"
>删除</el-button
>
</div>
</template>
</el-table-column>
</el-table>
<!-- 新增标准弹窗 -->
<el-dialog
:visible.sync="dialogVisibleAdd"
:title="dialogTitle"
center=""
width="850px"
style="text-align: center"
>
<el-form
ref="checkForm"
:model="checkForm"
label-position="right"
label-width="140px"
size="mini"
:rules="formRules"
>
<el-row>
<el-col :span="12">
<el-form-item label="物料编号" prop="物料编号">
<el-select
v-model="checkForm.物料编号"
placeholder="请选择物料编号"
clearable
style="width: 200px"
filterable
>
<el-option
v-for="item in partNoList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="工序名称" prop="工序名称编号">
<el-select
v-model="checkForm.工序名称编号"
placeholder="请选择工序名称"
clearable
style="width: 200px"
filterable
>
<el-option
v-for="item in processList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="检测类别" prop="检测类别编号">
<el-select
v-model="checkForm.检测类别编号"
placeholder="请选择检测类别"
clearable
style="width: 200px"
filterable
>
<el-option
v-for="item in typeList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="检具">
<el-input
v-model="checkForm.检具"
size="mini"
style="width: 200px"
/>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="检测项目">
<el-input
v-model="checkForm.检测项目"
size="mini"
style="width: 200px"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="理论值">
<el-input
v-model="checkForm.理论值"
size="mini"
style="width: 200px"
/>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="上限值">
<el-input
v-model="checkForm.上限值"
size="mini"
style="width: 200px"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="下限值">
<el-input
v-model="checkForm.下限值"
size="mini"
style="width: 200px"
/>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="测量单位">
<el-input
v-model="checkForm.测量单位"
size="mini"
style="width: 200px"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="检验比例">
<el-input
v-model="checkForm.检验比例"
size="mini"
style="width: 200px"
/>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item label="备注">
<el-input
v-model="checkForm.备注"
type="textarea"
:rows="3"
resize="vertical"
size="mini"
style="width: 400px"
/>
</el-form-item>
</el-col>
</el-row>
<div class="dialog-footer">
<div style="margin-bottom: 20px">
<el-button type="primary" @click="submitInspection('checkForm')"
>确定</el-button
>
<el-button @click="dialogVisibleAdd = false"> </el-button>
</div>
</div>
</el-form>
</el-dialog>
<!-- 修改标准弹窗 -->
<el-dialog
:visible.sync="dialogVisibleChange"
:title="dialogTitle"
center=""
width="850px"
style="text-align: center"
>
<el-form
ref="checkForm"
:model="checkForm"
label-position="right"
label-width="140px"
size="mini"
>
<el-row>
<el-col :span="12">
<el-form-item label="物料编号" prop="物料编号">
<el-input
v-model="checkForm.物料编号"
size="mini"
readonly=""
style="width: 200px"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="工序名称" prop="工序名称">
<el-input
:value="getProcessLabel(checkForm.工序名称编号)"
size="mini"
readonly=""
style="width: 200px"
/>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="检测类别编号" prop="检测类别编号">
<el-input
:value="getDetectionTypeLabel(checkForm.检测类别编号)"
size="mini"
readonly=""
style="width: 200px"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="检验比例">
<el-input
v-model="checkForm.检验比例"
size="mini"
style="width: 200px"
/>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="检测项目">
<el-input
v-model="checkForm.检测项目"
size="mini"
style="width: 200px"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="理论值">
<el-input
v-model="checkForm.理论值"
size="mini"
style="width: 200px"
/>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="上限值">
<el-input
v-model="checkForm.上限值"
size="mini"
style="width: 200px"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="下限值">
<el-input
v-model="checkForm.下限值"
size="mini"
style="width: 200px"
/>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="测量单位">
<el-input
v-model="checkForm.测量单位"
size="mini"
style="width: 200px"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="检具">
<el-input
v-model="checkForm.检具"
size="mini"
style="width: 200px"
/>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item label="备注">
<el-input
v-model="checkForm.备注"
type="textarea"
:rows="3"
resize="vertical"
size="mini"
style="width: 400px"
/>
</el-form-item>
</el-col>
</el-row>
<div class="dialog-footer">
<div style="margin-bottom: 20px">
<el-button type="primary" @click="updateInspection('checkForm')"
>确定</el-button
>
<el-button @click="dialogVisibleChange = false"> </el-button>
</div>
</div>
</el-form>
</el-dialog>
</el-card>
</div>
</template>
<script>
export default {
data() {
return {
物料编号: "", // 搜索条件
工序名称编号: "", // 搜索条件
检测类别编号: "", // 搜索条件
partNoList: [],
processList: [],
typeList: [],
dialogVisibleAdd: false,
dialogVisibleChange: false,
dialogTitle: "新增检验标准",
checkForm: {
AID: "",
物料编号: "",
工序名称编号: "",
检测类别编号: "",
检测项编号: "",
检测项目: "",
理论值: "",
上限值: "",
下限值: "",
测量单位: "",
检验比例: "",
检具: "",
备注: "",
阶段标识: "",
},
formRules: {
物料编号: [
{ required: true, message: "请选择物料编号", trigger: "change" },
],
工序名称编号: [
{ required: true, message: "请选择工序名称", trigger: "change" },
],
检测类别编号: [
{ required: true, message: "请选择检测类别", trigger: "change" },
],
},
currentEditRow: null,
loading: false,
tableData: [],
};
},
created() {
this.getNoList();
this.getProcessList();
this.getTypeList();
this.searchTable();
},
methods: {
getNoList() {
this.partNoList = [];
var Data = this.CreateData("11", "MES_ProcessManagement_PartGet");
this.ExecDatabase(Data).then((response) => {
// 使用对象来去重
const uniqueObj = {};
const uniqueList = [];
response.data.forEach((item) => {
const materialNo = item.物料编号;
if (!uniqueObj[materialNo]) {
uniqueObj[materialNo] = true;
uniqueList.push({
label: item.物料名称 || item.物料编号,
value: materialNo,
});
}
});
this.partNoList = uniqueList;
});
},
getProcessList() {
this.processList = [];
var Data = this.CreateData("11", "Prog_MES_LoadProcess");
this.ExecDatabase(Data).then((response) => {
for (let i = 0; i < response.data.length; i++) {
this.processList.push({
label: response.data[i].工序名称,
value: response.data[i].阶段标识 || response.data[i].工艺编号,
});
}
});
},
getTypeList() {
this.typeList = [];
var Data = this.CreateData("11", "查询字典");
this.ExecDatabase(Data).then((response) => {
for (let i = 0; i < response.data.length; i++) {
if (response.data[i].数据类别 === "检测类型") {
this.typeList.push({
label: response.data[i].词条名称,
value: response.data[i].词条编号,
});
}
}
});
},
getDetectionTypeLabel(value) {
const type = this.typeList.find((item) => item.value === value);
return type ? type.label : value;
},
getProcessLabel(value) {
const process = this.processList.find((item) => item.value === value);
return process ? process.label : value;
},
addCheckType() {
this.checkForm = {
AID: "",
物料编号: "",
工序名称编号: "",
检测类别编号: "",
检测项目: "",
理论值: "",
上限值: "",
下限值: "",
测量单位: "",
检验比例: "",
检具: "",
备注: "",
};
this.dialogTitle = "新增检验标准";
this.dialogVisibleAdd = true;
},
submitInspection(formName) {
this.$refs[formName].validate((valid) => {
if (valid) {
const param = [];
param.push(["物料编号", this.checkForm.物料编号]);
param.push(["工序名称编号", this.checkForm.工序名称编号]);
param.push(["检测类别编号", this.checkForm.检测类别编号]);
param.push(["检测项目", this.checkForm.检测项目]);
param.push(["理论值", this.checkForm.理论值]);
param.push(["上限值", this.checkForm.上限值]);
param.push(["下限值", this.checkForm.下限值]);
param.push(["测量单位", this.checkForm.测量单位]);
param.push(["检验比例", this.checkForm.检验比例]);
param.push(["检具", this.checkForm.检具]);
param.push(["备注", this.checkForm.备注]);
const data = this.CreateData("12", "质量管理_检验标准表_新增", param);
this.ExecDatabase(data)
.then((response) => {
if (response.data[0].result !== "1") {
this.$message({
message: "检验标准提交失败!" + response.data[0].message,
type: "error",
});
return;
}
this.$message({
message: "检验标准提交成功",
type: "success",
});
this.dialogVisibleAdd = false;
this.searchTable();
})
.catch((error) => {
this.$message({
message: "检验标准提交失败: " + error,
type: "error",
});
});
}
});
},
searchTable() {
this.loading = true;
this.tableData = [];
var param = [];
if (this.物料编号) {
param.push(["物料编号", this.物料编号]);
}
if (this.工序名称编号) {
param.push(["工序名称编号", this.工序名称编号]);
}
if (this.检测类别编号) {
param.push(["检测类别编号", this.检测类别编号]);
}
var Data = this.CreateData("11", "质量管理_检验标准表_查询", param);
this.ExecDatabase(Data)
.then((response) => {
this.loading = false;
if (response.data.length !== 0) {
this.tableData = response.data;
}
})
.catch((error) => {
this.loading = false;
this.$message.error("查询失败");
});
},
editInspectionStandard(row) {
this.checkForm = {
AID: row.AID,
物料编号: row.物料编号,
工序名称编号: row.工序名称编号,
检测类别编号: row.检测类别编号,
检测项编号: row.检测项编号,
检测项目: row.检测项目,
理论值: row.理论值,
上限值: row.上限值,
下限值: row.下限值,
测量单位: row.测量单位,
检验比例: row.检验比例,
检具: row.检具,
备注: row.备注,
};
this.currentEditRow = row;
this.dialogTitle = "修改检验标准";
this.dialogVisibleChange = true;
},
updateInspection(formName) {
this.$refs[formName].validate((valid) => {
if (valid) {
// 构建更新参数 - 使用与存储过程一致的参数名
const param = [];
param.push(["AID", this.checkForm.AID]);
param.push(["物料编号", this.checkForm.物料编号]);
param.push(["工序名称编号", this.checkForm.工序名称编号]);
param.push(["检测项目", this.checkForm.检测项目]);
param.push(["理论值", this.checkForm.理论值]);
param.push(["上限值", this.checkForm.上限值]);
param.push(["下限值", this.checkForm.下限值]);
param.push(["测量单位", this.checkForm.测量单位]);
param.push(["检验比例", this.checkForm.检验比例]);
param.push(["检具", this.checkForm.检具]);
param.push(["备注", this.checkForm.备注]);
param.push(["检测类别编号", this.checkForm.检测类别编号]);
// 调用更新存储过程
const data = this.CreateData("12", "质量管理_检验标准表_修改", param);
this.ExecDatabase(data)
.then((response) => {
if (response.data[0].result !== "1") {
this.$message({
message:
"检验标准更新失败!" + (response.data[0].message || ""),
type: "error",
});
return;
}
this.$message({
message: "检验标准更新成功",
type: "success",
});
this.dialogVisibleChange = false;
this.searchTable(); // 刷新表格数据
})
.catch((error) => {
this.$message({
message: "检验标准更新失败: " + error,
type: "error",
});
});
}
});
},
deleteInspectionStandard(row) {
this.$confirm("此操作将永久删除该检验标准, 是否继续?", "提示", {
cancelButtonText: "取消",
confirmButtonText: "确定",
type: "warning",
})
.then(() => {
// 构建删除参数
const param = [];
param.push(["AID", row.AID]); // 使用传入row参数中的AID而不是currentEditRow
// 调用删除存储过程
const data = this.CreateData("12", "质量管理_检验标准表_删除", param);
this.ExecDatabase(data)
.then((response) => {
if (response.data[0].result !== "1") {
this.$message({
message:
"检验标准删除失败!" + (response.data[0].message || ""),
type: "error",
});
return;
}
this.$message({
message: "检验标准删除成功",
type: "success",
});
this.searchTable(); // 刷新表格数据
})
.catch((error) => {
this.$message({
message: "检验标准删除失败: " + error,
type: "error",
});
});
})
.catch(() => {
this.$message({
type: "info",
message: "已取消删除",
});
});
},
},
};
</script>
<style scoped lang="scss">
.search-container {
margin-bottom: 20px;
}
.dialog-footer {
margin-top: 20px;
display: flex;
justify-content: center;
}
</style>

View File

@@ -0,0 +1,479 @@
<template>
<div>
<el-card>
<span class="show-text">角色:</span>
<el-select
id="selectRoleName"
v-model="roleName"
class="personal-role-value"
filterable
placeholder="请选择"
style="width:200px;margin-right: 14px"
@change="getModule">
<el-option
v-for="item in roleNames"
:key="item.value"
:label="item.label"
:value="item.value"/>
</el-select>
<el-row style="margin-top: 10px;width: 1500px">
<el-col
:span="7"
style="border: 1px solid #bfbfbf;height: 700px;padding: 5px;border-radius: 5px;overflow: auto">
<el-input
id="inputFilterTextLeft"
v-model="filterTextLeft"
class="personal-name"
clearable
placeholder="输入关键字进行过滤"/>
<el-table
ref="multipleTableLeft"
:data="fisrtLevelFilter"
height="calc(100vh - 330px)"
highlight-current-row
stripe
style="height:calc(100vh - 330px);"
@selection-change="handleSelectionChangeLeft">
<el-table-column
:selectable="selectable"
align="center"
type="selection"
width="55"/>
<el-table-column align="center" label="模块名称">
<template slot-scope="scope">
{{ scope.row.title }}
</template>
</el-table-column>
</el-table>
</el-col>
<el-col :span="1">
<el-tooltip class="item" content="将选中一级菜单分配给该角色" effect="dark" placement="top-start">
<el-button
:disabled="!roleName || selectLeft.length === 0"
icon="el-icon-arrow-right"
style="margin: 300px auto 0 auto;display: block;width: 40px;height: 60px;padding: 12px 12px"
type="primary"
@click="giveFirstLevel"/>
</el-tooltip>
</el-col>
<el-col
:span="8"
style="border: 1px solid #bfbfbf;height: 700px;padding: 5px;border-radius: 5px;overflow: auto">
<el-input
id="inputFilterText"
v-model="filterText"
class="personal-name"
clearable
placeholder="输入关键字进行过滤"
size="small"/>
<el-tree
ref="moduleTree"
:data="moduleTree"
:filter-node-method="filterNode"
check-strictly
class="moduleTree"
default-expand-all
node-key="id"
show-checkbox
@check-change="treeCheck">
<span slot-scope="{ node, data }" class="custom-tree-node">
<span>{{ node.label }}</span>
<span>
<!-- &nbsp;-->
<!-- <div v-if="data.isPage" style="flex:1;">-->
<!-- <el-checkbox :indeterminate="data.isIndeterminate" v-model="data.AuthButtonsAll" style="margin-right: 10px" @change="handleCheckAllChange(0, $event)">全部</el-checkbox>-->
<!-- <el-checkbox v-model="data.SearchData" style="margin-right: 10px" @change="handleCheckAllChange(1, $event)">查询</el-checkbox>-->
<!-- <el-checkbox v-model="data.AddData" style="margin-right: 10px" @change="handleCheckAllChange(2, $event)">增加</el-checkbox>-->
<!-- <el-checkbox v-model="data.EditData" style="margin-right: 10px" @change="handleCheckAllChange(3, $event)">编辑</el-checkbox>-->
<!-- <el-checkbox v-model="data.DeleteData" style="margin-right: 10px" @change="handleCheckAllChange(4, $event)">删除</el-checkbox>-->
<!-- </div>-->
<el-button
:disabled="data.children && data.children.length!==0"
style="font-size: 14px"
type="text"
@click="() => returnModule(node, data)">
移除
</el-button>
</span>
</span>
</el-tree>
</el-col>
<el-col :span="1">
<el-tooltip
class="item"
content="将选中二级菜单分配给该角色选中的一级菜单"
effect="dark"
placement="top-start">
<el-button
:disabled="treeCheckList.length !== 1 || selectRight.length === 0 || treeCheckListJudge"
icon="el-icon-arrow-left"
style="margin: 300px auto 0 auto;display: block;width: 40px;height: 60px;padding: 12px 12px"
type="primary"
@click="giveSecondLevel"/>
</el-tooltip>
</el-col>
<el-col
:span="7"
style="border: 1px solid #bfbfbf;height: 700px;padding: 5px;border-radius: 5px;overflow: auto">
<el-input
id="inputFilterTextRight"
v-model="filterTextRight"
class="personal-name"
clearable
placeholder="输入关键字进行过滤"
size="small"/>
<el-table
ref="multipleTableRight"
:data="secondLevelFilter"
height="calc(100vh - 330px)"
highlight-current-row
stripe
style="height:calc(100vh - 330px);"
@selection-change="handleSelectionChangeRight">
<el-table-column
:selectable="selectable"
align="center"
type="selection"
width="55"/>
<el-table-column align="center" label="模块名称">
<template slot-scope="scope">
{{ scope.row.title }}
</template>
</el-table-column>
<el-table-column align="center" label="模块路径">
<template slot-scope="scope">
{{ scope.row.title1 }}
</template>
</el-table-column>
</el-table>
</el-col>
</el-row>
</el-card>
<el-dialog :visible.sync="dialogVisible1" center style="min-height: 300px" title="新增一级模块" width="400px">
<el-form
ref="form1"
:model="form1"
:rules="rules1"
class="demo-ruleForm"
label-position="left"
label-width="110px">
<el-form-item label="模块名称" prop="moduleName">
<el-input
v-model="form1.moduleName"
size="small"
style="width:200px"/>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogVisible1=false">取消</el-button>
<el-button type="primary" @click="submitAdd()">确定</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import {
getModule,
initFisrtLevel,
initSecondLevel,
returnModule,
giveFirstLevel,
giveSecondLevel,
submitAdd
} from '@/api/BasicData/MenuManagement'
export default {
name: 'MenuManagement',
data() {
return {
roleName: null,
roleNames: [],
filterText: '',
filterTextLeft: '',
filterTextRight: '',
allModuleId: [],
moduleTree: [],
fisrtLevel: [],
fisrtLevelFilter: [],
secondLevel: [],
secondLevelFilter: [],
selectLeft: [],
selectRight: [],
treeCheckList: [],
treeCheckListJudge: null,
dialogVisible1: false,
form1: {
moduleName: ''
},
rules1: {
moduleName: [{ required: true, message: '请输入', trigger: ['blur', 'change'] }]
}
}
},
watch: {
filterText(val) {
this.$refs.moduleTree.filter(val)
},
filterTextLeft(val) {
this.fisrtLevelFilter = this.fisrtLevel.filter(v => {
return v.title.indexOf(val) > -1
})
},
filterTextRight(val) {
this.secondLevelFilter = this.secondLevel.filter(v => {
return v.title.indexOf(val) > -1
})
}
},
created() {
this.getRoleName()
this.initFisrtLevel()
this.initSecondLevel()
},
methods: {
// 撤回分配模块
returnModule(node, data) {
this.$confirm('确定撤回分配模块?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
confirmButtonClass: 'confirm-confirm-button',
cancelButtonClass: 'confirm-cancel-button',
type: 'warning'
}).then(() => {
returnModule(data.id, this.roleName).then(response => {
if (response.data[0].result === '1') {
this.filterText = ''
this.filterTextLeft = ''
this.filterTextRight = ''
this.getModule()
this.initFisrtLevel()
this.initSecondLevel()
this.$message.success('操作成功')
} else {
this.$message.error('操作失败')
}
})
}).catch(() => {
this.$message({
type: 'info',
message: '取消操作'
})
})
},
// 分配一级
giveFirstLevel() {
this.$confirm('确定将选中的一级模块分配给选中角色?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
confirmButtonClass: 'confirm-confirm-button',
cancelButtonClass: 'confirm-cancel-button',
type: 'warning'
}).then(() => {
giveFirstLevel(this.selectLeft, this.roleName).then(response => {
if (response.data[0].result === '1') {
this.filterText = ''
this.filterTextLeft = ''
this.filterTextRight = ''
this.getModule()
this.initFisrtLevel()
this.initSecondLevel()
this.$message.success('操作成功')
} else {
this.$message.error('操作失败')
}
})
}).catch(() => {
this.$message({
type: 'info',
message: '取消操作'
})
})
},
// 分配二级
giveSecondLevel() {
if (this.$refs.moduleTree.getCheckedKeys().length === 1) {
this.$confirm('确定将选中的二级模块分配给选中角色的选中一级模块?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
confirmButtonClass: 'confirm-confirm-button',
cancelButtonClass: 'confirm-cancel-button',
type: 'warning'
}).then(() => {
giveSecondLevel(this.selectRight, this.roleName, this.$refs.moduleTree.getCheckedKeys()).then(response => {
if (response.data[0].result === '1') {
this.filterText = ''
this.filterTextLeft = ''
this.filterTextRight = ''
this.getModule()
this.initFisrtLevel()
this.initSecondLevel()
this.$message.success('操作成功')
} else {
this.$message.error('操作失败')
}
})
}).catch(() => {
this.$message({
type: 'info',
message: '取消操作'
})
})
} else {
this.$message.error('只可以分配给一个一级菜单')
}
},
// 控制某行是否可选
selectable(row) {
return !this.allModuleId.includes(row.id)
},
// 树checkChange
treeCheck() {
const param = []
this.treeCheckList = this.$refs.moduleTree.getCheckedKeys()
this.fisrtLevel.map(v => {
param.push(v.id)
})
this.treeCheckListJudge = !param.includes(parseInt(this.treeCheckList))
},
// leftChange
handleSelectionChangeLeft(val) {
this.selectLeft = []
val.map(v => {
this.selectLeft.push(v.id)
})
},
// rightChange
handleSelectionChangeRight(val) {
this.selectRight = []
val.map(v => {
this.selectRight.push(v.id)
})
},
// 初始化一级
initFisrtLevel() {
initFisrtLevel().then(res => {
this.fisrtLevel = res.data
this.fisrtLevelFilter = res.data
})
},
// 初始化二级
initSecondLevel() {
initSecondLevel().then(res => {
this.secondLevel = res.data
this.secondLevelFilter = res.data
})
},
// 新增一级
addFisrtLevel() {
if (this.$refs['form1'] !== undefined) {
this.$refs['form1'].resetFields()
}
this.form1.moduleName = ''
this.dialogVisible1 = true
},
// 确认新增一级
submitAdd() {
this.$refs['form1'].validate((valid) => {
if (valid) {
this.dialogVisible1 = false
submitAdd(this.form1.moduleName).then(response => {
if (response.data[0].result === '1') {
this.$message.success('操作成功')
this.dialogVisible1 = false
this.initFisrtLevel()
} else {
this.$message.error('操作失败')
}
})
} else {
return false
}
})
},
// 新增二级
addSecondLevel() {
console.log(1)
},
// 递归
fn(data, pid) {
const result = []
let temp
for (let i = 0; i < data.length; i++) {
if (data[i].pid === pid) {
let isPage = false
if (!data[i].redirect) isPage = true
const obj = {
'id': data[i].id,
'label': data[i].title,
'isPage': isPage,
'AddData': !!parseInt(data[i].AddData),
'DeleteData': !!parseInt(data[i].DeleteData),
'EditData': !!parseInt(data[i].EditData),
'SearchData': !!parseInt(data[i].SearchData),
'isIndeterminate': !!parseInt(data[i].DeleteData) && !!parseInt(data[i].AddData) && !!parseInt(data[i].DeleteData) && !!parseInt(data[i].SearchData),
'AuthButtonsAll': !!parseInt(data[i].DeleteData) && !!parseInt(data[i].AddData) && !!parseInt(data[i].DeleteData) && !!parseInt(data[i].SearchData)
}
temp = this.fn(data, data[i].id)
if (temp.length > 0) {
obj.children = temp
}
result.push(obj)
}
}
return result
},
// 初始化角色
getRoleName() {
var param = []
param[0] = ['角色功能', this.RoleFunctioning]
param[1] = ['PageCurrent', 1]
param[2] = ['PageSize', 1000000]
param[3] = ['PageCount', '1111', 'int', '1']
param[4] = ['ItemCount', '1111', 'int', '1']
var Data = this.CreateData('11', '菜单系统模块_项目角色_查询数据_MESWORK', param)
this.ExecDatabase(Data).then(response => {
if (response.data.result.length !== 0) {
for (let i = 0; i < response.data.result.length; i++) {
this.roleNames.push({
value: response.data.result[i].Roles_number,
label: response.data.result[i].Roles_Function
})
}
}
})
},
// 根据角色查模块
getModule() {
this.$refs.multipleTableLeft.clearSelection()
this.$refs.multipleTableRight.clearSelection()
getModule(this.roleName).then(response => {
this.allModuleId = []
response.data.map(v => {
this.allModuleId.push(v.id)
})
this.moduleTree = this.fn(response.data, 0)
})
},
// 筛选节点
filterNode(value, data) {
if (!value) return true
return data.label.indexOf(value) !== -1
},
handleCheckAllChange(value, type) {
console.log(value, type)
}
}
}
</script>
<style scoped>
.custom-tree-node {
flex: 1;
display: flex;
align-items: center;
justify-content: space-between;
font-size: 14px;
padding-right: 8px;
}
</style>

View File

@@ -0,0 +1,240 @@
<template>
<div class="app-container">
<el-card>
<span class="show-text">部门名称:</span>
<el-input v-model="RoleFunctioning" clearable placeholder="请输入部门名称" style="width: 280px;margin-right: 26px" />
<el-button icon="el-icon-search" plain type="primary" @click="searchData()">查询</el-button>
<el-button icon="el-icon-circle-plus-outline" plain style="margin-left: 14px" type="success"
@click="handleAdd('form')">
新增
</el-button>
<div style="margin-top: 10px">
<el-table v-loading="loading" :data="tableData" border element-loading-background="rgba(0, 0, 0, 0.2)"
element-loading-spinner="el-icon-loading" element-loading-text="数据加载中" height="694"
highlight-current-row size="mini" stripe style="width: 642px" tooltip-effect="dark">
<el-table-column align="center" label=" " type="index" width="100" />
<el-table-column align="center" label="部门名称" width="341">
<template slot-scope="scope">
{{ scope.row.Roles_Function }}
</template>
</el-table-column>
<el-table-column align="center" label="编辑" width="200">
<template slot-scope="scope">
<el-button icon="el-icon-edit" style="font-family: MiSans Regular,serif;color: #4d77d6"
type="text" @click="handleEdit(scope.row)">编辑
</el-button>
<el-button icon="el-icon-delete" style="font-family: MiSans Regular,serif;color: #c61a1a"
type="text" @click="handleDelete(scope.row)">删除
</el-button>
</template>
</el-table-column>
</el-table>
<div class="block" style="margin-top: 10px;">
<el-pagination v-if="!loading" :current-page="pageList" :page-size="pageSize"
:page-sizes="[10, 20, 30, 40]" :total="total" background
layout="total, sizes, prev, pager, next, jumper" @size-change="handleSizeChange"
@current-change="handleCurrentChange" />
</div>
</div>
</el-card>
<el-dialog :visible.sync="dialogFormVisible1" center title="新增部门" width="440px">
<el-divider style="margin: 0" />
<el-form ref="form" :model="form" :rules="rules" label-position="left" label-width="100px">
<el-form-item label="部门名称" prop="部门名称" style="display: inline-block">
<el-input v-model="form.角色功能" clearable placeholder="部门名称" style="width: 240px;border-radius: 4px" />
</el-form-item>
<el-row>
<el-col :span="14" />
<el-form-item>
<el-button style="width: 80px;height: 40px" type="primary" @click="submitAdd1('form')">
</el-button>
<el-button style="width: 80px;height: 40px" @click="dialogFormVisible1 = false">取消</el-button>
</el-form-item>
</el-row>
</el-form>
</el-dialog>
<el-dialog :visible.sync="dialogFormVisible2" center title="编辑部门" width="440px">
<el-divider style="margin: 0" />
<el-form ref="form2" :model="form2" :rules="rules2" label-position="left" label-width="100px">
<el-form-item label="部门名称" prop="部门名称" style="display: inline-block">
<el-input v-model="form2.角色功能" clearable placeholder="部门名称" style="width: 240px;border-radius: 4px" />
</el-form-item>
<el-row>
<el-col :span="14" />
<el-form-item>
<el-button style="width: 80px;height: 40px" type="primary" @click="submitAdd2('form2')">
</el-button>
<el-button style="width: 80px;height: 40px" @click="dialogFormVisible2 = false">取消</el-button>
</el-form-item>
</el-row>
</el-form>
</el-dialog>
</div>
</template>
<script>
export default {
data() {
return {
RoleFunctioning: '',
loading: false,
tableData: [],
dialogFormVisible1: false,
dialogFormVisible2: false,
name: '',
num: '', // 角色编号
form: {
角色功能: ''
},
form2: {
角色功能: '',
num: '' // 角色编号
},
rules: {
角色功能: [{ required: true, message: '请输入角色名称', trigger: 'blur' }]
},
rules2: {
角色功能: [{ required: true, message: '请输入角色名称', trigger: 'blur' }]
},
total: 0, // 总条数
pageSize: 10, // 每页显示条数
pageList: 1 // 后台获取页
}
},
created() {
this.searchData()
},
methods: {
// 查询
searchData() {
this.loading = true
this.tableData = []
var param = []
param[0] = ['角色功能', this.RoleFunctioning]
param[1] = ['PageCurrent', this.pageList]
param[2] = ['PageSize', this.pageSize]
param[3] = ['PageCount', '1111', 'int', '1']
param[4] = ['ItemCount', '1111', 'int', '1']
var Data = this.CreateData('11', '菜单系统模块_项目角色_查询数据_MESWORK', param)
this.ExecDatabase(Data).then(response => {
if (response.data.result.length !== 0) {
this.tableData = response.data.result
}
this.total = parseInt(response.data.output[0].ItemCount)
this.loading = false
})
},
// 编辑角色
handleEdit(row) {
if (this.$refs['form2'] !== undefined) {
this.$refs['form2'].resetFields()
}
this.form2.角色功能 = row.Roles_Function
this.form2.num = row.Roles_number
this.dialogFormVisible2 = true
},
// 编辑角色功能
submitAdd2(formName) {
this.$refs[formName].validate((valid) => {
if (valid) {
var param = []
param[0] = ['角色功能', this.form2.角色功能]
param[1] = ['角色编号', this.form2.num]
var Data = this.CreateData('11', '菜单系统模块_项目角色_修改数据_MESWORK', param)
this.ExecDatabase(Data).then(response => {
if (response.data[0].result === 1) {
this.$message({
message: '信息编辑成功',
type: 'success'
})
this.searchData()
this.dialogFormVisible2 = false
} else {
this.$message.error('存在同名角色,信息编辑失败')
}
})
}
})
},
// 增加角色
handleAdd() {
if (this.$refs['form'] !== undefined) {
this.$refs['form'].resetFields()
}
this.dialogFormVisible1 = true
},
// 确认增加角色
submitAdd1(formName) { // 增加角色功能
this.$refs[formName].validate((valid) => {
if (valid) {
var param = []
param[0] = ['角色功能', this.form.角色功能]
var Data = this.CreateData('11', '菜单系统模块_项目角色_增加_MESWORK', param)
this.ExecDatabase(Data).then(response => {
if (response.data[0].result === 1) {
this.$message({
message: '信息编辑成功',
type: 'success'
})
this.searchData()
this.dialogFormVisible1 = false
} else {
this.$message.error('存在同名角色,信息增加失败')
}
})
}
})
},
// 删除角色
handleDelete(row) {
this.$confirm('当前角色将永久删除, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
confirmButtonClass: 'confirm-confirm-button',
cancelButtonClass: 'confirm-cancel-button',
type: 'warning'
}).then(() => {
var param = []
param[0] = ['角色编号', row.Roles_number]
var Data = this.CreateData('11', '菜单系统模块_项目角色_删除_MESWORK', param)
this.ExecDatabase(Data).then(response => {
if (response.data[0].result === 1) {
this.$message.success('删除成功')
} else if (response.data[0].result === 0) {
this.$message.error('删除失败,当前角色已经分配了菜单!')
} else if (response.data[0].result === 2) {
this.$message.error('删除失败,当前角色已经分配了人员!')
} else {
this.$message.error('删除失败')
}
this.searchData()
})
}).catch(() => {
this.$message({
type: 'info',
message: '已取消删除'
})
})
},
// 分页
handleSizeChange(val) {
this.pageList = 1
this.pageSize = val
this.searchTable()
},
handleCurrentChange(val) {
this.pageList = val
this.searchTable()
}
}
}
</script>
<style scoped>
.el-card {
margin: 0px;
}
</style>

View File

@@ -0,0 +1,525 @@
<template>
<div>
<el-card>
<span class="show-text">姓名:</span>
<el-input id="inputPersonalName" v-model="PersonalName" class="personal-name" clearable placeholder="请输入姓名"
style="width: 200px;margin-right: 26px" />
<span class="show-text">角色:</span>
<el-select id="selectPersonalRoleValue" v-model="PersonalroleValue" class="personal-role-value" clearable
placeholder="请选择角色" style="width:200px;margin-right: 14px">
<el-option v-for="item in Personalrole" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
<el-button :disabled="loading" icon="el-icon-search" plain type="primary" @click="searchTable()">查询</el-button>
<el-button icon="el-icon-circle-plus-outline" plain style="margin-left: 14px" type="success"
@click="addType('form')">
新增
</el-button>
<div style="margin-top: 10px">
<el-table v-loading="loading" :data="tableData" border element-loading-background="rgba(0, 0, 0, 0.2)"
element-loading-spinner="el-icon-loading" element-loading-text="数据加载中" height="76vh" highlight-current-row
size="mini" stripe style="width: 1580px;" tooltip-effect="dark">
<el-table-column align="center" label=" " type="index" width="100" />
<el-table-column align="left" label="姓名" show-overflow-tooltip width="320">
<template slot-scope="scope">
<template v-if="scope.row.edit">
<el-input v-model="scope.row.personnel_name" clearable size="mini" style="width:200px;margin-right:3px"
width="120" />
</template>
<span v-else>{{ scope.row.personnel_name }}</span>
</template>
</el-table-column>
<el-table-column align="center" label="工号" min-width="180" show-overflow-tooltip>
<template slot-scope="scope">
<template v-if="scope.row.edit">
<el-input v-model="scope.row.account" clearable size="mini" style="width:200px;margin-right:3px"
width="120" />
</template>
<span v-else>{{ scope.row.account }}</span>
</template>
</el-table-column>
<el-table-column align="center" label="密码" min-width="180" show-overflow-tooltip>
<template slot-scope="scope">
<template v-if="scope.row.edit">
<el-input v-model="scope.row.password" clearable size="mini" style="width:200px;margin-right:3px"
width="120" />
</template>
<!-- <span v-else>{{ scope.row.password }}</span>-->
<span v-else>******</span>
</template>
</el-table-column>
<el-table-column align="center" label="角色" min-width="180" show-overflow-tooltip>
<template slot-scope="scope">
<span type="success">{{ scope.row.roles_function }}</span>
</template>
</el-table-column>
<el-table-column align="center" label="操作" min-width="450">
<template slot-scope="scope">
<el-button icon="el-icon-refresh-right" style="font-family: MiSans Regular,serif;color: #4d77d6"
type="text" @click="resetPassword(scope.row)">重置密码
</el-button>
<el-button icon="el-icon-edit" style="font-family: MiSans Regular,serif;color: #4d77d6" type="text"
@click="editType('form1', scope.row)">编辑
</el-button>
<el-button icon="el-icon-delete"
style="font-family: MiSans Regular,serif;color: #c61a1a;padding: 0;margin: 0" type="text"
@click="openDelete(scope.row)">删除&nbsp;&nbsp;
</el-button>
</template>
</el-table-column>
</el-table>
<div class="block" style="margin-top: 10px;">
<el-pagination v-if="!loading" :current-page="pageList" :page-size="pageSize" :page-sizes="[10, 20, 30, 40]"
:total="total" background layout="total, sizes, prev, pager, next, jumper" @size-change="handleSizeChange"
@current-change="handleCurrentChange" />
</div>
</div>
</el-card>
<el-dialog :show-close="false" :title="title" :visible.sync="dialogFormVisible" center width="440px">
<el-divider style="margin: 0" />
<el-form ref="form" :model="form" :rules="rules" label-position="right" label-width="100px">
<el-form-item label="姓名" prop="PersonalName">
<el-input v-model="form.PersonalName" clearable placeholder="请输入姓名" style="width: 240px;border-radius: 4px" />
</el-form-item>
<el-form-item label="工号" prop="account">
<el-input v-model="form.account" clearable placeholder="请输入工号" style="width: 240px;border-radius: 4px" />
</el-form-item>
<!-- <el-form-item label="密码" prop="password">-->
<!-- <el-input v-model="form.password" clearable placeholder="请输入密码" style="width: 240px;border-radius: 4px"/>-->
<!-- </el-form-item>-->
<el-form-item label="角色" prop="PersonalroleValue">
<el-select v-model="form.PersonalroleValue" clearable filterable placeholder="请选择角色"
style="width:240px;border-radius: 4px">
<el-option v-for="item in Personalrole" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</el-form-item>
<el-row>
<el-col :span="14" />
<el-form-item>
<el-button style="width: 80px;height: 40px" type="primary" @click="submit('form')"> </el-button>
<el-button style="width: 80px;height: 40px" @click="callOff('form')">取消</el-button>
</el-form-item>
</el-row>
</el-form>
</el-dialog>
<el-dialog :show-close="false" :title="title1" :visible.sync="dialogFormVisible1" center width="440px">
<el-divider style="margin: 0" />
<el-form ref="form1" :model="form1" :rules="rules1" label-position="right" label-width="100px">
<el-form-item label="姓名" prop="PersonalName">
<el-input v-model="form1.PersonalName" clearable placeholder="请输入姓名"
style="width: 240px;border-radius: 4px" />
</el-form-item>
<el-form-item label="工号" prop="account">
<el-input v-model="form1.account" placeholder="请输入工号" readonly style="width: 240px;border-radius: 4px" />
</el-form-item>
<!-- <el-form-item label="密码" prop="password">-->
<!-- <el-input-->
<!-- v-model="form1.password"-->
<!-- clearable-->
<!-- placeholder="请输入密码"-->
<!-- style="width: 240px;border-radius: 4px"/>-->
<!-- </el-form-item>-->
<el-form-item label="角色" prop="PersonalroleValue">
<el-select v-model="form1.PersonalroleValue" clearable filterable placeholder="请选择角色"
style="width:240px;border-radius: 4px">
<el-option v-for="item in Personalrole" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</el-form-item>
<el-row>
<el-col :span="14" />
<el-form-item>
<el-button style="width: 80px;height: 40px" type="primary" @click="confirmEdit('form1')"> </el-button>
<el-button style="width: 80px;height: 40px" @click="callOff1('form1')">取消</el-button>
</el-form-item>
</el-row>
</el-form>
</el-dialog>
</div>
</template>
<script>
export default {
data() {
return {
PersonalName: '', // 姓名
PersonalroleValue: '', // 角色
Personalrole: [],
title: '',
title1: '',
dialogFormVisible: false,
dialogFormVisible1: false,
isShowSearchOpNamePermission: false,
clickOpNamePermissionList: [],
isShowCameraPermission: false, // 摄像头权限
cameraPermissionList: [],
form: {
PersonalName: '',
account: '',
password: '',
PersonalroleValue: ''
},
rules: {
PersonalName: [{ required: true, message: '请输入姓名', trigger: 'blur' }],
account: [{ required: true, message: '请输入账号', trigger: 'change' }],
password: [{ required: true, message: '请输入密码', trigger: 'change' }],
PersonalroleValue: [{ required: true, message: '请选择角色', trigger: 'blur' }]
},
form1: {
PersonalName: '',
account: '',
password: '',
PersonalroleValue: ''
},
rules1: {
PersonalName: [{ required: true, message: '请输入姓名', trigger: 'blur' }],
account: [{ required: true, message: '请输入账号', trigger: 'change' }],
password: [{ required: true, message: '请输入密码', trigger: 'change' }],
PersonalroleValue: [{ required: true, message: '请选择角色', trigger: 'blur' }]
},
loading: false,
tableData: [],
total: 0, // 总条数
pageSize: 10, // 每页显示条数
pageList: 1 // 后台获取页
}
},
created() {
this.getPersonalrole()
this.searchTable()
},
methods: {
// 初始化获取角色信息
getPersonalrole() {
this.Personalrole = []
var Data = this.CreateData('11', '人员管理_角色信息初始化查询_查询')
this.ExecDatabase(Data).then(response => {
for (let i = 0; i < response.data.length; i++) {
this.Personalrole.push({
label: response.data[i].Roles_Function,
value: response.data[i].Roles_number
})
}
})
},
changeIsClient(row) {
var param = []
param[0] = ['Personnel_Number', row.personnel_number]
param[1] = ['value', row.isClient]
var Data = this.CreateData('12', '登录基础数据_人员信息_切换是否用户', param)
this.ExecDatabase(Data).then(response => {
if (response.data[0].result === '1') {
this.$message({
message: '修改成功',
type: 'success'
})
this.searchTable()
} else {
this.$message.error('修改失败')
}
})
},
// 查询
searchTable() {
if (this.PersonalName === '' || this.PersonalName === null) {
this.PersonalName_check = 0
} else {
this.PersonalName_check = 1
}
if (this.PersonalroleValue === '' || this.PersonalroleValue === null) {
this.PersonalroleValue_check = 0
} else {
this.PersonalroleValue_check = 1
}
this.loading = true
this.tableData = []
var param = []
param[0] = ['姓名_check', this.PersonalName_check]
param[1] = ['姓名', this.PersonalName]
param[2] = ['角色代码_check', this.PersonalroleValue_check]
param[3] = ['角色代码', this.PersonalroleValue]
param[4] = ['PageCurrent', this.pageList]
param[5] = ['PageSize', this.pageSize]
param[6] = ['PageCount', '1111', 'int', '1']
param[7] = ['ItemCount', '1111', 'int', '1']
var Data = this.CreateData('11', '人员管理_人员信息查询_查询', param)
this.ExecDatabase(Data).then(response => {
if (response.data.result.length !== 0) {
for (let i = 0; i < response.data.result.length; i++) {
this.tableData.push({
personnel_number: response.data.result[i].Personnel_Number,
personnel_name: response.data.result[i].Personnel_Name,
account: response.data.result[i].account,
password: response.data.result[i].password,
roles_number: parseInt(response.data.result[i].Roles_number),
roles_function: response.data.result[i].Roles_Function,
isClient: response.data.result[i].isClient
})
}
}
this.total = parseInt(response.data.output[0].ItemCount)
this.loading = false
})
},
// 点击编辑
editType(formName, row) {
if (this.$refs[formName] !== undefined) {
this.$refs[formName].resetFields()
}
this.form1.PersonalName = row.personnel_name
this.form1.personnel_number = row.personnel_number
this.form1.account = row.account
this.form1.password = row.password
this.form1.PersonalroleValue = row.roles_number
this.title1 = '编辑人员'
this.dialogFormVisible1 = true
},
// 确定编辑
confirmEdit(formName) {
this.$refs[formName].validate((valid) => {
if (valid) {
var param = []
param[0] = ['Personnel_Number', this.form1.personnel_number]
param[1] = ['account', this.form1.account]
param[2] = ['password', this.form1.password]
param[3] = ['Personnel_Name', this.form1.PersonalName]
param[4] = ['Roles_number', this.form1.PersonalroleValue]
if (this.form1.account === '' || this.form1.account === null) {
this.$message.error('请输入工号')
} else if (this.form1.password === '' || this.form1.password === null) {
this.$message.error('请输入密码')
} else if (this.form1.personnel_name === '' || this.form1.personnel_name === null) {
this.$message.error('请输入姓名')
} else if (this.form1.PersonalroleValue === '' || this.form1.PersonalroleValue === null) {
this.$message.error('请选择角色')
} else {
var Data = this.CreateData('12', '人员管理_人员信息修改_编辑', param)
this.ExecDatabase(Data).then(response => {
if (response.data[0].result === '1') {
this.$message({
message: '信息编辑成功',
type: 'success'
})
this.searchTable()
this.dialogFormVisible1 = false
} else {
this.$message.error('信息编辑失败')
}
})
}
}
})
},
// 删除
openDelete(row) {
this.$confirm('当前人员将永久删除, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
confirmButtonClass: 'confirm-confirm-button',
cancelButtonClass: 'confirm-cancel-button',
type: 'warning'
}).then(() => {
var param = []
param[0] = ['Personnel_Number', row.personnel_number]
var Data = this.CreateData('12', '人员管理_人员信息修改_删除', param)
this.ExecDatabase(Data).then(response => {
if (response.data[0].result === '1') {
this.$message({
message: '人员离职成功',
type: 'success'
})
this.searchTable()
} else {
this.$message.error('人员离职失败')
}
})
}).catch(() => {
this.$message({
type: 'info',
message: '已取消删除'
})
})
},
// 点击增加
addType(formName) {
if (this.$refs[formName] !== undefined) {
this.$refs[formName].resetFields()
}
this.form.PersonalName = ''
this.form.account = ''
this.form.password = '123456'
this.form.PersonalroleValue = ''
this.title = '增加人员'
this.dialogFormVisible = true
},
// 增加确定
submit(formName) {
this.$refs[formName].validate((valid) => {
if (valid) {
// 验证密码复杂性 最小六位 并且必须存在数字 与 字母
// 复杂度校验放在第二次手动设置密码中了
// if (this.form.password.length < 6 || !/[0-9]/.test(this.form.password) || !/[a-zA-Z]/.test(this.form.password)) {
// this.$message.error('密码复杂度不符合要求,最小六位且必须数字与字母同时存在')
// return false
// }
var param = []
param[0] = ['Personnel_Name', this.form.PersonalName]
param[1] = ['account', this.form.account]
param[2] = ['password', this.form.password]
param[3] = ['Roles_number', this.form.PersonalroleValue]
var Data = this.CreateData('11', '人员管理_人员信息新增_新增', param)
this.ExecDatabase(Data).then(response => {
if (response.data[0].result === '1') {
this.$message({
message: '信息增加成功',
type: 'success'
})
this.pageList = 1
this.pageSize = 10
this.searchTable()
} else {
this.$message.error('信息增加失败')
}
})
this.dialogFormVisible = false
} else {
return false
}
})
},
// 查看设备权限
searchOpNamePermission(row) {
console.log(row)
this.isShowSearchOpNamePermission = true
this.getUserOpNameList(row.personnel_number)
},
// 摄像头权限
searchCameraPermission(row) {
console.log(row)
this.isShowCameraPermission = true
this.getCameraPermission(row.personnel_number)
},
getCameraPermission(personnel_number) {
this.cameraPermissionList = []
var param = []
param[0] = ['Personnel_Number', personnel_number]
var Data = this.CreateData('11', 'WEB_摄像头查看权限_查询', param)
this.ExecDatabase(Data).then(response => {
if (response.data.length != 0) {
this.cameraPermissionList = response.data
}
})
},
// 重置密码
resetPassword(row) {
this.$confirm('是否重置此用户的登陆密码为初始密码?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
confirmButtonClass: 'confirm-confirm-button',
cancelButtonClass: 'confirm-cancel-button',
type: 'warning'
}).then(() => {
this.clickOpNamePermissionList = []
var param = []
param[0] = ['Personnel_Number', row.personnel_number]
var Data = this.CreateData('12', 'WEB_登录基础数据_人员信息_重置密码', param)
this.ExecDatabase(Data).then(response => {
if (response.data[0].result == 1) {
this.$message.success('密码重置成功初始密码为123456')
}
})
})
},
getUserOpNameList(personnel_number) {
this.clickOpNamePermissionList = []
var param = []
param[0] = ['Personnel_Number', personnel_number]
var Data = this.CreateData('11', 'WEB_人员设备查看权限_查询', param)
this.ExecDatabase(Data).then(response => {
if (response.data[0].length != 0) {
this.clickOpNamePermissionList = response.data
}
})
},
updateOpNamePermission(row, type) {
console.log(row)
this.$confirm('是否确认切换设权限', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
var param = []
param[0] = ['设备AID', row.设备AID]
param[1] = ['Personnel_Number', row.Personnel_Number]
param[2] = ['type', type]
var Data = this.CreateData('12', 'WEB_人员设备查看权限_权限切换', param)
this.ExecDatabase(Data).then(response => {
if (response.data[0].result == '1') {
this.$message.success('权限切换成功')
this.getUserOpNameList(row.Personnel_Number)
}
})
})
},
updateCameraPermission(row, type) {
console.log(row)
this.$confirm('是否确认切换摄像头权限', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
var param = []
param[0] = ['摄像头AID', row.AID]
param[1] = ['Personnel_Number', row.Personnel_Number]
param[2] = ['type', type]
var Data = this.CreateData('12', 'WEB_人员摄像头查看权限_权限切换', param)
this.ExecDatabase(Data).then(response => {
if (response.data[0].result == '1') {
this.$message.success('权限切换成功')
this.getCameraPermission(row.Personnel_Number)
}
})
})
},
tableRowClassName({ row }) {
if (row.是否授权 == 1) {
return 'success'
} else {
return 'no-success'
}
},
// 重置表单
callOff(formName) {
this.dialogFormVisible = false
this.$refs[formName].resetFields()
},
// 重置表单
callOff1(formName) {
this.dialogFormVisible1 = false
this.$refs[formName].resetFields()
},
// 分页
handleSizeChange(val) {
this.pageList = 1
this.pageSize = val
this.searchTable()
},
handleCurrentChange(val) {
this.pageList = val
this.searchTable()
}
}
}
</script>
<style scoped>
::v-deep.el-table .success {}
::v-deep.el-table .no-success {}
</style>

View File

@@ -0,0 +1,275 @@
<template>
<div class="app-container">
<el-card>
<span class="show-text">角色功能:</span>
<el-input
v-model="RoleFunctioning"
clearable
placeholder="请输入角色功能"
style="width: 280px;margin-right: 26px"/>
<el-button icon="el-icon-search" plain type="primary" @click="searchData()">查询</el-button>
<el-button
icon="el-icon-circle-plus-outline"
plain
style="margin-left: 14px"
type="success"
@click="handleAdd('form')">
新增
</el-button>
<div style="margin-top: 10px">
<el-table
v-loading="loading"
:data="tableData"
border
element-loading-background="rgba(0, 0, 0, 0.2)"
element-loading-spinner="el-icon-loading"
element-loading-text="数据加载中"
height="694"
highlight-current-row
size="mini"
stripe
style="width: 642px"
tooltip-effect="dark">
<el-table-column align="center" label=" " type="index" width="100"/>
<el-table-column align="center" label="角色功能" width="341">
<template slot-scope="scope">
{{ scope.row.Roles_Function }}
</template>
</el-table-column>
<el-table-column align="center" label="编辑" width="200">
<template slot-scope="scope">
<el-button
icon="el-icon-edit"
style="font-family: MiSans Regular,serif;color: #4d77d6"
type="text"
@click="handleEdit(scope.row)">编辑
</el-button>
<el-button
icon="el-icon-delete"
style="font-family: MiSans Regular,serif;color: #c61a1a"
type="text"
@click="handleDelete(scope.row)">删除
</el-button>
</template>
</el-table-column>
</el-table>
<div class="block" style="margin-top: 10px;">
<el-pagination
v-if="!loading"
:current-page="pageList"
:page-size="pageSize"
:page-sizes="[10, 20, 30, 40]"
:total="total"
background
layout="total, sizes, prev, pager, next, jumper"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"/>
</div>
</div>
</el-card>
<el-dialog :visible.sync="dialogFormVisible1" center title="新增角色" width="440px">
<el-divider style="margin: 0"/>
<el-form ref="form" :model="form" :rules="rules" label-position="left" label-width="100px">
<el-form-item label="角色功能" prop="角色功能" style="display: inline-block">
<el-input
v-model="form.角色功能"
clearable
placeholder="角色功能"
style="width: 240px;border-radius: 4px"/>
</el-form-item>
<el-row>
<el-col :span="14"/>
<el-form-item>
<el-button style="width: 80px;height: 40px" type="primary" @click="submitAdd1('form')"> </el-button>
<el-button style="width: 80px;height: 40px" @click="dialogFormVisible1 = false">取消</el-button>
</el-form-item>
</el-row>
</el-form>
</el-dialog>
<el-dialog :visible.sync="dialogFormVisible2" center title="编辑角色" width="440px">
<el-divider style="margin: 0"/>
<el-form ref="form2" :model="form2" :rules="rules2" label-position="left" label-width="100px">
<el-form-item label="角色名称" prop="角色功能" style="display: inline-block">
<el-input
v-model="form2.角色功能"
clearable
placeholder="角色功能"
style="width: 240px;border-radius: 4px"/>
</el-form-item>
<el-row>
<el-col :span="14"/>
<el-form-item>
<el-button style="width: 80px;height: 40px" type="primary" @click="submitAdd2('form2')"> </el-button>
<el-button style="width: 80px;height: 40px" @click="dialogFormVisible2 = false">取消</el-button>
</el-form-item>
</el-row>
</el-form>
</el-dialog>
</div>
</template>
<script>
export default {
data() {
return {
RoleFunctioning: '',
loading: false,
tableData: [],
dialogFormVisible1: false,
dialogFormVisible2: false,
name: '',
num: '', // 角色编号
form: {
角色功能: ''
},
form2: {
角色功能: '',
num: '' // 角色编号
},
rules: {
角色功能: [{ required: true, message: '请输入角色名称', trigger: 'blur' }]
},
rules2: {
角色功能: [{ required: true, message: '请输入角色名称', trigger: 'blur' }]
},
total: 0, // 总条数
pageSize: 10, // 每页显示条数
pageList: 1 // 后台获取页
}
},
created() {
this.searchData()
},
methods: {
// 查询
searchData() {
this.loading = true
this.tableData = []
var param = []
param[0] = ['角色功能', this.RoleFunctioning]
param[1] = ['PageCurrent', this.pageList]
param[2] = ['PageSize', this.pageSize]
param[3] = ['PageCount', '1111', 'int', '1']
param[4] = ['ItemCount', '1111', 'int', '1']
var Data = this.CreateData('11', '菜单系统模块_项目角色_查询数据_MESWORK', param)
this.ExecDatabase(Data).then(response => {
if (response.data.result.length !== 0) {
this.tableData = response.data.result
}
this.total = parseInt(response.data.output[0].ItemCount)
this.loading = false
})
},
// 编辑角色
handleEdit(row) {
if (this.$refs['form2'] !== undefined) {
this.$refs['form2'].resetFields()
}
this.form2.角色功能 = row.Roles_Function
this.form2.num = row.Roles_number
this.dialogFormVisible2 = true
},
// 编辑角色功能
submitAdd2(formName) {
this.$refs[formName].validate((valid) => {
if (valid) {
var param = []
param[0] = ['角色功能', this.form2.角色功能]
param[1] = ['角色编号', this.form2.num]
var Data = this.CreateData('11', '菜单系统模块_项目角色_修改数据_MESWORK', param)
this.ExecDatabase(Data).then(response => {
if (response.data[0].result === 1) {
this.$message({
message: '信息编辑成功',
type: 'success'
})
this.searchData()
this.dialogFormVisible2 = false
} else {
this.$message.error('存在同名角色,信息编辑失败')
}
})
}
})
},
// 增加角色
handleAdd() {
if (this.$refs['form'] !== undefined) {
this.$refs['form'].resetFields()
}
this.dialogFormVisible1 = true
},
// 确认增加角色
submitAdd1(formName) { // 增加角色功能
this.$refs[formName].validate((valid) => {
if (valid) {
var param = []
param[0] = ['角色功能', this.form.角色功能]
var Data = this.CreateData('11', '菜单系统模块_项目角色_增加_MESWORK', param)
this.ExecDatabase(Data).then(response => {
if (response.data[0].result === 1) {
this.$message({
message: '信息编辑成功',
type: 'success'
})
this.searchData()
this.dialogFormVisible1 = false
} else {
this.$message.error('存在同名角色,信息增加失败')
}
})
}
})
},
// 删除角色
handleDelete(row) {
this.$confirm('当前角色将永久删除, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
confirmButtonClass: 'confirm-confirm-button',
cancelButtonClass: 'confirm-cancel-button',
type: 'warning'
}).then(() => {
var param = []
param[0] = ['角色编号', row.Roles_number]
var Data = this.CreateData('11', '菜单系统模块_项目角色_删除_MESWORK', param)
this.ExecDatabase(Data).then(response => {
if (response.data[0].result === 1) {
this.$message.success('删除成功')
} else if (response.data[0].result === 0) {
this.$message.error('删除失败,当前角色已经分配了菜单!')
} else if (response.data[0].result === 2) {
this.$message.error('删除失败,当前角色已经分配了人员!')
} else {
this.$message.error('删除失败')
}
this.searchData()
})
}).catch(() => {
this.$message({
type: 'info',
message: '已取消删除'
})
})
},
// 分页
handleSizeChange(val) {
this.pageList = 1
this.pageSize = val
this.searchTable()
},
handleCurrentChange(val) {
this.pageList = val
this.searchTable()
}
}
}
</script>
<style scoped>
.el-card {
margin: 0px;
}
</style>

View File

@@ -0,0 +1,305 @@
<template>
<div class="app-container">
<el-card>
<span class="show-text">工位名称:</span>
<el-input
v-model="RoleFunctioning"
clearable
placeholder="请输入工位名称"
style="width: 280px;margin-right: 26px"/>
<el-button icon="el-icon-search" plain type="primary" @click="searchData()">查询</el-button>
<el-button
icon="el-icon-circle-plus-outline"
plain
style="margin-left: 14px"
type="success"
@click="handleAdd('form')">
新增
</el-button>
<div style="margin-top: 10px">
<el-table
v-loading="loading"
:data="tableData"
border
element-loading-background="rgba(0, 0, 0, 0.2)"
element-loading-spinner="el-icon-loading"
element-loading-text="数据加载中"
height="694"
highlight-current-row
size="mini"
stripe
style="width: 642px"
tooltip-effect="dark">
<el-table-column align="center" label=" " type="index" width="100"/>
<el-table-column align="center" label="工位名称" width="100">
<template slot-scope="scope">
{{ scope.row.指南工位号 }}
</template>
</el-table-column>
<el-table-column align="center" label="工位号" width="100">
<template slot-scope="scope">
{{ scope.row.工位号 }}
</template>
</el-table-column>
<el-table-column align="center" label="编辑" width="200">
<template slot-scope="scope">
<el-button
icon="el-icon-edit"
style="font-family: MiSans Regular,serif;color: #4d77d6"
type="text"
@click="handleEdit(scope.row)">编辑
</el-button>
<!-- <el-button
icon="el-icon-delete"
style="font-family: MiSans Regular,serif;color: #c61a1a"
type="text"
@click="handleDelete(scope.row)">删除
</el-button> -->
</template>
</el-table-column>
</el-table>
</div>
</el-card>
<el-dialog :visible.sync="dialogFormVisible1" center title="新增工位" width="440px">
<el-divider style="margin: 0"/>
<el-form ref="form" :model="form" :rules="rules" label-position="left" label-width="100px">
<el-form-item label="工位名称" prop="工位名称" style="display: inline-block">
<el-input
v-model="form.工位名称"
clearable
placeholder="工位名称"
style="width: 240px;border-radius: 4px"/>
</el-form-item>
<el-form-item label="工位号" prop="工位号" style="display: inline-block">
<el-input
v-model="form.工位号"
clearable
placeholder="工位号"
style="width: 240px;border-radius: 4px"/>
</el-form-item>
<el-row>
<el-col :span="14"/>
<el-form-item>
<el-button style="width: 80px;height: 40px" type="primary" @click="submitAdd1('form')"> </el-button>
<el-button style="width: 80px;height: 40px" @click="dialogFormVisible1 = false">取消</el-button>
</el-form-item>
</el-row>
</el-form>
</el-dialog>
<el-dialog :visible.sync="dialogFormVisible2" center title="编辑工位" width="440px">
<el-divider style="margin: 0"/>
<el-form ref="form2" :model="form2" :rules="rules2" label-position="left" label-width="100px">
<el-form-item label="工位名称" prop="工位名称" style="display: inline-block">
<el-input
v-model="form2.工位名称"
clearable
placeholder="工位名称"
style="width: 240px;border-radius: 4px"/>
</el-form-item>
<el-row>
<el-col :span="14"/>
<el-form-item>
<el-button style="width: 80px;height: 40px" type="primary" @click="submitAdd2('form2')"> </el-button>
<el-button style="width: 80px;height: 40px" @click="dialogFormVisible2 = false">取消</el-button>
</el-form-item>
</el-row>
</el-form>
</el-dialog>
</div>
</template>
<script>
import { postB1 } from '@/api/b1s';
import { getB1 } from '@/api/b1s';
import { patchB1 } from '@/api/b1s';
export default {
data() {
return {
RoleFunctioning: '',
loading: false,
tableData: [],
dialogFormVisible1: false,
dialogFormVisible2: false,
name: '',
num: '', // 工位号
form: {
工位名称: ''
},
form2: {
工位名称: '',
num: '' // 工位号
},
rules: {
工位名称: [{ required: true, message: '请输入工位名称', trigger: 'blur' }],
工位号: [{ required: true, message: '请输入工位名称', trigger: 'blur' }]
},
rules2: {
工位名称: [{ required: true, message: '请输入工位名称', trigger: 'blur' }]
},
}
},
created() {
this.searchData()
var now = new Date();
var start = new Date(
Date.UTC(now.getFullYear() , now.getMonth(), now.getDate())
)
.toISOString()
.replace("T", " ")
.replace(".000Z", "");
var end = new Date(
Date.UTC(now.getFullYear(), now.getMonth(), now.getDate(), 23, 59, 59)
)
.toISOString()
.replace("T", " ")
.replace(".000Z", "");
this.completionTime= [start, end];
},
methods: {
// 查询
searchData() {
this.loading = true
this.tableData = []
var param = []
var Data = this.CreateData('11', 'MES_登录_工位与名称_查询', param)
this.ExecDatabase(Data).then(response => {
if (response.data.length !== 0) {
this.tableData = response.data
}
this.loading = false
})
},
// 编辑工位
handleEdit(row) {
if (this.$refs['form2'] !== undefined) {
this.$refs['form2'].resetFields()
}
this.form2.工位名称 = row.工位名称
this.form2.工位号 = row.工位号
this.dialogFormVisible2 = true
},
// 编辑工位功能
submitAdd2(formName) {
this.$refs[formName].validate((valid) => {
if (valid) {
var param = []
param[0] = ['工位名称', this.form2.工位名称.toString()]
param[1] = ['工位号', this.form2.工位号.toString()]
var Data = this.CreateData('11', '系统管理_工位管理_工位信息修改', param)
this.ExecDatabase(Data).then( async response => {
if (response.data[0].result === 1) {
this.$message({
message: '信息编辑成功',
type: 'success'
})
this.$message.success('编辑成功')
patchB1("/Resources('"+this.form2.工位号.toString()+"')",{
"Name": this.form2.工位名称.toString()
})
this.searchData()
this.dialogFormVisible2 = false
} else {
this.$message.error('存在同名工位,信息编辑失败')
}
})
}
})
},
// 增加工位
handleAdd() {
if (this.$refs['form'] !== undefined) {
this.$refs['form'].resetFields()
}
this.dialogFormVisible1 = true
},
// 确认增加工位
submitAdd1(formName) { // 增加工位功能
this.$refs[formName].validate((valid) => {
if (valid) {
var param = []
param[0] = ['工位名称', this.form.工位名称.toString()]
param[1] = ['工位号', this.form.工位号.toString()]
var Data = this.CreateData('11', '系统管理_工位管理_工位信息增加', param)
this.ExecDatabase(Data).then(response => {
if (response.data[0].result === 1) {
this.$message({
message: '信息编辑成功',
type: 'success'
})
postB1("/Resources",{
"VisCode": this.form.工位号,
"Name": this.form.工位名称,
"ForeignName": '',
"Type": "rtMachine",
"Group": 1,
"UnitOfMeasure": '',
"IssueMethod": "rimManual",
"Active": "tYES",
"Inactive": "tNO",
"Remarks": '',
"Allocation": "raOnStartDate"
})
this.searchData()
this.dialogFormVisible1 = false
} else {
this.$message.error('存在同名工位,信息增加失败')
}
})
}
})
},
// 删除工位
handleDelete(row) {
this.$confirm('当前工位将永久删除, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
confirmButtonClass: 'confirm-confirm-button',
cancelButtonClass: 'confirm-cancel-button',
type: 'warning'
}).then(() => {
var param = []
param[0] = ['工位号', row.工位号]
var Data = this.CreateData('11', '系统管理_工位管理_工位信息删除', param)
this.ExecDatabase(Data).then(response => {
if (response.data[0].result === 1) {
this.$message.success('删除成功')
// } else if (response.data[0].result === 0) {
// this.$message.error('删除失败,当前工位已经分配了菜单!')
// } else if (response.data[0].result === 2) {
// this.$message.error('删除失败,当前工位已经分配了人员!')
// } else {
// this.$message.error('删除失败')
}
this.searchData()
})
}).catch(() => {
this.$message({
type: 'info',
message: '已取消删除'
})
})
},
// 分页
handleSizeChange(val) {
this.pageList = 1
this.pageSize = val
this.searchTable()
},
handleCurrentChange(val) {
this.pageList = val
this.searchTable()
}
}
}
</script>
<style scoped>
.el-card {
margin: 0px;
}
</style>

View File

@@ -0,0 +1,355 @@
<template>
<div id="fullscreen" ref="fullscreen" class="fullscreen">
<!-- <div style="width: 500px;height:770px;filter:blur(10);z-index: 999">-->
<!-- <d-m-t ref="dmtDashBoard" containerheight="800px" containerwidth="1640px" />-->
<!-- </div>-->
<el-card style="min-height:calc(100vh - 84px);background-size:100% 100%">
<!-- <a-button type="primary" @click="fullScreen()">全屏</a-button> -->
<div class="dashboard-container">
<div class="sudoku_row">
<!-- <div v-for="(value3, index3) in fathers1" :key="'info2-' + index3" style="width:100%">
<div style="margin-top: 20px" />
<el-divider content-position="left">{{ value3.title }}</el-divider>
<a v-for="(value4, index4) in sons1" v-if="value4.pid === value3.id" :key="index4" target="_blank"
:href="value4.path">
<el-card class="sudoku_item" shadow="hover"
style="height:130px;width:150px;margin: 5px;display: inline-block;background: rgba(255,255,255,0.4)">
<svg-icon :icon-class="value4.icon" :style="{ color: Color(index4) }" class="bgc"
style="display:block;margin: auto;border: 0 solid black;width:50px;height:50px" />
<br>
<div style="color:black;text-align:center;margin-top: -10px">{{ value4.title }}</div>
</el-card>
</a>
</div> -->
<div v-for="(value1, index1) in fathers" :key="index1" style="width:100%">
<div style="margin-top: 20px" />
<el-divider content-position="left">{{ value1.title }}</el-divider>
<router-link v-for="(value2, index2) in sons" v-if="value2.pid === value1.id" :key="index2"
:to="value2.path">
<el-card class="sudoku_item" shadow="hover"
style="height:130px;width:150px;margin: 5px;display: inline-block;background: rgba(255,255,255,0.4)">
<svg-icon :icon-class="value2.icon" :style="{ color: Color(index2) }" class="bgc"
style="display:block;margin: auto;border: 0 solid black;width:50px;height:50px" />
<br>
<div style="color:black;text-align:center;margin-top: -10px">{{ value2.title }}</div>
</el-card>
</router-link>
</div>
</div>
</div>
</el-card>
</div>
</template>
<script>
import { mapGetters } from 'vuex'
import request from '@/utils/request'
import Router from '@/router/index'
// import DMT from '../../components/DMT/index'
export default {
name: 'Dashboard',
// components: { DMT },
data() {
return {
a: '',
sudokus: [],
curSelect: null,
number: '',
timer: '',
fathers: [],
sons: [],
fathers1: [],
sons1: [],
// 上一次点击时间
lastTime: null,
// 当前时间
currentTime: null,
// 超时时间, 如果半个小时都没有点击页面就算超时
sys_timeout: 12 * 60 * 60 * 1000,
// 检查的时间每隔5分钟检查一次有没有超时
check_time: 5 * 60 * 1000,
// 计时器
whole_timer: null,
}
},
created() {
// 启动这个定时器
this.isLoginOut()
},
computed: {
...mapGetters([
'name',
'token',
'id'
])
},
mounted() {
// this.getFileList()
// this.timer = setInterval(this.getFileList, 60 * 60 * 1000) // 60 分钟一刷新
this.initFirstModule()
this.initSecondModule()
},
beforeDestroy() {
// clearInterval(this.timer)
},
methods: {
toView(path) {
},
fullScreen() {
const result = logintm()
// 全屏
// var full = document.getElementById('fullscreen')
// this.launchIntoFullscreen(full)
},
exitFullscreen() {
if (document.exitFullscreen) {
document.exitFullscreen()
} else if (document.mozCancelFullScreen) {
document.mozCancelFullScreen()
} else if (document.webkitExitFullscreen) {
document.webkitExitFullscreen()
}
},
checkFull() {
// 判断浏览器是否处于全屏状态 (需要考虑兼容问题)
// 火狐浏览器
let isFull = document.mozFullScreen ||
document.fullScreen ||
// 谷歌浏览器及Webkit内核浏览器
document.webkitIsFullScreen ||
document.webkitRequestFullScreen ||
document.mozRequestFullScreen ||
document.msFullscreenEnabled
if (isFull === undefined) {
isFull = false
}
return isFull
},
launchIntoFullscreen(element) {
if (element.requestFullscreen) {
element.requestFullscreen()
} else if (element.mozRequestFullScreen) {
element.mozRequestFullScreen()
} else if (element.webkitRequestFullscreen) {
element.webkitRequestFullscreen()
} else if (element.msRequestFullscreen) {
element.msRequestFullscreen()
}
},
// 获取自己写的静态路由
getRouter() {
var constantRouterMap = Router.options.routes[0]
this.fathers1.push({
id: 1000,
title: constantRouterMap.meta.title
})
for (let i = 0; i < constantRouterMap.children.length; i++) {
this.sons1.push({
id: i,
pid: 1000,
path: constantRouterMap.children[i].path,
icon: constantRouterMap.children[i].meta.icon,
title: constantRouterMap.children[i].meta.title
})
}
},
async initFirstModule() {
await request({
url: '',
method: 'post',
data: {
type: '3',
name: `select * from 登录基础数据_二级菜单 where 账号代码= ${this.token} and pid = 0 and 是否启用 = 1 order by id `
}
}).then(data => {
this.fathers = []
data.data.map(v => {
this.fathers.push({
id: v.id,
title: v.title
})
})
})
},
Color(index) {
// const colorAngle = Math.floor(Math.random() * 360 + index)
// return 'hsla(' + colorAngle + ',70%,30%,1)'
// 返回固定颜色
return 'rgb(37, 89, 164)'
},
async initSecondModule() {
await request({
url: '',
method: 'post',
data: {
type: '1',
name: '菜单模块系统_项目角色模块列表_二级_查询数据',
param: `角色编号=${this.token}`
}
}).then(data => {
this.sons = []
data.data.map(v => {
this.sons.push({
id: v.id,
pid: v.pid,
path: v.componet,
icon: v.icon,
title: v.title
})
})
// this.getRouter()
})
},
// async getFileList() {
// await request({
// url: '',
// method: 'post',
// data: {
// type: '3',
// name: `select * from 基础表_角色模块信息 inner join 基础表_模块信息 on 基础表_角色模块信息.id = 基础表_模块信息.id where 角色编号=${this.token} and 是否通知 = 1`
// }
// }).then(data => {
// this.sudokus = []
// for (let i = 0; i < data.data.length; i++) {
// this.getMessageNum(data.data[i].消息通知来源, data.data[i].通知条件, data, i)
// }
// console.log(this.sudokus)
// })
// },
// async getMessageNum(tableName, condition, rawData, i) {
// await request({
// url: '',
// method: 'post',
// data: {
// type: '3',
// name: `select count(*) from ${tableName} where ${condition}`
// }
// }).then(res => {
// this.sudokus.push({
// id: rawData.data[i].id,
// name: rawData.data[i].title,
// icon: rawData.data[i].icon,
// router: rawData.data[i].path,
// value: res.data[0].Column1
// })
// })
// }
isTimeOut() {
// 页面上一次的点击时间
this.lastTime = this.$store.state.login.lastTime
this.currentTime = new Date().getTime()
// 超时了
if ((this.currentTime - this.lastTime) > this.sys_timeout) {
return true
} else {
return false
}
},
isLoginOut() {
// console.log("11111:" + this)
// 每次用定时器之前先清除一下
clearInterval(this.whole_timer)
// 这里要备份一下this指针
const _this = this
this.whole_timer = setInterval(function() {
// 判断一下是否超时,如果超时了就退出
if (_this.isTimeOut()) {
// console.log("22222:" + this)
_this.$store.dispatch('FedLogOut')
_this.$router.push(`/login?redirect=${_this.$route.fullPath}`)
// 如果退出了就清除这个定时器,这里要延迟一秒清除,因为跳转到登录界面会有一点点延迟~
setTimeout(function() {
clearInterval(_this.whole_timer)
}, 1000)
}
}, _this.check_time)
},
}
}
</script>
<style lang="scss" rel="stylesheet/scss">
.dashboard-container .el-divider__text {
color: gray;
font-size: 22px;
background-color: rgba(255, 255, 255, 0.8);
}
</style>
<style lang="scss" rel="stylesheet/scss" scoped>
/*.text {*/
/*font-size: 14px;*/
/*}*/
/*.item {*/
/*margin-bottom: 18px;*/
/*}*/
.clearfix:before,
.clearfix:after {
display: table;
content: "";
}
.clearfix:after {
clear: both
}
.box-card {
width: 100%
}
.item {
margin-top: 10px;
margin-right: 40px;
}
.sudoku_row {
display: flex;
align-items: center;
width: 100%;
flex-wrap: wrap;
}
.sudoku_item {
margin-bottom: 20px;
margin-left: 20px;
//border: 0 solid red;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
width: 15%;
height: 80px;
/*padding-top: 10px;*/
/*padding-bottom: 10px;*/
border: 2px solid rgb(208, 222, 234);
}
.sudoku_item:hover {
border: 2px solid white;
}
.opacity {
opacity: 0.4;
background: #e5e5e5;
}
.sudoku_item img {
margin-top: 10px;
display: block;
}
.dashboard {
&-container {
margin: 30px;
}
&-text {
font-size: 30px;
line-height: 46px;
}
}
</style>

View File

@@ -0,0 +1,71 @@
<template>
<div :class="classObj" class="app-wrapper">
<div v-if="device==='mobile'&&sidebar.opened" class="drawer-bg" @click="handleClickOutside"/>
<sidebar class="sidebar-container"/>
<div class="main-container">
<navbar/>
<tags-view/>
<app-main/>
</div>
</div>
</template>
<script>
import { Navbar, Sidebar, AppMain, TagsView } from './components'
import ResizeMixin from './mixin/ResizeHandler'
export default {
name: 'Layout',
components: {
Navbar,
Sidebar,
AppMain,
TagsView
},
mixins: [ResizeMixin],
computed: {
sidebar() {
return this.$store.state.app.sidebar
},
device() {
return this.$store.state.app.device
},
classObj() {
return {
hideSidebar: !this.sidebar.opened,
openSidebar: this.sidebar.opened,
withoutAnimation: this.sidebar.withoutAnimation,
mobile: this.device === 'mobile'
}
}
},
methods: {
handleClickOutside() {
this.$store.dispatch('CloseSideBar', { withoutAnimation: false })
}
}
}
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
@import "src/styles/mixin.scss";
.app-wrapper {
@include clearfix;
position: relative;
height: 100%;
width: 100%;
&.mobile.openSidebar{
position: fixed;
top: 0;
}
}
.drawer-bg {
background: #000;
opacity: 0.3;
width: 100%;
top: 0;
height: 100%;
position: absolute;
z-index: 999;
}
</style>

View File

@@ -0,0 +1,31 @@
<template>
<section class="app-main">
<transition name="fade-transform" mode="out-in">
<!-- or name="fade" -->
<!-- <router-view :key="key"></router-view> -->
<!--<keep-alive>-->
<router-view/>
<!--</keep-alive>-->
</transition>
</section>
</template>
<script>
export default {
name: 'AppMain',
computed: {
// key() {
// return this.$route.name !== undefined ? this.$route.name + +new Date() : this.$route + +new Date()
// }
}
}
</script>
<style scoped>
.app-main {
min-height: calc(100% - 30px);
position: relative;
overflow: hidden;
padding: 5px;
border-radius: 4px;
}
</style>

View File

@@ -0,0 +1,378 @@
<template>
<el-menu class="navbar" mode="horizontal">
<hamburger :is-active="sidebar.opened" :toggle-click="toggleSideBar" class="hamburger-container"/>
<div class="avatar-wrapper" style="position: absolute;right: 0;font-family: 'MiSans Medium',serif">
<span style="margin-right: 90px">
<el-badge :hidden="isHiddenBadge" :value="unReadAlarmCount" style="margin: 0 10px;">
<el-button circle icon="el-icon-message" @click="toErrorPage"/>
</el-badge>
<el-button circle icon="el-icon-edit-outline" @click="clickUpdatePassword"/>
</span>
<!--<span style="color: white">[ &nbsp</span> <a style="color: white" @click="logout">登出</a> <span style="color: white">&nbsp ] &nbsp</span>-->
<!-- <el-button type="success" size="mini" class="loginoff" @click="logout">Log Off</el-button>-->
<!--<el-tag style="width: 60px; text-align: center">-->
<!--<a style="color: white" @click="logout">登出</a>-->
<!--</el-tag>-->
<!--<img :src="require('@/assets/img/user.jpg')" class="user-avatar">-->
<el-dropdown class="avatar-container right-menu-item hover-effect" trigger="click">
<div class="avatar-wrapper">
<img :src="require('@/assets/img/user.jpg')" class="user-avatar">
</div>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item>{{ name }}</el-dropdown-item>
<!-- <router-link to="/">-->
<!-- <el-dropdown-item>Dashboard</el-dropdown-item>-->
<!-- </router-link>-->
<!-- <a target="_blank" href="https://github.com/PanJiaChen/vue-element-admin/">-->
<!-- <el-dropdown-item>Github</el-dropdown-item>-->
<!-- </a>-->
<!-- <a target="_blank" href="https://panjiachen.github.io/vue-element-admin-site/#/">-->
<!-- <el-dropdown-item>Docs</el-dropdown-item>-->
<!-- </a>-->
<el-dropdown-item divided @click.native="logout">
<span style="display:block;">Log Out</span>
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
<breadcrumb/>
<el-dialog
:before-close="handleClose"
:visible.sync="isShowDialog"
title="修改密码"
width="30%">
<el-form label-width="80px">
<el-form-item label="旧密码">
<el-input v-model="updatePasswordForm.oldPassword"/>
</el-form-item>
<el-form-item label="新密码">
<el-input v-model="updatePasswordForm.newPassword1" type="password"/>
</el-form-item>
<el-form-item label="确认密码">
<el-input v-model="updatePasswordForm.newPassword2" type="password"/>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button style="height: 40px;width: 100px" @click="hideUpdatePasswordBox()"> </el-button>
<el-button style="height: 40px;width: 100px" type="primary" @click="submitUpdatePassword"> </el-button>
</span>
</el-dialog>
</el-menu>
</template>
<script>
import { mapGetters } from 'vuex'
import Breadcrumb from '@/components/Breadcrumb'
import Hamburger from '@/components/Hamburger'
export default {
components: {
Breadcrumb,
Hamburger
},
data: function() {
return {
isShowDialog: false,
updatePasswordForm: {
oldPassword: '',
newPassword1: '',
newPassword2: ''
},
passWordIsOk: true,
timer1: null,
unReadAlarmCount: '',
isHiddenBadge: false
}
},
computed: {
...mapGetters([
'sidebar',
'avatar',
'name',
'id'
])
},
mounted() {
this.checkPasswordIsOk()
},
// 页面关闭 关闭定时器
beforeDestroy() {
clearInterval(this.timer1)
},
methods: {
toErrorPage() {
this.$router.push('/RemoteControl/AlarmSearch/index')
},
toggleSideBar() {
this.$store.dispatch('ToggleSideBar')
},
logout() {
this.$store.dispatch('FedLogOut').then(() => {
location.reload() // 为了重新实例化vue-router对象 避免bug
})
},
// 收次登陆判断是否需要修改密码 若需要自动弹窗修改密码框
checkPasswordIsOk() {
var param = []
param.push(['Personnel_Number', this.$store.state.user.id])
var Data = this.CreateData('11', '登录基础数据_人员信息_登陆检查密码', param)
this.ExecDatabase(Data).then(response => {
if (response.data.length !== 0) {
// 强制修改密码
if (response.data[0].result === 2) {
// this.$message.warning(response.data[0].msg)
this.passWordIsOk = false
this.clickUpdatePassword()
this.$message.warning('初始密码 进入系统需先修改密码!')
}
}
})
},
handleClose(done) {
if (!this.passWordIsOk) {
this.$message.warning('用户为初始密码 进入系统需先修改密码!')
return
} else {
done()
}
},
clickUpdatePassword() {
this.updatePasswordForm.oldPassword = ''
this.updatePasswordForm.newPassword1 = ''
this.updatePasswordForm.newPassword2 = ''
this.isShowDialog = true
},
submitUpdatePassword() {
if (this.updatePasswordForm.newPassword1 !== this.updatePasswordForm.newPassword2) {
this.$message.warning('两次密码不一致')
return
}
// 对新密码做复杂度校验 必须要 包含大小写字母以及长度不少于 6位
const regex = /^(?=.*[a-z])(?=.*[A-Z]).{6,}$/
if (!regex.test(this.updatePasswordForm.newPassword1)) {
this.$message.warning('新密码需包含大小写字母及长度不少于6位')
return
}
var param = []
param.push(['userId', this.$store.state.user.id])
param.push(['旧密码', this.updatePasswordForm.oldPassword])
param.push(['新密码1', this.updatePasswordForm.newPassword1])
param.push(['新密码2', this.updatePasswordForm.newPassword2])
var Data = this.CreateData('11', '登录基础数据_人员信息_修改密码', param)
this.ExecDatabase(Data).then(response => {
if (response.data.length !== 0) {
if (response.data[0].result === 1) {
this.$message.success(response.data[0].msg)
this.passWordIsOk = true
this.isShowDialog = false
} else {
this.$message.warning(response.data[0].msg)
}
}
})
},
hideUpdatePasswordBox() {
if (this.passWordIsOk) {
this.isShowDialog = false
} else {
this.$message.warning('用户为初始密码 进入系统需先修改密码!')
}
},
// 获取最新一条报警信息,弹出提示
sendAlarmMessage() {
var param = []
param.push(['personnel_Number', this.id])
var Data = this.CreateData('11', 'WEB_报警查询_未读报警记录_查询', param)
this.ExecDatabase(Data).then(response => {
if (response.data.length !== 0) {
if (response.data.length > 0) {
this.$notify.warning({
title: '报警通知',
message: `设备 <span style="color: #097e00">${response.data[0].设备名称}</span> 报警,报警信息如下<br><span style="color:#ff9a02;">${response.data[0].报警内容}</span>`,
position: 'bottom-right',
dangerouslyUseHTMLString: true
})
}
}
})
},
// 获取未读总报警数量
getUnReadAlarmCount() {
var param = []
param.push(['personnel_Number', this.id])
var Data = this.CreateData('11', 'WEB_报警查询_未读报警记录_未读条数查询', param)
this.ExecDatabase(Data).then(response => {
if (response.data.length !== 0) {
if (response.data.length > 0) {
this.unReadAlarmCount = response.data[0].未读条数
if (this.unReadAlarmCount == 0) this.isHiddenBadge = true
}
}
})
}
}
}
</script>
<style lang="scss" rel="stylesheet/scss" scoped>
.navbar {
height: 50px;
line-height: 50px;
border-radius: 0px !important;
background-color: #354387 !important;
.hamburger-container {
line-height: 58px;
height: 50px;
float: left;
padding: 0 16px;
}
.avatar-container {
height: 50px;
display: inline-block;
position: absolute;
right: 20px;
.avatar-wrapper {
cursor: pointer;
padding-top: 7px;
position: relative;
font-size: 16px;
.user-avatar {
width: 40px;
height: 40px;
border-radius: 10px;
}
.el-icon-caret-bottom {
position: absolute;
right: -20px;
top: 25px;
font-size: 12px;
}
}
}
.el-tag {
float: right;
margin-top: 8px;
margin-right: 5px;
}
.right-menu {
float: right;
height: 100%;
line-height: 50px;
&:focus {
outline: none;
}
.right-menu-item {
display: inline-block;
padding: 0 8px;
height: 100%;
font-size: 13px;
color: #5a5e66;
vertical-align: text-bottom;
&.hover-effect {
cursor: pointer;
transition: background .3s;
&:hover {
background: rgba(0, 0, 0, .025)
}
}
}
.avatar-container {
margin-right: 30px;
.avatar-wrapper {
margin-top: 5px;
position: relative;
.user-avatar {
cursor: pointer;
width: 40px;
height: 40px;
border-radius: 10px;
}
.el-icon-caret-bottom {
cursor: pointer;
position: absolute;
right: -20px;
top: 25px;
font-size: 12px;
}
}
}
}
}
.loginin {
font-family: 'MiSans Demibold', serif;
margin-left: 19px;
border: 1px solid #fafcff;
border-radius: 10px;
width: 88px;
height: 28px;
background-color: #fafcff;
color: #354387;
font-size: 16px;
padding: 3px 15px;
margin-top: 30px
}
.loginoff {
font-family: 'MiSans Demibold', serif;
margin-left: 15px;
border-radius: 10px;
border: 1px solid #fafcff;
width: 88px;
height: 28px;
background-color: #354387;
color: #fafcff;
font-size: 16px;
padding: 3px 15px;
}
.TVshow {
color: #1aba9d;
width: 50px;
height: 50px;
margin-right: 20px;
line-height: 40px;
margin-top: 15px;
cursor: pointer;
}
.TVshow1 {
color: #1aba9d;
width: 50px;
height: 50px;
margin-right: 50px;
line-height: 40px;
margin-top: 15px;
cursor: pointer;
}
::v-deep .el-badge__content.is-fixed {
top: 17px !important;
}
::v-deep .el-button {
width: 35px;
i {
margin-top: -3px !important;
margin-left: -2px;
}
}
</style>

View File

@@ -0,0 +1,29 @@
<script>
export default {
name: 'MenuItem',
functional: true,
props: {
icon: {
type: String,
default: ''
},
title: {
type: String,
default: ''
}
},
render(h, context) {
const { icon, title } = context.props
const vnodes = []
if (icon) {
vnodes.push(<svg-icon icon-class={icon}/>)
}
if (title) {
vnodes.push(<span slot='title'>{(title)}</span>)
}
return vnodes
}
}
</script>

View File

@@ -0,0 +1,110 @@
<template>
<div v-if="!item.hidden && item.children" class="menu-wrapper">
<template
v-if="hasOneShowingChild(item.children, item) && (!onlyOneChild.children || onlyOneChild.noShowingChildren) && !item.alwaysShow">
<a :href="onlyOneChild.path" target="_blank" @click="clickLink(onlyOneChild.path, $event)">
<el-menu-item :index="resolvePath(onlyOneChild.path)" :class="{ 'submenu-title-noDropdown': !isNest }">
<item v-if="onlyOneChild.meta" :icon="onlyOneChild.meta.icon || item.meta.icon"
:title="onlyOneChild.meta.title" />
</el-menu-item>
</a>
</template>
<el-submenu v-else :index="item.name || item.path">
<template slot="title">
<item v-if="item.meta" :icon="item.meta.icon" :title="item.meta.title" />
</template>
<template v-for="child in item.children" v-if="!child.hidden">
<sidebar-item v-if="child.children && child.children.length > 0" :is-nest="true" :item="child" :key="child.path"
:base-path="resolvePath(child.path)" class="nest-menu" />
<a v-else :href="child.path" :key="child.name" target="_blank" @click="clickLink(child.path, $event)">
<el-menu-item :index="resolvePath(child.path)">
<item v-if="child.meta" :icon="child.meta.icon" :title="child.meta.title" />
</el-menu-item>
</a>
</template>
</el-submenu>
</div>
</template>
<script>
import path from 'path'
import { validateURL } from '@/utils/validate'
import Item from './Item'
import { mapGetters } from 'vuex'
export default {
name: 'SidebarItem',
components: { Item },
props: {
// route object
item: {
type: Object,
required: true
},
isNest: {
type: Boolean,
default: false
},
basePath: {
type: String,
default: ''
}
},
data() {
return {
onlyOneChild: null
}
},
computed: {
...mapGetters([
'name',
'token',
'id'
])
},
methods: {
hasOneShowingChild(children, parent) {
const showingChildren = children.filter(item => {
if (item.hidden) {
return false
} else {
// Temp set(will be used if only has one showing child)
this.onlyOneChild = item
return true
}
})
// When there is only one child router, the child router is displayed by default
if (showingChildren.length === 1) {
return true
}
// Show parent if there are no child router to display
if (showingChildren.length === 0) {
this.onlyOneChild = { ...parent, path: '', noShowingChildren: true }
return true
}
return false
},
resolvePath(routePath) {
return path.resolve(this.basePath, routePath)
},
isExternalLink(routePath) {
return validateURL(routePath)
},
clickLink(routePath, e) {
// console.log('触发跳转方法!!',routePath,e.srcElement.innerText)
if (!this.isExternalLink(routePath)) {
e.preventDefault()
const path = this.resolvePath(routePath)
this.$router.push(path)
}
}
}
}
</script>

View File

@@ -0,0 +1,83 @@
<template>
<div>
<el-scrollbar wrap-class="scrollbar-wrapper">
<div v-show="isShow" class="img-wrapper">
<div style="background-color: #fff; height: 49px; width:100%">
<img :src="require('@/assets/img/logo.png')">
</div>
</div>
<div v-show="!isShow" class="img-wrapper-small">
<div style="background-color: #fff; height: 49px; width:100%">
<img :src="require('@/assets/img/DFlogo.png')" width="60">
</div>
</div>
<el-menu
:collapse="isCollapse"
:default-active="$route.path"
:show-timeout="200"
mode="vertical"
style="height:calc(100% - 49px)"
>
<sidebar-item v-for="route in permission_routers" :key="route.name" :base-path="route.path" :item="route"/>
</el-menu>
</el-scrollbar>
</div>
</template>
<script>
import { mapGetters } from 'vuex'
import SidebarItem from './SidebarItem'
export default {
components: { SidebarItem },
data() {
return {
isShow: ''
}
},
computed: {
...mapGetters([
'sidebar',
'permission_routers'
]),
routes() {
return this.$router.options.routes
},
isCollapse() {
this.showLogo()
return !this.sidebar.opened
}
},
methods: {
showLogo() {
this.isShow = this.sidebar.opened === true
}
}
}
</script>
<style lang="scss" scoped>
.img-wrapper {
img {
width: 200px;
}
}
.img-wrapper-small {
img {
margin: 7px 9px;
}
}
.img-wrapper img {
width: auto;
height: 100%;
}
.img-wrapper-small {
img {
margin: 0px 9px;
height: 100%;
width: auto;
}
}
</style>

View File

@@ -0,0 +1,218 @@
<template>
<div class="tags-view-container">
<scroll-pane ref="scrollPane" class="tags-view-wrapper">
<router-link
v-for="tag in Array.from(visitedViews)"
ref="tag"
:key="tag.path"
:class="isActive(tag)?'active':''"
:to="tag.path"
class="tags-view-item"
@contextmenu.prevent.native="openMenu(tag,$event)">
{{ tag.title }}
<span class="el-icon-close" @click.prevent.stop="closeSelectedTag(tag)"/>
</router-link>
</scroll-pane>
<ul v-show="visible" :style="{left:left+'px',top:top+'px'}" class="contextmenu">
<li @click="closeSelectedTag(selectedTag)">关闭当前</li>
<li @click="closeOthersTags">关闭其他</li>
<li @click="closeAllTags">关闭全部</li>
</ul>
</div>
</template>
<script>
import ScrollPane from '@/components/Scrollpane'
import Cookies from 'js-cookie'
export default {
components: { ScrollPane },
data() {
return {
visible: false,
top: 0,
left: 0,
selectedTag: {}
}
},
computed: {
visitedViews() {
return this.$store.state.tagsView.visitedViews
}
},
watch: {
$route() {
this.addViewTags()
// this.moveToCurrentTag()
},
visible(value) {
if (value) {
window.addEventListener('click', this.closeMenu)
} else {
window.removeEventListener('click', this.closeMenu)
}
}
},
mounted() {
this.addViewTags()
},
methods: {
// generateTitle, // generateTitle by vue-i18n
generateRoute() {
if (this.$route.name) {
return this.$route
}
return false
},
isActive(route) {
return route.path === this.$route.path || route.name === this.$route.name
},
addViewTags() {
const route = this.generateRoute()
if (!route) {
return false
}
this.$store.dispatch('addVisitedViews', route)
},
moveToCurrentTag() {
const tags = this.$refs.tag
this.$nextTick(() => {
for (const tag of tags) {
if (tag.to === this.$route.path) {
this.$refs.scrollPane.moveToTarget(tag.$el)
break
}
}
})
},
closeSelectedTag(view) {
this.$store.dispatch('delVisitedViews', view).then((views) => {
if (this.isActive(view)) {
const latestView = views.slice(-1)[0]
if (latestView) {
this.$router.push(latestView.path)
} else {
this.$router.push('/')
}
}
})
},
closeOthersTags() {
this.$router.push(this.selectedTag.path)
this.$store.dispatch('delOthersViews', this.selectedTag).then(() => {
this.moveToCurrentTag()
})
},
closeAllTags() {
this.$store.dispatch('delAllViews')
this.$router.push('/')
},
openMenu(tag, e) {
console.log(e)
const status = Cookies.get('sidebarStatus')
this.visible = true
this.selectedTag = tag
this.left = e.clientX
this.left = status === '0' ? parseInt(e.clientX) - 220 : parseInt(e.clientX) - 80
this.top = e.clientY
},
closeMenu() {
this.visible = false
}
}
}
</script>
<style lang="scss" rel="stylesheet/scss" scoped>
.tags-view-container {
font-family: "MiSans Medium", serif;
.tags-view-wrapper {
overflow-x: auto;
background: #fafcff;
height: 29px;
border-bottom: 1px solid #d8dce5;
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, .12), 0 0 3px 0 rgba(0, 0, 0, .04);
.tags-view-item {
text-align: center;
display: inline-block;
position: relative;
height: 24px;
line-height: 24px;
border: 1px solid #354387;
color: #354387;
background: inherit;
padding: 0 8px;
font-size: 12px;
margin-left: 8px;
margin-top: 2px;
border-radius: 4px;
max-width: 120px;
&:first-of-type {
margin-left: 16px;
}
&.active {
background-color: #354387;
color: #fafcff;
border-color: #fafcff;
}
}
}
.contextmenu {
margin: 0;
background: #fff;
z-index: 99;
position: absolute;
list-style-type: none;
padding: 5px 0;
border-radius: 4px;
font-weight: 400;
color: #333;
box-shadow: 2px 2px 3px 0 rgba(0, 0, 0, .3);
li {
margin: 0;
padding: 7px 16px;
cursor: pointer;
&:hover {
background: #eee;
}
}
}
}
</style>
<style lang="scss" rel="stylesheet/scss">
//reset element css of el-icon-close
.tags-view-wrapper {
font-family: MiSans Medium, serif;
.tags-view-item {
.el-icon-close {
width: 14px;
height: 14px;
vertical-align: 3px;
border-radius: 50%;
text-align: center;
transition: all .3s cubic-bezier(.645, .045, .355, 1);
transform-origin: 100% 50%;
&:before {
transform: scale(.6);
display: inline-block;
vertical-align: -3px;
}
&:hover {
background-color: #b4bccc;
color: #fff;
}
}
}
}
</style>

View File

@@ -0,0 +1,4 @@
export { default as Navbar } from './Navbar'
export { default as Sidebar } from './Sidebar'
export { default as AppMain } from './AppMain'
export { default as TagsView } from './TagsView'

View File

@@ -0,0 +1,52 @@
import store from '@/store'
const { body } = document
const WIDTH = 1024
const RATIO = 3
export default {
watch: {
$route(route) {
if (this.device === 'mobile' && this.sidebar.opened) {
store.dispatch('CloseSideBar', { withoutAnimation: false })
}
}
},
beforeMount() {
window.addEventListener('resize', this.resizeHandler)
},
mounted() {
const isMobile = this.isMobile()
const isSmallDesktop = this.isSmallDesktop()
if (isSmallDesktop) {
store.dispatch('CloseSideBar', { withoutAnimation: false })
}
if (isMobile) {
store.dispatch('ToggleDevice', 'mobile')
store.dispatch('CloseSideBar', { withoutAnimation: true })
}
},
methods: {
isMobile() {
const rect = body.getBoundingClientRect()
return rect.width - RATIO < WIDTH
},
isSmallDesktop() {
const rect = body.getBoundingClientRect()
return rect.width - RATIO < 1300
},
resizeHandler() {
if (!document.hidden) {
const isMobile = this.isMobile()
const isSmallDesktop = this.isSmallDesktop()
store.dispatch('ToggleDevice', isMobile ? 'mobile' : 'desktop')
if (isSmallDesktop) {
store.dispatch('CloseSideBar', { withoutAnimation: false })
}
if (isMobile) {
store.dispatch('CloseSideBar', { withoutAnimation: true })
}
}
}
}
}

View File

@@ -0,0 +1,500 @@
<template>
<div>
<div class="login-container">
<i class="login-img"/>
<el-form
ref="loginForm"
:model="loginForm"
:rules="loginRules"
auto-complete="on"
class="card-box login-form"
label-position="left"
label-width="0px">
<div class="content">
<div style="padding: 30px">
<h1 class="title">MES工业互联网平台</h1>
</div>
<div class="inner">
<div class="child">
<el-form-item prop="username">
<span class="svg-container svg-container_login">
<svg-icon icon-class="username"/>
</span>
<el-input
v-model="loginForm.username"
auto-complete="on"
name="username"
placeholder="请输入用户名"
type="text"
@input.native="changeUser"/>
</el-form-item>
<el-form-item prop="password">
<span class="svg-container">
<svg-icon icon-class="password"/>
</span>
<el-input
v-model="loginForm.password"
:type="pwdType"
auto-complete="on"
name="password"
placeholder="请输入密码"
@keyup.enter.native="handleLogin"/>
<span class="show-pwd" @click="showPwd"><svg-icon icon-class="eye"/></span>
</el-form-item>
<div style="float: left">
<el-checkbox v-model="loginForm.checked" class="remeberPassword">记住账号</el-checkbox>
<!--<span style="color: #555c66">|</span>-->
<!--<el-button type="text" @click="handleEdit('form')">修改密码</el-button>-->
</div>
<el-button :loading="loading" class="signIn" type="primary" @click.native.prevent="handleLogin">登录
</el-button>
</div>
</div>
</div>
</el-form>
</div>
<el-dialog
:close-on-click-modal="false"
:close-on-press-escape="false"
:show-close="false"
:visible.sync="dialogVisible"
align="center"
style="font-size: 20px"
title="请选择登录角色"
width="300px">
<el-table
:data="tableData"
:show-header="false"
highlight-current-row
size="mini"
style="width: 100%"
@row-click="rowClick">
<el-table-column label="角色名称">
<template slot-scope="scope">
{{ scope.row.Roles_Function }}
</template>
</el-table-column>
</el-table>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false;loading=false">取消</el-button>
<el-button type="primary" @click="submitSelect">确定</el-button>
</div>
</el-dialog>
<el-dialog
:visible.sync="dialogFormVisible"
center
style="min-height: 200px;font-size: 16px"
title="修改密码"
width="400px">
<el-form ref="form" :model="form" :rules="rules" label-position="left" label-width="110px">
<el-form-item label="工号" prop="Account" style="display: inline-block;font-family: sans-serif">
<el-input v-model="form.Account" size="small" style="width:200px"/>
</el-form-item>
<el-form-item label="原始密码" prop="beforPassword" style="display: inline-block;font-family: Arial ">
<el-input v-model="form.beforPassword" size="small" style="width:200px"/>
</el-form-item>
<el-form-item label="新密码" prop="newPassword" style="display: inline-block;font-family: sans-serif">
<el-input v-model="form.newPassword" size="small" style="width:200px;"/>
</el-form-item>
<el-form-item label="确认密码" prop="againPassword" style="display: inline-block;font-family: sans-serif">
<el-input v-model="form.againPassword" size="small" style="width:200px"/>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button size="small" @click="callOff()">取消</el-button>
<el-button size="small" type="primary" @click="EditPassword('form')">确定</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
// import { isvalidUsername } from '@/utils/validate'
import { editPassword } from '@/api/login'
import { setToken } from '@/utils/auth'
import Cookie from 'js-cookie'
export default {
name: 'Login',
data() {
const validateValue = (rules, value, callback) => {
if (typeof (this.form.againPassword) === 'string' || typeof (this.form.againPassword) === 'string' || typeof (this.form.againPassword) === 'string') {
callback(new Error('请输入英文字母组合'))
} else {
callback()
}
if (this.form.newPassword !== this.form.againPassword) {
callback(new Error('两次输入密码不同'))
} else {
callback()
}
}
return {
dialogVisible: false,
tableData: [],
commit: null,
row: null,
rules: {
againPassword: [
{ required: true, message: '请输入确认密码', trigger: 'blur' },
{ required: true, trigger: 'blur', validator: validateValue }],
Account: [{ required: true, message: '请输入考勤编号', trigger: 'blur' },
{ required: true, trigger: 'blur', validator: validateValue }],
beforPassword: [{ required: true, message: '请输入原始密码', trigger: 'blur' },
{ required: true, trigger: 'blur', validator: validateValue }],
newPassword: [{ required: true, message: '请输入新密码', trigger: 'blur' },
{ required: true, trigger: 'blur', validator: validateValue }]
},
list: [],
form: {
againPassword: '',
Account: '',
beforPassword: '',
newPassword: ''
},
dialogFormVisible: false,
loginForm: {
username: '',
password: '',
checked: false
},
loginRules: {
// username: [{ required: true, trigger: 'blur', validator: validateUsername }]
username: [{ required: true, message: '请输入用户名', trigger: 'blur' }],
password: [{ required: true, message: '请输入密码', trigger: 'blur' }]
},
loading: false,
pwdType: 'password'
}
},
// 页面加载调用获取cookie值
mounted() {
this.getCookie()
},
methods: {
showPwd() {
if (this.pwdType === 'password') {
this.pwdType = ''
} else {
this.pwdType = 'password'
}
},
changeUser() {
this.loginForm.password = ''
},
handleLogin() {
this.row = null
this.$refs.loginForm.validate(valid => {
if (valid) {
this.loading = true
this.$store.dispatch('Login', this.loginForm).then(res => {
if (res.data.length > 1) {
this.tableData = res.data
this.commit = res.commit
this.dialogVisible = true
} else {
this.loading = false
this.$router.push({ path: '/' })
}
}).catch(() => {
this.loading = false
})
} else {
console.log('error submit!!')
return false
}
if (this.loginForm.checked === true) { // 传入账号名密码和保存天数3个参数
this.setCookie(this.loginForm.username, this.loginForm.password, this.loginForm.checked)
} else {
this.clearCookie()
}
})
},
// 选择登录角色
rowClick(row) {
this.row = row
},
// 确认选择登录角色
submitSelect() {
if (this.row) {
setToken(this.row.Roles_number)
Cookie.set('id', this.row.Personnel_Number, { expires: 1 })
Cookie.set('name', this.row.Personnel_Name, { expires: 1 })
Cookie.set('account', this.row.account, { expires: 1 })
this.commit('SET_TOKEN', this.row.Roles_number)
this.commit('SET_NAME', this.row.Personnel_Name)
this.commit('SET_ID', this.row.Personnel_Number)
this.commit('SET_account', this.row.account)
this.loading = false
this.$router.push({ path: '/' })
} else {
this.$message({
type: 'warning',
message: '请选择登录角色!'
})
}
},
handleEdit() {
this.addForm('form', [this.dialogFormVisible = true])
},
callOff() {
this.dialogFormVisible = false
},
// 设置cookie
setCookie(username, password, checked) {
Cookie.set('username', username, { expires: 7 })
Cookie.set('password', password, { expires: 7 })
Cookie.set('checked', checked, { expires: 7 })
},
// 读取 cookie
getCookie() {
this.loginForm.username = Cookie.get('username')
this.loginForm.password = Cookie.get('password')
this.loginForm.checked = Boolean(Cookie.get('checked'))
},
// 清除cookie
clearCookie() {
Cookie.remove('username')
Cookie.remove('password')
Cookie.remove('checked')
},
EditPassword(formName) {
this.$refs[formName].validate((valid) => {
if (valid) {
editPassword(this.form.Account, this.form.beforPassword, this.form.newPassword, 5).then(response => {
if (response.data.output[0].返回 === '1') {
this.dialogFormVisible = false
this.$message.success('密码修改成功,请重新登陆')
} else {
this.$message.error('密码修改失败,若忘记原密码请联系管理员')
}
})
}
})
}
}
}
</script>
<style lang="scss" rel="stylesheet/scss">
$bg: #2d3a4b;
$dark_gray: #889aa4;
$light_gray: #eee;
.login-container {
position: fixed;
height: 100%;
width: 100%;
background-color: #ebebeb;
background-image: url("../../../static/loginBackground.jpg");
background-repeat: no-repeat;
background-size: 100% 100%;
-moz-background-size: 100% 100%;
overflow: scroll;
input:-webkit-autofill {
-webkit-box-shadow: 0 0 0 1000px #293444 inset !important;
-webkit-text-fill-color: #fff !important;
}
/*.login-img{*/
/*position: absolute;*/
/*width: 100%;*/
/*height: 100%;*/
/*background: url("../../../static/login.png") no-repeat;*/
/*}*/
input {
background: transparent;
border: 0;
-webkit-appearance: none;
border-radius: 0;
padding: 12px 5px 12px 15px;
color: $light_gray;
height: 47px;
}
.el-input {
display: inline-block;
height: 47px;
width: 85%;
}
.svg-container {
padding: 6px 5px 6px 15px;
color: #4D77D6;
font-size: 20px !important;
vertical-align: middle;
width: 30px;
display: inline-block;
&_login {
font-size: 20px;
}
}
.title {
font-size: 22px;
line-height: 30px;
/*color: #2D3C67;*/
color: #4D77D6;
margin: 20px auto 20px auto;
text-align: center;
font-weight: bold;
}
.el-table--mini {
font-size: 12px;
}
.el-form-item__label {
font-family: "sans-serif";
text-align: right;
float: left;
font-size: 12px;
color: #606266;
line-height: 40px;
padding: 0 12px 0 0;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
.content {
width: 450px;
height: 500px;
background-image: url("../../../static/loginWindowBackground.png");
background-repeat: no-repeat;
background-size: 100% 100%;
-moz-background-size: 100% 100%;
margin: 5px auto 0 auto;
}
/*.line{*/
/*width: 70%;*/
/*margin: 0 auto 25px auto;*/
/*background-color: #ffffff;*/
/*height: 1px;*/
/*}*/
.login-form {
position: absolute;
left: 0;
right: 0;
width: 400px;
padding: 35px 35px 15px 35px;
margin: 150px auto;
}
.tips {
font-size: 14px;
color: #fff;
margin-bottom: 10px;
span {
&:first-of-type {
margin-right: 16px;
}
}
}
.el-input__inner {
border: none !important;
font-size: 16px !important;
color: #29335b !important;
}
.el-form-item {
border: 1px solid #ebf1ee;
background: #ffffff;
border-radius: 5px;
color: #454545;
}
/*登录button*/
.signIn {
width: 100%;
border: none;
margin-top: 20px;
border-radius: 5px;
font-size: 18px;
height: 50px;
color: white;
background-color: #4D77D6;
}
.remeberPassword {
color: $dark_gray;
}
.inner {
margin: 10% auto;
text-align: center;
}
.child {
display: inline-block;
vertical-align: top;
}
.show-pwd {
position: absolute;
right: 10px;
top: 7px;
font-size: 16px;
color: $dark_gray;
cursor: pointer;
user-select: none;
}
@media (min-width: 1024px) {
/*根据屏幕大小确定显示的位置*/
.login-form {
position: absolute;
left: 40%;
top: 0;
width: 600px;
}
.title {
font-size: 40px !important;
line-height: 32px;
}
.el-form-item {
width: 400px;
height: 50px;
}
.content {
width: 450px;
}
}
@media (min-width: 1281px) {
.login-form {
position: absolute;
left: 60%;
/*top: 2%;*/
width: 600px;
}
}
}
</style>
<style>
.remeberPassword .el-checkbox__inner:hover {
border: 1px solid #4D77D6;
}
.remeberPassword .el-checkbox__input.is-checked .el-checkbox__inner {
background-color: #4D77D6;
border-color: #4D77D6;
}
.remeberPassword .el-checkbox__input.is-checked + .el-checkbox__label {
color: #C0C4CC;
}
.remeberPassword .el-checkbox__input.is-focus .el-checkbox__inner {
border-color: #4D77D6;
}
.login-container input:-webkit-autofill {
-webkit-box-shadow: 0 0 0 1000px #fff inset !important;
-webkit-text-fill-color: #000000 !important;
}
</style>