|
|
@ -1,22 +1,26 @@
|
|
|
|
import React, { useState, useEffect, useRef, useMemo } from 'react';
|
|
|
|
import React, { useState, useEffect } from 'react';
|
|
|
|
import { Button, Card, Col, Row, Breadcrumb, Table, Popconfirm, Form, Input, InputNumber, Tag, Modal, Select, Tree, FloatButton, DatePicker, Spin, message } from 'antd';
|
|
|
|
import { Tooltip, 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, useProductsAuditStatesMapVal } from '@/hooks/useProductsSets';
|
|
|
|
import Extras from './Detail/Extras';
|
|
|
|
import Extras from './Detail/Extras';
|
|
|
|
import { useParams } from 'react-router-dom';
|
|
|
|
import { useParams } from 'react-router-dom';
|
|
|
|
import useProductsStore from '@/stores/Products/Index';
|
|
|
|
import useProductsStore from '@/stores/Products/Index';
|
|
|
|
|
|
|
|
import postProductsSave 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/BatchImportPrice';
|
|
|
|
import BatchImportPrice from './Detail/BatchImportPrice';
|
|
|
|
import dayjs from 'dayjs';
|
|
|
|
import dayjs from 'dayjs';
|
|
|
|
import { PlusCircleFilled } from '@ant-design/icons';
|
|
|
|
import { PlusCircleFilled, FileAddOutlined, ExportOutlined } 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 CitySelector from '@/components/CitySelector';
|
|
|
|
import { HT_HOST } from '@/config';
|
|
|
|
import { HT_HOST } from '@/config';
|
|
|
|
import { postJSON } from '@/utils/request';
|
|
|
|
import { postJSON, postForm } from '@/utils/request';
|
|
|
|
|
|
|
|
import RequireAuth from '@/components/RequireAuth'
|
|
|
|
|
|
|
|
import { PERM_ROLE_NEW } from '@/config'
|
|
|
|
import { create } from 'zustand';
|
|
|
|
import { create } from 'zustand';
|
|
|
|
|
|
|
|
import { PERM_PRODUCTS_MANAGEMENT } from '@/config';
|
|
|
|
function Detail() {
|
|
|
|
function Detail() {
|
|
|
|
const { t } = useTranslation();
|
|
|
|
const { t } = useTranslation();
|
|
|
|
const [form] = Form.useForm();
|
|
|
|
const [form] = Form.useForm();
|
|
|
@ -35,8 +39,7 @@ 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, audit_state, use_year } = useParams();
|
|
|
|
const { travel_agency_id } = useParams();
|
|
|
|
|
|
|
|
const { language } = useDefaultLgc();
|
|
|
|
const { language } = useDefaultLgc();
|
|
|
|
const HTLanguageSets = useHTLanguageSets();
|
|
|
|
const HTLanguageSets = useHTLanguageSets();
|
|
|
|
const { Search } = Input;
|
|
|
|
const { Search } = Input;
|
|
|
@ -53,17 +56,18 @@ function Detail() {
|
|
|
|
const [addProductType, setAddProductType] = useState('');
|
|
|
|
const [addProductType, setAddProductType] = useState('');
|
|
|
|
const [addproductName, setAddProductName] = useState('');
|
|
|
|
const [addproductName, setAddProductName] = useState('');
|
|
|
|
const [dataFetched, setDataFetched] = useState(false); // 添加一个标志位
|
|
|
|
const [dataFetched, setDataFetched] = useState(false); // 添加一个标志位
|
|
|
|
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 [info, setInfo] = useState();
|
|
|
|
const travel_agency_name = activeAgency.travel_agency_name;
|
|
|
|
const travel_agency_name = activeAgency.travel_agency_name;
|
|
|
|
|
|
|
|
const audit_state_id = activeAgency.audit_state_id;
|
|
|
|
|
|
|
|
let isCanEditable = !(audit_state_id === 1 || audit_state_id === 3 || audit_state_id === -1)
|
|
|
|
const [currentQuotationRecord, setCurrentQuotationRecord] = useState({
|
|
|
|
const [currentQuotationRecord, setCurrentQuotationRecord] = useState({
|
|
|
|
use_dates_start: null,
|
|
|
|
use_dates_start: null,
|
|
|
|
use_dates_end: null
|
|
|
|
use_dates_end: null
|
|
|
|
});
|
|
|
|
});
|
|
|
|
const formatDate = (date) => (date ? dayjs(date) : null);
|
|
|
|
const formatDate = (date) => (date ? dayjs(date) : null);
|
|
|
|
|
|
|
|
const stateMapVal = useProductsAuditStatesMapVal();
|
|
|
|
|
|
|
|
|
|
|
|
const startDate = currentQuotationRecord.use_dates_start && dayjs(currentQuotationRecord.use_dates_start).isValid()
|
|
|
|
const startDate = currentQuotationRecord.use_dates_start && dayjs(currentQuotationRecord.use_dates_start).isValid()
|
|
|
|
? formatDate(currentQuotationRecord.use_dates_start)
|
|
|
|
? formatDate(currentQuotationRecord.use_dates_start)
|
|
|
@ -80,7 +84,6 @@ function Detail() {
|
|
|
|
const days = [
|
|
|
|
const days = [
|
|
|
|
'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'
|
|
|
|
'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'
|
|
|
|
];
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
|
|
const productProject = {
|
|
|
|
const productProject = {
|
|
|
|
"6": [
|
|
|
|
"6": [
|
|
|
|
{ code: "code", name: t('products:Code'), nameKey: 'products:Code' },
|
|
|
|
{ code: "code", name: t('products:Code'), nameKey: 'products:Code' },
|
|
|
@ -90,42 +93,162 @@ function Detail() {
|
|
|
|
{ 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' },
|
|
|
|
{ code: "km", name: t('products:KM'), nameKey: 'products:KM' },
|
|
|
|
{ code: "km", name: t('products:KM'), nameKey: 'products:KM' },
|
|
|
|
{ code: "remarks", name: t('products:Remarks'), nameKey: 'products:Remarks' }
|
|
|
|
{
|
|
|
|
|
|
|
|
code: "remarks",
|
|
|
|
|
|
|
|
name: (
|
|
|
|
|
|
|
|
<RequireAuth subject={PERM_PRODUCTS_MANAGEMENT}>
|
|
|
|
|
|
|
|
{t('products:Remarks')}
|
|
|
|
|
|
|
|
</RequireAuth>
|
|
|
|
|
|
|
|
),
|
|
|
|
|
|
|
|
nameKey: 'products:Remarks',
|
|
|
|
|
|
|
|
},
|
|
|
|
],
|
|
|
|
],
|
|
|
|
"J": [
|
|
|
|
"J": [
|
|
|
|
{ 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' },
|
|
|
|
{ code: "recommends_rate", name: t('products:recommendationRate'), nameKey: 'products:recommendationRate' },
|
|
|
|
{
|
|
|
|
|
|
|
|
code: "recommends_rate",
|
|
|
|
|
|
|
|
name: (
|
|
|
|
|
|
|
|
<RequireAuth subject={PERM_PRODUCTS_MANAGEMENT}>
|
|
|
|
|
|
|
|
{t('products:recommendationRate')}
|
|
|
|
|
|
|
|
</RequireAuth>
|
|
|
|
|
|
|
|
),
|
|
|
|
|
|
|
|
nameKey: 'products:recommendationRate',
|
|
|
|
|
|
|
|
},
|
|
|
|
{ code: "duration", name: t('products:Duration'), nameKey: 'products:Duration' },
|
|
|
|
{ code: "duration", name: t('products:Duration'), nameKey: 'products:Duration' },
|
|
|
|
{ code: "dept_name", name: t('products:Dept'), nameKey: 'products:Dept' },
|
|
|
|
{
|
|
|
|
{ code: "display_to_c", name: t('products:DisplayToC'), nameKey: 'products:DisplayToC' },
|
|
|
|
code: "dept_name",
|
|
|
|
{ code: "remarks", name: t('products:Remarks'), nameKey: 'products:Remarks' },
|
|
|
|
name: (
|
|
|
|
|
|
|
|
<RequireAuth subject={PERM_PRODUCTS_MANAGEMENT}>
|
|
|
|
|
|
|
|
{t('products:Dept')}
|
|
|
|
|
|
|
|
</RequireAuth>
|
|
|
|
|
|
|
|
),
|
|
|
|
|
|
|
|
nameKey: 'products:Dept',
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
code: "display_to_c",
|
|
|
|
|
|
|
|
name: (
|
|
|
|
|
|
|
|
<RequireAuth subject={PERM_PRODUCTS_MANAGEMENT}>
|
|
|
|
|
|
|
|
{t('products:DisplayToC')}
|
|
|
|
|
|
|
|
</RequireAuth>
|
|
|
|
|
|
|
|
),
|
|
|
|
|
|
|
|
nameKey: 'products:DisplayToC',
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
code: "remarks",
|
|
|
|
|
|
|
|
name: (
|
|
|
|
|
|
|
|
<RequireAuth subject={PERM_PRODUCTS_MANAGEMENT}>
|
|
|
|
|
|
|
|
{t('products:Remarks')}
|
|
|
|
|
|
|
|
</RequireAuth>
|
|
|
|
|
|
|
|
),
|
|
|
|
|
|
|
|
nameKey: 'products:Remarks',
|
|
|
|
|
|
|
|
},
|
|
|
|
],
|
|
|
|
],
|
|
|
|
"Q": [
|
|
|
|
"Q": [
|
|
|
|
{ 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' },
|
|
|
|
{ code: "recommends_rate", name: t('products:recommendationRate'), nameKey: 'products:recommendationRate' },
|
|
|
|
{
|
|
|
|
|
|
|
|
code: "recommends_rate",
|
|
|
|
|
|
|
|
name: (
|
|
|
|
|
|
|
|
<RequireAuth subject={PERM_PRODUCTS_MANAGEMENT}>
|
|
|
|
|
|
|
|
{t('products:recommendationRate')}
|
|
|
|
|
|
|
|
</RequireAuth>
|
|
|
|
|
|
|
|
),
|
|
|
|
|
|
|
|
nameKey: 'products:recommendationRate',
|
|
|
|
|
|
|
|
},
|
|
|
|
{ code: "duration", name: t('products:Duration'), nameKey: 'products:Duration' },
|
|
|
|
{ code: "duration", name: t('products:Duration'), nameKey: 'products:Duration' },
|
|
|
|
{ code: "dept_name", name: t('products:Dept'), nameKey: 'products:Dept' },
|
|
|
|
{
|
|
|
|
{ code: "display_to_c", name: t('products:DisplayToC'), nameKey: 'products:DisplayToC' },
|
|
|
|
code: "dept_name",
|
|
|
|
{ code: "remarks", name: t('products:Remarks'), nameKey: 'products:Remarks' },
|
|
|
|
name: (
|
|
|
|
|
|
|
|
<RequireAuth subject={PERM_PRODUCTS_MANAGEMENT}>
|
|
|
|
|
|
|
|
{t('products:Dept')}
|
|
|
|
|
|
|
|
</RequireAuth>
|
|
|
|
|
|
|
|
),
|
|
|
|
|
|
|
|
nameKey: 'products:Dept',
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
code: "display_to_c",
|
|
|
|
|
|
|
|
name: (
|
|
|
|
|
|
|
|
<RequireAuth subject={PERM_PRODUCTS_MANAGEMENT}>
|
|
|
|
|
|
|
|
{t('products:DisplayToC')}
|
|
|
|
|
|
|
|
</RequireAuth>
|
|
|
|
|
|
|
|
),
|
|
|
|
|
|
|
|
nameKey: 'products:DisplayToC',
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
code: "remarks",
|
|
|
|
|
|
|
|
name: (
|
|
|
|
|
|
|
|
<RequireAuth subject={PERM_PRODUCTS_MANAGEMENT}>
|
|
|
|
|
|
|
|
{t('products:Remarks')}
|
|
|
|
|
|
|
|
</RequireAuth>
|
|
|
|
|
|
|
|
),
|
|
|
|
|
|
|
|
nameKey: 'products:Remarks',
|
|
|
|
|
|
|
|
},
|
|
|
|
],
|
|
|
|
],
|
|
|
|
"D": [
|
|
|
|
"D": [
|
|
|
|
{ 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' },
|
|
|
|
{ code: "recommends_rate", name: t('products:recommendationRate'), nameKey: 'products:recommendationRate' },
|
|
|
|
{
|
|
|
|
|
|
|
|
code: "recommends_rate",
|
|
|
|
|
|
|
|
name: (
|
|
|
|
|
|
|
|
<RequireAuth subject={PERM_PRODUCTS_MANAGEMENT}>
|
|
|
|
|
|
|
|
{t('products:recommendationRate')}
|
|
|
|
|
|
|
|
</RequireAuth>
|
|
|
|
|
|
|
|
),
|
|
|
|
|
|
|
|
nameKey: 'products:recommendationRate',
|
|
|
|
|
|
|
|
},
|
|
|
|
{ code: "duration", name: t('products:Duration'), nameKey: 'products:Duration' },
|
|
|
|
{ code: "duration", name: t('products:Duration'), nameKey: 'products:Duration' },
|
|
|
|
{ code: "dept_name", name: t('products:Dept'), nameKey: 'products:Dept' },
|
|
|
|
{
|
|
|
|
{ code: "display_to_c", name: t('products:DisplayToC'), nameKey: 'products:DisplayToC' },
|
|
|
|
code: "dept_name",
|
|
|
|
{ code: "remarks", name: t('products:Remarks'), nameKey: 'products:Remarks' },
|
|
|
|
name: (
|
|
|
|
|
|
|
|
<RequireAuth subject={PERM_PRODUCTS_MANAGEMENT}>
|
|
|
|
|
|
|
|
{t('products:Dept')}
|
|
|
|
|
|
|
|
</RequireAuth>
|
|
|
|
|
|
|
|
),
|
|
|
|
|
|
|
|
nameKey: 'products:Dept',
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
code: "display_to_c",
|
|
|
|
|
|
|
|
name: (
|
|
|
|
|
|
|
|
<RequireAuth subject={PERM_PRODUCTS_MANAGEMENT}>
|
|
|
|
|
|
|
|
{t('products:DisplayToC')}
|
|
|
|
|
|
|
|
</RequireAuth>
|
|
|
|
|
|
|
|
),
|
|
|
|
|
|
|
|
nameKey: 'products:DisplayToC',
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
code: "remarks",
|
|
|
|
|
|
|
|
name: (
|
|
|
|
|
|
|
|
<RequireAuth subject={PERM_PRODUCTS_MANAGEMENT}>
|
|
|
|
|
|
|
|
{t('products:Remarks')}
|
|
|
|
|
|
|
|
</RequireAuth>
|
|
|
|
|
|
|
|
),
|
|
|
|
|
|
|
|
nameKey: 'products:Remarks',
|
|
|
|
|
|
|
|
},
|
|
|
|
],
|
|
|
|
],
|
|
|
|
"7": [
|
|
|
|
"7": [
|
|
|
|
{ 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' },
|
|
|
|
{ code: "recommends_rate", name: t('products:recommendationRate'), nameKey: 'products:recommendationRate' },
|
|
|
|
{
|
|
|
|
|
|
|
|
code: "recommends_rate",
|
|
|
|
|
|
|
|
name: (
|
|
|
|
|
|
|
|
<RequireAuth subject={PERM_PRODUCTS_MANAGEMENT}>
|
|
|
|
|
|
|
|
{t('products:recommendationRate')}
|
|
|
|
|
|
|
|
</RequireAuth>
|
|
|
|
|
|
|
|
),
|
|
|
|
|
|
|
|
nameKey: 'products:recommendationRate',
|
|
|
|
|
|
|
|
},
|
|
|
|
{ code: "duration", name: t('products:Duration'), nameKey: 'products:Duration' },
|
|
|
|
{ code: "duration", name: t('products:Duration'), nameKey: 'products:Duration' },
|
|
|
|
{ code: "open_weekdays", name: t('products:OpenWeekdays'), nameKey: 'products:OpenWeekdays' },
|
|
|
|
{ code: "open_weekdays", name: t('products:OpenWeekdays'), nameKey: 'products:OpenWeekdays' },
|
|
|
|
{ code: "remarks", name: t('products:Remarks'), nameKey: 'products:Remarks' },
|
|
|
|
{
|
|
|
|
|
|
|
|
code: "remarks",
|
|
|
|
|
|
|
|
name: (
|
|
|
|
|
|
|
|
<RequireAuth subject={PERM_PRODUCTS_MANAGEMENT}>
|
|
|
|
|
|
|
|
{t('products:Remarks')}
|
|
|
|
|
|
|
|
</RequireAuth>
|
|
|
|
|
|
|
|
),
|
|
|
|
|
|
|
|
nameKey: 'products:Remarks',
|
|
|
|
|
|
|
|
},
|
|
|
|
],
|
|
|
|
],
|
|
|
|
"8": [
|
|
|
|
"8": [
|
|
|
|
{ code: "code", name: t('products:Code') },
|
|
|
|
{ code: "code", name: t('products:Code') },
|
|
|
@ -136,7 +259,7 @@ function Detail() {
|
|
|
|
{ code: "city_name", name: t('products:City'), nameKey: 'products:City' },
|
|
|
|
{ code: "city_name", name: t('products:City'), nameKey: 'products:City' },
|
|
|
|
]
|
|
|
|
]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
const [selectedCategory, setSelectedCategory] = useState(productProject.B);
|
|
|
|
const [selectedCategory, setSelectedCategory] = useState([]);
|
|
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
useEffect(() => {
|
|
|
|
setLanguageStatus(language);
|
|
|
|
setLanguageStatus(language);
|
|
|
@ -169,10 +292,11 @@ function Detail() {
|
|
|
|
};
|
|
|
|
};
|
|
|
|
const tempExpandedKeys = productsTypes.map(item => item.key)
|
|
|
|
const tempExpandedKeys = productsTypes.map(item => item.key)
|
|
|
|
const treeData = generateTreeData(productsTypes, agencyProducts);
|
|
|
|
const treeData = generateTreeData(productsTypes, agencyProducts);
|
|
|
|
|
|
|
|
|
|
|
|
setDataFetched(true); // 设置标志位为 true,表示数据已获取
|
|
|
|
setDataFetched(true); // 设置标志位为 true,表示数据已获取
|
|
|
|
setTreeData(treeData);
|
|
|
|
setTreeData(treeData);
|
|
|
|
setExpandedKeys(tempExpandedKeys);
|
|
|
|
setExpandedKeys(tempExpandedKeys);
|
|
|
|
console.log("agencyProducts", agencyProducts)
|
|
|
|
console.log("stateMapVal", stateMapVal);
|
|
|
|
setProductsData(agencyProducts);
|
|
|
|
setProductsData(agencyProducts);
|
|
|
|
setDefaultData(treeData);
|
|
|
|
setDefaultData(treeData);
|
|
|
|
setDataList(flattenTreeData(treeData));
|
|
|
|
setDataList(flattenTreeData(treeData));
|
|
|
@ -182,7 +306,37 @@ function Detail() {
|
|
|
|
fetchData();
|
|
|
|
fetchData();
|
|
|
|
}, [agencyProducts, dataFetched]);
|
|
|
|
}, [agencyProducts, dataFetched]);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// useEffect(()=>{
|
|
|
|
|
|
|
|
// // if(editingProduct && treeData){
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// editingProductQuotation();
|
|
|
|
|
|
|
|
// // }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// },[treeData,editingProduct])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// const editingProductQuotation = () => {
|
|
|
|
|
|
|
|
// console.log("editingProduct",editingProduct)
|
|
|
|
|
|
|
|
// const editingProductID = editingProduct.id;
|
|
|
|
|
|
|
|
// let stopProgram = false;
|
|
|
|
|
|
|
|
// for (const element of treeData) {
|
|
|
|
|
|
|
|
// if (stopProgram) {
|
|
|
|
|
|
|
|
// return;
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// const childList = element.children;
|
|
|
|
|
|
|
|
// for (const product of childList) {
|
|
|
|
|
|
|
|
// const childrenID = product.key.split('-')[1];
|
|
|
|
|
|
|
|
// console.log("childrenID",childrenID);
|
|
|
|
|
|
|
|
// console.log("editingProductID",editingProductID);
|
|
|
|
|
|
|
|
// if (editingProductID == childrenID) {
|
|
|
|
|
|
|
|
// console.log("AAAAAAAAAA");
|
|
|
|
|
|
|
|
// console.log("product",product);
|
|
|
|
|
|
|
|
// stopProgram = true;
|
|
|
|
|
|
|
|
// handleNodeSelect(product);
|
|
|
|
|
|
|
|
// break;
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// }
|
|
|
|
const flattenTreeData = (tree) => {
|
|
|
|
const flattenTreeData = (tree) => {
|
|
|
|
let flatList = [];
|
|
|
|
let flatList = [];
|
|
|
|
const flatten = (nodes) => {
|
|
|
|
const flatten = (nodes) => {
|
|
|
@ -197,6 +351,17 @@ function Detail() {
|
|
|
|
return flatList;
|
|
|
|
return flatList;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// const ProductsSave = async (products) => {
|
|
|
|
|
|
|
|
// await postProductsSave(products)
|
|
|
|
|
|
|
|
// .then((json)=> {
|
|
|
|
|
|
|
|
// if (json.errcode === 0) {
|
|
|
|
|
|
|
|
// message.success("保存成功");
|
|
|
|
|
|
|
|
// }else{
|
|
|
|
|
|
|
|
// message.error("保存失败")
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// })
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
const getParentKey = (key, tree) => {
|
|
|
|
const getParentKey = (key, tree) => {
|
|
|
|
let parentKey;
|
|
|
|
let parentKey;
|
|
|
|
for (let i = 0; i < tree.length; i++) {
|
|
|
|
for (let i = 0; i < tree.length; i++) {
|
|
|
@ -257,9 +422,6 @@ function Detail() {
|
|
|
|
setCurrentQuotationRecord(record);
|
|
|
|
setCurrentQuotationRecord(record);
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const cancel = () => {
|
|
|
|
|
|
|
|
setEditingid('');
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const handleDelete = (index) => {
|
|
|
|
const handleDelete = (index) => {
|
|
|
|
const newData = [...quotation];
|
|
|
|
const newData = [...quotation];
|
|
|
@ -295,6 +457,8 @@ function Detail() {
|
|
|
|
tempKey: Math.random()
|
|
|
|
tempKey: Math.random()
|
|
|
|
};
|
|
|
|
};
|
|
|
|
setQuotation([...quotation, newData]);
|
|
|
|
setQuotation([...quotation, newData]);
|
|
|
|
|
|
|
|
const index = [...quotation, newData].length - 1
|
|
|
|
|
|
|
|
edit(newData, index);
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const handleBatchImport = () => {
|
|
|
|
const handleBatchImport = () => {
|
|
|
@ -376,22 +540,38 @@ function Detail() {
|
|
|
|
|
|
|
|
|
|
|
|
{ title: t('products:Weekdays'), dataIndex: 'weekdays', width: '10%' },
|
|
|
|
{ title: t('products:Weekdays'), dataIndex: 'weekdays', width: '10%' },
|
|
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 根据条件判断是否要添加操作列
|
|
|
|
|
|
|
|
if (!isCanEditable) {
|
|
|
|
|
|
|
|
columns.push({
|
|
|
|
title: t('products:operation'),
|
|
|
|
title: t('products:operation'),
|
|
|
|
dataIndex: 'operation',
|
|
|
|
dataIndex: 'operation',
|
|
|
|
render: (_, record, index) => {
|
|
|
|
render: (_, record, index) => {
|
|
|
|
|
|
|
|
const canEdit = record.audit_state_id === -1;
|
|
|
|
return (
|
|
|
|
return (
|
|
|
|
<span>
|
|
|
|
<span>
|
|
|
|
<a onClick={() => edit(record, index)} style={{ marginRight: 8 }}>{t('Edit')}</a>
|
|
|
|
{canEdit ? (
|
|
|
|
<Popconfirm title={t('sureDelete')} onConfirm={() => handleDelete(index)}>
|
|
|
|
<a onClick={() => edit(record, index)} style={{ marginRight: 8 }}>{t('Edit')}</a>
|
|
|
|
<a>{t('Delete')}</a>
|
|
|
|
) : (
|
|
|
|
</Popconfirm>
|
|
|
|
<span style={{ color: 'gray', marginRight: 8 }}>{t('Edit')}</span>
|
|
|
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
{canEdit ? (
|
|
|
|
|
|
|
|
<Popconfirm title={t('sureDelete')} onConfirm={() => handleDelete(index)}>
|
|
|
|
|
|
|
|
<a>{t('Delete')}</a>
|
|
|
|
|
|
|
|
</Popconfirm>
|
|
|
|
|
|
|
|
) : (
|
|
|
|
|
|
|
|
<span style={{ color: 'gray' }}>{t('Delete')}</span>
|
|
|
|
|
|
|
|
)}
|
|
|
|
</span>
|
|
|
|
</span>
|
|
|
|
)
|
|
|
|
);
|
|
|
|
},
|
|
|
|
}
|
|
|
|
},
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const handleTagClick = (tag) => {
|
|
|
|
const handleTagClick = (tag) => {
|
|
|
@ -451,10 +631,10 @@ function Detail() {
|
|
|
|
// 更新整个 lgc_details 对象
|
|
|
|
// 更新整个 lgc_details 对象
|
|
|
|
const updatedLgcDetails = {
|
|
|
|
const updatedLgcDetails = {
|
|
|
|
...lgc_details,
|
|
|
|
...lgc_details,
|
|
|
|
[languageStatus]: {
|
|
|
|
[languageStatus]: {
|
|
|
|
...lgc_details[languageStatus],
|
|
|
|
...lgc_details[languageStatus],
|
|
|
|
[field]: value,
|
|
|
|
[field]: value,
|
|
|
|
lgc: languageStatus.toString(),
|
|
|
|
lgc: languageStatus.toString(),
|
|
|
|
id: lgc_details[languageStatus]?.id || ''
|
|
|
|
id: lgc_details[languageStatus]?.id || ''
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
};
|
|
|
@ -477,9 +657,9 @@ function Detail() {
|
|
|
|
|
|
|
|
|
|
|
|
//树组件方法
|
|
|
|
//树组件方法
|
|
|
|
const handleNodeSelect = (_, { node }) => {
|
|
|
|
const handleNodeSelect = (_, { node }) => {
|
|
|
|
|
|
|
|
console.log("node",node)
|
|
|
|
setSelectedNodeid(node.key);
|
|
|
|
setSelectedNodeid(node.key);
|
|
|
|
const fatherKey = node.key.split('-')[0];
|
|
|
|
const fatherKey = node.key.split('-')[0];
|
|
|
|
setSelectedNodeKey(fatherKey);
|
|
|
|
|
|
|
|
setSelectedCategory(productProject[fatherKey]);
|
|
|
|
setSelectedCategory(productProject[fatherKey]);
|
|
|
|
setTags([languageLabel]);
|
|
|
|
setTags([languageLabel]);
|
|
|
|
// 如果点击的是同一个节点,不做任何操作
|
|
|
|
// 如果点击的是同一个节点,不做任何操作
|
|
|
@ -490,23 +670,20 @@ function Detail() {
|
|
|
|
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);
|
|
|
|
if (!node._raw.info.id) {
|
|
|
|
if (!node._raw.info.id) {
|
|
|
|
let infoData = node._raw.info;
|
|
|
|
let infoData = node._raw.info;
|
|
|
|
setInfo(node._raw.info);
|
|
|
|
setInfo(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);
|
|
|
|
|
|
|
|
form.setFieldsValue({
|
|
|
|
form.setFieldsValue({
|
|
|
|
info: {
|
|
|
|
info: {
|
|
|
|
id: infoData.id || "",
|
|
|
|
id: infoData.id || "",
|
|
|
|
title: infoData.title || "",
|
|
|
|
title: infoData.title || "",
|
|
|
|
code: infoData.code || "",
|
|
|
|
code: infoData.code || "",
|
|
|
|
type: infoData.product_type_id || "",
|
|
|
|
type: infoData.product_type_id || "",
|
|
|
|
audit_state:"-1",
|
|
|
|
audit_state: "-1",
|
|
|
|
create_date: infoData.create_date || "",
|
|
|
|
create_date: infoData.create_date || "",
|
|
|
|
created_by: infoData.created_by || "",
|
|
|
|
created_by: infoData.created_by || "",
|
|
|
|
travel_agency_id: travel_agency_id || "",
|
|
|
|
travel_agency_id: travel_agency_id || "",
|
|
|
@ -524,7 +701,7 @@ function Detail() {
|
|
|
|
city_id: infoData.city_id || "",
|
|
|
|
city_id: infoData.city_id || "",
|
|
|
|
// product_type_name: infoData.product_type_name || "",
|
|
|
|
// product_type_name: infoData.product_type_name || "",
|
|
|
|
// dept_name: infoData.dept_name || "",
|
|
|
|
// dept_name: infoData.dept_name || "",
|
|
|
|
|
|
|
|
|
|
|
|
},
|
|
|
|
},
|
|
|
|
lgc_details: {
|
|
|
|
lgc_details: {
|
|
|
|
lgc: language,
|
|
|
|
lgc: language,
|
|
|
@ -548,9 +725,6 @@ function Detail() {
|
|
|
|
}])
|
|
|
|
}])
|
|
|
|
return
|
|
|
|
return
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let initialQuotationData = null;
|
|
|
|
let initialQuotationData = null;
|
|
|
|
let infoData = null;
|
|
|
|
let infoData = null;
|
|
|
|
let lgcDetailsData = null;
|
|
|
|
let lgcDetailsData = null;
|
|
|
@ -576,7 +750,7 @@ function Detail() {
|
|
|
|
};
|
|
|
|
};
|
|
|
|
delete updatedObject.unit_name;
|
|
|
|
delete updatedObject.unit_name;
|
|
|
|
delete updatedObject.unit_id;
|
|
|
|
delete updatedObject.unit_id;
|
|
|
|
delete updatedObject.audit_state_id;
|
|
|
|
// delete updatedObject.audit_state_id;
|
|
|
|
delete updatedObject.audit_state_name;
|
|
|
|
delete updatedObject.audit_state_name;
|
|
|
|
return updatedObject;
|
|
|
|
return updatedObject;
|
|
|
|
});
|
|
|
|
});
|
|
|
@ -593,9 +767,6 @@ function Detail() {
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (node._raw.info.id) {
|
|
|
|
|
|
|
|
setInfoDataForId(infoData.id)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
setLgc_details(newLgcDetails);
|
|
|
|
setLgc_details(newLgcDetails);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -651,12 +822,11 @@ function Detail() {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//新增产品
|
|
|
|
const handelAddProduct = () => {
|
|
|
|
const handelAddProduct = () => {
|
|
|
|
// 找到对应的产品类型节点
|
|
|
|
// 找到对应的产品类型节点
|
|
|
|
const productTypeNode = treeData.find(item => item.key === addProductType);
|
|
|
|
const productTypeNode = treeData.find(item => item.key === addProductType);
|
|
|
@ -711,8 +881,7 @@ function Detail() {
|
|
|
|
return item;
|
|
|
|
return item;
|
|
|
|
});
|
|
|
|
});
|
|
|
|
// 更新 treeData
|
|
|
|
// 更新 treeData
|
|
|
|
setEditingProduct(null)
|
|
|
|
// setEditingProduct(null);
|
|
|
|
console.log("newTreeData", newTreeData);
|
|
|
|
|
|
|
|
setTreeData(newTreeData);
|
|
|
|
setTreeData(newTreeData);
|
|
|
|
|
|
|
|
|
|
|
|
let tempProductDataList = productsData[addProductType];
|
|
|
|
let tempProductDataList = productsData[addProductType];
|
|
|
@ -725,62 +894,39 @@ function Detail() {
|
|
|
|
setAddProductVisible(false);
|
|
|
|
setAddProductVisible(false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// let tempProductDataList = productsData[addProductType];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// //初始化产品数据
|
|
|
|
|
|
|
|
// const newProduct = {
|
|
|
|
|
|
|
|
// info: {
|
|
|
|
|
|
|
|
// code: 'addProduct'
|
|
|
|
|
|
|
|
// },
|
|
|
|
|
|
|
|
// quotation: [],
|
|
|
|
|
|
|
|
// lgc_details: []
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// tempProductDataList.push(newProduct);
|
|
|
|
|
|
|
|
// const newProductsData = {
|
|
|
|
|
|
|
|
// ...productsData, // 假设使用了展开运算符来复制现有数组
|
|
|
|
|
|
|
|
// [addProductType]: tempProductDataList
|
|
|
|
|
|
|
|
// };
|
|
|
|
|
|
|
|
// setProductsData(newProductsData);
|
|
|
|
|
|
|
|
// setAddProductVisible(false);
|
|
|
|
|
|
|
|
// };
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const renderFormItem = (item) => {
|
|
|
|
const renderFormItem = (item) => {
|
|
|
|
switch (item.code) {
|
|
|
|
switch (item.code) {
|
|
|
|
case "duration":
|
|
|
|
case "duration":
|
|
|
|
return <Input suffix="H" />;
|
|
|
|
return <Input suffix="H" disabled={isCanEditable} />;
|
|
|
|
case "display_to_c":
|
|
|
|
case "display_to_c":
|
|
|
|
return (
|
|
|
|
return (
|
|
|
|
<Select>
|
|
|
|
<Select disabled={isCanEditable}>
|
|
|
|
<Select.Option value={0}>在计划显示,不在报价信显示</Select.Option>
|
|
|
|
<Select.Option value={0}>在计划显示,不在报价信显示</Select.Option>
|
|
|
|
<Select.Option value={1}>计划和报价信都要显示</Select.Option>
|
|
|
|
<Select.Option value={1}>计划和报价信都要显示</Select.Option>
|
|
|
|
<Select.Option value={2}>计划和报价信都不用显示</Select.Option>
|
|
|
|
<Select.Option value={2}>计划和报价信都不用显示</Select.Option>
|
|
|
|
</Select>
|
|
|
|
</Select>
|
|
|
|
);
|
|
|
|
);
|
|
|
|
case "dept_name":
|
|
|
|
case "dept_name":
|
|
|
|
return <DeptSelector />;
|
|
|
|
return <DeptSelector disabled={isCanEditable} />;
|
|
|
|
case "city_name":
|
|
|
|
case "city_name":
|
|
|
|
return <CitySelector />;
|
|
|
|
return <CitySelector disabled={isCanEditable} />;
|
|
|
|
default:
|
|
|
|
default:
|
|
|
|
return <Input />;
|
|
|
|
return <Input disabled={isCanEditable} />;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//保存产品
|
|
|
|
const onSave = async (values) => {
|
|
|
|
const onSave = async (values) => {
|
|
|
|
let tempInfo
|
|
|
|
let tempInfo
|
|
|
|
console.log("values", values)
|
|
|
|
|
|
|
|
console.log("info", info)
|
|
|
|
|
|
|
|
if (info.id === "") {
|
|
|
|
if (info.id === "") {
|
|
|
|
tempInfo = {
|
|
|
|
tempInfo = {
|
|
|
|
...info,
|
|
|
|
...info,
|
|
|
|
...values.info,
|
|
|
|
...values.info,
|
|
|
|
city_name: values.info.city_name.label,
|
|
|
|
city_name: values.info.city_name.label,
|
|
|
|
audit_state:"-1"
|
|
|
|
audit_state: "-1"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
delete tempInfo.product_type_name;
|
|
|
|
delete tempInfo.product_type_name;
|
|
|
|
delete tempInfo.dept_name;
|
|
|
|
delete tempInfo.dept_name;
|
|
|
|
|
|
|
|
|
|
|
|
console.log("新增")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let tempQuotation = quotation.map(element => {
|
|
|
|
let tempQuotation = quotation.map(element => {
|
|
|
|
const updateData = {
|
|
|
|
const updateData = {
|
|
|
@ -790,18 +936,17 @@ function Detail() {
|
|
|
|
delete updateData.tempKey
|
|
|
|
delete updateData.tempKey
|
|
|
|
return updateData
|
|
|
|
return updateData
|
|
|
|
})
|
|
|
|
})
|
|
|
|
let tempLgc_details = [{...lgc_details}]
|
|
|
|
let tempLgc_details = [{ ...lgc_details }]
|
|
|
|
console.log("tempLgc_details",tempLgc_details)
|
|
|
|
|
|
|
|
const tempData = {
|
|
|
|
const tempData = {
|
|
|
|
travel_agency_id,
|
|
|
|
travel_agency_id,
|
|
|
|
info: tempInfo,
|
|
|
|
info: tempInfo,
|
|
|
|
quotation: tempQuotation,
|
|
|
|
quotation: tempQuotation,
|
|
|
|
lgc_details: Object.values(lgc_details)
|
|
|
|
lgc_details: Object.values(lgc_details)
|
|
|
|
};
|
|
|
|
};
|
|
|
|
console.log("tempData",tempData);
|
|
|
|
console.log("tempData", tempData);
|
|
|
|
|
|
|
|
|
|
|
|
const { errcode, result } = await postJSON(`${HT_HOST}/Service_BaseInfoWeb/agency_product_save`, tempData);
|
|
|
|
const { errcode, result } = await postJSON(`${HT_HOST}/Service_BaseInfoWeb/agency_product_save`, tempData);
|
|
|
|
console.log("result",result)
|
|
|
|
console.log("result", result);
|
|
|
|
if (errcode === 0) {
|
|
|
|
if (errcode === 0) {
|
|
|
|
message.success("保存成功");
|
|
|
|
message.success("保存成功");
|
|
|
|
setDataFetched(false);
|
|
|
|
setDataFetched(false);
|
|
|
@ -809,14 +954,18 @@ function Detail() {
|
|
|
|
message.error(`保存失败: ${result}`);
|
|
|
|
message.error(`保存失败: ${result}`);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return
|
|
|
|
return
|
|
|
|
} else {
|
|
|
|
|
|
|
|
tempInfo = {
|
|
|
|
|
|
|
|
...info,
|
|
|
|
|
|
|
|
...values.info,
|
|
|
|
|
|
|
|
audit_state: "-1"
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
tempInfo = {
|
|
|
|
|
|
|
|
...info,
|
|
|
|
|
|
|
|
...values.info,
|
|
|
|
|
|
|
|
audit_state: "-1"
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
console.log("tempInfo", tempInfo)
|
|
|
|
console.log("tempInfo", tempInfo)
|
|
|
|
|
|
|
|
|
|
|
|
let tempQuotation = quotation.map(element => {
|
|
|
|
let tempQuotation = quotation.map(element => {
|
|
|
@ -836,8 +985,8 @@ function Detail() {
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
console.log("tempData", tempData)
|
|
|
|
console.log("tempData", tempData)
|
|
|
|
|
|
|
|
// const { errcode, result } = await postProductsSave(tempData);
|
|
|
|
const { errcode, result } = await postJSON(`${HT_HOST}/Service_BaseInfoWeb/agency_product_save`, tempData);
|
|
|
|
const { errcode, result } = await postJSON(`${HT_HOST}/Service_BaseInfoWeb/agency_product_save`, tempData);
|
|
|
|
|
|
|
|
|
|
|
|
if (errcode === 0) {
|
|
|
|
if (errcode === 0) {
|
|
|
|
message.success("保存成功");
|
|
|
|
message.success("保存成功");
|
|
|
|
setDataFetched(false);
|
|
|
|
setDataFetched(false);
|
|
|
@ -937,12 +1086,14 @@ function Detail() {
|
|
|
|
<Input
|
|
|
|
<Input
|
|
|
|
style={{ width: "30%" }}
|
|
|
|
style={{ width: "30%" }}
|
|
|
|
onChange={(e) => handleChange('title', e.target.value)}
|
|
|
|
onChange={(e) => handleChange('title', e.target.value)}
|
|
|
|
|
|
|
|
disabled={isCanEditable}
|
|
|
|
/>
|
|
|
|
/>
|
|
|
|
</Form.Item>
|
|
|
|
</Form.Item>
|
|
|
|
<Form.Item label={t('products:Description')} name={['lgc_details', 'description']}>
|
|
|
|
<Form.Item label={t('products:Description')} name={['lgc_details', 'description']}>
|
|
|
|
<Input.TextArea
|
|
|
|
<Input.TextArea
|
|
|
|
rows={4}
|
|
|
|
rows={4}
|
|
|
|
onChange={(e) => handleChange('description', e.target.value)}
|
|
|
|
onChange={(e) => handleChange('description', e.target.value)}
|
|
|
|
|
|
|
|
disabled={isCanEditable}
|
|
|
|
/>
|
|
|
|
/>
|
|
|
|
</Form.Item>
|
|
|
|
</Form.Item>
|
|
|
|
{/* </Card> */}
|
|
|
|
{/* </Card> */}
|
|
|
@ -956,145 +1107,159 @@ function Detail() {
|
|
|
|
dataSource={quotation}
|
|
|
|
dataSource={quotation}
|
|
|
|
columns={columns}
|
|
|
|
columns={columns}
|
|
|
|
rowClassName="editable-row"
|
|
|
|
rowClassName="editable-row"
|
|
|
|
pagination={{ onChange: cancel }}
|
|
|
|
// pagination={{ onChange: cancel }}
|
|
|
|
/>
|
|
|
|
/>
|
|
|
|
<Button onClick={handleAdd} type="primary" style={{ marginBottom: 16 }}>
|
|
|
|
{
|
|
|
|
|
|
|
|
!isCanEditable &&
|
|
|
|
|
|
|
|
<Button onClick={handleAdd} type="primary" style={{ marginTop: 16 }}>
|
|
|
|
{t('products:addQuotation')}
|
|
|
|
{t('products:addQuotation')}
|
|
|
|
</Button>
|
|
|
|
</Button>
|
|
|
|
|
|
|
|
}
|
|
|
|
<Button onClick={handleBatchImport} type="primary" style={{ marginBottom: 16 }}>批量添加</Button>
|
|
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
!isCanEditable &&
|
|
|
|
|
|
|
|
<Button onClick={handleBatchImport} type="primary" style={{ marginTop: 16, marginLeft: 16 }}>批量添加</Button>
|
|
|
|
|
|
|
|
}
|
|
|
|
</Form.Item>
|
|
|
|
</Form.Item>
|
|
|
|
|
|
|
|
|
|
|
|
<Button type="primary" htmlType="submit" style={{ marginTop: 16, float: "right", marginRight: "20%" }}>
|
|
|
|
<Button type="primary" htmlType="submit" style={{ marginTop: 16, float: "right", marginRight: "20%" }}>
|
|
|
|
{t('Save')}
|
|
|
|
{t('Save')}
|
|
|
|
</Button>
|
|
|
|
</Button>
|
|
|
|
<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%" }}> */}
|
|
|
|
{/* <Card style={{ width: "80%" }}> */}
|
|
|
|
<Extras productId={2} />
|
|
|
|
<Extras productId={2} />
|
|
|
|
{/* </Card> */}
|
|
|
|
{/* </Card> */}
|
|
|
|
<FloatButton icon={<PlusCircleFilled />} onClick={() => setAddProductVisible(true)} />
|
|
|
|
|
|
|
|
</Col>
|
|
|
|
|
|
|
|
</Row>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
{/* <FloatButton icon={<PlusCircleFilled />} onClick={() => setAddProductVisible(true)} /> */}
|
|
|
|
(
|
|
|
|
|
|
|
|
<Modal
|
|
|
|
|
|
|
|
title="批量添加价格"
|
|
|
|
|
|
|
|
visible={batchImportPriceVisible}
|
|
|
|
|
|
|
|
onOk={handleBatchImportOK}
|
|
|
|
|
|
|
|
onCancel={() => setBatchImportPriceVisible(false)}
|
|
|
|
|
|
|
|
width="80%"
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
<BatchImportPrice onBatchImportData={handleBatchImportData} />
|
|
|
|
|
|
|
|
</Modal>
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
<FloatButton.Group
|
|
|
|
(
|
|
|
|
trigger="hover"
|
|
|
|
<Modal
|
|
|
|
type="primary"
|
|
|
|
title="增加新产品"
|
|
|
|
style={{ right: 80 }}
|
|
|
|
visible={addProductVisible}
|
|
|
|
icon={<PlusCircleFilled />}
|
|
|
|
onOk={handelAddProduct}
|
|
|
|
|
|
|
|
onCancel={() => setAddProductVisible(false)}
|
|
|
|
|
|
|
|
>
|
|
|
|
>
|
|
|
|
<h4>选择产品类别</h4>
|
|
|
|
<Tooltip title="增加产品">
|
|
|
|
|
|
|
|
<FloatButton icon={<FileAddOutlined />} onClick={() => setAddProductVisible(true)} />
|
|
|
|
<Select style={{ width: "50%" }}
|
|
|
|
</Tooltip>
|
|
|
|
value={addProductType}
|
|
|
|
<Tooltip title="提交审核">
|
|
|
|
onChange={(value) => setAddProductType(value)}
|
|
|
|
<FloatButton icon={<ExportOutlined />} onClick={async () => {
|
|
|
|
>
|
|
|
|
const formData = new FormData();
|
|
|
|
{productsTypes.map((item) => (
|
|
|
|
formData.append('use_year', use_year);
|
|
|
|
<Select.Option key={item.key} value={item.value}>
|
|
|
|
formData.append('travel_agency_id', travel_agency_id);
|
|
|
|
{item.label}
|
|
|
|
const { errcode, result } = await postForm(`${HT_HOST}/Service_BaseInfoWeb/agency_submit`, formData);
|
|
|
|
</Select.Option>
|
|
|
|
console.log("errcode", errcode);
|
|
|
|
))}
|
|
|
|
console.log("result", result);
|
|
|
|
</Select>
|
|
|
|
}} />
|
|
|
|
|
|
|
|
</Tooltip>
|
|
|
|
<h4>新增产品名称</h4>
|
|
|
|
</FloatButton.Group>
|
|
|
|
<Input
|
|
|
|
</Col>
|
|
|
|
value={addproductName}
|
|
|
|
</Row>
|
|
|
|
onChange={(e) => setAddProductName(e.target.value)}
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
</Modal>
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
<Modal
|
|
|
|
(
|
|
|
|
title="批量添加价格"
|
|
|
|
<Modal
|
|
|
|
visible={batchImportPriceVisible}
|
|
|
|
title="编辑供应商报价"
|
|
|
|
onOk={handleBatchImportOK}
|
|
|
|
visible={quotationTableVisible}
|
|
|
|
onCancel={() => setBatchImportPriceVisible(false)}
|
|
|
|
onOk={quotationTableVisibleOK}
|
|
|
|
width="80%"
|
|
|
|
onCancel={quotationTableVisibleCancel}
|
|
|
|
>
|
|
|
|
>
|
|
|
|
<BatchImportPrice onBatchImportData={handleBatchImportData} />
|
|
|
|
<h3>成人价</h3>
|
|
|
|
</Modal>
|
|
|
|
<InputNumber value={currentQuotationRecord.adult_cost} onChange={(e) => setCurrentQuotationRecord({ ...currentQuotationRecord, adult_cost: e })} />
|
|
|
|
|
|
|
|
<h3>儿童价</h3>
|
|
|
|
<Modal
|
|
|
|
<InputNumber value={currentQuotationRecord.child_cost} onChange={(e) => setCurrentQuotationRecord({ ...currentQuotationRecord, child_cost: e })} />
|
|
|
|
title="增加新产品"
|
|
|
|
<h3>币种</h3>
|
|
|
|
visible={addProductVisible}
|
|
|
|
<Select style={{ width: "30%" }} value={currentQuotationRecord.currency} onChange={(e) => setCurrentQuotationRecord({ ...currentQuotationRecord, currency: e })}>
|
|
|
|
onOk={handelAddProduct}
|
|
|
|
<Select.Option value="rmb">rmb</Select.Option>
|
|
|
|
onCancel={() => setAddProductVisible(false)}
|
|
|
|
<Select.Option value="usd">usd</Select.Option>
|
|
|
|
>
|
|
|
|
</Select >
|
|
|
|
<h4>选择产品类别</h4>
|
|
|
|
<h3>类型</h3>
|
|
|
|
|
|
|
|
<Select style={{ width: "30%" }} value={currentQuotationRecord.unit} onChange={(e) => setCurrentQuotationRecord({ ...currentQuotationRecord, unit: e })}>
|
|
|
|
<Select style={{ width: "50%" }}
|
|
|
|
<Select.Option value="0">每人</Select.Option>
|
|
|
|
value={addProductType}
|
|
|
|
<Select.Option value="1">每团</Select.Option>
|
|
|
|
onChange={(value) => setAddProductType(value)}
|
|
|
|
</Select>
|
|
|
|
>
|
|
|
|
|
|
|
|
{productsTypes.map((item) => (
|
|
|
|
<h3>人等</h3>
|
|
|
|
<Select.Option key={item.key} value={item.value}>
|
|
|
|
<td style={{ display: 'flex', alignItems: 'center' }}>
|
|
|
|
{item.label}
|
|
|
|
<InputNumber
|
|
|
|
</Select.Option>
|
|
|
|
min={0}
|
|
|
|
))}
|
|
|
|
value={currentQuotationRecord.group_size_min}
|
|
|
|
</Select>
|
|
|
|
onChange={(e) => setCurrentQuotationRecord({ ...currentQuotationRecord, group_size_min: e })}
|
|
|
|
|
|
|
|
style={{ width: '50%', marginRight: '10px' }}
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
<span>-</span>
|
|
|
|
|
|
|
|
<InputNumber
|
|
|
|
|
|
|
|
min={0}
|
|
|
|
|
|
|
|
value={currentQuotationRecord.group_size_max}
|
|
|
|
|
|
|
|
onChange={(e) => setCurrentQuotationRecord({ ...currentQuotationRecord, group_size_max: e })}
|
|
|
|
|
|
|
|
style={{ width: '50%', marginLeft: '10px' }}
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
</td>
|
|
|
|
|
|
|
|
<h3>有效期</h3>
|
|
|
|
|
|
|
|
<RangePicker
|
|
|
|
|
|
|
|
allowClear={true}
|
|
|
|
|
|
|
|
inputReadOnly={true}
|
|
|
|
|
|
|
|
presets={presets}
|
|
|
|
|
|
|
|
placeholder={['From', 'Thru']}
|
|
|
|
|
|
|
|
value={startDate && endDate ? [startDate, endDate] : null}
|
|
|
|
|
|
|
|
onChange={(dates) => {
|
|
|
|
|
|
|
|
setCurrentQuotationRecord({
|
|
|
|
|
|
|
|
...currentQuotationRecord,
|
|
|
|
|
|
|
|
use_dates_start: dates[0],
|
|
|
|
|
|
|
|
use_dates_end: dates[1]
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
}}
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
<h3>周末</h3>
|
|
|
|
|
|
|
|
{days.map((day, index) => (
|
|
|
|
|
|
|
|
<Button
|
|
|
|
|
|
|
|
key={index}
|
|
|
|
|
|
|
|
type={selectedDays.includes((index % 7) + 1) ? 'primary' : 'default'}
|
|
|
|
|
|
|
|
onClick={() => handleDayClick(index)}
|
|
|
|
|
|
|
|
style={{ margin: '5px' }}
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
{day}
|
|
|
|
|
|
|
|
</Button>
|
|
|
|
|
|
|
|
))}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
</Modal>
|
|
|
|
<h4>新增产品名称</h4>
|
|
|
|
|
|
|
|
<Input
|
|
|
|
|
|
|
|
value={addproductName}
|
|
|
|
|
|
|
|
onChange={(e) => setAddProductName(e.target.value)}
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
</Modal>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<Modal
|
|
|
|
|
|
|
|
title="编辑供应商报价"
|
|
|
|
|
|
|
|
visible={quotationTableVisible}
|
|
|
|
|
|
|
|
onOk={quotationTableVisibleOK}
|
|
|
|
|
|
|
|
onCancel={quotationTableVisibleCancel}
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
<h3>成人价</h3>
|
|
|
|
|
|
|
|
<InputNumber value={currentQuotationRecord.adult_cost} onChange={(e) => setCurrentQuotationRecord({ ...currentQuotationRecord, adult_cost: e })} />
|
|
|
|
|
|
|
|
<h3>儿童价</h3>
|
|
|
|
|
|
|
|
<InputNumber value={currentQuotationRecord.child_cost} onChange={(e) => setCurrentQuotationRecord({ ...currentQuotationRecord, child_cost: e })} />
|
|
|
|
|
|
|
|
<h3>币种</h3>
|
|
|
|
|
|
|
|
<Select style={{ width: "30%" }} value={currentQuotationRecord.currency} onChange={(e) => setCurrentQuotationRecord({ ...currentQuotationRecord, currency: e })}>
|
|
|
|
|
|
|
|
<Select.Option value="rmb">rmb</Select.Option>
|
|
|
|
|
|
|
|
<Select.Option value="usd">usd</Select.Option>
|
|
|
|
|
|
|
|
</Select >
|
|
|
|
|
|
|
|
<h3>类型</h3>
|
|
|
|
|
|
|
|
<Select style={{ width: "30%" }} value={currentQuotationRecord.unit} onChange={(e) => setCurrentQuotationRecord({ ...currentQuotationRecord, unit: e })}>
|
|
|
|
|
|
|
|
<Select.Option value="0">每人</Select.Option>
|
|
|
|
|
|
|
|
<Select.Option value="1">每团</Select.Option>
|
|
|
|
|
|
|
|
</Select>
|
|
|
|
|
|
|
|
|
|
|
|
)
|
|
|
|
<h3>人等</h3>
|
|
|
|
}
|
|
|
|
<td style={{ display: 'flex', alignItems: 'center' }}>
|
|
|
|
|
|
|
|
<InputNumber
|
|
|
|
|
|
|
|
min={0}
|
|
|
|
|
|
|
|
value={currentQuotationRecord.group_size_min}
|
|
|
|
|
|
|
|
onChange={(e) => setCurrentQuotationRecord({ ...currentQuotationRecord, group_size_min: e })}
|
|
|
|
|
|
|
|
style={{ width: '50%', marginRight: '10px' }}
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
<span>-</span>
|
|
|
|
|
|
|
|
<InputNumber
|
|
|
|
|
|
|
|
min={0}
|
|
|
|
|
|
|
|
value={currentQuotationRecord.group_size_max}
|
|
|
|
|
|
|
|
onChange={(e) => setCurrentQuotationRecord({ ...currentQuotationRecord, group_size_max: e })}
|
|
|
|
|
|
|
|
style={{ width: '50%', marginLeft: '10px' }}
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
</td>
|
|
|
|
|
|
|
|
<h3>有效期</h3>
|
|
|
|
|
|
|
|
<RangePicker
|
|
|
|
|
|
|
|
allowClear={true}
|
|
|
|
|
|
|
|
inputReadOnly={true}
|
|
|
|
|
|
|
|
presets={presets}
|
|
|
|
|
|
|
|
placeholder={['From', 'Thru']}
|
|
|
|
|
|
|
|
value={startDate && endDate ? [startDate, endDate] : null}
|
|
|
|
|
|
|
|
onChange={(dates) => {
|
|
|
|
|
|
|
|
setCurrentQuotationRecord({
|
|
|
|
|
|
|
|
...currentQuotationRecord,
|
|
|
|
|
|
|
|
use_dates_start: dates[0],
|
|
|
|
|
|
|
|
use_dates_end: dates[1]
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
}}
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
<h3>周末</h3>
|
|
|
|
|
|
|
|
{days.map((day, index) => (
|
|
|
|
|
|
|
|
<Button
|
|
|
|
|
|
|
|
key={index}
|
|
|
|
|
|
|
|
type={selectedDays.includes((index % 7) + 1) ? 'primary' : 'default'}
|
|
|
|
|
|
|
|
onClick={() => handleDayClick(index)}
|
|
|
|
|
|
|
|
style={{ margin: '5px' }}
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
{day}
|
|
|
|
|
|
|
|
</Button>
|
|
|
|
|
|
|
|
))}
|
|
|
|
|
|
|
|
</Modal>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</Spin>
|
|
|
|
</Spin>
|
|
|
|
);
|
|
|
|
);
|
|
|
|