You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
4582 lines
153 KiB
4582 lines
153 KiB
<template>
|
|
<div class="mod-config">
|
|
<el-form :inline="true" label-position="top" label-width="100px" style="margin-top: 0px;">
|
|
<el-form-item :label="'BU:'">
|
|
<el-select v-model="searchData.buNo" placeholder="请选择" >
|
|
<el-option label="全部" value=""></el-option>
|
|
<el-option
|
|
v-for = "i in buList"
|
|
:key = "i.buNo"
|
|
:label = "i.buDesc"
|
|
:value = "i.buNo">
|
|
</el-option>
|
|
</el-select>
|
|
</el-form-item>
|
|
<el-form-item :label="'发货通知单:'">
|
|
<el-input v-model="searchData.delNo" style="width: 120px"></el-input>
|
|
</el-form-item>
|
|
<el-form-item :label="'CMC Invoice:'">
|
|
<el-input v-model="searchData.cmcInvoice" style="width: 120px"></el-input>
|
|
</el-form-item>
|
|
<el-form-item :label="'通知单状态:'">
|
|
<el-select filterable v-model="searchData.notifyStatus" style="width: 120px">
|
|
<el-option label="全部" value=""></el-option>
|
|
<el-option label="已下达" value="已下达"></el-option>
|
|
<el-option label="仓库已确认" value="仓库已确认"></el-option>
|
|
<el-option label="已报关" value="已报关"></el-option>
|
|
<el-option label="订单取消" value="订单取消"></el-option>
|
|
</el-select>
|
|
</el-form-item>
|
|
<el-form-item :label="'ReadyDate'" >
|
|
<el-date-picker
|
|
style="width: 120px"
|
|
v-model="searchData.startDate"
|
|
type="date"
|
|
format="yyyy-MM-dd"
|
|
value-format="yyyy-MM-dd"
|
|
placeholder="选择日期">
|
|
</el-date-picker>
|
|
</el-form-item>
|
|
<el-form-item :label="'To'" >
|
|
<el-date-picker
|
|
style="width: 120px"
|
|
v-model="searchData.endDate"
|
|
type="date"
|
|
format="yyyy-MM-dd"
|
|
value-format="yyyy-MM-dd"
|
|
placeholder="选择日期">
|
|
</el-date-picker>
|
|
</el-form-item>
|
|
<el-form-item :label="'是否导出:'">
|
|
<el-select v-model="searchData.exportFlag" style="width: 120px">
|
|
<el-option label="全部" value=""></el-option>
|
|
<el-option label="已导出" value="Y"></el-option>
|
|
<el-option label="未导出" value="N"></el-option>
|
|
</el-select>
|
|
</el-form-item>
|
|
<el-form-item label="改单">
|
|
<el-checkbox v-model="searchData.modifyData" true-label="true" false-label="false" @change="searchTable()"></el-checkbox>
|
|
</el-form-item>
|
|
<el-form-item :label="' '" >
|
|
<el-button @click="searchTable()" type="primary" style="margin-left: 2px;margin-top: 0px">{{'查询'}}</el-button>
|
|
</el-form-item>
|
|
</el-form>
|
|
|
|
<el-table
|
|
@row-click="changeData"
|
|
highlight-current-row
|
|
:height="height"
|
|
:data="dataList"
|
|
ref="mainTable"
|
|
border :cell-style="cellStyle"
|
|
:row-class-name="tableRowClassName"
|
|
v-loading="dataListLoading"
|
|
style="width: 100%;">
|
|
<el-table-column
|
|
header-align="center"
|
|
align="center"
|
|
width="100"
|
|
fixed="left"
|
|
label="操作">
|
|
<template slot-scope="scope">
|
|
<a type="text" size="small" v-if="scope.row.notifyStatus==='已报关'" @click="updateModelOpen(scope.row)">修改</a>
|
|
<a type="text" size="small" v-if="scope.row.notifyStatus==='已下达'" @click="confirmModelOpen(scope.row)">仓库确认</a>
|
|
<a type="text" size="small" v-if="scope.row.notifyStatus==='仓库已确认'" @click="cancerConfirm(scope.row)">取消确认</a>
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column
|
|
v-for="(item,index) in columnList1" :key="index"
|
|
:sortable="item.columnSortable"
|
|
:prop="item.columnProp"
|
|
:header-align="item.headerAlign"
|
|
:show-overflow-tooltip="item.showOverflowTooltip"
|
|
: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>
|
|
<span v-if="item.columnImage"><img :src="scope.row[item.columnProp]"
|
|
style="width: 100px; height: 80px"/></span>
|
|
</template>
|
|
</el-table-column>
|
|
</el-table>
|
|
<el-pagination
|
|
@size-change="sizeChangeHandle"
|
|
@current-change="currentChangeHandle"
|
|
:current-page="pageIndex"
|
|
:page-sizes="[20, 50, 100, 1000]"
|
|
:page-size="pageSize"
|
|
:total="totalPage"
|
|
layout="total, sizes, prev, pager, next, jumper">
|
|
</el-pagination>
|
|
<el-tabs style="font-size: 12px;min-height: 200px" class="customer-tab" v-model="activeName" type="border-card" @tab-click="tabClick" >
|
|
<el-tab-pane :label="currentRow.cmcInvoice+'明细'" name="detail">
|
|
<el-table
|
|
:height="height" ref="cloDetailTable"
|
|
:data="dataList2" show-summary :summary-method="getDetailSummaries"
|
|
border :cell-style="cellStyleDetail"
|
|
style="width: 100%;">
|
|
<el-table-column
|
|
v-for="(item,index) in columnList2" :key="index"
|
|
:sortable="item.columnSortable"
|
|
:prop="item.columnProp"
|
|
:header-align="item.headerAlign"
|
|
:show-overflow-tooltip="item.showOverflowTooltip"
|
|
:align="item.align"
|
|
:fixed="item.fixed==''?false:item.fixed"
|
|
:min-width="item.columnWidth"
|
|
:label="item.columnLabel">
|
|
<template slot-scope="scope">
|
|
<!-- 金额字段特殊处理 -->
|
|
<span v-if="item.columnProp === 'ttlAmount' || item.columnProp === 'sumPrice'">
|
|
{{!!scope.row[item.columnProp]?scope.row[item.columnProp].toFixed(2):''}}
|
|
</span>
|
|
|
|
<!-- PN字段特殊处理,添加提示信息 -->
|
|
<template v-else-if="item.columnProp === 'pn'">
|
|
<el-tooltip
|
|
v-if="isPnDataIncomplete(scope.row)"
|
|
:content="getPnIncompleteTooltip(scope.row)"
|
|
placement="top">
|
|
<span
|
|
v-if="!item.columnHidden"
|
|
class="clickable-pn"
|
|
@click="navigateToPartHsCode(scope.row.pn)">
|
|
{{ scope.row[item.columnProp] }}
|
|
</span>
|
|
</el-tooltip>
|
|
<span v-else-if="!item.columnHidden">{{ scope.row[item.columnProp] }}</span>
|
|
</template>
|
|
|
|
<!-- 其他字段正常处理 -->
|
|
<template v-else>
|
|
<span v-if="!item.columnHidden">{{ scope.row[item.columnProp] }}</span>
|
|
<span v-if="item.columnImage"><img :src="scope.row[item.columnProp]" style="width: 100px; height: 80px"/></span>
|
|
</template>
|
|
</template>
|
|
</el-table-column>
|
|
|
|
</el-table>
|
|
</el-tab-pane>
|
|
|
|
<el-tab-pane label="手工装箱" name="box">
|
|
<!-- <el-button @click="oneClickPacking()" type="primary" style="margin-left: 2px;margin-top: 0px">{{'一键装箱'}}</el-button>
|
|
<el-button @click="newPalletModel()" type="primary" style="margin-left: 2px;margin-top: 0px">{{'装箱'}}</el-button>-->
|
|
<el-button @click="openMergeBoxDialog()" type="primary" style="margin-left: 2px;margin-top: 0px">{{'装箱'}}</el-button>
|
|
<el-button @click="palletMaintenance()" type="primary" style="margin-left: 2px;margin-top: 0px">{{'栈板维护'}}</el-button>
|
|
<el-button @click="exportExcel()" type="primary" style="margin-left: 2px;margin-top: 0px">{{'导出装箱数据'}}</el-button>
|
|
<el-button @click="upLoadPallet()" type="success" style="margin-left: 2px;margin-top: 0px">{{'导入装箱单'}}</el-button>
|
|
<el-table ref="detailTable"
|
|
:data="dataList4"
|
|
:height="height"
|
|
border show-summary :summary-method="getSummaries"
|
|
v-loading="dataListLoading"
|
|
style="width: 100%; ">
|
|
<el-table-column
|
|
header-align="center"
|
|
align="center"
|
|
width="150"
|
|
fixed="left"
|
|
label="操作">
|
|
<template slot-scope="scope">
|
|
<a type="text" size="small" @click="updatePalletModel(scope.row)">修改</a>
|
|
<a type="text" size="small" @click="deletePallet(scope.row)">删除</a>
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column
|
|
v-for="(item,index) in columnList4" :key="index"
|
|
:sortable="item.columnSortable"
|
|
:prop="item.columnProp"
|
|
:header-align="item.headerAlign"
|
|
:show-overflow-tooltip="item.showOverflowTooltip"
|
|
: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>
|
|
<span v-if="item.columnImage"><img :src="scope.row[item.columnProp]"
|
|
style="width: 100px; height: 80px"/></span>
|
|
</template>
|
|
</el-table-column>
|
|
</el-table>
|
|
</el-tab-pane>
|
|
|
|
<el-tab-pane label="装箱明细" name="pallet">
|
|
<packing-detail-tab
|
|
ref="packingDetailTab"
|
|
:current-row="currentRow"
|
|
:height="height"
|
|
:show-actions="true"
|
|
@refresh="searchTable">
|
|
</packing-detail-tab>
|
|
</el-tab-pane>
|
|
<el-tab-pane label="相关文档" name="codelnotifyConfirmDocument">
|
|
<oss-components label="申请单号" style="margin-top: 5px" height="44vh" :columns="ossColumns"
|
|
:order-ref1="currentRow.site" :order-ref2="currentRow.delNo" :codelnotifyFlag="'2'"
|
|
:rfq-no="currentRow.delNo">
|
|
</oss-components>
|
|
</el-tab-pane>
|
|
</el-tabs>
|
|
|
|
<el-dialog title="仓库确认" :close-on-click-modal="false" v-drag :visible.sync="confirmModelFlag" width="400px">
|
|
<el-form label-position="top" style="margin-left: 7px;margin-top: -5px;">
|
|
<el-row :gutter="20">
|
|
<el-col :span="12">
|
|
<el-form-item :label="'CMC Invoice'" >
|
|
<el-input v-model="confirmModel.cmcInvoice" disabled ></el-input>
|
|
</el-form-item>
|
|
</el-col>
|
|
<el-col :span="12">
|
|
<el-form-item :label="'ReadyDate'" >
|
|
<el-input v-model="confirmModel.readyDate" disabled ></el-input>
|
|
</el-form-item>
|
|
</el-col>
|
|
<el-col :span="12">
|
|
<el-form-item :label="'预计发货日期'" >
|
|
<el-date-picker
|
|
style="width: 100%"
|
|
v-model="confirmModel.notifyDate"
|
|
type="date"
|
|
format="yyyy-MM-dd"
|
|
value-format="yyyy-MM-dd"
|
|
placeholder="选择日期">
|
|
</el-date-picker>
|
|
</el-form-item>
|
|
</el-col>
|
|
</el-row>
|
|
</el-form>
|
|
<el-footer style="height:40px;margin-top: 10px;text-align:center">
|
|
<el-button type="primary" @click="confirmDo()">保存</el-button>
|
|
<el-button type="primary" @click="confirmModelFlag=false">关闭</el-button>
|
|
</el-footer>
|
|
</el-dialog>
|
|
|
|
<el-dialog title="修改" :close-on-click-modal="false" v-drag :visible.sync="updateModelFlag" width="350px">
|
|
<el-form label-position="top" style="margin-left: 7px;margin-top: -5px;">
|
|
<el-row :gutter="20">
|
|
<el-col :span="12">
|
|
<el-form-item :label="'ReadyDate'" >
|
|
<el-date-picker
|
|
style="width: 100%"
|
|
v-model="confirmModel.readyDate"
|
|
type="date"
|
|
format="yyyy-MM-dd"
|
|
value-format="yyyy-MM-dd"
|
|
placeholder="选择日期">
|
|
</el-date-picker>
|
|
</el-form-item>
|
|
</el-col>
|
|
<el-col :span="12">
|
|
<el-form-item :label="'预计发货日期'" >
|
|
<el-date-picker
|
|
style="width: 100%"
|
|
v-model="confirmModel.notifyDate"
|
|
type="date"
|
|
format="yyyy-MM-dd"
|
|
value-format="yyyy-MM-dd"
|
|
placeholder="选择日期">
|
|
</el-date-picker>
|
|
</el-form-item>
|
|
</el-col>
|
|
</el-row>
|
|
</el-form>
|
|
<el-footer style="height:40px;margin-top: 10px;text-align:center">
|
|
<el-button type="primary" @click="updateDo()">保存</el-button>
|
|
<el-button type="primary" @click="updateModelFlag=false">关闭</el-button>
|
|
</el-footer>
|
|
</el-dialog>
|
|
|
|
<el-dialog title="维护箱" :close-on-click-modal="false" v-drag :visible.sync="boxModelFlag" width="500px">
|
|
<el-form label-position="top" style="margin-left: 7px;margin-top: -5px;">
|
|
<el-row :gutter="20">
|
|
<el-col :span="12">
|
|
<el-form-item :label="boxModelData.type===1?'物料编码':''">
|
|
<span v-if="boxModelData.type===0" slot="label" @click="openPartDialog()"><a herf="#">物料编码</a></span>
|
|
<el-input v-model="boxModelData.pn" :disabled="boxModelData.type===1" ></el-input>
|
|
</el-form-item>
|
|
</el-col>
|
|
<el-col :span="12">
|
|
<el-form-item :label="'数量'" >
|
|
<el-input v-model="boxModelData.qty" type="number" ></el-input>
|
|
</el-form-item>
|
|
</el-col>
|
|
<el-col :span="12" v-if="boxModelData.type===0">
|
|
<el-form-item :label="'PO'" >
|
|
<el-input v-model="boxModelData.poNo" ></el-input>
|
|
</el-form-item>
|
|
</el-col>
|
|
<el-col :span="12">
|
|
<el-form-item :label="'箱数'" >
|
|
<el-input v-model="boxModelData.boxQty"></el-input>
|
|
</el-form-item>
|
|
</el-col>
|
|
<el-col :span="12">
|
|
<el-form-item :label="'ROLLS'" >
|
|
<el-input v-model="boxModelData.rolls" ></el-input>
|
|
</el-form-item>
|
|
</el-col>
|
|
<el-col :span="12">
|
|
<el-form-item :label="'毛重'" >
|
|
<el-input v-model="boxModelData.grossWeight"></el-input>
|
|
</el-form-item>
|
|
</el-col>
|
|
<el-col :span="12">
|
|
<el-form-item :label="'净重'" >
|
|
<el-input v-model="boxModelData.netWeight" ></el-input>
|
|
</el-form-item>
|
|
</el-col>
|
|
</el-row>
|
|
</el-form>
|
|
<el-footer style="height:40px;margin-top: 10px;text-align:center">
|
|
<el-button type="primary" @click="saveBoxHeader()">保存</el-button>
|
|
<el-button type="primary" @click="boxModelFlag=false">关闭</el-button>
|
|
</el-footer>
|
|
</el-dialog>
|
|
|
|
<!-- 装箱(新增/修改栈板) -->
|
|
<el-dialog
|
|
:title="palletModelData.addFlag===1 ? '修改栈板' : '手工装箱'"
|
|
:close-on-click-modal="false"
|
|
v-drag
|
|
:visible.sync="palletModelFlag"
|
|
width="780px"
|
|
class="pallet-dialog">
|
|
|
|
<!-- 区域 1:箱信息 -->
|
|
<div class="section section-header">
|
|
<h4 class="section-title">箱信息</h4>
|
|
<el-divider></el-divider>
|
|
<el-form label-position="top" class="box-info-form">
|
|
<el-row :gutter="20">
|
|
<el-col :span="6">
|
|
<el-form-item label="箱数">
|
|
<el-input v-model="palletModelData.boxQty" type="number" placeholder="请输入箱数" @input="calculateWeightsByBoxQty"></el-input>
|
|
</el-form-item>
|
|
</el-col>
|
|
<el-col :span="6">
|
|
<el-form-item label="毛重">
|
|
<el-input v-model="palletModelData.grossWeight" type="number" placeholder="自动计算" @input="onPalletGrossWeightChange"></el-input>
|
|
</el-form-item>
|
|
</el-col>
|
|
<el-col :span="6">
|
|
<el-form-item label="净重">
|
|
<el-input v-model="palletModelData.netWeight" type="number" placeholder="自动计算" @input="onPalletNetWeightChange"></el-input>
|
|
</el-form-item>
|
|
</el-col>
|
|
<el-col :span="6">
|
|
<el-form-item label="总Rolls(箱明细无rolls才可修改)">
|
|
<el-input
|
|
v-model="palletModelData.rolls"
|
|
type="number"
|
|
placeholder="箱明细无rolls才可修改"
|
|
:disabled="isTotalRollsDisabled"
|
|
></el-input>
|
|
</el-form-item>
|
|
</el-col>
|
|
</el-row>
|
|
</el-form>
|
|
</div>
|
|
|
|
<!-- 区域 2:箱明细 -->
|
|
<div class="section section-detail">
|
|
<h4 class="section-title">箱明细</h4>
|
|
<el-divider></el-divider>
|
|
<div class="table-wrapper">
|
|
<el-table
|
|
ref="partTableRef"
|
|
:data="dataList8"
|
|
height="100%"
|
|
stripe
|
|
border
|
|
class="zxClass"
|
|
style="width: 100%;">
|
|
<el-table-column prop="pn" label="PN" min-width="120"></el-table-column>
|
|
<el-table-column prop="partDescription" label="Description" min-width="220"></el-table-column>
|
|
<el-table-column prop="qty" label="原数量" align="right" width="70"></el-table-column>
|
|
<el-table-column prop="surplusQty" label="可装箱数量" align="right" width="80"></el-table-column>
|
|
<el-table-column label="装箱数量" align="center" width="80">
|
|
<template slot-scope="scope">
|
|
<el-input v-model.number="scope.row.useQty" type="number" :min="0" :max="999999" size="mini" @input="calculateRolls(scope.row)"></el-input>
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column label="Rolls" align="center" width="80">
|
|
<template slot-scope="scope">
|
|
<el-input v-model="scope.row.rolls" type="number" :min="0" :max="999999" size="mini" placeholder="自动计算" @input="delayCalculateTotalRolls"></el-input>
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column label="操作" align="center" width="70">
|
|
<template slot-scope="scope">
|
|
<a type="text" size="small" @click="fillUseQty(scope.row)">全数装箱</a>
|
|
</template>
|
|
</el-table-column>
|
|
</el-table>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 底部操作按钮 -->
|
|
<div slot="footer" class="dialog-footer">
|
|
<el-button type="primary" @click="savePalletHeader(0)">保存</el-button>
|
|
<el-button type="primary" @click="savePalletHeader(1)">保存并关闭</el-button>
|
|
<el-button @click="palletModelFlag=false">关闭</el-button>
|
|
</div>
|
|
</el-dialog>
|
|
|
|
<el-dialog
|
|
:title=" '修改栈板'"
|
|
:close-on-click-modal="false"
|
|
v-drag
|
|
:visible.sync="palletEditFlag"
|
|
width="240px"
|
|
class="pallet-dialog">
|
|
<div class="section section-header">
|
|
<el-divider></el-divider>
|
|
<el-form label-position="top" class="box-info-form">
|
|
<el-row :gutter="20">
|
|
<el-col :span="24">
|
|
<el-form-item label="栈板高度(M)">
|
|
<el-input v-model="palletModelData.height" type="number" placeholder="请输入栈板高度(M)"></el-input>
|
|
</el-form-item>
|
|
</el-col>
|
|
<el-col :span="24">
|
|
<el-form-item label="托数">
|
|
<el-input v-model="palletModelData.palletQty" type="number" placeholder="请输入托数"></el-input>
|
|
</el-form-item>
|
|
</el-col>
|
|
</el-row>
|
|
</el-form>
|
|
</div>
|
|
<!-- 底部操作按钮 -->
|
|
<div slot="footer" class="dialog-footer">
|
|
<el-button type="primary" @click="updateCodelPalletHeaderPalletQty">保存</el-button>
|
|
<el-button @click="palletEditFlag=false">关闭</el-button>
|
|
</div>
|
|
</el-dialog>
|
|
|
|
|
|
<el-dialog title="一键装箱" :close-on-click-modal="false" v-drag :visible.sync="oneClickPackingModelFlag" width="170px">
|
|
<el-form label-position="top" style="margin-left: 7px;margin-top: 10px;">
|
|
<el-row :gutter="20">
|
|
<el-col :span="12">
|
|
<el-form-item :label="''" >
|
|
<el-checkbox v-model="oneClickPackingModelData.boxRemnant">是否显示零数箱</el-checkbox>
|
|
</el-form-item>
|
|
</el-col>
|
|
</el-row>
|
|
</el-form>
|
|
<el-footer style="height:40px;margin-top: 10px;text-align:center">
|
|
<el-button type="primary" @click="saveOneClickPacking()">保存</el-button>
|
|
<el-button type="primary" @click="oneClickPackingModelFlag=false">关闭</el-button>
|
|
</el-footer>
|
|
</el-dialog>
|
|
|
|
<!-- 合箱批量编辑弹出框 -->
|
|
<el-dialog
|
|
title="合箱批量编辑"
|
|
:visible.sync="mergeBoxDialogVisible"
|
|
width="60%"
|
|
top="5vh"
|
|
custom-class="batch-edit-dialog"
|
|
:close-on-click-modal="false"
|
|
@open="loadMergeBoxData">
|
|
<div class="batch-edit-container" v-loading="mergeBoxLoading">
|
|
<!-- 操作工具栏 -->
|
|
<div class="merge-box-toolbar">
|
|
<el-button
|
|
type="primary"
|
|
size="small"
|
|
icon="el-icon-connection"
|
|
:disabled="mergeBoxSelection.length < 2"
|
|
@click="doMergeBoxes">
|
|
合并选中的箱 ({{ mergeBoxSelection.length }})
|
|
</el-button>
|
|
<el-button
|
|
type="warning"
|
|
size="small"
|
|
icon="el-icon-refresh-left"
|
|
:disabled="mergeBoxSelection.length === 0"
|
|
@click="doUnmergeSelectedBoxes">
|
|
取消合并
|
|
</el-button>
|
|
<div class="merge-stats">
|
|
<el-tag type="success" size="small">总箱数: {{ getUniqueBoxCount() }}</el-tag>
|
|
<span v-if="mergeBoxModifiedCount > 0" class="modified-count">
|
|
已修改 <b>{{ mergeBoxModifiedCount }}</b> 处
|
|
</span>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 操作提示 -->
|
|
<div class="batch-edit-tips">
|
|
<el-alert
|
|
type="info"
|
|
:closable="false"
|
|
show-icon>
|
|
<template slot="title">
|
|
<span>直接在表格中编辑数据,选择多个箱点击"合并"按钮可以合箱,选择已合并的箱点击"取消合并"可以拆分,修改后点击"保存所有修改"按钮提交</span>
|
|
</template>
|
|
</el-alert>
|
|
</div>
|
|
|
|
<!-- 行合并表格 -->
|
|
<el-table
|
|
ref="mergeBoxTable"
|
|
:data="mergeBoxTableData"
|
|
:span-method="mergeBoxSpanMethod"
|
|
border class="zxClass"
|
|
size="small"
|
|
height="50vh"
|
|
style="width: 100%"
|
|
@selection-change="handleMergeBoxSelectionChange"
|
|
:row-class-name="getMergeBoxRowClassName"
|
|
:header-cell-style="{background:'#f5f7fa', color:'#606266', fontWeight:'600'}">
|
|
|
|
<!-- 复选框列 - 只在第一行显示 -->
|
|
<el-table-column
|
|
type="selection"
|
|
width="55"
|
|
align="center"
|
|
:selectable="row => row._isFirstRowOfBox">
|
|
</el-table-column>
|
|
|
|
<!-- Box信息列(会合并) -->
|
|
<el-table-column label="序号" prop="item_no" width="60" align="center">
|
|
<template slot-scope="scope">
|
|
<span class="box-info-cell">{{ scope.row.item_no }}</span>
|
|
</template>
|
|
</el-table-column>
|
|
|
|
<el-table-column label="箱数" prop="box_qty" width="80" align="center">
|
|
<template slot-scope="scope">
|
|
<el-input
|
|
v-model="scope.row.box_qty"
|
|
size="mini"
|
|
type="number"
|
|
:class="{'modified-input': isBoxFieldModified(scope.row, 'box_qty')}"
|
|
@input="onMergeBoxQtyInput(scope.row)"
|
|
@change="onMergeBoxFieldChange(scope.row, 'box_qty')">
|
|
</el-input>
|
|
</template>
|
|
</el-table-column>
|
|
|
|
<el-table-column label="毛重" prop="grossWeight" width="100" align="center">
|
|
<template slot-scope="scope">
|
|
<el-input
|
|
v-model="scope.row.grossWeight"
|
|
size="mini"
|
|
type="number"
|
|
:class="{'modified-input': isBoxFieldModified(scope.row, 'grossWeight')}"
|
|
@input="onMergeGrossWeightInput(scope.row)"
|
|
@change="onMergeBoxFieldChange(scope.row, 'grossWeight')">
|
|
</el-input>
|
|
</template>
|
|
</el-table-column>
|
|
|
|
<el-table-column label="净重" prop="netWeight" width="100" align="center">
|
|
<template slot-scope="scope">
|
|
<el-input
|
|
v-model="scope.row.netWeight"
|
|
size="mini"
|
|
type="number"
|
|
:class="{'modified-input': isBoxFieldModified(scope.row, 'netWeight')}"
|
|
@input="onMergeNetWeightInput(scope.row)"
|
|
@change="onMergeBoxFieldChange(scope.row, 'netWeight')">
|
|
</el-input>
|
|
</template>
|
|
</el-table-column>
|
|
|
|
<el-table-column label="总Rolls" prop="rolls" width="100" align="center">
|
|
<template slot-scope="scope">
|
|
<el-input
|
|
v-model="scope.row.rolls"
|
|
size="mini"
|
|
type="number"
|
|
:disabled="hasDetailRolls(scope.row)"
|
|
:placeholder="hasDetailRolls(scope.row) ? '自动计算' : '请输入'"
|
|
:class="{'modified-input': isBoxFieldModified(scope.row, 'rolls')}"
|
|
@change="onMergeBoxFieldChange(scope.row, 'rolls')">
|
|
</el-input>
|
|
</template>
|
|
</el-table-column>
|
|
|
|
<!-- 明细信息列(不合并) -->
|
|
<el-table-column label="PO" prop="poNo" min-width="120" align="center">
|
|
<template slot-scope="scope">
|
|
<span>{{ scope.row.poNo || '-' }}</span>
|
|
</template>
|
|
</el-table-column>
|
|
|
|
<el-table-column label="PN" prop="pn" min-width="120" align="center">
|
|
<template slot-scope="scope">
|
|
<span>{{ scope.row.pn || '-' }}</span>
|
|
</template>
|
|
</el-table-column>
|
|
|
|
<el-table-column label="数量" prop="qty" width="100" align="center">
|
|
<template slot-scope="scope">
|
|
<el-input
|
|
v-model="scope.row.qty"
|
|
size="mini"
|
|
type="number"
|
|
:class="{'modified-input': isDetailFieldModified(scope.row, 'qty')}"
|
|
@input="onDetailQtyChange(scope.row)"
|
|
@change="onMergeDetailFieldChange(scope.row, 'qty')">
|
|
</el-input>
|
|
</template>
|
|
</el-table-column>
|
|
|
|
<el-table-column label="Rolls" prop="detailRolls" width="80" align="center">
|
|
<template slot-scope="scope">
|
|
<el-input
|
|
v-model="scope.row.detailRolls"
|
|
size="mini"
|
|
type="number"
|
|
:class="{'modified-input': isDetailFieldModified(scope.row, 'detailRolls')}"
|
|
@input="onDetailRollsInput(scope.row)"
|
|
@change="onMergeDetailFieldChange(scope.row, 'detailRolls')">
|
|
</el-input>
|
|
</template>
|
|
</el-table-column>
|
|
</el-table>
|
|
</div>
|
|
|
|
<div slot="footer" class="dialog-footer">
|
|
<el-button @click="mergeBoxDialogVisible = false">取消</el-button>
|
|
<el-button
|
|
type="primary"
|
|
:loading="mergeBoxSaving"
|
|
:disabled="getUniqueBoxCount() === 0"
|
|
@click="saveMergeBoxEdit">
|
|
保存所有修改 ({{ getUniqueBoxCount() }}箱 / {{ mergeBoxModifiedCount }}处修改)
|
|
</el-button>
|
|
</div>
|
|
</el-dialog>
|
|
|
|
<el-dialog :close-on-click-modal="false" v-drag :visible.sync="palletMaintenanceModelFlag" width="450px">
|
|
<div slot="title" class="dialog-title">
|
|
<span>栈板维护</span>
|
|
<el-tooltip effect="dark" placement="top">
|
|
<div slot="content">
|
|
<div>栈板维护功能说明:</div>
|
|
<div>• 系统会自动加载当前BU下的所有栈板</div>
|
|
<div>• 栈板高度单位为米(M),请输入准确数值</div>
|
|
<div>• 只有托数大于0的栈板记录才会被保存</div>
|
|
</div>
|
|
<i class="el-icon-question" style="color: #17b3a3; margin-left: 8px; cursor: pointer; font-size: 16px;"></i>
|
|
</el-tooltip>
|
|
</div>
|
|
<!-- 栈板记录列表 -->
|
|
<div style="margin: 15px 0;">
|
|
<el-table :data="palletMaintenanceRecords" border style="width: 100%; margin-bottom: 15px;" class="zxClass"
|
|
max-height="200" v-if="palletMaintenanceRecords.length > 0">
|
|
<el-table-column label="栈板类型" min-width="100">
|
|
<template slot-scope="scope">
|
|
<el-input v-model="scope.row.palletType" disabled style="width: 100%;"></el-input>
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column width="120">
|
|
<template slot="header">
|
|
<span>栈板高度(M)</span>
|
|
</template>
|
|
<template slot-scope="scope">
|
|
<el-input v-model="scope.row.height" type="text" placeholder="请输入高度" style="width: 100%;"></el-input>
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column width="100">
|
|
<template slot="header">
|
|
<span>托数</span>
|
|
</template>
|
|
<template slot-scope="scope">
|
|
<el-input v-model="scope.row.palletQty" type="text" placeholder="请输入托数" style="width: 100%;"></el-input>
|
|
</template>
|
|
</el-table-column>
|
|
</el-table>
|
|
<div v-if="palletMaintenanceRecords.length === 0" style="text-align: center; color: #999; padding: 20px; border: 1px dashed #ddd;">
|
|
正在加载栈板记录...
|
|
</div>
|
|
|
|
<!-- 操作提示 -->
|
|
<div v-if="palletMaintenanceRecords.length > 0" style="margin-top: 10px; padding: 8px 12px; background: #f0f9ff; border: 1px solid #b3d8ff; border-radius: 4px; font-size: 12px; color: #409EFF;">
|
|
<i class="el-icon-info" style="margin-right: 4px;"></i>
|
|
<span>提示:托数大于0的记录才会被保存。</span>
|
|
</div>
|
|
</div>
|
|
<el-footer style="height:40px;margin-top: 10px;text-align:center">
|
|
<el-button type="primary" :loading="saveLoading" :disabled="saveLoading" @click="savePalletMaintenance()">确定</el-button>
|
|
<el-button type="primary" @click="palletMaintenanceModelFlag=false">关闭</el-button>
|
|
</el-footer>
|
|
</el-dialog>
|
|
<el-dialog title="物料信息" @close="closePartDialog" @open="openPartDialog" :visible.sync="partFlag" width="559px" v-drag>
|
|
<el-form inline="inline" label-position="top" :model="partData" style="margin-left: 7px;margin-top: -5px;">
|
|
|
|
</el-form>
|
|
<el-table
|
|
:height="height + 110"
|
|
:data="partList"
|
|
stripe
|
|
highlight-current-row
|
|
border
|
|
@row-dblclick="partRowDblclick"
|
|
style="width: 100%;">
|
|
<el-table-column
|
|
prop="pn"
|
|
header-align="center"
|
|
align="center"
|
|
label="物料编码">
|
|
</el-table-column>
|
|
<el-table-column
|
|
prop="part_desc"
|
|
header-align="center"
|
|
align="center"
|
|
label="物料名称">
|
|
</el-table-column>
|
|
</el-table>
|
|
<el-footer style="height:40px;margin-top: 10px;text-align:center">
|
|
<el-button @click="partFlag = false">关闭</el-button>
|
|
</el-footer>
|
|
</el-dialog>
|
|
|
|
<el-dialog title="栈板" @close="closePalletDialog" @open="openPalletDialog" :visible.sync="palletFlag" width="559px" v-drag>
|
|
<el-form inline="inline" label-position="top" :model="palletData" style="margin-left: 7px;margin-top: -5px;">
|
|
<el-form-item label="栈板类型">
|
|
<el-input v-model="palletData.palletType" clearable style="width: 110px"></el-input>
|
|
</el-form-item>
|
|
<el-form-item label=" ">
|
|
<el-button type="primary" style="padding: 3px 12px" @click="searchPalletList()">查询</el-button>
|
|
</el-form-item>
|
|
</el-form>
|
|
<el-table
|
|
:height="height + 110"
|
|
:data="palletList"
|
|
stripe
|
|
highlight-current-row
|
|
border
|
|
@row-dblclick="palletRowDblclick"
|
|
style="width: 100%;">
|
|
<el-table-column
|
|
prop="palletNo"
|
|
header-align="center"
|
|
align="center"
|
|
width="120"
|
|
label="栈板编码">
|
|
</el-table-column>
|
|
<el-table-column
|
|
prop="palletType"
|
|
header-align="center"
|
|
align="center"
|
|
label="栈板类型">
|
|
</el-table-column>
|
|
<el-table-column
|
|
prop="applicationArea"
|
|
header-align="center"
|
|
align="center"
|
|
label="应用环境">
|
|
</el-table-column>
|
|
<el-table-column
|
|
prop="length"
|
|
header-align="center"
|
|
align="center"
|
|
label="长(M)">
|
|
</el-table-column>
|
|
<el-table-column
|
|
prop="width"
|
|
header-align="center"
|
|
align="center"
|
|
label="宽(M)">
|
|
</el-table-column>
|
|
<el-table-column
|
|
prop="height"
|
|
header-align="center"
|
|
align="center"
|
|
label="栈板高(M)">
|
|
</el-table-column>
|
|
</el-table>
|
|
<el-footer style="height:40px;margin-top: 10px;text-align:center">
|
|
<el-button @click="palletFlag = false">关闭</el-button>
|
|
</el-footer>
|
|
</el-dialog>
|
|
<!-- 导入 -->
|
|
<pallet-upload-excel ref="palletUploadExcel" @refreshTable="searchPalletTable" v-drag></pallet-upload-excel>
|
|
<!--列表的组件-->
|
|
<Chooselist ref="baseList" @getBaseData="getBaseData"></Chooselist>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
import Chooselist from '@/views/modules/common/Chooselist_eam'
|
|
import {} from "@/api/sysLanguage.js"
|
|
import palletUploadExcel from "./pallet_upload_excel.vue";
|
|
import PackingDetailTab from "./components/PackingDetailTab.vue";
|
|
import OssComponents from '../oss/ossComponents.vue'
|
|
import {
|
|
searchEcssCoDelNotifyHeaderForCK,
|
|
searchEcssCoDelNotifyDetail,
|
|
confirmEcssDel,
|
|
updateEcssDel,
|
|
cancerConfirmEcssDel,
|
|
searchCoDelPalletDataNew,
|
|
selectBoxList,
|
|
searchEcssCoDelPalletHeaderData,
|
|
searchEcssCoDelPalletDetailData,
|
|
savePalletHeader,
|
|
deletePalletHeader,
|
|
savePalletDetail,
|
|
deletePalletDetail,
|
|
saveOneClickPacking,
|
|
savePalletMaintenance,
|
|
getNotifyPartDetail,
|
|
searchPalletList,
|
|
updateExportFlag,
|
|
updateCodelPalletHeaderPalletQty,
|
|
getPartPackageProperties,
|
|
mergeBox
|
|
}from "@/api/ecss/ecss.js"
|
|
import {getBuList}from '@/api/factory/site.js'
|
|
import excel from "@/utils/excel-util.js";
|
|
import excelOpts from '@/utils/export-options.js'
|
|
import ExportUtil from "@/utils/export";
|
|
import { getTableUserListLanguage} from "@/api/table.js"
|
|
import {getTableDefaultListLanguage} from "../../../api/table";
|
|
export default {
|
|
name: "null",
|
|
components:{
|
|
OssComponents,
|
|
palletUploadExcel,
|
|
Chooselist,
|
|
PackingDetailTab,
|
|
},
|
|
data() {
|
|
return {
|
|
multipleSelection: [],
|
|
palletFlag:false,
|
|
palletList:[],
|
|
palletData:{},
|
|
partFlag:false,
|
|
partData:{},
|
|
partList:[],
|
|
|
|
pageIndex: 1,
|
|
pageSize: 100,
|
|
totalPage: 0,
|
|
// 选中行持久化相关
|
|
selectedRowKey: null, // 当前选中行的唯一标识
|
|
height: 200,
|
|
buList:[],
|
|
dataList:[],
|
|
dataList2:[],
|
|
dataList3:[],
|
|
dataList4:[],
|
|
dataList5:[],
|
|
dataList8:[],
|
|
notifyDetailMap: new Map(),
|
|
boxDetailData:{
|
|
site:'',
|
|
buNo:'',
|
|
delNo:'',
|
|
seqNo:'',
|
|
},
|
|
dataListLoading: false,
|
|
boxDetailModelFlag: false,
|
|
searchData: {
|
|
page: 1,
|
|
limit: 100,
|
|
buNo:'',
|
|
delNo:'',
|
|
cmcInvoice:'',
|
|
notifyStatus:'',
|
|
startDate:'',
|
|
endDate:'',
|
|
exportFlag:'',
|
|
username:this.$store.state.user.name,
|
|
},
|
|
oneClickPackingModelFlag:false,
|
|
oneClickPackingModelData:{
|
|
boxRemnant: false,
|
|
},
|
|
|
|
// 合箱批量编辑相关
|
|
mergeBoxDialogVisible: false,
|
|
mergeBoxLoading: false,
|
|
mergeBoxSaving: false,
|
|
mergeBoxTableData: [], // 扁平化的表格数据
|
|
mergeBoxSelection: [], // 已选择的箱(用于合箱)
|
|
mergeBoxOriginalData: {}, // 原始数据快照(用于对比是否修改)
|
|
mergeBoxModifiedBoxes: {}, // 修改过的Box记录
|
|
mergeBoxMergeHistory: [], // 合并历史记录(用于取消合并)
|
|
mergeBoxModifiedDetails: {}, // 修改过的明细记录
|
|
nextItemNo: 1, // 下一个序号
|
|
|
|
// 栈板维护相关
|
|
palletMaintenanceModelFlag: false,
|
|
saveLoading: false,
|
|
palletMaintenanceRecords: [],
|
|
palletModelFlag:false,
|
|
palletEditFlag:false,
|
|
palletModelData:{
|
|
addFlag:0,
|
|
site:'',
|
|
buNo:'',
|
|
delNo:'',
|
|
seqNo:'',
|
|
palletNo:'',
|
|
palletQty:'',
|
|
length:'',
|
|
width:'',
|
|
height:'',
|
|
boxQty:'',
|
|
grossWeight:'',
|
|
netWeight:'',
|
|
palletRemark:'',
|
|
rolls:'',
|
|
|
|
},
|
|
boxModelFlag:false,
|
|
boxModelData:{
|
|
addFlag:0,
|
|
site:'',
|
|
buNo:'',
|
|
delNo:'',
|
|
seqNo:'',
|
|
itemNo:'',
|
|
partNo:'',
|
|
pn:'',
|
|
qty:'',
|
|
poNo:'',
|
|
boxQty:'',
|
|
rolls:'',
|
|
|
|
},
|
|
buttons:{
|
|
search:'查询',
|
|
},
|
|
confirmModelFlag:false,
|
|
updateModelFlag:false,
|
|
confirmModel:{
|
|
site:'',
|
|
buDesc:'',
|
|
cmcInvoice:'',
|
|
delNo:'',
|
|
readyDate:'',
|
|
shippingMode:'',
|
|
destination:'',
|
|
notifyDate:'',
|
|
remark:'',
|
|
},
|
|
|
|
activeName:'detail',
|
|
columnList1: [
|
|
{
|
|
userId: this.$store.state.user.name,
|
|
functionId: 801002,
|
|
serialNumber: '801002Table1BuDesc',
|
|
tableId: "801002Table1",
|
|
tableName: "关务系统发货通知单",
|
|
columnProp: "buDesc",
|
|
headerAlign: "center",
|
|
align: "left",
|
|
columnLabel: "BU",
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: '',
|
|
columnWidth: 60
|
|
},
|
|
{
|
|
userId: this.$store.state.user.name,
|
|
functionId: 801002,
|
|
serialNumber: '801002Table1CmcInvoice',
|
|
tableId: "801002Table1",
|
|
tableName: "关务系统发货通知单",
|
|
columnProp: "cmcInvoice",
|
|
headerAlign: "center",
|
|
align: "left",
|
|
columnLabel: "CMC Invoice",
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: '',
|
|
columnWidth: 100
|
|
},
|
|
{
|
|
userId: this.$store.state.user.name,
|
|
functionId: 801002,
|
|
serialNumber: '801002Table1DelNo',
|
|
tableId: "801002Table1",
|
|
tableName: "关务系统发货通知单",
|
|
columnProp: "delNo",
|
|
headerAlign: "center",
|
|
align: "center",
|
|
columnLabel: "发货通知单号",
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: '',
|
|
columnWidth: 110
|
|
},
|
|
{
|
|
userId: this.$store.state.user.name,
|
|
functionId: 801002,
|
|
serialNumber: '801002Table1ReadyDate',
|
|
tableId: "801002Table1",
|
|
tableName: "关务系统发货通知单",
|
|
columnProp: "readyDate",
|
|
headerAlign: "center",
|
|
align: "center",
|
|
columnLabel: "ReadyDate",
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: '',
|
|
columnWidth: 100
|
|
},
|
|
{
|
|
userId: this.$store.state.user.name,
|
|
functionId: 801002,
|
|
serialNumber: '801002Table1CustomerName',
|
|
tableId: "801002Table1",
|
|
tableName: "关务系统发货通知单",
|
|
columnProp: "customerName",
|
|
headerAlign: "center",
|
|
align: "left",
|
|
columnLabel: "客户名称",
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: '',
|
|
columnWidth: 220
|
|
},
|
|
{
|
|
userId: this.$store.state.user.name,
|
|
functionId: 801002,
|
|
serialNumber: '801002Table1ShippingMode',
|
|
tableId: "801002Table1",
|
|
tableName: "关务系统发货通知单",
|
|
columnProp: "shippingMode",
|
|
headerAlign: "center",
|
|
align: "left",
|
|
columnLabel: "ShippingMode",
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: '',
|
|
columnWidth: 100
|
|
},
|
|
{
|
|
userId: this.$store.state.user.name,
|
|
functionId: 801002,
|
|
serialNumber: '801002Table1Destination',
|
|
tableId: "801002Table1",
|
|
tableName: "关务系统发货通知单",
|
|
columnProp: "destination",
|
|
headerAlign: "center",
|
|
align: "left",
|
|
columnLabel: "Destination",
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: '',
|
|
columnWidth: 100
|
|
},
|
|
{
|
|
userId: this.$store.state.user.name,
|
|
functionId: 801002,
|
|
serialNumber: '801002Table1NotifyStatus',
|
|
tableId: "801002Table1",
|
|
tableName: "关务系统发货通知单",
|
|
columnProp: "notifyStatus",
|
|
headerAlign: "center",
|
|
align: "left",
|
|
columnLabel: "通知单状态",
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: '',
|
|
columnWidth: 100
|
|
},
|
|
{
|
|
userId: this.$store.state.user.name,
|
|
functionId: 801001,
|
|
serialNumber: '801001Table1NotifyStatus',
|
|
tableId: "801001Table1",
|
|
tableName: "关务系统发货通知单",
|
|
columnProp: "modifyLabel",
|
|
headerAlign: "center",
|
|
align: "left",
|
|
columnLabel: "改单",
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: '',
|
|
columnWidth: 60
|
|
},
|
|
{
|
|
userId: this.$store.state.user.name,
|
|
functionId: 801002,
|
|
serialNumber: '801002Table1ExportFlag',
|
|
tableId: "801002Table1",
|
|
tableName: "关务系统发货通知单",
|
|
columnProp: "exportFlag",
|
|
headerAlign: "center",
|
|
align: "center",
|
|
columnLabel: "是否导出",
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: '',
|
|
columnWidth: 80
|
|
},
|
|
{
|
|
userId: this.$store.state.user.name,
|
|
functionId: 801002,
|
|
serialNumber: '801002Table1NotifyDate',
|
|
tableId: "801002Table1",
|
|
tableName: "关务系统发货通知单",
|
|
columnProp: "notifyDate",
|
|
headerAlign: "center",
|
|
align: "center",
|
|
columnLabel: "发货日期",
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: '',
|
|
columnWidth: 120
|
|
},
|
|
{
|
|
userId: this.$store.state.user.name,
|
|
functionId: 801002,
|
|
serialNumber: '801002Table1ErpDelNo',
|
|
tableId: "801002Table1",
|
|
tableName: "关务系统发货通知单",
|
|
columnProp: "walMartOrderFlag",
|
|
headerAlign: "center",
|
|
align: "left",
|
|
columnLabel: "沃尔玛订单",
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: '',
|
|
columnWidth: 100
|
|
},
|
|
{
|
|
userId: this.$store.state.user.name,
|
|
functionId: 801002,
|
|
serialNumber: '801002Table1CreateBy',
|
|
tableId: "801002Table1",
|
|
tableName: "关务系统发货通知单",
|
|
columnProp: "createBy",
|
|
headerAlign: "center",
|
|
align: "left",
|
|
columnLabel: "创建人",
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: '',
|
|
columnWidth: 80
|
|
},
|
|
{
|
|
userId: this.$store.state.user.name,
|
|
functionId: 801002,
|
|
serialNumber: '801002Table1CreateDate',
|
|
tableId: "801002Table1",
|
|
tableName: "关务系统发货通知单",
|
|
columnProp: "createDate",
|
|
headerAlign: "center",
|
|
align: "center",
|
|
columnLabel: "创建时间",
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: '',
|
|
columnWidth: 130
|
|
},
|
|
{
|
|
userId: this.$store.state.user.name,
|
|
functionId: 801002,
|
|
serialNumber: '801002Table1UpdateBy',
|
|
tableId: "801002Table1",
|
|
tableName: "关务系统发货通知单",
|
|
columnProp: "updateBy",
|
|
headerAlign: "center",
|
|
align: "left",
|
|
columnLabel: "修改人",
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: '',
|
|
columnWidth: 80
|
|
},
|
|
{
|
|
userId: this.$store.state.user.name,
|
|
functionId: 801002,
|
|
serialNumber: '801002Table1UpdateDate',
|
|
tableId: "801002Table1",
|
|
tableName: "关务系统发货通知单",
|
|
columnProp: "updateDate",
|
|
headerAlign: "center",
|
|
align: "center",
|
|
columnLabel: "修改时间",
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: '',
|
|
columnWidth: 130
|
|
},
|
|
{
|
|
userId: this.$store.state.user.name,
|
|
functionId: 801002,
|
|
serialNumber: '801002Table1Remark',
|
|
tableId: "801002Table1",
|
|
tableName: "关务系统发货通知单",
|
|
columnProp: "remark",
|
|
headerAlign: "center",
|
|
align: "left",
|
|
columnLabel: "Remark",
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: '',
|
|
columnWidth: 300
|
|
},
|
|
],
|
|
columnList2: [
|
|
{
|
|
userId: this.$store.state.user.name,
|
|
functionId: 801002,
|
|
serialNumber: '801002Table2ItemNo',
|
|
tableId: "801002Table2",
|
|
tableName: "关务系统发货通知单明细",
|
|
columnProp: "itemNo",
|
|
headerAlign: "center",
|
|
align: "left",
|
|
columnLabel: "行号",
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: '',
|
|
columnWidth: 80
|
|
},
|
|
{
|
|
userId: this.$store.state.user.name,
|
|
functionId: 801002,
|
|
serialNumber: '801002Table2PartNo',
|
|
tableId: "801002Table2",
|
|
tableName: "关务系统发货通知单明细",
|
|
columnProp: "pn",
|
|
headerAlign: "center",
|
|
align: "left",
|
|
columnLabel: "PN",
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: '',
|
|
columnWidth: 100
|
|
},
|
|
{
|
|
userId: this.$store.state.user.name,
|
|
functionId: 801002,
|
|
serialNumber: '801002Table2PartDescription',
|
|
tableId: "801002Table2",
|
|
tableName: "关务系统发货通知单明细",
|
|
columnProp: "partDescription",
|
|
headerAlign: "center",
|
|
align: "left",
|
|
columnLabel: "Description",
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: '',
|
|
columnWidth: 300
|
|
},
|
|
{
|
|
userId: this.$store.state.user.name,
|
|
functionId: 801002,
|
|
serialNumber: '801002Table2Qty',
|
|
tableId: "801002Table2",
|
|
tableName: "关务系统发货通知单明细",
|
|
columnProp: "qty",
|
|
headerAlign: "center",
|
|
align: "right",
|
|
columnLabel: "Qty (pcs)",
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: '',
|
|
columnWidth: 100
|
|
},
|
|
{
|
|
userId: this.$store.state.user.name,
|
|
functionId: 801002,
|
|
serialNumber: '801002Table2SalesOrder',
|
|
tableId: "801002Table2",
|
|
tableName: "关务系统发货通知单明细",
|
|
columnProp: "salesOrder",
|
|
headerAlign: "center",
|
|
align: "left",
|
|
columnLabel: "销售订单号",
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: '',
|
|
columnWidth: 100
|
|
},
|
|
{
|
|
userId: this.$store.state.user.name,
|
|
functionId: 801002,
|
|
serialNumber: '801002Table2CustomerPO',
|
|
tableId: "801002Table2",
|
|
tableName: "关务系统发货通知单明细",
|
|
columnProp: "customerPO",
|
|
headerAlign: "center",
|
|
align: "left",
|
|
columnLabel: "客户采购单号",
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: '',
|
|
columnWidth: 100
|
|
},
|
|
{
|
|
userId: this.$store.state.user.name,
|
|
functionId: 801002,
|
|
serialNumber: '801002Table2Version',
|
|
tableId: "801002Table2",
|
|
tableName: "关务系统发货通知单明细",
|
|
columnProp: "version",
|
|
headerAlign: "center",
|
|
align: "left",
|
|
columnLabel: "Version",
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: '',
|
|
columnWidth: 100
|
|
},
|
|
{
|
|
userId: this.$store.state.user.name,
|
|
functionId: 801002,
|
|
serialNumber: '801002Table2Status',
|
|
tableId: "801002Table2",
|
|
tableName: "关务系统发货通知单明细",
|
|
columnProp: "status",
|
|
headerAlign: "center",
|
|
align: "left",
|
|
columnLabel: "Status",
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: '',
|
|
columnWidth: 100
|
|
},
|
|
{
|
|
userId: this.$store.state.user.name,
|
|
functionId: 801002,
|
|
serialNumber: '801002Table2Family',
|
|
tableId: "801002Table2",
|
|
tableName: "关务系统发货通知单明细",
|
|
columnProp: "family",
|
|
headerAlign: "center",
|
|
align: "left",
|
|
columnLabel: "Family",
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: '',
|
|
columnWidth: 100
|
|
},
|
|
{
|
|
userId: this.$store.state.user.name,
|
|
functionId: 801002,
|
|
serialNumber: '801002Table2Lt',
|
|
tableId: "801002Table2",
|
|
tableName: "关务系统发货通知单明细",
|
|
columnProp: "lt",
|
|
headerAlign: "center",
|
|
align: "right",
|
|
columnLabel: "LT (wks)",
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: '',
|
|
columnWidth: 100
|
|
},
|
|
{
|
|
userId: this.$store.state.user.name,
|
|
functionId: 801002,
|
|
serialNumber: '801002Table2CmcComment',
|
|
tableId: "801002Table2",
|
|
tableName: "关务系统发货通知单明细",
|
|
columnProp: "cmcComment",
|
|
headerAlign: "center",
|
|
align: "left",
|
|
columnLabel: "CMC Comment",
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: '',
|
|
columnWidth: 100
|
|
},
|
|
{
|
|
userId: this.$store.state.user.name,
|
|
functionId: 801002,
|
|
serialNumber: '801002Table2SaleType',
|
|
tableId: "801002Table2",
|
|
tableName: "关务系统发货通知单明细",
|
|
columnProp: "saleType",
|
|
headerAlign: "center",
|
|
align: "left",
|
|
columnLabel: "内外销方式",
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: '',
|
|
columnWidth: 100
|
|
},
|
|
{
|
|
userId: this.$store.state.user.name,
|
|
functionId: 801002,
|
|
serialNumber: '801002Table2AwbBl',
|
|
tableId: "801002Table2",
|
|
tableName: "关务系统发货通知单明细",
|
|
columnProp: "awbBl",
|
|
headerAlign: "center",
|
|
align: "left",
|
|
columnLabel: "AWB/ BL#",
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: '',
|
|
columnWidth: 100
|
|
},
|
|
{
|
|
userId: this.$store.state.user.name,
|
|
functionId: 801002,
|
|
serialNumber: '801002Table2ShippingNumber',
|
|
tableId: "801002Table2",
|
|
tableName: "关务系统发货通知单明细",
|
|
columnProp: "shippingNumber",
|
|
headerAlign: "center",
|
|
align: "left",
|
|
columnLabel: "ShippingNumber",
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: '',
|
|
columnWidth: 100
|
|
},
|
|
{
|
|
userId: this.$store.state.user.name,
|
|
functionId: 801002,
|
|
serialNumber: '801002Table2ForwarderInfo',
|
|
tableId: "801002Table2",
|
|
tableName: "关务系统发货通知单明细",
|
|
columnProp: "forwarderInfo",
|
|
headerAlign: "center",
|
|
align: "left",
|
|
columnLabel: "Forwarder Info",
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: '',
|
|
columnWidth: 100
|
|
},
|
|
{
|
|
userId: this.$store.state.user.name,
|
|
functionId: 801002,
|
|
serialNumber: '801002Table2Currency',
|
|
tableId: "801002Table2",
|
|
tableName: "关务系统发货通知单明细",
|
|
columnProp: "currency",
|
|
headerAlign: "center",
|
|
align: "left",
|
|
columnLabel: "Currency",
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: '',
|
|
columnWidth: 100
|
|
},
|
|
{
|
|
userId: this.$store.state.user.name,
|
|
functionId: 801002,
|
|
serialNumber: '801002Table2Tp',
|
|
tableId: "801002Table2",
|
|
tableName: "关务系统发货通知单明细",
|
|
columnProp: "tp",
|
|
headerAlign: "center",
|
|
align: "right",
|
|
columnLabel: "TP",
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: '',
|
|
columnWidth: 80
|
|
},
|
|
{
|
|
userId: this.$store.state.user.name,
|
|
functionId: 801002,
|
|
serialNumber: '801002Table2TtlAmount',
|
|
tableId: "801002Table2",
|
|
tableName: "关务系统发货通知单明细",
|
|
columnProp: "ttlAmount",
|
|
headerAlign: "center",
|
|
align: "right",
|
|
columnLabel: "TTL Amount",
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: '',
|
|
columnWidth: 80
|
|
},
|
|
{
|
|
userId: this.$store.state.user.name,
|
|
functionId: 801001,
|
|
serialNumber: '801001Table2Remark',
|
|
tableId: "801001Table2",
|
|
tableName: "关务系统发货通知单明细",
|
|
columnProp: "vat",
|
|
headerAlign: "center",
|
|
align: "right",
|
|
columnLabel: "VAT",
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: '',
|
|
columnWidth: 100
|
|
},
|
|
{
|
|
userId: this.$store.state.user.name,
|
|
functionId: 801002,
|
|
serialNumber: '801002Table2SumPrice',
|
|
tableId: "801002Table2",
|
|
tableName: "关务系统发货通知单明细",
|
|
columnProp: "sumPrice",
|
|
headerAlign: "center",
|
|
align: "right",
|
|
columnLabel: "价税合计",
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: '',
|
|
columnWidth: 80
|
|
},
|
|
{
|
|
userId: this.$store.state.user.name,
|
|
functionId: 801002,
|
|
serialNumber: '801002Table2So',
|
|
tableId: "801002Table2",
|
|
tableName: "关务系统发货通知单明细",
|
|
columnProp: "so",
|
|
headerAlign: "center",
|
|
align: "left",
|
|
columnLabel: "SO",
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: '',
|
|
columnWidth: 100
|
|
},
|
|
{
|
|
userId: this.$store.state.user.name,
|
|
functionId: 801002,
|
|
serialNumber: '801002Table2Upc',
|
|
tableId: "801002Table2",
|
|
tableName: "关务系统发货通知单明细",
|
|
columnProp: "upc",
|
|
headerAlign: "center",
|
|
align: "left",
|
|
columnLabel: "UPC",
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: '',
|
|
columnWidth: 100
|
|
},
|
|
{
|
|
userId: this.$store.state.user.name,
|
|
functionId: 801002,
|
|
serialNumber: '801002Table2Remark',
|
|
tableId: "801002Table2",
|
|
tableName: "关务系统发货通知单明细",
|
|
columnProp: "remark",
|
|
headerAlign: "center",
|
|
align: "left",
|
|
columnLabel: "Remark",
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: '',
|
|
columnWidth: 300
|
|
},
|
|
{
|
|
userId: this.$store.state.user.name,
|
|
functionId: 801001,
|
|
serialNumber: '801001Table2Remark',
|
|
tableId: "801001Table2",
|
|
tableName: "关务系统发货通知单明细",
|
|
columnProp: "roll",
|
|
headerAlign: "center",
|
|
align: "right",
|
|
columnLabel: "Roll",
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: '',
|
|
columnWidth: 100
|
|
},
|
|
{
|
|
userId: this.$store.state.user.name,
|
|
functionId: 801001,
|
|
serialNumber: '801001Table2Remark',
|
|
tableId: "801001Table2",
|
|
tableName: "关务系统发货通知单明细",
|
|
columnProp: "carton",
|
|
headerAlign: "center",
|
|
align: "right",
|
|
columnLabel: "Carton",
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: '',
|
|
columnWidth: 100
|
|
},
|
|
{
|
|
userId: this.$store.state.user.name,
|
|
functionId: 801001,
|
|
serialNumber: '801001Table2Remark',
|
|
tableId: "801001Table2",
|
|
tableName: "关务系统发货通知单明细",
|
|
columnProp: "qtyRoll",
|
|
headerAlign: "center",
|
|
align: "right",
|
|
columnLabel: "qty/roll",
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: '',
|
|
columnWidth: 100
|
|
},
|
|
{
|
|
userId: this.$store.state.user.name,
|
|
functionId: 801001,
|
|
serialNumber: '801001Table2Remark',
|
|
tableId: "801001Table2",
|
|
tableName: "关务系统发货通知单明细",
|
|
columnProp: "qtyBox",
|
|
headerAlign: "center",
|
|
align: "right",
|
|
columnLabel: "qty/box",
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: '',
|
|
columnWidth: 100
|
|
},
|
|
],
|
|
columnList3:[
|
|
{
|
|
userId: this.$store.state.user.name,
|
|
functionId: 801002,
|
|
serialNumber: '801002Table3ItemNo',
|
|
tableId: "801002Table3",
|
|
tableName: "装箱明细",
|
|
columnProp: "itemNo",
|
|
headerAlign: "center",
|
|
align: "right",
|
|
columnLabel: "序号",
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: '',
|
|
columnWidth: 40
|
|
},
|
|
{
|
|
userId: this.$store.state.user.name,
|
|
functionId: 801002,
|
|
serialNumber: '801002Table3PoNo',
|
|
tableId: "801002Table3",
|
|
tableName: "装箱明细",
|
|
columnProp: "poNo",
|
|
headerAlign: "center",
|
|
align: "left",
|
|
columnLabel: "PO",
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: '',
|
|
columnWidth: 100
|
|
},
|
|
{
|
|
userId: this.$store.state.user.name,
|
|
functionId: 801002,
|
|
serialNumber: '801002Table3PN',
|
|
tableId: "801002Table3",
|
|
tableName: "装箱明细",
|
|
columnProp: "pn",
|
|
headerAlign: "center",
|
|
align: "left",
|
|
columnLabel: "PN",
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: '',
|
|
columnWidth: 100
|
|
},
|
|
{
|
|
userId: this.$store.state.user.name,
|
|
functionId: 801002,
|
|
serialNumber: '801002Table3Qty',
|
|
tableId: "801002Table3",
|
|
tableName: "装箱明细",
|
|
columnProp: "qty",
|
|
headerAlign: "center",
|
|
align: "right",
|
|
columnLabel: "数量",
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: '',
|
|
columnWidth: 50
|
|
},
|
|
{
|
|
userId: this.$store.state.user.name,
|
|
functionId: 801002,
|
|
serialNumber: '801002Table3Rolls',
|
|
tableId: "801002Table3",
|
|
tableName: "装箱明细",
|
|
columnProp: "rolls",
|
|
headerAlign: "center",
|
|
align: "right",
|
|
columnLabel: "Rolls",
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: '',
|
|
columnWidth: 50
|
|
},
|
|
],
|
|
|
|
columnList4:[
|
|
{
|
|
userId: this.$store.state.user.name,
|
|
functionId: 801002,
|
|
serialNumber: '801002Table4SeqNo',
|
|
tableId: "801002Table4",
|
|
tableName: "装箱栈板主表",
|
|
columnProp: "seqNo",
|
|
headerAlign: "center",
|
|
align: "right",
|
|
columnLabel: "序号",
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: '',
|
|
columnWidth: 40
|
|
},
|
|
{
|
|
userId: this.$store.state.user.name,
|
|
functionId: 801002,
|
|
serialNumber: '801002Table4PalletRemark',
|
|
tableId: "801002Table4",
|
|
tableName: "装箱栈板主表",
|
|
columnProp: "palletRemark",
|
|
headerAlign: "center",
|
|
align: "left",
|
|
columnLabel: "栈板码",
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: '',
|
|
columnWidth: 60
|
|
},
|
|
{
|
|
userId: this.$store.state.user.name,
|
|
functionId: 801002,
|
|
serialNumber: '801002Table4PalletQty',
|
|
tableId: "801002Table4",
|
|
tableName: "装箱栈板主表",
|
|
columnProp: "palletQty",
|
|
headerAlign: "center",
|
|
align: "right",
|
|
columnLabel: "数量",
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: '',
|
|
columnWidth: 50
|
|
},
|
|
{
|
|
userId: this.$store.state.user.name,
|
|
functionId: 801002,
|
|
serialNumber: '801002Table4PalletQty',
|
|
tableId: "801002Table4",
|
|
tableName: "装箱栈板主表",
|
|
columnProp: "weight",
|
|
headerAlign: "center",
|
|
align: "right",
|
|
columnLabel: "重量(KG)",
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: '',
|
|
columnWidth: 50
|
|
},
|
|
{
|
|
userId: this.$store.state.user.name,
|
|
functionId: 801002,
|
|
serialNumber: '801002Table4Length',
|
|
tableId: "801002Table4",
|
|
tableName: "装箱栈板主表",
|
|
columnProp: "length",
|
|
headerAlign: "center",
|
|
align: "right",
|
|
columnLabel: "长(M)",
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: '',
|
|
columnWidth: 50
|
|
},
|
|
{
|
|
userId: this.$store.state.user.name,
|
|
functionId: 801002,
|
|
serialNumber: '801002Table4Width',
|
|
tableId: "801002Table4",
|
|
tableName: "装箱栈板主表",
|
|
columnProp: "width",
|
|
headerAlign: "center",
|
|
align: "right",
|
|
columnLabel: "宽(M)",
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: '',
|
|
columnWidth: 50
|
|
},
|
|
{
|
|
userId: this.$store.state.user.name,
|
|
functionId: 801002,
|
|
serialNumber: '801002Table4Height',
|
|
tableId: "801002Table4",
|
|
tableName: "装箱栈板主表",
|
|
columnProp: "height",
|
|
headerAlign: "center",
|
|
align: "right",
|
|
columnLabel: "高(M)",
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: '',
|
|
columnWidth: 50
|
|
},
|
|
],
|
|
columnList5:[
|
|
{
|
|
userId: this.$store.state.user.name,
|
|
functionId: 801002,
|
|
serialNumber: '801002Table5PartNo',
|
|
tableId: "801002Table5",
|
|
tableName: "栈板装箱明细",
|
|
columnProp: "pn",
|
|
headerAlign: "center",
|
|
align: "left",
|
|
columnLabel: "物料编码",
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: '',
|
|
columnWidth: 70
|
|
},
|
|
{
|
|
userId: this.$store.state.user.name,
|
|
functionId: 801002,
|
|
serialNumber: '801002Table5Qty',
|
|
tableId: "801002Table5",
|
|
tableName: "栈板装箱明细",
|
|
columnProp: "qty",
|
|
headerAlign: "center",
|
|
align: "right",
|
|
columnLabel: "数量",
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: '',
|
|
columnWidth: 80
|
|
},
|
|
{
|
|
userId: this.$store.state.user.name,
|
|
functionId: 801002,
|
|
serialNumber: '801002Table5BoxQty',
|
|
tableId: "801002Table5",
|
|
tableName: "栈板装箱明细",
|
|
columnProp: "boxQty",
|
|
headerAlign: "center",
|
|
align: "right",
|
|
columnLabel: "箱数",
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: '',
|
|
columnWidth: 70
|
|
},
|
|
{
|
|
userId: this.$store.state.user.name,
|
|
functionId: 801002,
|
|
serialNumber: '801002Table5Rolls',
|
|
tableId: "801002Table5",
|
|
tableName: "栈板装箱明细",
|
|
columnProp: "rolls",
|
|
headerAlign: "center",
|
|
align: "right",
|
|
columnLabel: "Rolls",
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: '',
|
|
columnWidth: 70
|
|
},
|
|
],
|
|
|
|
ossColumns:[
|
|
{
|
|
userId: this.$store.state.user.name,
|
|
functionId: 103001,
|
|
serialNumber: '103001Table2FileName',
|
|
tableId: '103001Table2',
|
|
tableName: '文件信息表',
|
|
columnProp: 'fileName',
|
|
headerAlign: 'center',
|
|
align: 'center',
|
|
columnLabel: '文件名称',
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: '',
|
|
columnWidth: 140
|
|
},
|
|
{
|
|
userId: this.$store.state.user.name,
|
|
functionId: 103001,
|
|
serialNumber: '103001Table2FileRemark',
|
|
tableId: '103001Table2',
|
|
tableName: '文件信息表',
|
|
columnProp: 'fileRemark',
|
|
headerAlign: 'center',
|
|
align: 'center',
|
|
columnLabel: '备注',
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: '',
|
|
columnWidth: 240
|
|
},
|
|
{
|
|
userId: this.$store.state.user.name,
|
|
functionId: 103001,
|
|
serialNumber: '103001Table2CreateDate',
|
|
tableId: '103001Table2',
|
|
tableName: '文件信息表',
|
|
columnProp: 'createDate',
|
|
headerAlign: 'center',
|
|
align: 'center',
|
|
columnLabel: '上传时间',
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: '',
|
|
columnWidth: 140
|
|
},
|
|
{
|
|
userId: this.$store.state.user.name,
|
|
functionId: 103001,
|
|
serialNumber: '103001Table2CreatedBy',
|
|
tableId: '103001Table2',
|
|
tableName: '文件信息表',
|
|
columnProp: 'createdBy',
|
|
headerAlign: 'center',
|
|
align: 'center',
|
|
columnLabel: '上传人',
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: '',
|
|
columnWidth: 140
|
|
}
|
|
],
|
|
currentRow:{},
|
|
}
|
|
},
|
|
mounted() {
|
|
this.$nextTick(() => {
|
|
this.height = (window.innerHeight - 260)/2;
|
|
})
|
|
},
|
|
|
|
computed: {
|
|
/**
|
|
* 判断是否禁用总Rolls输入框
|
|
* 逻辑:只有当所有明细的rolls都是空或0时,才允许修改总rolls
|
|
* @returns {boolean} true=禁用,false=启用
|
|
*/
|
|
isTotalRollsDisabled() {
|
|
// 检查是否有任何明细的 rolls 不为空且大于 0
|
|
const hasValidRolls = this.dataList8.some(item => {
|
|
const rollsValue = parseFloat(item.rolls);
|
|
return !isNaN(rollsValue) && rollsValue > 0;
|
|
});
|
|
// 如果有任何明细有有效的rolls值,则禁用总rolls输入框
|
|
return hasValidRolls;
|
|
},
|
|
|
|
/**
|
|
* 合箱批量编辑修改数量
|
|
*/
|
|
mergeBoxModifiedCount() {
|
|
return Object.keys(this.mergeBoxModifiedBoxes).length +
|
|
Object.keys(this.mergeBoxModifiedDetails).length;
|
|
}
|
|
},
|
|
|
|
methods: {
|
|
// 动态列开始 获取 用户保存的 格式列
|
|
async getTableUserColumn (tableId, columnId) {
|
|
let queryTableUser = {
|
|
userId: this.$store.state.user.name,
|
|
functionId: this.$route.meta.menuId,
|
|
tableId: tableId,
|
|
status: true,
|
|
languageCode: this.$i18n.locale
|
|
}
|
|
await getTableUserListLanguage(queryTableUser).then(({data}) => {
|
|
if (data.rows.length > 0) {
|
|
//this.columnList1 = []
|
|
switch (columnId) {
|
|
case 1:
|
|
this.columnList1 = data.rows
|
|
break;
|
|
// case 2:
|
|
// this.columnDetailList = data.rows
|
|
// break;
|
|
// case 3:
|
|
// this.columnList2 = data.rows
|
|
// break;
|
|
// case 4:
|
|
// this.columnList3 = data.rows
|
|
// break;
|
|
}
|
|
} else {
|
|
this.getColumnList(tableId, columnId)
|
|
}
|
|
})
|
|
},
|
|
// 获取 tableDefault 列
|
|
async getColumnList (tableId, columnId) {
|
|
let queryTable = {
|
|
functionId: this.$route.meta.menuId,
|
|
tableId: tableId,
|
|
languageCode: this.$i18n.locale
|
|
}
|
|
await getTableDefaultListLanguage(queryTable).then(({data}) => {
|
|
if (!data.rows.length == 0) {
|
|
switch (columnId) {
|
|
case 1:
|
|
this.columnList1 = data.rows
|
|
break;
|
|
// case 2:
|
|
// this.columnDetailList = data.rows
|
|
// break;
|
|
// case 3:
|
|
// this.columnList2 = data.rows
|
|
// break;
|
|
// case 4:
|
|
// this.columnList3 = data.rows
|
|
// break;
|
|
}
|
|
} else {
|
|
// this.showDefault = true.
|
|
}
|
|
})
|
|
},
|
|
isPnDataIncomplete(row) {
|
|
const hasBoxrolls = row.boxrolls !== null && row.boxrolls !== undefined && row.boxrolls !== '';
|
|
const hasRollqty = row.rollqty !== null && row.rollqty !== undefined && row.rollqty !== '';
|
|
const hasBoxweight = row.boxweight !== null && row.boxweight !== undefined && row.boxweight !== '';
|
|
const packageNo = row.packageNo !== null && row.packageNo !== undefined && row.packageNo !== '';
|
|
return !hasBoxrolls || !hasRollqty || !hasBoxweight || !packageNo;
|
|
},
|
|
|
|
// 获取PN数据缺失的具体字段提示信息
|
|
getPnIncompleteTooltip(row) {
|
|
const missingFields = [];
|
|
|
|
// 检查每个字段是否缺失
|
|
if (!(row.rollqty !== null && row.rollqty !== undefined && row.rollqty !== '')) {
|
|
missingFields.push('每卷数量');
|
|
}
|
|
if (!(row.boxrolls !== null && row.boxrolls !== undefined && row.boxrolls !== '')) {
|
|
missingFields.push('每箱卷数');
|
|
}
|
|
if (!(row.boxweight !== null && row.boxweight !== undefined && row.boxweight !== '')) {
|
|
missingFields.push('箱重量');
|
|
}
|
|
if (!(row.packageNo !== null && row.packageNo !== undefined && row.packageNo !== '')) {
|
|
missingFields.push('箱类型');
|
|
}
|
|
|
|
// 根据缺失字段生成提示信息
|
|
if (missingFields.length > 0) {
|
|
return `基本信息(${missingFields.join('、')})未维护,点击跳转到维护页面`;
|
|
}
|
|
return '';
|
|
},
|
|
|
|
// 跳转到PN维护页面
|
|
navigateToPartHsCode(pn) {
|
|
if (!pn) {
|
|
this.$message.warning('PN不能为空');
|
|
return;
|
|
}
|
|
this.$router.push({
|
|
path: '/ecss-partHsCode',
|
|
query: {
|
|
sku: pn
|
|
}
|
|
});
|
|
},
|
|
|
|
openPartDialog () {
|
|
this.searchPartList();
|
|
this.partFlag = true
|
|
},
|
|
closePartDialog () {
|
|
this.partList = []
|
|
this.partFlag = false
|
|
},
|
|
searchPartList () {
|
|
this.partData.site = this.currentRow.site
|
|
this.partData.delNo = this.currentRow.delNo
|
|
getNotifyPartDetail(this.partData).then(({data}) => {
|
|
if (data && data.code === 0){
|
|
this.partList = data.rows;
|
|
}
|
|
})
|
|
},
|
|
partRowDblclick (row) {
|
|
this.boxModelData.partNo = row.partNo
|
|
this.boxModelData.pn = row.pn
|
|
this.partFlag = false
|
|
},
|
|
// 获取基础数据列表S
|
|
getBaseList(val, type) {
|
|
this.tagNo = val
|
|
this.$nextTick(() => {
|
|
let strVal = ''
|
|
if (val === 507) {
|
|
strVal = this.boxModelData.partNo
|
|
}
|
|
this.$refs.baseList.init(val, strVal)
|
|
})
|
|
},
|
|
|
|
/* 列表方法的回调 */
|
|
getBaseData(val) {
|
|
if (this.tagNo === 507) {
|
|
this.boxModelData.partNo = val.part_no
|
|
}
|
|
},
|
|
// 每页数
|
|
sizeChangeHandle (val) {
|
|
this.pageSize = val
|
|
this.pageIndex = 1
|
|
this.searchTable()
|
|
},
|
|
// 当前页
|
|
currentChangeHandle (val) {
|
|
this.pageIndex = val
|
|
this.searchTable()
|
|
},
|
|
searchTable(){
|
|
this.searchData.limit = this.pageSize
|
|
this.searchData.page = this.pageIndex
|
|
searchEcssCoDelNotifyHeaderForCK(this.searchData).then(({data}) => {
|
|
//区分请求成功和失败的状况
|
|
if (data && data.code == 0) {
|
|
this.dataList = data.page.list
|
|
this.pageIndex = data.page.currPage
|
|
this.pageSize = data.page.pageSize
|
|
this.totalPage = data.page.totalCount
|
|
if(this.dataList.length>0){
|
|
this.dataList.forEach(o => {
|
|
if (o.notifyStatus==='仓库已确认'&&!o.notifyDate) {
|
|
o.notifyDate='发货日期不确定'
|
|
}
|
|
// 显示改单次数,如:改单(1)、改单(2)
|
|
o.modifyLabel = !!o.modifyFlag ? (o.modifyCount ? '改单(' + o.modifyCount + ')' : '改单(1)') : '';
|
|
});
|
|
|
|
// 使用 $nextTick 确保 DOM 渲染完成后再设置选中行
|
|
this.$nextTick(() => {
|
|
try {
|
|
// 检查表格引用是否存在
|
|
if (!this.$refs.mainTable) {
|
|
console.warn('[确认页面行选择持久化] 表格引用不存在,跳过设置选中行');
|
|
return;
|
|
}
|
|
|
|
// 尝试恢复之前选中的行
|
|
const restoredRow = this.restoreSelectedRow();
|
|
if (restoredRow) {
|
|
this.$refs.mainTable.setCurrentRow(restoredRow);
|
|
this.changeData(restoredRow);
|
|
} else {
|
|
// 如果没有之前选中的行,默认选中第一行
|
|
this.$refs.mainTable.setCurrentRow(this.dataList[0]);
|
|
this.changeData(this.dataList[0]);
|
|
}
|
|
} catch (error) {
|
|
console.error('[确认页面行选择持久化] 设置选中行失败:', error);
|
|
// 降级处理:只调用 changeData,不设置表格选中状态
|
|
const restoredRow = this.restoreSelectedRow();
|
|
this.changeData(restoredRow || this.dataList[0]);
|
|
}
|
|
});
|
|
}else {
|
|
this.changeData(null)
|
|
}
|
|
} else {
|
|
this.dataList = [];
|
|
}
|
|
});
|
|
},
|
|
tableRowClassName({row}) {
|
|
if (row.notifyStatus==='订单取消') {
|
|
return 'warning-row';
|
|
}
|
|
},
|
|
cellStyle({row, column }) {
|
|
if (column.property === 'notifyDate' && row.notifyDate==='发货日期不确定') { // 根据列属性判断
|
|
return { color: '#ff5d03' };
|
|
}
|
|
// 改单列显示橙色:只要modifyFlag为true就显示橙色
|
|
if (column.property === 'modifyLabel' && row.modifyFlag===true) {
|
|
return { color: '#ff5d03' };
|
|
}
|
|
return {};
|
|
},
|
|
cellStyleDetail({row, column }) {
|
|
// 只有数量列且 modifyQtyFlag=true 时才变色
|
|
if (column.property === 'qty' && row.modifyQtyFlag===true) {
|
|
return { color: '#ff5d03' };
|
|
}
|
|
|
|
// PN列保持原有的 modifyFlag 判断
|
|
if (column.property === 'pn' && row.modifyFlag===true) {
|
|
return { color: '#ff5d03' };
|
|
}
|
|
|
|
// 检查 pn 列,当 boxrolls、rollqty、boxweight 其中任意一个没有值时,将 pn 颜色改成橙色
|
|
if (column.property === 'pn') {
|
|
const hasBoxrolls = row.boxrolls !== null && row.boxrolls !== undefined && row.boxrolls !== '';
|
|
const hasRollqty = row.rollqty !== null && row.rollqty !== undefined && row.rollqty !== '';
|
|
const hasBoxweight = row.boxweight !== null && row.boxweight !== undefined && row.boxweight !== '';
|
|
const packageNo = row.packageNo !== null && row.packageNo !== undefined && row.packageNo !== '';
|
|
if (!hasBoxrolls || !hasRollqty || !hasBoxweight || !packageNo) {
|
|
return { color: '#ff8c00' }; // 橙色
|
|
}
|
|
}
|
|
|
|
return {};
|
|
},
|
|
changeData(row){
|
|
this.currentRow = JSON.parse(JSON.stringify(row));
|
|
if (this.currentRow&&this.currentRow.notifyDate==='发货日期不确定') {
|
|
this.currentRow.notifyDate=''
|
|
}
|
|
this.headerData=row;
|
|
|
|
// 保存选中行的唯一标识到本地存储
|
|
if (row && row.delNo) {
|
|
this.selectedRowKey = row.delNo;
|
|
this.saveSelectedRowToStorage();
|
|
}
|
|
|
|
this.refreshCurrentTabTable ();
|
|
},
|
|
refreshCurrentTabTable(){
|
|
if(this.currentRow===''||this.currentRow===null){
|
|
this.currentRow={site:'',delNo:'',notifyStatus:''}
|
|
}
|
|
if(this.activeName==='detail'){
|
|
searchEcssCoDelNotifyDetail(this.currentRow).then(({data}) => {
|
|
//区分请求成功和失败的状况
|
|
if (data && data.code == 0) {
|
|
this.dataList2 = data.rows
|
|
} else {
|
|
this.dataList2 = [];
|
|
}
|
|
});
|
|
}
|
|
if(this.activeName==='pallet'){
|
|
// 刷新装箱明细组件
|
|
if (this.$refs.packingDetailTab) {
|
|
this.$refs.packingDetailTab.refresh();
|
|
}
|
|
}
|
|
if(this.activeName==='box'){
|
|
searchEcssCoDelPalletHeaderData(this.currentRow).then(({data}) => {
|
|
//区分请求成功和失败的状况
|
|
if (data && data.code == 0) {
|
|
this.dataList4 = data.rows
|
|
|
|
} else {
|
|
this.dataList4 = [];
|
|
}
|
|
});
|
|
}
|
|
},
|
|
tabClick (tab, event) {
|
|
// 刷新列表数据
|
|
this.refreshCurrentTabTable()
|
|
},
|
|
|
|
confirmDo(){
|
|
confirmEcssDel(this.confirmModel).then(({data}) => {
|
|
if (data && data.code === 0) {
|
|
// 保存当前选中行的标识,以便刷新后恢复
|
|
const currentSelectedKey = this.confirmModel ? this.confirmModel.delNo : null;
|
|
if (currentSelectedKey) {
|
|
this.selectedRowKey = currentSelectedKey;
|
|
this.saveSelectedRowToStorage();
|
|
}
|
|
this.searchTable()
|
|
this.confirmModelFlag=false
|
|
this.$message({
|
|
message: '操作成功',
|
|
type: 'success',
|
|
duration: 1500,
|
|
onClose: () => {}
|
|
})
|
|
} else {
|
|
this.$alert(data.msg, '错误', {
|
|
confirmButtonText: '确定'
|
|
})
|
|
}
|
|
})
|
|
},
|
|
cancerConfirm(row){
|
|
let indata=JSON.parse(JSON.stringify(row));
|
|
if (row.notifyDate==='发货日期不确定') {
|
|
indata.notifyDate=''
|
|
}
|
|
this.$confirm('取消确认这条发货通知单?', '提示').then(() => {
|
|
cancerConfirmEcssDel(indata).then(({data}) => {
|
|
if (data && data.code === 0) {
|
|
// 保存当前选中行的标识,以便刷新后恢复
|
|
const currentSelectedKey = row ? row.delNo : null;
|
|
if (currentSelectedKey) {
|
|
this.selectedRowKey = currentSelectedKey;
|
|
this.saveSelectedRowToStorage();
|
|
}
|
|
this.searchTable()
|
|
this.$message({
|
|
message: '操作成功',
|
|
type: 'success',
|
|
duration: 1500,
|
|
onClose: () => {}
|
|
})
|
|
} else {
|
|
this.$alert(data.msg, '错误', {
|
|
confirmButtonText: '确定'
|
|
})
|
|
}
|
|
})
|
|
})
|
|
},
|
|
getBu () {
|
|
let tempData = {
|
|
username: this.$store.state.user.name,
|
|
}
|
|
getBuList(tempData).then(({data}) => {
|
|
if (data.code === 0) {
|
|
this.buList = data.row2
|
|
if (this.buList.length===1) {
|
|
this.searchData.buNo = this.buList[0].buNo;
|
|
}
|
|
}
|
|
})
|
|
},
|
|
confirmModelOpen(row){
|
|
this.confirmModel=JSON.parse(JSON.stringify(row));
|
|
this.confirmModelFlag=true
|
|
},
|
|
updateModelOpen(row){
|
|
this.confirmModel=JSON.parse(JSON.stringify(row));
|
|
if (this.confirmModel.notifyDate==='发货日期不确定') {
|
|
this.confirmModel.notifyDate=''
|
|
}
|
|
this.updateModelFlag=true
|
|
},
|
|
updateDo(){
|
|
if (!this.confirmModel.readyDate) {
|
|
this.$alert('请选择ReadyDate!', '错误', {
|
|
confirmButtonText: '确定'
|
|
})
|
|
return false
|
|
}
|
|
// 添加更新人信息
|
|
this.confirmModel.updateBy = this.$store.state.user.name
|
|
updateEcssDel(this.confirmModel).then(({data}) => {
|
|
if (data && data.code === 0) {
|
|
// 保存当前选中行的标识,以便刷新后恢复
|
|
const currentSelectedKey = this.confirmModel ? this.confirmModel.delNo : null;
|
|
if (currentSelectedKey) {
|
|
this.selectedRowKey = currentSelectedKey;
|
|
this.saveSelectedRowToStorage();
|
|
}
|
|
this.searchTable()
|
|
this.updateModelFlag=false
|
|
this.$message({
|
|
message: '操作成功',
|
|
type: 'success',
|
|
duration: 1500,
|
|
onClose: () => {}
|
|
})
|
|
} else {
|
|
this.$alert(data.msg, '错误', {
|
|
confirmButtonText: '确定'
|
|
})
|
|
}
|
|
})
|
|
},
|
|
upLoadPallet(){
|
|
if(this.currentRow.site===''||this.currentRow.site==null){
|
|
this.$alert('请先选择发货通知单!', '错误', {
|
|
confirmButtonText: '确定'
|
|
})
|
|
return false
|
|
}
|
|
let inData={
|
|
site:this.currentRow.site,
|
|
buNo:this.currentRow.buNo,
|
|
delNo:this.currentRow.delNo,
|
|
cmcInvoice:this.currentRow.cmcInvoice,
|
|
shippingMode: this.currentRow.shippingMode,
|
|
destination : this.currentRow.destination,
|
|
walMartOrderFlag:this.currentRow.walMartOrderFlag
|
|
}
|
|
this.$nextTick(() => {
|
|
this.$refs.palletUploadExcel.init(inData)
|
|
})
|
|
},
|
|
async exportExcel() {
|
|
if(this.currentRow.site===''||this.currentRow.site==null){
|
|
this.$alert('请先选择发货通知单!', '错误', {
|
|
confirmButtonText: '确定'
|
|
})
|
|
return false
|
|
}
|
|
|
|
let exportParam = {
|
|
site: this.currentRow.site,
|
|
buNo: this.currentRow.buNo,
|
|
delNo: this.currentRow.delNo,
|
|
cmcInvoice: this.currentRow.cmcInvoice,
|
|
shippingMode: this.currentRow.shippingMode,
|
|
destination : this.currentRow.destination,
|
|
readyDate: this.currentRow.readyDate, // 增加ReadyDate列
|
|
remark: this.currentRow.remark, // 增加备注列
|
|
createBy: this.$store.state.user.name,
|
|
}
|
|
|
|
try {
|
|
// 使用后台Excel模版导出
|
|
ExportUtil.export(
|
|
"/ecss/coDel/exportPackingTemplate",
|
|
exportParam,
|
|
this.currentRow.cmcInvoice + "装箱数据.xlsx"
|
|
);
|
|
|
|
// 导出成功后更新export_flag字段
|
|
let updateData = {
|
|
site: this.currentRow.site,
|
|
buNo: this.currentRow.buNo,
|
|
delNo: this.currentRow.delNo,
|
|
exportFlag: 'Y',
|
|
updateBy: this.$store.state.user.name
|
|
}
|
|
|
|
updateExportFlag(updateData).then(({data}) => {
|
|
if (data.code === 0) {
|
|
// 刷新当前行的导出状态
|
|
this.currentRow.exportFlag = 'Y';
|
|
// 刷新表格数据
|
|
this.searchTable();
|
|
this.$message({
|
|
message: '导出成功',
|
|
type: 'success',
|
|
duration: 1500
|
|
});
|
|
} else {
|
|
this.$message.warning('导出成功,但更新导出状态失败:' + data.msg);
|
|
}
|
|
}).catch(error => {
|
|
this.$message.warning('导出成功,但更新导出状态失败');
|
|
console.error('更新导出状态失败:', error);
|
|
});
|
|
|
|
} catch (error) {
|
|
this.$message.error('导出失败');
|
|
console.error('导出失败:', error);
|
|
}
|
|
},
|
|
searchPalletTable(){
|
|
this.refreshCurrentTabTable();
|
|
},
|
|
boxDetailModel(row){
|
|
this.boxDetailData=row
|
|
searchEcssCoDelPalletDetailData(row).then(({data}) => {
|
|
if (data.code === 0) {
|
|
this.dataList5 = data.rows
|
|
}
|
|
})
|
|
this.boxDetailModelFlag=true
|
|
},
|
|
updatePalletModel(row){
|
|
this.palletModelData=JSON.parse(JSON.stringify(row))
|
|
this.palletModelData.palletRemark=row.palletRemark
|
|
this.palletModelData.addFlag=1
|
|
this.palletEditFlag=true
|
|
},
|
|
newPalletModel(){
|
|
if(this.currentRow.site===''||this.currentRow.site==null){
|
|
this.$alert('请先选择发货通知单!', '错误', {
|
|
confirmButtonText: '确定'
|
|
})
|
|
return false
|
|
}
|
|
this.palletModelData={
|
|
addFlag:0,
|
|
site:this.currentRow.site,
|
|
buNo:this.currentRow.buNo,
|
|
delNo:this.currentRow.delNo,
|
|
grossWeight:'',
|
|
netWeight:'',
|
|
boxQty:'',
|
|
}
|
|
searchEcssCoDelNotifyDetail(this.currentRow).then(({data}) => {
|
|
if (data && data.code == 0) {
|
|
this.dataList8 = data.rows
|
|
} else {
|
|
this.dataList8 = [];
|
|
}
|
|
});
|
|
this.palletModelFlag=true
|
|
},
|
|
fillUseQty(row) {
|
|
row.useQty = row.surplusQty || 0;
|
|
// 全数装箱后也需要计算rolls
|
|
this.calculateRolls(row);
|
|
},
|
|
/**
|
|
* 根据装箱数量自动计算Rolls(卷数)
|
|
* 计算公式:Rolls = 装箱数量 / 每卷数量
|
|
* @param row 当前行数据
|
|
*/
|
|
calculateRolls(row) {
|
|
// 如果装箱数量为空或为0,清空rolls
|
|
if (!row.useQty || row.useQty <= 0) {
|
|
this.$set(row, 'rolls', null);
|
|
// 装箱数量变化后,重新计算总箱数和重量
|
|
this.calculateTotalBoxQtyAndWeights();
|
|
return;
|
|
}
|
|
|
|
// 如果已经有缓存的每卷数量,直接计算
|
|
if (row.rollQtyCache && row.rollQtyCache > 0) {
|
|
const rolls = row.useQty / row.rollQtyCache;
|
|
this.$set(row, 'rolls', parseFloat(rolls.toFixed(4)));
|
|
// 装箱数量变化后,重新计算总箱数和重量
|
|
this.calculateTotalBoxQtyAndWeights();
|
|
return;
|
|
}
|
|
|
|
// 调用后端API获取每卷数量
|
|
const params = {
|
|
site: this.currentRow.site,
|
|
buNo: this.currentRow.buNo,
|
|
partNo: row.partNo
|
|
};
|
|
|
|
getPartPackageProperties(params).then(({data}) => {
|
|
if (data && data.code === 0 && data.data) {
|
|
const rollQty = data.data.rollQty;
|
|
|
|
if (rollQty && rollQty > 0) {
|
|
// 缓存每卷数量到row中,避免重复请求
|
|
this.$set(row, 'rollQtyCache', rollQty);
|
|
this.$set(row, 'boxRollsCache', data.data.boxRolls);
|
|
this.$set(row, 'boxWeightCache', data.data.boxWeight);
|
|
|
|
// 计算rolls:装箱数量 / 每卷数量
|
|
const rolls = row.useQty / rollQty;
|
|
this.$set(row, 'rolls', parseFloat(rolls.toFixed(4)));
|
|
|
|
// 装箱数量变化后,重新计算总箱数和重量
|
|
this.calculateTotalBoxQtyAndWeights();
|
|
} else {
|
|
this.$message.warning(`物料 ${row.partNo} 未配置每卷数量(ROLLQTY)属性,无法自动计算Rolls`);
|
|
this.$set(row, 'rolls', null);
|
|
}
|
|
} else {
|
|
console.error('获取物料包装属性失败:', data ? data.msg : '未知错误');
|
|
// 失败时不阻断用户操作,允许手动输入
|
|
this.$set(row, 'rolls', null);
|
|
}
|
|
}).catch(error => {
|
|
console.error('获取物料包装属性异常:', error);
|
|
// 异常时不阻断用户操作,允许手动输入
|
|
this.$set(row, 'rolls', null);
|
|
});
|
|
},
|
|
/**
|
|
* 根据物料装箱数量自动计算总箱数、毛重、净重和总Rolls
|
|
*/
|
|
calculateTotalBoxQtyAndWeights() {
|
|
// 获取有装箱数量的物料列表
|
|
const selectedRows = this.dataList8.filter(item => item.useQty && item.useQty > 0);
|
|
|
|
// 先计算总Rolls(不管是否有缓存属性,都可以汇总)
|
|
this.calculateTotalRolls();
|
|
|
|
if (selectedRows.length === 0) {
|
|
// 没有装箱数量时,清空
|
|
this.palletModelData.boxQty = null;
|
|
this.palletModelData.grossWeight = null;
|
|
this.palletModelData.netWeight = null;
|
|
return;
|
|
}
|
|
|
|
// 检查是否所有物料都已缓存包装属性
|
|
const allHaveCache = selectedRows.every(row =>
|
|
row.rollQtyCache && row.boxRollsCache && row.boxWeightCache
|
|
);
|
|
|
|
if (!allHaveCache) {
|
|
// 如果有物料未缓存属性,不自动计算(避免数据不完整)
|
|
return;
|
|
}
|
|
|
|
// 计算总箱数和总重量
|
|
let totalBoxQty = 0;
|
|
let totalGrossWeight = 0;
|
|
|
|
selectedRows.forEach(row => {
|
|
// 每箱EA = 每卷数量 × 每箱卷数
|
|
const eaPerBox = row.rollQtyCache * row.boxRollsCache;
|
|
// 该物料的箱数(向上取整)
|
|
const partBoxQty = Math.ceil(row.useQty / eaPerBox);
|
|
// 该物料的毛重 = 箱数 × 箱重量
|
|
const partGrossWeight = partBoxQty * row.boxWeightCache;
|
|
|
|
totalBoxQty += partBoxQty;
|
|
totalGrossWeight += partGrossWeight;
|
|
});
|
|
|
|
// 净重 = 毛重 - (箱数 / 2)
|
|
const totalNetWeight = totalGrossWeight - (totalBoxQty / 2);
|
|
|
|
// 自动填入箱数、毛重、净重
|
|
this.palletModelData.boxQty = totalBoxQty;
|
|
this.palletModelData.grossWeight = parseFloat(totalGrossWeight.toFixed(2));
|
|
this.palletModelData.netWeight = parseFloat(totalNetWeight.toFixed(2));
|
|
},
|
|
|
|
/**
|
|
* 汇总明细的Rolls总和
|
|
*/
|
|
calculateTotalRolls() {
|
|
let totalRolls = 0;
|
|
this.dataList8.forEach(row => {
|
|
const rollsValue = parseFloat(row.rolls);
|
|
if (!isNaN(rollsValue) && rollsValue > 0) {
|
|
totalRolls += rollsValue;
|
|
}
|
|
});
|
|
// 自动填入总Rolls(取整)
|
|
this.$set(this.palletModelData, 'rolls', totalRolls > 0 ? Math.round(totalRolls) : null);
|
|
},
|
|
|
|
/**
|
|
* 延迟计算总Rolls(等待v-model更新完成)
|
|
*/
|
|
delayCalculateTotalRolls() {
|
|
this.$nextTick(() => {
|
|
this.calculateTotalRolls();
|
|
});
|
|
},
|
|
/**
|
|
* 根据箱数自动计算毛重和净重
|
|
* 计算公式(来自后端代码2991-2992行):
|
|
* 毛重 = 箱数 × 箱重量
|
|
* 净重 = 毛重 - (箱数 / 2)
|
|
*/
|
|
calculateWeightsByBoxQty() {
|
|
// 如果箱数为空或为0,清空毛重和净重
|
|
if (!this.palletModelData.boxQty || this.palletModelData.boxQty <= 0) {
|
|
this.palletModelData.grossWeight = null;
|
|
this.palletModelData.netWeight = null;
|
|
return;
|
|
}
|
|
|
|
// 获取有装箱数量的物料列表
|
|
const selectedRows = this.dataList8.filter(item => item.useQty && item.useQty > 0);
|
|
|
|
if (selectedRows.length === 0) {
|
|
// 没有选择物料时,不自动计算,允许用户手动输入
|
|
return;
|
|
}
|
|
|
|
// 检查是否所有物料都已缓存箱重量
|
|
const needFetchProperties = selectedRows.filter(row => !row.boxWeightCache);
|
|
|
|
if (needFetchProperties.length === 0) {
|
|
// 所有物料都有缓存,直接计算
|
|
this.calculateWeightsWithCache(selectedRows);
|
|
} else {
|
|
// 需要获取部分物料的属性
|
|
this.fetchBoxWeightsAndCalculate(selectedRows, needFetchProperties);
|
|
}
|
|
},
|
|
/**
|
|
* 使用缓存的箱重量计算毛重和净重
|
|
*/
|
|
calculateWeightsWithCache(selectedRows) {
|
|
// 根据装箱数量计算加权平均箱重量
|
|
let totalWeight = 0;
|
|
let totalQty = 0;
|
|
|
|
selectedRows.forEach(row => {
|
|
if (row.boxWeightCache && row.boxWeightCache > 0 && row.rollQtyCache && row.rollQtyCache > 0 && row.boxRollsCache && row.boxRollsCache > 0) {
|
|
// 每箱EA = 每卷数量 × 每箱卷数
|
|
const eaPerBox = row.rollQtyCache * row.boxRollsCache;
|
|
// 该物料的箱数
|
|
const partBoxQty = Math.ceil(row.useQty / eaPerBox);
|
|
// 累计重量和箱数
|
|
totalWeight += partBoxQty * row.boxWeightCache;
|
|
totalQty += partBoxQty;
|
|
}
|
|
});
|
|
|
|
if (totalQty > 0) {
|
|
// 计算平均箱重量
|
|
const avgBoxWeight = totalWeight / totalQty;
|
|
this.calculateFinalWeights(avgBoxWeight);
|
|
} else {
|
|
// 如果无法计算平均重量,使用第一个物料的箱重量
|
|
const firstRow = selectedRows.find(row => row.boxWeightCache && row.boxWeightCache > 0);
|
|
if (firstRow) {
|
|
this.calculateFinalWeights(firstRow.boxWeightCache);
|
|
}
|
|
}
|
|
},
|
|
/**
|
|
* 获取物料箱重量并计算毛重净重
|
|
*/
|
|
fetchBoxWeightsAndCalculate(selectedRows, needFetchProperties) {
|
|
// 批量获取物料属性
|
|
const promises = needFetchProperties.map(row => {
|
|
const params = {
|
|
site: this.currentRow.site,
|
|
buNo: this.currentRow.buNo,
|
|
partNo: row.partNo
|
|
};
|
|
return getPartPackageProperties(params).then(({data}) => {
|
|
if (data && data.code === 0 && data.data) {
|
|
// 缓存物料属性
|
|
this.$set(row, 'rollQtyCache', data.data.rollQty);
|
|
this.$set(row, 'boxRollsCache', data.data.boxRolls);
|
|
this.$set(row, 'boxWeightCache', data.data.boxWeight);
|
|
return true;
|
|
}
|
|
return false;
|
|
}).catch(error => {
|
|
console.error(`获取物料 ${row.partNo} 属性失败:`, error);
|
|
return false;
|
|
});
|
|
});
|
|
|
|
Promise.all(promises).then(() => {
|
|
// 所有属性获取完成后,重新计算
|
|
this.calculateWeightsWithCache(selectedRows);
|
|
});
|
|
},
|
|
/**
|
|
* 计算最终的毛重和净重
|
|
* @param avgBoxWeight 平均箱重量
|
|
*/
|
|
calculateFinalWeights(avgBoxWeight) {
|
|
const boxQty = parseFloat(this.palletModelData.boxQty);
|
|
|
|
// 毛重 = 箱数 × 箱重量
|
|
const grossWeight = boxQty * avgBoxWeight;
|
|
|
|
// 净重 = 毛重 - (箱数 / 2)
|
|
const netWeight = grossWeight - (boxQty / 2);
|
|
|
|
// 保留2位小数
|
|
this.palletModelData.grossWeight = parseFloat(grossWeight.toFixed(2));
|
|
this.palletModelData.netWeight = parseFloat(netWeight.toFixed(2));
|
|
},
|
|
|
|
/**
|
|
* 毛重改变时自动计算净重
|
|
* 计算公式:净重 = 毛重 - (箱数 / 2)
|
|
*/
|
|
onPalletGrossWeightChange(value) {
|
|
// 防止循环触发,使用标志位
|
|
if (this._isPalletWeightCalculating) {
|
|
return;
|
|
}
|
|
|
|
this._isPalletWeightCalculating = true;
|
|
|
|
try {
|
|
const grossWeight = parseFloat(value) || 0;
|
|
const boxQty = parseFloat(this.palletModelData.boxQty) || 0;
|
|
|
|
if (grossWeight <= 0) {
|
|
this.palletModelData.netWeight = '';
|
|
return;
|
|
}
|
|
|
|
// 计算净重:净重 = 毛重 - (箱数 / 2)
|
|
const netWeight = grossWeight - (boxQty / 2);
|
|
|
|
// 保留2位小数
|
|
this.palletModelData.netWeight = parseFloat(netWeight.toFixed(2));
|
|
} finally {
|
|
this._isPalletWeightCalculating = false;
|
|
}
|
|
},
|
|
|
|
/**
|
|
* 净重改变时自动计算毛重
|
|
* 反向计算公式:毛重 = 净重 + (箱数 / 2)
|
|
*/
|
|
onPalletNetWeightChange(value) {
|
|
// 防止循环触发,使用标志位
|
|
if (this._isPalletWeightCalculating) {
|
|
return;
|
|
}
|
|
|
|
this._isPalletWeightCalculating = true;
|
|
|
|
try {
|
|
const netWeight = parseFloat(value) || 0;
|
|
const boxQty = parseFloat(this.palletModelData.boxQty) || 0;
|
|
|
|
if (netWeight <= 0) {
|
|
this.palletModelData.grossWeight = '';
|
|
return;
|
|
}
|
|
|
|
// 反向计算毛重:毛重 = 净重 + (箱数 / 2)
|
|
const grossWeight = netWeight + (boxQty / 2);
|
|
|
|
// 保留2位小数
|
|
this.palletModelData.grossWeight = parseFloat(grossWeight.toFixed(2));
|
|
} finally {
|
|
this._isPalletWeightCalculating = false;
|
|
}
|
|
},
|
|
savePalletHeader(type) {
|
|
// 过滤出 useQty > 0 的行
|
|
const selectedRows = this.dataList8.filter(item => item.useQty && item.useQty > 0);
|
|
|
|
if (this.palletModelData.addFlag === 0 && selectedRows.length === 0) {
|
|
this.$alert('请至少输入一行装箱数量!', '错误', {
|
|
confirmButtonText: '确定'
|
|
});
|
|
return false;
|
|
}
|
|
if (this.palletModelData.grossWeight<=0||this.palletModelData.grossWeight==null) {
|
|
this.$alert('请输入毛重!', '错误', {
|
|
confirmButtonText: '确定'
|
|
});
|
|
return false;
|
|
|
|
}
|
|
if (this.palletModelData.netWeight<=0||this.palletModelData.netWeight==null) {
|
|
this.$alert('请输入净重!', '错误', {
|
|
confirmButtonText: '确定'
|
|
});
|
|
return false;
|
|
}
|
|
if (this.palletModelData.boxQty<=0||this.palletModelData.boxQty==null) {
|
|
this.$alert('请输入箱数!', '错误', {
|
|
confirmButtonText: '确定'
|
|
});
|
|
return false;
|
|
}
|
|
// 校验:装箱数量不能大于可装箱数量 (item.qty)
|
|
const invalidRow = selectedRows.find(item => item.useQty > item.surplusQty);
|
|
if (invalidRow) {
|
|
this.$alert(`PN ${invalidRow.pn} 的装箱数量不能大于可装箱数量(${invalidRow.surplusQty})!`, '错误', {
|
|
confirmButtonText: '确定'
|
|
});
|
|
return false;
|
|
}
|
|
|
|
this.palletModelData.walMartOrderFlag = this.currentRow.walMartOrderFlag;
|
|
this.palletModelData.notifyDetailList = selectedRows;
|
|
|
|
savePalletHeader(this.palletModelData).then(({ data }) => {
|
|
if (data && data.code === 0) {
|
|
if (type===0) {
|
|
this.palletModelData={
|
|
addFlag:0,
|
|
site:this.currentRow.site,
|
|
buNo:this.currentRow.buNo,
|
|
delNo:this.currentRow.delNo,
|
|
grossWeight:'',
|
|
netWeight:'',
|
|
boxQty:'',
|
|
}
|
|
searchEcssCoDelNotifyDetail(this.currentRow).then(({data}) => {
|
|
if (data && data.code == 0) {
|
|
this.dataList8 = data.rows
|
|
} else {
|
|
this.dataList8 = [];
|
|
}
|
|
});
|
|
} else {
|
|
this.refreshCurrentTabTable()
|
|
this.palletModelFlag=false;
|
|
}
|
|
this.$message({
|
|
message: '操作成功',
|
|
type: 'success',
|
|
duration: 1500
|
|
});
|
|
} else {
|
|
this.$alert(data.msg, '错误', {
|
|
confirmButtonText: '确定'
|
|
});
|
|
}
|
|
});
|
|
},
|
|
|
|
updateCodelPalletHeaderPalletQty(row){
|
|
// 显示页面loading
|
|
const loading = this.$loading({
|
|
lock: true,
|
|
text: '保存中...',
|
|
spinner: 'el-icon-loading',
|
|
background: 'rgba(0, 0, 0, 0.3)'
|
|
});
|
|
|
|
updateCodelPalletHeaderPalletQty(this.palletModelData).then(({data}) => {
|
|
loading.close();
|
|
if (data && data.code === 0) {
|
|
this.palletEditFlag = false
|
|
// 刷新当前tab表格
|
|
this.refreshCurrentTabTable()
|
|
// 刷新上方的发货通知单列表
|
|
this.searchTable()
|
|
this.$message({
|
|
message: '操作成功',
|
|
type: 'success',
|
|
duration: 1500,
|
|
onClose: () => {}
|
|
})
|
|
} else {
|
|
this.$alert(data.msg, '错误', {
|
|
confirmButtonText: '确定'
|
|
})
|
|
}
|
|
}).catch(error => {
|
|
loading.close();
|
|
this.$message.error('保存失败: ' + (error.message || '未知错误'))
|
|
})
|
|
},
|
|
|
|
deletePallet(row){
|
|
this.$confirm('确认删除此明细?', '提示').then(() => {
|
|
// 显示页面loading
|
|
const loading = this.$loading({
|
|
lock: true,
|
|
text: '删除中...',
|
|
spinner: 'el-icon-loading',
|
|
background: 'rgba(0, 0, 0, 0.3)'
|
|
});
|
|
|
|
deletePalletHeader(row).then(({data}) => {
|
|
loading.close();
|
|
if (data && data.code === 0) {
|
|
this.refreshCurrentTabTable()
|
|
// 刷新上方的发货通知单列表
|
|
this.searchTable()
|
|
this.$message({
|
|
message: '操作成功',
|
|
type: 'success',
|
|
duration: 1500,
|
|
onClose: () => {}
|
|
})
|
|
} else {
|
|
this.$alert(data.msg, '错误', {
|
|
confirmButtonText: '确定'
|
|
})
|
|
}
|
|
}).catch(error => {
|
|
loading.close();
|
|
this.$message.error('删除失败: ' + (error.message || '未知错误'))
|
|
})
|
|
})
|
|
},
|
|
|
|
updateBoxModel(row,type){
|
|
this.boxModelData=JSON.parse(JSON.stringify(row))
|
|
this.boxModelData.addFlag=1
|
|
this.boxModelData.type=type
|
|
this.boxModelFlag=true
|
|
},
|
|
newBoxModel(){
|
|
this.boxModelData={
|
|
addFlag:0,
|
|
site:this.boxDetailData.site,
|
|
buNo:this.boxDetailData.buNo,
|
|
delNo:this.boxDetailData.delNo,
|
|
seqNo:this.boxDetailData.seqNo,
|
|
itemNo:'',
|
|
partNo:'',
|
|
pn:'',
|
|
qty:'',
|
|
poNo:'',
|
|
boxQty:'',
|
|
rolls:'',
|
|
type:0
|
|
}
|
|
this.boxModelFlag=true
|
|
},
|
|
saveBoxHeader(){
|
|
if(this.boxModelData.partNo===''||this.boxModelData.partNo==null){
|
|
this.$alert('请输入物料!', '错误', {
|
|
confirmButtonText: '确定'
|
|
})
|
|
return false
|
|
}
|
|
if(this.boxModelData.qty<=0||this.boxModelData.qty==null){
|
|
this.$alert('请输入数量!', '错误', {
|
|
confirmButtonText: '确定'
|
|
})
|
|
return false
|
|
}
|
|
|
|
savePalletDetail(this.boxModelData).then(({data}) => {
|
|
if (data && data.code === 0) {
|
|
searchEcssCoDelPalletDetailData(this.boxDetailData).then(({data}) => {
|
|
if (data.code === 0) {
|
|
this.dataList5 = data.rows
|
|
}
|
|
})
|
|
searchCoDelPalletDataNew(this.currentRow).then(({data}) => {
|
|
if (data && data.code == 0) {
|
|
this.dataList3 = data.rows
|
|
} else {
|
|
this.dataList3 = [];
|
|
}
|
|
});
|
|
this.boxModelFlag=false;
|
|
this.$message({
|
|
message: '操作成功',
|
|
type: 'success',
|
|
duration: 1500,
|
|
onClose: () => {}
|
|
})
|
|
} else {
|
|
this.$alert(data.msg, '错误', {
|
|
confirmButtonText: '确定'
|
|
})
|
|
}
|
|
})
|
|
},
|
|
|
|
oneClickPacking(){
|
|
if(this.currentRow.site===''||this.currentRow.site==null){
|
|
this.$alert('请先选择发货通知单!', '错误', {
|
|
confirmButtonText: '确定'
|
|
})
|
|
return false
|
|
}
|
|
this.oneClickPackingModelData={
|
|
boxRemnant: false,
|
|
}
|
|
this.oneClickPackingModelFlag=true
|
|
},
|
|
saveOneClickPacking(){
|
|
let saveData = {
|
|
site: this.currentRow.site,
|
|
buNo: this.currentRow.buNo,
|
|
delNo: this.currentRow.delNo,
|
|
boxRemnant: this.oneClickPackingModelData.boxRemnant,
|
|
}
|
|
|
|
// 显示页面loading
|
|
const loading = this.$loading({
|
|
lock: true,
|
|
text: '一键装箱计算中...',
|
|
spinner: 'el-icon-loading',
|
|
background: 'rgba(0, 0, 0, 0.3)'
|
|
});
|
|
|
|
saveOneClickPacking(saveData).then(({data}) => {
|
|
loading.close();
|
|
if (data && data.code === 0) {
|
|
this.oneClickPackingModelFlag=false;
|
|
// 刷新当前tab表格
|
|
this.refreshCurrentTabTable()
|
|
// 刷新上方的发货通知单列表
|
|
this.searchTable()
|
|
this.$message({
|
|
message: '操作成功',
|
|
type: 'success',
|
|
duration: 1500,
|
|
onClose: () => {}
|
|
})
|
|
} else {
|
|
this.$alert(data.msg, '错误', {
|
|
confirmButtonText: '确定'
|
|
})
|
|
}
|
|
}).catch(error => {
|
|
loading.close();
|
|
this.$message.error('一键装箱失败: ' + (error.message || '未知错误'))
|
|
})
|
|
},
|
|
|
|
// ========== 合箱批量编辑相关方法 ==========
|
|
|
|
/**
|
|
* 打开合箱批量编辑弹出框
|
|
*/
|
|
openMergeBoxDialog() {
|
|
if(this.currentRow.site===''||this.currentRow.site==null){
|
|
this.$alert('请先选择发货通知单!', '错误', {
|
|
confirmButtonText: '确定'
|
|
})
|
|
return false
|
|
}
|
|
this.mergeBoxDialogVisible = true
|
|
},
|
|
|
|
/**
|
|
* 加载合箱批量编辑数据
|
|
* 将发货通知单明细扁平化为表格数据,每条明细默认是一个箱子
|
|
*/
|
|
async loadMergeBoxData() {
|
|
this.mergeBoxLoading = true
|
|
this.mergeBoxTableData = []
|
|
this.mergeBoxSelection = []
|
|
this.mergeBoxOriginalData = {}
|
|
this.mergeBoxModifiedBoxes = {}
|
|
this.mergeBoxModifiedDetails = {}
|
|
this.mergeBoxMergeHistory = []
|
|
this.nextItemNo = 1
|
|
|
|
try {
|
|
// 每次都重新查询最新的发货通知单明细数据
|
|
const detailResponse = await searchEcssCoDelNotifyDetail(this.currentRow)
|
|
const detailList = (detailResponse.data && detailResponse.data.code === 0)
|
|
? detailResponse.data.rows || []
|
|
: []
|
|
|
|
if (detailList.length === 0) {
|
|
this.$message.warning('当前发货通知单没有明细数据')
|
|
this.mergeBoxLoading = false
|
|
return
|
|
}
|
|
|
|
// 处理明细数据 - 每条明细作为一个单独的箱
|
|
const tableData = []
|
|
let itemNo = 1
|
|
|
|
// 只处理剩余数量(surplus_qty)大于0的明细
|
|
const detailsToProcess = []
|
|
detailList.forEach(detail => {
|
|
const surplusQty = Number(detail.surplusQty) || 0
|
|
|
|
// 只处理剩余数量大于0的明细
|
|
if (surplusQty > 0) {
|
|
detailsToProcess.push({
|
|
detail: detail,
|
|
unpackedQty: surplusQty // 使用剩余数量
|
|
})
|
|
}
|
|
})
|
|
|
|
if (detailsToProcess.length === 0) {
|
|
this.$message.warning('所有明细都已装箱完毕')
|
|
this.mergeBoxLoading = false
|
|
return
|
|
}
|
|
|
|
// 创建表格数据
|
|
// searchEcssCoDelNotifyDetail已经返回了rollqty、boxrolls、boxweight,直接使用
|
|
detailsToProcess.forEach(({detail, unpackedQty}) => {
|
|
const boxKey = `box_${itemNo}`
|
|
|
|
// 直接从detail中读取包装属性(小写字段名)
|
|
const rollQty = Number(detail.rollqty) || 0
|
|
const boxRolls = Number(detail.boxrolls) || 0
|
|
const boxWeight = Number(detail.boxweight) || 0
|
|
|
|
// 计算默认值
|
|
let detailRolls = 0
|
|
let box_qty = 1
|
|
let grossWeight = 0
|
|
let netWeight = 0
|
|
let rolls = 0
|
|
|
|
// 1. 根据数量计算明细rolls(与calculateRolls保持一致)
|
|
if (rollQty > 0) {
|
|
detailRolls = parseFloat((unpackedQty / rollQty).toFixed(4))
|
|
// 总rolls = 明细rolls四舍五入取整(初始时每箱只有一条明细)
|
|
rolls = Math.round(detailRolls)
|
|
}
|
|
|
|
// 2. 根据数量计算箱数
|
|
if (rollQty > 0 && boxRolls > 0) {
|
|
const eaPerBox = rollQty * boxRolls
|
|
box_qty = Math.ceil(unpackedQty / eaPerBox)
|
|
}
|
|
|
|
// 3. 根据箱数计算毛重
|
|
if (boxWeight > 0) {
|
|
grossWeight = parseFloat((box_qty * boxWeight).toFixed(3))
|
|
}
|
|
|
|
// 4. 根据毛重计算净重(与装箱按钮保持一致)
|
|
netWeight = parseFloat((grossWeight - (box_qty / 2)).toFixed(3))
|
|
|
|
// 创建一行数据(Box和明细合并在一起)
|
|
const rowData = {
|
|
// Box信息
|
|
_boxKey: boxKey,
|
|
_isFirstRowOfBox: true,
|
|
_rowSpan: 1,
|
|
item_no: itemNo,
|
|
box_qty: box_qty,
|
|
grossWeight: grossWeight,
|
|
netWeight: netWeight,
|
|
rolls: rolls,
|
|
// 明细信息
|
|
_detailKey: `${detail.itemNo}_${detail.customerPO}_${detail.pn}`,
|
|
_hasDetail: true,
|
|
itemNo: detail.itemNo,
|
|
poNo: detail.customerPO,
|
|
pn: detail.pn,
|
|
qty: unpackedQty,
|
|
detailRolls: detailRolls,
|
|
readyDate: detail.readyDate,
|
|
partDesc: detail.partDesc,
|
|
// 缓存物料属性(用于后续自动计算)
|
|
rollQtyCache: rollQty,
|
|
boxRollsCache: boxRolls,
|
|
boxWeightCache: boxWeight
|
|
}
|
|
|
|
tableData.push(rowData)
|
|
|
|
// 保存Box原始数据
|
|
this.mergeBoxOriginalData[boxKey] = {
|
|
box_qty: box_qty,
|
|
grossWeight: grossWeight,
|
|
netWeight: netWeight,
|
|
rolls: rolls,
|
|
boxWeight: boxWeight
|
|
}
|
|
|
|
// 保存明细原始数据
|
|
this.mergeBoxOriginalData[rowData._detailKey] = {
|
|
qty: unpackedQty,
|
|
detailRolls: detailRolls
|
|
}
|
|
|
|
itemNo++
|
|
})
|
|
|
|
this.mergeBoxTableData = tableData
|
|
this.nextItemNo = itemNo
|
|
|
|
} catch (error) {
|
|
console.error('加载合箱数据失败:', error)
|
|
this.$message.error('加载数据失败')
|
|
} finally {
|
|
this.mergeBoxLoading = false
|
|
}
|
|
},
|
|
|
|
/**
|
|
* 选择变化事件处理
|
|
*/
|
|
handleMergeBoxSelectionChange(selection) {
|
|
this.mergeBoxSelection = selection
|
|
},
|
|
|
|
/**
|
|
* 合并选中的箱
|
|
*/
|
|
doMergeBoxes() {
|
|
if (this.mergeBoxSelection.length < 2) {
|
|
this.$message.warning('请至少选择2个箱进行合并')
|
|
return
|
|
}
|
|
|
|
// 获取选中箱的所有行数据
|
|
const selectedBoxKeys = this.mergeBoxSelection.map(row => row._boxKey)
|
|
const rowsToMerge = this.mergeBoxTableData.filter(row =>
|
|
selectedBoxKeys.includes(row._boxKey)
|
|
)
|
|
|
|
// 保存合并前的状态(用于取消合并)
|
|
const mergeHistoryItem = {
|
|
timestamp: Date.now(),
|
|
boxes: []
|
|
}
|
|
|
|
// 记录每个被合并的箱的原始状态
|
|
selectedBoxKeys.forEach(boxKey => {
|
|
const boxRows = this.mergeBoxTableData.filter(row => row._boxKey === boxKey)
|
|
if (boxRows.length > 0) {
|
|
mergeHistoryItem.boxes.push({
|
|
boxKey: boxKey,
|
|
item_no: boxRows[0].item_no,
|
|
box_qty: boxRows[0].box_qty,
|
|
grossWeight: boxRows[0].grossWeight,
|
|
netWeight: boxRows[0].netWeight,
|
|
rolls: boxRows[0].rolls,
|
|
rowCount: boxRows.length,
|
|
details: boxRows.map(r => ({
|
|
_detailKey: r._detailKey,
|
|
itemNo: r.itemNo,
|
|
poNo: r.poNo,
|
|
pn: r.pn,
|
|
qty: r.qty,
|
|
detailRolls: r.detailRolls
|
|
}))
|
|
})
|
|
}
|
|
})
|
|
|
|
this.mergeBoxMergeHistory.push(mergeHistoryItem)
|
|
|
|
// 使用第一个箱的序号作为合并后的序号
|
|
const targetItemNo = this.mergeBoxSelection[0].item_no
|
|
const targetBoxKey = this.mergeBoxSelection[0]._boxKey
|
|
|
|
// 计算合并后的累加值
|
|
let totalBoxQty = 0
|
|
let totalGrossWeight = 0
|
|
let totalNetWeight = 0
|
|
let totalRolls = 0
|
|
|
|
// 按箱Key分组,计算每个箱的值
|
|
const boxMap = new Map()
|
|
rowsToMerge.forEach(row => {
|
|
if (!boxMap.has(row._boxKey)) {
|
|
boxMap.set(row._boxKey, {
|
|
box_qty: parseFloat(row.box_qty) || 0,
|
|
grossWeight: parseFloat(row.grossWeight) || 0,
|
|
netWeight: parseFloat(row.netWeight) || 0,
|
|
rolls: parseFloat(row.rolls) || 0
|
|
})
|
|
}
|
|
})
|
|
|
|
// 累加所有箱的值
|
|
boxMap.forEach(boxData => {
|
|
totalBoxQty += boxData.box_qty
|
|
totalGrossWeight += boxData.grossWeight
|
|
totalNetWeight += boxData.netWeight
|
|
})
|
|
|
|
// 累加所有明细的rolls
|
|
rowsToMerge.forEach(row => {
|
|
if (row.detailRolls && row.detailRolls > 0) {
|
|
totalRolls += parseFloat(row.detailRolls)
|
|
}
|
|
})
|
|
|
|
// 四舍五入取整(与装箱按钮保持一致)
|
|
const finalRolls = Math.round(totalRolls)
|
|
|
|
// 更新所有被合并的行
|
|
rowsToMerge.forEach((row, index) => {
|
|
row.item_no = targetItemNo
|
|
row._boxKey = targetBoxKey
|
|
row._isFirstRowOfBox = index === 0
|
|
row._rowSpan = index === 0 ? rowsToMerge.length : 0
|
|
|
|
// 所有行使用累加后的值
|
|
row.box_qty = totalBoxQty
|
|
row.grossWeight = parseFloat(totalGrossWeight.toFixed(3))
|
|
row.netWeight = parseFloat(totalNetWeight.toFixed(3))
|
|
row.rolls = finalRolls
|
|
})
|
|
|
|
// 合并后重新编号所有箱
|
|
this.renumberBoxes()
|
|
|
|
// 按序号重新排序表格数据
|
|
this.sortTableDataByItemNo()
|
|
|
|
// 清空选择
|
|
this.$refs.mergeBoxTable.clearSelection()
|
|
this.mergeBoxSelection = []
|
|
|
|
this.$message.success(`已合并 ${selectedBoxKeys.length} 个箱(箱数: ${totalBoxQty}, 毛重: ${totalGrossWeight.toFixed(3)}, 净重: ${totalNetWeight.toFixed(3)}),当前共 ${this.getUniqueBoxCount()} 个箱`)
|
|
},
|
|
|
|
/**
|
|
* 取消选中箱的合并
|
|
*/
|
|
doUnmergeSelectedBoxes() {
|
|
if (this.mergeBoxSelection.length === 0) {
|
|
this.$message.warning('请先选择要取消合并的箱')
|
|
return
|
|
}
|
|
|
|
const selectedBoxKeys = this.mergeBoxSelection.map(row => row._boxKey)
|
|
|
|
// 找到选中箱的所有明细
|
|
const rowsToUnmerge = this.mergeBoxTableData.filter(row =>
|
|
selectedBoxKeys.includes(row._boxKey) && row._hasDetail
|
|
)
|
|
|
|
if (rowsToUnmerge.length === 0) {
|
|
this.$message.warning('所选箱没有明细数据')
|
|
return
|
|
}
|
|
|
|
// 获取原箱的序号,用于为新箱分配临时序号
|
|
const originalItemNo = rowsToUnmerge[0].item_no
|
|
|
|
// 为每条明细创建独立的箱,恢复成初始化时的原始数据
|
|
const newRows = []
|
|
rowsToUnmerge.forEach((row, index) => {
|
|
const newBoxKey = `box_${Date.now()}_${index}`
|
|
|
|
// 从mergeBoxOriginalData恢复该明细的原始数据
|
|
const detailOriginalData = this.mergeBoxOriginalData[row._detailKey]
|
|
|
|
let box_qty, grossWeight, netWeight, rolls, detailRolls
|
|
|
|
// 始终使用缓存的包装属性重新计算(确保恢复到初始值)
|
|
const rollQty = row.rollQtyCache || 0
|
|
const boxRolls = row.boxRollsCache || 0
|
|
const boxWeight = row.boxWeightCache || 0
|
|
const qty = row.qty || 0
|
|
|
|
// 恢复明细rolls
|
|
if (detailOriginalData && detailOriginalData.detailRolls !== undefined) {
|
|
detailRolls = detailOriginalData.detailRolls
|
|
} else if (rollQty > 0) {
|
|
detailRolls = parseFloat((qty / rollQty).toFixed(4))
|
|
} else {
|
|
detailRolls = 0
|
|
}
|
|
|
|
// 计算总rolls(初始时每箱只有一条明细)
|
|
rolls = Math.round(detailRolls)
|
|
|
|
// 计算箱数
|
|
if (rollQty > 0 && boxRolls > 0) {
|
|
const eaPerBox = rollQty * boxRolls
|
|
box_qty = Math.ceil(qty / eaPerBox)
|
|
} else {
|
|
box_qty = 1
|
|
}
|
|
|
|
// 计算毛重
|
|
if (boxWeight > 0) {
|
|
grossWeight = parseFloat((box_qty * boxWeight).toFixed(3))
|
|
} else {
|
|
grossWeight = 0
|
|
}
|
|
|
|
// 计算净重
|
|
netWeight = parseFloat((grossWeight - (box_qty / 2)).toFixed(3))
|
|
|
|
const newRow = {
|
|
...row,
|
|
_boxKey: newBoxKey,
|
|
_isFirstRowOfBox: true,
|
|
_rowSpan: 1,
|
|
item_no: originalItemNo + index * 0.001, // 使用原序号加小数,保持顺序
|
|
box_qty: box_qty,
|
|
grossWeight: grossWeight,
|
|
netWeight: netWeight,
|
|
rolls: rolls,
|
|
detailRolls: detailRolls // 恢复明细rolls
|
|
}
|
|
|
|
newRows.push(newRow)
|
|
|
|
// 为新箱保存原始数据(用于后续编辑)
|
|
this.mergeBoxOriginalData[newBoxKey] = {
|
|
box_qty: box_qty,
|
|
grossWeight: grossWeight,
|
|
netWeight: netWeight,
|
|
rolls: rolls,
|
|
boxWeight: boxWeight
|
|
}
|
|
})
|
|
|
|
// 删除旧的行
|
|
selectedBoxKeys.forEach(boxKey => {
|
|
for (let i = this.mergeBoxTableData.length - 1; i >= 0; i--) {
|
|
if (this.mergeBoxTableData[i]._boxKey === boxKey) {
|
|
this.mergeBoxTableData.splice(i, 1)
|
|
}
|
|
}
|
|
})
|
|
|
|
// 添加新的行
|
|
this.mergeBoxTableData.push(...newRows)
|
|
|
|
// 重新编号
|
|
this.renumberBoxes()
|
|
|
|
// 按序号重新排序表格数据
|
|
this.sortTableDataByItemNo()
|
|
|
|
// 清空选择
|
|
this.$refs.mergeBoxTable.clearSelection()
|
|
this.mergeBoxSelection = []
|
|
|
|
this.$message.success(`已取消合并,拆分为 ${newRows.length} 个独立的箱,当前共 ${this.getUniqueBoxCount()} 个箱`)
|
|
},
|
|
|
|
/**
|
|
* 重新编号所有箱
|
|
*/
|
|
renumberBoxes() {
|
|
// 获取所有唯一的箱,并记录每个箱在表格中第一次出现的位置
|
|
const boxKeysWithIndex = []
|
|
const seenBoxKeys = new Set()
|
|
|
|
this.mergeBoxTableData.forEach((row, index) => {
|
|
if (!seenBoxKeys.has(row._boxKey)) {
|
|
seenBoxKeys.add(row._boxKey)
|
|
boxKeysWithIndex.push({
|
|
boxKey: row._boxKey,
|
|
item_no: row.item_no,
|
|
firstIndex: index // 在表格中第一次出现的位置
|
|
})
|
|
}
|
|
})
|
|
|
|
// 按当前序号排序,如果序号相同则按在表格中出现的位置排序
|
|
const sortedBoxKeys = boxKeysWithIndex.sort((a, b) => {
|
|
if (a.item_no !== b.item_no) {
|
|
return a.item_no - b.item_no
|
|
}
|
|
// 序号相同时,按在表格中的位置排序
|
|
return a.firstIndex - b.firstIndex
|
|
})
|
|
|
|
// 重新分配序号
|
|
sortedBoxKeys.forEach((boxInfo, index) => {
|
|
const newItemNo = index + 1
|
|
this.mergeBoxTableData.forEach(row => {
|
|
if (row._boxKey === boxInfo.boxKey) {
|
|
row.item_no = newItemNo
|
|
}
|
|
})
|
|
})
|
|
|
|
// 更新下一个序号
|
|
this.nextItemNo = sortedBoxKeys.length + 1
|
|
},
|
|
|
|
/**
|
|
* 按序号对表格数据重新排序
|
|
*/
|
|
sortTableDataByItemNo() {
|
|
this.mergeBoxTableData.sort((a, b) => {
|
|
// 先按序号排序
|
|
if (a.item_no !== b.item_no) {
|
|
return a.item_no - b.item_no
|
|
}
|
|
// 序号相同时,保持原有顺序(同一箱内的明细)
|
|
return 0
|
|
})
|
|
},
|
|
|
|
/**
|
|
* 获取唯一箱数量
|
|
*/
|
|
getUniqueBoxCount() {
|
|
const boxKeys = new Set(this.mergeBoxTableData.map(row => row._boxKey))
|
|
return boxKeys.size
|
|
},
|
|
|
|
/**
|
|
* 表格行合并方法
|
|
*/
|
|
mergeBoxSpanMethod({ row, column, rowIndex, columnIndex }) {
|
|
// Box信息列(前6列:复选框、序号、箱数、毛重、净重、总Rolls)需要合并
|
|
if (columnIndex < 6) {
|
|
if (row._isFirstRowOfBox) {
|
|
return {
|
|
rowspan: row._rowSpan,
|
|
colspan: 1
|
|
};
|
|
} else {
|
|
return {
|
|
rowspan: 0,
|
|
colspan: 0
|
|
};
|
|
}
|
|
}
|
|
return {
|
|
rowspan: 1,
|
|
colspan: 1
|
|
};
|
|
},
|
|
|
|
/**
|
|
* 获取行样式类名
|
|
*/
|
|
getMergeBoxRowClassName({ row }) {
|
|
const classes = [];
|
|
// 检查该行是否有Box修改
|
|
if (this.mergeBoxModifiedBoxes[row._boxKey]) {
|
|
classes.push('box-modified-row');
|
|
}
|
|
// 检查该行是否有明细修改
|
|
if (row._hasDetail && this.mergeBoxModifiedDetails[row._detailKey]) {
|
|
classes.push('detail-modified-row');
|
|
}
|
|
return classes.join(' ');
|
|
},
|
|
|
|
/**
|
|
* 检查Box字段是否被修改
|
|
*/
|
|
isBoxFieldModified(row, field) {
|
|
const boxKey = row._boxKey;
|
|
return this.mergeBoxModifiedBoxes[boxKey] &&
|
|
this.mergeBoxModifiedBoxes[boxKey][field] !== undefined;
|
|
},
|
|
|
|
/**
|
|
* 检查明细字段是否被修改
|
|
*/
|
|
isDetailFieldModified(row, field) {
|
|
if (!row._hasDetail) return false;
|
|
const detailKey = row._detailKey;
|
|
return this.mergeBoxModifiedDetails[detailKey] &&
|
|
this.mergeBoxModifiedDetails[detailKey][field] !== undefined;
|
|
},
|
|
|
|
/**
|
|
* 箱数输入时联动计算毛重和净重
|
|
*/
|
|
onMergeBoxQtyInput(row) {
|
|
if (this._isMergeCalculating) return;
|
|
this._isMergeCalculating = true;
|
|
|
|
try {
|
|
const boxKey = row._boxKey;
|
|
const newBoxQty = parseFloat(row.box_qty) || 0;
|
|
|
|
// 先从原始数据获取,如果没有则从row缓存获取
|
|
let boxWeight = 0;
|
|
const originalData = this.mergeBoxOriginalData[boxKey];
|
|
if (originalData && originalData.boxWeight) {
|
|
boxWeight = parseFloat(originalData.boxWeight);
|
|
} else if (row.boxWeightCache) {
|
|
boxWeight = parseFloat(row.boxWeightCache);
|
|
}
|
|
|
|
if (boxWeight > 0 && newBoxQty > 0) {
|
|
const newGrossWeight = boxWeight * newBoxQty;
|
|
const newNetWeight = newGrossWeight - (newBoxQty / 2);
|
|
row.grossWeight = parseFloat(newGrossWeight.toFixed(3));
|
|
row.netWeight = parseFloat(newNetWeight.toFixed(3));
|
|
|
|
// 同步更新所有同Box的行
|
|
this.mergeBoxTableData.forEach(r => {
|
|
if (r._boxKey === boxKey) {
|
|
r.box_qty = row.box_qty;
|
|
r.grossWeight = row.grossWeight;
|
|
r.netWeight = row.netWeight;
|
|
}
|
|
});
|
|
|
|
this.onMergeBoxFieldChange(row, 'grossWeight');
|
|
this.onMergeBoxFieldChange(row, 'netWeight');
|
|
}
|
|
} finally {
|
|
this._isMergeCalculating = false;
|
|
}
|
|
},
|
|
|
|
/**
|
|
* 毛重输入时联动计算净重
|
|
*/
|
|
onMergeGrossWeightInput(row) {
|
|
if (this._isMergeCalculating) return;
|
|
this._isMergeCalculating = true;
|
|
|
|
try {
|
|
const grossWeight = parseFloat(row.grossWeight) || 0;
|
|
const boxQty = parseFloat(row.box_qty) || 0;
|
|
const netWeight = grossWeight - (boxQty / 2);
|
|
row.netWeight = netWeight.toFixed(2);
|
|
|
|
// 同步更新所有同Box的行
|
|
const boxKey = row._boxKey;
|
|
this.mergeBoxTableData.forEach(r => {
|
|
if (r._boxKey === boxKey) {
|
|
r.grossWeight = row.grossWeight;
|
|
r.netWeight = row.netWeight;
|
|
}
|
|
});
|
|
|
|
this.onMergeBoxFieldChange(row, 'netWeight');
|
|
} finally {
|
|
this._isMergeCalculating = false;
|
|
}
|
|
},
|
|
|
|
/**
|
|
* 净重输入时联动计算毛重
|
|
*/
|
|
onMergeNetWeightInput(row) {
|
|
if (this._isMergeCalculating) return;
|
|
this._isMergeCalculating = true;
|
|
|
|
try {
|
|
const netWeight = parseFloat(row.netWeight) || 0;
|
|
const boxQty = parseFloat(row.box_qty) || 0;
|
|
const grossWeight = netWeight + (boxQty / 2);
|
|
row.grossWeight = grossWeight.toFixed(2);
|
|
|
|
// 同步更新所有同Box的行
|
|
const boxKey = row._boxKey;
|
|
this.mergeBoxTableData.forEach(r => {
|
|
if (r._boxKey === boxKey) {
|
|
r.netWeight = row.netWeight;
|
|
r.grossWeight = row.grossWeight;
|
|
}
|
|
});
|
|
|
|
this.onMergeBoxFieldChange(row, 'grossWeight');
|
|
} finally {
|
|
this._isMergeCalculating = false;
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Box字段变化处理
|
|
*/
|
|
onMergeBoxFieldChange(row, field) {
|
|
const boxKey = row._boxKey;
|
|
const original = this.mergeBoxOriginalData[boxKey];
|
|
if (!original) return;
|
|
|
|
const currentValue = String(row[field]);
|
|
const originalValue = String(original[field]);
|
|
|
|
if (currentValue !== originalValue) {
|
|
if (!this.mergeBoxModifiedBoxes[boxKey]) {
|
|
this.$set(this.mergeBoxModifiedBoxes, boxKey, {});
|
|
}
|
|
this.$set(this.mergeBoxModifiedBoxes[boxKey], field, {
|
|
oldValue: original[field],
|
|
newValue: row[field]
|
|
});
|
|
|
|
// 同步更新所有同Box的行
|
|
this.mergeBoxTableData.forEach(r => {
|
|
if (r._boxKey === boxKey) {
|
|
r[field] = row[field];
|
|
}
|
|
});
|
|
} else {
|
|
if (this.mergeBoxModifiedBoxes[boxKey]) {
|
|
this.$delete(this.mergeBoxModifiedBoxes[boxKey], field);
|
|
if (Object.keys(this.mergeBoxModifiedBoxes[boxKey]).length === 0) {
|
|
this.$delete(this.mergeBoxModifiedBoxes, boxKey);
|
|
}
|
|
}
|
|
}
|
|
},
|
|
|
|
/**
|
|
* 明细字段变化处理
|
|
*/
|
|
onMergeDetailFieldChange(row, field) {
|
|
if (!row._hasDetail) return;
|
|
|
|
const detailKey = row._detailKey;
|
|
const original = this.mergeBoxOriginalData[detailKey];
|
|
if (!original) return;
|
|
|
|
const currentValue = String(row[field]);
|
|
const originalValue = String(original[field]);
|
|
|
|
if (currentValue !== originalValue) {
|
|
if (!this.mergeBoxModifiedDetails[detailKey]) {
|
|
this.$set(this.mergeBoxModifiedDetails, detailKey, {
|
|
row: row
|
|
});
|
|
}
|
|
this.$set(this.mergeBoxModifiedDetails[detailKey], field, {
|
|
oldValue: original[field],
|
|
newValue: row[field]
|
|
});
|
|
} else {
|
|
if (this.mergeBoxModifiedDetails[detailKey]) {
|
|
this.$delete(this.mergeBoxModifiedDetails[detailKey], field);
|
|
const remainingFields = Object.keys(this.mergeBoxModifiedDetails[detailKey])
|
|
.filter(k => k !== 'row');
|
|
if (remainingFields.length === 0) {
|
|
this.$delete(this.mergeBoxModifiedDetails, detailKey);
|
|
}
|
|
}
|
|
}
|
|
},
|
|
|
|
/**
|
|
* 明细Rolls输入事件处理 - 自动计算总Rolls
|
|
*/
|
|
onDetailRollsInput(row) {
|
|
this.$nextTick(() => {
|
|
this.calculateBoxTotalRolls(row);
|
|
});
|
|
},
|
|
|
|
/**
|
|
* 计算同一Box下所有明细Rolls的总和
|
|
* 计算规则:总Rolls = Sum(所有明细rolls),然后四舍五入取整
|
|
*/
|
|
calculateBoxTotalRolls(row) {
|
|
const boxKey = row._boxKey;
|
|
const boxRows = this.mergeBoxTableData.filter(r => r._boxKey === boxKey && r._hasDetail);
|
|
|
|
let totalDetailRolls = 0;
|
|
let hasDetailRolls = false;
|
|
|
|
boxRows.forEach(r => {
|
|
const rollsValue = parseFloat(r.detailRolls);
|
|
if (!isNaN(rollsValue) && rollsValue > 0) {
|
|
totalDetailRolls += rollsValue;
|
|
hasDetailRolls = true;
|
|
}
|
|
});
|
|
|
|
// 四舍五入取整(与装箱按钮保持一致)
|
|
const newRolls = hasDetailRolls ? Math.round(totalDetailRolls) : 0;
|
|
|
|
this.mergeBoxTableData.forEach(r => {
|
|
if (r._boxKey === boxKey) {
|
|
this.$set(r, 'rolls', newRolls);
|
|
}
|
|
});
|
|
|
|
this.onMergeBoxFieldChange(row, 'rolls');
|
|
},
|
|
|
|
/**
|
|
* 检查Box是否有明细Rolls值
|
|
*/
|
|
hasDetailRolls(row) {
|
|
const boxKey = row._boxKey;
|
|
const boxRows = this.mergeBoxTableData.filter(r => r._boxKey === boxKey && r._hasDetail);
|
|
|
|
return boxRows.some(r => {
|
|
const rollsValue = parseFloat(r.detailRolls);
|
|
return !isNaN(rollsValue) && rollsValue > 0;
|
|
});
|
|
},
|
|
|
|
/**
|
|
* 明细数量变化时重新计算rolls
|
|
*/
|
|
onDetailQtyChange(row) {
|
|
// 如果有缓存的每卷数量,重新计算rolls
|
|
if (row.rollQtyCache && row.rollQtyCache > 0 && row.qty > 0) {
|
|
const newRolls = parseFloat((row.qty / row.rollQtyCache).toFixed(4))
|
|
this.$set(row, 'detailRolls', newRolls)
|
|
|
|
// 更新总Rolls
|
|
this.$nextTick(() => {
|
|
this.calculateBoxTotalRolls(row)
|
|
})
|
|
}
|
|
},
|
|
|
|
/**
|
|
* 保存合箱批量编辑
|
|
*/
|
|
async saveMergeBoxEdit() {
|
|
// 允许直接保存,即使没有修改
|
|
this.mergeBoxSaving = true
|
|
|
|
try {
|
|
// 构造提交数据 - 按箱分组
|
|
const boxMap = new Map()
|
|
|
|
// 遍历表格数据,按箱分组
|
|
this.mergeBoxTableData.forEach(row => {
|
|
const boxKey = row._boxKey
|
|
if (!boxMap.has(boxKey)) {
|
|
boxMap.set(boxKey, {
|
|
item_no: row.item_no,
|
|
box_qty: row.box_qty,
|
|
grossWeight: row.grossWeight,
|
|
netWeight: row.netWeight,
|
|
rolls: row.rolls,
|
|
details: []
|
|
})
|
|
}
|
|
|
|
// 添加明细
|
|
if (row._hasDetail) {
|
|
boxMap.get(boxKey).details.push({
|
|
itemNo: row.itemNo,
|
|
poNo: row.poNo,
|
|
pn: row.pn,
|
|
qty: row.qty,
|
|
detailRolls: row.detailRolls,
|
|
readyDate: row.readyDate
|
|
})
|
|
}
|
|
})
|
|
|
|
// 转换为数组
|
|
const boxList = Array.from(boxMap.values())
|
|
|
|
if (boxList.length === 0) {
|
|
this.$message.warning('没有可保存的箱数据')
|
|
this.mergeBoxSaving = false
|
|
return
|
|
}
|
|
|
|
const mergeData = {
|
|
site: this.currentRow.site,
|
|
buNo: this.currentRow.buNo,
|
|
delNo: this.currentRow.delNo,
|
|
createBy: this.$store.state.user.name,
|
|
boxList: boxList
|
|
}
|
|
|
|
// 调用合箱API
|
|
const response = await mergeBox(mergeData)
|
|
|
|
if (response.data && response.data.code === 0) {
|
|
this.$message.success(`成功保存 ${boxList.length} 个箱的数据`)
|
|
this.mergeBoxDialogVisible = false
|
|
// 刷新当前tab表格
|
|
this.refreshCurrentTabTable()
|
|
// 刷新上方的发货通知单列表
|
|
this.searchTable()
|
|
} else {
|
|
this.$alert(response.data.msg || '保存失败', '错误', {
|
|
confirmButtonText: '确定'
|
|
})
|
|
}
|
|
} catch (error) {
|
|
console.error('保存失败:', error)
|
|
this.$message.error('保存失败: ' + (error.message || '未知错误'))
|
|
} finally {
|
|
this.mergeBoxSaving = false
|
|
}
|
|
},
|
|
|
|
openPalletDialog () {
|
|
//请求
|
|
this.searchPalletList();
|
|
},
|
|
closePalletDialog () {
|
|
this.palletList = []
|
|
this.palletFlag = false
|
|
},
|
|
searchPalletList () {
|
|
this.palletData.buNo = this.palletModelData.buNo
|
|
searchPalletList(this.palletData).then(({data}) => {
|
|
if (data && data.code === 0){
|
|
this.palletList = data.rows;
|
|
}
|
|
})
|
|
},
|
|
palletRowDblclick (row) {
|
|
this.palletModelData.pallet = row.palletNo
|
|
this.palletFlag = false
|
|
},
|
|
|
|
// 栈板维护相关方法
|
|
palletMaintenance() {
|
|
if(this.currentRow.site===''||this.currentRow.site==null){
|
|
this.$alert('请先选择发货通知单!', '错误', {
|
|
confirmButtonText: '确定'
|
|
})
|
|
return false
|
|
}
|
|
// 重置栈板记录
|
|
this.palletMaintenanceRecords = []
|
|
// 默认根据buNo获取全部栈板
|
|
this.loadAllPalletsForMaintenance()
|
|
this.palletMaintenanceModelFlag = true
|
|
},
|
|
|
|
// 根据buNo加载全部栈板用于维护
|
|
loadAllPalletsForMaintenance() {
|
|
let searchData = {
|
|
palletType: '', // 不限制栈板类型,获取全部
|
|
buNo: this.currentRow.buNo
|
|
}
|
|
searchPalletList(searchData).then(({data}) => {
|
|
if (data.code === 0) {
|
|
const pallets = data.rows || []
|
|
// 为每个栈板创建一条记录
|
|
this.palletMaintenanceRecords = pallets.map(pallet => ({
|
|
pallet: pallet.palletNo,
|
|
palletType: pallet.palletType,
|
|
palletQty: '', // 默认为空,用户需要输入
|
|
height: '' // 使用栈板的默认高度
|
|
}))
|
|
}
|
|
}).catch(error => {
|
|
console.error('加载栈板列表失败:', error)
|
|
// 如果加载失败,至少添加一行空记录
|
|
this.palletMaintenanceRecords = [{
|
|
pallet: '',
|
|
palletType: '',
|
|
palletQty: '',
|
|
height: ''
|
|
}]
|
|
})
|
|
},
|
|
|
|
savePalletMaintenance() {
|
|
// 过滤出托数大于0的栈板记录
|
|
const validPalletRecords = this.palletMaintenanceRecords.filter(record => {
|
|
return record.palletQty && parseFloat(record.palletQty) > 0
|
|
})
|
|
|
|
if (validPalletRecords.length === 0) {
|
|
this.$alert('请至少输入一条有效的栈板记录!', '错误', {
|
|
confirmButtonText: '确定'
|
|
})
|
|
return false
|
|
}
|
|
// 验证有效的栈板记录
|
|
for (let i = 0; i < validPalletRecords.length; i++) {
|
|
const record = validPalletRecords[i]
|
|
if (!record.pallet) {
|
|
this.$alert(`栈板不能为空!`, '错误', {
|
|
confirmButtonText: '确定'
|
|
})
|
|
return false
|
|
}
|
|
if (!record.height || record.height <= 0) {
|
|
this.$alert(`栈板高度必须大于0!`, '错误', {
|
|
confirmButtonText: '确定'
|
|
})
|
|
return false
|
|
}
|
|
}
|
|
this.saveLoading = true
|
|
// 这里只新增栈板记录,不做其他事情
|
|
let saveData = {
|
|
site: this.currentRow.site,
|
|
buNo: this.currentRow.buNo,
|
|
delNo: this.currentRow.delNo,
|
|
palletRecords: JSON.stringify(validPalletRecords),
|
|
}
|
|
|
|
// 使用相同的API,但传递maintenanceOnly标识
|
|
savePalletMaintenance(saveData).then(({data}) => {
|
|
if (data && data.code === 0) {
|
|
this.searchTable()
|
|
this.refreshCurrentTabTable()
|
|
this.palletMaintenanceModelFlag = false;
|
|
this.$message({
|
|
message: '栈板记录新增成功',
|
|
type: 'success',
|
|
duration: 1500,
|
|
onClose: () => {}
|
|
})
|
|
this.saveLoading = false
|
|
} else {
|
|
this.$alert(data.msg, '错误', {
|
|
confirmButtonText: '确定'
|
|
})
|
|
this.saveLoading = false
|
|
}
|
|
}).catch((error) => {
|
|
console.error('保存失败:', error)
|
|
this.$message.error('保存失败,请重试')
|
|
}).finally(() => {
|
|
this.saveLoading = false
|
|
})
|
|
},
|
|
getSummaries(param) {
|
|
const { columns } = param;
|
|
const sums = [];
|
|
columns.forEach((column, index) => {
|
|
if (index === 0) {
|
|
sums[index] = '合计';
|
|
return;
|
|
}
|
|
let sumDataList = this.dataList4.filter(item => item.palletQty>0);
|
|
const values = sumDataList.map(item => Number(item[column.property]));
|
|
if (!values.every(value => isNaN(value))) {
|
|
switch(column.property) {
|
|
case 'palletQty':
|
|
sums[index] = `${values.reduce((a, b) => a + b, 0)}`;
|
|
break;
|
|
case 'weight':
|
|
sums[index] = `${values.reduce((a, b) => a + b, 0)}`;
|
|
break;
|
|
default:
|
|
sums[index] = '';
|
|
}
|
|
} else {
|
|
sums[index] = '';
|
|
}
|
|
});
|
|
this.$nextTick(() => this.$refs.detailTable.doLayout());// 强制刷新布局, 否则会被表格覆盖
|
|
return sums;
|
|
},
|
|
getDetailSummaries(param) {
|
|
const { columns } = param;
|
|
const sums = [];
|
|
columns.forEach((column, index) => {
|
|
if (index === 0) {
|
|
sums[index] = '合计';
|
|
return;
|
|
}
|
|
let sumDataList = this.dataList2.filter(item => item.qty>0);
|
|
const values = sumDataList.map(item => Number(item[column.property]));
|
|
if (!values.every(value => isNaN(value))) {
|
|
switch(column.property) {
|
|
case 'qty':
|
|
sums[index] = `${values.reduce((a, b) => a + b, 0)}`;
|
|
break;
|
|
case 'ttlAmount':
|
|
sums[index] = `${values.reduce((a, b) => a + b, 0).toFixed(2)}`;
|
|
break;
|
|
case 'sumPrice':
|
|
sums[index] = `${values.reduce((a, b) => a + b, 0).toFixed(2)}`;
|
|
break;
|
|
default:
|
|
sums[index] = '';
|
|
}
|
|
} else {
|
|
sums[index] = '';
|
|
}
|
|
});
|
|
this.$nextTick(() => this.$refs.cloDetailTable.doLayout());// 强制刷新布局, 否则会被表格覆盖
|
|
return sums;
|
|
},
|
|
/**
|
|
* 保存选中行到本地存储
|
|
* 使用页面路径和用户名作为存储键的一部分,确保不同页面和用户的选择互不影响
|
|
*/
|
|
saveSelectedRowToStorage() {
|
|
try {
|
|
const storageKey = `codelnotifyConfirm_selected_row_${this.$store.state.user.name}`;
|
|
localStorage.setItem(storageKey, this.selectedRowKey);
|
|
console.log(`[确认页面行选择持久化] 已保存选中行: ${this.selectedRowKey}`);
|
|
} catch (error) {
|
|
console.warn('保存选中行状态失败:', error);
|
|
}
|
|
},
|
|
|
|
/**
|
|
* 从本地存储恢复选中行
|
|
* @returns {Object|null} 返回匹配的行数据,如果没有找到则返回null
|
|
*/
|
|
restoreSelectedRow() {
|
|
try {
|
|
const storageKey = `codelnotifyConfirm_selected_row_${this.$store.state.user.name}`;
|
|
const savedRowKey = localStorage.getItem(storageKey);
|
|
|
|
// 检查必要的条件
|
|
if (!savedRowKey) {
|
|
console.log('[确认页面行选择持久化] 没有保存的选中行');
|
|
return null;
|
|
}
|
|
|
|
if (!this.dataList || this.dataList.length === 0) {
|
|
console.log('[确认页面行选择持久化] 数据列表为空,无法恢复选中行');
|
|
return null;
|
|
}
|
|
|
|
// 在当前数据列表中查找匹配的行
|
|
const matchedRow = this.dataList.find(row => row && row.delNo === savedRowKey);
|
|
if (matchedRow) {
|
|
this.selectedRowKey = savedRowKey;
|
|
console.log(`[确认页面行选择持久化] 已恢复选中行: ${savedRowKey}`);
|
|
return matchedRow;
|
|
} else {
|
|
console.log(`[确认页面行选择持久化] 未找到匹配的行: ${savedRowKey},当前数据列表长度: ${this.dataList.length}`);
|
|
}
|
|
|
|
return null;
|
|
} catch (error) {
|
|
console.warn('恢复选中行状态失败:', error);
|
|
return null;
|
|
}
|
|
},
|
|
|
|
/**
|
|
* 清除本地存储的选中行状态
|
|
*/
|
|
clearSelectedRowStorage() {
|
|
try {
|
|
const storageKey = `codelnotifyConfirm_selected_row_${this.$store.state.user.name}`;
|
|
localStorage.removeItem(storageKey);
|
|
this.selectedRowKey = null;
|
|
} catch (error) {
|
|
console.warn('清除选中行状态失败:', error);
|
|
}
|
|
},
|
|
|
|
},
|
|
activated() {
|
|
this.searchTable()
|
|
},
|
|
created() {
|
|
this.getBu ()
|
|
// 动态列
|
|
this.getTableUserColumn(this.$route.meta.menuId+'table1',1)
|
|
|
|
// 初始化时从本地存储加载选中行状态
|
|
try {
|
|
const storageKey = `codelnotifyConfirm_selected_row_${this.$store.state.user.name}`;
|
|
const savedRowKey = localStorage.getItem(storageKey);
|
|
if (savedRowKey) {
|
|
this.selectedRowKey = savedRowKey;
|
|
}
|
|
} catch (error) {
|
|
console.warn('初始化选中行状态失败:', error);
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss">
|
|
.warning-row td{
|
|
color: darkred !important;
|
|
}
|
|
.zxClass .cell {
|
|
line-height: 24px;
|
|
font-size: 12px;
|
|
height: 24px;
|
|
}
|
|
|
|
/* 可点击的PN样式 */
|
|
.clickable-pn {
|
|
cursor: pointer;
|
|
text-decoration: underline;
|
|
}
|
|
|
|
.clickable-pn:hover {
|
|
opacity: 0.8;
|
|
}
|
|
|
|
/* 对话框标题样式 */
|
|
.dialog-title {
|
|
display: flex;
|
|
align-items: center;
|
|
font-size: 16px;
|
|
font-weight: 500;
|
|
}
|
|
|
|
.dialog-title .el-icon-question:hover {
|
|
color: #66b1ff;
|
|
transform: scale(1.1);
|
|
transition: all 0.3s ease;
|
|
}
|
|
|
|
/* 表格头部提示图标样式 */
|
|
/deep/ .el-table th .el-icon-question:hover {
|
|
color: #409EFF;
|
|
transform: scale(1.1);
|
|
transition: all 0.2s ease;
|
|
}
|
|
|
|
/* 提示框内容样式 */
|
|
/deep/ .el-tooltip__popper {
|
|
max-width: 300px;
|
|
}
|
|
|
|
/deep/ .el-tooltip__popper .el-tooltip__content {
|
|
line-height: 1.6;
|
|
}
|
|
|
|
/deep/ .el-tooltip__popper .el-tooltip__content div {
|
|
margin-bottom: 4px;
|
|
}
|
|
|
|
/deep/ .el-tooltip__popper .el-tooltip__content div:first-child {
|
|
font-weight: bold;
|
|
margin-bottom: 8px;
|
|
color: #409EFF;
|
|
}
|
|
.pallet-dialog .section {
|
|
margin: 10px 7px;
|
|
}
|
|
|
|
.section-title {
|
|
font-size: 14px;
|
|
font-weight: bold;
|
|
color: #333;
|
|
margin-bottom: 8px;
|
|
}
|
|
|
|
.table-wrapper {
|
|
height: 300px; /* 让表格部分固定高度并滚动 */
|
|
overflow-y: auto;
|
|
}
|
|
|
|
/* ========== 合箱批量编辑弹出框样式 ========== */
|
|
|
|
/* 修复表格滚动条右侧的颜色问题 - 强制设置gutter背景色为白色 */
|
|
.el-dialog__wrapper .batch-edit-dialog .el-table th.gutter {
|
|
background-color: #f5f7fa !important;
|
|
}
|
|
|
|
/* 工具栏样式 */
|
|
.merge-box-toolbar {
|
|
display: flex;
|
|
align-items: center;
|
|
margin-bottom: 15px;
|
|
padding: 10px;
|
|
background: #f5f7fa;
|
|
border-radius: 4px;
|
|
}
|
|
|
|
.merge-box-toolbar .merge-stats {
|
|
margin-left: auto;
|
|
display: flex;
|
|
align-items: center;
|
|
}
|
|
|
|
.merge-box-toolbar .modified-count {
|
|
color: #e6a23c;
|
|
margin-left: 10px;
|
|
}
|
|
|
|
.merge-box-toolbar .modified-count b {
|
|
color: #f56c6c;
|
|
font-size: 16px;
|
|
}
|
|
|
|
/* Box信息单元格样式 */
|
|
.box-info-cell {
|
|
font-weight: 600;
|
|
color: #409eff;
|
|
font-size: 13px;
|
|
}
|
|
|
|
/* 修改过的输入框样式 */
|
|
/deep/ .batch-edit-container .modified-input .el-input__inner {
|
|
background-color: #fff7e6;
|
|
border-color: #e6a23c;
|
|
color: #e6a23c;
|
|
}
|
|
|
|
/* 修改过的行样式 */
|
|
/deep/ .batch-edit-container .box-modified-row td:nth-child(-n+6) {
|
|
background-color: #fdf6ec !important;
|
|
}
|
|
|
|
/deep/ .batch-edit-container .detail-modified-row td:nth-child(n+7) {
|
|
background-color: #fff7e6 !important;
|
|
}
|
|
|
|
/* 输入框样式 */
|
|
/deep/ .batch-edit-container .el-input--mini .el-input__inner {
|
|
text-align: center;
|
|
padding: 0 8px;
|
|
border-color: #dcdfe6;
|
|
}
|
|
|
|
/deep/ .batch-edit-container .el-input--mini .el-input__inner:focus {
|
|
border-color: #409eff;
|
|
}
|
|
|
|
/* 表格单元格内边距 */
|
|
/deep/ .batch-edit-container .el-table td {
|
|
padding: 6px 0;
|
|
}
|
|
|
|
/deep/ .batch-edit-container .el-table .cell {
|
|
padding: 0 8px;
|
|
}
|
|
|
|
/* 数字输入框隐藏上下箭头 */
|
|
/deep/ .batch-edit-container input[type="number"]::-webkit-inner-spin-button,
|
|
/deep/ .batch-edit-container input[type="number"]::-webkit-outer-spin-button {
|
|
-webkit-appearance: none;
|
|
margin: 0;
|
|
}
|
|
|
|
/deep/ .batch-edit-container input[type="number"] {
|
|
-moz-appearance: textfield;
|
|
}
|
|
|
|
/* 合并单元格的垂直居中 */
|
|
/deep/ .batch-edit-container .el-table__body td[rowspan] {
|
|
vertical-align: middle;
|
|
}
|
|
|
|
/deep/ .batch-edit-container .el-table__body td[rowspan] .cell {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
height: 100%;
|
|
}
|
|
|
|
/* 文字样式 */
|
|
/deep/ .batch-edit-container .el-table .cell span {
|
|
font-size: 13px;
|
|
color: #606266;
|
|
}
|
|
|
|
</style>
|