<template> <div> <el-form ref="cusDeclarationForm" :rules="rules" :model="cusDeclarationObj" label-width="120px"> <el-form-item label="单证要求"> <template v-for="(item, index) in cusDeclarationObj.documentInfo"> <dict-tag :type="DICT_TYPE.ECW_CUSTOMS_TYPE" :value="item" :key="index" /> </template> <el-button type="primary" style="margin-left:10px;" @click="downloadVGM">{{getButtonLabel(cusDeclarationObj.documentInfo)}}</el-button> </el-form-item> <el-form-item label="柜重" prop="dcBoxWgt"> <el-input v-model="cusDeclarationObj.dcBoxWgt" placeholder="请输入柜重" clearable /> </el-form-item> <el-form-item label="货重" prop="dcGoodsWgt"> <el-input v-model="cusDeclarationObj.dcGoodsWgt" placeholder="请输入货重" clearable /> </el-form-item> <el-form-item label="VGM重量"> <el-input v-model="cusDeclarationObj.dcVgmWgt" placeholder="请输入VGM重量" clearable /> </el-form-item> <el-form-item label="报关方式" prop="dcCustomsType"> <el-select v-model="cusDeclarationObj.dcCustomsType" placeholder="请选择报关方式"> <el-option v-for="type in this.getDictDatas(DICT_TYPE.BOX_SHIPPING_CUSTOMS_TYPE)" :key="type.value" :label="type.label" :value="type.value"></el-option> </el-select> </el-form-item> <el-form-item label="正常报关订单"> </el-form-item> <el-form-item label="报关公司名称"> <supplierSelect v-model="cusDeclarationObj.dcCompanyId" :companyType="'2'" placeholder="请选择报关公司名称" :allSupplier="this.$attrs.allSupplier" /> </el-form-item> <el-form-item label="截关时间"> <el-date-picker type="datetime" placeholder="请选择日期" v-model="cusDeclarationObj.dcCutOffTime" value-format="yyyy-MM-dd HH:mm:ss"></el-date-picker> </el-form-item> <el-form-item label="状态" prop="dcCustomsStatus"> <el-radio-group v-model="cusDeclarationObj.dcCustomsStatus" :disabled="inReview || isCheckDeal"> <el-radio v-for="item in this.getDictDatas(DICT_TYPE.BOX_SHIPPING_DCCUSTOMS_STATUS)" :key="item.value" :label="item.value">{{item.label}}</el-radio> </el-radio-group> </el-form-item> <!-- 查验 --> <div v-show="cusDeclarationObj.dcCustomsStatus === '3'"> <el-form-item label="查验"> <el-radio-group v-model="cusDeclarationObj.dcCheckStatus" :disabled="inReview || isCheckDeal"> <el-radio v-for="item in this.getDictDatas(DICT_TYPE.BOX_SHIPPING_CHECK_STATUS)" :key="item.value" :label="item.value" :disabled="disabledRadio(item)">{{item.label}}</el-radio> </el-radio-group> </el-form-item> </div> <!-- 退场 --> <div v-show="['1','2','3'].includes(cusDeclarationObj.dcCheckStatus)"> <el-form-item label="查验时间"> <el-date-picker type="datetime" placeholder="请选择日期" v-model="cusDeclarationObj.dcCheckTime" value-format="yyyy-MM-dd HH:mm:ss"></el-date-picker> </el-form-item> <el-form-item label="查验前图片"> <ImageUpload :limit="1" :isShowTip=false v-model="cusDeclarationObj.dcCheckPreImg" /> </el-form-item> <el-form-item label="新封条"> <el-input v-model="cusDeclarationObj.dcStripSeal" placeholder="请输入新封条" clearable /> </el-form-item> <el-form-item label="退场状态" v-if="cusDeclarationObj.dcCheckStatus === '1' || cusDeclarationObj.dcCheckStatus === '2'"> {{getCheckExamineStatus}} </el-form-item> </div> <!-- 放行 --> <el-form-item label="放行时间" v-show="cusDeclarationObj.dcCustomsStatus === '2' || cusDeclarationObj.dcCheckStatus === '3'"> <el-date-picker type="datetime" placeholder="请选择日期" v-model="cusDeclarationObj.dcPassTime" value-format="yyyy-MM-dd HH:mm:ss"></el-date-picker> </el-form-item> <!-- <el-form-item label="装箱单"> <el-button type="primary">下载装箱单</el-button> </el-form-item> --> <el-form-item label="报关单"> <el-button type="primary" @click="downloadCusFile">下载所有报关单</el-button> </el-form-item> </el-form> <el-row class="operate-button" v-if="inReview"> <el-button type="primary" @click="jumpReviewDetail">{{cusDeclarationObj.dcCheckStatus === '1' ? '全部退场审核中' : '部分退场审核中'}}</el-button> <el-button type="primary" plain @click="canclAudit">{{cusDeclarationObj.dcCheckStatus === '1' ? '取消全部退场审核' : '取消部分退场审核'}}</el-button> </el-row> <el-row class="operate-button"> <el-button type="primary" @click="onSubmit(1)" :disabled="isCheckDeal">保存</el-button> <el-button type="success" v-if="!inReview" @click="onSubmit(2)" :disabled="isCheckDeal">提交</el-button> <el-button @click="cancel">关闭</el-button> <el-button type="primary" @click="extraCost" v-show="cusDeclarationObj.dcCustomsStatus === '2' || cusDeclarationObj.dcCustomsStatus === '3'">额外费用</el-button> </el-row> <!-- 对话框 --> <el-dialog custom-class="shipping-dialog customsClearance" :title="dialogConfig.title" :visible.sync="dialogConfig.dialogVisible" width="700px" :modal-append-to-body=false append-to-body> <el-row> <el-row> <el-form label-width="100px"> <el-form-item label="订单号" class="two-element"> <el-input v-model="orderNo" placeholder="请输入订单号" clearable /> <el-button type="primary" icon="el-icon-search" @click="searchOrder"></el-button> </el-form-item> </el-form> </el-row> <el-row> <el-table :data="costOrderList"> <el-table-column label="订单号" align="center" prop="orderNo" /> <el-table-column label="报关费用" align="center" prop="fee"> <template slot-scope="scope"> <el-input-number v-model="scope.row.fee" controls-position="right" :min="1"></el-input-number> </template> </el-table-column> <el-table-column label="操作" align="center" class-name="small-padding fixed-width"> <template slot-scope="scope"> <el-button type="primary" size="small" @click="createExtraCost(scope.row)">确定</el-button> </template> </el-table-column> </el-table> </el-row> <el-row class="cost-title"> <div>额外费用订单</div> <div> <el-button size="small" @click="restCostList()">重置</el-button> </div> </el-row> <el-row> <el-table :data="costList"> <el-table-column type="selection" width="55" /> <el-table-column label="订单号" align="center" prop="orderNo" /> <el-table-column label="报关费用" align="center" prop="fee" width="220px"> <template slot-scope="scope"> <el-input-number v-model="scope.row.fee" controls-position="right" :min="1"></el-input-number> </template> </el-table-column> <el-table-column label="操作" align="center" class-name="small-padding fixed-width"> <template slot-scope="scope"> <el-button type="primary" size="small" @click="updateExtraCost(scope.row)">修改</el-button> <el-button size="small" @click="restCostList(scope.row)">重置</el-button> </template> </el-table-column> </el-table> </el-row> </el-row> </el-dialog> </div> </template> <script> import supplierSelect from "./common/supplierSelect.vue"; import { customsCreate, extraCostList, extraCostOrder, extraCostCreate, extraCostUpdate, approvalCancel, } from "@/api/ecw/boxSea"; import { formatNumberString, formatDateStr, serviceMsg, toReviewDetail, downloadFile, } from "../utils"; import ImageUpload from "@/components/ImageUpload"; /** * 报关 */ export default { name: "cusDeclaration", inheritAttrs: false, components: { supplierSelect, ImageUpload }, props: { shipmentObj: Object, }, data() { return { // 报关对象 cusDeclarationObj: {}, // 校验 rules: { dcBoxWgt: [{ required: true, message: "必填", trigger: "change" }], dcGoodsWgt: [{ required: true, message: "必填", trigger: "change" }], dcCustomsType: [{ required: true, message: "必填", trigger: "change" }], dcCustomsStatus: [ { required: true, message: "必填", trigger: "change" }, ], }, // 弹窗配置 dialogConfig: { title: "", dialogVisible: false, }, // 订单号 orderNo: "", // 订单列表 costOrderList: [], // 额外费用列表 costList: [], // 是否审核中 inReview: false, }; }, created() { const { currNode } = this.$attrs; const { voName } = currNode; let oldData = { ...this.shipmentObj[voName], documentInfo: this.shipmentObj.documentInfo?.split(",") ?? [], }; oldData = formatDateStr(oldData, [ "dcCutOffTime", "dcCheckTime", "dcPassTime", ]); oldData = formatNumberString(oldData, [ "dcCustomsType", "dcCustomsStatus", "dcCheckStatus", ]); this.cusDeclarationObj = oldData; }, methods: { getButtonLabel(documentInfo = []) { const newList = Array.from(new Set(documentInfo)); return newList.length > 2 ? "混合报关" : "VGM声明"; }, submitCustomsCreate(operateType) { customsCreate({ ...this.cusDeclarationObj, shipmentId: this.shipmentObj.id, operateType, }).then((res) => { serviceMsg(res, this).then(() => { this.cancel("submit"); }); }); }, /** 提交 */ onSubmit(operateType) { this.$refs["cusDeclarationForm"].validate((valid) => { if (valid) { if (operateType === 1) { this.submitCustomsCreate(operateType); return; // 保存 } // 提交 const { dcCustomsStatus, dcCheckStatus } = this.cusDeclarationObj; // 1.状态 报关中/放行 直接提交 if (dcCustomsStatus !== "3") { this.submitCustomsCreate(operateType); return; } // 2.查验状态,空 直接提交 if (!dcCheckStatus) { this.submitCustomsCreate(operateType); return; } // 3.查验状态,查验后放行 直接提交 if (dcCheckStatus === "3") { const { checkExamineStatus } = this.shipmentObj; // 没有退场审核中的状态 if (checkExamineStatus !== 1) { this.submitCustomsCreate(operateType); return; } } // 4.查验状态,退场/部分退场 提示 if (["1", "2"].includes(dcCheckStatus)) { const { checkExamineStatus } = this.shipmentObj; // 退场审核状态,1-审核中,2-审核成功,3-审核失败,4-取消 if ([0, 2, 3, 4].includes(checkExamineStatus)) { this.$modal .confirm( `您确认提交${ dcCheckStatus === "1" ? "全部退场" : "部分退场" }审核吗?` ) .then(() => { customsCreate({ ...this.cusDeclarationObj, shipmentId: this.shipmentObj.id, operateType, }).then((res) => { serviceMsg(res, this).then(() => { // 触发外层重新查询出货信息 this.$emit("getBoxInfo"); }); }); }); } else { this.submitCustomsCreate(operateType); } } } }); }, /* 查询订单号 */ searchOrder() { if (!this.orderNo) { this.$message.error("请输入订单号"); return; } extraCostOrder({ shipmentId: this.shipmentObj.id, orderNo: this.orderNo, }).then((res) => { this.costOrderList = [ { orderNo: this.orderNo, orderId: res.data, }, ]; this.searchCostList(res.data); }); }, /* 查询额外费用订单 */ searchCostList(orderId) { extraCostList({ shipmentId: this.shipmentObj.id, orderId: orderId, }).then((res) => { this.costList = res.data.map((item) => { return { originalFee: item.fee, ...item }; }); }); }, /* 创建额外费用 */ createExtraCost(row) { if (!row.fee) { this.$message.error("请输入费用"); return; } extraCostCreate({ fee: row.fee, orderId: row.orderId, orderNo: row.orderNo, shipmentId: this.shipmentObj.id, }).then((res) => { serviceMsg(res, this).then(() => { this.searchCostList(row.orderId); }); }); }, /* 修改额外费用 */ updateExtraCost(row) { if (!row.fee) { this.$message.error("请输入费用"); return; } extraCostUpdate(row).then((res) => { serviceMsg(res, this).then(() => { this.searchCostList(row.orderId); }); }); }, /* 重置 */ restCostList(row) { this.costList = this.costList.map((item) => { if (row && row.id === item.id) { return { ...item, fee: item.originalFee, }; } if (!row) { return { ...item, fee: item.originalFee, }; } return item; }); }, /** 取消 */ cancel(type) { this.$emit("closeDialog", type); }, // 下载VGM downloadVGM() { window.open( "http://pdatest.groupage.cn//apivue/boxTrack/vgmExport?token=930b11a41d9ca06f306d157f336a5dcb&id=1752" ); }, // 额外费用 extraCost() { // 清空额外费用 this.orderNo = ""; this.costOrderList = []; this.costList = []; this.$set( this.dialogConfig, "title", `${this.shipmentObj.selfNo} 报关费用` ); this.$set(this.dialogConfig, "dialogVisible", true); }, // 计算VGM重量 calcVGM(dcBoxWgt, dcGoodsWgt) { let dcBoxWgtTmp = 0, dcGoodsWgtTmp = 0; if (!Number.isNaN(Number(dcBoxWgt))) { dcBoxWgtTmp = Number(dcBoxWgt); } if (!Number.isNaN(Number(dcGoodsWgt))) { dcGoodsWgtTmp = Number(dcGoodsWgt); } this.$set( this.cusDeclarationObj, "dcVgmWgt", dcBoxWgtTmp + dcGoodsWgtTmp ); }, // 审核详情 jumpReviewDetail() { const { customsApprovalInfo } = this.shipmentObj; toReviewDetail.apply(this, [customsApprovalInfo.bpmProcessId]); this.cancel("close"); }, /* 取消审核 */ canclAudit() { approvalCancel({ applyReason: "取消审核", id: this.shipmentObj["customsApprovalInfo"].id, shipmentId: this.shipmentObj.id, }).then((res) => { serviceMsg(res, this).then(() => { // 触发外层重新查询出货信息 this.cancel("close"); this.$emit("getBoxInfo"); }); }); }, /* 判断查验选择是否禁用 */ disabledRadio(item) { const { checkExamineStatus, checkDealStatus, customsInfo = {}, } = this.shipmentObj; const { dcCheckStatus } = customsInfo; // 部分退场状态并且审核通过,退场不可选择 if ( checkExamineStatus === 2 && dcCheckStatus === 2 && item.value === "1" ) { return true; } return false; }, /* 下载报关单 */ downloadCusFile() { downloadFile( "downloadCustomFiles", { shipmentId: this.shipmentObj.id }, `报关单(${this.shipmentObj.selfNo}).xlsx`, "xlsx" ); }, }, watch: { "cusDeclarationObj.dcBoxWgt"(dcBoxWgt) { this.calcVGM(dcBoxWgt, this.cusDeclarationObj.dcGoodsWgt); }, "cusDeclarationObj.dcGoodsWgt"(dcGoodsWgt) { this.calcVGM(this.cusDeclarationObj.dcBoxWgt, dcGoodsWgt); }, "cusDeclarationObj.dcCustomsStatus"(val) { if (val !== "3") { this.$set(this.cusDeclarationObj, "dcCheckStatus", ""); } else { const { customsInfo = {} } = this.shipmentObj; this.$set( this.cusDeclarationObj, "dcCheckStatus", (customsInfo.dcCheckStatus && String(customsInfo.dcCheckStatus)) || "3" ); } }, shipmentObj: { deep: true, immediate: true, handler: function (val) { // 监听查验状态变化 let { checkExamineStatus } = val; if (checkExamineStatus === 1) { // 按钮变成审核中 this.inReview = true; } }, }, }, computed: { /* 获取报关审核退场状态文字 */ getCheckExamineStatus() { const { checkExamineStatus, customsInfo = {} } = this.shipmentObj; const { dcCheckStatus } = customsInfo; if (checkExamineStatus === 1) { return dcCheckStatus === 1 ? "退场审核中" : "部分退场审核中"; } if (checkExamineStatus === 2) { return dcCheckStatus === 1 ? "审核通过,退场中" : "审核通过,部分退场中"; } return "未审核"; }, /* 判断是否已处理 */ isCheckDeal() { const { checkExamineStatus, checkDealStatus, customsInfo = {}, } = this.shipmentObj; const { dcCheckStatus } = customsInfo; // 退场未处理不能操作 if ( checkExamineStatus === 2 && dcCheckStatus === 1 && checkDealStatus === 0 ) { return true; } return false; }, }, }; </script> <style lang="scss"> .customsClearance { .cost-title { display: flex; align-items: center; margin: 20px 0; border-left: 5px solid gray; > div:first-child { margin-left: 10px; } > div:last-child { flex: 1; text-align: right; } } } </style>