Browse Source

2026-07-09

工单明细数据汇总
master
fengyuan_yang 3 weeks ago
parent
commit
2a8635d0ce
  1. 31
      src/api/shopOrder/workOrderDetailsAlloc.js
  2. 22
      src/mixins/labelPrintTemplates.js
  3. 963
      src/views/modules/shopOrder/workOrderAlloc/searchWorkOrderDetailsAlloc.vue

31
src/api/shopOrder/workOrderDetailsAlloc.js

@ -0,0 +1,31 @@
import { createAPI } from '@/utils/httpRequest.js'
// -------------工单明细数据汇总--------------
/**
* 分页查询工单明细汇总主信息
* @param {Object} data 查询条件
*/
export const searchWorkOrderDetailsForAlloc = data =>
createAPI(`/shopOrder/workOrderDetailsAlloc/searchWorkOrderDetails`, 'post', data)
/**
* 根据allocType查询工单汇总数据
* @param {Object} data 查询条件
*/
export const selectWorkOrderDetailsByAllocType = data =>
createAPI(`/shopOrder/workOrderDetailsAlloc/list`, 'post', data)
/**
* 执行工单明细数据汇总调用存储过程
* @param {Object} data 请求参数
*/
export const executeWorkOrderDetailsAlloc = data =>
createAPI(`/shopOrder/workOrderDetailsAlloc/executeAlloc`, 'post', data)
/**
* 执行工单数据回传调用U8接口
* @param {Object} data 请求参数
*/
export const executeWorkOrderDetailsSync = data =>
createAPI(`/shopOrder/workOrderDetailsAlloc/executeSync`, 'post', data)

22
src/mixins/labelPrintTemplates.js

