diff --git a/nkebao/src/pages/mobile/mine/recharge/index.module.scss b/nkebao/src/pages/mobile/mine/recharge/index/index.module.scss
similarity index 100%
rename from nkebao/src/pages/mobile/mine/recharge/index.module.scss
rename to nkebao/src/pages/mobile/mine/recharge/index/index.module.scss
diff --git a/nkebao/src/pages/mobile/mine/recharge/index.tsx b/nkebao/src/pages/mobile/mine/recharge/index/index.tsx
similarity index 98%
rename from nkebao/src/pages/mobile/mine/recharge/index.tsx
rename to nkebao/src/pages/mobile/mine/recharge/index/index.tsx
index e322aca2..9507b73c 100644
--- a/nkebao/src/pages/mobile/mine/recharge/index.tsx
+++ b/nkebao/src/pages/mobile/mine/recharge/index/index.tsx
@@ -1,6 +1,6 @@
import React, { useState } from "react";
import { useNavigate } from "react-router-dom";
-import { Card, Button, Toast, NavBar, Tabs } from "antd-mobile";
+import { Card, Button, Toast, Tabs } from "antd-mobile";
import { useUserStore } from "@/store/module/user";
import style from "./index.module.scss";
import {
@@ -338,7 +338,7 @@ const Recharge: React.FC = () => {
right={
navigate("/mine/consumption-records")}
+ onClick={() => navigate("/recharge/order")}
>
记录
diff --git a/nkebao/src/pages/mobile/mine/recharge/order/api.ts b/nkebao/src/pages/mobile/mine/recharge/order/api.ts
new file mode 100644
index 00000000..11d4573e
--- /dev/null
+++ b/nkebao/src/pages/mobile/mine/recharge/order/api.ts
@@ -0,0 +1,197 @@
+import {
+ RechargeOrdersResponse,
+ RechargeOrderDetail,
+ RechargeOrderParams,
+} from "./data";
+
+// 模拟数据
+const mockOrders = [
+ {
+ id: "1",
+ orderNo: "RC20241201001",
+ amount: 100.0,
+ paymentMethod: "wechat",
+ status: "success" as const,
+ createTime: "2024-12-01T10:30:00Z",
+ payTime: "2024-12-01T10:32:15Z",
+ description: "账户充值",
+ balance: 150.0,
+ },
+ {
+ id: "2",
+ orderNo: "RC20241201002",
+ amount: 200.0,
+ paymentMethod: "alipay",
+ status: "pending" as const,
+ createTime: "2024-12-01T14:20:00Z",
+ description: "账户充值",
+ balance: 350.0,
+ },
+ {
+ id: "3",
+ orderNo: "RC20241130001",
+ amount: 50.0,
+ paymentMethod: "bank",
+ status: "success" as const,
+ createTime: "2024-11-30T09:15:00Z",
+ payTime: "2024-11-30T09:18:30Z",
+ description: "账户充值",
+ balance: 50.0,
+ },
+ {
+ id: "4",
+ orderNo: "RC20241129001",
+ amount: 300.0,
+ paymentMethod: "wechat",
+ status: "failed" as const,
+ createTime: "2024-11-29T16:45:00Z",
+ description: "账户充值",
+ },
+ {
+ id: "5",
+ orderNo: "RC20241128001",
+ amount: 150.0,
+ paymentMethod: "alipay",
+ status: "cancelled" as const,
+ createTime: "2024-11-28T11:20:00Z",
+ description: "账户充值",
+ },
+ {
+ id: "6",
+ orderNo: "RC20241127001",
+ amount: 80.0,
+ paymentMethod: "wechat",
+ status: "success" as const,
+ createTime: "2024-11-27T13:10:00Z",
+ payTime: "2024-11-27T13:12:45Z",
+ description: "账户充值",
+ balance: 80.0,
+ },
+ {
+ id: "7",
+ orderNo: "RC20241126001",
+ amount: 120.0,
+ paymentMethod: "bank",
+ status: "success" as const,
+ createTime: "2024-11-26T08:30:00Z",
+ payTime: "2024-11-26T08:33:20Z",
+ description: "账户充值",
+ balance: 120.0,
+ },
+ {
+ id: "8",
+ orderNo: "RC20241125001",
+ amount: 250.0,
+ paymentMethod: "alipay",
+ status: "pending" as const,
+ createTime: "2024-11-25T15:45:00Z",
+ description: "账户充值",
+ balance: 370.0,
+ },
+];
+
+// 模拟延迟
+const delay = (ms: number) => new Promise(resolve => setTimeout(resolve, ms));
+
+// 获取充值记录列表
+export async function getRechargeOrders(
+ params: RechargeOrderParams,
+): Promise
{
+ await delay(800); // 模拟网络延迟
+
+ let filteredOrders = [...mockOrders];
+
+ // 状态筛选
+ if (params.status && params.status !== "all") {
+ filteredOrders = filteredOrders.filter(
+ order => order.status === params.status,
+ );
+ }
+
+ // 时间筛选
+ if (params.startTime) {
+ filteredOrders = filteredOrders.filter(
+ order => new Date(order.createTime) >= new Date(params.startTime!),
+ );
+ }
+ if (params.endTime) {
+ filteredOrders = filteredOrders.filter(
+ order => new Date(order.createTime) <= new Date(params.endTime!),
+ );
+ }
+
+ // 分页
+ const startIndex = (params.page - 1) * params.limit;
+ const endIndex = startIndex + params.limit;
+ const paginatedOrders = filteredOrders.slice(startIndex, endIndex);
+
+ return {
+ list: paginatedOrders,
+ total: filteredOrders.length,
+ page: params.page,
+ limit: params.limit,
+ };
+}
+
+// 获取充值记录详情
+export async function getRechargeOrderDetail(
+ id: string,
+): Promise {
+ await delay(500);
+
+ const order = mockOrders.find(o => o.id === id);
+ if (!order) {
+ throw new Error("订单不存在");
+ }
+
+ return {
+ ...order,
+ paymentChannel:
+ order.paymentMethod === "wechat"
+ ? "微信支付"
+ : order.paymentMethod === "alipay"
+ ? "支付宝"
+ : "银行转账",
+ transactionId: `TX${order.orderNo}`,
+ };
+}
+
+// 取消充值订单
+export async function cancelRechargeOrder(id: string): Promise {
+ await delay(1000);
+
+ const orderIndex = mockOrders.findIndex(o => o.id === id);
+ if (orderIndex === -1) {
+ throw new Error("订单不存在");
+ }
+
+ if (mockOrders[orderIndex].status !== "pending") {
+ throw new Error("只能取消处理中的订单");
+ }
+
+ // 模拟更新订单状态
+ (mockOrders[orderIndex] as any).status = "cancelled";
+}
+
+// 申请退款
+export async function refundRechargeOrder(
+ id: string,
+ reason: string,
+): Promise {
+ await delay(1200);
+
+ const orderIndex = mockOrders.findIndex(o => o.id === id);
+ if (orderIndex === -1) {
+ throw new Error("订单不存在");
+ }
+
+ if (mockOrders[orderIndex].status !== "success") {
+ throw new Error("只能对成功的订单申请退款");
+ }
+
+ // 模拟添加退款信息
+ const order = mockOrders[orderIndex];
+ (order as any).refundAmount = order.amount;
+ (order as any).refundTime = new Date().toISOString();
+ (order as any).refundReason = reason;
+}
diff --git a/nkebao/src/pages/mobile/mine/recharge/order/data.ts b/nkebao/src/pages/mobile/mine/recharge/order/data.ts
new file mode 100644
index 00000000..95b9a0e9
--- /dev/null
+++ b/nkebao/src/pages/mobile/mine/recharge/order/data.ts
@@ -0,0 +1,40 @@
+// 充值记录类型定义
+export interface RechargeOrder {
+ id: string;
+ orderNo: string;
+ amount: number;
+ paymentMethod: string;
+ status: "success" | "pending" | "failed" | "cancelled";
+ createTime: string;
+ payTime?: string;
+ description?: string;
+ remark?: string;
+ operator?: string;
+ balance?: number;
+}
+
+// API响应类型
+export interface RechargeOrdersResponse {
+ list: RechargeOrder[];
+ total: number;
+ page: number;
+ limit: number;
+}
+
+// 充值记录详情
+export interface RechargeOrderDetail extends RechargeOrder {
+ paymentChannel?: string;
+ transactionId?: string;
+ refundAmount?: number;
+ refundTime?: string;
+ refundReason?: string;
+}
+
+// 查询参数
+export interface RechargeOrderParams {
+ page: number;
+ limit: number;
+ status?: string;
+ startTime?: string;
+ endTime?: string;
+}
diff --git a/nkebao/src/pages/mobile/mine/recharge/order/index.module.scss b/nkebao/src/pages/mobile/mine/recharge/order/index.module.scss
new file mode 100644
index 00000000..64031e92
--- /dev/null
+++ b/nkebao/src/pages/mobile/mine/recharge/order/index.module.scss
@@ -0,0 +1,242 @@
+.recharge-orders-page {
+ padding: 16px;
+ background: #f5f5f5;
+ min-height: 100vh;
+
+ .orders-list {
+ .order-card {
+ margin-bottom: 12px;
+ border-radius: 12px;
+ background: #fff;
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
+ overflow: hidden;
+
+ .order-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 16px;
+ border-bottom: 1px solid #f0f0f0;
+
+ .order-info {
+ flex: 1;
+
+ .order-no {
+ font-size: 14px;
+ color: #333;
+ font-weight: 500;
+ margin-bottom: 4px;
+ }
+
+ .order-time {
+ font-size: 12px;
+ color: #999;
+ display: flex;
+ align-items: center;
+ gap: 4px;
+ }
+ }
+
+ .order-amount {
+ text-align: right;
+
+ .amount-text {
+ font-size: 18px;
+ font-weight: 600;
+ color: #52c41a;
+ margin-bottom: 4px;
+ }
+
+ .status-tag {
+ font-size: 12px;
+ padding: 2px 8px;
+ border-radius: 10px;
+ }
+ }
+ }
+
+ .order-details {
+ padding: 12px 16px;
+
+ .detail-row {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-bottom: 8px;
+ font-size: 14px;
+
+ &:last-child {
+ margin-bottom: 0;
+ }
+
+ .label {
+ color: #666;
+ }
+
+ .value {
+ color: #333;
+ font-weight: 500;
+ }
+ }
+
+ .payment-method {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ margin-bottom: 8px;
+
+ .method-icon {
+ width: 20px;
+ height: 20px;
+ border-radius: 4px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 12px;
+ color: #fff;
+ }
+
+ .method-text {
+ font-size: 14px;
+ color: #333;
+ }
+ }
+
+ .balance-info {
+ background: #f8f9fa;
+ padding: 8px 12px;
+ border-radius: 6px;
+ font-size: 12px;
+ color: #666;
+ margin-top: 8px;
+ }
+ }
+
+ .order-actions {
+ padding: 12px 16px;
+ border-top: 1px solid #f0f0f0;
+ display: flex;
+ gap: 8px;
+
+ .action-btn {
+ flex: 1;
+ height: 32px;
+ border-radius: 6px;
+ font-size: 12px;
+ border: none;
+ cursor: pointer;
+ transition: all 0.2s;
+
+ &.primary {
+ background: #1677ff;
+ color: #fff;
+
+ &:hover {
+ background: #0958d9;
+ }
+ }
+
+ &.secondary {
+ background: #f5f5f5;
+ color: #666;
+ border: 1px solid #d9d9d9;
+
+ &:hover {
+ background: #e6e6e6;
+ }
+ }
+
+ &.danger {
+ background: #ff4d4f;
+ color: #fff;
+
+ &:hover {
+ background: #cf1322;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ .empty-state {
+ padding: 60px 20px;
+ text-align: center;
+
+ .empty-icon {
+ font-size: 48px;
+ color: #d9d9d9;
+ margin-bottom: 16px;
+ }
+
+ .empty-text {
+ font-size: 14px;
+ color: #999;
+ }
+ }
+
+ .loading-container {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ padding: 40px 20px;
+
+ .loading-text {
+ margin-top: 12px;
+ font-size: 14px;
+ color: #666;
+ }
+ }
+
+ .load-more {
+ text-align: center;
+ padding: 16px;
+ color: #1677ff;
+ font-size: 14px;
+ cursor: pointer;
+ background: #fff;
+ border-radius: 8px;
+ margin-top: 12px;
+
+ &:hover {
+ background: #f0f8ff;
+ }
+ }
+
+ .filter-bar {
+ background: #fff;
+ border-radius: 12px;
+ padding: 16px;
+ margin-bottom: 16px;
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
+
+ .filter-tabs {
+ display: flex;
+ gap: 8px;
+
+ .filter-tab {
+ flex: 1;
+ height: 32px;
+ border-radius: 16px;
+ font-size: 12px;
+ border: 1px solid #d9d9d9;
+ background: #fff;
+ color: #666;
+ cursor: pointer;
+ transition: all 0.2s;
+
+ &.active {
+ background: #1677ff;
+ color: #fff;
+ border-color: #1677ff;
+ }
+
+ &:hover:not(.active) {
+ border-color: #1677ff;
+ color: #1677ff;
+ }
+ }
+ }
+ }
+}
diff --git a/nkebao/src/pages/mobile/mine/recharge/order/index.tsx b/nkebao/src/pages/mobile/mine/recharge/order/index.tsx
new file mode 100644
index 00000000..7e5260e6
--- /dev/null
+++ b/nkebao/src/pages/mobile/mine/recharge/order/index.tsx
@@ -0,0 +1,344 @@
+import React, { useState, useEffect, useCallback } from "react";
+import { useNavigate } from "react-router-dom";
+import { Card, SpinLoading, Empty, Toast, Dialog } from "antd-mobile";
+import {
+ WalletOutlined,
+ ClockCircleOutlined,
+ WechatOutlined,
+ AlipayCircleOutlined,
+ BankOutlined,
+} from "@ant-design/icons";
+import NavCommon from "@/components/NavCommon";
+import Layout from "@/components/Layout/Layout";
+import {
+ getRechargeOrders,
+ cancelRechargeOrder,
+ refundRechargeOrder,
+} from "./api";
+import { RechargeOrder } from "./data";
+import style from "./index.module.scss";
+
+const RechargeOrders: React.FC = () => {
+ const navigate = useNavigate();
+ const [orders, setOrders] = useState([]);
+ const [loading, setLoading] = useState(true);
+ const [hasMore, setHasMore] = useState(true);
+ const [page, setPage] = useState(1);
+ const [statusFilter, setStatusFilter] = useState("all");
+
+ const loadOrders = async (reset = false) => {
+ setLoading(true);
+ try {
+ const currentPage = reset ? 1 : page;
+ const params = {
+ page: currentPage,
+ limit: 20,
+ ...(statusFilter !== "all" && { status: statusFilter }),
+ };
+
+ const response = await getRechargeOrders(params);
+ const newOrders = response.list || [];
+ setOrders(prev => (reset ? newOrders : [...prev, ...newOrders]));
+ setHasMore(newOrders.length === 20);
+ if (reset) setPage(1);
+ else setPage(currentPage + 1);
+ } catch (error) {
+ console.error("加载充值记录失败:", error);
+ Toast.show({ content: "加载失败,请重试", position: "top" });
+ } finally {
+ setLoading(false);
+ }
+ };
+
+ // 初始化加载
+ useEffect(() => {
+ loadOrders(true);
+ }, []);
+
+ // 筛选条件变化时重新加载
+ const handleFilterChange = (newStatus: string) => {
+ setStatusFilter(newStatus);
+ setPage(1);
+ setOrders([]);
+ loadOrders(true);
+ };
+
+ const getStatusText = (status: string) => {
+ switch (status) {
+ case "success":
+ return "充值成功";
+ case "pending":
+ return "处理中";
+ case "failed":
+ return "充值失败";
+ case "cancelled":
+ return "已取消";
+ default:
+ return "未知状态";
+ }
+ };
+
+ const getStatusColor = (status: string) => {
+ switch (status) {
+ case "success":
+ return "#52c41a";
+ case "pending":
+ return "#faad14";
+ case "failed":
+ return "#ff4d4f";
+ case "cancelled":
+ return "#999";
+ default:
+ return "#666";
+ }
+ };
+
+ const getPaymentMethodIcon = (method: string) => {
+ switch (method.toLowerCase()) {
+ case "wechat":
+ return ;
+ case "alipay":
+ return ;
+ case "bank":
+ return ;
+ default:
+ return ;
+ }
+ };
+
+ const getPaymentMethodColor = (method: string) => {
+ switch (method.toLowerCase()) {
+ case "wechat":
+ return "#07c160";
+ case "alipay":
+ return "#1677ff";
+ case "bank":
+ return "#722ed1";
+ default:
+ return "#666";
+ }
+ };
+
+ const formatTime = (timeStr: string) => {
+ const date = new Date(timeStr);
+ const now = new Date();
+ const diff = now.getTime() - date.getTime();
+ const days = Math.floor(diff / (1000 * 60 * 60 * 24));
+
+ if (days === 0) {
+ return date.toLocaleTimeString("zh-CN", {
+ hour: "2-digit",
+ minute: "2-digit",
+ });
+ } else if (days === 1) {
+ return (
+ "昨天 " +
+ date.toLocaleTimeString("zh-CN", {
+ hour: "2-digit",
+ minute: "2-digit",
+ })
+ );
+ } else if (days < 7) {
+ return `${days}天前`;
+ } else {
+ return date.toLocaleDateString("zh-CN");
+ }
+ };
+
+ const handleCancelOrder = async (orderId: string) => {
+ const result = await Dialog.confirm({
+ content: "确定要取消这个充值订单吗?",
+ confirmText: "确定取消",
+ cancelText: "再想想",
+ });
+
+ if (result) {
+ try {
+ await cancelRechargeOrder(orderId);
+ Toast.show({ content: "订单已取消", position: "top" });
+ loadOrders(true);
+ } catch (error) {
+ console.error("取消订单失败:", error);
+ Toast.show({ content: "取消失败,请重试", position: "top" });
+ }
+ }
+ };
+
+ const handleRefundOrder = async (orderId: string) => {
+ const result = await Dialog.confirm({
+ content: "确定要申请退款吗?退款将在1-3个工作日内处理。",
+ confirmText: "申请退款",
+ cancelText: "取消",
+ });
+
+ if (result) {
+ try {
+ await refundRechargeOrder(orderId, "用户主动申请退款");
+ Toast.show({ content: "退款申请已提交", position: "top" });
+ loadOrders(true);
+ } catch (error) {
+ console.error("申请退款失败:", error);
+ Toast.show({ content: "申请失败,请重试", position: "top" });
+ }
+ }
+ };
+
+ const renderOrderItem = (order: RechargeOrder) => (
+
+
+
+
订单号:{order.orderNo}
+
+
+ {formatTime(order.createTime)}
+
+
+
+
+ ¥{order.amount.toFixed(2)}
+
+
+ {getStatusText(order.status)}
+
+
+
+
+
+
+
+ {getPaymentMethodIcon(order.paymentMethod)}
+
+
{order.paymentMethod}
+
+
+ {order.description && (
+
+ 备注
+ {order.description}
+
+ )}
+
+ {order.payTime && (
+
+ 支付时间
+ {formatTime(order.payTime)}
+
+ )}
+
+ {order.balance !== undefined && (
+
+ 充值后余额: ¥{order.balance.toFixed(2)}
+
+ )}
+
+
+ {order.status === "pending" && (
+
+
+
+ )}
+
+ {order.status === "success" && (
+
+
+
+
+ )}
+
+ {order.status === "failed" && (
+
+
+
+ )}
+
+ );
+
+ const filterTabs = [
+ { key: "all", label: "全部" },
+ { key: "success", label: "成功" },
+ { key: "pending", label: "处理中" },
+ { key: "failed", label: "失败" },
+ { key: "cancelled", label: "已取消" },
+ ];
+
+ return (
+ }
+ loading={loading && page === 1}
+ >
+
+
+
+ {filterTabs.map(tab => (
+
+ ))}
+
+
+
+ {orders.length === 0 && !loading ? (
+
}
+ />
+ ) : (
+
+ {orders.map(renderOrderItem)}
+ {loading && page > 1 && (
+
+ )}
+ {!loading && hasMore && (
+
loadOrders()}>
+ 加载更多
+
+ )}
+
+ )}
+
+
+ );
+};
+
+export default RechargeOrders;
diff --git a/nkebao/src/pages/mobile/mine/setting/Privacy.tsx b/nkebao/src/pages/mobile/mine/setting/Privacy.tsx
index ab3f0737..4a3ea570 100644
--- a/nkebao/src/pages/mobile/mine/setting/Privacy.tsx
+++ b/nkebao/src/pages/mobile/mine/setting/Privacy.tsx
@@ -1,27 +1,17 @@
import React from "react";
-import { useNavigate } from "react-router-dom";
-import { NavBar, Card } from "antd-mobile";
+import { Card } from "antd-mobile";
import Layout from "@/components/Layout/Layout";
import style from "./index.module.scss";
+import NavCommon from "@/components/NavCommon";
const Privacy: React.FC = () => {
- const navigate = useNavigate();
-
return (
- navigate(-1)} style={{ background: "#fff" }}>
-
- 用户隐私协议
-
-
- }
- >
+ }>
用户隐私协议
-
更新时间:2024年12月1日
+
更新时间:2025年8月1日
1. 信息收集
diff --git a/nkebao/src/router/module/mine.tsx b/nkebao/src/router/module/mine.tsx
index 431c3da2..9bdb1ac3 100644
--- a/nkebao/src/router/module/mine.tsx
+++ b/nkebao/src/router/module/mine.tsx
@@ -6,6 +6,7 @@ import TrafficPoolDetail from "@/pages/mobile/mine/traffic-pool/detail/index";
import WechatAccounts from "@/pages/mobile/mine/wechat-accounts/list/index";
import WechatAccountDetail from "@/pages/mobile/mine/wechat-accounts/detail/index";
import Recharge from "@/pages/mobile/mine/recharge/index";
+import RechargeOrder from "@/pages/mobile/mine/recharge/order/index";
import Setting from "@/pages/mobile/mine/setting/index";
import SecuritySetting from "@/pages/mobile/mine/setting/SecuritySetting";
import About from "@/pages/mobile/mine/setting/About";
@@ -54,6 +55,11 @@ const routes = [
element: ,
auth: true,
},
+ {
+ path: "/recharge/order",
+ element: ,
+ auth: true,
+ },
{
path: "/settings",
element: ,