@@ -12417,6 +12531,19 @@ const exchangeRateData=[
{month:'2026-05',averageRate:7.2095,updatedBy:'李芳',updatedAt:'2026-06-03 14:20',remark:'2026年5月平均汇率'},
{month:'2025-12',averageRate:7.1023,updatedBy:'张经理',updatedAt:'2026-01-05 09:05',remark:'2025年12月平均汇率'},
];
+const taxRateData=[
+{id:'TR001',hs:'9503000090',cnName:'塑料玩具/塑料充气装饰品',enName:'TOY',price:'0.85',material:'塑胶',imageUrl:'',imageLabel:'TOY',imageColor:'#f59e0b',basicTax:'Free',additionalTax:''},
+{id:'TR002',hs:'9503000090',cnName:'塑料玩具',enName:'TOY',price:'0.85',material:'塑料',imageUrl:'',imageLabel:'TOY',imageColor:'#22c55e',basicTax:'Free',additionalTax:''},
+{id:'TR003',hs:'6104632011',cnName:'瑜伽裤',enName:'Yoga pants',price:'0.40',material:'涤纶',imageUrl:'',imageLabel:'YOGA',imageColor:'#64748b',basicTax:'28.2%',additionalTax:'7.5%'},
+{id:'TR004',hs:'9404904000',cnName:'抱枕套',enName:'PILLOW COVER',price:'0.30',material:'涤纶',imageUrl:'',imageLabel:'HOME',imageColor:'#ec4899',basicTax:'12%',additionalTax:'5%'},
+{id:'TR005',hs:'4421999090',cnName:'DIY木制工艺品',enName:'CRAFTS',price:'0.56',material:'杉木',imageUrl:'',imageLabel:'WOOD',imageColor:'#a16207',basicTax:'Free',additionalTax:''},
+{id:'TR006',hs:'7323990000',cnName:'锅架',enName:'PAN ORGANIZER',price:'1.00',material:'不锈钢',imageUrl:'',imageLabel:'PAN',imageColor:'#0f766e',basicTax:'2.6%',additionalTax:''},
+{id:'TR007',hs:'3924900000',cnName:'刮铲',enName:'SILICONE SPATULA',price:'1.00',material:'硅胶',imageUrl:'',imageLabel:'KITCHEN',imageColor:'#8b5cf6',basicTax:'3.4%',additionalTax:''},
+{id:'TR008',hs:'6304920000',cnName:'三合板挂饰',enName:'HANGING DECORATION',price:'0.60',material:'杉木+塑料+麻布',imageUrl:'',imageLabel:'DECOR',imageColor:'#ef4444',basicTax:'6.4%',additionalTax:''},
+];
+let taxRateSeq=9;
+let taxRateEditingId='';
+let taxRateImportRows=[];
const genOwnedWarehouseData=[
{id:'OWN001',name:'洛杉矶仓',address:'原型未定义',city:'',state:'',zip:'',country:'美国',status:'启用'},
{id:'OWN002',name:'纽约仓',address:'原型未定义',city:'',state:'',zip:'',country:'美国',status:'启用'},
@@ -13267,7 +13394,18 @@ ctListData.forEach(function(item){
if(typeof item.isAbnormal!=='boolean')item.isAbnormal=false;
if(!Array.isArray(item.abnormalLogs))item.abnormalLogs=[];
if(typeof item.abnormalReason!=='string')item.abnormalReason='';
+ if(!item.pdaMaterials){
+ item.pdaMaterials=[
+ {key:'licensePlate',type:'车牌照片',status:'待接收',file:'',receivedAt:'',source:''},
+ {key:'containerSeal',type:'集装箱封签',status:'待接收',file:'',receivedAt:'',source:''},
+ {key:'openingPhoto',type:'开柜照片',status:'待接收',file:'',receivedAt:'',source:''}
+ ];
+ }
});
+if(ctListData[0]&&ctListData[0].pdaMaterials){
+ Object.assign(ctListData[0].pdaMaterials[0],{status:'已接收',file:'PDA_车牌照片_FFAU6685194.jpg',receivedAt:'2026-08-13 10:25',source:'PDA'});
+ Object.assign(ctListData[0].pdaMaterials[1],{status:'已接收',file:'PDA_集装箱封签_FFAU6685194.jpg',receivedAt:'2026-08-13 10:26',source:'PDA'});
+}
const ctCostData=[
{id:'COST001',ctNo:'FFAU6685194',type:'港口费',amount:850,currency:'USD',date:'2026-07-16',remark:'洛杉矶港港口操作费'},
{id:'COST002',ctNo:'CSNU9332868',type:'堆存费',amount:320,currency:'USD',date:'2026-07-17',remark:'堆存3天'},
@@ -13379,11 +13517,11 @@ const fbaReturnOutboundData = [
/* FBA退货 - 入库单数据 */
const fbaInboundOrderData = [
-{inboundNo:'FBIO20260720001',bolNo:'BOL260720001',type:'国内订单',wh:'洛杉矶长滩海外仓',owner:'杭州积乐',totalBoxes:120,chargeVol:24.5,palletTotal:4,palletType:'标准托盘',isOutsourced:false,status:'待审核',fees:[{name:'打托费',currency:'USD',amount:120,remark:'入库打托作业'},{name:'拆柜费',currency:'USD',amount:280,remark:'集装箱拆柜'},{name:'提柜费',currency:'USD',amount:350,remark:'码头提柜'}]},
-{inboundNo:'FBIO20260721002',bolNo:'BOL260720002',type:'海外订单',wh:'纽约海外仓',owner:'岩盛、欧业',totalBoxes:200,chargeVol:38.0,palletTotal:6,palletType:'木托盘',isOutsourced:true,status:'已审核',fees:[{name:'打托费',currency:'USD',amount:180,remark:'入库打托作业'},{name:'拆柜费',currency:'USD',amount:320,remark:'集装箱拆柜'},{name:'提柜费',currency:'USD',amount:420,remark:'码头提柜'}]},
-{inboundNo:'FBIO20260722003',bolNo:'BOL260220003',type:'海外订单',wh:'汉堡海外仓',owner:'上海粤讯',totalBoxes:80,chargeVol:15.2,palletTotal:3,palletType:'纸托盘',isOutsourced:false,status:'已入库',fees:[{name:'打托费',currency:'USD',amount:95,remark:'入库打托作业'},{name:'拆柜费',currency:'USD',amount:240,remark:'集装箱拆柜'},{name:'提柜费',currency:'USD',amount:310,remark:'码头提柜'}]},
-{inboundNo:'FBIO20260723004',bolNo:'BOL260240004',type:'国内订单',wh:'洛杉矶长滩海外仓',owner:'义乌卓越',totalBoxes:150,chargeVol:29.8,palletTotal:5,palletType:'标准托盘',isOutsourced:true,status:'待审核',fees:[{name:'打托费',currency:'USD',amount:150,remark:'入库打托作业'},{name:'拆柜费',currency:'USD',amount:300,remark:'集装箱拆柜'},{name:'提柜费',currency:'USD',amount:380,remark:'码头提柜'}]},
-{inboundNo:'FBIO20260725005',bolNo:'BOL260250005',type:'国内订单',wh:'纽约海外仓',owner:'杭州积乐',totalBoxes:90,chargeVol:18.6,palletTotal:3,palletType:'木托盘',isOutsourced:false,status:'已审核',fees:[{name:'打托费',currency:'USD',amount:105,remark:'入库打托作业'},{name:'拆柜费',currency:'USD',amount:260,remark:'集装箱拆柜'},{name:'提柜费',currency:'USD',amount:330,remark:'码头提柜'}]},
+{inboundNo:'FBIO20260720001',bolNo:'BOL260720001',type:'国内订单',wh:'洛杉矶长滩海外仓',owner:'杭州积乐',productName:'蓝牙耳机套件',totalBoxes:120,chargeVol:24.5,palletTotal:4,palletType:'标准托盘',isOutsourced:false,status:'待审核',palletDetails:[{palletNo:'PAL-A1001-01',productName:'蓝牙耳机套件',boxes:32,photoName:'打托照片_PAL-A1001-01.jpg',photo:'https://images.unsplash.com/photo-1586528116311-ad8dd3c8310d?auto=format&fit=crop&w=900&q=80'},{palletNo:'PAL-A1001-02',productName:'蓝牙耳机套件',boxes:30,photoName:'打托照片_PAL-A1001-02.jpg',photo:'https://images.unsplash.com/photo-1586528116311-ad8dd3c8310d?auto=format&fit=crop&w=900&q=80'},{palletNo:'PAL-A1001-03',productName:'蓝牙耳机套件',boxes:30,photo:''},{palletNo:'PAL-A1001-04',productName:'蓝牙耳机套件',boxes:28,photo:''}],fees:[{name:'打托费',currency:'USD',amount:120,remark:'入库打托作业'},{name:'拆柜费',currency:'USD',amount:280,remark:'集装箱拆柜'},{name:'提柜费',currency:'USD',amount:350,remark:'码头提柜'}]},
+{inboundNo:'FBIO20260721002',bolNo:'BOL260720002',type:'海外订单',wh:'纽约海外仓',owner:'岩盛、欧业',productName:'手机保护壳',totalBoxes:200,chargeVol:38.0,palletTotal:6,palletType:'木托盘',isOutsourced:true,status:'已审核',palletDetails:[{palletNo:'PAL-B2002-01',productName:'手机保护壳',boxes:34,photoName:'打托照片_PAL-B2002-01.jpg',photo:'https://images.unsplash.com/photo-1586528116311-ad8dd3c8310d?auto=format&fit=crop&w=900&q=80'},{palletNo:'PAL-B2002-02',productName:'手机保护壳',boxes:34,photo:''},{palletNo:'PAL-B2002-03',productName:'手机保护壳',boxes:34,photo:''},{palletNo:'PAL-B2002-04',productName:'手机保护壳',boxes:34,photo:''},{palletNo:'PAL-B2002-05',productName:'手机保护壳',boxes:32,photo:''},{palletNo:'PAL-B2002-06',productName:'手机保护壳',boxes:32,photo:''}],fees:[{name:'打托费',currency:'USD',amount:180,remark:'入库打托作业'},{name:'拆柜费',currency:'USD',amount:320,remark:'集装箱拆柜'},{name:'提柜费',currency:'USD',amount:420,remark:'码头提柜'}]},
+{inboundNo:'FBIO20260722003',bolNo:'BOL260220003',type:'海外订单',wh:'汉堡海外仓',owner:'上海粤讯',productName:'充电器套装',totalBoxes:80,chargeVol:15.2,palletTotal:3,palletType:'纸托盘',isOutsourced:false,status:'已入库',fees:[{name:'打托费',currency:'USD',amount:95,remark:'入库打托作业'},{name:'拆柜费',currency:'USD',amount:240,remark:'集装箱拆柜'},{name:'提柜费',currency:'USD',amount:310,remark:'码头提柜'}]},
+{inboundNo:'FBIO20260723004',bolNo:'BOL260240004',type:'国内订单',wh:'洛杉矶长滩海外仓',owner:'义乌卓越',productName:'LED台灯',totalBoxes:150,chargeVol:29.8,palletTotal:5,palletType:'标准托盘',isOutsourced:true,status:'待审核',fees:[{name:'打托费',currency:'USD',amount:150,remark:'入库打托作业'},{name:'拆柜费',currency:'USD',amount:300,remark:'集装箱拆柜'},{name:'提柜费',currency:'USD',amount:380,remark:'码头提柜'}]},
+{inboundNo:'FBIO20260725005',bolNo:'BOL260250005',type:'国内订单',wh:'纽约海外仓',owner:'杭州积乐',productName:'收纳盒组合',totalBoxes:90,chargeVol:18.6,palletTotal:3,palletType:'木托盘',isOutsourced:false,status:'已审核',fees:[{name:'打托费',currency:'USD',amount:105,remark:'入库打托作业'},{name:'拆柜费',currency:'USD',amount:260,remark:'集装箱拆柜'},{name:'提柜费',currency:'USD',amount:330,remark:'码头提柜'}]},
];
const fbioQueryMeta=[
{deliveryWh:'宁波仓',warehouseCode:'RK26072001',eta:'2026-07-28',feeAudit:'已审核',containerNo:'MSCU7283910',cabinetNo:'40HQ-001',channel:'洛杉矶普船海卡',sailingDate:'2026-07-22',loaded:'是',fullContainer:'是',measureAudit:'已审核',fbaCode:'ONT8-A1001',createdDate:'2026-07-20'},
@@ -13489,7 +13627,7 @@ const dispatchBolPrintData = [
];
const staticDispatchRecords = [
{dispatchNo:'YWBHK260820001',bolNo:'BOL20260820001',status:'已签收',pickingStatus:'拣货完成',customer:'义乌市赛恩进出口有限公司',contact:'陈女士 13800138101',warehouse:'洛杉矶长滩海外仓',destFba:'FBA ONT8',expressNo:'UPS20260820001',outboundAt:'2026-08-18 09:00:00',deliveredAt:'2026-08-20 15:36',courierNodes:[{time:'2026-08-20 15:36',status:'已签收'}]},
- {dispatchNo:'YWBHK260818002',bolNo:'BOL20260818002',status:'已签收',pickingStatus:'拣货完成',customer:'上海粤讯供应链有限公司',contact:'刘先生 13900139102',warehouse:'纽约海外仓',destFba:'FBA CLT2',expressNo:'FEDEX20260818002',outboundAt:'2026-08-16 13:20:00',signedAt:'2026-08-18 11:08',courierNodes:[{time:'2026-08-18 11:08',status:'已签收'}],customerFollowup:{status:'已回访',followedUpAt:'2026-08-19 10:20',operator:'王客服',result:'满意',feedback:'客户确认货物完好,派送时效符合预期。',note:'',attachments:[{fileName:'客户回访记录_0819.pdf',uploadedAt:'2026-08-19 10:18',size:186320}]}},
+ {dispatchNo:'YWBHK260818002',bolNo:'BOL20260818002',status:'已签收',pickingStatus:'拣货完成',customer:'上海粤讯供应链有限公司',contact:'刘先生 13900139102',warehouse:'纽约海外仓',destFba:'FBA CLT2',expressNo:'FEDEX20260818002',outboundAt:'2026-08-16 13:20:00',signedAt:'2026-08-18 11:08',courierNodes:[{time:'2026-08-18 11:08',status:'已签收'}],customerFollowup:{status:'已回访',followedUpAt:'2026-08-19 10:20',operator:'王客服',result:'已接收',feedback:'客户确认货物完好,派送时效符合预期。',note:'',attachments:[{fileName:'客户回访记录_0819.pdf',uploadedAt:'2026-08-19 10:18',size:186320}]}},
{dispatchNo:'YWBHK260815003',bolNo:'BOL20260815003',status:'已签收',pickingStatus:'拣货完成',customer:'宁波远洋供应链有限公司',contact:'孙女士 13700137103',warehouse:'汉堡海外仓',destFba:'DE Frankfurt',expressNo:'DHL20260815003',outboundAt:'2026-08-14 08:45:00',completedAt:'2026-08-15 17:42',courierNodes:[{time:'2026-08-15 17:42',status:'已签收'}]},
{dispatchNo:'YWBHK200615001',bolNo:'BOL20260615001',status:'待派送',pickingStatus:'已拣货',customer:'义乌欧业进出口有限公司',contact:'张三 13800138000',expressNo:'SF1234567890',outboundAt:'2026-06-15 14:00:00',courierNodes:[],fleetVehicleId:'VD4'},
{dispatchNo:'YWBHK200615002',bolNo:'BOL20260615002',status:'已签收',pickingStatus:'拣货完成',customer:'青岛远航贸易有限公司',contact:'李四 13900139000',expressNo:'UPS20260615002',outboundAt:'2026-06-14 16:30:00',courierNodes:[]},
@@ -13692,6 +13830,7 @@ const menuPermTree = [
{key:'gen-product',label:'产品信息'},
{key:'gen-fee',label:'费用项目'},
{key:'gen-exchange-rate',label:'汇率管理'},
+ {key:'gen-tax-rate',label:'税率查询表'},
{key:'gen-fba',label:'仓库管理'},
{key:'gen-download',label:'下载中心'},
{key:'gen-pallet',label:'托盘管理'},
@@ -13723,6 +13862,7 @@ roleData.forEach(role=>{
role.perms=role.perms.filter(key=>key!=='sys-tenant'&&key!=='sys-brand');
if(role.perms.includes('gen-fba')&&!role.perms.includes('gen-download'))role.perms.push('gen-download');
if(role.perms.includes('gen-fee')&&!role.perms.includes('gen-exchange-rate'))role.perms.push('gen-exchange-rate');
+if(role.perms.includes('gen-exchange-rate')&&!role.perms.includes('gen-tax-rate'))role.perms.push('gen-tax-rate');
if(role.code==='SUPER_ADMIN'&&!role.perms.includes('sys-menu-permissions'))role.perms.push('sys-menu-permissions');
});
@@ -15980,6 +16120,62 @@ document.getElementById('exchange-rate-month-filter').value='';
renderExchangeRates();
}
+function taxRateImageSrc(label,color){
+const svg='
';
+return 'data:image/svg+xml;charset=UTF-8,'+encodeURIComponent(svg);
+}
+
+function taxRateEscape(value){return String(value??'').replace(/[&<>"']/g,c=>({'&':'&','<':'<','>':'>','"':'"',"'":'''}[c]));}
+function taxRateUniqueKey(item){return [item.hs,item.cnName,item.enName].map(value=>String(value||'').trim().toLowerCase()).join('|');}
+function taxRateImage(item){const fallback=taxRateImageSrc(item.imageLabel||'IMAGE',item.imageColor||'#64748b');return item.imageUrl?'
+')
':'

';}
+function validateTaxRate(item,ignoreId,existing){
+const required=[['HS',item.hs],['中文品名',item.cnName],['英文品名',item.enName],['材质',item.material],['基础关税',item.basicTax]];
+for(const entry of required)if(!String(entry[1]||'').trim())return entry[0]+'不能为空';
+if(item.price===''||item.price===null||item.price===undefined||!Number.isFinite(Number(item.price))||Number(item.price)<0)return '价格必须为大于等于 0 的数字';
+if(item.imageUrl){try{new URL(item.imageUrl);}catch(error){return '产品图片必须是有效 URL';}}
+const key=taxRateUniqueKey(item);if(existing.some(row=>row.id!==ignoreId&&taxRateUniqueKey(row)===key))return 'HS、中文品名、英文品名组合已存在';
+return '';
+}
+
+function getFilteredTaxRates(){const filters=getTaxRateFilters();return taxRateData.filter(item=>(!filters.hs||item.hs.toLowerCase().includes(filters.hs))&&(!filters.cn||item.cnName.toLowerCase().includes(filters.cn))&&(!filters.en||item.enName.toLowerCase().includes(filters.en)));}
+
+function getTaxRateFilters(){
+return {
+hs:(document.getElementById('tax-rate-hs-filter')||{}).value?.trim().toLowerCase()||'',
+cn:(document.getElementById('tax-rate-cn-filter')||{}).value?.trim().toLowerCase()||'',
+en:(document.getElementById('tax-rate-en-filter')||{}).value?.trim().toLowerCase()||''
+};
+}
+
+function renderTaxRates(){
+const tbody=document.getElementById('tbody-gen-tax-rate');
+if(!tbody)return;
+const rows=getFilteredTaxRates();
+tbody.innerHTML=rows.length?rows.map(item=>'
| '+taxRateEscape(item.hs)+' | '+taxRateEscape(item.cnName)+' | '+taxRateEscape(item.enName)+' | '+taxRateEscape(item.price)+' | '+taxRateEscape(item.material)+' | '+taxRateImage(item)+' | '+taxRateEscape(item.basicTax)+' | '+taxRateEscape(item.additionalTax||'-')+' | |
').join(''):'
| 暂无匹配的税率记录 |
';
+}
+
+function resetTaxRateFilters(){
+['tax-rate-hs-filter','tax-rate-cn-filter','tax-rate-en-filter'].forEach(id=>{const input=document.getElementById(id);if(input)input.value='';});
+renderTaxRates();
+}
+
+function updateTaxRateImagePreview(){const input=document.getElementById('tax-rate-form-image');const preview=document.getElementById('tax-rate-form-image-preview');if(!preview)return;const url=input&&input.value.trim();preview.src=url||taxRateImageSrc('IMAGE','#64748b');preview.onerror=function(){this.onerror=null;this.src=taxRateImageSrc('IMAGE','#64748b');};}
+function clearTaxRateForm(){['hs','cn','en','price','material','image','basic-tax','additional-tax'].forEach(key=>{const el=document.getElementById('tax-rate-form-'+key);if(el)el.value='';});updateTaxRateImagePreview();}
+function openTaxRateModal(id){taxRateEditingId=id||'';const record=taxRateData.find(item=>item.id===taxRateEditingId);document.getElementById('tax-rate-modal-title').textContent=record?'编辑税率':'新增税率';clearTaxRateForm();if(record){document.getElementById('tax-rate-form-hs').value=record.hs;document.getElementById('tax-rate-form-cn').value=record.cnName;document.getElementById('tax-rate-form-en').value=record.enName;document.getElementById('tax-rate-form-price').value=record.price;document.getElementById('tax-rate-form-material').value=record.material;document.getElementById('tax-rate-form-image').value=record.imageUrl||'';document.getElementById('tax-rate-form-basic-tax').value=record.basicTax;document.getElementById('tax-rate-form-additional-tax').value=record.additionalTax||'';updateTaxRateImagePreview();}showModal('modal-tax-rate-edit');}
+function readTaxRateForm(){return {hs:document.getElementById('tax-rate-form-hs').value.trim(),cnName:document.getElementById('tax-rate-form-cn').value.trim(),enName:document.getElementById('tax-rate-form-en').value.trim(),price:document.getElementById('tax-rate-form-price').value.trim(),material:document.getElementById('tax-rate-form-material').value.trim(),imageUrl:document.getElementById('tax-rate-form-image').value.trim(),basicTax:document.getElementById('tax-rate-form-basic-tax').value.trim(),additionalTax:document.getElementById('tax-rate-form-additional-tax').value.trim()};}
+function saveTaxRate(){const value=readTaxRateForm();const error=validateTaxRate(value,taxRateEditingId,taxRateData);if(error){showToast(error,'warning');return;}const index=taxRateData.findIndex(item=>item.id===taxRateEditingId);const id=taxRateEditingId||'TR'+String(taxRateSeq++).padStart(3,'0');const record=Object.assign({id:id,imageLabel:'IMAGE',imageColor:'#64748b'},value);if(index>-1)taxRateData.splice(index,1,record);else taxRateData.push(record);hideModal('modal-tax-rate-edit');renderTaxRates();showToast(index>-1?'税率记录已更新':'税率记录已新增','success');}
+function deleteTaxRate(id){const index=taxRateData.findIndex(item=>item.id===id);if(index<0)return;const item=taxRateData[index];if(!window.confirm('确定删除 '+item.cnName+' 的税率记录吗?'))return;taxRateData.splice(index,1);renderTaxRates();showToast('税率记录已删除','success');}
+
+const taxRateExcelFields=[{header:'HS',key:'hs',required:true},{header:'中文品名',key:'cnName',required:true},{header:'英文品名',key:'enName',required:true},{header:'价格',key:'price',required:true},{header:'材质',key:'material',required:true},{header:'产品图片',key:'imageUrl',required:false},{header:'基础关税',key:'basicTax',required:true},{header:'附加税',key:'additionalTax',required:false}];
+function taxRateExcelRows(rows){return rows.map(item=>taxRateExcelFields.reduce((row,field)=>{row[field.header]=item[field.key]||'';return row;},{}));}
+function taxRateWorkbookDownload(filename,rows){if(typeof XLSX==='undefined'){showToast('Excel 组件未加载','error');return;}const sheet=XLSX.utils.json_to_sheet(rows);const book=XLSX.utils.book_new();XLSX.utils.book_append_sheet(book,sheet,'税率查询表');XLSX.writeFile(book,filename);}
+function downloadTaxRateTemplate(){taxRateWorkbookDownload('税率查询表导入模板.xlsx',[{hs:'9503000090',cnName:'示例塑料玩具',enName:'TOY',price:'0.85',material:'塑料',imageUrl:'https://example.com/toy.jpg',basicTax:'Free',additionalTax:''}].map(item=>taxRateExcelRows([item])[0]));}
+function exportTaxRates(){const rows=getFilteredTaxRates();if(!rows.length){showToast('当前查询结果为空','warning');return;}const date=new Date();const stamp=date.getFullYear()+String(date.getMonth()+1).padStart(2,'0')+String(date.getDate()).padStart(2,'0');taxRateWorkbookDownload('税率查询表-'+stamp+'.xlsx',taxRateExcelRows(rows));showToast('税率查询结果已导出','success');}
+function openTaxRateImportModal(){taxRateImportRows=[];const file=document.getElementById('tax-rate-import-file');if(file)file.value='';document.getElementById('tax-rate-import-summary').textContent='尚未选择文件';document.getElementById('tax-rate-import-confirm').disabled=true;document.getElementById('tbody-tax-rate-import-preview').innerHTML='
| 选择文件后显示前 10 条数据 |
';showModal('modal-tax-rate-import');}
+function renderTaxRateImportPreview(){const summary=document.getElementById('tax-rate-import-summary');const body=document.getElementById('tbody-tax-rate-import-preview');const confirm=document.getElementById('tax-rate-import-confirm');const valid=taxRateImportRows.filter(row=>!row.error).length;summary.innerHTML=taxRateImportRows.length?'共读取
'+taxRateImportRows.length+' 条,可导入
'+valid+' 条,失败
'+(taxRateImportRows.length-valid)+' 条':'尚未选择文件';body.innerHTML=taxRateImportRows.length?taxRateImportRows.slice(0,10).map(row=>'
| '+row.rowNumber+' | '+(row.error||'通过')+' | '+taxRateEscape(row.data.hs)+' | '+taxRateEscape(row.data.cnName)+' | '+taxRateEscape(row.data.enName)+' | '+taxRateEscape(row.data.price)+' | '+taxRateEscape(row.data.material)+' | '+taxRateEscape(row.data.imageUrl)+' | '+taxRateEscape(row.data.basicTax)+' | '+taxRateEscape(row.data.additionalTax)+' |
').join(''):'
| 选择文件后显示前 10 条数据 |
';confirm.disabled=!taxRateImportRows.length||valid!==taxRateImportRows.length;}
+function handleTaxRateImportFile(input){const file=input&&input.files&&input.files[0];if(!file)return;if(!/\.xlsx$/i.test(file.name)){showToast('仅支持 .xlsx 文件','warning');input.value='';return;}if(typeof XLSX==='undefined'){showToast('Excel 组件未加载','error');return;}const reader=new FileReader();reader.onload=function(event){try{const workbook=XLSX.read(event.target.result,{type:'array'});const sheet=workbook.Sheets[workbook.SheetNames[0]];const matrix=XLSX.utils.sheet_to_json(sheet,{header:1,defval:''});if(!matrix.length)throw new Error('文件没有数据');const headers=matrix[0].map(value=>String(value).trim());if(taxRateExcelFields.some(field=>headers.indexOf(field.header)<0))throw new Error('表头必须包含:'+taxRateExcelFields.map(field=>field.header).join('、'));const rows=[];const keys=new Set();for(let index=1;index
String(value).trim()===''))continue;const data={};taxRateExcelFields.forEach(field=>{const cell=cells[headers.indexOf(field.header)];data[field.key]=cell===undefined?'':String(cell).trim();});let error=validateTaxRate(data,'',taxRateData);const key=taxRateUniqueKey(data);if(!error&&keys.has(key))error='导入文件内存在重复组合';if(!error)keys.add(key);rows.push({rowNumber:index+1,data:data,error:error});}taxRateImportRows=rows;renderTaxRateImportPreview();}catch(error){taxRateImportRows=[];renderTaxRateImportPreview();showToast(error.message||'文件解析失败','error');}};reader.readAsArrayBuffer(file);}
+function confirmTaxRateImport(){if(!taxRateImportRows.length||taxRateImportRows.some(row=>row.error)){showToast('导入文件存在错误,无法整批导入','warning');return;}taxRateImportRows.forEach(row=>taxRateData.push(Object.assign({id:'TR'+String(taxRateSeq++).padStart(3,'0'),imageLabel:'IMAGE',imageColor:'#64748b'},row.data)));const count=taxRateImportRows.length;hideModal('modal-tax-rate-import');renderTaxRates();showToast('导入完成:成功 '+count+' 条','success');}
+
function updateExchangeRateOverwriteHint(){
const month=document.getElementById('exchange-rate-month').value;
const exists=exchangeRateData.some(item=>item.month===month);
@@ -18821,6 +19017,27 @@ function buildCtPalletLabels(containers,manifests,detailMap){
let currentCtPalletLabels=[];
const ctPalletLabelFontSizes={code:120,destination:180};
var ctPalletLabelReturnFocus=null;
+function renderCtPalletLabelBarcodes(){
+ const nodes=Array.from(document.querySelectorAll('.ct-pallet-label-barcode'));
+ nodes.forEach(function(svg){
+ const value=svg.dataset.barcodeValue||'';
+ const fallback=svg.nextElementSibling;
+ if(!value||typeof window.JsBarcode!=='function'){
+ svg.hidden=true;
+ if(fallback)fallback.hidden=false;
+ return;
+ }
+ try{
+ window.JsBarcode(svg,value,{format:'CODE128',displayValue:false,width:3,height:96,margin:0});
+ svg.hidden=false;
+ if(fallback)fallback.hidden=true;
+ }catch(error){
+ svg.hidden=true;
+ if(fallback)fallback.hidden=false;
+ console.error('托盘标条形码生成失败',value,error);
+ }
+ });
+}
function renderCtPalletLabelPreview(){
const modal=document.getElementById('modal-ct-pallet-label-preview');
const list=document.getElementById('ct-pallet-label-list');
@@ -18842,8 +19059,9 @@ function renderCtPalletLabelPreview(){
list.innerHTML=currentCtPalletLabels.map(function(label,index){
const code=escapeMfAttr(label&&label.code);
const destination=escapeMfAttr(label&&label.destWh);
- return `${code}
${destination}
`;
+ return `${code}
${destination}
条形码生成失败
`;
}).join('');
+ renderCtPalletLabelBarcodes();
}
function openCtPalletLabelPreview(){
const checked=Array.from(document.querySelectorAll('.ct-row-cb:checked'));
@@ -18910,7 +19128,7 @@ document.addEventListener('keydown',function(event){
});
function renderCtList(){renderTable('tbody-ct-list',ctListData,['_cb','_act','_emptyWarning','no','manifest','status','isAbnormal','ctNo','clearDoc','releaseDoc','puDoc','fleet','wh','bl','vessel','type','carrier','pol','pod','vol','time','etd','atd','eta','ata','pickupExpectedAt','appointmentAt','emptiedAt','returnedAt'],(d,c,i)=>{
if(c==='_cb')return ``;
-if(c==='_act')return `编辑 清关 ${d.isAbnormal?'取消异常':'标记异常'} 更多 ∨`;
+if(c==='_act')return `编辑 清关 ${d.isAbnormal?'取消异常':'标记异常'} 更多 ∨ 管理资料`;
if(c==='status')return renderContainerStatusTag(d.status);
if(c==='isAbnormal')return renderAbnormalTag(getContainerAbnormalState(d.no));
if(c==='fleet'){
@@ -18958,7 +19176,67 @@ function mfUploadDoc(no,key,el){
};
inp.click();
}
-function showCtMore(i){showToast('更多操作:详情 / 跟踪 / 日志');}
+let currentCtMaterialsIndex=-1;
+function showCtMore(i){
+ const d=ctListData[i];
+ if(!d){showToast('未找到该货柜','warning');return;}
+ currentCtMaterialsIndex=i;
+ const el=document.getElementById('ct-more-container');
+ if(el)el.textContent=d.no||d.ctNo||'—';
+ showModal('modal-ct-more');
+}
+function openCtMaterials(index){
+ const d=ctListData[index];
+ if(!d){showToast('未找到该货柜','warning');return;}
+ currentCtMaterialsIndex=index;
+ const container=d.ctNo||d.no||'—';
+ const title=document.getElementById('ct-materials-title');
+ const noEl=document.getElementById('ct-materials-container');
+ if(title)title.textContent='管理资料 - '+container;
+ if(noEl)noEl.textContent=container;
+ renderCtMaterials(d);
+ showModal('modal-ct-materials');
+}
+function renderCtMaterials(d){
+ const body=document.getElementById('ct-materials-body');
+ if(!body)return;
+ const materials=Array.isArray(d.pdaMaterials)?d.pdaMaterials:[];
+ const received=materials.filter(m=>m.status==='已接收').length;
+ const summary=document.getElementById('ct-materials-summary');
+ if(summary)summary.textContent='已接收 '+received+' / 3 类';
+ body.innerHTML=materials.map(function(m,idx){
+ const ok=m.status==='已接收';
+ const file=m.file?'📎 '+m.file+'':'暂无文件';
+ const view=ok?'查看照片':'';
+ const upload='上传';
+ const action=''+view+upload+'';
+ return '| '+m.type+' | '+(m.status||'待接收')+' | '+file+' | '+(m.receivedAt||'—')+' | '+(m.source||'—')+' | '+action+' |
';
+ }).join('');
+}
+function uploadCtMaterial(index){
+ const d=ctListData[currentCtMaterialsIndex];
+ if(!d||!d.pdaMaterials||!d.pdaMaterials[index])return;
+ const m=d.pdaMaterials[index];
+ const inp=document.createElement('input');
+ inp.type='file';
+ inp.accept='.jpg,.jpeg,.png,.webp';
+ inp.style.display='none';
+ const cleanup=function(){if(inp.parentNode)inp.parentNode.removeChild(inp);};
+ inp.onchange=function(){
+ const file=inp.files&&inp.files[0];
+ if(!file){cleanup();return;}
+ m.status='已接收';
+ m.file=file.name;
+ m.receivedAt=new Date().toISOString().slice(0,16).replace('T',' ');
+ m.source='手动上传';
+ renderCtMaterials(d);
+ showToast(m.type+'上传成功','success');
+ cleanup();
+ };
+ inp.oncancel=cleanup;
+ document.body.appendChild(inp);
+ inp.click();
+}
function ctClearance(no){
var d=ctListData.find(function(x){return x.no===no;});
if(!d){showToast('未找到该货柜','warning');return;}
@@ -21504,13 +21782,54 @@ function renderFbaReceivableFees(bodyId,totalId,fees){
totalNode.textContent='$'+total.toFixed(2);
}
function renderFbaInboundFees(fees){renderFbaReceivableFees('fbd-inbound-fees','fbd-inbound-fee-total',fees);}
+function getFbaInboundPalletDetails(record){
+ const explicit=Array.isArray(record&&record.palletDetails)?record.palletDetails.filter(Boolean):[];
+ if(explicit.length)return explicit;
+ const count=Math.max(0,Math.floor(Number(record&&record.palletTotal)||0));
+ if(!count)return [];
+ const totalBoxes=Math.max(0,Math.floor(Number(record&&record.totalBoxes)||0));
+ const base=Math.floor(totalBoxes/count),remainder=totalBoxes%count;
+ return Array.from({length:count},(_,index)=>({
+ palletNo:(record&&record.inboundNo?record.inboundNo:'PAL')+'-P'+String(index+1).padStart(2,'0'),
+ productName:record&&record.productName||'—',
+ boxes:base+(index{
+ const palletNo=lmoEsc(fbaDetailDisplay(item.palletNo)),productName=lmoEsc(fbaDetailDisplay(item.productName)),boxes=lmoEsc(fbaDetailDisplay(item.boxes)),photo=String(item.photo||'').trim(),photoName=lmoEsc(fbaDetailDisplay(item.photoName||'打托照片_'+String(item.palletNo||'托盘')+'.jpg'));
+ const photoCell=photo?'':'暂无附件';
+ return '| '+palletNo+' | '+productName+' | '+boxes+' | '+photoCell+' |
';
+ }).join(''):'| 暂无托盘明细 |
';
+}
+function openFbaInboundPalletPhoto(photo,palletNo){
+ const image=document.getElementById('fbd-inbound-photo-preview-image'),caption=document.getElementById('fbd-inbound-photo-preview-caption');
+ if(!image||!photo)return;
+ image.src=photo;image.alt=fbaDetailDisplay(palletNo)+' 打托照片';
+ if(caption)caption.textContent=fbaDetailDisplay(palletNo)+' · 打托照片';
+ image.onerror=function(){this.onerror=null;this.alt='打托照片加载失败';showToast('打托照片加载失败,请检查附件地址','error');};
+ showModal('modal-fbd-inbound-photo-preview');
+}
+function closeFbaInboundPalletPhoto(){
+ const image=document.getElementById('fbd-inbound-photo-preview-image'),caption=document.getElementById('fbd-inbound-photo-preview-caption');
+ if(image){image.src='';image.alt='打托照片预览';image.onerror=null;}
+ if(caption)caption.textContent='打托照片';
+ hideModal('modal-fbd-inbound-photo-preview');
+}
function renderFbaOutboundFees(fees){renderFbaReceivableFees('fbd-outbound-fees','fbd-outbound-fee-total',fees);}
function openFbaInboundOrderDetail(no){
const d=fbaInboundOrderData.find(item=>item.inboundNo===no);
if(!d){showToast('未找到入库单记录','error');return;}
- showFbaReadOnlyDetail('fba-inbound-order-detail','fbd-inbound-no','fbd-inbound-status',d.inboundNo,d.status,'fbd-inbound-content',[
+ showFbaReadOnlyDetail('fba-inbound-order-detail','fbd-inbound-no','fbd-inbound-status',d.inboundNo,d.status,'fbd-inbound-top-content',[
{title:'单据信息',rows:[['入库单号',d.inboundNo],['入仓码',d.warehouseCode],['类型',d.type],['货主',d.owner],['关联订单',d.relatedOrderNo]]},
- {title:'仓储信息',rows:[['海外仓',d.wh],['FBA仓库',getFbioFbaWarehouse(d)],['总箱数',d.totalBoxes],['计费体积(m³)',d.chargeVol],['总托盘数',d.palletTotal],['托盘类型',getInboundPalletType(d)],['是否外配',formatInboundOutsourced(d)],['是否加急',formatInboundUrgent(d)]]},
+ {title:'仓储信息',rows:[['海外仓',d.wh],['FBA仓库',getFbioFbaWarehouse(d)],['总箱数',d.totalBoxes],['计费体积(m³)',d.chargeVol],['总托盘数',d.palletTotal],['托盘类型',getInboundPalletType(d)],['是否外配',formatInboundOutsourced(d)],['是否加急',formatInboundUrgent(d)]]}
+ ]);
+ renderFbaInboundPalletDetails(d);
+ renderFbaReadOnlyDetail('fbd-inbound-appointment-content',[
{title:'预约与排车',rows:[['状态',d.status],['预约状态',d.appointmentStatus||'未预约'],['预约送仓时间',d.appointmentDate||'—'],['预计装车时间',d.estimatedLoadingTime||'—'],['排车状态',d.scheduleStatus||'未排车'],['创建时间',d.createdAt],['更新时间',d.updatedAt],['备注',d.remark]]}
]);
renderFbaInboundFees(d.fees);
@@ -23123,6 +23442,7 @@ if(page==='rpt-business')renderRptBusiness();
if(page==='gen-product')renderGenProduct();
if(page==='gen-fee')renderGenFee();
if(page==='gen-exchange-rate')renderExchangeRates();
+if(page==='gen-tax-rate')renderTaxRates();
if(page==='gen-owned-warehouse')renderOwnedWarehouse();
if(page==='gen-fba')renderGenFba();
if(page==='gen-partner-warehouse')renderPartnerWarehouse();
diff --git a/悦/货代SAAS平台后台/prototype-src/app.js b/悦/货代SAAS平台后台/prototype-src/app.js
index 5f05259..91f0795 100644
--- a/悦/货代SAAS平台后台/prototype-src/app.js
+++ b/悦/货代SAAS平台后台/prototype-src/app.js
@@ -129,6 +129,19 @@ const exchangeRateData=[
{month:'2026-05',averageRate:7.2095,updatedBy:'李芳',updatedAt:'2026-06-03 14:20',remark:'2026年5月平均汇率'},
{month:'2025-12',averageRate:7.1023,updatedBy:'张经理',updatedAt:'2026-01-05 09:05',remark:'2025年12月平均汇率'},
];
+const taxRateData=[
+{id:'TR001',hs:'9503000090',cnName:'塑料玩具/塑料充气装饰品',enName:'TOY',price:'0.85',material:'塑胶',imageUrl:'',imageLabel:'TOY',imageColor:'#f59e0b',basicTax:'Free',additionalTax:''},
+{id:'TR002',hs:'9503000090',cnName:'塑料玩具',enName:'TOY',price:'0.85',material:'塑料',imageUrl:'',imageLabel:'TOY',imageColor:'#22c55e',basicTax:'Free',additionalTax:''},
+{id:'TR003',hs:'6104632011',cnName:'瑜伽裤',enName:'Yoga pants',price:'0.40',material:'涤纶',imageUrl:'',imageLabel:'YOGA',imageColor:'#64748b',basicTax:'28.2%',additionalTax:'7.5%'},
+{id:'TR004',hs:'9404904000',cnName:'抱枕套',enName:'PILLOW COVER',price:'0.30',material:'涤纶',imageUrl:'',imageLabel:'HOME',imageColor:'#ec4899',basicTax:'12%',additionalTax:'5%'},
+{id:'TR005',hs:'4421999090',cnName:'DIY木制工艺品',enName:'CRAFTS',price:'0.56',material:'杉木',imageUrl:'',imageLabel:'WOOD',imageColor:'#a16207',basicTax:'Free',additionalTax:''},
+{id:'TR006',hs:'7323990000',cnName:'锅架',enName:'PAN ORGANIZER',price:'1.00',material:'不锈钢',imageUrl:'',imageLabel:'PAN',imageColor:'#0f766e',basicTax:'2.6%',additionalTax:''},
+{id:'TR007',hs:'3924900000',cnName:'刮铲',enName:'SILICONE SPATULA',price:'1.00',material:'硅胶',imageUrl:'',imageLabel:'KITCHEN',imageColor:'#8b5cf6',basicTax:'3.4%',additionalTax:''},
+{id:'TR008',hs:'6304920000',cnName:'三合板挂饰',enName:'HANGING DECORATION',price:'0.60',material:'杉木+塑料+麻布',imageUrl:'',imageLabel:'DECOR',imageColor:'#ef4444',basicTax:'6.4%',additionalTax:''},
+];
+let taxRateSeq=9;
+let taxRateEditingId='';
+let taxRateImportRows=[];
const genOwnedWarehouseData=[
{id:'OWN001',name:'洛杉矶仓',address:'原型未定义',city:'',state:'',zip:'',country:'美国',status:'启用'},
{id:'OWN002',name:'纽约仓',address:'原型未定义',city:'',state:'',zip:'',country:'美国',status:'启用'},
@@ -979,7 +992,18 @@ ctListData.forEach(function(item){
if(typeof item.isAbnormal!=='boolean')item.isAbnormal=false;
if(!Array.isArray(item.abnormalLogs))item.abnormalLogs=[];
if(typeof item.abnormalReason!=='string')item.abnormalReason='';
+ if(!item.pdaMaterials){
+ item.pdaMaterials=[
+ {key:'licensePlate',type:'车牌照片',status:'待接收',file:'',receivedAt:'',source:''},
+ {key:'containerSeal',type:'集装箱封签',status:'待接收',file:'',receivedAt:'',source:''},
+ {key:'openingPhoto',type:'开柜照片',status:'待接收',file:'',receivedAt:'',source:''}
+ ];
+ }
});
+if(ctListData[0]&&ctListData[0].pdaMaterials){
+ Object.assign(ctListData[0].pdaMaterials[0],{status:'已接收',file:'PDA_车牌照片_FFAU6685194.jpg',receivedAt:'2026-08-13 10:25',source:'PDA'});
+ Object.assign(ctListData[0].pdaMaterials[1],{status:'已接收',file:'PDA_集装箱封签_FFAU6685194.jpg',receivedAt:'2026-08-13 10:26',source:'PDA'});
+}
const ctCostData=[
{id:'COST001',ctNo:'FFAU6685194',type:'港口费',amount:850,currency:'USD',date:'2026-07-16',remark:'洛杉矶港港口操作费'},
{id:'COST002',ctNo:'CSNU9332868',type:'堆存费',amount:320,currency:'USD',date:'2026-07-17',remark:'堆存3天'},
@@ -1091,11 +1115,11 @@ const fbaReturnOutboundData = [
/* FBA退货 - 入库单数据 */
const fbaInboundOrderData = [
-{inboundNo:'FBIO20260720001',bolNo:'BOL260720001',type:'国内订单',wh:'洛杉矶长滩海外仓',owner:'杭州积乐',totalBoxes:120,chargeVol:24.5,palletTotal:4,palletType:'标准托盘',isOutsourced:false,status:'待审核',fees:[{name:'打托费',currency:'USD',amount:120,remark:'入库打托作业'},{name:'拆柜费',currency:'USD',amount:280,remark:'集装箱拆柜'},{name:'提柜费',currency:'USD',amount:350,remark:'码头提柜'}]},
-{inboundNo:'FBIO20260721002',bolNo:'BOL260720002',type:'海外订单',wh:'纽约海外仓',owner:'岩盛、欧业',totalBoxes:200,chargeVol:38.0,palletTotal:6,palletType:'木托盘',isOutsourced:true,status:'已审核',fees:[{name:'打托费',currency:'USD',amount:180,remark:'入库打托作业'},{name:'拆柜费',currency:'USD',amount:320,remark:'集装箱拆柜'},{name:'提柜费',currency:'USD',amount:420,remark:'码头提柜'}]},
-{inboundNo:'FBIO20260722003',bolNo:'BOL260220003',type:'海外订单',wh:'汉堡海外仓',owner:'上海粤讯',totalBoxes:80,chargeVol:15.2,palletTotal:3,palletType:'纸托盘',isOutsourced:false,status:'已入库',fees:[{name:'打托费',currency:'USD',amount:95,remark:'入库打托作业'},{name:'拆柜费',currency:'USD',amount:240,remark:'集装箱拆柜'},{name:'提柜费',currency:'USD',amount:310,remark:'码头提柜'}]},
-{inboundNo:'FBIO20260723004',bolNo:'BOL260240004',type:'国内订单',wh:'洛杉矶长滩海外仓',owner:'义乌卓越',totalBoxes:150,chargeVol:29.8,palletTotal:5,palletType:'标准托盘',isOutsourced:true,status:'待审核',fees:[{name:'打托费',currency:'USD',amount:150,remark:'入库打托作业'},{name:'拆柜费',currency:'USD',amount:300,remark:'集装箱拆柜'},{name:'提柜费',currency:'USD',amount:380,remark:'码头提柜'}]},
-{inboundNo:'FBIO20260725005',bolNo:'BOL260250005',type:'国内订单',wh:'纽约海外仓',owner:'杭州积乐',totalBoxes:90,chargeVol:18.6,palletTotal:3,palletType:'木托盘',isOutsourced:false,status:'已审核',fees:[{name:'打托费',currency:'USD',amount:105,remark:'入库打托作业'},{name:'拆柜费',currency:'USD',amount:260,remark:'集装箱拆柜'},{name:'提柜费',currency:'USD',amount:330,remark:'码头提柜'}]},
+{inboundNo:'FBIO20260720001',bolNo:'BOL260720001',type:'国内订单',wh:'洛杉矶长滩海外仓',owner:'杭州积乐',productName:'蓝牙耳机套件',totalBoxes:120,chargeVol:24.5,palletTotal:4,palletType:'标准托盘',isOutsourced:false,status:'待审核',palletDetails:[{palletNo:'PAL-A1001-01',productName:'蓝牙耳机套件',boxes:32,photoName:'打托照片_PAL-A1001-01.jpg',photo:'https://images.unsplash.com/photo-1586528116311-ad8dd3c8310d?auto=format&fit=crop&w=900&q=80'},{palletNo:'PAL-A1001-02',productName:'蓝牙耳机套件',boxes:30,photoName:'打托照片_PAL-A1001-02.jpg',photo:'https://images.unsplash.com/photo-1586528116311-ad8dd3c8310d?auto=format&fit=crop&w=900&q=80'},{palletNo:'PAL-A1001-03',productName:'蓝牙耳机套件',boxes:30,photo:''},{palletNo:'PAL-A1001-04',productName:'蓝牙耳机套件',boxes:28,photo:''}],fees:[{name:'打托费',currency:'USD',amount:120,remark:'入库打托作业'},{name:'拆柜费',currency:'USD',amount:280,remark:'集装箱拆柜'},{name:'提柜费',currency:'USD',amount:350,remark:'码头提柜'}]},
+{inboundNo:'FBIO20260721002',bolNo:'BOL260720002',type:'海外订单',wh:'纽约海外仓',owner:'岩盛、欧业',productName:'手机保护壳',totalBoxes:200,chargeVol:38.0,palletTotal:6,palletType:'木托盘',isOutsourced:true,status:'已审核',palletDetails:[{palletNo:'PAL-B2002-01',productName:'手机保护壳',boxes:34,photoName:'打托照片_PAL-B2002-01.jpg',photo:'https://images.unsplash.com/photo-1586528116311-ad8dd3c8310d?auto=format&fit=crop&w=900&q=80'},{palletNo:'PAL-B2002-02',productName:'手机保护壳',boxes:34,photo:''},{palletNo:'PAL-B2002-03',productName:'手机保护壳',boxes:34,photo:''},{palletNo:'PAL-B2002-04',productName:'手机保护壳',boxes:34,photo:''},{palletNo:'PAL-B2002-05',productName:'手机保护壳',boxes:32,photo:''},{palletNo:'PAL-B2002-06',productName:'手机保护壳',boxes:32,photo:''}],fees:[{name:'打托费',currency:'USD',amount:180,remark:'入库打托作业'},{name:'拆柜费',currency:'USD',amount:320,remark:'集装箱拆柜'},{name:'提柜费',currency:'USD',amount:420,remark:'码头提柜'}]},
+{inboundNo:'FBIO20260722003',bolNo:'BOL260220003',type:'海外订单',wh:'汉堡海外仓',owner:'上海粤讯',productName:'充电器套装',totalBoxes:80,chargeVol:15.2,palletTotal:3,palletType:'纸托盘',isOutsourced:false,status:'已入库',fees:[{name:'打托费',currency:'USD',amount:95,remark:'入库打托作业'},{name:'拆柜费',currency:'USD',amount:240,remark:'集装箱拆柜'},{name:'提柜费',currency:'USD',amount:310,remark:'码头提柜'}]},
+{inboundNo:'FBIO20260723004',bolNo:'BOL260240004',type:'国内订单',wh:'洛杉矶长滩海外仓',owner:'义乌卓越',productName:'LED台灯',totalBoxes:150,chargeVol:29.8,palletTotal:5,palletType:'标准托盘',isOutsourced:true,status:'待审核',fees:[{name:'打托费',currency:'USD',amount:150,remark:'入库打托作业'},{name:'拆柜费',currency:'USD',amount:300,remark:'集装箱拆柜'},{name:'提柜费',currency:'USD',amount:380,remark:'码头提柜'}]},
+{inboundNo:'FBIO20260725005',bolNo:'BOL260250005',type:'国内订单',wh:'纽约海外仓',owner:'杭州积乐',productName:'收纳盒组合',totalBoxes:90,chargeVol:18.6,palletTotal:3,palletType:'木托盘',isOutsourced:false,status:'已审核',fees:[{name:'打托费',currency:'USD',amount:105,remark:'入库打托作业'},{name:'拆柜费',currency:'USD',amount:260,remark:'集装箱拆柜'},{name:'提柜费',currency:'USD',amount:330,remark:'码头提柜'}]},
];
const fbioQueryMeta=[
{deliveryWh:'宁波仓',warehouseCode:'RK26072001',eta:'2026-07-28',feeAudit:'已审核',containerNo:'MSCU7283910',cabinetNo:'40HQ-001',channel:'洛杉矶普船海卡',sailingDate:'2026-07-22',loaded:'是',fullContainer:'是',measureAudit:'已审核',fbaCode:'ONT8-A1001',createdDate:'2026-07-20'},
@@ -1201,7 +1225,7 @@ const dispatchBolPrintData = [
];
const staticDispatchRecords = [
{dispatchNo:'YWBHK260820001',bolNo:'BOL20260820001',status:'已签收',pickingStatus:'拣货完成',customer:'义乌市赛恩进出口有限公司',contact:'陈女士 13800138101',warehouse:'洛杉矶长滩海外仓',destFba:'FBA ONT8',expressNo:'UPS20260820001',outboundAt:'2026-08-18 09:00:00',deliveredAt:'2026-08-20 15:36',courierNodes:[{time:'2026-08-20 15:36',status:'已签收'}]},
- {dispatchNo:'YWBHK260818002',bolNo:'BOL20260818002',status:'已签收',pickingStatus:'拣货完成',customer:'上海粤讯供应链有限公司',contact:'刘先生 13900139102',warehouse:'纽约海外仓',destFba:'FBA CLT2',expressNo:'FEDEX20260818002',outboundAt:'2026-08-16 13:20:00',signedAt:'2026-08-18 11:08',courierNodes:[{time:'2026-08-18 11:08',status:'已签收'}],customerFollowup:{status:'已回访',followedUpAt:'2026-08-19 10:20',operator:'王客服',result:'满意',feedback:'客户确认货物完好,派送时效符合预期。',note:'',attachments:[{fileName:'客户回访记录_0819.pdf',uploadedAt:'2026-08-19 10:18',size:186320}]}},
+ {dispatchNo:'YWBHK260818002',bolNo:'BOL20260818002',status:'已签收',pickingStatus:'拣货完成',customer:'上海粤讯供应链有限公司',contact:'刘先生 13900139102',warehouse:'纽约海外仓',destFba:'FBA CLT2',expressNo:'FEDEX20260818002',outboundAt:'2026-08-16 13:20:00',signedAt:'2026-08-18 11:08',courierNodes:[{time:'2026-08-18 11:08',status:'已签收'}],customerFollowup:{status:'已回访',followedUpAt:'2026-08-19 10:20',operator:'王客服',result:'已接收',feedback:'客户确认货物完好,派送时效符合预期。',note:'',attachments:[{fileName:'客户回访记录_0819.pdf',uploadedAt:'2026-08-19 10:18',size:186320}]}},
{dispatchNo:'YWBHK260815003',bolNo:'BOL20260815003',status:'已签收',pickingStatus:'拣货完成',customer:'宁波远洋供应链有限公司',contact:'孙女士 13700137103',warehouse:'汉堡海外仓',destFba:'DE Frankfurt',expressNo:'DHL20260815003',outboundAt:'2026-08-14 08:45:00',completedAt:'2026-08-15 17:42',courierNodes:[{time:'2026-08-15 17:42',status:'已签收'}]},
{dispatchNo:'YWBHK200615001',bolNo:'BOL20260615001',status:'待派送',pickingStatus:'已拣货',customer:'义乌欧业进出口有限公司',contact:'张三 13800138000',expressNo:'SF1234567890',outboundAt:'2026-06-15 14:00:00',courierNodes:[],fleetVehicleId:'VD4'},
{dispatchNo:'YWBHK200615002',bolNo:'BOL20260615002',status:'已签收',pickingStatus:'拣货完成',customer:'青岛远航贸易有限公司',contact:'李四 13900139000',expressNo:'UPS20260615002',outboundAt:'2026-06-14 16:30:00',courierNodes:[]},
@@ -1404,6 +1428,7 @@ const menuPermTree = [
{key:'gen-product',label:'产品信息'},
{key:'gen-fee',label:'费用项目'},
{key:'gen-exchange-rate',label:'汇率管理'},
+ {key:'gen-tax-rate',label:'税率查询表'},
{key:'gen-fba',label:'仓库管理'},
{key:'gen-download',label:'下载中心'},
{key:'gen-pallet',label:'托盘管理'},
@@ -1435,6 +1460,7 @@ roleData.forEach(role=>{
role.perms=role.perms.filter(key=>key!=='sys-tenant'&&key!=='sys-brand');
if(role.perms.includes('gen-fba')&&!role.perms.includes('gen-download'))role.perms.push('gen-download');
if(role.perms.includes('gen-fee')&&!role.perms.includes('gen-exchange-rate'))role.perms.push('gen-exchange-rate');
+if(role.perms.includes('gen-exchange-rate')&&!role.perms.includes('gen-tax-rate'))role.perms.push('gen-tax-rate');
if(role.code==='SUPER_ADMIN'&&!role.perms.includes('sys-menu-permissions'))role.perms.push('sys-menu-permissions');
});
@@ -3692,6 +3718,62 @@ document.getElementById('exchange-rate-month-filter').value='';
renderExchangeRates();
}
+function taxRateImageSrc(label,color){
+const svg='';
+return 'data:image/svg+xml;charset=UTF-8,'+encodeURIComponent(svg);
+}
+
+function taxRateEscape(value){return String(value??'').replace(/[&<>"']/g,c=>({'&':'&','<':'<','>':'>','"':'"',"'":'''}[c]));}
+function taxRateUniqueKey(item){return [item.hs,item.cnName,item.enName].map(value=>String(value||'').trim().toLowerCase()).join('|');}
+function taxRateImage(item){const fallback=taxRateImageSrc(item.imageLabel||'IMAGE',item.imageColor||'#64748b');return item.imageUrl?'
':'
';}
+function validateTaxRate(item,ignoreId,existing){
+const required=[['HS',item.hs],['中文品名',item.cnName],['英文品名',item.enName],['材质',item.material],['基础关税',item.basicTax]];
+for(const entry of required)if(!String(entry[1]||'').trim())return entry[0]+'不能为空';
+if(item.price===''||item.price===null||item.price===undefined||!Number.isFinite(Number(item.price))||Number(item.price)<0)return '价格必须为大于等于 0 的数字';
+if(item.imageUrl){try{new URL(item.imageUrl);}catch(error){return '产品图片必须是有效 URL';}}
+const key=taxRateUniqueKey(item);if(existing.some(row=>row.id!==ignoreId&&taxRateUniqueKey(row)===key))return 'HS、中文品名、英文品名组合已存在';
+return '';
+}
+
+function getFilteredTaxRates(){const filters=getTaxRateFilters();return taxRateData.filter(item=>(!filters.hs||item.hs.toLowerCase().includes(filters.hs))&&(!filters.cn||item.cnName.toLowerCase().includes(filters.cn))&&(!filters.en||item.enName.toLowerCase().includes(filters.en)));}
+
+function getTaxRateFilters(){
+return {
+hs:(document.getElementById('tax-rate-hs-filter')||{}).value?.trim().toLowerCase()||'',
+cn:(document.getElementById('tax-rate-cn-filter')||{}).value?.trim().toLowerCase()||'',
+en:(document.getElementById('tax-rate-en-filter')||{}).value?.trim().toLowerCase()||''
+};
+}
+
+function renderTaxRates(){
+const tbody=document.getElementById('tbody-gen-tax-rate');
+if(!tbody)return;
+const rows=getFilteredTaxRates();
+tbody.innerHTML=rows.length?rows.map(item=>'| '+taxRateEscape(item.hs)+' | '+taxRateEscape(item.cnName)+' | '+taxRateEscape(item.enName)+' | '+taxRateEscape(item.price)+' | '+taxRateEscape(item.material)+' | '+taxRateImage(item)+' | '+taxRateEscape(item.basicTax)+' | '+taxRateEscape(item.additionalTax||'-')+' | |
').join(''):'| 暂无匹配的税率记录 |
';
+}
+
+function resetTaxRateFilters(){
+['tax-rate-hs-filter','tax-rate-cn-filter','tax-rate-en-filter'].forEach(id=>{const input=document.getElementById(id);if(input)input.value='';});
+renderTaxRates();
+}
+
+function updateTaxRateImagePreview(){const input=document.getElementById('tax-rate-form-image');const preview=document.getElementById('tax-rate-form-image-preview');if(!preview)return;const url=input&&input.value.trim();preview.src=url||taxRateImageSrc('IMAGE','#64748b');preview.onerror=function(){this.onerror=null;this.src=taxRateImageSrc('IMAGE','#64748b');};}
+function clearTaxRateForm(){['hs','cn','en','price','material','image','basic-tax','additional-tax'].forEach(key=>{const el=document.getElementById('tax-rate-form-'+key);if(el)el.value='';});updateTaxRateImagePreview();}
+function openTaxRateModal(id){taxRateEditingId=id||'';const record=taxRateData.find(item=>item.id===taxRateEditingId);document.getElementById('tax-rate-modal-title').textContent=record?'编辑税率':'新增税率';clearTaxRateForm();if(record){document.getElementById('tax-rate-form-hs').value=record.hs;document.getElementById('tax-rate-form-cn').value=record.cnName;document.getElementById('tax-rate-form-en').value=record.enName;document.getElementById('tax-rate-form-price').value=record.price;document.getElementById('tax-rate-form-material').value=record.material;document.getElementById('tax-rate-form-image').value=record.imageUrl||'';document.getElementById('tax-rate-form-basic-tax').value=record.basicTax;document.getElementById('tax-rate-form-additional-tax').value=record.additionalTax||'';updateTaxRateImagePreview();}showModal('modal-tax-rate-edit');}
+function readTaxRateForm(){return {hs:document.getElementById('tax-rate-form-hs').value.trim(),cnName:document.getElementById('tax-rate-form-cn').value.trim(),enName:document.getElementById('tax-rate-form-en').value.trim(),price:document.getElementById('tax-rate-form-price').value.trim(),material:document.getElementById('tax-rate-form-material').value.trim(),imageUrl:document.getElementById('tax-rate-form-image').value.trim(),basicTax:document.getElementById('tax-rate-form-basic-tax').value.trim(),additionalTax:document.getElementById('tax-rate-form-additional-tax').value.trim()};}
+function saveTaxRate(){const value=readTaxRateForm();const error=validateTaxRate(value,taxRateEditingId,taxRateData);if(error){showToast(error,'warning');return;}const index=taxRateData.findIndex(item=>item.id===taxRateEditingId);const id=taxRateEditingId||'TR'+String(taxRateSeq++).padStart(3,'0');const record=Object.assign({id:id,imageLabel:'IMAGE',imageColor:'#64748b'},value);if(index>-1)taxRateData.splice(index,1,record);else taxRateData.push(record);hideModal('modal-tax-rate-edit');renderTaxRates();showToast(index>-1?'税率记录已更新':'税率记录已新增','success');}
+function deleteTaxRate(id){const index=taxRateData.findIndex(item=>item.id===id);if(index<0)return;const item=taxRateData[index];if(!window.confirm('确定删除 '+item.cnName+' 的税率记录吗?'))return;taxRateData.splice(index,1);renderTaxRates();showToast('税率记录已删除','success');}
+
+const taxRateExcelFields=[{header:'HS',key:'hs',required:true},{header:'中文品名',key:'cnName',required:true},{header:'英文品名',key:'enName',required:true},{header:'价格',key:'price',required:true},{header:'材质',key:'material',required:true},{header:'产品图片',key:'imageUrl',required:false},{header:'基础关税',key:'basicTax',required:true},{header:'附加税',key:'additionalTax',required:false}];
+function taxRateExcelRows(rows){return rows.map(item=>taxRateExcelFields.reduce((row,field)=>{row[field.header]=item[field.key]||'';return row;},{}));}
+function taxRateWorkbookDownload(filename,rows){if(typeof XLSX==='undefined'){showToast('Excel 组件未加载','error');return;}const sheet=XLSX.utils.json_to_sheet(rows);const book=XLSX.utils.book_new();XLSX.utils.book_append_sheet(book,sheet,'税率查询表');XLSX.writeFile(book,filename);}
+function downloadTaxRateTemplate(){taxRateWorkbookDownload('税率查询表导入模板.xlsx',[{hs:'9503000090',cnName:'示例塑料玩具',enName:'TOY',price:'0.85',material:'塑料',imageUrl:'https://example.com/toy.jpg',basicTax:'Free',additionalTax:''}].map(item=>taxRateExcelRows([item])[0]));}
+function exportTaxRates(){const rows=getFilteredTaxRates();if(!rows.length){showToast('当前查询结果为空','warning');return;}const date=new Date();const stamp=date.getFullYear()+String(date.getMonth()+1).padStart(2,'0')+String(date.getDate()).padStart(2,'0');taxRateWorkbookDownload('税率查询表-'+stamp+'.xlsx',taxRateExcelRows(rows));showToast('税率查询结果已导出','success');}
+function openTaxRateImportModal(){taxRateImportRows=[];const file=document.getElementById('tax-rate-import-file');if(file)file.value='';document.getElementById('tax-rate-import-summary').textContent='尚未选择文件';document.getElementById('tax-rate-import-confirm').disabled=true;document.getElementById('tbody-tax-rate-import-preview').innerHTML='| 选择文件后显示前 10 条数据 |
';showModal('modal-tax-rate-import');}
+function renderTaxRateImportPreview(){const summary=document.getElementById('tax-rate-import-summary');const body=document.getElementById('tbody-tax-rate-import-preview');const confirm=document.getElementById('tax-rate-import-confirm');const valid=taxRateImportRows.filter(row=>!row.error).length;summary.innerHTML=taxRateImportRows.length?'共读取 '+taxRateImportRows.length+' 条,可导入 '+valid+' 条,失败 '+(taxRateImportRows.length-valid)+' 条':'尚未选择文件';body.innerHTML=taxRateImportRows.length?taxRateImportRows.slice(0,10).map(row=>'| '+row.rowNumber+' | '+(row.error||'通过')+' | '+taxRateEscape(row.data.hs)+' | '+taxRateEscape(row.data.cnName)+' | '+taxRateEscape(row.data.enName)+' | '+taxRateEscape(row.data.price)+' | '+taxRateEscape(row.data.material)+' | '+taxRateEscape(row.data.imageUrl)+' | '+taxRateEscape(row.data.basicTax)+' | '+taxRateEscape(row.data.additionalTax)+' |
').join(''):'| 选择文件后显示前 10 条数据 |
';confirm.disabled=!taxRateImportRows.length||valid!==taxRateImportRows.length;}
+function handleTaxRateImportFile(input){const file=input&&input.files&&input.files[0];if(!file)return;if(!/\.xlsx$/i.test(file.name)){showToast('仅支持 .xlsx 文件','warning');input.value='';return;}if(typeof XLSX==='undefined'){showToast('Excel 组件未加载','error');return;}const reader=new FileReader();reader.onload=function(event){try{const workbook=XLSX.read(event.target.result,{type:'array'});const sheet=workbook.Sheets[workbook.SheetNames[0]];const matrix=XLSX.utils.sheet_to_json(sheet,{header:1,defval:''});if(!matrix.length)throw new Error('文件没有数据');const headers=matrix[0].map(value=>String(value).trim());if(taxRateExcelFields.some(field=>headers.indexOf(field.header)<0))throw new Error('表头必须包含:'+taxRateExcelFields.map(field=>field.header).join('、'));const rows=[];const keys=new Set();for(let index=1;indexString(value).trim()===''))continue;const data={};taxRateExcelFields.forEach(field=>{const cell=cells[headers.indexOf(field.header)];data[field.key]=cell===undefined?'':String(cell).trim();});let error=validateTaxRate(data,'',taxRateData);const key=taxRateUniqueKey(data);if(!error&&keys.has(key))error='导入文件内存在重复组合';if(!error)keys.add(key);rows.push({rowNumber:index+1,data:data,error:error});}taxRateImportRows=rows;renderTaxRateImportPreview();}catch(error){taxRateImportRows=[];renderTaxRateImportPreview();showToast(error.message||'文件解析失败','error');}};reader.readAsArrayBuffer(file);}
+function confirmTaxRateImport(){if(!taxRateImportRows.length||taxRateImportRows.some(row=>row.error)){showToast('导入文件存在错误,无法整批导入','warning');return;}taxRateImportRows.forEach(row=>taxRateData.push(Object.assign({id:'TR'+String(taxRateSeq++).padStart(3,'0'),imageLabel:'IMAGE',imageColor:'#64748b'},row.data)));const count=taxRateImportRows.length;hideModal('modal-tax-rate-import');renderTaxRates();showToast('导入完成:成功 '+count+' 条','success');}
+
function updateExchangeRateOverwriteHint(){
const month=document.getElementById('exchange-rate-month').value;
const exists=exchangeRateData.some(item=>item.month===month);
@@ -6533,6 +6615,27 @@ function buildCtPalletLabels(containers,manifests,detailMap){
let currentCtPalletLabels=[];
const ctPalletLabelFontSizes={code:120,destination:180};
var ctPalletLabelReturnFocus=null;
+function renderCtPalletLabelBarcodes(){
+ const nodes=Array.from(document.querySelectorAll('.ct-pallet-label-barcode'));
+ nodes.forEach(function(svg){
+ const value=svg.dataset.barcodeValue||'';
+ const fallback=svg.nextElementSibling;
+ if(!value||typeof window.JsBarcode!=='function'){
+ svg.hidden=true;
+ if(fallback)fallback.hidden=false;
+ return;
+ }
+ try{
+ window.JsBarcode(svg,value,{format:'CODE128',displayValue:false,width:3,height:96,margin:0});
+ svg.hidden=false;
+ if(fallback)fallback.hidden=true;
+ }catch(error){
+ svg.hidden=true;
+ if(fallback)fallback.hidden=false;
+ console.error('托盘标条形码生成失败',value,error);
+ }
+ });
+}
function renderCtPalletLabelPreview(){
const modal=document.getElementById('modal-ct-pallet-label-preview');
const list=document.getElementById('ct-pallet-label-list');
@@ -6554,8 +6657,9 @@ function renderCtPalletLabelPreview(){
list.innerHTML=currentCtPalletLabels.map(function(label,index){
const code=escapeMfAttr(label&&label.code);
const destination=escapeMfAttr(label&&label.destWh);
- return `${code}
${destination}
`;
+ return `${code}
${destination}
条形码生成失败
`;
}).join('');
+ renderCtPalletLabelBarcodes();
}
function openCtPalletLabelPreview(){
const checked=Array.from(document.querySelectorAll('.ct-row-cb:checked'));
@@ -6622,7 +6726,7 @@ document.addEventListener('keydown',function(event){
});
function renderCtList(){renderTable('tbody-ct-list',ctListData,['_cb','_act','_emptyWarning','no','manifest','status','isAbnormal','ctNo','clearDoc','releaseDoc','puDoc','fleet','wh','bl','vessel','type','carrier','pol','pod','vol','time','etd','atd','eta','ata','pickupExpectedAt','appointmentAt','emptiedAt','returnedAt'],(d,c,i)=>{
if(c==='_cb')return ``;
-if(c==='_act')return `编辑 清关 ${d.isAbnormal?'取消异常':'标记异常'} 更多 ∨`;
+if(c==='_act')return `编辑 清关 ${d.isAbnormal?'取消异常':'标记异常'} 更多 ∨ 管理资料`;
if(c==='status')return renderContainerStatusTag(d.status);
if(c==='isAbnormal')return renderAbnormalTag(getContainerAbnormalState(d.no));
if(c==='fleet'){
@@ -6670,7 +6774,67 @@ function mfUploadDoc(no,key,el){
};
inp.click();
}
-function showCtMore(i){showToast('更多操作:详情 / 跟踪 / 日志');}
+let currentCtMaterialsIndex=-1;
+function showCtMore(i){
+ const d=ctListData[i];
+ if(!d){showToast('未找到该货柜','warning');return;}
+ currentCtMaterialsIndex=i;
+ const el=document.getElementById('ct-more-container');
+ if(el)el.textContent=d.no||d.ctNo||'—';
+ showModal('modal-ct-more');
+}
+function openCtMaterials(index){
+ const d=ctListData[index];
+ if(!d){showToast('未找到该货柜','warning');return;}
+ currentCtMaterialsIndex=index;
+ const container=d.ctNo||d.no||'—';
+ const title=document.getElementById('ct-materials-title');
+ const noEl=document.getElementById('ct-materials-container');
+ if(title)title.textContent='管理资料 - '+container;
+ if(noEl)noEl.textContent=container;
+ renderCtMaterials(d);
+ showModal('modal-ct-materials');
+}
+function renderCtMaterials(d){
+ const body=document.getElementById('ct-materials-body');
+ if(!body)return;
+ const materials=Array.isArray(d.pdaMaterials)?d.pdaMaterials:[];
+ const received=materials.filter(m=>m.status==='已接收').length;
+ const summary=document.getElementById('ct-materials-summary');
+ if(summary)summary.textContent='已接收 '+received+' / 3 类';
+ body.innerHTML=materials.map(function(m,idx){
+ const ok=m.status==='已接收';
+ const file=m.file?'📎 '+m.file+'':'暂无文件';
+ const view=ok?'查看照片':'';
+ const upload='上传';
+ const action=''+view+upload+'';
+ return '| '+m.type+' | '+(m.status||'待接收')+' | '+file+' | '+(m.receivedAt||'—')+' | '+(m.source||'—')+' | '+action+' |
';
+ }).join('');
+}
+function uploadCtMaterial(index){
+ const d=ctListData[currentCtMaterialsIndex];
+ if(!d||!d.pdaMaterials||!d.pdaMaterials[index])return;
+ const m=d.pdaMaterials[index];
+ const inp=document.createElement('input');
+ inp.type='file';
+ inp.accept='.jpg,.jpeg,.png,.webp';
+ inp.style.display='none';
+ const cleanup=function(){if(inp.parentNode)inp.parentNode.removeChild(inp);};
+ inp.onchange=function(){
+ const file=inp.files&&inp.files[0];
+ if(!file){cleanup();return;}
+ m.status='已接收';
+ m.file=file.name;
+ m.receivedAt=new Date().toISOString().slice(0,16).replace('T',' ');
+ m.source='手动上传';
+ renderCtMaterials(d);
+ showToast(m.type+'上传成功','success');
+ cleanup();
+ };
+ inp.oncancel=cleanup;
+ document.body.appendChild(inp);
+ inp.click();
+}
function ctClearance(no){
var d=ctListData.find(function(x){return x.no===no;});
if(!d){showToast('未找到该货柜','warning');return;}
@@ -9216,13 +9380,54 @@ function renderFbaReceivableFees(bodyId,totalId,fees){
totalNode.textContent='$'+total.toFixed(2);
}
function renderFbaInboundFees(fees){renderFbaReceivableFees('fbd-inbound-fees','fbd-inbound-fee-total',fees);}
+function getFbaInboundPalletDetails(record){
+ const explicit=Array.isArray(record&&record.palletDetails)?record.palletDetails.filter(Boolean):[];
+ if(explicit.length)return explicit;
+ const count=Math.max(0,Math.floor(Number(record&&record.palletTotal)||0));
+ if(!count)return [];
+ const totalBoxes=Math.max(0,Math.floor(Number(record&&record.totalBoxes)||0));
+ const base=Math.floor(totalBoxes/count),remainder=totalBoxes%count;
+ return Array.from({length:count},(_,index)=>({
+ palletNo:(record&&record.inboundNo?record.inboundNo:'PAL')+'-P'+String(index+1).padStart(2,'0'),
+ productName:record&&record.productName||'—',
+ boxes:base+(index{
+ const palletNo=lmoEsc(fbaDetailDisplay(item.palletNo)),productName=lmoEsc(fbaDetailDisplay(item.productName)),boxes=lmoEsc(fbaDetailDisplay(item.boxes)),photo=String(item.photo||'').trim(),photoName=lmoEsc(fbaDetailDisplay(item.photoName||'打托照片_'+String(item.palletNo||'托盘')+'.jpg'));
+ const photoCell=photo?'':'暂无附件';
+ return '| '+palletNo+' | '+productName+' | '+boxes+' | '+photoCell+' |
';
+ }).join(''):'| 暂无托盘明细 |
';
+}
+function openFbaInboundPalletPhoto(photo,palletNo){
+ const image=document.getElementById('fbd-inbound-photo-preview-image'),caption=document.getElementById('fbd-inbound-photo-preview-caption');
+ if(!image||!photo)return;
+ image.src=photo;image.alt=fbaDetailDisplay(palletNo)+' 打托照片';
+ if(caption)caption.textContent=fbaDetailDisplay(palletNo)+' · 打托照片';
+ image.onerror=function(){this.onerror=null;this.alt='打托照片加载失败';showToast('打托照片加载失败,请检查附件地址','error');};
+ showModal('modal-fbd-inbound-photo-preview');
+}
+function closeFbaInboundPalletPhoto(){
+ const image=document.getElementById('fbd-inbound-photo-preview-image'),caption=document.getElementById('fbd-inbound-photo-preview-caption');
+ if(image){image.src='';image.alt='打托照片预览';image.onerror=null;}
+ if(caption)caption.textContent='打托照片';
+ hideModal('modal-fbd-inbound-photo-preview');
+}
function renderFbaOutboundFees(fees){renderFbaReceivableFees('fbd-outbound-fees','fbd-outbound-fee-total',fees);}
function openFbaInboundOrderDetail(no){
const d=fbaInboundOrderData.find(item=>item.inboundNo===no);
if(!d){showToast('未找到入库单记录','error');return;}
- showFbaReadOnlyDetail('fba-inbound-order-detail','fbd-inbound-no','fbd-inbound-status',d.inboundNo,d.status,'fbd-inbound-content',[
+ showFbaReadOnlyDetail('fba-inbound-order-detail','fbd-inbound-no','fbd-inbound-status',d.inboundNo,d.status,'fbd-inbound-top-content',[
{title:'单据信息',rows:[['入库单号',d.inboundNo],['入仓码',d.warehouseCode],['类型',d.type],['货主',d.owner],['关联订单',d.relatedOrderNo]]},
- {title:'仓储信息',rows:[['海外仓',d.wh],['FBA仓库',getFbioFbaWarehouse(d)],['总箱数',d.totalBoxes],['计费体积(m³)',d.chargeVol],['总托盘数',d.palletTotal],['托盘类型',getInboundPalletType(d)],['是否外配',formatInboundOutsourced(d)],['是否加急',formatInboundUrgent(d)]]},
+ {title:'仓储信息',rows:[['海外仓',d.wh],['FBA仓库',getFbioFbaWarehouse(d)],['总箱数',d.totalBoxes],['计费体积(m³)',d.chargeVol],['总托盘数',d.palletTotal],['托盘类型',getInboundPalletType(d)],['是否外配',formatInboundOutsourced(d)],['是否加急',formatInboundUrgent(d)]]}
+ ]);
+ renderFbaInboundPalletDetails(d);
+ renderFbaReadOnlyDetail('fbd-inbound-appointment-content',[
{title:'预约与排车',rows:[['状态',d.status],['预约状态',d.appointmentStatus||'未预约'],['预约送仓时间',d.appointmentDate||'—'],['预计装车时间',d.estimatedLoadingTime||'—'],['排车状态',d.scheduleStatus||'未排车'],['创建时间',d.createdAt],['更新时间',d.updatedAt],['备注',d.remark]]}
]);
renderFbaInboundFees(d.fees);
@@ -10835,6 +11040,7 @@ if(page==='rpt-business')renderRptBusiness();
if(page==='gen-product')renderGenProduct();
if(page==='gen-fee')renderGenFee();
if(page==='gen-exchange-rate')renderExchangeRates();
+if(page==='gen-tax-rate')renderTaxRates();
if(page==='gen-owned-warehouse')renderOwnedWarehouse();
if(page==='gen-fba')renderGenFba();
if(page==='gen-partner-warehouse')renderPartnerWarehouse();
diff --git a/悦/货代SAAS平台后台/prototype-src/manifest.json b/悦/货代SAAS平台后台/prototype-src/manifest.json
index adb1b4c..0d04e80 100644
--- a/悦/货代SAAS平台后台/prototype-src/manifest.json
+++ b/悦/货代SAAS平台后台/prototype-src/manifest.json
@@ -17,6 +17,7 @@
"gen-product",
"gen-fee",
"gen-exchange-rate",
+ "gen-tax-rate",
"outbound-vehicle",
"gen-owned-warehouse",
"gen-fba",
@@ -380,6 +381,7 @@
"gen-product",
"gen-fee",
"gen-exchange-rate",
+ "gen-tax-rate",
"gen-owned-warehouse",
"gen-fba",
"gen-partner-warehouse",
diff --git a/悦/货代SAAS平台后台/prototype-src/modules/03-overseas-warehouse.html b/悦/货代SAAS平台后台/prototype-src/modules/03-overseas-warehouse.html
index b420065..dc009ad 100644
--- a/悦/货代SAAS平台后台/prototype-src/modules/03-overseas-warehouse.html
+++ b/悦/货代SAAS平台后台/prototype-src/modules/03-overseas-warehouse.html
@@ -482,12 +482,28 @@
#page-fba-inbound-order .fbio-list-action-buttons .btn{min-width:76px}
.fbd-inbound-fee-table th,.fbd-inbound-fee-table td{text-align:center!important}
.fbd-receivable-fee-table th,.fbd-receivable-fee-table td{text-align:center!important}
+.fbd-inbound-ops-grid{margin-top:16px;align-items:start}
+#page-fba-inbound-order-detail .fbd-body{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:16px 20px}
+#page-fba-inbound-order-detail #fbd-inbound-top-content{grid-column:1/-1}
+#page-fba-inbound-order-detail .fbd-inbound-pallet-grid{grid-column:1;margin-top:0}
+#page-fba-inbound-order-detail #fbd-inbound-appointment-content{grid-column:2;margin-top:0}
+#page-fba-inbound-order-detail .fbd-inbound-pallet-grid{grid-template-columns:1fr}
+#page-fba-inbound-order-detail #fbd-inbound-appointment-content{grid-template-columns:1fr}
+#page-fba-inbound-order-detail .fbd-section-wide{grid-column:1/-1;margin-top:0}
+.fbd-inbound-pallet-table{min-width:540px;table-layout:fixed}
+.fbd-inbound-pallet-table th,.fbd-inbound-pallet-table td{white-space:normal;overflow-wrap:anywhere;word-break:break-word;vertical-align:middle}
+.fbd-inbound-pallet-table th:nth-child(1),.fbd-inbound-pallet-table td:nth-child(1){width:140px}
+.fbd-inbound-pallet-table th:nth-child(2),.fbd-inbound-pallet-table td:nth-child(2){width:130px}
+.fbd-inbound-pallet-table th:nth-child(3),.fbd-inbound-pallet-table td:nth-child(3){width:62px}
+.fbd-inbound-pallet-table td:nth-child(3){text-align:left!important}
+.fbd-inbound-pallet-table th:nth-child(4),.fbd-inbound-pallet-table td:nth-child(4){width:220px;white-space:nowrap;overflow-wrap:normal;word-break:normal}
+.fbd-photo-link{display:inline-block;max-width:none;padding:0;border:0;background:transparent;color:#1677ff;text-align:left;text-decoration:underline;cursor:pointer;white-space:nowrap;overflow-wrap:normal;word-break:normal}
.fbio-edit-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:16px 20px}
.fbio-edit-grid .form-group{min-width:0;margin:0}
.fbio-edit-grid .form-group input,.fbio-edit-grid .form-group select{width:100%;box-sizing:border-box}
.fbio-edit-grid .lmo-checkbox-option input{width:16px;flex:0 0 16px}
.fbio-readonly-input{background:#f5f7fa!important;color:#64748b!important;cursor:not-allowed}
-@media(max-width:720px){#page-fba-inbound-order .fbio-list-actions{align-items:flex-start;flex-direction:column;padding:10px 14px}#page-fba-inbound-order .fbio-list-action-buttons{width:100%;justify-content:flex-start}.fbio-edit-grid{grid-template-columns:1fr}}
+@media(max-width:720px){#page-fba-inbound-order .fbio-list-actions{align-items:flex-start;flex-direction:column;padding:10px 14px}#page-fba-inbound-order .fbio-list-action-buttons{width:100%;justify-content:flex-start}.fbio-edit-grid{grid-template-columns:1fr}#page-fba-inbound-order-detail .fbd-body{grid-template-columns:1fr}#page-fba-inbound-order-detail .fbd-inbound-pallet-grid,#page-fba-inbound-order-detail #fbd-inbound-appointment-content{grid-column:1}}
首页 > 海外仓 > 入库单
@@ -688,9 +704,11 @@
首页 > 海外仓 > 入库单 > 详情
-
应收费用明细
| 序号 | 费用项目 | 币种 | 金额 | 备注 |
|---|
| 暂无应收费用明细 |
| 应收费用合计(USD) | $0.00 | |
+
托盘明细
| 托盘号 | 产品名称 | 箱数 | 附件名称(打托照片) |
|---|
| 暂无托盘明细 |
应收费用明细
| 序号 | 费用项目 | 币种 | 金额 | 备注 |
|---|
| 暂无应收费用明细 |
| 应收费用合计(USD) | $0.00 | |
+
+
首页 > 海外仓 > 出库单 > 详情
diff --git a/悦/货代SAAS平台后台/prototype-src/modules/10-general.html b/悦/货代SAAS平台后台/prototype-src/modules/10-general.html
index fa2934f..a209786 100644
--- a/悦/货代SAAS平台后台/prototype-src/modules/10-general.html
+++ b/悦/货代SAAS平台后台/prototype-src/modules/10-general.html
@@ -32,6 +32,14 @@ FORM: 已建立后台列表页的精确扩展;本次需求已明确,因此
+
+
diff --git a/悦/货代SAAS平台后台/prototype-src/overlays.html b/悦/货代SAAS平台后台/prototype-src/overlays.html
index dac062e..45bfc18 100644
--- a/悦/货代SAAS平台后台/prototype-src/overlays.html
+++ b/悦/货代SAAS平台后台/prototype-src/overlays.html
@@ -12,7 +12,7 @@
完成时间—
目的地—
-
+
@@ -599,6 +599,43 @@