优化
This commit is contained in:
+35
-14
@@ -1134,29 +1134,29 @@
|
||||
<p class="text-lg text-gray-600" data-i18n="cont_subtitle">随时欢迎咨询,我们的专业团队将为您提供跨境物流解决方案与报价。</p>
|
||||
</div>
|
||||
|
||||
<div class="grid md:grid-cols-2 lg:grid-cols-4 gap-8">
|
||||
<div class="bg-white rounded-2xl p-8 shadow-card border border-gray-100 text-center reveal">
|
||||
<div class="w-14 h-14 rounded-full bg-blue-50 flex items-center justify-center text-brand-blue text-2xl mx-auto mb-5">
|
||||
<i class="fas fa-map-marker-alt"></i>
|
||||
</div>
|
||||
<h4 class="text-lg font-bold text-gray-900 mb-2" data-i18n="cont_addr_t">公司地址</h4>
|
||||
<p class="text-gray-600 text-sm leading-relaxed" data-i18n="cont_addr_d">浙江省义乌市福田街道稠州北路 1399 号 8613-8615 室</p>
|
||||
</div>
|
||||
<div class="bg-white rounded-2xl p-8 shadow-card border border-gray-100 text-center reveal" style="transition-delay: 0.05s;">
|
||||
<div class="flex items-center gap-3 mb-6 reveal"><div class="w-10 h-10 rounded-xl bg-blue-50 flex items-center justify-center text-brand-blue"><i class="fas fa-map-marker-alt"></i></div><h3 class="text-2xl font-bold text-gray-900" data-i18n="cont_addr_t">公司地址</h3></div>
|
||||
<div class="grid md:grid-cols-2 lg:grid-cols-4 gap-5 mb-8">
|
||||
<div class="bg-white rounded-2xl p-6 shadow-card border border-gray-100 reveal"><div class="text-xs font-bold tracking-wider text-brand-blue mb-3" data-i18n="cont_addr_sz_t">深圳</div><p class="text-gray-600 text-sm leading-relaxed" data-i18n="cont_addr_sz_d">深圳市龙岗区坂田街道万科万致天地A座3218室</p></div>
|
||||
<div class="bg-white rounded-2xl p-6 shadow-card border border-gray-100 reveal" style="transition-delay:0.05s"><div class="text-xs font-bold tracking-wider text-brand-blue mb-3" data-i18n="cont_addr_yw_t">义乌</div><p class="text-gray-600 text-sm leading-relaxed" data-i18n="cont_addr_yw_d">浙江省义乌市福田街道稠州北路 1399 号 8613-8615 室</p></div>
|
||||
<div class="bg-white rounded-2xl p-6 shadow-card border border-gray-100 reveal" style="transition-delay:0.1s"><div class="text-xs font-bold tracking-wider text-brand-blue mb-3" data-i18n="cont_addr_ny_t">纽约</div><p class="text-gray-600 text-sm leading-relaxed" data-i18n="cont_addr_ny_d">Door 13-14, 75 Carter Dr, Edison, New Jersey 08817</p></div>
|
||||
<div class="bg-white rounded-2xl p-6 shadow-card border border-gray-100 reveal" style="transition-delay:0.15s"><div class="text-xs font-bold tracking-wider text-brand-blue mb-3" data-i18n="cont_addr_la_t">洛杉矶</div><p class="text-gray-600 text-sm leading-relaxed" data-i18n="cont_addr_la_d">10767 7th Street, Rancho Cucamonga, California 91730</p></div>
|
||||
</div>
|
||||
<div class="grid md:grid-cols-3 gap-5">
|
||||
<div class="bg-white rounded-2xl p-7 shadow-card border border-gray-100 text-center reveal">
|
||||
<div class="w-14 h-14 rounded-full bg-green-50 flex items-center justify-center text-brand-green text-2xl mx-auto mb-5">
|
||||
<i class="fas fa-phone-alt"></i>
|
||||
</div>
|
||||
<h4 class="text-lg font-bold text-gray-900 mb-2" data-i18n="cont_phone_t">联系电话</h4>
|
||||
<p class="text-gray-600 text-sm leading-relaxed">0579-85875557</p>
|
||||
</div>
|
||||
<div class="bg-white rounded-2xl p-8 shadow-card border border-gray-100 text-center reveal" style="transition-delay: 0.1s;">
|
||||
<div class="bg-white rounded-2xl p-7 shadow-card border border-gray-100 text-center reveal" style="transition-delay: 0.05s;">
|
||||
<div class="w-14 h-14 rounded-full bg-cyan-50 flex items-center justify-center text-brand-teal text-2xl mx-auto mb-5">
|
||||
<i class="fas fa-envelope"></i>
|
||||
</div>
|
||||
<h4 class="text-lg font-bold text-gray-900 mb-2" data-i18n="cont_email_t">电子邮箱</h4>
|
||||
<p class="text-gray-600 text-sm leading-relaxed break-all">contact@baiyuelogistics.com</p>
|
||||
</div>
|
||||
<div class="bg-white rounded-2xl p-8 shadow-card border border-gray-100 text-center reveal" style="transition-delay: 0.15s;">
|
||||
<div class="bg-white rounded-2xl p-7 shadow-card border border-gray-100 text-center reveal" style="transition-delay: 0.1s;">
|
||||
<div class="w-14 h-14 rounded-full bg-indigo-50 flex items-center justify-center text-indigo-600 text-2xl mx-auto mb-5">
|
||||
<i class="fas fa-clock"></i>
|
||||
</div>
|
||||
@@ -1744,7 +1744,14 @@
|
||||
cont_title: "联系我们",
|
||||
cont_subtitle: "随时欢迎咨询,我们的专业团队将为您提供跨境物流解决方案与报价。",
|
||||
cont_addr_t: "公司地址",
|
||||
cont_addr_d: "浙江省义乌市福田街道稠州北路 1399 号 8613-8615 室",
|
||||
cont_addr_la_t: "洛杉矶",
|
||||
cont_addr_la_d: "10767 7th Street, Rancho Cucamonga, California 91730",
|
||||
cont_addr_ny_t: "纽约",
|
||||
cont_addr_ny_d: "Door 13-14, 75 Carter Dr, Edison, New Jersey 08817",
|
||||
cont_addr_yw_t: "义乌",
|
||||
cont_addr_yw_d: "浙江省义乌市福田街道稠州北路 1399 号 8613-8615 室",
|
||||
cont_addr_sz_t: "深圳",
|
||||
cont_addr_sz_d: "深圳市龙岗区坂田街道万科万致天地A座3218室",
|
||||
cont_phone_t: "联系电话",
|
||||
cont_email_t: "电子邮箱",
|
||||
cont_hours_t: "工作时间",
|
||||
@@ -1933,7 +1940,14 @@
|
||||
cont_title: "Contact Us",
|
||||
cont_subtitle: "You are always welcome to reach out — our team will provide cross-border logistics solutions and quotes.",
|
||||
cont_addr_t: "Address",
|
||||
cont_addr_d: "Room 8613-8615, No.1399 Chouzhou North Rd, Futian St., Yiwu, Zhejiang, China",
|
||||
cont_addr_la_t: "Los Angeles",
|
||||
cont_addr_la_d: "10767 7th Street, Rancho Cucamonga, California 91730",
|
||||
cont_addr_ny_t: "New York",
|
||||
cont_addr_ny_d: "Door 13-14, 75 Carter Dr, Edison, New Jersey 08817",
|
||||
cont_addr_yw_t: "Yiwu",
|
||||
cont_addr_yw_d: "Room 8613-8615, No. 1399 Chouzhou North Road, Futian Street, Yiwu, Zhejiang, China",
|
||||
cont_addr_sz_t: "Shenzhen",
|
||||
cont_addr_sz_d: "Room 3218, Tower A, Vanke Wanzhi Tiandi, Bantian Street, Longgang District, Shenzhen, China",
|
||||
cont_phone_t: "Phone",
|
||||
cont_email_t: "Email",
|
||||
cont_hours_t: "Business Hours",
|
||||
@@ -2122,7 +2136,14 @@
|
||||
cont_title: "Contáctanos",
|
||||
cont_subtitle: "Siempre eres bienvenido a contactarnos: nuestro equipo te ofrecerá soluciones logísticas y cotizaciones.",
|
||||
cont_addr_t: "Dirección",
|
||||
cont_addr_d: "Sala 8613-8615, No.1399 Chouzhou North Rd, Calle Futian, Yiwu, Zhejiang, China",
|
||||
cont_addr_la_t: "Los Ángeles",
|
||||
cont_addr_la_d: "10767 7th Street, Rancho Cucamonga, California 91730",
|
||||
cont_addr_ny_t: "Nueva York",
|
||||
cont_addr_ny_d: "Door 13-14, 75 Carter Dr, Edison, New Jersey 08817",
|
||||
cont_addr_yw_t: "Yiwu",
|
||||
cont_addr_yw_d: "Sala 8613-8615, No. 1399 Chouzhou North Road, Futian, Yiwu, Zhejiang, China",
|
||||
cont_addr_sz_t: "Shenzhen",
|
||||
cont_addr_sz_d: "Sala 3218, Torre A, Vanke Wanzhi Tiandi, Bantian, Longgang, Shenzhen, China",
|
||||
cont_phone_t: "Teléfono",
|
||||
cont_email_t: "Correo",
|
||||
cont_hours_t: "Horario",
|
||||
|
||||
@@ -1377,7 +1377,7 @@
|
||||
</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-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>
|
||||
@@ -2116,11 +2116,11 @@
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="col-checkbox"><input type="checkbox" onchange="toggleAllTable('inbound-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>
|
||||
<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="25"><div class="empty-icon">📦</div><div class="empty-text">暂无数据</div></td></tr>
|
||||
<tr class="empty-state"><td colspan="23"><div class="empty-icon">📦</div><div class="empty-text">暂无数据</div></td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
@@ -2454,7 +2454,7 @@
|
||||
<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 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>
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
# 退货换标列表字段改名 Implementation Plan
|
||||
|
||||
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
||||
|
||||
**Goal:** 将 0805 客户端退货换标列表中的“后台尾程订单号”“后台换标单号”分别改为“尾程订单号”“换标单号”。
|
||||
|
||||
**Architecture:** 仅修改退货换标列表的两个静态表头,不改表格数据字段、渲染逻辑或详情页。更新现有精确表头测试,并保留详情页后台关联文案断言作为范围保护。
|
||||
|
||||
**Tech Stack:** 静态 HTML、Node.js `node:assert` 校验脚本。
|
||||
|
||||
---
|
||||
|
||||
### Task 1: 修改退货换标列表表头
|
||||
|
||||
**Files:**
|
||||
- Modify: `tests/verify-return-relabel-consolidation.mjs`
|
||||
- Modify: `../官网头程下单/workbench.html`
|
||||
|
||||
- [x] **Step 1: 写入失败的列表表头测试**
|
||||
|
||||
在 `tests/verify-return-relabel-consolidation.mjs` 的列表列名期望中,将:
|
||||
|
||||
```js
|
||||
'后台尾程订单号',
|
||||
'后台换标单号',
|
||||
```
|
||||
|
||||
改为:
|
||||
|
||||
```js
|
||||
'尾程订单号',
|
||||
'换标单号',
|
||||
```
|
||||
|
||||
保留详情页测试中对“后台尾程订单号”“后台换标单号”的断言。
|
||||
|
||||
- [x] **Step 2: 运行测试并确认因旧表头失败**
|
||||
|
||||
Run:
|
||||
|
||||
```powershell
|
||||
node tests/verify-return-relabel-consolidation.mjs
|
||||
```
|
||||
|
||||
Expected: 列表表头测试因实际值仍包含“后台”而失败;详情页后台关联文案测试通过。
|
||||
|
||||
- [x] **Step 3: 修改最小生产代码**
|
||||
|
||||
在 `../官网头程下单/workbench.html` 的 `page-return-relabel-list` 表格中,将:
|
||||
|
||||
```html
|
||||
<th>后台尾程订单号</th><th>后台换标单号</th>
|
||||
```
|
||||
|
||||
改为:
|
||||
|
||||
```html
|
||||
<th>尾程订单号</th><th>换标单号</th>
|
||||
```
|
||||
|
||||
不修改 `page-return-relabel-detail` 和 `page-storage-transfer-list` 中的“后台”文案。
|
||||
|
||||
- [x] **Step 4: 运行定向测试并确认通过**
|
||||
|
||||
Run:
|
||||
|
||||
```powershell
|
||||
node tests/verify-return-relabel-consolidation.mjs
|
||||
```
|
||||
|
||||
Expected: 10 项退货换标测试全部通过。
|
||||
|
||||
- [x] **Step 5: 运行相关回归和范围检查**
|
||||
|
||||
Run:
|
||||
|
||||
```powershell
|
||||
node tests/verify-storage-transfer-prototype.mjs
|
||||
node tests/verify-cargo-disposal-prototype.mjs
|
||||
node tests/verify-architecture-html.mjs
|
||||
```
|
||||
|
||||
Expected: 仓储转运、货物废弃和架构测试全部通过。
|
||||
|
||||
再精确检查:
|
||||
|
||||
```powershell
|
||||
rg -n "尾程订单号|换标单号|后台关联单据" ../官网头程下单/workbench.html
|
||||
```
|
||||
|
||||
Expected: 退货换标列表表头不含“后台”;退货换标详情页和仓储转运相关文案仍保留“后台”。
|
||||
|
||||
由于当前目录不是 Git 仓库,本计划不包含提交步骤。
|
||||
@@ -0,0 +1,83 @@
|
||||
# 仓储转运栏目改名 Implementation Plan
|
||||
|
||||
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
||||
|
||||
**Goal:** 将 0805 客户端“海外仓”侧边栏的“仓储转运单”改为“仓储转运”,同时保留各业务页面中的订单名称。
|
||||
|
||||
**Architecture:** 仅修改侧边栏入口的可见文本,不改导航目标、页面标识或业务逻辑。更新直接读取海外仓菜单的测试期望,并增加页面标题保留断言,防止栏目改名扩散到订单文案。
|
||||
|
||||
**Tech Stack:** 静态 HTML、Node.js `node:assert` 校验脚本。
|
||||
|
||||
---
|
||||
|
||||
### Task 1: 调整菜单名称并验证范围
|
||||
|
||||
**Files:**
|
||||
- Modify: `tests/verify-storage-transfer-prototype.mjs`
|
||||
- Modify: `tests/verify-return-relabel-consolidation.mjs`
|
||||
- Modify: `tests/verify-cargo-disposal-prototype.mjs`
|
||||
- Modify: `../官网头程下单/workbench.html`
|
||||
|
||||
- [x] **Step 1: 写入失败的菜单文案测试**
|
||||
|
||||
将三个测试中的海外仓菜单期望由“仓储转运单”改为“仓储转运”。在 `tests/verify-storage-transfer-prototype.mjs` 中同时断言列表、新增和详情页标题仍包含:
|
||||
|
||||
```js
|
||||
assert.match(listPage, /<div class="page-title">仓储转运单<\/div>/);
|
||||
assert.match(createPage, /<div class="page-title"[^>]*>新增仓储转运单<\/div>/);
|
||||
assert.match(detailPage, /<div class="page-title">仓储转运单详情<\/div>/);
|
||||
```
|
||||
|
||||
- [x] **Step 2: 运行测试并确认因旧菜单名称失败**
|
||||
|
||||
Run:
|
||||
|
||||
```powershell
|
||||
node tests/verify-storage-transfer-prototype.mjs
|
||||
node tests/verify-return-relabel-consolidation.mjs
|
||||
node tests/verify-cargo-disposal-prototype.mjs
|
||||
```
|
||||
|
||||
Expected: 三个测试均因实际菜单仍为“仓储转运单”而失败;页面标题保留断言通过。
|
||||
|
||||
- [x] **Step 3: 修改最小生产代码**
|
||||
|
||||
在 `../官网头程下单/workbench.html` 的海外仓菜单中,将:
|
||||
|
||||
```html
|
||||
<span>仓储转运单</span>
|
||||
```
|
||||
|
||||
改为:
|
||||
|
||||
```html
|
||||
<span>仓储转运</span>
|
||||
```
|
||||
|
||||
保留 `dashNavigate('storage-transfer-list', this)` 以及其他所有“仓储转运单”页面文案。
|
||||
|
||||
- [x] **Step 4: 运行定向测试并确认通过**
|
||||
|
||||
Run:
|
||||
|
||||
```powershell
|
||||
node tests/verify-storage-transfer-prototype.mjs
|
||||
node tests/verify-return-relabel-consolidation.mjs
|
||||
node tests/verify-cargo-disposal-prototype.mjs
|
||||
```
|
||||
|
||||
Expected: 三个命令均输出通过信息并以退出码 0 结束。
|
||||
|
||||
- [x] **Step 5: 运行相关回归测试和文案范围检查**
|
||||
|
||||
Run:
|
||||
|
||||
```powershell
|
||||
node tests/verify-architecture-html.mjs
|
||||
python -m unittest tests/test_requirements_workbook.py
|
||||
rg -n "dashNavigate\('storage-transfer-list', this\)|仓储转运单" ../官网头程下单/workbench.html
|
||||
```
|
||||
|
||||
Expected: 架构与需求表测试通过;检索结果显示侧边栏导航行使用“仓储转运”,页面标题和订单文案继续使用“仓储转运单”。
|
||||
|
||||
由于当前目录不是 Git 仓库,本计划不包含提交步骤。
|
||||
@@ -0,0 +1,98 @@
|
||||
# 入库订单列表表头调整 Implementation Plan
|
||||
|
||||
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
||||
|
||||
**Goal:** 将 0805 客户端入库订单列表调整为截图对应的 23 列表头结构。
|
||||
|
||||
**Architecture:** 保留现有静态页面和表格组件,仅替换 `inbound-table` 的 `<thead>` 字段并同步空状态 `colspan`。新增独立 Node.js 测试精确解析入库表格,同时断言派送表仍保留原表头,限制修改范围。
|
||||
|
||||
**Tech Stack:** 静态 HTML、Node.js `node:test`、`node:assert`。
|
||||
|
||||
---
|
||||
|
||||
### Task 1: 建立入库表头回归测试
|
||||
|
||||
**Files:**
|
||||
- Create: `tests/verify-inbound-order-table.mjs`
|
||||
- Modify: `../官网头程下单/workbench.html`
|
||||
|
||||
- [x] **Step 1: 写入失败的表头测试**
|
||||
|
||||
创建 `tests/verify-inbound-order-table.mjs`,读取 `../../官网头程下单/workbench.html`,提取 `page-inbound` 页面和 `inbound-table`,并断言表头依次为:
|
||||
|
||||
```js
|
||||
[
|
||||
'',
|
||||
'序号',
|
||||
'操作',
|
||||
'入仓码',
|
||||
'渠道',
|
||||
'目的仓',
|
||||
'当前订单状态',
|
||||
'箱数',
|
||||
'快递公司',
|
||||
'快递单号',
|
||||
'SKUS',
|
||||
'总毛重',
|
||||
'总净重',
|
||||
'总体积',
|
||||
'总数量',
|
||||
'计费单价',
|
||||
'计费体积',
|
||||
'计费重量',
|
||||
'备注',
|
||||
'货件编号',
|
||||
'跟踪编号',
|
||||
'国内仓入库时间',
|
||||
'业务日期',
|
||||
]
|
||||
```
|
||||
|
||||
同时断言空状态单元格 `colspan="23"`,并断言 `delivery-table` 仍包含“单号”“派送状态”“国际单号”。
|
||||
|
||||
- [x] **Step 2: 运行测试并确认旧结构失败**
|
||||
|
||||
Run:
|
||||
|
||||
```powershell
|
||||
node tests/verify-inbound-order-table.mjs
|
||||
```
|
||||
|
||||
Expected: 入库表头断言失败,显示当前旧表头以“单号、件数、重量(kg)”开头;派送表保护断言通过。
|
||||
|
||||
- [x] **Step 3: 替换入库表格表头**
|
||||
|
||||
在 `../官网头程下单/workbench.html` 的 `inbound-table` 中保留首列复选框,将其余 `<th>` 替换为:
|
||||
|
||||
```html
|
||||
<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>
|
||||
```
|
||||
|
||||
将空状态行由 `colspan="25"` 改为 `colspan="23"`。不修改 `delivery-table`。
|
||||
|
||||
- [x] **Step 4: 运行定向测试并确认通过**
|
||||
|
||||
Run:
|
||||
|
||||
```powershell
|
||||
node tests/verify-inbound-order-table.mjs
|
||||
```
|
||||
|
||||
Expected: 入库表头、23 列空状态和派送表保护测试全部通过。
|
||||
|
||||
- [x] **Step 5: 运行相关回归测试和视觉检查**
|
||||
|
||||
Run:
|
||||
|
||||
```powershell
|
||||
node tests/verify-storage-transfer-prototype.mjs
|
||||
node tests/verify-return-relabel-consolidation.mjs
|
||||
node tests/verify-cargo-disposal-prototype.mjs
|
||||
node tests/verify-architecture-html.mjs
|
||||
```
|
||||
|
||||
Expected: 既有仓储转运、退货换标、货物废弃和架构测试全部通过。
|
||||
|
||||
在桌面浏览器中打开 `page-inbound`,确认 23 列按顺序渲染在横向滚动表格内,空状态横跨整表且其他页面未发生布局变化。
|
||||
|
||||
由于当前目录不是 Git 仓库,本计划不包含提交步骤。
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
# 退货换标列表字段改名设计
|
||||
|
||||
## 目标
|
||||
|
||||
在 0805 版本客户端“海外仓 → 退货换标”列表中,去掉两个关联单号表头中的“后台”字样。
|
||||
|
||||
## 修改范围
|
||||
|
||||
- 将列表表头“后台尾程订单号”改为“尾程订单号”。
|
||||
- 将列表表头“后台换标单号”改为“换标单号”。
|
||||
- 更新直接校验退货换标列表表头的自动化测试。
|
||||
|
||||
## 保持不变
|
||||
|
||||
- 表格列顺序、行数据及数据字段不变。
|
||||
- 查询、分页、查看详情和订单生成逻辑不变。
|
||||
- 详情页继续显示“后台关联单据”“后台尾程订单号”和“后台换标单号”。
|
||||
- 仓储转运单及其他业务模块中的同名字段不变。
|
||||
- 需求管理表、栏目架构图及其他版本不做修改。
|
||||
|
||||
## 验收标准
|
||||
|
||||
1. 退货换标列表依次显示“尾程订单号”和“换标单号”。
|
||||
2. 两列原有单号数据保持不变。
|
||||
3. 详情页的后台关联单据文案保持不变。
|
||||
4. 相关自动化测试通过。
|
||||
@@ -0,0 +1,25 @@
|
||||
# 仓储转运栏目改名设计
|
||||
|
||||
## 目标
|
||||
|
||||
在 0805 版本客户端“海外仓”菜单中,将侧边栏栏目名称由“仓储转运单”改为“仓储转运”。
|
||||
|
||||
## 修改范围
|
||||
|
||||
- 修改 `官网头程下单/workbench.html` 中“海外仓”侧边栏对应入口的可见文案。
|
||||
- 更新直接校验该侧边栏名称及菜单顺序的自动化测试。
|
||||
|
||||
## 保持不变
|
||||
|
||||
- 页面列表标题仍为“仓储转运单”。
|
||||
- 新增页、详情页、面包屑、成功提示及订单相关文案仍使用“仓储转运单”。
|
||||
- 页面 ID、CSS 类名、JavaScript 函数名、本地存储键和导航行为不变。
|
||||
- 需求管理表、栏目架构图及其他版本不做修改。
|
||||
|
||||
## 验收标准
|
||||
|
||||
1. 0805 客户端“海外仓”侧边栏显示“仓储转运”。
|
||||
2. 点击该入口仍进入原“仓储转运单”列表页。
|
||||
3. 列表、新增和详情页面中的订单名称保持“仓储转运单”。
|
||||
4. 海外仓其他菜单名称和顺序保持不变。
|
||||
5. 相关自动化测试通过。
|
||||
@@ -0,0 +1,28 @@
|
||||
# 入库订单列表表头调整设计
|
||||
|
||||
## 目标
|
||||
|
||||
在 0805 版本客户端“订单管理 → 入库订单列表”中,将实际表格表头调整为截图所示字段和顺序。
|
||||
|
||||
## 修改范围
|
||||
|
||||
- 保留表格首列的全选复选框。
|
||||
- 将其余表头依次调整为:序号、操作、入仓码、渠道、目的仓、当前订单状态、箱数、快递公司、快递单号、SKUS、总毛重、总净重、总体积、总数量、计费单价、计费体积、计费重量、备注、货件编号、跟踪编号、国内仓入库时间、业务日期。
|
||||
- 表格总列数为 23 列,包括首列复选框。
|
||||
- 将空数据行的 `colspan` 调整为 23。
|
||||
- 新增或更新自动化测试,精确校验表头名称、顺序及空状态跨列数。
|
||||
|
||||
## 保持不变
|
||||
|
||||
- 不新增截图中的“选择要显示的列”区域。
|
||||
- 不修改筛选条件、操作按钮、分页或导航。
|
||||
- 不新增示例订单数据。
|
||||
- 不修改派送订单列表及其他业务表格。
|
||||
- 不修改需求管理表、栏目架构图或其他版本。
|
||||
|
||||
## 验收标准
|
||||
|
||||
1. 入库订单列表展示 23 列,表头名称和顺序与本规格一致。
|
||||
2. 空数据状态横跨全部 23 列。
|
||||
3. 入库订单列表以外的页面不受影响。
|
||||
4. 相关自动化测试通过。
|
||||
Binary file not shown.
@@ -24,7 +24,7 @@ function fn(name) {
|
||||
test('cargo disposal navigation and page trio exist', () => {
|
||||
const warehouse = html.match(/<!-- 海外仓 -->([\s\S]*?)<!-- 订单管理 -->/);
|
||||
assert.ok(warehouse);
|
||||
assert.match(warehouse[1], /仓储转运单[\s\S]*货物废弃[\s\S]*退货换标/);
|
||||
assert.match(warehouse[1], /<span>仓储转运<\/span>[\s\S]*<span>货物废弃<\/span>[\s\S]*<span>退货换标<\/span>/);
|
||||
assert.match(warehouse[1], /dashNavigate\('cargo-disposal-list', this\)/);
|
||||
for (const id of ['page-cargo-disposal-list', 'page-cargo-disposal-create', 'page-cargo-disposal-detail']) page(id);
|
||||
});
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
import assert from 'node:assert/strict';
|
||||
import { existsSync, readFileSync } from 'node:fs';
|
||||
import { test } from 'node:test';
|
||||
|
||||
const prototypePath = new URL('../../官网头程下单/workbench.html', import.meta.url);
|
||||
const html = existsSync(prototypePath) ? readFileSync(prototypePath, 'utf8') : '';
|
||||
|
||||
function extractPageFragment(pageId) {
|
||||
const idMatch = new RegExp(`id=["']${pageId}["']`).exec(html);
|
||||
assert.ok(idMatch, `${pageId} should exist`);
|
||||
const start = html.lastIndexOf('<div', idMatch.index);
|
||||
const remainingHtml = html.slice(idMatch.index + idMatch[0].length);
|
||||
const nextPageMatch = /<div\s+class=["'][^"']*\bpage-content\b[^"']*["'][^>]*>/.exec(remainingHtml);
|
||||
const end = nextPageMatch
|
||||
? idMatch.index + idMatch[0].length + nextPageMatch.index
|
||||
: html.length;
|
||||
return html.slice(start, end);
|
||||
}
|
||||
|
||||
function extractHeaders(pageFragment, tableId) {
|
||||
const tableMatch = pageFragment.match(
|
||||
new RegExp(`<table[^>]*id=["']${tableId}["'][^>]*>([\\s\\S]*?)<\\/table>`),
|
||||
);
|
||||
assert.ok(tableMatch, `${tableId} should exist`);
|
||||
return [...tableMatch[1].matchAll(/<th[^>]*>([\s\S]*?)<\/th>/g)].map((match) =>
|
||||
match[1].replace(/<[^>]+>/g, '').trim(),
|
||||
);
|
||||
}
|
||||
|
||||
test('inbound order list matches the approved 23-column header contract', () => {
|
||||
const page = extractPageFragment('page-inbound');
|
||||
assert.deepEqual(extractHeaders(page, 'inbound-table'), [
|
||||
'',
|
||||
'序号',
|
||||
'操作',
|
||||
'入仓码',
|
||||
'渠道',
|
||||
'目的仓',
|
||||
'当前订单状态',
|
||||
'箱数',
|
||||
'快递公司',
|
||||
'快递单号',
|
||||
'SKUS',
|
||||
'总毛重',
|
||||
'总净重',
|
||||
'总体积',
|
||||
'总数量',
|
||||
'计费单价',
|
||||
'计费体积',
|
||||
'计费重量',
|
||||
'备注',
|
||||
'货件编号',
|
||||
'跟踪编号',
|
||||
'国内仓入库时间',
|
||||
'业务日期',
|
||||
]);
|
||||
assert.match(page, /<td colspan=["']23["']/);
|
||||
});
|
||||
|
||||
test('delivery order table keeps its existing status and tracking headers', () => {
|
||||
const page = extractPageFragment('page-delivery');
|
||||
const headers = extractHeaders(page, 'delivery-table');
|
||||
assert.ok(headers.includes('单号'));
|
||||
assert.ok(headers.includes('派送状态'));
|
||||
assert.ok(headers.includes('国际单号'));
|
||||
});
|
||||
@@ -40,7 +40,7 @@ test('overseas menu is consolidated to the three approved entries', () => {
|
||||
const labels = [...warehouseMenu[1].matchAll(/<a[^>]*class=["'][^"']*dash-nav-link\s+sub[^"']*["'][^>]*>[\s\S]*?<span[^>]*>([^<]+)<\/span>/g)].map((match) =>
|
||||
match[1].trim(),
|
||||
);
|
||||
assert.deepEqual(labels, ['贴标申请', '仓储转运单', '货物废弃', '退货换标']);
|
||||
assert.deepEqual(labels, ['贴标申请', '仓储转运', '货物废弃', '退货换标']);
|
||||
assert.doesNotMatch(warehouseMenu[1], /退货入库|退货出库/);
|
||||
});
|
||||
|
||||
@@ -61,8 +61,8 @@ test('return relabel list table has the consolidated order columns', () => {
|
||||
'退件总数',
|
||||
'是否换标',
|
||||
'贴标要求',
|
||||
'后台尾程订单号',
|
||||
'后台换标单号',
|
||||
'尾程订单号',
|
||||
'换标单号',
|
||||
'换标状态',
|
||||
'尾程订单状态',
|
||||
'创建时间',
|
||||
|
||||
@@ -43,7 +43,7 @@ test('storage transfer entry appears in the overseas warehouse menu in the appro
|
||||
const menuLabels = [...warehouseMenu[1].matchAll(/<a[^>]*class=["'][^"']*dash-nav-link\s+sub[^"']*["'][^>]*>[\s\S]*?<span[^>]*>([^<]+)<\/span>/g)].map((match) =>
|
||||
match[1].trim(),
|
||||
);
|
||||
assert.deepEqual(menuLabels, ['贴标申请', '仓储转运单', '货物废弃', '退货换标']);
|
||||
assert.deepEqual(menuLabels, ['贴标申请', '仓储转运', '货物废弃', '退货换标']);
|
||||
assert.ok(
|
||||
warehouseMenu[1].includes("dashNavigate('storage-transfer-list', this)"),
|
||||
"warehouse transfer menu should call dashNavigate('storage-transfer-list', this)",
|
||||
@@ -63,6 +63,7 @@ test('storage transfer list, create, and detail pages exist', () => {
|
||||
test('storage transfer list has the approved filters, columns, actions, and pagination', () => {
|
||||
const listPage = extractPageFragment('page-storage-transfer-list');
|
||||
assert.ok(listPage, 'storage transfer list page fragment should exist');
|
||||
assert.match(listPage, /<div class="page-title">仓储转运单<\/div>/);
|
||||
assert.match(
|
||||
listPage,
|
||||
/<input(?=[^>]*id=["']storage-transfer-filter-created-start["'])(?=[^>]*type=["']date["'])[^>]*>/,
|
||||
@@ -121,6 +122,8 @@ test('storage transfer form and detail expose required fields and backend relati
|
||||
const detailPage = extractPageFragment('page-storage-transfer-detail');
|
||||
assert.ok(createPage, 'storage transfer create page fragment should exist');
|
||||
assert.ok(detailPage, 'storage transfer detail page fragment should exist');
|
||||
assert.match(createPage, /<div class="page-title"[^>]*>新增仓储转运单<\/div>/);
|
||||
assert.match(detailPage, /<div class="page-title">仓储转运单详情<\/div>/);
|
||||
|
||||
for (const field of [
|
||||
'进仓编号',
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
[ 1885ms] [VERBOSE] [DOM] Password field is not contained in a form: (More info: https://goo.gl/9p2vKq) %o @ http://127.0.0.1:8783/%E8%B4%A7%E4%BB%A3SaaS%E5%B9%B3%E5%8F%B0%E5%8E%9F%E5%9E%8B.html:0
|
||||
[ 1885ms] [VERBOSE] [DOM] Password field is not contained in a form: (More info: https://goo.gl/9p2vKq) %o @ http://127.0.0.1:8783/%E8%B4%A7%E4%BB%A3SaaS%E5%B9%B3%E5%8F%B0%E5%8E%9F%E5%9E%8B.html:0
|
||||
[ 1885ms] [VERBOSE] [DOM] Password field is not contained in a form: (More info: https://goo.gl/9p2vKq) @ http://127.0.0.1:8783/%E8%B4%A7%E4%BB%A3SaaS%E5%B9%B3%E5%8F%B0%E5%8E%9F%E5%9E%8B.html:0
|
||||
[ 1885ms] [VERBOSE] [DOM] Password field is not contained in a form: (More info: https://goo.gl/9p2vKq) %o @ http://127.0.0.1:8783/%E8%B4%A7%E4%BB%A3SaaS%E5%B9%B3%E5%8F%B0%E5%8E%9F%E5%9E%8B.html:0
|
||||
[ 1885ms] [VERBOSE] [DOM] Password field is not contained in a form: (More info: https://goo.gl/9p2vKq) %o @ http://127.0.0.1:8783/%E8%B4%A7%E4%BB%A3SaaS%E5%B9%B3%E5%8F%B0%E5%8E%9F%E5%9E%8B.html:0
|
||||
[ 1886ms] [VERBOSE] [DOM] Password field is not contained in a form: (More info: https://goo.gl/9p2vKq) %o @ http://127.0.0.1:8783/%E8%B4%A7%E4%BB%A3SaaS%E5%B9%B3%E5%8F%B0%E5%8E%9F%E5%9E%8B.html:0
|
||||
@@ -0,0 +1,6 @@
|
||||
[ 282ms] [VERBOSE] [DOM] Password field is not contained in a form: (More info: https://goo.gl/9p2vKq) %o @ http://127.0.0.1:8783/%E8%B4%A7%E4%BB%A3SaaS%E5%B9%B3%E5%8F%B0%E5%8E%9F%E5%9E%8B.html:0
|
||||
[ 282ms] [VERBOSE] [DOM] Password field is not contained in a form: (More info: https://goo.gl/9p2vKq) %o @ http://127.0.0.1:8783/%E8%B4%A7%E4%BB%A3SaaS%E5%B9%B3%E5%8F%B0%E5%8E%9F%E5%9E%8B.html:0
|
||||
[ 282ms] [VERBOSE] [DOM] Password field is not contained in a form: (More info: https://goo.gl/9p2vKq) @ http://127.0.0.1:8783/%E8%B4%A7%E4%BB%A3SaaS%E5%B9%B3%E5%8F%B0%E5%8E%9F%E5%9E%8B.html:0
|
||||
[ 282ms] [VERBOSE] [DOM] Password field is not contained in a form: (More info: https://goo.gl/9p2vKq) %o @ http://127.0.0.1:8783/%E8%B4%A7%E4%BB%A3SaaS%E5%B9%B3%E5%8F%B0%E5%8E%9F%E5%9E%8B.html:0
|
||||
[ 282ms] [VERBOSE] [DOM] Password field is not contained in a form: (More info: https://goo.gl/9p2vKq) %o @ http://127.0.0.1:8783/%E8%B4%A7%E4%BB%A3SaaS%E5%B9%B3%E5%8F%B0%E5%8E%9F%E5%9E%8B.html:0
|
||||
[ 282ms] [VERBOSE] [DOM] Password field is not contained in a form: (More info: https://goo.gl/9p2vKq) %o @ http://127.0.0.1:8783/%E8%B4%A7%E4%BB%A3SaaS%E5%B9%B3%E5%8F%B0%E5%8E%9F%E5%9E%8B.html:0
|
||||
@@ -0,0 +1,16 @@
|
||||
[ 1620ms] [VERBOSE] [DOM] Password field is not contained in a form: (More info: https://goo.gl/9p2vKq) %o @ http://127.0.0.1:8784/%E8%B4%A7%E4%BB%A3SaaS%E5%B9%B3%E5%8F%B0%E5%8E%9F%E5%9E%8B.html:0
|
||||
[ 1620ms] [VERBOSE] [DOM] Password field is not contained in a form: (More info: https://goo.gl/9p2vKq) %o @ http://127.0.0.1:8784/%E8%B4%A7%E4%BB%A3SaaS%E5%B9%B3%E5%8F%B0%E5%8E%9F%E5%9E%8B.html:0
|
||||
[ 1620ms] [VERBOSE] [DOM] Password field is not contained in a form: (More info: https://goo.gl/9p2vKq) @ http://127.0.0.1:8784/%E8%B4%A7%E4%BB%A3SaaS%E5%B9%B3%E5%8F%B0%E5%8E%9F%E5%9E%8B.html:0
|
||||
[ 1620ms] [VERBOSE] [DOM] Password field is not contained in a form: (More info: https://goo.gl/9p2vKq) %o @ http://127.0.0.1:8784/%E8%B4%A7%E4%BB%A3SaaS%E5%B9%B3%E5%8F%B0%E5%8E%9F%E5%9E%8B.html:0
|
||||
[ 1621ms] [VERBOSE] [DOM] Password field is not contained in a form: (More info: https://goo.gl/9p2vKq) %o @ http://127.0.0.1:8784/%E8%B4%A7%E4%BB%A3SaaS%E5%B9%B3%E5%8F%B0%E5%8E%9F%E5%9E%8B.html:0
|
||||
[ 1621ms] [VERBOSE] [DOM] Password field is not contained in a form: (More info: https://goo.gl/9p2vKq) %o @ http://127.0.0.1:8784/%E8%B4%A7%E4%BB%A3SaaS%E5%B9%B3%E5%8F%B0%E5%8E%9F%E5%9E%8B.html:0
|
||||
[ 128496ms] TypeError: Cannot set properties of null (setting 'disabled')
|
||||
at renderLastMileOrderDetail (http://127.0.0.1:8784/%E8%B4%A7%E4%BB%A3SaaS%E5%B9%B3%E5%8F%B0%E5%8E%9F%E5%9E%8B.html:17801:89)
|
||||
at openLastMileOrderDetail (http://127.0.0.1:8784/%E8%B4%A7%E4%BB%A3SaaS%E5%B9%B3%E5%8F%B0%E5%8E%9F%E5%9E%8B.html:17792:173)
|
||||
at HTMLAnchorElement.onclick (http://127.0.0.1:8784/%E8%B4%A7%E4%BB%A3SaaS%E5%B9%B3%E5%8F%B0%E5%8E%9F%E5%9E%8B.html:1:1)
|
||||
[ 272844ms] [VERBOSE] [DOM] Password field is not contained in a form: (More info: https://goo.gl/9p2vKq) %o @ http://127.0.0.1:8784/%E8%B4%A7%E4%BB%A3SaaS%E5%B9%B3%E5%8F%B0%E5%8E%9F%E5%9E%8B.html:0
|
||||
[ 272844ms] [VERBOSE] [DOM] Password field is not contained in a form: (More info: https://goo.gl/9p2vKq) %o @ http://127.0.0.1:8784/%E8%B4%A7%E4%BB%A3SaaS%E5%B9%B3%E5%8F%B0%E5%8E%9F%E5%9E%8B.html:0
|
||||
[ 272844ms] [VERBOSE] [DOM] Password field is not contained in a form: (More info: https://goo.gl/9p2vKq) @ http://127.0.0.1:8784/%E8%B4%A7%E4%BB%A3SaaS%E5%B9%B3%E5%8F%B0%E5%8E%9F%E5%9E%8B.html:0
|
||||
[ 272844ms] [VERBOSE] [DOM] Password field is not contained in a form: (More info: https://goo.gl/9p2vKq) %o @ http://127.0.0.1:8784/%E8%B4%A7%E4%BB%A3SaaS%E5%B9%B3%E5%8F%B0%E5%8E%9F%E5%9E%8B.html:0
|
||||
[ 272844ms] [VERBOSE] [DOM] Password field is not contained in a form: (More info: https://goo.gl/9p2vKq) %o @ http://127.0.0.1:8784/%E8%B4%A7%E4%BB%A3SaaS%E5%B9%B3%E5%8F%B0%E5%8E%9F%E5%9E%8B.html:0
|
||||
[ 272844ms] [VERBOSE] [DOM] Password field is not contained in a form: (More info: https://goo.gl/9p2vKq) %o @ http://127.0.0.1:8784/%E8%B4%A7%E4%BB%A3SaaS%E5%B9%B3%E5%8F%B0%E5%8E%9F%E5%9E%8B.html:0
|
||||
@@ -0,0 +1,6 @@
|
||||
[ 1186ms] [VERBOSE] [DOM] Password field is not contained in a form: (More info: https://goo.gl/9p2vKq) %o @ http://127.0.0.1:8784/%E8%B4%A7%E4%BB%A3SaaS%E5%B9%B3%E5%8F%B0%E5%8E%9F%E5%9E%8B.html:0
|
||||
[ 1186ms] [VERBOSE] [DOM] Password field is not contained in a form: (More info: https://goo.gl/9p2vKq) %o @ http://127.0.0.1:8784/%E8%B4%A7%E4%BB%A3SaaS%E5%B9%B3%E5%8F%B0%E5%8E%9F%E5%9E%8B.html:0
|
||||
[ 1186ms] [VERBOSE] [DOM] Password field is not contained in a form: (More info: https://goo.gl/9p2vKq) @ http://127.0.0.1:8784/%E8%B4%A7%E4%BB%A3SaaS%E5%B9%B3%E5%8F%B0%E5%8E%9F%E5%9E%8B.html:0
|
||||
[ 1186ms] [VERBOSE] [DOM] Password field is not contained in a form: (More info: https://goo.gl/9p2vKq) %o @ http://127.0.0.1:8784/%E8%B4%A7%E4%BB%A3SaaS%E5%B9%B3%E5%8F%B0%E5%8E%9F%E5%9E%8B.html:0
|
||||
[ 1186ms] [VERBOSE] [DOM] Password field is not contained in a form: (More info: https://goo.gl/9p2vKq) %o @ http://127.0.0.1:8784/%E8%B4%A7%E4%BB%A3SaaS%E5%B9%B3%E5%8F%B0%E5%8E%9F%E5%9E%8B.html:0
|
||||
[ 1186ms] [VERBOSE] [DOM] Password field is not contained in a form: (More info: https://goo.gl/9p2vKq) %o @ http://127.0.0.1:8784/%E8%B4%A7%E4%BB%A3SaaS%E5%B9%B3%E5%8F%B0%E5%8E%9F%E5%9E%8B.html:0
|
||||
@@ -0,0 +1,6 @@
|
||||
[ 1898ms] [VERBOSE] [DOM] Password field is not contained in a form: (More info: https://goo.gl/9p2vKq) %o @ http://127.0.0.1:8784/%E8%B4%A7%E4%BB%A3SaaS%E5%B9%B3%E5%8F%B0%E5%8E%9F%E5%9E%8B.html:0
|
||||
[ 1898ms] [VERBOSE] [DOM] Password field is not contained in a form: (More info: https://goo.gl/9p2vKq) %o @ http://127.0.0.1:8784/%E8%B4%A7%E4%BB%A3SaaS%E5%B9%B3%E5%8F%B0%E5%8E%9F%E5%9E%8B.html:0
|
||||
[ 1898ms] [VERBOSE] [DOM] Password field is not contained in a form: (More info: https://goo.gl/9p2vKq) @ http://127.0.0.1:8784/%E8%B4%A7%E4%BB%A3SaaS%E5%B9%B3%E5%8F%B0%E5%8E%9F%E5%9E%8B.html:0
|
||||
[ 1898ms] [VERBOSE] [DOM] Password field is not contained in a form: (More info: https://goo.gl/9p2vKq) %o @ http://127.0.0.1:8784/%E8%B4%A7%E4%BB%A3SaaS%E5%B9%B3%E5%8F%B0%E5%8E%9F%E5%9E%8B.html:0
|
||||
[ 1898ms] [VERBOSE] [DOM] Password field is not contained in a form: (More info: https://goo.gl/9p2vKq) %o @ http://127.0.0.1:8784/%E8%B4%A7%E4%BB%A3SaaS%E5%B9%B3%E5%8F%B0%E5%8E%9F%E5%9E%8B.html:0
|
||||
[ 1898ms] [VERBOSE] [DOM] Password field is not contained in a form: (More info: https://goo.gl/9p2vKq) %o @ http://127.0.0.1:8784/%E8%B4%A7%E4%BB%A3SaaS%E5%B9%B3%E5%8F%B0%E5%8E%9F%E5%9E%8B.html:0
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,143 @@
|
||||
# 货代 SaaS 平台后台原型指引
|
||||
|
||||
## 首读入口
|
||||
|
||||
- 页面、字段和局部交互先按下方“原型模块快速索引”定位,再只读取命中的 `prototype-src/modules/*.html`。
|
||||
- 页面涉及弹窗、抽屉或跨模块交互时,再读取 `prototype-src/overlays.html` 和 `prototype-src/app.js` 中对应 ID/函数;视觉样式按需读取 `prototype-src/shell.html`。
|
||||
- `index.html` 是由拆分源码生成的完整可运行入口,本地预览直接双击它。`货代SaaS平台原型-完整备份.html` 仅作为迁移前的大文件备份,不作为日常入口。
|
||||
- WMS 字段未在原型中明确时,再读取 `wms_full_data.json` 和 `柏悦WMS系统文档.md`。
|
||||
|
||||
## 怎么看
|
||||
|
||||
- 本地看完整后台:双击 `index.html`。它是当前模块源码生成的可运行总入口,不要打开备份文件作为产品验收入口。
|
||||
- 查看某个业务模块:直接打开索引命中的 `prototype-src/modules/*.html`;模块文件是页面片段,不是可独立运行的完整 HTML,不能直接双击判断布局。
|
||||
- 查看某个页面:先在 `prototype-src/manifest.json` 搜索页面 ID,再在对应模块中搜索 `id="page-页面ID"`。
|
||||
- 查看页面字段:读取该页面容器内的 `<th>`、表单 `<label>`、按钮文字和 `id`;若 `<tbody>` 为空或由 `renderTable` 填充,继续读取 `prototype-src/app.js` 的数据数组和渲染函数。
|
||||
- 查看页面流程:从页面内的 `onclick`、`data-*` 和返回链接开始,追踪 `switchPage('页面ID')`、`showModal('弹窗ID')`、`render...()`、`save...()`、`submit...()`;弹窗定义在 `overlays.html`,函数通常在 `app.js`。
|
||||
- 查看导航入口:读取 `prototype-src/shell.html` 中对应 `.sidebar-item` 和 `.sub-menu-item`;页面存在但没有导航入口时,按历史/隐藏页面处理,不要自行假定它是当前产品入口。
|
||||
|
||||
## 怎么读取
|
||||
|
||||
### 产品确认页面
|
||||
|
||||
按以下顺序读取,满足需求即可停止,不要默认加载整个原型:
|
||||
|
||||
1. 本文件的“原型模块快速索引”。
|
||||
2. 命中的模块 HTML,定位 `page-页面ID`。
|
||||
3. 页面中涉及的弹窗 ID,读取 `prototype-src/overlays.html` 对应弹窗。
|
||||
4. 页面按钮引用的函数,读取 `prototype-src/app.js` 中对应函数及其直接调用的数据数组。
|
||||
5. 若涉及 WMS 字段,再读取 `wms_full_data.json` 或 `柏悦WMS系统文档.md`。
|
||||
|
||||
### 开发实现需求
|
||||
|
||||
读取结果至少记录:页面 ID、模块文件、导航入口、页面字段、操作按钮、弹窗 ID、跳转页面 ID、数据数组、渲染函数、保存/提交函数和状态变化。无法从原型确认的流程必须标记为“原型未定义”,不得用猜测补齐。
|
||||
|
||||
### 按页面 ID 定向检索
|
||||
|
||||
```powershell
|
||||
$page = 'clearance-doc'
|
||||
rg -n -C 3 "page-$page|switchPage\('$page'|render.*$page|$page" prototype-src
|
||||
```
|
||||
|
||||
检索结果跨模块时,以 `manifest.json` 的归属为准;不要因为同名数据或函数出现在共享脚本,就把页面移动到共享文件。
|
||||
|
||||
## 修改规则
|
||||
|
||||
- `prototype-src/modules/*.html`、`prototype-src/shell.html`、`prototype-src/overlays.html`、`prototype-src/app.js` 和 `prototype-src/tail.html` 是维护源码。
|
||||
- 页面主体放在唯一一个模块文件中;共用弹窗放 `overlays.html`,全局样式和导航壳放 `shell.html`,交互脚本放 `app.js`。
|
||||
- 新增、删除、改名或移动 `page-*` 时同步更新本文件中的模块索引和 `prototype-src/manifest.json`;页面 ID 在所有模块中必须唯一。
|
||||
- 修改后在本目录执行 `node scripts/build-prototype.cjs`,重建 `index.html`,再执行 `node tests/verify-prototype-modules.cjs`。
|
||||
- `node scripts/split-prototype.cjs` 会用完整原型覆盖全部拆分源码,仅用于首次迁移或明确需要从总文件重新拆分时,日常修改禁止执行。
|
||||
- 原型中的产品层级、文案和表格操作列继续遵守仓库根 `AGENTS.md`;原型不能替代阶段需求和已确认契约。
|
||||
|
||||
## 模块边界
|
||||
|
||||
- 模块按后台一级业务导航划分,列表、详情、新增、编辑及其同域隐藏页面保留在同一个模块文件。
|
||||
- `12-legacy-orders.html`、`13-freight-customs.html` 收纳当前侧栏未直接展示但完整原型仍保留的历史页面,修改前需先确认当前需求是否仍使用。
|
||||
- 不把同一业务拆成“一页一文件”;这会割裂列表与详情上下文,也会增加产品同步维护成本。
|
||||
|
||||
## 怎么加页面
|
||||
|
||||
### 新增普通页面
|
||||
|
||||
1. 先确定一级业务模块和唯一页面 ID,例如 `page-customs-audit`。
|
||||
2. 在对应 `prototype-src/modules/*.html` 的同域页面末尾添加完整 `<div class="page" id="page-...">...</div>`;列表、详情、新增、编辑页面放在同一模块。
|
||||
3. 在 `prototype-src/manifest.json` 的对应模块 `pages` 和 `pageOrder` 中登记页面 ID,保持页面顺序与生成入口一致。
|
||||
4. 若页面需要侧栏入口,在 `prototype-src/shell.html` 增加 `.sub-menu-item`,其调用必须是 `switchPage('页面ID',this)`。
|
||||
5. 若页面有动态表格或交互,在 `prototype-src/app.js` 增加数据、渲染和操作函数;共用弹窗放 `prototype-src/overlays.html`。
|
||||
6. 执行构建和校验命令,确认新页面能在 `index.html` 中找到且导航可进入。
|
||||
|
||||
### 新增弹窗或详情操作
|
||||
|
||||
- 页面内按钮只负责调用 `showModal('modal-唯一ID')` 或业务函数。
|
||||
- 弹窗 HTML 放 `prototype-src/overlays.html`,保存/提交逻辑放 `prototype-src/app.js`,不要把大段共用弹窗复制到多个模块。
|
||||
- 新增字段时同时检查弹窗初始值、校验、保存数据、列表渲染和详情展示。
|
||||
|
||||
## 怎么改页面
|
||||
|
||||
### 改静态字段或文案
|
||||
|
||||
1. 在模块文件中按 `page-页面ID` 定位目标页面。
|
||||
2. 修改对应 `<th>`、`<label>`、按钮或提示文字。
|
||||
3. 搜索旧字段文本和相关 `id`,确认详情、弹窗、空态和操作列没有遗漏。
|
||||
4. 构建并校验;如果字段是产品契约的一部分,同时核对对应阶段需求文档。
|
||||
|
||||
### 改动态表格字段
|
||||
|
||||
必须同时检查四处:
|
||||
|
||||
- 模块 HTML 的 `<th>` 顺序和表格容器。
|
||||
- `app.js` 的数据数组字段名。
|
||||
- `renderTable(...)` 或专用 `render...()` 的列映射。
|
||||
- 操作列、详情弹窗和导出/打印函数是否仍使用旧字段。
|
||||
|
||||
只改 `<th>` 只能改变表头,不代表字段已经接通。
|
||||
|
||||
### 改页面流程
|
||||
|
||||
- 页面跳转:修改页面内 `switchPage` 调用,并检查目标页面 ID 在 manifest 中存在。
|
||||
- 弹窗流程:同时修改按钮、弹窗 HTML、打开函数、保存/提交函数和成功/失败提示。
|
||||
- 状态流转:搜索状态文案在模块、数据数组、渲染函数和筛选条件中的全部引用,确认状态前后兼容。
|
||||
- 导航调整:只改 `shell.html` 的导航项;不要通过复制页面解决导航问题。
|
||||
|
||||
## 修改后验证
|
||||
|
||||
```powershell
|
||||
node scripts/build-prototype.cjs
|
||||
node tests/verify-prototype-modules.cjs
|
||||
```
|
||||
|
||||
- 必须确认 `index.html` 已生成、目标 `page-*` 只出现一次、`manifest.json` 与模块页面清单一致。
|
||||
- 涉及交互时,在浏览器打开 `index.html` 手工走一遍入口、主操作、返回、弹窗确认和错误/空态。
|
||||
- 不要执行 `node scripts/split-prototype.cjs` 作为日常构建;它会从完整备份覆盖拆分源码,可能抹掉模块中的产品修改。
|
||||
|
||||
## 原型模块快速索引
|
||||
|
||||
| 业务模块 | 首读文件 | 页面 ID / 内容 |
|
||||
|---|---|---|
|
||||
| 首页数据看板 | `prototype-src/modules/00-dashboard.html` | `dashboard` |
|
||||
| 客户管理 | `prototype-src/modules/01-customers.html` | `tenant-list`、`tenant-detail`、`warehouse-tier-fee` |
|
||||
| 国内仓 | `prototype-src/modules/02-domestic-warehouse.html` | 入库订单与详情、测量/收货审核、WMS 基础/入库/盘点/出库/库存/加工/移库/上架、库位、托盘、国内整柜 |
|
||||
| 海外仓 | `prototype-src/modules/03-overseas-warehouse.html` | 尾程订单,海外仓入库/出库/换标,产品/托盘/箱号/库存,采购库存及详情 |
|
||||
| 海外派送 | `prototype-src/modules/04-overseas-delivery.html` | `outbound-dispatch`、BOL/自提历史页、排车列表/编辑/详情 |
|
||||
| 供应商中心 | `prototype-src/modules/05-suppliers.html` | 供应商列表/编辑、快递公司、往来单位、海运渠道 |
|
||||
| 货柜管理 | `prototype-src/modules/06-containers.html` | 订舱、拖车、货柜、装柜清单、预装清单、装柜看板 |
|
||||
| 海外业务 | `prototype-src/modules/07-overseas-business.html` | 采购订单、本土卡车、本土散板及新增/编辑/详情 |
|
||||
| 财务管理 | `prototype-src/modules/08-finance.html` | 客户账户、应收应付、对账单、结算单、费用分析、利润表及历史财务报表页 |
|
||||
| 销售管理 | `prototype-src/modules/09-sales.html` | 拜访记录新增/详情、销售提成 |
|
||||
| 通用资料 | `prototype-src/modules/10-general.html` | 产品、费用项目、仓库、下载、船期价格、车辆及历史库位/托盘/路线页 |
|
||||
| 系统与消息 | `prototype-src/modules/11-system-messages.html` | 用户、角色、菜单权限、品牌/客户历史页、消息管理/模板/我的消息、海外用户 |
|
||||
| 历史订单与库存 | `prototype-src/modules/12-legacy-orders.html` | 旧运单、OMS、库存及库龄页面;当前侧栏无直接入口,使用前核对需求 |
|
||||
| 运价、报关与清关 | `prototype-src/modules/13-freight-customs.html` | 旧运价/报价/空运/铁路/对账/报表、报关基础资料、清关页面;当前侧栏无直接入口,使用前核对需求 |
|
||||
|
||||
精确页面 ID 清单以 `prototype-src/manifest.json` 为准,避免在本文件重复 169 个 ID 后产生双份维护。
|
||||
|
||||
## 共享文件快速索引
|
||||
|
||||
| 文件 | 内容 | 何时读取 |
|
||||
|---|---|---|
|
||||
| `prototype-src/shell.html` | 文档头、全局 CSS、顶部导航、侧栏和主内容开头 | 调整全局视觉、布局或导航时 |
|
||||
| `prototype-src/overlays.html` | 页面外的共用弹窗、抽屉和浮层 | 页面操作打开弹窗/抽屉时 |
|
||||
| `prototype-src/app.js` | 全部示例数据、渲染函数和交互逻辑 | 核对按钮行为、状态切换、数据映射时 |
|
||||
| `prototype-src/tail.html` | 主脚本后的附加脚本及 HTML 结尾 | 只有对应函数不在 `app.js` 时 |
|
||||
| `prototype-src/manifest.json` | 模块归属与完整原型中的页面顺序 | 新增、删除、改名或移动页面时 |
|
||||
@@ -0,0 +1,261 @@
|
||||
# 海外仓换标单新增、编辑与费用明细 Implementation Plan
|
||||
|
||||
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
||||
|
||||
**Goal:** 为 0805 后台原型的海外仓换标单增加可用的新增/编辑弹框,并在详情页展示只读 CNY 费用明细。
|
||||
|
||||
**Architecture:** 在现有单页 HTML 原型内复用一个换标单表单弹框,通过 `fbroEditingOrderNo` 区分新增和编辑模式。保存逻辑继续操作 `fbaRelabelOrderData`,编辑时显式保留主键、关联键、创建时间和费用;详情渲染通过独立费用格式化函数将有效金额显示为 CNY,空值显示 `-`。
|
||||
|
||||
**Tech Stack:** HTML、CSS、原生 JavaScript、Node.js 静态/行为契约测试、Playwright CLI。
|
||||
|
||||
---
|
||||
|
||||
## 文件结构
|
||||
|
||||
- 修改 `货代SaaS平台原型.html`:弹框、列表操作入口、新增/编辑/保存逻辑、费用数据和详情渲染。
|
||||
- 创建 `tests/verify-fba-relabel-create-edit-fees.cjs`:专项静态与真实函数行为测试。
|
||||
- 修改 `tests/verify-overseas-warehouse-detail-pages.cjs`:将费用明细纳入既有换标单详情回归契约。
|
||||
- 参考 `docs/superpowers/specs/2026-08-12-fba-relabel-create-edit-fees-design.md`:已确认需求边界。
|
||||
|
||||
### Task 1: 建立专项失败测试
|
||||
|
||||
**Files:**
|
||||
- Create: `tests/verify-fba-relabel-create-edit-fees.cjs`
|
||||
- Test: `货代SaaS平台原型.html`
|
||||
|
||||
- [ ] **Step 1: 编写弹框与入口静态契约**
|
||||
|
||||
测试必须检查:
|
||||
|
||||
```js
|
||||
expectMatch(/onclick="openFbaRelabelCreate\(\)"/, '新增换标单真实入口');
|
||||
expectMatch(/id="modal-fba-relabel-form"/, '新增编辑共用弹框');
|
||||
for (const id of ['fbro-form-order-no','fbro-form-related-order','fbro-form-sku','fbro-form-cn-name','fbro-form-boxes','fbro-form-label-req','fbro-form-file','fbro-form-status','fbro-form-remark']) {
|
||||
expectMatch(new RegExp(`id="${id}"`), `${id} 表单字段`);
|
||||
}
|
||||
expectMatch(/data-fbro-edit-order/, '列表编辑数据入口');
|
||||
```
|
||||
|
||||
- [ ] **Step 2: 编写真实函数行为契约**
|
||||
|
||||
从原型提取并执行 `nextFbaRelabelOrderNo`、`formatFbaRelabelFee` 和 `buildFbaRelabelRecord`,断言:
|
||||
|
||||
```js
|
||||
assert.equal(nextFbaRelabelOrderNo('2026-08-12', [
|
||||
{orderNo:'FBRO20260812001'},
|
||||
{orderNo:'FBRO20260812009'},
|
||||
]), 'FBRO20260812010');
|
||||
assert.equal(formatFbaRelabelFee(null), '-');
|
||||
assert.equal(formatFbaRelabelFee(''), '-');
|
||||
assert.equal(formatFbaRelabelFee('abc'), '-');
|
||||
assert.equal(formatFbaRelabelFee(0), '¥0.00');
|
||||
assert.equal(formatFbaRelabelFee(12.5), '¥12.50');
|
||||
```
|
||||
|
||||
`buildFbaRelabelRecord` 的新增行为必须生成待处理记录;编辑行为必须保留 `orderNo`、`lastMileNo`、`createdAt` 和 `fees`,同时更新允许修改的字段与 `updatedAt`。
|
||||
|
||||
- [ ] **Step 3: 编写费用详情契约**
|
||||
|
||||
检查 `openFbaRelabelOrderDetail` 的配置包含:
|
||||
|
||||
```js
|
||||
{title:'费用明细',rows:[
|
||||
['开箱费',formatFbaRelabelFee(d.fees&&d.fees.openBoxFee)],
|
||||
['挑货费',formatFbaRelabelFee(d.fees&&d.fees.pickingFee)],
|
||||
['换标费',formatFbaRelabelFee(d.fees&&d.fees.relabelFee)],
|
||||
['换箱唛标费',formatFbaRelabelFee(d.fees&&d.fees.cartonMarkFee)]
|
||||
]}
|
||||
```
|
||||
|
||||
- [ ] **Step 4: 运行专项测试确认 RED**
|
||||
|
||||
Run: `node tests/verify-fba-relabel-create-edit-fees.cjs`
|
||||
|
||||
Expected: `FBA_RELABEL_CREATE_EDIT_FEES_CHECK_FAIL`,失败原因是新增/编辑函数、弹框和费用明细尚不存在。
|
||||
|
||||
### Task 2: 实现共用新增与编辑弹框
|
||||
|
||||
**Files:**
|
||||
- Modify: `货代SaaS平台原型.html:8233-8257`
|
||||
- Test: `tests/verify-fba-relabel-create-edit-fees.cjs`
|
||||
|
||||
- [ ] **Step 1: 连接新增按钮并增加共用弹框**
|
||||
|
||||
工具栏按钮改为:
|
||||
|
||||
```html
|
||||
<button class="btn btn-primary" onclick="openFbaRelabelCreate()">+ 新增换标单</button>
|
||||
```
|
||||
|
||||
在列表页后增加 `modal-fba-relabel-form`,包含只读单号、关联订单、SKU、中文品名、箱数、贴标要求、文件、状态和备注字段;保存按钮调用 `saveFbaRelabelOrder()`。贴标要求提供“全覆盖换标”“加贴新标”“移除原标+换标”选项,状态提供“待处理”“处理中”“已完成”选项。
|
||||
|
||||
- [ ] **Step 2: 增加弹框模式状态与清空函数**
|
||||
|
||||
```js
|
||||
let fbroEditingOrderNo='';
|
||||
|
||||
function resetFbaRelabelForm(){
|
||||
['fbro-form-order-no','fbro-form-related-order','fbro-form-sku','fbro-form-cn-name','fbro-form-boxes','fbro-form-remark'].forEach(id=>{
|
||||
const element=document.getElementById(id);
|
||||
if(element)element.value='';
|
||||
});
|
||||
document.getElementById('fbro-form-label-req').value='';
|
||||
document.getElementById('fbro-form-status').value='待处理';
|
||||
document.getElementById('fbro-form-file').value='';
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 3: 实现新增与编辑打开行为**
|
||||
|
||||
`openFbaRelabelCreate()` 清空字段、将标题设为“新增换标单”、显示“系统自动生成”,默认待处理。
|
||||
|
||||
`openFbaRelabelEdit(orderNo)` 查找记录并回填,标题设为“编辑换标单”,显示只读换标单号。记录不存在时显示错误提示并停止。
|
||||
|
||||
- [ ] **Step 4: 将列表编辑改为数据属性入口**
|
||||
|
||||
列表动态文本全部调用 `escapeFbaDetailHtml`;查看和编辑按钮分别使用 `data-fbro-view-order`、`data-fbro-edit-order`。添加一次事件委托,将查看交给 `openFbaRelabelOrderDetail`,编辑交给 `openFbaRelabelEdit`。
|
||||
|
||||
- [ ] **Step 5: 运行专项测试检查中间状态**
|
||||
|
||||
Run: `node tests/verify-fba-relabel-create-edit-fees.cjs`
|
||||
|
||||
Expected: 弹框与入口断言通过,保存和费用相关断言仍失败。
|
||||
|
||||
### Task 3: 实现单号、校验与新增编辑保存
|
||||
|
||||
**Files:**
|
||||
- Modify: `货代SaaS平台原型.html:18097-18131`
|
||||
- Test: `tests/verify-fba-relabel-create-edit-fees.cjs`
|
||||
|
||||
- [ ] **Step 1: 实现单号与时间工具函数**
|
||||
|
||||
```js
|
||||
function nextFbaRelabelOrderNo(dateValue,orders){
|
||||
const date=String(dateValue||'').replace(/\D/g,'').slice(0,8);
|
||||
const prefix='FBRO'+date;
|
||||
const max=(orders||[]).reduce((current,item)=>{
|
||||
const match=String(item&&item.orderNo||'').match(new RegExp('^'+prefix+'(\\d{3})$'));
|
||||
return match?Math.max(current,Number(match[1])):current;
|
||||
},0);
|
||||
return prefix+String(max+1).padStart(3,'0');
|
||||
}
|
||||
```
|
||||
|
||||
增加本地时间格式化函数,生成 `YYYY-MM-DD HH:mm` 和用于单号的 `YYYY-MM-DD`。
|
||||
|
||||
- [ ] **Step 2: 实现纯函数 `buildFbaRelabelRecord`**
|
||||
|
||||
函数签名:
|
||||
|
||||
```js
|
||||
function buildFbaRelabelRecord(form,current,nowValue,orders)
|
||||
```
|
||||
|
||||
新增返回包含 `orderNo`、表单字段、`status:'待处理'`、`createdAt`、`updatedAt`、`fees:{}` 的记录。编辑通过 `Object.assign({},current,allowedFields,{updatedAt:nowValue})` 显式保留不可编辑字段。
|
||||
|
||||
- [ ] **Step 3: 实现表单读取与验证**
|
||||
|
||||
读取九个表单字段,使用 `fileInput.files[0]?.name || fileInput.dataset.currentFile || ''` 保存文件名。关联订单、SKU、中文品名、箱数和贴标要求缺失时提示完整填写;箱数不是正整数时提示“箱数必须为正整数”。
|
||||
|
||||
- [ ] **Step 4: 实现保存函数**
|
||||
|
||||
新增将记录插入数组开头;编辑替换原数组位置。只有构建和校验成功后才修改数组。成功后关闭弹框,调用 `fbroApplyCurrentSearch()` 刷新当前筛选结果,并显示成功提示。
|
||||
|
||||
- [ ] **Step 5: 重构查询以便保存后保持筛选**
|
||||
|
||||
新增 `getFilteredFbaRelabelOrders()` 读取当前 SKU 和状态控件并返回过滤结果;`fbroSearch()`、`fbroApplyCurrentSearch()` 与保存逻辑共用该函数。
|
||||
|
||||
- [ ] **Step 6: 运行专项测试确认保存契约通过**
|
||||
|
||||
Run: `node tests/verify-fba-relabel-create-edit-fees.cjs`
|
||||
|
||||
Expected: 除费用详情外其余断言通过。
|
||||
|
||||
### Task 4: 增加只读 CNY 费用明细
|
||||
|
||||
**Files:**
|
||||
- Modify: `货代SaaS平台原型.html:12200-12290`
|
||||
- Modify: `货代SaaS平台原型.html:18325-18333`
|
||||
- Modify: `tests/verify-overseas-warehouse-detail-pages.cjs`
|
||||
- Test: `tests/verify-fba-relabel-create-edit-fees.cjs`
|
||||
|
||||
- [ ] **Step 1: 为示例记录预留费用对象**
|
||||
|
||||
保持费用计算逻辑不在范围内。示例数据可保留空 `fees:{}`,并为一条记录提供非空数据用于验证展示:
|
||||
|
||||
```js
|
||||
fees:{openBoxFee:12,pickingFee:8.5,relabelFee:36,cartonMarkFee:null}
|
||||
```
|
||||
|
||||
- [ ] **Step 2: 实现费用格式化函数**
|
||||
|
||||
```js
|
||||
function formatFbaRelabelFee(value){
|
||||
if(value===''||value===null||value===undefined)return '-';
|
||||
const amount=Number(value);
|
||||
return Number.isFinite(amount)?'¥'+amount.toFixed(2):'-';
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 3: 在详情配置中增加费用明细**
|
||||
|
||||
在作业要求之后加入四行费用,分别读取 `openBoxFee`、`pickingFee`、`relabelFee`、`cartonMarkFee`。模块标题为“费用明细”,不增加编辑按钮、总费用或计算说明。
|
||||
|
||||
- [ ] **Step 4: 扩充既有详情回归测试**
|
||||
|
||||
在 `verify-overseas-warehouse-detail-pages.cjs` 的换标单字段断言中加入 `费用明细`、`开箱费`、`挑货费`、`换标费`、`换箱唛标费`。
|
||||
|
||||
- [ ] **Step 5: 运行专项与详情测试确认 GREEN**
|
||||
|
||||
Run:
|
||||
|
||||
```powershell
|
||||
node tests/verify-fba-relabel-create-edit-fees.cjs
|
||||
node tests/verify-overseas-warehouse-detail-pages.cjs
|
||||
node tests/verify-last-mile-relabel-display.cjs
|
||||
```
|
||||
|
||||
Expected: 三项均输出 `*_CHECK_PASS`。
|
||||
|
||||
### Task 5: 浏览器与回归验收
|
||||
|
||||
**Files:**
|
||||
- Verify: `货代SaaS平台原型.html`
|
||||
- Verify: `tests/*.cjs`
|
||||
|
||||
- [ ] **Step 1: 检查内联脚本语法**
|
||||
|
||||
提取原型内所有非空 `<script>` 内容,逐个执行 `node --check`。
|
||||
|
||||
Expected: `INLINE_SCRIPT_NODE_CHECK_PASS`。
|
||||
|
||||
- [ ] **Step 2: 运行相关回归**
|
||||
|
||||
```powershell
|
||||
node tests/verify-fba-relabel-create-edit-fees.cjs
|
||||
node tests/verify-overseas-warehouse-detail-pages.cjs
|
||||
node tests/verify-last-mile-relabel-display.cjs
|
||||
node tests/verify-last-mile-orders.cjs
|
||||
node tests/verify-admin-architecture-0805.cjs
|
||||
```
|
||||
|
||||
记录与本功能无关的既有失败,不把无关问题混入本次改动。
|
||||
|
||||
- [ ] **Step 3: 启动静态服务并完成桌面浏览器验收**
|
||||
|
||||
进入海外仓 > 换标单,验证:
|
||||
|
||||
1. 点击“新增换标单”,单号为系统自动生成,状态默认待处理。
|
||||
2. 填入合法数据并保存,新记录出现在当前筛选结果中。
|
||||
3. 点击新记录“编辑”,单号只读且字段正确回填。
|
||||
4. 修改业务字段并保存,列表与详情同步更新。
|
||||
5. 打开空费用记录详情,四项费用均为 `-`。
|
||||
6. 打开有费用样例,金额按 `¥0.00` 格式显示。
|
||||
|
||||
- [ ] **Step 4: 完成移动端验收**
|
||||
|
||||
将视口调整为 390×844,检查弹框字段单列排列、操作按钮不重叠、详情费用明细不横向溢出。
|
||||
|
||||
- [ ] **Step 5: 停止本次浏览器会话和静态服务**
|
||||
|
||||
只清理本次验收创建的会话和端口,不影响已有进程。
|
||||
@@ -0,0 +1,49 @@
|
||||
# 尾程订单查询背景统一实施计划
|
||||
|
||||
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
||||
|
||||
**Goal:** 将尾程订单查询区容器风格与入库单、出库单统一,同时保留现有查询结构和功能。
|
||||
|
||||
**Architecture:** 覆盖 `.lmo-status-tabs`、`.lmo-search` 及其表单控件 CSS,不修改内部网格或 HTML。状态筛选栏与查询区组成连续浅灰筛选带,控件复用入库单、出库单的尺寸、边框和聚焦规范;通过静态测试固定样式参数,并继续运行尾程订单现有业务回归测试。
|
||||
|
||||
**Tech Stack:** HTML、CSS、原生 JavaScript、Node.js 静态测试。
|
||||
|
||||
---
|
||||
|
||||
### Task 1: 固定容器样式契约
|
||||
|
||||
**Files:**
|
||||
- Create: `tests/verify-last-mile-search-background.cjs`
|
||||
|
||||
- [ ] **Step 1: 写入失败测试**
|
||||
|
||||
验证 `.lmo-search` 使用统一容器参数,`.lmo-status-tabs` 使用同一浅灰背景、当前页签使用白色选中面;输入框和下拉框使用统一高度、边框、圆角、字体和聚焦状态,同时保留四列网格和字段标签。
|
||||
|
||||
- [ ] **Step 2: 运行测试确认失败**
|
||||
|
||||
Run: `node tests/verify-last-mile-search-background.cjs`
|
||||
|
||||
Expected: 输出 `LAST_MILE_SEARCH_BACKGROUND_CHECK_FAIL`,指出当前内边距或分隔线与统一查询栏不一致。
|
||||
|
||||
### Task 2: 修改并验证容器样式
|
||||
|
||||
**Files:**
|
||||
- Modify: `货代SaaS平台原型.html`
|
||||
|
||||
- [ ] **Step 1: 修改 `.lmo-search` 容器 CSS**
|
||||
|
||||
将容器参数改为统一查询栏标准,保留 `display:grid`、四列网格和现有间距。
|
||||
|
||||
- [ ] **Step 2: 运行专项与回归测试**
|
||||
|
||||
Run: `node tests/verify-last-mile-search-background.cjs`
|
||||
|
||||
Expected: 输出 `LAST_MILE_SEARCH_BACKGROUND_CHECK_PASS`。
|
||||
|
||||
Run: `node tests/verify-last-mile-orders.cjs`
|
||||
|
||||
Expected: 输出 `LAST_MILE_ORDERS_CHECK_PASS`。
|
||||
|
||||
- [ ] **Step 3: 浏览器验证**
|
||||
|
||||
同视口对照尾程订单与入库单查询区的计算样式,确认背景、内边距、底线、圆角和阴影一致,并确认查询功能正常。
|
||||
@@ -0,0 +1,76 @@
|
||||
# 海外仓入库单查询区布局实施计划
|
||||
|
||||
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
||||
|
||||
**Goal:** 将 0805 版本海外仓入库单查询区改为与出库单一致的紧凑 `.search-row` 工具栏,并保持全部查询逻辑不变。
|
||||
|
||||
**Architecture:** 只调整单文件原型中 `page-fba-inbound-order` 的查询区 HTML/CSS。查询字段直接放入现有 `.search-row` 弹性布局,复用出库单的背景、控件和按钮规范;现有元素 ID、选项和事件函数保持不变。
|
||||
|
||||
**Tech Stack:** HTML、CSS、原生 JavaScript、Node.js 静态结构测试。
|
||||
|
||||
---
|
||||
|
||||
### Task 1: 固定查询区布局契约
|
||||
|
||||
**Files:**
|
||||
- Create: `tests/verify-fba-inbound-search-layout.cjs`
|
||||
|
||||
- [ ] **Step 1: 写入失败测试**
|
||||
|
||||
测试读取 `货代SaaS平台原型.html`,限定在 `page-fba-inbound-order` 查询区,验证 `.search-row`、无标签、无独立查询卡片、紧凑字段宽度、`.btn-sm` 按钮和查询按钮位置。
|
||||
|
||||
- [ ] **Step 2: 运行测试确认失败**
|
||||
|
||||
Run: `node tests/verify-fba-inbound-search-layout.cjs`
|
||||
|
||||
Expected: 输出 `FBA_INBOUND_SEARCH_LAYOUT_CHECK_FAIL`,失败原因指向独立卡片、字段标签或网格布局。
|
||||
|
||||
### Task 2: 实现查询区新布局
|
||||
|
||||
**Files:**
|
||||
- Modify: `货代SaaS平台原型.html`
|
||||
- Modify: `tests/verify-tail-order-and-inbound-filters.cjs`
|
||||
|
||||
- [ ] **Step 1: 扁平化查询区结构**
|
||||
|
||||
删除 `fbio-search-panel`、`fbio-search-grid` 和 `fbio-field` 包装,将全部查询控件直接放入 `<div class="search-row fbio-search-row">`。保留所有原字段 ID、选项、按钮事件和字段顺序。
|
||||
|
||||
- [ ] **Step 2: 改为响应式网格样式**
|
||||
|
||||
复用全局 `.search-row` 的浅灰背景、底部分隔线、控件高度和自动换行。为不同条件设置与出库单一致的 `130px` 至 `170px` 宽度,日期输入框为 `150px`;查询和重置按钮使用 `.btn-sm`。
|
||||
|
||||
|
||||
- [ ] **Step 3: 更新旧结构测试**
|
||||
|
||||
将原测试中的“三行查询布局”断言替换为“查询字段直接位于单一网格中”的断言,其他业务功能断言保持不变。
|
||||
|
||||
- [ ] **Step 4: 运行专项和回归测试**
|
||||
|
||||
Run: `node tests/verify-fba-inbound-search-layout.cjs`
|
||||
|
||||
Expected: 输出 `FBA_INBOUND_SEARCH_LAYOUT_CHECK_PASS`。
|
||||
|
||||
Run: `node tests/verify-tail-order-and-inbound-filters.cjs`
|
||||
|
||||
Expected: 输出 `TAIL_ORDER_INBOUND_FILTER_CHECK_PASS`。
|
||||
|
||||
Run: `node tests/verify-0810-tail-inbound-revisions.cjs`
|
||||
|
||||
Expected: 输出对应 `PASS` 状态且退出码为 0。
|
||||
|
||||
### Task 3: 浏览器视觉验证
|
||||
|
||||
**Files:**
|
||||
- Verify: `货代SaaS平台原型.html`
|
||||
|
||||
- [ ] **Step 1: 宽屏验证**
|
||||
|
||||
在桌面视口打开海外仓入库单,确认查询区三列、标签位于控件上方、日期框清晰可用、查询和重置位于日期右侧。
|
||||
|
||||
- [ ] **Step 2: 中屏和窄屏验证**
|
||||
|
||||
在中屏确认两列且按钮独占一行右对齐;在窄屏确认单列、日期框等宽且页面无异常横向溢出。
|
||||
|
||||
- [ ] **Step 3: 功能冒烟验证**
|
||||
|
||||
确认查询、重置、预约和智能排车入口仍可触发,页面控制台无新增错误。
|
||||
@@ -0,0 +1,70 @@
|
||||
# 尾程订单详情隐藏操作按钮 Implementation Plan
|
||||
|
||||
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
||||
|
||||
**Goal:** 从尾程订单查看详情页移除转仓、入库计划、合托、FBA预约、出库计划五个操作按钮,同时保留列表入口与底层功能。
|
||||
|
||||
**Architecture:** 以页面片段为边界删除详情头部的 `lmo-detail-actions` 容器,不改弹框和函数。使用静态契约测试分别验证详情页中按钮缺失、列表入口仍存在、操作能力代码仍保留。
|
||||
|
||||
**Tech Stack:** 单文件 HTML/CSS/JavaScript 原型、Node.js 静态验证脚本、Playwright CLI
|
||||
|
||||
---
|
||||
|
||||
### Task 1: 锁定详情页隐藏边界
|
||||
|
||||
**Files:**
|
||||
- Create: `tests/verify-last-mile-detail-actions-hidden.cjs`
|
||||
- Modify: `货代SaaS平台原型.html:8590`
|
||||
|
||||
- [ ] **Step 1: 写失败测试**
|
||||
|
||||
新增 Node.js 验证脚本,截取 `page-last-mile-order-detail` 页面片段,断言其中没有 `lmo-detail-actions`、五个操作函数入口及五个按钮文案;同时断言列表页仍有 `openLastMileBatchTransfer()` 和 `openLastMileBatchConsolidate()`,完整 HTML 中仍有五个弹框与五个函数定义。
|
||||
|
||||
- [ ] **Step 2: 运行测试并确认预期失败**
|
||||
|
||||
Run: `node tests\verify-last-mile-detail-actions-hidden.cjs`
|
||||
|
||||
Expected: `LAST_MILE_DETAIL_ACTIONS_HIDDEN_CHECK_FAIL`,原因是详情页仍包含操作区。
|
||||
|
||||
- [ ] **Step 3: 做最小实现**
|
||||
|
||||
从 `page-last-mile-order-detail` 的头部删除:
|
||||
|
||||
```html
|
||||
<div class="lmo-detail-actions">...</div>
|
||||
```
|
||||
|
||||
不删除对应的弹框和函数。
|
||||
|
||||
- [ ] **Step 4: 运行聚焦测试**
|
||||
|
||||
Run: `node tests\verify-last-mile-detail-actions-hidden.cjs`
|
||||
|
||||
Expected: `LAST_MILE_DETAIL_ACTIONS_HIDDEN_CHECK_PASS`
|
||||
|
||||
### Task 2: 回归与界面验收
|
||||
|
||||
**Files:**
|
||||
- Verify: `货代SaaS平台原型.html`
|
||||
- Verify: `tests/verify-last-mile-orders.cjs`
|
||||
- Verify: `tests/verify-last-mile-batch-transfer.cjs`
|
||||
- Verify: `tests/verify-last-mile-pending-direct-actions.cjs`
|
||||
|
||||
- [ ] **Step 1: 校验全部内联脚本语法**
|
||||
|
||||
解析所有非空 `<script>` 块并通过 `new Function(...)` 编译,预期输出 `INLINE_SCRIPT_SYNTAX_CHECK_PASS`。
|
||||
|
||||
- [ ] **Step 2: 运行尾程订单相关回归测试**
|
||||
|
||||
依次运行本次新增测试、`verify-last-mile-batch-transfer.cjs`、`verify-last-mile-pending-direct-actions.cjs` 和现有尾程订单测试,记录任何既有基线失败。
|
||||
|
||||
- [ ] **Step 3: 用真实浏览器检查详情页**
|
||||
|
||||
打开本地原型,进入海外仓 → 尾程订单 → 查看,确认详情头部仅保留返回、标题、单号和状态,五个操作按钮不可见且信息布局无异常。
|
||||
|
||||
- [ ] **Step 4: 重新运行聚焦测试**
|
||||
|
||||
Run: `node tests\verify-last-mile-detail-actions-hidden.cjs`
|
||||
|
||||
Expected: `LAST_MILE_DETAIL_ACTIONS_HIDDEN_CHECK_PASS`
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
# 海外仓换标单新增、编辑与费用明细设计
|
||||
|
||||
## 目标
|
||||
|
||||
在 0805 本地版本的海外仓“换标单”栏目中补齐新增、编辑能力,并在既有换标单详情页增加只读费用明细。界面和交互沿用当前后台原型风格,不扩展审批、费用计算或后端接口。
|
||||
|
||||
## 范围
|
||||
|
||||
- 列表工具栏的“新增换标单”按钮打开新增弹框。
|
||||
- 列表每行的“编辑”打开同一个弹框,并回填当前记录。
|
||||
- 新增和编辑共用字段、校验及保存逻辑。
|
||||
- 换标单详情页新增“费用明细”模块。
|
||||
- 费用币种统一为 CNY。
|
||||
- 本次不实现费用计算逻辑,也不允许在新增或编辑弹框中维护费用。
|
||||
|
||||
## 新增与编辑弹框
|
||||
|
||||
弹框按“订单信息”和“作业要求”组织字段:
|
||||
|
||||
| 字段 | 新增 | 编辑 | 规则 |
|
||||
|---|---|---|---|
|
||||
| 换标单号 | 自动生成 | 只读 | 格式为 `FBRO日期+流水号` |
|
||||
| 关联订单 | 可填写 | 可修改 | 必填 |
|
||||
| 商品 SKU | 可填写 | 可修改 | 必填 |
|
||||
| 中文品名 | 可填写 | 可修改 | 必填 |
|
||||
| 箱数 | 可填写 | 可修改 | 必填,正整数 |
|
||||
| 贴标要求 | 可选择 | 可修改 | 必填 |
|
||||
| 上传文件 | 可选择 | 可修改 | 非必填,仅保留文件名供原型展示 |
|
||||
| 状态 | 默认待处理 | 可修改 | 待处理、处理中、已完成 |
|
||||
| 备注 | 可填写 | 可修改 | 非必填 |
|
||||
|
||||
新增时单号在保存阶段按当日现有最大流水号递增生成,状态默认“待处理”。编辑时以换标单号定位原记录,单号不允许修改。
|
||||
|
||||
## 费用明细
|
||||
|
||||
详情页在“作业要求”之后新增“费用明细”,包含:
|
||||
|
||||
- 开箱费
|
||||
- 挑货费
|
||||
- 换标费
|
||||
- 换箱唛标费
|
||||
|
||||
四项费用使用独立数据字段预留给后续计算逻辑。当前记录没有有效费用时显示 `-`;有费用时按 CNY 显示为 `¥金额`,金额保留两位小数。费用为零时视为有效金额并显示 `¥0.00`。费用不参与本次新增或编辑保存。
|
||||
|
||||
## 数据与交互
|
||||
|
||||
- 继续使用现有 `fbaRelabelOrderData` 作为原型数据源。
|
||||
- 每条换标单可包含 `fees` 对象,字段为 `openBoxFee`、`pickingFee`、`relabelFee`、`cartonMarkFee`。
|
||||
- 新增记录补充创建时间、更新时间和详情所需字段。
|
||||
- 编辑保留换标单号、创建时间、尾程订单关联键和既有费用,只更新表单允许修改的业务字段及更新时间。
|
||||
- 保存成功后关闭弹框,并用当前查询条件重新渲染列表。
|
||||
- 找不到编辑目标、必填项缺失或箱数无效时显示提示,不修改数据。
|
||||
- 列表与详情中的动态文本统一转义;操作入口使用数据属性与事件委托,避免业务值进入内联 JavaScript。
|
||||
|
||||
## 错误与边界
|
||||
|
||||
- 单号生成按当天最大有效流水号递增,避免删除记录后重复。
|
||||
- SKU、品名、关联订单等字段允许普通特殊字符,并安全渲染。
|
||||
- 上传文件仅记录浏览器提供的文件名,不读取或持久化文件内容。
|
||||
- 费用字段缺失、空字符串、`null` 或非有限数字均显示 `-`。
|
||||
- 保存失败或目标记录不存在时,弹框保持打开,方便用户修正。
|
||||
|
||||
## 验证
|
||||
|
||||
- 专项测试覆盖弹框节点、字段、真实新增入口、真实编辑入口、单号生成、默认状态、校验、保存行为和费用格式化。
|
||||
- 详情页测试覆盖“费用明细”标题及四项费用字段。
|
||||
- 回归现有海外仓详情、尾程订单换标关联、后台架构和内联脚本语法。
|
||||
- 浏览器验证新增弹框、编辑回填、保存后列表更新、详情费用空值显示及移动端布局。
|
||||
@@ -0,0 +1,32 @@
|
||||
# 尾程订单查询背景统一设计
|
||||
|
||||
## 目标
|
||||
|
||||
将海外仓“尾程订单”查询区完整改为与“入库单、出库单”一致的紧凑查询栏。
|
||||
|
||||
## 范围
|
||||
|
||||
- 保留全部查询字段、字段顺序、查询和重置逻辑。
|
||||
- 取消字段标签和四列网格包装,改用 `.search-row` 横向紧凑排列并自动换行。
|
||||
- 不修改状态页签、批量操作区、列表、详情页或弹窗。
|
||||
|
||||
## 样式
|
||||
|
||||
- 背景:`#f8fafc`。
|
||||
- 内边距:`14px 18px`。
|
||||
- 底部分隔线:`1px solid #e5eaf1`。
|
||||
- 外边距:`0`。
|
||||
- 圆角:`0`。
|
||||
- 阴影:无。
|
||||
- 使用 `border-box`,避免边框改变容器尺寸。
|
||||
- “全部 / 待分配”状态栏作为查询筛选带的一部分使用 `#f8fafc` 背景,当前选中页签使用白色背景和原蓝色底线。
|
||||
- 输入框和下拉框直接复用 `.search-row` 的 `36px` 高、`7px 11px` 内边距、`1px solid #d7dee8` 边框、`7px` 圆角、白色背景和 `13px` 字体。
|
||||
- 聚焦状态统一使用 `#3b82f6` 边框和 `0 0 0 3px rgba(59,130,246,.1)` 外圈。
|
||||
|
||||
## 验收标准
|
||||
|
||||
- 查询区容器与入库单、出库单查询栏使用相同背景、内边距、分隔线、圆角和阴影参数。
|
||||
- 状态栏和查询区背景连续,视觉上能明确识别为同一筛选区域。
|
||||
- 查询条件通过占位文字和下拉默认项说明用途,不再显示顶部标签。
|
||||
- 普通输入框、下拉框和日期输入框与入库单、出库单控件样式一致。
|
||||
- 查询、重置及列表筛选功能不受影响。
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
# 海外仓入库单查询区样式设计
|
||||
|
||||
## 目标
|
||||
|
||||
调整 0805 本地版本“海外仓 - 入库单”的查询模块,使其与海外仓“出库单”查询栏保持一致,避免同一业务栏目出现两套查询区风格。
|
||||
|
||||
## 范围
|
||||
|
||||
- 仅修改 `page-fba-inbound-order` 查询模块的 HTML 结构和 CSS。
|
||||
- 保留现有查询字段、元素 ID、选项、查询函数、重置函数和列表功能。
|
||||
- 不修改国内仓入库页面、入库单列表、预约、智能排车或详情页面。
|
||||
|
||||
## 布局
|
||||
|
||||
- 查询区直接复用全站 `.search-row`,使用与出库单相同的浅灰工具栏背景、底部分隔线和紧凑间距。
|
||||
- 取消独立圆角查询卡片、字段标签和三列网格,字段通过占位文字或下拉默认项说明用途。
|
||||
- 字段顺序保持:入库单号、入仓码、订单状态、海外仓、FBA仓库、预约状态、是否排车、入库时间。
|
||||
- 查询和重置按钮紧跟在入库时间之后;查询条件超出可用宽度时按现有 `.search-row` 规则自然换行。
|
||||
|
||||
## 控件尺寸
|
||||
|
||||
- 普通输入框和选择框采用出库单页面的 `130px` 至 `170px` 紧凑宽度,统一高度 `36px`。
|
||||
- 入库时间采用两个 `150px` 日期输入框,中间显示短横分隔符。
|
||||
- 查询、重置按钮使用 `.btn.btn-sm`,颜色、圆角和高度与出库单页面一致。
|
||||
|
||||
## 响应式规则
|
||||
|
||||
- 宽屏和中屏:查询条件按可用空间横向排列,空间不足时自然换行。
|
||||
- 窄屏:查询条件继续换行,不强制改成独立卡片或纵向标签表单。
|
||||
|
||||
## 验收标准
|
||||
|
||||
- 所有 8 个查询条件均保留并可正常输入或选择。
|
||||
- 查询区与出库单页面使用相同的 `.search-row` 外观,不显示字段标签。
|
||||
- 入库时间两个日期框宽度约为 `150px`,无明显挤压。
|
||||
- 查询和重置按钮位于查询条件之后。
|
||||
- 查询、重置、预约、智能排车和列表功能不受影响。
|
||||
- 页面无横向异常溢出和控制台错误。
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
# 尾程订单详情隐藏操作按钮设计
|
||||
|
||||
## 目标
|
||||
|
||||
在海外仓“尾程订单”的查看详情页面中隐藏转仓、入库计划、合托、FBA预约、出库计划五个操作按钮,减少详情页上的可执行操作。
|
||||
|
||||
## 范围
|
||||
|
||||
- 移除 `page-last-mile-order-detail` 详情页头部的整个 `lmo-detail-actions` 操作区。
|
||||
- 保留返回按钮、详情标题、尾程单号、订单类型标签和状态标签。
|
||||
- 保留尾程订单列表页的批量转仓、批量合托按钮。
|
||||
- 保留五类操作对应的弹框和 JavaScript 函数,避免影响其他入口及后续复用。
|
||||
- 不调整详情字段、列表字段、状态逻辑或数据。
|
||||
|
||||
## 验收
|
||||
|
||||
- 详情页片段不包含转仓、入库计划、合托、FBA预约、出库计划按钮或 `lmo-detail-actions` 容器。
|
||||
- 列表页仍包含批量转仓和批量合托入口。
|
||||
- 五类操作的弹框和函数仍存在。
|
||||
- 内联脚本语法及现有尾程订单相关回归测试通过。
|
||||
|
||||
@@ -8184,31 +8184,30 @@ body.dashboard-fullscreen #page-dashboard table:has(>thead)>tbody>tr>td{backgrou
|
||||
|
||||
<!-- ==================== FBA RETURN - 入库单 ==================== -->
|
||||
<style>
|
||||
#page-fba-inbound-order .fbio-search-panel{margin:0 20px 16px;padding:16px 18px;background:#f7f9fc;border:1px solid #edf0f5;border-radius:12px}
|
||||
#page-fba-inbound-order .fbio-search-grid{display:flex;flex-direction:column;gap:12px}.fbio-search-row{display:grid;grid-template-columns:repeat(3,minmax(220px,1fr));gap:12px 18px;align-items:center}.fbio-search-row.with-actions{grid-template-columns:repeat(3,minmax(210px,1fr)) auto}.fbio-field{display:flex;align-items:center;gap:10px;min-width:0}.fbio-field>label{width:84px;flex:0 0 84px;text-align:right;font-size:12px;font-weight:650;color:#526071}.fbio-field>input,.fbio-field>select{width:100%;min-width:0;height:38px;border:1px solid #dfe4ec;border-radius:7px;background:#fff;padding:0 12px;color:#334155;box-sizing:border-box;outline:none}.fbio-field>input:focus,.fbio-field>select:focus{border-color:#667eea;box-shadow:0 0 0 2px rgba(102,126,234,.1)}.fbio-date-range{display:flex;align-items:center;gap:7px;min-width:0}.fbio-date-range input{width:calc(50% - 10px);height:38px;border:1px solid #dfe4ec;border-radius:7px;padding:0 8px;box-sizing:border-box}.fbio-search-actions{display:flex;align-items:center;justify-content:flex-start;gap:8px;white-space:nowrap}.fbio-search-actions .btn{min-width:64px}.fbio-smart-schedule-btn{background:#6f42c1!important;border-color:#6f42c1!important;color:#fff!important}
|
||||
#page-fba-inbound-order .fbio-search-row{gap:8px}
|
||||
#page-fba-inbound-order .fbio-date-range{display:flex;align-items:center;gap:6px;color:#94a3b8}
|
||||
#page-fba-inbound-order .fbio-date-range input{flex:0 0 150px}
|
||||
.fbio-smart-schedule-btn{background:#6f42c1!important;border-color:#6f42c1!important;color:#fff!important}
|
||||
#page-fba-inbound-order .fbio-list-actions{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:10px 20px;border-top:1px solid #eef2f7;border-bottom:1px solid #e5e7eb;background:#fafbfc}
|
||||
#page-fba-inbound-order .fbio-list-action-buttons{display:flex;align-items:center;justify-content:flex-end;gap:8px}
|
||||
#page-fba-inbound-order .fbio-list-action-buttons .btn{min-width:76px}
|
||||
@media(max-width:1200px){#page-fba-inbound-order .fbio-search-row,#page-fba-inbound-order .fbio-search-row.with-actions{grid-template-columns:repeat(2,minmax(260px,1fr))}.fbio-search-actions{grid-column:1/-1;justify-content:flex-end}}
|
||||
@media(max-width:720px){#page-fba-inbound-order .fbio-search-row,#page-fba-inbound-order .fbio-search-row.with-actions{grid-template-columns:1fr}.fbio-field>label{width:76px;flex-basis:76px}.fbio-search-actions{grid-column:auto}#page-fba-inbound-order .fbio-list-actions{align-items:flex-start;flex-direction:column;padding:10px 14px}#page-fba-inbound-order .fbio-list-action-buttons{width:100%;justify-content:flex-start}}
|
||||
@media(max-width:720px){#page-fba-inbound-order .fbio-list-actions{align-items:flex-start;flex-direction:column;padding:10px 14px}#page-fba-inbound-order .fbio-list-action-buttons{width:100%;justify-content:flex-start}}
|
||||
</style>
|
||||
<div class="page" id="page-fba-inbound-order">
|
||||
<div class="breadcrumb">首页 <span class="sep">></span> 海外仓 <span class="sep">></span> <strong>入库单</strong></div>
|
||||
<div class="table-card">
|
||||
<div class="table-toolbar"><span class="title">入库单</span><div class="toolbar-actions"><button class="btn btn-primary">+ 新建入库单</button><button class="btn btn-default">导出Excel</button></div></div>
|
||||
<div class="fbio-search-panel"><div class="fbio-search-grid"><div class="fbio-search-row">
|
||||
<div class="fbio-field"><label>入库单号:</label><input id="fbio-no" placeholder="请输入入库单号"></div>
|
||||
<div class="fbio-field"><label>入仓码:</label><input id="fbio-warehouse-code" placeholder="请输入入仓码"></div>
|
||||
<div class="fbio-field"><label>订单状态:</label><select id="fbio-status"><option value="">全部状态</option><option>待审核</option><option>已审核</option><option>已入库</option></select></div>
|
||||
</div><div class="fbio-search-row">
|
||||
<div class="fbio-field"><label>海外仓:</label><select id="fbio-overseas-warehouse"><option value="">全部海外仓</option><option>洛杉矶长滩海外仓</option><option>纽约海外仓</option><option>汉堡海外仓</option></select></div>
|
||||
<div class="fbio-field"><label>FBA仓库:</label><select id="fbio-fba-warehouse"><option value="">全部 FBA 仓库</option><option>FBA ONT8</option><option>FBA ABE8</option><option>DE Frankfurt</option><option>FBA LGB8</option><option>FBA JFK8</option></select></div>
|
||||
<div class="fbio-field"><label>预约状态:</label><select id="fbio-appointment-filter-status"><option value="">全部预约状态</option><option>未预约</option><option>预约中</option><option>预约成功</option></select></div>
|
||||
</div><div class="fbio-search-row with-actions">
|
||||
<div class="fbio-field"><label>是否排车:</label><select id="fbio-schedule-status"><option value="">全部排车状态</option><option>未排车</option><option>已排车</option></select></div>
|
||||
<div class="fbio-field"><label>入库时间:</label><div class="fbio-date-range"><input id="fbio-inbound-start" type="date" aria-label="入库开始时间"><span>–</span><input id="fbio-inbound-end" type="date" aria-label="入库结束时间"></div></div>
|
||||
<div class="fbio-search-actions"><button class="btn btn-primary" onclick="fbioSearch()">查询</button><button class="btn btn-default" onclick="fbioReset()">重置</button></div>
|
||||
</div></div></div>
|
||||
<div class="search-row fbio-search-row">
|
||||
<input id="fbio-no" placeholder="入库单号" style="width:170px"/>
|
||||
<input id="fbio-warehouse-code" placeholder="入仓码" style="width:150px"/>
|
||||
<select id="fbio-status" style="width:130px"><option value="">全部状态</option><option>待审核</option><option>已审核</option><option>已入库</option></select>
|
||||
<select id="fbio-overseas-warehouse" style="width:160px"><option value="">全部海外仓</option><option>洛杉矶长滩海外仓</option><option>纽约海外仓</option><option>汉堡海外仓</option></select>
|
||||
<select id="fbio-fba-warehouse" style="width:150px"><option value="">全部 FBA 仓库</option><option>FBA ONT8</option><option>FBA ABE8</option><option>DE Frankfurt</option><option>FBA LGB8</option><option>FBA JFK8</option></select>
|
||||
<select id="fbio-appointment-filter-status" style="width:140px"><option value="">全部预约状态</option><option>未预约</option><option>预约中</option><option>预约成功</option></select>
|
||||
<select id="fbio-schedule-status" style="width:140px"><option value="">全部排车状态</option><option>未排车</option><option>已排车</option></select>
|
||||
<div class="fbio-date-range"><input id="fbio-inbound-start" type="date" aria-label="入库开始时间" style="width:150px"><span>–</span><input id="fbio-inbound-end" type="date" aria-label="入库结束时间" style="width:150px"></div>
|
||||
<button class="btn btn-sm btn-primary" onclick="fbioSearch()">查询</button><button class="btn btn-sm btn-default" onclick="fbioReset()">重置</button>
|
||||
</div>
|
||||
<div class="fbio-list-actions"><span id="fbio-selected-count" style="font-size:12px;color:#64748b">已选 0 条</span><div class="fbio-list-action-buttons"><button id="fbio-batch-appointment" class="btn btn-default" onclick="openFbioBatchAppointment()">预约</button><button id="fbio-smart-schedule" class="btn fbio-smart-schedule-btn" onclick="openDispatchSchedule()">智能排车</button></div></div>
|
||||
<div style="overflow-x:auto">
|
||||
<table style="min-width:1180px;font-size:12px"><thead><tr style="background:#fafafa;color:#666">
|
||||
@@ -8236,7 +8235,7 @@ body.dashboard-fullscreen #page-dashboard table:has(>thead)>tbody>tr>td{backgrou
|
||||
<div class="page" id="page-fba-relabel-order">
|
||||
<div class="breadcrumb">首页 <span class="sep">></span> FBA退货 <span class="sep">></span> <strong>换标单</strong></div>
|
||||
<div class="table-card">
|
||||
<div class="table-toolbar"><span class="title">换标单</span><div class="toolbar-actions"><button class="btn btn-primary">+ 新建换标单</button><button class="btn btn-default">导出Excel</button></div></div>
|
||||
<div class="table-toolbar"><span class="title">换标单</span><div class="toolbar-actions"><button class="btn btn-primary" onclick="openFbaRelabelCreate()">+ 新增换标单</button><button class="btn btn-default">导出Excel</button></div></div>
|
||||
<div class="search-row" style="flex-wrap:wrap;gap:8px">
|
||||
<input id="fbro-sku" placeholder="商品SKU" style="width:150px"/>
|
||||
<select id="fbro-status" style="width:130px"><option value="">全部状态</option><option>待处理</option><option>处理中</option><option>已完成</option></select>
|
||||
@@ -8257,6 +8256,15 @@ body.dashboard-fullscreen #page-dashboard table:has(>thead)>tbody>tr>td{backgrou
|
||||
</div>
|
||||
<div class="pagination"><span id="fbro-total">共 0 条</span><button class="page-btn active">1</button></div>
|
||||
</div></div>
|
||||
<div class="modal-overlay" id="modal-fba-relabel-form"><div class="modal" style="max-width:760px;width:94%"><div class="modal-header"><span id="fbro-form-title">新增换标单</span><span onclick="hideModal('modal-fba-relabel-form')" style="cursor:pointer;font-size:20px" aria-label="关闭">×</span></div><div class="modal-body">
|
||||
<div class="section-title" style="margin-top:0">订单信息</div>
|
||||
<div class="form-row"><div class="form-group"><label>换标单号</label><input id="fbro-form-order-no" readonly value="系统自动生成" style="background:#f8fafc;color:#64748b"></div><div class="form-group"><label>关联订单 *</label><input id="fbro-form-related-order" maxlength="64" placeholder="请输入关联订单号"></div></div>
|
||||
<div class="form-row"><div class="form-group"><label>商品SKU *</label><input id="fbro-form-sku" maxlength="64" placeholder="请输入商品SKU"></div><div class="form-group"><label>中文品名 *</label><input id="fbro-form-cn-name" maxlength="100" placeholder="请输入中文品名"></div></div>
|
||||
<div class="form-row"><div class="form-group"><label>箱数 *</label><input id="fbro-form-boxes" type="number" min="1" step="1" placeholder="请输入箱数"></div><div class="form-group"><label>状态</label><select id="fbro-form-status"><option>待处理</option><option>处理中</option><option>已完成</option></select></div></div>
|
||||
<div class="section-title">作业要求</div>
|
||||
<div class="form-row"><div class="form-group"><label>贴标要求 *</label><select id="fbro-form-label-req"><option value="">请选择贴标要求</option><option>全覆盖换标</option><option>加贴新标</option><option>移除原标+换标</option></select></div><div class="form-group"><label>上传文件</label><input id="fbro-form-file" type="file" accept=".pdf,.jpg,.jpeg,.png,.xls,.xlsx"></div></div>
|
||||
<div class="form-group"><label>备注</label><textarea id="fbro-form-remark" rows="3" maxlength="500" placeholder="请输入备注"></textarea></div>
|
||||
</div><div class="modal-footer"><button class="btn btn-default" onclick="hideModal('modal-fba-relabel-form')">取消</button><button class="btn btn-primary" onclick="saveFbaRelabelOrder()">保存换标单</button></div></div></div>
|
||||
|
||||
<!-- ==================== FBA RETURN - 出库单 ==================== -->
|
||||
<style>
|
||||
@@ -8506,17 +8514,12 @@ FIRST VIEWPORT: 查询条件位于顶部,订单列表紧随其后;详情页
|
||||
FORM: 采用现有后台的列表加标准详情结构,保持高信息密度和稳定扫描顺序。
|
||||
-->
|
||||
<style>
|
||||
#page-last-mile-orders .lmo-search{display:grid;grid-template-columns:repeat(4,minmax(180px,1fr));gap:12px 16px;padding:16px 18px;border-bottom:1px solid #e8edf3;background:#f8fafc}
|
||||
#page-last-mile-orders .lmo-search-field{display:flex;flex-direction:column;gap:6px;min-width:0}
|
||||
#page-last-mile-orders .lmo-search-field label{font-size:12px;font-weight:600;color:#526071}
|
||||
#page-last-mile-orders .lmo-search-field input,#page-last-mile-orders .lmo-search-field select{width:100%;height:36px;padding:0 10px;border:1px solid #dfe4ec;border-radius:6px;background:#fff;color:#334155;box-sizing:border-box;outline:none}
|
||||
#page-last-mile-orders .lmo-search-field input:focus,#page-last-mile-orders .lmo-search-field select:focus{border-color:#667eea;box-shadow:0 0 0 2px rgba(102,126,234,.1)}
|
||||
#page-last-mile-orders .lmo-search-date-range{display:grid;grid-template-columns:minmax(0,1fr) auto minmax(0,1fr);align-items:center;gap:6px}#page-last-mile-orders .lmo-search-date-range input{min-width:0}#page-last-mile-orders .lmo-search-date-range span{color:#94a3b8;font-size:12px}
|
||||
#page-last-mile-orders .lmo-search-actions{display:flex;align-items:flex-end;justify-content:flex-end;gap:8px}
|
||||
#page-last-mile-orders .lmo-search{gap:8px;align-items:center}
|
||||
#page-last-mile-orders .lmo-search-date-range{display:flex;align-items:center;gap:6px;color:#94a3b8}#page-last-mile-orders .lmo-search-date-range input{flex:0 0 150px;width:150px}#page-last-mile-orders .lmo-search-date-range span{font-size:12px}
|
||||
#page-last-mile-orders .lmo-selection-summary{height:56px;display:flex;align-items:center;padding:0 14px;border-top:1px solid #e8edf3;border-bottom:1px solid #e8edf3;background:#fff;color:#64748b;font-size:12px}
|
||||
#page-last-mile-orders .lmo-status-tabs{display:flex;align-items:center;gap:0;min-height:46px;padding:0 18px;border-bottom:1px solid #e8edf3;background:#fff;overflow-x:auto}
|
||||
#page-last-mile-orders .lmo-status-tabs{display:flex;align-items:center;gap:0;min-height:46px;padding:0 18px;border-bottom:1px solid #e5eaf1;background:#f8fafc;overflow-x:auto}
|
||||
#page-last-mile-orders .lmo-status-tab{height:46px;padding:0 20px;border:0;border-bottom:3px solid transparent;background:transparent;color:#64748b;font:600 13px inherit;cursor:pointer;white-space:nowrap;transition:color .18s,border-color .18s,background .18s}
|
||||
#page-last-mile-orders .lmo-status-tab:hover{color:#667eea;background:#f7f8ff}#page-last-mile-orders .lmo-status-tab.active{color:#667eea;border-bottom-color:#667eea;background:#f7f8ff}
|
||||
#page-last-mile-orders .lmo-status-tab:hover{color:#667eea;background:#f1f5f9}#page-last-mile-orders .lmo-status-tab.active{color:#667eea;border-bottom-color:#667eea;background:#fff}
|
||||
#page-last-mile-orders.lmo-hide-operation .lmo-operation-col{display:none!important}
|
||||
#page-last-mile-orders .more-dropdown{position:relative;display:inline-block}
|
||||
#page-last-mile-orders .more-dropdown-btn{color:#3b82f6;font-weight:600;cursor:pointer}
|
||||
@@ -8548,9 +8551,9 @@ FORM: 采用现有后台的列表加标准详情结构,保持高信息密度
|
||||
.lmo-detail-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:14px;margin-top:14px}.lmo-section{background:#fff;border:1px solid #e5eaf1;border-radius:8px;overflow:hidden}.lmo-section.wide{grid-column:1/-1}.lmo-section-title{min-height:44px;padding:12px 16px;border-bottom:1px solid #e8edf3;box-sizing:border-box;font-size:14px;font-weight:700;color:#1f2937}.lmo-info-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));padding:4px 16px 12px}.lmo-info-item{display:grid;grid-template-columns:118px minmax(0,1fr);gap:10px;padding:10px 4px;border-bottom:1px solid #f0f2f5;font-size:13px}.lmo-info-item .label{color:#8491a3}.lmo-info-item .value{color:#273548;font-weight:500;word-break:break-word}.lmo-empty{padding:28px;text-align:center;color:#94a3b8;font-size:13px}
|
||||
.lmo-modal-note{margin-bottom:14px;padding:10px 12px;border:1px solid #dbeafe;border-radius:6px;background:#f7faff;color:#526071;font-size:12px}.lmo-modal-note.warning{border-color:#fde2b8;background:#fffaf0;color:#9a5b13}
|
||||
.lmo-checkbox-option{display:flex;align-items:center;gap:8px;min-height:36px;color:#334155;font-size:13px;cursor:pointer}.lmo-checkbox-option input{width:16px;height:16px;margin:0;accent-color:#667eea}
|
||||
@media(max-width:1350px){#page-last-mile-orders .lmo-search{grid-template-columns:repeat(3,minmax(180px,1fr))}}
|
||||
@media(max-width:900px){#page-last-mile-orders .lmo-search{grid-template-columns:1fr 1fr}#page-last-mile-orders .lmo-search-date-field{grid-column:1/-1}.lmo-detail-grid{grid-template-columns:1fr}.lmo-section.wide{grid-column:auto}.lmo-detail-head{align-items:flex-start;flex-wrap:wrap}.lmo-detail-head .lmo-detail-actions{width:100%;margin-left:0}.lmo-info-grid{grid-template-columns:1fr}.lmo-field-selector-grid{grid-template-columns:repeat(2,minmax(0,1fr))}}
|
||||
@media(max-width:900px){.lmo-detail-grid{grid-template-columns:1fr}.lmo-section.wide{grid-column:auto}.lmo-detail-head{align-items:flex-start;flex-wrap:wrap}.lmo-detail-head .lmo-detail-actions{width:100%;margin-left:0}.lmo-info-grid{grid-template-columns:1fr}.lmo-field-selector-grid{grid-template-columns:repeat(2,minmax(0,1fr))}}
|
||||
@media(max-width:600px){#modal-lmo-inbound-plan .modal{width:calc(100% - 24px);max-width:none}.modal-overlay#modal-lmo-inbound-plan .modal-body{padding:20px}.modal-overlay#modal-lmo-inbound-plan .form-row{grid-template-columns:minmax(0,1fr);gap:12px;margin-bottom:12px}.modal-overlay#modal-lmo-inbound-plan .form-group{min-width:0}.modal-overlay#modal-lmo-inbound-plan .modal-footer{padding:12px 16px;flex-wrap:wrap}}
|
||||
@media(max-width:600px){#modal-fba-relabel-form .modal{width:calc(100% - 24px)!important;max-width:none!important}#modal-fba-relabel-form .modal-body{padding:20px}#modal-fba-relabel-form .form-row{grid-template-columns:minmax(0,1fr);gap:12px;margin-bottom:12px}#modal-fba-relabel-form .form-group{min-width:0}#modal-fba-relabel-form .modal-footer{padding:12px 16px;flex-wrap:wrap}}
|
||||
</style>
|
||||
|
||||
<!-- ==================== OVERSEAS WAREHOUSE - 尾程订单 ==================== -->
|
||||
@@ -8562,18 +8565,18 @@ FORM: 采用现有后台的列表加标准详情结构,保持高信息密度
|
||||
<button type="button" class="lmo-status-tab active" data-lmo-tab="全部" role="tab" aria-selected="true" onclick="switchLastMileStatusTab('全部',this)">全部</button>
|
||||
<button type="button" class="lmo-status-tab" data-lmo-tab="待分配" role="tab" aria-selected="false" onclick="switchLastMileStatusTab('待分配',this)">待分配</button>
|
||||
</div>
|
||||
<div class="lmo-search">
|
||||
<div class="lmo-search-field"><label>尾程单号</label><input id="lmo-no" placeholder="请输入尾程单号"/></div>
|
||||
<div class="lmo-search-field"><label>入仓码</label><input id="lmo-first-leg-no" placeholder="请输入入仓码"/></div>
|
||||
<div class="lmo-search-field"><label>海外仓</label><select id="lmo-warehouse"><option value="">全部海外仓</option><option>洛杉矶长滩海外仓</option><option>纽约海外仓</option><option>汉堡海外仓</option></select></div>
|
||||
<div class="lmo-search-field"><label>FBA仓库</label><select id="lmo-fba-warehouse"><option value="">全部FBA仓库</option><option>FBA ONT8</option><option>FBA CLT2</option><option>FBA MEM1</option><option>FBA IND9</option><option>DE Frankfurt</option></select></div>
|
||||
<div class="lmo-search-field"><label>订单类型</label><select id="lmo-order-type"><option value="">全部订单类型</option><option>一件代发</option><option>头程</option></select></div>
|
||||
<div class="lmo-search-field"><label>货主</label><input id="lmo-owner" placeholder="请输入货主"/></div>
|
||||
<div class="lmo-search-field"><label>集装箱号</label><input id="lmo-container" placeholder="请输入集装箱号"/></div>
|
||||
<div class="lmo-search-field"><label>当前状态</label><select id="lmo-status"><option value="">全部状态</option><option>待入库计划</option><option>待清关</option><option>清关完成</option><option>已合托</option><option>待预约</option><option>预约中</option><option>预约成功</option></select></div>
|
||||
<div class="lmo-search-field"><label>是否合托</label><select id="lmo-consolidated-filter"><option value="">全部</option><option value="yes">是</option><option value="no">否</option></select></div>
|
||||
<div class="lmo-search-field lmo-search-date-field"><label>预计到港时间</label><div class="lmo-search-date-range"><input id="lmo-port-eta-start" type="date" aria-label="预计到港开始时间"/><span>–</span><input id="lmo-port-eta-end" type="date" aria-label="预计到港结束时间"/></div></div>
|
||||
<div class="lmo-search-actions"><button class="btn btn-default" onclick="lastMileReset()">重置</button><button class="btn btn-primary" onclick="lastMileSearch()">查询</button></div>
|
||||
<div class="search-row lmo-search">
|
||||
<input id="lmo-no" placeholder="尾程单号" style="width:170px"/>
|
||||
<input id="lmo-first-leg-no" placeholder="入仓码" style="width:150px"/>
|
||||
<select id="lmo-warehouse" style="width:160px"><option value="">全部海外仓</option><option>洛杉矶长滩海外仓</option><option>纽约海外仓</option><option>汉堡海外仓</option></select>
|
||||
<select id="lmo-fba-warehouse" style="width:150px"><option value="">全部FBA仓库</option><option>FBA ONT8</option><option>FBA CLT2</option><option>FBA MEM1</option><option>FBA IND9</option><option>DE Frankfurt</option></select>
|
||||
<select id="lmo-order-type" style="width:140px"><option value="">全部订单类型</option><option>一件代发</option><option>头程</option></select>
|
||||
<input id="lmo-owner" placeholder="货主" style="width:150px"/>
|
||||
<input id="lmo-container" placeholder="集装箱号" style="width:160px"/>
|
||||
<select id="lmo-status" style="width:140px"><option value="">全部状态</option><option>待入库计划</option><option>待清关</option><option>清关完成</option><option>已合托</option><option>待预约</option><option>预约中</option><option>预约成功</option></select>
|
||||
<select id="lmo-consolidated-filter" style="width:130px"><option value="">是否合托</option><option value="yes">是</option><option value="no">否</option></select>
|
||||
<div class="lmo-search-date-range"><input id="lmo-port-eta-start" type="date" aria-label="预计到港开始时间"/><span>–</span><input id="lmo-port-eta-end" type="date" aria-label="预计到港结束时间"/></div>
|
||||
<button class="btn btn-sm btn-primary" onclick="lastMileSearch()">查询</button><button class="btn btn-sm btn-default" onclick="lastMileReset()">重置</button>
|
||||
</div>
|
||||
<div class="lmo-selection-summary"><span id="lmo-selected-count">已选 0 条</span></div>
|
||||
<div style="overflow-x:auto">
|
||||
@@ -8587,7 +8590,7 @@ FORM: 采用现有后台的列表加标准详情结构,保持高信息密度
|
||||
<!-- ==================== OVERSEAS WAREHOUSE - 尾程订单详情 ==================== -->
|
||||
<div class="page" id="page-last-mile-order-detail">
|
||||
<div class="breadcrumb">首页 <span class="sep">></span> 海外仓 <span class="sep">></span> 尾程订单 <span class="sep">></span> <strong>详情</strong></div>
|
||||
<div class="lmo-detail-head"><button class="btn btn-default" onclick="backToLastMileOrders()">返回</button><div><h2>尾程订单详情</h2><div style="margin-top:4px;font-size:12px;color:#8491a3">尾程单号 <strong id="lmo-detail-no" style="color:#334155">—</strong><span id="lmo-detail-service" class="lmo-service-tag" style="display:none">一件代发</span></div></div><span id="lmo-detail-status" class="tag tag-gray">—</span><div class="lmo-detail-actions"><button class="btn btn-default" onclick="openLastMileTransfer()">转仓</button><button id="lmo-detail-inbound-btn" class="btn btn-default" onclick="openLastMileInboundPlan()">入库计划</button><button class="btn btn-default" onclick="openLastMileConsolidate()">合托</button><button class="btn btn-default" onclick="openLastMileAppointment()">FBA预约</button><button id="lmo-detail-outbound-btn" class="btn btn-primary" onclick="openLastMileOutboundPlan()">出库计划</button></div></div>
|
||||
<div class="lmo-detail-head"><button class="btn btn-default" onclick="backToLastMileOrders()">返回</button><div><h2>尾程订单详情</h2><div style="margin-top:4px;font-size:12px;color:#8491a3">尾程单号 <strong id="lmo-detail-no" style="color:#334155">—</strong><span id="lmo-detail-service" class="lmo-service-tag" style="display:none">一件代发</span></div></div><span id="lmo-detail-status" class="tag tag-gray">—</span></div>
|
||||
<div class="lmo-detail-grid">
|
||||
<section class="lmo-section"><div class="lmo-section-title">订单信息</div><div class="lmo-info-grid" id="lmo-detail-order-info"></div></section>
|
||||
<section class="lmo-section"><div class="lmo-section-title">订单明细</div><div class="lmo-info-grid" id="lmo-detail-order-details"></div></section>
|
||||
@@ -9785,6 +9788,8 @@ FORM: 采用现有后台的列表加标准详情结构,保持高信息密度
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<!-- ==================== MODALS ==================== -->
|
||||
<div class="modal-overlay" id="modal-tenant-add">
|
||||
<div class="modal" style="max-width:680px"><div class="modal-header">新增客户<span onclick="hideModal('modal-tenant-add')" style="cursor:pointer;font-size:20px">×</span></div>
|
||||
@@ -11169,8 +11174,6 @@ FORM: 采用现有后台的列表加标准详情结构,保持高信息密度
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<script>
|
||||
// ==================== DATA ====================
|
||||
const orderData = [
|
||||
@@ -12200,7 +12203,7 @@ fbaInboundOrderData.forEach((d,i)=>Object.assign(d,fbioQueryMeta[i]||{}));
|
||||
|
||||
/* FBA退货 - 换标单数据 */
|
||||
const fbaRelabelOrderData = [
|
||||
{orderNo:'FBRO20260720001',lastMileNo:'LMO20260810001',sku:'SKU-A1001',cnName:'蓝牙耳机套件',boxes:12,labelReq:'全覆盖换标',file:'换标清单_A1001.pdf',status:'待处理'},
|
||||
{orderNo:'FBRO20260720001',lastMileNo:'LMO20260810001',sku:'SKU-A1001',cnName:'蓝牙耳机套件',boxes:12,labelReq:'全覆盖换标',file:'换标清单_A1001.pdf',status:'待处理',fees:{openBoxFee:12,pickingFee:8.5,relabelFee:36,cartonMarkFee:null}},
|
||||
{orderNo:'FBRO20260721002',lastMileNo:'LMO20260810002',sku:'SKU-B2002',cnName:'手机保护壳',boxes:20,labelReq:'加贴新标',file:'',status:'处理中'},
|
||||
{orderNo:'FBRO20260722003',lastMileNo:'LMO20260810003',sku:'SKU-C3003',cnName:'充电器套装',boxes:28,labelReq:'移除原标+换标',file:'换标清单_C3003.pdf',status:'已完成'},
|
||||
{orderNo:'FBRO20260723004',sku:'SKU-D4004',cnName:'LED台灯',boxes:16,labelReq:'全覆盖换标',file:'',status:'待处理'},
|
||||
@@ -17795,8 +17798,6 @@ function renderLastMileOrderDetail(order){
|
||||
document.getElementById('lmo-detail-no').textContent=order.no;
|
||||
const service=document.getElementById('lmo-detail-service');service.style.display=order.serviceType==='一件代发'?'inline-flex':'none';
|
||||
const status=document.getElementById('lmo-detail-status');status.textContent=order.status;status.className='tag '+lastMileStatusClass(order.status);
|
||||
const inboundBtn=document.getElementById('lmo-detail-inbound-btn');inboundBtn.disabled=isLastMileInboundLocked(order);inboundBtn.title=inboundBtn.disabled?'清关已完成,入库计划不可更改':'';
|
||||
const outboundBtn=document.getElementById('lmo-detail-outbound-btn');if(outboundBtn){outboundBtn.disabled=isLastMileOrderDetained(order);outboundBtn.title=outboundBtn.disabled?'头程订单已暂扣,不能创建出库单':'';}
|
||||
const containerAbnormal=getContainerAbnormalState(order.containerNo);
|
||||
const relabel=getLastMileRelabelOrder(order);
|
||||
document.getElementById('lmo-detail-order-info').innerHTML=lmoInfo('订单类型',order.serviceType)+lmoInfo('头程单号',order.firstLegNo)+lmoInfo('货主',order.owner)+lmoInfo('海外仓',order.warehouse)+lmoInfo('转仓目的仓',order.transferWarehouse)+lmoInfo('FBA仓库',order.fbaWarehouse)+lmoInfo('集装箱号',order.containerNo)+lmoInfo('货柜异常',containerAbnormal.isAbnormal?'异常':'正常')+lmoInfo('异常原因',containerAbnormal.isAbnormal?(containerAbnormal.reason||'未填写异常原因'):'—')+lmoInfo('运输方式',order.transportMode)+lmoInfo('预计到仓',order.eta)+lmoInfo('清关状态',order.customsStatus);
|
||||
@@ -18097,32 +18098,102 @@ function fbioReset(){
|
||||
}
|
||||
|
||||
/* ===== FBA退货 - 换标单 ===== */
|
||||
let fbroEditingOrderNo='';
|
||||
function fbroNowParts(date){
|
||||
const value=date instanceof Date?date:new Date(),pad=number=>String(number).padStart(2,'0');
|
||||
const day=value.getFullYear()+'-'+pad(value.getMonth()+1)+'-'+pad(value.getDate());
|
||||
return {day,time:day+' '+pad(value.getHours())+':'+pad(value.getMinutes())};
|
||||
}
|
||||
function nextFbaRelabelOrderNo(dateValue,orders){
|
||||
const date=String(dateValue||'').replace(/\D/g,'').slice(0,8),prefix='FBRO'+date;
|
||||
const max=(orders||[]).reduce((current,item)=>{const match=String(item&&item.orderNo||'').match(new RegExp('^'+prefix+'(\\d{3})$'));return match?Math.max(current,Number(match[1])):current;},0);
|
||||
return prefix+String(max+1).padStart(3,'0');
|
||||
}
|
||||
function formatFbaRelabelFee(value){
|
||||
if(value===''||value===null||value===undefined)return '-';
|
||||
const amount=Number(value);
|
||||
return Number.isFinite(amount)?'¥'+amount.toFixed(2):'-';
|
||||
}
|
||||
function buildFbaRelabelRecord(form,current,nowValue,orders){
|
||||
const allowed={relatedOrderNo:form.relatedOrderNo,sku:form.sku,cnName:form.cnName,boxes:Number(form.boxes),labelReq:form.labelReq,file:form.file||'',status:form.status||'待处理',remark:form.remark||''};
|
||||
if(current)return Object.assign({},current,allowed,{updatedAt:nowValue});
|
||||
const day=String(nowValue||'').slice(0,10);
|
||||
return Object.assign({orderNo:nextFbaRelabelOrderNo(day,orders),createdAt:nowValue,updatedAt:nowValue,fees:{}},allowed,{status:'待处理'});
|
||||
}
|
||||
function resetFbaRelabelForm(){
|
||||
['fbro-form-related-order','fbro-form-sku','fbro-form-cn-name','fbro-form-boxes','fbro-form-remark'].forEach(id=>{const element=document.getElementById(id);if(element)element.value='';});
|
||||
const file=document.getElementById('fbro-form-file');if(file){file.value='';file.dataset.currentFile='';}
|
||||
document.getElementById('fbro-form-label-req').value='';
|
||||
document.getElementById('fbro-form-status').value='待处理';
|
||||
}
|
||||
function openFbaRelabelCreate(){
|
||||
fbroEditingOrderNo='';resetFbaRelabelForm();
|
||||
document.getElementById('fbro-form-title').textContent='新增换标单';
|
||||
document.getElementById('fbro-form-order-no').value='系统自动生成';
|
||||
document.getElementById('fbro-form-status').disabled=true;
|
||||
showModal('modal-fba-relabel-form');
|
||||
}
|
||||
function openFbaRelabelEdit(orderNo){
|
||||
const record=fbaRelabelOrderData.find(item=>item.orderNo===orderNo);
|
||||
if(!record){showToast('未找到换标单记录','error');return false;}
|
||||
fbroEditingOrderNo=record.orderNo;resetFbaRelabelForm();
|
||||
document.getElementById('fbro-form-title').textContent='编辑换标单';
|
||||
document.getElementById('fbro-form-order-no').value=record.orderNo;
|
||||
document.getElementById('fbro-form-related-order').value=record.relatedOrderNo||'';
|
||||
document.getElementById('fbro-form-sku').value=record.sku||'';
|
||||
document.getElementById('fbro-form-cn-name').value=record.cnName||'';
|
||||
document.getElementById('fbro-form-boxes').value=record.boxes||'';
|
||||
document.getElementById('fbro-form-label-req').value=record.labelReq||'';
|
||||
document.getElementById('fbro-form-status').disabled=false;
|
||||
document.getElementById('fbro-form-status').value=record.status||'待处理';
|
||||
document.getElementById('fbro-form-remark').value=record.remark==='—'?'':record.remark||'';
|
||||
document.getElementById('fbro-form-file').dataset.currentFile=record.file||'';
|
||||
showModal('modal-fba-relabel-form');return true;
|
||||
}
|
||||
function readFbaRelabelForm(){
|
||||
const fileInput=document.getElementById('fbro-form-file');
|
||||
return {relatedOrderNo:document.getElementById('fbro-form-related-order').value.trim(),sku:document.getElementById('fbro-form-sku').value.trim(),cnName:document.getElementById('fbro-form-cn-name').value.trim(),boxes:Number(document.getElementById('fbro-form-boxes').value),labelReq:document.getElementById('fbro-form-label-req').value,status:document.getElementById('fbro-form-status').value,remark:document.getElementById('fbro-form-remark').value.trim(),file:fileInput.files&&fileInput.files[0]?fileInput.files[0].name:(fileInput.dataset.currentFile||'')};
|
||||
}
|
||||
function saveFbaRelabelOrder(){
|
||||
const form=readFbaRelabelForm();
|
||||
if(!form.relatedOrderNo||!form.sku||!form.cnName||!form.labelReq){showToast('请完整填写关联订单、商品SKU、中文品名、箱数和贴标要求','warning');return false;}
|
||||
if(!Number.isInteger(form.boxes)||form.boxes<=0){showToast('箱数必须为正整数','warning');return false;}
|
||||
const current=fbroEditingOrderNo?fbaRelabelOrderData.find(item=>item.orderNo===fbroEditingOrderNo):null;
|
||||
if(fbroEditingOrderNo&&!current){showToast('未找到换标单记录','error');return false;}
|
||||
const now=fbroNowParts(new Date()).time,record=buildFbaRelabelRecord(form,current,now,fbaRelabelOrderData);
|
||||
if(current)fbaRelabelOrderData.splice(fbaRelabelOrderData.indexOf(current),1,record);else fbaRelabelOrderData.unshift(record);
|
||||
hideModal('modal-fba-relabel-form');fbroApplyCurrentSearch();showToast(current?'换标单编辑成功':'换标单新增成功','success');return true;
|
||||
}
|
||||
function renderFbaRelabelOrder(list){
|
||||
const data=list||fbaRelabelOrderData;
|
||||
const tb=document.getElementById('tbody-fba-relabel-order');
|
||||
if(!tb)return;
|
||||
tb.innerHTML=data.map(d=>`<tr style="border-bottom:1px solid #f0f0f0">
|
||||
<td style="padding:9px 10px;font-weight:600;color:#1f2937;white-space:nowrap">${d.orderNo}</td>
|
||||
<td style="padding:9px 10px;white-space:nowrap">${d.sku}</td>
|
||||
<td style="padding:9px 10px">${d.cnName}</td>
|
||||
<td style="padding:9px 10px;text-align:right">${d.boxes}</td>
|
||||
<td style="padding:9px 10px;white-space:nowrap;color:#666">${d.labelReq}</td>
|
||||
<td style="padding:9px 10px;text-align:center;white-space:nowrap"><a href="javascript:void(0)" style="color:#1890ff;text-decoration:none">${d.file?d.file:'上传'}</a></td>
|
||||
<td style="padding:9px 10px;text-align:center"><span class="tag ${d.status==='已完成'?'tag-green':d.status==='处理中'?'tag-purple':'tag-orange'}">${d.status}</span></td>
|
||||
<td style="padding:9px 10px;text-align:center;white-space:nowrap"><a href="javascript:void(0)" style="color:#1890ff;text-decoration:none" onclick="openFbaRelabelOrderDetail('${d.orderNo}')">查看</a> <a href="javascript:void(0)" style="color:#1890ff;text-decoration:none" onclick="showToast('编辑换标单 ${d.orderNo}','info')">编辑</a></td>
|
||||
<td style="padding:9px 10px;font-weight:600;color:#1f2937;white-space:nowrap">${lmoEsc(d.orderNo)}</td>
|
||||
<td style="padding:9px 10px;white-space:nowrap">${lmoEsc(d.sku)}</td>
|
||||
<td style="padding:9px 10px">${lmoEsc(d.cnName)}</td>
|
||||
<td style="padding:9px 10px;text-align:right">${lmoEsc(d.boxes)}</td>
|
||||
<td style="padding:9px 10px;white-space:nowrap;color:#666">${lmoEsc(d.labelReq)}</td>
|
||||
<td style="padding:9px 10px;text-align:center;white-space:nowrap">${d.file?lmoEsc(d.file):'—'}</td>
|
||||
<td style="padding:9px 10px;text-align:center"><span class="tag ${d.status==='已完成'?'tag-green':d.status==='处理中'?'tag-purple':'tag-orange'}">${lmoEsc(d.status)}</span></td>
|
||||
<td style="padding:9px 10px;text-align:center;white-space:nowrap"><a href="javascript:void(0)" style="color:#1890ff;text-decoration:none" data-fbro-view-order="${lmoEsc(d.orderNo)}">查看</a> <a href="javascript:void(0)" style="color:#1890ff;text-decoration:none" data-fbro-edit-order="${lmoEsc(d.orderNo)}">编辑</a></td>
|
||||
</tr>`).join('');
|
||||
const pg=document.getElementById('fbro-total');
|
||||
if(pg)pg.textContent='共 '+data.length+' 条';
|
||||
}
|
||||
function fbroSearch(){
|
||||
function getFilteredFbaRelabelOrders(){
|
||||
const sku=(document.getElementById('fbro-sku')||{}).value||'';
|
||||
const st=(document.getElementById('fbro-status')||{}).value||'';
|
||||
const kw=s=>(''+(s||'')).toLowerCase();
|
||||
const filtered=fbaRelabelOrderData.filter(d=>{
|
||||
return fbaRelabelOrderData.filter(d=>{
|
||||
if(sku && !kw(d.sku).includes(kw(sku))) return false;
|
||||
if(st && d.status!==st) return false;
|
||||
return true;
|
||||
});
|
||||
}
|
||||
function fbroApplyCurrentSearch(){renderFbaRelabelOrder(getFilteredFbaRelabelOrders());}
|
||||
function fbroSearch(){
|
||||
const filtered=getFilteredFbaRelabelOrders();
|
||||
renderFbaRelabelOrder(filtered);
|
||||
showToast('查询完成,共 '+filtered.length+' 条','success');
|
||||
}
|
||||
@@ -18131,6 +18202,11 @@ function fbroReset(){
|
||||
renderFbaRelabelOrder();
|
||||
showToast('已重置','info');
|
||||
}
|
||||
document.addEventListener('click',event=>{
|
||||
const view=event.target.closest('[data-fbro-view-order]'),edit=event.target.closest('[data-fbro-edit-order]');
|
||||
if(view){event.preventDefault();openFbaRelabelOrderDetail(view.dataset.fbroViewOrder);}
|
||||
if(edit){event.preventDefault();openFbaRelabelEdit(edit.dataset.fbroEditOrder);}
|
||||
});
|
||||
|
||||
/* ===== FBA退货 - 出库单 ===== */
|
||||
function openFbaOutboundCreate(){
|
||||
@@ -18330,7 +18406,8 @@ function openFbaRelabelOrderDetail(no){
|
||||
showFbaReadOnlyDetail('fba-relabel-order-detail','fbd-relabel-no','fbd-relabel-status',d.orderNo,d.status,'fbd-relabel-content',[
|
||||
{title:'单据信息',rows:[['换标单号',d.orderNo],['关联订单',d.relatedOrderNo],['状态',d.status],['创建时间',d.createdAt],['更新时间',d.updatedAt]]},
|
||||
{title:'商品信息',rows:[['商品SKU',d.sku],['中文品名',d.cnName],['箱数',d.boxes]]},
|
||||
{title:'作业要求',rows:[['贴标要求',d.labelReq],['上传文件',d.file],['备注',d.remark]]}
|
||||
{title:'作业要求',rows:[['贴标要求',d.labelReq],['上传文件',d.file],['备注',d.remark]]},
|
||||
{title:'费用明细',rows:[['开箱费',formatFbaRelabelFee(d.fees&&d.fees.openBoxFee)],['挑货费',formatFbaRelabelFee(d.fees&&d.fees.pickingFee)],['换标费',formatFbaRelabelFee(d.fees&&d.fees.relabelFee)],['换箱唛标费',formatFbaRelabelFee(d.fees&&d.fees.cartonMarkFee)]]}
|
||||
]);
|
||||
}
|
||||
function openFbaPalletDetail(code){
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 43 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 41 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 49 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 91 KiB |
Vendored
+11431
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,429 @@
|
||||
{
|
||||
"source": "index.html",
|
||||
"pageOrder": [
|
||||
"dashboard",
|
||||
"tenant-list",
|
||||
"warehouse-tier-fee",
|
||||
"inbound-list",
|
||||
"inbound-detail",
|
||||
"inbound-dedup",
|
||||
"inbound-measure",
|
||||
"inbound-receive",
|
||||
"outbound-dispatch",
|
||||
"outbound-bol",
|
||||
"outbound-selfpick",
|
||||
"gen-product",
|
||||
"gen-fee",
|
||||
"outbound-vehicle",
|
||||
"outbound-vehicle-edit",
|
||||
"gen-fba",
|
||||
"gen-download",
|
||||
"gen-pallet",
|
||||
"gen-location",
|
||||
"gen-route",
|
||||
"gen-express",
|
||||
"gen-counterparty",
|
||||
"gen-voyage",
|
||||
"gen-sales",
|
||||
"gen-sales-add",
|
||||
"gen-sales-detail",
|
||||
"sales-commission",
|
||||
"order-list",
|
||||
"order-create",
|
||||
"order-tracking",
|
||||
"order-batch",
|
||||
"order-exception",
|
||||
"order-label",
|
||||
"order-booking",
|
||||
"freight-rate",
|
||||
"freight-quote",
|
||||
"freight-air",
|
||||
"freight-rail",
|
||||
"freight-reconcile",
|
||||
"freight-report",
|
||||
"customs-hs",
|
||||
"customs-estimate",
|
||||
"customs-port",
|
||||
"customs-taxbill",
|
||||
"customs-declare",
|
||||
"customs-rate",
|
||||
"customs-currency",
|
||||
"wh-basic",
|
||||
"wh-inbound",
|
||||
"wh-check",
|
||||
"wh-outbound",
|
||||
"wh-stock",
|
||||
"wh-process",
|
||||
"wh-transfer",
|
||||
"wh-shelve",
|
||||
"clearance-list",
|
||||
"clearance-doc",
|
||||
"oms-order",
|
||||
"oms-review",
|
||||
"oms-allocate",
|
||||
"oms-track",
|
||||
"inv-product",
|
||||
"inv-box",
|
||||
"inv-return",
|
||||
"inv-composite",
|
||||
"inv-age-product",
|
||||
"inv-age-box",
|
||||
"inv-age-return",
|
||||
"finance-ar",
|
||||
"finance-ap",
|
||||
"finance-bill",
|
||||
"finance-bill-edit",
|
||||
"finance-bill-items",
|
||||
"finance-bill-detail",
|
||||
"finance-bill-generate",
|
||||
"finance-bill-recon-detail",
|
||||
"finance-customer-recon-detail",
|
||||
"finance-settle",
|
||||
"finance-settle-detail",
|
||||
"rpt-overview",
|
||||
"rpt-income",
|
||||
"rpt-ar-aging",
|
||||
"rpt-cost",
|
||||
"rpt-freight",
|
||||
"rpt-business",
|
||||
"finance-cashflow",
|
||||
"finance-integration",
|
||||
"customer-account",
|
||||
"customer-account-detail",
|
||||
"finance-cost",
|
||||
"customer-arap",
|
||||
"customer-arap-detail",
|
||||
"customer-recon-stmt",
|
||||
"settlement-ar",
|
||||
"settlement-ap",
|
||||
"settlement-detail",
|
||||
"sys-users",
|
||||
"sys-roles",
|
||||
"sys-menu-permissions",
|
||||
"sys-brand",
|
||||
"sys-tenant",
|
||||
"msg-manage",
|
||||
"msg-template",
|
||||
"msg-my",
|
||||
"booking-list",
|
||||
"truck-list",
|
||||
"truck-add",
|
||||
"truck-edit",
|
||||
"supplier-list",
|
||||
"ocean-channel",
|
||||
"supplier-edit",
|
||||
"booking-detail",
|
||||
"ct-list",
|
||||
"ct-manifest",
|
||||
"fba-stock-management",
|
||||
"inventory-overview",
|
||||
"warehouse-stock",
|
||||
"overseas-stock",
|
||||
"overseas-inbound",
|
||||
"overseas-outbound",
|
||||
"overseas-relabel",
|
||||
"profit",
|
||||
"vehicle",
|
||||
"fba-return-inbound",
|
||||
"fba-return-relabel",
|
||||
"fba-return-outbound",
|
||||
"fba-inbound-order",
|
||||
"fba-relabel-order",
|
||||
"fba-outbound-order",
|
||||
"fba-pallet",
|
||||
"fba-carton",
|
||||
"fba-inbound-order-detail",
|
||||
"fba-outbound-order-detail",
|
||||
"fba-relabel-order-detail",
|
||||
"fba-pallet-detail",
|
||||
"fba-carton-detail",
|
||||
"outbound-vehicle-detail",
|
||||
"fba-product-detail",
|
||||
"fba-product",
|
||||
"purchase-stock",
|
||||
"last-mile-orders",
|
||||
"last-mile-order-detail",
|
||||
"warehouse-stock-detail",
|
||||
"inventory-transactions",
|
||||
"purchase-stock-detail",
|
||||
"fba-return-stock",
|
||||
"overseas-location",
|
||||
"domestic-stock-management",
|
||||
"domestic-container-business",
|
||||
"domestic-container-detail",
|
||||
"pallet-manage",
|
||||
"ct-preload",
|
||||
"ct-preload-detail",
|
||||
"ct-board",
|
||||
"tenant-detail",
|
||||
"overseas-users",
|
||||
"overseas-purchase",
|
||||
"overseas-truck",
|
||||
"overseas-truck-add",
|
||||
"domestic-purchase-edit",
|
||||
"overseas-purchase-edit",
|
||||
"legacy-purchase-edit",
|
||||
"domestic-purchase-detail",
|
||||
"overseas-purchase-detail",
|
||||
"legacy-purchase-detail",
|
||||
"overseas-looseboard",
|
||||
"overseas-looseboard-add",
|
||||
"overseas-truck-edit",
|
||||
"overseas-looseboard-edit"
|
||||
],
|
||||
"modules": [
|
||||
{
|
||||
"file": "modules/00-dashboard.html",
|
||||
"title": "首页数据看板",
|
||||
"pages": [
|
||||
"dashboard"
|
||||
]
|
||||
},
|
||||
{
|
||||
"file": "modules/01-customers.html",
|
||||
"title": "客户管理",
|
||||
"pages": [
|
||||
"tenant-list",
|
||||
"warehouse-tier-fee",
|
||||
"tenant-detail"
|
||||
]
|
||||
},
|
||||
{
|
||||
"file": "modules/02-domestic-warehouse.html",
|
||||
"title": "国内仓",
|
||||
"pages": [
|
||||
"inbound-list",
|
||||
"inbound-detail",
|
||||
"inbound-dedup",
|
||||
"inbound-measure",
|
||||
"inbound-receive",
|
||||
"wh-basic",
|
||||
"wh-inbound",
|
||||
"wh-check",
|
||||
"wh-outbound",
|
||||
"wh-stock",
|
||||
"wh-process",
|
||||
"wh-transfer",
|
||||
"wh-shelve",
|
||||
"overseas-location",
|
||||
"domestic-stock-management",
|
||||
"domestic-container-business",
|
||||
"domestic-container-detail",
|
||||
"pallet-manage"
|
||||
]
|
||||
},
|
||||
{
|
||||
"file": "modules/03-overseas-warehouse.html",
|
||||
"title": "海外仓",
|
||||
"pages": [
|
||||
"fba-stock-management",
|
||||
"inventory-overview",
|
||||
"warehouse-stock",
|
||||
"overseas-stock",
|
||||
"overseas-inbound",
|
||||
"overseas-outbound",
|
||||
"overseas-relabel",
|
||||
"fba-return-inbound",
|
||||
"fba-return-relabel",
|
||||
"fba-return-outbound",
|
||||
"fba-inbound-order",
|
||||
"fba-relabel-order",
|
||||
"fba-outbound-order",
|
||||
"fba-pallet",
|
||||
"fba-carton",
|
||||
"fba-inbound-order-detail",
|
||||
"fba-outbound-order-detail",
|
||||
"fba-relabel-order-detail",
|
||||
"fba-pallet-detail",
|
||||
"fba-carton-detail",
|
||||
"fba-product-detail",
|
||||
"fba-product",
|
||||
"purchase-stock",
|
||||
"last-mile-orders",
|
||||
"last-mile-order-detail",
|
||||
"warehouse-stock-detail",
|
||||
"inventory-transactions",
|
||||
"purchase-stock-detail",
|
||||
"fba-return-stock"
|
||||
]
|
||||
},
|
||||
{
|
||||
"file": "modules/04-overseas-delivery.html",
|
||||
"title": "海外派送",
|
||||
"pages": [
|
||||
"outbound-dispatch",
|
||||
"outbound-bol",
|
||||
"outbound-selfpick",
|
||||
"outbound-vehicle",
|
||||
"outbound-vehicle-edit",
|
||||
"outbound-vehicle-detail"
|
||||
]
|
||||
},
|
||||
{
|
||||
"file": "modules/05-suppliers.html",
|
||||
"title": "供应商中心",
|
||||
"pages": [
|
||||
"gen-express",
|
||||
"gen-counterparty",
|
||||
"supplier-list",
|
||||
"ocean-channel",
|
||||
"supplier-edit"
|
||||
]
|
||||
},
|
||||
{
|
||||
"file": "modules/06-containers.html",
|
||||
"title": "货柜管理",
|
||||
"pages": [
|
||||
"booking-list",
|
||||
"truck-list",
|
||||
"truck-add",
|
||||
"truck-edit",
|
||||
"booking-detail",
|
||||
"ct-list",
|
||||
"ct-manifest",
|
||||
"ct-preload",
|
||||
"ct-preload-detail",
|
||||
"ct-board"
|
||||
]
|
||||
},
|
||||
{
|
||||
"file": "modules/07-overseas-business.html",
|
||||
"title": "海外业务",
|
||||
"pages": [
|
||||
"overseas-purchase",
|
||||
"overseas-truck",
|
||||
"overseas-truck-add",
|
||||
"domestic-purchase-edit",
|
||||
"overseas-purchase-edit",
|
||||
"legacy-purchase-edit",
|
||||
"domestic-purchase-detail",
|
||||
"overseas-purchase-detail",
|
||||
"legacy-purchase-detail",
|
||||
"overseas-looseboard",
|
||||
"overseas-looseboard-add",
|
||||
"overseas-truck-edit",
|
||||
"overseas-looseboard-edit"
|
||||
]
|
||||
},
|
||||
{
|
||||
"file": "modules/08-finance.html",
|
||||
"title": "财务管理",
|
||||
"pages": [
|
||||
"finance-ar",
|
||||
"finance-ap",
|
||||
"finance-bill",
|
||||
"finance-bill-edit",
|
||||
"finance-bill-items",
|
||||
"finance-bill-detail",
|
||||
"finance-bill-generate",
|
||||
"finance-bill-recon-detail",
|
||||
"finance-customer-recon-detail",
|
||||
"finance-settle",
|
||||
"finance-settle-detail",
|
||||
"rpt-overview",
|
||||
"rpt-income",
|
||||
"rpt-ar-aging",
|
||||
"rpt-cost",
|
||||
"rpt-freight",
|
||||
"rpt-business",
|
||||
"finance-cashflow",
|
||||
"finance-integration",
|
||||
"customer-account",
|
||||
"customer-account-detail",
|
||||
"finance-cost",
|
||||
"customer-arap",
|
||||
"customer-arap-detail",
|
||||
"customer-recon-stmt",
|
||||
"settlement-ar",
|
||||
"settlement-ap",
|
||||
"settlement-detail",
|
||||
"profit"
|
||||
]
|
||||
},
|
||||
{
|
||||
"file": "modules/09-sales.html",
|
||||
"title": "销售管理",
|
||||
"pages": [
|
||||
"gen-sales",
|
||||
"gen-sales-add",
|
||||
"gen-sales-detail",
|
||||
"sales-commission"
|
||||
]
|
||||
},
|
||||
{
|
||||
"file": "modules/10-general.html",
|
||||
"title": "通用资料",
|
||||
"pages": [
|
||||
"gen-product",
|
||||
"gen-fee",
|
||||
"gen-fba",
|
||||
"gen-download",
|
||||
"gen-pallet",
|
||||
"gen-location",
|
||||
"gen-route",
|
||||
"gen-voyage",
|
||||
"vehicle"
|
||||
]
|
||||
},
|
||||
{
|
||||
"file": "modules/11-system-messages.html",
|
||||
"title": "系统与消息",
|
||||
"pages": [
|
||||
"sys-users",
|
||||
"sys-roles",
|
||||
"sys-menu-permissions",
|
||||
"sys-brand",
|
||||
"sys-tenant",
|
||||
"msg-manage",
|
||||
"msg-template",
|
||||
"msg-my",
|
||||
"overseas-users"
|
||||
]
|
||||
},
|
||||
{
|
||||
"file": "modules/12-legacy-orders.html",
|
||||
"title": "历史订单与库存",
|
||||
"pages": [
|
||||
"order-list",
|
||||
"order-create",
|
||||
"order-tracking",
|
||||
"order-batch",
|
||||
"order-exception",
|
||||
"order-label",
|
||||
"order-booking",
|
||||
"oms-order",
|
||||
"oms-review",
|
||||
"oms-allocate",
|
||||
"oms-track",
|
||||
"inv-product",
|
||||
"inv-box",
|
||||
"inv-return",
|
||||
"inv-composite",
|
||||
"inv-age-product",
|
||||
"inv-age-box",
|
||||
"inv-age-return"
|
||||
]
|
||||
},
|
||||
{
|
||||
"file": "modules/13-freight-customs.html",
|
||||
"title": "运价、报关与清关",
|
||||
"pages": [
|
||||
"freight-rate",
|
||||
"freight-quote",
|
||||
"freight-air",
|
||||
"freight-rail",
|
||||
"freight-reconcile",
|
||||
"freight-report",
|
||||
"customs-hs",
|
||||
"customs-estimate",
|
||||
"customs-port",
|
||||
"customs-taxbill",
|
||||
"customs-declare",
|
||||
"customs-rate",
|
||||
"customs-currency",
|
||||
"clearance-list",
|
||||
"clearance-doc"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
<!-- 模块:首页数据看板。页面片段由 scripts/split-prototype.cjs 从完整原型拆出。 -->
|
||||
<div class="page active" id="page-dashboard">
|
||||
<div class="dashboard-local-head" style="display:flex;align-items:center;justify-content:space-between;margin-bottom:14px">
|
||||
<div style="font-size:16px;font-weight:700;color:#1e293b">📊 实时数据看板</div>
|
||||
<div style="display:flex;align-items:center;gap:10px">
|
||||
<span style="font-size:12px;color:#71717a">数据更新时间:<b id="dashboardUpdatedAt" style="font-weight:500">2026-06-02 08:45</b></span>
|
||||
<button class="btn btn-default btn-sm" onclick="toggleDashboardFullscreen()" title="进入全屏大屏模式">⛶ 全屏展示</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="stat-row">
|
||||
<div class="stat-card" onclick="switchPage('order-list')" style="cursor:pointer"><div class="decorator"></div><div class="label">今日新运单 <span style="color:#1677ff">→</span></div><div class="value">128<span>票</span></div><div class="trend">较昨日 <span class="up">↑ 12.3%</span></div></div>
|
||||
<div class="stat-card"><div class="decorator"></div><div class="label">在途柜量</div><div class="value">3,842<span>TEU</span></div><div class="trend">较上周 <span class="up">↑ 8.5%</span></div></div>
|
||||
<div class="stat-card"><div class="decorator"></div><div class="label">本月营收</div><div class="value">¥856<span>万</span></div><div class="trend">较上月 <span class="up">↑ 15.2%</span></div></div>
|
||||
<div class="stat-card"><div class="decorator"></div><div class="label">活跃客户</div><div class="value">368<span>家</span></div><div class="trend">新增 <span class="up">+6</span> 家本周</div></div>
|
||||
<div class="stat-card"><div class="decorator"></div><div class="label">待清关票数</div><div class="value">47<span>票</span></div><div class="trend">其中 <span style="color:#f5222d">3票</span> 即将超期</div></div>
|
||||
</div>
|
||||
<div class="chart-row">
|
||||
<div class="chart-card"><div class="chart-header"><span class="chart-title">近30天运单量趋势</span><div class="chart-filters"><button class="chart-filter-btn active">海运</button><button class="chart-filter-btn">空运</button><button class="chart-filter-btn">陆运</button></div></div><canvas id="chartOrderTrend" height="220"></canvas></div>
|
||||
<div class="chart-card"><div class="chart-header"><span class="chart-title">运单状态分布</span></div><canvas id="chartStatusDist" height="260"></canvas></div>
|
||||
</div>
|
||||
<div class="chart-row equal">
|
||||
<div class="chart-card"><div class="chart-header"><span class="chart-title">TOP10 航线货量 (TEU)</span></div><canvas id="chartRouteVol" height="240"></canvas></div>
|
||||
<div class="chart-card"><div class="chart-header"><span class="chart-title">收入构成</span></div><canvas id="chartRevenue" height="260"></canvas></div>
|
||||
</div>
|
||||
<div class="table-card"><div class="table-toolbar"><span class="title">⏰ 待办事项</span></div>
|
||||
<table><thead><tr><th>类型</th><th>内容</th><th>优先级</th><th>截止时间</th><th>操作</th></tr></thead><tbody>
|
||||
<tr><td>订舱确认</td><td>BY20260528003 - 美森快船待确认S/O</td><td><span class="tag tag-orange">重要</span></td><td>2026-06-01</td><td><button class="btn btn-sm btn-primary">确认</button></td></tr>
|
||||
<tr><td>账单到期</td><td>3笔应收账单即将到期,合计 ¥128,500</td><td><span class="tag tag-orange">重要</span></td><td>2026-06-03</td><td><button class="btn btn-sm btn-default">查看</button></td></tr>
|
||||
<tr><td>报关提醒</td><td>BY20260525001 - 截关时间临近,请尽快申报</td><td><span class="tag tag-red">紧急</span></td><td>2026-06-01</td><td><button class="btn btn-sm btn-primary">处理</button></td></tr>
|
||||
</tbody></table></div>
|
||||
</div>
|
||||
|
||||
<!-- ==================== TENANT LIST ==================== -->
|
||||
@@ -0,0 +1,250 @@
|
||||
<!-- 模块:客户管理。页面片段由 scripts/split-prototype.cjs 从完整原型拆出。 -->
|
||||
<div class="page" id="page-tenant-list">
|
||||
<div class="table-card"><div class="table-toolbar"><span class="title">客户列表</span><div class="toolbar-actions"><button class="btn btn-primary" onclick="showModal('modal-tenant-add')">+ 新增客户</button><button class="btn btn-default">导出Excel</button></div></div>
|
||||
<div class="search-row">
|
||||
<select><option>全部状态</option><option>正常</option><option>待审核</option><option>停用</option></select>
|
||||
<input placeholder="公司名称/联系人" style="width:180px"/>
|
||||
<button class="btn btn-sm btn-primary">查询</button>
|
||||
</div>
|
||||
<div class="tenant-table-scroll"><table><thead><tr><th>客户ID</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="tbody-tenant"></tbody></table></div>
|
||||
<div class="pagination" id="tenant-pagination"><span>共 42 条</span><button class="page-btn active">1</button><button class="page-btn">2</button><button class="page-btn">3</button><button class="page-btn">→</button></div></div></div>
|
||||
|
||||
|
||||
<!-- ==================== WAREHOUSE TIER FEE ==================== -->
|
||||
<div class="page" id="page-warehouse-tier-fee">
|
||||
<div class="table-card"><div class="table-toolbar"><span class="title">海外仓阶梯费用</span></div>
|
||||
<div class="search-row" style="border-bottom:1px solid #e4e4e750">
|
||||
<select id="wtf-search-tenant"><option value="">请选择客户公司</option></select>
|
||||
<button class="btn btn-sm btn-primary" onclick="renderWarehouseTierFee()">查询</button>
|
||||
<button class="btn btn-sm btn-default" onclick="document.getElementById('wtf-search-tenant').value='';renderWarehouseTierFee()">重置</button>
|
||||
<button class="btn btn-sm btn-default" onclick="document.getElementById('wtf-search-tenant').value=''">收起</button>
|
||||
</div>
|
||||
<div style="padding:12px 24px">
|
||||
<button class="btn btn-sm btn-primary" onclick="showWarehouseTierFeeAdd()" style="margin-bottom:8px">+ 新增</button>
|
||||
</div>
|
||||
<table><thead><tr><th style="width:50px">#</th><th>客户公司</th><th>阶梯费用明细</th><th>币种</th><th style="width:140px">操作</th></tr></thead><tbody id="tbody-warehouse-tier-fee"></tbody></table>
|
||||
<div class="pagination" id="wtf-pagination"><span>共 10 条</span></div></div></div>
|
||||
|
||||
<!-- ==================== WAREHOUSE TIER FEE ADD MODAL ==================== -->
|
||||
<div class="modal-overlay" id="modal-wtf-add">
|
||||
<div class="modal" style="max-width:640px"><div class="modal-header">新增海外仓阶梯费用<span onclick="hideModal('modal-wtf-add')" style="cursor:pointer;font-size:20px">×</span></div>
|
||||
<div class="modal-body">
|
||||
<div class="form-row"><div class="form-group"><label>客户公司 *</label><select id="wtf-add-tenant"><option value="">请选择客户公司</option></select></div><div class="form-group"><label>币种 *</label><select id="wtf-add-currency"><option>美元</option><option>人民币</option><option>欧元</option></select></div></div>
|
||||
<div style="margin-top:16px;border:1px solid #e5e7eb;border-radius:12px;padding:16px">
|
||||
<div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:12px">
|
||||
<span style="font-size:14px;font-weight:700;color:#374151">📊 阶梯费用明细</span>
|
||||
</div>
|
||||
<table style="width:100%;margin-bottom:8px"><thead><tr><th style="padding:8px;font-size:13px">起始天</th><th style="padding:8px;font-size:13px">结束天</th><th style="padding:8px;font-size:13px">仓储费标准</th><th style="width:50px;padding:8px"></th></tr></thead><tbody id="wtf-add-tiers"></tbody></table>
|
||||
<button class="btn btn-sm btn-default" onclick="addWtfTierRow('wtf-add-tiers')" style="width:100%">+ 添加一组</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer"><button class="btn btn-default" onclick="hideModal('modal-wtf-add')">取消</button><button class="btn btn-primary" onclick="saveWarehouseTierFee()">确认</button></div></div></div>
|
||||
|
||||
<!-- ==================== WAREHOUSE TIER FEE EDIT MODAL ==================== -->
|
||||
<div class="modal-overlay" id="modal-wtf-edit">
|
||||
<div class="modal" style="max-width:640px"><div class="modal-header">编辑海外仓阶梯费用<span onclick="hideModal('modal-wtf-edit')" style="cursor:pointer;font-size:20px">×</span></div>
|
||||
<div class="modal-body">
|
||||
<div class="form-row"><div class="form-group"><label>客户公司</label><input id="wtf-edit-tenant" disabled style="background:#f5f5f5"/></div><div class="form-group"><label>币种</label><select id="wtf-edit-currency"><option>美元</option><option>人民币</option><option>欧元</option></select></div></div>
|
||||
<div style="margin-top:16px;border:1px solid #e5e7eb;border-radius:12px;padding:16px">
|
||||
<div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:12px">
|
||||
<span style="font-size:14px;font-weight:700;color:#374151">📊 阶梯费用明细</span>
|
||||
</div>
|
||||
<table style="width:100%;margin-bottom:8px"><thead><tr><th style="padding:8px;font-size:13px">起始天</th><th style="padding:8px;font-size:13px">结束天</th><th style="padding:8px;font-size:13px">仓储费标准</th><th style="width:50px;padding:8px"></th></tr></thead><tbody id="wtf-edit-tiers"></tbody></table>
|
||||
<button class="btn btn-sm btn-default" onclick="addWtfTierRow('wtf-edit-tiers')" style="width:100%">+ 添加一组</button>
|
||||
</div>
|
||||
<input type="hidden" id="wtf-edit-id"/>
|
||||
</div>
|
||||
<div class="modal-footer"><button class="btn btn-default" onclick="hideModal('modal-wtf-edit')">取消</button><button class="btn btn-primary" onclick="updateWarehouseTierFee()">保存</button></div></div></div>
|
||||
|
||||
<!-- 仓库管理新增弹窗 -->
|
||||
<div class="modal-overlay" id="modal-fba-add">
|
||||
<div class="modal" style="max-width:560px">
|
||||
<div class="modal-header">新增<span onclick="hideModal('modal-fba-add')" style="cursor:pointer;font-size:20px">×</span></div>
|
||||
<div class="modal-body" id="fba-add-body">
|
||||
<style>
|
||||
#fba-add-body .form-row.single .form-group{flex-direction:row;align-items:center;gap:12px;margin-bottom:0;}
|
||||
#fba-add-body .form-row.single .form-group label{width:180px;text-align:right;flex-shrink:0;margin:0;font-size:14px;color:#52525b;font-weight:600;}
|
||||
#fba-add-body .form-row.single .form-group label .required{color:#ef4444;margin-right:4px;}
|
||||
#fba-add-body .form-row.single .form-group input,
|
||||
#fba-add-body .form-row.single .form-group select{flex:1;padding:10px 14px;border:1px solid rgba(102,126,234,.2);border-radius:12px;font-size:14px;outline:none;background:rgba(255,255,255,.9);transition:all .3s cubic-bezier(.4,0,.2,1);}
|
||||
#fba-add-body .form-row.single .form-group input:focus,
|
||||
#fba-add-body .form-row.single .form-group select:focus{border-color:#667eea;box-shadow:0 0 0 4px rgba(102,126,234,.1);transform:translateY(-1px);}
|
||||
</style>
|
||||
<div class="form-row single"><div class="form-group"><label><span class="required">*</span>国家:</label><select id="fba-add-country"><option value="">请输入国家</option><option>美国</option><option>英国</option><option>德国</option><option>日本</option><option>加拿大</option><option>澳大利亚</option></select></div></div>
|
||||
<div class="form-row single"><div class="form-group"><label><span class="required">*</span>FBA编码:</label><input id="fba-add-code" placeholder="请输入FBA编码"/></div></div>
|
||||
<div class="form-row single"><div class="form-group"><label>City:</label><input id="fba-add-city" placeholder="请输入City"/></div></div>
|
||||
<div class="form-row single"><div class="form-group"><label>State:</label><input id="fba-add-state" placeholder="请输入State"/></div></div>
|
||||
<div class="form-row single"><div class="form-group"><label><span class="required">*</span>详细地址:</label><input id="fba-add-addr" placeholder="请输入详细地址"/></div></div>
|
||||
<div class="form-row single"><div class="form-group"><label><span class="required">*</span>邮编:</label><input id="fba-add-zip" placeholder="请输入邮编"/></div></div>
|
||||
<div class="form-row single"><div class="form-group"><label>包税补运费标准(按毛重每公斤/美元):</label><input id="fba-add-tax-rate" placeholder="请输入包税补运费标准(按毛重每公斤/美元)"/></div></div>
|
||||
<div class="form-row single"><div class="form-group"><label>不包税补运费标准(按立方每立方米/美元):</label><input id="fba-add-no-tax-rate" placeholder="请输入不包税补运费标准(按立方每立方米/美元)"/></div></div>
|
||||
<div class="form-row single"><div class="form-group"><label>内部编号:</label><input id="fba-add-inner-code" placeholder="请输入内部编号"/></div></div>
|
||||
</div>
|
||||
<div class="modal-footer"><button class="btn btn-primary" onclick="saveFbaAdd()">确定</button><button class="btn btn-default" onclick="hideModal('modal-fba-add')">关闭</button></div></div></div>
|
||||
|
||||
<!-- ==================== INBOUND LIST ==================== -->
|
||||
<div class="page" id="page-tenant-detail">
|
||||
<div style="display:flex;align-items:center;gap:10px;margin-bottom:14px">
|
||||
<button class="btn btn-default btn-sm" onclick="switchPage('tenant-list')">← 返回列表</button>
|
||||
<span style="font-size:16px;font-weight:700;color:#222" id="td-title">客户详情</span>
|
||||
<span class="tag tag-green" id="td-status-badge" style="font-size:12px">正常</span>
|
||||
<div style="margin-left:auto;display:flex;gap:8px">
|
||||
<button class="btn btn-default btn-sm" onclick="showToast('编辑功能开发中','success')">✏️ 编辑信息</button>
|
||||
<button class="btn btn-danger btn-sm" onclick="showToast('账号已停用','success')">🚫 停用账号</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 顶部概况卡片 -->
|
||||
<div class="stat-row" id="td-stat-row" style="grid-template-columns:repeat(4,1fr)">
|
||||
<div class="stat-card"><div class="decorator"></div><div class="label">累计运单</div><div class="value" id="td-orders">—<span>票</span></div><div class="trend">本月 <span class="up" id="td-orders-month">—</span></div></div>
|
||||
<div class="stat-card"><div class="decorator"></div><div class="label">累计应收</div><div class="value" id="td-ar">—<span>万</span></div><div class="trend">未结清 <span style="color:#f5222d" id="td-ar-bal">—</span></div></div>
|
||||
<div class="stat-card"><div class="decorator"></div><div class="label">在途柜量</div><div class="value" id="td-teu">—<span>TEU</span></div><div class="trend" id="td-teu-trend">—</div></div>
|
||||
</div>
|
||||
|
||||
<!-- Tabs -->
|
||||
<div class="page-tabs" id="td-tabs">
|
||||
<div class="tab-item active" onclick="switchTdTab('info',this)">📋 基本信息</div>
|
||||
<div class="tab-item" onclick="switchTdTab('business',this)">📊 业务概况</div>
|
||||
<div class="tab-item" onclick="switchTdTab('orders',this)">📦 运单记录</div>
|
||||
<div class="tab-item" onclick="switchTdTab('finance',this)">💰 财务账单</div>
|
||||
<div class="tab-item" onclick="switchTdTab('log',this)">📝 操作日志</div>
|
||||
<div class="tab-item" onclick="switchTdTab('billing',this)">⚖️ 计费规则</div>
|
||||
</div>
|
||||
|
||||
<!-- Tab: 基本信息 -->
|
||||
<div id="td-tab-info">
|
||||
<div style="display:grid;grid-template-columns:1fr 1fr;gap:16px">
|
||||
<div class="table-card" style="padding:20px">
|
||||
<div class="detail-section"><h4>企业基本信息</h4>
|
||||
<div class="info-grid" style="grid-template-columns:1fr 1fr" id="td-basic-info"></div>
|
||||
</div>
|
||||
<div class="detail-section"><h4>联系信息</h4>
|
||||
<div class="info-grid" style="grid-template-columns:1fr 1fr" id="td-contact-info"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="table-card" style="padding:20px">
|
||||
<div class="detail-section"><h4>资质文件</h4>
|
||||
<table style="width:100%;font-size:13px;border-collapse:collapse">
|
||||
<thead><tr><th style="text-align:left;padding:8px 4px;color:#555;border-bottom:1px solid #f0f0f0">文件类型</th><th style="text-align:left;padding:8px 4px;color:#555;border-bottom:1px solid #f0f0f0">状态</th><th style="text-align:left;padding:8px 4px;color:#555;border-bottom:1px solid #f0f0f0">有效期</th><th style="padding:8px 4px;border-bottom:1px solid #f0f0f0"></th></tr></thead>
|
||||
<tbody id="td-docs-table"></tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Tab: 业务概况 -->
|
||||
<div id="td-tab-business" style="display:none">
|
||||
<div style="display:grid;grid-template-columns:2fr 1fr;gap:16px;margin-bottom:16px">
|
||||
<div class="chart-card"><div class="chart-header"><span class="chart-title">近6个月运单量趋势</span></div><canvas id="td-chart-orders" height="220"></canvas></div>
|
||||
<div class="chart-card"><div class="chart-header"><span class="chart-title">运输方式分布</span></div><canvas id="td-chart-mode" height="220"></canvas></div>
|
||||
</div>
|
||||
<div style="display:grid;grid-template-columns:1fr 1fr;gap:16px">
|
||||
<div class="chart-card"><div class="chart-header"><span class="chart-title">主要目的港 TOP5(TEU)</span></div><canvas id="td-chart-port" height="200"></canvas></div>
|
||||
<div class="chart-card" style="padding:20px"><div class="chart-header"><span class="chart-title">近3月收入贡献</span></div>
|
||||
<table style="width:100%;font-size:13px;border-collapse:collapse;margin-top:8px">
|
||||
<thead><tr><th style="text-align:left;padding:6px 8px;background:#fafbfc;color:#555">月份</th><th style="padding:6px 8px;background:#fafbfc;color:#555">应收金额</th><th style="padding:6px 8px;background:#fafbfc;color:#555">实收金额</th><th style="padding:6px 8px;background:#fafbfc;color:#555">回款率</th></tr></thead>
|
||||
<tbody id="td-income-table"></tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Tab: 运单记录 -->
|
||||
<div id="td-tab-orders" style="display:none">
|
||||
<div class="table-card">
|
||||
<div class="table-toolbar">
|
||||
<span class="title">运单记录</span>
|
||||
<div class="toolbar-actions">
|
||||
<select style="padding:5px 8px;border:1px solid #d9d9d9;border-radius:4px;font-size:13px" id="td-order-filter">
|
||||
<option value="">全部状态</option>
|
||||
<option>已确认</option><option>已订舱</option><option>运输中</option><option>已完成</option>
|
||||
</select>
|
||||
<button class="btn btn-default btn-sm">导出</button>
|
||||
</div>
|
||||
</div>
|
||||
<table><thead><tr><th>运单号</th><th>运输方式</th><th>起运港→目的港</th><th>柜型/数量</th><th>ETD</th><th>ETA</th><th>应收金额</th><th>状态</th><th>操作</th></tr></thead>
|
||||
<tbody id="td-orders-table"></tbody></table>
|
||||
<div class="pagination"><span id="td-order-count">—</span></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Tab: 财务账单 -->
|
||||
<div id="td-tab-finance" style="display:none">
|
||||
<div style="display:grid;grid-template-columns:repeat(3,1fr);gap:16px;margin-bottom:16px" id="td-finance-stats"></div>
|
||||
<div class="table-card">
|
||||
<div class="table-toolbar"><span class="title">账单明细</span><div class="toolbar-actions"><button class="btn btn-primary btn-sm" onclick="showToast('已生成对账单','success')">生成对账单</button><button class="btn btn-default btn-sm">导出明细</button></div></div>
|
||||
<table><thead><tr><th>账单编号</th><th>类型</th><th>关联运单</th><th>金额</th><th>已付</th><th>未付</th><th>到期日</th><th>状态</th><th>操作</th></tr></thead>
|
||||
<tbody id="td-finance-table"></tbody></table>
|
||||
<div class="pagination"><span id="td-finance-count">—</span></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Tab: 操作日志 -->
|
||||
<div id="td-tab-log" style="display:none">
|
||||
<div class="table-card">
|
||||
<div class="table-toolbar"><span class="title">操作日志</span></div>
|
||||
<table><thead><tr><th>时间</th><th>操作人</th><th>操作类型</th><th>操作内容</th><th>IP地址</th></tr></thead>
|
||||
<tbody id="td-log-table"></tbody></table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Tab: 计费规则 -->
|
||||
<div id="td-tab-billing" style="display:none">
|
||||
<div class="table-card">
|
||||
<div class="table-toolbar">
|
||||
<span class="title">按箱规计费规则</span>
|
||||
<div class="toolbar-actions">
|
||||
<button class="btn btn-primary btn-sm" onclick="showBillingEdit()">✏️ 编辑规则</button>
|
||||
</div>
|
||||
</div>
|
||||
<div style="padding:12px 20px;background:#fafbfc;border-bottom:1px solid #f0f0f0;font-size:13px;color:#666">
|
||||
<span style="margin-right:24px">计费方式:<strong>按箱规计算</strong></span>
|
||||
<span style="margin-right:24px">计费公式:基础费率 × 权重系数 = 实际费率</span>
|
||||
<span>币种:USD</span>
|
||||
</div>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>箱规类型</th>
|
||||
<th>箱体尺寸</th>
|
||||
<th>基础费率 (USD)</th>
|
||||
<th>权重系数</th>
|
||||
<th>计算后费率 (USD)</th>
|
||||
<th>备注</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="td-billing-table"></tbody>
|
||||
</table>
|
||||
</div>
|
||||
<!-- 箱规尺寸计算 -->
|
||||
<div class="table-card" style="margin-top:16px">
|
||||
<div class="table-toolbar">
|
||||
<span class="title">按箱规尺寸计算</span>
|
||||
<div class="toolbar-actions">
|
||||
<button class="btn btn-primary btn-sm" onclick="showBoxSizeEdit()">✏️ 编辑规则</button>
|
||||
</div>
|
||||
</div>
|
||||
<div style="padding:12px 20px;background:#fafbfc;border-bottom:1px solid #f0f0f0;font-size:13px;color:#666">
|
||||
<span style="margin-right:24px">计算方式:<strong>内径尺寸 + 外边加宽 = 外径尺寸</strong></span>
|
||||
<span style="margin-right:24px">体积公式:外径长 × 外径宽 × 外径高 ÷ 1,000,000 = CBM</span>
|
||||
<span>默认加边:2cm(每侧)</span>
|
||||
</div>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>箱规类型</th>
|
||||
<th>内径尺寸 (长×宽×高 cm)</th>
|
||||
<th>外边加宽 (cm)</th>
|
||||
<th>外径尺寸 (长×宽×高 cm)</th>
|
||||
<th>体积 (CBM)</th>
|
||||
<th>备注</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="td-boxsize-table"></tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ==================== OVERSEAS USERS ==================== -->
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,162 @@
|
||||
<!-- 模块:供应商中心。页面片段由 scripts/split-prototype.cjs 从完整原型拆出。 -->
|
||||
<div class="page" id="page-gen-express">
|
||||
<div class="table-card"><div class="table-toolbar"><span class="title">快递公司</span><div class="toolbar-actions"><button class="btn btn-primary">+ 新增</button><button class="btn btn-default">导入</button><button class="btn btn-default">导出</button></div></div>
|
||||
<div class="search-row"><input placeholder="公司名称/编码" style="width:180px"/><select><option>全部状态</option><option>合作中</option><option>已终止</option></select><button class="btn btn-sm btn-primary">查询</button></div>
|
||||
<table><thead><tr><th>公司名称</th><th>编码</th><th>官网</th><th>客服电话</th><th>状态</th><th>操作</th></tr></thead><tbody id="tbody-gen-express"></tbody></table>
|
||||
<div class="pagination"><span>共 18 条</span><button class="page-btn active">1</button><button class="page-btn">2</button></div></div></div>
|
||||
|
||||
<div class="page" id="page-gen-counterparty">
|
||||
<div class="table-card"><div class="table-toolbar"><span class="title">往来单位</span><div class="toolbar-actions"><button class="btn btn-primary">+ 新增</button><button class="btn btn-default">导入</button><button class="btn btn-default">导出</button></div></div>
|
||||
<div class="search-row"><input placeholder="单位名称" style="width:180px"/><select><option>全部类型</option><option>供应商</option><option>客户</option><option>承运商</option><option>报关行</option></select><select><option>全部状态</option><option>启用</option><option>停用</option></select><button class="btn btn-sm btn-primary">查询</button></div>
|
||||
<table><thead><tr><th>单位名称</th><th>类型</th><th>联系人</th><th>电话</th><th>状态</th><th>操作</th></tr></thead><tbody id="tbody-gen-counterparty"></tbody></table>
|
||||
<div class="pagination"><span>共 64 条</span><button class="page-btn active">1</button><button class="page-btn">2</button><button class="page-btn">3</button><button class="page-btn">...</button><button class="page-btn">7</button></div></div></div>
|
||||
|
||||
<style>
|
||||
#page-gen-voyage .voyage-tabs{display:flex;gap:28px;padding:0 22px;border-bottom:1px solid #e8ebf2;background:#fff}
|
||||
#page-gen-voyage .voyage-tab{position:relative;padding:17px 2px 15px;color:#64748b;font-size:14px;font-weight:600;cursor:pointer}
|
||||
#page-gen-voyage .voyage-tab.active{color:#667eea}.voyage-tab.active:after{content:"";position:absolute;left:0;right:0;bottom:-1px;height:3px;border-radius:3px 3px 0 0;background:linear-gradient(90deg,#667eea,#764ba2)}
|
||||
#page-gen-voyage .voyage-pane{display:none}#page-gen-voyage .voyage-pane.active{display:block}
|
||||
#page-gen-voyage .week-summary{display:flex;align-items:center;gap:10px;padding:10px 16px;margin:0 20px 14px;border-radius:9px;background:#f5f7ff;color:#475569;font-size:13px}
|
||||
#page-gen-voyage .current-week-badge{padding:3px 9px;border-radius:10px;background:#e8edff;color:#667eea;font-size:12px;font-weight:700}
|
||||
#page-gen-voyage .cost-hero{margin:18px 20px 14px;padding:18px 20px;border-radius:14px;background:linear-gradient(135deg,#f5f7ff,#faf8ff);border:1px solid #e7e9fb}
|
||||
#page-gen-voyage .cost-hero-head{display:flex;align-items:flex-start;justify-content:space-between;gap:20px;margin-bottom:16px}
|
||||
#page-gen-voyage .cost-hero-title{font-size:16px;font-weight:750;color:#1e293b}.cost-hero-sub{font-size:12px;color:#7c8799;margin-top:5px}
|
||||
#page-gen-voyage .cost-fields{display:grid;grid-template-columns:repeat(7,minmax(125px,1fr));gap:12px}
|
||||
#page-gen-voyage .cost-field label{display:block;font-size:12px;color:#64748b;margin-bottom:6px}.cost-field input,.cost-field select{width:100%;height:36px;padding:0 10px;border:1px solid #dce1ea;border-radius:7px;background:#fff;color:#334155;box-sizing:border-box;outline:none}
|
||||
#page-gen-voyage .cost-field input:focus,.cost-field select:focus,.cost-input:focus{border-color:#667eea;box-shadow:0 0 0 2px rgba(102,126,234,.1)}
|
||||
#page-gen-voyage .cost-table-wrap{margin:0 20px;overflow:auto;border:1px solid #e8ebf2;border-radius:10px}
|
||||
#page-gen-voyage .cost-table{width:2100px;min-width:2100px;font-size:12px}.cost-table th{padding:10px 8px;background:#f7f8fc;text-align:center}.cost-table td{padding:8px;text-align:center}
|
||||
#page-gen-voyage .cost-input{width:82px;height:30px;padding:0 7px;border:1px solid #dce1ea;border-radius:5px;text-align:right;box-sizing:border-box;outline:none}.cost-input.warehouse{width:72px;text-align:left;font-weight:650}
|
||||
#page-gen-voyage .calc-cell{font-variant-numeric:tabular-nums;font-weight:650;color:#334155}.cost-quote{color:#667eea;font-weight:750}
|
||||
#page-gen-voyage .cost-footnote{padding:12px 22px 18px;color:#8490a3;font-size:12px}
|
||||
@media(max-width:1500px){#page-gen-voyage .cost-fields{grid-template-columns:repeat(4,minmax(150px,1fr))}}
|
||||
</style>
|
||||
<div class="page" id="page-supplier-list">
|
||||
<div class="page-nav">
|
||||
<span class="nav-item" onclick="switchPage('dashboard',this)">首页</span>
|
||||
<span class="nav-sep">></span>
|
||||
<span class="nav-item active">供应商中心</span>
|
||||
</div>
|
||||
|
||||
<!-- 四类统计卡片 -->
|
||||
<div class="stat-row">
|
||||
<div class="stat-card"><div class="decorator"></div><div class="label">订舱供应商</div><div class="value">8<span>家</span></div></div>
|
||||
<div class="stat-card"><div class="decorator"></div><div class="label">报关供应商</div><div class="value">5<span>家</span></div></div>
|
||||
<div class="stat-card"><div class="decorator"></div><div class="label">拖车供应商</div><div class="value">6<span>家</span></div></div>
|
||||
<div class="stat-card"><div class="decorator"></div><div class="label">证书供应商</div><div class="value">3<span>家</span></div></div>
|
||||
</div>
|
||||
|
||||
<div class="table-card">
|
||||
<div class="table-toolbar">
|
||||
<span class="title">供应商列表</span>
|
||||
<div class="toolbar-actions">
|
||||
<button class="btn btn-primary" onclick="openSupplierAdd()">+ 新增供应商</button>
|
||||
<button class="btn btn-default">导出Excel</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 四类分类Tab -->
|
||||
<div style="display:flex;gap:6px;padding:4px 0 14px 0;border-bottom:1px solid #eee;margin-bottom:14px;flex-wrap:wrap">
|
||||
<div class="supplier-tab" data-cat="booking" onclick="switchSupplierCat('booking',this)" style="padding:6px 20px;font-size:13px;border-radius:6px;cursor:pointer;background:#1890ff;color:#fff;font-weight:600">订舱</div>
|
||||
<div class="supplier-tab" data-cat="customs" onclick="switchSupplierCat('customs',this)" style="padding:6px 20px;font-size:13px;border-radius:6px;cursor:pointer;background:#f5f5f5;color:#555">报关</div>
|
||||
<div class="supplier-tab" data-cat="trucking" onclick="switchSupplierCat('trucking',this)" style="padding:6px 20px;font-size:13px;border-radius:6px;cursor:pointer;background:#f5f5f5;color:#555">拖车</div>
|
||||
<div class="supplier-tab" data-cat="cert" onclick="switchSupplierCat('cert',this)" style="padding:6px 20px;font-size:13px;border-radius:6px;cursor:pointer;background:#f5f5f5;color:#555">证书</div>
|
||||
</div>
|
||||
|
||||
<div class="search-row">
|
||||
<select id="supplier-status"><option>全部状态</option><option>合作中</option><option>停用</option></select>
|
||||
<span id="supplier-scope-group" style="display:none"><select id="supplier-scope"><option value="">全部国内/国外</option><option value="国内">国内</option><option value="国外">国外</option></select></span>
|
||||
<select id="supplier-region"><option value="">全部地区</option><option>宁波</option><option>上海</option><option>深圳</option><option>北京</option><option>洛杉矶</option></select>
|
||||
<input id="supplier-kw" placeholder="供应商名称/联系人" style="width:200px"/>
|
||||
<button class="btn btn-sm btn-primary" onclick="supplierSearch()">查询</button>
|
||||
<button class="btn btn-sm btn-default" onclick="supplierReset()">重置</button>
|
||||
</div>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>供应商名称</th>
|
||||
<th>类别</th>
|
||||
<th class="supplier-scope-col" style="display:none">国内/国外</th>
|
||||
<th>地区</th>
|
||||
<th>法人</th>
|
||||
<th>联系人</th>
|
||||
<th>联系电话</th>
|
||||
<th>营业执照号</th>
|
||||
<th>营业执照</th>
|
||||
<th>状态</th>
|
||||
<th>结算周期</th>
|
||||
<th>操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="tbody-supplier"></tbody>
|
||||
</table>
|
||||
<div class="pagination"><span id="supplier-count">共 0 条</span><button class="page-btn active">1</button></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ==================== OCEAN CHANNEL ==================== -->
|
||||
<div class="page" id="page-ocean-channel">
|
||||
<div class="page-nav"><span class="nav-item" onclick="switchPage('dashboard',this)">首页</span><span class="nav-sep">></span><span class="nav-item">供应商中心</span><span class="nav-sep">></span><span class="nav-item active">海运渠道</span></div>
|
||||
<div class="table-card"><div class="table-toolbar"><span class="title">海运渠道</span><div class="toolbar-actions"><button class="btn btn-primary" onclick="openOceanChannelModal()">+ 新增渠道</button><button class="btn btn-default" onclick="showToast('海运渠道已导出','success')">导出Excel</button></div></div>
|
||||
<div class="search-row"><input id="oc-search-name" placeholder="渠道名称/渠道编码" style="width:210px"><select id="oc-search-mode" style="width:130px"><option value="">全部运输方式</option><option>海铁</option><option>海卡</option></select><select id="oc-search-status" style="width:130px"><option value="">全部状态</option><option>启用</option><option>停用</option></select><button class="btn btn-sm btn-primary" onclick="renderOceanChannels()">查询</button><button class="btn btn-sm btn-default" onclick="resetOceanChannelSearch()">重置</button></div>
|
||||
<div class="inbound-table-container"><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="tbody-ocean-channel"></tbody></table></div><div class="pagination"><span id="oc-total">共 0 条</span><button class="page-btn active">1</button></div></div></div>
|
||||
|
||||
<div class="modal-overlay" id="modal-ocean-channel"><div class="modal" style="max-width:760px"><div class="modal-header"><span id="oc-modal-title">新增海运渠道</span><span onclick="hideModal('modal-ocean-channel')" style="cursor:pointer;font-size:20px">×</span></div><div class="modal-body" style="padding:22px 26px"><input type="hidden" id="oc-edit-id"><div class="form-row"><div class="form-group"><label>渠道名称 <span style="color:#ef4444">*</span></label><input id="oc-name" placeholder="例如:芝加哥普船海铁"></div><div class="form-group"><label>渠道编码 <span style="color:#ef4444">*</span></label><input id="oc-code" placeholder="例如:CHI-SEA-RAIL"></div></div><div class="form-row"><div class="form-group"><label>运输方式 <span style="color:#ef4444">*</span></label><select id="oc-mode"><option>海铁</option><option>海卡</option></select></div><div class="form-group"><label>目的区域</label><input id="oc-destination" placeholder="请输入目的城市/区域"></div></div><div class="form-row"><div class="form-group"><label>参考时效</label><input id="oc-transit" placeholder="例如:船开后约35天"></div><div class="form-group"><label>船期</label><input id="oc-sailing" placeholder="例如:周四"></div></div><div class="form-row"><div class="form-group"><label>合作供应商</label><input id="oc-supplier" placeholder="请输入合作供应商"></div><div class="form-group"><label>状态</label><select id="oc-status"><option>启用</option><option>停用</option></select></div></div><div class="form-row"><div class="form-group" style="width:100%"><label>备注</label><textarea id="oc-remark" rows="3" placeholder="请输入渠道说明" style="resize:vertical"></textarea></div></div></div><div class="modal-footer"><button class="btn btn-default" onclick="hideModal('modal-ocean-channel')">取消</button><button class="btn btn-primary" onclick="saveOceanChannel()">保存</button></div></div></div>
|
||||
|
||||
<!-- ==================== SUPPLIER EDIT ==================== -->
|
||||
<div class="page" id="page-supplier-edit">
|
||||
<div class="page-nav">
|
||||
<span class="nav-item" onclick="switchPage('dashboard',this)">首页</span>
|
||||
<span class="nav-sep">></span>
|
||||
<span class="nav-item" onclick="switchPage('supplier-list',this)">供应商中心</span>
|
||||
<span class="nav-sep">></span>
|
||||
<span class="nav-item active" id="supplier-edit-navtitle">新增供应商</span>
|
||||
</div>
|
||||
|
||||
<div class="table-card" style="margin-top:16px">
|
||||
<div class="table-toolbar">
|
||||
<span class="title" id="supplier-edit-title">新增供应商</span>
|
||||
<div class="toolbar-actions">
|
||||
<button class="btn btn-default" onclick="switchPage('supplier-list',this)">返回</button>
|
||||
</div>
|
||||
</div>
|
||||
<div style="padding:22px">
|
||||
<div class="form-row">
|
||||
<div class="form-group"><label>* 供应商名称:</label><input id="sup-add-name" placeholder="请输入供应商名称"/></div>
|
||||
<div class="form-group"><label>* 供应商类别:</label><select id="sup-add-cat" onchange="updateSupplierScopeField(this.value)"><option value="booking">订舱</option><option value="customs">报关</option><option value="trucking">拖车</option><option value="cert">证书</option></select></div>
|
||||
<div class="form-group"><label>地区:</label><select id="sup-add-region"><option>宁波</option><option>上海</option><option>深圳</option><option>北京</option><option>洛杉矶</option></select></div>
|
||||
<div class="form-group" id="supplier-scope-group-edit" style="display:none"><label>国内/国外:</label><select id="sup-add-scope"><option value="国内">国内</option><option value="国外">国外</option></select></div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<div class="form-group"><label>* 法人代表:</label><input id="sup-add-legal" placeholder="请输入法人代表"/></div>
|
||||
<div class="form-group"><label>* 联系人:</label><input id="sup-add-contact" placeholder="请输入联系人"/></div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<div class="form-group"><label>* 联系电话:</label><input id="sup-add-phone" placeholder="请输入联系电话"/></div>
|
||||
<div class="form-group"><label>营业执照号:</label><input id="sup-add-license" placeholder="统一社会信用代码"/></div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<div class="form-group"><label>电子邮箱:</label><input id="sup-add-email" placeholder="请输入邮箱"/></div>
|
||||
<div class="form-group"><label>合作状态:</label><select id="sup-add-status"><option>合作中</option><option>停用</option></select></div>
|
||||
</div>
|
||||
<div class="form-row single"><div class="form-group"><label>结算周期:</label><select id="sup-add-period"><option>月结30天</option><option>月结45天</option><option>月结60天</option><option>月结90天</option><option>票结</option><option>现结</option></select></div></div>
|
||||
<div class="form-row single"><div class="form-group"><label>公司地址:</label><input id="sup-add-addr" placeholder="请输入公司地址"/></div></div>
|
||||
<div class="form-row single"><div class="form-group"><label>营业执照上传:</label>
|
||||
<div style="border:1px dashed #d9d9d9;border-radius:6px;padding:24px;text-align:center;color:#999;font-size:13px;cursor:pointer;background:#fafafa">
|
||||
<div style="font-size:28px;line-height:1">📄</div>
|
||||
<div style="margin-top:6px">点击或拖拽上传营业执照(支持 JPG/PNG/PDF)</div>
|
||||
</div>
|
||||
</div></div>
|
||||
<div class="form-row single"><div class="form-group"><label>备注:</label><textarea id="sup-add-remark" rows="2" placeholder="请输入备注"></textarea></div></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 底部操作栏 -->
|
||||
<div style="display:flex;justify-content:center;gap:14px;padding:18px 0 8px;border-top:1px solid #f0f0f0;margin-top:6px">
|
||||
<button class="btn btn-primary" onclick="saveSupplier()" style="padding:7px 40px">保存</button>
|
||||
<button class="btn btn-default" onclick="switchPage('supplier-list',this)" style="padding:7px 28px">取消</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ==================== BOOKING DETAIL ==================== -->
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,431 @@
|
||||
<!-- 模块:海外业务。页面片段由 scripts/split-prototype.cjs 从完整原型拆出。 -->
|
||||
<div class="page" id="page-overseas-purchase">
|
||||
<div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:16px"><div style="font-size:16px;font-weight:700;color:#1e293b">采购订单</div></div>
|
||||
<div class="purchase-order-tabs"><button id="purchase-domestic-tab" class="purchase-order-tab active" onclick="switchPurchaseOrderTab('domestic')">国内</button><button id="purchase-overseas-tab" class="purchase-order-tab" onclick="switchPurchaseOrderTab('overseas')">海外</button></div>
|
||||
<div id="domestic-purchase-panel" class="purchase-order-panel active table-card" style="border-top-left-radius:0;border-top-right-radius:0">
|
||||
<div class="purchase-query"><div class="purchase-query-field"><label>订单编号</label><input id="domestic-purchase-no" placeholder="请输入订单编号" oninput="renderDomesticPurchaseList()"></div><div class="purchase-query-field"><label>采购品类</label><input id="domestic-purchase-category" placeholder="请输入采购品类" oninput="renderDomesticPurchaseList()"></div><div class="purchase-query-field"><label>商品名称</label><input id="domestic-purchase-name" placeholder="请输入商品名称" oninput="renderDomesticPurchaseList()"></div><div class="purchase-query-actions"><button class="btn btn-primary" onclick="renderDomesticPurchaseList()">查询</button><button class="btn btn-default" onclick="resetDomesticPurchaseQuery()">重置</button></div></div>
|
||||
<table style="font-size:12px"><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="tbody-domestic-purchase-list"></tbody></table><div class="purchase-pagination"><span id="domestic-purchase-count"></span></div>
|
||||
</div>
|
||||
<div id="overseas-purchase-panel" class="purchase-order-panel table-card" style="border-top-left-radius:0;border-top-right-radius:0">
|
||||
<div class="purchase-query"><div class="purchase-query-field"><label>订单编号</label><input id="overseas-purchase-no" placeholder="请输入订单编号" oninput="renderOverseasPurchaseList()"></div><div class="purchase-query-field"><label>采购品类</label><input id="overseas-purchase-category" placeholder="请输入采购品类" oninput="renderOverseasPurchaseList()"></div><div class="purchase-query-field"><label>商品名称</label><input id="overseas-purchase-name" placeholder="请输入商品名称" oninput="renderOverseasPurchaseList()"></div><div class="purchase-query-actions"><button class="btn btn-primary" onclick="renderOverseasPurchaseList()">查询</button><button class="btn btn-default" onclick="resetOverseasPurchaseQuery()">重置</button></div></div>
|
||||
<table style="font-size:12px"><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="tbody-overseas-purchase-list"></tbody></table><div class="purchase-pagination"><span id="overseas-purchase-count"></span></div>
|
||||
</div></div>
|
||||
|
||||
<!-- 历史新增表单仅保留为不可达模板,后台采购订单不提供新增入口 -->
|
||||
<div style="display:none" id="legacy-overseas-purchase-add-template" aria-hidden="true">
|
||||
<div style="font-size:14px;color:#666;margin-bottom:12px"><a href="javascript:void(0)" onclick="switchPage('overseas-purchase')" style="color:#1890ff;text-decoration:none">← 返回列表</a></div>
|
||||
<div class="table-card" style="max-width:720px">
|
||||
<div style="font-size:15px;font-weight:700;color:#1e293b;margin-bottom:20px">历史采购订单表单</div>
|
||||
<div style="background:#f7f7f7;border-radius:8px;padding:28px 32px">
|
||||
<div class="form-row" style="margin-bottom:18px;display:grid;grid-template-columns:1fr 1fr;gap:0 24px">
|
||||
<div class="form-group" style="margin:0"><label style="font-size:13px;font-weight:600;color:#333;margin-bottom:6px;display:block">采购品类 <span style="color:#ef4444">*</span></label><input id="po-category" placeholder="如:家居用品 / 3C 配件" style="width:100%;padding:10px 12px;border-radius:8px;border:1px solid #e0e0e0;background:#fff;font-size:13px;outline:none;box-sizing:border-box"/></div>
|
||||
<div class="form-group" style="margin:0"><label style="font-size:13px;font-weight:600;color:#333;margin-bottom:6px;display:block">商品名称</label><input id="po-name" placeholder="如:棉麻抱枕套" style="width:100%;padding:10px 12px;border-radius:8px;border:1px solid #e0e0e0;background:#fff;font-size:13px;outline:none;box-sizing:border-box"/></div>
|
||||
</div>
|
||||
<div class="form-row" style="margin-bottom:18px;display:grid;grid-template-columns:1fr 1fr;gap:0 24px">
|
||||
<div class="form-group" style="margin:0"><label style="font-size:13px;font-weight:600;color:#333;margin-bottom:6px;display:block">商品规格</label><input id="po-spec" placeholder="如:尺寸 / 颜色 / 材质" style="width:100%;padding:10px 12px;border-radius:8px;border:1px solid #e0e0e0;background:#fff;font-size:13px;outline:none;box-sizing:border-box"/></div>
|
||||
<div class="form-group" style="margin:0"><label style="font-size:13px;font-weight:600;color:#333;margin-bottom:6px;display:block">商品链接</label><input id="po-link" placeholder="https://" style="width:100%;padding:10px 12px;border-radius:8px;border:1px solid #e0e0e0;background:#fff;font-size:13px;outline:none;box-sizing:border-box"/></div>
|
||||
</div>
|
||||
<div class="form-row" style="margin-bottom:18px;display:grid;grid-template-columns:1fr 1fr;gap:0 24px">
|
||||
<div class="form-group" style="margin:0"><label style="font-size:13px;font-weight:600;color:#333;margin-bottom:6px;display:block">采购数量 <span style="color:#ef4444">*</span></label><input id="po-qty" type="number" value="0" min="0" style="width:100%;padding:10px 12px;border-radius:8px;border:1px solid #e0e0e0;background:#fff;font-size:13px;outline:none;box-sizing:border-box"/></div>
|
||||
<div class="form-group" style="margin:0"><label style="font-size:13px;font-weight:600;color:#333;margin-bottom:6px;display:block">预算单价</label><div style="position:relative"><span style="position:absolute;left:12px;top:50%;transform:translateY(-50%);font-size:13px;color:#999">$</span><input id="po-price" type="number" value="0" step="0.01" min="0" placeholder="0.00" style="width:100%;padding:10px 12px 10px 22px;border-radius:8px;border:1px solid #e0e0e0;background:#fff;font-size:13px;outline:none;box-sizing:border-box"/></div></div>
|
||||
</div>
|
||||
<div class="form-row" style="margin-bottom:18px">
|
||||
<div class="form-group" style="margin:0;width:100%"><label style="font-size:13px;font-weight:600;color:#333;margin-bottom:6px;display:block">收货地址</label><input id="po-address" placeholder="请输入收货地址(选填)" style="width:100%;padding:10px 12px;border-radius:8px;border:1px solid #e0e0e0;background:#fff;font-size:13px;outline:none;box-sizing:border-box"/></div>
|
||||
</div>
|
||||
<div class="form-row" style="margin-bottom:18px;display:grid;grid-template-columns:1fr 1fr;gap:0 24px">
|
||||
<div class="form-group" style="margin:0"><label style="font-size:13px;font-weight:600;color:#333;margin-bottom:6px;display:block">中国快递单号</label><input id="po-cnTracking" placeholder="请输入中国快递单号" style="width:100%;padding:10px 12px;border-radius:8px;border:1px solid #e0e0e0;background:#fff;font-size:13px;outline:none;box-sizing:border-box"/></div>
|
||||
<div class="form-group" style="margin:0"><label style="font-size:13px;font-weight:600;color:#333;margin-bottom:6px;display:block">美国快递单号</label><input id="po-usTracking" placeholder="请输入美国快递单号" style="width:100%;padding:10px 12px;border-radius:8px;border:1px solid #e0e0e0;background:#fff;font-size:13px;outline:none;box-sizing:border-box"/></div>
|
||||
</div>
|
||||
<div class="form-row" style="margin-bottom:18px;display:grid;grid-template-columns:1fr 1fr;gap:0 24px">
|
||||
<div class="form-group" style="margin:0"><label style="font-size:13px;font-weight:600;color:#333;margin-bottom:6px;display:block">预计到达时间</label><input id="po-eta" type="datetime-local" style="width:100%;padding:10px 12px;border-radius:8px;border:1px solid #e0e0e0;background:#fff;font-size:13px;outline:none;box-sizing:border-box"/></div>
|
||||
<div class="form-group" style="margin:0"><label style="font-size:13px;font-weight:600;color:#333;margin-bottom:6px;display:block">操作费(¥)</label><input id="po-opFee" type="number" value="0" step="0.01" min="0" placeholder="0.00" style="width:100%;padding:10px 12px;border-radius:8px;border:1px solid #e0e0e0;background:#fff;font-size:13px;outline:none;box-sizing:border-box"/></div>
|
||||
</div>
|
||||
<div class="form-row" style="margin-bottom:18px;display:grid;grid-template-columns:1fr 1fr;gap:0 24px">
|
||||
<div class="form-group" style="margin:0"><label style="font-size:13px;font-weight:600;color:#333;margin-bottom:6px;display:block">联系人 <span style="color:#ef4444">*</span></label><input id="po-contact" placeholder="请输入联系人姓名" style="width:100%;padding:10px 12px;border-radius:8px;border:1px solid #e0e0e0;background:#fff;font-size:13px;outline:none;box-sizing:border-box"/></div>
|
||||
<div class="form-group" style="margin:0"><label style="font-size:13px;font-weight:600;color:#333;margin-bottom:6px;display:block">联系电话 <span style="color:#ef4444">*</span></label><input id="po-phone" placeholder="请输入联系电话" style="width:100%;padding:10px 12px;border-radius:8px;border:1px solid #e0e0e0;background:#fff;font-size:13px;outline:none;box-sizing:border-box"/></div>
|
||||
</div>
|
||||
<div class="form-row" style="margin-bottom:0">
|
||||
<div class="form-group" style="margin:0;width:100%"><label style="font-size:13px;font-weight:600;color:#333;margin-bottom:6px;display:block">订单备注</label><textarea id="po-remark" rows="4" placeholder="其他需求说明(选填)" style="width:100%;padding:10px 12px;border-radius:8px;border:1px solid #e0e0e0;background:#fff;font-size:13px;outline:none;resize:vertical;box-sizing:border-box"></textarea></div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="display:flex;justify-content:flex-end;gap:12px;margin-top:20px;padding-top:16px;border-top:1px solid #eee">
|
||||
<button class="btn btn-default" style="padding:8px 28px;border-radius:6px" onclick="switchPage('overseas-purchase')">取消</button>
|
||||
<button class="btn btn-primary" style="padding:8px 28px;border-radius:6px" onclick="savePurchaseOrder()">提交订单</button>
|
||||
</div>
|
||||
</div></div>
|
||||
|
||||
<!-- ==================== OVERSEAS TRUCK ==================== -->
|
||||
<div class="page" id="page-overseas-truck">
|
||||
<div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:16px">
|
||||
<div style="font-size:16px;font-weight:700;color:#1e293b">本土卡车</div>
|
||||
<button class="btn btn-primary" onclick="switchPage('overseas-truck-add')">+ 新增订单</button>
|
||||
</div>
|
||||
<div class="table-card">
|
||||
<div style="display:flex;align-items:center;gap:10px;margin-bottom:12px;padding:0 4px">
|
||||
<select id="truck-order-status-filter" onchange="renderTruckOrderList()" style="padding:6px 10px;border-radius:5px;border:1px solid #d9d9d9;outline:none;font-size:13px;background:#fff;color:#333">
|
||||
<option value="">全部状态</option><option value="待接单">待接单</option><option value="已派车">已派车</option><option value="运输中">运输中</option><option value="已完成">已完成</option></select>
|
||||
<input id="truck-order-search" placeholder="起运地/目的地" oninput="renderTruckOrderList()" style="flex:1;max-width:240px;padding:6px 10px;border-radius:5px;border:1px solid #d9d9d9;outline:none;font-size:13px"/>
|
||||
<button class="btn btn-primary" style="padding:6px 18px;border-radius:5px" onclick="renderTruckOrderList()">查询</button>
|
||||
</div>
|
||||
<table style="font-size:12px">
|
||||
<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><th>操作</th>
|
||||
</tr></thead>
|
||||
<tbody id="tbody-truck-order-list"></tbody>
|
||||
</table>
|
||||
<div style="display:flex;align-items:center;justify-content:space-between;padding:12px 4px 0;font-size:12px;color:#666">
|
||||
<span></span>
|
||||
<span style="cursor:pointer;color:#1890ff">1-5 共5条</span>
|
||||
</div>
|
||||
</div></div>
|
||||
|
||||
<!-- ==================== OVERSEAS TRUCK ADD ==================== -->
|
||||
<div class="page" id="page-overseas-truck-add">
|
||||
<div style="font-size:14px;color:#666;margin-bottom:12px"><a href="javascript:void(0)" onclick="switchPage('overseas-truck')" style="color:#1890ff;text-decoration:none">← 返回列表</a></div>
|
||||
<div class="table-card" style="max-width:760px">
|
||||
<div style="font-size:15px;font-weight:700;color:#1e293b;margin-bottom:20px">新增本土卡车订单</div>
|
||||
<div style="background:#f7f7f7;border-radius:8px;padding:28px 32px">
|
||||
<!-- 运输类型 -->
|
||||
<div style="margin-bottom:20px"><label style="font-size:13px;font-weight:600;color:#333;margin-bottom:10px;display:block">运输类型 <span style="color:#ef4444">*</span></label>
|
||||
<div style="display:flex;gap:12px">
|
||||
<label class="truck-type-btn" data-val="港口提柜"><span style="margin-right:4px">⚓</span> 港口提柜</label>
|
||||
<label class="truck-type-btn" data-val="仓到仓"><span style="margin-right:4px">🏭</span> 仓到仓</label>
|
||||
<label class="truck-type-btn" data-val="仓到门"><span style="margin-right:4px">🚛</span> 仓到门</label>
|
||||
<input type="hidden" id="ta-transport-type"/>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 起运地 / 目的地 -->
|
||||
<div style="display:grid;grid-template-columns:1fr 1fr;gap:0 24px;margin-bottom:18px">
|
||||
<div><label style="font-size:13px;font-weight:600;color:#333;margin-bottom:8px;display:block">起运地 <span style="color:#ef4444">*</span></label><input id="ta-origin" placeholder="城市 / 港口 / 州" style="width:100%;padding:11px 14px;border-radius:8px;border:1px solid #e0e0e0;background:#fff;font-size:13px;outline:none;box-sizing:border-box"/></div>
|
||||
<div><label style="font-size:13px;font-weight:600;color:#333;margin-bottom:8px;display:block">目的地 <span style="color:#ef4444">*</span></label><input id="ta-dest" placeholder="城市 / 州" style="width:100%;padding:11px 14px;border-radius:8px;border:1px solid #e0e0e0;background:#fff;font-size:13px;outline:none;box-sizing:border-box"/></div>
|
||||
</div>
|
||||
<!-- 详细地址 -->
|
||||
<div style="display:grid;grid-template-columns:1fr 1fr;gap:0 24px;margin-bottom:18px">
|
||||
<div><label style="font-size:13px;font-weight:600;color:#333;margin-bottom:8px;display:block">详细地址</label><input id="ta-detail-addr" placeholder="街道 / 门牌" style="width:100%;padding:11px 14px;border-radius:8px;border:1px solid #e0e0e0;background:#fff;font-size:13px;outline:none;box-sizing:border-box"/></div>
|
||||
<div><label style="font-size:13px;font-weight:600;color:#333;margin-bottom:8px;display:block">详细地址 / 码头 / 仓号</label><input id="ta-wharf" placeholder="地址 / 码头 / 仓号" style="width:100%;padding:11px 14px;border-radius:8px;border:1px solid #e0e0e0;background:#fff;font-size:13px;outline:none;box-sizing:border-box"/></div>
|
||||
</div>
|
||||
<!-- 联系人 / 联系方式 -->
|
||||
<div style="display:grid;grid-template-columns:1fr 1fr;gap:0 24px;margin-bottom:18px">
|
||||
<div><label style="font-size:13px;font-weight:600;color:#333;margin-bottom:8px;display:block">联系人</label><input id="ta-contact" placeholder="联系人姓名" style="width:100%;padding:11px 14px;border-radius:8px;border:1px solid #e0e0e0;background:#fff;font-size:13px;outline:none;box-sizing:border-box"/></div>
|
||||
<div><label style="font-size:13px;font-weight:600;color:#333;margin-bottom:8px;display:block">联系方式</label><input id="ta-phone" placeholder="联系电话" style="width:100%;padding:11px 14px;border-radius:8px;border:1px solid #e0e0e0;background:#fff;font-size:13px;outline:none;box-sizing:border-box"/></div>
|
||||
</div>
|
||||
<!-- 货物信息 -->
|
||||
<div style="margin-bottom:20px"><div style="font-size:13px;font-weight:600;color:#333;margin-bottom:10px;display:flex;align-items:center;gap:6px"><span>📦</span> 货物信息</div>
|
||||
<div style="display:grid;grid-template-columns:1fr 1fr 1fr 1fr;gap:16px">
|
||||
<div><label style="font-size:12px;color:#666;margin-bottom:6px;display:block">柜型</label><select id="ta-container" style="width:100%;padding:9px 12px;border-radius:8px;border:1px solid #e0e0e0;background:#fff;font-size:13px;outline:none;box-sizing:border-box"><option>20GP</option><option>40GP</option><option>40HQ</option><option>45HQ</option></select></div>
|
||||
<div><label style="font-size:12px;color:#666;margin-bottom:6px;display:block">件数</label><input id="ta-pieces" type="number" value="0" min="0" style="width:100%;padding:9px 12px;border-radius:8px;border:1px solid #e0e0e0;background:#fff;font-size:13px;outline:none;box-sizing:border-box"/></div>
|
||||
<div><label style="font-size:12px;color:#666;margin-bottom:6px;display:block">总重量 (kg)</label><input id="ta-gw" type="number" value="0" min="0" step="0.01" style="width:100%;padding:9px 12px;border-radius:8px;border:1px solid #e0e0e0;background:#fff;font-size:13px;outline:none;box-sizing:border-box"/></div>
|
||||
<div><label style="font-size:12px;color:#666;margin-bottom:6px;display:block">总体积 (m³)</label><input id="ta-vol" type="number" value="0" min="0" step="0.001" style="width:100%;padding:9px 12px;border-radius:8px;border:1px solid #e0e0e0;background:#fff;font-size:13px;outline:none;box-sizing:border-box"/></div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 预算总价 -->
|
||||
<div style="margin-bottom:18px"><label style="font-size:13px;font-weight:600;color:#333;margin-bottom:8px;display:block">预算总价(¥)</label><input id="ta-budget" type="number" min="0" step="0.01" placeholder="0.00" style="width:100%;max-width:300px;padding:11px 14px;border-radius:8px;border:1px solid #e0e0e0;background:#fff;font-size:13px;outline:none;box-sizing:border-box"/></div>
|
||||
<!-- 要求时间 -->
|
||||
<div><label style="font-size:13px;font-weight:600;color:#333;margin-bottom:8px;display:block">要求时间</label><input id="ta-required-date" type="date" style="width:100%;max-width:300px;padding:11px 14px;border-radius:8px;border:1px solid #e0e0e0;background:#fff;font-size:13px;outline:none;box-sizing:border-box"/></div>
|
||||
</div>
|
||||
<div style="display:flex;justify-content:flex-end;gap:12px;margin-top:20px;padding-top:16px;border-top:1px solid #eee">
|
||||
<button class="btn btn-default" style="padding:8px 28px;border-radius:6px" onclick="switchPage('overseas-truck')">取消</button>
|
||||
<button class="btn btn-primary" style="padding:8px 28px;border-radius:6px" onclick="saveTruckOrder()">提交订单</button>
|
||||
</div>
|
||||
</div></div>
|
||||
|
||||
<!-- ==================== DOMESTIC PURCHASE EDIT ==================== -->
|
||||
<div class="page" id="page-domestic-purchase-edit">
|
||||
<div class="purchase-edit-shell"><div class="purchase-edit-head"><div class="purchase-edit-title">编辑国内采购订单</div><a href="javascript:void(0)" onclick="switchPage('overseas-purchase');switchPurchaseOrderTab('domestic')" style="color:#1890ff;text-decoration:none">返回</a></div>
|
||||
<div class="purchase-edit-body"><div class="purchase-edit-section"><div class="purchase-edit-section-title">商品信息</div><div class="purchase-edit-grid">
|
||||
<div class="purchase-edit-field"><label>订单编号</label><input id="domestic-edit-no" disabled></div><div class="purchase-edit-field"><label>采购品类</label><input id="domestic-edit-category"></div><div class="purchase-edit-field"><label>商品名称</label><input id="domestic-edit-name"></div><div class="purchase-edit-field span-2"><label>商品规格</label><input id="domestic-edit-spec"></div><div class="purchase-edit-field span-3"><label>商品链接</label><input id="domestic-edit-link"></div>
|
||||
</div></div><div class="purchase-edit-section"><div class="purchase-edit-section-title">库存与快递信息</div><div class="purchase-edit-grid">
|
||||
<div class="purchase-edit-field"><label>入库量</label><input id="domestic-edit-inbound" type="number" min="0"></div><div class="purchase-edit-field"><label>出库量</label><input id="domestic-edit-outbound" type="number" min="0"></div><div class="purchase-edit-field"><label>状态</label><select id="domestic-edit-status"><option>待审核</option><option>已确认</option><option>采购中</option><option>已完成</option></select></div><div class="purchase-edit-field"><label>国内承运商</label><input id="domestic-edit-cnCarrier"></div><div class="purchase-edit-field"><label>国内运单号</label><input id="domestic-edit-cnTracking"></div><div class="purchase-edit-field"><label>海外承运商</label><input id="domestic-edit-overseasCarrier"></div><div class="purchase-edit-field"><label>海外运单号</label><input id="domestic-edit-usTracking"></div><div class="purchase-edit-field"><label>预计到达时间</label><input id="domestic-edit-eta" type="datetime-local"></div><div class="purchase-edit-field span-3"><label>备注</label><textarea id="domestic-edit-remark"></textarea></div>
|
||||
</div></div></div><div class="purchase-edit-actions"><button class="btn btn-default" onclick="switchPage('overseas-purchase');switchPurchaseOrderTab('domestic')">取消</button><button class="btn btn-primary" onclick="saveDomesticPurchaseEdit()">保存</button></div></div>
|
||||
</div>
|
||||
|
||||
<!-- ==================== OVERSEAS PURCHASE EDIT ==================== -->
|
||||
<div class="page" id="page-overseas-purchase-edit">
|
||||
<div class="purchase-edit-shell"><div class="purchase-edit-head"><div class="purchase-edit-title">编辑海外采购订单</div><a href="javascript:void(0)" onclick="switchPage('overseas-purchase');switchPurchaseOrderTab('overseas')" style="color:#1890ff;text-decoration:none">返回</a></div>
|
||||
<div class="purchase-edit-body"><div class="purchase-edit-section"><div class="purchase-edit-section-title">商品信息</div><div class="purchase-edit-grid">
|
||||
<div class="purchase-edit-field"><label>订单编号</label><input id="overseas-edit-no" disabled></div><div class="purchase-edit-field"><label>采购品类</label><input id="overseas-edit-category"></div><div class="purchase-edit-field"><label>商品名称</label><input id="overseas-edit-name"></div><div class="purchase-edit-field span-2"><label>商品规格</label><input id="overseas-edit-spec"></div><div class="purchase-edit-field span-3"><label>商品链接</label><input id="overseas-edit-link"></div>
|
||||
</div></div><div class="purchase-edit-section"><div class="purchase-edit-section-title">库存与快递信息</div><div class="purchase-edit-grid">
|
||||
<div class="purchase-edit-field"><label>入库量</label><input id="overseas-edit-inbound" type="number" min="0"></div><div class="purchase-edit-field"><label>出库量</label><input id="overseas-edit-outbound" type="number" min="0"></div><div class="purchase-edit-field"><label>状态</label><select id="overseas-edit-status"><option>待审核</option><option>已确认</option><option>采购中</option><option>已完成</option></select></div><div class="purchase-edit-field"><label>国内承运商</label><input id="overseas-edit-cnCarrier"></div><div class="purchase-edit-field"><label>国内运单号</label><input id="overseas-edit-cnTracking"></div><div class="purchase-edit-field"><label>海外承运商</label><input id="overseas-edit-overseasCarrier"></div><div class="purchase-edit-field"><label>海外运单号</label><input id="overseas-edit-usTracking"></div><div class="purchase-edit-field"><label>预计到达时间</label><input id="overseas-edit-eta" type="datetime-local"></div><div class="purchase-edit-field span-3"><label>备注</label><textarea id="overseas-edit-remark"></textarea></div>
|
||||
</div></div></div><div class="purchase-edit-actions"><button class="btn btn-default" onclick="switchPage('overseas-purchase');switchPurchaseOrderTab('overseas')">取消</button><button class="btn btn-primary" onclick="saveOverseasPurchaseEdit()">保存</button></div></div>
|
||||
</div>
|
||||
|
||||
<!-- ==================== LEGACY PURCHASE EDIT (UNLINKED) ==================== -->
|
||||
<div class="page" id="page-legacy-purchase-edit">
|
||||
<div style="font-size:14px;color:#666;margin-bottom:12px"><a href="javascript:void(0)" onclick="switchPage('overseas-purchase')" style="color:#1890ff;text-decoration:none">← 返回列表</a></div>
|
||||
<div class="table-card" style="max-width:720px">
|
||||
<div style="font-size:15px;font-weight:700;color:#1e293b;margin-bottom:20px">编辑采购订单</div>
|
||||
<div style="background:#f7f7f7;border-radius:8px;padding:28px 32px">
|
||||
<div class="form-row" style="margin-bottom:18px;display:grid;grid-template-columns:1fr 1fr;gap:0 24px">
|
||||
<div class="form-group" style="margin:0"><label style="font-size:13px;font-weight:600;color:#333;margin-bottom:6px;display:block">采购品类 <span style="color:#ef4444">*</span></label><input id="pe-category" style="width:100%;padding:10px 12px;border-radius:8px;border:1px solid #e0e0e0;background:#fff;font-size:13px;outline:none;box-sizing:border-box"/></div>
|
||||
<div class="form-group" style="margin:0"><label style="font-size:13px;font-weight:600;color:#333;margin-bottom:6px;display:block">商品名称</label><input id="pe-name" style="width:100%;padding:10px 12px;border-radius:8px;border:1px solid #e0e0e0;background:#fff;font-size:13px;outline:none;box-sizing:border-box"/></div>
|
||||
</div>
|
||||
<div class="form-row" style="margin-bottom:18px;display:grid;grid-template-columns:1fr 1fr;gap:0 24px">
|
||||
<div class="form-group" style="margin:0"><label style="font-size:13px;font-weight:600;color:#333;margin-bottom:6px;display:block">商品规格</label><input id="pe-spec" style="width:100%;padding:10px 12px;border-radius:8px;border:1px solid #e0e0e0;background:#fff;font-size:13px;outline:none;box-sizing:border-box"/></div>
|
||||
<div class="form-group" style="margin:0"><label style="font-size:13px;font-weight:600;color:#333;margin-bottom:6px;display:block">商品链接</label><input id="pe-link" style="width:100%;padding:10px 12px;border-radius:8px;border:1px solid #e0e0e0;background:#fff;font-size:13px;outline:none;box-sizing:border-box"/></div>
|
||||
</div>
|
||||
<div class="form-row" style="margin-bottom:18px;display:grid;grid-template-columns:1fr 1fr;gap:0 24px">
|
||||
<div class="form-group" style="margin:0"><label style="font-size:13px;font-weight:600;color:#333;margin-bottom:6px;display:block">采购数量 <span style="color:#ef4444">*</span></label><input id="pe-qty" type="number" min="0" style="width:100%;padding:10px 12px;border-radius:8px;border:1px solid #e0e0e0;background:#fff;font-size:13px;outline:none;box-sizing:border-box"/></div>
|
||||
<div class="form-group" style="margin:0"><label style="font-size:13px;font-weight:600;color:#333;margin-bottom:6px;display:block">预算单价</label><div style="position:relative"><span style="position:absolute;left:12px;top:50%;transform:translateY(-50%);font-size:13px;color:#999">$</span><input id="pe-price" type="number" step="0.01" min="0" placeholder="0.00" style="width:100%;padding:10px 12px 10px 22px;border-radius:8px;border:1px solid #e0e0e0;background:#fff;font-size:13px;outline:none;box-sizing:border-box"/></div></div>
|
||||
</div>
|
||||
<div class="form-row" style="margin-bottom:18px">
|
||||
<div class="form-group" style="margin:0;width:100%"><label style="font-size:13px;font-weight:600;color:#333;margin-bottom:6px;display:block">收货地址</label><input id="pe-address" style="width:100%;padding:10px 12px;border-radius:8px;border:1px solid #e0e0e0;background:#fff;font-size:13px;outline:none;box-sizing:border-box"/></div>
|
||||
</div>
|
||||
<div class="form-row" style="margin-bottom:18px;display:grid;grid-template-columns:1fr 1fr;gap:0 24px">
|
||||
<div class="form-group" style="margin:0"><label style="font-size:13px;font-weight:600;color:#333;margin-bottom:6px;display:block">中国快递单号</label><input id="pe-cnTracking" style="width:100%;padding:10px 12px;border-radius:8px;border:1px solid #e0e0e0;background:#fff;font-size:13px;outline:none;box-sizing:border-box"/></div>
|
||||
<div class="form-group" style="margin:0"><label style="font-size:13px;font-weight:600;color:#333;margin-bottom:6px;display:block">美国快递单号</label><input id="pe-usTracking" style="width:100%;padding:10px 12px;border-radius:8px;border:1px solid #e0e0e0;background:#fff;font-size:13px;outline:none;box-sizing:border-box"/></div>
|
||||
</div>
|
||||
<div class="form-row" style="margin-bottom:18px;display:grid;grid-template-columns:1fr 1fr;gap:0 24px">
|
||||
<div class="form-group" style="margin:0"><label style="font-size:13px;font-weight:600;color:#333;margin-bottom:6px;display:block">预计到达时间</label><input id="pe-eta" type="datetime-local" style="width:100%;padding:10px 12px;border-radius:8px;border:1px solid #e0e0e0;background:#fff;font-size:13px;outline:none;box-sizing:border-box"/></div>
|
||||
<div class="form-group" style="margin:0"><label style="font-size:13px;font-weight:600;color:#333;margin-bottom:6px;display:block">操作费(¥)</label><input id="pe-opFee" type="number" value="0" step="0.01" min="0" placeholder="0.00" style="width:100%;padding:10px 12px;border-radius:8px;border:1px solid #e0e0e0;background:#fff;font-size:13px;outline:none;box-sizing:border-box"/></div>
|
||||
</div>
|
||||
<div class="form-row" style="margin-bottom:18px;display:grid;grid-template-columns:1fr 1fr;gap:0 24px">
|
||||
<div class="form-group" style="margin:0"><label style="font-size:13px;font-weight:600;color:#333;margin-bottom:6px;display:block">联系人 <span style="color:#ef4444">*</span></label><input id="pe-contact" style="width:100%;padding:10px 12px;border-radius:8px;border:1px solid #e0e0e0;background:#fff;font-size:13px;outline:none;box-sizing:border-box"/></div>
|
||||
<div class="form-group" style="margin:0"><label style="font-size:13px;font-weight:600;color:#333;margin-bottom:6px;display:block">联系电话 <span style="color:#ef4444">*</span></label><input id="pe-phone" style="width:100%;padding:10px 12px;border-radius:8px;border:1px solid #e0e0e0;background:#fff;font-size:13px;outline:none;box-sizing:border-box"/></div>
|
||||
</div>
|
||||
<div class="form-row" style="margin-bottom:18px;display:grid;grid-template-columns:1fr 1fr;gap:0 24px">
|
||||
<div class="form-group" style="margin:0"><label style="font-size:13px;font-weight:600;color:#333;margin-bottom:6px;display:block">状态</label><select id="pe-status" style="width:100%;padding:10px 12px;border-radius:8px;border:1px solid #e0e0e0;background:#fff;font-size:13px;outline:none;box-sizing:border-box"><option>待审核</option><option>已确认</option><option>采购中</option><option>已完成</option></select></div>
|
||||
<div class="form-group" style="margin:0"></div>
|
||||
</div>
|
||||
<div class="form-row" style="margin-bottom:0">
|
||||
<div class="form-group" style="margin:0;width:100%"><label style="font-size:13px;font-weight:600;color:#333;margin-bottom:6px;display:block">订单备注</label><textarea id="pe-remark" rows="4" style="width:100%;padding:10px 12px;border-radius:8px;border:1px solid #e0e0e0;background:#fff;font-size:13px;outline:none;resize:vertical;box-sizing:border-box"></textarea></div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="display:flex;justify-content:flex-end;gap:12px;margin-top:20px;padding-top:16px;border-top:1px solid #eee">
|
||||
<button class="btn btn-default" style="padding:8px 28px;border-radius:6px" onclick="switchPage('overseas-purchase')">取消</button>
|
||||
<button class="btn btn-primary" style="padding:8px 28px;border-radius:6px" onclick="savePurchaseEdit()">保存修改</button>
|
||||
</div>
|
||||
</div></div>
|
||||
|
||||
<!-- ==================== OVERSEAS PURCHASE DETAIL ==================== -->
|
||||
<div class="page" id="page-domestic-purchase-detail">
|
||||
<div class="purchase-edit-shell"><div class="purchase-detail-head"><div class="purchase-detail-title">国内采购订单详情</div><button class="btn btn-default" onclick="switchPage('overseas-purchase');switchPurchaseOrderTab('domestic')">返回</button></div><div class="purchase-detail-body"><div class="purchase-detail-grid"><section class="purchase-detail-section"><h3>商品信息</h3><div id="domestic-detail-product" class="purchase-detail-fields"></div></section><section class="purchase-detail-section"><h3>库存信息</h3><div id="domestic-detail-stock" class="purchase-detail-fields"></div></section><section class="purchase-detail-section"><h3>订单信息</h3><div id="domestic-detail-order" class="purchase-detail-fields"></div></section><section class="purchase-detail-section"><h3>快递信息</h3><div id="domestic-detail-courier" class="purchase-detail-fields"></div></section><section class="purchase-detail-section full"><h3>进销存明细</h3><div id="domestic-detail-ledger" class="purchase-ledger-wrap"></div></section></div></div></div>
|
||||
</div>
|
||||
|
||||
<div class="page" id="page-overseas-purchase-detail">
|
||||
<div class="purchase-edit-shell"><div class="purchase-detail-head"><div class="purchase-detail-title">海外采购订单详情</div><button class="btn btn-default" onclick="switchPage('overseas-purchase');switchPurchaseOrderTab('overseas')">返回</button></div><div class="purchase-detail-body"><div class="purchase-detail-grid"><section class="purchase-detail-section"><h3>商品信息</h3><div id="overseas-detail-product" class="purchase-detail-fields"></div></section><section class="purchase-detail-section"><h3>库存信息</h3><div id="overseas-detail-stock" class="purchase-detail-fields"></div></section><section class="purchase-detail-section"><h3>订单信息</h3><div id="overseas-detail-order" class="purchase-detail-fields"></div></section><section class="purchase-detail-section"><h3>快递信息</h3><div id="overseas-detail-courier" class="purchase-detail-fields"></div></section><section class="purchase-detail-section full"><h3>进销存明细</h3><div id="overseas-detail-ledger" class="purchase-ledger-wrap"></div></section></div></div></div>
|
||||
</div>
|
||||
|
||||
<!-- ==================== LEGACY PURCHASE DETAIL (UNLINKED) ==================== -->
|
||||
<div class="page" id="page-legacy-purchase-detail">
|
||||
<div style="font-size:14px;color:#666;margin-bottom:12px"><a href="javascript:void(0)" onclick="switchPage('overseas-purchase')" style="color:#1890ff;text-decoration:none">← 返回列表</a></div>
|
||||
<div class="table-card" style="max-width:720px">
|
||||
<div style="font-size:15px;font-weight:700;color:#1e293b;margin-bottom:20px">采购订单详情</div>
|
||||
<div style="background:#f7f7f7;border-radius:8px;padding:28px 32px">
|
||||
<div id="pd-content"></div>
|
||||
</div>
|
||||
<div style="display:flex;justify-content:flex-end;margin-top:20px;padding-top:16px;border-top:1px solid #eee">
|
||||
<button class="btn btn-primary" style="padding:8px 28px;border-radius:6px" onclick="switchPage('overseas-purchase')">返回</button>
|
||||
</div>
|
||||
</div></div>
|
||||
|
||||
<!-- ==================== OVERSEAS LOOSEBOARD ==================== -->
|
||||
<div class="page" id="page-overseas-looseboard">
|
||||
<div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:16px">
|
||||
<div style="font-size:16px;font-weight:700;color:#1e293b">本土散板</div>
|
||||
<button class="btn btn-primary" onclick="switchPage('overseas-looseboard-add')">+ 新增订单</button>
|
||||
</div>
|
||||
<div class="table-card">
|
||||
<div style="display:flex;align-items:center;gap:10px;margin-bottom:12px;padding:0 4px">
|
||||
<select id="lb-status-filter" onchange="renderLooseboardList()" style="padding:6px 10px;border-radius:5px;border:1px solid #d9d9d9;outline:none;font-size:13px;background:#fff;color:#333">
|
||||
<option value="">全部状态</option><option value="待接单">待接单</option><option value="已派车">已派车</option><option value="运输中">运输中</option><option value="已完成">已完成</option></select>
|
||||
<input id="lb-search" placeholder="起运地/目的地" oninput="renderLooseboardList()" style="flex:1;max-width:240px;padding:6px 10px;border-radius:5px;border:1px solid #d9d9d9;outline:none;font-size:13px"/>
|
||||
<button class="btn btn-primary" style="padding:6px 18px;border-radius:5px" onclick="renderLooseboardList()">查询</button>
|
||||
</div>
|
||||
<table style="font-size:12px">
|
||||
<thead><tr>
|
||||
<th>订单编号</th><th>运输方式</th><th>是否打盘</th><th>运输类型</th><th>起运地</th><th>目的地</th><th>联系人</th><th>联系方式</th><th>总重量(kg)</th><th>预算总价</th><th>要求时间</th><th>状态</th><th>操作</th>
|
||||
</tr></thead>
|
||||
<tbody id="tbody-looseboard-list"></tbody>
|
||||
</table>
|
||||
<div style="display:flex;align-items:center;justify-content:space-between;padding:12px 4px 0;font-size:12px;color:#666">
|
||||
<span></span>
|
||||
<span style="cursor:pointer;color:#1890ff">1-5 共5条</span>
|
||||
</div>
|
||||
</div></div>
|
||||
|
||||
<!-- ==================== OVERSEAS LOOSEBOARD ADD ==================== -->
|
||||
<div class="page" id="page-overseas-looseboard-add">
|
||||
<div style="font-size:14px;color:#666;margin-bottom:12px"><a href="javascript:void(0)" onclick="switchPage('overseas-looseboard')" style="color:#1890ff;text-decoration:none">← 返回列表</a></div>
|
||||
<div class="table-card" style="max-width:760px">
|
||||
<div style="font-size:15px;font-weight:700;color:#1e293b;margin-bottom:20px">新增本土散板订单</div>
|
||||
<div style="background:#f7f7f7;border-radius:8px;padding:28px 32px">
|
||||
<!-- 运输方式 -->
|
||||
<div style="margin-bottom:18px"><label style="font-size:13px;font-weight:600;color:#333;margin-bottom:10px;display:block">运输方式 <span style="color:#ef4444">*</span></label>
|
||||
<div style="display:flex;gap:12px">
|
||||
<label class="truck-type-btn" data-val="拼车"><span style="margin-right:2px">🚐</span> 拼车</label>
|
||||
<label class="truck-type-btn" data-val="优先拼载"><span style="margin-right:2px">📦</span> 优先拼载</label>
|
||||
<input type="hidden" id="lb-transport-mode"/>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 是否打盘 -->
|
||||
<div style="margin-bottom:20px"><label style="font-size:13px;font-weight:600;color:#333;margin-bottom:10px;display:block">是否打盘 <span style="color:#ef4444">*</span></label>
|
||||
<div style="display:flex;gap:12px">
|
||||
<label class="truck-type-btn" data-val="是">是</label>
|
||||
<label class="truck-type-btn" data-val="否">否</label>
|
||||
<input type="hidden" id="lb-pallet"/>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 运输类型 -->
|
||||
<div style="margin-bottom:20px"><label style="font-size:13px;font-weight:600;color:#333;margin-bottom:10px;display:block">运输类型 <span style="color:#ef4444">*</span></label>
|
||||
<div style="display:flex;gap:12px">
|
||||
<label class="truck-type-btn" data-val="港口提柜"><span style="margin-right:4px">⚓</span> 港口提柜</label>
|
||||
<label class="truck-type-btn" data-val="仓到仓"><span style="margin-right:4px">🏭</span> 仓到仓</label>
|
||||
<label class="truck-type-btn" data-val="仓到门"><span style="margin-right:4px">🚛</span> 仓到门</label>
|
||||
<input type="hidden" id="lb-transport-type"/>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 起运地 / 目的地 -->
|
||||
<div style="display:grid;grid-template-columns:1fr 1fr;gap:0 24px;margin-bottom:18px">
|
||||
<div><label style="font-size:13px;font-weight:600;color:#333;margin-bottom:8px;display:block">起运地 <span style="color:#ef4444">*</span></label><input id="lb-origin" placeholder="城市 / 港口 / 州" style="width:100%;padding:11px 14px;border-radius:8px;border:1px solid #e0e0e0;background:#fff;font-size:13px;outline:none;box-sizing:border-box"/></div>
|
||||
<div><label style="font-size:13px;font-weight:600;color:#333;margin-bottom:8px;display:block">目的地 <span style="color:#ef4444">*</span></label><input id="lb-dest" placeholder="城市 / 州" style="width:100%;padding:11px 14px;border-radius:8px;border:1px solid #e0e0e0;background:#fff;font-size:13px;outline:none;box-sizing:border-box"/></div>
|
||||
</div>
|
||||
<!-- 详细地址 -->
|
||||
<div style="display:grid;grid-template-columns:1fr 1fr;gap:0 24px;margin-bottom:18px">
|
||||
<div><label style="font-size:13px;font-weight:600;color:#333;margin-bottom:8px;display:block">详细地址</label><input id="lb-detail-addr" placeholder="街道 / 门牌" style="width:100%;padding:11px 14px;border-radius:8px;border:1px solid #e0e0e0;background:#fff;font-size:13px;outline:none;box-sizing:border-box"/></div>
|
||||
<div><label style="font-size:13px;font-weight:600;color:#333;margin-bottom:8px;display:block">详细地址 / 码头 / 仓号</label><input id="lb-wharf" placeholder="地址 / 码头 / 仓号" style="width:100%;padding:11px 14px;border-radius:8px;border:1px solid #e0e0e0;background:#fff;font-size:13px;outline:none;box-sizing:border-box"/></div>
|
||||
</div>
|
||||
<!-- 联系人 / 联系方式 -->
|
||||
<div style="display:grid;grid-template-columns:1fr 1fr;gap:0 24px;margin-bottom:18px">
|
||||
<div><label style="font-size:13px;font-weight:600;color:#333;margin-bottom:8px;display:block">联系人</label><input id="lb-contact" placeholder="联系人姓名" style="width:100%;padding:11px 14px;border-radius:8px;border:1px solid #e0e0e0;background:#fff;font-size:13px;outline:none;box-sizing:border-box"/></div>
|
||||
<div><label style="font-size:13px;font-weight:600;color:#333;margin-bottom:8px;display:block">联系方式</label><input id="lb-phone" placeholder="联系电话" style="width:100%;padding:11px 14px;border-radius:8px;border:1px solid #e0e0e0;background:#fff;font-size:13px;outline:none;box-sizing:border-box"/></div>
|
||||
</div>
|
||||
<!-- 货物信息 -->
|
||||
<div style="margin-bottom:20px"><div style="font-size:13px;font-weight:600;color:#333;margin-bottom:10px;display:flex;align-items:center;gap:6px"><span>📦</span> 货物信息</div>
|
||||
<div style="display:grid;grid-template-columns:1fr 1fr 1fr 1fr;gap:16px">
|
||||
<div><label style="font-size:12px;color:#666;margin-bottom:6px;display:block">柜型</label><select id="lb-container" style="width:100%;padding:9px 12px;border-radius:8px;border:1px solid #e0e0e0;background:#fff;font-size:13px;outline:none;box-sizing:border-box"><option>20GP</option><option>40GP</option><option>40HQ</option><option>45HQ</option></select></div>
|
||||
<div><label style="font-size:12px;color:#666;margin-bottom:6px;display:block">件数</label><input id="lb-pieces" type="number" value="0" min="0" style="width:100%;padding:9px 12px;border-radius:8px;border:1px solid #e0e0e0;background:#fff;font-size:13px;outline:none;box-sizing:border-box"/></div>
|
||||
<div><label style="font-size:12px;color:#666;margin-bottom:6px;display:block">总重量 (kg)</label><input id="lb-gw" type="number" value="0" min="0" step="0.01" style="width:100%;padding:9px 12px;border-radius:8px;border:1px solid #e0e0e0;background:#fff;font-size:13px;outline:none;box-sizing:border-box"/></div>
|
||||
<div><label style="font-size:12px;color:#666;margin-bottom:6px;display:block">总体积 (m³)</label><input id="lb-vol" type="number" value="0" min="0" step="0.001" style="width:100%;padding:9px 12px;border-radius:8px;border:1px solid #e0e0e0;background:#fff;font-size:13px;outline:none;box-sizing:border-box"/></div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 预算总价 -->
|
||||
<div style="margin-bottom:18px"><label style="font-size:13px;font-weight:600;color:#333;margin-bottom:8px;display:block">预算总价(¥)</label><input id="lb-budget" type="number" min="0" step="0.01" placeholder="0.00" style="width:100%;max-width:300px;padding:11px 14px;border-radius:8px;border:1px solid #e0e0e0;background:#fff;font-size:13px;outline:none;box-sizing:border-box"/></div>
|
||||
<!-- 要求时间 -->
|
||||
<div><label style="font-size:13px;font-weight:600;color:#333;margin-bottom:8px;display:block">要求时间</label><input id="lb-required-date" type="date" style="width:100%;max-width:300px;padding:11px 14px;border-radius:8px;border:1px solid #e0e0e0;background:#fff;font-size:13px;outline:none;box-sizing:border-box"/></div>
|
||||
</div>
|
||||
<div style="display:flex;justify-content:flex-end;gap:12px;margin-top:20px;padding-top:16px;border-top:1px solid #eee">
|
||||
<button class="btn btn-default" style="padding:8px 28px;border-radius:6px" onclick="switchPage('overseas-looseboard')">取消</button>
|
||||
<button class="btn btn-primary" style="padding:8px 28px;border-radius:6px" onclick="saveLooseboardOrder()">提交订单</button>
|
||||
</div>
|
||||
</div></div>
|
||||
|
||||
<!-- ==================== OVERSEAS TRUCK EDIT ==================== -->
|
||||
<div class="page" id="page-overseas-truck-edit">
|
||||
<div style="font-size:14px;color:#666;margin-bottom:12px"><a href="javascript:void(0)" onclick="switchPage('overseas-truck')" style="color:#1890ff;text-decoration:none">← 返回列表</a></div>
|
||||
<div class="table-card" style="max-width:760px">
|
||||
<div style="font-size:15px;font-weight:700;color:#1e293b;margin-bottom:20px">编辑本土卡车订单</div>
|
||||
<div style="background:#f7f7f7;border-radius:8px;padding:28px 32px">
|
||||
<!-- 运输类型 -->
|
||||
<div style="margin-bottom:20px"><label style="font-size:13px;font-weight:600;color:#333;margin-bottom:10px;display:block">运输类型 <span style="color:#ef4444">*</span></label>
|
||||
<div style="display:flex;gap:12px">
|
||||
<label class="truck-type-btn" data-val="港口提柜"><span style="margin-right:4px">⚓</span> 港口提柜</label>
|
||||
<label class="truck-type-btn" data-val="仓到仓"><span style="margin-right:4px">🏭</span> 仓到仓</label>
|
||||
<label class="truck-type-btn" data-val="仓到门"><span style="margin-right:4px">🚛</span> 仓到门</label>
|
||||
<input type="hidden" id="tke-transport-type"/>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 起运地 / 目的地 -->
|
||||
<div style="display:grid;grid-template-columns:1fr 1fr;gap:0 24px;margin-bottom:18px">
|
||||
<div><label style="font-size:13px;font-weight:600;color:#333;margin-bottom:8px;display:block">起运地 <span style="color:#ef4444">*</span></label><input id="tke-origin" style="width:100%;padding:11px 14px;border-radius:8px;border:1px solid #e0e0e0;background:#fff;font-size:13px;outline:none;box-sizing:border-box"/></div>
|
||||
<div><label style="font-size:13px;font-weight:600;color:#333;margin-bottom:8px;display:block">目的地 <span style="color:#ef4444">*</span></label><input id="tke-dest" style="width:100%;padding:11px 14px;border-radius:8px;border:1px solid #e0e0e0;background:#fff;font-size:13px;outline:none;box-sizing:border-box"/></div>
|
||||
</div>
|
||||
<!-- 详细地址 -->
|
||||
<div style="display:grid;grid-template-columns:1fr 1fr;gap:0 24px;margin-bottom:18px">
|
||||
<div><label style="font-size:13px;font-weight:600;color:#333;margin-bottom:8px;display:block">详细地址</label><input id="tke-detail-addr" style="width:100%;padding:11px 14px;border-radius:8px;border:1px solid #e0e0e0;background:#fff;font-size:13px;outline:none;box-sizing:border-box"/></div>
|
||||
<div><label style="font-size:13px;font-weight:600;color:#333;margin-bottom:8px;display:block">详细地址 / 码头 / 仓号</label><input id="tke-wharf" style="width:100%;padding:11px 14px;border-radius:8px;border:1px solid #e0e0e0;background:#fff;font-size:13px;outline:none;box-sizing:border-box"/></div>
|
||||
</div>
|
||||
<!-- 联系人 / 联系方式 -->
|
||||
<div style="display:grid;grid-template-columns:1fr 1fr;gap:0 24px;margin-bottom:18px">
|
||||
<div><label style="font-size:13px;font-weight:600;color:#333;margin-bottom:8px;display:block">联系人</label><input id="tke-contact" style="width:100%;padding:11px 14px;border-radius:8px;border:1px solid #e0e0e0;background:#fff;font-size:13px;outline:none;box-sizing:border-box"/></div>
|
||||
<div><label style="font-size:13px;font-weight:600;color:#333;margin-bottom:8px;display:block">联系方式</label><input id="tke-phone" style="width:100%;padding:11px 14px;border-radius:8px;border:1px solid #e0e0e0;background:#fff;font-size:13px;outline:none;box-sizing:border-box"/></div>
|
||||
</div>
|
||||
<!-- 货物信息 -->
|
||||
<div style="margin-bottom:20px"><div style="font-size:13px;font-weight:600;color:#333;margin-bottom:10px;display:flex;align-items:center;gap:6px"><span>📦</span> 货物信息</div>
|
||||
<div style="display:grid;grid-template-columns:1fr 1fr 1fr 1fr;gap:16px">
|
||||
<div><label style="font-size:12px;color:#666;margin-bottom:6px;display:block">柜型</label><select id="tke-container" style="width:100%;padding:9px 12px;border-radius:8px;border:1px solid #e0e0e0;background:#fff;font-size:13px;outline:none;box-sizing:border-box"><option>20GP</option><option>40GP</option><option>40HQ</option><option>45HQ</option></select></div>
|
||||
<div><label style="font-size:12px;color:#666;margin-bottom:6px;display:block">件数</label><input id="tke-pieces" type="number" value="0" min="0" style="width:100%;padding:9px 12px;border-radius:8px;border:1px solid #e0e0e0;background:#fff;font-size:13px;outline:none;box-sizing:border-box"/></div>
|
||||
<div><label style="font-size:12px;color:#666;margin-bottom:6px;display:block">总重量 (kg)</label><input id="tke-gw" type="number" value="0" min="0" step="0.01" style="width:100%;padding:9px 12px;border-radius:8px;border:1px solid #e0e0e0;background:#fff;font-size:13px;outline:none;box-sizing:border-box"/></div>
|
||||
<div><label style="font-size:12px;color:#666;margin-bottom:6px;display:block">总体积 (m³)</label><input id="tke-vol" type="number" value="0" min="0" step="0.001" style="width:100%;padding:9px 12px;border-radius:8px;border:1px solid #e0e0e0;background:#fff;font-size:13px;outline:none;box-sizing:border-box"/></div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 预算总价 -->
|
||||
<div style="margin-bottom:20px"><label style="font-size:13px;font-weight:600;color:#333;margin-bottom:8px;display:block">预算总价(¥)</label><input id="tke-budget" type="number" min="0" step="0.01" placeholder="0.00" style="width:100%;max-width:300px;padding:11px 14px;border-radius:8px;border:1px solid #e0e0e0;background:#fff;font-size:13px;outline:none;box-sizing:border-box"/></div>
|
||||
<!-- 要求时间 -->
|
||||
<div style="margin-bottom:20px"><label style="font-size:13px;font-weight:600;color:#333;margin-bottom:8px;display:block">要求时间</label><input id="tke-required-date" type="date" style="width:100%;max-width:300px;padding:11px 14px;border-radius:8px;border:1px solid #e0e0e0;background:#fff;font-size:13px;outline:none;box-sizing:border-box"/></div>
|
||||
<!-- 状态 -->
|
||||
<div style="display:grid;grid-template-columns:1fr 1fr;gap:0 24px;margin-bottom:0"><div><label style="font-size:13px;font-weight:600;color:#333;margin-bottom:8px;display:block">状态</label><select id="tke-status" style="width:100%;padding:11px 14px;border-radius:8px;border:1px solid #e0e0e0;background:#fff;font-size:13px;outline:none;box-sizing:border-box"><option>待接单</option><option>已派车</option><option>运输中</option><option>已完成</option></select></div><div></div></div>
|
||||
</div>
|
||||
<div style="display:flex;justify-content:flex-end;gap:12px;margin-top:20px;padding-top:16px;border-top:1px solid #eee">
|
||||
<button class="btn btn-default" style="padding:8px 28px;border-radius:6px" onclick="switchPage('overseas-truck')">取消</button>
|
||||
<button class="btn btn-primary" style="padding:8px 28px;border-radius:6px" onclick="saveTruckOrderEdit()">保存修改</button>
|
||||
</div>
|
||||
</div></div>
|
||||
|
||||
<!-- ==================== OVERSEAS LOOSEBOARD EDIT ==================== -->
|
||||
<div class="page" id="page-overseas-looseboard-edit">
|
||||
<div style="font-size:14px;color:#666;margin-bottom:12px"><a href="javascript:void(0)" onclick="switchPage('overseas-looseboard')" style="color:#1890ff;text-decoration:none">← 返回列表</a></div>
|
||||
<div class="table-card" style="max-width:760px">
|
||||
<div style="font-size:15px;font-weight:700;color:#1e293b;margin-bottom:20px">编辑本土散板订单</div>
|
||||
<div style="background:#f7f7f7;border-radius:8px;padding:28px 32px">
|
||||
<!-- 运输方式 -->
|
||||
<div style="margin-bottom:18px"><label style="font-size:13px;font-weight:600;color:#333;margin-bottom:10px;display:block">运输方式 <span style="color:#ef4444">*</span></label>
|
||||
<div style="display:flex;gap:12px">
|
||||
<label class="truck-type-btn" data-val="拼车">🚐 拼车</label>
|
||||
<label class="truck-type-btn" data-val="优先拼载">📦 优先拼载</label>
|
||||
<input type="hidden" id="lbe-transport-mode"/>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 是否打盘 -->
|
||||
<div style="margin-bottom:20px"><label style="font-size:13px;font-weight:600;color:#333;margin-bottom:10px;display:block">是否打盘 <span style="color:#ef4444">*</span></label>
|
||||
<div style="display:flex;gap:12px">
|
||||
<label class="truck-type-btn" data-val="是">是</label>
|
||||
<label class="truck-type-btn" data-val="否">否</label>
|
||||
<input type="hidden" id="lbe-pallet"/>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 运输类型 -->
|
||||
<div style="margin-bottom:20px"><label style="font-size:13px;font-weight:600;color:#333;margin-bottom:10px;display:block">运输类型 <span style="color:#ef4444">*</span></label>
|
||||
<div style="display:flex;gap:12px">
|
||||
<label class="truck-type-btn" data-val="港口提柜"><span style="margin-right:4px">⚓</span> 港口提柜</label>
|
||||
<label class="truck-type-btn" data-val="仓到仓"><span style="margin-right:4px">🏭</span> 仓到仓</label>
|
||||
<label class="truck-type-btn" data-val="仓到门"><span style="margin-right:4px">🚛</span> 仓到门</label>
|
||||
<input type="hidden" id="lbe-transport-type"/>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 起运地 / 目的地 -->
|
||||
<div style="display:grid;grid-template-columns:1fr 1fr;gap:0 24px;margin-bottom:18px">
|
||||
<div><label style="font-size:13px;font-weight:600;color:#333;margin-bottom:8px;display:block">起运地 <span style="color:#ef4444">*</span></label><input id="lbe-origin" style="width:100%;padding:11px 14px;border-radius:8px;border:1px solid #e0e0e0;background:#fff;font-size:13px;outline:none;box-sizing:border-box"/></div>
|
||||
<div><label style="font-size:13px;font-weight:600;color:#333;margin-bottom:8px;display:block">目的地 <span style="color:#ef4444">*</span></label><input id="lbe-dest" style="width:100%;padding:11px 14px;border-radius:8px;border:1px solid #e0e0e0;background:#fff;font-size:13px;outline:none;box-sizing:border-box"/></div>
|
||||
</div>
|
||||
<!-- 详细地址 -->
|
||||
<div style="display:grid;grid-template-columns:1fr 1fr;gap:0 24px;margin-bottom:18px">
|
||||
<div><label style="font-size:13px;font-weight:600;color:#333;margin-bottom:8px;display:block">详细地址</label><input id="lbe-detail-addr" style="width:100%;padding:11px 14px;border-radius:8px;border:1px solid #e0e0e0;background:#fff;font-size:13px;outline:none;box-sizing:border-box"/></div>
|
||||
<div><label style="font-size:13px;font-weight:600;color:#333;margin-bottom:8px;display:block">详细地址 / 码头 / 仓号</label><input id="lbe-wharf" style="width:100%;padding:11px 14px;border-radius:8px;border:1px solid #e0e0e0;background:#fff;font-size:13px;outline:none;box-sizing:border-box"/></div>
|
||||
</div>
|
||||
<!-- 联系人 / 联系方式 -->
|
||||
<div style="display:grid;grid-template-columns:1fr 1fr;gap:0 24px;margin-bottom:18px">
|
||||
<div><label style="font-size:13px;font-weight:600;color:#333;margin-bottom:8px;display:block">联系人</label><input id="lbe-contact" style="width:100%;padding:11px 14px;border-radius:8px;border:1px solid #e0e0e0;background:#fff;font-size:13px;outline:none;box-sizing:border-box"/></div>
|
||||
<div><label style="font-size:13px;font-weight:600;color:#333;margin-bottom:8px;display:block">联系方式</label><input id="lbe-phone" style="width:100%;padding:11px 14px;border-radius:8px;border:1px solid #e0e0e0;background:#fff;font-size:13px;outline:none;box-sizing:border-box"/></div>
|
||||
</div>
|
||||
<!-- 货物信息 -->
|
||||
<div style="margin-bottom:20px"><div style="font-size:13px;font-weight:600;color:#333;margin-bottom:10px;display:flex;align-items:center;gap:6px"><span>📦</span> 货物信息</div>
|
||||
<div style="display:grid;grid-template-columns:1fr 1fr 1fr 1fr;gap:16px">
|
||||
<div><label style="font-size:12px;color:#666;margin-bottom:6px;display:block">柜型</label><select id="lbe-container" style="width:100%;padding:9px 12px;border-radius:8px;border:1px solid #e0e0e0;background:#fff;font-size:13px;outline:none;box-sizing:border-box"><option>20GP</option><option>40GP</option><option>40HQ</option><option>45HQ</option></select></div>
|
||||
<div><label style="font-size:12px;color:#666;margin-bottom:6px;display:block">件数</label><input id="lbe-pieces" type="number" value="0" min="0" style="width:100%;padding:9px 12px;border-radius:8px;border:1px solid #e0e0e0;background:#fff;font-size:13px;outline:none;box-sizing:border-box"/></div>
|
||||
<div><label style="font-size:12px;color:#666;margin-bottom:6px;display:block">总重量 (kg)</label><input id="lbe-gw" type="number" value="0" min="0" step="0.01" style="width:100%;padding:9px 12px;border-radius:8px;border:1px solid #e0e0e0;background:#fff;font-size:13px;outline:none;box-sizing:border-box"/></div>
|
||||
<div><label style="font-size:12px;color:#666;margin-bottom:6px;display:block">总体积 (m³)</label><input id="lbe-vol" type="number" value="0" min="0" step="0.001" style="width:100%;padding:9px 12px;border-radius:8px;border:1px solid #e0e0e0;background:#fff;font-size:13px;outline:none;box-sizing:border-box"/></div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 预算总价 -->
|
||||
<div style="margin-bottom:20px"><label style="font-size:13px;font-weight:600;color:#333;margin-bottom:8px;display:block">预算总价(¥)</label><input id="lbe-budget" type="number" min="0" step="0.01" placeholder="0.00" style="width:100%;max-width:300px;padding:11px 14px;border-radius:8px;border:1px solid #e0e0e0;background:#fff;font-size:13px;outline:none;box-sizing:border-box"/></div>
|
||||
<!-- 要求时间 -->
|
||||
<div style="margin-bottom:20px"><label style="font-size:13px;font-weight:600;color:#333;margin-bottom:8px;display:block">要求时间</label><input id="lbe-required-date" type="date" style="width:100%;max-width:300px;padding:11px 14px;border-radius:8px;border:1px solid #e0e0e0;background:#fff;font-size:13px;outline:none;box-sizing:border-box"/></div>
|
||||
<!-- 状态 -->
|
||||
<div style="display:grid;grid-template-columns:1fr 1fr;gap:0 24px;margin-bottom:0"><div><label style="font-size:13px;font-weight:600;color:#333;margin-bottom:8px;display:block">状态</label><select id="lbe-status" style="width:100%;padding:11px 14px;border-radius:8px;border:1px solid #e0e0e0;background:#fff;font-size:13px;outline:none;box-sizing:border-box"><option>待接单</option><option>已派车</option><option>运输中</option><option>已完成</option></select></div><div></div></div>
|
||||
</div>
|
||||
<div style="display:flex;justify-content:flex-end;gap:12px;margin-top:20px;padding-top:16px;border-top:1px solid #eee">
|
||||
<button class="btn btn-default" style="padding:8px 28px;border-radius:6px" onclick="switchPage('overseas-looseboard')">取消</button>
|
||||
<button class="btn btn-primary" style="padding:8px 28px;border-radius:6px" onclick="saveLooseboardOrderEdit()">保存修改</button>
|
||||
</div>
|
||||
</div></div>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,102 @@
|
||||
<!-- 模块:销售管理。页面片段由 scripts/split-prototype.cjs 从完整原型拆出。 -->
|
||||
<div class="page" id="page-gen-sales">
|
||||
<div class="breadcrumb">首页 <span class="sep">></span> 销售管理 <span class="sep">></span> <strong>拜访记录</strong></div>
|
||||
<div class="table-card"><div class="table-toolbar"><span class="title">拜访记录</span><div class="toolbar-actions"><button class="btn btn-primary" onclick="showSalesVisitAdd()">+ 新增拜访记录</button><button class="btn btn-default">导出</button></div></div>
|
||||
<div class="search-row">
|
||||
<input placeholder="客户名称/联系人" style="width:180px"/>
|
||||
<input placeholder="销售人员" style="width:150px"/>
|
||||
<input type="date" style="width:150px" placeholder="拜访时间"/>
|
||||
<button class="btn btn-sm btn-primary">查询</button><button class="btn btn-sm btn-default">重置</button>
|
||||
</div>
|
||||
<table><thead><tr><th>客户信息</th><th>来源渠道</th><th>名称</th><th>联系人</th><th>联系电话</th><th>拜访时间</th><th>销售人员</th><th>拜访内容记录</th><th>操作</th></tr></thead><tbody id="tbody-gen-sales"></tbody></table>
|
||||
<div class="pagination"><span>共 0 条</span><button class="page-btn active">1</button></div></div></div>
|
||||
|
||||
<!-- ==================== SALES VISIT ADD ==================== -->
|
||||
<div class="page" id="page-gen-sales-add">
|
||||
<div style="font-size:14px;color:#666;margin-bottom:12px"><a href="javascript:void(0)" onclick="cancelSalesVisitEdit()" style="color:#1890ff;text-decoration:none">← 返回列表</a></div>
|
||||
<div class="table-card" style="max-width:720px">
|
||||
<div id="sv-form-title" style="font-size:15px;font-weight:700;color:#1e293b;margin-bottom:20px">新增拜访记录</div>
|
||||
<div style="background:#f7f7f7;border-radius:8px;padding:28px 32px">
|
||||
<div class="form-row" style="margin-bottom:18px;display:grid;grid-template-columns:1fr 1fr;gap:0 24px">
|
||||
<div class="form-group" style="margin:0"><label style="font-size:13px;font-weight:600;color:#333;margin-bottom:6px;display:block">客户信息 <span style="color:#ef4444">*</span></label><input id="sv-customer" placeholder="请输入客户公司名称" style="width:100%;padding:10px 12px;border-radius:8px;border:1px solid #e0e0e0;background:#fff;font-size:13px;outline:none;box-sizing:border-box"/></div>
|
||||
<div class="form-group" style="margin:0"><label style="font-size:13px;font-weight:600;color:#333;margin-bottom:6px;display:block">名称 <span style="color:#ef4444">*</span></label><input id="sv-name" placeholder="请输入被拜访人名称" style="width:100%;padding:10px 12px;border-radius:8px;border:1px solid #e0e0e0;background:#fff;font-size:13px;outline:none;box-sizing:border-box"/></div>
|
||||
</div>
|
||||
<div class="form-row" style="margin-bottom:18px;display:grid;grid-template-columns:1fr 1fr;gap:0 24px">
|
||||
<div class="form-group" style="margin:0"><label style="font-size:13px;font-weight:600;color:#333;margin-bottom:6px;display:block">联系人 <span style="color:#ef4444">*</span></label><input id="sv-contact" placeholder="请输入联系人姓名" style="width:100%;padding:10px 12px;border-radius:8px;border:1px solid #e0e0e0;background:#fff;font-size:13px;outline:none;box-sizing:border-box"/></div>
|
||||
<div class="form-group" style="margin:0"><label style="font-size:13px;font-weight:600;color:#333;margin-bottom:6px;display:block">联系电话 <span style="color:#ef4444">*</span></label><input id="sv-phone" placeholder="请输入联系电话" style="width:100%;padding:10px 12px;border-radius:8px;border:1px solid #e0e0e0;background:#fff;font-size:13px;outline:none;box-sizing:border-box"/></div>
|
||||
</div>
|
||||
<div class="form-row" style="margin-bottom:18px;display:grid;grid-template-columns:1fr 1fr;gap:0 24px">
|
||||
<div class="form-group" style="margin:0"><label style="font-size:13px;font-weight:600;color:#333;margin-bottom:6px;display:block">拜访时间 <span style="color:#ef4444">*</span></label><input id="sv-visitTime" type="datetime-local" style="width:100%;padding:10px 12px;border-radius:8px;border:1px solid #e0e0e0;background:#fff;font-size:13px;outline:none;box-sizing:border-box"/></div>
|
||||
<div class="form-group" style="margin:0"><label style="font-size:13px;font-weight:600;color:#333;margin-bottom:6px;display:block">销售人员 <span style="color:#ef4444">*</span></label><input id="sv-salesPerson" placeholder="请输入销售人员姓名" style="width:100%;padding:10px 12px;border-radius:8px;border:1px solid #e0e0e0;background:#fff;font-size:13px;outline:none;box-sizing:border-box"/></div>
|
||||
</div>
|
||||
<div class="form-row" style="margin-bottom:18px">
|
||||
<div class="form-group" style="margin:0;width:100%"><label style="font-size:13px;font-weight:600;color:#333;margin-bottom:6px;display:block">来源渠道 <span style="color:#ef4444">*</span></label><select id="sv-source" style="width:100%;padding:10px 12px;border-radius:8px;border:1px solid #e0e0e0;background:#fff;font-size:13px;outline:none;box-sizing:border-box"><option value="">请选择来源渠道</option><option>客户转介绍</option><option>官网咨询</option><option>展会获客</option><option>电话开发</option><option>社交媒体</option><option>渠道合作</option><option>老客户复购</option><option>其他</option></select></div>
|
||||
</div>
|
||||
<div class="form-row" style="margin-bottom:18px">
|
||||
<div class="form-group" style="margin:0;width:100%"><label style="font-size:13px;font-weight:600;color:#333;margin-bottom:6px;display:block">拜访内容记录 <span style="color:#ef4444">*</span></label><textarea id="sv-content" rows="5" placeholder="请详细记录本次拜访/沟通的内容" style="width:100%;padding:10px 12px;border-radius:8px;border:1px solid #e0e0e0;background:#fff;font-size:13px;outline:none;resize:vertical;box-sizing:border-box"></textarea></div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="display:flex;justify-content:flex-end;gap:12px;margin-top:20px;padding-top:16px;border-top:1px solid #eee">
|
||||
<button class="btn btn-default" style="padding:8px 28px;border-radius:6px" onclick="cancelSalesVisitEdit()">取消</button>
|
||||
<button class="btn btn-primary" id="sv-submit-btn" style="padding:8px 28px;border-radius:6px" onclick="saveSalesVisit()">提交记录</button>
|
||||
</div>
|
||||
</div></div>
|
||||
|
||||
<!-- ==================== SALES VISIT DETAIL ==================== -->
|
||||
<div class="page" id="page-gen-sales-detail">
|
||||
<div style="font-size:14px;color:#666;margin-bottom:12px"><a href="javascript:void(0)" onclick="switchPage('gen-sales')" style="color:#1890ff;text-decoration:none">← 返回列表</a></div>
|
||||
<div class="table-card" style="max-width:720px">
|
||||
<div style="font-size:15px;font-weight:700;color:#1e293b;margin-bottom:20px">拜访记录详情</div>
|
||||
<div style="background:#f7f7f7;border-radius:8px;padding:28px 32px">
|
||||
<div id="sv-detail-content"></div>
|
||||
</div>
|
||||
<div style="display:flex;justify-content:flex-end;gap:12px;margin-top:20px;padding-top:16px;border-top:1px solid #eee">
|
||||
<button class="btn btn-default" style="padding:8px 28px;border-radius:6px" onclick="switchPage('gen-sales')">返回列表</button>
|
||||
</div>
|
||||
</div></div>
|
||||
|
||||
<!-- ==================== SALES COMMISSION ==================== -->
|
||||
<div class="page" id="page-sales-commission">
|
||||
<div class="breadcrumb">首页 <span class="sep">></span> 销售管理 <span class="sep">></span> <strong>销售提成</strong></div>
|
||||
|
||||
<div style="display:grid;grid-template-columns:repeat(4,1fr);gap:16px;margin-bottom:18px">
|
||||
<div style="background:linear-gradient(135deg,#1677ff,#4096ff);border-radius:10px;padding:18px 20px;color:#fff">
|
||||
<div style="font-size:13px;opacity:.9">总销售额</div>
|
||||
<div style="font-size:22px;font-weight:700;margin-top:6px" id="sc-card-amount">¥0.00</div>
|
||||
</div>
|
||||
<div style="background:linear-gradient(135deg,#cf1322,#ff4d4f);border-radius:10px;padding:18px 20px;color:#fff">
|
||||
<div style="font-size:13px;opacity:.9">提成金额合计</div>
|
||||
<div style="font-size:22px;font-weight:700;margin-top:6px" id="sc-card-comm">¥0.00</div>
|
||||
</div>
|
||||
<div style="background:linear-gradient(135deg,#13c2c2,#36cfc9);border-radius:10px;padding:18px 20px;color:#fff">
|
||||
<div style="font-size:13px;opacity:.9">销售人员数</div>
|
||||
<div style="font-size:22px;font-weight:700;margin-top:6px" id="sc-card-sales">0</div>
|
||||
</div>
|
||||
<div style="background:linear-gradient(135deg,#722ed1,#9254de);border-radius:10px;padding:18px 20px;color:#fff">
|
||||
<div style="font-size:13px;opacity:.9">订单总数</div>
|
||||
<div style="font-size:22px;font-weight:700;margin-top:6px" id="sc-card-cust">0</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="table-card"><div class="table-toolbar"><span class="title">销售提成明细</span><div class="toolbar-actions"><button class="btn btn-default">导出Excel</button><button class="btn btn-default">打印</button></div></div>
|
||||
<div class="search-row">
|
||||
<input id="sc-sales" placeholder="销售姓名/编号" style="width:170px"/>
|
||||
<select id="sc-team" style="width:150px"><option value="">全部区域</option><option>华东大区</option><option>华南大区</option><option>华北大区</option><option>海外大区</option></select>
|
||||
<input type="month" id="sc-month" style="width:170px" title="提成月份"/>
|
||||
<button class="btn btn-sm btn-primary" onclick="renderSalesCommission()">查询</button>
|
||||
<button class="btn btn-sm btn-default" onclick="scReset()">重置</button>
|
||||
</div>
|
||||
<table><thead><tr><th>销售编号</th><th>销售姓名</th><th>区域/团队</th><th>客户数</th><th>订单数</th><th>销售额(元)</th><th>综合提成率</th><th>提成金额(元)</th><th>操作</th></tr></thead><tbody id="tbody-sales-commission"></tbody><tfoot id="tfoot-sales-commission"></tfoot></table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ==================== SALES COMMISSION DETAIL MODAL ==================== -->
|
||||
<div class="modal-overlay" id="modal-sc-detail">
|
||||
<div class="modal" style="width:1160px;max-width:96vw;max-height:88vh;overflow-y:auto">
|
||||
<div class="modal-header"><span id="sc-detail-title">销售提成明细</span><span onclick="hideModal('modal-sc-detail')" style="cursor:pointer;font-size:20px">×</span></div>
|
||||
<div class="modal-body" id="sc-detail-body" style="padding:24px"></div>
|
||||
<div class="modal-footer"><button class="btn btn-default" onclick="hideModal('modal-sc-detail')">关闭</button></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ==================== ORDER LIST ==================== -->
|
||||
@@ -0,0 +1,207 @@
|
||||
<!-- 模块:通用资料。页面片段由 scripts/split-prototype.cjs 从完整原型拆出。 -->
|
||||
<div class="page" id="page-gen-product">
|
||||
<div class="table-card"><div class="table-toolbar"><span class="title">产品信息</span><div class="toolbar-actions"><button class="btn btn-primary">+ 新增</button><button class="btn btn-default">导入</button><button class="btn btn-default">导出</button><button class="btn btn-default">高级查询</button></div></div>
|
||||
<div class="search-row"><input placeholder="产品名称/SKU" style="width:180px"/><select><option>全部分类</option><option>电子产品</option><option>服装</option><option>家居</option></select><select><option>全部状态</option><option>启用</option><option>停用</option></select><button class="btn btn-sm btn-primary">查询</button></div>
|
||||
<table><thead><tr><th>产品名称</th><th>SKU</th><th>分类</th><th>规格</th><th>重量(kg)</th><th>体积(m³)</th><th>状态</th><th>操作</th></tr></thead><tbody id="tbody-gen-product"></tbody></table>
|
||||
<div class="pagination"><span>共 86 条</span><button class="page-btn active">1</button><button class="page-btn">2</button><button class="page-btn">3</button><button class="page-btn">...</button><button class="page-btn">9</button></div></div></div>
|
||||
|
||||
<div class="page" id="page-gen-fee">
|
||||
<div class="table-card"><div class="table-toolbar"><span class="title">费用项目</span><div class="toolbar-actions"><button class="btn btn-primary">+ 新增</button><button class="btn btn-default">导入</button><button class="btn btn-default">导出</button><button class="btn btn-default">高级查询</button></div></div>
|
||||
<div class="search-row"><select><option>全部分类</option><option>洛杉矶仓储成本</option><option>默认</option></select><select><option>全部国内国际</option><option>国内</option><option>国际</option></select><input placeholder="费用类型名称" style="width:180px"/><button class="btn btn-sm btn-primary">查询</button></div>
|
||||
<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></tr></thead><tbody id="tbody-gen-fee"></tbody></table>
|
||||
<div class="pagination"><span>共 110 条</span><button class="page-btn active">1</button><button class="page-btn">2</button><button class="page-btn">3</button><button class="page-btn">...</button><button class="page-btn">11</button></div></div></div>
|
||||
|
||||
<!-- ==================== OUTBOUND VEHICLE (排车列表) ==================== -->
|
||||
<div class="page" id="page-gen-fba">
|
||||
<div class="table-card"><div class="table-toolbar"><span class="title">仓库管理</span><div class="toolbar-actions"><button class="btn btn-primary" onclick="showModal('modal-fba-add')">+ 新增</button><button class="btn btn-default">导入</button><button class="btn btn-default">导出</button></div></div>
|
||||
<div class="search-row"><input placeholder="仓库代码/地址" style="width:200px"/><select><option>全部国家</option><option>美国</option><option>英国</option><option>德国</option><option>日本</option></select><button class="btn btn-sm btn-primary">查询</button></div>
|
||||
<table><thead><tr><th>仓库代码</th><th>仓库地址</th><th>城市</th><th>州/省</th><th>邮编</th><th>国家</th><th>状态</th><th>操作</th></tr></thead><tbody id="tbody-gen-fba"></tbody></table>
|
||||
<div class="pagination"><span>共 56 条</span><button class="page-btn active">1</button><button class="page-btn">2</button><button class="page-btn">3</button><button class="page-btn">...</button><button class="page-btn">6</button></div></div></div>
|
||||
|
||||
<div class="page" id="page-gen-download">
|
||||
<div class="table-card">
|
||||
<div class="table-toolbar"><span class="title">下载中心</span></div>
|
||||
<div class="search-row" aria-label="下载任务查询">
|
||||
<select id="download-type" aria-label="任务类型"><option value="">全部任务类型</option><option>客户列表</option><option>订单列表</option><option>入库单</option><option>客户对账单</option></select>
|
||||
<select id="download-status" aria-label="任务状态"><option value="">全部任务状态</option><option>已完成</option><option>生成中</option><option>失败</option><option>已过期</option></select>
|
||||
<input id="download-start-date" type="date" aria-label="开始日期"/>
|
||||
<span style="color:#8c8c8c">至</span>
|
||||
<input id="download-end-date" type="date" aria-label="结束日期"/>
|
||||
<button class="btn btn-sm btn-primary" onclick="queryDownloadTasks()">查询</button>
|
||||
<button class="btn btn-sm btn-default" onclick="resetDownloadTasks()">重置</button>
|
||||
</div>
|
||||
<div style="overflow-x:auto">
|
||||
<table style="min-width:1320px"><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="tbody-gen-download"></tbody></table>
|
||||
</div>
|
||||
<div class="pagination" id="pagination-gen-download"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal-overlay" id="modal-download-detail">
|
||||
<div class="modal" style="max-width:720px">
|
||||
<div class="modal-header">下载任务详情<span onclick="hideModal('modal-download-detail')" style="cursor:pointer;font-size:20px">×</span></div>
|
||||
<div class="modal-body"><div class="info-grid" id="download-detail-grid"></div></div>
|
||||
<div class="modal-footer"><button class="btn btn-default" onclick="hideModal('modal-download-detail')">关闭</button><button class="btn btn-primary" id="download-detail-action">下载文件</button></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="page" id="page-gen-pallet">
|
||||
<div class="table-card"><div class="table-toolbar"><span class="title">托盘管理</span><div class="toolbar-actions"><button class="btn btn-primary">+ 新增</button><button class="btn btn-default">导入</button><button class="btn btn-default">导出</button></div></div>
|
||||
<div class="search-row"><input placeholder="托盘编号" style="width:150px"/><select><option>全部类型</option><option>木质</option><option>塑料</option><option>金属</option></select><select><option>全部状态</option><option>空闲</option><option>使用中</option><option>损坏</option></select><button class="btn btn-sm btn-primary">查询</button></div>
|
||||
<table><thead><tr><th>托盘编号</th><th>类型</th><th>尺寸(cm)</th><th>承重(kg)</th><th>所在仓库</th><th>状态</th><th>操作</th></tr></thead><tbody id="tbody-gen-pallet"></tbody></table>
|
||||
<div class="pagination"><span>共 320 条</span><button class="page-btn active">1</button><button class="page-btn">2</button><button class="page-btn">3</button><button class="page-btn">...</button><button class="page-btn">32</button></div></div></div>
|
||||
|
||||
<div class="page" id="page-gen-location">
|
||||
<div class="table-card"><div class="table-toolbar"><span class="title">库位/货架管理</span><div class="toolbar-actions"><button class="btn btn-primary">+ 新增</button><button class="btn btn-default">导入</button><button class="btn btn-default">导出</button></div></div>
|
||||
<div class="search-row"><select><option>全部仓库</option><option>洛杉矶仓</option><option>纽约仓</option><option>宁波仓</option></select><input placeholder="库位编码" style="width:150px"/><select><option>全部状态</option><option>空闲</option><option>占用</option><option>冻结</option></select><button class="btn btn-sm btn-primary">查询</button></div>
|
||||
<table><thead><tr><th>仓库</th><th>库区</th><th>货架</th><th>库位</th><th>容量(m³)</th><th>状态</th><th>操作</th></tr></thead><tbody id="tbody-gen-location"></tbody></table>
|
||||
<div class="pagination"><span>共 480 条</span><button class="page-btn active">1</button><button class="page-btn">2</button><button class="page-btn">3</button><button class="page-btn">...</button><button class="page-btn">48</button></div></div></div>
|
||||
|
||||
<div class="page" id="page-gen-route">
|
||||
<div class="table-card"><div class="table-toolbar"><span class="title">订单流程路径</span><div class="toolbar-actions"><button class="btn btn-primary">+ 新增</button><button class="btn btn-default">导出</button></div></div>
|
||||
<div class="search-row"><input placeholder="路径名称" style="width:180px"/><select><option>全部业务类型</option><option>海运出口</option><option>海运进口</option><option>空运</option></select><button class="btn btn-sm btn-primary">查询</button></div>
|
||||
<table><thead><tr><th>路径名称</th><th>业务类型</th><th>节点数</th><th>节点列表</th><th>状态</th><th>操作</th></tr></thead><tbody id="tbody-gen-route"></tbody></table>
|
||||
<div class="pagination"><span>共 12 条</span><button class="page-btn active">1</button><button class="page-btn">2</button></div></div></div>
|
||||
|
||||
<div class="page" id="page-gen-voyage">
|
||||
<div class="table-card">
|
||||
<div class="table-toolbar"><div><span class="title">船期价格表</span><span style="font-size:12px;color:#94a3b8;margin-left:10px">按周沉淀渠道价格,支持成本测算</span></div></div>
|
||||
<div class="voyage-tabs">
|
||||
<div class="voyage-tab active" data-tab="weekly" onclick="switchVoyageTab('weekly')">渠道周价格</div>
|
||||
<div class="voyage-tab" data-tab="cost" onclick="switchVoyageTab('cost')">成本测算</div>
|
||||
</div>
|
||||
|
||||
<div class="voyage-pane active" id="voyage-pane-weekly">
|
||||
<div class="table-toolbar" style="padding-bottom:4px"><span style="font-size:13px;color:#64748b">当前与历史周价格档案</span><div class="toolbar-actions"><button class="btn btn-primary">+ 新增</button><button class="btn btn-default">导入</button><button class="btn btn-default">导出</button></div></div>
|
||||
<div class="search-row">
|
||||
<input id="voyage-filter-fba" placeholder="FBA仓库" style="width:145px"/>
|
||||
<select id="voyage-filter-channel" style="width:180px"><option value="">全部渠道</option><option>美森正班海卡</option><option>美森加班海卡</option><option>EXX海卡</option><option>合德海卡</option><option>纽约EXX海铁</option><option>洛杉矶普船海卡</option><option>洛杉矶普船全卡</option><option>芝加哥普船海铁</option><option>休斯顿普船海卡</option></select>
|
||||
<select id="voyage-filter-week" style="width:205px"><option value="2026-08-03">2026-08-03 至 08-09(当前周)</option><option value="2026-07-27">2026-07-27 至 08-02</option><option value="2026-07-20">2026-07-20 至 07-26</option><option value="2026-07-13">2026-07-13 至 07-19</option><option value="2026-07-06">2026-07-06 至 07-12</option><option value="2026-06-29">2026-06-29 至 07-05</option></select>
|
||||
<select id="voyage-filter-sailing" style="width:125px"><option value="">全部船期</option><option>周一</option><option>周二</option><option>周三</option><option>周四</option><option>周五</option><option>周六</option><option>周日</option></select>
|
||||
<button class="btn btn-sm btn-primary" onclick="filterVoyageWeeklyPrices()">查询</button><button class="btn btn-sm btn-default" onclick="resetVoyageWeeklyFilters()">重置</button>
|
||||
</div>
|
||||
<div class="week-summary"><span class="current-week-badge" id="voyage-week-badge">当前周</span><strong id="voyage-week-title">2026-08-03 至 2026-08-09</strong><span id="voyage-week-note">本周价格生效中,后续修改仅影响当前周数据</span></div>
|
||||
<div class="inbound-table-container"><table><thead><tr><th>操作</th><th>FBA仓库</th><th>渠道</th><th>华东仓(义乌)<br/>不包税(/CBM)</th><th>华东仓(义乌)<br/>包税(/KG)</th><th>华南仓(深圳)<br/>包税(/CBM)</th><th>华南仓(深圳)<br/>包税(/KG)</th><th>参考时效<br/>(船开后)</th><th>最晚进仓时间</th><th>船期</th><th>附加费</th><th>备注</th><th>生效状态</th></tr></thead><tbody id="tbody-gen-voyage"></tbody></table></div>
|
||||
<div class="pagination"><span id="voyage-total-count">共 26 条</span><button class="page-btn active">1</button></div>
|
||||
</div>
|
||||
|
||||
<div class="voyage-pane" id="voyage-pane-cost">
|
||||
<div class="cost-hero">
|
||||
<div class="cost-hero-head"><div><div class="cost-hero-title">芝加哥普船海铁 · 成本测算</div><div class="cost-hero-sub">参考《芝加哥普船海铁成本测算》,所有费用均可编辑,点击测算后自动更新成本与报价。</div></div><div class="toolbar-actions"><button class="btn btn-default" onclick="addCostCalcRow()">+ 新增仓库行</button><button class="btn btn-default" onclick="saveCostCalcPlan()">保存方案</button><button class="btn btn-primary" onclick="calculateVoyageCosts()">测算成本</button></div></div>
|
||||
<div class="cost-fields">
|
||||
<div class="cost-field"><label>渠道</label><select id="cost-channel"><option>芝加哥普船海铁</option><option>纽约EXX海铁</option><option>洛杉矶普船海卡</option></select></div>
|
||||
<div class="cost-field"><label>计税方式</label><select id="cost-tax-mode" onchange="toggleCostTaxMode()"><option value="tax">包税(按重量)</option><option value="noTax">不包税(按立方)</option></select></div>
|
||||
<div class="cost-field"><label>船期</label><input id="cost-voyage-date" type="date" value="2026-08-13"/></div>
|
||||
<div class="cost-field"><label>海运费成本(USD)</label><input id="cost-ocean" type="number" value="8700" step="100"/></div>
|
||||
<div class="cost-field"><label>汇率</label><input id="cost-rate" type="number" value="6.9" step="0.01"/></div>
|
||||
<div class="cost-field"><label id="cost-markup-label">报价加成(元/kg)</label><input id="cost-markup" type="number" value="0.6" step="0.1"/></div>
|
||||
<div class="cost-field"><label>参考时效</label><input id="cost-time" value="船开后约35天"/></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="cost-table-wrap"><table class="cost-table"><thead><tr><th>操作</th><th>亚马逊仓</th><th>AMS+换单费</th><th>内陆</th><th>清关/报关费</th><th>关税</th><th>提柜费</th><th>拆柜费</th><th>托盘费</th><th>派送费</th><th>费用小计</th><th>海运费成本</th><th>总成本(USD)</th><th>汇率</th><th>折人民币</th><th id="cost-base-header">重量(kg)</th><th id="cost-unit-header">成本单价(元/kg)</th><th>建议报价</th></tr></thead><tbody id="tbody-voyage-cost"></tbody></table></div>
|
||||
<div class="cost-footnote">计算公式:费用小计 = AMS/换单 + 内陆 + 清关/报关 + 关税 + 提柜 + 拆柜 + 托盘 + 派送;总成本 = 小计 + 海运费;成本单价 = 总成本 × 汇率 ÷ 计费基数。</div>
|
||||
</div>
|
||||
</div></div>
|
||||
|
||||
<!-- ==================== SALES MANAGEMENT ==================== -->
|
||||
<div class="page" id="page-vehicle">
|
||||
<div class="breadcrumb">首页 <span class="sep">></span> 车辆管理 <span class="sep">></span> <strong>车辆列表</strong></div>
|
||||
<div class="table-card">
|
||||
<div class="table-toolbar"><span class="title">车辆列表</span><div class="toolbar-actions"><button class="btn btn-primary" onclick="openVehicleModal('add')">+ 添加车辆</button><button class="btn btn-default">导出Excel</button></div></div>
|
||||
<div class="search-row" style="flex-wrap:wrap;gap:8px">
|
||||
<input id="vehicle-kw" placeholder="车牌 / 司机 / 车型" style="width:220px"/>
|
||||
<select id="vehicle-status" style="width:140px"><option value="">全部状态</option><option>在役</option><option>外派中</option><option>维修中</option><option>停用</option><option>已归还</option></select>
|
||||
<button class="btn btn-sm btn-primary" onclick="vehicleSearch()">查询</button>
|
||||
<button class="btn btn-sm btn-default" onclick="vehicleReset()">重置</button>
|
||||
</div>
|
||||
<div style="display:flex;gap:0;border-bottom:2px solid #e5e7eb;margin:14px 0 12px;padding:0 4px">
|
||||
<div class="vehicle-stab active" onclick="switchVehicleTab(this,'own')" style="padding:10px 22px;font-size:14px;cursor:pointer;color:#1677ff;border-bottom:2px solid #1677ff;margin-bottom:-2px;font-weight:600">自有车辆</div>
|
||||
<div class="vehicle-stab" onclick="switchVehicleTab(this,'dispatch')" style="padding:10px 22px;font-size:14px;cursor:pointer;color:#374151;border-bottom:2px solid transparent;margin-bottom:-2px">外派车辆</div>
|
||||
</div>
|
||||
|
||||
<!-- 自有车辆 -->
|
||||
<div class="vehicle-panel" id="panel-vehicle-own">
|
||||
<div style="display:flex;gap:8px;align-items:center;margin:2px 2px 12px">
|
||||
<span style="font-size:13px;color:#666">区域:</span>
|
||||
<span class="vregion-pill" data-key="own" data-reg="all" onclick="setVehicleRegion('own','all',this)" style="cursor:pointer;padding:5px 16px;border-radius:16px;font-size:13px;color:#fa8c16;background:#fff7e6;border:1px solid #ffd591">全部</span>
|
||||
<span class="vregion-pill" data-key="own" data-reg="domestic" onclick="setVehicleRegion('own','domestic',this)" style="cursor:pointer;padding:5px 16px;border-radius:16px;font-size:13px;color:#374151;background:#fff;border:1px solid #e5e7eb">国内</span>
|
||||
<span class="vregion-pill" data-key="own" data-reg="overseas" onclick="setVehicleRegion('own','overseas',this)" style="cursor:pointer;padding:5px 16px;border-radius:16px;font-size:13px;color:#374151;background:#fff;border:1px solid #e5e7eb">国外</span>
|
||||
</div>
|
||||
<div style="overflow-x:auto"><table style="min-width:1140px;font-size:12px"><thead><tr style="background:#fafafa;color:#666">
|
||||
<th style="padding:9px 10px;text-align:left;white-space:nowrap">车牌</th>
|
||||
<th style="padding:9px 10px;text-align:left;white-space:nowrap">车型</th>
|
||||
<th style="padding:9px 10px;text-align:right;white-space:nowrap">油耗(L/100km)</th>
|
||||
<th style="padding:9px 10px;text-align:right;white-space:nowrap">当前公里码(km)</th>
|
||||
<th style="padding:9px 10px;text-align:left;white-space:nowrap">司机</th>
|
||||
<th style="padding:9px 10px;text-align:left;white-space:nowrap">联系电话</th>
|
||||
<th style="padding:9px 10px;text-align:center;white-space:nowrap">状态</th>
|
||||
<th style="padding:9px 10px;text-align:center;white-space:nowrap">区域</th>
|
||||
<th style="padding:9px 10px;text-align:center;white-space:nowrap;width:160px">操作</th>
|
||||
</tr></thead><tbody id="tbody-vehicle-own"></tbody></table></div>
|
||||
</div>
|
||||
|
||||
<!-- 外派车辆 -->
|
||||
<div class="vehicle-panel" id="panel-vehicle-dispatch" style="display:none">
|
||||
<div style="display:flex;gap:8px;align-items:center;margin:2px 2px 12px">
|
||||
<span style="font-size:13px;color:#666">区域:</span>
|
||||
<span class="vregion-pill" data-key="dispatch" data-reg="all" onclick="setVehicleRegion('dispatch','all',this)" style="cursor:pointer;padding:5px 16px;border-radius:16px;font-size:13px;color:#fa8c16;background:#fff7e6;border:1px solid #ffd591">全部</span>
|
||||
<span class="vregion-pill" data-key="dispatch" data-reg="domestic" onclick="setVehicleRegion('dispatch','domestic',this)" style="cursor:pointer;padding:5px 16px;border-radius:16px;font-size:13px;color:#374151;background:#fff;border:1px solid #e5e7eb">国内</span>
|
||||
<span class="vregion-pill" data-key="dispatch" data-reg="overseas" onclick="setVehicleRegion('dispatch','overseas',this)" style="cursor:pointer;padding:5px 16px;border-radius:16px;font-size:13px;color:#374151;background:#fff;border:1px solid #e5e7eb">国外</span>
|
||||
</div>
|
||||
<div style="overflow-x:auto"><table style="min-width:1140px;font-size:12px"><thead><tr style="background:#fafafa;color:#666">
|
||||
<th style="padding:9px 10px;text-align:left;white-space:nowrap">车牌</th>
|
||||
<th style="padding:9px 10px;text-align:left;white-space:nowrap">车型</th>
|
||||
<th style="padding:9px 10px;text-align:right;white-space:nowrap">油耗(L/100km)</th>
|
||||
<th style="padding:9px 10px;text-align:right;white-space:nowrap">当前公里码(km)</th>
|
||||
<th style="padding:9px 10px;text-align:left;white-space:nowrap">外派单位</th>
|
||||
<th style="padding:9px 10px;text-align:left;white-space:nowrap">联系电话</th>
|
||||
<th style="padding:9px 10px;text-align:center;white-space:nowrap">状态</th>
|
||||
<th style="padding:9px 10px;text-align:center;white-space:nowrap">区域</th>
|
||||
<th style="padding:9px 10px;text-align:center;white-space:nowrap;width:160px">操作</th>
|
||||
</tr></thead><tbody id="tbody-vehicle-dispatch"></tbody></table></div>
|
||||
</div>
|
||||
|
||||
<div class="pagination"><span id="vehicle-total">共 0 条</span><button class="page-btn active">1</button></div>
|
||||
</div></div>
|
||||
|
||||
<!-- 车辆 新增/编辑 弹窗 -->
|
||||
<div class="modal-overlay" id="modal-vehicle-edit">
|
||||
<div class="modal" style="width:760px;max-width:95vw;max-height:88vh;overflow-y:auto">
|
||||
<div class="modal-header"><span id="vehicle-modal-title">添加车辆</span><span onclick="hideModal('modal-vehicle-edit')" style="cursor:pointer;font-size:20px">×</span></div>
|
||||
<div class="modal-body" style="padding:20px 24px">
|
||||
<div class="form-row">
|
||||
<div class="form-group"><label>车辆归属</label><select id="vehicle-m-type" style="height:40px"><option value="own">自有车辆</option><option value="dispatch">外派车辆</option></select></div>
|
||||
<div class="form-group"><label><span style="color:#ff4d4f">*</span> 车牌号</label><input id="vehicle-m-plate" placeholder="如 沪A·D8891"/></div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<div class="form-group"><label><span style="color:#ff4d4f">*</span> 车型</label><input id="vehicle-m-model" placeholder="如 福田欧马可 4.2米"/></div>
|
||||
<div class="form-group"><label><span style="color:#ff4d4f">*</span> 油耗(L/100km)</label><input id="vehicle-m-fuel" type="number" step="0.1" placeholder="如 13.5"/></div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<div class="form-group"><label><span style="color:#ff4d4f">*</span> 当前公里码(km)</label><input id="vehicle-m-mileage" type="number" placeholder="如 86520"/></div>
|
||||
<div class="form-group"><label>联系电话</label><input id="vehicle-m-phone" placeholder="司机/外派单位联系电话"/></div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<div class="form-group"><label>司机 / 外派单位</label><input id="vehicle-m-driver" placeholder="司机姓名 或 外派单位"/></div>
|
||||
<div class="form-group"><label>区域</label><select id="vehicle-m-region" style="height:40px"><option value="domestic">国内</option><option value="overseas">国外</option></select></div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<div class="form-group"><label>状态</label><select id="vehicle-m-status" style="height:40px"><option>在役</option><option>外派中</option><option>维修中</option><option>停用</option><option>已归还</option></select></div>
|
||||
<div class="form-group"><label>备注</label><input id="vehicle-m-note" placeholder="选填"/></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer" style="justify-content:flex-end;gap:10px;padding:14px 24px;border-top:1px solid #f0f0f0">
|
||||
<button class="btn btn-default" onclick="hideModal('modal-vehicle-edit')">取消</button>
|
||||
<button class="btn btn-primary" onclick="saveVehicle()">保存</button>
|
||||
</div>
|
||||
</div></div>
|
||||
|
||||
<!-- 车辆 查看 弹窗 -->
|
||||
<div class="modal-overlay" id="modal-vehicle-view">
|
||||
<div class="modal" style="width:600px;max-width:95vw;max-height:88vh;overflow-y:auto">
|
||||
<div class="modal-header"><span id="vehicle-view-title">车辆详情</span><span onclick="hideModal('modal-vehicle-view')" style="cursor:pointer;font-size:20px">×</span></div>
|
||||
<div class="modal-body" id="vehicle-view-body" style="padding:20px 24px"></div>
|
||||
<div class="modal-footer" style="justify-content:flex-end;padding:14px 24px;border-top:1px solid #f0f0f0"><button class="btn btn-default" onclick="hideModal('modal-vehicle-view')">关闭</button></div>
|
||||
</div></div>
|
||||
|
||||
<!-- ==================== FBA RETURN - 退货入库 ==================== -->
|
||||
@@ -0,0 +1,319 @@
|
||||
<!-- 模块:系统与消息。页面片段由 scripts/split-prototype.cjs 从完整原型拆出。 -->
|
||||
<div class="page" id="page-sys-users">
|
||||
<div class="table-card"><div class="table-toolbar"><span class="title">用户管理</span><div class="toolbar-actions"><button class="btn btn-primary" onclick="showModal('modal-user-add')">+ 新增用户</button></div></div>
|
||||
<table><thead><tr><th>用户名</th><th>姓名</th><th>所属租户</th><th>角色</th><th>状态</th><th>最后登录</th><th>操作</th></tr></thead><tbody id="tbody-users"></tbody></table></div></div>
|
||||
|
||||
<!-- ==================== SYSTEM ROLES ==================== -->
|
||||
<div class="page" id="page-sys-roles">
|
||||
<div class="table-card"><div class="table-toolbar"><span class="title">角色权限管理</span><div class="toolbar-actions"><button class="btn btn-primary" onclick="showRoleEdit(null)">+ 新增角色</button></div></div>
|
||||
<table><thead><tr><th>角色名称</th><th>角色编码</th><th>描述</th><th>用户数</th><th>数据权限</th><th>状态</th><th>操作</th></tr></thead><tbody id="tbody-roles"></tbody></table></div></div>
|
||||
|
||||
<!-- ==================== SYSTEM MENU PERMISSIONS ==================== -->
|
||||
<div class="page" id="page-sys-menu-permissions">
|
||||
<style>
|
||||
#page-sys-menu-permissions .smp-search-keyword{width:240px}
|
||||
#page-sys-menu-permissions .smp-filter{width:200px}
|
||||
#page-sys-menu-permissions .smp-list-toolbar{display:flex;align-items:center;justify-content:space-between;gap:16px;flex-wrap:wrap;padding:14px 18px;border-bottom:1px solid #e5eaf1;background:#fff}
|
||||
#page-sys-menu-permissions .smp-legend{display:flex;align-items:center;gap:14px;flex-wrap:wrap;color:#64748b;font-size:12px}
|
||||
#page-sys-menu-permissions .smp-legend-item{display:inline-flex;align-items:center;gap:5px}
|
||||
#page-sys-menu-permissions .smp-dot{width:7px;height:7px;border-radius:2px;background:#1677ff}
|
||||
#page-sys-menu-permissions .smp-dot.action{background:#0f9f8f}
|
||||
#page-sys-menu-permissions .smp-dot.api{background:#8b5cf6}
|
||||
#page-sys-menu-permissions .smp-tree-wrap{overflow-x:auto}
|
||||
#page-sys-menu-permissions table{min-width:980px}
|
||||
#page-sys-menu-permissions .smp-tree-cell{display:flex;align-items:center;gap:9px;min-width:250px}
|
||||
#page-sys-menu-permissions .smp-tree-cell.depth-1{padding-left:26px}
|
||||
#page-sys-menu-permissions .smp-tree-cell.depth-2{padding-left:54px}
|
||||
#page-sys-menu-permissions .smp-toggle{width:24px;height:24px;display:inline-flex;align-items:center;justify-content:center;border:0;background:transparent;color:#64748b;cursor:pointer;border-radius:5px;font-size:15px}
|
||||
#page-sys-menu-permissions .smp-toggle:hover{background:#eef4ff;color:#1677ff}
|
||||
#page-sys-menu-permissions .smp-toggle:focus-visible{outline:2px solid #1677ff;outline-offset:1px}
|
||||
#page-sys-menu-permissions .smp-toggle-spacer{width:24px;display:inline-block;flex:0 0 24px}
|
||||
#page-sys-menu-permissions .smp-node-icon{width:28px;height:28px;display:inline-flex;align-items:center;justify-content:center;border-radius:6px;background:#eef4ff;color:#1677ff;font-size:13px;font-weight:700;flex:0 0 28px}
|
||||
#page-sys-menu-permissions .smp-node-icon.menu{background:#f2f8f6;color:#0f8f7f}
|
||||
#page-sys-menu-permissions .smp-node-icon.action{background:#f6f0ff;color:#7c3aed}
|
||||
#page-sys-menu-permissions .smp-node-name{font-weight:600;color:#1f2937}
|
||||
#page-sys-menu-permissions .smp-node-meta{margin-top:2px;color:#94a3b8;font-size:11px}
|
||||
#page-sys-menu-permissions .smp-actions{display:flex;align-items:center;gap:8px;white-space:nowrap}
|
||||
#page-sys-menu-permissions .smp-action-link{border:0;background:transparent;color:#1677ff;padding:2px 0;cursor:pointer;font-size:12px}
|
||||
#page-sys-menu-permissions .smp-action-link:hover{text-decoration:underline}
|
||||
#page-sys-menu-permissions .smp-code,#page-sys-menu-permissions .smp-route{font-family:ui-monospace,SFMono-Regular,Consolas,monospace;color:#475569;font-size:11px}
|
||||
@media(max-width:768px){body:has(#page-sys-menu-permissions.active) .top-nav{padding:0 12px;gap:8px}body:has(#page-sys-menu-permissions.active) .top-nav .logo{min-width:0;flex:1;font-size:18px}body:has(#page-sys-menu-permissions.active) .top-nav .tenant-switch,body:has(#page-sys-menu-permissions.active) .top-nav .nav-right{display:none}#page-sys-menu-permissions .smp-search-keyword,#page-sys-menu-permissions .smp-filter{width:100%}#page-sys-menu-permissions .search-row .btn{flex:1}#page-sys-menu-permissions .smp-list-toolbar{align-items:flex-start}#page-sys-menu-permissions .smp-list-toolbar .toolbar-actions{width:100%;justify-content:flex-end}}
|
||||
</style>
|
||||
<div class="table-card">
|
||||
<div class="table-toolbar"><span class="title">菜单权限管理</span></div>
|
||||
<div class="search-row" aria-label="菜单权限查询">
|
||||
<input class="smp-search-keyword" id="smp-keyword" placeholder="权限名称、编码或路径" aria-label="权限名称、编码或路径"/>
|
||||
<select class="smp-filter" id="smp-type" aria-label="权限类型"><option value="">全部类型</option><option>目录</option><option>菜单</option><option>操作</option><option>接口</option></select>
|
||||
<select class="smp-filter" id="smp-status" aria-label="权限状态"><option value="">全部状态</option><option>启用</option><option>停用</option></select>
|
||||
<button class="btn btn-sm btn-primary" onclick="queryMenuPermissions()">查询</button>
|
||||
<button class="btn btn-sm btn-default" onclick="resetMenuPermissions()">重置</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="table-card">
|
||||
<div class="smp-list-toolbar">
|
||||
<div class="smp-legend"><span class="smp-legend-item"><i class="smp-dot"></i>目录 / 菜单</span><span class="smp-legend-item"><i class="smp-dot action"></i>操作</span><span class="smp-legend-item"><i class="smp-dot api"></i>接口预留</span><button class="smp-action-link" onclick="expandAllMenuPermissions()">展开全部</button><button class="smp-action-link" id="smp-operation-toggle" onclick="toggleMenuPermissionOperations()">收起操作权限</button></div>
|
||||
<div class="toolbar-actions"><button class="btn btn-primary" onclick="showMenuPermissionEdit()">+ 新增权限</button></div>
|
||||
</div>
|
||||
<div class="smp-tree-wrap"><table><thead><tr><th>操作</th><th>权限名称</th><th>权限编码</th><th>类型</th><th>路由 / 接口</th><th>排序</th><th>状态</th></tr></thead><tbody id="tbody-sys-menu-permissions"></tbody></table></div>
|
||||
<div class="pagination" id="pagination-sys-menu-permissions"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal-overlay" id="modal-sys-menu-permission">
|
||||
<div class="modal" style="max-width:720px">
|
||||
<div class="modal-header"><span id="smp-modal-title">新增权限</span><span onclick="hideModal('modal-sys-menu-permission')" style="cursor:pointer;font-size:20px">×</span></div>
|
||||
<div class="modal-body">
|
||||
<div class="form-row"><div class="form-group"><label>上级权限</label><select id="smp-parent"></select></div><div class="form-group"><label>权限类型 *</label><select id="smp-edit-type"><option>目录</option><option>菜单</option><option>操作</option><option>接口</option></select></div></div>
|
||||
<div class="form-row"><div class="form-group"><label>权限名称 *</label><input id="smp-edit-name" placeholder="请输入权限名称"/></div><div class="form-group"><label>权限编码 *</label><input id="smp-edit-code" placeholder="如:platform:customer:list"/></div></div>
|
||||
<div class="form-row"><div class="form-group"><label>路由 / 接口</label><input id="smp-edit-route" placeholder="如:/customers/list"/></div><div class="form-group"><label>排序</label><input id="smp-edit-sort" type="number" min="0" value="10"/></div></div>
|
||||
<div class="form-row"><div class="form-group"><label>状态</label><select id="smp-edit-status"><option>启用</option><option>停用</option></select></div></div>
|
||||
</div>
|
||||
<div class="modal-footer"><button class="btn btn-default" onclick="hideModal('modal-sys-menu-permission')">取消</button><button class="btn btn-primary" onclick="saveMenuPermission()">保存</button></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ==================== SYSTEM BRAND SETTINGS ==================== -->
|
||||
<div class="page" id="page-sys-brand">
|
||||
<div class="table-card"><div class="table-toolbar"><span class="title">品牌设置</span></div>
|
||||
<div style="padding:20px;max-width:800px">
|
||||
<div class="detail-section"><h4>品牌信息</h4>
|
||||
<div class="form-row">
|
||||
<div class="form-group"><label>品牌名称</label><input id="brand-name" placeholder="请输入平台品牌名称" style="max-width:360px"/></div>
|
||||
</div></div>
|
||||
<div class="detail-section"><h4>品牌Logo</h4>
|
||||
<div class="form-row" style="grid-template-columns:200px 1fr">
|
||||
<div class="form-group">
|
||||
<div id="brand-logo-preview" style="width:160px;height:160px;border:2px dashed #d9d9d9;border-radius:8px;display:flex;align-items:center;justify-content:center;background:#fafafa;cursor:pointer;overflow:hidden;position:relative" onclick="document.getElementById('brand-logo-input').click()">
|
||||
<span id="brand-logo-placeholder" style="font-size:40px;color:#bbb;pointer-events:none">📷</span>
|
||||
<img id="brand-logo-img" style="display:none;width:100%;height:100%;object-fit:contain;pointer-events:none" alt="Logo预览"/>
|
||||
</div>
|
||||
<input type="file" id="brand-logo-input" accept="image/*" onchange="handleBrandLogoUpload(event)" style="display:none"/>
|
||||
<div style="margin-top:8px;font-size:12px;color:#999">点击上传,支持 PNG/JPG/SVG<br>建议尺寸 200×200px</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="detail-section"><h4>主题配色</h4>
|
||||
<div class="form-row" style="grid-template-columns:1fr 1fr">
|
||||
<div class="form-group"><label>品牌主色</label><div style="display:flex;align-items:center;gap:8px"><input type="color" id="brand-primary" value="#1677ff" style="width:36px;height:36px;border:none;border-radius:4px;cursor:pointer;padding:0"/><input id="brand-primary-hex" value="#1677ff" style="width:100px" oninput="document.getElementById('brand-primary').value=this.value" placeholder="#1677ff"/></div></div>
|
||||
<div class="form-group"><label>辅助色</label><div style="display:flex;align-items:center;gap:8px"><input type="color" id="brand-secondary" value="#722ed1" style="width:36px;height:36px;border:none;border-radius:4px;cursor:pointer;padding:0"/><input id="brand-secondary-hex" value="#722ed1" style="width:100px" oninput="document.getElementById('brand-secondary').value=this.value" placeholder="#722ed1"/></div></div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<div class="form-group"><label>成功色</label><div style="display:flex;align-items:center;gap:8px"><input type="color" id="brand-success" value="#52c41a" style="width:36px;height:36px;border:none;border-radius:4px;cursor:pointer;padding:0"/><input id="brand-success-hex" value="#52c41a" style="width:100px" oninput="document.getElementById('brand-success').value=this.value" placeholder="#52c41a"/></div></div>
|
||||
<div class="form-group"><label>警告色</label><div style="display:flex;align-items:center;gap:8px"><input type="color" id="brand-warning" value="#fa8c16" style="width:36px;height:36px;border:none;border-radius:4px;cursor:pointer;padding:0"/><input id="brand-warning-hex" value="#fa8c16" style="width:100px" oninput="document.getElementById('brand-warning').value=this.value" placeholder="#fa8c16"/></div></div>
|
||||
</div></div>
|
||||
</div>
|
||||
</div></div>
|
||||
<div style="margin-top:20px;display:flex;gap:10px">
|
||||
<button class="btn btn-primary" onclick="saveBrandSettings()">💾 保存设置</button>
|
||||
<button class="btn btn-default" onclick="resetBrandSettings()">🔄 恢复默认</button>
|
||||
</div>
|
||||
</div></div></div>
|
||||
|
||||
<!-- ==================== SYSTEM TENANT MANAGEMENT ==================== -->
|
||||
<div class="page" id="page-sys-tenant">
|
||||
<div class="stat-row">
|
||||
<div class="stat-card"><div class="decorator"></div><div class="label">租户总数</div><div class="value">42</div><div class="trend" style="color:#52c41a">↑ 本月新增 5</div></div>
|
||||
<div class="stat-card"><div class="decorator"></div><div class="label">正常运营</div><div class="value">36</div><div class="trend">占比 85.7%</div></div>
|
||||
<div class="stat-card"><div class="decorator"></div><div class="label">待审核</div><div class="value">4</div><div class="trend" style="color:#fa8c16">需及时处理</div></div>
|
||||
<div class="stat-card"><div class="decorator"></div><div class="label">已停用</div><div class="value">2</div><div class="trend">占比 4.8%</div></div>
|
||||
</div>
|
||||
<div class="table-card"><div class="table-toolbar"><span class="title">租户管理</span><div class="toolbar-actions"><button class="btn btn-primary" onclick="showModal('modal-sys-tenant-add')">+ 新增租户</button><button class="btn btn-default">导出Excel</button></div></div>
|
||||
<div class="search-row">
|
||||
<select><option>全部状态</option><option>正常</option><option>待审核</option><option>停用</option></select>
|
||||
<select><option>全部套餐</option><option>基础版</option><option>专业版</option><option>企业版</option></select>
|
||||
<input placeholder="租户名称/信用代码" style="width:200px"/>
|
||||
<button class="btn btn-sm btn-primary">查询</button><button class="btn btn-sm btn-default">重置</button>
|
||||
</div>
|
||||
<table><thead><tr><th>租户ID</th><th>公司名称</th><th>统一社会信用代码</th><th>联系人</th><th>联系电话</th><th>套餐</th><th>用户数</th><th>状态</th><th>入驻时间</th><th>操作</th></tr></thead><tbody id="tbody-sys-tenant"></tbody></table>
|
||||
<div class="pagination"><span>共 42 条</span><button class="page-btn active">1</button><button class="page-btn">2</button><button class="page-btn">3</button><button class="page-btn">→</button></div></div></div>
|
||||
|
||||
<!-- ==================== SYS TENANT EDIT MODAL ==================== -->
|
||||
<div class="modal-overlay" id="modal-sys-tenant-edit">
|
||||
<div class="modal" style="max-width:700px">
|
||||
<div class="modal-header">编辑租户信息<span onclick="hideModal('modal-sys-tenant-edit')" style="cursor:pointer;font-size:20px">×</span></div>
|
||||
<div class="modal-body">
|
||||
<input type="hidden" id="ste-id"/>
|
||||
<div class="form-row">
|
||||
<div class="form-group"><label>租户ID</label><input id="ste-id-show" disabled style="background:#f5f5f5"/></div>
|
||||
<div class="form-group"><label>公司名称 *</label><input id="ste-name" placeholder="请输入公司全称"/></div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<div class="form-group"><label>统一社会信用代码</label><input id="ste-creditCode" placeholder="18位信用代码"/></div>
|
||||
<div class="form-group"><label>联系人 *</label><input id="ste-contact" placeholder="联系人姓名"/></div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<div class="form-group"><label>联系电话</label><input id="ste-phone" placeholder="联系电话"/></div>
|
||||
<div class="form-group"><label>邮箱</label><input id="ste-email" placeholder="企业邮箱"/></div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<div class="form-group" style="flex:1"><label>公司地址</label><input id="ste-address" placeholder="详细地址"/></div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<div class="form-group"><label>套餐</label><select id="ste-pkg"><option>基础版</option><option>专业版</option><option>企业版</option></select></div>
|
||||
<div class="form-group"><label>状态</label><select id="ste-status"><option value="正常">正常</option><option value="待审核">待审核</option><option value="停用">停用</option></select></div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<div class="form-group" style="flex:1"><label>备注</label><textarea id="ste-remark" rows="3" style="width:100%;resize:vertical;padding:8px;border:1px solid #dde1e7;border-radius:8px;font-size:13px" placeholder="备注信息(选填)"></textarea></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn btn-default" onclick="hideModal('modal-sys-tenant-edit')">取消</button>
|
||||
<button class="btn btn-primary" onclick="saveSysTenantEdit()">保存</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ==================== SYS TENANT MORE MODAL ==================== -->
|
||||
<div class="modal-overlay" id="modal-sys-tenant-more">
|
||||
<div class="modal" style="max-width:800px">
|
||||
<div class="modal-header">租户详情<span onclick="hideModal('modal-sys-tenant-more')" style="cursor:pointer;font-size:20px">×</span></div>
|
||||
<div class="modal-body" style="padding:0">
|
||||
<!-- Tab 导航 -->
|
||||
<div class="stm-tabs-wrap" style="display:flex;gap:0;border-bottom:1px solid #e8eaf0;padding:0 20px">
|
||||
<button class="stm-tab active" onclick="switchSysTenantMoreTab(this,'stm-panel-info')" style="padding:12px 20px;border:none;background:none;font-size:14px;cursor:pointer;border-bottom:2px solid transparent;color:#666;font-weight:500;transition:all .2s">基本信息</button>
|
||||
<button class="stm-tab" onclick="switchSysTenantMoreTab(this,'stm-panel-users')" style="padding:12px 20px;border:none;background:none;font-size:14px;cursor:pointer;border-bottom:2px solid transparent;color:#666;font-weight:500;transition:all .2s">用户列表</button>
|
||||
<button class="stm-tab" onclick="switchSysTenantMoreTab(this,'stm-panel-pkg')" style="padding:12px 20px;border:none;background:none;font-size:14px;cursor:pointer;border-bottom:2px solid transparent;color:#666;font-weight:500;transition:all .2s">套餐信息</button>
|
||||
<button class="stm-tab" onclick="switchSysTenantMoreTab(this,'stm-panel-log')" style="padding:12px 20px;border:none;background:none;font-size:14px;cursor:pointer;border-bottom:2px solid transparent;color:#666;font-weight:500;transition:all .2s">操作日志</button>
|
||||
</div>
|
||||
<style>
|
||||
#modal-sys-tenant-more .stm-tab.active{color:#1677ff!important;border-bottom-color:#1677ff!important}
|
||||
#modal-sys-tenant-more .stm-panel{padding:20px}
|
||||
#modal-sys-tenant-more .info-grid{display:grid;grid-template-columns:1fr 1fr;gap:14px 24px}
|
||||
#modal-sys-tenant-more .info-item{display:flex;flex-direction:column;gap:4px}
|
||||
#modal-sys-tenant-more .info-item .info-label{font-size:12px;color:#8c8c8c}
|
||||
#modal-sys-tenant-more .info-item .info-val{font-size:14px;color:#1f2937;font-weight:500}
|
||||
#modal-sys-tenant-more .stm-mini-table{width:100%;border-collapse:collapse;font-size:13px}
|
||||
#modal-sys-tenant-more .stm-mini-table th{background:#f8f9fb;padding:9px 12px;text-align:left;font-weight:600;color:#595959;border-bottom:1px solid #e8eaf0}
|
||||
#modal-sys-tenant-more .stm-mini-table td{padding:9px 12px;border-bottom:1px solid #f0f2f5;color:#1f2937}
|
||||
#modal-sys-tenant-more .stm-mini-table tr:last-child td{border-bottom:none}
|
||||
#modal-sys-tenant-more .pkg-card{border:1px solid #e8eaf0;border-radius:12px;padding:16px 20px;background:#fafbff}
|
||||
#modal-sys-tenant-more .pkg-row{display:flex;justify-content:space-between;align-items:center;padding:8px 0;border-bottom:1px solid #f0f2f5;font-size:13px}
|
||||
#modal-sys-tenant-more .pkg-row:last-child{border-bottom:none}
|
||||
#modal-sys-tenant-more .pkg-key{color:#8c8c8c}
|
||||
#modal-sys-tenant-more .pkg-val{font-weight:600;color:#1f2937}
|
||||
</style>
|
||||
|
||||
<!-- 基本信息 Panel -->
|
||||
<div id="stm-panel-info" class="stm-panel">
|
||||
<div class="info-grid">
|
||||
<div class="info-item"><span class="info-label">租户ID</span><span class="info-val" id="stm-id">—</span></div>
|
||||
<div class="info-item"><span class="info-label">公司名称</span><span class="info-val" id="stm-name">—</span></div>
|
||||
<div class="info-item"><span class="info-label">统一社会信用代码</span><span class="info-val" id="stm-creditCode">—</span></div>
|
||||
<div class="info-item"><span class="info-label">联系人</span><span class="info-val" id="stm-contact">—</span></div>
|
||||
<div class="info-item"><span class="info-label">联系电话</span><span class="info-val" id="stm-phone">—</span></div>
|
||||
<div class="info-item"><span class="info-label">邮箱</span><span class="info-val" id="stm-email">—</span></div>
|
||||
<div class="info-item" style="grid-column:1/-1"><span class="info-label">公司地址</span><span class="info-val" id="stm-address">—</span></div>
|
||||
<div class="info-item"><span class="info-label">当前套餐</span><span class="info-val" id="stm-pkg">—</span></div>
|
||||
<div class="info-item"><span class="info-label">用户数</span><span class="info-val" id="stm-users">—</span></div>
|
||||
<div class="info-item"><span class="info-label">状态</span><span class="info-val" id="stm-status">—</span></div>
|
||||
<div class="info-item"><span class="info-label">入驻时间</span><span class="info-val" id="stm-date">—</span></div>
|
||||
<div class="info-item" style="grid-column:1/-1"><span class="info-label">备注</span><span class="info-val" id="stm-remark">—</span></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 用户列表 Panel -->
|
||||
<div id="stm-panel-users" class="stm-panel" style="display:none">
|
||||
<div class="inbound-table-container">
|
||||
<table class="stm-mini-table">
|
||||
<thead><tr><th>用户名</th><th>姓名</th><th>角色</th><th>状态</th><th>最后登录</th></tr></thead>
|
||||
<tbody id="stm-tbody-users"></tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 套餐信息 Panel -->
|
||||
<div id="stm-panel-pkg" class="stm-panel" style="display:none">
|
||||
<div class="pkg-card">
|
||||
<div style="font-size:15px;font-weight:700;color:#1677ff;margin-bottom:14px">📦 当前套餐:<span id="stm-pkg-name">—</span></div>
|
||||
<div class="pkg-row"><span class="pkg-key">最大用户数</span><span class="pkg-val">20人</span></div>
|
||||
<div class="pkg-row"><span class="pkg-key">最大运单/月</span><span class="pkg-val">5,000单</span></div>
|
||||
<div class="pkg-row"><span class="pkg-key">存储空间</span><span class="pkg-val">50 GB</span></div>
|
||||
<div class="pkg-row"><span class="pkg-key">API调用/天</span><span class="pkg-val">10,000次</span></div>
|
||||
<div class="pkg-row"><span class="pkg-key">到期时间</span><span class="pkg-val">2027-06-14</span></div>
|
||||
<div class="pkg-row"><span class="pkg-key">月费</span><span class="pkg-val">¥2,980</span></div>
|
||||
<div class="pkg-row"><span class="pkg-key">年费</span><span class="pkg-val">¥29,800</span></div>
|
||||
<div class="pkg-row"><span class="pkg-key">续费状态</span><span class="pkg-val"><span class="tag tag-green">已续费</span></span></div>
|
||||
</div>
|
||||
<div style="margin-top:14px;display:flex;gap:8px">
|
||||
<button class="btn btn-primary btn-sm" onclick="showToast('升级套餐功能开发中','info')">升级套餐</button>
|
||||
<button class="btn btn-default btn-sm" onclick="showToast('续费功能开发中','info')">立即续费</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 操作日志 Panel -->
|
||||
<div id="stm-panel-log" class="stm-panel" style="display:none">
|
||||
<div class="inbound-table-container">
|
||||
<table class="stm-mini-table">
|
||||
<thead><tr><th>操作时间</th><th>操作内容</th><th>操作人</th><th>IP地址</th></tr></thead>
|
||||
<tbody id="stm-tbody-log"></tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn btn-default" onclick="hideModal('modal-sys-tenant-more')">关闭</button>
|
||||
<button class="btn btn-primary" onclick="hideModal('modal-sys-tenant-more');showSysTenantEdit(document.getElementById('stm-id').textContent)">编辑信息</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ==================== MESSAGE MANAGE ==================== -->
|
||||
<div class="page" id="page-msg-manage">
|
||||
<div class="table-card"><div class="table-toolbar"><span class="title">消息管理</span><div class="toolbar-actions"><button class="btn btn-primary" onclick="showMsgCreate()">+ 新建消息</button><button class="btn btn-default">导出Excel</button></div></div>
|
||||
<div class="search-row">
|
||||
<select><option>全部类型</option><option>系统通知</option><option>业务提醒</option><option>异常告警</option></select>
|
||||
<select><option>全部状态</option><option>已发送</option><option>草稿</option></select>
|
||||
<input placeholder="消息标题/内容" style="width:180px"/>
|
||||
<button class="btn btn-sm btn-primary">查询</button>
|
||||
</div>
|
||||
<table><thead><tr><th>消息ID</th><th>标题</th><th>类型</th><th>接收对象</th><th>发送时间</th><th>已读/总数</th><th>状态</th><th>操作</th></tr></thead><tbody id="tbody-msg-manage"></tbody></table>
|
||||
<div class="pagination"><span>共 156 条</span><button class="page-btn active">1</button><button class="page-btn">2</button><button class="page-btn">3</button><button class="page-btn">...</button><button class="page-btn">8</button></div></div></div>
|
||||
|
||||
<!-- ==================== MESSAGE TEMPLATE ==================== -->
|
||||
<div class="page" id="page-msg-template">
|
||||
<div class="table-card"><div class="table-toolbar"><span class="title">模板管理</span><div class="toolbar-actions"><button class="btn btn-primary" onclick="showMsgTemplateCreate()">+ 新增模板</button><button class="btn btn-default">导出</button><button class="btn btn-default">导入</button></div></div>
|
||||
<div class="search-row">
|
||||
<input placeholder="模板CODE" style="width:150px"/>
|
||||
<input placeholder="模板内容" style="width:200px"/>
|
||||
<button class="btn btn-sm btn-primary">查询</button><button class="btn btn-sm btn-default">重置</button>
|
||||
</div>
|
||||
<table><thead><tr><th>#</th><th>模板CODE</th><th>模板标题</th><th>模板内容</th><th>模板类型</th><th>操作</th></tr></thead><tbody id="tbody-msg-template"></tbody></table>
|
||||
<div class="pagination"><span>共 4 条</span><button class="page-btn active">1</button></div></div></div>
|
||||
|
||||
<!-- ==================== MY MESSAGE ==================== -->
|
||||
<div class="page" id="page-msg-my">
|
||||
<div class="table-card"><div class="table-toolbar"><span class="title">我的消息</span><div class="toolbar-actions"><button class="btn btn-default">全部标为已读</button><button class="btn btn-default">清空已读</button></div></div>
|
||||
<div class="search-row">
|
||||
<select><option>全部状态</option><option>未读</option><option>已读</option></select>
|
||||
<select><option>全部类型</option><option>系统通知</option><option>业务提醒</option><option>任务待办</option></select>
|
||||
<button class="btn btn-sm btn-primary">查询</button>
|
||||
</div>
|
||||
<table><thead><tr><th>消息标题</th><th>内容摘要</th><th>类型</th><th>发送时间</th><th>状态</th><th>操作</th></tr></thead><tbody id="tbody-msg-my"></tbody></table>
|
||||
<div class="pagination"><span>共 28 条</span><button class="page-btn active">1</button><button class="page-btn">2</button><button class="page-btn">3</button></div></div></div>
|
||||
|
||||
<!-- ==================== BOOKING LIST ==================== -->
|
||||
<div class="page" id="page-overseas-users">
|
||||
<div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:16px">
|
||||
<div style="font-size:16px;font-weight:700;color:#1e293b">用户列表</div>
|
||||
<button class="btn btn-primary" onclick="showModal('modal-overseas-user-add')">+ 新增用户</button>
|
||||
</div>
|
||||
<div class="table-card">
|
||||
<div style="display:flex;align-items:center;gap:10px;margin-bottom:12px;padding:0 4px">
|
||||
<select id="overseas-user-status-filter" onchange="renderOverseasUsers()" style="padding:6px 10px;border-radius:5px;border:1px solid #d9d9d9;outline:none;font-size:13px;background:#fff;color:#333">
|
||||
<option value="">全部状态</option><option value="正常">正常</option><option value="停用">停用</option>
|
||||
</select>
|
||||
<input id="overseas-user-search" placeholder="用户名" oninput="renderOverseasUsers()" style="flex:1;max-width:220px;padding:6px 10px;border-radius:5px;border:1px solid #d9d9d9;outline:none;font-size:13px"/>
|
||||
<button class="btn btn-primary" style="padding:6px 18px;border-radius:5px" onclick="renderOverseasUsers()">查询</button>
|
||||
</div>
|
||||
<table style="font-size:12px">
|
||||
<thead><tr>
|
||||
<th>用户ID</th><th>用户名</th><th>密码</th><th>注册时间</th><th>状态</th><th>操作</th>
|
||||
</tr></thead>
|
||||
<tbody id="tbody-overseas-users"></tbody>
|
||||
</table>
|
||||
<div style="display:flex;align-items:center;justify-content:space-between;padding:12px 4px 0;font-size:12px;color:#666">
|
||||
<span id="overseas-user-page-info"></span>
|
||||
<span style="cursor:pointer;color:#1890ff">1-7 共7条</span>
|
||||
</div>
|
||||
</div></div>
|
||||
|
||||
<!-- ==================== OVERSEAS PURCHASE LIST ==================== -->
|
||||
@@ -0,0 +1,354 @@
|
||||
<!-- 模块:历史订单与库存。页面片段由 scripts/split-prototype.cjs 从完整原型拆出。 -->
|
||||
<div class="page" id="page-order-list">
|
||||
<div class="table-card"><div class="table-toolbar"><span class="title">运单列表</span><div class="toolbar-actions"><button class="btn btn-primary" onclick="switchPage('order-create')">+ 创建运单</button><button class="btn btn-default">导出Excel</button><button class="btn btn-default">批量更新状态</button></div></div>
|
||||
<div class="search-row">
|
||||
<select><option>全部状态</option><option>草稿</option><option>已确认</option><option>已订舱</option><option>运输中</option><option>已完成</option></select>
|
||||
<select><option>全部运输方式</option><option>海运整箱FCL</option><option>海运拼箱LCL</option><option>空运</option><option>陆运</option></select>
|
||||
<select><option>全部进出口</option><option>出口</option><option>进口</option></select>
|
||||
<input placeholder="运单号/客户名" style="width:150px"/>
|
||||
<input type="date" style="width:130px"/>-<input type="date" style="width:130px"/>
|
||||
<button class="btn btn-sm btn-primary">查询</button>
|
||||
</div>
|
||||
<table><thead><tr><th>运单号</th><th>客户</th><th>运输方式</th><th>起运港→目的港</th><th>柜型/箱量</th><th>ETD</th><th>ETA</th><th>应收</th><th>状态</th><th>操作</th></tr></thead><tbody id="tbody-order"></tbody></table>
|
||||
<div class="pagination"><span>共 1,286 条</span><button class="page-btn active">1</button><button class="page-btn">2</button><button class="page-btn">3</button><button class="page-btn">...</button><button class="page-btn">65</button></div></div></div>
|
||||
|
||||
<!-- ==================== ORDER CREATE ==================== -->
|
||||
<div class="page" id="page-order-create">
|
||||
<div class="table-card"><div class="table-toolbar"><span class="title">创建运单</span><div class="toolbar-actions"><button class="btn btn-default" onclick="switchPage('order-list')">返回列表</button></div></div>
|
||||
<div style="padding:20px">
|
||||
<div class="detail-section"><h4>基本信息</h4>
|
||||
<div class="form-row">
|
||||
<div class="form-group"><label>客户 *</label><select><option>华远贸易有限公司</option><option>深圳速达供应链</option><option>广州恒通物流</option></select></div>
|
||||
<div class="form-group"><label>运输方式 *</label><select id="orderTransport" onchange="toggleContainerFields()"><option>海运整箱 FCL</option><option>海运拼箱 LCL</option><option>空运</option><option>陆运</option><option>多式联运</option></select></div>
|
||||
<div class="form-group"><label>贸易条款 Incoterms</label><select><option>FOB</option><option>CIF</option><option>EXW</option><option>DDP</option><option>DAP</option></select></div>
|
||||
<div class="form-group"><label>业务类型 *</label><select><option>出口</option><option>进口</option></select></div>
|
||||
<div class="form-group"><label>客户参考号</label><input placeholder="客户内部单号"/></div>
|
||||
<div class="form-group"><label>优先级</label><select><option>普通</option><option>紧急</option><option>加急</option></select></div>
|
||||
</div></div>
|
||||
<div class="detail-section"><h4>起运/目的信息</h4>
|
||||
<div class="form-row">
|
||||
<div class="form-group"><label>起运港 POL *</label><select><option>上海 SHANGHAI</option><option>宁波 NINGBO</option><option>深圳 SHENZHEN</option><option>青岛 QINGDAO</option><option>天津 TIANJIN</option></select></div>
|
||||
<div class="form-group"><label>目的港 POD *</label><select><option>洛杉矶 LOS ANGELES</option><option>长滩 LONG BEACH</option><option>纽约 NEW YORK</option><option>鹿特丹 ROTTERDAM</option><option>汉堡 HAMBURG</option></select></div>
|
||||
<div class="form-group"><label>预计出发 ETD</label><input type="date"/></div>
|
||||
<div class="form-group"><label>预计到达 ETA</label><input type="date"/></div>
|
||||
</div></div>
|
||||
<div class="detail-section"><h4>集装箱信息</h4>
|
||||
<div class="form-row" id="containerFields">
|
||||
<div class="form-group"><label>箱型 *</label><select><option>20GP</option><option>40GP</option><option>40HC</option><option>40NR</option><option>45HC</option></select></div>
|
||||
<div class="form-group"><label>箱量</label><input type="number" value="1" min="1" max="100"/></div>
|
||||
<div class="form-group"><label>柜号</label><input placeholder="如:MSCU1234567"/></div>
|
||||
<div class="form-group"><label>封条号</label><input placeholder="封条编号"/></div>
|
||||
</div></div>
|
||||
<div class="detail-section"><h4>发货方信息</h4>
|
||||
<div class="form-row">
|
||||
<div class="form-group"><label>发货方名称 *</label><input placeholder="Shipper Name"/></div>
|
||||
<div class="form-group"><label>联系人</label><input/></div>
|
||||
<div class="form-group"><label>电话</label><input/></div>
|
||||
<div class="form-group"><label>地址</label><input/></div>
|
||||
</div></div>
|
||||
<div class="detail-section"><h4>收货方信息</h4>
|
||||
<div class="form-row">
|
||||
<div class="form-group"><label>收货方名称 *</label><input placeholder="Consignee Name"/></div>
|
||||
<div class="form-group"><label>联系人</label><input/></div>
|
||||
<div class="form-group"><label>电话</label><input/></div>
|
||||
<div class="form-group"><label>地址</label><input/></div>
|
||||
</div></div>
|
||||
<div style="display:flex;gap:10px;justify-content:flex-end;margin-top:16px">
|
||||
<button class="btn btn-default" onclick="switchPage('order-list')">取消</button>
|
||||
<button class="btn btn-default">保存草稿</button>
|
||||
<button class="btn btn-primary" onclick="showToast('运单创建成功!运单号:BY20260601001','success');switchPage('order-list')">提交运单</button>
|
||||
</div>
|
||||
</div></div></div>
|
||||
|
||||
<!-- ==================== ORDER TRACKING ==================== -->
|
||||
<div class="page" id="page-order-tracking">
|
||||
<div class="table-card"><div class="table-toolbar"><span class="title">物流追踪 - 运单:BY20260528001</span></div>
|
||||
<div style="padding:20px">
|
||||
<div class="detail-section"><h4>运单概要</h4>
|
||||
<div class="info-grid">
|
||||
<div class="info-item"><span class="key">运单号:</span><span class="val">BY20260528001</span></div>
|
||||
<div class="info-item"><span class="key">运输方式:</span><span class="val">海运整箱 FCL</span></div>
|
||||
<div class="info-item"><span class="key">船名/航次:</span><span class="val">COSCO SHIPPING / 052E</span></div>
|
||||
<div class="info-item"><span class="key">起运港→目的港:</span><span class="val">上海 → 洛杉矶</span></div>
|
||||
<div class="info-item"><span class="key">ETD/ETA:</span><span class="val">2026-05-30 / 2026-06-18</span></div>
|
||||
<div class="info-item"><span class="key">当前状态:</span><span class="val"><span class="tag tag-blue">运输中</span></span></div>
|
||||
</div></div>
|
||||
<div class="detail-section"><h4>轨迹时间线</h4>
|
||||
<table><thead><tr><th>时间</th><th>状态</th><th>地点</th><th>描述</th></tr></thead><tbody>
|
||||
<tr><td>2026-05-30 14:30</td><td><span class="tag tag-blue">已装船</span></td><td>上海洋山港</td><td>货物已装船,COSCO SHIPPING 052E航次</td></tr>
|
||||
<tr><td>2026-05-29 10:00</td><td><span class="tag tag-green">已放行</span></td><td>上海海关</td><td>海关放行,通关编号:SH2026052900123</td></tr>
|
||||
<tr><td>2026-05-28 16:00</td><td><span class="tag tag-green">已申报</span></td><td>上海海关</td><td>电子申报提交成功</td></tr>
|
||||
<tr><td>2026-05-27 09:00</td><td><span class="tag tag-orange">已做柜</span></td><td>上海外高桥</td><td>装箱完成,柜号MSCU1234567,封条号SL987654</td></tr>
|
||||
<tr><td>2026-05-25 11:00</td><td><span class="tag tag-blue">已订舱</span></td><td>上海</td><td>获取S/O,船名COSCO SHIPPING,航次052E</td></tr>
|
||||
<tr><td>2026-05-24 15:00</td><td><span class="tag tag-green">已确认</span></td><td>-</td><td>客户确认运单</td></tr>
|
||||
</tbody></table></div></div></div></div>
|
||||
|
||||
<!-- ==================== ORDER BATCH ==================== -->
|
||||
<div class="page" id="page-order-batch">
|
||||
<div class="stat-row">
|
||||
<div class="stat-card"><div class="decorator"></div><div class="label">待处理运单</div><div class="value">156<span>票</span></div></div>
|
||||
<div class="stat-card"><div class="decorator"></div><div class="label">今日批量完成</div><div class="value">42<span>票</span></div></div>
|
||||
<div class="stat-card"><div class="decorator"></div><div class="label">成功率</div><div class="value">96.8<span>%</span></div></div>
|
||||
<div class="stat-card"><div class="decorator"></div><div class="label">平均处理时长</div><div class="value">3.2<span>分钟/票</span></div></div>
|
||||
</div>
|
||||
<div class="table-card"><div class="table-toolbar"><span class="title">批量操作列表</span><div class="toolbar-actions"><button class="btn btn-primary">+ 新建批量任务</button><button class="btn btn-default">导出Excel</button></div></div>
|
||||
<div class="search-row">
|
||||
<select><option>全部状态</option><option>处理中</option><option>已完成</option><option>失败</option></select>
|
||||
<select><option>全部类型</option><option>批量更新状态</option><option>批量导入</option><option>批量导出</option></select>
|
||||
<input placeholder="任务编号" style="width:150px"/>
|
||||
<button class="btn btn-sm btn-primary">查询</button>
|
||||
</div>
|
||||
<table><thead><tr><th>任务编号</th><th>任务类型</th><th>运单数量</th><th>创建人</th><th>创建时间</th><th>完成时间</th><th>成功/失败</th><th>状态</th><th>操作</th></tr></thead><tbody id="tbody-order-batch"></tbody></table>
|
||||
<div class="pagination"><span>共 38 条</span><button class="page-btn active">1</button><button class="page-btn">2</button></div></div></div>
|
||||
|
||||
<!-- ==================== ORDER EXCEPTION ==================== -->
|
||||
<div class="page" id="page-order-exception">
|
||||
<div class="stat-row">
|
||||
<div class="stat-card"><div class="decorator"></div><div class="label">未处理异常</div><div class="value">23<span>条</span></div></div>
|
||||
<div class="stat-card"><div class="decorator"></div><div class="label">今日已处理</div><div class="value">8<span>条</span></div></div>
|
||||
<div class="stat-card"><div class="decorator"></div><div class="label">平均响应时间</div><div class="value">1.5<span>小时</span></div></div>
|
||||
<div class="stat-card"><div class="decorator"></div><div class="label">解决率</div><div class="value">94.2<span>%</span></div></div>
|
||||
</div>
|
||||
<div class="table-card"><div class="table-toolbar"><span class="title">异常处理列表</span><div class="toolbar-actions"><button class="btn btn-primary">+ 新建异常</button><button class="btn btn-default">批量处理</button></div></div>
|
||||
<div class="search-row">
|
||||
<select><option>全部状态</option><option>待处理</option><option>处理中</option><option>已解决</option><option>已关闭</option></select>
|
||||
<select><option>全部类型</option><option>船期延误</option><option>海关查验</option><option>货物破损</option><option>单证异常</option><option>其他</option></select>
|
||||
<input placeholder="运单号" style="width:150px"/>
|
||||
<button class="btn btn-sm btn-primary">查询</button>
|
||||
</div>
|
||||
<table><thead><tr><th>异常编号</th><th>关联运单</th><th>客户</th><th>异常类型</th><th>描述</th><th>责任人</th><th>创建时间</th><th>状态</th><th>操作</th></tr></thead><tbody id="tbody-order-exception"></tbody></table>
|
||||
<div class="pagination"><span>共 128 条</span><button class="page-btn active">1</button><button class="page-btn">2</button><button class="page-btn">3</button><button class="page-btn">...</button><button class="page-btn">7</button></div></div></div>
|
||||
|
||||
<!-- ==================== ORDER LABEL ==================== -->
|
||||
<div class="page" id="page-order-label">
|
||||
<div class="stat-row">
|
||||
<div class="stat-card"><div class="decorator"></div><div class="label">待打印面单</div><div class="value">68<span>张</span></div></div>
|
||||
<div class="stat-card"><div class="decorator"></div><div class="label">今日已打印</div><div class="value">35<span>张</span></div></div>
|
||||
<div class="stat-card"><div class="decorator"></div><div class="label">打印机在线</div><div class="value">3<span>台</span></div></div>
|
||||
</div>
|
||||
<div class="table-card"><div class="table-toolbar"><span class="title">面单打印列表</span><div class="toolbar-actions"><button class="btn btn-primary">+ 批量打印</button><button class="btn btn-default">导出PDF</button></div></div>
|
||||
<div class="search-row">
|
||||
<select><option>全部状态</option><option>待打印</option><option>已打印</option><option>打印失败</option></select>
|
||||
<select><option>全部面单类型</option><option>海运提单</option><option>空运提单</option><option>箱单</option><option>报关单</option></select>
|
||||
<select><option>全部打印机</option><option>仓库A-Zebra</option><option>仓库B-Zebra</option><option>办公室-HP</option></select>
|
||||
<input placeholder="运单号" style="width:150px"/>
|
||||
<button class="btn btn-sm btn-primary">查询</button>
|
||||
</div>
|
||||
<table><thead><tr><th>面单编号</th><th>关联运单</th><th>面单类型</th><th>客户</th><th>件数/重量</th><th>创建时间</th><th>打印机</th><th>状态</th><th>操作</th></tr></thead><tbody id="tbody-order-label"></tbody></table>
|
||||
<div class="pagination"><span>共 215 条</span><button class="page-btn active">1</button><button class="page-btn">2</button><button class="page-btn">3</button><button class="page-btn">...</button><button class="page-btn">11</button></div></div></div>
|
||||
|
||||
<!-- ==================== ORDER BOOKING ==================== -->
|
||||
<div class="page" id="page-order-booking">
|
||||
<div class="stat-row">
|
||||
<div class="stat-card"><div class="decorator"></div><div class="label">待订舱运单</div><div class="value">42<span>票</span></div></div>
|
||||
<div class="stat-card"><div class="decorator"></div><div class="label">今日已完成</div><div class="value">18<span>票</span></div></div>
|
||||
<div class="stat-card"><div class="decorator"></div><div class="label">平均放舱时间</div><div class="value">4.6<span>小时</span></div></div>
|
||||
<div class="stat-card"><div class="decorator"></div><div class="label">订舱成功率</div><div class="value">97.5<span>%</span></div></div>
|
||||
</div>
|
||||
<div class="table-card"><div class="table-toolbar"><span class="title">订舱管理</span><div class="toolbar-actions"><button class="btn btn-primary">+ 新建订舱</button><button class="btn btn-default">批量订舱</button></div></div>
|
||||
<div class="search-row">
|
||||
<select><option>全部状态</option><option>待订舱</option><option>已订舱</option><option>已放舱</option><option>订舱失败</option></select>
|
||||
<select><option>全部船公司</option><option>COSCO</option><option>MAERSK</option><option>MSC</option><option>CMA CGM</option><option>EVERGREEN</option></select>
|
||||
<select><option>全部航线</option><option>美西</option><option>美东</option><option>欧洲</option><option>东南亚</option><option>中东</option></select>
|
||||
<input placeholder="S/O号" style="width:150px"/>
|
||||
<button class="btn btn-sm btn-primary">查询</button>
|
||||
</div>
|
||||
<table><thead><tr><th>订舱编号</th><th>关联运单</th><th>船公司</th><th>船名/航次</th><th>航线</th><th>箱型/箱量</th><th>S/O号</th><th>截关日期</th><th>状态</th><th>操作</th></tr></thead><tbody id="tbody-order-booking"></tbody></table>
|
||||
<div class="pagination"><span>共 326 条</span><button class="page-btn active">1</button><button class="page-btn">2</button><button class="page-btn">3</button><button class="page-btn">...</button><button class="page-btn">17</button></div></div></div>
|
||||
|
||||
<!-- ==================== FREIGHT RATE ==================== -->
|
||||
<div class="page" id="page-oms-order">
|
||||
<div class="stat-row" style="grid-template-columns:repeat(4,1fr)">
|
||||
<div class="stat-card"><div class="label">今日订单</div><div class="value">128<span>单</span></div><div class="trend"><span class="up">↑ 12%</span> 较昨日</div></div>
|
||||
<div class="stat-card"><div class="label">待处理</div><div class="value">23<span>单</span></div><div class="trend">需尽快处理</div></div>
|
||||
<div class="stat-card"><div class="label">已完成</div><div class="value">96<span>单</span></div><div class="trend">完成率 75%</div></div>
|
||||
<div class="stat-card"><div class="label">异常订单</div><div class="value" style="color:#f5222d">5<span>单</span></div><div class="trend">需人工介入</div></div>
|
||||
</div>
|
||||
<div class="table-card"><div class="table-toolbar"><span class="title">订单列表</span><div class="toolbar-actions">
|
||||
<select class="search-select"><option value="">全部状态</option><option>待审核</option><option>已审核</option><option>已分配</option><option>拣货中</option><option>已发货</option><option>已完成</option><option>已取消</option></select>
|
||||
<select class="search-select"><option value="">全部渠道</option><option>自营商城</option><option>天猫</option><option>京东</option><option>拼多多</option><option>一件代发</option></select>
|
||||
<button class="btn btn-primary" onclick="showToast('新建订单功能开发中','info')">+ 新建订单</button>
|
||||
<button class="btn btn-default">批量导入</button>
|
||||
<button class="btn btn-default">导出</button>
|
||||
</div></div>
|
||||
<table><thead><tr><th>订单编号</th><th>渠道来源</th><th>客户名称</th><th>SKU数</th><th>总件数</th><th>订单金额</th><th>收货地区</th><th>下单时间</th><th>状态</th><th>操作</th></tr></thead><tbody id="tbody-oms-order"></tbody></table>
|
||||
<div class="pagination"><span>共 10 条</span></div></div></div>
|
||||
|
||||
<!-- ==================== OMS REVIEW ==================== -->
|
||||
<div class="page" id="page-oms-review">
|
||||
<div class="stat-row" style="grid-template-columns:repeat(4,1fr)">
|
||||
<div class="stat-card"><div class="label">待审核</div><div class="value" style="color:#fa8c16">18<span>单</span></div><div class="trend">请尽快审核</div></div>
|
||||
<div class="stat-card"><div class="label">今日已审</div><div class="value">42<span>单</span></div><div class="trend"><span class="up">↑ 8%</span> 较昨日</div></div>
|
||||
<div class="stat-card"><div class="label">审核驳回</div><div class="value">3<span>单</span></div><div class="trend">需商家修改</div></div>
|
||||
<div class="stat-card"><div class="label">平均审核时效</div><div class="value">15<span>分钟</span></div><div class="trend">目标≤30分钟</div></div>
|
||||
</div>
|
||||
<div class="table-card"><div class="table-toolbar"><span class="title">待审核订单</span><div class="toolbar-actions">
|
||||
<button class="btn btn-primary" onclick="showToast('批量审核功能开发中','info')">✓ 批量审核通过</button>
|
||||
<button class="btn btn-default">批量驳回</button>
|
||||
</div></div>
|
||||
<table><thead><tr><th>订单编号</th><th>客户名称</th><th>渠道来源</th><th>SKU数</th><th>订单金额</th><th>风险标记</th><th>下单时间</th><th>操作</th></tr></thead><tbody id="tbody-oms-review"></tbody></table>
|
||||
<div class="pagination"><span>共 8 条</span></div></div></div>
|
||||
|
||||
<!-- ==================== OMS SPLIT ==================== -->
|
||||
|
||||
<!-- ==================== OMS ALLOCATE ==================== -->
|
||||
<div class="page" id="page-oms-allocate">
|
||||
<div class="stat-row" style="grid-template-columns:repeat(4,1fr)">
|
||||
<div class="stat-card"><div class="label">待分配</div><div class="value" style="color:#fa8c16">45<span>单</span></div><div class="trend">等待仓库分配</div></div>
|
||||
<div class="stat-card"><div class="label">已分配</div><div class="value">83<span>单</span></div><div class="trend">今日完成</div></div>
|
||||
<div class="stat-card"><div class="label">分配失败</div><div class="value" style="color:#f5222d">6<span>单</span></div><div class="trend">库存不足</div></div>
|
||||
<div class="stat-card"><div class="label">自动分配率</div><div class="value">92<span>%</span></div><div class="trend"><span class="up">↑ 3%</span></div></div>
|
||||
</div>
|
||||
<div class="table-card"><div class="table-toolbar"><span class="title">订单分配列表</span><div class="toolbar-actions">
|
||||
<select class="search-select"><option value="">全部状态</option><option>待分配</option><option>已分配</option><option>分配失败</option></select>
|
||||
<button class="btn btn-primary" onclick="showToast('批量分配功能开发中','info')">✓ 批量分配</button>
|
||||
<button class="btn btn-default">手动分配</button>
|
||||
<button class="btn btn-default">导出</button>
|
||||
</div></div>
|
||||
<table><thead><tr><th>订单编号</th><th>客户名称</th><th>SKU数</th><th>总件数</th><th>分配仓库</th><th>库存状态</th><th>分配规则</th><th>分配时间</th><th>状态</th><th>操作</th></tr></thead><tbody id="tbody-oms-allocate"></tbody></table>
|
||||
<div class="pagination"><span>共 8 条</span></div></div></div>
|
||||
|
||||
<!-- ==================== OMS TRACK ==================== -->
|
||||
<div class="page" id="page-oms-track">
|
||||
<div class="stat-row" style="grid-template-columns:repeat(4,1fr)">
|
||||
<div class="stat-card"><div class="label">在途订单</div><div class="value" style="color:#1677ff">256<span>单</span></div><div class="trend">实时跟踪中</div></div>
|
||||
<div class="stat-card"><div class="label">已签收</div><div class="value">1,382<span>单</span></div><div class="trend">本月累计</div></div>
|
||||
<div class="stat-card"><div class="label">配送异常</div><div class="value" style="color:#f5222d">8<span>单</span></div><div class="trend">需跟进处理</div></div>
|
||||
<div class="stat-card"><div class="label">平均时效</div><div class="value">2.8<span>天</span></div><div class="trend"><span class="up">↓ 0.3天</span> 优化中</div></div>
|
||||
</div>
|
||||
<div class="table-card"><div class="table-toolbar"><span class="title">订单跟踪</span><div class="toolbar-actions">
|
||||
<select class="search-select"><option value="">全部状态</option><option>待发货</option><option>已发货</option><option>运输中</option><option>派送中</option><option>已签收</option><option>异常</option></select>
|
||||
<input class="search-input" placeholder="搜索订单号/运单号" style="width:180px"/>
|
||||
<button class="btn btn-default">导出</button>
|
||||
</div></div>
|
||||
<table><thead><tr><th>订单编号</th><th>运单号</th><th>客户名称</th><th>收货地区</th><th>物流商</th><th>物流状态</th><th>最新轨迹</th><th>更新时间</th><th>操作</th></tr></thead><tbody id="tbody-oms-track"></tbody></table>
|
||||
<div class="pagination"><span>共 10 条</span></div></div></div>
|
||||
|
||||
<!-- ==================== OMS RETURN ==================== -->
|
||||
|
||||
<!-- ==================== INV PRODUCT ==================== -->
|
||||
<div class="page" id="page-inv-product">
|
||||
<div class="stat-row" style="grid-template-columns:repeat(4,1fr)">
|
||||
<div class="stat-card"><div class="label">总SKU数</div><div class="value">1,856<span>个</span></div><div class="trend"><span class="up">↑ 3.2%</span> 较上月</div></div>
|
||||
<div class="stat-card"><div class="label">总库存件数</div><div class="value">286,500<span>件</span></div><div class="trend"><span class="up">↑ 5.8%</span> 较上月</div></div>
|
||||
<div class="stat-card"><div class="label">可用库存</div><div class="value">245,800<span>件</span></div><div class="trend"><span class="up">↑ 4.1%</span> 较上月</div></div>
|
||||
<div class="stat-card"><div class="label">锁定库存</div><div class="value" style="color:#fa8c16">40,700<span>件</span></div><div class="trend">订单占用</div></div>
|
||||
</div>
|
||||
<div class="table-card"><div class="table-toolbar"><span class="title">产品库存明细</span><div class="toolbar-actions">
|
||||
<select class="search-select"><option value="">全部仓库</option><option>上海外高桥仓</option><option>深圳盐田仓</option><option>宁波北仑仓</option></select>
|
||||
<select class="search-select"><option value="">全部品类</option><option>电子产品</option><option>服装纺织</option><option>食品饮料</option><option>化工原料</option><option>家居建材</option></select>
|
||||
<button class="btn btn-primary">+ 新增SKU</button><button class="btn btn-default">导出Excel</button>
|
||||
</div></div>
|
||||
<table><thead><tr><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="tbody-inv-product"></tbody></table>
|
||||
<div class="pagination"><span>共 10 条</span></div></div></div>
|
||||
|
||||
<!-- ==================== INV BOX ==================== -->
|
||||
<div class="page" id="page-inv-box">
|
||||
<div class="stat-row" style="grid-template-columns:repeat(4,1fr)">
|
||||
<div class="stat-card"><div class="label">总箱数</div><div class="value">3,240<span>箱</span></div><div class="trend"><span class="up">↑ 2.1%</span> 较上月</div></div>
|
||||
<div class="stat-card"><div class="label">总SKU数</div><div class="value">1,856<span>个</span></div><div class="trend">覆盖全部SKU</div></div>
|
||||
<div class="stat-card"><div class="label">满箱率</div><div class="value">87.3<span>%</span></div><div class="trend"><span class="up">↑ 1.5%</span> 优化中</div></div>
|
||||
<div class="stat-card"><div class="label">空箱数</div><div class="value" style="color:#f5222d">412<span>箱</span></div><div class="trend">待清理</div></div>
|
||||
</div>
|
||||
<div class="table-card"><div class="table-toolbar"><span class="title">箱库存明细</span><div class="toolbar-actions">
|
||||
<select class="search-select"><option value="">全部仓库</option><option>上海外高桥仓</option><option>深圳盐田仓</option><option>宁波北仑仓</option></select>
|
||||
<select class="search-select"><option value="">全部状态</option><option>满箱</option><option>半箱</option><option>空箱</option></select>
|
||||
<button class="btn btn-default">导出Excel</button>
|
||||
</div></div>
|
||||
<table><thead><tr><th>箱号</th><th>仓库</th><th>SKU数</th><th>总件数</th><th>箱型</th><th>库位</th><th>状态</th><th>创建时间</th><th>操作</th></tr></thead><tbody id="tbody-inv-box"></tbody></table>
|
||||
<div class="pagination"><span>共 10 条</span></div></div></div>
|
||||
|
||||
<!-- ==================== INV RETURN ==================== -->
|
||||
<div class="page" id="page-inv-return">
|
||||
<div class="stat-row" style="grid-template-columns:repeat(4,1fr)">
|
||||
<div class="stat-card"><div class="label">退货总件数</div><div class="value">8,650<span>件</span></div><div class="trend"><span class="down">↓ 3.2%</span> 较上月</div></div>
|
||||
<div class="stat-card"><div class="label">待检验</div><div class="value" style="color:#fa8c16">320<span>件</span></div><div class="trend">质检中</div></div>
|
||||
<div class="stat-card"><div class="label">已入库</div><div class="value">6,180<span>件</span></div><div class="trend">可二次销售</div></div>
|
||||
<div class="stat-card"><div class="label">待处理</div><div class="value" style="color:#f5222d">2,150<span>件</span></div><div class="trend">待报废/返厂</div></div>
|
||||
</div>
|
||||
<div class="table-card"><div class="table-toolbar"><span class="title">退货库存明细</span><div class="toolbar-actions">
|
||||
<select class="search-select"><option value="">全部状态</option><option>待检验</option><option>已入库</option><option>待处理</option><option>已报废</option></select>
|
||||
<button class="btn btn-default">导出Excel</button>
|
||||
</div></div>
|
||||
<table><thead><tr><th>退货单号</th><th>原订单号</th><th>客户名称</th><th>SKU</th><th>数量</th><th>退货原因</th><th>状态</th><th>入库时间</th><th>操作</th></tr></thead><tbody id="tbody-inv-return"></tbody></table>
|
||||
<div class="pagination"><span>共 10 条</span></div></div></div>
|
||||
|
||||
<!-- ==================== INV COMPOSITE ==================== -->
|
||||
<div class="page" id="page-inv-composite">
|
||||
<div class="stat-row" style="grid-template-columns:repeat(4,1fr)">
|
||||
<div class="stat-card"><div class="label">总库存件数</div><div class="value">286,500<span>件</span></div><div class="trend"><span class="up">↑ 5.8%</span> 较上月</div></div>
|
||||
<div class="stat-card"><div class="label">产品库存</div><div class="value">245,800<span>件</span></div><div class="trend">占比 85.8%</div></div>
|
||||
<div class="stat-card"><div class="label">箱库存</div><div class="value">32,050<span>件</span></div><div class="trend">占比 11.2%</div></div>
|
||||
<div class="stat-card"><div class="label">退货库存</div><div class="value">8,650<span>件</span></div><div class="trend">占比 3.0%</div></div>
|
||||
</div>
|
||||
<div class="chart-row equal" style="margin-bottom:16px">
|
||||
<div class="chart-card"><div class="chart-header"><span class="chart-title">库存构成</span></div><div style="position:relative;height:260px"><canvas id="chartInvCompositePie"></canvas></div></div>
|
||||
<div class="chart-card"><div class="chart-header"><span class="chart-title">库存趋势</span></div><div style="position:relative;height:260px"><canvas id="chartInvCompositeTrend"></canvas></div></div>
|
||||
</div>
|
||||
<div class="table-card"><div class="table-toolbar"><span class="title">综合库存明细</span><div class="toolbar-actions">
|
||||
<select class="search-select"><option value="">全部仓库</option><option>上海外高桥仓</option><option>深圳盐田仓</option><option>宁波北仑仓</option></select>
|
||||
<button class="btn btn-default">导出Excel</button>
|
||||
</div></div>
|
||||
<table><thead><tr><th>仓库</th><th>产品库存</th><th>箱库存</th><th>退货库存</th><th>总库存</th><th>库存状态</th></tr></thead><tbody id="tbody-inv-composite"></tbody></table>
|
||||
<div class="pagination"><span>共 10 条</span><button class="page-btn active">1</button><button class="page-btn">2</button></div></div></div>
|
||||
|
||||
<!-- ==================== INV AGE PRODUCT ==================== -->
|
||||
<div class="page" id="page-inv-age-product">
|
||||
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:12px">
|
||||
<h2 style="font-size:18px;font-weight:600;margin:0">产品库龄分析</h2>
|
||||
<span style="color:#8c8c8c;font-size:13px">更新日期: 2026-06-04</span>
|
||||
</div>
|
||||
<div class="stat-row" style="grid-template-columns:repeat(4,1fr)">
|
||||
<div class="stat-card"><div class="label">平均库龄</div><div class="value">42<span>天</span></div><div class="trend">行业均值 38天</div></div>
|
||||
<div class="stat-card"><div class="label">0-30天</div><div class="value">1,120<span>SKU</span></div><div class="trend"><span class="up">↑ 5.2%</span> 健康</div></div>
|
||||
<div class="stat-card"><div class="label">31-90天</div><div class="value">520<span>SKU</span></div><div class="trend">需关注</div></div>
|
||||
<div class="stat-card"><div class="label">90天以上</div><div class="value" style="color:#f5222d">216<span>SKU</span></div><div class="trend"><span class="down">↓ 1.2%</span> 优化中</div></div>
|
||||
</div>
|
||||
<div class="table-card"><div class="table-toolbar"><span class="title">产品库龄明细</span><div class="toolbar-actions">
|
||||
<select class="search-select"><option value="">全部仓库</option><option>上海外高桥仓</option><option>深圳盐田仓</option><option>宁波北仑仓</option></select>
|
||||
<select class="search-select"><option value="">全部库龄段</option><option>0-30天</option><option>31-60天</option><option>61-90天</option><option>91-180天</option><option>180天以上</option></select>
|
||||
<button class="btn btn-default">导出Excel</button>
|
||||
</div></div>
|
||||
<table><thead><tr><th>SKU编码</th><th>品名</th><th>仓库</th><th>库存数量</th><th>入库日期</th><th>库龄(天)</th><th>库龄段</th><th>库存金额</th><th>状态</th></tr></thead><tbody id="tbody-inv-age-product"></tbody></table>
|
||||
<div class="pagination"><span>共 10 条</span></div></div></div>
|
||||
|
||||
<!-- ==================== INV AGE BOX ==================== -->
|
||||
<div class="page" id="page-inv-age-box">
|
||||
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:12px">
|
||||
<h2 style="font-size:18px;font-weight:600;margin:0">箱库龄分析</h2>
|
||||
<span style="color:#8c8c8c;font-size:13px">更新日期: 2026-06-04</span>
|
||||
</div>
|
||||
<div class="stat-row" style="grid-template-columns:repeat(4,1fr)">
|
||||
<div class="stat-card"><div class="label">平均箱龄</div><div class="value">28<span>天</span></div><div class="trend">行业均值 25天</div></div>
|
||||
<div class="stat-card"><div class="label">0-30天</div><div class="value">2,680<span>箱</span></div><div class="trend"><span class="up">↑ 3.1%</span> 健康</div></div>
|
||||
<div class="stat-card"><div class="label">31-90天</div><div class="value">420<span>箱</span></div><div class="trend">需关注</div></div>
|
||||
<div class="stat-card"><div class="label">90天以上</div><div class="value" style="color:#f5222d">140<span>箱</span></div><div class="trend"><span class="down">↓ 0.8%</span> 优化中</div></div>
|
||||
</div>
|
||||
<div class="table-card"><div class="table-toolbar"><span class="title">箱库龄明细</span><div class="toolbar-actions">
|
||||
<select class="search-select"><option value="">全部仓库</option><option>上海外高桥仓</option><option>深圳盐田仓</option><option>宁波北仑仓</option></select>
|
||||
<select class="search-select"><option value="">全部库龄段</option><option>0-30天</option><option>31-60天</option><option>61-90天</option><option>91-180天</option><option>180天以上</option></select>
|
||||
<button class="btn btn-default">导出Excel</button>
|
||||
</div></div>
|
||||
<table><thead><tr><th>箱号</th><th>仓库</th><th>SKU数</th><th>总件数</th><th>入库日期</th><th>箱龄(天)</th><th>库龄段</th><th>状态</th></tr></thead><tbody id="tbody-inv-age-box"></tbody></table>
|
||||
<div class="pagination"><span>共 10 条</span></div></div></div>
|
||||
|
||||
<!-- ==================== INV AGE RETURN ==================== -->
|
||||
<div class="page" id="page-inv-age-return">
|
||||
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:12px">
|
||||
<h2 style="font-size:18px;font-weight:600;margin:0">退货库龄分析</h2>
|
||||
<span style="color:#8c8c8c;font-size:13px">更新日期: 2026-06-04</span>
|
||||
</div>
|
||||
<div class="stat-row" style="grid-template-columns:repeat(4,1fr)">
|
||||
<div class="stat-card"><div class="label">平均退货库龄</div><div class="value">8<span>天</span></div><div class="trend">目标 <7天</div></div>
|
||||
<div class="stat-card"><div class="label">0-7天</div><div class="value">6,820<span>件</span></div><div class="trend"><span class="up">↑ 2.5%</span> 正常</div></div>
|
||||
<div class="stat-card"><div class="label">8-30天</div><div class="value">1,280<span>件</span></div><div class="trend">需加快处理</div></div>
|
||||
<div class="stat-card"><div class="label">30天以上</div><div class="value" style="color:#f5222d">550<span>件</span></div><div class="trend"><span class="down">↓ 0.5%</span> 积压</div></div>
|
||||
</div>
|
||||
<div class="table-card"><div class="table-toolbar"><span class="title">退货库龄明细</span><div class="toolbar-actions">
|
||||
<select class="search-select"><option value="">全部状态</option><option>待检验</option><option>已入库</option><option>待处理</option><option>已报废</option></select>
|
||||
<button class="btn btn-default">导出Excel</button>
|
||||
</div></div>
|
||||
<table><thead><tr><th>退货单号</th><th>客户名称</th><th>SKU</th><th>数量</th><th>退货原因</th><th>入库日期</th><th>库龄(天)</th><th>状态</th></tr></thead><tbody id="tbody-inv-age-return"></tbody></table>
|
||||
<div class="pagination"><span>共 10 条</span></div></div></div>
|
||||
|
||||
<!-- ==================== FINANCE AR ==================== -->
|
||||
@@ -0,0 +1,197 @@
|
||||
<!-- 模块:运价、报关与清关。页面片段由 scripts/split-prototype.cjs 从完整原型拆出。 -->
|
||||
<div class="page" id="page-freight-rate">
|
||||
<div class="table-card"><div class="table-toolbar"><span class="title">海运费管理</span><div class="toolbar-actions"><button class="btn btn-primary">+ 新增费率</button><button class="btn btn-default">批量导入</button></div></div>
|
||||
<div class="search-row">
|
||||
<select><option>全部起运港</option><option>上海</option><option>宁波</option><option>深圳</option></select>
|
||||
<select><option>全部目的港</option><option>洛杉矶</option><option>长滩</option><option>纽约</option><option>鹿特丹</option></select>
|
||||
<select><option>全部箱型</option><option>20GP</option><option>40GP</option><option>40HC</option></select>
|
||||
<button class="btn btn-sm btn-primary">查询</button>
|
||||
</div>
|
||||
<div class="inbound-table-container"><table><thead><tr><th>航线</th><th>船公司</th><th>箱型</th><th>海运费(USD)</th><th>BAF(USD)</th><th>THC(¥)</th><th>文件费(¥)</th><th>封条费(¥)</th><th>AMS(USD)</th><th>有效期</th><th>航程</th><th>状态</th><th>操作</th></tr></thead><tbody id="tbody-freight"></tbody></table></div>
|
||||
<div class="pagination"><span>共 156 条</span><button class="page-btn active">1</button><button class="page-btn">2</button><button class="page-btn">3</button><button class="page-btn">...</button><button class="page-btn">6</button></div></div></div>
|
||||
|
||||
<!-- ==================== FREIGHT QUOTE ==================== -->
|
||||
<div class="page" id="page-freight-quote">
|
||||
<div class="table-card"><div class="table-toolbar"><span class="title">询价报价</span><div class="toolbar-actions"><button class="btn btn-primary" onclick="showModal('modal-quote')">+ 新建询价</button></div></div>
|
||||
<table><thead><tr><th>询价编号</th><th>客户</th><th>航线</th><th>箱型/箱量</th><th>海运费(USD)</th><th>BAF(USD)</th><th>THC(¥)</th><th>报价总额(USD)</th><th>有效期</th><th>状态</th><th>操作</th></tr></thead><tbody id="tbody-quote"></tbody></table>
|
||||
<div class="pagination"><span>共 7 条</span></div>
|
||||
</div>
|
||||
<!-- 常见航线参考运价 -->
|
||||
<div class="table-card" style="margin-top:16px">
|
||||
<div class="table-toolbar"><span class="title">📊 各大航线市场参考运价(2026年6月)</span><div class="toolbar-actions"><button class="btn btn-sm btn-default">刷新运价</button></div></div>
|
||||
<div class="inbound-table-container"><table><thead><tr><th>航线区域</th><th>代表航线</th><th>20GP</th><th>40GP</th><th>40HC</th><th>LCL (USD/CBM)</th><th>航程</th><th>运价趋势</th></tr></thead><tbody>
|
||||
<tr><td><strong>美西</strong></td><td>上海→洛杉矶</td><td style="color:#1677ff;font-weight:600">$1,550-1,750</td><td style="color:#1677ff;font-weight:600">$2,650-2,950</td><td style="color:#1677ff;font-weight:600">$2,850-3,150</td><td>$185-220</td><td>13-16天</td><td><span class="tag tag-green">↓ 下降</span></td></tr>
|
||||
<tr><td><strong>美东</strong></td><td>上海→纽约</td><td style="color:#1677ff;font-weight:600">$2,150-2,350</td><td style="color:#1677ff;font-weight:600">$3,650-3,950</td><td style="color:#1677ff;font-weight:600">$3,950-4,250</td><td>$280-350</td><td>27-32天</td><td><span class="tag tag-green">↓ 下降</span></td></tr>
|
||||
<tr><td><strong>北欧</strong></td><td>上海→汉堡</td><td style="color:#1677ff;font-weight:600">$1,750-1,950</td><td style="color:#1677ff;font-weight:600">$3,150-3,450</td><td style="color:#1677ff;font-weight:600">$3,450-3,650</td><td>$240-290</td><td>28-32天</td><td><span class="tag tag-orange">→ 持平</span></td></tr>
|
||||
<tr><td><strong>地中海</strong></td><td>上海→比雷埃夫斯</td><td style="color:#1677ff;font-weight:600">$1,650-1,850</td><td style="color:#1677ff;font-weight:600">$2,850-3,050</td><td style="color:#1677ff;font-weight:600">$3,050-3,250</td><td>$220-270</td><td>22-26天</td><td><span class="tag tag-orange">→ 持平</span></td></tr>
|
||||
<tr><td><strong>中东</strong></td><td>上海→迪拜</td><td style="color:#1677ff;font-weight:600">$1,050-1,250</td><td style="color:#1677ff;font-weight:600">$1,550-1,750</td><td style="color:#1677ff;font-weight:600">$1,750-1,950</td><td>$120-155</td><td>16-20天</td><td><span class="tag tag-red">↑ 上涨</span></td></tr>
|
||||
<tr><td><strong>东南亚</strong></td><td>深圳→曼谷</td><td style="color:#1677ff;font-weight:600">$320-450</td><td style="color:#1677ff;font-weight:600">$580-750</td><td style="color:#1677ff;font-weight:600">$680-850</td><td>$45-65</td><td>4-7天</td><td><span class="tag tag-green">↓ 下降</span></td></tr>
|
||||
</tbody></table></div>
|
||||
</div></div>
|
||||
|
||||
<!-- ==================== FREIGHT AIR ==================== -->
|
||||
<div class="page" id="page-freight-air">
|
||||
<div class="stat-row">
|
||||
<div class="stat-card"><div class="decorator"></div><div class="label">本月空运单量</div><div class="value" id="air-monthly-count">--<span>票</span></div><div class="trend"><span class="up">↑ 12%</span> 较上月</div></div>
|
||||
<div class="stat-card"><div class="decorator"></div><div class="label">空运总收入</div><div class="value" id="air-monthly-revenue">--<span>万元</span></div><div class="trend"><span class="up">↑ 8%</span> 较上月</div></div>
|
||||
<div class="stat-card"><div class="decorator"></div><div class="label">平均单价</div><div class="value" id="air-avg-price">--<span>元/kg</span></div><div class="trend"><span class="down">↓ 3%</span> 较上月</div></div>
|
||||
<div class="stat-card"><div class="decorator"></div><div class="label">在途票数</div><div class="value" id="air-in-transit">--<span>票</span></div><div class="trend">正常</div></div>
|
||||
</div>
|
||||
<div class="table-card"><div class="table-toolbar"><span class="title">航空运费管理</span><div class="toolbar-actions"><button class="btn btn-primary">+ 新增</button><button class="btn btn-default">导入运价</button></div></div>
|
||||
<div class="search-row">
|
||||
<select><option>全部起运地</option><option>上海(PVG)</option><option>深圳(SZX)</option><option>北京(PEK)</option></select>
|
||||
<select><option>全部目的地</option><option>洛杉矶(LAX)</option><option>法兰克福(FRA)</option><option>东京(NRT)</option></select>
|
||||
<select><option>全部航线</option><option>美线</option><option>欧线</option><option>亚太</option></select>
|
||||
<button class="btn btn-sm btn-primary">查询</button>
|
||||
</div>
|
||||
<div class="inbound-table-container"><table><thead><tr><th>运价编号</th><th>航线</th><th>航空公司</th><th>起运地</th><th>目的地</th><th>+45kg</th><th>+100kg</th><th>+300kg</th><th>+500kg</th><th>+1000kg</th><th>燃油附加费</th><th>有效期</th><th>状态</th><th>操作</th></tr></thead><tbody id="tbody-freight-air"></tbody></table></div>
|
||||
<div class="pagination"><span>共 89 条</span><button class="page-btn active">1</button><button class="page-btn">2</button><button class="page-btn">3</button></div></div></div>
|
||||
|
||||
<!-- ==================== FREIGHT RAIL ==================== -->
|
||||
<div class="page" id="page-freight-rail">
|
||||
<div class="stat-row">
|
||||
<div class="stat-card"><div class="decorator"></div><div class="label">本月铁路单量</div><div class="value" id="rail-monthly-count">--<span>票</span></div><div class="trend"><span class="up">↑ 22%</span> 较上月</div></div>
|
||||
<div class="stat-card"><div class="decorator"></div><div class="label">铁路总收入</div><div class="value" id="rail-monthly-revenue">--<span>万元</span></div><div class="trend"><span class="up">↑ 15%</span> 较上月</div></div>
|
||||
<div class="stat-card"><div class="decorator"></div><div class="label">平均箱价</div><div class="value" id="rail-avg-price">--<span>USD/40HQ</span></div><div class="trend"><span class="up">↑ 5%</span> 较上月</div></div>
|
||||
<div class="stat-card"><div class="decorator"></div><div class="label">在途柜量</div><div class="value" id="rail-in-transit">--<span>柜</span></div><div class="trend">正常</div></div>
|
||||
</div>
|
||||
<div class="table-card"><div class="table-toolbar"><span class="title">铁路运费管理</span><div class="toolbar-actions"><button class="btn btn-primary">+ 新增</button><button class="btn btn-default">导入运价</button></div></div>
|
||||
<div class="search-row">
|
||||
<select><option>全部始发站</option><option>西安</option><option>成都</option><option>重庆</option><option>郑州</option><option>义乌</option></select>
|
||||
<select><option>全部终点站</option><option>马拉舍维奇</option><option>汉堡</option><option>杜伊斯堡</option><option>布达佩斯</option></select>
|
||||
<select><option>全部班列</option><option>中欧班列(长安号)</option><option>中欧班列(蓉欧)</option><option>中欧班列(渝新欧)</option></select>
|
||||
<button class="btn btn-sm btn-primary">查询</button>
|
||||
</div>
|
||||
<div class="inbound-table-container"><table><thead><tr><th>班列编号</th><th>线路</th><th>始发站</th><th>终点站</th><th>20GP</th><th>40GP</th><th>40HQ</th><th>LCL(USD/CBM)</th><th>全程时效</th><th>有效期</th><th>状态</th><th>操作</th></tr></thead><tbody id="tbody-freight-rail"></tbody></table></div>
|
||||
<div class="pagination"><span>共 42 条</span><button class="page-btn active">1</button><button class="page-btn">2</button></div></div></div>
|
||||
|
||||
<!-- ==================== FREIGHT RECONCILE ==================== -->
|
||||
<div class="page" id="page-freight-reconcile">
|
||||
<div class="table-card"><div class="table-toolbar"><span class="title">运费对账</span><div class="toolbar-actions"><button class="btn btn-primary">+ 新建对账单</button></div></div>
|
||||
<div class="search-row">
|
||||
<input placeholder="对账单号/客户名称" style="width:250px"/>
|
||||
<select><option>全部状态</option><option>待确认</option><option>已确认</option><option>有差异</option><option>已完成</option></select>
|
||||
<button class="btn btn-sm btn-primary">查询</button>
|
||||
</div>
|
||||
<div class="inbound-table-container"><table><thead><tr><th>对账单号</th><th>客户</th><th>账单期间</th><th>运费总额(USD)</th><th>附加费(USD)</th><th>应付合计(USD)</th><th>已付金额(USD)</th><th>差异(USD)</th><th>状态</th><th>操作</th></tr></thead><tbody id="tbody-freight-reconcile"></tbody></table></div>
|
||||
<div class="pagination"><span>共 23 条</span><button class="page-btn active">1</button><button class="page-btn">2</button></div></div></div>
|
||||
|
||||
<!-- ==================== FREIGHT REPORT ==================== -->
|
||||
<div class="page" id="page-freight-report">
|
||||
<div class="stat-row">
|
||||
<div class="stat-card"><div class="decorator"></div><div class="label">运费总收入</div><div class="value" id="fr-total-revenue">--<span>万元</span></div><div class="trend"><span class="up">↑ 10%</span> 较上月</div></div>
|
||||
<div class="stat-card"><div class="decorator"></div><div class="label">海运占比</div><div class="value" id="fr-sea-pct">--<span>%</span></div><div class="trend">较上月持平</div></div>
|
||||
<div class="stat-card"><div class="decorator"></div><div class="label">空运占比</div><div class="value" id="fr-air-pct">--<span>%</span></div><div class="trend"><span class="up">↑ 3%</span></div></div>
|
||||
<div class="stat-card"><div class="decorator"></div><div class="label">铁路占比</div><div class="value" id="fr-rail-pct">--<span>%</span></div><div class="trend"><span class="up">↑ 5%</span></div></div>
|
||||
</div>
|
||||
<div class="table-card" style="margin-bottom:16px"><div class="table-toolbar"><span class="title">运费趋势图</span></div>
|
||||
<div style="position:relative;height:280px"><canvas id="freightReportChart"></canvas></div></div>
|
||||
<div class="table-card"><div class="table-toolbar"><span class="title">各运输方式运费明细</span><div class="toolbar-actions"><button class="btn btn-sm btn-default">导出报表</button></div></div>
|
||||
<div class="inbound-table-container"><table><thead><tr><th>运输方式</th><th>本月票数</th><th>本月运费(USD)</th><th>环比增长</th><th>上月运费(USD)</th><th>去年同期(USD)</th><th>同比增长</th></tr></thead><tbody id="tbody-freight-report"></tbody></table></div>
|
||||
<div class="pagination"><span>共 3 条</span></div></div></div>
|
||||
|
||||
<!-- ==================== CUSTOMS HS ==================== -->
|
||||
<div class="page" id="page-customs-hs">
|
||||
<div class="table-card"><div class="table-toolbar"><span class="title">HS关税查询</span></div>
|
||||
<div class="search-row">
|
||||
<input placeholder="搜索HS编码或品名(如:6109.10 或 棉制T恤)" style="width:350px"/>
|
||||
<button class="btn btn-sm btn-primary">搜索</button>
|
||||
</div>
|
||||
<table><thead><tr><th>HS编码</th><th>中文品名</th><th>英文品名</th><th>法定单位</th><th>监管条件</th><th>出口退税率</th><th>操作</th></tr></thead><tbody id="tbody-hs"></tbody></table>
|
||||
<div class="pagination"><span>共 12,847 条</span><button class="page-btn active">1</button><button class="page-btn">2</button><button class="page-btn">3</button></div></div></div>
|
||||
|
||||
<!-- ==================== CUSTOMS ESTIMATE ==================== -->
|
||||
<div class="page" id="page-customs-estimate">
|
||||
<div class="table-card"><div class="table-toolbar"><span class="title">关税预估计算器</span></div>
|
||||
<div style="padding:20px">
|
||||
<div class="calc-card">
|
||||
<div class="form-row">
|
||||
<div class="form-group"><label>HS编码 *</label><input placeholder="如:6109.10.00" value="6109.10.00"/></div>
|
||||
<div class="form-group"><label>原产国 *</label><select><option>中国 China</option><option>越南 Vietnam</option><option>印度 India</option></select></div>
|
||||
<div class="form-group"><label>目的国 *</label><select><option>美国 United States</option><option>德国 Germany</option><option>日本 Japan</option></select></div>
|
||||
<div class="form-group"><label>申报数量</label><input type="number" value="1000" min="1"/></div>
|
||||
<div class="form-group"><label>单位</label><select><option>件 PCS</option><option>千克 KG</option><option>双 PRS</option></select></div>
|
||||
<div class="form-group"><label>单价(USD)</label><input type="number" value="12.50" step="0.01"/></div>
|
||||
<div class="form-group"><label>运费(USD)</label><input type="number" value="800" step="0.01"/></div>
|
||||
<div class="form-group"><label>保险费(USD)</label><input type="number" value="50" step="0.01"/></div>
|
||||
</div>
|
||||
<button class="btn btn-primary" onclick="calcDuty()">计算关税</button>
|
||||
<div class="calc-result" id="calcDutyResult" style="display:none">
|
||||
<h4 style="margin-bottom:10px">关税预估报告</h4>
|
||||
<div class="info-grid">
|
||||
<div class="info-item"><span class="key">HS编码:</span><span class="val">6109.10.00 - 棉制针织T恤</span></div>
|
||||
<div class="info-item"><span class="key">CIF总价:</span><span class="val">USD 13,350.00</span></div>
|
||||
<div class="info-item"><span class="key">关税税率:</span><span class="val">16.5% (最惠国)</span></div>
|
||||
<div class="info-item"><span class="key">关税额:</span><span class="val" style="color:#f5222d;font-weight:600">USD 2,202.75</span></div>
|
||||
<div class="info-item"><span class="key">增值税率:</span><span class="val">— (美国无VAT)</span></div>
|
||||
<div class="info-item"><span class="key">反倾销税:</span><span class="val">0% (不适用)</span></div>
|
||||
<div class="info-item" style="grid-column:1/-1"><span class="key">税费合计:</span><span class="total">USD 2,202.75 ≈ ¥15,970</span></div>
|
||||
</div></div>
|
||||
</div></div></div></div>
|
||||
|
||||
<!-- ==================== CUSTOMS PORT ==================== -->
|
||||
<div class="page" id="page-customs-port">
|
||||
<div class="stat-row" style="grid-template-columns:repeat(4,1fr)">
|
||||
<div class="stat-card"><div class="decorator"></div><div class="label">今日对接次数</div><div class="value">156<span>次</span></div><div class="trend"><span class="up">▲ 8%</span> 较昨日</div></div>
|
||||
<div class="stat-card"><div class="decorator"></div><div class="label">成功率</div><div class="value">99.2<span>%</span></div><div class="trend">状态正常</div></div>
|
||||
<div class="stat-card"><div class="decorator"></div><div class="label">待处理</div><div class="value">3<span>条</span></div><div class="trend">需要关注</div></div>
|
||||
<div class="stat-card"><div class="decorator"></div><div class="label">本月累计</div><div class="value">3,240<span>次</span></div></div>
|
||||
</div>
|
||||
<div class="table-card"><div class="table-toolbar"><span class="title">电子口岸对接日志</span><div class="toolbar-actions"><button class="btn btn-primary">+ 新建对接</button></div></div>
|
||||
<table><thead><tr><th>对接单号</th><th>口岸名称</th><th>业务类型</th><th>申报状态</th><th>回执状态</th><th>发起时间</th><th>耗时</th><th>操作</th></tr></thead><tbody id="tbody-customs-port"></tbody></table></div></div>
|
||||
|
||||
<!-- ==================== CUSTOMS TAXBILL ==================== -->
|
||||
<div class="page" id="page-customs-taxbill">
|
||||
<div class="stat-row" style="grid-template-columns:repeat(4,1fr)">
|
||||
<div class="stat-card"><div class="decorator"></div><div class="label">本月税单</div><div class="value">48<span>张</span></div></div>
|
||||
<div class="stat-card"><div class="decorator"></div><div class="label">已缴税</div><div class="value">42<span>张</span></div></div>
|
||||
<div class="stat-card"><div class="decorator"></div><div class="label">待缴税</div><div class="value">6<span>张</span></div></div>
|
||||
<div class="stat-card"><div class="decorator"></div><div class="label">税费总额</div><div class="value">$156,800</div></div>
|
||||
</div>
|
||||
<div class="table-card"><div class="table-toolbar"><span class="title">税单列表</span><div class="toolbar-actions"><button class="btn btn-primary">+ 录入税单</button><button class="btn btn-default">导出</button></div></div>
|
||||
<table><thead><tr><th>税单编号</th><th>报关单号</th><th>税种</th><th>税率</th><th>计税金额</th><th>税额</th><th>状态</th><th>缴款日期</th><th>操作</th></tr></thead><tbody id="tbody-customs-taxbill"></tbody></table></div></div>
|
||||
|
||||
<!-- ==================== CUSTOMS DECLARE ==================== -->
|
||||
<div class="page" id="page-customs-declare">
|
||||
<div class="stat-row" style="grid-template-columns:repeat(4,1fr)">
|
||||
<div class="stat-card"><div class="decorator"></div><div class="label">今日申报</div><div class="value">23<span>票</span></div><div class="trend"><span class="up">▲ 12%</span> 较昨日</div></div>
|
||||
<div class="stat-card"><div class="decorator"></div><div class="label">放行率</div><div class="value">96.5<span>%</span></div></div>
|
||||
<div class="stat-card"><div class="decorator"></div><div class="label">查验中</div><div class="value">4<span>票</span></div></div>
|
||||
<div class="stat-card"><div class="decorator"></div><div class="label">本月申报</div><div class="value">520<span>票</span></div></div>
|
||||
</div>
|
||||
<div class="table-card"><div class="table-toolbar"><span class="title">海关申报单列表</span><div class="toolbar-actions"><button class="btn btn-primary">+ 新建申报</button></div></div>
|
||||
<table><thead><tr><th>申报单号</th><th>报关类型</th><th>监管方式</th><th>口岸</th><th>商品项数</th><th>总货值</th><th>申报状态</th><th>海关回执</th><th>申报时间</th><th>操作</th></tr></thead><tbody id="tbody-customs-declare"></tbody></table></div></div>
|
||||
|
||||
<!-- ==================== CUSTOMS RATE ==================== -->
|
||||
<div class="page" id="page-customs-rate">
|
||||
<div class="stat-row" style="grid-template-columns:repeat(4,1fr)">
|
||||
<div class="stat-card"><div class="decorator"></div><div class="label">维护税率版本</div><div class="value">6<span>个</span></div></div>
|
||||
<div class="stat-card"><div class="decorator"></div><div class="label">当前生效</div><div class="value">2025Q2</div></div>
|
||||
<div class="stat-card"><div class="decorator"></div><div class="label">待生效</div><div class="value">2<span>个</span></div></div>
|
||||
<div class="stat-card"><div class="decorator"></div><div class="label">历史版本</div><div class="value">12<span>个</span></div></div>
|
||||
</div>
|
||||
<div class="table-card"><div class="table-toolbar"><span class="title">税率版本管理</span><div class="toolbar-actions"><button class="btn btn-primary">+ 新建版本</button></div></div>
|
||||
<table><thead><tr><th>版本编号</th><th>版本名称</th><th>适用国家</th><th>生效日期</th><th>到期日期</th><th>HS条目数</th><th>状态</th><th>创建人</th><th>操作</th></tr></thead><tbody id="tbody-customs-rate"></tbody></table></div></div>
|
||||
|
||||
<!-- ==================== CUSTOMS CURRENCY ==================== -->
|
||||
<div class="page" id="page-customs-currency">
|
||||
<div class="stat-row" style="grid-template-columns:repeat(4,1fr)">
|
||||
<div class="stat-card"><div class="decorator"></div><div class="label">支持币种</div><div class="value">28<span>种</span></div></div>
|
||||
<div class="stat-card"><div class="decorator"></div><div class="label">今日汇率更新</div><div class="value">08:30</div></div>
|
||||
<div class="stat-card"><div class="decorator"></div><div class="label">基准货币</div><div class="value">USD</div></div>
|
||||
<div class="stat-card"><div class="decorator"></div><div class="label">数据源</div><div class="value">中国银行</div></div>
|
||||
</div>
|
||||
<div class="table-card"><div class="table-toolbar"><span class="title">实时汇率表</span><div class="toolbar-actions"><button class="btn btn-default">刷新汇率</button></div></div>
|
||||
<table><thead><tr><th>币种</th><th>货币名称</th><th>买入价</th><th>卖出价</th><th>中间价</th><th>更新时间</th><th>操作</th></tr></thead><tbody id="tbody-customs-currency"></tbody></table></div></div>
|
||||
|
||||
<!-- ==================== WMS BASIC DATA ==================== -->
|
||||
<div class="page" id="page-clearance-list">
|
||||
<div class="table-card"><div class="table-toolbar"><span class="title">报关单列表</span><div class="toolbar-actions"><button class="btn btn-primary">+ 创建报关单</button></div></div>
|
||||
<table><thead><tr><th>报关单号</th><th>运单号</th><th>进出口</th><th>贸易方式</th><th>口岸</th><th>申报状态</th><th>海关放行</th><th>申报日期</th><th>操作</th></tr></thead><tbody id="tbody-clearance"></tbody></table></div></div>
|
||||
|
||||
<!-- ==================== CLEARANCE DOC ==================== -->
|
||||
<div class="page" id="page-clearance-doc">
|
||||
<div class="table-card"><div class="table-toolbar"><span class="title">单证管理</span><div class="toolbar-actions"><button class="btn btn-primary">+ 上传单证</button></div></div>
|
||||
<table><thead><tr><th>单证编号</th><th>关联报关单</th><th>单证类型</th><th>文件名</th><th>上传时间</th><th>状态</th><th>操作</th></tr></thead><tbody id="tbody-clearance-doc"></tbody></table></div></div>
|
||||
|
||||
<!-- ==================== OMS ORDER ==================== -->
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@@ -0,0 +1,251 @@
|
||||
|
||||
|
||||
<!-- ==================== 转BOL / 创建托盘BOL MODAL ==================== -->
|
||||
<div class="modal-overlay" id="modal-bol">
|
||||
<div class="modal" style="max-width:980px"><div class="modal-header">洛杉矶仓 + 创建托盘BOL<span onclick="hideModal('modal-bol')" style="cursor:pointer;font-size:20px">×</span></div>
|
||||
<div style="padding:20px 24px">
|
||||
<!-- 第一行 -->
|
||||
<div style="display:grid;grid-template-columns:1fr 1fr 1fr 1fr;gap:0 16px;margin-bottom:14px">
|
||||
<div><label style="font-size:12px;font-weight:600;color:#333;display:block;margin-bottom:4px">日期类型</label><select id="bol-dateType" style="width:100%;padding:9px 12px;border:1px solid #d9d9d9;border-radius:6px;font-size:13px;box-sizing:border-box;color:#999"><option value="">请选择</option><option>预约日期</option><option>实际日期</option></select></div>
|
||||
<div><label style="font-size:12px;font-weight:600;color:#333;display:block;margin-bottom:4px">开始时间</label><input id="bol-startDate" type="date" placeholder="请选择开始时间" style="width:100%;padding:9px 12px;border:1px solid #d9d9d9;border-radius:6px;font-size:13px;box-sizing:border-box"/></div>
|
||||
<div><label style="font-size:12px;font-weight:600;color:#333;display:block;margin-bottom:4px">结束时间</label><input id="bol-endDate" type="date" placeholder="请选择结束时间" style="width:100%;padding:9px 12px;border:1px solid #d9d9d9;border-radius:6px;font-size:13px;box-sizing:border-box"/></div>
|
||||
<div><label style="font-size:12px;font-weight:600;color:#333;display:block;margin-bottom:4px">目的仓类别</label><select id="bol-destCategory" style="width:100%;padding:9px 12px;border:1px solid #d9d9d9;border-radius:6px;font-size:13px;box-sizing:border-box;color:#999"><option value="">请选择</option><option>FBA仓库</option><option>海外仓</option><option>私人地址</option></select></div>
|
||||
</div>
|
||||
<!-- 第二行 -->
|
||||
<div style="display:grid;grid-template-columns:1fr 1fr 1fr 1fr;gap:0 16px;margin-bottom:14px">
|
||||
<div><label style="font-size:12px;font-weight:600;color:#333;display:block;margin-bottom:4px">FBA目的仓编号</label><select id="bol-fbaWh" style="width:100%;padding:9px 12px;border:1px solid #d9d9d9;border-radius:6px;font-size:13px;box-sizing:border-box;color:#999"><option value="">请选择</option><option>LAX9</option><option>LGB8</option><option>ONT9</option><option>SBD1</option><option>SJC7</option><option>SNA4</option></select></div>
|
||||
<div><label style="font-size:12px;font-weight:600;color:#333;display:block;margin-bottom:4px">托盘类型</label><select id="bol-palletType" style="width:100%;padding:9px 12px;border:1px solid #d9d9d9;border-radius:6px;font-size:13px;box-sizing:border-box;color:#999"><option value="">请选择</option><option>标准托盘</option><option>欧标托盘</option><option>定制托盘</option></select></div>
|
||||
<div><label style="font-size:12px;font-weight:600;color:#333;display:block;margin-bottom:4px">快递公司</label><select id="bol-expressCo" style="width:100%;padding:9px 12px;border:1px solid #d9d9d9;border-radius:6px;font-size:13px;box-sizing:border-box;color:#999"><option value="">请选择</option><option>UPS</option><option>FedEx</option><option>DHL</option></select></div>
|
||||
<div><label style="font-size:12px;font-weight:600;color:#333;display:block;margin-bottom:4px">入仓码</label><input id="bol-warehouseCode" placeholder="请输入入仓码" style="width:100%;padding:9px 12px;border:1px solid #d9d9d9;border-radius:6px;font-size:13px;box-sizing:border-box"/></div>
|
||||
</div>
|
||||
<!-- 第三行 -->
|
||||
<div style="display:grid;grid-template-columns:1fr 1fr 1fr 1fr;gap:0 16px;margin-bottom:14px">
|
||||
<div><label style="font-size:12px;font-weight:600;color:#333;display:block;margin-bottom:4px">出库单号</label><input id="bol-outboundNo" placeholder="请输入出库单号" style="width:100%;padding:9px 12px;border:1px solid #d9d9d9;border-radius:6px;font-size:13px;box-sizing:border-box"/></div>
|
||||
<div><label style="font-size:12px;font-weight:600;color:#333;display:block;margin-bottom:4px">托盘编号</label><input id="bol-palletNo" placeholder="请输入托盘编号" style="width:100%;padding:9px 12px;border:1px solid #d9d9d9;border-radius:6px;font-size:13px;box-sizing:border-box"/></div>
|
||||
<div><label style="font-size:12px;font-weight:600;color:#333;display:block;margin-bottom:4px">柜号</label><input id="bol-cabinetNo" placeholder="请输入柜号" style="width:100%;padding:9px 12px;border:1px solid #d9d9d9;border-radius:6px;font-size:13px;box-sizing:border-box"/></div>
|
||||
<div><label style="font-size:12px;font-weight:600;color:#333;display:block;margin-bottom:4px">集装箱号</label><input id="bol-containerNo" placeholder="请输入集装箱号" style="width:100%;padding:9px 12px;border:1px solid #d9d9d9;border-radius:6px;font-size:13px;box-sizing:border-box"/></div>
|
||||
</div>
|
||||
<!-- 第四行 -->
|
||||
<div style="display:grid;grid-template-columns:1fr 1fr auto;gap:0 16px;margin-bottom:14px;align-items:end">
|
||||
<div><label style="font-size:12px;font-weight:600;color:#333;display:block;margin-bottom:4px">预派送日期 <span style="color:#f5222d">*</span></label><input id="bol-deliveryDate" type="date" placeholder="请选择预派送日期" style="width:100%;padding:9px 12px;border:1px solid #d9d9d9;border-radius:6px;font-size:13px;box-sizing:border-box"/></div>
|
||||
<div><label style="font-size:12px;font-weight:600;color:#333;display:block;margin-bottom:4px">派送方式 <span style="color:#f5222d">*</span></label><select id="bol-deliveryMethod" style="width:100%;padding:9px 12px;border:1px solid #d9d9d9;border-radius:6px;font-size:13px;box-sizing:border-box;color:#999"><option value="">请选择</option><option>自提</option><option>配送</option><option>第三方物流</option></select></div>
|
||||
<div><button class="btn btn-primary" style="padding:9px 24px;border-radius:6px;font-size:13px" onclick="bolSearch()">🔍 搜索</button></div>
|
||||
</div>
|
||||
<!-- 分隔线 -->
|
||||
<div style="border-top:1px solid #e8e8e8;margin:18px 0"></div>
|
||||
<!-- 第五行 -->
|
||||
<div style="display:grid;grid-template-columns:1fr 1fr 1fr 1fr;gap:0 16px;margin-bottom:14px">
|
||||
<div><label style="font-size:12px;font-weight:600;color:#333;display:block;margin-bottom:4px">车队/司机名</label><input id="bol-driverName" placeholder="请输入车队/司机名" style="width:100%;padding:9px 12px;border:1px solid #d9d9d9;border-radius:6px;font-size:13px;box-sizing:border-box"/></div>
|
||||
<div><label style="font-size:12px;font-weight:600;color:#333;display:block;margin-bottom:4px">车队联系电话</label><input id="bol-driverPhone" placeholder="请输入车队联系电话" style="width:100%;padding:9px 12px;border:1px solid #d9d9d9;border-radius:6px;font-size:13px;box-sizing:border-box"/></div>
|
||||
<div><label style="font-size:12px;font-weight:600;color:#333;display:block;margin-bottom:4px">车队邮箱</label><input id="bol-driverEmail" placeholder="请输入车队邮箱" style="width:100%;padding:9px 12px;border:1px solid #d9d9d9;border-radius:6px;font-size:13px;box-sizing:border-box"/></div>
|
||||
<div><label style="font-size:12px;font-weight:600;color:#333;display:block;margin-bottom:4px">车辆类型</label><select id="bol-vehicleType" style="width:100%;padding:9px 12px;border:1px solid #d9d9d9;border-radius:6px;font-size:13px;box-sizing:border-box;color:#999"><option value="">请选择车辆类型</option><option>厢式货车</option><option>平板车</option><option>冷藏车</option><option>集装箱卡车</option></select></div>
|
||||
</div>
|
||||
<!-- 第六行 -->
|
||||
<div style="display:grid;grid-template-columns:1fr 1fr 1fr 1fr;gap:0 16px;margin-bottom:14px">
|
||||
<div><label style="font-size:12px;font-weight:600;color:#333;display:block;margin-bottom:4px">预约账号</label><input id="bol-bookAccount" placeholder="请输入预约账号" style="width:100%;padding:9px 12px;border:1px solid #d9d9d9;border-radius:6px;font-size:13px;box-sizing:border-box"/></div>
|
||||
<div><label style="font-size:12px;font-weight:600;color:#333;display:block;margin-bottom:4px">ISA号码</label><input id="bol-isaNo" placeholder="请输入ISA号码" style="width:100%;padding:9px 12px;border:1px solid #d9d9d9;border-radius:6px;font-size:13px;box-sizing:border-box"/></div>
|
||||
<div><label style="font-size:12px;font-weight:600;color:#333;display:block;margin-bottom:4px">车辆大小</label><input id="bol-vehicleSize" placeholder="请输入车辆大小" style="width:100%;padding:9px 12px;border:1px solid #d9d9d9;border-radius:6px;font-size:13px;box-sizing:border-box"/></div>
|
||||
<div><label style="font-size:12px;font-weight:600;color:#333;display:block;margin-bottom:4px">是否发送派送单</label><select id="bol-sendDispatch" style="width:100%;padding:9px 12px;border:1px solid #d9d9d9;border-radius:6px;font-size:13px;box-sizing:border-box;color:#999"><option value="">请输入是否发送派送单</option><option>是</option><option>否</option></select></div>
|
||||
</div>
|
||||
<!-- 订单明细 -->
|
||||
<div style="border-top:1px solid #e8e8e8;margin:18px 0 12px;padding-top:6px">
|
||||
<div style="font-size:13px;font-weight:700;color:#1e293b;margin-bottom:10px">订单明细 <span id="bol-detail-count" style="color:#999;font-weight:400;font-size:12px"></span></div>
|
||||
<div style="overflow-x:auto">
|
||||
<table style="width:100%;border-collapse:collapse;font-size:12px;min-width:760px">
|
||||
<thead><tr style="background:#fafafa;color:#666">
|
||||
<th style="padding:8px 10px;text-align:left;border-bottom:1px solid #eee;white-space:nowrap">出库单号</th>
|
||||
<th style="padding:8px 10px;text-align:right;border-bottom:1px solid #eee;white-space:nowrap">重量(kg)</th>
|
||||
<th style="padding:8px 10px;text-align:right;border-bottom:1px solid #eee;white-space:nowrap">托盘数量</th>
|
||||
<th style="padding:8px 10px;text-align:left;border-bottom:1px solid #eee;white-space:nowrap">目的地FBA</th>
|
||||
<th style="padding:8px 10px;text-align:right;border-bottom:1px solid #eee;white-space:nowrap">体积(m³)</th>
|
||||
<th style="padding:8px 10px;text-align:left;border-bottom:1px solid #eee;white-space:nowrap">货柜号</th>
|
||||
</tr></thead>
|
||||
<tbody id="bol-detail-body"></tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer"><button class="btn btn-default" onclick="hideModal('modal-bol')">取消</button><button class="btn btn-primary" onclick="saveBol()">确认提交</button></div></div></div>
|
||||
|
||||
<!-- ==================== 装柜清单 - 查看查询 MODAL ==================== -->
|
||||
<div class="modal-overlay" id="modal-mf-query">
|
||||
<div class="modal" style="max-width:720px"><div class="modal-header">装柜清单查询条件<span onclick="hideModal('modal-mf-query')" style="cursor:pointer;font-size:20px">×</span></div>
|
||||
<div style="padding:20px 24px">
|
||||
<div style="display:grid;grid-template-columns:1fr 1fr;gap:0 16px;margin-bottom:14px">
|
||||
<div><label style="font-size:12px;font-weight:600;color:#333;display:block;margin-bottom:4px">仓库</label><select style="width:100%;padding:9px 12px;border:1px solid #d9d9d9;border-radius:6px;font-size:13px"><option>全部</option><option>义乌仓</option><option>深圳仓</option></select></div>
|
||||
<div><label style="font-size:12px;font-weight:600;color:#333;display:block;margin-bottom:4px">装柜清单号</label><input placeholder="请输入" style="width:100%;padding:9px 12px;border:1px solid #d9d9d9;border-radius:6px;font-size:13px"/></div>
|
||||
</div>
|
||||
<div style="display:grid;grid-template-columns:1fr 1fr;gap:0 16px;margin-bottom:14px">
|
||||
<div><label style="font-size:12px;font-weight:600;color:#333;display:block;margin-bottom:4px">集装箱号</label><input placeholder="请输入" style="width:100%;padding:9px 12px;border:1px solid #d9d9d9;border-radius:6px;font-size:13px"/></div>
|
||||
<div><label style="font-size:12px;font-weight:600;color:#333;display:block;margin-bottom:4px">柜号</label><input placeholder="请输入" style="width:100%;padding:9px 12px;border:1px solid #d9d9d9;border-radius:6px;font-size:13px"/></div>
|
||||
</div>
|
||||
<div style="display:grid;grid-template-columns:1fr 1fr;gap:0 16px;margin-bottom:14px">
|
||||
<div><label style="font-size:12px;font-weight:600;color:#333;display:block;margin-bottom:4px">状态</label><select style="width:100%;padding:9px 12px;border:1px solid #d9d9d9;border-radius:6px;font-size:13px"><option>全部</option><option>国内报关成功</option><option>待拣货装柜</option><option>已装柜</option><option>已封箱</option></select></div>
|
||||
<div><label style="font-size:12px;font-weight:600;color:#333;display:block;margin-bottom:4px">创建人</label><input placeholder="请输入" style="width:100%;padding:9px 12px;border:1px solid #d9d9d9;border-radius:6px;font-size:13px"/></div>
|
||||
</div>
|
||||
<div style="display:grid;grid-template-columns:1fr 1fr;gap:0 16px;margin-bottom:14px">
|
||||
<div><label style="font-size:12px;font-weight:600;color:#333;display:block;margin-bottom:4px">创建日期起</label><input type="date" style="width:100%;padding:9px 12px;border:1px solid #d9d9d9;border-radius:6px;font-size:13px"/></div>
|
||||
<div><label style="font-size:12px;font-weight:600;color:#333;display:block;margin-bottom:4px">创建日期止</label><input type="date" style="width:100%;padding:9px 12px;border:1px solid #d9d9d9;border-radius:6px;font-size:13px"/></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer"><button class="btn btn-default" onclick="hideModal('modal-mf-query')">关闭</button><button class="btn btn-primary" onclick="hideModal('modal-mf-query');showToast('查询已应用','success')">应用筛选</button></div></div></div>
|
||||
|
||||
<!-- ==================== 海外仓库存 - 查看明细(进销存) MODAL ==================== -->
|
||||
<div class="modal-overlay" id="modal-stock-detail">
|
||||
<div class="modal" style="max-width:900px"><div class="modal-header">进销存明细 · <span id="stock-detail-title" style="font-size:15px"></span><span onclick="hideModal('modal-stock-detail')" style="cursor:pointer;font-size:20px">×</span></div>
|
||||
<div style="padding:18px 22px">
|
||||
<div style="overflow-x:auto">
|
||||
<table style="width:100%;border-collapse:collapse;font-size:12px;min-width:760px">
|
||||
<thead><tr style="background:#fafafa;color:#666">
|
||||
<th style="padding:8px 10px;text-align:left;white-space:nowrap">日期</th>
|
||||
<th style="padding:8px 10px;text-align:left;white-space:nowrap">类型</th>
|
||||
<th style="padding:8px 10px;text-align:left;white-space:nowrap">单据号</th>
|
||||
<th style="padding:8px 10px;text-align:left;white-space:nowrap">关联单</th>
|
||||
<th style="padding:8px 10px;text-align:right;white-space:nowrap">入库</th>
|
||||
<th style="padding:8px 10px;text-align:right;white-space:nowrap">出库</th>
|
||||
<th style="padding:8px 10px;text-align:right;white-space:nowrap">结存</th>
|
||||
<th style="padding:8px 10px;text-align:left;white-space:nowrap">操作人</th>
|
||||
<th style="padding:8px 10px;text-align:left;white-space:nowrap">备注</th>
|
||||
</tr></thead>
|
||||
<tbody id="stock-ioc-body"></tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer"><button class="btn btn-default" onclick="hideModal('modal-stock-detail')">关闭</button></div></div></div>
|
||||
|
||||
<script>
|
||||
(function(){
|
||||
var storageKey='dispatchSearchFieldOrder';
|
||||
var row=document.getElementById('dispatch-search-fields');
|
||||
var draggingItem=null;
|
||||
if(!row)return;
|
||||
|
||||
var defaultOrder=Array.prototype.map.call(row.children,function(item,index){
|
||||
item.dataset.defaultIndex=index;
|
||||
var handle=document.createElement('span');
|
||||
handle.className='dispatch-drag-handle';
|
||||
handle.draggable=true;
|
||||
handle.tabIndex=0;
|
||||
handle.setAttribute('role','button');
|
||||
handle.setAttribute('aria-label','拖动调整'+item.querySelector('label').textContent.replace(':','')+'的位置');
|
||||
handle.title='拖动调整顺序';
|
||||
handle.textContent='⠿';
|
||||
item.insertBefore(handle,item.firstChild);
|
||||
return item.dataset.searchKey;
|
||||
});
|
||||
|
||||
function getItems(){return Array.prototype.slice.call(row.querySelectorAll('.inbound-search-item'));}
|
||||
function saveOrder(){
|
||||
try{localStorage.setItem(storageKey,JSON.stringify(getItems().map(function(item){return item.dataset.searchKey;})));}catch(e){}
|
||||
}
|
||||
function applyOrder(order){
|
||||
if(!Array.isArray(order))return;
|
||||
var items={};
|
||||
getItems().forEach(function(item){items[item.dataset.searchKey]=item;});
|
||||
order.forEach(function(key){if(items[key]){row.appendChild(items[key]);delete items[key];}});
|
||||
defaultOrder.forEach(function(key){if(items[key])row.appendChild(items[key]);});
|
||||
}
|
||||
try{applyOrder(JSON.parse(localStorage.getItem(storageKey)||'null'));}catch(e){}
|
||||
|
||||
row.addEventListener('dragstart',function(event){
|
||||
var handle=event.target.closest('.dispatch-drag-handle');
|
||||
if(!handle)return;
|
||||
draggingItem=handle.closest('.inbound-search-item');
|
||||
draggingItem.classList.add('dispatch-dragging');
|
||||
event.dataTransfer.effectAllowed='move';
|
||||
event.dataTransfer.setData('text/plain',draggingItem.dataset.searchKey);
|
||||
});
|
||||
row.addEventListener('dragover',function(event){
|
||||
if(!draggingItem)return;
|
||||
event.preventDefault();
|
||||
event.dataTransfer.dropEffect='move';
|
||||
var target=event.target.closest('.inbound-search-item');
|
||||
getItems().forEach(function(item){item.classList.remove('dispatch-drag-over');});
|
||||
if(!target||target===draggingItem)return;
|
||||
target.classList.add('dispatch-drag-over');
|
||||
var rect=target.getBoundingClientRect();
|
||||
var insertBefore=event.clientX<rect.left+rect.width/2;
|
||||
row.insertBefore(draggingItem,insertBefore?target:target.nextSibling);
|
||||
});
|
||||
row.addEventListener('drop',function(event){
|
||||
if(!draggingItem)return;
|
||||
event.preventDefault();
|
||||
saveOrder();
|
||||
});
|
||||
row.addEventListener('dragend',function(){
|
||||
getItems().forEach(function(item){item.classList.remove('dispatch-dragging','dispatch-drag-over');});
|
||||
draggingItem=null;
|
||||
saveOrder();
|
||||
});
|
||||
row.addEventListener('keydown',function(event){
|
||||
if(!event.target.classList.contains('dispatch-drag-handle'))return;
|
||||
if(event.key!=='ArrowLeft'&&event.key!=='ArrowRight'&&event.key!=='ArrowUp'&&event.key!=='ArrowDown')return;
|
||||
event.preventDefault();
|
||||
var item=event.target.closest('.inbound-search-item');
|
||||
var items=getItems();
|
||||
var index=items.indexOf(item);
|
||||
var step=(event.key==='ArrowLeft'||event.key==='ArrowUp')?-1:1;
|
||||
var target=items[index+step];
|
||||
if(!target)return;
|
||||
row.insertBefore(item,step<0?target:target.nextSibling);
|
||||
event.target.focus();
|
||||
saveOrder();
|
||||
});
|
||||
|
||||
window.resetDispatchSearchOrder=function(){
|
||||
applyOrder(defaultOrder);
|
||||
try{localStorage.removeItem(storageKey);}catch(e){}
|
||||
if(typeof showToast==='function')showToast('查询项已恢复默认排列','success');
|
||||
};
|
||||
})();
|
||||
|
||||
(function(){
|
||||
var scroller=document.getElementById('dispatch-table-scroll');
|
||||
if(!scroller)return;
|
||||
var active=false;
|
||||
var moved=false;
|
||||
var suppressClick=false;
|
||||
var pointerId=null;
|
||||
var startX=0;
|
||||
var startScrollLeft=0;
|
||||
|
||||
function finishDrag(){
|
||||
if(!active)return;
|
||||
active=false;
|
||||
suppressClick=moved;
|
||||
window.setTimeout(function(){suppressClick=false;},0);
|
||||
scroller.classList.remove('dispatch-table-dragging');
|
||||
if(pointerId!==null&&scroller.hasPointerCapture(pointerId))scroller.releasePointerCapture(pointerId);
|
||||
pointerId=null;
|
||||
}
|
||||
|
||||
scroller.addEventListener('pointerdown',function(event){
|
||||
if(event.button!==0||event.target.closest('a,button,input,select,textarea,label'))return;
|
||||
active=true;
|
||||
moved=false;
|
||||
pointerId=event.pointerId;
|
||||
startX=event.clientX;
|
||||
startScrollLeft=scroller.scrollLeft;
|
||||
scroller.setPointerCapture(pointerId);
|
||||
});
|
||||
scroller.addEventListener('pointermove',function(event){
|
||||
if(!active||event.pointerId!==pointerId)return;
|
||||
var distance=event.clientX-startX;
|
||||
if(!moved&&Math.abs(distance)<5)return;
|
||||
moved=true;
|
||||
event.preventDefault();
|
||||
scroller.classList.add('dispatch-table-dragging');
|
||||
scroller.scrollLeft=startScrollLeft-distance;
|
||||
},{passive:false});
|
||||
scroller.addEventListener('pointerup',finishDrag);
|
||||
scroller.addEventListener('pointercancel',finishDrag);
|
||||
scroller.addEventListener('click',function(event){
|
||||
if(!suppressClick)return;
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
suppressClick=false;
|
||||
},true);
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,38 @@
|
||||
const fs = require('node:fs');
|
||||
const path = require('node:path');
|
||||
|
||||
const root = path.resolve(__dirname, '..');
|
||||
const sourceRoot = path.join(root, 'prototype-src');
|
||||
const manifest = JSON.parse(fs.readFileSync(path.join(sourceRoot, 'manifest.json'), 'utf8'));
|
||||
const pages = new Map();
|
||||
|
||||
for (const module of manifest.modules) {
|
||||
const content = fs.readFileSync(path.join(sourceRoot, module.file), 'utf8');
|
||||
const pattern = /<div\s+class="page(?:\s+active)?"\s+id="page-([^"]+)"/g;
|
||||
const starts = [];
|
||||
let match;
|
||||
while ((match = pattern.exec(content))) starts.push({ id: match[1], start: match.index });
|
||||
for (let index = 0; index < starts.length; index += 1) {
|
||||
pages.set(starts[index].id, content.slice(starts[index].start, starts[index + 1]?.start ?? content.length));
|
||||
}
|
||||
}
|
||||
|
||||
const missing = manifest.pageOrder.filter(id => !pages.has(id));
|
||||
const extra = [...pages.keys()].filter(id => !manifest.pageOrder.includes(id));
|
||||
if (missing.length || extra.length) {
|
||||
throw new Error(`页面清单不一致。缺失: ${missing.join(', ') || '无'};多余: ${extra.join(', ') || '无'}`);
|
||||
}
|
||||
|
||||
const output = [
|
||||
fs.readFileSync(path.join(sourceRoot, 'shell.html'), 'utf8'),
|
||||
manifest.pageOrder.map(id => pages.get(id)).join(''),
|
||||
'</main>',
|
||||
fs.readFileSync(path.join(sourceRoot, 'overlays.html'), 'utf8'),
|
||||
'<script>',
|
||||
fs.readFileSync(path.join(sourceRoot, 'app.js'), 'utf8'),
|
||||
'</script>',
|
||||
fs.readFileSync(path.join(sourceRoot, 'tail.html'), 'utf8'),
|
||||
].join('');
|
||||
|
||||
fs.writeFileSync(path.join(root, manifest.source), output, 'utf8');
|
||||
console.log(`已重建 ${manifest.source},包含 ${pages.size} 个页面。`);
|
||||
@@ -0,0 +1,82 @@
|
||||
const fs = require('node:fs');
|
||||
const path = require('node:path');
|
||||
|
||||
const root = path.resolve(__dirname, '..');
|
||||
const sourcePath = path.join(root, '货代SaaS平台原型-完整备份.html');
|
||||
const outputRoot = path.join(root, 'prototype-src');
|
||||
const modulesRoot = path.join(outputRoot, 'modules');
|
||||
const source = fs.readFileSync(sourcePath, 'utf8');
|
||||
|
||||
const mainOpen = source.indexOf('<main class="main-content" id="mainContent">');
|
||||
const mainContentStart = source.indexOf('\n', mainOpen) + 1;
|
||||
const mainClose = source.indexOf('</main>', mainContentStart);
|
||||
const firstScript = source.indexOf('<script>', mainClose);
|
||||
const firstScriptBody = firstScript + '<script>'.length;
|
||||
const firstScriptClose = source.indexOf('</script>', firstScriptBody);
|
||||
|
||||
if ([mainOpen, mainContentStart, mainClose, firstScript, firstScriptClose].some(index => index < 0)) {
|
||||
throw new Error('无法识别原型的 main 或 script 边界。');
|
||||
}
|
||||
|
||||
const moduleDefinitions = [
|
||||
['00-dashboard.html', '首页数据看板', id => id === 'dashboard'],
|
||||
['01-customers.html', '客户管理', id => id.startsWith('tenant-') || id === 'warehouse-tier-fee'],
|
||||
['02-domestic-warehouse.html', '国内仓', id => id.startsWith('inbound-') || id.startsWith('domestic-container-') || id === 'domestic-stock-management' || id === 'pallet-manage' || id === 'overseas-location' || id.startsWith('wh-')],
|
||||
['03-overseas-warehouse.html', '海外仓', id => id.startsWith('fba-') || id.startsWith('last-mile-') || id.startsWith('inventory-') || id.startsWith('warehouse-stock') || id.startsWith('overseas-inbound') || id.startsWith('overseas-outbound') || id.startsWith('overseas-relabel') || id.startsWith('overseas-stock') || id.startsWith('purchase-stock')],
|
||||
['04-overseas-delivery.html', '海外派送', id => id.startsWith('outbound-')],
|
||||
['05-suppliers.html', '供应商中心', id => id.startsWith('supplier-') || id === 'gen-express' || id === 'gen-counterparty' || id === 'ocean-channel'],
|
||||
['06-containers.html', '货柜管理', id => id.startsWith('booking-') || id.startsWith('truck-') || id.startsWith('ct-')],
|
||||
['07-overseas-business.html', '海外业务', id => id.startsWith('overseas-purchase') || id.startsWith('overseas-truck') || id.startsWith('overseas-looseboard') || id.startsWith('domestic-purchase') || id.startsWith('legacy-purchase')],
|
||||
['08-finance.html', '财务管理', id => id.startsWith('finance-') || id.startsWith('customer-account') || id.startsWith('customer-arap') || id.startsWith('customer-recon') || id.startsWith('settlement-') || id.startsWith('rpt-') || id === 'profit'],
|
||||
['09-sales.html', '销售管理', id => id.startsWith('gen-sales') || id === 'sales-commission'],
|
||||
['10-general.html', '通用资料', id => ['gen-product', 'gen-fee', 'gen-fba', 'gen-download', 'gen-voyage', 'gen-location', 'gen-pallet', 'gen-route', 'vehicle'].includes(id)],
|
||||
['11-system-messages.html', '系统与消息', id => id.startsWith('sys-') || id.startsWith('msg-') || id === 'overseas-users'],
|
||||
['12-legacy-orders.html', '历史订单与库存', id => id.startsWith('order-') || id.startsWith('oms-') || id.startsWith('inv-')],
|
||||
['13-freight-customs.html', '运价、报关与清关', id => id.startsWith('freight-') || id.startsWith('customs-') || id.startsWith('clearance-')],
|
||||
];
|
||||
|
||||
const mainContent = source.slice(mainContentStart, mainClose);
|
||||
const pagePattern = /<div\s+class="page(?:\s+active)?"\s+id="page-([^"]+)"/g;
|
||||
const starts = [];
|
||||
let match;
|
||||
while ((match = pagePattern.exec(mainContent))) starts.push({ id: match[1], start: match.index });
|
||||
|
||||
if (!starts.length) throw new Error('没有找到 page-* 页面。');
|
||||
|
||||
const chunks = starts.map((page, index) => ({
|
||||
id: page.id,
|
||||
content: mainContent.slice(page.start, starts[index + 1]?.start ?? mainContent.length),
|
||||
}));
|
||||
|
||||
const prelude = mainContent.slice(0, starts[0].start);
|
||||
const assignments = new Map(moduleDefinitions.map(([file]) => [file, []]));
|
||||
for (const chunk of chunks) {
|
||||
const owner = moduleDefinitions.find(([, , predicate]) => predicate(chunk.id));
|
||||
if (!owner) throw new Error(`页面 ${chunk.id} 未配置模块归属。`);
|
||||
assignments.get(owner[0]).push(chunk);
|
||||
}
|
||||
|
||||
fs.mkdirSync(modulesRoot, { recursive: true });
|
||||
for (const [file, title] of moduleDefinitions) {
|
||||
const pages = assignments.get(file);
|
||||
const header = `<!-- 模块:${title}。页面片段由 scripts/split-prototype.cjs 从完整原型拆出。 -->\n`;
|
||||
fs.writeFileSync(path.join(modulesRoot, file), header + pages.map(page => page.content).join(''), 'utf8');
|
||||
}
|
||||
|
||||
fs.writeFileSync(path.join(outputRoot, 'shell.html'), source.slice(0, mainContentStart) + prelude, 'utf8');
|
||||
fs.writeFileSync(path.join(outputRoot, 'overlays.html'), source.slice(mainClose + '</main>'.length, firstScript), 'utf8');
|
||||
fs.writeFileSync(path.join(outputRoot, 'app.js'), source.slice(firstScriptBody, firstScriptClose), 'utf8');
|
||||
fs.writeFileSync(path.join(outputRoot, 'tail.html'), source.slice(firstScriptClose + '</script>'.length), 'utf8');
|
||||
|
||||
const manifest = {
|
||||
source: 'index.html',
|
||||
pageOrder: chunks.map(page => page.id),
|
||||
modules: moduleDefinitions.map(([file, title]) => ({
|
||||
file: `modules/${file}`,
|
||||
title,
|
||||
pages: assignments.get(file).map(page => page.id),
|
||||
})),
|
||||
};
|
||||
fs.writeFileSync(path.join(outputRoot, 'manifest.json'), `${JSON.stringify(manifest, null, 2)}\n`, 'utf8');
|
||||
|
||||
console.log(`已拆分 ${chunks.length} 个页面到 ${moduleDefinitions.length} 个模块。`);
|
||||
@@ -0,0 +1,53 @@
|
||||
const fs = require('node:fs');
|
||||
const path = require('node:path');
|
||||
|
||||
const html = fs.readFileSync(path.resolve(__dirname, '..', '货代SaaS平台原型.html'), 'utf8');
|
||||
const failures = [];
|
||||
|
||||
function expect(pattern, label, source = html) {
|
||||
if (!pattern.test(source)) failures.push(`missing ${label}`);
|
||||
}
|
||||
|
||||
function expectAbsent(pattern, label, source = html) {
|
||||
if (pattern.test(source)) failures.push(`unexpected ${label}`);
|
||||
}
|
||||
|
||||
const pageStart = html.indexOf('<div class="page" id="page-fba-inbound-order">');
|
||||
const pageEnd = html.indexOf('<div class="modal-overlay" id="modal-fbio-appointment">', pageStart);
|
||||
const page = pageStart >= 0 && pageEnd > pageStart ? html.slice(pageStart, pageEnd) : '';
|
||||
|
||||
const searchMatch = page.match(/<div class="search-row fbio-search-row">([\s\S]*?)<div class="fbio-list-actions">/);
|
||||
const search = searchMatch ? searchMatch[1] : '';
|
||||
|
||||
expect(/<div class="search-row fbio-search-row">/, 'outbound-style search row', page);
|
||||
expectAbsent(/fbio-search-panel|fbio-search-grid|fbio-field|<label>/, 'standalone card, grid, or field labels', search || page.slice(0, page.indexOf('<div class="fbio-list-actions">')));
|
||||
expect(/fbio-inbound-end[\s\S]*?fbioSearch\(\)[\s\S]*?fbioReset\(\)/, 'actions after inbound date', search);
|
||||
expect(/class="btn btn-sm btn-primary"[^>]*onclick="fbioSearch\(\)"/, 'outbound-style search button', search);
|
||||
expect(/class="btn btn-sm btn-default"[^>]*onclick="fbioReset\(\)"/, 'outbound-style reset button', search);
|
||||
|
||||
for (const id of [
|
||||
'fbio-no',
|
||||
'fbio-warehouse-code',
|
||||
'fbio-status',
|
||||
'fbio-overseas-warehouse',
|
||||
'fbio-fba-warehouse',
|
||||
'fbio-appointment-filter-status',
|
||||
'fbio-schedule-status',
|
||||
'fbio-inbound-start',
|
||||
'fbio-inbound-end'
|
||||
]) {
|
||||
expect(new RegExp(`id="${id}"`), `query control ${id}`, search);
|
||||
}
|
||||
|
||||
expect(/id="fbio-no"[^>]*style="width:170px"/, 'compact inbound number width', search);
|
||||
expect(/id="fbio-status"[^>]*style="width:130px"/, 'compact status width', search);
|
||||
expect(/class="fbio-date-range"[\s\S]*?id="fbio-inbound-start"[^>]*style="width:150px"[\s\S]*?id="fbio-inbound-end"[^>]*style="width:150px"/, 'compact date range', search);
|
||||
expect(/#page-fba-inbound-order \.fbio-date-range\{[^}]*display:flex;[^}]*align-items:center;[^}]*gap:6px/, 'inline date range styling');
|
||||
|
||||
if (failures.length) {
|
||||
console.error('FBA_INBOUND_SEARCH_LAYOUT_CHECK_FAIL');
|
||||
failures.forEach(failure => console.error(`- ${failure}`));
|
||||
process.exitCode = 1;
|
||||
} else {
|
||||
console.log('FBA_INBOUND_SEARCH_LAYOUT_CHECK_PASS');
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const fs = require('node:fs');
|
||||
const path = require('node:path');
|
||||
const assert = require('node:assert/strict');
|
||||
|
||||
const htmlPath = path.resolve(__dirname, '..', '货代SaaS平台原型.html');
|
||||
const html = fs.readFileSync(htmlPath, 'utf8');
|
||||
const failures = [];
|
||||
|
||||
function expectMatch(pattern, label, source = html) {
|
||||
if (!pattern.test(source)) failures.push(`missing ${label}`);
|
||||
}
|
||||
|
||||
function functionSource(name, source = html) {
|
||||
const match = new RegExp(`function\\s+${name}\\s*\\([^)]*\\)\\s*\\{`).exec(source);
|
||||
if (!match) return '';
|
||||
const start = source.indexOf('{', match.index);
|
||||
let depth = 0;
|
||||
let quote = '';
|
||||
let escaped = false;
|
||||
for (let index = start; index < source.length; index += 1) {
|
||||
const char = source[index];
|
||||
if (quote) {
|
||||
if (escaped) escaped = false;
|
||||
else if (char === '\\') escaped = true;
|
||||
else if (char === quote) quote = '';
|
||||
continue;
|
||||
}
|
||||
if (char === "'" || char === '"' || char === '`') {
|
||||
quote = char;
|
||||
continue;
|
||||
}
|
||||
if (char === '{') depth += 1;
|
||||
if (char === '}' && --depth === 0) return source.slice(match.index, index + 1);
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
expectMatch(/onclick="openFbaRelabelCreate\(\)"/, '新增换标单真实入口');
|
||||
expectMatch(/id="modal-fba-relabel-form"/, '新增编辑共用弹框');
|
||||
for (const id of [
|
||||
'fbro-form-order-no',
|
||||
'fbro-form-related-order',
|
||||
'fbro-form-sku',
|
||||
'fbro-form-cn-name',
|
||||
'fbro-form-boxes',
|
||||
'fbro-form-label-req',
|
||||
'fbro-form-file',
|
||||
'fbro-form-status',
|
||||
'fbro-form-remark',
|
||||
]) {
|
||||
expectMatch(new RegExp(`id="${id}"`), `${id} 表单字段`);
|
||||
}
|
||||
expectMatch(/data-fbro-edit-order/, '列表编辑数据入口');
|
||||
expectMatch(/data-fbro-view-order/, '列表查看数据入口');
|
||||
|
||||
const sources = Object.fromEntries([
|
||||
'nextFbaRelabelOrderNo',
|
||||
'formatFbaRelabelFee',
|
||||
'buildFbaRelabelRecord',
|
||||
'openFbaRelabelCreate',
|
||||
'openFbaRelabelEdit',
|
||||
'saveFbaRelabelOrder',
|
||||
'openFbaRelabelOrderDetail',
|
||||
].map((name) => [name, functionSource(name)]));
|
||||
|
||||
for (const [name, source] of Object.entries(sources)) {
|
||||
if (!source) failures.push(`missing ${name} function`);
|
||||
}
|
||||
|
||||
if (sources.nextFbaRelabelOrderNo) {
|
||||
try {
|
||||
const nextFbaRelabelOrderNo = new Function(`return (${sources.nextFbaRelabelOrderNo});`)();
|
||||
assert.equal(nextFbaRelabelOrderNo('2026-08-12', [
|
||||
{ orderNo: 'FBRO20260812001' },
|
||||
{ orderNo: 'FBRO20260812009' },
|
||||
{ orderNo: 'FBRO20260811099' },
|
||||
]), 'FBRO20260812010');
|
||||
} catch (error) {
|
||||
failures.push(`换标单号生成行为失败:${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
if (sources.formatFbaRelabelFee) {
|
||||
try {
|
||||
const formatFbaRelabelFee = new Function(`return (${sources.formatFbaRelabelFee});`)();
|
||||
assert.equal(formatFbaRelabelFee(null), '-');
|
||||
assert.equal(formatFbaRelabelFee(''), '-');
|
||||
assert.equal(formatFbaRelabelFee('abc'), '-');
|
||||
assert.equal(formatFbaRelabelFee(0), '¥0.00');
|
||||
assert.equal(formatFbaRelabelFee(12.5), '¥12.50');
|
||||
} catch (error) {
|
||||
failures.push(`换标费用格式化行为失败:${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
if (sources.buildFbaRelabelRecord) {
|
||||
try {
|
||||
const buildFbaRelabelRecord = new Function(`${sources.nextFbaRelabelOrderNo}\nreturn (${sources.buildFbaRelabelRecord});`)();
|
||||
const form = {
|
||||
relatedOrderNo: 'RMA-NEW', sku: 'SKU-NEW', cnName: '新品', boxes: 3,
|
||||
labelReq: '加贴新标', file: 'new.pdf', status: '已完成', remark: '新建备注',
|
||||
};
|
||||
const orders = [{ orderNo: 'FBRO20260812001' }];
|
||||
const created = buildFbaRelabelRecord(form, null, '2026-08-12 19:00', orders);
|
||||
assert.equal(created.orderNo, 'FBRO20260812002');
|
||||
assert.equal(created.status, '待处理');
|
||||
assert.equal(created.createdAt, '2026-08-12 19:00');
|
||||
assert.equal(created.updatedAt, '2026-08-12 19:00');
|
||||
assert.deepEqual(created.fees, {});
|
||||
|
||||
const current = {
|
||||
orderNo: 'FBRO20260720001', lastMileNo: 'LMO-KEEP', createdAt: '2026-07-20 10:15',
|
||||
updatedAt: '2026-07-21 15:40', fees: { openBoxFee: 12 }, sku: 'OLD', status: '处理中',
|
||||
};
|
||||
const edited = buildFbaRelabelRecord({ ...form, status: '已完成' }, current, '2026-08-12 19:10', orders);
|
||||
assert.equal(edited.orderNo, current.orderNo);
|
||||
assert.equal(edited.lastMileNo, current.lastMileNo);
|
||||
assert.equal(edited.createdAt, current.createdAt);
|
||||
assert.deepEqual(edited.fees, current.fees);
|
||||
assert.equal(edited.sku, 'SKU-NEW');
|
||||
assert.equal(edited.status, '已完成');
|
||||
assert.equal(edited.updatedAt, '2026-08-12 19:10');
|
||||
} catch (error) {
|
||||
failures.push(`换标单构建行为失败:${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
if (sources.openFbaRelabelOrderDetail) {
|
||||
for (const label of ['费用明细', '开箱费', '挑货费', '换标费', '换箱唛标费']) {
|
||||
expectMatch(new RegExp(label), `详情${label}`, sources.openFbaRelabelOrderDetail);
|
||||
}
|
||||
expectMatch(/formatFbaRelabelFee/, '详情使用统一费用格式化', sources.openFbaRelabelOrderDetail);
|
||||
}
|
||||
|
||||
if (sources.saveFbaRelabelOrder) {
|
||||
expectMatch(/buildFbaRelabelRecord/, '保存调用记录构建函数', sources.saveFbaRelabelOrder);
|
||||
expectMatch(/Number\.isInteger/, '箱数正整数校验', sources.saveFbaRelabelOrder);
|
||||
expectMatch(/fbroApplyCurrentSearch/, '保存后保留当前筛选结果', sources.saveFbaRelabelOrder);
|
||||
}
|
||||
|
||||
if (failures.length) {
|
||||
console.error('FBA_RELABEL_CREATE_EDIT_FEES_CHECK_FAIL');
|
||||
failures.forEach((failure) => console.error(`- ${failure}`));
|
||||
process.exitCode = 1;
|
||||
} else {
|
||||
console.log('FBA_RELABEL_CREATE_EDIT_FEES_CHECK_PASS');
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const fs = require('node:fs');
|
||||
const path = require('node:path');
|
||||
|
||||
const html = fs.readFileSync(path.resolve(__dirname, '..', '货代SaaS平台原型.html'), 'utf8');
|
||||
const failures = [];
|
||||
|
||||
function expect(condition, message) {
|
||||
if (!condition) failures.push(message);
|
||||
}
|
||||
|
||||
function section(startMarker, endMarker) {
|
||||
const start = html.indexOf(startMarker);
|
||||
const end = html.indexOf(endMarker, start + startMarker.length);
|
||||
return start >= 0 && end > start ? html.slice(start, end) : '';
|
||||
}
|
||||
|
||||
function functionSource(name) {
|
||||
const start = html.indexOf(`function ${name}(`);
|
||||
if (start < 0) return '';
|
||||
const braceStart = html.indexOf('{', start);
|
||||
let depth = 0;
|
||||
let quote = '';
|
||||
let escaped = false;
|
||||
for (let index = braceStart; index < html.length; index += 1) {
|
||||
const char = html[index];
|
||||
if (quote) {
|
||||
if (escaped) escaped = false;
|
||||
else if (char === '\\') escaped = true;
|
||||
else if (char === quote) quote = '';
|
||||
continue;
|
||||
}
|
||||
if (char === "'" || char === '"' || char === '`') {
|
||||
quote = char;
|
||||
continue;
|
||||
}
|
||||
if (char === '{') depth += 1;
|
||||
if (char === '}' && --depth === 0) return html.slice(start, index + 1);
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
const listPage = section(
|
||||
'<div class="page" id="page-last-mile-orders">',
|
||||
'<!-- ==================== OVERSEAS WAREHOUSE - 尾程订单详情'
|
||||
);
|
||||
const detailPage = section(
|
||||
'<div class="page" id="page-last-mile-order-detail">',
|
||||
'<!-- 尾程订单 - 入库计划 -->'
|
||||
);
|
||||
const renderDetail = functionSource('renderLastMileOrderDetail');
|
||||
|
||||
expect(Boolean(detailPage), '缺少尾程订单详情页面');
|
||||
expect(Boolean(renderDetail), '缺少尾程订单详情渲染函数');
|
||||
expect(!/lmo-detail-actions/.test(detailPage), '详情页不应保留操作按钮容器');
|
||||
expect(!/lmo-detail-inbound-btn/.test(renderDetail), '详情渲染不应访问已删除的入库计划按钮');
|
||||
expect(!/lmo-detail-outbound-btn/.test(renderDetail), '详情渲染不应访问已删除的出库计划按钮');
|
||||
|
||||
[
|
||||
['openLastMileTransfer', '转仓'],
|
||||
['openLastMileInboundPlan', '入库计划'],
|
||||
['openLastMileConsolidate', '合托'],
|
||||
['openLastMileAppointment', 'FBA预约'],
|
||||
['openLastMileOutboundPlan', '出库计划']
|
||||
].forEach(([handler, label]) => {
|
||||
expect(!new RegExp(`onclick="${handler}\\(\\)"`).test(detailPage), `详情页不应显示${label}按钮`);
|
||||
});
|
||||
|
||||
expect(/openLastMileBatchTransfer\(\)/.test(listPage), '列表页应保留批量转仓入口');
|
||||
expect(/openLastMileBatchConsolidate\(\)/.test(listPage), '列表页应保留批量合托入口');
|
||||
|
||||
[
|
||||
'modal-lmo-transfer',
|
||||
'modal-lmo-inbound-plan',
|
||||
'modal-lmo-consolidate',
|
||||
'modal-lmo-fba-appointment',
|
||||
'modal-lmo-outbound-plan'
|
||||
].forEach(id => expect(html.includes(`id="${id}"`), `应保留操作弹框 ${id}`));
|
||||
|
||||
[
|
||||
'openLastMileTransfer',
|
||||
'openLastMileInboundPlan',
|
||||
'openLastMileConsolidate',
|
||||
'openLastMileAppointment',
|
||||
'openLastMileOutboundPlan'
|
||||
].forEach(name => expect(html.includes(`function ${name}(`), `应保留操作函数 ${name}`));
|
||||
|
||||
if (failures.length) {
|
||||
console.error('LAST_MILE_DETAIL_ACTIONS_HIDDEN_CHECK_FAIL');
|
||||
failures.forEach(failure => console.error(`- ${failure}`));
|
||||
process.exitCode = 1;
|
||||
} else {
|
||||
console.log('LAST_MILE_DETAIL_ACTIONS_HIDDEN_CHECK_PASS');
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
const fs = require('node:fs');
|
||||
const path = require('node:path');
|
||||
|
||||
const html = fs.readFileSync(path.resolve(__dirname, '..', '货代SaaS平台原型.html'), 'utf8');
|
||||
const failures = [];
|
||||
|
||||
function expect(pattern, label, source = html) {
|
||||
if (!pattern.test(source)) failures.push(`missing ${label}`);
|
||||
}
|
||||
|
||||
const ruleMatch = html.match(/#page-last-mile-orders \.lmo-search\{([^}]*)\}/);
|
||||
const rule = ruleMatch ? ruleMatch[1] : '';
|
||||
|
||||
expect(/gap:8px;/, 'compact search spacing', rule);
|
||||
expect(/align-items:center;?$/, 'vertically aligned controls', rule);
|
||||
|
||||
const tabsRuleMatch = html.match(/#page-last-mile-orders \.lmo-status-tabs\{([^}]*)\}/);
|
||||
const tabsRule = tabsRuleMatch ? tabsRuleMatch[1] : '';
|
||||
expect(/background:#f8fafc;/, 'filter tabs continuous background', tabsRule);
|
||||
expect(/border-bottom:1px solid #e5eaf1;/, 'filter tabs unified divider', tabsRule);
|
||||
|
||||
const activeRuleMatch = html.match(/#page-last-mile-orders \.lmo-status-tab\.active\{([^}]*)\}/);
|
||||
const activeRule = activeRuleMatch ? activeRuleMatch[1] : '';
|
||||
expect(/background:#fff;?$/, 'active filter tab white surface', activeRule);
|
||||
|
||||
const pageStart = html.indexOf('<div class="page" id="page-last-mile-orders">');
|
||||
const pageEnd = html.indexOf('<!-- ==================== OVERSEAS WAREHOUSE - 尾程订单详情', pageStart);
|
||||
const page = pageStart >= 0 && pageEnd > pageStart ? html.slice(pageStart, pageEnd) : '';
|
||||
const searchMatch = page.match(/<div class="search-row lmo-search">([\s\S]*?)<div class="lmo-selection-summary">/);
|
||||
const search = searchMatch ? searchMatch[1] : '';
|
||||
expect(/<div class="search-row lmo-search">/, 'shared compact search row', page);
|
||||
expect(/id="lmo-no"[^>]*placeholder="尾程单号"[^>]*style="width:170px"/, 'compact last mile number input', search);
|
||||
expect(/id="lmo-first-leg-no"[^>]*placeholder="入仓码"/, 'compact warehouse code input', search);
|
||||
expect(/class="lmo-search-date-range"[\s\S]*?id="lmo-port-eta-start"[\s\S]*?id="lmo-port-eta-end"/, 'inline date range', search);
|
||||
expect(/class="btn btn-sm btn-primary"[^>]*onclick="lastMileSearch\(\)"/, 'compact search action', search);
|
||||
expect(/class="btn btn-sm btn-default"[^>]*onclick="lastMileReset\(\)"/, 'compact reset action', search);
|
||||
if (/<label|lmo-search-field/.test(search)) failures.push('unexpected labeled grid fields');
|
||||
|
||||
for (const id of ['lmo-no','lmo-first-leg-no','lmo-warehouse','lmo-fba-warehouse','lmo-order-type','lmo-owner','lmo-container','lmo-status','lmo-consolidated-filter','lmo-port-eta-start','lmo-port-eta-end']) {
|
||||
expect(new RegExp(`id="${id}"`), `query control ${id}`, search);
|
||||
}
|
||||
|
||||
if (failures.length) {
|
||||
console.error('LAST_MILE_SEARCH_BACKGROUND_CHECK_FAIL');
|
||||
failures.forEach(failure => console.error(`- ${failure}`));
|
||||
process.exitCode = 1;
|
||||
} else {
|
||||
console.log('LAST_MILE_SEARCH_BACKGROUND_CHECK_PASS');
|
||||
}
|
||||
@@ -42,7 +42,7 @@ const detailPages = [
|
||||
renderer: 'renderFbaRelabelOrder',
|
||||
entryField: 'orderNo',
|
||||
title: '换标单详情',
|
||||
fields: ['换标单号', '贴标要求'],
|
||||
fields: ['换标单号', '贴标要求', '费用明细', '开箱费', '挑货费', '换标费', '换箱唛标费'],
|
||||
},
|
||||
{
|
||||
pageId: 'fba-pallet-detail',
|
||||
@@ -138,14 +138,19 @@ detailPages.forEach((detail) => {
|
||||
);
|
||||
|
||||
const rendererSource = getFunctionSource(detail.renderer);
|
||||
const entryPattern = new RegExp(
|
||||
`${escapeRegExp(detail.openFunction)}\\s*\\([^)]*\\b(?:d|item|record)\\.${escapeRegExp(detail.entryField)}\\b[^)]*\\)`,
|
||||
);
|
||||
requireMatch(
|
||||
entryPattern,
|
||||
`${detail.renderer} 列表查看入口传入 ${detail.entryField}`,
|
||||
rendererSource,
|
||||
);
|
||||
if (detail.pageId === 'fba-relabel-order-detail') {
|
||||
requireMatch(/data-fbro-view-order/, `${detail.renderer} 列表查看数据入口`, rendererSource);
|
||||
requireMatch(/openFbaRelabelOrderDetail\s*\(\s*view\.dataset\.fbroViewOrder\s*\)/, `${detail.renderer} 委托查看入口传入 ${detail.entryField}`);
|
||||
} else {
|
||||
const entryPattern = new RegExp(
|
||||
`${escapeRegExp(detail.openFunction)}\\s*\\([^)]*\\b(?:d|item|record)\\.${escapeRegExp(detail.entryField)}\\b[^)]*\\)`,
|
||||
);
|
||||
requireMatch(
|
||||
entryPattern,
|
||||
`${detail.renderer} 列表查看入口传入 ${detail.entryField}`,
|
||||
rendererSource,
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
if (failures.length) {
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
const assert = require('node:assert/strict');
|
||||
const fs = require('node:fs');
|
||||
const path = require('node:path');
|
||||
|
||||
const root = path.resolve(__dirname, '..');
|
||||
const sourceRoot = path.join(root, 'prototype-src');
|
||||
const manifest = JSON.parse(fs.readFileSync(path.join(sourceRoot, 'manifest.json'), 'utf8'));
|
||||
const complete = fs.readFileSync(path.join(root, manifest.source), 'utf8');
|
||||
|
||||
const modulePages = [];
|
||||
for (const module of manifest.modules) {
|
||||
const modulePath = path.join(sourceRoot, module.file);
|
||||
assert.ok(fs.existsSync(modulePath), `缺少模块文件: ${module.file}`);
|
||||
const content = fs.readFileSync(modulePath, 'utf8');
|
||||
const ids = [...content.matchAll(/id="page-([^"]+)"/g)].map(match => match[1]);
|
||||
assert.deepEqual(ids, module.pages, `${module.file} 的页面清单与 manifest 不一致`);
|
||||
modulePages.push(...ids);
|
||||
}
|
||||
|
||||
assert.equal(new Set(modulePages).size, modulePages.length, '模块中存在重复 page-* ID');
|
||||
assert.deepEqual(new Set(modulePages), new Set(manifest.pageOrder), '模块页面与 pageOrder 不一致');
|
||||
|
||||
const completePages = [...complete.matchAll(/id="page-([^"]+)"/g)].map(match => match[1]);
|
||||
assert.deepEqual(completePages, manifest.pageOrder, '完整原型的页面顺序或页面清单不一致,请重新构建');
|
||||
assert.ok(complete.includes('<main class="main-content" id="mainContent">'), '完整原型缺少主内容壳');
|
||||
assert.ok(complete.includes('function switchPage(page,el)'), '完整原型缺少导航脚本');
|
||||
|
||||
console.log(`验证通过:${manifest.modules.length} 个模块,${modulePages.length} 个页面。`);
|
||||
@@ -23,8 +23,9 @@ const inboundEnd = html.indexOf('<div class="modal-overlay" id="modal-fbio-appoi
|
||||
const inboundPage = inboundStart >= 0 && inboundEnd > inboundStart ? html.slice(inboundStart, inboundEnd) : '';
|
||||
expect(/id="fbio-appointment-filter-status"/, '预约状态查询', inboundPage);
|
||||
expect(/id="fbio-schedule-status"/, '是否排车查询', inboundPage);
|
||||
expect(/class="fbio-search-row(?: with-actions)?"[\s\S]*?class="fbio-search-row(?: with-actions)?"/, '入库单双行查询布局', inboundPage);
|
||||
expect(/fbio-inbound-end[\s\S]*?class="fbio-search-actions"[\s\S]*?fbioSearch\(\)[\s\S]*?fbioReset\(\)/, '查询重置按钮位于条件后', inboundPage);
|
||||
expect(/class="search-row fbio-search-row">[\s\S]*?id="fbio-inbound-end"[\s\S]*?fbioSearch\(\)[\s\S]*?fbioReset\(\)/, '入库单统一查询栏', inboundPage);
|
||||
expectAbsent(/fbio-search-panel|fbio-search-grid|fbio-field|class="fbio-search-row with-actions"/, '旧入库单独立查询布局', inboundPage);
|
||||
expect(/fbio-inbound-end[\s\S]*?class="btn btn-sm btn-primary"[^>]*fbioSearch\(\)[\s\S]*?class="btn btn-sm btn-default"[^>]*fbioReset\(\)/, '查询重置按钮位于条件后', inboundPage);
|
||||
expect(/id="fbio-smart-schedule"[^>]*onclick="openDispatchSchedule\(\)"[^>]*>智能排车<\/button>/, '列表右上角智能排车入口', inboundPage);
|
||||
expectAbsent(/id="fbio-batch-schedule"|>批量排车<\/button>/, '旧批量排车入口', inboundPage);
|
||||
expect(/id="modal-dispatch-schedule"[\s\S]*?>智能排车</, '智能排车弹窗');
|
||||
|
||||
File diff suppressed because one or more lines are too long
+8
-8
@@ -9,19 +9,19 @@
|
||||
| task_id | display_name | responsibility |
|
||||
|---|---|---|
|
||||
| `019ff0da-7699-7532-ac64-703325c995fd` | 全量验收总控 | 统筹跨模块契约、专项实现、验证、人工部署准备及正式全量验收接入;当前覆盖 Finance 一期与三期智能装柜渠道柜链路 |
|
||||
| `019ff55b-a375-75d1-8cce-6fb284df10f2` | 消息中心总控 | 统筹消息中心任务规划、长期独立任务创建与协调、联调与调试、跨任务信息汇总及交付收敛 |
|
||||
|
||||
总控创建、需要长期复用的用户独立任务:
|
||||
|
||||
| task_id | parent_task_id | display_name | responsibility |
|
||||
|---|---|---|---|
|
||||
| `019ff537-970e-7870-adea-47ecdd778e0b` | `019ff0da-7699-7532-ac64-703325c995fd` | 渠道柜自动生成与混装门禁 | 实现订舱确认后按渠道和箱型需求生成稳定内部柜次、渠道混装硬门禁及真实集装箱号后补审计契约 |
|
||||
| `019ff580-aa88-77c1-84a2-5ff83c9aba2c` | `019ff0da-7699-7532-ac64-703325c995fd` | Admin渠道柜与智能排柜适配 | 维护 Admin 订舱渠道、仓库与箱型容量快照、放舱专用请求、按订舱查询智能候选及稳定柜次展示契约 |
|
||||
| `019ff580-b0b4-7d11-b0de-ea6144da4225` | `019ff0da-7699-7532-ac64-703325c995fd` | PDA稳定柜次身份适配 | 维护 PDA 任务查询、草稿恢复、导航和提交幂等中的稳定柜次身份,真实集装箱号仅作为可变展示字段 |
|
||||
| `019ff579-3d8f-7c43-99ad-40bdcc9ea5e7` | `019ff55b-a375-75d1-8cce-6fb284df10f2` | IAM消息中心后端 | 在 IAM 服务内维护消息模板、消息任务、收件人、站内信、已读状态、定时发送、MQ 消费及消息中心服务端契约 |
|
||||
| `019ff579-41c3-7e10-b470-79ac8037e617` | `019ff55b-a375-75d1-8cce-6fb284df10f2` | Admin消息中心 | 维护 Admin 消息管理、模板管理、平台员工我的消息、顶部未读入口及对应原型交互 |
|
||||
| `019ff579-46a0-7803-82ba-e8e134a99eed` | `019ff55b-a375-75d1-8cce-6fb284df10f2` | Client我的消息 | 维护 Client 企业成员站内信、未读数量、消息详情、已读操作及顶部消息入口 |
|
||||
| `019ff5c3-a249-7871-8ab8-c4414e83e2da` | `019ff55b-a375-75d1-8cce-6fb284df10f2` | 消息中心 MQ 与调度 | 维护 IAM 消息业务事件消费、事件收件箱幂等、定时任务调度、超时回收、RocketMQ 配置及相关验证 |
|
||||
| `019ff5fa-b448-7713-a142-1af7f2c72d2d` | `019ff0da-7699-7532-ac64-703325c995fd` | 简化清关报关后端 | 按原型维护货柜清关资料与完成动作、装柜清单报关资料与完成动作的最小后端契约、文件归属、审计及数据库脚本 |
|
||||
| `019ff5fa-bdfc-7bf1-8cb2-18a25dccc67d` | `019ff0da-7699-7532-ac64-703325c995fd` | Admin原型流程与验收收敛 | 按原型收敛 Admin 导航与路由,在货柜和装柜清单承载清关/报关操作,并同步全量人工状态矩阵 |
|
||||
| `019ff5fe-dcc2-7481-8d8a-b0e1b39de145` | `019ff0da-7699-7532-ac64-703325c995fd` | File平台公共业务文件适配 | 维护内部服务令牌入口对平台公共业务文件 `tenantId=0` 的受控支持、清关报关文件类型白名单及上传校验下载契约 |
|
||||
| `019ff600-e924-7902-b00e-fa1ee1658e08` | `019ff0da-7699-7532-ac64-703325c995fd` | 平台基础原型只读审计 | 只读比对客户、平台用户、角色权限、仓库、库位、托盘及主数据的已确认范围、原型和当前实现 |
|
||||
| `019ff600-f15a-7be3-8f5d-8771115f9828` | `019ff0da-7699-7532-ac64-703325c995fd` | 订单入库审计与 WAIT_SPLIT 修复 | 先复用订单、测量、计费、统一订单及客户工作台审计证据,再修复 WAIT_SPLIT 主链并同步必要消费者与测试 |
|
||||
| `019ff600-f9f1-78f1-a357-7c80c13e574e` | `019ff0da-7699-7532-ac64-703325c995fd` | 货柜出仓审计与 PDA 门禁修复 | 先复用订舱、拖车、智能装柜、预装、装柜清单及 PDA 审计证据,再修复渠道约束和真实柜号现场门禁 |
|
||||
| `019ff601-029f-7801-851c-7c68e02804ca` | `019ff0da-7699-7532-ac64-703325c995fd` | 财务审计与正式结算契约修复 | 先复用财务审计证据,再统一正式结算模型、Client JSON 适配、权限和相关测试 |
|
||||
| `019ff607-87b3-70b3-b5c3-7bc9c528363c` | `019ff0da-7699-7532-ac64-703325c995fd` | 测试环境重建与人工验收数据矩阵 | 维护数据库重建后的基础初始化数据核验、全量验收脚本编排、各真实可达列表状态样本保留及人工点击验收报告 |
|
||||
|
||||
## 规则
|
||||
|
||||
|
||||
Reference in New Issue
Block a user