Files
mini-programs/src/user_pages/downloadBill/index.tsx
张成 1226350099 1
2025-11-14 23:14:18 +08:00

458 lines
14 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import React, { useState, useEffect } from "react";
import { View, Text, Button, Input, Image } 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, GeneralNavbar } from "@/components";
import httpService from "@/services/httpService";
import img from "@/config/images";
export enum TransactionSubType {
All = "",
GameActivity = "game_activity",
Withdrawal = "withdrawal",
Refund = "refund",
Compensation = "compensation",
}
export enum TransactionType {
All = "",
Income = "income",
Expense = "expense",
}
interface Option<T> {
label: string;
value: T;
}
interface TransactionLoadParams {
transaction_sub_type: TransactionSubType;
date_range?: string[];
}
const DownloadBill: React.FC = () => {
// 获取当前页面的配置
const currentPage = Taro.getCurrentInstance();
const pageConfig = currentPage.page?.config;
const pageTitle = pageConfig?.navigationBarTitleText;
const [dateRange, setDateRange] = useState({ start: "", end: "" });
const [transactionSubType, setTransactionSubType] =
useState<TransactionSubType>(TransactionSubType.All);
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<string[]>(new Array(6).fill(""));
useEffect(() => {
culculateDateRange(dateType);
}, []);
const [showFilterPopup, setShowFilterPopup] = useState(false);
const culculateDateRange = (dateType: string) => {
const today = new Date();
const year = today.getFullYear();
const month = today.getMonth();
const day = today.getDate();
if (dateType === "week") {
today.setDate(day - 6);
} else if (dateType === "month") {
today.setMonth(month - 1);
today.setDate(day + 1);
}
const startYear = today.getFullYear();
const startMonth = today.getMonth();
const startDay = today.getDate();
setDateRange({
start: `${startYear}-${String(startMonth + 1).padStart(2, "0")}-${String(
startDay
).padStart(2, "0")}`,
end: `${year}-${String(month + 1).padStart(2, "0")}-${String(
day
).padStart(2, "0")}`,
});
};
const selectDateRange = (range: string) => {
if (dateType === range) {
if (range === "custom") {
setVisible(true);
return;
}
return;
}
switch (range) {
case "week":
setCurrentTimeValue(new Date());
setDateType("week");
culculateDateRange("week");
break;
case "month":
setCurrentTimeValue(new Date());
setDateType("month");
culculateDateRange("month");
break;
case "custom":
setDateType("custom");
setDateRange({ start: "", end: "" });
break;
}
};
const [currentTimeValue, setCurrentTimeValue] = useState<Date | Date[]>(
new Date()
);
const handleConfirm = (val: Date[]) => {
setCurrentTimeValue(val);
const [start, end] = val;
setDateRange({
start: dayjs(start).format("YYYY-MM-DD"),
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<TransactionSubType>[] = [
{
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<TransactionLoadParams>({
transaction_sub_type: TransactionSubType.All,
date_range: [],
});
const handleClose = () => {
setTransactionSubType(load_transactions_params.transaction_sub_type);
setShowFilterPopup(false);
};
const handleTypeConfirm = () => {
set_load_transactions_params((prev) => {
return { ...prev, transaction_sub_type: transactionSubType };
});
setShowFilterPopup(false);
};
const downloadExample = async () => {
const { start, end } = dateRange;
if (!start || !end) return;
try {
const res = await httpService.post("/parameter/many_key", {
keys: "bill_example",
});
const { bill_example, fileName } = res.data;
// 调用下载文件接口
wx.downloadFile({
url: bill_example, // 文件路径
success: function (res) {
// 只有200状态码表示下载成功
if (res.statusCode === 200) {
// 下载成功后可以使用res.tempFilePath访问临时文件路径
console.log("文件下载成功,临时路径为:", res.tempFilePath);
// 保存文件到本地
wx.openDocument({
filePath: res.tempFilePath,
showMenu: true, // 显示保存菜单
});
}
},
fail: function (err) {
console.error("文件下载失败:", err);
},
});
} catch (error) {
console.error(error);
}
};
const handleDownloadBill = async () => {
const { start, end } = dateRange;
if (!start || !end) return;
try {
const { transaction_sub_type } = load_transactions_params;
const date_range = [start, end];
const res = await httpService.post("/wallet/download_bill", {
transaction_sub_type,
date_range,
});
const { fileUrl, fileName } = res.data;
// 调用下载文件接口
wx.downloadFile({
url: fileUrl, // 文件路径
success: function (res) {
// 只有200状态码表示下载成功
if (res.statusCode === 200) {
// 下载成功后可以使用res.tempFilePath访问临时文件路径
console.log("文件下载成功,临时路径为:", res.tempFilePath);
// 保存文件到本地
wx.openDocument({
filePath: res.tempFilePath,
showMenu: true, // 显示保存菜单
});
}
},
fail: function (err) {
console.error("文件下载失败:", err);
},
});
} catch (error) {
console.error(error);
}
};
return (
<View className="download_bill_page">
{/* 导航栏 */}
{/* <View className="custom-navbar">
<View className="detail-navigator">
<View
className="detail-navigator-back"
onClick={() => {
Taro.navigateBack();
}}
>
<Image
className="detail-navigator-back-icon"
src={img.ICON_NAVIGATOR_BACK}
/>
<Text>{pageTitle}</Text>
</View>
</View>
</View> */}
{/* 顶部导航栏 */}
<GeneralNavbar
title={pageTitle}
showBack={true}
showAvatar={false}
onBack={() => {
Taro.navigateBack();
}}
/>
<View className="hint_content">
<Text> </Text>
<Text className="button_text" onClick={downloadExample}>
</Text>
{/* <Text className="button_text">示例文件</Text> */}
</View>
<View className="form_container">
{/* <View className="form_item">
<Text className="title_text">接收方式</Text>
<View className="value_content arrow">
<Text>小程序消息</Text>
</View>
</View> */}
<View
className="form_item"
onClick={() => {
setShowFilterPopup(true);
}}
>
<Text className="title_text"></Text>
<View className="value_content arrow">
<Text>
{
transaction_type_options.find(
(item) =>
item.value === load_transactions_params.transaction_sub_type
)?.label
}
</Text>
</View>
</View>
<View className="form_item">
<Text className="title_text"></Text>
<View className="value_content">
<View
className={`option_button ${dateType === "week" ? "active" : ""}`}
onClick={() => {
selectDateRange("week");
}}
>
</View>
<View
className={`option_button ${dateType === "month" ? "active" : ""
}`}
onClick={() => {
selectDateRange("month");
}}
>
</View>
<View
className={`option_button ${dateType === "custom" ? "active" : ""
}`}
onClick={() => {
selectDateRange("custom");
}}
>
</View>
</View>
</View>
{dateRange.start && dateRange.end && dateType !== "custom" && (
<View className="time_box">
<Text>{dateRange.start}</Text> <Text>{dateRange.end}</Text>
</View>
)}
{dateType === "custom" && (
<View
className="form_item"
onClick={() => {
setVisible(true);
}}
>
<Text className="title_text"></Text>
<View className="value_content arrow">
<Text>
{dateRange.start && dateRange.end
? `${dateRange.start}${dateRange.end}`
: "请选择账单时间"}
</Text>
</View>
</View>
)}
</View>
<View className="button_container">
<Text
className="button_text"
onClick={() =>
Taro.navigateTo({ url: "/user_pages/downloadBillRecords/index" })
}
>
</Text>
<Button
className={`download_button ${!dateRange.start ? "disabled" : ""}`}
onClick={handleDownloadBill}
>
</Button>
</View>
{visible && (
<DialogCalendarCard
visible={visible}
searchType={"range"}
value={currentTimeValue}
onChange={handleConfirm}
onClose={() => setVisible(false)}
/>
)}
{/* 下载账单输入密码弹窗 */}
<CommonPopup
showHeader={true}
visible={show_download_popup}
onClose={() => set_show_download_popup(false)}
title="提现"
className="withdraw_popup"
hideFooter={true}
>
<View className="popup_content">
<View className="popup_text">{`支付账单流水文件(文件名).xlsx`}</View>
<View className="popup_text">{`文件大小7KB`}</View>
<View className="popup_text">{`请输入交易密码`}</View>
<View className="password_container">
{password.map((item, index) => (
<View key={index} className="password_item">
<Text className="password_text">{item}</Text>
</View>
))}
</View>
<Input
focus={isFocus}
type="number"
style={{ width: "0", height: "0", opacity: "0" }}
value={password.filter((item) => item !== "").join("")}
maxlength={6}
onInput={handlePasswordInput}
/>
</View>
</CommonPopup>
{/* 筛选账单弹窗 */}
<CommonPopup
showHeader={true}
visible={showFilterPopup}
onClose={handleClose}
onConfirm={handleTypeConfirm}
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">
{transaction_type_options.map(
(option: Option<TransactionSubType>) => (
<View
className={
transactionSubType === option.value
? "option_item active"
: "option_item"
}
key={option.value}
onClick={() => {
setTransactionSubType(option.value);
}}
>
{option.label}
</View>
)
)}
</View>
</View>
</View>
</View>
</CommonPopup>
</View>
);
};
export default DownloadBill;