458 lines
14 KiB
TypeScript
458 lines
14 KiB
TypeScript
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;
|