产品编辑页面: 组件 info, form, lgc

perf/export-docx
Lei OT 1 year ago
parent 2a193f9955
commit a63887a7b6

@ -101,16 +101,17 @@ export const useProductsAuditStatesMapVal = (value) => {
export const useProductsTypesFieldsets = (type) => { export const useProductsTypesFieldsets = (type) => {
const [isPermitted] = useAuthStore((state) => [state.isPermitted]); const [isPermitted] = useAuthStore((state) => [state.isPermitted]);
const infoDefault = [['code'], ['title']]; const infoDefault = [['code'], ['title']];
const infoAdmin = ['remarks', 'dept', ]; // 'display_to_c' const infoAdmin = ['remarks', 'dept']; // 'display_to_c'
const infoDisplay = isPermitted(PERM_PRODUCTS_MANAGEMENT) ? ['display_to_c'] : [];
const infoTypesMap = { const infoTypesMap = {
'6': [['city',],[]], '6': [['city'], []],
'B': [['city', 'km'], []], 'B': [['city', 'km'], []],
'J': [['city', 'recommends_rate', 'duration', 'display_to_c'], ['description',]], 'J': [['city', 'recommends_rate', 'duration', ...infoDisplay], ['description']],
'Q': [['city', 'recommends_rate', 'duration', 'display_to_c'], ['description',]], 'Q': [['city', 'recommends_rate', 'duration', ...infoDisplay], ['description']],
'D': [['city', 'recommends_rate','duration', 'display_to_c'], ['description',]], 'D': [['city', 'recommends_rate', 'duration', ...infoDisplay], ['description']],
'7': [['city', 'recommends_rate', 'duration', 'display_to_c', 'open_weekdays'], ['description',]], '7': [['city', 'recommends_rate', 'duration', ...infoDisplay, 'open_weekdays'], ['description']],
'R': [['city',], ['description',]], 'R': [['city'], ['description']],
'8': [['display_to_c'],[]], // todo: ? '8': [[...infoDisplay], []],
}; };
const thisTypeFieldset = (_type) => { const thisTypeFieldset = (_type) => {
if (isEmpty(_type)) { if (isEmpty(_type)) {
@ -119,8 +120,62 @@ export const useProductsTypesFieldsets = (type) => {
const adminSet = isPermitted(PERM_PRODUCTS_MANAGEMENT) ? infoAdmin : []; const adminSet = isPermitted(PERM_PRODUCTS_MANAGEMENT) ? infoAdmin : [];
return [ return [
[...infoDefault[0], ...infoTypesMap[_type][0], ...adminSet], [...infoDefault[0], ...infoTypesMap[_type][0], ...adminSet],
[...infoDefault[1], ...infoTypesMap[_type][1]] [...infoDefault[1], ...infoTypesMap[_type][1]],
]; ];
}; };
return thisTypeFieldset(type); return thisTypeFieldset(type);
} };
export const useNewProductRecord = () => {
return {
info: {
'id': null,
'title': '',
'code': '',
'product_type_id': '',
'product_type_name': '',
'remarks': '',
'duration': 0,
'duration_unit': 'h',
'open_weekdays': '',
'recommends_rate': 0,
'dept_id': 0,
'dept_name': '',
'display_to_c': 0,
'km': 0,
'city_id': 0,
'city_name': '',
},
default_lgc: {
'title': '',
'description': '',
'lgc': 1,
'id': null,
},
default_quotation: {
'id': null,
'adult_cost': 0,
'child_cost': 0,
'currency': 'CNY',
'unit_id': '1',
'unit_name': '每团',
'group_size_min': 1,
'group_size_max': 2,
'use_dates_start': '',
'use_dates_end': '',
'weekdays': '',
'audit_state_id': -1,
'audit_state_name': '',
'lastedit_changed': '',
},
lgc_details: [
{
'title': '',
'description': '',
'lgc': 1,
'id': null,
},
],
quotation: [],
};
};

@ -107,6 +107,7 @@ const initialState = {
activeAgency: {}, // 审核/编辑 页: 当前的供应商 activeAgency: {}, // 审核/编辑 页: 当前的供应商
agencyProducts: {}, // 审核/编辑 页: 供应商产品列表 agencyProducts: {}, // 审核/编辑 页: 供应商产品列表
editingProduct: {}, // 编辑页: 当前编辑的产品 editingProduct: {}, // 编辑页: 当前编辑的产品
editing: false,
}; };
export const useProductsStore = create( export const useProductsStore = create(
devtools((set, get) => ({ devtools((set, get) => ({
@ -120,6 +121,7 @@ export const useProductsStore = create(
setActiveAgency: (activeAgency) => set({ activeAgency }), setActiveAgency: (activeAgency) => set({ activeAgency }),
setAgencyProducts: (agencyProducts) => set({ agencyProducts }), setAgencyProducts: (agencyProducts) => set({ agencyProducts }),
setEditingProduct: (editingProduct) => set({ editingProduct }), setEditingProduct: (editingProduct) => set({ editingProduct }),
setEditing: (editing) => set({ editing }),
reset: () => set(initialState), reset: () => set(initialState),

@ -135,7 +135,7 @@ const TypesPanels = (props) => {
.map((w) => t(`weekdaysShort.${w}`)) .map((w) => t(`weekdaysShort.${w}`))
.join(', '), .join(', '),
info: c.info, info: c.info,
lgc_details: c.lgc_details.reduce((rlgc, clgc) => ({...r, [clgc.lgc]: clgc}), {}), lgc_details: c.lgc_details.reduce((rlgc, clgc) => ({...rlgc, [clgc.lgc]: clgc}), {}),
rowSpan: i === 0 ? c.quotation.length : 0, rowSpan: i === 0 ? c.quotation.length : 0,
rowSpanI: [ri, i], rowSpanI: [ri, i],
})) }))

@ -2,7 +2,7 @@ import React, { useState, useEffect } from 'react';
import { Tooltip, Button, Card, Col, Row, Breadcrumb, Table, Popconfirm, Form, Input, InputNumber, Tag, Modal, Select, Tree, FloatButton, DatePicker, Spin, message, Divider,Empty, Flex } from 'antd'; import { Tooltip, Button, Card, Col, Row, Breadcrumb, Table, Popconfirm, Form, Input, InputNumber, Tag, Modal, Select, Tree, FloatButton, DatePicker, Spin, message, Divider,Empty, Flex } from 'antd';
import { Link, useNavigate } from 'react-router-dom'; import { Link, useNavigate } from 'react-router-dom';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { useProductsTypes, useProductsAuditStatesMapVal, useProductsTypesMapVal } from '@/hooks/useProductsSets'; import { useProductsTypes, useProductsAuditStatesMapVal, useProductsTypesMapVal, useNewProductRecord } from '@/hooks/useProductsSets';
import Extras from './Detail/Extras'; import Extras from './Detail/Extras';
import { isEmpty } from '@/utils/commons'; import { isEmpty } from '@/utils/commons';
import SecondHeaderWrapper from '@/components/SecondHeaderWrapper'; import SecondHeaderWrapper from '@/components/SecondHeaderWrapper';
@ -860,12 +860,20 @@ function Detail() {
}; };
// //
const handelAddProduct = () => { const newProduct = useNewProductRecord();
// const { language } = useDefaultLgc();
const handelAddProduct = () => {
// //
const productTypeNode = treeData.find(item => item.key === addProductType); // const productTypeNode = treeData.find(item => item.key === addProductType);
console.log("productTypeNode", productTypeNode) const copyNewProduct = structuredClone(newProduct);
// if (productTypeNode) { copyNewProduct.info.title = addproductName;
// // children copyNewProduct.info.product_type_id = productsTypesMapVal[addProductType].value;
copyNewProduct.info.product_type_name = productsTypesMapVal[addProductType].label;
copyNewProduct.lgc_details[0].lgc = language;
setEditingProduct(copyNewProduct);
setAddProductVisible(false);
// todo: , active
return false;
const tempAddData = { const tempAddData = {
info: { info: {
id: "", id: "",
@ -1065,12 +1073,12 @@ function Detail() {
// <YearSelector title={activeAgency.travel_agency_name} refresh={handleGetAgencyProducts} onStateChange={handleStateChange}/> // <YearSelector title={activeAgency.travel_agency_name} refresh={handleGetAgencyProducts} onStateChange={handleStateChange}/>
}> }>
{isEmpty(agencyProducts) ? <Empty /> : {isEmpty(agencyProducts) ? <Empty /> :
<div> <>
<Flex gap={10}> <Flex gap={10}>
{/* onNodeSelect={handleNodeSelect} */} {/* onNodeSelect={handleNodeSelect} */}
<ProductsTree className='basis-64 sticky top-16 overflow-y-auto shrink-0' style={{ height: 'calc(100vh - 150px)' }} /> <ProductsTree className='basis-64 sticky top-16 overflow-y-auto shrink-0' style={{ height: 'calc(100vh - 150px)' }} />
<Divider type={'vertical'} className='mx-1 h-auto' /> <Divider type={'vertical'} className='mx-1 h-auto' />
<div className=' flex-auto grow-0'> <div className=' flex-auto grow-0 min-w-[800px]'>
<ProductInfo /> <ProductInfo />
{/* <Row> */} {/* <Row> */}
{/* <Col span={6} className=' relative'> */} {/* <Col span={6} className=' relative'> */}
@ -1327,7 +1335,7 @@ function Detail() {
</Button> </Button>
))} ))}
</Modal> */} </Modal> */}
</div>} </>}
</SecondHeaderWrapper> </SecondHeaderWrapper>
); );
} }

