From 4dfe6b491eead125fc55a1114eb84ad6e0b71e25 Mon Sep 17 00:00:00 2001 From: BenjaminNH <1249376374@qq.com> Date: Tue, 24 Jun 2025 17:27:50 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=AE=9E=E7=8E=B0=E6=99=AE=E9=80=9A?= =?UTF-8?q?=E7=94=A8=E6=88=B7=E9=A2=84=E7=BA=A6=E8=AE=BE=E5=A4=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-lock.json | 1 + package.json | 1 + src/api/axios.js | 5 +- src/main.jsx | 13 +++- src/pages/user/DeviceDetailModal.jsx | 104 +++++++++++++++++++++++++++ src/pages/user/Reserve.jsx | 5 +- 6 files changed, 123 insertions(+), 6 deletions(-) create mode 100644 src/pages/user/DeviceDetailModal.jsx diff --git a/package-lock.json b/package-lock.json index 0839ce3..b28e72c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,6 +13,7 @@ "@tailwindcss/vite": "^4.1.10", "antd": "^5.26.1", "axios": "^1.10.0", + "dayjs": "^1.11.13", "react": "^18.3.1", "react-dom": "^18.3.1", "react-redux": "^9.2.0", diff --git a/package.json b/package.json index de315da..9f83217 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "@tailwindcss/vite": "^4.1.10", "antd": "^5.26.1", "axios": "^1.10.0", + "dayjs": "^1.11.13", "react": "^18.3.1", "react-dom": "^18.3.1", "react-redux": "^9.2.0", diff --git a/src/api/axios.js b/src/api/axios.js index f70e190..95c4862 100644 --- a/src/api/axios.js +++ b/src/api/axios.js @@ -2,8 +2,10 @@ import { message } from "antd"; import axios from "axios"; import { logout } from "../features/auth/authSlice"; +const baseURL = "http://127.0.0.1:8080"; + const axiosInstance = axios.create({ - baseURL: "http://127.0.0.1:8080", + baseURL: baseURL, timeout: 2000, // 2秒 }); @@ -42,4 +44,5 @@ axiosInstance.interceptors.response.use( } ); +export { baseURL }; export default axiosInstance; diff --git a/src/main.jsx b/src/main.jsx index ab657d3..1e7f053 100644 --- a/src/main.jsx +++ b/src/main.jsx @@ -5,11 +5,18 @@ import { RouterProvider } from "react-router-dom"; import "./index.css"; import router from "./router/index.jsx"; import { store } from "./store/index.js"; +import dayjs from "dayjs"; +import zhCN from "antd/locale/zh_CN"; +import { ConfigProvider } from "antd"; + +dayjs.locale("zh-cn"); createRoot(document.getElementById("root")).render( - - - + + + + + ); diff --git a/src/pages/user/DeviceDetailModal.jsx b/src/pages/user/DeviceDetailModal.jsx new file mode 100644 index 0000000..de9fbdc --- /dev/null +++ b/src/pages/user/DeviceDetailModal.jsx @@ -0,0 +1,104 @@ +import { + DatePicker, + Descriptions, + Form, + Image, + message, + Modal, + Space, +} from "antd"; +import dayjs from "dayjs"; +import axiosInstance, { baseURL } from "../../api/axios"; +import { useEffect, useState } from "react"; +import isBetween from "dayjs/plugin/isBetween"; +import { store } from "../../store"; +import { useSelector, useStore } from "react-redux"; + +export default function DeviceDetailModal({ visiable, device, onclose }) { + const [unavailableTimes, setUnavailableTims] = useState([]); + useEffect(() => { + const fetchUnavailableTimes = async (id) => { + const data = await axiosInstance.get(`/device/unavailable-times/${id}`); + setUnavailableTims(data); + }; + + if (visiable && device?.deviceId) { + fetchUnavailableTimes(device.deviceId); + } + }, [visiable, device?.deviceId]); + + const { RangePicker } = DatePicker; + const disabledDate = (current) => { + if (!current) return false; + const today = dayjs().startOf("day"); + const currentDay = current.startOf("day"); + if (currentDay.isBefore(today)) { + return true; + } + dayjs.extend(isBetween); + + return unavailableTimes.some(({ startTime, endTime }) => { + const start = dayjs(startTime).startOf("day"); + const end = dayjs(endTime).endOf("day"); + return currentDay.isBetween(start, end, null, "[]"); + }); + }; + + const [form] = Form.useForm(); + const userId = useSelector((state) => state.auth.userId); + + const handleOK = async () => { + const values = await form.validateFields(); + + const [startTime, endTime] = values.date; + + const payload = { + deviceId: device.deviceId, + userId, + startTime: startTime.format("YYYY-MM-DD"), + endTime: endTime.format("YYYY-MM-DD"), + }; + console.log(payload); + + await axiosInstance.post("/reservation", payload); + message.success("预约成功"); + form.resetFields(); + onclose(); + }; + + return ( + { + onclose(); + }} + onOk={handleOK} + > + + + {device?.name} + + {device?.usageRequirement} + + + {device?.location} + + + + + + +
+ + + +
+
+
+ ); +} diff --git a/src/pages/user/Reserve.jsx b/src/pages/user/Reserve.jsx index b710004..5d9a28f 100644 --- a/src/pages/user/Reserve.jsx +++ b/src/pages/user/Reserve.jsx @@ -2,6 +2,7 @@ import { Input, Space, Table, Tag } from "antd"; import Column from "antd/es/table/Column"; import { useEffect, useState } from "react"; import axiosInstance from "../../api/axios"; +import DeviceDetailModal from "./DeviceDetailModal"; const statusColorMap = { 空闲: "green", @@ -100,11 +101,11 @@ export default function Reserve() { )} /> - {/* setSelectedDevice(null)} - /> */} + /> ); }