fix:批量设置人等取值不对

del:不用的组件
perf/export-docx
Jimmy Liow 1 year ago
parent c2e4b027a1
commit 19dfc575b4

@ -125,7 +125,7 @@ export const useProductsStore = create(
setEditingProduct: (product) => {
set(() => ({
editingProduct: product,
quotationList: product.quotation
quotationList: product?.quotation
}))
},
setEditing: (editing) => set({ editing }),

@ -1,390 +0,0 @@
import { useState } from 'react';
import { Button, Card, Checkbox, Table, Col, Flex, DatePicker, Typography, Form, Input, Row, Select, Space } from 'antd';
import dayjs from "dayjs";
import { useTranslation } from 'react-i18next';
import { CloseOutlined, StarTwoTone, PlusOutlined } from '@ant-design/icons';
import { useDatePresets } from '@/hooks/useDatePresets';
const { Option } = Select;
const { RangePicker } = DatePicker;
const BatchImportPrice = ({ onBatchImportData }) => {
const { t } = useTranslation()
const previewTableColumns = [
{ title: t('products:adultPrice'), dataIndex: 'adult_cost', width: '10%' },
{ title: t('products:childrenPrice'), dataIndex: 'child_cost', width: '10%' },
{ title: t('products:currency'), dataIndex: 'currency', width: '10%' },
{
title: t('products:Types'),
dataIndex: 'unit',
width: '10%',
editable: true,
render: (text) => (text === '0' ? '每人' : text === '1' ? '每团' : text),
},
{
title: t('products:number'),
dataIndex: 'group_size',
width: '10%',
editable: true,
render: (_, record) => `${record.group_size_min}-${record.group_size_max}`
},
{
title: t('products:validityPeriod'),
dataIndex: 'validityPeriod',
width: '20%',
editable: true,
render: (_, record) => dayjs(record.use_dates_start).format('YYYY-MM-DD') + '~' + dayjs(record.use_dates_end).format('YYYY-MM-DD')
},
{ title: t('products:Weekdays'), dataIndex: 'weekdays', width: '10%' },
]
const [priceForm] = Form.useForm()
const [previewData, setPreviewData] = useState([])
const presets = useDatePresets()
const previewSetupPrice = () => {
let previewList = []
const defList = priceForm.getFieldsValue().defList
defList.forEach(definition => {
const previewPrice = definition?.priceList.map(price => {
return {
adult_cost: price.priceInput.audultPrice,
child_cost: price.priceInput.childrenPrice,
group_size_min: price.priceInput.numberStart,
group_size_max: price.priceInput.numberEnd,
currency: definition.currency,
unit: definition.unitName,
// API
use_dates_start: definition.useDate[0],
use_dates_end: definition.useDate[1],
weekdays: definition.weekend.join(','),
}
})
previewList.push(...previewPrice)
})
setPreviewData(previewList)
}
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>
)
}
const priceInitialValues = {
"defList": [
//
{
"useDate": [
dayjs().add(1, 'year').startOf("y"), dayjs().add(1, 'year').endOf("y")
],
"unitName": "每人",
"currency": "CNY",
"weekend": [
"5",
"6"
],
"priceList": [
{
"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
}
}
]
},
//
{
"useDate": [
dayjs().add(1, 'year').subtract(2, "M").startOf("M"), dayjs().add(1, 'year').endOf("M")
],
"unitName": "每人",
"currency": "CNY",
"weekend": [
"5",
"6"
],
"priceList": [
{
"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
}
}
]
}
]
}
const defaultPriceValue = {
"priceInput": {
"numberStart": 1,
"numberEnd": 2,
"audultPrice": 0,
"childrenPrice": 0
}
}
const defaultDefinitionValue = {
"useDate": [
dayjs().add(1, 'year').subtract(2, "M").startOf("M"), dayjs().add(1, 'year').endOf("M")
],
"unitName": "每人",
"currency": "CNY",
"weekend": [
"5",
"6"
],
"priceList": [
// defaultPriceValue
]
}
return (
<Row gutter={16} justify="center">
<Col span={12}>
<Form
labelCol={{ span: 3 }}
wrapperCol={{ span: 20 }}
form={priceForm}
name="priceForm"
autoComplete="off"
initialValues={priceInitialValues}
>
<Form.List name="defList">
{(fields, { add, remove }) => (
<Flex gap="middle" vertical>
{fields.map((field, index) => (
<Card
size="small"
title={index==0?'旺季':index==1?'淡季':'其他'}
key={field.key}
extra={index==0?<StarTwoTone twoToneColor="#eb2f96" />:<CloseOutlined onClick={() => {
remove(field.name)
}} />}
>
<Form.Item label="币种" name={[field.name, 'currency']}>
<Select placeholder="选择币种">
<Option value="CNY">CNY</Option>
<Option value="USD">USD</Option>
</Select>
</Form.Item>
<Form.Item label="类型" name={[field.name, 'unitName']}>
<Select placeholder="选择类型">
<Option value="每人">每人</Option>
<Option value="每团">每团</Option>
</Select>
</Form.Item>
<Form.Item label="周末" name={[field.name, 'weekend']}>
<Checkbox.Group
options={['5', '6', '7']}
/>
</Form.Item>
<Form.Item label="有效期" name={[field.name, 'useDate']}>
<RangePicker style={{width: '100%'}} allowClear={true} inputReadOnly={true} presets={presets} placeholder={['From', 'Thru']} />
</Form.Item>
<Form.Item label="人等">
<Form.List name={[field.name, 'priceList']}>
{(priceFieldList, priceOptList) => (
<Flex gap="middle" vertical>
{priceFieldList.map((priceField, index) => (
<Space key={priceField.key}>
<Form.Item noStyle name={[priceField.name, 'priceInput']}>
<PriceInput />
</Form.Item>
{index==0?<StarTwoTone twoToneColor="#eb2f96" />:<CloseOutlined onClick={() => priceOptList.remove(priceField.name)} />}
</Space>
))}
<Button type="dashed" icon={<PlusOutlined />} onClick={() => priceOptList.add(defaultPriceValue)} block>
新增人等
</Button>
</Flex>
)}
</Form.List>
</Form.Item>
</Card>
))}
<Button type="dashed" icon={<PlusOutlined />} onClick={() => add(defaultDefinitionValue)} block>
新增设置
</Button>
</Flex>
)}
</Form.List>
<Form.Item noStyle shouldUpdate>
{() => (
<Typography className='hidden'>
<pre>{JSON.stringify(priceForm.getFieldsValue(), null, 2)}</pre>
</Typography>
)}
</Form.Item>
</Form>
</Col>
<Col span={12}>
<Button type="dashed" onClick={() => previewSetupPrice()} block>
预览
</Button>
<Table
bordered
pagination={false}
dataSource={previewData}
columns={previewTableColumns}
/>
</Col>
</Row>
);
};
export default BatchImportPrice;

