From a758629a8d5b40e5678fb9869e70a15b15abe729 Mon Sep 17 00:00:00 2001 From: Jimmy Liow Date: Tue, 3 Sep 2024 09:25:40 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=20=20=20=20a.=20=E6=88=BF=E5=9E=8B?= =?UTF-8?q?=E5=88=97=E8=A1=A8=E5=B1=95=E7=A4=BA=E6=90=9C=E7=B4=A2=E6=9D=A1?= =?UTF-8?q?=E4=BB=B6=EF=BC=88=E6=97=A5=E6=9C=9F=E3=80=81=E9=85=92=E5=BA=97?= =?UTF-8?q?=E5=90=8D=E3=80=81=E6=88=BF=E9=97=B4=E6=95=B0=E3=80=81=E4=BA=BA?= =?UTF-8?q?=E6=95=B0=EF=BC=89=20=20=20=20=20c.=20=E5=8F=96=E6=B6=88?= =?UTF-8?q?=E6=9D=A1=E6=AC=BE=E5=B1=95=E7=A4=BA=E8=AF=A6=E7=BB=86=E5=86=85?= =?UTF-8?q?=E5=AE=B9=20=20=20=20=20d.=20=E6=88=BF=E5=9E=8B=E4=BB=B7?= =?UTF-8?q?=E6=A0=BC=E6=94=B9=E4=B8=BA=E6=98=BE=E7=A4=BA=E5=8D=95=E4=BB=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- web/src/stores/Hotel.js | 10 +-- web/src/views/App.jsx | 2 +- web/src/views/hotel/Detail.jsx | 88 +++++++++++++++++++++---- web/src/views/hotel/HotelComponents.jsx | 84 ++++++++++++++++++----- web/src/views/hotel/List.jsx | 49 +++----------- 5 files changed, 158 insertions(+), 75 deletions(-) diff --git a/web/src/stores/Hotel.js b/web/src/stores/Hotel.js index e08b3e2..d902f48 100644 --- a/web/src/stores/Hotel.js +++ b/web/src/stores/Hotel.js @@ -11,10 +11,10 @@ export const fetchHotelList = async (hotelName, checkinDateString, checkoutDateS return errcode !== 0 ? {} : data } -export const fetchAvailability = async (hotelId, checkinDateString, checkoutDateString) => { +export const fetchAvailability = async (hotelId, checkinDateString, checkoutDateString, adultCount=2, roomCount=1) => { const { errcode, data } = await fetchJSON( 'http://202.103.68.93:3002/availability', - { hotel_id: hotelId, checkin: checkinDateString, checkout: checkoutDateString } + { hotel_id: hotelId, checkin: checkinDateString, checkout: checkoutDateString, adults: adultCount, rooms: roomCount } ) return errcode !== 0 ? {} : data } @@ -47,11 +47,13 @@ const useHotelStore = create(devtools((set, get) => ({ })) }, - getRoomListByHotel: async(hotelId, checkin, checkout) => { + getRoomListByHotel: async(hotelId, checkin, checkout, adultCount=2, roomCount=1) => { const resultArray = await fetchAvailability( hotelId, checkin, - checkout + checkout, + adultCount, + roomCount ) console.info(resultArray) diff --git a/web/src/views/App.jsx b/web/src/views/App.jsx index c2ebf3c..a654d57 100644 --- a/web/src/views/App.jsx +++ b/web/src/views/App.jsx @@ -46,7 +46,7 @@ function App() { -
+
diff --git a/web/src/views/hotel/Detail.jsx b/web/src/views/hotel/Detail.jsx index c553af0..ed08ff9 100644 --- a/web/src/views/hotel/Detail.jsx +++ b/web/src/views/hotel/Detail.jsx @@ -1,9 +1,11 @@ import { useState, useEffect } from 'react' import { useParams, useNavigate } from 'react-router-dom' -import { Row, Col, Modal, Space, Form, Typography, DatePicker, Input, Button, App } from 'antd' +import { Row, Col, Modal, InputNumber, Form, Typography, DatePicker, Input, Button, App } from 'antd' import useHotelStore from '@/stores/Hotel' import { HotelList, RoomList } from "./HotelComponents"; import { ExclamationCircleFilled } from '@ant-design/icons' +import dayjs from 'dayjs' +import { isEmpty } from '@/utils/commons' const { Title } = Typography function Detail() { @@ -18,6 +20,7 @@ function Detail() { }) const navigate = useNavigate() + const [searchForm] = Form.useForm() const { notification, modal } = App.useApp() const [selectedHotel, getRoomListByHotel, roomList] = useHotelStore(state => @@ -25,11 +28,34 @@ function Detail() { useEffect (() => { + // http://localhost:5175/hotel/416980/2024-09-10/2024-09-11 + if (isEmpty(hotelId) || isEmpty(checkin) || isEmpty(checkout)) { + console.info('criteria is null') + } else { + searchForm.setFieldsValue({ + dataRange: [dayjs(checkin), dayjs(checkout)], + adultCount: 2, + roomCount: 1 + }) + setLoading(true) + getRoomListByHotel(hotelId, checkin, checkout) + .finally(() => setLoading(false)) + } + + }, []) + + const handelFormFinish = () => { + const formValue = searchForm.getFieldValue() + // setSearchParams({ + // hotel: formValue.hotelName, + // checkin: formValue.dataRange[0].format('YYYY-MM-DD'), + // checkout: formValue.dataRange[1].format('YYYY-MM-DD') + // }) setLoading(true) - getRoomListByHotel(hotelId, checkin, checkout) + getRoomListByHotel(hotelId, checkin, checkout, formValue.adultCount, formValue.roomCount) .finally(() => setLoading(false)) - }, []) + } const handleRoomChange = (room, plan) => { console.info('room: ', room) @@ -60,26 +86,62 @@ function Detail() { } return ( - <> +

酒店:{hotelQuotation.hotelName}

房型:{hotelQuotation.roomName}

价格:{hotelQuotation.price}

- - + {selectedHotel.hotel_name} - - - - - +
+
console.info('onFinishFailed')} + autoComplete='off' + > + + + + + + + + + + + + + + + +
+
{handleRoomChange(room, plan)}} dataSource={roomList}> - +
); } -export default Detail; +export default Detail diff --git a/web/src/views/hotel/HotelComponents.jsx b/web/src/views/hotel/HotelComponents.jsx index de40506..d4abebf 100644 --- a/web/src/views/hotel/HotelComponents.jsx +++ b/web/src/views/hotel/HotelComponents.jsx @@ -1,8 +1,69 @@ import { createContext, useContext, useState } from 'react' -import { Flex, Button, Image, Typography, Empty, Skeleton, Row, Col } from 'antd' +import { Flex, Button, Image, Divider, Typography, Empty, Skeleton, Row, Col, InputNumber, Form, DatePicker, Input } from 'antd' const HotelContext = createContext() +export function SearchForm({ onSearch, onInit }) { + const [searchForm] = Form.useForm() + + onInit(searchForm) + + const handelFormFinish = () => { + const formValue = searchForm.getFieldValue() + // setSearchParams({ + // hotel: formValue.hotelName, + // checkin: formValue.dataRange[0].format('YYYY-MM-DD'), + // checkout: formValue.dataRange[1].format('YYYY-MM-DD') + // }) + + onSearch(formValue) + + // setLoading(true) + // searchByCriteria(formValue) + // .finally(() => setLoading(false)) + } + + return ( +
console.info('onFinishFailed')} + autoComplete='off' + > + + + + + + + + + +
+ ) +} + export function HotelList({ dataSource, loading, onChange }) { if (dataSource && dataSource.length > 0) { @@ -100,18 +161,6 @@ export function RoomList({ dataSource, loading, onChange }) { } } -const getDeductDesc = (type) => { - let desc = '未知' - if (type === 1) desc = '扣首日' - else if (type === 2) desc = '扣全额' - else if (type === 3) desc = '按价格多少百分比扣' - else if (type === 4) desc = '免费取消' - else if (type === 5) desc = '扣几晚' - else if (type === 6) desc = '扣多少钱' - - return desc -} - const getMealDesc = (plan) => { const type = plan.MealType let desc = '未知' @@ -127,18 +176,19 @@ const getMealDesc = (plan) => { const PlanItem = ({room, plan}) => { const { triggerChange } = useContext(HotelContext) return ( -
+ <> 餐: {getMealDesc(plan)} - 取消: {plan.Cancelable ? plan.CancelRules.map(r => getDeductDesc(r.DeductType)).join(',') : '不'} + {plan.Cancelable ? plan.CancelRulesText.join(';') : plan.CancelableText} - {plan.Price} + {plan.PriceUnit} {plan.Currency} -
+ + ) } diff --git a/web/src/views/hotel/List.jsx b/web/src/views/hotel/List.jsx index 8048dd5..4a96874 100644 --- a/web/src/views/hotel/List.jsx +++ b/web/src/views/hotel/List.jsx @@ -1,16 +1,16 @@ import { useState, useEffect } from 'react' import { useNavigate, useSearchParams } from 'react-router-dom' -import { Row, Col, Modal, Space, Form, Typography, DatePicker, Input, Button, App } from 'antd' +import { Row, Col, InputNumber, Space, Form, Typography, DatePicker, Input, Button, App } from 'antd' import useHotelStore from '@/stores/Hotel' import dayjs from 'dayjs' -import { HotelList, RoomList } from "./HotelComponents"; +import { HotelList, SearchForm } from './HotelComponents' import { isEmpty } from '@/utils/commons' const { Title } = Typography const List = () => { const [loading, setLoading] = useState(false) - const [searchForm] = Form.useForm() + let searchForm = null const [searchByCriteria, hotelList, selectHotel] = useHotelStore(state => [state.searchByCriteria, state.hotelList, state.selectHotel]) @@ -25,6 +25,7 @@ const List = () => { const checkoutDateString = searchParams.get('checkout') useEffect(() => { + console.info(searchForm) // http://localhost:5175/hotel/list?hotel=s&checkin=2024-8-20&checkout=2024-8-21 if (isEmpty(hotelName) || isEmpty(checkinDateString) || isEmpty(checkoutDateString)) { console.info('criteria is null') @@ -39,8 +40,7 @@ const List = () => { } }, []) - const onSearchFinish = () => { - const formValue = searchForm.getFieldValue() + const handelSearch = (formValue) => { setSearchParams({ hotel: formValue.hotelName, checkin: formValue.dataRange[0].format('YYYY-MM-DD'), @@ -61,42 +61,11 @@ const List = () => { <> 酒店列表 -
console.info('onFinishFailed')} - autoComplete='off' + searchForm = form} > - - - - - - - - - - +
handleHotelChange(h)}>