feat: 餐线营养秤双屏取餐页合并 + 收银设备全流程原型补齐
- 餐线营养秤:合并 dual-large/dual-small 两页为单页 03-meal-pickup-dual.html(左右双屏同页布局) - 餐线营养秤:5 个二级页面(01/04/05/06/03)统一返回按钮 history.back() 兜底逻辑 - 餐线营养秤:02-dish-display 与 03-meal-pickup 样式重构(信息卡双行布局、菜品行价格靠右) - 收银设备:新增 9 个收银员屏页面(01-login ~ 09-print-receipt,覆盖登录/待机/收银/支付成功/订单/详情/统计/对账/小票) - 收银设备:新增 4 个用户屏页面(user-01-idle ~ user-04-success,覆盖待机/同步/支付/成功) - 收银设备:index 重构为左右双屏(用户屏/收银员屏)布局 - 同步更新记忆索引、项目进度与 lint 报告 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.7
parent
a7e0e02945
commit
51661ab127
@@ -1,10 +1,10 @@
|
||||
_Last synced: 2026-08-05 | Base commit: `d00208a`_
|
||||
_Last synced: 2026-08-06 | Base commit: `445d824`_
|
||||
|
||||
# 记忆索引
|
||||
| 文件 | 描述 | 类型 | 最后更新 |
|
||||
|------|------|------|----------|
|
||||
| project_overview.md | 项目技术栈、架构与模块结构 | project | 2026-05-14 |
|
||||
| project_progress.md | 各模块原型开发进度 | project | 2026-08-05 |
|
||||
| project_progress.md | 各模块原型开发进度 | project | 2026-08-06 |
|
||||
| decisions.md | 关键设计决策与架构约定 | project | 2026-08-05 |
|
||||
| feedback.md | 协作规范与用户纠正记录 | feedback | 2026-06-15 |
|
||||
| user_profile.md | 用户角色与偏好 | user | 2026-04-21 |
|
||||
|
||||
@@ -2,12 +2,12 @@
|
||||
name: 记忆健康检查报告
|
||||
description: memory-lint 最新一次执行的检查结果与待处理项
|
||||
type: lint
|
||||
last_updated: 2026-08-05
|
||||
last_updated: 2026-08-06
|
||||
---
|
||||
|
||||
# 记忆健康检查报告
|
||||
|
||||
> _执行时间: 2026-08-05 | Base commit: `d00208a` | Last synced: 2026-08-05_
|
||||
> _执行时间: 2026-08-06 | Base commit: `445d824` | Last synced: 2026-08-06_
|
||||
|
||||
## 健康概览
|
||||
|
||||
@@ -18,11 +18,11 @@ last_updated: 2026-08-05
|
||||
| 引用存在性检测(3A) | ✅ | 0 | 0 |
|
||||
| 双链对称性检测(3B) | ✅ | 0 | 0 |
|
||||
| 内容矛盾检测 | ✅ | — | 0 |
|
||||
| 过期检测 | ⚠ | — | 2 待处理 |
|
||||
| 过期检测 | ⚠ | — | 3 待处理 |
|
||||
| 可推断内容污染 | ⚠ | — | 1 待处理 |
|
||||
| frontmatter 完整性 | ⚠ | — | 4 待处理 |
|
||||
|
||||
**AUTO-FIX 已执行 0 项 | NEED-HUMAN 待处理 7 项**
|
||||
**AUTO-FIX 已执行 0 项 | NEED-HUMAN 待处理 8 项**
|
||||
|
||||
---
|
||||
|
||||
@@ -30,18 +30,23 @@ last_updated: 2026-08-05
|
||||
|
||||
### [ERROR] 严重过期 — user_profile.md
|
||||
|
||||
- **文件**:`user_profile.md`(last_updated: 2026-04-21,距今 106 天,超过 90 天 ERROR 阈值)
|
||||
- **文件**:`user_profile.md`(last_updated: 2026-04-21,距今 107 天,超过 90 天 ERROR 阈值)
|
||||
- **建议**:确认用户角色/偏好是否有变化,执行 `/memory-update` 更新。
|
||||
|
||||
### [WARN] 过期 — feedback.md
|
||||
|
||||
- **文件**:`feedback.md`(last_updated: 2026-06-15,距今 51 天,超 30 天 WARN 阈值)
|
||||
- **文件**:`feedback.md`(last_updated: 2026-06-15,距今 52 天,超 30 天 WARN 阈值)
|
||||
- **建议**:确认是否有新的协作规范需要记录。
|
||||
|
||||
### [WARN] 过期 — project_overview.md
|
||||
|
||||
- **文件**:`project_overview.md`(last_updated: 2026-05-14,距今 84 天,超 30 天 WARN 阈值,临近 90 天 ERROR)
|
||||
- **建议**:确认项目技术栈/架构是否有变化需要同步。
|
||||
|
||||
### [WARN] 可推断内容污染 — project_progress.md
|
||||
|
||||
- **文件**:`project_progress.md` 第 110~145 行「近期里程碑」区段
|
||||
- **问题**:含具体文件路径列表(如 `canteen-nutrition-scale/02-dish-display.html`、`prod-clean-order`/`sup-clean-external`/`sup-clean-internal`)和 commit message 风格描述,按 memory-update 规则「Git 历史(可用 git log 查)」不应写入记忆文件
|
||||
- **文件**:`project_progress.md` 第 108~145 行「近期里程碑」区段
|
||||
- **问题**:含具体文件路径列表(如 `canteen-nutrition-scale/02-dish-display.html`、`prod-clean-order`/`sup-clean-external`/`sup-clean-internal`、`din-ingredient-add.html` 等)和 commit message 风格描述,按 memory-update 规则「Git 历史(可用 git log 查)」不应写入记忆文件
|
||||
- **建议**:保留里程碑结论,删除具体文件路径与 commit message 流水,让用户能通过 `git log` 自查细节。
|
||||
|
||||
### [WARN] frontmatter 缺失 — 4 个文件
|
||||
@@ -60,4 +65,4 @@ last_updated: 2026-08-05
|
||||
|
||||
- `decisions.md#餐厅终端设备 PAD 居中外壳设计模式` → `[[feedback.md#PAD 终端页面内禁止可见滚动条]]` ✅ 目标存在,双向闭环
|
||||
- `feedback.md#PAD 终端页面内禁止可见滚动条` → `[[decisions.md#餐厅终端设备 PAD 居中外壳设计模式]]` ✅ 目标存在,双向闭环
|
||||
- `decisions.md#规格体系统一化改造` → `[[feedback.md]]` ✅ 目标存在(占位引用「暂无直接关联条目」)
|
||||
- `decisions.md#规格体系统一化改造` → `[[feedback.md]]` ✅ 目标存在(占位引用「暂无直接关联条目」,非对称但属预期)
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
name: 项目进度
|
||||
description: 各模块原型开发进度与里程碑
|
||||
type: project
|
||||
last_updated: 2026-08-05
|
||||
commit: d00208a
|
||||
last_updated: 2026-08-06
|
||||
commit: 445d824
|
||||
---
|
||||
|
||||
# 项目进度
|
||||
@@ -105,6 +105,7 @@ Web 管理端和员工端 APP 的其余模块(系统管理、运动管理、
|
||||
- 覆盖模块:18 个(含三端+其他终端)
|
||||
|
||||
## 近期里程碑
|
||||
- 2026-08-06:食材档案新增「基础定价」字段 + 净菜订单按餐次核算人数与「生成中」状态(commit 445d824)——①`din-ingredient.html`/`din-ingredient-add.html` 食材档案新增 `basePrice` 字段(元/100g),列表详情区与新增/编辑/复制三形态同步(input 含「元/100g」内联单位后缀);②`prod-clean-order.html` 由食谱快速创建订单弹窗重构:移除顶部全局人数输入框与「订单汇总」预览区、当日食谱表格新增「就餐人数」列(每餐次独立 input 4 个)、新增预定配送时间字段(datetime-local,默认次日 10:00)、新增 `validateMealDinerCounts()` 校验、份数计算改为按各餐次人数累加、由食谱创建的订单 `lines[].status` 初始置为「生成中」;③新增「生成中」订单状态全链路:青色脉冲呼吸动效 `.tag-cyan` + `@keyframes statusPulse`、`aggregateStatus()` 聚合规则、状态筛选下拉、统计卡片、订单操作列「生成完成」入口(流转到「备货中」)、智能核算提示语 `.recipe-tip`。同日 `din-dish-add/all/own.html` 三页定价区继续微调(与 2026-08-05/06 定价区改造一脉相承)。
|
||||
- 2026-08-05:餐线营养秤菜品展示页新增视频演示模式 + 净菜订单/申领三页统一订单金额字段(commit d00208a)——①`canteen-nutrition-scale/02-dish-display.html` 新增演示模式切换 pill(常规/视频)与视频模式布局(上视频+下信息卡,680px 16:9 视频播放器含播放按钮/控制条,下方菜品名+营养指标信息卡),通过 `main-area.mode-video` 状态类控制 CSS 布局切换;②`web-admin/nutrition` 净菜三页(`prod-clean-order`/`sup-clean-external`/`sup-clean-internal`)统一增加订单金额字段:订单明细 `lines[]` 每项新增 `price` 与 `subtotal` 字段、列表表头新增「订单金额」列、弹窗移除「汇总预览」表格改为底部灰底「订单总金额」栏(`#orderTotalAmount`/`#extTotalAmount`/`#claimTotalAmount`)、新增 `calcOrderTotal(o)` 与 `formatMoney(n)` 工具函数(`¥1,234.5` 千分位 + 最多 2 位小数)。
|
||||
- 2026-08-05:规格体系统一化改造阶段四(设备端)+ 阶段五(辅助页)全部完成(commit 4fd44f1)——阶段四覆盖设备端 9 任务 14 文件:①毛菜验收秤 `verifyType` 字段(weight/count)+ UNIT_OPTIONS 分类;②毛菜加工秤 4 页存储层斤→克、`formatGram` 展示层兼容、`yieldRate` 字段、04-history 语法错误修复;③净菜加工秤设置页删除"重量单位"select、滚刀块 cm→mm;④净菜包装贴标秤 3 页(最复杂)5 个工具函数内联、`cutSpec`/`packSpec` 全部结构化、`portions`→`packSize` 重命名;⑤净菜组配秤 3 页工具函数内联 + `localStorage['dish_specs_v1']` 跨页共享 + `resolvePackSpec` 兜底。阶段五覆盖辅助页 3 任务 6 文件:①营养质控 3 页(confirmSync 真落地写入餐品总库、菜品下拉跨页共享、同步日志驱动);②分析页字典语义修正(`sup-process-analysis` 切配线"切丝"→"丝"形状名词、新增独立 `pack_method` 字典;`sup-biz-analysis` 投料/产出吨→kg 对齐);③净菜进柜 `prod-proc-cabinet` 的 `spec` 多形态字符串结构化(含决策点 #10:`'6份/箱'` 理解为 6 个份型单位装一箱)。新增权威源 `doc/spec-utils-reference.md`、改造任务清单与研发同步说明。阶段四+五完成标志着规格体系统一化五个阶段全部完成。
|
||||
- 2026-08-05:体重管理新增 `eat-exercise-detail-v2.html`(饮食运动详情 v2);西安中心应急大屏迭代至 `index-v4.html`。
|
||||
|
||||
Generated
+27
-4
@@ -7,7 +7,7 @@
|
||||
<value>
|
||||
<TabSessionState>
|
||||
<option name="provider" value="claude" />
|
||||
<option name="sessionId" value="2a1427c6-520d-4da9-87a9-28e066647864" />
|
||||
<option name="sessionId" value="502b97a5-c9e7-4eb8-b7fc-9567cb6a69da" />
|
||||
<option name="cwd" value="$PROJECT_DIR$" />
|
||||
<option name="model" value="claude-opus-4-7[1m]" />
|
||||
<option name="permissionMode" value="bypassPermissions" />
|
||||
@@ -19,7 +19,7 @@
|
||||
<value>
|
||||
<TabSessionState>
|
||||
<option name="provider" value="claude" />
|
||||
<option name="sessionId" value="916a3047-30c5-4f02-a0de-f2e2ba660d52" />
|
||||
<option name="sessionId" value="6a9b0916-c45b-4c23-8e0c-f35ea3deee13" />
|
||||
<option name="cwd" value="$PROJECT_DIR$" />
|
||||
<option name="model" value="claude-opus-4-7[1m]" />
|
||||
<option name="permissionMode" value="bypassPermissions" />
|
||||
@@ -31,7 +31,30 @@
|
||||
<value>
|
||||
<TabSessionState>
|
||||
<option name="provider" value="claude" />
|
||||
<option name="sessionId" value="eb87e0d9-e045-4412-8eaa-bcecfed97b43" />
|
||||
<option name="sessionId" value="55b6098e-8bc5-4fe4-ba55-1965903c9d6c" />
|
||||
<option name="cwd" value="$PROJECT_DIR$" />
|
||||
<option name="model" value="claude-opus-4-7[1m]" />
|
||||
<option name="permissionMode" value="bypassPermissions" />
|
||||
<option name="reasoningEffort" value="high" />
|
||||
</TabSessionState>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="3">
|
||||
<value>
|
||||
<TabSessionState>
|
||||
<option name="provider" value="claude" />
|
||||
<option name="cwd" value="$PROJECT_DIR$" />
|
||||
<option name="model" value="claude-sonnet-4-6" />
|
||||
<option name="permissionMode" value="bypassPermissions" />
|
||||
<option name="reasoningEffort" value="high" />
|
||||
</TabSessionState>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="4">
|
||||
<value>
|
||||
<TabSessionState>
|
||||
<option name="provider" value="claude" />
|
||||
<option name="sessionId" value="2c735e9c-8739-48be-8864-ef433d7fc841" />
|
||||
<option name="cwd" value="$PROJECT_DIR$" />
|
||||
<option name="model" value="claude-opus-4-7[1m]" />
|
||||
<option name="permissionMode" value="bypassPermissions" />
|
||||
@@ -41,6 +64,6 @@
|
||||
</entry>
|
||||
</map>
|
||||
</option>
|
||||
<option name="tabCount" value="3" />
|
||||
<option name="tabCount" value="5" />
|
||||
</component>
|
||||
</project>
|
||||
@@ -522,6 +522,11 @@
|
||||
</div>
|
||||
|
||||
<script>
|
||||
/* ===== 返回按钮:优先 history.back(),无历史记录时兜底跳模块导航 ===== */
|
||||
document.getElementById('backBtn').addEventListener('click', function() {
|
||||
if (history.length > 1) { history.back(); }
|
||||
else { window.location.href = 'index.html'; }
|
||||
});
|
||||
/**
|
||||
* 餐品数据库(模拟)
|
||||
*/
|
||||
|
||||
@@ -48,85 +48,6 @@
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/* 居中大标题 */
|
||||
.center-heading {
|
||||
position: absolute;
|
||||
top: 60px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
text-align: center;
|
||||
}
|
||||
.big-text {
|
||||
font-size: 56px;
|
||||
font-weight: 700;
|
||||
color: #FF9800;
|
||||
letter-spacing: 6px;
|
||||
text-shadow: 0 0 30px rgba(255,152,0,0.25), 0 2px 10px rgba(0,0,0,0.3);
|
||||
}
|
||||
|
||||
/* 底部菜品信息 */
|
||||
.dish-info {
|
||||
position: absolute;
|
||||
bottom: 60px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 18px;
|
||||
cursor: pointer;
|
||||
padding: 16px 24px;
|
||||
border-radius: 12px;
|
||||
transition: background 0.2s;
|
||||
}
|
||||
.dish-info:hover {
|
||||
background: rgba(74,144,217,0.08);
|
||||
}
|
||||
.dish-img-box {
|
||||
width: 120px;
|
||||
height: 90px;
|
||||
border-radius: 10px;
|
||||
overflow: hidden;
|
||||
flex-shrink: 0;
|
||||
box-shadow: 0 4px 16px rgba(0,0,0,0.5);
|
||||
}
|
||||
.dish-img-box svg {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.dish-info-text {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
}
|
||||
.dish-name-row {
|
||||
font-size: 32px;
|
||||
font-weight: 600;
|
||||
}
|
||||
.dish-name-row .price-info {
|
||||
font-size: 22px;
|
||||
font-weight: 400;
|
||||
color: rgba(255,255,255,0.7);
|
||||
}
|
||||
.dish-name-row .price-num {
|
||||
color: #0AC4A8;
|
||||
font-weight: 600;
|
||||
}
|
||||
.dish-cal-row {
|
||||
font-size: 22px;
|
||||
color: rgba(255,255,255,0.6);
|
||||
}
|
||||
.dish-cal-row .cal-num {
|
||||
color: #0AC4A8;
|
||||
font-weight: 600;
|
||||
}
|
||||
.dish-hint {
|
||||
font-size: 12px;
|
||||
color: rgba(255,255,255,0.25);
|
||||
margin-top: 4px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* ---- 设置按钮 ---- */
|
||||
.settings-btn {
|
||||
position: absolute;
|
||||
@@ -200,7 +121,7 @@
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
.mode-switch button {
|
||||
padding: 0 12px;
|
||||
padding: 0 14px;
|
||||
font-size: 11px;
|
||||
color: rgba(255,255,255,0.5);
|
||||
background: transparent;
|
||||
@@ -219,40 +140,239 @@
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
/* ---- 视频模式布局(纵向:上视频 + 下信息卡) ---- */
|
||||
.video-mode {
|
||||
/* ================ 常规模式布局(左右分栏:左大图 + 右信息卡) ================ */
|
||||
.normal-mode {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
display: none;
|
||||
top: 0; left: 0; right: 0; bottom: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 50px 80px 30px;
|
||||
}
|
||||
/* 顶部副标题 */
|
||||
.normal-heading {
|
||||
text-align: center;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
.normal-heading__text {
|
||||
font-size: 26px;
|
||||
font-weight: 600;
|
||||
color: #FF9800;
|
||||
letter-spacing: 4px;
|
||||
text-shadow: 0 0 20px rgba(255,152,0,0.2);
|
||||
}
|
||||
/* 中部左右分栏内容 */
|
||||
.normal-content {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 40px 60px 30px;
|
||||
gap: 24px;
|
||||
cursor: pointer;
|
||||
transition: background 0.2s;
|
||||
border-radius: 16px;
|
||||
}
|
||||
/* 视频模式激活时显示视频布局 */
|
||||
.main-area.mode-video .video-mode {
|
||||
.normal-content:hover {
|
||||
background: rgba(74,144,217,0.05);
|
||||
}
|
||||
/* 左侧大图 */
|
||||
.normal-img-box {
|
||||
width: 480px;
|
||||
height: 360px;
|
||||
border-radius: 20px;
|
||||
overflow: hidden;
|
||||
flex-shrink: 0;
|
||||
box-shadow: 0 16px 48px rgba(0,0,0,0.5), 0 0 0 1px rgba(255,255,255,0.06);
|
||||
}
|
||||
.normal-img-box svg { width: 100%; height: 100%; }
|
||||
/* 右侧信息卡 */
|
||||
.normal-info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 18px;
|
||||
min-width: 380px;
|
||||
max-width: 440px;
|
||||
}
|
||||
/* 视频模式激活时隐藏常规模式的标题和菜品信息 */
|
||||
.main-area.mode-video .center-heading,
|
||||
.main-area.mode-video .dish-info {
|
||||
.normal-info__name {
|
||||
font-size: 40px;
|
||||
font-weight: 700;
|
||||
color: #fff;
|
||||
line-height: 1.2;
|
||||
}
|
||||
/* 价格突出显示 */
|
||||
.normal-info__price {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
gap: 6px;
|
||||
padding: 14px 20px;
|
||||
background: linear-gradient(135deg, rgba(10,196,168,0.12), rgba(10,196,168,0.04));
|
||||
border: 1px solid rgba(10,196,168,0.3);
|
||||
border-radius: 12px;
|
||||
width: fit-content;
|
||||
}
|
||||
.normal-info__price-symbol {
|
||||
font-size: 24px;
|
||||
font-weight: 600;
|
||||
color: #0AC4A8;
|
||||
}
|
||||
.normal-info__price-num {
|
||||
font-size: 56px;
|
||||
font-weight: 800;
|
||||
color: #0AC4A8;
|
||||
line-height: 1;
|
||||
text-shadow: 0 0 20px rgba(10,196,168,0.3);
|
||||
}
|
||||
.normal-info__price-unit {
|
||||
font-size: 16px;
|
||||
color: rgba(10,196,168,0.7);
|
||||
font-weight: 400;
|
||||
}
|
||||
/* 餐品标签 chips */
|
||||
.normal-tags {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
}
|
||||
.dish-tag {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
padding: 5px 12px;
|
||||
font-size: 13px;
|
||||
color: #0AC4A8;
|
||||
background: rgba(10,196,168,0.12);
|
||||
border: 1px solid rgba(10,196,168,0.25);
|
||||
border-radius: 12px;
|
||||
letter-spacing: 0.5px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.dish-tag:nth-child(3n+2) {
|
||||
color: #FF9800;
|
||||
background: rgba(255,152,0,0.10);
|
||||
border-color: rgba(255,152,0,0.25);
|
||||
}
|
||||
.dish-tag:nth-child(3n) {
|
||||
color: #5B9BF8;
|
||||
background: rgba(91,155,248,0.12);
|
||||
border-color: rgba(91,155,248,0.25);
|
||||
}
|
||||
/* 分隔线 */
|
||||
.normal-divider {
|
||||
width: 100%;
|
||||
height: 1px;
|
||||
background: rgba(255,255,255,0.1);
|
||||
margin: 4px 0;
|
||||
}
|
||||
/* 热量信息 */
|
||||
.normal-cal {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
gap: 8px;
|
||||
}
|
||||
.normal-cal__label {
|
||||
font-size: 14px;
|
||||
color: rgba(255,255,255,0.5);
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
.normal-cal__num {
|
||||
font-size: 28px;
|
||||
font-weight: 700;
|
||||
color: #fff;
|
||||
}
|
||||
.normal-cal__unit {
|
||||
font-size: 13px;
|
||||
color: rgba(255,255,255,0.5);
|
||||
}
|
||||
/* 底部进入提示 */
|
||||
.normal-hint {
|
||||
text-align: center;
|
||||
font-size: 13px;
|
||||
color: rgba(255,255,255,0.35);
|
||||
margin-top: 16px;
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
|
||||
/* 视频模式激活时隐藏常规布局 */
|
||||
.main-area.mode-video .normal-mode {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* 视频播放器 */
|
||||
.video-player {
|
||||
width: 100%;
|
||||
max-width: 680px;
|
||||
aspect-ratio: 16 / 9;
|
||||
/* ================ 视频模式布局(上信息条 + 下大视频) ================ */
|
||||
.video-mode {
|
||||
position: absolute;
|
||||
top: 0; left: 0; right: 0; bottom: 0;
|
||||
display: none;
|
||||
flex-direction: column;
|
||||
padding: 24px 40px 28px;
|
||||
gap: 20px;
|
||||
}
|
||||
.main-area.mode-video .video-mode {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
/* 顶部信息条(菜名 + 价格突出 + 标签) */
|
||||
.video-topbar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 24px;
|
||||
padding: 14px 24px;
|
||||
background: rgba(255,255,255,0.04);
|
||||
border: 1px solid rgba(255,255,255,0.08);
|
||||
border-radius: 12px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.video-topbar__name {
|
||||
font-size: 32px;
|
||||
font-weight: 700;
|
||||
color: #fff;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
/* 视频模式价格突出(青底胶囊,靠右) */
|
||||
.video-topbar__price {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
gap: 4px;
|
||||
padding: 8px 18px;
|
||||
background: linear-gradient(135deg, rgba(10,196,168,0.18), rgba(10,196,168,0.08));
|
||||
border: 1px solid rgba(10,196,168,0.4);
|
||||
border-radius: 10px;
|
||||
flex-shrink: 0;
|
||||
margin-left: auto;
|
||||
}
|
||||
.video-topbar__price-symbol {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: #0AC4A8;
|
||||
}
|
||||
.video-topbar__price-num {
|
||||
font-size: 36px;
|
||||
font-weight: 800;
|
||||
color: #0AC4A8;
|
||||
line-height: 1;
|
||||
text-shadow: 0 0 12px rgba(10,196,168,0.4);
|
||||
}
|
||||
.video-topbar__price-unit {
|
||||
font-size: 13px;
|
||||
color: rgba(10,196,168,0.7);
|
||||
margin-left: 2px;
|
||||
}
|
||||
/* 视频模式标签行 */
|
||||
.video-topbar__tags {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 6px;
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
/* 视频播放区(尽量放大) */
|
||||
.video-player {
|
||||
flex: 1;
|
||||
width: 100%;
|
||||
border-radius: 14px;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
background: #000;
|
||||
box-shadow: 0 12px 32px rgba(0,0,0,0.5), 0 0 0 1px rgba(255,255,255,0.06);
|
||||
box-shadow: 0 16px 40px rgba(0,0,0,0.5), 0 0 0 1px rgba(255,255,255,0.06);
|
||||
min-height: 0;
|
||||
}
|
||||
.video-player .video-bg {
|
||||
position: absolute;
|
||||
@@ -263,7 +383,7 @@
|
||||
position: absolute;
|
||||
top: 50%; left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
width: 56px; height: 56px;
|
||||
width: 64px; height: 64px;
|
||||
background: rgba(0,0,0,0.55);
|
||||
border: 2px solid rgba(255,255,255,0.85);
|
||||
border-radius: 50%;
|
||||
@@ -281,26 +401,26 @@
|
||||
.video-play-btn::after {
|
||||
content: '';
|
||||
width: 0; height: 0;
|
||||
border-left: 16px solid #fff;
|
||||
border-top: 10px solid transparent;
|
||||
border-bottom: 10px solid transparent;
|
||||
margin-left: 4px;
|
||||
border-left: 18px solid #fff;
|
||||
border-top: 12px solid transparent;
|
||||
border-bottom: 12px solid transparent;
|
||||
margin-left: 5px;
|
||||
}
|
||||
.video-controls {
|
||||
position: absolute;
|
||||
bottom: 0; left: 0; right: 0;
|
||||
padding: 10px 14px;
|
||||
padding: 12px 16px;
|
||||
background: linear-gradient(to top, rgba(0,0,0,0.75), transparent);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
font-size: 11px;
|
||||
gap: 12px;
|
||||
font-size: 12px;
|
||||
color: rgba(255,255,255,0.85);
|
||||
z-index: 2;
|
||||
}
|
||||
.video-progress {
|
||||
flex: 1;
|
||||
height: 3px;
|
||||
height: 4px;
|
||||
background: rgba(255,255,255,0.2);
|
||||
border-radius: 2px;
|
||||
position: relative;
|
||||
@@ -315,172 +435,20 @@
|
||||
border-radius: 2px;
|
||||
}
|
||||
.video-time {
|
||||
font-size: 11px;
|
||||
font-size: 12px;
|
||||
letter-spacing: 0.5px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.video-fullscreen {
|
||||
font-size: 13px;
|
||||
font-size: 14px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* 信息卡 */
|
||||
.video-info-card {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 28px;
|
||||
padding: 14px 36px;
|
||||
background: rgba(255,255,255,0.04);
|
||||
border: 1px solid rgba(255,255,255,0.08);
|
||||
border-radius: 12px;
|
||||
}
|
||||
.video-info-name {
|
||||
font-size: 26px;
|
||||
font-weight: 600;
|
||||
color: #fff;
|
||||
}
|
||||
.video-info-divider {
|
||||
width: 1px;
|
||||
height: 28px;
|
||||
background: rgba(255,255,255,0.15);
|
||||
}
|
||||
.video-info-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
gap: 4px;
|
||||
}
|
||||
.video-info-label {
|
||||
font-size: 11px;
|
||||
color: rgba(255,255,255,0.4);
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
.video-info-value {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: #0AC4A8;
|
||||
}
|
||||
.video-info-unit {
|
||||
font-size: 12px;
|
||||
color: rgba(255,255,255,0.5);
|
||||
font-weight: 400;
|
||||
margin-left: 4px;
|
||||
}
|
||||
|
||||
/* ---- 视频模式布局2(横向:左视频 + 右信息卡含标签) ---- */
|
||||
.video-mode-h {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
display: none;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 40px 50px;
|
||||
gap: 32px;
|
||||
}
|
||||
/* 视频2 模式激活时显示横向布局 */
|
||||
.main-area.mode-video2 .video-mode-h {
|
||||
display: flex;
|
||||
}
|
||||
/* 视频2 模式激活时隐藏常规元素与纵向视频布局 */
|
||||
.main-area.mode-video2 .center-heading,
|
||||
.main-area.mode-video2 .dish-info,
|
||||
.main-area.mode-video2 .video-mode {
|
||||
display: none;
|
||||
}
|
||||
/* 纵向视频模式激活时也隐藏横向布局 */
|
||||
.main-area.mode-video .video-mode-h {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* 横向布局下的视频播放器(左侧,固定宽度) */
|
||||
.video-mode-h .video-player {
|
||||
flex: 0 0 auto;
|
||||
width: 680px;
|
||||
max-width: 60%;
|
||||
}
|
||||
|
||||
/* 右侧信息卡(横向布局,纵向排列内容) */
|
||||
.video-info-card-h {
|
||||
flex: 1;
|
||||
min-width: 280px;
|
||||
max-width: 380px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
gap: 14px;
|
||||
padding: 24px 28px;
|
||||
background: rgba(255,255,255,0.04);
|
||||
border: 1px solid rgba(255,255,255,0.08);
|
||||
border-radius: 14px;
|
||||
}
|
||||
.video-info-name-h {
|
||||
font-size: 28px;
|
||||
font-weight: 600;
|
||||
color: #fff;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
/* 餐品标签 chips */
|
||||
.video-tags-row {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
}
|
||||
.video-tag-chip {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
padding: 4px 10px;
|
||||
font-size: 12px;
|
||||
color: #0AC4A8;
|
||||
background: rgba(10,196,168,0.12);
|
||||
border: 1px solid rgba(10,196,168,0.25);
|
||||
border-radius: 10px;
|
||||
letter-spacing: 0.5px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
/* 标签色系变化(按位置循环,增加视觉层次) */
|
||||
.video-tag-chip:nth-child(3n+2) {
|
||||
color: #FF9800;
|
||||
background: rgba(255,152,0,0.10);
|
||||
border-color: rgba(255,152,0,0.25);
|
||||
}
|
||||
.video-tag-chip:nth-child(3n) {
|
||||
color: #5B9BF8;
|
||||
background: rgba(91,155,248,0.12);
|
||||
border-color: rgba(91,155,248,0.25);
|
||||
}
|
||||
|
||||
.video-info-divider-h {
|
||||
width: 100%;
|
||||
height: 1px;
|
||||
background: rgba(255,255,255,0.12);
|
||||
margin: 4px 0;
|
||||
}
|
||||
.video-info-item-h {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
gap: 6px;
|
||||
width: 100%;
|
||||
}
|
||||
/* 横向布局右侧信息卡中的数值字号加大 */
|
||||
.video-info-item-h .video-info-value {
|
||||
font-size: 22px;
|
||||
}
|
||||
.video-info-item-h .video-info-label {
|
||||
font-size: 12px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="device-frame">
|
||||
<!-- 顶部窗口栏 -->
|
||||
<div class="top-bar">
|
||||
|
||||
<a class="back-btn" id="backBtn" href="javascript:void(0)">◀ 返回</a> <span>Phone-192.168.1.165:5555</span>
|
||||
</div>
|
||||
|
||||
@@ -488,7 +456,6 @@
|
||||
<div class="mode-switch" id="modeSwitch">
|
||||
<button class="active" data-mode="normal">常规</button>
|
||||
<button data-mode="video">视频</button>
|
||||
<button data-mode="video2">视频2</button>
|
||||
</div>
|
||||
|
||||
<!-- 设置按钮 -->
|
||||
@@ -499,64 +466,62 @@
|
||||
|
||||
<!-- 主内容区 -->
|
||||
<div class="main-area">
|
||||
<!-- 中央大标题 -->
|
||||
<div class="center-heading">
|
||||
<div class="big-text">先识别 后取餐</div>
|
||||
</div>
|
||||
|
||||
<!-- 底部菜品信息(点击进入开餐界面) -->
|
||||
<div class="dish-info" id="dishInfo">
|
||||
<div class="dish-img-box" id="dishImg"></div>
|
||||
<div class="dish-info-text">
|
||||
<div class="dish-name-row">
|
||||
<span id="dishName">宫保鸡丁</span>
|
||||
<span class="price-info">(单价 <span class="price-num" id="dishPrice">5</span> 元/100克)</span>
|
||||
</div>
|
||||
<div class="dish-cal-row">
|
||||
热量 <span class="cal-num" id="dishKcal">158.66</span> 千卡/100克
|
||||
</div>
|
||||
<div class="dish-hint">点击菜品信息 → 进入开餐界面</div>
|
||||
<!-- ============ 常规模式:左右分栏(左大图 + 右信息卡) ============ -->
|
||||
<div class="normal-mode">
|
||||
<!-- 顶部副标题 -->
|
||||
<div class="normal-heading">
|
||||
<span class="normal-heading__text">先识别 后取餐</span>
|
||||
</div>
|
||||
|
||||
<!-- 中部内容(点击进入开餐界面) -->
|
||||
<div class="normal-content" id="dishInfo">
|
||||
<!-- 左侧大图 -->
|
||||
<div class="normal-img-box" id="dishImg"></div>
|
||||
<!-- 右侧信息卡 -->
|
||||
<div class="normal-info">
|
||||
<div class="normal-info__name" id="dishName">宫保鸡丁</div>
|
||||
<!-- 价格突出 -->
|
||||
<div class="normal-info__price">
|
||||
<span class="normal-info__price-symbol">¥</span>
|
||||
<span class="normal-info__price-num" id="dishPrice">5</span>
|
||||
<span class="normal-info__price-unit">元/100克</span>
|
||||
</div>
|
||||
<!-- 餐品标签 -->
|
||||
<div class="normal-tags" id="dishTags"></div>
|
||||
<!-- 分隔线 -->
|
||||
<div class="normal-divider"></div>
|
||||
<!-- 热量 -->
|
||||
<div class="normal-cal">
|
||||
<span class="normal-cal__label">热量</span>
|
||||
<span class="normal-cal__num" id="dishKcal">158.66</span>
|
||||
<span class="normal-cal__unit">千卡/100克</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 底部进入提示 -->
|
||||
<div class="normal-hint">点击菜品信息 → 进入取餐界面</div>
|
||||
</div>
|
||||
|
||||
<!-- 视频模式布局(纵向:上视频 + 下信息卡,默认隐藏) -->
|
||||
<!-- ============ 视频模式:上信息条 + 下大视频 ============ -->
|
||||
<div class="video-mode" id="videoMode">
|
||||
<!-- 视频播放器 -->
|
||||
<div class="video-player">
|
||||
<!-- 视频背景(用 SVG 模拟菜品展示画面) -->
|
||||
<div class="video-bg" id="videoBg"></div>
|
||||
<!-- 播放按钮 -->
|
||||
<div class="video-play-btn" id="videoPlayBtn" title="播放"></div>
|
||||
<!-- 控制条 -->
|
||||
<div class="video-controls">
|
||||
<span style="cursor:pointer;">⏯</span>
|
||||
<div class="video-progress"></div>
|
||||
<span class="video-time">01:23 / 03:45</span>
|
||||
<span class="video-fullscreen">⛶</span>
|
||||
<!-- 顶部信息条 -->
|
||||
<div class="video-topbar">
|
||||
<span class="video-topbar__name" id="videoDishName">宫保鸡丁</span>
|
||||
<!-- 标签(紧跟菜名) -->
|
||||
<div class="video-topbar__tags" id="videoTags"></div>
|
||||
<!-- 价格突出(右侧) -->
|
||||
<div class="video-topbar__price">
|
||||
<span class="video-topbar__price-symbol">¥</span>
|
||||
<span class="video-topbar__price-num" id="videoDishPrice">5</span>
|
||||
<span class="video-topbar__price-unit">元/100克</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 餐品信息卡 -->
|
||||
<div class="video-info-card">
|
||||
<div class="video-info-name" id="videoDishName">宫保鸡丁</div>
|
||||
<div class="video-info-divider"></div>
|
||||
<div class="video-info-item">
|
||||
<span class="video-info-label">单价</span>
|
||||
<span class="video-info-value"><span id="videoDishPrice">5</span><span class="video-info-unit">元/100克</span></span>
|
||||
</div>
|
||||
<div class="video-info-divider"></div>
|
||||
<div class="video-info-item">
|
||||
<span class="video-info-label">热量</span>
|
||||
<span class="video-info-value"><span id="videoDishKcal">158.66</span><span class="video-info-unit">千卡/100克</span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 视频模式布局2(横向:左视频 + 右信息卡含标签,默认隐藏) -->
|
||||
<div class="video-mode-h" id="videoModeH">
|
||||
<!-- 左侧:视频播放器 -->
|
||||
<!-- 视频播放器(铺满下方剩余空间) -->
|
||||
<div class="video-player">
|
||||
<div class="video-bg" id="videoBgH"></div>
|
||||
<div class="video-play-btn" id="videoPlayBtnH" title="播放"></div>
|
||||
<div class="video-bg" id="videoBg"></div>
|
||||
<div class="video-play-btn" id="videoPlayBtn" title="播放"></div>
|
||||
<div class="video-controls">
|
||||
<span style="cursor:pointer;">⏯</span>
|
||||
<div class="video-progress"></div>
|
||||
@@ -564,31 +529,17 @@
|
||||
<span class="video-fullscreen">⛶</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 右侧:餐品信息卡(含标签) -->
|
||||
<div class="video-info-card-h">
|
||||
<!-- 餐品名称 -->
|
||||
<div class="video-info-name-h" id="videoDishNameH">宫保鸡丁</div>
|
||||
<!-- 餐品标签 chips -->
|
||||
<div class="video-tags-row" id="videoTagsRow"></div>
|
||||
<!-- 分隔线 -->
|
||||
<div class="video-info-divider-h"></div>
|
||||
<!-- 单价 -->
|
||||
<div class="video-info-item-h">
|
||||
<span class="video-info-label">单价</span>
|
||||
<span class="video-info-value"><span id="videoDishPriceH">5</span><span class="video-info-unit">元/100克</span></span>
|
||||
</div>
|
||||
<!-- 每百克热量 -->
|
||||
<div class="video-info-item-h">
|
||||
<span class="video-info-label">每百克热量</span>
|
||||
<span class="video-info-value"><span id="videoDishKcalH">158.66</span><span class="video-info-unit">千卡/100克</span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<script>
|
||||
/* ===== 返回按钮:优先 history.back(),无历史记录时兜底跳模块导航 ===== */
|
||||
document.getElementById('backBtn').addEventListener('click', function() {
|
||||
if (history.length > 1) { history.back(); }
|
||||
else { window.location.href = 'index.html'; }
|
||||
});
|
||||
/**
|
||||
* 待取餐界面交互逻辑
|
||||
*/
|
||||
@@ -635,37 +586,57 @@
|
||||
'</svg>';
|
||||
}
|
||||
|
||||
/* ===== 视频背景 SVG(按菜品色系生成展示画面) ===== */
|
||||
function videoBgSVG(colors) {
|
||||
var w = 1200, h = 675; // 16:9 比例,放大以匹配大视频区
|
||||
var id = 'vidGrad';
|
||||
return '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ' + w + ' ' + h + '" preserveAspectRatio="xMidYMid slice" style="width:100%;height:100%;">' +
|
||||
'<defs><linearGradient id="' + id + '" x1="0" y1="0" x2="1" y2="1">' +
|
||||
'<stop offset="0%" stop-color="' + colors[0] + '"/>' +
|
||||
'<stop offset="50%" stop-color="' + colors[1] + '"/>' +
|
||||
'<stop offset="100%" stop-color="' + colors[2] + '"/></linearGradient></defs>' +
|
||||
'<rect width="' + w + '" height="' + h + '" fill="url(#' + id + ')"/>' +
|
||||
'<ellipse cx="' + (w*0.3) + '" cy="' + (h*0.35) + '" rx="280" ry="200" fill="rgba(255,255,255,0.08)"/>' +
|
||||
'<ellipse cx="' + (w*0.7) + '" cy="' + (h*0.65) + '" rx="340" ry="240" fill="rgba(0,0,0,0.12)"/>' +
|
||||
'<ellipse cx="' + (w/2) + '" cy="' + (h/2) + '" rx="' + (w*0.32) + '" ry="' + (h*0.35) + '" fill="none" stroke="rgba(255,255,255,0.12)" stroke-width="2"/>' +
|
||||
'<ellipse cx="' + (w/2) + '" cy="' + (h/2) + '" rx="' + (w*0.22) + '" ry="' + (h*0.22) + '" fill="rgba(255,255,255,0.06)"/>' +
|
||||
'<ellipse cx="' + (w*0.4) + '" cy="' + (h*0.4) + '" rx="100" ry="70" fill="rgba(255,255,255,0.18)"/>' +
|
||||
'<ellipse cx="' + (w*0.6) + '" cy="' + (h*0.55) + '" rx="70" ry="45" fill="rgba(0,0,0,0.15)"/>' +
|
||||
'<text x="' + (w/2) + '" y="' + (h*0.18) + '" text-anchor="middle" fill="rgba(255,255,255,0.6)" font-size="32" font-weight="600" font-family="-apple-system,Microsoft YaHei,sans-serif">餐品制作工艺展示</text>' +
|
||||
'<text x="' + (w/2) + '" y="' + (h*0.85) + '" text-anchor="middle" fill="rgba(255,255,255,0.35)" font-size="20" font-family="-apple-system,Microsoft YaHei,sans-serif">主厨推荐 · 现场烹制</text>' +
|
||||
'</svg>';
|
||||
}
|
||||
|
||||
/* ===== 渲染餐品标签(共用:常规模式 + 视频模式) ===== */
|
||||
function renderTags(containerId, tags) {
|
||||
var html = '';
|
||||
for (var i = 0; i < tags.length; i++) {
|
||||
html += '<span class="dish-tag">' + tags[i] + '</span>';
|
||||
}
|
||||
document.getElementById(containerId).innerHTML = html;
|
||||
}
|
||||
|
||||
/* ===== 初始化 ===== */
|
||||
var dishId = getQueryParam('dishId');
|
||||
var dishData = (dishId && DISH_MAP[dishId]) || DISH_MAP[2]; // 默认宫保鸡丁
|
||||
document.getElementById('dishImg').innerHTML = dishFoodSVG(120, 90, dishData.colors);
|
||||
var dishTags = dishData.tags || [];
|
||||
|
||||
/* 常规模式数据填充 */
|
||||
document.getElementById('dishImg').innerHTML = dishFoodSVG(480, 360, dishData.colors);
|
||||
document.getElementById('dishName').textContent = dishData.name;
|
||||
document.getElementById('dishPrice').textContent = dishData.price;
|
||||
document.getElementById('dishKcal').textContent = dishData.kcal;
|
||||
renderTags('dishTags', dishTags);
|
||||
|
||||
/* ===== 视频模式数据填充(纵向布局) ===== */
|
||||
/* 视频模式数据填充 */
|
||||
document.getElementById('videoDishName').textContent = dishData.name;
|
||||
document.getElementById('videoDishPrice').textContent = dishData.price;
|
||||
document.getElementById('videoDishKcal').textContent = dishData.kcal;
|
||||
document.getElementById('videoBg').innerHTML = videoBgSVG(dishData.colors);
|
||||
renderTags('videoTags', dishTags);
|
||||
|
||||
/* ===== 视频模式数据填充(横向布局,含标签) ===== */
|
||||
document.getElementById('videoDishNameH').textContent = dishData.name;
|
||||
document.getElementById('videoDishPriceH').textContent = dishData.price;
|
||||
document.getElementById('videoDishKcalH').textContent = dishData.kcal;
|
||||
document.getElementById('videoBgH').innerHTML = videoBgSVG(dishData.colors);
|
||||
// 渲染餐品标签 chips
|
||||
var tagsRow = document.getElementById('videoTagsRow');
|
||||
var tagsHtml = '';
|
||||
var dishTags = dishData.tags || [];
|
||||
for (var i = 0; i < dishTags.length; i++) {
|
||||
tagsHtml += '<span class="video-tag-chip">' + dishTags[i] + '</span>';
|
||||
}
|
||||
tagsRow.innerHTML = tagsHtml;
|
||||
|
||||
/* ===== 点击菜品信息 → 进入开餐界面 ===== */
|
||||
/* ===== 点击菜品信息 → 进入单屏取餐界面 ===== */
|
||||
document.getElementById('dishInfo').addEventListener('click', function() {
|
||||
window.location.href = '01-meal-start.html';
|
||||
window.location.href = '03-meal-pickup.html';
|
||||
});
|
||||
|
||||
/* ===== 演示说明:原 3 秒自动跳转逻辑已移除,改为用户主动点击菜品信息后跳转 ===== */
|
||||
@@ -693,7 +664,7 @@
|
||||
window.location.href = '04-settings.html';
|
||||
});
|
||||
|
||||
/* ===== 演示模式切换(常规 / 视频 / 视频2) ===== */
|
||||
/* ===== 演示模式切换(常规 / 视频) ===== */
|
||||
var modeSwitch = document.getElementById('modeSwitch');
|
||||
var mainArea = document.querySelector('.main-area');
|
||||
modeSwitch.addEventListener('click', function(e) {
|
||||
@@ -705,46 +676,16 @@
|
||||
for (var i = 0; i < btns.length; i++) {
|
||||
btns[i].classList.toggle('active', btns[i] === btn);
|
||||
}
|
||||
// 通过 main-area 的 class 控制布局切换:先清除所有模式类,再按需添加
|
||||
mainArea.classList.remove('mode-video', 'mode-video2');
|
||||
if (mode === 'video') {
|
||||
mainArea.classList.add('mode-video');
|
||||
} else if (mode === 'video2') {
|
||||
mainArea.classList.add('mode-video2');
|
||||
}
|
||||
// 通过 main-area 的 class 控制布局切换
|
||||
mainArea.classList.toggle('mode-video', mode === 'video');
|
||||
});
|
||||
|
||||
/* ===== 视频播放按钮(演示用,点击切换播放/暂停图标) ===== */
|
||||
var videoPlaying = false;
|
||||
function bindVideoPlayBtn(btnId) {
|
||||
document.getElementById(btnId).addEventListener('click', function() {
|
||||
videoPlaying = !videoPlaying;
|
||||
this.style.opacity = videoPlaying ? '0' : '1';
|
||||
});
|
||||
}
|
||||
bindVideoPlayBtn('videoPlayBtn');
|
||||
bindVideoPlayBtn('videoPlayBtnH');
|
||||
|
||||
/* ===== 视频背景 SVG(按菜品色系生成展示画面) ===== */
|
||||
function videoBgSVG(colors) {
|
||||
var w = 680, h = 383; // 16:9 比例
|
||||
var id = 'vidGrad';
|
||||
return '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ' + w + ' ' + h + '" preserveAspectRatio="xMidYMid slice" style="width:100%;height:100%;">' +
|
||||
'<defs><linearGradient id="' + id + '" x1="0" y1="0" x2="1" y2="1">' +
|
||||
'<stop offset="0%" stop-color="' + colors[0] + '"/>' +
|
||||
'<stop offset="50%" stop-color="' + colors[1] + '"/>' +
|
||||
'<stop offset="100%" stop-color="' + colors[2] + '"/></linearGradient></defs>' +
|
||||
'<rect width="' + w + '" height="' + h + '" fill="url(#' + id + ')"/>' +
|
||||
'<ellipse cx="' + (w*0.3) + '" cy="' + (h*0.35) + '" rx="180" ry="120" fill="rgba(255,255,255,0.08)"/>' +
|
||||
'<ellipse cx="' + (w*0.7) + '" cy="' + (h*0.65) + '" rx="220" ry="140" fill="rgba(0,0,0,0.12)"/>' +
|
||||
'<ellipse cx="' + (w/2) + '" cy="' + (h/2) + '" rx="' + (w*0.32) + '" ry="' + (h*0.35) + '" fill="none" stroke="rgba(255,255,255,0.12)" stroke-width="1.5"/>' +
|
||||
'<ellipse cx="' + (w/2) + '" cy="' + (h/2) + '" rx="' + (w*0.22) + '" ry="' + (h*0.22) + '" fill="rgba(255,255,255,0.06)"/>' +
|
||||
'<ellipse cx="' + (w*0.4) + '" cy="' + (h*0.4) + '" rx="60" ry="40" fill="rgba(255,255,255,0.18)"/>' +
|
||||
'<ellipse cx="' + (w*0.6) + '" cy="' + (h*0.55) + '" rx="40" ry="25" fill="rgba(0,0,0,0.15)"/>' +
|
||||
'<text x="' + (w/2) + '" y="' + (h*0.18) + '" text-anchor="middle" fill="rgba(255,255,255,0.6)" font-size="20" font-weight="600" font-family="-apple-system,Microsoft YaHei,sans-serif">餐品制作工艺展示</text>' +
|
||||
'<text x="' + (w/2) + '" y="' + (h*0.85) + '" text-anchor="middle" fill="rgba(255,255,255,0.35)" font-size="12" font-family="-apple-system,Microsoft YaHei,sans-serif">主厨推荐 · 现场烹制</text>' +
|
||||
'</svg>';
|
||||
}
|
||||
document.getElementById('videoPlayBtn').addEventListener('click', function() {
|
||||
videoPlaying = !videoPlaying;
|
||||
this.style.opacity = videoPlaying ? '0' : '1';
|
||||
});
|
||||
</script>
|
||||
|
||||
</body>
|
||||
|
||||
@@ -1,313 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=1280, initial-scale=1.0">
|
||||
<title>取餐信息屏(大屏)- 蚁熊智能餐养平台</title>
|
||||
<style>
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
/* 外层视口:全屏深色背景,承载居中 PAD 外壳 */
|
||||
body {
|
||||
font-family: -apple-system, "Microsoft YaHei", "PingFang SC", sans-serif;
|
||||
background: #05080f;
|
||||
color: #fff;
|
||||
min-height: 100vh;
|
||||
min-width: 1280px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 20px;
|
||||
}
|
||||
/* PAD 设备外壳 */
|
||||
.device-frame {
|
||||
width: 1280px;
|
||||
height: 720px;
|
||||
background: linear-gradient(135deg, #0a1628 0%, #0d1f40 50%, #080f1e 100%);
|
||||
border-radius: 24px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 24px 64px rgba(0, 0, 0, 0.6), 0 0 0 1px rgba(255, 255, 255, 0.04);
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.main-area {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 12px 14px;
|
||||
gap: 12px;
|
||||
}
|
||||
.settings-btn {
|
||||
position: absolute;
|
||||
top: 8px;
|
||||
right: 8px;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: rgba(255,255,255,0.06);
|
||||
border: 1px solid rgba(255,255,255,0.1);
|
||||
border-radius: 6px;
|
||||
font-size: 12px;
|
||||
color: rgba(255,255,255,0.5);
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
transition: all 0.2s;
|
||||
z-index: 10;
|
||||
}
|
||||
.settings-btn:hover {
|
||||
background: rgba(255,255,255,0.1);
|
||||
color: #fff;
|
||||
}
|
||||
.info-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.info-card {
|
||||
flex: 1;
|
||||
background: #1a2b4a;
|
||||
border-radius: 10px;
|
||||
padding: 12px 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
position: relative;
|
||||
}
|
||||
.info-card__avatar {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: 50%;
|
||||
background: linear-gradient(135deg, #4a90d9, #3570ad);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 18px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.info-card__body { flex: 1; min-width: 0; }
|
||||
.info-card__name { font-size: 14px; font-weight: 600; margin-bottom: 2px; }
|
||||
.info-card__id { font-size: 10px; color: rgba(255,255,255,0.4); margin-bottom: 4px; }
|
||||
.info-card__heat { display: flex; align-items: baseline; gap: 4px; }
|
||||
.info-card__heat-label { font-size: 11px; color: rgba(255,255,255,0.45); }
|
||||
.info-card__heat-value { font-size: 18px; font-weight: 700; color: #0AC4A8; line-height: 1; }
|
||||
.info-card__heat-unit { font-size: 12px; color: rgba(10,196,168,0.6); font-weight: 400; }
|
||||
.content-row {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
gap: 12px;
|
||||
min-height: 0;
|
||||
}
|
||||
.dish-display {
|
||||
flex: 1;
|
||||
background: #1a2b4a;
|
||||
border-radius: 10px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-width: 0;
|
||||
}
|
||||
.dish-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 18px;
|
||||
}
|
||||
.dish-img-box {
|
||||
width: 120px;
|
||||
height: 90px;
|
||||
border-radius: 10px;
|
||||
overflow: hidden;
|
||||
flex-shrink: 0;
|
||||
box-shadow: 0 4px 16px rgba(0,0,0,0.5);
|
||||
}
|
||||
.dish-img-box svg { width: 100%; height: 100%; }
|
||||
.dish-info-text { display: flex; flex-direction: column; gap: 8px; }
|
||||
.dish-name-row { font-size: 32px; font-weight: 600; }
|
||||
.dish-name-row .price-info { font-size: 22px; font-weight: 400; color: rgba(255,255,255,0.7); }
|
||||
.dish-name-row .price-num { color: #0AC4A8; font-weight: 600; }
|
||||
.dish-cal-row { font-size: 22px; color: rgba(255,255,255,0.6); }
|
||||
.dish-cal-row .cal-num { color: #0AC4A8; font-weight: 600; }
|
||||
.pickup-section {
|
||||
width: 320px;
|
||||
background: #1a2b4a;
|
||||
border-radius: 10px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.pickup-section__header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 12px 16px 8px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.pickup-section__header .section-label {
|
||||
font-size: 12px;
|
||||
color: rgba(255,255,255,0.45);
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
.pickup-table {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
padding: 0 16px;
|
||||
}
|
||||
.pickup-header {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr 1fr;
|
||||
padding: 8px 0;
|
||||
font-size: 11px;
|
||||
color: rgba(255,255,255,0.4);
|
||||
border-bottom: 1px solid rgba(255,255,255,0.08);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.pickup-list {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
padding: 0;
|
||||
}
|
||||
.pickup-row {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr 1fr;
|
||||
padding: 10px 0;
|
||||
font-size: 12px;
|
||||
color: rgba(255,255,255,0.7);
|
||||
border-bottom: 1px solid rgba(255,255,255,0.04);
|
||||
}
|
||||
.pickup-footer {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr 1fr;
|
||||
padding: 10px 0;
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
border-top: 1px solid rgba(255,255,255,0.12);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.pickup-footer .lbl { color: rgba(255,255,255,0.55); }
|
||||
.pickup-footer .val { color: #fff; }
|
||||
.pickup-footer .price-val { color: #0AC4A8; }
|
||||
.toast {
|
||||
position: fixed;
|
||||
top: 40px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%) translateY(-20px);
|
||||
background: rgba(0, 0, 0, 0.85);
|
||||
color: #fff;
|
||||
padding: 10px 24px;
|
||||
border-radius: 8px;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
z-index: 1000;
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
transition: opacity 0.3s, transform 0.3s, visibility 0.3s;
|
||||
white-space: nowrap;
|
||||
pointer-events: none;
|
||||
}
|
||||
.toast.show { opacity: 1; visibility: visible; transform: translateX(-50%) translateY(0); }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="device-frame">
|
||||
<!-- 返回按钮 -->
|
||||
<div style="position:absolute;top:12px;left:16px;z-index:10;">
|
||||
<a class="back-btn" id="backBtn" href="javascript:void(0)" style="font-size:14px;color:rgba(255,255,255,0.7);text-decoration:none;cursor:pointer;">◀ 返回</a>
|
||||
</div>
|
||||
<div class="toast" id="toast"></div>
|
||||
<div class="main-area">
|
||||
<!-- 用户信息 -->
|
||||
<div class="info-row">
|
||||
<div class="info-card">
|
||||
<div class="info-card__avatar">👤</div>
|
||||
<div class="info-card__body">
|
||||
<div class="info-card__name">张三</div>
|
||||
<div class="info-card__id">ID: 98369</div>
|
||||
<div class="info-card__heat">
|
||||
<span class="info-card__heat-label">推荐热量</span>
|
||||
<span class="info-card__heat-value">720</span>
|
||||
<span class="info-card__heat-unit">千卡</span>
|
||||
</div>
|
||||
</div>
|
||||
<a class="settings-btn" id="settingsBtn" title="设置">⚙</a>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 左侧餐品展示 + 右侧取餐记录 -->
|
||||
<div class="content-row">
|
||||
<div class="dish-display">
|
||||
<div class="dish-info">
|
||||
<div class="dish-img-box" id="dishImg"></div>
|
||||
<div class="dish-info-text">
|
||||
<div class="dish-name-row">
|
||||
宫保鸡丁
|
||||
<span class="price-info">(单价 <span class="price-num">5</span> 元/100克)</span>
|
||||
</div>
|
||||
<div class="dish-cal-row">
|
||||
热量 <span class="cal-num">158.66</span> 千卡/100克
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pickup-section">
|
||||
<div class="pickup-section__header">
|
||||
<span class="section-label">🧾 取餐记录</span>
|
||||
</div>
|
||||
<div class="pickup-table">
|
||||
<div class="pickup-header">
|
||||
<span>餐品名称</span>
|
||||
<span>重量(克)</span>
|
||||
<span>小计(元)</span>
|
||||
</div>
|
||||
<div class="pickup-list">
|
||||
<div class="pickup-row">
|
||||
<span>宫保鸡丁</span><span>186</span><span>9.30</span>
|
||||
</div>
|
||||
<div class="pickup-row">
|
||||
<span>大米饭</span><span>200</span><span>3.00</span>
|
||||
</div>
|
||||
<div class="pickup-row">
|
||||
<span>清炒时蔬</span><span>120</span><span>3.60</span>
|
||||
</div>
|
||||
<div class="pickup-row">
|
||||
<span>紫菜蛋花汤</span><span>250</span><span>5.00</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pickup-footer">
|
||||
<span class="lbl">合计</span>
|
||||
<span class="val">756克</span>
|
||||
<span class="price-val">20.90元</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
document.getElementById('settingsBtn').addEventListener('click', function(e) {
|
||||
e.preventDefault();
|
||||
window.location.href = '04-settings.html';
|
||||
});
|
||||
function dishFoodSVG(w, h, colors) {
|
||||
var id = 'dg';
|
||||
return '<svg xmlns="http://www.w3.org/2000/svg" width="' + w + '" height="' + h + '" viewBox="0 0 ' + w + ' ' + h + '">' +
|
||||
'<defs><linearGradient id="' + id + '" x1="0" y1="0" x2="1" y2="1">' +
|
||||
'<stop offset="0%" stop-color="' + colors[0] + '"/>' +
|
||||
'<stop offset="50%" stop-color="' + colors[1] + '"/>' +
|
||||
'<stop offset="100%" stop-color="' + colors[2] + '"/></linearGradient></defs>' +
|
||||
'<rect width="' + w + '" height="' + h + '" fill="url(#' + id + ')"/>' +
|
||||
'<ellipse cx="' + (w*0.4) + '" cy="' + (h*0.45) + '" rx="' + (w*0.3) + '" ry="' + (h*0.25) + '" fill="rgba(255,255,255,0.08)"/>' +
|
||||
'<ellipse cx="' + (w*0.6) + '" cy="' + (h*0.55) + '" rx="' + (w*0.25) + '" ry="' + (h*0.2) + '" fill="rgba(0,0,0,0.1)"/>' +
|
||||
'<ellipse cx="' + (w*0.35) + '" cy="' + (h*0.35) + '" rx="' + (w*0.12) + '" ry="' + (h*0.1) + '" fill="rgba(255,255,255,0.15)"/>' +
|
||||
'</svg>';
|
||||
}
|
||||
document.getElementById('dishImg').innerHTML = dishFoodSVG(120, 90, ['#C87030', '#E8A040', '#D08028']);
|
||||
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,182 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=480, initial-scale=1.0">
|
||||
<title>取餐营养屏(小屏)- 蚁熊智能餐养平台</title>
|
||||
<style>
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
/* 外层视口:全屏深色背景,承载居中副屏外壳 */
|
||||
body {
|
||||
font-family: -apple-system, "Microsoft YaHei", "PingFang SC", sans-serif;
|
||||
background: #05080f;
|
||||
color: #fff;
|
||||
min-height: 100vh;
|
||||
min-width: 480px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 20px;
|
||||
}
|
||||
.screen-frame {
|
||||
width: 480px;
|
||||
height: 320px;
|
||||
background: linear-gradient(180deg, #1a2b4a 0%, #142038 100%);
|
||||
border-radius: 16px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 16px 40px rgba(0, 0, 0, 0.6), inset 0 0 0 1px rgba(74, 144, 217, 0.15);
|
||||
}
|
||||
.header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 8px 16px;
|
||||
border-bottom: 1px solid rgba(255,255,255,0.06);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.header .n-title {
|
||||
font-size: 9px;
|
||||
font-weight: 600;
|
||||
color: #fff;
|
||||
}
|
||||
.header .n-meal {
|
||||
font-size: 8px;
|
||||
color: rgba(255,255,255,0.45);
|
||||
}
|
||||
.header .n-time {
|
||||
font-size: 7px;
|
||||
color: rgba(255,255,255,0.3);
|
||||
margin-left: 6px;
|
||||
}
|
||||
.cyl-group {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
justify-content: center;
|
||||
gap: 28px;
|
||||
padding: 10px 16px 8px;
|
||||
}
|
||||
.cyl-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
}
|
||||
.cyl-value {
|
||||
font-size: 10px;
|
||||
font-weight: 700;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
line-height: 1.3;
|
||||
}
|
||||
.cyl-value .cyl-unit {
|
||||
font-size: 7px;
|
||||
font-weight: 400;
|
||||
opacity: 0.7;
|
||||
}
|
||||
.cyl-svg { display: block; }
|
||||
.cyl-label {
|
||||
font-size: 8px;
|
||||
color: rgba(255,255,255,0.6);
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="screen-frame">
|
||||
<!-- 返回按钮 -->
|
||||
<div style="position:absolute;top:12px;left:16px;z-index:10;">
|
||||
<a class="back-btn" id="backBtn" href="javascript:void(0)" style="font-size:14px;color:rgba(255,255,255,0.7);text-decoration:none;cursor:pointer;">◀ 返回</a>
|
||||
</div>
|
||||
<div class="header">
|
||||
<span class="n-title">📊 本餐次摄入</span>
|
||||
<span>
|
||||
<span class="n-meal">当前餐次:早餐</span>
|
||||
<span class="n-time">06:00 ~ 10:19</span>
|
||||
</span>
|
||||
</div>
|
||||
<div class="cyl-group">
|
||||
<!-- 热量柱 -->
|
||||
<div class="cyl-item">
|
||||
<div class="cyl-value">1070<span class="cyl-unit">千卡</span></div>
|
||||
<svg class="cyl-svg" width="72" height="190" viewBox="0 0 72 190">
|
||||
<defs>
|
||||
<linearGradient id="heatGrad" x1="0" y1="0" x2="1" y2="0">
|
||||
<stop offset="0%" stop-color="#cc1111"/>
|
||||
<stop offset="50%" stop-color="#ff2020"/>
|
||||
<stop offset="100%" stop-color="#cc1111"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<ellipse cx="36" cy="8" rx="32" ry="7" fill="#cc1111"/>
|
||||
<rect x="4" y="8" width="64" height="175" fill="url(#heatGrad)"/>
|
||||
<rect x="8" y="8" width="8" height="175" fill="rgba(255,255,255,0.08)"/>
|
||||
<ellipse cx="36" cy="8" rx="30" ry="6" fill="rgba(255,255,255,0.15)"/>
|
||||
<text x="36" y="178" text-anchor="middle" font-size="14">🔥</text>
|
||||
</svg>
|
||||
<div class="cyl-label">热量</div>
|
||||
</div>
|
||||
<!-- 主食柱 -->
|
||||
<div class="cyl-item">
|
||||
<div class="cyl-value">68<span class="cyl-unit">克</span></div>
|
||||
<svg class="cyl-svg" width="56" height="120" viewBox="0 0 56 120">
|
||||
<defs>
|
||||
<linearGradient id="stapleGrad" x1="0" y1="0" x2="1" y2="0">
|
||||
<stop offset="0%" stop-color="#68a868"/>
|
||||
<stop offset="50%" stop-color="#88cc88"/>
|
||||
<stop offset="100%" stop-color="#68a868"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<ellipse cx="28" cy="8" rx="26" ry="6" fill="#68a868"/>
|
||||
<rect x="2" y="8" width="52" height="105" fill="url(#stapleGrad)"/>
|
||||
<rect x="6" y="8" width="6" height="105" fill="rgba(255,255,255,0.08)"/>
|
||||
<ellipse cx="28" cy="8" rx="24" ry="5" fill="rgba(255,255,255,0.15)"/>
|
||||
<text x="28" y="108" text-anchor="middle" font-size="12">🍚</text>
|
||||
</svg>
|
||||
<div class="cyl-label">主食</div>
|
||||
</div>
|
||||
<!-- 果蔬柱 -->
|
||||
<div class="cyl-item">
|
||||
<div class="cyl-value">68<span class="cyl-unit">克</span></div>
|
||||
<svg class="cyl-svg" width="56" height="120" viewBox="0 0 56 120">
|
||||
<defs>
|
||||
<linearGradient id="vegGrad" x1="0" y1="0" x2="1" y2="0">
|
||||
<stop offset="0%" stop-color="#68a868"/>
|
||||
<stop offset="50%" stop-color="#88cc88"/>
|
||||
<stop offset="100%" stop-color="#68a868"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<ellipse cx="28" cy="8" rx="26" ry="6" fill="#68a868"/>
|
||||
<rect x="2" y="8" width="52" height="105" fill="url(#vegGrad)"/>
|
||||
<rect x="6" y="8" width="6" height="105" fill="rgba(255,255,255,0.08)"/>
|
||||
<ellipse cx="28" cy="8" rx="24" ry="5" fill="rgba(255,255,255,0.15)"/>
|
||||
<text x="28" y="108" text-anchor="middle" font-size="12">🥗</text>
|
||||
</svg>
|
||||
<div class="cyl-label">果蔬</div>
|
||||
</div>
|
||||
<!-- 肉蛋柱 -->
|
||||
<div class="cyl-item">
|
||||
<div class="cyl-value">68<span class="cyl-unit">克</span></div>
|
||||
<svg class="cyl-svg" width="56" height="105" viewBox="0 0 56 105">
|
||||
<defs>
|
||||
<linearGradient id="meatGrad" x1="0" y1="0" x2="1" y2="0">
|
||||
<stop offset="0%" stop-color="#cc1111"/>
|
||||
<stop offset="50%" stop-color="#ff2020"/>
|
||||
<stop offset="100%" stop-color="#cc1111"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<ellipse cx="28" cy="8" rx="26" ry="6" fill="#cc1111"/>
|
||||
<rect x="2" y="8" width="52" height="90" fill="url(#meatGrad)"/>
|
||||
<rect x="6" y="8" width="6" height="90" fill="rgba(255,255,255,0.08)"/>
|
||||
<ellipse cx="28" cy="8" rx="24" ry="5" fill="rgba(255,255,255,0.15)"/>
|
||||
<text x="28" y="94" text-anchor="middle" font-size="12">🥩</text>
|
||||
</svg>
|
||||
<div class="cyl-label">肉蛋</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,761 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=1920, initial-scale=1.0">
|
||||
<title>取餐界面(双屏)- 蚁熊智能餐养平台</title>
|
||||
<style>
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
/* 外层视口:全屏深色背景,承载左右双屏 */
|
||||
body {
|
||||
font-family: -apple-system, "Microsoft YaHei", "PingFang SC", sans-serif;
|
||||
background: #05080f;
|
||||
color: #fff;
|
||||
min-height: 100vh;
|
||||
min-width: 1820px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 20px;
|
||||
}
|
||||
/* 双屏容器:左侧大屏 + 右侧小屏横向排列 */
|
||||
.dual-wrap {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 24px;
|
||||
position: relative;
|
||||
}
|
||||
.screen-label {
|
||||
position: absolute;
|
||||
top: -28px;
|
||||
left: 0;
|
||||
font-size: 12px;
|
||||
color: rgba(255,255,255,0.4);
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
.dual-col { position: relative; }
|
||||
.dual-col--large .screen-label { left: 0; }
|
||||
.dual-col--small .screen-label { left: 0; }
|
||||
|
||||
/* ===== 左侧:大屏 PAD 外壳 1280×720 ===== */
|
||||
.device-frame {
|
||||
width: 1280px;
|
||||
height: 720px;
|
||||
background: linear-gradient(135deg, #0a1628 0%, #0d1f40 50%, #080f1e 100%);
|
||||
border-radius: 24px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 24px 64px rgba(0, 0, 0, 0.6), 0 0 0 1px rgba(255, 255, 255, 0.04);
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
/* ===== 主内容区:两列网格(参考 03-meal-pickup) ===== */
|
||||
.large-main {
|
||||
height: 100%;
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 320px;
|
||||
padding: 16px 20px;
|
||||
gap: 16px;
|
||||
}
|
||||
/* 中列:用户信息 + 餐品介绍 纵向堆叠 */
|
||||
.center-column {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
min-width: 0;
|
||||
}
|
||||
/* 设置按钮(浮于 pickup-section 头部) */
|
||||
.settings-btn {
|
||||
width: 32px; height: 32px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: rgba(255,255,255,0.06);
|
||||
border: 1px solid rgba(255,255,255,0.1);
|
||||
border-radius: 6px;
|
||||
font-size: 16px;
|
||||
color: rgba(255,255,255,0.6);
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
transition: all 0.2s;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.settings-btn:hover { background: rgba(255,255,255,0.1); color: #fff; }
|
||||
|
||||
/* ===== 用户信息 + 餐品信息 横排 ===== */
|
||||
.info-row {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.info-card {
|
||||
flex: 1;
|
||||
background: #1a2b4a;
|
||||
border-radius: 10px;
|
||||
padding: 12px 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
min-width: 0;
|
||||
}
|
||||
.info-card__avatar {
|
||||
width: 42px; height: 42px;
|
||||
border-radius: 50%;
|
||||
background: linear-gradient(135deg, #4a90d9, #3570ad);
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
font-size: 20px; flex-shrink: 0;
|
||||
}
|
||||
.info-card__body { flex: 1; min-width: 0; }
|
||||
/* 用户信息卡:第一行 姓名 + 编号 同行 */
|
||||
.info-card__line {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
gap: 8px;
|
||||
margin-bottom: 4px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.info-card__name {
|
||||
font-size: 22px;
|
||||
font-weight: 700;
|
||||
line-height: 1.1;
|
||||
color: #fff;
|
||||
}
|
||||
.info-card__id {
|
||||
font-size: 16px;
|
||||
color: rgba(255,255,255,0.55);
|
||||
font-weight: 500;
|
||||
}
|
||||
/* 第二行:推荐热量 + 范围值 */
|
||||
.info-card__heat {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
gap: 6px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.info-card__label {
|
||||
font-size: 11px;
|
||||
color: rgba(255,255,255,0.45);
|
||||
font-weight: 400;
|
||||
}
|
||||
.info-card__value {
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
color: #0AC4A8;
|
||||
line-height: 1.1;
|
||||
}
|
||||
.info-card__unit {
|
||||
font-size: 11px;
|
||||
font-weight: 400;
|
||||
color: rgba(10,196,168,0.7);
|
||||
}
|
||||
|
||||
/* ===== 餐品信息卡 ===== */
|
||||
.info-card--dish {
|
||||
cursor: pointer;
|
||||
transition: background 0.2s;
|
||||
}
|
||||
.info-card--dish:hover {
|
||||
background: rgba(74,144,217,0.12);
|
||||
}
|
||||
.info-card__dish-line {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 10px;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
.info-card__dish-name {
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
line-height: 1.1;
|
||||
white-space: nowrap;
|
||||
color: #fff;
|
||||
}
|
||||
.info-card__dish-price {
|
||||
font-size: 36px;
|
||||
font-weight: 800;
|
||||
color: #FFB236;
|
||||
line-height: 1;
|
||||
letter-spacing: -0.5px;
|
||||
white-space: nowrap;
|
||||
text-shadow: 0 1px 6px rgba(255,140,40,0.45);
|
||||
}
|
||||
.info-card__dish-price .price-unit {
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
color: rgba(255,178,54,0.85);
|
||||
margin-left: 3px;
|
||||
letter-spacing: 0;
|
||||
text-shadow: none;
|
||||
}
|
||||
.info-card__dish-heat {
|
||||
font-size: 11px;
|
||||
color: rgba(255,255,255,0.5);
|
||||
line-height: 1.3;
|
||||
}
|
||||
.info-card__dish-heat em {
|
||||
font-style: normal;
|
||||
color: #0AC4A8;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* ===== 当前餐次标题行(参考单屏 03 nutrition-header-row) ===== */
|
||||
.meal-header-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
background: #1a2b4a;
|
||||
border-radius: 10px;
|
||||
padding: 12px 20px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.meal-header-row .n-title {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: #fff;
|
||||
}
|
||||
.meal-header-row .n-title-hint {
|
||||
font-size: 12px;
|
||||
font-weight: 400;
|
||||
color: #FFB236;
|
||||
margin-left: 4px;
|
||||
}
|
||||
.meal-header-row .n-meal {
|
||||
font-size: 13px;
|
||||
color: rgba(255,255,255,0.5);
|
||||
}
|
||||
.meal-header-row .n-time {
|
||||
font-size: 12px;
|
||||
color: rgba(255,255,255,0.35);
|
||||
margin-left: 12px;
|
||||
}
|
||||
|
||||
/* ===== 中列下半部:餐品介绍(替代 nutrition-core) ===== */
|
||||
.dish-display {
|
||||
flex: 1;
|
||||
background: linear-gradient(180deg, #1a2b4a 0%, #142038 100%);
|
||||
border-radius: 14px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 24px;
|
||||
min-height: 0;
|
||||
}
|
||||
.dish-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 32px;
|
||||
width: 100%;
|
||||
}
|
||||
.dish-img-box {
|
||||
width: 320px; height: 320px;
|
||||
border-radius: 20px;
|
||||
overflow: hidden;
|
||||
flex-shrink: 0;
|
||||
box-shadow: 0 12px 32px rgba(0,0,0,0.55), 0 0 0 1px rgba(255,255,255,0.06);
|
||||
}
|
||||
.dish-img-box svg { width: 100%; height: 100%; }
|
||||
.dish-info-text {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
max-width: 420px;
|
||||
}
|
||||
.dish-name-row {
|
||||
font-size: 38px;
|
||||
font-weight: 700;
|
||||
color: #fff;
|
||||
line-height: 1.2;
|
||||
}
|
||||
/* 价格胶囊(青色) */
|
||||
.dish-price-pill {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
gap: 6px;
|
||||
padding: 10px 20px;
|
||||
background: linear-gradient(135deg, rgba(10,196,168,0.18), rgba(10,196,168,0.06));
|
||||
border: 1px solid rgba(10,196,168,0.4);
|
||||
border-radius: 12px;
|
||||
width: fit-content;
|
||||
}
|
||||
.dish-price-pill__symbol {
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
color: #0AC4A8;
|
||||
}
|
||||
.dish-price-pill__num {
|
||||
font-size: 44px;
|
||||
font-weight: 800;
|
||||
color: #0AC4A8;
|
||||
line-height: 1;
|
||||
text-shadow: 0 0 16px rgba(10,196,168,0.35);
|
||||
}
|
||||
.dish-price-pill__unit {
|
||||
font-size: 14px;
|
||||
color: rgba(10,196,168,0.8);
|
||||
font-weight: 400;
|
||||
}
|
||||
/* 餐品标签 chips */
|
||||
.dish-tags {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
}
|
||||
.dish-tag {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
padding: 5px 12px;
|
||||
font-size: 13px;
|
||||
color: #0AC4A8;
|
||||
background: rgba(10,196,168,0.12);
|
||||
border: 1px solid rgba(10,196,168,0.25);
|
||||
border-radius: 12px;
|
||||
letter-spacing: 0.5px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.dish-tag:nth-child(3n+2) {
|
||||
color: #FF9800;
|
||||
background: rgba(255,152,0,0.10);
|
||||
border-color: rgba(255,152,0,0.25);
|
||||
}
|
||||
.dish-tag:nth-child(3n) {
|
||||
color: #5B9BF8;
|
||||
background: rgba(91,155,248,0.12);
|
||||
border-color: rgba(91,155,248,0.25);
|
||||
}
|
||||
.dish-divider {
|
||||
width: 100%;
|
||||
height: 1px;
|
||||
background: rgba(255,255,255,0.1);
|
||||
}
|
||||
.dish-cal-row {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
gap: 8px;
|
||||
}
|
||||
.dish-cal-row__label {
|
||||
font-size: 13px;
|
||||
color: rgba(255,255,255,0.5);
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
.dish-cal-row__num {
|
||||
font-size: 26px;
|
||||
font-weight: 700;
|
||||
color: #fff;
|
||||
}
|
||||
.dish-cal-row__unit {
|
||||
font-size: 12px;
|
||||
color: rgba(255,255,255,0.5);
|
||||
}
|
||||
|
||||
/* ===== 右列:取餐记录(通顶) ===== */
|
||||
.right-column {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-width: 0;
|
||||
}
|
||||
.pickup-section {
|
||||
flex: 1;
|
||||
background: #1a2b4a;
|
||||
border-radius: 10px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
}
|
||||
.pickup-section__header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 12px 16px 8px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.pickup-section__header .section-label {
|
||||
font-size: 12px;
|
||||
color: rgba(255,255,255,0.4);
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
.pickup-table {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
padding: 0 16px;
|
||||
}
|
||||
.pickup-header {
|
||||
display: grid; grid-template-columns: 1fr 1fr 1fr;
|
||||
padding: 8px 0; font-size: 12px;
|
||||
color: rgba(255,255,255,0.45);
|
||||
border-bottom: 1px solid rgba(255,255,255,0.08);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.pickup-list { flex: 1; overflow-y: auto; padding: 0; }
|
||||
.pickup-row {
|
||||
display: grid; grid-template-columns: 1fr 1fr 1fr;
|
||||
padding: 10px 0; font-size: 13px;
|
||||
color: rgba(255,255,255,0.7);
|
||||
border-bottom: 1px solid rgba(255,255,255,0.04);
|
||||
}
|
||||
/* 合计区:橙色胶囊(沿用单屏 03 样式) */
|
||||
.pickup-footer {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
justify-content: space-between;
|
||||
gap: 8px;
|
||||
margin-top: 6px;
|
||||
padding: 14px 14px;
|
||||
background: linear-gradient(135deg, rgba(255,178,54,0.2) 0%, rgba(255,140,40,0.32) 100%);
|
||||
border: 1px solid rgba(255,178,54,0.5);
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 4px 14px rgba(255,140,40,0.25);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.pickup-footer .lbl {
|
||||
color: rgba(255,255,255,0.85);
|
||||
font-size: 14px;
|
||||
font-weight: 700;
|
||||
letter-spacing: 1px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.pickup-footer .val {
|
||||
color: #fff;
|
||||
font-size: 15px;
|
||||
font-weight: 700;
|
||||
white-space: nowrap;
|
||||
}
|
||||
/* 超大醒目金额:40px,800字重,橙色高亮+发光阴影 */
|
||||
.pickup-footer .price-val {
|
||||
color: #FFB236;
|
||||
font-size: 40px;
|
||||
font-weight: 800;
|
||||
text-shadow: 0 2px 10px rgba(255,140,40,0.6);
|
||||
letter-spacing: -1px;
|
||||
line-height: 1;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.pickup-footer .price-val::before {
|
||||
content: '\FFE5';
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
margin-right: 3px;
|
||||
vertical-align: 5px;
|
||||
}
|
||||
|
||||
/* ===== 右侧:小屏副屏外壳 480×320 ===== */
|
||||
.screen-frame {
|
||||
width: 480px;
|
||||
height: 320px;
|
||||
background: linear-gradient(180deg, #1a2b4a 0%, #142038 100%);
|
||||
border-radius: 16px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 16px 40px rgba(0, 0, 0, 0.6), inset 0 0 0 1px rgba(74, 144, 217, 0.15);
|
||||
}
|
||||
.small-header {
|
||||
display: flex; align-items: center; justify-content: space-between;
|
||||
padding: 8px 16px;
|
||||
border-bottom: 1px solid rgba(255,255,255,0.06);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.small-header .n-title { font-size: 9px; font-weight: 600; color: #fff; }
|
||||
/* 标题内推荐热量副文案:字号更小 + 暖橙色区分 */
|
||||
.small-header .n-title .n-sub {
|
||||
font-size: 8px;
|
||||
font-weight: 400;
|
||||
color: #FFB236;
|
||||
margin-left: 4px;
|
||||
letter-spacing: 0.2px;
|
||||
}
|
||||
.small-header .n-meal { font-size: 8px; color: rgba(255,255,255,0.45); }
|
||||
.small-header .n-time { font-size: 7px; color: rgba(255,255,255,0.3); margin-left: 6px; }
|
||||
.cyl-group {
|
||||
flex: 1;
|
||||
display: flex; align-items: flex-end; justify-content: center;
|
||||
gap: 28px; padding: 10px 16px 8px;
|
||||
}
|
||||
.cyl-item { display: flex; flex-direction: column; align-items: center; gap: 4px; }
|
||||
.cyl-value { font-size: 10px; font-weight: 700; color: #fff; text-align: center; line-height: 1.3; }
|
||||
.cyl-value .cyl-unit { font-size: 7px; font-weight: 400; opacity: 0.7; }
|
||||
.cyl-svg { display: block; }
|
||||
.cyl-label { font-size: 8px; color: rgba(255,255,255,0.6); text-align: center; }
|
||||
|
||||
/* ===== 顶部返回按钮(浮于双屏容器之上) ===== */
|
||||
.back-btn {
|
||||
position: fixed;
|
||||
top: 20px;
|
||||
left: 20px;
|
||||
z-index: 100;
|
||||
font-size: 14px;
|
||||
color: rgba(255,255,255,0.7);
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
background: rgba(0,0,0,0.4);
|
||||
padding: 6px 12px;
|
||||
border-radius: 6px;
|
||||
}
|
||||
.back-btn:hover { color: #fff; background: rgba(0,0,0,0.6); }
|
||||
|
||||
.toast {
|
||||
position: fixed;
|
||||
top: 40px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%) translateY(-20px);
|
||||
background: rgba(0, 0, 0, 0.85);
|
||||
color: #fff;
|
||||
padding: 10px 24px;
|
||||
border-radius: 8px;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
z-index: 1000;
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
transition: opacity 0.3s, transform 0.3s, visibility 0.3s;
|
||||
white-space: nowrap;
|
||||
pointer-events: none;
|
||||
}
|
||||
.toast.show { opacity: 1; visibility: visible; transform: translateX(-50%) translateY(0); }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<!-- 返回按钮 -->
|
||||
<a class="back-btn" id="backBtn" href="javascript:void(0)">◀ 返回</a>
|
||||
<div class="toast" id="toast"></div>
|
||||
|
||||
<div class="dual-wrap">
|
||||
<!-- ===== 左:大屏 ===== -->
|
||||
<div class="dual-col dual-col--large">
|
||||
<span class="screen-label">大屏 · 1280×720</span>
|
||||
<div class="device-frame">
|
||||
<div class="large-main">
|
||||
<!-- ===== 中列:用户信息 + 餐品信息 + 餐品介绍 ===== -->
|
||||
<div class="center-column">
|
||||
<!-- 用户信息 + 餐品信息 横排 -->
|
||||
<div class="info-row">
|
||||
<!-- 用户信息卡 -->
|
||||
<div class="info-card">
|
||||
<div class="info-card__avatar">👤</div>
|
||||
<div class="info-card__body">
|
||||
<div class="info-card__line" style="justify-content:space-between;margin-bottom:0;">
|
||||
<span class="info-card__name">张三</span>
|
||||
<span class="info-card__id">编号: 98369</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 餐品信息卡 -->
|
||||
<div class="info-card info-card--dish" id="dishInfoCard">
|
||||
<div class="info-card__body">
|
||||
<div class="info-card__dish-line">
|
||||
<span class="info-card__dish-name">宫保鸡丁</span>
|
||||
<span class="info-card__dish-price">5<span class="price-unit">元/100g</span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 当前餐次标题行 -->
|
||||
<div class="meal-header-row">
|
||||
<span class="n-title">📊 本餐次摄入<span class="n-title-hint">(推荐热量 580~720 千卡)</span></span>
|
||||
<span>
|
||||
<span class="n-meal">当前餐次:早餐</span>
|
||||
<span class="n-time">06:00 ~ 10:19</span>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!-- 餐品介绍(替代原 nutrition-core) -->
|
||||
<div class="dish-display">
|
||||
<div class="dish-info">
|
||||
<div class="dish-img-box" id="dishImg"></div>
|
||||
<div class="dish-info-text">
|
||||
<div class="dish-name-row">宫保鸡丁</div>
|
||||
<div class="dish-price-pill">
|
||||
<span class="dish-price-pill__symbol">¥</span>
|
||||
<span class="dish-price-pill__num">5</span>
|
||||
<span class="dish-price-pill__unit">元/100克</span>
|
||||
</div>
|
||||
<div class="dish-tags">
|
||||
<span class="dish-tag">高蛋白</span>
|
||||
<span class="dish-tag">低芥酸</span>
|
||||
<span class="dish-tag">营养均衡</span>
|
||||
</div>
|
||||
<div class="dish-divider"></div>
|
||||
<div class="dish-cal-row">
|
||||
<span class="dish-cal-row__label">热量</span>
|
||||
<span class="dish-cal-row__num">158.66</span>
|
||||
<span class="dish-cal-row__unit">千卡/100克</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ===== 右列:取餐记录(通顶) ===== -->
|
||||
<div class="right-column">
|
||||
<div class="pickup-section">
|
||||
<div class="pickup-section__header">
|
||||
<span class="section-label">🧾 取餐记录</span>
|
||||
<a class="settings-btn" id="settingsBtn" title="设置">⚙</a>
|
||||
</div>
|
||||
<div class="pickup-table">
|
||||
<div class="pickup-header">
|
||||
<span>餐品名称</span>
|
||||
<span>重量(克)</span>
|
||||
<span>小计(元)</span>
|
||||
</div>
|
||||
<div class="pickup-list">
|
||||
<div class="pickup-row">
|
||||
<span>宫保鸡丁</span><span>186</span><span>9.30</span>
|
||||
</div>
|
||||
<div class="pickup-row">
|
||||
<span>大米饭</span><span>200</span><span>3.00</span>
|
||||
</div>
|
||||
<div class="pickup-row">
|
||||
<span>清炒时蔬</span><span>120</span><span>3.60</span>
|
||||
</div>
|
||||
<div class="pickup-row">
|
||||
<span>紫菜蛋花汤</span><span>250</span><span>5.00</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pickup-footer">
|
||||
<span class="lbl">合计</span>
|
||||
<span class="val">756克</span>
|
||||
<span class="price-val">20.90</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ===== 右:小屏 ===== -->
|
||||
<div class="dual-col dual-col--small">
|
||||
<span class="screen-label">小屏 · 480×320</span>
|
||||
<div class="screen-frame">
|
||||
<div class="small-header">
|
||||
<span class="n-title">📊 本餐次摄入<span class="n-sub">推荐热量 580~720 千卡</span></span>
|
||||
<span>
|
||||
<span class="n-meal">当前餐次:早餐</span>
|
||||
<span class="n-time">06:00 ~ 10:19</span>
|
||||
</span>
|
||||
</div>
|
||||
<div class="cyl-group">
|
||||
<!-- 热量柱 -->
|
||||
<div class="cyl-item">
|
||||
<div class="cyl-value">1070<span class="cyl-unit">千卡</span></div>
|
||||
<svg class="cyl-svg" width="72" height="190" viewBox="0 0 72 190">
|
||||
<defs>
|
||||
<linearGradient id="heatGrad" x1="0" y1="0" x2="1" y2="0">
|
||||
<stop offset="0%" stop-color="#cc1111"/>
|
||||
<stop offset="50%" stop-color="#ff2020"/>
|
||||
<stop offset="100%" stop-color="#cc1111"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<ellipse cx="36" cy="8" rx="32" ry="7" fill="#cc1111"/>
|
||||
<rect x="4" y="8" width="64" height="175" fill="url(#heatGrad)"/>
|
||||
<rect x="8" y="8" width="8" height="175" fill="rgba(255,255,255,0.08)"/>
|
||||
<ellipse cx="36" cy="8" rx="30" ry="6" fill="rgba(255,255,255,0.15)"/>
|
||||
<text x="36" y="178" text-anchor="middle" font-size="14">🔥</text>
|
||||
</svg>
|
||||
<div class="cyl-label">热量</div>
|
||||
</div>
|
||||
<!-- 主食柱 -->
|
||||
<div class="cyl-item">
|
||||
<div class="cyl-value">68<span class="cyl-unit">克</span></div>
|
||||
<svg class="cyl-svg" width="56" height="120" viewBox="0 0 56 120">
|
||||
<defs>
|
||||
<linearGradient id="stapleGrad" x1="0" y1="0" x2="1" y2="0">
|
||||
<stop offset="0%" stop-color="#68a868"/>
|
||||
<stop offset="50%" stop-color="#88cc88"/>
|
||||
<stop offset="100%" stop-color="#68a868"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<ellipse cx="28" cy="8" rx="26" ry="6" fill="#68a868"/>
|
||||
<rect x="2" y="8" width="52" height="105" fill="url(#stapleGrad)"/>
|
||||
<rect x="6" y="8" width="6" height="105" fill="rgba(255,255,255,0.08)"/>
|
||||
<ellipse cx="28" cy="8" rx="24" ry="5" fill="rgba(255,255,255,0.15)"/>
|
||||
<text x="28" y="108" text-anchor="middle" font-size="12">🍚</text>
|
||||
</svg>
|
||||
<div class="cyl-label">主食</div>
|
||||
</div>
|
||||
<!-- 果蔬柱 -->
|
||||
<div class="cyl-item">
|
||||
<div class="cyl-value">68<span class="cyl-unit">克</span></div>
|
||||
<svg class="cyl-svg" width="56" height="120" viewBox="0 0 56 120">
|
||||
<defs>
|
||||
<linearGradient id="vegGrad" x1="0" y1="0" x2="1" y2="0">
|
||||
<stop offset="0%" stop-color="#68a868"/>
|
||||
<stop offset="50%" stop-color="#88cc88"/>
|
||||
<stop offset="100%" stop-color="#68a868"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<ellipse cx="28" cy="8" rx="26" ry="6" fill="#68a868"/>
|
||||
<rect x="2" y="8" width="52" height="105" fill="url(#vegGrad)"/>
|
||||
<rect x="6" y="8" width="6" height="105" fill="rgba(255,255,255,0.08)"/>
|
||||
<ellipse cx="28" cy="8" rx="24" ry="5" fill="rgba(255,255,255,0.15)"/>
|
||||
<text x="28" y="108" text-anchor="middle" font-size="12">🥗</text>
|
||||
</svg>
|
||||
<div class="cyl-label">果蔬</div>
|
||||
</div>
|
||||
<!-- 肉蛋柱 -->
|
||||
<div class="cyl-item">
|
||||
<div class="cyl-value">68<span class="cyl-unit">克</span></div>
|
||||
<svg class="cyl-svg" width="56" height="105" viewBox="0 0 56 105">
|
||||
<defs>
|
||||
<linearGradient id="meatGrad" x1="0" y1="0" x2="1" y2="0">
|
||||
<stop offset="0%" stop-color="#cc1111"/>
|
||||
<stop offset="50%" stop-color="#ff2020"/>
|
||||
<stop offset="100%" stop-color="#cc1111"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<ellipse cx="28" cy="8" rx="26" ry="6" fill="#cc1111"/>
|
||||
<rect x="2" y="8" width="52" height="90" fill="url(#meatGrad)"/>
|
||||
<rect x="6" y="8" width="6" height="90" fill="rgba(255,255,255,0.08)"/>
|
||||
<ellipse cx="28" cy="8" rx="24" ry="5" fill="rgba(255,255,255,0.15)"/>
|
||||
<text x="28" y="94" text-anchor="middle" font-size="12">🥩</text>
|
||||
</svg>
|
||||
<div class="cyl-label">肉蛋</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
/* ===== 返回按钮:优先 history.back(),无历史记录时兜底跳模块导航 ===== */
|
||||
document.getElementById('backBtn').addEventListener('click', function() {
|
||||
if (history.length > 1) { history.back(); }
|
||||
else { window.location.href = 'index.html'; }
|
||||
});
|
||||
|
||||
/* ===== 设置按钮 ===== */
|
||||
document.getElementById('settingsBtn').addEventListener('click', function(e) {
|
||||
e.preventDefault();
|
||||
window.location.href = '04-settings.html';
|
||||
});
|
||||
|
||||
/* ===== 点击餐品信息卡 → 进入开餐界面 ===== */
|
||||
document.getElementById('dishInfoCard').addEventListener('click', function() {
|
||||
window.location.href = '01-meal-start.html';
|
||||
});
|
||||
|
||||
/* ===== 餐品占位图(SVG) ===== */
|
||||
function dishFoodSVG(w, h, colors) {
|
||||
var id = 'dg';
|
||||
return '<svg xmlns="http://www.w3.org/2000/svg" width="' + w + '" height="' + h + '" viewBox="0 0 ' + w + ' ' + h + '">' +
|
||||
'<defs><linearGradient id="' + id + '" x1="0" y1="0" x2="1" y2="1">' +
|
||||
'<stop offset="0%" stop-color="' + colors[0] + '"/>' +
|
||||
'<stop offset="50%" stop-color="' + colors[1] + '"/>' +
|
||||
'<stop offset="100%" stop-color="' + colors[2] + '"/></linearGradient></defs>' +
|
||||
'<rect width="' + w + '" height="' + h + '" fill="url(#' + id + ')"/>' +
|
||||
'<ellipse cx="' + (w*0.4) + '" cy="' + (h*0.45) + '" rx="' + (w*0.3) + '" ry="' + (h*0.25) + '" fill="rgba(255,255,255,0.08)"/>' +
|
||||
'<ellipse cx="' + (w*0.6) + '" cy="' + (h*0.55) + '" rx="' + (w*0.25) + '" ry="' + (h*0.2) + '" fill="rgba(0,0,0,0.1)"/>' +
|
||||
'<ellipse cx="' + (w*0.35) + '" cy="' + (h*0.35) + '" rx="' + (w*0.12) + '" ry="' + (h*0.1) + '" fill="rgba(255,255,255,0.15)"/>' +
|
||||
'</svg>';
|
||||
}
|
||||
document.getElementById('dishImg').innerHTML = dishFoodSVG(320, 320, ['#C87030', '#E8A040', '#D08028']);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -74,24 +74,44 @@
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.info-card__body { flex: 1; min-width: 0; }
|
||||
.info-card__name { font-size: 15px; font-weight: 600; }
|
||||
.info-card__id { font-size: 11px; color: rgba(255,255,255,0.4); }
|
||||
.info-card__right { text-align: right; flex-shrink: 0; }
|
||||
.info-card__label { font-size: 10px; color: rgba(255,255,255,0.4); }
|
||||
.info-card__value { font-size: 17px; font-weight: 700; color: #0AC4A8; }
|
||||
.info-card__unit { font-size: 10px; font-weight: 400; color: rgba(10,196,168,0.6); }
|
||||
/* 第一行:姓名 + ID 同行,强制不换行 */
|
||||
.info-card__line {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
gap: 8px;
|
||||
margin-bottom: 4px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.info-card__name { font-size: 22px; font-weight: 700; line-height: 1.1; }
|
||||
.info-card__id {
|
||||
font-size: 16px;
|
||||
color: rgba(255,255,255,0.55);
|
||||
font-weight: 500;
|
||||
}
|
||||
/* 第二行:推荐热量 + 范围值,强制不换行 */
|
||||
.info-card__heat {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
gap: 6px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.info-card__label {
|
||||
font-size: 11px;
|
||||
color: rgba(255,255,255,0.45);
|
||||
font-weight: 400;
|
||||
}
|
||||
.info-card__value {
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
color: #0AC4A8;
|
||||
line-height: 1.1;
|
||||
}
|
||||
.info-card__unit {
|
||||
font-size: 11px;
|
||||
font-weight: 400;
|
||||
color: rgba(10,196,168,0.7);
|
||||
}
|
||||
|
||||
.info-card__emoji {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.info-card__emoji svg {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.info-card--dish {
|
||||
cursor: pointer;
|
||||
transition: background 0.2s;
|
||||
@@ -99,9 +119,48 @@
|
||||
.info-card--dish:hover {
|
||||
background: rgba(74,144,217,0.12);
|
||||
}
|
||||
.info-card__dish-name { font-size: 14px; font-weight: 600; margin-bottom: 2px; }
|
||||
.info-card__dish-detail { font-size: 11px; color: rgba(255,255,255,0.45); line-height: 1.4; }
|
||||
.info-card__dish-detail em { font-style: normal; color: #0AC4A8; font-weight: 600; }
|
||||
/* 菜品行:名称 + 价格(靠右) */
|
||||
.info-card__dish-line {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 10px;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
.info-card__dish-name {
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
line-height: 1.1;
|
||||
white-space: nowrap;
|
||||
}
|
||||
/* 醒目价格:放大到 36px,带元/100g 单位 */
|
||||
.info-card__dish-price {
|
||||
font-size: 36px;
|
||||
font-weight: 800;
|
||||
color: #FFB236;
|
||||
line-height: 1;
|
||||
letter-spacing: -0.5px;
|
||||
white-space: nowrap;
|
||||
text-shadow: 0 1px 6px rgba(255,140,40,0.45);
|
||||
}
|
||||
.info-card__dish-price .price-unit {
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
color: rgba(255,178,54,0.85);
|
||||
margin-left: 3px;
|
||||
letter-spacing: 0;
|
||||
text-shadow: none;
|
||||
}
|
||||
.info-card__dish-heat {
|
||||
font-size: 11px;
|
||||
color: rgba(255,255,255,0.5);
|
||||
line-height: 1.3;
|
||||
}
|
||||
.info-card__dish-heat em {
|
||||
font-style: normal;
|
||||
color: #0AC4A8;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* 营养标题行 */
|
||||
.nutrition-header-row {
|
||||
@@ -118,6 +177,13 @@
|
||||
font-weight: 600;
|
||||
color: #fff;
|
||||
}
|
||||
/* 标题行内的推荐热量提示:小字号+淡青色,作为辅助信息弱化视觉权重 */
|
||||
.nutrition-header-row .n-title-hint {
|
||||
font-size: 12px;
|
||||
font-weight: 400;
|
||||
color: #0AC4A8;
|
||||
margin-left: 4px;
|
||||
}
|
||||
.nutrition-header-row .n-meal {
|
||||
font-size: 13px;
|
||||
color: rgba(255,255,255,0.5);
|
||||
@@ -262,18 +328,50 @@
|
||||
color: rgba(255,255,255,0.7);
|
||||
border-bottom: 1px solid rgba(255,255,255,0.04);
|
||||
}
|
||||
/* 合计区:单行排布,合计/重量/金额一行,金额最大化 */
|
||||
.pickup-footer {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr 1fr;
|
||||
padding: 10px 0;
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
border-top: 1px solid rgba(255,255,255,0.12);
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
justify-content: space-between;
|
||||
gap: 8px;
|
||||
margin-top: 6px;
|
||||
padding: 14px 14px;
|
||||
background: linear-gradient(135deg, rgba(255,178,54,0.2) 0%, rgba(255,140,40,0.32) 100%);
|
||||
border: 1px solid rgba(255,178,54,0.5);
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 4px 14px rgba(255,140,40,0.25);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.pickup-footer .lbl { color: rgba(255,255,255,0.55); }
|
||||
.pickup-footer .val { color: #fff; }
|
||||
.pickup-footer .price-val { color: #0AC4A8; }
|
||||
.pickup-footer .lbl {
|
||||
color: rgba(255,255,255,0.85);
|
||||
font-size: 14px;
|
||||
font-weight: 700;
|
||||
letter-spacing: 1px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.pickup-footer .val {
|
||||
color: #fff;
|
||||
font-size: 15px;
|
||||
font-weight: 700;
|
||||
white-space: nowrap;
|
||||
}
|
||||
/* 超大醒目金额:40px,800字重,橙色高亮+发光阴影 */
|
||||
.pickup-footer .price-val {
|
||||
color: #FFB236;
|
||||
font-size: 40px;
|
||||
font-weight: 800;
|
||||
text-shadow: 0 2px 10px rgba(255,140,40,0.6);
|
||||
letter-spacing: -1px;
|
||||
line-height: 1;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.pickup-footer .price-val::before {
|
||||
content: '\FFE5';
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
margin-right: 3px;
|
||||
vertical-align: 5px;
|
||||
}
|
||||
|
||||
/* Toast */
|
||||
.toast {
|
||||
@@ -324,26 +422,25 @@
|
||||
<div class="info-card">
|
||||
<div class="info-card__avatar">👤</div>
|
||||
<div class="info-card__body">
|
||||
<div class="info-card__name">张三</div>
|
||||
<div class="info-card__id">ID: 98369</div>
|
||||
</div>
|
||||
<div class="info-card__right">
|
||||
<div class="info-card__label">推荐热量</div>
|
||||
<div class="info-card__value">720 <span class="info-card__unit">千卡</span></div>
|
||||
<div class="info-card__line" style="justify-content:space-between;margin-bottom:0;">
|
||||
<span class="info-card__name">张三</span>
|
||||
<span class="info-card__id">编号: 98369</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="info-card info-card--dish" id="dishInfoCard">
|
||||
<div class="info-card__emoji" id="dishEmoji"></div>
|
||||
<div class="info-card__body">
|
||||
<div class="info-card__dish-name">宫保鸡丁</div>
|
||||
<div class="info-card__dish-detail">单价 <em>5</em> 元/100克 | 热量 <em>158.66</em> 千卡/100克</div>
|
||||
<div class="info-card__dish-line">
|
||||
<span class="info-card__dish-name">宫保鸡丁</span>
|
||||
<span class="info-card__dish-price">5<span class="price-unit">元/100g</span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 营养标题行 -->
|
||||
<div class="nutrition-header-row">
|
||||
<span class="n-title">📊 本餐次摄入</span>
|
||||
<span class="n-title">📊 本餐次摄入<span class="n-title-hint">(推荐热量 2000~2500 千卡)</span></span>
|
||||
<span>
|
||||
<span class="n-meal">当前餐次:早餐</span>
|
||||
<span class="n-time">06:00 ~ 10:19</span>
|
||||
@@ -478,7 +575,7 @@
|
||||
<div class="pickup-footer">
|
||||
<span class="lbl">合计</span>
|
||||
<span class="val">756克</span>
|
||||
<span class="price-val">20.90元</span>
|
||||
<span class="price-val">20.90</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -489,6 +586,11 @@
|
||||
</div>
|
||||
|
||||
<script>
|
||||
/* ===== 返回按钮:优先 history.back(),无历史记录时兜底跳模块导航 ===== */
|
||||
document.getElementById('backBtn').addEventListener('click', function() {
|
||||
if (history.length > 1) { history.back(); }
|
||||
else { window.location.href = 'index.html'; }
|
||||
});
|
||||
/**
|
||||
* 取餐界面交互逻辑
|
||||
*/
|
||||
@@ -527,24 +629,6 @@
|
||||
}, t);
|
||||
}
|
||||
|
||||
// 拟真食物图片
|
||||
function dishFoodSVG(w, h, colors) {
|
||||
var id = 'dg';
|
||||
return '<svg xmlns="http://www.w3.org/2000/svg" width="' + w + '" height="' + h + '" viewBox="0 0 ' + w + ' ' + h + '">' +
|
||||
'<defs><linearGradient id="' + id + '" x1="0" y1="0" x2="1" y2="1">' +
|
||||
'<stop offset="0%" stop-color="' + colors[0] + '"/>' +
|
||||
'<stop offset="50%" stop-color="' + colors[1] + '"/>' +
|
||||
'<stop offset="100%" stop-color="' + colors[2] + '"/></linearGradient></defs>' +
|
||||
'<rect width="' + w + '" height="' + h + '" fill="url(#' + id + ')"/>' +
|
||||
'<ellipse cx="' + (w*0.4) + '" cy="' + (h*0.45) + '" rx="' + (w*0.3) + '" ry="' + (h*0.25) + '" fill="rgba(255,255,255,0.08)"/>' +
|
||||
'<ellipse cx="' + (w*0.6) + '" cy="' + (h*0.55) + '" rx="' + (w*0.25) + '" ry="' + (h*0.2) + '" fill="rgba(0,0,0,0.1)"/>' +
|
||||
'<ellipse cx="' + (w*0.35) + '" cy="' + (h*0.35) + '" rx="' + (w*0.12) + '" ry="' + (h*0.1) + '" fill="rgba(255,255,255,0.15)"/>' +
|
||||
'</svg>';
|
||||
}
|
||||
// 宫保鸡丁:暖橙金
|
||||
document.getElementById('dishEmoji').innerHTML = dishFoodSVG(48, 48, ['#C87030', '#E8A040', '#D08028']);
|
||||
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -471,6 +471,11 @@
|
||||
|
||||
<!-- ===== 交互逻辑 ===== -->
|
||||
<script>
|
||||
/* ===== 返回按钮:优先 history.back(),无历史记录时兜底跳模块导航 ===== */
|
||||
document.getElementById('backBtn').addEventListener('click', function() {
|
||||
if (history.length > 1) { history.back(); }
|
||||
else { window.location.href = 'index.html'; }
|
||||
});
|
||||
var toast = document.getElementById('toast');
|
||||
|
||||
/**
|
||||
|
||||
@@ -270,6 +270,11 @@ body {
|
||||
</div>
|
||||
|
||||
<script>
|
||||
/* ===== 返回按钮:优先 history.back(),无历史记录时兜底跳模块导航 ===== */
|
||||
document.getElementById('backBtn').addEventListener('click', function() {
|
||||
if (history.length > 1) { history.back(); }
|
||||
else { window.location.href = 'index.html'; }
|
||||
});
|
||||
/**
|
||||
* 餐品采样界面交互逻辑
|
||||
*/
|
||||
|
||||
@@ -303,6 +303,11 @@ body {
|
||||
</div>
|
||||
|
||||
<script>
|
||||
/* ===== 返回按钮:优先 history.back(),无历史记录时兜底跳模块导航 ===== */
|
||||
document.getElementById('backBtn').addEventListener('click', function() {
|
||||
if (history.length > 1) { history.back(); }
|
||||
else { window.location.href = 'index.html'; }
|
||||
});
|
||||
/**
|
||||
* 采样历史页面交互逻辑
|
||||
*/
|
||||
|
||||
@@ -105,15 +105,10 @@
|
||||
<div class="card__title">取餐界面(单屏)</div>
|
||||
<div class="card__desc">取餐确认、订单生成与营养报告</div>
|
||||
</a>
|
||||
<a class="card" href="03-meal-pickup-dual-large.html">
|
||||
<a class="card" href="03-meal-pickup-dual.html">
|
||||
<span class="card__icon">🖥️</span>
|
||||
<div class="card__title">取餐界面(双屏·大屏)</div>
|
||||
<div class="card__desc">大屏取餐信息展示、用户信息与取餐记录</div>
|
||||
</a>
|
||||
<a class="card" href="03-meal-pickup-dual-small.html">
|
||||
<span class="card__icon">📊</span>
|
||||
<div class="card__title">取餐界面(双屏·小屏)</div>
|
||||
<div class="card__desc">小屏营养摄入柱状图与推荐热量展示</div>
|
||||
<div class="card__title">取餐界面(双屏)</div>
|
||||
<div class="card__desc">左大屏取餐信息+右小屏营养摄入柱状图同页展示</div>
|
||||
</a>
|
||||
<a class="card" href="04-settings.html">
|
||||
<span class="card__icon">⚙️</span>
|
||||
|
||||
@@ -0,0 +1,751 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=1280, initial-scale=1.0">
|
||||
<title>结算设备 - 收银员登录 | 蚁熊智能餐养平台</title>
|
||||
<style>
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
/* 外层视口:全屏深色背景,承载居中 PAD 外壳 */
|
||||
body {
|
||||
font-family: -apple-system, "Microsoft YaHei", "PingFang SC", sans-serif;
|
||||
background: #05080f;
|
||||
color: #fff;
|
||||
min-height: 100vh;
|
||||
min-width: 1280px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 20px;
|
||||
}
|
||||
/* PAD 设备外壳 */
|
||||
.device-frame {
|
||||
width: 1280px;
|
||||
height: 720px;
|
||||
background: #0e1326;
|
||||
border-radius: 24px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 24px 64px rgba(0, 0, 0, 0.6), 0 0 0 1px rgba(255, 255, 255, 0.04);
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
/* ===== 顶部导航栏 ===== */
|
||||
.top-bar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 44px;
|
||||
background: #1a2b4a;
|
||||
padding: 0 20px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.back-btn {
|
||||
font-size: 13px;
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
transition: color 0.2s;
|
||||
}
|
||||
.back-btn:hover { color: #fff; }
|
||||
.top-bar__title {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
color: rgba(255, 255, 255, 0.85);
|
||||
}
|
||||
.top-bar__meta {
|
||||
font-size: 12px;
|
||||
color: rgba(255, 255, 255, 0.5);
|
||||
font-family: Menlo, Consolas, monospace;
|
||||
}
|
||||
|
||||
/* ===== 主内容:左右两列 ===== */
|
||||
.main-area {
|
||||
flex: 1;
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 360px;
|
||||
gap: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* ===== 左列:人脸识别区 ===== */
|
||||
.camera-col {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 28px 28px 20px;
|
||||
gap: 18px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.col-label {
|
||||
font-size: 12px;
|
||||
color: rgba(255, 255, 255, 0.4);
|
||||
font-weight: 500;
|
||||
letter-spacing: 1.5px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
.col-label__bar {
|
||||
width: 3px;
|
||||
height: 12px;
|
||||
background: #4a90d9;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
/* 摄像头预览框 */
|
||||
.camera-frame {
|
||||
flex: 1;
|
||||
background: #050a1a;
|
||||
border-radius: 16px;
|
||||
position: relative;
|
||||
border: 1px solid rgba(74, 144, 217, 0.2);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
overflow: hidden;
|
||||
min-height: 0;
|
||||
}
|
||||
/* 背景径向渐变模拟摄像头画面 */
|
||||
.camera-frame__bg {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background:
|
||||
radial-gradient(circle at 50% 40%, rgba(74, 144, 217, 0.12) 0%, transparent 60%),
|
||||
radial-gradient(circle at 50% 100%, rgba(74, 144, 217, 0.06) 0%, transparent 70%);
|
||||
}
|
||||
/* 十字虚线参考线 */
|
||||
.camera-frame__cross-h, .camera-frame__cross-v {
|
||||
position: absolute;
|
||||
pointer-events: none;
|
||||
z-index: 2;
|
||||
}
|
||||
.camera-frame__cross-h {
|
||||
top: 50%; left: 12%; right: 12%;
|
||||
height: 1px;
|
||||
border-top: 1px dashed rgba(74, 144, 217, 0.25);
|
||||
}
|
||||
.camera-frame__cross-v {
|
||||
left: 50%; top: 15%; bottom: 15%;
|
||||
width: 1px;
|
||||
border-left: 1px dashed rgba(74, 144, 217, 0.25);
|
||||
}
|
||||
/* 四角识别标记 */
|
||||
.corner {
|
||||
position: absolute;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
z-index: 3;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
.corner--tl { top: 18px; left: 18px; border-top: 2px solid #4a90d9; border-left: 2px solid #4a90d9; }
|
||||
.corner--tr { top: 18px; right: 18px; border-top: 2px solid #4a90d9; border-right: 2px solid #4a90d9; }
|
||||
.corner--bl { bottom: 18px; left: 18px; border-bottom: 2px solid #4a90d9; border-left: 2px solid #4a90d9; }
|
||||
.corner--br { bottom: 18px; right: 18px; border-bottom: 2px solid #4a90d9; border-right: 2px solid #4a90d9; }
|
||||
/* 识别中四角变绿 */
|
||||
.camera-frame.success .corner { border-color: #52c41a; }
|
||||
|
||||
/* 人脸头像占位(模拟检测到人脸) */
|
||||
.face-placeholder {
|
||||
width: 160px;
|
||||
height: 160px;
|
||||
border-radius: 50%;
|
||||
background: radial-gradient(circle at 50% 40%, rgba(74, 144, 217, 0.25), rgba(74, 144, 217, 0.05) 70%);
|
||||
border: 2px solid rgba(74, 144, 217, 0.5);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 64px;
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
position: relative;
|
||||
z-index: 4;
|
||||
box-shadow: 0 0 40px rgba(74, 144, 217, 0.3);
|
||||
}
|
||||
/* 识别中扫描线 */
|
||||
.scan-line {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
width: 180px;
|
||||
height: 2px;
|
||||
background: linear-gradient(90deg, transparent, #4a90d9 50%, transparent);
|
||||
transform: translate(-50%, -50%);
|
||||
z-index: 5;
|
||||
box-shadow: 0 0 8px rgba(74, 144, 217, 0.6);
|
||||
opacity: 0;
|
||||
transition: opacity 0.3s;
|
||||
}
|
||||
.camera-frame.scanning .scan-line {
|
||||
opacity: 1;
|
||||
animation: scanMove 1.8s ease-in-out infinite;
|
||||
}
|
||||
@keyframes scanMove {
|
||||
0%, 100% { transform: translate(-50%, -80px); }
|
||||
50% { transform: translate(-50%, 80px); }
|
||||
}
|
||||
|
||||
/* 识别状态文字 */
|
||||
.camera-status {
|
||||
position: absolute;
|
||||
bottom: 24px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
padding: 8px 18px;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
border: 1px solid rgba(74, 144, 217, 0.35);
|
||||
border-radius: 20px;
|
||||
font-size: 13px;
|
||||
color: rgba(255, 255, 255, 0.85);
|
||||
backdrop-filter: blur(8px);
|
||||
z-index: 6;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.camera-status__dot {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 50%;
|
||||
background: #4a90d9;
|
||||
box-shadow: 0 0 8px #4a90d9;
|
||||
animation: pulse 1.4s ease-in-out infinite;
|
||||
}
|
||||
.camera-frame.success .camera-status {
|
||||
border-color: rgba(82, 196, 26, 0.45);
|
||||
color: #4ade80;
|
||||
}
|
||||
.camera-frame.success .camera-status__dot {
|
||||
background: #52c41a;
|
||||
box-shadow: 0 0 8px #52c41a;
|
||||
animation: none;
|
||||
}
|
||||
.camera-frame.error .camera-status {
|
||||
border-color: rgba(245, 34, 45, 0.45);
|
||||
color: #ff6b6b;
|
||||
}
|
||||
.camera-frame.error .camera-status__dot {
|
||||
background: #f5222d;
|
||||
box-shadow: 0 0 8px #f5222d;
|
||||
animation: none;
|
||||
}
|
||||
@keyframes pulse {
|
||||
0%, 100% { opacity: 1; transform: scale(1); }
|
||||
50% { opacity: 0.5; transform: scale(1.2); }
|
||||
}
|
||||
|
||||
/* 识别成功后展示的姓名浮层 */
|
||||
.face-success-overlay {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: rgba(5, 10, 26, 0.85);
|
||||
backdrop-filter: blur(4px);
|
||||
display: none;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
z-index: 10;
|
||||
animation: fadeIn 0.3s ease;
|
||||
}
|
||||
.camera-frame.success .face-success-overlay { display: flex; }
|
||||
@keyframes fadeIn {
|
||||
from { opacity: 0; }
|
||||
to { opacity: 1; }
|
||||
}
|
||||
.success-avatar {
|
||||
width: 110px;
|
||||
height: 110px;
|
||||
border-radius: 50%;
|
||||
background: linear-gradient(135deg, #52c41a 0%, #0AC4A8 100%);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 48px;
|
||||
color: #fff;
|
||||
font-weight: 600;
|
||||
box-shadow: 0 8px 32px rgba(82, 196, 26, 0.4);
|
||||
}
|
||||
.success-info { text-align: center; }
|
||||
.success-name {
|
||||
font-size: 22px;
|
||||
font-weight: 700;
|
||||
color: #fff;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
.success-meta {
|
||||
font-size: 12px;
|
||||
color: rgba(255, 255, 255, 0.5);
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
.success-tip {
|
||||
font-size: 12px;
|
||||
color: #4ade80;
|
||||
margin-top: 8px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
/* 左列底部说明栏 */
|
||||
.tip-bar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 12px 16px;
|
||||
background: rgba(26, 43, 74, 0.4);
|
||||
border: 1px solid rgba(255, 255, 255, 0.06);
|
||||
border-radius: 10px;
|
||||
}
|
||||
.tip-bar__left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
font-size: 12px;
|
||||
color: rgba(255, 255, 255, 0.65);
|
||||
}
|
||||
.tip-bar__icon {
|
||||
font-size: 14px;
|
||||
}
|
||||
.tip-bar__right {
|
||||
font-size: 11px;
|
||||
color: rgba(255, 255, 255, 0.4);
|
||||
font-family: Menlo, Consolas, monospace;
|
||||
}
|
||||
|
||||
/* ===== 右列:班次信息 + 操作入口 ===== */
|
||||
.info-col {
|
||||
background: rgba(26, 43, 74, 0.3);
|
||||
border-left: 1px solid rgba(255, 255, 255, 0.06);
|
||||
padding: 28px 24px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
overflow-y: auto;
|
||||
scrollbar-width: none;
|
||||
}
|
||||
.info-col::-webkit-scrollbar { display: none; }
|
||||
|
||||
/* 大时钟 */
|
||||
.clock-card {
|
||||
text-align: center;
|
||||
padding: 20px 0 8px;
|
||||
}
|
||||
.clock-card__time {
|
||||
font-size: 44px;
|
||||
font-weight: 200;
|
||||
color: #fff;
|
||||
font-family: Menlo, Consolas, "Courier New", monospace;
|
||||
line-height: 1;
|
||||
letter-spacing: 2px;
|
||||
}
|
||||
.clock-card__date {
|
||||
font-size: 13px;
|
||||
color: rgba(255, 255, 255, 0.5);
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
/* 班次信息卡 */
|
||||
.shift-card {
|
||||
background: #1a2b4a;
|
||||
border: 1px solid rgba(74, 144, 217, 0.25);
|
||||
border-radius: 10px;
|
||||
padding: 14px 16px;
|
||||
}
|
||||
.shift-card__title {
|
||||
font-size: 11px;
|
||||
color: rgba(255, 255, 255, 0.5);
|
||||
letter-spacing: 1px;
|
||||
margin-bottom: 10px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
}
|
||||
.shift-card__title::before {
|
||||
content: "";
|
||||
width: 3px;
|
||||
height: 11px;
|
||||
background: #4a90d9;
|
||||
border-radius: 2px;
|
||||
}
|
||||
.shift-card__row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 6px 0;
|
||||
font-size: 13px;
|
||||
}
|
||||
.shift-card__row + .shift-card__row {
|
||||
border-top: 1px dashed rgba(255, 255, 255, 0.06);
|
||||
}
|
||||
.shift-card__label {
|
||||
color: rgba(255, 255, 255, 0.55);
|
||||
font-size: 12px;
|
||||
}
|
||||
.shift-card__value {
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
font-weight: 600;
|
||||
}
|
||||
.meal-tag {
|
||||
font-size: 10px;
|
||||
line-height: 1;
|
||||
padding: 4px 8px;
|
||||
border-radius: 9px;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.3px;
|
||||
}
|
||||
.meal-tag--breakfast {
|
||||
background: rgba(250, 140, 22, 0.18);
|
||||
color: #fb923c;
|
||||
border: 1px solid rgba(250, 140, 22, 0.35);
|
||||
}
|
||||
.meal-tag--lunch {
|
||||
background: rgba(37, 99, 235, 0.18);
|
||||
color: #60a5fa;
|
||||
border: 1px solid rgba(37, 99, 235, 0.35);
|
||||
}
|
||||
.meal-tag--dinner {
|
||||
background: rgba(34, 197, 94, 0.18);
|
||||
color: #4ade80;
|
||||
border: 1px solid rgba(34, 197, 94, 0.35);
|
||||
}
|
||||
|
||||
/* 设备状态卡 */
|
||||
.device-card {
|
||||
background: #1a2b4a;
|
||||
border: 1px solid rgba(255, 255, 255, 0.06);
|
||||
border-radius: 10px;
|
||||
padding: 14px 16px;
|
||||
}
|
||||
.device-card__row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 5px 0;
|
||||
font-size: 12px;
|
||||
}
|
||||
.device-card__label {
|
||||
color: rgba(255, 255, 255, 0.55);
|
||||
}
|
||||
.device-card__value {
|
||||
color: rgba(255, 255, 255, 0.85);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 5px;
|
||||
}
|
||||
.status-dot {
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
border-radius: 50%;
|
||||
background: #52c41a;
|
||||
box-shadow: 0 0 6px #52c41a;
|
||||
}
|
||||
.status-dot--offline { background: #f5222d; box-shadow: 0 0 6px #f5222d; }
|
||||
|
||||
/* 快捷入口 */
|
||||
.quick-entry {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 10px;
|
||||
margin-top: auto;
|
||||
padding-top: 10px;
|
||||
}
|
||||
.quick-btn {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
padding: 14px 10px;
|
||||
background: rgba(255, 255, 255, 0.03);
|
||||
border: 1px solid rgba(255, 255, 255, 0.08);
|
||||
border-radius: 10px;
|
||||
text-decoration: none;
|
||||
color: rgba(255, 255, 255, 0.75);
|
||||
font-size: 11px;
|
||||
transition: all 0.2s;
|
||||
cursor: pointer;
|
||||
}
|
||||
.quick-btn:hover {
|
||||
background: rgba(74, 144, 217, 0.08);
|
||||
border-color: rgba(74, 144, 217, 0.35);
|
||||
color: #fff;
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
.quick-btn__icon {
|
||||
font-size: 22px;
|
||||
}
|
||||
|
||||
/* 底部:登录失败次数提示 */
|
||||
.fail-counter {
|
||||
display: none;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 6px;
|
||||
padding: 8px 12px;
|
||||
background: rgba(245, 34, 45, 0.1);
|
||||
border: 1px solid rgba(245, 34, 45, 0.3);
|
||||
border-radius: 8px;
|
||||
font-size: 12px;
|
||||
color: #ff6b6b;
|
||||
}
|
||||
.fail-counter.show { display: flex; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="device-frame">
|
||||
|
||||
<!-- 顶部导航 -->
|
||||
<div class="top-bar">
|
||||
<a class="back-btn" href="index.html">◀ 返回</a>
|
||||
<span class="top-bar__title">收银员登录</span>
|
||||
<span class="top-bar__meta" id="topMeta">2026-08-06 周四</span>
|
||||
</div>
|
||||
|
||||
<!-- 主内容 -->
|
||||
<div class="main-area">
|
||||
|
||||
<!-- 左列:人脸识别区 -->
|
||||
<div class="camera-col">
|
||||
<div class="col-label">
|
||||
<span class="col-label__bar"></span>
|
||||
人脸识别登录
|
||||
</div>
|
||||
|
||||
<div class="camera-frame" id="cameraFrame">
|
||||
<div class="camera-frame__bg"></div>
|
||||
<div class="camera-frame__cross-h"></div>
|
||||
<div class="camera-frame__cross-v"></div>
|
||||
<div class="corner corner--tl"></div>
|
||||
<div class="corner corner--tr"></div>
|
||||
<div class="corner corner--bl"></div>
|
||||
<div class="corner corner--br"></div>
|
||||
|
||||
<!-- 人脸占位 -->
|
||||
<div class="face-placeholder">👤</div>
|
||||
<!-- 扫描线 -->
|
||||
<div class="scan-line"></div>
|
||||
|
||||
<!-- 状态提示 -->
|
||||
<div class="camera-status">
|
||||
<span class="camera-status__dot"></span>
|
||||
<span id="statusText">请面向摄像头进行识别</span>
|
||||
</div>
|
||||
|
||||
<!-- 识别成功浮层 -->
|
||||
<div class="face-success-overlay">
|
||||
<div class="success-avatar">张</div>
|
||||
<div class="success-info">
|
||||
<div class="success-name">张三</div>
|
||||
<div class="success-meta">工号:CS001 · 一楼结算台</div>
|
||||
<div class="success-tip">✅ 识别成功,正在登录...</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="tip-bar">
|
||||
<div class="tip-bar__left">
|
||||
<span class="tip-bar__icon">📷</span>
|
||||
<span>请保持面部正对摄像头,光线充足,摘掉口罩/墨镜</span>
|
||||
</div>
|
||||
<div class="tip-bar__right">设备:CHK-001</div>
|
||||
</div>
|
||||
|
||||
<div class="fail-counter" id="failCounter">
|
||||
⚠️ 识别失败,今日剩余尝试次数:<span id="failCount">3</span> 次
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 右列:班次信息 + 操作入口 -->
|
||||
<div class="info-col">
|
||||
|
||||
<!-- 大时钟 -->
|
||||
<div class="clock-card">
|
||||
<div class="clock-card__time" id="clockTime">12:30:45</div>
|
||||
<div class="clock-card__date" id="clockDate">2026-08-06 周四</div>
|
||||
</div>
|
||||
|
||||
<!-- 班次信息卡 -->
|
||||
<div class="shift-card">
|
||||
<div class="shift-card__title">当前班次</div>
|
||||
<div class="shift-card__row">
|
||||
<span class="shift-card__label">所属食堂</span>
|
||||
<span class="shift-card__value">数味餐厅</span>
|
||||
</div>
|
||||
<div class="shift-card__row">
|
||||
<span class="shift-card__label">餐次</span>
|
||||
<span class="meal-tag meal-tag--lunch" id="mealTag">午餐</span>
|
||||
</div>
|
||||
<div class="shift-card__row">
|
||||
<span class="shift-card__label">餐线</span>
|
||||
<span class="shift-card__value">一楼 A 区 2 号餐线</span>
|
||||
</div>
|
||||
<div class="shift-card__row">
|
||||
<span class="shift-card__label">班次时段</span>
|
||||
<span class="shift-card__value">11:00 - 14:00</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 设备状态卡 -->
|
||||
<div class="device-card">
|
||||
<div class="shift-card__title" style="margin-bottom:8px;">设备状态</div>
|
||||
<div class="device-card__row">
|
||||
<span class="device-card__label">网络连接</span>
|
||||
<span class="device-card__value"><span class="status-dot"></span>正常</span>
|
||||
</div>
|
||||
<div class="device-card__row">
|
||||
<span class="device-card__label">摄像头</span>
|
||||
<span class="device-card__value"><span class="status-dot"></span>就绪</span>
|
||||
</div>
|
||||
<div class="device-card__row">
|
||||
<span class="device-card__label">小票打印机</span>
|
||||
<span class="device-card__value"><span class="status-dot"></span>就绪</span>
|
||||
</div>
|
||||
<div class="device-card__row">
|
||||
<span class="device-card__label">扫码器</span>
|
||||
<span class="device-card__value"><span class="status-dot"></span>就绪</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 快捷入口 -->
|
||||
<div class="quick-entry">
|
||||
<a class="quick-btn" href="javascript:void(0)" onclick="showToast('请联系管理员在后台开启维护模式')">
|
||||
<span class="quick-btn__icon">🔧</span>
|
||||
<span>管理员设置</span>
|
||||
</a>
|
||||
<a class="quick-btn" href="javascript:void(0)" onclick="showToast('已上报故障,运维人员将尽快处理')">
|
||||
<span class="quick-btn__icon">📡</span>
|
||||
<span>故障报修</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- Toast -->
|
||||
<div class="toast" id="toast"></div>
|
||||
|
||||
<style>
|
||||
/* Toast */
|
||||
.toast {
|
||||
position: fixed;
|
||||
top: 60px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%) translateY(-20px);
|
||||
background: rgba(0, 0, 0, 0.85);
|
||||
color: #fff;
|
||||
padding: 12px 28px;
|
||||
border-radius: 8px;
|
||||
font-size: 13px;
|
||||
z-index: 1000;
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
transition: opacity 0.3s, transform 0.3s, visibility 0.3s;
|
||||
white-space: nowrap;
|
||||
pointer-events: none;
|
||||
max-width: 90%;
|
||||
text-align: center;
|
||||
line-height: 1.5;
|
||||
}
|
||||
.toast.show {
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
transform: translateX(-50%) translateY(0);
|
||||
}
|
||||
.toast--warn { background: rgba(250, 173, 22, 0.92); }
|
||||
.toast--success { background: rgba(82, 196, 26, 0.92); }
|
||||
</style>
|
||||
|
||||
<script>
|
||||
/* ==================== 实时时钟 ==================== */
|
||||
function updateClock() {
|
||||
var now = new Date();
|
||||
var hh = String(now.getHours()).padStart(2, '0');
|
||||
var mm = String(now.getMinutes()).padStart(2, '0');
|
||||
var ss = String(now.getSeconds()).padStart(2, '0');
|
||||
var timeStr = hh + ':' + mm + ':' + ss;
|
||||
|
||||
var year = now.getFullYear();
|
||||
var month = String(now.getMonth() + 1).padStart(2, '0');
|
||||
var date = String(now.getDate()).padStart(2, '0');
|
||||
var weekDay = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'][now.getDay()];
|
||||
var dateStr = year + '-' + month + '-' + date + ' ' + weekDay;
|
||||
|
||||
document.getElementById('clockTime').textContent = timeStr;
|
||||
document.getElementById('clockDate').textContent = dateStr;
|
||||
document.getElementById('topMeta').textContent = dateStr;
|
||||
}
|
||||
|
||||
/* 根据当前小时自动判断餐次 */
|
||||
function detectMealType() {
|
||||
var hour = new Date().getHours();
|
||||
var mealTag = document.getElementById('mealTag');
|
||||
if (hour >= 6 && hour < 10) {
|
||||
mealTag.className = 'meal-tag meal-tag--breakfast';
|
||||
mealTag.textContent = '早餐';
|
||||
} else if (hour >= 10 && hour < 14) {
|
||||
mealTag.className = 'meal-tag meal-tag--lunch';
|
||||
mealTag.textContent = '午餐';
|
||||
} else if (hour >= 16 && hour < 21) {
|
||||
mealTag.className = 'meal-tag meal-tag--dinner';
|
||||
mealTag.textContent = '晚餐';
|
||||
} else {
|
||||
mealTag.className = 'meal-tag meal-tag--lunch';
|
||||
mealTag.textContent = '非餐时段';
|
||||
}
|
||||
}
|
||||
|
||||
/* ==================== 人脸识别流程模拟 ==================== */
|
||||
var frame = document.getElementById('cameraFrame');
|
||||
var statusText = document.getElementById('statusText');
|
||||
var failCounter = document.getElementById('failCounter');
|
||||
var failCountEl = document.getElementById('failCount');
|
||||
var failCount = 3;
|
||||
|
||||
function startRecognition() {
|
||||
/* 阶段 1:提示用户 */
|
||||
frame.className = 'camera-frame';
|
||||
statusText.textContent = '请面向摄像头进行识别';
|
||||
|
||||
/* 阶段 2:1.5s 后开始扫描 */
|
||||
setTimeout(function() {
|
||||
frame.classList.add('scanning');
|
||||
statusText.textContent = '人脸识别中...';
|
||||
}, 1500);
|
||||
|
||||
/* 阶段 3:4s 后识别成功,1.5s 后跳转待机页 */
|
||||
setTimeout(function() {
|
||||
frame.classList.remove('scanning');
|
||||
frame.classList.add('success');
|
||||
statusText.textContent = '识别成功';
|
||||
setTimeout(function() {
|
||||
window.location.href = '02-standby.html';
|
||||
}, 1500);
|
||||
}, 4000);
|
||||
}
|
||||
|
||||
/* ==================== Toast ==================== */
|
||||
function showToast(msg, type) {
|
||||
var el = document.getElementById('toast');
|
||||
el.textContent = msg;
|
||||
el.className = 'toast';
|
||||
if (type === 'success') el.classList.add('toast--success');
|
||||
if (type === 'warn') el.classList.add('toast--warn');
|
||||
el.classList.add('show');
|
||||
clearTimeout(el._timer);
|
||||
el._timer = setTimeout(function() { el.classList.remove('show'); }, 2200);
|
||||
}
|
||||
|
||||
/* ==================== 初始化 ==================== */
|
||||
updateClock();
|
||||
detectMealType();
|
||||
setInterval(updateClock, 1000);
|
||||
/* 自动启动人脸识别模拟 */
|
||||
setTimeout(startRecognition, 800);
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,495 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=1280, initial-scale=1.0">
|
||||
<title>结算设备 - 待机 | 蚁熊智能餐养平台</title>
|
||||
<style>
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
body {
|
||||
font-family: -apple-system, "Microsoft YaHei", "PingFang SC", sans-serif;
|
||||
background: #05080f;
|
||||
color: #fff;
|
||||
min-height: 100vh;
|
||||
min-width: 1280px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 20px;
|
||||
}
|
||||
.device-frame {
|
||||
width: 1280px;
|
||||
height: 720px;
|
||||
background: #0e1326;
|
||||
border-radius: 24px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 24px 64px rgba(0, 0, 0, 0.6), 0 0 0 1px rgba(255, 255, 255, 0.04);
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
/* 顶部导航 */
|
||||
.top-bar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 44px;
|
||||
background: #1a2b4a;
|
||||
padding: 0 20px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.back-btn {
|
||||
font-size: 13px;
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
transition: color 0.2s;
|
||||
}
|
||||
.back-btn:hover { color: #fff; }
|
||||
.top-bar__title {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
color: rgba(255, 255, 255, 0.85);
|
||||
}
|
||||
.top-bar__meta {
|
||||
font-size: 12px;
|
||||
color: rgba(255, 255, 255, 0.5);
|
||||
font-family: Menlo, Consolas, monospace;
|
||||
}
|
||||
|
||||
/* 主内容 */
|
||||
.main-area {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 32px 56px 28px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* 顶部欢迎区 */
|
||||
.welcome {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-start;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
.welcome__left { display: flex; flex-direction: column; gap: 6px; }
|
||||
.welcome__hello {
|
||||
font-size: 28px;
|
||||
font-weight: 600;
|
||||
color: #fff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
}
|
||||
.welcome__name { color: #4a90d9; }
|
||||
.welcome__sub {
|
||||
font-size: 13px;
|
||||
color: rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
.welcome__right {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
align-items: center;
|
||||
}
|
||||
.cashier-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 6px 12px 6px 6px;
|
||||
background: rgba(26, 43, 74, 0.6);
|
||||
border: 1px solid rgba(255, 255, 255, 0.06);
|
||||
border-radius: 22px;
|
||||
}
|
||||
.cashier-info__avatar {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
border-radius: 50%;
|
||||
background: linear-gradient(135deg, #4a90d9, #0AC4A8);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
}
|
||||
.cashier-info__text { font-size: 12px; color: rgba(255, 255, 255, 0.85); }
|
||||
.logout-btn {
|
||||
padding: 6px 14px;
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
border-radius: 18px;
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
font-size: 12px;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
text-decoration: none;
|
||||
}
|
||||
.logout-btn:hover {
|
||||
background: rgba(245, 34, 45, 0.15);
|
||||
border-color: rgba(245, 34, 45, 0.35);
|
||||
color: #ff6b6b;
|
||||
}
|
||||
|
||||
/* 中央:核心动作区 */
|
||||
.hero {
|
||||
flex: 1;
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 24px;
|
||||
margin-bottom: 24px;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
/* 左:大时钟 + 待机动作 */
|
||||
.hero__left {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
gap: 24px;
|
||||
padding: 28px 32px;
|
||||
background: linear-gradient(135deg, rgba(74, 144, 217, 0.12) 0%, rgba(26, 43, 74, 0.4) 100%);
|
||||
border: 1px solid rgba(74, 144, 217, 0.2);
|
||||
border-radius: 18px;
|
||||
}
|
||||
.big-clock {
|
||||
font-size: 76px;
|
||||
font-weight: 200;
|
||||
font-family: Menlo, Consolas, "Courier New", monospace;
|
||||
line-height: 1;
|
||||
letter-spacing: 3px;
|
||||
color: #fff;
|
||||
}
|
||||
.big-date {
|
||||
font-size: 16px;
|
||||
color: rgba(255, 255, 255, 0.55);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
}
|
||||
.meal-tag-large {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
padding: 6px 14px;
|
||||
border-radius: 16px;
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
}
|
||||
.meal-tag-large--lunch {
|
||||
background: rgba(37, 99, 235, 0.18);
|
||||
color: #60a5fa;
|
||||
border: 1px solid rgba(37, 99, 235, 0.35);
|
||||
}
|
||||
|
||||
/* 开始结算按钮 */
|
||||
.start-checkout {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 14px;
|
||||
padding: 22px 28px;
|
||||
background: linear-gradient(135deg, #4a90d9, #3a7bc8);
|
||||
border: none;
|
||||
border-radius: 14px;
|
||||
cursor: pointer;
|
||||
transition: all 0.25s;
|
||||
text-decoration: none;
|
||||
box-shadow: 0 8px 24px rgba(74, 144, 217, 0.3);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
.start-checkout:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 12px 32px rgba(74, 144, 217, 0.45);
|
||||
}
|
||||
.start-checkout:active { transform: scale(0.99); }
|
||||
.start-checkout__icon {
|
||||
font-size: 32px;
|
||||
}
|
||||
.start-checkout__text {
|
||||
text-align: left;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 2px;
|
||||
}
|
||||
.start-checkout__title {
|
||||
font-size: 20px;
|
||||
font-weight: 700;
|
||||
color: #fff;
|
||||
}
|
||||
.start-checkout__desc {
|
||||
font-size: 12px;
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
}
|
||||
/* 呼吸灯 */
|
||||
.start-checkout::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: linear-gradient(45deg, transparent 30%, rgba(255,255,255,0.15) 50%, transparent 70%);
|
||||
transform: translateX(-100%);
|
||||
animation: shimmer 2.5s ease-in-out infinite;
|
||||
}
|
||||
@keyframes shimmer {
|
||||
0%, 100% { transform: translateX(-100%); }
|
||||
50% { transform: translateX(100%); }
|
||||
}
|
||||
|
||||
/* 右:今日数据预览 */
|
||||
.hero__right {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 22px 24px;
|
||||
background: rgba(26, 43, 74, 0.4);
|
||||
border: 1px solid rgba(255, 255, 255, 0.06);
|
||||
border-radius: 18px;
|
||||
}
|
||||
.panel-title {
|
||||
font-size: 13px;
|
||||
color: rgba(255, 255, 255, 0.55);
|
||||
letter-spacing: 1px;
|
||||
margin-bottom: 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
.panel-title::before {
|
||||
content: "";
|
||||
width: 3px;
|
||||
height: 13px;
|
||||
background: #4a90d9;
|
||||
border-radius: 2px;
|
||||
}
|
||||
.kpi-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 12px;
|
||||
flex: 1;
|
||||
}
|
||||
.kpi-cell {
|
||||
background: rgba(0, 0, 0, 0.2);
|
||||
border: 1px solid rgba(255, 255, 255, 0.04);
|
||||
border-radius: 10px;
|
||||
padding: 14px 16px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 6px;
|
||||
}
|
||||
.kpi-cell__label {
|
||||
font-size: 11px;
|
||||
color: rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
.kpi-cell__value {
|
||||
font-size: 22px;
|
||||
font-weight: 700;
|
||||
color: #fff;
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
gap: 4px;
|
||||
}
|
||||
.kpi-cell__unit {
|
||||
font-size: 12px;
|
||||
font-weight: 400;
|
||||
color: rgba(255, 255, 255, 0.55);
|
||||
}
|
||||
.kpi-cell__value--green { color: #4ade80; }
|
||||
.kpi-cell__value--gold { color: #fbbf24; }
|
||||
.kpi-cell__hint {
|
||||
font-size: 10px;
|
||||
color: rgba(255, 255, 255, 0.35);
|
||||
}
|
||||
|
||||
/* 底部:功能入口横排 */
|
||||
.bottom-entry {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
gap: 14px;
|
||||
}
|
||||
.entry-card {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
padding: 14px 18px;
|
||||
background: rgba(26, 43, 74, 0.5);
|
||||
border: 1px solid rgba(255, 255, 255, 0.06);
|
||||
border-radius: 12px;
|
||||
text-decoration: none;
|
||||
transition: all 0.2s;
|
||||
cursor: pointer;
|
||||
}
|
||||
.entry-card:hover {
|
||||
transform: translateY(-2px);
|
||||
background: rgba(74, 144, 217, 0.1);
|
||||
border-color: rgba(74, 144, 217, 0.35);
|
||||
box-shadow: 0 6px 20px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
.entry-card__icon {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: 10px;
|
||||
background: rgba(74, 144, 217, 0.15);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 20px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.entry-card__icon--gold { background: rgba(251, 191, 36, 0.15); }
|
||||
.entry-card__icon--purple { background: rgba(168, 85, 247, 0.15); }
|
||||
.entry-card__icon--green { background: rgba(82, 196, 26, 0.15); }
|
||||
.entry-card__text { display: flex; flex-direction: column; gap: 2px; }
|
||||
.entry-card__title {
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: #fff;
|
||||
}
|
||||
.entry-card__desc {
|
||||
font-size: 11px;
|
||||
color: rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="device-frame">
|
||||
|
||||
<!-- 顶部导航 -->
|
||||
<div class="top-bar">
|
||||
<a class="back-btn" href="index.html">◀ 返回主页</a>
|
||||
<span class="top-bar__title">结算台待机</span>
|
||||
<span class="top-bar__meta" id="topMeta">2026-08-06 周四</span>
|
||||
</div>
|
||||
|
||||
<!-- 主内容 -->
|
||||
<div class="main-area">
|
||||
|
||||
<!-- 顶部欢迎区 -->
|
||||
<div class="welcome">
|
||||
<div class="welcome__left">
|
||||
<div class="welcome__hello">
|
||||
👋 中午好,<span class="welcome__name">张三</span>
|
||||
</div>
|
||||
<div class="welcome__sub">数味餐厅 · 一楼 A 区 2 号餐线 · 等待顾客取餐</div>
|
||||
</div>
|
||||
<div class="welcome__right">
|
||||
<div class="cashier-info">
|
||||
<div class="cashier-info__avatar">张</div>
|
||||
<div class="cashier-info__text">CS001 · 张三</div>
|
||||
</div>
|
||||
<a class="logout-btn" href="01-login.html" onclick="return confirm('确定退出登录吗?');">退出登录</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 中央核心动作区 -->
|
||||
<div class="hero">
|
||||
|
||||
<!-- 左:大时钟 + 开始结算 -->
|
||||
<div class="hero__left">
|
||||
<div>
|
||||
<div class="big-clock" id="bigClock">12:30:45</div>
|
||||
<div class="big-date" id="bigDate">
|
||||
2026-08-06 周四
|
||||
<span class="meal-tag-large meal-tag-large--lunch" id="mealTag">🥪 午餐时段</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a class="start-checkout" href="03-checkout.html">
|
||||
<span class="start-checkout__icon">🛍️</span>
|
||||
<span class="start-checkout__text">
|
||||
<span class="start-checkout__title">开始结算</span>
|
||||
<span class="start-checkout__desc">顾客取餐完成,点击进入结算流程</span>
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- 右:今日数据预览 -->
|
||||
<div class="hero__right">
|
||||
<div class="panel-title">午餐餐次数据 · 11:00 - 14:00</div>
|
||||
<div class="kpi-grid">
|
||||
<div class="kpi-cell">
|
||||
<div class="kpi-cell__label">本餐次营收</div>
|
||||
<div class="kpi-cell__value kpi-cell__value--green">¥2,614<span class="kpi-cell__unit">.50</span></div>
|
||||
<div class="kpi-cell__hint">较昨日午餐 +12.5%</div>
|
||||
</div>
|
||||
<div class="kpi-cell">
|
||||
<div class="kpi-cell__label">本餐次订单</div>
|
||||
<div class="kpi-cell__value">96<span class="kpi-cell__unit">单</span></div>
|
||||
<div class="kpi-cell__hint">较昨日午餐 -36</div>
|
||||
</div>
|
||||
<div class="kpi-cell">
|
||||
<div class="kpi-cell__label">客单价</div>
|
||||
<div class="kpi-cell__value kpi-cell__value--gold">¥27.23</div>
|
||||
<div class="kpi-cell__hint">较昨日午餐 +0.85</div>
|
||||
</div>
|
||||
<div class="kpi-cell">
|
||||
<div class="kpi-cell__label">平均菜品数</div>
|
||||
<div class="kpi-cell__value">3.2<span class="kpi-cell__unit">道/单</span></div>
|
||||
<div class="kpi-cell__hint">较昨日午餐 +0.3 道</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 底部功能入口 -->
|
||||
<div class="bottom-entry">
|
||||
<a class="entry-card" href="05-orders.html">
|
||||
<div class="entry-card__icon">📋</div>
|
||||
<div class="entry-card__text">
|
||||
<div class="entry-card__title">订单列表</div>
|
||||
<div class="entry-card__desc">今日订单查询/退款</div>
|
||||
</div>
|
||||
</a>
|
||||
<a class="entry-card" href="07-statistics.html">
|
||||
<div class="entry-card__icon entry-card__icon--purple">📊</div>
|
||||
<div class="entry-card__text">
|
||||
<div class="entry-card__title">运营统计</div>
|
||||
<div class="entry-card__desc">今日数据可视化</div>
|
||||
</div>
|
||||
</a>
|
||||
<a class="entry-card" href="09-print-receipt.html">
|
||||
<div class="entry-card__icon entry-card__icon--gold">🖨️</div>
|
||||
<div class="entry-card__text">
|
||||
<div class="entry-card__title">小票打印</div>
|
||||
<div class="entry-card__desc">补打/重打订单小票</div>
|
||||
</div>
|
||||
</a>
|
||||
<a class="entry-card" href="javascript:void(0)" onclick="alert('设置功能待开发')">
|
||||
<div class="entry-card__icon entry-card__icon--green">⚙️</div>
|
||||
<div class="entry-card__text">
|
||||
<div class="entry-card__title">设备设置</div>
|
||||
<div class="entry-card__desc">本机参数/网络/音量</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<script>
|
||||
/* 实时时钟 */
|
||||
function updateClock() {
|
||||
var now = new Date();
|
||||
var hh = String(now.getHours()).padStart(2, '0');
|
||||
var mm = String(now.getMinutes()).padStart(2, '0');
|
||||
var ss = String(now.getSeconds()).padStart(2, '0');
|
||||
var timeStr = hh + ':' + mm + ':' + ss;
|
||||
|
||||
var year = now.getFullYear();
|
||||
var month = String(now.getMonth() + 1).padStart(2, '0');
|
||||
var date = String(now.getDate()).padStart(2, '0');
|
||||
var weekDay = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'][now.getDay()];
|
||||
var dateStr = year + '-' + month + '-' + date + ' ' + weekDay;
|
||||
|
||||
document.getElementById('bigClock').textContent = timeStr;
|
||||
document.getElementById('bigDate').firstChild.textContent = ' ' + dateStr + ' ';
|
||||
document.getElementById('topMeta').textContent = dateStr;
|
||||
}
|
||||
updateClock();
|
||||
setInterval(updateClock, 1000);
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,412 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=1280, initial-scale=1.0">
|
||||
<title>结算设备 - 支付成功 | 蚁熊智能餐养平台</title>
|
||||
<style>
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
body {
|
||||
font-family: -apple-system, "Microsoft YaHei", "PingFang SC", sans-serif;
|
||||
background: #05080f;
|
||||
color: #fff;
|
||||
min-height: 100vh;
|
||||
min-width: 1280px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 20px;
|
||||
}
|
||||
.device-frame {
|
||||
width: 1280px;
|
||||
height: 720px;
|
||||
background: linear-gradient(180deg, #0e1326 0%, #0a1f2e 100%);
|
||||
border-radius: 24px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 24px 64px rgba(0, 0, 0, 0.6), 0 0 0 1px rgba(255, 255, 255, 0.04);
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
/* 顶部导航 */
|
||||
.top-bar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 44px;
|
||||
background: #1a2b4a;
|
||||
padding: 0 20px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.top-bar__title {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
color: rgba(255, 255, 255, 0.85);
|
||||
}
|
||||
.top-bar__meta {
|
||||
font-size: 12px;
|
||||
color: rgba(255, 255, 255, 0.5);
|
||||
font-family: Menlo, Consolas, monospace;
|
||||
}
|
||||
.top-bar__left { width: 100px; }
|
||||
|
||||
/* 主内容 */
|
||||
.main-area {
|
||||
flex: 1;
|
||||
display: grid;
|
||||
grid-template-columns: 1.2fr 1fr;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* ============ 左:成功动画 + 金额展示 ============ */
|
||||
.success-col {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 40px;
|
||||
gap: 28px;
|
||||
border-right: 1px solid rgba(255, 255, 255, 0.06);
|
||||
}
|
||||
.success-icon {
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
border-radius: 50%;
|
||||
background: linear-gradient(135deg, #52c41a, #0AC4A8);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 60px;
|
||||
color: #fff;
|
||||
box-shadow: 0 12px 40px rgba(82, 196, 26, 0.5), 0 0 0 8px rgba(82, 196, 26, 0.1);
|
||||
animation: bounceIn 0.6s cubic-bezier(0.68, -0.55, 0.27, 1.55);
|
||||
}
|
||||
@keyframes bounceIn {
|
||||
0% { transform: scale(0); opacity: 0; }
|
||||
60% { transform: scale(1.1); opacity: 1; }
|
||||
100% { transform: scale(1); }
|
||||
}
|
||||
|
||||
.success-title {
|
||||
font-size: 32px;
|
||||
font-weight: 700;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
}
|
||||
.success-amount {
|
||||
text-align: center;
|
||||
}
|
||||
.success-amount__label {
|
||||
font-size: 14px;
|
||||
color: rgba(255, 255, 255, 0.5);
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.success-amount__value {
|
||||
font-size: 64px;
|
||||
font-weight: 700;
|
||||
color: #0AC4A8;
|
||||
font-family: Menlo, Consolas, monospace;
|
||||
line-height: 1;
|
||||
}
|
||||
.success-pay-method {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
padding: 6px 14px;
|
||||
background: rgba(82, 196, 26, 0.15);
|
||||
border: 1px solid rgba(82, 196, 26, 0.35);
|
||||
border-radius: 18px;
|
||||
font-size: 12px;
|
||||
color: #4ade80;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
/* 订单基础信息 */
|
||||
.success-meta {
|
||||
width: 100%;
|
||||
max-width: 380px;
|
||||
background: rgba(26, 43, 74, 0.4);
|
||||
border: 1px solid rgba(255, 255, 255, 0.06);
|
||||
border-radius: 12px;
|
||||
padding: 14px 18px;
|
||||
}
|
||||
.meta-row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 6px 0;
|
||||
font-size: 12px;
|
||||
}
|
||||
.meta-row + .meta-row { border-top: 1px dashed rgba(255, 255, 255, 0.06); }
|
||||
.meta-row__label { color: rgba(255, 255, 255, 0.55); }
|
||||
.meta-row__value { color: rgba(255, 255, 255, 0.9); font-weight: 600; }
|
||||
|
||||
/* ============ 右:操作 + 营养摘要 ============ */
|
||||
.action-col {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 28px 28px 24px;
|
||||
gap: 18px;
|
||||
overflow-y: auto;
|
||||
scrollbar-width: none;
|
||||
}
|
||||
.action-col::-webkit-scrollbar { display: none; }
|
||||
|
||||
.section-label {
|
||||
font-size: 11px;
|
||||
color: rgba(255, 255, 255, 0.5);
|
||||
letter-spacing: 1px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
}
|
||||
.section-label::before {
|
||||
content: "";
|
||||
width: 3px;
|
||||
height: 11px;
|
||||
background: #4a90d9;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
/* 营养摘要卡 */
|
||||
.nutrition-card {
|
||||
background: linear-gradient(135deg, rgba(10, 196, 168, 0.12), rgba(74, 144, 217, 0.08));
|
||||
border: 1px solid rgba(10, 196, 168, 0.3);
|
||||
border-radius: 14px;
|
||||
padding: 16px;
|
||||
}
|
||||
.nutrition-head {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
.nutrition-head__title {
|
||||
font-size: 13px;
|
||||
color: rgba(255, 255, 255, 0.85);
|
||||
font-weight: 600;
|
||||
}
|
||||
.nutrition-score {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
padding: 4px 10px;
|
||||
background: rgba(251, 191, 36, 0.15);
|
||||
border: 1px solid rgba(251, 191, 36, 0.3);
|
||||
border-radius: 14px;
|
||||
font-size: 12px;
|
||||
color: #fbbf24;
|
||||
font-weight: 700;
|
||||
}
|
||||
.nutrition-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
gap: 8px;
|
||||
}
|
||||
.nutrition-item {
|
||||
text-align: center;
|
||||
padding: 10px 4px;
|
||||
background: rgba(0, 0, 0, 0.2);
|
||||
border-radius: 8px;
|
||||
}
|
||||
.nutrition-item__label {
|
||||
font-size: 10px;
|
||||
color: rgba(255, 255, 255, 0.5);
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
.nutrition-item__value {
|
||||
font-size: 18px;
|
||||
font-weight: 700;
|
||||
color: #fff;
|
||||
font-family: Menlo, Consolas, monospace;
|
||||
}
|
||||
.nutrition-item__unit {
|
||||
font-size: 10px;
|
||||
color: rgba(255, 255, 255, 0.4);
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
/* 操作按钮 */
|
||||
.actions-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 10px;
|
||||
margin-top: auto;
|
||||
}
|
||||
.btn {
|
||||
padding: 14px 12px;
|
||||
border: none;
|
||||
border-radius: 10px;
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
font-family: inherit;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 6px;
|
||||
text-decoration: none;
|
||||
}
|
||||
.btn--primary {
|
||||
background: linear-gradient(135deg, #52c41a, #0AC4A8);
|
||||
color: #fff;
|
||||
box-shadow: 0 6px 20px rgba(82, 196, 26, 0.35);
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
.btn--primary:hover { transform: translateY(-1px); }
|
||||
.btn--ghost {
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
border: 1px solid rgba(255, 255, 255, 0.12);
|
||||
}
|
||||
.btn--ghost:hover {
|
||||
background: rgba(74, 144, 217, 0.1);
|
||||
border-color: rgba(74, 144, 217, 0.35);
|
||||
color: #fff;
|
||||
}
|
||||
.btn--gold {
|
||||
background: rgba(251, 191, 36, 0.15);
|
||||
color: #fbbf24;
|
||||
border: 1px solid rgba(251, 191, 36, 0.35);
|
||||
}
|
||||
.btn--gold:hover {
|
||||
background: rgba(251, 191, 36, 0.25);
|
||||
}
|
||||
|
||||
/* 小票打印状态 */
|
||||
.print-status {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 10px 12px;
|
||||
background: rgba(74, 144, 217, 0.1);
|
||||
border: 1px solid rgba(74, 144, 217, 0.25);
|
||||
border-radius: 8px;
|
||||
font-size: 12px;
|
||||
color: #60a5fa;
|
||||
}
|
||||
.print-status__dot {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 50%;
|
||||
background: #52c41a;
|
||||
box-shadow: 0 0 8px #52c41a;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="device-frame">
|
||||
|
||||
<!-- 顶部导航 -->
|
||||
<div class="top-bar">
|
||||
<div class="top-bar__left"></div>
|
||||
<span class="top-bar__title">支付成功</span>
|
||||
<span class="top-bar__meta">2026-08-06 12:32:50</span>
|
||||
</div>
|
||||
|
||||
<!-- 主内容 -->
|
||||
<div class="main-area">
|
||||
|
||||
<!-- 左:成功动画 + 金额 -->
|
||||
<div class="success-col">
|
||||
<div class="success-icon">✔</div>
|
||||
|
||||
<div class="success-title">支付成功</div>
|
||||
|
||||
<div class="success-amount">
|
||||
<div class="success-amount__label">实付金额</div>
|
||||
<div class="success-amount__value">¥41.60</div>
|
||||
<div class="success-pay-method">📱 在线支付 · 微信支付</div>
|
||||
</div>
|
||||
|
||||
<div class="success-meta">
|
||||
<div class="meta-row">
|
||||
<span class="meta-row__label">订单号</span>
|
||||
<span class="meta-row__value">CO-20260806-031</span>
|
||||
</div>
|
||||
<div class="meta-row">
|
||||
<span class="meta-row__label">餐线</span>
|
||||
<span class="meta-row__value">一楼 A 区 2 号</span>
|
||||
</div>
|
||||
<div class="meta-row">
|
||||
<span class="meta-row__label">收银员</span>
|
||||
<span class="meta-row__value">张三 (CS001)</span>
|
||||
</div>
|
||||
<div class="meta-row">
|
||||
<span class="meta-row__label">原价/优惠</span>
|
||||
<span class="meta-row__value">¥46.60 / -¥5.00</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 右:操作 + 营养 -->
|
||||
<div class="action-col">
|
||||
|
||||
<!-- 营养摘要 -->
|
||||
<div>
|
||||
<div class="section-label" style="margin-bottom:8px;">本餐营养摄入</div>
|
||||
<div class="nutrition-card">
|
||||
<div class="nutrition-head">
|
||||
<span class="nutrition-head__title">🥗 营养摄入摘要</span>
|
||||
<span class="nutrition-score">⭐ 88 分</span>
|
||||
</div>
|
||||
<div class="nutrition-grid">
|
||||
<div class="nutrition-item">
|
||||
<div class="nutrition-item__label">热量</div>
|
||||
<div class="nutrition-item__value">720<span class="nutrition-item__unit">kcal</span></div>
|
||||
</div>
|
||||
<div class="nutrition-item">
|
||||
<div class="nutrition-item__label">蛋白质</div>
|
||||
<div class="nutrition-item__value">35<span class="nutrition-item__unit">g</span></div>
|
||||
</div>
|
||||
<div class="nutrition-item">
|
||||
<div class="nutrition-item__label">脂肪</div>
|
||||
<div class="nutrition-item__value">28<span class="nutrition-item__unit">g</span></div>
|
||||
</div>
|
||||
<div class="nutrition-item">
|
||||
<div class="nutrition-item__label">碳水</div>
|
||||
<div class="nutrition-item__value">88<span class="nutrition-item__unit">g</span></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 小票打印状态 -->
|
||||
<div class="print-status">
|
||||
<span class="print-status__dot"></span>
|
||||
<span>小票已自动打印(顾客可领取)</span>
|
||||
</div>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<div class="actions-grid">
|
||||
<a class="btn btn--primary" href="02-standby.html" style="grid-column:1 / -1;">
|
||||
🛍️ 开始下一单
|
||||
</a>
|
||||
<a class="btn btn--gold" href="09-print-receipt.html">
|
||||
🖨️ 重打小票
|
||||
</a>
|
||||
<a class="btn btn--ghost" href="06-order-detail.html">
|
||||
📄 订单详情
|
||||
</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<script>
|
||||
/* 8 秒后提示开始下一单 */
|
||||
setTimeout(function() {
|
||||
if (confirm('订单已完成,是否开始下一单?')) {
|
||||
window.location.href = '02-standby.html';
|
||||
}
|
||||
}, 8000);
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,598 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=1280, initial-scale=1.0">
|
||||
<title>结算设备 - 订单列表 | 蚁熊智能餐养平台</title>
|
||||
<style>
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
body {
|
||||
font-family: -apple-system, "Microsoft YaHei", "PingFang SC", sans-serif;
|
||||
background: #05080f;
|
||||
color: #fff;
|
||||
min-height: 100vh;
|
||||
min-width: 1280px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 20px;
|
||||
}
|
||||
.device-frame {
|
||||
width: 1280px;
|
||||
height: 720px;
|
||||
background: #0e1326;
|
||||
border-radius: 24px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 24px 64px rgba(0, 0, 0, 0.6), 0 0 0 1px rgba(255, 255, 255, 0.04);
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
/* 顶部导航 */
|
||||
.top-bar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 44px;
|
||||
background: #1a2b4a;
|
||||
padding: 0 20px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.back-btn {
|
||||
font-size: 13px;
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
transition: color 0.2s;
|
||||
}
|
||||
.back-btn:hover { color: #fff; }
|
||||
.top-bar__title {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
color: rgba(255, 255, 255, 0.85);
|
||||
}
|
||||
.top-bar__meta {
|
||||
font-size: 12px;
|
||||
color: rgba(255, 255, 255, 0.5);
|
||||
font-family: Menlo, Consolas, monospace;
|
||||
}
|
||||
|
||||
/* 主内容 */
|
||||
.main-area {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* 顶部筛选区 */
|
||||
.filter-bar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
padding: 14px 20px;
|
||||
background: rgba(26, 43, 74, 0.4);
|
||||
border-bottom: 1px solid rgba(255, 255, 255, 0.06);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.date-range {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
padding: 6px 14px;
|
||||
background: rgba(74, 144, 217, 0.15);
|
||||
border: 1px solid rgba(74, 144, 217, 0.35);
|
||||
border-radius: 6px;
|
||||
font-size: 12px;
|
||||
color: #60a5fa;
|
||||
font-weight: 600;
|
||||
}
|
||||
.filter-select {
|
||||
background: rgba(0, 0, 0, 0.25);
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
border-radius: 6px;
|
||||
padding: 6px 12px;
|
||||
font-size: 12px;
|
||||
color: rgba(255, 255, 255, 0.85);
|
||||
font-family: inherit;
|
||||
outline: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
.filter-select:focus { border-color: #4a90d9; }
|
||||
.filter-bar__search {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 6px 12px;
|
||||
background: rgba(0, 0, 0, 0.25);
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
border-radius: 6px;
|
||||
}
|
||||
.filter-bar__search input {
|
||||
flex: 1;
|
||||
background: none;
|
||||
border: none;
|
||||
color: rgba(255, 255, 255, 0.85);
|
||||
font-size: 12px;
|
||||
outline: none;
|
||||
font-family: inherit;
|
||||
}
|
||||
.filter-bar__search input::placeholder {
|
||||
color: rgba(255, 255, 255, 0.35);
|
||||
}
|
||||
.filter-bar__stat {
|
||||
display: flex;
|
||||
gap: 14px;
|
||||
padding: 6px 14px;
|
||||
background: rgba(0, 0, 0, 0.2);
|
||||
border-radius: 6px;
|
||||
font-size: 11px;
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
}
|
||||
.filter-bar__stat strong {
|
||||
color: #4ade80;
|
||||
font-family: Menlo, Consolas, monospace;
|
||||
}
|
||||
|
||||
/* 订单列表 */
|
||||
.order-list {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
padding: 14px 20px;
|
||||
scrollbar-width: none;
|
||||
}
|
||||
.order-list::-webkit-scrollbar { display: none; }
|
||||
|
||||
.order-row {
|
||||
display: grid;
|
||||
grid-template-columns: 40px 1.3fr 70px 0.9fr 1.1fr 110px 95px 95px 130px;
|
||||
gap: 10px;
|
||||
align-items: center;
|
||||
padding: 12px 14px;
|
||||
background: rgba(26, 43, 74, 0.4);
|
||||
border: 1px solid rgba(255, 255, 255, 0.04);
|
||||
border-radius: 8px;
|
||||
margin-bottom: 6px;
|
||||
transition: all 0.15s;
|
||||
cursor: pointer;
|
||||
}
|
||||
/* 表头 */
|
||||
.order-head {
|
||||
display: grid;
|
||||
grid-template-columns: 40px 1.3fr 70px 0.9fr 1.1fr 110px 95px 95px 130px;
|
||||
gap: 10px;
|
||||
padding: 8px 14px;
|
||||
font-size: 11px;
|
||||
color: rgba(255, 255, 255, 0.45);
|
||||
letter-spacing: 0.5px;
|
||||
background: rgba(0, 0, 0, 0.2);
|
||||
border-radius: 6px;
|
||||
margin-bottom: 6px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.order-head > div { font-weight: 600; }
|
||||
.order-head__amount { text-align: right; }
|
||||
.order-head__actions { text-align: right; }
|
||||
.order-row__amount { text-align: right; }
|
||||
.order-row:hover {
|
||||
background: rgba(74, 144, 217, 0.08);
|
||||
border-color: rgba(74, 144, 217, 0.25);
|
||||
}
|
||||
.order-row.refunded { opacity: 0.55; }
|
||||
.order-row__index {
|
||||
font-size: 12px;
|
||||
color: rgba(255, 255, 255, 0.4);
|
||||
font-family: Menlo, Consolas, monospace;
|
||||
text-align: center;
|
||||
}
|
||||
.order-row__id {
|
||||
font-size: 13px;
|
||||
color: #fff;
|
||||
font-weight: 600;
|
||||
font-family: Menlo, Consolas, monospace;
|
||||
}
|
||||
.order-row__sub {
|
||||
font-size: 10px;
|
||||
color: rgba(255, 255, 255, 0.4);
|
||||
margin-top: 2px;
|
||||
}
|
||||
.meal-tag {
|
||||
font-size: 10px;
|
||||
line-height: 1;
|
||||
padding: 4px 7px;
|
||||
border-radius: 9px;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.3px;
|
||||
text-align: center;
|
||||
}
|
||||
.meal-tag--breakfast {
|
||||
background: rgba(250, 140, 22, 0.18);
|
||||
color: #fb923c;
|
||||
border: 1px solid rgba(250, 140, 22, 0.35);
|
||||
}
|
||||
.meal-tag--lunch {
|
||||
background: rgba(37, 99, 235, 0.18);
|
||||
color: #60a5fa;
|
||||
border: 1px solid rgba(37, 99, 235, 0.35);
|
||||
}
|
||||
.meal-tag--dinner {
|
||||
background: rgba(34, 197, 94, 0.18);
|
||||
color: #4ade80;
|
||||
border: 1px solid rgba(34, 197, 94, 0.35);
|
||||
}
|
||||
.order-row__items {
|
||||
font-size: 12px;
|
||||
color: rgba(255, 255, 255, 0.85);
|
||||
font-weight: 600;
|
||||
line-height: 1.4;
|
||||
}
|
||||
.order-row__items-hint {
|
||||
font-size: 10px;
|
||||
color: rgba(255, 255, 255, 0.4);
|
||||
font-weight: 400;
|
||||
margin-top: 2px;
|
||||
}
|
||||
.order-row__txn {
|
||||
font-size: 11px;
|
||||
color: rgba(255, 255, 255, 0.75);
|
||||
font-family: Menlo, Consolas, monospace;
|
||||
line-height: 1.4;
|
||||
}
|
||||
.order-row__pay-time {
|
||||
font-size: 10px;
|
||||
color: rgba(255, 255, 255, 0.4);
|
||||
margin-top: 2px;
|
||||
}
|
||||
.order-row__amount {
|
||||
font-size: 15px;
|
||||
color: #0AC4A8;
|
||||
font-weight: 700;
|
||||
font-family: Menlo, Consolas, monospace;
|
||||
}
|
||||
.order-row__pay-method {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
font-size: 11px;
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
}
|
||||
.order-row__actions {
|
||||
display: flex;
|
||||
gap: 4px;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
.action-btn {
|
||||
padding: 5px 8px;
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
border-radius: 4px;
|
||||
color: rgba(255, 255, 255, 0.75);
|
||||
font-size: 11px;
|
||||
cursor: pointer;
|
||||
transition: all 0.15s;
|
||||
text-decoration: none;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.action-btn:hover {
|
||||
background: rgba(74, 144, 217, 0.15);
|
||||
border-color: rgba(74, 144, 217, 0.35);
|
||||
color: #fff;
|
||||
}
|
||||
.action-btn--danger {
|
||||
color: #ff6b6b;
|
||||
border-color: rgba(245, 34, 45, 0.2);
|
||||
}
|
||||
.action-btn--danger:hover {
|
||||
background: rgba(245, 34, 45, 0.15);
|
||||
border-color: rgba(245, 34, 45, 0.45);
|
||||
color: #ff6b6b;
|
||||
}
|
||||
.action-btn--gold {
|
||||
color: #fbbf24;
|
||||
border-color: rgba(251, 191, 36, 0.2);
|
||||
}
|
||||
.action-btn--gold:hover {
|
||||
background: rgba(251, 191, 36, 0.15);
|
||||
border-color: rgba(251, 191, 36, 0.45);
|
||||
}
|
||||
|
||||
/* 状态标签 */
|
||||
.status-pill {
|
||||
display: inline-block;
|
||||
padding: 2px 6px;
|
||||
border-radius: 8px;
|
||||
font-size: 9px;
|
||||
font-weight: 600;
|
||||
margin-left: 4px;
|
||||
}
|
||||
.status-pill--normal {
|
||||
background: rgba(82, 196, 26, 0.15);
|
||||
color: #4ade80;
|
||||
border: 1px solid rgba(82, 196, 26, 0.3);
|
||||
}
|
||||
.status-pill--refunded {
|
||||
background: rgba(245, 34, 45, 0.15);
|
||||
color: #ff6b6b;
|
||||
border: 1px solid rgba(245, 34, 45, 0.3);
|
||||
}
|
||||
|
||||
/* 空状态 */
|
||||
.empty {
|
||||
text-align: center;
|
||||
padding: 60px 20px;
|
||||
color: rgba(255, 255, 255, 0.3);
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
/* 底部分页 */
|
||||
.pagination {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 10px 20px;
|
||||
background: rgba(26, 43, 74, 0.4);
|
||||
border-top: 1px solid rgba(255, 255, 255, 0.06);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.pagination__info {
|
||||
font-size: 12px;
|
||||
color: rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
.pagination__info strong { color: #fff; }
|
||||
.pagination__pages { display: flex; gap: 4px; }
|
||||
.page-btn {
|
||||
min-width: 28px;
|
||||
padding: 4px 8px;
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
border-radius: 4px;
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
font-size: 11px;
|
||||
cursor: pointer;
|
||||
transition: all 0.15s;
|
||||
font-family: Menlo, Consolas, monospace;
|
||||
}
|
||||
.page-btn:hover { background: rgba(74, 144, 217, 0.15); color: #fff; }
|
||||
.page-btn.active {
|
||||
background: #4a90d9;
|
||||
border-color: #4a90d9;
|
||||
color: #fff;
|
||||
}
|
||||
.page-btn--disabled {
|
||||
opacity: 0.4;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
/* Toast */
|
||||
.toast {
|
||||
position: fixed;
|
||||
top: 60px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%) translateY(-20px);
|
||||
background: rgba(0, 0, 0, 0.85);
|
||||
color: #fff;
|
||||
padding: 12px 28px;
|
||||
border-radius: 8px;
|
||||
font-size: 13px;
|
||||
z-index: 1000;
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
transition: opacity 0.3s, transform 0.3s, visibility 0.3s;
|
||||
white-space: nowrap;
|
||||
pointer-events: none;
|
||||
}
|
||||
.toast.show {
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
transform: translateX(-50%) translateY(0);
|
||||
}
|
||||
.toast--warn { background: rgba(250, 173, 22, 0.92); }
|
||||
.toast--success { background: rgba(82, 196, 26, 0.92); }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="device-frame">
|
||||
|
||||
<!-- 顶部导航 -->
|
||||
<div class="top-bar">
|
||||
<a class="back-btn" href="index.html">◀ 返回主页</a>
|
||||
<span class="top-bar__title">订单列表</span>
|
||||
<span class="top-bar__meta">今日 2026-08-06</span>
|
||||
</div>
|
||||
|
||||
<!-- 主内容 -->
|
||||
<div class="main-area">
|
||||
|
||||
<!-- 筛选栏 -->
|
||||
<div class="filter-bar">
|
||||
<div class="date-range">📅 2026-08-06(今日)</div>
|
||||
<select class="filter-select">
|
||||
<option>全部餐次</option>
|
||||
<option selected>午餐(当前)</option>
|
||||
<option>早餐</option>
|
||||
<option>晚餐</option>
|
||||
</select>
|
||||
<select class="filter-select">
|
||||
<option>全部状态</option>
|
||||
<option>正常</option>
|
||||
<option>已退款</option>
|
||||
</select>
|
||||
<select class="filter-select">
|
||||
<option>全部支付</option>
|
||||
<option>在线支付</option>
|
||||
<option>现金</option>
|
||||
<option>餐券/补贴码</option>
|
||||
<option>刷脸</option>
|
||||
</select>
|
||||
<div class="filter-bar__search">
|
||||
<span>🔍</span>
|
||||
<input type="text" placeholder="搜索订单号 / 顾客姓名">
|
||||
</div>
|
||||
<div class="filter-bar__stat">
|
||||
午餐单数:<strong>5</strong>
|
||||
午餐营收:<strong>¥151.30</strong>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 订单列表 -->
|
||||
<div class="order-list" id="orderList">
|
||||
<!-- 表头(静态保留,不被 JS 覆盖) -->
|
||||
<div class="order-head" id="orderHead">
|
||||
<div>#</div>
|
||||
<div>订单号 / 状态</div>
|
||||
<div>餐次</div>
|
||||
<div>商品</div>
|
||||
<div>支付流水号</div>
|
||||
<div class="order-head__amount">金额</div>
|
||||
<div>支付方式</div>
|
||||
<div>支付时间</div>
|
||||
<div class="order-head__actions">操作</div>
|
||||
</div>
|
||||
<!-- 订单行容器(JS 渲染到这里) -->
|
||||
<div id="orderRows"></div>
|
||||
</div>
|
||||
|
||||
<!-- 分页 -->
|
||||
<div class="pagination">
|
||||
<div class="pagination__info">共 <strong>5</strong> 条 · 当前第 <strong>1/1</strong> 页</div>
|
||||
<div class="pagination__pages">
|
||||
<button class="page-btn page-btn--disabled">◀</button>
|
||||
<button class="page-btn active">1</button>
|
||||
<button class="page-btn page-btn--disabled">▶</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- Toast -->
|
||||
<div class="toast" id="toast"></div>
|
||||
|
||||
<script>
|
||||
/* ==================== Mock 订单数据(当前餐次:午餐) ==================== */
|
||||
var mockOrders = [
|
||||
{
|
||||
id: 'CO-20260806-031', mealType: 'lunch', mealLabel: '午餐',
|
||||
cashier: '张三',
|
||||
itemCount: 5, itemsSummary: '红烧肉/清炒时蔬/鱼香肉丝/米饭/...',
|
||||
payable: 41.60,
|
||||
txnNo: 'WX2608061232509987',
|
||||
payMethod: '在线支付', payIcon: '📱',
|
||||
payTime: '12:32:50',
|
||||
printed: true, status: 'normal'
|
||||
},
|
||||
{
|
||||
id: 'CO-20260806-030', mealType: 'lunch', mealLabel: '午餐',
|
||||
cashier: '张三',
|
||||
itemCount: 4, itemsSummary: '宫保鸡丁/番茄炒蛋/米饭/...',
|
||||
payable: 32.50,
|
||||
txnNo: 'FACE260806122801234',
|
||||
payMethod: '刷脸支付', payIcon: '👤',
|
||||
payTime: '12:28:15',
|
||||
printed: true, status: 'normal'
|
||||
},
|
||||
{
|
||||
id: 'CO-20260806-029', mealType: 'lunch', mealLabel: '午餐',
|
||||
cashier: '张三',
|
||||
itemCount: 3, itemsSummary: '麻婆豆腐/番茄炒蛋/米饭',
|
||||
payable: 18.50,
|
||||
txnNo: 'MQ26080612180056',
|
||||
payMethod: '餐券/补贴码', payIcon: '🎫',
|
||||
payTime: '12:18:42',
|
||||
printed: true, status: 'normal'
|
||||
},
|
||||
{
|
||||
id: 'CO-20260806-028', mealType: 'lunch', mealLabel: '午餐',
|
||||
cashier: '张三',
|
||||
itemCount: 3, itemsSummary: '清蒸鲈鱼/蒜蓉西兰花/紫米饭',
|
||||
payable: 34.00,
|
||||
txnNo: 'WX2608061210304452',
|
||||
payMethod: '在线支付', payIcon: '📱',
|
||||
payTime: '12:10:30',
|
||||
printed: true, status: 'refunded'
|
||||
},
|
||||
{
|
||||
id: 'CO-20260806-027', mealType: 'lunch', mealLabel: '午餐',
|
||||
cashier: '张三',
|
||||
itemCount: 4, itemsSummary: '鱼香肉丝/麻婆豆腐/米饭/...',
|
||||
payable: 24.70,
|
||||
txnNo: 'CASH26080612021899',
|
||||
payMethod: '现金', payIcon: '💶',
|
||||
payTime: '12:02:18',
|
||||
printed: false, status: 'normal'
|
||||
}
|
||||
];
|
||||
|
||||
function renderOrders() {
|
||||
var listEl = document.getElementById('orderRows');
|
||||
if (mockOrders.length === 0) {
|
||||
listEl.innerHTML = '<div class="empty">📋 今日暂无订单</div>';
|
||||
return;
|
||||
}
|
||||
|
||||
var html = mockOrders.map(function(o, idx) {
|
||||
var mealTagClass = 'meal-tag--' + o.mealType;
|
||||
var refundedClass = o.status === 'refunded' ? ' refunded' : '';
|
||||
var statusPill = o.status === 'refunded'
|
||||
? '<span class="status-pill status-pill--refunded">已退款</span>'
|
||||
: '<span class="status-pill status-pill--normal">正常</span>';
|
||||
|
||||
/* 商品汇总显示:餐品 x N */
|
||||
var itemsHtml = '<div class="order-row__items">🍽️ 餐品 x' + o.itemCount + '</div>'
|
||||
+ '<div class="order-row__items-hint">' + o.itemsSummary + '</div>';
|
||||
|
||||
/* 支付流水号 */
|
||||
var txnHtml = '<div class="order-row__txn" title="' + o.txnNo + '">' + o.txnNo + '</div>';
|
||||
/* 支付方式(独立一列) */
|
||||
var payMethodHtml = '<div class="order-row__pay-method">' + o.payIcon + ' ' + o.payMethod + '</div>';
|
||||
/* 支付时间(独立一列) */
|
||||
var payTimeHtml = '<div class="order-row__txn">' + o.payTime + '</div>';
|
||||
|
||||
/* 操作按钮 - 退款按钮携带 action=refund 参数跳转详情页 */
|
||||
var detailHref = '06-order-detail.html?id=' + o.id;
|
||||
var refundHref = '06-order-detail.html?id=' + o.id + '&action=refund';
|
||||
var actions = o.status === 'refunded'
|
||||
? '<a class="action-btn" href="' + detailHref + '">详情</a>'
|
||||
: '<a class="action-btn" href="' + detailHref + '">详情</a>'
|
||||
+ '<a class="action-btn action-btn--gold" href="09-print-receipt.html?id=' + o.id + '">打印</a>'
|
||||
+ '<a class="action-btn action-btn--danger" href="' + refundHref + '">去退款</a>';
|
||||
|
||||
return '<div class="order-row' + refundedClass + '" onclick="window.location.href=\'' + detailHref + '\'">'
|
||||
+ '<div class="order-row__index">#' + (idx + 1) + '</div>'
|
||||
+ '<div>'
|
||||
+ '<div class="order-row__id">' + o.id + statusPill + '</div>'
|
||||
+ '</div>'
|
||||
+ '<div><span class="meal-tag ' + mealTagClass + '">' + o.mealLabel + '</span></div>'
|
||||
+ '<div>' + itemsHtml + '</div>'
|
||||
+ '<div>' + txnHtml + '</div>'
|
||||
+ '<div class="order-row__amount">¥' + o.payable.toFixed(2) + '</div>'
|
||||
+ '<div>' + payMethodHtml + '</div>'
|
||||
+ '<div>' + payTimeHtml + '</div>'
|
||||
+ '<div class="order-row__actions" onclick="event.stopPropagation();">' + actions + '</div>'
|
||||
+ '</div>';
|
||||
}).join('');
|
||||
|
||||
listEl.innerHTML = html;
|
||||
}
|
||||
|
||||
function showToast(msg, type) {
|
||||
var el = document.getElementById('toast');
|
||||
el.textContent = msg;
|
||||
el.className = 'toast';
|
||||
if (type === 'success') el.classList.add('toast--success');
|
||||
if (type === 'warn') el.classList.add('toast--warn');
|
||||
el.classList.add('show');
|
||||
clearTimeout(el._timer);
|
||||
el._timer = setTimeout(function() { el.classList.remove('show'); }, 2200);
|
||||
}
|
||||
|
||||
renderOrders();
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,999 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=1280, initial-scale=1.0">
|
||||
<title>结算设备 - 订单详情 | 蚁熊智能餐养平台</title>
|
||||
<style>
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
body {
|
||||
font-family: -apple-system, "Microsoft YaHei", "PingFang SC", sans-serif;
|
||||
background: #05080f;
|
||||
color: #fff;
|
||||
min-height: 100vh;
|
||||
min-width: 1280px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 20px;
|
||||
}
|
||||
.device-frame {
|
||||
width: 1280px;
|
||||
height: 720px;
|
||||
background: #0e1326;
|
||||
border-radius: 24px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 24px 64px rgba(0, 0, 0, 0.6), 0 0 0 1px rgba(255, 255, 255, 0.04);
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
/* 顶部导航 */
|
||||
.top-bar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 44px;
|
||||
background: #1a2b4a;
|
||||
padding: 0 20px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.back-btn {
|
||||
font-size: 13px;
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
transition: color 0.2s;
|
||||
}
|
||||
.back-btn:hover { color: #fff; }
|
||||
.top-bar__title {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
color: rgba(255, 255, 255, 0.85);
|
||||
}
|
||||
.top-bar__meta {
|
||||
font-size: 12px;
|
||||
color: rgba(255, 255, 255, 0.5);
|
||||
font-family: Menlo, Consolas, monospace;
|
||||
}
|
||||
|
||||
/* 主内容:左右两列 */
|
||||
.main-area {
|
||||
flex: 1;
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 360px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* ============ 左列:订单信息 + 商品明细 ============ */
|
||||
.left-col {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow-y: auto;
|
||||
padding: 18px 20px;
|
||||
gap: 14px;
|
||||
scrollbar-width: none;
|
||||
}
|
||||
.left-col::-webkit-scrollbar { display: none; }
|
||||
|
||||
.card {
|
||||
background: rgba(26, 43, 74, 0.4);
|
||||
border: 1px solid rgba(255, 255, 255, 0.06);
|
||||
border-radius: 10px;
|
||||
padding: 14px 16px;
|
||||
}
|
||||
.card__title {
|
||||
font-size: 12px;
|
||||
color: rgba(255, 255, 255, 0.55);
|
||||
letter-spacing: 1px;
|
||||
margin-bottom: 10px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
}
|
||||
.card__title::before {
|
||||
content: "";
|
||||
width: 3px;
|
||||
height: 12px;
|
||||
background: #4a90d9;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
/* 订单头 */
|
||||
.order-head {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding-bottom: 12px;
|
||||
border-bottom: 1px dashed rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
.order-head__id {
|
||||
font-size: 18px;
|
||||
color: #fff;
|
||||
font-weight: 700;
|
||||
font-family: Menlo, Consolas, monospace;
|
||||
}
|
||||
.order-head__status {
|
||||
display: flex;
|
||||
gap: 6px;
|
||||
}
|
||||
.status-pill {
|
||||
display: inline-block;
|
||||
padding: 4px 10px;
|
||||
border-radius: 12px;
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
}
|
||||
.status-pill--normal {
|
||||
background: rgba(82, 196, 26, 0.15);
|
||||
color: #4ade80;
|
||||
border: 1px solid rgba(82, 196, 26, 0.3);
|
||||
}
|
||||
.status-pill--printed {
|
||||
background: rgba(74, 144, 217, 0.15);
|
||||
color: #60a5fa;
|
||||
border: 1px solid rgba(74, 144, 217, 0.3);
|
||||
}
|
||||
.status-pill--refunded {
|
||||
background: rgba(245, 34, 45, 0.15);
|
||||
color: #ff6b6b;
|
||||
border: 1px solid rgba(245, 34, 45, 0.3);
|
||||
}
|
||||
|
||||
/* 信息网格 */
|
||||
.info-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr 1fr;
|
||||
gap: 12px;
|
||||
}
|
||||
.info-item__label {
|
||||
font-size: 11px;
|
||||
color: rgba(255, 255, 255, 0.5);
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
.info-item__value {
|
||||
font-size: 13px;
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
font-weight: 600;
|
||||
}
|
||||
.meal-tag {
|
||||
display: inline-block;
|
||||
font-size: 10px;
|
||||
line-height: 1;
|
||||
padding: 4px 8px;
|
||||
border-radius: 9px;
|
||||
font-weight: 600;
|
||||
}
|
||||
.meal-tag--lunch {
|
||||
background: rgba(37, 99, 235, 0.18);
|
||||
color: #60a5fa;
|
||||
border: 1px solid rgba(37, 99, 235, 0.35);
|
||||
}
|
||||
|
||||
/* 商品明细表 */
|
||||
.item-table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
font-size: 13px;
|
||||
}
|
||||
.item-table th {
|
||||
text-align: left;
|
||||
padding: 8px 6px;
|
||||
color: rgba(255, 255, 255, 0.5);
|
||||
font-weight: 600;
|
||||
font-size: 11px;
|
||||
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
.item-table th.num { text-align: right; }
|
||||
.item-table td {
|
||||
padding: 8px 6px;
|
||||
color: rgba(255, 255, 255, 0.85);
|
||||
border-bottom: 1px dashed rgba(255, 255, 255, 0.05);
|
||||
}
|
||||
.item-table td.num { text-align: right; font-family: Menlo, Consolas, monospace; }
|
||||
.item-table tr.zone-header td {
|
||||
font-size: 11px;
|
||||
color: rgba(255, 255, 255, 0.55);
|
||||
padding-top: 10px;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.5px;
|
||||
border-bottom: none;
|
||||
}
|
||||
.item-table .item-name {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
.item-name__thumb {
|
||||
width: 26px;
|
||||
height: 26px;
|
||||
border-radius: 6px;
|
||||
background: linear-gradient(135deg, rgba(74, 144, 217, 0.2), rgba(10, 196, 168, 0.2));
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 14px;
|
||||
}
|
||||
.item-table .subtotal {
|
||||
color: #0AC4A8;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
/* 金额汇总 */
|
||||
.amount-list { display: flex; flex-direction: column; gap: 6px; }
|
||||
.amount-line {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
font-size: 13px;
|
||||
}
|
||||
.amount-line__label { color: rgba(255, 255, 255, 0.6); }
|
||||
.amount-line__value { color: rgba(255, 255, 255, 0.9); font-weight: 600; }
|
||||
.amount-line--total {
|
||||
padding-top: 10px;
|
||||
margin-top: 4px;
|
||||
border-top: 1px dashed rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
.amount-line--total .amount-line__label { font-size: 14px; color: #fff; }
|
||||
.amount-line--total .amount-line__value {
|
||||
font-size: 22px;
|
||||
color: #0AC4A8;
|
||||
font-family: Menlo, Consolas, monospace;
|
||||
}
|
||||
|
||||
/* 退款金额显示 */
|
||||
.refund-summary {
|
||||
display: none;
|
||||
padding: 10px 12px;
|
||||
background: rgba(245, 34, 45, 0.1);
|
||||
border: 1px solid rgba(245, 34, 45, 0.3);
|
||||
border-radius: 8px;
|
||||
font-size: 13px;
|
||||
color: #ff6b6b;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.refund-summary.show { display: flex; }
|
||||
.refund-summary__amount {
|
||||
font-weight: 700;
|
||||
font-family: Menlo, Consolas, monospace;
|
||||
}
|
||||
|
||||
/* ============ 右列:操作面板 ============ */
|
||||
.right-col {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 18px 20px;
|
||||
background: rgba(26, 43, 74, 0.2);
|
||||
border-left: 1px solid rgba(255, 255, 255, 0.06);
|
||||
gap: 12px;
|
||||
overflow-y: auto;
|
||||
scrollbar-width: none;
|
||||
}
|
||||
.right-col::-webkit-scrollbar { display: none; }
|
||||
|
||||
/* 操作按钮组 */
|
||||
.btn-group { display: flex; flex-direction: column; gap: 8px; }
|
||||
.btn {
|
||||
padding: 12px;
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
font-family: inherit;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 6px;
|
||||
text-decoration: none;
|
||||
}
|
||||
.btn--ghost {
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
color: rgba(255, 255, 255, 0.85);
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
.btn--ghost:hover {
|
||||
background: rgba(74, 144, 217, 0.1);
|
||||
border-color: rgba(74, 144, 217, 0.35);
|
||||
}
|
||||
.btn--gold {
|
||||
background: rgba(251, 191, 36, 0.15);
|
||||
color: #fbbf24;
|
||||
border: 1px solid rgba(251, 191, 36, 0.35);
|
||||
}
|
||||
.btn--gold:hover {
|
||||
background: rgba(251, 191, 36, 0.25);
|
||||
}
|
||||
.btn--danger {
|
||||
background: rgba(245, 34, 45, 0.12);
|
||||
color: #ff6b6b;
|
||||
border: 1px solid rgba(245, 34, 45, 0.35);
|
||||
}
|
||||
.btn--danger:hover {
|
||||
background: rgba(245, 34, 45, 0.22);
|
||||
}
|
||||
|
||||
/* 退款流程弹层 */
|
||||
.refund-panel {
|
||||
display: none;
|
||||
background: rgba(0, 0, 0, 0.25);
|
||||
border: 1px solid rgba(245, 34, 45, 0.3);
|
||||
border-radius: 10px;
|
||||
padding: 14px;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
}
|
||||
.refund-panel.show { display: flex; }
|
||||
.refund-panel__title {
|
||||
font-size: 13px;
|
||||
color: #ff6b6b;
|
||||
font-weight: 600;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
}
|
||||
.refund-panel__label {
|
||||
font-size: 11px;
|
||||
color: rgba(255, 255, 255, 0.55);
|
||||
}
|
||||
.refund-reason {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 6px;
|
||||
}
|
||||
.refund-reason__item {
|
||||
padding: 8px 6px;
|
||||
background: rgba(255, 255, 255, 0.04);
|
||||
border: 1px solid rgba(255, 255, 255, 0.08);
|
||||
border-radius: 6px;
|
||||
font-size: 11px;
|
||||
color: rgba(255, 255, 255, 0.75);
|
||||
cursor: pointer;
|
||||
transition: all 0.15s;
|
||||
text-align: center;
|
||||
}
|
||||
.refund-reason__item:hover {
|
||||
background: rgba(245, 34, 45, 0.1);
|
||||
border-color: rgba(245, 34, 45, 0.35);
|
||||
color: #fff;
|
||||
}
|
||||
.refund-reason__item.active {
|
||||
background: rgba(245, 34, 45, 0.15);
|
||||
border-color: #f5222d;
|
||||
color: #fff;
|
||||
}
|
||||
.refund-actions {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 6px;
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
/* 退款方式切换(全额/部分) */
|
||||
.refund-type {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 6px;
|
||||
}
|
||||
.refund-type__item {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 10px;
|
||||
padding: 10px 12px;
|
||||
background: rgba(255, 255, 255, 0.04);
|
||||
border: 1px solid rgba(255, 255, 255, 0.08);
|
||||
border-radius: 8px;
|
||||
cursor: pointer;
|
||||
transition: all 0.15s;
|
||||
}
|
||||
.refund-type__item:hover {
|
||||
background: rgba(245, 34, 45, 0.06);
|
||||
border-color: rgba(245, 34, 45, 0.25);
|
||||
}
|
||||
.refund-type__item.active {
|
||||
background: rgba(245, 34, 45, 0.1);
|
||||
border-color: #f5222d;
|
||||
}
|
||||
.refund-type__radio {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
border-radius: 50%;
|
||||
border: 2px solid rgba(255, 255, 255, 0.3);
|
||||
flex-shrink: 0;
|
||||
margin-top: 2px;
|
||||
position: relative;
|
||||
transition: all 0.15s;
|
||||
}
|
||||
.refund-type__item.active .refund-type__radio {
|
||||
border-color: #f5222d;
|
||||
}
|
||||
.refund-type__item.active .refund-type__radio::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 3px;
|
||||
left: 3px;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 50%;
|
||||
background: #f5222d;
|
||||
}
|
||||
.refund-type__body { flex: 1; }
|
||||
.refund-type__name {
|
||||
font-size: 13px;
|
||||
color: #fff;
|
||||
font-weight: 600;
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
.refund-type__hint {
|
||||
font-size: 11px;
|
||||
color: rgba(255, 255, 255, 0.55);
|
||||
}
|
||||
|
||||
/* 部分退款金额输入 */
|
||||
.refund-amount-wrap {
|
||||
display: none;
|
||||
}
|
||||
.refund-amount-wrap.show { display: block; }
|
||||
.refund-amount-input {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
padding: 8px 12px;
|
||||
background: rgba(0, 0, 0, 0.3);
|
||||
border: 1px solid rgba(245, 34, 45, 0.3);
|
||||
border-radius: 8px;
|
||||
}
|
||||
.refund-amount-input__symbol {
|
||||
font-size: 18px;
|
||||
color: #ff6b6b;
|
||||
font-weight: 700;
|
||||
}
|
||||
.refund-amount-input input {
|
||||
flex: 1;
|
||||
background: none;
|
||||
border: none;
|
||||
color: #fff;
|
||||
font-size: 18px;
|
||||
font-family: Menlo, Consolas, monospace;
|
||||
outline: none;
|
||||
text-align: right;
|
||||
}
|
||||
.refund-amount-quick {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
gap: 4px;
|
||||
margin-top: 6px;
|
||||
}
|
||||
.refund-amount-quick button {
|
||||
padding: 6px 0;
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
border-radius: 4px;
|
||||
color: rgba(255, 255, 255, 0.85);
|
||||
font-size: 11px;
|
||||
cursor: pointer;
|
||||
transition: all 0.15s;
|
||||
font-family: Menlo, Consolas, monospace;
|
||||
}
|
||||
.refund-amount-quick button:hover {
|
||||
background: rgba(245, 34, 45, 0.15);
|
||||
border-color: rgba(245, 34, 45, 0.35);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
/* 退款备注 */
|
||||
.refund-note {
|
||||
width: 100%;
|
||||
padding: 8px 10px;
|
||||
background: rgba(0, 0, 0, 0.25);
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
border-radius: 6px;
|
||||
color: #fff;
|
||||
font-size: 12px;
|
||||
font-family: inherit;
|
||||
resize: vertical;
|
||||
outline: none;
|
||||
line-height: 1.6;
|
||||
}
|
||||
.refund-note:focus { border-color: #f5222d; }
|
||||
.refund-note::placeholder { color: rgba(255, 255, 255, 0.35); }
|
||||
.refund-note__counter {
|
||||
text-align: right;
|
||||
font-size: 10px;
|
||||
color: rgba(255, 255, 255, 0.4);
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
/* 让 summary 始终展示 */
|
||||
.refund-panel .refund-summary { display: flex !important; }
|
||||
|
||||
/* 退款记录(已退款订单显示) */
|
||||
.refund-record {
|
||||
display: none;
|
||||
padding: 12px;
|
||||
background: rgba(245, 34, 45, 0.08);
|
||||
border: 1px solid rgba(245, 34, 45, 0.25);
|
||||
border-radius: 8px;
|
||||
font-size: 12px;
|
||||
color: rgba(255, 255, 255, 0.75);
|
||||
line-height: 1.7;
|
||||
}
|
||||
.refund-record.show { display: block; }
|
||||
.refund-record strong { color: #ff6b6b; }
|
||||
|
||||
/* 关联信息 */
|
||||
.related-info {
|
||||
padding: 10px 12px;
|
||||
background: rgba(26, 43, 74, 0.5);
|
||||
border: 1px solid rgba(255, 255, 255, 0.06);
|
||||
border-radius: 8px;
|
||||
font-size: 11px;
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
line-height: 1.7;
|
||||
}
|
||||
.related-info__row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.related-info__row strong { color: rgba(255, 255, 255, 0.85); }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="device-frame">
|
||||
|
||||
<!-- 顶部导航 -->
|
||||
<div class="top-bar">
|
||||
<a class="back-btn" href="05-orders.html">◀ 返回订单列表</a>
|
||||
<span class="top-bar__title">订单详情</span>
|
||||
<span class="top-bar__meta">2026-08-06</span>
|
||||
</div>
|
||||
|
||||
<!-- 主内容 -->
|
||||
<div class="main-area">
|
||||
|
||||
<!-- 左列:订单信息 -->
|
||||
<div class="left-col">
|
||||
|
||||
<!-- 订单头 -->
|
||||
<div class="card">
|
||||
<div class="order-head">
|
||||
<div>
|
||||
<div class="order-head__id">CO-20260806-031</div>
|
||||
<div style="font-size:11px;color:rgba(255,255,255,0.4);margin-top:4px;">
|
||||
下单:2026-08-06 12:15:30 · 支付:12:32:50
|
||||
</div>
|
||||
</div>
|
||||
<div class="order-head__status">
|
||||
<span class="status-pill status-pill--normal">正常</span>
|
||||
<span class="status-pill status-pill--printed">已打印</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="info-grid" style="margin-top:14px;">
|
||||
<div class="info-item">
|
||||
<div class="info-item__label">餐次</div>
|
||||
<div class="info-item__value"><span class="meal-tag meal-tag--lunch">午餐</span></div>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<div class="info-item__label">餐线</div>
|
||||
<div class="info-item__value">一楼 A 区 2 号</div>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<div class="info-item__label">收银员</div>
|
||||
<div class="info-item__value">张三 (CS001)</div>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<div class="info-item__label">顾客类型</div>
|
||||
<div class="info-item__value">企业员工</div>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<div class="info-item__label">订单件数</div>
|
||||
<div class="info-item__value">5 件</div>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<div class="info-item__label">订单总重</div>
|
||||
<div class="info-item__value">1040g</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 商品明细 -->
|
||||
<div class="card">
|
||||
<div class="card__title">商品明细</div>
|
||||
<table class="item-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>餐品</th>
|
||||
<th class="num">单价/100g</th>
|
||||
<th class="num">取用量</th>
|
||||
<th class="num">小计</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="zone-header"><td colspan="4">【档口】 ×3</td></tr>
|
||||
<tr>
|
||||
<td><div class="item-name"><span class="item-name__thumb">🍖</span>红烧肉</div></td>
|
||||
<td class="num">¥12.00</td>
|
||||
<td class="num">180g</td>
|
||||
<td class="num subtotal">21.60</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><div class="item-name"><span class="item-name__thumb">🍟</span>鱼香肉丝</div></td>
|
||||
<td class="num">¥7.50</td>
|
||||
<td class="num">160g</td>
|
||||
<td class="num subtotal">12.00</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><div class="item-name"><span class="item-name__thumb">🍲</span>冬瓜排骨汤</div></td>
|
||||
<td class="num">¥1.00</td>
|
||||
<td class="num">300g</td>
|
||||
<td class="num subtotal">3.00</td>
|
||||
</tr>
|
||||
<tr class="zone-header"><td colspan="4">【餐线】 ×2</td></tr>
|
||||
<tr>
|
||||
<td><div class="item-name"><span class="item-name__thumb">🥦</span>清炒时蔬</div></td>
|
||||
<td class="num">¥4.00</td>
|
||||
<td class="num">150g</td>
|
||||
<td class="num subtotal">6.00</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><div class="item-name"><span class="item-name__thumb">🍚</span>米饭</div></td>
|
||||
<td class="num">¥1.60</td>
|
||||
<td class="num">250g</td>
|
||||
<td class="num subtotal">4.00</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<!-- 金额汇总 -->
|
||||
<div class="card">
|
||||
<div class="card__title">金额汇总</div>
|
||||
<div class="amount-list">
|
||||
<div class="amount-line">
|
||||
<span class="amount-line__label">商品合计</span>
|
||||
<span class="amount-line__value">¥46.60</span>
|
||||
</div>
|
||||
<div class="amount-line">
|
||||
<span class="amount-line__label">企业补贴优惠</span>
|
||||
<span class="amount-line__value" style="color:#4ade80;">-¥5.00</span>
|
||||
</div>
|
||||
<div class="amount-line amount-line--total">
|
||||
<span class="amount-line__label">实付金额</span>
|
||||
<span class="amount-line__value">¥41.60</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="margin-top:14px;padding-top:12px;border-top:1px dashed rgba(255,255,255,0.1);">
|
||||
<div class="amount-line">
|
||||
<span class="amount-line__label">支付方式</span>
|
||||
<span class="amount-line__value">📱 在线支付 · 微信支付</span>
|
||||
</div>
|
||||
<div class="amount-line" style="margin-top:6px;">
|
||||
<span class="amount-line__label">交易流水号</span>
|
||||
<span class="amount-line__value" style="font-family:Menlo,monospace;font-size:11px;">WX2026080612305012</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 右列:操作面板 -->
|
||||
<div class="right-col">
|
||||
|
||||
<!-- 退款记录(已退款时显示) -->
|
||||
<div class="refund-record" id="refundRecord" style="display:none;">
|
||||
<div style="margin-bottom:6px;color:#ff6b6b;font-weight:600;">⚠️ 已退款</div>
|
||||
<div>退款金额:<strong>¥41.60</strong></div>
|
||||
<div>退款方式:原路退回(微信)</div>
|
||||
<div>退款时间:2026-08-06 13:05:12</div>
|
||||
<div>操作人:张三 (CS001)</div>
|
||||
<div>退款原因:顾客反馈菜品口味问题</div>
|
||||
</div>
|
||||
|
||||
<!-- 正常订单操作 -->
|
||||
<div id="normalActions">
|
||||
<div class="card__title" style="font-size:12px;color:rgba(255,255,255,0.55);letter-spacing:1px;margin-bottom:10px;">订单操作</div>
|
||||
<div class="btn-group">
|
||||
<button class="btn btn--gold" onclick="window.location.href='09-print-receipt.html'">
|
||||
🖨️ 重新打印小票
|
||||
</button>
|
||||
<button class="btn btn--ghost" onclick="alert('已发起补齐明细流程')">
|
||||
✏️ 补齐明细(漏记/多记)
|
||||
</button>
|
||||
<button class="btn btn--ghost" onclick="alert('订单已加入今日异常单列表')">
|
||||
⚠️ 标记为异常订单
|
||||
</button>
|
||||
<button class="btn btn--danger" onclick="toggleRefundPanel()">
|
||||
💸 申请退款
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- 退款流程面板 -->
|
||||
<div class="refund-panel" id="refundPanel" style="margin-top:12px;">
|
||||
<div class="refund-panel__title">💸 发起退款</div>
|
||||
|
||||
<!-- 退款方式切换 -->
|
||||
<div class="refund-panel__label">退款方式</div>
|
||||
<div class="refund-type">
|
||||
<div class="refund-type__item active" data-type="full" onclick="switchRefundType('full')">
|
||||
<div class="refund-type__radio"></div>
|
||||
<div class="refund-type__body">
|
||||
<div class="refund-type__name">全额退款</div>
|
||||
<div class="refund-type__hint">一键退回 ¥41.60 到原支付账户</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="refund-type__item" data-type="partial" onclick="switchRefundType('partial')">
|
||||
<div class="refund-type__radio"></div>
|
||||
<div class="refund-type__body">
|
||||
<div class="refund-type__name">部分退款</div>
|
||||
<div class="refund-type__hint">手动输入退款金额(最多 ¥41.60)</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 部分退款金额输入 -->
|
||||
<div class="refund-amount-wrap" id="partialAmountWrap">
|
||||
<div class="refund-panel__label" style="margin-top:4px;">退款金额</div>
|
||||
<div class="refund-amount-input">
|
||||
<span class="refund-amount-input__symbol">¥</span>
|
||||
<input type="number" id="partialAmount" value="0.00" step="0.01" min="0" max="41.60" oninput="updatePartialAmount()">
|
||||
</div>
|
||||
<div class="refund-amount-quick">
|
||||
<button onclick="setPartial(10)">10</button>
|
||||
<button onclick="setPartial(20)">20</button>
|
||||
<button onclick="setPartial(41.60)">全额</button>
|
||||
<button onclick="setPartial(0)">清零</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 退款原因 -->
|
||||
<div class="refund-panel__label" style="margin-top:4px;">退款原因(必选)</div>
|
||||
<div class="refund-reason" id="refundReason">
|
||||
<div class="refund-reason__item" onclick="selectReason(this)">顾客反馈</div>
|
||||
<div class="refund-reason__item" onclick="selectReason(this)">操作错误</div>
|
||||
<div class="refund-reason__item" onclick="selectReason(this)">商品问题</div>
|
||||
<div class="refund-reason__item" onclick="selectReason(this)">重复结算</div>
|
||||
</div>
|
||||
|
||||
<!-- 退款备注 -->
|
||||
<div class="refund-panel__label" style="margin-top:4px;">退款备注(可选)</div>
|
||||
<textarea class="refund-note" id="refundNote" placeholder="补充说明本次退款的具体原因,如:顾客反馈米饭夹生,已重新补一份..." rows="3" maxlength="200" oninput="updateNoteCounter()"></textarea>
|
||||
<div class="refund-note__counter"><span id="noteCounter">0</span>/200</div>
|
||||
|
||||
<!-- 退款金额汇总 -->
|
||||
<div class="refund-summary">
|
||||
<span>本次退款金额</span>
|
||||
<span class="refund-summary__amount" id="refundAmountDisplay">¥41.60</span>
|
||||
</div>
|
||||
|
||||
<div class="refund-actions">
|
||||
<button class="btn btn--ghost" onclick="toggleRefundPanel()">取消</button>
|
||||
<button class="btn btn--danger" onclick="confirmRefund()">确认退款</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 关联信息 -->
|
||||
<div style="margin-top:auto;">
|
||||
<div class="related-info">
|
||||
<div class="related-info__row">
|
||||
<span>原价</span>
|
||||
<strong>¥46.60</strong>
|
||||
</div>
|
||||
<div class="related-info__row">
|
||||
<span>优惠</span>
|
||||
<strong>-¥5.00</strong>
|
||||
</div>
|
||||
<div class="related-info__row">
|
||||
<span>件数</span>
|
||||
<strong>5 件 / 1040g</strong>
|
||||
</div>
|
||||
<div class="related-info__row" style="margin-top:6px;padding-top:6px;border-top:1px dashed rgba(255,255,255,0.1);">
|
||||
<span>餐次</span>
|
||||
<strong>午餐 · 一楼 A 区</strong>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- Toast -->
|
||||
<div class="toast" id="toast"></div>
|
||||
|
||||
<style>
|
||||
.toast {
|
||||
position: fixed;
|
||||
top: 60px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%) translateY(-20px);
|
||||
background: rgba(0, 0, 0, 0.85);
|
||||
color: #fff;
|
||||
padding: 12px 28px;
|
||||
border-radius: 8px;
|
||||
font-size: 13px;
|
||||
z-index: 1000;
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
transition: opacity 0.3s, transform 0.3s, visibility 0.3s;
|
||||
white-space: nowrap;
|
||||
pointer-events: none;
|
||||
}
|
||||
.toast.show { opacity: 1; visibility: visible; transform: translateX(-50%) translateY(0); }
|
||||
.toast--warn { background: rgba(250, 173, 22, 0.92); }
|
||||
.toast--success { background: rgba(82, 196, 26, 0.92); }
|
||||
</style>
|
||||
|
||||
<script>
|
||||
/* 订单原金额 */
|
||||
var ORDER_PAYABLE = 41.60;
|
||||
/* 当前退款方式:full / partial */
|
||||
var currentRefundType = 'full';
|
||||
|
||||
function toggleRefundPanel() {
|
||||
var panel = document.getElementById('refundPanel');
|
||||
panel.classList.toggle('show');
|
||||
/* 默认重置为全额退款 */
|
||||
if (panel.classList.contains('show')) {
|
||||
switchRefundType('full');
|
||||
}
|
||||
}
|
||||
|
||||
/* 切换退款方式 */
|
||||
function switchRefundType(type) {
|
||||
currentRefundType = type;
|
||||
document.querySelectorAll('.refund-type__item').forEach(function(el) {
|
||||
el.classList.toggle('active', el.dataset.type === type);
|
||||
});
|
||||
var wrap = document.getElementById('partialAmountWrap');
|
||||
wrap.classList.toggle('show', type === 'partial');
|
||||
updateRefundDisplay();
|
||||
}
|
||||
|
||||
/* 部分退款:快捷金额 */
|
||||
function setPartial(v) {
|
||||
document.getElementById('partialAmount').value = v.toFixed(2);
|
||||
updatePartialAmount();
|
||||
}
|
||||
|
||||
function updatePartialAmount() {
|
||||
var input = document.getElementById('partialAmount');
|
||||
var v = parseFloat(input.value) || 0;
|
||||
/* 不超过订单应付 */
|
||||
if (v > ORDER_PAYABLE) {
|
||||
v = ORDER_PAYABLE;
|
||||
input.value = v.toFixed(2);
|
||||
showToast('退款金额不能超过应付金额 ¥' + ORDER_PAYABLE.toFixed(2), 'warn');
|
||||
}
|
||||
if (v < 0) {
|
||||
v = 0;
|
||||
input.value = '0.00';
|
||||
}
|
||||
updateRefundDisplay();
|
||||
}
|
||||
|
||||
/* 更新退款金额显示 */
|
||||
function updateRefundDisplay() {
|
||||
var amount = currentRefundType === 'full' ? ORDER_PAYABLE : (parseFloat(document.getElementById('partialAmount').value) || 0);
|
||||
document.getElementById('refundAmountDisplay').innerHTML = '¥' + amount.toFixed(2);
|
||||
}
|
||||
|
||||
/* 退款原因选择 */
|
||||
function selectReason(el) {
|
||||
document.querySelectorAll('.refund-reason__item').forEach(function(e) {
|
||||
e.classList.remove('active');
|
||||
});
|
||||
el.classList.add('active');
|
||||
}
|
||||
|
||||
/* 备注字数计数 */
|
||||
function updateNoteCounter() {
|
||||
var len = document.getElementById('refundNote').value.length;
|
||||
document.getElementById('noteCounter').textContent = len;
|
||||
}
|
||||
|
||||
/* 确认退款 */
|
||||
function confirmRefund() {
|
||||
var reasonEl = document.querySelector('.refund-reason__item.active');
|
||||
if (!reasonEl) {
|
||||
showToast('请选择退款原因', 'warn');
|
||||
return;
|
||||
}
|
||||
var reason = reasonEl.textContent.trim();
|
||||
var note = document.getElementById('refundNote').value.trim();
|
||||
var amount = currentRefundType === 'full' ? ORDER_PAYABLE : (parseFloat(document.getElementById('partialAmount').value) || 0);
|
||||
|
||||
if (amount <= 0) {
|
||||
showToast('退款金额必须大于 0', 'warn');
|
||||
return;
|
||||
}
|
||||
if (amount > ORDER_PAYABLE) {
|
||||
showToast('退款金额不能超过应付金额', 'warn');
|
||||
return;
|
||||
}
|
||||
|
||||
var typeText = currentRefundType === 'full' ? '全额退款' : '部分退款';
|
||||
var msg = '确认' + typeText + '?\n\n'
|
||||
+ '退款金额:¥' + amount.toFixed(2) + '\n'
|
||||
+ '退款原因:' + reason + '\n'
|
||||
+ (note ? '备注:' + note + '\n' : '')
|
||||
+ '此操作不可撤销。';
|
||||
|
||||
if (confirm(msg)) {
|
||||
showToast(typeText + ' ¥' + amount.toFixed(2) + ' 已发起', 'success');
|
||||
/* 隐藏操作面板,显示退款记录 */
|
||||
setTimeout(function() {
|
||||
document.getElementById('normalActions').style.display = 'none';
|
||||
var record = document.getElementById('refundRecord');
|
||||
record.style.display = 'block';
|
||||
/* 渲染退款记录内容 */
|
||||
record.innerHTML =
|
||||
'<div style="margin-bottom:6px;color:#ff6b6b;font-weight:600;">⚠️ ' + typeText + '已发起</div>'
|
||||
+ '<div>退款金额:<strong>¥' + amount.toFixed(2) + '</strong> / ' + (currentRefundType === 'full' ? '原订单全额' : ('剩余 ¥' + (ORDER_PAYABLE - amount).toFixed(2) + ' 已结算')) + '</div>'
|
||||
+ '<div>退款方式:原路退回(微信)</div>'
|
||||
+ '<div>退款时间:2026-08-06 14:30:25</div>'
|
||||
+ '<div>操作人:张三 (CS001)</div>'
|
||||
+ '<div>退款原因:' + reason + '</div>'
|
||||
+ (note ? '<div>备注:' + note + '</div>' : '');
|
||||
}, 1200);
|
||||
}
|
||||
}
|
||||
|
||||
function showToast(msg, type) {
|
||||
var el = document.getElementById('toast');
|
||||
el.textContent = msg;
|
||||
el.className = 'toast';
|
||||
if (type === 'success') el.classList.add('toast--success');
|
||||
if (type === 'warn') el.classList.add('toast--warn');
|
||||
el.classList.add('show');
|
||||
clearTimeout(el._timer);
|
||||
el._timer = setTimeout(function() { el.classList.remove('show'); }, 2200);
|
||||
}
|
||||
|
||||
/* ==================== URL 参数解析 ====================
|
||||
* 从订单列表跳转时携带的参数:
|
||||
* - id:订单号(用于显示)
|
||||
* - action=refund:自动展开退款面板
|
||||
* 例如:06-order-detail.html?id=CO-20260806-031&action=refund
|
||||
*/
|
||||
function getQueryParam(name) {
|
||||
var match = (window.location.search.match(new RegExp('[?&]' + name + '=([^&]+)')) || [])[1];
|
||||
return match ? decodeURIComponent(match) : null;
|
||||
}
|
||||
|
||||
(function autoInitFromUrl() {
|
||||
/* 同步订单号(若 URL 带了 id 参数,显示在订单头) */
|
||||
var orderId = getQueryParam('id');
|
||||
if (orderId) {
|
||||
var idEl = document.querySelector('.order-head__id');
|
||||
if (idEl) idEl.textContent = orderId;
|
||||
}
|
||||
var action = getQueryParam('action');
|
||||
/* 退款操作:自动展开退款面板并滚动到右侧 */
|
||||
if (action === 'refund') {
|
||||
/* 等待 DOM 渲染完成后展开 */
|
||||
setTimeout(function() {
|
||||
toggleRefundPanel();
|
||||
/* 滚动右侧操作区到退款面板位置 */
|
||||
var panel = document.getElementById('refundPanel');
|
||||
var rightCol = panel.closest('.right-col');
|
||||
if (rightCol && panel) {
|
||||
rightCol.scrollTop = panel.offsetTop - 20;
|
||||
}
|
||||
/* 高亮提示一下退款面板 */
|
||||
panel.style.boxShadow = '0 0 0 3px rgba(245, 34, 45, 0.3)';
|
||||
setTimeout(function() { panel.style.boxShadow = ''; }, 1800);
|
||||
showToast('请在下方填写退款信息', 'warn');
|
||||
}, 200);
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,888 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=1280, initial-scale=1.0">
|
||||
<title>结算设备 - 补齐明细 | 蚁熊智能餐养平台</title>
|
||||
<style>
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
body {
|
||||
font-family: -apple-system, "Microsoft YaHei", "PingFang SC", sans-serif;
|
||||
background: #05080f;
|
||||
color: #fff;
|
||||
min-height: 100vh;
|
||||
min-width: 1280px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 20px;
|
||||
}
|
||||
.device-frame {
|
||||
width: 1280px;
|
||||
height: 720px;
|
||||
background: #0e1326;
|
||||
border-radius: 24px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 24px 64px rgba(0, 0, 0, 0.6), 0 0 0 1px rgba(255, 255, 255, 0.04);
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
/* 顶部导航 */
|
||||
.top-bar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 44px;
|
||||
background: #1a2b4a;
|
||||
padding: 0 20px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.back-btn {
|
||||
font-size: 13px;
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
transition: color 0.2s;
|
||||
}
|
||||
.back-btn:hover { color: #fff; }
|
||||
.top-bar__title {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
color: rgba(255, 255, 255, 0.85);
|
||||
}
|
||||
.top-bar__meta {
|
||||
font-size: 12px;
|
||||
color: rgba(255, 255, 255, 0.5);
|
||||
font-family: Menlo, Consolas, monospace;
|
||||
}
|
||||
|
||||
/* 主内容 */
|
||||
.main-area {
|
||||
flex: 1;
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 360px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* ============ 左列:商品操作区 ============ */
|
||||
.items-col {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
}
|
||||
.items-col__header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 12px 20px;
|
||||
background: rgba(26, 43, 74, 0.5);
|
||||
border-bottom: 1px solid rgba(255, 255, 255, 0.06);
|
||||
}
|
||||
.items-col__title {
|
||||
font-size: 13px;
|
||||
color: rgba(255, 255, 255, 0.85);
|
||||
font-weight: 600;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
.items-col__icon {
|
||||
padding: 2px 8px;
|
||||
background: rgba(251, 191, 36, 0.15);
|
||||
color: #fbbf24;
|
||||
border: 1px solid rgba(251, 191, 36, 0.3);
|
||||
border-radius: 9px;
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
}
|
||||
.items-col__hint {
|
||||
font-size: 11px;
|
||||
color: rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
|
||||
/* Tab 切换:当前商品 / 添加商品 */
|
||||
.tabs {
|
||||
display: flex;
|
||||
gap: 6px;
|
||||
padding: 10px 20px;
|
||||
background: rgba(26, 43, 74, 0.3);
|
||||
border-bottom: 1px solid rgba(255, 255, 255, 0.06);
|
||||
}
|
||||
.tab {
|
||||
padding: 7px 16px;
|
||||
background: rgba(255, 255, 255, 0.04);
|
||||
border: 1px solid rgba(255, 255, 255, 0.08);
|
||||
border-radius: 6px;
|
||||
color: rgba(255, 255, 255, 0.65);
|
||||
font-size: 12px;
|
||||
cursor: pointer;
|
||||
transition: all 0.15s;
|
||||
}
|
||||
.tab.active {
|
||||
background: rgba(74, 144, 217, 0.15);
|
||||
border-color: #4a90d9;
|
||||
color: #fff;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* 商品列表区 */
|
||||
.items-list {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
padding: 12px 16px;
|
||||
scrollbar-width: none;
|
||||
}
|
||||
.items-list::-webkit-scrollbar { display: none; }
|
||||
|
||||
.zone-group { margin-bottom: 14px; }
|
||||
|
||||
/* 表头(对齐 03-checkout) */
|
||||
.table-head {
|
||||
display: grid;
|
||||
grid-template-columns: 24px auto 1fr auto 32px;
|
||||
gap: 10px;
|
||||
padding: 6px 14px;
|
||||
font-size: 11px;
|
||||
color: rgba(255, 255, 255, 0.4);
|
||||
letter-spacing: 1px;
|
||||
font-weight: 500;
|
||||
border-bottom: 1px solid rgba(255, 255, 255, 0.08);
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
.table-head__name { text-align: left; }
|
||||
.table-head__weight { text-align: center; justify-self: center; }
|
||||
.table-head__price { text-align: right; }
|
||||
|
||||
/* 分组标题(对齐 03-checkout) */
|
||||
.zone-header {
|
||||
font-size: 13px;
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.5px;
|
||||
padding: 6px 0 8px;
|
||||
border-bottom: 1px dashed rgba(255, 255, 255, 0.1);
|
||||
margin-bottom: 6px;
|
||||
margin-top: 8px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 8px;
|
||||
}
|
||||
.zone-header__name {
|
||||
font-size: 13px;
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.5px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
}
|
||||
.zone-header__count {
|
||||
padding: 1px 8px;
|
||||
background: rgba(74, 144, 217, 0.18);
|
||||
border-radius: 10px;
|
||||
font-size: 11px;
|
||||
color: #60a5fa;
|
||||
font-weight: 500;
|
||||
margin-left: 6px;
|
||||
}
|
||||
.zone-header__total {
|
||||
font-size: 11px;
|
||||
color: rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
|
||||
/* 商品行(对齐 03-checkout item-card 样式) */
|
||||
.item-card {
|
||||
display: grid;
|
||||
grid-template-columns: 24px auto 1fr auto 28px;
|
||||
gap: 10px;
|
||||
padding: 8px 14px;
|
||||
background: rgba(26, 43, 74, 0.35);
|
||||
border: 1px solid rgba(255, 255, 255, 0.04);
|
||||
border-radius: 8px;
|
||||
margin-bottom: 4px;
|
||||
align-items: center;
|
||||
}
|
||||
.item-card.added {
|
||||
background: rgba(82, 196, 26, 0.08);
|
||||
border-color: rgba(82, 196, 26, 0.3);
|
||||
}
|
||||
.item-card.removed {
|
||||
opacity: 0.45;
|
||||
background: rgba(245, 34, 45, 0.05);
|
||||
border-color: rgba(245, 34, 45, 0.25);
|
||||
}
|
||||
.item-card.removed .item-card__name { text-decoration: line-through; }
|
||||
.item-card__seq {
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
border-radius: 50%;
|
||||
background: rgba(74, 144, 217, 0.18);
|
||||
border: 1px solid rgba(74, 144, 217, 0.35);
|
||||
color: #60a5fa;
|
||||
font-size: 11px;
|
||||
font-weight: 700;
|
||||
font-family: Menlo, Consolas, monospace;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.item-card__info {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
gap: 8px;
|
||||
min-width: 0;
|
||||
}
|
||||
.item-card__name {
|
||||
font-size: 15px;
|
||||
color: #fff;
|
||||
font-weight: 600;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
.item-card__unit-price {
|
||||
font-size: 12px;
|
||||
color: rgba(255, 255, 255, 0.55);
|
||||
font-family: Menlo, Consolas, monospace;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.item-card__weight {
|
||||
font-size: 12px;
|
||||
color: #0AC4A8;
|
||||
font-family: Menlo, Consolas, monospace;
|
||||
padding: 2px 10px;
|
||||
background: rgba(10, 196, 168, 0.12);
|
||||
border-radius: 10px;
|
||||
white-space: nowrap;
|
||||
text-align: center;
|
||||
min-width: 76px;
|
||||
justify-self: center;
|
||||
}
|
||||
.item-card.removed .item-card__weight {
|
||||
color: #ff6b6b;
|
||||
background: rgba(245, 34, 45, 0.1);
|
||||
}
|
||||
.item-card.added .item-card__weight {
|
||||
color: #4ade80;
|
||||
background: rgba(82, 196, 26, 0.12);
|
||||
}
|
||||
.item-card__price {
|
||||
font-size: 16px;
|
||||
color: #0AC4A8;
|
||||
font-weight: 700;
|
||||
font-family: Menlo, Consolas, monospace;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.item-card__action {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
border-radius: 6px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
transition: all 0.15s;
|
||||
font-size: 13px;
|
||||
border: 1px solid;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.item-card__action--remove {
|
||||
background: rgba(245, 34, 45, 0.12);
|
||||
border-color: rgba(245, 34, 45, 0.35);
|
||||
color: #ff6b6b;
|
||||
}
|
||||
.item-card__action--remove:hover { background: rgba(245, 34, 45, 0.25); }
|
||||
.item-card__action--restore {
|
||||
background: rgba(82, 196, 26, 0.12);
|
||||
border-color: rgba(82, 196, 26, 0.35);
|
||||
color: #4ade80;
|
||||
}
|
||||
.item-card__action--restore:hover { background: rgba(82, 196, 26, 0.25); }
|
||||
|
||||
/* 变更标记 */
|
||||
.change-badge {
|
||||
display: inline-block;
|
||||
padding: 2px 6px;
|
||||
border-radius: 8px;
|
||||
font-size: 9px;
|
||||
font-weight: 700;
|
||||
margin-left: 6px;
|
||||
}
|
||||
.change-badge--add {
|
||||
background: rgba(82, 196, 26, 0.15);
|
||||
color: #4ade80;
|
||||
}
|
||||
.change-badge--remove {
|
||||
background: rgba(245, 34, 45, 0.15);
|
||||
color: #ff6b6b;
|
||||
}
|
||||
|
||||
/* 添加商品候选区 */
|
||||
.candidate-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 8px;
|
||||
}
|
||||
.candidate-item {
|
||||
padding: 10px;
|
||||
background: rgba(26, 43, 74, 0.4);
|
||||
border: 1px solid rgba(255, 255, 255, 0.06);
|
||||
border-radius: 8px;
|
||||
cursor: pointer;
|
||||
transition: all 0.15s;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
text-align: center;
|
||||
}
|
||||
.candidate-item:hover {
|
||||
background: rgba(82, 196, 26, 0.08);
|
||||
border-color: rgba(82, 196, 26, 0.3);
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
.candidate-item__thumb {
|
||||
font-size: 24px;
|
||||
}
|
||||
.candidate-item__name {
|
||||
font-size: 12px;
|
||||
color: #fff;
|
||||
font-weight: 600;
|
||||
}
|
||||
.candidate-item__meta {
|
||||
font-size: 10px;
|
||||
color: rgba(255, 255, 255, 0.55);
|
||||
}
|
||||
.candidate-item__add {
|
||||
margin-top: 4px;
|
||||
padding: 4px;
|
||||
background: rgba(82, 196, 26, 0.15);
|
||||
border: 1px solid rgba(82, 196, 26, 0.3);
|
||||
border-radius: 4px;
|
||||
color: #4ade80;
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* 搜索栏 */
|
||||
.search-bar {
|
||||
padding: 0 4px 12px;
|
||||
}
|
||||
.search-input {
|
||||
width: 100%;
|
||||
padding: 8px 12px;
|
||||
background: rgba(0, 0, 0, 0.25);
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
border-radius: 6px;
|
||||
color: #fff;
|
||||
font-size: 12px;
|
||||
outline: none;
|
||||
font-family: inherit;
|
||||
}
|
||||
.search-input:focus { border-color: #4a90d9; }
|
||||
|
||||
/* ============ 右列:差额汇总 ============ */
|
||||
.summary-col {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 18px 20px;
|
||||
background: rgba(26, 43, 74, 0.2);
|
||||
border-left: 1px solid rgba(255, 255, 255, 0.06);
|
||||
gap: 14px;
|
||||
overflow-y: auto;
|
||||
scrollbar-width: none;
|
||||
}
|
||||
.summary-col::-webkit-scrollbar { display: none; }
|
||||
|
||||
.section-label {
|
||||
font-size: 11px;
|
||||
color: rgba(255, 255, 255, 0.5);
|
||||
letter-spacing: 1px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
}
|
||||
.section-label::before {
|
||||
content: "";
|
||||
width: 3px;
|
||||
height: 11px;
|
||||
background: #fbbf24;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
/* 变更前后对比 */
|
||||
.compare-block {
|
||||
background: rgba(26, 43, 74, 0.4);
|
||||
border: 1px solid rgba(255, 255, 255, 0.06);
|
||||
border-radius: 10px;
|
||||
padding: 14px;
|
||||
}
|
||||
.compare-row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 6px 0;
|
||||
font-size: 12px;
|
||||
}
|
||||
.compare-row + .compare-row { border-top: 1px dashed rgba(255, 255, 255, 0.06); }
|
||||
.compare-row__label { color: rgba(255, 255, 255, 0.6); }
|
||||
.compare-row__value { color: rgba(255, 255, 255, 0.9); font-weight: 600; }
|
||||
.compare-row--old .compare-row__value {
|
||||
color: rgba(255, 255, 255, 0.55);
|
||||
text-decoration: line-through;
|
||||
}
|
||||
.compare-row--new .compare-row__value { color: #fff; }
|
||||
.compare-row--delta .compare-row__value {
|
||||
color: #4ade80;
|
||||
font-size: 16px;
|
||||
font-family: Menlo, Consolas, monospace;
|
||||
}
|
||||
.compare-row--delta-minus .compare-row__value { color: #ff6b6b; }
|
||||
|
||||
/* 变更日志 */
|
||||
.change-log {
|
||||
background: rgba(0, 0, 0, 0.2);
|
||||
border: 1px solid rgba(255, 255, 255, 0.06);
|
||||
border-radius: 8px;
|
||||
padding: 10px 12px;
|
||||
max-height: 180px;
|
||||
overflow-y: auto;
|
||||
scrollbar-width: none;
|
||||
font-size: 12px;
|
||||
}
|
||||
.change-log::-webkit-scrollbar { display: none; }
|
||||
.change-log__empty {
|
||||
text-align: center;
|
||||
color: rgba(255, 255, 255, 0.3);
|
||||
padding: 20px 0;
|
||||
}
|
||||
.log-item {
|
||||
display: flex;
|
||||
gap: 6px;
|
||||
padding: 5px 0;
|
||||
line-height: 1.5;
|
||||
}
|
||||
.log-item + .log-item { border-top: 1px dashed rgba(255, 255, 255, 0.05); }
|
||||
.log-item__icon { font-size: 12px; }
|
||||
.log-item__text { flex: 1; color: rgba(255, 255, 255, 0.75); }
|
||||
.log-item__name { color: #fff; font-weight: 600; }
|
||||
.log-item__amount { font-family: Menlo, Consolas, monospace; }
|
||||
.log-item__amount--add { color: #4ade80; }
|
||||
.log-item__amount--remove { color: #ff6b6b; }
|
||||
.log-item__time {
|
||||
font-size: 10px;
|
||||
color: rgba(255, 255, 255, 0.35);
|
||||
font-family: Menlo, Consolas, monospace;
|
||||
}
|
||||
|
||||
/* 操作按钮 */
|
||||
.actions {
|
||||
margin-top: auto;
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 2fr;
|
||||
gap: 8px;
|
||||
}
|
||||
.btn {
|
||||
padding: 13px 12px;
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
font-family: inherit;
|
||||
text-decoration: none;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 4px;
|
||||
}
|
||||
.btn--ghost {
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
border: 1px solid rgba(255, 255, 255, 0.12);
|
||||
}
|
||||
.btn--ghost:hover {
|
||||
background: rgba(245, 34, 45, 0.12);
|
||||
border-color: rgba(245, 34, 45, 0.35);
|
||||
color: #ff6b6b;
|
||||
}
|
||||
.btn--primary {
|
||||
background: linear-gradient(135deg, #fbbf24, #fb923c);
|
||||
color: #fff;
|
||||
box-shadow: 0 6px 20px rgba(251, 191, 36, 0.35);
|
||||
}
|
||||
.btn--primary:hover { transform: translateY(-1px); }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="device-frame">
|
||||
|
||||
<!-- 顶部导航 -->
|
||||
<div class="top-bar">
|
||||
<a class="back-btn" href="03-checkout.html">◀ 返回结算</a>
|
||||
<span class="top-bar__title">补齐明细</span>
|
||||
<span class="top-bar__meta">订单 CO-20260806-031</span>
|
||||
</div>
|
||||
|
||||
<!-- 主内容 -->
|
||||
<div class="main-area">
|
||||
|
||||
<!-- 左列:商品操作 -->
|
||||
<div class="items-col">
|
||||
<div class="items-col__header">
|
||||
<div class="items-col__title">
|
||||
✏️ 修正明细
|
||||
<span class="items-col__icon">支付前修正</span>
|
||||
</div>
|
||||
<div class="items-col__hint">点击 - 移除多记商品,在添加候选区点 + 补齐漏记</div>
|
||||
</div>
|
||||
|
||||
<div class="tabs">
|
||||
<div class="tab active" onclick="switchTab('current')">当前订单(5)</div>
|
||||
<div class="tab" onclick="switchTab('add')">添加商品</div>
|
||||
</div>
|
||||
|
||||
<!-- 当前订单商品 -->
|
||||
<div class="items-list" id="currentList"></div>
|
||||
|
||||
<!-- 添加商品候选区(默认隐藏) -->
|
||||
<div class="items-list" id="addList" style="display:none;">
|
||||
<div class="search-bar">
|
||||
<input type="text" class="search-input" placeholder="🔍 搜索菜品名称..." id="searchInput" oninput="filterCandidates()">
|
||||
</div>
|
||||
<div class="zone-group">
|
||||
<div class="zone-header">
|
||||
<span class="zone-header__name">🥜 营养秤 · 餐线菜品</span>
|
||||
<span class="zone-header__total">8 个候选</span>
|
||||
</div>
|
||||
<div class="candidate-grid" id="candidateScale"></div>
|
||||
</div>
|
||||
<div class="zone-group">
|
||||
<div class="zone-header">
|
||||
<span class="zone-header__name">⚖️ 档口秤 · 档口菜品</span>
|
||||
<span class="zone-header__total">6 个候选</span>
|
||||
</div>
|
||||
<div class="candidate-grid" id="candidateStall"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 右列:差额汇总 -->
|
||||
<div class="summary-col">
|
||||
|
||||
<div>
|
||||
<div class="section-label">金额变化对比</div>
|
||||
<div class="compare-block" style="margin-top:8px;">
|
||||
<div class="compare-row compare-row--old">
|
||||
<span class="compare-row__label">原订单合计</span>
|
||||
<span class="compare-row__value">¥46.60</span>
|
||||
</div>
|
||||
<div class="compare-row">
|
||||
<span class="compare-row__label">本次修正</span>
|
||||
<span class="compare-row__value" id="changeAmount">+¥0.00</span>
|
||||
</div>
|
||||
<div class="compare-row compare-row--new">
|
||||
<span class="compare-row__label">修正后合计</span>
|
||||
<span class="compare-row__value" id="newAmount">¥46.60</span>
|
||||
</div>
|
||||
<div class="compare-row" style="border-top:1px solid rgba(255,255,255,0.1);margin-top:6px;padding-top:10px;">
|
||||
<span class="compare-row__label">企业补贴优惠</span>
|
||||
<span class="compare-row__value" style="color:#4ade80;">-¥5.00</span>
|
||||
</div>
|
||||
<div class="compare-row compare-row--delta" id="deltaRow">
|
||||
<span class="compare-row__label">应付金额</span>
|
||||
<span class="compare-row__value" id="newPayable">¥41.60</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 变更日志 -->
|
||||
<div>
|
||||
<div class="section-label">变更日志</div>
|
||||
<div class="change-log" id="changeLog" style="margin-top:8px;">
|
||||
<div class="change-log__empty">暂无变更,请到左侧添加或移除商品</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<div class="actions">
|
||||
<a class="btn btn--ghost" href="03-checkout.html">放弃修正</a>
|
||||
<button class="btn btn--primary" onclick="applyChanges()">
|
||||
✅ 应用修正并返回结算
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<script>
|
||||
/* ==================== Mock 数据 ==================== */
|
||||
var currentItems = [
|
||||
{ id: 1, name: '红烧肉', zone: '档口秤', thumb: '🍖', weight: 180, price: 12.00, status: 'normal' },
|
||||
{ id: 2, name: '清炒时蔬', zone: '营养秤', thumb: '🥦', weight: 150, price: 4.00, status: 'normal' },
|
||||
{ id: 3, name: '鱼香肉丝', zone: '档口秤', thumb: '🍟', weight: 160, price: 7.50, status: 'normal' },
|
||||
{ id: 4, name: '米饭', zone: '营养秤', thumb: '🍚', weight: 250, price: 1.60, status: 'normal' },
|
||||
{ id: 5, name: '冬瓜排骨汤', zone: '档口秤', thumb: '🍲', weight: 300, price: 1.00, status: 'normal' }
|
||||
];
|
||||
|
||||
var candidates = [
|
||||
{ id: 101, name: '宫保鸡丁', zone: '档口秤', thumb: '🍗', price: 9.00 },
|
||||
{ id: 102, name: '番茄炒蛋', zone: '营养秤', thumb: '🥛', price: 5.00 },
|
||||
{ id: 103, name: '麻婆豆腐', zone: '档口秤', thumb: '🍲', price: 5.00 },
|
||||
{ id: 104, name: '紫菜蛋花汤', zone: '营养秤', thumb: '🍲', price: 2.00 },
|
||||
{ id: 105, name: '蒜蓉西兰花', zone: '营养秤', thumb: '🥦', price: 4.00 },
|
||||
{ id: 106, name: '清蒸鲈鱼', zone: '档口秤', thumb: '🐟', price: 12.50 },
|
||||
{ id: 107, name: '紫米饭', zone: '营养秤', thumb: '🍚', price: 1.50 },
|
||||
{ id: 108, name: '豆浆', zone: '营养秤', thumb: '🥛', price: 1.00 },
|
||||
{ id: 109, name: '青椒土豆丝', zone: '档口秤', thumb: '🥔', price: 4.50 },
|
||||
{ id: 110, name: '回锅肉', zone: '档口秤', thumb: '🍖', price: 11.00 },
|
||||
{ id: 111, name: '凉拌黄瓜', zone: '营养秤', thumb: '🥒', price: 3.00 },
|
||||
{ id: 112, name: '番茄蛋汤', zone: '档口秤', thumb: '🍲', price: 1.50 },
|
||||
{ id: 113, name: '酸菜鱼', zone: '档口秤', thumb: '🐟', price: 14.00 },
|
||||
{ id: 114, name: '馒头', zone: '营养秤', thumb: '🍞', price: 0.80 }
|
||||
];
|
||||
|
||||
var changeLog = [];
|
||||
|
||||
function subtotal(it) {
|
||||
return it.weight ? it.weight / 100 * it.price : it.price;
|
||||
}
|
||||
|
||||
/* 渲染当前商品列表(对齐 03-checkout 商品行样式) */
|
||||
function renderCurrent() {
|
||||
var grouped = { '营养秤': [], '档口秤': [] };
|
||||
currentItems.forEach(function(it) {
|
||||
if (!grouped[it.zone]) grouped[it.zone] = [];
|
||||
grouped[it.zone].push(it);
|
||||
});
|
||||
|
||||
var html = '<div class="table-head">'
|
||||
+ '<span>#</span>'
|
||||
+ '<span class="table-head__name">餐品名称 / 单价</span>'
|
||||
+ '<span class="table-head__weight">取餐量</span>'
|
||||
+ '<span class="table-head__price">金额</span>'
|
||||
+ '<span></span>'
|
||||
+ '</div>';
|
||||
|
||||
var seq = 0;
|
||||
['营养秤', '档口秤'].forEach(function(zone) {
|
||||
var items = grouped[zone] || [];
|
||||
if (items.length === 0) return;
|
||||
var zoneLabel = zone === '营养秤' ? '餐线菜品' : '档口菜品';
|
||||
var zoneIcon = zone === '营养秤' ? '🥜' : '⚖️';
|
||||
var zoneTotal = items.reduce(function(s, it) {
|
||||
return s + (it.status !== 'removed' ? subtotal(it) : 0);
|
||||
}, 0);
|
||||
|
||||
html += '<div class="zone-group">'
|
||||
+ '<div class="zone-header">'
|
||||
+ '<span class="zone-header__name">' + zoneIcon + ' ' + zoneLabel
|
||||
+ '<span class="zone-header__count">' + items.length + ' 件</span>'
|
||||
+ '</span>'
|
||||
+ '<span class="zone-header__total">小计 ¥' + zoneTotal.toFixed(2) + '</span>'
|
||||
+ '</div>';
|
||||
|
||||
items.forEach(function(it) {
|
||||
seq++;
|
||||
var actionBtn = it.status === 'removed'
|
||||
? '<div class="item-card__action item-card__action--restore" onclick="restoreItem(' + it.id + ')" title="恢复">↺</div>'
|
||||
: '<div class="item-card__action item-card__action--remove" onclick="removeItem(' + it.id + ')" title="移除">−</div>';
|
||||
|
||||
var badge = '';
|
||||
if (it.status === 'added') badge = '<span class="change-badge change-badge--add">新加</span>';
|
||||
if (it.status === 'removed') badge = '<span class="change-badge change-badge--remove">已移除</span>';
|
||||
|
||||
var weightText = it.weight ? '取 ' + it.weight + 'g' : '需称重';
|
||||
var unitPrice = it.weight ? '¥' + it.price.toFixed(2) + '/100g' : '¥' + it.price.toFixed(2) + '/份';
|
||||
|
||||
html += '<div class="item-card ' + (it.status === 'added' ? 'added' : '') + (it.status === 'removed' ? ' removed' : '') + '">'
|
||||
+ '<div class="item-card__seq">' + seq + '</div>'
|
||||
+ '<div class="item-card__info">'
|
||||
+ '<span class="item-card__name">' + it.name + badge + '</span>'
|
||||
+ '<span class="item-card__unit-price">' + unitPrice + '</span>'
|
||||
+ '</div>'
|
||||
+ '<span class="item-card__weight">' + weightText + '</span>'
|
||||
+ '<div class="item-card__price">¥' + subtotal(it).toFixed(2) + '</div>'
|
||||
+ actionBtn
|
||||
+ '</div>';
|
||||
});
|
||||
|
||||
html += '</div>';
|
||||
});
|
||||
|
||||
document.getElementById('currentList').innerHTML = html;
|
||||
}
|
||||
|
||||
/* 渲染候选添加商品 */
|
||||
function renderCandidates() {
|
||||
var grouped = { '营养秤': [], '档口秤': [] };
|
||||
candidates.forEach(function(it) {
|
||||
grouped[it.zone].push(it);
|
||||
});
|
||||
|
||||
document.getElementById('candidateScale').innerHTML = grouped['营养秤'].map(function(it) {
|
||||
return candidateHtml(it);
|
||||
}).join('');
|
||||
|
||||
document.getElementById('candidateStall').innerHTML = grouped['档口秤'].map(function(it) {
|
||||
return candidateHtml(it);
|
||||
}).join('');
|
||||
}
|
||||
|
||||
function candidateHtml(it) {
|
||||
return '<div class="candidate-item" data-name="' + it.name + '">'
|
||||
+ '<div class="candidate-item__thumb">' + it.thumb + '</div>'
|
||||
+ '<div class="candidate-item__name">' + it.name + '</div>'
|
||||
+ '<div class="candidate-item__meta">¥' + it.price.toFixed(2) + '/100g</div>'
|
||||
+ '<div class="candidate-item__add" onclick="addItem(' + it.id + ')">+ 添加</div>'
|
||||
+ '</div>';
|
||||
}
|
||||
|
||||
/* 搜索过滤 */
|
||||
function filterCandidates() {
|
||||
var keyword = document.getElementById('searchInput').value.toLowerCase();
|
||||
document.querySelectorAll('.candidate-item').forEach(function(el) {
|
||||
var name = el.dataset.name.toLowerCase();
|
||||
el.style.display = name.indexOf(keyword) >= 0 ? '' : 'none';
|
||||
});
|
||||
}
|
||||
|
||||
/* Tab 切换 */
|
||||
function switchTab(type) {
|
||||
document.querySelectorAll('.tab').forEach(function(el, idx) {
|
||||
el.classList.toggle('active', (type === 'current' && idx === 0) || (type === 'add' && idx === 1));
|
||||
});
|
||||
document.getElementById('currentList').style.display = type === 'current' ? '' : 'none';
|
||||
document.getElementById('addList').style.display = type === 'add' ? '' : 'none';
|
||||
}
|
||||
|
||||
/* 移除商品(多记) */
|
||||
function removeItem(id) {
|
||||
var item = currentItems.filter(function(it) { return it.id === id; })[0];
|
||||
if (!item) return;
|
||||
if (item.status === 'added') {
|
||||
/* 新加的直接删除 */
|
||||
currentItems = currentItems.filter(function(it) { return it.id !== id; });
|
||||
changeLog = changeLog.filter(function(l) { return l.id !== id; });
|
||||
} else {
|
||||
item.status = 'removed';
|
||||
changeLog.push({
|
||||
id: id, type: 'remove', name: item.name,
|
||||
amount: -subtotal(item), time: getTime()
|
||||
});
|
||||
}
|
||||
renderCurrent();
|
||||
renderLog();
|
||||
recalc();
|
||||
}
|
||||
|
||||
/* 恢复商品 */
|
||||
function restoreItem(id) {
|
||||
var item = currentItems.filter(function(it) { return it.id === id; })[0];
|
||||
if (!item) return;
|
||||
item.status = 'normal';
|
||||
changeLog = changeLog.filter(function(l) { return l.id !== id; });
|
||||
renderCurrent();
|
||||
renderLog();
|
||||
recalc();
|
||||
}
|
||||
|
||||
/* 添加商品 */
|
||||
function addItem(candidateId) {
|
||||
var cand = candidates.filter(function(c) { return c.id === candidateId; })[0];
|
||||
if (!cand) return;
|
||||
|
||||
/* 弹窗输入重量 */
|
||||
var weight = prompt('请输入 "' + cand.name + '" 的重量(克):', '150');
|
||||
if (!weight) return;
|
||||
var w = parseFloat(weight) || 150;
|
||||
|
||||
var newItem = {
|
||||
id: Date.now(), name: cand.name, zone: cand.zone, thumb: cand.thumb,
|
||||
weight: w, price: cand.price, status: 'added'
|
||||
};
|
||||
currentItems.push(newItem);
|
||||
changeLog.push({
|
||||
id: newItem.id, type: 'add', name: cand.name,
|
||||
amount: subtotal(newItem), time: getTime()
|
||||
});
|
||||
renderCurrent();
|
||||
renderLog();
|
||||
recalc();
|
||||
|
||||
/* 切回当前订单 Tab */
|
||||
switchTab('current');
|
||||
}
|
||||
|
||||
function getTime() {
|
||||
var d = new Date();
|
||||
return String(d.getHours()).padStart(2, '0') + ':' + String(d.getMinutes()).padStart(2, '0') + ':' + String(d.getSeconds()).padStart(2, '0');
|
||||
}
|
||||
|
||||
/* 变更日志 */
|
||||
function renderLog() {
|
||||
var el = document.getElementById('changeLog');
|
||||
if (changeLog.length === 0) {
|
||||
el.innerHTML = '<div class="change-log__empty">暂无变更,请到左侧添加或移除商品</div>';
|
||||
return;
|
||||
}
|
||||
el.innerHTML = changeLog.map(function(l) {
|
||||
var icon = l.type === 'add' ? '➕' : '➖';
|
||||
var cls = l.type === 'add' ? 'add' : 'remove';
|
||||
return '<div class="log-item">'
|
||||
+ '<span class="log-item__icon">' + icon + '</span>'
|
||||
+ '<div class="log-item__text">'
|
||||
+ '<span class="log-item__name">' + l.name + '</span> '
|
||||
+ '<span class="log-item__amount log-item__amount--' + cls + '">(' + (l.amount > 0 ? '+' : '') + '¥' + l.amount.toFixed(2) + ')</span>'
|
||||
+ ' <span class="log-item__time">' + l.time + '</span>'
|
||||
+ '</div>'
|
||||
+ '</div>';
|
||||
}).join('');
|
||||
}
|
||||
|
||||
/* 重新计算金额 */
|
||||
function recalc() {
|
||||
var original = 46.60;
|
||||
var newTotal = currentItems.reduce(function(s, it) {
|
||||
return s + (it.status === 'removed' ? 0 : subtotal(it));
|
||||
}, 0);
|
||||
var change = newTotal - original;
|
||||
var discount = 5.00;
|
||||
var newPayable = newTotal - discount;
|
||||
|
||||
document.getElementById('changeAmount').innerHTML = (change >= 0 ? '+' : '') + '¥' + change.toFixed(2);
|
||||
document.getElementById('changeAmount').style.color = change >= 0 ? '#4ade80' : '#ff6b6b';
|
||||
document.getElementById('newAmount').textContent = '¥' + newTotal.toFixed(2);
|
||||
document.getElementById('newPayable').innerHTML = '¥' + newPayable.toFixed(2);
|
||||
|
||||
var deltaRow = document.getElementById('deltaRow');
|
||||
deltaRow.className = change >= 0 ? 'compare-row compare-row--delta' : 'compare-row compare-row--delta compare-row--delta-minus';
|
||||
}
|
||||
|
||||
/* 应用变更 */
|
||||
function applyChanges() {
|
||||
if (changeLog.length === 0) {
|
||||
alert('暂无变更,可直接返回结算');
|
||||
return;
|
||||
}
|
||||
if (confirm('确认应用本次修正?\n变更:' + changeLog.length + ' 项\n新应付金额:¥' + (currentItems.reduce(function(s, it) { return s + (it.status === 'removed' ? 0 : subtotal(it)); }, 0) - 5).toFixed(2))) {
|
||||
alert('修正已应用,返回结算页');
|
||||
window.location.href = '03-checkout.html';
|
||||
}
|
||||
}
|
||||
|
||||
/* 初始化 */
|
||||
renderCurrent();
|
||||
renderCandidates();
|
||||
recalc();
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
+33
-362
@@ -59,152 +59,15 @@
|
||||
color: rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
|
||||
/* 主体:左右两列 */
|
||||
/* 主体:单列小票预览 */
|
||||
.page-body {
|
||||
display: grid;
|
||||
grid-template-columns: 340px 1fr;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: calc(100% - 44px);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* ===== 左列:订单列表 ===== */
|
||||
.left-col {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
border-right: 1px solid rgba(255, 255, 255, 0.06);
|
||||
background: rgba(26, 43, 74, 0.3);
|
||||
}
|
||||
.filter-bar {
|
||||
padding: 12px 16px;
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
border-bottom: 1px solid rgba(255, 255, 255, 0.06);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.filter-select {
|
||||
flex: 1;
|
||||
background: rgba(0, 0, 0, 0.25);
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
border-radius: 6px;
|
||||
padding: 6px 10px;
|
||||
font-size: 12px;
|
||||
color: rgba(255, 255, 255, 0.85);
|
||||
font-family: inherit;
|
||||
outline: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
.filter-select:focus { border-color: #4a90d9; }
|
||||
|
||||
.order-list {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
padding: 10px 12px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
scrollbar-width: none;
|
||||
}
|
||||
.order-list::-webkit-scrollbar { display: none; }
|
||||
|
||||
.order-card {
|
||||
background: #1a2b4a;
|
||||
border: 1px solid rgba(255, 255, 255, 0.06);
|
||||
border-radius: 8px;
|
||||
padding: 10px 12px;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
position: relative;
|
||||
}
|
||||
.order-card:hover {
|
||||
border-color: rgba(74, 144, 217, 0.4);
|
||||
background: rgba(74, 144, 217, 0.08);
|
||||
}
|
||||
.order-card.active {
|
||||
border-color: #4a90d9;
|
||||
background: rgba(74, 144, 217, 0.12);
|
||||
box-shadow: 0 0 0 1px rgba(74, 144, 217, 0.3);
|
||||
}
|
||||
.order-card.printed {
|
||||
opacity: 0.55;
|
||||
}
|
||||
.order-card__row1 {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
.order-card__id {
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
font-family: Menlo, Consolas, monospace;
|
||||
}
|
||||
.meal-tag {
|
||||
font-size: 10px;
|
||||
line-height: 1;
|
||||
padding: 3px 7px;
|
||||
border-radius: 9px;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.3px;
|
||||
}
|
||||
.meal-tag--breakfast {
|
||||
background: rgba(250, 140, 22, 0.18);
|
||||
color: #fb923c;
|
||||
border: 1px solid rgba(250, 140, 22, 0.35);
|
||||
}
|
||||
.meal-tag--lunch {
|
||||
background: rgba(37, 99, 235, 0.18);
|
||||
color: #60a5fa;
|
||||
border: 1px solid rgba(37, 99, 235, 0.35);
|
||||
}
|
||||
.meal-tag--dinner {
|
||||
background: rgba(34, 197, 94, 0.18);
|
||||
color: #4ade80;
|
||||
border: 1px solid rgba(34, 197, 94, 0.35);
|
||||
}
|
||||
.order-card__row2 {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
font-size: 11px;
|
||||
color: rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
.order-card__time {
|
||||
font-family: Menlo, Consolas, monospace;
|
||||
}
|
||||
.order-card__amount {
|
||||
font-size: 14px;
|
||||
font-weight: 700;
|
||||
color: #0AC4A8;
|
||||
}
|
||||
.order-card__status {
|
||||
position: absolute;
|
||||
top: 8px;
|
||||
right: 8px;
|
||||
font-size: 9px;
|
||||
line-height: 1;
|
||||
padding: 3px 6px;
|
||||
border-radius: 8px;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.3px;
|
||||
}
|
||||
.order-card__status--printed {
|
||||
background: rgba(255, 255, 255, 0.06);
|
||||
color: rgba(255, 255, 255, 0.4);
|
||||
border: 1px solid rgba(255, 255, 255, 0.12);
|
||||
}
|
||||
.order-card__status--pending {
|
||||
background: rgba(234, 88, 12, 0.18);
|
||||
color: #fb923c;
|
||||
border: 1px solid rgba(234, 88, 12, 0.35);
|
||||
}
|
||||
|
||||
/* ===== 右列:小票预览 ===== */
|
||||
.right-col {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
}
|
||||
/* ===== 小票预览区 ===== */
|
||||
.receipt-stage {
|
||||
flex: 1;
|
||||
padding: 24px 32px;
|
||||
@@ -549,7 +412,7 @@
|
||||
|
||||
<!-- 顶部导航 -->
|
||||
<div class="top-bar">
|
||||
<a class="back-btn" href="index.html">◀ 返回</a>
|
||||
<a class="back-btn" href="index.html">◀ 返回主页</a>
|
||||
<span class="top-bar__title">打印小票预览</span>
|
||||
<span class="top-bar__meta" id="topMeta">2026-08-03</span>
|
||||
</div>
|
||||
@@ -557,31 +420,11 @@
|
||||
<!-- 主体 -->
|
||||
<div class="page-body">
|
||||
|
||||
<!-- 左列:订单列表 -->
|
||||
<div class="left-col">
|
||||
<div class="filter-bar">
|
||||
<select class="filter-select" id="mealFilter" onchange="renderOrderList()">
|
||||
<option value="all">全部餐次</option>
|
||||
<option value="breakfast">早餐</option>
|
||||
<option value="lunch">午餐</option>
|
||||
<option value="dinner">晚餐</option>
|
||||
</select>
|
||||
<select class="filter-select" id="statusFilter" onchange="renderOrderList()">
|
||||
<option value="all">全部状态</option>
|
||||
<option value="pending">未打印</option>
|
||||
<option value="printed">已打印</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="order-list" id="orderList"></div>
|
||||
</div>
|
||||
|
||||
<!-- 右列:小票预览 -->
|
||||
<div class="right-col">
|
||||
<div class="receipt-stage" id="receiptStage"></div>
|
||||
<div class="action-bar">
|
||||
<button class="btn btn--ghost" onclick="window.location.href='index.html'">◀ 返回</button>
|
||||
<button class="btn btn--success" id="printBtn" onclick="handlePrint()">🖨️ 打印小票</button>
|
||||
</div>
|
||||
<!-- 小票预览区 -->
|
||||
<div class="receipt-stage" id="receiptStage"></div>
|
||||
<div class="action-bar">
|
||||
<button class="btn btn--ghost" onclick="window.location.href='index.html'">◀ 返回主页</button>
|
||||
<button class="btn btn--success" id="printBtn" onclick="handlePrint()">🖨️ 打印小票</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@@ -592,121 +435,27 @@
|
||||
<div class="toast" id="toast"></div>
|
||||
|
||||
<script>
|
||||
/* ==================== Mock 订单数据 ==================== */
|
||||
var mockOrders = [
|
||||
{
|
||||
id: 'CO-20260803-001',
|
||||
mealType: 'lunch',
|
||||
mealLabel: '午餐',
|
||||
line: '一楼',
|
||||
cashier: '张三',
|
||||
time: '2026-08-03 12:15:30',
|
||||
payTime: '2026-08-03 12:15:35',
|
||||
items: [
|
||||
/* 小计 = 克重 ÷ 100 × 单价(100g) */
|
||||
{ name: '宫保鸡丁', zone: '档口秤', weight: 200, price: 9.00, qty: 1 },
|
||||
{ name: '番茄炒蛋', zone: '营养秤', weight: 150, price: 5.00, qty: 1 },
|
||||
{ name: '米饭', zone: '营养秤', weight: 250, price: 1.60, qty: 1 },
|
||||
{ name: '紫菜蛋花汤', zone: '档口秤', weight: 300, price: 2.00, qty: 1 }
|
||||
],
|
||||
total: 35.50, discount: 3.00, payable: 32.50, paid: 32.50,
|
||||
payType: '会员支付', payMethod: '人脸支付', balance: 1280.50,
|
||||
nutrition: { calories: 685, protein: 28, fat: 18, carb: 95, score: 82 },
|
||||
printed: true
|
||||
},
|
||||
{
|
||||
id: 'CO-20260803-008',
|
||||
mealType: 'breakfast',
|
||||
mealLabel: '早餐',
|
||||
line: '一楼',
|
||||
cashier: '张三',
|
||||
time: '2026-08-03 07:42:18',
|
||||
payTime: '2026-08-03 07:42:23',
|
||||
items: [
|
||||
{ name: '豆浆', zone: '营养秤', weight: 300, price: 1.00, qty: 1 },
|
||||
{ name: '油条', zone: '档口秤', weight: 240, price: 2.50, qty: 2 },
|
||||
{ name: '茶叶蛋', zone: '营养秤', weight: 60, price: 4.00, qty: 1 }
|
||||
],
|
||||
total: 11.40, discount: 0, payable: 11.40, paid: 11.40,
|
||||
payType: '会员支付', payMethod: '人脸支付', balance: 1292.50,
|
||||
nutrition: { calories: 425, protein: 15, fat: 12, carb: 60, score: 75 },
|
||||
printed: true
|
||||
},
|
||||
{
|
||||
id: 'CO-20260803-015',
|
||||
mealType: 'lunch',
|
||||
mealLabel: '午餐',
|
||||
line: 'A 区 2 号餐线',
|
||||
cashier: '李四',
|
||||
time: '2026-08-03 12:32:45',
|
||||
payTime: '2026-08-03 12:32:50',
|
||||
items: [
|
||||
{ name: '红烧肉', zone: '档口秤', weight: 180, price: 12.00, qty: 1 },
|
||||
{ name: '清炒时蔬', zone: '营养秤', weight: 150, price: 4.00, qty: 1 },
|
||||
{ name: '鱼香肉丝', zone: '档口秤', weight: 160, price: 7.50, qty: 1 },
|
||||
{ name: '米饭', zone: '营养秤', weight: 250, price: 1.60, qty: 1 },
|
||||
{ name: '冬瓜排骨汤', zone: '档口秤', weight: 300, price: 1.00, qty: 1 }
|
||||
],
|
||||
total: 46.60, discount: 5.00, payable: 41.60, paid: 41.60,
|
||||
payType: '会员支付', payMethod: '人脸支付', balance: 1240.50,
|
||||
nutrition: { calories: 720, protein: 35, fat: 28, carb: 88, score: 88 },
|
||||
printed: false
|
||||
},
|
||||
{
|
||||
id: 'CO-20260803-022',
|
||||
mealType: 'dinner',
|
||||
mealLabel: '晚餐',
|
||||
line: '一楼',
|
||||
cashier: '王五',
|
||||
time: '2026-08-03 18:15:20',
|
||||
payTime: '2026-08-03 18:15:25',
|
||||
items: [
|
||||
{ name: '清蒸鲈鱼', zone: '档口秤', weight: 200, price: 12.50, qty: 1 },
|
||||
{ name: '蒜蓉西兰花', zone: '营养秤', weight: 150, price: 4.00, qty: 1 },
|
||||
{ name: '紫米饭', zone: '营养秤', weight: 200, price: 1.50, qty: 1 }
|
||||
],
|
||||
total: 34.00, discount: 0, payable: 34.00, paid: 34.00,
|
||||
payType: '扫码支付', payMethod: '微信支付',
|
||||
nutrition: { calories: 510, protein: 32, fat: 14, carb: 65, score: 90 },
|
||||
printed: false
|
||||
},
|
||||
{
|
||||
id: 'CO-20260803-029',
|
||||
mealType: 'lunch',
|
||||
mealLabel: '午餐',
|
||||
line: 'A 区 3 号餐线',
|
||||
cashier: '张三',
|
||||
time: '2026-08-03 12:48:10',
|
||||
payTime: '2026-08-03 12:48:15',
|
||||
items: [
|
||||
{ name: '番茄炒蛋', zone: '营养秤', weight: 150, price: 5.00, qty: 1 },
|
||||
{ name: '麻婆豆腐', zone: '档口秤', weight: 180, price: 5.00, qty: 1 },
|
||||
{ name: '米饭', zone: '营养秤', weight: 250, price: 1.60, qty: 1 },
|
||||
{ name: '番茄蛋汤', zone: '档口秤', weight: 280, price: 1.50, qty: 1 }
|
||||
],
|
||||
total: 24.70, discount: 0, payable: 24.70, paid: 24.70,
|
||||
payType: '会员支付', payMethod: '人脸支付', balance: 1187.50,
|
||||
nutrition: { calories: 480, protein: 22, fat: 15, carb: 70, score: 78 },
|
||||
printed: false
|
||||
},
|
||||
{
|
||||
id: 'CO-20260803-035',
|
||||
mealType: 'breakfast',
|
||||
mealLabel: '早餐',
|
||||
line: 'A 区 2 号餐线',
|
||||
cashier: '李四',
|
||||
time: '2026-08-03 08:15:30',
|
||||
payTime: '2026-08-03 08:15:33',
|
||||
items: [
|
||||
{ name: '皮蛋瘦肉粥', zone: '档口秤', weight: 350, price: 1.40, qty: 1 },
|
||||
{ name: '鲜肉包子', zone: '营养秤', weight: 150, price: 2.00, qty: 1 }
|
||||
],
|
||||
total: 7.90, discount: 0, payable: 7.90, paid: 7.90,
|
||||
payType: '扫码支付', payMethod: '支付宝支付',
|
||||
nutrition: { calories: 320, protein: 12, fat: 8, carb: 48, score: 70 },
|
||||
printed: false
|
||||
}
|
||||
];
|
||||
/* ==================== Mock 订单数据(仅展示样本) ==================== */
|
||||
var mockOrder = {
|
||||
id: 'CO-20260803-001',
|
||||
mealType: 'lunch',
|
||||
mealLabel: '午餐',
|
||||
line: '一楼',
|
||||
cashier: '张三',
|
||||
time: '2026-08-03 12:15:30',
|
||||
payTime: '2026-08-03 12:15:35',
|
||||
items: [
|
||||
/* 小计 = 克重 ÷ 100 × 单价(100g) */
|
||||
{ name: '宫保鸡丁', zone: '档口秤', weight: 200, price: 9.00, qty: 1 },
|
||||
{ name: '番茄炒蛋', zone: '营养秤', weight: 150, price: 5.00, qty: 1 },
|
||||
{ name: '米饭', zone: '营养秤', weight: 250, price: 1.60, qty: 1 },
|
||||
{ name: '紫菜蛋花汤', zone: '档口秤', weight: 300, price: 2.00, qty: 1 }
|
||||
],
|
||||
total: 35.50, discount: 3.00, payable: 32.50, paid: 32.50,
|
||||
payType: '会员支付', payMethod: '人脸支付', balance: 1280.50,
|
||||
nutrition: { calories: 685, protein: 28, fat: 18, carb: 95, score: 82 },
|
||||
printed: true
|
||||
};
|
||||
|
||||
/* 食堂抬头 */
|
||||
var canteenInfo = {
|
||||
@@ -715,57 +464,9 @@
|
||||
phone: '023-7788-XXXX'
|
||||
};
|
||||
|
||||
var currentOrderId = mockOrders[0].id;
|
||||
|
||||
/* ==================== 渲染:订单列表 ==================== */
|
||||
function renderOrderList() {
|
||||
var mealFilter = document.getElementById('mealFilter').value;
|
||||
var statusFilter = document.getElementById('statusFilter').value;
|
||||
|
||||
var filtered = mockOrders.filter(function(o) {
|
||||
if (mealFilter !== 'all' && o.mealType !== mealFilter) return false;
|
||||
if (statusFilter === 'pending' && o.printed) return false;
|
||||
if (statusFilter === 'printed' && !o.printed) return false;
|
||||
return true;
|
||||
});
|
||||
|
||||
var listEl = document.getElementById('orderList');
|
||||
if (filtered.length === 0) {
|
||||
listEl.innerHTML = '<div style="text-align:center;padding:24px 8px;color:rgba(255,255,255,0.3);font-size:12px;">无符合条件的订单</div>';
|
||||
return;
|
||||
}
|
||||
|
||||
var html = filtered.map(function(o) {
|
||||
var mealTagClass = 'meal-tag--' + o.mealType;
|
||||
var printedClass = o.printed ? ' printed' : '';
|
||||
var activeClass = o.id === currentOrderId ? ' active' : '';
|
||||
var statusHtml = o.printed
|
||||
? '<span class="order-card__status order-card__status--printed">已打印</span>'
|
||||
: '<span class="order-card__status order-card__status--pending">未打印</span>';
|
||||
return '<div class="order-card' + activeClass + printedClass + '" onclick="selectOrder(\'' + o.id + '\')">'
|
||||
+ statusHtml
|
||||
+ '<div class="order-card__row1">'
|
||||
+ '<span class="order-card__id">' + o.id + '</span>'
|
||||
+ '<span class="meal-tag ' + mealTagClass + '">' + o.mealLabel + '</span>'
|
||||
+ '</div>'
|
||||
+ '<div class="order-card__row2">'
|
||||
+ '<span class="order-card__time">' + o.time + '</span>'
|
||||
+ '<span class="order-card__amount">¥' + o.payable.toFixed(2) + '</span>'
|
||||
+ '</div>'
|
||||
+ '</div>';
|
||||
}).join('');
|
||||
|
||||
listEl.innerHTML = html;
|
||||
}
|
||||
|
||||
/* ==================== 渲染:小票预览 ==================== */
|
||||
function renderReceipt() {
|
||||
var order = mockOrders.filter(function(o) { return o.id === currentOrderId; })[0];
|
||||
if (!order) {
|
||||
document.getElementById('receiptStage').innerHTML = '<div style="color:rgba(255,255,255,0.3);font-size:12px;">请选择左侧订单查看小票</div>';
|
||||
updatePrintBtn();
|
||||
return;
|
||||
}
|
||||
var order = mockOrder;
|
||||
|
||||
/* 按分区分组 */
|
||||
var zoneOrder = ['营养秤', '档口秤'];
|
||||
@@ -898,7 +599,6 @@
|
||||
+ '</div>';
|
||||
|
||||
document.getElementById('receiptStage').innerHTML = html;
|
||||
updatePrintBtn();
|
||||
}
|
||||
|
||||
/* 简化版二维码 SVG (21x21 模块,模拟外观) */
|
||||
@@ -973,37 +673,9 @@
|
||||
return generateQRCodeSVG(matrix);
|
||||
}
|
||||
|
||||
/* 切换订单 */
|
||||
function selectOrder(orderId) {
|
||||
currentOrderId = orderId;
|
||||
renderOrderList();
|
||||
renderReceipt();
|
||||
}
|
||||
|
||||
/* 打印按钮状态切换 */
|
||||
function updatePrintBtn() {
|
||||
var order = mockOrders.filter(function(o) { return o.id === currentOrderId; })[0];
|
||||
var btn = document.getElementById('printBtn');
|
||||
if (order && order.printed) {
|
||||
btn.className = 'btn btn--primary';
|
||||
btn.innerHTML = '🖨️ 重新打印';
|
||||
} else {
|
||||
btn.className = 'btn btn--success';
|
||||
btn.innerHTML = '🖨️ 打印小票';
|
||||
}
|
||||
}
|
||||
|
||||
/* 打印处理 */
|
||||
function handlePrint() {
|
||||
var order = mockOrders.filter(function(o) { return o.id === currentOrderId; })[0];
|
||||
if (!order) {
|
||||
showToast('请先选择订单', 'warn');
|
||||
return;
|
||||
}
|
||||
order.printed = true;
|
||||
renderOrderList();
|
||||
updatePrintBtn();
|
||||
showToast('订单 ' + order.id + ' 小票打印成功', 'success');
|
||||
showToast('订单 ' + mockOrder.id + ' 小票打印成功', 'success');
|
||||
}
|
||||
|
||||
/* Toast */
|
||||
@@ -1019,7 +691,6 @@
|
||||
}
|
||||
|
||||
/* 初始化 */
|
||||
renderOrderList();
|
||||
renderReceipt();
|
||||
</script>
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
<title>结算设备 - 蚁熊智能餐养平台</title>
|
||||
<style>
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
/* 外层视口:全屏深色背景,承载居中 PAD 外壳 */
|
||||
body {
|
||||
font-family: -apple-system, "Microsoft YaHei", "PingFang SC", sans-serif;
|
||||
background: #05080f;
|
||||
@@ -18,7 +17,6 @@
|
||||
justify-content: center;
|
||||
padding: 20px;
|
||||
}
|
||||
/* PAD 设备外壳 */
|
||||
.device-frame {
|
||||
width: 1280px;
|
||||
height: 720px;
|
||||
@@ -46,99 +44,137 @@
|
||||
font-weight: 600;
|
||||
color: rgba(255, 255, 255, 0.85);
|
||||
}
|
||||
/* 主内容区:三菜单网格 */
|
||||
|
||||
/* 主内容:左右两区(用户屏 / 收银员屏) */
|
||||
.main-content {
|
||||
flex: 1;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 28px;
|
||||
padding: 56px 80px;
|
||||
height: calc(100% - 44px);
|
||||
align-content: center;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 20px;
|
||||
padding: 20px 28px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* 屏幕分区 */
|
||||
.screen-section {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
}
|
||||
.screen-section__header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 0 4px 12px;
|
||||
border-bottom: 1px solid rgba(255, 255, 255, 0.08);
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
.screen-section__title {
|
||||
font-size: 14px;
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
font-weight: 600;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
.screen-section__title-bar {
|
||||
width: 4px;
|
||||
height: 14px;
|
||||
border-radius: 2px;
|
||||
}
|
||||
.screen-section--user .screen-section__title-bar { background: #0AC4A8; }
|
||||
.screen-section--cashier .screen-section__title-bar { background: #4a90d9; }
|
||||
.screen-section__sub {
|
||||
font-size: 11px;
|
||||
color: rgba(255, 255, 255, 0.45);
|
||||
}
|
||||
|
||||
.card-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 10px;
|
||||
overflow-y: auto;
|
||||
scrollbar-width: none;
|
||||
padding-right: 4px;
|
||||
}
|
||||
.card-grid::-webkit-scrollbar { display: none; }
|
||||
|
||||
/* 菜单卡片 */
|
||||
.card {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 18px;
|
||||
padding: 36px 24px;
|
||||
gap: 10px;
|
||||
padding: 12px 14px;
|
||||
background: #1a2b4a;
|
||||
border-radius: 16px;
|
||||
border-radius: 10px;
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
border: 1px solid rgba(255, 255, 255, 0.06);
|
||||
text-align: center;
|
||||
position: relative;
|
||||
}
|
||||
.card:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.3);
|
||||
border-color: rgba(74, 144, 217, 0.3);
|
||||
border-color: rgba(74, 144, 217, 0.35);
|
||||
background: rgba(74, 144, 217, 0.08);
|
||||
}
|
||||
.screen-section--user .card:hover {
|
||||
border-color: rgba(10, 196, 168, 0.35);
|
||||
background: rgba(10, 196, 168, 0.08);
|
||||
}
|
||||
/* 禁用卡片(待开发) */
|
||||
.card--disabled {
|
||||
pointer-events: none;
|
||||
background: rgba(26, 43, 74, 0.4);
|
||||
opacity: 0.55;
|
||||
opacity: 0.4;
|
||||
}
|
||||
.card--disabled:hover {
|
||||
transform: none;
|
||||
box-shadow: none;
|
||||
border-color: rgba(255, 255, 255, 0.06);
|
||||
}
|
||||
/* 图标圆底 */
|
||||
.card__icon {
|
||||
font-size: 44px;
|
||||
width: 84px;
|
||||
height: 84px;
|
||||
border-radius: 50%;
|
||||
background: rgba(74, 144, 217, 0.12);
|
||||
font-size: 22px;
|
||||
width: 38px;
|
||||
height: 38px;
|
||||
border-radius: 8px;
|
||||
background: rgba(74, 144, 217, 0.15);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.card--disabled .card__icon {
|
||||
background: rgba(255, 255, 255, 0.04);
|
||||
.screen-section--user .card__icon {
|
||||
background: rgba(10, 196, 168, 0.15);
|
||||
}
|
||||
.card__body { flex: 1; min-width: 0; }
|
||||
.card__title {
|
||||
font-size: 17px;
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
color: #fff;
|
||||
}
|
||||
.card--disabled .card__title {
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
.card__desc {
|
||||
font-size: 12px;
|
||||
font-size: 10px;
|
||||
color: rgba(255, 255, 255, 0.45);
|
||||
line-height: 1.5;
|
||||
line-height: 1.4;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
.card--disabled .card__desc {
|
||||
color: rgba(255, 255, 255, 0.3);
|
||||
}
|
||||
/* 右上角状态标签 */
|
||||
.card__status {
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
right: 10px;
|
||||
font-size: 10px;
|
||||
top: 6px;
|
||||
right: 6px;
|
||||
font-size: 9px;
|
||||
line-height: 1;
|
||||
padding: 4px 8px;
|
||||
border-radius: 9px;
|
||||
padding: 3px 6px;
|
||||
border-radius: 7px;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.3px;
|
||||
}
|
||||
.card__status--done {
|
||||
background: rgba(34, 197, 94, 0.18);
|
||||
background: rgba(34, 197, 94, 0.2);
|
||||
color: #4ade80;
|
||||
border: 1px solid rgba(34, 197, 94, 0.35);
|
||||
border: 1px solid rgba(34, 197, 94, 0.4);
|
||||
}
|
||||
.card__status--pending {
|
||||
background: rgba(234, 88, 12, 0.18);
|
||||
color: #fb923c;
|
||||
border: 1px solid rgba(234, 88, 12, 0.35);
|
||||
.card__status--core {
|
||||
background: rgba(251, 191, 36, 0.2);
|
||||
color: #fbbf24;
|
||||
border: 1px solid rgba(251, 191, 36, 0.4);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
@@ -151,32 +187,140 @@
|
||||
<span class="top-bar__title">结算设备</span>
|
||||
</div>
|
||||
|
||||
<!-- 主内容:三菜单卡片 -->
|
||||
<!-- 主内容:左右两屏 -->
|
||||
<div class="main-content">
|
||||
|
||||
<!-- 1. 员工登录(待开发) -->
|
||||
<a class="card card--disabled" href="javascript:void(0)">
|
||||
<span class="card__status card__status--pending">待开发</span>
|
||||
<div class="card__icon">🔐</div>
|
||||
<div class="card__title">员工登录</div>
|
||||
<div class="card__desc">人脸识别 / 账号密码登录</div>
|
||||
</a>
|
||||
<!-- 左区:用户屏(副屏) -->
|
||||
<div class="screen-section screen-section--user">
|
||||
<div class="screen-section__header">
|
||||
<div class="screen-section__title">
|
||||
<span class="screen-section__title-bar"></span>
|
||||
💻 用户屏(副屏)
|
||||
</div>
|
||||
<span class="screen-section__sub">面向就餐人员展示</span>
|
||||
</div>
|
||||
|
||||
<!-- 2. 结算台(待开发) -->
|
||||
<a class="card card--disabled" href="javascript:void(0)">
|
||||
<span class="card__status card__status--pending">待开发</span>
|
||||
<div class="card__icon">💳</div>
|
||||
<div class="card__title">结算台</div>
|
||||
<div class="card__desc">智能结算与餐卡支付</div>
|
||||
</a>
|
||||
<div class="card-grid">
|
||||
<a class="card" href="user-01-idle.html">
|
||||
<span class="card__status card__status--done">U01</span>
|
||||
<div class="card__icon">👋</div>
|
||||
<div class="card__body">
|
||||
<div class="card__title">待机欢迎</div>
|
||||
<div class="card__desc">欢迎语 + 时钟 + 营养宣传</div>
|
||||
</div>
|
||||
</a>
|
||||
<a class="card" href="user-02-checkout-sync.html">
|
||||
<span class="card__status card__status--done">U02</span>
|
||||
<div class="card__icon">🛍️</div>
|
||||
<div class="card__body">
|
||||
<div class="card__title">取餐明细展示</div>
|
||||
<div class="card__desc">同步商品列表 + 营养摘要</div>
|
||||
</div>
|
||||
</a>
|
||||
<a class="card" href="user-03-paying.html">
|
||||
<span class="card__status card__status--done">U03</span>
|
||||
<div class="card__icon">📱</div>
|
||||
<div class="card__body">
|
||||
<div class="card__title">支付引导</div>
|
||||
<div class="card__desc">4 种支付方式引导切换</div>
|
||||
</div>
|
||||
</a>
|
||||
<a class="card" href="user-04-success.html">
|
||||
<span class="card__status card__status--done">U04</span>
|
||||
<div class="card__icon">✅</div>
|
||||
<div class="card__body">
|
||||
<div class="card__title">支付成功</div>
|
||||
<div class="card__desc">大金额 + 营养评分 + 引导</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 3. 打印小票(已设计) -->
|
||||
<a class="card" href="02-print-receipt.html">
|
||||
<span class="card__status card__status--done">已设计</span>
|
||||
<div class="card__icon">🖨️</div>
|
||||
<div class="card__title">打印小票</div>
|
||||
<div class="card__desc">餐后结算小票预览与打印</div>
|
||||
</a>
|
||||
<!-- 右区:收银员屏(主屏) -->
|
||||
<div class="screen-section screen-section--cashier">
|
||||
<div class="screen-section__header">
|
||||
<div class="screen-section__title">
|
||||
<span class="screen-section__title-bar"></span>
|
||||
🧑‍💻 收银员屏(主屏)
|
||||
</div>
|
||||
<span class="screen-section__sub">收银员全流程操作</span>
|
||||
</div>
|
||||
|
||||
<div class="card-grid">
|
||||
<a class="card" href="01-login.html">
|
||||
<span class="card__status card__status--done">01</span>
|
||||
<div class="card__icon">🔐</div>
|
||||
<div class="card__body">
|
||||
<div class="card__title">收银员登录</div>
|
||||
<div class="card__desc">人脸识别登录 + 班次信息</div>
|
||||
</div>
|
||||
</a>
|
||||
<a class="card" href="02-standby.html">
|
||||
<span class="card__status card__status--done">02</span>
|
||||
<div class="card__icon">📋</div>
|
||||
<div class="card__body">
|
||||
<div class="card__title">待机页</div>
|
||||
<div class="card__desc">时钟 + 数据预览 + 入口</div>
|
||||
</div>
|
||||
</a>
|
||||
<a class="card" href="03-checkout.html">
|
||||
<span class="card__status card__status--core">03 核心</span>
|
||||
<div class="card__icon">💳</div>
|
||||
<div class="card__body">
|
||||
<div class="card__title">结算页</div>
|
||||
<div class="card__desc">4 种支付 + 商品 + 补齐</div>
|
||||
</div>
|
||||
</a>
|
||||
<a class="card" href="04-pay-success.html">
|
||||
<span class="card__status card__status--done">04</span>
|
||||
<div class="card__icon">🎉</div>
|
||||
<div class="card__body">
|
||||
<div class="card__title">支付成功</div>
|
||||
<div class="card__desc">打印 + 新单 + 详情入口</div>
|
||||
</div>
|
||||
</a>
|
||||
<a class="card" href="05-orders.html">
|
||||
<span class="card__status card__status--done">05</span>
|
||||
<div class="card__icon">📚</div>
|
||||
<div class="card__body">
|
||||
<div class="card__title">订单列表</div>
|
||||
<div class="card__desc">今日订单 + 筛选 + 退款</div>
|
||||
</div>
|
||||
</a>
|
||||
<a class="card" href="06-order-detail.html">
|
||||
<span class="card__status card__status--done">06</span>
|
||||
<div class="card__icon">📄</div>
|
||||
<div class="card__body">
|
||||
<div class="card__title">订单详情</div>
|
||||
<div class="card__desc">明细 + 退款流程 + 重打</div>
|
||||
</div>
|
||||
</a>
|
||||
<a class="card" href="07-statistics.html">
|
||||
<span class="card__status card__status--done">07</span>
|
||||
<div class="card__icon">📊</div>
|
||||
<div class="card__body">
|
||||
<div class="card__title">运营数据统计</div>
|
||||
<div class="card__desc">营收 + 餐次 + Top + 时段</div>
|
||||
</div>
|
||||
</a>
|
||||
<a class="card" href="08-reconcile.html">
|
||||
<span class="card__status card__status--done">08</span>
|
||||
<div class="card__icon">✏️</div>
|
||||
<div class="card__body">
|
||||
<div class="card__title">补齐明细</div>
|
||||
<div class="card__desc">漏记添加 / 多记删除</div>
|
||||
</div>
|
||||
</a>
|
||||
<a class="card" href="09-print-receipt.html">
|
||||
<span class="card__status card__status--done">09</span>
|
||||
<div class="card__icon">🖨️</div>
|
||||
<div class="card__body">
|
||||
<div class="card__title">打印小票</div>
|
||||
<div class="card__desc">餐后小票预览与打印</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
@@ -0,0 +1,339 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=1280, initial-scale=1.0">
|
||||
<title>用户屏 - 待机欢迎 | 蚁熊智能餐养平台</title>
|
||||
<style>
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
body {
|
||||
font-family: -apple-system, "Microsoft YaHei", "PingFang SC", sans-serif;
|
||||
background: #05080f;
|
||||
color: #fff;
|
||||
min-height: 100vh;
|
||||
min-width: 1280px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 20px;
|
||||
}
|
||||
/* 用户屏外壳:竖屏式(实际副屏为竖式) */
|
||||
.device-frame {
|
||||
width: 1280px;
|
||||
height: 720px;
|
||||
background: linear-gradient(180deg, #0e1326 0%, #1a2b4a 50%, #0e1326 100%);
|
||||
border-radius: 24px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 24px 64px rgba(0, 0, 0, 0.6), 0 0 0 1px rgba(255, 255, 255, 0.04);
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
/* 背景装饰:营养元素 */
|
||||
.bg-deco {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
pointer-events: none;
|
||||
opacity: 0.06;
|
||||
background-image:
|
||||
radial-gradient(circle at 20% 20%, #4a90d9 0%, transparent 30%),
|
||||
radial-gradient(circle at 80% 80%, #0AC4A8 0%, transparent 30%),
|
||||
radial-gradient(circle at 50% 50%, #fbbf24 0%, transparent 20%);
|
||||
}
|
||||
.bg-deco__icon {
|
||||
position: absolute;
|
||||
font-size: 50px;
|
||||
opacity: 0.1;
|
||||
}
|
||||
.bg-deco__icon--1 { top: 10%; left: 5%; }
|
||||
.bg-deco__icon--2 { top: 15%; right: 8%; }
|
||||
.bg-deco__icon--3 { bottom: 20%; left: 8%; }
|
||||
.bg-deco__icon--4 { bottom: 15%; right: 6%; }
|
||||
|
||||
/* 顶部:食堂信息 */
|
||||
.header {
|
||||
padding: 30px 60px 20px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
z-index: 2;
|
||||
}
|
||||
.canteen-info { display: flex; align-items: center; gap: 14px; }
|
||||
.canteen-logo {
|
||||
width: 56px;
|
||||
height: 56px;
|
||||
border-radius: 14px;
|
||||
background: linear-gradient(135deg, #4a90d9, #0AC4A8);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 28px;
|
||||
box-shadow: 0 4px 16px rgba(74, 144, 217, 0.3);
|
||||
}
|
||||
.canteen-text { display: flex; flex-direction: column; gap: 2px; }
|
||||
.canteen-name {
|
||||
font-size: 26px;
|
||||
font-weight: 700;
|
||||
color: #fff;
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
.canteen-sub {
|
||||
font-size: 12px;
|
||||
color: rgba(255, 255, 255, 0.5);
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
.weather {
|
||||
text-align: right;
|
||||
font-size: 12px;
|
||||
color: rgba(255, 255, 255, 0.55);
|
||||
line-height: 1.6;
|
||||
}
|
||||
.weather__icon { font-size: 22px; }
|
||||
.weather__temp { color: #fff; font-size: 16px; font-weight: 600; }
|
||||
|
||||
/* 中央:大时钟 */
|
||||
.clock-area {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 14px;
|
||||
z-index: 2;
|
||||
}
|
||||
.big-time {
|
||||
font-size: 144px;
|
||||
font-weight: 200;
|
||||
color: #fff;
|
||||
font-family: Menlo, Consolas, "Courier New", monospace;
|
||||
line-height: 1;
|
||||
letter-spacing: 6px;
|
||||
text-shadow: 0 4px 30px rgba(74, 144, 217, 0.4);
|
||||
}
|
||||
.big-date {
|
||||
font-size: 18px;
|
||||
color: rgba(255, 255, 255, 0.65);
|
||||
letter-spacing: 1px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
}
|
||||
.meal-tag-large {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
padding: 6px 16px;
|
||||
border-radius: 18px;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
}
|
||||
.meal-tag-large--lunch {
|
||||
background: rgba(37, 99, 235, 0.25);
|
||||
color: #60a5fa;
|
||||
border: 1px solid rgba(37, 99, 235, 0.5);
|
||||
}
|
||||
|
||||
/* 欢迎横幅 */
|
||||
.welcome-banner {
|
||||
padding: 0 60px;
|
||||
text-align: center;
|
||||
z-index: 2;
|
||||
}
|
||||
.welcome-text {
|
||||
font-size: 32px;
|
||||
font-weight: 700;
|
||||
background: linear-gradient(90deg, #4a90d9, #0AC4A8, #4ade80);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
background-clip: text;
|
||||
letter-spacing: 4px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.welcome-sub {
|
||||
font-size: 14px;
|
||||
color: rgba(255, 255, 255, 0.55);
|
||||
letter-spacing: 2px;
|
||||
}
|
||||
|
||||
/* 营养宣传区 */
|
||||
.nutrition-promo {
|
||||
padding: 24px 60px 30px;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
gap: 16px;
|
||||
z-index: 2;
|
||||
}
|
||||
.promo-card {
|
||||
padding: 18px 16px;
|
||||
background: rgba(26, 43, 74, 0.5);
|
||||
border: 1px solid rgba(255, 255, 255, 0.08);
|
||||
border-radius: 14px;
|
||||
backdrop-filter: blur(10px);
|
||||
text-align: center;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
.promo-card:hover {
|
||||
transform: translateY(-3px);
|
||||
border-color: rgba(74, 144, 217, 0.4);
|
||||
}
|
||||
.promo-card__icon {
|
||||
font-size: 36px;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
.promo-card__value {
|
||||
font-size: 22px;
|
||||
font-weight: 700;
|
||||
color: #fff;
|
||||
font-family: Menlo, Consolas, monospace;
|
||||
}
|
||||
.promo-card__unit {
|
||||
font-size: 12px;
|
||||
color: rgba(255, 255, 255, 0.5);
|
||||
font-weight: 400;
|
||||
}
|
||||
.promo-card__label {
|
||||
font-size: 12px;
|
||||
color: rgba(255, 255, 255, 0.65);
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
/* 底部:滚动提示 */
|
||||
.footer-tip {
|
||||
padding: 12px 60px 18px;
|
||||
text-align: center;
|
||||
z-index: 2;
|
||||
font-size: 13px;
|
||||
color: rgba(255, 255, 255, 0.55);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 8px;
|
||||
border-top: 1px solid rgba(255, 255, 255, 0.06);
|
||||
}
|
||||
.footer-tip__dot {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 50%;
|
||||
background: #52c41a;
|
||||
box-shadow: 0 0 8px #52c41a;
|
||||
animation: blink 1.5s infinite;
|
||||
}
|
||||
@keyframes blink {
|
||||
0%, 100% { opacity: 1; }
|
||||
50% { opacity: 0.3; }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="device-frame">
|
||||
|
||||
<div class="bg-deco">
|
||||
<div class="bg-deco__icon bg-deco__icon--1">🍎</div>
|
||||
<div class="bg-deco__icon bg-deco__icon--2">🥗</div>
|
||||
<div class="bg-deco__icon bg-deco__icon--3">🍆</div>
|
||||
<div class="bg-deco__icon bg-deco__icon--4">🥛</div>
|
||||
</div>
|
||||
|
||||
<!-- 顶部:食堂信息 -->
|
||||
<div class="header">
|
||||
<div class="canteen-info">
|
||||
<div class="canteen-logo">🍽</div>
|
||||
<div class="canteen-text">
|
||||
<div class="canteen-name">数味餐厅</div>
|
||||
<div class="canteen-sub">SHUWEI CANTEEN · 智慧营养 · 健康生活</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="weather">
|
||||
<div><span class="weather__icon">☀️</span> 西安 晴</div>
|
||||
<div class="weather__temp">28°C</div>
|
||||
<div style="font-size:11px;color:rgba(255,255,255,0.4);">空气优 · 湿度 45%</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 中央:大时钟 -->
|
||||
<div class="clock-area">
|
||||
<div class="big-time" id="bigTime">12:30:45</div>
|
||||
<div class="big-date" id="bigDate">
|
||||
2026 年 08 月 06 日 · 周四
|
||||
<span class="meal-tag-large meal-tag-large--lunch" id="mealTag">🥪 午餐时段</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 欢迎横幅 -->
|
||||
<div class="welcome-banner">
|
||||
<div class="welcome-text">合理膳食 · 均衡营养</div>
|
||||
</div>
|
||||
|
||||
<!-- 营养宣传卡片 -->
|
||||
<div class="nutrition-promo">
|
||||
<div class="promo-card">
|
||||
<div class="promo-card__icon">🍎</div>
|
||||
<div class="promo-card__value">100<span class="promo-card__unit">+</span></div>
|
||||
<div class="promo-card__label">菜品任选</div>
|
||||
</div>
|
||||
<div class="promo-card">
|
||||
<div class="promo-card__icon">🌱</div>
|
||||
<div class="promo-card__value">5<span class="promo-card__unit">大</span></div>
|
||||
<div class="promo-card__label">营养素分析</div>
|
||||
</div>
|
||||
<div class="promo-card">
|
||||
<div class="promo-card__icon">📱</div>
|
||||
<div class="promo-card__value">4<span class="promo-card__unit">种</span></div>
|
||||
<div class="promo-card__label">便捷支付</div>
|
||||
</div>
|
||||
<div class="promo-card">
|
||||
<div class="promo-card__icon">📊</div>
|
||||
<div class="promo-card__value">7×24<span class="promo-card__unit"></span></div>
|
||||
<div class="promo-card__label">营养监测</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 底部提示 -->
|
||||
<div class="footer-tip">
|
||||
<span class="footer-tip__dot"></span>
|
||||
<span>请从左侧取餐区取餐后,前往结算台完成支付</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function updateClock() {
|
||||
var now = new Date();
|
||||
var hh = String(now.getHours()).padStart(2, '0');
|
||||
var mm = String(now.getMinutes()).padStart(2, '0');
|
||||
var ss = String(now.getSeconds()).padStart(2, '0');
|
||||
document.getElementById('bigTime').textContent = hh + ':' + mm + ':' + ss;
|
||||
|
||||
var year = now.getFullYear();
|
||||
var month = String(now.getMonth() + 1).padStart(2, '0');
|
||||
var date = String(now.getDate()).padStart(2, '0');
|
||||
var weekDay = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'][now.getDay()];
|
||||
document.getElementById('bigDate').firstChild.textContent = ' ' + year + ' 年 ' + month + ' 月 ' + date + ' 日 · ' + weekDay + ' ';
|
||||
|
||||
/* 自动判断餐次 */
|
||||
var hour = now.getHours();
|
||||
var mealTag = document.getElementById('mealTag');
|
||||
if (hour >= 6 && hour < 10) {
|
||||
mealTag.style.background = 'rgba(250,140,22,0.25)';
|
||||
mealTag.style.color = '#fb923c';
|
||||
mealTag.style.borderColor = 'rgba(250,140,22,0.5)';
|
||||
mealTag.innerHTML = '🌅 早餐时段';
|
||||
} else if (hour >= 10 && hour < 14) {
|
||||
mealTag.innerHTML = '🥪 午餐时段';
|
||||
} else if (hour >= 16 && hour < 21) {
|
||||
mealTag.style.background = 'rgba(34,197,94,0.25)';
|
||||
mealTag.style.color = '#4ade80';
|
||||
mealTag.style.borderColor = 'rgba(34,197,94,0.5)';
|
||||
mealTag.innerHTML = '🌙 晚餐时段';
|
||||
} else {
|
||||
mealTag.innerHTML = '🌟 欢迎光临';
|
||||
}
|
||||
}
|
||||
updateClock();
|
||||
setInterval(updateClock, 1000);
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,716 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=1280, initial-scale=1.0">
|
||||
<title>用户屏 - 取餐明细 | 蚁熊智能餐养平台</title>
|
||||
<style>
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
body {
|
||||
font-family: -apple-system, "Microsoft YaHei", "PingFang SC", sans-serif;
|
||||
background: #05080f;
|
||||
color: #fff;
|
||||
min-height: 100vh;
|
||||
min-width: 1280px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 20px;
|
||||
}
|
||||
.device-frame {
|
||||
width: 1280px;
|
||||
height: 720px;
|
||||
background: linear-gradient(180deg, #0e1326 0%, #1a2b4a 50%, #0e1326 100%);
|
||||
border-radius: 24px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 24px 64px rgba(0, 0, 0, 0.6), 0 0 0 1px rgba(255, 255, 255, 0.04);
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
/* 顶部标题区 */
|
||||
.header {
|
||||
padding: 20px 36px;
|
||||
background: rgba(26, 43, 74, 0.5);
|
||||
border-bottom: 1px solid rgba(255, 255, 255, 0.06);
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.header__title {
|
||||
font-size: 22px;
|
||||
font-weight: 700;
|
||||
color: #fff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
}
|
||||
.header__count {
|
||||
padding: 3px 12px;
|
||||
background: rgba(74, 144, 217, 0.2);
|
||||
border: 1px solid rgba(74, 144, 217, 0.4);
|
||||
border-radius: 14px;
|
||||
font-size: 13px;
|
||||
color: #60a5fa;
|
||||
}
|
||||
.header__time {
|
||||
font-size: 13px;
|
||||
color: rgba(255, 255, 255, 0.55);
|
||||
font-family: Menlo, Consolas, monospace;
|
||||
}
|
||||
|
||||
/* 主体:左右两列 */
|
||||
.body {
|
||||
flex: 1;
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 360px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* 左:商品列表 */
|
||||
.items-area {
|
||||
padding: 14px 28px 18px;
|
||||
overflow-y: auto;
|
||||
scrollbar-width: none;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.items-area::-webkit-scrollbar { display: none; }
|
||||
|
||||
.zone-header {
|
||||
font-size: 13px;
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.5px;
|
||||
padding: 6px 0 8px;
|
||||
border-bottom: 1px dashed rgba(255, 255, 255, 0.1);
|
||||
margin-bottom: 6px;
|
||||
margin-top: 4px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
.zone-header__count {
|
||||
padding: 1px 8px;
|
||||
background: rgba(74, 144, 217, 0.18);
|
||||
border-radius: 10px;
|
||||
font-size: 11px;
|
||||
color: #60a5fa;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.item-card {
|
||||
display: grid;
|
||||
grid-template-columns: 24px auto 1fr auto;
|
||||
gap: 10px;
|
||||
padding: 8px 14px;
|
||||
background: rgba(26, 43, 74, 0.35);
|
||||
border: 1px solid rgba(255, 255, 255, 0.04);
|
||||
border-radius: 8px;
|
||||
margin-bottom: 4px;
|
||||
align-items: center;
|
||||
animation: slideIn 0.4s ease;
|
||||
}
|
||||
@keyframes slideIn {
|
||||
from { opacity: 0; transform: translateX(-20px); }
|
||||
to { opacity: 1; transform: translateX(0); }
|
||||
}
|
||||
.item-card__seq {
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
border-radius: 50%;
|
||||
background: rgba(74, 144, 217, 0.18);
|
||||
border: 1px solid rgba(74, 144, 217, 0.35);
|
||||
color: #60a5fa;
|
||||
font-size: 11px;
|
||||
font-weight: 700;
|
||||
font-family: Menlo, Consolas, monospace;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.item-card__info {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
gap: 8px;
|
||||
min-width: 0;
|
||||
}
|
||||
.item-card__name {
|
||||
font-size: 15px;
|
||||
color: #fff;
|
||||
font-weight: 600;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
.item-card__unit-price {
|
||||
font-size: 12px;
|
||||
color: rgba(255, 255, 255, 0.55);
|
||||
font-family: Menlo, Consolas, monospace;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.item-card__weight {
|
||||
font-size: 12px;
|
||||
color: #0AC4A8;
|
||||
font-family: Menlo, Consolas, monospace;
|
||||
padding: 2px 10px;
|
||||
background: rgba(10, 196, 168, 0.12);
|
||||
border-radius: 10px;
|
||||
white-space: nowrap;
|
||||
text-align: center;
|
||||
min-width: 76px;
|
||||
justify-self: center;
|
||||
}
|
||||
.item-card__price {
|
||||
font-size: 16px;
|
||||
color: #0AC4A8;
|
||||
font-weight: 700;
|
||||
font-family: Menlo, Consolas, monospace;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* 列表底部统一小计条 */
|
||||
.subtotal-bar {
|
||||
margin-top: 10px;
|
||||
padding: 12px 16px;
|
||||
background: linear-gradient(90deg, rgba(10, 196, 168, 0.12), rgba(74, 144, 217, 0.08));
|
||||
border: 1px solid rgba(10, 196, 168, 0.3);
|
||||
border-radius: 10px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
/* 表头 */
|
||||
.table-head {
|
||||
display: grid;
|
||||
grid-template-columns: 24px auto 1fr auto;
|
||||
gap: 10px;
|
||||
padding: 6px 14px;
|
||||
font-size: 11px;
|
||||
color: rgba(255, 255, 255, 0.4);
|
||||
letter-spacing: 1px;
|
||||
font-weight: 500;
|
||||
border-bottom: 1px solid rgba(255, 255, 255, 0.08);
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
.table-head__name { text-align: left; }
|
||||
.table-head__weight { text-align: center; justify-self: center; }
|
||||
.table-head__price { text-align: right; }
|
||||
.subtotal-bar__count {
|
||||
font-size: 13px;
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
}
|
||||
.subtotal-bar__count strong {
|
||||
color: #fff;
|
||||
font-size: 15px;
|
||||
font-family: Menlo, Consolas, monospace;
|
||||
margin: 0 2px;
|
||||
}
|
||||
.subtotal-bar__amount {
|
||||
font-size: 22px;
|
||||
font-weight: 700;
|
||||
color: #0AC4A8;
|
||||
font-family: Menlo, Consolas, monospace;
|
||||
}
|
||||
|
||||
/* 右:用户 + 金额 + 营养 */
|
||||
.side-area {
|
||||
padding: 16px 20px;
|
||||
background: rgba(26, 43, 74, 0.3);
|
||||
border-left: 1px solid rgba(255, 255, 255, 0.06);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 14px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* 用户信息卡 */
|
||||
.user-card {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
padding: 12px 14px;
|
||||
background: linear-gradient(90deg, rgba(74, 144, 217, 0.15), rgba(10, 196, 168, 0.06));
|
||||
border: 1px solid rgba(74, 144, 217, 0.3);
|
||||
border-radius: 12px;
|
||||
}
|
||||
.user-card__avatar {
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
border-radius: 50%;
|
||||
background: linear-gradient(135deg, #4a90d9, #0AC4A8);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 20px;
|
||||
flex-shrink: 0;
|
||||
box-shadow: 0 4px 12px rgba(74, 144, 217, 0.3);
|
||||
}
|
||||
.user-card__main {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 3px;
|
||||
}
|
||||
.user-card__name-row {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
gap: 8px;
|
||||
}
|
||||
.user-card__name {
|
||||
font-size: 16px;
|
||||
color: #fff;
|
||||
font-weight: 700;
|
||||
}
|
||||
.user-card__empno {
|
||||
font-size: 11px;
|
||||
color: rgba(255, 255, 255, 0.5);
|
||||
font-family: Menlo, Consolas, monospace;
|
||||
}
|
||||
.user-card__sub {
|
||||
font-size: 11px;
|
||||
color: rgba(255, 255, 255, 0.55);
|
||||
}
|
||||
.user-card__level {
|
||||
padding: 4px 10px;
|
||||
background: linear-gradient(135deg, rgba(251, 191, 36, 0.25), rgba(251, 146, 60, 0.18));
|
||||
border: 1px solid rgba(251, 191, 36, 0.5);
|
||||
border-radius: 12px;
|
||||
font-size: 11px;
|
||||
color: #fbbf24;
|
||||
font-weight: 700;
|
||||
text-align: center;
|
||||
line-height: 1.3;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.user-card__level small {
|
||||
display: block;
|
||||
font-size: 9px;
|
||||
color: rgba(251, 191, 36, 0.85);
|
||||
font-weight: 500;
|
||||
margin-top: 1px;
|
||||
}
|
||||
.section-label {
|
||||
font-size: 12px;
|
||||
color: rgba(255, 255, 255, 0.5);
|
||||
letter-spacing: 1px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
}
|
||||
.section-label::before {
|
||||
content: "";
|
||||
width: 3px;
|
||||
height: 11px;
|
||||
background: #4a90d9;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
/* 营养达标卡片 */
|
||||
.nutrition-card {
|
||||
flex: 1;
|
||||
background: linear-gradient(135deg, rgba(10, 196, 168, 0.12), rgba(74, 144, 217, 0.06));
|
||||
border: 1px solid rgba(10, 196, 168, 0.25);
|
||||
border-radius: 12px;
|
||||
padding: 12px 14px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.nutrition-head {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.nutrition-head__title {
|
||||
font-size: 13px;
|
||||
color: #fff;
|
||||
font-weight: 600;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 2px;
|
||||
}
|
||||
.nutrition-head__title small {
|
||||
font-size: 10px;
|
||||
color: rgba(255, 255, 255, 0.5);
|
||||
font-weight: 400;
|
||||
}
|
||||
.nutrition-score {
|
||||
padding: 3px 10px;
|
||||
background: rgba(251, 191, 36, 0.2);
|
||||
border: 1px solid rgba(251, 191, 36, 0.4);
|
||||
border-radius: 12px;
|
||||
font-size: 12px;
|
||||
color: #fbbf24;
|
||||
font-weight: 700;
|
||||
text-align: right;
|
||||
}
|
||||
.nutrition-score small {
|
||||
display: block;
|
||||
font-size: 10px;
|
||||
color: rgba(251, 191, 36, 0.85);
|
||||
font-weight: 500;
|
||||
margin-top: 1px;
|
||||
}
|
||||
|
||||
/* 热量环形 + 三大营养条 */
|
||||
.nutrition-main {
|
||||
display: grid;
|
||||
grid-template-columns: 88px 1fr;
|
||||
gap: 12px;
|
||||
align-items: center;
|
||||
}
|
||||
.calorie-ring {
|
||||
position: relative;
|
||||
width: 88px;
|
||||
height: 88px;
|
||||
}
|
||||
.calorie-ring__svg {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
transform: rotate(-90deg);
|
||||
}
|
||||
.calorie-ring__center {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
text-align: center;
|
||||
}
|
||||
.calorie-ring__value {
|
||||
font-size: 18px;
|
||||
font-weight: 800;
|
||||
color: #fff;
|
||||
font-family: Menlo, Consolas, monospace;
|
||||
line-height: 1;
|
||||
}
|
||||
.calorie-ring__unit {
|
||||
font-size: 9px;
|
||||
color: rgba(255, 255, 255, 0.5);
|
||||
margin-top: 1px;
|
||||
}
|
||||
.calorie-ring__hint {
|
||||
font-size: 9px;
|
||||
color: #fbbf24;
|
||||
margin-top: 3px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* 三大营养素横条 */
|
||||
.macro-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 7px;
|
||||
}
|
||||
.macro-row__head {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: baseline;
|
||||
font-size: 11px;
|
||||
margin-bottom: 3px;
|
||||
}
|
||||
.macro-row__label {
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
}
|
||||
.macro-row__dot {
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
.macro-row__value {
|
||||
color: #fff;
|
||||
font-family: Menlo, Consolas, monospace;
|
||||
font-weight: 600;
|
||||
}
|
||||
.macro-row__value small {
|
||||
color: rgba(255, 255, 255, 0.4);
|
||||
font-weight: 400;
|
||||
font-size: 10px;
|
||||
margin-left: 2px;
|
||||
}
|
||||
.macro-bar {
|
||||
position: relative;
|
||||
height: 6px;
|
||||
background: rgba(0, 0, 0, 0.3);
|
||||
border-radius: 3px;
|
||||
}
|
||||
.macro-bar__target {
|
||||
position: absolute;
|
||||
top: -2px;
|
||||
bottom: -2px;
|
||||
width: 2px;
|
||||
background: rgba(255, 255, 255, 0.6);
|
||||
border-radius: 1px;
|
||||
}
|
||||
.macro-bar__fill {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
/* 营养结论 */
|
||||
.nutrition-conclusion {
|
||||
margin-top: 10px;
|
||||
padding: 7px 10px;
|
||||
background: rgba(251, 191, 36, 0.1);
|
||||
border-left: 2px solid #fbbf24;
|
||||
border-radius: 4px;
|
||||
font-size: 11px;
|
||||
color: rgba(255, 255, 255, 0.78);
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
/* 应付金额(突出展示) */
|
||||
.amount-card {
|
||||
background: linear-gradient(135deg, rgba(10, 196, 168, 0.18), rgba(0, 0, 0, 0.35));
|
||||
border: 1.5px solid rgba(10, 196, 168, 0.55);
|
||||
border-radius: 14px;
|
||||
padding: 14px 16px;
|
||||
text-align: center;
|
||||
box-shadow: 0 6px 20px rgba(10, 196, 168, 0.18);
|
||||
}
|
||||
.amount-card__label {
|
||||
font-size: 14px;
|
||||
color: rgba(255, 255, 255, 0.85);
|
||||
font-weight: 600;
|
||||
letter-spacing: 1px;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
.amount-card__value {
|
||||
font-size: 52px;
|
||||
font-weight: 800;
|
||||
color: #0AC4A8;
|
||||
font-family: Menlo, Consolas, monospace;
|
||||
line-height: 1.05;
|
||||
text-shadow: 0 0 24px rgba(10, 196, 168, 0.4);
|
||||
}
|
||||
.amount-card__sub {
|
||||
font-size: 12px;
|
||||
color: rgba(255, 255, 255, 0.55);
|
||||
margin-top: 4px;
|
||||
}
|
||||
.amount-card__sub strong { color: #4ade80; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="device-frame">
|
||||
|
||||
<!-- 顶部标题 -->
|
||||
<div class="header">
|
||||
<div class="header__title">
|
||||
🛍️ 您的取餐明细
|
||||
<span class="header__count">共 5 件</span>
|
||||
</div>
|
||||
<div class="header__time" id="nowTime">2026-08-06 12:30:45</div>
|
||||
</div>
|
||||
|
||||
<!-- 主体 -->
|
||||
<div class="body">
|
||||
|
||||
<!-- 左:商品列表 -->
|
||||
<div class="items-area">
|
||||
<!-- 表头 -->
|
||||
<div class="table-head">
|
||||
<span>#</span>
|
||||
<span class="table-head__name">餐品名称 / 单价</span>
|
||||
<span class="table-head__weight">取餐量</span>
|
||||
<span class="table-head__price">金额</span>
|
||||
</div>
|
||||
|
||||
<!-- 餐线 -->
|
||||
<div class="zone-header">
|
||||
<span>🥜 餐线菜品</span>
|
||||
<span class="zone-header__count">2 件</span>
|
||||
</div>
|
||||
<div class="item-card">
|
||||
<div class="item-card__seq">1</div>
|
||||
<div class="item-card__info">
|
||||
<span class="item-card__name">清炒时蔬</span>
|
||||
<span class="item-card__unit-price">¥4.00/100g</span>
|
||||
</div>
|
||||
<span class="item-card__weight">取 150g</span>
|
||||
<div class="item-card__price">¥6.00</div>
|
||||
</div>
|
||||
<div class="item-card">
|
||||
<div class="item-card__seq">2</div>
|
||||
<div class="item-card__info">
|
||||
<span class="item-card__name">米饭</span>
|
||||
<span class="item-card__unit-price">¥1.60/100g</span>
|
||||
</div>
|
||||
<span class="item-card__weight">取 250g</span>
|
||||
<div class="item-card__price">¥4.00</div>
|
||||
</div>
|
||||
|
||||
<!-- 档口 -->
|
||||
<div class="zone-header">
|
||||
<span>⚖️ 档口菜品</span>
|
||||
<span class="zone-header__count">3 件</span>
|
||||
</div>
|
||||
<div class="item-card">
|
||||
<div class="item-card__seq">3</div>
|
||||
<div class="item-card__info">
|
||||
<span class="item-card__name">红烧肉</span>
|
||||
<span class="item-card__unit-price">¥12.00/100g</span>
|
||||
</div>
|
||||
<span class="item-card__weight">取 180g</span>
|
||||
<div class="item-card__price">¥21.60</div>
|
||||
</div>
|
||||
<div class="item-card">
|
||||
<div class="item-card__seq">4</div>
|
||||
<div class="item-card__info">
|
||||
<span class="item-card__name">鱼香肉丝</span>
|
||||
<span class="item-card__unit-price">¥7.50/100g</span>
|
||||
</div>
|
||||
<span class="item-card__weight">取 160g</span>
|
||||
<div class="item-card__price">¥12.00</div>
|
||||
</div>
|
||||
<div class="item-card">
|
||||
<div class="item-card__seq">5</div>
|
||||
<div class="item-card__info">
|
||||
<span class="item-card__name">冬瓜排骨汤</span>
|
||||
<span class="item-card__unit-price">¥1.00/100g</span>
|
||||
</div>
|
||||
<span class="item-card__weight">取 300g</span>
|
||||
<div class="item-card__price">¥3.00</div>
|
||||
</div>
|
||||
|
||||
<!-- 统一小计条 -->
|
||||
<div class="subtotal-bar">
|
||||
<div class="subtotal-bar__count">餐品种类 <strong>5</strong> 项 · 总重量 <strong>1040</strong>g · 餐线 <strong>2</strong> · 档口 <strong>3</strong></div>
|
||||
<div class="subtotal-bar__amount">¥46.60</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 右:用户信息 + 应付金额 + 营养达标 -->
|
||||
<div class="side-area">
|
||||
<!-- 用户信息卡 -->
|
||||
<div class="user-card">
|
||||
<div class="user-card__avatar">👤‍🌾</div>
|
||||
<div class="user-card__main">
|
||||
<div class="user-card__name-row">
|
||||
<span class="user-card__name">张*明</span>
|
||||
<span class="user-card__empno">EMP002346</span>
|
||||
</div>
|
||||
<span class="user-card__sub">研发中心 · 二荤餐线</span>
|
||||
</div>
|
||||
<div class="user-card__level">
|
||||
金牌会员
|
||||
<small>LV5</small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 应付金额(突出) -->
|
||||
<div class="amount-card">
|
||||
<div class="amount-card__label">应付金额</div>
|
||||
<div class="amount-card__value">¥41.60</div>
|
||||
<div class="amount-card__sub">原价 <strong>¥46.60</strong> · 优惠金额 ¥5.00</div>
|
||||
</div>
|
||||
|
||||
<!-- 营养达标分析 -->
|
||||
<div class="nutrition-card">
|
||||
<div class="nutrition-head">
|
||||
<span class="nutrition-head__title">
|
||||
🥗 本餐营养摄入
|
||||
<small>您的午餐目标 · 热量 950 kcal</small>
|
||||
</span>
|
||||
<span class="nutrition-score">
|
||||
⭐ 88 分
|
||||
<small>搭配均衡</small>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="nutrition-main">
|
||||
<!-- 热量环形(76%) -->
|
||||
<div class="calorie-ring">
|
||||
<svg class="calorie-ring__svg" viewBox="0 0 100 100">
|
||||
<circle cx="50" cy="50" r="42" fill="none" stroke="rgba(255,255,255,0.08)" stroke-width="8"/>
|
||||
<circle cx="50" cy="50" r="42" fill="none" stroke="#0AC4A8" stroke-width="8"
|
||||
stroke-linecap="round"
|
||||
stroke-dasharray="263.9"
|
||||
stroke-dashoffset="63.3"/>
|
||||
</svg>
|
||||
<div class="calorie-ring__center">
|
||||
<div class="calorie-ring__value">720</div>
|
||||
<div class="calorie-ring__unit">/ 950 kcal</div>
|
||||
<div class="calorie-ring__hint">略少 76%</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 三大营养素 -->
|
||||
<div class="macro-list">
|
||||
<!-- 蛋白质:目标 35g · 实际 35g · 100% -->
|
||||
<div class="macro-row">
|
||||
<div class="macro-row__head">
|
||||
<span class="macro-row__label"><span class="macro-row__dot" style="background:#4ade80;"></span>蛋白质</span>
|
||||
<span class="macro-row__value">35<small>/ 35g</small></span>
|
||||
</div>
|
||||
<div class="macro-bar">
|
||||
<div class="macro-bar__target" style="left:100%;"></div>
|
||||
<div class="macro-bar__fill" style="width:100%;background:#4ade80;"></div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 脂肪:目标 30g · 实际 28g · 93% -->
|
||||
<div class="macro-row">
|
||||
<div class="macro-row__head">
|
||||
<span class="macro-row__label"><span class="macro-row__dot" style="background:#fbbf24;"></span>脂肪</span>
|
||||
<span class="macro-row__value">28<small>/ 30g</small></span>
|
||||
</div>
|
||||
<div class="macro-bar">
|
||||
<div class="macro-bar__target" style="left:100%;"></div>
|
||||
<div class="macro-bar__fill" style="width:93%;background:#fbbf24;"></div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 碳水:目标 110g · 实际 88g · 80% -->
|
||||
<div class="macro-row">
|
||||
<div class="macro-row__head">
|
||||
<span class="macro-row__label"><span class="macro-row__dot" style="background:#60a5fa;"></span>碳水</span>
|
||||
<span class="macro-row__value">88<small>/ 110g</small></span>
|
||||
</div>
|
||||
<div class="macro-bar">
|
||||
<div class="macro-bar__target" style="left:100%;"></div>
|
||||
<div class="macro-bar__fill" style="width:80%;background:#60a5fa;"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="nutrition-conclusion">
|
||||
💡 搭配均衡,蛋白质达标、脂肪与碳水略低于目标,建议搭配一份水果补充能量
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function updateTime() {
|
||||
var d = new Date();
|
||||
var yyyy = d.getFullYear();
|
||||
var mm = String(d.getMonth() + 1).padStart(2, '0');
|
||||
var dd = String(d.getDate()).padStart(2, '0');
|
||||
var hh = String(d.getHours()).padStart(2, '0');
|
||||
var mi = String(d.getMinutes()).padStart(2, '0');
|
||||
var ss = String(d.getSeconds()).padStart(2, '0');
|
||||
document.getElementById('nowTime').textContent = yyyy + '-' + mm + '-' + dd + ' ' + hh + ':' + mi + ':' + ss;
|
||||
}
|
||||
updateTime();
|
||||
setInterval(updateTime, 1000);
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,210 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=1280, initial-scale=1.0">
|
||||
<title>用户屏 - 支付引导 | 蚁熊智能餐养平台</title>
|
||||
<style>
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
body {
|
||||
font-family: -apple-system, "Microsoft YaHei", "PingFang SC", sans-serif;
|
||||
background: #05080f;
|
||||
color: #fff;
|
||||
min-height: 100vh;
|
||||
min-width: 1280px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 20px;
|
||||
}
|
||||
.device-frame {
|
||||
width: 1280px;
|
||||
height: 720px;
|
||||
background: linear-gradient(180deg, #0e1326 0%, #1a2b4a 50%, #0e1326 100%);
|
||||
border-radius: 24px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 24px 64px rgba(0, 0, 0, 0.6), 0 0 0 1px rgba(255, 255, 255, 0.04);
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
/* 顶部金额条 */
|
||||
.header {
|
||||
padding: 24px 36px 20px;
|
||||
background: rgba(26, 43, 74, 0.5);
|
||||
border-bottom: 1px solid rgba(255, 255, 255, 0.06);
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.header__left { display: flex; align-items: baseline; gap: 12px; }
|
||||
.header__label {
|
||||
font-size: 14px;
|
||||
color: rgba(255, 255, 255, 0.55);
|
||||
}
|
||||
.header__amount {
|
||||
font-size: 42px;
|
||||
font-weight: 700;
|
||||
color: #0AC4A8;
|
||||
font-family: Menlo, Consolas, monospace;
|
||||
line-height: 1;
|
||||
}
|
||||
.header__right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 8px 16px;
|
||||
background: rgba(74, 144, 217, 0.15);
|
||||
border: 1px solid rgba(74, 144, 217, 0.35);
|
||||
border-radius: 18px;
|
||||
font-size: 13px;
|
||||
color: #60a5fa;
|
||||
font-weight: 600;
|
||||
}
|
||||
.header__right__dot {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 50%;
|
||||
background: #52c41a;
|
||||
box-shadow: 0 0 8px #52c41a;
|
||||
animation: pulse 1.2s infinite;
|
||||
}
|
||||
@keyframes pulse {
|
||||
0%, 100% { opacity: 1; transform: scale(1); }
|
||||
50% { opacity: 0.5; transform: scale(1.3); }
|
||||
}
|
||||
|
||||
/* 主体 */
|
||||
.body {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 30px 60px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* 支付方式面板 */
|
||||
.pay-panel {
|
||||
width: 100%;
|
||||
max-width: 720px;
|
||||
text-align: center;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 24px;
|
||||
}
|
||||
|
||||
/* 支付图标动画区 */
|
||||
.pay-icon-area {
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
border-radius: 50%;
|
||||
background: radial-gradient(circle at 50% 50%, rgba(74, 144, 217, 0.25), rgba(74, 144, 217, 0.05) 70%);
|
||||
border: 2px solid rgba(74, 144, 217, 0.35);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
box-shadow: 0 0 60px rgba(74, 144, 217, 0.25);
|
||||
}
|
||||
/* 外圈呼吸 */
|
||||
.pay-icon-area::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
inset: -20px;
|
||||
border-radius: 50%;
|
||||
border: 1px solid rgba(74, 144, 217, 0.2);
|
||||
animation: ripple 2s ease-out infinite;
|
||||
}
|
||||
.pay-icon-area::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
inset: -40px;
|
||||
border-radius: 50%;
|
||||
border: 1px solid rgba(74, 144, 217, 0.1);
|
||||
animation: ripple 2s ease-out infinite;
|
||||
animation-delay: 0.7s;
|
||||
}
|
||||
@keyframes ripple {
|
||||
0% { opacity: 1; transform: scale(0.8); }
|
||||
100% { opacity: 0; transform: scale(1.2); }
|
||||
}
|
||||
.pay-icon-area__icon {
|
||||
font-size: 100px;
|
||||
filter: drop-shadow(0 4px 12px rgba(0, 0, 0, 0.3));
|
||||
}
|
||||
|
||||
/* 支付状态文字 */
|
||||
.pay-status { display: flex; flex-direction: column; gap: 10px; }
|
||||
.pay-status__title {
|
||||
font-size: 36px;
|
||||
font-weight: 700;
|
||||
color: #fff;
|
||||
letter-spacing: 2px;
|
||||
}
|
||||
.pay-status__hint {
|
||||
font-size: 16px;
|
||||
color: rgba(255, 255, 255, 0.65);
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
/* 额度提示(在线支付/餐券) */
|
||||
.pay-method-tip {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 8px 18px;
|
||||
background: rgba(82, 196, 26, 0.1);
|
||||
border: 1px solid rgba(82, 196, 26, 0.3);
|
||||
border-radius: 22px;
|
||||
font-size: 13px;
|
||||
color: #4ade80;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="device-frame">
|
||||
|
||||
<!-- 顶部金额条 -->
|
||||
<div class="header">
|
||||
<div class="header__left">
|
||||
<span class="header__label">应付金额</span>
|
||||
<span class="header__amount">¥41.60</span>
|
||||
</div>
|
||||
<div class="header__right">
|
||||
<span class="header__right__dot"></span>
|
||||
<span>等待支付中</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 主体 -->
|
||||
<div class="body">
|
||||
|
||||
<!-- 当前支付方式:在线支付(扫码) -->
|
||||
<div class="pay-panel" id="payPanel">
|
||||
<div class="pay-icon-area">
|
||||
<span class="pay-icon-area__icon" id="payIcon">📱</span>
|
||||
</div>
|
||||
|
||||
<div class="pay-status">
|
||||
<div class="pay-status__title" id="payTitle">请出示付款码</div>
|
||||
<div class="pay-status__hint" id="payHint">
|
||||
打开微信/支付宝,将付款码对准扫码器
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="pay-method-tip" id="payTip">
|
||||
📱 支持微信 / 支付宝 / 银联云闪付
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,565 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=1280, initial-scale=1.0">
|
||||
<title>用户屏 - 支付成功 | 蚁熊智能餐养平台</title>
|
||||
<style>
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
body {
|
||||
font-family: -apple-system, "Microsoft YaHei", "PingFang SC", sans-serif;
|
||||
background: #05080f;
|
||||
color: #fff;
|
||||
min-height: 100vh;
|
||||
min-width: 1280px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 20px;
|
||||
}
|
||||
.device-frame {
|
||||
width: 1280px;
|
||||
height: 720px;
|
||||
background: linear-gradient(180deg, #0a2e1f 0%, #0e1326 50%, #0a2e1f 100%);
|
||||
border-radius: 24px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 24px 64px rgba(0, 0, 0, 0.6), 0 0 0 1px rgba(82, 196, 26, 0.15);
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
/* 背景烟花动画 */
|
||||
.confetti {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
pointer-events: none;
|
||||
overflow: hidden;
|
||||
}
|
||||
.confetti__piece {
|
||||
position: absolute;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
opacity: 0.7;
|
||||
animation: fall 3s linear infinite;
|
||||
}
|
||||
@keyframes fall {
|
||||
0% { transform: translateY(-100px) rotate(0deg); opacity: 1; }
|
||||
100% { transform: translateY(800px) rotate(720deg); opacity: 0; }
|
||||
}
|
||||
|
||||
/* 主体 */
|
||||
.body {
|
||||
flex: 1;
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
align-items: center;
|
||||
padding: 40px 50px;
|
||||
gap: 30px;
|
||||
z-index: 2;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* 左:成功动画 + 金额 */
|
||||
.success-block {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 18px;
|
||||
}
|
||||
.success-icon {
|
||||
width: 140px;
|
||||
height: 140px;
|
||||
border-radius: 50%;
|
||||
background: linear-gradient(135deg, #52c41a, #0AC4A8);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 76px;
|
||||
color: #fff;
|
||||
box-shadow: 0 12px 50px rgba(82, 196, 26, 0.5), 0 0 0 12px rgba(82, 196, 26, 0.1);
|
||||
animation: bounceIn 0.7s cubic-bezier(0.68, -0.55, 0.27, 1.55);
|
||||
}
|
||||
@keyframes bounceIn {
|
||||
0% { transform: scale(0) rotate(-180deg); opacity: 0; }
|
||||
60% { transform: scale(1.15) rotate(10deg); opacity: 1; }
|
||||
100% { transform: scale(1) rotate(0); }
|
||||
}
|
||||
|
||||
.success-title {
|
||||
font-size: 40px;
|
||||
font-weight: 700;
|
||||
color: #fff;
|
||||
letter-spacing: 4px;
|
||||
text-align: center;
|
||||
}
|
||||
.success-amount {
|
||||
text-align: center;
|
||||
}
|
||||
.success-amount__value {
|
||||
font-size: 72px;
|
||||
font-weight: 700;
|
||||
color: #0AC4A8;
|
||||
font-family: Menlo, Consolas, monospace;
|
||||
line-height: 1;
|
||||
text-shadow: 0 4px 24px rgba(10, 196, 168, 0.4);
|
||||
}
|
||||
.success-amount__method {
|
||||
margin-top: 10px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
padding: 6px 16px;
|
||||
background: rgba(82, 196, 26, 0.2);
|
||||
border: 1px solid rgba(82, 196, 26, 0.4);
|
||||
border-radius: 18px;
|
||||
font-size: 13px;
|
||||
color: #4ade80;
|
||||
}
|
||||
|
||||
/* 账户信息条(仅刷脸支付显示) */
|
||||
.account-info {
|
||||
width: 100%;
|
||||
max-width: 360px;
|
||||
padding: 12px 18px;
|
||||
background: linear-gradient(90deg, rgba(74, 144, 217, 0.18), rgba(10, 196, 168, 0.12));
|
||||
border: 1px solid rgba(74, 144, 217, 0.35);
|
||||
border-radius: 12px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
gap: 14px;
|
||||
animation: slideUp 0.5s ease;
|
||||
}
|
||||
@keyframes slideUp {
|
||||
from { opacity: 0; transform: translateY(10px); }
|
||||
to { opacity: 1; transform: translateY(0); }
|
||||
}
|
||||
.account-info__col {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 2px;
|
||||
}
|
||||
.account-info__label {
|
||||
font-size: 11px;
|
||||
color: rgba(255, 255, 255, 0.55);
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
.account-info__value {
|
||||
font-size: 18px;
|
||||
font-weight: 700;
|
||||
color: #fff;
|
||||
font-family: Menlo, Consolas, monospace;
|
||||
line-height: 1.1;
|
||||
}
|
||||
.account-info__value--expense { color: #fb923c; }
|
||||
.account-info__value--balance { color: #4ade80; }
|
||||
.account-info__divider {
|
||||
width: 1px;
|
||||
height: 32px;
|
||||
background: rgba(255, 255, 255, 0.15);
|
||||
}
|
||||
|
||||
/* 演示切换按钮(原型展示用) */
|
||||
.demo-switcher {
|
||||
position: absolute;
|
||||
top: 16px;
|
||||
right: 16px;
|
||||
z-index: 10;
|
||||
display: flex;
|
||||
gap: 6px;
|
||||
padding: 6px;
|
||||
background: rgba(0, 0, 0, 0.4);
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
border-radius: 22px;
|
||||
backdrop-filter: blur(8px);
|
||||
}
|
||||
.demo-switcher__btn {
|
||||
padding: 5px 14px;
|
||||
background: transparent;
|
||||
border: none;
|
||||
border-radius: 16px;
|
||||
font-size: 12px;
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
cursor: pointer;
|
||||
transition: all 0.25s;
|
||||
font-family: inherit;
|
||||
}
|
||||
.demo-switcher__btn:hover {
|
||||
color: #fff;
|
||||
background: rgba(255, 255, 255, 0.06);
|
||||
}
|
||||
.demo-switcher__btn.active {
|
||||
background: rgba(74, 144, 217, 0.35);
|
||||
color: #fff;
|
||||
box-shadow: 0 2px 8px rgba(74, 144, 217, 0.3);
|
||||
}
|
||||
|
||||
/* 右:营养 + 引导 */
|
||||
.side-block {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 18px;
|
||||
}
|
||||
|
||||
/* 营养卡片 */
|
||||
.nutrition-card {
|
||||
background: linear-gradient(135deg, rgba(10, 196, 168, 0.15), rgba(74, 144, 217, 0.08));
|
||||
border: 1px solid rgba(10, 196, 168, 0.3);
|
||||
border-radius: 16px;
|
||||
padding: 20px;
|
||||
}
|
||||
.nutrition-head {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
.nutrition-head__title {
|
||||
font-size: 18px;
|
||||
color: #fff;
|
||||
font-weight: 600;
|
||||
}
|
||||
.nutrition-score {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 6px 14px;
|
||||
background: rgba(251, 191, 36, 0.15);
|
||||
border: 1px solid rgba(251, 191, 36, 0.4);
|
||||
border-radius: 12px;
|
||||
}
|
||||
.nutrition-score__label {
|
||||
font-size: 10px;
|
||||
color: rgba(251, 191, 36, 0.8);
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
.nutrition-score__value {
|
||||
font-size: 22px;
|
||||
color: #fbbf24;
|
||||
font-weight: 700;
|
||||
font-family: Menlo, Consolas, monospace;
|
||||
}
|
||||
.nutrition-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
gap: 8px;
|
||||
}
|
||||
.nutrition-item {
|
||||
text-align: center;
|
||||
padding: 12px 4px;
|
||||
background: rgba(0, 0, 0, 0.25);
|
||||
border-radius: 8px;
|
||||
}
|
||||
.nutrition-item__label {
|
||||
font-size: 11px;
|
||||
color: rgba(255, 255, 255, 0.55);
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
.nutrition-item__value {
|
||||
font-size: 22px;
|
||||
font-weight: 700;
|
||||
color: #fff;
|
||||
font-family: Menlo, Consolas, monospace;
|
||||
}
|
||||
.nutrition-item__unit {
|
||||
font-size: 10px;
|
||||
color: rgba(255, 255, 255, 0.4);
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
/* 健康建议 */
|
||||
.health-tip {
|
||||
padding: 14px 16px;
|
||||
background: rgba(82, 196, 26, 0.1);
|
||||
border: 1px solid rgba(82, 196, 26, 0.3);
|
||||
border-radius: 12px;
|
||||
font-size: 13px;
|
||||
color: rgba(255, 255, 255, 0.85);
|
||||
line-height: 1.6;
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
align-items: flex-start;
|
||||
}
|
||||
.health-tip__icon { font-size: 18px; }
|
||||
.health-tip__text strong { color: #4ade80; }
|
||||
|
||||
/* 二维码引导 */
|
||||
.qr-guide {
|
||||
padding: 14px 18px;
|
||||
background: rgba(26, 43, 74, 0.5);
|
||||
border: 1px solid rgba(74, 144, 217, 0.3);
|
||||
border-radius: 12px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 14px;
|
||||
}
|
||||
.qr-guide__img {
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
border-radius: 8px;
|
||||
background: #fff;
|
||||
padding: 4px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.qr-guide__text { flex: 1; }
|
||||
.qr-guide__title {
|
||||
font-size: 14px;
|
||||
color: #fff;
|
||||
font-weight: 600;
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
.qr-guide__sub {
|
||||
font-size: 11px;
|
||||
color: rgba(255, 255, 255, 0.55);
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
/* 底部 */
|
||||
.footer {
|
||||
padding: 14px 36px;
|
||||
background: rgba(0, 0, 0, 0.3);
|
||||
border-top: 1px solid rgba(255, 255, 255, 0.06);
|
||||
text-align: center;
|
||||
flex-shrink: 0;
|
||||
z-index: 2;
|
||||
}
|
||||
.footer__tip {
|
||||
font-size: 14px;
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
}
|
||||
.footer__sub {
|
||||
font-size: 12px;
|
||||
color: rgba(255, 255, 255, 0.4);
|
||||
margin-top: 4px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="device-frame">
|
||||
|
||||
<!-- 演示切换按钮(原型展示用,实际部署可移除) -->
|
||||
<div class="demo-switcher">
|
||||
<button class="demo-switcher__btn" data-method="online">在线支付演示</button>
|
||||
<button class="demo-switcher__btn active" data-method="face">刷脸支付演示</button>
|
||||
</div>
|
||||
|
||||
<!-- 烟花动画背景 -->
|
||||
<div class="confetti" id="confetti"></div>
|
||||
|
||||
<!-- 主体 -->
|
||||
<div class="body">
|
||||
|
||||
<!-- 左:成功动画 + 金额 -->
|
||||
<div class="success-block">
|
||||
<div class="success-icon">✔</div>
|
||||
<div class="success-title">支付成功</div>
|
||||
|
||||
<!-- 账户信息条(仅刷脸支付显示) -->
|
||||
<div class="account-info" id="accountInfo">
|
||||
<div class="account-info__col">
|
||||
<span class="account-info__label">本次消费</span>
|
||||
<span class="account-info__value account-info__value--expense">-¥41.60</span>
|
||||
</div>
|
||||
<div class="account-info__divider"></div>
|
||||
<div class="account-info__col">
|
||||
<span class="account-info__label">账户余额 · 张明</span>
|
||||
<span class="account-info__value account-info__value--balance">¥128.40</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="success-amount">
|
||||
<div class="success-amount__value">¥41.60</div>
|
||||
<div class="success-amount__method" id="payMethodBadge">👤 刷脸支付 · 已扣款</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 右:营养 + 引导 -->
|
||||
<div class="side-block">
|
||||
|
||||
<!-- 营养摘要 -->
|
||||
<div class="nutrition-card">
|
||||
<div class="nutrition-head">
|
||||
<span class="nutrition-head__title">🥗 本餐营养摄入</span>
|
||||
<div class="nutrition-score">
|
||||
<span class="nutrition-score__label">SCORE</span>
|
||||
<span class="nutrition-score__value">88</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="nutrition-grid">
|
||||
<div class="nutrition-item">
|
||||
<div class="nutrition-item__label">热量</div>
|
||||
<div class="nutrition-item__value">720<span class="nutrition-item__unit">kcal</span></div>
|
||||
</div>
|
||||
<div class="nutrition-item">
|
||||
<div class="nutrition-item__label">蛋白质</div>
|
||||
<div class="nutrition-item__value">35<span class="nutrition-item__unit">g</span></div>
|
||||
</div>
|
||||
<div class="nutrition-item">
|
||||
<div class="nutrition-item__label">脂肪</div>
|
||||
<div class="nutrition-item__value">28<span class="nutrition-item__unit">g</span></div>
|
||||
</div>
|
||||
<div class="nutrition-item">
|
||||
<div class="nutrition-item__label">碳水</div>
|
||||
<div class="nutrition-item__value">88<span class="nutrition-item__unit">g</span></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 健康建议 -->
|
||||
<div class="health-tip">
|
||||
<span class="health-tip__icon">💡</span>
|
||||
<span class="health-tip__text">
|
||||
本餐蛋白质摄入 <strong>达标</strong>,建议下午补充 1500ml 水分,适量增加蔬菜摄入量
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!-- 小程序引导 -->
|
||||
<div class="qr-guide">
|
||||
<svg class="qr-guide__img" viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect x="0" y="0" width="64" height="64" fill="#fff"/>
|
||||
<g fill="#0e1326">
|
||||
<!-- 三个定位角 -->
|
||||
<rect x="4" y="4" width="14" height="14"/>
|
||||
<rect x="6" y="6" width="10" height="10" fill="#fff"/>
|
||||
<rect x="8" y="8" width="6" height="6" fill="#0e1326"/>
|
||||
<rect x="46" y="4" width="14" height="14"/>
|
||||
<rect x="48" y="6" width="10" height="10" fill="#fff"/>
|
||||
<rect x="50" y="8" width="6" height="6" fill="#0e1326"/>
|
||||
<rect x="4" y="46" width="14" height="14"/>
|
||||
<rect x="6" y="48" width="10" height="10" fill="#fff"/>
|
||||
<rect x="8" y="50" width="6" height="6" fill="#0e1326"/>
|
||||
<!-- 数据点(模拟) -->
|
||||
<rect x="22" y="6" width="2" height="2"/>
|
||||
<rect x="26" y="6" width="2" height="2"/>
|
||||
<rect x="30" y="6" width="2" height="2"/>
|
||||
<rect x="38" y="6" width="2" height="2"/>
|
||||
<rect x="22" y="10" width="2" height="2"/>
|
||||
<rect x="34" y="10" width="2" height="2"/>
|
||||
<rect x="22" y="14" width="6" height="2"/>
|
||||
<rect x="32" y="14" width="2" height="2"/>
|
||||
<rect x="38" y="14" width="2" height="2"/>
|
||||
<rect x="6" y="22" width="2" height="2"/>
|
||||
<rect x="10" y="22" width="2" height="2"/>
|
||||
<rect x="14" y="22" width="2" height="2"/>
|
||||
<rect x="22" y="22" width="2" height="2"/>
|
||||
<rect x="26" y="22" width="6" height="2"/>
|
||||
<rect x="34" y="22" width="2" height="2"/>
|
||||
<rect x="42" y="22" width="2" height="2"/>
|
||||
<rect x="50" y="22" width="2" height="2"/>
|
||||
<rect x="54" y="22" width="2" height="2"/>
|
||||
<rect x="6" y="26" width="2" height="2"/>
|
||||
<rect x="14" y="26" width="2" height="2"/>
|
||||
<rect x="22" y="26" width="2" height="2"/>
|
||||
<rect x="30" y="26" width="2" height="2"/>
|
||||
<rect x="38" y="26" width="2" height="2"/>
|
||||
<rect x="46" y="26" width="2" height="2"/>
|
||||
<rect x="54" y="26" width="2" height="2"/>
|
||||
<rect x="10" y="30" width="2" height="2"/>
|
||||
<rect x="18" y="30" width="2" height="2"/>
|
||||
<rect x="26" y="30" width="2" height="2"/>
|
||||
<rect x="34" y="30" width="2" height="2"/>
|
||||
<rect x="42" y="30" width="2" height="2"/>
|
||||
<rect x="50" y="30" width="2" height="2"/>
|
||||
<rect x="58" y="30" width="2" height="2"/>
|
||||
<rect x="6" y="34" width="2" height="2"/>
|
||||
<rect x="14" y="34" width="2" height="2"/>
|
||||
<rect x="22" y="34" width="2" height="2"/>
|
||||
<rect x="30" y="34" width="6" height="2"/>
|
||||
<rect x="42" y="34" width="2" height="2"/>
|
||||
<rect x="50" y="34" width="2" height="2"/>
|
||||
<rect x="22" y="38" width="2" height="2"/>
|
||||
<rect x="26" y="38" width="2" height="2"/>
|
||||
<rect x="34" y="38" width="2" height="2"/>
|
||||
<rect x="42" y="38" width="2" height="2"/>
|
||||
<rect x="46" y="38" width="2" height="2"/>
|
||||
<rect x="54" y="38" width="2" height="2"/>
|
||||
<rect x="22" y="42" width="6" height="2"/>
|
||||
<rect x="34" y="42" width="2" height="2"/>
|
||||
<rect x="42" y="42" width="2" height="2"/>
|
||||
<rect x="50" y="42" width="6" height="2"/>
|
||||
<rect x="22" y="46" width="2" height="2"/>
|
||||
<rect x="30" y="46" width="2" height="2"/>
|
||||
<rect x="22" y="50" width="2" height="2"/>
|
||||
<rect x="26" y="50" width="2" height="2"/>
|
||||
<rect x="34" y="50" width="2" height="2"/>
|
||||
<rect x="42" y="50" width="2" height="2"/>
|
||||
<rect x="46" y="50" width="2" height="2"/>
|
||||
<rect x="54" y="50" width="2" height="2"/>
|
||||
<rect x="22" y="54" width="2" height="2"/>
|
||||
<rect x="30" y="54" width="2" height="2"/>
|
||||
<rect x="38" y="54" width="2" height="2"/>
|
||||
<rect x="46" y="54" width="2" height="2"/>
|
||||
<rect x="50" y="54" width="6" height="2"/>
|
||||
</g>
|
||||
</svg>
|
||||
<div class="qr-guide__text">
|
||||
<div class="qr-guide__title">📱 扫码查看详细营养报告</div>
|
||||
<div class="qr-guide__sub">小程序内可查看每日营养摄入趋势、健康建议、餐品推荐</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- 底部 -->
|
||||
<div class="footer">
|
||||
<div class="footer__tip">😊 感谢您的惠顾,祝您用餐愉快!</div>
|
||||
<div class="footer__sub">合理膳食 · 均衡营养 · 健康生活</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<script>
|
||||
/* 生成烟花碎片 */
|
||||
function createConfetti() {
|
||||
var colors = ['#52c41a', '#0AC4A8', '#4a90d9', '#fbbf24', '#fb923c', '#a855f7'];
|
||||
var shapes = ['50%', '0', '0'];
|
||||
var confetti = document.getElementById('confetti');
|
||||
for (var i = 0; i < 40; i++) {
|
||||
var piece = document.createElement('div');
|
||||
piece.className = 'confetti__piece';
|
||||
piece.style.left = Math.random() * 100 + '%';
|
||||
piece.style.background = colors[Math.floor(Math.random() * colors.length)];
|
||||
piece.style.borderRadius = shapes[Math.floor(Math.random() * shapes.length)];
|
||||
piece.style.animationDelay = Math.random() * 3 + 's';
|
||||
piece.style.animationDuration = (2 + Math.random() * 2) + 's';
|
||||
piece.style.width = (6 + Math.random() * 8) + 'px';
|
||||
piece.style.height = piece.style.width;
|
||||
confetti.appendChild(piece);
|
||||
}
|
||||
}
|
||||
createConfetti();
|
||||
|
||||
/* 支付方式演示切换 */
|
||||
var methodConfig = {
|
||||
online: {
|
||||
badge: '📱 在线支付 · 微信',
|
||||
showAccount: false
|
||||
},
|
||||
face: {
|
||||
badge: '👤 刷脸支付 · 已扣款',
|
||||
showAccount: true
|
||||
}
|
||||
};
|
||||
|
||||
function switchDemo(method) {
|
||||
var cfg = methodConfig[method];
|
||||
if (!cfg) return;
|
||||
document.getElementById('payMethodBadge').innerHTML = cfg.badge;
|
||||
document.getElementById('accountInfo').style.display = cfg.showAccount ? 'flex' : 'none';
|
||||
document.querySelectorAll('.demo-switcher__btn').forEach(function(btn) {
|
||||
btn.classList.toggle('active', btn.dataset.method === method);
|
||||
});
|
||||
}
|
||||
|
||||
document.querySelectorAll('.demo-switcher__btn').forEach(function(btn) {
|
||||
btn.addEventListener('click', function() {
|
||||
switchDemo(btn.dataset.method);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user