@ -2,7 +2,7 @@ import { useEffect, useState } from 'react'
import { Table, Form, Modal, Button, Radio, Input, Flex, Card, Select, Typography, InputNumber, Checkbox, DatePicker, Space } from 'antd'
import { useTranslation } from 'react-i18next'
import dayjs from 'dayjs'
import { CloseOutlined, StarTwoTone, PlusOutlined } from '@ant-design/icons';
import { CloseOutlined, StarTwoTone, PlusOutlined, ExclamationCircleFilled } from '@ant-design/icons';
import { useDatePresets } from '@/hooks/useDatePresets'
import useProductsStore from '@/stores/Products/Index'
@ -120,7 +120,7 @@ const batchSetupInitialValues = {
'useDate': [
dayjs().add(1, 'year').startOf('y'), dayjs().add(1, 'year').endOf('y')
],
'unitName': '每人',
'unitId': '0',
'currency': 'CNY',
'weekend': [
'5',
@ -166,7 +166,7 @@ const batchSetupInitialValues = {
'useDate': [
dayjs().add(1, 'year').subtract(2, 'M').startOf('M'), dayjs().add(1, 'year').endOf('M')
],
'unitName': '每人',
'unitId': '0',
'currency': 'CNY',
'weekend': [
'5',
@ -223,7 +223,7 @@ const defaultDefinitionValue = {
'useDate': [
dayjs().add(1, 'year').subtract(2, 'M').startOf('M'), dayjs().add(1, 'year').endOf('M')
],
'unitName': '每人',
'unitId': '0',
'currency': 'CNY',
'weekend': [
'5',
@ -288,7 +288,7 @@ const ProductInfoQuotation = ({ editable, ...props }) => {
}
const onBatchSetupFinish = () => {
// console.info(batchSetupForm.getFieldsValue())
console.info(batchSetupForm.getFieldsValue())
let previewList = []
const defList = batchSetupForm.getFieldsValue().defList
@ -302,7 +302,7 @@ const ProductInfoQuotation = ({ editable, ...props }) => {
group_size_max: price.priceInput.numberEnd,
currency: definition.currency,
unit: definition.unitName,
unit_id: definition.unitId,
// API
use_dates_start: definition.useDate[0].format('YYYY-MM-DD'),
use_dates_end: definition.useDate[1].format('YYYY-MM-DD'),
@ -322,7 +322,7 @@ const ProductInfoQuotation = ({ editable, ...props }) => {
{ title: t('products:currency'), dataIndex: 'currency', width: '4rem' },
{
title: t('products:Types'),
dataIndex: 'unit_name',
dataIndex: 'unit_id',
width: '4rem',
render: (text) => (text === '0' ? '每人' : text === '1' ? '每团' : text),
},
@ -349,7 +349,19 @@ const ProductInfoQuotation = ({ editable, ...props }) => {
return (
<Space>
<Button type='link' onClick={() => onQuotationSeleted(quotation)}>{t('Edit')}</Button>
<Button type='link' danger onClick={() => handleDelete(quotation)}>{t('Delete')}</Button>
<Button type='link' danger onClick={() => {
Modal.confirm({
title: '请确认',
icon: <ExclamationCircleFilled />,
content: '你要删除这条价格吗?',
onOk() {
console.log('OK');
},
onCancel() {
console.log('Cancel');
},
})
}}>{t('Delete')}</Button>
</Space>
)
},
@ -415,10 +427,10 @@ const ProductInfoQuotation = ({ editable, ...props }) => {
<Select.Option value='USD'>USD</Select.Option>
</Select>
</Form.Item>
<Form.Item label='类型' name={[field.name, 'unitName']}>
<Form.Item label='类型' name={[field.name, 'unitId']}>
<Select placeholder='选择类型'>
<Select.Option value='每人'>每人</Select.Option>
<Select.Option value='每团'>每团</Select.Option>
<Select.Option value='0'>每人</Select.Option>
<Select.Option value='1'>每团</Select.Option>
</Select>
</Form.Item>
<Form.Item label='周末' name={[field.name, 'weekend']}>

@ -1,81 +0,0 @@
import { useEffect, useState } from 'react';
import { useParams, Link, useNavigate } from 'react-router-dom';
import { App, Button, Divider, Select } from 'antd';
import { useProductsAuditStatesMapVal } from '@/hooks/useProductsSets';
import { useTranslation } from 'react-i18next';
import useProductsStore, { postProductsQuoteAuditAction, } from '@/stores/Products/Index';
import { isEmpty } from '@/utils/commons';
import useAuthStore from '@/stores/Auth';
import RequireAuth from '@/components/RequireAuth';
// import PrintContractPDF from './PrintContractPDF';
import { PERM_PRODUCTS_OFFER_AUDIT, PERM_PRODUCTS_OFFER_PUT } from '@/config';
import dayjs from 'dayjs';
import AuditStateSelector from '@/components/AuditStateSelector';
const YearSelector = ({ refresh,onStateChange }) => {
const { travel_agency_id, use_year, audit_state } = useParams();
const { t } = useTranslation();
const stateMapVal = useProductsAuditStatesMapVal();
const navigate = useNavigate();
const yearOptions = [];
const currentYear = dayjs().year();
const baseYear = Number(use_year === 'all' ? currentYear : use_year);
for (let i = baseYear - 3; i <= baseYear + 3; i++) {
yearOptions.push({ label: i, value: i, });
}
const [param, setParam] = useState({ pick_year: baseYear, pick_agency: travel_agency_id, });
const [pickYear, setPickYear] = useState(baseYear);
const [pickAuditState, setPickAuditState] = useState();
useEffect(() => {
refresh(param);
return () => {};
}, [param]);
const emptyPickState = { value: '', label: t('products:State') };
useEffect(() => {
const baseState = audit_state === 'all' ? emptyPickState : stateMapVal[`${audit_state}`];
if (isEmpty(pickAuditState)) {
setPickAuditState(baseState);
}
return () => {};
}, [audit_state, stateMapVal])
const handleYearChange = (value) => {
setPickYear(value);
setParam((pre) => ({ ...pre, ...{ pick_year: value } }));
};
const handleAuditStateChange = (labelValue) => {
const { value } = labelValue || emptyPickState;
setPickAuditState(labelValue || emptyPickState);
setParam((pre) => ({ ...pre, ...{ pick_state: value } }));
};
const addproducts = () => {
onStateChange('addProducts');
};
const submitreview = () => {
onStateChange('submitReview');
}
return (
<div className='flex justify-end items-center gap-4 h-full'>
<div className='grow'>
<h2 className='m-0 leading-tight'>
<Divider type={'vertical'} />
<Select options={yearOptions} variant={'borderless'} className='w-24' size='large' value={pickYear} onChange={handleYearChange} />
<Divider type={'vertical'} />
<AuditStateSelector variant={'borderless'} className='w-32' size='large' value={pickAuditState} onChange={handleAuditStateChange} />
</h2>
</div>
<Button size='small' type={'primary'} onClick={addproducts}>
增加产品
</Button>
<Button size='small' type={'primary'} onClick={submitreview}>
提交审核
</Button>
</div>
);
};
export default YearSelector;
Loading…
Cancel
Save