|
|
@ -1,9 +1,9 @@
|
|
|
|
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 } from 'antd';
|
|
|
|
import { Button, Card, Col, Row, Breadcrumb, Table, Popconfirm, Form, Input, InputNumber, Tag, Modal, Select, Tree, FloatButton, DatePicker } 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 AddValidityWithWeekend from '@/views/products/Detail/addValidityWithWeekend';
|
|
|
|
import AddValidityWithWeekend from '@/views/products/Detail/addValidityWithWeekend';
|
|
|
|
import { searchAgencyAction, getAgencyProductsAction } from '@/stores/Products/Index';
|
|
|
|
import { getAgencyProductsAction } from '@/stores/Products/Index';
|
|
|
|
import { useProductsTypes } from '@/hooks/useProductsSets';
|
|
|
|
import { useProductsTypes } from '@/hooks/useProductsSets';
|
|
|
|
import Extras from './Detail/Extras';
|
|
|
|
import Extras from './Detail/Extras';
|
|
|
|
import { groupBy } from '@/utils/commons';
|
|
|
|
import { groupBy } from '@/utils/commons';
|
|
|
@ -12,9 +12,16 @@ import useProductsStore from '@/stores/Products/Index';
|
|
|
|
import { useHTLanguageSets } from '@/hooks/useHTLanguageSets';
|
|
|
|
import { useHTLanguageSets } from '@/hooks/useHTLanguageSets';
|
|
|
|
import { useDefaultLgc } from '@/i18n/LanguageSwitcher';
|
|
|
|
import { useDefaultLgc } from '@/i18n/LanguageSwitcher';
|
|
|
|
import BatchImportPrice from './Detail/BatchImportPrice1';
|
|
|
|
import BatchImportPrice from './Detail/BatchImportPrice1';
|
|
|
|
|
|
|
|
import dayjs from 'dayjs';
|
|
|
|
|
|
|
|
import { PlusCircleFilled } from '@ant-design/icons';
|
|
|
|
|
|
|
|
import { info } from 'autoprefixer';
|
|
|
|
|
|
|
|
import { DeptSelector } from '@/components/DeptSelector';
|
|
|
|
|
|
|
|
import { useDatePresets } from '@/hooks/useDatePresets';
|
|
|
|
|
|
|
|
|
|
|
|
function Detail() {
|
|
|
|
function Detail() {
|
|
|
|
const { t } = useTranslation();
|
|
|
|
const { t } = useTranslation();
|
|
|
|
const [form] = Form.useForm();
|
|
|
|
const [form] = Form.useForm();
|
|
|
|
|
|
|
|
const { RangePicker } = DatePicker;
|
|
|
|
const [editingid, setEditingid] = useState('');
|
|
|
|
const [editingid, setEditingid] = useState('');
|
|
|
|
const [tags, setTags] = useState([]);
|
|
|
|
const [tags, setTags] = useState([]);
|
|
|
|
const [isModalVisible, setIsModalVisible] = useState(false);
|
|
|
|
const [isModalVisible, setIsModalVisible] = useState(false);
|
|
|
@ -22,6 +29,7 @@ function Detail() {
|
|
|
|
const [saveData, setSaveData] = useState(null);
|
|
|
|
const [saveData, setSaveData] = useState(null);
|
|
|
|
const [datePickerVisible, setDatePickerVisible] = useState(false);
|
|
|
|
const [datePickerVisible, setDatePickerVisible] = useState(false);
|
|
|
|
const [batchImportPriceVisible, setBatchImportPriceVisible] = useState(false);
|
|
|
|
const [batchImportPriceVisible, setBatchImportPriceVisible] = useState(false);
|
|
|
|
|
|
|
|
const [quotationTableVisible, setQuotationTableVisible] = useState(false)
|
|
|
|
const [currentid, setCurrentid] = useState(null);
|
|
|
|
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);
|
|
|
@ -33,25 +41,40 @@ function Detail() {
|
|
|
|
const [quotation, setQuotation] = useState(null);
|
|
|
|
const [quotation, setQuotation] = useState(null);
|
|
|
|
const [lgc_details, setLgc_details] = useState(null);
|
|
|
|
const [lgc_details, setLgc_details] = useState(null);
|
|
|
|
const [languageLabel, setLanguageLabel] = useState(null);
|
|
|
|
const [languageLabel, setLanguageLabel] = useState(null);
|
|
|
|
|
|
|
|
const [infoDataForId, setInfoDataForId] = useState(null);
|
|
|
|
const { travel_agency_id } = useParams();
|
|
|
|
const { travel_agency_id } = useParams();
|
|
|
|
const { language } = useDefaultLgc();
|
|
|
|
const { language } = useDefaultLgc();
|
|
|
|
const HTLanguageSets = useHTLanguageSets();
|
|
|
|
const HTLanguageSets = useHTLanguageSets();
|
|
|
|
const { Search } = Input;
|
|
|
|
const { Search } = Input;
|
|
|
|
|
|
|
|
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 { getAgencyProducts } = 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);
|
|
|
|
const [dataList, setDataList] = useState([]);
|
|
|
|
const [dataList, setDataList] = useState([]);
|
|
|
|
const [defaultData, setDefaultData] = useState([]);
|
|
|
|
const [defaultData, setDefaultData] = useState([]);
|
|
|
|
const [batchImportData, setBatchImportData] = useState([]);
|
|
|
|
const [batchImportData, setBatchImportData] = useState([]);
|
|
|
|
|
|
|
|
const [addProductType, setAddProductType] = useState('');
|
|
|
|
|
|
|
|
const [addproductName, setAddProductName] = useState('');
|
|
|
|
|
|
|
|
const [dataFetched, setDataFetched] = useState(false); // 添加一个标志位
|
|
|
|
|
|
|
|
const [selectedNodeKey, setSelectedNodeKey] = useState(null);
|
|
|
|
|
|
|
|
const [selectedDays, setSelectedDays] = useState([]);
|
|
|
|
|
|
|
|
const [currentQuotationRecord, setCurrentQuotationRecord] = useState(null);
|
|
|
|
|
|
|
|
const presets = useDatePresets();
|
|
|
|
const handleBatchImportData = (data) => {
|
|
|
|
const handleBatchImportData = (data) => {
|
|
|
|
setBatchImportData(data);
|
|
|
|
setBatchImportData(data);
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
const days = [
|
|
|
|
|
|
|
|
'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'
|
|
|
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
|
|
const productProject = {
|
|
|
|
const productProject = {
|
|
|
|
"6": [],
|
|
|
|
"6": [
|
|
|
|
|
|
|
|
{ code: "code", name: t('products:Code'), nameKey: 'products:Code' },
|
|
|
|
|
|
|
|
{ code: "city_name", name: t('products:City'), nameKey: 'products:City' },
|
|
|
|
|
|
|
|
],
|
|
|
|
"B": [
|
|
|
|
"B": [
|
|
|
|
{ code: "code", name: t('products:Code'), nameKey: 'products:Code' },
|
|
|
|
{ code: "code", name: t('products:Code'), nameKey: 'products:Code' },
|
|
|
|
{ code: "city_name", name: t('products:City'), nameKey: 'products:City' },
|
|
|
|
{ code: "city_name", name: t('products:City'), nameKey: 'products:City' },
|
|
|
@ -110,42 +133,45 @@ function Detail() {
|
|
|
|
const languageLabel = matchedLanguage.label
|
|
|
|
const languageLabel = matchedLanguage.label
|
|
|
|
setLanguageLabel(languageLabel)
|
|
|
|
setLanguageLabel(languageLabel)
|
|
|
|
setSelectedTag(languageLabel)
|
|
|
|
setSelectedTag(languageLabel)
|
|
|
|
setRemainderLanguage(HTLanguageSets.filter(item => item.key !== language.toString()))
|
|
|
|
// setRemainderLanguage(HTLanguageSets.filter(item => item.key !== language.toString()))
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
useEffect(() => {
|
|
|
|
const fetchData = async () => {
|
|
|
|
const fetchData = async () => {
|
|
|
|
const a = { travel_agency_id };
|
|
|
|
if (productsTypes && !dataFetched) {
|
|
|
|
const res = await getAgencyProductsAction(a);
|
|
|
|
const agency_id = { travel_agency_id };
|
|
|
|
const groupedProducts = groupBy(res.products, (row) => row.info.product_type_id);
|
|
|
|
await getAgencyProducts(agency_id);
|
|
|
|
|
|
|
|
console.log("agencyProducts", agencyProducts)
|
|
|
|
const generateTreeData = (productsTypes, productsData) => {
|
|
|
|
console.log("productsTypes", productsTypes)
|
|
|
|
return productsTypes.map(type => ({
|
|
|
|
const generateTreeData = (productsTypes, productsData) => {
|
|
|
|
title: type.label,
|
|
|
|
return productsTypes.map(type => ({
|
|
|
|
key: type.value,
|
|
|
|
title: type.label,
|
|
|
|
selectable: false,
|
|
|
|
key: type.value,
|
|
|
|
children: (productsData[type.value] || []).map(product => ({
|
|
|
|
selectable: false,
|
|
|
|
title: product.info.title,
|
|
|
|
children: (productsData[type.value] || []).map(product => ({
|
|
|
|
key: `${type.value}-${product.info.id}`,
|
|
|
|
title: product.info.title,
|
|
|
|
_raw: product,
|
|
|
|
key: `${type.value}-${product.info.id}`,
|
|
|
|
}))
|
|
|
|
_raw: product,
|
|
|
|
}));
|
|
|
|
}))
|
|
|
|
};
|
|
|
|
}));
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const treeData = generateTreeData(productsTypes, groupedProducts);
|
|
|
|
const treeData = generateTreeData(productsTypes, agencyProducts);
|
|
|
|
console.log("treeData", treeData)
|
|
|
|
console.log("treeData", treeData)
|
|
|
|
setTreeData(treeData);
|
|
|
|
setDataFetched(true); // 设置标志位为 true,表示数据已获取
|
|
|
|
setProductsData(groupedProducts);
|
|
|
|
setTreeData(treeData);
|
|
|
|
setDefaultData(treeData);
|
|
|
|
setProductsData(agencyProducts);
|
|
|
|
setDataList(flattenTreeData(treeData));
|
|
|
|
setDefaultData(treeData);
|
|
|
|
|
|
|
|
setDataList(flattenTreeData(treeData));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
fetchData();
|
|
|
|
fetchData();
|
|
|
|
}, [productsTypes]);
|
|
|
|
}, [agencyProducts, dataFetched]);
|
|
|
|
|
|
|
|
|
|
|
|
const flattenTreeData = (tree) => {
|
|
|
|
const flattenTreeData = (tree) => {
|
|
|
|
let flatList = [];
|
|
|
|
let flatList = [];
|
|
|
@ -218,6 +244,9 @@ function Detail() {
|
|
|
|
const isEditing = (record) => record.id === editingid;
|
|
|
|
const isEditing = (record) => record.id === editingid;
|
|
|
|
|
|
|
|
|
|
|
|
const edit = (record) => {
|
|
|
|
const edit = (record) => {
|
|
|
|
|
|
|
|
// setQuotationTableVisible(true);
|
|
|
|
|
|
|
|
// setCurrentQuotationRecord(record);
|
|
|
|
|
|
|
|
console.log("record", record)
|
|
|
|
form.setFieldsValue({ ...record });
|
|
|
|
form.setFieldsValue({ ...record });
|
|
|
|
setEditingid(record.id);
|
|
|
|
setEditingid(record.id);
|
|
|
|
};
|
|
|
|
};
|
|
|
@ -237,7 +266,17 @@ function Detail() {
|
|
|
|
delete newData[index].quotation
|
|
|
|
delete newData[index].quotation
|
|
|
|
delete newData[index].extras
|
|
|
|
delete newData[index].extras
|
|
|
|
console.log("newData", newData)
|
|
|
|
console.log("newData", newData)
|
|
|
|
setQuotation(newData);
|
|
|
|
|
|
|
|
|
|
|
|
//按人等范围排序
|
|
|
|
|
|
|
|
const sortedData = [...newData].sort((a, b) => {
|
|
|
|
|
|
|
|
// 首先按照 group_size_min 升序排序
|
|
|
|
|
|
|
|
if (a.group_size_min !== b.group_size_min) {
|
|
|
|
|
|
|
|
return a.group_size_min - b.group_size_min;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
// 如果 group_size_min 相同,则按照 group_size_max 升序排序
|
|
|
|
|
|
|
|
return a.group_size_max - b.group_size_max;
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
setQuotation(sortedData);
|
|
|
|
setEditingid('');
|
|
|
|
setEditingid('');
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
newData.push(restRow);
|
|
|
|
newData.push(restRow);
|
|
|
@ -253,12 +292,23 @@ function Detail() {
|
|
|
|
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);
|
|
|
|
setQuotation(newData);
|
|
|
|
|
|
|
|
|
|
|
|
//按人等范围排序
|
|
|
|
|
|
|
|
const sortedData = [...newData].sort((a, b) => {
|
|
|
|
|
|
|
|
// 首先按照 group_size_min 升序排序
|
|
|
|
|
|
|
|
if (a.group_size_min !== b.group_size_min) {
|
|
|
|
|
|
|
|
return a.group_size_min - b.group_size_min;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
// 如果 group_size_min 相同,则按照 group_size_max 升序排序
|
|
|
|
|
|
|
|
return a.group_size_max - b.group_size_max;
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
setQuotation(sortedData);
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const handleAdd = () => {
|
|
|
|
const handleAdd = () => {
|
|
|
|
const newData = {
|
|
|
|
const newData = {
|
|
|
|
id: `${quotation.length + 1}`,
|
|
|
|
// id: `${quotation.length + 1}`,
|
|
|
|
value: '',
|
|
|
|
value: '',
|
|
|
|
currency: '',
|
|
|
|
currency: '',
|
|
|
|
unit_name: '',
|
|
|
|
unit_name: '',
|
|
|
@ -280,8 +330,18 @@ function Detail() {
|
|
|
|
setDatePickerVisible(true);
|
|
|
|
setDatePickerVisible(true);
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const quotationTableVisibleOK = () => {
|
|
|
|
|
|
|
|
setQuotationTableVisible(false);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
const quotationTableVisibleCancel = () => {
|
|
|
|
|
|
|
|
setQuotationTableVisible(false);
|
|
|
|
|
|
|
|
}
|
|
|
|
const handleDateChange = ({ dateRange, selectedDays }) => {
|
|
|
|
const handleDateChange = ({ dateRange, selectedDays }) => {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
console.log("dateRange", dateRange)
|
|
|
|
|
|
|
|
console.log("selectedDays", selectedDays)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 计算周末
|
|
|
|
// 计算周末
|
|
|
|
const weekdays = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'];
|
|
|
|
const weekdays = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'];
|
|
|
|
let weekDayCount = selectedDays.map(day => weekdays.indexOf(day) + 1).sort().join(',');
|
|
|
|
let weekDayCount = selectedDays.map(day => weekdays.indexOf(day) + 1).sort().join(',');
|
|
|
@ -299,20 +359,22 @@ function Detail() {
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const handleDateOk = () => {
|
|
|
|
const handleDateOk = () => {
|
|
|
|
const { dateRange } = selectedDateData;
|
|
|
|
let { dateRange } = selectedDateData;
|
|
|
|
const dateRangeList = dateRange.split('-');
|
|
|
|
console.log("handleDateOk_dateRange", dateRange)
|
|
|
|
const use_dates_start = dateRangeList[0];
|
|
|
|
const use_dates_start = dateRange[0];
|
|
|
|
const use_dates_end = dateRangeList[1];
|
|
|
|
const use_dates_end = dateRange[1];
|
|
|
|
if (currentid !== null) {
|
|
|
|
if (currentid !== null) {
|
|
|
|
const newData = [...quotation];
|
|
|
|
const newData = [...quotation];
|
|
|
|
const index = newData.findIndex((item) => currentid === item.id);
|
|
|
|
const index = newData.findIndex((item) => currentid === item.id);
|
|
|
|
if (index > -1) {
|
|
|
|
if (index > -1) {
|
|
|
|
newData[index].use_dates_start = use_dates_start;
|
|
|
|
newData[index].use_dates_start = use_dates_start;
|
|
|
|
newData[index].use_dates_end = use_dates_end;
|
|
|
|
newData[index].use_dates_end = use_dates_end;
|
|
|
|
|
|
|
|
console.log("newData", newData)
|
|
|
|
setQuotation(newData);
|
|
|
|
setQuotation(newData);
|
|
|
|
setCurrentid(null);
|
|
|
|
setCurrentid(null);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
setSelectedDateData({ dateRange: null, selectedDays: [] })
|
|
|
|
setDatePickerVisible(false);
|
|
|
|
setDatePickerVisible(false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -329,8 +391,18 @@ function Detail() {
|
|
|
|
// 将剩余的属性添加到 quotation 中
|
|
|
|
// 将剩余的属性添加到 quotation 中
|
|
|
|
const newData = [...quotation, ...tempBatchImportData];
|
|
|
|
const newData = [...quotation, ...tempBatchImportData];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//按人等范围排序
|
|
|
|
|
|
|
|
const sortedData = [...newData].sort((a, b) => {
|
|
|
|
|
|
|
|
// 首先按照 group_size_min 升序排序
|
|
|
|
|
|
|
|
if (a.group_size_min !== b.group_size_min) {
|
|
|
|
|
|
|
|
return a.group_size_min - b.group_size_min;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
// 如果 group_size_min 相同,则按照 group_size_max 升序排序
|
|
|
|
|
|
|
|
return a.group_size_max - b.group_size_max;
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
// 更新状态来更新页面
|
|
|
|
// 更新状态来更新页面
|
|
|
|
setQuotation(newData);
|
|
|
|
setQuotation(sortedData);
|
|
|
|
setBatchImportPriceVisible(false);
|
|
|
|
setBatchImportPriceVisible(false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -358,8 +430,8 @@ function Detail() {
|
|
|
|
if (dataIndex === 'currency' && editing) {
|
|
|
|
if (dataIndex === 'currency' && editing) {
|
|
|
|
inputNode = (
|
|
|
|
inputNode = (
|
|
|
|
<Select>
|
|
|
|
<Select>
|
|
|
|
<Select.Option value="每人">RMB</Select.Option>
|
|
|
|
<Select.Option value="CNY">CNY</Select.Option>
|
|
|
|
<Select.Option value="每团">MY</Select.Option>
|
|
|
|
<Select.Option value="USD">USD</Select.Option>
|
|
|
|
</Select>
|
|
|
|
</Select>
|
|
|
|
);
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -448,10 +520,8 @@ function Detail() {
|
|
|
|
const editable = isEditing(record);
|
|
|
|
const editable = isEditing(record);
|
|
|
|
return editable ? (
|
|
|
|
return editable ? (
|
|
|
|
<span>
|
|
|
|
<span>
|
|
|
|
{/* <a href="#!" onClick={() => handleSave(record.id)} style={{ marginRight: 8 }}>{t('Save')}</a> */}
|
|
|
|
|
|
|
|
<Button type="link" onClick={() => handleSave(record.id)}>{t('Save')}</Button>
|
|
|
|
<Button type="link" onClick={() => handleSave(record.id)}>{t('Save')}</Button>
|
|
|
|
<Button type="link" onClick={cancel}>{t('Cancel')}</Button>
|
|
|
|
<Button type="link" onClick={cancel}>{t('Cancel')}</Button>
|
|
|
|
{/* <Popconfirm title={t('sureCancel')} onConfirm={cancel}><a>{t('Cancel')}</a></Popconfirm> */}
|
|
|
|
|
|
|
|
</span>
|
|
|
|
</span>
|
|
|
|
) : (
|
|
|
|
) : (
|
|
|
|
<span>
|
|
|
|
<span>
|
|
|
@ -507,17 +577,20 @@ function Detail() {
|
|
|
|
let tempRemainderLanguage = remainderLanguage.filter((item) => {
|
|
|
|
let tempRemainderLanguage = remainderLanguage.filter((item) => {
|
|
|
|
return item.label !== selectedTag;
|
|
|
|
return item.label !== selectedTag;
|
|
|
|
})
|
|
|
|
})
|
|
|
|
console.log("AAAA", lgc_details)
|
|
|
|
|
|
|
|
console.log("selectTag", selectedTag)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const matchedLanguage = HTLanguageSets.find(HTLanguage => HTLanguage.label === selectedTag);
|
|
|
|
const matchedLanguage = HTLanguageSets.find(HTLanguage => HTLanguage.label === selectedTag);
|
|
|
|
const languageKey = matchedLanguage.key
|
|
|
|
const languageKey = parseInt(matchedLanguage.key)
|
|
|
|
const tempLgc_details = {
|
|
|
|
if (!(languageKey in lgc_details)) {
|
|
|
|
...lgc_details, [languageKey]: {
|
|
|
|
const tempLgc_details = {
|
|
|
|
title: {},
|
|
|
|
...lgc_details, [languageKey]: {
|
|
|
|
|
|
|
|
title: "",
|
|
|
|
|
|
|
|
lgc: languageKey,
|
|
|
|
|
|
|
|
descriptions: ""
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
setLgc_details(tempLgc_details)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
console.log("languageKey", languageKey)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
setRemainderLanguage(tempRemainderLanguage)
|
|
|
|
setRemainderLanguage(tempRemainderLanguage)
|
|
|
|
setTags([...tags, selectedTag])
|
|
|
|
setTags([...tags, selectedTag])
|
|
|
@ -532,37 +605,78 @@ function Detail() {
|
|
|
|
const handleTagChange = (value) => {
|
|
|
|
const handleTagChange = (value) => {
|
|
|
|
console.log("handleTagChange", value)
|
|
|
|
console.log("handleTagChange", value)
|
|
|
|
setSelectedTag(value);
|
|
|
|
setSelectedTag(value);
|
|
|
|
console.log("setSelectedTag", selectedTag)
|
|
|
|
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const handleChange = (field, value) => {
|
|
|
|
const handleChange = (field, value) => {
|
|
|
|
console.log("languageStatus", languageStatus)
|
|
|
|
|
|
|
|
console.log("...lgc_details[languageStatus]", { ...lgc_details[languageStatus] })
|
|
|
|
|
|
|
|
// 更新整个 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 }
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
console.log("updatedLgcDetails", updatedLgcDetails)
|
|
|
|
setLgc_details(updatedLgcDetails)
|
|
|
|
setLgc_details(updatedLgcDetails)
|
|
|
|
console.log("AAAAAAAAAAAAAA", lgc_details);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const handleDayClick = (day) => {
|
|
|
|
|
|
|
|
setSelectedDays((prevSelectedDays) => {
|
|
|
|
|
|
|
|
const updatedDays = prevSelectedDays.includes(day)
|
|
|
|
|
|
|
|
? prevSelectedDays.filter((d) => d !== day)
|
|
|
|
|
|
|
|
: [...prevSelectedDays, day];
|
|
|
|
|
|
|
|
return updatedDays;
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
//树组件方法
|
|
|
|
//树组件方法
|
|
|
|
const handleNodeSelect = (_, { node }) => {
|
|
|
|
const handleNodeSelect = (_, { node }) => {
|
|
|
|
|
|
|
|
if (!node._raw.info.id) {
|
|
|
|
|
|
|
|
console.log("nodeNoID", node)
|
|
|
|
|
|
|
|
const infoData = node._raw.info
|
|
|
|
|
|
|
|
const newLgcDetails = node._raw.lgc_details
|
|
|
|
|
|
|
|
const fatherKey = node.key.split('-')[0];
|
|
|
|
|
|
|
|
setSelectedNodeid(node.key);
|
|
|
|
|
|
|
|
setSelectedNodeKey(fatherKey);
|
|
|
|
|
|
|
|
form.setFieldsValue({
|
|
|
|
|
|
|
|
info: {
|
|
|
|
|
|
|
|
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: language,
|
|
|
|
|
|
|
|
title: newLgcDetails[language]?.title || '',
|
|
|
|
|
|
|
|
descriptions: newLgcDetails[language]?.descriptions || ''
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
setTags([languageLabel])
|
|
|
|
setTags([languageLabel])
|
|
|
|
// 如果点击的是同一个节点,不做任何操作
|
|
|
|
// 如果点击的是同一个节点,不做任何操作
|
|
|
|
if (selectedNodeid === node.key) return;
|
|
|
|
if (selectedNodeid === node.key) return;
|
|
|
|
const fatherKey = node.key.split('-')[0];
|
|
|
|
|
|
|
|
setSelectedCategory(productProject[fatherKey])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
setLanguageStatus(language);
|
|
|
|
const matchedLanguage = HTLanguageSets.find(HTLanguage => HTLanguage.key === language.toString());
|
|
|
|
const matchedLanguage = HTLanguageSets.find(HTLanguage => HTLanguage.key === language.toString());
|
|
|
|
const languageLabelRefresh = matchedLanguage.label
|
|
|
|
const languageLabelRefresh = matchedLanguage.label;
|
|
|
|
setLanguageLabel(languageLabelRefresh)
|
|
|
|
setLanguageLabel(languageLabelRefresh);
|
|
|
|
setSelectedTag(languageLabelRefresh)
|
|
|
|
setSelectedTag(languageLabelRefresh);
|
|
|
|
setRemainderLanguage(HTLanguageSets.filter(item => item.key !== language.toString()))
|
|
|
|
setRemainderLanguage(HTLanguageSets.filter(item => item.key !== language.toString()));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
setEditingProduct(node._raw);
|
|
|
|
setEditingProduct(node._raw);
|
|
|
@ -570,55 +684,186 @@ function Detail() {
|
|
|
|
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.title === node.title) {
|
|
|
|
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;
|
|
|
|
return true;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
console.log("infoData", infoData)
|
|
|
|
if (!node._raw.info.id) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
console.log("lgcDetailsData", lgcDetailsData)
|
|
|
|
// 累积 lgc_details 数据
|
|
|
|
// 累积 lgc_details 数据
|
|
|
|
let newLgcDetails = {};
|
|
|
|
let newLgcDetails = {};
|
|
|
|
lgcDetailsData.forEach(element => {
|
|
|
|
if (lgcDetailsData) {
|
|
|
|
newLgcDetails[element.lgc] = element;
|
|
|
|
lgcDetailsData.forEach(element => {
|
|
|
|
});
|
|
|
|
newLgcDetails[element.lgc] = element;
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
console.log("infoData", infoData)
|
|
|
|
|
|
|
|
console.log("laug", language)
|
|
|
|
|
|
|
|
|
|
|
|
// 一次性更新 lgc_details
|
|
|
|
if (node._raw.info.id) {
|
|
|
|
|
|
|
|
setInfoDataForId(infoData.id)
|
|
|
|
|
|
|
|
}
|
|
|
|
setLgc_details(newLgcDetails);
|
|
|
|
setLgc_details(newLgcDetails);
|
|
|
|
|
|
|
|
|
|
|
|
setQuotation(initialQuotationData);
|
|
|
|
setQuotation(initialQuotationData);
|
|
|
|
|
|
|
|
|
|
|
|
// 使用 setTimeout 确保 lgc_details 已经更新
|
|
|
|
// 使用 setTimeout 确保 lgc_details 已经更新
|
|
|
|
form.setFieldsValue({
|
|
|
|
if (node._raw.info.id) {
|
|
|
|
|
|
|
|
form.setFieldsValue({
|
|
|
|
|
|
|
|
info: {
|
|
|
|
|
|
|
|
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: language,
|
|
|
|
|
|
|
|
title: newLgcDetails[language]?.title || '',
|
|
|
|
|
|
|
|
descriptions: newLgcDetails[language]?.descriptions || ''
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const handelAddProduct = () => {
|
|
|
|
|
|
|
|
// 找到对应的产品类型节点
|
|
|
|
|
|
|
|
const productTypeNode = treeData.find(item => item.key === addProductType);
|
|
|
|
|
|
|
|
console.log("productTypeNode", productTypeNode);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (productTypeNode) {
|
|
|
|
|
|
|
|
// 在 children 数组中插入新的产品节点
|
|
|
|
|
|
|
|
const newChildren = [
|
|
|
|
|
|
|
|
...productTypeNode.children,
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
title: addproductName,
|
|
|
|
|
|
|
|
key: `${addProductType}-${Date.now()}`, // 使用时间戳作为唯一的 key
|
|
|
|
|
|
|
|
_raw: {
|
|
|
|
|
|
|
|
info: { code: '' },
|
|
|
|
|
|
|
|
lgc_details: [],
|
|
|
|
|
|
|
|
quotation: []
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
];
|
|
|
|
|
|
|
|
// 创建新的 treeData 数组,确保 React 能够检测到更改
|
|
|
|
|
|
|
|
const newTreeData = treeData.map(item => {
|
|
|
|
|
|
|
|
if (item.key === addProductType) {
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
|
|
|
...item,
|
|
|
|
|
|
|
|
children: newChildren,
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return item;
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
// 更新 treeData
|
|
|
|
|
|
|
|
setEditingProduct(null)
|
|
|
|
|
|
|
|
setTreeData(newTreeData);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
console.log("productData", productsData)
|
|
|
|
|
|
|
|
console.log("addProductType", addProductType)
|
|
|
|
|
|
|
|
let tempProductDataList = productsData[addProductType];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//初始化产品数据
|
|
|
|
|
|
|
|
const newProduct = {
|
|
|
|
info: {
|
|
|
|
info: {
|
|
|
|
title: infoData.title,
|
|
|
|
code: 'addProduct'
|
|
|
|
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: {
|
|
|
|
quotation: [],
|
|
|
|
lgc: language,
|
|
|
|
lgc_details: []
|
|
|
|
title: newLgcDetails[language]?.title || '',
|
|
|
|
}
|
|
|
|
descriptions: newLgcDetails[language]?.descriptions || ''
|
|
|
|
tempProductDataList.push(newProduct);
|
|
|
|
}
|
|
|
|
console.log("tempProductDataList", tempProductDataList)
|
|
|
|
});
|
|
|
|
const newProductsData = {
|
|
|
|
|
|
|
|
...productsData, // 假设使用了展开运算符来复制现有数组
|
|
|
|
|
|
|
|
[addProductType]: tempProductDataList
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
setProductsData(newProductsData);
|
|
|
|
|
|
|
|
console.log("newProductsData", newProductsData)
|
|
|
|
|
|
|
|
setAddProductVisible(false);
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const onSave = (values) => {
|
|
|
|
const onSave = (values) => {
|
|
|
|
const tempData = values;
|
|
|
|
// 找到匹配的树节点
|
|
|
|
tempData['quotation'] = quotation;
|
|
|
|
let matchedTreeData = treeData.find(treeKey => treeKey.key === selectedNodeKey);
|
|
|
|
setSaveData(tempData);
|
|
|
|
if (matchedTreeData) {
|
|
|
|
console.log("保存的数据", tempData)
|
|
|
|
// 找到匹配的子节点
|
|
|
|
|
|
|
|
const matchedTreeDataChildren = matchedTreeData.children;
|
|
|
|
|
|
|
|
// 检查是否已存在具有 selectedNodeid 的子节点
|
|
|
|
|
|
|
|
console.log("matchedTreeDataChildren", matchedTreeDataChildren)
|
|
|
|
|
|
|
|
console.log("selectedNodeid", selectedNodeid)
|
|
|
|
|
|
|
|
// 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;
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// } else {
|
|
|
|
|
|
|
|
// console.log("No matching child node found.");
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
console.log("No matching tree node found.");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// if (infoDataForId) {
|
|
|
|
|
|
|
|
// // 创建新的 tempData 对象
|
|
|
|
|
|
|
|
// const tempData = {
|
|
|
|
|
|
|
|
// ...values,
|
|
|
|
|
|
|
|
// info: { ...values.info, id: infoDataForId },
|
|
|
|
|
|
|
|
// quotation: quotation,
|
|
|
|
|
|
|
|
// lgc_details: Object.values(lgc_details)
|
|
|
|
|
|
|
|
// };
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// setSaveData(tempData);
|
|
|
|
|
|
|
|
// console.log("保存的数据", tempData);
|
|
|
|
|
|
|
|
// } else {
|
|
|
|
|
|
|
|
// // 创建新的 tempData 对象
|
|
|
|
|
|
|
|
// const tempData = {
|
|
|
|
|
|
|
|
// ...values,
|
|
|
|
|
|
|
|
// info: { ...values.info },
|
|
|
|
|
|
|
|
// quotation: quotation,
|
|
|
|
|
|
|
|
// lgc_details: Object.values(lgc_details)
|
|
|
|
|
|
|
|
// };
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// setSaveData(tempData);
|
|
|
|
|
|
|
|
// console.log("保存的数据", tempData);
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
return (
|
|
|
@ -626,7 +871,10 @@ function Detail() {
|
|
|
|
<Row>
|
|
|
|
<Row>
|
|
|
|
<Col span={6} className=' relative'>
|
|
|
|
<Col span={6} className=' relative'>
|
|
|
|
<Card className='w-[inherit] fixed overflow-y-auto max-h-[80vh]'>
|
|
|
|
<Card className='w-[inherit] fixed overflow-y-auto max-h-[80vh]'>
|
|
|
|
<Search style={{ marginBottom: 8 }} placeholder="Search" onChange={onChange} />
|
|
|
|
<Row>
|
|
|
|
|
|
|
|
<Search style={{ marginBottom: 8 }} placeholder="Search" onChange={onChange} />
|
|
|
|
|
|
|
|
</Row>
|
|
|
|
|
|
|
|
|
|
|
|
<Tree
|
|
|
|
<Tree
|
|
|
|
onSelect={handleNodeSelect}
|
|
|
|
onSelect={handleNodeSelect}
|
|
|
|
treeData={treeData}
|
|
|
|
treeData={treeData}
|
|
|
@ -652,24 +900,29 @@ function Detail() {
|
|
|
|
>
|
|
|
|
>
|
|
|
|
<h2>{t('products:EditComponents.info')}</h2>
|
|
|
|
<h2>{t('products:EditComponents.info')}</h2>
|
|
|
|
<Row gutter={16}>
|
|
|
|
<Row gutter={16}>
|
|
|
|
{selectedCategory.map((item, index) => (
|
|
|
|
{selectedCategory.map((item, index) => {
|
|
|
|
|
|
|
|
// const key = `${item.code}-${index}`;
|
|
|
|
<Col span={8} id={index} key={`${item.code}-${index}`}>
|
|
|
|
// console.log(key);
|
|
|
|
<Form.Item name={['info', item.code]} label={item.name}>
|
|
|
|
return (
|
|
|
|
{item.code === "duration" ? (
|
|
|
|
<Col span={8} id={index} key={`${item.code}-${index}`}>
|
|
|
|
<Input suffix="H" />
|
|
|
|
<Form.Item name={['info', item.code]} label={item.name}>
|
|
|
|
) : (item.code === "display_to_c") ? (
|
|
|
|
{item.code === "duration" ? (
|
|
|
|
<Select>
|
|
|
|
<Input suffix="H" />
|
|
|
|
<Select.Option value="plan_only">在计划显示,不在报价信显示</Select.Option>
|
|
|
|
) : (item.code === "display_to_c") ? (
|
|
|
|
<Select.Option value="plan_and_quote">计划和报价信都要显示</Select.Option>
|
|
|
|
<Select>
|
|
|
|
<Select.Option value="none"> 计划和报价信都不用显示</Select.Option>
|
|
|
|
<Select.Option value="在计划显示,不在报价信显示">在计划显示,不在报价信显示</Select.Option>
|
|
|
|
</Select>
|
|
|
|
<Select.Option value="计划和报价信都要显示">计划和报价信都要显示</Select.Option>
|
|
|
|
) : (
|
|
|
|
<Select.Option value="计划和报价信都不用显示"> 计划和报价信都不用显示</Select.Option>
|
|
|
|
<Input />
|
|
|
|
</Select>
|
|
|
|
)}
|
|
|
|
) : (item.code === "dept_name") ? (
|
|
|
|
</Form.Item>
|
|
|
|
<DeptSelector />
|
|
|
|
</Col>
|
|
|
|
) : (
|
|
|
|
))}
|
|
|
|
<Input />
|
|
|
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
</Form.Item>
|
|
|
|
|
|
|
|
</Col>
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
})}
|
|
|
|
</Row>
|
|
|
|
</Row>
|
|
|
|
|
|
|
|
|
|
|
|
<Card title={
|
|
|
|
<Card title={
|
|
|
@ -721,9 +974,9 @@ function Detail() {
|
|
|
|
/>
|
|
|
|
/>
|
|
|
|
</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={'id'}
|
|
|
@ -747,13 +1000,13 @@ function Detail() {
|
|
|
|
<Button type="primary" htmlType="submit" style={{ marginTop: 16, float: "right", marginRight: "5%" }}>
|
|
|
|
<Button type="primary" htmlType="submit" style={{ marginTop: 16, float: "right", marginRight: "5%" }}>
|
|
|
|
提交审核
|
|
|
|
提交审核
|
|
|
|
</Button>
|
|
|
|
</Button>
|
|
|
|
</Card>
|
|
|
|
</Card>
|
|
|
|
</Form>
|
|
|
|
</Form>
|
|
|
|
|
|
|
|
|
|
|
|
{/* <Card style={{ width: "80%" }}> */}
|
|
|
|
|
|
|
|
<Extras productId={2} />
|
|
|
|
|
|
|
|
{/* </Card> */}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{/* <Card style={{ width: "80%" }}> */}
|
|
|
|
|
|
|
|
<Extras productId={2} />
|
|
|
|
|
|
|
|
{/* </Card> */}
|
|
|
|
|
|
|
|
<FloatButton icon={<PlusCircleFilled />} onClick={() => setAddProductVisible(true)} />
|
|
|
|
</Col>
|
|
|
|
</Col>
|
|
|
|
</Row>
|
|
|
|
</Row>
|
|
|
|
|
|
|
|
|
|
|
@ -782,6 +1035,94 @@ function Detail() {
|
|
|
|
</Modal>
|
|
|
|
</Modal>
|
|
|
|
)
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
addProductVisible && (
|
|
|
|
|
|
|
|
<Modal
|
|
|
|
|
|
|
|
title="增加新产品"
|
|
|
|
|
|
|
|
visible={addProductVisible}
|
|
|
|
|
|
|
|
onOk={handelAddProduct}
|
|
|
|
|
|
|
|
onCancel={() => setAddProductVisible(false)}
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
<h4>选择产品类别</h4>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<Select style={{ width: "50%" }}
|
|
|
|
|
|
|
|
value={addProductType}
|
|
|
|
|
|
|
|
onChange={(value) => setAddProductType(value)}
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
{productsTypes.map((item) => (
|
|
|
|
|
|
|
|
<Select.Option key={item.key} value={item.value}>
|
|
|
|
|
|
|
|
{item.label}
|
|
|
|
|
|
|
|
</Select.Option>
|
|
|
|
|
|
|
|
))}
|
|
|
|
|
|
|
|
</Select>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<h4>新增产品名称</h4>
|
|
|
|
|
|
|
|
<Input
|
|
|
|
|
|
|
|
value={addproductName}
|
|
|
|
|
|
|
|
onChange={(e) => setAddProductName(e.target.value)}
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
</Modal>
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{/* {
|
|
|
|
|
|
|
|
quotationTableVisible && (
|
|
|
|
|
|
|
|
<Modal
|
|
|
|
|
|
|
|
title="编辑供应商报价"
|
|
|
|
|
|
|
|
visible={quotationTableVisible}
|
|
|
|
|
|
|
|
onOk={quotationTableVisibleOK}
|
|
|
|
|
|
|
|
onCancel={quotationTableVisibleCancel}
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
<h3>成人价</h3>
|
|
|
|
|
|
|
|
<Input value={currentQuotationRecord.adult_cost} />
|
|
|
|
|
|
|
|
<h3>儿童价</h3>
|
|
|
|
|
|
|
|
<Input value={currentQuotationRecord.children} />
|
|
|
|
|
|
|
|
<h3>币种</h3>
|
|
|
|
|
|
|
|
<Select style={{ width: "30%" }} value={currentQuotationRecord.currency}>
|
|
|
|
|
|
|
|
<Select.Option value="CNY">CNY</Select.Option>
|
|
|
|
|
|
|
|
<Select.Option value="USD">USD</Select.Option>
|
|
|
|
|
|
|
|
</Select >
|
|
|
|
|
|
|
|
<h3>类型</h3>
|
|
|
|
|
|
|
|
<Select style={{ width: "30%" }} value={currentQuotationRecord.unit_name}>
|
|
|
|
|
|
|
|
<Select.Option value="每人">每人</Select.Option>
|
|
|
|
|
|
|
|
<Select.Option value="每团">每团</Select.Option>
|
|
|
|
|
|
|
|
</Select>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<h3>人等</h3>
|
|
|
|
|
|
|
|
<td style={{ display: 'flex', alignItems: 'center' }}>
|
|
|
|
|
|
|
|
<InputNumber
|
|
|
|
|
|
|
|
min={0}
|
|
|
|
|
|
|
|
value={currentQuotationRecord.group_size_min}
|
|
|
|
|
|
|
|
// onChange={(value) => handleInputGroupSize('group_size_min', currentQuotationRecord.id, 'group_size', value)}
|
|
|
|
|
|
|
|
style={{ width: '50%', marginRight: '10px' }}
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
<span>-</span>
|
|
|
|
|
|
|
|
<InputNumber
|
|
|
|
|
|
|
|
min={0}
|
|
|
|
|
|
|
|
value={currentQuotationRecord.group_size_max}
|
|
|
|
|
|
|
|
// onChange={(value) => handleInputGroupSize('group_size_max', currentQuotationRecord.id, 'group_size', value)}
|
|
|
|
|
|
|
|
style={{ width: '50%', marginLeft: '10px' }}
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
</td>
|
|
|
|
|
|
|
|
<h4>有效期</h4>
|
|
|
|
|
|
|
|
<RangePicker allowClear={true} inputReadOnly={true} presets={presets} placeholder={['From', 'Thru']} value={[dayjs(currentQuotationRecord.use_dates_start).format('YYYY-MM-DD'),dayjs(currentQuotationRecord.use_dates_end).format('YYYY-MM-DD')]}/>
|
|
|
|
|
|
|
|
<h4>周末</h4>
|
|
|
|
|
|
|
|
{days.map((day, index) => (
|
|
|
|
|
|
|
|
<Button
|
|
|
|
|
|
|
|
key={index}
|
|
|
|
|
|
|
|
type={selectedDays.includes(day) ? 'primary' : 'default'}
|
|
|
|
|
|
|
|
onClick={() => handleDayClick(day)}
|
|
|
|
|
|
|
|
style={{ margin: '5px' }}
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
{day}
|
|
|
|
|
|
|
|
</Button>
|
|
|
|
|
|
|
|
))}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
</Modal>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
} */}
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
);
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|