init: 微信支付 Native 页面 (Express + JSON 存储)

This commit is contained in:
2026-07-12 14:44:44 +08:00
commit d46977be14
13 changed files with 2392 additions and 0 deletions
+25
View File
@@ -0,0 +1,25 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>微信支付 - 商品列表</title>
<link rel="stylesheet" href="/css/style.css">
</head>
<body>
<div class="container">
<h1>📦 商品列表</h1>
<div class="product-list">
<% products.forEach(product => { %>
<div class="product-card">
<h2><%= product.name %></h2>
<p class="price">¥ <%= (product.price / 100).toFixed(2) %></p>
<p class="desc"><%= product.desc %></p>
<a href="/pay/create/<%= product.id %>" class="btn">立即购买</a>
</div>
<% }) %>
</div>
<a href="/pay/orders" class="btn nav-btn">📋 订单记录</a>
</div>
</body>
</html>
+46
View File
@@ -0,0 +1,46 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>订单记录</title>
<link rel="stylesheet" href="/css/style.css">
</head>
<body>
<div class="container">
<h1>📋 订单记录</h1>
<div class="orders-card">
<% if (orders.length === 0) { %>
<p class="empty">暂无订单</p>
<% } else { %>
<table class="orders-table">
<thead>
<tr>
<th>订单号</th>
<th>商品</th>
<th>金额</th>
<th>状态</th>
<th>时间</th>
</tr>
</thead>
<tbody>
<% orders.forEach(order => { %>
<tr>
<td class="order-id" title="<%= order.orderId %>"><%= order.orderId.substring(0, 12) %>...</td>
<td><%= order.productName %></td>
<td>¥ <%= (order.totalFee / 100).toFixed(2) %></td>
<td>
<% const statusMap = { CREATING: '创建中', PENDING: '待支付', SUCCESS: '已支付', FAILED: '失败' }; %>
<span class="badge badge-<%= order.status.toLowerCase() %>"><%= statusMap[order.status] || order.status %></span>
</td>
<td><%= new Date(order.createdAt).toLocaleString() %></td>
</tr>
<% }) %>
</tbody>
</table>
<% } %>
</div>
<a href="/" class="btn nav-btn">← 返回首页</a>
</div>
</body>
</html>
+59
View File
@@ -0,0 +1,59 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>微信支付 - 扫码支付</title>
<link rel="stylesheet" href="/css/style.css">
</head>
<body>
<div class="container">
<% if (error) { %>
<div class="error-card">
<h1>❌ 下单失败</h1>
<p><%= error %></p>
<a href="/" class="btn">返回重试</a>
</div>
<% } else { %>
<div class="pay-card">
<h1>⚡ 微信扫码支付</h1>
<div class="order-info">
<p>订单号: <span><%= order.orderId %></span></p>
<p>商品: <span><%= order.productName %></span></p>
<p>金额: <span>¥ <%= (order.totalFee / 100).toFixed(2) %></span></p>
</div>
<div class="qrcode-wrapper">
<img src="<%= qrDataUrl %>" alt="支付二维码">
<p class="hint">请使用微信扫描二维码支付</p>
</div>
<div id="status" class="status pending">等待支付...</div>
<a href="/" class="btn btn-back">返回首页</a>
</div>
<% } %>
</div>
<script>
<% if (!error) { %>
const orderId = '<%= order.orderId %>';
const checkStatus = () => {
fetch('/pay/status/' + orderId)
.then(r => r.json())
.then(data => {
const el = document.getElementById('status');
if (data.status === 'SUCCESS') {
el.className = 'status success';
el.textContent = '✅ 支付成功!';
clearInterval(timer);
setTimeout(() => { window.location.href = '/pay/success/' + orderId; }, 1500);
} else if (data.status === 'FAILED') {
el.className = 'status failed';
el.textContent = '❌ 支付失败';
clearInterval(timer);
}
});
};
const timer = setInterval(checkStatus, 2000);
<% } %>
</script>
</body>
</html>
+22
View File
@@ -0,0 +1,22 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>支付成功</title>
<link rel="stylesheet" href="/css/style.css">
</head>
<body>
<div class="container">
<div class="success-card">
<h1>✅ 支付成功</h1>
<div class="order-info">
<p>订单号: <span><%= order.orderId %></span></p>
<p>商品: <span><%= order.productName %></span></p>
<p>金额: <span>¥ <%= (order.totalFee / 100).toFixed(2) %></span></p>
</div>
<a href="/" class="btn">继续购物</a>
</div>
</div>
</body>
</html>