2025-07-09 05:22:28 +08:00

366 lines
17 KiB
HTML

{% extends "admin/base.html" %}
{% block title %}订单管理 - 太白购物商城管理后台{% endblock %}
{% block page_title %}订单管理{% endblock %}
{% block page_description %}管理系统中的所有订单{% endblock %}
{% block extra_css %}
<link href="{{ url_for('static', filename='css/admin_orders.css') }}" rel="stylesheet">
{% endblock %}
{% block content %}
<div class="admin-orders">
<!-- 统计卡片 -->
<div class="row mb-4">
<div class="col-md-2">
<div class="card stats-card">
<div class="card-body text-center">
<div class="stats-number">{{ order_stats.get(0, {}).get('count', 0) + order_stats.get(1, {}).get('count', 0) + order_stats.get(2, {}).get('count', 0) + order_stats.get(3, {}).get('count', 0) + order_stats.get(4, {}).get('count', 0) + order_stats.get(5, {}).get('count', 0) + order_stats.get(6, {}).get('count', 0) + order_stats.get(7, {}).get('count', 0) }}</div>
<div class="stats-label">总订单</div>
</div>
</div>
</div>
<div class="col-md-2">
<div class="card stats-card pending-payment">
<div class="card-body text-center">
<div class="stats-number">{{ order_stats.get(1, {}).get('count', 0) }}</div>
<div class="stats-label">待支付</div>
</div>
</div>
</div>
<div class="col-md-2">
<div class="card stats-card pending-shipment">
<div class="card-body text-center">
<div class="stats-number">{{ order_stats.get(2, {}).get('count', 0) }}</div>
<div class="stats-label">待发货</div>
</div>
</div>
</div>
<div class="col-md-2">
<div class="card stats-card shipped">
<div class="card-body text-center">
<div class="stats-number">{{ order_stats.get(3, {}).get('count', 0) }}</div>
<div class="stats-label">待收货</div>
</div>
</div>
</div>
<div class="col-md-2">
<div class="card stats-card completed">
<div class="card-body text-center">
<div class="stats-number">{{ order_stats.get(5, {}).get('count', 0) }}</div>
<div class="stats-label">已完成</div>
</div>
</div>
</div>
<div class="col-md-2">
<div class="card stats-card cancelled">
<div class="card-body text-center">
<div class="stats-number">{{ order_stats.get(6, {}).get('count', 0) }}</div>
<div class="stats-label">已取消</div>
</div>
</div>
</div>
</div>
<!-- 搜索和筛选 -->
<div class="card mb-4">
<div class="card-body">
<form method="GET" class="row g-3">
<div class="col-md-3">
<label for="search" class="form-label">搜索</label>
<input type="text" class="form-control" id="search" name="search"
value="{{ search }}" placeholder="订单号/用户名/手机号">
</div>
<div class="col-md-2">
<label for="status" class="form-label">订单状态</label>
<select class="form-select" id="status" name="status">
<option value="">全部状态</option>
{% for status_code, status_name in ORDER_STATUS.items() %}
<option value="{{ status_code }}" {% if status == status_code|string %}selected{% endif %}>
{{ status_name }}
</option>
{% endfor %}
</select>
</div>
<div class="col-md-2">
<label for="start_date" class="form-label">开始日期</label>
<input type="date" class="form-control" id="start_date" name="start_date" value="{{ start_date }}">
</div>
<div class="col-md-2">
<label for="end_date" class="form-label">结束日期</label>
<input type="date" class="form-control" id="end_date" name="end_date" value="{{ end_date }}">
</div>
<div class="col-md-3">
<label class="form-label">&nbsp;</label>
<div class="d-flex gap-2">
<button type="submit" class="btn btn-primary">
<i class="bi bi-search"></i> 搜索
</button>
<a href="{{ url_for('admin.orders') }}" class="btn btn-outline-secondary">
<i class="bi bi-arrow-clockwise"></i> 重置
</a>
</div>
</div>
</form>
</div>
</div>
<!-- 订单列表 -->
<div class="card">
<div class="card-header">
<h5 class="card-title mb-0">订单列表</h5>
</div>
<div class="card-body">
{% if orders.items %}
<div class="table-responsive">
<table class="table table-hover">
<thead>
<tr>
<th>订单号</th>
<th>用户信息</th>
<th>订单金额</th>
<th>订单状态</th>
<th>支付方式</th>
<th>创建时间</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{% for order in orders.items %}
<tr>
<td>
<div class="fw-bold">{{ order.order_sn }}</div>
<small class="text-muted">ID: {{ order.id }}</small>
</td>
<td>
<div class="fw-bold">{{ order.user.username }}</div>
{% if order.user.phone %}
<small class="text-muted">{{ order.user.phone }}</small>
{% endif %}
</td>
<td>
<div class="fw-bold text-primary">¥{{ "%.2f"|format(order.actual_amount) }}</div>
{% if order.shipping_fee > 0 %}
<small class="text-muted">含运费: ¥{{ "%.2f"|format(order.shipping_fee) }}</small>
{% endif %}
</td>
<td>
<span class="badge order-status-{{ order.status }}">{{ order.get_status_text() }}</span>
</td>
<td>
{% if order.payment_method %}
<span class="badge bg-info">{{ order.payment_method }}</span>
{% else %}
<span class="text-muted">未设置</span>
{% endif %}
</td>
<td>
<div>{{ order.created_at.strftime('%Y-%m-%d') }}</div>
<small class="text-muted">{{ order.created_at.strftime('%H:%M:%S') }}</small>
</td>
<td>
<div class="btn-group" role="group">
<a href="{{ url_for('admin.order_detail', order_id=order.id) }}"
class="btn btn-sm btn-outline-primary">
<i class="bi bi-eye"></i> 详情
</a>
{% if order.status == 2 %}
<button class="btn btn-sm btn-outline-success"
onclick="showShipModal({{ order.id }}, '{{ order.order_sn }}')">
<i class="bi bi-truck"></i> 发货
</button>
{% endif %}
{% if order.status in [2, 3] %}
<button class="btn btn-sm btn-outline-warning"
onclick="showRefundModal({{ order.id }}, '{{ order.order_sn }}')">
<i class="bi bi-arrow-return-left"></i> 退款
</button>
{% endif %}
{% if order.can_cancel() %}
<button class="btn btn-sm btn-outline-danger"
onclick="showCancelModal({{ order.id }}, '{{ order.order_sn }}')">
<i class="bi bi-x-circle"></i> 取消
</button>
{% endif %}
</div>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<!-- 分页 -->
{% if orders.pages > 1 %}
<nav aria-label="订单分页">
<ul class="pagination justify-content-center">
{% if orders.has_prev %}
<li class="page-item">
<a class="page-link" href="{{ url_for('admin.orders', page=orders.prev_num, search=search, status=status, start_date=start_date, end_date=end_date) }}">
<i class="bi bi-chevron-left"></i>
</a>
</li>
{% endif %}
{% for page_num in orders.iter_pages() %}
{% if page_num %}
{% if page_num != orders.page %}
<li class="page-item">
<a class="page-link" href="{{ url_for('admin.orders', page=page_num, search=search, status=status, start_date=start_date, end_date=end_date) }}">
{{ page_num }}
</a>
</li>
{% else %}
<li class="page-item active">
<span class="page-link">{{ page_num }}</span>
</li>
{% endif %}
{% else %}
<li class="page-item disabled">
<span class="page-link"></span>
</li>
{% endif %}
{% endfor %}
{% if orders.has_next %}
<li class="page-item">
<a class="page-link" href="{{ url_for('admin.orders', page=orders.next_num, search=search, status=status, start_date=start_date, end_date=end_date) }}">
<i class="bi bi-chevron-right"></i>
</a>
</li>
{% endif %}
</ul>
</nav>
{% endif %}
{% else %}
<div class="text-center py-4">
<i class="bi bi-inbox display-1 text-muted"></i>
<p class="text-muted mt-2">暂无订单数据</p>
</div>
{% endif %}
</div>
</div>
</div>
<!-- 发货模态框 -->
<div class="modal fade" id="shipModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">订单发货</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<form id="shipForm">
<div class="modal-body">
<div class="mb-3">
<label class="form-label">订单号</label>
<input type="text" class="form-control" id="shipOrderSn" readonly>
</div>
<div class="mb-3">
<label class="form-label">物流公司 <span class="text-danger">*</span></label>
<select class="form-select" name="shipping_company" required>
<option value="">请选择物流公司</option>
<option value="顺丰速运">顺丰速运</option>
<option value="圆通速递">圆通速递</option>
<option value="中通快递">中通快递</option>
<option value="申通快递">申通快递</option>
<option value="韵达速递">韵达速递</option>
<option value="百世快递">百世快递</option>
<option value="德邦快递">德邦快递</option>
<option value="京东物流">京东物流</option>
</select>
</div>
<div class="mb-3">
<label class="form-label">快递单号 <span class="text-danger">*</span></label>
<input type="text" class="form-control" name="tracking_number" required>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">取消</button>
<button type="submit" class="btn btn-success">
<i class="bi bi-truck"></i> 确认发货
</button>
</div>
</form>
</div>
</div>
</div>
<!-- 退款模态框 -->
<div class="modal fade" id="refundModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">订单退款</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<form id="refundForm">
<div class="modal-body">
<div class="mb-3">
<label class="form-label">订单号</label>
<input type="text" class="form-control" id="refundOrderSn" readonly>
</div>
<div class="mb-3">
<label class="form-label">退款原因 <span class="text-danger">*</span></label>
<textarea class="form-control" name="refund_reason" rows="3" required placeholder="请输入退款原因"></textarea>
</div>
<div class="alert alert-warning">
<i class="bi bi-exclamation-triangle"></i>
退款后将自动恢复库存,减少销量统计
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">取消</button>
<button type="submit" class="btn btn-warning">
<i class="bi bi-arrow-return-left"></i> 确认退款
</button>
</div>
</form>
</div>
</div>
</div>
<!-- 取消模态框 -->
<div class="modal fade" id="cancelModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">取消订单</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<form id="cancelForm">
<div class="modal-body">
<div class="mb-3">
<label class="form-label">订单号</label>
<input type="text" class="form-control" id="cancelOrderSn" readonly>
</div>
<div class="mb-3">
<label class="form-label">取消原因</label>
<textarea class="form-control" name="cancel_reason" rows="3" placeholder="请输入取消原因(可选)"></textarea>
</div>
<div class="alert alert-danger">
<i class="bi bi-exclamation-triangle"></i>
取消订单后将自动恢复库存,减少销量统计
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">取消</button>
<button type="submit" class="btn btn-danger">
<i class="bi bi-x-circle"></i> 确认取消
</button>
</div>
</form>
</div>
</div>
</div>
{% endblock %}
{% block extra_js %}
<script src="{{ url_for('static', filename='js/admin_orders.js') }}"></script>
{% endblock %}