Files
docs/悦/官网头程下单/workbench.html
T
2026-08-13 09:50:04 +08:00

5098 lines
375 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>虫虫出海 CHONGCHONG GLOBAL | 工作台</title>
<meta name="description" content="虫虫出海工作台 - 海外采购、美国本土卡车、美本土散板一键下单。">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+SC:wght@300;400;500;600;700&family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<script src="https://cdn.tailwindcss.com"></script>
<script>
tailwind.config = {
theme: {
extend: {
colors: {
brand: {
green: '#4CAF50',
greenDark: '#2E7D32',
blue: '#1565C0',
blueDark: '#0D47A1',
teal: '#00838F',
light: '#F0F7FF',
dark: '#0A1628'
}
},
fontFamily: {
sans: ['Inter', 'Noto Sans SC', 'system-ui', 'sans-serif'],
},
boxShadow: {
'card': '0 10px 40px rgba(10, 22, 40, 0.08)',
'card-hover': '0 20px 60px rgba(10, 22, 40, 0.15)',
}
}
}
}
</script>
<style>
* { scroll-behavior: smooth; }
body { font-family: 'Inter', 'Noto Sans SC', system-ui, sans-serif; overflow-x: hidden; }
.btn-primary {
background: linear-gradient(135deg, #1565C0 0%, #0D47A1 100%);
transition: all 0.3s ease;
}
.btn-primary:hover {
transform: translateY(-2px);
box-shadow: 0 10px 30px rgba(21, 101, 192, 0.35);
}
.btn-accent {
background: linear-gradient(135deg, #4CAF50 0%, #2E7D32 100%);
transition: all 0.3s ease;
}
.btn-accent:hover {
transform: translateY(-2px);
box-shadow: 0 10px 30px rgba(76, 175, 80, 0.35);
}
/* 语言切换器 */
.lang-switcher {
display: flex;
align-items: center;
background: rgba(255, 255, 255, 0.15);
border-radius: 9999px;
padding: 3px;
backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, 0.2);
}
.lang-switcher button {
font-size: 12px;
font-weight: 600;
padding: 4px 9px;
border-radius: 9999px;
color: rgba(255, 255, 255, 0.9);
transition: all 0.25s ease;
white-space: nowrap;
}
.lang-switcher button:hover { color: #fff; }
.lang-switcher button.active { background: #fff; color: #0D47A1; }
/* ===== 下单工作台 Dashboard ===== */
.dash-view { animation: fadeIn 0.4s ease; }
.dash-card {
background: #fff;
border: 1px solid #eef2f7;
border-radius: 1.25rem;
box-shadow: 0 10px 40px rgba(10, 22, 40, 0.06);
transition: all 0.35s cubic-bezier(0.4, 0, 0.2, 1);
cursor: pointer;
}
.dash-card:hover {
transform: translateY(-8px);
box-shadow: 0 24px 60px rgba(10, 22, 40, 0.14);
border-color: rgba(21, 101, 192, 0.35);
}
.dash-form-input {
width: 100%;
padding: 0.75rem 1rem;
border: 1px solid #e2e8f0;
border-radius: 0.75rem;
outline: none;
font-size: 0.95rem;
color: #1f2937;
background: #fff;
transition: all 0.2s ease;
}
.dash-form-input:focus {
border-color: #1565C0;
box-shadow: 0 0 0 3px rgba(21, 101, 192, 0.12);
}
.dash-form-input::placeholder { color: #9ca3af; }
.dash-label {
display: block;
font-size: 0.875rem;
font-weight: 600;
color: #374151;
margin-bottom: 0.5rem;
}
.dash-label .req { color: #ef4444; margin-left: 2px; }
.seg-input { position: absolute; opacity: 0; width: 0; height: 0; }
.seg-pill {
display: inline-flex;
align-items: center;
justify-content: center;
gap: 6px;
padding: 0.65rem 1.1rem;
border: 1px solid #e2e8f0;
border-radius: 0.75rem;
cursor: pointer;
font-size: 0.9rem;
color: #475569;
background: #fff;
transition: all 0.2s ease;
user-select: none;
}
.seg-pill:hover { border-color: #cbd5e1; }
.seg-input:checked + .seg-pill {
border-color: #1565C0;
background: #EAF2FD;
color: #0D47A1;
font-weight: 600;
box-shadow: 0 0 0 1px #1565C0 inset;
}
.dash-topbar {
background: rgba(255, 255, 255, 0.92);
backdrop-filter: blur(12px);
border-bottom: 1px solid #eef2f7;
}
.dash-sidebar {
width: 250px;
flex-shrink: 0;
background: linear-gradient(180deg, #0B1F3A 0%, #0C2A52 100%);
color: #fff;
display: flex;
flex-direction: column;
position: sticky;
top: 0;
height: 100vh;
padding: 1.25rem 0.875rem;
}
.dash-sidebar-brand {
display: flex;
align-items: center;
gap: 0.6rem;
padding: 0.4rem 0.55rem 1.1rem;
border-bottom: 1px solid rgba(255, 255, 255, 0.08);
margin-bottom: 0.6rem;
}
.dash-sidebar-brand .brand-name { font-weight: 700; font-size: 1rem; line-height: 1.15; }
.dash-sidebar-brand .brand-sub { font-size: 0.62rem; letter-spacing: 0.12em; color: rgba(255, 255, 255, 0.45); }
.dash-nav { flex: 1; display: flex; flex-direction: column; gap: 0.25rem; overflow-y: auto; }
.dash-nav-group {
font-size: 0.68rem; text-transform: uppercase; letter-spacing: 0.1em;
color: rgba(255, 255, 255, 0.4); padding: 0.85rem 0.75rem 0.35rem;
}
.dash-nav-link {
display: flex; align-items: center; gap: 0.75rem;
padding: 0.72rem 0.85rem; border-radius: 0.75rem;
color: rgba(255, 255, 255, 0.72); font-size: 0.92rem; font-weight: 500;
cursor: pointer; transition: all 0.2s ease; white-space: nowrap;
}
.dash-nav-link i { width: 1.2rem; text-align: center; font-size: 0.95rem; }
.dash-nav-link:hover { background: rgba(255, 255, 255, 0.07); color: #fff; }
.dash-nav-link.active {
background: linear-gradient(90deg, #1565C0, #1E88E5); color: #fff;
box-shadow: 0 6px 18px rgba(21, 101, 192, 0.4);
}
.dash-sidebar-bottom {
border-top: 1px solid rgba(255, 255, 255, 0.08); padding-top: 0.9rem;
display: flex; flex-direction: column; gap: 0.7rem; align-items: stretch;
}
.dash-sidebar-bottom #langSwitcherDash { align-self: center; }
.dash-logout-btn {
display: flex; align-items: center; justify-content: center; gap: 0.5rem;
padding: 0.6rem; border-radius: 0.7rem; font-size: 0.88rem; font-weight: 600;
background: rgba(239, 68, 68, 0.12); color: #fca5a5; cursor: pointer;
transition: all 0.2s ease;
}
.dash-logout-btn:hover { background: rgba(239, 68, 68, 0.22); color: #fff; }
.dash-main { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.dash-menu-btn {
display: none; width: 2.25rem; height: 2.25rem; border-radius: 0.6rem;
align-items: center; justify-content: center; color: #374151;
background: #f1f5f9; cursor: pointer;
}
.dash-overlay { display: none; position: fixed; inset: 0; background: rgba(0, 0, 0, 0.45); z-index: 45; }
.dash-overlay.show { display: block; }
.dash-right {
width: 320px; flex-shrink: 0;
background: #fff; border-left: 1px solid #eef2f7;
padding: 1.25rem 1rem;
position: sticky; top: 3.5rem; align-self: flex-start;
max-height: calc(100vh - 3.5rem); overflow-y: auto;
}
.dash-right.dash-right-hidden { display: none !important; }
.dash-topup-btn {
display: inline-flex; align-items: center; gap: 0.45rem;
padding: 0.45rem 0.9rem; border-radius: 0.7rem;
font-size: 0.85rem; font-weight: 600; cursor: pointer;
color: #fff; background: linear-gradient(135deg, #1565C0, #00BFA5);
border: none; box-shadow: 0 4px 14px rgba(21,101,192,0.3);
transition: all 0.2s ease;
}
.dash-topup-btn:hover { transform: translateY(-1px); box-shadow: 0 6px 18px rgba(21,101,192,0.4); }
.dash-topup-btn i { font-size: 0.95rem; }
.topup-overlay {
position: fixed; inset: 0; background: rgba(15,23,42,0.55);
display: flex; align-items: center; justify-content: center; z-index: 100; padding: 1rem;
}
.topup-overlay.hidden { display: none; }
.topup-modal {
width: 380px; max-width: 100%; background: #fff; border-radius: 1.25rem;
box-shadow: 0 24px 60px rgba(0,0,0,0.25); overflow: hidden; animation: topupIn .25s ease;
}
@keyframes topupIn { from { opacity: 0; transform: translateY(12px) scale(.98); } to { opacity: 1; transform: none; } }
.topup-head { display: flex; align-items: center; justify-content: space-between; padding: 1.1rem 1.25rem; border-bottom: 1px solid #eef2f7; }
.topup-head h3 { font-size: 1.05rem; font-weight: 700; color: #0f172a; }
.topup-close { background: none; border: none; font-size: 1.4rem; line-height: 1; color: #94a3b8; cursor: pointer; }
.topup-close:hover { color: #475569; }
.topup-body { padding: 1.25rem; }
.topup-amount-label { font-size: 0.85rem; color: #475569; margin-bottom: 0.5rem; }
.topup-amount-input {
display: flex; align-items: center; gap: 0.5rem;
border: 1.5px solid rgba(21,101,192,0.25); border-radius: 0.8rem;
padding: 0 0.9rem; height: 3rem; margin-bottom: 1.1rem; transition: border-color .2s, box-shadow .2s;
}
.topup-amount-input:focus-within { border-color: #1565C0; box-shadow: 0 0 0 4px rgba(21,101,192,0.1); }
.topup-amount-input .cur { font-size: 1.1rem; font-weight: 700; color: #0f172a; }
.topup-amount-input input { flex: 1; min-width: 0; border: none; outline: none; font-size: 1.05rem; font-weight: 600; color: #0f172a; background: transparent; }
.topup-presets { display: flex; gap: 0.5rem; margin-bottom: 1.2rem; }
.topup-preset { flex: 1; padding: 0.5rem; border-radius: 0.6rem; border: 1px solid #e2e8f0; background: #f8fafc; font-size: 0.85rem; color: #475569; cursor: pointer; transition: all .2s; }
.topup-preset:hover { border-color: #1565C0; color: #1565C0; }
.topup-preset.active { background: linear-gradient(135deg, rgba(21,101,192,0.1), rgba(0,191,165,0.1)); border-color: #1565C0; color: #1565C0; font-weight: 600; }
.topup-methods { display: flex; gap: 0.75rem; margin-bottom: 1.1rem; }
.topup-method {
flex: 1; display: flex; align-items: center; justify-content: center; gap: 0.5rem;
padding: 0.7rem; border-radius: 0.8rem; border: 1.5px solid #e2e8f0; background: #fff;
font-size: 0.9rem; font-weight: 600; color: #475569; cursor: pointer; transition: all .2s;
}
.topup-method i { font-size: 1.2rem; }
.topup-method[data-method="wechat"] i { color: #09bb07; }
.topup-method[data-method="alipay"] i { color: #1677ff; }
.topup-method.active { border-color: #1565C0; background: linear-gradient(135deg, rgba(21,101,192,0.06), rgba(0,191,165,0.06)); color: #0f172a; }
.topup-qr {
display: flex; flex-direction: column; align-items: center; gap: 0.7rem;
padding: 1.2rem; background: #f8fafc; border-radius: 0.9rem; border: 1px dashed #cbd5e1;
}
.topup-qr-box { width: 150px; height: 150px; border-radius: 0.8rem; background: #fff; display: flex; align-items: center; justify-content: center; border: 1px solid #e2e8f0; }
.topup-qr-box .fa-weixin { color: #09bb07; }
.topup-qr-box .fa-alipay { color: #1677ff; }
.topup-qr-tip { font-size: 0.82rem; color: #64748b; text-align: center; }
.topup-foot { display: flex; gap: 0.75rem; padding: 0 1.25rem 1.25rem; }
.topup-foot button { flex: 1; padding: 0.7rem; border-radius: 0.8rem; font-size: 0.9rem; font-weight: 600; cursor: pointer; border: none; transition: all .2s; }
.topup-cancel { background: #f1f5f9; color: #475569; }
.topup-cancel:hover { background: #e2e8f0; }
.topup-confirm { background: linear-gradient(135deg, #1565C0, #00BFA5); color: #fff; box-shadow: 0 4px 14px rgba(21,101,192,0.3); }
.topup-confirm:hover { transform: translateY(-1px); box-shadow: 0 6px 18px rgba(21,101,192,0.4); }
.dash-right-card {
background: #f8fafc; border: 1px solid #eef2f7;
border-radius: 0.85rem; padding: 1rem; margin-bottom: 0.85rem;
}
.dash-right-card h4 {
font-size: 0.72rem; font-weight: 700; letter-spacing: 0.06em;
text-transform: uppercase; color: #94a3b8; margin-bottom: 0.9rem;
}
.dash-account { display: flex; align-items: center; gap: 0.75rem; }
.dash-account-avatar {
width: 2.75rem; height: 2.75rem; border-radius: 0.8rem;
background: linear-gradient(135deg, #1565C0, #00BFA5); color: #fff;
display: flex; align-items: center; justify-content: center;
font-weight: 700; font-size: 1.1rem; flex-shrink: 0;
}
.dash-account-name { font-weight: 700; color: #0f172a; font-size: 0.95rem; line-height: 1.2; }
.dash-account-type { font-size: 0.75rem; color: #64748b; margin-top: 0.15rem; }
.dash-stat-row { display: flex; justify-content: space-between; align-items: center; padding: 0.6rem 0; border-bottom: 1px dashed #e2e8f0; }
.dash-stat-row:last-child { border-bottom: none; }
.dash-stat-label { font-size: 0.85rem; color: #475569; }
.dash-stat-value { font-weight: 700; color: #0f172a; font-size: 0.95rem; }
.dash-help-item {
display: flex; align-items: center; gap: 0.6rem;
padding: 0.6rem 0.55rem; border-radius: 0.6rem; cursor: pointer;
color: #334155; font-size: 0.9rem; transition: background 0.2s, color 0.2s;
}
.dash-help-item:hover { background: #eef2f7; color: #1565C0; }
.dash-help-item i { color: #00BFA5; width: 1.15rem; text-align: center; }
.dash-tip {
background: linear-gradient(135deg, rgba(0,191,165,0.08), rgba(21,101,192,0.08));
border: 1px solid rgba(0,191,165,0.22); border-radius: 1rem;
padding: 0.9rem; font-size: 0.82rem; color: #475569; line-height: 1.65;
}
.dash-tip i { color: #00BFA5; margin-right: 0.4rem; }
.dash-empty { padding: 1rem; color: #94a3b8; }
.dash-empty i { font-size: 3rem; color: #cbd5e1; margin-bottom: 1rem; display: block; }
@keyframes fadeIn {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}
@media (max-width: 768px) {
.dash-sidebar {
position: fixed; left: 0; top: 0; z-index: 50;
transform: translateX(-100%); transition: transform 0.3s ease;
}
.dash-sidebar.open { transform: translateX(0); }
.dash-menu-btn { display: inline-flex; }
}
/* ===== 折叠分组菜单(来自柏悦客户端,统一为 workbench 样式)===== */
.dash-nav-divider { height: 1px; background: rgba(255, 255, 255, 0.08); margin: 0.5rem 0.75rem; }
.dash-menu-group { display: flex; flex-direction: column; }
.dash-menu-group-header {
display: flex; align-items: center; gap: 0.7rem;
padding: 0.62rem 0.85rem; border-radius: 0.7rem;
color: rgba(255, 255, 255, 0.6); font-size: 0.86rem; font-weight: 600;
cursor: pointer; transition: all 0.2s ease; user-select: none; white-space: nowrap;
}
.dash-menu-group-header:hover { background: rgba(255, 255, 255, 0.05); color: #fff; }
.dash-menu-group-header .g-icon { width: 1.2rem; text-align: center; font-size: 0.92rem; }
.dash-menu-group-header .g-title { flex: 1; }
.dash-menu-group-header .g-arrow { font-size: 0.62rem; transition: transform 0.3s ease; }
.dash-menu-group-header.collapsed .g-arrow { transform: rotate(-90deg); }
.dash-menu-sub {
display: flex; flex-direction: column; gap: 0.12rem; overflow: hidden;
max-height: 600px; opacity: 1; margin-top: 0.12rem;
transition: max-height 0.3s ease, opacity 0.25s ease, margin-top 0.2s ease;
}
.dash-menu-sub.collapsed { max-height: 0; opacity: 0; margin-top: 0; }
.dash-nav-link.sub { padding-left: 2.55rem; font-size: 0.88rem; font-weight: 500; }
.dash-nav-link.sub i { font-size: 0.8rem; opacity: 0.65; }
.dash-business-subgroup { padding: 0.35rem 0 0.3rem; border-bottom: 1px solid rgba(148, 163, 184, 0.14); }
.dash-business-subgroup:last-child { border-bottom: 0; }
.dash-business-label { display: flex; align-items: center; gap: 0.55rem; padding: 0.42rem 1rem; color: rgba(255,255,255,0.55); font-size: 0.76rem; font-weight: 600; }
.dash-business-label i { width: 1rem; text-align: center; }
.dash-business-subgroup .dash-nav-link.sub { padding-left: 2.85rem; font-size: 0.82rem; }
.sea-business-page { display: flex; flex-direction: column; gap: 0.9rem; }
.sea-business-page.hidden, .sea-business-form-panel[hidden] { display: none; }
.sea-page-header { display: flex; align-items: center; justify-content: space-between; gap: 1rem; }
.sea-page-header h1 { margin: 0; color: #0f172a; font-size: 1.35rem; font-weight: 700; }
.sea-page-header p { margin: 0.3rem 0 0; color: #64748b; font-size: 0.85rem; }
.sea-order-filters { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 0.8rem; padding: 1rem; background: #fff; border-radius: 0.75rem; box-shadow: 0 4px 14px rgba(15,23,42,0.06); }
.sea-order-filters input, .sea-order-filters select { width: 100%; height: 2.4rem; padding: 0 0.75rem; border: 1px solid #dbe3ec; border-radius: 0.5rem; background: #fff; color: #334155; font-size: 0.84rem; }
.sea-filter-actions { display: flex; align-items: center; gap: 0.6rem; grid-column: 1 / -1; justify-content: flex-end; }
.sea-order-table-wrap { overflow-x: auto; background: #fff; border-radius: 0.75rem; box-shadow: 0 4px 14px rgba(15,23,42,0.06); }
.sea-order-table { width: 100%; min-width: 760px; border-collapse: collapse; font-size: 0.82rem; }
.sea-order-table th, .sea-order-table td { padding: 0.8rem 0.9rem; text-align: left; border-bottom: 1px solid #edf1f5; white-space: nowrap; }
.sea-order-table th { color: #475569; background: #f8fafc; font-weight: 600; }
.sea-business-page .btn-primary, .sea-business-form-panel .btn-primary, .sea-business-detail-page .btn-primary { background: linear-gradient(135deg, #667eea, #764ba2); box-shadow: 0 4px 15px rgba(102,126,234,0.35); }
.sea-business-page .btn-primary:hover, .sea-business-form-panel .btn-primary:hover, .sea-business-detail-page .btn-primary:hover { background: linear-gradient(135deg, #5a6fd8, #6b4295); box-shadow: 0 6px 20px rgba(102,126,234,0.45); }
.sea-business-page .sea-order-table th { background: linear-gradient(135deg, rgba(102,126,234,0.08), rgba(118,75,162,0.08)); color: #667eea; border-bottom-color: rgba(102,126,234,0.15); }
.sea-business-page .sea-table-action { color: #667eea; }
.sea-business-page .sea-table-action:hover { color: #764ba2; }
.sea-order-empty { padding: 2.2rem 1rem !important; color: #94a3b8; text-align: center !important; }
.sea-table-actions { display: flex; align-items: center; gap: 0.75rem; }
.sea-table-action { color: #1565c0; font-weight: 600; }
.sea-table-action:hover { color: #0d47a1; text-decoration: underline; }
.sea-business-detail-page { display: flex; flex-direction: column; gap: 1rem; }
.sea-business-detail-page[hidden] { display: none; }
.sea-detail-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1rem; }
.sea-detail-section { background: #fff; border: 1px solid #e2e8f0; border-radius: 0.75rem; padding: 1.15rem; }
.sea-detail-section h3 { margin: 0 0 1rem; color: #0f172a; font-size: 1rem; font-weight: 700; }
.sea-detail-section dl { display: grid; grid-template-columns: 7rem minmax(0, 1fr); row-gap: 0.75rem; margin: 0; font-size: 0.85rem; }
.sea-detail-section dt { color: #64748b; }
.sea-detail-section dd { min-width: 0; margin: 0; color: #1e293b; font-weight: 500; overflow-wrap: anywhere; }
.procurement-detail-header { display: flex; align-items: center; justify-content: space-between; gap: 1rem; }
.procurement-detail-heading h1 { margin: 0; color: #1f2937; font-size: 1.25rem; font-weight: 700; }
.procurement-detail-heading p { margin: 0.35rem 0 0; color: #64748b; font-size: 0.82rem; }
.procurement-detail-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1rem; }
.procurement-detail-card { overflow: hidden; border: 1px solid #e2e8f0; border-radius: 0.5rem; background: #fff; }
.procurement-detail-card.is-product { grid-column: 1 / -1; }
.procurement-detail-card h3 { margin: 0; padding: 0.8rem 1rem; border-bottom: 1px solid #e2e8f0; background: #f8fafc; color: #1f2937; font-size: 0.9rem; font-weight: 700; }
.procurement-detail-card dl { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); margin: 0; padding: 0.25rem 1rem 0.75rem; column-gap: 1.75rem; }
.procurement-detail-card .detail-field { display: grid; grid-template-columns: 6.5rem minmax(0, 1fr); align-items: center; min-height: 2.65rem; border-bottom: 1px dashed #e2e8f0; font-size: 0.82rem; }
.procurement-detail-card .detail-field:last-child, .procurement-detail-card .detail-field:nth-last-child(2):nth-child(odd) { border-bottom-color: transparent; }
.procurement-detail-card dt { color: #64748b; }
.procurement-detail-card dd { min-width: 0; margin: 0; color: #1f2937; font-weight: 500; overflow-wrap: anywhere; }
.sea-progress-track { display: flex; align-items: flex-start; }
.sea-progress-step { position: relative; display: flex; flex: 1; flex-direction: column; align-items: center; gap: 0.45rem; color: #94a3b8; font-size: 0.78rem; text-align: center; }
.sea-progress-step:not(:last-child)::after { content: ''; position: absolute; top: 0.78rem; left: 58%; width: 84%; height: 2px; background: #e2e8f0; }
.sea-progress-step span { position: relative; z-index: 1; display: grid; width: 1.6rem; height: 1.6rem; place-items: center; border-radius: 50%; background: #e2e8f0; color: #64748b; font-weight: 700; }
.sea-progress-step.is-current { color: #1565c0; }
.sea-progress-step.is-current span { background: #1565c0; color: #fff; }
.sea-progress-step.is-done { color: #0f766e; }
.sea-progress-step.is-done span { background: #ccfbf1; color: #0f766e; }
.sea-edit-overlay { position: fixed; inset: 0; z-index: 1200; display: grid; place-items: center; padding: 1rem; background: rgba(15, 23, 42, 0.55); }
.sea-edit-overlay[hidden] { display: none; }
.sea-edit-dialog { display: flex; width: min(820px, 100%); max-height: min(88vh, 820px); flex-direction: column; overflow: hidden; border-radius: 0.75rem; background: #fff; box-shadow: 0 24px 60px rgba(15, 23, 42, 0.24); }
.sea-edit-header, .sea-edit-footer { display: flex; align-items: center; justify-content: space-between; gap: 1rem; padding: 1rem 1.25rem; border-bottom: 1px solid #e2e8f0; }
.sea-edit-header h2 { margin: 0; color: #0f172a; font-size: 1.1rem; font-weight: 700; }
.sea-edit-close { display: grid; width: 2.25rem; height: 2.25rem; place-items: center; border-radius: 0.5rem; color: #64748b; }
.sea-edit-close:hover { background: #f1f5f9; color: #0f172a; }
.sea-edit-body { overflow-y: auto; padding: 1.25rem; }
.sea-edit-footer { justify-content: flex-end; border-top: 1px solid #e2e8f0; border-bottom: 0; }
@media (max-width: 780px) { .sea-page-header, .procurement-detail-header { align-items: flex-start; flex-direction: column; } .sea-order-filters { grid-template-columns: 1fr; } .sea-filter-actions { grid-column: 1; justify-content: flex-start; } .sea-detail-grid, .procurement-detail-grid { grid-template-columns: 1fr; } .sea-detail-section dl { grid-template-columns: 6rem minmax(0, 1fr); } .procurement-detail-card.is-product { grid-column: auto; } .procurement-detail-card dl { grid-template-columns: 1fr; } .procurement-detail-card .detail-field { grid-template-columns: 6.5rem minmax(0, 1fr); } .sea-edit-dialog { max-height: 94vh; } }
.dash-nav-link.logout { color: #fca5a5; background: rgba(239, 68, 68, 0.10); margin-top: 0.2rem; }
.dash-nav-link.logout:hover { background: rgba(239, 68, 68, 0.22); color: #fff; }
/* ===== 柏悦客户端组件样式(已统一作用域到 .client-shell)===== */
.client-shell * {
box-sizing: border-box; margin: 0; padding: 0; }
.client-shell html, .client-shell body {
overflow-x: hidden; max-width: 100vw; }
.client-shell body {
font-family: -apple-system, BlinkMacSystemFont, 'PingFang SC', 'Helvetica Neue', sans-serif; background: #f5f7fa; color: #262626; display: flex; min-height: 100vh; }
.client-shell /* ===== SIDEBAR ===== */
.sidebar {
width: 240px; background: rgba(255,255,255,0.95); backdrop-filter: blur(20px); border-right: 1px solid rgba(255,255,255,0.3);
display: flex; flex-direction: column;
position: fixed; left: 0; top: 64px; bottom: 0;
z-index: 100; box-shadow: 2px 0 20px rgba(0,0,0,.08);
transition: all .3s cubic-bezier(.4,0,.2,1);
}
.client-shell .sidebar.collapsed {
width: 0; transform: translateX(-100%); border-right: none; overflow: hidden; }
.client-shell .nav {
flex: 1; overflow-y: auto; padding: 16px 12px; }
.client-shell .nav-item {
display: flex; align-items: center; gap: 10px;
padding: 12px 16px; font-size: 13px; color: #595959;
cursor: pointer; transition: all .3s cubic-bezier(.4,0,.2,1);
position: relative; text-decoration: none; border-radius: 10px;
}
.client-shell .nav-item:hover {
background: linear-gradient(135deg, rgba(102,126,234,0.08), rgba(118,75,162,0.08)); color: #667eea; transform: translateX(3px); }
.client-shell .nav-item.active {
background: linear-gradient(135deg, #667eea, #764ba2); color: #fff; font-weight: 500; box-shadow: 0 4px 15px rgba(102,126,234,0.3); }
.client-shell .nav-item.active::before {
content: ''; position: absolute; left: -8px; top: 50%; transform: translateY(-50%);
width: 4px; height: 24px; background: linear-gradient(135deg, #667eea, #f093fb); border-radius: 0 4px 4px 0;
}
.client-shell .nav-item .nav-icon, .client-shell .nav-group-left .nav-icon {
width: 18px; height: 18px; display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
.client-shell .nav-item .nav-icon svg, .client-shell .nav-group-left .nav-icon svg {
width: 16px; height: 16px; }
.client-shell .nav-divider {
height: 1px; background: linear-gradient(90deg, transparent, rgba(102,126,234,0.2), transparent); margin: 12px 8px; }
.client-shell .nav-group {
display: flex; flex-direction: column; }
.client-shell .nav-group-header {
display: flex; align-items: center; justify-content: space-between;
padding: 12px 16px; font-size: 13px; color: #595959;
cursor: pointer; transition: all .3s cubic-bezier(.4,0,.2,1); user-select: none;
border-radius: 10px;
}
.client-shell .nav-group-header:hover {
background: linear-gradient(135deg, rgba(102,126,234,0.08), rgba(118,75,162,0.08)); color: #667eea; }
.client-shell .nav-group-header .nav-group-left {
display: flex; align-items: center; gap: 10px; }
.client-shell .nav-group-header .nav-arrow {
font-size: 10px; color: #8c8c8c; transition: transform .3s; }
.client-shell .nav-group-header.expanded .nav-arrow {
transform: rotate(180deg); }
.client-shell .nav-group-header.active {
color: #667eea; font-weight: 600; }
.client-shell .nav-sub {
display: none; flex-direction: column; }
.client-shell .nav-sub.expanded {
display: flex; }
.client-shell .nav-sub-item {
display: flex; align-items: center; gap: 8px;
padding: 10px 16px 10px 40px; font-size: 13px; color: #8c8c8c;
cursor: pointer; text-decoration: none; transition: all .3s cubic-bezier(.4,0,.2,1);
border-radius: 8px;
}
.client-shell .nav-sub-item:hover {
color: #667eea; background: linear-gradient(135deg, rgba(102,126,234,0.05), rgba(118,75,162,0.05)); }
.client-shell .nav-sub-item.active {
color: #fff; font-weight: 600; background: linear-gradient(135deg, #667eea, #764ba2); }
.client-shell /* ===== TOPBAR ===== */
.topbar {
position: fixed; top: 0; left: 0; right: 0; height: 64px;
background: linear-gradient(135deg, rgba(102,126,234,0.95), rgba(118,75,162,0.95), rgba(240,147,251,0.95));
backdrop-filter: blur(20px); display: flex; align-items: center;
justify-content: space-between; padding: 0 28px; z-index: 99;
box-shadow: 0 4px 30px rgba(102,126,234,.35);
border-bottom: 1px solid rgba(255,255,255,.2);
}
.client-shell .topbar-left {
display: flex; align-items: center; gap: 18px; }
.client-shell .topbar-menu-icon {
width: 24px; height: 20px; display: flex; flex-direction: column;
justify-content: space-between; cursor: pointer; padding: 4px 0;
}
.client-shell .topbar-menu-icon span {
display: block; height: 2px; background: #fff; border-radius: 3px; transition: all .3s; }
.client-shell .topbar-menu-icon:hover span:first-child {
width: 14px; transform: translateX(2px); }
.client-shell .topbar-menu-icon:hover span:last-child {
width: 14px; transform: translateX(-2px); }
.client-shell .topbar-logo-small {
width: 36px; height: 36px; object-fit: contain; display: block; border-radius: 10px; background: rgba(255,255,255,0.9); box-shadow: 0 2px 10px rgba(0,0,0,0.1); }
.client-shell .topbar-brand-text {
font-size: 22px; font-weight: 700; color: #fff; letter-spacing: 2px; text-shadow: 0 2px 8px rgba(0,0,0,0.1); }
.client-shell .topbar-right {
display: flex; align-items: center; gap: 18px; }
.client-shell .topbar-icon-btn {
width: 38px; height: 38px; display: flex; align-items: center; justify-content: center;
border-radius: 50%; cursor: pointer; color: #fff; font-size: 16px; transition: all .3s;
background: rgba(255,255,255,0.1);
}
.client-shell .topbar-icon-btn:hover {
background: rgba(255,255,255,0.25); transform: scale(1.1); }
.client-shell .topbar-avatar {
width: 34px; height: 34px; border-radius: 50%; background: linear-gradient(135deg, rgba(255,255,255,0.3), rgba(255,255,255,0.15));
display: flex; align-items: center; justify-content: center;
font-size: 14px; font-weight: 700; color: #fff; cursor: pointer; border: 2px solid rgba(255,255,255,0.4);
transition: all .3s;
}
.client-shell .topbar-avatar:hover {
transform: scale(1.1); box-shadow: 0 4px 15px rgba(255,255,255,0.3); }
.client-shell .topbar-logout {
font-size: 13px; color: rgba(255,255,255,.9); cursor: pointer; transition: all .3s; padding: 6px 14px; border-radius: 8px; }
.client-shell .topbar-logout:hover {
color: #fff; background: rgba(255,255,255,0.15); }
.client-shell /* ===== MAIN CONTENT ===== */
.main {
margin-left: 240px; margin-top: 64px; flex: 1;
padding: 28px; min-height: calc(100vh - 64px);
transition: all .3s cubic-bezier(.4,0,.2,1);
max-width: calc(100vw - 0px); overflow-x: hidden;
}
.client-shell .main.expanded {
margin-left: 0; }
.client-shell /* Page content panels */
.page-content {
display: none; }
.client-shell .page-content.active {
display: block; }
.client-shell /* ===== SHARED: Page Header / Breadcrumb ===== */
.page-header {
display: flex; align-items: flex-start; justify-content: space-between; margin-bottom: 18px; }
.client-shell .page-title {
font-size: 20px; font-weight: 700; color: #1e293b; }
.client-shell .page-subtitle {
font-size: 13px; color: #71717a; margin-top: 6px; }
.client-shell .breadcrumb {
display: flex; align-items: center; gap: 8px; font-size: 13px; color: #71717a; margin-bottom: 18px; }
.client-shell .breadcrumb a {
color: #71717a; text-decoration: none; transition: all .2s; }
.client-shell .breadcrumb a:hover {
color: #667eea; }
.client-shell .link-primary {
color: #667eea; text-decoration: none; font-size: 13px; transition: all .2s; }
.client-shell .link-primary:hover {
text-decoration: underline; color: #764ba2; }
.client-shell /* Company info tabs */
.info-tabs {
display: flex; gap: 0; border: 1.5px solid rgba(102,126,234,0.2); border-radius: 14px; overflow: hidden; width: fit-content; margin-bottom: 20px; background: rgba(255,255,255,0.95); }
.client-shell .info-tab {
padding: 12px 32px; font-size: 13px; cursor: pointer; color: #595959; background: transparent; border: none; transition: all .3s cubic-bezier(.4,0,.2,1); border-right: 1px solid rgba(102,126,234,0.15); font-weight: 500; }
.client-shell .info-tab:last-child {
border-right: none; }
.client-shell .info-tab:hover {
color: #667eea; background: linear-gradient(135deg, rgba(102,126,234,0.08), rgba(118,75,162,0.08)); }
.client-shell .info-tab.active {
background: linear-gradient(135deg, #667eea, #764ba2); color: #fff; font-weight: 600; }
.client-shell .info-tab-content {
display: none; }
.client-shell .info-tab-content.active {
display: block; }
.client-shell .balance-card {
display: flex; align-items: center; justify-content: space-between;
background: linear-gradient(135deg, rgba(102,126,234,0.08), rgba(118,75,162,0.08));
border: 1px solid rgba(102,126,234,0.22); border-radius: 14px;
padding: 18px 22px; margin-bottom: 18px; }
.client-shell .balance-label {
font-size: 13px; color: #64748b; margin-bottom: 4px; }
.client-shell .balance-amount {
font-size: 1.6rem; font-weight: 700; color: #4338ca; line-height: 1.1; }
.client-shell .balance-actions {
display: flex; align-items: center; gap: 10px; }
.client-shell .balance-detail-btn {
display: inline-flex; align-items: center; gap: 7px; padding: 8px 18px;
border: 1px solid rgba(102,126,234,0.38); border-radius: 8px; background: #fff;
color: #4f46e5; font-size: 13px; font-weight: 600; cursor: pointer; transition: all .2s ease; }
.client-shell .balance-detail-btn:hover {
border-color: #667eea; background: rgba(102,126,234,0.07); transform: translateY(-1px); }
.balance-detail-modal { width: 760px; }
.balance-detail-summary {
display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; margin-bottom: 18px; }
.balance-summary-item {
padding: 14px 16px; border: 1px solid #e8edf5; border-radius: 12px; background: #f8fafc; }
.balance-summary-label { color: #64748b; font-size: 12px; margin-bottom: 5px; }
.balance-summary-value { color: #0f172a; font-size: 19px; font-weight: 700; }
.balance-summary-value.income { color: #059669; }
.balance-summary-value.expense { color: #e11d48; }
.balance-detail-filter {
display: flex; align-items: center; justify-content: space-between; gap: 12px;
flex-wrap: wrap; margin-bottom: 14px; padding: 12px; border-radius: 12px; background: #f8fafc; }
.balance-quick-periods { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.balance-period-btn {
padding: 6px 11px; border: 1px solid #dbe3ef; border-radius: 7px; background: #fff;
color: #64748b; font-size: 12px; cursor: pointer; transition: all .2s ease; }
.balance-period-btn:hover, .balance-period-btn.active {
border-color: #667eea; background: rgba(102,126,234,.08); color: #4f46e5; }
.balance-date-range { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; }
.balance-date-range input {
width: 142px; padding: 6px 9px; border: 1px solid #dbe3ef; border-radius: 7px;
background: #fff; color: #334155; font-size: 12px; outline: none; }
.balance-date-range input:focus { border-color: #667eea; box-shadow: 0 0 0 2px rgba(102,126,234,.1); }
.balance-filter-action {
padding: 7px 13px; border: 0; border-radius: 7px; background: #4f46e5;
color: #fff; font-size: 12px; font-weight: 600; cursor: pointer; }
.balance-filter-reset { background: #fff; border: 1px solid #dbe3ef; color: #64748b; }
.balance-detail-table-wrap { overflow-x: auto; border: 1px solid #e8edf5; border-radius: 12px; }
.balance-detail-table { width: 100%; border-collapse: collapse; min-width: 680px; font-size: 13px; }
.balance-detail-table th {
padding: 11px 14px; background: #f8fafc; color: #64748b; font-weight: 600; text-align: left; white-space: nowrap; }
.balance-detail-table td { padding: 13px 14px; border-top: 1px solid #eef2f7; color: #334155; white-space: nowrap; }
.balance-detail-table .amount-in { color: #059669; font-weight: 600; }
.balance-detail-table .amount-out { color: #e11d48; font-weight: 600; }
.balance-status {
display: inline-flex; padding: 3px 9px; border-radius: 999px; background: #ecfdf5; color: #059669; font-size: 11px; }
.balance-empty-row td { padding: 30px 14px; color: #94a3b8; text-align: center; }
.balance-detail-note { margin-top: 12px; color: #94a3b8; font-size: 12px; text-align: right; }
@media (max-width: 640px) {
.client-shell .balance-card { align-items: flex-start; gap: 16px; flex-direction: column; }
.client-shell .balance-actions { width: 100%; }
.client-shell .balance-actions button { flex: 1; justify-content: center; }
.balance-detail-summary { grid-template-columns: 1fr; }
}
.client-shell /* Company info cards */
.info-card {
background: rgba(255,255,255,0.95); backdrop-filter: blur(20px); border-radius: 18px; padding: 28px; box-shadow: 0 8px 32px rgba(0,0,0,.08); border: 1px solid rgba(255,255,255,0.4); }
.client-shell .info-section-title {
font-size: 15px; font-weight: 700; color: #667eea; margin-bottom: 18px; padding-bottom: 12px; border-bottom: 1px solid rgba(102,126,234,0.1); }
.client-shell .info-row {
display: flex; margin-bottom: 14px; }
.client-shell .info-label {
width: 100px; color: #8c8c8c; font-size: 13px; flex-shrink: 0; }
.client-shell .info-value {
flex: 1; color: #262626; font-size: 13px; }
.client-shell .info-grid {
display: grid; grid-template-columns: 1fr 1fr; gap: 16px 40px; }
.client-shell .info-doc-table {
width: 100%; border-collapse: collapse; font-size: 13px; }
.client-shell .info-doc-table thead th {
background: #fafafa; padding: 10px 12px; text-align: left; font-weight: 500; color: #8c8c8c; border-bottom: 1px solid #f0f0f0; }
.client-shell .info-doc-table tbody td {
padding: 12px; border-bottom: 1px solid #f5f5f5; color: #262626; }
.client-shell .info-doc-table tbody tr:last-child td {
border-bottom: none; }
.client-shell .doc-status {
color: #52c41a; font-size: 12px; }
.client-shell .doc-btn {
padding: 3px 12px; border: 1px solid #d9d9d9; border-radius: 4px; font-size: 12px; color: #595959; background: #fff; cursor: pointer; }
.client-shell .doc-btn:hover {
border-color: #1677ff; color: #1677ff; }
.client-shell .info-two-col {
display: grid; grid-template-columns: 1fr 1fr; gap: 20px; }
.client-shell .breadcrumb a:hover {
color: #667eea; }
.client-shell .breadcrumb .sep {
color: #a1a1aa; }
.client-shell .breadcrumb .current {
color: #1e293b; font-weight: 500; }
.client-shell /* ===== SHARED: Card ===== */
.card {
background: rgba(255,255,255,0.95); backdrop-filter: blur(20px); border-radius: 20px;
box-shadow: 0 8px 32px rgba(0,0,0,.08), 0 2px 8px rgba(0,0,0,.04);
border: 1px solid rgba(255,255,255,0.4);
margin-bottom: 14px; overflow: hidden;
transition: all .4s cubic-bezier(.4,0,.2,1);
}
.client-shell .card:hover {
transform: translateY(-2px); box-shadow: 0 12px 40px rgba(102,126,234,.15); }
.client-shell .card-header {
display: flex; align-items: center; justify-content: space-between;
padding: 18px 20px 14px; border-bottom: 1px solid rgba(102,126,234,0.1);
}
.client-shell .card-title {
font-size: 18px; font-weight: 700; color: #1e293b; }
.client-shell .card-subtitle {
font-size: 13px; color: #8c8c8c; margin-top: 4px; }
.client-shell .card-body {
padding: 18px 20px; }
.client-shell /* ===== SHARED: Buttons ===== */
.btn {
display: inline-flex; align-items: center; gap: 8px;
padding: 10px 20px; border-radius: 12px; font-size: 13px;
cursor: pointer; border: none; transition: all .3s cubic-bezier(.4,0,.2,1); font-family: inherit;
font-weight: 500;
}
.client-shell .btn-primary {
background: linear-gradient(135deg, #667eea, #764ba2); color: #fff; box-shadow: 0 4px 15px rgba(102,126,234,0.35); }
.client-shell .btn-primary:hover {
transform: translateY(-2px); box-shadow: 0 6px 20px rgba(102,126,234,0.45); }
.client-shell .btn-default {
background: rgba(255,255,255,0.9); color: #595959; border: 1.5px solid rgba(102,126,234,0.2); }
.client-shell .btn-default:hover {
border-color: #667eea; color: #667eea; transform: translateY(-1px); box-shadow: 0 4px 12px rgba(102,126,234,0.15); }
.client-shell .btn-danger {
background: rgba(255,255,255,0.9); color: #ff6b6b; border: 1.5px solid rgba(255,107,107,0.3); }
.client-shell .btn-danger:hover {
background: linear-gradient(135deg, rgba(255,107,107,0.05), rgba(255,77,79,0.05)); transform: translateY(-1px); }
.client-shell .btn-ghost {
background: linear-gradient(135deg, rgba(102,126,234,0.08), rgba(118,75,162,0.08)); color: #667eea; border: 1px solid rgba(102,126,234,0.2); }
.client-shell .btn-ghost:hover {
background: linear-gradient(135deg, rgba(102,126,234,0.15), rgba(118,75,162,0.15)); transform: translateY(-1px); }
.client-shell .btn-sm {
padding: 6px 12px; font-size: 12px; border-radius: 8px; }
.client-shell .btn-purple {
background: linear-gradient(135deg, #764ba2, #f093fb); color: #fff; border: none; box-shadow: 0 4px 15px rgba(118,75,162,0.35); }
.client-shell .btn-purple:hover {
transform: translateY(-2px); box-shadow: 0 6px 20px rgba(118,75,162,0.45); }
.client-shell /* Flat toolbar buttons */
.btn-flat {
display: inline-flex; align-items: center; gap: 6px;
padding: 8px 16px; border-radius: 10px; font-size: 13px;
cursor: pointer; border: 1.5px solid rgba(102,126,234,0.2); transition: all .3s cubic-bezier(.4,0,.2,1);
font-family: inherit; background: rgba(255,255,255,0.9); color: #595959;
}
.client-shell .btn-flat:hover {
border-color: #667eea; color: #667eea; background: linear-gradient(135deg, rgba(102,126,234,0.08), rgba(118,75,162,0.08)); transform: translateY(-1px); }
.client-shell .btn-flat-blue {
background: linear-gradient(135deg, #4f46e5, #7c3aed); color: #fff; border-color: transparent; box-shadow: 0 4px 16px rgba(79, 70, 229, 0.35); border-radius: 10px; padding: 10px 20px; font-weight: 500; }
.client-shell .btn-flat-blue:hover {
background: linear-gradient(135deg, #4338ca, #6d28d9); transform: translateY(-2px); box-shadow: 0 8px 22px rgba(79, 70, 229, 0.45); }
.client-shell .btn-flat-blue:active {
transform: translateY(0); box-shadow: 0 4px 12px rgba(79, 70, 229, 0.35); }
.client-shell .btn-flat-purple {
background: linear-gradient(135deg, #764ba2, #f093fb); color: #fff; border-color: transparent; box-shadow: 0 4px 15px rgba(118,75,162,0.35); }
.client-shell .btn-flat-purple:hover {
background: linear-gradient(135deg, #667eea, #764ba2); transform: translateY(-2px); box-shadow: 0 6px 20px rgba(118,75,162,0.45); }
.client-shell .btn-flat-red {
color: #ff6b6b; border-color: rgba(255,107,107,0.3); background: rgba(255,255,255,0.9); }
.client-shell .btn-flat-red:hover {
background: linear-gradient(135deg, rgba(255,107,107,0.08), rgba(255,77,79,0.08)); border-color: #ff6b6b; transform: translateY(-1px); }
.client-shell .btn-flat .icon-svg {
width: 14px; height: 14px; flex-shrink: 0; }
.client-shell /* ===== PAGE: 头程下单 - Form ===== */
.form-group {
display: flex; align-items: flex-start; gap: 12px; margin-bottom: 14px; min-height: 32px; }
.client-shell .form-group:last-child {
margin-bottom: 0; }
.client-shell .form-label {
font-size: 13px; color: #595959; font-weight: 400; min-width: 80px; text-align: right; padding-top: 5px; line-height: 22px; }
.client-shell .form-label .required {
color: #ff4d4f; margin-right: 4px; }
.client-shell .form-content {
flex: 1; display: flex; align-items: center; gap: 20px; flex-wrap: wrap; }
.client-shell .radio-group {
display: flex; flex-wrap: wrap; gap: 24px; align-items: center; }
.client-shell .radio-label {
display: inline-flex; align-items: center; gap: 10px; font-size: 13px; color: #262626; cursor: pointer; user-select: none; transition: all .2s; }
.client-shell .radio-label:hover {
color: #667eea; }
.client-shell .radio-label input[type=radio] {
width: 16px; height: 16px; accent-color: #667eea; cursor: pointer; margin: 0; }
.client-shell .radio-label.disabled {
color: #bfbfbf; cursor: not-allowed; }
.client-shell .radio-label.disabled input[type=radio] {
accent-color: #d9d9d9; cursor: not-allowed; }
.client-shell .form-input, .client-shell .form-select, .client-shell .form-textarea {
height: 40px; padding: 0 16px; border: 1.5px solid rgba(102,126,234,0.2); border-radius: 10px;
font-size: 13px; color: #262626; background: rgba(255,255,255,0.95); outline: none; transition: all .3s cubic-bezier(.4,0,.2,1); font-family: inherit;
}
.client-shell .form-input:focus, .client-shell .form-select:focus, .client-shell .form-textarea:focus {
border-color: #667eea; box-shadow: 0 0 0 4px rgba(102,126,234,0.1); }
.client-shell .form-input::placeholder, .client-shell .form-textarea::placeholder {
color: #bfbfbf; }
.client-shell /* 强制表单控件不撑宽页面 */
.main .form-input, .client-shell .main .form-select, .client-shell .main .form-textarea {
min-width: 0 !important; max-width: 100% !important; }
.client-shell .main .form-content {
flex: 1; min-width: 0; }
.client-shell .form-textarea {
width: 100%; max-width: 100%; height: 90px; padding: 12px 16px; resize: vertical; border-radius: 12px; }
.client-shell .input-wrap {
position: relative; display: flex; align-items: center; }
.client-shell .input-wrap .form-input {
padding-right: 32px; }
.client-shell .input-suffix {
position: absolute; right: 10px; color: #bfbfbf; font-size: 14px; pointer-events: none; }
.client-shell .select-wrap {
position: relative; display: inline-block; }
.client-shell .select-wrap .form-select {
min-width: 160px; padding-right: 32px; appearance: auto; }
.client-shell .date-range {
display: flex; align-items: center; gap: 8px; }
.client-shell .date-range .form-input {
width: 160px; }
.client-shell .date-sep {
color: #bfbfbf; font-size: 13px; white-space: nowrap; }
.client-shell /* Dest type tabs */
.dest-type-tabs {
display: flex; gap: 0; border: 1.5px solid rgba(102,126,234,0.2); border-radius: 14px; overflow: hidden; width: fit-content; background: rgba(255,255,255,0.95); }
.client-shell .dest-tab {
padding: 10px 28px; font-size: 13px; cursor: pointer; color: #595959; background: transparent; border: none; transition: all .3s cubic-bezier(.4,0,.2,1); border-right: 1px solid rgba(102,126,234,0.15); font-weight: 500; }
.client-shell .dest-tab:last-child {
border-right: none; }
.client-shell .dest-tab:hover {
color: #667eea; background: linear-gradient(135deg, rgba(102,126,234,0.08), rgba(118,75,162,0.08)); }
.client-shell .dest-tab.active {
background: linear-gradient(135deg, #667eea, #764ba2); color: #fff; font-weight: 600; }
.client-shell .dest-content {
display: none; }
.client-shell .dest-content.active {
display: block; }
.client-shell .dest-content-bulk {
display: none; }
.client-shell .dest-content-bulk.active {
display: block; }
.client-shell /* Goods table */
.table-toolbar {
display: flex; align-items: center; justify-content: space-between; margin-bottom: 16px; }
.client-shell .table-actions {
display: flex; gap: 10px; }
.client-shell .table-wrap {
overflow-x: auto; border: 1px solid rgba(102,126,234,0.15); border-radius: 16px; background: rgba(255,255,255,0.95); }
.client-shell table.goods-table {
width: 100%; border-collapse: collapse; font-size: 12px; }
.client-shell .goods-table thead th {
background: linear-gradient(135deg, rgba(102,126,234,0.08), rgba(118,75,162,0.08)); border-bottom: 1px solid rgba(102,126,234,0.15); padding: 14px 10px; text-align: left; font-weight: 600; color: #667eea; white-space: nowrap; position: sticky; top: 0; z-index: 1; }
.client-shell .goods-table thead th:first-child {
width: 48px; text-align: center; }
.client-shell .goods-table tbody tr {
border-bottom: 1px solid rgba(102,126,234,0.08); transition: all .3s cubic-bezier(.4,0,.2,1); }
.client-shell .goods-table tbody tr:last-child {
border-bottom: none; }
.client-shell .goods-table tbody tr:hover {
background: linear-gradient(135deg, rgba(102,126,234,0.05), rgba(118,75,162,0.05)); }
.client-shell .goods-table tbody td {
padding: 12px 10px; vertical-align: middle; }
.client-shell .goods-table tbody td:first-child {
text-align: center; color: #bfbfbf; font-size: 12px; }
.client-shell .td-input {
width: 100%; height: 36px; padding: 0 10px; border: 1.5px solid transparent; border-radius: 8px; font-size: 12px; color: #262626; background: transparent; outline: none; transition: all .3s cubic-bezier(.4,0,.2,1); font-family: inherit; }
.client-shell .td-input:focus, .client-shell .td-input:hover {
border-color: rgba(102,126,234,0.3); background: rgba(255,255,255,0.9); }
.client-shell .td-input::placeholder {
color: #bfbfbf; }
.client-shell .empty-row td {
padding: 28px 0; text-align: center; color: #bfbfbf; font-size: 13px; }
.client-shell .upload-link {
display: inline-flex; align-items: center; gap: 8px; font-size: 13px; color: #667eea; cursor: pointer; padding: 10px 22px; border: 2px dashed rgba(102,126,234,0.4); border-radius: 12px; background: linear-gradient(135deg, rgba(102,126,234,0.05), rgba(118,75,162,0.05)); transition: all .3s cubic-bezier(.4,0,.2,1); font-weight: 600; }
.client-shell .upload-link:hover {
background: linear-gradient(135deg, rgba(102,126,234,0.1), rgba(118,75,162,0.1)); border-color: #667eea; transform: translateY(-1px); }
.client-shell /* Upload zone (image upload) */
.upload-zone {
border: 2px dashed rgba(102,126,234,0.4); border-radius: 14px; padding: 32px 20px; text-align: center; cursor: pointer; background: linear-gradient(135deg, rgba(102,126,234,0.03), rgba(118,75,162,0.03)); transition: all .3s cubic-bezier(.4,0,.2,1); }
.client-shell .upload-zone:hover {
border-color: #667eea; background: linear-gradient(135deg, rgba(102,126,234,0.08), rgba(118,75,162,0.08)); }
.client-shell .upload-zone.dragover {
border-color: #667eea; background: linear-gradient(135deg, rgba(102,126,234,0.12), rgba(118,75,162,0.12)); }
.client-shell .upload-zone-icon {
font-size: 36px; margin-bottom: 8px; }
.client-shell .upload-zone-text {
font-size: 14px; color: #262626; font-weight: 600; margin-bottom: 4px; }
.client-shell .upload-zone-hint {
font-size: 12px; color: #8c8c8c; }
.client-shell .upload-preview {
display: flex; flex-wrap: wrap; gap: 12px; margin-top: 14px; }
.client-shell .upload-preview-item {
position: relative; width: 110px; height: 110px; border-radius: 10px; overflow: hidden; border: 1px solid rgba(102,126,234,0.2); background: #fff; }
.client-shell .upload-preview-item img {
width: 100%; height: 100%; object-fit: cover; }
.client-shell .upload-preview-item .upload-remove {
position: absolute; top: 4px; right: 4px; width: 22px; height: 22px; background: rgba(0,0,0,0.6); color: #fff; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 12px; cursor: pointer; line-height: 1; }
.client-shell .upload-preview-item .upload-remove:hover {
background: #ff4d4f; }
.client-shell .upload-preview-item .upload-filename {
position: absolute; bottom: 0; left: 0; right: 0; padding: 4px 6px; background: rgba(0,0,0,0.55); color: #fff; font-size: 10px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.client-shell .row-upload-cell {
display: inline-flex; align-items: center; gap: 6px; cursor: pointer; padding: 4px 10px; border: 1px dashed #d9d9d9; border-radius: 6px; font-size: 12px; color: #667eea; background: #fafafa; }
.client-shell .row-upload-cell:hover {
border-color: #667eea; background: #f0f4ff; }
.client-shell .row-upload-cell input {
display: none; }
.client-shell .row-img-cell {
width: 60px; height: 60px; border: 1px dashed #d9d9d9; border-radius: 6px; display: flex; align-items: center; justify-content: center; cursor: pointer; color: #bfbfbf; font-size: 18px; background: #fafafa; position: relative; overflow: hidden; }
.client-shell .row-img-cell:hover {
border-color: #667eea; color: #667eea; }
.client-shell .row-img-cell img {
width: 100%; height: 100%; object-fit: cover; }
.client-shell .row-img-cell input {
display: none; }
.client-shell .download-link {
display: inline-flex; align-items: center; gap: 8px; font-size: 13px; color: #595959; text-decoration: none; padding: 10px 22px; border: 1.5px solid rgba(102,126,234,0.2); border-radius: 12px; background: rgba(255,255,255,0.95); transition: all .3s cubic-bezier(.4,0,.2,1); font-weight: 500; }
.client-shell .download-link:hover {
border-color: #667eea; color: #667eea; transform: translateY(-1px); }
.client-shell /* Action row buttons — outlined style matching screenshots */
.btn-outline-blue {
display: inline-flex; align-items: center; gap: 8px; padding: 10px 22px; border: 2px solid #667eea; border-radius: 12px; color: #667eea; background: rgba(255,255,255,0.9); font-size: 13px; cursor: pointer; transition: all .3s cubic-bezier(.4,0,.2,1); font-family: inherit; font-weight: 500; }
.client-shell .btn-outline-blue:hover {
background: linear-gradient(135deg, #667eea, #764ba2); color: #fff; transform: translateY(-1px); box-shadow: 0 4px 15px rgba(102,126,234,0.35); }
.client-shell .btn-outline-red {
display: inline-flex; align-items: center; gap: 8px; padding: 10px 22px; border: 2px solid #ff6b6b; border-radius: 12px; color: #ff6b6b; background: rgba(255,255,255,0.9); font-size: 13px; cursor: pointer; transition: all .3s cubic-bezier(.4,0,.2,1); font-family: inherit; font-weight: 500; }
.client-shell .btn-outline-red:hover {
background: linear-gradient(135deg, #ff6b6b, #ff8787); color: #fff; transform: translateY(-1px); box-shadow: 0 4px 15px rgba(255,107,107,0.35); }
.client-shell .form-footer {
background: rgba(255,255,255,0.95); backdrop-filter: blur(20px); border-radius: 16px; padding: 20px 28px; display: flex; flex-direction: column; align-items: center; gap: 12px; box-shadow: 0 8px 32px rgba(0,0,0,.08); border: 1px solid rgba(255,255,255,0.4); position: sticky; bottom: 0; z-index: 50; }
.client-shell .footer-tips {
font-size: 12px; color: #8c8c8c; display: flex; align-items: center; gap: 8px; }
.client-shell .footer-tips .tip-icon {
color: #ffd93d; }
.client-shell .btn-submit {
background: linear-gradient(135deg, #667eea, #764ba2, #f093fb); color: #fff; border: none; padding: 12px 48px; border-radius: 14px; font-size: 15px; font-weight: 600; cursor: pointer; transition: all .3s cubic-bezier(.4,0,.2,1); box-shadow: 0 6px 20px rgba(102,126,234,.4); }
.client-shell .btn-submit:hover {
background: linear-gradient(135deg, #764ba2, #f093fb, #667eea); box-shadow: 0 8px 25px rgba(102,126,234,.5); transform: translateY(-2px); }
.client-shell .btn-submit:active {
transform: translateY(0); }
.client-shell /* ===== 费用预估 ===== */
.cost-estimate {
margin-top: 16px; }
.client-shell .cost-estimate .card-header {
border-bottom: none; padding-bottom: 0; }
.client-shell .cost-cards {
display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; }
.client-shell .cost-card {
background: #fff; border-radius: 20px; padding: 28px 20px; text-align: center;
cursor: pointer; transition: all .35s cubic-bezier(.4,0,.2,1);
border: 2px solid rgba(102,126,234,.08);
position: relative;
box-shadow: 0 2px 12px rgba(102,126,234,.04);
}
.client-shell .cost-card:hover {
transform: translateY(-4px);
box-shadow: 0 8px 28px rgba(102,126,234,.15);
border-color: rgba(102,126,234,.25);
}
.client-shell .cost-card.active {
background: linear-gradient(135deg, rgba(102,126,234,.06), rgba(118,75,162,.06));
border-color: #667eea;
box-shadow: 0 6px 24px rgba(102,126,234,.22), inset 0 1px 0 rgba(255,255,255,.6);
}
.client-shell .cost-badge {
position: absolute; top: -10px; right: 18px;
padding: 4px 14px; border-radius: 12px; font-size: 11px; font-weight: 600; color: #fff;
line-height: 1.4;
}
.client-shell .cost-badge.fastest {
background: linear-gradient(135deg, #5c6bc0, #3949ab); }
.client-shell .cost-badge.recommend {
background: linear-gradient(135deg, #667eea, #764ba2); box-shadow: 0 3px 10px rgba(102,126,234,.35); }
.client-shell .cost-badge.economy {
background: linear-gradient(135deg, #78909c, #546e7a); }
.client-shell .cost-days {
font-size: 26px; font-weight: 700; color: #333; margin-bottom: 14px; letter-spacing: 1px; }
.client-shell .cost-price {
font-size: 34px; font-weight: 800; color: #667eea; margin-bottom: 10px; line-height: 1.2; }
.client-shell .cost-price span {
font-size: 20px; font-weight: 600; }
.client-shell .cost-desc {
font-size: 13px; color: #999; }
.client-shell input[type=checkbox] {
width: 16px; height: 16px; accent-color: #667eea; cursor: pointer; }
.client-shell .col-checkbox {
width: 36px; }
.client-shell /* ===== PAGE: 订单列表 - Filter ===== */
.filter-grid {
display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px 20px; align-items: center; }
.client-shell .filter-item {
display: flex; align-items: center; gap: 8px; }
.client-shell .filter-item.span2 {
grid-column: span 2; }
.client-shell .filter-label {
font-size: 13px; color: #595959; white-space: nowrap; flex-shrink: 0; min-width: 70px; text-align: right; }
.client-shell .filter-input, .client-shell .filter-select {
flex: 1; height: 40px; padding: 0 16px; border: 1.5px solid rgba(102,126,234,0.2); border-radius: 10px; font-size: 13px; color: #262626; background: rgba(255,255,255,0.95); outline: none; font-family: inherit; min-width: 0; transition: all .3s cubic-bezier(.4,0,.2,1); }
.client-shell .filter-input:focus, .client-shell .filter-select:focus {
border-color: #667eea; box-shadow: 0 0 0 4px rgba(102,126,234,0.1); }
.client-shell .filter-input::placeholder {
color: #bfbfbf; }
.client-shell .date-range-wrap {
display: flex; align-items: center; gap: 6px; flex: 1; }
.client-shell .date-range-wrap .filter-input {
flex: 1; }
.client-shell .filter-actions {
display: flex; align-items: center; gap: 12px; margin-top: 16px; padding-top: 16px; border-top: 1px solid rgba(79, 70, 229, 0.1); flex-wrap: wrap; }
.client-shell /* Data table */
.table-wrap-simple {
overflow-x: auto; border: 1px solid rgba(102,126,234,0.15); border-radius: 16px; background: rgba(255,255,255,0.95); }
.client-shell .data-table {
width: 100%; border-collapse: collapse; font-size: 12px; }
.client-shell .data-table thead th {
background: linear-gradient(135deg, rgba(102,126,234,0.08), rgba(118,75,162,0.08)); padding: 14px 14px; text-align: left; font-weight: 600; color: #667eea; border-bottom: 1px solid rgba(102,126,234,0.15); white-space: nowrap; }
.client-shell .data-table tbody td {
padding: 14px 14px; border-bottom: 1px solid rgba(102,126,234,0.08); color: #262626; white-space: nowrap; }
.client-shell .data-table tbody tr:hover {
background: linear-gradient(135deg, rgba(102,126,234,0.05), rgba(118,75,162,0.05)); }
.client-shell .data-table tbody tr:last-child td {
border-bottom: none; }
.client-shell .data-table .col-checkbox {
width: 40px; text-align: center; }
.client-shell .data-table .col-checkbox input {
cursor: pointer; }
.client-shell .empty-state {
text-align: center; padding: 60px 20px; color: #bfbfbf; }
.client-shell .empty-state .empty-icon {
font-size: 48px; margin-bottom: 12px; }
.client-shell .empty-state .empty-text {
font-size: 14px; }
.client-shell /* Quick Order Table */
.quick-table-wrap {
border: 1px solid rgba(102,126,234,0.15); border-radius: 16px; overflow: hidden; background: rgba(255,255,255,0.95); }
.client-shell .quick-table {
width: 100%; border-collapse: collapse; font-size: 13px; }
.client-shell .quick-table thead th {
background: linear-gradient(135deg, rgba(102,126,234,0.08), rgba(118,75,162,0.08)); padding: 14px 16px; text-align: left; font-weight: 600; color: #667eea; border-bottom: 1px solid rgba(102,126,234,0.15); }
.client-shell .quick-table tbody td {
padding: 16px 16px; border-bottom: 1px solid rgba(102,126,234,0.08); vertical-align: top; }
.client-shell .quick-table tbody tr:last-child td {
border-bottom: none; }
.client-shell .quick-table .select-wrap .form-select {
min-width: 120px; }
.client-shell .product-line {
display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 8px; }
.client-shell .product-line:last-child {
margin-bottom: 0; }
.client-shell /* Tags */
.tag {
display: inline-flex; align-items: center; padding: 4px 10px; border-radius: 8px; font-size: 12px; font-weight: 600; white-space: nowrap; }
.client-shell .tag-blue {
background: linear-gradient(135deg, rgba(102,126,234,0.15), rgba(118,75,162,0.15)); color: #667eea; border: 1px solid rgba(102,126,234,0.3); }
.client-shell .tag-success {
background: linear-gradient(135deg, rgba(82,196,26,0.12), rgba(116,227,101,0.12)); color: #52c41a; border: 1px solid rgba(82,196,26,0.3); }
.client-shell .tag-warning {
background: linear-gradient(135deg, rgba(255,217,61,0.15), rgba(250,173,20,0.15)); color: #faad14; border: 1px solid rgba(250,173,20,0.3); }
.client-shell .tag-error {
background: linear-gradient(135deg, rgba(255,107,107,0.12), rgba(255,77,79,0.12)); color: #ff6b6b; border: 1px solid rgba(255,107,107,0.3); }
.client-shell .tag-info {
background: linear-gradient(135deg, rgba(102,126,234,0.15), rgba(118,75,162,0.15)); color: #667eea; border: 1px solid rgba(102,126,234,0.3); }
.client-shell .tag-default {
background: rgba(0,0,0,0.05); color: #8c8c8c; border: 1px solid rgba(0,0,0,0.1); }
.client-shell /* Pagination */
.pagination-bar {
display: flex; align-items: center; justify-content: space-between; padding: 16px 28px; border-top: 1px solid rgba(102,126,234,0.1); font-size: 13px; color: #8c8c8c; }
.client-shell .pagination-info {
display: flex; align-items: center; gap: 10px; }
.client-shell .pagination-ctrl {
display: flex; align-items: center; gap: 6px; }
.client-shell .page-btn {
min-width: 36px; height: 36px; display: flex; align-items: center; justify-content: center; border: 1.5px solid rgba(102,126,234,0.2); background: rgba(255,255,255,0.95); border-radius: 10px; font-size: 13px; color: #595959; cursor: pointer; transition: all .3s cubic-bezier(.4,0,.2,1); padding: 0 10px; font-weight: 500; }
.client-shell .page-btn:hover {
border-color: #667eea; color: #667eea; transform: translateY(-1px); }
.client-shell .page-btn.active {
background: linear-gradient(135deg, #667eea, #764ba2); color: #fff; border-color: transparent; box-shadow: 0 4px 15px rgba(102,126,234,0.35); }
.client-shell .page-btn:disabled {
opacity: .5; cursor: not-allowed; border-color: rgba(0,0,0,0.1); color: #bfbfbf; }
.client-shell .page-size-select {
height: 36px; padding: 0 12px; border: 1.5px solid rgba(102,126,234,0.2); border-radius: 10px; font-size: 13px; background: rgba(255,255,255,0.95); outline: none; transition: all .3s cubic-bezier(.4,0,.2,1); }
.client-shell .page-size-select:focus {
border-color: #667eea; box-shadow: 0 0 0 4px rgba(102,126,234,0.1); }
.client-shell /* Scrollbar */
::-webkit-scrollbar {
width: 6px; height: 6px; }
.client-shell ::-webkit-scrollbar-track {
background: transparent; }
.client-shell ::-webkit-scrollbar-thumb {
background: #d9d9d9; border-radius: 3px; }
.client-shell ::-webkit-scrollbar-thumb:hover {
background: #bfbfbf; }
.client-shell /* ===== Modal ===== */
.modal-overlay {
display: none; position: fixed; inset: 0; z-index: 1000;
background: rgba(0,0,0,.45); backdrop-filter: blur(4px);
align-items: center; justify-content: center;
}
.client-shell .modal-overlay.show {
display: flex; }
.client-shell .modal-box {
background: #fff; border-radius: 16px; width: 600px; max-width: 90vw;
max-height: 85vh; overflow: hidden; display: flex; flex-direction: column;
box-shadow: 0 20px 60px rgba(0,0,0,.25);
animation: modalIn .3s cubic-bezier(.4,0,.2,1);
}
@keyframes modalIn {
from { opacity: 0; transform: scale(.92) translateY(20px); } to { opacity: 1; transform: scale(1) translateY(0); } }
.client-shell .modal-header {
display: flex; align-items: center; justify-content: space-between;
padding: 20px 28px; border-bottom: 1px solid #f0f0f0;
}
.client-shell .modal-title {
font-size: 16px; font-weight: 600; color: #262626; }
.client-shell .modal-close {
width: 32px; height: 32px; border: none; background: #f5f5f5; border-radius: 8px;
cursor: pointer; font-size: 18px; color: #8c8c8c; transition: all .2s;
display: flex; align-items: center; justify-content: center;
}
.client-shell .modal-close:hover {
background: #fff1f0; color: #ff4d4f; }
.client-shell .modal-body {
flex: 1; overflow-y: auto; padding: 28px; }
.client-shell .doc-preview {
text-align: center; }
.client-shell .doc-preview img {
max-width: 100%; border-radius: 8px; border: 1px solid #f0f0f0; }
.client-shell .doc-info {
margin-top: 20px; }
.client-shell .doc-info-row {
display: flex; margin-bottom: 12px; font-size: 13px; }
.client-shell .doc-info-label {
width: 100px; color: #8c8c8c; flex-shrink: 0; }
.client-shell .doc-info-value {
color: #262626; flex: 1; }
.client-shell .modal-footer {
display: flex; justify-content: flex-end; gap: 12px;
padding: 16px 28px; border-top: 1px solid #f0f0f0;
}
.client-shell .modal-box.modal-wide {
width: 920px; max-width: 92vw; }
.client-shell .modal-section-title {
font-size: 14px; font-weight: 600; color: #262626; margin-bottom: 12px; padding-left: 10px; border-left: 3px solid #667eea; }
.client-shell .page-header-actions {
display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px; }
.client-shell .page-header-actions .page-title {
margin: 0; }
.client-shell .page-action-group {
display: flex; gap: 10px; }
.client-shell .status-badge {
display: inline-flex; align-items: center; padding: 4px 10px; border-radius: 6px; font-size: 12px; font-weight: 500; }
.client-shell .status-pending {
background: #fff7e6; color: #fa8c16; }
.client-shell .status-processing {
background: #e6f7ff; color: #1677ff; }
.client-shell .status-done {
background: #f6ffed; color: #52c41a; }
.client-shell .status-rejected {
background: #fff1f0; color: #ff4d4f; }
.client-shell .link-action {
color: #1677ff; font-size: 12px; cursor: pointer; margin-right: 8px; }
.client-shell .link-action:hover {
color: #0056b3; text-decoration: underline; }
.client-shell .form-section {
margin-bottom: 14px; }
.client-shell .form-section:last-child {
margin-bottom: 0; }
.client-shell .product-table-wrap {
overflow-x: auto; border: 1px solid #f0f0f0; border-radius: 10px; margin-bottom: 12px; }
.client-shell .product-table {
width: 100%; border-collapse: collapse; font-size: 12px; }
.client-shell .product-table thead th {
background: #f8f8ff; padding: 12px; text-align: left; font-weight: 600; color: #667eea; border-bottom: 1px solid #e8e8ff; }
.client-shell .product-table tbody td {
padding: 10px 12px; border-bottom: 1px solid #f0f0f0; }
.client-shell .product-table tbody tr:last-child td {
border-bottom: none; }
.client-shell .product-table .cell-input {
width: 100%; min-width: 100px; height: 34px; padding: 0 10px; border: 1px solid #d9d9d9; border-radius: 6px; font-size: 12px; outline: none; }
.client-shell .product-table .cell-input:focus {
border-color: #667eea; box-shadow: 0 0 0 3px rgba(102,126,234,0.1); }
.client-shell .text-error {
color: #ff4d4f; font-size: 12px; margin-top: 4px; }
.client-shell .btn-text {
color: #1677ff; font-size: 13px; cursor: pointer; background: none; border: none; display: inline-flex; align-items: center; gap: 4px; }
.client-shell .btn-text:hover {
color: #0056b3; }
.client-shell .btn-ghost {
background: #fff; border: 1px solid #d9d9d9; color: #595959; padding: 8px 18px; border-radius: 10px; font-size: 13px; cursor: pointer; transition: all .2s; }
.client-shell .btn-ghost:hover {
border-color: #667eea; color: #667eea; }
/* ===== 仓储转运单 ===== */
.client-shell .storage-transfer-filter-grid,
.client-shell .storage-transfer-form-grid,
.client-shell .storage-transfer-summary-grid {
display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 16px 20px; }
.client-shell .storage-transfer-filter-item,
.client-shell .storage-transfer-field {
display: flex; flex-direction: column; gap: 7px; min-width: 0; }
.client-shell .storage-transfer-filter-label,
.client-shell .storage-transfer-field-label {
color: #475569; font-size: 12px; font-weight: 600; }
.client-shell .storage-transfer-input,
.client-shell .storage-transfer-select,
.client-shell .storage-transfer-textarea {
width: 100%; border: 1px solid #dbe3ef; border-radius: 8px; background: #fff;
color: #1e293b; font-size: 13px; outline: none; transition: border-color .2s, box-shadow .2s; }
.client-shell .storage-transfer-input,
.client-shell .storage-transfer-select {
height: 38px; padding: 0 11px; }
.client-shell .storage-transfer-textarea {
min-height: 84px; padding: 10px 11px; resize: vertical; }
.client-shell .storage-transfer-input:focus,
.client-shell .storage-transfer-select:focus,
.client-shell .storage-transfer-textarea:focus {
border-color: #667eea; box-shadow: 0 0 0 3px rgba(102,126,234,.1); }
.client-shell .storage-transfer-span-3 {
grid-column: 1 / -1; }
.client-shell .storage-transfer-filter-actions,
.client-shell .storage-transfer-form-actions {
display: flex; align-items: center; justify-content: flex-end; gap: 10px; margin-top: 18px; }
.client-shell .storage-transfer-section {
margin-bottom: 14px; }
.client-shell .storage-transfer-section-title {
color: #1e293b; font-size: 14px; font-weight: 700; margin-bottom: 16px;
padding-bottom: 10px; border-bottom: 1px solid #eef2f7; }
.client-shell .storage-transfer-relabel {
display: flex; align-items: flex-start; gap: 10px; padding: 14px 16px;
border: 1px solid #dbe3ef; border-radius: 9px; background: #f8fafc; }
.client-shell .storage-transfer-relabel-copy {
color: #64748b; font-size: 12px; line-height: 1.6; }
.client-shell .storage-transfer-radio-group {
display: flex; align-items: center; gap: 18px; }
.client-shell .storage-transfer-radio-option {
display: inline-flex; align-items: center; gap: 7px; color: #334155; font-size: 13px; cursor: pointer; }
.client-shell .storage-transfer-date-range {
display: grid; grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr); align-items: center; gap: 7px; }
.client-shell .storage-transfer-file-name {
display: block; max-width: 130px; margin-top: 5px; color: #64748b; font-size: 11px;
overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.client-shell .storage-transfer-error {
min-height: 16px; margin-top: 4px; color: #ff4d4f; font-size: 12px; line-height: 1.35; }
.client-shell .storage-transfer-input[aria-invalid="true"],
.client-shell .storage-transfer-select[aria-invalid="true"],
.client-shell .storage-transfer-cargo-input[aria-invalid="true"] {
border-color: #ff4d4f; }
.client-shell .storage-transfer-cargo-input {
width: 100%; min-width: 108px; height: 34px; padding: 0 9px; border: 1px solid #d9d9d9;
border-radius: 6px; color: #1e293b; font-size: 12px; outline: none; }
.client-shell .storage-transfer-cargo-input:focus {
border-color: #667eea; box-shadow: 0 0 0 3px rgba(102,126,234,.1); }
.client-shell .storage-transfer-cargo-error {
min-height: 15px; margin-top: 3px; color: #ff4d4f; font-size: 11px; }
.client-shell .storage-transfer-file-control {
display: inline-flex; align-items: center; min-height: 32px; color: #1677ff; cursor: pointer; }
.client-shell .storage-transfer-file-control input { position: absolute; width: 1px; height: 1px; opacity: 0; }
.client-shell .storage-transfer-cargo-table { min-width: 920px; }
.client-shell .storage-transfer-list-card .table-wrap-simple { overflow-x: auto; }
.client-shell .storage-transfer-list-card .data-table { min-width: 1500px; }
.client-shell .storage-transfer-submit[disabled] { cursor: not-allowed; opacity: .65; }
.client-shell .storage-transfer-summary-item {
padding: 14px 16px; border: 1px solid #e8edf5; border-radius: 8px; background: #f8fafc; }
.client-shell .storage-transfer-summary-label {
color: #64748b; font-size: 12px; margin-bottom: 5px; }
.client-shell .storage-transfer-summary-value {
color: #1e293b; font-size: 13px; font-weight: 600; }
.client-shell .storage-transfer-relation-grid {
display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; }
.client-shell .storage-transfer-relation-item {
padding: 14px 16px; border: 1px solid #dbeafe; border-radius: 8px; background: #eff6ff; }
.client-shell .storage-transfer-pagination {
display: flex; align-items: center; justify-content: space-between; min-height: 56px;
padding: 10px 16px; border-top: 1px solid #f0f0f0; }
@media (max-width: 760px) {
.client-shell .storage-transfer-filter-grid,
.client-shell .storage-transfer-form-grid,
.client-shell .storage-transfer-summary-grid,
.client-shell .storage-transfer-relation-grid {
grid-template-columns: minmax(0, 1fr); }
.client-shell .storage-transfer-span-3 {
grid-column: auto; }
.client-shell .storage-transfer-filter-actions,
.client-shell .storage-transfer-form-actions {
flex-wrap: wrap; }
}
.client-shell .return-relabel-filter-grid,.client-shell .return-relabel-form-grid,.client-shell .return-relabel-summary-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:16px 20px}.client-shell .return-relabel-filter-grid label,.client-shell .return-relabel-form-grid label{display:block;color:#475569;font-size:12px;font-weight:600;margin-bottom:7px}.client-shell .return-relabel-input,.client-shell .return-relabel-select,.client-shell .return-relabel-textarea{width:100%;height:38px;padding:0 11px;border:1px solid #dbe3ef;border-radius:8px;background:#fff;color:#1e293b;font-size:13px;outline:none}.client-shell .return-relabel-textarea{height:84px;padding:10px;resize:vertical}.client-shell .return-relabel-filter-actions,.client-shell .return-relabel-form-actions{display:flex;justify-content:flex-end;gap:10px;margin-top:16px}.client-shell .return-relabel-table{min-width:1500px}.client-shell .return-relabel-list-card .table-wrap-simple,.client-shell .return-relabel-table-wrap{overflow-x:auto}.client-shell .return-relabel-pagination{display:flex;justify-content:space-between;align-items:center;padding:12px 16px;border-top:1px solid #f0f0f0}.client-shell .return-relabel-section{margin-bottom:14px}.client-shell .return-relabel-section-title{font-weight:700;color:#1e293b;font-size:14px;margin-bottom:14px;padding-bottom:10px;border-bottom:1px solid #eef2f7}.client-shell .return-relabel-case-grid{display:flex;flex-wrap:wrap;gap:14px;margin:14px 0;color:#475569;font-size:12px}.client-shell .return-relabel-file-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:16px}.client-shell .return-relabel-relation-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:14px}.client-shell .return-relabel-relation-grid>div{padding:14px;border:1px solid #dbeafe;background:#eff6ff;border-radius:8px}.client-shell .return-relabel-relation-grid label{display:block;color:#64748b;font-size:12px;margin-bottom:5px}.client-shell .return-relabel-error{min-height:18px;color:#ff4d4f;font-size:12px;margin-top:10px}.client-shell .return-relabel-span-2{grid-column:span 2}@media(max-width:760px){.client-shell .return-relabel-filter-grid,.client-shell .return-relabel-form-grid,.client-shell .return-relabel-summary-grid,.client-shell .return-relabel-relation-grid,.client-shell .return-relabel-file-grid{grid-template-columns:1fr}.client-shell .return-relabel-span-2{grid-column:auto}.client-shell .return-relabel-filter-actions,.client-shell .return-relabel-form-actions{flex-wrap:wrap;justify-content:flex-start}}
.client-shell .cargo-disposal-filter-grid,
.client-shell .cargo-disposal-summary-grid { display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:16px 20px; }
.client-shell .cargo-disposal-filter-item,
.client-shell .cargo-disposal-field { display:flex; flex-direction:column; gap:7px; min-width:0; }
.client-shell .cargo-disposal-label { color:#475569; font-size:12px; font-weight:600; }
.client-shell .cargo-disposal-input,
.client-shell .cargo-disposal-select { width:100%; height:38px; padding:0 11px; border:1px solid #dbe3ef; border-radius:8px; background:#fff; color:#1e293b; font-size:13px; outline:none; }
.client-shell .cargo-disposal-input:focus,.client-shell .cargo-disposal-select:focus { border-color:#1677ff; box-shadow:0 0 0 3px rgba(22,119,255,.1); }
.client-shell .cargo-disposal-actions { display:flex; justify-content:flex-end; gap:10px; margin-top:18px; }
.client-shell .cargo-disposal-inbound-card { border:1px solid #dbe3ef; border-radius:10px; background:#fff; margin-bottom:12px; overflow:hidden; }
.client-shell .cargo-disposal-inbound-card.is-selected { border-color:#1677ff; box-shadow:0 0 0 2px rgba(22,119,255,.08); }
.client-shell .cargo-disposal-inbound-summary { display:flex; align-items:center; justify-content:space-between; gap:14px; padding:14px 16px; cursor:pointer; }
.client-shell .cargo-disposal-inbound-meta { color:#64748b; font-size:12px; margin-top:4px; }
.client-shell .cargo-disposal-inbound-search { max-width:440px; margin:14px 0 16px; }
.client-shell .cargo-disposal-inbound-search .cargo-disposal-label { display:block; margin-bottom:7px; }
.client-shell .cargo-disposal-inbound-body { display:none; padding:0 16px 16px; border-top:1px solid #eef2f7; }
.client-shell .cargo-disposal-inbound-card.expanded .cargo-disposal-inbound-body { display:block; }
.client-shell .cargo-disposal-table { width:100%; min-width:680px; border-collapse:collapse; font-size:12px; }
.client-shell .cargo-disposal-table th { background:#f8fafc; color:#64748b; padding:10px; text-align:left; }
.client-shell .cargo-disposal-table td { padding:10px; border-top:1px solid #f0f0f0; }
.client-shell .cargo-disposal-table-wrap { overflow-x:auto; margin-top:14px; }
.client-shell .cargo-disposal-quantity { width:92px; height:34px; padding:0 8px; border:1px solid #d9d9d9; border-radius:6px; }
.client-shell .cargo-disposal-fee-bar { display:flex; justify-content:space-between; align-items:center; gap:12px; padding:14px 16px; margin-top:14px; border-radius:8px; background:#e7f4f1; color:#225b56; }
.client-shell .cargo-disposal-fee-amount { color:#087d73; font-size:18px; font-weight:700; }
.client-shell .cargo-disposal-relation-grid { display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:14px; }
.client-shell .cargo-disposal-relation-item { padding:14px 16px; border:1px solid #dbeafe; border-radius:8px; background:#eff6ff; }
@media (max-width:760px) { .client-shell .cargo-disposal-filter-grid,.client-shell .cargo-disposal-summary-grid,.client-shell .cargo-disposal-relation-grid { grid-template-columns:minmax(0,1fr); } .client-shell .cargo-disposal-inbound-summary { align-items:flex-start; } .client-shell .cargo-disposal-actions { flex-wrap:wrap; } }
</style>
</head>
<body class="text-gray-800 antialiased bg-gray-50">
<!-- Toast 提示 -->
<div id="toast" class="fixed top-24 left-1/2 -translate-x-1/2 z-[60] opacity-0 pointer-events-none transition-all duration-300 transform -translate-y-4">
<div class="bg-gray-900 text-white px-6 py-3 rounded-full shadow-2xl flex items-center space-x-2">
<i class="fas fa-info-circle text-brand-green"></i>
<span id="toastMessage">提示信息</span>
</div>
</div>
<!-- 工作台 -->
<section id="workbench" class="min-h-screen flex">
<aside id="dashSidebar" class="dash-sidebar">
<div class="dash-sidebar-brand">
<img src="assets/logo.png" alt="虫虫出海" style="width:161px;height:60px;object-fit:contain;">
</div>
<nav class="dash-nav">
<!-- 业务总览(工作台首页) -->
<a class="dash-nav-link active" data-view="Home" onclick="dashNavigate('Home', this)">
<i class="fas fa-gauge-high"></i><span data-i18n="m_overview">业务总览</span>
</a>
<!-- 头程物流 -->
<div class="dash-menu-group">
<div class="dash-menu-group-header" onclick="toggleDashGroup(this)">
<span class="g-icon"><i class="fas fa-ship"></i></span>
<span class="g-title" data-i18n="m_g_head">头程物流</span>
<span class="g-arrow"><i class="fas fa-chevron-down"></i></span>
</div>
<div class="dash-menu-sub">
<a class="dash-nav-link sub" data-gicon="fa-file-invoice" data-gtitle="m_head_order" data-gsub="m_head_order_sub" onclick="dashNavigate('order', this)"><i class="fas fa-file-invoice"></i><span data-i18n="m_head_order">头程下单</span></a>
<a class="dash-nav-link sub" data-gicon="fa-file-import" data-gtitle="m_head_bulk" data-gsub="m_head_bulk_sub" onclick="dashNavigate('bulk', this)"><i class="fas fa-file-import"></i><span data-i18n="m_head_bulk">一键导入</span></a>
<a class="dash-nav-link sub" data-gicon="fa-bolt" data-gtitle="m_head_quick" data-gsub="m_head_quick_sub" onclick="dashNavigate('quick', this)"><i class="fas fa-bolt"></i><span data-i18n="m_head_quick">快速下单</span></a>
</div>
</div>
<!-- 出海下单 -->
<div class="dash-menu-group">
<div class="dash-menu-group-header" onclick="toggleDashGroup(this)">
<span class="g-icon"><i class="fas fa-plane-departure"></i></span>
<span class="g-title" data-i18n="m_g_sea">出海下单</span>
<span class="g-arrow"><i class="fas fa-chevron-down"></i></span>
</div>
<div class="dash-menu-sub">
<a class="dash-nav-link sub" href="#" data-view="Procurement" data-business="Procurement" onclick="openSeaBusiness('Procurement','list',this);return false;"><i class="fas fa-shopping-cart"></i><span>海外采购</span></a>
<a class="dash-nav-link sub" href="#" data-view="Truck" data-business="Truck" onclick="openSeaBusiness('Truck','list',this);return false;"><i class="fas fa-truck-moving"></i><span>美国本土卡</span></a>
<a class="dash-nav-link sub" href="#" data-view="Pallet" data-business="Pallet" onclick="openSeaBusiness('Pallet','list',this);return false;"><i class="fas fa-pallet"></i><span>美本土散板</span></a>
</div>
</div>
<!-- 海外仓 -->
<div class="dash-menu-group">
<div class="dash-menu-group-header" onclick="toggleDashGroup(this)">
<span class="g-icon"><i class="fas fa-warehouse"></i></span>
<span class="g-title" data-i18n="m_g_overseas">海外仓</span>
<span class="g-arrow"><i class="fas fa-chevron-down"></i></span>
</div>
<div class="dash-menu-sub">
<a class="dash-nav-link sub" data-gicon="fa-tags" data-gtitle="m_ov_label" data-gsub="m_ov_label_sub" onclick="dashNavigate('labeling-list', this)"><i class="fas fa-tags"></i><span data-i18n="m_ov_label">贴标申请</span></a>
<a class="dash-nav-link sub" data-gicon="fa-truck-fast" onclick="dashNavigate('storage-transfer-list', this)"><i class="fas fa-truck-fast"></i><span>仓储转运</span></a>
<a class="dash-nav-link sub" data-gicon="fa-box-open" onclick="dashNavigate('cargo-disposal-list', this)"><i class="fas fa-box-open"></i><span>货物废弃</span></a>
<a class="dash-nav-link sub" data-gicon="fa-retweet" onclick="dashNavigate('return-relabel-list', this)"><i class="fas fa-retweet"></i><span>退货换标</span></a>
</div>
</div>
<!-- 订单管理 -->
<div class="dash-menu-group">
<div class="dash-menu-group-header" onclick="toggleDashGroup(this)">
<span class="g-icon"><i class="fas fa-clipboard-list"></i></span>
<span class="g-title" data-i18n="m_g_order">订单管理</span>
<span class="g-arrow"><i class="fas fa-chevron-down"></i></span>
</div>
<div class="dash-menu-sub">
<a class="dash-nav-link sub" data-gicon="fa-boxes-stacked" data-gtitle="m_inbound" data-gsub="m_inbound_sub" onclick="dashNavigate('inbound', this)"><i class="fas fa-boxes-stacked"></i><span data-i18n="m_inbound">入库订单列表</span></a>
<a class="dash-nav-link sub" data-gicon="fa-truck-ramp-box" data-gtitle="m_delivery" data-gsub="m_delivery_sub" onclick="dashNavigate('delivery', this)"><i class="fas fa-truck-ramp-box"></i><span data-i18n="m_delivery">派送订单列表</span></a>
</div>
</div>
<!-- 财务结算 -->
<div class="dash-menu-group">
<div class="dash-menu-group-header" onclick="toggleDashGroup(this)">
<span class="g-icon"><i class="fas fa-file-invoice-dollar"></i></span>
<span class="g-title" data-i18n="m_g_fin">财务结算</span>
<span class="g-arrow"><i class="fas fa-chevron-down"></i></span>
</div>
<div class="dash-menu-sub">
<a class="dash-nav-link sub" data-gicon="fa-money-bill-wave" data-gtitle="m_bizfee" data-gsub="m_bizfee_sub" onclick="dashNavigate('biz-fee', this)"><i class="fas fa-money-bill-wave"></i><span data-i18n="m_bizfee">应付账单</span></a>
</div>
</div>
<div class="dash-nav-divider"></div>
<!-- 设置类 -->
<a class="dash-nav-link" data-gicon="fa-building" data-gtitle="m_company" data-gsub="m_company_sub" onclick="dashNavigate('company', this)">
<i class="fas fa-building"></i><span data-i18n="m_company">公司信息</span>
</a>
<a class="dash-nav-link" data-gicon="fa-user" data-gtitle="m_profile" data-gsub="m_profile_sub" onclick="dashNavigate('profile', this)">
<i class="fas fa-user"></i><span data-i18n="m_profile">我的信息</span>
</a>
<a class="dash-nav-link logout" onclick="doLogout()">
<i class="fas fa-sign-out-alt"></i><span data-i18n="dash_logout">退出登录</span>
</a>
</nav>
<div class="dash-sidebar-bottom">
<div id="langSwitcherDash" class="lang-switcher flex">
<button data-lang="zh">中</button>
<button data-lang="en">EN</button>
<button data-lang="es">🇲🇽</button>
</div>
</div>
</aside>
<!-- 移动端遮罩 -->
<div id="dashOverlay" class="dash-overlay" onclick="toggleDashSidebar()"></div>
<!-- 主内容区 -->
<div class="dash-main">
<header class="dash-topbar sticky top-0 z-30">
<div class="px-4 sm:px-5 lg:px-6 h-14 flex items-center justify-between">
<div class="flex items-center space-x-3">
<button class="dash-menu-btn" onclick="toggleDashSidebar()"><i class="fas fa-bars"></i></button>
<span class="text-sm text-gray-500" id="dashUserName">Hi, 客户</span>
</div>
<div class="flex items-center space-x-4">
<button class="dash-topup-btn" onclick="openTopup()"><i class="fas fa-wallet"></i><span data-i18n="dash_topup">充值</span></button>
<a href="index.html" class="text-sm text-gray-600 hover:text-brand-blue font-medium px-3 py-2 transition-colors" data-i18n="dash_home_link">返回官网</a>
</div>
</div>
</header>
<div class="flex flex-1 min-h-0">
<main class="flex-1 px-4 sm:px-5 lg:px-6 py-5 min-w-0">
<!-- 视图1:选择业务 -->
<div id="dashViewHome" class="dash-view">
<div class="mb-6">
<h1 class="text-3xl lg:text-4xl font-bold text-gray-900 mb-3" data-i18n="dash_welcome_title">选择业务,快速下单</h1>
<p class="text-gray-500" data-i18n="dash_welcome_sub">请选择您需要的业务类型,填写信息后提交订单,我们将尽快为您安排。</p>
</div>
<div class="grid md:grid-cols-3 gap-4">
<div class="dash-card p-6" onclick="openOrder('Procurement')">
<div class="w-14 h-14 rounded-2xl bg-gradient-to-br from-brand-blue to-brand-blueDark flex items-center justify-center text-white text-2xl mb-6">
<i class="fas fa-shopping-cart"></i>
</div>
<h3 class="text-xl font-bold text-gray-900 mb-2" data-i18n="dash_biz1_title">海外采购</h3>
<p class="text-sm text-gray-500 mb-6" data-i18n="dash_biz1_desc">采购代购 · 验货质检 · 集中发货</p>
<span class="inline-flex items-center text-brand-blue font-semibold text-sm">
<span data-i18n="dash_start">开始下单</span><i class="fas fa-arrow-right ml-2"></i>
</span>
</div>
<div class="dash-card p-6" onclick="openOrder('Truck')">
<div class="w-14 h-14 rounded-2xl bg-gradient-to-br from-brand-green to-brand-greenDark flex items-center justify-center text-white text-2xl mb-6">
<i class="fas fa-truck-moving"></i>
</div>
<h3 class="text-xl font-bold text-gray-900 mb-2" data-i18n="dash_biz2_title">美国本土卡</h3>
<p class="text-sm text-gray-500 mb-6" data-i18n="dash_biz2_desc">港口提柜 · 仓到仓 · 仓到门</p>
<span class="inline-flex items-center text-brand-green font-semibold text-sm">
<span data-i18n="dash_start">开始下单</span><i class="fas fa-arrow-right ml-2"></i>
</span>
</div>
<div class="dash-card p-6" onclick="openOrder('Pallet')">
<div class="w-14 h-14 rounded-2xl bg-gradient-to-br from-brand-teal to-cyan-700 flex items-center justify-center text-white text-2xl mb-6">
<i class="fas fa-pallet"></i>
</div>
<h3 class="text-xl font-bold text-gray-900 mb-2" data-i18n="dash_biz3_title">美本土散板</h3>
<p class="text-sm text-gray-500 mb-6" data-i18n="dash_biz3_desc">拼车拼载 · 打盘服务 · 灵活派送</p>
<span class="inline-flex items-center text-brand-teal font-semibold text-sm">
<span data-i18n="dash_start">开始下单</span><i class="fas fa-arrow-right ml-2"></i>
</span>
</div>
</div>
</div>
<!-- 视图2:海外采购下单 -->
<div id="dashViewProcurement" class="dash-view hidden">
<section class="sea-business-page" id="sea-procurement-page" data-business="Procurement"><div class="sea-page-header"><div><h1>海外采购</h1><p>查询并管理海外采购头程订单</p></div><button class="btn-primary text-white font-bold px-6 py-3 rounded-xl" type="button" onclick="openSeaBusiness('Procurement','new',this)">新增下单</button></div><div class="sea-order-filters"><input data-filter="orderNo" placeholder="订单号"><input data-filter="customer" placeholder="客户/联系人"><select data-filter="status"><option value="">全部状态</option><option>待确认</option><option>处理中</option><option>已完成</option></select><div class="sea-filter-actions"><button class="btn-primary text-white font-semibold px-5 py-2 rounded-lg" type="button" onclick="querySeaOrders('Procurement')">查询</button><button class="px-5 py-2 rounded-lg border border-gray-200 text-gray-600" type="button" onclick="resetSeaOrders('Procurement')">重置</button></div></div><div class="sea-order-table-wrap"><table class="sea-order-table"><thead><tr><th>订单号</th><th>采购品类</th><th>商品规格</th><th>采购数量</th><th>预算单价</th><th>状态</th><th>操作</th></tr></thead><tbody id="sea-procurement-orders-body"></tbody></table></div></section>
<section class="sea-business-detail-page" id="sea-procurement-detail" data-business-detail="Procurement" hidden><div class="procurement-detail-header"><div class="procurement-detail-heading"><h1>海外采购订单详情</h1><p>订单号:<span data-detail-content="orderNo">-</span></p></div><button type="button" class="btn btn-default" onclick="showSeaBusinessPage('Procurement')"><i class="fas fa-arrow-left mr-2"></i>返回</button></div><div class="procurement-detail-grid"><div class="procurement-detail-card is-product"><h3>商品信息</h3><dl><div class="detail-field"><dt>采购品类</dt><dd data-detail-content="采购品类">-</dd></div><div class="detail-field"><dt>商品规格</dt><dd data-detail-content="商品规格">-</dd></div><div class="detail-field"><dt>商品链接</dt><dd data-detail-content="商品链接">-</dd></div></dl></div><div class="procurement-detail-card"><h3>订单信息</h3><dl><div class="detail-field"><dt>订单号</dt><dd data-detail-content="orderNo">-</dd></div><div class="detail-field"><dt>采购数量</dt><dd data-detail-content="采购数量">-</dd></div><div class="detail-field"><dt>预算单价</dt><dd data-detail-content="预算单价($)">-</dd></div><div class="detail-field"><dt>预算总价</dt><dd data-detail-content="预算总价">-</dd></div><div class="detail-field"><dt>订单状态</dt><dd data-detail-content="status">-</dd></div><div class="detail-field"><dt>联系人</dt><dd data-detail-content="联系人">-</dd></div><div class="detail-field"><dt>联系电话</dt><dd data-detail-content="联系电话">-</dd></div><div class="detail-field"><dt>收货地址</dt><dd data-detail-content="收货地址">-</dd></div><div class="detail-field"><dt>订单备注</dt><dd data-detail-content="订单备注">-</dd></div></dl></div><div class="procurement-detail-card"><h3>快递信息</h3><dl><div class="detail-field"><dt>国内快递公司</dt><dd data-detail-content="国内快递公司">-</dd></div><div class="detail-field"><dt>国内运单号</dt><dd data-detail-content="国内运单号">-</dd></div><div class="detail-field"><dt>海外快递公司</dt><dd data-detail-content="海外快递公司">-</dd></div><div class="detail-field"><dt>海外运单号</dt><dd data-detail-content="海外运单号">-</dd></div></dl></div></div></section>
<div class="sea-business-form-panel" data-order-panel="Procurement" hidden>
<button onclick="showSeaBusinessPage('Procurement')" class="inline-flex items-center text-gray-500 hover:text-brand-blue mb-6 text-sm font-medium">
<i class="fas fa-arrow-left mr-2"></i><span data-i18n="dash_back">返回业务选择</span>
</button>
<div class="bg-white rounded-2xl shadow-card border border-gray-100 p-6 lg:p-8 w-full">
<div class="flex items-center space-x-3 mb-8">
<div class="w-11 h-11 rounded-xl bg-gradient-to-br from-brand-blue to-brand-blueDark flex items-center justify-center text-white text-lg"><i class="fas fa-shopping-cart"></i></div>
<h2 class="text-2xl font-bold text-gray-900" data-i18n="po_title">海外采购下单</h2>
</div>
<form class="order-form space-y-4" data-order="海外采购 Overseas Sourcing" data-order-form="Procurement">
<div class="grid sm:grid-cols-2 gap-5">
<div>
<label class="dash-label"><span data-i18n="po_category">采购品类</span><span class="req">*</span></label>
<input type="text" name="采购品类" required class="dash-form-input" placeholder="如:家居用品 / 3C 配件" data-i18n-ph="po_category_ph">
</div>
<div>
<label class="dash-label"><span data-i18n="po_spec">商品规格</span></label>
<input type="text" name="商品规格" class="dash-form-input" placeholder="如:尺寸 / 颜色 / 材质" data-i18n-ph="po_spec_ph">
</div>
</div>
<div>
<label class="dash-label"><span data-i18n="po_link">商品链接</span></label>
<input type="url" name="商品链接" class="dash-form-input" placeholder="https://" data-i18n-ph="po_link_ph">
</div>
<div class="grid sm:grid-cols-2 gap-5">
<div>
<label class="dash-label"><span data-i18n="po_qty">采购数量</span><span class="req">*</span></label>
<input type="number" min="1" name="采购数量" required class="dash-form-input" placeholder="0" data-i18n-ph="po_qty_ph">
</div>
<div>
<label class="dash-label"><span data-i18n="po_price">预算单价</span></label>
<div class="relative">
<span class="absolute left-4 top-1/2 -translate-y-1/2 text-gray-400 font-medium">$</span>
<input type="number" min="0" step="0.01" name="预算单价($)" class="dash-form-input pl-8" placeholder="0.00" data-i18n-ph="po_price_ph">
</div>
</div>
</div>
<div>
<label class="dash-label"><span data-i18n="po_address">收货地址</span></label>
<input type="text" name="收货地址" class="dash-form-input" placeholder="请输入收货地址" data-i18n-ph="po_address_ph">
</div>
<div class="grid sm:grid-cols-2 gap-5">
<div>
<label class="dash-label"><span data-i18n="po_contact">联系人</span><span class="req">*</span></label>
<input type="text" name="联系人" required class="dash-form-input" placeholder="请输入联系人姓名" data-i18n-ph="po_contact_ph">
</div>
<div>
<label class="dash-label"><span data-i18n="po_phone">联系电话</span><span class="req">*</span></label>
<input type="tel" name="联系电话" required class="dash-form-input" placeholder="请输入联系电话" data-i18n-ph="po_phone_ph">
</div>
</div>
<div>
<label class="dash-label"><span data-i18n="po_note">订单备注</span></label>
<textarea name="订单备注" rows="3" class="dash-form-input" placeholder="其他需求说明(选填)" data-i18n-ph="po_note_ph"></textarea>
</div>
<div class="flex gap-3 pt-2">
<button type="submit" class="btn-primary text-white font-bold px-8 py-3.5 rounded-xl" data-i18n="dash_submit">提交订单</button>
<button type="button" onclick="showSeaBusinessPage('Procurement')" class="px-8 py-3.5 rounded-xl border border-gray-200 text-gray-600 font-medium hover:bg-gray-50" data-i18n="dash_cancel">取消</button>
</div>
</form>
</div></div>
</div>
<!-- 视图3:美国本土卡下单 -->
<div id="dashViewTruck" class="dash-view hidden">
<section class="sea-business-page" id="sea-truck-page" data-business="Truck"><div class="sea-page-header"><div><h1>美国本土卡</h1><p>查询并管理美国本土卡头程订单</p></div><button class="btn-primary text-white font-bold px-6 py-3 rounded-xl" type="button" onclick="openSeaBusiness('Truck','new',this)">新增下单</button></div><div class="sea-order-filters"><input data-filter="orderNo" placeholder="订单编号"><input data-filter="route" placeholder="起运地/目的地"><select data-filter="status"><option value="">全部状态</option><option>待确认</option><option>处理中</option><option>已完成</option></select><div class="sea-filter-actions"><button class="btn-primary text-white font-semibold px-5 py-2 rounded-lg" type="button" onclick="querySeaOrders('Truck')">查询</button><button class="px-5 py-2 rounded-lg border border-gray-200 text-gray-600" type="button" onclick="resetSeaOrders('Truck')">重置</button></div></div><div class="sea-order-table-wrap"><table class="sea-order-table"><thead><tr><th>操作</th><th>订单编号</th><th>运输类型</th><th>起运地</th><th>目的地</th><th>柜型</th><th>总重量(kg)</th><th>预算总价</th><th>要求时间</th><th>状态</th></tr></thead><tbody id="sea-truck-orders-body"></tbody></table></div></section>
<section class="sea-business-detail-page" id="sea-truck-detail" data-business-detail="Truck" hidden><div class="sea-page-header"><div><h1>美国本土卡订单详情</h1><p data-detail-content="orderNo">-</p></div><button type="button" class="px-5 py-2 rounded-lg border border-gray-200 text-gray-600" onclick="showSeaBusinessPage('Truck')"><i class="fas fa-arrow-left mr-2"></i>返回列表</button></div><div class="sea-detail-grid"><div class="sea-detail-section"><h3>运输信息</h3><dl><dt>运输类型</dt><dd data-detail-content="运输类型">-</dd><dt>起运地</dt><dd data-detail-content="起运地">-</dd><dt>目的地</dt><dd data-detail-content="目的地">-</dd><dt>要求时间</dt><dd data-detail-content="要求时间">-</dd></dl></div><div class="sea-detail-section"><h3>货物信息</h3><dl><dt>柜型</dt><dd data-detail-content="柜型">-</dd><dt>件数</dt><dd data-detail-content="件数">-</dd><dt>总重量(kg)</dt><dd data-detail-content="总重量(kg)">-</dd><dt>总体积(m³)</dt><dd data-detail-content="总体积(m³)">-</dd></dl></div><div class="sea-detail-section"><h3>承运商信息</h3><dl><dt>联系人</dt><dd data-detail-content="联系人">-</dd><dt>联系方式</dt><dd data-detail-content="联系方式">-</dd><dt>承运商</dt><dd data-detail-content="carrier">待分配</dd></dl></div><div class="sea-detail-section"><h3>运输进度</h3><div class="sea-progress-track"><div class="sea-progress-step is-current"><span>1</span><b>待确认</b></div><div class="sea-progress-step"><span>2</span><b>运输中</b></div><div class="sea-progress-step"><span>3</span><b>已完成</b></div></div><p class="text-sm text-gray-500 mt-4">当前状态:<strong data-detail-content="status">-</strong></p></div></div></section>
<div class="sea-business-form-panel" data-order-panel="Truck" hidden>
<button onclick="showSeaBusinessPage('Truck')" class="inline-flex items-center text-gray-500 hover:text-brand-blue mb-6 text-sm font-medium">
<i class="fas fa-arrow-left mr-2"></i><span data-i18n="dash_back">返回业务选择</span>
</button>
<div class="bg-white rounded-2xl shadow-card border border-gray-100 p-6 lg:p-8 w-full">
<div class="flex items-center space-x-3 mb-8">
<div class="w-11 h-11 rounded-xl bg-gradient-to-br from-brand-green to-brand-greenDark flex items-center justify-center text-white text-lg"><i class="fas fa-truck-moving"></i></div>
<h2 class="text-2xl font-bold text-gray-900" data-i18n="tk_title">美国本土卡下单</h2>
</div>
<form class="order-form space-y-6" data-order="美国本土卡 US Trucking" data-order-form="Truck">
<div>
<label class="dash-label"><span data-i18n="ts_type">运输类型</span><span class="req">*</span></label>
<div class="flex flex-wrap gap-3">
<label><input type="radio" name="运输类型" value="港口提柜" class="seg-input" checked><span class="seg-pill"><i class="fas fa-anchor text-xs"></i><span data-i18n="ts_type_port">港口提柜</span></span></label>
<label><input type="radio" name="运输类型" value="仓到仓" class="seg-input"><span class="seg-pill"><i class="fas fa-warehouse text-xs"></i><span data-i18n="ts_type_w2w">仓到仓</span></span></label>
<label><input type="radio" name="运输类型" value="仓到门" class="seg-input"><span class="seg-pill"><i class="fas fa-door-open text-xs"></i><span data-i18n="ts_type_w2d">仓到门</span></span></label>
</div>
</div>
<div class="grid sm:grid-cols-2 gap-5">
<div>
<label class="dash-label"><span data-i18n="ts_origin">起运地</span><span class="req">*</span></label>
<input type="text" name="起运地" required class="dash-form-input" placeholder="城市 / 港口 / 州" data-i18n-ph="ts_origin_ph">
</div>
<div>
<label class="dash-label"><span data-i18n="ts_dest">目的地</span><span class="req">*</span></label>
<input type="text" name="目的地" required class="dash-form-input" placeholder="城市 / 州" data-i18n-ph="ts_dest_ph">
</div>
<div>
<label class="dash-label"><span data-i18n="ts_origin_addr">详细地址</span></label>
<input type="text" name="起运详细地址" class="dash-form-input" placeholder="街道 / 门牌" data-i18n-ph="ts_origin_addr_ph">
</div>
<div>
<label class="dash-label"><span data-i18n="ts_dest_addr">详细地址 / 码头 / 仓号</span></label>
<input type="text" name="目的详细地址/码头/仓号" class="dash-form-input" placeholder="地址 / 码头 / 仓号" data-i18n-ph="ts_dest_addr_ph">
</div>
</div>
<div>
<label class="dash-label mb-3"><i class="fas fa-box mr-1 text-gray-400"></i><span data-i18n="cargo_title">货物信息</span></label>
<div class="grid sm:grid-cols-2 lg:grid-cols-4 gap-4">
<div>
<label class="text-xs text-gray-500 mb-1 block" data-i18n="cargo_container">柜型</label>
<select name="柜型" class="dash-form-input">
<option value="20GP">20GP</option>
<option value="40GP">40GP</option>
<option value="40HQ">40HQ</option>
<option value="45HQ">45HQ</option>
<option value="LTL" data-i18n="cargo_container_ltl">散货/托盘</option>
</select>
</div>
<div>
<label class="text-xs text-gray-500 mb-1 block" data-i18n="cargo_pieces">件数</label>
<input type="number" min="0" name="件数" class="dash-form-input" placeholder="0">
</div>
<div>
<label class="text-xs text-gray-500 mb-1 block" data-i18n="cargo_weight">总重量 (kg)</label>
<input type="number" min="0" step="0.01" name="总重量(kg)" class="dash-form-input" placeholder="0">
</div>
<div>
<label class="text-xs text-gray-500 mb-1 block" data-i18n="cargo_volume">总体积 (m³)</label>
<input type="number" min="0" step="0.01" name="总体积(m³)" class="dash-form-input" placeholder="0">
</div>
</div>
</div>
<div class="max-w-xs"><label class="dash-label">预算总价</label><div class="relative"><span class="absolute left-4 top-1/2 -translate-y-1/2 text-gray-400 font-medium">$</span><input type="number" min="0" step="0.01" name="预算总价" class="dash-form-input pl-8" placeholder="0.00"></div></div>
<div>
<label class="dash-label mb-3"><i class="fas fa-user mr-1 text-gray-400"></i><span data-i18n="contact_title">联系人信息</span></label>
<div class="grid sm:grid-cols-2 gap-5">
<div>
<label class="dash-label"><span data-i18n="contact_name">联系人</span><span class="req">*</span></label>
<input type="text" name="联系人" required class="dash-form-input" placeholder="请输入联系人姓名" data-i18n-ph="contact_name_ph">
</div>
<div>
<label class="dash-label"><span data-i18n="contact_phone">联系方式</span><span class="req">*</span></label>
<input type="text" name="联系方式" required class="dash-form-input" placeholder="电话 / 微信 / 邮箱" data-i18n-ph="contact_phone_ph">
</div>
</div>
</div>
<div class="max-w-xs">
<label class="dash-label"><span data-i18n="req_time">要求时间</span></label>
<input type="date" name="要求时间" class="dash-form-input">
</div>
<div class="flex gap-3 pt-2">
<button type="submit" class="btn-primary text-white font-bold px-8 py-3.5 rounded-xl" data-i18n="dash_submit">提交订单</button>
<button type="button" onclick="showSeaBusinessPage('Truck')" class="px-8 py-3.5 rounded-xl border border-gray-200 text-gray-600 font-medium hover:bg-gray-50" data-i18n="dash_cancel">取消</button>
</div>
</form>
</div></div>
</div>
<!-- 视图4:美本土散板下单 -->
<div id="dashViewPallet" class="dash-view hidden">
<section class="sea-business-page" id="sea-pallet-page" data-business="Pallet"><div class="sea-page-header"><div><h1>美本土散板</h1><p>查询并管理美本土散板头程订单</p></div><button class="btn-primary text-white font-bold px-6 py-3 rounded-xl" type="button" onclick="openSeaBusiness('Pallet','new',this)">新增下单</button></div><div class="sea-order-filters"><input data-filter="orderNo" placeholder="订单编号"><input data-filter="route" placeholder="起运地/目的地"><select data-filter="status"><option value="">全部状态</option><option>待确认</option><option>处理中</option><option>已完成</option></select><div class="sea-filter-actions"><button class="btn-primary text-white font-semibold px-5 py-2 rounded-lg" type="button" onclick="querySeaOrders('Pallet')">查询</button><button class="px-5 py-2 rounded-lg border border-gray-200 text-gray-600" type="button" onclick="resetSeaOrders('Pallet')">重置</button></div></div><div class="sea-order-table-wrap"><table class="sea-order-table"><thead><tr><th>操作</th><th>订单编号</th><th>运输方式</th><th>是否打盘</th><th>运输类型</th><th>起运地</th><th>目的地</th><th>总重量(kg)</th><th>预算总价</th><th>要求时间</th><th>状态</th></tr></thead><tbody id="sea-pallet-orders-body"></tbody></table></div></section>
<section class="sea-business-detail-page" id="sea-pallet-detail" data-business-detail="Pallet" hidden><div class="sea-page-header"><div><h1>美本土散板订单详情</h1><p data-detail-content="orderNo">-</p></div><button type="button" class="px-5 py-2 rounded-lg border border-gray-200 text-gray-600" onclick="showSeaBusinessPage('Pallet')"><i class="fas fa-arrow-left mr-2"></i>返回列表</button></div><div class="sea-detail-grid"><div class="sea-detail-section"><h3>运输信息</h3><dl><dt>运输方式</dt><dd data-detail-content="运输方式">-</dd><dt>是否打盘</dt><dd data-detail-content="是否打盘">-</dd><dt>起运地</dt><dd data-detail-content="起运地">-</dd><dt>目的地</dt><dd data-detail-content="目的地">-</dd></dl></div><div class="sea-detail-section"><h3>货物信息</h3><dl><dt>柜型</dt><dd data-detail-content="柜型">-</dd><dt>件数</dt><dd data-detail-content="件数">-</dd><dt>总重量(kg)</dt><dd data-detail-content="总重量(kg)">-</dd><dt>总体积(m³)</dt><dd data-detail-content="总体积(m³)">-</dd></dl></div><div class="sea-detail-section"><h3>承运商信息</h3><dl><dt>联系人</dt><dd data-detail-content="联系人">-</dd><dt>联系方式</dt><dd data-detail-content="联系方式">-</dd><dt>承运商</dt><dd data-detail-content="carrier">待分配</dd></dl></div><div class="sea-detail-section"><h3>运输进度</h3><div class="sea-progress-track"><div class="sea-progress-step is-current"><span>1</span><b>待确认</b></div><div class="sea-progress-step"><span>2</span><b>运输中</b></div><div class="sea-progress-step"><span>3</span><b>已完成</b></div></div><p class="text-sm text-gray-500 mt-4">当前状态:<strong data-detail-content="status">-</strong></p></div></div></section>
<div class="sea-business-form-panel" data-order-panel="Pallet" hidden>
<button onclick="showSeaBusinessPage('Pallet')" class="inline-flex items-center text-gray-500 hover:text-brand-blue mb-6 text-sm font-medium">
<i class="fas fa-arrow-left mr-2"></i><span data-i18n="dash_back">返回业务选择</span>
</button>
<div class="bg-white rounded-2xl shadow-card border border-gray-100 p-6 lg:p-8 w-full">
<div class="flex items-center space-x-3 mb-8">
<div class="w-11 h-11 rounded-xl bg-gradient-to-br from-brand-teal to-cyan-700 flex items-center justify-center text-white text-lg"><i class="fas fa-pallet"></i></div>
<h2 class="text-2xl font-bold text-gray-900" data-i18n="pl_title">美本土散板下单</h2>
</div>
<form class="order-form space-y-6" data-order="美本土散板 US Pallet" data-order-form="Pallet">
<div class="grid sm:grid-cols-2 gap-5">
<div>
<label class="dash-label"><span data-i18n="pl_method">运输方式</span><span class="req">*</span></label>
<div class="flex flex-wrap gap-3">
<label><input type="radio" name="运输方式" value="拼车" class="seg-input" checked><span class="seg-pill"><span data-i18n="pl_method_pool">拼车</span></span></label>
<label><input type="radio" name="运输方式" value="优先拼载" class="seg-input"><span class="seg-pill"><span data-i18n="pl_method_priority">优先拼载</span></span></label>
</div>
</div>
<div>
<label class="dash-label"><span data-i18n="pl_palletize">是否打盘</span><span class="req">*</span></label>
<div class="flex flex-wrap gap-3">
<label><input type="radio" name="是否打盘" value="是" class="seg-input" checked><span class="seg-pill"><span data-i18n="pl_yes">是</span></span></label>
<label><input type="radio" name="是否打盘" value="否" class="seg-input"><span class="seg-pill"><span data-i18n="pl_no">否</span></span></label>
</div>
</div>
</div>
<div>
<label class="dash-label"><span data-i18n="ts_type">运输类型</span><span class="req">*</span></label>
<div class="flex flex-wrap gap-3">
<label><input type="radio" name="运输类型" value="港口提柜" class="seg-input" checked><span class="seg-pill"><i class="fas fa-anchor text-xs"></i><span data-i18n="ts_type_port">港口提柜</span></span></label>
<label><input type="radio" name="运输类型" value="仓到仓" class="seg-input"><span class="seg-pill"><i class="fas fa-warehouse text-xs"></i><span data-i18n="ts_type_w2w">仓到仓</span></span></label>
<label><input type="radio" name="运输类型" value="仓到门" class="seg-input"><span class="seg-pill"><i class="fas fa-door-open text-xs"></i><span data-i18n="ts_type_w2d">仓到门</span></span></label>
</div>
</div>
<div class="grid sm:grid-cols-2 gap-5">
<div>
<label class="dash-label"><span data-i18n="ts_origin">起运地</span><span class="req">*</span></label>
<input type="text" name="起运地" required class="dash-form-input" placeholder="城市 / 港口 / 州" data-i18n-ph="ts_origin_ph">
</div>
<div>
<label class="dash-label"><span data-i18n="ts_dest">目的地</span><span class="req">*</span></label>
<input type="text" name="目的地" required class="dash-form-input" placeholder="城市 / 州" data-i18n-ph="ts_dest_ph">
</div>
<div>
<label class="dash-label"><span data-i18n="ts_origin_addr">详细地址</span></label>
<input type="text" name="起运详细地址" class="dash-form-input" placeholder="街道 / 门牌" data-i18n-ph="ts_origin_addr_ph">
</div>
<div>
<label class="dash-label"><span data-i18n="ts_dest_addr">详细地址 / 码头 / 仓号</span></label>
<input type="text" name="目的详细地址/码头/仓号" class="dash-form-input" placeholder="地址 / 码头 / 仓号" data-i18n-ph="ts_dest_addr_ph">
</div>
</div>
<div>
<label class="dash-label mb-3"><i class="fas fa-box mr-1 text-gray-400"></i><span data-i18n="cargo_title">货物信息</span></label>
<div class="grid sm:grid-cols-2 lg:grid-cols-4 gap-4">
<div>
<label class="text-xs text-gray-500 mb-1 block" data-i18n="cargo_container">柜型</label>
<select name="柜型" class="dash-form-input">
<option value="20GP">20GP</option>
<option value="40GP">40GP</option>
<option value="40HQ">40HQ</option>
<option value="45HQ">45HQ</option>
<option value="LTL" data-i18n="cargo_container_ltl">散货/托盘</option>
</select>
</div>
<div>
<label class="text-xs text-gray-500 mb-1 block" data-i18n="cargo_pieces">件数</label>
<input type="number" min="0" name="件数" class="dash-form-input" placeholder="0">
</div>
<div>
<label class="text-xs text-gray-500 mb-1 block" data-i18n="cargo_weight">总重量 (kg)</label>
<input type="number" min="0" step="0.01" name="总重量(kg)" class="dash-form-input" placeholder="0">
</div>
<div>
<label class="text-xs text-gray-500 mb-1 block" data-i18n="cargo_volume">总体积 (m³)</label>
<input type="number" min="0" step="0.01" name="总体积(m³)" class="dash-form-input" placeholder="0">
</div>
</div>
</div>
<div class="max-w-xs"><label class="dash-label">预算总价</label><div class="relative"><span class="absolute left-4 top-1/2 -translate-y-1/2 text-gray-400 font-medium">$</span><input type="number" min="0" step="0.01" name="预算总价" class="dash-form-input pl-8" placeholder="0.00"></div></div>
<div>
<label class="dash-label mb-3"><i class="fas fa-user mr-1 text-gray-400"></i><span data-i18n="contact_title">联系人信息</span></label>
<div class="grid sm:grid-cols-2 gap-5">
<div>
<label class="dash-label"><span data-i18n="contact_name">联系人</span><span class="req">*</span></label>
<input type="text" name="联系人" required class="dash-form-input" placeholder="请输入联系人姓名" data-i18n-ph="contact_name_ph">
</div>
<div>
<label class="dash-label"><span data-i18n="contact_phone">联系方式</span><span class="req">*</span></label>
<input type="text" name="联系方式" required class="dash-form-input" placeholder="电话 / 微信 / 邮箱" data-i18n-ph="contact_phone_ph">
</div>
</div>
</div>
<div class="max-w-xs">
<label class="dash-label"><span data-i18n="req_time">要求时间</span></label>
<input type="date" name="要求时间" class="dash-form-input">
</div>
<div class="flex gap-3 pt-2">
<button type="submit" class="btn-primary text-white font-bold px-8 py-3.5 rounded-xl" data-i18n="dash_submit">提交订单</button>
<button type="button" onclick="showSeaBusinessPage('Pallet')" class="px-8 py-3.5 rounded-xl border border-gray-200 text-gray-600 font-medium hover:bg-gray-50" data-i18n="dash_cancel">取消</button>
</div>
</form>
</div></div>
</div>
<!-- 视图5:我的订单 -->
<div id="dashViewOrders" class="dash-view hidden">
<div class="bg-white rounded-2xl shadow-card border border-gray-100 p-10 lg:p-14 max-w-3xl mx-auto text-center">
<div class="dash-empty">
<i class="fas fa-clipboard-list"></i>
<h3 class="text-xl font-bold text-gray-700 mb-2" data-i18n="dash_orders_empty">暂无订单</h3>
<p class="text-gray-500" data-i18n="dash_orders_hint">您还没有提交任何订单,前往「业务总览」选择服务开始下单吧。</p>
</div>
</div>
</div>
<!-- 视图6:柏悦客户端全部页面(已并入,统一作用域 .client-shell) -->
<div id="dashViewClient" class="dash-view hidden client-shell">
<div class="page-content active" id="page-order">
<div class="page-header">
<div>
<div class="page-title">头程下单</div>
<div class="page-subtitle">填写货物信息,创建新的头程运输订单</div>
</div>
</div>
<!-- SECTION 1: 基本信息 -->
<div class="card">
<div class="card-header" style="flex-direction:column;align-items:flex-start;">
<div class="card-title">客户下单</div>
<div class="card-subtitle">创建新订单</div>
</div>
<div class="card-body">
<div class="form-group">
<div class="form-label"><span class="required">*</span>取货方式</div>
<div class="form-content">
<div class="dest-type-tabs" id="pickup-tabs">
<button class="dest-tab active" onclick="setPickupTab(this,'express')">自送货-快递</button>
<button class="dest-tab" onclick="setPickupTab(this,'pickup')">我司提货(有取货费)</button>
<button class="dest-tab" onclick="setPickupTab(this,'truck')">自送货-卡车</button>
</div>
</div>
</div>
<!-- 自送货-快递 -->
<div class="dest-content active" id="pickup-express">
<div class="form-group">
<div class="form-label">预计送达时间</div>
<div class="form-content">
<input type="datetime-local" class="form-input" placeholder="请选择预计送达时间" style="min-width:280px;">
</div>
</div>
<div class="form-group">
<div class="form-label">快递单号</div>
<div class="form-content">
<input type="text" class="form-input" placeholder="请输入快递单号" style="min-width:300px;">
</div>
</div>
</div>
<!-- 我司提货 -->
<div class="dest-content" id="pickup-pickup">
<div class="form-group">
<div class="form-label"><span class="required">*</span>提货地址</div>
<div class="form-content">
<textarea class="form-input" placeholder="请输入提货详细地址" style="min-width:400px;height:80px;"></textarea>
</div>
</div>
<div class="form-group">
<div class="form-label"><span class="required">*</span>提货时间</div>
<div class="form-content">
<input type="datetime-local" class="form-input" placeholder="请选择提货时间" style="min-width:280px;">
</div>
</div>
<div class="form-group">
<div class="form-label">联系人</div>
<div class="form-content">
<input type="text" class="form-input" placeholder="请输入联系人姓名" style="min-width:280px;">
</div>
</div>
<div class="form-group">
<div class="form-label">联系电话</div>
<div class="form-content">
<input type="tel" class="form-input" placeholder="请输入联系电话" style="min-width:280px;">
</div>
</div>
<div class="form-group">
<div class="form-label">提货备注</div>
<div class="form-content">
<input type="text" class="form-input" placeholder="如:小区门禁、特殊要求等" style="min-width:300px;">
</div>
</div>
</div>
<!-- 自送货-卡车 -->
<div class="dest-content" id="pickup-truck">
<div class="form-group">
<div class="form-label"><span class="required">*</span>预计到达时间</div>
<div class="form-content">
<input type="datetime-local" class="form-input" placeholder="请选择预计到达时间" style="min-width:280px;">
</div>
</div>
<div class="form-group">
<div class="form-label">车牌号</div>
<div class="form-content">
<input type="text" class="form-input" placeholder="请输入车牌号" style="min-width:200px;">
</div>
</div>
<div class="form-group">
<div class="form-label">司机姓名</div>
<div class="form-content">
<input type="text" class="form-input" placeholder="请输入司机姓名" style="min-width:200px;">
</div>
</div>
<div class="form-group">
<div class="form-label">司机电话</div>
<div class="form-content">
<input type="tel" class="form-input" placeholder="请输入司机电话" style="min-width:200px;">
</div>
</div>
</div>
<div class="form-group">
<div class="form-label"><span class="required">*</span>收货仓</div>
<div class="form-content">
<label class="radio-label"><input type="radio" name="warehouse"> 义乌仓</label>
<label class="radio-label"><input type="radio" name="warehouse"> 深圳仓</label>
<label class="radio-label"><input type="radio" name="warehouse"> 青岛仓</label>
<label class="radio-label"><input type="radio" name="warehouse"> 上海仓</label>
<label class="radio-label"><input type="radio" name="warehouse"> 宁波仓</label>
<label class="radio-label"><input type="radio" name="warehouse"> 厦门仓</label>
</div>
</div>
<div class="form-group">
<div class="form-label"><span class="required">*</span>渠道</div>
<div class="form-content">
<div class="select-wrap">
<select class="form-select">
<option value="">请选择</option>
<option>美线普货专线</option>
<option>美线敏感货专线</option>
<option>美线快线</option>
<option>美线FBA直送</option>
</select>
</div>
</div>
</div>
<div class="form-group">
<div class="form-label"><span class="required">*</span>买单/退税</div>
<div class="form-content">
<label class="radio-label"><input type="radio" name="tax"> 买单</label>
<label class="radio-label"><input type="radio" name="tax"> 退税</label>
</div>
</div>
<div class="form-group">
<div class="form-label">是否整柜</div>
<div class="form-content">
<label class="radio-label"><input type="radio" name="container"> 整柜</label>
<label class="radio-label"><input type="radio" name="container"> 散货</label>
</div>
</div>
<div class="form-group">
<div class="form-label"><span class="required">*</span>是否商检</div>
<div class="form-content">
<label class="radio-label"><input type="radio" name="inspection"> 是</label>
<label class="radio-label"><input type="radio" name="inspection"> 否</label>
</div>
</div>
<div class="form-group">
<div class="form-label">船期</div>
<div class="form-content">
<div class="date-range">
<div class="input-wrap"><input type="date" class="form-input" placeholder="开船时间"></div>
<div class="input-wrap"><input type="date" class="form-input" placeholder="到港时间"></div>
</div>
</div>
</div>
<div class="form-group" style="align-items:flex-start;">
<div class="form-label" style="padding-top:6px;">备注NOTE</div>
<div class="form-content">
<textarea class="form-textarea" placeholder="请填写订单备注信息(选填)"></textarea>
</div>
</div>
</div>
</div>
<!-- SECTION 2: 目的地信息 -->
<div class="card">
<div class="card-header" style="flex-direction:column;align-items:flex-start;">
<div class="card-title">目的地信息</div>
</div>
<div class="card-body">
<div class="form-group">
<div class="form-label">目的仓类型</div>
<div class="form-content">
<div class="dest-type-tabs" id="dest-tabs">
<button class="dest-tab active" onclick="setDestTab(this,'fba')">FBA仓</button>
<button class="dest-tab" onclick="setDestTab(this,'overseas')">海外仓</button>
<button class="dest-tab" onclick="setDestTab(this,'private')">私人仓</button>
</div>
</div>
</div>
<!-- FBA仓 -->
<div class="dest-content active" id="dest-fba">
<div class="form-group"><div class="form-label"><span class="required">*</span>亚马逊仓代码</div><div class="form-content"><div class="input-wrap"><input type="text" class="form-input" placeholder="请输入亚马逊仓代码,如 ONT8、LAX9" style="min-width:280px;padding-right:48px;"><span style="position:absolute;right:10px;font-size:11px;color:#bfbfbf;">搜索</span></div></div></div>
<div class="form-group"><div class="form-label">收件人姓名</div><div class="form-content"><input type="text" class="form-input" placeholder="请输入收件人姓名" style="min-width:280px;"></div></div>
<div class="form-group"><div class="form-label">收件人电话</div><div class="form-content"><input type="text" class="form-input" placeholder="请输入收件人电话" style="min-width:280px;"></div></div>
<div class="form-group"><div class="form-label">收件地址</div><div class="form-content"><input type="text" class="form-input" placeholder="请输入收件地址" style="min-width:400px;"></div></div>
<div class="form-group"><div class="form-label">货件编号</div><div class="form-content"><input type="text" class="form-input" placeholder="Shipment ID" style="min-width:280px;"></div></div>
<div class="form-group"><div class="form-label">跟踪编号</div><div class="form-content"><input type="text" class="form-input" placeholder="Reference ID" style="min-width:280px;"></div></div>
<div class="form-group"><div class="form-label">期望到达时间</div><div class="form-content"><input type="date" class="form-input" placeholder="请选择期望到达时间" style="min-width:200px;"></div></div>
<div class="form-group"><div class="form-label"></div><div class="form-content"><button class="btn btn-ghost" onclick="alert('查看最新报价')">💰 查看最新报价</button></div></div>
</div>
<!-- 海外仓 -->
<div class="dest-content" id="dest-overseas">
<div class="form-group"><div class="form-label"><span class="required">*</span>海外仓</div><div class="form-content"><div class="select-wrap"><select class="form-select" style="min-width:280px;"><option value="">请选择海外仓</option><option>美西仓 - 洛杉矶</option><option>美东仓 - 纽瓦克</option><option>美中仓 - 芝加哥</option><option>美南仓 - 达拉斯</option><option>萨凡纳仓</option></select></div></div></div>
<div class="form-group"><div class="form-label"><span class="required">*</span>收件人姓名</div><div class="form-content"><input type="text" class="form-input" placeholder="请输入收件人姓名" style="min-width:280px;"></div></div>
<div class="form-group"><div class="form-label"><span class="required">*</span>收件人电话</div><div class="form-content"><input type="text" class="form-input" placeholder="请输入收件人电话" style="min-width:280px;"></div></div>
<div class="form-group"><div class="form-label"><span class="required">*</span>收件国家</div><div class="form-content"><div class="select-wrap"><select class="form-select" style="min-width:280px;"><option value="">请选择国家</option><option>美国</option><option>加拿大</option><option>墨西哥</option></select></div></div></div>
<div class="form-group"><div class="form-label"><span class="required">*</span>收件地址</div><div class="form-content"><input type="text" class="form-input" placeholder="请输入收件详细地址" style="min-width:400px;"></div></div>
<div class="form-group"><div class="form-label">邮编</div><div class="form-content"><input type="text" class="form-input" placeholder="请输入邮编" style="min-width:200px;"></div></div>
<div class="form-group"><div class="form-label">期望到达时间</div><div class="form-content"><input type="date" class="form-input" placeholder="请选择期望到达时间" style="min-width:200px;"></div></div>
<div class="form-group"><div class="form-label"></div><div class="form-content"><button class="btn btn-ghost" onclick="alert('查看最新报价')">💰 查看最新报价</button></div></div>
</div>
<!-- 私人仓 -->
<div class="dest-content" id="dest-private">
<div class="form-group"><div class="form-label"><span class="required">*</span>收件人姓名</div><div class="form-content"><input type="text" class="form-input" placeholder="请输入收件人姓名" style="min-width:280px;"></div></div>
<div class="form-group"><div class="form-label"><span class="required">*</span>收件人电话</div><div class="form-content"><input type="text" class="form-input" placeholder="请输入收件人电话" style="min-width:280px;"></div></div>
<div class="form-group"><div class="form-label"><span class="required">*</span>收件国家</div><div class="form-content"><div class="select-wrap"><select class="form-select" style="min-width:280px;"><option value="">请选择国家</option><option>美国</option><option>加拿大</option><option>墨西哥</option></select></div></div></div>
<div class="form-group"><div class="form-label"><span class="required">*</span>州/省</div><div class="form-content"><input type="text" class="form-input" placeholder="请输入州/省" style="min-width:280px;"></div></div>
<div class="form-group"><div class="form-label"><span class="required">*</span>城市</div><div class="form-content"><input type="text" class="form-input" placeholder="请输入城市" style="min-width:280px;"></div></div>
<div class="form-group"><div class="form-label"><span class="required">*</span>收件地址</div><div class="form-content"><input type="text" class="form-input" placeholder="请输入收件详细地址" style="min-width:400px;"></div></div>
<div class="form-group"><div class="form-label"><span class="required">*</span>邮编</div><div class="form-content"><input type="text" class="form-input" placeholder="请输入邮编" style="min-width:200px;"></div></div>
<div class="form-group"><div class="form-label">期望到达时间</div><div class="form-content"><input type="date" class="form-input" placeholder="请选择期望到达时间" style="min-width:200px;"></div></div>
<div class="form-group"><div class="form-label"></div><div class="form-content"><button class="btn btn-ghost" onclick="alert('查看最新报价')">💰 查看最新报价</button></div></div>
</div>
</div>
</div>
<!-- SECTION 3: 货物明细 -->
<div class="card">
<div class="card-header"><div class="card-title">货物明细</div></div>
<div class="card-body">
<div class="table-toolbar">
<div class="table-actions">
<label class="upload-link"><input type="file" accept=".xlsx,.xls" style="display:none" onchange="alert('Excel已选择:'+this.files[0]?.name)"> 📤 上传 Excel</label>
<a class="download-link" href="#">⬇️ 下载模板</a>
</div>
<div class="table-actions">
<button class="btn-flat" onclick="addRow()"><svg class="icon-svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg>添加行</button>
<button class="btn-flat btn-flat-red" onclick="deleteSelectedRows()"><svg class="icon-svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="3 6 5 6 21 6"/><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/></svg>删除所选行</button>
</div>
</div>
<div class="table-wrap">
<table class="goods-table" id="goods-table">
<thead>
<tr>
<th class="col-checkbox"><input type="checkbox" id="check-all-goods" onchange="toggleAllGoods(this)"></th>
<th>#</th>
<th style="min-width:130px">SKU NO. <span style="font-size:10px;color:#faad14;">FBA必填</span></th>
<th style="min-width:90px">中文品名</th>
<th style="min-width:60px">图片</th>
<th style="min-width:130px">英文品名</th>
<th style="min-width:100px">报关 HS CODE</th>
<th style="min-width:100px">清关 HS CODE</th>
<th>箱规长 cm</th><th>箱规宽 cm</th><th>箱规高 cm</th>
<th>每箱数量</th><th>箱数</th><th>总毛重</th><th>总体积</th><th>总数量</th><th>总净重</th>
<th style="min-width:110px">清关申报单价 USD</th>
<th style="min-width:110px">清关申报金额 USD</th>
<th style="min-width:100px">材质</th><th style="min-width:100px">用途</th>
<th style="min-width:80px">型号</th><th style="min-width:80px">品牌</th>
<th style="min-width:110px">产品规格 长×宽×高</th>
<th style="min-width:130px">货件编号 <span style="font-size:10px;color:#faad14;">必填</span></th>
<th style="min-width:130px">跟踪编号 <span style="font-size:10px;color:#faad14;">必填</span></th>
<th style="min-width:120px">UPC NO. <span style="font-size:10px;color:#faad14;">FBA必填</span></th>
<th style="min-width:100px">备注</th>
</tr>
</thead>
<tbody id="goods-tbody">
<tr class="empty-row" id="empty-row">
<td colspan="28" style="text-align:center;padding:40px;color:#bfbfbf;">
<div style="font-size:32px;margin-bottom:8px;">📦</div>
<div style="font-size:13px;">暂无货物明细,请点击「添加行」或上传 Excel</div>
</td>
</tr>
</tbody>
</table>
</div>
<div style="margin-top:12px;display:flex;align-items:center;gap:16px;font-size:12px;color:#8c8c8c;">
<span>💡 FBA货物仓储/散货/快递时,SKU NO.、UPC NO. 为必填项</span>
<span>•</span>
<span>亚马逊货物,货件编号和跟踪编号为必填项</span>
</div>
</div>
</div>
<!-- SECTION 4: 费用预估 -->
<div class="card cost-estimate">
<div class="card-header"><div class="card-title">费用预估</div></div>
<div class="card-body">
<div class="cost-cards" id="cost-cards">
<div class="cost-card" onclick="selectCost(this,0)">
<span class="cost-badge fastest">最快</span>
<div class="cost-days">10天</div>
<div class="cost-price"><span>¥</span> 3,310</div>
<div class="cost-desc">优先配送,时效保障</div>
</div>
<div class="cost-card active" onclick="selectCost(this,1)">
<span class="cost-badge recommend">推荐</span>
<div class="cost-days">13天</div>
<div class="cost-price"><span>¥</span> 2,990</div>
<div class="cost-desc">性价比之选</div>
</div>
<div class="cost-card" onclick="selectCost(this,2)">
<span class="cost-badge economy">经济</span>
<div class="cost-days">16天</div>
<div class="cost-price"><span>¥</span> 2,500</div>
<div class="cost-desc">经济实惠</div>
</div>
</div>
</div>
</div>
<div class="form-footer">
<div class="footer-tips"><span class="tip-icon">⚠️</span> 提交前请确认货物信息准确无误,提交后不可修改货物明细</div>
<div style="display:flex;gap:12px;align-items:center;justify-content:center;">
<button class="btn btn-default" onclick="alert('已重置表单')">重置</button>
<button class="btn-submit" onclick="submitOrder()">✈️ 提交订单</button>
</div>
</div>
</div>
<!-- ========== PAGE 2: 入库订单列表 ========== -->
<div class="page-content" id="page-inbound">
<div class="breadcrumb"><a href="#" onclick="switchPage('order');return false;">首页</a><span class="sep">/</span><span class="current">入库订单列表</span></div>
<div class="page-title" style="margin-bottom:16px;">入库订单列表</div>
<div class="card">
<div class="card-body">
<div class="filter-grid">
<div class="filter-item"><span class="filter-label">订单号</span><input type="text" class="filter-input" placeholder="请输入订单号"></div>
<div class="filter-item"><span class="filter-label">收货仓</span><select class="filter-select"><option value="">全部</option><option>义乌仓</option><option>深圳仓</option><option>青岛仓</option><option>上海仓</option><option>宁波仓</option><option>厦门仓</option></select></div>
<div class="filter-item"><span class="filter-label">渠道名称</span><select class="filter-select"><option value="">全部</option><option>美线普货专线</option><option>美线敏感货专线</option><option>美线快线</option><option>美线FBA直送</option></select></div>
<div class="filter-item"><span class="filter-label">客户姓名/手机号</span><input type="text" class="filter-input" placeholder="请输入"></div>
<div class="filter-item span2"><span class="filter-label">创建时间</span><div class="date-range-wrap"><input type="date" class="filter-input"><span class="date-sep">~</span><input type="date" class="filter-input"></div></div>
<div class="filter-item"><span class="filter-label">付款状态</span><select class="filter-select"><option value="">全部</option><option>已付款</option><option>未付款</option><option>部分付款</option></select></div>
<div class="filter-item"><span class="filter-label">出货状态</span><select class="filter-select"><option value="">全部</option><option>已出货</option><option>未出货</option><option>出货中</option></select></div>
<div class="filter-item"><span class="filter-label">操作状态</span><select class="filter-select"><option value="">全部</option><option>待处理</option><option>处理中</option><option>已完成</option><option>已取消</option></select></div>
<div class="filter-item"><span class="filter-label">目的仓类型</span><select class="filter-select"><option value="">全部</option><option>FBA仓</option><option>海外仓</option><option>私人仓</option></select></div>
</div>
<div class="filter-actions">
<button class="btn-flat btn-flat-blue"><svg class="icon-svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></svg>下载唛头</button>
<button class="btn-flat btn-flat-blue"><svg class="icon-svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></svg>导出订单尾程信息</button>
<button class="btn-flat btn-flat-blue"><svg class="icon-svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>查询</button>
<button class="btn-flat btn-flat-blue"><svg class="icon-svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="1 4 1 10 7 10"/><path d="M3.51 15a9 9 0 1 0 2.13-9.36L1 10"/></svg>重置查询条件</button>
<button class="btn-flat btn-flat-blue"><svg class="icon-svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="1 4 1 10 7 10"/><path d="M3.51 15a9 9 0 1 0 2.13-9.36L1 10"/></svg>重置所有状态</button>
</div>
</div>
</div>
<div class="card">
<div class="table-wrap-simple">
<table class="data-table" id="inbound-table">
<thead>
<tr>
<th class="col-checkbox"><input type="checkbox" onchange="toggleAllTable('inbound-table', this)"></th>
<th>序号</th><th>操作</th><th>入仓码</th><th>渠道</th><th>目的仓</th><th>当前订单状态</th><th>箱数</th><th>快递公司</th><th>快递单号</th><th>SKUS</th><th>总毛重</th><th>总净重</th><th>总体积</th><th>总数量</th><th>计费单价</th><th>计费体积</th><th>计费重量</th><th>备注</th><th>货件编号</th><th>跟踪编号</th><th>国内仓入库时间</th><th>业务日期</th>
</tr>
</thead>
<tbody>
<tr class="empty-state"><td colspan="23"><div class="empty-icon">📦</div><div class="empty-text">暂无数据</div></td></tr>
</tbody>
</table>
</div>
<div class="pagination-bar">
<div class="pagination-info"><span>共 <strong>0</strong> 条</span><select class="page-size-select"><option>10 条/页</option><option>20 条/页</option><option>50 条/页</option><option>100 条/页</option></select></div>
<div class="pagination-ctrl"><button class="page-btn" disabled>上一页</button><button class="page-btn active">1</button><button class="page-btn" disabled>下一页</button></div>
</div>
</div>
</div>
<!-- ========== PAGE 3: 派送订单列表 ========== -->
<div class="page-content" id="page-delivery">
<div class="breadcrumb"><a href="#" onclick="switchPage('order');return false;">首页</a><span class="sep">/</span><span class="current">派送订单列表</span></div>
<div class="page-title" style="margin-bottom:16px;">派送订单列表</div>
<div class="card">
<div class="card-body">
<div class="filter-grid">
<div class="filter-item"><span class="filter-label">订单号</span><input type="text" class="filter-input" placeholder="请输入订单号"></div>
<div class="filter-item"><span class="filter-label">派送仓</span><select class="filter-select"><option value="">全部</option><option>洛杉矶仓</option><option>纽约仓</option><option>芝加哥仓</option><option>达拉斯仓</option><option>萨凡纳仓</option></select></div>
<div class="filter-item"><span class="filter-label">渠道名称</span><select class="filter-select"><option value="">全部</option><option>美线普货专线</option><option>美线敏感货专线</option><option>美线快线</option><option>美线FBA直送</option></select></div>
<div class="filter-item"><span class="filter-label">客户姓名/手机号</span><input type="text" class="filter-input" placeholder="请输入"></div>
<div class="filter-item span2"><span class="filter-label">创建时间</span><div class="date-range-wrap"><input type="date" class="filter-input"><span class="date-sep">~</span><input type="date" class="filter-input"></div></div>
<div class="filter-item"><span class="filter-label">付款状态</span><select class="filter-select"><option value="">全部</option><option>已付款</option><option>未付款</option><option>部分付款</option></select></div>
<div class="filter-item"><span class="filter-label">派送状态</span><select class="filter-select"><option value="">全部</option><option>待派送</option><option>派送中</option><option>已派送</option><option>派送失败</option></select></div>
<div class="filter-item"><span class="filter-label">操作状态</span><select class="filter-select"><option value="">全部</option><option>待处理</option><option>处理中</option><option>已完成</option><option>已取消</option></select></div>
<div class="filter-item"><span class="filter-label">目的仓类型</span><select class="filter-select"><option value="">全部</option><option>FBA仓</option><option>海外仓</option><option>私人仓</option></select></div>
</div>
<div class="filter-actions">
<button class="btn-flat btn-flat-blue"><svg class="icon-svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>查询</button>
<button class="btn-flat"><svg class="icon-svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="1 4 1 10 7 10"/><path d="M3.51 15a9 9 0 1 0 2.13-9.36L1 10"/></svg>重置</button>
</div>
</div>
</div>
<div class="card">
<div class="table-wrap-simple">
<table class="data-table" id="delivery-table">
<thead>
<tr>
<th class="col-checkbox"><input type="checkbox" onchange="toggleAllTable('delivery-table', this)"></th>
<th>单号</th><th>件数</th><th>重量(kg)</th><th>入方编码</th><th>渠道名</th><th>目的仓类型</th><th>客户</th><th>收货公司</th><th>规格型号</th><th>派送状态</th><th>总数量</th><th>总毛重</th><th>总净重</th><th>总体积</th><th>清关申报单价</th><th>清关申报金额</th><th>材质</th><th>用途</th><th>品牌</th><th>创建时间</th><th>跟踪编号</th><th>国际单号</th><th>操作人</th><th>备注</th>
</tr>
</thead>
<tbody>
<tr class="empty-state"><td colspan="25"><div class="empty-icon">📦</div><div class="empty-text">暂无数据</div></td></tr>
</tbody>
</table>
</div>
<div class="pagination-bar">
<div class="pagination-info"><span>共 <strong>0</strong> 条</span><select class="page-size-select"><option>10 条/页</option><option>20 条/页</option><option>50 条/页</option><option>100 条/页</option></select></div>
<div class="pagination-ctrl"><button class="page-btn" disabled>上一页</button><button class="page-btn active">1</button><button class="page-btn" disabled>下一页</button></div>
</div>
</div>
</div>
<!-- ========== PAGE: 贴标申请列表 ========== -->
<div class="page-content" id="page-labeling-list">
<div class="breadcrumb"><a href="#" onclick="switchPage('order');return false;">首页</a><span class="sep">/</span><span class="current">贴标申请</span></div>
<div class="page-header-actions"><div class="page-title">贴标申请</div><div class="page-action-group"><button type="button" class="btn btn-primary" onclick="openLabelingCreate()">+ 新增贴标申请</button></div></div>
<div class="card storage-transfer-section"><div class="card-body">
<div class="storage-transfer-filter-grid">
<div class="storage-transfer-filter-item"><label class="storage-transfer-filter-label" for="labeling-filter-order-no">贴标申请单号</label><input class="storage-transfer-input" id="labeling-filter-order-no" type="text" placeholder="请输入贴标申请单号"></div>
<div class="storage-transfer-filter-item"><label class="storage-transfer-filter-label" for="labeling-filter-customer-no">客户单号</label><input class="storage-transfer-input" id="labeling-filter-customer-no" type="text" placeholder="请输入客户单号"></div>
<div class="storage-transfer-filter-item"><label class="storage-transfer-filter-label" for="labeling-filter-status">订单状态</label><select class="storage-transfer-select" id="labeling-filter-status"><option value="">全部状态</option><option>待处理</option><option>处理中</option><option>已完成</option></select></div>
</div>
<div class="storage-transfer-filter-actions"><button type="button" class="btn btn-primary" onclick="filterLabelingOrders()">查询</button><button type="button" class="btn btn-default" onclick="resetLabelingFilters()">重置</button></div>
</div></div>
<div class="card"><div class="table-wrap-simple"><table class="data-table" id="labeling-list-table"><thead><tr><th>贴标申请单号</th><th>客户单号</th><th>目的海外仓</th><th>贴标要求</th><th>SKU 数</th><th>总箱数</th><th>状态</th><th>创建时间</th></tr></thead><tbody id="labeling-list-body"><tr class="empty-state"><td colspan="8"><div class="empty-text">暂无贴标申请</div></td></tr></tbody></table></div><div class="pagination-bar"><div class="pagination-info">共 <strong id="labeling-total">0</strong> 条</div></div></div>
</div>
<!-- ========== PAGE: 新增贴标申请 ========== -->
<div class="page-content" id="page-labeling">
<div class="breadcrumb"><a href="#" onclick="openLabelingList();return false;">贴标申请</a><span class="sep">/</span><span class="current">新增</span></div>
<div class="page-header-actions"><div class="page-title">新增贴标申请</div><button type="button" class="btn btn-default" onclick="openLabelingList()">返回列表</button></div>
<form id="labeling-form" onsubmit="submitLabeling(event)">
<!-- 订单信息 -->
<div class="card" style="margin-bottom:12px;">
<div class="card-body">
<div class="info-section-title" style="margin-bottom:18px;">订单信息</div>
<div style="display:grid;grid-template-columns:1fr 1fr;gap:16px 24px;">
<div class="form-group">
<div class="form-label"><span class="required">*</span>客户单号</div>
<div class="form-content"><input type="text" class="form-input" name="customerNo" placeholder="请输入客户单号" style="width:100%;max-width:360px;" required></div>
</div>
<div class="form-group">
<div class="form-label"><span class="required">*</span>目的海外仓</div>
<div class="form-content">
<select class="form-input" name="warehouse" style="width:100%;max-width:360px;" required>
<option value="">请选择</option>
<option>美西海外仓-ONT8</option>
<option>美西海外仓-LAX9</option>
<option>美东海外仓-ATL2</option>
<option>美东海外仓-EWR4</option>
<option>美中海外仓-MDW2</option>
</select>
</div>
</div>
<div class="form-group">
<div class="form-label"><span class="required">*</span>贴标截止时间</div>
<div class="form-content"><input type="datetime-local" class="form-input" name="deadline" style="width:100%;max-width:360px;" required></div>
</div>
<div class="form-group">
<div class="form-label"><span class="required">*</span>联系人</div>
<div class="form-content"><input type="text" class="form-input" name="contact" placeholder="请输入联系人" style="width:100%;max-width:360px;" required></div>
</div>
<div class="form-group">
<div class="form-label"><span class="required">*</span>联系电话</div>
<div class="form-content"><input type="text" class="form-input" name="phone" placeholder="请输入联系电话" style="width:100%;max-width:360px;" required></div>
</div>
<div class="form-group" style="grid-column:1 / -1;">
<div class="form-label">备注</div>
<div class="form-content"><textarea class="form-textarea" name="remark" placeholder="请输入备注信息" style="max-width:760px;height:70px;"></textarea></div>
</div>
</div>
</div>
</div>
<!-- 面单贴标文件 -->
<div class="card" style="margin-bottom:12px;">
<div class="card-body">
<div class="info-section-title" style="margin-bottom:18px;">面单贴标文件</div>
<div class="upload-zone" id="label-upload-zone" onclick="document.getElementById('label-file-input').click()">
<div class="upload-zone-icon">📎</div>
<div class="upload-zone-text">点击或拖拽图片到此处上传</div>
<div class="upload-zone-hint">支持 PNG / JPG / JPEG 格式,可上传多张</div>
<input type="file" id="label-file-input" accept="image/*" multiple style="display:none;" onchange="handleLabelFiles(this.files)">
</div>
<div class="upload-preview" id="label-preview"></div>
</div>
</div>
<!-- 货物明细 -->
<div class="card" style="margin-bottom:12px;">
<div class="card-body">
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:14px;">
<div class="info-section-title" style="margin:0;">货物明细</div>
<div style="display:flex;gap:10px;">
<button type="button" class="btn btn-primary" onclick="addLabelingRow()" style="font-size:12px;padding:6px 16px;">+ 添加行</button>
<button type="button" class="btn btn-default" onclick="clearLabelingRows()" style="font-size:12px;padding:6px 16px;">清空</button>
</div>
</div>
<div class="table-wrap-simple">
<table class="data-table" id="labeling-table">
<thead>
<tr>
<th class="col-checkbox"><input type="checkbox" onchange="toggleAllTable('labeling-table', this)"></th>
<th>商品SKU<span style="color:#ff4d4f;">*</span></th>
<th>商品图片</th>
<th>中文品名<span style="color:#ff4d4f;">*</span></th>
<th>总箱数<span style="color:#ff4d4f;">*</span></th>
<th>通知移仓件数(箱数)<span style="color:#ff4d4f;">*</span></th>
<th>货件编号<span style="color:#ff4d4f;">*</span></th>
<th>追踪编码</th>
<th>换标新SKU<span style="color:#ff4d4f;">*</span></th>
<th>贴标要求</th>
<th>上传换标文件</th>
<th>操作</th>
</tr>
</thead>
<tbody id="labeling-tbody">
<tr class="empty-state"><td colspan="12"><div class="empty-icon">📦</div><div class="empty-text">暂无货物明细,请点击「添加行」</div></td></tr>
</tbody>
</table>
</div>
</div>
</div>
<!-- 提交按钮 -->
<div class="form-footer">
<div class="footer-tips"><span class="tip-icon">⚠️</span> 提交后海外仓将按要求进行换标贴标,请确认货物信息准确</div>
<div style="display:flex;gap:12px;align-items:center;justify-content:center;">
<button type="button" class="btn btn-default" onclick="resetLabelingForm()">重置</button>
<button type="submit" class="btn-submit" id="labeling-submit">提交贴标申请</button>
</div>
</div>
</form>
</div>
<!-- ========== PAGE: 仓储转运单列表 ========== -->
<div class="page-content" id="page-storage-transfer-list">
<div class="breadcrumb"><a href="#" onclick="switchPage('order');return false;">首页</a><span class="sep">/</span><span class="current">仓储转运单</span></div>
<div class="page-header-actions">
<div class="page-title">仓储转运单</div>
<div class="page-action-group">
<button type="button" class="btn btn-primary" onclick="openStorageTransferCreate()">+ 新增订单</button>
</div>
</div>
<div class="card storage-transfer-section">
<div class="card-body">
<div class="storage-transfer-filter-grid">
<div class="storage-transfer-filter-item"><label class="storage-transfer-filter-label" for="storage-transfer-filter-order-no">转运单号</label><input class="storage-transfer-input" id="storage-transfer-filter-order-no" type="text" placeholder="请输入转运单号"></div>
<div class="storage-transfer-filter-item"><label class="storage-transfer-filter-label" for="storage-transfer-filter-inbound-no">进仓编号</label><input class="storage-transfer-input" id="storage-transfer-filter-inbound-no" type="text" placeholder="请输入进仓编号"></div>
<div class="storage-transfer-filter-item"><label class="storage-transfer-filter-label" for="storage-transfer-filter-warehouse">操作仓</label><select class="storage-transfer-select" id="storage-transfer-filter-warehouse"><option value="">全部操作仓</option><option>美西洛杉矶仓</option><option>美东新泽西仓</option><option>美中芝加哥仓</option></select></div>
<div class="storage-transfer-filter-item"><label class="storage-transfer-filter-label" for="storage-transfer-filter-fba">FBA 目的仓</label><input class="storage-transfer-input" id="storage-transfer-filter-fba" type="text" placeholder="请输入仓代码"></div>
<div class="storage-transfer-filter-item"><label class="storage-transfer-filter-label" for="storage-transfer-filter-relabel">是否换标</label><select class="storage-transfer-select" id="storage-transfer-filter-relabel"><option value="">全部</option><option value="yes">是</option><option value="no">否</option></select></div>
<div class="storage-transfer-filter-item"><label class="storage-transfer-filter-label" for="storage-transfer-filter-status">订单状态</label><select class="storage-transfer-select" id="storage-transfer-filter-status"><option value="">全部状态</option><option>待处理</option><option>处理中</option><option>已完成</option><option>已提交</option></select></div>
<div class="storage-transfer-filter-item"><span class="storage-transfer-filter-label">创建时间</span><div class="storage-transfer-date-range"><input class="storage-transfer-input" id="storage-transfer-filter-created-start" type="date" aria-label="创建开始时间"><span>至</span><input class="storage-transfer-input" id="storage-transfer-filter-created-end" type="date" aria-label="创建结束时间"></div></div>
</div>
<div class="storage-transfer-filter-actions">
<button type="button" class="btn btn-primary" onclick="filterStorageTransferOrders()">查询</button>
<button type="button" class="btn btn-default" onclick="resetStorageTransferFilters()">重置</button>
</div>
</div>
</div>
<div class="card storage-transfer-list-card">
<div class="table-wrap-simple">
<table class="data-table" id="storage-transfer-list-table">
<thead><tr><th>转运单号</th><th>进仓编号</th><th>发货箱数</th><th>操作仓</th><th>FBA 目的仓</th><th>FBA货件编号</th><th>派送方式</th><th>是否换标</th><th>后台尾程订单号</th><th>后台换标单号</th><th>状态</th><th>创建时间</th><th>查看</th></tr></thead>
<tbody id="storage-transfer-list-body"><tr class="empty-state"><td colspan="13"><div class="empty-text">暂无仓储转运订单</div></td></tr></tbody>
</table>
</div>
<div class="storage-transfer-pagination" id="storage-transfer-pagination">
<div class="pagination-info">共 <strong id="storage-transfer-total">0</strong> 条</div>
<div class="pagination-ctrl"><button class="page-btn" id="storage-transfer-prev" onclick="changeStorageTransferPage(-1)">上一页</button><button class="page-btn active" id="storage-transfer-page-number">1</button><button class="page-btn" id="storage-transfer-next" onclick="changeStorageTransferPage(1)">下一页</button></div>
</div>
</div>
</div>
<!-- ========== PAGE: 新增仓储转运单 ========== -->
<div class="page-content" id="page-storage-transfer-create">
<div class="breadcrumb"><a href="#" onclick="openStorageTransferList();return false;">仓储转运单</a><span class="sep">/</span><span class="current">新增订单</span></div>
<div class="page-title" style="margin-bottom:16px;">新增仓储转运单</div>
<form id="storage-transfer-form" onsubmit="submitStorageTransferOrder(event)">
<div class="card storage-transfer-section">
<div class="card-body">
<div class="storage-transfer-section-title">基础与派送信息</div>
<div class="storage-transfer-form-grid">
<div class="storage-transfer-field"><label class="storage-transfer-field-label" for="storage-transfer-inbound-no">进仓编号</label><input class="storage-transfer-input" id="storage-transfer-inbound-no" name="inboundNo" type="text" required></div>
<div class="storage-transfer-field"><label class="storage-transfer-field-label" for="storage-transfer-warehouse">操作仓</label><select class="storage-transfer-select" id="storage-transfer-warehouse" name="warehouse" required><option value="">请选择操作仓</option><option>美西洛杉矶仓</option><option>美东新泽西仓</option><option>美中芝加哥仓</option></select></div>
<div class="storage-transfer-field"><label class="storage-transfer-field-label" for="storage-transfer-fba-code">FBA 目的仓代码</label><input class="storage-transfer-input" id="storage-transfer-fba-code" name="fbaCode" type="text" required></div>
<div class="storage-transfer-field storage-transfer-span-3"><label class="storage-transfer-field-label" for="storage-transfer-address">详细派送地址</label><input class="storage-transfer-input" id="storage-transfer-address" name="address" type="text" required></div>
<div class="storage-transfer-field"><label class="storage-transfer-field-label" for="storage-transfer-box-count">发货箱数</label><input class="storage-transfer-input" id="storage-transfer-box-count" name="boxCount" type="number" min="1" required></div>
<div class="storage-transfer-field"><label class="storage-transfer-field-label" for="storage-transfer-delivery-method">派送方式</label><select class="storage-transfer-select" id="storage-transfer-delivery-method" name="deliveryMethod" required><option value="">请选择派送方式</option><option>卡车派送</option><option>快递派送</option></select></div>
<div class="storage-transfer-field"><label class="storage-transfer-field-label" for="storage-transfer-expected-arrival">期望到达时间</label><input class="storage-transfer-input" id="storage-transfer-expected-arrival" name="expectedArrival" type="datetime-local" required></div>
<div class="storage-transfer-field"><label class="storage-transfer-field-label" for="storage-transfer-shipment-id">FBA 货件编号</label><input class="storage-transfer-input" id="storage-transfer-shipment-id" name="shipmentId" type="text" required></div>
<div class="storage-transfer-field"><label class="storage-transfer-field-label" for="storage-transfer-tracking-id">FBA 追踪编号</label><input class="storage-transfer-input" id="storage-transfer-tracking-id" name="trackingId" type="text" placeholder="选填"></div>
<div class="storage-transfer-field"><label class="storage-transfer-field-label" for="storage-transfer-box-id">FBA BOX 编号</label><input class="storage-transfer-input" id="storage-transfer-box-id" name="boxId" type="text" placeholder="选填,支持单号或连续范围"></div>
<div class="storage-transfer-field storage-transfer-span-3"><label class="storage-transfer-field-label" for="storage-transfer-note">订单备注</label><textarea class="storage-transfer-textarea" id="storage-transfer-note" name="note"></textarea></div>
</div>
</div>
</div>
<div class="card storage-transfer-section">
<div class="card-body">
<div class="storage-transfer-section-title">是否换标</div>
<div class="storage-transfer-relabel">
<div class="storage-transfer-radio-group">
<label class="storage-transfer-radio-option"><input name="relabel" type="radio" value="yes" onchange="toggleStorageTransferRelabel()">是</label>
<label class="storage-transfer-radio-option"><input name="relabel" type="radio" value="no" checked onchange="toggleStorageTransferRelabel()">否</label>
</div>
<span class="storage-transfer-relabel-copy">选择换标时同时生成后台换标单</span>
</div>
</div>
</div>
<div class="card storage-transfer-section">
<div class="card-body">
<div class="storage-transfer-section-title">货物明细</div>
<div class="product-table-wrap">
<table class="product-table storage-transfer-cargo-table" id="storage-transfer-cargo-table"><thead><tr><th>商品SKU</th><th>中文品名</th><th>箱数</th><th class="storage-transfer-relabel-column">换标后SKU</th><th class="storage-transfer-relabel-column">贴标要求</th><th class="storage-transfer-relabel-column">换标文件</th><th>操作</th></tr></thead><tbody id="storage-transfer-cargo-body"></tbody></table>
</div>
<div class="storage-transfer-error" id="storage-transfer-cargo-error" aria-live="polite"></div>
<button type="button" class="btn btn-default" onclick="addStorageTransferCargoRow()">+ 添加货物</button>
</div>
</div>
<div class="storage-transfer-form-actions">
<button type="button" class="btn btn-default" onclick="cancelStorageTransferCreate()">取消</button>
<button type="submit" class="btn btn-primary storage-transfer-submit" id="storage-transfer-submit">提交订单</button>
</div>
</form>
</div>
<!-- ========== PAGE: 仓储转运单详情 ========== -->
<div class="page-content" id="page-storage-transfer-detail">
<div class="breadcrumb"><a href="#" onclick="openStorageTransferList();return false;">仓储转运单</a><span class="sep">/</span><span class="current">订单详情</span></div>
<div class="page-header-actions"><div class="page-title">仓储转运单详情</div><button type="button" class="btn btn-default" onclick="openStorageTransferList()">返回列表</button></div>
<section class="card storage-transfer-section" aria-labelledby="storage-transfer-summary-title">
<div class="card-body"><div class="storage-transfer-section-title" id="storage-transfer-summary-title">订单概览</div><div class="storage-transfer-summary-grid" id="storage-transfer-detail-summary"><div class="storage-transfer-summary-item"><div class="storage-transfer-summary-label">转运单号</div><div class="storage-transfer-summary-value">-</div></div><div class="storage-transfer-summary-item"><div class="storage-transfer-summary-label">订单状态</div><div class="storage-transfer-summary-value">-</div></div><div class="storage-transfer-summary-item"><div class="storage-transfer-summary-label">是否换标</div><div class="storage-transfer-summary-value">-</div></div></div></div>
</section>
<section class="card storage-transfer-section" aria-labelledby="storage-transfer-detail-cargo-title">
<div class="card-body"><div class="storage-transfer-section-title" id="storage-transfer-detail-cargo-title">货物明细</div><div class="product-table-wrap"><table class="product-table storage-transfer-cargo-table" id="storage-transfer-detail-cargo-table"><thead><tr><th>商品SKU</th><th>中文品名</th><th>箱数</th><th>换标后SKU</th><th>贴标要求</th><th>换标文件</th></tr></thead><tbody id="storage-transfer-detail-cargo"><tr class="empty-state"><td colspan="6">暂无货物明细</td></tr></tbody></table></div></div>
</section>
<section class="card storage-transfer-section" aria-labelledby="storage-transfer-relation-title">
<div class="card-body"><div class="storage-transfer-section-title" id="storage-transfer-relation-title">关联单号</div><div class="storage-transfer-relation-grid"><div class="storage-transfer-relation-item"><div class="storage-transfer-summary-label">后台尾程订单号</div><div class="storage-transfer-summary-value" id="storage-transfer-tail-order-no">-</div></div><div class="storage-transfer-relation-item"><div class="storage-transfer-summary-label">后台换标单号</div><div class="storage-transfer-summary-value" id="storage-transfer-relabel-order-no">-</div></div></div></div>
</section>
</div>
<!-- ========== PAGE: 货物废弃列表 ========== -->
<div class="page-content" id="page-cargo-disposal-list">
<div class="breadcrumb"><a href="#" onclick="switchPage('order');return false;">首页</a><span class="sep">/</span><span class="current">货物废弃</span></div>
<div class="page-header-actions"><div class="page-title">货物废弃</div><div class="page-action-group"><button type="button" class="btn btn-primary" onclick="openCargoDisposalCreate()">+ 新增货物废弃</button></div></div>
<div class="card cargo-disposal-section"><div class="card-body"><div class="cargo-disposal-filter-grid">
<div class="cargo-disposal-filter-item"><label class="cargo-disposal-label" for="cargo-disposal-filter-order-no">货物废弃单号</label><input class="cargo-disposal-input" id="cargo-disposal-filter-order-no" placeholder="请输入货物废弃单号"></div>
<div class="cargo-disposal-filter-item"><label class="cargo-disposal-label" for="cargo-disposal-filter-inbound-no">入库单号</label><input class="cargo-disposal-input" id="cargo-disposal-filter-inbound-no" placeholder="请输入入库单号"></div>
<div class="cargo-disposal-filter-item"><label class="cargo-disposal-label" for="cargo-disposal-filter-warehouse">操作仓</label><select class="cargo-disposal-select" id="cargo-disposal-filter-warehouse"><option value="">全部操作仓</option><option>美西洛杉矶仓</option><option>美东新泽西仓</option></select></div>
<div class="cargo-disposal-filter-item"><label class="cargo-disposal-label" for="cargo-disposal-filter-status">订单状态</label><select class="cargo-disposal-select" id="cargo-disposal-filter-status"><option value="">全部状态</option><option>待处理</option><option>处理中</option><option>已完成</option></select></div>
<div class="cargo-disposal-filter-item"><span class="cargo-disposal-label">创建时间</span><div style="display:grid;grid-template-columns:1fr auto 1fr;gap:7px;align-items:center;"><input class="cargo-disposal-input" id="cargo-disposal-filter-created-start" type="date" aria-label="创建开始时间"><span>至</span><input class="cargo-disposal-input" id="cargo-disposal-filter-created-end" type="date" aria-label="创建结束时间"></div></div>
</div><div class="cargo-disposal-actions"><button type="button" class="btn btn-primary" onclick="filterCargoDisposalOrders()">查询</button><button type="button" class="btn btn-default" onclick="resetCargoDisposalFilters()">重置</button></div></div></div>
<div class="card"><div class="table-wrap-simple"><table class="data-table" id="cargo-disposal-list-table"><thead><tr><th>货物废弃单号</th><th>关联入库单</th><th>废弃箱数</th><th>操作仓</th><th>弃货费</th><th>入仓码</th><th>废弃出库单号</th><th>计费单号</th><th>状态</th><th>创建时间</th><th>查看</th></tr></thead><tbody id="cargo-disposal-list-body"><tr class="empty-state"><td colspan="11">暂无货物废弃订单</td></tr></tbody></table></div><div class="storage-transfer-pagination"><div class="pagination-info">共 <strong id="cargo-disposal-total">0</strong> 条</div><div class="pagination-ctrl"><button class="page-btn" id="cargo-disposal-prev" onclick="changeCargoDisposalPage(-1)">上一页</button><button class="page-btn active" id="cargo-disposal-page-number">1</button><button class="page-btn" id="cargo-disposal-next" onclick="changeCargoDisposalPage(1)">下一页</button></div></div></div>
</div>
<!-- ========== PAGE: 新增货物废弃 ========== -->
<div class="page-content" id="page-cargo-disposal-create">
<div class="breadcrumb"><a href="#" onclick="openCargoDisposalList();return false;">货物废弃</a><span class="sep">/</span><span class="current">新增</span></div>
<div class="page-header-actions"><div class="page-title">新增货物废弃</div><button type="button" class="btn btn-default" onclick="openCargoDisposalList()">返回列表</button></div>
<form id="cargo-disposal-form" onsubmit="submitCargoDisposalOrder(event)">
<div class="card"><div class="card-body"><div class="storage-transfer-section-title">选择入仓码</div><div class="cargo-disposal-inbound-meta">展开入仓码后填写每条明细的可用箱数与废弃箱数,废弃箱数不能超过可用箱数。</div><div class="cargo-disposal-inbound-search"><label class="cargo-disposal-label" for="cargo-disposal-inbound-search">入仓码搜索</label><input class="cargo-disposal-input" id="cargo-disposal-inbound-search" type="search" placeholder="请输入入仓码" autocomplete="off" oninput="filterCargoDisposalInboundCards()"></div><input class="cargo-disposal-quantity" type="number" hidden aria-hidden="true"><div id="cargo-disposal-inbound-cards" aria-live="polite"><div class="empty-text">正在加载入仓码...</div></div><div class="cargo-disposal-fee-bar"><span>弃货费按废弃箱数 × 5 USD/箱计算</span><strong class="cargo-disposal-fee-amount" id="cargo-disposal-fee">$0.00</strong></div><div class="storage-transfer-error" id="cargo-disposal-error" aria-live="polite"></div></div></div>
<div class="cargo-disposal-actions"><button type="button" class="btn btn-default" onclick="openCargoDisposalList()">取消</button><button type="submit" class="btn btn-primary" id="cargo-disposal-submit">提交货物废弃</button></div>
</form>
</div>
<!-- ========== PAGE: 货物废弃详情 ========== -->
<div class="page-content" id="page-cargo-disposal-detail">
<div class="breadcrumb"><a href="#" onclick="openCargoDisposalList();return false;">货物废弃</a><span class="sep">/</span><span class="current">订单详情</span></div>
<div class="page-header-actions"><div class="page-title">货物废弃详情</div><button type="button" class="btn btn-default" onclick="openCargoDisposalList()">返回列表</button></div>
<section class="card"><div class="card-body"><div class="storage-transfer-section-title">订单概览</div><div class="cargo-disposal-summary-grid" id="cargo-disposal-detail-summary"></div></div></section>
<section class="card"><div class="card-body"><div class="storage-transfer-section-title">废弃货物明细</div><div class="cargo-disposal-table-wrap"><table class="cargo-disposal-table"><thead><tr><th>SKU</th><th>中文品名</th><th>可用箱数</th><th>废弃箱数</th></tr></thead><tbody id="cargo-disposal-detail-items"></tbody></table></div></div></section>
<section class="card"><div class="card-body"><div class="storage-transfer-section-title">关联单据</div><div class="cargo-disposal-relation-grid"><div class="cargo-disposal-relation-item"><div class="storage-transfer-summary-label">客户端货物废弃单号</div><div class="storage-transfer-summary-value" id="cargo-disposal-detail-order-no">-</div></div><div class="cargo-disposal-relation-item"><div class="storage-transfer-summary-label">后台尾程单号</div><div class="storage-transfer-summary-value" id="cargo-disposal-detail-tail-order-no">-</div></div><div class="cargo-disposal-relation-item"><div class="storage-transfer-summary-label">废弃出库单号</div><div class="storage-transfer-summary-value" id="cargo-disposal-detail-outbound-order-no">-</div></div><div class="cargo-disposal-relation-item"><div class="storage-transfer-summary-label">弃货费计费单号</div><div class="storage-transfer-summary-value" id="cargo-disposal-detail-billing-no">-</div></div></div></div></section>
</div>
<!-- ========== PAGE: 退货换标(合并退货入库/换标/出库) ========== -->
<div class="page-content" id="page-return-relabel-list">
<div class="breadcrumb"><a href="#" onclick="switchPage('order');return false;">首页</a><span class="sep">/</span><span class="current">退货换标</span></div>
<div class="page-header-actions"><div class="page-title">退货换标</div><button class="btn btn-primary" onclick="openReturnRelabelCreate()">+ 新建退货换标单</button></div>
<div class="card return-relabel-filter-card"><div class="card-body"><div class="return-relabel-filter-grid">
<div><label>退货换标单号</label><input class="return-relabel-input" id="return-relabel-filter-order-no" type="text"></div><div><label>来源 FBA 仓</label><select class="return-relabel-select" id="return-relabel-filter-source"><option value="">全部</option><option>ONT8</option><option>ABE8</option><option>CLT2</option></select></div><div><label>目的 FBA 仓</label><select class="return-relabel-select" id="return-relabel-filter-destination"><option value="">全部</option><option>ONT8</option><option>LAX9</option><option>ABE8</option></select></div><div><label>商品 SKU</label><input class="return-relabel-input" id="return-relabel-filter-sku" type="text"></div><div><label>是否换标</label><select class="return-relabel-select" id="return-relabel-filter-enabled"><option value="">全部</option><option value="yes">是</option><option value="no">否</option></select></div><div><label>尾程订单状态</label><select class="return-relabel-select" id="return-relabel-filter-tail-status"><option value="">全部</option><option>待入库</option><option>已入库待出库</option><option>出库中</option><option>已完成</option></select></div><div><label>换标状态</label><select class="return-relabel-select" id="return-relabel-filter-status"><option value="">全部</option><option>待换标</option><option>换标中</option><option>已完成</option></select></div><div><label>创建时间</label><input class="return-relabel-input" id="return-relabel-filter-created-start" type="date"></div><div><label>&nbsp;</label><input class="return-relabel-input" id="return-relabel-filter-created-end" type="date"></div>
</div><div class="return-relabel-filter-actions"><button class="btn btn-primary" onclick="filterReturnRelabelOrders()">查询</button><button class="btn btn-default" onclick="resetReturnRelabelFilters()">重置</button></div></div></div>
<div class="card return-relabel-list-card"><div class="table-wrap-simple"><table class="data-table return-relabel-table"><thead><tr><th>退货换标单号</th><th>来源FBA仓</th><th>目的FBA仓</th><th>SKU汇总</th><th>退件总数</th><th>是否换标</th><th>贴标要求</th><th>尾程订单号</th><th>换标单号</th><th>换标状态</th><th>尾程订单状态</th><th>创建时间</th><th>查看</th></tr></thead><tbody id="return-relabel-list-body"></tbody></table></div><div class="return-relabel-pagination"><span>共 <strong id="return-relabel-total">0</strong> 条</span><div><button class="page-btn" onclick="changeReturnRelabelPage(-1)" id="return-relabel-prev">上一页</button><button class="page-btn active" id="return-relabel-page-number">1</button><button class="page-btn" onclick="changeReturnRelabelPage(1)" id="return-relabel-next">下一页</button></div></div></div>
</div>
<div class="page-content" id="page-return-relabel-create"><div class="breadcrumb"><a href="#" onclick="openReturnRelabelList();return false;">退货换标</a><span class="sep">/</span><span class="current">新建</span></div><div class="page-header-actions"><div class="page-title">新建退货换标单</div><button class="btn btn-default" onclick="openReturnRelabelList()">返回列表</button></div><form id="return-relabel-form" onsubmit="submitReturnRelabelOrder(event)"><div class="card return-relabel-section"><div class="card-body"><div class="return-relabel-section-title">退货信息</div><div class="return-relabel-form-grid"><div><label>来源 FBA 仓库</label><select class="return-relabel-select" name="sourceFba" required><option value="">请选择</option><option>ONT8</option><option>ABE8</option><option>CLT2</option></select></div><div><label>移除订单 Order ID</label><input class="return-relabel-input" name="orderId" required></div><div><label>退货原因</label><select class="return-relabel-select" name="reason" required><option value="">请选择</option><option>客户退货</option><option>亚马逊移除</option><option>不可售</option></select></div><div><label>物流承运商</label><input class="return-relabel-input" name="carrier" required></div><div><label>物流跟踪号</label><input class="return-relabel-input" name="trackingNo" required></div><div class="return-relabel-span-2"><label>退货备注</label><textarea class="return-relabel-textarea" name="returnRemark"></textarea></div></div></div></div><div class="card return-relabel-section"><div class="card-body"><div class="return-relabel-section-title">货物明细</div><div class="return-relabel-table-wrap"><table class="product-table" id="return-relabel-sku-table"><thead><tr><th>商品SKU</th><th>中文品名</th><th>FNSKU</th><th>退件数量</th><th>操作</th></tr></thead><tbody id="return-relabel-sku-body"></tbody></table></div><button type="button" class="btn btn-ghost" onclick="addReturnRelabelSkuRow()">+ 添加 SKU</button></div></div><div class="card return-relabel-section"><div class="card-body"><div class="return-relabel-section-title">换标设置</div><label><input type="checkbox" name="relabel" onchange="toggleReturnRelabel()"> 是否换标</label><div id="return-relabel-settings-fields"><div class="return-relabel-case-grid"><label><input type="radio" name="labelCase" value="Case1" checked onchange="updateFileRequirements()"> Case1:只换箱唛</label><label><input type="radio" name="labelCase" value="Case2" onchange="updateFileRequirements()"> Case2:只换SKU标</label><label><input type="radio" name="labelCase" value="Case3" onchange="updateFileRequirements()"> Case3:既换箱唛,又换SKU标</label></div><div class="return-relabel-file-grid"><div><label>上传箱唛</label><input type="file" name="cartonLabel"></div><div><label>上传 SKU 标签</label><input type="file" name="skuLabel"></div></div><div id="return-relabel-file-hint"></div></div></div></div><div class="card return-relabel-section"><div class="card-body"><div class="return-relabel-section-title">尾程信息</div><div class="return-relabel-form-grid"><div><label>目的 FBA 仓库</label><select class="return-relabel-select" name="destinationFba" required><option value="">请选择</option><option>ONT8</option><option>LAX9</option><option>ABE8</option></select></div><div><label>派送地址</label><input class="return-relabel-input" name="address" required></div><div><label>目的仓代码</label><input class="return-relabel-input" name="destinationCode" required></div><div><label>期望到达时间</label><input class="return-relabel-input" name="expectedArrival" type="datetime-local" required></div><div class="return-relabel-span-2"><label>尾程备注</label><textarea class="return-relabel-textarea" name="tailRemark"></textarea></div></div><div id="return-relabel-error" class="return-relabel-error"></div></div></div><div class="return-relabel-form-actions"><button type="button" class="btn btn-default" onclick="openReturnRelabelList()">取消</button><button type="submit" class="btn btn-primary" id="return-relabel-submit">提交订单</button></div></form></div>
<div class="page-content" id="page-return-relabel-detail"><div class="breadcrumb"><a href="#" onclick="openReturnRelabelList();return false;">退货换标</a><span class="sep">/</span><span class="current">订单详情</span></div><div class="page-header-actions"><div class="page-title">退货换标详情</div><button class="btn btn-default" onclick="openReturnRelabelList()">返回列表</button></div><section class="card return-relabel-section"><div class="card-body"><div class="return-relabel-section-title">订单概览</div><div class="return-relabel-summary-grid" id="return-relabel-detail-summary"></div></div></section><section class="card return-relabel-section"><div class="card-body"><div class="return-relabel-section-title">商品明细</div><div class="return-relabel-table-wrap"><table class="product-table" id="return-relabel-detail-sku-table"><thead><tr><th>商品SKU</th><th>中文品名</th><th>FNSKU</th><th>退件数量</th></tr></thead><tbody id="return-relabel-detail-sku-body"></tbody></table></div></div></section><section class="card return-relabel-section"><div class="card-body"><div class="return-relabel-section-title">后台关联单据</div><div class="return-relabel-relation-grid"><div><label>后台尾程订单号</label><strong id="return-relabel-detail-tail-order-no">-</strong></div><div><label>后台换标单号</label><strong id="return-relabel-detail-relabel-order-no">-</strong></div><div><label>换标状态</label><strong id="return-relabel-detail-relabel-status">待换标</strong></div><div><label>尾程订单状态</label><strong id="return-relabel-detail-tail-status">待入库</strong></div></div></div></section></div>
<!-- ========== PAGE: 旧退货入库(保留 DOM 兼容,不再出现在导航) ========== -->
<div class="page-content" id="page-label-return-in">
<div class="breadcrumb"><a href="#" onclick="switchPage('order');return false;">首页</a><span class="sep">/</span><span class="current">退货入库</span></div>
<div class="page-header-actions">
<div class="page-title">退货入库</div>
<div class="page-action-group">
<button class="btn btn-primary" onclick="openReturnInModal()">+ 新建</button>
<button class="btn btn-default" onclick="alert('导出Excel')">导出Excel</button>
</div>
</div>
<div class="card" style="margin-bottom:12px;">
<div class="card-body">
<div class="filter-grid" style="grid-template-columns:200px 1fr 160px 120px 80px 80px;">
<div class="filter-item">
<select class="filter-select"><option value="">全部FBA仓库</option><option>FBA ONT8</option><option>FBA CLT2</option><option>FBA MEM1</option><option>DE Frankfurt</option><option>FBA IND9</option></select>
</div>
<div class="filter-item">
<input type="text" class="filter-input" placeholder="退货单号">
</div>
<div class="filter-item">
<select class="filter-select"><option value="">全部状态</option><option>待接收</option><option>已接收</option></select>
</div>
<button class="btn-flat btn-flat-blue" onclick="alert('查询')">查询</button>
<button class="btn-flat" onclick="alert('重置')">重置</button>
</div>
</div>
</div>
<div class="card">
<div class="table-wrap-simple">
<table class="data-table">
<thead>
<tr>
<th>退货单号</th><th>FBA仓库</th><th>商品SKU</th><th>中文品名</th><th>箱数</th><th>退货原因</th><th>状态</th><th>操作</th>
</tr>
</thead>
<tbody>
<tr>
<td>RTN20260701001</td><td>FBA ONT8</td><td>SKU-A1001</td><td>蓝牙耳机套件</td><td>6</td><td>客户退货-质量问题</td>
<td><span class="status-badge status-pending">待接收</span></td>
<td><span class="link-action">查看</span><span class="link-action">编辑</span></td>
</tr>
<tr>
<td>RTN20260701002</td><td>FBA CLT2</td><td>SKU-B2002</td><td>手机保护壳</td><td>10</td><td>客户退货-七天无理由</td>
<td><span class="status-badge status-processing">已接收</span></td>
<td><span class="link-action">查看</span><span class="link-action">编辑</span></td>
</tr>
<tr>
<td>RTN20260701003</td><td>FBA MEM1</td><td>SKU-C3003</td><td>充电器套装</td><td>14</td><td>亚马逊移除-不可售</td>
<td><span class="status-badge status-pending">待接收</span></td>
<td><span class="link-action">查看</span><span class="link-action">编辑</span></td>
</tr>
<tr>
<td>RTN20260701004</td><td>DE Frankfurt</td><td>SKU-D4004</td><td>LED台灯</td><td>8</td><td>客户退货-尺寸不符</td>
<td><span class="status-badge status-processing">已接收</span></td>
<td><span class="link-action">查看</span><span class="link-action">编辑</span></td>
</tr>
<tr>
<td>RTN20260701005</td><td>FBA IND9</td><td>SKU-E5005</td><td>收纳盒组合</td><td>16</td><td>亚马逊移除-可售</td>
<td><span class="status-badge status-pending">待接收</span></td>
<td><span class="link-action">查看</span><span class="link-action">编辑</span></td>
</tr>
</tbody>
</table>
</div>
<div class="pagination-bar">
<div class="pagination-info"><span>共 <strong>5</strong> 条</span></div>
<div class="pagination-ctrl"><button class="page-btn" disabled>上一页</button><button class="page-btn active">1</button><button class="page-btn" disabled>下一页</button></div>
</div>
</div>
</div>
<!-- ========== PAGE: 退货换标 ========== -->
<div class="page-content" id="page-label-return-swap">
<div class="breadcrumb"><a href="#" onclick="switchPage('order');return false;">首页</a><span class="sep">/</span><span class="current">退货换标</span></div>
<div class="page-header-actions">
<div class="page-title">退货换标</div>
<div class="page-action-group">
<button class="btn btn-primary" onclick="alert('新建换标单')">+ 新建换标单</button>
<button class="btn btn-default" onclick="alert('导出Excel')">导出Excel</button>
</div>
</div>
<div class="card" style="margin-bottom:12px;">
<div class="card-body">
<div class="filter-grid" style="grid-template-columns:200px 1fr 160px 120px 80px 80px;">
<div class="filter-item">
<select class="filter-select"><option value="">全部FBA仓库</option><option>FBA ONT8</option><option>FBA CLT2</option><option>FBA MEM1</option><option>DE Frankfurt</option><option>FBA IND9</option></select>
</div>
<div class="filter-item">
<input type="text" class="filter-input" placeholder="商品SKU">
</div>
<div class="filter-item">
<select class="filter-select"><option value="">全部状态</option><option>待换标</option><option>换标中</option><option>已完成</option></select>
</div>
<button class="btn-flat btn-flat-blue" onclick="alert('查询')">查询</button>
<button class="btn-flat" onclick="alert('重置')">重置</button>
</div>
</div>
</div>
<div class="card">
<div class="table-wrap-simple">
<table class="data-table">
<thead>
<tr>
<th>换标单号</th><th>FBA仓库</th><th>商品SKU</th><th>中文品名</th><th>箱数</th><th>贴标要求</th><th>状态</th><th>操作</th>
</tr>
</thead>
<tbody>
<tr>
<td>RRL20260710001</td><td>FBA ONT8</td><td>SKU-A1001</td><td>蓝牙耳机套件</td><td>6</td><td>全覆盖换标</td>
<td><span class="status-badge status-pending">待换标</span></td>
<td><span class="link-action">查看</span><span class="link-action">编辑</span></td>
</tr>
<tr>
<td>RRL20260711002</td><td>FBA CLT2</td><td>SKU-B2002</td><td>手机保护壳</td><td>10</td><td>加贴新标</td>
<td><span class="status-badge status-processing">换标中</span></td>
<td><span class="link-action">查看</span><span class="link-action">编辑</span></td>
</tr>
<tr>
<td>RRL20260712003</td><td>FBA MEM1</td><td>SKU-C3003</td><td>充电器套装</td><td>14</td><td>移除原标+换标</td>
<td><span class="status-badge status-done">已完成</span></td>
<td><span class="link-action">查看</span><span class="link-action">编辑</span></td>
</tr>
<tr>
<td>RRL20260713004</td><td>DE Frankfurt</td><td>SKU-D4004</td><td>LED台灯</td><td>8</td><td>全覆盖换标</td>
<td><span class="status-badge status-pending">待换标</span></td>
<td><span class="link-action">查看</span><span class="link-action">编辑</span></td>
</tr>
<tr>
<td>RRL20260714005</td><td>FBA IND9</td><td>SKU-E5005</td><td>收纳盒组合</td><td>16</td><td>加贴新标</td>
<td><span class="status-badge status-processing">换标中</span></td>
<td><span class="link-action">查看</span><span class="link-action">编辑</span></td>
</tr>
</tbody>
</table>
</div>
<div class="pagination-bar">
<div class="pagination-info"><span>共 <strong>5</strong> 条</span></div>
<div class="pagination-ctrl"><button class="page-btn" disabled>上一页</button><button class="page-btn active">1</button><button class="page-btn" disabled>下一页</button></div>
</div>
</div>
</div>
<!-- ========== PAGE: 退货出库 ========== -->
<div class="page-content" id="page-label-return-out">
<div class="breadcrumb"><a href="#" onclick="switchPage('order');return false;">首页</a><span class="sep">/</span><span class="current">退货出库</span></div>
<div class="page-header-actions">
<div class="page-title">退货出库</div>
<div class="page-action-group">
<button class="btn btn-primary" onclick="alert('新建出库单')">+ 新建出库单</button>
<button class="btn btn-default" onclick="alert('导出Excel')">导出Excel</button>
</div>
</div>
<div class="card" style="margin-bottom:12px;">
<div class="card-body">
<div class="filter-grid" style="grid-template-columns:200px 1fr 160px 120px 80px 80px;">
<div class="filter-item">
<select class="filter-select"><option value="">全部FBA仓库</option><option>FBA ONT8</option><option>FBA CLT2</option><option>FBA MEM1</option><option>DE Frankfurt</option><option>FBA IND9</option></select>
</div>
<div class="filter-item">
<input type="text" class="filter-input" placeholder="出库单号">
</div>
<div class="filter-item">
<select class="filter-select"><option value="">全部状态</option><option>待出库</option><option>已出库</option></select>
</div>
<button class="btn-flat btn-flat-blue" onclick="alert('查询')">查询</button>
<button class="btn-flat" onclick="alert('重置')">重置</button>
</div>
</div>
</div>
<div class="card">
<div class="table-wrap-simple">
<table class="data-table">
<thead>
<tr>
<th>出库单号</th><th>FBA仓库</th><th>目的仓</th><th>商品SKU</th><th>中文品名</th><th>箱数</th><th>状态</th><th>操作</th>
</tr>
</thead>
<tbody>
<tr>
<td>RTO20260715001</td><td>FBA ONT8</td><td>FBA LAX9</td><td>SKU-A1001</td><td>蓝牙耳机套件</td><td>6</td>
<td><span class="status-badge status-pending">待出库</span></td>
<td><span class="link-action">查看</span><span class="link-action">编辑</span></td>
</tr>
<tr>
<td>RTO20260716002</td><td>FBA CLT2</td><td>FBA SBD1</td><td>SKU-B2002</td><td>手机保护壳</td><td>10</td>
<td><span class="status-badge status-done">已出库</span></td>
<td><span class="link-action">查看</span><span class="link-action">编辑</span></td>
</tr>
<tr>
<td>RTO20260717003</td><td>FBA MEM1</td><td>FBA FTW1</td><td>SKU-C3003</td><td>充电器套装</td><td>14</td>
<td><span class="status-badge status-pending">待出库</span></td>
<td><span class="link-action">查看</span><span class="link-action">编辑</span></td>
</tr>
<tr>
<td>RTO20260718004</td><td>DE Frankfurt</td><td>DE Munich</td><td>SKU-D4004</td><td>LED台灯</td><td>8</td>
<td><span class="status-badge status-done">已出库</span></td>
<td><span class="link-action">查看</span><span class="link-action">编辑</span></td>
</tr>
<tr>
<td>RTO20260719005</td><td>FBA IND9</td><td>FBA LAS1</td><td>SKU-E5005</td><td>收纳盒组合</td><td>16</td>
<td><span class="status-badge status-pending">待出库</span></td>
<td><span class="link-action">查看</span><span class="link-action">编辑</span></td>
</tr>
</tbody>
</table>
</div>
<div class="pagination-bar">
<div class="pagination-info"><span>共 <strong>5</strong> 条</span></div>
<div class="pagination-ctrl"><button class="page-btn" disabled>上一页</button><button class="page-btn active">1</button><button class="page-btn" disabled>下一页</button></div>
</div>
</div>
</div>
<!-- PAGE: 一键导入(FBA批量下单) -->
<div class="page-content" id="page-bulk">
<div class="breadcrumb"><a href="#" onclick="switchPage('order');return false;">首页</a><span class="sep">/</span><span class="sep-item">美线头程下单</span><span class="sep">/</span><span class="current">一键导入(FBA批量下单)</span></div>
<div class="page-title" style="margin-bottom:16px;">一键导入(FBA批量下单)</div>
<!-- 基本信息 -->
<div class="card" style="margin-bottom:12px;">
<div class="card-body">
<div class="form-group">
<div class="form-label"><span class="required">*</span>取货方式</div>
<div class="form-content">
<div class="dest-type-tabs" id="pickup-tabs-bulk">
<button class="dest-tab active" onclick="setPickupTabBulk(this,'express')">自送货-快递</button>
<button class="dest-tab" onclick="setPickupTabBulk(this,'pickup')">我司提货(有取货费)</button>
<button class="dest-tab" onclick="setPickupTabBulk(this,'truck')">自送货-卡车</button>
</div>
</div>
</div>
<!-- 自送货-快递 -->
<div class="dest-content-bulk active" id="pickup-bulk-express">
<div class="form-group">
<div class="form-label">预计送达时间</div>
<div class="form-content">
<input type="datetime-local" class="form-input" placeholder="请选择预计送达时间" style="min-width:280px;">
</div>
</div>
<div class="form-group">
<div class="form-label">快递单号</div>
<div class="form-content">
<input type="text" class="form-input" placeholder="请输入快递单号" style="min-width:300px;">
</div>
</div>
</div>
<!-- 我司提货 -->
<div class="dest-content-bulk" id="pickup-bulk-pickup">
<div class="form-group">
<div class="form-label"><span class="required">*</span>提货地址</div>
<div class="form-content">
<textarea class="form-input" placeholder="请输入提货详细地址" style="min-width:400px;height:80px;"></textarea>
</div>
</div>
<div class="form-group">
<div class="form-label"><span class="required">*</span>提货时间</div>
<div class="form-content">
<input type="datetime-local" class="form-input" placeholder="请选择提货时间" style="min-width:280px;">
</div>
</div>
<div class="form-group">
<div class="form-label">联系人</div>
<div class="form-content">
<input type="text" class="form-input" placeholder="请输入联系人姓名" style="min-width:280px;">
</div>
</div>
<div class="form-group">
<div class="form-label">联系电话</div>
<div class="form-content">
<input type="tel" class="form-input" placeholder="请输入联系电话" style="min-width:280px;">
</div>
</div>
<div class="form-group">
<div class="form-label">提货备注</div>
<div class="form-content">
<input type="text" class="form-input" placeholder="如:小区门禁、特殊要求等" style="min-width:300px;">
</div>
</div>
</div>
<!-- 自送货-卡车 -->
<div class="dest-content-bulk" id="pickup-bulk-truck">
<div class="form-group">
<div class="form-label"><span class="required">*</span>预计到达时间</div>
<div class="form-content">
<input type="datetime-local" class="form-input" placeholder="请选择预计到达时间" style="min-width:280px;">
</div>
</div>
<div class="form-group">
<div class="form-label">车牌号</div>
<div class="form-content">
<input type="text" class="form-input" placeholder="请输入车牌号" style="min-width:200px;">
</div>
</div>
<div class="form-group">
<div class="form-label">司机姓名</div>
<div class="form-content">
<input type="text" class="form-input" placeholder="请输入司机姓名" style="min-width:200px;">
</div>
</div>
<div class="form-group">
<div class="form-label">司机电话</div>
<div class="form-content">
<input type="tel" class="form-input" placeholder="请输入司机电话" style="min-width:200px;">
</div>
</div>
</div>
<div class="form-group">
<div class="form-label"><span class="required">*</span>收货仓</div>
<div class="form-content">
<label class="radio-label"><input type="radio" name="bulk-wh"> 义乌仓</label>
<label class="radio-label"><input type="radio" name="bulk-wh"> 深圳仓</label>
<label class="radio-label"><input type="radio" name="bulk-wh"> 青岛仓</label>
<label class="radio-label"><input type="radio" name="bulk-wh"> 上海仓</label>
<label class="radio-label"><input type="radio" name="bulk-wh"> 宁波仓</label>
<label class="radio-label"><input type="radio" name="bulk-wh"> 厦门仓</label>
</div>
</div>
<div class="form-group">
<div class="form-label"><span class="required">*</span>渠道</div>
<div class="form-content">
<select class="form-select" style="width:220px;">
<option value="">请选择渠道</option>
<option>美线普货专线</option>
<option>美线敏感货专线</option>
<option>美线快线</option>
<option>美线FBA直送</option>
</select>
</div>
</div>
<div class="form-group">
<div class="form-label"><span class="required">*</span>买单/退税</div>
<div class="form-content">
<label class="radio-label"><input type="radio" name="bulk-tax"> 买单</label>
<label class="radio-label"><input type="radio" name="bulk-tax"> 退税</label>
</div>
</div>
<div class="form-group">
<div class="form-label">是否整柜</div>
<div class="form-content">
<label class="radio-label"><input type="radio" name="bulk-container"> 整柜</label>
<label class="radio-label"><input type="radio" name="bulk-container"> 散货</label>
</div>
</div>
<div class="form-group">
<div class="form-label"><span class="required">*</span>是否商检</div>
<div class="form-content">
<label class="radio-label"><input type="radio" name="bulk-inspect"> 是</label>
<label class="radio-label"><input type="radio" name="bulk-inspect"> 否</label>
</div>
</div>
<div class="form-group">
<div class="form-label">船期</div>
<div class="form-content">
<div class="date-range">
<input type="date" class="form-input" style="width:160px;">
<span class="date-sep">~</span>
<input type="date" class="form-input" style="width:160px;">
</div>
</div>
</div>
<div class="form-group" style="align-items:flex-start;">
<div class="form-label" style="padding-top:6px;">备注NOTE</div>
<div class="form-content">
<textarea class="form-textarea" placeholder="请填写订单备注信息(选填)"></textarea>
</div>
</div>
</div>
</div>
<!-- 货物明细表格 -->
<div class="card" style="margin-bottom:12px;">
<div style="padding:16px 16px 12px;border-bottom:1px solid #f0f0f0;">
<div style="font-size:14px;font-weight:500;color:#262626;margin-bottom:12px;">货物明细</div>
<!-- 上传/下载按钮行 -->
<div style="display:flex;gap:10px;align-items:center;margin-bottom:10px;">
<label class="upload-link" style="cursor:pointer;">
<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="17 8 12 3 7 8"/><line x1="12" y1="3" x2="12" y2="15"/></svg>
上传 Excel<input type="file" accept=".xlsx,.xls" style="display:none;" onchange="alert('已选择:'+(this.files[0]?.name||''))">
</label>
<a class="download-link" href="#">
<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></svg>
下载模板
</a>
</div>
</div>
<div style="overflow-x:auto;">
<table style="width:100%;border-collapse:collapse;font-size:12px;" id="bulk-table">
<thead>
<tr style="background:#fafafa;">
<th style="width:36px;padding:10px 8px;border-bottom:1px solid #f0f0f0;text-align:center;"><input type="checkbox" id="bulk-check-all" onchange="toggleBulkAll(this)"></th>
<th style="padding:10px 8px;border-bottom:1px solid #f0f0f0;white-space:nowrap;font-weight:500;color:#8c8c8c;text-align:left;">序号</th>
<th style="padding:10px 8px;border-bottom:1px solid #f0f0f0;white-space:nowrap;font-weight:500;color:#8c8c8c;text-align:left;">目的仓类型</th>
<th style="padding:10px 8px;border-bottom:1px solid #f0f0f0;white-space:nowrap;font-weight:500;color:#8c8c8c;text-align:left;">亚马逊仓代码</th>
<th style="padding:10px 8px;border-bottom:1px solid #f0f0f0;white-space:nowrap;font-weight:500;color:#8c8c8c;text-align:left;">货件编号(ShipmentID)</th>
<th style="padding:10px 8px;border-bottom:1px solid #f0f0f0;white-space:nowrap;font-weight:500;color:#8c8c8c;text-align:left;">跟踪编号(ReferenceID)</th>
<th style="padding:10px 8px;border-bottom:1px solid #f0f0f0;white-space:nowrap;font-weight:500;color:#8c8c8c;text-align:left;">收件人</th>
<th style="padding:10px 8px;border-bottom:1px solid #f0f0f0;white-space:nowrap;font-weight:500;color:#8c8c8c;text-align:left;">收件地址</th>
<th style="padding:10px 8px;border-bottom:1px solid #f0f0f0;white-space:nowrap;font-weight:500;color:#8c8c8c;text-align:left;">产品英文名称</th>
<th style="padding:10px 8px;border-bottom:1px solid #f0f0f0;white-space:nowrap;font-weight:500;color:#8c8c8c;text-align:left;">FNSKU</th>
<th style="padding:10px 8px;border-bottom:1px solid #f0f0f0;white-space:nowrap;font-weight:500;color:#8c8c8c;text-align:left;">ASIN</th>
<th style="padding:10px 8px;border-bottom:1px solid #f0f0f0;white-space:nowrap;font-weight:500;color:#8c8c8c;text-align:left;">单品申报价值(USD)</th>
<th style="padding:10px 8px;border-bottom:1px solid #f0f0f0;white-space:nowrap;font-weight:500;color:#8c8c8c;text-align:left;">总件数</th>
<th style="padding:10px 8px;border-bottom:1px solid #f0f0f0;white-space:nowrap;font-weight:500;color:#8c8c8c;text-align:left;">箱数</th>
<th style="padding:10px 8px;border-bottom:1px solid #f0f0f0;white-space:nowrap;font-weight:500;color:#8c8c8c;text-align:left;">每箱件数</th>
<th style="padding:10px 8px;border-bottom:1px solid #f0f0f0;white-space:nowrap;font-weight:500;color:#8c8c8c;text-align:left;">长(cm)</th>
<th style="padding:10px 8px;border-bottom:1px solid #f0f0f0;white-space:nowrap;font-weight:500;color:#8c8c8c;text-align:left;">宽(cm)</th>
<th style="padding:10px 8px;border-bottom:1px solid #f0f0f0;white-space:nowrap;font-weight:500;color:#8c8c8c;text-align:left;">高(cm)</th>
<th style="padding:10px 8px;border-bottom:1px solid #f0f0f0;white-space:nowrap;font-weight:500;color:#8c8c8c;text-align:left;">毛重(kg)</th>
<th style="padding:10px 8px;border-bottom:1px solid #f0f0f0;white-space:nowrap;font-weight:500;color:#8c8c8c;text-align:left;">是否带电</th>
<th style="padding:10px 8px;border-bottom:1px solid #f0f0f0;white-space:nowrap;font-weight:500;color:#8c8c8c;text-align:left;">是否含液体</th>
<th style="padding:10px 8px;border-bottom:1px solid #f0f0f0;white-space:nowrap;font-weight:500;color:#8c8c8c;text-align:left;">是否纯电</th>
<th style="padding:10px 8px;border-bottom:1px solid #f0f0f0;white-space:nowrap;font-weight:500;color:#8c8c8c;text-align:left;">海关品名</th>
<th style="padding:10px 8px;border-bottom:1px solid #f0f0f0;white-space:nowrap;font-weight:500;color:#8c8c8c;text-align:left;">备注</th>
</tr>
</thead>
<tbody id="bulk-tbody">
<tr id="bulk-empty-row">
<td colspan="24" style="padding:40px 0;text-align:center;color:#bfbfbf;">
<div style="font-size:28px;margin-bottom:8px;">📦</div>
<div style="font-size:13px;">暂无数据,请点击「添加行」或导入 Excel</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- 添加行/删除行按钮 — 表格下方 -->
<div style="padding:12px 16px;border-top:1px solid #f0f0f0;display:flex;gap:10px;align-items:center;">
<button class="btn-outline-blue" onclick="addBulkRow()">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg>
添加行
</button>
<button class="btn-outline-red" onclick="deleteBulkRows()">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="3 6 5 6 21 6"/><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/></svg>
删除行
</button>
</div>
</div>
<!-- 底部按钮 -->
<div class="form-footer">
<div class="footer-tips"><span class="tip-icon">⚠</span>提交前请确认货物明细信息无误</div>
<div style="display:flex;gap:8px;">
<button class="btn btn-default" onclick="alert('已保存草稿')">保存草稿</button>
<button class="btn btn-primary" onclick="alert('提交成功!')">提交订单</button>
</div>
</div>
</div>
<!-- PAGE: 快速下单 -->
<div class="page-content" id="page-quick">
<div class="page-header">
<h1 class="page-title">快速下单</h1>
</div>
<div class="card">
<div class="card-header" style="flex-direction:column;align-items:flex-start;border-bottom:1px solid #f0f0f0;">
<div class="card-title">客户下单</div>
<div class="card-subtitle" style="line-height:1.6;">
快速下单:只需输入来源目的仓产品SKU/箱数,即可下单<br>
每行数据提交成功后给客户生成一个订单,支持一行订单多个产品SKU情况
</div>
</div>
<div class="card-body">
<div class="quick-table-wrap">
<table class="quick-table">
<thead>
<tr>
<th style="width:140px;">选择渠道</th>
<th style="width:160px;">目的仓</th>
<th style="width:160px;">操作</th>
<th>产品信息:产品SKU/箱数</th>
</tr>
</thead>
<tbody id="quick-rows">
<tr class="quick-row">
<td>
<div class="select-wrap">
<select class="form-select">
<option value="">请选择</option>
<option>美线普货专线</option>
<option>美线敏感货专线</option>
<option>美线快线</option>
<option>美线FBA直送</option>
</select>
</div>
</td>
<td>
<label class="radio-label" style="display:block;margin-bottom:4px;"><input type="radio" name="dest1"> FBA</label>
<label class="radio-label" style="display:block;margin-bottom:4px;"><input type="radio" name="dest1"> 海外仓</label>
<label class="radio-label" style="display:block;"><input type="radio" name="dest1"> 私人仓</label>
</td>
<td>
<a href="javascript:void(0)" onclick="addProduct(this)" style="color:#1677ff;font-size:13px;">+ 添加产品</a>
<a href="javascript:void(0)" onclick="delQuickRow(this)" style="color:#ff4d4f;font-size:13px;margin-left:10px;">- 删除本行</a>
</td>
<td>
<div class="product-line">
<input type="text" class="form-input" placeholder="产品SKU" style="width:140px;">
<input type="number" class="form-input" value="0" style="width:80px;text-align:center;">
<a href="javascript:void(0)" onclick="delProduct(this)" style="color:#ff4d4f;font-size:13px;">- 删除此产品</a>
</div>
</td>
</tr>
</tbody>
</table>
</div>
<div style="margin-top:12px;">
<button class="btn btn-ghost" onclick="addQuickRow()" style="font-size:13px;">+ 新增一行</button>
</div>
<div style="text-align:center;margin-top:24px;">
<button class="btn btn-primary" onclick="submitQuickOrder()">提交订单</button>
</div>
</div>
</div>
</div>
<!-- ========== PAGE: 应付账单 ========== -->
<div class="page-content" id="page-biz-fee">
<div class="breadcrumb"><a href="#" onclick="switchPage('order');return false;">首页</a><span class="sep">/</span><span class="current">账单结果</span></div>
<div class="page-title" style="margin-bottom:16px;">账单列表</div>
<div class="card">
<div class="table-wrap-simple" style="overflow-x:auto;">
<table class="data-table" id="finance-table">
<thead>
<tr>
<th>#</th>
<th>操作</th>
<th>状态</th>
<th>单据状态</th>
<th>账单编号</th>
<th>创建日期</th>
<th>币种</th>
<th>汇率</th>
<th>开票日期</th>
<th>最近一次收款日期</th>
<th>账期(天)</th>
<th>应付金额</th>
<th>已付金额</th>
<th>备注</th>
<th>总金额</th>
<th>退票结果日</th>
<th>退款到期日</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td><a href="#" class="link-primary" onclick="viewBillDetail('Y2407069');return false;">查看明细</a></td>
<td><span class="tag tag-success">已确认</span></td>
<td><span class="tag tag-success">已确认</span></td>
<td>Y2407069</td>
<td>2024-07-04 13:53:13</td>
<td>CNY</td>
<td>7.26</td>
<td>—</td>
<td>2024-08-03</td>
<td>30</td>
<td>10160.5</td>
<td>0</td>
<td>0</td>
<td>2024-08-03</td>
<td>2024-07-04</td>
</tr>
<tr>
<td>2</td>
<td><a href="#" class="link-primary" onclick="viewBillDetail('Y2506061');return false;">查看明细</a></td>
<td><span class="tag tag-error">已作废</span></td>
<td><span class="tag tag-error">已作废</span></td>
<td>Y2506061</td>
<td>2025-05-02 09:09:57</td>
<td>CNY</td>
<td>7.11</td>
<td>—</td>
<td>2025-06-01</td>
<td>30</td>
<td>267769.75</td>
<td>0</td>
<td>0</td>
<td>2025-06-08</td>
<td>2025-05-09</td>
</tr>
<tr>
<td>3</td>
<td><a href="#" class="link-primary" onclick="viewBillDetail('Y2508075');return false;">查看明细</a></td>
<td><span class="tag tag-error">已作废</span></td>
<td><span class="tag tag-error">已作废</span></td>
<td>Y2508075</td>
<td>2025-05-09 09:50:08</td>
<td>CNY</td>
<td>7.11</td>
<td>—</td>
<td>—</td>
<td>30</td>
<td>913.6</td>
<td>0</td>
<td>0</td>
<td>2025-06-08</td>
<td>2025-05-09</td>
</tr>
<tr>
<td>4</td>
<td><a href="#" class="link-primary" onclick="viewBillDetail('Y2508047');return false;">查看明细</a></td>
<td><span class="tag tag-success">已确认</span></td>
<td><span class="tag tag-success">已确认</span></td>
<td>Y2508047</td>
<td>2025-05-05 16:13:05</td>
<td>CNY</td>
<td>7.22</td>
<td>—</td>
<td>—</td>
<td>30</td>
<td>202858</td>
<td>0</td>
<td>0</td>
<td>2025-06-05</td>
<td>2025-05-05</td>
</tr>
<tr>
<td>5</td>
<td><a href="#" class="link-primary" onclick="viewBillDetail('Y2507049');return false;">查看明细</a></td>
<td><span class="tag tag-success">已确认</span></td>
<td><span class="tag tag-success">已确认</span></td>
<td>Y2507049</td>
<td>2025-07-08 10:50:18</td>
<td>CNY</td>
<td>7.2</td>
<td>—</td>
<td>—</td>
<td>30</td>
<td>202881.6</td>
<td>0</td>
<td>0</td>
<td>2025-08-07</td>
<td>2025-07-08</td>
</tr>
</tbody>
</table>
</div>
<div class="pagination-bar">
<div class="pagination-info"><span>共 <strong>11</strong> 条</span></div>
<div class="pagination-ctrl">
<button class="page-btn" disabled>上一页</button>
<button class="page-btn active">1</button>
<button class="page-btn">2</button>
<button class="page-btn">3</button>
<button class="page-btn">4</button>
<button class="page-btn">下一页</button>
</div>
</div>
</div>
</div>
<!-- ========== PAGE: 账单明细 ========== -->
<div class="page-content" id="page-bill-detail">
<div class="breadcrumb"><a href="#" onclick="switchPage('biz-fee');return false;">首页</a><span class="sep">/</span><a href="#" onclick="switchPage('biz-fee');return false;">应付账单</a><span class="sep">/</span><span class="current">账单明细</span></div>
<div class="page-title" style="margin-bottom:16px;">账单明细 <span id="detail-bill-no" style="font-size:14px;color:#8c8c8c;font-weight:400;margin-left:8px;"></span></div>
<div class="card">
<div class="table-wrap-simple" style="overflow-x:auto;">
<table class="data-table" id="bill-detail-table">
<thead>
<tr>
<th>#</th>
<th>入仓单号</th>
<th>SKU</th>
<th>渠道</th>
<th>FBA仓</th>
<th>FBA编号</th>
<th>箱数</th>
<th>毛重</th>
<th>体积</th>
<th>费用类型</th>
<th>币种</th>
<th>账单金额</th>
<th>入仓时间</th>
<th>出仓时间</th>
<th>结算结束日</th>
<th>结算起始日</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>PCHWK24061161</td>
<td>海外仓日用</td>
<td>洛杉矶普船海卡包税</td>
<td>—</td>
<td>—</td>
<td>6</td>
<td>106</td>
<td>0.292</td>
<td>运费</td>
<td>人民币</td>
<td>0</td>
<td>2024-06-11</td>
<td>—</td>
<td>2024-06-11</td>
<td>2024-07-11</td>
</tr>
<tr>
<td>2</td>
<td>BYHWK24061281</td>
<td>海外仓日用</td>
<td>美森加班海卡包税</td>
<td>—</td>
<td>—</td>
<td>37</td>
<td>654</td>
<td>1.799</td>
<td>运费</td>
<td>人民币</td>
<td>0</td>
<td>2024-06-12</td>
<td>—</td>
<td>2024-06-12</td>
<td>2024-07-12</td>
</tr>
<tr>
<td>3</td>
<td>PCHWK24061739</td>
<td>海外仓日用</td>
<td>洛杉矶普船海卡包税</td>
<td>—</td>
<td>—</td>
<td>2</td>
<td>36</td>
<td>0.097</td>
<td>运费</td>
<td>人民币</td>
<td>0</td>
<td>2024-06-17</td>
<td>—</td>
<td>2024-06-17</td>
<td>2024-07-17</td>
</tr>
<tr>
<td>4</td>
<td>PCHWK24062923</td>
<td>海外仓日用</td>
<td>洛杉矶普船海卡包税</td>
<td>—</td>
<td>—</td>
<td>2</td>
<td>36</td>
<td>0.097</td>
<td>运费</td>
<td>人民币</td>
<td>0</td>
<td>2024-06-29</td>
<td>—</td>
<td>2024-07-01</td>
<td>2024-07-31</td>
</tr>
<tr>
<td>5</td>
<td>PCHWK24062971</td>
<td>小白快递</td>
<td>洛杉矶普船海卡包税</td>
<td>—</td>
<td>—</td>
<td>5</td>
<td>1462</td>
<td>8.77</td>
<td>叉车费</td>
<td>人民币</td>
<td>130</td>
<td>2024-06-29</td>
<td>—</td>
<td>2024-07-03</td>
<td>2024-08-02</td>
</tr>
<tr>
<td>6</td>
<td>PCHWK24063021</td>
<td>小白快递</td>
<td>洛杉矶普船海卡包税</td>
<td>—</td>
<td>—</td>
<td>29</td>
<td>1175</td>
<td>7.045</td>
<td>运费</td>
<td>人民币</td>
<td>6932.5</td>
<td>2024-06-11</td>
<td>—</td>
<td>2024-07-04</td>
<td>2024-08-03</td>
</tr>
<tr>
<td>7</td>
<td>PCHWK24062971</td>
<td>小白快递</td>
<td>洛杉矶普船海卡包税</td>
<td>—</td>
<td>—</td>
<td>5</td>
<td>1462</td>
<td>8.77</td>
<td>运费</td>
<td>人民币</td>
<td>9503</td>
<td>2024-06-29</td>
<td>—</td>
<td>2024-07-04</td>
<td>2024-08-03</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<!-- ========== PAGE: 公司信息 ========== -->
<div class="page-content" id="page-company">
<div class="breadcrumb"><a href="#" onclick="switchPage('order');return false;">首页</a><span class="sep">/</span><span class="current">公司信息</span></div>
<div class="page-title" style="margin-bottom:16px;">公司信息</div>
<div class="info-tabs">
<button class="info-tab active" onclick="setInfoTab(this,'basic')">企业基本信息</button>
<button class="info-tab" onclick="setInfoTab(this,'contact')">联系信息</button>
<button class="info-tab" onclick="setInfoTab(this,'qualify')">资质文件</button>
</div>
<!-- Tab 1: 企业基本信息 -->
<div class="info-tab-content active" id="info-basic">
<div class="info-card">
<div class="info-section-title">企业基本信息</div>
<div class="info-grid">
<div class="info-row">
<div class="info-label">公司名称</div>
<div class="info-value">华远贸易有限公司</div>
</div>
<div class="info-row">
<div class="info-label">统一信用代码</div>
<div class="info-value">91110108MA01XXXXXX</div>
</div>
<div class="info-row">
<div class="info-label">企业类型</div>
<div class="info-value">有限责任公司</div>
</div>
<div class="info-row">
<div class="info-label">注册地</div>
<div class="info-value">北京市朝阳区</div>
</div>
<div class="info-row">
<div class="info-label">成立日期</div>
<div class="info-value">2018-06-15</div>
</div>
<div class="info-row">
<div class="info-label">注册资本</div>
<div class="info-value">500万人民币</div>
</div>
<div class="info-row">
<div class="info-label"><span style="color:#ff4d4f;margin-right:4px;">*</span>法人姓名</div>
<div class="info-value">李明华</div>
</div>
<div class="info-row">
<div class="info-label"><span style="color:#ff4d4f;margin-right:4px;">*</span>法人电话</div>
<div class="info-value">139****8866</div>
</div>
</div>
</div>
</div>
<!-- Tab 2: 联系信息 -->
<div class="info-tab-content" id="info-contact">
<div class="info-card">
<div class="info-section-title">联系信息</div>
<div class="info-grid">
<div class="info-row">
<div class="info-label">联系人</div>
<div class="info-value">张伟</div>
</div>
<div class="info-row">
<div class="info-label">手机</div>
<div class="info-value">138****6789</div>
</div>
<div class="info-row">
<div class="info-label">邮箱</div>
<div class="info-value">zhangwei@huayuan.com</div>
</div>
<div class="info-row">
<div class="info-label">微信</div>
<div class="info-value">zhangwei_hy</div>
</div>
<div class="info-row" style="grid-column: 1 / -1;">
<div class="info-label">地址</div>
<div class="info-value">北京市朝阳区建国路88号</div>
</div>
</div>
</div>
</div>
<!-- Tab 3: 资质文件 -->
<div class="info-tab-content" id="info-qualify">
<div class="info-card">
<div class="info-section-title">资质文件</div>
<table class="info-doc-table">
<thead>
<tr>
<th>文件类型</th>
<th>状态</th>
<th>有效期</th>
<th style="width:80px;">操作</th>
</tr>
</thead>
<tbody>
<tr>
<td>营业执照</td>
<td><span class="doc-status">已验证</span></td>
<td>2028-06-15</td>
<td><button class="doc-btn" onclick="viewDoc('营业执照','2028-06-15','已验证')">查看</button></td>
</tr>
<tr>
<td>法人身份证</td>
<td><span class="doc-status">已验证</span></td>
<td>2030-01-01</td>
<td><button class="doc-btn" onclick="viewDoc('法人身份证','2030-01-01','已验证')">查看</button></td>
</tr>
<tr>
<td>货代资质证书</td>
<td><span class="doc-status">已验证</span></td>
<td>2027-03-01</td>
<td><button class="doc-btn" onclick="viewDoc('货代资质证书','2027-03-01','已验证')">查看</button></td>
</tr>
<tr>
<td>银行开户许可证</td>
<td><span class="doc-status">已验证</span></td>
<td>长期有效</td>
<td><button class="doc-btn" onclick="viewDoc('银行开户许可证','长期有效','已验证')">查看</button></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<!-- ========== PAGE: 我的信息 ========== -->
<div class="page-content" id="page-profile">
<div class="breadcrumb"><a href="#" onclick="switchPage('order');return false;">首页</a><span class="sep">/</span><span class="current">我的信息</span></div>
<div class="page-title" style="margin-bottom:16px;">我的信息</div>
<!-- 账户余额 -->
<div class="balance-card">
<div class="balance-info">
<div class="balance-label" data-i18n="m_balance">账户余额</div>
<div class="balance-amount">¥ <span id="profileBalance">12,850.00</span></div>
</div>
<div class="balance-actions">
<button class="balance-detail-btn" onclick="openBalanceDetails()"><i class="fas fa-list-ul"></i>余额明细</button>
<button class="btn btn-primary" onclick="openTopup()" style="font-size:13px;padding:8px 22px;">充值</button>
</div>
</div>
<div class="info-tabs">
<button class="info-tab active" onclick="setProfileTab(this,'base')">基本信息</button>
<button class="info-tab" onclick="setProfileTab(this,'password')">修改密码</button>
</div>
<!-- Tab 1: 基本信息 -->
<div class="info-tab-content active" id="profile-base">
<div class="info-card">
<div class="info-section-title" style="display:flex;justify-content:space-between;align-items:center;">
基本信息
<button class="btn btn-primary" id="btn-edit-profile" onclick="toggleEditProfile(true)" style="font-size:12px;padding:6px 18px;">编辑</button>
</div>
<!-- 查看模式 -->
<div class="info-grid" id="profile-view">
<div class="info-row">
<div class="info-label">用户名</div>
<div class="info-value">zhangwei</div>
</div>
<div class="info-row">
<div class="info-label">真实姓名</div>
<div class="info-value">张伟</div>
</div>
<div class="info-row">
<div class="info-label">手机号</div>
<div class="info-value">138****6789</div>
</div>
<div class="info-row">
<div class="info-label">邮箱</div>
<div class="info-value">zhangwei@huayuan.com</div>
</div>
<div class="info-row">
<div class="info-label">微信</div>
<div class="info-value">zhangwei_hy</div>
</div>
<div class="info-row">
<div class="info-label">所属公司</div>
<div class="info-value">华远贸易有限公司</div>
</div>
</div>
<!-- 编辑模式 -->
<div class="info-grid" id="profile-edit" style="display:none;">
<div class="info-row">
<div class="info-label">用户名</div>
<div class="info-value"><input type="text" class="form-input" value="zhangwei" style="width:260px;"></div>
</div>
<div class="info-row">
<div class="info-label">真实姓名</div>
<div class="info-value"><input type="text" class="form-input" value="张伟" style="width:260px;"></div>
</div>
<div class="info-row">
<div class="info-label">手机号</div>
<div class="info-value"><input type="text" class="form-input" value="138****6789" style="width:260px;"></div>
</div>
<div class="info-row">
<div class="info-label">邮箱</div>
<div class="info-value"><input type="text" class="form-input" value="zhangwei@huayuan.com" style="width:260px;"></div>
</div>
<div class="info-row">
<div class="info-label">微信</div>
<div class="info-value"><input type="text" class="form-input" value="zhangwei_hy" style="width:260px;"></div>
</div>
<div class="info-row">
<div class="info-label">所属公司</div>
<div class="info-value"><input type="text" class="form-input" value="华远贸易有限公司" style="width:260px;" disabled></div>
</div>
</div>
<div id="profile-actions" style="margin-top:20px;padding-top:16px;border-top:1px solid #f0f0f0;display:none;">
<button class="btn btn-primary" onclick="saveProfile()">保存修改</button>
<button class="btn btn-default" onclick="cancelEditProfile()" style="margin-left:10px;">取消</button>
</div>
</div>
</div>
<!-- Tab 2: 修改密码 -->
<div class="info-tab-content" id="profile-password">
<div class="info-card" style="max-width:480px;">
<div class="info-section-title">修改密码</div>
<div class="form-row" style="margin-bottom:16px;">
<label class="form-label" style="width:100px;">当前密码</label>
<input type="password" class="form-input" placeholder="请输入当前密码" style="width:260px;">
</div>
<div class="form-row" style="margin-bottom:16px;">
<label class="form-label" style="width:100px;">新密码</label>
<input type="password" class="form-input" placeholder="请输入新密码" style="width:260px;">
</div>
<div class="form-row" style="margin-bottom:16px;">
<label class="form-label" style="width:100px;">确认新密码</label>
<input type="password" class="form-input" placeholder="请再次输入新密码" style="width:260px;">
</div>
<div style="margin-top:20px;padding-top:16px;border-top:1px solid #f0f0f0;">
<button class="btn btn-primary" onclick="changePassword()">确认修改</button>
</div>
</div>
</div>
</div>
<!-- ========== MODAL: 资质文件查看 ========== -->
<div class="modal-overlay" id="doc-modal" onclick="if(event.target===this)closeDocModal()">
<div class="modal-box">
<div class="modal-header">
<div class="modal-title" id="doc-modal-title">资质文件查看</div>
<button class="modal-close" onclick="closeDocModal()">&times;</button>
</div>
<div class="modal-body">
<div class="doc-preview">
<div style="width:100%;height:320px;background:linear-gradient(135deg,#f5f7fa,#e8ecf1);border-radius:12px;display:flex;align-items:center;justify-content:center;flex-direction:column;gap:12px;">
<div style="font-size:64px;">📄</div>
<div style="font-size:14px;color:#8c8c8c;" id="doc-placeholder-text">文件预览</div>
</div>
</div>
<div class="doc-info">
<div class="doc-info-row"><div class="doc-info-label">文件类型</div><div class="doc-info-value" id="doc-modal-type">-</div></div>
<div class="doc-info-row"><div class="doc-info-label">验证状态</div><div class="doc-info-value" id="doc-modal-status">-</div></div>
<div class="doc-info-row"><div class="doc-info-label">有效期</div><div class="doc-info-value" id="doc-modal-expire">-</div></div>
<div class="doc-info-row"><div class="doc-info-label">上传时间</div><div class="doc-info-value" id="doc-modal-upload">2024-03-10</div></div>
</div>
</div>
<div class="modal-footer">
<button class="btn btn-default" onclick="closeDocModal()">关闭</button>
<button class="btn btn-primary" onclick="alert('开始下载文件...')">下载文件</button>
</div>
</div>
</div>
<!-- ========== MODAL: 新建退货入库单 ========== -->
<div class="modal-overlay" id="return-in-modal" onclick="if(event.target===this)closeReturnInModal()">
<div class="modal-box modal-wide">
<div class="modal-header">
<div class="modal-title">新建退货入库单</div>
<button class="modal-close" onclick="closeReturnInModal()">&times;</button>
</div>
<div class="modal-body">
<div class="form-section">
<div class="modal-section-title">基础信息</div>
<div style="display:grid;grid-template-columns:1fr 1fr;gap:16px 24px;">
<div class="form-group">
<div class="form-label"><span class="required">*</span>仓库</div>
<div class="form-content">
<select class="form-input" style="width:100%;">
<option value="">请选择</option>
<option>FBA ONT8</option>
<option>FBA CLT2</option>
<option>FBA MEM1</option>
<option>DE Frankfurt</option>
<option>FBA IND9</option>
</select>
</div>
</div>
<div class="form-group">
<div class="form-label">移除订单Order ID</div>
<div class="form-content"><input type="text" class="form-input" placeholder="请输入移除订单Order ID" style="width:100%;"></div>
</div>
<div class="form-group" style="grid-column:1 / -1;">
<div class="form-label">备注</div>
<div class="form-content">
<textarea class="form-textarea" placeholder="请输入备注" style="width:100%;height:70px;max-width:100%;"></textarea>
<div style="text-align:right;font-size:12px;color:#bfbfbf;">0/255</div>
</div>
</div>
</div>
</div>
<div class="form-section">
<div class="modal-section-title">产品信息</div>
<div class="product-table-wrap">
<table class="product-table" id="return-in-product-table">
<thead>
<tr>
<th><span class="required">*</span>物流承运商</th>
<th><span class="required">*</span>物流跟踪号</th>
<th><span class="required">*</span>SKU</th>
<th><span class="required">*</span>产品名称</th>
<th><span class="required">*</span>FNSKU</th>
<th><span class="required">*</span>退件数量</th>
<th>操作</th>
</tr>
</thead>
<tbody id="return-in-product-tbody">
<tr>
<td><input type="text" class="cell-input" placeholder="物流承运商"></td>
<td><input type="text" class="cell-input" placeholder="物流跟踪号"></td>
<td>—</td>
<td>—</td>
<td><input type="text" class="cell-input" placeholder="FNSKU"></td>
<td><input type="number" class="cell-input" placeholder="数量"></td>
<td><button class="btn-text" style="color:#ff4d4f;" onclick="this.closest('tr').remove()">删除</button></td>
</tr>
</tbody>
</table>
</div>
<div style="display:flex;justify-content:center;margin:12px 0;">
<button class="btn-text" onclick="alert('选择产品')"><span style="font-size:14px;">◎</span> 选择产品</button>
</div>
<button class="btn-ghost" onclick="addReturnInProductRow()">+ 添加产品</button>
</div>
</div>
<div class="modal-footer">
<button class="btn-ghost" onclick="closeReturnInModal()">取消</button>
<button class="btn btn-primary" onclick="submitReturnInModal()">提交</button>
<button class="btn btn-default" onclick="saveReturnInDraft()">保存草稿</button>
</div>
</div>
</div>
</div>
</main>
<!-- 右侧信息栏 -->
<aside id="dashRight" class="dash-right hidden lg:flex flex-col">
<div class="dash-right-card">
<h4 data-i18n="right_account_title">账户信息</h4>
<div class="dash-account">
<div class="dash-account-avatar" id="dashAvatar">C</div>
<div>
<div class="dash-account-name" id="dashAccountName">虫虫出海客户</div>
<div class="dash-account-type" data-i18n="right_account_type">企业客户</div>
</div>
</div>
</div>
<div class="dash-right-card">
<h4 data-i18n="right_stat_title">数据概览</h4>
<div class="dash-stat-row">
<span class="dash-stat-label" data-i18n="right_stat_progress">进行中订单</span>
<span class="dash-stat-value" id="statProgress">0</span>
</div>
<div class="dash-stat-row">
<span class="dash-stat-label" data-i18n="right_stat_done">已完成订单</span>
<span class="dash-stat-value" id="statDone">0</span>
</div>
<div class="dash-stat-row">
<span class="dash-stat-label" data-i18n="right_stat_month">本月下单</span>
<span class="dash-stat-value" id="statMonth">0</span>
</div>
</div>
<div class="dash-right-card">
<h4 data-i18n="right_help_title">帮助与支持</h4>
<div class="dash-help-item" onclick="showToast(t('right_help_cs_toast'))">
<i class="fas fa-headset"></i><span data-i18n="right_help_cs">联系客服</span>
</div>
<div class="dash-help-item" onclick="showToast(t('right_help_faq_toast'))">
<i class="fas fa-question-circle"></i><span data-i18n="right_help_faq">常见问题</span>
</div>
<div class="dash-help-item" onclick="showToast(t('right_help_quote_toast'))">
<i class="fas fa-tag"></i><span data-i18n="right_help_quote">获取报价</span>
</div>
</div>
<div class="dash-tip">
<i class="fas fa-lightbulb"></i>
<span data-i18n="right_tip_text">提交订单后,专属客户经理将在 24 小时内与您联系,确认运输方案与报价。</span>
</div>
</aside>
</div>
</div>
</section>
<!-- 充值弹窗 -->
<div id="topupModal" class="topup-overlay hidden" onclick="if(event.target===this)closeTopup()">
<div class="topup-modal">
<div class="topup-head">
<h3 data-i18n="dash_topup_title">账户充值</h3>
<button class="topup-close" onclick="closeTopup()" aria-label="关闭">&times;</button>
</div>
<div class="topup-body">
<div class="topup-amount-label" data-i18n="dash_topup_amount">充值金额</div>
<div class="topup-amount-input">
<span class="cur">¥</span>
<input type="number" id="topupAmount" value="100" min="1" step="1">
</div>
<div class="topup-presets" id="topupPresets">
<button class="topup-preset" onclick="setTopupAmount(50,this)">¥50</button>
<button class="topup-preset active" onclick="setTopupAmount(100,this)">¥100</button>
<button class="topup-preset" onclick="setTopupAmount(200,this)">¥200</button>
<button class="topup-preset" onclick="setTopupAmount(500,this)">¥500</button>
</div>
<div class="topup-methods">
<button class="topup-method active" data-method="wechat" onclick="selectPay('wechat',this)"><i class="fab fa-weixin"></i><span data-i18n="dash_pay_wechat">微信支付</span></button>
<button class="topup-method" data-method="alipay" onclick="selectPay('alipay',this)"><i class="fab fa-alipay"></i><span data-i18n="dash_pay_alipay">支付宝</span></button>
</div>
<div class="topup-qr">
<div class="topup-qr-box"><i id="topupQrIcon" class="fab fa-weixin"></i></div>
<div class="topup-qr-tip" id="topupQrTip" data-i18n="dash_topup_scan_wechat">请使用微信扫一扫完成支付</div>
</div>
</div>
<div class="topup-foot">
<button class="topup-cancel" onclick="closeTopup()" data-i18n="dash_cancel">取消</button>
<button class="topup-confirm" onclick="confirmTopup()" data-i18n="dash_topup_confirm">确认充值</button>
</div>
</div>
</div>
<!-- 余额明细弹窗 -->
<div id="balanceDetailsModal" class="topup-overlay hidden" onclick="if(event.target===this)closeBalanceDetails()">
<div class="topup-modal balance-detail-modal">
<div class="topup-head">
<h3>余额明细</h3>
<button class="topup-close" onclick="closeBalanceDetails()" aria-label="关闭">&times;</button>
</div>
<div class="topup-body">
<div class="balance-detail-summary">
<div class="balance-summary-item">
<div class="balance-summary-label">当前余额</div>
<div class="balance-summary-value">¥12,850.00</div>
</div>
<div class="balance-summary-item">
<div class="balance-summary-label">本月收入</div>
<div class="balance-summary-value income">+¥8,000.00</div>
</div>
<div class="balance-summary-item">
<div class="balance-summary-label">本月支出</div>
<div class="balance-summary-value expense">-¥3,260.00</div>
</div>
</div>
<div class="balance-detail-filter">
<div class="balance-quick-periods" id="balanceQuickPeriods">
<button class="balance-period-btn" onclick="setBalancePeriod('today',this)">今天</button>
<button class="balance-period-btn" onclick="setBalancePeriod(7,this)">近7天</button>
<button class="balance-period-btn" onclick="setBalancePeriod('month',this)">本月</button>
<button class="balance-period-btn active" onclick="setBalancePeriod(30,this)">近30天</button>
</div>
<div class="balance-date-range">
<input type="date" id="balanceStartDate" aria-label="开始日期">
<span>至</span>
<input type="date" id="balanceEndDate" aria-label="结束日期">
<button class="balance-filter-action" onclick="filterBalanceDetails()">查询</button>
<button class="balance-filter-action balance-filter-reset" onclick="resetBalanceFilter()">重置</button>
</div>
</div>
<div class="balance-detail-table-wrap">
<table class="balance-detail-table">
<thead><tr><th>交易时间</th><th>业务类型</th><th>关联单号</th><th>收支金额</th><th>交易后余额</th><th>状态</th></tr></thead>
<tbody id="balanceDetailRows">
<tr data-balance-date="2026-07-28"><td>2026-07-28 14:32</td><td>账户充值</td><td>CZ20260728001</td><td class="amount-in">+¥5,000.00</td><td>¥12,850.00</td><td><span class="balance-status">已完成</span></td></tr>
<tr data-balance-date="2026-07-25"><td>2026-07-25 10:18</td><td>运费扣款</td><td>BY2607250086</td><td class="amount-out">-¥1,860.00</td><td>¥7,850.00</td><td><span class="balance-status">已完成</span></td></tr>
<tr data-balance-date="2026-07-20"><td>2026-07-20 16:45</td><td>账户充值</td><td>CZ20260720003</td><td class="amount-in">+¥3,000.00</td><td>¥9,710.00</td><td><span class="balance-status">已完成</span></td></tr>
<tr data-balance-date="2026-07-16"><td>2026-07-16 09:26</td><td>运费扣款</td><td>BY2607160032</td><td class="amount-out">-¥1,400.00</td><td>¥6,710.00</td><td><span class="balance-status">已完成</span></td></tr>
<tr class="balance-empty-row" id="balanceEmptyRow" hidden><td colspan="6">所选时间范围内暂无余额明细</td></tr>
</tbody>
</table>
</div>
<div class="balance-detail-note" id="balanceDetailNote">仅展示近 30 天余额流水</div>
</div>
</div>
</div>
<div class="sea-edit-overlay" id="sea-order-edit-modal" hidden onclick="if(event.target===this)closeSeaOrderEditor()">
<div class="sea-edit-dialog" role="dialog" aria-modal="true" aria-labelledby="sea-order-edit-title">
<div class="sea-edit-header"><h2 id="sea-order-edit-title">编辑订单</h2><button class="sea-edit-close" type="button" onclick="closeSeaOrderEditor()" aria-label="关闭"><i class="fas fa-times"></i></button></div>
<div class="sea-edit-body"><form id="sea-order-edit-form" class="space-y-4"></form></div>
<div class="sea-edit-footer"><button type="button" class="px-5 py-2 rounded-lg border border-gray-200 text-gray-600" onclick="closeSeaOrderEditor()">取消</button><button type="submit" form="sea-order-edit-form" class="btn-primary text-white font-semibold px-5 py-2 rounded-lg">保存修改</button></div>
</div>
</div>
<script>
// 工作台交互
function setDashUser(name) {
const display = name ? name : '虫虫出海客户';
const topEl = document.getElementById('dashUserName');
if (topEl) topEl.textContent = 'Hi, ' + display;
const accEl = document.getElementById('dashAccountName');
if (accEl) accEl.textContent = display;
const avEl = document.getElementById('dashAvatar');
if (avEl) avEl.textContent = display.charAt(0).toUpperCase();
}
const BUILTIN_VIEWS = ['Home', 'Procurement', 'Truck', 'Pallet', 'Orders'];
const seaOrders = {
Procurement: [{ id:'proc-demo-1', orderNo:'HC202608120001', customer:'王经理', summary:'家居用品', createdAt:'2026-08-12 09:20', status:'处理中', fields:{'采购品类':'家居用品','商品规格':'白色 / 45×35×28cm','商品链接':'https://example.com/product','采购数量':'120','预算单价($)':'8.50','收货地址':'洛杉矶海外仓 A 区','联系人':'王经理','联系电话':'13800000000','订单备注':'采购完成后统一送仓','国内快递公司':'顺丰速运','国内运单号':'SF1234567890','海外快递公司':'UPS','海外运单号':'1Z999AA10123456784'} }],
Truck: [{ id:'truck-demo-1', orderNo:'HC202608120002', customer:'李经理', summary:'洛杉矶港 → 安大略仓', createdAt:'2026-08-12 10:05', status:'待确认', carrier:'待分配', fields:{'运输类型':'港口提柜','起运地':'洛杉矶港','目的地':'安大略仓','起运详细地址':'Pier 400','目的详细地址/码头/仓号':'Ontario WH-02','柜型':'40HQ','件数':'680','总重量(kg)':'12600','总体积(m³)':'62','预算总价':'3800','联系人':'李经理','联系方式':'13900000000','要求时间':'2026-08-16'} }],
Pallet: [{ id:'pallet-demo-1', orderNo:'HC202608120003', customer:'陈经理', summary:'工业市 → 达拉斯', createdAt:'2026-08-12 11:30', status:'处理中', carrier:'美西拼载运输', fields:{'运输方式':'拼车','是否打盘':'是','运输类型':'仓到仓','起运地':'工业市','目的地':'达拉斯','起运详细地址':'Industry WH-08','目的详细地址/码头/仓号':'Dallas WH-03','柜型':'LTL','件数':'48','总重量(kg)':'920','总体积(m³)':'6.8','预算总价':'1500','联系人':'陈经理','联系方式':'13700000000','要求时间':'2026-08-18'} }]
};
const seaPageState = { Procurement: { orderNo:'', customer:'', status:'' }, Truck: { orderNo:'', customer:'', status:'' }, Pallet: { orderNo:'', customer:'', status:'' } };
let editingSeaOrder = null;
function seaBusinessSlug(type) { return {Procurement:'procurement',Truck:'truck',Pallet:'pallet'}[type] || 'procurement'; }
function seaBusinessName(type) { return {Procurement:'海外采购',Truck:'美国本土卡',Pallet:'美本土散板'}[type] || '海外采购'; }
function escapeSeaOrderHtml(value) { return String(value == null ? '' : value).replace(/[&<>"']/g, char => ({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;'}[char])); }
function showSeaBusinessPage(type) { const page=document.querySelector('.sea-business-page[data-business="'+type+'"]'),panel=document.querySelector('[data-order-panel="'+type+'"]');document.querySelectorAll('[data-business-detail]').forEach(detail=>detail.hidden=true);if(page)page.classList.remove('hidden');if(panel)panel.hidden=true;renderSeaOrders(type);window.scrollTo(0,0); }
function showSeaBusinessOrderForm(type) { const page=document.querySelector('.sea-business-page[data-business="'+type+'"]'),panel=document.querySelector('[data-order-panel="'+type+'"]');document.querySelectorAll('[data-business-detail]').forEach(detail=>detail.hidden=true);if(page)page.classList.add('hidden');if(panel)panel.hidden=false;window.scrollTo(0,0); }
function openSeaBusiness(type, action, el) { const link=el&&el.classList?.contains('dash-nav-link')?el:document.querySelector('.dash-nav-link[data-business="'+type+'"]');dashNavigate(type,link);if(action==='new')showSeaBusinessOrderForm(type);else showSeaBusinessPage(type); }
function seaOrderCells(type, order) { const fields=order.fields||{},total=fields['预算总价']||((Number(fields['总重量(kg)']||0)*0.3).toFixed(2));if(type==='Procurement')return [order.orderNo,fields['采购品类'],fields['商品规格'],fields['采购数量'],fields['预算单价($)']?('$'+fields['预算单价($)']):'-',order.status];if(type==='Truck')return [order.orderNo,fields['运输类型'],fields['起运地'],fields['目的地'],fields['柜型'],fields['总重量(kg)']?Number(fields['总重量(kg)']).toLocaleString():'-',total?('$'+total):'-',fields['要求时间'],order.status];return [order.orderNo,fields['运输方式'],fields['是否打盘'],fields['运输类型'],fields['起运地'],fields['目的地'],fields['总重量(kg)']?Number(fields['总重量(kg)']).toLocaleString():'-',total?('$'+total):'-',fields['要求时间'],order.status]; }
function renderSeaOrders(type) { const body=document.getElementById('sea-'+seaBusinessSlug(type)+'-orders-body');if(!body)return;const state=seaPageState[type],rows=seaOrders[type].filter(order=>{const fields=order.fields||{},route=((fields['起运地']||'')+' '+(fields['目的地']||'')).toLowerCase();return (!state.orderNo||order.orderNo.toLowerCase().includes(state.orderNo))&&(!state.customer||route.includes(state.customer))&&(!state.status||order.status===state.status)});const colspan=type==='Procurement'?7:(type==='Truck'?10:11);body.innerHTML=rows.length?rows.map(order=>{const actions='<div class="sea-table-actions"><button type="button" class="sea-table-action" onclick="showSeaOrderDetail(\''+type+'\',\''+order.id+'\')">查看</button><button type="button" class="sea-table-action" onclick="openSeaOrderEditor(\''+type+'\',\''+order.id+'\')">编辑</button></div>';const cells=seaOrderCells(type,order).map(value=>'<td>'+escapeSeaOrderHtml(value||'-')+'</td>').join('');return type==='Procurement'?'<tr>'+cells+'<td>'+actions+'</td></tr>':'<tr><td>'+actions+'</td>'+cells+'</tr>';}).join(''):'<tr><td class="sea-order-empty" colspan="'+colspan+'">暂无'+seaBusinessName(type)+'头程订单</td></tr>'; }
function collectSeaOrderFields(form) { const fields={};new FormData(form).forEach((value,key)=>{fields[key]=String(value)});return fields; }
function fillSeaOrderForm(form, fields) { Object.entries(fields||{}).forEach(([name,value])=>{const controls=form.querySelectorAll('[name="'+CSS.escape(name)+'"]');controls.forEach(control=>{if(control.type==='radio'||control.type==='checkbox')control.checked=control.value===value;else control.value=value})}); }
function openSeaOrderEditor(type, id) { const order=seaOrders[type].find(item=>item.id===id),source=document.querySelector('[data-order-form="'+type+'"]'),form=document.getElementById('sea-order-edit-form');if(!order||!source||!form)return;editingSeaOrder={type,id};form.innerHTML=source.innerHTML;form.querySelectorAll('[type="submit"],button[type="button"]').forEach(button=>button.closest('.flex.gap-3')?.remove()||button.remove());fillSeaOrderForm(form,order.fields);document.getElementById('sea-order-edit-title').textContent='编辑'+seaBusinessName(type)+'订单';document.getElementById('sea-order-edit-modal').hidden=false;document.body.style.overflow='hidden'; }
function closeSeaOrderEditor() { document.getElementById('sea-order-edit-modal').hidden=true;document.getElementById('sea-order-edit-form').innerHTML='';editingSeaOrder=null;document.body.style.overflow=''; }
function saveSeaOrderEdit(event) { event.preventDefault();if(!editingSeaOrder)return;const {type,id}=editingSeaOrder,order=seaOrders[type].find(item=>item.id===id),form=event.currentTarget;if(!order||!form.reportValidity())return;order.fields=collectSeaOrderFields(form);order.customer=order.fields['联系人']||order.fields['联系方式']||'客户';order.summary=type==='Procurement'?(order.fields['采购品类']||'采购订单'):((order.fields['起运地']||'')+' → '+(order.fields['目的地']||'')).replace(/^\s*→\s*$/,'运输订单');closeSeaOrderEditor();renderSeaOrders(type);showToast('订单修改已保存'); }
function showSeaOrderDetail(type, id) { const order=seaOrders[type].find(item=>item.id===id),page=document.querySelector('.sea-business-page[data-business="'+type+'"]'),panel=document.querySelector('[data-order-panel="'+type+'"]'),detail=document.querySelector('[data-business-detail="'+type+'"]');if(!order||!detail)return;if(page)page.classList.add('hidden');if(panel)panel.hidden=true;const fields=order.fields||{};detail.querySelectorAll('[data-detail-content]').forEach(element=>{const key=element.dataset.detailContent;let value=key==='orderNo'?order.orderNo:key==='status'?order.status:key==='carrier'?(order.carrier||'待分配'):key==='预算总价'&&fields['采购数量']&&fields['预算单价($)']?('$'+(Number(fields['采购数量'])*Number(fields['预算单价($)'])).toFixed(2)):(fields[key]||'-');if(key==='预算单价($)'&&value!=='-')value='$'+value;element.textContent=value});const currentStep=({'待确认':0,'处理中':1,'已完成':2})[order.status]??0;detail.querySelectorAll('.sea-progress-step').forEach((step,index)=>{step.classList.toggle('is-current',index===currentStep);step.classList.toggle('is-done',index<currentStep)});detail.hidden=false;window.scrollTo(0,0); }
function querySeaOrders(type) { const page=document.querySelector('.sea-business-page[data-business="'+type+'"]');if(!page)return;seaPageState[type]={orderNo:(page.querySelector('[data-filter="orderNo"]')?.value||'').trim().toLowerCase(),customer:(page.querySelector('[data-filter="route"]')?.value||page.querySelector('[data-filter="customer"]')?.value||'').trim().toLowerCase(),status:page.querySelector('[data-filter="status"]')?.value||''};renderSeaOrders(type); }
function resetSeaOrders(type) { const page=document.querySelector('.sea-business-page[data-business="'+type+'"]');if(page)page.querySelectorAll('[data-filter]').forEach(control=>control.value='');seaPageState[type]={orderNo:'',customer:'',status:''};renderSeaOrders(type); }
const CLIENT_PAGES = ['order', 'bulk', 'quick', 'labeling-list', 'labeling', 'storage-transfer-list', 'storage-transfer-create', 'storage-transfer-detail', 'cargo-disposal-list', 'cargo-disposal-create', 'cargo-disposal-detail', 'return-relabel-list', 'return-relabel-create', 'return-relabel-detail', 'inbound', 'delivery', 'biz-fee', 'company', 'profile'];
let currentGenericEl = null;
function dashNavigate(name, el) {
document.querySelectorAll('#workbench .dash-view').forEach(v => v.classList.add('hidden'));
if (BUILTIN_VIEWS.indexOf(name) !== -1) {
const view = document.getElementById('dashView' + name);
if (view) view.classList.remove('hidden');
if (['Procurement','Truck','Pallet'].includes(name)) showSeaBusinessPage(name);
} else if (CLIENT_PAGES.indexOf(name) !== -1) {
const cv = document.getElementById('dashViewClient');
if (cv) cv.classList.remove('hidden');
if (typeof switchPage === 'function') switchPage(name);
} else {
if (el) { populateGeneric(el); currentGenericEl = el; }
const gv = document.getElementById('dashViewGeneric');
if (gv) gv.classList.remove('hidden');
}
document.querySelectorAll('.dash-nav-link').forEach(l => l.classList.remove('active'));
if (el) el.classList.add('active');
const right = document.getElementById('dashRight');
if (right) right.classList.toggle('dash-right-hidden', name !== 'Home');
window.scrollTo(0, 0);
closeDashSidebar();
}
function goHome() {
const link = document.querySelector('.dash-nav-link[data-view="Home"]');
dashNavigate('Home', link);
}
function toggleDashGroup(header) {
header.classList.toggle('collapsed');
const sub = header.parentElement.querySelector('.dash-menu-sub');
if (sub) sub.classList.toggle('collapsed');
}
function populateGeneric(el) {
const icon = el.getAttribute('data-gicon') || 'fa-layer-group';
const title = t(el.getAttribute('data-gtitle') || 'm_coming');
const sub = t(el.getAttribute('data-gsub') || 'm_coming_sub');
const ic = document.getElementById('genericIcon');
if (ic) ic.className = 'fas ' + icon;
const ti = document.getElementById('genericTitle');
if (ti) ti.textContent = title;
const su = document.getElementById('genericSub');
if (su) su.textContent = sub;
}
function toggleDashSidebar() {
const sb = document.getElementById('dashSidebar');
const ov = document.getElementById('dashOverlay');
if (!sb) return;
const open = sb.classList.toggle('open');
if (ov) ov.classList.toggle('show', open);
document.body.style.overflow = open ? 'hidden' : '';
}
function closeDashSidebar() {
const sb = document.getElementById('dashSidebar');
const ov = document.getElementById('dashOverlay');
if (sb) sb.classList.remove('open');
if (ov) ov.classList.remove('show');
document.body.style.overflow = '';
}
function openOrder(type) {
openSeaBusiness(type,'new',null);
}
function doLogout() {
showToast(t('toast_logout'));
setTimeout(() => { window.location.href = 'index.html'; }, 700);
}
// 订单表单提交
document.querySelectorAll('.order-form').forEach(form => {
form.addEventListener('submit', function(e) {
e.preventDefault();
const type=this.dataset.orderForm;
if(type&&seaOrders[type]){const fields=collectSeaOrderFields(this),now=new Date(),customer=fields['联系人']||fields['联系方式']||'客户',summary=type==='Procurement'?(fields['采购品类']||'采购订单'):((fields['起运地']||'')+' → '+(fields['目的地']||'')).replace(/^\s*→\s*$/,'运输订单');seaOrders[type].unshift({id:type+'-'+now.getTime(),orderNo:'HC'+String(now.getFullYear())+String(now.getMonth()+1).padStart(2,'0')+String(now.getDate()).padStart(2,'0')+String(seaOrders[type].length+1).padStart(4,'0'),customer,summary,fields,carrier:'待分配',createdAt:now.getFullYear()+'-'+String(now.getMonth()+1).padStart(2,'0')+'-'+String(now.getDate()).padStart(2,'0')+' '+String(now.getHours()).padStart(2,'0')+':'+String(now.getMinutes()).padStart(2,'0'),status:'待确认'});}
showToast(t('toast_order_ok'));
this.reset();
if(type&&seaOrders[type])setTimeout(()=>showSeaBusinessPage(type),400);else setTimeout(() => goHome(), 1200);
});
});
document.getElementById('sea-order-edit-form')?.addEventListener('submit', saveSeaOrderEdit);
// ====== 多语言 i18n ======
const i18n = {
zh: {
dash_home_link: "返回官网", dash_logout: "退出登录",
dash_topup: "充值", m_balance: "账户余额", dash_topup_title: "账户充值", dash_topup_amount: "充值金额", dash_topup_confirm: "确认充值", dash_pay_wechat: "微信支付", dash_pay_alipay: "支付宝", dash_topup_scan_wechat: "请使用微信扫一扫完成支付", dash_topup_scan_alipay: "请使用支付宝扫一扫完成支付", dash_topup_ok: "已提交充值 ¥{amt}({method}),请尽快完成支付",
dash_welcome_title: "选择业务,快速下单", dash_welcome_sub: "请选择您需要的业务类型,填写信息后提交订单,我们将尽快为您安排。",
dash_biz1_title: "海外采购", dash_biz1_desc: "采购代购 · 验货质检 · 集中发货",
dash_biz2_title: "美国本土卡", dash_biz2_desc: "港口提柜 · 仓到仓 · 仓到门",
dash_biz3_title: "美本土散板", dash_biz3_desc: "拼车拼载 · 打盘服务 · 灵活派送",
dash_start: "开始下单", dash_back: "返回业务选择", dash_submit: "提交订单", dash_cancel: "取消",
po_title: "海外采购下单", po_category: "采购品类", po_category_ph: "如:家居用品 / 3C 配件",
po_spec: "商品规格", po_spec_ph: "如:尺寸 / 颜色 / 材质", po_link: "商品链接", po_link_ph: "https://",
po_qty: "采购数量", po_qty_ph: "0", po_price: "预算单价", po_price_ph: "0.00",
po_address: "收货地址", po_address_ph: "请输入收货地址", po_contact: "联系人", po_contact_ph: "请输入联系人姓名",
po_phone: "联系电话", po_phone_ph: "请输入联系电话", po_note: "订单备注", po_note_ph: "其他需求说明(选填)",
tk_title: "美国本土卡下单",
pl_title: "美本土散板下单", pl_method: "运输方式", pl_method_pool: "拼车", pl_method_priority: "优先拼载",
pl_palletize: "是否打盘", pl_yes: "是", pl_no: "否",
ts_type: "运输类型", ts_type_port: "港口提柜", ts_type_w2w: "仓到仓", ts_type_w2d: "仓到门",
ts_origin: "起运地", ts_origin_ph: "城市 / 港口 / 州", ts_dest: "目的地", ts_dest_ph: "城市 / 州",
ts_origin_addr: "详细地址", ts_origin_addr_ph: "街道 / 门牌",
ts_dest_addr: "详细地址 / 码头 / 仓号", ts_dest_addr_ph: "地址 / 码头 / 仓号",
cargo_title: "货物信息", cargo_container: "柜型", cargo_container_ltl: "散货/托盘",
cargo_pieces: "件数", cargo_weight: "总重量 (kg)", cargo_volume: "总体积 (m³)",
req_time: "要求时间", contact_title: "联系人信息", contact_name: "联系人", contact_name_ph: "请输入联系人姓名", contact_phone: "联系方式", contact_phone_ph: "电话 / 微信 / 邮箱",
toast_logout: "已退出登录", toast_order_ok: "订单提交成功,我们将尽快为您安排!",
dash_menu_main: "主导航", dash_menu_overview: "业务总览", dash_menu_proc: "海外采购",
dash_menu_truck: "美国本土卡", dash_menu_pallet: "美本土散板", dash_menu_orders: "我的订单",
dash_orders_empty: "暂无订单", dash_orders_hint: "您还没有提交任何订单,前往「业务总览」选择服务开始下单吧。",
right_account_title: "账户信息", right_account_type: "企业客户",
right_stat_title: "数据概览", right_stat_progress: "进行中订单", right_stat_done: "已完成订单", right_stat_month: "本月下单",
right_help_title: "帮助与支持", right_help_cs: "联系客服", right_help_faq: "常见问题", right_help_quote: "获取报价",
right_help_cs_toast: "客服热线:400-XXX-XXXX(工作日 9:00-18:00)", right_help_faq_toast: "常见问题页面即将上线", right_help_quote_toast: "报价顾问将尽快与您联系",
right_tip_text: "提交订单后,专属客户经理将在 24 小时内与您联系,确认运输方案与报价。"
},
en: {
dash_home_link: "Back to Site", dash_logout: "Log Out",
dash_topup: "Top Up", m_balance: "Account Balance", dash_topup_title: "Account Top Up", dash_topup_amount: "Amount", dash_topup_confirm: "Confirm Top Up", dash_pay_wechat: "WeChat Pay", dash_pay_alipay: "Alipay", dash_topup_scan_wechat: "Scan with WeChat to pay", dash_topup_scan_alipay: "Scan with Alipay to pay", dash_topup_ok: "Top up ¥{amt} ({method}) submitted, please complete payment",
dash_welcome_title: "Choose a Service to Order", dash_welcome_sub: "Select the service you need, fill in the details, and submit your order — we will arrange it for you shortly.",
dash_biz1_title: "Overseas Sourcing", dash_biz1_desc: "Sourcing · Inspection · Consolidation",
dash_biz2_title: "US Domestic Trucking", dash_biz2_desc: "Port Pickup · Warehouse-to-Warehouse · Door-to-Door",
dash_biz3_title: "US Pallet Break", dash_biz3_desc: "Pooled Freight · Palletizing · Flexible Delivery",
dash_start: "Start Order", dash_back: "Back to Services", dash_submit: "Submit Order", dash_cancel: "Cancel",
po_title: "Overseas Sourcing Order", po_category: "Product Category", po_category_ph: "e.g. Home goods / 3C accessories",
po_spec: "Specs", po_spec_ph: "e.g. Size / Color / Material", po_link: "Product Link", po_link_ph: "https://",
po_qty: "Quantity", po_qty_ph: "0", po_price: "Budget Unit Price", po_price_ph: "0.00",
po_address: "Shipping Address", po_address_ph: "Enter shipping address", po_contact: "Contact Name", po_contact_ph: "Enter contact name",
po_phone: "Contact Phone", po_phone_ph: "Enter phone number", po_note: "Order Notes", po_note_ph: "Other requirements (optional)",
tk_title: "US Domestic Trucking Order",
pl_title: "US Pallet Break Order", pl_method: "Transport Mode", pl_method_pool: "Pooled", pl_method_priority: "Priority Load",
pl_palletize: "Palletize?", pl_yes: "Yes", pl_no: "No",
ts_type: "Transport Type", ts_type_port: "Port Pickup", ts_type_w2w: "Warehouse to Warehouse", ts_type_w2d: "Warehouse to Door",
ts_origin: "Origin", ts_origin_ph: "City / Port / State", ts_dest: "Destination", ts_dest_ph: "City / State",
ts_origin_addr: "Detailed Address", ts_origin_addr_ph: "Street / Number",
ts_dest_addr: "Detailed Address / Pier / WH No.", ts_dest_addr_ph: "Address / Pier / WH No.",
cargo_title: "Cargo Info", cargo_container: "Container Type", cargo_container_ltl: "Loose / Pallet",
cargo_pieces: "Pieces", cargo_weight: "Total Weight (kg)", cargo_volume: "Total Volume (m³)",
req_time: "Required By", contact_title: "Contact Info", contact_name: "Contact Person", contact_name_ph: "Enter contact name", contact_phone: "Contact Number", contact_phone_ph: "Phone / WeChat / Email",
toast_logout: "Logged out", toast_order_ok: "Order submitted! We will arrange it for you shortly.",
dash_menu_main: "Main Menu", dash_menu_overview: "Overview", dash_menu_proc: "Overseas Sourcing",
dash_menu_truck: "US Trucking", dash_menu_pallet: "US Pallet Break", dash_menu_orders: "My Orders",
dash_orders_empty: "No Orders Yet", dash_orders_hint: "You haven't placed any orders yet. Go to Overview to start a new order.",
right_account_title: "Account", right_account_type: "Enterprise Client",
right_stat_title: "Overview", right_stat_progress: "In Progress", right_stat_done: "Completed", right_stat_month: "This Month",
right_help_title: "Help & Support", right_help_cs: "Contact Support", right_help_faq: "FAQ", right_help_quote: "Get a Quote",
right_help_cs_toast: "Support Hotline: 400-XXX-XXXX (Mon-Fri 9:00-18:00)", right_help_faq_toast: "FAQ page coming soon", right_help_quote_toast: "A quoting specialist will contact you shortly",
right_tip_text: "After you submit an order, your dedicated account manager will contact you within 24 hours to confirm the shipping plan and quote."
},
es: {
dash_home_link: "Volver al sitio", dash_logout: "Cerrar sesión",
dash_topup: "Recargar", m_balance: "Saldo de cuenta", dash_topup_title: "Recarga de cuenta", dash_topup_amount: "Monto", dash_topup_confirm: "Confirmar recarga", dash_pay_wechat: "WeChat Pay", dash_pay_alipay: "Alipay", dash_topup_scan_wechat: "Escanea con WeChat para pagar", dash_topup_scan_alipay: "Escanea con Alipay para pagar", dash_topup_ok: "Recarga de ¥{amt} ({method}) enviada, completa el pago",
dash_welcome_title: "Elige un servicio para pedir", dash_welcome_sub: "Selecciona el servicio que necesitas, completa los datos y envía tu pedido; lo gestionaremos lo antes posible.",
dash_biz1_title: "Abastecimiento en el extranjero", dash_biz1_desc: "Compras · Inspección · Consolidación",
dash_biz2_title: "Transporte por camión en EE.UU.", dash_biz2_desc: "Recogida en puerto · Almacén a almacén · Puerta a puerta",
dash_biz3_title: "Despaletizado en EE.UU.", dash_biz3_desc: "Carga compartida · Paletizado · Entrega flexible",
dash_start: "Iniciar pedido", dash_back: "Volver a servicios", dash_submit: "Enviar pedido", dash_cancel: "Cancelar",
po_title: "Pedido de abastecimiento", po_category: "Categoría del producto", po_category_ph: "ej. Artículos para el hogar / Accesorios 3C",
po_spec: "Especificaciones", po_spec_ph: "ej. Tamaño / Color / Material", po_link: "Enlace del producto", po_link_ph: "https://",
po_qty: "Cantidad", po_qty_ph: "0", po_price: "Precio unitario estimado", po_price_ph: "0.00",
po_address: "Dirección de envío", po_address_ph: "Ingresa la dirección de envío", po_contact: "Persona de contacto", po_contact_ph: "Ingresa el nombre de contacto",
po_phone: "Teléfono de contacto", po_phone_ph: "Ingresa el teléfono", po_note: "Notas del pedido", po_note_ph: "Otros requisitos (opcional)",
tk_title: "Pedido de camión en EE.UU.",
pl_title: "Pedido de despaletizado en EE.UU.", pl_method: "Modo de transporte", pl_method_pool: "Carga compartida", pl_method_priority: "Carga prioritaria",
pl_palletize: "¿Paletizar?", pl_yes: "Sí", pl_no: "No",
ts_type: "Tipo de transporte", ts_type_port: "Recogida en puerto", ts_type_w2w: "Almacén a almacén", ts_type_w2d: "Almacén a puerta",
ts_origin: "Origen", ts_origin_ph: "Ciudad / Puerto / Estado", ts_dest: "Destino", ts_dest_ph: "Ciudad / Estado",
ts_origin_addr: "Dirección detallada", ts_origin_addr_ph: "Calle / Número",
ts_dest_addr: "Dirección / Muelle / N.º almacén", ts_dest_addr_ph: "Dirección / Muelle / N.º almacén",
cargo_title: "Información de carga", cargo_container: "Tipo de contenedor", cargo_container_ltl: "Carga suelta / Paleta",
cargo_pieces: "Piezas", cargo_weight: "Peso total (kg)", cargo_volume: "Volumen total (m³)",
req_time: "Fecha requerida", contact_title: "Información de contacto", contact_name: "Persona de contacto", contact_name_ph: "Ingrese el nombre de contacto", contact_phone: "Número de contacto", contact_phone_ph: "Teléfono / WeChat / Email",
toast_logout: "Sesión cerrada", toast_order_ok: "¡Pedido enviado! Lo gestionaremos lo antes posible.",
dash_menu_main: "Menú principal", dash_menu_overview: "Resumen", dash_menu_proc: "Abastecimiento",
dash_menu_truck: "Camión en EE.UU.", dash_menu_pallet: "Despaletizado", dash_menu_orders: "Mis pedidos",
dash_orders_empty: "Sin pedidos", dash_orders_hint: "Aún no has enviado pedidos. Ve a Resumen para empezar uno nuevo.",
right_account_title: "Cuenta", right_account_type: "Cliente Empresarial",
right_stat_title: "Resumen", right_stat_progress: "En Progreso", right_stat_done: "Completados", right_stat_month: "Este Mes",
right_help_title: "Ayuda y Soporte", right_help_cs: "Contactar Soporte", right_help_faq: "Preguntas Frecuentes", right_help_quote: "Obtener Cotización",
right_help_cs_toast: "Línea de soporte: 400-XXX-XXXX (Lun-Vie 9:00-18:00)", right_help_faq_toast: "Página de preguntas próximamente", right_help_quote_toast: "Un especialista en cotización te contactará pronto",
right_tip_text: "Después de enviar el pedido, tu ejecutivo de cuenta te contactará en 24 horas para confirmar el plan de envío y la cotización."
}
};
let currentLang = localStorage.getItem('cc_lang') || 'zh';
function t(key) {
return (i18n[currentLang] && i18n[currentLang][key] !== undefined) ? i18n[currentLang][key] : key;
}
function applyLanguage(lang) {
if (!i18n[lang]) lang = 'zh';
currentLang = lang;
const langAttr = lang === 'zh' ? 'zh-CN' : (lang === 'es' ? 'es-MX' : 'en');
document.documentElement.setAttribute('lang', langAttr);
document.querySelectorAll('[data-i18n]').forEach(el => {
const k = el.getAttribute('data-i18n');
if (i18n[lang][k] !== undefined) el.textContent = i18n[lang][k];
});
document.querySelectorAll('[data-i18n-ph]').forEach(el => {
const k = el.getAttribute('data-i18n-ph');
if (i18n[lang][k] !== undefined) el.setAttribute('placeholder', i18n[lang][k]);
});
document.querySelectorAll('#langSwitcherDash [data-lang]').forEach(b => {
b.classList.toggle('active', b.getAttribute('data-lang') === lang);
});
if (currentGenericEl) populateGeneric(currentGenericEl);
try { localStorage.setItem('cc_lang', lang); } catch (e) {}
}
document.querySelectorAll('#langSwitcherDash [data-lang]').forEach(b => {
b.addEventListener('click', () => applyLanguage(b.getAttribute('data-lang')));
});
// Toast 提示
function showToast(message) {
const toast = document.getElementById('toast');
const toastMessage = document.getElementById('toastMessage');
toastMessage.textContent = message;
toast.classList.remove('opacity-0', 'pointer-events-none', '-translate-y-4');
toast.classList.add('opacity-100', 'translate-y-0');
setTimeout(() => {
toast.classList.add('opacity-0', 'pointer-events-none', '-translate-y-4');
toast.classList.remove('opacity-100', 'translate-y-0');
}, 3000);
}
// 充值弹窗
function openTopup() {
document.getElementById('topupModal').classList.remove('hidden');
}
function closeTopup() {
document.getElementById('topupModal').classList.add('hidden');
}
function openBalanceDetails() {
document.getElementById('balanceDetailsModal').classList.remove('hidden');
if (!document.getElementById('balanceStartDate').value) {
const defaultPeriod = document.querySelector('#balanceQuickPeriods .balance-period-btn.active');
setBalancePeriod(30, defaultPeriod);
}
}
function closeBalanceDetails() {
document.getElementById('balanceDetailsModal').classList.add('hidden');
}
function formatBalanceDate(date) {
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
return year + '-' + month + '-' + day;
}
function setBalancePeriod(period, el) {
const end = new Date();
const start = new Date(end);
if (period === 'today') {
// 开始和结束均为今天
} else if (period === 'month') {
start.setDate(1);
} else {
start.setDate(end.getDate() - Number(period) + 1);
}
document.getElementById('balanceStartDate').value = formatBalanceDate(start);
document.getElementById('balanceEndDate').value = formatBalanceDate(end);
document.querySelectorAll('#balanceQuickPeriods .balance-period-btn').forEach(btn => btn.classList.remove('active'));
if (el) el.classList.add('active');
filterBalanceDetails();
}
function filterBalanceDetails() {
const start = document.getElementById('balanceStartDate').value;
const end = document.getElementById('balanceEndDate').value;
if (start && end && start > end) {
showToast('开始日期不能晚于结束日期');
return;
}
let visibleCount = 0;
document.querySelectorAll('#balanceDetailRows tr[data-balance-date]').forEach(row => {
const date = row.dataset.balanceDate;
const visible = (!start || date >= start) && (!end || date <= end);
row.hidden = !visible;
if (visible) visibleCount++;
});
document.getElementById('balanceEmptyRow').hidden = visibleCount !== 0;
document.getElementById('balanceDetailNote').textContent = start || end
? (start || '最早') + ' 至 ' + (end || '今天') + ',共 ' + visibleCount + ' 条流水'
: '全部时间,共 ' + visibleCount + ' 条流水';
}
function resetBalanceFilter() {
const buttons = document.querySelectorAll('#balanceQuickPeriods .balance-period-btn');
setBalancePeriod(30, buttons[buttons.length - 1]);
}
function setTopupAmount(v, el) {
document.getElementById('topupAmount').value = v;
document.querySelectorAll('#topupPresets .topup-preset').forEach(b => b.classList.remove('active'));
if (el) el.classList.add('active');
}
function selectPay(method, el) {
document.querySelectorAll('.topup-method').forEach(b => b.classList.remove('active'));
if (el) el.classList.add('active');
const icon = document.getElementById('topupQrIcon');
const tip = document.getElementById('topupQrTip');
if (method === 'wechat') {
icon.className = 'fab fa-weixin';
tip.setAttribute('data-i18n', 'dash_topup_scan_wechat');
tip.textContent = t('dash_topup_scan_wechat');
} else {
icon.className = 'fab fa-alipay';
tip.setAttribute('data-i18n', 'dash_topup_scan_alipay');
tip.textContent = t('dash_topup_scan_alipay');
}
}
function confirmTopup() {
const amt = document.getElementById('topupAmount').value || '0';
const method = document.querySelector('.topup-method.active').getAttribute('data-method');
const mp = method === 'wechat' ? t('dash_pay_wechat') : t('dash_pay_alipay');
const num = parseFloat(amt);
if (!isNaN(num)) {
accountBalance += num;
renderBalance();
}
showToast(t('dash_topup_ok').replace('{amt}', amt).replace('{method}', mp));
closeTopup();
}
let accountBalance = 12850.00;
function renderBalance() {
const el = document.getElementById('profileBalance');
if (el) el.textContent = accountBalance.toLocaleString('zh-CN', { minimumFractionDigits: 2, maximumFractionDigits: 2 });
}
// 初始化
document.addEventListener('DOMContentLoaded', function() {
applyLanguage(currentLang);
renderBalance();
// 尝试从官网登录带入用户名(URL ?user=xxx)
const params = new URLSearchParams(window.location.search);
const userParam = params.get('user');
if (userParam) {
setDashUser(decodeURIComponent(userParam));
}
// 默认首页显示右侧信息栏,其他页面隐藏
const right = document.getElementById('dashRight');
if (right) right.classList.remove('dash-right-hidden');
});
applyLanguage(currentLang);
/* ===== 柏悦客户端交互逻辑(原样并入)===== */
// ===== Page switching =====
function switchPage(pageId, clickedEl) {
// Hide all pages
document.querySelectorAll('.page-content').forEach(p => p.classList.remove('active'));
// Show target
const target = document.getElementById('page-' + pageId);
if (target) target.classList.add('active');
// Update sidebar active state
document.querySelectorAll('.nav-item, .nav-sub-item').forEach(el => el.classList.remove('active'));
document.querySelectorAll('.nav-group-header').forEach(h => h.classList.remove('active'));
if (clickedEl) {
clickedEl.classList.add('active');
} else {
// Find by data-page
const el = document.querySelector('[data-page="' + pageId + '"]');
if (el) el.classList.add('active');
}
// For 美线头程下单 sub-items, highlight parent group header
if (pageId === 'order' || pageId === 'bulk' || pageId === 'quick') {
const orderGroup = document.querySelector('.nav-group:first-of-type');
if (orderGroup) {
const header = orderGroup.querySelector('.nav-group-header');
const sub = orderGroup.querySelector('.nav-sub');
if (header) header.classList.add('active');
if (header && !header.classList.contains('expanded')) {
header.classList.add('expanded');
sub.classList.add('expanded');
}
}
}
// For 订单管理 sub-items, expand the group
if (pageId === 'inbound' || pageId === 'delivery') {
const groups = document.querySelectorAll('.nav-group');
groups.forEach(g => {
const header = g.querySelector('.nav-group-header');
const sub = g.querySelector('.nav-sub');
if (header && header.textContent.includes('订单管理')) {
header.classList.add('active');
if (!header.classList.contains('expanded')) {
header.classList.add('expanded');
sub.classList.add('expanded');
}
}
});
}
// For 海外仓下单, expand the group
if (pageId === 'labeling-list' || pageId === 'labeling' || pageId === 'storage-transfer-list' || pageId === 'storage-transfer-create' || pageId === 'storage-transfer-detail' || pageId === 'cargo-disposal-list' || pageId === 'cargo-disposal-create' || pageId === 'cargo-disposal-detail' || pageId === 'return-relabel-list' || pageId === 'return-relabel-create' || pageId === 'return-relabel-detail') {
const groups = document.querySelectorAll('.nav-group');
groups.forEach(g => {
const header = g.querySelector('.nav-group-header');
const sub = g.querySelector('.nav-sub');
if (header && header.textContent.includes('海外仓下单')) {
header.classList.add('active');
if (!header.classList.contains('expanded')) {
header.classList.add('expanded');
sub.classList.add('expanded');
}
}
});
}
}
// ===== 仓储转运单 =====
const STORAGE_TRANSFER_KEY='by_storage_transfer_orders_0805';
const STORAGE_TRANSFER_PAGE_SIZE = 10;
const STORAGE_TRANSFER_SEED = [
{
id: 'storage-transfer-seed-1', orderNo: 'ZY202608050001', inboundNo: 'RK20260805018',
boxCount: 12, warehouse: '美西洛杉矶仓', fbaCode: 'ONT8',
address: '24300 Nandina Ave, Moreno Valley, CA 92551', deliveryMethod: '卡车派送',
expectedArrival: '2026-08-12T10:00', shipmentId: 'FBA18Q7K2L9P', trackingId: 'PRO80465021',
boxId: 'U001-U012', note: '预约送仓', relabel: 'no', tailOrderNo: 'LC202608050001',
relabelOrderNo: '', status: '待处理', createdAt: '2026-08-05 09:20',
cargo: [{ sku: 'SKU-CC-1001', name: '蓝牙耳机套件', boxes: 12, relabelSku: '', requirement: '', fileName: '' }]
},
{
id: 'storage-transfer-seed-2', orderNo: 'ZY202608050002', inboundNo: 'RK20260805023',
boxCount: 8, warehouse: '美东新泽西仓', fbaCode: 'ABE8',
address: '309 Cedar Ln, Florence, NJ 08518', deliveryMethod: '快递派送',
expectedArrival: '2026-08-13T14:00', shipmentId: 'FBA18R2M6X4D', trackingId: '1Z80526039',
boxId: 'E001-E008', note: '', relabel: 'yes', tailOrderNo: 'LC202608050002',
relabelOrderNo: 'HB202608050001', status: '处理中', createdAt: '2026-08-05 14:35',
cargo: [{ sku: 'SKU-CC-2002', name: '手机保护壳', boxes: 8, relabelSku: 'SKU-CC-2002-N', requirement: '覆盖原标签', fileName: 'FNSKU-2002.pdf' }]
}
];
let storageTransferFilteredOrders = null;
let storageTransferCurrentPage = 1;
let storageTransferSubmitting = false;
function cloneStorageTransferSeed() {
return JSON.parse(JSON.stringify(STORAGE_TRANSFER_SEED));
}
function loadStorageTransferOrders() {
try {
const raw = localStorage.getItem(STORAGE_TRANSFER_KEY);
if (!raw) {
const seeded = cloneStorageTransferSeed();
saveStorageTransferOrders(seeded);
return seeded;
}
const parsed = JSON.parse(raw);
if (!Array.isArray(parsed)) throw new Error('仓储转运数据格式无效');
return parsed.filter(order => order && typeof order === 'object');
} catch (error) {
console.warn('读取仓储转运单失败,已使用示例数据。', error);
return cloneStorageTransferSeed();
}
}
function saveStorageTransferOrders(orders) {
if (!Array.isArray(orders)) return false;
try {
localStorage.setItem(STORAGE_TRANSFER_KEY, JSON.stringify(orders));
return true;
} catch (error) {
console.warn('保存仓储转运单失败。', error);
return false;
}
}
function escapeStorageTransferHtml(value) {
return String(value == null ? '' : value)
.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;')
.replace(/"/g, '&quot;').replace(/'/g, '&#39;');
}
function getStorageTransferNavLink() {
return Array.from(document.querySelectorAll('.dash-nav-link')).find(link =>
(link.getAttribute('onclick') || '').includes("dashNavigate('storage-transfer-list', this)")) || null;
}
function navigateStorageTransferPage(pageId) {
dashNavigate(pageId, getStorageTransferNavLink());
}
// ===== 退货换标 =====
const RETURN_RELABEL_KEY = 'by_return_relabel_orders_0812';
const RETURN_RELABEL_PAGE_SIZE = 10;
const RETURN_RELABEL_SEED = [
{id:'return-relabel-seed-1',orderNo:'THHB202608120001',sourceFba:'ONT8',destinationFba:'LAX9',orderId:'RM123456789',carrier:'UPS',trackingNo:'1Z999AA101',reason:'客户退货',relabel:true,labelCase:'Case1',cartonLabel:'carton-label.pdf',skuLabel:'',address:'123 Main St, Los Angeles CA',destinationCode:'LAX9',expectedArrival:'2026-08-16T10:00',returnRemark:'优先处理',tailRemark:'',backendTailOrderNo:'LC202608120001',backendRelabelOrderNo:'HB202608120001',relabelStatus:'换标中',tailStatus:'待入库',createdAt:'2026-08-12 09:15',skus:[{sku:'SKU-A1001',name:'蓝牙耳机套件',fnsku:'X001ABC',quantity:24}]},
{id:'return-relabel-seed-2',orderNo:'THHB202608120002',sourceFba:'ABE8',destinationFba:'ONT8',orderId:'RM987654321',carrier:'FedEx',trackingNo:'794123456',reason:'亚马逊移除',relabel:false,address:'456 Harbor Rd, Ontario CA',destinationCode:'ONT8',expectedArrival:'2026-08-17T14:00',returnRemark:'',tailRemark:'',backendTailOrderNo:'LC202608120002',tailStatus:'已入库待出库',createdAt:'2026-08-12 11:20',skus:[{sku:'SKU-B2002',name:'手机保护壳',fnsku:'X002DEF',quantity:12}]},
{id:'return-relabel-status-seed',orderNo:'THHB202608120003',sourceFba:'CLT2',destinationFba:'ONT8',orderId:'RM555666777',carrier:'UPS',trackingNo:'1ZSTATUS003',reason:'不可售',relabel:true,labelCase:'Case3',cartonLabel:'carton-status.pdf',skuLabel:'sku-status.pdf',relabelStatus:'已完成',tailStatus:'出库中',createdAt:'2026-08-12 12:00',backendTailOrderNo:'LC202608120003',backendRelabelOrderNo:'HB202608120003',address:'789 Trade Center Dr, Charlotte NC',destinationCode:'ONT8',expectedArrival:'2026-08-18T09:30',returnRemark:'状态示例',tailRemark:'按预约送达',skus:[{sku:'SKU-C3003',name:'智能家居配件',fnsku:'X003GHI',quantity:8}]}
];
let returnRelabelFilteredOrders = null, returnRelabelCurrentPage = 1, returnRelabelSubmitting = false, returnRelabelDetailId = null;
function loadReturnRelabelOrders(){try{const raw=localStorage.getItem(RETURN_RELABEL_KEY);if(!raw){return JSON.parse(JSON.stringify(RETURN_RELABEL_SEED));}const parsed=JSON.parse(raw);if(!Array.isArray(parsed)){showToast('退货换标数据格式异常,已恢复示例数据');return JSON.parse(JSON.stringify(RETURN_RELABEL_SEED));}const seedIds=new Set(RETURN_RELABEL_SEED.map(item=>item.id));const validLocal=parsed.filter(item=>{if(!item||typeof item!=='object'||seedIds.has(item.id)||typeof item.id!=='string'||typeof item.orderNo!=='string'||!Array.isArray(item.skus)||!item.skus.length)return false;return item.skus.every(s=>s&&typeof s==='object'&&typeof s.sku==='string'&&typeof s.name==='string'&&typeof s.fnsku==='string'&&Number.isFinite(Number(s.quantity))&&Number(s.quantity)>0);});if(validLocal.length!==parsed.length)showToast('部分退货换标数据异常,已忽略损坏记录');return JSON.parse(JSON.stringify(validLocal.concat(RETURN_RELABEL_SEED)));}catch(e){showToast('读取退货换标数据失败,已恢复示例数据');return JSON.parse(JSON.stringify(RETURN_RELABEL_SEED));}}
function saveReturnRelabelOrders(orders){try{const seedIds=new Set(RETURN_RELABEL_SEED.map(item=>item.id));const localOrders=(Array.isArray(orders)?orders:[]).filter(item=>item&&typeof item==='object'&&!seedIds.has(item.id));localStorage.setItem(RETURN_RELABEL_KEY,JSON.stringify(localOrders));return true;}catch(e){showToast('保存退货换标数据失败');return false;}}
function escapeReturnRelabelHtml(value){return String(value==null?'':value).replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/"/g,'&quot;').replace(/'/g,'&#39;');}
function returnRelabelNav(){return Array.from(document.querySelectorAll('.dash-nav-link')).find(l=>(l.getAttribute('onclick')||'').includes("dashNavigate('return-relabel-list'"))||null;}
function openReturnRelabelList(){dashNavigate('return-relabel-list',returnRelabelNav());}
function openReturnRelabelCreate(){dashNavigate('return-relabel-create',returnRelabelNav());setTimeout(()=>{const form=document.getElementById('return-relabel-form');if(form)form.reset();const body=document.getElementById('return-relabel-sku-body');if(body)body.innerHTML='';addReturnRelabelSkuRow();toggleReturnRelabel();updateFileRequirements();},0);}
function changeReturnRelabelPage(delta){const orders=returnRelabelFilteredOrders===null?loadReturnRelabelOrders():returnRelabelFilteredOrders;const pages=Math.max(1,Math.ceil(orders.length/RETURN_RELABEL_PAGE_SIZE));const next=returnRelabelCurrentPage+Number(delta||0);if(next<1||next>pages)return;returnRelabelCurrentPage=next;renderReturnRelabelList();}
function renderReturnRelabelList(){const body=document.getElementById('return-relabel-list-body');if(!body)return;const orders=returnRelabelFilteredOrders===null?loadReturnRelabelOrders():returnRelabelFilteredOrders;const pages=Math.max(1,Math.ceil(orders.length/RETURN_RELABEL_PAGE_SIZE));returnRelabelCurrentPage=Math.min(returnRelabelCurrentPage,pages);const rows=orders.slice((returnRelabelCurrentPage-1)*RETURN_RELABEL_PAGE_SIZE,returnRelabelCurrentPage*RETURN_RELABEL_PAGE_SIZE);body.innerHTML=rows.length?rows.map(o=>{const skuCount=(o.skus||[]).length;const sku=skuCount?(o.skus[0].sku+(skuCount>1?' 等 '+skuCount+' 项':'')):'—';const qty=(o.skus||[]).reduce((n,s)=>n+Number(s.quantity||0),0);const labelCase=o.relabel?(o.labelCase||'—'):'—';const relabelOrder=o.relabel?(o.backendRelabelOrderNo||'—'):'—';const relabelStatus=o.relabel?(o.relabelStatus||'—'):'—';return '<tr><td>'+escapeReturnRelabelHtml(o.orderNo)+'</td><td>'+escapeReturnRelabelHtml(o.sourceFba)+'</td><td>'+escapeReturnRelabelHtml(o.destinationFba)+'</td><td>'+escapeReturnRelabelHtml(sku)+'</td><td>'+qty+'</td><td>'+(o.relabel?'是':'否')+'</td><td>'+escapeReturnRelabelHtml(labelCase)+'</td><td>'+escapeReturnRelabelHtml(o.backendTailOrderNo||'—')+'</td><td>'+escapeReturnRelabelHtml(relabelOrder)+'</td><td>'+escapeReturnRelabelHtml(relabelStatus)+'</td><td>'+escapeReturnRelabelHtml(o.tailStatus||'待入库')+'</td><td>'+escapeReturnRelabelHtml(o.createdAt)+'</td><td><button type="button" class="btn-text" data-return-relabel-id="'+escapeReturnRelabelHtml(o.id)+'">查看</button></td></tr>';}).join(''):'<tr class="empty-state"><td colspan="13">暂无退货换标订单</td></tr>';document.getElementById('return-relabel-total').textContent=orders.length;document.getElementById('return-relabel-page-number').textContent=returnRelabelCurrentPage+' / '+pages;document.getElementById('return-relabel-prev').disabled=returnRelabelCurrentPage<=1;document.getElementById('return-relabel-next').disabled=returnRelabelCurrentPage>=pages;}
function returnRelabelDateValue(value){const match=String(value||'').match(/(\d{4})[-/]?(\d{2})[-/]?(\d{2})/);return match?match.slice(1).join('-'):'';}
function filterReturnRelabelOrders(){const v=id=>(document.getElementById(id)?.value||'').trim().toLowerCase();const start=v('return-relabel-filter-created-start'),end=v('return-relabel-filter-created-end'),source=v('return-relabel-filter-source'),destination=v('return-relabel-filter-destination'),sku=v('return-relabel-filter-sku'),enabled=v('return-relabel-filter-enabled'),relabelStatus=v('return-relabel-filter-status'),tailStatus=v('return-relabel-filter-tail-status');if(start&&end&&start>end){showToast('创建开始时间不能晚于结束时间');return;}returnRelabelFilteredOrders=loadReturnRelabelOrders().filter(o=>(!v('return-relabel-filter-order-no')||String(o.orderNo).toLowerCase().includes(v('return-relabel-filter-order-no')))&&(!source||String(o.sourceFba).toLowerCase()===source)&&(!destination||String(o.destinationFba).toLowerCase()===destination)&&(!sku||(o.skus||[]).some(item=>String(item.sku||'').toLowerCase().includes(sku)))&&(!enabled||(enabled==='yes'?!!o.relabel:!o.relabel))&&(!relabelStatus||o.relabel&&String(o.relabelStatus).toLowerCase()===relabelStatus)&&(!tailStatus||String(o.tailStatus).toLowerCase()===tailStatus)&&(!start||returnRelabelDateValue(o.createdAt)>=start)&&(!end||returnRelabelDateValue(o.createdAt)<=end));returnRelabelCurrentPage=1;renderReturnRelabelList();}
function resetReturnRelabelFilters(){['return-relabel-filter-order-no','return-relabel-filter-source','return-relabel-filter-destination','return-relabel-filter-sku','return-relabel-filter-enabled','return-relabel-filter-tail-status','return-relabel-filter-status','return-relabel-filter-created-start','return-relabel-filter-created-end'].forEach(id=>{const el=document.getElementById(id);if(el)el.value='';});returnRelabelFilteredOrders=null;returnRelabelCurrentPage=1;renderReturnRelabelList();}
function addReturnRelabelSkuRow(item){const tbody=document.getElementById('return-relabel-sku-body');if(!tbody)return;item=item||{};const tr=document.createElement('tr');tr.innerHTML='<td><input class="return-relabel-input return-relabel-sku" value="'+escapeReturnRelabelHtml(item.sku||'')+'" required></td><td><input class="return-relabel-input return-relabel-name" value="'+escapeReturnRelabelHtml(item.name||'')+'" required></td><td><input class="return-relabel-input return-relabel-fnsku" value="'+escapeReturnRelabelHtml(item.fnsku||'')+'" required></td><td><input class="return-relabel-input return-relabel-quantity" type="number" min="1" value="'+(item.quantity||1)+'" required></td><td><button type="button" class="btn-text" onclick="removeReturnRelabelSkuRow(this)">删除</button></td>';tbody.appendChild(tr);}
function removeReturnRelabelSkuRow(button){const row=button&&button.closest?button.closest('tr'):null;if(row)row.remove();if(!document.querySelector('#return-relabel-sku-body tr'))addReturnRelabelSkuRow();}
function toggleReturnRelabel(){const enabled=!!document.querySelector('#return-relabel-form input[name="relabel"]:checked');const settings=document.getElementById('return-relabel-settings-fields');if(settings)settings.hidden=!enabled;document.querySelectorAll('#return-relabel-form input[name="labelCase"],#return-relabel-form input[name="cartonLabel"],#return-relabel-form input[name="skuLabel"]').forEach(el=>el.disabled=!enabled);updateFileRequirements();}
function updateFileRequirements(){const form=document.getElementById('return-relabel-form');const enabled=!!form&&!!form.querySelector('input[name="relabel"]:checked');const c= form?.querySelector('input[name="labelCase"]:checked')?.value||'Case1';const carton=form?.elements.cartonLabel,sku=form?.elements.skuLabel;if(carton)carton.disabled=!enabled||c==='Case2';if(sku)sku.disabled=!enabled||c==='Case1';const hint=document.getElementById('return-relabel-file-hint');if(hint)hint.textContent=enabled?({Case1:'Case1:需要上传箱唛',Case2:'Case2:需要上传 SKU 标签',Case3:'Case3:需要上传箱唛和 SKU 标签'}[c]||''):'未勾选换标,无需上传标签文件';}
function validateReturnRelabelForm(){const form=document.getElementById('return-relabel-form');const error=document.getElementById('return-relabel-error');if(error)error.textContent='';if(!form||!form.checkValidity()){if(form)form.reportValidity();return false;}for(const field of ['orderId','carrier','trackingNo','address','destinationCode']){if(!String(form.elements[field]?.value||'').trim()){if(error)error.textContent='请完整填写退货和尾程信息';return false;}}const rows=Array.from(document.querySelectorAll('#return-relabel-sku-body tr'));if(!rows.length){if(error)error.textContent='请至少添加一条 SKU';return false;}for(const row of rows){if(!row.querySelector('.return-relabel-sku').value.trim()||!row.querySelector('.return-relabel-name').value.trim()||!row.querySelector('.return-relabel-fnsku').value.trim()||Number(row.querySelector('.return-relabel-quantity').value)<1){if(error)error.textContent='请完整填写 SKU 明细';return false;}}const relabel=form.elements.relabel.checked, c=form.querySelector('input[name="labelCase"]:checked')?.value||'Case1';if(relabel){const carton=form.elements.cartonLabel.files?.[0],sku=form.elements.skuLabel.files?.[0];if(c==='Case1'&&!carton){if(error)error.textContent='Case1 需要上传箱唛';return false;}if(c==='Case2'&&!sku){if(error)error.textContent='Case2 需要上传 SKU 标签';return false;}if(c==='Case3'&&(!carton||!sku)){if(error)error.textContent='Case3 需要上传箱唛和 SKU 标签';return false;}}return true;}
function submitReturnRelabelOrder(event){if(event)event.preventDefault();if(returnRelabelSubmitting)return false;returnRelabelSubmitting=true;const submitButton=document.getElementById('return-relabel-submit');if(submitButton)submitButton.disabled=true;try{if(!validateReturnRelabelForm())return false;const form=document.getElementById('return-relabel-form'),orders=loadReturnRelabelOrders(),now=new Date(),datePart=now.getFullYear()+'-'+String(now.getMonth()+1).padStart(2,'0')+'-'+String(now.getDate()).padStart(2,'0'),stamp=datePart.replace(/-/g,''),nextSeq=orders.reduce((max,item)=>{const match=String(item.orderNo||'').match(new RegExp('^THHB'+stamp+'(\\d+)$'));return match?Math.max(max,Number(match[1])):max;},0)+1,seq=String(nextSeq).padStart(4,'0'),relabel=form.elements.relabel.checked;const order={id:'return-relabel-'+now.getTime(),orderNo:'THHB'+stamp+seq,sourceFba:form.elements.sourceFba.value,destinationFba:form.elements.destinationFba.value,orderId:form.elements.orderId.value.trim(),carrier:form.elements.carrier.value.trim(),trackingNo:form.elements.trackingNo.value.trim(),reason:form.elements.reason.value,relabel,address:form.elements.address.value.trim(),destinationCode:form.elements.destinationCode.value.trim(),expectedArrival:form.elements.expectedArrival.value,returnRemark:form.elements.returnRemark.value.trim(),tailRemark:form.elements.tailRemark.value.trim(),backendTailOrderNo:'LC'+stamp+seq,tailStatus:'待入库',createdAt:datePart+' '+String(now.getHours()).padStart(2,'0')+':'+String(now.getMinutes()).padStart(2,'0'),skus:Array.from(document.querySelectorAll('#return-relabel-sku-body tr')).map(r=>({sku:r.querySelector('.return-relabel-sku').value.trim(),name:r.querySelector('.return-relabel-name').value.trim(),fnsku:r.querySelector('.return-relabel-fnsku').value.trim(),quantity:Number(r.querySelector('.return-relabel-quantity').value)}))};if(relabel){order.labelCase=form.querySelector('input[name="labelCase"]:checked')?.value||'Case1';order.cartonLabel=order.labelCase==='Case2'?'':(form.elements.cartonLabel.files?.[0]?.name||'');order.skuLabel=order.labelCase==='Case1'?'':(form.elements.skuLabel.files?.[0]?.name||'');order.backendRelabelOrderNo='HB'+stamp+seq;order.relabelStatus='待换标';}else{order.backendRelabelOrderNo='-';}if(!saveReturnRelabelOrders([order].concat(orders))){const error=document.getElementById('return-relabel-error');if(error)error.textContent='保存失败';return false;}returnRelabelFilteredOrders=null;renderReturnRelabelList();showToast(relabel?'退货换标单提交成功,已生成换标单和尾程订单':'退货换标单提交成功,已生成尾程订单');openReturnRelabelList();return false;}finally{returnRelabelSubmitting=false;if(submitButton)submitButton.disabled=false;}}
function openReturnRelabelDetail(orderId){const order=loadReturnRelabelOrders().find(o=>String(o.id)===String(orderId));if(!order){showToast('未找到退货换标单');return;}const total=(order.skus||[]).reduce((sum,item)=>sum+Number(item.quantity||0),0);const summary=document.getElementById('return-relabel-detail-summary');if(summary)summary.innerHTML=[['退货换标单号',order.orderNo],['来源FBA仓',order.sourceFba],['目的FBA仓',order.destinationFba],['移除订单 Order ID',order.orderId],['退货原因',order.reason],['物流承运商',order.carrier],['物流跟踪号',order.trackingNo],['是否换标',order.relabel?'是':'否'],['贴标要求',order.relabel?(order.labelCase||'—'):'—'],['上传箱唛',order.relabel?(order.cartonLabel||'—'):'—'],['上传 SKU 标签',order.relabel?(order.skuLabel||'—'):'—'],['期望到达时间',order.expectedArrival||'—'],['退件总数',total],['退货备注',order.returnRemark||order.remark||'—'],['尾程备注',order.tailRemark||'—'],['地址',order.address],['目的仓代码',order.destinationCode],['创建时间',order.createdAt]].map(f=>'<div class="storage-transfer-summary-item"><div class="storage-transfer-summary-label">'+f[0]+'</div><div class="storage-transfer-summary-value">'+escapeReturnRelabelHtml(f[1])+'</div></div>').join('');const body=document.getElementById('return-relabel-detail-sku-body');if(body)body.innerHTML=(order.skus||[]).map(s=>'<tr><td>'+escapeReturnRelabelHtml(s.sku)+'</td><td>'+escapeReturnRelabelHtml(s.name)+'</td><td>'+escapeReturnRelabelHtml(s.fnsku)+'</td><td>'+s.quantity+'</td></tr>').join('');document.getElementById('return-relabel-detail-tail-order-no').textContent=order.backendTailOrderNo||'—';document.getElementById('return-relabel-detail-relabel-order-no').textContent=order.relabel?(order.backendRelabelOrderNo||'—'):'—';document.getElementById('return-relabel-detail-relabel-status').textContent=order.relabel?(order.relabelStatus||'—'):'—';document.getElementById('return-relabel-detail-tail-status').textContent=order.tailStatus||'待入库';dashNavigate('return-relabel-detail',returnRelabelNav());}
document.addEventListener('DOMContentLoaded',()=>{const body=document.getElementById('return-relabel-list-body');if(body&&!body.dataset.returnRelabelBound){body.dataset.returnRelabelBound='1';body.addEventListener('click',event=>{const button=event.target.closest('[data-return-relabel-id]');if(button)openReturnRelabelDetail(button.getAttribute('data-return-relabel-id'));});}renderReturnRelabelList();});
// ===== 货物废弃 =====
const CARGO_DISPOSAL_KEY = 'by_cargo_disposal_orders_0805';
const CARGO_DISPOSAL_PAGE_SIZE = 10;
const CARGO_DISPOSAL_FEE_PER_BOX = 5;
const CARGO_DISPOSAL_INBOUND_SEED = [
{ id:'inbound-disposal-1', inboundNo:'RK20260808018', warehouse:'美西洛杉矶仓', receivedAt:'2026-08-08', availableBoxes:24, expanded:true, items:[{id:'rk18-1',sku:'SKU-LM-2048',name:'折叠收纳盒',availableBoxes:12},{id:'rk18-2',sku:'SKU-KT-9912',name:'厨房置物架',availableBoxes:12}] },
{ id:'inbound-disposal-2', inboundNo:'RK20260806023', warehouse:'美东新泽西仓', receivedAt:'2026-08-06', availableBoxes:16, expanded:false, items:[{id:'rk23-1',sku:'SKU-PH-3301',name:'手机保护壳',availableBoxes:8},{id:'rk23-2',sku:'SKU-CB-4410',name:'收纳篮',availableBoxes:8}] }
];
const CARGO_DISPOSAL_ORDER_SEED = [
{id:'cargo-disposal-seed-1',orderNo:'FH202608120001',inboundNo:'RK20260808018',warehouse:'美西洛杉矶仓',disposalBoxes:6,feeAmount:30,currency:'USD',tailOrderNo:'LC202608120001',outboundOrderNo:'CK202608120001',billingNo:'JF202608120001',status:'待处理',createdAt:'2026-08-12 09:20',items:[{sku:'SKU-LM-2048',name:'折叠收纳盒',availableBoxes:12,disposalBoxes:4},{sku:'SKU-KT-9912',name:'厨房置物架',availableBoxes:12,disposalBoxes:2}]},
{id:'cargo-disposal-seed-2',orderNo:'FH202608110002',inboundNo:'RK20260806023',warehouse:'美东新泽西仓',disposalBoxes:3,feeAmount:15,currency:'USD',tailOrderNo:'LC202608110002',outboundOrderNo:'CK202608110002',billingNo:'JF202608110002',status:'处理中',createdAt:'2026-08-11 14:35',items:[{sku:'SKU-PH-3301',name:'手机保护壳',availableBoxes:8,disposalBoxes:3}]},
{id:'cargo-disposal-seed-3',orderNo:'FH202608100003',inboundNo:'RK20260808018',warehouse:'美西洛杉矶仓',disposalBoxes:8,feeAmount:40,currency:'USD',tailOrderNo:'LC202608100003',outboundOrderNo:'CK202608100003',billingNo:'JF202608100003',status:'已完成',createdAt:'2026-08-10 16:10',items:[{sku:'SKU-KT-9912',name:'厨房置物架',availableBoxes:12,disposalBoxes:8}]}
];
let cargoDisposalFilteredOrders = null;
let cargoDisposalCurrentPage = 1;
let cargoDisposalSubmitting = false;
function cloneCargoDisposalInboundSeed() { return JSON.parse(JSON.stringify(CARGO_DISPOSAL_INBOUND_SEED)); }
function cloneCargoDisposalOrderSeed() { return JSON.parse(JSON.stringify(CARGO_DISPOSAL_ORDER_SEED)); }
function loadCargoDisposalOrders() {
try { const raw = localStorage.getItem(CARGO_DISPOSAL_KEY); if (!raw) return cloneCargoDisposalOrderSeed(); const parsed = JSON.parse(raw); if (!Array.isArray(parsed)) throw new Error('货物废弃数据格式无效'); const seedIds=new Set(CARGO_DISPOSAL_ORDER_SEED.map(item=>item.id)); const localOrders=parsed.filter(item=>item&&typeof item==='object'&&!seedIds.has(item.id)); return localOrders.concat(cloneCargoDisposalOrderSeed()); }
catch (error) { console.warn('读取货物废弃订单失败,已恢复示例数据。', error); return cloneCargoDisposalOrderSeed(); }
}
function saveCargoDisposalOrders(orders) { try { const seedIds=new Set(CARGO_DISPOSAL_ORDER_SEED.map(item=>item.id)); const localOrders=(Array.isArray(orders)?orders:[]).filter(item=>item&&typeof item==='object'&&!seedIds.has(item.id)); localStorage.setItem(CARGO_DISPOSAL_KEY, JSON.stringify(localOrders)); return true; } catch (error) { console.warn('保存货物废弃订单失败。', error); return false; } }
function escapeCargoDisposalHtml(value) { return String(value == null ? '' : value).replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/"/g,'&quot;').replace(/'/g,'&#39;'); }
function getCargoDisposalNavLink() { return Array.from(document.querySelectorAll('.dash-nav-link')).find(link => (link.getAttribute('onclick') || '').includes("dashNavigate('cargo-disposal-list', this)")) || null; }
function navigateCargoDisposalPage(pageId) { dashNavigate(pageId, getCargoDisposalNavLink()); }
function generateCargoDisposalNumber(prefix, orders) { const date = new Date(); const stamp = date.getFullYear() + String(date.getMonth()+1).padStart(2,'0') + String(date.getDate()).padStart(2,'0'); const used = new Set(orders.flatMap(item => [item.orderNo,item.tailOrderNo,item.outboundOrderNo,item.billingNo])); let i=orders.length+1; let value; do { value = prefix + stamp + String(i++).padStart(4,'0'); } while (used.has(value)); return value; }
function calculateCargoDisposalFee(boxes) { return Math.max(0, Number(boxes) || 0) * CARGO_DISPOSAL_FEE_PER_BOX; }
function getCargoDisposalSelection() { const card = document.querySelector('.cargo-disposal-inbound-card.is-selected'); if (!card) return null; const inbound = CARGO_DISPOSAL_INBOUND_SEED.find(item => item.id === card.dataset.inboundId); if (!inbound) return null; return { inbound, items: Array.from(card.querySelectorAll('.cargo-disposal-quantity')).map(input => ({ id:input.dataset.itemId, disposalBoxes:Number(input.value) || 0 })) }; }
function renderCargoDisposalFee() { const selection = getCargoDisposalSelection(); const total = selection ? selection.items.reduce((sum,item) => sum + item.disposalBoxes, 0) : 0; const fee = document.getElementById('cargo-disposal-fee'); if (fee) fee.textContent = '$' + calculateCargoDisposalFee(total).toFixed(2); }
function toggleCargoDisposalInbound(card) { document.querySelectorAll('.cargo-disposal-inbound-card').forEach(item => { item.classList.remove('is-selected'); if (item !== card) item.classList.remove('expanded'); }); card.classList.add('is-selected','expanded'); renderCargoDisposalFee(); }
function renderCargoDisposalInboundCards(query) { const container = document.getElementById('cargo-disposal-inbound-cards'); if (!container) return; const normalizedQuery=String(query==null?(document.getElementById('cargo-disposal-inbound-search')?.value||''):query).trim().toLowerCase(); const inboundCodes=cloneCargoDisposalInboundSeed().filter(inbound=>!normalizedQuery||inbound.inboundNo.toLowerCase().includes(normalizedQuery)); if(!inboundCodes.length){container.innerHTML='<div class="empty-text">未找到匹配的入仓码,请检查后重新搜索</div>';renderCargoDisposalFee();return;} container.innerHTML = inboundCodes.map(inbound => '<div class="cargo-disposal-inbound-card ' + (inbound.expanded ? 'expanded is-selected' : '') + '" data-inbound-id="' + inbound.id + '"><div class="cargo-disposal-inbound-summary" role="button" tabindex="0" onclick="toggleCargoDisposalInbound(this.parentElement)" onkeydown="if(event.key===\'Enter\'||event.key===\' \'){event.preventDefault();toggleCargoDisposalInbound(this.parentElement)}"><div><strong>' + escapeCargoDisposalHtml(inbound.inboundNo) + '</strong><div class="cargo-disposal-inbound-meta">' + escapeCargoDisposalHtml(inbound.warehouse) + ' · ' + escapeCargoDisposalHtml(inbound.receivedAt) + ' · 可用 ' + inbound.availableBoxes + ' 箱</div></div><span aria-hidden="true">' + (inbound.expanded ? '⌃' : '⌄') + '</span></div><div class="cargo-disposal-inbound-body"><div class="cargo-disposal-table-wrap"><table class="cargo-disposal-table"><thead><tr><th>商品 SKU</th><th>中文品名</th><th>可用箱数</th><th>废弃箱数</th></tr></thead><tbody>' + inbound.items.map(item => '<tr><td>' + escapeCargoDisposalHtml(item.sku) + '</td><td>' + escapeCargoDisposalHtml(item.name) + '</td><td>' + item.availableBoxes + '</td><td><input class="cargo-disposal-quantity" type="number" min="0" max="' + item.availableBoxes + '" value="0" data-item-id="' + item.id + '" aria-label="' + escapeCargoDisposalHtml(item.sku) + '废弃箱数" oninput="renderCargoDisposalFee()"></td></tr>').join('') + '</tbody></table></div></div></div>').join(''); renderCargoDisposalFee(); }
function filterCargoDisposalInboundCards() { const query=(document.getElementById('cargo-disposal-inbound-search')?.value||'').trim().toLowerCase(); const matches=CARGO_DISPOSAL_INBOUND_SEED.filter(inbound=>inbound.inboundNo.toLowerCase().includes(query)); renderCargoDisposalInboundCards(query); return matches.length; }
function renderCargoDisposalList() { const body=document.getElementById('cargo-disposal-list-body'); if (!body) return; const orders=cargoDisposalFilteredOrders===null?loadCargoDisposalOrders():cargoDisposalFilteredOrders; const pages=Math.max(1,Math.ceil(orders.length/CARGO_DISPOSAL_PAGE_SIZE)); cargoDisposalCurrentPage=Math.min(Math.max(1,cargoDisposalCurrentPage),pages); const rows=orders.slice((cargoDisposalCurrentPage-1)*CARGO_DISPOSAL_PAGE_SIZE,cargoDisposalCurrentPage*CARGO_DISPOSAL_PAGE_SIZE); body.innerHTML=rows.length?rows.map(order=>'<tr><td>'+escapeCargoDisposalHtml(order.orderNo)+'</td><td>'+escapeCargoDisposalHtml(order.inboundNo)+'</td><td>'+order.disposalBoxes+'</td><td>'+escapeCargoDisposalHtml(order.warehouse)+'</td><td>$'+Number(order.feeAmount).toFixed(2)+'</td><td>'+escapeCargoDisposalHtml(order.inboundNo)+'</td><td>'+escapeCargoDisposalHtml(order.outboundOrderNo)+'</td><td>'+escapeCargoDisposalHtml(order.billingNo)+'</td><td><span class="status-badge status-processing">'+escapeCargoDisposalHtml(order.status)+'</span></td><td>'+escapeCargoDisposalHtml(order.createdAt)+'</td><td><button type="button" class="btn-text" onclick="openCargoDisposalDetail(\''+escapeCargoDisposalHtml(order.id)+'\')">查看</button></td></tr>').join(''):'<tr class="empty-state"><td colspan="11"><div class="empty-text">暂无货物废弃订单</div></td></tr>'; document.getElementById('cargo-disposal-total').textContent=orders.length; document.getElementById('cargo-disposal-page-number').textContent=cargoDisposalCurrentPage+' / '+pages; document.getElementById('cargo-disposal-prev').disabled=cargoDisposalCurrentPage<=1; document.getElementById('cargo-disposal-next').disabled=cargoDisposalCurrentPage>=pages; }
function filterCargoDisposalOrders() { const val=id=>(document.getElementById(id)?.value||'').trim().toLowerCase(); const start=val('cargo-disposal-filter-created-start'), end=val('cargo-disposal-filter-created-end'); if(start&&end&&start>end){showToast('创建开始时间不能晚于结束时间');return;} cargoDisposalFilteredOrders=loadCargoDisposalOrders().filter(order=>(!val('cargo-disposal-filter-order-no')||order.orderNo.toLowerCase().includes(val('cargo-disposal-filter-order-no')))&&(!val('cargo-disposal-filter-inbound-no')||order.inboundNo.toLowerCase().includes(val('cargo-disposal-filter-inbound-no')))&&(!val('cargo-disposal-filter-warehouse')||order.warehouse===document.getElementById('cargo-disposal-filter-warehouse').value)&&(!val('cargo-disposal-filter-status')||order.status===document.getElementById('cargo-disposal-filter-status').value)&&(!start||order.createdAt.slice(0,10)>=start)&&(!end||order.createdAt.slice(0,10)<=end)); cargoDisposalCurrentPage=1; renderCargoDisposalList(); }
function resetCargoDisposalFilters() { ['cargo-disposal-filter-order-no','cargo-disposal-filter-inbound-no','cargo-disposal-filter-warehouse','cargo-disposal-filter-status','cargo-disposal-filter-created-start','cargo-disposal-filter-created-end'].forEach(id=>{const el=document.getElementById(id);if(el)el.value='';}); cargoDisposalFilteredOrders=null; cargoDisposalCurrentPage=1; renderCargoDisposalList(); }
function changeCargoDisposalPage(delta) { const orders=cargoDisposalFilteredOrders===null?loadCargoDisposalOrders():cargoDisposalFilteredOrders; const pages=Math.max(1,Math.ceil(orders.length/CARGO_DISPOSAL_PAGE_SIZE)); const next=cargoDisposalCurrentPage+Number(delta||0); if(next<1||next>pages)return; cargoDisposalCurrentPage=next; renderCargoDisposalList(); }
function openCargoDisposalList() { renderCargoDisposalList(); navigateCargoDisposalPage('cargo-disposal-list'); }
function openCargoDisposalCreate() { const form=document.getElementById('cargo-disposal-form'); if(form)form.reset(); renderCargoDisposalInboundCards(); cargoDisposalSubmitting=false; navigateCargoDisposalPage('cargo-disposal-create'); }
function validateCargoDisposalForm() { const selection=getCargoDisposalSelection(); const error=document.getElementById('cargo-disposal-error'); if(error)error.textContent=''; if(!selection){if(error)error.textContent='请选择一个入仓码';return false;} const inboundById=new Map(selection.inbound.items.map(item=>[item.id,item])); let total=0; for(const item of selection.items){ const availableBoxes=inboundById.get(item.id)?.availableBoxes||0; if(!Number.isInteger(item.disposalBoxes)||item.disposalBoxes<0||item.disposalBoxes>availableBoxes){if(error)error.textContent='废弃箱数必须是整数且不能超过可用箱数';return false;} total+=item.disposalBoxes; } if(total<1){if(error)error.textContent='请至少填写一条大于 0 的废弃箱数';return false;} return true; }
function submitCargoDisposalOrder(event) { if(event)event.preventDefault(); if(cargoDisposalSubmitting)return false; cargoDisposalSubmitting=true; const submit=document.getElementById('cargo-disposal-submit'); if(submit)submit.disabled=true; try{if(!validateCargoDisposalForm())return false; const selection=getCargoDisposalSelection(), orders=loadCargoDisposalOrders(), now=new Date(), disposalBoxes=selection.items.reduce((sum,item)=>sum+item.disposalBoxes,0); const order={id:'cargo-disposal-'+now.getTime(),orderNo:generateCargoDisposalNumber('FH',orders),inboundNo:selection.inbound.inboundNo,warehouse:selection.inbound.warehouse,disposalBoxes,feeAmount:calculateCargoDisposalFee(disposalBoxes),currency:'USD',tailOrderNo:generateCargoDisposalNumber('LC',orders),outboundOrderNo:generateCargoDisposalNumber('CK',orders),billingNo:generateCargoDisposalNumber('JF',orders),status:'待处理',createdAt:now.getFullYear()+'-'+String(now.getMonth()+1).padStart(2,'0')+'-'+String(now.getDate()).padStart(2,'0')+' '+String(now.getHours()).padStart(2,'0')+':'+String(now.getMinutes()).padStart(2,'0'),items:selection.items.filter(item=>item.disposalBoxes>0).map(item=>{const source=selection.inbound.items.find(sourceItem=>sourceItem.id===item.id);return {sku:source.sku,name:source.name,availableBoxes:source.availableBoxes,disposalBoxes:item.disposalBoxes};})}; if(!saveCargoDisposalOrders([order].concat(orders))){showToast('保存失败,请检查浏览器存储设置');return false;} cargoDisposalFilteredOrders=null;cargoDisposalCurrentPage=1;renderCargoDisposalList();showToast('货物废弃单提交成功,已生成尾程单、废弃出库单和弃货费计费单');navigateCargoDisposalPage('cargo-disposal-list');return false;} finally{cargoDisposalSubmitting=false;if(submit)submit.disabled=false;} }
function openCargoDisposalDetail(orderId) { const order=loadCargoDisposalOrders().find(item=>String(item.id)===String(orderId)); if(!order){showToast('未找到货物废弃订单');return;} const summary=document.getElementById('cargo-disposal-detail-summary'); if(summary)summary.innerHTML=[['入库单号',order.inboundNo],['操作仓',order.warehouse],['废弃箱数',order.disposalBoxes+' 箱'],['弃货费','$'+Number(order.feeAmount).toFixed(2)+' '+order.currency],['订单状态',order.status],['创建时间',order.createdAt]].map(field=>'<div class="storage-transfer-summary-item"><div class="storage-transfer-summary-label">'+field[0]+'</div><div class="storage-transfer-summary-value">'+escapeCargoDisposalHtml(field[1])+'</div></div>').join(''); const items=document.getElementById('cargo-disposal-detail-items'); if(items)items.innerHTML=order.items.map(item=>'<tr><td>'+escapeCargoDisposalHtml(item.sku)+'</td><td>'+escapeCargoDisposalHtml(item.name)+'</td><td>'+item.availableBoxes+'</td><td>'+item.disposalBoxes+'</td></tr>').join(''); document.getElementById('cargo-disposal-detail-order-no').textContent=order.orderNo;document.getElementById('cargo-disposal-detail-tail-order-no').textContent=order.tailOrderNo;document.getElementById('cargo-disposal-detail-outbound-order-no').textContent=order.outboundOrderNo;document.getElementById('cargo-disposal-detail-billing-no').textContent=order.billingNo; navigateCargoDisposalPage('cargo-disposal-detail'); }
document.addEventListener('DOMContentLoaded', function(){ renderCargoDisposalList(); });
function renderStorageTransferList() {
const tbody = document.getElementById('storage-transfer-list-body');
if (!tbody) return;
const orders = storageTransferFilteredOrders === null
? loadStorageTransferOrders()
: storageTransferFilteredOrders;
const totalPages = Math.max(1, Math.ceil(orders.length / STORAGE_TRANSFER_PAGE_SIZE));
storageTransferCurrentPage = Math.min(Math.max(1, storageTransferCurrentPage), totalPages);
const start = (storageTransferCurrentPage - 1) * STORAGE_TRANSFER_PAGE_SIZE;
const rows = orders.slice(start, start + STORAGE_TRANSFER_PAGE_SIZE);
tbody.innerHTML = rows.length ? rows.map(order => {
const id = escapeStorageTransferHtml(order.id);
return '<tr>' +
'<td>' + escapeStorageTransferHtml(order.orderNo) + '</td>' +
'<td>' + escapeStorageTransferHtml(order.inboundNo) + '</td>' +
'<td>' + escapeStorageTransferHtml(order.boxCount) + '</td>' +
'<td>' + escapeStorageTransferHtml(order.warehouse) + '</td>' +
'<td>' + escapeStorageTransferHtml(order.fbaCode) + '</td>' +
'<td>' + escapeStorageTransferHtml(order.shipmentId) + '</td>' +
'<td>' + escapeStorageTransferHtml(order.deliveryMethod) + '</td>' +
'<td>' + (order.relabel === 'yes' ? '是' : '否') + '</td>' +
'<td>' + escapeStorageTransferHtml(order.tailOrderNo) + '</td>' +
'<td>' + escapeStorageTransferHtml(order.relabelOrderNo || '-') + '</td>' +
'<td><span class="status-badge status-processing">' + escapeStorageTransferHtml(order.status) + '</span></td>' +
'<td>' + escapeStorageTransferHtml(order.createdAt) + '</td>' +
'<td><button type="button" class="btn-text" data-storage-transfer-id="' + id + '" onclick="openStorageTransferDetail(this.dataset.storageTransferId)">查看</button></td>' +
'</tr>';
}).join('') : '<tr class="empty-state"><td colspan="13"><div class="empty-text">暂无符合条件的仓储转运订单</div></td></tr>';
const total = document.getElementById('storage-transfer-total');
const pageNumber = document.getElementById('storage-transfer-page-number');
const previous = document.getElementById('storage-transfer-prev');
const next = document.getElementById('storage-transfer-next');
if (total) total.textContent = orders.length;
if (pageNumber) pageNumber.textContent = storageTransferCurrentPage + ' / ' + totalPages;
if (previous) previous.disabled = storageTransferCurrentPage <= 1;
if (next) next.disabled = storageTransferCurrentPage >= totalPages;
}
function filterStorageTransferOrders() {
const value = id => (document.getElementById(id)?.value || '').trim().toLowerCase();
const orderNo = value('storage-transfer-filter-order-no');
const inboundNo = value('storage-transfer-filter-inbound-no');
const warehouse = value('storage-transfer-filter-warehouse');
const fbaCode = value('storage-transfer-filter-fba');
const relabel = value('storage-transfer-filter-relabel');
const status = value('storage-transfer-filter-status');
const createdStart = value('storage-transfer-filter-created-start');
const createdEnd = value('storage-transfer-filter-created-end');
if (createdStart && createdEnd && createdStart > createdEnd) {
showToast('创建开始时间不能晚于结束时间');
return;
}
storageTransferFilteredOrders = loadStorageTransferOrders().filter(order => {
const createdDate = String(order.createdAt || '').slice(0, 10);
return (!orderNo || String(order.orderNo || '').toLowerCase().includes(orderNo)) &&
(!inboundNo || String(order.inboundNo || '').toLowerCase().includes(inboundNo)) &&
(!warehouse || String(order.warehouse || '').toLowerCase() === warehouse) &&
(!fbaCode || String(order.fbaCode || '').toLowerCase().includes(fbaCode)) &&
(!relabel || String(order.relabel || '').toLowerCase() === relabel) &&
(!status || String(order.status || '').toLowerCase() === status) &&
(!createdStart || createdDate >= createdStart) && (!createdEnd || createdDate <= createdEnd);
});
storageTransferCurrentPage = 1;
renderStorageTransferList();
}
function resetStorageTransferFilters() {
[
'storage-transfer-filter-order-no', 'storage-transfer-filter-inbound-no',
'storage-transfer-filter-warehouse', 'storage-transfer-filter-fba',
'storage-transfer-filter-relabel', 'storage-transfer-filter-status',
'storage-transfer-filter-created-start', 'storage-transfer-filter-created-end'
].forEach(id => {
const control = document.getElementById(id);
if (control) control.value = '';
});
storageTransferFilteredOrders = null;
storageTransferCurrentPage = 1;
renderStorageTransferList();
}
function changeStorageTransferPage(delta) {
const orders = storageTransferFilteredOrders === null ? loadStorageTransferOrders() : storageTransferFilteredOrders;
const totalPages = Math.max(1, Math.ceil(orders.length / STORAGE_TRANSFER_PAGE_SIZE));
const nextPage = storageTransferCurrentPage + Number(delta || 0);
if (nextPage < 1 || nextPage > totalPages) return;
storageTransferCurrentPage = nextPage;
renderStorageTransferList();
}
function openStorageTransferCreate() {
const form = document.getElementById('storage-transfer-form');
if (form) form.reset();
const tbody = document.getElementById('storage-transfer-cargo-body');
if (tbody) tbody.innerHTML = '';
addStorageTransferCargoRow();
toggleStorageTransferRelabel();
storageTransferSubmitting = false;
navigateStorageTransferPage('storage-transfer-create');
}
function openStorageTransferList() {
renderStorageTransferList();
navigateStorageTransferPage('storage-transfer-list');
}
function cancelStorageTransferCreate() {
openStorageTransferList();
}
function addStorageTransferCargoRow(cargo) {
const tbody = document.getElementById('storage-transfer-cargo-body');
if (!tbody) return;
const item = cargo || {};
const row = document.createElement('tr');
row.innerHTML =
'<td><input class="cell-input storage-transfer-cargo-sku" type="text" value="' + escapeStorageTransferHtml(item.sku) + '" aria-label="商品SKU"></td>' +
'<td><input class="cell-input storage-transfer-cargo-name" type="text" value="' + escapeStorageTransferHtml(item.name) + '" aria-label="中文品名"></td>' +
'<td><input class="cell-input storage-transfer-cargo-boxes" type="number" min="1" value="' + escapeStorageTransferHtml(item.boxes || '') + '" aria-label="箱数"></td>' +
'<td class="storage-transfer-relabel-column"><input class="cell-input storage-transfer-cargo-relabel-input storage-transfer-cargo-relabel-sku" type="text" value="' + escapeStorageTransferHtml(item.relabelSku) + '" aria-label="换标后SKU"></td>' +
'<td class="storage-transfer-relabel-column"><input class="cell-input storage-transfer-cargo-relabel-input storage-transfer-cargo-requirement" type="text" value="' + escapeStorageTransferHtml(item.requirement) + '" aria-label="贴标要求"></td>' +
'<td class="storage-transfer-relabel-column"><input class="storage-transfer-cargo-relabel-input storage-transfer-cargo-file" type="file" aria-label="换标文件" onchange="captureStorageTransferFileName(this)"><input class="storage-transfer-cargo-file-name" type="hidden" value="' + escapeStorageTransferHtml(item.fileName) + '"><span class="storage-transfer-file-name">' + escapeStorageTransferHtml(item.fileName || '未选择文件') + '</span></td>' +
'<td><button type="button" class="btn-text" style="color:#ff4d4f;" onclick="removeStorageTransferCargoRow(this)">删除</button></td>';
tbody.appendChild(row);
toggleStorageTransferRelabel();
}
function removeStorageTransferCargoRow(button) {
const row = button.closest('tr');
if (row) row.remove();
if (!document.querySelector('#storage-transfer-cargo-body tr')) addStorageTransferCargoRow();
}
function captureStorageTransferFileName(input) {
const cell = input.closest('td');
if (!cell) return;
const fileName = input.files && input.files[0] ? input.files[0].name : '';
const hidden = cell.querySelector('.storage-transfer-cargo-file-name');
const label = cell.querySelector('.storage-transfer-file-name');
if (hidden) hidden.value = fileName;
if (label) label.textContent = fileName || '未选择文件';
}
function toggleStorageTransferRelabel() {
const selected = document.querySelector('input[name="relabel"]:checked');
const enabled = selected && selected.value === 'yes';
document.querySelectorAll('#storage-transfer-cargo-table .storage-transfer-relabel-column').forEach(cell => {
cell.hidden = !enabled;
});
document.querySelectorAll('#storage-transfer-cargo-body .storage-transfer-cargo-relabel-input').forEach(input => {
input.disabled = !enabled;
});
}
function validateStorageTransferForm() {
const form = document.getElementById('storage-transfer-form');
if (!form) return false;
if (!form.checkValidity()) {
form.reportValidity();
return false;
}
const rows = Array.from(document.querySelectorAll('#storage-transfer-cargo-body tr'));
if (!rows.length) {
showToast('请至少添加一条货物明细');
return false;
}
let cargoBoxes = 0;
const relabel = form.elements.relabel.value === 'yes';
for (const row of rows) {
const sku = row.querySelector('.storage-transfer-cargo-sku').value.trim();
const name = row.querySelector('.storage-transfer-cargo-name').value.trim();
const boxes = Number(row.querySelector('.storage-transfer-cargo-boxes').value);
if (!sku || !name || !Number.isInteger(boxes) || boxes < 1) {
showToast('请完整填写货物 SKU、中文品名和有效箱数');
return false;
}
cargoBoxes += boxes;
if (relabel) {
const relabelSku = row.querySelector('.storage-transfer-cargo-relabel-sku').value.trim();
const requirement = row.querySelector('.storage-transfer-cargo-requirement').value.trim();
const fileName = row.querySelector('.storage-transfer-cargo-file-name').value.trim();
if (!relabelSku || !requirement || !fileName) {
showToast('选择换标时,请填写换标后 SKU、贴标要求并上传换标文件');
return false;
}
}
}
const declaredBoxes = Number(document.getElementById('storage-transfer-box-count').value);
if (cargoBoxes !== declaredBoxes) {
showToast('货物明细箱数合计必须与发货箱数一致');
return false;
}
return true;
}
function collectStorageTransferCargo() {
return Array.from(document.querySelectorAll('#storage-transfer-cargo-body tr')).map(row => ({
sku: row.querySelector('.storage-transfer-cargo-sku').value.trim(),
name: row.querySelector('.storage-transfer-cargo-name').value.trim(),
boxes: Number(row.querySelector('.storage-transfer-cargo-boxes').value),
relabelSku: row.querySelector('.storage-transfer-cargo-relabel-sku').value.trim(),
requirement: row.querySelector('.storage-transfer-cargo-requirement').value.trim(),
fileName: row.querySelector('.storage-transfer-cargo-file-name').value.trim()
}));
}
function generateStorageTransferNumber(prefix, orders) {
const now = new Date();
const date = now.getFullYear() + String(now.getMonth() + 1).padStart(2, '0') + String(now.getDate()).padStart(2, '0');
const existing = new Set(orders.flatMap(order => [order.orderNo, order.tailOrderNo, order.relabelOrderNo]));
let sequence = String(orders.length + 1).padStart(4, '0');
let candidate = prefix + date + sequence;
while (existing.has(candidate)) {
sequence = String(Number(sequence) + 1).padStart(4, '0');
candidate = prefix + date + sequence;
}
return candidate;
}
function submitStorageTransferOrder(event) {
if (event) event.preventDefault();
if (storageTransferSubmitting) return false;
storageTransferSubmitting = true;
const submitButton = document.getElementById('storage-transfer-submit');
if (submitButton) submitButton.disabled = true;
try {
if (!validateStorageTransferForm()) return false;
const form = document.getElementById('storage-transfer-form');
const orders = loadStorageTransferOrders();
const now = new Date();
const relabel = form.elements.relabel.value;
const order = {
id: 'storage-transfer-' + now.getTime(),
orderNo: generateStorageTransferNumber('ZY', orders),
inboundNo: form.elements.inboundNo.value.trim(),
boxCount: Number(form.elements.boxCount.value),
warehouse: form.elements.warehouse.value,
fbaCode: form.elements.fbaCode.value.trim(),
address: form.elements.address.value.trim(),
deliveryMethod: form.elements.deliveryMethod.value,
expectedArrival: form.elements.expectedArrival.value,
shipmentId: form.elements.shipmentId.value.trim(),
trackingId: form.elements.trackingId.value.trim(),
boxId: form.elements.boxId.value.trim(),
note: form.elements.note.value.trim(),
relabel: relabel,
tailOrderNo: generateStorageTransferNumber('LC', orders),
relabelOrderNo: relabel === 'yes' ? generateStorageTransferNumber('HB', orders) : '',
status: '待处理',
createdAt: now.getFullYear() + '-' + String(now.getMonth() + 1).padStart(2, '0') + '-' + String(now.getDate()).padStart(2, '0') + ' ' + String(now.getHours()).padStart(2, '0') + ':' + String(now.getMinutes()).padStart(2, '0'),
cargo: collectStorageTransferCargo()
};
if (!saveStorageTransferOrders([order].concat(orders))) {
showToast('保存失败,请检查浏览器存储设置');
return false;
}
storageTransferFilteredOrders = null;
storageTransferCurrentPage = 1;
renderStorageTransferList();
showToast('仓储转运单提交成功');
navigateStorageTransferPage('storage-transfer-list');
return false;
} finally {
storageTransferSubmitting = false;
if (submitButton) submitButton.disabled = false;
}
}
function openStorageTransferDetail(orderId) {
const order = loadStorageTransferOrders().find(item => String(item.id) === String(orderId));
if (!order) {
showToast('未找到仓储转运单');
return;
}
const summary = document.getElementById('storage-transfer-detail-summary');
const fields = [
['转运单号', order.orderNo], ['进仓编号', order.inboundNo], ['状态', order.status],
['操作仓', order.warehouse], ['FBA 目的仓代码', order.fbaCode], ['发货箱数', order.boxCount],
['派送方式', order.deliveryMethod], ['期望到达时间', order.expectedArrival], ['是否换标', order.relabel === 'yes' ? '是' : '否'],
['FBA 货件编号', order.shipmentId], ['FBA 追踪编号', order.trackingId || '-'], ['FBA BOX 编号', order.boxId || '-'],
['详细派送地址', order.address], ['订单备注', order.note || '-'], ['创建时间', order.createdAt]
];
if (summary) summary.innerHTML = fields.map(field =>
'<div class="storage-transfer-summary-item"><div class="storage-transfer-summary-label">' + escapeStorageTransferHtml(field[0]) + '</div><div class="storage-transfer-summary-value">' + escapeStorageTransferHtml(field[1]) + '</div></div>'
).join('');
const cargoBody = document.getElementById('storage-transfer-detail-cargo');
if (cargoBody) cargoBody.innerHTML = (order.cargo || []).map(item => '<tr>' +
'<td>' + escapeStorageTransferHtml(item.sku) + '</td><td>' + escapeStorageTransferHtml(item.name) + '</td>' +
'<td>' + escapeStorageTransferHtml(item.boxes) + '</td><td>' + escapeStorageTransferHtml(item.relabelSku || '-') + '</td>' +
'<td>' + escapeStorageTransferHtml(item.requirement || '-') + '</td><td>' + escapeStorageTransferHtml(item.fileName || '-') + '</td></tr>').join('') ||
'<tr class="empty-state"><td colspan="6">暂无货物明细</td></tr>';
const tailOrder = document.getElementById('storage-transfer-tail-order-no');
const relabelOrder = document.getElementById('storage-transfer-relabel-order-no');
if (tailOrder) tailOrder.textContent = order.tailOrderNo || '-';
if (relabelOrder) relabelOrder.textContent = order.relabelOrderNo || '未生成';
navigateStorageTransferPage('storage-transfer-detail');
}
document.addEventListener('DOMContentLoaded', function() {
renderStorageTransferList();
});
// ===== 新建退货入库单弹窗 =====
function openReturnInModal() {
document.getElementById('return-in-modal').classList.add('show');
}
function closeReturnInModal() {
document.getElementById('return-in-modal').classList.remove('show');
}
function addReturnInProductRow() {
var tbody = document.getElementById('return-in-product-tbody');
var tr = document.createElement('tr');
tr.innerHTML = '<td><input type="text" class="cell-input" placeholder="物流承运商"></td>' +
'<td><input type="text" class="cell-input" placeholder="物流跟踪号"></td>' +
'<td>—</td><td>—</td>' +
'<td><input type="text" class="cell-input" placeholder="FNSKU"></td>' +
'<td><input type="number" class="cell-input" placeholder="数量"></td>' +
'<td><button class="btn-text" style="color:#ff4d4f;" onclick="this.closest(\'tr\').remove()">删除</button></td>';
tbody.appendChild(tr);
}
function submitReturnInModal() {
alert('退货入库单已提交!');
closeReturnInModal();
}
function saveReturnInDraft() {
alert('已保存为草稿');
closeReturnInModal();
}
// ===== Sidebar toggle =====
function toggleSidebar() {
document.querySelector('.sidebar').classList.toggle('collapsed');
document.querySelector('.main').classList.toggle('expanded');
}
// ===== Nav group toggle =====
function toggleNavGroup(header) {
header.classList.toggle('expanded');
const sub = header.nextElementSibling;
if (sub) sub.classList.toggle('expanded');
}
// ===== View bill detail =====
function viewBillDetail(billNo) {
document.querySelectorAll('.page-content').forEach(p => p.classList.remove('active'));
const target = document.getElementById('page-bill-detail');
if (target) target.classList.add('active');
const label = document.getElementById('detail-bill-no');
if (label) label.textContent = '账单号:' + billNo;
}
// ===== Company info tab toggle =====
function setInfoTab(el, type) {
document.querySelectorAll('.info-tabs .info-tab').forEach(tab => tab.classList.remove('active'));
el.classList.add('active');
document.querySelectorAll('.info-tab-content').forEach(c => c.classList.remove('active'));
const target = document.getElementById('info-' + type);
if (target) target.classList.add('active');
}
// ===== 资质文件查看弹窗 =====
function viewDoc(type, expire, status) {
document.getElementById('doc-modal-title').textContent = type + ' - 文件查看';
document.getElementById('doc-modal-type').textContent = type;
document.getElementById('doc-modal-status').textContent = status;
document.getElementById('doc-modal-expire').textContent = expire;
document.getElementById('doc-placeholder-text').textContent = type + ' 预览';
document.getElementById('doc-modal').classList.add('show');
}
function closeDocModal() {
document.getElementById('doc-modal').classList.remove('show');
}
// ===== Profile tab toggle =====
function setProfileTab(el, type) {
document.querySelectorAll('.info-tabs .info-tab').forEach(tab => tab.classList.remove('active'));
el.classList.add('active');
document.querySelectorAll('.info-tab-content').forEach(c => c.classList.remove('active'));
const target = document.getElementById('profile-' + type);
if (target) target.classList.add('active');
}
function toggleEditProfile(editing) {
document.getElementById('profile-view').style.display = editing ? 'none' : '';
document.getElementById('profile-edit').style.display = editing ? '' : 'none';
document.getElementById('btn-edit-profile').style.display = editing ? 'none' : '';
document.getElementById('profile-actions').style.display = editing ? '' : 'none';
if (editing) {
var firstInput = document.querySelector('#profile-edit input:not([disabled])');
if (firstInput) firstInput.focus();
}
}
function cancelEditProfile() {
// 恢复原始值
var fields = ['zhangwei','张伟','138****6789','zhangwei@huayuan.com','zhangwei_hy'];
var inputs = document.querySelectorAll('#profile-edit input:not([disabled])');
inputs.forEach(function(input, i) { if (fields[i]) input.value = fields[i]; });
toggleEditProfile(false);
}
function saveProfile() {
alert('保存成功!');
// 将编辑框的值同步到查看模式
var inputs = document.querySelectorAll('#profile-edit input:not([disabled])');
var viewValues = document.querySelectorAll('#profile-view .info-value');
inputs.forEach(function(input, i) {
if (viewValues[i]) viewValues[i].textContent = input.value;
});
toggleEditProfile(false);
}
function changePassword() { alert('密码修改成功!'); }
// ===== 贴标申请 =====
const LABELING_ORDER_KEY = 'by_labeling_orders_0812';
const LABELING_ORDER_SEED = [
{id:'labeling-seed-1',orderNo:'TB202608120001',customerNo:'KH20260812018',warehouse:'美西洛杉矶仓',labelRequirement:'换箱唛',skuCount:2,totalBoxes:18,status:'待处理',createdAt:'2026-08-12 09:05'},
{id:'labeling-seed-2',orderNo:'TB202608110002',customerNo:'KH20260811026',warehouse:'美东新泽西仓',labelRequirement:'换SKU标',skuCount:3,totalBoxes:24,status:'处理中',createdAt:'2026-08-11 14:20'},
{id:'labeling-seed-3',orderNo:'TB202608100003',customerNo:'KH20260810009',warehouse:'美西洛杉矶仓',labelRequirement:'既换箱唛,也换SKU标',skuCount:1,totalBoxes:10,status:'已完成',createdAt:'2026-08-10 16:45'}
];
let labelingFilteredOrders = null;
function escapeLabelingHtml(value) { return String(value == null ? '' : value).replace(/[&<>"']/g, char => ({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;'}[char])); }
function loadLabelingOrders() { try { const raw=localStorage.getItem(LABELING_ORDER_KEY); if(!raw)return JSON.parse(JSON.stringify(LABELING_ORDER_SEED)); const parsed=JSON.parse(raw); if(!Array.isArray(parsed))throw new Error('贴标申请数据格式无效'); const seedIds=new Set(LABELING_ORDER_SEED.map(item=>item.id)); const localOrders=parsed.filter(item=>item&&typeof item==='object'&&!seedIds.has(item.id)); return localOrders.concat(JSON.parse(JSON.stringify(LABELING_ORDER_SEED))); } catch(error) { return JSON.parse(JSON.stringify(LABELING_ORDER_SEED)); } }
function saveLabelingOrders(orders) { try { const seedIds=new Set(LABELING_ORDER_SEED.map(item=>item.id)); const localOrders=(Array.isArray(orders)?orders:[]).filter(item=>item&&typeof item==='object'&&!seedIds.has(item.id)); localStorage.setItem(LABELING_ORDER_KEY,JSON.stringify(localOrders)); return true; } catch(error) { return false; } }
function labelingNav() { return document.querySelector('.dash-nav-link[onclick*="labeling-list"]'); }
function openLabelingList() { labelingFilteredOrders=null; renderLabelingList(); dashNavigate('labeling-list',labelingNav()); }
function openLabelingCreate() { resetLabelingForm(); dashNavigate('labeling',labelingNav()); }
function renderLabelingList() { const body=document.getElementById('labeling-list-body'); if(!body)return; const orders=labelingFilteredOrders===null?loadLabelingOrders():labelingFilteredOrders; body.innerHTML=orders.length?orders.map(order=>'<tr><td>'+escapeLabelingHtml(order.orderNo)+'</td><td>'+escapeLabelingHtml(order.customerNo)+'</td><td>'+escapeLabelingHtml(order.warehouse)+'</td><td>'+escapeLabelingHtml(order.labelRequirement)+'</td><td>'+Number(order.skuCount||0)+'</td><td>'+Number(order.totalBoxes||0)+'</td><td><span class="status-badge status-processing">'+escapeLabelingHtml(order.status)+'</span></td><td>'+escapeLabelingHtml(order.createdAt)+'</td></tr>').join(''):'<tr class="empty-state"><td colspan="8"><div class="empty-text">暂无贴标申请</div></td></tr>'; const total=document.getElementById('labeling-total'); if(total)total.textContent=orders.length; }
function filterLabelingOrders() { const orderNo=(document.getElementById('labeling-filter-order-no')?.value||'').trim().toLowerCase(),customerNo=(document.getElementById('labeling-filter-customer-no')?.value||'').trim().toLowerCase(),status=document.getElementById('labeling-filter-status')?.value||''; labelingFilteredOrders=loadLabelingOrders().filter(order=>(!orderNo||String(order.orderNo).toLowerCase().includes(orderNo))&&(!customerNo||String(order.customerNo).toLowerCase().includes(customerNo))&&(!status||order.status===status)); renderLabelingList(); }
function resetLabelingFilters() { ['labeling-filter-order-no','labeling-filter-customer-no','labeling-filter-status'].forEach(id=>{const el=document.getElementById(id);if(el)el.value='';}); labelingFilteredOrders=null; renderLabelingList(); }
function resetLabelingForm() { const form=document.getElementById('labeling-form'); if(form)form.reset(); const preview=document.getElementById('label-preview'); if(preview)preview.innerHTML=''; const tbody=document.getElementById('labeling-tbody'); if(tbody)tbody.innerHTML='<tr class="empty-state"><td colspan="12"><div class="empty-text">暂无货物明细,请点击「添加行」</div></td></tr>'; }
function handleLabelFiles(files) {
var preview = document.getElementById('label-preview');
Array.from(files).forEach(function(file) {
if (!file.type.startsWith('image/')) return;
var reader = new FileReader();
reader.onload = function(e) {
var item = document.createElement('div');
item.className = 'upload-preview-item';
item.innerHTML = '<img src="'+e.target.result+'"><div class="upload-remove" onclick="this.parentElement.remove()">×</div><div class="upload-filename">'+file.name+'</div>';
preview.appendChild(item);
};
reader.readAsDataURL(file);
});
document.getElementById('label-file-input').value = '';
}
(function() {
var zone = document.getElementById('label-upload-zone');
if (!zone) return;
zone.addEventListener('dragover', function(e) { e.preventDefault(); zone.classList.add('dragover'); });
zone.addEventListener('dragleave', function() { zone.classList.remove('dragover'); });
zone.addEventListener('drop', function(e) {
e.preventDefault();
zone.classList.remove('dragover');
if (e.dataTransfer.files) handleLabelFiles(e.dataTransfer.files);
});
})();
function addLabelingRow() {
var tbody = document.getElementById('labeling-tbody');
var empty = tbody.querySelector('.empty-state');
if (empty) tbody.innerHTML = '';
var tr = document.createElement('tr');
tr.innerHTML = '<td><input type="checkbox"></td>' +
'<td><input type="text" class="form-input labeling-sku" style="width:140px;" required></td>' +
'<td><label class="row-img-cell" onclick="this.querySelector(\'input\').click()">+<input type="file" accept="image/*" onchange="previewRowImage(this)"></label></td>' +
'<td><input type="text" class="form-input labeling-name" style="width:140px;" required></td>' +
'<td><input type="number" class="form-input labeling-boxes" min="1" style="width:80px;" required></td>' +
'<td><input type="number" class="form-input labeling-transfer-boxes" min="1" style="width:90px;" required></td>' +
'<td><input type="text" class="form-input" style="width:130px;"></td>' +
'<td><input type="text" class="form-input" style="width:140px;"></td>' +
'<td><input type="text" class="form-input" style="width:130px;"></td>' +
'<td><select class="form-input labeling-requirement" name="labelRequirement" style="width:180px;"><option>换箱唛</option><option>换SKU标</option><option>既换箱唛,也换SKU标</option></select></td>' +
'<td><label class="row-upload-cell" onclick="this.querySelector(\'input\').click()">📎 上传<input type="file" onchange="labelingFileName(this)"></label></td>' +
'<td><button type="button" class="btn btn-default" style="font-size:12px;padding:4px 10px;color:#ff4d4f;" onclick="this.closest(\'tr\').remove()">删除</button></td>';
tbody.appendChild(tr);
}
function clearLabelingRows() {
if (!confirm('确认清空所有货物明细?')) return;
var tbody = document.getElementById('labeling-tbody');
tbody.innerHTML = '<tr class="empty-state"><td colspan="12"><div class="empty-icon">📦</div><div class="empty-text">暂无货物明细,请点击「添加行」</div></td></tr>';
}
function previewRowImage(input) {
if (!input.files || !input.files[0]) return;
var reader = new FileReader();
reader.onload = function(e) {
var label = input.parentElement;
label.innerHTML = '<img src="'+e.target.result+'"><input type="file" accept="image/*" onchange="previewRowImage(this)">';
};
reader.readAsDataURL(input.files[0]);
}
function labelingFileName(input) {
if (!input.files || !input.files[0]) return;
var label = input.parentElement;
label.innerHTML = '✓ '+input.files[0].name+'<input type="file" onchange="labelingFileName(this)">';
}
function submitLabeling(event) {
if(event)event.preventDefault();
var form = document.getElementById('labeling-form');
var tbody = document.getElementById('labeling-tbody');
if(!form||!form.checkValidity()){if(form)form.reportValidity();return false;}
if (tbody.querySelector('.empty-state')) { showToast('请至少添加一行货物明细'); return false; }
var rows=Array.from(tbody.querySelectorAll('tr'));
if(!rows.length){showToast('请至少添加一行货物明细');return false;}
for(var row of rows){if(!row.querySelector('.labeling-sku').value.trim()||!row.querySelector('.labeling-name').value.trim()||Number(row.querySelector('.labeling-boxes').value)<1||Number(row.querySelector('.labeling-transfer-boxes').value)<1){showToast('请完整填写货物明细');return false;}}
var orders=loadLabelingOrders(),now=new Date(),date=now.getFullYear()+String(now.getMonth()+1).padStart(2,'0')+String(now.getDate()).padStart(2,'0'),sequence=String(orders.length+1).padStart(4,'0'),requirements=[...new Set(rows.map(row=>row.querySelector('.labeling-requirement').value))];
var order={id:'labeling-'+now.getTime(),orderNo:'TB'+date+sequence,customerNo:form.elements.customerNo.value.trim(),warehouse:form.elements.warehouse.value,deadline:form.elements.deadline.value,contact:form.elements.contact.value.trim(),phone:form.elements.phone.value.trim(),remark:form.elements.remark.value.trim(),labelRequirement:requirements.join('、'),skuCount:rows.length,totalBoxes:rows.reduce((sum,row)=>sum+Number(row.querySelector('.labeling-boxes').value||0),0),status:'待处理',createdAt:now.getFullYear()+'-'+String(now.getMonth()+1).padStart(2,'0')+'-'+String(now.getDate()).padStart(2,'0')+' '+String(now.getHours()).padStart(2,'0')+':'+String(now.getMinutes()).padStart(2,'0')};
if(!saveLabelingOrders([order].concat(orders))){showToast('保存失败,请检查浏览器存储设置');return false;}
labelingFilteredOrders=null;renderLabelingList();showToast('贴标申请提交成功');openLabelingList();return false;
}
document.addEventListener('DOMContentLoaded',renderLabelingList);
// ===== Dest tab toggle =====
function setDestTab(el, type) {
document.querySelectorAll('#dest-tabs .dest-tab').forEach(tab => tab.classList.remove('active'));
el.classList.add('active');
document.querySelectorAll('.dest-content').forEach(c => c.classList.remove('active'));
const target = document.getElementById('dest-' + type);
if (target) target.classList.add('active');
}
// ===== Pickup tab toggle =====
function setPickupTab(el, type) {
document.querySelectorAll('#pickup-tabs .dest-tab').forEach(tab => tab.classList.remove('active'));
el.classList.add('active');
document.querySelectorAll('.dest-content').forEach(c => c.classList.remove('active'));
const target = document.getElementById('pickup-' + type);
if (target) target.classList.add('active');
}
// ===== Bulk Pickup tab toggle =====
function setPickupTabBulk(el, type) {
document.querySelectorAll('#pickup-tabs-bulk .dest-tab').forEach(tab => tab.classList.remove('active'));
el.classList.add('active');
document.querySelectorAll('.dest-content-bulk').forEach(c => c.classList.remove('active'));
const target = document.getElementById('pickup-bulk-' + type);
if (target) target.classList.add('active');
}
// ===== Bulk order table =====
let bulkRowCount = 0;
function addBulkRow() {
bulkRowCount++;
const emptyRow = document.getElementById('bulk-empty-row');
if (emptyRow) emptyRow.remove();
const tbody = document.getElementById('bulk-tbody');
const cols = ['FBA仓','','','','','','','','','','','1','1','1','','','','是','否','否','',''];
const inputs = cols.map((v, i) => {
if (i === 0) return `<select style="width:80px;height:28px;border:1px solid transparent;border-radius:4px;font-size:12px;background:transparent;padding:0 4px;" onmouseover="this.style.borderColor='#d9d9d9'" onmouseout="this.style.borderColor='transparent'"><option>FBA仓</option><option>海外仓</option><option>私人仓</option></select>`;
if ([17,18,19].includes(i)) return `<select style="width:60px;height:28px;border:1px solid transparent;border-radius:4px;font-size:12px;background:transparent;padding:0 4px;" onmouseover="this.style.borderColor='#d9d9d9'" onmouseout="this.style.borderColor='transparent'"><option>否</option><option>是</option></select>`;
return `<input type="text" value="${v}" style="width:100%;min-width:80px;height:28px;padding:0 6px;border:1px solid transparent;border-radius:4px;font-size:12px;background:transparent;outline:none;" onmouseover="this.style.borderColor='#d9d9d9'" onmouseout="if(document.activeElement!==this)this.style.borderColor='transparent'" onfocus="this.style.borderColor='#1677ff'" onblur="this.style.borderColor='transparent'" placeholder="">`;
});
const tr = document.createElement('tr');
tr.style.borderBottom = '1px solid #f5f5f5';
tr.innerHTML = `<td style="padding:6px 8px;text-align:center;"><input type="checkbox" class="bulk-row-check"></td>
<td style="padding:6px 8px;text-align:center;color:#bfbfbf;font-size:12px;">${bulkRowCount}</td>
${inputs.map(inp => `<td style="padding:4px 6px;">${inp}</td>`).join('')}`;
tbody.appendChild(tr);
}
function deleteBulkRows() {
document.querySelectorAll('.bulk-row-check:checked').forEach(cb => cb.closest('tr').remove());
if (!document.getElementById('bulk-tbody').querySelector('tr:not(#bulk-empty-row)')) {
bulkRowCount = 0;
document.getElementById('bulk-tbody').innerHTML = '<tr id="bulk-empty-row"><td colspan="24" style="padding:40px 0;text-align:center;color:#bfbfbf;"><div style="font-size:28px;margin-bottom:8px;">📦</div><div style="font-size:13px;">暂无数据,请点击「添加行」或导入 Excel</div></td></tr>';
}
}
function toggleBulkAll(el) {
document.querySelectorAll('.bulk-row-check').forEach(cb => cb.checked = el.checked);
}
// ===== Goods table row management =====
let rowCount = 0;
function addRow() {
rowCount++;
const emptyRow = document.getElementById('empty-row');
if (emptyRow) emptyRow.remove();
const tbody = document.getElementById('goods-tbody');
const row = document.createElement('tr');
row.dataset.rowId = rowCount;
row.innerHTML = `
<td><input type="checkbox" class="row-check"></td>
<td style="text-align:center;color:#8c8c8c;font-size:11px;">${rowCount}</td>
<td><input class="td-input" placeholder="SKU编号"></td>
<td><input class="td-input" placeholder="中文品名"></td>
<td><label style="cursor:pointer;display:flex;align-items:center;justify-content:center;height:30px;width:40px;border:1px dashed #d9d9d9;border-radius:4px;font-size:16px;color:#bfbfbf;" title="上传图片">+</label></td>
<td><input class="td-input" placeholder="English Name"></td>
<td><input class="td-input" placeholder="HS Code"></td>
<td><input class="td-input" placeholder="HS Code"></td>
<td><input class="td-input" type="number" placeholder="L" style="width:60px"></td>
<td><input class="td-input" type="number" placeholder="W" style="width:60px"></td>
<td><input class="td-input" type="number" placeholder="H" style="width:60px"></td>
<td><input class="td-input" type="number" placeholder="0"></td>
<td><input class="td-input" type="number" placeholder="0"></td>
<td><input class="td-input" type="number" placeholder="0.00"></td>
<td><input class="td-input" type="number" placeholder="0.000"></td>
<td><input class="td-input" type="number" placeholder="0"></td>
<td><input class="td-input" type="number" placeholder="0.00"></td>
<td><input class="td-input" type="number" placeholder="0.00"></td>
<td><input class="td-input" type="number" placeholder="0.00"></td>
<td><input class="td-input" placeholder="材质"></td>
<td><input class="td-input" placeholder="用途"></td>
<td><input class="td-input" placeholder="型号"></td>
<td><input class="td-input" placeholder="品牌"></td>
<td><input class="td-input" placeholder="L×W×H cm"></td>
<td><input class="td-input" placeholder="SHIPMENT ID"></td>
<td><input class="td-input" placeholder="REFERENCE ID"></td>
<td><input class="td-input" placeholder="UPC编号"></td>
<td><input class="td-input" placeholder="备注"></td>
`;
tbody.appendChild(row);
}
function deleteSelectedRows() {
const checkboxes = document.querySelectorAll('.row-check:checked');
if (checkboxes.length === 0) { alert('请先勾选要删除的行'); return; }
checkboxes.forEach(cb => cb.closest('tr').remove());
if (document.querySelectorAll('#goods-tbody tr').length === 0) {
document.getElementById('goods-tbody').innerHTML = `<tr class="empty-row" id="empty-row"><td colspan="28" style="text-align:center;padding:40px;color:#bfbfbf;"><div style="font-size:32px;margin-bottom:8px;">📦</div><div style="font-size:13px;">暂无货物明细,请点击「添加行」或上传 Excel</div></td></tr>`;
rowCount = 0;
}
document.querySelectorAll('#goods-tbody tr:not(.empty-row)').forEach((row, i) => {
const numCell = row.cells[1];
if (numCell) numCell.textContent = i + 1;
});
}
function toggleAllGoods(el) {
document.querySelectorAll('.row-check').forEach(cb => cb.checked = el.checked);
}
function toggleAllTable(tableId, el) {
document.querySelectorAll('#' + tableId + ' tbody input[type=checkbox]').forEach(cb => cb.checked = el.checked);
}
function submitOrder() {
const rows = document.querySelectorAll('#goods-tbody tr:not(.empty-row)');
if (rows.length === 0) {
alert('请至少添加一行货物明细后再提交');
return;
}
alert('订单提交成功!系统将发送确认通知至您的联系邮箱。');
}
// ===== 费用预估选择 =====
let selectedCostIndex = 1;
function selectCost(el, index) {
selectedCostIndex = index;
document.querySelectorAll('.cost-card').forEach(c => c.classList.remove('active'));
el.classList.add('active');
}
// ===== Quick Order functions =====
let quickRowIndex = 2;
function addQuickRow() {
const tbody = document.getElementById('quick-rows');
const tr = document.createElement('tr');
tr.className = 'quick-row';
tr.innerHTML = `
<td>
<div class="select-wrap">
<select class="form-select">
<option value="">请选择</option>
<option>美线普货专线</option>
<option>美线敏感货专线</option>
<option>美线快线</option>
<option>美线FBA直送</option>
</select>
</div>
</td>
<td>
<label class="radio-label" style="display:block;margin-bottom:4px;"><input type="radio" name="dest${quickRowIndex}"> FBA</label>
<label class="radio-label" style="display:block;margin-bottom:4px;"><input type="radio" name="dest${quickRowIndex}"> 海外仓</label>
<label class="radio-label" style="display:block;"><input type="radio" name="dest${quickRowIndex}"> 私人仓</label>
</td>
<td>
<a href="javascript:void(0)" onclick="addProduct(this)" style="color:#1677ff;font-size:13px;">+ 添加产品</a>
<a href="javascript:void(0)" onclick="delQuickRow(this)" style="color:#ff4d4f;font-size:13px;margin-left:10px;">- 删除本行</a>
</td>
<td>
<div class="product-line">
<input type="text" class="form-input" placeholder="产品SKU" style="width:140px;">
<input type="number" class="form-input" value="0" style="width:80px;text-align:center;">
<a href="javascript:void(0)" onclick="delProduct(this)" style="color:#ff4d4f;font-size:13px;">- 删除此产品</a>
</div>
</td>
`;
tbody.appendChild(tr);
quickRowIndex++;
}
function delQuickRow(el) {
const rows = document.querySelectorAll('#quick-rows .quick-row');
if (rows.length <= 1) { alert('至少需要保留一行'); return; }
el.closest('tr').remove();
}
function addProduct(el) {
const td = el.closest('tr').querySelector('td:last-child');
const div = document.createElement('div');
div.className = 'product-line';
div.innerHTML = `
<input type="text" class="form-input" placeholder="产品SKU" style="width:140px;">
<input type="number" class="form-input" value="0" style="width:80px;text-align:center;">
<a href="javascript:void(0)" onclick="delProduct(this)" style="color:#ff4d4f;font-size:13px;">- 删除此产品</a>
`;
td.appendChild(div);
}
function delProduct(el) {
const td = el.closest('td');
const lines = td.querySelectorAll('.product-line');
if (lines.length <= 1) { alert('每行至少需要保留一个产品'); return; }
el.closest('.product-line').remove();
}
function submitQuickOrder() {
alert('快速订单提交成功!');
}
</script>
</body>
</html>