Files
MES_Manage_View_V20/src/views/PlanManagement/SelfMakePlando/index.vue

1782 lines
68 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<div>
<el-card>
<div class="search-container" @keyup.enter="searchTable">
<span class="show-head">待排产任务</span>
<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"
popper-class="virtual-cell-time-picker"
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="planStartTime"
: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" />
<span class="show-text">计划完成:</span>
<el-date-picker
v-model="planendTime"
: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: 100px;" @click="AllworkPlan">批量排产</el-button>
<el-button type="success" size="mini" style="width: 100px;" @click="workPlanOver" >排产完成</el-button>
<el-checkbox-group v-model="Doing" @change = "Doingform" style="margin: 20px;">
<el-checkbox v-for="item in Doingoptions" :key="item.工位号" :label="item.指南工位号" :value="item.工位号"> </el-checkbox>
</el-checkbox-group>
</div>
<el-tabs v-model="activeTab" class="custom-tabs">
<el-tab-pane label="表单" name="form">
<div style="width: 100%;">
<el-table
v-loading="loading"
:data="tableData"
:height="'60vh'"
border
element-loading-background="rgba(0, 0, 0, 0.2)"
element-loading-spinner="el-icon-loading"
highlight-current-row
size="mini"
style="width: 100%;"
tooltip-effect="dark"
ref="multipleTable"
@row-click="handleRowClick"
@selection-change="handleSelectionChange"
:row-class-name="tableRowClassName"
>
<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="80" fixed/>
<!-- <el-table-column align="center" prop="计划号" label="计划号" width="80" fixed/> -->
<el-table-column align="center" prop="产品编码" label="物料编码" width="150" fixed/>
<el-table-column align="center" prop="产品名称" label="物料名称" width="150" fixed/>
<el-table-column align="center" prop="计划数量" label="计划数" width="70" fixed/>
<el-table-column align="center" label="要求完工日期" width="100" fixed>
<template slot-scope="scope">
{{ formatDate(scope.row.要求完工日期) }}
</template>
</el-table-column>
<el-table-column align="center" prop="标准工时" label="工时" width="80" fixed/>
<el-table-column align="center" prop="工序名称" label="工序名称" width="80" fixed/>
<!-- <el-table-column align="center" prop="性质" label="性质" width="100" /> -->
<!-- <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="100" /> -->
<el-table-column align="center" prop="指派对象" label="指派对象" width="150" >
<template slot-scope="scope">
<div v-if="!scope.row.editingTarget" class="editable-cell" @click="startEditingTarget(scope.row)">
{{ scope.row.指派对象 ? scope.row.指派对象: "请选择"}}
</div>
<div v-if="scope.row.editingTarget">
<el-select
v-model="scope.row.指派对象"
filterable
placeholder="请选择"
@change="editdomTask"
ref="TargetSelect"
style="width: 100%">
<el-option
v-for="item in stationOptions"
:key="item.code"
:label="item.label"
:value="item.value"
/>
</el-select>
</div>
</template>
</el-table-column>
<el-table-column align="center" prop="指派数量" label="指派数量" width="200" >
<template slot-scope="scope">
<div v-if="!scope.row.editingNum" class="editable-cell" @click="startEditingNum(scope.row)">
{{ scope.row.指派数量? scope.row.指派数量: scope.row.计划数量 }}
</div>
<div v-if="scope.row.editingNum" >
<el-input class="editable-cell"
v-model="scope.row.指派数量"
size="small"
placeholder="数量"
@change="saveNum"
type="int"
style="width: 80px;"
></el-input>
<el-button type="warning" size="mini" style="width: 50px;" @click="editsum">确定</el-button>
</div>
</template>
</el-table-column>
<el-table-column align="center" label="计划开始" width="180">
<el-date-picker
v-model="scope.row.计划开始时间"
type="date"
slot-scope="scope"
placeholder = "计划开始时间"
size = "small"
style="width: 155px;"
value-format="yyyy/MM/dd"
@change = "editstarTask"
>
</el-date-picker>
</el-table-column>
<el-table-column align="center" label="计划完成" width="180">
<el-date-picker
v-model="scope.row.计划完成时间"
type="date"
slot-scope="scope"
placeholder = "计划完成时间"
size = "small"
style="width: 155px;"
value-format="yyyy/MM/dd"
@change = "editendTask">
</el-date-picker>
</el-table-column>
<el-table-column align="center" prop="外协分组" label="外协分组" width="120" >
<template slot-scope="scope">
<el-input class="editable-cell"
v-model="scope.row.外协分组"
size="small"
placeholder="外协分组"
@change="savegroup"
type="int"
style="width: 80px;"
></el-input>
</template>
</el-table-column>
<el-table-column align="center" label="原料状态" width="100">
<template slot-scope="scope">
<el-button type="text" size="mini"
@click="getitemdata(scope.row.订单号)">查看</el-button>
</template>
</el-table-column>
<el-table-column align="center" label="历史工时" width="100">
<template slot-scope="scope">
<el-button type="text" size="mini"
@click="getWorkHour(scope.row.产品编码)">查看</el-button>
</template>
</el-table-column>
<el-table-column align="center" label="图纸" width="200">
<template slot-scope="scope">
<el-button v-if="scope.row.worker !=0"
type="text"
size="mini"
style="margin-right: 5px; padding:0; width:auto"
@click="getitemdraw(scope.row)">零件图纸
</el-button>
<el-button
type="text"
size="mini"
style="margin-right: 5px; padding:0; width:auto"
@click="getprocessdraw(scope.row)">工艺图纸
</el-button>
</template>
</el-table-column>
<el-table-column align="center" prop="备注" label="备注" width="150" show-overflow-tooltip />
<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="editRemark(scope.row)">编辑</el-button>
</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="200">
<template slot-scope="scope">
<el-select
v-model="scope.row.二次派工"
filterable
placeholder="请选择"
@change="editpersonnel(scope.row)"
style="width: 100%"
multiple
>
<el-option
v-for="item in personnelOptions"
:key="item.code"
:label="item.label"
:value="item.value"
/>
</el-select>
</template>
</el-table-column>
<el-table-column align="center" label="最晚开始" width="180">
<el-date-picker
v-model="scope.row.最晚开始时间"
type="date"
slot-scope="scope"
placeholder = "最晚开始时间"
size = "small"
style="width: 155px;"
value-format="yyyy/MM/dd"
@change = "editlateTask">
</el-date-picker>
</el-table-column>
<!-- <el-table-column align="center" label="排产" width="120">
<template slot-scope="scope">
<el-button type="text" size="mini" @click="workPlan(scope.row)">计划排产</el-button>
</template>
</el-table-column> -->
<!-- <el-table-column align="center" label="派工状态" width="100">
<template slot-scope="scope">
<el-tag :type="scope.row.派工状态 === 1 ? 'success' : 'danger'" size="mini">
{{ scope.row.派工状态 === 1 ? '已完成' : '未完成' }}
</el-tag>
</template>
</el-table-column> -->
<el-table-column align="center" prop="优先级" label="优先级" width="80" >
<template slot-scope="scope">
<el-tag :type="scope.row.优先级 === '是' ? 'warning' : 'info'" size="mini">
{{ scope.row.优先级 }}
</el-tag>
</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="editRemark(scope.row)">编辑</el-button>
</template>
</el-table-column>
<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="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>
<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-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="remarkDialogVisible"
title="编辑备注信息"
width="600px"
center>
<el-form
ref="remarkForm"
:model="remarkForm"
label-width="140px"
size="mini">
<el-form-item label="优先级">
<el-select v-model="remarkForm.优先级" 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="remarkForm.未完成说明"
:rows="2"
type="textarea"
placeholder="请输入未完成说明"/>
</el-form-item>
<el-form-item label="派工特殊备注">
<el-input
v-model="remarkForm.派工特殊说明"
:rows="3"
type="textarea"
placeholder="请输入派工特殊备注"/>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="remarkDialogVisible = false"> </el-button>
<el-button
:loading="remarkSubmitLoading"
type="primary"
@click="submitRemark"> </el-button>
</div>
</el-dialog>
<el-dialog :visible.sync="dialogcasual" title="原料信息" center style="min-height: 300px;" width="1400px">
<el-card style="height: 550px">
<el-table
:data="itemdata"
:height="'55vh'"
border
size="mini"
style="margin-top: 20px; width: 95%;"
>
<el-table-column align="center" label="序号" type="index" width="50" />
<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="100" />
<el-table-column align="center" prop="拣配数量" label="拣配数量" width="100" />
<el-table-column align="center" prop="计划数量" label="计划数量" width="100" />
<el-table-column align="center" prop="存货量" label="存货量" width="80" />
<el-table-column align="center" prop="材质" label="材质" width="80" />
</el-table>
</el-card>
</el-dialog>
<el-dialog :visible.sync="dialogcasual2" title="历史工时" center style="min-height: 300px;" width="1400px">
<el-card style="height: 550px">
<el-table
:data="itemdata"
:height="'55vh'"
border
size="mini"
style="margin-top: 20px; width: 95%;"
>
<el-table-column prop="taskDescription" label="任务描述" min-width="380" show-overflow-tooltip>
<template slot-scope="scope">
<span :class="{ 'bold-text': scope.row.level === 1 }">{{ scope.row.taskDescription || '' }}</span>
</template>
</el-table-column>
<el-table-column prop="settlementReportPieceHours" label="结算报工单件工时" width="140" align="center">
<template slot-scope="scope">
{{ scope.row.settlementReportPieceHours*60 || 0 }}
</template>
</el-table-column>
<el-table-column prop="settlementAuxiliaryPieceHours" label="结算辅助单件工时" width="140" align="center">
<template slot-scope="scope">
{{ scope.row.settlementAuxiliaryPieceHours*60 || 0 }}
</template>
</el-table-column>
<el-table-column prop="station" label="工位" width="110" align="center" show-overflow-tooltip>
<template slot-scope="scope">
{{ scope.row.station || '' }}
</template>
</el-table-column>
<el-table-column prop="productionOrderNo" label="生产订单号" width="130" align="center" show-overflow-tooltip>
<template slot-scope="scope">
{{ scope.row.productionOrderNo || '' }}
</template>
</el-table-column>
<el-table-column prop="operatorNames" label="操作人" width="180" align="center" show-overflow-tooltip>
<template slot-scope="scope">
{{ scope.row.operatorNames || '' }}
</template>
</el-table-column>
<el-table-column prop="reportWorkHours" label="报工工时" width="100" align="center">
<template slot-scope="scope">
<span :class="{ 'bold-text': scope.row.level <= 2 }">{{ scope.row.reportWorkHours || '' }}</span>
</template>
</el-table-column>
<el-table-column prop="auxiliaryWorkHours" label="辅助工时" width="100" align="center">
<template slot-scope="scope">
<span :class="{ 'bold-text': scope.row.level <= 2 }">{{ scope.row.auxiliaryWorkHours || '' }}</span>
</template>
</el-table-column>
<el-table-column prop="reportFinishQty" label="报工完成数" width="110" align="center">
<template slot-scope="scope">
<span :class="{ 'bold-text': scope.row.level <= 2 }">{{ scope.row.reportFinishQty || '' }}</span>
</template>
</el-table-column>
<el-table-column prop="auxiliaryFinishQty" label="辅助完成数" width="110" align="center">
<template slot-scope="scope">
<span :class="{ 'bold-text': scope.row.level <= 2 }">{{ scope.row.auxiliaryFinishQty || '' }}</span>
</template>
</el-table-column>
<el-table-column prop="totalWorkHours" label="合计工时" width="100" align="center">
<template slot-scope="scope">
<span :class="{ 'bold-text': scope.row.level <= 2 }">{{ scope.row.totalWorkHours || '' }}</span>
</template>
</el-table-column>
<el-table-column prop="clampingTime" label="装夹时间" width="100" align="center">
<template slot-scope="scope">
{{ scope.row.clampingTime || '' }}
</template>
</el-table-column>
<el-table-column prop="programTime" label="程序时间" width="100" align="center">
<template slot-scope="scope">
{{ scope.row.programTime || '' }}
</template>
</el-table-column>
</el-table>
</el-card>
</el-dialog>
<!-- 图纸弹框 -->
<el-dialog :visible.sync="seeVisible" title="图纸" center width="1200px" overflow="scroll" >
<div id="el-dialog__body" style="min-height: 500px;"></div>
<div slot="footer" class="dialog-footer">
<el-button @click="seeVisible = false">关闭</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
// 这三个组件用于绘制日历
import FullCalendar from '@fullcalendar/vue'
import dayGridPlugin from '@fullcalendar/daygrid'
import interactionPlugin from '@fullcalendar/interaction'
import { MESDownFile } from '@/utils/request'
import { patchB1 } from '@/api/b1s';
import { postB1 } from '@/api/b1s';
import { seepdf, initPDFKeyboardShortcuts, setZoom } from '@/utils/pdf';
export default {
components: { FullCalendar },
data() {
return {
seeVisible:false,
downPDF:MESDownFile,
activeTab: 'form',
doneactiveTab: 'form',
orderNo: '',
contractNo: '',
productCode: '',
productName: '',
processName: '',
nature: '',
productionStatus: '未完成',
donecontractNo: '',
doneorderNo: '',
doneproductCode: '',
doneproductName: '',
doneprocessName: '',
donenature: '',
doneproductionStatus: '已完成',
Doing:[],
Doingoptions:[],
station:'全部',
completids:[],
completionTime: [],
planStartTime: [],
planendTime: [],
loading: false,
tableData: [],
donetableData: [],
multipleSelection: [],
dialogVisible: false,
submitLoading: false,
currentRow: {},
stationOptions: [],
selectedRow: null,
editnumber:0,
submitstatus:0,
formData: {
指派对象: '',
指派对象编号: '',
指派数量: 0,
计划开始时间: '',
计划完成时间: '',
最晚开始时间: '',
派工特殊说明: ''
},
remarkDialogVisible: false,
remarkSubmitLoading: false,
remarkForm: {
优先级: '',
未完成说明: '',
派工特殊说明: ''
},
personnelOptions: [],
personnel:[],
// 分页
total: 0, // 分页总数
pageCurrent: 1, // 分页当前页
pageSize: 20, // 分页每页显示条数
donetotal: 0, // 分页总数
donepageCurrent: 1, // 分页当前页
donepageSize: 20, // 分页每页显示条数
// 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, // 调整大小完成后回调
eventClick:this.handleEventClick,
height: 'auto', // 设置高度为auto使其自适应内容
dayMaxEvents: true // 限制每天显示的事件数量
},
donecalendarOptions: {
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, // 调整大小完成后回调
eventClick:this.handleEventClick,
height: 'auto', // 设置高度为auto使其自适应内容
dayMaxEvents: true // 限制每天显示的事件数量
},
currentTime: "",
itemdata:[],
dialogcasual:false,
dialogcasual2:false
}
},
computed: {
calendarEvents() {
return this.tableData.map(item => {
const isPriority = item.优先级 === '是'
return {
id: `${item.订单号}-${item.订单行号}-${item.拆分内码}`,
title: `${item.订单号} | ${item.产品名称} | ${item.指派对象} | ${item.计划数量}`,
start: this.formatDateForCalendar(this.formatDate2(item.计划开始时间)),
end: this.formatDateForCalendar(this.formatDate2(item.计划完成时间), true),
extendedProps: {
订单号: item.订单号,
订单行号: item.订单行号,
拆分内码: item.拆分内码,
指派对象: item.指派对象,
计划数量: item.计划数量,
优先级: item.优先级
},
backgroundColor: isPriority ? '#f56c6c' : '#409EFF', // 优先级高为红色,普通为蓝色
borderColor: isPriority ? '#f56c6c' : '#409EFF',
textColor: isPriority ? '#fff' : '#fff', // 白色文字
classNames: isPriority ? ['priority-event'] : ['normal-event']
}
})
},
donecalendarEvents() {
return this.donetableData.map(item => {
const isPriority = item.优先级 === '是'
return {
id: `${item.订单号}-${item.订单行号}-${item.拆分内码}`,
title: `${item.订单号} | ${item.产品名称} | ${item.指派对象} | ${item.计划数量} | ${item.完成数量} `,
start: this.formatDateForCalendar(this.formatDate2(item.计划开始时间)),
end: this.formatDateForCalendar(this.formatDate2(item.计划完成时间), true),
extendedProps: {
订单号: item.订单号,
订单行号: item.订单行号,
拆分内码: item.拆分内码,
指派对象: item.指派对象,
计划数量: item.计划数量,
优先级: item.优先级
},
backgroundColor: isPriority ? '#f56c6c' : '#409EFF', // 优先级高为红色,普通为蓝色
borderColor: isPriority ? '#f56c6c' : '#409EFF',
textColor: isPriority ? '#fff' : '#fff', // 白色文字
classNames: isPriority ? ['priority-event'] : ['normal-event']
}
})
}
},
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
})
}
},
doneactiveTab(newVal) {
if (newVal === 'doneschedule') {
this.$nextTick(() => {
// 判断日历的HTML Dom 是否存在
const calendarApi = this.$refs.donefullCalendar && this.$refs.donefullCalendar.getApi()
if (calendarApi) {
// 重新绘制日历界面 避免出现未渲染问题
calendarApi.updateSize()
}
this.donecalendarOptions.events = this.donecalendarEvents
})
}
},
tableData: {
handler() {
if (this.activeTab === 'schedule') {
this.calendarOptions.events = this.calendarEvents
this.$nextTick(() => {
const calendarApi = this.$refs.fullCalendar && this.$refs.fullCalendar.getApi()
if (calendarApi) {
calendarApi.refetchEvents()
}
})
}
},
deep: true
},
donetableData: {
handler() {
if (this.doneactiveTab === 'doneschedule') {
this.donecalendarOptions.events = this.donecalendarEvents
this.$nextTick(() => {
const calendarApi = this.$refs.donefullCalendar && this.$refs.donefullCalendar.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.getDoing()
this.getStationList()
this.getcompletids()
this.getpersonnelList()
this.getCurrentTime();
setInterval(this.getCurrentTime, 1000);
},
methods: {
getitemdraw(row) {
var param = [];
param[0] = ['物料编号', row.产品编码];
var Data = this.CreateData('11', '工艺管理_图纸维护_查看图纸', param);
this.ExecDatabase(Data).then(async (response) => {
console.log(response);
if (response.data.length > 0) {
var pdfSrc = "" + this.downPDF + "" + response.data[0].uid + ".pdf";
// 1. 先打开对话框
this.seeVisible = true;
// 2. 等待对话框完全渲染(使用 $nextTick 确保 DOM 已更新)
await this.$nextTick();
// 3. 等待一小段时间确保对话框内的容器完全渲染
setTimeout(async () => {
try {
await seepdf(pdfSrc, 'see');
} catch (error) {
console.error('PDF 渲染失败:', error);
this.$message.error('PDF 渲染失败: ' + error.message);
}
}, 300); // 增加延迟确保 DOM 完全渲染
} else {
this.$message.error('未上传图纸');
}
});
},
getprocessdraw(row) {
var param = []
param[0] = ['物料编号',row.产品编码]
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"
this.seeVisible = true
seepdf(pdfSrc,'see')
}else{
this.$message.error('未上传图纸')
}
})
},
getitemdata(item){
var param = []
this.dialogcasual = true
this.itemdata = []
param.push(["订单编号",item])
var Data = this.CreateData('11', '工艺管理_获取物料原料信息',param)
this.ExecDatabase(Data).then(response => {
response.data.forEach(element => {
if(element.U_MoType == '机加件'){
this.itemdata.push({
'子件编码':element.子件编码,
'子件名称':element.子件名称,
'计划数量':element.计划数量,
'材质':element.材质,
'基本数量':element.基本数量,
'存货量':element.存货量,
'待出数量':element.待出数量,
'拣配数量':element.拣配数量,
})
}
})
})
},
getWorkHour(item){
var param = []
this.dialogcasual2 = true
this.itemdata = []
param.push(["产品编码",item])
param.push(["合同号",''])
param.push(["订单号",''])
param.push(["工位",''])
param.push(["开始日期",''])
param.push(["结束日期",''])
param.push(["数据条数",100])
var Data = this.CreateData('11', '生产管理_结算工时_查询',param)
this.ExecDatabase(Data).then(response => {
response.data.forEach(element => {
if(element.Level == 2)
this.itemdata.push(element)
})
})
},
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}`;
},
getcompletids(){
const Data = this.CreateData('11', '计划排产_生产订单_已排产订单查询'); // 确保这个接口返回包含订单号的数据
this.ExecDatabase(Data).then(response => {
if (response.data && Array.isArray(response.data)) {
this.completids = response.data.map(item => item.订单编号); // 提取所有订单号
this.updateTableDataOrder(); // 数据更新后重新排序
}
})
},
updateTableDataOrder() {
this.$nextTick(() => {
const specialOrderNos = new Set(this.completids);
// 定义优先级等级映射(可根据实际值调整)
const priorityLevel = {
'高': 3,
'中': 2,
'低': 1,
'是': 1,
'否': 0,
'加急': 4,
'紧急': 4,
'一般': 2
// 如果还有其他值,比如 '紧急'、'重要',可以加
};
this.tableData.sort((a, b) => {
const aIsUrgent = a.加急状态 === '加急';
const bIsUrgent = b.加急状态 === '加急';
// 1. 加急任务优先置顶
if (aIsUrgent && !bIsUrgent) return -1;
if (!aIsUrgent && bIsUrgent) return 1;
// 2. 非加急中,按【优先级字段】排序(高 > 中 > 低)
const aPriority = priorityLevel[a.优先级] || 0;
const bPriority = priorityLevel[b.优先级] || 0;
if (aPriority !== bPriority) {
return bPriority - aPriority; // 降序:高优先级在前
}
// 3. 优先级相同,则匹配 completids 的任务靠前
const aIsSpecial = specialOrderNos.has(a.订单号);
const bIsSpecial = specialOrderNos.has(b.订单号);
if (aIsSpecial && !bIsSpecial) return -1;
if (!aIsSpecial && bIsSpecial) return 1;
// 4. 优先级相同,按订单号排序(安全比较)
const aOrderNo = String(a.订单号 || '');
const bOrderNo = String(b.订单号 || '');
if (aOrderNo !== bOrderNo) {
return aOrderNo.localeCompare(bOrderNo);
}
// 5. 订单号相同,按拆分内码排序(安全比较)
const aSplitCode = Number(a.订单行号) || 0;
const bSplitCode = Number(b.订单行号) || 0;
return aSplitCode - bSplitCode;
});
});
},
doneupdateTableDataOrder() {
this.$nextTick(() => {
const specialOrderNos = new Set(this.completids);
// 定义优先级等级映射(可根据实际值调整)
const priorityLevel = {
'高': 3,
'中': 2,
'低': 1,
'是': 1,
'否': 0,
'加急': 4,
'紧急': 4,
'一般': 2
// 如果还有其他值,比如 '紧急'、'重要',可以加
};
this.donetableData.sort((a, b) => {
const aIsUrgent = a.加急状态 === '加急';
const bIsUrgent = b.加急状态 === '加急';
// 1. 加急任务优先置顶
if (aIsUrgent && !bIsUrgent) return -1;
if (!aIsUrgent && bIsUrgent) return 1;
// 2. 非加急中,按【优先级字段】排序(高 > 中 > 低)
const aPriority = priorityLevel[a.优先级] || 0;
const bPriority = priorityLevel[b.优先级] || 0;
if (aPriority !== bPriority) {
return bPriority - aPriority; // 降序:高优先级在前
}
// 3. 优先级相同,则匹配 completids 的任务靠前
const aIsSpecial = specialOrderNos.has(a.订单号);
const bIsSpecial = specialOrderNos.has(b.订单号);
if (aIsSpecial && !bIsSpecial) return -1;
if (!aIsSpecial && bIsSpecial) return 1;
// 4. 优先级相同,按订单号排序(安全比较)
const aOrderNo = String(a.订单号 || '');
const bOrderNo = String(b.订单号 || '');
if (aOrderNo !== bOrderNo) {
return aOrderNo.localeCompare(bOrderNo);
}
// 5. 订单号相同,按拆分内码排序(安全比较)
const aSplitCode = Number(a.订单行号) || 0;
const bSplitCode = Number(b.订单行号) || 0;
return aSplitCode - bSplitCode;
});
});
},
tableRowClassName({ row, rowIndex }) {
const isUrgent = row.优先级 === '是' || row.加急状态 === '加急' ;
const isSpecial = this.completids.includes(row.订单号);
if (isUrgent) {
return 'priority-row';
}else if (isSpecial) {
return 'special-row'; // 新增橙色类
}
return '';
},
donetableRowClassName({ row, rowIndex }) {
const isUrgent = row.优先级 === '是' || row.加急状态 === '加急' ;
if (isUrgent) {
return 'priority-row';
}
return '';
},
handleEventClick(info) {
// info 包含点击的事件信息
const event = info.event
const taskInfo = event.extendedProps
// 可以弹出提示或打开编辑弹窗
this.$alert(`
<div style="text-align: left;">
<p><strong>订单号:</strong> ${taskInfo.订单号}</p>
<p><strong>指派对象:</strong> ${taskInfo.指派对象}</p>
<p><strong>计划数量:</strong> ${taskInfo.计划数量}</p>
<p><strong>开始时间:</strong> ${this.formatDate(event.startStr)}</p>
<p><strong>结束时间:</strong> ${this.formatDate(event.endStr)}</p>
</div>
`, '任务详情', {
dangerouslyUseHTMLString: true,
confirmButtonText: '关闭',
callback: () => {}
})
},
getDoing(){
var Data = this.CreateData('11', 'MES_登录_工位与名称_查询')
this.ExecDatabase(Data).then(response => {
this.loading = false
if (response.data.length !== 0) {
this.Doingoptions= response.data
// response.data.forEach(item => {
// this.Doing.push(item.指南工位号)
// });
this.searchTable()
this.donesearchTable()
}
})
},
Doingform(value){
this.station = ''
},
formatDate(date) {
if (!date) return ''
return date.split(' ').length > 1 ? date.split(' ')[0] : date
},
formatDate2(input) {
const parts = input.split(' ')[0].split('/'); // 取日期部分并按 / 分割
const [year, month, day] = parts;
return `${year}-${String(month).padStart(2, '0')}-${String(day).padStart(2, '0')}`;
},
handleSizeChanges(val) {
this.pageCurrent = 1
this.pageSize = val
this.searchTable()
},
handleCurrentChanges(val) {
this.pageCurrent = val
this.searchTable()
},
donehandleSizeChanges(val) {
this.pageCurrent = 1
this.pageSize = val
this.donesearchTable()
},
donehandleCurrentChanges(val) {
this.pageCurrent = val
this.donesearchTable()
},
searchTable() {
this.loading = true
this.tableData = []
var param = []
if(this.Doing.length>0 & this.station=='' ){
this.station = this.Doing.join(",")
}else if (this.station !='' & this.station !='全部'){
this.station = this.Doing.join(",")
}else{
this.station = '全部'
}
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[0]])
param.push(['要求完工日期2', this.completionTime[1]])
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(['排产状态', this.productionStatus])
param.push(['指派对象', this.station])
var Data = this.CreateData('11', 'MES_OrderPlanned_Query', param,this.pageSize, this.pageCurrent)
this.ExecDatabase(Data).then(response => {
this.loading = false
if (response.data.rows.length !== 0) {
this.total = response.data.total
this.tableData = response.data.rows
this.fninsertidx()
.map(item => ({
...item,
editingNum: false,
editingStatus: false,
editingTarget: false
}))
this.updateTableDataOrder();
}
}).catch(() => {
this.loading = false
})
},
fninsertidx(){
this.tableData.forEach(item => {
if(item.二次派工){
item.二次派工 = item.二次派工.split(",").map(Number)
}
if(item.最晚开始时间 =='1900/1/1 0:00:00'){
item.最晚开始时间 = ''
}
});
console.log(this.tableData)
},
donesearchTable() {
this.loading = true
this.donetableData = []
var param = []
if(this.Doing.length>0 & this.station=='' ){
this.station = this.Doing.join(",")
}else if (this.station !='' & this.station !='全部'){
this.station = this.Doing.join(",")
}else{
this.station = '全部'
}
param.push(['订单号', this.doneorderNo || 0])
param.push(['物料类型', '自制件'])
param.push(['合同号', this.donecontractNo])
param.push(['产品编码', this.doneproductCode])
param.push(['产品名称', this.doneproductName])
param.push(['工序名称', this.doneprocessName])
// param.push(['性质', this.donenature])
param.push(['要求完工日期1', this.completionTime[0]])
param.push(['要求完工日期2', this.completionTime[1]])
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(['排产状态', this.doneproductionStatus])
param.push(['指派对象', this.station])
var Data = this.CreateData('11', 'MES_OrderPlanned_Query', param,this.pageSize, this.pageCurrent)
this.ExecDatabase(Data).then(response => {
this.loading = false
const priorityLevel = {
'是': 1,
'否': 0,
// 如果还有其他值,比如 '紧急'、'重要',可以加
};
if (response.data.rows.length !== 0) {
this.donetotal = response.data.total
this.donetableData = response.data.rows
this.donefninsertidx()
.map(item => ({
...item,
editingNum: false,
editingStatus: false,
editingTarget: false
}))
this.doneupdateTableDataOrder();
}
}).catch(() => {
this.loading = false
})
},
donefninsertidx(){
this.donetableData.forEach(item => {
if(item.二次派工){
item.二次派工 = item.二次派工.split(",").map(Number)
}
if(item.最晚开始时间 =='1900/1/1 0:00:00'){
item.最晚开始时间 = ''
}
});
console.log(this.tableData)
},
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
}))
}
})
},
getpersonnelList() {
const params = []
const Data = this.CreateData('11', '系统管理_人员管理_所有有效人员查询', params)
this.ExecDatabase(Data).then(response => {
if (response.data && response.data.length > 0) {
this.personnelOptions = response.data.map(item => ({
label: item.人员姓名,
value: item.人员编号,
code: item.人员编号
}))
}
})
},
handleStationChange(value) {
const selected = this.stationOptions.find(item => item.value === value)
this.formData.指派对象编号 = selected ? selected.code : ''
},
workPlan(row) {
this.currentRow = row
this.getStationList()
this.dialogVisible = true
this.formData = {
指派对象: row.指派对象,
指派对象编号: row.指派对象编号,
指派数量: row.计划数量,
计划开始时间: row.计划开始时间,
计划完成时间: row.计划完成时间,
最晚开始时间: row.最晚开始时间,
派工特殊说明: row.派工特殊说明
}
},
handleSelectionChange(val) {
this.multipleSelection = val;
},
editstarTask(date){
var editstr = "[计划开始时间] = '"+ date+"'"
var params = [];
var row = this.selectedRow
params.push(["editstr",editstr])
params.push(["订单号",row.订单号])
params.push(["订单行号",row.订单行号])
params.push(["订单拆分内码",row.拆分内码])
const Data = this.CreateData('12', 'MES_OrderPlanned_EditTaskPlanned', params)
this.ExecDatabase(Data).then(response => {
if (response.data[0].result !== '1') {
this.$message.error('修改失败')
return
}
this.$message.success('修改成功')
})
},
editendTask(date){
var editstr = "[计划完成时间] = '"+ date+"'"
var params = [];
var row = this.selectedRow
params.push(["editstr",editstr])
params.push(["订单号",row.订单号])
params.push(["订单行号",row.订单行号])
params.push(["订单拆分内码",row.拆分内码])
const Data = this.CreateData('12', 'MES_OrderPlanned_EditTaskPlanned', params)
this.ExecDatabase(Data).then(response => {
if (response.data[0].result !== '1') {
this.$message.error('修改失败')
return
}
this.$message.success('修改成功')
})
},
editlateTask(date){
var editstr = "[最晚开始时间] = '"+ date+"'"
var params = [];
var row = this.selectedRow
params.push(["editstr",editstr])
params.push(["订单号",row.订单号])
params.push(["订单行号",row.订单行号])
params.push(["订单拆分内码",row.拆分内码])
const Data = this.CreateData('12', 'MES_OrderPlanned_EditTaskPlanned', params)
this.ExecDatabase(Data).then(response => {
if (response.data[0].result !== '1') {
this.$message.error('修改失败')
return
}
this.$message.success('修改成功')
})
},
editdomTask(date){
var editstr = "[指派对象] = '"+ date+"'"
var params = [];
var row = this.selectedRow
params.push(["editstr",editstr])
params.push(["订单号",row.订单号])
params.push(["订单行号",row.订单行号])
params.push(["订单拆分内码",row.拆分内码])
const Data = this.CreateData('12', 'MES_OrderPlanned_EditTaskPlanned', params)
this.ExecDatabase(Data).then(response => {
if (response.data[0].result !== '1') {
this.$message.error('修改失败')
return
}
this.cancelAllEditing();
this.$message.success('修改成功')
})
},
editpersonnel(row){
var params = [];
params.push(["TaskAID",row.taskaid])
params.push(["personnel",row.二次派工])
const Data = this.CreateData('12', '计划排产_二次派工', params)
this.ExecDatabase(Data).then(response => {
this.$message.success('修改成功')
})
},
doneeditpersonnel(row){
var params = [];
params.push(["TaskAID",row.taskaid])
params.push(["personnel",row.二次派工])
const Data = this.CreateData('12', '计划排产_二次派工', params)
this.ExecDatabase(Data).then(response => {
this.$message.success('修改成功')
})
},
AllworkPlan() {
const multipleSelectionrow = this.multipleSelection;
// 1. 校验:至少选择两个任务
if (multipleSelectionrow.length < 2) {
return this.$message.error('请选择多个任务');
}
// 新增:根据页面排序规则对选中行进行排序
// 假设您的表格数据有 sortOrder 字段,或者您需要根据特定字段排序
// 这里需要根据您实际的页面排序逻辑来调整
const sortedRows = [...multipleSelectionrow].sort((a, b) => {
// 示例排序逻辑:按照您页面显示的默认排序字段进行排序
// 比如按照 工序顺序、计划开始时间 或 其他业务字段
// 请根据实际需求修改以下排序条件
if (Number(a.订单行号) && Number(b.订单行号)) {
return Number(a.订单行号) - Number(b.订单行号); // 按工序顺序升序
}
// 如果没有工序顺序,可以按其他字段排序
return 0; // 保持原顺序
});
const firstpo = sortedRows[0];
// 2. 检查第一行是否有指派数量(若无则可设默认值)
if (!firstpo.指派数量) {
firstpo.指派数量 = firstpo.计划数量;
}
// 3. 检查第一行关键字段
if (!firstpo.指派对象 || !firstpo.计划开始时间) {
return this.$message.error('请填写第一道工序的指派对象和计划开始时间');
}
// 4. 遍历所有选中行,按排序后的顺序处理
console.log('排序前的选中行:', multipleSelectionrow);
console.log('排序后的选中行:', sortedRows);
for (let i = 0; i < sortedRows.length; i++) {
const item = sortedRows[i];
// 检查是否属于同一订单
if (item.订单号 !== firstpo.订单号) {
return this.$message.error('请选择同一订单任务');
}
// === 统一赋值:指派对象 和 指派数量(用第一行的值)===
if (i === 0) {
// 第一行:必须有值(已校验)
if (!item.指派对象) {
item.指派对象 = firstpo.指派对象;
}
} else {
const prevItem = sortedRows[i - 1]; // 注意:这里使用排序后的前一行
if (!item.指派对象) {
item.指派对象 = prevItem.指派对象;
}
}
if (!item.指派数量) {
item.指派数量 = item.计划数量;
}
// === 处理 计划开始时间:为空则继承上一行 ===
if (i === 0) {
// 第一行:必须有值(已校验)
if (!item.计划开始时间) {
item.计划开始时间 = firstpo.计划开始时间;
}
} else {
const prevItem = sortedRows[i - 1]; // 注意:这里使用排序后的前一行
if (!item.计划开始时间) {
item.计划开始时间 = prevItem.计划开始时间;
}
if (!item.计划完成时间) {
item.计划完成时间 = prevItem.计划完成时间;
}
}
// === 处理 计划完成时间:为空则等于当前行的 计划开始时间 ===
}
// 5. 更新状态
this.submitstatus = 1;
this.multipleSelection = sortedRows; // 更新为排序后的数据
},
// clickadjust(){
// var row = this.selectedRow
// const params = []
// params.push(['TaskAID', row.taskaid])
// params.push(['订单号', row.订单号])
// params.push(['订单行号', row.订单行号])
// params.push(['订单拆分内码', row.拆分内码])
// params.push(['派工特殊说明', row.派工特殊说明])
// params.push(['派工操作人', this.$store.state.user.name])
// const Data = this.CreateData('12', '计划排产_派工', params)
// this.ExecDatabase(Data).then(response => {
// if (response.data[0].result !== '1') {
// this.$message.error('派工失败')
// return
// }
// this.$message.success('派工成功')
// })
// },
editsum(){
var row = this.selectedRow
const params = []
if(this.editnumber >= 1 & this.editnumber <=row.计划数量 ){
params.push(['订单号', row.订单号])
params.push(['订单行号', row.订单行号])
params.push(['订单拆分内码', row.拆分内码])
params.push(['指派对象编号', row.指派对象编号])
params.push(['指派对象', row.指派对象])
params.push(['指派数量', this.editnumber ])
params.push(['派工特殊说明', row.派工特殊说明])
params.push(['计划开始时间', row.计划开始时间])
params.push(['计划完成时间', row.计划完成时间])
params.push(['最晚开始时间', row.最晚开始时间])
params.push(['派工操作人', this.$store.state.user.name])
}else{
return this.$message.error('指派数量输入错误')
}
const Data = this.CreateData('12', 'MES_OrderPlanned_SingleTaskPlanned', params)
this.ExecDatabase(Data).then(response => {
this.submitLoading = false
if (response.data[0].result !== '1') {
this.$message.error('派工失败')
return
}
this.$message.success('派工成功')
this.dialogVisible = false
this.searchTable()
this.donesearchTable()
}).catch(() => {
this.submitLoading = false
})
},
submitForm() {
this.submitLoading = true
this.multipleSelection.forEach(item => {
const params = []
params.push(['订单号', item.订单号])
params.push(['订单行号', item.订单行号])
params.push(['订单拆分内码', item.拆分内码])
params.push(['指派对象编号', item.指派对象编号])
params.push(['指派对象', item.指派对象])
params.push(['指派数量', item.指派数量])
params.push(['派工特殊说明', item.派工特殊说明])
params.push(['计划开始时间', item.计划开始时间])
params.push(['计划完成时间', item.计划完成时间])
params.push(['最晚开始时间', item.最晚开始时间])
params.push(['派工操作人', this.$store.state.user.name])
const Data = this.CreateData('12', 'MES_OrderPlanned_SingleTaskPlanned', params)
this.ExecDatabase(Data).then(response => {
this.submitLoading = false
if (response.data[0].result !== '1') {
this.$message.error('派工失败')
return
}
this.$message.success('派工成功')
}).catch(() => {
this.submitLoading = false
})
});
this.dialogVisible = false
this.searchTable()
this.donesearchTable()
this.submitstatus = 0
this.multipleSelection = []
},
startEditingNum(row) {
this.cancelAllEditing();
this.$set(row, 'editingNum', true);
},
startEditingTarget(row) {
this.cancelAllEditing();
this.$set(row, 'editingTarget', true);
},
saveNum(num) {
this.editnumber = num
},
savegroup(num) {
var row = this.selectedRow
const params = []
params.push(['TaskAID', row.taskaid])
params.push(['外协分组', num])
console.log(params)
const Data = this.CreateData('12', '计划排产_外协分组', params)
this.ExecDatabase(Data).then(response => {
this.$message.success('保存成功')
// this.searchTable()
// this.donesearchTable()
}).catch(() => {
this.submitLoading = false
})
},
handleRowClick(row) {
this.selectedRow = row
},
// 取消所有编辑
cancelAllEditing() {
this.tableData.forEach(row => {
this.$set(row, 'editingNum', false);
this.$set(row, 'editingStatus', false);
this.$set(row, 'editingTarget', false);
});
},
workPlanOver() {
const multipleSelectionrow = this.multipleSelection;
if (multipleSelectionrow.length < 1) {
return this.$message.error('请选择任务');
}
// 使用 for...of可以正常使用 return 跳出整个函数
for (const item of multipleSelectionrow) {
if (!item.指派对象) {
this.$message.error('请选择' + item.订单号 + '的指派对象');
return; // ✅ 成功截停整个函数
}
if (!item.指派数量) {
item.指派数量 = item.计划数量;
}
if (!item.计划开始时间) {
this.$message.error('请选择' + item.订单号 + '的计划开始时间');
return; // ✅ 截停
}
if (!item.计划完成时间) {
this.$message.error('请选择' + item.订单号 + '的计划完成时间');
return; // ✅ 截停
}
}
// 所有校验通过,继续执行
const params = [];
params.push(['任务列表', JSON.stringify(multipleSelectionrow)]);
params.push(['派工操作人', this.$store.state.user.name]);
const result = {};
multipleSelectionrow.forEach(element => {
const orderNo = element.订单号;
const startTime = element.计划开始时间; // "2025-10-01 00:00:00"
const finishTime = element.计划完成时间; // "2025-10-10 00:00:00"
// 如果该订单号还未在 result 中,初始化
if (!result[orderNo]) {
result[orderNo] = {
最早开始: null,
最晚完成: null
};
}
// 更新 最早开始时间(取最小值)
if (result[orderNo].最早开始 === null || startTime < result[orderNo].最早开始) {
result[orderNo].最早开始 = startTime;
}
// 更新 最晚完成时间(取最大值)
if (result[orderNo].最晚完成 === null || finishTime > result[orderNo].最晚完成) {
result[orderNo].最晚完成 = finishTime;
}
});
// 输出结果
const resultArray = Object.keys(result).map(orderNo => ({
订单号: orderNo,
最早开始: result[orderNo].最早开始?.replace(/\//g, '-'), // 将 / 替换为 -
最晚完成: result[orderNo].最晚完成?.replace(/\//g, '-') // 将 / 替换为 -
}));
resultArray.forEach(element => {
patchB1("/ProductionOrders("+element.订单号+")",{
"AbsoluteEntry": element.订单号,
"U_MODueDate": element.最晚完成,
"U_MOStartDate": element.最早开始,
})
})
const Data = this.CreateData('11', 'MES_OrderPlanned_Finish', params);
this.ExecDatabase(Data).then(response => {
this.$message.success('排产完成');
this.multipleSelection = [];
this.searchTable();
this.donesearchTable();
});
},
editRemark(row) {
this.currentRow = row
this.remarkDialogVisible = true
this.remarkForm = {
优先级: row.优先级 || '',
未完成说明: row.未完成说明 || '',
派工特殊说明: row.派工特殊说明 || ''
}
},
submitRemark() {
this.remarkSubmitLoading = true
const params = []
params.push(['订单号', this.currentRow.订单号])
params.push(['订单行号', this.currentRow.订单行号])
params.push(['订单拆分内码', this.currentRow.拆分内码])
params.push(['优先级', this.remarkForm.优先级])
params.push(['未完成说明', this.remarkForm.未完成说明])
params.push(['派工特殊说明', this.remarkForm.派工特殊说明])
params.push(['最后编辑人', this.$store.state.user.name])
const Data = this.CreateData('12', 'MES_OrderPlanned_DescriptionEdit', params)
this.ExecDatabase(Data).then(response => {
if (response.data[0].result !== '1') {
this.$message.error('保存失败')
return
}
this.$message.success('保存成功')
this.remarkDialogVisible = false
this.searchTable()
this.donesearchTable()
}).finally(() => {
this.remarkSubmitLoading = 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 = []
params.push(['订单号', taskInfo.订单号])
params.push(['订单行号', taskInfo.订单行号])
params.push(['订单拆分内码', taskInfo.拆分内码])
params.push(['计划开始时间', startTime])
params.push(['计划完成时间', endTime])
const Data = this.CreateData('12', '计划排产_自制件_日程时间修改', params)
this.ExecDatabase(Data).then(response => {
if (response.data[0].result !== '1') {
this.$message.error('计划时间更新失败')
if (revertCallback) revertCallback()
return
}
const row = this.tableData.find(item =>
item.订单号 === taskInfo.订单号 &&
item.订单行号 === taskInfo.订单行号 &&
item.拆分内码 === taskInfo.拆分内码
)
if (row) {
row.计划开始时间 = startTime
row.计划完成时间 = endTime
// 注意:这里不要触发 deep watch 的性能问题,但数据必须更新
}
this.$message.success('计划时间更新成功')
this.searchTable()
}).catch(() => {
this.$message.error('更新失败')
if (revertCallback) revertCallback()
})
}).catch(() => {
if (revertCallback) revertCallback()
})
}
}
}
</script>
<style scoped>
.priority-row {
background-color: #f56c6c !important; /* 浅红色背景 */
color: #000000 !important; /* 深红色文字 */
}
::v-deep .priority-row td {
background-color: #f56c6c !important;
color: #000000 !important;
border: #f56c6c;
}
::v-deep .special-row {
background-color: #ff9800 !important; /* 橙色背景 */
color: #000000 !important;
border: #ff9800;
}
::v-deep .special-row td {
background-color: #ff9800 !important;
color: #000000 !important;
border: #ff9800;
}
.el-table ::v-deep td.el-table__cell .editable-cell{
height: inherit;
}
.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;
}
::v-deep .el-checkbox__label {
display: inline-block;
padding-left: 10px;
line-height: 16px;
font-size: 14px;
font-weight: bold;
}
::v-deep .el-table__fixed {
height: auto !important;
bottom: 12px !important; /* 给滚动条留出空间 */
}
.el-picker-panel__icon-btn{
padding: 0;
}
</style>