chore: update project changes

This commit is contained in:
meswork764
2026-06-09 08:37:50 +08:00
parent 6f9f8fe148
commit 0bf5f3f704
14 changed files with 3429 additions and 145 deletions

View File

@@ -0,0 +1,69 @@
USE [YL_MESDB]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[_加急任务查询]
AS
BEGIN
SET NOCOUNT ON;
SELECT
[]
,[]
,[]
,[]
,[]
,[]
,[]
,[]
,[]
,[]
,[]
,[]
, as
,
,
,
,REPLACE(STUFF((
SELECT
' -> ' + ISNULL(d2., '') + '(' + ISNULL(d2., '') + ')'
+ '|' + ISNULL(CAST(d2. AS VARCHAR(10)), '0')
+ '|' + ISNULL(CAST(CAST(ISNULL((
SELECT SUM()
FROM [dbo].[YL_质量检验_质检记录]
WHERE TaskAID = d2.TaskAID
), 0) AS INT) AS VARCHAR(10)), '0')
+ '|' + ISNULL(CONVERT(VARCHAR(2), MONTH(d2.)) + '' + CONVERT(VARCHAR(2), DAY(d2.)) + '', '')
+ '|' + ISNULL(CAST(d2. AS VARCHAR(10)), '')
+ '|' + ISNULL(CAST(d2. AS NVARCHAR(50)), '')
+ '|' + ISNULL(CAST(CAST(ISNULL((
SELECT SUM()
FROM [dbo].[YL_加工中心_操作记录表]
WHERE TaskAID = d2.TaskAID
AND = '收料'
), 0) AS INT) AS VARCHAR(10)), '0')
+ '|' + ISNULL(CAST(CAST(ISNULL((
SELECT SUM()
FROM [dbo].[YL_质量检验_质检记录]
WHERE TaskAID = d2.TaskAID
), 0) AS INT) AS VARCHAR(10)), '0')
FROM [dbo].[View_生产订单_MES] d2
WHERE d2. = v.
ORDER BY d2.
FOR XML PATH('')
), 1, 6, ''), '>', '>') AS
,(SELECT COUNT(DISTINCT ) FROM [YL_MESDB].[dbo].[View_生产订单_MES] WHERE > 0 AND NOT LIKE '%装配%') AS []
FROM [YL_MESDB].[dbo].[View_生产订单_MES] v
WHERE > 0
AND NOT LIKE '%装配%'
AND = (
SELECT MIN()
FROM [YL_MESDB].[dbo].[View_生产订单_MES]
WHERE = v.
)
END

View File

