diff --git a/src/app.config.ts b/src/app.config.ts index 61baa7e..5ae88f1 100644 --- a/src/app.config.ts +++ b/src/app.config.ts @@ -32,6 +32,7 @@ export default defineAppConfig({ "billDetail/index", // 账单详情 "setTransactionPassword/index", // 设置交易密码 "validPhone/index", // 验证手机号 + "withdrawal/index", // 提现 ], }, // { diff --git a/src/user_pages/downloadBill/index.scss b/src/user_pages/downloadBill/index.scss index 2a10ee3..e0682d9 100644 --- a/src/user_pages/downloadBill/index.scss +++ b/src/user_pages/downloadBill/index.scss @@ -132,3 +132,39 @@ } } } +// 过滤弹窗 +.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; + } + } + } + } + } + } +} \ No newline at end of file diff --git a/src/user_pages/downloadBill/index.tsx b/src/user_pages/downloadBill/index.tsx index 0dd43fd..f31a56a 100644 --- a/src/user_pages/downloadBill/index.tsx +++ b/src/user_pages/downloadBill/index.tsx @@ -1,20 +1,48 @@ import React, { useState, useEffect } from "react"; -import { View, Text, Button } from "@tarojs/components"; +import { View, Text, Button, Input } from "@tarojs/components"; import Taro, { useDidShow } from "@tarojs/taro"; import dayjs from "dayjs"; import "./index.scss"; import { DialogCalendarCard } from "@/components/index"; // import { CalendarUI } from "@/components"; +import { CommonPopup } from "@/components"; +export enum TransactionSubType { + All = "", + GameActivity = "game_activity", + Withdrawal = "withdrawal", + Refund = "refund", + Compensation = "compensation", +} +export enum TransactionType { + All = "", + Income = "income", + Expense = "expense", +} +interface Option { + label: string; + value: T; +} +interface TransactionLoadParams { + page: number; + limit: number; + type: TransactionType; + transaction_sub_type: TransactionSubType; + keyword?: string; + date?: string; +} const DownloadBill: React.FC = () => { const [dateRange, setDateRange] = useState({ start: "", end: "" }); const [dateType, setDateType] = useState("week"); const [visible, setVisible] = useState(false); + const [show_download_popup, set_show_download_popup] = useState(false); + const [isFocus, setIsFocus] = useState(false); + const [password, setPassword] = useState(new Array(6).fill("")); useEffect(() => { culculateDateRange(dateType); }, []); - + const [showFilterPopup, setShowFilterPopup] = useState(false); const culculateDateRange = (dateType: string) => { const today = new Date(); const year = today.getFullYear(); @@ -59,7 +87,6 @@ const DownloadBill: React.FC = () => { case "custom": setDateType("custom"); setDateRange({ start: "", end: "" }); - setVisible(true); break; } }; @@ -74,6 +101,69 @@ const DownloadBill: React.FC = () => { end: dayjs(end).format("YYYY-MM-DD"), }); }; + const handlePasswordInput = (e: any) => { + const value = e.detail.value; + const [one = "", two = "", three = "", four = "", five = "", six = ""] = value.split(""); + setPassword([one, two, three, four, five, six]); + if (value.length === 6) { + // const timer = setTimeout(() => { + // // TODO 校验密码 + // if (false) { + // set_show_download_popup(false); + // Taro.showModal({ + // content: "支付密码错误,请重试", + // cancelText: "忘记密码", + // confirmText: "重试", + // cancelColor: "#000", + // confirmColor: "#fff", + // }).then((res) => { + // if (res.confirm) { + // set_show_download_popup(true); + // } else if (res.cancel) { + // Taro.navigateTo({ + // url: "/user_pages/validPhone/index" + // }); + // } + // }).finally(() => { + // clearTimeout(timer); + // }); + // } else { + // // TODO 下载账单 + // } + // }, 100); + } + } + const transaction_type_options: Option[] = [ + { + label: "全部", + value: TransactionSubType.All, + }, + { + label: "组织活动", + value: TransactionSubType.GameActivity, + }, + { + label: "提现", + value: TransactionSubType.Withdrawal, + }, + { + label: "退款", + value: TransactionSubType.Refund, + }, + { + label: "企业赔付", + value: TransactionSubType.Compensation, + }, + ]; + const [load_transactions_params, set_load_transactions_params] = + useState({ + page: 1, + limit: 20, + type: TransactionType.All, + transaction_sub_type: TransactionSubType.All, + keyword: "", + date: "", + }); return ( @@ -81,13 +171,13 @@ const DownloadBill: React.FC = () => { 示例文件 - + {/* 接收方式 小程序消息 - - + */} + { setShowFilterPopup(true) }}> 交易类型 全部 @@ -105,9 +195,8 @@ const DownloadBill: React.FC = () => { 近一周 { selectDateRange("month"); }} @@ -115,9 +204,8 @@ const DownloadBill: React.FC = () => { 近一月 { selectDateRange("custom"); }} @@ -126,11 +214,21 @@ const DownloadBill: React.FC = () => { - {dateRange.start && dateRange.end && ( + {dateRange.start && dateRange.end && dateType !== "custom" && ( {dateRange.start}{dateRange.end} )} + { + dateType === "custom" && ( + { setVisible(true); }}> + 时间范围 + + {dateRange.start && dateRange.end ? `${dateRange.start} 至 ${dateRange.end}` : "请选择账单时间"} + + + ) + } { onClose={() => setVisible(false)} /> )} + + {/* 下载账单输入密码弹窗 */} + set_show_download_popup(false)} + title="提现" + className="withdraw_popup" + hideFooter={true} + > + + {`支付账单流水文件(文件名).xlsx`} + {`文件大小:7KB`} + {`请输入交易密码`} + + { + password.map((item, index) => ( + + {item} + + )) + } + + item !== "").join("")} maxlength={6} onInput={handlePasswordInput} /> + + + + {/* 筛选账单弹窗 */} + setShowFilterPopup(false)} + onConfirm={() => { }} + title="选择筛选项" + className="filter_popup" + > + + + + 交易类型 + + {transaction_type_options.map( + (option: Option) => ( + { + set_load_transactions_params({ + ...load_transactions_params, + transaction_sub_type: option.value, + }); + }} + > + {option.label} + + ) + )} + + + + + ); }; diff --git a/src/user_pages/downloadBillRecords/index.scss b/src/user_pages/downloadBillRecords/index.scss index e69de29..c92820d 100644 --- a/src/user_pages/downloadBillRecords/index.scss +++ b/src/user_pages/downloadBillRecords/index.scss @@ -0,0 +1,64 @@ +.download-bill-records-page { + color: #3C3C4399; + font-family: PingFang SC; + font-weight: 400; + font-style: Regular; + font-size: 16px; + line-height: 24px; + letter-spacing: 0px; + padding: 20px; + + + .records-container { + .record-item { + padding: 16px 0; + + &+.record-item { + border-top: 1px solid #0000000D; + } + + .title-text { + font-size: 16px; + color: #000; + margin-bottom: 8px; + + } + + .info-item { + display: flex; + gap: 20px; + + &+.info-item { + margin-top: 8px; + } + + Text { + &:first-child { + width: 64px; + } + + &:last-child { + flex: 1; + color: #000; + + &.btn { + color: #007AFF; + flex: unset; + width: fit-content; + } + } + } + + } + + } + } + + .tips { + font-size: 12px; + text-align: center; + position: fixed; + bottom: 40px; + width: calc(100% - 40px); + } +} \ No newline at end of file diff --git a/src/user_pages/downloadBillRecords/index.tsx b/src/user_pages/downloadBillRecords/index.tsx index c45a50d..4a4d568 100644 --- a/src/user_pages/downloadBillRecords/index.tsx +++ b/src/user_pages/downloadBillRecords/index.tsx @@ -1,9 +1,45 @@ import React, { useState, useEffect } from "react"; -import { View } from "@tarojs/components"; +import { View, Text } from "@tarojs/components"; + +import "./index.scss"; const DownloadBillRecords: React.FC = () => { return ( - 下载记录 + + + + 账单流水文件 + + 申请时间 + 2025年9月12日 19:03:06 + + + 账单范围 + 2025年9月12日 19:03:06 至 2025年9月12日 19:03:06 + + + + 查看材料 + + + + 账单流水文件 + + 申请时间 + 2025年9月12日 19:03:06 + + + 账单范围 + 2025年9月12日 19:03:06 至 2025年9月12日 19:03:06 + + + + 查看材料 + + + + 出于信息安全考虑,仅保留并展示7天内的账单下载记录 + ); }; diff --git a/src/user_pages/queryTransactions/index.scss b/src/user_pages/queryTransactions/index.scss index 7ea9960..d0bbd4e 100644 --- a/src/user_pages/queryTransactions/index.scss +++ b/src/user_pages/queryTransactions/index.scss @@ -1,197 +1,206 @@ .listSearchContainer { - padding: 0 15px; - padding-top: 16px; + padding: 0 15px; + padding-top: 16px; - .icon16 { - width: 16px; - height: 16px; - } - - .topSearch { - padding: 10px 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); - - .nut-input { - padding: 0; - height: 100%; - } - } - - .searchRight { - display: flex; - align-items: center; - gap: 12px; - - .searchLine { - width: 1px; - height: 20px; - border-radius: 20px; - background: rgba(0, 0, 0, 0.06); + .icon16 { + width: 16px; + height: 16px; } - .searchText { - color: #000000; - font-size: 16px; - font-weight: 600; - line-height: 20px; - } - } + .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); - .searchIcon { - width: 20px; - height: 20px; - } - - .historySearchTitleWrapper { - display: flex; - padding: 12px 15px; - justify-content: space-between; - align-items: flex-end; - align-self: stretch; - - .historySearchTitle, - .historySearchClear { - color: #000; - font-size: 14px; - font-weight: 600; - line-height: 20px; + .nut-input { + padding: 0; + height: 100%; + } } - .historySearchClear { - color: #9a9a9a; - display: flex; - align-items: center; - gap: 4px; - } - } - - .historySearchList { - display: flex; - align-items: center; - flex-wrap: wrap; - gap: 8px; - - .historySearchItem { - flex-shrink: 0; - flex-grow: 0; - display: flex; - height: 28px; - 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 { + .searchRight { 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: 8px 20px; - - .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; + .searchLine { + width: 1px; + height: 20px; + border-radius: 20px; + background: rgba(0, 0, 0, 0.06); } - .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; - } + .searchText { + color: #000000; + font-size: 16px; + font-weight: 600; + line-height: 20px; } - } + } - .transaction_right { + .searchIcon { + width: 20px; + height: 20px; + } + + .historySearchTitleWrapper { display: flex; - flex-direction: column; + padding: 12px 0; + justify-content: space-between; align-items: flex-end; - gap: 4px; - width: 68px; + align-self: stretch; - .transaction_amount { - font-size: 12px; - font-weight: 600; - color: #000; - line-height: 1.5; - text-align: right; + .historySearchTitle, + .historySearchClear { + color: #000; + font-size: 14px; + font-weight: 600; + line-height: 20px; } - .balance_info { - font-size: 10px; - font-weight: 400; - color: rgba(60, 60, 67, 0.6); - line-height: 1.2; - text-align: right; + .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; + } + + .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 diff --git a/src/user_pages/queryTransactions/index.tsx b/src/user_pages/queryTransactions/index.tsx index c86aafa..71bc6d2 100644 --- a/src/user_pages/queryTransactions/index.tsx +++ b/src/user_pages/queryTransactions/index.tsx @@ -341,6 +341,11 @@ const QueryTransactions = () => { )} + { + transactions.length > 0 && ( + 仅支持查找2024年9月1日以后的账单 + ) + } ); diff --git a/src/user_pages/setTransactionPassword/index.tsx b/src/user_pages/setTransactionPassword/index.tsx index 0a449ce..15656f0 100644 --- a/src/user_pages/setTransactionPassword/index.tsx +++ b/src/user_pages/setTransactionPassword/index.tsx @@ -15,7 +15,7 @@ interface FormFields { const SetTransactionPassword: React.FC = () => { const [handleType, setHandleType] = useState("set"); const router = useRouter(); - const { type } = router.params; + const { type, phone, sms_code } = router.params; useEffect(() => { if (type) { @@ -60,9 +60,9 @@ const SetTransactionPassword: React.FC = () => { return; } } else if (handleType === "reset") { - const { old_password } = formData; + // const { old_password } = formData; try { - await httpService.post("/wallet/change_payment_password", { old_password, new_password }); + await httpService.post("/wallet/reset_payment_password", { phone, new_password, sms_code }); Taro.showToast({ title: "修改交易密码成功", icon: "success", @@ -81,12 +81,12 @@ const SetTransactionPassword: React.FC = () => { return ( { - handleType === "reset" && ( - - 旧密码 - { handleInput(e, "old_password") }}> - - ) + // handleType === "reset" && ( + // + // 旧密码 + // { handleInput(e, "old_password") }}> + // + // ) } 交易密码 diff --git a/src/user_pages/validPhone/index.tsx b/src/user_pages/validPhone/index.tsx index 98f112c..71a6464 100644 --- a/src/user_pages/validPhone/index.tsx +++ b/src/user_pages/validPhone/index.tsx @@ -4,6 +4,7 @@ import { View, Text, Input, Button } from "@tarojs/components"; import "./index.scss"; import httpService from "@/services/httpService"; +import { useUserInfo } from "@/store/userStore"; interface FormFields { phone?: string; @@ -11,8 +12,9 @@ interface FormFields { } const ValidPhone: React.FC = () => { + const userInfo = useUserInfo(); const [formData, setFormData] = useState({ - phone: "", + phone: userInfo.phone || "", sms_code: "", }); @@ -22,21 +24,32 @@ const ValidPhone: React.FC = () => { const handleConfirm = async () => { // TODO: 校验验证码 - Taro.navigateTo({ url: "/user_pages/setTransactionPassword/index?type=find" }); + Taro.navigateTo({ url: `/user_pages/setTransactionPassword/index?type=reset&phone=${formData.phone}&sms_code=${formData.sms_code}` }); + }; + + const getSMSCode = async () => { + const { phone } = formData; + try { + await httpService.post("/wallet/send_reset_password_sms", { phone }); + Taro.showToast({ title: "验证码已发送", icon: "none" }); + } catch (error) { + console.log(error); + Taro.showToast({ title: "获取验证码失败", icon: "none" }); + } }; return ( 手机号 - + 验证码 { handleInput(e, "sms_code") }}> - + - + ); }; diff --git a/src/user_pages/wallet/index.tsx b/src/user_pages/wallet/index.tsx index 3898a30..2e8b8d5 100644 --- a/src/user_pages/wallet/index.tsx +++ b/src/user_pages/wallet/index.tsx @@ -228,14 +228,20 @@ const WalletPage: React.FC = () => { }; const navigateToSetTransactionPassword = (type: "set" | "reset") => { + let url = "" + if (type === "set") { + url = `/user_pages/setTransactionPassword/index?type=${type}` + } else if (type === "reset") { + url = `/user_pages/validPhone/index` + } Taro.navigateTo({ - url: `/user_pages/setTransactionPassword/index?type=${type}`, + url, }); }; // 处理提现 const handle_withdraw = () => { - if (!password_status) { + if (password_status) { navigateToSetTransactionPassword("set"); return; } @@ -247,7 +253,10 @@ const WalletPage: React.FC = () => { }); return; } - set_show_withdraw_popup(true); + Taro.navigateTo({ + url: "/user_pages/withdrawal/index", + }); + // set_show_withdraw_popup(true); }; // 提交提现申请 diff --git a/src/user_pages/withdrawal/index.config.ts b/src/user_pages/withdrawal/index.config.ts new file mode 100644 index 0000000..6c10df6 --- /dev/null +++ b/src/user_pages/withdrawal/index.config.ts @@ -0,0 +1,3 @@ +export default definePageConfig({ + navigationBarTitleText: '钱包', +}) diff --git a/src/user_pages/withdrawal/index.scss b/src/user_pages/withdrawal/index.scss new file mode 100644 index 0000000..9fcaba2 --- /dev/null +++ b/src/user_pages/withdrawal/index.scss @@ -0,0 +1,144 @@ +.withdrawal-page { + height: 100vh; + font-family: PingFang SC; + font-weight: 400; + font-style: Regular; + color: #3C3C4399; + font-size: 12px; + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + overflow: hidden; + + .withdrawal-container { + margin: 20px 5px 0; + border-radius: 20px; + padding-top: 12px; + padding-right: 20px; + padding-bottom: 24px; + padding-left: 20px; + gap: 16px; + border: 0.5px solid #EBEBEB; + box-shadow: 0px 4px 36px 0px #0000000D; + + .title-text { + color: #000; + } + + .input-container { + font-weight: bold; + color: #000; + display: flex; + align-items: flex-end; + gap: 8px; + border-bottom: 0.5px solid var(--Fills-Tertiary, #7878801F); + margin: 12px 0; + padding-bottom: 12px; + + .symbol { + font-size: 20px; + } + + Input { + font-size: 32px; + overflow: unset; + text-overflow: unset; + height: 32px; + line-height: 32px; + margin: 0; + padding: 0; + border: none; + background: none; + color: inherit; + outline: none; + box-sizing: border-box; + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + flex: 1; + } + + .btn { + height: 24px; + border: 1px solid rgba(0, 0, 0, 0.06); + display: flex; + align-items: center; + justify-content: center; + color: #fff; + background: #000; + box-shadow: 0 8px 64px 0 rgba(0, 0, 0, 0.1); + backdrop-filter: blur(16px); + font-feature-settings: "liga" off, "clig" off; + font-family: "PingFang SC"; + font-size: 9.6px; + font-style: normal; + line-height: normal; + border-radius: 8px; + margin-right: 0; + } + } + + .tips-text { + color: #F3334A; + } + + .btn-container { + display: flex; + justify-content: space-between; + + .btn { + color: #007AFF; + } + } + } + + .tips-container { + padding: 20px 20px 0; + + .title-text { + font-weight: 600; + margin-bottom: 12px; + } + + .tips-text { + display: flex; + flex-direction: column; + } + } +} + +.withdraw_popup { + .popup_content { + display: flex; + flex-direction: column; + align-items: center; + + .popup_text { + font-family: DingTalk JinBuTi; + font-weight: 400; + font-style: Regular; + font-size: 20px; + line-height: 16px; + margin: 20px 0; + } + + .password_container { + display: flex; + gap: 4px; + align-items: center; + + .password_item { + width: 32px; + height: 32px; + border-radius: 4px; + background-color: #7878801F; + display: flex; + justify-content: center; + align-items: center; + -webkit-text-security: disc; + } + } + } +} \ No newline at end of file diff --git a/src/user_pages/withdrawal/index.tsx b/src/user_pages/withdrawal/index.tsx new file mode 100644 index 0000000..c0a03c4 --- /dev/null +++ b/src/user_pages/withdrawal/index.tsx @@ -0,0 +1,282 @@ +import React, { useState, useEffect } from "react"; +import { View, Text, Input, Button } from "@tarojs/components"; +import Taro, { useDidShow } from "@tarojs/taro"; + +import httpService from "@/services/httpService"; +import "./index.scss"; +import { CommonPopup } from "@/components"; + +interface WalletInfo { + balance: string; + frozen_balance?: string; + total_balance?: string; + total_income?: string; + total_withdraw?: string; +} + +const Withdrawal: React.FC = () => { + const [showTips, setShowTips] = useState(false); + const [tipsText, setTipsText] = useState(""); + const [inputValue, setInputValue] = useState("0.00"); + const [walletInfo, setWalletInfo] = useState({ + balance: "0.00", + }); + const [isFocus, setIsFocus] = useState(false); + + const [show_withdraw_popup, set_show_withdraw_popup] = useState(false); + + const [password, setPassword] = useState(new Array(6).fill("")); + + const toastConfig = { + aa: { + title: "已超单日限额", + content: "您今日提现已超过支付通道2000元单日限额;建议您明日再发起提现,资金仍安全存放在钱包余额中。" + }, + bb: { + title: "已超单日限额", + content: "今日提现通道额度已用完,暂时无法提现;您的余额安全存放在钱包中,我们会在 次日0点恢复 提现服务;如有紧急情况,请联系客服。" + } + } + + useDidShow(() => { + load_wallet_data(); + }); + + useEffect(() => { + if (show_withdraw_popup) { + setIsFocus(true); + } else { + setPassword(new Array(6).fill("")); + setIsFocus(false); + } + }, [show_withdraw_popup]); + + const validateWithdrawAmount = (amount: string) => { + if (Number(amount) > Number(walletInfo.balance)) { + setShowTips(true); + setTipsText("输入金额超过钱包余额"); + } else if (Number(amount) > 200) { + setShowTips(true); + setTipsText("单笔提现金额不能超过 200元"); + } + }; + + const withdrawAll = () => { + setInputValue(walletInfo.balance); + validateWithdrawAmount(walletInfo.balance); + }; + + const handleInput = (e: any) => { + console.log(e); + const value = e.detail.value; + setInputValue(value); + validateWithdrawAmount(value); + }; + // 加载钱包数据 + 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; + setWalletInfo({ + 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 handleWithdraw = async () => { + // TODO 校验提现状态 + // if (true) { + // Taro.showToast({ + // title: "您今日已累计提现 10次,达到每日次数上限", + // icon: "none", + // }); + // } + // const { aa, bb } = toastConfig; + // Taro.showModal({ + // title: aa.title, + // content: aa.content, + // showCancel: false, + // confirmColor: "#000", + // }); + // Taro.showModal({ + // title: bb.title, + // content: bb.content, + // showCancel: false, + // confirmColor: "#000", + // }); + set_show_withdraw_popup(true); + }; + const submit_withdraw = async () => { + // 先调用后端接口获取提现参数 + const response = await httpService.post("/wallet/withdraw", { + amount: parseFloat(inputValue), + transfer_remark: "用户申请提现", + }); + + // 根据后端返回的数据结构解析参数 + const { mch_id, app_id, package_info, open_id } = response.data; + + console.log("/wallet/withdraw:", response.data); + set_show_withdraw_popup(false); + + // 调用微信商户转账接口 + (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); + setInputValue("0.00"); + // 重新加载数据 + load_wallet_data(); + }, + fail: (res) => { + console.log("微信转账失败:", res); + }, + }); + } + const handlePasswordInput = (e: any) => { + const value = e.detail.value; + const [one = "", two = "", three = "", four = "", five = "", six = ""] = value.split(""); + setPassword([one, two, three, four, five, six]); + if (value.length === 6) { + const timer = setTimeout(() => { + // TODO 校验密码 + if (false) { + set_show_withdraw_popup(false); + Taro.showModal({ + content: "支付密码错误,请重试", + cancelText: "忘记密码", + confirmText: "重试", + cancelColor: "#000", + confirmColor: "#fff", + }).then((res) => { + if (res.confirm) { + set_show_withdraw_popup(true); + } else if (res.cancel) { + Taro.navigateTo({ + url: "/user_pages/validPhone/index" + }); + } + }).finally(() => { + clearTimeout(timer); + }); + } else { + submit_withdraw(); + } + }, 100); + } + } + return ( + + + 提现金额 + + ¥ + + { + !showTips && (Number(inputValue) !== 0) && ( + + ) + } + + + + {`我的余额:¥${walletInfo.balance}`} + (可提现余额:¥5000.00) + + 全部提现 + + { + showTips && ( + {tipsText} + ) + } + + + 提现须知 + + 1. 本钱包余额由平台统一管理,提现服务由 微信支付(财付通) 提供。 + 2. 提现仅支持提现至本人实名认证的微信支付账户,请确保账户信息真实有效。 + 3. 每次提现金额不得超过钱包余额,且需满足提现金额最低限制(如有)。 + 4. 正常情况下提现 实时到账,如遇网络、系统或银行通道原因,可能会有延迟。 + 5. 提现过程中平台不收取任何手续费,如微信支付有特殊规则,按其实际规定执行。 + 6. 若发现异常交易、涉嫌违规或存在风险,平台有权暂停或拒绝提现操作。 + 7. 实际到账结果以 微信支付通知 为准。 + + + + + 免费声明 + + 1. 本平台不向用户收取提现手续费,提现服务免费。 + 2. 若因银行或微信支付方收取相关费用,与本平台无关。 + 3. 因网络、系统或第三方原因造成的延迟、失败,本平台不承担责任。 + 4. 用户在使用提现服务前,应充分了解并同意上述规则。 + + + {/* 提现输入密码弹窗 */} + set_show_withdraw_popup(false)} + title="提现" + className="withdraw_popup" + hideFooter={true} + > + + {`¥${inputValue}`} + + { + password.map((item, index) => ( + + {item} + + )) + } + + item !== "").join("")} maxlength={6} onInput={handlePasswordInput} /> + + + + ); +}; + +export default Withdrawal; \ No newline at end of file