From 5f13effcd447e95ef29da48473a4894f3f6669a7 Mon Sep 17 00:00:00 2001 From: Ultrame <1019265060@qq.com> Date: Tue, 30 Sep 2025 17:18:44 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=97=E8=A1=A8=E5=8A=A0=E8=BD=BD=E6=9B=B4?= =?UTF-8?q?=E5=A4=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/store/listStore.ts | 4 +- src/user_pages/queryTransactions/index.scss | 386 +++++++++--------- src/user_pages/queryTransactions/index.tsx | 115 +++--- .../setTransactionPassword/index.tsx | 196 +++++---- src/user_pages/wallet/index.tsx | 53 ++- src/user_pages/withdrawal/index.tsx | 4 +- 6 files changed, 419 insertions(+), 339 deletions(-) diff --git a/src/store/listStore.ts b/src/store/listStore.ts index dbdfefc..94f2ce3 100644 --- a/src/store/listStore.ts +++ b/src/store/listStore.ts @@ -435,11 +435,11 @@ export const useListStore = create()((set, get) => ({ const state = get(); const currentPageState = state.isSearchResult ? state.searchPageState : state.listPageState; const { pageOption, isHasMoreData } = currentPageState || {}; - + if (!isHasMoreData) { return; } - + const newPageOption = { page: (pageOption?.page || 1) + 1, pageSize: 20, diff --git a/src/user_pages/queryTransactions/index.scss b/src/user_pages/queryTransactions/index.scss index d0bbd4e..f4cb1ed 100644 --- a/src/user_pages/queryTransactions/index.scss +++ b/src/user_pages/queryTransactions/index.scss @@ -1,206 +1,226 @@ .listSearchContainer { - padding: 0 15px; - padding-top: 16px; + padding: 0 15px; + padding-top: 16px; - .icon16 { - width: 16px; - height: 16px; + .icon16 { + width: 16px; + height: 16px; + } + + .topSearchWrapper { + position: fixed; + top: 0; + left: 0; + background-color: #fff; + width: 100vw; + padding: 5px 15px; + box-sizing: border-box; + } + + .topSearch { + display: flex; + align-items: center; + height: 44px; + box-sizing: border-box; + gap: 10px; + border-radius: 44px; + border: 0.5px solid rgba(0, 0, 0, 0.06); + background: #fff; + box-shadow: 0 4px 48px 0 rgba(0, 0, 0, 0.08); + padding: 0 16px 0 12px; + + .nut-input { + padding: 0; + height: 100%; + } + } + + .historySearch { + padding-top: 50px; + } + + .searchRight { + display: flex; + align-items: center; + gap: 12px; + + .searchLine { + width: 1px; + height: 20px; + border-radius: 20px; + background: rgba(0, 0, 0, 0.06); } - .topSearch { - padding: 5px 16px 5px 12px; - display: flex; - align-items: center; - height: 44px; - box-sizing: border-box; - gap: 10px; - border-radius: 44px; - border: 0.5px solid rgba(0, 0, 0, 0.06); - background: #fff; - box-shadow: 0 4px 48px 0 rgba(0, 0, 0, 0.08); + .searchText { + color: #000000; + font-size: 16px; + font-weight: 600; + line-height: 20px; + } + } - .nut-input { - padding: 0; - height: 100%; - } + .searchIcon { + width: 20px; + height: 20px; + } + + .historySearchTitleWrapper { + display: flex; + padding: 12px 0; + justify-content: space-between; + align-items: flex-end; + align-self: stretch; + + .historySearchTitle, + .historySearchClear { + color: #000; + font-size: 14px; + font-weight: 600; + line-height: 20px; } - .searchRight { + .historySearchClear { + color: #9a9a9a; + display: flex; + align-items: center; + gap: 4px; + } + } + + .historySearchList { + display: flex; + align-items: center; + flex-wrap: wrap; + gap: 8px; + + .historySearchItem { + color: #3c3c4399; + font-size: 12px; + flex-shrink: 0; + flex-grow: 0; + display: flex; + padding: 4px 12px; + justify-content: center; + align-items: center; + gap: 2px; + border-radius: 999px; + border: 0.5px solid rgba(0, 0, 0, 0.06); + background: rgba(0, 0, 0, 0.03); + } + } + + .searchSuggestion { + padding: 6px 0; + + .searchSuggestionItem { + padding: 10px 20px; + display: flex; + align-items: center; + justify-content: space-between; + + .searchSuggestionItemLeft { display: flex; align-items: center; gap: 12px; + color: rgba(60, 60, 67, 0.6); + font-size: 14px; + font-weight: 400; + line-height: 20px; + } - .searchLine { - width: 1px; - height: 20px; - border-radius: 20px; - background: rgba(0, 0, 0, 0.06); - } + .highlight { + color: #000000; + } + } + } - .searchText { - color: #000000; - font-size: 16px; - font-weight: 600; - line-height: 20px; - } + .transaction_list { + padding: 40px 0 70px; + + .loading_state, + .empty_state { + padding: 40px 20px; + text-align: center; + + .loading_text, + .empty_text { + font-size: 14px; + color: #999; + } } - .searchIcon { - width: 20px; - height: 20px; - } + .transaction_item { + display: flex; + justify-content: space-between; + align-items: center; + padding: 12px 0; - .historySearchTitleWrapper { + .transaction_left { display: flex; - padding: 12px 0; - justify-content: space-between; + flex-direction: column; + gap: 4px; + flex: 1; + + .transaction_title { + font-size: 12px; + font-weight: 600; + color: #000; + line-height: 1.5; + text-align: left; + } + + .transaction_time { + display: flex; + align-items: center; + align-self: stretch; + gap: 4px; + + .transaction_date, + .transaction_clock { + font-size: 10px; + font-weight: 400; + color: rgba(60, 60, 67, 0.6); + line-height: 1.2; + text-align: left; + } + } + } + + .transaction_right { + display: flex; + flex-direction: column; align-items: flex-end; - align-self: stretch; + gap: 4px; + width: 68px; - .historySearchTitle, - .historySearchClear { - color: #000; - font-size: 14px; - font-weight: 600; - line-height: 20px; + .transaction_amount { + font-size: 12px; + font-weight: 600; + color: #000; + line-height: 1.5; + text-align: right; } - .historySearchClear { - color: #9a9a9a; - display: flex; - align-items: center; - gap: 4px; + .balance_info { + font-size: 10px; + font-weight: 400; + color: rgba(60, 60, 67, 0.6); + line-height: 1.2; + text-align: right; } + } } + } - .historySearchList { - display: flex; - align-items: center; - flex-wrap: wrap; - gap: 8px; - - .historySearchItem { - color: #3C3C4399; - font-size: 12px; - flex-shrink: 0; - flex-grow: 0; - display: flex; - padding: 4px 12px; - justify-content: center; - align-items: center; - gap: 2px; - border-radius: 999px; - border: 0.5px solid rgba(0, 0, 0, 0.06); - background: rgba(0, 0, 0, 0.03); - } - } - - .searchSuggestion { - padding: 6px 0; - - .searchSuggestionItem { - padding: 10px 20px; - display: flex; - align-items: center; - justify-content: space-between; - - .searchSuggestionItemLeft { - display: flex; - align-items: center; - gap: 12px; - color: rgba(60, 60, 67, 0.6); - font-size: 14px; - font-weight: 400; - line-height: 20px; - } - - .highlight { - color: #000000; - } - } - } - - .transaction_list { - - .loading_state, - .empty_state { - padding: 40px 20px; - text-align: center; - - .loading_text, - .empty_text { - font-size: 14px; - color: #999; - } - } - - .transaction_item { - display: flex; - justify-content: space-between; - align-items: center; - padding: 12px 0; - - .transaction_left { - display: flex; - flex-direction: column; - gap: 4px; - flex: 1; - - .transaction_title { - font-size: 12px; - font-weight: 600; - color: #000; - line-height: 1.5; - text-align: left; - } - - .transaction_time { - display: flex; - align-items: center; - align-self: stretch; - gap: 4px; - - .transaction_date, - .transaction_clock { - font-size: 10px; - font-weight: 400; - color: rgba(60, 60, 67, 0.6); - line-height: 1.2; - text-align: left; - } - } - } - - .transaction_right { - display: flex; - flex-direction: column; - align-items: flex-end; - gap: 4px; - width: 68px; - - .transaction_amount { - font-size: 12px; - font-weight: 600; - color: #000; - line-height: 1.5; - text-align: right; - } - - .balance_info { - font-size: 10px; - font-weight: 400; - color: rgba(60, 60, 67, 0.6); - line-height: 1.2; - text-align: right; - } - } - } - } - - .tips_text { - font-size: 12px; - text-align: center; - color: #3C3C4399; - margin-top: 20px; - } -} \ No newline at end of file + .tips_text { + font-size: 12px; + text-align: center; + color: rgba(60, 60, 67, 0.6); + position: fixed; + bottom: 0; + left: 0; + width: 100%; + padding: 20px 0 40px; + background: #fff; + } +} diff --git a/src/user_pages/queryTransactions/index.tsx b/src/user_pages/queryTransactions/index.tsx index 71bc6d2..83aa9b4 100644 --- a/src/user_pages/queryTransactions/index.tsx +++ b/src/user_pages/queryTransactions/index.tsx @@ -1,12 +1,11 @@ -import { useState } from "react"; +import { useState, useEffect, useRef } from "react"; import { View, Image, Text } from "@tarojs/components"; import { Input } from "@nutui/nutui-react-taro"; -import { useEffect, useRef } from "react"; import img from "@/config/images"; import { withAuth } from "@/components"; import "./index.scss"; import httpService from "@/services/httpService"; -import Taro from "@tarojs/taro"; +import Taro, { useReachBottom } from "@tarojs/taro"; interface Transaction { id: number; user_id: number; @@ -19,15 +18,6 @@ interface Transaction { related_id: number; } -// 钱包信息类型 -interface WalletInfo { - balance: number; - frozen_balance?: number; - total_balance?: number; - total_income?: number; - total_withdraw?: number; -} - interface History { id: number; keyword: string; @@ -39,6 +29,7 @@ interface TransactionLoadParams { } const QueryTransactions = () => { + const isInitialMount = useRef(true); const [loading_transactions, set_loading_transactions] = useState(false); const [transactions, setTransactions] = useState([]); const [searchHistory, setSearchHistory] = useState([]); @@ -63,6 +54,23 @@ const QueryTransactions = () => { } }, [ref.current]); + useReachBottom(() => { + set_load_transactions_params((prev) => { + return { + ...prev, + page: prev.page + 1, + } + }) + }); + + useEffect(() => { + if (isInitialMount.current) { + isInitialMount.current = false; + } else { + handleSearch(); + } + }, [load_transactions_params]); + // 是否显示清空图标 const isShowClearIcon = load_transactions_params.keyword && @@ -106,7 +114,6 @@ const QueryTransactions = () => { */ const handleHistoryClick = (item: { id: number; keyword: string }) => { set_load_transactions_params((prev) => { - handleSearch(item?.keyword); return { ...prev, keyword: item?.keyword }; }); }; @@ -123,21 +130,15 @@ const QueryTransactions = () => { * @description 点击搜索 */ const handleSearch = async (val?: string) => { - if (!val) { - return; - } - set_loading_transactions(true); + // set_loading_transactions(true); try { const response = await httpService.post("/wallet/transactions", { ...load_transactions_params, keyword: val, }); - console.log("交易记录响应:", response); if (response && response.data && response.data.list) { - setTransactions(response.data.list); - } else { - setTransactions([]); + setTransactions([...transactions, ...response.data.list]); } } catch (error) { setTransactions([]); @@ -169,13 +170,9 @@ const QueryTransactions = () => { return numAmount.toFixed(2); }; - // 钱包信息状态 - const [wallet_info, set_wallet_info] = useState({ - balance: 0, - }); - // 格式化时间显示 const format_time = (time: string) => { + time = time.replace(/-/g, '/'); const date = new Date(time); const month = String(date.getMonth() + 1).padStart(2, "0"); const day = String(date.getDate()).padStart(2, "0"); @@ -235,33 +232,35 @@ const QueryTransactions = () => { <> {/* 搜索 */} - - - - - {isShowClearIcon && ( - - )} - - handleSearch(load_transactions_params.keyword)} - > - 搜索 - + + + + + + {isShowClearIcon && ( + + )} + + handleSearch(load_transactions_params.keyword)} + > + 搜索 + + {/* 查找历史 */} @@ -329,7 +328,7 @@ const QueryTransactions = () => { {get_amount_display(transaction)} - 余额 ¥{format_amount(wallet_info.balance)} + 余额 ¥{format_amount(transaction.amount)} @@ -341,11 +340,9 @@ const QueryTransactions = () => { )} - { - transactions.length > 0 && ( - 仅支持查找2024年9月1日以后的账单 - ) - } + {transactions.length > 0 && ( + 仅支持查找2024年9月1日以后的账单 + )} ); diff --git a/src/user_pages/setTransactionPassword/index.tsx b/src/user_pages/setTransactionPassword/index.tsx index cd8cb78..f4e945f 100644 --- a/src/user_pages/setTransactionPassword/index.tsx +++ b/src/user_pages/setTransactionPassword/index.tsx @@ -1,95 +1,139 @@ import React, { useState, useEffect } from "react"; -import Taro, { useRouter } from '@tarojs/taro'; +import Taro, { useRouter } from "@tarojs/taro"; import { View, Text, Input, Button } from "@tarojs/components"; import "./index.scss"; import httpService from "@/services/httpService"; interface FormFields { - old_password?: string; - new_password: string; - confirm_password: string; - sms_code?: string; + old_password?: string; + new_password: string; + confirm_password: string; + sms_code?: string; } const SetTransactionPassword: React.FC = () => { - const [handleType, setHandleType] = useState("set"); - const router = useRouter(); - const { type, phone, sms_code } = router.params; + const [handleType, setHandleType] = useState("set"); + const router = useRouter(); + const { type, phone, sms_code } = router.params; - useEffect(() => { - if (type) { - setHandleType(type); - } - }, [type]); + useEffect(() => { + if (type) { + setHandleType(type); + } + }, [type]); - const [formData, setFormData] = useState({ - old_password: "", - new_password: "", - confirm_password: "", - sms_code: "", - }); + const [formData, setFormData] = useState({ + old_password: "", + new_password: "", + confirm_password: "", + sms_code: "", + }); - const handleInput = (e: any, field: string) => { - setFormData({ ...formData, [field]: e.detail.value }); - }; + const handleInput = (e: any, field: string) => { + setFormData({ ...formData, [field]: e.detail.value }); + }; - const handleConfirm = async () => { - const { new_password, confirm_password } = formData; - if (new_password !== confirm_password) { - Taro.showToast({ - title: "两次密码输入不一致", - icon: "none", - }); - return; - } - try { - await httpService.post("/wallet/set_payment_password", { password: new_password }); - Taro.showToast({ - title: "设置交易密码成功", - icon: "success", - }); - Taro.navigateBack(); - } catch (error) { - Taro.showToast({ - title: "设置交易密码失败", - icon: "none", - }); - return; - } - }; + const handleConfirm = async () => { + const { new_password, confirm_password } = formData; + if (new_password !== confirm_password) { + Taro.showToast({ + title: "两次密码输入不一致", + icon: "none", + }); + return; + } + try { + await httpService.post("/wallet/set_payment_password", { + password: new_password, + }); + Taro.showToast({ + title: "设置交易密码成功", + icon: "success", + }); + Taro.navigateBack(); + } catch (error) { + Taro.showToast({ + title: "设置交易密码失败", + icon: "none", + }); + return; + } + }; - return ( - - { - // handleType === "reset" && ( - // - // 旧密码 - // { handleInput(e, "old_password") }}> - // - // ) - } - - 交易密码 - { handleInput(e, "new_password") }}> - - - 重复密码 - { handleInput(e, "confirm_password") }}> - - { - handleType === "set" && ( - - 手机验证 - { handleInput(e, "sms_code") }}> - - - ) - } - * 密码由6位数字组成 - + const getSMSCode = async () => { + try { + await httpService.post("/wallet/send_set_password_sms", { + type: "set_password", + }); + Taro.showToast({ + title: "验证码发送成功", + icon: "none", + }); + } catch (error) { + Taro.showToast({ + title: "验证码发送失败", + icon: "none", + }); + return; + } + }; + + return ( + + { + // handleType === "reset" && ( + // + // 旧密码 + // { handleInput(e, "old_password") }}> + // + // ) + } + + 交易密码 + { + handleInput(e, "new_password"); + }} + > + + + 重复密码 + { + handleInput(e, "confirm_password"); + }} + > + + {handleType === "set" && ( + + 手机验证 + { + handleInput(e, "sms_code"); + }} + > + - ); + )} + * 密码由6位数字组成 + + + ); }; export default SetTransactionPassword; diff --git a/src/user_pages/wallet/index.tsx b/src/user_pages/wallet/index.tsx index 2da38cb..3aca5ae 100644 --- a/src/user_pages/wallet/index.tsx +++ b/src/user_pages/wallet/index.tsx @@ -7,6 +7,7 @@ import httpService from "@/services/httpService"; import { withAuth } from "@/components"; import { PopupPicker } from "@/components/Picker/index"; import { handleCustomerService } from "@/services/userService"; +import { useReachBottom } from "@tarojs/taro"; // 交易记录类型 interface Transaction { @@ -96,6 +97,15 @@ const transaction_type_options: Option[] = [ ]; const WalletPage: React.FC = () => { + useReachBottom(() => { + // 加载更多方法 + set_load_transactions_params((prev) => { + return { + ...prev, + page: prev.page + 1, + }; + }); + }); // 钱包信息状态 const [wallet_info, set_wallet_info] = useState({ balance: 0, @@ -131,7 +141,7 @@ const WalletPage: React.FC = () => { type: TransactionType.All, transaction_sub_type: TransactionSubType.All, keyword: "", - date: `${year}-${month}` + date: `${year}-${month}`, }); useEffect(() => { @@ -150,12 +160,10 @@ const WalletPage: React.FC = () => { ...prev, type, transaction_sub_type, - } - }) + }; + }); }; - - const check_password_status = async () => { try { const res = await httpService.post("/wallet/check_password_status"); @@ -163,7 +171,7 @@ const WalletPage: React.FC = () => { } catch (e) { console.error("检查交易密码状态失败:", e); } - } + }; // 加载钱包数据 const load_wallet_data = async () => { @@ -211,7 +219,7 @@ const WalletPage: React.FC = () => { setShowFilterPopup(false); // set_load_transactions_params({ ...load_transactions_params, page: 1 }); try { - set_loading_transactions(true); + if (!transactions.length) set_loading_transactions(true); console.log("开始加载交易记录..."); const response = await httpService.post("/wallet/transactions", { ...load_transactions_params, @@ -220,7 +228,7 @@ const WalletPage: React.FC = () => { console.log("交易记录响应:", response); if (response && response.data && response.data.list) { - set_transactions(response.data.list); + set_transactions([...transactions, ...response.data.list]); console.log("设置交易记录:", response.data.list); } else { console.log("响应数据格式异常:", response); @@ -254,11 +262,11 @@ const WalletPage: React.FC = () => { }; const navigateToSetTransactionPassword = (type: "set" | "reset") => { - let url = "" + let url = ""; if (type === "set") { - url = `/user_pages/setTransactionPassword/index?type=${type}` + url = `/user_pages/setTransactionPassword/index?type=${type}`; } else if (type === "reset") { - url = `/user_pages/validPhone/index` + url = `/user_pages/validPhone/index`; } Taro.navigateTo({ url, @@ -422,7 +430,12 @@ const WalletPage: React.FC = () => { {/* 头部信息 */} 我的现金 - navigateToSetTransactionPassword("reset")}>修改交易密码 + navigateToSetTransactionPassword("reset")} + > + 修改交易密码 + {/* 余额显示 */} @@ -491,7 +504,7 @@ const WalletPage: React.FC = () => { className="function_icon" src={require("@/static/wallet/custom-service.svg")} /> - 客服中心 + 客服中心 @@ -500,8 +513,13 @@ const WalletPage: React.FC = () => { {/* 标题栏 */} 现金明细 - setShowMonthPicker(true)}> - {load_transactions_params.date} + setShowMonthPicker(true)} + > + + {load_transactions_params.date} + @@ -599,7 +617,7 @@ const WalletPage: React.FC = () => { setvisible={setShowMonthPicker} value={[ Number(load_transactions_params.date!.split("-")[0]), - Number(load_transactions_params.date!.split("-")[1]) + Number(load_transactions_params.date!.split("-")[1]), ]} type="month" onChange={(e) => { @@ -653,8 +671,7 @@ const WalletPage: React.FC = () => { (option: Option) => ( { } else if (Number(amount) > 200) { setShowTips(true); setTipsText("单笔提现金额不能超过 200元"); + } else { + setShowTips(false); } }; @@ -287,4 +289,4 @@ const Withdrawal: React.FC = () => { ); }; -export default Withdrawal; \ No newline at end of file +export default Withdrawal;