@@ -0,0 +1,861 @@
<template>
<div>
<el-card>
<div class="search-container" @keyup.enter="searchTable">
<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="plannum" placeholder="请输入计划号" clearable style="width: 150px;margin-right: 10px" />
<span class="show-text">自制件属性:</span>
<el-select v-model="selfStatus" 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-select v-model="outsourceStatus" 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-select v-model="urgentStatus" 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-select v-model="orderStatus" clearable placeholder="请选择单据状态" style="width: 150px;margin-right: 10px">
<el-option label="全部" value="全部" />
<el-option label="关闭" value="关闭" />
<el-option label="正常" value="正常" />
</el-select>
<!-- 其他搜索条件保持不变 -->
<el-button :disabled="loading" icon="el-icon-search" plain type="primary" @click="searchTable()">查询</el-button>
</div>
<el-table v-loading="loading" :data="tableData" :height="'80vh'" 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="外协" 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="计划开始时间" 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">
<template slot-scope="scope">{{ scope.row.开始时间 === '1900-01-01 00:00:00'? '':scope.row.开始时间}}</template>
</el-table-column>
<el-table-column align="center" label="实际结束时间" width="100">
<template slot-scope="scope">{{ scope.row.指派对象 === '外协' ? scope.row.外协结束时间 === '1900-01-01 00:00:00'? '':scope.row.外协结束时间 : scope.row.结束时间 === '1900-01-01 00:00:00'? '':scope.row.结束时间}}</template>
</el-table-column>
<el-table-column align="center" label="完成进度" prop="进度" width="100">
<template slot-scope="scope">{{ scope.row.进度}}%</template>
</el-table-column>
<el-table-column align="center" label="完成数量" prop="完成数量" width="100" />
<el-table-column align="center" label="外协发料数量" prop="收料数量" width="100" >
<template slot-scope="scope">{{scope.row.指派对象 === '外协' ? 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-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="80">
<template slot-scope="scope">
<div @click="Urgent(scope.row)" style="color: aqua;">
{{ scope.row.加急总数 }}
</div>
</template>
</el-table-column>
<el-table-column align="center" label="工艺路线" width="450">
<template slot-scope="scope">
<div class="process-route" v-html="formatProcessRoute(scope.row)" />
</template>
</el-table-column>
<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" 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.排产状态 === 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="Number(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="优先级" 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="80" />
<el-table-column align="center" prop="计划号" label="计划号" width="120" />
</el-table>
</el-card>
<el-dialog
:visible.sync="UrgentVisible"
title="加急明细"
width="1200px"
center
:close-on-click-modal="false"
>
<el-form ref="Urgentarr" :model="Urgentarr" size="mini">
<el-form-item v-for="item in Urgentarr" :key="item.订单编号" >
<div class="info-container" >
<div class="info-item">
<span class="info-label" style="width: 80px">生产订单</span>
<span class="info-value">
<el-input
v-model="item.订单编号"
size="mini"
readonly
style="width: 300px"
/>
</span>
</div>
<div class="info-item">
<span class="info-label" style="width: 80px">加急数量</span>
<span class="info-value">
<el-input
v-model="item.加急数量"
size="mini"
style="width: 150px"
readonly
/>
</span>
</div>
<div class="info-item">
<span class="info-label" style="width: 80px">物料编号</span>
<span class="info-value">
<el-input
v-model="item.物料编号"
size="mini"
style="width: 150px"
readonly
/>
</span>
</div>
</div>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="UrgentVisible = false">关闭</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
export default {
data() {
return {
orderNo: '',
contractNo: '',
productCode: '',
plannum: '',
productName: '',
processName: '',
nature: '',
productionStatus: '全部',
selfStatus: '全部',
// 新增过滤字段
outsourceStatus: '全部', // 外协状态
urgentStatus: '全部', // 加急状态
orderStatus:'正常',
completionTime: [],
loading: false,
tableData: [],
selectedRow: null,
editDialogVisible: false,
editSubmitLoading: false,
currentRow: {},
editForm: {
优先级: '',
未完成说明: '',
派工特殊说明: ''
},
splitTaskDialogVisible: false,
splitTaskSubmitLoading: false,
stationOptions: [],
splitTaskForm: {
分配数量: 0,
指派对象: '',
指派对象编号: '',
派工特殊备注: '',
计划开始时间: '',
计划结束时间: '',
最晚开始时间: '',
任务概述: ''
},
planStartTime: [],
planendTime: [],
UrgentVisible: false,
Urgentarr: {}
}
},
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.searchTable()
},
methods: {
Urgent(row){
var param = []
param.push(["物料编号",row.产品编码])
this.UrgentVisible = true
var Data = this.CreateData("11", "加急订单_加急明细查询",param);
this.ExecDatabase(Data).then((response) => {
this.Urgentarr = response.data
});
},
getHeaderClass({ row, rowIndex }) {
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
},
toProcessNumber(value) {
const num = Number(value)
return Number.isFinite(num) ? num : 0
},
escapeProcessHtml(value) {
return String(value == null ? '' : value)
.replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;')
.replace(/'/g, '&#39;')
},
isOutsourceProcess(process) {
return process.指派对象 === '外协' ||
String(process.工序名称 || '').includes('(外协)') ||
String(process.工序名称 || '').includes('(外协)')
},
getProcessStatusNum(status) {
const statusNum = parseInt(status)
if (Number.isFinite(statusNum)) {
return statusNum
}
const statusMap = {
辅助开始: 2,
辅助结束: 3,
开始加工: 4,
暂停: 5,
报工: 6,
装配加工: 4
}
return statusMap[status] || 0
},
isBlueProcess(process) {
const statusNum = this.getProcessStatusNum(process.加工状态)
const countNum = parseInt(process.收检合格数)
return statusNum === 6 || statusNum === 3 || countNum > 0
},
isGreenProcess(process) {
return this.isOutsourceProcess(process) &&
this.toProcessNumber(process.收料数量) > this.toProcessNumber(process.收检合格数) + this.toProcessNumber(process.收检不合格数)
},
getProcessBaseClass(process) {
if (this.isGreenProcess(process)) {
return 'process-route-green'
}
if (this.isBlueProcess(process)) {
return 'process-route-blue'
}
const statusNum = this.getProcessStatusNum(process.加工状态)
if (statusNum === 2 || statusNum === 4) {
return 'process-route-green'
}
return 'process-route-red'
},
getOutsourceGroupClassState(processes) {
const classes = new Map()
let currentIndexes = []
let lastProcess = null
const flushOutsourceRun = () => {
if (currentIndexes.length > 0 && lastProcess) {
const className = this.getProcessBaseClass(lastProcess)
currentIndexes.forEach(index => classes.set(index, className))
}
currentIndexes = []
lastProcess = null
}
const isSameContinuousGroup = process => {
if (!lastProcess) {
return true
}
const lineNo = this.toProcessNumber(process.订单行号)
const lastLineNo = this.toProcessNumber(lastProcess.订单行号)
return lineNo === lastLineNo + 1 &&
String(process.外协分组 || '') === String(lastProcess.外协分组 || '')
}
processes.forEach((process, index) => {
if (!this.isOutsourceProcess(process)) {
flushOutsourceRun()
return
}
if (!isSameContinuousGroup(process)) {
flushOutsourceRun()
}
currentIndexes.push(index)
lastProcess = process
})
flushOutsourceRun()
return classes
},
getProcessClass(process, index, outsourceGroupClasses) {
if (this.isOutsourceProcess(process)) {
return outsourceGroupClasses.get(index) || this.getProcessBaseClass(process)
}
return this.getProcessBaseClass(process)
},
getRouteProcesses(row) {
if (Array.isArray(row.子数据) && row.子数据.length > 0) {
return row.子数据
}
return String(row.工艺路线 || '')
.split(',')
.map(name => name.trim())
.filter(Boolean)
.map(name => ({
工序名称: name,
加工状态: 0,
收检合格数: 0,
指派对象: '',
订单行号: 0,
收料数量: 0,
收检不合格数: 0
}))
},
formatProcessRoute(row) {
const processes = this.getRouteProcesses(row)
if (processes.length === 0) {
return ''
}
const outsourceGroupClasses = this.getOutsourceGroupClassState(processes)
return processes.map((process, index) => {
const name = process.工序名称 || ''
const className = this.getProcessClass(process, index, outsourceGroupClasses)
const arrow = index < processes.length - 1 ? '<span class="process-route-arrow">-&gt;</span>' : ''
return `<span class="${className}">${this.escapeProcessHtml(name)}</span>${arrow}`
}).join('')
},
mergeOrderData(dataList) {
// 第一步:先按照订单行号对原始数据进行排序
const sortedDataList = [...dataList].sort((a, b) => {
const rowA = parseInt(a.订单行号 || 0)
const rowB = parseInt(b.订单行号 || 0)
return rowA - rowB
})
const orderMap = new Map()
sortedDataList.forEach((item, index) => {
const orderNumber = item.订单号
if (!orderMap.has(orderNumber)) {
// 判断该工序是否外协
const isOutsource = item.指派对象 && item.指派对象.includes('外协')
orderMap.set(orderNumber, {
...item,
当前序: '',
开工时间: 0,
序检: item.序检,
是否外协: isOutsource, // 新增:记录订单是否包含外协
子数据: [{
工序名称: item.工序名称,
指派对象: item.指派对象,
计划完成时间: item.计划完成时间,
计划开始时间: item.计划开始时间,
进度: item.进度,
拆分内码: item.拆分内码,
计划数量: item.计划数量,
开工时间: item.开工时间,
完成数量: item.完成数量,
收料数量: item.收料数量,
收检合格数: item.收检合格数,
收检不合格数: item.收检不合格数,
任务状态: item.任务状态,
加工状态: item.加工状态,
终检: item.终检,
是否外协: isOutsource, // 新增:记录该工序是否外协
绿: 0,
: 0,
: 0,
订单行号: item.订单行号,
加急总数:item.加急总数,
外协结束时间:item.外协结束时间,
开始时间:item.开始时间,
外协分组: item.外协分组
}]
})
} else {
const existingItem = orderMap.get(orderNumber)
// 判断该工序是否外协
const isOutsource = item.指派对象 && item.指派对象.includes('外协')
// 如果发现外协工序,更新订单的外协状态
if (isOutsource) {
existingItem.是否外协 = true
}
// 插入子数据时保持排序
existingItem.子数据.push({
工序名称: item.工序名称,
指派对象: item.指派对象,
计划完成时间: item.计划完成时间,
计划开始时间: item.计划开始时间,
进度: item.进度,
拆分内码: item.拆分内码,
计划数量: item.计划数量,
开工时间: item.开工时间,
完成数量: item.完成数量,
收料数量: item.收料数量,
收检合格数: item.收检合格数,
收检不合格数: item.收检不合格数,
任务状态: item.任务状态,
加工状态: item.加工状态,
终检: item.终检,
是否外协: isOutsource, // 新增:记录该工序是否外协
绿: 0,
: 0,
: 0,
订单行号: item.订单行号,
加急总数:item.加急总数,
开始时间:item.开始时间,
结束时间:item.结束时间,
外协结束时间:item.外协结束时间,
外协分组: item.外协分组
})
// 对子数据按照订单行号排序
existingItem.子数据.sort((a, b) => {
const rowA = parseInt(a.订单行号 || 0)
const rowB = parseInt(b.订单行号 || 0)
return rowA - rowB
})
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.收检合格数 > 0) {
existingItem.当前序 = item.工序名称
}
if (item.优先级 == '是') {
existingItem.优先级 = item.优先级
}
if (item.终检 == '是') {
existingItem.终检 = item.终检
}
if (new Date(item.开工时间) > new Date('1900-01-01 00:00:00')) {
existingItem.开工时间 = 1
}
// 确保加急状态正确传递
if (item.加急状态 === '加急') {
existingItem.加急状态 = '加急'
}
}
})
// 应用过滤条件
let filteredData = 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.是否外协, // 新增:是否外协订单
加急数量: item.加急数量,
加急总数: item.加急总数,
入库数量: item.入库数量,
}))
// 应用外协过滤
if (this.outsourceStatus !== '全部') {
const isOutsource = this.outsourceStatus === '是'
filteredData = filteredData.filter(item => item.是否外协 === isOutsource)
}
// 应用加急过滤
if (this.urgentStatus !== '全部') {
const isUrgent = this.urgentStatus === '加急'
filteredData = filteredData.filter(item =>
isUrgent ? item.加急状态 === '加急' : (!item.加急状态 || item.加急状态 !== '加急')
)
}
this.tableData = filteredData
},
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(['计划开始1', this.planStartTime[0]])
param.push(['计划开始2', this.planStartTime[1]])
param.push(['计划完成1', this.planendTime[0]])
param.push(['计划完成2', this.planendTime[1]])
param.push(['要求完工日期1', this.completionTime ? this.completionTime[0] : ''])
param.push(['要求完工日期2', this.completionTime ? this.completionTime[1] : ''])
param.push(['排产状态', this.productionStatus])
param.push(['自制件属性', this.selfStatus])
param.push(['指派对象', '全部'])
param.push(['计划号', this.plannum])
param.push(['加急状态', this.urgentStatus])
param.push(['单据状态', this.orderStatus])
// // 添加外协状态过滤条件
// if (this.outsourceStatus !== '全部') {
// param.push(['是否外协', this.outsourceStatus === '是' ? 1 : 0])
// }
var Data = this.CreateData('11', '生产管理_生产计划跟踪', 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;
}
.process-route {
line-height: 20px;
white-space: normal;
word-break: break-all;
}
::v-deep .process-route-green {
color: #28d961;
font-weight: 700;
}
::v-deep .process-route-blue {
color: #09a8ff;
font-weight: 700;
}
::v-deep .process-route-red {
color: #ff3f37;
font-weight: 700;
}
::v-deep .process-route-arrow {
margin: 0 4px;
color: #909399;
}
.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;
}
.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

