feat: 完成国际出港移库/出库交接页面5.5寸手机端适配

- 落地手机端双形态适配框架:同名布局+资源限定符(layout/手机、
  layout-sw600dp/平板)自动切换,DeviceUtil 设备形态判定,7个
  手机版公共组件(PhoneSearchBar/StatusTab/DataLayout/FilterPanel/
  BottomBar/StatBox/KvItem)
- 完成「国际出港移库」「国际出港出库交接」两页手机端适配,新增
  各自详情页(IntExpMoveDetailActivity/IntExpOutHandoverDetailActivity)
- 手机端首页菜单接入"出港移库""出库交接"入口
- 修复手机端进入页面先横屏后转竖屏的闪屏问题:Manifest 全项目
  192 处改为 screenOrientation="unspecified",由 BaseActivity
  按设备形态运行时锁定方向
- 修复该方案的中间版本在平板端引入的回归(先竖后横 + UI放大1.6倍)
- AutoSize 补充手机竖屏 390×844 设计基准
- 修复 CHANGELOG.md 因脚本异常导致的内容重复损坏(膨胀至12万行),
  恢复正常结构并补充本次变更记录

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-29 14:18:29 +08:00
parent 9c4588e47e
commit db062c8ee3
134 changed files with 19602 additions and 2965 deletions

View File

