emis-frontend/src/views/emis/emisWaybill/batchWaybillRecord.vue
2025-06-21 10:29:14 +08:00

673 lines
25 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<XdPageContainer class="app-container">
<div slot="pageHeader"></div>
<XdTable
slot="pageContent"
slot-scope="slotProps"
:height="(slotProps.contentHeight)+'px'"
storageName="batchWaybillRecord_main"
ref="multipleTable"
:row-class-name="tableRowClassName"
v-loading="loading"
border
size="mini"
:data="orderList"
:showSearch.sync="showSearch"
:queryParams="queryParams"
:total="total"
@queryTable="getList"
@selection-change="handleSelectionChange"
@sort-change="handleSortChange"
>
<div slot="toolbar">
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button plain class="filter-item" size="mini" type="primary" icon="el-icon-upload2" @click="handleBatchImport">选择文件</el-button>
<el-link type="primary" style="line-height: 28px;font-size:13px;color:blue" href="/static/tpl/batch_import_order.xls">下载导入Excel模板</el-link>
</el-col>
<el-col :span="1.5">
<el-button
type="primary"
plain
size="mini"
@click="handleRealUploadAll"
>批量下单</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
>删除</el-button>
</el-col>
</el-row>
</div>
<el-table-column type="selection" width="55" align="center" />
<el-table-column :label="$t('状态')" align="center" prop="uploadStatus" min-width="80" :show-overflow-tooltip="true" >
<template slot-scope="scope">
<el-tag v-if="scope.row.uploadStatus==1" type="success">下单成功</el-tag>
<el-tag v-if="scope.row.uploadStatus==0" type="info">待下单</el-tag>
<el-tag v-if="scope.row.uploadStatus==-1" type="danger">下单异常</el-tag>
</template>
</el-table-column>
<el-table-column :label="$t('异常信息')" align="center" prop="errorInfo" min-width="300" :show-overflow-tooltip="true" >
<template slot-scope="scope">
<span v-if="scope.row.uploadStatus==-1" style="color:red">{{ scope.row.errorInfo }}</span>
<span v-if="scope.row.uploadStatus==1">下单成功</span>
<span v-if="scope.row.uploadStatus==0">待下单</span>
</template>
</el-table-column>
<el-table-column :label="$t('运单号')" align="center" prop="billCode" min-width="120" :show-overflow-tooltip="true" />
<el-table-column :label="$t('线路')" align="center" prop="transLineType" min-width="80" :show-overflow-tooltip="true"/>
<el-table-column :label="$t('产品类型')" align="center" prop="productType" min-width="80" :show-overflow-tooltip="true"/>
<el-table-column :label="$t('取件方式')" align="center" prop="pickupMethod" width="100" />
<el-table-column :label="$t('取件员/操作员')" align="center" prop="operateEmployeeCode" min-width="100"/>
<el-table-column :label="$t('报关方式')" align="center" prop="customsEclaration" min-width="80" />
<el-table-column :label="$t('清关方式')" align="center" prop="customsClear" min-width="80" />
<el-table-column :label="$t('回款联系人')" align="center" prop="payee" min-width="100" />
<el-table-column :label="$t('销售联系人')" align="center" prop="salesmen" min-width="100" />
<el-table-column :label="$t('收件人')" align="center" prop="receiveName" min-width="80" :show-overflow-tooltip="true"/>
<el-table-column :label="$t('收件电话')" align="center" prop="receiveMobile" min-width="80" :show-overflow-tooltip="true"/>
<el-table-column :label="$t('收件公司')" align="center" prop="receiveCompany" min-width="80" :show-overflow-tooltip="true"/>
<el-table-column :label="$t('收件国家')" align="center" prop="receiveCountry" min-width="80" :show-overflow-tooltip="true"/>
<el-table-column :label="$t('收件省')" align="center" prop="receiveProvince" min-width="80" :show-overflow-tooltip="true"/>
<el-table-column :label="$t('收件市')" align="center" prop="receiveCity" min-width="80" :show-overflow-tooltip="true"/>
<el-table-column :label="$t('收件区')" align="center" prop="receiveCounty" min-width="80" :show-overflow-tooltip="true"/>
<el-table-column :label="$t('收件地址')" align="center" prop="receiveAddress" min-width="80" :show-overflow-tooltip="true"/>
<el-table-column :label="$t('寄件人')" align="center" prop="sendName" min-width="80" :show-overflow-tooltip="true"/>
<el-table-column :label="$t('寄件手机')" align="center" prop="sendMobile" min-width="80" :show-overflow-tooltip="true"/>
<el-table-column :label="$t('寄件公司')" align="center" prop="sendCompany" min-width="80" :show-overflow-tooltip="true"/>
<el-table-column :label="$t('寄件国家')" align="center" prop="sendCountry" min-width="80" :show-overflow-tooltip="true" />
<el-table-column :label="$t('寄件省')" align="center" prop="sendProvince" min-width="80" :show-overflow-tooltip="true"/>
<el-table-column :label="$t('寄件市')" align="center" prop="sendCity" min-width="80" :show-overflow-tooltip="true"/>
<el-table-column :label="$t('寄件区')" align="center" prop="sendCounty" min-width="80" :show-overflow-tooltip="true"/>
<el-table-column :label="$t('寄件地址')" align="center" prop="sendAddress" min-width="80" :show-overflow-tooltip="true"/>
<el-table-column :label="$t('月结客户')" align="center" prop="custNo" min-width="80" :show-overflow-tooltip="true"/>
<el-table-column :label="$t('寄件/签收短信')" align="center" prop="blMessage" min-width="80" :show-overflow-tooltip="true"/>
<el-table-column :label="$t('货物名称')" align="center" prop="goodsInfo" min-width="80" :show-overflow-tooltip="true"/>
<el-table-column :label="$t('包装类型')" align="center" prop="packType" min-width="80" />
<el-table-column :label="$t('件数')" align="center" prop="parcelQty" min-width="80" />
<el-table-column :label="$t('实际重量')" align="center" prop="billWeight" min-width="80" />
<el-table-column :label="$t('体积')" align="center" prop="totalVolume" min-width="80" />
<el-table-column :label="$t('派件方式')" align="center" prop="dispatchMethod" min-width="80" />
<el-table-column :label="$t('支付类型')" align="center" prop="paymentType" min-width="80" :show-overflow-tooltip="true" />
<el-table-column :label="$t('运费')" align="center" prop="freight" min-width="80" />
<el-table-column :label="$t('费用备注')" align="center" prop="feeRemark" min-width="80" :show-overflow-tooltip="true"/>
<el-table-column :label="$t('录单备注')" align="center" prop="remark" min-width="80" :show-overflow-tooltip="true"></el-table-column>
<el-table-column :label="$t('货值')" align="center" prop="realValue" min-width="80" />
<el-table-column :label="$t('附加信息')" align="center" prop="extInfo" min-width="80" :show-overflow-tooltip="true"/>
<el-table-column :label="$t('是否虚拟单')" align="center" prop="blVirtual" min-width="80" :show-overflow-tooltip="true"/>
<el-table-column :label="$t('关联主单')" align="center" prop="masterBillCode" min-width="80" :show-overflow-tooltip="true"/>
</XdTable>
<el-dialog title="上传文件" :visible.sync="openUploadForm" width="50%" v-dialogDrag :destroy-on-close="true" :close-on-click-modal="false" append-to-body>
<el-row :gutter="0">
<el-form ref="form" :model="form" :rules="rules" size="mini" label-width="80px">
<el-col :span="24">
<el-form-item label="选择文件" prop="uploadFile" >
<el-upload
action=""
name="file"
accept="application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
:show-file-list="true"
:limit="1"
:file-list="fileList"
:tooltip="fileName"
:on-change="fileChange"
:before-upload="beforeUpload">
<el-button slot="trigger" plain class="filter-item" size="mini" type="primary" >选择文件</el-button>
<el-link type="primary" style="line-height: 28px;font-size:13px;color:blue" href="/static/tpl/batch_import_order.xls">下载导入Excel模板</el-link>
<div v-if="uploadExcelDataInfo !=''" style="color: black;font-size: 12px;font-weight: 800;">{{ fileName }} {{ uploadExcelDataInfo }}</div>
</el-upload>
<el-alert
title="注意"
type="info"
description="仅允许导入“xls”或“xlsx”格式文件!"
close-text="知道了">
</el-alert>
</el-form-item>
</el-col>
</el-form>
</el-row>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="batchImpDataForm">确 定</el-button>
<el-button @click="cancel">取 消</el-button>
</div>
</el-dialog>
</XdPageContainer>
</template>
<script>
import { listEmisWaybill, draftSubmitOrder } from "@/api/emis/emisWaybill";
import { parseTime } from "@/utils/custom";
import {timeDiffTime,timeFormat} from '@/utils/dateUtils'
import { formatSearchStr,deepClone } from '@/utils/index'
import XLSX from 'xlsx'
export default {
name: "BatchWaybillRecord",
components: {
},
dicts: ['emis_qujian_fangshi','emis_declare_mode','emis_customs_clear',
'emis_tab_packing_type','emis_tab_dispatch_mode','emis_payment_type',
'emis_calc_fee_type','emis_print_type','emis_payment_status','emis_waybill_status','emis_tab_dispatch_mode'
],
data() {
return {
resetRefreshId:null,
// 遮罩层
loading: false,
// 选中数组
ids: [],
// 非单个禁用
single: true,
// 非多个禁用
multiple: true,
// 显示搜索条件
showSearch: true,
// 总条数
total: 0,
// 运单列表表格数据
orderList: [],
tmpDataList: [],
selectionList:[],
selectionIndexList: [],
form:{},
rules:{},
openUploadForm:false,
uploadMsg:"",
uploadExcelDataInfo:"",
fileName:"",
fileList:[],
// 查询参数
queryParams: {
pageNum: 1,
pageSize: 20,
orderSn: null,
billCode: null,
billCodeSub: null,
orderStatus: null,
waybillStatus: null,
orderType: null,
orderDate: null,
customerCode: null,
customerName: null,
receiveCustomerCode: null,
receiveCustomerName: null,
thirdCustomerCode: null,
thirdCustomerName: null,
receiveName: null,
receiveCompany: null,
receiveMobile: null,
receiveTel: null,
receiveCountry: null,
receiveProvince: null,
receiveCity: null,
receiveCounty: null,
receiveTown: null,
receiveAddress: null,
receivePostcode: null,
receivePcd: null,
sendName: null,
sendCompany: null,
sendMobile: null,
sendTel: null,
sendCountry: null,
sendProvince: null,
sendCity: null,
sendCounty: null,
sendTown: null,
sendAddress: null,
sendPostcode: null,
sendPcd: null,
paymentType: null,
calcFeeType: null,
custNo: null,
transLineType: null,
productType: null,
timeType: null,
meterType: null,
customsClear: null,
customsEclaration: null,
estimateDate: null,
packType: null,
dispatchMethod: null,
pickupMethod: null,
pickStartDate: null,
pickFinishDate: null,
pickFailReason: null,
intoWarehouseCode: null,
intoWarehouseName: null,
intoWarehouseAddress: null,
intoWarehouseContact: null,
intoWarehousePhone: null,
intoWarehouseBillCode: null,
warehouseInNo: null,
customerDeliveryBeginTime: null,
customerDeliveryEndTime: null,
goodsType: null,
goodsInfo: null,
goodsPics: null,
blPrepareInFreight: null,
prepareInEstFee: null,
prepareInRealFee: null,
prepareInExpress: null,
prepareInBillCode: null,
prepareInRemark: null,
prepareInSupplier: null,
totalWeight: null,
totalVolume: null,
parcelQty: null,
billWeight: null,
volumeWeight: null,
currency: null,
settlementWeight: null,
feeWeight: null,
freight: null,
blOverLong: null,
blBill: null,
blOverWeight: null,
overWeightNumber: null,
feeRemark: null,
thirdCode: null,
realValue: null,
blInsure: null,
insureValue: null,
insureValueCurrency: null,
insureFeeCurrency: null,
insureFee: null,
insureRemark: null,
insureSiteCode: null,
insureDate: null,
blPrint: null,
printManCode: null,
printSite: null,
printDate: null,
printCount: null,
blDispFd: null,
transferCode: null,
transferBillcode: null,
dispFdDate: null,
dispFdReason: null,
currentSiteCode: null,
lastSiteCode: null,
registerSiteCode: null,
registerDate: null,
registerManCode: null,
takePieceEmployeeCode: null,
sendSiteCode: null,
sendDate: null,
dispatchManCode: null,
dispatchDate: null,
dispatchSiteCode: null,
produceBillDate: null,
produceBillSiteCode: null,
produceBillManCode: null,
destinationCode: null,
destinationProvince: null,
destinationCity: null,
destinationCounty: null,
dispatchUnderlingSiteCode: null,
destinationCenterCode: null,
marketManCode: null,
payee: null,
salesmen: null,
operateEmployeeCode: null,
blIsQuestion: null,
problemType: null,
problemCause: null,
problemDelayDays: null,
blMessage: null,
blAcceptMessage: null,
blGenSubbill: null,
signMan: null,
signManCode: null,
signSiteCode: null,
signDate: null,
billPicSendRmk: null,
billPicDispatchRmk: null,
timezoneOffset: null,
delFlag: null,
remark: null,
params:{
blSign:null,
expireNotSign:null,
problemQueryType:null,
}
},
};
},
created() {
if(this.$store.getters.ownerSiteCode!='88888'){
this.queryParams.sendSiteCode=this.$store.getters.ownerSiteCode;
}
},
mounted() {
},
methods: {
getUUID() {
return Math.random().toString(36).substring(3,10);
},
handleBatchImport(){
this.resetRefreshId="importForm-"+this.getUUID();
this.openUploadForm=true;
this.fileList=[];
this.uploadExcelDataInfo="";
this.fileName="";
},
calcDeliveryTime(startData,endDate){
return timeDiffTime(startData,endDate)
},
//标红table指定行
tableRowClassName(row, index) {
row.row.index = row.rowIndex;
if (row.uploadStatus=='1') {
return 'success-row';
}
else if (row.uploadStatus=='-1') {
return 'warning-row';
}
return '';
},
/** 查询运单列表列表 */
getList() {
this.loading = true;
},
fileChange(file, fileList) {
this.fileList = fileList;
},
beforeUpload(file) {
this.fileName = file.name;
this.form.batchName = file.name;
this.readerData(file)
return false
},
readerData(rawFile) {
return new Promise((resolve, reject) => {
const reader = new FileReader()
reader.onload = e => {
const data = e.target.result
const workbook = XLSX.read(data, { type: 'array' })
const firstSheetName = workbook.SheetNames[0] // firstSheetName
// if (!excelTypes.includes(firstSheetName)) {
// reject('无法识别当前Excel模板')
// this.$modal.msgError('无法识别当前Excel模板')
// return
// }
const worksheet = workbook.Sheets[firstSheetName]
// const header = this.getHeaderRow(worksheet) // 标题
const results = XLSX.utils.sheet_to_json(worksheet)
console.log(results);
this.batchImportData(results);
resolve()
}
reader.readAsArrayBuffer(rawFile)
})
},
getHeaderRow(sheet) {
const headers = []
const range = XLSX.utils.decode_range(sheet['!ref'])
let C
const R = range.s.r
/* start in the first row */
for (C = range.s.c; C <= range.e.c; ++C) { /* walk every column in the range */
const cell = sheet[XLSX.utils.encode_cell({ c: C, r: R })]
/* find the cell in the first row */
let hdr = 'UNKNOWN ' + C // <-- replace with your desired default
if (cell && cell.t) hdr = XLSX.utils.format_cell(cell)
headers.push(hdr)
}
return headers
},
async batchImportData(results) {
const _index = 1
let loadingInstance = this.$loading({
text: '正在解析 ' + _index + ' 数据...'
})
this.orderList = [];
let lastOrderSn = '';
let orderIndex = 0;
// 组装提交的数据
for (let index = 0; index < results.length; index++) {
const element = results[index]
// 运单号 收件人 收件电话 收件国 收件省 收件市 收件区 收件公司 收件地址
// 寄件人 寄件电话 寄件国 寄件省 寄件市 寄件区 寄件公司 寄件地址
// 线路 产品类型 报关方式 清关方式 快递员 货物名称 包装类型 件数 实际重量 体积
// 取件方式 派送方式 运费 支付方式 月结客户 回款联系人 销售联系人 费用备注
// 取件员/操作员
// 寄件/签收短信
let rowIndex=element['__rowNum__']
let orderData={
billCode: element['运单号'],
sendDate: parseTime(new Date()),
custNo: element['月结客户'],
receiveName: element['收件人'],
receiveCompany:element['收件公司'],
receiveMobile:element['收件电话'],
receiveCountry: element['收件国'],
receiveProvince: element['收件省'],
receiveCity: element['收件市'],
receiveCounty: element['收件区'],
receiveAddress: element['收件地址'],
sendName: element['寄件人'],
sendCompany: element['寄件公司'],
sendMobile: element['寄件电话'],
sendCountry: element['寄件国'],
sendProvince: element['寄件省'],
sendCity:element['寄件市'],
sendCounty:element['寄件区'],
sendAddress: element['寄件地址'],
paymentType: element['支付方式'],
calcFeeType: element['计费方式'],
transLineType: element['线路'],
productType: element['产品类型'],
customsClear: element['清关方式'],
customsEclaration: element['报关方式'],
packType: element['包装类型'],
dispatchMethod: element['派送方式'],
pickupMethod: element['取件方式'],
goodsInfo: element['货物名称'],
totalVolume: element['体积'],
parcelQty: element['件数'],
billWeight: element['实际重量'],
freight: element['运费'],
feeRemark:element['费用备注'],
payee: element['回款联系人'],
salesmen: element['销售联系人'],
operateEmployeeCode: element['取件员/操作员'],
remark: element['录单备注'],
blMessage: element['寄件/签收短信'],
realValue: element['货值'],
extInfo: element['附加信息'],
blVirtual: element['是否虚拟单'],
masterBillCode: element['关联主单'],
uploadStatus: 0,
errorInfo:'',
}
this.tmpDataList.push(orderData);
}
this.uploadExcelDataInfo="总共 " + this.tmpDataList.length +" 条数据。";
loadingInstance.close()
},
handleRealUploadAll(){
if (this.ids && this.ids.length>0) {
this.$confirm("确认下单吗?", "提示", {
cancelButtonText: "取消",
confirmButtonText: "确认",
type: "warning",
distinguishCancelAndClose: true,
closeOnClickModal: false
}).then(async () => {
if(this.selectionList&&this.selectionList.length>0){
for(let i=0;i<this.selectionList.length;i++){
let orderItem=this.selectionList[i];
let res=await draftSubmitOrder(orderItem)
let rstData=res.data;
if(rstData.result=='success'){
orderItem.uploadStatus=1;
orderItem.errorInfo="下单成功";
orderItem.billCode=rstData.billDetail.billCode;
}
else{
orderItem.uploadStatus=-1;
orderItem.errorInfo=rstData.msg;
}
}
this.$modal.msgSuccess("上传成功");
}
});
}
},
batchImpDataForm() {
// 判断是否有数据
if(this.tmpDataList.length==0){
this.$modal.msgError('表格中没有数据');
return;
}
this.orderList = this.orderList.concat(this.tmpDataList);
//拼接remark 和virtualRemark
this.orderList.forEach((item,index)=>{
if(item.blVirtual ==='是'){
item.remark = `${item.remark},此单为虚拟单,对应主单为:${item.masterBillCode}`
}
})
this.tmpDataList=[];
this.openUploadForm = false;
},
/** 搜索按钮操作 */
handleQuery() {
// this.queryParams.pageNum = 1;
// this.getList();
},
/** 重置按钮操作 */
resetQuery() {
// this.resetForm("queryForm");
// this.handleQuery();
},
// 多选框选中数据
handleSelectionChange(selection) {
this.selectionList=selection;
this.ids = selection.map(item => item.id)
this.single = selection.length!==1
this.multiple = !selection.length
},
// 排序 查询字段是表格中字段名字 动态取值排序顺序
handleSortChange(column) {
this.queryParams.orderByColumn = column.prop;
this.queryParams.isAsc = column.order;
this.getList();
},
cancel(){
this.openUploadForm = false;
},
/** 删除按钮操作 */
handleDelete(row) {
const ids = row.id || this.ids;
let that=this;
this.$modal.confirm('是否确认删除').then(function() {
that.selectionList.forEach((item,index) =>{
that.orderList.forEach((v,i)=>{
if(item.index === v.index){
that.orderList.splice(i,1)
}
})
})
that.$refs.multipleTable.clearSelection();
}).then(() => {
this.$modal.msgSuccess("删除成功");
}).catch(() => {});
},
/** 列索引函数 */
getIndex($index) {
return (this.queryParams.pageNum - 1) * this.queryParams.pageSize + $index + 1
},
}
};
</script>
<style lang="scss" scoped>
:deep .el-form-item__label-wrap {
margin-left: 0 !important;
}
.el-divider{
margin-top: 0px;
background: 0 0;
border-top: 1px solid #E6EBF5;
}
.el-divider__text {
color: #0955ee;
cursor: pointer;
}
.query-label {
.el-radio{
display: block;
line-height: 23px;
white-space: normal;
margin-right: 0;
}
}
.queryForm .el-form-item {
margin-bottom: 0px !important;
}
:deep .el-table .success-row {
color: rgb(21, 174, 31) !important;
}
:deep .el-table .warning-row {
color: #f51f1f !important;
}
:deep .el-form-item__label {
text-align: left;
}
</style>