|
|
@ -1,13 +1,14 @@
|
|
|
|
import React, { useState } from 'react';
|
|
|
|
import { useEffect, useState } from 'react';
|
|
|
|
import { Button, Card, Checkbox, Col, DatePicker, Form, Input, Row, Select, Space, Tag, Table, InputNumber } from 'antd';
|
|
|
|
import { Button, Card, Checkbox, Col, DatePicker, Typography, Form, Input, Row, Select, Space, Tag, Table, InputNumber } from 'antd';
|
|
|
|
import { CloseOutlined } from '@ant-design/icons';
|
|
|
|
import { CloseOutlined } from '@ant-design/icons';
|
|
|
|
import dayjs from 'dayjs';
|
|
|
|
|
|
|
|
import { useDatePresets } from '@/hooks/useDatePresets';
|
|
|
|
import { useDatePresets } from '@/hooks/useDatePresets';
|
|
|
|
const { Option } = Select;
|
|
|
|
const { Option } = Select;
|
|
|
|
const { RangePicker } = DatePicker;
|
|
|
|
const { RangePicker } = DatePicker;
|
|
|
|
|
|
|
|
|
|
|
|
const BatchImportPrice = ({ onBatchImportData }) => {
|
|
|
|
const BatchImportPrice = ({ onBatchImportData }) => {
|
|
|
|
const [form] = Form.useForm();
|
|
|
|
const [form] = Form.useForm();
|
|
|
|
|
|
|
|
const [peopleForm] = Form.useForm();
|
|
|
|
|
|
|
|
|
|
|
|
const [tags, setTags] = useState([]);
|
|
|
|
const [tags, setTags] = useState([]);
|
|
|
|
const [minPeople, setMinPeople] = useState('');
|
|
|
|
const [minPeople, setMinPeople] = useState('');
|
|
|
|
const [maxPeople, setMaxPeople] = useState('');
|
|
|
|
const [maxPeople, setMaxPeople] = useState('');
|
|
|
@ -16,6 +17,35 @@ const BatchImportPrice = ({ onBatchImportData }) => {
|
|
|
|
const [sendData, setSendData] = useState(null);
|
|
|
|
const [sendData, setSendData] = useState(null);
|
|
|
|
const presets = useDatePresets();
|
|
|
|
const presets = useDatePresets();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
|
|
|
peopleForm.setFieldValue({
|
|
|
|
|
|
|
|
"items": [
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
"weekend": [
|
|
|
|
|
|
|
|
"5",
|
|
|
|
|
|
|
|
"6",
|
|
|
|
|
|
|
|
"7"
|
|
|
|
|
|
|
|
],
|
|
|
|
|
|
|
|
"peopleList": [
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
"peoplePrice": "22",
|
|
|
|
|
|
|
|
"numberStart": "1",
|
|
|
|
|
|
|
|
"numberEnd": "2",
|
|
|
|
|
|
|
|
"audultPrice": "23",
|
|
|
|
|
|
|
|
"childrenPrice": "44"
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
"numberStart": "3",
|
|
|
|
|
|
|
|
"numberEnd": "5",
|
|
|
|
|
|
|
|
"audultPrice": "24",
|
|
|
|
|
|
|
|
"childrenPrice": "12"
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
const handleTagClose = (removedTag) => {
|
|
|
|
const handleTagClose = (removedTag) => {
|
|
|
|
setTags(tags.filter(tag => tag !== removedTag));
|
|
|
|
setTags(tags.filter(tag => tag !== removedTag));
|
|
|
|
};
|
|
|
|
};
|
|
|
@ -237,63 +267,228 @@ const BatchImportPrice = ({ onBatchImportData }) => {
|
|
|
|
...generatePeopleColumns(),
|
|
|
|
...generatePeopleColumns(),
|
|
|
|
];
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const PriceInput = (props) => {
|
|
|
|
|
|
|
|
const { id, value = {}, onChange } = props
|
|
|
|
|
|
|
|
const [numberStart, setNumberStart] = useState(0)
|
|
|
|
|
|
|
|
const [numberEnd, setNumberEnd] = useState(0)
|
|
|
|
|
|
|
|
const [audultPrice, setAudultPrice] = useState(0)
|
|
|
|
|
|
|
|
const [childrenPrice, setChildrenPrice] = useState(0)
|
|
|
|
|
|
|
|
const triggerChange = (changedValue) => {
|
|
|
|
|
|
|
|
onChange?.({
|
|
|
|
|
|
|
|
numberStart,
|
|
|
|
|
|
|
|
numberEnd,
|
|
|
|
|
|
|
|
audultPrice,
|
|
|
|
|
|
|
|
childrenPrice,
|
|
|
|
|
|
|
|
...value,
|
|
|
|
|
|
|
|
...changedValue,
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
const onNumberStartChange = (e) => {
|
|
|
|
|
|
|
|
const newNumber = parseInt(e.target.value || '0', 10)
|
|
|
|
|
|
|
|
if (Number.isNaN(numberStart)) {
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!('numberStart' in value)) {
|
|
|
|
|
|
|
|
setNumberStart(newNumber);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
triggerChange({
|
|
|
|
|
|
|
|
numberStart: newNumber,
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
const onNumberEndChange = (e) => {
|
|
|
|
|
|
|
|
const newNumber = parseInt(e.target.value || '0', 10)
|
|
|
|
|
|
|
|
if (Number.isNaN(numberEnd)) {
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!('numberEnd' in value)) {
|
|
|
|
|
|
|
|
setNumberEnd(newNumber)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
triggerChange({
|
|
|
|
|
|
|
|
numberEnd: newNumber,
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
const onAudultPriceChange = (e) => {
|
|
|
|
|
|
|
|
const newNumber = parseInt(e.target.value || '0', 10)
|
|
|
|
|
|
|
|
if (Number.isNaN(audultPrice)) {
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!('audultPrice' in value)) {
|
|
|
|
|
|
|
|
setAudultPrice(newNumber)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
triggerChange({
|
|
|
|
|
|
|
|
audultPrice: newNumber,
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
const onChildrenPriceChange = (e) => {
|
|
|
|
|
|
|
|
const newNumber = parseInt(e.target.value || '0', 10)
|
|
|
|
|
|
|
|
if (Number.isNaN(childrenPrice)) {
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!('childrenPrice' in value)) {
|
|
|
|
|
|
|
|
setChildrenPrice(newNumber)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
triggerChange({
|
|
|
|
|
|
|
|
childrenPrice: newNumber,
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
|
|
|
<Space.Compact id={id}>
|
|
|
|
|
|
|
|
<Input
|
|
|
|
|
|
|
|
type="text"
|
|
|
|
|
|
|
|
value={value.numberStart || numberStart}
|
|
|
|
|
|
|
|
onChange={onNumberStartChange}
|
|
|
|
|
|
|
|
style={{
|
|
|
|
|
|
|
|
width: '20%',
|
|
|
|
|
|
|
|
}}
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
<Input
|
|
|
|
|
|
|
|
type="text"
|
|
|
|
|
|
|
|
value={value.numberEnd || numberEnd}
|
|
|
|
|
|
|
|
onChange={onNumberEndChange}
|
|
|
|
|
|
|
|
style={{
|
|
|
|
|
|
|
|
width: '40%',
|
|
|
|
|
|
|
|
}}
|
|
|
|
|
|
|
|
addonBefore="~"
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
<Input
|
|
|
|
|
|
|
|
type="text"
|
|
|
|
|
|
|
|
value={value.audultPrice || audultPrice}
|
|
|
|
|
|
|
|
onChange={onAudultPriceChange}
|
|
|
|
|
|
|
|
style={{
|
|
|
|
|
|
|
|
width: '70%',
|
|
|
|
|
|
|
|
}}
|
|
|
|
|
|
|
|
addonBefore="成人价"
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
<Input
|
|
|
|
|
|
|
|
type="text"
|
|
|
|
|
|
|
|
value={value.childrenPrice || childrenPrice}
|
|
|
|
|
|
|
|
onChange={onChildrenPriceChange}
|
|
|
|
|
|
|
|
style={{
|
|
|
|
|
|
|
|
width: '70%',
|
|
|
|
|
|
|
|
}}
|
|
|
|
|
|
|
|
addonBefore="儿童价"
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
</Space.Compact>
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
return (
|
|
|
|
<div>
|
|
|
|
<Row gutter={16}>
|
|
|
|
<Card
|
|
|
|
<Col span={10}>
|
|
|
|
size="small"
|
|
|
|
<Form
|
|
|
|
title="选择人等、周末"
|
|
|
|
labelCol={{ span: 6 }}
|
|
|
|
style={{ marginBottom: 16 }}
|
|
|
|
wrapperCol={{ span: 18 }}
|
|
|
|
|
|
|
|
form={peopleForm}
|
|
|
|
|
|
|
|
name="peopleForm"
|
|
|
|
|
|
|
|
autoComplete="off"
|
|
|
|
|
|
|
|
initialValues={{
|
|
|
|
|
|
|
|
"items": [
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
"weekend": [
|
|
|
|
|
|
|
|
"5",
|
|
|
|
|
|
|
|
"6",
|
|
|
|
|
|
|
|
"7"
|
|
|
|
|
|
|
|
],
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"prieceList": [
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
"priceInput": {
|
|
|
|
|
|
|
|
"numberStart": 1,
|
|
|
|
|
|
|
|
"numberEnd": 2,
|
|
|
|
|
|
|
|
"audultPrice": 0,
|
|
|
|
|
|
|
|
"childrenPrice": 0
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
"priceInput": {
|
|
|
|
|
|
|
|
"numberStart": 3,
|
|
|
|
|
|
|
|
"numberEnd": 4,
|
|
|
|
|
|
|
|
"audultPrice": 0,
|
|
|
|
|
|
|
|
"childrenPrice": 0
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
"priceInput": {
|
|
|
|
|
|
|
|
"numberStart": 5,
|
|
|
|
|
|
|
|
"numberEnd": 6,
|
|
|
|
|
|
|
|
"audultPrice": 0,
|
|
|
|
|
|
|
|
"childrenPrice": 0
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
"priceInput": {
|
|
|
|
|
|
|
|
"numberStart": 7,
|
|
|
|
|
|
|
|
"numberEnd": 9,
|
|
|
|
|
|
|
|
"audultPrice": 0,
|
|
|
|
|
|
|
|
"childrenPrice": 0
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
}}
|
|
|
|
>
|
|
|
|
>
|
|
|
|
<Row>
|
|
|
|
<Form.List name="items" >
|
|
|
|
<Col>
|
|
|
|
{(fields, { add, remove }) => (
|
|
|
|
<Input.Group compact style={{ marginTop: 10 }}>
|
|
|
|
<div style={{ display: 'flex', rowGap: 16, flexDirection: 'column' }}>
|
|
|
|
<Input
|
|
|
|
{fields.map((field, index) => (
|
|
|
|
style={{ width: 100, textAlign: 'center' }}
|
|
|
|
<Card
|
|
|
|
placeholder="Start"
|
|
|
|
size="small"
|
|
|
|
value={minPeople}
|
|
|
|
title={`周末、人等`}
|
|
|
|
onChange={(e) => setMinPeople(e.target.value)}
|
|
|
|
key={field.key}
|
|
|
|
/>
|
|
|
|
>
|
|
|
|
<Input
|
|
|
|
<Form.Item label="周末" name={[field.name, 'weekend']}>
|
|
|
|
style={{ width: 30, borderLeft: 0, pointerEvents: 'none', backgroundColor: '#fff' }}
|
|
|
|
|
|
|
|
placeholder="~"
|
|
|
|
<Checkbox.Group
|
|
|
|
disabled
|
|
|
|
options={['5', '6', '7']}
|
|
|
|
/>
|
|
|
|
onChange={handleCheckboxChange}
|
|
|
|
<Input
|
|
|
|
/>
|
|
|
|
style={{ width: 100, textAlign: 'center', borderLeft: 0 }}
|
|
|
|
</Form.Item>
|
|
|
|
placeholder="End"
|
|
|
|
|
|
|
|
value={maxPeople}
|
|
|
|
|
|
|
|
onChange={(e) => setMaxPeople(e.target.value)}
|
|
|
|
<Form.Item label="价格">
|
|
|
|
/>
|
|
|
|
<Form.List name={[field.name, 'prieceList']}>
|
|
|
|
</Input.Group>
|
|
|
|
{(priceFields, priceOpt) => (
|
|
|
|
</Col>
|
|
|
|
<>
|
|
|
|
|
|
|
|
{priceFields.map((priceField) => (
|
|
|
|
<Col>
|
|
|
|
<Space key={priceField.key}>
|
|
|
|
<Button size="small" type="primary" onClick={handleInputConfirm} style={{ marginLeft: 12, marginTop: 12 }}>
|
|
|
|
<Form.Item noStyle name={[priceField.name, 'priceInput']}>
|
|
|
|
添加人等
|
|
|
|
<PriceInput />
|
|
|
|
</Button>
|
|
|
|
</Form.Item>
|
|
|
|
</Col>
|
|
|
|
|
|
|
|
</Row>
|
|
|
|
|
|
|
|
<div style={{ marginTop: 16 }}>
|
|
|
|
|
|
|
|
{tags.map((tag) => (
|
|
|
|
|
|
|
|
<Tag key={tag} closable onClose={() => handleTagClose(tag)}>
|
|
|
|
|
|
|
|
{tag}
|
|
|
|
|
|
|
|
</Tag>
|
|
|
|
|
|
|
|
))}
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<Checkbox.Group
|
|
|
|
<CloseOutlined onClick={() => priceOpt.remove(priceField.name)} />
|
|
|
|
style={{ marginTop: 16 }}
|
|
|
|
</Space>
|
|
|
|
options={['5', '6', '7']}
|
|
|
|
))}
|
|
|
|
onChange={handleCheckboxChange}
|
|
|
|
<Button type="dashed" onClick={() => priceOpt.add()} block>
|
|
|
|
/>
|
|
|
|
+ 新增人等
|
|
|
|
</Card>
|
|
|
|
</Button>
|
|
|
|
|
|
|
|
</>
|
|
|
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
</Form.List>
|
|
|
|
|
|
|
|
</Form.Item>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
</Card>
|
|
|
|
|
|
|
|
))}
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
</Form.List>
|
|
|
|
|
|
|
|
<Form.Item noStyle shouldUpdate>
|
|
|
|
|
|
|
|
{() => (
|
|
|
|
|
|
|
|
<Typography>
|
|
|
|
|
|
|
|
<pre>{JSON.stringify(peopleForm.getFieldsValue(), null, 2)}</pre>
|
|
|
|
|
|
|
|
</Typography>
|
|
|
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
</Form.Item>
|
|
|
|
|
|
|
|
</Form>
|
|
|
|
|
|
|
|
</Col>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<Col span={14}>
|
|
|
|
<Form
|
|
|
|
<Form
|
|
|
|
labelCol={{ span: 6 }}
|
|
|
|
labelCol={{ span: 6 }}
|
|
|
|
wrapperCol={{ span: 18 }}
|
|
|
|
wrapperCol={{ span: 18 }}
|
|
|
|
form={form}
|
|
|
|
form={form}
|
|
|
|
name="dynamic_form_complex"
|
|
|
|
name="dynamic_form_complex"
|
|
|
|
style={{ maxWidth: 600 }}
|
|
|
|
|
|
|
|
autoComplete="off"
|
|
|
|
autoComplete="off"
|
|
|
|
initialValues={{ items: [{}] }}
|
|
|
|
initialValues={{ items: [{}] }}
|
|
|
|
>
|
|
|
|
>
|
|
|
@ -348,6 +543,13 @@ const BatchImportPrice = ({ onBatchImportData }) => {
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
)}
|
|
|
|
)}
|
|
|
|
</Form.List>
|
|
|
|
</Form.List>
|
|
|
|
|
|
|
|
<Form.Item noStyle shouldUpdate>
|
|
|
|
|
|
|
|
{() => (
|
|
|
|
|
|
|
|
<Typography>
|
|
|
|
|
|
|
|
<pre>{JSON.stringify(form.getFieldsValue(), null, 2)}</pre>
|
|
|
|
|
|
|
|
</Typography>
|
|
|
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
</Form.Item>
|
|
|
|
</Form>
|
|
|
|
</Form>
|
|
|
|
|
|
|
|
|
|
|
|
<Button type="primary" onClick={generateTableData} style={{ marginTop: 20 }}>
|
|
|
|
<Button type="primary" onClick={generateTableData} style={{ marginTop: 20 }}>
|
|
|
@ -364,7 +566,8 @@ const BatchImportPrice = ({ onBatchImportData }) => {
|
|
|
|
/>
|
|
|
|
/>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
)}
|
|
|
|
)}
|
|
|
|
</div>
|
|
|
|
</Col>
|
|
|
|
|
|
|
|
</Row>
|
|
|
|
);
|
|
|
|
);
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|