Files
2026-09-29 17:22:12 +08:00

1568 lines
26 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
```html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>FMS ERP 查询原型</title>
<style>
* {
box-sizing: border-box;
}
:root {
--primary: #2563eb;
--primary-soft: #eff6ff;
--text: #1f2937;
--text-secondary: #6b7280;
--border: #e5e7eb;
--border-light: #edf0f3;
--bg: #f5f6f8;
--panel: #fff;
--hover: #f8fafc;
--danger: #ef4444;
--control-height: 32px;
}
html,
body {
margin: 0;
width: 100%;
height: 100%;
font-family:
Inter,
"Microsoft YaHei",
"PingFang SC",
Arial,
sans-serif;
color: var(--text);
font-size: 13px;
background: var(--bg);
}
button,
input,
select {
font: inherit;
}
button {
cursor: pointer;
}
.app {
display: flex;
height: 100vh;
overflow: hidden;
}
/* =========================
Sidebar
========================= */
.sidebar {
width: 210px;
flex-shrink: 0;
background: #fff;
border-right: 1px solid var(--border);
display: flex;
flex-direction: column;
}
.logo {
height: 52px;
display: flex;
align-items: center;
padding: 0 18px;
border-bottom: 1px solid var(--border);
font-size: 15px;
font-weight: 600;
}
.logo-mark {
width: 26px;
height: 26px;
border-radius: 6px;
background: var(--primary);
color: white;
display: flex;
align-items: center;
justify-content: center;
margin-right: 9px;
font-size: 13px;
}
.menu {
padding: 10px 8px;
overflow-y: auto;
}
.menu-group {
margin-bottom: 12px;
}
.menu-title {
padding: 7px 10px;
color: #9ca3af;
font-size: 12px;
}
.menu-item {
height: 34px;
display: flex;
align-items: center;
gap: 9px;
padding: 0 10px;
border-radius: 5px;
color: #4b5563;
margin-bottom: 2px;
}
.menu-item:hover {
background: var(--hover);
}
.menu-item.active {
color: var(--primary);
background: var(--primary-soft);
font-weight: 500;
}
.menu-icon {
width: 16px;
text-align: center;
color: #9ca3af;
}
.menu-item.active .menu-icon {
color: var(--primary);
}
/* =========================
Main
========================= */
.main {
min-width: 0;
flex: 1;
display: flex;
flex-direction: column;
}
/* topbar */
.topbar {
height: 52px;
flex-shrink: 0;
background: #fff;
border-bottom: 1px solid var(--border);
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 18px;
}
.topbar-left {
display: flex;
align-items: center;
gap: 18px;
}
.org {
color: #4b5563;
}
.topbar-right {
display: flex;
align-items: center;
gap: 16px;
color: #6b7280;
}
.avatar {
width: 28px;
height: 28px;
border-radius: 50%;
background: #dbeafe;
color: #2563eb;
display: flex;
align-items: center;
justify-content: center;
}
/* tabs */
.tabs {
height: 38px;
flex-shrink: 0;
background: #fff;
border-bottom: 1px solid var(--border);
display: flex;
align-items: end;
padding: 0 14px;
gap: 3px;
}
.tab {
height: 37px;
padding: 0 15px;
display: flex;
align-items: center;
color: #6b7280;
border-bottom: 2px solid transparent;
}
.tab.active {
color: var(--primary);
border-bottom-color: var(--primary);
}
/* content */
.content {
flex: 1;
min-height: 0;
overflow: auto;
padding: 14px;
}
/* =========================
Page header
========================= */
.page-header {
height: 36px;
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 10px;
}
.page-title {
font-size: 16px;
font-weight: 600;
}
.actions {
display: flex;
gap: 7px;
}
.btn {
height: 32px;
padding: 0 12px;
border: 1px solid var(--border);
border-radius: 5px;
background: white;
color: #374151;
}
.btn:hover {
background: #f9fafb;
}
.btn-primary {
background: var(--primary);
border-color: var(--primary);
color: white;
}
.btn-primary:hover {
background: #1d4ed8;
}
/* =========================
Search
========================= */
.search-panel {
background: white;
border: 1px solid var(--border);
border-radius: 6px;
padding: 10px 12px;
}
.search-row {
display: grid;
grid-template-columns:
minmax(190px, 1.4fr)
minmax(150px, 1fr)
minmax(130px, .8fr)
minmax(150px, 1fr)
auto;
gap: 8px;
align-items: center;
}
.form-item {
display: flex;
align-items: center;
min-width: 0;
}
.form-label {
color: #6b7280;
margin-right: 7px;
white-space: nowrap;
}
.input,
.select {
width: 100%;
height: var(--control-height);
border: 1px solid #d9dde3;
border-radius: 4px;
padding: 0 9px;
outline: none;
background: white;
color: #374151;
}
.input:focus,
.select:focus {
border-color: #93c5fd;
box-shadow: 0 0 0 2px rgba(37,99,235,.08);
}
.search-actions {
display: flex;
gap: 6px;
}
.more-btn {
color: #2563eb;
border: none;
background: transparent;
padding: 0 5px;
white-space: nowrap;
}
/* saved search */
.saved-row {
display: flex;
align-items: center;
margin-top: 9px;
padding-top: 8px;
border-top: 1px solid var(--border-light);
min-height: 29px;
}
.saved-label {
color: #9ca3af;
margin-right: 8px;
}
.saved-item {
height: 25px;
padding: 0 9px;
border-radius: 4px;
display: flex;
align-items: center;
color: #4b5563;
cursor: pointer;
margin-right: 3px;
}
.saved-item:hover {
background: #f3f4f6;
}
.saved-item.active {
color: var(--primary);
background: var(--primary-soft);
}
/* =========================
Status Tabs
========================= */
.status-tabs {
margin-top: 10px;
height: 40px;
background: white;
border: 1px solid var(--border);
border-radius: 6px;
display: flex;
align-items: stretch;
padding: 0 8px;
}
.status-tab {
padding: 0 15px;
display: flex;
align-items: center;
color: #6b7280;
border-bottom: 2px solid transparent;
cursor: pointer;
}
.status-tab:hover {
color: var(--text);
}
.status-tab.active {
color: var(--primary);
border-bottom-color: var(--primary);
font-weight: 500;
}
.count {
margin-left: 5px;
color: #9ca3af;
font-size: 12px;
}
/* =========================
Table
========================= */
.table-panel {
margin-top: 10px;
background: white;
border: 1px solid var(--border);
border-radius: 6px;
overflow: hidden;
}
.table-toolbar {
height: 40px;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 12px;
border-bottom: 1px solid var(--border);
}
.result-info {
color: #6b7280;
}
.toolbar-actions {
display: flex;
gap: 12px;
color: #6b7280;
}
table {
width: 100%;
border-collapse: collapse;
}
thead {
background: #fafafa;
}
th {
height: 38px;
padding: 0 10px;
text-align: left;
font-weight: 500;
color: #4b5563;
border-bottom: 1px solid var(--border);
white-space: nowrap;
}
td {
height: 40px;
padding: 0 10px;
border-bottom: 1px solid var(--border-light);
white-space: nowrap;
}
tbody tr:hover {
background: #fafcff;
}
.checkbox {
width: 15px;
height: 15px;
}
.link {
color: var(--primary);
cursor: pointer;
}
.status {
display: inline-flex;
align-items: center;
padding: 2px 7px;
border-radius: 3px;
font-size: 12px;
}
.status.pending {
background: #fff7ed;
color: #c2410c;
}
.status.approved {
background: #ecfdf5;
color: #047857;
}
.status.draft {
background: #f3f4f6;
color: #6b7280;
}
/* =========================
Drawer
========================= */
.overlay {
position: fixed;
inset: 0;
background: rgba(15, 23, 42, .18);
display: none;
z-index: 20;
}
.overlay.show {
display: block;
}
.drawer {
position: absolute;
right: 0;
top: 0;
bottom: 0;
width: 590px;
background: white;
box-shadow: -8px 0 30px rgba(0,0,0,.12);
display: flex;
flex-direction: column;
}
.drawer-header {
height: 52px;
padding: 0 18px;
display: flex;
align-items: center;
justify-content: space-between;
border-bottom: 1px solid var(--border);
}
.drawer-title {
font-size: 15px;
font-weight: 600;
}
.close {
width: 28px;
height: 28px;
border: none;
background: transparent;
color: #6b7280;
font-size: 20px;
}
.drawer-body {
flex: 1;
overflow-y: auto;
padding: 16px;
}
.condition-group {
border: 1px solid var(--border);
border-radius: 6px;
margin-bottom: 12px;
}
.group-header {
height: 36px;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 10px;
background: #fafafa;
border-bottom: 1px solid var(--border);
font-weight: 500;
}
.condition {
display: grid;
grid-template-columns: 120px 110px 1fr 28px;
gap: 7px;
padding: 9px 10px;
align-items: center;
}
.logic {
padding: 0 10px 5px;
color: #9ca3af;
font-size: 12px;
}
.delete {
width: 27px;
height: 27px;
border: none;
background: transparent;
color: #9ca3af;
font-size: 16px;
}
.delete:hover {
color: var(--danger);
}
.add-condition {
padding: 0 10px 10px;
}
.add-condition button {
border: 1px dashed #cbd5e1;
background: white;
color: var(--primary);
width: 100%;
height: 31px;
border-radius: 4px;
}
.drawer-footer {
height: 58px;
border-top: 1px solid var(--border);
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 16px;
}
.footer-left {
display: flex;
gap: 8px;
}
.footer-right {
display: flex;
gap: 8px;
}
/* save query modal */
.modal-overlay {
position: fixed;
inset: 0;
background: rgba(15, 23, 42, .25);
display: none;
align-items: center;
justify-content: center;
z-index: 30;
}
.modal-overlay.show {
display: flex;
}
.modal {
width: 430px;
background: white;
border-radius: 7px;
box-shadow: 0 20px 50px rgba(0,0,0,.18);
}
.modal-header {
height: 48px;
padding: 0 16px;
border-bottom: 1px solid var(--border);
display: flex;
align-items: center;
justify-content: space-between;
font-weight: 600;
}
.modal-body {
padding: 18px 16px;
}
.modal-footer {
height: 58px;
padding: 0 16px;
border-top: 1px solid var(--border);
display: flex;
align-items: center;
justify-content: flex-end;
gap: 8px;
}
.full-input {
width: 100%;
}
.help {
margin-top: 7px;
color: #9ca3af;
font-size: 12px;
}
/* responsive */
@media (max-width: 1200px) {
.sidebar {
width: 180px;
}
.search-row {
grid-template-columns:
1.2fr
1fr
1fr
auto;
}
.search-row .form-item:nth-child(4) {
display: none;
}
}
</style>
</head>
<body>
<div class="app">
<!-- Sidebar -->
<aside class="sidebar">
<div class="logo">
<div class="logo-mark">F</div>
FMS ERP
</div>
<div class="menu">
<div class="menu-group">
<div class="menu-title">业务管理</div>
<div class="menu-item">
<span class="menu-icon">▣</span>
工作台
</div>
<div class="menu-item active">
<span class="menu-icon">▤</span>
订舱管理
</div>
<div class="menu-item">
<span class="menu-icon">□</span>
船期管理
</div>
<div class="menu-item">
<span class="menu-icon">◫</span>
集装箱管理
</div>
</div>
<div class="menu-group">
<div class="menu-title">财务管理</div>
<div class="menu-item">
<span class="menu-icon">¥</span>
费用管理
</div>
<div class="menu-item">
<span class="menu-icon">▤</span>
应收管理
</div>
</div>
<div class="menu-group">
<div class="menu-title">基础资料</div>
<div class="menu-item">
<span class="menu-icon">◇</span>
客户档案
</div>
<div class="menu-item">
<span class="menu-icon">◇</span>
船公司
</div>
</div>
</div>
</aside>
<!-- Main -->
<main class="main">
<!-- Topbar -->
<header class="topbar">
<div class="topbar-left">
<span>☰</span>
<span class="org">上海分公司</span>
</div>
<div class="topbar-right">
<span>◌</span>
<span>⚙</span>
<span>帮助</span>
<div class="avatar">张</div>
</div>
</header>
<!-- Tabs -->
<div class="tabs">
<div class="tab active">
订舱单
</div>
<div class="tab">
船期
</div>
<div class="tab">
客户档案
</div>
</div>
<!-- Content -->
<section class="content">
<!-- Page header -->
<div class="page-header">
<div class="page-title">
订舱单
</div>
<div class="actions">
<button class="btn">导入</button>
<button class="btn">导出</button>
<button class="btn btn-primary">+ 新增</button>
</div>
</div>
<!-- Search -->
<div class="search-panel">
<div class="search-row">
<div class="form-item">
<span class="form-label">关键词</span>
<input
class="input"
placeholder="单号 / 客户 / 船名"
/>
</div>
<div class="form-item">
<span class="form-label">客户</span>
<input
class="input"
placeholder="请选择客户"
/>
</div>
<div class="form-item">
<span class="form-label">状态</span>
<select class="select">
<option>全部状态</option>
<option>待提交</option>
<option>待审核</option>
<option>已审核</option>
<option>已取消</option>
</select>
</div>
<div class="form-item">
<span class="form-label">ETD</span>
<input
class="input"
placeholder="日期范围"
/>
</div>
<div class="search-actions">
<button class="btn btn-primary">查询</button>
<button
class="more-btn"
onclick="openDrawer()"
>
更多条件
</button>
</div>
</div>
<!-- Saved queries -->
<div class="saved-row">
<span class="saved-label">
我的查询
</span>
<div class="saved-item active">
全部
</div>
<div class="saved-item">
我的待处理
</div>
<div class="saved-item">
本月待审核
</div>
<div class="saved-item">
华东客户
</div>
<div
class="saved-item"
onclick="openSaveModal()"
>
+ 保存当前条件
</div>
</div>
</div>
<!-- Status tabs -->
<div class="status-tabs">
<div class="status-tab active">
全部
<span class="count">326</span>
</div>
<div class="status-tab">
待提交
<span class="count">18</span>
</div>
<div class="status-tab">
待审核
<span class="count">32</span>
</div>
<div class="status-tab">
已审核
<span class="count">241</span>
</div>
<div class="status-tab">
已取消
<span class="count">35</span>
</div>
</div>
<!-- Table -->
<div class="table-panel">
<div class="table-toolbar">
<div class="result-info">
共 326 条
</div>
<div class="toolbar-actions">
<span>列设置</span>
<span>刷新</span>
<span>密度</span>
</div>
</div>
<table>
<thead>
<tr>
<th style="width:35px;">
<input type="checkbox" class="checkbox">
</th>
<th>订舱单号</th>
<th>客户</th>
<th>船公司</th>
<th>船名 / 航次</th>
<th>ETD</th>
<th>ETA</th>
<th>业务员</th>
<th>状态</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<input type="checkbox" class="checkbox">
</td>
<td class="link">BK20260929001</td>
<td>上海 XX 国际物流</td>
<td>MAERSK</td>
<td>MSC MIA / 023W</td>
<td>2026-09-30</td>
<td>2026-10-25</td>
<td>张三</td>
<td>
<span class="status pending">待审核</span>
</td>
</tr>
<tr>
<td>
<input type="checkbox" class="checkbox">
</td>
<td class="link">BK20260929002</td>
<td>宁波 XX 供应链</td>
<td>MSC</td>
<td>MSC LISA / 118E</td>
<td>2026-10-02</td>
<td>2026-10-28</td>
<td>李四</td>
<td>
<span class="status approved">已审核</span>
</td>
</tr>
<tr>
<td>
<input type="checkbox" class="checkbox">
</td>
<td class="link">BK20260929003</td>
<td>杭州 XX 贸易</td>
<td>CMA</td>
<td>CMA CGM / 086W</td>
<td>2026-10-04</td>
<td>2026-10-29</td>
<td>王五</td>
<td>
<span class="status draft">草稿</span>
</td>
</tr>
<tr>
<td>
<input type="checkbox" class="checkbox">
</td>
<td class="link">BK20260929004</td>
<td>上海 XX 实业</td>
<td>EVERGREEN</td>
<td>EVER ALPHA / 062W</td>
<td>2026-10-06</td>
<td>2026-11-01</td>
<td>张三</td>
<td>
<span class="status approved">已审核</span>
</td>
</tr>
<tr>
<td>
<input type="checkbox" class="checkbox">
</td>
<td class="link">BK20260929005</td>
<td>苏州 XX 科技</td>
<td>ONE</td>
<td>ONE HARMONY / 031W</td>
<td>2026-10-08</td>
<td>2026-11-02</td>
<td>赵六</td>
<td>
<span class="status pending">待提交</span>
</td>
</tr>
</tbody>
</table>
</div>
</section>
</main>
</div>
<!-- =========================
More Conditions Drawer
========================= -->
<div
id="overlay"
class="overlay"
onclick="closeDrawer()"
>
<aside
class="drawer"
onclick="event.stopPropagation()"
>
<div class="drawer-header">
<div class="drawer-title">
更多条件
</div>
<button
class="close"
onclick="closeDrawer()"
>
×
</button>
</div>
<div class="drawer-body">
<!-- Group 1 -->
<div class="condition-group">
<div class="group-header">
基本条件
</div>
<div class="condition">
<select class="select">
<option>订舱单号</option>
<option>客户</option>
<option>业务员</option>
</select>
<select class="select">
<option>等于</option>
<option>包含</option>
<option>不等于</option>
</select>
<input
class="input"
placeholder="请输入"
/>
<button class="delete">
×
</button>
</div>
<div class="logic">
AND
</div>
<div class="condition">
<select class="select">
<option>客户</option>
<option>订舱单号</option>
<option>业务员</option>
</select>
<select class="select">
<option>等于</option>
<option>包含</option>
<option>不等于</option>
</select>
<input
class="input"
placeholder="请选择客户"
/>
<button class="delete">
×
</button>
</div>
<div class="logic">
AND
</div>
<div class="condition">
<select class="select">
<option>ETD</option>
<option>ETA</option>
<option>创建时间</option>
</select>
<select class="select">
<option>大于等于</option>
<option>等于</option>
<option>小于等于</option>
<option>区间</option>
</select>
<input
class="input"
placeholder="2026-09-01"
/>
<button class="delete">
×
</button>
</div>
<div class="add-condition">
<button>
+ 添加条件
</button>
</div>
</div>
<!-- Group 2 -->
<div class="condition-group">
<div class="group-header">
<span>
高级条件组
</span>
<span style="color:#9ca3af;font-size:12px;">
OR
</span>
</div>
<div class="condition">
<select class="select">
<option>船公司</option>
<option>船名</option>
<option>航次</option>
</select>
<select class="select">
<option>等于</option>
<option>包含</option>
</select>
<input
class="input"
value="MAERSK"
/>
<button class="delete">
×
</button>
</div>
<div class="logic">
OR
</div>
<div class="condition">
<select class="select">
<option>船公司</option>
<option>船名</option>
<option>航次</option>
</select>
<select class="select">
<option>等于</option>
<option>包含</option>
</select>
<input
class="input"
value="MSC"
/>
<button class="delete">
×
</button>
</div>
<div class="add-condition">
<button>
+ 添加条件
</button>
</div>
</div>
<!-- Other fields -->
<div class="condition-group">
<div class="group-header">
其他字段
</div>
<div class="condition">
<select class="select">
<option>目的港</option>
<option>起运港</option>
<option>贸易方式</option>
<option>箱型</option>
</select>
<select class="select">
<option>等于</option>
<option>包含</option>
</select>
<input
class="input"
placeholder="请输入"
/>
<button class="delete">
×
</button>
</div>
<div class="add-condition">
<button>
+ 添加条件
</button>
</div>
</div>
</div>
<div class="drawer-footer">
<div class="footer-left">
<button
class="btn"
onclick="openSaveModal()"
>
保存查询
</button>
<button class="btn">
重置
</button>
</div>
<div class="footer-right">
<button
class="btn"
onclick="closeDrawer()"
>
取消
</button>
<button
class="btn btn-primary"
onclick="closeDrawer()"
>
应用条件
</button>
</div>
</div>
</aside>
</div>
<!-- =========================
Save Query Modal
========================= -->
<div
id="saveModal"
class="modal-overlay"
onclick="closeSaveModal()"
>
<div
class="modal"
onclick="event.stopPropagation()"
>
<div class="modal-header">
<span>
保存查询
</span>
<button
class="close"
onclick="closeSaveModal()"
>
×
</button>
</div>
<div class="modal-body">
<div
style="
color:#6b7280;
margin-bottom:8px;
"
>
查询名称
</div>
<input
class="input full-input"
placeholder="例如:本月待审核"
/>
<div class="help">
保存后可以直接从「我的查询」快速使用。
</div>
</div>
<div class="modal-footer">
<button
class="btn"
onclick="closeSaveModal()"
>
取消
</button>
<button
class="btn btn-primary"
onclick="closeSaveModal()"
>
保存
</button>
</div>
</div>
</div>
<script>
function openDrawer() {
document
.getElementById("overlay")
.classList.add("show");
}
function closeDrawer() {
document
.getElementById("overlay")
.classList.remove("show");
}
function openSaveModal() {
document
.getElementById("saveModal")
.classList.add("show");
}
function closeSaveModal() {
document
.getElementById("saveModal")
.classList.remove("show");
}
/* 状态页签 */
document
.querySelectorAll(".status-tab")
.forEach(tab => {
tab.addEventListener("click", () => {
document
.querySelectorAll(".status-tab")
.forEach(item => {
item.classList.remove("active");
});
tab.classList.add("active");
});
});
/* 我的查询 */
document
.querySelectorAll(".saved-item")
.forEach(item => {
item.addEventListener("click", () => {
if (item.textContent.includes("保存")) {
return;
}
document
.querySelectorAll(".saved-item")
.forEach(i => {
i.classList.remove("active");
});
item.classList.add("active");
});
});
</script>
</body>
</html>
```