324 lines
12 KiB
HTML
324 lines
12 KiB
HTML
{% set page = page | default(1) %}
|
|
{% set total_pages = total_pages | default(1) %}
|
|
{% set status = status | default('in_progress') %}
|
|
|
|
<table class="table table-striped table-bordered">
|
|
<thead class="thead-light">
|
|
<tr>
|
|
<th>订单ID</th>
|
|
<th>用户名称</th> <!-- 原用户ID改为用户名称 -->
|
|
<th>游戏桌号</th> <!-- 原游戏桌ID改为桌号 -->
|
|
<th>游戏人数</th>
|
|
<th>开始时间</th>
|
|
<th>结束时间</th>
|
|
<th>结算时间</th>
|
|
<th>应付金额</th>
|
|
<th>实付金额</th>
|
|
<th>积分使用</th> <!-- 新增 -->
|
|
<th>优惠券</th> <!-- 新增 -->
|
|
<th>游戏时长</th> <!-- 新增 -->
|
|
<th>支付方式</th>
|
|
<th>状态</th>
|
|
<th>操作</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for order in orders %}
|
|
<tr>
|
|
<td>{{ order.order_id }}</td>
|
|
<td>{{ order.user_name }}</td> <!-- 显示用户名 -->
|
|
<td>{{ order.game_table_number or '未分配' }}</td> <!-- 显示桌号 -->
|
|
<td>{{ order.num_players }}</td>
|
|
<td>{{ order.start_datetime }}</td>
|
|
<td>{{ order.end_datetime or '进行中' }}</td>
|
|
<td>{{ order.settlement_time or '未付款' }}</td>
|
|
|
|
<td>¥{{ "%.2f"|format(order.payable_price|default('0')|float) }}</td>
|
|
<td>¥{{ "%.2f"|format(order.paid_price|default('0')|float) }}</td>
|
|
<td>{{ order.used_points or '0' }} 积分</td>
|
|
<td>{{ order.coupon_id or '无' }}</td>
|
|
<td>{{ order.game_process_time or '0' }} 分钟</td>
|
|
|
|
<td>
|
|
{% if order.order_status not in ['pending', 'in_progress'] %}
|
|
{% if order.payment_method == 'offline' %}
|
|
线下支付
|
|
{% else %}
|
|
{{ order.payment_method | default('现金支付') }}
|
|
{% endif %}
|
|
{% else %}
|
|
-
|
|
{% endif %}
|
|
</td>
|
|
|
|
<td>
|
|
<span class="badge
|
|
{% if order.order_status == 'completed' %}badge-success
|
|
{% elif order.order_status == 'cancelled' %}badge-danger
|
|
{% else %}badge-warning{% endif %}">
|
|
{{ order.order_status }}
|
|
</span>
|
|
</td>
|
|
<td>
|
|
{% if order.order_status == 'in_progress' %}
|
|
<button class="btn btn-success btn-sm"
|
|
onclick="openCompleteModal('{{ order.order_id }}')">结束订单</button>
|
|
{% elif order.order_status == 'pending' %}
|
|
<button class="btn btn-primary btn-sm"
|
|
onclick="openSettleModal('{{ order.order_id }}')">结算订单</button>
|
|
{% endif %}
|
|
</td>
|
|
</tr>
|
|
{% else %}
|
|
<tr>
|
|
<td class="text-center" colspan="9">暂无订单数据</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
|
|
<nav aria-label="Page navigation">
|
|
<ul class="pagination">
|
|
{% if page > 1 %}
|
|
<li class="page-item">
|
|
<a class="page-link" data-page="{{ page - 1 }}" href="#">上一页</a>
|
|
</li>
|
|
{% endif %}
|
|
|
|
{% for p in range(1, total_pages + 1) %}
|
|
<li class="page-item {% if p == page %}active{% endif %}">
|
|
<a class="page-link" data-page="{{ p }}" href="#">{{ p }}</a>
|
|
</li>
|
|
{% endfor %}
|
|
|
|
{% if page < total_pages %}
|
|
<li class="page-item">
|
|
<a class="page-link" data-page="{{ page + 1 }}" href="#">下一页</a>
|
|
</li>
|
|
{% endif %}
|
|
</ul>
|
|
</nav>
|
|
|
|
|
|
<div class="modal fade" id="completeModal">
|
|
<div class="modal-dialog">
|
|
<div class="modal-content">
|
|
<form onsubmit="completeOrder(event)">
|
|
<input id="complete-order-id" type="hidden">
|
|
<div class="modal-body">
|
|
<div class="form-group">
|
|
<label>结束时间</label>
|
|
<input class="form-control" id="end-time" required step="1" type="datetime-local">
|
|
</div>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button class="btn btn-primary" type="submit">提交</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="modal fade" id="settleModal">
|
|
<div class="modal-dialog modal-lg">
|
|
<div class="modal-content">
|
|
<form onsubmit="settleOrder(event)">
|
|
<input id="settle-order-id" type="hidden">
|
|
<div class="modal-body">
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<p>订单号:<span id="settle-order-number"></span></p>
|
|
<p>用户名称:<span id="user-name"></span></p>
|
|
<p>联系电话:<span id="user-phone"></span></p>
|
|
<p>可用积分:<span id="available-points"></span></p>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<p>开始时间:<span id="start-time"></span></p>
|
|
<p>结束时间:<span id="game-end-time"></span></p>
|
|
<p>游戏时长:<span id="duration"></span> 分钟</p>
|
|
<p>应付金额:<span id="payable-price"></span> 元</p>
|
|
</div>
|
|
</div>
|
|
<div class="form-group">
|
|
<label>使用积分</label>
|
|
<input class="form-control" id="used-points" min="0" type="number" value="0">
|
|
</div>
|
|
<div class="form-group">
|
|
<label>优惠券编号</label>
|
|
<input class="form-control" id="coupon-code" type="text">
|
|
</div>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button class="btn btn-primary" type="submit">确认结算</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<script>
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
// 分页事件监听
|
|
document.querySelectorAll('.page-link').forEach(link => {
|
|
link.addEventListener('click', function(e) {
|
|
e.preventDefault();
|
|
const page = this.dataset.page;
|
|
fetchOrders(page);
|
|
});
|
|
});
|
|
});
|
|
|
|
async function fetchOrders(page) {
|
|
try {
|
|
const response = await fetch(`/orders/list?page=${page}`);
|
|
const html = await response.text();
|
|
document.querySelector('table').innerHTML =
|
|
new DOMParser().parseFromString(html, 'text/html')
|
|
.querySelector('table').innerHTML;
|
|
} catch (error) {
|
|
console.error('加载订单失败:', error);
|
|
}
|
|
}
|
|
|
|
// 辅助函数:格式化日期为 YYYY-MM-DDTHH:mm 格式(本地时间)
|
|
function formatLocalDateTime(date) {
|
|
const pad = n => n < 10 ? '0' + n : n;
|
|
return date.getFullYear() + '-' +
|
|
pad(date.getMonth() + 1) + '-' +
|
|
pad(date.getDate()) + 'T' +
|
|
pad(date.getHours()) + ':' +
|
|
pad(date.getMinutes());
|
|
}
|
|
|
|
// 结束订单功能:打开模态框时预填本地时间
|
|
function openCompleteModal(orderId) {
|
|
// 获取当前本地时间并格式化
|
|
const now = new Date();
|
|
const timeString = formatLocalDateTime(now);
|
|
|
|
document.getElementById('end-time').value = timeString;
|
|
document.getElementById('complete-order-id').value = orderId;
|
|
$('#completeModal').modal('show');
|
|
}
|
|
|
|
// 完成订单功能:提交订单完成的时间到后台
|
|
async function completeOrder(event) {
|
|
event.preventDefault();
|
|
const orderId = document.getElementById('complete-order-id').value;
|
|
const endTime = document.getElementById('end-time').value; // 格式为 "YYYY-MM-DDTHH:mm",代表本地时间
|
|
|
|
try {
|
|
const response = await fetch(`/orders/complete/${orderId}`, {
|
|
method: 'PUT',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'Authorization': `Bearer ${sessionStorage.getItem('token')}`
|
|
},
|
|
// 直接提交本地时间字符串,后台可按需求解析
|
|
body: JSON.stringify({
|
|
end_datetime: endTime
|
|
})
|
|
});
|
|
|
|
if (response.ok) {
|
|
$('#completeModal').modal('hide');
|
|
currentPage = document.querySelector('.page-item.active .page-link').dataset.page;
|
|
fetchOrders(currentPage); // 刷新订单列表
|
|
} else {
|
|
const error = await response.json();
|
|
alert(`操作失败: ${error.detail}`);
|
|
}
|
|
} catch (error) {
|
|
console.error('请求失败:', error);
|
|
}
|
|
}
|
|
|
|
|
|
async function openSettleModal(orderId) {
|
|
try {
|
|
// 先获取订单详情
|
|
const order = await fetch(`/orders/details/${orderId}`)
|
|
.then(res => {
|
|
if (!res.ok) throw new Error(`订单请求失败: ${res.status}`);
|
|
return res.json();
|
|
});
|
|
|
|
console.log(order.start_datetime);
|
|
// 再根据用户ID获取用户信息
|
|
const user = await fetch(`/users/search`, {
|
|
method: "POST",
|
|
headers: {"Content-Type": "application/json"},
|
|
body: JSON.stringify({
|
|
query_mode: "uid",
|
|
query_value: order.user_id.toString()
|
|
})
|
|
|
|
}).then(res => {
|
|
if (!res.ok) throw new Error(`用户请求失败: ${res.status}`);
|
|
return res.json();
|
|
});
|
|
console.log(user);
|
|
console.log(user[0].user_id);
|
|
|
|
// 填充结算模态框数据
|
|
document.getElementById('settle-order-id').value = orderId;
|
|
console.log(user[0].username);
|
|
document.getElementById('settle-order-number').textContent = orderId;
|
|
document.getElementById('user-name').textContent = user[0].username;
|
|
document.getElementById('user-phone').textContent = user[0].phone_number;
|
|
document.getElementById('start-time').textContent =
|
|
new Date(order.start_datetime).toLocaleString();
|
|
console.log(order.start_datetime);
|
|
document.getElementById('game-end-time').textContent =
|
|
new Date(order.end_datetime).toLocaleString();
|
|
document.getElementById('duration').textContent =
|
|
Math.round((new Date(order.end_datetime) - new Date(order.start_datetime)) / 60000);
|
|
console.log(Math.round((new Date(order.end_datetime) - new Date(order.start_datetime)) / 60000));
|
|
// 假设 available-points 为存在的字段
|
|
document.getElementById('available-points').textContent = user[0].points;
|
|
console.log(order.payable_price);
|
|
console.log(order.paid_price);
|
|
document.getElementById('payable-price').textContent = order.payable_price;
|
|
|
|
$('#settleModal').modal('show');
|
|
} catch (error) {
|
|
console.error('加载数据失败:', error);
|
|
}
|
|
}
|
|
|
|
|
|
async function settleOrder(event) {
|
|
event.preventDefault();
|
|
const orderId = document.getElementById('settle-order-id').value;
|
|
console.log(orderId);
|
|
const payload = {
|
|
used_points: parseInt(document.getElementById('used-points').value) || 0,
|
|
coupon_id: document.getElementById('coupon-code').value || null
|
|
};
|
|
|
|
try {
|
|
const response = await fetch(`/orders/settle/${orderId}`, {
|
|
method: 'PUT',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
},
|
|
body: JSON.stringify(payload)
|
|
});
|
|
|
|
if (response.ok) {
|
|
$('#settleModal').modal('hide');
|
|
currentPage = document.querySelector('.page-item.active .page-link').dataset.page;
|
|
fetchOrders(currentPage); // 刷新列表
|
|
alert('结算成功!');
|
|
} else {
|
|
const error = await response.json();
|
|
alert(`结算失败: ${error.detail}`);
|
|
}
|
|
} catch (error) {
|
|
console.error('请求失败:', error);
|
|
}
|
|
}
|
|
|
|
</script>
|