init: 微信支付 Native 页面 (Express + JSON 存储)
This commit is contained in:
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
Reference in New Issue
Block a user