feat: 小程序端-人脸认证流程+钱包明细详情
- me-home.html 用户卡片新增「未认证/已认证」人脸标签,未认证点击跳转人脸录入 - me-account.html 增加演示切换开关用于切换人脸认证状态 - 新增 me-face-verify.html(人脸认证引导/采集)和 me-face-info.html(认证信息展示) - me-wallet.html 钱包页扩展收支明细/账户卡片等内容 - 新增 me-wallet-detail.html 钱包明细详情页 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.7
parent
836b05383d
commit
799be643b2
@@ -64,6 +64,26 @@
|
||||
.info-value.gold { color: #d4a017; }
|
||||
.info-row.editable { cursor: pointer; }
|
||||
.edit-icon { font-size: 12px; font-style: normal; opacity: 0.6; }
|
||||
/* 演示切换栏 */
|
||||
.demo-bar {
|
||||
display: flex; align-items: center; gap: 8px; padding: 10px 16px;
|
||||
background: #fffbe6; border-bottom: 1px solid #ffe58f; font-size: 12px; color: #8c6d1f;
|
||||
}
|
||||
.demo-bar .demo-label { font-weight: 600; }
|
||||
.demo-bar .demo-state { font-weight: 600; min-width: 48px; }
|
||||
/* 切换开关 */
|
||||
.toggle-switch { position: relative; display: inline-block; width: 44px; height: 24px; }
|
||||
.toggle-switch input { display: none; }
|
||||
.toggle-slider {
|
||||
position: absolute; top: 0; left: 0; right: 0; bottom: 0;
|
||||
background: #d9d9d9; border-radius: 24px; cursor: pointer; transition: 0.3s;
|
||||
}
|
||||
.toggle-slider::before {
|
||||
content: ''; position: absolute; left: 3px; bottom: 3px; width: 18px; height: 18px;
|
||||
background: #fff; border-radius: 50%; transition: 0.3s;
|
||||
}
|
||||
input:checked + .toggle-slider { background: #52c41a; }
|
||||
input:checked + .toggle-slider::before { transform: translateX(20px); }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@@ -86,6 +106,15 @@
|
||||
</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>
|
||||
</div>
|
||||
<!-- 信息列表 -->
|
||||
<div class="info-group">
|
||||
<div class="info-row"><span class="info-label">姓名</span><span class="info-value">张三</span></div>
|
||||
@@ -97,9 +126,47 @@
|
||||
<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>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="home-indicator"></div>
|
||||
</div>
|
||||
<script>
|
||||
var isFaceVerified = false;
|
||||
|
||||
/* [交互] 切换开关:改变人脸认证状态 */
|
||||
function toggleFaceState() {
|
||||
isFaceVerified = document.getElementById('faceToggle').checked;
|
||||
updateFaceRow();
|
||||
}
|
||||
|
||||
/* [交互] 根据状态更新人脸信息行 */
|
||||
function updateFaceRow() {
|
||||
var valEl = document.getElementById('faceValue');
|
||||
var labelEl = document.getElementById('demoStateLabel');
|
||||
if (isFaceVerified) {
|
||||
valEl.style.color = '#52c41a';
|
||||
valEl.innerHTML = '已认证<i class="edit-icon">›</i>';
|
||||
labelEl.textContent = '已认证';
|
||||
} else {
|
||||
valEl.style.color = '#fa8c16';
|
||||
valEl.innerHTML = '未认证<i class="edit-icon">›</i>';
|
||||
labelEl.textContent = '未认证';
|
||||
}
|
||||
}
|
||||
|
||||
/* [交互] 点击人脸信息行:已认证→人脸详情页;未认证→人脸录入页 */
|
||||
function handleFaceClick() {
|
||||
if (isFaceVerified) {
|
||||
window.location.href = 'me-face-info.html';
|
||||
} else {
|
||||
window.location.href = 'me-face-verify.html';
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,111 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>人脸信息 | 智能餐养小程序</title>
|
||||
<style>
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
body {
|
||||
background: #2a2a2a; display: flex; justify-content: center; align-items: flex-start;
|
||||
min-height: 100vh; font-family: -apple-system, BlinkMacSystemFont, 'PingFang SC', 'Helvetica Neue', sans-serif;
|
||||
padding: 24px 0 40px;
|
||||
}
|
||||
.phone-shell {
|
||||
width: 390px; height: 844px; background: #fff; border-radius: 44px;
|
||||
box-shadow: 0 20px 60px rgba(0,0,0,0.3), inset 0 0 0 2px #e0e0e0;
|
||||
overflow: hidden; position: relative; display: flex; flex-direction: column;
|
||||
}
|
||||
.status-bar {
|
||||
height: 44px; background: #fff; display: flex; align-items: center;
|
||||
justify-content: space-between; padding: 0 24px; font-size: 12px; font-weight: 600; flex-shrink: 0; color: #333;
|
||||
}
|
||||
.status-bar .time { font-size: 15px; font-weight: 700; }
|
||||
.status-bar .icons { display: flex; gap: 6px; align-items: center; }
|
||||
.nav-bar {
|
||||
height: 44px; background: #fff; display: flex; align-items: center; padding: 0 16px;
|
||||
border-bottom: 0.5px solid #f0f0f0; flex-shrink: 0;
|
||||
}
|
||||
.nav-back { font-size: 20px; color: #333; text-decoration: none; width: 32px; }
|
||||
.nav-title { flex: 1; text-align: center; font-size: 16px; font-weight: 600; color: #333; }
|
||||
.nav-placeholder { width: 32px; }
|
||||
.page-content { flex: 1; overflow-y: auto; background: #f5f5f5; }
|
||||
.page-content::-webkit-scrollbar { display: none; }
|
||||
.home-indicator {
|
||||
height: 20px; display: flex; align-items: center; justify-content: center; background: #fff; flex-shrink: 0;
|
||||
}
|
||||
.home-indicator::after { content: ''; width: 120px; height: 5px; background: #1a1a1a; border-radius: 3px; opacity: 0.2; }
|
||||
|
||||
/* 人脸照片区域 */
|
||||
.face-photo-section {
|
||||
background: #fff; padding: 30px 16px; display: flex; flex-direction: column;
|
||||
align-items: center; margin-bottom: 8px;
|
||||
}
|
||||
.face-photo-wrap {
|
||||
width: 120px; height: 120px; border-radius: 50%;
|
||||
background: linear-gradient(135deg, #e6f7ff, #bae7ff);
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
font-size: 60px; border: 4px solid #1677ff; margin-bottom: 10px;
|
||||
position: relative;
|
||||
}
|
||||
.face-photo-badge {
|
||||
position: absolute; bottom: 2px; right: 2px; width: 28px; height: 28px;
|
||||
background: #52c41a; border-radius: 50%; display: flex; align-items: center;
|
||||
justify-content: center; font-size: 14px; color: #fff;
|
||||
border: 2px solid #fff;
|
||||
}
|
||||
|
||||
/* 信息列表 */
|
||||
.info-group { background: #fff; margin-bottom: 8px; }
|
||||
.info-row {
|
||||
display: flex; align-items: center; justify-content: space-between;
|
||||
padding: 16px; border-bottom: 0.5px solid #f5f5f5;
|
||||
}
|
||||
.info-row:last-child { border-bottom: none; }
|
||||
.info-label { font-size: 14px; color: #666; }
|
||||
.info-value { font-size: 14px; color: #333; font-weight: 500; }
|
||||
.info-value.green { color: #52c41a; }
|
||||
|
||||
/* 重新录入按钮 */
|
||||
.btn-section { padding: 24px 16px; text-align: center; }
|
||||
.btn-reenroll {
|
||||
display: inline-block; padding: 13px 40px; border: 1px solid #1677ff;
|
||||
border-radius: 22px; background: #fff; color: #1677ff;
|
||||
font-size: 15px; cursor: pointer; text-decoration: none;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="phone-shell">
|
||||
<div class="status-bar">
|
||||
<span class="time">09:41</span>
|
||||
<div class="icons"><span>📶</span><span>WiFi</span><span>🔋</span></div>
|
||||
</div>
|
||||
<div class="nav-bar">
|
||||
<a class="nav-back" href="me-account.html">‹</a>
|
||||
<span class="nav-title">人脸信息</span>
|
||||
<span class="nav-placeholder"></span>
|
||||
</div>
|
||||
<div class="page-content">
|
||||
<!-- 人脸照片 -->
|
||||
<div class="face-photo-section">
|
||||
<div class="face-photo-wrap">
|
||||
🙂
|
||||
<span class="face-photo-badge">✓</span>
|
||||
</div>
|
||||
</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">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>
|
||||
</div>
|
||||
</div>
|
||||
<div class="home-indicator"></div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,317 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>人脸认证 | 智能餐养小程序</title>
|
||||
<style>
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
body {
|
||||
background: #2a2a2a; display: flex; justify-content: center; align-items: flex-start;
|
||||
min-height: 100vh; font-family: -apple-system, BlinkMacSystemFont, 'PingFang SC', 'Helvetica Neue', sans-serif;
|
||||
padding: 24px 0 40px;
|
||||
}
|
||||
.phone-shell {
|
||||
width: 390px; height: 844px; background: #fff; border-radius: 44px;
|
||||
box-shadow: 0 20px 60px rgba(0,0,0,0.3), inset 0 0 0 2px #e0e0e0;
|
||||
overflow: hidden; position: relative; display: flex; flex-direction: column;
|
||||
}
|
||||
.status-bar {
|
||||
height: 44px; background: #fff; display: flex; align-items: center;
|
||||
justify-content: space-between; padding: 0 24px; font-size: 12px; font-weight: 600; flex-shrink: 0; color: #333;
|
||||
}
|
||||
.status-bar .time { font-size: 15px; font-weight: 700; }
|
||||
.status-bar .icons { display: flex; gap: 6px; align-items: center; }
|
||||
.nav-bar {
|
||||
height: 44px; background: #fff; display: flex; align-items: center; padding: 0 16px;
|
||||
border-bottom: 0.5px solid #f0f0f0; flex-shrink: 0;
|
||||
}
|
||||
.nav-back { font-size: 20px; color: #333; text-decoration: none; width: 32px; }
|
||||
.nav-title { flex: 1; text-align: center; font-size: 16px; font-weight: 600; color: #333; }
|
||||
.nav-placeholder { width: 32px; }
|
||||
.page-content { flex: 1; overflow-y: auto; background: #f5f5f5; }
|
||||
.page-content::-webkit-scrollbar { display: none; }
|
||||
.home-indicator {
|
||||
height: 20px; display: flex; align-items: center; justify-content: center; background: #fff; flex-shrink: 0;
|
||||
}
|
||||
.home-indicator::after { content: ''; width: 120px; height: 5px; background: #1a1a1a; border-radius: 3px; opacity: 0.2; }
|
||||
|
||||
/* 步骤指示器 */
|
||||
.step-bar {
|
||||
display: flex; align-items: center; justify-content: center; padding: 20px 40px; background: #fff;
|
||||
}
|
||||
.step-dot {
|
||||
width: 28px; height: 28px; border-radius: 50%; background: #e8e8e8;
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
font-size: 12px; color: #999; font-weight: 600;
|
||||
}
|
||||
.step-dot.active { background: #1677ff; color: #fff; }
|
||||
.step-dot.done { background: #52c41a; color: #fff; }
|
||||
.step-line { flex: 1; height: 2px; background: #e8e8e8; margin: 0 8px; }
|
||||
.step-line.done { background: #52c41a; }
|
||||
|
||||
/* 主体区域 */
|
||||
.verify-body {
|
||||
display: flex; flex-direction: column; align-items: center; padding: 20px 16px;
|
||||
}
|
||||
|
||||
/* 摄像头取景框 */
|
||||
.camera-frame {
|
||||
width: 240px; height: 320px; position: relative; margin: 0 auto 20px;
|
||||
border-radius: 50% / 40%; overflow: hidden;
|
||||
background: #1a1a1a; box-shadow: 0 0 0 4px rgba(22,119,255,0.3), 0 8px 32px rgba(0,0,0,0.2);
|
||||
}
|
||||
.camera-frame::before {
|
||||
content: ''; position: absolute; top: 0; left: 0; right: 0; bottom: 0;
|
||||
border: 2px dashed rgba(255,255,255,0.3); border-radius: inherit;
|
||||
margin: 12px; pointer-events: none;
|
||||
}
|
||||
/* 取景框四角装饰 */
|
||||
.camera-corners { position: absolute; top: 0; left: 0; right: 0; bottom: 0; pointer-events: none; }
|
||||
.camera-corner {
|
||||
position: absolute; width: 20px; height: 20px;
|
||||
border-color: #1677ff; border-style: solid; border-width: 0;
|
||||
}
|
||||
.camera-corner--tl { top: 10px; left: 10px; border-top-width: 3px; border-left-width: 3px; border-radius: 6px 0 0 0; }
|
||||
.camera-corner--tr { top: 10px; right: 10px; border-top-width: 3px; border-right-width: 3px; border-radius: 0 6px 0 0; }
|
||||
.camera-corner--bl { bottom: 10px; left: 10px; border-bottom-width: 3px; border-left-width: 3px; border-radius: 0 0 0 6px; }
|
||||
.camera-corner--br { bottom: 10px; right: 10px; border-bottom-width: 3px; border-right-width: 3px; border-radius: 0 0 6px 0; }
|
||||
|
||||
/* 人脸占位 */
|
||||
.face-placeholder {
|
||||
position: absolute; top: 50%; left: 50%; transform: translate(-50%,-50%);
|
||||
display: flex; flex-direction: column; align-items: center; gap: 8px; color: rgba(255,255,255,0.5);
|
||||
}
|
||||
.face-placeholder .face-icon { font-size: 60px; line-height: 1; }
|
||||
.face-placeholder .face-tip { font-size: 12px; }
|
||||
|
||||
/* 扫描线动画 */
|
||||
.scan-line {
|
||||
position: absolute; left: 0; right: 0; height: 2px;
|
||||
background: linear-gradient(90deg, transparent, rgba(22,119,255,0.8), transparent);
|
||||
animation: scanAnim 2s ease-in-out infinite;
|
||||
}
|
||||
@keyframes scanAnim {
|
||||
0%, 100% { top: 15%; }
|
||||
50% { top: 85%; }
|
||||
}
|
||||
|
||||
/* 提示文字 */
|
||||
.verify-tip {
|
||||
font-size: 14px; color: #666; text-align: center; margin-bottom: 24px; line-height: 1.6;
|
||||
}
|
||||
.verify-tip .icon { font-size: 18px; }
|
||||
|
||||
/* 认证按钮 */
|
||||
.btn-start {
|
||||
width: 200px; padding: 14px 0; border: none; border-radius: 24px;
|
||||
background: linear-gradient(135deg, #1677ff, #4096ff);
|
||||
color: #fff; font-size: 16px; font-weight: 600; cursor: pointer;
|
||||
box-shadow: 0 6px 20px rgba(22,119,255,0.3);
|
||||
letter-spacing: 2px; display: block; margin: 0 auto; text-align: center;
|
||||
text-decoration: none;
|
||||
}
|
||||
.btn-start:disabled {
|
||||
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;
|
||||
}
|
||||
.result-card .result-icon { font-size: 56px; line-height: 1; margin-bottom: 10px; }
|
||||
.result-card .result-title { font-size: 18px; font-weight: 700; color: #333; margin-bottom: 6px; }
|
||||
.result-card .result-desc { font-size: 13px; color: #999; margin-bottom: 16px; }
|
||||
.result-card .result-meta { display: flex; justify-content: center; gap: 20px; }
|
||||
.result-card .meta-item { text-align: center; }
|
||||
.result-card .meta-val { font-size: 14px; font-weight: 600; color: #333; }
|
||||
.result-card .meta-label { font-size: 11px; color: #999; }
|
||||
|
||||
.btn-group { display: flex; gap: 12px; justify-content: center; }
|
||||
.btn-outline {
|
||||
padding: 12px 28px; border: 1px solid #1677ff; border-radius: 22px;
|
||||
background: #fff; color: #1677ff; font-size: 14px; cursor: pointer;
|
||||
text-decoration: none; display: inline-block;
|
||||
}
|
||||
.btn-primary {
|
||||
padding: 12px 28px; border: none; border-radius: 22px;
|
||||
background: linear-gradient(135deg, #1677ff, #4096ff);
|
||||
color: #fff; font-size: 14px; cursor: pointer; font-weight: 500;
|
||||
text-decoration: none; display: inline-block;
|
||||
}
|
||||
|
||||
/* 注意事项 */
|
||||
.notice-box {
|
||||
background: #fffbe6; border: 1px solid #ffe58f; border-radius: 8px;
|
||||
padding: 12px 14px; margin-top: 16px; width: 100%;
|
||||
}
|
||||
.notice-box .notice-title { font-size: 13px; font-weight: 600; color: #d48806; margin-bottom: 6px; }
|
||||
.notice-box .notice-item { font-size: 12px; color: #8c6d1f; line-height: 1.8; padding-left: 8px; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="phone-shell">
|
||||
<div class="status-bar">
|
||||
<span class="time">09:41</span>
|
||||
<div class="icons"><span>📶</span><span>WiFi</span><span>🔋</span></div>
|
||||
</div>
|
||||
<div class="nav-bar">
|
||||
<a class="nav-back" href="me-home.html" id="btnBack">‹</a>
|
||||
<span class="nav-title">人脸认证</span>
|
||||
<span class="nav-placeholder"></span>
|
||||
</div>
|
||||
<div class="page-content">
|
||||
<!-- 步骤指示器 -->
|
||||
<div class="step-bar">
|
||||
<div class="step-dot active" id="step1">1</div>
|
||||
<div class="step-line" id="line1"></div>
|
||||
<div class="step-dot" id="step2">2</div>
|
||||
<div class="step-line" id="line2"></div>
|
||||
<div class="step-dot" id="step3">3</div>
|
||||
</div>
|
||||
|
||||
<!-- [交互] 阶段一:准备认证 -->
|
||||
<div class="verify-body" id="phasePrepare">
|
||||
<div class="camera-frame">
|
||||
<div class="camera-corners">
|
||||
<span class="camera-corner camera-corner--tl"></span>
|
||||
<span class="camera-corner camera-corner--tr"></span>
|
||||
<span class="camera-corner camera-corner--bl"></span>
|
||||
<span class="camera-corner camera-corner--br"></span>
|
||||
</div>
|
||||
<div class="face-placeholder">
|
||||
<span class="face-icon">👤</span>
|
||||
<span class="face-tip">请将面部置于取景框内</span>
|
||||
</div>
|
||||
</div>
|
||||
<p class="verify-tip">
|
||||
<span class="icon">💡</span> 请确保光线充足、面部无遮挡<br>按提示完成眨眼、张嘴等动作
|
||||
</p>
|
||||
<!-- [交互] 点击开始人脸认证采集 -->
|
||||
<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">
|
||||
<span class="camera-corner camera-corner--tl" style="border-color:#52c41a;"></span>
|
||||
<span class="camera-corner camera-corner--tr" style="border-color:#52c41a;"></span>
|
||||
<span class="camera-corner camera-corner--bl" style="border-color:#52c41a;"></span>
|
||||
<span class="camera-corner camera-corner--br" style="border-color:#52c41a;"></span>
|
||||
</div>
|
||||
<div class="scan-line" id="scanLine"></div>
|
||||
<div class="face-placeholder">
|
||||
<span class="face-icon">🙂</span>
|
||||
<span class="face-tip" id="captureTip">正在采集中…</span>
|
||||
</div>
|
||||
</div>
|
||||
<p class="verify-tip" style="color:#1677ff;font-weight:500;">
|
||||
<span class="icon">📷</span> 请保持面部稳定,不要移动
|
||||
</p>
|
||||
<!-- [交互] 模拟采集进度,完成后自动跳转结果 -->
|
||||
<div style="width:200px;height:4px;background:#e8e8e8;border-radius:2px;margin:0 auto 20px;overflow:hidden;">
|
||||
<div id="progressBar" style="width:0%;height:100%;background:linear-gradient(90deg,#1677ff,#52c41a);border-radius:2px;transition:width 0.3s;"></div>
|
||||
</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-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>
|
||||
</div>
|
||||
<div class="btn-group">
|
||||
<!-- [交互] 点击重新采集人脸 -->
|
||||
<button class="btn-outline" onclick="redoVerify()">重新采集</button>
|
||||
<!-- [交互] 点击返回账号信息页 -->
|
||||
<a class="btn-primary" href="me-account.html">完成</a>
|
||||
</div>
|
||||
<div class="notice-box">
|
||||
<div class="notice-title">📌 温馨提示</div>
|
||||
<div class="notice-item">• 人脸信息仅用于身份核验,加密存储不外泄</div>
|
||||
<div class="notice-item">• 如需更新人脸信息,可在"账号信息→人脸信息"中重新录入</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="home-indicator"></div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
/* [交互] 开始认证:切换到采集阶段,模拟采集进度 */
|
||||
function startVerify() {
|
||||
document.getElementById('phasePrepare').style.display = 'none';
|
||||
document.getElementById('phaseCapturing').style.display = 'flex';
|
||||
document.getElementById('step1').classList.remove('active');
|
||||
document.getElementById('step1').classList.add('done');
|
||||
document.getElementById('step1').textContent = '✓';
|
||||
document.getElementById('step2').classList.add('active');
|
||||
document.getElementById('line1').classList.add('done');
|
||||
|
||||
/* 模拟采集进度 0→100%,约3秒完成 */
|
||||
var bar = document.getElementById('progressBar');
|
||||
var tip = document.getElementById('captureTip');
|
||||
var tips = ['正在采集中…', '请眨眼…', '请张嘴…', '请缓慢转头…'];
|
||||
var idx = 0;
|
||||
var p = 0;
|
||||
var timer = setInterval(function() {
|
||||
p += Math.random() * 12 + 4;
|
||||
if (p >= 100) {
|
||||
p = 100; bar.style.width = '100%';
|
||||
clearInterval(timer);
|
||||
tip.textContent = '采集完成 ✓';
|
||||
setTimeout(showResult, 500);
|
||||
} else {
|
||||
bar.style.width = p + '%';
|
||||
if (p > 25 && idx === 0) { tip.textContent = tips[1]; idx++; }
|
||||
if (p > 50 && idx === 1) { tip.textContent = tips[2]; idx++; }
|
||||
if (p > 75 && idx === 2) { tip.textContent = tips[3]; idx++; }
|
||||
}
|
||||
}, 180);
|
||||
}
|
||||
|
||||
/* [交互] 显示认证结果 */
|
||||
function showResult() {
|
||||
document.getElementById('phaseCapturing').style.display = 'none';
|
||||
document.getElementById('phaseResult').style.display = 'flex';
|
||||
document.getElementById('step2').classList.remove('active');
|
||||
document.getElementById('step2').classList.add('done');
|
||||
document.getElementById('step2').textContent = '✓';
|
||||
document.getElementById('step3').classList.add('active');
|
||||
document.getElementById('line2').classList.add('done');
|
||||
|
||||
/* 模拟结果数据 */
|
||||
var now = new Date();
|
||||
document.getElementById('metaTime').textContent =
|
||||
now.getFullYear()+'-'+
|
||||
String(now.getMonth()+1).padStart(2,'0')+'-'+
|
||||
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)) + '%';
|
||||
}
|
||||
|
||||
/* [交互] 重新采集:回到准备阶段 */
|
||||
function redoVerify() {
|
||||
if (!confirm('确定重新采集人脸信息吗?')) return;
|
||||
document.getElementById('phaseResult').style.display = 'none';
|
||||
document.getElementById('phasePrepare').style.display = 'flex';
|
||||
/* 重置步骤条 */
|
||||
['step1','step2','step3'].forEach(function(id) {
|
||||
var el = document.getElementById(id);
|
||||
el.classList.remove('done','active');
|
||||
el.textContent = id === 'step1' ? '1' : id === 'step2' ? '2' : '3';
|
||||
});
|
||||
document.getElementById('step1').classList.add('active');
|
||||
document.getElementById('line1').classList.remove('done');
|
||||
document.getElementById('line2').classList.remove('done');
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -53,6 +53,16 @@
|
||||
}
|
||||
.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;
|
||||
text-decoration: none; vertical-align: middle;
|
||||
}
|
||||
.face-tag--verified { background: rgba(82, 196, 26, 0.25); color: #d9f7be; }
|
||||
.face-tag--unverified {
|
||||
background: rgba(250, 140, 22, 0.25); color: #ffd591;
|
||||
}
|
||||
.user-arrow {
|
||||
width: 28px; display: flex; align-items: center; justify-content: center;
|
||||
font-size: 18px; opacity: 0.7; flex-shrink: 0; cursor: pointer;
|
||||
@@ -112,10 +122,12 @@
|
||||
<div class="user-meta">
|
||||
<div class="user-name-row">
|
||||
<span class="user-name">张三</span>
|
||||
<span class="vip-badge">黄金会员</span>
|
||||
<!-- [交互] 未认证时点击跳转人脸录入页;已认证时切换为 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">
|
||||
<span class="vip-badge">黄金会员</span>
|
||||
<span>积分 <b>1,280</b></span>
|
||||
<span>余额 <b>¥368.50</b></span>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,181 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>交易详情 | 智能餐养小程序</title>
|
||||
<style>
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
body { background: #2a2a2a; display: flex; justify-content: center; align-items: flex-start; min-height: 100vh; font-family: -apple-system, BlinkMacSystemFont, 'PingFang SC', 'Helvetica Neue', sans-serif; padding: 24px 0 40px; }
|
||||
.phone-shell { width: 390px; height: 844px; background: #fff; border-radius: 44px; box-shadow: 0 20px 60px rgba(0,0,0,0.3), inset 0 0 0 2px #e0e0e0; overflow: hidden; position: relative; display: flex; flex-direction: column; }
|
||||
.status-bar { height: 44px; background: #fff; display: flex; align-items: center; justify-content: space-between; padding: 0 24px; font-size: 12px; font-weight: 600; flex-shrink: 0; }
|
||||
.status-bar .time { font-size: 15px; font-weight: 700; }
|
||||
.status-bar .icons { display: flex; gap: 6px; align-items: center; }
|
||||
.nav-bar { height: 44px; background: #fff; display: flex; align-items: center; padding: 0 16px; border-bottom: 0.5px solid #f0f0f0; flex-shrink: 0; position: relative; }
|
||||
.nav-bar .back { font-size: 22px; color: #1677ff; cursor: pointer; text-decoration: none; line-height: 1; }
|
||||
.nav-bar .title { position: absolute; left: 50%; transform: translateX(-50%); font-size: 17px; font-weight: 600; }
|
||||
.page-content { flex: 1; overflow-y: auto; background: #f5f5f5; }
|
||||
.page-content::-webkit-scrollbar { display: none; }
|
||||
|
||||
/* 交易头部 */
|
||||
.detail-header { background: #fff; padding: 24px 16px; text-align: center; }
|
||||
.detail-icon-wrap { width: 56px; height: 56px; border-radius: 16px; display: flex; align-items: center; justify-content: center; margin: 0 auto 12px; }
|
||||
.detail-icon-wrap.food { background: #e6f7ff; }
|
||||
.detail-icon-wrap.recharge { background: #f6ffed; }
|
||||
.detail-name { font-size: 16px; font-weight: 500; color: #333; margin-bottom: 8px; }
|
||||
.detail-amount-big { font-size: 32px; font-weight: 700; letter-spacing: -1px; }
|
||||
.detail-amount-big.expense { color: #333; }
|
||||
.detail-amount-big.income { color: #52c41a; }
|
||||
|
||||
/* 信息卡片 */
|
||||
.info-card { background: #fff; margin: 12px 16px; border-radius: 12px; overflow: hidden; }
|
||||
.info-card .card-title { font-size: 13px; font-weight: 600; color: #333; padding: 14px 16px 8px; }
|
||||
.info-row { display: flex; padding: 10px 16px; font-size: 14px; border-bottom: 0.5px solid #f5f5f5; }
|
||||
.info-row:last-child { border-bottom: none; }
|
||||
.info-label { width: 80px; color: #999; flex-shrink: 0; }
|
||||
.info-value { flex: 1; color: #333; text-align: right; }
|
||||
.info-value.success { color: #52c41a; }
|
||||
|
||||
.home-indicator { height: 34px; display: flex; align-items: flex-end; justify-content: center; padding-bottom: 8px; background: #f5f5f5; flex-shrink: 0; }
|
||||
.home-indicator::after { content: ''; width: 134px; height: 5px; background: #000; border-radius: 3px; opacity: 0.2; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="phone-shell">
|
||||
<!-- 状态栏 -->
|
||||
<div class="status-bar">
|
||||
<span class="time">09:41</span>
|
||||
<div class="icons">
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none"><path d="M2 9l10-7 10 7v11a2 2 0 01-2 2h-4v-6H8v6H4a2 2 0 01-2-2V9z" fill="#333"/></svg>
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none"><path d="M1 9l2-2c5.5-5.5 14-5.5 19.5 0l2 2M5 13l2-2c3.5-3.5 9-3.5 12.5 0l2 2M9 17l3-3 3 3" stroke="#333" stroke-width="2"/></svg>
|
||||
<svg width="20" height="12" viewBox="0 0 20 12"><rect x="0" y="1" width="16" height="10" rx="2" stroke="#333" fill="none" stroke-width="1.2"/><rect x="2" y="3" width="10" height="6" rx="1" fill="#333"/><path d="M17 4v4a2 2 0 002-2v0a2 2 0 00-2-2z" fill="#333"/></svg>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 导航栏 -->
|
||||
<div class="nav-bar">
|
||||
<a class="back" href="me-wallet.html">‹</a>
|
||||
<span class="title">交易详情</span>
|
||||
</div>
|
||||
|
||||
<!-- 页面内容 -->
|
||||
<div class="page-content">
|
||||
<!-- 交易头部 -->
|
||||
<div class="detail-header">
|
||||
<div class="detail-icon-wrap" id="detailIcon">
|
||||
<svg width="28" height="28" viewBox="0 0 24 24" fill="none"><path d="M18 8h1a4 4 0 010 8h-1M2 8h16v9a4 4 0 01-4 4H6a4 4 0 01-4-4V8zm4-4h8v4H6V4z" stroke="#1677ff" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
||||
</div>
|
||||
<div class="detail-name" id="detailName">午餐消费</div>
|
||||
<div class="detail-amount-big expense" id="detailAmount">-¥28.50</div>
|
||||
</div>
|
||||
|
||||
<!-- 交易信息 -->
|
||||
<div class="info-card">
|
||||
<div class="card-title">交易信息</div>
|
||||
<div class="info-row">
|
||||
<span class="info-label">交易时间</span>
|
||||
<span class="info-value" id="infoTime">2026年8月3日 11:32:15</span>
|
||||
</div>
|
||||
<div class="info-row">
|
||||
<span class="info-label">交易单号</span>
|
||||
<span class="info-value" id="infoOrderNo">NM20260803113215001</span>
|
||||
</div>
|
||||
<div class="info-row">
|
||||
<span class="info-label">支付流水号</span>
|
||||
<span class="info-value" id="infoPayNo">WX2026080311321500123456</span>
|
||||
</div>
|
||||
<div class="info-row">
|
||||
<span class="info-label">交易类型</span>
|
||||
<span class="info-value" id="infoType">消费支出</span>
|
||||
</div>
|
||||
<div class="info-row" id="merchantRow" style="display:none">
|
||||
<span class="info-label">商户名称</span>
|
||||
<span class="info-value" id="infoMerchant">二号食堂</span>
|
||||
</div>
|
||||
<div class="info-row">
|
||||
<span class="info-label">支付方式</span>
|
||||
<span class="info-value" id="infoMethod">微信支付</span>
|
||||
</div>
|
||||
<div class="info-row">
|
||||
<span class="info-label">交易前余额</span>
|
||||
<span class="info-value" id="infoBefore">¥256.50</span>
|
||||
</div>
|
||||
<div class="info-row">
|
||||
<span class="info-label">交易后余额</span>
|
||||
<span class="info-value" id="infoAfter">¥228.00</span>
|
||||
</div>
|
||||
<div class="info-row">
|
||||
<span class="info-label">交易状态</span>
|
||||
<span class="info-value success" id="infoStatus">交易成功</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 底部指示器 -->
|
||||
<div class="home-indicator"></div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
/* 从 URL hash 解析交易参数 */
|
||||
(function() {
|
||||
var hash = window.location.hash.replace('#', '');
|
||||
if (!hash) return;
|
||||
var params = {};
|
||||
hash.split('&').forEach(function(pair) {
|
||||
var parts = pair.split('=');
|
||||
if (parts.length === 2) {
|
||||
params[decodeURIComponent(parts[0])] = decodeURIComponent(parts[1]);
|
||||
}
|
||||
});
|
||||
|
||||
var type = params.type || 'meal';
|
||||
|
||||
/* 类型图标 */
|
||||
var iconWrap = document.getElementById('detailIcon');
|
||||
var iconSvg = iconWrap.querySelector('svg');
|
||||
if (type === 'recharge') {
|
||||
iconWrap.className = 'detail-icon-wrap recharge';
|
||||
iconSvg.innerHTML = '<circle cx="12" cy="12" r="9" stroke="#52c41a" stroke-width="1.5"/><path d="M12 8v8M8 12h8" stroke="#52c41a" stroke-width="1.5" stroke-linecap="round"/>';
|
||||
}
|
||||
|
||||
/* 交易名称 */
|
||||
if (params.name) document.getElementById('detailName').textContent = params.name;
|
||||
|
||||
/* 金额 */
|
||||
var amountEl = document.getElementById('detailAmount');
|
||||
if (params.amount) {
|
||||
amountEl.textContent = params.amount;
|
||||
amountEl.className = 'detail-amount-big ' + (params.amount.indexOf('+') === 0 ? 'income' : 'expense');
|
||||
}
|
||||
|
||||
/* 时间 */
|
||||
if (params.time) document.getElementById('infoTime').textContent = params.time;
|
||||
|
||||
/* 单号 */
|
||||
if (params.orderNo) document.getElementById('infoOrderNo').textContent = params.orderNo;
|
||||
|
||||
/* 支付流水号 */
|
||||
if (params.payNo) document.getElementById('infoPayNo').textContent = params.payNo;
|
||||
|
||||
/* 交易类型文本 */
|
||||
if (type === 'recharge') {
|
||||
document.getElementById('infoType').textContent = '余额充值';
|
||||
} else {
|
||||
document.getElementById('infoType').textContent = '消费支出';
|
||||
/* 消费类型显示商户名称 */
|
||||
if (params.merchant) {
|
||||
document.getElementById('infoMerchant').textContent = params.merchant;
|
||||
document.getElementById('merchantRow').style.display = 'flex';
|
||||
}
|
||||
}
|
||||
|
||||
/* 支付方式 */
|
||||
if (params.payMethod) document.getElementById('infoMethod').textContent = params.payMethod;
|
||||
|
||||
/* 余额 */
|
||||
if (params.balance) document.getElementById('infoAfter').textContent = '¥' + params.balance;
|
||||
if (params.before) document.getElementById('infoBefore').textContent = '¥' + params.before;
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -25,14 +25,25 @@
|
||||
.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; }
|
||||
.transaction-list { background: #fff; margin: 0 16px; border-radius: 10px; overflow: hidden; }
|
||||
.transaction-item { display: flex; align-items: center; justify-content: space-between; padding: 14px 16px; border-bottom: 0.5px solid #f5f5f5; }
|
||||
.transaction-item:last-child { border-bottom: none; }
|
||||
.transaction-info .transaction-name { font-size: 15px; color: #333; }
|
||||
.transaction-info .transaction-time { font-size: 12px; color: #999; margin-top: 4px; }
|
||||
.transaction-amount { font-size: 15px; font-weight: 500; }
|
||||
.transaction-amount.expense { color: #333; }
|
||||
.transaction-amount.income { color: #52c41a; }
|
||||
/* 月份分组 */
|
||||
.month-group { margin: 0 16px 4px; }
|
||||
.month-label { font-size: 13px; color: #999; padding: 12px 0 8px; }
|
||||
/* 明细列表 */
|
||||
.detail-list { background: #fff; border-radius: 10px; overflow: hidden; }
|
||||
.detail-item { display: flex; align-items: center; padding: 14px 16px; border-bottom: 0.5px solid #f5f5f5; cursor: pointer; transition: background 0.15s; }
|
||||
.detail-item:active { background: #f5f5f5; }
|
||||
.detail-item:last-child { border-bottom: none; }
|
||||
.detail-icon { width: 36px; height: 36px; border-radius: 8px; display: flex; align-items: center; justify-content: center; flex-shrink: 0; margin-right: 12px; }
|
||||
.detail-icon.food { background: #e6f7ff; }
|
||||
.detail-icon.recharge { background: #f6ffed; }
|
||||
.detail-info { flex: 1; min-width: 0; }
|
||||
.detail-name { font-size: 15px; color: #333; }
|
||||
.detail-time { font-size: 12px; color: #999; margin-top: 4px; }
|
||||
.detail-right { text-align: right; flex-shrink: 0; margin-left: 12px; }
|
||||
.detail-amount { font-size: 15px; font-weight: 500; }
|
||||
.detail-amount.expense { color: #333; }
|
||||
.detail-amount.income { color: #52c41a; }
|
||||
.detail-balance { font-size: 12px; color: #999; margin-top: 4px; }
|
||||
.home-indicator { height: 34px; display: flex; align-items: flex-end; justify-content: center; padding-bottom: 8px; background: #f5f5f5; flex-shrink: 0; }
|
||||
.home-indicator::after { content: ''; width: 134px; height: 5px; background: #000; border-radius: 3px; opacity: 0.2; }
|
||||
</style>
|
||||
@@ -67,36 +78,170 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 最近交易 -->
|
||||
<div class="section-title">最近交易</div>
|
||||
<div class="transaction-list">
|
||||
<div class="transaction-item">
|
||||
<div class="transaction-info">
|
||||
<div class="transaction-name">午餐消费</div>
|
||||
<div class="transaction-time">今天 11:32</div>
|
||||
<!-- 余额明细 -->
|
||||
<div class="section-title">余额明细</div>
|
||||
|
||||
<!-- 2026年8月 -->
|
||||
<div class="month-group">
|
||||
<div class="month-label">2026年8月</div>
|
||||
<div class="detail-list">
|
||||
<div class="detail-item">
|
||||
<div class="detail-icon food">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none"><path d="M18 8h1a4 4 0 010 8h-1M2 8h16v9a4 4 0 01-4 4H6a4 4 0 01-4-4V8zm4-4h8v4H6V4z" stroke="#1677ff" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
||||
</div>
|
||||
<div class="detail-info">
|
||||
<div class="detail-name">午餐消费</div>
|
||||
<div class="detail-time">8月3日 11:32</div>
|
||||
</div>
|
||||
<div class="detail-right">
|
||||
<div class="detail-amount expense">-¥28.50</div>
|
||||
<div class="detail-balance">余额 ¥228.00</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="detail-item">
|
||||
<div class="detail-icon food">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none"><path d="M18 8h1a4 4 0 010 8h-1M2 8h16v9a4 4 0 01-4 4H6a4 4 0 01-4-4V8zm4-4h8v4H6V4z" stroke="#1677ff" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
||||
</div>
|
||||
<div class="detail-info">
|
||||
<div class="detail-name">早餐消费</div>
|
||||
<div class="detail-time">8月3日 07:45</div>
|
||||
</div>
|
||||
<div class="detail-right">
|
||||
<div class="detail-amount expense">-¥15.00</div>
|
||||
<div class="detail-balance">余额 ¥256.50</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="detail-item">
|
||||
<div class="detail-icon food">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none"><path d="M18 8h1a4 4 0 010 8h-1M2 8h16v9a4 4 0 01-4 4H6a4 4 0 01-4-4V8zm4-4h8v4H6V4z" stroke="#1677ff" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
||||
</div>
|
||||
<div class="detail-info">
|
||||
<div class="detail-name">午餐消费</div>
|
||||
<div class="detail-time">8月1日 12:10</div>
|
||||
</div>
|
||||
<div class="detail-right">
|
||||
<div class="detail-amount expense">-¥32.00</div>
|
||||
<div class="detail-balance">余额 ¥271.50</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="detail-item">
|
||||
<div class="detail-icon recharge">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none"><circle cx="12" cy="12" r="9" stroke="#52c41a" stroke-width="1.5"/><path d="M12 8v8M8 12h8" stroke="#52c41a" stroke-width="1.5" stroke-linecap="round"/></svg>
|
||||
</div>
|
||||
<div class="detail-info">
|
||||
<div class="detail-name">充值</div>
|
||||
<div class="detail-time">8月1日 09:00</div>
|
||||
</div>
|
||||
<div class="detail-right">
|
||||
<div class="detail-amount income">+¥200.00</div>
|
||||
<div class="detail-balance">余额 ¥303.50</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="transaction-amount expense">-¥28.5</div>
|
||||
</div>
|
||||
<div class="transaction-item">
|
||||
<div class="transaction-info">
|
||||
<div class="transaction-name">早餐消费</div>
|
||||
<div class="transaction-time">今天 07:45</div>
|
||||
</div>
|
||||
|
||||
<!-- 2026年7月 -->
|
||||
<div class="month-group">
|
||||
<div class="month-label">2026年7月</div>
|
||||
<div class="detail-list">
|
||||
<div class="detail-item">
|
||||
<div class="detail-icon food">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none"><path d="M18 8h1a4 4 0 010 8h-1M2 8h16v9a4 4 0 01-4 4H6a4 4 0 01-4-4V8zm4-4h8v4H6V4z" stroke="#1677ff" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
||||
</div>
|
||||
<div class="detail-info">
|
||||
<div class="detail-name">午餐消费</div>
|
||||
<div class="detail-time">7月31日 11:45</div>
|
||||
</div>
|
||||
<div class="detail-right">
|
||||
<div class="detail-amount expense">-¥35.00</div>
|
||||
<div class="detail-balance">余额 ¥103.50</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="detail-item">
|
||||
<div class="detail-icon food">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none"><path d="M18 8h1a4 4 0 010 8h-1M2 8h16v9a4 4 0 01-4 4H6a4 4 0 01-4-4V8zm4-4h8v4H6V4z" stroke="#1677ff" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
||||
</div>
|
||||
<div class="detail-info">
|
||||
<div class="detail-name">晚餐消费</div>
|
||||
<div class="detail-time">7月30日 18:20</div>
|
||||
</div>
|
||||
<div class="detail-right">
|
||||
<div class="detail-amount expense">-¥42.00</div>
|
||||
<div class="detail-balance">余额 ¥138.50</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="detail-item">
|
||||
<div class="detail-icon food">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none"><path d="M18 8h1a4 4 0 010 8h-1M2 8h16v9a4 4 0 01-4 4H6a4 4 0 01-4-4V8zm4-4h8v4H6V4z" stroke="#1677ff" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
||||
</div>
|
||||
<div class="detail-info">
|
||||
<div class="detail-name">早餐消费</div>
|
||||
<div class="detail-time">7月30日 07:30</div>
|
||||
</div>
|
||||
<div class="detail-right">
|
||||
<div class="detail-amount expense">-¥12.00</div>
|
||||
<div class="detail-balance">余额 ¥180.50</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="detail-item">
|
||||
<div class="detail-icon recharge">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none"><circle cx="12" cy="12" r="9" stroke="#52c41a" stroke-width="1.5"/><path d="M12 8v8M8 12h8" stroke="#52c41a" stroke-width="1.5" stroke-linecap="round"/></svg>
|
||||
</div>
|
||||
<div class="detail-info">
|
||||
<div class="detail-name">充值</div>
|
||||
<div class="detail-time">7月28日 10:15</div>
|
||||
</div>
|
||||
<div class="detail-right">
|
||||
<div class="detail-amount income">+¥100.00</div>
|
||||
<div class="detail-balance">余额 ¥192.50</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="transaction-amount expense">-¥15.0</div>
|
||||
</div>
|
||||
<div class="transaction-item">
|
||||
<div class="transaction-info">
|
||||
<div class="transaction-name">充值</div>
|
||||
<div class="transaction-time">昨天</div>
|
||||
</div>
|
||||
|
||||
<!-- 2026年6月 -->
|
||||
<div class="month-group">
|
||||
<div class="month-label">2026年6月</div>
|
||||
<div class="detail-list">
|
||||
<div class="detail-item">
|
||||
<div class="detail-icon food">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none"><path d="M18 8h1a4 4 0 010 8h-1M2 8h16v9a4 4 0 01-4 4H6a4 4 0 01-4-4V8zm4-4h8v4H6V4z" stroke="#1677ff" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
||||
</div>
|
||||
<div class="detail-info">
|
||||
<div class="detail-name">午餐消费</div>
|
||||
<div class="detail-time">6月30日 12:00</div>
|
||||
</div>
|
||||
<div class="detail-right">
|
||||
<div class="detail-amount expense">-¥28.00</div>
|
||||
<div class="detail-balance">余额 ¥92.50</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="transaction-amount income">+¥100.0</div>
|
||||
</div>
|
||||
<div class="transaction-item">
|
||||
<div class="transaction-info">
|
||||
<div class="transaction-name">午餐消费</div>
|
||||
<div class="transaction-time">昨天</div>
|
||||
<div class="detail-item">
|
||||
<div class="detail-icon food">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none"><path d="M18 8h1a4 4 0 010 8h-1M2 8h16v9a4 4 0 01-4 4H6a4 4 0 01-4-4V8zm4-4h8v4H6V4z" stroke="#1677ff" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
||||
</div>
|
||||
<div class="detail-info">
|
||||
<div class="detail-name">早餐消费</div>
|
||||
<div class="detail-time">6月29日 08:00</div>
|
||||
</div>
|
||||
<div class="detail-right">
|
||||
<div class="detail-amount expense">-¥10.00</div>
|
||||
<div class="detail-balance">余额 ¥120.50</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="detail-item">
|
||||
<div class="detail-icon recharge">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none"><circle cx="12" cy="12" r="9" stroke="#52c41a" stroke-width="1.5"/><path d="M12 8v8M8 12h8" stroke="#52c41a" stroke-width="1.5" stroke-linecap="round"/></svg>
|
||||
</div>
|
||||
<div class="detail-info">
|
||||
<div class="detail-name">充值</div>
|
||||
<div class="detail-time">6月25日 14:30</div>
|
||||
</div>
|
||||
<div class="detail-right">
|
||||
<div class="detail-amount income">+¥50.00</div>
|
||||
<div class="detail-balance">余额 ¥130.50</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="transaction-amount expense">-¥35.0</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -104,5 +249,68 @@
|
||||
<!-- 底部指示器 -->
|
||||
<div class="home-indicator"></div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
/* 明细条目点击跳转至交易详情页 */
|
||||
(function() {
|
||||
var items = document.querySelectorAll('.detail-item');
|
||||
items.forEach(function(item, index) {
|
||||
item.addEventListener('click', function() {
|
||||
var name = item.querySelector('.detail-name').textContent;
|
||||
var amount = item.querySelector('.detail-amount').textContent;
|
||||
var shortTime = item.querySelector('.detail-time').textContent;
|
||||
var balance = item.querySelector('.detail-balance').textContent.replace('余额 ', '').replace('¥', '');
|
||||
var icon = item.querySelector('.detail-icon');
|
||||
var type = icon.classList.contains('recharge') ? 'recharge' : 'meal';
|
||||
|
||||
/* 从月份分组标签提取年份,拼接完整时间 */
|
||||
var monthGroup = item.closest('.month-group');
|
||||
var monthLabel = monthGroup.querySelector('.month-label').textContent;
|
||||
var year = monthLabel.match(/\d{4}/)[0];
|
||||
var timeMatch = shortTime.match(/(\d+)月(\d+)日\s+(\d+:\d+)/);
|
||||
var sec = String(index * 7 % 60).padStart(2, '0');
|
||||
var fullTime = year + '年' + timeMatch[1] + '月' + timeMatch[2] + '日 ' + timeMatch[3] + ':' + sec;
|
||||
|
||||
/* 计算交易前余额 */
|
||||
var amountNum = parseFloat(amount.replace(/[^0-9.-]/g, ''));
|
||||
var balanceNum = parseFloat(balance.replace(/[^0-9.]/g, ''));
|
||||
var beforeNum = type === 'recharge' ? (balanceNum - amountNum) : (balanceNum - amountNum);
|
||||
var before = beforeNum.toFixed(2);
|
||||
|
||||
/* 生成单号 */
|
||||
var now = new Date();
|
||||
var orderNo = 'NM' + now.getFullYear() +
|
||||
String(now.getMonth() + 1).padStart(2, '0') +
|
||||
String(now.getDate()).padStart(2, '0') +
|
||||
String(now.getHours()).padStart(2, '0') +
|
||||
String(now.getMinutes()).padStart(2, '0') +
|
||||
String(now.getSeconds()).padStart(2, '0') +
|
||||
String(index).padStart(3, '0');
|
||||
|
||||
/* 支付方式:消费用微信支付,充值交替使用不同方式 */
|
||||
var payMethods = ['微信支付', '现金支付', '微信支付'];
|
||||
var payMethod = type === 'meal' ? '微信支付' : payMethods[index % payMethods.length];
|
||||
|
||||
var params = [
|
||||
'type=' + encodeURIComponent(type),
|
||||
'name=' + encodeURIComponent(name),
|
||||
'amount=' + encodeURIComponent(amount),
|
||||
'time=' + encodeURIComponent(fullTime),
|
||||
'balance=' + encodeURIComponent(balance),
|
||||
'before=' + encodeURIComponent(before),
|
||||
'orderNo=' + encodeURIComponent(orderNo),
|
||||
'payMethod=' + encodeURIComponent(payMethod)
|
||||
];
|
||||
|
||||
/* 消费类型添加商户名称 */
|
||||
if (type === 'meal') {
|
||||
params.push('merchant=' + encodeURIComponent('二号食堂'));
|
||||
}
|
||||
|
||||
window.location.href = 'me-wallet-detail.html#' + params.join('&');
|
||||
});
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user