@@ -0,0 +1,535 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8"/>
<meta content="width=device-width, initial-scale=1.0" name="viewport"/>
<title>出港运抵</title>
<!-- Tailwind CSS -->
<script src="https://cdn.tailwindcss.com"></script>
<!-- Iconify -->
<script src="https://cdn.jsdelivr.net/npm/iconify-icon@2.1.0/dist/iconify-icon.min.js"></script>
<style>
.no-scrollbar::-webkit-scrollbar {
display: none;
}
body {
background-color: #f3f6f8;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
margin: 0;
}
@keyframes fadeIn {
from { opacity: 0; transform: translate(-50%, 10px); }
to { opacity: 1; transform: translate(-50%, 0); }
}
.animate-fadeIn {
animation: fadeIn 0.3s ease-out;
}
</style>
</head>
<body class="bg-gray-100">
<div class="phone-shell w-[375px] h-[812px] bg-[#F5F5F7] overflow-hidden flex flex-col relative rounded-[48px] border-[10px] border-gray-900">
<div class="bg-[#2563EB] flex-none">
<div class="h-[44px] flex justify-between items-center px-8 text-white">
<span class="text-[15px] font-semibold">09:41</span>
<div class="flex items-center gap-1.5">
<iconify-icon class="text-lg" icon="mdi:signal-cellular-3"></iconify-icon>
<iconify-icon class="text-lg" icon="mdi:wifi"></iconify-icon>
<iconify-icon class="text-xl" icon="mdi:battery"></iconify-icon>
</div>
</div>
<div class="h-[44px] flex items-center px-4 relative">
<div class="flex items-center text-white cursor-pointer" onclick="window.history.back()">
<iconify-icon class="text-2xl" icon="mdi:chevron-left"></iconify-icon>
<span class="text-sm">返回</span>
</div>
<div class="absolute inset-0 flex items-center justify-center pointer-events-none">
<h1 class="text-white text-lg font-bold">出港运抵</h1>
</div>
<div class="ml-auto w-10"></div>
</div>
</div>
<div class="flex-1 overflow-y-auto no-scrollbar">
<section class="px-4 pt-4 pb-3 bg-white">
<div class="flex items-center gap-2">
<div class="flex items-center bg-white border border-gray-200 shadow-sm rounded-[12px] h-10 px-3 gap-2 flex-1">
<iconify-icon class="text-gray-400 text-lg flex-none" icon="mdi:magnify"></iconify-icon>
<input class="flex-1 bg-transparent text-[14px] text-gray-800 placeholder-gray-400 outline-none border-none rounded-lg px-2" placeholder="搜索运单号" type="text"/>
<button class="flex-none text-blue-500">
<iconify-icon class="text-lg" icon="mdi:qrcode-scan"></iconify-icon>
</button>
</div>
<button class="bg-white p-2.5 rounded-full shadow-sm border border-gray-200 text-[#2563EB] flex items-center justify-center flex-none" onclick="showFilterSheet2()">
<iconify-icon class="text-lg" icon="mdi:filter-variant"></iconify-icon>
</button>
</div>
</section>
<div class="flex bg-white border-b sticky top-0 z-20">
<button class="tab-btn flex-1 py-3 text-sm font-bold border-b-2 transition-all text-[#1F2937] border-[#1F2937]" id="tab-pending" onclick="switchTab('pending')">
待运抵 <span class="bg-[#DBEAF6] text-[#2563EB] text-[11px] font-medium px-1.5 py-0.5 rounded-md ml-1.5" id="count-pending">1</span>
</button>
<button class="tab-btn flex-1 py-3 text-sm font-bold border-b-2 transition-all text-gray-400 border-transparent" id="tab-shipped" onclick="switchTab('shipped')">
已运抵 <span class="bg-[#DBEAF6] text-[#2563EB] text-[11px] font-medium px-1.5 py-0.5 rounded-md ml-1.5" id="count-shipped">4</span>
</button>
</div>
<div class="px-5 pb-5 pt-3">
<div class="flex flex-col items-center justify-center py-16 text-gray-400 hidden" id="empty-pending">
<svg class="w-16 h-16 text-gray-300 mb-4" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24">
<path d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"></path>
</svg>
<p class="text-sm">暂无待运抵的运单</p>
</div>
<!-- 待运抵卡片(长按显示补充按钮) -->
<div class="bg-white rounded-2xl p-5 shadow-sm border border-gray-100/50 mb-4 uld-card relative" data-status="pending">
<div class="flex items-center justify-between">
<div class="flex items-center gap-2">
<span class="radio-btn border-2 border-gray-300 rounded-full w-5 h-5 inline-flex items-center justify-center flex-none cursor-pointer"></span>
<div class="flex items-baseline">
<span class="text-sm font-bold text-gray-900">78133363396</span>
</div>
</div>
<div class="flex items-center gap-2">
<span class="bg-red-500 text-white text-[11px] font-medium px-2.5 py-0.5 rounded-full">提前运抵</span>
</div>
</div>
<div class="grid grid-cols-2 gap-y-2 text-gray-500 text-[13px] mt-3">
<div><span>代理:</span><span>马道</span></div>
<div><span>件数:</span><span>444</span></div>
<div><span>重量:</span><span>150kg</span></div>
<div><span>航班日期:</span><span>20260713</span></div>
<div><span>航班号:</span><span>MU2033</span></div>
<div><span>航程:</span><span>HFE-LAX</span></div>
</div>
<div class="mt-2">
<button class="w-full bg-[#EFF6FF] text-[#2563EB] text-xs py-2 rounded-[6px] font-medium h-8 flex items-center justify-center gap-2" onclick="event.stopPropagation(); window.location.href='suborder.html'">
查看分单
<span class="text-[#2563EB] text-[10px] font-bold">3</span>
</button>
</div>
<!-- 长按弹出操作层 -->
<div class="card-action-overlay absolute inset-0 bg-black/40 rounded-2xl z-10 hidden flex items-center justify-center pointer-events-none">
<div class="flex items-center gap-4 pointer-events-auto shipped-actions hidden">
<button class="bg-amber-500 text-white text-[10px] font-bold w-14 h-14 rounded-full shadow-lg shadow-amber-500/30 flex items-center justify-center leading-tight" onclick="event.stopPropagation(); this.closest('.card-action-overlay').classList.add('hidden'); setTimeout(() => showResetStatusSheet(), 200)">重置</button>
<button class="bg-emerald-500 text-white text-[10px] font-bold w-14 h-14 rounded-full shadow-lg shadow-emerald-500/30 flex items-center justify-center leading-tight" onclick="event.stopPropagation(); window.location.href='receipt.html'">回执</button>
</div>
</div>
</div>
<!-- 已运抵卡片1 -->
<div class="bg-white rounded-2xl p-5 shadow-sm border border-gray-100/50 mb-4 uld-card relative" data-status="shipped" style="display: none;">
<div class="flex items-center justify-between">
<div class="flex items-center gap-2">
<span class="text-sm font-bold text-gray-900">78133363397</span>
</div>
<div class="flex items-center gap-2">
<span class="bg-indigo-100 text-indigo-500 text-[11px] font-medium px-2.5 py-0.5 rounded-full">W</span>
<span class="bg-green-100 text-green-600 text-[11px] font-medium px-2 py-0.5 rounded-md">11</span>
</div>
</div>
<div class="grid grid-cols-2 gap-y-2 text-gray-500 text-[13px] mt-3">
<div><span>代理:</span><span>徽远</span></div>
<div><span>件数:</span><span>300</span></div>
<div><span>重量:</span><span>120kg</span></div>
<div><span>航班日期:</span><span>20260713</span></div>
<div><span>航班号:</span><span>MU2033</span></div>
<div><span>航程:</span><span>HFE-LAX</span></div>
</div>
<div class="mt-2">
<button class="w-full bg-[#EFF6FF] text-[#2563EB] text-xs py-2 rounded-[6px] font-medium h-8 flex items-center justify-center gap-2" onclick="event.stopPropagation(); window.location.href='suborder.html'">
查看分单
<span class="text-[#2563EB] text-[10px] font-bold">2</span>
</button>
</div>
<div class="card-action-overlay absolute inset-0 bg-black/40 rounded-2xl z-10 hidden flex items-center justify-center pointer-events-none">
<div class="flex items-center gap-4 pointer-events-auto pending-actions hidden">
<button class="bg-purple-500 text-white text-[10px] font-bold w-14 h-14 rounded-full shadow-lg shadow-purple-500/30 flex items-center justify-center leading-tight" onclick="event.stopPropagation(); this.closest('.card-action-overlay').classList.add('hidden'); window.location.href='supplement.html'">补充</button>
</div>
<div class="flex items-center gap-4 pointer-events-auto shipped-actions hidden">
<button class="bg-amber-500 text-white text-[10px] font-bold w-14 h-14 rounded-full shadow-lg shadow-amber-500/30 flex items-center justify-center leading-tight" onclick="event.stopPropagation(); this.closest('.card-action-overlay').classList.add('hidden'); setTimeout(() => showResetStatusSheet(), 200)">重置</button>
<button class="bg-emerald-500 text-white text-[10px] font-bold w-14 h-14 rounded-full shadow-lg shadow-emerald-500/30 flex items-center justify-center leading-tight" onclick="event.stopPropagation(); window.location.href='receipt.html'">回执</button>
</div>
</div>
</div>
<!-- 已运抵卡片2 -->
<div class="bg-white rounded-2xl p-5 shadow-sm border border-gray-100/50 mb-4 uld-card relative" data-status="shipped" style="display: none;">
<div class="flex items-center justify-between">
<div class="flex items-center gap-2">
<span class="text-sm font-bold text-gray-900">78133363398</span>
</div>
<div class="flex items-center gap-2">
<span class="bg-green-100 text-green-600 text-[11px] font-medium px-2.5 py-0.5 rounded-full">01</span>
<span class="bg-green-100 text-green-600 text-[11px] font-medium px-2 py-0.5 rounded-md">11</span>
</div>
</div>
<div class="grid grid-cols-2 gap-y-2 text-gray-500 text-[13px] mt-3">
<div><span>代理:</span><span>中外运</span></div>
<div><span>件数:</span><span>130</span></div>
<div><span>重量:</span><span>130kg</span></div>
<div><span>航班日期:</span><span>20260713</span></div>
<div><span>航班号:</span><span>MU2033</span></div>
<div><span>航程:</span><span>HFE-LAX</span></div>
</div>
<div class="mt-2">
<button class="w-full bg-[#EFF6FF] text-[#2563EB] text-xs py-2 rounded-[6px] font-medium h-8 flex items-center justify-center gap-2" onclick="event.stopPropagation(); window.location.href='suborder.html'">
查看分单
<span class="text-[#2563EB] text-[10px] font-bold">2</span>
</button>
</div>
<div class="card-action-overlay absolute inset-0 bg-black/40 rounded-2xl z-10 hidden flex items-center justify-center pointer-events-none">
<div class="flex items-center gap-4 pointer-events-auto pending-actions hidden">
<button class="bg-purple-500 text-white text-[10px] font-bold w-14 h-14 rounded-full shadow-lg shadow-purple-500/30 flex items-center justify-center leading-tight" onclick="event.stopPropagation(); this.closest('.card-action-overlay').classList.add('hidden'); window.location.href='supplement.html'">补充</button>
</div>
<div class="flex items-center gap-4 pointer-events-auto shipped-actions hidden">
<button class="bg-amber-500 text-white text-[10px] font-bold w-14 h-14 rounded-full shadow-lg shadow-amber-500/30 flex items-center justify-center leading-tight" onclick="event.stopPropagation(); this.closest('.card-action-overlay').classList.add('hidden'); setTimeout(() => showResetStatusSheet(), 200)">重置</button>
<button class="bg-emerald-500 text-white text-[10px] font-bold w-14 h-14 rounded-full shadow-lg shadow-emerald-500/30 flex items-center justify-center leading-tight" onclick="event.stopPropagation(); window.location.href='receipt.html'">回执</button>
</div>
</div>
</div>
<!-- 已运抵卡片378133363399 -->
<div class="bg-white rounded-2xl p-5 shadow-sm border border-gray-100/50 mb-4 uld-card relative" data-status="shipped" style="display: none;">
<div class="flex items-center justify-between">
<div class="flex items-center gap-2">
<span class="text-sm font-bold text-gray-900">78133363399</span>
</div>
<div class="flex items-center gap-2">
<span class="bg-amber-100 text-amber-600 text-[11px] font-medium px-2.5 py-0.5 rounded-full">E</span>
<span class="bg-green-100 text-green-600 text-[11px] font-medium px-2 py-0.5 rounded-md">11</span>
</div>
</div>
<div class="grid grid-cols-2 gap-y-2 text-gray-500 text-[13px] mt-3">
<div><span>代理:</span><span>MU</span></div>
<div><span>件数:</span><span>300</span></div>
<div><span>重量:</span><span>110kg</span></div>
<div><span>航班日期:</span><span>20260713</span></div>
<div><span>航班号:</span><span>MU2034</span></div>
<div><span>航程:</span><span>HFE-LAX</span></div>
</div>
<div class="mt-2">
<button class="w-full bg-[#EFF6FF] text-[#2563EB] text-xs py-2 rounded-[6px] font-medium h-8 flex items-center justify-center gap-2" onclick="event.stopPropagation(); window.location.href='https://modao.cc/agent-py/workspace/6a50a1993333bc5bbd8ee054/waybill-arrival.html/suborder.html?render_html=true'">
查看分单
<span class="text-[#2563EB] text-[10px] font-bold">1</span>
</button>
</div>
<!-- 卡片操作菜单(默认隐藏) -->
<div class="card-action-overlay absolute inset-0 bg-black/40 rounded-2xl z-10 hidden flex items-center justify-center pointer-events-none">
<!-- 已运抵按钮容器(显示重置+回执) -->
<div class="flex items-center gap-4 pointer-events-auto shipped-actions hidden">
<button class="bg-amber-500 text-white text-[10px] font-bold w-14 h-14 rounded-full shadow-lg shadow-amber-500/30 flex items-center justify-center leading-tight" onclick="event.stopPropagation(); this.closest('.card-action-overlay').classList.add('hidden'); setTimeout(() => showResetStatusSheet(), 200)">
重置
</button>
<button class="bg-emerald-500 text-white text-[10px] font-bold w-14 h-14 rounded-full shadow-lg shadow-emerald-500/30 flex items-center justify-center leading-tight" onclick="event.stopPropagation(); window.location.href='https://modao.cc/agent-py/workspace/6a50a1993333bc5bbd8ee054/waybill-arrival.html/receipt.html?render_html=true'">
回执
</button>
</div>
</div>
</div>
</div>
</div>
<!-- 底部操作栏 -->
<div class="flex-none bg-white border-t border-gray-100" id="bottom-action-bar">
<div class="flex items-center justify-between px-5 py-3">
<div class="flex items-center gap-2 select-all cursor-pointer">
<span class="radio-select-all w-5 h-5 rounded-full border-2 border-gray-300 bg-white flex items-center justify-center"></span>
<span class="text-sm text-gray-700 font-medium">全选</span>
</div>
<div class="flex items-center gap-3 bottom-action-container">
<span class="text-[12px] text-[#9CA3AF]">已选 <span id="selected-count">0</span></span>
<button class="bg-[#2563EB] text-white text-[15px] font-bold px-5 py-2 rounded-[10px] shadow-lg shadow-blue-500/25" onclick="alert('运抵申报')">申报</button>
</div>
</div>
<div class="pb-2 flex justify-center">
<div class="w-32 h-1.5 bg-gray-200 rounded-full"></div>
</div>
</div>
<!-- 筛选弹窗 -->
<div class="absolute inset-0 bg-black/40 z-50 hidden" id="filter-sheet2-overlay" onclick="hideFilterSheet2()"></div>
<div class="absolute bottom-0 left-0 right-0 bg-white rounded-t-2xl shadow-2xl z-50 transform translate-y-full transition-transform duration-300 ease-in-out" id="filter-sheet2">
<div class="px-5 pt-5 pb-8">
<div class="flex items-center justify-center mb-6 relative">
<h3 class="text-base font-bold text-gray-900">筛选条件</h3>
<button class="absolute right-0 w-8 h-8 rounded-full bg-gray-100 flex items-center justify-center" onclick="hideFilterSheet2()">
<svg class="w-4 h-4 text-gray-500" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" viewBox="0 0 24 24">
<line x1="18" x2="6" y1="6" y2="18"></line>
<line x1="6" x2="18" y1="6" y2="18"></line>
</svg>
</button>
</div>
<div class="space-y-4">
<div>
<label class="text-sm text-gray-500 font-medium mb-1.5 block">航班日期</label>
<div class="flex items-center bg-gray-50 border border-gray-200 rounded-xl h-10 px-3">
<iconify-icon class="text-gray-400 text-lg flex-none" icon="mdi:calendar"></iconify-icon>
<input class="flex-1 bg-transparent text-[14px] text-gray-800 placeholder-gray-400 outline-none border-none px-2" placeholder="选择日期" type="text" value="2026-07-10"/>
</div>
</div>
<div>
<label class="text-sm text-gray-500 font-medium mb-1.5 block">航班号</label>
<div class="flex items-center bg-gray-50 border border-gray-200 rounded-xl h-10 px-3">
<input class="flex-1 bg-transparent text-[14px] text-gray-800 placeholder-gray-400 outline-none border-none" placeholder="请输入航班号" type="text"/>
</div>
</div>
<div>
<label class="text-sm text-gray-500 font-medium mb-1.5 block">代理</label>
<select class="w-full bg-gray-50 border border-gray-200 rounded-xl h-10 px-3 text-[14px] text-gray-800 outline-none appearance-none bg-[url('data:image/svg+xml;charset=UTF-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2212%22%20height%3D%2212%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20stroke%3D%22%239CA3AF%22%20stroke-width%3D%222%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%3E%3Cpolyline%20points%3D%226%209%2012%2015%2018%209%22%3E%3C%2Fpolyline%3E%3C%2Fsvg%3E')] bg-[length:14px] bg-[right_12px_center] bg-no-repeat">
<option disabled selected value="">请选择代理</option>
<option value="马道">马道</option>
<option value="徽远">徽远</option>
<option value="中外运">中外运</option>
<option value="MU">MU</option>
</select>
</div>
</div>
<div class="flex gap-3 mt-6">
<button class="flex-1 py-3 text-sm font-medium text-gray-500 bg-gray-100 rounded-xl" onclick="hideFilterSheet2()">重置</button>
<button class="flex-1 py-3 text-sm font-medium text-white bg-[#2563EB] rounded-xl" onclick="hideFilterSheet2()">确定</button>
</div>
</div>
</div>
<!-- 重置状态弹窗 -->
<div class="absolute inset-0 bg-black/40 z-50 hidden" id="reset-sheet-overlay" onclick="hideResetStatusSheet()"></div>
<div class="absolute bottom-0 left-0 right-0 bg-white rounded-t-2xl shadow-2xl z-50 transform translate-y-full transition-transform duration-300 ease-in-out" id="reset-sheet">
<div class="px-5 pt-5 pb-8">
<div class="flex items-center justify-center mb-6 relative">
<h3 class="text-base font-bold text-gray-900">重置状态</h3>
<button class="absolute right-0 w-8 h-8 rounded-full bg-gray-100 flex items-center justify-center" onclick="hideResetStatusSheet()">
<svg class="w-4 h-4 text-gray-500" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" viewBox="0 0 24 24">
<line x1="18" x2="6" y1="6" y2="18"></line>
<line x1="6" x2="18" y1="6" y2="18"></line>
</svg>
</button>
</div>
<div>
<label class="text-sm text-gray-500 font-medium mb-1.5 block">状态</label>
<select class="w-full bg-gray-50 border border-gray-200 rounded-xl h-10 px-3 text-[14px] text-gray-800 outline-none appearance-none bg-[url('data:image/svg+xml;charset=UTF-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2212%22%20height%3D%2212%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20stroke%3D%22%239CA3AF%22%20stroke-width%3D%222%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%3E%3Cpolyline%20points%3D%226%209%2012%2015%2018%209%22%3E%3C%2Fpolyline%3E%3C%2Fsvg%3E')] bg-[length:14px] bg-[right_12px_center] bg-no-repeat" id="reset-status-select">
<option disabled selected value="">请选择状态</option>
<option value=""></option>
<option value="01">01</option>
</select>
</div>
<button class="w-full mt-6 py-3 text-sm font-medium text-white bg-[#2563EB] rounded-xl" onclick="confirmResetStatus()">确定</button>
</div>
</div>
</div>
<script>
let currentTab = 'pending';
let longPressTimer = null;
let isLongPress = false;
// Toast提示
function showToast(message) {
const existingToast = document.querySelector('.custom-toast');
if (existingToast) existingToast.remove();
const toast = document.createElement('div');
toast.className = 'custom-toast fixed bottom-32 left-1/2 -translate-x-1/2 bg-gray-800 text-white text-sm px-5 py-3 rounded-xl shadow-lg z-50 animate-fadeIn';
toast.textContent = message;
document.body.appendChild(toast);
setTimeout(() => {
toast.style.opacity = '0';
toast.style.transition = 'opacity 0.3s';
setTimeout(() => toast.remove(), 300);
}, 2000);
}
// 清空所有选中
function resetAllSelections() {
document.querySelectorAll('.radio-btn').forEach(radio => toggleRadio(radio, false));
const selectAllRadio = document.querySelector('.radio-select-all');
toggleRadio(selectAllRadio, false);
}
// 切换标签页
function switchTab(tab) {
currentTab = tab;
const tabPending = document.getElementById('tab-pending');
const tabShipped = document.getElementById('tab-shipped');
const bottomBar = document.getElementById('bottom-action-bar');
const emptyTip = document.getElementById('empty-pending');
// 切换tab样式
if (tab === 'pending') {
tabPending.classList.remove('text-gray-400', 'border-transparent');
tabPending.classList.add('text-[#1F2937]', 'border-[#1F2937]');
tabShipped.classList.remove('text-[#1F2937]', 'border-[#1F2937]');
tabShipped.classList.add('text-gray-400', 'border-transparent');
bottomBar.classList.remove('hidden');
} else {
tabPending.classList.remove('text-[#1F2937]', 'border-[#1F2937]');
tabPending.classList.add('text-gray-400', 'border-transparent');
tabShipped.classList.remove('text-gray-400', 'border-transparent');
tabShipped.classList.add('text-[#1F2937]', 'border-[#1F2937]');
bottomBar.classList.add('hidden');
}
// 切换卡片显示
const allCards = document.querySelectorAll('.uld-card');
let showCount = 0;
allCards.forEach(card => {
if (card.dataset.status === tab) {
card.style.display = 'block';
showCount++;
} else {
card.style.display = 'none';
}
});
emptyTip.classList.toggle('hidden', showCount > 0);
resetAllSelections();
updateSelectCount();
}
// 更新选中数量
function updateSelectCount() {
const list = document.querySelectorAll(`.uld-card[data-status="${currentTab}"] .radio-btn.bg-blue-500`);
document.getElementById('selected-count').textContent = list.length;
syncSelectAllStatus();
}
// 同步全选按钮样式
function syncSelectAllStatus() {
const allCards = document.querySelectorAll(`.uld-card[data-status="${currentTab}"]`);
const selectedCards = document.querySelectorAll(`.uld-card[data-status="${currentTab}"] .radio-btn.bg-blue-500`);
const selectAllBtn = document.querySelector('.radio-select-all');
if (allCards.length > 0 && allCards.length === selectedCards.length) {
selectAllBtn.classList.add('bg-blue-500', 'border-blue-500');
selectAllBtn.classList.remove('border-gray-300', 'bg-white');
selectAllBtn.innerHTML = `<svg class="w-3 h-3 text-white" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg>`;
} else {
selectAllBtn.classList.remove('bg-blue-500', 'border-blue-500');
selectAllBtn.classList.add('border-gray-300', 'bg-white');
selectAllBtn.innerHTML = '';
}
}
// 单选按钮切换
function toggleRadio(el, force) {
const isChecked = force != null ? force : !el.classList.contains('bg-blue-500');
if (isChecked) {
el.classList.add('bg-blue-500', 'border-blue-500');
el.classList.remove('border-gray-300', 'bg-white');
el.innerHTML = `<svg class="w-3 h-3 text-white" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg>`;
} else {
el.classList.remove('bg-blue-500', 'border-blue-500');
el.classList.add('border-gray-300', 'bg-white');
el.innerHTML = '';
}
updateSelectCount();
}
// 单个单选点击
document.querySelectorAll('.radio-btn').forEach(radio => {
radio.onclick = (e) => {
e.stopPropagation();
toggleRadio(radio);
};
});
// 全选按钮
document.querySelector('.select-all').onclick = function() {
const currentCards = document.querySelectorAll(`.uld-card[data-status="${currentTab}"] .radio-btn`);
const allSelected = Array.from(currentCards).every(item => item.classList.contains('bg-blue-500'));
currentCards.forEach(radio => toggleRadio(radio, !allSelected));
};
// ========== 完整长按逻辑(待运抵弹出补充,已运抵弹出重置回执) ==========
document.querySelectorAll('.uld-card').forEach(card => {
// 触摸长按
card.addEventListener('touchstart', (e) => {
// 点击单选框、按钮不触发长按
if (e.target.closest('.radio-btn') || e.target.closest('button')) return;
isLongPress = false;
longPressTimer = setTimeout(() => {
isLongPress = true;
showCardAction(card);
}, 600);
});
card.addEventListener('touchend', () => clearTimeout(longPressTimer));
card.addEventListener('touchmove', () => clearTimeout(longPressTimer));
// 鼠标长按兼容
card.addEventListener('mousedown', (e) => {
if (e.target.closest('.radio-btn') || e.target.closest('button')) return;
isLongPress = false;
longPressTimer = setTimeout(() => {
isLongPress = true;
showCardAction(card);
}, 600);
});
card.addEventListener('mouseup', () => clearTimeout(longPressTimer));
card.addEventListener('mouseleave', () => clearTimeout(longPressTimer));
});
// 展示卡片操作面板
function showCardAction(card) {
// 关闭所有卡片操作层
document.querySelectorAll('.card-action-overlay').forEach(overlay => overlay.classList.add('hidden'));
const overlay = card.querySelector('.card-action-overlay');
const pendingAction = overlay.querySelector('.pending-actions');
const shippedAction = overlay.querySelector('.shipped-actions');
pendingAction.classList.add('hidden');
shippedAction.classList.add('hidden');
// 根据状态展示对应按钮
if (card.dataset.status === 'pending') {
pendingAction.classList.remove('hidden');
} else {
shippedAction.classList.remove('hidden');
}
overlay.classList.remove('hidden');
}
// 点击空白区域关闭操作弹窗
document.addEventListener('click', (e) => {
if (!e.target.closest('.uld-card') && !e.target.closest('.card-action-overlay')) {
document.querySelectorAll('.card-action-overlay').forEach(overlay => overlay.classList.add('hidden'));
}
});
// 筛选弹窗
function showFilterSheet2() {
const overlay = document.getElementById('filter-sheet2-overlay');
const sheet = document.getElementById('filter-sheet2');
overlay.classList.remove('hidden');
setTimeout(() => sheet.classList.remove('translate-y-full'), 10);
}
function hideFilterSheet2() {
const overlay = document.getElementById('filter-sheet2-overlay');
const sheet = document.getElementById('filter-sheet2');
sheet.classList.add('translate-y-full');
setTimeout(() => overlay.classList.add('hidden'), 300);
}
// 重置状态弹窗
function showResetStatusSheet() {
document.getElementById('reset-sheet-overlay').classList.remove('hidden');
document.getElementById('reset-sheet').classList.remove('translate-y-full');
}
function hideResetStatusSheet() {
document.getElementById('reset-sheet-overlay').classList.add('hidden');
document.getElementById('reset-sheet').classList.add('translate-y-full');
}
function confirmResetStatus() {
const selectVal = document.getElementById('reset-status-select').value;
if (!selectVal) {
alert('请选择状态');
return;
}
alert('已选择状态:' + (selectVal === '' ? '置空' : selectVal));
hideResetStatusSheet();
}
// 页面初始化
switchTab('pending');
</script>
</body>
</html>