feat: 用户管理账户体系+餐品档案结构调整+小程序人脸认证完善
- 后台用户管理:表格新增账号余额列与账户管理操作;新增批量充值弹窗、编辑会员信息弹窗 - 后台账户管理页:重构为两栏布局(用户概要+充值卡片),优化账单列表区 - 后台餐品档案:宣传视频启用开关;营养指标 Tab 合并入餐品构成;新增熟重字段;步骤数 7→6 - 小程序人脸认证:采集/认证话术统一;首页与档案页接入认证状态标签 - 小程序钱包/订单:钱包主页扩展,新增明细详情入口 - 文档:更新 CHANGELOG,新增下周工作计划 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.7
parent
09f1080730
commit
e83b0f0697
@@ -106,14 +106,14 @@
|
||||
</div>
|
||||
<span class="avatar-tip">点击修改头像</span>
|
||||
</div>
|
||||
<!-- [原型演示] 人脸认证状态切换 -->
|
||||
<!-- [原型演示] 人脸采集状态切换 -->
|
||||
<div class="demo-bar">
|
||||
<span class="demo-label">演示切换:</span>
|
||||
<label class="toggle-switch">
|
||||
<input type="checkbox" id="faceToggle" onchange="toggleFaceState()">
|
||||
<span class="toggle-slider"></span>
|
||||
</label>
|
||||
<span class="demo-state" id="demoStateLabel">未认证</span>
|
||||
<span class="demo-state" id="demoStateLabel">未采集</span>
|
||||
</div>
|
||||
<!-- 信息列表 -->
|
||||
<div class="info-group">
|
||||
@@ -126,10 +126,10 @@
|
||||
<div class="info-row"><span class="info-label">单位</span><span class="info-value">CQ能源</span></div>
|
||||
<div class="info-row"><span class="info-label">部门</span><span class="info-value">采油一厂</span></div>
|
||||
<div class="info-row"><span class="info-label">会员等级</span><span class="info-value gold">黄金会员</span></div>
|
||||
<!-- [交互] 已认证:点击查看人脸信息/重新录入;未认证:点击前往录入 -->
|
||||
<!-- [交互] 已采集:点击查看人脸信息/重新录入;未采集:点击前往录入 -->
|
||||
<div class="info-row editable" id="faceRow" onclick="handleFaceClick()">
|
||||
<span class="info-label">人脸信息</span>
|
||||
<span class="info-value" id="faceValue" style="color:#fa8c16;">未认证<i class="edit-icon">›</i></span>
|
||||
<span class="info-value" id="faceValue" style="color:#fa8c16;">未采集<i class="edit-icon">›</i></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -138,7 +138,7 @@
|
||||
<script>
|
||||
var isFaceVerified = false;
|
||||
|
||||
/* [交互] 切换开关:改变人脸认证状态 */
|
||||
/* [交互] 切换开关:改变人脸采集状态 */
|
||||
function toggleFaceState() {
|
||||
isFaceVerified = document.getElementById('faceToggle').checked;
|
||||
updateFaceRow();
|
||||
@@ -150,16 +150,16 @@
|
||||
var labelEl = document.getElementById('demoStateLabel');
|
||||
if (isFaceVerified) {
|
||||
valEl.style.color = '#52c41a';
|
||||
valEl.innerHTML = '已认证<i class="edit-icon">›</i>';
|
||||
labelEl.textContent = '已认证';
|
||||
valEl.innerHTML = '已采集<i class="edit-icon">›</i>';
|
||||
labelEl.textContent = '已采集';
|
||||
} else {
|
||||
valEl.style.color = '#fa8c16';
|
||||
valEl.innerHTML = '未认证<i class="edit-icon">›</i>';
|
||||
labelEl.textContent = '未认证';
|
||||
valEl.innerHTML = '未采集<i class="edit-icon">›</i>';
|
||||
labelEl.textContent = '未采集';
|
||||
}
|
||||
}
|
||||
|
||||
/* [交互] 点击人脸信息行:已认证→人脸详情页;未认证→人脸录入页 */
|
||||
/* [交互] 点击人脸信息行:已采集→人脸详情页;未采集→人脸录入页 */
|
||||
function handleFaceClick() {
|
||||
if (isFaceVerified) {
|
||||
window.location.href = 'me-face-info.html';
|
||||
|
||||
@@ -96,13 +96,12 @@
|
||||
</div>
|
||||
<!-- 人脸信息详情 -->
|
||||
<div class="info-group">
|
||||
<div class="info-row"><span class="info-label">认证状态</span><span class="info-value green">已认证</span></div>
|
||||
<div class="info-row"><span class="info-label">采集状态</span><span class="info-value green">已采集</span></div>
|
||||
<div class="info-row"><span class="info-label">录入时间</span><span class="info-value">2026-08-01 14:30</span></div>
|
||||
<div class="info-row"><span class="info-label">清晰度</span><span class="info-value green">95%</span></div>
|
||||
</div>
|
||||
<!-- [交互] 点击跳转人脸重新录入 -->
|
||||
<div class="btn-section">
|
||||
<a class="btn-reenroll" href="me-face-verify.html">重新录入</a>
|
||||
<a class="btn-reenroll" href="me-face-verify.html">重新采集</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="home-indicator"></div>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>人脸认证 | 智能餐养小程序</title>
|
||||
<title>人脸采集 | 智能餐养小程序</title>
|
||||
<style>
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
body {
|
||||
@@ -102,7 +102,7 @@
|
||||
}
|
||||
.verify-tip .icon { font-size: 18px; }
|
||||
|
||||
/* 认证按钮 */
|
||||
/* 采集按钮 */
|
||||
.btn-start {
|
||||
width: 200px; padding: 14px 0; border: none; border-radius: 24px;
|
||||
background: linear-gradient(135deg, #1677ff, #4096ff);
|
||||
@@ -115,7 +115,7 @@
|
||||
background: #ccc; box-shadow: none; cursor: not-allowed;
|
||||
}
|
||||
|
||||
/* 认证结果卡片 */
|
||||
/* 采集结果卡片 */
|
||||
.result-card {
|
||||
width: 100%; background: #fff; border-radius: 12px; padding: 24px 16px;
|
||||
text-align: center; margin-bottom: 16px;
|
||||
@@ -158,7 +158,7 @@
|
||||
</div>
|
||||
<div class="nav-bar">
|
||||
<a class="nav-back" href="me-home.html" id="btnBack">‹</a>
|
||||
<span class="nav-title">人脸认证</span>
|
||||
<span class="nav-title">人脸采集</span>
|
||||
<span class="nav-placeholder"></span>
|
||||
</div>
|
||||
<div class="page-content">
|
||||
@@ -171,7 +171,7 @@
|
||||
<div class="step-dot" id="step3">3</div>
|
||||
</div>
|
||||
|
||||
<!-- [交互] 阶段一:准备认证 -->
|
||||
<!-- [交互] 阶段一:准备采集 -->
|
||||
<div class="verify-body" id="phasePrepare">
|
||||
<div class="camera-frame">
|
||||
<div class="camera-corners">
|
||||
@@ -188,11 +188,11 @@
|
||||
<p class="verify-tip">
|
||||
<span class="icon">💡</span> 请确保光线充足、面部无遮挡<br>按提示完成眨眼、张嘴等动作
|
||||
</p>
|
||||
<!-- [交互] 点击开始人脸认证采集 -->
|
||||
<button class="btn-start" onclick="startVerify()">开始认证</button>
|
||||
<!-- [交互] 点击开始人脸采集 -->
|
||||
<button class="btn-start" onclick="startVerify()">开始采集</button>
|
||||
</div>
|
||||
|
||||
<!-- [交互] 阶段二:认证进行中(默认隐藏) -->
|
||||
<!-- [交互] 阶段二:采集中(默认隐藏) -->
|
||||
<div class="verify-body" id="phaseCapturing" style="display:none;">
|
||||
<div class="camera-frame" style="box-shadow: 0 0 0 4px rgba(22,119,255,0.6), 0 8px 32px rgba(0,0,0,0.2);">
|
||||
<div class="camera-corners">
|
||||
@@ -216,15 +216,14 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- [交互] 阶段三:认证结果(默认隐藏) -->
|
||||
<!-- [交互] 阶段三:采集结果(默认隐藏) -->
|
||||
<div class="verify-body" id="phaseResult" style="display:none;">
|
||||
<div class="result-card">
|
||||
<div class="result-icon" id="resultIcon">✅</div>
|
||||
<div class="result-title" id="resultTitle">认证成功</div>
|
||||
<div class="result-title" id="resultTitle">采集成功</div>
|
||||
<div class="result-desc" id="resultDesc">人脸信息已录入,可用于后续快速验证</div>
|
||||
<div class="result-meta">
|
||||
<div class="meta-item"><div class="meta-val" id="metaTime">--</div><div class="meta-label">认证时间</div></div>
|
||||
<div class="meta-item"><div class="meta-val" style="color:#52c41a;" id="metaScore">--</div><div class="meta-label">清晰度</div></div>
|
||||
<div class="meta-item"><div class="meta-val" id="metaTime">--</div><div class="meta-label">采集时间</div></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="btn-group">
|
||||
@@ -244,7 +243,7 @@
|
||||
</div>
|
||||
|
||||
<script>
|
||||
/* [交互] 开始认证:切换到采集阶段,模拟采集进度 */
|
||||
/* [交互] 开始采集:切换到采集阶段,模拟采集进度 */
|
||||
function startVerify() {
|
||||
document.getElementById('phasePrepare').style.display = 'none';
|
||||
document.getElementById('phaseCapturing').style.display = 'flex';
|
||||
@@ -276,7 +275,7 @@
|
||||
}, 180);
|
||||
}
|
||||
|
||||
/* [交互] 显示认证结果 */
|
||||
/* [交互] 显示采集结果 */
|
||||
function showResult() {
|
||||
document.getElementById('phaseCapturing').style.display = 'none';
|
||||
document.getElementById('phaseResult').style.display = 'flex';
|
||||
@@ -294,7 +293,6 @@
|
||||
String(now.getDate()).padStart(2,'0')+' '+
|
||||
String(now.getHours()).padStart(2,'0')+':'+
|
||||
String(now.getMinutes()).padStart(2,'0');
|
||||
document.getElementById('metaScore').textContent = (92 + Math.floor(Math.random()*7)) + '%';
|
||||
}
|
||||
|
||||
/* [交互] 重新采集:回到准备阶段 */
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
}
|
||||
.user-dept { font-size: 12px; opacity: 0.8; margin-top: 3px; }
|
||||
.user-extra { display: flex; gap: 12px; margin-top: 4px; font-size: 11px; opacity: 0.85; }
|
||||
/* 人脸认证标签 */
|
||||
/* 人脸采集标签 */
|
||||
.face-tag {
|
||||
display: inline-flex; align-items: center; gap: 3px;
|
||||
padding: 1px 7px; border-radius: 10px; font-size: 10px; font-weight: 500;
|
||||
@@ -122,8 +122,8 @@
|
||||
<div class="user-meta">
|
||||
<div class="user-name-row">
|
||||
<span class="user-name">张三</span>
|
||||
<!-- [交互] 未认证时点击跳转人脸录入页;已认证时切换为 face-tag--verified -->
|
||||
<a class="face-tag face-tag--unverified" href="me-face-verify.html">未认证</a>
|
||||
<!-- [交互] 未采集时点击跳转人脸录入页;已采集时切换为 face-tag--verified -->
|
||||
<a class="face-tag face-tag--unverified" href="me-face-verify.html">未采集</a>
|
||||
</div>
|
||||
<div class="user-dept">CQ能源 · 采油一厂</div>
|
||||
<div class="user-extra">
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
.oh-date { font-size: 15px; font-weight: 700; color: #333; margin-bottom: 3px; }
|
||||
.oh-id { font-size: 11px; color: #999; }
|
||||
.oh-order-time { font-size: 11px; color: #999; margin-top: 2px; }
|
||||
.oh-order-place { font-size: 11px; color: #999; margin-top: 2px; }
|
||||
.oh-badge { font-size: 12px; padding: 3px 10px; border-radius: 12px; background: #f6ffed; color: #52c41a; font-weight: 600; }
|
||||
.oh-stats { display: flex; gap: 0; padding: 10px 0; border-top: 0.5px solid #f5f5f5; border-bottom: 0.5px solid #f5f5f5; }
|
||||
.oh-stat { flex: 1; text-align: center; }
|
||||
@@ -117,6 +118,7 @@
|
||||
<div>
|
||||
<div class="oh-date">2026-04-28 午餐</div>
|
||||
<div class="oh-id">NM-20260428-001</div>
|
||||
<div class="oh-order-place">下单场所:二号食堂</div>
|
||||
<div class="oh-order-time">下单时间:2026-04-28 11:32:15</div>
|
||||
</div>
|
||||
<span class="oh-badge">✅ 已完成</span>
|
||||
@@ -326,6 +328,7 @@
|
||||
+ '<div>'
|
||||
+ '<div class="oh-date">2026-05-14 午餐</div>'
|
||||
+ '<div class="oh-id">XL-20260514-001</div>'
|
||||
+ '<div class="oh-order-place">下单场所:二号食堂</div>'
|
||||
+ '<div class="oh-order-time">下单时间:2026-05-14 11:58:32</div>'
|
||||
+ '</div>'
|
||||
+ '<span class="oh-badge" style="background:#f6ffed;color:#52c41a;">✅ 已完成</span>'
|
||||
@@ -403,10 +406,6 @@
|
||||
+ '<span class="ir-label">支付时间</span>'
|
||||
+ '<span class="ir-value">2026-05-14 11:58:35</span>'
|
||||
+ '</div>'
|
||||
+ '<div class="info-row">'
|
||||
+ '<span class="ir-label">取餐餐线</span>'
|
||||
+ '<span class="ir-value">A区中餐线</span>'
|
||||
+ '</div>'
|
||||
+ '</div>';
|
||||
} else if (type === 'clean') {
|
||||
/* 状态徽标:文案与配色随 status 切换 */
|
||||
@@ -423,7 +422,8 @@
|
||||
+ '<div>'
|
||||
+ '<div class="oh-date">2026-04-29 午餐时段配送</div>'
|
||||
+ '<div class="oh-id">CL-20260428-017</div>'
|
||||
+ '<div class="oh-order-time">下单时间:2026-04-28 14:23:08</div>'
|
||||
+ '<div class="oh-order-place">下单场所:二号食堂</div>'
|
||||
+ '<div class="oh-order-time">下单时间:2026-04-28 14:23:08</div>'
|
||||
+ '</div>'
|
||||
+ '<span class="oh-badge" style="background:' + b.bg + ';color:' + b.color + ';">' + b.text + '</span>'
|
||||
+ '</div>'
|
||||
|
||||
@@ -20,10 +20,6 @@
|
||||
.balance-label { font-size: 14px; opacity: 0.85; margin-bottom: 8px; }
|
||||
.balance-amount { font-size: 36px; font-weight: 700; letter-spacing: -1px; }
|
||||
.balance-amount .symbol { font-size: 20px; font-weight: 500; margin-right: 4px; }
|
||||
.action-buttons { display: flex; gap: 12px; margin-top: 20px; }
|
||||
.action-btn { flex: 1; height: 36px; border-radius: 18px; border: none; font-size: 14px; font-weight: 500; cursor: pointer; }
|
||||
.action-btn.primary { background: #fff; color: #1677ff; }
|
||||
.action-btn.secondary { background: rgba(255,255,255,0.25); color: #fff; border: 1px solid rgba(255,255,255,0.5); }
|
||||
.section-title { font-size: 15px; font-weight: 600; color: #333; padding: 16px 16px 12px; }
|
||||
/* 月份分组 */
|
||||
.month-group { margin: 0 16px 4px; }
|
||||
@@ -72,10 +68,6 @@
|
||||
<div class="balance-card">
|
||||
<div class="balance-label">当前余额</div>
|
||||
<div class="balance-amount"><span class="symbol">¥</span>256.50</div>
|
||||
<div class="action-buttons">
|
||||
<button class="action-btn primary">充值</button>
|
||||
<button class="action-btn secondary">提现</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 余额明细 -->
|
||||
|
||||
Reference in New Issue
Block a user