feat(UI): 四 Tab 头部统一 + 清单模板分类 + 宏观 tab 顺序与溢出提示

头部统一
- 新增 PageHeader 组件: 高度 23px (原 NavBar 45px 的一半), 标题 12px 主色加粗, 背景取页面底色
- 打卡 / 宏观 / 监控 三页各自引用, 互不影响; 宏观与监控补齐「宏观」「监控」标题
- 「我」页移除 NavBar 空白条, 蓝色头像区直接贴顶 (不引用 PageHeader, 与其余三页解耦)
- 清理失效样式 .me-navbar

清单模板分类
- 分段由 2 项扩为 3 项: 进行中 / 已归档 / 模板; 右上角按钮随分段切换
- 模板独立增删改查: 新增 GET /templates/:id、PUT /templates/:id; 预置模板拒绝改删
- 模板按名称字母顺序排序 (Intl.Collator zh-Hans-CN, 中文按拼音/数字按数值), 前后端同口径
- 新建清单去掉场景选择器, 仅保留名称; scene 改为沿用模板自带场景
- 模板改为从右侧滑出 78vw 面板选择, 首项「不使用模板」

宏观 tab
- 顺序改为 报警 → 新闻 → 油价 → 经济数据 → 策略研究 → 经济文章, 默认选中新闻
- /macro 由路由直接重定向到 /macro/news, activeFromPath 兜底同样返回 news
- SwipeTabs 增加右侧溢出提示: 渐变遮罩 + 主色圆底箭头, 可点击向右翻页, 滚到末尾自动消失
- 切换 tab 时自动把激活项滚到可视区中央
This commit is contained in:
cheney
2026-10-23 16:40:32 +08:00
parent 5f41cb05b7
commit c765755906
11 changed files with 623 additions and 136 deletions
+129 -3
View File
@@ -67,12 +67,31 @@ input, textarea, select { font: inherit; }
to { opacity: 1; transform: translateY(0); }
}
/* 带有 antd-mobile NavBar 的页面 (Home/Monitor/Macro/Article) */
/* 带有页面头部的页面 (Checkin/Monitor/Macro) */
/* height:100% 让页面占满 app-main 高度, 内部 tab-content 独立滚动,
头部 NavBar 与分类 tab 固定在顶部不上滚 */
头部与分类 tab 固定在顶部不上滚 */
.page-with-navbar { display: flex; flex-direction: column; height: 100%; min-height: 0; }
.page-with-navbar .adm-error-block { flex: 1; }
/* 统一主 Tab 头部 (打卡 / 宏观 / 监控): 原 NavBar 45px → 23px, 标题主色小字
注意: 「我」页不使用此头部, 见 MePage (顶部直接是头像区) */
.page-header {
height: 23px;
flex: 0 0 23px;
display: flex;
align-items: center;
justify-content: center;
background: var(--color-bg);
overflow: hidden;
}
.page-header-title {
font-size: 12px;
line-height: 1;
font-weight: 600;
letter-spacing: 1px;
color: var(--color-primary);
}
/* 底部 antd-mobile TabBar 定位 */
.app-tabbar.adm-tab-bar {
position: fixed;
@@ -92,11 +111,53 @@ input, textarea, select { font: inherit; }
/* 宏观页 SwipeTabs */
.swipe-tabs-wrap {
position: relative;
display: flex;
flex-direction: column;
flex: 1 1 auto;
min-height: 0;
}
/* tab 条右侧溢出提示: 渐变遮罩 + 箭头, 表示右边还有未展示的 tab
遮罩宽度留足, 让被截断的 tab 文字淡出而不是被箭头压住 */
.swipe-tabs-wrap .adm-tabs-header {
position: relative;
background: var(--color-card);
}
.swipe-tabs-wrap .adm-tabs-tab-wrapper { padding: 0 10px; }
.tab-more-hint {
position: absolute;
top: 0;
right: 0;
height: 45px;
width: 58px;
z-index: 3;
display: flex;
align-items: center;
justify-content: flex-end;
padding-right: 6px;
cursor: pointer;
background: linear-gradient(to right, rgba(255,255,255,0) 0%, #fff 62%, #fff 100%);
}
.tab-more-arrow {
display: inline-flex;
align-items: center;
justify-content: center;
width: 19px;
height: 19px;
border-radius: 50%;
background: #fff;
border: 1px solid #e3e6ea;
color: var(--color-primary);
font-size: 14px;
line-height: 1;
font-weight: 700;
box-shadow: 0 1px 4px rgba(0,0,0,.14);
animation: tab-more-nudge 1.5s ease-in-out infinite;
}
@keyframes tab-more-nudge {
0%, 100% { transform: translateX(0); }
50% { transform: translateX(3px); }
}
.tab-content {
flex: 1 1 auto;
min-height: 0;
@@ -200,8 +261,8 @@ input, textarea, select { font: inherit; }
.login-error { background: #fef2f2; color: var(--color-danger); padding: 10px; border-radius: 6px; font-size: 13px; margin-bottom: 12px; }
/* ================== 我的页 ================== */
/* 「我」页不设顶部头部条: 头像区直接贴顶 (2026-10-23 界面调整) */
.me-page { display: flex; flex-direction: column; min-height: 100%; background: var(--color-bg); }
.me-navbar.adm-nav-bar { background: #fff; border-bottom: 1px solid var(--color-border); }
.me-profile { background: linear-gradient(135deg, #1677ff, #4096ff); color: #fff; padding: 24px 16px 28px; display: flex; flex-direction: column; align-items: center; gap: 6px; }
.me-avatar { background: rgba(255,255,255,.2); color: #fff; font-size: 28px; }
.me-name { font-size: 18px; font-weight: 600; }
@@ -652,6 +713,71 @@ input, textarea, select { font: inherit; }
.checklist-add .adm-input { flex: 1; border: 1px solid var(--color-border); border-radius: 6px; padding: 6px 8px; }
.checklist-actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 10px; }
/* ----- 模板分类 (清单的第三个分段: 进行中 / 已归档 / 模板) ----- */
.template-wrap { display: flex; flex-direction: column; gap: 10px; }
.template-card {
background: #fff; border-radius: 10px; padding: 12px;
box-shadow: 0 1px 2px rgba(0,0,0,.04);
}
.template-head { display: flex; align-items: center; gap: 8px; }
.template-name { font-size: 15px; font-weight: 600; color: var(--color-text); word-break: break-all; }
.template-badge {
font-size: 10px; color: var(--color-muted); background: #f2f3f5;
border-radius: 4px; padding: 1px 5px; flex-shrink: 0;
}
.template-count { margin-left: auto; font-size: 11px; color: var(--color-muted); flex-shrink: 0; }
.template-items { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.template-item-chip {
font-size: 11px; color: var(--color-muted); background: #f7f8fa;
border-radius: 4px; padding: 2px 7px; max-width: 100%;
overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.template-item-chip.more { color: var(--color-primary); background: #f0f5ff; }
.template-actions {
display: flex; flex-wrap: wrap; gap: 14px; margin-top: 10px;
padding-top: 8px; border-top: 1px dashed var(--color-border);
}
/* 新建清单: 模板行 (点击后从右侧滑出选择面板) */
.template-pick-row {
display: flex; align-items: center; gap: 8px; cursor: pointer;
border: 1px solid var(--color-border); border-radius: 8px; padding: 8px 10px;
}
.template-pick-row:active { background: #fafafa; }
.template-pick-name { flex: 1; font-size: 14px; color: var(--color-text); }
.template-pick-name.placeholder { color: #b8bcc4; }
.template-pick-meta { display: inline-flex; align-items: center; gap: 4px; font-size: 12px; color: var(--color-muted); }
.template-pick-arrow { font-size: 16px; line-height: 1; color: #c8c8c8; }
/* 模板选择面板 (右侧滑出) */
.tpl-picker { display: flex; flex-direction: column; height: 100%; padding: 14px 0 0; }
.tpl-picker-head { display: flex; align-items: center; padding: 0 16px 6px; }
.tpl-picker-title { font-size: 16px; font-weight: 700; color: var(--color-text); }
.tpl-picker-close { margin-left: auto; font-size: 22px; line-height: 1; color: #c8c8c8; cursor: pointer; padding: 0 4px; }
.tpl-picker-tip { font-size: 11px; color: var(--color-muted); padding: 0 16px 8px; }
.tpl-picker-list { flex: 1 1 auto; min-height: 0; overflow-y: auto; padding: 0 10px 16px; }
.tpl-picker-item {
display: flex; align-items: baseline; gap: 8px; padding: 11px 10px;
border-radius: 8px; cursor: pointer;
}
.tpl-picker-item:active { background: #f5f6f8; }
.tpl-picker-item.active { background: #f0f5ff; }
.tpl-picker-name {
flex: 1; font-size: 14px; font-weight: 600; color: var(--color-text);
display: inline-flex; align-items: center; gap: 6px; word-break: break-all;
}
.tpl-picker-item.active .tpl-picker-name { color: var(--color-primary); }
.tpl-picker-sub { font-size: 11px; color: var(--color-muted); flex-shrink: 0; }
.tpl-picker-empty { padding: 40px 0; text-align: center; font-size: 13px; color: var(--color-muted); }
/* 模板编辑弹层 */
.tpl-edit-items { display: flex; flex-direction: column; gap: 6px; }
.tpl-edit-item { display: flex; align-items: center; gap: 8px; }
.tpl-edit-index { width: 18px; text-align: right; font-size: 11px; color: var(--color-muted); flex-shrink: 0; }
.tpl-edit-item .adm-input {
flex: 1; border: 1px solid var(--color-border); border-radius: 6px; padding: 6px 8px;
}
/* ----- 表单弹窗 (打卡项 / 清单) ----- */
.form-popup { padding: 16px 16px 8px; }
.form-title { font-size: 16px; font-weight: 700; color: var(--color-text); margin-bottom: 12px; }