|
|
@ -1,5 +1,5 @@
|
|
|
|
import React, { useState, useEffect, useRef, useMemo } from 'react';
|
|
|
|
import React, { useState, useEffect, useRef, useMemo } from 'react';
|
|
|
|
import { Button, Card, Col, Row, Breadcrumb, Table, Popconfirm, Form, Input, InputNumber, Tag, Modal, Select, Tree, FloatButton, DatePicker } from 'antd';
|
|
|
|
import { Button, Card, Col, Row, Breadcrumb, Table, Popconfirm, Form, Input, InputNumber, Tag, Modal, Select, Tree, FloatButton, DatePicker, Spin, message } from 'antd';
|
|
|
|
import { Link } from 'react-router-dom';
|
|
|
|
import { Link } from 'react-router-dom';
|
|
|
|
import { useTranslation } from 'react-i18next';
|
|
|
|
import { useTranslation } from 'react-i18next';
|
|
|
|
import { useProductsTypes } from '@/hooks/useProductsSets';
|
|
|
|
import { useProductsTypes } from '@/hooks/useProductsSets';
|
|
|
@ -13,23 +13,22 @@ import dayjs from 'dayjs';
|
|
|
|
import { PlusCircleFilled } from '@ant-design/icons';
|
|
|
|
import { PlusCircleFilled } from '@ant-design/icons';
|
|
|
|
import { DeptSelector } from '@/components/DeptSelector';
|
|
|
|
import { DeptSelector } from '@/components/DeptSelector';
|
|
|
|
import { useDatePresets } from '@/hooks/useDatePresets';
|
|
|
|
import { useDatePresets } from '@/hooks/useDatePresets';
|
|
|
|
|
|
|
|
import CitySelector from '@/components/CitySelector';
|
|
|
|
|
|
|
|
import { HT_HOST } from '@/config';
|
|
|
|
|
|
|
|
import { postJSON } from '@/utils/request';
|
|
|
|
|
|
|
|
import { create } from 'zustand';
|
|
|
|
function Detail() {
|
|
|
|
function Detail() {
|
|
|
|
const { t } = useTranslation();
|
|
|
|
const { t } = useTranslation();
|
|
|
|
const [form] = Form.useForm();
|
|
|
|
const [form] = Form.useForm();
|
|
|
|
const { RangePicker } = DatePicker;
|
|
|
|
const { RangePicker } = DatePicker;
|
|
|
|
const [editingid, setEditingid] = useState('');
|
|
|
|
|
|
|
|
const [tags, setTags] = useState([]);
|
|
|
|
const [tags, setTags] = useState([]);
|
|
|
|
const [isModalVisible, setIsModalVisible] = useState(false);
|
|
|
|
const [isModalVisible, setIsModalVisible] = useState(false);
|
|
|
|
const [selectedTag, setSelectedTag] = useState(null);
|
|
|
|
const [selectedTag, setSelectedTag] = useState(null);
|
|
|
|
const [saveData, setSaveData] = useState(null);
|
|
|
|
|
|
|
|
const [batchImportPriceVisible, setBatchImportPriceVisible] = useState(false);
|
|
|
|
const [batchImportPriceVisible, setBatchImportPriceVisible] = useState(false);
|
|
|
|
const [quotationTableVisible, setQuotationTableVisible] = useState(false)
|
|
|
|
const [quotationTableVisible, setQuotationTableVisible] = useState(false)
|
|
|
|
const [currentid, setCurrentid] = useState(null);
|
|
|
|
|
|
|
|
const [languageStatus, setLanguageStatus] = useState(null);
|
|
|
|
const [languageStatus, setLanguageStatus] = useState(null);
|
|
|
|
const [selectedNodeid, setSelectedNodeid] = useState(null);
|
|
|
|
const [selectedNodeid, setSelectedNodeid] = useState(null);
|
|
|
|
const [remainderLanguage, setRemainderLanguage] = useState([])
|
|
|
|
const [remainderLanguage, setRemainderLanguage] = useState([])
|
|
|
|
const [selectedDateData, setSelectedDateData] = useState({ dateRange: null, selectedDays: [] });
|
|
|
|
|
|
|
|
const [treeData, setTreeData] = useState([]);
|
|
|
|
const [treeData, setTreeData] = useState([]);
|
|
|
|
const productsTypes = useProductsTypes();
|
|
|
|
const productsTypes = useProductsTypes();
|
|
|
|
const [productsData, setProductsData] = useState(null);
|
|
|
|
const [productsData, setProductsData] = useState(null);
|
|
|
@ -44,7 +43,7 @@ function Detail() {
|
|
|
|
const [addProductVisible, setAddProductVisible] = useState(false);
|
|
|
|
const [addProductVisible, setAddProductVisible] = useState(false);
|
|
|
|
const [editingProduct, setEditingProduct] = useProductsStore((state) => [state.editingProduct, state.setEditingProduct]);
|
|
|
|
const [editingProduct, setEditingProduct] = useProductsStore((state) => [state.editingProduct, state.setEditingProduct]);
|
|
|
|
const [agencyProducts, setAgencyProducts] = useProductsStore((state) => [state.agencyProducts, state.setAgencyProducts]);
|
|
|
|
const [agencyProducts, setAgencyProducts] = useProductsStore((state) => [state.agencyProducts, state.setAgencyProducts]);
|
|
|
|
const { getAgencyProducts } = useProductsStore();
|
|
|
|
const { getAgencyProducts, activeAgency } = useProductsStore();
|
|
|
|
const [expandedKeys, setExpandedKeys] = useState([]);
|
|
|
|
const [expandedKeys, setExpandedKeys] = useState([]);
|
|
|
|
const [searchValue, setSearchValue] = useState('');
|
|
|
|
const [searchValue, setSearchValue] = useState('');
|
|
|
|
const [autoExpandParent, setAutoExpandParent] = useState(true);
|
|
|
|
const [autoExpandParent, setAutoExpandParent] = useState(true);
|
|
|
@ -56,7 +55,9 @@ function Detail() {
|
|
|
|
const [dataFetched, setDataFetched] = useState(false); // 添加一个标志位
|
|
|
|
const [dataFetched, setDataFetched] = useState(false); // 添加一个标志位
|
|
|
|
const [selectedNodeKey, setSelectedNodeKey] = useState(null);
|
|
|
|
const [selectedNodeKey, setSelectedNodeKey] = useState(null);
|
|
|
|
const [selectedDays, setSelectedDays] = useState([]);
|
|
|
|
const [selectedDays, setSelectedDays] = useState([]);
|
|
|
|
const [weekdays,setWeekdays] = useState([]);
|
|
|
|
const [weekdays, setWeekdays] = useState([]);
|
|
|
|
|
|
|
|
const [info, setInfo] = useState();
|
|
|
|
|
|
|
|
const travel_agency_name = activeAgency.travel_agency_name;
|
|
|
|
const [currentQuotationRecord, setCurrentQuotationRecord] = useState({
|
|
|
|
const [currentQuotationRecord, setCurrentQuotationRecord] = useState({
|
|
|
|
use_dates_start: null,
|
|
|
|
use_dates_start: null,
|
|
|
|
use_dates_end: null
|
|
|
|
use_dates_end: null
|
|
|
@ -154,8 +155,6 @@ function Detail() {
|
|
|
|
if (productsTypes && !dataFetched) {
|
|
|
|
if (productsTypes && !dataFetched) {
|
|
|
|
const agency_id = { travel_agency_id };
|
|
|
|
const agency_id = { travel_agency_id };
|
|
|
|
await getAgencyProducts(agency_id);
|
|
|
|
await getAgencyProducts(agency_id);
|
|
|
|
console.log("agencyProducts", agencyProducts)
|
|
|
|
|
|
|
|
console.log("productsTypes", productsTypes)
|
|
|
|
|
|
|
|
const generateTreeData = (productsTypes, productsData) => {
|
|
|
|
const generateTreeData = (productsTypes, productsData) => {
|
|
|
|
return productsTypes.map(type => ({
|
|
|
|
return productsTypes.map(type => ({
|
|
|
|
title: type.label,
|
|
|
|
title: type.label,
|
|
|
@ -169,19 +168,17 @@ function Detail() {
|
|
|
|
}));
|
|
|
|
}));
|
|
|
|
};
|
|
|
|
};
|
|
|
|
const tempExpandedKeys = productsTypes.map(item => item.key)
|
|
|
|
const tempExpandedKeys = productsTypes.map(item => item.key)
|
|
|
|
console.log("tempExpandedKeys", tempExpandedKeys)
|
|
|
|
|
|
|
|
const treeData = generateTreeData(productsTypes, agencyProducts);
|
|
|
|
const treeData = generateTreeData(productsTypes, agencyProducts);
|
|
|
|
console.log("treeData", treeData)
|
|
|
|
|
|
|
|
setDataFetched(true); // 设置标志位为 true,表示数据已获取
|
|
|
|
setDataFetched(true); // 设置标志位为 true,表示数据已获取
|
|
|
|
setTreeData(treeData);
|
|
|
|
setTreeData(treeData);
|
|
|
|
setExpandedKeys(tempExpandedKeys)
|
|
|
|
setExpandedKeys(tempExpandedKeys);
|
|
|
|
|
|
|
|
console.log("agencyProducts", agencyProducts)
|
|
|
|
setProductsData(agencyProducts);
|
|
|
|
setProductsData(agencyProducts);
|
|
|
|
setDefaultData(treeData);
|
|
|
|
setDefaultData(treeData);
|
|
|
|
setDataList(flattenTreeData(treeData));
|
|
|
|
setDataList(flattenTreeData(treeData));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
fetchData();
|
|
|
|
fetchData();
|
|
|
|
}, [agencyProducts, dataFetched]);
|
|
|
|
}, [agencyProducts, dataFetched]);
|
|
|
|
|
|
|
|
|
|
|
@ -244,7 +241,6 @@ function Detail() {
|
|
|
|
.filter(item => item.title.includes(value))
|
|
|
|
.filter(item => item.title.includes(value))
|
|
|
|
.map(item => getParentKey(item.key, defaultData))
|
|
|
|
.map(item => getParentKey(item.key, defaultData))
|
|
|
|
.filter((item, i, self) => item && self.indexOf(item) === i);
|
|
|
|
.filter((item, i, self) => item && self.indexOf(item) === i);
|
|
|
|
console.log("newExpandedKeys", newExpandedKeys)
|
|
|
|
|
|
|
|
setExpandedKeys(newExpandedKeys);
|
|
|
|
setExpandedKeys(newExpandedKeys);
|
|
|
|
setSearchValue(value);
|
|
|
|
setSearchValue(value);
|
|
|
|
setAutoExpandParent(true);
|
|
|
|
setAutoExpandParent(true);
|
|
|
@ -255,13 +251,9 @@ function Detail() {
|
|
|
|
setAutoExpandParent(false);
|
|
|
|
setAutoExpandParent(false);
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const isEditing = (record) => record.id === editingid;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const edit = (record, index) => {
|
|
|
|
const edit = (record, index) => {
|
|
|
|
setQuotationTableVisible(true);
|
|
|
|
setQuotationTableVisible(true);
|
|
|
|
setEditIndex(index);
|
|
|
|
setEditIndex(index);
|
|
|
|
// record.use_dates_start = dayjs(record.use_dates_start);
|
|
|
|
|
|
|
|
// record.use_dates_end = dayjs(record.use_dates_end);
|
|
|
|
|
|
|
|
setCurrentQuotationRecord(record);
|
|
|
|
setCurrentQuotationRecord(record);
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
@ -269,11 +261,10 @@ function Detail() {
|
|
|
|
setEditingid('');
|
|
|
|
setEditingid('');
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const handleDelete = (id) => {
|
|
|
|
const handleDelete = (index) => {
|
|
|
|
const newData = [...quotation];
|
|
|
|
const newData = [...quotation];
|
|
|
|
const index = newData.findIndex((item) => id === item.id);
|
|
|
|
// // const index = newData.findIndex((item) => id === item.id);
|
|
|
|
newData.splice(index, 1);
|
|
|
|
newData.splice(index, 1);
|
|
|
|
|
|
|
|
|
|
|
|
const sortedData = [...newData].sort((a, b) => {
|
|
|
|
const sortedData = [...newData].sort((a, b) => {
|
|
|
|
const aValidPeriod = dayjs(a.use_dates_end).diff(dayjs(a.use_dates_start));
|
|
|
|
const aValidPeriod = dayjs(a.use_dates_end).diff(dayjs(a.use_dates_start));
|
|
|
|
const bValidPeriod = dayjs(b.use_dates_end).diff(dayjs(b.use_dates_start));
|
|
|
|
const bValidPeriod = dayjs(b.use_dates_end).diff(dayjs(b.use_dates_start));
|
|
|
@ -291,14 +282,17 @@ function Detail() {
|
|
|
|
|
|
|
|
|
|
|
|
const handleAdd = () => {
|
|
|
|
const handleAdd = () => {
|
|
|
|
const newData = {
|
|
|
|
const newData = {
|
|
|
|
value: '',
|
|
|
|
adult_cost: 0,
|
|
|
|
|
|
|
|
child_cost: 0,
|
|
|
|
currency: '',
|
|
|
|
currency: '',
|
|
|
|
unit_name: '',
|
|
|
|
group_size_min: 0,
|
|
|
|
weekdays: '',
|
|
|
|
group_size_max: 0,
|
|
|
|
|
|
|
|
id: '',
|
|
|
|
|
|
|
|
lastedit_changed: '',
|
|
|
|
use_dates_start: '',
|
|
|
|
use_dates_start: '',
|
|
|
|
use_dates_end: '',
|
|
|
|
use_dates_end: '',
|
|
|
|
group_size_min: '',
|
|
|
|
weekdays: '',
|
|
|
|
group_size_max: ''
|
|
|
|
tempKey: Math.random()
|
|
|
|
};
|
|
|
|
};
|
|
|
|
setQuotation([...quotation, newData]);
|
|
|
|
setQuotation([...quotation, newData]);
|
|
|
|
};
|
|
|
|
};
|
|
|
@ -307,19 +301,11 @@ function Detail() {
|
|
|
|
setBatchImportPriceVisible(true);
|
|
|
|
setBatchImportPriceVisible(true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const handleDateSelect = (id) => {
|
|
|
|
|
|
|
|
setCurrentid(id);
|
|
|
|
|
|
|
|
setDatePickerVisible(true);
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const quotationTableVisibleOK = () => {
|
|
|
|
const quotationTableVisibleOK = () => {
|
|
|
|
currentQuotationRecord.use_dates_start = dayjs(currentQuotationRecord.use_dates_start).format('YYYY-MM-DD')
|
|
|
|
currentQuotationRecord.use_dates_start = dayjs(currentQuotationRecord.use_dates_start).format('YYYY-MM-DD')
|
|
|
|
currentQuotationRecord.use_dates_end = dayjs(currentQuotationRecord.use_dates_end).format('YYYY-MM-DD')
|
|
|
|
currentQuotationRecord.use_dates_end = dayjs(currentQuotationRecord.use_dates_end).format('YYYY-MM-DD')
|
|
|
|
console.log("currentQuotationRecord", currentQuotationRecord);
|
|
|
|
|
|
|
|
console.log("qqqqq", quotation)
|
|
|
|
|
|
|
|
const tempQuotation = [...quotation];
|
|
|
|
const tempQuotation = [...quotation];
|
|
|
|
tempQuotation[editIndex] = { ...currentQuotationRecord,weekdays:weekdays };
|
|
|
|
tempQuotation[editIndex] = { ...currentQuotationRecord, weekdays: weekdays };
|
|
|
|
console.log("tempQuotation", tempQuotation)
|
|
|
|
|
|
|
|
const sortedData = [...tempQuotation].sort((a, b) => {
|
|
|
|
const sortedData = [...tempQuotation].sort((a, b) => {
|
|
|
|
const aValidPeriod = dayjs(a.use_dates_end).diff(dayjs(a.use_dates_start));
|
|
|
|
const aValidPeriod = dayjs(a.use_dates_end).diff(dayjs(a.use_dates_start));
|
|
|
|
const bValidPeriod = dayjs(b.use_dates_end).diff(dayjs(b.use_dates_start));
|
|
|
|
const bValidPeriod = dayjs(b.use_dates_end).diff(dayjs(b.use_dates_start));
|
|
|
@ -332,8 +318,6 @@ function Detail() {
|
|
|
|
|
|
|
|
|
|
|
|
return aGroupSize - bGroupSize;
|
|
|
|
return aGroupSize - bGroupSize;
|
|
|
|
});
|
|
|
|
});
|
|
|
|
console.log("sortedData",sortedData)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
setQuotation(sortedData);
|
|
|
|
setQuotation(sortedData);
|
|
|
|
setQuotationTableVisible(false);
|
|
|
|
setQuotationTableVisible(false);
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -343,11 +327,6 @@ function Detail() {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const handleBatchImportOK = () => {
|
|
|
|
const handleBatchImportOK = () => {
|
|
|
|
console.log("quotation", quotation)
|
|
|
|
|
|
|
|
console.log('Batch Import Data:', batchImportData);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const tempBatchImportData = batchImportData.map(item => {
|
|
|
|
const tempBatchImportData = batchImportData.map(item => {
|
|
|
|
const { tag, validPeriod, ...rest } = item;
|
|
|
|
const { tag, validPeriod, ...rest } = item;
|
|
|
|
return rest;
|
|
|
|
return rest;
|
|
|
@ -372,7 +351,13 @@ function Detail() {
|
|
|
|
{ title: t('products:adultPrice'), dataIndex: 'adult_cost', width: '10%', editable: true },
|
|
|
|
{ title: t('products:adultPrice'), dataIndex: 'adult_cost', width: '10%', editable: true },
|
|
|
|
{ title: t('products:childrenPrice'), dataIndex: 'child_cost', width: '10%', editable: true },
|
|
|
|
{ title: t('products:childrenPrice'), dataIndex: 'child_cost', width: '10%', editable: true },
|
|
|
|
{ title: t('products:currency'), dataIndex: 'currency', width: '10%', editable: true },
|
|
|
|
{ title: t('products:currency'), dataIndex: 'currency', width: '10%', editable: true },
|
|
|
|
{ title: t('products:Types'), dataIndex: 'unit_name', width: '10%', editable: true },
|
|
|
|
{
|
|
|
|
|
|
|
|
title: t('products:Types'),
|
|
|
|
|
|
|
|
dataIndex: 'unit',
|
|
|
|
|
|
|
|
width: '10%',
|
|
|
|
|
|
|
|
editable: true,
|
|
|
|
|
|
|
|
render: (text) => (text === '0' ? '每人' : text === '1' ? '每团' : text),
|
|
|
|
|
|
|
|
},
|
|
|
|
{
|
|
|
|
{
|
|
|
|
title: t('products:number'),
|
|
|
|
title: t('products:number'),
|
|
|
|
dataIndex: 'group_size',
|
|
|
|
dataIndex: 'group_size',
|
|
|
@ -398,7 +383,7 @@ function Detail() {
|
|
|
|
return (
|
|
|
|
return (
|
|
|
|
<span>
|
|
|
|
<span>
|
|
|
|
<a onClick={() => edit(record, index)} style={{ marginRight: 8 }}>{t('Edit')}</a>
|
|
|
|
<a onClick={() => edit(record, index)} style={{ marginRight: 8 }}>{t('Edit')}</a>
|
|
|
|
<Popconfirm title={t('sureDelete')} onConfirm={() => handleDelete(record.id)}>
|
|
|
|
<Popconfirm title={t('sureDelete')} onConfirm={() => handleDelete(index)}>
|
|
|
|
<a>{t('Delete')}</a>
|
|
|
|
<a>{t('Delete')}</a>
|
|
|
|
</Popconfirm>
|
|
|
|
</Popconfirm>
|
|
|
|
</span>
|
|
|
|
</span>
|
|
|
@ -409,23 +394,6 @@ function Detail() {
|
|
|
|
];
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// const mergedColumns = columns.map((col) => {
|
|
|
|
|
|
|
|
// if (!col.editable) {
|
|
|
|
|
|
|
|
// return col;
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// return {
|
|
|
|
|
|
|
|
// ...col,
|
|
|
|
|
|
|
|
// onCell: (record) => ({
|
|
|
|
|
|
|
|
// record,
|
|
|
|
|
|
|
|
// inputType: col.dataIndex === 'age' ? 'number' : 'text',
|
|
|
|
|
|
|
|
// dataIndex: col.dataIndex,
|
|
|
|
|
|
|
|
// title: col.title,
|
|
|
|
|
|
|
|
// editing: isEditing(record),
|
|
|
|
|
|
|
|
// handleDateSelect: handleDateSelect,
|
|
|
|
|
|
|
|
// }),
|
|
|
|
|
|
|
|
// };
|
|
|
|
|
|
|
|
// });
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const handleTagClick = (tag) => {
|
|
|
|
const handleTagClick = (tag) => {
|
|
|
|
setSelectedTag(tag);
|
|
|
|
setSelectedTag(tag);
|
|
|
|
const matchedLanguage = HTLanguageSets.find(language => language.label === tag);
|
|
|
|
const matchedLanguage = HTLanguageSets.find(language => language.label === tag);
|
|
|
@ -433,7 +401,7 @@ function Detail() {
|
|
|
|
form.setFieldsValue({
|
|
|
|
form.setFieldsValue({
|
|
|
|
lgc_details: {
|
|
|
|
lgc_details: {
|
|
|
|
title: lgc_details[key] ? lgc_details[key].title : '',
|
|
|
|
title: lgc_details[key] ? lgc_details[key].title : '',
|
|
|
|
descriptions: lgc_details[key] ? lgc_details[key].descriptions : ''
|
|
|
|
description: lgc_details[key] ? lgc_details[key].description : ''
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
setLanguageStatus(key)
|
|
|
|
setLanguageStatus(key)
|
|
|
@ -458,7 +426,8 @@ function Detail() {
|
|
|
|
...lgc_details, [languageKey]: {
|
|
|
|
...lgc_details, [languageKey]: {
|
|
|
|
title: "",
|
|
|
|
title: "",
|
|
|
|
lgc: languageKey,
|
|
|
|
lgc: languageKey,
|
|
|
|
descriptions: ""
|
|
|
|
description: "",
|
|
|
|
|
|
|
|
id: ""
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
setLgc_details(tempLgc_details)
|
|
|
|
setLgc_details(tempLgc_details)
|
|
|
@ -475,7 +444,6 @@ function Detail() {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const handleTagChange = (value) => {
|
|
|
|
const handleTagChange = (value) => {
|
|
|
|
console.log("handleTagChange", value)
|
|
|
|
|
|
|
|
setSelectedTag(value);
|
|
|
|
setSelectedTag(value);
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
@ -483,9 +451,13 @@ function Detail() {
|
|
|
|
// 更新整个 lgc_details 对象
|
|
|
|
// 更新整个 lgc_details 对象
|
|
|
|
const updatedLgcDetails = {
|
|
|
|
const updatedLgcDetails = {
|
|
|
|
...lgc_details,
|
|
|
|
...lgc_details,
|
|
|
|
[languageStatus]: { ...lgc_details[languageStatus], [field]: value, lgc: languageStatus }
|
|
|
|
[languageStatus]: {
|
|
|
|
|
|
|
|
...lgc_details[languageStatus],
|
|
|
|
|
|
|
|
[field]: value,
|
|
|
|
|
|
|
|
lgc: languageStatus.toString(),
|
|
|
|
|
|
|
|
id: lgc_details[languageStatus]?.id || ''
|
|
|
|
|
|
|
|
}
|
|
|
|
};
|
|
|
|
};
|
|
|
|
console.log("updatedLgcDetails", updatedLgcDetails)
|
|
|
|
|
|
|
|
setLgc_details(updatedLgcDetails)
|
|
|
|
setLgc_details(updatedLgcDetails)
|
|
|
|
|
|
|
|
|
|
|
|
};
|
|
|
|
};
|
|
|
@ -497,89 +469,122 @@ function Detail() {
|
|
|
|
const updatedDays = prevSelectedDays.includes(dayOfWeek)
|
|
|
|
const updatedDays = prevSelectedDays.includes(dayOfWeek)
|
|
|
|
? prevSelectedDays.filter((d) => d !== dayOfWeek)
|
|
|
|
? prevSelectedDays.filter((d) => d !== dayOfWeek)
|
|
|
|
: [...prevSelectedDays, dayOfWeek];
|
|
|
|
: [...prevSelectedDays, dayOfWeek];
|
|
|
|
console.log("updatedDays",updatedDays);
|
|
|
|
|
|
|
|
const weekdaysString = updatedDays.sort().join(',');
|
|
|
|
const weekdaysString = updatedDays.sort().join(',');
|
|
|
|
console.log("weekdaysString",weekdaysString)
|
|
|
|
setWeekdays(weekdaysString);
|
|
|
|
setWeekdays(weekdaysString)
|
|
|
|
|
|
|
|
return updatedDays;
|
|
|
|
return updatedDays;
|
|
|
|
});
|
|
|
|
});
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
//树组件方法
|
|
|
|
//树组件方法
|
|
|
|
const handleNodeSelect = (_, { node }) => {
|
|
|
|
const handleNodeSelect = (_, { node }) => {
|
|
|
|
|
|
|
|
setSelectedNodeid(node.key);
|
|
|
|
|
|
|
|
const fatherKey = node.key.split('-')[0];
|
|
|
|
|
|
|
|
setSelectedNodeKey(fatherKey);
|
|
|
|
|
|
|
|
setSelectedCategory(productProject[fatherKey]);
|
|
|
|
|
|
|
|
setTags([languageLabel]);
|
|
|
|
|
|
|
|
// 如果点击的是同一个节点,不做任何操作
|
|
|
|
|
|
|
|
if (selectedNodeid === node.key) return;
|
|
|
|
|
|
|
|
setLanguageStatus(language);
|
|
|
|
|
|
|
|
const matchedLanguage = HTLanguageSets.find(HTLanguage => HTLanguage.key === language.toString());
|
|
|
|
|
|
|
|
const languageLabelRefresh = matchedLanguage.label;
|
|
|
|
|
|
|
|
setLanguageLabel(languageLabelRefresh);
|
|
|
|
|
|
|
|
setSelectedTag(languageLabelRefresh);
|
|
|
|
|
|
|
|
setRemainderLanguage(HTLanguageSets.filter(item => item.key !== language.toString()));
|
|
|
|
|
|
|
|
setEditingProduct(node._raw);
|
|
|
|
if (!node._raw.info.id) {
|
|
|
|
if (!node._raw.info.id) {
|
|
|
|
console.log("nodeNoID", node)
|
|
|
|
let infoData = node._raw.info;
|
|
|
|
setQuotation([])
|
|
|
|
setInfo(node._raw.info);
|
|
|
|
const infoData = node._raw.info
|
|
|
|
console.log("node._raw",node._raw)
|
|
|
|
|
|
|
|
console.log("没有id");
|
|
|
|
const newLgcDetails = node._raw.lgc_details
|
|
|
|
const newLgcDetails = node._raw.lgc_details
|
|
|
|
const fatherKey = node.key.split('-')[0];
|
|
|
|
const fatherKey = node.key.split('-')[0];
|
|
|
|
setSelectedNodeid(node.key);
|
|
|
|
setSelectedNodeid(node.key);
|
|
|
|
setSelectedNodeKey(fatherKey);
|
|
|
|
setSelectedNodeKey(fatherKey);
|
|
|
|
form.setFieldsValue({
|
|
|
|
form.setFieldsValue({
|
|
|
|
info: {
|
|
|
|
info: {
|
|
|
|
title: infoData.title,
|
|
|
|
id: infoData.id || "",
|
|
|
|
code: infoData.code,
|
|
|
|
title: infoData.title || "",
|
|
|
|
product_type_name: infoData.product_type_name,
|
|
|
|
code: infoData.code || "",
|
|
|
|
city_name: infoData.city_name,
|
|
|
|
type: infoData.product_type_id || "",
|
|
|
|
remarks: infoData.remarks,
|
|
|
|
audit_state:"-1",
|
|
|
|
open_weekdays: infoData.open_weekdays,
|
|
|
|
create_date: infoData.create_date || "",
|
|
|
|
recommends_rate: infoData.recommends_rate,
|
|
|
|
created_by: infoData.created_by || "",
|
|
|
|
duration: infoData.duration,
|
|
|
|
travel_agency_id: travel_agency_id || "",
|
|
|
|
dept: infoData.dept,
|
|
|
|
travel_agency_name: activeAgency.travel_agency_name || "",
|
|
|
|
km: infoData.km,
|
|
|
|
lastedit_changed: infoData.lastedit_changed || "",
|
|
|
|
dept_name: infoData.dept_name,
|
|
|
|
remarks: infoData.remarks || "",
|
|
|
|
|
|
|
|
duration: infoData.duration || "",
|
|
|
|
|
|
|
|
duration_unit: infoData.duration_unit || "",
|
|
|
|
|
|
|
|
open_weekdays: infoData.open_weekdays || "",
|
|
|
|
|
|
|
|
recommends_rate: infoData.recommends_rate || "",
|
|
|
|
|
|
|
|
dept: infoData.dept_id || "",
|
|
|
|
|
|
|
|
display_to_c: infoData.display_to_c || "",
|
|
|
|
|
|
|
|
km: infoData.km || "",
|
|
|
|
|
|
|
|
city_name: infoData.city_name || "",
|
|
|
|
|
|
|
|
city_id: infoData.city_id || "",
|
|
|
|
|
|
|
|
// product_type_name: infoData.product_type_name || "",
|
|
|
|
|
|
|
|
// dept_name: infoData.dept_name || "",
|
|
|
|
|
|
|
|
|
|
|
|
},
|
|
|
|
},
|
|
|
|
lgc_details: {
|
|
|
|
lgc_details: {
|
|
|
|
lgc: language,
|
|
|
|
lgc: language,
|
|
|
|
title: newLgcDetails[language]?.title || '',
|
|
|
|
title: newLgcDetails[language]?.title || '',
|
|
|
|
descriptions: newLgcDetails[language]?.descriptions || ''
|
|
|
|
description: newLgcDetails[language]?.description || ''
|
|
|
|
}
|
|
|
|
}
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
setLgc_details([])
|
|
|
|
|
|
|
|
setQuotation([{
|
|
|
|
|
|
|
|
adult_cost: 0,
|
|
|
|
|
|
|
|
child_cost: 0,
|
|
|
|
|
|
|
|
currency: '',
|
|
|
|
|
|
|
|
group_size_min: 0,
|
|
|
|
|
|
|
|
group_size_max: 0,
|
|
|
|
|
|
|
|
id: '',
|
|
|
|
|
|
|
|
lastedit_changed: '',
|
|
|
|
|
|
|
|
use_dates_start: '',
|
|
|
|
|
|
|
|
use_dates_end: '',
|
|
|
|
|
|
|
|
weekdays: '',
|
|
|
|
|
|
|
|
tempKey: Math.random()
|
|
|
|
|
|
|
|
}])
|
|
|
|
return
|
|
|
|
return
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
setTags([languageLabel])
|
|
|
|
|
|
|
|
// 如果点击的是同一个节点,不做任何操作
|
|
|
|
|
|
|
|
if (selectedNodeid === node.key) return;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
setSelectedNodeid(node.key);
|
|
|
|
|
|
|
|
const fatherKey = node.key.split('-')[0];
|
|
|
|
|
|
|
|
setSelectedNodeKey(fatherKey);
|
|
|
|
|
|
|
|
console.log("node.key", node.key);
|
|
|
|
|
|
|
|
console.log("fatherKey", fatherKey)
|
|
|
|
|
|
|
|
setSelectedCategory(productProject[fatherKey]);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
setLanguageStatus(language);
|
|
|
|
|
|
|
|
const matchedLanguage = HTLanguageSets.find(HTLanguage => HTLanguage.key === language.toString());
|
|
|
|
|
|
|
|
const languageLabelRefresh = matchedLanguage.label;
|
|
|
|
|
|
|
|
setLanguageLabel(languageLabelRefresh);
|
|
|
|
|
|
|
|
setSelectedTag(languageLabelRefresh);
|
|
|
|
|
|
|
|
setRemainderLanguage(HTLanguageSets.filter(item => item.key !== language.toString()));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
setEditingProduct(node._raw);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let initialQuotationData = null;
|
|
|
|
let initialQuotationData = null;
|
|
|
|
let infoData = null;
|
|
|
|
let infoData = null;
|
|
|
|
let lgcDetailsData = null;
|
|
|
|
let lgcDetailsData = null;
|
|
|
|
console.log("productsData", productsData)
|
|
|
|
|
|
|
|
console.log("productsData[fatherKey]", productsData[fatherKey])
|
|
|
|
|
|
|
|
console.log("node", node)
|
|
|
|
|
|
|
|
// console.log("node",node._raw)
|
|
|
|
|
|
|
|
productsData[fatherKey].forEach(element => {
|
|
|
|
productsData[fatherKey].forEach(element => {
|
|
|
|
if (element.info.id === node._raw.info.id) {
|
|
|
|
if (element.info.id === node._raw.info.id) {
|
|
|
|
initialQuotationData = element.quotation;
|
|
|
|
initialQuotationData = element.quotation;
|
|
|
|
infoData = element.info;
|
|
|
|
infoData = element.info;
|
|
|
|
lgcDetailsData = element.lgc_details;
|
|
|
|
lgcDetailsData = element.lgc_details.map(item => {
|
|
|
|
|
|
|
|
const newItem = {
|
|
|
|
|
|
|
|
...item,
|
|
|
|
|
|
|
|
description: item.descriptions,
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
delete newItem.descriptions;
|
|
|
|
|
|
|
|
return newItem;
|
|
|
|
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
const quotationData = initialQuotationData.map(element => {
|
|
|
|
|
|
|
|
const updatedObject = {
|
|
|
|
|
|
|
|
...element,
|
|
|
|
|
|
|
|
unit: element.unit_id,
|
|
|
|
|
|
|
|
tempKey: Math.random()
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
delete updatedObject.unit_name;
|
|
|
|
|
|
|
|
delete updatedObject.unit_id;
|
|
|
|
|
|
|
|
delete updatedObject.audit_state_id;
|
|
|
|
|
|
|
|
delete updatedObject.audit_state_name;
|
|
|
|
|
|
|
|
return updatedObject;
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!node._raw.info.id) {
|
|
|
|
if (!node._raw.info.id) {
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
console.log("lgcDetailsData", lgcDetailsData)
|
|
|
|
|
|
|
|
// 累积 lgc_details 数据
|
|
|
|
// 累积 lgc_details 数据
|
|
|
|
let newLgcDetails = {};
|
|
|
|
let newLgcDetails = {};
|
|
|
|
if (lgcDetailsData) {
|
|
|
|
if (lgcDetailsData) {
|
|
|
@ -587,8 +592,6 @@ function Detail() {
|
|
|
|
newLgcDetails[element.lgc] = element;
|
|
|
|
newLgcDetails[element.lgc] = element;
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
console.log("infoData", infoData)
|
|
|
|
|
|
|
|
console.log("laug", language)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (node._raw.info.id) {
|
|
|
|
if (node._raw.info.id) {
|
|
|
|
setInfoDataForId(infoData.id)
|
|
|
|
setInfoDataForId(infoData.id)
|
|
|
@ -596,7 +599,7 @@ function Detail() {
|
|
|
|
setLgc_details(newLgcDetails);
|
|
|
|
setLgc_details(newLgcDetails);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const sortedData = [...initialQuotationData].sort((a, b) => {
|
|
|
|
let sortedData = [...quotationData].sort((a, b) => {
|
|
|
|
// 计算有效期范围大小
|
|
|
|
// 计算有效期范围大小
|
|
|
|
const aValidPeriod = dayjs(a.use_dates_end).diff(dayjs(a.use_dates_start));
|
|
|
|
const aValidPeriod = dayjs(a.use_dates_end).diff(dayjs(a.use_dates_start));
|
|
|
|
const bValidPeriod = dayjs(b.use_dates_end).diff(dayjs(b.use_dates_start));
|
|
|
|
const bValidPeriod = dayjs(b.use_dates_end).diff(dayjs(b.use_dates_start));
|
|
|
@ -612,53 +615,92 @@ function Detail() {
|
|
|
|
|
|
|
|
|
|
|
|
return aGroupSize - bGroupSize;
|
|
|
|
return aGroupSize - bGroupSize;
|
|
|
|
});
|
|
|
|
});
|
|
|
|
setQuotation(sortedData);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const tempInfo = {
|
|
|
|
|
|
|
|
id: infoData.id || "",
|
|
|
|
|
|
|
|
title: infoData.title || "",
|
|
|
|
|
|
|
|
code: infoData.code || "",
|
|
|
|
|
|
|
|
type: infoData.product_type_id || "",
|
|
|
|
|
|
|
|
create_date: infoData.create_date || "",
|
|
|
|
|
|
|
|
created_by: infoData.created_by || "",
|
|
|
|
|
|
|
|
travel_agency_id: travel_agency_id || "",
|
|
|
|
|
|
|
|
travel_agency_name: activeAgency.travel_agency_name || "",
|
|
|
|
|
|
|
|
lastedit_changed: infoData.lastedit_changed || "",
|
|
|
|
|
|
|
|
remarks: infoData.remarks || "",
|
|
|
|
|
|
|
|
duration: infoData.duration || "",
|
|
|
|
|
|
|
|
duration_unit: infoData.duration_unit || "",
|
|
|
|
|
|
|
|
open_weekdays: infoData.open_weekdays || "",
|
|
|
|
|
|
|
|
recommends_rate: infoData.recommends_rate || "",
|
|
|
|
|
|
|
|
dept: infoData.dept_id || "",
|
|
|
|
|
|
|
|
display_to_c: infoData.display_to_c || "",
|
|
|
|
|
|
|
|
km: infoData.km || "",
|
|
|
|
|
|
|
|
city_name: infoData.city_name || "",
|
|
|
|
|
|
|
|
city_id: infoData.city_id || "",
|
|
|
|
|
|
|
|
product_type_name: infoData.product_type_name || "",
|
|
|
|
|
|
|
|
dept_name: infoData.dept_name || "",
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
setInfo(tempInfo);
|
|
|
|
|
|
|
|
setQuotation(sortedData);
|
|
|
|
if (node._raw.info.id) {
|
|
|
|
if (node._raw.info.id) {
|
|
|
|
form.setFieldsValue({
|
|
|
|
form.setFieldsValue({
|
|
|
|
info: {
|
|
|
|
info: tempInfo,
|
|
|
|
title: infoData.title,
|
|
|
|
|
|
|
|
code: infoData.code,
|
|
|
|
|
|
|
|
product_type_name: infoData.product_type_name,
|
|
|
|
|
|
|
|
city_name: infoData.city_name,
|
|
|
|
|
|
|
|
remarks: infoData.remarks,
|
|
|
|
|
|
|
|
open_weekdays: infoData.open_weekdays,
|
|
|
|
|
|
|
|
recommends_rate: infoData.recommends_rate,
|
|
|
|
|
|
|
|
duration: infoData.duration,
|
|
|
|
|
|
|
|
dept: infoData.dept,
|
|
|
|
|
|
|
|
km: infoData.km,
|
|
|
|
|
|
|
|
dept_name: infoData.dept_name,
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
lgc_details: {
|
|
|
|
lgc_details: {
|
|
|
|
lgc: language,
|
|
|
|
lgc: language,
|
|
|
|
title: newLgcDetails[language]?.title || '',
|
|
|
|
title: newLgcDetails[language]?.title || '',
|
|
|
|
descriptions: newLgcDetails[language]?.descriptions || ''
|
|
|
|
description: newLgcDetails[language]?.description || ''
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const handelAddProduct = () => {
|
|
|
|
const handelAddProduct = () => {
|
|
|
|
// 找到对应的产品类型节点
|
|
|
|
// 找到对应的产品类型节点
|
|
|
|
const productTypeNode = treeData.find(item => item.key === addProductType);
|
|
|
|
const productTypeNode = treeData.find(item => item.key === addProductType);
|
|
|
|
console.log("productTypeNode", productTypeNode);
|
|
|
|
console.log("productTypeNode", productTypeNode)
|
|
|
|
|
|
|
|
// if (productTypeNode) {
|
|
|
|
if (productTypeNode) {
|
|
|
|
// // 在 children 数组中插入新的产品节点
|
|
|
|
// 在 children 数组中插入新的产品节点
|
|
|
|
const tempAddData = {
|
|
|
|
|
|
|
|
info: {
|
|
|
|
|
|
|
|
id: "",
|
|
|
|
|
|
|
|
title: addproductName,
|
|
|
|
|
|
|
|
code: "",
|
|
|
|
|
|
|
|
type: addProductType,
|
|
|
|
|
|
|
|
create_date: "",
|
|
|
|
|
|
|
|
created_by: "",
|
|
|
|
|
|
|
|
travel_agency_id: "",
|
|
|
|
|
|
|
|
travel_agency_name: "",
|
|
|
|
|
|
|
|
lastedit_changed: "",
|
|
|
|
|
|
|
|
remarks: "",
|
|
|
|
|
|
|
|
duration: "",
|
|
|
|
|
|
|
|
duration_unit: "",
|
|
|
|
|
|
|
|
open_weekdays: "",
|
|
|
|
|
|
|
|
recommends_rate: "",
|
|
|
|
|
|
|
|
dept: "",
|
|
|
|
|
|
|
|
display_to_c: "",
|
|
|
|
|
|
|
|
km: "",
|
|
|
|
|
|
|
|
city_name: "",
|
|
|
|
|
|
|
|
city_id: "",
|
|
|
|
|
|
|
|
product_type_name: "",
|
|
|
|
|
|
|
|
dept_name: "",
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
lgc_details: [
|
|
|
|
|
|
|
|
],
|
|
|
|
|
|
|
|
quotation: []
|
|
|
|
|
|
|
|
}
|
|
|
|
const newChildren = [
|
|
|
|
const newChildren = [
|
|
|
|
...productTypeNode.children,
|
|
|
|
...productTypeNode.children,
|
|
|
|
{
|
|
|
|
{
|
|
|
|
title: addproductName,
|
|
|
|
title: addproductName,
|
|
|
|
key: `${addProductType}-${Date.now()}`, // 使用时间戳作为唯一的 key
|
|
|
|
key: `${addProductType}-${Date.now()}`,
|
|
|
|
_raw: {
|
|
|
|
_raw: tempAddData
|
|
|
|
info: { code: '' },
|
|
|
|
|
|
|
|
lgc_details: [],
|
|
|
|
|
|
|
|
quotation: []
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
];
|
|
|
|
];
|
|
|
|
// 创建新的 treeData 数组,确保 React 能够检测到更改
|
|
|
|
// // 创建新的 treeData 数组,确保 React 能够检测到更改
|
|
|
|
const newTreeData = treeData.map(item => {
|
|
|
|
const newTreeData = treeData.map(item => {
|
|
|
|
if (item.key === addProductType) {
|
|
|
|
if (item.key === addProductType) {
|
|
|
|
return {
|
|
|
|
return {
|
|
|
@ -670,100 +712,146 @@ function Detail() {
|
|
|
|
});
|
|
|
|
});
|
|
|
|
// 更新 treeData
|
|
|
|
// 更新 treeData
|
|
|
|
setEditingProduct(null)
|
|
|
|
setEditingProduct(null)
|
|
|
|
|
|
|
|
console.log("newTreeData", newTreeData);
|
|
|
|
setTreeData(newTreeData);
|
|
|
|
setTreeData(newTreeData);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
console.log("productData", productsData)
|
|
|
|
|
|
|
|
console.log("addProductType", addProductType)
|
|
|
|
|
|
|
|
let tempProductDataList = productsData[addProductType];
|
|
|
|
let tempProductDataList = productsData[addProductType];
|
|
|
|
|
|
|
|
tempProductDataList.push(tempAddData);
|
|
|
|
//初始化产品数据
|
|
|
|
|
|
|
|
const newProduct = {
|
|
|
|
|
|
|
|
info: {
|
|
|
|
|
|
|
|
code: 'addProduct'
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
quotation: [],
|
|
|
|
|
|
|
|
lgc_details: []
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
tempProductDataList.push(newProduct);
|
|
|
|
|
|
|
|
console.log("tempProductDataList", tempProductDataList)
|
|
|
|
|
|
|
|
const newProductsData = {
|
|
|
|
const newProductsData = {
|
|
|
|
...productsData, // 假设使用了展开运算符来复制现有数组
|
|
|
|
...productsData, // 假设使用了展开运算符来复制现有数组
|
|
|
|
[addProductType]: tempProductDataList
|
|
|
|
[addProductType]: tempProductDataList
|
|
|
|
};
|
|
|
|
};
|
|
|
|
setProductsData(newProductsData);
|
|
|
|
setProductsData(newProductsData);
|
|
|
|
console.log("newProductsData", newProductsData)
|
|
|
|
|
|
|
|
setAddProductVisible(false);
|
|
|
|
setAddProductVisible(false);
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const onSave = (values) => {
|
|
|
|
// let tempProductDataList = productsData[addProductType];
|
|
|
|
// 找到匹配的树节点
|
|
|
|
|
|
|
|
let matchedTreeData = treeData.find(treeKey => treeKey.key === selectedNodeKey);
|
|
|
|
// //初始化产品数据
|
|
|
|
if (matchedTreeData) {
|
|
|
|
// const newProduct = {
|
|
|
|
// 找到匹配的子节点
|
|
|
|
// info: {
|
|
|
|
const matchedTreeDataChildren = matchedTreeData.children;
|
|
|
|
// code: 'addProduct'
|
|
|
|
// 检查是否已存在具有 selectedNodeid 的子节点
|
|
|
|
// },
|
|
|
|
console.log("matchedTreeDataChildren", matchedTreeDataChildren)
|
|
|
|
// quotation: [],
|
|
|
|
console.log("selectedNodeid", selectedNodeid)
|
|
|
|
// lgc_details: []
|
|
|
|
// if (matchedTreeDataChildren.some(child => child.key === selectedNodeid)) {
|
|
|
|
|
|
|
|
// console.log("Child with this ID already exists.");
|
|
|
|
|
|
|
|
// return;
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
let tempTreeDataChildrenData = matchedTreeDataChildren.find(element => element.key === selectedNodeid);
|
|
|
|
|
|
|
|
console.log("tempTreeDataChildrenData", tempTreeDataChildrenData);
|
|
|
|
|
|
|
|
// if (tempTreeDataChildrenData) {
|
|
|
|
|
|
|
|
tempTreeDataChildrenData._raw = values;
|
|
|
|
|
|
|
|
console.log("tempTreeDataChildrenData改", tempTreeDataChildrenData)
|
|
|
|
|
|
|
|
console.log("treeData111111", treeData)
|
|
|
|
|
|
|
|
console.log("lgc_details", lgc_details)
|
|
|
|
|
|
|
|
tempTreeDataChildrenData._raw.lgc_details = lgc_details
|
|
|
|
|
|
|
|
// console.log("matchedTreeData", matchedTreeData)
|
|
|
|
|
|
|
|
// if (!matchedTreeData.children.some(element => element.key === selectedNodeid)) {
|
|
|
|
|
|
|
|
// console.log("重复了");
|
|
|
|
|
|
|
|
// matchedTreeData.children.push(tempTreeDataChildrenData)
|
|
|
|
|
|
|
|
// console.log("matchedTreeData改", matchedTreeData)
|
|
|
|
|
|
|
|
// return;
|
|
|
|
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
|
|
|
|
// tempProductDataList.push(newProduct);
|
|
|
|
|
|
|
|
// const newProductsData = {
|
|
|
|
|
|
|
|
// ...productsData, // 假设使用了展开运算符来复制现有数组
|
|
|
|
|
|
|
|
// [addProductType]: tempProductDataList
|
|
|
|
|
|
|
|
// };
|
|
|
|
|
|
|
|
// setProductsData(newProductsData);
|
|
|
|
|
|
|
|
// setAddProductVisible(false);
|
|
|
|
|
|
|
|
// };
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// } else {
|
|
|
|
const renderFormItem = (item) => {
|
|
|
|
// console.log("No matching child node found.");
|
|
|
|
switch (item.code) {
|
|
|
|
// }
|
|
|
|
case "duration":
|
|
|
|
|
|
|
|
return <Input suffix="H" />;
|
|
|
|
|
|
|
|
case "display_to_c":
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
|
|
|
<Select>
|
|
|
|
|
|
|
|
<Select.Option value={0}>在计划显示,不在报价信显示</Select.Option>
|
|
|
|
|
|
|
|
<Select.Option value={1}>计划和报价信都要显示</Select.Option>
|
|
|
|
|
|
|
|
<Select.Option value={2}>计划和报价信都不用显示</Select.Option>
|
|
|
|
|
|
|
|
</Select>
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
case "dept_name":
|
|
|
|
|
|
|
|
return <DeptSelector />;
|
|
|
|
|
|
|
|
case "city_name":
|
|
|
|
|
|
|
|
return <CitySelector />;
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
|
|
|
return <Input />;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const onSave = async (values) => {
|
|
|
|
|
|
|
|
let tempInfo
|
|
|
|
|
|
|
|
console.log("values", values)
|
|
|
|
|
|
|
|
console.log("info", info)
|
|
|
|
|
|
|
|
if (info.id === "") {
|
|
|
|
|
|
|
|
tempInfo = {
|
|
|
|
|
|
|
|
...info,
|
|
|
|
|
|
|
|
...values.info,
|
|
|
|
|
|
|
|
city_name: values.info.city_name.label,
|
|
|
|
|
|
|
|
audit_state:"-1"
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
delete tempInfo.product_type_name;
|
|
|
|
|
|
|
|
delete tempInfo.dept_name;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
console.log("新增")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let tempQuotation = quotation.map(element => {
|
|
|
|
|
|
|
|
const updateData = {
|
|
|
|
|
|
|
|
...element,
|
|
|
|
|
|
|
|
audit_state: "-1"
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
delete updateData.tempKey
|
|
|
|
|
|
|
|
return updateData
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
let tempLgc_details = [{...lgc_details}]
|
|
|
|
|
|
|
|
console.log("tempLgc_details",tempLgc_details)
|
|
|
|
|
|
|
|
const tempData = {
|
|
|
|
|
|
|
|
travel_agency_id,
|
|
|
|
|
|
|
|
info: tempInfo,
|
|
|
|
|
|
|
|
quotation: tempQuotation,
|
|
|
|
|
|
|
|
lgc_details: Object.values(lgc_details)
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
console.log("tempData",tempData);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const { errcode, result } = await postJSON(`${HT_HOST}/Service_BaseInfoWeb/agency_product_save`, tempData);
|
|
|
|
|
|
|
|
console.log("result",result)
|
|
|
|
|
|
|
|
if (errcode === 0) {
|
|
|
|
|
|
|
|
message.success("保存成功");
|
|
|
|
|
|
|
|
setDataFetched(false);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
message.error(`保存失败: ${result}`);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
console.log("No matching tree node found.");
|
|
|
|
tempInfo = {
|
|
|
|
|
|
|
|
...info,
|
|
|
|
|
|
|
|
...values.info,
|
|
|
|
|
|
|
|
audit_state: "-1"
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
console.log("tempInfo", tempInfo)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let tempQuotation = quotation.map(element => {
|
|
|
|
|
|
|
|
const updateData = {
|
|
|
|
|
|
|
|
...element,
|
|
|
|
|
|
|
|
audit_state: "-1"
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return updateData
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// if (infoDataForId) {
|
|
|
|
const tempData = {
|
|
|
|
// // 创建新的 tempData 对象
|
|
|
|
travel_agency_id,
|
|
|
|
// const tempData = {
|
|
|
|
info: tempInfo,
|
|
|
|
// ...values,
|
|
|
|
quotation: tempQuotation,
|
|
|
|
// info: { ...values.info, id: infoDataForId },
|
|
|
|
lgc_details: Object.values(lgc_details)
|
|
|
|
// quotation: quotation,
|
|
|
|
};
|
|
|
|
// lgc_details: Object.values(lgc_details)
|
|
|
|
|
|
|
|
// };
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// setSaveData(tempData);
|
|
|
|
console.log("tempData", tempData)
|
|
|
|
// console.log("保存的数据", tempData);
|
|
|
|
const { errcode, result } = await postJSON(`${HT_HOST}/Service_BaseInfoWeb/agency_product_save`, tempData);
|
|
|
|
// } else {
|
|
|
|
|
|
|
|
// // 创建新的 tempData 对象
|
|
|
|
|
|
|
|
// const tempData = {
|
|
|
|
|
|
|
|
// ...values,
|
|
|
|
|
|
|
|
// info: { ...values.info },
|
|
|
|
|
|
|
|
// quotation: quotation,
|
|
|
|
|
|
|
|
// lgc_details: Object.values(lgc_details)
|
|
|
|
|
|
|
|
// };
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// setSaveData(tempData);
|
|
|
|
if (errcode === 0) {
|
|
|
|
// console.log("保存的数据", tempData);
|
|
|
|
message.success("保存成功");
|
|
|
|
// }
|
|
|
|
setDataFetched(false);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
message.error(`保存失败: ${result}`);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
return (
|
|
|
|
<div>
|
|
|
|
<Spin spinning={treeData.length === 0}>
|
|
|
|
|
|
|
|
<div >
|
|
|
|
<Row>
|
|
|
|
<Row>
|
|
|
|
<Col span={6} className=' relative'>
|
|
|
|
<Col span={6} className=' relative'>
|
|
|
|
<Card className='w-[inherit] fixed overflow-y-auto max-h-[80%] max-w-[22%] overflow-x-auto'>
|
|
|
|
<Card className='w-[inherit] fixed overflow-y-auto max-h-[80%] max-w-[22%] overflow-x-auto'>
|
|
|
@ -802,27 +890,15 @@ function Detail() {
|
|
|
|
return (
|
|
|
|
return (
|
|
|
|
<Col span={8} id={index} key={`${item.code}-${index}`}>
|
|
|
|
<Col span={8} id={index} key={`${item.code}-${index}`}>
|
|
|
|
<Form.Item name={['info', item.code]} label={item.name}>
|
|
|
|
<Form.Item name={['info', item.code]} label={item.name}>
|
|
|
|
{item.code === "duration" ? (
|
|
|
|
{renderFormItem(item)}
|
|
|
|
<Input suffix="H" />
|
|
|
|
|
|
|
|
) : (item.code === "display_to_c") ? (
|
|
|
|
|
|
|
|
<Select>
|
|
|
|
|
|
|
|
<Select.Option value="在计划显示,不在报价信显示">在计划显示,不在报价信显示</Select.Option>
|
|
|
|
|
|
|
|
<Select.Option value="计划和报价信都要显示">计划和报价信都要显示</Select.Option>
|
|
|
|
|
|
|
|
<Select.Option value="计划和报价信都不用显示"> 计划和报价信都不用显示</Select.Option>
|
|
|
|
|
|
|
|
</Select>
|
|
|
|
|
|
|
|
) : (item.code === "dept_name") ? (
|
|
|
|
|
|
|
|
<DeptSelector />
|
|
|
|
|
|
|
|
) : (
|
|
|
|
|
|
|
|
<Input />
|
|
|
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
</Form.Item>
|
|
|
|
</Form.Item>
|
|
|
|
</Col>
|
|
|
|
</Col>
|
|
|
|
);
|
|
|
|
);
|
|
|
|
})}
|
|
|
|
})}
|
|
|
|
</Row>
|
|
|
|
</Row>
|
|
|
|
|
|
|
|
|
|
|
|
<Card title={
|
|
|
|
{/* <Card title={ */}
|
|
|
|
<div>
|
|
|
|
<div style={{ marginBottom: "1%", marginLeft: "3%" }}>
|
|
|
|
{tags.map(tag => (
|
|
|
|
{tags.map(tag => (
|
|
|
|
<Tag
|
|
|
|
<Tag
|
|
|
|
key={tag}
|
|
|
|
key={tag}
|
|
|
@ -836,7 +912,7 @@ function Detail() {
|
|
|
|
))}
|
|
|
|
))}
|
|
|
|
<Tag onClick={showModal} style={{ cursor: 'pointer' }}>+</Tag>
|
|
|
|
<Tag onClick={showModal} style={{ cursor: 'pointer' }}>+</Tag>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
}>
|
|
|
|
{/* }> */}
|
|
|
|
<Modal title="选择语言" visible={isModalVisible} onOk={handleOk} onCancel={handleCancel}>
|
|
|
|
<Modal title="选择语言" visible={isModalVisible} onOk={handleOk} onCancel={handleCancel}>
|
|
|
|
<Select
|
|
|
|
<Select
|
|
|
|
showSearch
|
|
|
|
showSearch
|
|
|
@ -863,19 +939,19 @@ function Detail() {
|
|
|
|
onChange={(e) => handleChange('title', e.target.value)}
|
|
|
|
onChange={(e) => handleChange('title', e.target.value)}
|
|
|
|
/>
|
|
|
|
/>
|
|
|
|
</Form.Item>
|
|
|
|
</Form.Item>
|
|
|
|
<Form.Item label={t('products:Description')} name={['lgc_details', 'descriptions']}>
|
|
|
|
<Form.Item label={t('products:Description')} name={['lgc_details', 'description']}>
|
|
|
|
<Input.TextArea
|
|
|
|
<Input.TextArea
|
|
|
|
rows={4}
|
|
|
|
rows={4}
|
|
|
|
onChange={(e) => handleChange('descriptions', e.target.value)}
|
|
|
|
onChange={(e) => handleChange('description', e.target.value)}
|
|
|
|
/>
|
|
|
|
/>
|
|
|
|
</Form.Item>
|
|
|
|
</Form.Item>
|
|
|
|
</Card>
|
|
|
|
{/* </Card> */}
|
|
|
|
{/* </Card> */}
|
|
|
|
{/* </Card> */}
|
|
|
|
|
|
|
|
|
|
|
|
{/* <Card style={{ width: "80%" }}> */}
|
|
|
|
{/* <Card style={{ width: "80%" }}> */}
|
|
|
|
<h2>{t('products:supplierQuotation')}</h2>
|
|
|
|
<h2>{t('products:supplierQuotation')}</h2>
|
|
|
|
<Form.Item name="quotation">
|
|
|
|
<Form.Item name="quotation">
|
|
|
|
<Table rowKey={'id'}
|
|
|
|
<Table rowKey={'tempKey'}
|
|
|
|
bordered
|
|
|
|
bordered
|
|
|
|
dataSource={quotation}
|
|
|
|
dataSource={quotation}
|
|
|
|
columns={columns}
|
|
|
|
columns={columns}
|
|
|
@ -906,7 +982,7 @@ function Detail() {
|
|
|
|
</Row>
|
|
|
|
</Row>
|
|
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
{
|
|
|
|
batchImportPriceVisible && (
|
|
|
|
(
|
|
|
|
<Modal
|
|
|
|
<Modal
|
|
|
|
title="批量添加价格"
|
|
|
|
title="批量添加价格"
|
|
|
|
visible={batchImportPriceVisible}
|
|
|
|
visible={batchImportPriceVisible}
|
|
|
@ -920,7 +996,7 @@ function Detail() {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
{
|
|
|
|
addProductVisible && (
|
|
|
|
(
|
|
|
|
<Modal
|
|
|
|
<Modal
|
|
|
|
title="增加新产品"
|
|
|
|
title="增加新产品"
|
|
|
|
visible={addProductVisible}
|
|
|
|
visible={addProductVisible}
|
|
|
@ -950,7 +1026,7 @@ function Detail() {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
{
|
|
|
|
quotationTableVisible && (
|
|
|
|
(
|
|
|
|
<Modal
|
|
|
|
<Modal
|
|
|
|
title="编辑供应商报价"
|
|
|
|
title="编辑供应商报价"
|
|
|
|
visible={quotationTableVisible}
|
|
|
|
visible={quotationTableVisible}
|
|
|
@ -958,32 +1034,32 @@ function Detail() {
|
|
|
|
onCancel={quotationTableVisibleCancel}
|
|
|
|
onCancel={quotationTableVisibleCancel}
|
|
|
|
>
|
|
|
|
>
|
|
|
|
<h3>成人价</h3>
|
|
|
|
<h3>成人价</h3>
|
|
|
|
<InputNumber defaultValue={currentQuotationRecord.adult_cost} onChange={(e) => setCurrentQuotationRecord({ ...currentQuotationRecord, adult_cost: e })} />
|
|
|
|
<InputNumber value={currentQuotationRecord.adult_cost} onChange={(e) => setCurrentQuotationRecord({ ...currentQuotationRecord, adult_cost: e })} />
|
|
|
|
<h3>儿童价</h3>
|
|
|
|
<h3>儿童价</h3>
|
|
|
|
<InputNumber defaultValue={currentQuotationRecord.child_cost} onChange={(e) => setCurrentQuotationRecord({ ...currentQuotationRecord, child_cost: e })} />
|
|
|
|
<InputNumber value={currentQuotationRecord.child_cost} onChange={(e) => setCurrentQuotationRecord({ ...currentQuotationRecord, child_cost: e })} />
|
|
|
|
<h3>币种</h3>
|
|
|
|
<h3>币种</h3>
|
|
|
|
<Select style={{ width: "30%" }} defaultValue={currentQuotationRecord.currency} onChange={(e) => setCurrentQuotationRecord({ ...currentQuotationRecord, currency: e })}>
|
|
|
|
<Select style={{ width: "30%" }} value={currentQuotationRecord.currency} onChange={(e) => setCurrentQuotationRecord({ ...currentQuotationRecord, currency: e })}>
|
|
|
|
<Select.Option value="RMB">RMB</Select.Option>
|
|
|
|
<Select.Option value="rmb">rmb</Select.Option>
|
|
|
|
<Select.Option value="USD">USD</Select.Option>
|
|
|
|
<Select.Option value="usd">usd</Select.Option>
|
|
|
|
</Select >
|
|
|
|
</Select >
|
|
|
|
<h3>类型</h3>
|
|
|
|
<h3>类型</h3>
|
|
|
|
<Select style={{ width: "30%" }} defaultValue={currentQuotationRecord.unit_name} onChange={(e) => setCurrentQuotationRecord({ ...currentQuotationRecord, unit_name: e })}>
|
|
|
|
<Select style={{ width: "30%" }} value={currentQuotationRecord.unit} onChange={(e) => setCurrentQuotationRecord({ ...currentQuotationRecord, unit: e })}>
|
|
|
|
<Select.Option value="每人">每人</Select.Option>
|
|
|
|
<Select.Option value="0">每人</Select.Option>
|
|
|
|
<Select.Option value="每团">每团</Select.Option>
|
|
|
|
<Select.Option value="1">每团</Select.Option>
|
|
|
|
</Select>
|
|
|
|
</Select>
|
|
|
|
|
|
|
|
|
|
|
|
<h3>人等</h3>
|
|
|
|
<h3>人等</h3>
|
|
|
|
<td style={{ display: 'flex', alignItems: 'center' }}>
|
|
|
|
<td style={{ display: 'flex', alignItems: 'center' }}>
|
|
|
|
<InputNumber
|
|
|
|
<InputNumber
|
|
|
|
min={0}
|
|
|
|
min={0}
|
|
|
|
defaultValue={currentQuotationRecord.group_size_min}
|
|
|
|
value={currentQuotationRecord.group_size_min}
|
|
|
|
onChange={(e) => setCurrentQuotationRecord({ ...currentQuotationRecord, group_size_min: e })}
|
|
|
|
onChange={(e) => setCurrentQuotationRecord({ ...currentQuotationRecord, group_size_min: e })}
|
|
|
|
style={{ width: '50%', marginRight: '10px' }}
|
|
|
|
style={{ width: '50%', marginRight: '10px' }}
|
|
|
|
/>
|
|
|
|
/>
|
|
|
|
<span>-</span>
|
|
|
|
<span>-</span>
|
|
|
|
<InputNumber
|
|
|
|
<InputNumber
|
|
|
|
min={0}
|
|
|
|
min={0}
|
|
|
|
defaultValue={currentQuotationRecord.group_size_max}
|
|
|
|
value={currentQuotationRecord.group_size_max}
|
|
|
|
onChange={(e) => setCurrentQuotationRecord({ ...currentQuotationRecord, group_size_max: e })}
|
|
|
|
onChange={(e) => setCurrentQuotationRecord({ ...currentQuotationRecord, group_size_max: e })}
|
|
|
|
style={{ width: '50%', marginLeft: '10px' }}
|
|
|
|
style={{ width: '50%', marginLeft: '10px' }}
|
|
|
|
/>
|
|
|
|
/>
|
|
|
@ -994,7 +1070,7 @@ function Detail() {
|
|
|
|
inputReadOnly={true}
|
|
|
|
inputReadOnly={true}
|
|
|
|
presets={presets}
|
|
|
|
presets={presets}
|
|
|
|
placeholder={['From', 'Thru']}
|
|
|
|
placeholder={['From', 'Thru']}
|
|
|
|
defaultValue={startDate && endDate ? [startDate, endDate] : null}
|
|
|
|
value={startDate && endDate ? [startDate, endDate] : null}
|
|
|
|
onChange={(dates) => {
|
|
|
|
onChange={(dates) => {
|
|
|
|
setCurrentQuotationRecord({
|
|
|
|
setCurrentQuotationRecord({
|
|
|
|
...currentQuotationRecord,
|
|
|
|
...currentQuotationRecord,
|
|
|
@ -1020,6 +1096,7 @@ function Detail() {
|
|
|
|
)
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
</Spin>
|
|
|
|
);
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
export default Detail;
|
|
|
|
export default Detail;
|
|
|
|