diff --git a/src/app.config.ts b/src/app.config.ts
index 6b57329..de03c8c 100644
--- a/src/app.config.ts
+++ b/src/app.config.ts
@@ -25,6 +25,7 @@ export default defineAppConfig({
"edit/index", // 编辑个人中心
"other/index", // 他人个人主页
"follow/index", // 球友关注页
+ "wallet/index", // 钱包页
],
},
// {
diff --git a/src/game_pages/detail/index.tsx b/src/game_pages/detail/index.tsx
index d15244f..d2028db 100644
--- a/src/game_pages/detail/index.tsx
+++ b/src/game_pages/detail/index.tsx
@@ -230,12 +230,18 @@ function toast(message) {
Taro.showToast({ title: message, icon: "none" });
}
-function isFull (counts) {
+function isFull(counts) {
const { max_players, current_players, max_substitute_players, current_substitute_count, is_substitute_supported } = counts
- if (is_substitute_supported === IsSubstituteSupported.SUPPORT) {
+ if (max_players === current_players) {
+
+ return true
+ }
+
+ else if (is_substitute_supported === IsSubstituteSupported.SUPPORT) {
return max_substitute_players === current_substitute_count
}
- return max_players === current_players
+
+ return false
}
// 底部操作栏
@@ -354,7 +360,7 @@ function StickyButton(props) {
return "";
}
- const { text, available = true, action = () => {} } = generateTextAndAction(user_action_status)!;
+ const { text, available = true, action = () => { } } = generateTextAndAction(user_action_status)!;
let ActionText: React.FC | string = text;
@@ -552,7 +558,7 @@ function GameInfo(props) {
{ latitude: c_latitude, longitude: c_longitude },
]}
includePadding={{ left: 50, right: 50, top: 50, bottom: 50 }}
- onError={() => {}}
+ onError={() => { }}
// hide business msg
showLocation
theme="dark"
@@ -752,9 +758,8 @@ function Participants(props) {
{participants.map((participant) => {
@@ -863,8 +868,8 @@ function genRecommendGames(games, location, avatar) {
skill_level_max !== skill_level_min
? `${skill_level_min || "-"}至${skill_level_max || "-"}`
: skill_level_min === "1"
- ? "无要求"
- : `${skill_level_min}以上`,
+ ? "无要求"
+ : `${skill_level_min}以上`,
playType: play_type,
};
});
@@ -874,7 +879,7 @@ function OrganizerInfo(props) {
const {
userInfo,
currentLocation: location,
- onUpdateUserInfo = () => {},
+ onUpdateUserInfo = () => { },
handleViewUserInfo,
handleAddComment,
} = props;
diff --git a/src/services/walletService.ts b/src/services/walletService.ts
new file mode 100644
index 0000000..a431003
--- /dev/null
+++ b/src/services/walletService.ts
@@ -0,0 +1,115 @@
+import httpService from "./httpService";
+
+// 钱包信息接口
+export interface WalletInfo {
+ balance: number;
+ total_income: number;
+ total_withdraw: number;
+}
+
+// 交易记录接口
+export interface TransactionRecord {
+ id: string;
+ type: "withdraw" | "income" | "refund";
+ amount: number;
+ description: string;
+ created_time: string;
+ status: "pending" | "success" | "failed";
+}
+
+// 提现请求接口
+export interface WithdrawRequest {
+ amount: number;
+ bank_id: string;
+}
+
+
+
+export class WalletService {
+ /**
+ * 获取钱包信息
+ */
+ static async get_wallet_info(): Promise {
+ try {
+ const response = await httpService.post("/api/wallet/get_info", {});
+
+ if (response.code === 200) {
+ return response.data;
+ } else {
+ throw new Error(response.message || "获取钱包信息失败");
+ }
+ } catch (error) {
+ console.error("获取钱包信息失败:", error);
+ // 返回模拟数据
+ return {
+ balance: 1588.80,
+ total_income: 3200.00,
+ total_withdraw: 1611.20,
+ };
+ }
+ }
+
+ /**
+ * 获取交易记录
+ */
+ static async get_transactions(): Promise {
+ try {
+ const response = await httpService.post("/api/wallet/get_transactions", {});
+
+ if (response.code === 200) {
+ return response.data;
+ } else {
+ throw new Error(response.message || "获取交易记录失败");
+ }
+ } catch (error) {
+ console.error("获取交易记录失败:", error);
+ // 返回模拟数据
+ return [
+ {
+ id: "1",
+ type: "income",
+ amount: 150.00,
+ description: "球局收入",
+ created_time: "2024-12-20 14:30:00",
+ status: "success",
+ },
+ {
+ id: "2",
+ type: "withdraw",
+ amount: 200.00,
+ description: "提现",
+ created_time: "2024-12-19 10:15:00",
+ status: "success",
+ },
+ {
+ id: "3",
+ type: "refund",
+ amount: 80.00,
+ description: "球局退款",
+ created_time: "2024-12-18 16:45:00",
+ status: "success",
+ },
+ ];
+ }
+ }
+
+ /**
+ * 提交提现申请
+ */
+ static async submit_withdraw(request: WithdrawRequest): Promise {
+ try {
+ const response = await httpService.post("/wallet/withdraw", {
+ amount: request.amount,
+ transfer_remark: "用户申请提现"
+ });
+
+ if (response.code !== 200) {
+ throw new Error(response.message || "提现申请提交失败");
+ }
+ } catch (error) {
+ console.error("提现申请提交失败:", error);
+ throw error;
+ }
+ }
+
+}
diff --git a/src/static/userInfo/bank_card.svg b/src/static/userInfo/bank_card.svg
new file mode 100644
index 0000000..a1a7eed
--- /dev/null
+++ b/src/static/userInfo/bank_card.svg
@@ -0,0 +1,6 @@
+
diff --git a/src/static/userInfo/income_icon.svg b/src/static/userInfo/income_icon.svg
new file mode 100644
index 0000000..cc7d323
--- /dev/null
+++ b/src/static/userInfo/income_icon.svg
@@ -0,0 +1,4 @@
+
diff --git a/src/static/userInfo/recharge_btn.svg b/src/static/userInfo/recharge_btn.svg
new file mode 100644
index 0000000..971984a
--- /dev/null
+++ b/src/static/userInfo/recharge_btn.svg
@@ -0,0 +1,5 @@
+
diff --git a/src/static/userInfo/refund_icon.svg b/src/static/userInfo/refund_icon.svg
new file mode 100644
index 0000000..f98f74e
--- /dev/null
+++ b/src/static/userInfo/refund_icon.svg
@@ -0,0 +1,4 @@
+
diff --git a/src/static/userInfo/transaction_icon.svg b/src/static/userInfo/transaction_icon.svg
new file mode 100644
index 0000000..ed9d481
--- /dev/null
+++ b/src/static/userInfo/transaction_icon.svg
@@ -0,0 +1,4 @@
+
diff --git a/src/static/userInfo/transaction_list.svg b/src/static/userInfo/transaction_list.svg
new file mode 100644
index 0000000..80c4c50
--- /dev/null
+++ b/src/static/userInfo/transaction_list.svg
@@ -0,0 +1,6 @@
+
diff --git a/src/static/userInfo/withdraw_btn.svg b/src/static/userInfo/withdraw_btn.svg
new file mode 100644
index 0000000..2489285
--- /dev/null
+++ b/src/static/userInfo/withdraw_btn.svg
@@ -0,0 +1,5 @@
+
diff --git a/src/static/userInfo/withdraw_icon.svg b/src/static/userInfo/withdraw_icon.svg
new file mode 100644
index 0000000..c658d1e
--- /dev/null
+++ b/src/static/userInfo/withdraw_icon.svg
@@ -0,0 +1,4 @@
+
diff --git a/src/user_pages/myself/index.tsx b/src/user_pages/myself/index.tsx
index c56fa46..034980b 100644
--- a/src/user_pages/myself/index.tsx
+++ b/src/user_pages/myself/index.tsx
@@ -30,13 +30,13 @@ const MyselfPage: React.FC = () => {
participated: 0,
},
bio: "加载中...",
+ city: "加载中...",
occupation: "加载中...",
ntrp_level: "NTRP 3.0",
personal_profile: "加载中...",
gender: '',
country: '',
province: '',
- city: '',
});
// 球局记录状态
@@ -146,10 +146,10 @@ const MyselfPage: React.FC = () => {
});
};
- // 处理收藏
- const handle_favorites = () => {
+ // 处理钱包
+ const handle_wallet = () => {
Taro.navigateTo({
- url: "/other_pages/favorites/index",
+ url: "/user_pages/wallet/index",
});
};
@@ -183,7 +183,7 @@ const MyselfPage: React.FC = () => {
球局订单
-
+
{
+ // 钱包信息状态
+ const [wallet_info, set_wallet_info] = useState({
+ balance: 0,
+ });
+
+ // 提现弹窗状态
+ const [show_withdraw_popup, set_show_withdraw_popup] = useState(false);
+ const [withdraw_amount, set_withdraw_amount] = useState("");
+ const [submitting, set_submitting] = useState(false);
+
+ // 交易记录状态
+ const [transactions, set_transactions] = useState([]);
+ const [loading_transactions, set_loading_transactions] = useState(false);
+
+ // 页面显示时加载数据
+ useDidShow(() => {
+ load_wallet_data();
+ load_transactions();
+ });
+
+ // 加载钱包数据
+ const load_wallet_data = async () => {
+ try {
+ const response = await httpService.post("/wallet/balance");
+ const { balance, frozen_balance, total_balance, total_income, total_withdraw } = response.data;
+ set_wallet_info({
+ balance,
+ frozen_balance,
+ total_balance,
+ total_income,
+ total_withdraw
+ });
+ } catch (error: any) {
+ console.error("加载钱包数据失败:", error);
+
+ let errorMessage = "加载失败,请重试";
+ if (error && error.response && error.response.data && error.response.data.message) {
+ errorMessage = error.response.data.message;
+ } else if (error && error.data && error.data.message) {
+ errorMessage = error.data.message;
+ }
+
+ Taro.showToast({
+ title: errorMessage,
+ icon: "error",
+ duration: 2000,
+ });
+ }
+ };
+
+ // 加载交易记录
+ const load_transactions = async () => {
+ try {
+ set_loading_transactions(true);
+ console.log("开始加载交易记录...");
+
+ const response = await httpService.post("/wallet/transactions", {
+ page: 1,
+ limit: 20
+ });
+
+ console.log("交易记录响应:", response);
+
+ if (response && response.data && response.data.list) {
+ set_transactions(response.data.list);
+ console.log("设置交易记录:", response.data.list);
+ } else {
+ console.log("响应数据格式异常:", response);
+ set_transactions([]);
+ }
+ } catch (error: any) {
+ console.error("加载交易记录失败:", error);
+ set_transactions([]);
+
+ let errorMessage = "加载交易记录失败";
+ if (error && error.response && error.response.data && error.response.data.message) {
+ errorMessage = error.response.data.message;
+ } else if (error && error.data && error.data.message) {
+ errorMessage = error.data.message;
+ }
+
+ Taro.showToast({
+ title: errorMessage,
+ icon: "error",
+ duration: 2000,
+ });
+ } finally {
+ console.log("加载交易记录完成,设置loading为false");
+ set_loading_transactions(false);
+ }
+ };
+
+ // 处理提现
+ const handle_withdraw = () => {
+ if (wallet_info.balance <= 0) {
+ Taro.showToast({
+ title: "余额不足",
+ icon: "error",
+ duration: 2000,
+ });
+ return;
+ }
+ set_show_withdraw_popup(true);
+ };
+
+ // 提交提现申请
+ const submit_withdraw = async () => {
+ if (!withdraw_amount || parseFloat(withdraw_amount) <= 0) {
+ Taro.showToast({
+ title: "请输入有效金额",
+ icon: "error",
+ duration: 2000,
+ });
+ return;
+ }
+
+ if (parseFloat(withdraw_amount) > wallet_info.balance) {
+ Taro.showToast({
+ title: "提现金额不能超过余额",
+ icon: "error",
+ duration: 2000,
+ });
+ return;
+ }
+
+
+ set_submitting(true);
+
+ // 先调用后端接口获取提现参数
+ const response = await httpService.post("/wallet/withdraw", {
+ amount: parseFloat(withdraw_amount),
+ transfer_remark: "用户申请提现"
+ });
+
+ // 根据后端返回的数据结构解析参数
+ const { mch_id, app_id, package: package_info, open_id } = response.data;
+
+ // 调用微信商户转账接口
+ (Taro as any).requestMerchantTransfer({
+ mchId: mch_id,
+ appId: app_id,
+ package: package_info,
+ openId: open_id,
+ success: (res) => {
+ console.log("微信转账成功:", res);
+
+ Taro.showToast({
+ title: "提现成功",
+ icon: "success",
+ duration: 2000,
+ });
+
+ // 关闭弹窗并重置状态
+ set_show_withdraw_popup(false);
+ set_withdraw_amount("");
+ // 重新加载数据
+ load_wallet_data();
+ },
+ fail: (res) => {
+ console.log("微信转账失败:", res);
+ }
+ });
+
+
+ };
+
+
+ // 格式化金额显示
+ const format_amount = (amount: number | string) => {
+ const numAmount = typeof amount === 'string' ? parseFloat(amount) : amount;
+ return numAmount.toFixed(2);
+ };
+
+ // 格式化时间显示
+ const format_time = (time: string) => {
+ const date = new Date(time);
+ const month = String(date.getMonth() + 1).padStart(2, '0');
+ const day = String(date.getDate()).padStart(2, '0');
+ const hours = String(date.getHours()).padStart(2, '0');
+ const minutes = String(date.getMinutes()).padStart(2, '0');
+ const seconds = String(date.getSeconds()).padStart(2, '0');
+
+ return {
+ date: `2025-${month}-${day}`,
+ time: `${hours}:${minutes}:${seconds}`
+ };
+ };
+
+ // 获取交易类型文字
+ const get_transaction_type_text = (transaction: Transaction) => {
+ // 如果有描述信息,优先使用描述
+ if (transaction.description) {
+ return transaction.description;
+ }
+
+ const typeMap: { [key: string]: string } = {
+ 'income': '收入',
+ 'expense': '支出',
+ 'freeze': '冻结',
+ 'unfreeze': '解冻'
+ };
+
+ let typeText = typeMap[transaction.transaction_type] || transaction.transaction_type;
+
+ // 如果有冻结操作,添加到类型文字中
+ if (transaction.freeze_action) {
+ const freezeMap: { [key: string]: string } = {
+ 'freeze': '冻结',
+ 'unfreeze': '解冻'
+ };
+ typeText += `(${freezeMap[transaction.freeze_action]})`;
+ }
+
+ return typeText;
+ };
+
+ // 获取金额显示(带符号)
+ const get_amount_display = (transaction: Transaction) => {
+ const isPositive = transaction.transaction_type === 'income';
+ const prefix = isPositive ? '+' : '-';
+ return `${prefix}${format_amount(transaction.amount)}`;
+ };
+
+ return (
+
+ {/* 钱包主卡片 */}
+
+ {/* 头部信息 */}
+
+ 我的现金
+ 修改交易密码
+
+
+ {/* 余额显示 */}
+
+
+
+ ¥
+
+ {Math.floor(wallet_info.balance)}
+ .{((wallet_info.balance % 1) * 100).toFixed(0).padStart(2, '0')}
+
+
+
+
+ 可提现金额:¥{format_amount(wallet_info.balance)}
+
+
+
+ {/* 功能按钮区域 */}
+
+
+
+ 📄
+
+ 全部账单
+
+
+
+ 🔍
+
+ 查询交易
+
+
+
+ ⬇️
+
+ 下载账单
+
+
+
+ 💬
+
+ 客服中心
+
+
+
+ {/* 现金明细 */}
+
+ {/* 标题栏 */}
+
+ 现金明细
+
+ 2025-09
+ ⌄
+
+
+
+ {/* 交易记录列表 */}
+
+ {loading_transactions ? (
+
+ 加载中...
+
+ ) : transactions.length > 0 ? (
+ transactions.map((transaction) => {
+ const timeInfo = format_time(transaction.create_time);
+ return (
+
+
+
+ {get_transaction_type_text(transaction)}
+
+
+ {timeInfo.date}
+ {timeInfo.time}
+
+
+
+
+ {get_amount_display(transaction)}
+
+
+ 余额 ¥{format_amount(wallet_info.balance)}
+
+
+
+ );
+ })
+ ) : (
+
+ 暂无交易记录
+
+ )}
+
+
+
+ {/* 提现弹窗 */}
+ set_show_withdraw_popup(false)}
+ onConfirm={submit_withdraw}
+ title="申请提现"
+ className="withdraw_popup"
+ >
+
+
+ {/* 提现金额 */}
+
+ 提现金额
+
+ ¥
+ set_withdraw_amount(e.detail.value)}
+ />
+
+
+ 可提现余额:¥{format_amount(wallet_info.balance)}
+
+
+
+ {/* 提现说明 */}
+
+ 提现说明
+
+
+ 提现申请提交后,我们将在1-3个工作日内处理并转账到您的账户
+
+
+
+
+
+
+
+ );
+};
+
+export default withAuth(WalletPage);