|
|
<template> <div class="customer-css"> <el-dialog :title="titleCon" :close-on-click-modal="false" :visible.sync="visible" :width="showPreview ? '1300px' : '600px'" class="customer-dialog" > <el-form label-position="top"> <el-row :gutter="16"> <el-col :span="12"> <el-form-item label="BU"> <el-select v-model="pageData.buNo" placeholder="请选择" style="width: 100%"> <el-option v-for="i in buList" :key="i.buNo" :label="i.buDesc" :value="i.buNo"></el-option> </el-select> </el-form-item> </el-col> <el-col :span="4"> <el-form-item label=" ">
</el-form-item> </el-col> <el-col :span="8"> <el-form-item label=" " v-if="showPreview"> <div style="margin-top:40px;padding: 10px; background-color: #FFF3E0; border: 1px solid #FFB74D; border-radius: 4px; font-size: 13px; line-height: 1.6;"> <div style="color: #E65100; font-weight: bold; margin-bottom: 5px;"> <i class="el-icon-warning" style="margin-right: 5px;"></i>导入规则 </div> <div style="color: #666;"> 以下3种情况不读取Excel内容:<br/> 1、发票在系统已存在<br/> 2、内销<br/> 3、CargoReady Date为空 </div> <div style="color: #E65100; font-weight: bold; margin-bottom: 5px;"> <i class="el-icon-warning" style="margin-right: 5px;"></i>保存模板规则 </div> <div style="color: #666;"> 客户模板名称无修改,点"保存模板"会修改原模板<br/> 客户模板名称有修改,点"保存模板"会另存为新模板 </div> </div> </el-form-item> </el-col> <el-col :span="20" style="margin-top: 10px"> <el-upload class="customer-upload" drag action="javascript:void(0);" ref="uploadFile" :limit="1" accept=".xlsx,.xls" :before-upload="beforeUploadHandle" :on-change="onChange" :auto-upload="false" style="text-align: left;"> <i class="el-icon-upload"></i> <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div> </el-upload> </el-col> </el-row> </el-form>
<!-- 预览数据表格 --> <!-- 加载状态 --> <div v-if="previewLoading" style="margin-top: 20px; text-align: center; padding: 40px;"> <i class="el-icon-loading" style="font-size: 24px; color: #409EFF;"></i> <p style="margin-top: 10px; color: #666;">正在解析文件,请稍候...</p> </div>
<div v-if="showPreview" style="margin-top: 10px; margin-bottom: 10px;"> <!-- 可导入的发票表格 --> <div v-if="validInvoices.length > 0"> <div style="display: flex; align-items: center; margin-bottom: 8px;"> <span style="color: #67C23A;"> <i class="el-icon-success" style="margin-right: 8px;"></i> 可导入的发票 (共{{ validInvoices.length }}个发票) </span> <el-button type="danger" size="mini" style="margin-left: 15px;" :disabled="selectedRows.length === 0" @click="batchDeleteRows"> <i class="el-icon-delete"></i> 批量删除 <span v-if="selectedRows.length > 0">({{ selectedRows.length }})</span> </el-button> </div> <el-table :data="validInvoices" border style="width: 100%" max-height="300" :show-overflow-tooltip="true" class="delClass valid-table" ref="validInvoicesTable" @selection-change="handleSelectionChange"> <el-table-column type="selection" width="40" fixed="left" align="center"></el-table-column><!-- <el-table-column label="操作" width="50" fixed="left"> <template slot-scope="scope"> <a type="text" size="small" style="color: red" @click="deleteRow(scope.$index, scope.row)">删除</a> </template> </el-table-column>--> <el-table-column prop="cmcInvoice" label="发票号" width="90" fixed="left"> <template slot-scope="scope"> <div> <span :style="scope.row.exists ? 'color: red; font-weight: bold;' : ''"> {{ scope.row.cmcInvoice }} </span> <div style="margin-top: 2px;"> <el-tag v-if="scope.row.exists" type="warning" size="mini">已存在</el-tag> </div> </div> </template> </el-table-column> <el-table-column prop="destination" label="目的地" width="100" :show-overflow-tooltip="true"></el-table-column> <el-table-column label="客户模板名称" width="150"> <template slot-scope="scope"> <el-input v-model="scope.row.selectedTemplate" placeholder="请选择客户模板名称" @dblclick.native="selectTemplateForRow(scope.row)" size="small" style="cursor: pointer;"> </el-input> </template> </el-table-column> <el-table-column label="客户" width="150"> <template slot-scope="scope"> <el-input v-model="scope.row.selectedCustomer" placeholder="请选择客户" @dblclick.native="selectCustomerForRow(scope.row)" size="small" style="cursor: pointer;" readonly> <i slot="suffix" class="el-icon-edit" style="cursor: pointer;" @click.stop="openEditDialog(scope.row, 'selectedCustomer', '客户', '编辑客户信息')"></i> </el-input> </template> </el-table-column> <el-table-column label="客户地址" min-width="160"> <template slot-scope="scope"> <el-input v-model="scope.row.selectedLocalAddress" placeholder="请选择客户地址" @dblclick.native="selectLocalAddressForRow(scope.row)" size="small" style="cursor: pointer;" readonly> <i slot="suffix" class="el-icon-edit" style="cursor: pointer;" @click.stop="openEditDialog(scope.row, 'selectedLocalAddress', '客户地址', '编辑客户地址')"></i> </el-input> </template> </el-table-column> <el-table-column label="收货单位" width="150"> <template slot-scope="scope"> <el-input v-model="scope.row.selectedOverseasShipper" placeholder="请选择收货单位" @dblclick.native="selectOverseasShipperForRow(scope.row)" size="small" style="cursor: pointer;" readonly> <i slot="suffix" class="el-icon-edit" style="cursor: pointer;" @click.stop="openEditDialog(scope.row, 'selectedOverseasShipper', '收货单位', '编辑收货单位')"></i> </el-input> </template> </el-table-column> <el-table-column label="收货单位地址" width="160"> <template slot-scope="scope"> <el-input v-model="scope.row.selectedOverseasAddress" placeholder="请选择收货单位地址" @dblclick.native="selectOverseasAddressForRow(scope.row)" size="small" style="cursor: pointer;" readonly> <i slot="suffix" class="el-icon-edit" style="cursor: pointer;" @click.stop="openEditDialog(scope.row, 'selectedOverseasAddress', '收货单位地址', '编辑收货单位地址')"></i> </el-input> </template> </el-table-column> <el-table-column label="运抵国" width="80"> <template slot-scope="scope"> <el-input v-model="scope.row.selectedCnative" placeholder="运抵国" size="small" style="cursor: pointer;" readonly> <i slot="suffix" class="el-icon-edit" style="cursor: pointer;" @click.stop="openEditDialog(scope.row, 'selectedCnative', '运抵国', '编辑运抵国')"></i> </el-input> </template> </el-table-column> <el-table-column label="贸易国" width="80"> <template slot-scope="scope"> <el-input v-model="scope.row.selectedSalesArea" placeholder="贸易国" size="small" style="cursor: pointer;" readonly> <i slot="suffix" class="el-icon-edit" style="cursor: pointer;" @click.stop="openEditDialog(scope.row, 'selectedSalesArea', '贸易国', '编辑贸易国')"></i> </el-input> </template> </el-table-column> <el-table-column label="操作" width="60" fixed="right"> <template slot-scope="scope"> <a v-if="scope.row.selectedTemplate" type="text" size="small" @click="saveTemplateChanges(scope.row)"> 保存模板 </a> <span v-else style="color: #C0C4CC; font-size: 12px;">未选择</span> </template> </el-table-column> </el-table> </div>
<!-- 物料不存在的发票表格 --> <div v-if="invalidInvoices.length > 0" style="margin-top: 10px;margin-bottom: 10px"> <span style="color: #F56C6C;"> <i class="el-icon-warning" style="margin-right: 8px;"></i> 物料不存在的发票 (共{{ invalidInvoices.length }}个发票,将不会导入) </span> <el-table :data="invalidInvoices" border style="width: 100%" max-height="300" :show-overflow-tooltip="true" class="delClass invalid-table"> <el-table-column prop="cmcInvoice" label="发票号" width="120" fixed="left"> <template slot-scope="scope"> <div> <span class="clickable-invoice" style="color: #F56C6C; font-weight: bold;" @click="showInvalidMaterials(scope.row)"> {{ scope.row.cmcInvoice }} <i class="el-icon-view" style="margin-left: 4px; font-size: 12px;"></i> </span> <div style="margin-top: 2px;"> <el-tag type="danger" size="mini">物料不存在</el-tag> </div> </div> </template> </el-table-column> <el-table-column prop="destination" label="目的地" width="100"></el-table-column> <el-table-column label="状态" width="100"> <template slot-scope="scope"> <div style="color: #F56C6C;"> <el-tag type="danger" size="small">物料不存在</el-tag> <div style="font-size: 12px; margin-top: 2px;">将不会导入</div> </div> </template> </el-table-column> <el-table-column label="不存在物料" width="150"> <template slot-scope="scope"> <div style="color: #F56C6C;"> <el-tag type="danger" size="small">{{ scope.row.invalidMaterials ? scope.row.invalidMaterials.length : 0 }}个物料</el-tag> <div style="font-size: 12px; margin-top: 2px;"> 点击发票号查看详情 </div> </div> </template> </el-table-column> <el-table-column label="客户信息" width="150"> <template slot-scope="scope"> <div style="color: #999; font-size: 12px;"> 无需填写 </div> </template> </el-table-column> <el-table-column prop="readyDate" label="Ready Date" width="160"></el-table-column> <el-table-column prop="totalQty" label="总数量" width="150" align="right"> <template slot-scope="scope"> {{ scope.row.totalQty || 0 }} </template> </el-table-column> <el-table-column prop="totalItems" label="明细数" width="160" align="center"> <template slot-scope="scope"> {{ scope.row.totalItems || 0 }} </template> </el-table-column> <el-table-column prop="shippingMode" label="运输方式" min-width="80"></el-table-column> </el-table> </div>
<!-- Sheet错误信息展示 --> <div v-if="sheetErrors.length > 0" style="margin-bottom: 5px;"> <span style="color: #E6A23C; "> <i class="el-icon-warning" style="margin-right: 8px;"></i> Sheet处理警告 (共{{ sheetErrors.length }}个Sheet存在问题) </span> <el-table :data="sheetErrors" border style="width: 100%" max-height="400" class="delClass warning-table"> <el-table-column prop="sheetName" label="Sheet名称" width="150" fixed="left" > <template slot-scope="scope"> <span style="font-weight: bold;">{{ scope.row.sheetName }}</span> </template> </el-table-column> <el-table-column prop="errorMessage" label="原因" min-width="300"> <template slot-scope="scope"> <div> <el-tooltip v-if="scope.row.errorDetails && scope.row.errorDetails.length > 0" placement="top" effect="light"> <div slot="content" style="max-width: 500px; line-height: 1.6;"> <div style="font-weight: bold; margin-bottom: 8px; color: #E6A23C;">详细错误信息 (共{{ scope.row.errorDetails.length }}条):</div> <div v-for="(detail, index) in scope.row.errorDetails" :key="index" style="margin-bottom: 6px;"> <span style="color: #E6A23C; font-weight: bold;">{{ index + 1 }}.</span> {{ detail }} </div> </div> <div style="font-size: 12px; color: #909399; cursor: pointer; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;"> <span v-for="(detail, index) in scope.row.errorDetails" :key="index"> <span v-if="index > 0">; </span> <span style="color: #E6A23C; font-weight: bold;">{{ index + 1 }}.</span> {{ detail }} </span> </div> </el-tooltip> </div> </template> </el-table-column> </el-table> </div> </div>
<span slot="footer" class="dialog-footer" style="margin-top: 10px"> <el-button v-if="!showPreview" type="primary" @click="saveUploadFile" :loading="saveButtonLoading" :disabled="saveButtonLoading">保存</el-button> <el-button v-if="showPreview" type="primary" @click="saveFromPreview" :loading="confirmSaveButtonLoading" :disabled="confirmSaveButtonLoading">确认保存</el-button> <el-button v-if="showPreview" @click="cancelPreview" :disabled="confirmSaveButtonLoading">取消预览</el-button> <el-button v-if="!showPreview" type="primary" @click="closeDialog" :disabled="saveButtonLoading">关闭</el-button> </span> </el-dialog>
<el-dialog :title="currentRow ? `为发票号 ${currentRow.cmcInvoice} 选择客户模板` : '客户模板'" @close="templateFlag = false; currentRow = null" :visible.sync="templateFlag" width="1200px" v-drag> <!-- 搜索表单 --> <el-form :inline="true" label-position="top" :model="templateSearchData" label-width="100px" > <el-form-item label="模板名称"> <el-input v-model="templateSearchData.templateName" placeholder="请输入模板名称" style="width: 200px;" clearable> </el-input> </el-form-item> <el-form-item label="客户名称"> <el-input v-model="templateSearchData.customerName" placeholder="请输入客户名称" style="width: 200px;" clearable> </el-input> </el-form-item> <el-form-item label=" "> <el-button type="primary" @click="searchTemplateList">查询</el-button> </el-form-item> <el-form-item label=" "> <el-button @click="resetTemplateSearch">重置</el-button> </el-form-item> </el-form>
<el-table :height="400" :data="customerTemplateList" stripe highlight-current-row border class="delClass" @row-dblclick="rowDblclickTemplate" style="width: 100%;"> <el-table-column prop="template_name" header-align="center" align="left" width="150" label="模板名称"> </el-table-column> <el-table-column prop="ccusname" header-align="center" align="left" width="200" label="客户名称"> </el-table-column> <el-table-column prop="localShipAddress" header-align="center" align="left" width="300" label="客户地址"> </el-table-column> <el-table-column prop="overseasShipper" header-align="center" align="left" width="200" label="收货单位"> </el-table-column> <el-table-column prop="overseasAddress" header-align="center" align="left" width="300" label="收货地址"> </el-table-column> <el-table-column prop="salesArea" header-align="center" align="left" width="80" label="贸易国"> </el-table-column> <el-table-column prop="cnative" header-align="center" align="left" width="80" label="运抵国"> </el-table-column> </el-table> <el-footer style="height:40px;margin-top: 10px;text-align:center"> <el-button @click="templateFlag = false; currentRow = null">关闭</el-button> </el-footer> </el-dialog>
<el-dialog :title="currentRow ? `为发票号 ${currentRow.cmcInvoice} 选择客户` : '客户'" @close="closeCustomDialog" :visible.sync="customFlag" width="500px" v-drag> <el-form inline="inline" label-position="top" :model="customSearchData" style="margin-left: 7px;margin-top: -5px;"> <el-form-item label="客户名称"> <el-input v-model="customSearchData.ccusname" clearable style="width: 150px"></el-input> </el-form-item> <el-form-item label=" "> <el-button type="primary" style="padding: 3px 12px" @click="getCustomerList()">查询</el-button> </el-form-item> </el-form> <el-table :height="400" :data="customerList" stripe highlight-current-row border @row-dblclick="rowDblclick" style="width: 100%;"> <el-table-column prop="ccusname" header-align="center" align="left" width="350" label="客户名称"> </el-table-column> <el-table-column prop="country" header-align="center" align="left" label="贸易国"> </el-table-column> </el-table> <el-footer style="height:40px;margin-top: 10px;text-align:center"> <el-button @click="customFlag = false">关闭</el-button> </el-footer> </el-dialog>
<el-dialog :title="currentRow ? `为发票号 ${currentRow.cmcInvoice} 选择客户地址` : '客户地址'" @close="localShipAddressFlag = false; currentRow = null" :visible.sync="localShipAddressFlag" width="500px" v-drag> <el-table :height="400" :data="customerAddrs" stripe highlight-current-row border @row-dblclick="rowDblclick2" style="width: 100%;"> <el-table-column prop="cDeliverAdd" header-align="center" align="left" label="客户地址"> </el-table-column> </el-table> <el-footer style="height:40px;margin-top: 10px;text-align:center"> <el-button @click="localShipAddressFlag = false; currentRow = null">关闭</el-button> </el-footer> </el-dialog>
<el-dialog :title="currentRow ? `为发票号 ${currentRow.cmcInvoice} 选择收货单位地址` : '收货单位地址'" @close="overseasAddressFlag = false; currentRow = null" :visible.sync="overseasAddressFlag" width="500px" v-drag> <el-table :height="400" :data="customerAddrs" stripe highlight-current-row border @row-dblclick="rowDblclick3" style="width: 100%;"> <el-table-column prop="cDeliverAdd" header-align="center" align="left" label="收货单位地址"> </el-table-column> </el-table> <el-footer style="height:40px;margin-top: 10px;text-align:center"> <el-button @click="overseasAddressFlag = false; currentRow = null">关闭</el-button> </el-footer> </el-dialog>
<el-dialog :title="currentRow ? `为发票号 ${currentRow.cmcInvoice} 选择收货单位` : '收货单位'" @close="overseasShipperFlag = false; currentRow = null" :visible.sync="overseasShipperFlag" width="500px" v-drag> <el-table :height="400" :data="customerAddrs" stripe highlight-current-row border @row-dblclick="rowDblclick4" style="width: 100%;"> <el-table-column prop="cDeliverUnit" header-align="left" align="left" width="350" label="收货单位"> </el-table-column> <el-table-column prop="deliverycountry" header-align="center" align="left" label="运抵国"> </el-table-column> </el-table> <el-footer style="height:40px;margin-top: 10px;text-align:center"> <el-button @click="overseasShipperFlag = false; currentRow = null">关闭</el-button> </el-footer> </el-dialog>
<!-- 大输入框编辑弹窗 --> <el-dialog :title="editDialog.title" :visible.sync="editDialog.visible" width="600px" class="edit-dialog" @close="closeEditDialog"> <div class="edit-dialog-tip"> <i class="el-icon-info"></i> 提示:您可以在此编辑较长的文本内容,支持多行输入 </div> <el-form label-position="top" style="margin-bottom: 120px"> <el-form-item :label="editDialog.label"> <el-input ref="editTextarea" v-model="editDialog.value" type="textarea" :rows="6" placeholder="请输入内容,支持多行文本..." maxlength="500" show-word-limit class="edit-textarea"> </el-input> </el-form-item> </el-form> <span slot="footer" class="dialog-footer"> <el-button @click="closeEditDialog">取消</el-button> <el-button type="primary" @click="confirmEdit">保存</el-button> </span> </el-dialog>
<!-- 物料不存在详情对话框 --> <el-dialog :title="`发票号 ${invalidMaterialsDialog.invoice} - 不存在的物料详情`" :visible.sync="invalidMaterialsDialog.visible" width="320px" class="invalid-materials-dialog" @close="closeInvalidMaterialsDialog"> <div class="invalid-materials-content"> <el-table :data="invalidMaterialsDialog.materials" border style="width: 100%; margin-top: 15px;" max-height="300"> <el-table-column type="index" label="序号" width="60" align="center"> </el-table-column> <el-table-column prop="material" label="物料号" align="left"> <template slot-scope="scope"> <span style="color: #F56C6C; font-weight: bold;">{{ scope.row }}</span> </template> </el-table-column> </el-table> <div class="materials-summary" style="margin-top: 15px; padding: 10px; background-color: #FEF0F0; border-radius: 4px;"> <span style="color: #F56C6C;"> <i class="el-icon-info"></i> 共发现 <strong>{{ invalidMaterialsDialog.materials.length }}</strong> 个不存在的物料 </span> </div> </div> <span slot="footer" class="dialog-footer"> <el-button type="primary" @click="closeInvalidMaterialsDialog">确定</el-button> </span> </el-dialog> </div></template>
<script> import {queryFileId} from "@/api/qc/qc.js" import {previewExcelTX,saveEcssCoDelNotifyByExcelTX,getCustomerList,getCustomers,getCustomerAdd,getCustomerTemplateList,saveExcelImportTemplate} from '@/api/ecss/ecss.js' import {downLoadObjectFile} from '@/api/eam/eam_object_list.js' import {getBuList}from '@/api/factory/site.js' export default { name: 'delUploadExcelTx', data() { return { buList: [], titleCon: '天线/硬标导入', visible: false, fileList: [], pageData: { site: '', buNo: '', createBy: this.$store.state.user.name, customerName:'', localShipAddress:'', overseasShipper:'', overseasAddress:'', cnative:'', salesArea:'', }, previewData: [], // 预览数据
showPreview: false, // 是否显示预览
selectedFile: null, // 选择的文件
previewLoading: false, // 预览加载状态
saveButtonLoading: false, // 保存按钮加载状态
confirmSaveButtonLoading: false, // 确认保存按钮加载状态
deletedInvoices: [], // 被删除的发票号列表
sheetErrors: [], // Sheet错误信息列表
customSearchData: {}, customerList : [],//所有客户
customerAddrs : [],//地址
customerPersons : [],//联系人
customerMap:new Map, customFlag:false, localShipAddressFlag:false, overseasShipperFlag:false, overseasAddressFlag:false, templateFlag:false, customerTemplateList: [],//客户模板列表
templateSearchData: { templateName: '', customerName: '' },//模板搜索条件
cacheKey: '', // 缓存键
cacheTimer: null, // 缓存定时器
currentRow: null, // 当前编辑的行
cachedFileInfo: null, // 缓存的文件信息
cachedFileList: [], // 缓存的文件列表
// 大输入框编辑弹窗相关数据
editDialog: { visible: false, title: '', label: '', value: '', fieldName: '', // 要编辑的字段名
row: null // 当前编辑的行数据
}, // 物料不存在详情对话框相关数据
invalidMaterialsDialog: { visible: false, invoice: '', materials: [] }, // 批量删除相关数据
selectedRows: [] // 选中的行
} }, computed: { // 可导入的发票(不包含物料不存在的发票)
validInvoices() { return this.previewData.filter(item => !item.hasInvalidMaterials) }, // 物料不存在的发票
invalidInvoices() { return this.previewData.filter(item => item.hasInvalidMaterials) } }, watch: { // 深度监听pageData的变化,自动保存到缓存
pageData: { handler: function(newVal, oldVal) { // 只有在组件已初始化且对话框可见时才保存缓存
if (this.visible && this.cacheKey) { this.saveToCache(); } }, deep: true }, // 深度监听previewData的变化,保存用户的编辑
previewData: { handler: function(newVal, oldVal) { // 只有在组件已初始化且对话框可见时才保存缓存
if (this.visible && this.cacheKey && newVal && newVal.length > 0) { this.saveToCache(); } }, deep: true } }, beforeDestroy() { // 组件销毁前清理定时器
if (this.cacheTimer) { clearTimeout(this.cacheTimer); } }, methods: { // 生成缓存键
generateCacheKey() { const userId = this.$store.state.user.id || this.$store.state.user.name; return `ecss_del_upload_cache_${userId}`; },
// 保存数据到缓存(防抖处理)
saveToCache() { // 清除之前的定时器
if (this.cacheTimer) { clearTimeout(this.cacheTimer); }
// 设置新的定时器,500ms后执行保存
this.cacheTimer = setTimeout(() => { try { const cacheData = { pageData: { buNo: this.pageData.buNo, customerName: this.pageData.customerName, localShipAddress: this.pageData.localShipAddress, overseasShipper: this.pageData.overseasShipper, overseasAddress: this.pageData.overseasAddress, cnative: this.pageData.cnative, salesArea: this.pageData.salesArea, }, // 保存文件和预览相关数据
fileInfo: this.selectedFile ? { name: this.selectedFile.name, size: this.selectedFile.size, lastModified: this.selectedFile.lastModified } : null, showPreview: this.showPreview, previewData: this.previewData, deletedInvoices: this.deletedInvoices, fileList: this.fileList.map(file => ({ name: file.name, size: file.size, lastModified: file.lastModified, uid: file.uid })) }; localStorage.setItem(this.cacheKey, JSON.stringify(cacheData)); } catch (error) { console.warn('保存缓存失败:', error); } }, 500); },
// 从缓存加载数据
loadFromCache() { try { const cachedData = localStorage.getItem(this.cacheKey); if (cachedData) { const parsedData = JSON.parse(cachedData); if (parsedData.pageData) { // 恢复基础表单数据
Object.assign(this.pageData, parsedData.pageData);
// 恢复预览数据和文件状态
if (parsedData.previewData && parsedData.previewData.length > 0) { this.previewData = parsedData.previewData; this.showPreview = parsedData.showPreview || false; }
// 恢复删除的发票号列表
if (parsedData.deletedInvoices) { this.deletedInvoices = parsedData.deletedInvoices; }
// 恢复文件列表信息(用于界面显示)
if (parsedData.fileList && parsedData.fileList.length > 0) { // 记录缓存的文件信息,用于后续比对
this.cachedFileInfo = parsedData.fileInfo; this.cachedFileList = parsedData.fileList; }
return true; } } } catch (error) { console.warn('加载缓存失败:', error); } return false; },
// 清除缓存
clearCache() { try { localStorage.removeItem(this.cacheKey); } catch (error) { console.warn('清除缓存失败:', error); } },
// 检查并恢复文件状态
checkAndRestoreFileState() { // 检查上传组件中是否有文件
const uploadFiles = this.$refs.uploadFile.uploadFiles;
if (this.cachedFileInfo && this.cachedFileList.length > 0) { // 如果有缓存的文件信息,检查当前上传组件中的文件
if (uploadFiles && uploadFiles.length > 0) { const currentFile = uploadFiles[0]; const isSameFile = currentFile.name === this.cachedFileInfo.name && currentFile.size === this.cachedFileInfo.size && currentFile.lastModified === this.cachedFileInfo.lastModified;
if (isSameFile) { // 是同一个文件,恢复文件相关状态
this.selectedFile = currentFile; this.fileList = [currentFile]; console.log('恢复文件状态:', currentFile.name); } else { // 文件不匹配,清除预览状态但保留表单数据
this.showPreview = false; this.previewData = []; this.selectedFile = null; this.fileList = []; console.log('文件不匹配,清除预览状态'); } } else { // 没有文件但有缓存,说明文件可能被清除了
this.showPreview = false; this.previewData = []; this.selectedFile = null; this.fileList = []; console.log('没有找到文件,清除预览状态'); } }
// 保存当前状态
this.saveToCache(); },
// 初始化组件的参数
init () { // 初始化缓存键,但不清除任何现有数据
this.cacheKey = this.generateCacheKey(); this.previewLoading = false
let tempData = { username: this.$store.state.user.name, } getBuList(tempData).then(({data}) => { if (data.code === 0) { this.buList = data.row2 if(data.row2.length===1){ this.pageData.buNo=data.row2[0].buNo } } // 在获取BU列表后尝试加载缓存
this.loadFromCache();
// 检查并恢复文件状态
this.$nextTick(() => { this.checkAndRestoreFileState(); }); })
getCustomerList({}).then(({data}) => { //区分请求成功和失败的状况
if (data && data.code === 0) { this.customerList=data.rows } });
// 只有在完全没有缓存数据时才初始化为空
const hasCache = this.loadFromCache(); if (!hasCache) { this.fileList = [] this.previewData = [] this.showPreview = false this.selectedFile = null this.deletedInvoices = [] this.pageData.customerName='' this.pageData.cnative='' this.pageData.localShipAddress='', this.pageData.overseasShipper='', this.pageData.overseasAddress='', this.pageData.salesArea='' }
this.customerPersons=[] this.customerAddrs=[] // 打开页面
this.visible = true }, getCustomerList(){ getCustomerList(this.customSearchData).then(({data}) => { //区分请求成功和失败的状况
if (data && data.code === 0) { this.customerList=data.rows } }); }, getCusPersons(){ let cusData = {ccusname: this.pageData.customerName} getCustomers(cusData).then(({data}) => { //区分请求成功和失败的状况
if (data && data.code === 0) { this.customerPersons=data.rows this.customerPersons.forEach(o => { if (!this.customerMap.has(o.ccontactname)) { this.customerMap.set(o.ccontactname, o.cnative); } }); } }); getCustomerAdd(cusData).then(({data}) => { //区分请求成功和失败的状况
if (data && data.code === 0) { this.customerAddrs=data.rows } }); }, setCnative(){ this.pageData.cnative=this.customerMap.get(this.pageData.overseasShipper) }, closeCustomDialog () { this.customFlag = false this.currentRow = null }, rowDblclickTemplate(row) { console.log(row) if (this.currentRow) { // 使用模板设置当前行的所有信息
this.currentRow.templateNo = row.template_no this.currentRow.ccuscode = row.ccuscode this.currentRow.selectedTemplate = row.template_name this.currentRow.originalTemplateName = row.template_name // 保存原始模板名称,用于判断是否修改
this.currentRow.selectedCustomer = row.ccusname || '' this.currentRow.selectedLocalAddress = row.localShipAddress || '' this.currentRow.selectedOverseasShipper = row.overseasShipper || '' this.currentRow.selectedOverseasAddress = row.overseasAddress || '' this.currentRow.selectedCnative = row.cnative || '' this.currentRow.selectedSalesArea = row.salesArea || ''
// 如果模板中有客户信息,自动获取该客户的地址和收货单位信息
if (row.ccusname) { this.getCusPersonsForRow(row.ccusname) } } this.templateFlag = false this.currentRow = null },
rowDblclick (row) { if (this.currentRow) { // 预览模式下,为当前行设置客户信息
this.currentRow.selectedCustomer = row.ccusname this.currentRow.selectedSalesArea = row.country this.currentRow.selectedLocalAddress = '' this.currentRow.selectedOverseasShipper = '' this.currentRow.selectedOverseasAddress = '' this.currentRow.selectedCnative = '' this.getCusPersonsForRow(row.ccusname) } else { // 普通模式下,设置全局信息
this.pageData.customerName=row.ccusname this.pageData.cnative='', this.pageData.localShipAddress='', this.pageData.overseasShipper='', this.pageData.overseasAddress='', this.pageData.salesArea = row.country this.getCusPersons() } this.customFlag = false }, rowDblclick2 (row) { if (this.currentRow) { this.currentRow.selectedLocalAddress = row.cDeliverAdd } else { this.pageData.localShipAddress = row.cDeliverAdd } this.localShipAddressFlag = false this.currentRow = null }, rowDblclick3 (row) { if (this.currentRow) { this.currentRow.selectedOverseasAddress = row.cDeliverAdd } else { this.pageData.overseasAddress = row.cDeliverAdd } this.overseasAddressFlag = false this.currentRow = null }, rowDblclick4 (row) { if (this.currentRow) { this.currentRow.selectedOverseasShipper = row.cDeliverUnit this.currentRow.selectedCnative = row.deliverycountry } else { this.pageData.overseasShipper = row.cDeliverUnit this.pageData.cnative = row.deliverycountry } this.overseasShipperFlag = false this.currentRow = null },
// 上传之前
beforeUploadHandle (file) { let extName = file[0].name.substring(file[0].name.lastIndexOf('.')).toLowerCase() if (!(extName === '.xlsx' || extName === '.xls')) { this.$message.error('数据导入失败,请选择正确的xlsx模板文件') return false } },
// 选择上传文件时
onChange (file) { this.fileList.push(file) this.selectedFile = file this.previewFile(file) // 保存文件信息到缓存
this.saveToCache() },
// 关闭modal
closeDialog () { // 保存当前状态到缓存
this.saveToCache() // 关闭当前的页面
this.visible = false this.$emit('refreshTable') }, deleteFile(){ // 只有在明确需要清除数据时才调用此方法
this.fileList = [] this.previewData = [] this.showPreview = false this.selectedFile = null this.deletedInvoices = [] this.cachedFileInfo = null this.cachedFileList = [] // 清空文件上传记录
this.$refs.uploadFile.clearFiles() // 清除缓存
this.clearCache() // 刷新报工的页面
this.$emit('refreshTable') },
// 保修当前的数据
saveUploadFile () { if (null == this.pageData.buNo || this.pageData.buNo=='') { this.$message.error("请先选择BU!") return false } if (null == this.pageData.customerName || this.pageData.customerName=='') { this.$message.error("请先选择客户!") return false } if (null == this.pageData.localShipAddress || this.pageData.localShipAddress=='') { this.$message.error("请先填写客户发货地址!") return false } if (null == this.pageData.overseasShipper || this.pageData.overseasShipper=='') { this.$message.error("请先填写收货单位!") return false } if (null == this.pageData.overseasAddress || this.pageData.overseasAddress=='') { this.$message.error("请先填写收货单位地址!") return false } if (null == this.pageData.cnative || this.pageData.cnative=='') { this.$message.error("请先填写收货单位运抵国!") return false } // 判断文件是否上传
if (null == this.fileList || 0 === this.fileList.length) { this.$message.error("请先上传文件!") return false }
this.saveButtonLoading = true // 开始加载
const formData = new FormData() formData.append("buNo",this.pageData.buNo) formData.append("username",this.$store.state.user.name) formData.append("file", this.fileList[0].raw) formData.append("customerName", this.pageData.customerName) formData.append("localShipAddress", this.pageData.localShipAddress) formData.append("overseasShipper", this.pageData.overseasShipper) formData.append("overseasAddress", this.pageData.overseasAddress) formData.append("cnative", this.pageData.cnative) formData.append("salesArea", this.pageData.salesArea) saveEcssCoDelNotifyByExcelTX(formData).then(({ data }) => { if (data.code === 0) { const { resultMap } = data; const successList = resultMap.success || []; const failList = resultMap.fail || [];
// 紧凑样式
let html = `
<div style="max-height:380px;overflow:auto;font-size:12px;line-height:1.4;"> `;
if (successList.length > 0) { html += `<div style="margin-bottom:6px;">
<div style="color:green;font-weight:bold;margin-bottom:3px;"> ✅ 成功(${successList.length}) </div> <table border="1" cellspacing="0" cellpadding="2" style="border-collapse:collapse;width:100%;"> `;
successList.forEach(item => { html += `<tr><td style="color:green;padding:2px 4px;">${item}</td></tr>`; }); html += `</table></div>`; }
if (failList.length > 0) { html += `<div>
<div style="color:red;font-weight:bold;margin-bottom:3px;"> ❌ 失败(${failList.length}) </div> <table border="1" cellspacing="0" cellpadding="2" style="border-collapse:collapse;width:100%;"> `;
failList.forEach(item => { html += `<tr><td style="color:red;padding:2px 4px;">${item}</td></tr>`; }); html += `</table></div>`; }
html += `</div>`;
this.$alert(html, '导入结果', { confirmButtonText: '确定', dangerouslyUseHTMLString: true, callback: () => { if (successList.length > 0){ this.clearCache(); this.clearPreviewData(); this.closeDialog(); } } }); } else { this.$alert(data.msg, '错误', { confirmButtonText: '确定' }); } }).catch(error => { this.$message.error('保存失败:' + (error.message || '网络异常')) }).finally(() => { this.saveButtonLoading = false // 结束加载
});
},
// 预览文件
async previewFile(file) { if (!file || !file.raw) { return } if (!this.pageData.buNo) { this.$message.error('请先选择BU!') this.fileList = [] this.$refs.uploadFile.clearFiles() return }
this.previewLoading = true // 开始加载
const formData = new FormData() formData.append("file", file.raw) formData.append("buNo", this.pageData.buNo)
try { const { data } = await previewExcelTX(formData)
if (data.code === 0) { this.previewData = data.data || [] this.sheetErrors = data.sheetErrors || [] this.showPreview = true // 清空删除列表,因为这是新的文件预览
this.deletedInvoices = []
// 如果有Sheet错误,显示警告信息
if (this.sheetErrors.length > 0) { const skippedCount = this.sheetErrors.filter(e => e.skipped).length const errorCount = this.sheetErrors.filter(e => !e.skipped).length let message = `文件解析完成,但有 ${this.sheetErrors.length} 个Sheet存在问题` if (skippedCount > 0) { message += `(${skippedCount}个已跳过` } if (errorCount > 0) { message += `${skippedCount > 0 ? ',' : '('}${errorCount}个处理失败` } message += '),请查看详细信息' this.$message.warning(message) }
// 为每个发票号初始化客户信息
this.previewData.forEach(item => { this.$set(item, 'templateNo', '') this.$set(item, 'ccuscode', '') this.$set(item, 'selectedTemplate', '') this.$set(item, 'originalTemplateName', '') this.$set(item, 'selectedCustomer', '') this.$set(item, 'selectedLocalAddress', '') this.$set(item, 'selectedOverseasShipper', '') this.$set(item, 'selectedOverseasAddress', '') this.$set(item, 'selectedCnative', '') this.$set(item, 'selectedSalesArea','') }) // 预览成功后立即保存缓存
this.saveToCache() } else { this.$message.error(data.msg || '文件预览失败') } } catch (error) { this.$message.error('文件预览失败:' + error.message) } finally { this.previewLoading = false // 结束加载
} },
// 从预览数据保存
saveFromPreview() { // 检查是否有可导入的发票
if (this.validInvoices.length === 0) { this.$message.warning('没有可导入的发票!') return false }
// 只验证可导入发票的必填信息
for (let item of this.validInvoices) { if (!item.selectedCustomer) { this.$message.error(`发票号 ${item.cmcInvoice} 请选择客户`) return false } if (!item.selectedLocalAddress) { this.$message.error(`发票号 ${item.cmcInvoice} 请填写客户地址`) return false } if (!item.selectedOverseasShipper) { this.$message.error(`发票号 ${item.cmcInvoice} 请填写收货单位`) return false } if (!item.selectedOverseasAddress) { this.$message.error(`发票号 ${item.cmcInvoice} 请填写收货单位地址`) return false } if (!item.selectedCnative) { this.$message.error(`发票号 ${item.cmcInvoice} 请填写运抵国`) return false } }
this.confirmSaveButtonLoading = true // 开始加载
// 发送保存请求
const formData = new FormData() formData.append("buNo", this.pageData.buNo) formData.append("username", this.$store.state.user.name) formData.append("file", this.fileList[0].raw) // 添加被删除的发票号列表(包括用户手动删除的和物料不存在的)
const allDeletedInvoices = [...this.deletedInvoices] // 将物料不存在的发票也添加到删除列表中
this.invalidInvoices.forEach(item => { if (!allDeletedInvoices.includes(item.cmcInvoice)) { allDeletedInvoices.push(item.cmcInvoice) } }) formData.append("deletedInvoices", JSON.stringify(allDeletedInvoices)) // 只为可导入的发票设置客户信息
this.validInvoices.forEach((item, index) => { formData.append(`templateNo_${item.cmcInvoice}`, item.templateNo) formData.append(`customerName_${item.cmcInvoice}`, item.selectedCustomer) formData.append(`localShipAddress_${item.cmcInvoice}`, item.selectedLocalAddress) formData.append(`overseasShipper_${item.cmcInvoice}`, item.selectedOverseasShipper) formData.append(`overseasAddress_${item.cmcInvoice}`, item.selectedOverseasAddress) formData.append(`cnative_${item.cmcInvoice}`, item.selectedCnative) formData.append(`salesArea_${item.cmcInvoice}`, item.selectedSalesArea) })
saveEcssCoDelNotifyByExcelTX(formData).then(({ data }) => { if (data.code === 0) { const { resultMap } = data; const successList = resultMap.success || []; const failList = resultMap.fail || [];
// 紧凑样式
let html = `
<div style="max-height:380px;overflow:auto;font-size:12px;line-height:1.4;"> `;
if (successList.length > 0) { html += `<div style="margin-bottom:6px;">
<div style="color:green;font-weight:bold;margin-bottom:3px;"> ✅ 成功(${successList.length}) </div> <table border="1" cellspacing="0" cellpadding="2" style="border-collapse:collapse;width:100%;"> `;
successList.forEach(item => { html += `<tr><td style="color:green;padding:2px 4px;">${item}</td></tr>`; }); html += `</table></div>`; }
if (failList.length > 0) { html += `<div>
<div style="color:red;font-weight:bold;margin-bottom:3px;"> ❌ 失败(${failList.length}) </div> <table border="1" cellspacing="0" cellpadding="2" style="border-collapse:collapse;width:100%;"> `;
failList.forEach(item => { html += `<tr><td style="color:red;padding:2px 4px;">${item}</td></tr>`; }); html += `</table></div>`; }
html += `</div>`;
this.$alert(html, '导入结果', { confirmButtonText: '确定', dangerouslyUseHTMLString: true, callback: () => { if (successList.length > 0){ this.clearCache(); this.clearPreviewData(); this.closeDialog(); } } }); } else { this.$alert(data.msg, '错误', { confirmButtonText: '确定' }); } }).catch(error => { this.$message.error('保存失败:' + (error.message || '网络异常')) }).finally(() => { this.confirmSaveButtonLoading = false // 结束加载
}); },
// 取消预览
cancelPreview() { this.showPreview = false this.previewData = [] this.sheetErrors = [] this.fileList = [] this.selectedFile = null this.deletedInvoices = [] this.cachedFileInfo = null this.cachedFileList = [] this.$refs.uploadFile.clearFiles() // 更新缓存
this.saveToCache() },
// 清除预览数据
clearPreviewData() { this.previewData = [] this.sheetErrors = [] this.showPreview = false this.selectedFile = null this.fileList = [] this.deletedInvoices = [] this.previewLoading = false this.cachedFileInfo = null this.cachedFileList = [] this.$refs.uploadFile.clearFiles() // 更新缓存
this.saveToCache() },
// 为行选择客户模板
selectTemplateForRow(row) { this.currentRow = row this.getCustomerTemplateList() this.templateFlag = true },
// 为行选择客户
selectCustomerForRow(row) { this.currentRow = row this.customFlag = true },
// 为行选择客户地址
selectLocalAddressForRow(row) { if (!row.selectedCustomer) { this.$message.warning('请先选择客户') return } this.currentRow = row this.getCusPersonsForRow(row.selectedCustomer) this.localShipAddressFlag = true },
// 为行选择收货单位
selectOverseasShipperForRow(row) { if (!row.selectedCustomer) { this.$message.warning('请先选择客户') return } this.currentRow = row this.getCusPersonsForRow(row.selectedCustomer) this.overseasShipperFlag = true },
// 为行选择收货单位地址
selectOverseasAddressForRow(row) { if (!row.selectedCustomer) { this.$message.warning('请先选择客户') return } this.currentRow = row this.getCusPersonsForRow(row.selectedCustomer) this.overseasAddressFlag = true },
// 获取客户模板列表
async getCustomerTemplateList(searchParams = {}) { try { const { data } = await getCustomerTemplateList(searchParams) if (data && data.code === 0) { this.customerTemplateList = data.rows || [] } } catch (error) { console.error('获取客户模板列表失败:', error) this.customerTemplateList = [] } },
// 搜索客户模板
searchTemplateList() { const searchParams = { templateName: this.templateSearchData.templateName, customerName: this.templateSearchData.customerName } this.getCustomerTemplateList(searchParams) },
// 重置模板搜索
resetTemplateSearch() { this.templateSearchData = { templateName: '', customerName: '' } this.getCustomerTemplateList() },
// 获取特定客户的地址信息
getCusPersonsForRow(customerName) { let cusData = {ccusname: customerName} getCustomers(cusData).then(({data}) => { if (data && data.code === 0) { this.customerPersons = data.rows this.customerPersons.forEach(o => { if (!this.customerMap.has(o.ccontactname)) { this.customerMap.set(o.ccontactname, o.cnative); } }); } }); getCustomerAdd(cusData).then(({data}) => { if (data && data.code === 0) { this.customerAddrs = data.rows } }); },
// 打开大输入框编辑弹窗
openEditDialog(row, fieldName, label, title) { this.editDialog.visible = true this.editDialog.title = title this.editDialog.label = label this.editDialog.fieldName = fieldName this.editDialog.row = row this.editDialog.value = row[fieldName] || '' this.$nextTick(() => this.$refs.editTextarea.focus()); },
// 关闭大输入框编辑弹窗
closeEditDialog() { this.editDialog.visible = false this.editDialog.title = '' this.editDialog.label = '' this.editDialog.fieldName = '' this.editDialog.row = null this.editDialog.value = '' },
// 确认编辑
confirmEdit() { if (this.editDialog.row && this.editDialog.fieldName) { this.editDialog.row[this.editDialog.fieldName] = this.editDialog.value } this.closeEditDialog() },
// 处理表格选择变化
handleSelectionChange(selection) { this.selectedRows = selection },
// 批量删除行
batchDeleteRows() { if (this.selectedRows.length === 0) { this.$message.warning('请先选择要删除的发票') return }
const invoiceNumbers = this.selectedRows.map(row => row.cmcInvoice).join('、') this.$confirm(`确定要删除以下 ${this.selectedRows.length} 个发票吗?\n${invoiceNumbers}\n\n删除后将不会提交到后台。`, '批量删除确认', { confirmButtonText: '确定删除', cancelButtonText: '取消', type: 'warning' }).then(() => { // 记录被删除的发票号并从预览数据中移除
this.selectedRows.forEach(row => { // 记录被删除的发票号
if (!this.deletedInvoices.includes(row.cmcInvoice)) { this.deletedInvoices.push(row.cmcInvoice) } // 从预览数据中移除该行
const previewIndex = this.previewData.findIndex(item => item.cmcInvoice === row.cmcInvoice) if (previewIndex !== -1) { this.previewData.splice(previewIndex, 1) } }) this.$message.success(`已成功删除 ${this.selectedRows.length} 个发票`) // 清空选中状态
this.selectedRows = [] // 保存到缓存
this.saveToCache() }).catch(() => { // 用户取消删除
}) },
// 删除行
deleteRow(index, row) { this.$confirm(`确定要删除发票号 "${row.cmcInvoice}" 吗?删除后将不会提交到后台。`, '删除确认', { confirmButtonText: '确定删除', cancelButtonText: '取消', type: 'warning' }).then(() => { // 记录被删除的发票号
if (!this.deletedInvoices.includes(row.cmcInvoice)) { this.deletedInvoices.push(row.cmcInvoice) } // 从预览数据中移除该行(根据发票号查找)
const previewIndex = this.previewData.findIndex(item => item.cmcInvoice === row.cmcInvoice) if (previewIndex !== -1) { this.previewData.splice(previewIndex, 1) } this.$message.success(`发票号 "${row.cmcInvoice}" 已删除`) // 清空选中状态(如果删除的是选中的行)
this.selectedRows = this.selectedRows.filter(r => r.cmcInvoice !== row.cmcInvoice) // 保存到缓存
this.saveToCache() }).catch(() => { // 用户取消删除
}) },
// 下载
async downloadFile () { let file = { id: 0, fileName: '' } let tempData = { orderRef1: 'ecss', orderRef2: 'upLoadDel' } await queryFileId(tempData).then(({data}) => { if (data && data.code === 0) { file.id = data.data.id file.fileName = data.data.fileName } else { this.$alert(data.msg, '错误', { confirmButtonText: '确定' }) } })
await downLoadObjectFile(file).then(({data}) => { // 不限制文件下载类型
const blob = new Blob([data], {type: "application/octet-stream"}) // 下载文件名称
const fileName = file.fileName // a标签下载
const linkNode = document.createElement('a') // a标签的download属性规定下载文件的名称
linkNode.download = fileName linkNode.style.display = 'none' // 生成一个Blob URL
linkNode.href = URL.createObjectURL(blob) document.body.appendChild(linkNode) // 模拟在按钮上的一次鼠标单击
linkNode.click() // 释放URL 对象
URL.revokeObjectURL(linkNode.href) document.body.removeChild(linkNode) }) },
// 显示物料不存在详情
showInvalidMaterials(row) { this.invalidMaterialsDialog.invoice = row.cmcInvoice this.invalidMaterialsDialog.materials = row.invalidMaterials || [] this.invalidMaterialsDialog.visible = true },
// 关闭物料不存在详情对话框
closeInvalidMaterialsDialog() { this.invalidMaterialsDialog.visible = false this.invalidMaterialsDialog.invoice = '' this.invalidMaterialsDialog.materials = [] },
/** * 检查行数据是否已准备好保存模板 * @param {Object} row - 行数据 * @return {boolean} 是否可以保存 */ isRowReadyForSave(row) { return !!(row.selectedTemplate && row.selectedTemplate.trim() && row.selectedCustomer && row.selectedCustomer.trim()) },
/** * 保存模板修改 * @param {Object} row - 行数据 */ async saveTemplateChanges(row) { // 验证必填字段
if (!row.selectedTemplate || !row.selectedTemplate.trim()) { this.$message.warning('请输入模板名称') return }
if (!row.selectedCustomer || !row.selectedCustomer.trim()) { this.$message.warning('请填写客户信息') return }
// 判断操作类型,给用户明确提示
const isNewTemplate = !row.originalTemplateName || row.originalTemplateName === '' const isNameChanged = row.originalTemplateName && row.selectedTemplate !== row.originalTemplateName
let confirmMessage = '' if (isNewTemplate) { // 手动输入的新模板名
confirmMessage = `确定要保存模板"${row.selectedTemplate}"吗?\n\n如果此模板名已存在,将会覆盖原有模板内容!` } else if (isNameChanged) { // 基于已选模板另存为新模板
confirmMessage = `确定要将模板"${row.originalTemplateName}"另存为"${row.selectedTemplate}"吗?\n\n如果"${row.selectedTemplate}"已存在,将会覆盖原有模板内容!` } else { // 更新原有模板
confirmMessage = `确定要更新模板"${row.selectedTemplate}"吗?\n\n此操作将覆盖原有模板内容!` }
// 弹出确认对话框
try { await this.$confirm(confirmMessage, '操作确认', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning', distinguishCancelAndClose: true }) } catch (error) { // 用户取消操作
return }
// 准备保存数据
const templateData = { templateName: row.selectedTemplate.trim(), // ✅ 修复Bug:保持空字符串不变,不要用 || 运算符替换
// 空字符串表示"新增或更新同名模板",非空表示"基于原模板修改"
originalTemplateName: row.originalTemplateName || '', ccuscode: '', // 后端会根据实际情况自动处理
ccusname: row.selectedCustomer.trim(), localShipAddress: row.selectedLocalAddress || '', overseasShipper: row.selectedOverseasShipper || '', overseasAddress: row.selectedOverseasAddress || '', cnative: row.selectedCnative || '', salesArea: row.selectedSalesArea || '' }
try { const { data } = await saveExcelImportTemplate(templateData)
if (data && data.code === 0) { // 判断是新增还是修改,给出不同的成功提示
if (isNewTemplate) { this.$message.success(`模板"${row.selectedTemplate}"保存成功!`) // 保存成功后更新 originalTemplateName,下次保存时就是修改模式
row.originalTemplateName = row.selectedTemplate } else if (isNameChanged) { this.$message.success(`新模板"${row.selectedTemplate}"另存成功!`) // 另存为成功后更新 originalTemplateName
row.originalTemplateName = row.selectedTemplate } else { this.$message.success(`模板"${row.selectedTemplate}"更新成功!`) }
// 保存成功后更新缓存
this.saveToCache() } else { this.$message.error(data.msg || '保存模板失败') } } catch (error) { console.error('保存模板失败:', error) this.$message.error('保存模板失败:' + (error.message || '网络异常')) } }, } }</script><style scoped>/deep/ .delClass .cell { line-height: 24px !important; font-size: 12px !important; height: 24px !important;}
/deep/ .customer-upload .el-upload .el-upload-dragger { width: 580px;}
/* 输入框样式优化 */.el-input.is-readonly { cursor: pointer !important;}
.el-input.is-readonly .el-input__inner { cursor: pointer !important; background-color: #f8f9fa;}
.el-input.is-readonly .el-input__inner:hover { background-color: #e9ecef; border-color: #409EFF;}
/* 编辑图标样式 */.el-input__suffix .el-icon-edit { color: #409EFF; transition: all 0.3s; font-size: 14px; padding: 2px; border-radius: 3px;}
.el-input__suffix .el-icon-edit:hover { color: #ffffff; background-color: #409EFF; transform: scale(1.1);}
/* 编辑弹窗整体样式 */.edit-dialog .el-dialog__body { padding: 20px 20px 0;}
.edit-dialog-tip { margin-bottom: 15px; color: #909399; font-size: 12px; background-color: #f4f4f5; padding: 8px 12px; border-radius: 4px; border-left: 3px solid #409EFF;}
.edit-dialog-tip .el-icon-info { margin-right: 5px; color: #409EFF;}
/* 大输入框样式 */.edit-textarea .el-textarea__inner { resize: vertical !important; min-height: 120px !important; border: 1px solid #dcdfe6 !important; border-radius: 4px !important; padding: 8px 12px !important; font-size: 14px !important; line-height: 1.5 !important; color: #606266 !important; background-color: #fff !important; transition: border-color 0.2s cubic-bezier(.645,.045,.355,1) !important; box-sizing: border-box !important;}
.edit-textarea .el-textarea__inner:focus { outline: none !important; border-color: #409EFF !important; box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.2) !important;}
.edit-textarea .el-input__count { color: #909399 !important; background: #fff !important; position: absolute !important; font-size: 12px !important; bottom: 5px !important; right: 10px !important;}
/* 修复弹窗中的表单项样式 */.edit-dialog .el-form-item { margin-bottom: 18px !important;}
.edit-dialog .el-form-item__label { color: #606266 !important; font-weight: 500 !important; line-height: 1.5 !important; padding: 0 0 8px 0 !important; box-sizing: border-box !important; font-size: 14px !important;}
/* 编辑弹窗按钮样式 */.edit-dialog .dialog-footer { text-align: right !important; padding: 15px 20px 20px !important;}
.edit-dialog .dialog-footer .el-button { margin-left: 10px !important;}
/* 确保弹窗内容不会溢出 */.edit-dialog .el-dialog__wrapper { overflow: hidden;}
.edit-dialog .el-dialog { margin-top: 5vh !important; margin-bottom: 50px !important;}
/* 表格输入框提示文字 */.el-table .el-input__inner::placeholder { font-size: 12px; color: #c0c4cc;}
/* 可点击发票号样式 */.clickable-invoice { cursor: pointer !important; text-decoration: underline; transition: all 0.3s;}
.clickable-invoice:hover { color: #409EFF !important; text-shadow: 0 0 3px rgba(64, 158, 255, 0.3);}
/* 表格样式区分 */.valid-table .el-table__header { background-color: #F0F9FF !important;}
.valid-table .el-table th { background-color: #F0F9FF !important; color: #67C23A !important;}
.invalid-table .el-table__header { background-color: #FEF0F0 !important;}
.invalid-table .el-table th { background-color: #FEF0F0 !important; color: #F56C6C !important;}
.invalid-table .el-table .el-table__row:hover > td { background-color: #FDF2F2 !important;}
/* 物料不存在详情对话框样式 */.invalid-materials-dialog .el-dialog__body { padding: 20px;}
.invalid-materials-content .warning-tip { padding: 12px 16px; background-color: #FEF0F0; border: 1px solid #FBC4C4; border-radius: 4px; margin-bottom: 15px;}
.invalid-materials-content .materials-summary { text-align: center; font-size: 14px;}
.invalid-materials-dialog .el-table th { background-color: #FEF0F0 !important;}
.invalid-materials-dialog .el-table .el-table__row:hover > td { background-color: #FDF2F2 !important;}
/* Sheet错误表格样式 */.warning-table .el-table__header { background-color: #FDF6EC !important;}
.warning-table .el-table th { background-color: #FDF6EC !important; color: #E6A23C !important;}
.warning-table .el-table .el-table__row:hover > td { background-color: #FEF5E7 !important;}
</style>
|