diff --git a/app.py b/app.py index b4e25ba..068ac28 100644 --- a/app.py +++ b/app.py @@ -156,6 +156,11 @@ def create_app(): def video_page(): return render_template('video.html') + @app.route('/admin/orders/') + def order_detail(order_id): + # 权限检查可以在这里做,或者让模板里的 JS 向 API 请求时做 (API 已有权限检查) + return render_template('order_detail.html') + @app.route('/files/') def get_file(filename): """Proxy route to serve files from MinIO via the backend""" diff --git a/blueprints/admin.py b/blueprints/admin.py index 4b372b1..2e27470 100644 --- a/blueprints/admin.py +++ b/blueprints/admin.py @@ -1,8 +1,8 @@ -from flask import Blueprint, request, jsonify +from flask import Blueprint, request, jsonify, g from datetime import timedelta from extensions import db from models import User, Role, Permission, SystemDict, SystemNotification, Order, PointsGrant, InviteReward, to_bj_time, get_bj_now -from middlewares.auth import permission_required +from middlewares.auth import permission_required, login_required from services.logger import system_logger admin_bp = Blueprint('admin', __name__, url_prefix='/api/admin') @@ -303,6 +303,40 @@ def get_orders(): } for o in orders] }) +@admin_bp.route('/orders/', methods=['GET']) +@login_required +def get_order_detail(order_id): + order = db.session.get(Order, order_id) + if not order: + return jsonify({"error": "订单不存在"}), 404 + + # 权限检查:必须是管理员或者订单所有者 + if not g.user.has_permission('manage_system') and order.user_id != g.user.id: + return jsonify({"error": "无权访问此订单"}), 403 + + user = order.user + return jsonify({ + "order": { + "id": order.id, + "out_trade_no": order.out_trade_no, + "trade_no": order.trade_no, + "amount": float(order.amount), + "points": order.points, + "status": order.status, + "created_at": order.created_at_bj.strftime('%Y-%m-%d %H:%M:%S'), + "paid_at": order.paid_at_bj.strftime('%Y-%m-%d %H:%M:%S') if order.paid_at else None + }, + "buyer": { + "id": user.id, + "phone": user.phone, + "current_points": user.points, + "created_at": user.created_at_bj.strftime('%Y-%m-%d %H:%M:%S'), + "is_banned": user.is_banned, + "role": user.role.name if user.role else "普通用户" + }, + "current_is_admin": g.user.has_permission('manage_system') + }) + # --- 积分发放管理 --- @admin_bp.route('/points/grant', methods=['POST']) @permission_required('manage_system') diff --git a/templates/buy.html b/templates/buy.html index 99ff7c4..4d434ed 100644 --- a/templates/buy.html +++ b/templates/buy.html @@ -181,7 +181,8 @@ 订单信息 积分/金额 状态 - 时间 + 时间 + 操作 @@ -216,15 +217,21 @@ 已取消 {% endif %} - + {{ order.paid_at_bj.strftime('%Y-%m-%d %H:%M') if order.paid_at_bj else order.created_at_bj.strftime('%Y-%m-%d %H:%M') }} + + + + + {% endfor %} {% else %} - + 暂无充值记录 diff --git a/templates/order_detail.html b/templates/order_detail.html new file mode 100644 index 0000000..ca78fd4 --- /dev/null +++ b/templates/order_detail.html @@ -0,0 +1,238 @@ +{% extends "base.html" %} + +{% block title %}订单详情 - 管理后台{% endblock %} + +{% block content %} +
+
+ +
+
+ + + +
+

订单详情

+

+ + 订单号: ... +

+
+
+
+ +
+
+ +
+ +
+ +
+
+

+ + 商品信息 +

+
+ +
+
+
+
+ +
+
+

账户充值积分

+

虚拟商品 · 即时到账

+
+
+
+
+0 Pts +
+
¥0.00
+
+
+ +
+
+ 商品总额 + ¥0.00 +
+
+ 优惠金额 + -¥0.00 +
+
+ 实付款 + ¥0.00 +
+
+
+
+ + +
+

+ + 支付信息 +

+ +
+
+ +
+ 支付宝 (Alipay) +
+
+
+ +

--

+
+
+ +

--

+
+
+ +

--

+
+
+
+
+ + +
+
+

+ + 买家信息 +

+ +
+
+ +
+
+

--

+
+ -- + +
+
+
+ +
+
+ 用户 ID + #0 +
+
+ 注册时间 + -- +
+
+ 当前余额 +
+ + 0 +
+
+
+ + +
+ + +
+
+ +

系统提示

+
+

+ 该订单由系统自动处理并完成积分发放。如有异常,请及时联系技术人员查看服务器日志。 +

+
+
+
+
+
+{% endblock %} + +{% block scripts %} + +{% endblock %} \ No newline at end of file diff --git a/templates/orders.html b/templates/orders.html index a91d21b..479704f 100644 --- a/templates/orders.html +++ b/templates/orders.html @@ -16,31 +16,41 @@
- +
-
-
+
- - - - - + + + + + + - - - - `; - lucide.createIcons(); + renderEmptyState(); return; } @@ -116,28 +116,48 @@ - + `).join(''); lucide.createIcons(); } + function renderEmptyState() { + const list = document.getElementById('orderList'); + list.innerHTML = ` + + + + `; + lucide.createIcons(); + } + document.getElementById('orderSearch').oninput = (e) => { const val = e.target.value.toLowerCase(); - const filtered = allOrders.filter(o => - o.user_phone.includes(val) || + const filtered = allOrders.filter(o => + o.user_phone.includes(val) || o.out_trade_no.toLowerCase().includes(val) ); renderOrders(filtered); @@ -145,4 +165,4 @@ loadOrders(); -{% endblock %} +{% endblock %} \ No newline at end of file diff --git a/templates/recharge_history.html b/templates/recharge_history.html index 5b196f3..4ae2133 100644 --- a/templates/recharge_history.html +++ b/templates/recharge_history.html @@ -38,6 +38,8 @@ + @@ -84,11 +86,17 @@ {% endif %} + {% endfor %} {% else %} -
用户信息订单详情积分/金额状态时间用户信息 + 订单详情 + 积分/金额 + 状态 + 时间 + 操作 +
+

正在获取记录...

@@ -73,17 +83,7 @@ function renderOrders(orders) { const list = document.getElementById('orderList'); if (orders.length === 0) { - list.innerHTML = ` -
-
- -

暂无记录

-
-
- ${o.status === 'PAID' - ? '已完成' - : o.status === 'PENDING' - ? '待支付' - : '已取消' - } + ${o.status === 'PAID' + ? '已完成' + : o.status === 'PENDING' + ? '待支付' + : '已取消' + } +
创建: ${o.created_at} ${o.paid_at ? '完成: ' + o.paid_at : ''}
+ + + +
+
+ +

暂无记录

+
+
支付时间 操作 +
+ + + +
+

暂无充值记录