ai_v/templates/orders.html

149 lines
7.1 KiB
HTML
Raw Normal View History

{% extends "base.html" %}
{% block title %}全员充值记录 - 管理后台{% endblock %}
{% block content %}
<div class="flex-1 overflow-y-auto p-8 relative">
<div class="max-w-7xl mx-auto space-y-8">
<!-- 头部 -->
<div class="flex items-center justify-between">
<div class="space-y-1">
<h1 class="text-3xl font-black text-slate-900 tracking-tight">全员充值记录</h1>
<p class="text-slate-500 font-bold text-sm flex items-center gap-2">
<i data-lucide="shield-check" class="w-4 h-4"></i>
管理和查询系统内所有用户的充值情况
</p>
</div>
<div class="flex gap-4">
<div class="relative">
<input type="text" id="orderSearch" placeholder="搜索手机号/订单号..." class="pl-10 pr-4 py-2 bg-white border border-slate-200 rounded-xl text-sm focus:ring-2 focus:ring-indigo-500 outline-none transition-all w-64">
<i data-lucide="search" class="w-4 h-4 absolute left-3 top-1/2 -translate-y-1/2 text-slate-400"></i>
</div>
<button onclick="loadOrders()" class="w-10 h-10 bg-white border border-slate-200 rounded-xl flex items-center justify-center text-slate-500 hover:text-indigo-600 transition-colors">
<i data-lucide="refresh-cw" class="w-4 h-4"></i>
</button>
</div>
</div>
<!-- 记录列表 -->
<div class="bg-white/70 backdrop-blur-xl rounded-[2.5rem] border border-slate-200/50 shadow-2xl overflow-hidden">
<div class="overflow-x-auto">
<table class="w-full text-left border-collapse">
<thead>
<tr class="border-b border-slate-100 bg-slate-50/50">
<th class="px-8 py-5 text-[10px] font-black text-slate-400 uppercase tracking-widest">用户信息</th>
<th class="px-8 py-5 text-[10px] font-black text-slate-400 uppercase tracking-widest">订单详情</th>
<th class="px-8 py-5 text-[10px] font-black text-slate-400 uppercase tracking-widest">积分/金额</th>
<th class="px-8 py-5 text-[10px] font-black text-slate-400 uppercase tracking-widest">状态</th>
<th class="px-8 py-5 text-[10px] font-black text-slate-400 uppercase tracking-widest">时间</th>
</tr>
</thead>
<tbody id="orderList" class="divide-y divide-slate-100">
<tr>
<td colspan="5" class="px-8 py-20 text-center">
<div class="flex flex-col items-center gap-4 animate-pulse">
<i data-lucide="loader-2" class="w-8 h-8 text-indigo-500 animate-spin"></i>
<p class="text-slate-400 font-bold">正在获取记录...</p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
{% endblock %}
{% block scripts %}
<script>
let allOrders = [];
async function loadOrders() {
try {
const r = await fetch('/api/admin/orders');
const d = await r.json();
allOrders = d.orders || [];
renderOrders(allOrders);
} catch (e) {
showToast('加载失败: ' + e.message, 'error');
}
}
function renderOrders(orders) {
const list = document.getElementById('orderList');
if (orders.length === 0) {
list.innerHTML = `
<tr>
<td colspan="5" class="px-8 py-20 text-center">
<div class="flex flex-col items-center gap-4 opacity-20">
<i data-lucide="inbox" class="w-16 h-16"></i>
<p class="font-black text-xl">暂无记录</p>
</div>
</td>
</tr>
`;
lucide.createIcons();
return;
}
list.innerHTML = orders.map(o => `
<tr class="hover:bg-slate-50/50 transition-colors group">
<td class="px-8 py-5">
<div class="flex items-center gap-3">
<div class="w-10 h-10 bg-indigo-50 text-indigo-600 rounded-xl flex items-center justify-center font-black text-xs">
${o.user_phone.slice(-4)}
</div>
<div class="flex flex-col">
<span class="text-sm font-bold text-slate-700">${o.user_phone}</span>
<span class="text-[10px] text-slate-400">UID: ${o.id}</span>
</div>
</div>
</td>
<td class="px-8 py-5">
<div class="flex flex-col">
<span class="text-xs font-bold text-slate-600">${o.out_trade_no}</span>
<span class="text-[10px] text-slate-400 font-mono">Ali: ${o.trade_no || '-'}</span>
</div>
</td>
<td class="px-8 py-5">
<div class="flex flex-col">
<div class="flex items-center gap-1">
<i data-lucide="zap" class="w-3 h-3 text-amber-500"></i>
<span class="text-sm font-black text-slate-900">+${o.points}</span>
</div>
<span class="text-xs font-bold text-slate-400">¥${o.amount}</span>
</div>
</td>
<td class="px-8 py-5">
${o.status === 'PAID'
? '<span class="px-3 py-1 bg-emerald-50 text-emerald-600 text-[10px] font-black rounded-lg border border-emerald-100">已完成</span>'
: o.status === 'PENDING'
? '<span class="px-3 py-1 bg-amber-50 text-amber-600 text-[10px] font-black rounded-lg border border-amber-100">待支付</span>'
: '<span class="px-3 py-1 bg-slate-50 text-slate-400 text-[10px] font-black rounded-lg border border-slate-100">已取消</span>'
}
</td>
<td class="px-8 py-5">
<div class="flex flex-col">
<span class="text-[10px] font-bold text-slate-500">创建: ${o.created_at}</span>
<span class="text-[10px] font-bold text-emerald-500">${o.paid_at ? '完成: ' + o.paid_at : ''}</span>
</div>
</td>
</tr>
`).join('');
lucide.createIcons();
}
document.getElementById('orderSearch').oninput = (e) => {
const val = e.target.value.toLowerCase();
const filtered = allOrders.filter(o =>
o.user_phone.includes(val) ||
o.out_trade_no.toLowerCase().includes(val)
);
renderOrders(filtered);
};
loadOrders();
</script>
{% endblock %}