@ -173,13 +173,15 @@ export default {
const lineHeight = '3.5mm'; // 行高(避免同字号时看起来偏小)
// 第1行:编码(左) + Packing List(右)
// 优化点:Packing List 最长5位,区域缩小到12mm,No.区域扩展到36mm。
const packingList = printData.packingList || printData.PackingList || printData.packinglist || '';
// 第一行总可用宽度约 48mm:No 区 28mm,Packing List 区 20mm
const text1 = LODOP.ADD_PRINT_TEXT('2.8mm', startX, '28mm', lineHeight, `No.:${printData.partNo || ''}`);
LODOP.SET_PRINT_STYLEA(text1, "FontName", "Microsoft YaHei"); // 使用Arial,比微软雅黑窄
const noLineWidth = '36mm';
const packingStartX = '56mm';
const packingWidth = '12mm';
const text1 = LODOP.ADD_PRINT_TEXT('2.8mm', startX, noLineWidth, lineHeight, `No.:${printData.partNo || ''}`);
LODOP.SET_PRINT_STYLEA(text1, "FontName", "Microsoft YaHei");
LODOP.SET_PRINT_STYLEA(text1, "FontSize", fontSize);
// 右侧从48mm开始,宽20mm,结束于68mm,不会超出边框
const text1Right = LODOP.ADD_PRINT_TEXT('2.8mm', '48mm', '20mm', lineHeight, `${packingList}`);
const text1Right = LODOP.ADD_PRINT_TEXT('2.8mm', packingStartX, packingWidth, lineHeight, `${packingList}`);
LODOP.SET_PRINT_STYLEA(text1Right, "FontName", "Microsoft YaHei");
LODOP.SET_PRINT_STYLEA(text1Right, "FontSize", packingFontSize);
LODOP.SET_PRINT_STYLEA(text1Right, "Alignment", 1);
@ -316,13 +318,15 @@ export default {
const lineHeight = '4mm'; // 行高
// 第1行:编码(左) + Packing List(右)
// 优化点:Packing List 最长5位,区域缩小到12mm,No.区域扩展到36mm。
const packingList = printData.packingList || printData.PackingList || printData.packinglist || '';
// 第一行总可用宽度约 48mm:No 区 28mm,Packing List 区 20mm
const text1 = LODOP.ADD_PRINT_TEXT('3.5mm', startX, '28mm', lineHeight, `No.:${printData.partNo || ''}`);
const noLineWidth = '36mm';
const packingStartX = '56mm';
const packingWidth = '12mm';
const text1 = LODOP.ADD_PRINT_TEXT('3.5mm', startX, noLineWidth, lineHeight, `No.:${printData.partNo || ''}`);
LODOP.SET_PRINT_STYLEA(text1, "FontName", "Microsoft YaHei");
LODOP.SET_PRINT_STYLEA(text1, "FontSize", fontSize);
// 右侧从48mm开始,宽20mm,结束于68mm,不会超出边框
const text1Right = LODOP.ADD_PRINT_TEXT('3.5mm', '48mm', '20mm', lineHeight, `${packingList}`);
const text1Right = LODOP.ADD_PRINT_TEXT('3.5mm', packingStartX, packingWidth, lineHeight, `${packingList}`);
LODOP.SET_PRINT_STYLEA(text1Right, "FontName", "Microsoft YaHei");
LODOP.SET_PRINT_STYLEA(text1Right, "FontSize", packingFontSize);
LODOP.SET_PRINT_STYLEA(text1Right, "Alignment", 1);

963
src/views/modules/shopOrder/workOrderAlloc/searchWorkOrderDetailsAlloc.vue

@ -0,0 +1,963 @@
<template>
<div class="mod-config">
<el-card :class="['search-card', { collapsed: !searchExpanded }]" shadow="hover">
<div slot="header" class="search-header">
<div class="header-left">
<i class="el-icon-search"></i>
<span class="header-title">Search</span>
</div>
<div class="header-right">
<el-button
type="text"
size="small"
@click="toggleSearchExpand"
class="collapse-btn">
<i :class="searchExpanded ? 'el-icon-arrow-up' : 'el-icon-arrow-down'"></i>
{{ searchExpanded ? "收起" : "展开" }}
</el-button>
</div>
</div>
<el-form
:inline="true"
label-position="top"
:model="searchData"
class="search-form"
@keyup.enter.native="getData">
<template v-if="searchExpanded">
<el-row :gutter="16">
<el-col :span="4">
<el-form-item label="工厂编码">
<el-select v-model="searchData.site" placeholder="请选择工厂编码" clearable style="width: 100%">
<el-option
v-for="item in siteList"
:key="item"
:label="item"
:value="item">
</el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="4">
<el-form-item label="订单类型">
<el-input v-model="searchData.orderType" placeholder="请输入订单类型" clearable @click.native="getBaseList(16)"></el-input>
</el-form-item>
</el-col>
<el-col :span="4">
<el-form-item label="生产订单号">
<el-input v-model="searchData.orderNo" placeholder="请输入订单号" clearable></el-input>
</el-form-item>
</el-col>
<el-col :span="4">
<el-form-item label="派工单号">
<el-input v-model="searchData.seqNo" placeholder="请输入派工单号" clearable></el-input>
</el-form-item>
</el-col>
<el-col :span="4">
<el-form-item label="物料编码">
<el-input v-model="searchData.partNo" placeholder="请输入物料编码" clearable @click.native="getBaseList(5)"></el-input>
</el-form-item>
</el-col>
<el-col :span="4">
<el-form-item label="物料名称">
<el-input v-model="searchData.partDescription" placeholder="请输入物料名称" clearable></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="4">
<el-form-item label="报工人">
<el-input v-model="searchData.userName" placeholder="请输入报工人" clearable></el-input>
</el-form-item>
</el-col>
<el-col :span="4">
<el-form-item label="加工中心">
<el-input v-model="searchData.workCenterNo" placeholder="请输入加工中心" clearable></el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="工单创建日期">
<el-date-picker
v-model="searchData.date1"
type="date"
value-format="yyyy-MM-dd"
placeholder="开始日期"
style="width: 45%">
</el-date-picker>
<span style="margin: 0 6px; color: #DCDFE6;">~</span>
<el-date-picker
v-model="searchData.date2"
type="date"
value-format="yyyy-MM-dd"
placeholder="结束日期"
style="width: 45%">
</el-date-picker>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="计划完工日期">
<el-date-picker
v-model="searchData.date3"
type="date"
value-format="yyyy-MM-dd"
placeholder="开始日期"
style="width: 45%">
</el-date-picker>
<span style="margin: 0 6px; color: #DCDFE6;">~</span>
<el-date-picker
v-model="searchData.date4"
type="date"
value-format="yyyy-MM-dd"
placeholder="结束日期"
style="width: 45%">
</el-date-picker>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="8">
<el-form-item label="实际完工日期">
<el-date-picker
v-model="searchData.finishDate1"
type="date"
value-format="yyyy-MM-dd"
placeholder="开始日期"
style="width: 45%">
</el-date-picker>
<span style="margin: 0 6px; color: #DCDFE6;">~</span>
<el-date-picker
v-model="searchData.finishDate2"
type="date"
value-format="yyyy-MM-dd"
placeholder="结束日期"
style="width: 45%">
</el-date-picker>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="报工日期">
<el-date-picker
v-model="searchData.reportDate1"
type="date"
value-format="yyyy-MM-dd"
placeholder="开始日期"
style="width: 45%">
</el-date-picker>
<span style="margin: 0 6px; color: #DCDFE6;">~</span>
<el-date-picker
v-model="searchData.reportDate2"
type="date"
value-format="yyyy-MM-dd"
placeholder="结束日期"
style="width: 45%">
</el-date-picker>
</el-form-item>
</el-col>
</el-row>
</template>
<el-row :gutter="16">
<el-col :span="24">
<div class="search-actions">
<div class="action-left">
<el-button
type="primary"
icon="el-icon-search"
:loading="searchLoading"
@click="getData">
查询
</el-button>
<el-button
icon="el-icon-refresh"
@click="resetSearch">
重置
</el-button>
</div>
<div class="action-right">
<el-button
type="success"
icon="el-icon-document-add"
:loading="allocLoading"
@click="executeAlloc">
工单明细数据汇总
</el-button>
<el-button
type="warning"
icon="el-icon-upload2"
:loading="syncLoading"
@click="executeSync">
工单数据回传
</el-button>
</div>
</div>
</el-col>
</el-row>
</el-form>
</el-card>
<div class="section-title-bar">
<i class="el-icon-document"></i>
<span>工单明细信息</span>
<span class="selected-count" v-if="selectedOrders.length > 0">已选择 {{ selectedOrders.length }} </span>
</div>
<el-table
ref="orderTable"
:height="orderTableHeight"
:data="orderList"
border
highlight-current-row
v-loading="orderListLoading"
@selection-change="handleOrderSelectionChange"
@row-click="handleOrderRowClick"
style="width: 100%;">
<el-table-column
type="selection"
header-align="center"
align="center"
width="50">
</el-table-column>
<el-table-column
v-for="(item, index) in orderColumnList"
:key="index"
:sortable="item.columnSortable"
:prop="item.columnProp"
:header-align="item.headerAlign"
:show-overflow-tooltip="true"
:align="item.align"
:fixed="item.fixed == '' ? false : item.fixed"
:min-width="item.columnWidth"
:label="item.columnLabel">
<template slot-scope="scope">
<span v-if="!item.columnHidden">{{ scope.row[item.columnProp] }}</span>
</template>
</el-table-column>
</el-table>
<el-pagination
style="margin-top: 0px"
@size-change="sizeChangeHandle"
@current-change="currentChangeHandle"
:current-page="pageIndex"
:page-sizes="[20, 50, 100, 200, 500, 1000]"
:page-size="pageSize"
:total="totalPage"
layout="total, sizes, prev, pager, next, jumper">
</el-pagination>
<div class="section-title-bar" style="margin-top: 0px;">
<i class="el-icon-data-analysis"></i>
<span>汇总数据明细</span>
<span class="current-order-info" v-if="currentOrder">
当前工单: {{ currentOrder.orderNo }} / 派工单: {{ currentOrder.seqNo }}
</span>
</div>
<el-tabs v-model="activeTab" type="border-card" @tab-click="handleTabClick" class="customer-tab" :style="{height: allocTableHeight + 60 + 'px'}">
<el-tab-pane label="产量未传输记录" name="产量未传输">
<el-table
:height="allocTableHeight"
:data="allocList"
border
v-loading="allocListLoading"
style="width: 100%">
<el-table-column
v-for="(item, index) in filteredAllocColumnList"
:key="index"
:prop="item.columnProp"
:header-align="item.headerAlign"
:show-overflow-tooltip="true"
:align="item.align"
:min-width="item.columnWidth"
:label="item.columnLabel">
</el-table-column>
</el-table>
</el-tab-pane>
<el-tab-pane label="产量已传输记录" name="产量已传输">
<el-table
:height="allocTableHeight"
:data="allocList"
border
v-loading="allocListLoading"
style="width: 100%">
<el-table-column
v-for="(item, index) in filteredAllocColumnList"
:key="index"
:prop="item.columnProp"
:header-align="item.headerAlign"
:show-overflow-tooltip="true"
:align="item.align"
:min-width="item.columnWidth"
:label="item.columnLabel">
</el-table-column>
</el-table>
</el-tab-pane>
<el-tab-pane label="工时未传输记录" name="工时未传输">
<el-table
:height="allocTableHeight"
:data="allocList"
border
v-loading="allocListLoading"
style="width: 100%">
<el-table-column
v-for="(item, index) in filteredAllocColumnList"
:key="index"
:prop="item.columnProp"
:header-align="item.headerAlign"
:show-overflow-tooltip="true"
:align="item.align"
:min-width="item.columnWidth"
:label="item.columnLabel">
</el-table-column>
</el-table>
</el-tab-pane>
<el-tab-pane label="工时已传输记录" name="工时已传输">
<el-table
:height="allocTableHeight"
:data="allocList"
border
v-loading="allocListLoading"
style="width: 100%">
<el-table-column
v-for="(item, index) in filteredAllocColumnList"
:key="index"
:prop="item.columnProp"
:header-align="item.headerAlign"
:show-overflow-tooltip="true"
:align="item.align"
:min-width="item.columnWidth"
:label="item.columnLabel">
</el-table-column>
</el-table>
</el-tab-pane>
</el-tabs>
<Chooselist ref="baseList" @getBaseData="getBaseData"></Chooselist>
</div>
</template>
<script>
import Chooselist from '@/views/modules/common/Chooselist'
import {
searchWorkOrderDetailsForAlloc,
selectWorkOrderDetailsByAllocType,
executeWorkOrderDetailsAlloc,
executeWorkOrderDetailsSync
} from '@/api/shopOrder/workOrderDetailsAlloc.js'
import { getSiteList } from '@/api/report/partTemplateStatus.js'
export default {
name: 'searchWorkOrderDetailsAlloc',
components: {
Chooselist
},
data () {
return {
siteList: [],
tagNo: '',
searchExpanded: true,
searchLoading: false,
allocLoading: false,
syncLoading: false,
orderListLoading: false,
allocListLoading: false,
orderTableHeight: 200,
allocTableHeight: 200,
pageIndex: 1,
pageSize: 20,
totalPage: 0,
searchData: {
site: '',
orderType: '',
orderNo: '',
seqNo: '',
partNo: '',
partDescription: '',
userName: '',
workCenterNo: '',
date1: '',
date2: '',
date3: '',
date4: '',
finishDate1: '',
finishDate2: '',
reportDate1: '',
reportDate2: '',
user: this.$store.state.user.name,
page: 0,
limit: 20
},
orderList: [],
selectedOrders: [],
currentOrder: null,
allocList: [],
activeTab: '产量未传输',
orderColumnList: [
{ columnProp: 'site', headerAlign: 'center', align: 'left', columnLabel: '工厂编码', columnWidth: 90, fixed: 'left' },
{ columnProp: 'orderNo', headerAlign: 'center', align: 'left', columnLabel: '订单号', columnWidth: 140, fixed: 'left' },
{ columnProp: 'orderType', headerAlign: 'center', align: 'left', columnLabel: '订单类型', columnWidth: 90 },
{ columnProp: 'seqNo', headerAlign: 'center', align: 'left', columnLabel: '派工单号', columnWidth: 100 },
{ columnProp: 'partNo', headerAlign: 'center', align: 'left', columnLabel: '物料编码', columnWidth: 120 },
{ columnProp: 'partDescription', headerAlign: 'center', align: 'left', columnLabel: '物料名称', columnWidth: 180 },
{ columnProp: 'lotSize', headerAlign: 'center', align: 'right', columnLabel: '订单需求数量', columnWidth: 120 },
{ columnProp: 'batchNo', headerAlign: 'center', align: 'left', columnLabel: '合约号码', columnWidth: 120 },
{ columnProp: 'createDate', headerAlign: 'center', align: 'left', columnLabel: '工单创建时间', columnWidth: 150 },
{ columnProp: 'planFinishTime', headerAlign: 'center', align: 'left', columnLabel: '计划完工日期', columnWidth: 150 },
{ columnProp: 'finishTime', headerAlign: 'center', align: 'left', columnLabel: '实际完工日期', columnWidth: 150 },
{ columnProp: 'sScheduledDate', headerAlign: 'center', align: 'left', columnLabel: '派工单创建日期', columnWidth: 150 },
{ columnProp: 'closedDate', headerAlign: 'center', align: 'left', columnLabel: '派工单关闭日期', columnWidth: 150 },
{ columnProp: 'operatorId', headerAlign: 'center', align: 'left', columnLabel: '报工人', columnWidth: 100 },
{ columnProp: 'reportDate', headerAlign: 'center', align: 'left', columnLabel: '报工时间', columnWidth: 150 },
{ columnProp: 'scheduledShiftNo', headerAlign: 'center', align: 'left', columnLabel: '班次', columnWidth: 90 },
{ columnProp: 'workCenterNo', headerAlign: 'center', align: 'left', columnLabel: '加工中心', columnWidth: 120 },
{ columnProp: 'totalReportQty', headerAlign: 'center', align: 'right', columnLabel: '报告数量', columnWidth: 100 },
{ columnProp: 'totalApproveQty', headerAlign: 'center', align: 'right', columnLabel: '合格数量', columnWidth: 100 },
{ columnProp: 'defectQty', headerAlign: 'center', align: 'right', columnLabel: '不良数量', columnWidth: 100 },
{ columnProp: 'totalSetupTime', headerAlign: 'center', align: 'right', columnLabel: '调机总时长', columnWidth: 100 },
{ columnProp: 'totalManfTime', headerAlign: 'center', align: 'right', columnLabel: '制造总时长', columnWidth: 100 },
{ columnProp: 'totalDownTime', headerAlign: 'center', align: 'right', columnLabel: '停机总时长', columnWidth: 100 }
],
allocColumnList: [
{ columnProp: 'orderNo', headerAlign: 'center', align: 'left', columnLabel: '订单号', columnWidth: 120 },
{ columnProp: 'batchNo', headerAlign: 'center', align: 'left', columnLabel: '批次号', columnWidth: 100 },
{ columnProp: 'erpOrderNo', headerAlign: 'center', align: 'left', columnLabel: 'ERP订单号', columnWidth: 120 },
{ columnProp: 'erpOrderLineNo', headerAlign: 'center', align: 'left', columnLabel: 'ERP订单行号', columnWidth: 100 },
{ columnProp: 'rowNo', headerAlign: 'center', align: 'left', columnLabel: '行号', columnWidth: 100 },
{ columnProp: 'itemNo', headerAlign: 'center', align: 'left', columnLabel: '工序号', columnWidth: 80 },
{ columnProp: 'operator', headerAlign: 'center', align: 'left', columnLabel: '操作员', columnWidth: 100 },
{ columnProp: 'allocReportQty', headerAlign: 'center', align: 'right', columnLabel: '报告数量', columnWidth: 100 },
{ columnProp: 'allocApproveQty', headerAlign: 'center', align: 'right', columnLabel: '合格数量', columnWidth: 100 },
{ columnProp: 'allocScrapQty', headerAlign: 'center', align: 'right', columnLabel: '不良数量', columnWidth: 100 },
{ columnProp: 'allocSetupTime', headerAlign: 'center', align: 'right', columnLabel: '调机时长', columnWidth: 100 },
{ columnProp: 'allocManfTime', headerAlign: 'center', align: 'right', columnLabel: '制造时长', columnWidth: 100 },
{ columnProp: 'allocBy', headerAlign: 'center', align: 'left', columnLabel: '汇总操作人', columnWidth: 100 },
{ columnProp: 'allocDate', headerAlign: 'center', align: 'left', columnLabel: '汇总时间', columnWidth: 150 },
{ columnProp: 'syncedDate', headerAlign: 'center', align: 'left', columnLabel: '回传时间', columnWidth: 150 },
{ columnProp: 'syncedMes', headerAlign: 'center', align: 'left', columnLabel: '异常原因', columnWidth: 200 },
{ columnProp: 'allocType', headerAlign: 'center', align: 'left', columnLabel: '数据类型', columnWidth: 100 }
]
}
},
watch: {
searchData: {
deep: true,
handler () {
this.searchData.orderType = (this.searchData.orderType || '').toUpperCase()
this.searchData.partNo = (this.searchData.partNo || '').toUpperCase()
this.searchData.orderNo = (this.searchData.orderNo || '').toUpperCase()
this.searchData.seqNo = (this.searchData.seqNo || '').toUpperCase()
this.searchData.workCenterNo = (this.searchData.workCenterNo || '').toUpperCase()
}
}
},
computed: {
filteredAllocColumnList () {
const hideColumnsByTab = {
'产量未传输': ['allocSetupTime', 'allocManfTime'],
'产量已传输': ['allocSetupTime', 'allocManfTime'],
'工时未传输': ['allocReportQty', 'allocApproveQty', 'allocScrapQty']
}
const hiddenColumnProps = hideColumnsByTab[this.activeTab] || []
return this.allocColumnList.filter(item => !hiddenColumnProps.includes(item.columnProp))
}
},
mounted () {
this.calculateTableHeight()
window.addEventListener('resize', this.calculateTableHeight)
},
beforeDestroy () {
window.removeEventListener('resize', this.calculateTableHeight)
},
created () {
this.setDefaultDateRange()
this.getSiteList()
this.getData()
},
methods: {
getSiteList () {
getSiteList().then(({ data }) => {
if (data && data.code === 0) {
this.siteList = data.siteList || []
}
})
},
setDefaultDateRange () {
const now = new Date()
const year = now.getFullYear()
const month = now.getMonth()
const firstDay = new Date(year, month, 1)
const lastDay = new Date(year, month + 1, 0)
const formatDate = date => {
const y = date.getFullYear()
const m = String(date.getMonth() + 1).padStart(2, '0')
const d = String(date.getDate()).padStart(2, '0')
return `${y}-${m}-${d}`
}
this.searchData.date1 = formatDate(firstDay)
this.searchData.date2 = formatDate(lastDay)
},
calculateTableHeight () {
this.$nextTick(() => {
const windowHeight = window.innerHeight
const headerHeight = this.searchExpanded ? 486 : 294
this.orderTableHeight = (windowHeight - headerHeight - 85) / 2
this.allocTableHeight = (windowHeight - headerHeight - 85) / 2
})
},
toggleSearchExpand () {
this.searchExpanded = !this.searchExpanded
this.calculateTableHeight()
},
resetSearch () {
this.searchData = {
site: '',
orderType: '',
orderNo: '',
seqNo: '',
partNo: '',
partDescription: '',
userName: '',
workCenterNo: '',
date1: '',
date2: '',
date3: '',
date4: '',
finishDate1: '',
finishDate2: '',
reportDate1: '',
reportDate2: '',
user: this.$store.state.user.name,
page: 0,
limit: 20
}
this.currentOrder = null
this.selectedOrders = []
this.allocList = []
this.setDefaultDateRange()
},
getBaseData (val) {
if (this.tagNo === 16) {
this.searchData.orderType = val.OrderType
}
if (this.tagNo === 5) {
this.searchData.partNo = val.PartNo
}
},
getBaseList (val) {
this.tagNo = val
this.$nextTick(() => {
let strVal = ''
if (val === 16) {
strVal = this.searchData.orderType
}
if (val === 5) {
strVal = this.searchData.partNo
}
this.$refs.baseList.init(val, strVal)
})
},
getData () {
this.searchLoading = true
this.orderListLoading = true
this.searchData.limit = this.pageSize
this.searchData.page = (this.pageIndex - 1) * this.pageSize
searchWorkOrderDetailsForAlloc(this.searchData)
.then(({ data }) => {
this.searchLoading = false
this.orderListLoading = false
if (data.code === 0) {
this.orderList = data.page.list || []
this.totalPage = data.page.totalCount
if (this.orderList.length > 0) {
const stillExists = this.currentOrder && this.orderList.some(
item =>
item.orderNo === this.currentOrder.orderNo &&
item.seqNo === this.currentOrder.seqNo &&
item.reportDate === this.currentOrder.reportDate
)
if (!stillExists) {
this.currentOrder = this.orderList[0]
}
this.getAllocData()
} else {
this.currentOrder = null
this.allocList = []
}
} else {
this.$message.error(data.msg || '查询失败')
}
})
.catch(err => {
this.searchLoading = false
this.orderListLoading = false
this.$message.error('查询异常:' + err.message)
})
},
getAllocData () {
if (!this.currentOrder) {
this.allocList = []
return
}
this.allocListLoading = true
const queryData = {
site: this.currentOrder.site,
orderNo: this.currentOrder.orderNo,
allocType: this.activeTab,
page: 0,
limit: 1000
}
selectWorkOrderDetailsByAllocType(queryData)
.then(({ data }) => {
this.allocListLoading = false
if (data.code === 0) {
this.allocList = data.page.list || []
} else {
this.$message.error(data.msg || '查询汇总数据失败')
}
})
.catch(err => {
this.allocListLoading = false
this.$message.error('查询汇总数据异常:' + err.message)
})
},
handleOrderSelectionChange (selection) {
this.selectedOrders = selection
},
handleOrderRowClick (row, column) {
if (column && column.type === 'selection') {
return
}
this.currentOrder = row
this.getAllocData()
},
handleTabClick (tab) {
this.activeTab = tab.name
this.getAllocData()
},
executeAlloc () {
this.$confirm('将按当前查询条件执行工单明细数据汇总,是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.doExecuteAlloc()
}).catch(() => {
//
})
},
doExecuteAlloc () {
this.allocLoading = true
const requestData = {
...this.searchData,
user: this.$store.state.user.name
}
executeWorkOrderDetailsAlloc(requestData)
.then(({ data }) => {
this.allocLoading = false
if (data.code === 0) {
this.$message.success(data.msg || '工单明细数据汇总成功')
this.getAllocData()
} else {
this.$message.error(data.msg || '工单明细数据汇总失败')
}
})
.catch(err => {
this.allocLoading = false
this.$message.error('工单明细数据汇总异常:' + err.message)
})
},
executeSync () {
this.$confirm('该操作将根据所勾选工单汇总未传输的工时及产量数据回传至上位系统,是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.syncLoading = true
const orderList = this.selectedOrders.map(item => ({ orderNo: item.orderNo, site: item.site }))
const requestData = {
site: this.searchData.site || '',
userName: this.searchData.user,
orderList: orderList.length > 0 ? orderList : null
}
executeWorkOrderDetailsSync(requestData)
.then(({ data }) => {
this.syncLoading = false
if (data.code === 0) {
this.$message.success(data.msg || '工单数据回传成功')
this.getAllocData()
} else {
this.$message.error(data.msg || '工单数据回传失败')
}
})
.catch(err => {
this.syncLoading = false
this.$message.error('工单数据回传异常:' + err.message)
})
}).catch(() => {
//
})
},
sizeChangeHandle (val) {
this.pageSize = val
this.pageIndex = 1
this.getData()
},
currentChangeHandle (val) {
this.pageIndex = val
this.getData()
}
}
}
</script>
<style scoped>
.search-card {
margin-bottom: 16px;
border-radius: 8px;
overflow: hidden;
transition: all 0.3s ease;
}
.search-card:hover {
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
}
.search-card /deep/ .el-card__header {
padding: 5px 20px;
background: linear-gradient(135deg, #9ac3d0 20%, #b6c7dd 80%);
border-bottom: none;
}
.search-header {
display: flex;
justify-content: space-between;
align-items: center;
}
.header-left {
display: flex;
align-items: center;
color: #fff;
}
.header-left i {
font-size: 16px;
margin-right: 8px;
}
.header-title {
font-size: 14px;
font-weight: 600;
letter-spacing: 0.5px;
}
.header-right {
color: #fff;
}
.collapse-btn {
color: #fff;
font-weight: 500;
transition: all 0.3s ease;
}
.collapse-btn:hover {
color: #f0f0f0;
transform: translateY(-1px);
}
.collapse-btn i {
transition: transform 0.3s ease;
}
.search-form {
padding: 6px 0;
min-height: 0;
}
.search-card /deep/ .el-card__body {
padding: 10px;
transition: all 0.3s ease;
}
.search-card.collapsed /deep/ .el-card__body {
padding: 10px 20px;
}
.search-form /deep/ .el-form-item {
margin-bottom: 12px;
}
.search-form /deep/ .el-form-item__label {
font-weight: 500;
color: #606266;
padding-bottom: 4px;
}
.search-form /deep/ .el-input__inner,
.search-form /deep/ .el-textarea__inner {
border-radius: 6px;
border: 1px solid #DCDFE6;
transition: all 0.3s ease;
}
.search-form /deep/ .el-input__inner:focus,
.search-form /deep/ .el-textarea__inner:focus {
border-color: #9ac3d0;
box-shadow: 0 0 0 2px rgba(154, 195, 208, 0.1);
}
.search-form /deep/ .el-select {
width: 100%;
}
.search-form /deep/ .el-date-editor.el-input {
width: 100%;
}
.search-actions {
display: flex;
justify-content: space-between;
align-items: center;
padding: 8px 0 2px 0;
}
.search-card:not(.collapsed) .search-actions {
border-top: 1px solid #f0f0f0;
margin-top: 6px;
}
.search-card.collapsed .search-actions {
border-top: none;
margin-top: 0;
padding-top: 0;
}
.action-left,
.action-right {
display: flex;
gap: 8px;
}
.search-actions .el-button {
border-radius: 4px;
padding: 5px 10px;
font-size: 12px;
font-weight: 500;
transition: all 0.3s ease;
}
.search-actions .el-button:hover {
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}
.search-actions .el-button--primary {
background: #60aeff;
border-color: #60aeff;
}
.search-actions .el-button--primary:hover {
background: #7dbdff;
border-color: #7dbdff;
}
.search-actions .el-button--success {
background: #67C23A;
border-color: #67C23A;
}
.search-actions .el-button--success:hover {
background: #85ce61;
border-color: #85ce61;
}
.search-actions .el-button--warning {
background: #E6A23C;
border-color: #E6A23C;
}
.search-actions .el-button--warning:hover {
background: #ebb563;
border-color: #ebb563;
}
.section-title-bar {
display: flex;
align-items: center;
padding: 8px 12px;
background: linear-gradient(135deg, #f5f7fa 0%, #e4e7eb 100%);
border-radius: 4px;
margin-bottom: 8px;
font-size: 14px;
font-weight: 600;
color: #303133;
}
.section-title-bar i {
font-size: 16px;
margin-right: 8px;
color: #409eff;
}
.section-title-bar .selected-count {
margin-left: 10px;
font-size: 12px;
font-weight: normal;
color: #67C23A;
}
.section-title-bar .current-order-info {
margin-left: 10px;
font-size: 12px;
font-weight: normal;
color: #409EFF;
}
/deep/ .customer-tab .el-tabs__content {
padding: 5px !important;
}
/deep/ .customer-tab .el-tabs__header {
margin-bottom: 0;
}
/deep/ .customer-tab .el-tabs__item {
font-weight: 500;
}
/deep/ .customer-tab .el-tabs__item.is-active {
color: #409eff;
font-weight: 600;
}
.el-table /deep/ .cell {
height: auto;
line-height: 1.5;
}
.el-table /deep/ .current-row {
background-color: #ecf5ff !important;
}
@media (max-width: 1200px) {
.search-actions {
flex-direction: column;
gap: 10px;
}
.action-left,
.action-right {
width: 100%;
justify-content: center;
}
}
</style>
Loading…
Cancel
Save