日期范围选择器、账单筛选
This commit is contained in:
@@ -4,26 +4,26 @@
|
||||
min-height: 100vh;
|
||||
background-color: #f5f5f5;
|
||||
padding: 5px;
|
||||
|
||||
|
||||
.wallet_main_card {
|
||||
background: #000;
|
||||
border-radius: 20px;
|
||||
padding: 12px 20px 32px;
|
||||
margin-bottom: 8px;
|
||||
color: #fff;
|
||||
|
||||
|
||||
.card_header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 32px;
|
||||
|
||||
|
||||
.header_title {
|
||||
font-size: 12px;
|
||||
font-weight: 400;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
|
||||
.modify_password {
|
||||
font-size: 12px;
|
||||
font-weight: 400;
|
||||
@@ -31,37 +31,37 @@
|
||||
line-height: 1.5;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.balance_display {
|
||||
.amount_section {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 8px;
|
||||
|
||||
|
||||
.amount_container {
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
gap: 8px;
|
||||
|
||||
|
||||
.currency_symbol {
|
||||
font-family: 'DingTalk JinBuTi', sans-serif;
|
||||
font-size: 32px;
|
||||
font-weight: 400;
|
||||
line-height: 0.8;
|
||||
}
|
||||
|
||||
|
||||
.amount_group {
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
|
||||
|
||||
.main_amount {
|
||||
font-family: 'DingTalk JinBuTi', sans-serif;
|
||||
font-size: 32px;
|
||||
font-weight: 400;
|
||||
line-height: 0.75;
|
||||
}
|
||||
|
||||
|
||||
.decimal_amount {
|
||||
font-family: 'DingTalk JinBuTi', sans-serif;
|
||||
font-size: 32px;
|
||||
@@ -70,7 +70,7 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.withdraw_btn {
|
||||
background: #fff;
|
||||
border: none;
|
||||
@@ -86,7 +86,7 @@
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.available_amount {
|
||||
font-size: 12px;
|
||||
font-weight: 400;
|
||||
@@ -95,13 +95,13 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.function_buttons {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
margin-bottom: 8px;
|
||||
|
||||
|
||||
.function_item {
|
||||
background: white;
|
||||
border: 0.5px solid #EBEBEB;
|
||||
@@ -114,19 +114,19 @@
|
||||
box-shadow: 0px 4px 36px 0px rgba(0, 0, 0, 0.05);
|
||||
height: 24px;
|
||||
flex: 1;
|
||||
|
||||
|
||||
.function_icon {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
|
||||
.icon_text {
|
||||
font-size: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.function_text {
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
@@ -134,7 +134,7 @@
|
||||
line-height: 1.33;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
|
||||
&:active {
|
||||
background: #f8f8f8;
|
||||
}
|
||||
@@ -169,7 +169,8 @@
|
||||
position: relative;
|
||||
padding-right: 16px;
|
||||
|
||||
&::before, &::after {
|
||||
&::before,
|
||||
&::after {
|
||||
content: '';
|
||||
display: block;
|
||||
width: 2px;
|
||||
@@ -195,6 +196,7 @@
|
||||
}
|
||||
|
||||
.transaction_list {
|
||||
|
||||
.loading_state,
|
||||
.empty_state {
|
||||
padding: 40px 20px;
|
||||
@@ -277,21 +279,21 @@
|
||||
.popup_content {
|
||||
padding: 12px;
|
||||
overflow: hidden;
|
||||
|
||||
|
||||
.form_section {
|
||||
.form_item {
|
||||
margin-bottom: 12px;
|
||||
|
||||
|
||||
.form_label {
|
||||
font-size: 12px;
|
||||
color: #333;
|
||||
margin-bottom: 6px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
|
||||
.input_wrapper {
|
||||
position: relative;
|
||||
|
||||
|
||||
.amount_input {
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
@@ -301,17 +303,17 @@
|
||||
padding: 0 10px;
|
||||
font-size: 14px;
|
||||
color: #333;
|
||||
|
||||
|
||||
&:focus {
|
||||
border-color: #667eea;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
|
||||
&::placeholder {
|
||||
color: #bbb;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.currency_symbol {
|
||||
position: absolute;
|
||||
left: 10px;
|
||||
@@ -321,24 +323,24 @@
|
||||
color: #999;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
|
||||
.amount_input.with_symbol {
|
||||
padding-left: 28px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.balance_tip {
|
||||
font-size: 10px;
|
||||
color: #999;
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
|
||||
.withdraw_desc {
|
||||
padding: 8px;
|
||||
background: #f8f9fa;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #e9ecef;
|
||||
|
||||
|
||||
.desc_text {
|
||||
font-size: 10px;
|
||||
color: #666;
|
||||
@@ -349,3 +351,40 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 过滤弹窗
|
||||
.filter_popup {
|
||||
padding: 20px;
|
||||
|
||||
.popup_content {
|
||||
.form_section {
|
||||
.form_item {
|
||||
margin-bottom: 20px;
|
||||
.form_label {
|
||||
display: inline-block;
|
||||
font-family: PingFang SC;
|
||||
font-weight: 600;
|
||||
font-style: Semibold;
|
||||
font-size: 16px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.options_wrapper {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 8px;
|
||||
.option_item {
|
||||
background-color: #0000000D;
|
||||
text-align: center;
|
||||
padding: 8px;
|
||||
border-radius: 4px;
|
||||
&.active {
|
||||
background-color: #000000;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useState } from "react";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { View, Text, Input, Button, Image } from "@tarojs/components";
|
||||
import Taro, { useDidShow } from "@tarojs/taro";
|
||||
import "./index.scss";
|
||||
@@ -28,6 +28,71 @@ interface WalletInfo {
|
||||
total_withdraw?: number;
|
||||
}
|
||||
|
||||
enum TransactionType {
|
||||
All = '',
|
||||
Income = 'income',
|
||||
Expense = 'expense',
|
||||
}
|
||||
|
||||
enum TransactionSubType {
|
||||
All = '',
|
||||
GameActivity = 'game_activity',
|
||||
Withdrawal = 'withdrawal',
|
||||
Refund = 'refund',
|
||||
Compensation = 'compensation',
|
||||
}
|
||||
|
||||
interface TransactionLoadParams {
|
||||
page: number;
|
||||
limit: number;
|
||||
type: TransactionType;
|
||||
transaction_sub_type: TransactionSubType;
|
||||
keyword?: string;
|
||||
date?: string;
|
||||
}
|
||||
interface Option<T> {
|
||||
label: string;
|
||||
value: T;
|
||||
}
|
||||
|
||||
const income_expense_options: Option<TransactionType>[] = [
|
||||
{
|
||||
label: '全部',
|
||||
value: TransactionType.All
|
||||
},
|
||||
{
|
||||
label: '支出',
|
||||
value: TransactionType.Expense
|
||||
},
|
||||
{
|
||||
label: '收入',
|
||||
value: TransactionType.Income
|
||||
},
|
||||
];
|
||||
|
||||
const transaction_type_options: Option<TransactionSubType>[] = [
|
||||
{
|
||||
label: '全部',
|
||||
value: TransactionSubType.All
|
||||
},
|
||||
{
|
||||
label: '组织活动',
|
||||
value: TransactionSubType.GameActivity
|
||||
},
|
||||
{
|
||||
label: '提现',
|
||||
value: TransactionSubType.Withdrawal
|
||||
},
|
||||
{
|
||||
label: '退款',
|
||||
value: TransactionSubType.Refund
|
||||
},
|
||||
{
|
||||
label: '企业赔付',
|
||||
value: TransactionSubType.Compensation
|
||||
},
|
||||
];
|
||||
|
||||
|
||||
const WalletPage: React.FC = () => {
|
||||
// 钱包信息状态
|
||||
@@ -44,6 +109,18 @@ const WalletPage: React.FC = () => {
|
||||
const [transactions, set_transactions] = useState<Transaction[]>([]);
|
||||
const [loading_transactions, set_loading_transactions] = useState(false);
|
||||
|
||||
// 交易记录过滤状态
|
||||
const [showFilterPopup, setShowFilterPopup] = useState(false);
|
||||
|
||||
const [load_transactions_params, set_load_transactions_params] = useState<TransactionLoadParams>({
|
||||
page: 1,
|
||||
limit: 20,
|
||||
type: TransactionType.All,
|
||||
transaction_sub_type: TransactionSubType.All,
|
||||
keyword: "",
|
||||
date: ""
|
||||
});
|
||||
|
||||
// 页面显示时加载数据
|
||||
useDidShow(() => {
|
||||
load_wallet_data();
|
||||
@@ -82,14 +159,13 @@ const WalletPage: React.FC = () => {
|
||||
|
||||
// 加载交易记录
|
||||
const load_transactions = async () => {
|
||||
setShowFilterPopup(false);
|
||||
set_load_transactions_params({ ...load_transactions_params, page: 1 });
|
||||
try {
|
||||
set_loading_transactions(true);
|
||||
console.log("开始加载交易记录...");
|
||||
|
||||
const response = await httpService.post("/wallet/transactions", {
|
||||
page: 1,
|
||||
limit: 20
|
||||
});
|
||||
const response = await httpService.post("/wallet/transactions", { ...load_transactions_params });
|
||||
|
||||
console.log("交易记录响应:", response);
|
||||
|
||||
@@ -165,7 +241,7 @@ const WalletPage: React.FC = () => {
|
||||
});
|
||||
|
||||
// 根据后端返回的数据结构解析参数
|
||||
const { mch_id, app_id, package_info, open_id } = response.data;
|
||||
const { mch_id, app_id, package_info, open_id } = response.data;
|
||||
|
||||
console.log("/wallet/withdraw:", response.data);
|
||||
|
||||
@@ -255,6 +331,10 @@ const WalletPage: React.FC = () => {
|
||||
return `${prefix}${format_amount(transaction.amount)}`;
|
||||
};
|
||||
|
||||
const show_filter_popup = () => {
|
||||
setShowFilterPopup(true)
|
||||
}
|
||||
|
||||
return (
|
||||
<View className="wallet_page">
|
||||
{/* 钱包主卡片 */}
|
||||
@@ -285,7 +365,7 @@ const WalletPage: React.FC = () => {
|
||||
|
||||
{/* 功能按钮区域 */}
|
||||
<View className="function_buttons">
|
||||
<View className="function_item">
|
||||
<View className="function_item" onClick={show_filter_popup}>
|
||||
<Text className="function_text">全部账单</Text>
|
||||
<Image className="function_icon" src={require("@/static/wallet/arrow-down.svg")} />
|
||||
</View>
|
||||
@@ -392,6 +472,37 @@ const WalletPage: React.FC = () => {
|
||||
</View>
|
||||
</View>
|
||||
</CommonPopup>
|
||||
|
||||
{/* 筛选账单弹窗 */}
|
||||
<CommonPopup
|
||||
visible={showFilterPopup}
|
||||
onClose={() => setShowFilterPopup(false)}
|
||||
onConfirm={load_transactions}
|
||||
title="选择筛选项"
|
||||
className="filter_popup"
|
||||
>
|
||||
<View className="popup_content">
|
||||
<View className="form_section">
|
||||
<View className="form_item">
|
||||
<Text className="form_label">收支类型</Text>
|
||||
<View className="options_wrapper">
|
||||
{income_expense_options.map((option: Option<TransactionType>) => (
|
||||
<View className={load_transactions_params.type === option.value ? "option_item active" : "option_item"} key={option.value} onClick={() => { set_load_transactions_params({ ...load_transactions_params, type: option.value }) }}>{option.label}</View>
|
||||
))}
|
||||
</View>
|
||||
</View>
|
||||
<View className="form_item">
|
||||
<Text className="form_label">交易类型</Text>
|
||||
<View className="options_wrapper">
|
||||
{transaction_type_options.map((option: Option<TransactionSubType>) => (
|
||||
<View className={load_transactions_params.transaction_sub_type === option.value ? "option_item active" : "option_item"} key={option.value} onClick={() => { set_load_transactions_params({ ...load_transactions_params, transaction_sub_type: option.value }) }}>{option.label}</View>
|
||||
))}
|
||||
</View>
|
||||
</View>
|
||||
|
||||
</View>
|
||||
</View>
|
||||
</CommonPopup>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user