Merge remote-tracking branch 'origin/main'

perf/export-docx
Lei OT 11 months ago
commit 09091eaff5

@ -15,7 +15,7 @@ import VendorSelector from '@/components/VendorSelector';
const { RangePicker } = DatePicker; const { RangePicker } = DatePicker;
const SearchForm = ({ initialValue, onSubmit, onReset, confirmText, formName, formLayout, loading, ...props }) => { const SearchForm = ({ initialValue, onSubmit, onReset, onMounted, confirmText, formName, formLayout, loading, ...props }) => {
const { t } = useTranslation(); const { t } = useTranslation();
const presets = useDatePresets(); const presets = useDatePresets();
const [formValues, setFormValues] = useFormStore((state) => [state.formValues, state.setFormValues]); const [formValues, setFormValues] = useFormStore((state) => [state.formValues, state.setFormValues]);
@ -89,8 +89,14 @@ const SearchForm = ({ initialValue, onSubmit, onReset, confirmText, formName, fo
}; };
useEffect(() => { useEffect(() => {
const dest = formValuesMapper(formValues); setFormValues(readValues);
const dest = formValuesMapper(readValues);
setFormValuesToSub(dest); setFormValuesToSub(dest);
if (typeof onMounted === 'function') {
onMounted(dest)
}
return () => {}; return () => {};
}, []); }, []);

@ -95,6 +95,11 @@ export const postProductsAuditAction = async (auditState, infoRow) => {
// return errcode !== 0 ? {} : result; // return errcode !== 0 ? {} : result;
}; };
export const postProductsSave = async (products) => {
const { errcode, result } = await postJSON(`${HT_HOST}/Service_BaseInfoWeb/agency_product_save`, products);
return { errcode, result };
}
const initialState = { const initialState = {
loading: false, loading: false,
searchValues: {}, searchValues: {},

@ -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>
); );

@ -96,7 +96,6 @@ function Newest() {
const [guideSelectOptions, setGuideSelectOptions] = useState([]) const [guideSelectOptions, setGuideSelectOptions] = useState([])
const formValuesToSub = useFormStore((state) => state.formValuesToSub) const formValuesToSub = useFormStore((state) => state.formValuesToSub)
const [fetchAllGuideList, fetchReservationList, reservationList, reservationPage, cityList, selectReservation, getCityListByReservationId, setupCityGuide, updateReservationGuide] = const [fetchAllGuideList, fetchReservationList, reservationList, reservationPage, cityList, selectReservation, getCityListByReservationId, setupCityGuide, updateReservationGuide] =
useReservationStore((state) => useReservationStore((state) =>
[state.fetchAllGuideList, state.fetchReservationList, state.reservationList, state.reservationPage, state.cityList, state.selectReservation, state.getCityListByReservationId, state.setupCityGuide, state.updateReservationGuide]) [state.fetchAllGuideList, state.fetchReservationList, state.reservationList, state.reservationPage, state.cityList, state.selectReservation, state.getCityListByReservationId, state.setupCityGuide, state.updateReservationGuide])
@ -104,13 +103,9 @@ function Newest() {
const { notification } = App.useApp() const { notification } = App.useApp()
useEffect (() => { useEffect (() => {
if (location.search !== '?back') {
//
onSearchClick(1, 1)
}
fetchAllGuideList() fetchAllGuideList()
.then((guideList) => { .then((guideList) => {
const selectOptions = guideList.map((data, index) => { const selectOptions = guideList.map((data) => {
return { return {
value: data.guideId, value: data.guideId,
label: data.guideName label: data.guideName
@ -137,6 +132,7 @@ function Newest() {
setDataLoading(false); setDataLoading(false);
}) })
} }
const handleOk = () => { const handleOk = () => {
updateReservationGuide() updateReservationGuide()
.finally(() => { .finally(() => {
@ -144,15 +140,18 @@ function Newest() {
setDataLoading(false); setDataLoading(false);
}) })
} }
const handleCancel = () => { const handleCancel = () => {
setIsModalOpen(false); setIsModalOpen(false);
setDataLoading(false); setDataLoading(false);
} }
// //
const onSearchClick = (current=1, status=null) => { const searchReservation = (submitValues, current=1) => {
setDataLoading(true) setDataLoading(true)
fetchReservationList(formValuesToSub, current) console.info('onSearchClick')
console.info(submitValues)
fetchReservationList(submitValues, current)
.catch(ex => { .catch(ex => {
notification.error({ notification.error({
message: `Notification`, message: `Notification`,
@ -208,20 +207,11 @@ function Newest() {
dates: { label: t('group:ArrivalDate') }, dates: { label: t('group:ArrivalDate') },
}, },
}} }}
onSubmit={(err, formVal, filedsVal) => { onMounted={(initialValue) => {
setDataLoading(true) searchReservation(initialValue)
fetchReservationList(formVal) }}
.catch(ex => { onSubmit={() => {
notification.error({ searchReservation(formValuesToSub)
message: 'Notification',
description: ex.message,
placement: 'top',
duration: 4,
})
})
.finally(() => {
setDataLoading(false)
})
}} }}
/> />
<Title level={3}></Title> <Title level={3}></Title>
@ -238,7 +228,9 @@ function Newest() {
total: reservationPage.total, total: reservationPage.total,
simple: true simple: true
}} }}
onChange={(pagination) => {onSearchClick(pagination.current)}} onChange={(pagination) => {
searchReservation(formValuesToSub, pagination.current)
}}
columns={reservationListColumns} dataSource={reservationList} columns={reservationListColumns} dataSource={reservationList}
/> />
</Col> </Col>

Loading…
Cancel
Save