@ -23,7 +23,7 @@ const Header = ({ refresh, ...props }) => {
const yearOptions = []; const yearOptions = [];
const currentYear = dayjs().year(); const currentYear = dayjs().year();
const baseYear = Number(use_year === 'all' ? currentYear : use_year); const baseYear = use_year ? Number(use_year === 'all' ? currentYear : use_year) : currentYear;
for (let i = baseYear - 3; i <= baseYear + 3; i++) { for (let i = baseYear - 3; i <= baseYear + 3; i++) {
yearOptions.push({ label: i, value: i }); yearOptions.push({ label: i, value: i });
} }
@ -40,7 +40,7 @@ const Header = ({ refresh, ...props }) => {
const emptyPickState = { value: '', label: t('products:State') }; const emptyPickState = { value: '', label: t('products:State') };
useEffect(() => { useEffect(() => {
const baseState = audit_state === 'all' ? emptyPickState : stateMapVal[`${audit_state}`]; const baseState = audit_state ? (audit_state === 'all' ? emptyPickState : stateMapVal[`${audit_state}`]) : emptyPickState;
if (isEmpty(pickAuditState)) { if (isEmpty(pickAuditState)) {
setPickAuditState(baseState); setPickAuditState(baseState);
} }

@ -2,193 +2,44 @@ import { createContext, useEffect, useState } from 'react';
import { Breadcrumb, Form, Divider, Button, Input, Select, Row, Col } from 'antd'; import { Breadcrumb, Form, Divider, Button, Input, Select, Row, Col } from 'antd';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { useProductsTypesMapVal, } from '@/hooks/useProductsSets'; import { useProductsTypesMapVal, } from '@/hooks/useProductsSets';
import useProductsStore from '@/stores/Products/Index'; import useProductsStore, { postProductsSave } from '@/stores/Products/Index';
import useAuthStore from '@/stores/Auth';
import RequireAuth from '@/components/RequireAuth'; import RequireAuth from '@/components/RequireAuth';
import { PERM_PRODUCTS_MANAGEMENT, PERM_PRODUCTS_OFFER_AUDIT, PERM_PRODUCTS_OFFER_PUT } from '@/config'; import { PERM_PRODUCTS_MANAGEMENT, PERM_PRODUCTS_OFFER_AUDIT, PERM_PRODUCTS_OFFER_PUT } from '@/config';
import DeptSelector from '@/components/DeptSelector'; import DeptSelector from '@/components/DeptSelector';
import CitySelector from '@/components/CitySelector'; import CitySelector from '@/components/CitySelector';
import { at, isEmpty } from '@/utils/commons'; import { at, isEmpty, pick } from '@/utils/commons';
import ProductInfoForm from './ProductInfoForm'; import ProductInfoForm from './ProductInfoForm';
const ProductInfo = ({ ...props }) => { const ProductInfo = ({ ...props }) => {
const { t } = useTranslation(); const { t } = useTranslation();
const [form] = Form.useForm(); const isPermitted = useAuthStore((state) => state.isPermitted);
const productsTypesMapVal = useProductsTypesMapVal(); const productsTypesMapVal = useProductsTypesMapVal();
const [agencyProducts, editingProduct, setEditingProduct] = useProductsStore((state) => [state.agencyProducts, state.editingProduct, state.setEditingProduct]); const [activeAgency, agencyProducts, editingProduct, setEditingProduct] = useProductsStore((state) => [state.activeAgency, state.agencyProducts, state.editingProduct, state.setEditingProduct]);
const [editable, setEditable] = useState(true);
useEffect(() => { useEffect(() => {
const notAudit = activeAgency.audit_state_id < 0 || activeAgency.audit_state_id === 3;
const hasAuditPer = isPermitted(PERM_PRODUCTS_OFFER_AUDIT);
const hasEditPer = isPermitted(PERM_PRODUCTS_OFFER_PUT);
setEditable(notAudit && hasEditPer);
// setEditable(true); // test: 0
return () => {};
}, [activeAgency, editingProduct])
return () => { const onSave = (err, values, forms) => {
values.travel_agency_id = activeAgency.travel_agency_id;
} const poster = {
}, [editingProduct]) "audit_state": "-1",
// "create_date": "",
// "created_by": "",
const productTypeFormItems = { "travel_agency_id": activeAgency.travel_agency_id,
'6': [ // "travel_agency_name": "",
{ key: 'code', name: t('products:Code'), nameKey: 'products:Code' }, // "lastedit_changed": "",
{ key: 'city_name', name: t('products:City'), nameKey: 'products:City' }, };
], const copyFields = pick(editingProduct.info, ['title', 'product_type_id', ]);
'B': [ const readyToSubInfo = {...values.info, ...copyFields, type: copyFields.product_type_id, ...poster };
{ key: 'code', name: t('products:Code'), nameKey: 'products:Code' }, console.log('onSave', editingProduct.info, readyToSubInfo);
{ key: 'city_name', name: t('products:City'), nameKey: 'products:City' },
{ key: 'km', name: t('products:KM'), nameKey: 'products:KM' },
{
key: 'remarks',
name: <RequireAuth subject={PERM_PRODUCTS_MANAGEMENT}>{t('products:Remarks')}</RequireAuth>,
nameKey: 'products:Remarks',
},
],
'J': [
{ key: 'code', name: t('products:Code'), nameKey: 'products:Code' },
{ key: 'city_name', name: t('products:City'), nameKey: 'products:City' },
{
key: 'recommends_rate',
name: <RequireAuth subject={PERM_PRODUCTS_MANAGEMENT}>{t('products:recommendationRate')}</RequireAuth>,
nameKey: 'products:recommendationRate',
},
{ key: 'duration', name: t('products:Duration'), nameKey: 'products:Duration' },
{
key: 'dept_name',
name: <RequireAuth subject={PERM_PRODUCTS_MANAGEMENT}>{t('products:Dept')}</RequireAuth>,
nameKey: 'products:Dept',
},
{
key: 'display_to_c',
name: <RequireAuth subject={PERM_PRODUCTS_MANAGEMENT}>{t('products:DisplayToC')}</RequireAuth>,
nameKey: 'products:DisplayToC',
},
{
key: 'remarks',
name: <RequireAuth subject={PERM_PRODUCTS_MANAGEMENT}>{t('products:Remarks')}</RequireAuth>,
nameKey: 'products:Remarks',
},
],
'Q': [
{ key: 'code', name: t('products:Code'), nameKey: 'products:Code' },
{ key: 'city_name', name: t('products:City'), nameKey: 'products:City' },
{
key: 'recommends_rate',
name: <RequireAuth subject={PERM_PRODUCTS_MANAGEMENT}>{t('products:recommendationRate')}</RequireAuth>,
nameKey: 'products:recommendationRate',
},
{ key: 'duration', name: t('products:Duration'), nameKey: 'products:Duration' },
{
key: 'dept_name',
name: <RequireAuth subject={PERM_PRODUCTS_MANAGEMENT}>{t('products:Dept')}</RequireAuth>,
nameKey: 'products:Dept',
},
{
key: 'display_to_c',
name: <RequireAuth subject={PERM_PRODUCTS_MANAGEMENT}>{t('products:DisplayToC')}</RequireAuth>,
nameKey: 'products:DisplayToC',
},
{
key: 'remarks',
name: <RequireAuth subject={PERM_PRODUCTS_MANAGEMENT}>{t('products:Remarks')}</RequireAuth>,
nameKey: 'products:Remarks',
},
],
'D': [
{ key: 'code', name: t('products:Code'), nameKey: 'products:Code' },
{ key: 'city_name', name: t('products:City'), nameKey: 'products:City' },
{
key: 'recommends_rate',
name: <RequireAuth subject={PERM_PRODUCTS_MANAGEMENT}>{t('products:recommendationRate')}</RequireAuth>,
nameKey: 'products:recommendationRate',
},
{ key: 'duration', name: t('products:Duration'), nameKey: 'products:Duration' },
{
key: 'dept_name',
name: <RequireAuth subject={PERM_PRODUCTS_MANAGEMENT}>{t('products:Dept')}</RequireAuth>,
nameKey: 'products:Dept',
},
{
key: 'display_to_c',
name: <RequireAuth subject={PERM_PRODUCTS_MANAGEMENT}>{t('products:DisplayToC')}</RequireAuth>,
nameKey: 'products:DisplayToC',
},
{
key: 'remarks',
name: <RequireAuth subject={PERM_PRODUCTS_MANAGEMENT}>{t('products:Remarks')}</RequireAuth>,
nameKey: 'products:Remarks',
},
],
'7': [
{ key: 'code', name: t('products:Code'), nameKey: 'products:Code' },
{ key: 'city_name', name: t('products:City'), nameKey: 'products:City' },
{
key: 'recommends_rate',
name: <RequireAuth subject={PERM_PRODUCTS_MANAGEMENT}>{t('products:recommendationRate')}</RequireAuth>,
nameKey: 'products:recommendationRate',
},
{ key: 'duration', name: t('products:Duration'), nameKey: 'products:Duration' },
{ key: 'open_weekdays', name: t('products:OpenWeekdays'), nameKey: 'products:OpenWeekdays' },
{
key: 'remarks',
name: <RequireAuth subject={PERM_PRODUCTS_MANAGEMENT}>{t('products:Remarks')}</RequireAuth>,
nameKey: 'products:Remarks',
},
],
'8': [
{ key: 'code', name: t('products:Code'), nameKey: 'products:Code' },
{ key: 'city_name', name: t('products:City'), nameKey: 'products:City' },
],
'R': [
{ key: 'code', name: t('products:Code'), nameKey: 'products:Code' },
{ key: 'city_name', name: t('products:City'), nameKey: 'products:City' },
],
};
const isCanEditable = false;
const renderFormItem = (item) => {
// const item = { key: 'code', name: t('products:Code'), nameKey: 'products:Code' };
// console.log(editingProduct?.info);
if (isEmpty(editingProduct)) {
return null;
}
console.log(item.key, at(editingProduct?.info, item.key)[0]);
let InputCom = <Input disabled={isCanEditable} />;
switch (item.key) {
case 'duration':
InputCom = <Input suffix='H' disabled={isCanEditable} />;
break;
case 'display_to_c':
InputCom = (
<Select disabled={isCanEditable}>
<Select.Option value={0}>在计划显示不在报价信显示</Select.Option>
<Select.Option value={1}>计划和报价信都要显示</Select.Option>
<Select.Option value={2}>计划和报价信都不用显示</Select.Option>
</Select>
);
break;
case 'dept_name':
InputCom = <DeptSelector disabled={isCanEditable} />;
break;
case 'city_name':
InputCom = <CitySelector disabled={isCanEditable} />;
break;
case 'remarks':
InputCom = <Input.TextArea rows={2} disabled={isCanEditable} />;
break;
default:
InputCom = <Input disabled={isCanEditable} />;
}
return (
<Col span={item.key === 'remarks' ? 24 : 8} key={`${item.key}`}>
<Form.Item name={item.key} label={t(item.nameKey)} >
{/* {renderFormItem(item)} */}
<InputCom />
</Form.Item>
</Col>
);
};
const onValuesChange = (changedValues, allValues) => {
// const dest = formValuesMapper(allValues);
console.log('form onValuesChange', Object.keys(changedValues), );
};
const onSave = (e) => {
console.log(e);
}; };
return ( return (
<> <>
@ -200,16 +51,7 @@ const ProductInfo = ({ ...props }) => {
/> />
<Divider className='my-1' /> <Divider className='my-1' />
<h2>{t('products:EditComponents.info')}</h2> <h2>{t('products:EditComponents.info')}</h2>
<ProductInfoForm editable showSubmit initialValues={editingProduct?.info} /> <ProductInfoForm editable={editable} showSubmit initialValues={editingProduct?.info} onSubmit={onSave} />
{/* <Form form={form} name='product-edit' initialValues={editingProduct?.info} onValuesChange={onValuesChange} onFinish={onSave}>
<Form.Item>
<div className='flex justify-around'>
<Button type='primary' htmlType='submit'>
{t('Save')}
</Button>
</div>
</Form.Item>
</Form> */}
<Divider className='my-1' /> <Divider className='my-1' />
</> </>
); );

@ -1,6 +1,6 @@
import { useEffect } from 'react'; import { useEffect } from 'react';
import { Form, Input, Row, Col, Select, DatePicker, Space, Button, InputNumber, Radio, Checkbox, Divider } from 'antd'; import { Form, Input, Row, Col, Select, DatePicker, Space, Button, InputNumber, Radio, Checkbox, Divider } from 'antd';
import { objectMapper, at } from '@/utils/commons'; import { objectMapper, at, isEmpty } from '@/utils/commons';
import { DATE_FORMAT, SMALL_DATETIME_FORMAT } from '@/config'; import { DATE_FORMAT, SMALL_DATETIME_FORMAT } from '@/config';
// import useFormStore from '@/stores/Form'; // import useFormStore from '@/stores/Form';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
@ -74,8 +74,8 @@ const InfoForm = ({ formInstance, onSubmit, onReset, onValuesChange, editable, s
return ( return (
<> <>
<Form form={form} disabled={!(editable || false)} name={formName || 'product_info'} onFinish={onFinish} onValuesChange={onIValuesChange} initialValues={editingProduct?.info}> <Form form={form} disabled={!(editable || false)} name={formName || 'product_info'} onFinish={onFinish} onValuesChange={onIValuesChange} initialValues={editingProduct?.info}>
<Row gutter={16}> <Row>
{getFields({ sort, initialValue: editingProduct?.info, hides, shows, fieldProps, fieldComProps, form, t, dataSets: { weekdays } })} {getFields({ sort, initialValue: editingProduct?.info, hides, shows, fieldProps, fieldComProps, form, t, dataSets: { weekdays }, editable })}
{/* {showSubmit && ( {/* {showSubmit && (
<Col flex='1 0 90px' className='flex justify-end items-start'> <Col flex='1 0 90px' className='flex justify-end items-start'>
<Space align='center'> <Space align='center'>
@ -88,13 +88,13 @@ const InfoForm = ({ formInstance, onSubmit, onReset, onValuesChange, editable, s
</Row> </Row>
{/* <Divider className='my-1' /> */} {/* <Divider className='my-1' /> */}
<ProductInfoLgc formInstance={form} /> <ProductInfoLgc editable={editable} formInstance={form} />
<ProductInfoQuotation formInstance={form} /> <ProductInfoQuotation editable={editable} formInstance={form} />
<Form.Item hidden name={'id'} label={'ID'}> <Form.Item hidden name={'id'} label={'ID'}>
<Input /> <Input />
</Form.Item> </Form.Item>
{showSubmit && ( {editable && (
<Form.Item> <Form.Item>
<div className='flex justify-around'> <div className='flex justify-around'>
<Button type='primary' htmlType='submit'> <Button type='primary' htmlType='submit'>
@ -110,18 +110,23 @@ const InfoForm = ({ formInstance, onSubmit, onReset, onValuesChange, editable, s
function getFields(props) { function getFields(props) {
const { fieldProps, fieldComProps, form, t, dataSets } = props; const { fieldProps, fieldComProps, form, t, dataSets } = props;
console.log('getFields', props.initialValue); // console.log('getFields', props.initialValue);
const styleProps = {};
// !props.editable ? {
// variant: 'borderless',
// className: '!text-slate-500',
// } : {};
const bigCol = 4 * 2; const bigCol = 4 * 2;
const midCol = 6; const midCol = 8;
const layoutProps = { const layoutProps = {
// gutter: { xs: 8, sm: 8, lg: 16 }, // gutter: { xs: 8, sm: 8, lg: 16 },
lg: { span: 4 }, lg: { span: 6 },
md: { span: 8 }, md: { span: 8 },
sm: { span: 12 }, sm: { span: 12 },
xs: { span: 24 }, xs: { span: 24 },
}; };
const item = (name, sort = 0, render, col) => { const item = (name, sort = 0, render, col) => {
const customCol = col || 4; const customCol = col || midCol;
const mdCol = customCol * 2; const mdCol = customCol * 2;
return { return {
'key': '', 'key': '',
@ -129,7 +134,7 @@ function getFields(props) {
name, name,
render, render,
'hide': false, 'hide': false,
'col': { lg: { span: customCol }, md: { span: mdCol < 8 ? 10 : mdCol }, flex: mdCol < 8 ? '1 0' : '' }, 'col': { lg: { span: customCol }, md: { span: mdCol < 8 ? 10 : (mdCol > 24 ? 24 : mdCol) }, flex: mdCol < 8 ? '1 0' : '' },
}; };
}; };
let baseChildren = []; let baseChildren = [];
@ -138,49 +143,49 @@ function getFields(props) {
'code', 'code',
99, 99,
<Form.Item name='code' label={t('Code')} {...fieldProps.code} _initialValue={at(props, 'initialValue.code')[0]}> <Form.Item name='code' label={t('Code')} {...fieldProps.code} _initialValue={at(props, 'initialValue.code')[0]}>
<Input allowClear {...fieldComProps.code} /> <Input allowClear {...fieldComProps.code} {...styleProps} />
</Form.Item>, </Form.Item>,
fieldProps?.code?.col || 8 fieldProps?.code?.col || midCol
), ),
item( item(
'city', // todo: 'city', // todo:
99, 99,
<Form.Item name='city' label={t('City')} {...fieldProps.city} _initialValue={at(props, 'initialValue.city')[0]}> <Form.Item name='city' label={t('City')} {...fieldProps.city} _initialValue={at(props, 'initialValue.city')[0]}>
<CitySelector /> <CitySelector {...styleProps} />
</Form.Item>, </Form.Item>,
fieldProps?.city?.col || 8 fieldProps?.city?.col || midCol
), ),
item( item(
'dept', // todo: 'dept', // todo:
99, 99,
<Form.Item name='dept' label={t('Dept')} {...fieldProps.dept}> <Form.Item name='dept' label={t('Dept')} {...fieldProps.dept}>
<DeptSelector labelInValue={false} /> <DeptSelector labelInValue={false} isLeaf {...styleProps} />
</Form.Item>, </Form.Item>,
fieldProps?.dept?.col || 8 fieldProps?.dept?.col || midCol
), ),
item( item(
'duration', 'duration',
99, 99,
<Form.Item name='duration' label={t('Duration')} {...fieldProps.duration}> <Form.Item name='duration' label={t('Duration')} {...fieldProps.duration}>
<InputNumber suffix={'H'} max={24} /> <InputNumber suffix={'H'} max={24} {...styleProps} />
{/* <Input allowClear {...fieldComProps.duration} suffix={'H'} /> */} {/* <Input allowClear {...fieldComProps.duration} suffix={'H'} /> */}
</Form.Item>, </Form.Item>,
fieldProps?.duration?.col || 8 fieldProps?.duration?.col || midCol
), ),
item( item(
'km', 'km',
99, 99,
<Form.Item name='km' label={t('KM')} {...fieldProps.km}> <Form.Item name='km' label={t('KM')} {...fieldProps.km}>
<InputNumber suffix={'KM'} min={1} /> <InputNumber suffix={'KM'} min={0.1} {...styleProps} />
</Form.Item>, </Form.Item>,
fieldProps?.km?.col || 8 fieldProps?.km?.col || midCol
), ),
item( item(
'recommends_rate', // todo: 'recommends_rate', // todo:
99, 99,
<Form.Item name='recommends_rate' label={t('RecommendsRate')} {...fieldProps.recommends_rate}> <Form.Item name='recommends_rate' label={t('RecommendsRate')} {...fieldProps.recommends_rate}>
{/* <Input placeholder={t('RecommendsRate')} allowClear /> */} {/* <Input placeholder={t('RecommendsRate')} allowClear /> */}
<Select <Select {...styleProps}
style={{ width: '100%' }} style={{ width: '100%' }}
labelInValue labelInValue
options={[ options={[
@ -192,7 +197,7 @@ function getFields(props) {
]} ]}
/> />
</Form.Item>, </Form.Item>,
fieldProps?.recommends_rate?.col || 8 fieldProps?.recommends_rate?.col || midCol
), ),
item( item(
'display_to_c', 'display_to_c',
@ -222,16 +227,16 @@ function getFields(props) {
{ value: '153001', label: '在计划显示,不在报价信显示' }, { value: '153001', label: '在计划显示,不在报价信显示' },
{ value: 0, label: '计划和报价信都要显示' }, { value: 0, label: '计划和报价信都要显示' },
{ value: '153001, 153002', label: '计划和报价信都不用显示' }, { value: '153001, 153002', label: '计划和报价信都不用显示' },
]} /> ]} {...styleProps} />
</Form.Item>, </Form.Item>,
fieldProps?.display_to_c?.col || 8 fieldProps?.display_to_c?.col || midCol
), ),
item( item(
'open_weekdays', 'open_weekdays',
99, 99,
<Form.Item name='open_weekdays' label={t('OpenWeekdays')} initialValue={['1', '2', '3', '4', '5', '6', '7']} {...fieldProps.open_weekdays}> <Form.Item name='open_weekdays' label={t('OpenWeekdays')} initialValue={['1', '2', '3', '4', '5', '6', '7']} {...fieldProps.open_weekdays}>
{/* 默认全部 */} {/* 默认全部 */}
<Checkbox.Group options={dataSets.weekdays} /> <Checkbox.Group options={dataSets.weekdays} {...styleProps} />
</Form.Item>, </Form.Item>,
fieldProps?.open_weekdays?.col || 24 fieldProps?.open_weekdays?.col || 24
), ),
@ -239,7 +244,7 @@ function getFields(props) {
'remarks', 'remarks',
99, 99,
<Form.Item name='remarks' label={t('Remarks')} {...fieldProps.remarks}> <Form.Item name='remarks' label={t('Remarks')} {...fieldProps.remarks}>
<Input.TextArea allowClear rows={2} maxLength={2000} {...fieldComProps.remarks} /> <Input.TextArea allowClear rows={2} maxLength={2000} {...fieldComProps.remarks} {...styleProps} />
</Form.Item>, </Form.Item>,
fieldProps?.remarks?.col || 24 fieldProps?.remarks?.col || 24
), ),
@ -282,7 +287,7 @@ function getFields(props) {
style = i % 2 === 0 && baseChildren[i].col === 12 ? { ...style, ...leftStyle } : style; style = i % 2 === 0 && baseChildren[i].col === 12 ? { ...style, ...leftStyle } : style;
style = !baseChildren[i].hide ? { ...style, display: 'block' } : { ...style, display: 'none' }; style = !baseChildren[i].hide ? { ...style, display: 'block' } : { ...style, display: 'none' };
const Item = ( const Item = (
<Col key={String(i)} style={style} {...layoutProps} {...baseChildren[i].col}> <Col key={String(i)} style={style} {...baseChildren[i].col} className='px-1 shrink-0 grow'>
{baseChildren[i].render} {baseChildren[i].render}
</Col> </Col>
); );
@ -290,28 +295,32 @@ function getFields(props) {
} }
return children; return children;
} }
const formValuesMapper = (values) => { const formValuesMapper = (values) => {
const destinationObject = { const destinationObject = {
'keyword': { key: 'keyword', transform: (value) => value || '' }, 'city': [{ key: 'city_id', transform: (value) => value?.value || value?.key || '' }, { key: 'city_name', transform: (value) => value?.label || '' }],
'referenceNo': { key: 'referenceNo', transform: (value) => value || '' }, 'dept': { key: 'dept', transform: (value) => typeof value === 'string' ? value : (value?.value || value?.key || '') },
'dates': [ 'open_weekdays': { key: 'open_weekdays', transform: (value) => (Array.isArray(value) ? value.join(',') : value) },
{ key: 'startdate', transform: (arrVal) => (arrVal ? arrVal[0].format(DATE_FORMAT) : '') }, 'recommends_rate': { key: 'recommends_rate', transform: (value) => typeof value === 'string' ? value : (value?.value || value?.key || '') },
{ key: 'enddate', transform: (arrVal) => (arrVal ? arrVal[1].format(DATE_FORMAT) : '') }, 'lgc_details': [
{ key: 'starttime', transform: (arrVal) => (arrVal ? arrVal[0].format(DATE_FORMAT) : '') }, {
{ key: 'endtime', transform: (arrVal) => (arrVal ? arrVal[1].format(SMALL_DATETIME_FORMAT) : '') }, key: 'lgc_details',
], transform: (value) => {
'invoiceStatus': { key: 'invoiceStatus', transform: (value) => value?.value || value?.key || '', default: '' }, const _val = value.filter((s) => !isEmpty(s));
'audit_state': { key: 'audit_state', transform: (value) => value?.value || value?.key || '', default: '' }, return _val || '';
'agency': { },
key: 'agency',
transform: (value) => {
return Array.isArray(value) ? value.map((ele) => ele.key).join(',') : value ? value.value : '';
}, },
}, {
'year': [{ key: 'year', transform: (arrVal) => (arrVal ? arrVal.format('YYYY') : '') }], key: 'lgc_details_mapped',
transform: (value) => {
const _val = value.filter((s) => !isEmpty(s));
return _val.reduce((r, c) => ({ ...r, [c.lgc]: c }), {});
},
},
],
}; };
let dest = {}; let dest = {};
const { dates, ...omittedValue } = values; const { city, ...omittedValue } = values;
dest = { ...omittedValue, ...objectMapper(values, destinationObject) }; dest = { ...omittedValue, ...objectMapper(values, destinationObject) };
for (const key in dest) { for (const key in dest) {
if (Object.prototype.hasOwnProperty.call(dest, key)) { if (Object.prototype.hasOwnProperty.call(dest, key)) {
@ -320,7 +329,8 @@ const formValuesMapper = (values) => {
} }
// omit empty // omit empty
// Object.keys(dest).forEach((key) => (dest[key] == null || dest[key] === '' || dest[key].length === 0) && delete dest[key]); // Object.keys(dest).forEach((key) => (dest[key] == null || dest[key] === '' || dest[key].length === 0) && delete dest[key]);
return dest; const { lgc_details, lgc_details_mapped, ...info } = dest;
return { info, lgc_details, lgc_details_mapped };
}; };

@ -9,7 +9,7 @@ import { useTranslation } from 'react-i18next';
import { useDefaultLgc } from '@/i18n/LanguageSwitcher'; import { useDefaultLgc } from '@/i18n/LanguageSwitcher';
import { cloneDeep, isEmpty } from '@/utils/commons'; import { cloneDeep, isEmpty } from '@/utils/commons';
const ProductInfoLgc = ({ formInstance, ...props }) => { const ProductInfoLgc = ({ editable, formInstance, ...props }) => {
const { t } = useTranslation(); const { t } = useTranslation();
const { language: languageHT } = useDefaultLgc(); const { language: languageHT } = useDefaultLgc();
const [isPermitted, currentUser] = useAuthStore((state) => [state.isPermitted, state.currentUser]); const [isPermitted, currentUser] = useAuthStore((state) => [state.isPermitted, state.currentUser]);
@ -27,31 +27,31 @@ const ProductInfoLgc = ({ formInstance, ...props }) => {
const [items, setItems] = useState([]); const [items, setItems] = useState([]);
const newTabIndex = useRef(0); const newTabIndex = useRef(0);
useEffect(() => { useEffect(() => {
const existsLgc = (editingProduct?.lgc_details || []).map((ele) => ({ const existsLgc = (editingProduct?.lgc_details || []).map((ele, li) => ({
...ele, ...ele,
label: HTLanguageSetsMapVal[ele.lgc].label, label: HTLanguageSetsMapVal[ele.lgc].label,
key: `${editingProduct.info.id}-${ele.id}`, key: `${editingProduct.info.id}-${ele.id}`,
closable: false, // isPermitted(PERM_PRODUCTS_MANAGEMENT) ? true : false, closable: false, // isPermitted(PERM_PRODUCTS_MANAGEMENT) ? true : false,
children: ( children: (
<> <>
<Form.Item name={[`${ele.lgc}`, 'title']} label={t('products:Title')} initialValue={ele.title}> <Form.Item name={[li, 'title']} label={t('products:Title')} initialValue={ele.title}>
<Input <Input className=' !text-slate-500'
// onChange={(e) => handleChange('title', e.target.value)} // onChange={(e) => handleChange('title', e.target.value)}
// disabled={isCanEditable} // disabled={isCanEditable}
disabled={!isEmpty(ele.title)} disabled={!isEmpty(ele.title) || !editable}
/> />
</Form.Item> </Form.Item>
<Form.Item name={[`${ele.lgc}`, 'description']} label={t('products:Description')} initialValue={ele.descriptions}> <Form.Item name={[li, 'description']} label={t('products:Description')} initialValue={ele.descriptions}>
<Input.TextArea <Input.TextArea className='!text-slate-500'
rows={3} rows={3}
// onChange={(e) => handleChange('description', e.target.value)} // onChange={(e) => handleChange('description', e.target.value)}
disabled={!isEmpty(ele.descriptions)} disabled={!isEmpty(ele.descriptions) || !editable}
/> />
</Form.Item> </Form.Item>
<Form.Item hidden name={[`${ele.lgc}`, 'lgc']} initialValue={ele.lgc}> <Form.Item hidden name={[li, 'lgc']} initialValue={ele.lgc}>
<Input /> <Input />
</Form.Item> </Form.Item>
<Form.Item hidden name={[`${ele.lgc}`, 'id']} initialValue={ele.id}> <Form.Item hidden name={[li, 'id']} initialValue={ele.id}>
<Input /> <Input />
</Form.Item> </Form.Item>
</> </>
@ -72,21 +72,22 @@ const ProductInfoLgc = ({ formInstance, ...props }) => {
}; };
const addLgc = (lgcItem) => { const addLgc = (lgcItem) => {
const newActiveKey = lgcItem.value; // `newTab${newTabIndex.current++}`; const newActiveKey = lgcItem.value; // `newTab${newTabIndex.current++}`;
const i = 8+Number(lgcItem.value);
const newPanes = [...items]; const newPanes = [...items];
newPanes.push({ newPanes.push({
...lgcItem, ...lgcItem,
children: ( children: (
<> <>
<Form.Item name={[`${lgcItem.value}`, 'title']} label={t('products:Title')}> <Form.Item name={[i, 'title']} label={t('products:Title')}>
<Input /> <Input />
</Form.Item> </Form.Item>
<Form.Item name={[`${lgcItem.value}`, 'description']} label={t('products:Description')}> <Form.Item name={[i, 'description']} label={t('products:Description')}>
<Input.TextArea rows={3} /> <Input.TextArea rows={3} />
</Form.Item> </Form.Item>
<Form.Item hidden name={[`${lgcItem.value}`, 'lgc']} initialValue={lgcItem.value}> <Form.Item hidden name={[i, 'lgc']} initialValue={lgcItem.value}>
<Input /> <Input />
</Form.Item> </Form.Item>
<Form.Item hidden name={[`${lgcItem.value}`, 'id']}> <Form.Item hidden name={[i, 'id']}>
<Input /> <Input />
</Form.Item> </Form.Item>
</> </>
@ -94,7 +95,7 @@ const ProductInfoLgc = ({ formInstance, ...props }) => {
}); });
setItems(newPanes); setItems(newPanes);
setActiveKey(newActiveKey); setActiveKey(newActiveKey);
const currentLgcOptions = cloneDeep(lgcOptions); const currentLgcOptions = structuredClone(lgcOptions);
currentLgcOptions.splice(currentLgcOptions.findIndex(ele => ele.value === lgcItem.value), 1); currentLgcOptions.splice(currentLgcOptions.findIndex(ele => ele.value === lgcItem.value), 1);
setLgcOptions(currentLgcOptions); setLgcOptions(currentLgcOptions);
setSelectNewLgc(null); setSelectNewLgc(null);
@ -143,7 +144,7 @@ const ProductInfoLgc = ({ formInstance, ...props }) => {
return ( return (
<> <>
<Form.List name={'lgc_details'}> <Form.List name={'lgc_details'}>
{(fields, { add, remove }) => <Tabs type='editable-card' size='small' onChange={onChange} activeKey={activeKey} onEdit={onEdit} items={items} hideAdd={isEmpty(lgcOptions)} tabPosition='top' />} {(fields, { add, remove }) => <Tabs type='editable-card' size='small' onChange={onChange} activeKey={activeKey} onEdit={onEdit} items={items} hideAdd={isEmpty(lgcOptions) || !editable} tabPosition='top' />}
</Form.List> </Form.List>
<Modal title='选择语言' open={newLgcModalVisible} onOk={handleOk} onCancel={() => setNewLgcModalVisible(false)}> <Modal title='选择语言' open={newLgcModalVisible} onOk={handleOk} onCancel={() => setNewLgcModalVisible(false)}>
<Select <Select

@ -1,14 +1,15 @@
import { createContext, useEffect, useState } from 'react'; import { createContext, useEffect, useState } from 'react';
import { Table, Form, Modal, Button, InputNumber, Select, DatePicker } from 'antd'; import { Table, Form, Modal, Button, InputNumber, Select, DatePicker, Popconfirm } from 'antd';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import dayjs from 'dayjs'; import dayjs from 'dayjs';
import BatchImportPrice from './BatchImportPrice'; import BatchImportPrice from './BatchImportPrice';
import { useDatePresets } from '@/hooks/useDatePresets'; import { useDatePresets, useWeekdays } from '@/hooks/useDatePresets';
const { RangePicker } = DatePicker; const { RangePicker } = DatePicker;
const ProductInfoQuotation = ({ formInstance, ...props }) => { const ProductInfoQuotation = ({ editable, formInstance, ...props }) => {
const { t } = useTranslation(); const { t } = useTranslation();
const presets = useDatePresets(); const presets = useDatePresets();
const weekdaySets = useWeekdays();
const [batchImportPriceVisible, setBatchImportPriceVisible] = useState(false); const [batchImportPriceVisible, setBatchImportPriceVisible] = useState(false);
const [quotationTableVisible, setQuotationTableVisible] = useState(false); const [quotationTableVisible, setQuotationTableVisible] = useState(false);
const [editIndex, setEditIndex] = useState(null); const [editIndex, setEditIndex] = useState(null);
@ -91,8 +92,7 @@ const ProductInfoQuotation = ({ formInstance, ...props }) => {
setQuotationTableVisible(false); setQuotationTableVisible(false);
}; };
const days = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']; const days = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'];
const handleDayClick = (dayIndex) => { const handleDayClick = (dayOfWeek) => {
const dayOfWeek = (dayIndex % 7) + 1;
setSelectedDays((prevSelectedDays) => { setSelectedDays((prevSelectedDays) => {
const updatedDays = prevSelectedDays.includes(dayOfWeek) ? prevSelectedDays.filter((d) => d !== dayOfWeek) : [...prevSelectedDays, dayOfWeek]; const updatedDays = prevSelectedDays.includes(dayOfWeek) ? prevSelectedDays.filter((d) => d !== dayOfWeek) : [...prevSelectedDays, dayOfWeek];
@ -101,34 +101,78 @@ const ProductInfoQuotation = ({ formInstance, ...props }) => {
return updatedDays; return updatedDays;
}); });
}; };
const handleDelete = (index) => {
const newData = [...quotation];
newData.splice(index, 1);
const sortedData = [...newData].sort((a, b) => {
const aValidPeriod = dayjs(a.use_dates_end).diff(dayjs(a.use_dates_start));
const bValidPeriod = dayjs(b.use_dates_end).diff(dayjs(b.use_dates_start));
if (aValidPeriod !== bValidPeriod) {
return aValidPeriod - bValidPeriod;
}
const aGroupSize = a.group_size_max - a.group_size_min;
const bGroupSize = b.group_size_max - b.group_size_min;
return aGroupSize - bGroupSize;
});
setQuotation(sortedData);
};
const columns = [ const columns = [
{ title: t('products:adultPrice'), dataIndex: 'adult_cost', width: '10%', editable: true }, { title: t('products:adultPrice'), dataIndex: 'adult_cost', width: '4rem' },
{ title: t('products:childrenPrice'), dataIndex: 'child_cost', width: '10%', editable: true }, { title: t('products:childrenPrice'), dataIndex: 'child_cost', width: '4rem' },
{ title: t('products:currency'), dataIndex: 'currency', width: '10%', editable: true }, { title: t('products:currency'), dataIndex: 'currency', width: '4rem' },
{ {
title: t('products:Types'), title: t('products:Types'),
dataIndex: 'unit', dataIndex: 'unit',
width: '10%', width: '4rem',
editable: true,
render: (text) => (text === '0' ? '每人' : text === '1' ? '每团' : text), render: (text) => (text === '0' ? '每人' : text === '1' ? '每团' : text),
}, },
{ {
title: t('products:number'), title: t('products:number'),
dataIndex: 'group_size', dataIndex: 'group_size',
width: '20%', width: '4rem',
editable: true,
render: (_, record) => `${record.group_size_min}-${record.group_size_max}`, render: (_, record) => `${record.group_size_min}-${record.group_size_max}`,
}, },
{ {
title: t('products:validityPeriod'), title: t('products:validityPeriod'),
dataIndex: 'validityPeriod', dataIndex: 'validityPeriod',
width: '20%', width: '6rem',
editable: true,
render: (_, record) => `${record.use_dates_start}-${record.use_dates_end}`, render: (_, record) => `${record.use_dates_start}-${record.use_dates_end}`,
}, },
{ title: t('products:Weekdays'), dataIndex: 'weekdays', width: '10%' }, { title: t('products:Weekdays'), dataIndex: 'weekdays', width: '4rem' },
...(editable
? [
{
title: t('products:operation'),
dataIndex: 'operation',
width: '6rem',
render: (_, record, index) => {
const canEdit = true; // record.audit_state_id === -1; // todo:
return (
<span>
{canEdit ? (
<a onClick={() => edit(record, index)} style={{ marginRight: 8 }}>
{t('Edit')}
</a>
) : (
<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>
);
},
},
]
: []),
]; ];
return ( return (
<> <>
@ -143,13 +187,14 @@ const ProductInfoQuotation = ({ formInstance, ...props }) => {
// pagination={{ onChange: cancel }} // pagination={{ onChange: cancel }}
/> />
{ {
// !isCanEditable && editable &&
<Button onClick={handleAdd} type='primary' ghost style={{ marginTop: 16 }}> <Button onClick={handleAdd} type='primary' ghost style={{ marginTop: 16 }}>
{t('products:addQuotation')} {t('products:addQuotation')}
</Button> </Button>
} }
{ {
editable &&
<Button onClick={handleBatchImport} type='primary' ghost style={{ marginTop: 16, marginLeft: 16 }}> <Button onClick={handleBatchImport} type='primary' ghost style={{ marginTop: 16, marginLeft: 16 }}>
批量添加 批量添加
</Button> </Button>
@ -208,9 +253,9 @@ const ProductInfoQuotation = ({ formInstance, ...props }) => {
}} }}
/> />
<h3>周末</h3> <h3>周末</h3>
{days.map((day, index) => ( {weekdaySets.map((day, index) => (
<Button key={index} type={selectedDays.includes((index % 7) + 1) ? 'primary' : 'default'} onClick={() => handleDayClick(index)} style={{ margin: '5px' }}> <Button key={day.value} type={selectedDays.includes(day.value) ? 'primary' : 'default'} onClick={() => handleDayClick(day.value)} style={{ margin: '5px' }}>
{day} {day.label}
</Button> </Button>
))} ))}
</Modal> </Modal>

@ -49,7 +49,8 @@ const ProductsTree = ({ onNodeSelect, ...props }) => {
const [autoExpandParent, setAutoExpandParent] = useState(true); const [autoExpandParent, setAutoExpandParent] = useState(true);
useEffect(() => { useEffect(() => {
// ; , ; , // ;
// const title = text || r.lgc_details?.['2']?.title || r.lgc_details?.['1']?.title || '';
const hasDataTypes = Object.keys(agencyProducts); const hasDataTypes = Object.keys(agencyProducts);
const _show = productsTypes const _show = productsTypes
.filter((kk) => hasDataTypes.includes(kk.value)) .filter((kk) => hasDataTypes.includes(kk.value))
@ -57,12 +58,14 @@ const ProductsTree = ({ onNodeSelect, ...props }) => {
...ele, ...ele,
title: ele.label, title: ele.label,
key: ele.value, key: ele.value,
children: (agencyProducts[ele.value] || []).map((product) => ({ children: (agencyProducts[ele.value] || []).map((product) => {
title: product.info.title, const lgc_map = product.lgc_details.reduce((rlgc, clgc) => ({...rlgc, [clgc.lgc]: clgc}), {});
return {
title: product.info.title || lgc_map?.['2']?.title || lgc_map?.['1']?.title || '',
// key: `${ele.value}-${product.info.id}`, // key: `${ele.value}-${product.info.id}`,
key: product.info.id, key: product.info.id,
_raw: product, _raw: product,
})), }}),
})); }));
setTreeData(_show); setTreeData(_show);
setRawTreeData(_show); setRawTreeData(_show);
@ -121,6 +124,7 @@ const ProductsTree = ({ onNodeSelect, ...props }) => {
<Tree <Tree
blockNode blockNode
showLine showLine
selectedKeys={[editingProduct?.info?.id || editingProduct?.info?.product_type_id]}
switcherIcon={<CaretDownOutlined />} switcherIcon={<CaretDownOutlined />}
onSelect={handleNodeSelect} onSelect={handleNodeSelect}
treeData={treeData} treeData={treeData}

Loading…
Cancel
Save