feat: 实现设备使用详情统计

This commit is contained in:
BenjaminNH 2025-07-17 19:04:55 +08:00
parent 87cc58be92
commit b34646f869
2 changed files with 157 additions and 0 deletions

View File

@ -0,0 +1,129 @@
import { message, Modal, Space, Spin, Table } from "antd";
import { useEffect, useState } from "react";
import axiosInstance from "../../api/axios";
export default function DeviceDetailStatsModal({
visible,
record,
range,
onClose,
}) {
const [loading, setLoading] = useState(false);
const [data, setData] = useState([]);
const fetchData = async () => {
setLoading(true);
try {
const res = await axiosInstance.get("/device/detail-stats", {
params: {
deviceId: record.deviceId,
start: range[0].format("YYYY-MM-DD"),
end: range[1].format("YYYY-MM-DD"),
},
});
setData(res);
} catch (e) {
message.error("获取数据失败");
} finally {
setLoading(false);
}
};
const handleExport = async () => {
setLoading(true);
try {
const response = await axiosInstance.get("/device/detail-stats/export", {
params: {
deviceId: record.deviceId,
start: range[0].format("YYYY-MM-DD"),
end: range[1].format("YYYY-MM-DD"),
},
responseType: "blob", //
skipInterceptor: true,
});
//
const fileName = `${record?.deviceName}_${range[0].format(
"YYYY.MM.DD"
)}-${range[1].format("YYYY.MM.DD")}_使用详情.xlsx`;
// blob
const blob = new Blob([response.data], {
type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
});
const url = window.URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = fileName;
document.body.appendChild(a);
a.click();
a.remove();
window.URL.revokeObjectURL(url);
message.success("导出成功");
} catch (error) {
message.error("导出失败,请稍后重试");
console.error(error);
} finally {
setLoading(false);
}
};
useEffect(() => {
if (visible) {
fetchData();
}
}, [visible, record]);
const columns = [
{
title: "使用人",
dataIndex: "applicantName",
key: "applicantName",
sorter: (a, b) => a.applicantName.localeCompare(b.applicantName),
},
{
title: "所属团队",
dataIndex: "applicantTeam",
key: "applicantTeam",
sorter: (a, b) => a.applicantTeam.localeCompare(b.applicantTeam),
},
{
title: "开始日期",
dataIndex: "startDay",
key: "startDay",
sorter: (a, b) => a.startDay.localeCompare(b.startDay),
},
{
title: "结束日期",
dataIndex: "endDay",
key: "endDay",
sorter: (a, b) => a.endDay.localeCompare(b.endDay),
},
];
return (
<Spin spinning={loading}>
<Modal
open={visible}
title={`${record?.deviceName}_${range[0].format(
"YYYY.MM.DD"
)}-${range[1].format("YYYY.MM.DD")}_使用详情`}
width={"80%"}
cancelText="返回"
onCancel={() => {
onClose();
}}
okText="导出Excel"
onOk={handleExport}
>
<Table
rowKey={(record) => record.deviceId}
dataSource={data}
columns={columns}
className="mt-4"
/>
</Modal>
</Spin>
);
}

View File

@ -3,6 +3,7 @@ import dayjs from "dayjs";
import { useEffect, useState } from "react";
import axiosInstance from "../../api/axios";
import { datePresets } from "../../config/datePresetsConfig";
import DeviceDetailStatsModal from "./DeviceDetailStatsModal";
const { RangePicker } = DatePicker;
@ -15,6 +16,8 @@ export default function DeviceStats() {
]);
const [search, setSearch] = useState("");
const [loading, setLoading] = useState(false);
const [visiable, setVisiable] = useState(false);
const [selectedRecord, setSelectedRecord] = useState(null);
const fetchData = async () => {
setLoading(true);
@ -107,6 +110,23 @@ export default function DeviceStats() {
key: "totalUsageDays",
sorter: (a, b) => a.totalUsageDays - b.totalUsageDays,
},
{
title: "操作",
key: "action",
render: (_, record) => {
return (
<Button
size="small"
onClick={() => {
setSelectedRecord(record);
setVisiable(true);
}}
>
查看详情
</Button>
);
},
},
];
return (
@ -135,6 +155,14 @@ export default function DeviceStats() {
dataSource={filteredData}
columns={columns}
/>
<DeviceDetailStatsModal
visible={visiable}
record={selectedRecord}
onClose={() => {
setVisiable(false);
}}
range={range}
/>
</Spin>
);
}