5098 lines
375 KiB
HTML
5098 lines
375 KiB
HTML
<!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> </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()">×</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()">×</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="关闭">×</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="关闭">×</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 => ({'&':'&','<':'<','>':'>','"':'"',"'":'''}[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, '&').replace(/</g, '<').replace(/>/g, '>')
|
||
.replace(/"/g, '"').replace(/'/g, ''');
|
||
}
|
||
|
||
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,'&').replace(/</g,'<').replace(/>/g,'>').replace(/"/g,'"').replace(/'/g,''');}
|
||
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,'&').replace(/</g,'<').replace(/>/g,'>').replace(/"/g,'"').replace(/'/g,'''); }
|
||
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 => ({'&':'&','<':'<','>':'>','"':'"',"'":'''}[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>
|
||
|
||
|
||
|
||
|