<template> <div class="startPacking"> <el-card> <el-row class="content-area"> <!-- 左侧 --> <el-col :span="6" class="left-area"> <el-row v-for="item in listData" :key="item.id" class="title-info" :class="item.id === tableData.id ? 'selected' : ''"> <div @click="partClick(item)"> <p>{{item.title}}</p> </div> <div> <template v-if="item.secStatistics"> {{getTotlContent(item.secStatistics)}} </template> </div> </el-row> </el-col> <!-- 右侧 --> <el-col :span="18" class="right-area"> <!-- 操作 --> <el-row class="table-title"> <div>{{$t('当前装柜')}}:{{tableData.title}}</div> <div> <template v-if="!isUnderReview"> <el-input v-model="qrCode" :placeholder="$t('请输入二维码/条码编号')" clearable></el-input> <el-button type="primary" @click="handlerBatchCreate('single')">{{$t('确定')}}</el-button> <el-button type="primary" @click="handlerClick('batchInput',$t('批量输入'))">{{$t('批量输入')}}</el-button> <el-button type="primary" @click="handlerClick('correction',$t('装柜纠错'))">{{$t('装柜纠错')}}</el-button> <el-button type="primary" @click="handlerClick('correctionOrder',$t('批量装柜纠错'))">{{$t('批量装柜纠错')}}</el-button> </template> </div> </el-row> <!-- 表格 --> <el-row class="table-content"> <el-table :data="tableData.sectionOrderList" border max-height="500px"> <el-table-column :label="$t('序号')" align="center" width="50" prop="tidanNum" /> <el-table-column :label="$t('订单号')" align="center" prop="orderNo"> <template slot-scope="scope"> <div> <a href="javascript:void(0);" class="order-href" @click="orderClick(scope.row)">{{ scope.row.orderNo }}</a> </div> <div style="color:blue;fontWeight:bold;"> {{ scope.row.isExternalWarehouse === 1 ? '(' + $t('外部仓') + ')' : ''}} </div> </template> </el-table-column> <el-table-column :label="$t('货物信息')" align="center" prop="goodsList"> <template slot-scope="scope"> <section class="table-goodList"> <div v-for="(item, index) in scope.row.goodsList" :key="index" class="goodList-div"> <p>{{$t('品名')}}:{{$l(item,'prodTitle')}}</p> <p>{{$t('品牌')}}:【<template v-if="item.brandName">{{item.brandName}}</template> <dict-tag v-else :type="DICT_TYPE.ECW_IS_BRAND" :value="item.feeType" />{{ $t('】') }}</p> <p>{{$t('其他')}}:{{getTotlContent(item)}}</p> </div> </section> </template> </el-table-column> <el-table-column :label="$t('报关方式')" align="center" prop="customsType"> <template slot-scope="scope"> <div :class="scope.row.customsType !== 1 ? 'custom_type_red' : ''"> <dict-tag :type="DICT_TYPE.ECW_CUSTOMS_TYPE" :value="scope.row.customsType" /> </div> </template> </el-table-column> <el-table-column :label="$t('计划箱数')" align="center" prop="num"> <template slot-scope="scope"> {{getTotlContent(scope.row,['num'])}} </template> </el-table-column> <el-table-column :label="$t('实装箱数')" align="center" prop="installNum"> <template slot-scope="scope"> {{ scope.row.installNum }}{{$t('箱')}} </template> </el-table-column> <el-table-column :label="$t('体积')" align="center" prop="volume"> <template slot-scope="scope"> {{getTotlContent(scope.row,['volume'])}} </template> </el-table-column> <el-table-column :label="$t('重量')" align="center" prop="weight"> <template slot-scope="scope"> {{getTotlContent(scope.row,['weight'])}} </template> </el-table-column> <el-table-column :label="$t('操作')" align="center" class-name="small-padding fixed-width"> <template slot-scope="scope"> <el-button type="text" size="small" @click="moveOut(scope.row)" v-if="!isUnderReview && scope.row.installNum === 0">{{$t('移出')}}</el-button> <el-button type="text" size="small" v-if="isShowSplitOrder(scope.row)" @click="handlerSplitOrder(scope.row, 'splitOrder', $t('拆单'))">{{$t('拆单')}}</el-button> </template> </el-table-column> </el-table> </el-row> </el-col> </el-row> </el-card> <!-- 统计 --> <el-row> <el-col :span="6" class="totle-info"> <div class="count-info"> <p>{{$t('总计')}}:{{getSumData}}</p> </div> <div> <p>{{$t('容量')}}:</p> <p>{{calcCapacity}}</p> </div> <div>{{$t('已装')}} {{getInstallNumCount}} {{$t('箱')}}</div> </el-col> </el-row> <!-- 审核流程 --> <el-row class="process-area"> <div class="process"> <div>{{$t('审批流程')}}</div> <work-flow xmlkey="close_container" v-model="selectedUsers"></work-flow> </div> <!-- 操作 --> <div v-if="!isUnderReview"> <el-button type="primary" @click="handlerClick('supplementOrder',$t('补单'))">{{$t('补单')}}</el-button> <el-button type="primary" @click="applyCloseCabinet">{{$t('封柜申请')}}</el-button> <el-button type="primary" @click="handlerClick('modifyCabinet',$t('修改柜信息'))">{{$t('修改柜信息')}}</el-button> </div> <div v-if="isUnderReview"> <el-button type="primary" @click="jumpReviewDetail">{{$t('封柜审核中')}}</el-button> <el-button plain type="primary" @click="canclAudit">{{$t('取消审核')}}</el-button> <el-button plain type="primary" @click="$emit('closeDialog1')">{{$t('返回')}}</el-button> </div> </el-row> <!-- 对话框 --> <el-dialog custom-class="shipping-dialog" :title="dialogConfig.title" :visible.sync="dialogConfig.dialogVisible" :fullscreen="dialogConfig.fullscreen" :width="dialogConfig.width" :modal-append-to-body=false append-to-body> <!-- 已装未装订单 --> <template v-if="dialogConfig.type === 'orderTable'"> <el-table :data="orderList" height="500px" border> <el-table-column :label="$t('已装')" align="center" prop="loadTag" /> <el-table-column :label="$t('未装')" align="center" prop="unloadTag" /> </el-table> </template> <!-- 补单 --> <supplementOrder v-if="dialogConfig.type === 'supplementOrder' && dialogConfig.dialogVisible" v-bind="$attrs" :shipmentObj="shipmentObj" @supplementFinish="supplementFinish" /> <!-- 修改柜信息 --> <template v-if="dialogConfig.type === 'modifyCabinet' && dialogConfig.dialogVisible"> <el-form ref="modifyForm" :rules="rules" :model="modifyCabinetObj" label-width="80px"> <el-form-item v-if="false" :label="$t('起运仓库')" prop="startWarehouseId"> <el-select v-model="modifyCabinetObj.startWarehouseId" :placeholder="$t('请选择仓库')" filterable> <el-option v-for="warehouse in $attrs.warehouseList" :key="warehouse.id" :label="$l(warehouse, 'title')" :value="warehouse.id"></el-option> </el-select> </el-form-item> <el-form-item :label="$t('预装日期')">{{preinstallDate}}</el-form-item> <el-form-item :label="$t('选择柜型')" prop="cabinetId"> <el-select v-model="modifyCabinetObj.cabinetId" :placeholder="$t('请选择柜型')"> <el-option v-for="item in cabinetList" :label="item.name" :value="item.id" :key="item.id"></el-option> </el-select> </el-form-item> <el-form-item :label="$t('柜号')"> <el-input v-model="modifyCabinetObj.cubNo" :placeholder="$t('请输入柜号')" clearable /> </el-form-item> </el-form> <el-row class="operate-button"> <el-button type="primary" @click="onSubmit('modifyForm')">{{$t('下一步')}}</el-button> <el-button @click="closeDialog2">{{$t('取消')}}</el-button> </el-row> </template> <!-- 装柜纠错 --> <template v-if="dialogConfig.type === 'correction' && dialogConfig.dialogVisible"> <el-form ref="correctionForm" :rules="rules" :model="correctionObj" label-position="top"> <el-form-item :label="$t('装柜纠错(二维码/条形码编号)')" prop="qrCode"> <el-input v-model="correctionObj.qrCode" :placeholder="$t('请输入二维码/条形码编号')" clearable /> </el-form-item> </el-form> <el-row class="operate-button"> <el-button type="primary" @click="onSubmit('correctionForm')">{{$t('提交')}}</el-button> <el-button @click="closeDialog2">{{$t('取消')}}</el-button> </el-row> </template> <!-- 批量装柜纠错(订单号) --> <template v-if="dialogConfig.type === 'correctionOrder' && dialogConfig.dialogVisible"> <el-form ref="orderForm" :rules="rules" :model="orderObj" label-position="top"> <el-form-item :label="$t('装柜纠错') +'(' + $t('订单号') + ')'" prop="orderNo"> <el-input type="textarea" :rows="3" v-model="orderObj.orderNo" :placeholder="$t('请输入,多个以逗号分隔')" clearable /> </el-form-item> </el-form> <el-row class="operate-button"> <el-button type="primary" @click="onSubmit('orderForm')">{{$t('提交')}}</el-button> <el-button @click="closeDialog2">{{$t('取消')}}</el-button> </el-row> </template> <!-- 装柜批量输入 --> <template v-if="dialogConfig.type === 'batchInput' && dialogConfig.dialogVisible"> <el-form ref="batchForm" :rules="rules" :model="batchObj"> <el-form-item label="" prop="qrCode" class="two-element"> <el-input v-model="batchObj.qrCode" :placeholder="$t('请输入订单号')" clearable /> <el-button style="marginLeft:10px;" type="primary" @click="queryOrderInfo">{{$t('确定')}}</el-button> </el-form-item> <el-row> <el-col :span="12"> <el-form-item :label="$t('订单号')"> {{boxOrderInfo.orderNo}} </el-form-item> </el-col> <el-col :span="12"> <el-form-item :label="$t('箱数')"> <el-input-number v-if="boxOrderInfo.isExternalWarehouse === 1" v-model="batchObj.boxNum" :min="0" :max="boxOrderInfo.num" /> <template v-else> {{boxOrderInfo.num}} </template> </el-form-item> </el-col> </el-row> <el-row> <el-col :span="12"> <el-form-item :label="$t('方数')"> {{getTotlContent(boxOrderInfo, ['volume'])}} </el-form-item> </el-col> <el-col :span="12"> <el-form-item :label="$t('重量')"> {{getTotlContent(boxOrderInfo, ['weight'])}} </el-form-item> </el-col> </el-row> </el-form> <el-row class="operate-button"> <el-button type="primary" :disabled="boxOrderInfo.orderId ? false : true" @click="batchLoad">{{$t('提交')}}</el-button> <el-button @click="closeDialog2">{{$t('取消')}}</el-button> </el-row> </template> <!-- 拆单 --> <splitOrder v-bind="$attrs" v-on="$listeners" :shipmentObj="shipmentObj" v-if="dialogConfig.type === 'splitOrder' && dialogConfig.dialogVisible" :currRow="currRow" @closeDialog2="closeDialog2" /> </el-dialog> </div> </template> <script> import dayjs from "dayjs"; import supplementOrder from "./supplementOrder.vue"; import { getCabinetPage } from "@/api/ecw/cabinet"; import { getbox } from "@/api/ecw/box"; import { loadSecGoodsList, orderTagList, singleCreate, batchCreate, singleDelete, batchDelete, remove, boxUpdate, approvalCreate, approvalCancel, getOrderDetailByBoxNo, externalLoad, } from "@/api/ecw/boxSea"; import { getTotlContent, serviceMsg, getCapacity, sumStatistics, toReviewDetail, } from "../../utils"; import splitOrder from "./splitOrder.vue"; import WorkFlow from "@/components/WorkFlow"; import Decimal from "decimal.js"; /** * 开始装柜 */ export default { name: "startPacking", inheritAttrs: false, components: { supplementOrder, splitOrder, WorkFlow, }, props: { shipmentObj: Object, }, data() { return { // 表格数据 listData: [], // 表格数据 tableData: {}, // 弹窗配置 dialogConfig: { title: "", dialogVisible: false, width: "30%", type: "", fullscreen: false, }, // 已装/未装 orderList: [], // 柜型 cabinetList: [], // 二维码/条码编号 qrCode: "", // 批量输入 batchObj: { boxNum: 0, }, // 批量纠错(订单号) orderObj: {}, // 纠错 correctionObj: {}, // 修改柜信息 modifyCabinetObj: {}, // 修改柜信息校验 rules: { startWarehouseId: [ { required: true, message: this.$t("必填"), trigger: "change" }, ], cabinetId: [ { required: true, message: this.$t("必填"), trigger: "change" }, ], qrCode: [ { required: true, message: this.$t("必填"), trigger: "change" }, ], orderNo: [ { required: true, message: this.$t("必填"), trigger: "change" }, ], }, // 当前行 currRow: {}, selectedUsers: [], // 订单信息 boxOrderInfo: {}, newshipmentObj: {} }; }, created() { this.getLoadSecGoodsList(); // 柜型 getCabinetPage(null).then((response) => { this.cabinetList = response.data.list; }); // this.getBoxInfo() }, methods: { getTotlContent, getBoxInfo() { getbox(this.shipmentObj.id).then((res) => { const { data } = res; this.newshipmentObj = data ?? {}; }); }, /* 装柜部分列表 */ getLoadSecGoodsList() { loadSecGoodsList({ shipmentId: this.shipmentObj.id }).then((res) => { const { data = [] } = res; this.listData = data.map((item, index) => { return { ...item, title: this.$t("第{index}部分", { index: 1 + index }), }; }); if (this.listData.length) { this.tableData = this.listData[0]; } }); }, /** 点击事件统一入口 */ handlerClick(type, title) { this.shwoDialog({ type, title }); }, /* 拆单 */ handlerSplitOrder(row, type, title) { this.currRow = row; this.shwoDialog({ type, title }); }, /** 表格订单号点击 */ orderClick(row) { orderTagList({ orderId: row.orderId }).then((res) => { const { data = {} } = res; this.orderList = []; // 取最长的list let dataLength = data.loadList.length; if (data.unLoadList.length > dataLength) { dataLength = data.unLoadList.length; } // 组装数据,用一个table组件渲染 for (let index = 0; index < dataLength; index++) { this.orderList.push({ loadTag: data.loadList[index], unloadTag: data.unLoadList[index], }); } }); this.shwoDialog({ type: "orderTable", title: row.selfNo, }); }, /** 弹窗事件 */ shwoDialog(config) { this.$set(this.dialogConfig, "title", config.title); this.$set(this.dialogConfig, "type", config.type); switch (config.type) { case "orderTable": this.$set(this.dialogConfig, "fullscreen", false); break; case "supplementOrder": this.$set(this.dialogConfig, "fullscreen", true); break; case "batchInput": this.$set(this.dialogConfig, "fullscreen", false); this.batchObj = { boxNum: 0 }; this.boxOrderInfo = {}; break; case "correction": this.$set(this.dialogConfig, "fullscreen", false); this.correctionObj = {}; break; case "correctionOrder": this.$set(this.dialogConfig, "fullscreen", false); this.orderObj = {}; break; case "modifyCabinet": this.$set(this.dialogConfig, "fullscreen", false); this.modifyCabinetObj = {}; this.$set(this.modifyCabinetObj,'cabinetId',this.shipmentObj.cabinetId) this.$set(this.modifyCabinetObj,'cubNo',this.shipmentObj.cubNo) break; case "splitOrder": this.$set(this.dialogConfig, "fullscreen", true); break; } this.$set(this.dialogConfig, "dialogVisible", true); }, /** 关闭弹窗 */ closeDialog2() { this.$set(this.dialogConfig, "dialogVisible", false); }, /** 修改提交 */ onSubmit(formName) { this.$refs[formName].validate((valid) => { if (valid) { if (formName === "batchForm") { this.handlerBatchCreate("batch"); } if (formName === "correctionForm") { this.handlerBatchDelete( { orderNumCode: this.correctionObj.qrCode, }, "single" ); } if (formName === "orderForm") { this.handlerBatchDelete( { orderNo: this.orderObj.orderNo }, "batch" ); } if (formName === "modifyForm") { this.modifyBoxUpdate(); } } }); }, /* 部分点击 */ partClick(item) { this.tableData = item; }, /* 装柜 */ handlerBatchCreate(type) { let params = { shipmentId: this.shipmentObj.id, secId: this.tableData.id, }; if (type === "single") { if (!this.qrCode) { this.$message.error(this.$t("请输入二维码/条码编号")); return; } params.orderNumCode = this.qrCode; singleCreate(params).then((res) => { serviceMsg(res, this).then(() => { this.qrCode = ""; this.getLoadSecGoodsList(); }); }); } else { params.orderNo = this.batchObj.qrCode; batchCreate(params).then((res) => { serviceMsg(res, this).then(() => { this.closeDialog2(); this.getLoadSecGoodsList(); }); }); } }, /* 删除已装柜 */ handlerBatchDelete(params, type) { params = { shipmentId: this.shipmentObj.id, secId: this.tableData.id, ...params, }; if (type === "single") { singleDelete(params).then((res) => { serviceMsg(res, this).then(() => { this.closeDialog2(); this.getLoadSecGoodsList(); }); }); } else { batchDelete(params).then((res) => { serviceMsg(res, this).then(() => { this.closeDialog2(); this.getLoadSecGoodsList(); }); }); } }, /* 移出 */ moveOut(row) { let params = { shipmentId: this.shipmentObj.id, secId: this.tableData.id, orderId: row.orderId, }; remove(params).then((res) => { serviceMsg(res, this).then(() => { this.getLoadSecGoodsList(); }); }).catch((res) => { if (res.code === 666) { this.$confirm("<div style='max-height:500px;overflow:auto'>"+res.msg+this.$t('是否需要一起移出?')+"</div>", this.$t("提示"), { dangerouslyUseHTMLString: true, distinguishCancelAndClose: true, confirmButtonText: '确定移出', cancelButtonText: '仅移出当前订单' }) .then((_) => { remove({ ...params, deleteType: 2 }).then((res) => { serviceMsg(res, this).then(() => { this.getLoadSecGoodsList(); }); }); }) .catch(action => { if(action =='cancel'){ remove({ ...params, deleteType: 1 }).then((res) => { serviceMsg(res, this).then(() => { this.getLoadSecGoodsList(); }); }); } }); } }); }, /* 修改柜信息 */ modifyBoxUpdate() { let params = { shipmentId: this.shipmentObj.id, ...this.modifyCabinetObj, }; boxUpdate(params).then((res) => { serviceMsg(res, this); // this.getBoxInfo() this.$emit('getBoxInfo') this.closeDialog2(); }); }, /* 补单完成 */ supplementFinish() { this.closeDialog2(); this.getLoadSecGoodsList(); }, /* 申请封柜 */ applyCloseCabinet() { approvalCreate({ applyReason: this.$t("封柜审核"), approvalStatus: 0, approvalType: 2, // 封柜 copyUserId: this.selectedUsers, shipmentId: this.shipmentObj.id, }).then((res) => { serviceMsg(res, this).then(() => { this.$emit("closeDialog1", "submit"); }); }); }, /* 是否显示拆单 */ isShowSplitOrder(row) { if (row.num > row.installNum && row.installNum !== 0) { return true; } return false; }, /* 取消审核 */ canclAudit() { approvalCancel({ applyReason: this.$t("取消审核"), id: this.shipmentObj["cabinetApprovalInfo"].id, shipmentId: this.shipmentObj.id, }).then((res) => { serviceMsg(res, this).then(() => { this.$emit("closeDialog1", "submit"); }); }); }, /* 跳转详情 */ jumpReviewDetail() { const { cabinetApprovalInfo } = this.shipmentObj; toReviewDetail.apply(this, [cabinetApprovalInfo.bpmProcessId]); this.$emit("closeDialog1", "close"); }, queryOrderInfo() { this.$refs["batchForm"].validate((valid) => { if (valid) { getOrderDetailByBoxNo({ orderNumCode: this.batchObj.qrCode, shipmentId: this.shipmentObj.id, }).then((res) => { const { data } = res; this.boxOrderInfo = data; this.batchObj.boxNum = Number(data.num); }); } }); }, batchLoad() { if (!this.boxOrderInfo.orderId) { this.$message.error(this.$t("请输入订单号")); return; } if (this.batchObj.boxNum === 0) { this.$message.error(this.$t("箱数不能为0")); return; } let params = { boxNum: this.boxOrderInfo.num, orderId: this.boxOrderInfo.orderId, orderNo: this.boxOrderInfo.orderNo, shipmentId: this.shipmentObj.id, }; if (this.boxOrderInfo.isExternalWarehouse === 1) { params.boxNum = this.batchObj.boxNum; } externalLoad(params).then((res) => { serviceMsg(res, this).then(() => { this.closeDialog2(); this.boxOrderInfo = {}; this.getLoadSecGoodsList(); }); }); }, }, computed: { /* 是否审核中 */ isUnderReview() { const { currNode } = this.$attrs; return this.shipmentObj[currNode.keyName] === 44 ? true : false; }, /* 预计时间 */ preinstallDate() { if (this.shipmentObj.preInstallInfo.createTime) { return dayjs(this.shipmentObj.preInstallInfo.createTime).format( "YYYY-MM-DD HH:mm:ss" ); } return null; }, /* 容量 */ calcCapacity() { const { cabinetRespVO } = this.shipmentObj; return getCapacity(cabinetRespVO); }, /* 总计 */ getSumData() { return sumStatistics(this.listData); }, /* 已装总数 */ getInstallNumCount() { let count = 0; if (Array.isArray(this.listData)) { this.listData.forEach((item) => { const { sectionOrderList = [] } = item; sectionOrderList.forEach((item) => { count = Decimal.add(count, item.installNum).toNumber(); }); }); } return count; }, }, }; </script> <style lang="scss" scoped> .startPacking { display: flex; flex-direction: column; p { margin: 0; } .content-area { display: flex; .left-area { border-right: 3px solid #e6ebf5; padding-right: 10px; .title-info { height: 80px; &.selected { > div:first-child { background-color: #4f9cdd; color: #fff; } } > div:first-child { font-size: 16px; background-color: #f2f2f2; line-height: 30px; text-align: center; cursor: pointer; } > :last-child { display: flex; > p { margin-right: 10px; color: #4f9cdd; } } } } .right-area { padding-left: 10px; .table-title { display: flex; align-items: center; margin-bottom: 10px; > div:first-child { flex: 1; font-size: 16px; } > div:last-child { display: flex; > .el-input { margin-right: 10px; } } } .table-content { .table-goodList { .goodList-div { border-bottom: 1px solid #e6ebf5; > p { text-align: left; } > p:last-child { > span { margin-right: 5px; } } } > div:last-child { border-bottom: none; } } .el-table { color: red; } } } } .totle-info { font-size: 20px; margin-top: 15px; > div { display: flex; margin-bottom: 5px; } .count-info { > p > span { margin-right: 5px; } } } .process-area { margin-top: 15px; padding-bottom: 30px; .process { display: flex; flex-direction: column; > :first-child { color: #606266; font-weight: bolder; font-size: 16px; } } } } </style>