1.增加搜索框

2.动态显示产品项目信息
3.修改变量名
feature/price_manager
黄文强@HWQ-PC 1 year ago
parent 8fd197a3e0
commit ed651ff3d4

@ -1,7 +1,7 @@
import React, { useState } from 'react';
import { DatePicker, Button } from 'antd';
const DateComponent = ({ onDateChange }) => {
const Date = ({ onDateChange }) => {
const dateFormat = 'YYYY/MM/DD';
const { RangePicker } = DatePicker;
const [dateRange, setDateRange] = useState(null);
@ -48,4 +48,4 @@ const DateComponent = ({ onDateChange }) => {
);
};
export default DateComponent;
export default Date;

@ -2,7 +2,7 @@ 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 { Link } from 'react-router-dom';
import { useTranslation } from 'react-i18next';
import DateComponent from '@/components/date';
import Date from '@/components/date';
import { searchAgencyAction, getAgencyProductsAction } from '@/stores/Products/Index';
import { useProductsTypes } from '@/hooks/useProductsSets';
import Extras from './Detail/Extras';
@ -10,7 +10,7 @@ import { groupBy } from '@/utils/commons';
import { useParams } from 'react-router-dom';
import { useHTLanguageSets } from '@/hooks/useHTLanguageSets';
import { useDefaultLgc } from '@/i18n/LanguageSwitcher';
function Index() {
function Detail() {
const { t } = useTranslation();
const [form] = Form.useForm();
const [editingid, setEditingid] = useState('');
@ -33,6 +33,65 @@ function Index() {
const { travel_agency_id } = useParams();
const { language } = useDefaultLgc();
const HTLanguageSets = useHTLanguageSets();
const { Search } = Input;
const [expandedKeys, setExpandedKeys] = useState([]);
const [searchValue, setSearchValue] = useState('');
const [autoExpandParent, setAutoExpandParent] = useState(true);
const [dataList, setDataList] = useState([]);
const [defaultData, setDefaultData] = useState([]);
const productProject = {
"6": [],
"B": [
{ code: "code", name: t('products:Code') },
{ code: "city_name", name: t('products:City') },
{ code: "km", name: t('products:KM') },
{ code: "remarks", name: t('products:Remarks') }
],
"J": [
{ code: "code", name: t('products:Code') },
{ code: "city_name", name: t('products:City') },
{ code: "recommends_rate", name: t('products:recommendationRate') },
{ code: "duration", name: t('products:Duration') },
{ code: "dept_name", name: t('products:Dept') },
{ code: "display_to_c", name: t('products:DisplayToC') },
{ code: "remarks", name: t('products:Remarks') },
],
"Q": [
{ code: "code", name: t('products:Code') },
{ code: "city_name", name: t('products:City') },
{ code: "recommends_rate", name: t('products:recommendationRate') },
{ code: "duration", name: t('products:Duration') },
{ code: "dept_name", name: t('products:Dept') },
{ code: "display_to_c", name: t('products:DisplayToC') },
{ code: "remarks", name: t('products:Remarks') },
],
"D": [
{ code: "code", name: t('products:Code') },
{ code: "city_name", name: t('products:City') },
{ code: "recommends_rate", name: t('products:recommendationRate') },
{ code: "duration", name: t('products:Duration') },
{ code: "dept_name", name: t('products:Dept') },
{ code: "display_to_c", name: t('products:DisplayToC') },
{ code: "remarks", name: t('products:Remarks') },
],
"7": [
{ code: "code", name: t('products:Code') },
{ code: "city_name", name: t('products:City') },
{ code: "recommends_rate", name: t('products:recommendationRate') },
{ code: "duration", name: t('products:Duration') },
{ code: "open_weekdays", name: t('products:OpenWeekdays') },
{ code: "remarks", name: t('products:Remarks') },
],
"R": [
{ code: "code", name: t('products:Code') },
{ code: "city_name", name: t('products:City') },
]
}
const [selectedCategory, setSelectedCategory] = useState(productProject.B);
useEffect(() => {
setLanguageStatus(language);
@ -45,6 +104,8 @@ function Index() {
useEffect(() => {
const fetchData = async () => {
const a = { travel_agency_id };
const res = await getAgencyProductsAction(a);
@ -63,23 +124,94 @@ function Index() {
};
const treeData = generateTreeData(productsTypes, groupedProducts);
setProductsData(groupedProducts);
console.log("treeData", treeData)
setTreeData1(treeData);
setProductsData(groupedProducts);
setDefaultData(treeData);
setDataList(flattenTreeData(treeData));
};
useEffect(() => {
fetchData();
}, [productsTypes]);
const flattenTreeData = (tree) => {
let flatList = [];
const flatten = (nodes) => {
nodes.forEach((node) => {
flatList.push({ title: node.title, key: node.key });
if (node.children) {
flatten(node.children);
}
});
};
flatten(tree);
return flatList;
};
const getParentKey = (key, tree) => {
let parentKey;
for (let i = 0; i < tree.length; i++) {
const node = tree[i];
if (node.children) {
if (node.children.some((item) => item.key === key)) {
parentKey = node.key;
} else {
const pKey = getParentKey(key, node.children);
if (pKey) {
parentKey = pKey;
}
}
}
}
return parentKey;
};
const titleRender = (node) => {
const index = node.title.indexOf(searchValue);
const beforeStr = node.title.substr(0, index);
const afterStr = node.title.substr(index + searchValue.length);
const highlighted = (
<span style={{ color: 'red' }}>{searchValue}</span>
);
return index > -1 ? (
<span>
{beforeStr}
{highlighted}
{afterStr}
</span>
) : (
<span>{node.title}</span>
);
};
const onChange = (e) => {
const { value } = e.target;
const newExpandedKeys = dataList
.filter(item => item.title.includes(value))
.map(item => getParentKey(item.key, defaultData))
.filter((item, i, self) => item && self.indexOf(item) === i);
console.log("newExpandedKeys", newExpandedKeys)
setExpandedKeys(newExpandedKeys);
setSearchValue(value);
setAutoExpandParent(true);
};
const onExpand = (keys) => {
setExpandedKeys(keys);
setAutoExpandParent(false);
};
// const productProject = [
// { code: "code", name: t('products:Code') },
// { code: "city_name", name: t('products:City') },
// { code: "remarks", name: t('products:Remarks') },
// { code: "open_hours", name: t('products:tourTime') },
// { code: "recommends_rate", name: t('products:recommendationRate') }
// ];
const productProject = [
{ code: "code", name: t('products:Code') },
{ code: "city_name", name: t('products:City') },
{ code: "remarks", name: t('products:Remarks') },
{ code: "open_hours", name: t('products:tourTime') },
{ code: "recommends_rate", name: t('products:recommendationRate') }
];
const isEditing = (record) => record.id === editingid;
@ -355,15 +487,6 @@ function Index() {
console.log("handleTagChange", value)
setSelectedTag(value);
console.log("setSelectedTag", selectedTag)
// setLanguageStatus()
// if (!tags.includes(value)) {
// setTags([...tags, value]);
// setLanguageStatus([...languageStatus, { [value]: { title: "", descriptions: "" } }]);
// }
// setSelectedTag(value);
// setIsModalVisible(false);
};
const handleChange = (field, value) => {
@ -379,19 +502,14 @@ function Index() {
};
const findLanguageDetails = (tag) => {
const lang = languageStatus.find(lang => lang[tag]);
return lang ? lang[tag] : { title: "", descriptions: "" };
};
//
const handleNodeSelect = (_, { node }) => {
setTags([languageLabel])
//
if (selectedNodeid === node.key) return;
const fatherKey = node.key.split('-')[0];
console.log("fatherKey", fatherKey)
setSelectedCategory(productProject[fatherKey])
let initialQuotationData = null;
let infoData = null;
let lgcDetailsData = null;
@ -404,6 +522,8 @@ function Index() {
}
});
console.log("infoData", infoData)
// lgc_details
let newLgcDetails = {};
lgcDetailsData.forEach(element => {
@ -426,7 +546,10 @@ function Index() {
remarks: infoData.remarks,
open_weekdays: infoData.open_weekdays,
recommends_rate: infoData.recommends_rate,
unit_name: infoData.unit_name
duration: infoData.duration,
dept: infoData.dept,
km: infoData.km,
dept_name: infoData.dept_name
},
lgc_details: {
title: newLgcDetails[language]?.title || '',
@ -450,182 +573,28 @@ function Index() {
};
//
const initBindingData = [
{ id: '1', title: '英文导游', value: "100", age_type: '每人' },
{ id: '2', title: '中文导游', value: "200", age_type: '每团' },
{ id: '3', title: '可陪餐费', value: "400", age_type: '每人' },
]
const [bindingData, setBindingData] = useState(initBindingData);
const isEditingBinding = (record) => record.id === editingidBinding;
const [editingidBinding, setEditingidBinding] = useState('');
const editBinding = (record) => {
form.setFieldsValue({ ...record });
setEditingidBinding(record.id);
};
const cancelBinding = () => {
setEditingidBinding('');
};
const EditableCellBinding = ({
editing,
dataIndex,
title,
inputType,
record,
index,
children,
...restProps
}) => {
let inputNode = inputType === 'number' ? <InputNumber /> : <Input />;
if (dataIndex === 'unit_name' && editing) {
inputNode = (
<Select>
<Select.Option value="每人">每人</Select.Option>
<Select.Option value="每团">每团</Select.Option>
</Select>
);
}
return (
<td {...restProps}>
{editing ? (
<Form.Item
name={dataIndex}
style={{ margin: 0 }}
rules={[{ required: true, message: `请输入${title}` }]}
>
{inputNode}
</Form.Item>
) : (
children
)}
</td>
);
};
const bindingColums = [
{ title: t('products:Name'), dataIndex: 'title', width: '25%', editable: true },
{ title: t('products:price'), dataIndex: 'value', width: '25%', editable: true },
{ title: t('products:Types'), dataIndex: 'age_type', width: '25%', editable: true },
{
title: t('products:operation'),
dataIndex: 'operation',
render: (_, record) => {
const editable = isEditingBinding(record);
return editable ? (
<span>
<a href="#!" onClick={() => handleSaveBinding(record.id)} style={{ marginRight: 8 }}>{t('products:save')}</a>
<Popconfirm title={t('products:sureCancel')} onConfirm={cancelBinding}><a>{t('products:cancel')}</a></Popconfirm>
</span>
) : (
<span>
<a disabled={editingidBinding !== ''} onClick={() => editBinding(record)} style={{ marginRight: 8 }}>{t('products:edit')}</a>
<Popconfirm title={t('products:sureDelete')} onConfirm={() => handleDeleteBinding(record.id)}>
<a>{t('products:delete')}</a>
</Popconfirm>
</span>
);
},
},
].map(col => {
if (!col.editable) {
return col;
}
return {
...col,
onCell: record => ({
record,
inputType: col.dataIndex === 'value' ? 'number' : 'text',
dataIndex: col.dataIndex,
title: col.title,
editing: isEditingBinding(record),
}),
};
});
const handleAddBinding = () => {
const newData = {
id: `${bindingData.length + 1}`,
title: '',
value: '',
age_type: '',
};
setBindingData([...bindingData, newData]);
setEditingidBinding(''); //
};
//Effect
const handleSaveBinding = async (id) => {
try {
const row = await form.validateFields();
const newData = [...bindingData];
const { value, title, age_type } = row
const index = newData.findIndex((item) => id === item.id);
if (index > -1) {
const item = newData[index];
newData.splice(index, 1, { ...item, value, title, age_type });
setBindingData(newData);
setEditingidBinding('');
} else {
newData.push(row);
setBindingData(newData);
setEditingidBinding('');
}
} catch (errInfo) {
console.log('Validate Failed:', errInfo);
}
};
const handleDeleteBinding = (id) => {
const newData = [...bindingData];
const index = newData.findIndex((item) => id === item.id);
newData.splice(index, 1);
setBindingData(newData);
};
const componentsBinding = {
body: {
cell: EditableCellBinding,
},
};
const treeData = [
{
title: '综费',
// id: 'zf',
selectable: false,
children: [{ title: '北京怡然假日', id: 'bjyrjr' }]
},
{
title: '车费',
// id: 'cf',
selectable: false,
children: [
{ title: '北京', id: 'bj' },
{ title: '天津', id: 'tj' },
{ title: '北京-天津', id: 'bj-tj-3-5' }
]
}
]
//Effect
useEffect(() => {
if (saveData) {
}
}, [saveData]);
return (
<div>
<Row>
<Col span={6}>
<Card style={{ width: "20%", position: "fixed", maxHeight: "80vh", overflowY: "auto" }}>
<Search style={{ marginBottom: 8 }} placeholder="Search" onChange={onChange} />
<Tree
onSelect={handleNodeSelect}
treeData={treeData1}
expandedKeys={expandedKeys}
autoExpandParent={autoExpandParent}
onExpand={onExpand}
titleRender={titleRender}
/>
</Card>
</Col>
@ -644,14 +613,18 @@ function Index() {
>
<h2>{t('products:productProject')}</h2>
<Row gutter={16}>
{productProject.map((item, index) => (
{selectedCategory.map((item, index) => (
<Col span={8} id={index}>
<Form.Item name={['info', item.code]} label={item.name}>
{item.code === "duration" ? (
<Input suffix="H"/>
) : (
<Input />
)}
</Form.Item>
</Col>
))}
</Row>
</Row>duration
<Card title={
<div>
@ -720,20 +693,6 @@ function Index() {
</Card>
<Card style={{ width: "80%" }}>
{/* <h2>{t('products:bindingProducts')}</h2>
<Form.Item name="extras">
<Table
components={componentsBinding}
bordered
dataSource={bindingData}
columns={bindingColums}
rowClassName="editable-row"
pagination={{ onChange: cancelBinding }}
/>
<Button onClick={handleAddBinding} type="primary" style={{ marginBottom: 16 }}>
{t('products:addBinding')}
</Button>
</Form.Item> */}
<Extras productId={2} />
</Card>
@ -755,12 +714,12 @@ function Index() {
onOk={handleDateOk}
onCancel={() => setDatePickerVisible(false)}
>
<DateComponent onDateChange={handleDateChange} />
<Date onDateChange={handleDateChange} />
</Modal>
)}
</div>
);
}
export default Index;
export default Detail;

Loading…
Cancel
Save