feat: migrate all files to typescript with strict false mode
This commit is contained in:
parent
b3d4e14409
commit
d56bca6692
@ -1,9 +1,9 @@
|
|||||||
import dayjs from "dayjs";
|
import dayjs, { Dayjs } from "dayjs";
|
||||||
import quarterOfYear from "dayjs/plugin/quarterOfYear";
|
import quarterOfYear from "dayjs/plugin/quarterOfYear";
|
||||||
|
|
||||||
dayjs.extend(quarterOfYear);
|
dayjs.extend(quarterOfYear);
|
||||||
|
|
||||||
export const datePresets = [
|
export const datePresets: Array<{ label: string; value: [Dayjs, Dayjs] }> = [
|
||||||
{
|
{
|
||||||
label: "本月",
|
label: "本月",
|
||||||
value: [dayjs().startOf("month"), dayjs().endOf("month")],
|
value: [dayjs().startOf("month"), dayjs().endOf("month")],
|
||||||
@ -30,7 +30,7 @@ const authSlice = createSlice({
|
|||||||
state.roles = payload.roles;
|
state.roles = payload.roles;
|
||||||
state.token = payload.token;
|
state.token = payload.token;
|
||||||
|
|
||||||
localStorage.setItem("userId", payload.userId);
|
localStorage.setItem("userId", payload.userId.toString());
|
||||||
localStorage.setItem("name", payload.name);
|
localStorage.setItem("name", payload.name);
|
||||||
localStorage.setItem("roles", JSON.stringify(payload.roles));
|
localStorage.setItem("roles", JSON.stringify(payload.roles));
|
||||||
localStorage.setItem("token", action.payload.token);
|
localStorage.setItem("token", action.payload.token);
|
||||||
@ -1,11 +0,0 @@
|
|||||||
import { createAsyncThunk } from "@reduxjs/toolkit";
|
|
||||||
import axiosInstance from "../../api/axios";
|
|
||||||
|
|
||||||
export const login = createAsyncThunk(
|
|
||||||
"auth/login",
|
|
||||||
async (values, thunkAPI) => {
|
|
||||||
const res = await axiosInstance.post("/login", values);
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
15
src/features/auth/authThunk.ts
Normal file
15
src/features/auth/authThunk.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import { createAsyncThunk } from "@reduxjs/toolkit";
|
||||||
|
import axiosInstance from "../../api/axios";
|
||||||
|
import { LoginResponse } from "./types";
|
||||||
|
|
||||||
|
export const login = createAsyncThunk<LoginResponse>(
|
||||||
|
"auth/login",
|
||||||
|
async (values) => {
|
||||||
|
const res = await axiosInstance.post<LoginResponse, LoginResponse>(
|
||||||
|
"/login",
|
||||||
|
values
|
||||||
|
);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
);
|
||||||
6
src/features/auth/types.ts
Normal file
6
src/features/auth/types.ts
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
export interface LoginResponse {
|
||||||
|
userId: number;
|
||||||
|
name: string;
|
||||||
|
roles: string[];
|
||||||
|
token: string;
|
||||||
|
}
|
||||||
@ -3,7 +3,7 @@ import { createRoot } from "react-dom/client";
|
|||||||
import { Provider } from "react-redux";
|
import { Provider } from "react-redux";
|
||||||
import { RouterProvider } from "react-router-dom";
|
import { RouterProvider } from "react-router-dom";
|
||||||
import "./index.css";
|
import "./index.css";
|
||||||
import router from "./router/index.jsx";
|
import router from "./router/index.js";
|
||||||
import { store } from "./store/index.js";
|
import { store } from "./store/index.js";
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
import zhCN from "antd/locale/zh_CN";
|
import zhCN from "antd/locale/zh_CN";
|
||||||
@ -4,9 +4,10 @@ import { useDispatch } from "react-redux";
|
|||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
import { login } from "../features/auth/authThunk";
|
import { login } from "../features/auth/authThunk";
|
||||||
import roleRoute from "../config/roleRouteConfig";
|
import roleRoute from "../config/roleRouteConfig";
|
||||||
|
import { store } from "store";
|
||||||
|
|
||||||
export default function Login() {
|
export default function Login() {
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch<typeof store.dispatch>();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
const onFinish = async (values) => {
|
const onFinish = async (values) => {
|
||||||
@ -1,7 +1,14 @@
|
|||||||
import { message, Modal, Space, Spin, Table } from "antd";
|
import { message, Modal, Spin, Table } from "antd";
|
||||||
import { useEffect, useState } from "react";
|
import { useCallback, useEffect, useState } from "react";
|
||||||
import axiosInstance from "../../api/axios";
|
import axiosInstance from "../../api/axios";
|
||||||
|
|
||||||
|
interface DeviceDetailStats {
|
||||||
|
applicantName: string;
|
||||||
|
applicantTeam: string;
|
||||||
|
startDay: Date;
|
||||||
|
endDay: Date;
|
||||||
|
}
|
||||||
|
|
||||||
export default function DeviceDetailStatsModal({
|
export default function DeviceDetailStatsModal({
|
||||||
visible,
|
visible,
|
||||||
record,
|
record,
|
||||||
@ -9,12 +16,15 @@ export default function DeviceDetailStatsModal({
|
|||||||
onClose,
|
onClose,
|
||||||
}) {
|
}) {
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
const [data, setData] = useState([]);
|
const [data, setData] = useState<DeviceDetailStats[]>([]);
|
||||||
|
|
||||||
const fetchData = async () => {
|
const fetchData = useCallback(async () => {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
try {
|
try {
|
||||||
const res = await axiosInstance.get("/device/detail-stats", {
|
const res = await axiosInstance.get<
|
||||||
|
DeviceDetailStats[],
|
||||||
|
DeviceDetailStats[]
|
||||||
|
>("/device/detail-stats", {
|
||||||
params: {
|
params: {
|
||||||
deviceId: record.deviceId,
|
deviceId: record.deviceId,
|
||||||
start: range[0].format("YYYY-MM-DD"),
|
start: range[0].format("YYYY-MM-DD"),
|
||||||
@ -22,12 +32,12 @@ export default function DeviceDetailStatsModal({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
setData(res);
|
setData(res);
|
||||||
} catch (e) {
|
} catch {
|
||||||
message.error("获取数据失败");
|
message.error("获取数据失败");
|
||||||
} finally {
|
} finally {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
}
|
}
|
||||||
};
|
}, [record, range]);
|
||||||
|
|
||||||
const handleExport = async () => {
|
const handleExport = async () => {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
@ -73,7 +83,7 @@ export default function DeviceDetailStatsModal({
|
|||||||
if (visible) {
|
if (visible) {
|
||||||
fetchData();
|
fetchData();
|
||||||
}
|
}
|
||||||
}, [visible, record]);
|
}, [visible, fetchData]);
|
||||||
|
|
||||||
const columns = [
|
const columns = [
|
||||||
{
|
{
|
||||||
@ -1,41 +1,52 @@
|
|||||||
import { Button, DatePicker, Input, Space, Spin, Table, message } from "antd";
|
import { Button, DatePicker, Input, Space, Spin, Table, message } from "antd";
|
||||||
import dayjs from "dayjs";
|
import dayjs, { Dayjs } from "dayjs";
|
||||||
import { useEffect, useState } from "react";
|
import { useCallback, useEffect, useState } from "react";
|
||||||
import axiosInstance from "../../api/axios";
|
import axiosInstance from "../../api/axios";
|
||||||
import { datePresets } from "../../config/datePresetsConfig";
|
import { datePresets } from "../../config/datePresetsConfig";
|
||||||
import DeviceDetailStatsModal from "./DeviceDetailStatsModal";
|
import DeviceDetailStatsModal from "./DeviceDetailStatsModal";
|
||||||
|
|
||||||
|
interface UsageStats {
|
||||||
|
deviceId: string;
|
||||||
|
deviceName: string;
|
||||||
|
usageCount: number;
|
||||||
|
totalUsageDays: number;
|
||||||
|
}
|
||||||
|
|
||||||
const { RangePicker } = DatePicker;
|
const { RangePicker } = DatePicker;
|
||||||
|
|
||||||
export default function DeviceStats() {
|
export default function DeviceStats() {
|
||||||
const [data, setData] = useState([]);
|
const [data, setData] = useState<UsageStats[]>([]);
|
||||||
const [filteredData, setFilteredData] = useState([]);
|
const [filteredData, setFilteredData] = useState<UsageStats[]>([]);
|
||||||
const [range, setRange] = useState([
|
const [range, setRange] = useState<[Dayjs, Dayjs]>([
|
||||||
dayjs().startOf("month"),
|
dayjs().startOf("month"),
|
||||||
dayjs().endOf("month"),
|
dayjs().endOf("month"),
|
||||||
]);
|
]);
|
||||||
|
// eslint-disable-next-line no-unused-vars, @typescript-eslint/no-unused-vars
|
||||||
const [search, setSearch] = useState("");
|
const [search, setSearch] = useState("");
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
const [visiable, setVisiable] = useState(false);
|
const [visiable, setVisiable] = useState(false);
|
||||||
const [selectedRecord, setSelectedRecord] = useState(null);
|
const [selectedRecord, setSelectedRecord] = useState(null);
|
||||||
|
|
||||||
const fetchData = async () => {
|
const fetchData = useCallback(async () => {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
try {
|
try {
|
||||||
const res = await axiosInstance.get("/device/usage-stats", {
|
const res = await axiosInstance.get<UsageStats[], UsageStats[]>(
|
||||||
params: {
|
"/device/usage-stats",
|
||||||
start: range[0].format("YYYY-MM-DD"),
|
{
|
||||||
end: range[1].format("YYYY-MM-DD"),
|
params: {
|
||||||
},
|
start: range[0].format("YYYY-MM-DD"),
|
||||||
});
|
end: range[1].format("YYYY-MM-DD"),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
setData(res);
|
setData(res);
|
||||||
setFilteredData(res);
|
setFilteredData(res);
|
||||||
} catch (e) {
|
} catch {
|
||||||
message.error("获取数据失败");
|
message.error("获取数据失败");
|
||||||
} finally {
|
} finally {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
}
|
}
|
||||||
};
|
}, [range]);
|
||||||
|
|
||||||
const handleSearch = (value) => {
|
const handleSearch = (value) => {
|
||||||
setSearch(value);
|
setSearch(value);
|
||||||
@ -89,7 +100,7 @@ export default function DeviceStats() {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetchData();
|
fetchData();
|
||||||
}, [range]);
|
}, [fetchData]);
|
||||||
|
|
||||||
const columns = [
|
const columns = [
|
||||||
{
|
{
|
||||||
@ -1,38 +1,50 @@
|
|||||||
import { Button, DatePicker, Input, Space, Spin, Table, message } from "antd";
|
import { Button, DatePicker, Input, Space, Spin, Table, message } from "antd";
|
||||||
import dayjs from "dayjs";
|
import dayjs, { Dayjs } from "dayjs";
|
||||||
import { useEffect, useState } from "react";
|
import { useCallback, useEffect, useState } from "react";
|
||||||
import axiosInstance from "../../api/axios";
|
import axiosInstance from "../../api/axios";
|
||||||
import { datePresets } from "../../config/datePresetsConfig";
|
import { datePresets } from "../../config/datePresetsConfig";
|
||||||
|
|
||||||
|
interface ReservationStat {
|
||||||
|
deviceId: string;
|
||||||
|
deviceName: string;
|
||||||
|
applicantName: string;
|
||||||
|
applicantTeam: string;
|
||||||
|
usageCount: number;
|
||||||
|
}
|
||||||
|
|
||||||
const { RangePicker } = DatePicker;
|
const { RangePicker } = DatePicker;
|
||||||
|
|
||||||
export default function ReservationStats() {
|
export default function ReservationStats() {
|
||||||
const [data, setData] = useState([]);
|
const [data, setData] = useState<ReservationStat[]>([]);
|
||||||
const [filteredData, setFilteredData] = useState([]);
|
const [filteredData, setFilteredData] = useState<ReservationStat[]>([]);
|
||||||
const [range, setRange] = useState([
|
const [range, setRange] = useState<[Dayjs, Dayjs]>([
|
||||||
dayjs().startOf("month"),
|
dayjs().startOf("month"),
|
||||||
dayjs().endOf("month"),
|
dayjs().endOf("month"),
|
||||||
]);
|
]);
|
||||||
|
// eslint-disable-next-line no-unused-vars, @typescript-eslint/no-unused-vars
|
||||||
const [search, setSearch] = useState("");
|
const [search, setSearch] = useState("");
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
|
|
||||||
const fetchData = async () => {
|
const fetchData = useCallback(async () => {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
try {
|
try {
|
||||||
const res = await axiosInstance.get("/reservation/stats", {
|
const res = await axiosInstance.get<ReservationStat[], ReservationStat[]>(
|
||||||
params: {
|
"/reservation/stats",
|
||||||
start: range[0].format("YYYY-MM-DD"),
|
{
|
||||||
end: range[1].format("YYYY-MM-DD"),
|
params: {
|
||||||
},
|
start: range[0].format("YYYY-MM-DD"),
|
||||||
});
|
end: range[1].format("YYYY-MM-DD"),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
setData(res);
|
setData(res);
|
||||||
setFilteredData(res);
|
setFilteredData(res);
|
||||||
} catch (e) {
|
} catch {
|
||||||
message.error("获取数据失败");
|
message.error("获取数据失败");
|
||||||
} finally {
|
} finally {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
}
|
}
|
||||||
};
|
}, [range]);
|
||||||
|
|
||||||
const handleSearch = (value) => {
|
const handleSearch = (value) => {
|
||||||
setSearch(value);
|
setSearch(value);
|
||||||
@ -86,7 +98,7 @@ export default function ReservationStats() {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetchData();
|
fetchData();
|
||||||
}, [range]);
|
}, [fetchData]);
|
||||||
|
|
||||||
const columns = [
|
const columns = [
|
||||||
{
|
{
|
||||||
@ -1,20 +1,22 @@
|
|||||||
import { List, Modal, Typography } from "antd";
|
import { List, Modal } from "antd";
|
||||||
import { useEffect, useState } from "react";
|
import { useCallback, useEffect, useState } from "react";
|
||||||
import axiosInstance from "../../api/axios";
|
import axiosInstance from "../../api/axios";
|
||||||
|
|
||||||
export default function TeamDetailModal({ open, team, onclose }) {
|
export default function TeamDetailModal({ open, team, onclose }) {
|
||||||
const [data, setData] = useState([]);
|
const [data, setData] = useState<string[]>([]);
|
||||||
|
|
||||||
const fetchData = async () => {
|
const fetchData = useCallback(async () => {
|
||||||
const data = await axiosInstance.get(`/user-team/${team.id}`);
|
const data = await axiosInstance.get<string[], string[]>(
|
||||||
|
`/user-team/${team.id}`
|
||||||
|
);
|
||||||
setData(data);
|
setData(data);
|
||||||
};
|
}, [team]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (open) {
|
if (open) {
|
||||||
fetchData();
|
fetchData();
|
||||||
}
|
}
|
||||||
}, [open, team]);
|
}, [open, fetchData]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
@ -4,19 +4,20 @@ import { useEffect, useState } from "react";
|
|||||||
import axiosInstance from "../../api/axios";
|
import axiosInstance from "../../api/axios";
|
||||||
import TeamDeleteButton from "../../components/TeamDeleteButton";
|
import TeamDeleteButton from "../../components/TeamDeleteButton";
|
||||||
import TeamDetailModal from "./TeamDetailModal";
|
import TeamDetailModal from "./TeamDetailModal";
|
||||||
|
import { Team } from "types/model";
|
||||||
|
|
||||||
export default function TeamManage() {
|
export default function TeamManage() {
|
||||||
const [teams, setTeams] = useState([]);
|
const [teams, setTeams] = useState<Team[]>([]);
|
||||||
const [data, setData] = useState([]);
|
const [data, setData] = useState<Team[]>([]);
|
||||||
const [searchName, setSearchName] = useState();
|
const [searchName, setSearchName] = useState<string>();
|
||||||
const [editingId, setEditingId] = useState();
|
const [editingId, setEditingId] = useState();
|
||||||
const [editingName, setEditingName] = useState("");
|
const [editingName, setEditingName] = useState("");
|
||||||
const [newTeamName, setNewTeamName] = useState();
|
const [newTeamName, setNewTeamName] = useState("");
|
||||||
const [open, setOpen] = useState(false);
|
const [open, setOpen] = useState(false);
|
||||||
const [selectedTeam, setSelectedTeam] = useState(null);
|
const [selectedTeam, setSelectedTeam] = useState(null);
|
||||||
|
|
||||||
const fetchData = async () => {
|
const fetchData = async () => {
|
||||||
const data = await axiosInstance.get("/teams");
|
const data = await axiosInstance.get<Team[], Team[]>("/teams");
|
||||||
setData(data);
|
setData(data);
|
||||||
setTeams(data);
|
setTeams(data);
|
||||||
setSearchName(null);
|
setSearchName(null);
|
||||||
@ -1,7 +1,15 @@
|
|||||||
import { Form, Input, message, Modal, Select } from "antd";
|
import { Form, Input, message, Modal, Select } from "antd";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import axiosInstance from "../../api/axios";
|
import axiosInstance from "../../api/axios";
|
||||||
import Password from "antd/es/input/Password";
|
|
||||||
|
interface UserDTO {
|
||||||
|
username: string;
|
||||||
|
name: string;
|
||||||
|
phone: string;
|
||||||
|
password?: string;
|
||||||
|
teamId: string;
|
||||||
|
roleId: string;
|
||||||
|
}
|
||||||
|
|
||||||
export default function UserDetailModal({
|
export default function UserDetailModal({
|
||||||
visiable,
|
visiable,
|
||||||
@ -12,11 +20,14 @@ export default function UserDetailModal({
|
|||||||
onSuccess,
|
onSuccess,
|
||||||
}) {
|
}) {
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
const [initialValues, setInitialValues] = useState();
|
const [initialValues, setInitialValues] = useState<UserDTO>();
|
||||||
const [teams, setTeams] = useState([]);
|
const [teams, setTeams] = useState<{ label: string; value: string }[]>();
|
||||||
|
|
||||||
const fetchTeams = async () => {
|
const fetchTeams = async () => {
|
||||||
const data = await axiosInstance.get("/team-label");
|
const data = await axiosInstance.get<
|
||||||
|
unknown,
|
||||||
|
{ label: string; value: string }[]
|
||||||
|
>("/team-label");
|
||||||
setTeams(data);
|
setTeams(data);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -27,7 +38,7 @@ export default function UserDetailModal({
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (visiable) {
|
if (visiable) {
|
||||||
if (mode === "edit") {
|
if (mode === "edit") {
|
||||||
const values = {
|
const values: UserDTO = {
|
||||||
username: user.username,
|
username: user.username,
|
||||||
name: user.name,
|
name: user.name,
|
||||||
phone: user.phone,
|
phone: user.phone,
|
||||||
@ -38,7 +49,7 @@ export default function UserDetailModal({
|
|||||||
setInitialValues(values);
|
setInitialValues(values);
|
||||||
form.setFieldsValue(values);
|
form.setFieldsValue(values);
|
||||||
} else {
|
} else {
|
||||||
const values = {
|
const values: UserDTO = {
|
||||||
username: undefined,
|
username: undefined,
|
||||||
password: undefined,
|
password: undefined,
|
||||||
name: undefined,
|
name: undefined,
|
||||||
@ -2,29 +2,33 @@ import { Button, Flex, Input, Popconfirm, Space, Table } from "antd";
|
|||||||
import Column from "antd/es/table/Column";
|
import Column from "antd/es/table/Column";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import axiosInstance from "../../api/axios";
|
import axiosInstance from "../../api/axios";
|
||||||
import DeviceDetailModal from "../deviceAdmin/DeviceDetailModal";
|
|
||||||
import UserDetailModal from "./UserDetailModal";
|
import UserDetailModal from "./UserDetailModal";
|
||||||
|
import { PageResult, Pagination } from "types/common";
|
||||||
|
import { UserVo } from "types/model";
|
||||||
|
|
||||||
export default function UserManage() {
|
export default function UserManage() {
|
||||||
const [users, setUsers] = useState([]);
|
const [users, setUsers] = useState([]);
|
||||||
const [teams, setTeams] = useState([]);
|
// const [teams, setTeams] = useState([]);
|
||||||
const [modalMode, setModalMode] = useState();
|
const [modalMode, setModalMode] = useState<string>();
|
||||||
const [selectedUser, setSelectedUser] = useState();
|
const [selectedUser, setSelectedUser] = useState<UserVo>();
|
||||||
const [modalOpen, setModalOpen] = useState(false);
|
const [modalOpen, setModalOpen] = useState(false);
|
||||||
const [roles, setRoles] = useState([]);
|
const [roles, setRoles] = useState<{ label: string; value: string }[]>([]);
|
||||||
const [pagination, setPagination] = useState({
|
const [pagination, setPagination] = useState<Pagination>({
|
||||||
current: 1,
|
current: 1,
|
||||||
pageSize: 10,
|
pageSize: 10,
|
||||||
total: 0,
|
total: 0,
|
||||||
});
|
});
|
||||||
|
|
||||||
const fetchRoles = async () => {
|
const fetchRoles = async () => {
|
||||||
const data = await axiosInstance.get("/role");
|
const data = await axiosInstance.get<
|
||||||
|
unknown,
|
||||||
|
{ label: string; value: string }[]
|
||||||
|
>("/role");
|
||||||
setRoles(data);
|
setRoles(data);
|
||||||
};
|
};
|
||||||
|
|
||||||
const fetchData = async (pagination, name) => {
|
const fetchData = async (pagination: Pagination, name?: string) => {
|
||||||
const data = await axiosInstance.get("/user", {
|
const data = await axiosInstance.get<unknown, PageResult<UserVo>>("/user", {
|
||||||
params: {
|
params: {
|
||||||
page: pagination.current,
|
page: pagination.current,
|
||||||
size: pagination.pageSize,
|
size: pagination.pageSize,
|
||||||
@ -108,7 +112,7 @@ export default function UserManage() {
|
|||||||
/>
|
/>
|
||||||
<Column
|
<Column
|
||||||
title="操作"
|
title="操作"
|
||||||
render={(_, record) => {
|
render={(_, record: UserVo) => {
|
||||||
return (
|
return (
|
||||||
<Space>
|
<Space>
|
||||||
<Button
|
<Button
|
||||||
@ -15,6 +15,7 @@ import { useSelector } from "react-redux";
|
|||||||
import axiosInstance, { baseURL } from "../../api/axios";
|
import axiosInstance, { baseURL } from "../../api/axios";
|
||||||
import { deviceStatusOptions } from "../../config/DeviceStatusConfig";
|
import { deviceStatusOptions } from "../../config/DeviceStatusConfig";
|
||||||
import { selectUserId } from "../../features/auth/authSlice";
|
import { selectUserId } from "../../features/auth/authSlice";
|
||||||
|
import { UploadFile } from "antd/lib";
|
||||||
|
|
||||||
export default function DeviceDetailModal({
|
export default function DeviceDetailModal({
|
||||||
visiable,
|
visiable,
|
||||||
@ -26,7 +27,7 @@ export default function DeviceDetailModal({
|
|||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
const [imageFile, setImageFile] = useState(null);
|
const [imageFile, setImageFile] = useState(null);
|
||||||
const [initialValues, setInitialValues] = useState({});
|
const [initialValues, setInitialValues] = useState({});
|
||||||
const [fileList, setFileList] = useState();
|
const [fileList, setFileList] = useState<UploadFile[]>();
|
||||||
const userId = useSelector(selectUserId);
|
const userId = useSelector(selectUserId);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (visiable) {
|
if (visiable) {
|
||||||
@ -9,45 +9,61 @@ import {
|
|||||||
Tag,
|
Tag,
|
||||||
} from "antd";
|
} from "antd";
|
||||||
import Column from "antd/es/table/Column";
|
import Column from "antd/es/table/Column";
|
||||||
import { useEffect, useState } from "react";
|
import { useCallback, useEffect, useState } from "react";
|
||||||
import { useSelector } from "react-redux";
|
import { useSelector } from "react-redux";
|
||||||
import axiosInstance from "../../api/axios";
|
import axiosInstance from "../../api/axios";
|
||||||
import { deviceStatusOptions } from "../../config/DeviceStatusConfig";
|
import { deviceStatusOptions } from "../../config/DeviceStatusConfig";
|
||||||
import { selectUserId } from "../../features/auth/authSlice";
|
import { selectUserId } from "../../features/auth/authSlice";
|
||||||
import DeviceDetailModal from "./DeviceDetailModal";
|
import DeviceDetailModal from "./DeviceDetailModal";
|
||||||
|
import { PageResult, Pagination } from "types/common";
|
||||||
|
|
||||||
|
interface DeviceAdminVO {
|
||||||
|
deviceId: string;
|
||||||
|
name: string;
|
||||||
|
usageRequirement: string;
|
||||||
|
location: string;
|
||||||
|
imagePath: string;
|
||||||
|
status: string;
|
||||||
|
}
|
||||||
|
|
||||||
export default function DeviceManage() {
|
export default function DeviceManage() {
|
||||||
const [devices, setDevices] = useState([]);
|
const [devices, setDevices] = useState([]);
|
||||||
const [selectedDevice, setSelectedDevice] = useState(null);
|
const [selectedDevice, setSelectedDevice] = useState(null);
|
||||||
const [modalOpen, setModalOpen] = useState(false);
|
const [modalOpen, setModalOpen] = useState(false);
|
||||||
const [modalMode, setModalMode] = useState(null);
|
const [modalMode, setModalMode] = useState(null);
|
||||||
const [searchName, setSearchName] = useState(null);
|
const [searchName, setSearchName] = useState<string>(null);
|
||||||
const [pagination, setPagination] = useState({
|
const [pagination, setPagination] = useState<Pagination>({
|
||||||
current: 1,
|
current: 1,
|
||||||
pageSize: 10,
|
pageSize: 10,
|
||||||
total: 0,
|
total: 0,
|
||||||
});
|
});
|
||||||
|
|
||||||
const userId = useSelector(selectUserId);
|
const userId = useSelector(selectUserId);
|
||||||
const fetchData = async (pagination, name = searchName) => {
|
const fetchData = useCallback(
|
||||||
const data = await axiosInstance.get(`/device/${userId}`, {
|
async (pagination: Pagination, name: string = searchName) => {
|
||||||
params: {
|
const data = await axiosInstance.get<unknown, PageResult<DeviceAdminVO>>(
|
||||||
page: pagination.current,
|
`/device/${userId}`,
|
||||||
size: pagination.pageSize,
|
{
|
||||||
name,
|
params: {
|
||||||
},
|
page: pagination.current,
|
||||||
});
|
size: pagination.pageSize,
|
||||||
|
name,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
setDevices(data.records);
|
setDevices(data.records);
|
||||||
setPagination({
|
setPagination({
|
||||||
...pagination,
|
...pagination,
|
||||||
total: data.total,
|
total: data.total,
|
||||||
});
|
});
|
||||||
};
|
},
|
||||||
|
[userId, searchName]
|
||||||
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetchData(pagination);
|
fetchData(pagination);
|
||||||
}, []);
|
}, [fetchData, pagination]);
|
||||||
|
|
||||||
const handlePageChange = async (pagination) => {
|
const handlePageChange = async (pagination) => {
|
||||||
await fetchData(pagination);
|
await fetchData(pagination);
|
||||||
@ -1,10 +1,22 @@
|
|||||||
import { Button, message, Space, Table } from "antd";
|
import { Button, message, Space, Table } from "antd";
|
||||||
import Column from "antd/es/table/Column";
|
import Column from "antd/es/table/Column";
|
||||||
import { useEffect, useState } from "react";
|
import { useCallback, useEffect, useState } from "react";
|
||||||
import { useSelector } from "react-redux";
|
import { useSelector } from "react-redux";
|
||||||
import axiosInstance from "../../api/axios";
|
import axiosInstance from "../../api/axios";
|
||||||
import { selectUserId } from "../../features/auth/authSlice";
|
import { selectUserId } from "../../features/auth/authSlice";
|
||||||
import { selectUserRole } from "../../features/auth/authSlice";
|
import { selectUserRole } from "../../features/auth/authSlice";
|
||||||
|
import { PageResult, Pagination } from "types/common";
|
||||||
|
|
||||||
|
interface ReservationVO {
|
||||||
|
reservationId: string;
|
||||||
|
applicantName: string;
|
||||||
|
applicantTeam: string;
|
||||||
|
applicantContact: string;
|
||||||
|
deviceId: string;
|
||||||
|
deviceName: string;
|
||||||
|
startTime: Date;
|
||||||
|
endTime: Date;
|
||||||
|
}
|
||||||
|
|
||||||
export default function Approval() {
|
export default function Approval() {
|
||||||
const [reservations, setReservations] = useState([]);
|
const [reservations, setReservations] = useState([]);
|
||||||
@ -21,24 +33,30 @@ export default function Approval() {
|
|||||||
showNeedAssist = true;
|
showNeedAssist = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const fetchData = async (pagination) => {
|
const fetchData = useCallback(
|
||||||
const data = await axiosInstance.get(`/reservation/approval/${userId}`, {
|
async (pagination: Pagination) => {
|
||||||
params: {
|
const data = await axiosInstance.get<unknown, PageResult<ReservationVO>>(
|
||||||
page: pagination.current,
|
`/reservation/approval/${userId}`,
|
||||||
size: pagination.pageSize,
|
{
|
||||||
},
|
params: {
|
||||||
});
|
page: pagination.current,
|
||||||
|
size: pagination.pageSize,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
setReservations(data.records);
|
setReservations(data.records);
|
||||||
setPagination({
|
setPagination({
|
||||||
...pagination,
|
...pagination,
|
||||||
total: data.total,
|
total: data.total,
|
||||||
});
|
});
|
||||||
};
|
},
|
||||||
|
[userId]
|
||||||
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetchData(pagination);
|
fetchData(pagination);
|
||||||
}, []);
|
}, [fetchData, pagination]);
|
||||||
|
|
||||||
const handlePageChange = async (pagination) => {
|
const handlePageChange = async (pagination) => {
|
||||||
await fetchData(pagination);
|
await fetchData(pagination);
|
||||||
@ -1,11 +1,25 @@
|
|||||||
import { Button, DatePicker, Form, Input, message, Table, Tag } from "antd";
|
import { Button, DatePicker, Form, Input, message, Table, Tag } from "antd";
|
||||||
import { useForm } from "antd/es/form/Form";
|
import { useForm } from "antd/es/form/Form";
|
||||||
import Column from "antd/es/table/Column";
|
import Column from "antd/es/table/Column";
|
||||||
import { useEffect, useState } from "react";
|
import { useCallback, useEffect, useState } from "react";
|
||||||
import { useSelector } from "react-redux";
|
import { useSelector } from "react-redux";
|
||||||
import axiosInstance from "../../api/axios";
|
import axiosInstance from "../../api/axios";
|
||||||
import { selectUserId, selectUserRole } from "../../features/auth/authSlice";
|
import { selectUserId, selectUserRole } from "../../features/auth/authSlice";
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
|
import { PageResult, Pagination } from "types/common";
|
||||||
|
|
||||||
|
interface ApprovalVO {
|
||||||
|
reservationId: string;
|
||||||
|
approvalId: string;
|
||||||
|
applicantName: string;
|
||||||
|
applicantTeam: string;
|
||||||
|
applicantContact: string;
|
||||||
|
deviceName: string;
|
||||||
|
startTime: Date;
|
||||||
|
endTime: Date;
|
||||||
|
decision: number;
|
||||||
|
status: string;
|
||||||
|
}
|
||||||
|
|
||||||
export default function MyApproval() {
|
export default function MyApproval() {
|
||||||
const [approvals, setApprovals] = useState([]);
|
const [approvals, setApprovals] = useState([]);
|
||||||
@ -21,26 +35,35 @@ export default function MyApproval() {
|
|||||||
const userId = useSelector(selectUserId);
|
const userId = useSelector(selectUserId);
|
||||||
const userRole = useSelector(selectUserRole);
|
const userRole = useSelector(selectUserRole);
|
||||||
|
|
||||||
const fetchData = async (pagination, searchParam) => {
|
const fetchData = useCallback(
|
||||||
const data = await axiosInstance.get(`/approval/${userId}`, {
|
async (
|
||||||
params: {
|
pagination: Pagination,
|
||||||
page: pagination.current,
|
searchParam?: { applicantName: string; deviceName: string }
|
||||||
size: pagination.pageSize,
|
) => {
|
||||||
applicantName: searchParam?.applicantName,
|
const data = await axiosInstance.get<unknown, PageResult<ApprovalVO>>(
|
||||||
deviceName: searchParam?.deviceName,
|
`/approval/${userId}`,
|
||||||
},
|
{
|
||||||
});
|
params: {
|
||||||
|
page: pagination.current,
|
||||||
|
size: pagination.pageSize,
|
||||||
|
applicantName: searchParam?.applicantName,
|
||||||
|
deviceName: searchParam?.deviceName,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
setApprovals(data.records);
|
setApprovals(data.records);
|
||||||
setPagination({
|
setPagination({
|
||||||
...pagination,
|
...pagination,
|
||||||
total: data.total,
|
total: data.total,
|
||||||
});
|
});
|
||||||
};
|
},
|
||||||
|
[userId]
|
||||||
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetchData(pagination);
|
fetchData(pagination);
|
||||||
}, []);
|
}, [fetchData, pagination]);
|
||||||
|
|
||||||
const handlePageChange = async (pagination) => {
|
const handlePageChange = async (pagination) => {
|
||||||
const values = await form.validateFields();
|
const values = await form.validateFields();
|
||||||
@ -66,7 +89,7 @@ export default function MyApproval() {
|
|||||||
await fetchData(pagination, values);
|
await fetchData(pagination, values);
|
||||||
setEditingRow(null);
|
setEditingRow(null);
|
||||||
message.success("修改成功");
|
message.success("修改成功");
|
||||||
} catch (error) {
|
} catch {
|
||||||
message.error("修改失败");
|
message.error("修改失败");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -1,14 +1,14 @@
|
|||||||
import { Button, Col, Form, Input, message, Row } from "antd";
|
import { Button, Col, Form, Input, message, Row } from "antd";
|
||||||
import { useForm } from "antd/es/form/Form";
|
import { useCallback, useEffect, useState } from "react";
|
||||||
import { useEffect, useState } from "react";
|
|
||||||
import { useSelector } from "react-redux";
|
import { useSelector } from "react-redux";
|
||||||
import axiosInstance from "../../api/axios";
|
import axiosInstance from "../../api/axios";
|
||||||
import { selectUserId } from "../../features/auth/authSlice";
|
import { selectUserId } from "../../features/auth/authSlice";
|
||||||
|
import { UserVo } from "types/model";
|
||||||
|
|
||||||
export default function UserDetail() {
|
export default function UserDetail() {
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
const [showPassword, setShowPassword] = useState(false);
|
const [showPassword, setShowPassword] = useState(false);
|
||||||
const [user, setUser] = useState({
|
const [user, setUser] = useState<UserVo>({
|
||||||
userId: "",
|
userId: "",
|
||||||
username: "",
|
username: "",
|
||||||
team: "",
|
team: "",
|
||||||
@ -17,15 +17,20 @@ export default function UserDetail() {
|
|||||||
});
|
});
|
||||||
const userId = useSelector(selectUserId);
|
const userId = useSelector(selectUserId);
|
||||||
|
|
||||||
const fetchUser = async (userId) => {
|
const fetchUser = useCallback(
|
||||||
const user = await axiosInstance.get(`/userdetail/${userId}`);
|
async (userId: string) => {
|
||||||
setUser(user);
|
const user = await axiosInstance.get<unknown, UserVo>(
|
||||||
form.setFieldsValue(user);
|
`/userdetail/${userId}`
|
||||||
};
|
);
|
||||||
|
setUser(user);
|
||||||
|
form.setFieldsValue(user);
|
||||||
|
},
|
||||||
|
[form]
|
||||||
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetchUser(userId);
|
fetchUser(userId);
|
||||||
}, []);
|
}, [fetchUser, userId]);
|
||||||
|
|
||||||
const handleReset = () => {
|
const handleReset = () => {
|
||||||
form.resetFields();
|
form.resetFields();
|
||||||
@ -36,7 +41,7 @@ export default function UserDetail() {
|
|||||||
message.error("两次输入的密码不一致");
|
message.error("两次输入的密码不一致");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const changedFields = {};
|
const changedFields: Record<string, string> = {};
|
||||||
for (const key in values) {
|
for (const key in values) {
|
||||||
if (values[key] !== user[key] && values[key] !== undefined) {
|
if (values[key] !== user[key] && values[key] !== undefined) {
|
||||||
changedFields[key] = values[key];
|
changedFields[key] = values[key];
|
||||||
@ -44,7 +49,10 @@ export default function UserDetail() {
|
|||||||
}
|
}
|
||||||
delete changedFields.confirmPassword;
|
delete changedFields.confirmPassword;
|
||||||
|
|
||||||
const newUser = await axiosInstance.put(`/user/${userId}`, changedFields);
|
const newUser = await axiosInstance.put<unknown, UserVo>(
|
||||||
|
`/user/${userId}`,
|
||||||
|
changedFields
|
||||||
|
);
|
||||||
setUser(newUser);
|
setUser(newUser);
|
||||||
form.setFieldsValue(newUser);
|
form.setFieldsValue(newUser);
|
||||||
message.success("修改成功");
|
message.success("修改成功");
|
||||||
@ -10,21 +10,32 @@ import {
|
|||||||
Select,
|
Select,
|
||||||
Space,
|
Space,
|
||||||
} from "antd";
|
} from "antd";
|
||||||
import dayjs from "dayjs";
|
import dayjs, { Dayjs } from "dayjs";
|
||||||
import isBetween from "dayjs/plugin/isBetween";
|
import isBetween from "dayjs/plugin/isBetween";
|
||||||
import { useEffect, useState } from "react";
|
import { useCallback, useEffect, useState } from "react";
|
||||||
import { useSelector } from "react-redux";
|
import { useSelector } from "react-redux";
|
||||||
import axiosInstance, { baseURL } from "../../api/axios";
|
import axiosInstance, { baseURL } from "../../api/axios";
|
||||||
|
import { selectUserId } from "../../features/auth/authSlice";
|
||||||
|
import { UserVo } from "types/model";
|
||||||
|
|
||||||
|
interface FormValue {
|
||||||
|
name: string;
|
||||||
|
phone: string;
|
||||||
|
team: string;
|
||||||
|
}
|
||||||
|
|
||||||
export default function DeviceDetailModal({ visiable, device, onclose }) {
|
export default function DeviceDetailModal({ visiable, device, onclose }) {
|
||||||
const [unavailableTimes, setUnavailableTims] = useState([]);
|
const [unavailableTimes, setUnavailableTimes] = useState([]);
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
const userId = useSelector((state) => state.auth.userId);
|
const userId = useSelector(selectUserId);
|
||||||
const [teams, setTeams] = useState([]);
|
const [teams, setTeams] = useState([]);
|
||||||
const [initialValues, setInitialValues] = useState();
|
const [initialValues, setInitialValues] = useState<FormValue>();
|
||||||
|
|
||||||
const fetchTeams = async () => {
|
const fetchTeams = async () => {
|
||||||
const data = await axiosInstance.get("/team-label");
|
const data = await axiosInstance.get<
|
||||||
|
unknown,
|
||||||
|
{ label: string; value: string }[]
|
||||||
|
>("/team-label");
|
||||||
const teams = data.map((item) => ({
|
const teams = data.map((item) => ({
|
||||||
label: item.label,
|
label: item.label,
|
||||||
value: item.label,
|
value: item.label,
|
||||||
@ -32,8 +43,10 @@ export default function DeviceDetailModal({ visiable, device, onclose }) {
|
|||||||
setTeams(teams);
|
setTeams(teams);
|
||||||
};
|
};
|
||||||
|
|
||||||
const fetchUser = async () => {
|
const fetchUser = useCallback(async () => {
|
||||||
const data = await axiosInstance.get(`/userdetail/${userId}`);
|
const data = await axiosInstance.get<unknown, UserVo>(
|
||||||
|
`/userdetail/${userId}`
|
||||||
|
);
|
||||||
const values = {
|
const values = {
|
||||||
name: data.name,
|
name: data.name,
|
||||||
phone: data.phone,
|
phone: data.phone,
|
||||||
@ -41,7 +54,7 @@ export default function DeviceDetailModal({ visiable, device, onclose }) {
|
|||||||
};
|
};
|
||||||
setInitialValues(values);
|
setInitialValues(values);
|
||||||
form.setFieldsValue(values);
|
form.setFieldsValue(values);
|
||||||
};
|
}, [userId, form]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetchTeams();
|
fetchTeams();
|
||||||
@ -49,20 +62,23 @@ export default function DeviceDetailModal({ visiable, device, onclose }) {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const fetchUnavailableTimes = async (id) => {
|
const fetchUnavailableTimes = async (id) => {
|
||||||
const data = await axiosInstance.get(`/device/unavailable-times/${id}`);
|
const data = await axiosInstance.get<
|
||||||
setUnavailableTims(data);
|
unknown,
|
||||||
|
{ startTime: Date; endTime: Date }[]
|
||||||
|
>(`/device/unavailable-times/${id}`);
|
||||||
|
setUnavailableTimes(data);
|
||||||
};
|
};
|
||||||
|
|
||||||
if (visiable && device?.deviceId) {
|
if (visiable && device?.deviceId) {
|
||||||
fetchUnavailableTimes(device.deviceId);
|
fetchUnavailableTimes(device.deviceId);
|
||||||
fetchUser();
|
fetchUser();
|
||||||
}
|
}
|
||||||
}, [visiable, device?.deviceId]);
|
}, [visiable, device?.deviceId, fetchUser]);
|
||||||
|
|
||||||
const { RangePicker } = DatePicker;
|
const { RangePicker } = DatePicker;
|
||||||
const disabledDate = (current, { from } = {}) => {
|
const disabledDate = (current: Dayjs, info: { from?: Dayjs } = {}) => {
|
||||||
if (!current) return false;
|
if (!current) return false;
|
||||||
|
const { from } = info;
|
||||||
const today = dayjs().startOf("day");
|
const today = dayjs().startOf("day");
|
||||||
const currentDay = current.startOf("day");
|
const currentDay = current.startOf("day");
|
||||||
|
|
||||||
@ -1,10 +1,24 @@
|
|||||||
import { Table, Tag } from "antd";
|
import { Table, Tag } from "antd";
|
||||||
import { useEffect, useState } from "react";
|
import { useCallback, useEffect, useState } from "react";
|
||||||
import axiosInstance from "../../api/axios";
|
import axiosInstance from "../../api/axios";
|
||||||
import { useSelector } from "react-redux";
|
import { useSelector } from "react-redux";
|
||||||
import Column from "antd/es/table/Column";
|
import Column from "antd/es/table/Column";
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
import { selectUserId } from "../../features/auth/authSlice";
|
import { selectUserId } from "../../features/auth/authSlice";
|
||||||
|
import { PageResult } from "types/common";
|
||||||
|
|
||||||
|
interface UserReservationVO {
|
||||||
|
reservationId: string;
|
||||||
|
deviceName: string;
|
||||||
|
startTime: Date;
|
||||||
|
endTime: Date;
|
||||||
|
statusLabel: string;
|
||||||
|
deviceLeaderName: string;
|
||||||
|
deviceLeaderContact: string;
|
||||||
|
deviceAdminName: string;
|
||||||
|
deviceAdminContact: string;
|
||||||
|
createdTime: Date;
|
||||||
|
}
|
||||||
|
|
||||||
export default function MyReservation() {
|
export default function MyReservation() {
|
||||||
const [reservations, setReservations] = useState([]);
|
const [reservations, setReservations] = useState([]);
|
||||||
@ -16,23 +30,29 @@ export default function MyReservation() {
|
|||||||
|
|
||||||
const userId = useSelector(selectUserId);
|
const userId = useSelector(selectUserId);
|
||||||
|
|
||||||
const fetchData = async (pagination) => {
|
const fetchData = useCallback(
|
||||||
const data = await axiosInstance.get(`/reservation/${userId}`, {
|
async (pagination) => {
|
||||||
params: {
|
const data = await axiosInstance.get<
|
||||||
page: pagination.current,
|
unknown,
|
||||||
size: pagination.pageSize,
|
PageResult<UserReservationVO>
|
||||||
},
|
>(`/reservation/${userId}`, {
|
||||||
});
|
params: {
|
||||||
setReservations(data.records);
|
page: pagination.current,
|
||||||
setPagination({
|
size: pagination.pageSize,
|
||||||
...pagination,
|
},
|
||||||
total: data.total,
|
});
|
||||||
});
|
setReservations(data.records);
|
||||||
};
|
setPagination({
|
||||||
|
...pagination,
|
||||||
|
total: data.total,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
[userId]
|
||||||
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetchData(pagination);
|
fetchData(pagination);
|
||||||
}, []);
|
}, [fetchData, pagination]);
|
||||||
|
|
||||||
const handlePageChange = (pagination) => {
|
const handlePageChange = (pagination) => {
|
||||||
fetchData(pagination);
|
fetchData(pagination);
|
||||||
@ -1,8 +1,9 @@
|
|||||||
import { Input, Space, Table, Tag } from "antd";
|
import { Input, Space, Table, Tag } from "antd";
|
||||||
import Column from "antd/es/table/Column";
|
import Column from "antd/es/table/Column";
|
||||||
import { useEffect, useState } from "react";
|
import { useCallback, useEffect, useState } from "react";
|
||||||
import axiosInstance from "../../api/axios";
|
import axiosInstance from "../../api/axios";
|
||||||
import DeviceDetailModal from "./DeviceDetailModal";
|
import DeviceDetailModal from "./DeviceDetailModal";
|
||||||
|
import { PageResult } from "types/common";
|
||||||
|
|
||||||
const statusColorMap = {
|
const statusColorMap = {
|
||||||
空闲: "green",
|
空闲: "green",
|
||||||
@ -11,6 +12,15 @@ const statusColorMap = {
|
|||||||
维修中: "gray",
|
维修中: "gray",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
interface DeviceVO {
|
||||||
|
deviceId: string;
|
||||||
|
name: string;
|
||||||
|
usageRequirement: string;
|
||||||
|
location: string;
|
||||||
|
imagePath: string;
|
||||||
|
state: string;
|
||||||
|
}
|
||||||
|
|
||||||
export default function Reserve() {
|
export default function Reserve() {
|
||||||
const [name, setName] = useState(null);
|
const [name, setName] = useState(null);
|
||||||
const [pagination, setPagination] = useState({
|
const [pagination, setPagination] = useState({
|
||||||
@ -20,24 +30,31 @@ export default function Reserve() {
|
|||||||
});
|
});
|
||||||
const [devices, setDevices] = useState([]);
|
const [devices, setDevices] = useState([]);
|
||||||
|
|
||||||
const fetchData = async (pagination, searchName = name) => {
|
const fetchData = useCallback(
|
||||||
const data = await axiosInstance.get("/device", {
|
async (pagination, searchName = name) => {
|
||||||
params: {
|
const data = await axiosInstance.get<unknown, PageResult<DeviceVO>>(
|
||||||
page: pagination.current,
|
"/device",
|
||||||
size: pagination.pageSize,
|
{
|
||||||
name: searchName,
|
params: {
|
||||||
},
|
page: pagination.current,
|
||||||
});
|
size: pagination.pageSize,
|
||||||
|
name: searchName,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
setDevices(data.records);
|
||||||
|
setPagination({
|
||||||
|
...pagination,
|
||||||
|
total: data.total,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
[name]
|
||||||
|
);
|
||||||
|
|
||||||
setDevices(data.records);
|
|
||||||
setPagination({
|
|
||||||
...pagination,
|
|
||||||
total: data.total,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetchData(pagination);
|
fetchData(pagination);
|
||||||
}, []);
|
}, [fetchData, pagination]);
|
||||||
|
|
||||||
const handlePageChange = (pagination) => {
|
const handlePageChange = (pagination) => {
|
||||||
fetchData(pagination);
|
fetchData(pagination);
|
||||||
@ -74,7 +91,7 @@ export default function Reserve() {
|
|||||||
title="使用要求"
|
title="使用要求"
|
||||||
key="usageRequirement"
|
key="usageRequirement"
|
||||||
dataIndex="usageRequirement"
|
dataIndex="usageRequirement"
|
||||||
ellipsis="true"
|
ellipsis={true}
|
||||||
/>
|
/>
|
||||||
<Column title="位置" key="location" dataIndex="location" />
|
<Column title="位置" key="location" dataIndex="location" />
|
||||||
<Column
|
<Column
|
||||||
7
src/types/axios.d.ts
vendored
Normal file
7
src/types/axios.d.ts
vendored
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
import "axios";
|
||||||
|
|
||||||
|
declare module "axios" {
|
||||||
|
export interface AxiosRequestConfig {
|
||||||
|
skipInterceptor?: boolean;
|
||||||
|
}
|
||||||
|
}
|
||||||
12
src/types/common.ts
Normal file
12
src/types/common.ts
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
export interface PageResult<T> {
|
||||||
|
records: T[];
|
||||||
|
total: number;
|
||||||
|
size: number;
|
||||||
|
current: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Pagination {
|
||||||
|
current: number;
|
||||||
|
pageSize: number;
|
||||||
|
total?: number;
|
||||||
|
}
|
||||||
15
src/types/model.ts
Normal file
15
src/types/model.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
export interface Team {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
size: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface UserVo {
|
||||||
|
userId: string;
|
||||||
|
username: string;
|
||||||
|
team: string;
|
||||||
|
teamId?: string;
|
||||||
|
name: string;
|
||||||
|
phone: string;
|
||||||
|
roleId?: string;
|
||||||
|
}
|
||||||
1
src/vite-env.d.ts
vendored
Normal file
1
src/vite-env.d.ts
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
/// <reference types="vite/client" />
|
||||||
Loading…
x
Reference in New Issue
Block a user