@@ -24,7 +24,7 @@
<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"
@@ -36,7 +36,7 @@
<span class="show-text">计划开始:</span>
<el-date-picker
v-model="planStartTime"
:clearable="false"
placeholder="计划开始时间"
style="width: 150px;
@@ -46,7 +46,7 @@
<span class="show-text">计划完成:</span>
<el-date-picker
v-model="planendTime"
:clearable="false"
placeholder="计划完成时间"
style="width: 150px;
vertical-align: top"

File diff suppressed because it is too large Load Diff

View File

@@ -148,7 +148,11 @@
</template>
</el-table-column>
<el-table-column align="center" prop="当前序" label="当前序" width="80" />
<el-table-column align="center" prop="工艺路线" label="工艺路线" width="180" />
<el-table-column align="center" label="工艺路线" width="260">
<template slot-scope="scope">
<div class="process-route" v-html="formatProcessRoute(scope.row)" />
</template>
</el-table-column>
<el-table-column align="center" prop="计划号" label="计划号" width="120" />
</el-table>
</el-card>
@@ -284,6 +288,142 @@ export default {
if (!date) return ''
return date.split(' ').length > 1 ? date.split(' ')[0] : date
},
toProcessNumber(value) {
const num = Number(value)
return Number.isFinite(num) ? num : 0
},
escapeProcessHtml(value) {
return String(value == null ? '' : value)
.replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;')
.replace(/'/g, '&#39;')
},
isOutsourceProcess(process) {
return process.指派对象 === '外协' ||
String(process.工序名称 || '').includes('(外协)') ||
String(process.工序名称 || '').includes('(外协)')
},
getProcessStatusNum(status) {
const statusNum = parseInt(status)
if (Number.isFinite(statusNum)) {
return statusNum
}
const statusMap = {
辅助开始: 2,
辅助结束: 3,
开始加工: 4,
暂停: 5,
报工: 6,
装配加工: 4
}
return statusMap[status] || 0
},
isBlueProcess(process) {
const statusNum = this.getProcessStatusNum(process.加工状态)
const countNum = parseInt(process.收检合格数)
return statusNum === 6 || statusNum === 3 || countNum > 0
},
isGreenProcess(process) {
return this.isOutsourceProcess(process) &&
this.toProcessNumber(process.收料数量) > this.toProcessNumber(process.收检合格数) + this.toProcessNumber(process.收检不合格数)
},
getProcessBaseClass(process) {
if (this.isGreenProcess(process)) {
return 'process-route-green'
}
if (this.isBlueProcess(process)) {
return 'process-route-blue'
}
const statusNum = this.getProcessStatusNum(process.加工状态)
if (statusNum === 2 || statusNum === 4) {
return 'process-route-green'
}
return 'process-route-red'
},
getOutsourceGroupClassState(processes) {
const classes = new Map()
let currentIndexes = []
let lastProcess = null
const flushOutsourceRun = () => {
if (currentIndexes.length > 0 && lastProcess) {
const className = this.getProcessBaseClass(lastProcess)
currentIndexes.forEach(index => classes.set(index, className))
}
currentIndexes = []
lastProcess = null
}
const isSameContinuousGroup = process => {
if (!lastProcess) {
return true
}
const lineNo = this.toProcessNumber(process.订单行号)
const lastLineNo = this.toProcessNumber(lastProcess.订单行号)
return lineNo === lastLineNo + 1 &&
String(process.外协分组 || '') === String(lastProcess.外协分组 || '')
}
processes.forEach((process, index) => {
if (!this.isOutsourceProcess(process)) {
flushOutsourceRun()
return
}
if (!isSameContinuousGroup(process)) {
flushOutsourceRun()
}
currentIndexes.push(index)
lastProcess = process
})
flushOutsourceRun()
return classes
},
getProcessClass(process, index, outsourceGroupClasses) {
if (this.isOutsourceProcess(process)) {
return outsourceGroupClasses.get(index) || this.getProcessBaseClass(process)
}
return this.getProcessBaseClass(process)
},
getRouteProcesses(row) {
if (Array.isArray(row.子数据) && row.子数据.length > 0) {
return row.子数据
}
return String(row.工艺路线 || '')
.split(',')
.map(name => name.trim())
.filter(Boolean)
.map(name => ({
工序名称: name,
加工状态: 0,
收检合格数: 0,
指派对象: '',
订单行号: 0,
收料数量: 0,
收检不合格数: 0
}))
},
formatProcessRoute(row) {
const processes = this.getRouteProcesses(row)
if (processes.length === 0) {
return ''
}
const outsourceGroupClasses = this.getOutsourceGroupClassState(processes)
return processes.map((process, index) => {
const name = process.工序名称 || ''
const className = this.getProcessClass(process, index, outsourceGroupClasses)
const arrow = index < processes.length - 1 ? '<span class="process-route-arrow">-&gt;</span>' : ''
return `<span class="${className}">${this.escapeProcessHtml(name)}</span>${arrow}`
}).join('')
},
mergeOrderData(dataList) {
// 第一步:先按照订单行号对原始数据进行排序
const sortedDataList = [...dataList].sort((a, b) => {
@@ -330,7 +470,8 @@ export default {
订单行号: item.订单行号,
加急总数:item.加急总数,
外协结束时间:item.外协结束时间,
开始时间:item.开始时间
开始时间:item.开始时间,
外协分组: item.外协分组
}]
})
} else {
@@ -370,6 +511,7 @@ export default {
开始时间:item.开始时间,
结束时间:item.结束时间,
外协结束时间:item.外协结束时间,
外协分组: item.外协分组
})
// 对子数据按照订单行号排序
@@ -615,6 +757,33 @@ export default {
width: 120px;
display: inline-flex;
}
.process-route {
line-height: 20px;
white-space: normal;
word-break: break-all;
}
::v-deep .process-route-green {
color: #28d961;
font-weight: 700;
}
::v-deep .process-route-blue {
color: #09a8ff;
font-weight: 700;
}
::v-deep .process-route-red {
color: #ff3f37;
font-weight: 700;
}
::v-deep .process-route-arrow {
margin: 0 4px;
color: #909399;
}
.search-container {
margin-bottom: 20px;
}
@@ -688,4 +857,4 @@ export default {
display: flex;
align-items: center;
}
</style>
</style>

View File

@@ -59,7 +59,10 @@
</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=" uesrname != '付延辉'" icon="el-icon-check" plain type="danger" style="width: 100px;" @click="saveValidationRecord2(multipleSelection)">直接校验</el-button>
<el-button :disabled=" uesrname != '付延辉'" icon="el-icon-check" plain type="danger" style="position: absolute;
width: 100px;
right: 36px;
top: 70px;width: 100px;" @click="saveValidationRecord2(multipleSelection)">直接校验</el-button>
<!-- <el-button :disabled="!!loading" icon="el-icon-plus" plain type="warning" style="width: 130px;" @click="addWorkTimeRecord">新增工时记录</el-button> -->
</div>